From cebfc5c8facbf6ae335499f7f4b3dc57a60af999 Mon Sep 17 00:00:00 2001 From: George Hazan Date: Sun, 29 Sep 2024 19:03:55 +0300 Subject: TDLIB update up to the current state --- protocols/Telegram/src/auth.cpp | 1 - protocols/Telegram/src/menus.cpp | 2 +- protocols/Telegram/src/options.cpp | 2 +- protocols/Telegram/src/proto.cpp | 6 +- protocols/Telegram/src/server.cpp | 33 +- protocols/Telegram/src/utils.cpp | 106 +- protocols/Telegram/src/utils.h | 2 + protocols/Telegram/src/version.h | 4 +- .../Telegram/tdlib/td/sqlite/sqlite/sqlite3.c | 50474 ++++---- .../td/td/generate/auto/td/mtproto/mtproto_api.cpp | 68 - .../td/td/generate/auto/td/mtproto/mtproto_api.h | 355 +- .../td/td/generate/auto/td/telegram/secret_api.cpp | 135 +- .../td/td/generate/auto/td/telegram/secret_api.h | 642 +- .../td/td/generate/auto/td/telegram/td_api.cpp | 34704 ++++-- .../tdlib/td/td/generate/auto/td/telegram/td_api.h | 109039 +++++++++++++++--- .../td/td/generate/auto/td/telegram/td_api.hpp | 3887 +- .../td/generate/auto/td/telegram/td_api_json.cpp | 16921 ++- .../td/td/generate/auto/td/telegram/td_api_json.h | 1666 +- .../td/generate/auto/td/telegram/telegram_api.cpp | 46799 +++++--- .../td/td/generate/auto/td/telegram/telegram_api.h | 46165 +++++--- .../td/generate/auto/td/telegram/telegram_api.hpp | 2176 +- .../tdlib/td/td/generate/auto/tlo/td_api.tlo | Bin 275972 -> 380660 bytes .../tdlib/td/td/generate/auto/tlo/telegram_api.tlo | Bin 306988 -> 398760 bytes .../Telegram/tdlib/td/td/mtproto/AuthData.cpp | 43 +- protocols/Telegram/tdlib/td/td/mtproto/AuthData.h | 34 +- .../Telegram/tdlib/td/td/mtproto/CryptoStorer.h | 57 +- .../Telegram/tdlib/td/td/mtproto/Handshake.cpp | 60 +- protocols/Telegram/tdlib/td/td/mtproto/Handshake.h | 17 +- .../tdlib/td/td/mtproto/HandshakeConnection.h | 5 +- protocols/Telegram/tdlib/td/td/mtproto/MessageId.h | 70 + .../Telegram/tdlib/td/td/mtproto/MtprotoQuery.h | 8 +- .../Telegram/tdlib/td/td/mtproto/NoCryptoStorer.h | 10 +- .../Telegram/tdlib/td/td/mtproto/PacketInfo.h | 10 +- .../tdlib/td/td/mtproto/PingConnection.cpp | 44 +- .../Telegram/tdlib/td/td/mtproto/ProxySecret.cpp | 5 +- .../Telegram/tdlib/td/td/mtproto/RawConnection.cpp | 92 +- .../Telegram/tdlib/td/td/mtproto/RawConnection.h | 10 +- .../tdlib/td/td/mtproto/SessionConnection.cpp | 437 +- .../tdlib/td/td/mtproto/SessionConnection.h | 103 +- protocols/Telegram/tdlib/td/td/mtproto/TlsInit.cpp | 12 +- protocols/Telegram/tdlib/td/td/mtproto/TlsInit.h | 3 +- .../Telegram/tdlib/td/td/mtproto/Transport.cpp | 191 +- protocols/Telegram/tdlib/td/td/mtproto/Transport.h | 39 +- protocols/Telegram/tdlib/td/td/mtproto/utils.cpp | 8 +- protocols/Telegram/tdlib/td/td/mtproto/utils.h | 11 +- .../Telegram/tdlib/td/td/telegram/AccentColorId.h | 82 + .../Telegram/tdlib/td/td/telegram/Account.cpp | 661 - protocols/Telegram/tdlib/td/td/telegram/Account.h | 51 - .../tdlib/td/td/telegram/AccountManager.cpp | 1347 + .../Telegram/tdlib/td/td/telegram/AccountManager.h | 136 + .../Telegram/tdlib/td/td/telegram/AlarmManager.cpp | 58 + .../Telegram/tdlib/td/td/telegram/AlarmManager.h | 38 + .../tdlib/td/td/telegram/AnimationsManager.cpp | 67 +- .../Telegram/tdlib/td/td/telegram/Application.cpp | 39 +- .../Telegram/tdlib/td/td/telegram/Application.h | 4 +- .../tdlib/td/td/telegram/AttachMenuManager.cpp | 424 +- .../tdlib/td/td/telegram/AttachMenuManager.h | 28 +- .../tdlib/td/td/telegram/AudiosManager.cpp | 27 +- .../Telegram/tdlib/td/td/telegram/AuthManager.cpp | 651 +- .../Telegram/tdlib/td/td/telegram/AuthManager.h | 158 +- .../Telegram/tdlib/td/td/telegram/AuthManager.hpp | 130 +- .../tdlib/td/td/telegram/AutoDownloadSettings.cpp | 16 +- .../tdlib/td/td/telegram/AutoDownloadSettings.h | 3 +- .../tdlib/td/td/telegram/AutosaveManager.cpp | 36 +- .../tdlib/td/td/telegram/AutosaveManager.h | 4 +- .../tdlib/td/td/telegram/BackgroundInfo.cpp | 9 +- .../Telegram/tdlib/td/td/telegram/BackgroundInfo.h | 9 +- .../tdlib/td/td/telegram/BackgroundManager.cpp | 212 +- .../tdlib/td/td/telegram/BackgroundManager.h | 40 +- .../tdlib/td/td/telegram/BackgroundType.cpp | 60 +- .../Telegram/tdlib/td/td/telegram/BackgroundType.h | 16 +- .../tdlib/td/td/telegram/BackgroundType.hpp | 12 +- .../Telegram/tdlib/td/td/telegram/BaseTheme.cpp | 45 + .../Telegram/tdlib/td/td/telegram/BaseTheme.h | 22 + .../Telegram/tdlib/td/td/telegram/Birthdate.cpp | 69 + .../Telegram/tdlib/td/td/telegram/Birthdate.h | 69 + .../Telegram/tdlib/td/td/telegram/Birthdate.hpp | 25 + .../Telegram/tdlib/td/td/telegram/BlockListId.h | 99 + .../Telegram/tdlib/td/td/telegram/BoostManager.cpp | 524 + .../Telegram/tdlib/td/td/telegram/BoostManager.h | 65 + .../Telegram/tdlib/td/td/telegram/BotCommand.cpp | 31 +- .../Telegram/tdlib/td/td/telegram/BotCommand.h | 5 +- .../tdlib/td/td/telegram/BotCommandScope.cpp | 25 +- .../tdlib/td/td/telegram/BotInfoManager.cpp | 660 +- .../Telegram/tdlib/td/td/telegram/BotInfoManager.h | 107 +- .../tdlib/td/td/telegram/BotMenuButton.cpp | 9 +- .../Telegram/tdlib/td/td/telegram/BotQueries.cpp | 116 + .../Telegram/tdlib/td/td/telegram/BotQueries.h | 25 + .../tdlib/td/td/telegram/BusinessAwayMessage.cpp | 68 + .../tdlib/td/td/telegram/BusinessAwayMessage.h | 70 + .../tdlib/td/td/telegram/BusinessAwayMessage.hpp | 38 + .../td/td/telegram/BusinessAwayMessageSchedule.cpp | 105 + .../td/td/telegram/BusinessAwayMessageSchedule.h | 54 + .../td/td/telegram/BusinessAwayMessageSchedule.hpp | 50 + .../tdlib/td/td/telegram/BusinessBotManageBar.cpp | 94 + .../tdlib/td/td/telegram/BusinessBotManageBar.h | 86 + .../tdlib/td/td/telegram/BusinessChatLink.cpp | 56 + .../tdlib/td/td/telegram/BusinessChatLink.h | 54 + .../tdlib/td/td/telegram/BusinessConnectedBot.cpp | 46 + .../tdlib/td/td/telegram/BusinessConnectedBot.h | 71 + .../tdlib/td/td/telegram/BusinessConnectedBot.hpp | 35 + .../tdlib/td/td/telegram/BusinessConnectionId.h | 79 + .../td/td/telegram/BusinessConnectionManager.cpp | 1467 + .../td/td/telegram/BusinessConnectionManager.h | 224 + .../td/td/telegram/BusinessGreetingMessage.cpp | 68 + .../tdlib/td/td/telegram/BusinessGreetingMessage.h | 70 + .../td/td/telegram/BusinessGreetingMessage.hpp | 35 + .../Telegram/tdlib/td/td/telegram/BusinessInfo.cpp | 116 + .../Telegram/tdlib/td/td/telegram/BusinessInfo.h | 60 + .../Telegram/tdlib/td/td/telegram/BusinessInfo.hpp | 83 + .../tdlib/td/td/telegram/BusinessIntro.cpp | 97 + .../Telegram/tdlib/td/td/telegram/BusinessIntro.h | 62 + .../tdlib/td/td/telegram/BusinessIntro.hpp | 63 + .../tdlib/td/td/telegram/BusinessManager.cpp | 628 + .../tdlib/td/td/telegram/BusinessManager.h | 71 + .../tdlib/td/td/telegram/BusinessRecipients.cpp | 187 + .../tdlib/td/td/telegram/BusinessRecipients.h | 67 + .../tdlib/td/td/telegram/BusinessRecipients.hpp | 58 + .../tdlib/td/td/telegram/BusinessWorkHours.cpp | 251 + .../tdlib/td/td/telegram/BusinessWorkHours.h | 91 + .../tdlib/td/td/telegram/BusinessWorkHours.hpp | 43 + .../Telegram/tdlib/td/td/telegram/CallActor.cpp | 90 +- .../Telegram/tdlib/td/td/telegram/CallActor.h | 17 +- .../Telegram/tdlib/td/td/telegram/CallManager.cpp | 29 +- .../Telegram/tdlib/td/td/telegram/CallManager.h | 9 +- .../td/td/telegram/CallbackQueriesManager.cpp | 108 +- .../tdlib/td/td/telegram/CallbackQueriesManager.h | 13 +- protocols/Telegram/tdlib/td/td/telegram/ChainId.h | 13 +- .../td/telegram/ChannelRecommendationManager.cpp | 541 + .../td/td/telegram/ChannelRecommendationManager.h | 108 + .../Telegram/tdlib/td/td/telegram/ChatManager.cpp | 8971 ++ .../Telegram/tdlib/td/td/telegram/ChatManager.h | 955 + .../tdlib/td/td/telegram/ChatReactions.cpp | 126 +- .../Telegram/tdlib/td/td/telegram/ChatReactions.h | 66 +- .../tdlib/td/td/telegram/ChatReactions.hpp | 55 + protocols/Telegram/tdlib/td/td/telegram/Client.cpp | 11 +- .../Telegram/tdlib/td/td/telegram/ClientActor.cpp | 5 +- .../Telegram/tdlib/td/td/telegram/ClientJson.cpp | 7 +- .../tdlib/td/td/telegram/CommonDialogManager.cpp | 225 + .../tdlib/td/td/telegram/CommonDialogManager.h | 59 + .../tdlib/td/td/telegram/ConfigManager.cpp | 632 +- .../Telegram/tdlib/td/td/telegram/ConfigManager.h | 36 +- .../td/td/telegram/ConnectionStateManager.cpp | 61 + .../tdlib/td/td/telegram/ConnectionStateManager.h | 39 + .../Telegram/tdlib/td/td/telegram/Contact.cpp | 24 +- protocols/Telegram/tdlib/td/td/telegram/Contact.h | 16 +- .../tdlib/td/td/telegram/ContactsManager.cpp | 19107 --- .../tdlib/td/td/telegram/ContactsManager.h | 2051 - .../tdlib/td/td/telegram/CountryInfoManager.cpp | 29 +- .../tdlib/td/td/telegram/CountryInfoManager.h | 4 +- .../Telegram/tdlib/td/td/telegram/Dependencies.cpp | 57 +- .../Telegram/tdlib/td/td/telegram/Dependencies.h | 8 +- .../tdlib/td/td/telegram/DeviceTokenManager.cpp | 13 +- .../Telegram/tdlib/td/td/telegram/DialogAction.cpp | 19 +- .../tdlib/td/td/telegram/DialogActionBar.cpp | 23 +- .../tdlib/td/td/telegram/DialogActionManager.cpp | 427 + .../tdlib/td/td/telegram/DialogActionManager.h | 80 + .../tdlib/td/td/telegram/DialogAdministrator.cpp | 10 +- .../tdlib/td/td/telegram/DialogAdministrator.h | 7 +- .../tdlib/td/td/telegram/DialogBoostLinkInfo.h | 21 + .../Telegram/tdlib/td/td/telegram/DialogDate.h | 4 +- .../Telegram/tdlib/td/td/telegram/DialogDb.cpp | 18 +- .../tdlib/td/td/telegram/DialogEventLog.cpp | 172 +- .../Telegram/tdlib/td/td/telegram/DialogFilter.cpp | 112 +- .../Telegram/tdlib/td/td/telegram/DialogFilter.h | 12 +- .../Telegram/tdlib/td/td/telegram/DialogFilter.hpp | 16 +- .../td/td/telegram/DialogFilterInviteLink.cpp | 8 +- .../tdlib/td/td/telegram/DialogFilterManager.cpp | 229 +- .../tdlib/td/td/telegram/DialogFilterManager.h | 14 +- .../Telegram/tdlib/td/td/telegram/DialogId.cpp | 9 +- protocols/Telegram/tdlib/td/td/telegram/DialogId.h | 4 +- .../tdlib/td/td/telegram/DialogInviteLink.cpp | 42 +- .../tdlib/td/td/telegram/DialogInviteLink.h | 101 +- .../tdlib/td/td/telegram/DialogInviteLink.hpp | 126 + .../td/td/telegram/DialogInviteLinkManager.cpp | 1132 + .../tdlib/td/td/telegram/DialogInviteLinkManager.h | 144 + .../Telegram/tdlib/td/td/telegram/DialogListId.h | 14 +- .../tdlib/td/td/telegram/DialogLocation.cpp | 30 +- .../Telegram/tdlib/td/td/telegram/DialogLocation.h | 12 +- .../tdlib/td/td/telegram/DialogManager.cpp | 2349 + .../Telegram/tdlib/td/td/telegram/DialogManager.h | 299 + .../td/td/telegram/DialogNotificationSettings.cpp | 109 +- .../td/td/telegram/DialogNotificationSettings.h | 20 +- .../td/td/telegram/DialogNotificationSettings.hpp | 26 +- .../tdlib/td/td/telegram/DialogParticipant.cpp | 152 +- .../tdlib/td/td/telegram/DialogParticipant.h | 70 +- .../td/td/telegram/DialogParticipantFilter.cpp | 8 +- .../td/td/telegram/DialogParticipantManager.cpp | 3007 + .../td/td/telegram/DialogParticipantManager.h | 319 + .../tdlib/td/td/telegram/DocumentsManager.cpp | 63 +- .../tdlib/td/td/telegram/DocumentsManager.h | 9 +- .../tdlib/td/td/telegram/DownloadManager.cpp | 75 +- .../Telegram/tdlib/td/td/telegram/DraftMessage.cpp | 400 +- .../Telegram/tdlib/td/td/telegram/DraftMessage.h | 58 +- .../Telegram/tdlib/td/td/telegram/DraftMessage.hpp | 65 +- .../Telegram/tdlib/td/td/telegram/EmojiGroup.cpp | 46 +- .../Telegram/tdlib/td/td/telegram/EmojiGroup.h | 8 +- .../Telegram/tdlib/td/td/telegram/EmojiGroup.hpp | 27 +- .../tdlib/td/td/telegram/EmojiGroupType.cpp | 6 +- .../Telegram/tdlib/td/td/telegram/EmojiGroupType.h | 6 +- .../Telegram/tdlib/td/td/telegram/EmojiStatus.cpp | 98 +- .../Telegram/tdlib/td/td/telegram/EmojiStatus.h | 10 +- .../Telegram/tdlib/td/td/telegram/FactCheck.cpp | 68 + .../Telegram/tdlib/td/td/telegram/FactCheck.h | 66 + .../Telegram/tdlib/td/td/telegram/FactCheck.hpp | 55 + .../tdlib/td/td/telegram/FileReferenceManager.cpp | 144 +- .../tdlib/td/td/telegram/FileReferenceManager.h | 40 +- .../tdlib/td/td/telegram/FileReferenceManager.hpp | 72 +- protocols/Telegram/tdlib/td/td/telegram/FolderId.h | 10 +- .../Telegram/tdlib/td/td/telegram/ForumTopic.cpp | 6 +- .../tdlib/td/td/telegram/ForumTopicInfo.cpp | 9 +- .../tdlib/td/td/telegram/ForumTopicManager.cpp | 128 +- .../tdlib/td/td/telegram/ForumTopicManager.h | 5 +- .../Telegram/tdlib/td/td/telegram/FullMessageId.h | 74 - protocols/Telegram/tdlib/td/td/telegram/Game.cpp | 21 +- protocols/Telegram/tdlib/td/td/telegram/Game.h | 8 +- .../Telegram/tdlib/td/td/telegram/GameManager.cpp | 172 +- .../Telegram/tdlib/td/td/telegram/GameManager.h | 16 +- .../tdlib/td/td/telegram/GitCommitHash.cpp | 2 +- .../tdlib/td/td/telegram/GiveawayParameters.cpp | 202 + .../tdlib/td/td/telegram/GiveawayParameters.h | 94 + .../tdlib/td/td/telegram/GiveawayParameters.hpp | 65 + protocols/Telegram/tdlib/td/td/telegram/Global.cpp | 29 +- protocols/Telegram/tdlib/td/td/telegram/Global.h | 243 +- .../tdlib/td/td/telegram/GlobalPrivacySettings.cpp | 189 + .../tdlib/td/td/telegram/GlobalPrivacySettings.h | 52 + .../tdlib/td/td/telegram/GroupCallManager.cpp | 142 +- .../tdlib/td/td/telegram/GroupCallParticipant.cpp | 3 +- .../tdlib/td/td/telegram/GroupCallVideoPayload.cpp | 4 +- .../Telegram/tdlib/td/td/telegram/HashtagHints.cpp | 40 +- .../Telegram/tdlib/td/td/telegram/HashtagHints.h | 13 +- .../tdlib/td/td/telegram/InlineMessageManager.cpp | 387 + .../tdlib/td/td/telegram/InlineMessageManager.h | 61 + .../tdlib/td/td/telegram/InlineQueriesManager.cpp | 404 +- .../tdlib/td/td/telegram/InlineQueriesManager.h | 38 +- .../tdlib/td/td/telegram/InputBusinessChatLink.cpp | 50 + .../tdlib/td/td/telegram/InputBusinessChatLink.h | 36 + .../tdlib/td/td/telegram/InputDialogId.cpp | 21 +- .../Telegram/tdlib/td/td/telegram/InputDialogId.h | 4 +- .../Telegram/tdlib/td/td/telegram/InputInvoice.cpp | 100 +- .../Telegram/tdlib/td/td/telegram/InputInvoice.h | 15 +- .../Telegram/tdlib/td/td/telegram/InputInvoice.hpp | 13 +- .../tdlib/td/td/telegram/InputMessageText.cpp | 80 +- .../tdlib/td/td/telegram/InputMessageText.h | 36 +- .../tdlib/td/td/telegram/InputMessageText.hpp | 28 +- .../Telegram/tdlib/td/td/telegram/JsonValue.cpp | 24 +- .../tdlib/td/td/telegram/LanguagePackManager.cpp | 81 +- .../Telegram/tdlib/td/td/telegram/LinkManager.cpp | 821 +- .../Telegram/tdlib/td/td/telegram/LinkManager.h | 24 +- .../Telegram/tdlib/td/td/telegram/Location.cpp | 40 +- protocols/Telegram/tdlib/td/td/telegram/Location.h | 12 +- .../Telegram/tdlib/td/td/telegram/LogDotNet.cpp | 64 - .../Telegram/tdlib/td/td/telegram/MediaArea.cpp | 388 + .../Telegram/tdlib/td/td/telegram/MediaArea.h | 103 + .../Telegram/tdlib/td/td/telegram/MediaArea.hpp | 162 + .../tdlib/td/td/telegram/MediaAreaCoordinates.cpp | 84 + .../tdlib/td/td/telegram/MediaAreaCoordinates.h | 59 + .../tdlib/td/td/telegram/MediaAreaCoordinates.hpp | 56 + .../tdlib/td/td/telegram/MessageContent.cpp | 4285 +- .../Telegram/tdlib/td/td/telegram/MessageContent.h | 183 +- .../tdlib/td/td/telegram/MessageContentType.cpp | 427 +- .../tdlib/td/td/telegram/MessageContentType.h | 35 +- .../tdlib/td/td/telegram/MessageCopyOptions.h | 16 +- .../Telegram/tdlib/td/td/telegram/MessageDb.cpp | 82 +- .../Telegram/tdlib/td/td/telegram/MessageDb.h | 20 +- .../tdlib/td/td/telegram/MessageEffectId.h | 65 + .../tdlib/td/td/telegram/MessageEntity.cpp | 913 +- .../Telegram/tdlib/td/td/telegram/MessageEntity.h | 62 +- .../tdlib/td/td/telegram/MessageExtendedMedia.cpp | 304 +- .../tdlib/td/td/telegram/MessageExtendedMedia.h | 35 +- .../tdlib/td/td/telegram/MessageExtendedMedia.hpp | 17 +- .../tdlib/td/td/telegram/MessageForwardInfo.cpp | 278 + .../tdlib/td/td/telegram/MessageForwardInfo.h | 179 + .../tdlib/td/td/telegram/MessageForwardInfo.hpp | 105 + .../Telegram/tdlib/td/td/telegram/MessageFullId.h | 75 + .../tdlib/td/td/telegram/MessageImportManager.cpp | 575 + .../tdlib/td/td/telegram/MessageImportManager.h | 112 + .../tdlib/td/td/telegram/MessageInputReplyTo.cpp | 174 + .../tdlib/td/td/telegram/MessageInputReplyTo.h | 114 + .../tdlib/td/td/telegram/MessageInputReplyTo.hpp | 87 + .../tdlib/td/td/telegram/MessageOrigin.cpp | 172 + .../Telegram/tdlib/td/td/telegram/MessageOrigin.h | 101 + .../tdlib/td/td/telegram/MessageOrigin.hpp | 79 + .../Telegram/tdlib/td/td/telegram/MessageQuote.cpp | 238 + .../Telegram/tdlib/td/td/telegram/MessageQuote.h | 85 + .../Telegram/tdlib/td/td/telegram/MessageQuote.hpp | 50 + .../tdlib/td/td/telegram/MessageReaction.cpp | 984 +- .../tdlib/td/td/telegram/MessageReaction.h | 142 +- .../tdlib/td/td/telegram/MessageReaction.hpp | 52 +- .../tdlib/td/td/telegram/MessageReactor.cpp | 102 + .../Telegram/tdlib/td/td/telegram/MessageReactor.h | 86 + .../tdlib/td/td/telegram/MessageReactor.hpp | 46 + .../tdlib/td/td/telegram/MessageReplyHeader.cpp | 74 +- .../tdlib/td/td/telegram/MessageReplyHeader.h | 20 +- .../tdlib/td/td/telegram/MessageReplyInfo.cpp | 33 +- .../tdlib/td/td/telegram/MessageSearchOffset.cpp | 69 + .../tdlib/td/td/telegram/MessageSearchOffset.h | 30 + .../td/td/telegram/MessageSelfDestructType.cpp | 90 + .../tdlib/td/td/telegram/MessageSelfDestructType.h | 74 + .../tdlib/td/td/telegram/MessageSender.cpp | 48 +- .../tdlib/td/td/telegram/MessageSource.cpp | 6 +- .../Telegram/tdlib/td/td/telegram/MessageSource.h | 3 +- .../tdlib/td/td/telegram/MessageViewer.cpp | 37 +- .../Telegram/tdlib/td/td/telegram/MessageViewer.h | 24 +- .../Telegram/tdlib/td/td/telegram/MessagesInfo.cpp | 10 +- .../tdlib/td/td/telegram/MessagesManager.cpp | 16565 ++- .../tdlib/td/td/telegram/MessagesManager.h | 1485 +- .../Telegram/tdlib/td/td/telegram/MinChannel.h | 4 +- .../Telegram/tdlib/td/td/telegram/MinChannel.hpp | 12 +- .../tdlib/td/td/telegram/MissingInvitee.cpp | 57 + .../Telegram/tdlib/td/td/telegram/MissingInvitee.h | 54 + .../Telegram/tdlib/td/td/telegram/Notification.h | 6 +- .../td/td/telegram/NotificationGroupFromDatabase.h | 24 + .../tdlib/td/td/telegram/NotificationGroupInfo.cpp | 133 + .../tdlib/td/td/telegram/NotificationGroupInfo.h | 87 + .../tdlib/td/td/telegram/NotificationGroupInfo.hpp | 39 + .../tdlib/td/td/telegram/NotificationGroupType.cpp | 88 + .../tdlib/td/td/telegram/NotificationGroupType.h | 57 +- .../tdlib/td/td/telegram/NotificationManager.cpp | 934 +- .../tdlib/td/td/telegram/NotificationManager.h | 42 +- .../td/td/telegram/NotificationObjectFullId.h | 60 + .../tdlib/td/td/telegram/NotificationObjectId.h | 83 + .../td/td/telegram/NotificationSettingsManager.cpp | 401 +- .../td/td/telegram/NotificationSettingsManager.h | 39 +- .../tdlib/td/td/telegram/NotificationSound.cpp | 19 +- .../tdlib/td/td/telegram/NotificationSound.h | 8 +- .../tdlib/td/td/telegram/NotificationType.cpp | 106 +- .../tdlib/td/td/telegram/NotificationType.h | 8 +- .../tdlib/td/td/telegram/OnlineManager.cpp | 164 + .../Telegram/tdlib/td/td/telegram/OnlineManager.h | 60 + .../tdlib/td/td/telegram/OptionManager.cpp | 454 +- .../Telegram/tdlib/td/td/telegram/OptionManager.h | 4 +- .../Telegram/tdlib/td/td/telegram/OrderInfo.cpp | 14 +- .../tdlib/td/td/telegram/OrderedMessage.cpp | 21 +- .../Telegram/tdlib/td/td/telegram/OrderedMessage.h | 12 +- .../tdlib/td/td/telegram/PasswordManager.cpp | 120 +- .../tdlib/td/td/telegram/PasswordManager.h | 3 +- .../Telegram/tdlib/td/td/telegram/Payments.cpp | 520 +- protocols/Telegram/tdlib/td/td/telegram/Payments.h | 9 +- .../Telegram/tdlib/td/td/telegram/PeerColor.cpp | 33 + .../Telegram/tdlib/td/td/telegram/PeerColor.h | 22 + .../tdlib/td/td/telegram/PeopleNearbyManager.cpp | 450 + .../tdlib/td/td/telegram/PeopleNearbyManager.h | 105 + .../tdlib/td/td/telegram/PhoneNumberManager.cpp | 448 +- .../tdlib/td/td/telegram/PhoneNumberManager.h | 70 +- protocols/Telegram/tdlib/td/td/telegram/Photo.cpp | 120 +- protocols/Telegram/tdlib/td/td/telegram/Photo.h | 12 +- .../Telegram/tdlib/td/td/telegram/PhotoSize.cpp | 30 +- .../tdlib/td/td/telegram/PhotoSizeSource.cpp | 144 +- .../tdlib/td/td/telegram/PhotoSizeSource.h | 16 +- .../tdlib/td/td/telegram/PhotoSizeSource.hpp | 14 +- .../Telegram/tdlib/td/td/telegram/PollManager.cpp | 498 +- .../Telegram/tdlib/td/td/telegram/PollManager.h | 70 +- .../Telegram/tdlib/td/td/telegram/PollManager.hpp | 118 +- .../Telegram/tdlib/td/td/telegram/Premium.cpp | 702 +- protocols/Telegram/tdlib/td/td/telegram/Premium.h | 26 +- .../tdlib/td/td/telegram/PrivacyManager.cpp | 585 +- .../Telegram/tdlib/td/td/telegram/PrivacyManager.h | 150 +- .../tdlib/td/td/telegram/PromoDataManager.cpp | 148 + .../tdlib/td/td/telegram/PromoDataManager.h | 47 + .../tdlib/td/td/telegram/PublicDialogType.h | 4 +- .../Telegram/tdlib/td/td/telegram/QueryMerger.cpp | 6 +- .../Telegram/tdlib/td/td/telegram/QueryMerger.h | 4 +- .../tdlib/td/td/telegram/QuickReplyManager.cpp | 3737 + .../tdlib/td/td/telegram/QuickReplyManager.h | 479 + .../tdlib/td/td/telegram/QuickReplyMessageFullId.h | 79 + .../tdlib/td/td/telegram/QuickReplyShortcutId.h | 94 + .../tdlib/td/td/telegram/ReactionListType.cpp | 39 + .../tdlib/td/td/telegram/ReactionListType.h | 22 + .../tdlib/td/td/telegram/ReactionManager.cpp | 1489 + .../tdlib/td/td/telegram/ReactionManager.h | 339 + .../tdlib/td/td/telegram/ReactionManager.hpp | 220 + .../td/telegram/ReactionNotificationSettings.cpp | 75 + .../td/td/telegram/ReactionNotificationSettings.h | 60 + .../td/telegram/ReactionNotificationSettings.hpp | 45 + .../td/td/telegram/ReactionNotificationsFrom.cpp | 98 + .../td/td/telegram/ReactionNotificationsFrom.h | 52 + .../td/td/telegram/ReactionNotificationsFrom.hpp | 29 + .../Telegram/tdlib/td/td/telegram/ReactionType.cpp | 236 + .../Telegram/tdlib/td/td/telegram/ReactionType.h | 101 + .../Telegram/tdlib/td/td/telegram/ReactionType.hpp | 27 + .../td/td/telegram/ReactionUnavailabilityReason.h | 15 + .../tdlib/td/td/telegram/RecentDialogList.cpp | 52 +- .../tdlib/td/td/telegram/RecentDialogList.h | 5 +- .../tdlib/td/td/telegram/RepliedMessageInfo.cpp | 391 + .../tdlib/td/td/telegram/RepliedMessageInfo.h | 121 + .../tdlib/td/td/telegram/RepliedMessageInfo.hpp | 110 + .../Telegram/tdlib/td/td/telegram/ReplyMarkup.cpp | 107 +- .../Telegram/tdlib/td/td/telegram/ReplyMarkup.h | 23 +- .../Telegram/tdlib/td/td/telegram/ReportReason.cpp | 24 +- .../Telegram/tdlib/td/td/telegram/ReportReason.h | 4 +- .../tdlib/td/td/telegram/RequestedDialogType.cpp | 84 +- .../tdlib/td/td/telegram/RequestedDialogType.h | 19 +- .../tdlib/td/td/telegram/RequestedDialogType.hpp | 14 +- .../Telegram/tdlib/td/td/telegram/Requests.cpp | 7836 ++ protocols/Telegram/tdlib/td/td/telegram/Requests.h | 1692 + .../tdlib/td/td/telegram/RestrictionReason.cpp | 35 +- .../tdlib/td/td/telegram/RestrictionReason.h | 11 +- .../tdlib/td/td/telegram/SavedMessagesManager.cpp | 1053 + .../tdlib/td/td/telegram/SavedMessagesManager.h | 203 + .../tdlib/td/td/telegram/SavedMessagesTopicId.cpp | 126 + .../tdlib/td/td/telegram/SavedMessagesTopicId.h | 92 + .../td/td/telegram/ScopeNotificationSettings.cpp | 50 +- .../td/td/telegram/ScopeNotificationSettings.h | 14 +- .../td/td/telegram/ScopeNotificationSettings.hpp | 21 +- .../tdlib/td/td/telegram/SecretChatActor.cpp | 48 +- .../tdlib/td/td/telegram/SecretChatActor.h | 8 +- .../tdlib/td/td/telegram/SecretChatsManager.cpp | 64 +- .../tdlib/td/td/telegram/SecureManager.cpp | 9 +- .../tdlib/td/td/telegram/SecureStorage.cpp | 12 +- .../Telegram/tdlib/td/td/telegram/SecureValue.cpp | 56 +- .../tdlib/td/td/telegram/SendCodeHelper.cpp | 91 +- .../Telegram/tdlib/td/td/telegram/SendCodeHelper.h | 31 +- .../tdlib/td/td/telegram/SendCodeHelper.hpp | 4 +- .../Telegram/tdlib/td/td/telegram/SharedDialog.cpp | 83 + .../Telegram/tdlib/td/td/telegram/SharedDialog.h | 71 + .../Telegram/tdlib/td/td/telegram/SharedDialog.hpp | 70 + .../tdlib/td/td/telegram/SpecialStickerSetType.cpp | 12 +- .../tdlib/td/td/telegram/SpecialStickerSetType.h | 4 +- .../td/td/telegram/SponsoredMessageManager.cpp | 362 +- .../tdlib/td/td/telegram/SponsoredMessageManager.h | 11 +- .../Telegram/tdlib/td/td/telegram/StarManager.cpp | 997 + .../Telegram/tdlib/td/td/telegram/StarManager.h | 107 + .../tdlib/td/td/telegram/StarSubscription.cpp | 41 + .../tdlib/td/td/telegram/StarSubscription.h | 47 + .../td/td/telegram/StarSubscriptionPricing.cpp | 58 + .../tdlib/td/td/telegram/StarSubscriptionPricing.h | 55 + .../td/td/telegram/StarSubscriptionPricing.hpp | 32 + .../Telegram/tdlib/td/td/telegram/StateManager.cpp | 10 +- .../tdlib/td/td/telegram/StatisticsManager.cpp | 1008 + .../tdlib/td/td/telegram/StatisticsManager.h | 98 + .../tdlib/td/td/telegram/StickerListType.cpp | 43 + .../tdlib/td/td/telegram/StickerListType.h | 22 + .../tdlib/td/td/telegram/StickersManager.cpp | 2115 +- .../tdlib/td/td/telegram/StickersManager.h | 328 +- .../tdlib/td/td/telegram/StickersManager.hpp | 179 +- .../Telegram/tdlib/td/td/telegram/StoryContent.cpp | 538 + .../Telegram/tdlib/td/td/telegram/StoryContent.h | 75 + .../tdlib/td/td/telegram/StoryContentType.cpp | 24 + .../tdlib/td/td/telegram/StoryContentType.h | 26 + .../Telegram/tdlib/td/td/telegram/StoryDb.cpp | 569 + protocols/Telegram/tdlib/td/td/telegram/StoryDb.h | 133 + .../tdlib/td/td/telegram/StoryForwardInfo.cpp | 71 + .../tdlib/td/td/telegram/StoryForwardInfo.h | 60 + .../tdlib/td/td/telegram/StoryForwardInfo.hpp | 62 + .../Telegram/tdlib/td/td/telegram/StoryFullId.h | 77 + protocols/Telegram/tdlib/td/td/telegram/StoryId.h | 90 + .../tdlib/td/td/telegram/StoryInteractionInfo.cpp | 154 + .../tdlib/td/td/telegram/StoryInteractionInfo.h | 97 + .../tdlib/td/td/telegram/StoryInteractionInfo.hpp | 82 + .../Telegram/tdlib/td/td/telegram/StoryListId.h | 95 + .../Telegram/tdlib/td/td/telegram/StoryManager.cpp | 6016 + .../Telegram/tdlib/td/td/telegram/StoryManager.h | 753 + .../td/td/telegram/StoryNotificationSettings.h | 31 + .../tdlib/td/td/telegram/StoryStealthMode.cpp | 63 + .../tdlib/td/td/telegram/StoryStealthMode.h | 55 + .../tdlib/td/td/telegram/StoryStealthMode.hpp | 50 + .../Telegram/tdlib/td/td/telegram/StoryViewer.cpp | 229 + .../Telegram/tdlib/td/td/telegram/StoryViewer.h | 84 + .../tdlib/td/td/telegram/SuggestedAction.cpp | 66 +- .../tdlib/td/td/telegram/SuggestedAction.h | 19 +- .../tdlib/td/td/telegram/SuggestedAction.hpp | 50 + .../Telegram/tdlib/td/td/telegram/Support.cpp | 22 +- .../tdlib/td/td/telegram/SynchronousRequests.cpp | 400 + .../tdlib/td/td/telegram/SynchronousRequests.h | 89 + protocols/Telegram/tdlib/td/td/telegram/Td.cpp | 9774 +- protocols/Telegram/tdlib/td/td/telegram/Td.h | 1463 +- protocols/Telegram/tdlib/td/td/telegram/TdDb.cpp | 117 +- protocols/Telegram/tdlib/td/td/telegram/TdDb.h | 23 +- .../tdlib/td/td/telegram/TermsOfService.cpp | 106 +- .../Telegram/tdlib/td/td/telegram/TermsOfService.h | 42 +- .../tdlib/td/td/telegram/TermsOfService.hpp | 40 + .../tdlib/td/td/telegram/TermsOfServiceManager.cpp | 201 + .../tdlib/td/td/telegram/TermsOfServiceManager.h | 59 + .../Telegram/tdlib/td/td/telegram/ThemeManager.cpp | 884 +- .../Telegram/tdlib/td/td/telegram/ThemeManager.h | 142 +- .../tdlib/td/td/telegram/ThemeSettings.cpp | 46 + .../Telegram/tdlib/td/td/telegram/ThemeSettings.h | 58 + .../tdlib/td/td/telegram/ThemeSettings.hpp | 59 + .../tdlib/td/td/telegram/TimeZoneManager.cpp | 206 + .../tdlib/td/td/telegram/TimeZoneManager.h | 91 + .../tdlib/td/td/telegram/TopDialogCategory.cpp | 10 +- .../tdlib/td/td/telegram/TopDialogCategory.h | 3 +- .../tdlib/td/td/telegram/TopDialogManager.cpp | 126 +- .../tdlib/td/td/telegram/TopDialogManager.h | 8 +- .../tdlib/td/td/telegram/TranscriptionInfo.cpp | 51 +- .../tdlib/td/td/telegram/TranscriptionInfo.h | 10 +- .../tdlib/td/td/telegram/TranscriptionManager.cpp | 444 + .../tdlib/td/td/telegram/TranscriptionManager.h | 135 + .../tdlib/td/td/telegram/TranslationManager.cpp | 27 +- .../tdlib/td/td/telegram/UpdatesManager.cpp | 1500 +- .../Telegram/tdlib/td/td/telegram/UpdatesManager.h | 175 +- protocols/Telegram/tdlib/td/td/telegram/UserId.h | 9 +- .../Telegram/tdlib/td/td/telegram/UserManager.cpp | 8135 ++ .../Telegram/tdlib/td/td/telegram/UserManager.h | 1130 + .../tdlib/td/td/telegram/UserPrivacySetting.cpp | 160 + .../tdlib/td/td/telegram/UserPrivacySetting.h | 52 + .../td/td/telegram/UserPrivacySettingRule.cpp | 404 + .../tdlib/td/td/telegram/UserPrivacySettingRule.h | 154 + protocols/Telegram/tdlib/td/td/telegram/Venue.cpp | 14 +- protocols/Telegram/tdlib/td/td/telegram/Venue.h | 15 +- protocols/Telegram/tdlib/td/td/telegram/Version.h | 21 +- .../tdlib/td/td/telegram/VideoNotesManager.cpp | 180 +- .../tdlib/td/td/telegram/VideoNotesManager.h | 30 +- .../tdlib/td/td/telegram/VideosManager.cpp | 140 +- .../Telegram/tdlib/td/td/telegram/VideosManager.h | 16 +- .../tdlib/td/td/telegram/VideosManager.hpp | 36 +- .../tdlib/td/td/telegram/VoiceNotesManager.cpp | 195 +- .../tdlib/td/td/telegram/VoiceNotesManager.h | 30 +- protocols/Telegram/tdlib/td/td/telegram/WebApp.cpp | 3 +- .../Telegram/tdlib/td/td/telegram/WebPageBlock.cpp | 122 +- .../Telegram/tdlib/td/td/telegram/WebPageBlock.h | 4 +- .../Telegram/tdlib/td/td/telegram/WebPageId.h | 4 +- .../tdlib/td/td/telegram/WebPagesManager.cpp | 1551 +- .../tdlib/td/td/telegram/WebPagesManager.h | 82 +- protocols/Telegram/tdlib/td/td/telegram/cli.cpp | 2330 +- .../td/td/telegram/files/FileDownloadManager.cpp | 199 + .../td/td/telegram/files/FileDownloadManager.h | 128 + .../tdlib/td/td/telegram/files/FileDownloader.cpp | 499 +- .../tdlib/td/td/telegram/files/FileDownloader.h | 101 +- .../tdlib/td/td/telegram/files/FileFromBytes.h | 20 +- .../td/td/telegram/files/FileGenerateManager.cpp | 27 +- .../td/td/telegram/files/FileGenerateManager.h | 19 +- .../td/td/telegram/files/FileHashUploader.cpp | 7 +- .../tdlib/td/td/telegram/files/FileHashUploader.h | 34 +- .../tdlib/td/td/telegram/files/FileLoadManager.cpp | 289 +- .../tdlib/td/td/telegram/files/FileLoadManager.h | 154 +- .../tdlib/td/td/telegram/files/FileLoader.cpp | 363 - .../tdlib/td/td/telegram/files/FileLoader.h | 143 - .../tdlib/td/td/telegram/files/FileLoaderActor.h | 9 +- .../tdlib/td/td/telegram/files/FileLoaderUtils.cpp | 8 +- .../tdlib/td/td/telegram/files/FileLocation.h | 73 +- .../tdlib/td/td/telegram/files/FileLocation.hpp | 6 +- .../tdlib/td/td/telegram/files/FileManager.cpp | 1927 +- .../tdlib/td/td/telegram/files/FileManager.h | 366 +- .../tdlib/td/td/telegram/files/FileManager.hpp | 30 +- .../tdlib/td/td/telegram/files/FileStats.cpp | 22 +- .../tdlib/td/td/telegram/files/FileStats.h | 4 +- .../tdlib/td/td/telegram/files/FileStatsWorker.cpp | 19 +- .../tdlib/td/td/telegram/files/FileType.cpp | 70 +- .../Telegram/tdlib/td/td/telegram/files/FileType.h | 8 +- .../td/td/telegram/files/FileUploadManager.cpp | 200 + .../tdlib/td/td/telegram/files/FileUploadManager.h | 123 + .../tdlib/td/td/telegram/files/FileUploader.cpp | 296 +- .../tdlib/td/td/telegram/files/FileUploader.h | 94 +- .../tdlib/td/td/telegram/files/ResourceManager.h | 3 +- .../tdlib/td/td/telegram/logevent/LogEvent.h | 24 +- .../td/td/telegram/logevent/SecretChatEvent.h | 8 +- protocols/Telegram/tdlib/td/td/telegram/misc.cpp | 80 +- protocols/Telegram/tdlib/td/td/telegram/misc.h | 12 +- .../tdlib/td/td/telegram/net/AuthDataShared.cpp | 39 +- .../tdlib/td/td/telegram/net/AuthDataShared.h | 11 +- .../tdlib/td/td/telegram/net/ConnectionCreator.h | 67 +- .../tdlib/td/td/telegram/net/DcAuthManager.cpp | 52 +- .../tdlib/td/td/telegram/net/DcAuthManager.h | 7 +- protocols/Telegram/tdlib/td/td/telegram/net/DcId.h | 6 +- .../tdlib/td/td/telegram/net/DcOptionsSet.cpp | 35 +- .../tdlib/td/td/telegram/net/DcOptionsSet.h | 25 +- .../tdlib/td/td/telegram/net/MtprotoHeader.cpp | 12 +- .../tdlib/td/td/telegram/net/MtprotoHeader.h | 27 +- .../Telegram/tdlib/td/td/telegram/net/NetQuery.cpp | 91 +- .../Telegram/tdlib/td/td/telegram/net/NetQuery.h | 107 +- .../tdlib/td/td/telegram/net/NetQueryCreator.cpp | 49 +- .../tdlib/td/td/telegram/net/NetQueryCreator.h | 13 +- .../tdlib/td/td/telegram/net/NetQueryDelayer.cpp | 27 +- .../td/td/telegram/net/NetQueryDispatcher.cpp | 177 +- .../tdlib/td/td/telegram/net/NetQueryDispatcher.h | 16 +- .../tdlib/td/td/telegram/net/NetQueryStats.h | 4 +- .../tdlib/td/td/telegram/net/NetQueryVerifier.cpp | 98 + .../tdlib/td/td/telegram/net/NetQueryVerifier.h | 39 + .../tdlib/td/td/telegram/net/NetStatsManager.cpp | 10 +- .../tdlib/td/td/telegram/net/NetStatsManager.h | 5 +- .../td/td/telegram/net/PublicRsaKeyShared.cpp | 113 - .../tdlib/td/td/telegram/net/PublicRsaKeyShared.h | 56 - .../td/td/telegram/net/PublicRsaKeySharedCdn.cpp | 75 + .../td/td/telegram/net/PublicRsaKeySharedCdn.h | 59 + .../td/td/telegram/net/PublicRsaKeySharedMain.cpp | 70 + .../td/td/telegram/net/PublicRsaKeySharedMain.h | 33 + .../td/td/telegram/net/PublicRsaKeyWatchdog.cpp | 8 +- .../td/td/telegram/net/PublicRsaKeyWatchdog.h | 11 +- .../Telegram/tdlib/td/td/telegram/net/Session.cpp | 344 +- .../Telegram/tdlib/td/td/telegram/net/Session.h | 85 +- .../tdlib/td/td/telegram/net/SessionMultiProxy.cpp | 77 +- .../tdlib/td/td/telegram/net/SessionMultiProxy.h | 9 +- .../tdlib/td/td/telegram/net/SessionProxy.cpp | 47 +- .../tdlib/td/td/telegram/net/SessionProxy.h | 13 +- .../tdlib/td/td/telegram/net/TempAuthKeyWatchdog.h | 19 +- protocols/Telegram/tdlib/td/td/tl/TlObject.h | 10 +- .../Telegram/tdlib/td/td/tl/tl_jni_object.cpp | 25 +- protocols/Telegram/tdlib/td/td/tl/tl_jni_object.h | 8 +- protocols/Telegram/tdlib/td/td/tl/tl_json.h | 4 +- .../Telegram/tdlib/td/td/tl/tl_object_parse.h | 10 +- protocols/Telegram/tdlib/td/tdactor/CMakeLists.txt | 9 +- .../tdlib/td/tdactor/td/actor/PromiseFuture.h | 20 +- .../tdlib/td/tdactor/td/actor/impl/Actor-decl.h | 5 +- .../tdlib/td/tdactor/td/actor/impl/Actor.h | 6 +- .../tdlib/td/tdactor/td/actor/impl/Event.h | 8 +- .../td/tdactor/td/actor/impl/EventFull-decl.h | 6 +- .../td/tdactor/td/actor/impl/Scheduler-decl.h | 50 +- .../tdlib/td/tdactor/td/actor/impl/Scheduler.cpp | 63 +- .../tdlib/td/tdactor/td/actor/impl/Scheduler.h | 95 +- .../Telegram/tdlib/td/tdactor/test/actors_main.cpp | 11 +- .../tdlib/td/tdactor/test/actors_simple.cpp | 6 +- protocols/Telegram/tdlib/td/tddb/CMakeLists.txt | 7 +- .../Telegram/tdlib/td/tddb/td/db/BinlogKeyValue.h | 38 +- .../tdlib/td/tddb/td/db/KeyValueSyncInterface.h | 10 +- .../Telegram/tdlib/td/tddb/td/db/SeqKeyValue.h | 20 +- protocols/Telegram/tdlib/td/tddb/td/db/SqliteDb.h | 3 +- .../Telegram/tdlib/td/tddb/td/db/SqliteKeyValue.h | 17 +- .../tdlib/td/tddb/td/db/SqliteKeyValueSafe.h | 4 +- .../Telegram/tdlib/td/tddb/td/db/TsSeqKeyValue.h | 8 +- .../Telegram/tdlib/td/tddb/td/db/binlog/Binlog.cpp | 20 +- .../Telegram/tdlib/td/tddb/td/db/binlog/Binlog.h | 6 +- .../tdlib/td/tddb/td/db/binlog/BinlogEvent.cpp | 6 +- .../tdlib/td/tddb/td/db/binlog/BinlogInterface.h | 4 +- .../td/tddb/td/db/binlog/ConcurrentBinlog.cpp | 17 +- .../tdlib/td/tddb/td/db/binlog/ConcurrentBinlog.h | 4 +- .../tdlib/td/tddb/td/db/binlog/binlog_dump.cpp | 6 +- protocols/Telegram/tdlib/td/tdnet/CMakeLists.txt | 6 +- .../Telegram/tdlib/td/tdnet/td/net/DarwinHttp.mm | 16 +- .../tdlib/td/tdnet/td/net/GetHostByNameActor.cpp | 7 +- .../tdlib/td/tdnet/td/net/GetHostByNameActor.h | 3 +- .../tdlib/td/tdnet/td/net/HttpChunkedByteFlow.cpp | 15 +- .../tdlib/td/tdnet/td/net/HttpChunkedByteFlow.h | 4 +- .../tdlib/td/tdnet/td/net/HttpConnectionBase.cpp | 4 +- .../Telegram/tdlib/td/tdnet/td/net/HttpProxy.cpp | 7 +- .../Telegram/tdlib/td/tdnet/td/net/HttpReader.cpp | 24 +- .../Telegram/tdlib/td/tdnet/td/net/HttpReader.h | 7 +- .../Telegram/tdlib/td/tdnet/td/net/SslCtx.cpp | 4 +- .../Telegram/tdlib/td/tdnet/td/net/SslStream.cpp | 12 +- protocols/Telegram/tdlib/td/tdnet/td/net/Wget.h | 8 +- protocols/Telegram/tdlib/td/tdtl/CMakeLists.txt | 3 - .../Telegram/tdlib/td/tdtl/td/tl/tl_file_utils.cpp | 21 +- .../Telegram/tdlib/td/tdtl/td/tl/tl_file_utils.h | 6 +- .../Telegram/tdlib/td/tdtl/td/tl/tl_generate.cpp | 366 +- .../Telegram/tdlib/td/tdtl/td/tl/tl_generate.h | 5 +- .../Telegram/tdlib/td/tdtl/td/tl/tl_writer.cpp | 4 +- protocols/Telegram/tdlib/td/tdtl/td/tl/tl_writer.h | 8 +- protocols/Telegram/tdlib/td/tdutils/CMakeLists.txt | 29 +- .../generate/auto/extension_to_mime_type.cpp | 19 +- .../generate/auto/mime_type_to_extension.cpp | 19 +- .../tdlib/td/tdutils/td/utils/BufferedFd.h | 10 +- .../Telegram/tdlib/td/tdutils/td/utils/ByteFlow.h | 4 +- .../tdlib/td/tdutils/td/utils/ChainScheduler.h | 47 +- .../td/tdutils/td/utils/ConcurrentHashTable.h | 5 +- .../Telegram/tdlib/td/tdutils/td/utils/FileLog.cpp | 4 +- .../tdlib/td/tdutils/td/utils/FlatHashMap.h | 4 +- .../tdlib/td/tdutils/td/utils/FlatHashMapChunks.h | 19 +- .../tdlib/td/tdutils/td/utils/FlatHashSet.h | 4 +- .../tdlib/td/tdutils/td/utils/FlatHashTable.h | 14 +- .../tdlib/td/tdutils/td/utils/FloodControlStrict.h | 4 +- .../tdlib/td/tdutils/td/utils/GzipByteFlow.cpp | 7 +- .../tdlib/td/tdutils/td/utils/GzipByteFlow.h | 3 +- .../Telegram/tdlib/td/tdutils/td/utils/Hash.h | 4 +- .../tdlib/td/tdutils/td/utils/HashTableUtils.h | 10 +- .../Telegram/tdlib/td/tdutils/td/utils/Hints.cpp | 4 +- .../tdlib/td/tdutils/td/utils/HttpDate.cpp | 92 + .../Telegram/tdlib/td/tdutils/td/utils/HttpDate.h | 34 + .../tdlib/td/tdutils/td/utils/JsonBuilder.cpp | 367 +- .../tdlib/td/tdutils/td/utils/JsonBuilder.h | 93 +- .../Telegram/tdlib/td/tdutils/td/utils/MapNode.h | 12 +- .../Telegram/tdlib/td/tdutils/td/utils/MpmcQueue.h | 6 +- .../tdlib/td/tdutils/td/utils/ObjectPool.h | 4 +- .../Telegram/tdlib/td/tdutils/td/utils/Promise.h | 4 +- .../Telegram/tdlib/td/tdutils/td/utils/SetNode.h | 12 +- .../tdlib/td/tdutils/td/utils/StringBuilder.cpp | 20 +- .../tdlib/td/tdutils/td/utils/StringBuilder.h | 36 +- .../tdlib/td/tdutils/td/utils/TlStorerToString.h | 140 +- .../tdlib/td/tdutils/td/utils/WaitFreeHashSet.h | 7 +- .../Telegram/tdlib/td/tdutils/td/utils/algorithm.h | 69 +- .../Telegram/tdlib/td/tdutils/td/utils/check.h | 10 +- .../Telegram/tdlib/td/tdutils/td/utils/crypto.cpp | 61 +- .../Telegram/tdlib/td/tdutils/td/utils/emoji.cpp | 4 +- .../tdlib/td/tdutils/td/utils/filesystem.cpp | 6 +- .../tdlib/td/tdutils/td/utils/filesystem.h | 5 +- .../Telegram/tdlib/td/tdutils/td/utils/format.h | 38 +- .../Telegram/tdlib/td/tdutils/td/utils/logging.cpp | 5 +- .../Telegram/tdlib/td/tdutils/td/utils/misc.cpp | 100 +- .../Telegram/tdlib/td/tdutils/td/utils/optional.h | 5 +- .../tdlib/td/tdutils/td/utils/port/FileFd.cpp | 20 +- .../tdlib/td/tdutils/td/utils/port/FromApp.h | 9 +- .../td/tdutils/td/utils/port/ServerSocketFd.cpp | 10 +- .../td/tdutils/td/utils/port/ServerSocketFd.h | 5 +- .../tdlib/td/tdutils/td/utils/port/SocketFd.cpp | 12 +- .../tdlib/td/tdutils/td/utils/port/SocketFd.h | 5 +- .../tdlib/td/tdutils/td/utils/port/UdpSocketFd.cpp | 58 +- .../tdlib/td/tdutils/td/utils/port/UdpSocketFd.h | 4 +- .../td/tdutils/td/utils/port/detail/NativeFd.cpp | 43 +- .../td/tdutils/td/utils/port/detail/NativeFd.h | 7 +- .../tdlib/td/tdutils/td/utils/port/platform.h | 4 +- .../tdlib/td/tdutils/td/utils/port/uname.cpp | 4 +- .../tdlib/td/tdutils/td/utils/tl_parsers.cpp | 22 +- .../tdlib/td/tdutils/td/utils/tl_parsers.h | 23 +- .../Telegram/tdlib/td/tdutils/td/utils/unicode.cpp | 381 +- .../tdlib/td/tdutils/test/ChainScheduler.cpp | 8 +- .../tdlib/td/tdutils/test/ConcurrentHashMap.cpp | 38 +- .../Telegram/tdlib/td/tdutils/test/MpmcWaiter.cpp | 3 +- .../tdlib/td/tdutils/test/StealingQueue.cpp | 12 +- .../tdlib/td/tdutils/test/hashset_benchmark.cpp | 4 +- protocols/Telegram/tdlib/td/tdutils/test/json.cpp | 211 +- protocols/Telegram/tdlib/td/tdutils/test/misc.cpp | 110 +- protocols/Telegram/tdlib/td/tdutils/test/pq.cpp | 6 +- protocols/Telegram/tdlib/tdcore.vcxproj | 6 - protocols/Telegram/tdlib/tdcore.vcxproj.filters | 6 - protocols/Telegram/tdlib/tdlib.vcxproj | 191 +- protocols/Telegram/tdlib/tdlib.vcxproj.filters | 573 +- protocols/Telegram/tdlib/tdutils.vcxproj | 2 + protocols/Telegram/tdlib/tdutils.vcxproj.filters | 2 + 708 files changed, 340261 insertions(+), 147584 deletions(-) create mode 100644 protocols/Telegram/tdlib/td/td/mtproto/MessageId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/AccentColorId.h delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/Account.cpp delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/Account.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/AccountManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/AccountManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/AlarmManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/AlarmManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BaseTheme.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BaseTheme.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/Birthdate.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/Birthdate.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/Birthdate.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BlockListId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BoostManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BoostManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BotQueries.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BotQueries.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessAwayMessage.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessAwayMessage.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessAwayMessage.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessAwayMessageSchedule.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessAwayMessageSchedule.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessAwayMessageSchedule.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessBotManageBar.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessBotManageBar.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessChatLink.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessChatLink.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessConnectedBot.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessConnectedBot.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessConnectedBot.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessConnectionId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessConnectionManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessConnectionManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessGreetingMessage.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessGreetingMessage.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessGreetingMessage.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessInfo.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessInfo.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessInfo.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessIntro.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessIntro.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessIntro.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessRecipients.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessRecipients.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessRecipients.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessWorkHours.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessWorkHours.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/BusinessWorkHours.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ChannelRecommendationManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ChannelRecommendationManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ChatManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ChatManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ChatReactions.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/CommonDialogManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/CommonDialogManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ConnectionStateManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ConnectionStateManager.h delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/ContactsManager.cpp delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/ContactsManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogActionManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogActionManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogBoostLinkInfo.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogInviteLink.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogInviteLinkManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogInviteLinkManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogParticipantManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/DialogParticipantManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/FactCheck.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/FactCheck.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/FactCheck.hpp delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/FullMessageId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/GiveawayParameters.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/GiveawayParameters.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/GiveawayParameters.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/GlobalPrivacySettings.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/GlobalPrivacySettings.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/InlineMessageManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/InlineMessageManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/InputBusinessChatLink.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/InputBusinessChatLink.h delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/LogDotNet.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MediaArea.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MediaArea.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MediaArea.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageEffectId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageFullId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageImportManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageImportManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageQuote.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageQuote.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageQuote.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageReactor.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageReactor.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageReactor.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageSearchOffset.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageSearchOffset.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageSelfDestructType.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MessageSelfDestructType.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MissingInvitee.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/MissingInvitee.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/NotificationGroupFromDatabase.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/NotificationGroupType.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/NotificationObjectFullId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/NotificationObjectId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/OnlineManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/OnlineManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/PeerColor.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/PeerColor.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/PeopleNearbyManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/PeopleNearbyManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/PromoDataManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/PromoDataManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/QuickReplyManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/QuickReplyManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/QuickReplyMessageFullId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/QuickReplyShortcutId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionListType.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionListType.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionManager.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionType.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionType.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionType.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ReactionUnavailabilityReason.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/Requests.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/Requests.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SavedMessagesManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SavedMessagesManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SavedMessagesTopicId.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SavedMessagesTopicId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SharedDialog.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SharedDialog.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SharedDialog.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StarManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StarManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StarSubscription.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StarSubscription.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StatisticsManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StatisticsManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StickerListType.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StickerListType.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryContent.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryContent.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryContentType.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryContentType.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryDb.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryDb.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryFullId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryListId.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryNotificationSettings.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryViewer.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/StoryViewer.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SynchronousRequests.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/SynchronousRequests.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/TermsOfService.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/TermsOfServiceManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/TermsOfServiceManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.hpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/TimeZoneManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/TimeZoneManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/TranscriptionManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/TranscriptionManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/UserManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/UserManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/UserPrivacySetting.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/UserPrivacySetting.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/UserPrivacySettingRule.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/UserPrivacySettingRule.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/files/FileDownloadManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/files/FileDownloadManager.h delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/files/FileLoader.cpp delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/files/FileLoader.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/files/FileUploadManager.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/files/FileUploadManager.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/net/NetQueryVerifier.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/net/NetQueryVerifier.h delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/net/PublicRsaKeyShared.cpp delete mode 100644 protocols/Telegram/tdlib/td/td/telegram/net/PublicRsaKeyShared.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/net/PublicRsaKeySharedCdn.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/net/PublicRsaKeySharedCdn.h create mode 100644 protocols/Telegram/tdlib/td/td/telegram/net/PublicRsaKeySharedMain.cpp create mode 100644 protocols/Telegram/tdlib/td/td/telegram/net/PublicRsaKeySharedMain.h create mode 100644 protocols/Telegram/tdlib/td/tdutils/td/utils/HttpDate.cpp create mode 100644 protocols/Telegram/tdlib/td/tdutils/td/utils/HttpDate.h (limited to 'protocols/Telegram') diff --git a/protocols/Telegram/src/auth.cpp b/protocols/Telegram/src/auth.cpp index 97b0792bb7..0d757d13fe 100644 --- a/protocols/Telegram/src/auth.cpp +++ b/protocols/Telegram/src/auth.cpp @@ -116,7 +116,6 @@ void CTelegramProto::ProcessAuth(TD::updateAuthorizationState *pObj) request->system_language_code_ = Langpack_GetDefaultLocaleName(); request->device_model_ = T2Utf(m_wszDeviceName).get(); request->application_version_ = text; - request->enable_storage_optimizer_ = true; SendQuery(request, &CTelegramProto::OnUpdateAuth); } break; diff --git a/protocols/Telegram/src/menus.cpp b/protocols/Telegram/src/menus.cpp index acdbb6e54b..413193d8b0 100644 --- a/protocols/Telegram/src/menus.cpp +++ b/protocols/Telegram/src/menus.cpp @@ -121,7 +121,7 @@ public: auto *pUser = m_proto->FindUser(m_proto->GetId(hContact)); TD::array ids = message_ids; - m_proto->SendQuery(new TD::forwardMessages(pUser->chatId, 0, pMe->chatId, std::move(ids), 0, false, false, false)); + m_proto->SendQuery(new TD::forwardMessages(pUser->chatId, 0, pMe->chatId, std::move(ids), 0, false, false)); } } diff --git a/protocols/Telegram/src/options.cpp b/protocols/Telegram/src/options.cpp index 8b3bd7d1e7..c89d8518e1 100644 --- a/protocols/Telegram/src/options.cpp +++ b/protocols/Telegram/src/options.cpp @@ -324,7 +324,7 @@ void CTelegramProto::OnGetSessions(td::ClientManager::Response &response, void * pwszType = TranslateT("Unknown"); } pList->SetItemText(iItem, 1, pwszType); - pList->SetItemText(iItem, 2, Utf2T(pSession->country_.c_str())); + pList->SetItemText(iItem, 2, Utf2T(pSession->location_.c_str())); wchar_t wszLastLogin[100]; TimeZone_PrintTimeStamp(0, pSession->last_active_date_, L"d t", wszLastLogin, _countof(wszLastLogin), 0); diff --git a/protocols/Telegram/src/proto.cpp b/protocols/Telegram/src/proto.cpp index 714796a3e4..98572eea52 100644 --- a/protocols/Telegram/src/proto.cpp +++ b/protocols/Telegram/src/proto.cpp @@ -254,8 +254,8 @@ void CTelegramProto::OnEventEdited(MCONTACT hContact, MEVENT, const DBEVENTINFO if (dbei.szId && dbei.cbBlob && dbei.pBlob && dbei.eventType == EVENTTYPE_MESSAGE) { auto text = formatBbcodes((char*)dbei.pBlob); - auto content = TD::make_object(std::move(text), false, false); - SendQuery(new TD::editMessageText(pUser->chatId, dbei2id(dbei), 0, std::move(content))); + // auto content = TD::make_object(std::move(text), 0, false); + // SendQuery(new TD::editMessageText(pUser->chatId, dbei2id(dbei), 0, std::move(content))); } } @@ -683,7 +683,7 @@ int CTelegramProto::UserIsTyping(MCONTACT hContact, int type) { if (auto *pUser = FindUser(GetId(hContact))) if (type == PROTOTYPE_SELFTYPING_ON) - SendQuery(new TD::sendChatAction(pUser->chatId, 0, TD::make_object())); + SendQuery(new TD::sendChatAction(pUser->chatId, 0, "", TD::make_object())); return 0; } diff --git a/protocols/Telegram/src/server.cpp b/protocols/Telegram/src/server.cpp index d5f3caa43b..c2c8d3c1f2 100644 --- a/protocols/Telegram/src/server.cpp +++ b/protocols/Telegram/src/server.cpp @@ -378,7 +378,8 @@ int CTelegramProto::SendTextMessage(int64_t chatId, int64_t threadId, int64_t re pMessage->chat_id_ = chatId; pMessage->input_message_content_ = std::move(pContent); pMessage->message_thread_id_ = threadId; - pMessage->reply_to_message_id_ = replyId; + if (replyId) + pMessage->reply_to_.reset(new TD::inputMessageReplyToMessage(replyId, 0)); return SendQuery(pMessage, &CTelegramProto::OnSendMessage); } @@ -461,8 +462,8 @@ void CTelegramProto::OnGetHistory(td::ClientManager::Response &response, void *p dbei.flags |= DBEF_SENT; if (this->GetGcUserId(pUser, pMsg, szUserId)) dbei.szUserId = szUserId; - if (pMsg->reply_to_message_id_) { - szReplyId = msg2id(pMsg->chat_id_, pMsg->reply_to_message_id_); + if (auto iReplyId = getReplyId(pMsg->reply_to_.get())) { + szReplyId = msg2id(pMsg->chat_id_, iReplyId); dbei.szReplyId = szReplyId; } db_event_add(GetRealContact(pUser), &dbei); @@ -671,11 +672,6 @@ void CTelegramProto::ProcessChatNotification(TD::updateChatNotificationSettings void CTelegramProto::ProcessChatPosition(TD::updateChatPosition *pObj) { - if (pObj->position_->get_id() != TD::chatPosition::ID) { - debugLogA("Unsupport position"); - return; - } - auto *pUser = FindChat(pObj->chat_id_); if (pUser == nullptr) { debugLogA("Unknown chat, skipping"); @@ -939,8 +935,8 @@ void CTelegramProto::ProcessMessage(const TD::message *pMessage) dbei.flags |= DBEF_READ; if (GetGcUserId(pUser, pMessage, szUserId)) dbei.szUserId = szUserId; - if (pMessage->reply_to_message_id_) { - szReplyId = msg2id(pMessage->chat_id_, pMessage->reply_to_message_id_); + if (auto iReplyId = getReplyId(pMessage->reply_to_.get())) { + szReplyId = msg2id(pMessage->chat_id_, iReplyId); dbei.szReplyId = szReplyId; } @@ -1009,15 +1005,16 @@ void CTelegramProto::ProcessMessageReactions(TD::updateMessageInteractionInfo *p } JSONNode reactions; reactions.set_name("r"); - if (pObj->interaction_info_) { - for (auto &it : pObj->interaction_info_->reactions_) { - if (it->type_->get_id() != TD::reactionTypeEmoji::ID) - continue; - - auto *pEmoji = (TD::reactionTypeEmoji *)it->type_.get(); - reactions << INT_PARAM(pEmoji->emoji_.c_str(), it->total_count_); + if (pObj->interaction_info_) + if (pObj->interaction_info_->reactions_) { + for (auto &it : pObj->interaction_info_->reactions_->reactions_) { + if (it->type_->get_id() != TD::reactionTypeEmoji::ID) + continue; + + auto *pEmoji = (TD::reactionTypeEmoji *)it->type_.get(); + reactions << INT_PARAM(pEmoji->emoji_.c_str(), it->total_count_); + } } - } auto &json = dbei.setJson(); auto it = json.find("r"); diff --git a/protocols/Telegram/src/utils.cpp b/protocols/Telegram/src/utils.cpp index 618265af56..c823896051 100644 --- a/protocols/Telegram/src/utils.cpp +++ b/protocols/Telegram/src/utils.cpp @@ -84,36 +84,32 @@ TD::object_ptr formatBbcodes(const char *pszText) CMStringA CTelegramProto::GetFormattedText(TD::object_ptr &pText) { - if (pText->get_id() == TD::formattedText::ID) { - CMStringW ret(Utf2T(pText->text_.c_str())); - unsigned offset = 0; - - for (auto &it : pText->entities_) { - int iCode; - switch (it->type_->get_id()) { - case TD::textEntityTypeBold::ID: iCode = 0; break; - case TD::textEntityTypeItalic::ID: iCode = 1; break; - case TD::textEntityTypeStrikethrough::ID: iCode = 2; break; - case TD::textEntityTypeUnderline::ID: iCode = 3; break; - case TD::textEntityTypeCode::ID: iCode = 5; break; - case TD::textEntityTypeUrl::ID: - if (!m_bUrlPreview) - continue; - iCode = 4; - break; - default: + CMStringW ret(Utf2T(pText->text_.c_str())); + unsigned offset = 0; + + for (auto &it : pText->entities_) { + int iCode; + switch (it->type_->get_id()) { + case TD::textEntityTypeBold::ID: iCode = 0; break; + case TD::textEntityTypeItalic::ID: iCode = 1; break; + case TD::textEntityTypeStrikethrough::ID: iCode = 2; break; + case TD::textEntityTypeUnderline::ID: iCode = 3; break; + case TD::textEntityTypeCode::ID: iCode = 5; break; + case TD::textEntityTypeUrl::ID: + if (!m_bUrlPreview) continue; - } - - auto &bb = bbCodes[iCode]; - ret.Insert(offset + it->offset_ + it->length_, bb.end); - ret.Insert(offset + it->offset_, bb.begin); - offset += bb.len1 + bb.len2; + iCode = 4; + break; + default: + continue; } - return T2Utf(ret).get(); + + auto &bb = bbCodes[iCode]; + ret.Insert(offset + it->offset_ + it->length_, bb.end); + ret.Insert(offset + it->offset_, bb.begin); + offset += bb.len1 + bb.len2; } - - return ""; + return T2Utf(ret).get(); } ///////////////////////////////////////////////////////////////////////////////////////// @@ -170,6 +166,20 @@ TG_FILE_REQUEST::Type AutoDetectType(const wchar_t *pwszFilename) return TG_FILE_REQUEST::FILE; } +TD::int53 getReplyId(const TD::MessageReplyTo *pReply) +{ + if (pReply) { + switch (pReply->get_id()) { + case TD::messageReplyToMessage::ID: + return ((TD::messageReplyToMessage *)pReply)->message_id_; + + case TD::inputMessageReplyToExternalMessage::ID: + return ((TD::inputMessageReplyToExternalMessage *)pReply)->message_id_; + } + } + return 0; +} + CMStringW TG_USER::getDisplayName() const { if (hContact != 0) { @@ -422,11 +432,6 @@ bool CTelegramProto::GetGcUserId(TG_USER *pUser, const TD::message *pMsg, char * bool CTelegramProto::GetMessageFile(const EmbeddedFile &F, TG_FILE_REQUEST::Type iType, const TD::file *pFile, const char *pszFileName, const char *pszCaption) { - if (pFile->get_id() != TD::file::ID) { - debugLogA("Document contains unsupported type %d, exiting", pFile->get_id()); - return false; - } - auto *pRequest = new TG_FILE_REQUEST(iType, pFile->id_, pFile->remote_->id_.c_str()); pRequest->m_fileName = Utf2T(pszFileName); pRequest->m_fileSize = pFile->size_; @@ -447,8 +452,8 @@ bool CTelegramProto::GetMessageFile(const EmbeddedFile &F, TG_FILE_REQUEST::Type dbei.flags |= DBEF_SENT; if (!F.pUser->bInited || F.bRead) dbei.flags |= DBEF_READ; - if (F.pMsg->reply_to_message_id_) { - _i64toa(F.pMsg->reply_to_message_id_, szReplyId, 10); + if (auto iReplyId = getReplyId(F.pMsg->reply_to_.get())) { + _i64toa(iReplyId, szReplyId, 10); dbei.szReplyId = szReplyId; } @@ -540,20 +545,20 @@ CMStringA CTelegramProto::GetMessageText(TG_USER *pUser, const TD::message *pMsg if (auto *pForward = pMsg->forward_info_.get()) { CMStringW wszNick; switch (pForward->origin_->get_id()) { - case TD::messageForwardOriginUser::ID: - if (auto *p = FindUser(((TD::messageForwardOriginUser *)pForward->origin_.get())->sender_user_id_)) + case TD::messageOriginUser::ID: + if (auto *p = FindUser(((TD::messageOriginUser *)pForward->origin_.get())->sender_user_id_)) wszNick = p->getDisplayName(); break; - case TD::messageForwardOriginChat::ID: - if (auto *p = FindChat(((TD::messageForwardOriginChat *)pForward->origin_.get())->sender_chat_id_)) + case TD::messageOriginChat::ID: + if (auto *p = FindChat(((TD::messageOriginChat *)pForward->origin_.get())->sender_chat_id_)) wszNick = p->getDisplayName(); break; - case TD::messageForwardOriginHiddenUser::ID: - if (auto *p = (TD::messageForwardOriginHiddenUser *)pForward->origin_.get()) + case TD::messageOriginHiddenUser::ID: + if (auto *p = (TD::messageOriginHiddenUser *)pForward->origin_.get()) wszNick = Utf2T(p->sender_name_.c_str()); break; - case TD::messageForwardOriginChannel::ID: - if (auto *p = FindChat(((TD::messageForwardOriginChannel *)pForward->origin_.get())->chat_id_)) + case TD::messageOriginChannel::ID: + if (auto *p = FindChat(((TD::messageOriginChannel *)pForward->origin_.get())->chat_id_)) wszNick = p->getDisplayName(); break; default: @@ -728,9 +733,7 @@ CMStringA CTelegramProto::GetMessageText(TG_USER *pUser, const TD::message *pMsg case TD::messageInvoice::ID: if (auto *pInvoice = ((TD::messageInvoice *)pBody)) { ret.Format("%s: %.2lf %s", TranslateU("You received an invoice"), double(pInvoice->total_amount_)/100.0, pInvoice->currency_.c_str()); - if (!pInvoice->title_.empty()) - ret.AppendFormat("\r\n%s: %s", TranslateU("Title"), pInvoice->title_.c_str()); - if (auto pszText = GetFormattedText(pInvoice->description_)) + if (auto pszText = GetFormattedText(pInvoice->paid_media_caption_)) ret.AppendFormat("\r\n%s", pszText.c_str()); } break; @@ -739,18 +742,19 @@ CMStringA CTelegramProto::GetMessageText(TG_USER *pUser, const TD::message *pMsg if (auto *pText = ((TD::messageText *)pBody)) { ret = GetFormattedText(pText->text_); - if (auto *pWeb = pText->web_page_.get()) { - if (!pWeb->embed_url_.empty() && m_bUrlPreview) - ret.AppendFormat("\r\n[url]%s[/url]", pWeb->embed_url_.c_str()); + if (auto *pWeb = pText->link_preview_.get()) { + if (!pWeb->display_url_.empty() && m_bUrlPreview) + ret.AppendFormat("\r\n[url]%s[/url]", pWeb->display_url_.c_str()); - if (pWeb->photo_) { + if (pWeb->type_->get_id() == TD::linkPreviewTypePhoto::ID) { + auto *pPhoto = ((TD::linkPreviewTypePhoto *)pWeb->type_.get())->photo_.get(); const TD::photoSize *pSize = nullptr; - for (auto &it : pWeb->photo_->sizes_) + for (auto &it : pPhoto->sizes_) if (it->type_ == "m") pSize = it.get(); if (pSize == nullptr) - pSize = pWeb->photo_->sizes_[0].get(); + pSize = pPhoto->sizes_[0].get(); if (auto szText = GetMessagePreview(pSize->photo_.get())) ret.AppendFormat("\r\n[img=%s][/img]", szText.c_str()); diff --git a/protocols/Telegram/src/utils.h b/protocols/Telegram/src/utils.h index b6b3bd62da..81d60e239d 100644 --- a/protocols/Telegram/src/utils.h +++ b/protocols/Telegram/src/utils.h @@ -2,6 +2,8 @@ const char *getName(const TD::usernames *pName); +TD::int53 getReplyId(const TD::MessageReplyTo *pReply); + TD::object_ptr makeFile(const wchar_t *pwszFilename); TD::object_ptr formatBbcodes(const char *pszText); diff --git a/protocols/Telegram/src/version.h b/protocols/Telegram/src/version.h index ac231a237f..ea7e3f3bab 100644 --- a/protocols/Telegram/src/version.h +++ b/protocols/Telegram/src/version.h @@ -1,6 +1,6 @@ #define __MAJOR_VERSION 0 -#define __MINOR_VERSION 11 -#define __RELEASE_NUM 0 +#define __MINOR_VERSION 96 +#define __RELEASE_NUM 6 #define __BUILD_NUM 1 #include diff --git a/protocols/Telegram/tdlib/td/sqlite/sqlite/sqlite3.c b/protocols/Telegram/tdlib/td/sqlite/sqlite/sqlite3.c index 4fb5bc5e5d..34c9a653fd 100644 --- a/protocols/Telegram/tdlib/td/sqlite/sqlite/sqlite3.c +++ b/protocols/Telegram/tdlib/td/sqlite/sqlite/sqlite3.c @@ -14,7 +14,7 @@ ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming -** language. The code for the "tdsqlite3" command-line shell is also in a +** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. */ #define SQLITE_CORE 1 @@ -69,7 +69,7 @@ ** only a handful of compile-time options, so most times this array is usually ** rather short and uses little memory space. */ -static const char * const tdsqlite3azCompileOpt[] = { +static const char * const sqlite3azCompileOpt[] = { /* ** BEGIN CODE GENERATED BY tool/mkctime.tcl @@ -782,9 +782,9 @@ static const char * const tdsqlite3azCompileOpt[] = { */ }; -SQLITE_PRIVATE const char **tdsqlite3CompileOptions(int *pnOpt){ - *pnOpt = sizeof(tdsqlite3azCompileOpt) / sizeof(tdsqlite3azCompileOpt[0]); - return (const char**)tdsqlite3azCompileOpt; +SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt){ + *pnOpt = sizeof(sqlite3azCompileOpt) / sizeof(sqlite3azCompileOpt[0]); + return (const char**)sqlite3azCompileOpt; } #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ @@ -1161,8 +1161,8 @@ extern "C" { ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** -** See also: [tdsqlite3_libversion()], -** [tdsqlite3_libversion_number()], [tdsqlite3_sourceid()], +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.31.0" @@ -1171,7 +1171,7 @@ extern "C" { /* ** CAPI3REF: Run-Time Library Version Numbers -** KEYWORDS: tdsqlite3_version tdsqlite3_sourceid +** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros @@ -1182,18 +1182,18 @@ extern "C" { ** compiled with matching library and header files. ** **
-** assert( tdsqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
-** assert( strncmp(tdsqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
-** assert( strcmp(tdsqlite3_libversion(),SQLITE_VERSION)==0 );
+** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+** assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 );
+** assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 );
 ** 
)^ ** -** ^The tdsqlite3_version[] string constant contains the text of [SQLITE_VERSION] -** macro. ^The tdsqlite3_libversion() function returns a pointer to the -** to the tdsqlite3_version[] string constant. The tdsqlite3_libversion() +** ^The sqlite3_version[] string constant contains the text of [SQLITE_VERSION] +** macro. ^The sqlite3_libversion() function returns a pointer to the +** to the sqlite3_version[] string constant. The sqlite3_libversion() ** function is provided for use in DLLs since DLL users usually do not have ** direct access to string constants within the DLL. ^The -** tdsqlite3_libversion_number() function returns an integer equal to -** [SQLITE_VERSION_NUMBER]. ^(The tdsqlite3_sourceid() function returns +** sqlite3_libversion_number() function returns an integer equal to +** [SQLITE_VERSION_NUMBER]. ^(The sqlite3_sourceid() function returns ** a pointer to a string constant whose value is the same as the ** [SQLITE_SOURCE_ID] C preprocessor macro. Except if SQLite is built ** using an edited copy of [the amalgamation], then the last four characters @@ -1201,45 +1201,45 @@ extern "C" { ** ** See also: [sqlite_version()] and [sqlite_source_id()]. */ -SQLITE_API const char tdsqlite3_version[] = SQLITE_VERSION; -SQLITE_API const char *tdsqlite3_libversion(void); -SQLITE_API const char *tdsqlite3_sourceid(void); -SQLITE_API int tdsqlite3_libversion_number(void); +SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; +SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); +SQLITE_API int sqlite3_libversion_number(void); /* ** CAPI3REF: Run-Time Library Compilation Options Diagnostics ** -** ^The tdsqlite3_compileoption_used() function returns 0 or 1 +** ^The sqlite3_compileoption_used() function returns 0 or 1 ** indicating whether the specified option was defined at ** compile time. ^The SQLITE_ prefix may be omitted from the -** option name passed to tdsqlite3_compileoption_used(). +** option name passed to sqlite3_compileoption_used(). ** -** ^The tdsqlite3_compileoption_get() function allows iterating +** ^The sqlite3_compileoption_get() function allows iterating ** over the list of options that were defined at compile time by ** returning the N-th compile time option string. ^If N is out of range, -** tdsqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ +** sqlite3_compileoption_get() returns a NULL pointer. ^The SQLITE_ ** prefix is omitted from any strings returned by -** tdsqlite3_compileoption_get(). +** sqlite3_compileoption_get(). ** -** ^Support for the diagnostic functions tdsqlite3_compileoption_used() -** and tdsqlite3_compileoption_get() may be omitted by specifying the +** ^Support for the diagnostic functions sqlite3_compileoption_used() +** and sqlite3_compileoption_get() may be omitted by specifying the ** [SQLITE_OMIT_COMPILEOPTION_DIAGS] option at compile time. ** ** See also: SQL functions [sqlite_compileoption_used()] and ** [sqlite_compileoption_get()] and the [compile_options pragma]. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -SQLITE_API int tdsqlite3_compileoption_used(const char *zOptName); -SQLITE_API const char *tdsqlite3_compileoption_get(int N); +SQLITE_API int sqlite3_compileoption_used(const char *zOptName); +SQLITE_API const char *sqlite3_compileoption_get(int N); #else -# define tdsqlite3_compileoption_used(X) 0 -# define tdsqlite3_compileoption_get(X) ((void*)0) +# define sqlite3_compileoption_used(X) 0 +# define sqlite3_compileoption_get(X) ((void*)0) #endif /* ** CAPI3REF: Test To See If The Library Is Threadsafe ** -** ^The tdsqlite3_threadsafe() function returns zero if and only if +** ^The sqlite3_threadsafe() function returns zero if and only if ** SQLite was compiled with mutexing code omitted due to the ** [SQLITE_THREADSAFE] compile-time option being set to 0. ** @@ -1262,33 +1262,33 @@ SQLITE_API const char *tdsqlite3_compileoption_get(int N); ** This interface only reports on the compile-time mutex setting ** of the [SQLITE_THREADSAFE] flag. If SQLite is compiled with ** SQLITE_THREADSAFE=1 or =2 then mutexes are enabled by default but -** can be fully or partially disabled using a call to [tdsqlite3_config()] +** can be fully or partially disabled using a call to [sqlite3_config()] ** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD], ** or [SQLITE_CONFIG_SERIALIZED]. ^(The return value of the -** tdsqlite3_threadsafe() function shows only the compile-time setting of +** sqlite3_threadsafe() function shows only the compile-time setting of ** thread safety, not any run-time changes to that setting made by -** tdsqlite3_config(). In other words, the return value from tdsqlite3_threadsafe() -** is unchanged by calls to tdsqlite3_config().)^ +** sqlite3_config(). In other words, the return value from sqlite3_threadsafe() +** is unchanged by calls to sqlite3_config().)^ ** ** See the [threading mode] documentation for additional information. */ -SQLITE_API int tdsqlite3_threadsafe(void); +SQLITE_API int sqlite3_threadsafe(void); /* ** CAPI3REF: Database Connection Handle ** KEYWORDS: {database connection} {database connections} ** ** Each open SQLite database is represented by a pointer to an instance of -** the opaque structure named "tdsqlite3". It is useful to think of an tdsqlite3 -** pointer as an object. The [tdsqlite3_open()], [tdsqlite3_open16()], and -** [tdsqlite3_open_v2()] interfaces are its constructors, and [tdsqlite3_close()] -** and [tdsqlite3_close_v2()] are its destructors. There are many other +** the opaque structure named "sqlite3". It is useful to think of an sqlite3 +** pointer as an object. The [sqlite3_open()], [sqlite3_open16()], and +** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()] +** and [sqlite3_close_v2()] are its destructors. There are many other ** interfaces (such as -** [tdsqlite3_prepare_v2()], [tdsqlite3_create_function()], and -** [tdsqlite3_busy_timeout()] to name but three) that are methods on an -** tdsqlite3 object. +** [sqlite3_prepare_v2()], [sqlite3_create_function()], and +** [sqlite3_busy_timeout()] to name but three) that are methods on an +** sqlite3 object. */ -typedef struct tdsqlite3 tdsqlite3; +typedef struct sqlite3 sqlite3; /* ** CAPI3REF: 64-Bit Integer Types @@ -1297,13 +1297,13 @@ typedef struct tdsqlite3 tdsqlite3; ** Because there is no cross-platform way to specify 64-bit integer types ** SQLite includes typedefs for 64-bit signed and unsigned integers. ** -** The tdsqlite3_int64 and tdsqlite3_uint64 are the preferred type definitions. +** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions. ** The sqlite_int64 and sqlite_uint64 types are supported for backwards ** compatibility only. ** -** ^The tdsqlite3_int64 and sqlite_int64 types can store integer values +** ^The sqlite3_int64 and sqlite_int64 types can store integer values ** between -9223372036854775808 and +9223372036854775807 inclusive. ^The -** tdsqlite3_uint64 and sqlite_uint64 types can store integer values +** sqlite3_uint64 and sqlite_uint64 types can store integer values ** between 0 and +18446744073709551615 inclusive. */ #ifdef SQLITE_INT64_TYPE @@ -1320,116 +1320,116 @@ typedef struct tdsqlite3 tdsqlite3; typedef long long int sqlite_int64; typedef unsigned long long int sqlite_uint64; #endif -typedef sqlite_int64 tdsqlite3_int64; -typedef sqlite_uint64 tdsqlite3_uint64; +typedef sqlite_int64 sqlite3_int64; +typedef sqlite_uint64 sqlite3_uint64; /* ** If compiling for a processor that lacks floating point support, ** substitute integer for floating-point. */ #ifdef SQLITE_OMIT_FLOATING_POINT -# define double tdsqlite3_int64 +# define double sqlite3_int64 #endif /* ** CAPI3REF: Closing A Database Connection -** DESTRUCTOR: tdsqlite3 +** DESTRUCTOR: sqlite3 ** -** ^The tdsqlite3_close() and tdsqlite3_close_v2() routines are destructors -** for the [tdsqlite3] object. -** ^Calls to tdsqlite3_close() and tdsqlite3_close_v2() return [SQLITE_OK] if -** the [tdsqlite3] object is successfully destroyed and all associated +** ^The sqlite3_close() and sqlite3_close_v2() routines are destructors +** for the [sqlite3] object. +** ^Calls to sqlite3_close() and sqlite3_close_v2() return [SQLITE_OK] if +** the [sqlite3] object is successfully destroyed and all associated ** resources are deallocated. ** ** ^If the database connection is associated with unfinalized prepared -** statements or unfinished tdsqlite3_backup objects then tdsqlite3_close() +** statements or unfinished sqlite3_backup objects then sqlite3_close() ** will leave the database connection open and return [SQLITE_BUSY]. -** ^If tdsqlite3_close_v2() is called with unfinalized prepared statements -** and/or unfinished tdsqlite3_backups, then the database connection becomes +** ^If sqlite3_close_v2() is called with unfinalized prepared statements +** and/or unfinished sqlite3_backups, then the database connection becomes ** an unusable "zombie" which will automatically be deallocated when the -** last prepared statement is finalized or the last tdsqlite3_backup is -** finished. The tdsqlite3_close_v2() interface is intended for use with +** last prepared statement is finalized or the last sqlite3_backup is +** finished. The sqlite3_close_v2() interface is intended for use with ** host languages that are garbage collected, and where the order in which ** destructors are called is arbitrary. ** -** Applications should [tdsqlite3_finalize | finalize] all [prepared statements], -** [tdsqlite3_blob_close | close] all [BLOB handles], and -** [tdsqlite3_backup_finish | finish] all [tdsqlite3_backup] objects associated -** with the [tdsqlite3] object prior to attempting to close the object. ^If -** tdsqlite3_close_v2() is called on a [database connection] that still has +** Applications should [sqlite3_finalize | finalize] all [prepared statements], +** [sqlite3_blob_close | close] all [BLOB handles], and +** [sqlite3_backup_finish | finish] all [sqlite3_backup] objects associated +** with the [sqlite3] object prior to attempting to close the object. ^If +** sqlite3_close_v2() is called on a [database connection] that still has ** outstanding [prepared statements], [BLOB handles], and/or -** [tdsqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation +** [sqlite3_backup] objects then it returns [SQLITE_OK] and the deallocation ** of resources is deferred until all [prepared statements], [BLOB handles], -** and [tdsqlite3_backup] objects are also destroyed. +** and [sqlite3_backup] objects are also destroyed. ** -** ^If an [tdsqlite3] object is destroyed while a transaction is open, +** ^If an [sqlite3] object is destroyed while a transaction is open, ** the transaction is automatically rolled back. ** -** The C parameter to [tdsqlite3_close(C)] and [tdsqlite3_close_v2(C)] +** The C parameter to [sqlite3_close(C)] and [sqlite3_close_v2(C)] ** must be either a NULL -** pointer or an [tdsqlite3] object pointer obtained -** from [tdsqlite3_open()], [tdsqlite3_open16()], or -** [tdsqlite3_open_v2()], and not previously closed. -** ^Calling tdsqlite3_close() or tdsqlite3_close_v2() with a NULL pointer +** pointer or an [sqlite3] object pointer obtained +** from [sqlite3_open()], [sqlite3_open16()], or +** [sqlite3_open_v2()], and not previously closed. +** ^Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer ** argument is a harmless no-op. */ -SQLITE_API int tdsqlite3_close(tdsqlite3*); -SQLITE_API int tdsqlite3_close_v2(tdsqlite3*); +SQLITE_API int sqlite3_close(sqlite3*); +SQLITE_API int sqlite3_close_v2(sqlite3*); /* ** The type for a callback function. ** This is legacy and deprecated. It is included for historical ** compatibility and is not documented. */ -typedef int (*tdsqlite3_callback)(void*,int,char**, char**); +typedef int (*sqlite3_callback)(void*,int,char**, char**); /* ** CAPI3REF: One-Step Query Execution Interface -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** The tdsqlite3_exec() interface is a convenience wrapper around -** [tdsqlite3_prepare_v2()], [tdsqlite3_step()], and [tdsqlite3_finalize()], +** The sqlite3_exec() interface is a convenience wrapper around +** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()], ** that allows an application to run multiple statements of SQL ** without having to use a lot of C code. ** -** ^The tdsqlite3_exec() interface runs zero or more UTF-8 encoded, +** ^The sqlite3_exec() interface runs zero or more UTF-8 encoded, ** semicolon-separate SQL statements passed into its 2nd argument, ** in the context of the [database connection] passed in as its 1st ** argument. ^If the callback function of the 3rd argument to -** tdsqlite3_exec() is not NULL, then it is invoked for each result row +** sqlite3_exec() is not NULL, then it is invoked for each result row ** coming out of the evaluated SQL statements. ^The 4th argument to -** tdsqlite3_exec() is relayed through to the 1st argument of each -** callback invocation. ^If the callback pointer to tdsqlite3_exec() +** sqlite3_exec() is relayed through to the 1st argument of each +** callback invocation. ^If the callback pointer to sqlite3_exec() ** is NULL, then no callback is ever invoked and result rows are ** ignored. ** ** ^If an error occurs while evaluating the SQL statements passed into -** tdsqlite3_exec(), then execution of the current statement stops and -** subsequent statements are skipped. ^If the 5th parameter to tdsqlite3_exec() +** sqlite3_exec(), then execution of the current statement stops and +** subsequent statements are skipped. ^If the 5th parameter to sqlite3_exec() ** is not NULL then any error message is written into memory obtained -** from [tdsqlite3_malloc()] and passed back through the 5th parameter. -** To avoid memory leaks, the application should invoke [tdsqlite3_free()] +** from [sqlite3_malloc()] and passed back through the 5th parameter. +** To avoid memory leaks, the application should invoke [sqlite3_free()] ** on error message strings returned through the 5th parameter of -** tdsqlite3_exec() after the error message string is no longer needed. -** ^If the 5th parameter to tdsqlite3_exec() is not NULL and no errors -** occur, then tdsqlite3_exec() sets the pointer in its 5th parameter to +** sqlite3_exec() after the error message string is no longer needed. +** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors +** occur, then sqlite3_exec() sets the pointer in its 5th parameter to ** NULL before returning. ** -** ^If an tdsqlite3_exec() callback returns non-zero, the tdsqlite3_exec() +** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() ** routine returns SQLITE_ABORT without invoking the callback again and ** without running any subsequent SQL statements. ** -** ^The 2nd argument to the tdsqlite3_exec() callback function is the -** number of columns in the result. ^The 3rd argument to the tdsqlite3_exec() +** ^The 2nd argument to the sqlite3_exec() callback function is the +** number of columns in the result. ^The 3rd argument to the sqlite3_exec() ** callback is an array of pointers to strings obtained as if from -** [tdsqlite3_column_text()], one for each column. ^If an element of a +** [sqlite3_column_text()], one for each column. ^If an element of a ** result row is NULL then the corresponding string pointer for the -** tdsqlite3_exec() callback is a NULL pointer. ^The 4th argument to the -** tdsqlite3_exec() callback is an array of pointers to strings where each +** sqlite3_exec() callback is a NULL pointer. ^The 4th argument to the +** sqlite3_exec() callback is an array of pointers to strings where each ** entry represents the name of corresponding result column as obtained -** from [tdsqlite3_column_name()]. +** from [sqlite3_column_name()]. ** -** ^If the 2nd parameter to tdsqlite3_exec() is a NULL pointer, a pointer +** ^If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer ** to an empty string, or a pointer that contains only whitespace and/or ** SQL comments, then no SQL statements are evaluated and the database ** is not changed. @@ -1437,16 +1437,16 @@ typedef int (*tdsqlite3_callback)(void*,int,char**, char**); ** Restrictions: ** **
    -**
  • The application must ensure that the 1st parameter to tdsqlite3_exec() +**
  • The application must ensure that the 1st parameter to sqlite3_exec() ** is a valid and open [database connection]. **
  • The application must not close the [database connection] specified by -** the 1st parameter to tdsqlite3_exec() while tdsqlite3_exec() is running. +** the 1st parameter to sqlite3_exec() while sqlite3_exec() is running. **
  • The application must not modify the SQL statement text passed into -** the 2nd parameter of tdsqlite3_exec() while tdsqlite3_exec() is running. +** the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running. **
*/ -SQLITE_API int tdsqlite3_exec( - tdsqlite3*, /* An open database */ +SQLITE_API int sqlite3_exec( + sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ void *, /* 1st argument to callback */ @@ -1474,10 +1474,10 @@ SQLITE_API int tdsqlite3_exec( #define SQLITE_LOCKED 6 /* A table in the database is locked */ #define SQLITE_NOMEM 7 /* A malloc() failed */ #define SQLITE_READONLY 8 /* Attempt to write a readonly database */ -#define SQLITE_INTERRUPT 9 /* Operation terminated by tdsqlite3_interrupt()*/ +#define SQLITE_INTERRUPT 9 /* Operation terminated by sqlite3_interrupt()*/ #define SQLITE_IOERR 10 /* Some kind of disk I/O error occurred */ #define SQLITE_CORRUPT 11 /* The database disk image is malformed */ -#define SQLITE_NOTFOUND 12 /* Unknown opcode in tdsqlite3_file_control() */ +#define SQLITE_NOTFOUND 12 /* Unknown opcode in sqlite3_file_control() */ #define SQLITE_FULL 13 /* Insertion failed because database is full */ #define SQLITE_CANTOPEN 14 /* Unable to open the database file */ #define SQLITE_PROTOCOL 15 /* Database lock protocol error */ @@ -1490,12 +1490,12 @@ SQLITE_API int tdsqlite3_exec( #define SQLITE_NOLFS 22 /* Uses OS features not supported on host */ #define SQLITE_AUTH 23 /* Authorization denied */ #define SQLITE_FORMAT 24 /* Not used */ -#define SQLITE_RANGE 25 /* 2nd parameter to tdsqlite3_bind out of range */ +#define SQLITE_RANGE 25 /* 2nd parameter to sqlite3_bind out of range */ #define SQLITE_NOTADB 26 /* File opened that is not a database file */ -#define SQLITE_NOTICE 27 /* Notifications from tdsqlite3_log() */ -#define SQLITE_WARNING 28 /* Warnings from tdsqlite3_log() */ -#define SQLITE_ROW 100 /* tdsqlite3_step() has another row ready */ -#define SQLITE_DONE 101 /* tdsqlite3_step() has finished executing */ +#define SQLITE_NOTICE 27 /* Notifications from sqlite3_log() */ +#define SQLITE_WARNING 28 /* Warnings from sqlite3_log() */ +#define SQLITE_ROW 100 /* sqlite3_step() has another row ready */ +#define SQLITE_DONE 101 /* sqlite3_step() has finished executing */ /* end-of-error-codes */ /* @@ -1511,9 +1511,9 @@ SQLITE_API int tdsqlite3_exec( ** support for additional result codes that provide more detailed information ** about errors. These [extended result codes] are enabled or disabled ** on a per database connection basis using the -** [tdsqlite3_extended_result_codes()] API. Or, the extended code for +** [sqlite3_extended_result_codes()] API. Or, the extended code for ** the most recent error can be obtained using -** [tdsqlite3_extended_errcode()]. +** [sqlite3_extended_errcode()]. */ #define SQLITE_ERROR_MISSING_COLLSEQ (SQLITE_ERROR | (1<<8)) #define SQLITE_ERROR_RETRY (SQLITE_ERROR | (2<<8)) @@ -1590,17 +1590,17 @@ SQLITE_API int tdsqlite3_exec( ** CAPI3REF: Flags For File Open Operations ** ** These bit values are intended for use in the -** 3rd parameter to the [tdsqlite3_open_v2()] interface and -** in the 4th parameter to the [tdsqlite3_vfs.xOpen] method. +** 3rd parameter to the [sqlite3_open_v2()] interface and +** in the 4th parameter to the [sqlite3_vfs.xOpen] method. */ -#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for tdsqlite3_open_v2() */ -#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for tdsqlite3_open_v2() */ -#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for tdsqlite3_open_v2() */ +#define SQLITE_OPEN_READONLY 0x00000001 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_READWRITE 0x00000002 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_CREATE 0x00000004 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_DELETEONCLOSE 0x00000008 /* VFS only */ #define SQLITE_OPEN_EXCLUSIVE 0x00000010 /* VFS only */ #define SQLITE_OPEN_AUTOPROXY 0x00000020 /* VFS only */ -#define SQLITE_OPEN_URI 0x00000040 /* Ok for tdsqlite3_open_v2() */ -#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for tdsqlite3_open_v2() */ +#define SQLITE_OPEN_URI 0x00000040 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_MEMORY 0x00000080 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_MAIN_DB 0x00000100 /* VFS only */ #define SQLITE_OPEN_TEMP_DB 0x00000200 /* VFS only */ #define SQLITE_OPEN_TRANSIENT_DB 0x00000400 /* VFS only */ @@ -1608,22 +1608,22 @@ SQLITE_API int tdsqlite3_exec( #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000 /* VFS only */ #define SQLITE_OPEN_SUBJOURNAL 0x00002000 /* VFS only */ #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ -#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for tdsqlite3_open_v2() */ -#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for tdsqlite3_open_v2() */ -#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for tdsqlite3_open_v2() */ -#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for tdsqlite3_open_v2() */ +#define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ -#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for tdsqlite3_open_v2() */ +#define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */ /* Reserved: 0x00F00000 */ /* ** CAPI3REF: Device Characteristics ** -** The xDeviceCharacteristics method of the [tdsqlite3_io_methods] +** The xDeviceCharacteristics method of the [sqlite3_io_methods] ** object returns an integer which is a vector of these ** bit values expressing I/O characteristics of the mass storage -** device that holds the file that the [tdsqlite3_io_methods] +** device that holds the file that the [sqlite3_io_methods] ** refers to. ** ** The SQLITE_IOCAP_ATOMIC property means that all writes of @@ -1671,7 +1671,7 @@ SQLITE_API int tdsqlite3_exec( ** ** SQLite uses one of these integer values as the second ** argument to calls it makes to the xLock() and xUnlock() methods -** of an [tdsqlite3_io_methods] object. +** of an [sqlite3_io_methods] object. */ #define SQLITE_LOCK_NONE 0 #define SQLITE_LOCK_SHARED 1 @@ -1683,7 +1683,7 @@ SQLITE_API int tdsqlite3_exec( ** CAPI3REF: Synchronization Type Flags ** ** When SQLite invokes the xSync() method of an -** [tdsqlite3_io_methods] object it uses a combination of +** [sqlite3_io_methods] object it uses a combination of ** these integer values as the second argument. ** ** When the SQLITE_SYNC_DATAONLY flag is used, it means that the @@ -1712,33 +1712,33 @@ SQLITE_API int tdsqlite3_exec( /* ** CAPI3REF: OS Interface Open File Handle ** -** An [tdsqlite3_file] object represents an open file in the -** [tdsqlite3_vfs | OS interface layer]. Individual OS interface +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface ** implementations will ** want to subclass this object by appending additional fields ** for their own use. The pMethods entry is a pointer to an -** [tdsqlite3_io_methods] object that defines methods for performing +** [sqlite3_io_methods] object that defines methods for performing ** I/O operations on the open file. */ -typedef struct tdsqlite3_file tdsqlite3_file; -struct tdsqlite3_file { - const struct tdsqlite3_io_methods *pMethods; /* Methods for an open file */ +typedef struct sqlite3_file sqlite3_file; +struct sqlite3_file { + const struct sqlite3_io_methods *pMethods; /* Methods for an open file */ }; /* ** CAPI3REF: OS Interface File Virtual Methods Object ** -** Every file opened by the [tdsqlite3_vfs.xOpen] method populates an -** [tdsqlite3_file] object (or, more commonly, a subclass of the -** [tdsqlite3_file] object) with a pointer to an instance of this object. +** Every file opened by the [sqlite3_vfs.xOpen] method populates an +** [sqlite3_file] object (or, more commonly, a subclass of the +** [sqlite3_file] object) with a pointer to an instance of this object. ** This object defines the methods used to perform various operations -** against the open file represented by the [tdsqlite3_file] object. +** against the open file represented by the [sqlite3_file] object. ** -** If the [tdsqlite3_vfs.xOpen] method sets the tdsqlite3_file.pMethods element -** to a non-NULL pointer, then the tdsqlite3_io_methods.xClose method -** may be invoked even if the [tdsqlite3_vfs.xOpen] reported that it failed. The -** only way to prevent a call to xClose following a failed [tdsqlite3_vfs.xOpen] -** is for the [tdsqlite3_vfs.xOpen] to set the tdsqlite3_file.pMethods element +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The +** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] +** is for the [sqlite3_vfs.xOpen] to set the sqlite3_file.pMethods element ** to NULL. ** ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or @@ -1763,7 +1763,7 @@ struct tdsqlite3_file { ** ** The xFileControl() method is a generic interface that allows custom ** VFS implementations to directly control an open file using the -** [tdsqlite3_file_control()] interface. The second "op" argument is an +** [sqlite3_file_control()] interface. The second "op" argument is an ** integer opcode. The third argument is a generic pointer intended to ** point to a structure that may contain arguments or space in which to ** write return values. Potential uses for xFileControl() might be @@ -1819,29 +1819,29 @@ struct tdsqlite3_file { ** failure to zero-fill short reads will eventually lead to ** database corruption. */ -typedef struct tdsqlite3_io_methods tdsqlite3_io_methods; -struct tdsqlite3_io_methods { +typedef struct sqlite3_io_methods sqlite3_io_methods; +struct sqlite3_io_methods { int iVersion; - int (*xClose)(tdsqlite3_file*); - int (*xRead)(tdsqlite3_file*, void*, int iAmt, tdsqlite3_int64 iOfst); - int (*xWrite)(tdsqlite3_file*, const void*, int iAmt, tdsqlite3_int64 iOfst); - int (*xTruncate)(tdsqlite3_file*, tdsqlite3_int64 size); - int (*xSync)(tdsqlite3_file*, int flags); - int (*xFileSize)(tdsqlite3_file*, tdsqlite3_int64 *pSize); - int (*xLock)(tdsqlite3_file*, int); - int (*xUnlock)(tdsqlite3_file*, int); - int (*xCheckReservedLock)(tdsqlite3_file*, int *pResOut); - int (*xFileControl)(tdsqlite3_file*, int op, void *pArg); - int (*xSectorSize)(tdsqlite3_file*); - int (*xDeviceCharacteristics)(tdsqlite3_file*); + int (*xClose)(sqlite3_file*); + int (*xRead)(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); + int (*xWrite)(sqlite3_file*, const void*, int iAmt, sqlite3_int64 iOfst); + int (*xTruncate)(sqlite3_file*, sqlite3_int64 size); + int (*xSync)(sqlite3_file*, int flags); + int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize); + int (*xLock)(sqlite3_file*, int); + int (*xUnlock)(sqlite3_file*, int); + int (*xCheckReservedLock)(sqlite3_file*, int *pResOut); + int (*xFileControl)(sqlite3_file*, int op, void *pArg); + int (*xSectorSize)(sqlite3_file*); + int (*xDeviceCharacteristics)(sqlite3_file*); /* Methods above are valid for version 1 */ - int (*xShmMap)(tdsqlite3_file*, int iPg, int pgsz, int, void volatile**); - int (*xShmLock)(tdsqlite3_file*, int offset, int n, int flags); - void (*xShmBarrier)(tdsqlite3_file*); - int (*xShmUnmap)(tdsqlite3_file*, int deleteFlag); + int (*xShmMap)(sqlite3_file*, int iPg, int pgsz, int, void volatile**); + int (*xShmLock)(sqlite3_file*, int offset, int n, int flags); + void (*xShmBarrier)(sqlite3_file*); + int (*xShmUnmap)(sqlite3_file*, int deleteFlag); /* Methods above are valid for version 2 */ - int (*xFetch)(tdsqlite3_file*, tdsqlite3_int64 iOfst, int iAmt, void **pp); - int (*xUnfetch)(tdsqlite3_file*, tdsqlite3_int64 iOfst, void *p); + int (*xFetch)(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); + int (*xUnfetch)(sqlite3_file*, sqlite3_int64 iOfst, void *p); /* Methods above are valid for version 3 */ /* Additional methods may be added in future releases */ }; @@ -1851,7 +1851,7 @@ struct tdsqlite3_io_methods { ** KEYWORDS: {file control opcodes} {file control opcode} ** ** These integer constants are opcodes for the xFileControl method -** of the [tdsqlite3_io_methods] object and for the [tdsqlite3_file_control()] +** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()] ** interface. ** **
    @@ -1874,8 +1874,8 @@ struct tdsqlite3_io_methods { ** **
  • [[SQLITE_FCNTL_SIZE_LIMIT]] ** The [SQLITE_FCNTL_SIZE_LIMIT] opcode is used by in-memory VFS that -** implements [tdsqlite3_deserialize()] to set an upper bound on the size -** of the in-memory database. The argument is a pointer to a [tdsqlite3_int64]. +** implements [sqlite3_deserialize()] to set an upper bound on the size +** of the in-memory database. The argument is a pointer to a [sqlite3_int64]. ** If the integer pointed to is negative, then it is filled in with the ** current limit. Otherwise the limit is set to the larger of the value ** of the integer pointed to and the current database size. The integer @@ -1884,7 +1884,7 @@ struct tdsqlite3_io_methods { **
  • [[SQLITE_FCNTL_CHUNK_SIZE]] ** The [SQLITE_FCNTL_CHUNK_SIZE] opcode is used to request that the VFS ** extends and truncates the database file in chunks of a size specified -** by the user. The fourth argument to [tdsqlite3_file_control()] should +** by the user. The fourth argument to [sqlite3_file_control()] should ** point to an integer (type int) containing the new chunk-size to use ** for the nominated database. Allocating database file space in large ** chunks (say 1MB at a time), may reduce file-system fragmentation and @@ -1892,12 +1892,12 @@ struct tdsqlite3_io_methods { ** **
  • [[SQLITE_FCNTL_FILE_POINTER]] ** The [SQLITE_FCNTL_FILE_POINTER] opcode is used to obtain a pointer -** to the [tdsqlite3_file] object associated with a particular database +** to the [sqlite3_file] object associated with a particular database ** connection. See also [SQLITE_FCNTL_JOURNAL_POINTER]. ** **
  • [[SQLITE_FCNTL_JOURNAL_POINTER]] ** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer -** to the [tdsqlite3_file] object associated with the journal file (either +** to the [sqlite3_file] object associated with the journal file (either ** the [rollback journal] or the [write-ahead log]) for a particular database ** connection. See also [SQLITE_FCNTL_FILE_POINTER]. ** @@ -1915,7 +1915,7 @@ struct tdsqlite3_io_methods { ** as part of a multi-database commit, the argument points to a nul-terminated ** string containing the transactions master-journal file name. VFSes that ** do not need this signal should silently ignore this opcode. Applications -** should not call [tdsqlite3_file_control()] with this opcode as doing so may +** should not call [sqlite3_file_control()] with this opcode as doing so may ** disrupt the operation of the specialized VFSes that do require it. ** **
  • [[SQLITE_FCNTL_COMMIT_PHASETWO]] @@ -1923,7 +1923,7 @@ struct tdsqlite3_io_methods { ** and sent to the VFS after a transaction has been committed immediately ** but before the database is unlocked. VFSes that do not need this signal ** should silently ignore this opcode. Applications should not call -** [tdsqlite3_file_control()] with this opcode as doing so may disrupt the +** [sqlite3_file_control()] with this opcode as doing so may disrupt the ** operation of the specialized VFSes that do require it. ** **
  • [[SQLITE_FCNTL_WIN32_AV_RETRY]] @@ -1954,7 +1954,7 @@ struct tdsqlite3_io_methods { ** have write permission on the directory containing the database file want ** to read the database file, as the WAL and shared memory files must exist ** in order for the database to be readable. The fourth parameter to -** [tdsqlite3_file_control()] for this opcode should be a pointer to an integer. +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent ** WAL mode. If the integer is -1, then it is overwritten with the current ** WAL persistence setting. @@ -1964,7 +1964,7 @@ struct tdsqlite3_io_methods { ** persistent "powersafe-overwrite" or "PSOW" setting. The PSOW setting ** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the ** xDeviceCharacteristics methods. The fourth parameter to -** [tdsqlite3_file_control()] for this opcode should be a pointer to an integer. +** [sqlite3_file_control()] for this opcode should be a pointer to an integer. ** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage ** mode. If the integer is -1, then it is overwritten with the current ** zero-damage mode setting. @@ -1979,8 +1979,8 @@ struct tdsqlite3_io_methods { ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of ** all [VFSes] in the VFS stack. The names are of all VFS shims and the ** final bottom-level VFS are written into memory obtained from -** [tdsqlite3_malloc()] and the result is stored in the char* variable -** that the fourth parameter of [tdsqlite3_file_control()] points to. +** [sqlite3_malloc()] and the result is stored in the char* variable +** that the fourth parameter of [sqlite3_file_control()] points to. ** The caller is responsible for freeing the memory when done. As with ** all file-control actions, there is no guarantee that this will actually ** do anything. Callers should initialize the char* variable to a NULL @@ -1990,22 +1990,22 @@ struct tdsqlite3_io_methods { **
  • [[SQLITE_FCNTL_VFS_POINTER]] ** ^The [SQLITE_FCNTL_VFS_POINTER] opcode finds a pointer to the top-level ** [VFSes] currently in use. ^(The argument X in -** tdsqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be -** of type "[tdsqlite3_vfs] **". This opcodes will set *X +** sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be +** of type "[sqlite3_vfs] **". This opcodes will set *X ** to a pointer to the top-level VFS.)^ ** ^When there are multiple VFS shims in the stack, this opcode finds the ** upper-most shim only. ** **
  • [[SQLITE_FCNTL_PRAGMA]] ** ^Whenever a [PRAGMA] statement is parsed, an [SQLITE_FCNTL_PRAGMA] -** file control is sent to the open [tdsqlite3_file] object corresponding +** file control is sent to the open [sqlite3_file] object corresponding ** to the database file to which the pragma statement refers. ^The argument ** to the [SQLITE_FCNTL_PRAGMA] file control is an array of ** pointers to strings (char**) in which the second element of the array ** is the name of the pragma and the third element is the argument to the ** pragma or NULL if the pragma has no argument. ^The handler for an ** [SQLITE_FCNTL_PRAGMA] file control can optionally make the first element -** of the char** argument point to a string obtained from [tdsqlite3_mprintf()] +** of the char** argument point to a string obtained from [sqlite3_mprintf()] ** or the equivalent and that string will become the result of the pragma or ** the error message if the pragma fails. ^If the ** [SQLITE_FCNTL_PRAGMA] file control returns [SQLITE_NOTFOUND], then normal @@ -2039,13 +2039,13 @@ struct tdsqlite3_io_methods { ** temporary filename using the same algorithm that is followed to generate ** temporary filenames for TEMP tables and other internal uses. The ** argument should be a char** which will be filled with the filename -** written into memory obtained from [tdsqlite3_malloc()]. The caller should -** invoke [tdsqlite3_free()] on the result to avoid a memory leak. +** written into memory obtained from [sqlite3_malloc()]. The caller should +** invoke [sqlite3_free()] on the result to avoid a memory leak. ** **
  • [[SQLITE_FCNTL_MMAP_SIZE]] ** The [SQLITE_FCNTL_MMAP_SIZE] file control is used to query or set the ** maximum number of bytes that will be used for memory-mapped I/O. -** The argument is a pointer to a value of type tdsqlite3_int64 that +** The argument is a pointer to a value of type sqlite3_int64 that ** is an advisory maximum number of bytes in the file to memory map. The ** pointer is overwritten with the old value. The limit is not changed if ** the value originally pointed to is negative, and so the current limit @@ -2103,7 +2103,7 @@ struct tdsqlite3_io_methods { ** ^Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to ** the closing [SQLITE_FCNTL_COMMIT_ATOMIC_WRITE] or ** [SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE], SQLite will make -** no VFS interface calls on the same [tdsqlite3_file] file descriptor +** no VFS interface calls on the same [sqlite3_file] file descriptor ** except for calls to the xWrite method and the xFileControl method ** with [SQLITE_FCNTL_SIZE_HINT]. ** @@ -2141,11 +2141,11 @@ struct tdsqlite3_io_methods { ** "data version" changes whenever any change occurs to the corresponding ** database file, either through SQL statements on the same database ** connection or through transactions committed by separate database -** connections possibly in other processes. The [tdsqlite3_total_changes()] +** connections possibly in other processes. The [sqlite3_total_changes()] ** interface can be used to find if any database on the connection has changed, ** but that interface responds to changes on TEMP as well as MAIN and does ** not provide a mechanism to detect changes to MAIN only. Also, the -** [tdsqlite3_total_changes()] interface responds to internal changes only and +** [sqlite3_total_changes()] interface responds to internal changes only and ** omits changes made by other database connections. The ** [PRAGMA data_version] command provides a mechanism to detect changes to ** a single attached database that occur due to other database connections, @@ -2207,29 +2207,29 @@ struct tdsqlite3_io_methods { /* ** CAPI3REF: Mutex Handle ** -** The mutex module within SQLite defines [tdsqlite3_mutex] to be an +** The mutex module within SQLite defines [sqlite3_mutex] to be an ** abstract type for a mutex object. The SQLite core never looks -** at the internal representation of an [tdsqlite3_mutex]. It only -** deals with pointers to the [tdsqlite3_mutex] object. +** at the internal representation of an [sqlite3_mutex]. It only +** deals with pointers to the [sqlite3_mutex] object. ** -** Mutexes are created using [tdsqlite3_mutex_alloc()]. +** Mutexes are created using [sqlite3_mutex_alloc()]. */ -typedef struct tdsqlite3_mutex tdsqlite3_mutex; +typedef struct sqlite3_mutex sqlite3_mutex; /* ** CAPI3REF: Loadable Extension Thunk ** -** A pointer to the opaque tdsqlite3_api_routines structure is passed as +** A pointer to the opaque sqlite3_api_routines structure is passed as ** the third parameter to entry points of [loadable extensions]. This ** structure must be typedefed in order to work around compiler warnings ** on some platforms. */ -typedef struct tdsqlite3_api_routines tdsqlite3_api_routines; +typedef struct sqlite3_api_routines sqlite3_api_routines; /* ** CAPI3REF: OS Interface Object ** -** An instance of the tdsqlite3_vfs object defines the interface between +** An instance of the sqlite3_vfs object defines the interface between ** the SQLite core and the underlying operating system. The "vfs" ** in the name of the object stands for "virtual file system". See ** the [VFS | VFS documentation] for further information. @@ -2240,34 +2240,34 @@ typedef struct tdsqlite3_api_routines tdsqlite3_api_routines; ** SQLite [version 3.5.0] on [dateof:3.5.0], then increased to 2 ** with SQLite [version 3.7.0] on [dateof:3.7.0], and then increased ** to 3 with SQLite [version 3.7.6] on [dateof:3.7.6]. Additional fields -** may be appended to the tdsqlite3_vfs object and the iVersion value +** may be appended to the sqlite3_vfs object and the iVersion value ** may increase again in future versions of SQLite. ** Note that due to an oversight, the structure -** of the tdsqlite3_vfs object changed in the transition from +** of the sqlite3_vfs object changed in the transition from ** SQLite [version 3.5.9] to [version 3.6.0] on [dateof:3.6.0] ** and yet the iVersion field was not increased. ** -** The szOsFile field is the size of the subclassed [tdsqlite3_file] +** The szOsFile field is the size of the subclassed [sqlite3_file] ** structure used by this VFS. mxPathname is the maximum length of ** a pathname in this VFS. ** -** Registered tdsqlite3_vfs objects are kept on a linked list formed by -** the pNext pointer. The [tdsqlite3_vfs_register()] -** and [tdsqlite3_vfs_unregister()] interfaces manage this list -** in a thread-safe way. The [tdsqlite3_vfs_find()] interface +** Registered sqlite3_vfs objects are kept on a linked list formed by +** the pNext pointer. The [sqlite3_vfs_register()] +** and [sqlite3_vfs_unregister()] interfaces manage this list +** in a thread-safe way. The [sqlite3_vfs_find()] interface ** searches the list. Neither the application code nor the VFS ** implementation should use the pNext pointer. ** -** The pNext field is the only field in the tdsqlite3_vfs +** The pNext field is the only field in the sqlite3_vfs ** structure that SQLite will ever modify. SQLite will only access ** or modify this field while holding a particular static mutex. -** The application should never modify anything within the tdsqlite3_vfs +** The application should never modify anything within the sqlite3_vfs ** object once the object has been registered. ** ** The zName field holds the name of the VFS module. The name must ** be unique across all VFS modules. ** -** [[tdsqlite3_vfs.xOpen]] +** [[sqlite3_vfs.xOpen]] ** ^SQLite guarantees that the zFilename parameter to xOpen ** is either a NULL pointer or string obtained ** from xFullPathname() with an optional suffix added. @@ -2277,7 +2277,7 @@ typedef struct tdsqlite3_api_routines tdsqlite3_api_routines; ** ^SQLite further guarantees that ** the string will be valid and unchanged until xClose() is ** called. Because of the previous sentence, -** the [tdsqlite3_file] can safely store a pointer to the +** the [sqlite3_file] can safely store a pointer to the ** filename if it needs to remember the filename for some reason. ** If the zFilename parameter to xOpen is a NULL pointer then xOpen ** must invent its own temporary name for the file. ^Whenever the @@ -2285,8 +2285,8 @@ typedef struct tdsqlite3_api_routines tdsqlite3_api_routines; ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. ** ** The flags argument to xOpen() includes all bits set in -** the flags argument to [tdsqlite3_open_v2()]. Or if [tdsqlite3_open()] -** or [tdsqlite3_open16()] is used, then flags includes at least +** the flags argument to [sqlite3_open_v2()]. Or if [sqlite3_open()] +** or [sqlite3_open16()] is used, then flags includes at least ** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. ** If xOpen() opens a file read-only then it sets *pOutFlags to ** include [SQLITE_OPEN_READONLY]. Other bits in *pOutFlags may be set. @@ -2336,16 +2336,16 @@ typedef struct tdsqlite3_api_routines tdsqlite3_api_routines; ** for exclusive access. ** ** ^At least szOsFile bytes of memory are allocated by SQLite -** to hold the [tdsqlite3_file] structure passed as the third +** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. The xOpen method does not have to ** allocate the structure; it should just fill it in. Note that -** the xOpen method must set the tdsqlite3_file.pMethods to either -** a valid [tdsqlite3_io_methods] object or to NULL. xOpen must do -** this even if the open fails. SQLite expects that the tdsqlite3_file.pMethods +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods ** element will be valid after xOpen returns regardless of the success ** or failure of the xOpen call. ** -** [[tdsqlite3_vfs.xAccess]] +** [[sqlite3_vfs.xAccess]] ** ^The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to ** test whether a file is readable and writable, or [SQLITE_ACCESS_READ] @@ -2395,40 +2395,40 @@ typedef struct tdsqlite3_api_routines tdsqlite3_api_routines; ** from one release to the next. Applications must not attempt to access ** any of these methods if the iVersion of the VFS is less than 3. */ -typedef struct tdsqlite3_vfs tdsqlite3_vfs; -typedef void (*tdsqlite3_syscall_ptr)(void); -struct tdsqlite3_vfs { +typedef struct sqlite3_vfs sqlite3_vfs; +typedef void (*sqlite3_syscall_ptr)(void); +struct sqlite3_vfs { int iVersion; /* Structure version number (currently 3) */ - int szOsFile; /* Size of subclassed tdsqlite3_file */ + int szOsFile; /* Size of subclassed sqlite3_file */ int mxPathname; /* Maximum file pathname length */ - tdsqlite3_vfs *pNext; /* Next registered VFS */ + sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(tdsqlite3_vfs*, const char *zName, tdsqlite3_file*, + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); - int (*xDelete)(tdsqlite3_vfs*, const char *zName, int syncDir); - int (*xAccess)(tdsqlite3_vfs*, const char *zName, int flags, int *pResOut); - int (*xFullPathname)(tdsqlite3_vfs*, const char *zName, int nOut, char *zOut); - void *(*xDlOpen)(tdsqlite3_vfs*, const char *zFilename); - void (*xDlError)(tdsqlite3_vfs*, int nByte, char *zErrMsg); - void (*(*xDlSym)(tdsqlite3_vfs*,void*, const char *zSymbol))(void); - void (*xDlClose)(tdsqlite3_vfs*, void*); - int (*xRandomness)(tdsqlite3_vfs*, int nByte, char *zOut); - int (*xSleep)(tdsqlite3_vfs*, int microseconds); - int (*xCurrentTime)(tdsqlite3_vfs*, double*); - int (*xGetLastError)(tdsqlite3_vfs*, int, char *); + int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); + int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); + int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut); + void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename); + void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg); + void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); + void (*xDlClose)(sqlite3_vfs*, void*); + int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut); + int (*xSleep)(sqlite3_vfs*, int microseconds); + int (*xCurrentTime)(sqlite3_vfs*, double*); + int (*xGetLastError)(sqlite3_vfs*, int, char *); /* ** The methods above are in version 1 of the sqlite_vfs object ** definition. Those that follow are added in version 2 or later */ - int (*xCurrentTimeInt64)(tdsqlite3_vfs*, tdsqlite3_int64*); + int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); /* ** The methods above are in versions 1 and 2 of the sqlite_vfs object. ** Those below are for version 3 and greater. */ - int (*xSetSystemCall)(tdsqlite3_vfs*, const char *zName, tdsqlite3_syscall_ptr); - tdsqlite3_syscall_ptr (*xGetSystemCall)(tdsqlite3_vfs*, const char *zName); - const char *(*xNextSystemCall)(tdsqlite3_vfs*, const char *zName); + int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr); + sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName); + const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName); /* ** The methods above are in versions 1 through 3 of the sqlite_vfs object. ** New fields may be appended in future versions. The iVersion @@ -2440,7 +2440,7 @@ struct tdsqlite3_vfs { ** CAPI3REF: Flags for the xAccess VFS method ** ** These integer constants can be used as the third parameter to -** the xAccess method of an [tdsqlite3_vfs] object. They determine +** the xAccess method of an [sqlite3_vfs] object. They determine ** what kind of permissions the xAccess method is looking for. ** With SQLITE_ACCESS_EXISTS, the xAccess method ** simply checks whether the file exists. @@ -2464,7 +2464,7 @@ struct tdsqlite3_vfs { ** CAPI3REF: Flags for the xShmLock VFS method ** ** These integer constants define the various locking operations -** allowed by the xShmLock method of [tdsqlite3_io_methods]. The +** allowed by the xShmLock method of [sqlite3_io_methods]. The ** following are the only legal combinations of flags to the ** xShmLock method: ** @@ -2490,7 +2490,7 @@ struct tdsqlite3_vfs { /* ** CAPI3REF: Maximum xShmLock index ** -** The xShmLock method on [tdsqlite3_io_methods] may use values +** The xShmLock method on [sqlite3_io_methods] may use values ** between 0 and this upper bound as its "offset" argument. ** The SQLite core will never attempt to acquire or release a ** lock outside of this range @@ -2501,134 +2501,134 @@ struct tdsqlite3_vfs { /* ** CAPI3REF: Initialize The SQLite Library ** -** ^The tdsqlite3_initialize() routine initializes the -** SQLite library. ^The tdsqlite3_shutdown() routine -** deallocates any resources that were allocated by tdsqlite3_initialize(). +** ^The sqlite3_initialize() routine initializes the +** SQLite library. ^The sqlite3_shutdown() routine +** deallocates any resources that were allocated by sqlite3_initialize(). ** These routines are designed to aid in process initialization and ** shutdown on embedded systems. Workstation applications using ** SQLite normally do not need to invoke either of these routines. ** -** A call to tdsqlite3_initialize() is an "effective" call if it is -** the first time tdsqlite3_initialize() is invoked during the lifetime of -** the process, or if it is the first time tdsqlite3_initialize() is invoked -** following a call to tdsqlite3_shutdown(). ^(Only an effective call -** of tdsqlite3_initialize() does any initialization. All other calls +** A call to sqlite3_initialize() is an "effective" call if it is +** the first time sqlite3_initialize() is invoked during the lifetime of +** the process, or if it is the first time sqlite3_initialize() is invoked +** following a call to sqlite3_shutdown(). ^(Only an effective call +** of sqlite3_initialize() does any initialization. All other calls ** are harmless no-ops.)^ ** -** A call to tdsqlite3_shutdown() is an "effective" call if it is the first -** call to tdsqlite3_shutdown() since the last tdsqlite3_initialize(). ^(Only -** an effective call to tdsqlite3_shutdown() does any deinitialization. -** All other valid calls to tdsqlite3_shutdown() are harmless no-ops.)^ +** A call to sqlite3_shutdown() is an "effective" call if it is the first +** call to sqlite3_shutdown() since the last sqlite3_initialize(). ^(Only +** an effective call to sqlite3_shutdown() does any deinitialization. +** All other valid calls to sqlite3_shutdown() are harmless no-ops.)^ ** -** The tdsqlite3_initialize() interface is threadsafe, but tdsqlite3_shutdown() -** is not. The tdsqlite3_shutdown() interface must only be called from a +** The sqlite3_initialize() interface is threadsafe, but sqlite3_shutdown() +** is not. The sqlite3_shutdown() interface must only be called from a ** single thread. All open [database connections] must be closed and all ** other SQLite resources must be deallocated prior to invoking -** tdsqlite3_shutdown(). +** sqlite3_shutdown(). ** -** Among other things, ^tdsqlite3_initialize() will invoke -** tdsqlite3_os_init(). Similarly, ^tdsqlite3_shutdown() -** will invoke tdsqlite3_os_end(). +** Among other things, ^sqlite3_initialize() will invoke +** sqlite3_os_init(). Similarly, ^sqlite3_shutdown() +** will invoke sqlite3_os_end(). ** -** ^The tdsqlite3_initialize() routine returns [SQLITE_OK] on success. -** ^If for some reason, tdsqlite3_initialize() is unable to initialize +** ^The sqlite3_initialize() routine returns [SQLITE_OK] on success. +** ^If for some reason, sqlite3_initialize() is unable to initialize ** the library (perhaps it is unable to allocate a needed resource such ** as a mutex) it returns an [error code] other than [SQLITE_OK]. ** -** ^The tdsqlite3_initialize() routine is called internally by many other +** ^The sqlite3_initialize() routine is called internally by many other ** SQLite interfaces so that an application usually does not need to -** invoke tdsqlite3_initialize() directly. For example, [tdsqlite3_open()] -** calls tdsqlite3_initialize() so the SQLite library will be automatically -** initialized when [tdsqlite3_open()] is called if it has not be initialized +** invoke sqlite3_initialize() directly. For example, [sqlite3_open()] +** calls sqlite3_initialize() so the SQLite library will be automatically +** initialized when [sqlite3_open()] is called if it has not be initialized ** already. ^However, if SQLite is compiled with the [SQLITE_OMIT_AUTOINIT] -** compile-time option, then the automatic calls to tdsqlite3_initialize() -** are omitted and the application must call tdsqlite3_initialize() directly +** compile-time option, then the automatic calls to sqlite3_initialize() +** are omitted and the application must call sqlite3_initialize() directly ** prior to using any other SQLite interface. For maximum portability, -** it is recommended that applications always invoke tdsqlite3_initialize() +** it is recommended that applications always invoke sqlite3_initialize() ** directly prior to using any other SQLite interface. Future releases ** of SQLite may require this. In other words, the behavior exhibited ** when SQLite is compiled with [SQLITE_OMIT_AUTOINIT] might become the ** default behavior in some future release of SQLite. ** -** The tdsqlite3_os_init() routine does operating-system specific -** initialization of the SQLite library. The tdsqlite3_os_end() -** routine undoes the effect of tdsqlite3_os_init(). Typical tasks +** The sqlite3_os_init() routine does operating-system specific +** initialization of the SQLite library. The sqlite3_os_end() +** routine undoes the effect of sqlite3_os_init(). Typical tasks ** performed by these routines include allocation or deallocation ** of static resources, initialization of global variables, -** setting up a default [tdsqlite3_vfs] module, or setting up -** a default configuration using [tdsqlite3_config()]. -** -** The application should never invoke either tdsqlite3_os_init() -** or tdsqlite3_os_end() directly. The application should only invoke -** tdsqlite3_initialize() and tdsqlite3_shutdown(). The tdsqlite3_os_init() -** interface is called automatically by tdsqlite3_initialize() and -** tdsqlite3_os_end() is called by tdsqlite3_shutdown(). Appropriate -** implementations for tdsqlite3_os_init() and tdsqlite3_os_end() +** setting up a default [sqlite3_vfs] module, or setting up +** a default configuration using [sqlite3_config()]. +** +** The application should never invoke either sqlite3_os_init() +** or sqlite3_os_end() directly. The application should only invoke +** sqlite3_initialize() and sqlite3_shutdown(). The sqlite3_os_init() +** interface is called automatically by sqlite3_initialize() and +** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate +** implementations for sqlite3_os_init() and sqlite3_os_end() ** are built into SQLite when it is compiled for Unix, Windows, or OS/2. ** When [custom builds | built for other platforms] ** (using the [SQLITE_OS_OTHER=1] compile-time ** option) the application must supply a suitable implementation for -** tdsqlite3_os_init() and tdsqlite3_os_end(). An application-supplied -** implementation of tdsqlite3_os_init() or tdsqlite3_os_end() +** sqlite3_os_init() and sqlite3_os_end(). An application-supplied +** implementation of sqlite3_os_init() or sqlite3_os_end() ** must return [SQLITE_OK] on success and some other [error code] upon ** failure. */ -SQLITE_API int tdsqlite3_initialize(void); -SQLITE_API int tdsqlite3_shutdown(void); -SQLITE_API int tdsqlite3_os_init(void); -SQLITE_API int tdsqlite3_os_end(void); +SQLITE_API int sqlite3_initialize(void); +SQLITE_API int sqlite3_shutdown(void); +SQLITE_API int sqlite3_os_init(void); +SQLITE_API int sqlite3_os_end(void); /* ** CAPI3REF: Configuring The SQLite Library ** -** The tdsqlite3_config() interface is used to make global configuration +** The sqlite3_config() interface is used to make global configuration ** changes to SQLite in order to tune SQLite to the specific needs of ** the application. The default configuration is recommended for most ** applications and so this routine is usually not necessary. It is ** provided to support rare applications with unusual needs. ** -** The tdsqlite3_config() interface is not threadsafe. The application +** The sqlite3_config() interface is not threadsafe. The application ** must ensure that no other SQLite interfaces are invoked by other -** threads while tdsqlite3_config() is running. +** threads while sqlite3_config() is running. ** -** The tdsqlite3_config() interface +** The sqlite3_config() interface ** may only be invoked prior to library initialization using -** [tdsqlite3_initialize()] or after shutdown by [tdsqlite3_shutdown()]. -** ^If tdsqlite3_config() is called after [tdsqlite3_initialize()] and before -** [tdsqlite3_shutdown()] then it will return SQLITE_MISUSE. -** Note, however, that ^tdsqlite3_config() can be called as part of the -** implementation of an application-defined [tdsqlite3_os_init()]. +** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()]. +** ^If sqlite3_config() is called after [sqlite3_initialize()] and before +** [sqlite3_shutdown()] then it will return SQLITE_MISUSE. +** Note, however, that ^sqlite3_config() can be called as part of the +** implementation of an application-defined [sqlite3_os_init()]. ** -** The first argument to tdsqlite3_config() is an integer +** The first argument to sqlite3_config() is an integer ** [configuration option] that determines ** what property of SQLite is to be configured. Subsequent arguments ** vary depending on the [configuration option] ** in the first argument. ** -** ^When a configuration option is set, tdsqlite3_config() returns [SQLITE_OK]. +** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code]. */ -SQLITE_API int tdsqlite3_config(int, ...); +SQLITE_API int sqlite3_config(int, ...); /* ** CAPI3REF: Configure database connections -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** The tdsqlite3_db_config() interface is used to make configuration +** The sqlite3_db_config() interface is used to make configuration ** changes to a [database connection]. The interface is similar to -** [tdsqlite3_config()] except that the changes apply to a single +** [sqlite3_config()] except that the changes apply to a single ** [database connection] (specified in the first argument). ** -** The second argument to tdsqlite3_db_config(D,V,...) is the +** The second argument to sqlite3_db_config(D,V,...) is the ** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code ** that indicates what aspect of the [database connection] is being configured. ** Subsequent arguments vary depending on the configuration verb. ** -** ^Calls to tdsqlite3_db_config() return SQLITE_OK if and only if +** ^Calls to sqlite3_db_config() return SQLITE_OK if and only if ** the call is considered successful. */ -SQLITE_API int tdsqlite3_db_config(tdsqlite3*, int op, ...); +SQLITE_API int sqlite3_db_config(sqlite3*, int op, ...); /* ** CAPI3REF: Memory Allocation Routines @@ -2638,10 +2638,10 @@ SQLITE_API int tdsqlite3_db_config(tdsqlite3*, int op, ...); ** ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to -** [tdsqlite3_config()] when the configuration option is +** [sqlite3_config()] when the configuration option is ** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. ** By creating an instance of this object -** and passing it to [tdsqlite3_config]([SQLITE_CONFIG_MALLOC]) +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) ** during configuration, an application can specify an alternative ** memory allocation subsystem for SQLite to use for all of its ** dynamic memory needs. @@ -2668,20 +2668,20 @@ SQLITE_API int tdsqlite3_db_config(tdsqlite3*, int op, ...); ** a memory allocation given a particular requested size. Most memory ** allocators round up memory allocations at least to the next multiple ** of 8. Some allocators round up to a larger multiple or to a power of 2. -** Every memory allocation request coming in through [tdsqlite3_malloc()] -** or [tdsqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, ** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. For example, ** it might allocate any required mutexes or initialize internal data ** structures. The xShutdown method is invoked (indirectly) by -** [tdsqlite3_shutdown()] and should deallocate any resources acquired +** [sqlite3_shutdown()] and should deallocate any resources acquired ** by xInit. The pAppData pointer is used as the only parameter to ** xInit and xShutdown. ** ** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes ** the xInit method, so the xInit method need not be threadsafe. The -** xShutdown method is only called from [tdsqlite3_shutdown()] so it does +** xShutdown method is only called from [sqlite3_shutdown()] so it does ** not need to be threadsafe either. For all other methods, SQLite ** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the ** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which @@ -2693,8 +2693,8 @@ SQLITE_API int tdsqlite3_db_config(tdsqlite3*, int op, ...); ** SQLite will never invoke xInit() more than once without an intervening ** call to xShutdown(). */ -typedef struct tdsqlite3_mem_methods tdsqlite3_mem_methods; -struct tdsqlite3_mem_methods { +typedef struct sqlite3_mem_methods sqlite3_mem_methods; +struct sqlite3_mem_methods { void *(*xMalloc)(int); /* Memory allocation function */ void (*xFree)(void*); /* Free a prior allocation */ void *(*xRealloc)(void*,int); /* Resize an allocation */ @@ -2710,12 +2710,12 @@ struct tdsqlite3_mem_methods { ** KEYWORDS: {configuration option} ** ** These constants are the available integer configuration options that -** can be passed as the first argument to the [tdsqlite3_config()] interface. +** can be passed as the first argument to the [sqlite3_config()] interface. ** ** New configuration options may be added in future releases of SQLite. ** Existing configuration options might be discontinued. Applications -** should check the return code from [tdsqlite3_config()] to make sure that -** the call worked. The [tdsqlite3_config()] interface will return a +** should check the return code from [sqlite3_config()] to make sure that +** the call worked. The [sqlite3_config()] interface will return a ** non-zero [error code] if a discontinued or unsupported configuration option ** is invoked. ** @@ -2727,7 +2727,7 @@ struct tdsqlite3_mem_methods { ** by a single thread. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** it is not possible to change the [threading mode] from its default -** value of Single-thread and so [tdsqlite3_config()] will return +** value of Single-thread and so [sqlite3_config()] will return ** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD ** configuration option. ** @@ -2742,7 +2742,7 @@ struct tdsqlite3_mem_methods { ** [database connection] at the same time. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** it is not possible to set the Multi-thread [threading mode] and -** [tdsqlite3_config()] will return [SQLITE_ERROR] if called with the +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the ** SQLITE_CONFIG_MULTITHREAD configuration option. ** ** [[SQLITE_CONFIG_SERIALIZED]]
    SQLITE_CONFIG_SERIALIZED
    @@ -2758,22 +2758,22 @@ struct tdsqlite3_mem_methods { ** ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** it is not possible to set the Serialized [threading mode] and -** [tdsqlite3_config()] will return [SQLITE_ERROR] if called with the +** [sqlite3_config()] will return [SQLITE_ERROR] if called with the ** SQLITE_CONFIG_SERIALIZED configuration option. ** ** [[SQLITE_CONFIG_MALLOC]]
    SQLITE_CONFIG_MALLOC
    **
    ^(The SQLITE_CONFIG_MALLOC option takes a single argument which is -** a pointer to an instance of the [tdsqlite3_mem_methods] structure. +** a pointer to an instance of the [sqlite3_mem_methods] structure. ** The argument specifies ** alternative low-level memory allocation routines to be used in place of ** the memory allocation routines built into SQLite.)^ ^SQLite makes -** its own private copy of the content of the [tdsqlite3_mem_methods] structure -** before the [tdsqlite3_config()] call returns.
    +** its own private copy of the content of the [sqlite3_mem_methods] structure +** before the [sqlite3_config()] call returns. ** ** [[SQLITE_CONFIG_GETMALLOC]]
    SQLITE_CONFIG_GETMALLOC
    **
    ^(The SQLITE_CONFIG_GETMALLOC option takes a single argument which -** is a pointer to an instance of the [tdsqlite3_mem_methods] structure. -** The [tdsqlite3_mem_methods] +** is a pointer to an instance of the [sqlite3_mem_methods] structure. +** The [sqlite3_mem_methods] ** structure is filled with the currently defined memory allocation routines.)^ ** This option can be used to overload the default memory allocation ** routines with a wrapper that simulations memory allocation failure or @@ -2795,11 +2795,11 @@ struct tdsqlite3_mem_methods { ** memory allocation statistics. ^(When memory allocation statistics are ** disabled, the following SQLite interfaces become non-operational: **
      -**
    • [tdsqlite3_hard_heap_limit64()] -**
    • [tdsqlite3_memory_used()] -**
    • [tdsqlite3_memory_highwater()] -**
    • [tdsqlite3_soft_heap_limit64()] -**
    • [tdsqlite3_status64()] +**
    • [sqlite3_hard_heap_limit64()] +**
    • [sqlite3_memory_used()] +**
    • [sqlite3_memory_highwater()] +**
    • [sqlite3_soft_heap_limit64()] +**
    • [sqlite3_status64()] **
    )^ ** ^Memory allocation statistics are enabled by default unless SQLite is ** compiled with [SQLITE_DEFAULT_MEMSTATUS]=0 in which case memory @@ -2829,15 +2829,15 @@ struct tdsqlite3_mem_methods { ** aligned block of memory of at least sz*N bytes, otherwise ** subsequent behavior is undefined. ** ^When pMem is not NULL, SQLite will strive to use the memory provided -** to satisfy page cache needs, falling back to [tdsqlite3_malloc()] if +** to satisfy page cache needs, falling back to [sqlite3_malloc()] if ** a page cache line is larger than sz bytes or if all of the pMem buffer ** is exhausted. ** ^If pMem is NULL and N is non-zero, then each database connection ** does an initial bulk allocation for page cache memory -** from [tdsqlite3_malloc()] sufficient for N cache lines if N is positive or +** from [sqlite3_malloc()] sufficient for N cache lines if N is positive or ** of -1024*N bytes if N is negative, . ^If additional ** page cache memory is needed beyond what is provided by the initial -** allocation, then SQLite goes to [tdsqlite3_malloc()] separately for each +** allocation, then SQLite goes to [sqlite3_malloc()] separately for each ** additional cache line.
    ** ** [[SQLITE_CONFIG_HEAP]]
    SQLITE_CONFIG_HEAP
    @@ -2862,27 +2862,27 @@ struct tdsqlite3_mem_methods { ** ** [[SQLITE_CONFIG_MUTEX]]
    SQLITE_CONFIG_MUTEX
    **
    ^(The SQLITE_CONFIG_MUTEX option takes a single argument which is a -** pointer to an instance of the [tdsqlite3_mutex_methods] structure. +** pointer to an instance of the [sqlite3_mutex_methods] structure. ** The argument specifies alternative low-level mutex routines to be used ** in place the mutex routines built into SQLite.)^ ^SQLite makes a copy of -** the content of the [tdsqlite3_mutex_methods] structure before the call to -** [tdsqlite3_config()] returns. ^If SQLite is compiled with +** the content of the [sqlite3_mutex_methods] structure before the call to +** [sqlite3_config()] returns. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** the entire mutexing subsystem is omitted from the build and hence calls to -** [tdsqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will +** [sqlite3_config()] with the SQLITE_CONFIG_MUTEX configuration option will ** return [SQLITE_ERROR].
    ** ** [[SQLITE_CONFIG_GETMUTEX]]
    SQLITE_CONFIG_GETMUTEX
    **
    ^(The SQLITE_CONFIG_GETMUTEX option takes a single argument which -** is a pointer to an instance of the [tdsqlite3_mutex_methods] structure. The -** [tdsqlite3_mutex_methods] +** is a pointer to an instance of the [sqlite3_mutex_methods] structure. The +** [sqlite3_mutex_methods] ** structure is filled with the currently defined mutex routines.)^ ** This option can be used to overload the default mutex allocation ** routines with a wrapper used to track mutex usage for performance ** profiling or testing, for example. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** the entire mutexing subsystem is omitted from the build and hence calls to -** [tdsqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will +** [sqlite3_config()] with the SQLITE_CONFIG_GETMUTEX configuration option will ** return [SQLITE_ERROR].
    ** ** [[SQLITE_CONFIG_LOOKASIDE]]
    SQLITE_CONFIG_LOOKASIDE
    @@ -2892,18 +2892,18 @@ struct tdsqlite3_mem_methods { ** size of each lookaside buffer slot and the second is the number of ** slots allocated to each database connection.)^ ^(SQLITE_CONFIG_LOOKASIDE ** sets the default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] -** option to [tdsqlite3_db_config()] can be used to change the lookaside +** option to [sqlite3_db_config()] can be used to change the lookaside ** configuration on individual connections.)^ ** ** [[SQLITE_CONFIG_PCACHE2]]
    SQLITE_CONFIG_PCACHE2
    **
    ^(The SQLITE_CONFIG_PCACHE2 option takes a single argument which is -** a pointer to an [tdsqlite3_pcache_methods2] object. This object specifies +** a pointer to an [sqlite3_pcache_methods2] object. This object specifies ** the interface to a custom page cache implementation.)^ -** ^SQLite makes a copy of the [tdsqlite3_pcache_methods2] object.
    +** ^SQLite makes a copy of the [sqlite3_pcache_methods2] object. ** ** [[SQLITE_CONFIG_GETPCACHE2]]
    SQLITE_CONFIG_GETPCACHE2
    **
    ^(The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which -** is a pointer to an [tdsqlite3_pcache_methods2] object. SQLite copies of +** is a pointer to an [sqlite3_pcache_methods2] object. SQLite copies of ** the current page cache implementation into that object.)^
    ** ** [[SQLITE_CONFIG_LOG]]
    SQLITE_CONFIG_LOG
    @@ -2912,15 +2912,15 @@ struct tdsqlite3_mem_methods { ** (^The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a ** function with a call signature of void(*)(void*,int,const char*), ** and a pointer to void. ^If the function pointer is not NULL, it is -** invoked by [tdsqlite3_log()] to process each logging event. ^If the -** function pointer is NULL, the [tdsqlite3_log()] interface becomes a no-op. +** invoked by [sqlite3_log()] to process each logging event. ^If the +** function pointer is NULL, the [sqlite3_log()] interface becomes a no-op. ** ^The void pointer that is the second argument to SQLITE_CONFIG_LOG is ** passed through as the first parameter to the application-defined logger ** function whenever that function is invoked. ^The second parameter to ** the logger function is a copy of the first parameter to the corresponding -** [tdsqlite3_log()] call and is intended to be a [result code] or an +** [sqlite3_log()] call and is intended to be a [result code] or an ** [extended result code]. ^The third parameter passed to the logger is -** log message after formatting via [tdsqlite3_snprintf()]. +** log message after formatting via [sqlite3_snprintf()]. ** The SQLite logging interface is not reentrant; the logger function ** supplied by the application must not invoke any SQLite interface. ** In a multi-threaded application, the application-defined logger @@ -2930,8 +2930,8 @@ struct tdsqlite3_mem_methods { **
    ^(The SQLITE_CONFIG_URI option takes a single argument of type int. ** If non-zero, then URI handling is globally enabled. If the parameter is zero, ** then URI handling is globally disabled.)^ ^If URI handling is globally -** enabled, all filenames passed to [tdsqlite3_open()], [tdsqlite3_open_v2()], -** [tdsqlite3_open16()] or +** enabled, all filenames passed to [sqlite3_open()], [sqlite3_open_v2()], +** [sqlite3_open16()] or ** specified as part of [ATTACH] commands are interpreted as URIs, regardless ** of whether or not the [SQLITE_OPEN_URI] flag is set when the database ** connection is opened. ^If it is globally disabled, filenames are @@ -2963,7 +2963,7 @@ struct tdsqlite3_mem_methods { **
    SQLITE_CONFIG_SQLLOG **
    This option is only available if sqlite is compiled with the ** [SQLITE_ENABLE_SQLLOG] pre-processor macro defined. The first argument should -** be a pointer to a function of type void(*)(void*,tdsqlite3*,const char*, int). +** be a pointer to a function of type void(*)(void*,sqlite3*,const char*, int). ** The second should be of type (void*). The callback is invoked by the library ** in three separate circumstances, identified by the value passed as the ** fourth parameter. If the fourth parameter is 0, then the database connection @@ -2978,7 +2978,7 @@ struct tdsqlite3_mem_methods { ** ** [[SQLITE_CONFIG_MMAP_SIZE]] **
    SQLITE_CONFIG_MMAP_SIZE -**
    ^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (tdsqlite3_int64) values +**
    ^SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values ** that are the default mmap size limit (the default setting for ** [PRAGMA mmap_size]) and the maximum allowed mmap size limit. ** ^The default setting can be overridden by each database connection using @@ -3049,10 +3049,10 @@ struct tdsqlite3_mem_methods { ** [[SQLITE_CONFIG_MEMDB_MAXSIZE]] **
    SQLITE_CONFIG_MEMDB_MAXSIZE **
    The SQLITE_CONFIG_MEMDB_MAXSIZE option accepts a single parameter -** [tdsqlite3_int64] parameter which is the default maximum size for an in-memory -** database created using [tdsqlite3_deserialize()]. This default maximum +** [sqlite3_int64] parameter which is the default maximum size for an in-memory +** database created using [sqlite3_deserialize()]. This default maximum ** size can be adjusted up or down for individual databases using the -** [SQLITE_FCNTL_SIZE_LIMIT] [tdsqlite3_file_control|file-control]. If this +** [SQLITE_FCNTL_SIZE_LIMIT] [sqlite3_file_control|file-control]. If this ** configuration setting is never used, then the default maximum is determined ** by the [SQLITE_MEMDB_DEFAULT_MAXSIZE] compile-time option. If that ** compile-time option is not set, then the default maximum is 1073741824. @@ -3061,43 +3061,43 @@ struct tdsqlite3_mem_methods { #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ -#define SQLITE_CONFIG_MALLOC 4 /* tdsqlite3_mem_methods* */ -#define SQLITE_CONFIG_GETMALLOC 5 /* tdsqlite3_mem_methods* */ +#define SQLITE_CONFIG_MALLOC 4 /* sqlite3_mem_methods* */ +#define SQLITE_CONFIG_GETMALLOC 5 /* sqlite3_mem_methods* */ #define SQLITE_CONFIG_SCRATCH 6 /* No longer used */ #define SQLITE_CONFIG_PAGECACHE 7 /* void*, int sz, int N */ #define SQLITE_CONFIG_HEAP 8 /* void*, int nByte, int min */ #define SQLITE_CONFIG_MEMSTATUS 9 /* boolean */ -#define SQLITE_CONFIG_MUTEX 10 /* tdsqlite3_mutex_methods* */ -#define SQLITE_CONFIG_GETMUTEX 11 /* tdsqlite3_mutex_methods* */ +#define SQLITE_CONFIG_MUTEX 10 /* sqlite3_mutex_methods* */ +#define SQLITE_CONFIG_GETMUTEX 11 /* sqlite3_mutex_methods* */ /* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */ #define SQLITE_CONFIG_LOOKASIDE 13 /* int int */ #define SQLITE_CONFIG_PCACHE 14 /* no-op */ #define SQLITE_CONFIG_GETPCACHE 15 /* no-op */ #define SQLITE_CONFIG_LOG 16 /* xFunc, void* */ #define SQLITE_CONFIG_URI 17 /* int */ -#define SQLITE_CONFIG_PCACHE2 18 /* tdsqlite3_pcache_methods2* */ -#define SQLITE_CONFIG_GETPCACHE2 19 /* tdsqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ +#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ -#define SQLITE_CONFIG_MMAP_SIZE 22 /* tdsqlite3_int64, tdsqlite3_int64 */ +#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ #define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ #define SQLITE_CONFIG_PCACHE_HDRSZ 24 /* int *psz */ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */ #define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ -#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* tdsqlite3_int64 */ +#define SQLITE_CONFIG_MEMDB_MAXSIZE 29 /* sqlite3_int64 */ /* ** CAPI3REF: Database Connection Configuration Options ** ** These constants are the available integer configuration options that -** can be passed as the second argument to the [tdsqlite3_db_config()] interface. +** can be passed as the second argument to the [sqlite3_db_config()] interface. ** ** New configuration options may be added in future releases of SQLite. ** Existing configuration options might be discontinued. Applications -** should check the return code from [tdsqlite3_db_config()] to make sure that -** the call worked. ^The [tdsqlite3_db_config()] interface will return a +** should check the return code from [sqlite3_db_config()] to make sure that +** the call worked. ^The [sqlite3_db_config()] interface will return a ** non-zero [error code] if a discontinued or unsupported configuration option ** is invoked. ** @@ -3106,11 +3106,11 @@ struct tdsqlite3_mem_methods { **
    SQLITE_DBCONFIG_LOOKASIDE
    **
    ^This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. -** ^The first argument (the third parameter to [tdsqlite3_db_config()] is a +** ^The first argument (the third parameter to [sqlite3_db_config()] is a ** pointer to a memory buffer to use for lookaside memory. ** ^The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb ** may be NULL in which case SQLite will allocate the -** lookaside buffer itself using [tdsqlite3_malloc()]. ^The second argument is the +** lookaside buffer itself using [sqlite3_malloc()]. ^The second argument is the ** size of each lookaside buffer slot. ^The third argument is the number of ** slots. The size of the buffer in the first argument must be greater than ** or equal to the product of the second and third arguments. The buffer @@ -3120,7 +3120,7 @@ struct tdsqlite3_mem_methods { ** configuration for a database connection can only be changed when that ** connection is not currently using lookaside memory, or in other words ** when the "current value" returned by -** [tdsqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. +** [sqlite3_db_status](D,[SQLITE_CONFIG_LOOKASIDE],...) is zero. ** Any attempt to change the lookaside memory configuration when lookaside ** memory is in use leaves the configuration unchanged and returns ** [SQLITE_BUSY].)^
    @@ -3174,10 +3174,10 @@ struct tdsqlite3_mem_methods { ** ** [[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION]] **
    SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION
    -**
    ^This option is used to enable or disable the [tdsqlite3_load_extension()] +**
    ^This option is used to enable or disable the [sqlite3_load_extension()] ** interface independently of the [load_extension()] SQL function. -** The [tdsqlite3_enable_load_extension()] API enables or disables both the -** C-API [tdsqlite3_load_extension()] and the SQL function [load_extension()]. +** The [sqlite3_enable_load_extension()] API enables or disables both the +** C-API [sqlite3_load_extension()] and the SQL function [load_extension()]. ** There should be two additional arguments. ** When the first argument to this interface is 1, then only the C-API is ** enabled and the SQL function remains disabled. If the first argument to @@ -3185,7 +3185,7 @@ struct tdsqlite3_mem_methods { ** If the first argument is -1, then no changes are made to state of either the ** C-API or the SQL function. ** The second parameter is a pointer to an integer into which -** is written 0 or 1 to indicate whether [tdsqlite3_load_extension()] interface +** is written 0 or 1 to indicate whether [sqlite3_load_extension()] interface ** is disabled or enabled following this call. The second parameter may ** be a NULL pointer, in which case the new setting is not reported back. **
    @@ -3249,13 +3249,13 @@ struct tdsqlite3_mem_methods { **
      **
    1. If the database connection is newly opened, make sure it has read the ** database schema by preparing then discarding some query against the -** database, or calling tdsqlite3_table_column_metadata(), ignoring any +** database, or calling sqlite3_table_column_metadata(), ignoring any ** errors. This step is only necessary if the application desires to keep ** the database in WAL mode after the reset if it was in WAL mode before ** the reset. -**
    2. tdsqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); -**
    3. [tdsqlite3_exec](db, "[VACUUM]", 0, 0, 0); -**
    4. tdsqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); +**
    5. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); +**
    6. [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); +**
    7. sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); **
    ** Because resetting a database is destructive and irreversible, the ** process requires the use of this obscure API and multiple steps to help @@ -3380,17 +3380,17 @@ struct tdsqlite3_mem_methods { /* ** CAPI3REF: Enable Or Disable Extended Result Codes -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_extended_result_codes() routine enables or disables the +** ^The sqlite3_extended_result_codes() routine enables or disables the ** [extended result codes] feature of SQLite. ^The extended result ** codes are disabled by default for historical compatibility. */ -SQLITE_API int tdsqlite3_extended_result_codes(tdsqlite3*, int onoff); +SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); /* ** CAPI3REF: Last Insert Rowid -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^Each entry in most SQLite tables (except for [WITHOUT ROWID] tables) ** has a unique 64-bit signed @@ -3400,16 +3400,16 @@ SQLITE_API int tdsqlite3_extended_result_codes(tdsqlite3*, int onoff); ** the table has a column of type [INTEGER PRIMARY KEY] then that column ** is another alias for the rowid. ** -** ^The tdsqlite3_last_insert_rowid(D) interface usually returns the [rowid] of +** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of ** the most recent successful [INSERT] into a rowid table or [virtual table] ** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not ** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred -** on the database connection D, then tdsqlite3_last_insert_rowid(D) returns +** on the database connection D, then sqlite3_last_insert_rowid(D) returns ** zero. ** ** As well as being set automatically as rows are inserted into database ** tables, the value returned by this function may be set explicitly by -** [tdsqlite3_set_last_insert_rowid()] +** [sqlite3_set_last_insert_rowid()] ** ** Some virtual table implementations may INSERT rows into rowid tables as ** part of committing a transaction (e.g. to flush data accumulated in memory @@ -3417,7 +3417,7 @@ SQLITE_API int tdsqlite3_extended_result_codes(tdsqlite3*, int onoff); ** associated with these internal INSERT operations, which leads to ** unintuitive results. Virtual table implementations that do write to rowid ** tables in this way can avoid this problem by restoring the original -** rowid value using [tdsqlite3_set_last_insert_rowid()] before returning +** rowid value using [sqlite3_set_last_insert_rowid()] before returning ** control to the user. ** ** ^(If an [INSERT] occurs within a trigger then this routine will @@ -3442,27 +3442,27 @@ SQLITE_API int tdsqlite3_extended_result_codes(tdsqlite3*, int onoff); ** [last_insert_rowid() SQL function]. ** ** If a separate thread performs a new [INSERT] on the same -** database connection while the [tdsqlite3_last_insert_rowid()] +** database connection while the [sqlite3_last_insert_rowid()] ** function is running and thus changes the last insert [rowid], -** then the value returned by [tdsqlite3_last_insert_rowid()] is +** then the value returned by [sqlite3_last_insert_rowid()] is ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ -SQLITE_API tdsqlite3_int64 tdsqlite3_last_insert_rowid(tdsqlite3*); +SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); /* ** CAPI3REF: Set the Last Insert Rowid value. -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** The tdsqlite3_set_last_insert_rowid(D, R) method allows the application to -** set the value returned by calling tdsqlite3_last_insert_rowid(D) to R +** The sqlite3_set_last_insert_rowid(D, R) method allows the application to +** set the value returned by calling sqlite3_last_insert_rowid(D) to R ** without inserting a row into the database. */ -SQLITE_API void tdsqlite3_set_last_insert_rowid(tdsqlite3*,tdsqlite3_int64); +SQLITE_API void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); /* ** CAPI3REF: Count The Number Of Rows Modified -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^This function returns the number of rows modified, inserted or ** deleted by the most recently completed INSERT, UPDATE or DELETE @@ -3476,24 +3476,24 @@ SQLITE_API void tdsqlite3_set_last_insert_rowid(tdsqlite3*,tdsqlite3_int64); ** ** Changes to a view that are intercepted by ** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value -** returned by tdsqlite3_changes() immediately after an INSERT, UPDATE or +** returned by sqlite3_changes() immediately after an INSERT, UPDATE or ** DELETE statement run on a view is always zero. Only changes made to real ** tables are counted. ** -** Things are more complicated if the tdsqlite3_changes() function is +** Things are more complicated if the sqlite3_changes() function is ** executed while a trigger program is running. This may happen if the ** program uses the [changes() SQL function], or if some other callback -** function invokes tdsqlite3_changes() directly. Essentially: +** function invokes sqlite3_changes() directly. Essentially: ** **
      **
    • ^(Before entering a trigger program the value returned by -** tdsqlite3_changes() function is saved. After the trigger program +** sqlite3_changes() function is saved. After the trigger program ** has finished, the original value is restored.)^ ** **
    • ^(Within a trigger program each INSERT, UPDATE and DELETE -** statement sets the value returned by tdsqlite3_changes() +** statement sets the value returned by sqlite3_changes() ** upon completion as normal. Of course, this value will not include -** any changes performed by sub-triggers, as the tdsqlite3_changes() +** any changes performed by sub-triggers, as the sqlite3_changes() ** value will be saved and restored after each sub-trigger has run.)^ **
    ** @@ -3505,35 +3505,35 @@ SQLITE_API void tdsqlite3_set_last_insert_rowid(tdsqlite3*,tdsqlite3_int64); ** previous INSERT, UPDATE or DELETE statement within the same trigger. ** ** If a separate thread makes changes on the same database connection -** while [tdsqlite3_changes()] is running then the value returned +** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. ** ** See also: **
      -**
    • the [tdsqlite3_total_changes()] interface +**
    • the [sqlite3_total_changes()] interface **
    • the [count_changes pragma] **
    • the [changes() SQL function] **
    • the [data_version pragma] **
    */ -SQLITE_API int tdsqlite3_changes(tdsqlite3*); +SQLITE_API int sqlite3_changes(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^This function returns the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed ** since the database connection was opened, including those executed as ** part of trigger programs. ^Executing any other type of SQL statement -** does not affect the value returned by tdsqlite3_total_changes(). +** does not affect the value returned by sqlite3_total_changes(). ** ** ^Changes made as part of [foreign key actions] are included in the ** count, but those made as part of REPLACE constraint resolution are ** not. ^Changes to a view that are intercepted by INSTEAD OF triggers ** are not counted. ** -** The [tdsqlite3_total_changes(D)] interface only reports the number +** The [sqlite3_total_changes(D)] interface only reports the number ** of rows that changed due to SQL statement run against database ** connection D. Any changes by other database connections are ignored. ** To detect changes against a database file from other database @@ -3541,23 +3541,23 @@ SQLITE_API int tdsqlite3_changes(tdsqlite3*); ** [SQLITE_FCNTL_DATA_VERSION] [file control]. ** ** If a separate thread makes changes on the same database connection -** while [tdsqlite3_total_changes()] is running then the value +** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. ** ** See also: **
      -**
    • the [tdsqlite3_changes()] interface +**
    • the [sqlite3_changes()] interface **
    • the [count_changes pragma] **
    • the [changes() SQL function] **
    • the [data_version pragma] **
    • the [SQLITE_FCNTL_DATA_VERSION] [file control] **
    */ -SQLITE_API int tdsqlite3_total_changes(tdsqlite3*); +SQLITE_API int sqlite3_total_changes(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^This function causes any pending database operation to abort and ** return at its earliest opportunity. This routine is typically @@ -3568,10 +3568,10 @@ SQLITE_API int tdsqlite3_total_changes(tdsqlite3*); ** ^It is safe to call this routine from a thread different from the ** thread that is currently running the database operation. But it ** is not safe to call this routine with a [database connection] that -** is closed or might close before tdsqlite3_interrupt() returns. +** is closed or might close before sqlite3_interrupt() returns. ** ** ^If an SQL operation is very nearly finished at the time when -** tdsqlite3_interrupt() is called, then it might not have an opportunity +** sqlite3_interrupt() is called, then it might not have an opportunity ** to be interrupted and might continue to completion. ** ** ^An SQL operation that is interrupted will return [SQLITE_INTERRUPT]. @@ -3579,18 +3579,18 @@ SQLITE_API int tdsqlite3_total_changes(tdsqlite3*); ** that is inside an explicit transaction, then the entire transaction ** will be rolled back automatically. ** -** ^The tdsqlite3_interrupt(D) call is in effect until all currently running +** ^The sqlite3_interrupt(D) call is in effect until all currently running ** SQL statements on [database connection] D complete. ^Any new SQL statements -** that are started after the tdsqlite3_interrupt() call and before the +** that are started after the sqlite3_interrupt() call and before the ** running statement count reaches zero are interrupted as if they had been -** running prior to the tdsqlite3_interrupt() call. ^New SQL statements +** running prior to the sqlite3_interrupt() call. ^New SQL statements ** that are started after the running statement count reaches zero are -** not effected by the tdsqlite3_interrupt(). -** ^A call to tdsqlite3_interrupt(D) that occurs when there are no running +** not effected by the sqlite3_interrupt(). +** ^A call to sqlite3_interrupt(D) that occurs when there are no running ** SQL statements is a no-op and has no effect on SQL statements -** that are started after the tdsqlite3_interrupt() call returns. +** that are started after the sqlite3_interrupt() call returns. */ -SQLITE_API void tdsqlite3_interrupt(tdsqlite3*); +SQLITE_API void sqlite3_interrupt(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete @@ -3613,40 +3613,40 @@ SQLITE_API void tdsqlite3_interrupt(tdsqlite3*); ** ^These routines do not parse the SQL statements thus ** will not detect syntactically incorrect SQL. ** -** ^(If SQLite has not been initialized using [tdsqlite3_initialize()] prior -** to invoking tdsqlite3_complete16() then tdsqlite3_initialize() is invoked -** automatically by tdsqlite3_complete16(). If that initialization fails, -** then the return value from tdsqlite3_complete16() will be non-zero +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked +** automatically by sqlite3_complete16(). If that initialization fails, +** then the return value from sqlite3_complete16() will be non-zero ** regardless of whether or not the input SQL is complete.)^ ** -** The input to [tdsqlite3_complete()] must be a zero-terminated +** The input to [sqlite3_complete()] must be a zero-terminated ** UTF-8 string. ** -** The input to [tdsqlite3_complete16()] must be a zero-terminated +** The input to [sqlite3_complete16()] must be a zero-terminated ** UTF-16 string in native byte order. */ -SQLITE_API int tdsqlite3_complete(const char *sql); -SQLITE_API int tdsqlite3_complete16(const void *sql); +SQLITE_API int sqlite3_complete(const char *sql); +SQLITE_API int sqlite3_complete16(const void *sql); /* ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors ** KEYWORDS: {busy-handler callback} {busy handler} -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_busy_handler(D,X,P) routine sets a callback function X +** ^The sqlite3_busy_handler(D,X,P) routine sets a callback function X ** that might be invoked with argument P whenever ** an attempt is made to access a database table associated with ** [database connection] D when another thread ** or process has the table locked. -** The tdsqlite3_busy_handler() interface is used to implement -** [tdsqlite3_busy_timeout()] and [PRAGMA busy_timeout]. +** The sqlite3_busy_handler() interface is used to implement +** [sqlite3_busy_timeout()] and [PRAGMA busy_timeout]. ** ** ^If the busy callback is NULL, then [SQLITE_BUSY] ** is returned immediately upon encountering the lock. ^If the busy callback ** is not NULL, then the callback might be invoked with two arguments. ** ** ^The first argument to the busy handler is a copy of the void* pointer which -** is the third argument to tdsqlite3_busy_handler(). ^The second argument to +** is the third argument to sqlite3_busy_handler(). ^The second argument to ** the busy handler callback is the number of times that the busy handler has ** been invoked previously for the same locking event. ^If the ** busy callback returns 0, then no additional attempts are made to @@ -3675,7 +3675,7 @@ SQLITE_API int tdsqlite3_complete16(const void *sql); ** ** ^(There can only be a single busy handler defined for each ** [database connection]. Setting a new busy handler clears any -** previously set handler.)^ ^Note that calling [tdsqlite3_busy_timeout()] +** previously set handler.)^ ^Note that calling [sqlite3_busy_timeout()] ** or evaluating [PRAGMA busy_timeout=N] will change the ** busy handler and thus clear any previously set busy handler. ** @@ -3687,17 +3687,17 @@ SQLITE_API int tdsqlite3_complete16(const void *sql); ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ -SQLITE_API int tdsqlite3_busy_handler(tdsqlite3*,int(*)(void*,int),void*); +SQLITE_API int sqlite3_busy_handler(sqlite3*,int(*)(void*,int),void*); /* ** CAPI3REF: Set A Busy Timeout -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^This routine sets a [tdsqlite3_busy_handler | busy handler] that sleeps +** ^This routine sets a [sqlite3_busy_handler | busy handler] that sleeps ** for a specified amount of time when a table is locked. ^The handler ** will sleep multiple times until at least "ms" milliseconds of sleeping ** have accumulated. ^After at least "ms" milliseconds of sleeping, -** the handler returns 0 which causes [tdsqlite3_step()] to return +** the handler returns 0 which causes [sqlite3_step()] to return ** [SQLITE_BUSY]. ** ** ^Calling this routine with an argument less than or equal to zero @@ -3705,22 +3705,22 @@ SQLITE_API int tdsqlite3_busy_handler(tdsqlite3*,int(*)(void*,int),void*); ** ** ^(There can only be a single busy handler for a particular ** [database connection] at any given moment. If another busy handler -** was defined (using [tdsqlite3_busy_handler()]) prior to calling +** was defined (using [sqlite3_busy_handler()]) prior to calling ** this routine, that other busy handler is cleared.)^ ** ** See also: [PRAGMA busy_timeout] */ -SQLITE_API int tdsqlite3_busy_timeout(tdsqlite3*, int ms); +SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** This is a legacy interface that is preserved for backwards compatibility. ** Use of this interface is not recommended. ** ** Definition: A result table is memory data structure created by the -** [tdsqlite3_get_table()] interface. A result table records the +** [sqlite3_get_table()] interface. A result table records the ** complete query results from one or more queries. ** ** The table conceptually has a number of rows and columns. But @@ -3733,11 +3733,11 @@ SQLITE_API int tdsqlite3_busy_timeout(tdsqlite3*, int ms); ** to zero-terminated strings that contain the names of the columns. ** The remaining entries all point to query results. NULL values result ** in NULL pointers. All other values are in their UTF-8 zero-terminated -** string representation as returned by [tdsqlite3_column_text()]. +** string representation as returned by [sqlite3_column_text()]. ** ** A result table might consist of one or more memory allocations. -** It is not safe to pass a result table directly to [tdsqlite3_free()]. -** A result table should be deallocated using [tdsqlite3_free_table()]. +** It is not safe to pass a result table directly to [sqlite3_free()]. +** A result table should be deallocated using [sqlite3_free_table()]. ** ** ^(As an example of the result table format, suppose a query result ** is as follows: @@ -3765,35 +3765,35 @@ SQLITE_API int tdsqlite3_busy_timeout(tdsqlite3*, int ms); ** azResult[7] = "21"; ** )^ ** -** ^The tdsqlite3_get_table() function evaluates one or more +** ^The sqlite3_get_table() function evaluates one or more ** semicolon-separated SQL statements in the zero-terminated UTF-8 ** string of its 2nd parameter and returns a result table to the ** pointer given in its 3rd parameter. ** -** After the application has finished with the result from tdsqlite3_get_table(), -** it must pass the result table pointer to tdsqlite3_free_table() in order to +** After the application has finished with the result from sqlite3_get_table(), +** it must pass the result table pointer to sqlite3_free_table() in order to ** release the memory that was malloced. Because of the way the -** [tdsqlite3_malloc()] happens within tdsqlite3_get_table(), the calling -** function must not try to call [tdsqlite3_free()] directly. Only -** [tdsqlite3_free_table()] is able to release the memory properly and safely. +** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling +** function must not try to call [sqlite3_free()] directly. Only +** [sqlite3_free_table()] is able to release the memory properly and safely. ** -** The tdsqlite3_get_table() interface is implemented as a wrapper around -** [tdsqlite3_exec()]. The tdsqlite3_get_table() routine does not have access +** The sqlite3_get_table() interface is implemented as a wrapper around +** [sqlite3_exec()]. The sqlite3_get_table() routine does not have access ** to any internal data structures of SQLite. It uses only the public ** interface defined here. As a consequence, errors that occur in the -** wrapper layer outside of the internal [tdsqlite3_exec()] call are not -** reflected in subsequent calls to [tdsqlite3_errcode()] or -** [tdsqlite3_errmsg()]. +** wrapper layer outside of the internal [sqlite3_exec()] call are not +** reflected in subsequent calls to [sqlite3_errcode()] or +** [sqlite3_errmsg()]. */ -SQLITE_API int tdsqlite3_get_table( - tdsqlite3 *db, /* An open database */ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ int *pnRow, /* Number of result rows written here */ int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); -SQLITE_API void tdsqlite3_free_table(char **result); +SQLITE_API void sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions @@ -3805,40 +3805,40 @@ SQLITE_API void tdsqlite3_free_table(char **result); ** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]). ** See the [built-in printf()] documentation for details. ** -** ^The tdsqlite3_mprintf() and tdsqlite3_vmprintf() routines write their -** results into memory obtained from [tdsqlite3_malloc64()]. +** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their +** results into memory obtained from [sqlite3_malloc64()]. ** The strings returned by these two routines should be -** released by [tdsqlite3_free()]. ^Both routines return a -** NULL pointer if [tdsqlite3_malloc64()] is unable to allocate enough +** released by [sqlite3_free()]. ^Both routines return a +** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough ** memory to hold the resulting string. ** -** ^(The tdsqlite3_snprintf() routine is similar to "snprintf()" from +** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from ** the standard C library. The result is written into the ** buffer supplied as the second parameter whose size is given by ** the first parameter. Note that the order of the ** first two parameters is reversed from snprintf().)^ This is an ** historical accident that cannot be fixed without breaking -** backwards compatibility. ^(Note also that tdsqlite3_snprintf() +** backwards compatibility. ^(Note also that sqlite3_snprintf() ** returns a pointer to its buffer instead of the number of ** characters actually written into the buffer.)^ We admit that ** the number of characters written would be a more useful return -** value but we cannot change the implementation of tdsqlite3_snprintf() +** value but we cannot change the implementation of sqlite3_snprintf() ** now without breaking compatibility. ** -** ^As long as the buffer size is greater than zero, tdsqlite3_snprintf() +** ^As long as the buffer size is greater than zero, sqlite3_snprintf() ** guarantees that the buffer is always zero-terminated. ^The first ** parameter "n" is the total size of the buffer, including space for ** the zero terminator. So the longest string that can be completely ** written will be n-1 characters. ** -** ^The tdsqlite3_vsnprintf() routine is a varargs version of tdsqlite3_snprintf(). +** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). ** ** See also: [built-in printf()], [printf() SQL function] */ -SQLITE_API char *tdsqlite3_mprintf(const char*,...); -SQLITE_API char *tdsqlite3_vmprintf(const char*, va_list); -SQLITE_API char *tdsqlite3_snprintf(int,char*,const char*, ...); -SQLITE_API char *tdsqlite3_vsnprintf(int,char*,const char*, va_list); +SQLITE_API char *sqlite3_mprintf(const char*,...); +SQLITE_API char *sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *sqlite3_vsnprintf(int,char*,const char*, va_list); /* ** CAPI3REF: Memory Allocation Subsystem @@ -3848,105 +3848,105 @@ SQLITE_API char *tdsqlite3_vsnprintf(int,char*,const char*, va_list); ** does not include operating-system specific [VFS] implementation. The ** Windows VFS uses native malloc() and free() for some operations. ** -** ^The tdsqlite3_malloc() routine returns a pointer to a block +** ^The sqlite3_malloc() routine returns a pointer to a block ** of memory at least N bytes in length, where N is the parameter. -** ^If tdsqlite3_malloc() is unable to obtain sufficient free +** ^If sqlite3_malloc() is unable to obtain sufficient free ** memory, it returns a NULL pointer. ^If the parameter N to -** tdsqlite3_malloc() is zero or negative then tdsqlite3_malloc() returns +** sqlite3_malloc() is zero or negative then sqlite3_malloc() returns ** a NULL pointer. ** -** ^The tdsqlite3_malloc64(N) routine works just like -** tdsqlite3_malloc(N) except that N is an unsigned 64-bit integer instead +** ^The sqlite3_malloc64(N) routine works just like +** sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead ** of a signed 32-bit integer. ** -** ^Calling tdsqlite3_free() with a pointer previously returned -** by tdsqlite3_malloc() or tdsqlite3_realloc() releases that memory so -** that it might be reused. ^The tdsqlite3_free() routine is +** ^Calling sqlite3_free() with a pointer previously returned +** by sqlite3_malloc() or sqlite3_realloc() releases that memory so +** that it might be reused. ^The sqlite3_free() routine is ** a no-op if is called with a NULL pointer. Passing a NULL pointer -** to tdsqlite3_free() is harmless. After being freed, memory +** to sqlite3_free() is harmless. After being freed, memory ** should neither be read nor written. Even reading previously freed ** memory might result in a segmentation fault or other severe error. ** Memory corruption, a segmentation fault, or other severe error -** might result if tdsqlite3_free() is called with a non-NULL pointer that -** was not obtained from tdsqlite3_malloc() or tdsqlite3_realloc(). +** might result if sqlite3_free() is called with a non-NULL pointer that +** was not obtained from sqlite3_malloc() or sqlite3_realloc(). ** -** ^The tdsqlite3_realloc(X,N) interface attempts to resize a +** ^The sqlite3_realloc(X,N) interface attempts to resize a ** prior memory allocation X to be at least N bytes. -** ^If the X parameter to tdsqlite3_realloc(X,N) +** ^If the X parameter to sqlite3_realloc(X,N) ** is a NULL pointer then its behavior is identical to calling -** tdsqlite3_malloc(N). -** ^If the N parameter to tdsqlite3_realloc(X,N) is zero or +** sqlite3_malloc(N). +** ^If the N parameter to sqlite3_realloc(X,N) is zero or ** negative then the behavior is exactly the same as calling -** tdsqlite3_free(X). -** ^tdsqlite3_realloc(X,N) returns a pointer to a memory allocation +** sqlite3_free(X). +** ^sqlite3_realloc(X,N) returns a pointer to a memory allocation ** of at least N bytes in size or NULL if insufficient memory is available. ** ^If M is the size of the prior allocation, then min(N,M) bytes ** of the prior allocation are copied into the beginning of buffer returned -** by tdsqlite3_realloc(X,N) and the prior allocation is freed. -** ^If tdsqlite3_realloc(X,N) returns NULL and N is positive, then the +** by sqlite3_realloc(X,N) and the prior allocation is freed. +** ^If sqlite3_realloc(X,N) returns NULL and N is positive, then the ** prior allocation is not freed. ** -** ^The tdsqlite3_realloc64(X,N) interfaces works the same as -** tdsqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead +** ^The sqlite3_realloc64(X,N) interfaces works the same as +** sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead ** of a 32-bit signed integer. ** -** ^If X is a memory allocation previously obtained from tdsqlite3_malloc(), -** tdsqlite3_malloc64(), tdsqlite3_realloc(), or tdsqlite3_realloc64(), then -** tdsqlite3_msize(X) returns the size of that memory allocation in bytes. -** ^The value returned by tdsqlite3_msize(X) might be larger than the number +** ^If X is a memory allocation previously obtained from sqlite3_malloc(), +** sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then +** sqlite3_msize(X) returns the size of that memory allocation in bytes. +** ^The value returned by sqlite3_msize(X) might be larger than the number ** of bytes requested when X was allocated. ^If X is a NULL pointer then -** tdsqlite3_msize(X) returns zero. If X points to something that is not +** sqlite3_msize(X) returns zero. If X points to something that is not ** the beginning of memory allocation, or if it points to a formerly ** valid memory allocation that has now been freed, then the behavior -** of tdsqlite3_msize(X) is undefined and possibly harmful. +** of sqlite3_msize(X) is undefined and possibly harmful. ** -** ^The memory returned by tdsqlite3_malloc(), tdsqlite3_realloc(), -** tdsqlite3_malloc64(), and tdsqlite3_realloc64() +** ^The memory returned by sqlite3_malloc(), sqlite3_realloc(), +** sqlite3_malloc64(), and sqlite3_realloc64() ** is always aligned to at least an 8 byte boundary, or to a ** 4 byte boundary if the [SQLITE_4_BYTE_ALIGNED_MALLOC] compile-time ** option is used. ** -** The pointer arguments to [tdsqlite3_free()] and [tdsqlite3_realloc()] +** The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()] ** must be either NULL or else pointers obtained from a prior -** invocation of [tdsqlite3_malloc()] or [tdsqlite3_realloc()] that have +** invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have ** not yet been released. ** ** The application must not read or write any part of ** a block of memory after it has been released using -** [tdsqlite3_free()] or [tdsqlite3_realloc()]. +** [sqlite3_free()] or [sqlite3_realloc()]. */ -SQLITE_API void *tdsqlite3_malloc(int); -SQLITE_API void *tdsqlite3_malloc64(tdsqlite3_uint64); -SQLITE_API void *tdsqlite3_realloc(void*, int); -SQLITE_API void *tdsqlite3_realloc64(void*, tdsqlite3_uint64); -SQLITE_API void tdsqlite3_free(void*); -SQLITE_API tdsqlite3_uint64 tdsqlite3_msize(void*); +SQLITE_API void *sqlite3_malloc(int); +SQLITE_API void *sqlite3_malloc64(sqlite3_uint64); +SQLITE_API void *sqlite3_realloc(void*, int); +SQLITE_API void *sqlite3_realloc64(void*, sqlite3_uint64); +SQLITE_API void sqlite3_free(void*); +SQLITE_API sqlite3_uint64 sqlite3_msize(void*); /* ** CAPI3REF: Memory Allocator Statistics ** ** SQLite provides these two interfaces for reporting on the status -** of the [tdsqlite3_malloc()], [tdsqlite3_free()], and [tdsqlite3_realloc()] +** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()] ** routines, which form the built-in memory allocation subsystem. ** -** ^The [tdsqlite3_memory_used()] routine returns the number of bytes +** ^The [sqlite3_memory_used()] routine returns the number of bytes ** of memory currently outstanding (malloced but not freed). -** ^The [tdsqlite3_memory_highwater()] routine returns the maximum -** value of [tdsqlite3_memory_used()] since the high-water mark -** was last reset. ^The values returned by [tdsqlite3_memory_used()] and -** [tdsqlite3_memory_highwater()] include any overhead -** added by SQLite in its implementation of [tdsqlite3_malloc()], +** ^The [sqlite3_memory_highwater()] routine returns the maximum +** value of [sqlite3_memory_used()] since the high-water mark +** was last reset. ^The values returned by [sqlite3_memory_used()] and +** [sqlite3_memory_highwater()] include any overhead +** added by SQLite in its implementation of [sqlite3_malloc()], ** but not overhead added by the any underlying system library -** routines that [tdsqlite3_malloc()] may call. +** routines that [sqlite3_malloc()] may call. ** ** ^The memory high-water mark is reset to the current value of -** [tdsqlite3_memory_used()] if and only if the parameter to -** [tdsqlite3_memory_highwater()] is true. ^The value returned -** by [tdsqlite3_memory_highwater(1)] is the high-water mark +** [sqlite3_memory_used()] if and only if the parameter to +** [sqlite3_memory_highwater()] is true. ^The value returned +** by [sqlite3_memory_highwater(1)] is the high-water mark ** prior to the reset. */ -SQLITE_API tdsqlite3_int64 tdsqlite3_memory_used(void); -SQLITE_API tdsqlite3_int64 tdsqlite3_memory_highwater(int resetFlag); +SQLITE_API sqlite3_int64 sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); /* ** CAPI3REF: Pseudo-Random Number Generator @@ -3963,25 +3963,25 @@ SQLITE_API tdsqlite3_int64 tdsqlite3_memory_highwater(int resetFlag); ** ^If this routine has not been previously called or if the previous ** call had N less than one or a NULL pointer for P, then the PRNG is ** seeded using randomness obtained from the xRandomness method of -** the default [tdsqlite3_vfs] object. +** the default [sqlite3_vfs] object. ** ^If the previous call to this routine had an N of 1 or more and a ** non-NULL P then the pseudo-randomness is generated -** internally and without recourse to the [tdsqlite3_vfs] xRandomness +** internally and without recourse to the [sqlite3_vfs] xRandomness ** method. */ -SQLITE_API void tdsqlite3_randomness(int N, void *P); +SQLITE_API void sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** KEYWORDS: {authorizer callback} ** ** ^This routine registers an authorizer callback with a particular ** [database connection], supplied in the first argument. ** ^The authorizer callback is invoked as SQL statements are being compiled -** by [tdsqlite3_prepare()] or its variants [tdsqlite3_prepare_v2()], -** [tdsqlite3_prepare_v3()], [tdsqlite3_prepare16()], [tdsqlite3_prepare16_v2()], -** and [tdsqlite3_prepare16_v3()]. ^At various +** by [sqlite3_prepare()] or its variants [sqlite3_prepare_v2()], +** [sqlite3_prepare_v3()], [sqlite3_prepare16()], [sqlite3_prepare16_v2()], +** and [sqlite3_prepare16_v3()]. ^At various ** points during the compilation process, as logic is being created ** to perform various actions, the authorizer callback is invoked to ** see if those actions are allowed. ^The authorizer callback should @@ -3990,17 +3990,17 @@ SQLITE_API void tdsqlite3_randomness(int N, void *P); ** compiled, or [SQLITE_DENY] to cause the entire SQL statement to be ** rejected with an error. ^If the authorizer callback returns ** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] -** then the [tdsqlite3_prepare_v2()] or equivalent call that triggered +** then the [sqlite3_prepare_v2()] or equivalent call that triggered ** the authorizer will fail with an error message. ** ** When the callback returns [SQLITE_OK], that means the operation ** requested is ok. ^When the callback returns [SQLITE_DENY], the -** [tdsqlite3_prepare_v2()] or equivalent call that triggered the +** [sqlite3_prepare_v2()] or equivalent call that triggered the ** authorizer will fail with an error message explaining that ** access is denied. ** ** ^The first parameter to the authorizer callback is a copy of the third -** parameter to the tdsqlite3_set_authorizer() interface. ^The second parameter +** parameter to the sqlite3_set_authorizer() interface. ^The second parameter ** to the callback is an integer [SQLITE_COPY | action code] that specifies ** the particular action to be authorized. ^The third through sixth parameters ** to the callback are either NULL pointers or zero-terminated strings @@ -4023,7 +4023,7 @@ SQLITE_API void tdsqlite3_randomness(int N, void *P); ** [SQLITE_IGNORE] then the [DELETE] operation proceeds but the ** [truncate optimization] is disabled and all rows are deleted individually. ** -** An authorizer is used when [tdsqlite3_prepare | preparing] +** An authorizer is used when [sqlite3_prepare | preparing] ** SQL statements from an untrusted source, to ensure that the SQL statements ** do not try to access data they are not allowed to see, or that they do not ** try to execute malicious statements that damage the database. For @@ -4031,37 +4031,37 @@ SQLITE_API void tdsqlite3_randomness(int N, void *P); ** SQL queries for evaluation by a database. But the application does ** not want the user to be able to make arbitrary changes to the ** database. An authorizer could then be put in place while the -** user-entered SQL is being [tdsqlite3_prepare | prepared] that +** user-entered SQL is being [sqlite3_prepare | prepared] that ** disallows everything except [SELECT] statements. ** ** Applications that need to process SQL from untrusted sources -** might also consider lowering resource limits using [tdsqlite3_limit()] +** might also consider lowering resource limits using [sqlite3_limit()] ** and limiting database size using the [max_page_count] [PRAGMA] ** in addition to using an authorizer. ** ** ^(Only a single authorizer can be in place on a database connection -** at a time. Each call to tdsqlite3_set_authorizer overrides the +** at a time. Each call to sqlite3_set_authorizer overrides the ** previous call.)^ ^Disable the authorizer by installing a NULL callback. ** The authorizer is disabled by default. ** ** The authorizer callback must not do anything that will modify ** the database connection that invoked the authorizer callback. -** Note that [tdsqlite3_prepare_v2()] and [tdsqlite3_step()] both modify their +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** -** ^When [tdsqlite3_prepare_v2()] is used to prepare a statement, the -** statement might be re-prepared during [tdsqlite3_step()] due to a +** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the +** statement might be re-prepared during [sqlite3_step()] due to a ** schema change. Hence, the application should ensure that the -** correct authorizer callback remains in place during the [tdsqlite3_step()]. +** correct authorizer callback remains in place during the [sqlite3_step()]. ** ** ^Note that the authorizer callback is invoked only during -** [tdsqlite3_prepare()] or its variants. Authorization is not -** performed during statement evaluation in [tdsqlite3_step()], unless -** as stated in the previous paragraph, tdsqlite3_step() invokes -** tdsqlite3_prepare_v2() to reprepare a statement after a schema change. +** [sqlite3_prepare()] or its variants. Authorization is not +** performed during statement evaluation in [sqlite3_step()], unless +** as stated in the previous paragraph, sqlite3_step() invokes +** sqlite3_prepare_v2() to reprepare a statement after a schema change. */ -SQLITE_API int tdsqlite3_set_authorizer( - tdsqlite3*, +SQLITE_API int sqlite3_set_authorizer( + sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData ); @@ -4069,14 +4069,14 @@ SQLITE_API int tdsqlite3_set_authorizer( /* ** CAPI3REF: Authorizer Return Codes ** -** The [tdsqlite3_set_authorizer | authorizer callback function] must +** The [sqlite3_set_authorizer | authorizer callback function] must ** return either [SQLITE_OK] or one of these two constants in order ** to signal SQLite whether or not the action is permitted. See the -** [tdsqlite3_set_authorizer | authorizer documentation] for additional +** [sqlite3_set_authorizer | authorizer documentation] for additional ** information. ** ** Note that SQLITE_IGNORE is also used as a [conflict resolution mode] -** returned from the [tdsqlite3_vtab_on_conflict()] interface. +** returned from the [sqlite3_vtab_on_conflict()] interface. */ #define SQLITE_DENY 1 /* Abort the SQL statement with an error */ #define SQLITE_IGNORE 2 /* Don't allow access, but don't generate an error */ @@ -4084,7 +4084,7 @@ SQLITE_API int tdsqlite3_set_authorizer( /* ** CAPI3REF: Authorizer Action Codes ** -** The [tdsqlite3_set_authorizer()] interface registers a callback function +** The [sqlite3_set_authorizer()] interface registers a callback function ** that is invoked to authorize certain SQL statement actions. The ** second parameter to the callback is an integer code that specifies ** what action is being authorized. These are the integer action codes that @@ -4138,26 +4138,26 @@ SQLITE_API int tdsqlite3_set_authorizer( /* ** CAPI3REF: Tracing And Profiling Functions -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** These routines are deprecated. Use the [tdsqlite3_trace_v2()] interface +** These routines are deprecated. Use the [sqlite3_trace_v2()] interface ** instead of the routines described here. ** ** These routines register callback functions that can be used for ** tracing and profiling the execution of SQL statements. ** -** ^The callback function registered by tdsqlite3_trace() is invoked at -** various times when an SQL statement is being run by [tdsqlite3_step()]. -** ^The tdsqlite3_trace() callback is invoked with a UTF-8 rendering of the +** ^The callback function registered by sqlite3_trace() is invoked at +** various times when an SQL statement is being run by [sqlite3_step()]. +** ^The sqlite3_trace() callback is invoked with a UTF-8 rendering of the ** SQL statement text as the statement first begins executing. -** ^(Additional tdsqlite3_trace() callbacks might occur +** ^(Additional sqlite3_trace() callbacks might occur ** as each triggered subprogram is entered. The callbacks for triggers ** contain a UTF-8 SQL comment that identifies the trigger.)^ ** ** The [SQLITE_TRACE_SIZE_LIMIT] compile-time option can be used to limit -** the length of [bound parameter] expansion in the output of tdsqlite3_trace(). +** the length of [bound parameter] expansion in the output of sqlite3_trace(). ** -** ^The callback function registered by tdsqlite3_profile() is invoked +** ^The callback function registered by sqlite3_profile() is invoked ** as each SQL statement finishes. ^The profile callback contains ** the original statement text and an estimate of wall-clock time ** of how long that statement took to run. ^The profile callback @@ -4165,21 +4165,21 @@ SQLITE_API int tdsqlite3_set_authorizer( ** is only capable of millisecond resolution so the six least significant ** digits in the time are meaningless. Future versions of SQLite ** might provide greater resolution on the profiler callback. Invoking -** either [tdsqlite3_trace()] or [tdsqlite3_trace_v2()] will cancel the +** either [sqlite3_trace()] or [sqlite3_trace_v2()] will cancel the ** profile callback. */ -SQLITE_API SQLITE_DEPRECATED void *tdsqlite3_trace(tdsqlite3*, +SQLITE_API SQLITE_DEPRECATED void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); -SQLITE_API SQLITE_DEPRECATED void *tdsqlite3_profile(tdsqlite3*, - void(*xProfile)(void*,const char*,tdsqlite3_uint64), void*); +SQLITE_API SQLITE_DEPRECATED void *sqlite3_profile(sqlite3*, + void(*xProfile)(void*,const char*,sqlite3_uint64), void*); /* ** CAPI3REF: SQL Trace Event Codes ** KEYWORDS: SQLITE_TRACE ** ** These constants identify classes of events that can be monitored -** using the [tdsqlite3_trace_v2()] tracing logic. The M argument -** to [tdsqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of +** using the [sqlite3_trace_v2()] tracing logic. The M argument +** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of ** the following constants. ^The first argument to the trace callback ** is one of the following constants. ** @@ -4188,7 +4188,7 @@ SQLITE_API SQLITE_DEPRECATED void *tdsqlite3_profile(tdsqlite3*, ** ^A trace callback has four arguments: xCallback(T,C,P,X). ** ^The T argument is one of the integer type codes above. ** ^The C argument is a copy of the context pointer passed in as the -** fourth argument to [tdsqlite3_trace_v2()]. +** fourth argument to [sqlite3_trace_v2()]. ** The P and X arguments are pointers whose meanings depend on T. ** **
    @@ -4200,13 +4200,13 @@ SQLITE_API SQLITE_DEPRECATED void *tdsqlite3_profile(tdsqlite3*, ** [prepared statement]. ^The X argument is a pointer to a string which ** is the unexpanded SQL text of the prepared statement or an SQL comment ** that indicates the invocation of a trigger. ^The callback can compute -** the same text that would have been returned by the legacy [tdsqlite3_trace()] +** the same text that would have been returned by the legacy [sqlite3_trace()] ** interface by using the X argument when X begins with "--" and invoking -** [tdsqlite3_expanded_sql(P)] otherwise. +** [sqlite3_expanded_sql(P)] otherwise. ** ** [[SQLITE_TRACE_PROFILE]]
    SQLITE_TRACE_PROFILE
    **
    ^An SQLITE_TRACE_PROFILE callback provides approximately the same -** information as is provided by the [tdsqlite3_profile()] callback. +** information as is provided by the [sqlite3_profile()] callback. ** ^The P argument is a pointer to the [prepared statement] and the ** X argument points to a 64-bit integer which is the estimated of ** the number of nanosecond that the prepared statement took to run. @@ -4232,17 +4232,17 @@ SQLITE_API SQLITE_DEPRECATED void *tdsqlite3_profile(tdsqlite3*, /* ** CAPI3REF: SQL Trace Hook -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_trace_v2(D,M,X,P) interface registers a trace callback +** ^The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback ** function X against [database connection] D, using property mask M ** and context pointer P. ^If the X callback is ** NULL or if the M mask is zero, then tracing is disabled. The ** M argument should be the bitwise OR-ed combination of ** zero or more [SQLITE_TRACE] constants. ** -** ^Each call to either tdsqlite3_trace() or tdsqlite3_trace_v2() overrides -** (cancels) any prior calls to tdsqlite3_trace() or tdsqlite3_trace_v2(). +** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides +** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). ** ** ^The X callback is invoked whenever any of the events identified by ** mask M occur. ^The integer return value from the callback is currently @@ -4255,12 +4255,12 @@ SQLITE_API SQLITE_DEPRECATED void *tdsqlite3_profile(tdsqlite3*, ** ^The C argument is a copy of the context pointer. ** The P and X arguments are pointers whose meanings depend on T. ** -** The tdsqlite3_trace_v2() interface is intended to replace the legacy -** interfaces [tdsqlite3_trace()] and [tdsqlite3_profile()], both of which +** The sqlite3_trace_v2() interface is intended to replace the legacy +** interfaces [sqlite3_trace()] and [sqlite3_profile()], both of which ** are deprecated. */ -SQLITE_API int tdsqlite3_trace_v2( - tdsqlite3*, +SQLITE_API int sqlite3_trace_v2( + sqlite3*, unsigned uMask, int(*xCallback)(unsigned,void*,void*,void*), void *pCtx @@ -4268,11 +4268,11 @@ SQLITE_API int tdsqlite3_trace_v2( /* ** CAPI3REF: Query Progress Callbacks -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_progress_handler(D,N,X,P) interface causes the callback +** ^The sqlite3_progress_handler(D,N,X,P) interface causes the callback ** function X to be invoked periodically during long running calls to -** [tdsqlite3_exec()], [tdsqlite3_step()] and [tdsqlite3_get_table()] for +** [sqlite3_exec()], [sqlite3_step()] and [sqlite3_get_table()] for ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** @@ -4294,41 +4294,41 @@ SQLITE_API int tdsqlite3_trace_v2( ** ** The progress handler callback must not do anything that will modify ** the database connection that invoked the progress handler. -** Note that [tdsqlite3_prepare_v2()] and [tdsqlite3_step()] both modify their +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** */ -SQLITE_API void tdsqlite3_progress_handler(tdsqlite3*, int, int(*)(void*), void*); +SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection -** CONSTRUCTOR: tdsqlite3 +** CONSTRUCTOR: sqlite3 ** ** ^These routines open an SQLite database file as specified by the ** filename argument. ^The filename argument is interpreted as UTF-8 for -** tdsqlite3_open() and tdsqlite3_open_v2() and as UTF-16 in the native byte -** order for tdsqlite3_open16(). ^(A [database connection] handle is usually +** sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte +** order for sqlite3_open16(). ^(A [database connection] handle is usually ** returned in *ppDb, even if an error occurs. The only exception is that -** if SQLite is unable to allocate memory to hold the [tdsqlite3] object, -** a NULL will be written into *ppDb instead of a pointer to the [tdsqlite3] +** if SQLite is unable to allocate memory to hold the [sqlite3] object, +** a NULL will be written into *ppDb instead of a pointer to the [sqlite3] ** object.)^ ^(If the database is opened (and/or created) successfully, then ** [SQLITE_OK] is returned. Otherwise an [error code] is returned.)^ ^The -** [tdsqlite3_errmsg()] or [tdsqlite3_errmsg16()] routines can be used to obtain +** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain ** an English language description of the error following a failure of any -** of the tdsqlite3_open() routines. +** of the sqlite3_open() routines. ** ** ^The default encoding will be UTF-8 for databases created using -** tdsqlite3_open() or tdsqlite3_open_v2(). ^The default encoding for databases -** created using tdsqlite3_open16() will be UTF-16 in the native byte order. +** sqlite3_open() or sqlite3_open_v2(). ^The default encoding for databases +** created using sqlite3_open16() will be UTF-16 in the native byte order. ** ** Whether or not an error occurs when it is opened, resources ** associated with the [database connection] handle should be released by -** passing it to [tdsqlite3_close()] when it is no longer required. +** passing it to [sqlite3_close()] when it is no longer required. ** -** The tdsqlite3_open_v2() interface works like tdsqlite3_open() +** The sqlite3_open_v2() interface works like sqlite3_open() ** except that it accepts two additional parameters for additional control ** over the new database connection. ^(The flags parameter to -** tdsqlite3_open_v2() must include, at a minimum, one of the following +** sqlite3_open_v2() must include, at a minimum, one of the following ** three flag combinations:)^ ** **
    @@ -4344,7 +4344,7 @@ SQLITE_API void tdsqlite3_progress_handler(tdsqlite3*, int, int(*)(void*), void* ** ^(
    [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
    **
    The database is opened for reading and writing, and is created if ** it does not already exist. This is the behavior that is always used for -** tdsqlite3_open() and tdsqlite3_open16().
    )^ +** sqlite3_open() and sqlite3_open16().
    )^ **
    ** ** In addition to the required flags, the following optional flags are @@ -4376,26 +4376,26 @@ SQLITE_API void tdsqlite3_progress_handler(tdsqlite3*, int, int(*)(void*), void* ** ^(
    [SQLITE_OPEN_SHAREDCACHE]
    **
    The database is opened [shared cache] enabled, overriding ** the default shared cache setting provided by -** [tdsqlite3_enable_shared_cache()].)^ +** [sqlite3_enable_shared_cache()].)^ ** ** ^(
    [SQLITE_OPEN_PRIVATECACHE]
    **
    The database is opened [shared cache] disabled, overriding ** the default shared cache setting provided by -** [tdsqlite3_enable_shared_cache()].)^ +** [sqlite3_enable_shared_cache()].)^ ** ** [[OPEN_NOFOLLOW]] ^(
    [SQLITE_OPEN_NOFOLLOW]
    **
    The database filename is not allowed to be a symbolic link
    ** )^ ** -** If the 3rd parameter to tdsqlite3_open_v2() is not one of the +** If the 3rd parameter to sqlite3_open_v2() is not one of the ** required combinations shown above optionally combined with other ** [SQLITE_OPEN_READONLY | SQLITE_OPEN_* bits] ** then the behavior is undefined. ** -** ^The fourth parameter to tdsqlite3_open_v2() is the name of the -** [tdsqlite3_vfs] object that defines the operating system interface that +** ^The fourth parameter to sqlite3_open_v2() is the name of the +** [sqlite3_vfs] object that defines the operating system interface that ** the new database connection should use. ^If the fourth parameter is -** a NULL pointer then the default [tdsqlite3_vfs] object is used. +** a NULL pointer then the default [sqlite3_vfs] object is used. ** ** ^If the filename is ":memory:", then a private, temporary in-memory database ** is created for the connection. ^This in-memory database will vanish when @@ -4409,14 +4409,14 @@ SQLITE_API void tdsqlite3_progress_handler(tdsqlite3*, int, int(*)(void*), void* ** on-disk database will be created. ^This private database will be ** automatically deleted as soon as the database connection is closed. ** -** [[URI filenames in tdsqlite3_open()]]

    URI Filenames

    +** [[URI filenames in sqlite3_open()]]

    URI Filenames

    ** ** ^If [URI filename] interpretation is enabled, and the filename argument ** begins with "file:", then the filename is interpreted as a URI. ^URI ** filename interpretation is enabled if the [SQLITE_OPEN_URI] flag is -** set in the third argument to tdsqlite3_open_v2(), or if it has +** set in the third argument to sqlite3_open_v2(), or if it has ** been enabled globally using the [SQLITE_CONFIG_URI] option with the -** [tdsqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. +** [sqlite3_config()] method or by the [SQLITE_USE_URI] compile-time option. ** URI filename interpretation is turned off ** by default, but future releases of SQLite might enable URI filename ** interpretation by default. See "[URI filenames]" for additional @@ -4447,16 +4447,16 @@ SQLITE_API void tdsqlite3_progress_handler(tdsqlite3*, int, int(*)(void*), void* ** a VFS object that provides the operating system interface that should ** be used to access the database file on disk. ^If this option is set to ** an empty string the default VFS object is used. ^Specifying an unknown -** VFS is an error. ^If tdsqlite3_open_v2() is used and the vfs option is +** VFS is an error. ^If sqlite3_open_v2() is used and the vfs option is ** present, then the VFS specified by the option takes precedence over -** the value passed as the fourth parameter to tdsqlite3_open_v2(). +** the value passed as the fourth parameter to sqlite3_open_v2(). ** **
  • mode: ^(The mode parameter may be set to either "ro", "rw", ** "rwc", or "memory". Attempting to set it to any other value is ** an error)^. ** ^If "ro" is specified, then the database is opened for read-only ** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the -** third argument to tdsqlite3_open_v2(). ^If the mode option is set to +** third argument to sqlite3_open_v2(). ^If the mode option is set to ** "rw", then the database is opened for read-write (but not create) ** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had ** been set. ^Value "rwc" is equivalent to setting both @@ -4464,14 +4464,14 @@ SQLITE_API void tdsqlite3_progress_handler(tdsqlite3*, int, int(*)(void*), void* ** set to "memory" then a pure [in-memory database] that never reads ** or writes from disk is used. ^It is an error to specify a value for ** the mode parameter that is less restrictive than that specified by -** the flags passed in the third parameter to tdsqlite3_open_v2(). +** the flags passed in the third parameter to sqlite3_open_v2(). ** **
  • cache: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to -** tdsqlite3_open_v2(). ^Setting the cache parameter to "private" is +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. -** ^If tdsqlite3_open_v2() is used and the "cache" parameter is present in +** ^If sqlite3_open_v2() is used and the "cache" parameter is present in ** a URI filename, its value overrides any behavior requested by setting ** SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. ** @@ -4542,28 +4542,28 @@ SQLITE_API void tdsqlite3_progress_handler(tdsqlite3*, int, int(*)(void*), void* ** the results are undefined. ** ** Note to Windows users: The encoding used for the filename argument -** of tdsqlite3_open() and tdsqlite3_open_v2() must be UTF-8, not whatever +** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever ** codepage is currently defined. Filenames containing international ** characters must be converted to UTF-8 prior to passing them into -** tdsqlite3_open() or tdsqlite3_open_v2(). +** sqlite3_open() or sqlite3_open_v2(). ** ** Note to Windows Runtime users: The temporary directory must be set -** prior to calling tdsqlite3_open() or tdsqlite3_open_v2(). Otherwise, various +** prior to calling sqlite3_open() or sqlite3_open_v2(). Otherwise, various ** features that require the use of temporary files may fail. ** -** See also: [tdsqlite3_temp_directory] +** See also: [sqlite3_temp_directory] */ -SQLITE_API int tdsqlite3_open( +SQLITE_API int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ - tdsqlite3 **ppDb /* OUT: SQLite db handle */ + sqlite3 **ppDb /* OUT: SQLite db handle */ ); -SQLITE_API int tdsqlite3_open16( +SQLITE_API int sqlite3_open16( const void *filename, /* Database filename (UTF-16) */ - tdsqlite3 **ppDb /* OUT: SQLite db handle */ + sqlite3 **ppDb /* OUT: SQLite db handle */ ); -SQLITE_API int tdsqlite3_open_v2( +SQLITE_API int sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ - tdsqlite3 **ppDb, /* OUT: SQLite db handle */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ); @@ -4576,39 +4576,39 @@ SQLITE_API int tdsqlite3_open_v2( ** parameter, and if so obtains the value of that query parameter. ** ** If F is the database filename pointer passed into the xOpen() method of -** a VFS implementation or it is the return value of [tdsqlite3_db_filename()] +** a VFS implementation or it is the return value of [sqlite3_db_filename()] ** and if P is the name of the query parameter, then -** tdsqlite3_uri_parameter(F,P) returns the value of the P +** sqlite3_uri_parameter(F,P) returns the value of the P ** parameter if it exists or a NULL pointer if P does not appear as a ** query parameter on F. If P is a query parameter of F and it -** has no explicit value, then tdsqlite3_uri_parameter(F,P) returns +** has no explicit value, then sqlite3_uri_parameter(F,P) returns ** a pointer to an empty string. ** -** The tdsqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean ** parameter and returns true (1) or false (0) according to the value -** of P. The tdsqlite3_uri_boolean(F,P,B) routine returns true (1) if the +** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the ** value of query parameter P is one of "yes", "true", or "on" in any ** case or if the value begins with a non-zero number. The -** tdsqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of +** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of ** query parameter P is one of "no", "false", or "off" in any case or ** if the value begins with a numeric zero. If P is not a query ** parameter on F or if the value of P does not match any of the -** above, then tdsqlite3_uri_boolean(F,P,B) returns (B!=0). +** above, then sqlite3_uri_boolean(F,P,B) returns (B!=0). ** -** The tdsqlite3_uri_int64(F,P,D) routine converts the value of P into a +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a ** 64-bit signed integer and returns that integer, or D if P does not ** exist. If the value of P is something other than an integer, then ** zero is returned. ** -** The tdsqlite3_uri_key(F,N) returns a pointer to the name (not +** The sqlite3_uri_key(F,N) returns a pointer to the name (not ** the value) of the N-th query parameter for filename F, or a NULL ** pointer if N is less than zero or greater than the number of query ** parameters minus 1. The N value is zero-based so N should be 0 to obtain ** the name of the first query parameter, 1 for the second parameter, and ** so forth. ** -** If F is a NULL pointer, then tdsqlite3_uri_parameter(F,P) returns NULL and -** tdsqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and +** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and ** is not a database file pathname pointer that the SQLite core passed ** into the xOpen VFS method, then the behavior of this routine is undefined ** and probably undesirable. @@ -4623,10 +4623,10 @@ SQLITE_API int tdsqlite3_open_v2( ** ** See the [URI filename] documentation for additional information. */ -SQLITE_API const char *tdsqlite3_uri_parameter(const char *zFilename, const char *zParam); -SQLITE_API int tdsqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); -SQLITE_API tdsqlite3_int64 tdsqlite3_uri_int64(const char*, const char*, tdsqlite3_int64); -SQLITE_API const char *tdsqlite3_uri_key(const char *zFilename, int N); +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault); +SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64); +SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N); /* ** CAPI3REF: Translate filenames @@ -4636,64 +4636,64 @@ SQLITE_API const char *tdsqlite3_uri_key(const char *zFilename, int N); ** and the WAL file. ** ** If F is the name of an sqlite database file, journal file, or WAL file -** passed by the SQLite core into the VFS, then tdsqlite3_filename_database(F) +** passed by the SQLite core into the VFS, then sqlite3_filename_database(F) ** returns the name of the corresponding database file. ** ** If F is the name of an sqlite database file, journal file, or WAL file ** passed by the SQLite core into the VFS, or if F is a database filename -** obtained from [tdsqlite3_db_filename()], then tdsqlite3_filename_journal(F) +** obtained from [sqlite3_db_filename()], then sqlite3_filename_journal(F) ** returns the name of the corresponding rollback journal file. ** ** If F is the name of an sqlite database file, journal file, or WAL file ** that was passed by the SQLite core into the VFS, or if F is a database -** filename obtained from [tdsqlite3_db_filename()], then -** tdsqlite3_filename_wal(F) returns the name of the corresponding +** filename obtained from [sqlite3_db_filename()], then +** sqlite3_filename_wal(F) returns the name of the corresponding ** WAL file. ** ** In all of the above, if F is not the name of a database, journal or WAL ** filename passed into the VFS from the SQLite core and F is not the -** return value from [tdsqlite3_db_filename()], then the result is +** return value from [sqlite3_db_filename()], then the result is ** undefined and is likely a memory access violation. */ -SQLITE_API const char *tdsqlite3_filename_database(const char*); -SQLITE_API const char *tdsqlite3_filename_journal(const char*); -SQLITE_API const char *tdsqlite3_filename_wal(const char*); +SQLITE_API const char *sqlite3_filename_database(const char*); +SQLITE_API const char *sqlite3_filename_journal(const char*); +SQLITE_API const char *sqlite3_filename_wal(const char*); /* ** CAPI3REF: Error Codes And Messages -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^If the most recent tdsqlite3_* API call associated with -** [database connection] D failed, then the tdsqlite3_errcode(D) interface +** ^If the most recent sqlite3_* API call associated with +** [database connection] D failed, then the sqlite3_errcode(D) interface ** returns the numeric [result code] or [extended result code] for that ** API call. -** ^The tdsqlite3_extended_errcode() +** ^The sqlite3_extended_errcode() ** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. ** -** The values returned by tdsqlite3_errcode() and/or -** tdsqlite3_extended_errcode() might change with each API call. +** The values returned by sqlite3_errcode() and/or +** sqlite3_extended_errcode() might change with each API call. ** Except, there are some interfaces that are guaranteed to never ** change the value of the error code. The error-code preserving ** interfaces are: ** **
      -**
    • tdsqlite3_errcode() -**
    • tdsqlite3_extended_errcode() -**
    • tdsqlite3_errmsg() -**
    • tdsqlite3_errmsg16() +**
    • sqlite3_errcode() +**
    • sqlite3_extended_errcode() +**
    • sqlite3_errmsg() +**
    • sqlite3_errmsg16() **
    ** -** ^The tdsqlite3_errmsg() and tdsqlite3_errmsg16() return English-language +** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ ** -** ^The tdsqlite3_errstr() interface returns the English-language text +** ^The sqlite3_errstr() interface returns the English-language text ** that describes the [result code], as UTF-8. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. @@ -4704,19 +4704,19 @@ SQLITE_API const char *tdsqlite3_filename_wal(const char*); ** When that happens, the second error will be reported since these ** interfaces always report the most recent result. To avoid ** this, each thread can obtain exclusive use of the [database connection] D -** by invoking [tdsqlite3_mutex_enter]([tdsqlite3_db_mutex](D)) before beginning -** to use D and invoking [tdsqlite3_mutex_leave]([tdsqlite3_db_mutex](D)) after +** by invoking [sqlite3_mutex_enter]([sqlite3_db_mutex](D)) before beginning +** to use D and invoking [sqlite3_mutex_leave]([sqlite3_db_mutex](D)) after ** all calls to the interfaces listed here are completed. ** ** If an interface fails with SQLITE_MISUSE, that means the interface ** was invoked incorrectly by the application. In that case, the ** error code and message may or may not be set. */ -SQLITE_API int tdsqlite3_errcode(tdsqlite3 *db); -SQLITE_API int tdsqlite3_extended_errcode(tdsqlite3 *db); -SQLITE_API const char *tdsqlite3_errmsg(tdsqlite3*); -SQLITE_API const void *tdsqlite3_errmsg16(tdsqlite3*); -SQLITE_API const char *tdsqlite3_errstr(int); +SQLITE_API int sqlite3_errcode(sqlite3 *db); +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *sqlite3_errmsg(sqlite3*); +SQLITE_API const void *sqlite3_errmsg16(sqlite3*); +SQLITE_API const char *sqlite3_errstr(int); /* ** CAPI3REF: Prepared Statement Object @@ -4733,20 +4733,20 @@ SQLITE_API const char *tdsqlite3_errstr(int); ** The life-cycle of a prepared statement object usually goes like this: ** **
      -**
    1. Create the prepared statement object using [tdsqlite3_prepare_v2()]. -**
    2. Bind values to [parameters] using the tdsqlite3_bind_*() +**
    3. Create the prepared statement object using [sqlite3_prepare_v2()]. +**
    4. Bind values to [parameters] using the sqlite3_bind_*() ** interfaces. -**
    5. Run the SQL by calling [tdsqlite3_step()] one or more times. -**
    6. Reset the prepared statement using [tdsqlite3_reset()] then go back +**
    7. Run the SQL by calling [sqlite3_step()] one or more times. +**
    8. Reset the prepared statement using [sqlite3_reset()] then go back ** to step 2. Do this zero or more times. -**
    9. Destroy the object using [tdsqlite3_finalize()]. +**
    10. Destroy the object using [sqlite3_finalize()]. **
    */ -typedef struct tdsqlite3_stmt tdsqlite3_stmt; +typedef struct sqlite3_stmt sqlite3_stmt; /* ** CAPI3REF: Run-time Limits -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^(This interface allows the size of various constructs to be limited ** on a connection by connection basis. The first parameter is the @@ -4765,7 +4765,7 @@ typedef struct tdsqlite3_stmt tdsqlite3_stmt; ** silently truncated to the hard upper bound. ** ** ^Regardless of whether or not the limit was changed, the -** [tdsqlite3_limit()] interface returns the prior value of the limit. +** [sqlite3_limit()] interface returns the prior value of the limit. ** ^Hence, to find the current value of a limit without changing it, ** simply invoke this interface with the third parameter set to -1. ** @@ -4777,21 +4777,21 @@ typedef struct tdsqlite3_stmt tdsqlite3_stmt; ** off the Internet. The internal databases can be given the ** large, default limits. Databases managed by external sources can ** be given much smaller limits designed to prevent a denial of service -** attack. Developers might also want to use the [tdsqlite3_set_authorizer()] +** attack. Developers might also want to use the [sqlite3_set_authorizer()] ** interface to further control untrusted SQL. The size of the database ** created by an untrusted script can be contained using the ** [max_page_count] [PRAGMA]. ** ** New run-time limit categories may be added in future releases. */ -SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); /* ** CAPI3REF: Run-Time Limit Categories ** KEYWORDS: {limit category} {*limit categories} ** ** These constants define various performance limits -** that can be lowered at run-time using [tdsqlite3_limit()]. +** that can be lowered at run-time using [sqlite3_limit()]. ** The synopsis of the meanings of the various limits is shown below. ** Additional information is available at [limits | Limits in SQLite]. ** @@ -4815,7 +4815,7 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(
    SQLITE_LIMIT_VDBE_OP
    **
    The maximum number of instructions in a virtual machine program -** used to implement an SQL statement. If [tdsqlite3_prepare_v2()] or +** used to implement an SQL statement. If [sqlite3_prepare_v2()] or ** the equivalent tries to allocate space for more than this many opcodes ** in a single prepared statement, an SQLITE_NOMEM error is returned.
    )^ ** @@ -4859,8 +4859,8 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); ** CAPI3REF: Prepare Flags ** ** These constants define various flags that can be passed into -** "prepFlags" parameter of the [tdsqlite3_prepare_v3()] and -** [tdsqlite3_prepare16_v3()] interfaces. +** "prepFlags" parameter of the [sqlite3_prepare_v3()] and +** [sqlite3_prepare16_v3()] interfaces. ** ** New flags may be added in future releases of SQLite. ** @@ -4868,10 +4868,10 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); ** [[SQLITE_PREPARE_PERSISTENT]] ^(
    SQLITE_PREPARE_PERSISTENT
    **
    The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner ** that the prepared statement will be retained for a long time and -** probably reused many times.)^ ^Without this flag, [tdsqlite3_prepare_v3()] -** and [tdsqlite3_prepare16_v3()] assume that the prepared statement will +** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()] +** and [sqlite3_prepare16_v3()] assume that the prepared statement will ** be used just once or at most a few times and then destroyed using -** [tdsqlite3_finalize()] relatively soon. The current implementation acts +** [sqlite3_finalize()] relatively soon. The current implementation acts ** on this hint by avoiding the use of [lookaside memory] so as not to ** deplete the limited store of lookaside memory. Future versions of ** SQLite may act on this hint differently. @@ -4879,8 +4879,8 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); ** [[SQLITE_PREPARE_NORMALIZE]]
    SQLITE_PREPARE_NORMALIZE
    **
    The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used ** to be required for any prepared statement that wanted to use the -** [tdsqlite3_normalized_sql()] interface. However, the -** [tdsqlite3_normalized_sql()] interface is now available to all +** [sqlite3_normalized_sql()] interface. However, the +** [sqlite3_normalized_sql()] interface is now available to all ** prepared statements, regardless of whether or not they use this ** flag. ** @@ -4897,16 +4897,16 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); /* ** CAPI3REF: Compiling An SQL Statement ** KEYWORDS: {SQL statement compiler} -** METHOD: tdsqlite3 -** CONSTRUCTOR: tdsqlite3_stmt +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_stmt ** ** To execute an SQL statement, it must first be compiled into a byte-code ** program using one of these routines. Or, in other words, these routines ** are constructors for the [prepared statement] object. ** -** The preferred routine to use is [tdsqlite3_prepare_v2()]. The -** [tdsqlite3_prepare()] interface is legacy and should be avoided. -** [tdsqlite3_prepare_v3()] has an extra "prepFlags" option that is used +** The preferred routine to use is [sqlite3_prepare_v2()]. The +** [sqlite3_prepare()] interface is legacy and should be avoided. +** [sqlite3_prepare_v3()] has an extra "prepFlags" option that is used ** for special purposes. ** ** The use of the UTF-8 interfaces is preferred, as SQLite currently @@ -4915,14 +4915,14 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); ** input text into UTF-8, then invoking the corresponding UTF-8 interface. ** ** The first argument, "db", is a [database connection] obtained from a -** prior successful call to [tdsqlite3_open()], [tdsqlite3_open_v2()] or -** [tdsqlite3_open16()]. The database connection must not have been closed. +** prior successful call to [sqlite3_open()], [sqlite3_open_v2()] or +** [sqlite3_open16()]. The database connection must not have been closed. ** ** The second argument, "zSql", is the statement to be compiled, encoded -** as either UTF-8 or UTF-16. The tdsqlite3_prepare(), tdsqlite3_prepare_v2(), -** and tdsqlite3_prepare_v3() -** interfaces use UTF-8, and tdsqlite3_prepare16(), tdsqlite3_prepare16_v2(), -** and tdsqlite3_prepare16_v3() use UTF-16. +** as either UTF-8 or UTF-16. The sqlite3_prepare(), sqlite3_prepare_v2(), +** and sqlite3_prepare_v3() +** interfaces use UTF-8, and sqlite3_prepare16(), sqlite3_prepare16_v2(), +** and sqlite3_prepare16_v3() use UTF-16. ** ** ^If the nByte argument is negative, then zSql is read up to the ** first zero terminator. ^If nByte is positive, then it is the @@ -4939,38 +4939,38 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); ** what remains uncompiled. ** ** ^*ppStmt is left pointing to a compiled [prepared statement] that can be -** executed using [tdsqlite3_step()]. ^If there is an error, *ppStmt is set +** executed using [sqlite3_step()]. ^If there is an error, *ppStmt is set ** to NULL. ^If the input text contains no SQL (if the input is an empty ** string or a comment) then *ppStmt is set to NULL. ** The calling procedure is responsible for deleting the compiled -** SQL statement using [tdsqlite3_finalize()] after it has finished with it. +** SQL statement using [sqlite3_finalize()] after it has finished with it. ** ppStmt may not be NULL. ** -** ^On success, the tdsqlite3_prepare() family of routines return [SQLITE_OK]; +** ^On success, the sqlite3_prepare() family of routines return [SQLITE_OK]; ** otherwise an [error code] is returned. ** -** The tdsqlite3_prepare_v2(), tdsqlite3_prepare_v3(), tdsqlite3_prepare16_v2(), -** and tdsqlite3_prepare16_v3() interfaces are recommended for all new programs. -** The older interfaces (tdsqlite3_prepare() and tdsqlite3_prepare16()) +** The sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(), +** and sqlite3_prepare16_v3() interfaces are recommended for all new programs. +** The older interfaces (sqlite3_prepare() and sqlite3_prepare16()) ** are retained for backwards compatibility, but their use is discouraged. ** ^In the "vX" interfaces, the prepared statement -** that is returned (the [tdsqlite3_stmt] object) contains a copy of the -** original SQL text. This causes the [tdsqlite3_step()] interface to +** that is returned (the [sqlite3_stmt] object) contains a copy of the +** original SQL text. This causes the [sqlite3_step()] interface to ** behave differently in three ways: ** **
      **
    1. ** ^If the database schema changes, instead of returning [SQLITE_SCHEMA] as it -** always used to do, [tdsqlite3_step()] will automatically recompile the SQL +** always used to do, [sqlite3_step()] will automatically recompile the SQL ** statement and try to run it again. As many as [SQLITE_MAX_SCHEMA_RETRY] -** retries will occur before tdsqlite3_step() gives up and returns an error. +** retries will occur before sqlite3_step() gives up and returns an error. **
    2. ** **
    3. -** ^When an error occurs, [tdsqlite3_step()] will return one of the detailed +** ^When an error occurs, [sqlite3_step()] will return one of the detailed ** [error codes] or [extended error codes]. ^The legacy behavior was that -** [tdsqlite3_step()] would only return a generic [SQLITE_ERROR] result code -** and the application would have to make a second call to [tdsqlite3_reset()] +** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code +** and the application would have to make a second call to [sqlite3_reset()] ** in order to find the underlying cause of the problem. With the "v2" prepare ** interfaces, the underlying reason for the error is returned immediately. **
    4. @@ -4979,8 +4979,8 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); ** ^If the specific value bound to a [parameter | host parameter] in the ** WHERE clause might influence the choice of query plan for a statement, ** then the statement will be automatically recompiled, as if there had been -** a schema change, on the first [tdsqlite3_step()] call following any change -** to the [tdsqlite3_bind_text | bindings] of that [parameter]. +** a schema change, on the first [sqlite3_step()] call following any change +** to the [sqlite3_bind_text | bindings] of that [parameter]. ** ^The specific value of a WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column @@ -4988,69 +4988,69 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3*, int id, int newVal); ** **
    ** -**

    ^tdsqlite3_prepare_v3() differs from tdsqlite3_prepare_v2() only in having +**

    ^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having ** the extra prepFlags parameter, which is a bit array consisting of zero or ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The -** tdsqlite3_prepare_v2() interface works exactly the same as -** tdsqlite3_prepare_v3() with a zero prepFlags parameter. +** sqlite3_prepare_v2() interface works exactly the same as +** sqlite3_prepare_v3() with a zero prepFlags parameter. */ -SQLITE_API int tdsqlite3_prepare( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ - tdsqlite3_stmt **ppStmt, /* OUT: Statement handle */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int tdsqlite3_prepare_v2( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ - tdsqlite3_stmt **ppStmt, /* OUT: Statement handle */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int tdsqlite3_prepare_v3( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3_prepare_v3( + sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */ - tdsqlite3_stmt **ppStmt, /* OUT: Statement handle */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int tdsqlite3_prepare16( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ - tdsqlite3_stmt **ppStmt, /* OUT: Statement handle */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int tdsqlite3_prepare16_v2( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ - tdsqlite3_stmt **ppStmt, /* OUT: Statement handle */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); -SQLITE_API int tdsqlite3_prepare16_v3( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3_prepare16_v3( + sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_ flags */ - tdsqlite3_stmt **ppStmt, /* OUT: Statement handle */ + sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); /* ** CAPI3REF: Retrieving Statement SQL -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^The tdsqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 +** ^The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 ** SQL text used to create [prepared statement] P if P was -** created by [tdsqlite3_prepare_v2()], [tdsqlite3_prepare_v3()], -** [tdsqlite3_prepare16_v2()], or [tdsqlite3_prepare16_v3()]. -** ^The tdsqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 +** created by [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], +** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()]. +** ^The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 ** string containing the SQL text of prepared statement P with ** [bound parameters] expanded. -** ^The tdsqlite3_normalized_sql(P) interface returns a pointer to a UTF-8 +** ^The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8 ** string containing the normalized SQL text of prepared statement P. The ** semantics used to normalize a SQL statement are unspecified and subject ** to change. At a minimum, literal values will be replaced with suitable @@ -5058,41 +5058,41 @@ SQLITE_API int tdsqlite3_prepare16_v3( ** ** ^(For example, if a prepared statement is created using the SQL ** text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 -** and parameter :xyz is unbound, then tdsqlite3_sql() will return -** the original string, "SELECT $abc,:xyz" but tdsqlite3_expanded_sql() +** and parameter :xyz is unbound, then sqlite3_sql() will return +** the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() ** will return "SELECT 2345,NULL".)^ ** -** ^The tdsqlite3_expanded_sql() interface returns NULL if insufficient memory +** ^The sqlite3_expanded_sql() interface returns NULL if insufficient memory ** is available to hold the result, or if the result would exceed the ** the maximum string length determined by the [SQLITE_LIMIT_LENGTH]. ** ** ^The [SQLITE_TRACE_SIZE_LIMIT] compile-time option limits the size of ** bound parameter expansions. ^The [SQLITE_OMIT_TRACE] compile-time -** option causes tdsqlite3_expanded_sql() to always return NULL. +** option causes sqlite3_expanded_sql() to always return NULL. ** -** ^The strings returned by tdsqlite3_sql(P) and tdsqlite3_normalized_sql(P) +** ^The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) ** are managed by SQLite and are automatically freed when the prepared ** statement is finalized. -** ^The string returned by tdsqlite3_expanded_sql(P), on the other hand, -** is obtained from [tdsqlite3_malloc()] and must be free by the application -** by passing it to [tdsqlite3_free()]. +** ^The string returned by sqlite3_expanded_sql(P), on the other hand, +** is obtained from [sqlite3_malloc()] and must be free by the application +** by passing it to [sqlite3_free()]. */ -SQLITE_API const char *tdsqlite3_sql(tdsqlite3_stmt *pStmt); -SQLITE_API char *tdsqlite3_expanded_sql(tdsqlite3_stmt *pStmt); -SQLITE_API const char *tdsqlite3_normalized_sql(tdsqlite3_stmt *pStmt); +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); +SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt); +SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If An SQL Statement Writes The Database -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^The tdsqlite3_stmt_readonly(X) interface returns true (non-zero) if +** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if ** and only if the [prepared statement] X makes no direct changes to ** the content of the database file. ** ** Note that [application-defined SQL functions] or ** [virtual tables] might change the database indirectly as a side effect. ** ^(For example, if an application defines a function "eval()" that -** calls [tdsqlite3_exec()], then the following SQL statement would +** calls [sqlite3_exec()], then the following SQL statement would ** change the database file through side-effects: ** **

    @@ -5100,119 +5100,119 @@ SQLITE_API const char *tdsqlite3_normalized_sql(tdsqlite3_stmt *pStmt);
     ** 
    ** ** But because the [SELECT] statement does not change the database file -** directly, tdsqlite3_stmt_readonly() would still return true.)^ +** directly, sqlite3_stmt_readonly() would still return true.)^ ** ** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], -** [SAVEPOINT], and [RELEASE] cause tdsqlite3_stmt_readonly() to return true, +** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, ** since the statements themselves do not actually modify the database but ** rather they control the timing of when other statements modify the ** database. ^The [ATTACH] and [DETACH] statements also cause -** tdsqlite3_stmt_readonly() to return true since, while those statements +** sqlite3_stmt_readonly() to return true since, while those statements ** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. -** ^The tdsqlite3_stmt_readonly() interface returns true for [BEGIN] since +** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since ** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and ** [BEGIN|BEGIN EXCLUSIVE] commands do touch the database and so -** tdsqlite3_stmt_readonly() returns false for those commands. +** sqlite3_stmt_readonly() returns false for those commands. */ -SQLITE_API int tdsqlite3_stmt_readonly(tdsqlite3_stmt *pStmt); +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt); /* ** CAPI3REF: Query The EXPLAIN Setting For A Prepared Statement -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^The tdsqlite3_stmt_isexplain(S) interface returns 1 if the +** ^The sqlite3_stmt_isexplain(S) interface returns 1 if the ** prepared statement S is an EXPLAIN statement, or 2 if the ** statement S is an EXPLAIN QUERY PLAN. -** ^The tdsqlite3_stmt_isexplain(S) interface returns 0 if S is +** ^The sqlite3_stmt_isexplain(S) interface returns 0 if S is ** an ordinary statement or a NULL pointer. */ -SQLITE_API int tdsqlite3_stmt_isexplain(tdsqlite3_stmt *pStmt); +SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); /* ** CAPI3REF: Determine If A Prepared Statement Has Been Reset -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^The tdsqlite3_stmt_busy(S) interface returns true (non-zero) if the +** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the ** [prepared statement] S has been stepped at least once using -** [tdsqlite3_step(S)] but has neither run to completion (returned -** [SQLITE_DONE] from [tdsqlite3_step(S)]) nor -** been reset using [tdsqlite3_reset(S)]. ^The tdsqlite3_stmt_busy(S) +** [sqlite3_step(S)] but has neither run to completion (returned +** [SQLITE_DONE] from [sqlite3_step(S)]) nor +** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) ** interface returns false if S is a NULL pointer. If S is not a ** NULL pointer and is not a pointer to a valid [prepared statement] ** object, then the behavior is undefined and probably undesirable. ** -** This interface can be used in combination [tdsqlite3_next_stmt()] +** This interface can be used in combination [sqlite3_next_stmt()] ** to locate all prepared statements associated with a database ** connection that are in need of being reset. This can be used, ** for example, in diagnostic routines to search for prepared ** statements that are holding a transaction open. */ -SQLITE_API int tdsqlite3_stmt_busy(tdsqlite3_stmt*); +SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt*); /* ** CAPI3REF: Dynamically Typed Value Object -** KEYWORDS: {protected tdsqlite3_value} {unprotected tdsqlite3_value} +** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value} ** -** SQLite uses the tdsqlite3_value object to represent all values +** SQLite uses the sqlite3_value object to represent all values ** that can be stored in a database table. SQLite uses dynamic typing -** for the values it stores. ^Values stored in tdsqlite3_value objects +** for the values it stores. ^Values stored in sqlite3_value objects ** can be integers, floating point values, strings, BLOBs, or NULL. ** -** An tdsqlite3_value object may be either "protected" or "unprotected". -** Some interfaces require a protected tdsqlite3_value. Other interfaces -** will accept either a protected or an unprotected tdsqlite3_value. -** Every interface that accepts tdsqlite3_value arguments specifies -** whether or not it requires a protected tdsqlite3_value. The -** [tdsqlite3_value_dup()] interface can be used to construct a new -** protected tdsqlite3_value from an unprotected tdsqlite3_value. +** An sqlite3_value object may be either "protected" or "unprotected". +** Some interfaces require a protected sqlite3_value. Other interfaces +** will accept either a protected or an unprotected sqlite3_value. +** Every interface that accepts sqlite3_value arguments specifies +** whether or not it requires a protected sqlite3_value. The +** [sqlite3_value_dup()] interface can be used to construct a new +** protected sqlite3_value from an unprotected sqlite3_value. ** ** The terms "protected" and "unprotected" refer to whether or not ** a mutex is held. An internal mutex is held for a protected -** tdsqlite3_value object but no mutex is held for an unprotected -** tdsqlite3_value object. If SQLite is compiled to be single-threaded -** (with [SQLITE_THREADSAFE=0] and with [tdsqlite3_threadsafe()] returning 0) +** sqlite3_value object but no mutex is held for an unprotected +** sqlite3_value object. If SQLite is compiled to be single-threaded +** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) ** or if SQLite is run in one of reduced mutex modes ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] ** then there is no distinction between protected and unprotected -** tdsqlite3_value objects and they can be used interchangeably. However, +** sqlite3_value objects and they can be used interchangeably. However, ** for maximum code portability it is recommended that applications ** still make the distinction between protected and unprotected -** tdsqlite3_value objects even when not strictly required. +** sqlite3_value objects even when not strictly required. ** -** ^The tdsqlite3_value objects that are passed as parameters into the +** ^The sqlite3_value objects that are passed as parameters into the ** implementation of [application-defined SQL functions] are protected. -** ^The tdsqlite3_value object returned by -** [tdsqlite3_column_value()] is unprotected. -** Unprotected tdsqlite3_value objects may only be used as arguments -** to [tdsqlite3_result_value()], [tdsqlite3_bind_value()], and -** [tdsqlite3_value_dup()]. -** The [tdsqlite3_value_blob | tdsqlite3_value_type()] family of -** interfaces require protected tdsqlite3_value objects. +** ^The sqlite3_value object returned by +** [sqlite3_column_value()] is unprotected. +** Unprotected sqlite3_value objects may only be used as arguments +** to [sqlite3_result_value()], [sqlite3_bind_value()], and +** [sqlite3_value_dup()]. +** The [sqlite3_value_blob | sqlite3_value_type()] family of +** interfaces require protected sqlite3_value objects. */ -typedef struct tdsqlite3_value tdsqlite3_value; +typedef struct sqlite3_value sqlite3_value; /* ** CAPI3REF: SQL Function Context Object ** ** The context in which an SQL function executes is stored in an -** tdsqlite3_context object. ^A pointer to an tdsqlite3_context object +** sqlite3_context object. ^A pointer to an sqlite3_context object ** is always first parameter to [application-defined SQL functions]. ** The application-defined SQL function implementation will pass this -** pointer through into calls to [tdsqlite3_result_int | tdsqlite3_result()], -** [tdsqlite3_aggregate_context()], [tdsqlite3_user_data()], -** [tdsqlite3_context_db_handle()], [tdsqlite3_get_auxdata()], -** and/or [tdsqlite3_set_auxdata()]. +** pointer through into calls to [sqlite3_result_int | sqlite3_result()], +** [sqlite3_aggregate_context()], [sqlite3_user_data()], +** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()], +** and/or [sqlite3_set_auxdata()]. */ -typedef struct tdsqlite3_context tdsqlite3_context; +typedef struct sqlite3_context sqlite3_context; /* ** CAPI3REF: Binding Values To Prepared Statements ** KEYWORDS: {host parameter} {host parameters} {host parameter name} ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^(In the SQL statement text input to [tdsqlite3_prepare_v2()] and its variants, +** ^(In the SQL statement text input to [sqlite3_prepare_v2()] and its variants, ** literals may be replaced by a [parameter] that matches one of following ** templates: ** @@ -5227,37 +5227,37 @@ typedef struct tdsqlite3_context tdsqlite3_context; ** In the templates above, NNN represents an integer literal, ** and VVV represents an alphanumeric identifier.)^ ^The values of these ** parameters (also called "host parameter names" or "SQL parameters") -** can be set using the tdsqlite3_bind_*() routines defined here. +** can be set using the sqlite3_bind_*() routines defined here. ** -** ^The first argument to the tdsqlite3_bind_*() routines is always -** a pointer to the [tdsqlite3_stmt] object returned from -** [tdsqlite3_prepare_v2()] or its variants. +** ^The first argument to the sqlite3_bind_*() routines is always +** a pointer to the [sqlite3_stmt] object returned from +** [sqlite3_prepare_v2()] or its variants. ** ** ^The second argument is the index of the SQL parameter to be set. ** ^The leftmost SQL parameter has an index of 1. ^When the same named ** SQL parameter is used more than once, second and subsequent ** occurrences have the same index as the first occurrence. ** ^The index for named parameters can be looked up using the -** [tdsqlite3_bind_parameter_index()] API if desired. ^The index +** [sqlite3_bind_parameter_index()] API if desired. ^The index ** for "?NNN" parameters is the value of NNN. -** ^The NNN value must be between 1 and the [tdsqlite3_limit()] +** ^The NNN value must be between 1 and the [sqlite3_limit()] ** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999). ** ** ^The third argument is the value to bind to the parameter. -** ^If the third parameter to tdsqlite3_bind_text() or tdsqlite3_bind_text16() -** or tdsqlite3_bind_blob() is a NULL pointer then the fourth parameter -** is ignored and the end result is the same as tdsqlite3_bind_null(). +** ^If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() +** or sqlite3_bind_blob() is a NULL pointer then the fourth parameter +** is ignored and the end result is the same as sqlite3_bind_null(). ** ** ^(In those routines that have a fourth argument, its value is the ** number of bytes in the parameter. To be clear: the value is the ** number of bytes in the value, not the number of characters.)^ -** ^If the fourth parameter to tdsqlite3_bind_text() or tdsqlite3_bind_text16() +** ^If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() ** is negative, then the length of the string is ** the number of bytes up to the first zero terminator. -** If the fourth parameter to tdsqlite3_bind_blob() is negative, then +** If the fourth parameter to sqlite3_bind_blob() is negative, then ** the behavior is undefined. -** If a non-negative fourth parameter is provided to tdsqlite3_bind_text() -** or tdsqlite3_bind_text16() or tdsqlite3_bind_text64() then +** If a non-negative fourth parameter is provided to sqlite3_bind_text() +** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL ** terminated. If any NUL characters occur at byte offsets less than @@ -5276,78 +5276,78 @@ typedef struct tdsqlite3_context tdsqlite3_context; ** information is in static, unmanaged space and does not need to be freed. ** ^If the fifth argument has the value [SQLITE_TRANSIENT], then ** SQLite makes its own private copy of the data immediately, before -** the tdsqlite3_bind_*() routine returns. +** the sqlite3_bind_*() routine returns. ** -** ^The sixth argument to tdsqlite3_bind_text64() must be one of +** ^The sixth argument to sqlite3_bind_text64() must be one of ** [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE] ** to specify the encoding of the text in the third parameter. If -** the sixth argument to tdsqlite3_bind_text64() is not one of the +** the sixth argument to sqlite3_bind_text64() is not one of the ** allowed values shown above, or if the text encoding is different ** from the encoding specified by the sixth parameter, then the behavior ** is undefined. ** -** ^The tdsqlite3_bind_zeroblob() routine binds a BLOB of length N that +** ^The sqlite3_bind_zeroblob() routine binds a BLOB of length N that ** is filled with zeroes. ^A zeroblob uses a fixed amount of memory ** (just an integer to hold its size) while it is being processed. ** Zeroblobs are intended to serve as placeholders for BLOBs whose ** content is later written using -** [tdsqlite3_blob_open | incremental BLOB I/O] routines. +** [sqlite3_blob_open | incremental BLOB I/O] routines. ** ^A negative value for the zeroblob results in a zero-length BLOB. ** -** ^The tdsqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in +** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in ** [prepared statement] S to have an SQL value of NULL, but to also be ** associated with the pointer P of type T. ^D is either a NULL pointer or ** a pointer to a destructor function for P. ^SQLite will invoke the ** destructor D with a single argument of P when it is finished using ** P. The T parameter should be a static string, preferably a string -** literal. The tdsqlite3_bind_pointer() routine is part of the +** literal. The sqlite3_bind_pointer() routine is part of the ** [pointer passing interface] added for SQLite 3.20.0. ** -** ^If any of the tdsqlite3_bind_*() routines are called with a NULL pointer +** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which -** [tdsqlite3_step()] has been called more recently than [tdsqlite3_reset()], -** then the call will return [SQLITE_MISUSE]. If any tdsqlite3_bind_() +** [sqlite3_step()] has been called more recently than [sqlite3_reset()], +** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() ** routine is passed a [prepared statement] that has been finalized, the ** result is undefined and probably harmful. ** -** ^Bindings are not cleared by the [tdsqlite3_reset()] routine. +** ^Bindings are not cleared by the [sqlite3_reset()] routine. ** ^Unbound parameters are interpreted as NULL. ** -** ^The tdsqlite3_bind_* routines return [SQLITE_OK] on success or an +** ^The sqlite3_bind_* routines return [SQLITE_OK] on success or an ** [error code] if anything goes wrong. ** ^[SQLITE_TOOBIG] might be returned if the size of a string or BLOB -** exceeds limits imposed by [tdsqlite3_limit]([SQLITE_LIMIT_LENGTH]) or +** exceeds limits imposed by [sqlite3_limit]([SQLITE_LIMIT_LENGTH]) or ** [SQLITE_MAX_LENGTH]. ** ^[SQLITE_RANGE] is returned if the parameter ** index is out of range. ^[SQLITE_NOMEM] is returned if malloc() fails. ** -** See also: [tdsqlite3_bind_parameter_count()], -** [tdsqlite3_bind_parameter_name()], and [tdsqlite3_bind_parameter_index()]. +** See also: [sqlite3_bind_parameter_count()], +** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()]. */ -SQLITE_API int tdsqlite3_bind_blob(tdsqlite3_stmt*, int, const void*, int n, void(*)(void*)); -SQLITE_API int tdsqlite3_bind_blob64(tdsqlite3_stmt*, int, const void*, tdsqlite3_uint64, +SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_blob64(sqlite3_stmt*, int, const void*, sqlite3_uint64, void(*)(void*)); -SQLITE_API int tdsqlite3_bind_double(tdsqlite3_stmt*, int, double); -SQLITE_API int tdsqlite3_bind_int(tdsqlite3_stmt*, int, int); -SQLITE_API int tdsqlite3_bind_int64(tdsqlite3_stmt*, int, tdsqlite3_int64); -SQLITE_API int tdsqlite3_bind_null(tdsqlite3_stmt*, int); -SQLITE_API int tdsqlite3_bind_text(tdsqlite3_stmt*,int,const char*,int,void(*)(void*)); -SQLITE_API int tdsqlite3_bind_text16(tdsqlite3_stmt*, int, const void*, int, void(*)(void*)); -SQLITE_API int tdsqlite3_bind_text64(tdsqlite3_stmt*, int, const char*, tdsqlite3_uint64, +SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int sqlite3_bind_text(sqlite3_stmt*,int,const char*,int,void(*)(void*)); +SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int sqlite3_bind_text64(sqlite3_stmt*, int, const char*, sqlite3_uint64, void(*)(void*), unsigned char encoding); -SQLITE_API int tdsqlite3_bind_value(tdsqlite3_stmt*, int, const tdsqlite3_value*); -SQLITE_API int tdsqlite3_bind_pointer(tdsqlite3_stmt*, int, void*, const char*,void(*)(void*)); -SQLITE_API int tdsqlite3_bind_zeroblob(tdsqlite3_stmt*, int, int n); -SQLITE_API int tdsqlite3_bind_zeroblob64(tdsqlite3_stmt*, int, tdsqlite3_uint64); +SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_pointer(sqlite3_stmt*, int, void*, const char*,void(*)(void*)); +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); +SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt*, int, sqlite3_uint64); /* ** CAPI3REF: Number Of SQL Parameters -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** ^This routine can be used to find the number of [SQL parameters] ** in a [prepared statement]. SQL parameters are tokens of the ** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as -** placeholders for values that are [tdsqlite3_bind_blob | bound] +** placeholders for values that are [sqlite3_bind_blob | bound] ** to the parameters at a later time. ** ** ^(This routine actually returns the index of the largest (rightmost) @@ -5355,17 +5355,17 @@ SQLITE_API int tdsqlite3_bind_zeroblob64(tdsqlite3_stmt*, int, tdsqlite3_uint64) ** number of unique parameters. If parameters of the ?NNN form are used, ** there may be gaps in the list.)^ ** -** See also: [tdsqlite3_bind_blob|tdsqlite3_bind()], -** [tdsqlite3_bind_parameter_name()], and -** [tdsqlite3_bind_parameter_index()]. +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_name()], and +** [sqlite3_bind_parameter_index()]. */ -SQLITE_API int tdsqlite3_bind_parameter_count(tdsqlite3_stmt*); +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); /* ** CAPI3REF: Name Of A Host Parameter -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^The tdsqlite3_bind_parameter_name(P,N) interface returns +** ^The sqlite3_bind_parameter_name(P,N) interface returns ** the name of the N-th [SQL parameter] in the [prepared statement] P. ** ^(SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" ** have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" @@ -5380,78 +5380,78 @@ SQLITE_API int tdsqlite3_bind_parameter_count(tdsqlite3_stmt*); ** ^If the value N is out of range or if the N-th parameter is ** nameless, then NULL is returned. ^The returned string is ** always in UTF-8 encoding even if the named parameter was -** originally specified as UTF-16 in [tdsqlite3_prepare16()], -** [tdsqlite3_prepare16_v2()], or [tdsqlite3_prepare16_v3()]. +** originally specified as UTF-16 in [sqlite3_prepare16()], +** [sqlite3_prepare16_v2()], or [sqlite3_prepare16_v3()]. ** -** See also: [tdsqlite3_bind_blob|tdsqlite3_bind()], -** [tdsqlite3_bind_parameter_count()], and -** [tdsqlite3_bind_parameter_index()]. +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_index()]. */ -SQLITE_API const char *tdsqlite3_bind_parameter_name(tdsqlite3_stmt*, int); +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); /* ** CAPI3REF: Index Of A Parameter With A Given Name -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** ^Return the index of an SQL parameter given its name. ^The ** index value returned is suitable for use as the second -** parameter to [tdsqlite3_bind_blob|tdsqlite3_bind()]. ^A zero +** parameter to [sqlite3_bind_blob|sqlite3_bind()]. ^A zero ** is returned if no matching parameter is found. ^The parameter ** name must be given in UTF-8 even if the original statement -** was prepared from UTF-16 text using [tdsqlite3_prepare16_v2()] or -** [tdsqlite3_prepare16_v3()]. +** was prepared from UTF-16 text using [sqlite3_prepare16_v2()] or +** [sqlite3_prepare16_v3()]. ** -** See also: [tdsqlite3_bind_blob|tdsqlite3_bind()], -** [tdsqlite3_bind_parameter_count()], and -** [tdsqlite3_bind_parameter_name()]. +** See also: [sqlite3_bind_blob|sqlite3_bind()], +** [sqlite3_bind_parameter_count()], and +** [sqlite3_bind_parameter_name()]. */ -SQLITE_API int tdsqlite3_bind_parameter_index(tdsqlite3_stmt*, const char *zName); +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); /* ** CAPI3REF: Reset All Bindings On A Prepared Statement -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^Contrary to the intuition of many, [tdsqlite3_reset()] does not reset -** the [tdsqlite3_bind_blob | bindings] on a [prepared statement]. +** ^Contrary to the intuition of many, [sqlite3_reset()] does not reset +** the [sqlite3_bind_blob | bindings] on a [prepared statement]. ** ^Use this routine to reset all host parameters to NULL. */ -SQLITE_API int tdsqlite3_clear_bindings(tdsqlite3_stmt*); +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); /* ** CAPI3REF: Number Of Columns In A Result Set -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the ** [prepared statement]. ^If this routine returns 0, that means the ** [prepared statement] returns no data (for example an [UPDATE]). ** ^However, just because this routine returns a positive number does not ** mean that one or more rows of data will be returned. ^A SELECT statement -** will always have a positive tdsqlite3_column_count() but depending on the +** will always have a positive sqlite3_column_count() but depending on the ** WHERE clause constraints and the table content, it might return no rows. ** -** See also: [tdsqlite3_data_count()] +** See also: [sqlite3_data_count()] */ -SQLITE_API int tdsqlite3_column_count(tdsqlite3_stmt *pStmt); +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Column Names In A Result Set -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** ^These routines return the name assigned to a particular column -** in the result set of a [SELECT] statement. ^The tdsqlite3_column_name() +** in the result set of a [SELECT] statement. ^The sqlite3_column_name() ** interface returns a pointer to a zero-terminated UTF-8 string -** and tdsqlite3_column_name16() returns a pointer to a zero-terminated +** and sqlite3_column_name16() returns a pointer to a zero-terminated ** UTF-16 string. ^The first parameter is the [prepared statement] ** that implements the [SELECT] statement. ^The second parameter is the ** column number. ^The leftmost column is number 0. ** ** ^The returned string pointer is valid until either the [prepared statement] -** is destroyed by [tdsqlite3_finalize()] or until the statement is automatically -** reprepared by the first call to [tdsqlite3_step()] for a particular run +** is destroyed by [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run ** or until the next call to -** tdsqlite3_column_name() or tdsqlite3_column_name16() on the same column. +** sqlite3_column_name() or sqlite3_column_name16() on the same column. ** -** ^If tdsqlite3_malloc() fails during the processing of either routine +** ^If sqlite3_malloc() fails during the processing of either routine ** (for example during a conversion from UTF-8 to UTF-16) then a ** NULL pointer is returned. ** @@ -5460,12 +5460,12 @@ SQLITE_API int tdsqlite3_column_count(tdsqlite3_stmt *pStmt); ** then the name of the column is unspecified and may change from ** one release of SQLite to the next. */ -SQLITE_API const char *tdsqlite3_column_name(tdsqlite3_stmt*, int N); -SQLITE_API const void *tdsqlite3_column_name16(tdsqlite3_stmt*, int N); +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** ^These routines provide a means to determine the database, table, and ** table column that is the origin of a particular result column in @@ -5475,8 +5475,8 @@ SQLITE_API const void *tdsqlite3_column_name16(tdsqlite3_stmt*, int N); ** the database name, the _table_ routines return the table name, and ** the origin_ routines return the column name. ** ^The returned string is valid until the [prepared statement] is destroyed -** using [tdsqlite3_finalize()] or until the statement is automatically -** reprepared by the first call to [tdsqlite3_step()] for a particular run +** using [sqlite3_finalize()] or until the statement is automatically +** reprepared by the first call to [sqlite3_step()] for a particular run ** or until the same information is requested ** again in a different encoding. ** @@ -5501,20 +5501,20 @@ SQLITE_API const void *tdsqlite3_column_name16(tdsqlite3_stmt*, int N); ** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol. ** ** If two or more threads call one or more -** [tdsqlite3_column_database_name | column metadata interfaces] +** [sqlite3_column_database_name | column metadata interfaces] ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ -SQLITE_API const char *tdsqlite3_column_database_name(tdsqlite3_stmt*,int); -SQLITE_API const void *tdsqlite3_column_database_name16(tdsqlite3_stmt*,int); -SQLITE_API const char *tdsqlite3_column_table_name(tdsqlite3_stmt*,int); -SQLITE_API const void *tdsqlite3_column_table_name16(tdsqlite3_stmt*,int); -SQLITE_API const char *tdsqlite3_column_origin_name(tdsqlite3_stmt*,int); -SQLITE_API const void *tdsqlite3_column_origin_name16(tdsqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); /* ** CAPI3REF: Declared Datatype Of A Query Result -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** ^(The first parameter is a [prepared statement]. ** If this statement is a [SELECT] statement and the Nth column of the @@ -5542,24 +5542,24 @@ SQLITE_API const void *tdsqlite3_column_origin_name16(tdsqlite3_stmt*,int); ** is associated with individual values, not with the containers ** used to hold those values. */ -SQLITE_API const char *tdsqlite3_column_decltype(tdsqlite3_stmt*,int); -SQLITE_API const void *tdsqlite3_column_decltype16(tdsqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); /* ** CAPI3REF: Evaluate An SQL Statement -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** After a [prepared statement] has been prepared using any of -** [tdsqlite3_prepare_v2()], [tdsqlite3_prepare_v3()], [tdsqlite3_prepare16_v2()], -** or [tdsqlite3_prepare16_v3()] or one of the legacy -** interfaces [tdsqlite3_prepare()] or [tdsqlite3_prepare16()], this function +** [sqlite3_prepare_v2()], [sqlite3_prepare_v3()], [sqlite3_prepare16_v2()], +** or [sqlite3_prepare16_v3()] or one of the legacy +** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function ** must be called one or more times to evaluate the statement. ** -** The details of the behavior of the tdsqlite3_step() interface depend +** The details of the behavior of the sqlite3_step() interface depend ** on whether the statement was prepared using the newer "vX" interfaces -** [tdsqlite3_prepare_v3()], [tdsqlite3_prepare_v2()], [tdsqlite3_prepare16_v3()], -** [tdsqlite3_prepare16_v2()] or the older legacy -** interfaces [tdsqlite3_prepare()] and [tdsqlite3_prepare16()]. The use of the +** [sqlite3_prepare_v3()], [sqlite3_prepare_v2()], [sqlite3_prepare16_v3()], +** [sqlite3_prepare16_v2()] or the older legacy +** interfaces [sqlite3_prepare()] and [sqlite3_prepare16()]. The use of the ** new "vX" interface is recommended for new applications but the legacy ** interface will continue to be supported. ** @@ -5576,79 +5576,79 @@ SQLITE_API const void *tdsqlite3_column_decltype16(tdsqlite3_stmt*,int); ** continuing. ** ** ^[SQLITE_DONE] means that the statement has finished executing -** successfully. tdsqlite3_step() should not be called again on this virtual -** machine without first calling [tdsqlite3_reset()] to reset the virtual +** successfully. sqlite3_step() should not be called again on this virtual +** machine without first calling [sqlite3_reset()] to reset the virtual ** machine back to its initial state. ** ** ^If the SQL statement being executed returns any data, then [SQLITE_ROW] ** is returned each time a new row of data is ready for processing by the ** caller. The values may be accessed using the [column access functions]. -** tdsqlite3_step() is called again to retrieve the next row of data. +** sqlite3_step() is called again to retrieve the next row of data. ** ** ^[SQLITE_ERROR] means that a run-time error (such as a constraint -** violation) has occurred. tdsqlite3_step() should not be called again on -** the VM. More information may be found by calling [tdsqlite3_errmsg()]. +** violation) has occurred. sqlite3_step() should not be called again on +** the VM. More information may be found by calling [sqlite3_errmsg()]. ** ^With the legacy interface, a more specific error code (for example, ** [SQLITE_INTERRUPT], [SQLITE_SCHEMA], [SQLITE_CORRUPT], and so forth) -** can be obtained by calling [tdsqlite3_reset()] on the +** can be obtained by calling [sqlite3_reset()] on the ** [prepared statement]. ^In the "v2" interface, -** the more specific error code is returned directly by tdsqlite3_step(). +** the more specific error code is returned directly by sqlite3_step(). ** ** [SQLITE_MISUSE] means that the this routine was called inappropriately. ** Perhaps it was called on a [prepared statement] that has -** already been [tdsqlite3_finalize | finalized] or on one that had +** already been [sqlite3_finalize | finalized] or on one that had ** previously returned [SQLITE_ERROR] or [SQLITE_DONE]. Or it could ** be the case that the same database connection is being used by two or ** more threads at the same moment in time. ** ** For all versions of SQLite up to and including 3.6.23.1, a call to -** [tdsqlite3_reset()] was required after tdsqlite3_step() returned anything +** [sqlite3_reset()] was required after sqlite3_step() returned anything ** other than [SQLITE_ROW] before any subsequent invocation of -** tdsqlite3_step(). Failure to reset the prepared statement using -** [tdsqlite3_reset()] would result in an [SQLITE_MISUSE] return from -** tdsqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], -** tdsqlite3_step() began -** calling [tdsqlite3_reset()] automatically in this circumstance rather +** sqlite3_step(). Failure to reset the prepared statement using +** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from +** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], +** sqlite3_step() began +** calling [sqlite3_reset()] automatically in this circumstance rather ** than returning [SQLITE_MISUSE]. This is not considered a compatibility ** break because any application that ever receives an SQLITE_MISUSE error ** is broken by definition. The [SQLITE_OMIT_AUTORESET] compile-time option ** can be used to restore the legacy behavior. ** -** Goofy Interface Alert: In the legacy interface, the tdsqlite3_step() +** Goofy Interface Alert: In the legacy interface, the sqlite3_step() ** API always returns a generic error code, [SQLITE_ERROR], following any ** error other than [SQLITE_BUSY] and [SQLITE_MISUSE]. You must call -** [tdsqlite3_reset()] or [tdsqlite3_finalize()] in order to find one of the +** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the ** specific [error codes] that better describes the error. ** We admit that this is a goofy design. The problem has been fixed ** with the "v2" interface. If you prepare all of your SQL statements -** using [tdsqlite3_prepare_v3()] or [tdsqlite3_prepare_v2()] -** or [tdsqlite3_prepare16_v2()] or [tdsqlite3_prepare16_v3()] instead -** of the legacy [tdsqlite3_prepare()] and [tdsqlite3_prepare16()] interfaces, +** using [sqlite3_prepare_v3()] or [sqlite3_prepare_v2()] +** or [sqlite3_prepare16_v2()] or [sqlite3_prepare16_v3()] instead +** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces, ** then the more specific [error codes] are returned directly -** by tdsqlite3_step(). The use of the "vX" interfaces is recommended. +** by sqlite3_step(). The use of the "vX" interfaces is recommended. */ -SQLITE_API int tdsqlite3_step(tdsqlite3_stmt*); +SQLITE_API int sqlite3_step(sqlite3_stmt*); /* ** CAPI3REF: Number of columns in a result set -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^The tdsqlite3_data_count(P) interface returns the number of columns in the +** ^The sqlite3_data_count(P) interface returns the number of columns in the ** current row of the result set of [prepared statement] P. ** ^If prepared statement P does not have results ready to return -** (via calls to the [tdsqlite3_column_int | tdsqlite3_column()] family of -** interfaces) then tdsqlite3_data_count(P) returns 0. -** ^The tdsqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. -** ^The tdsqlite3_data_count(P) routine returns 0 if the previous call to -** [tdsqlite3_step](P) returned [SQLITE_DONE]. ^The tdsqlite3_data_count(P) -** will return non-zero if previous call to [tdsqlite3_step](P) returned +** (via calls to the [sqlite3_column_int | sqlite3_column()] family of +** interfaces) then sqlite3_data_count(P) returns 0. +** ^The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +** ^The sqlite3_data_count(P) routine returns 0 if the previous call to +** [sqlite3_step](P) returned [SQLITE_DONE]. ^The sqlite3_data_count(P) +** will return non-zero if previous call to [sqlite3_step](P) returned ** [SQLITE_ROW], except in the case of the [PRAGMA incremental_vacuum] ** where it always returns zero since each step of that multi-step ** pragma returns 0 columns of data. ** -** See also: [tdsqlite3_column_count()] +** See also: [sqlite3_column_count()] */ -SQLITE_API int tdsqlite3_data_count(tdsqlite3_stmt *pStmt); +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Fundamental Datatypes @@ -5685,25 +5685,25 @@ SQLITE_API int tdsqlite3_data_count(tdsqlite3_stmt *pStmt); /* ** CAPI3REF: Result Values From A Query ** KEYWORDS: {column access functions} -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** Summary: **
    -**
    tdsqlite3_column_blobBLOB result -**
    tdsqlite3_column_doubleREAL result -**
    tdsqlite3_column_int32-bit INTEGER result -**
    tdsqlite3_column_int6464-bit INTEGER result -**
    tdsqlite3_column_textUTF-8 TEXT result -**
    tdsqlite3_column_text16UTF-16 TEXT result -**
    tdsqlite3_column_valueThe result as an -** [tdsqlite3_value|unprotected tdsqlite3_value] object. +**
    sqlite3_column_blobBLOB result +**
    sqlite3_column_doubleREAL result +**
    sqlite3_column_int32-bit INTEGER result +**
    sqlite3_column_int6464-bit INTEGER result +**
    sqlite3_column_textUTF-8 TEXT result +**
    sqlite3_column_text16UTF-16 TEXT result +**
    sqlite3_column_valueThe result as an +** [sqlite3_value|unprotected sqlite3_value] object. **
        -**
    tdsqlite3_column_bytesSize of a BLOB +**
    sqlite3_column_bytesSize of a BLOB ** or a UTF-8 TEXT result in bytes -**
    tdsqlite3_column_bytes16   +**
    sqlite3_column_bytes16   ** →  Size of UTF-16 ** TEXT in bytes -**
    tdsqlite3_column_typeDefault +**
    sqlite3_column_typeDefault ** datatype of the result **
    ** @@ -5711,92 +5711,92 @@ SQLITE_API int tdsqlite3_data_count(tdsqlite3_stmt *pStmt); ** ** ^These routines return information about a single column of the current ** result row of a query. ^In every case the first argument is a pointer -** to the [prepared statement] that is being evaluated (the [tdsqlite3_stmt*] -** that was returned from [tdsqlite3_prepare_v2()] or one of its variants) +** to the [prepared statement] that is being evaluated (the [sqlite3_stmt*] +** that was returned from [sqlite3_prepare_v2()] or one of its variants) ** and the second argument is the index of the column for which information ** should be returned. ^The leftmost column of the result set has the index 0. ** ^The number of columns in the result can be determined using -** [tdsqlite3_column_count()]. +** [sqlite3_column_count()]. ** ** If the SQL statement does not currently point to a valid row, or if the ** column index is out of range, the result is undefined. ** These routines may only be called when the most recent call to -** [tdsqlite3_step()] has returned [SQLITE_ROW] and neither -** [tdsqlite3_reset()] nor [tdsqlite3_finalize()] have been called subsequently. -** If any of these routines are called after [tdsqlite3_reset()] or -** [tdsqlite3_finalize()] or after [tdsqlite3_step()] has returned +** [sqlite3_step()] has returned [SQLITE_ROW] and neither +** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently. +** If any of these routines are called after [sqlite3_reset()] or +** [sqlite3_finalize()] or after [sqlite3_step()] has returned ** something other than [SQLITE_ROW], the results are undefined. -** If [tdsqlite3_step()] or [tdsqlite3_reset()] or [tdsqlite3_finalize()] +** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()] ** are called from a different thread while any of these routines ** are pending, then the results are undefined. ** ** The first six interfaces (_blob, _double, _int, _int64, _text, and _text16) ** each return the value of a result column in a specific data format. If ** the result column is not initially in the requested format (for example, -** if the query returns an integer but the tdsqlite3_column_text() interface +** if the query returns an integer but the sqlite3_column_text() interface ** is used to extract the value) then an automatic type conversion is performed. ** -** ^The tdsqlite3_column_type() routine returns the +** ^The sqlite3_column_type() routine returns the ** [SQLITE_INTEGER | datatype code] for the initial data type ** of the result column. ^The returned value is one of [SQLITE_INTEGER], ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL]. -** The return value of tdsqlite3_column_type() can be used to decide which +** The return value of sqlite3_column_type() can be used to decide which ** of the first six interface should be used to extract the column value. -** The value returned by tdsqlite3_column_type() is only meaningful if no +** The value returned by sqlite3_column_type() is only meaningful if no ** automatic type conversions have occurred for the value in question. -** After a type conversion, the result of calling tdsqlite3_column_type() +** After a type conversion, the result of calling sqlite3_column_type() ** is undefined, though harmless. Future -** versions of SQLite may change the behavior of tdsqlite3_column_type() +** versions of SQLite may change the behavior of sqlite3_column_type() ** following a type conversion. ** -** If the result is a BLOB or a TEXT string, then the tdsqlite3_column_bytes() -** or tdsqlite3_column_bytes16() interfaces can be used to determine the size +** If the result is a BLOB or a TEXT string, then the sqlite3_column_bytes() +** or sqlite3_column_bytes16() interfaces can be used to determine the size ** of that BLOB or string. ** -** ^If the result is a BLOB or UTF-8 string then the tdsqlite3_column_bytes() +** ^If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() ** routine returns the number of bytes in that BLOB or string. -** ^If the result is a UTF-16 string, then tdsqlite3_column_bytes() converts +** ^If the result is a UTF-16 string, then sqlite3_column_bytes() converts ** the string to UTF-8 and then returns the number of bytes. -** ^If the result is a numeric value then tdsqlite3_column_bytes() uses -** [tdsqlite3_snprintf()] to convert that value to a UTF-8 string and returns +** ^If the result is a numeric value then sqlite3_column_bytes() uses +** [sqlite3_snprintf()] to convert that value to a UTF-8 string and returns ** the number of bytes in that string. -** ^If the result is NULL, then tdsqlite3_column_bytes() returns zero. +** ^If the result is NULL, then sqlite3_column_bytes() returns zero. ** -** ^If the result is a BLOB or UTF-16 string then the tdsqlite3_column_bytes16() +** ^If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() ** routine returns the number of bytes in that BLOB or string. -** ^If the result is a UTF-8 string, then tdsqlite3_column_bytes16() converts +** ^If the result is a UTF-8 string, then sqlite3_column_bytes16() converts ** the string to UTF-16 and then returns the number of bytes. -** ^If the result is a numeric value then tdsqlite3_column_bytes16() uses -** [tdsqlite3_snprintf()] to convert that value to a UTF-16 string and returns +** ^If the result is a numeric value then sqlite3_column_bytes16() uses +** [sqlite3_snprintf()] to convert that value to a UTF-16 string and returns ** the number of bytes in that string. -** ^If the result is NULL, then tdsqlite3_column_bytes16() returns zero. +** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. ** -** ^The values returned by [tdsqlite3_column_bytes()] and -** [tdsqlite3_column_bytes16()] do not include the zero terminators at the end +** ^The values returned by [sqlite3_column_bytes()] and +** [sqlite3_column_bytes16()] do not include the zero terminators at the end ** of the string. ^For clarity: the values returned by -** [tdsqlite3_column_bytes()] and [tdsqlite3_column_bytes16()] are the number of +** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of ** bytes in the string, not the number of characters. ** -** ^Strings returned by tdsqlite3_column_text() and tdsqlite3_column_text16(), +** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(), ** even empty strings, are always zero-terminated. ^The return -** value from tdsqlite3_column_blob() for a zero-length BLOB is a NULL pointer. -** -** Warning: ^The object returned by [tdsqlite3_column_value()] is an -** [unprotected tdsqlite3_value] object. In a multithreaded environment, -** an unprotected tdsqlite3_value object may only be used safely with -** [tdsqlite3_bind_value()] and [tdsqlite3_result_value()]. -** If the [unprotected tdsqlite3_value] object returned by -** [tdsqlite3_column_value()] is used in any other way, including calls -** to routines like [tdsqlite3_value_int()], [tdsqlite3_value_text()], -** or [tdsqlite3_value_bytes()], the behavior is not threadsafe. -** Hence, the tdsqlite3_column_value() interface +** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +** +** Warning: ^The object returned by [sqlite3_column_value()] is an +** [unprotected sqlite3_value] object. In a multithreaded environment, +** an unprotected sqlite3_value object may only be used safely with +** [sqlite3_bind_value()] and [sqlite3_result_value()]. +** If the [unprotected sqlite3_value] object returned by +** [sqlite3_column_value()] is used in any other way, including calls +** to routines like [sqlite3_value_int()], [sqlite3_value_text()], +** or [sqlite3_value_bytes()], the behavior is not threadsafe. +** Hence, the sqlite3_column_value() interface ** is normally only useful within the implementation of ** [application-defined SQL functions] or [virtual tables], not within ** top-level application code. ** ** The these routines may attempt to convert the datatype of the result. ** ^For example, if the internal representation is FLOAT and a text result -** is requested, [tdsqlite3_snprintf()] is used internally to perform the +** is requested, [sqlite3_snprintf()] is used internally to perform the ** conversion automatically. ^(The following table details the conversions ** that are applied: ** @@ -5824,20 +5824,20 @@ SQLITE_API int tdsqlite3_data_count(tdsqlite3_stmt *pStmt); ** )^ ** ** Note that when type conversions occur, pointers returned by prior -** calls to tdsqlite3_column_blob(), tdsqlite3_column_text(), and/or -** tdsqlite3_column_text16() may be invalidated. +** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or +** sqlite3_column_text16() may be invalidated. ** Type conversions and pointer invalidations might occur ** in the following cases: ** **
      -**
    • The initial content is a BLOB and tdsqlite3_column_text() or -** tdsqlite3_column_text16() is called. A zero-terminator might +**
    • The initial content is a BLOB and sqlite3_column_text() or +** sqlite3_column_text16() is called. A zero-terminator might ** need to be added to the string.
    • -**
    • The initial content is UTF-8 text and tdsqlite3_column_bytes16() or -** tdsqlite3_column_text16() is called. The content must be converted +**
    • The initial content is UTF-8 text and sqlite3_column_bytes16() or +** sqlite3_column_text16() is called. The content must be converted ** to UTF-16.
    • -**
    • The initial content is UTF-16 text and tdsqlite3_column_bytes() or -** tdsqlite3_column_text() is called. The content must be converted +**
    • The initial content is UTF-16 text and sqlite3_column_bytes() or +** sqlite3_column_text() is called. The content must be converted ** to UTF-8.
    • **
    ** @@ -5851,25 +5851,25 @@ SQLITE_API int tdsqlite3_data_count(tdsqlite3_stmt *pStmt); ** in one of the following ways: ** **
      -**
    • tdsqlite3_column_text() followed by tdsqlite3_column_bytes()
    • -**
    • tdsqlite3_column_blob() followed by tdsqlite3_column_bytes()
    • -**
    • tdsqlite3_column_text16() followed by tdsqlite3_column_bytes16()
    • +**
    • sqlite3_column_text() followed by sqlite3_column_bytes()
    • +**
    • sqlite3_column_blob() followed by sqlite3_column_bytes()
    • +**
    • sqlite3_column_text16() followed by sqlite3_column_bytes16()
    • **
    ** -** In other words, you should call tdsqlite3_column_text(), -** tdsqlite3_column_blob(), or tdsqlite3_column_text16() first to force the result -** into the desired format, then invoke tdsqlite3_column_bytes() or -** tdsqlite3_column_bytes16() to find the size of the result. Do not mix calls -** to tdsqlite3_column_text() or tdsqlite3_column_blob() with calls to -** tdsqlite3_column_bytes16(), and do not mix calls to tdsqlite3_column_text16() -** with calls to tdsqlite3_column_bytes(). +** In other words, you should call sqlite3_column_text(), +** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result +** into the desired format, then invoke sqlite3_column_bytes() or +** sqlite3_column_bytes16() to find the size of the result. Do not mix calls +** to sqlite3_column_text() or sqlite3_column_blob() with calls to +** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16() +** with calls to sqlite3_column_bytes(). ** ** ^The pointers returned are valid until a type conversion occurs as -** described above, or until [tdsqlite3_step()] or [tdsqlite3_reset()] or -** [tdsqlite3_finalize()] is called. ^The memory space used to hold strings +** described above, or until [sqlite3_step()] or [sqlite3_reset()] or +** [sqlite3_finalize()] is called. ^The memory space used to hold strings ** and BLOBs is freed automatically. Do not pass the pointers returned -** from [tdsqlite3_column_blob()], [tdsqlite3_column_text()], etc. into -** [tdsqlite3_free()]. +** from [sqlite3_column_blob()], [sqlite3_column_text()], etc. into +** [sqlite3_free()]. ** ** As long as the input parameters are correct, these routines will only ** fail if an out-of-memory error occurs during a format conversion. @@ -5877,50 +5877,50 @@ SQLITE_API int tdsqlite3_data_count(tdsqlite3_stmt *pStmt); ** errors: ** **
      -**
    • tdsqlite3_column_blob() -**
    • tdsqlite3_column_text() -**
    • tdsqlite3_column_text16() -**
    • tdsqlite3_column_bytes() -**
    • tdsqlite3_column_bytes16() +**
    • sqlite3_column_blob() +**
    • sqlite3_column_text() +**
    • sqlite3_column_text16() +**
    • sqlite3_column_bytes() +**
    • sqlite3_column_bytes16() **
    ** ** If an out-of-memory error occurs, then the return value from these ** routines is the same as if the column had contained an SQL NULL value. ** Valid SQL NULL returns can be distinguished from out-of-memory errors -** by invoking the [tdsqlite3_errcode()] immediately after the suspect +** by invoking the [sqlite3_errcode()] immediately after the suspect ** return value is obtained and before any ** other SQLite interface is called on the same [database connection]. */ -SQLITE_API const void *tdsqlite3_column_blob(tdsqlite3_stmt*, int iCol); -SQLITE_API double tdsqlite3_column_double(tdsqlite3_stmt*, int iCol); -SQLITE_API int tdsqlite3_column_int(tdsqlite3_stmt*, int iCol); -SQLITE_API tdsqlite3_int64 tdsqlite3_column_int64(tdsqlite3_stmt*, int iCol); -SQLITE_API const unsigned char *tdsqlite3_column_text(tdsqlite3_stmt*, int iCol); -SQLITE_API const void *tdsqlite3_column_text16(tdsqlite3_stmt*, int iCol); -SQLITE_API tdsqlite3_value *tdsqlite3_column_value(tdsqlite3_stmt*, int iCol); -SQLITE_API int tdsqlite3_column_bytes(tdsqlite3_stmt*, int iCol); -SQLITE_API int tdsqlite3_column_bytes16(tdsqlite3_stmt*, int iCol); -SQLITE_API int tdsqlite3_column_type(tdsqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object -** DESTRUCTOR: tdsqlite3_stmt +** DESTRUCTOR: sqlite3_stmt ** -** ^The tdsqlite3_finalize() function is called to delete a [prepared statement]. +** ^The sqlite3_finalize() function is called to delete a [prepared statement]. ** ^If the most recent evaluation of the statement encountered no errors -** or if the statement is never been evaluated, then tdsqlite3_finalize() returns +** or if the statement is never been evaluated, then sqlite3_finalize() returns ** SQLITE_OK. ^If the most recent evaluation of statement S failed, then -** tdsqlite3_finalize(S) returns the appropriate [error code] or +** sqlite3_finalize(S) returns the appropriate [error code] or ** [extended error code]. ** -** ^The tdsqlite3_finalize(S) routine can be called at any point during +** ^The sqlite3_finalize(S) routine can be called at any point during ** the life cycle of [prepared statement] S: ** before statement S is ever evaluated, after -** one or more calls to [tdsqlite3_reset()], or after any call -** to [tdsqlite3_step()] regardless of whether or not the statement has +** one or more calls to [sqlite3_reset()], or after any call +** to [sqlite3_step()] regardless of whether or not the statement has ** completed execution. ** -** ^Invoking tdsqlite3_finalize() on a NULL pointer is a harmless no-op. +** ^Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. ** ** The application must finalize every [prepared statement] in order to avoid ** resource leaks. It is a grievous error for the application to try to use @@ -5928,47 +5928,47 @@ SQLITE_API int tdsqlite3_column_type(tdsqlite3_stmt*, int iCol); ** statement after it has been finalized can result in undefined and ** undesirable behavior such as segfaults and heap corruption. */ -SQLITE_API int tdsqlite3_finalize(tdsqlite3_stmt *pStmt); +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); /* ** CAPI3REF: Reset A Prepared Statement Object -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** The tdsqlite3_reset() function is called to reset a [prepared statement] +** The sqlite3_reset() function is called to reset a [prepared statement] ** object back to its initial state, ready to be re-executed. ** ^Any SQL statement variables that had values bound to them using -** the [tdsqlite3_bind_blob | tdsqlite3_bind_*() API] retain their values. -** Use [tdsqlite3_clear_bindings()] to reset the bindings. +** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values. +** Use [sqlite3_clear_bindings()] to reset the bindings. ** -** ^The [tdsqlite3_reset(S)] interface resets the [prepared statement] S +** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S ** back to the beginning of its program. ** -** ^If the most recent call to [tdsqlite3_step(S)] for the +** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], -** or if [tdsqlite3_step(S)] has never before been called on S, -** then [tdsqlite3_reset(S)] returns [SQLITE_OK]. +** or if [sqlite3_step(S)] has never before been called on S, +** then [sqlite3_reset(S)] returns [SQLITE_OK]. ** -** ^If the most recent call to [tdsqlite3_step(S)] for the +** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S indicated an error, then -** [tdsqlite3_reset(S)] returns an appropriate [error code]. +** [sqlite3_reset(S)] returns an appropriate [error code]. ** -** ^The [tdsqlite3_reset(S)] interface does not change the values -** of any [tdsqlite3_bind_blob|bindings] on the [prepared statement] S. +** ^The [sqlite3_reset(S)] interface does not change the values +** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ -SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt); +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior ** of existing SQL functions or aggregates. The only differences between -** the three "tdsqlite3_create_function*" routines are the text encoding +** the three "sqlite3_create_function*" routines are the text encoding ** expected for the second parameter (the name of the function being ** created) and the presence or absence of a destructor callback for -** the application data pointer. Function tdsqlite3_create_window_function() +** the application data pointer. Function sqlite3_create_window_function() ** is similar, but allows the user to supply the extra callback functions ** needed by [aggregate window functions]. ** @@ -5988,7 +5988,7 @@ SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt); ** is the number of arguments that the SQL function or ** aggregate takes. ^If this parameter is -1, then the SQL function or ** aggregate may take any number of arguments between 0 and the limit -** set by [tdsqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third +** set by [sqlite3_limit]([SQLITE_LIMIT_FUNCTION_ARG]). If the third ** parameter is less than -1 or greater than 127 then the behavior is ** undefined. ** @@ -5996,9 +5996,9 @@ SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt); ** [SQLITE_UTF8 | text encoding] this SQL function prefers for ** its parameters. The application should set this parameter to ** [SQLITE_UTF16LE] if the function implementation invokes -** [tdsqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the -** implementation invokes [tdsqlite3_value_text16be()] on an input, or -** [SQLITE_UTF16] if [tdsqlite3_value_text16()] is used, or [SQLITE_UTF8] +** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the +** implementation invokes [sqlite3_value_text16be()] on an input, or +** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] ** otherwise. ^The same SQL function may be registered multiple times using ** different preferred text encodings, with different implementations for ** each encoding. @@ -6031,10 +6031,10 @@ SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt); ** ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the -** function can gain access to this pointer using [tdsqlite3_user_data()].)^ +** function can gain access to this pointer using [sqlite3_user_data()].)^ ** ** ^The sixth, seventh and eighth parameters passed to the three -** "tdsqlite3_create_function*" functions, xFunc, xStep and xFinal, are +** "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are ** pointers to C-language functions that implement the SQL function or ** aggregate. ^A scalar SQL function requires an implementation of the xFunc ** callback only; NULL pointers must be passed as the xStep and xFinal @@ -6044,7 +6044,7 @@ SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt); ** callbacks. ** ** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue -** and xInverse) passed to tdsqlite3_create_window_function are pointers to +** and xInverse) passed to sqlite3_create_window_function are pointers to ** C-language callbacks that implement the new function. xStep and xFinal ** must both be non-NULL. xValue and xInverse may either both be NULL, in ** which case a regular aggregate function is created, or must both be @@ -6053,14 +6053,14 @@ SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt); ** of aggregate window functions are ** [user-defined window functions|available here]. ** -** ^(If the final parameter to tdsqlite3_create_function_v2() or -** tdsqlite3_create_window_function() is not NULL, then it is destructor for +** ^(If the final parameter to sqlite3_create_function_v2() or +** sqlite3_create_window_function() is not NULL, then it is destructor for ** the application data pointer. The destructor is invoked when the function ** is deleted, either by being overloaded or when the database connection ** closes.)^ ^The destructor is also invoked if the call to -** tdsqlite3_create_function_v2() fails. ^When the destructor callback is +** sqlite3_create_function_v2() fails. ^When the destructor callback is ** invoked, it is passed a single argument which is a copy of the application -** data pointer which was the fifth parameter to tdsqlite3_create_function_v2(). +** data pointer which was the fifth parameter to sqlite3_create_function_v2(). ** ** ^It is permitted to register multiple implementations of the same ** functions with the same name but with either differing numbers of @@ -6082,47 +6082,47 @@ SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt); ** close the database connection nor finalize or reset the prepared ** statement in which the function is running. */ -SQLITE_API int tdsqlite3_create_function( - tdsqlite3 *db, +SQLITE_API int sqlite3_create_function( + sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*) + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) ); -SQLITE_API int tdsqlite3_create_function16( - tdsqlite3 *db, +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *pApp, - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*) + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) ); -SQLITE_API int tdsqlite3_create_function_v2( - tdsqlite3 *db, +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*), + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), void(*xDestroy)(void*) ); -SQLITE_API int tdsqlite3_create_window_function( - tdsqlite3 *db, +SQLITE_API int sqlite3_create_window_function( + sqlite3 *db, const char *zFunctionName, int nArg, int eTextRep, void *pApp, - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*), - void (*xValue)(tdsqlite3_context*), - void (*xInverse)(tdsqlite3_context*,int,tdsqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*) ); @@ -6137,15 +6137,15 @@ SQLITE_API int tdsqlite3_create_window_function( #define SQLITE_UTF16BE 3 /* IMP: R-51971-34154 */ #define SQLITE_UTF16 4 /* Use native byte order */ #define SQLITE_ANY 5 /* Deprecated */ -#define SQLITE_UTF16_ALIGNED 8 /* tdsqlite3_create_collation only */ +#define SQLITE_UTF16_ALIGNED 8 /* sqlite3_create_collation only */ /* ** CAPI3REF: Function Flags ** ** These constants may be ORed together with the ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument -** to [tdsqlite3_create_function()], [tdsqlite3_create_function16()], or -** [tdsqlite3_create_function_v2()]. +** to [sqlite3_create_function()], [sqlite3_create_function16()], or +** [sqlite3_create_function_v2()]. ** **
    ** [[SQLITE_DETERMINISTIC]]
    SQLITE_DETERMINISTIC
    @@ -6195,12 +6195,12 @@ SQLITE_API int tdsqlite3_create_window_function( ** ** [[SQLITE_SUBTYPE]]
    SQLITE_SUBTYPE
    ** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call -** [tdsqlite3_value_subtype()] to inspect the sub-types of its arguments. +** [sqlite3_value_subtype()] to inspect the sub-types of its arguments. ** Specifying this flag makes no difference for scalar or aggregate user ** functions. However, if it is not specified for a user-defined window ** function, then any sub-types belonging to arguments passed to the window ** function may be discarded before the window function is called (i.e. -** tdsqlite3_value_subtype() will always return 0). +** sqlite3_value_subtype() will always return 0). **
    **
    */ @@ -6220,87 +6220,87 @@ SQLITE_API int tdsqlite3_create_window_function( ** these functions, we will not explain what they do. */ #ifndef SQLITE_OMIT_DEPRECATED -SQLITE_API SQLITE_DEPRECATED int tdsqlite3_aggregate_count(tdsqlite3_context*); -SQLITE_API SQLITE_DEPRECATED int tdsqlite3_expired(tdsqlite3_stmt*); -SQLITE_API SQLITE_DEPRECATED int tdsqlite3_transfer_bindings(tdsqlite3_stmt*, tdsqlite3_stmt*); -SQLITE_API SQLITE_DEPRECATED int tdsqlite3_global_recover(void); -SQLITE_API SQLITE_DEPRECATED void tdsqlite3_thread_cleanup(void); -SQLITE_API SQLITE_DEPRECATED int tdsqlite3_memory_alarm(void(*)(void*,tdsqlite3_int64,int), - void*,tdsqlite3_int64); +SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int), + void*,sqlite3_int64); #endif /* ** CAPI3REF: Obtaining SQL Values -** METHOD: tdsqlite3_value +** METHOD: sqlite3_value ** ** Summary: **
    -**
    tdsqlite3_value_blobBLOB value -**
    tdsqlite3_value_doubleREAL value -**
    tdsqlite3_value_int32-bit INTEGER value -**
    tdsqlite3_value_int6464-bit INTEGER value -**
    tdsqlite3_value_pointerPointer value -**
    tdsqlite3_value_textUTF-8 TEXT value -**
    tdsqlite3_value_text16UTF-16 TEXT value in +**
    sqlite3_value_blobBLOB value +**
    sqlite3_value_doubleREAL value +**
    sqlite3_value_int32-bit INTEGER value +**
    sqlite3_value_int6464-bit INTEGER value +**
    sqlite3_value_pointerPointer value +**
    sqlite3_value_textUTF-8 TEXT value +**
    sqlite3_value_text16UTF-16 TEXT value in ** the native byteorder -**
    tdsqlite3_value_text16beUTF-16be TEXT value -**
    tdsqlite3_value_text16leUTF-16le TEXT value +**
    sqlite3_value_text16beUTF-16be TEXT value +**
    sqlite3_value_text16leUTF-16le TEXT value **
        -**
    tdsqlite3_value_bytesSize of a BLOB +**
    sqlite3_value_bytesSize of a BLOB ** or a UTF-8 TEXT in bytes -**
    tdsqlite3_value_bytes16   +**
    sqlite3_value_bytes16   ** →  Size of UTF-16 ** TEXT in bytes -**
    tdsqlite3_value_typeDefault +**
    sqlite3_value_typeDefault ** datatype of the value -**
    tdsqlite3_value_numeric_type   +**
    sqlite3_value_numeric_type   ** →  Best numeric datatype of the value -**
    tdsqlite3_value_nochange   +**
    sqlite3_value_nochange   ** →  True if the column is unchanged in an UPDATE ** against a virtual table. -**
    tdsqlite3_value_frombind   +**
    sqlite3_value_frombind   ** →  True if value originated from a [bound parameter] **
    ** ** Details: ** ** These routines extract type, size, and content information from -** [protected tdsqlite3_value] objects. Protected tdsqlite3_value objects +** [protected sqlite3_value] objects. Protected sqlite3_value objects ** are used to pass parameter information into the functions that ** implement [application-defined SQL functions] and [virtual tables]. ** -** These routines work only with [protected tdsqlite3_value] objects. -** Any attempt to use these routines on an [unprotected tdsqlite3_value] +** These routines work only with [protected sqlite3_value] objects. +** Any attempt to use these routines on an [unprotected sqlite3_value] ** is not threadsafe. ** ** ^These routines work just like the corresponding [column access functions] -** except that these routines take a single [protected tdsqlite3_value] object -** pointer instead of a [tdsqlite3_stmt*] pointer and an integer column number. +** except that these routines take a single [protected sqlite3_value] object +** pointer instead of a [sqlite3_stmt*] pointer and an integer column number. ** -** ^The tdsqlite3_value_text16() interface extracts a UTF-16 string +** ^The sqlite3_value_text16() interface extracts a UTF-16 string ** in the native byte-order of the host machine. ^The -** tdsqlite3_value_text16be() and tdsqlite3_value_text16le() interfaces +** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** -** ^If [tdsqlite3_value] object V was initialized -** using [tdsqlite3_bind_pointer(S,I,P,X,D)] or [tdsqlite3_result_pointer(C,P,X,D)] +** ^If [sqlite3_value] object V was initialized +** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)] ** and if X and Y are strings that compare equal according to strcmp(X,Y), -** then tdsqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, -** tdsqlite3_value_pointer(V,Y) returns a NULL. The tdsqlite3_bind_pointer() +** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, +** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** -** ^(The tdsqlite3_value_type(V) interface returns the +** ^(The sqlite3_value_type(V) interface returns the ** [SQLITE_INTEGER | datatype code] for the initial datatype of the -** [tdsqlite3_value] object V. The returned value is one of [SQLITE_INTEGER], +** [sqlite3_value] object V. The returned value is one of [SQLITE_INTEGER], ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].)^ -** Other interfaces might change the datatype for an tdsqlite3_value object. +** Other interfaces might change the datatype for an sqlite3_value object. ** For example, if the datatype is initially SQLITE_INTEGER and -** tdsqlite3_value_text(V) is called to extract a text value for that -** integer, then subsequent calls to tdsqlite3_value_type(V) might return +** sqlite3_value_text(V) is called to extract a text value for that +** integer, then subsequent calls to sqlite3_value_type(V) might return ** SQLITE_TEXT. Whether or not a persistent internal datatype conversion ** occurs is undefined and may change from one release of SQLite to the next. ** -** ^(The tdsqlite3_value_numeric_type() interface attempts to apply +** ^(The sqlite3_value_numeric_type() interface attempts to apply ** numeric affinity to the value. This means that an attempt is ** made to convert the value to an integer or floating point. If ** such a conversion is possible without loss of information (in other @@ -6309,31 +6309,31 @@ SQLITE_API SQLITE_DEPRECATED int tdsqlite3_memory_alarm(void(*)(void*,tdsqlite3_ ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^ ** ** ^Within the [xUpdate] method of a [virtual table], the -** tdsqlite3_value_nochange(X) interface returns true if and only if +** sqlite3_value_nochange(X) interface returns true if and only if ** the column corresponding to X is unchanged by the UPDATE operation ** that the xUpdate method call was invoked to implement and if ** and the prior [xColumn] method call that was invoked to extracted ** the value for that column returned without setting a result (probably -** because it queried [tdsqlite3_vtab_nochange()] and found that the column +** because it queried [sqlite3_vtab_nochange()] and found that the column ** was unchanging). ^Within an [xUpdate] method, any value for which -** tdsqlite3_value_nochange(X) is true will in all other respects appear -** to be a NULL value. If tdsqlite3_value_nochange(X) is invoked anywhere other +** sqlite3_value_nochange(X) is true will in all other respects appear +** to be a NULL value. If sqlite3_value_nochange(X) is invoked anywhere other ** than within an [xUpdate] method call for an UPDATE statement, then ** the return value is arbitrary and meaningless. ** -** ^The tdsqlite3_value_frombind(X) interface returns non-zero if the -** value X originated from one of the [tdsqlite3_bind_int|tdsqlite3_bind()] +** ^The sqlite3_value_frombind(X) interface returns non-zero if the +** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()] ** interfaces. ^If X comes from an SQL literal value, or a table column, -** or an expression, then tdsqlite3_value_frombind(X) returns zero. +** or an expression, then sqlite3_value_frombind(X) returns zero. ** ** Please pay particular attention to the fact that the pointer returned -** from [tdsqlite3_value_blob()], [tdsqlite3_value_text()], or -** [tdsqlite3_value_text16()] can be invalidated by a subsequent call to -** [tdsqlite3_value_bytes()], [tdsqlite3_value_bytes16()], [tdsqlite3_value_text()], -** or [tdsqlite3_value_text16()]. +** from [sqlite3_value_blob()], [sqlite3_value_text()], or +** [sqlite3_value_text16()] can be invalidated by a subsequent call to +** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()], +** or [sqlite3_value_text16()]. ** ** These routines must be called from the same thread as -** the SQL function that supplied the [tdsqlite3_value*] parameters. +** the SQL function that supplied the [sqlite3_value*] parameters. ** ** As long as the input parameter is correct, these routines can only ** fail if an out-of-memory error occurs during a format conversion. @@ -6341,142 +6341,142 @@ SQLITE_API SQLITE_DEPRECATED int tdsqlite3_memory_alarm(void(*)(void*,tdsqlite3_ ** errors: ** **
      -**
    • tdsqlite3_value_blob() -**
    • tdsqlite3_value_text() -**
    • tdsqlite3_value_text16() -**
    • tdsqlite3_value_text16le() -**
    • tdsqlite3_value_text16be() -**
    • tdsqlite3_value_bytes() -**
    • tdsqlite3_value_bytes16() +**
    • sqlite3_value_blob() +**
    • sqlite3_value_text() +**
    • sqlite3_value_text16() +**
    • sqlite3_value_text16le() +**
    • sqlite3_value_text16be() +**
    • sqlite3_value_bytes() +**
    • sqlite3_value_bytes16() **
    ** ** If an out-of-memory error occurs, then the return value from these ** routines is the same as if the column had contained an SQL NULL value. ** Valid SQL NULL returns can be distinguished from out-of-memory errors -** by invoking the [tdsqlite3_errcode()] immediately after the suspect +** by invoking the [sqlite3_errcode()] immediately after the suspect ** return value is obtained and before any ** other SQLite interface is called on the same [database connection]. */ -SQLITE_API const void *tdsqlite3_value_blob(tdsqlite3_value*); -SQLITE_API double tdsqlite3_value_double(tdsqlite3_value*); -SQLITE_API int tdsqlite3_value_int(tdsqlite3_value*); -SQLITE_API tdsqlite3_int64 tdsqlite3_value_int64(tdsqlite3_value*); -SQLITE_API void *tdsqlite3_value_pointer(tdsqlite3_value*, const char*); -SQLITE_API const unsigned char *tdsqlite3_value_text(tdsqlite3_value*); -SQLITE_API const void *tdsqlite3_value_text16(tdsqlite3_value*); -SQLITE_API const void *tdsqlite3_value_text16le(tdsqlite3_value*); -SQLITE_API const void *tdsqlite3_value_text16be(tdsqlite3_value*); -SQLITE_API int tdsqlite3_value_bytes(tdsqlite3_value*); -SQLITE_API int tdsqlite3_value_bytes16(tdsqlite3_value*); -SQLITE_API int tdsqlite3_value_type(tdsqlite3_value*); -SQLITE_API int tdsqlite3_value_numeric_type(tdsqlite3_value*); -SQLITE_API int tdsqlite3_value_nochange(tdsqlite3_value*); -SQLITE_API int tdsqlite3_value_frombind(tdsqlite3_value*); +SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); +SQLITE_API double sqlite3_value_double(sqlite3_value*); +SQLITE_API int sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API void *sqlite3_value_pointer(sqlite3_value*, const char*); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API int sqlite3_value_type(sqlite3_value*); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); +SQLITE_API int sqlite3_value_nochange(sqlite3_value*); +SQLITE_API int sqlite3_value_frombind(sqlite3_value*); /* ** CAPI3REF: Finding The Subtype Of SQL Values -** METHOD: tdsqlite3_value +** METHOD: sqlite3_value ** -** The tdsqlite3_value_subtype(V) function returns the subtype for +** The sqlite3_value_subtype(V) function returns the subtype for ** an [application-defined SQL function] argument V. The subtype ** information can be used to pass a limited amount of context from -** one SQL function to another. Use the [tdsqlite3_result_subtype()] +** one SQL function to another. Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function. */ -SQLITE_API unsigned int tdsqlite3_value_subtype(tdsqlite3_value*); +SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); /* ** CAPI3REF: Copy And Free SQL Values -** METHOD: tdsqlite3_value +** METHOD: sqlite3_value ** -** ^The tdsqlite3_value_dup(V) interface makes a copy of the [tdsqlite3_value] -** object D and returns a pointer to that copy. ^The [tdsqlite3_value] returned -** is a [protected tdsqlite3_value] object even if the input is not. -** ^The tdsqlite3_value_dup(V) interface returns NULL if V is NULL or if a +** ^The sqlite3_value_dup(V) interface makes a copy of the [sqlite3_value] +** object D and returns a pointer to that copy. ^The [sqlite3_value] returned +** is a [protected sqlite3_value] object even if the input is not. +** ^The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a ** memory allocation fails. ** -** ^The tdsqlite3_value_free(V) interface frees an [tdsqlite3_value] object -** previously obtained from [tdsqlite3_value_dup()]. ^If V is a NULL pointer -** then tdsqlite3_value_free(V) is a harmless no-op. +** ^The sqlite3_value_free(V) interface frees an [sqlite3_value] object +** previously obtained from [sqlite3_value_dup()]. ^If V is a NULL pointer +** then sqlite3_value_free(V) is a harmless no-op. */ -SQLITE_API tdsqlite3_value *tdsqlite3_value_dup(const tdsqlite3_value*); -SQLITE_API void tdsqlite3_value_free(tdsqlite3_value*); +SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value*); +SQLITE_API void sqlite3_value_free(sqlite3_value*); /* ** CAPI3REF: Obtain Aggregate Function Context -** METHOD: tdsqlite3_context +** METHOD: sqlite3_context ** ** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. ** -** ^The first time the tdsqlite3_aggregate_context(C,N) routine is called +** ^The first time the sqlite3_aggregate_context(C,N) routine is called ** for a particular aggregate function, SQLite allocates ** N bytes of memory, zeroes out that memory, and returns a pointer ** to the new memory. ^On second and subsequent calls to -** tdsqlite3_aggregate_context() for the same aggregate function instance, +** sqlite3_aggregate_context() for the same aggregate function instance, ** the same buffer is returned. Sqlite3_aggregate_context() is normally ** called once for each invocation of the xStep callback and then one ** last time when the xFinal callback is invoked. ^(When no rows match ** an aggregate query, the xStep() callback of the aggregate function ** implementation is never called and xFinal() is called exactly once. -** In those cases, tdsqlite3_aggregate_context() might be called for the +** In those cases, sqlite3_aggregate_context() might be called for the ** first time from within xFinal().)^ ** -** ^The tdsqlite3_aggregate_context(C,N) routine returns a NULL pointer +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory ** allocate error occurs. ** -** ^(The amount of space allocated by tdsqlite3_aggregate_context(C,N) is +** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is ** determined by the N parameter on first successful call. Changing the -** value of N in any subsequents call to tdsqlite3_aggregate_context() within +** value of N in any subsequents call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set -** N=0 in calls to tdsqlite3_aggregate_context(C,N) so that no +** N=0 in calls to sqlite3_aggregate_context(C,N) so that no ** pointless memory allocations occur. ** ** ^SQLite automatically frees the memory allocated by -** tdsqlite3_aggregate_context() when the aggregate query concludes. +** sqlite3_aggregate_context() when the aggregate query concludes. ** ** The first parameter must be a copy of the -** [tdsqlite3_context | SQL function context] that is the first parameter +** [sqlite3_context | SQL function context] that is the first parameter ** to the xStep or xFinal callback routine that implements the aggregate ** function. ** ** This routine must be called from the same thread in which ** the aggregate SQL function is running. */ -SQLITE_API void *tdsqlite3_aggregate_context(tdsqlite3_context*, int nBytes); +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* ** CAPI3REF: User Data For Functions -** METHOD: tdsqlite3_context +** METHOD: sqlite3_context ** -** ^The tdsqlite3_user_data() interface returns a copy of +** ^The sqlite3_user_data() interface returns a copy of ** the pointer that was the pUserData parameter (the 5th parameter) -** of the [tdsqlite3_create_function()] -** and [tdsqlite3_create_function16()] routines that originally +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. ** ** This routine must be called from the same thread in which ** the application-defined function is running. */ -SQLITE_API void *tdsqlite3_user_data(tdsqlite3_context*); +SQLITE_API void *sqlite3_user_data(sqlite3_context*); /* ** CAPI3REF: Database Connection For Functions -** METHOD: tdsqlite3_context +** METHOD: sqlite3_context ** -** ^The tdsqlite3_context_db_handle() interface returns a copy of +** ^The sqlite3_context_db_handle() interface returns a copy of ** the pointer to the [database connection] (the 1st parameter) -** of the [tdsqlite3_create_function()] -** and [tdsqlite3_create_function16()] routines that originally +** of the [sqlite3_create_function()] +** and [sqlite3_create_function16()] routines that originally ** registered the application defined function. */ -SQLITE_API tdsqlite3 *tdsqlite3_context_db_handle(tdsqlite3_context*); +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data -** METHOD: tdsqlite3_context +** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to ** associate metadata with argument values. If the same value is passed to @@ -6489,36 +6489,36 @@ SQLITE_API tdsqlite3 *tdsqlite3_context_db_handle(tdsqlite3_context*); ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The tdsqlite3_get_auxdata(C,N) interface returns a pointer to the metadata -** associated by the tdsqlite3_set_auxdata(C,N,P,X) function with the Nth argument +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata +** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument ** value to the application-defined function. ^N is zero for the left-most ** function argument. ^If there is no metadata -** associated with the function argument, the tdsqlite3_get_auxdata(C,N) interface +** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** -** ^The tdsqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th ** argument of the application-defined function. ^Subsequent -** calls to tdsqlite3_get_auxdata(C,N) return P from the most recent -** tdsqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or +** calls to sqlite3_get_auxdata(C,N) return P from the most recent +** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or ** NULL if the metadata has been discarded. -** ^After each call to tdsqlite3_set_auxdata(C,N,P,X) where X is not NULL, +** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly ** once, when the metadata is discarded. ** SQLite is free to discard the metadata at any time, including:
      **
    • ^(when the corresponding function parameter changes)^, or -**
    • ^(when [tdsqlite3_reset()] or [tdsqlite3_finalize()] is called for the +**
    • ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or -**
    • ^(when tdsqlite3_set_auxdata() is invoked again on the same +**
    • ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or -**
    • ^(during the original tdsqlite3_set_auxdata() call when a memory +**
    • ^(during the original sqlite3_set_auxdata() call when a memory ** allocation error occurs.)^
    ** ** Note the last bullet in particular. The destructor X in -** tdsqlite3_set_auxdata(C,N,P,X) might be called immediately, before the -** tdsqlite3_set_auxdata() interface even returns. Hence tdsqlite3_set_auxdata() +** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the +** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after -** tdsqlite3_set_auxdata() has been called. +** sqlite3_set_auxdata() has been called. ** ** ^(In practice, metadata is preserved between function calls for ** function parameters that are compile-time constants, including literal @@ -6531,15 +6531,15 @@ SQLITE_API tdsqlite3 *tdsqlite3_context_db_handle(tdsqlite3_context*); ** These routines must be called from the same thread in which ** the SQL function is running. */ -SQLITE_API void *tdsqlite3_get_auxdata(tdsqlite3_context*, int N); -SQLITE_API void tdsqlite3_set_auxdata(tdsqlite3_context*, int N, void*, void (*)(void*)); +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); /* ** CAPI3REF: Constants Defining Special Destructor Behavior ** ** These are special values for the destructor that is passed in as the -** final argument to routines like [tdsqlite3_result_blob()]. ^If the destructor +** final argument to routines like [sqlite3_result_blob()]. ^If the destructor ** argument is SQLITE_STATIC, it means that the content pointer is constant ** and will never change. It does not need to be destroyed. ^The ** SQLITE_TRANSIENT value means that the content will likely change in @@ -6549,89 +6549,89 @@ SQLITE_API void tdsqlite3_set_auxdata(tdsqlite3_context*, int N, void*, void (*) ** The typedef is necessary to work around problems in certain ** C++ compilers. */ -typedef void (*tdsqlite3_destructor_type)(void*); -#define SQLITE_STATIC ((tdsqlite3_destructor_type)0) -#define SQLITE_TRANSIENT ((tdsqlite3_destructor_type)-1) +typedef void (*sqlite3_destructor_type)(void*); +#define SQLITE_STATIC ((sqlite3_destructor_type)0) +#define SQLITE_TRANSIENT ((sqlite3_destructor_type)-1) /* ** CAPI3REF: Setting The Result Of An SQL Function -** METHOD: tdsqlite3_context +** METHOD: sqlite3_context ** ** These routines are used by the xFunc or xFinal callbacks that ** implement SQL functions and aggregates. See -** [tdsqlite3_create_function()] and [tdsqlite3_create_function16()] +** [sqlite3_create_function()] and [sqlite3_create_function16()] ** for additional information. ** ** These functions work very much like the [parameter binding] family of ** functions used to bind values to host parameters in prepared statements. ** Refer to the [SQL parameter] documentation for additional information. ** -** ^The tdsqlite3_result_blob() interface sets the result from +** ^The sqlite3_result_blob() interface sets the result from ** an application-defined function to be the BLOB whose content is pointed ** to by the second parameter and which is N bytes long where N is the ** third parameter. ** -** ^The tdsqlite3_result_zeroblob(C,N) and tdsqlite3_result_zeroblob64(C,N) +** ^The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N) ** interfaces set the result of the application-defined function to be ** a BLOB containing all zero bytes and N bytes in size. ** -** ^The tdsqlite3_result_double() interface sets the result from +** ^The sqlite3_result_double() interface sets the result from ** an application-defined function to be a floating point value specified ** by its 2nd argument. ** -** ^The tdsqlite3_result_error() and tdsqlite3_result_error16() functions +** ^The sqlite3_result_error() and sqlite3_result_error16() functions ** cause the implemented SQL function to throw an exception. ** ^SQLite uses the string pointed to by the -** 2nd parameter of tdsqlite3_result_error() or tdsqlite3_result_error16() +** 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() ** as the text of an error message. ^SQLite interprets the error -** message string from tdsqlite3_result_error() as UTF-8. ^SQLite -** interprets the string from tdsqlite3_result_error16() as UTF-16 in native -** byte order. ^If the third parameter to tdsqlite3_result_error() -** or tdsqlite3_result_error16() is negative then SQLite takes as the error +** message string from sqlite3_result_error() as UTF-8. ^SQLite +** interprets the string from sqlite3_result_error16() as UTF-16 in native +** byte order. ^If the third parameter to sqlite3_result_error() +** or sqlite3_result_error16() is negative then SQLite takes as the error ** message all text up through the first zero character. -** ^If the third parameter to tdsqlite3_result_error() or -** tdsqlite3_result_error16() is non-negative then SQLite takes that many +** ^If the third parameter to sqlite3_result_error() or +** sqlite3_result_error16() is non-negative then SQLite takes that many ** bytes (not characters) from the 2nd parameter as the error message. -** ^The tdsqlite3_result_error() and tdsqlite3_result_error16() +** ^The sqlite3_result_error() and sqlite3_result_error16() ** routines make a private copy of the error message text before ** they return. Hence, the calling function can deallocate or ** modify the text after they return without harm. -** ^The tdsqlite3_result_error_code() function changes the error code +** ^The sqlite3_result_error_code() function changes the error code ** returned by SQLite as a result of an error in a function. ^By default, -** the error code is SQLITE_ERROR. ^A subsequent call to tdsqlite3_result_error() -** or tdsqlite3_result_error16() resets the error code to SQLITE_ERROR. +** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() +** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. ** -** ^The tdsqlite3_result_error_toobig() interface causes SQLite to throw an +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an ** error indicating that a string or BLOB is too long to represent. ** -** ^The tdsqlite3_result_error_nomem() interface causes SQLite to throw an +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an ** error indicating that a memory allocation failed. ** -** ^The tdsqlite3_result_int() interface sets the return value +** ^The sqlite3_result_int() interface sets the return value ** of the application-defined function to be the 32-bit signed integer ** value given in the 2nd argument. -** ^The tdsqlite3_result_int64() interface sets the return value +** ^The sqlite3_result_int64() interface sets the return value ** of the application-defined function to be the 64-bit signed integer ** value given in the 2nd argument. ** -** ^The tdsqlite3_result_null() interface sets the return value +** ^The sqlite3_result_null() interface sets the return value ** of the application-defined function to be NULL. ** -** ^The tdsqlite3_result_text(), tdsqlite3_result_text16(), -** tdsqlite3_result_text16le(), and tdsqlite3_result_text16be() interfaces +** ^The sqlite3_result_text(), sqlite3_result_text16(), +** sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces ** set the return value of the application-defined function to be ** a text string which is represented as UTF-8, UTF-16 native byte order, ** UTF-16 little endian, or UTF-16 big endian, respectively. -** ^The tdsqlite3_result_text64() interface sets the return value of an +** ^The sqlite3_result_text64() interface sets the return value of an ** application-defined function to be a text string in an encoding ** specified by the fifth (and last) parameter, which must be one ** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE]. ** ^SQLite takes the text result from the application from -** the 2nd parameter of the tdsqlite3_result_text* interfaces. -** ^If the 3rd parameter to the tdsqlite3_result_text* interfaces +** the 2nd parameter of the sqlite3_result_text* interfaces. +** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is negative, then SQLite takes result text from the 2nd parameter ** through the first zero character. -** ^If the 3rd parameter to the tdsqlite3_result_text* interfaces +** ^If the 3rd parameter to the sqlite3_result_text* interfaces ** is non-negative, then as many bytes (not characters) of the text ** pointed to by the 2nd parameter are taken as the application-defined ** function result. If the 3rd parameter is non-negative, then it @@ -6640,94 +6640,94 @@ typedef void (*tdsqlite3_destructor_type)(void*); ** in the string at a byte offset that is less than the value of the 3rd ** parameter, then the resulting string will contain embedded NULs and the ** result of expressions operating on strings with embedded NULs is undefined. -** ^If the 4th parameter to the tdsqlite3_result_text* interfaces -** or tdsqlite3_result_blob is a non-NULL pointer, then SQLite calls that +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or BLOB result when it has ** finished using that result. -** ^If the 4th parameter to the tdsqlite3_result_text* interfaces or to -** tdsqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite +** ^If the 4th parameter to the sqlite3_result_text* interfaces or to +** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite ** assumes that the text or BLOB result is in constant space and does not ** copy the content of the parameter nor call a destructor on the content ** when it has finished using that result. -** ^If the 4th parameter to the tdsqlite3_result_text* interfaces -** or tdsqlite3_result_blob is the special constant SQLITE_TRANSIENT +** ^If the 4th parameter to the sqlite3_result_text* interfaces +** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT ** then SQLite makes a copy of the result into space obtained -** from [tdsqlite3_malloc()] before it returns. +** from [sqlite3_malloc()] before it returns. ** -** ^The tdsqlite3_result_value() interface sets the result of +** ^The sqlite3_result_value() interface sets the result of ** the application-defined function to be a copy of the -** [unprotected tdsqlite3_value] object specified by the 2nd parameter. ^The -** tdsqlite3_result_value() interface makes a copy of the [tdsqlite3_value] -** so that the [tdsqlite3_value] specified in the parameter may change or -** be deallocated after tdsqlite3_result_value() returns without harm. -** ^A [protected tdsqlite3_value] object may always be used where an -** [unprotected tdsqlite3_value] object is required, so either -** kind of [tdsqlite3_value] object can be used with this interface. -** -** ^The tdsqlite3_result_pointer(C,P,T,D) interface sets the result to an -** SQL NULL value, just like [tdsqlite3_result_null(C)], except that it +** [unprotected sqlite3_value] object specified by the 2nd parameter. ^The +** sqlite3_result_value() interface makes a copy of the [sqlite3_value] +** so that the [sqlite3_value] specified in the parameter may change or +** be deallocated after sqlite3_result_value() returns without harm. +** ^A [protected sqlite3_value] object may always be used where an +** [unprotected sqlite3_value] object is required, so either +** kind of [sqlite3_value] object can be used with this interface. +** +** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an +** SQL NULL value, just like [sqlite3_result_null(C)], except that it ** also associates the host-language pointer P or type T with that ** NULL value such that the pointer can be retrieved within an -** [application-defined SQL function] using [tdsqlite3_value_pointer()]. +** [application-defined SQL function] using [sqlite3_value_pointer()]. ** ^If the D parameter is not NULL, then it is a pointer to a destructor ** for the P parameter. ^SQLite invokes D with P as its only argument ** when SQLite is finished with P. The T parameter should be a static -** string and preferably a string literal. The tdsqlite3_result_pointer() +** string and preferably a string literal. The sqlite3_result_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** ** If these routines are called from within the different thread ** than the one containing the application-defined function that received -** the [tdsqlite3_context] pointer, the results are undefined. -*/ -SQLITE_API void tdsqlite3_result_blob(tdsqlite3_context*, const void*, int, void(*)(void*)); -SQLITE_API void tdsqlite3_result_blob64(tdsqlite3_context*,const void*, - tdsqlite3_uint64,void(*)(void*)); -SQLITE_API void tdsqlite3_result_double(tdsqlite3_context*, double); -SQLITE_API void tdsqlite3_result_error(tdsqlite3_context*, const char*, int); -SQLITE_API void tdsqlite3_result_error16(tdsqlite3_context*, const void*, int); -SQLITE_API void tdsqlite3_result_error_toobig(tdsqlite3_context*); -SQLITE_API void tdsqlite3_result_error_nomem(tdsqlite3_context*); -SQLITE_API void tdsqlite3_result_error_code(tdsqlite3_context*, int); -SQLITE_API void tdsqlite3_result_int(tdsqlite3_context*, int); -SQLITE_API void tdsqlite3_result_int64(tdsqlite3_context*, tdsqlite3_int64); -SQLITE_API void tdsqlite3_result_null(tdsqlite3_context*); -SQLITE_API void tdsqlite3_result_text(tdsqlite3_context*, const char*, int, void(*)(void*)); -SQLITE_API void tdsqlite3_result_text64(tdsqlite3_context*, const char*,tdsqlite3_uint64, +** the [sqlite3_context] pointer, the results are undefined. +*/ +SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_blob64(sqlite3_context*,const void*, + sqlite3_uint64,void(*)(void*)); +SQLITE_API void sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void sqlite3_result_null(sqlite3_context*); +SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text64(sqlite3_context*, const char*,sqlite3_uint64, void(*)(void*), unsigned char encoding); -SQLITE_API void tdsqlite3_result_text16(tdsqlite3_context*, const void*, int, void(*)(void*)); -SQLITE_API void tdsqlite3_result_text16le(tdsqlite3_context*, const void*, int,void(*)(void*)); -SQLITE_API void tdsqlite3_result_text16be(tdsqlite3_context*, const void*, int,void(*)(void*)); -SQLITE_API void tdsqlite3_result_value(tdsqlite3_context*, tdsqlite3_value*); -SQLITE_API void tdsqlite3_result_pointer(tdsqlite3_context*, void*,const char*,void(*)(void*)); -SQLITE_API void tdsqlite3_result_zeroblob(tdsqlite3_context*, int n); -SQLITE_API int tdsqlite3_result_zeroblob64(tdsqlite3_context*, tdsqlite3_uint64 n); +SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_pointer(sqlite3_context*, void*,const char*,void(*)(void*)); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); +SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context*, sqlite3_uint64 n); /* ** CAPI3REF: Setting The Subtype Of An SQL Function -** METHOD: tdsqlite3_context +** METHOD: sqlite3_context ** -** The tdsqlite3_result_subtype(C,T) function causes the subtype of +** The sqlite3_result_subtype(C,T) function causes the subtype of ** the result from the [application-defined SQL function] with -** [tdsqlite3_context] C to be the value T. Only the lower 8 bits +** [sqlite3_context] C to be the value T. Only the lower 8 bits ** of the subtype T are preserved in current versions of SQLite; ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite. */ -SQLITE_API void tdsqlite3_result_subtype(tdsqlite3_context*,unsigned int); +SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); /* ** CAPI3REF: Define New Collating Sequences -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^These functions add, remove, or modify a [collation] associated ** with the [database connection] specified as the first argument. ** ** ^The name of the collation is a UTF-8 string -** for tdsqlite3_create_collation() and tdsqlite3_create_collation_v2() -** and a UTF-16 string in native byte order for tdsqlite3_create_collation16(). -** ^Collation names that compare equal according to [tdsqlite3_strnicmp()] are +** for sqlite3_create_collation() and sqlite3_create_collation_v2() +** and a UTF-16 string in native byte order for sqlite3_create_collation16(). +** ^Collation names that compare equal according to [sqlite3_strnicmp()] are ** considered to be the same name. ** ** ^(The third argument (eTextRep) must be one of the constants: @@ -6780,41 +6780,41 @@ SQLITE_API void tdsqlite3_result_subtype(tdsqlite3_context*,unsigned int); ** collating function is registered and used, then the behavior of SQLite ** is undefined. ** -** ^The tdsqlite3_create_collation_v2() works like tdsqlite3_create_collation() +** ^The sqlite3_create_collation_v2() works like sqlite3_create_collation() ** with the addition that the xDestroy callback is invoked on pArg when ** the collating function is deleted. ** ^Collating functions are deleted when they are overridden by later ** calls to the collation creation functions or when the -** [database connection] is closed using [tdsqlite3_close()]. +** [database connection] is closed using [sqlite3_close()]. ** ** ^The xDestroy callback is not called if the -** tdsqlite3_create_collation_v2() function fails. Applications that invoke -** tdsqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** sqlite3_create_collation_v2() function fails. Applications that invoke +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should ** check the return code and dispose of the application data pointer ** themselves rather than expecting SQLite to deal with it for them. ** This is different from every other SQLite interface. The inconsistency ** is unfortunate but cannot be changed without breaking backwards ** compatibility. ** -** See also: [tdsqlite3_collation_needed()] and [tdsqlite3_collation_needed16()]. +** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ -SQLITE_API int tdsqlite3_create_collation( - tdsqlite3*, +SQLITE_API int sqlite3_create_collation( + sqlite3*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); -SQLITE_API int tdsqlite3_create_collation_v2( - tdsqlite3*, +SQLITE_API int sqlite3_create_collation_v2( + sqlite3*, const char *zName, int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDestroy)(void*) ); -SQLITE_API int tdsqlite3_create_collation16( - tdsqlite3*, +SQLITE_API int sqlite3_create_collation16( + sqlite3*, const void *zName, int eTextRep, void *pArg, @@ -6823,56 +6823,56 @@ SQLITE_API int tdsqlite3_create_collation16( /* ** CAPI3REF: Collation Needed Callbacks -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^To avoid having to register all collation sequences before a database ** can be used, a single callback function may be registered with the ** [database connection] to be invoked whenever an undefined collation ** sequence is required. ** -** ^If the function is registered using the tdsqlite3_collation_needed() API, +** ^If the function is registered using the sqlite3_collation_needed() API, ** then it is passed the names of undefined collation sequences as strings -** encoded in UTF-8. ^If tdsqlite3_collation_needed16() is used, +** encoded in UTF-8. ^If sqlite3_collation_needed16() is used, ** the names are passed as UTF-16 in machine native byte order. ** ^A call to either function replaces the existing collation-needed callback. ** ** ^(When the callback is invoked, the first argument passed is a copy -** of the second argument to tdsqlite3_collation_needed() or -** tdsqlite3_collation_needed16(). The second argument is the database +** of the second argument to sqlite3_collation_needed() or +** sqlite3_collation_needed16(). The second argument is the database ** connection. The third argument is one of [SQLITE_UTF8], [SQLITE_UTF16BE], ** or [SQLITE_UTF16LE], indicating the most desirable form of the collation ** sequence function required. The fourth parameter is the name of the ** required collation sequence.)^ ** ** The callback function should register the desired collation using -** [tdsqlite3_create_collation()], [tdsqlite3_create_collation16()], or -** [tdsqlite3_create_collation_v2()]. +** [sqlite3_create_collation()], [sqlite3_create_collation16()], or +** [sqlite3_create_collation_v2()]. */ -SQLITE_API int tdsqlite3_collation_needed( - tdsqlite3*, +SQLITE_API int sqlite3_collation_needed( + sqlite3*, void*, - void(*)(void*,tdsqlite3*,int eTextRep,const char*) + void(*)(void*,sqlite3*,int eTextRep,const char*) ); -SQLITE_API int tdsqlite3_collation_needed16( - tdsqlite3*, +SQLITE_API int sqlite3_collation_needed16( + sqlite3*, void*, - void(*)(void*,tdsqlite3*,int eTextRep,const void*) + void(*)(void*,sqlite3*,int eTextRep,const void*) ); #ifdef SQLITE_HAS_CODEC /* ** Specify the key for an encrypted database. This routine should be -** called right after tdsqlite3_open(). +** called right after sqlite3_open(). ** ** The code to implement this API is not available in the public release ** of SQLite. */ -SQLITE_API int tdsqlite3_key( - tdsqlite3 *db, /* Database to be rekeyed */ +SQLITE_API int sqlite3_key( + sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The key */ ); -SQLITE_API int tdsqlite3_key_v2( - tdsqlite3 *db, /* Database to be rekeyed */ +SQLITE_API int sqlite3_key_v2( + sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The key */ ); @@ -6901,12 +6901,12 @@ SQLITE_API int tdsqlite3_key_v2( END SQLCIPHER */ -SQLITE_API int tdsqlite3_rekey( - tdsqlite3 *db, /* Database to be rekeyed */ +SQLITE_API int sqlite3_rekey( + sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The new key */ ); -SQLITE_API int tdsqlite3_rekey_v2( - tdsqlite3 *db, /* Database to be rekeyed */ +SQLITE_API int sqlite3_rekey_v2( + sqlite3 *db, /* Database to be rekeyed */ const char *zDbName, /* Name of the database */ const void *pKey, int nKey /* The new key */ ); @@ -6915,7 +6915,7 @@ SQLITE_API int tdsqlite3_rekey_v2( ** Specify the activation key for a SEE database. Unless ** activated, none of the SEE routines will work. */ -SQLITE_API void tdsqlite3_activate_see( +SQLITE_API void sqlite3_activate_see( const char *zPassPhrase /* Activation phrase */ ); #endif @@ -6925,7 +6925,7 @@ SQLITE_API void tdsqlite3_activate_see( ** Specify the activation key for a CEROD database. Unless ** activated, none of the CEROD routines will work. */ -SQLITE_API void tdsqlite3_activate_cerod( +SQLITE_API void sqlite3_activate_cerod( const char *zPassPhrase /* Activation phrase */ ); #endif @@ -6933,7 +6933,7 @@ SQLITE_API void tdsqlite3_activate_cerod( /* ** CAPI3REF: Suspend Execution For A Short Time ** -** The tdsqlite3_sleep() function causes the current thread to suspend execution +** The sqlite3_sleep() function causes the current thread to suspend execution ** for at least a number of milliseconds specified in its parameter. ** ** If the operating system does not support sleep requests with @@ -6942,19 +6942,19 @@ SQLITE_API void tdsqlite3_activate_cerod( ** requested from the operating system is returned. ** ** ^SQLite implements this interface by calling the xSleep() -** method of the default [tdsqlite3_vfs] object. If the xSleep() method +** method of the default [sqlite3_vfs] object. If the xSleep() method ** of the default VFS is not implemented correctly, or not implemented at -** all, then the behavior of tdsqlite3_sleep() may deviate from the description +** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs. */ -SQLITE_API int tdsqlite3_sleep(int); +SQLITE_API int sqlite3_sleep(int); /* ** CAPI3REF: Name Of The Folder Holding Temporary Files ** ** ^(If this global variable is made to point to a string which is ** the name of a folder (a.k.a. directory), then all temporary files -** created by SQLite when using a built-in [tdsqlite3_vfs | VFS] +** created by SQLite when using a built-in [sqlite3_vfs | VFS] ** will be placed in that directory.)^ ^If this variable ** is a NULL pointer, then SQLite performs a search for an appropriate ** temporary file directory. @@ -6976,22 +6976,22 @@ SQLITE_API int tdsqlite3_sleep(int); ** thereafter. ** ** ^The [temp_store_directory pragma] may modify this variable and cause -** it to point to memory obtained from [tdsqlite3_malloc]. ^Furthermore, +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, ** the [temp_store_directory pragma] always assumes that any string ** that this variable points to is held in memory obtained from -** [tdsqlite3_malloc] and the pragma may attempt to free that memory -** using [tdsqlite3_free]. +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. ** Hence, if this variable is modified directly, either it should be -** made NULL or made to point to memory obtained from [tdsqlite3_malloc] +** made NULL or made to point to memory obtained from [sqlite3_malloc] ** or else the use of the [temp_store_directory pragma] should be avoided. ** Except when requested by the [temp_store_directory pragma], SQLite -** does not free the memory that tdsqlite3_temp_directory points to. If +** does not free the memory that sqlite3_temp_directory points to. If ** the application wants that memory to be freed, it must do ** so itself, taking care to only do so after all [database connection] ** objects have been destroyed. ** ** Note to Windows Runtime users: The temporary directory must be set -** prior to calling [tdsqlite3_open] or [tdsqlite3_open_v2]. Otherwise, various +** prior to calling [sqlite3_open] or [sqlite3_open_v2]. Otherwise, various ** features that require the use of temporary files may fail. Here is an ** example of how to do this using C++ with the Windows Runtime: ** @@ -7002,10 +7002,10 @@ SQLITE_API int tdsqlite3_sleep(int); ** memset(zPathBuf, 0, sizeof(zPathBuf)); ** WideCharToMultiByte(CP_UTF8, 0, zPath, -1, zPathBuf, sizeof(zPathBuf), **   NULL, NULL); -** tdsqlite3_temp_directory = tdsqlite3_mprintf("%s", zPathBuf); +** sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf); ** */ -SQLITE_API char *tdsqlite3_temp_directory; +SQLITE_API char *sqlite3_temp_directory; /* ** CAPI3REF: Name Of The Folder Holding Database Files @@ -7013,7 +7013,7 @@ SQLITE_API char *tdsqlite3_temp_directory; ** ^(If this global variable is made to point to a string which is ** the name of a folder (a.k.a. directory), then all database files ** specified with a relative pathname and created or accessed by -** SQLite when using a built-in windows [tdsqlite3_vfs | VFS] will be assumed +** SQLite when using a built-in windows [sqlite3_vfs | VFS] will be assumed ** to be relative to that directory.)^ ^If this variable is a NULL ** pointer, then SQLite assumes that all database files specified ** with a relative pathname are relative to the current directory @@ -7033,48 +7033,48 @@ SQLITE_API char *tdsqlite3_temp_directory; ** thereafter. ** ** ^The [data_store_directory pragma] may modify this variable and cause -** it to point to memory obtained from [tdsqlite3_malloc]. ^Furthermore, +** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, ** the [data_store_directory pragma] always assumes that any string ** that this variable points to is held in memory obtained from -** [tdsqlite3_malloc] and the pragma may attempt to free that memory -** using [tdsqlite3_free]. +** [sqlite3_malloc] and the pragma may attempt to free that memory +** using [sqlite3_free]. ** Hence, if this variable is modified directly, either it should be -** made NULL or made to point to memory obtained from [tdsqlite3_malloc] +** made NULL or made to point to memory obtained from [sqlite3_malloc] ** or else the use of the [data_store_directory pragma] should be avoided. */ -SQLITE_API char *tdsqlite3_data_directory; +SQLITE_API char *sqlite3_data_directory; /* ** CAPI3REF: Win32 Specific Interface ** ** These interfaces are available only on Windows. The -** [tdsqlite3_win32_set_directory] interface is used to set the value associated -** with the [tdsqlite3_temp_directory] or [tdsqlite3_data_directory] variable, to +** [sqlite3_win32_set_directory] interface is used to set the value associated +** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to ** zValue, depending on the value of the type parameter. The zValue parameter -** should be NULL to cause the previous value to be freed via [tdsqlite3_free]; -** a non-NULL value will be copied into memory obtained from [tdsqlite3_malloc] -** prior to being used. The [tdsqlite3_win32_set_directory] interface returns +** should be NULL to cause the previous value to be freed via [sqlite3_free]; +** a non-NULL value will be copied into memory obtained from [sqlite3_malloc] +** prior to being used. The [sqlite3_win32_set_directory] interface returns ** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported, ** or [SQLITE_NOMEM] if memory could not be allocated. The value of the -** [tdsqlite3_data_directory] variable is intended to act as a replacement for +** [sqlite3_data_directory] variable is intended to act as a replacement for ** the current directory on the sub-platforms of Win32 where that concept is -** not present, e.g. WinRT and UWP. The [tdsqlite3_win32_set_directory8] and -** [tdsqlite3_win32_set_directory16] interfaces behave exactly the same as the -** tdsqlite3_win32_set_directory interface except the string parameter must be +** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and +** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the +** sqlite3_win32_set_directory interface except the string parameter must be ** UTF-8 or UTF-16, respectively. */ -SQLITE_API int tdsqlite3_win32_set_directory( +SQLITE_API int sqlite3_win32_set_directory( unsigned long type, /* Identifier for directory being set or reset */ void *zValue /* New value for directory being set or reset */ ); -SQLITE_API int tdsqlite3_win32_set_directory8(unsigned long type, const char *zValue); -SQLITE_API int tdsqlite3_win32_set_directory16(unsigned long type, const void *zValue); +SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue); +SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue); /* ** CAPI3REF: Win32 Directory Types ** ** These macros are only available on Windows. They define the allowed values -** for the type argument to the [tdsqlite3_win32_set_directory] interface. +** for the type argument to the [sqlite3_win32_set_directory] interface. */ #define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1 #define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2 @@ -7082,9 +7082,9 @@ SQLITE_API int tdsqlite3_win32_set_directory16(unsigned long type, const void *z /* ** CAPI3REF: Test For Auto-Commit Mode ** KEYWORDS: {autocommit mode} -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_get_autocommit() interface returns non-zero or +** ^The sqlite3_get_autocommit() interface returns non-zero or ** zero if the given database connection is or is not in autocommit mode, ** respectively. ^Autocommit mode is on by default. ** ^Autocommit mode is disabled by a [BEGIN] statement. @@ -7101,26 +7101,26 @@ SQLITE_API int tdsqlite3_win32_set_directory16(unsigned long type, const void *z ** connection while this routine is running, then the return value ** is undefined. */ -SQLITE_API int tdsqlite3_get_autocommit(tdsqlite3*); +SQLITE_API int sqlite3_get_autocommit(sqlite3*); /* ** CAPI3REF: Find The Database Handle Of A Prepared Statement -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^The tdsqlite3_db_handle interface returns the [database connection] handle +** ^The sqlite3_db_handle interface returns the [database connection] handle ** to which a [prepared statement] belongs. ^The [database connection] -** returned by tdsqlite3_db_handle is the same [database connection] +** returned by sqlite3_db_handle is the same [database connection] ** that was the first argument -** to the [tdsqlite3_prepare_v2()] call (or its variants) that was used to +** to the [sqlite3_prepare_v2()] call (or its variants) that was used to ** create the statement in the first place. */ -SQLITE_API tdsqlite3 *tdsqlite3_db_handle(tdsqlite3_stmt*); +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Return The Filename For A Database Connection -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_db_filename(D,N) interface returns a pointer to the filename +** ^The sqlite3_db_filename(D,N) interface returns a pointer to the filename ** associated with database N of connection D. ** ^If there is no attached database N on the database ** connection D, or if database N is a temporary or in-memory database, then @@ -7138,29 +7138,29 @@ SQLITE_API tdsqlite3 *tdsqlite3_db_handle(tdsqlite3_stmt*); ** If the filename pointer returned by this routine is not NULL, then it ** can be used as the filename input parameter to these routines: **
      -**
    • [tdsqlite3_uri_parameter()] -**
    • [tdsqlite3_uri_boolean()] -**
    • [tdsqlite3_uri_int64()] -**
    • [tdsqlite3_filename_database()] -**
    • [tdsqlite3_filename_journal()] -**
    • [tdsqlite3_filename_wal()] +**
    • [sqlite3_uri_parameter()] +**
    • [sqlite3_uri_boolean()] +**
    • [sqlite3_uri_int64()] +**
    • [sqlite3_filename_database()] +**
    • [sqlite3_filename_journal()] +**
    • [sqlite3_filename_wal()] **
    */ -SQLITE_API const char *tdsqlite3_db_filename(tdsqlite3 *db, const char *zDbName); +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Determine if a database is read-only -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_db_readonly(D,N) interface returns 1 if the database N +** ^The sqlite3_db_readonly(D,N) interface returns 1 if the database N ** of connection D is read-only, 0 if it is read/write, or -1 if N is not ** the name of a database on connection D. */ -SQLITE_API int tdsqlite3_db_readonly(tdsqlite3 *db, const char *zDbName); +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName); /* ** CAPI3REF: Find the next prepared statement -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^This interface returns a pointer to the next [prepared statement] after ** pStmt associated with the [database connection] pDb. ^If pStmt is NULL @@ -7169,28 +7169,28 @@ SQLITE_API int tdsqlite3_db_readonly(tdsqlite3 *db, const char *zDbName); ** satisfies the conditions of this routine, it returns NULL. ** ** The [database connection] pointer D in a call to -** [tdsqlite3_next_stmt(D,S)] must refer to an open database +** [sqlite3_next_stmt(D,S)] must refer to an open database ** connection and in particular must not be a NULL pointer. */ -SQLITE_API tdsqlite3_stmt *tdsqlite3_next_stmt(tdsqlite3 *pDb, tdsqlite3_stmt *pStmt); +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); /* ** CAPI3REF: Commit And Rollback Notification Callbacks -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_commit_hook() interface registers a callback +** ^The sqlite3_commit_hook() interface registers a callback ** function to be invoked whenever a transaction is [COMMIT | committed]. -** ^Any callback set by a previous call to tdsqlite3_commit_hook() +** ^Any callback set by a previous call to sqlite3_commit_hook() ** for the same database connection is overridden. -** ^The tdsqlite3_rollback_hook() interface registers a callback +** ^The sqlite3_rollback_hook() interface registers a callback ** function to be invoked whenever a transaction is [ROLLBACK | rolled back]. -** ^Any callback set by a previous call to tdsqlite3_rollback_hook() +** ^Any callback set by a previous call to sqlite3_rollback_hook() ** for the same database connection is overridden. ** ^The pArg argument is passed through to the callback. ** ^If the callback on a commit hook function returns non-zero, ** then the commit is converted into a rollback. ** -** ^The tdsqlite3_commit_hook(D,C,P) and tdsqlite3_rollback_hook(D,C,P) functions +** ^The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions ** return the P argument from the previous call of the same function ** on the same [database connection] D, or NULL for ** the first call for each function on D. @@ -7199,10 +7199,10 @@ SQLITE_API tdsqlite3_stmt *tdsqlite3_next_stmt(tdsqlite3 *pDb, tdsqlite3_stmt *p ** The callback implementation must not do anything that will modify ** the database connection that invoked the callback. Any actions ** to modify the database connection must be deferred until after the -** completion of the [tdsqlite3_step()] call that triggered the commit +** completion of the [sqlite3_step()] call that triggered the commit ** or rollback hook in the first place. ** Note that running any other SQL statements, including SELECT statements, -** or merely calling [tdsqlite3_prepare_v2()] and [tdsqlite3_step()] will modify +** or merely calling [sqlite3_prepare_v2()] and [sqlite3_step()] will modify ** the database connections for the meaning of "modify" in this paragraph. ** ** ^Registering a NULL function disables the callback. @@ -7219,16 +7219,16 @@ SQLITE_API tdsqlite3_stmt *tdsqlite3_next_stmt(tdsqlite3 *pDb, tdsqlite3_stmt *p ** ^The rollback callback is not invoked if a transaction is ** automatically rolled back because the database connection is closed. ** -** See also the [tdsqlite3_update_hook()] interface. +** See also the [sqlite3_update_hook()] interface. */ -SQLITE_API void *tdsqlite3_commit_hook(tdsqlite3*, int(*)(void*), void*); -SQLITE_API void *tdsqlite3_rollback_hook(tdsqlite3*, void(*)(void *), void*); +SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_update_hook() interface registers a callback function +** ^The sqlite3_update_hook() interface registers a callback function ** with the [database connection] identified by the first argument ** to be invoked whenever a row is updated, inserted or deleted in ** a [rowid table]. @@ -7238,7 +7238,7 @@ SQLITE_API void *tdsqlite3_rollback_hook(tdsqlite3*, void(*)(void *), void*); ** ^The second argument is a pointer to the function to invoke when a ** row is updated, inserted or deleted in a rowid table. ** ^The first argument to the callback is a copy of the third argument -** to tdsqlite3_update_hook(). +** to sqlite3_update_hook(). ** ^The second callback argument is one of [SQLITE_INSERT], [SQLITE_DELETE], ** or [SQLITE_UPDATE], depending on the operation that caused the callback ** to be invoked. @@ -7261,21 +7261,21 @@ SQLITE_API void *tdsqlite3_rollback_hook(tdsqlite3*, void(*)(void *), void*); ** The update hook implementation must not do anything that will modify ** the database connection that invoked the update hook. Any actions ** to modify the database connection must be deferred until after the -** completion of the [tdsqlite3_step()] call that triggered the update hook. -** Note that [tdsqlite3_prepare_v2()] and [tdsqlite3_step()] both modify their +** completion of the [sqlite3_step()] call that triggered the update hook. +** Note that [sqlite3_prepare_v2()] and [sqlite3_step()] both modify their ** database connections for the meaning of "modify" in this paragraph. ** -** ^The tdsqlite3_update_hook(D,C,P) function +** ^The sqlite3_update_hook(D,C,P) function ** returns the P argument from the previous call ** on the same [database connection] D, or NULL for ** the first call on D. ** -** See also the [tdsqlite3_commit_hook()], [tdsqlite3_rollback_hook()], -** and [tdsqlite3_preupdate_hook()] interfaces. +** See also the [sqlite3_commit_hook()], [sqlite3_rollback_hook()], +** and [sqlite3_preupdate_hook()] interfaces. */ -SQLITE_API void *tdsqlite3_update_hook( - tdsqlite3*, - void(*)(void *,int ,char const *,char const *,tdsqlite3_int64), +SQLITE_API void *sqlite3_update_hook( + sqlite3*, + void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); @@ -7293,7 +7293,7 @@ SQLITE_API void *tdsqlite3_update_hook( ** sharing was enabled or disabled for each thread separately. ** ** ^(The cache sharing mode set by this interface effects all subsequent -** calls to [tdsqlite3_open()], [tdsqlite3_open_v2()], and [tdsqlite3_open16()]. +** calls to [sqlite3_open()], [sqlite3_open_v2()], and [sqlite3_open16()]. ** Existing database connections continue to use the sharing mode ** that was in effect at the time they were opened.)^ ** @@ -7305,50 +7305,50 @@ SQLITE_API void *tdsqlite3_update_hook( ** continues to be provided for historical compatibility, but its use is ** discouraged. Any use of shared cache is discouraged. If shared cache ** must be used, it is recommended that shared cache only be enabled for -** individual database connections using the [tdsqlite3_open_v2()] interface +** individual database connections using the [sqlite3_open_v2()] interface ** with the [SQLITE_OPEN_SHAREDCACHE] flag. ** ** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 ** and will always return SQLITE_MISUSE. On those systems, ** shared cache mode should be enabled per-database connection via -** [tdsqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. +** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. ** ** This interface is threadsafe on processors where writing a ** 32-bit integer is atomic. ** ** See Also: [SQLite Shared-Cache Mode] */ -SQLITE_API int tdsqlite3_enable_shared_cache(int); +SQLITE_API int sqlite3_enable_shared_cache(int); /* ** CAPI3REF: Attempt To Free Heap Memory ** -** ^The tdsqlite3_release_memory() interface attempts to free N bytes +** ^The sqlite3_release_memory() interface attempts to free N bytes ** of heap memory by deallocating non-essential memory allocations ** held by the database library. Memory used to cache database ** pages to improve performance is an example of non-essential memory. -** ^tdsqlite3_release_memory() returns the number of bytes actually freed, +** ^sqlite3_release_memory() returns the number of bytes actually freed, ** which might be more or less than the amount requested. -** ^The tdsqlite3_release_memory() routine is a no-op returning zero +** ^The sqlite3_release_memory() routine is a no-op returning zero ** if SQLite is not compiled with [SQLITE_ENABLE_MEMORY_MANAGEMENT]. ** -** See also: [tdsqlite3_db_release_memory()] +** See also: [sqlite3_db_release_memory()] */ -SQLITE_API int tdsqlite3_release_memory(int); +SQLITE_API int sqlite3_release_memory(int); /* ** CAPI3REF: Free Memory Used By A Database Connection -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_db_release_memory(D) interface attempts to free as much heap +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap ** memory as possible from database connection D. Unlike the -** [tdsqlite3_release_memory()] interface, this interface is in effect even +** [sqlite3_release_memory()] interface, this interface is in effect even ** when the [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is ** omitted. ** -** See also: [tdsqlite3_release_memory()] +** See also: [sqlite3_release_memory()] */ -SQLITE_API int tdsqlite3_db_release_memory(tdsqlite3*); +SQLITE_API int sqlite3_db_release_memory(sqlite3*); /* ** CAPI3REF: Impose A Limit On Heap Size @@ -7356,7 +7356,7 @@ SQLITE_API int tdsqlite3_db_release_memory(tdsqlite3*); ** These interfaces impose limits on the amount of heap memory that will be ** by all database connections within a single process. ** -** ^The tdsqlite3_soft_heap_limit64() interface sets and/or queries the +** ^The sqlite3_soft_heap_limit64() interface sets and/or queries the ** soft limit on the amount of heap memory that may be allocated by SQLite. ** ^SQLite strives to keep heap memory utilization below the soft heap ** limit by reducing the number of pages held in the page cache @@ -7366,30 +7366,30 @@ SQLITE_API int tdsqlite3_db_release_memory(tdsqlite3*); ** an [SQLITE_NOMEM] error. In other words, the soft heap limit ** is advisory only. ** -** ^The tdsqlite3_hard_heap_limit64(N) interface sets a hard upper bound of +** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of ** N bytes on the amount of memory that will be allocated. ^The -** tdsqlite3_hard_heap_limit64(N) interface is similar to -** tdsqlite3_soft_heap_limit64(N) except that memory allocations will fail +** sqlite3_hard_heap_limit64(N) interface is similar to +** sqlite3_soft_heap_limit64(N) except that memory allocations will fail ** when the hard heap limit is reached. ** -** ^The return value from both tdsqlite3_soft_heap_limit64() and -** tdsqlite3_hard_heap_limit64() is the size of +** ^The return value from both sqlite3_soft_heap_limit64() and +** sqlite3_hard_heap_limit64() is the size of ** the heap limit prior to the call, or negative in the case of an ** error. ^If the argument N is negative ** then no change is made to the heap limit. Hence, the current ** size of heap limits can be determined by invoking -** tdsqlite3_soft_heap_limit64(-1) or tdsqlite3_hard_heap_limit(-1). +** sqlite3_soft_heap_limit64(-1) or sqlite3_hard_heap_limit(-1). ** ** ^Setting the heap limits to zero disables the heap limiter mechanism. ** ** ^The soft heap limit may not be greater than the hard heap limit. -** ^If the hard heap limit is enabled and if tdsqlite3_soft_heap_limit(N) +** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) ** is invoked with a value of N that is greater than the hard heap limit, ** the the soft heap limit is set to the value of the hard heap limit. ** ^The soft heap limit is automatically enabled whenever the hard heap -** limit is enabled. ^When tdsqlite3_hard_heap_limit64(N) is invoked and +** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and ** the soft heap limit is outside the range of 1..N, then the soft heap -** limit is set to N. ^Invoking tdsqlite3_soft_heap_limit64(0) when the +** limit is set to N. ^Invoking sqlite3_soft_heap_limit64(0) when the ** hard heap limit is enabled makes the soft heap limit equal to the ** hard heap limit. ** @@ -7402,49 +7402,49 @@ SQLITE_API int tdsqlite3_db_release_memory(tdsqlite3*); **
      **
    • The limit value is set to zero. **
    • Memory accounting is disabled using a combination of the -** [tdsqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and +** [sqlite3_config]([SQLITE_CONFIG_MEMSTATUS],...) start-time option and ** the [SQLITE_DEFAULT_MEMSTATUS] compile-time option. **
    • An alternative page cache implementation is specified using -** [tdsqlite3_config]([SQLITE_CONFIG_PCACHE2],...). +** [sqlite3_config]([SQLITE_CONFIG_PCACHE2],...). **
    • The page cache allocates from its own memory pool supplied -** by [tdsqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than +** by [sqlite3_config]([SQLITE_CONFIG_PAGECACHE],...) rather than ** from the heap. **
    )^ ** ** The circumstances under which SQLite will enforce the heap limits may ** changes in future releases of SQLite. */ -SQLITE_API tdsqlite3_int64 tdsqlite3_soft_heap_limit64(tdsqlite3_int64 N); -SQLITE_API tdsqlite3_int64 tdsqlite3_hard_heap_limit64(tdsqlite3_int64 N); +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 N); +SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 N); /* ** CAPI3REF: Deprecated Soft Heap Limit Interface ** DEPRECATED ** -** This is a deprecated version of the [tdsqlite3_soft_heap_limit64()] +** This is a deprecated version of the [sqlite3_soft_heap_limit64()] ** interface. This routine is provided for historical compatibility ** only. All new applications should use the -** [tdsqlite3_soft_heap_limit64()] interface rather than this one. +** [sqlite3_soft_heap_limit64()] interface rather than this one. */ -SQLITE_API SQLITE_DEPRECATED void tdsqlite3_soft_heap_limit(int N); +SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N); /* ** CAPI3REF: Extract Metadata About A Column Of A Table -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^(The tdsqlite3_table_column_metadata(X,D,T,C,....) routine returns +** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns ** information about column C of table T in database D -** on [database connection] X.)^ ^The tdsqlite3_table_column_metadata() +** on [database connection] X.)^ ^The sqlite3_table_column_metadata() ** interface returns SQLITE_OK and fills in the non-NULL pointers in ** the final five arguments with appropriate values if the specified -** column exists. ^The tdsqlite3_table_column_metadata() interface returns +** column exists. ^The sqlite3_table_column_metadata() interface returns ** SQLITE_ERROR if the specified column does not exist. -** ^If the column-name parameter to tdsqlite3_table_column_metadata() is a +** ^If the column-name parameter to sqlite3_table_column_metadata() is a ** NULL pointer, then this routine simply checks for the existence of the ** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it ** does not. If the table name parameter T in a call to -** tdsqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is +** sqlite3_table_column_metadata(X,D,T,C,...) is NULL then the result is ** undefined behavior. ** ** ^The column is identified by the second, third and fourth parameters to @@ -7498,8 +7498,8 @@ SQLITE_API SQLITE_DEPRECATED void tdsqlite3_soft_heap_limit(int N); ** parsed, if that has not already been done, and returns an error if ** any errors are encountered while loading the schema. */ -SQLITE_API int tdsqlite3_table_column_metadata( - tdsqlite3 *db, /* Connection handle */ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ const char *zColumnName, /* Column name */ @@ -7512,11 +7512,11 @@ SQLITE_API int tdsqlite3_table_column_metadata( /* ** CAPI3REF: Load An Extension -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^This interface loads an SQLite extension library from the named file. ** -** ^The tdsqlite3_load_extension() interface attempts to load an +** ^The sqlite3_load_extension() interface attempts to load an ** [SQLite extension] library contained in the file zFile. If ** the file cannot be loaded directly, attempts are made to load ** with various operating-system specific extensions added. @@ -7526,36 +7526,36 @@ SQLITE_API int tdsqlite3_table_column_metadata( ** ** ^The entry point is zProc. ** ^(zProc may be 0, in which case SQLite will try to come up with an -** entry point name on its own. It first tries "tdsqlite3_extension_init". -** If that does not work, it constructs a name "tdsqlite3_X_init" where the +** entry point name on its own. It first tries "sqlite3_extension_init". +** If that does not work, it constructs a name "sqlite3_X_init" where the ** X is consists of the lower-case equivalent of all ASCII alphabetic ** characters in the filename from the last "/" to the first following ** "." and omitting any initial "lib".)^ -** ^The tdsqlite3_load_extension() interface returns +** ^The sqlite3_load_extension() interface returns ** [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong. ** ^If an error occurs and pzErrMsg is not 0, then the -** [tdsqlite3_load_extension()] interface shall attempt to +** [sqlite3_load_extension()] interface shall attempt to ** fill *pzErrMsg with error message text stored in memory -** obtained from [tdsqlite3_malloc()]. The calling function -** should free this memory by calling [tdsqlite3_free()]. +** obtained from [sqlite3_malloc()]. The calling function +** should free this memory by calling [sqlite3_free()]. ** ** ^Extension loading must be enabled using -** [tdsqlite3_enable_load_extension()] or -** [tdsqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL) +** [sqlite3_enable_load_extension()] or +** [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],1,NULL) ** prior to calling this API, ** otherwise an error will be returned. ** ** Security warning: It is recommended that the ** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this -** interface. The use of the [tdsqlite3_enable_load_extension()] interface +** interface. The use of the [sqlite3_enable_load_extension()] interface ** should be avoided. This will keep the SQL function [load_extension()] ** disabled and prevent SQL injections from giving attackers ** access to extension loading capabilities. ** ** See also the [load_extension() SQL function]. */ -SQLITE_API int tdsqlite3_load_extension( - tdsqlite3 *db, /* Load the extension into this database connection */ +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ char **pzErrMsg /* Put error message here if not 0 */ @@ -7563,21 +7563,21 @@ SQLITE_API int tdsqlite3_load_extension( /* ** CAPI3REF: Enable Or Disable Extension Loading -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^So as not to open security holes in older applications that are ** unprepared to deal with [extension loading], and as a means of disabling ** [extension loading] while evaluating user-entered SQL, the following API -** is provided to turn the [tdsqlite3_load_extension()] mechanism on and off. +** is provided to turn the [sqlite3_load_extension()] mechanism on and off. ** ** ^Extension loading is off by default. -** ^Call the tdsqlite3_enable_load_extension() routine with onoff==1 +** ^Call the sqlite3_enable_load_extension() routine with onoff==1 ** to turn extension loading on and call it with onoff==0 to turn ** it back off again. ** ** ^This interface enables or disables both the C-API -** [tdsqlite3_load_extension()] and the SQL function [load_extension()]. -** ^(Use [tdsqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..) +** [sqlite3_load_extension()] and the SQL function [load_extension()]. +** ^(Use [sqlite3_db_config](db,[SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION],..) ** to enable or disable only the C-API.)^ ** ** Security warning: It is recommended that extension loading @@ -7586,7 +7586,7 @@ SQLITE_API int tdsqlite3_load_extension( ** remains disabled. This will prevent SQL injections from giving attackers ** access to extension loading capabilities. */ -SQLITE_API int tdsqlite3_enable_load_extension(tdsqlite3 *db, int onoff); +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); /* ** CAPI3REF: Automatically Load Statically Linked Extensions @@ -7603,48 +7603,48 @@ SQLITE_API int tdsqlite3_enable_load_extension(tdsqlite3 *db, int onoff); ** **
     **    int xEntryPoint(
    -**      tdsqlite3 *db,
    +**      sqlite3 *db,
     **      const char **pzErrMsg,
    -**      const struct tdsqlite3_api_routines *pThunk
    +**      const struct sqlite3_api_routines *pThunk
     **    );
     ** 
    )^ ** ** If the xEntryPoint routine encounters an error, it should make *pzErrMsg -** point to an appropriate error message (obtained from [tdsqlite3_mprintf()]) +** point to an appropriate error message (obtained from [sqlite3_mprintf()]) ** and return an appropriate [error code]. ^SQLite ensures that *pzErrMsg ** is NULL before calling the xEntryPoint(). ^SQLite will invoke -** [tdsqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any -** xEntryPoint() returns an error, the [tdsqlite3_open()], [tdsqlite3_open16()], -** or [tdsqlite3_open_v2()] call that provoked the xEntryPoint() will fail. +** [sqlite3_free()] on *pzErrMsg after xEntryPoint() returns. ^If any +** xEntryPoint() returns an error, the [sqlite3_open()], [sqlite3_open16()], +** or [sqlite3_open_v2()] call that provoked the xEntryPoint() will fail. ** -** ^Calling tdsqlite3_auto_extension(X) with an entry point X that is already +** ^Calling sqlite3_auto_extension(X) with an entry point X that is already ** on the list of automatic extensions is a harmless no-op. ^No entry point ** will be called more than once for each database connection that is opened. ** -** See also: [tdsqlite3_reset_auto_extension()] -** and [tdsqlite3_cancel_auto_extension()] +** See also: [sqlite3_reset_auto_extension()] +** and [sqlite3_cancel_auto_extension()] */ -SQLITE_API int tdsqlite3_auto_extension(void(*xEntryPoint)(void)); +SQLITE_API int sqlite3_auto_extension(void(*xEntryPoint)(void)); /* ** CAPI3REF: Cancel Automatic Extension Loading ** -** ^The [tdsqlite3_cancel_auto_extension(X)] interface unregisters the +** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the ** initialization routine X that was registered using a prior call to -** [tdsqlite3_auto_extension(X)]. ^The [tdsqlite3_cancel_auto_extension(X)] +** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] ** routine returns 1 if initialization routine X was successfully ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ -SQLITE_API int tdsqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); +SQLITE_API int sqlite3_cancel_auto_extension(void(*xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading ** ** ^This interface disables all automatic extensions previously -** registered using [tdsqlite3_auto_extension()]. +** registered using [sqlite3_auto_extension()]. */ -SQLITE_API void tdsqlite3_reset_auto_extension(void); +SQLITE_API void sqlite3_reset_auto_extension(void); /* ** The interface to the virtual-table mechanism is currently considered @@ -7658,14 +7658,14 @@ SQLITE_API void tdsqlite3_reset_auto_extension(void); /* ** Structures used by the virtual table interface */ -typedef struct tdsqlite3_vtab tdsqlite3_vtab; -typedef struct tdsqlite3_index_info tdsqlite3_index_info; -typedef struct tdsqlite3_vtab_cursor tdsqlite3_vtab_cursor; -typedef struct tdsqlite3_module tdsqlite3_module; +typedef struct sqlite3_vtab sqlite3_vtab; +typedef struct sqlite3_index_info sqlite3_index_info; +typedef struct sqlite3_vtab_cursor sqlite3_vtab_cursor; +typedef struct sqlite3_module sqlite3_module; /* ** CAPI3REF: Virtual Table Object -** KEYWORDS: tdsqlite3_module {virtual table module} +** KEYWORDS: sqlite3_module {virtual table module} ** ** This structure, sometimes called a "virtual table module", ** defines the implementation of a [virtual table]. @@ -7673,45 +7673,45 @@ typedef struct tdsqlite3_module tdsqlite3_module; ** ** ^A virtual table module is created by filling in a persistent ** instance of this structure and passing a pointer to that instance -** to [tdsqlite3_create_module()] or [tdsqlite3_create_module_v2()]. +** to [sqlite3_create_module()] or [sqlite3_create_module_v2()]. ** ^The registration remains valid until it is replaced by a different ** module or until the [database connection] closes. The content ** of this structure must not change while it is registered with ** any database connection. */ -struct tdsqlite3_module { +struct sqlite3_module { int iVersion; - int (*xCreate)(tdsqlite3*, void *pAux, + int (*xCreate)(sqlite3*, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVTab, char**); - int (*xConnect)(tdsqlite3*, void *pAux, + sqlite3_vtab **ppVTab, char**); + int (*xConnect)(sqlite3*, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVTab, char**); - int (*xBestIndex)(tdsqlite3_vtab *pVTab, tdsqlite3_index_info*); - int (*xDisconnect)(tdsqlite3_vtab *pVTab); - int (*xDestroy)(tdsqlite3_vtab *pVTab); - int (*xOpen)(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCursor); - int (*xClose)(tdsqlite3_vtab_cursor*); - int (*xFilter)(tdsqlite3_vtab_cursor*, int idxNum, const char *idxStr, - int argc, tdsqlite3_value **argv); - int (*xNext)(tdsqlite3_vtab_cursor*); - int (*xEof)(tdsqlite3_vtab_cursor*); - int (*xColumn)(tdsqlite3_vtab_cursor*, tdsqlite3_context*, int); - int (*xRowid)(tdsqlite3_vtab_cursor*, tdsqlite3_int64 *pRowid); - int (*xUpdate)(tdsqlite3_vtab *, int, tdsqlite3_value **, tdsqlite3_int64 *); - int (*xBegin)(tdsqlite3_vtab *pVTab); - int (*xSync)(tdsqlite3_vtab *pVTab); - int (*xCommit)(tdsqlite3_vtab *pVTab); - int (*xRollback)(tdsqlite3_vtab *pVTab); - int (*xFindFunction)(tdsqlite3_vtab *pVtab, int nArg, const char *zName, - void (**pxFunc)(tdsqlite3_context*,int,tdsqlite3_value**), + sqlite3_vtab **ppVTab, char**); + int (*xBestIndex)(sqlite3_vtab *pVTab, sqlite3_index_info*); + int (*xDisconnect)(sqlite3_vtab *pVTab); + int (*xDestroy)(sqlite3_vtab *pVTab); + int (*xOpen)(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor); + int (*xClose)(sqlite3_vtab_cursor*); + int (*xFilter)(sqlite3_vtab_cursor*, int idxNum, const char *idxStr, + int argc, sqlite3_value **argv); + int (*xNext)(sqlite3_vtab_cursor*); + int (*xEof)(sqlite3_vtab_cursor*); + int (*xColumn)(sqlite3_vtab_cursor*, sqlite3_context*, int); + int (*xRowid)(sqlite3_vtab_cursor*, sqlite3_int64 *pRowid); + int (*xUpdate)(sqlite3_vtab *, int, sqlite3_value **, sqlite3_int64 *); + int (*xBegin)(sqlite3_vtab *pVTab); + int (*xSync)(sqlite3_vtab *pVTab); + int (*xCommit)(sqlite3_vtab *pVTab); + int (*xRollback)(sqlite3_vtab *pVTab); + int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg); - int (*xRename)(tdsqlite3_vtab *pVtab, const char *zNew); + int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); /* The methods above are in version 1 of the sqlite_module object. Those ** below are for version 2 and greater. */ - int (*xSavepoint)(tdsqlite3_vtab *pVTab, int); - int (*xRelease)(tdsqlite3_vtab *pVTab, int); - int (*xRollbackTo)(tdsqlite3_vtab *pVTab, int); + int (*xSavepoint)(sqlite3_vtab *pVTab, int); + int (*xRelease)(sqlite3_vtab *pVTab, int); + int (*xRollbackTo)(sqlite3_vtab *pVTab, int); /* The methods above are in versions 1 and 2 of the sqlite_module object. ** Those below are for version 3 and greater. */ int (*xShadowName)(const char*); @@ -7719,9 +7719,9 @@ struct tdsqlite3_module { /* ** CAPI3REF: Virtual Table Indexing Information -** KEYWORDS: tdsqlite3_index_info +** KEYWORDS: sqlite3_index_info ** -** The tdsqlite3_index_info structure and its substructures is used as part +** The sqlite3_index_info structure and its substructures is used as part ** of the [virtual table] interface to ** pass information into and receive the reply from the [xBestIndex] ** method of a [virtual table module]. The fields under **Inputs** are the @@ -7752,12 +7752,12 @@ struct tdsqlite3_module { ** The colUsed field indicates which columns of the virtual table may be ** required by the current scan. Virtual table columns are numbered from ** zero in the order in which they appear within the CREATE TABLE statement -** passed to tdsqlite3_declare_vtab(). For the first 63 columns (columns 0-62), +** passed to sqlite3_declare_vtab(). For the first 63 columns (columns 0-62), ** the corresponding bit is set within the colUsed mask if the column may be ** required by SQLite. If the table has at least 64 columns and any column ** to the right of the first 63 is required, then bit 63 of colUsed is also ** set. In other words, column iCol may be required if the expression -** (colUsed & ((tdsqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to +** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to ** non-zero. ** ** The [xBestIndex] method must fill aConstraintUsage[] with information @@ -7775,7 +7775,7 @@ struct tdsqlite3_module { ** ** ^The idxNum and idxPtr values are recorded and passed into the ** [xFilter] method. -** ^[tdsqlite3_free()] is used to free idxPtr if and only if +** ^[sqlite3_free()] is used to free idxPtr if and only if ** needToFreeIdxPtr is true. ** ** ^The orderByConsumed means that output from [xFilter]/[xNext] will occur in @@ -7806,56 +7806,56 @@ struct tdsqlite3_module { ** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by ** the xUpdate method are automatically rolled back by SQLite. ** -** IMPORTANT: The estimatedRows field was added to the tdsqlite3_index_info +** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info ** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). ** If a virtual table extension is ** used with an SQLite version earlier than 3.8.2, the results of attempting ** to read or write the estimatedRows field are undefined (but are likely ** to include crashing the application). The estimatedRows field should -** therefore only be used if [tdsqlite3_libversion_number()] returns a +** therefore only be used if [sqlite3_libversion_number()] returns a ** value greater than or equal to 3008002. Similarly, the idxFlags field ** was added for [version 3.9.0] ([dateof:3.9.0]). ** It may therefore only be used if -** tdsqlite3_libversion_number() returns a value greater than or equal to +** sqlite3_libversion_number() returns a value greater than or equal to ** 3009000. */ -struct tdsqlite3_index_info { +struct sqlite3_index_info { /* Inputs */ int nConstraint; /* Number of entries in aConstraint */ - struct tdsqlite3_index_constraint { + struct sqlite3_index_constraint { int iColumn; /* Column constrained. -1 for ROWID */ unsigned char op; /* Constraint operator */ unsigned char usable; /* True if this constraint is usable */ int iTermOffset; /* Used internally - xBestIndex should ignore */ } *aConstraint; /* Table of WHERE clause constraints */ int nOrderBy; /* Number of terms in the ORDER BY clause */ - struct tdsqlite3_index_orderby { + struct sqlite3_index_orderby { int iColumn; /* Column number */ unsigned char desc; /* True for DESC. False for ASC. */ } *aOrderBy; /* The ORDER BY clause */ /* Outputs */ - struct tdsqlite3_index_constraint_usage { + struct sqlite3_index_constraint_usage { int argvIndex; /* if >0, constraint is part of argv to xFilter */ unsigned char omit; /* Do not code a test for this constraint */ } *aConstraintUsage; int idxNum; /* Number used to identify the index */ - char *idxStr; /* String, possibly obtained from tdsqlite3_malloc */ - int needToFreeIdxStr; /* Free idxStr using tdsqlite3_free() if true */ + char *idxStr; /* String, possibly obtained from sqlite3_malloc */ + int needToFreeIdxStr; /* Free idxStr using sqlite3_free() if true */ int orderByConsumed; /* True if output is already ordered */ double estimatedCost; /* Estimated cost of using this index */ /* Fields below are only available in SQLite 3.8.2 and later */ - tdsqlite3_int64 estimatedRows; /* Estimated number of rows returned */ + sqlite3_int64 estimatedRows; /* Estimated number of rows returned */ /* Fields below are only available in SQLite 3.9.0 and later */ int idxFlags; /* Mask of SQLITE_INDEX_SCAN_* flags */ /* Fields below are only available in SQLite 3.10.0 and later */ - tdsqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */ + sqlite3_uint64 colUsed; /* Input: Mask of columns used by statement */ }; /* ** CAPI3REF: Virtual Table Scan Flags ** ** Virtual table implementations are allowed to set the -** [tdsqlite3_index_info].idxFlags field to some combination of +** [sqlite3_index_info].idxFlags field to some combination of ** these bits. */ #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ @@ -7864,7 +7864,7 @@ struct tdsqlite3_index_info { ** CAPI3REF: Virtual Table Constraint Operator Codes ** ** These macros define the allowed values for the -** [tdsqlite3_index_info].aConstraint[].op field. Each value represents +** [sqlite3_index_info].aConstraint[].op field. Each value represents ** an operator that is part of a constraint term in the wHERE clause of ** a query that uses a [virtual table]. */ @@ -7886,7 +7886,7 @@ struct tdsqlite3_index_info { /* ** CAPI3REF: Register A Virtual Table Implementation -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^These routines are used to register a new [virtual table module] name. ** ^Module names must be registered before @@ -7901,55 +7901,55 @@ struct tdsqlite3_index_info { ** into the [xCreate] and [xConnect] methods of the virtual table module ** when a new virtual table is be being created or reinitialized. ** -** ^The tdsqlite3_create_module_v2() interface has a fifth parameter which +** ^The sqlite3_create_module_v2() interface has a fifth parameter which ** is a pointer to a destructor for the pClientData. ^SQLite will ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. ^The destructor will also -** be invoked if the call to tdsqlite3_create_module_v2() fails. -** ^The tdsqlite3_create_module() -** interface is equivalent to tdsqlite3_create_module_v2() with a NULL +** be invoked if the call to sqlite3_create_module_v2() fails. +** ^The sqlite3_create_module() +** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. ** -** ^If the third parameter (the pointer to the tdsqlite3_module object) is +** ^If the third parameter (the pointer to the sqlite3_module object) is ** NULL then no new module is create and any existing modules with the ** same name are dropped. ** -** See also: [tdsqlite3_drop_modules()] +** See also: [sqlite3_drop_modules()] */ -SQLITE_API int tdsqlite3_create_module( - tdsqlite3 *db, /* SQLite connection to register module with */ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ - const tdsqlite3_module *p, /* Methods for the module */ + const sqlite3_module *p, /* Methods for the module */ void *pClientData /* Client data for xCreate/xConnect */ ); -SQLITE_API int tdsqlite3_create_module_v2( - tdsqlite3 *db, /* SQLite connection to register module with */ +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ - const tdsqlite3_module *p, /* Methods for the module */ + const sqlite3_module *p, /* Methods for the module */ void *pClientData, /* Client data for xCreate/xConnect */ void(*xDestroy)(void*) /* Module destructor function */ ); /* ** CAPI3REF: Remove Unnecessary Virtual Table Implementations -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The tdsqlite3_drop_modules(D,L) interface removes all virtual +** ^The sqlite3_drop_modules(D,L) interface removes all virtual ** table modules from database connection D except those named on list L. ** The L parameter must be either NULL or a pointer to an array of pointers ** to strings where the array is terminated by a single NULL pointer. ** ^If the L parameter is NULL, then all virtual table modules are removed. ** -** See also: [tdsqlite3_create_module()] +** See also: [sqlite3_create_module()] */ -SQLITE_API int tdsqlite3_drop_modules( - tdsqlite3 *db, /* Remove modules from this connection */ +SQLITE_API int sqlite3_drop_modules( + sqlite3 *db, /* Remove modules from this connection */ const char **azKeep /* Except, do not remove the ones named here */ ); /* ** CAPI3REF: Virtual Table Instance Object -** KEYWORDS: tdsqlite3_vtab +** KEYWORDS: sqlite3_vtab ** ** Every [virtual table module] implementation uses a subclass ** of this object to describe a particular instance @@ -7959,29 +7959,29 @@ SQLITE_API int tdsqlite3_drop_modules( ** common to all module implementations. ** ** ^Virtual tables methods can set an error message by assigning a -** string obtained from [tdsqlite3_mprintf()] to zErrMsg. The method should -** take care that any prior string is freed by a call to [tdsqlite3_free()] +** string obtained from [sqlite3_mprintf()] to zErrMsg. The method should +** take care that any prior string is freed by a call to [sqlite3_free()] ** prior to assigning a new string to zErrMsg. ^After the error message ** is delivered up to the client application, the string will be automatically -** freed by tdsqlite3_free() and the zErrMsg field will be zeroed. +** freed by sqlite3_free() and the zErrMsg field will be zeroed. */ -struct tdsqlite3_vtab { - const tdsqlite3_module *pModule; /* The module for this virtual table */ +struct sqlite3_vtab { + const sqlite3_module *pModule; /* The module for this virtual table */ int nRef; /* Number of open cursors */ - char *zErrMsg; /* Error message from tdsqlite3_mprintf() */ + char *zErrMsg; /* Error message from sqlite3_mprintf() */ /* Virtual table implementations will typically add additional fields */ }; /* ** CAPI3REF: Virtual Table Cursor Object -** KEYWORDS: tdsqlite3_vtab_cursor {virtual table cursor} +** KEYWORDS: sqlite3_vtab_cursor {virtual table cursor} ** ** Every [virtual table module] implementation uses a subclass of the ** following structure to describe cursors that point into the ** [virtual table] and are used ** to loop through the virtual table. Cursors are created using the -** [tdsqlite3_module.xOpen | xOpen] method of the module and are destroyed -** by the [tdsqlite3_module.xClose | xClose] method. Cursors are used +** [sqlite3_module.xOpen | xOpen] method of the module and are destroyed +** by the [sqlite3_module.xClose | xClose] method. Cursors are used ** by the [xFilter], [xNext], [xEof], [xColumn], and [xRowid] methods ** of the module. Each module implementation will define ** the content of a cursor structure to suit its own needs. @@ -7989,8 +7989,8 @@ struct tdsqlite3_vtab { ** This superclass exists in order to define fields of the cursor that ** are common to all implementations. */ -struct tdsqlite3_vtab_cursor { - tdsqlite3_vtab *pVtab; /* Virtual table of this cursor */ +struct sqlite3_vtab_cursor { + sqlite3_vtab *pVtab; /* Virtual table of this cursor */ /* Virtual table implementations will typically add additional fields */ }; @@ -8002,11 +8002,11 @@ struct tdsqlite3_vtab_cursor { ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ -SQLITE_API int tdsqlite3_declare_vtab(tdsqlite3*, const char *zSQL); +SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zSQL); /* ** CAPI3REF: Overload A Function For A Virtual Table -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^(Virtual tables can provide alternative implementations of functions ** using the [xFindFunction] method of the [virtual table module]. @@ -8021,7 +8021,7 @@ SQLITE_API int tdsqlite3_declare_vtab(tdsqlite3*, const char *zSQL); ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ -SQLITE_API int tdsqlite3_overload_function(tdsqlite3*, const char *zFuncName, int nArg); +SQLITE_API int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); /* ** The interface to the virtual-table mechanism defined above (back up @@ -8038,19 +8038,19 @@ SQLITE_API int tdsqlite3_overload_function(tdsqlite3*, const char *zFuncName, in ** KEYWORDS: {BLOB handle} {BLOB handles} ** ** An instance of this object represents an open BLOB on which -** [tdsqlite3_blob_open | incremental BLOB I/O] can be performed. -** ^Objects of this type are created by [tdsqlite3_blob_open()] -** and destroyed by [tdsqlite3_blob_close()]. -** ^The [tdsqlite3_blob_read()] and [tdsqlite3_blob_write()] interfaces +** [sqlite3_blob_open | incremental BLOB I/O] can be performed. +** ^Objects of this type are created by [sqlite3_blob_open()] +** and destroyed by [sqlite3_blob_close()]. +** ^The [sqlite3_blob_read()] and [sqlite3_blob_write()] interfaces ** can be used to read or write small subsections of the BLOB. -** ^The [tdsqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. +** ^The [sqlite3_blob_bytes()] interface returns the size of the BLOB in bytes. */ -typedef struct tdsqlite3_blob tdsqlite3_blob; +typedef struct sqlite3_blob sqlite3_blob; /* ** CAPI3REF: Open A BLOB For Incremental I/O -** METHOD: tdsqlite3 -** CONSTRUCTOR: tdsqlite3_blob +** METHOD: sqlite3 +** CONSTRUCTOR: sqlite3_blob ** ** ^(This interfaces opens a [BLOB handle | handle] to the BLOB located ** in row iRow, column zColumn, table zTable in database zDb; @@ -8073,7 +8073,7 @@ typedef struct tdsqlite3_blob tdsqlite3_blob; ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided -** the API is not misused, it is always safe to call [tdsqlite3_blob_close()] +** the API is not misused, it is always safe to call [sqlite3_blob_close()] ** on *ppBlob after this function it returns. ** ** This function fails with SQLITE_ERROR if any of the following are true: @@ -8094,12 +8094,12 @@ typedef struct tdsqlite3_blob tdsqlite3_blob; ** ** ^Unless it returns SQLITE_MISUSE, this function sets the ** [database connection] error code and message accessible via -** [tdsqlite3_errcode()] and [tdsqlite3_errmsg()] and related functions. +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** -** A BLOB referenced by tdsqlite3_blob_open() may be read using the -** [tdsqlite3_blob_read()] interface and modified by using -** [tdsqlite3_blob_write()]. The [BLOB handle] can be moved to a -** different row of the same table using the [tdsqlite3_blob_reopen()] +** A BLOB referenced by sqlite3_blob_open() may be read using the +** [sqlite3_blob_read()] interface and modified by using +** [sqlite3_blob_write()]. The [BLOB handle] can be moved to a +** different row of the same table using the [sqlite3_blob_reopen()] ** interface. However, the column, table, or database of a [BLOB handle] ** cannot be changed after the [BLOB handle] is opened. ** @@ -8108,41 +8108,41 @@ typedef struct tdsqlite3_blob tdsqlite3_blob; ** then the BLOB handle is marked as "expired". ** This is true if any column of the row is changed, even a column ** other than the one the BLOB handle is open on.)^ -** ^Calls to [tdsqlite3_blob_read()] and [tdsqlite3_blob_write()] for +** ^Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for ** an expired BLOB handle fail with a return code of [SQLITE_ABORT]. ** ^(Changes written into a BLOB prior to the BLOB expiring are not ** rolled back by the expiration of the BLOB. Such changes will eventually ** commit if the transaction continues to completion.)^ ** -** ^Use the [tdsqlite3_blob_bytes()] interface to determine the size of +** ^Use the [sqlite3_blob_bytes()] interface to determine the size of ** the opened blob. ^The size of a blob may not be changed by this ** interface. Use the [UPDATE] SQL command to change the size of a ** blob. ** -** ^The [tdsqlite3_bind_zeroblob()] and [tdsqlite3_result_zeroblob()] interfaces +** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces ** and the built-in [zeroblob] SQL function may be used to create a ** zero-filled blob to read or write using the incremental-blob interface. ** ** To avoid a resource leak, every open [BLOB handle] should eventually -** be released by a call to [tdsqlite3_blob_close()]. +** be released by a call to [sqlite3_blob_close()]. ** -** See also: [tdsqlite3_blob_close()], -** [tdsqlite3_blob_reopen()], [tdsqlite3_blob_read()], -** [tdsqlite3_blob_bytes()], [tdsqlite3_blob_write()]. +** See also: [sqlite3_blob_close()], +** [sqlite3_blob_reopen()], [sqlite3_blob_read()], +** [sqlite3_blob_bytes()], [sqlite3_blob_write()]. */ -SQLITE_API int tdsqlite3_blob_open( - tdsqlite3*, +SQLITE_API int sqlite3_blob_open( + sqlite3*, const char *zDb, const char *zTable, const char *zColumn, - tdsqlite3_int64 iRow, + sqlite3_int64 iRow, int flags, - tdsqlite3_blob **ppBlob + sqlite3_blob **ppBlob ); /* ** CAPI3REF: Move a BLOB Handle to a New Row -** METHOD: tdsqlite3_blob +** METHOD: sqlite3_blob ** ** ^This function is used to move an existing [BLOB handle] so that it points ** to a different row of the same database table. ^The new row is identified @@ -8151,23 +8151,23 @@ SQLITE_API int tdsqlite3_blob_open( ** remain the same. Moving an existing [BLOB handle] to a new row is ** faster than closing the existing handle and opening a new one. ** -** ^(The new row must meet the same criteria as for [tdsqlite3_blob_open()] - +** ^(The new row must meet the same criteria as for [sqlite3_blob_open()] - ** it must exist and there must be either a blob or text value stored in ** the nominated column.)^ ^If the new row is not present in the table, or if ** it does not contain a blob or text value, or if another error occurs, an ** SQLite error code is returned and the blob handle is considered aborted. -** ^All subsequent calls to [tdsqlite3_blob_read()], [tdsqlite3_blob_write()] or -** [tdsqlite3_blob_reopen()] on an aborted blob handle immediately return -** SQLITE_ABORT. ^Calling [tdsqlite3_blob_bytes()] on an aborted blob handle +** ^All subsequent calls to [sqlite3_blob_read()], [sqlite3_blob_write()] or +** [sqlite3_blob_reopen()] on an aborted blob handle immediately return +** SQLITE_ABORT. ^Calling [sqlite3_blob_bytes()] on an aborted blob handle ** always returns zero. ** ** ^This function sets the database handle error code and message. */ -SQLITE_API int tdsqlite3_blob_reopen(tdsqlite3_blob *, tdsqlite3_int64); +SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *, sqlite3_int64); /* ** CAPI3REF: Close A BLOB Handle -** DESTRUCTOR: tdsqlite3_blob +** DESTRUCTOR: sqlite3_blob ** ** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed ** unconditionally. Even if this routine returns an error code, the @@ -8182,15 +8182,15 @@ SQLITE_API int tdsqlite3_blob_reopen(tdsqlite3_blob *, tdsqlite3_int64); ** Calling this function with an argument that is not a NULL pointer or an ** open blob handle results in undefined behaviour. ^Calling this routine ** with a null pointer (such as would be returned by a failed call to -** [tdsqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function +** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function ** is passed a valid open blob handle, the values returned by the -** tdsqlite3_errcode() and tdsqlite3_errmsg() functions are set before returning. +** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. */ -SQLITE_API int tdsqlite3_blob_close(tdsqlite3_blob *); +SQLITE_API int sqlite3_blob_close(sqlite3_blob *); /* ** CAPI3REF: Return The Size Of An Open BLOB -** METHOD: tdsqlite3_blob +** METHOD: sqlite3_blob ** ** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The @@ -8198,15 +8198,15 @@ SQLITE_API int tdsqlite3_blob_close(tdsqlite3_blob *); ** blob content; they cannot change the size of a blob. ** ** This routine only works on a [BLOB handle] which has been created -** by a prior successful call to [tdsqlite3_blob_open()] and which has not -** been closed by [tdsqlite3_blob_close()]. Passing any other pointer in +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. */ -SQLITE_API int tdsqlite3_blob_bytes(tdsqlite3_blob *); +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); /* ** CAPI3REF: Read Data From A BLOB Incrementally -** METHOD: tdsqlite3_blob +** METHOD: sqlite3_blob ** ** ^(This function is used to read data from an open [BLOB handle] into a ** caller-supplied buffer. N bytes of data are copied into buffer Z @@ -8216,39 +8216,39 @@ SQLITE_API int tdsqlite3_blob_bytes(tdsqlite3_blob *); ** [SQLITE_ERROR] is returned and no data is read. ^If N or iOffset is ** less than zero, [SQLITE_ERROR] is returned and no data is read. ** ^The size of the blob (and hence the maximum value of N+iOffset) -** can be determined using the [tdsqlite3_blob_bytes()] interface. +** can be determined using the [sqlite3_blob_bytes()] interface. ** ** ^An attempt to read from an expired [BLOB handle] fails with an ** error code of [SQLITE_ABORT]. ** -** ^(On success, tdsqlite3_blob_read() returns SQLITE_OK. +** ^(On success, sqlite3_blob_read() returns SQLITE_OK. ** Otherwise, an [error code] or an [extended error code] is returned.)^ ** ** This routine only works on a [BLOB handle] which has been created -** by a prior successful call to [tdsqlite3_blob_open()] and which has not -** been closed by [tdsqlite3_blob_close()]. Passing any other pointer in +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** -** See also: [tdsqlite3_blob_write()]. +** See also: [sqlite3_blob_write()]. */ -SQLITE_API int tdsqlite3_blob_read(tdsqlite3_blob *, void *Z, int N, int iOffset); +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally -** METHOD: tdsqlite3_blob +** METHOD: sqlite3_blob ** ** ^(This function is used to write data into an open [BLOB handle] from a ** caller-supplied buffer. N bytes of data are copied from the buffer Z ** into the open BLOB, starting at offset iOffset.)^ ** -** ^(On success, tdsqlite3_blob_write() returns SQLITE_OK. +** ^(On success, sqlite3_blob_write() returns SQLITE_OK. ** Otherwise, an [error code] or an [extended error code] is returned.)^ ** ^Unless SQLITE_MISUSE is returned, this function sets the ** [database connection] error code and message accessible via -** [tdsqlite3_errcode()] and [tdsqlite3_errmsg()] and related functions. +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** ** ^If the [BLOB handle] passed as the first argument was not opened for -** writing (the flags parameter to [tdsqlite3_blob_open()] was zero), +** writing (the flags parameter to [sqlite3_blob_open()] was zero), ** this function returns [SQLITE_READONLY]. ** ** This function may only modify the contents of the BLOB; it is @@ -8256,7 +8256,7 @@ SQLITE_API int tdsqlite3_blob_read(tdsqlite3_blob *, void *Z, int N, int iOffset ** ^If offset iOffset is less than N bytes from the end of the BLOB, ** [SQLITE_ERROR] is returned and no data is written. The size of the ** BLOB (and hence the maximum value of N+iOffset) can be determined -** using the [tdsqlite3_blob_bytes()] interface. ^If N or iOffset are less +** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less ** than zero [SQLITE_ERROR] is returned and no data is written. ** ** ^An attempt to write to an expired [BLOB handle] fails with an @@ -8267,31 +8267,31 @@ SQLITE_API int tdsqlite3_blob_read(tdsqlite3_blob *, void *Z, int N, int iOffset ** or by other independent statements. ** ** This routine only works on a [BLOB handle] which has been created -** by a prior successful call to [tdsqlite3_blob_open()] and which has not -** been closed by [tdsqlite3_blob_close()]. Passing any other pointer in +** by a prior successful call to [sqlite3_blob_open()] and which has not +** been closed by [sqlite3_blob_close()]. Passing any other pointer in ** to this routine results in undefined and probably undesirable behavior. ** -** See also: [tdsqlite3_blob_read()]. +** See also: [sqlite3_blob_read()]. */ -SQLITE_API int tdsqlite3_blob_write(tdsqlite3_blob *, const void *z, int n, int iOffset); +SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); /* ** CAPI3REF: Virtual File System Objects ** -** A virtual filesystem (VFS) is an [tdsqlite3_vfs] object +** A virtual filesystem (VFS) is an [sqlite3_vfs] object ** that SQLite uses to interact ** with the underlying operating system. Most SQLite builds come with a ** single default VFS that is appropriate for the host computer. ** New VFSes can be registered and existing VFSes can be unregistered. ** The following interfaces are provided. ** -** ^The tdsqlite3_vfs_find() interface returns a pointer to a VFS given its name. +** ^The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. ** ^Names are case sensitive. ** ^Names are zero-terminated UTF-8 strings. ** ^If there is no match, a NULL pointer is returned. ** ^If zVfsName is NULL then the default VFS is returned. ** -** ^New VFSes are registered with tdsqlite3_vfs_register(). +** ^New VFSes are registered with sqlite3_vfs_register(). ** ^Each new VFS becomes the default VFS if the makeDflt flag is set. ** ^The same VFS can be registered multiple times without injury. ** ^To make an existing VFS into the default VFS, register it again @@ -8300,13 +8300,13 @@ SQLITE_API int tdsqlite3_blob_write(tdsqlite3_blob *, const void *z, int n, int ** VFS is registered with a name that is NULL or an empty string, ** then the behavior is undefined. ** -** ^Unregister a VFS with the tdsqlite3_vfs_unregister() interface. +** ^Unregister a VFS with the sqlite3_vfs_unregister() interface. ** ^(If the default VFS is unregistered, another VFS is chosen as ** the default. The choice for the new VFS is arbitrary.)^ */ -SQLITE_API tdsqlite3_vfs *tdsqlite3_vfs_find(const char *zVfsName); -SQLITE_API int tdsqlite3_vfs_register(tdsqlite3_vfs*, int makeDflt); -SQLITE_API int tdsqlite3_vfs_unregister(tdsqlite3_vfs*); +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); /* ** CAPI3REF: Mutexes @@ -8337,14 +8337,14 @@ SQLITE_API int tdsqlite3_vfs_unregister(tdsqlite3_vfs*); ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex ** implementation is included with the library. In this case the ** application must supply a custom mutex implementation using the -** [SQLITE_CONFIG_MUTEX] option of the tdsqlite3_config() function -** before calling tdsqlite3_initialize() or any other public tdsqlite3_ -** function that calls tdsqlite3_initialize(). +** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function +** before calling sqlite3_initialize() or any other public sqlite3_ +** function that calls sqlite3_initialize(). ** -** ^The tdsqlite3_mutex_alloc() routine allocates a new -** mutex and returns a pointer to it. ^The tdsqlite3_mutex_alloc() +** ^The sqlite3_mutex_alloc() routine allocates a new +** mutex and returns a pointer to it. ^The sqlite3_mutex_alloc() ** routine returns NULL if it is unable to allocate the requested -** mutex. The argument to tdsqlite3_mutex_alloc() must one of these +** mutex. The argument to sqlite3_mutex_alloc() must one of these ** integer constants: ** **
      @@ -8365,7 +8365,7 @@ SQLITE_API int tdsqlite3_vfs_unregister(tdsqlite3_vfs*); **
    ** ** ^The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) -** cause tdsqlite3_mutex_alloc() to create +** cause sqlite3_mutex_alloc() to create ** a new mutex. ^The new mutex is recursive when SQLITE_MUTEX_RECURSIVE ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. ** The mutex implementation does not need to make a distinction @@ -8375,7 +8375,7 @@ SQLITE_API int tdsqlite3_vfs_unregister(tdsqlite3_vfs*); ** implementation is available on the host platform, the mutex subsystem ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** -** ^The other allowed parameters to tdsqlite3_mutex_alloc() (anything other +** ^The other allowed parameters to sqlite3_mutex_alloc() (anything other ** than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return ** a pointer to a static preexisting mutex. ^Nine static mutexes are ** used by the current version of SQLite. Future versions of SQLite @@ -8385,19 +8385,19 @@ SQLITE_API int tdsqlite3_vfs_unregister(tdsqlite3_vfs*); ** SQLITE_MUTEX_RECURSIVE. ** ** ^Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then tdsqlite3_mutex_alloc() +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() ** returns a different mutex on every call. ^For the static ** mutex types, the same mutex is returned on every call that has ** the same type number. ** -** ^The tdsqlite3_mutex_free() routine deallocates a previously +** ^The sqlite3_mutex_free() routine deallocates a previously ** allocated dynamic mutex. Attempting to deallocate a static ** mutex results in undefined behavior. ** -** ^The tdsqlite3_mutex_enter() and tdsqlite3_mutex_try() routines attempt +** ^The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt ** to enter a mutex. ^If another thread is already within the mutex, -** tdsqlite3_mutex_enter() will block and tdsqlite3_mutex_try() will return -** SQLITE_BUSY. ^The tdsqlite3_mutex_try() interface returns [SQLITE_OK] +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. ^The sqlite3_mutex_try() interface returns [SQLITE_OK] ** upon successful entry. ^(Mutexes created using ** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. ** In such cases, the @@ -8406,27 +8406,27 @@ SQLITE_API int tdsqlite3_vfs_unregister(tdsqlite3_vfs*); ** than an SQLITE_MUTEX_RECURSIVE more than once, the behavior is undefined. ** ** ^(Some systems (for example, Windows 95) do not support the operation -** implemented by tdsqlite3_mutex_try(). On those systems, tdsqlite3_mutex_try() +** implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() ** will always return SQLITE_BUSY. The SQLite core only ever uses -** tdsqlite3_mutex_try() as an optimization so this is acceptable +** sqlite3_mutex_try() as an optimization so this is acceptable ** behavior.)^ ** -** ^The tdsqlite3_mutex_leave() routine exits a mutex that was +** ^The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered by the ** calling thread or is not currently allocated. ** -** ^If the argument to tdsqlite3_mutex_enter(), tdsqlite3_mutex_try(), or -** tdsqlite3_mutex_leave() is a NULL pointer, then all three routines +** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +** sqlite3_mutex_leave() is a NULL pointer, then all three routines ** behave as no-ops. ** -** See also: [tdsqlite3_mutex_held()] and [tdsqlite3_mutex_notheld()]. +** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ -SQLITE_API tdsqlite3_mutex *tdsqlite3_mutex_alloc(int); -SQLITE_API void tdsqlite3_mutex_free(tdsqlite3_mutex*); -SQLITE_API void tdsqlite3_mutex_enter(tdsqlite3_mutex*); -SQLITE_API int tdsqlite3_mutex_try(tdsqlite3_mutex*); -SQLITE_API void tdsqlite3_mutex_leave(tdsqlite3_mutex*); +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); /* ** CAPI3REF: Mutex Methods Object @@ -8439,38 +8439,38 @@ SQLITE_API void tdsqlite3_mutex_leave(tdsqlite3_mutex*); ** implementation for specialized deployments or systems for which SQLite ** does not provide a suitable implementation. In this case, the application ** creates and populates an instance of this structure to pass -** to tdsqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. +** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option. ** Additionally, an instance of this structure can be used as an ** output variable when querying the system for the current mutex ** implementation, using the [SQLITE_CONFIG_GETMUTEX] option. ** ** ^The xMutexInit method defined by this structure is invoked as -** part of system initialization by the tdsqlite3_initialize() function. +** part of system initialization by the sqlite3_initialize() function. ** ^The xMutexInit routine is called by SQLite exactly once for each -** effective call to [tdsqlite3_initialize()]. +** effective call to [sqlite3_initialize()]. ** ** ^The xMutexEnd method defined by this structure is invoked as -** part of system shutdown by the tdsqlite3_shutdown() function. The +** part of system shutdown by the sqlite3_shutdown() function. The ** implementation of this method is expected to release all outstanding ** resources obtained by the mutex methods implementation, especially ** those obtained by the xMutexInit method. ^The xMutexEnd() -** interface is invoked exactly once for each call to [tdsqlite3_shutdown()]. +** interface is invoked exactly once for each call to [sqlite3_shutdown()]. ** ** ^(The remaining seven methods defined by this structure (xMutexAlloc, ** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and ** xMutexNotheld) implement the following interfaces (respectively): ** **
      -**
    • [tdsqlite3_mutex_alloc()]
    • -**
    • [tdsqlite3_mutex_free()]
    • -**
    • [tdsqlite3_mutex_enter()]
    • -**
    • [tdsqlite3_mutex_try()]
    • -**
    • [tdsqlite3_mutex_leave()]
    • -**
    • [tdsqlite3_mutex_held()]
    • -**
    • [tdsqlite3_mutex_notheld()]
    • +**
    • [sqlite3_mutex_alloc()]
    • +**
    • [sqlite3_mutex_free()]
    • +**
    • [sqlite3_mutex_enter()]
    • +**
    • [sqlite3_mutex_try()]
    • +**
    • [sqlite3_mutex_leave()]
    • +**
    • [sqlite3_mutex_held()]
    • +**
    • [sqlite3_mutex_notheld()]
    • **
    )^ ** -** The only difference is that the public tdsqlite3_XXX functions enumerated +** The only difference is that the public sqlite3_XXX functions enumerated ** above silently ignore any invocations that pass a NULL pointer instead ** of a valid mutex handle. The implementations of the methods defined ** by this structure are not required to handle this case. The results @@ -8483,33 +8483,33 @@ SQLITE_API void tdsqlite3_mutex_leave(tdsqlite3_mutex*); ** intervening calls to xMutexEnd(). Second and subsequent calls to ** xMutexInit() must be no-ops. ** -** xMutexInit() must not use SQLite memory allocation ([tdsqlite3_malloc()] +** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] ** and its associates). Similarly, xMutexAlloc() must not use SQLite memory ** allocation for a static mutex. ^However xMutexAlloc() may use SQLite ** memory allocation for a fast or recursive mutex. ** -** ^SQLite will invoke the xMutexEnd() method when [tdsqlite3_shutdown()] is +** ^SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is ** called, but only if the prior call to xMutexInit returned SQLITE_OK. ** If xMutexInit fails in any way, it is expected to clean up after itself ** prior to returning. */ -typedef struct tdsqlite3_mutex_methods tdsqlite3_mutex_methods; -struct tdsqlite3_mutex_methods { +typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; +struct sqlite3_mutex_methods { int (*xMutexInit)(void); int (*xMutexEnd)(void); - tdsqlite3_mutex *(*xMutexAlloc)(int); - void (*xMutexFree)(tdsqlite3_mutex *); - void (*xMutexEnter)(tdsqlite3_mutex *); - int (*xMutexTry)(tdsqlite3_mutex *); - void (*xMutexLeave)(tdsqlite3_mutex *); - int (*xMutexHeld)(tdsqlite3_mutex *); - int (*xMutexNotheld)(tdsqlite3_mutex *); + sqlite3_mutex *(*xMutexAlloc)(int); + void (*xMutexFree)(sqlite3_mutex *); + void (*xMutexEnter)(sqlite3_mutex *); + int (*xMutexTry)(sqlite3_mutex *); + void (*xMutexLeave)(sqlite3_mutex *); + int (*xMutexHeld)(sqlite3_mutex *); + int (*xMutexNotheld)(sqlite3_mutex *); }; /* ** CAPI3REF: Mutex Verification Routines ** -** The tdsqlite3_mutex_held() and tdsqlite3_mutex_notheld() routines +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines ** are intended for use inside assert() statements. The SQLite core ** never uses these routines except inside an assert() and applications ** are advised to follow the lead of the core. The SQLite core only @@ -8526,24 +8526,24 @@ struct tdsqlite3_mutex_methods { ** versions of these routines, it should at least provide stubs that always ** return true so that one does not get spurious assertion failures. ** -** If the argument to tdsqlite3_mutex_held() is a NULL pointer then +** If the argument to sqlite3_mutex_held() is a NULL pointer then ** the routine should return 1. This seems counter-intuitive since ** clearly the mutex cannot be held if it does not exist. But ** the reason the mutex does not exist is because the build is not ** using mutexes. And we do not want the assert() containing the -** call to tdsqlite3_mutex_held() to fail, so a non-zero return is -** the appropriate thing to do. The tdsqlite3_mutex_notheld() +** call to sqlite3_mutex_held() to fail, so a non-zero return is +** the appropriate thing to do. The sqlite3_mutex_notheld() ** interface should also return 1 when given a NULL pointer. */ #ifndef NDEBUG -SQLITE_API int tdsqlite3_mutex_held(tdsqlite3_mutex*); -SQLITE_API int tdsqlite3_mutex_notheld(tdsqlite3_mutex*); +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); #endif /* ** CAPI3REF: Mutex Types ** -** The [tdsqlite3_mutex_alloc()] interface takes a single argument +** The [sqlite3_mutex_alloc()] interface takes a single argument ** which is one of these integer constants. ** ** The set of static mutexes may change from one SQLite release to the @@ -8553,13 +8553,13 @@ SQLITE_API int tdsqlite3_mutex_notheld(tdsqlite3_mutex*); #define SQLITE_MUTEX_FAST 0 #define SQLITE_MUTEX_RECURSIVE 1 #define SQLITE_MUTEX_STATIC_MASTER 2 -#define SQLITE_MUTEX_STATIC_MEM 3 /* tdsqlite3_malloc() */ +#define SQLITE_MUTEX_STATIC_MEM 3 /* sqlite3_malloc() */ #define SQLITE_MUTEX_STATIC_MEM2 4 /* NOT USED */ -#define SQLITE_MUTEX_STATIC_OPEN 4 /* tdsqlite3BtreeOpen() */ -#define SQLITE_MUTEX_STATIC_PRNG 5 /* tdsqlite3_randomness() */ +#define SQLITE_MUTEX_STATIC_OPEN 4 /* sqlite3BtreeOpen() */ +#define SQLITE_MUTEX_STATIC_PRNG 5 /* sqlite3_randomness() */ #define SQLITE_MUTEX_STATIC_LRU 6 /* lru page list */ #define SQLITE_MUTEX_STATIC_LRU2 7 /* NOT USED */ -#define SQLITE_MUTEX_STATIC_PMEM 7 /* tdsqlite3PageMalloc() */ +#define SQLITE_MUTEX_STATIC_PMEM 7 /* sqlite3PageMalloc() */ #define SQLITE_MUTEX_STATIC_APP1 8 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP2 9 /* For use by application */ #define SQLITE_MUTEX_STATIC_APP3 10 /* For use by application */ @@ -8569,23 +8569,23 @@ SQLITE_API int tdsqlite3_mutex_notheld(tdsqlite3_mutex*); /* ** CAPI3REF: Retrieve the mutex for a database connection -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^This interface returns a pointer the [tdsqlite3_mutex] object that +** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ -SQLITE_API tdsqlite3_mutex *tdsqlite3_db_mutex(tdsqlite3*); +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** KEYWORDS: {file control} ** -** ^The [tdsqlite3_file_control()] interface makes a direct call to the -** xFileControl method for the [tdsqlite3_io_methods] object associated +** ^The [sqlite3_file_control()] interface makes a direct call to the +** xFileControl method for the [sqlite3_io_methods] object associated ** with a particular database identified by the second argument. ^The ** name of the database is "main" for the main database or "temp" for the ** TEMP database, or the name that appears after the AS keyword for @@ -8597,35 +8597,35 @@ SQLITE_API tdsqlite3_mutex *tdsqlite3_db_mutex(tdsqlite3*); ** the xFileControl method. ^The return value of the xFileControl ** method becomes the return value of this routine. ** -** A few opcodes for [tdsqlite3_file_control()] are handled directly +** A few opcodes for [sqlite3_file_control()] are handled directly ** by the SQLite core and never invoke the -** tdsqlite3_io_methods.xFileControl method. +** sqlite3_io_methods.xFileControl method. ** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes -** a pointer to the underlying [tdsqlite3_file] object to be written into +** a pointer to the underlying [sqlite3_file] object to be written into ** the space pointed to by the 4th parameter. The ** [SQLITE_FCNTL_JOURNAL_POINTER] works similarly except that it returns -** the [tdsqlite3_file] object associated with the journal file instead of +** the [sqlite3_file] object associated with the journal file instead of ** the main database. The [SQLITE_FCNTL_VFS_POINTER] opcode returns -** a pointer to the underlying [tdsqlite3_vfs] object for the file. +** a pointer to the underlying [sqlite3_vfs] object for the file. ** The [SQLITE_FCNTL_DATA_VERSION] returns the data version counter ** from the pager. ** ** ^If the second parameter (zDbName) does not match the name of any ** open database file, then SQLITE_ERROR is returned. ^This error -** code is not remembered and will not be recalled by [tdsqlite3_errcode()] -** or [tdsqlite3_errmsg()]. The underlying xFileControl method might +** code is not remembered and will not be recalled by [sqlite3_errcode()] +** or [sqlite3_errmsg()]. The underlying xFileControl method might ** also return SQLITE_ERROR. There is no way to distinguish between ** an incorrect zDbName and an SQLITE_ERROR return from the underlying ** xFileControl method. ** ** See also: [file control opcodes] */ -SQLITE_API int tdsqlite3_file_control(tdsqlite3*, const char *zDbName, int op, void*); +SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); /* ** CAPI3REF: Testing Interface ** -** ^The tdsqlite3_test_control() interface is used to read out internal +** ^The sqlite3_test_control() interface is used to read out internal ** state of SQLite and to inject faults into SQLite for testing ** purposes. ^The first parameter is an operation code that determines ** the number, meaning, and operation of all subsequent parameters. @@ -8639,18 +8639,18 @@ SQLITE_API int tdsqlite3_file_control(tdsqlite3*, const char *zDbName, int op, v ** Unlike most of the SQLite API, this function is not guaranteed to ** operate consistently from one release to the next. */ -SQLITE_API int tdsqlite3_test_control(int op, ...); +SQLITE_API int sqlite3_test_control(int op, ...); /* ** CAPI3REF: Testing Interface Operation Codes ** ** These constants are the valid operation code parameters used -** as the first argument to [tdsqlite3_test_control()]. +** as the first argument to [sqlite3_test_control()]. ** ** These parameters and their meanings are subject to change ** without notice. These values are for testing purposes only. ** Applications should not use any of these parameters or the -** [tdsqlite3_test_control()] interface. +** [sqlite3_test_control()] interface. */ #define SQLITE_TESTCTRL_FIRST 5 #define SQLITE_TESTCTRL_PRNG_SAVE 5 @@ -8690,18 +8690,18 @@ SQLITE_API int tdsqlite3_test_control(int op, ...); ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. ** -** The tdsqlite3_keyword_count() interface returns the number of distinct +** The sqlite3_keyword_count() interface returns the number of distinct ** keywords understood by SQLite. ** -** The tdsqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and +** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and ** makes *Z point to that keyword expressed as UTF8 and writes the number ** of bytes in the keyword into *L. The string that *Z points to is not -** zero-terminated. The tdsqlite3_keyword_name(N,Z,L) routine returns +** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns ** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z ** or L are NULL or invalid pointers then calls to -** tdsqlite3_keyword_name(N,Z,L) result in undefined behavior. +** sqlite3_keyword_name(N,Z,L) result in undefined behavior. ** -** The tdsqlite3_keyword_check(Z,L) interface checks to see whether or not +** The sqlite3_keyword_check(Z,L) interface checks to see whether or not ** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero ** if it is and zero if not. ** @@ -8729,141 +8729,141 @@ SQLITE_API int tdsqlite3_test_control(int op, ...); ** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also, ** new keywords may be added to future releases of SQLite. */ -SQLITE_API int tdsqlite3_keyword_count(void); -SQLITE_API int tdsqlite3_keyword_name(int,const char**,int*); -SQLITE_API int tdsqlite3_keyword_check(const char*,int); +SQLITE_API int sqlite3_keyword_count(void); +SQLITE_API int sqlite3_keyword_name(int,const char**,int*); +SQLITE_API int sqlite3_keyword_check(const char*,int); /* ** CAPI3REF: Dynamic String Object ** KEYWORDS: {dynamic string} ** -** An instance of the tdsqlite3_str object contains a dynamically-sized +** An instance of the sqlite3_str object contains a dynamically-sized ** string under construction. ** -** The lifecycle of an tdsqlite3_str object is as follows: +** The lifecycle of an sqlite3_str object is as follows: **
      -**
    1. ^The tdsqlite3_str object is created using [tdsqlite3_str_new()]. -**
    2. ^Text is appended to the tdsqlite3_str object using various -** methods, such as [tdsqlite3_str_appendf()]. -**
    3. ^The tdsqlite3_str object is destroyed and the string it created -** is returned using the [tdsqlite3_str_finish()] interface. +**
    4. ^The sqlite3_str object is created using [sqlite3_str_new()]. +**
    5. ^Text is appended to the sqlite3_str object using various +** methods, such as [sqlite3_str_appendf()]. +**
    6. ^The sqlite3_str object is destroyed and the string it created +** is returned using the [sqlite3_str_finish()] interface. **
    */ -typedef struct tdsqlite3_str tdsqlite3_str; +typedef struct sqlite3_str sqlite3_str; /* ** CAPI3REF: Create A New Dynamic String Object -** CONSTRUCTOR: tdsqlite3_str +** CONSTRUCTOR: sqlite3_str ** -** ^The [tdsqlite3_str_new(D)] interface allocates and initializes -** a new [tdsqlite3_str] object. To avoid memory leaks, the object returned by -** [tdsqlite3_str_new()] must be freed by a subsequent call to -** [tdsqlite3_str_finish(X)]. +** ^The [sqlite3_str_new(D)] interface allocates and initializes +** a new [sqlite3_str] object. To avoid memory leaks, the object returned by +** [sqlite3_str_new()] must be freed by a subsequent call to +** [sqlite3_str_finish(X)]. ** -** ^The [tdsqlite3_str_new(D)] interface always returns a pointer to a -** valid [tdsqlite3_str] object, though in the event of an out-of-memory +** ^The [sqlite3_str_new(D)] interface always returns a pointer to a +** valid [sqlite3_str] object, though in the event of an out-of-memory ** error the returned object might be a special singleton that will ** silently reject new text, always return SQLITE_NOMEM from -** [tdsqlite3_str_errcode()], always return 0 for -** [tdsqlite3_str_length()], and always return NULL from -** [tdsqlite3_str_finish(X)]. It is always safe to use the value -** returned by [tdsqlite3_str_new(D)] as the tdsqlite3_str parameter -** to any of the other [tdsqlite3_str] methods. -** -** The D parameter to [tdsqlite3_str_new(D)] may be NULL. If the -** D parameter in [tdsqlite3_str_new(D)] is not NULL, then the maximum -** length of the string contained in the [tdsqlite3_str] object will be -** the value set for [tdsqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead +** [sqlite3_str_errcode()], always return 0 for +** [sqlite3_str_length()], and always return NULL from +** [sqlite3_str_finish(X)]. It is always safe to use the value +** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter +** to any of the other [sqlite3_str] methods. +** +** The D parameter to [sqlite3_str_new(D)] may be NULL. If the +** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum +** length of the string contained in the [sqlite3_str] object will be +** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead ** of [SQLITE_MAX_LENGTH]. */ -SQLITE_API tdsqlite3_str *tdsqlite3_str_new(tdsqlite3*); +SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*); /* ** CAPI3REF: Finalize A Dynamic String -** DESTRUCTOR: tdsqlite3_str +** DESTRUCTOR: sqlite3_str ** -** ^The [tdsqlite3_str_finish(X)] interface destroys the tdsqlite3_str object X -** and returns a pointer to a memory buffer obtained from [tdsqlite3_malloc64()] +** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X +** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] ** that contains the constructed string. The calling application should -** pass the returned value to [tdsqlite3_free()] to avoid a memory leak. -** ^The [tdsqlite3_str_finish(X)] interface may return a NULL pointer if any +** pass the returned value to [sqlite3_free()] to avoid a memory leak. +** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any ** errors were encountered during construction of the string. ^The -** [tdsqlite3_str_finish(X)] interface will also return a NULL pointer if the -** string in [tdsqlite3_str] object X is zero bytes long. +** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the +** string in [sqlite3_str] object X is zero bytes long. */ -SQLITE_API char *tdsqlite3_str_finish(tdsqlite3_str*); +SQLITE_API char *sqlite3_str_finish(sqlite3_str*); /* ** CAPI3REF: Add Content To A Dynamic String -** METHOD: tdsqlite3_str +** METHOD: sqlite3_str ** -** These interfaces add content to an tdsqlite3_str object previously obtained -** from [tdsqlite3_str_new()]. +** These interfaces add content to an sqlite3_str object previously obtained +** from [sqlite3_str_new()]. ** -** ^The [tdsqlite3_str_appendf(X,F,...)] and -** [tdsqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] +** ^The [sqlite3_str_appendf(X,F,...)] and +** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] ** functionality of SQLite to append formatted text onto the end of -** [tdsqlite3_str] object X. +** [sqlite3_str] object X. ** -** ^The [tdsqlite3_str_append(X,S,N)] method appends exactly N bytes from string S -** onto the end of the [tdsqlite3_str] object X. N must be non-negative. +** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S +** onto the end of the [sqlite3_str] object X. N must be non-negative. ** S must contain at least N non-zero bytes of content. To append a -** zero-terminated string in its entirety, use the [tdsqlite3_str_appendall()] +** zero-terminated string in its entirety, use the [sqlite3_str_appendall()] ** method instead. ** -** ^The [tdsqlite3_str_appendall(X,S)] method appends the complete content of -** zero-terminated string S onto the end of [tdsqlite3_str] object X. +** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of +** zero-terminated string S onto the end of [sqlite3_str] object X. ** -** ^The [tdsqlite3_str_appendchar(X,N,C)] method appends N copies of the -** single-byte character C onto the end of [tdsqlite3_str] object X. +** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the +** single-byte character C onto the end of [sqlite3_str] object X. ** ^This method can be used, for example, to add whitespace indentation. ** -** ^The [tdsqlite3_str_reset(X)] method resets the string under construction -** inside [tdsqlite3_str] object X back to zero bytes in length. +** ^The [sqlite3_str_reset(X)] method resets the string under construction +** inside [sqlite3_str] object X back to zero bytes in length. ** ** These methods do not return a result code. ^If an error occurs, that fact -** is recorded in the [tdsqlite3_str] object and can be recovered by a -** subsequent call to [tdsqlite3_str_errcode(X)]. +** is recorded in the [sqlite3_str] object and can be recovered by a +** subsequent call to [sqlite3_str_errcode(X)]. */ -SQLITE_API void tdsqlite3_str_appendf(tdsqlite3_str*, const char *zFormat, ...); -SQLITE_API void tdsqlite3_str_vappendf(tdsqlite3_str*, const char *zFormat, va_list); -SQLITE_API void tdsqlite3_str_append(tdsqlite3_str*, const char *zIn, int N); -SQLITE_API void tdsqlite3_str_appendall(tdsqlite3_str*, const char *zIn); -SQLITE_API void tdsqlite3_str_appendchar(tdsqlite3_str*, int N, char C); -SQLITE_API void tdsqlite3_str_reset(tdsqlite3_str*); +SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); +SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); +SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); +SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); +SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); +SQLITE_API void sqlite3_str_reset(sqlite3_str*); /* ** CAPI3REF: Status Of A Dynamic String -** METHOD: tdsqlite3_str +** METHOD: sqlite3_str ** -** These interfaces return the current status of an [tdsqlite3_str] object. +** These interfaces return the current status of an [sqlite3_str] object. ** ** ^If any prior errors have occurred while constructing the dynamic string -** in tdsqlite3_str X, then the [tdsqlite3_str_errcode(X)] method will return -** an appropriate error code. ^The [tdsqlite3_str_errcode(X)] method returns +** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return +** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns ** [SQLITE_NOMEM] following any out-of-memory error, or ** [SQLITE_TOOBIG] if the size of the dynamic string exceeds ** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors. ** -** ^The [tdsqlite3_str_length(X)] method returns the current length, in bytes, -** of the dynamic string under construction in [tdsqlite3_str] object X. -** ^The length returned by [tdsqlite3_str_length(X)] does not include the +** ^The [sqlite3_str_length(X)] method returns the current length, in bytes, +** of the dynamic string under construction in [sqlite3_str] object X. +** ^The length returned by [sqlite3_str_length(X)] does not include the ** zero-termination byte. ** -** ^The [tdsqlite3_str_value(X)] method returns a pointer to the current +** ^The [sqlite3_str_value(X)] method returns a pointer to the current ** content of the dynamic string under construction in X. The value -** returned by [tdsqlite3_str_value(X)] is managed by the tdsqlite3_str object X +** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X ** and might be freed or altered by any subsequent method on the same -** [tdsqlite3_str] object. Applications must not used the pointer returned -** [tdsqlite3_str_value(X)] after any subsequent method call on the same +** [sqlite3_str] object. Applications must not used the pointer returned +** [sqlite3_str_value(X)] after any subsequent method call on the same ** object. ^Applications may change the content of the string returned -** by [tdsqlite3_str_value(X)] as long as they do not write into any bytes -** outside the range of 0 to [tdsqlite3_str_length(X)] and do not read or -** write any byte after any subsequent tdsqlite3_str method call. +** by [sqlite3_str_value(X)] as long as they do not write into any bytes +** outside the range of 0 to [sqlite3_str_length(X)] and do not read or +** write any byte after any subsequent sqlite3_str method call. */ -SQLITE_API int tdsqlite3_str_errcode(tdsqlite3_str*); -SQLITE_API int tdsqlite3_str_length(tdsqlite3_str*); -SQLITE_API char *tdsqlite3_str_value(tdsqlite3_str*); +SQLITE_API int sqlite3_str_errcode(sqlite3_str*); +SQLITE_API int sqlite3_str_length(sqlite3_str*); +SQLITE_API char *sqlite3_str_value(sqlite3_str*); /* ** CAPI3REF: SQLite Runtime Status @@ -8882,20 +8882,20 @@ SQLITE_API char *tdsqlite3_str_value(tdsqlite3_str*); ** ^(Other parameters record only the highwater mark and not the current ** value. For these latter parameters nothing is written into *pCurrent.)^ ** -** ^The tdsqlite3_status() and tdsqlite3_status64() routines return +** ^The sqlite3_status() and sqlite3_status64() routines return ** SQLITE_OK on success and a non-zero [error code] on failure. ** ** If either the current value or the highwater mark is too large to ** be represented by a 32-bit integer, then the values returned by -** tdsqlite3_status() are undefined. +** sqlite3_status() are undefined. ** -** See also: [tdsqlite3_db_status()] +** See also: [sqlite3_db_status()] */ -SQLITE_API int tdsqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); -SQLITE_API int tdsqlite3_status64( +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API int sqlite3_status64( int op, - tdsqlite3_int64 *pCurrent, - tdsqlite3_int64 *pHighwater, + sqlite3_int64 *pCurrent, + sqlite3_int64 *pHighwater, int resetFlag ); @@ -8905,23 +8905,23 @@ SQLITE_API int tdsqlite3_status64( ** KEYWORDS: {status parameters} ** ** These integer constants designate various run-time status parameters -** that can be returned by [tdsqlite3_status()]. +** that can be returned by [sqlite3_status()]. ** **
    ** [[SQLITE_STATUS_MEMORY_USED]] ^(
    SQLITE_STATUS_MEMORY_USED
    **
    This parameter is the current amount of memory checked out -** using [tdsqlite3_malloc()], either directly or indirectly. The -** figure includes calls made to [tdsqlite3_malloc()] by the application +** using [sqlite3_malloc()], either directly or indirectly. The +** figure includes calls made to [sqlite3_malloc()] by the application ** and internal memory usage by the SQLite library. Auxiliary page-cache ** memory controlled by [SQLITE_CONFIG_PAGECACHE] is not included in ** this parameter. The amount returned is the sum of the allocation -** sizes as reported by the xSize method in [tdsqlite3_mem_methods].
    )^ +** sizes as reported by the xSize method in [sqlite3_mem_methods].
    )^ ** ** [[SQLITE_STATUS_MALLOC_SIZE]] ^(
    SQLITE_STATUS_MALLOC_SIZE
    **
    This parameter records the largest memory allocation request -** handed to [tdsqlite3_malloc()] or [tdsqlite3_realloc()] (or their +** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their ** internal equivalents). Only the value returned in the -** *pHighwater parameter to [tdsqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.
    )^ ** ** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
    SQLITE_STATUS_MALLOC_COUNT
    @@ -8938,7 +8938,7 @@ SQLITE_API int tdsqlite3_status64( ** ^(
    SQLITE_STATUS_PAGECACHE_OVERFLOW
    **
    This parameter returns the number of bytes of page cache ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] -** buffer and where forced to overflow to [tdsqlite3_malloc()]. The +** buffer and where forced to overflow to [sqlite3_malloc()]. The ** returned value includes allocations that overflowed because they ** where too large (they were larger than the "sz" parameter to ** [SQLITE_CONFIG_PAGECACHE]) and allocations that overflowed because @@ -8947,7 +8947,7 @@ SQLITE_API int tdsqlite3_status64( ** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
    SQLITE_STATUS_PAGECACHE_SIZE
    **
    This parameter records the largest memory allocation request ** handed to the [pagecache memory allocator]. Only the value returned in the -** *pHighwater parameter to [tdsqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.
    )^ ** ** [[SQLITE_STATUS_SCRATCH_USED]]
    SQLITE_STATUS_SCRATCH_USED
    @@ -8980,7 +8980,7 @@ SQLITE_API int tdsqlite3_status64( /* ** CAPI3REF: Database Connection Status -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the @@ -8996,24 +8996,24 @@ SQLITE_API int tdsqlite3_status64( ** the resetFlg is true, then the highest instantaneous value is ** reset back down to the current value. ** -** ^The tdsqlite3_db_status() routine returns SQLITE_OK on success and a +** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a ** non-zero [error code] on failure. ** -** See also: [tdsqlite3_status()] and [tdsqlite3_stmt_status()]. +** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. */ -SQLITE_API int tdsqlite3_db_status(tdsqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); +SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); /* ** CAPI3REF: Status Parameters for database connections ** KEYWORDS: {SQLITE_DBSTATUS options} ** ** These constants are the available integer "verbs" that can be passed as -** the second argument to the [tdsqlite3_db_status()] interface. +** the second argument to the [sqlite3_db_status()] interface. ** ** New verbs may be added in future releases of SQLite. Existing verbs ** might be discontinued. Applications should check the return code from -** [tdsqlite3_db_status()] to make sure that the call worked. -** The [tdsqlite3_db_status()] interface will return a non-zero error code +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code ** if a discontinued or unsupported verb is invoked. ** **
    @@ -9132,7 +9132,7 @@ SQLITE_API int tdsqlite3_db_status(tdsqlite3*, int op, int *pCur, int *pHiwtr, i /* ** CAPI3REF: Prepared Statement Status -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** ^(Each prepared statement maintains various ** [SQLITE_STMTSTATUS counters] that measure the number @@ -9152,16 +9152,16 @@ SQLITE_API int tdsqlite3_db_status(tdsqlite3*, int op, int *pCur, int *pHiwtr, i ** ^If the resetFlg is true, then the counter is reset to zero after this ** interface call returns. ** -** See also: [tdsqlite3_status()] and [tdsqlite3_db_status()]. +** See also: [sqlite3_status()] and [sqlite3_db_status()]. */ -SQLITE_API int tdsqlite3_stmt_status(tdsqlite3_stmt*, int op,int resetFlg); +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); /* ** CAPI3REF: Status Parameters for prepared statements ** KEYWORDS: {SQLITE_STMTSTATUS counter} {SQLITE_STMTSTATUS counters} ** ** These preprocessor macros define integer codes that name counter -** values associated with the [tdsqlite3_stmt_status()] interface. +** values associated with the [sqlite3_stmt_status()] interface. ** The meanings of the various counters are as follows: ** **
    @@ -9199,14 +9199,14 @@ SQLITE_API int tdsqlite3_stmt_status(tdsqlite3_stmt*, int op,int resetFlg); ** [[SQLITE_STMTSTATUS_RUN]]
    SQLITE_STMTSTATUS_RUN
    **
    ^This is the number of times that the prepared statement has ** been run. A single "run" for the purposes of this counter is one -** or more calls to [tdsqlite3_step()] followed by a call to [tdsqlite3_reset()]. -** The counter is incremented on the first [tdsqlite3_step()] call of each +** or more calls to [sqlite3_step()] followed by a call to [sqlite3_reset()]. +** The counter is incremented on the first [sqlite3_step()] call of each ** cycle. ** ** [[SQLITE_STMTSTATUS_MEMUSED]]
    SQLITE_STMTSTATUS_MEMUSED
    **
    ^This is the approximate number of bytes of heap memory ** used to store the prepared statement. ^This value is not actually -** a counter, and so the resetFlg parameter to tdsqlite3_stmt_status() +** a counter, and so the resetFlg parameter to sqlite3_stmt_status() ** is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. **
    **
    @@ -9222,28 +9222,28 @@ SQLITE_API int tdsqlite3_stmt_status(tdsqlite3_stmt*, int op,int resetFlg); /* ** CAPI3REF: Custom Page Cache Object ** -** The tdsqlite3_pcache type is opaque. It is implemented by +** The sqlite3_pcache type is opaque. It is implemented by ** the pluggable module. The SQLite core has no knowledge of ** its size or internal structure and never deals with the -** tdsqlite3_pcache object except by holding and passing pointers +** sqlite3_pcache object except by holding and passing pointers ** to the object. ** -** See [tdsqlite3_pcache_methods2] for additional information. +** See [sqlite3_pcache_methods2] for additional information. */ -typedef struct tdsqlite3_pcache tdsqlite3_pcache; +typedef struct sqlite3_pcache sqlite3_pcache; /* ** CAPI3REF: Custom Page Cache Object ** -** The tdsqlite3_pcache_page object represents a single page in the +** The sqlite3_pcache_page object represents a single page in the ** page cache. The page cache will allocate instances of this ** object. Various methods of the page cache use pointers to instances ** of this object as parameters or as their return value. ** -** See [tdsqlite3_pcache_methods2] for additional information. +** See [sqlite3_pcache_methods2] for additional information. */ -typedef struct tdsqlite3_pcache_page tdsqlite3_pcache_page; -struct tdsqlite3_pcache_page { +typedef struct sqlite3_pcache_page sqlite3_pcache_page; +struct sqlite3_pcache_page { void *pBuf; /* The content of the page */ void *pExtra; /* Extra information associated with the page */ }; @@ -9252,9 +9252,9 @@ struct tdsqlite3_pcache_page { ** CAPI3REF: Application Defined Page Cache. ** KEYWORDS: {page cache} ** -** ^(The [tdsqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can +** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can ** register an alternative page cache implementation by passing in an -** instance of the tdsqlite3_pcache_methods2 structure.)^ +** instance of the sqlite3_pcache_methods2 structure.)^ ** In many applications, most of the heap memory allocated by ** SQLite is used for the page cache. ** By implementing a @@ -9268,16 +9268,16 @@ struct tdsqlite3_pcache_page { ** extreme measure that is only needed by the most demanding applications. ** The built-in page cache is recommended for most uses. ** -** ^(The contents of the tdsqlite3_pcache_methods2 structure are copied to an -** internal buffer by SQLite within the call to [tdsqlite3_config]. Hence +** ^(The contents of the sqlite3_pcache_methods2 structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence ** the application may discard the parameter after the call to -** [tdsqlite3_config()] returns.)^ +** [sqlite3_config()] returns.)^ ** ** [[the xInit() page cache method]] ** ^(The xInit() method is called once for each effective -** call to [tdsqlite3_initialize()])^ +** call to [sqlite3_initialize()])^ ** (usually only once during the lifetime of the process). ^(The xInit() -** method is passed a copy of the tdsqlite3_pcache_methods2.pArg value.)^ +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ ** The intent of the xInit() method is to set up global data structures ** required by the custom page cache implementation. ** ^(If the xInit() method is NULL, then the @@ -9285,14 +9285,14 @@ struct tdsqlite3_pcache_page { ** page cache.)^ ** ** [[the xShutdown() page cache method]] -** ^The xShutdown() method is called by [tdsqlite3_shutdown()]. +** ^The xShutdown() method is called by [sqlite3_shutdown()]. ** It can be used to clean up ** any outstanding resources before process shutdown, if required. ** ^The xShutdown() method may be NULL. ** ** ^SQLite automatically serializes calls to the xInit method, ** so the xInit method need not be threadsafe. ^The -** xShutdown method is only called from [tdsqlite3_shutdown()] so it does +** xShutdown method is only called from [sqlite3_shutdown()] so it does ** not need to be threadsafe either. All other methods must be threadsafe ** in multithreaded applications. ** @@ -9336,10 +9336,10 @@ struct tdsqlite3_pcache_page { ** ** [[the xFetch() page cache methods]] ** The xFetch() method locates a page in the cache and returns a pointer to -** an tdsqlite3_pcache_page object associated with that page, or a NULL pointer. -** The pBuf element of the returned tdsqlite3_pcache_page object will be a +** an sqlite3_pcache_page object associated with that page, or a NULL pointer. +** The pBuf element of the returned sqlite3_pcache_page object will be a ** pointer to a buffer of szPage bytes used to store the content of a -** single database page. The pExtra element of tdsqlite3_pcache_page will be +** single database page. The pExtra element of sqlite3_pcache_page will be ** a pointer to the szExtra bytes of extra storage that SQLite has requested ** for each entry in the page cache. ** @@ -9397,8 +9397,8 @@ struct tdsqlite3_pcache_page { ** [[the xDestroy() page cache method]] ** ^The xDestroy() method is used to delete a cache allocated by xCreate(). ** All resources associated with the specified cache should be freed. ^After -** calling the xDestroy() method, SQLite considers the [tdsqlite3_pcache*] -** handle invalid, and will not use it with any other tdsqlite3_pcache_methods2 +** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*] +** handle invalid, and will not use it with any other sqlite3_pcache_methods2 ** functions. ** ** [[the xShrink() page cache method]] @@ -9407,56 +9407,56 @@ struct tdsqlite3_pcache_page { ** is not obligated to free any memory, but well-behaved implementations should ** do their best. */ -typedef struct tdsqlite3_pcache_methods2 tdsqlite3_pcache_methods2; -struct tdsqlite3_pcache_methods2 { +typedef struct sqlite3_pcache_methods2 sqlite3_pcache_methods2; +struct sqlite3_pcache_methods2 { int iVersion; void *pArg; int (*xInit)(void*); void (*xShutdown)(void*); - tdsqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); - void (*xCachesize)(tdsqlite3_pcache*, int nCachesize); - int (*xPagecount)(tdsqlite3_pcache*); - tdsqlite3_pcache_page *(*xFetch)(tdsqlite3_pcache*, unsigned key, int createFlag); - void (*xUnpin)(tdsqlite3_pcache*, tdsqlite3_pcache_page*, int discard); - void (*xRekey)(tdsqlite3_pcache*, tdsqlite3_pcache_page*, + sqlite3_pcache *(*xCreate)(int szPage, int szExtra, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, unsigned oldKey, unsigned newKey); - void (*xTruncate)(tdsqlite3_pcache*, unsigned iLimit); - void (*xDestroy)(tdsqlite3_pcache*); - void (*xShrink)(tdsqlite3_pcache*); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); + void (*xShrink)(sqlite3_pcache*); }; /* ** This is the obsolete pcache_methods object that has now been replaced -** by tdsqlite3_pcache_methods2. This object is not used by SQLite. It is +** by sqlite3_pcache_methods2. This object is not used by SQLite. It is ** retained in the header file for backwards compatibility only. */ -typedef struct tdsqlite3_pcache_methods tdsqlite3_pcache_methods; -struct tdsqlite3_pcache_methods { +typedef struct sqlite3_pcache_methods sqlite3_pcache_methods; +struct sqlite3_pcache_methods { void *pArg; int (*xInit)(void*); void (*xShutdown)(void*); - tdsqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); - void (*xCachesize)(tdsqlite3_pcache*, int nCachesize); - int (*xPagecount)(tdsqlite3_pcache*); - void *(*xFetch)(tdsqlite3_pcache*, unsigned key, int createFlag); - void (*xUnpin)(tdsqlite3_pcache*, void*, int discard); - void (*xRekey)(tdsqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); - void (*xTruncate)(tdsqlite3_pcache*, unsigned iLimit); - void (*xDestroy)(tdsqlite3_pcache*); + sqlite3_pcache *(*xCreate)(int szPage, int bPurgeable); + void (*xCachesize)(sqlite3_pcache*, int nCachesize); + int (*xPagecount)(sqlite3_pcache*); + void *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); + void (*xUnpin)(sqlite3_pcache*, void*, int discard); + void (*xRekey)(sqlite3_pcache*, void*, unsigned oldKey, unsigned newKey); + void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); + void (*xDestroy)(sqlite3_pcache*); }; /* ** CAPI3REF: Online Backup Object ** -** The tdsqlite3_backup object records state information about an ongoing -** online backup operation. ^The tdsqlite3_backup object is created by -** a call to [tdsqlite3_backup_init()] and is destroyed by a call to -** [tdsqlite3_backup_finish()]. +** The sqlite3_backup object records state information about an ongoing +** online backup operation. ^The sqlite3_backup object is created by +** a call to [sqlite3_backup_init()] and is destroyed by a call to +** [sqlite3_backup_finish()]. ** ** See Also: [Using the SQLite Online Backup API] */ -typedef struct tdsqlite3_backup tdsqlite3_backup; +typedef struct sqlite3_backup sqlite3_backup; /* ** CAPI3REF: Online Backup API. @@ -9477,63 +9477,63 @@ typedef struct tdsqlite3_backup tdsqlite3_backup; ** ** ^(To perform a backup operation: **
      -**
    1. tdsqlite3_backup_init() is called once to initialize the +**
    2. sqlite3_backup_init() is called once to initialize the ** backup, -**
    3. tdsqlite3_backup_step() is called one or more times to transfer +**
    4. sqlite3_backup_step() is called one or more times to transfer ** the data between the two databases, and finally -**
    5. tdsqlite3_backup_finish() is called to release all resources +**
    6. sqlite3_backup_finish() is called to release all resources ** associated with the backup operation. **
    )^ -** There should be exactly one call to tdsqlite3_backup_finish() for each -** successful call to tdsqlite3_backup_init(). +** There should be exactly one call to sqlite3_backup_finish() for each +** successful call to sqlite3_backup_init(). ** -** [[tdsqlite3_backup_init()]] tdsqlite3_backup_init() +** [[sqlite3_backup_init()]] sqlite3_backup_init() ** -** ^The D and N arguments to tdsqlite3_backup_init(D,N,S,M) are the +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the ** [database connection] associated with the destination database ** and the database name, respectively. ** ^The database name is "main" for the main database, "temp" for the ** temporary database, or the name specified after the AS keyword in ** an [ATTACH] statement for an attached database. ** ^The S and M arguments passed to -** tdsqlite3_backup_init(D,N,S,M) identify the [database connection] +** sqlite3_backup_init(D,N,S,M) identify the [database connection] ** and database name of the source database, respectively. ** ^The source and destination [database connections] (parameters S and D) -** must be different or else tdsqlite3_backup_init(D,N,S,M) will fail with +** must be different or else sqlite3_backup_init(D,N,S,M) will fail with ** an error. ** -** ^A call to tdsqlite3_backup_init() will fail, returning NULL, if +** ^A call to sqlite3_backup_init() will fail, returning NULL, if ** there is already a read or read-write transaction open on the ** destination database. ** -** ^If an error occurs within tdsqlite3_backup_init(D,N,S,M), then NULL is +** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is ** returned and an error code and error message are stored in the ** destination [database connection] D. -** ^The error code and message for the failed call to tdsqlite3_backup_init() -** can be retrieved using the [tdsqlite3_errcode()], [tdsqlite3_errmsg()], and/or -** [tdsqlite3_errmsg16()] functions. -** ^A successful call to tdsqlite3_backup_init() returns a pointer to an -** [tdsqlite3_backup] object. -** ^The [tdsqlite3_backup] object may be used with the tdsqlite3_backup_step() and -** tdsqlite3_backup_finish() functions to perform the specified backup +** ^The error code and message for the failed call to sqlite3_backup_init() +** can be retrieved using the [sqlite3_errcode()], [sqlite3_errmsg()], and/or +** [sqlite3_errmsg16()] functions. +** ^A successful call to sqlite3_backup_init() returns a pointer to an +** [sqlite3_backup] object. +** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and +** sqlite3_backup_finish() functions to perform the specified backup ** operation. ** -** [[tdsqlite3_backup_step()]] tdsqlite3_backup_step() +** [[sqlite3_backup_step()]] sqlite3_backup_step() ** -** ^Function tdsqlite3_backup_step(B,N) will copy up to N pages between -** the source and destination databases specified by [tdsqlite3_backup] object B. +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** the source and destination databases specified by [sqlite3_backup] object B. ** ^If N is negative, all remaining source pages are copied. -** ^If tdsqlite3_backup_step(B,N) successfully copies N pages and there +** ^If sqlite3_backup_step(B,N) successfully copies N pages and there ** are still more pages to be copied, then the function returns [SQLITE_OK]. -** ^If tdsqlite3_backup_step(B,N) successfully finishes copying all pages +** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages ** from source to destination, then it returns [SQLITE_DONE]. -** ^If an error occurs while running tdsqlite3_backup_step(B,N), +** ^If an error occurs while running sqlite3_backup_step(B,N), ** then an [error code] is returned. ^As well as [SQLITE_OK] and -** [SQLITE_DONE], a call to tdsqlite3_backup_step() may return [SQLITE_READONLY], +** [SQLITE_DONE], a call to sqlite3_backup_step() may return [SQLITE_READONLY], ** [SQLITE_NOMEM], [SQLITE_BUSY], [SQLITE_LOCKED], or an ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX] extended error code. ** -** ^(The tdsqlite3_backup_step() might return [SQLITE_READONLY] if +** ^(The sqlite3_backup_step() might return [SQLITE_READONLY] if **
      **
    1. the destination database was opened read-only, or **
    2. the destination database is using write-ahead-log journaling @@ -9542,76 +9542,76 @@ typedef struct tdsqlite3_backup tdsqlite3_backup; ** destination and source page sizes differ. **
    )^ ** -** ^If tdsqlite3_backup_step() cannot obtain a required file-system lock, then -** the [tdsqlite3_busy_handler | busy-handler function] +** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then +** the [sqlite3_busy_handler | busy-handler function] ** is invoked (if one is specified). ^If the ** busy-handler returns non-zero before the lock is available, then ** [SQLITE_BUSY] is returned to the caller. ^In this case the call to -** tdsqlite3_backup_step() can be retried later. ^If the source +** sqlite3_backup_step() can be retried later. ^If the source ** [database connection] -** is being used to write to the source database when tdsqlite3_backup_step() +** is being used to write to the source database when sqlite3_backup_step() ** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this -** case the call to tdsqlite3_backup_step() can be retried later on. ^(If +** case the call to sqlite3_backup_step() can be retried later on. ^(If ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or ** [SQLITE_READONLY] is returned, then -** there is no point in retrying the call to tdsqlite3_backup_step(). These +** there is no point in retrying the call to sqlite3_backup_step(). These ** errors are considered fatal.)^ The application must accept ** that the backup operation has failed and pass the backup operation handle -** to the tdsqlite3_backup_finish() to release associated resources. +** to the sqlite3_backup_finish() to release associated resources. ** -** ^The first call to tdsqlite3_backup_step() obtains an exclusive lock +** ^The first call to sqlite3_backup_step() obtains an exclusive lock ** on the destination file. ^The exclusive lock is not released until either -** tdsqlite3_backup_finish() is called or the backup operation is complete -** and tdsqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to -** tdsqlite3_backup_step() obtains a [shared lock] on the source database that -** lasts for the duration of the tdsqlite3_backup_step() call. +** sqlite3_backup_finish() is called or the backup operation is complete +** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to +** sqlite3_backup_step() obtains a [shared lock] on the source database that +** lasts for the duration of the sqlite3_backup_step() call. ** ^Because the source database is not locked between calls to -** tdsqlite3_backup_step(), the source database may be modified mid-way +** sqlite3_backup_step(), the source database may be modified mid-way ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically -** restarted by the next call to tdsqlite3_backup_step(). ^If the source +** restarted by the next call to sqlite3_backup_step(). ^If the source ** database is modified by the using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** -** [[tdsqlite3_backup_finish()]] tdsqlite3_backup_finish() +** [[sqlite3_backup_finish()]] sqlite3_backup_finish() ** -** When tdsqlite3_backup_step() has returned [SQLITE_DONE], or when the +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the ** application wishes to abandon the backup operation, the application -** should destroy the [tdsqlite3_backup] by passing it to tdsqlite3_backup_finish(). -** ^The tdsqlite3_backup_finish() interfaces releases all -** resources associated with the [tdsqlite3_backup] object. -** ^If tdsqlite3_backup_step() has not yet returned [SQLITE_DONE], then any +** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). +** ^The sqlite3_backup_finish() interfaces releases all +** resources associated with the [sqlite3_backup] object. +** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any ** active write-transaction on the destination database is rolled back. -** The [tdsqlite3_backup] object is invalid -** and may not be used following a call to tdsqlite3_backup_finish(). +** The [sqlite3_backup] object is invalid +** and may not be used following a call to sqlite3_backup_finish(). ** -** ^The value returned by tdsqlite3_backup_finish is [SQLITE_OK] if no -** tdsqlite3_backup_step() errors occurred, regardless or whether or not -** tdsqlite3_backup_step() completed. +** ^The value returned by sqlite3_backup_finish is [SQLITE_OK] if no +** sqlite3_backup_step() errors occurred, regardless or whether or not +** sqlite3_backup_step() completed. ** ^If an out-of-memory condition or IO error occurred during any prior -** tdsqlite3_backup_step() call on the same [tdsqlite3_backup] object, then -** tdsqlite3_backup_finish() returns the corresponding [error code]. +** sqlite3_backup_step() call on the same [sqlite3_backup] object, then +** sqlite3_backup_finish() returns the corresponding [error code]. ** -** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from tdsqlite3_backup_step() +** ^A return of [SQLITE_BUSY] or [SQLITE_LOCKED] from sqlite3_backup_step() ** is not a permanent error and does not affect the return value of -** tdsqlite3_backup_finish(). +** sqlite3_backup_finish(). ** -** [[tdsqlite3_backup_remaining()]] [[tdsqlite3_backup_pagecount()]] -** tdsqlite3_backup_remaining() and tdsqlite3_backup_pagecount() +** [[sqlite3_backup_remaining()]] [[sqlite3_backup_pagecount()]] +** sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** -** ^The tdsqlite3_backup_remaining() routine returns the number of pages still -** to be backed up at the conclusion of the most recent tdsqlite3_backup_step(). -** ^The tdsqlite3_backup_pagecount() routine returns the total number of pages +** ^The sqlite3_backup_remaining() routine returns the number of pages still +** to be backed up at the conclusion of the most recent sqlite3_backup_step(). +** ^The sqlite3_backup_pagecount() routine returns the total number of pages ** in the source database at the conclusion of the most recent -** tdsqlite3_backup_step(). +** sqlite3_backup_step(). ** ^(The values returned by these functions are only updated by -** tdsqlite3_backup_step(). If the source database is modified in a way that +** sqlite3_backup_step(). If the source database is modified in a way that ** changes the size of the source database or the number of pages remaining, -** those changes are not reflected in the output of tdsqlite3_backup_pagecount() -** and tdsqlite3_backup_remaining() until after the next -** tdsqlite3_backup_step().)^ +** those changes are not reflected in the output of sqlite3_backup_pagecount() +** and sqlite3_backup_remaining() until after the next +** sqlite3_backup_step().)^ ** ** Concurrent Usage of Database Handles ** @@ -9623,8 +9623,8 @@ typedef struct tdsqlite3_backup tdsqlite3_backup; ** ** However, the application must guarantee that the destination ** [database connection] is not passed to any other API (by any thread) after -** tdsqlite3_backup_init() is called and before the corresponding call to -** tdsqlite3_backup_finish(). SQLite does not currently check to see +** sqlite3_backup_init() is called and before the corresponding call to +** sqlite3_backup_finish(). SQLite does not currently check to see ** if the application incorrectly accesses the destination [database connection] ** and so no error code is reported, but the operations may malfunction ** nevertheless. Use of the destination database connection while a @@ -9635,29 +9635,29 @@ typedef struct tdsqlite3_backup tdsqlite3_backup; ** is not accessed while the backup is running. In practice this means ** that the application must guarantee that the disk file being ** backed up to is not accessed by any connection within the process, -** not just the specific connection that was passed to tdsqlite3_backup_init(). +** not just the specific connection that was passed to sqlite3_backup_init(). ** -** The [tdsqlite3_backup] object itself is partially threadsafe. Multiple -** threads may safely make multiple concurrent calls to tdsqlite3_backup_step(). -** However, the tdsqlite3_backup_remaining() and tdsqlite3_backup_pagecount() +** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** threads may safely make multiple concurrent calls to sqlite3_backup_step(). +** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the -** same time as another thread is invoking tdsqlite3_backup_step() it is +** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. */ -SQLITE_API tdsqlite3_backup *tdsqlite3_backup_init( - tdsqlite3 *pDest, /* Destination database handle */ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3 *pDest, /* Destination database handle */ const char *zDestName, /* Destination database name */ - tdsqlite3 *pSource, /* Source database handle */ + sqlite3 *pSource, /* Source database handle */ const char *zSourceName /* Source database name */ ); -SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage); -SQLITE_API int tdsqlite3_backup_finish(tdsqlite3_backup *p); -SQLITE_API int tdsqlite3_backup_remaining(tdsqlite3_backup *p); -SQLITE_API int tdsqlite3_backup_pagecount(tdsqlite3_backup *p); +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); /* ** CAPI3REF: Unlock Notification -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or @@ -9678,17 +9678,17 @@ SQLITE_API int tdsqlite3_backup_pagecount(tdsqlite3_backup *p); ** identity of the database connection (the blocking connection) that ** has locked the required resource is stored internally. ^After an ** application receives an SQLITE_LOCKED error, it may call the -** tdsqlite3_unlock_notify() method with the blocked connection handle as +** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked ** when the blocking connections current transaction is concluded. ^The -** callback is invoked from within the [tdsqlite3_step] or [tdsqlite3_close] +** callback is invoked from within the [sqlite3_step] or [sqlite3_close] ** call that concludes the blocking connection's transaction. ** -** ^(If tdsqlite3_unlock_notify() is called in a multi-threaded application, +** ^(If sqlite3_unlock_notify() is called in a multi-threaded application, ** there is a chance that the blocking connection will have already -** concluded its transaction by the time tdsqlite3_unlock_notify() is invoked. +** concluded its transaction by the time sqlite3_unlock_notify() is invoked. ** If this happens, then the specified callback is invoked immediately, -** from within the call to tdsqlite3_unlock_notify().)^ +** from within the call to sqlite3_unlock_notify().)^ ** ** ^If the blocked connection is attempting to obtain a write-lock on a ** shared-cache table, and more than one other connection currently holds @@ -9696,19 +9696,19 @@ SQLITE_API int tdsqlite3_backup_pagecount(tdsqlite3_backup *p); ** the other connections to use as the blocking connection. ** ** ^(There may be at most one unlock-notify callback registered by a -** blocked connection. If tdsqlite3_unlock_notify() is called when the +** blocked connection. If sqlite3_unlock_notify() is called when the ** blocked connection already has a registered unlock-notify callback, -** then the new callback replaces the old.)^ ^If tdsqlite3_unlock_notify() is +** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing ** unlock-notify callback is canceled. ^The blocked connections ** unlock-notify callback may also be canceled by closing the blocked -** connection using [tdsqlite3_close()]. +** connection using [sqlite3_close()]. ** ** The unlock-notify callback is not reentrant. If an application invokes -** any tdsqlite3_xxx API functions from within an unlock-notify callback, a +** any sqlite3_xxx API functions from within an unlock-notify callback, a ** crash or deadlock may be the result. ** -** ^Unless deadlock is detected (see below), tdsqlite3_unlock_notify() always +** ^Unless deadlock is detected (see below), sqlite3_unlock_notify() always ** returns SQLITE_OK. ** ** Callback Invocation Details @@ -9739,8 +9739,8 @@ SQLITE_API int tdsqlite3_backup_pagecount(tdsqlite3_backup *p); ** Y is waiting on connection X's transaction, then neither connection ** will proceed and the system may remain deadlocked indefinitely. ** -** To avoid this scenario, the tdsqlite3_unlock_notify() performs deadlock -** detection. ^If a given call to tdsqlite3_unlock_notify() would put the +** To avoid this scenario, the sqlite3_unlock_notify() performs deadlock +** detection. ^If a given call to sqlite3_unlock_notify() would put the ** system in a deadlocked state, then SQLITE_LOCKED is returned and no ** unlock-notify callback is registered. The system is said to be in ** a deadlocked state if connection A has registered for an unlock-notify @@ -9754,24 +9754,24 @@ SQLITE_API int tdsqlite3_backup_pagecount(tdsqlite3_backup *p); ** ** The "DROP TABLE" Exception ** -** When a call to [tdsqlite3_step()] returns SQLITE_LOCKED, it is almost -** always appropriate to call tdsqlite3_unlock_notify(). There is however, +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** always appropriate to call sqlite3_unlock_notify(). There is however, ** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, ** SQLite checks if there are any currently executing SELECT statements ** that belong to the same connection. If there are, SQLITE_LOCKED is ** returned. In this case there is no "blocking connection", so invoking -** tdsqlite3_unlock_notify() results in the unlock-notify callback being +** sqlite3_unlock_notify() results in the unlock-notify callback being ** invoked immediately. If the application then re-attempts the "DROP TABLE" ** or "DROP INDEX" query, an infinite loop might be the result. ** ** One way around this problem is to check the extended error code returned -** by an tdsqlite3_step() call. ^(If there is a blocking connection, then the +** by an sqlite3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in ** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ -SQLITE_API int tdsqlite3_unlock_notify( - tdsqlite3 *pBlocked, /* Waiting connection */ +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *pBlocked, /* Waiting connection */ void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ void *pNotifyArg /* Argument to pass to xNotify */ ); @@ -9780,82 +9780,82 @@ SQLITE_API int tdsqlite3_unlock_notify( /* ** CAPI3REF: String Comparison ** -** ^The [tdsqlite3_stricmp()] and [tdsqlite3_strnicmp()] APIs allow applications +** ^The [sqlite3_stricmp()] and [sqlite3_strnicmp()] APIs allow applications ** and extensions to compare the contents of two buffers containing UTF-8 ** strings in a case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ -SQLITE_API int tdsqlite3_stricmp(const char *, const char *); -SQLITE_API int tdsqlite3_strnicmp(const char *, const char *, int); +SQLITE_API int sqlite3_stricmp(const char *, const char *); +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); /* ** CAPI3REF: String Globbing * -** ^The [tdsqlite3_strglob(P,X)] interface returns zero if and only if +** ^The [sqlite3_strglob(P,X)] interface returns zero if and only if ** string X matches the [GLOB] pattern P. ** ^The definition of [GLOB] pattern matching used in -** [tdsqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the -** SQL dialect understood by SQLite. ^The [tdsqlite3_strglob(P,X)] function +** [sqlite3_strglob(P,X)] is the same as for the "X GLOB P" operator in the +** SQL dialect understood by SQLite. ^The [sqlite3_strglob(P,X)] function ** is case sensitive. ** ** Note that this routine returns zero on a match and non-zero if the strings -** do not match, the same as [tdsqlite3_stricmp()] and [tdsqlite3_strnicmp()]. +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. ** -** See also: [tdsqlite3_strlike()]. +** See also: [sqlite3_strlike()]. */ -SQLITE_API int tdsqlite3_strglob(const char *zGlob, const char *zStr); +SQLITE_API int sqlite3_strglob(const char *zGlob, const char *zStr); /* ** CAPI3REF: String LIKE Matching * -** ^The [tdsqlite3_strlike(P,X,E)] interface returns zero if and only if +** ^The [sqlite3_strlike(P,X,E)] interface returns zero if and only if ** string X matches the [LIKE] pattern P with escape character E. ** ^The definition of [LIKE] pattern matching used in -** [tdsqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E" +** [sqlite3_strlike(P,X,E)] is the same as for the "X LIKE P ESCAPE E" ** operator in the SQL dialect understood by SQLite. ^For "X LIKE P" without -** the ESCAPE clause, set the E parameter of [tdsqlite3_strlike(P,X,E)] to 0. -** ^As with the LIKE operator, the [tdsqlite3_strlike(P,X,E)] function is case +** the ESCAPE clause, set the E parameter of [sqlite3_strlike(P,X,E)] to 0. +** ^As with the LIKE operator, the [sqlite3_strlike(P,X,E)] function is case ** insensitive - equivalent upper and lower case ASCII characters match ** one another. ** -** ^The [tdsqlite3_strlike(P,X,E)] function matches Unicode characters, though +** ^The [sqlite3_strlike(P,X,E)] function matches Unicode characters, though ** only ASCII characters are case folded. ** ** Note that this routine returns zero on a match and non-zero if the strings -** do not match, the same as [tdsqlite3_stricmp()] and [tdsqlite3_strnicmp()]. +** do not match, the same as [sqlite3_stricmp()] and [sqlite3_strnicmp()]. ** -** See also: [tdsqlite3_strglob()]. +** See also: [sqlite3_strglob()]. */ -SQLITE_API int tdsqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); +SQLITE_API int sqlite3_strlike(const char *zGlob, const char *zStr, unsigned int cEsc); /* ** CAPI3REF: Error Logging Interface ** -** ^The [tdsqlite3_log()] interface writes a message into the [error log] -** established by the [SQLITE_CONFIG_LOG] option to [tdsqlite3_config()]. +** ^The [sqlite3_log()] interface writes a message into the [error log] +** established by the [SQLITE_CONFIG_LOG] option to [sqlite3_config()]. ** ^If logging is enabled, the zFormat string and subsequent arguments are -** used with [tdsqlite3_snprintf()] to generate the final output string. +** used with [sqlite3_snprintf()] to generate the final output string. ** -** The tdsqlite3_log() interface is intended for use by extensions such as +** The sqlite3_log() interface is intended for use by extensions such as ** virtual tables, collating functions, and SQL functions. While there is -** nothing to prevent an application from calling tdsqlite3_log(), doing so +** nothing to prevent an application from calling sqlite3_log(), doing so ** is considered bad form. ** ** The zFormat string must not be NULL. ** -** To avoid deadlocks and other threading problems, the tdsqlite3_log() routine +** To avoid deadlocks and other threading problems, the sqlite3_log() routine ** will not use dynamically allocated memory. The log message is stored in ** a fixed-length buffer on the stack. If the log message is longer than ** a few hundred characters, it will be truncated to the length of the ** buffer. */ -SQLITE_API void tdsqlite3_log(int iErrCode, const char *zFormat, ...); +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...); /* ** CAPI3REF: Write-Ahead Log Commit Hook -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The [tdsqlite3_wal_hook()] function is used to register a callback that +** ^The [sqlite3_wal_hook()] function is used to register a callback that ** is invoked each time data is committed to a database in wal mode. ** ** ^(The callback is invoked by SQLite after the commit has taken place and @@ -9863,7 +9863,7 @@ SQLITE_API void tdsqlite3_log(int iErrCode, const char *zFormat, ...); ** may read, write or [checkpoint] the database as required. ** ** ^The first parameter passed to the callback function when it is invoked -** is a copy of the third parameter passed to tdsqlite3_wal_hook() when +** is a copy of the third parameter passed to sqlite3_wal_hook() when ** registering the callback. ^The second is a copy of the database handle. ** ^The third parameter is the name of the database that was written to - ** either "main" or the name of an [ATTACH]-ed database. ^The fourth parameter @@ -9879,24 +9879,24 @@ SQLITE_API void tdsqlite3_log(int iErrCode, const char *zFormat, ...); ** are undefined. ** ** A single database handle may have at most a single write-ahead log callback -** registered at one time. ^Calling [tdsqlite3_wal_hook()] replaces any +** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any ** previously registered write-ahead log callback. ^Note that the -** [tdsqlite3_wal_autocheckpoint()] interface and the -** [wal_autocheckpoint pragma] both invoke [tdsqlite3_wal_hook()] and will -** overwrite any prior [tdsqlite3_wal_hook()] settings. +** [sqlite3_wal_autocheckpoint()] interface and the +** [wal_autocheckpoint pragma] both invoke [sqlite3_wal_hook()] and will +** overwrite any prior [sqlite3_wal_hook()] settings. */ -SQLITE_API void *tdsqlite3_wal_hook( - tdsqlite3*, - int(*)(void *,tdsqlite3*,const char*,int), +SQLITE_API void *sqlite3_wal_hook( + sqlite3*, + int(*)(void *,sqlite3*,const char*,int), void* ); /* ** CAPI3REF: Configure an auto-checkpoint -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^The [tdsqlite3_wal_autocheckpoint(D,N)] is a wrapper around -** [tdsqlite3_wal_hook()] that causes any database on [database connection] D +** ^The [sqlite3_wal_autocheckpoint(D,N)] is a wrapper around +** [sqlite3_wal_hook()] that causes any database on [database connection] D ** to automatically [checkpoint] ** after committing a transaction if there are N or ** more frames in the [write-ahead log] file. ^Passing zero or @@ -9904,15 +9904,15 @@ SQLITE_API void *tdsqlite3_wal_hook( ** checkpoints entirely. ** ** ^The callback registered by this function replaces any existing callback -** registered using [tdsqlite3_wal_hook()]. ^Likewise, registering a callback -** using [tdsqlite3_wal_hook()] disables the automatic checkpoint mechanism +** registered using [sqlite3_wal_hook()]. ^Likewise, registering a callback +** using [sqlite3_wal_hook()] disables the automatic checkpoint mechanism ** configured by this function. ** ** ^The [wal_autocheckpoint pragma] can be used to invoke this interface ** from SQL. ** ** ^Checkpoints initiated by this mechanism are -** [tdsqlite3_wal_checkpoint_v2|PASSIVE]. +** [sqlite3_wal_checkpoint_v2|PASSIVE]. ** ** ^Every new [database connection] defaults to having the auto-checkpoint ** enabled with a threshold of 1000 or [SQLITE_DEFAULT_WAL_AUTOCHECKPOINT] @@ -9920,35 +9920,35 @@ SQLITE_API void *tdsqlite3_wal_hook( ** is only necessary if the default setting is found to be suboptimal ** for a particular application. */ -SQLITE_API int tdsqlite3_wal_autocheckpoint(tdsqlite3 *db, int N); +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int N); /* ** CAPI3REF: Checkpoint a database -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^(The tdsqlite3_wal_checkpoint(D,X) is equivalent to -** [tdsqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ +** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to +** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ ** -** In brief, tdsqlite3_wal_checkpoint(D,X) causes the content in the +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the ** [write-ahead log] for database X on [database connection] D to be ** transferred into the database file and for the write-ahead log to ** be reset. See the [checkpointing] documentation for addition ** information. ** ** This interface used to be the only way to cause a checkpoint to -** occur. But then the newer and more powerful [tdsqlite3_wal_checkpoint_v2()] +** occur. But then the newer and more powerful [sqlite3_wal_checkpoint_v2()] ** interface was added. This interface is retained for backwards ** compatibility and as a convenience for applications that need to manually ** start a callback but which do not need the full power (and corresponding -** complication) of [tdsqlite3_wal_checkpoint_v2()]. +** complication) of [sqlite3_wal_checkpoint_v2()]. */ -SQLITE_API int tdsqlite3_wal_checkpoint(tdsqlite3 *db, const char *zDb); +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Checkpoint a database -** METHOD: tdsqlite3 +** METHOD: sqlite3 ** -** ^(The tdsqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint +** ^(The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint ** operation on database X of [database connection] D in mode M. Status ** information is written back into integers pointed to by L and C.)^ ** ^(The M parameter must be a valid [checkpoint mode]:)^ @@ -9964,7 +9964,7 @@ SQLITE_API int tdsqlite3_wal_checkpoint(tdsqlite3 *db, const char *zDb); ** **
    SQLITE_CHECKPOINT_FULL
    ** ^This mode blocks (it invokes the -** [tdsqlite3_busy_handler|busy-handler callback]) until there is no +** [sqlite3_busy_handler|busy-handler callback]) until there is no ** database writer and all readers are reading from the most recent database ** snapshot. ^It then checkpoints all frames in the log file and syncs the ** database file. ^This mode blocks new database writers while it is pending, @@ -10029,15 +10029,15 @@ SQLITE_API int tdsqlite3_wal_checkpoint(tdsqlite3 *db, const char *zDb); ** attached database, SQLITE_ERROR is returned to the caller. ** ** ^Unless it returns SQLITE_MISUSE, -** the tdsqlite3_wal_checkpoint_v2() interface +** the sqlite3_wal_checkpoint_v2() interface ** sets the error information that is queried by -** [tdsqlite3_errcode()] and [tdsqlite3_errmsg()]. +** [sqlite3_errcode()] and [sqlite3_errmsg()]. ** ** ^The [PRAGMA wal_checkpoint] command can be used to invoke this interface ** from SQL. */ -SQLITE_API int tdsqlite3_wal_checkpoint_v2( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ const char *zDb, /* Name of attached database (or NULL) */ int eMode, /* SQLITE_CHECKPOINT_* value */ int *pnLog, /* OUT: Size of WAL log in frames */ @@ -10049,8 +10049,8 @@ SQLITE_API int tdsqlite3_wal_checkpoint_v2( ** KEYWORDS: {checkpoint mode} ** ** These constants define all valid values for the "checkpoint mode" passed -** as the third parameter to the [tdsqlite3_wal_checkpoint_v2()] interface. -** See the [tdsqlite3_wal_checkpoint_v2()] documentation for details on the +** as the third parameter to the [sqlite3_wal_checkpoint_v2()] interface. +** See the [sqlite3_wal_checkpoint_v2()] documentation for details on the ** meaning of each of these checkpoint modes. */ #define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */ @@ -10068,15 +10068,15 @@ SQLITE_API int tdsqlite3_wal_checkpoint_v2( ** If this interface is invoked outside the context of an xConnect or ** xCreate virtual table method then the behavior is undefined. ** -** In the call tdsqlite3_vtab_config(D,C,...) the D parameter is the +** In the call sqlite3_vtab_config(D,C,...) the D parameter is the ** [database connection] in which the virtual table is being created and ** which is passed in as the first argument to the [xConnect] or [xCreate] -** method that is invoking tdsqlite3_vtab_config(). The C parameter is one +** method that is invoking sqlite3_vtab_config(). The C parameter is one ** of the [virtual table configuration options]. The presence and meaning ** of parameters after C depend on which [virtual table configuration option] ** is used. */ -SQLITE_API int tdsqlite3_vtab_config(tdsqlite3*, int op, ...); +SQLITE_API int sqlite3_vtab_config(sqlite3*, int op, ...); /* ** CAPI3REF: Virtual Table Configuration Options @@ -10084,16 +10084,16 @@ SQLITE_API int tdsqlite3_vtab_config(tdsqlite3*, int op, ...); ** KEYWORDS: {virtual table configuration option} ** ** These macros define the various options to the -** [tdsqlite3_vtab_config()] interface that [virtual table] implementations +** [sqlite3_vtab_config()] interface that [virtual table] implementations ** can use to customize and optimize their behavior. ** **
    ** [[SQLITE_VTAB_CONSTRAINT_SUPPORT]] **
    SQLITE_VTAB_CONSTRAINT_SUPPORT
    **
    Calls of the form -** [tdsqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, +** [sqlite3_vtab_config](db,SQLITE_VTAB_CONSTRAINT_SUPPORT,X) are supported, ** where X is an integer. If X is zero, then the [virtual table] whose -** [xCreate] or [xConnect] method invoked [tdsqlite3_vtab_config()] does not +** [xCreate] or [xConnect] method invoked [sqlite3_vtab_config()] does not ** support constraints. In this configuration (which is the default) if ** a call to the [xUpdate] method returns [SQLITE_CONSTRAINT], then the entire ** statement is rolled back as if [ON CONFLICT | OR ABORT] had been @@ -10112,7 +10112,7 @@ SQLITE_API int tdsqlite3_vtab_config(tdsqlite3*, int op, ...); ** ** Virtual table implementations that are required to handle OR REPLACE ** must do so within the [xUpdate] method. If a call to the -** [tdsqlite3_vtab_on_conflict()] function indicates that the current ON +** [sqlite3_vtab_on_conflict()] function indicates that the current ON ** CONFLICT policy is REPLACE, the virtual table implementation should ** silently replace the appropriate rows within the xUpdate callback and ** return SQLITE_OK. Or, if this is not possible, it may return @@ -10122,7 +10122,7 @@ SQLITE_API int tdsqlite3_vtab_config(tdsqlite3*, int op, ...); ** ** [[SQLITE_VTAB_DIRECTONLY]]
    SQLITE_VTAB_DIRECTONLY
    **
    Calls of the form -** [tdsqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the +** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the ** the [xConnect] or [xCreate] methods of a [virtual table] implmentation ** prohibits that virtual table from being used from within triggers and ** views. @@ -10130,7 +10130,7 @@ SQLITE_API int tdsqlite3_vtab_config(tdsqlite3*, int op, ...); ** ** [[SQLITE_VTAB_INNOCUOUS]]
    SQLITE_VTAB_INNOCUOUS
    **
    Calls of the form -** [tdsqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the +** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the ** the [xConnect] or [xCreate] methods of a [virtual table] implmentation ** identify that virtual table as being safe to use from within triggers ** and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the @@ -10154,26 +10154,26 @@ SQLITE_API int tdsqlite3_vtab_config(tdsqlite3*, int op, ...); ** of the SQL statement that triggered the call to the [xUpdate] method of the ** [virtual table]. */ -SQLITE_API int tdsqlite3_vtab_on_conflict(tdsqlite3 *); +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *); /* ** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE ** -** If the tdsqlite3_vtab_nochange(X) routine is called within the [xColumn] +** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn] ** method of a [virtual table], then it returns true if and only if the ** column is being fetched as part of an UPDATE operation during which the ** column value will not change. Applications might use this to substitute ** a return value that is less expensive to compute and that the corresponding ** [xUpdate] method understands as a "no-change" value. ** -** If the [xColumn] method calls tdsqlite3_vtab_nochange() and finds that +** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that ** the column is not changed by the UPDATE statement, then the xColumn ** method can optionally return without setting a result, without calling -** any of the [tdsqlite3_result_int|tdsqlite3_result_xxxxx() interfaces]. -** In that case, [tdsqlite3_value_nochange(X)] will return true for the +** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. +** In that case, [sqlite3_value_nochange(X)] will return true for the ** same column in the [xUpdate] method. */ -SQLITE_API int tdsqlite3_vtab_nochange(tdsqlite3_context*); +SQLITE_API int sqlite3_vtab_nochange(sqlite3_context*); /* ** CAPI3REF: Determine The Collation For a Virtual Table Constraint @@ -10181,29 +10181,29 @@ SQLITE_API int tdsqlite3_vtab_nochange(tdsqlite3_context*); ** This function may only be called from within a call to the [xBestIndex] ** method of a [virtual table]. ** -** The first argument must be the tdsqlite3_index_info object that is the +** The first argument must be the sqlite3_index_info object that is the ** first parameter to the xBestIndex() method. The second argument must be -** an index into the aConstraint[] array belonging to the tdsqlite3_index_info +** an index into the aConstraint[] array belonging to the sqlite3_index_info ** structure passed to xBestIndex. This function returns a pointer to a buffer ** containing the name of the collation sequence for the corresponding ** constraint. */ -SQLITE_API SQLITE_EXPERIMENTAL const char *tdsqlite3_vtab_collation(tdsqlite3_index_info*,int); +SQLITE_API SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); /* ** CAPI3REF: Conflict resolution modes ** KEYWORDS: {conflict resolution mode} ** -** These constants are returned by [tdsqlite3_vtab_on_conflict()] to +** These constants are returned by [sqlite3_vtab_on_conflict()] to ** inform a [virtual table] implementation what the [ON CONFLICT] mode ** is for the SQL statement being evaluated. ** ** Note that the [SQLITE_IGNORE] constant is also used as a potential -** return value from the [tdsqlite3_set_authorizer()] callback and that +** return value from the [sqlite3_set_authorizer()] callback and that ** [SQLITE_ABORT] is also a [result code]. */ #define SQLITE_ROLLBACK 1 -/* #define SQLITE_IGNORE 2 // Also used by tdsqlite3_authorizer() callback */ +/* #define SQLITE_IGNORE 2 // Also used by sqlite3_authorizer() callback */ #define SQLITE_FAIL 3 /* #define SQLITE_ABORT 4 // Also an error code */ #define SQLITE_REPLACE 5 @@ -10213,8 +10213,8 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *tdsqlite3_vtab_collation(tdsqlite3_in ** KEYWORDS: {scanstatus options} ** ** The following constants can be used for the T parameter to the -** [tdsqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a -** different metric for tdsqlite3_stmt_scanstatus() to return. +** [sqlite3_stmt_scanstatus(S,X,T,V)] interface. Each constant designates a +** different metric for sqlite3_stmt_scanstatus() to return. ** ** When the value returned to V is a string, space to hold that string is ** managed by the prepared statement S and will be automatically freed when @@ -10222,11 +10222,11 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *tdsqlite3_vtab_collation(tdsqlite3_in ** **
    ** [[SQLITE_SCANSTAT_NLOOP]]
    SQLITE_SCANSTAT_NLOOP
    -**
    ^The [tdsqlite3_int64] variable pointed to by the V parameter will be +**
    ^The [sqlite3_int64] variable pointed to by the V parameter will be ** set to the total number of times that the X-th loop has run.
    ** ** [[SQLITE_SCANSTAT_NVISIT]]
    SQLITE_SCANSTAT_NVISIT
    -**
    ^The [tdsqlite3_int64] variable pointed to by the V parameter will be set +**
    ^The [sqlite3_int64] variable pointed to by the V parameter will be set ** to the total number of rows examined by all iterations of the X-th loop.
    ** ** [[SQLITE_SCANSTAT_EST]]
    SQLITE_SCANSTAT_EST
    @@ -10264,7 +10264,7 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *tdsqlite3_vtab_collation(tdsqlite3_in /* ** CAPI3REF: Prepared Statement Scan Status -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** ** This interface returns information about the predicted and measured ** performance for pStmt. Advanced applications can use this @@ -10291,10 +10291,10 @@ SQLITE_API SQLITE_EXPERIMENTAL const char *tdsqlite3_vtab_collation(tdsqlite3_in ** as if the loop did not exist - it returns non-zero and leave the variable ** that pOut points to unchanged. ** -** See also: [tdsqlite3_stmt_scanstatus_reset()] +** See also: [sqlite3_stmt_scanstatus_reset()] */ -SQLITE_API int tdsqlite3_stmt_scanstatus( - tdsqlite3_stmt *pStmt, /* Prepared statement for which info desired */ +SQLITE_API int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ @@ -10302,24 +10302,24 @@ SQLITE_API int tdsqlite3_stmt_scanstatus( /* ** CAPI3REF: Zero Scan-Status Counters -** METHOD: tdsqlite3_stmt +** METHOD: sqlite3_stmt ** -** ^Zero all [tdsqlite3_stmt_scanstatus()] related event counters. +** ^Zero all [sqlite3_stmt_scanstatus()] related event counters. ** ** This API is only available if the library is built with pre-processor ** symbol [SQLITE_ENABLE_STMT_SCANSTATUS] defined. */ -SQLITE_API void tdsqlite3_stmt_scanstatus_reset(tdsqlite3_stmt*); +SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt*); /* ** CAPI3REF: Flush caches to disk mid-transaction ** ** ^If a write-transaction is open on [database connection] D when the -** [tdsqlite3_db_cacheflush(D)] interface invoked, any dirty +** [sqlite3_db_cacheflush(D)] interface invoked, any dirty ** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database -** file (page 1 is always "in use"). ^The [tdsqlite3_db_cacheflush(D)] +** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] ** interface flushes caches for all schemas - "main", "temp", and ** any [attached] databases. ** @@ -10336,12 +10336,12 @@ SQLITE_API void tdsqlite3_stmt_scanstatus_reset(tdsqlite3_stmt*); ** example an IO error or out-of-memory condition), then processing is ** abandoned and an SQLite [error code] is returned to the caller immediately. ** -** ^Otherwise, if no error occurs, [tdsqlite3_db_cacheflush()] returns SQLITE_OK. +** ^Otherwise, if no error occurs, [sqlite3_db_cacheflush()] returns SQLITE_OK. ** ** ^This function does not set the database handle error code or message -** returned by the [tdsqlite3_errcode()] and [tdsqlite3_errmsg()] functions. +** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. */ -SQLITE_API int tdsqlite3_db_cacheflush(tdsqlite3*); +SQLITE_API int sqlite3_db_cacheflush(sqlite3*); /* ** CAPI3REF: The pre-update hook. @@ -10349,15 +10349,15 @@ SQLITE_API int tdsqlite3_db_cacheflush(tdsqlite3*); ** ^These interfaces are only available if SQLite is compiled using the ** [SQLITE_ENABLE_PREUPDATE_HOOK] compile-time option. ** -** ^The [tdsqlite3_preupdate_hook()] interface registers a callback function +** ^The [sqlite3_preupdate_hook()] interface registers a callback function ** that is invoked prior to each [INSERT], [UPDATE], and [DELETE] operation ** on a database table. ** ^At most one preupdate hook may be registered at a time on a single -** [database connection]; each call to [tdsqlite3_preupdate_hook()] overrides +** [database connection]; each call to [sqlite3_preupdate_hook()] overrides ** the previous setting. -** ^The preupdate hook is disabled by invoking [tdsqlite3_preupdate_hook()] +** ^The preupdate hook is disabled by invoking [sqlite3_preupdate_hook()] ** with a NULL pointer as the second parameter. -** ^The third parameter to [tdsqlite3_preupdate_hook()] is passed through as +** ^The third parameter to [sqlite3_preupdate_hook()] is passed through as ** the first parameter to callbacks. ** ** ^The preupdate hook only fires for changes to real database tables; the @@ -10387,8 +10387,8 @@ SQLITE_API int tdsqlite3_db_cacheflush(tdsqlite3*); ** function is not defined for operations on WITHOUT ROWID tables, or for ** INSERT operations on rowid tables. ** -** The [tdsqlite3_preupdate_old()], [tdsqlite3_preupdate_new()], -** [tdsqlite3_preupdate_count()], and [tdsqlite3_preupdate_depth()] interfaces +** The [sqlite3_preupdate_old()], [sqlite3_preupdate_new()], +** [sqlite3_preupdate_count()], and [sqlite3_preupdate_depth()] interfaces ** provide additional information about a preupdate event. These routines ** may only be called from within a preupdate callback. Invoking any of ** these routines from outside of a preupdate callback or with a @@ -10396,53 +10396,53 @@ SQLITE_API int tdsqlite3_db_cacheflush(tdsqlite3*); ** to the preupdate callback results in undefined and probably undesirable ** behavior. ** -** ^The [tdsqlite3_preupdate_count(D)] interface returns the number of columns +** ^The [sqlite3_preupdate_count(D)] interface returns the number of columns ** in the row that is being inserted, updated, or deleted. ** -** ^The [tdsqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to -** a [protected tdsqlite3_value] that contains the value of the Nth column of +** ^The [sqlite3_preupdate_old(D,N,P)] interface writes into P a pointer to +** a [protected sqlite3_value] that contains the value of the Nth column of ** the table row before it is updated. The N parameter must be between 0 ** and one less than the number of columns or the behavior will be ** undefined. This must only be used within SQLITE_UPDATE and SQLITE_DELETE ** preupdate callbacks; if it is used by an SQLITE_INSERT callback then the -** behavior is undefined. The [tdsqlite3_value] that P points to +** behavior is undefined. The [sqlite3_value] that P points to ** will be destroyed when the preupdate callback returns. ** -** ^The [tdsqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to -** a [protected tdsqlite3_value] that contains the value of the Nth column of +** ^The [sqlite3_preupdate_new(D,N,P)] interface writes into P a pointer to +** a [protected sqlite3_value] that contains the value of the Nth column of ** the table row after it is updated. The N parameter must be between 0 ** and one less than the number of columns or the behavior will be ** undefined. This must only be used within SQLITE_INSERT and SQLITE_UPDATE ** preupdate callbacks; if it is used by an SQLITE_DELETE callback then the -** behavior is undefined. The [tdsqlite3_value] that P points to +** behavior is undefined. The [sqlite3_value] that P points to ** will be destroyed when the preupdate callback returns. ** -** ^The [tdsqlite3_preupdate_depth(D)] interface returns 0 if the preupdate +** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate ** callback was invoked as a result of a direct insert, update, or delete ** operation; or 1 for inserts, updates, or deletes invoked by top-level ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** -** See also: [tdsqlite3_update_hook()] +** See also: [sqlite3_update_hook()] */ #if defined(SQLITE_ENABLE_PREUPDATE_HOOK) -SQLITE_API void *tdsqlite3_preupdate_hook( - tdsqlite3 *db, +SQLITE_API void *sqlite3_preupdate_hook( + sqlite3 *db, void(*xPreUpdate)( void *pCtx, /* Copy of third arg to preupdate_hook() */ - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ int op, /* SQLITE_UPDATE, DELETE or INSERT */ char const *zDb, /* Database name */ char const *zName, /* Table name */ - tdsqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ - tdsqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ + sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ + sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ ), void* ); -SQLITE_API int tdsqlite3_preupdate_old(tdsqlite3 *, int, tdsqlite3_value **); -SQLITE_API int tdsqlite3_preupdate_count(tdsqlite3 *); -SQLITE_API int tdsqlite3_preupdate_depth(tdsqlite3 *); -SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *, int, tdsqlite3_value **); +SQLITE_API int sqlite3_preupdate_old(sqlite3 *, int, sqlite3_value **); +SQLITE_API int sqlite3_preupdate_count(sqlite3 *); +SQLITE_API int sqlite3_preupdate_depth(sqlite3 *); +SQLITE_API int sqlite3_preupdate_new(sqlite3 *, int, sqlite3_value **); #endif /* @@ -10451,15 +10451,15 @@ SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *, int, tdsqlite3_value **); ** ^Attempt to return the underlying operating system error code or error ** number that caused the most recent I/O error or failure to open a file. ** The return value is OS-dependent. For example, on unix systems, after -** [tdsqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be +** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be ** called to get back the underlying "errno" that caused the problem, such ** as ENOSPC, EAUTH, EISDIR, and so forth. */ -SQLITE_API int tdsqlite3_system_errno(tdsqlite3*); +SQLITE_API int sqlite3_system_errno(sqlite3*); /* ** CAPI3REF: Database Snapshot -** KEYWORDS: {snapshot} {tdsqlite3_snapshot} +** KEYWORDS: {snapshot} {sqlite3_snapshot} ** ** An instance of the snapshot object records the state of a [WAL mode] ** database for some specific point in history. @@ -10472,29 +10472,29 @@ SQLITE_API int tdsqlite3_system_errno(tdsqlite3*); ** Subsequent changes to the database from other connections are not seen ** by the reader until a new read transaction is started. ** -** The tdsqlite3_snapshot object records state information about an historical +** The sqlite3_snapshot object records state information about an historical ** version of the database file so that it is possible to later open a new read ** transaction that sees that historical version of the database rather than ** the most recent version. */ -typedef struct tdsqlite3_snapshot { +typedef struct sqlite3_snapshot { unsigned char hidden[48]; -} tdsqlite3_snapshot; +} sqlite3_snapshot; /* ** CAPI3REF: Record A Database Snapshot -** CONSTRUCTOR: tdsqlite3_snapshot +** CONSTRUCTOR: sqlite3_snapshot ** -** ^The [tdsqlite3_snapshot_get(D,S,P)] interface attempts to make a -** new [tdsqlite3_snapshot] object that records the current state of +** ^The [sqlite3_snapshot_get(D,S,P)] interface attempts to make a +** new [sqlite3_snapshot] object that records the current state of ** schema S in database connection D. ^On success, the -** [tdsqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly -** created [tdsqlite3_snapshot] object into *P and returns SQLITE_OK. +** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly +** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. ** If there is not already a read-transaction open on schema S when ** this function is called, one is opened automatically. ** ** The following must be true for this function to succeed. If any of -** the following statements are false when tdsqlite3_snapshot_get() is +** the following statements are false when sqlite3_snapshot_get() is ** called, SQLITE_ERROR is returned. The final value of *P is undefined ** in this case. ** @@ -10517,39 +10517,39 @@ typedef struct tdsqlite3_snapshot { ** database handle in autocommit mode but fails for some other reason, ** whether or not a read transaction is opened on schema S is undefined. ** -** The [tdsqlite3_snapshot] object returned from a successful call to -** [tdsqlite3_snapshot_get()] must be freed using [tdsqlite3_snapshot_free()] +** The [sqlite3_snapshot] object returned from a successful call to +** [sqlite3_snapshot_get()] must be freed using [sqlite3_snapshot_free()] ** to avoid a memory leak. ** -** The [tdsqlite3_snapshot_get()] interface is only available when the +** The [sqlite3_snapshot_get()] interface is only available when the ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ -SQLITE_API SQLITE_EXPERIMENTAL int tdsqlite3_snapshot_get( - tdsqlite3 *db, +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_get( + sqlite3 *db, const char *zSchema, - tdsqlite3_snapshot **ppSnapshot + sqlite3_snapshot **ppSnapshot ); /* ** CAPI3REF: Start a read transaction on an historical snapshot -** METHOD: tdsqlite3_snapshot +** METHOD: sqlite3_snapshot ** -** ^The [tdsqlite3_snapshot_open(D,S,P)] interface either starts a new read +** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read ** transaction or upgrades an existing one for schema S of ** [database connection] D such that the read transaction refers to ** historical [snapshot] P, rather than the most recent change to the -** database. ^The [tdsqlite3_snapshot_open()] interface returns SQLITE_OK +** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK ** on success or an appropriate [error code] if it fails. ** ** ^In order to succeed, the database connection must not be in -** [autocommit mode] when [tdsqlite3_snapshot_open(D,S,P)] is called. If there +** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there ** is already a read transaction open on schema S, then the database handle ** must have no active statements (SELECT statements that have been passed -** to tdsqlite3_step() but not tdsqlite3_reset() or tdsqlite3_finalize()). +** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). ** SQLITE_ERROR is returned if either of these conditions is violated, or ** if schema S does not exist, or if the snapshot object is invalid. ** -** ^A call to tdsqlite3_snapshot_open() will fail to open if the specified +** ^A call to sqlite3_snapshot_open() will fail to open if the specified ** snapshot has been overwritten by a [checkpoint]. In this case ** SQLITE_ERROR_SNAPSHOT is returned. ** @@ -10561,7 +10561,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int tdsqlite3_snapshot_get( ** read transaction is undefined. If SQLITE_OK is returned, then the ** read transaction is now open on database snapshot P. ** -** ^(A call to [tdsqlite3_snapshot_open(D,S,P)] will fail if the +** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the ** database connection D does not know that the database file for ** schema S is in [WAL mode]. A database connection might not know ** that the database file is in [WAL mode] if there has been no prior @@ -10570,40 +10570,40 @@ SQLITE_API SQLITE_EXPERIMENTAL int tdsqlite3_snapshot_get( ** (Hint: Run "[PRAGMA application_id]" against a newly opened ** database connection in order to make it ready to use snapshots.) ** -** The [tdsqlite3_snapshot_open()] interface is only available when the +** The [sqlite3_snapshot_open()] interface is only available when the ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ -SQLITE_API SQLITE_EXPERIMENTAL int tdsqlite3_snapshot_open( - tdsqlite3 *db, +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_open( + sqlite3 *db, const char *zSchema, - tdsqlite3_snapshot *pSnapshot + sqlite3_snapshot *pSnapshot ); /* ** CAPI3REF: Destroy a snapshot -** DESTRUCTOR: tdsqlite3_snapshot +** DESTRUCTOR: sqlite3_snapshot ** -** ^The [tdsqlite3_snapshot_free(P)] interface destroys [tdsqlite3_snapshot] P. -** The application must eventually free every [tdsqlite3_snapshot] object +** ^The [sqlite3_snapshot_free(P)] interface destroys [sqlite3_snapshot] P. +** The application must eventually free every [sqlite3_snapshot] object ** using this routine to avoid a memory leak. ** -** The [tdsqlite3_snapshot_free()] interface is only available when the +** The [sqlite3_snapshot_free()] interface is only available when the ** [SQLITE_ENABLE_SNAPSHOT] compile-time option is used. */ -SQLITE_API SQLITE_EXPERIMENTAL void tdsqlite3_snapshot_free(tdsqlite3_snapshot*); +SQLITE_API SQLITE_EXPERIMENTAL void sqlite3_snapshot_free(sqlite3_snapshot*); /* ** CAPI3REF: Compare the ages of two snapshot handles. -** METHOD: tdsqlite3_snapshot +** METHOD: sqlite3_snapshot ** -** The tdsqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages +** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages ** of two valid snapshot handles. ** ** If the two snapshot handles are not associated with the same database ** file, the result of the comparison is undefined. ** ** Additionally, the result of the comparison is only valid if both of the -** snapshot handles were obtained by calling tdsqlite3_snapshot_get() since the +** snapshot handles were obtained by calling sqlite3_snapshot_get() since the ** last time the wal file was deleted. The wal file is deleted when the ** database is changed back to rollback mode or when the number of database ** clients drops to zero. If either snapshot handle was obtained before the @@ -10617,26 +10617,26 @@ SQLITE_API SQLITE_EXPERIMENTAL void tdsqlite3_snapshot_free(tdsqlite3_snapshot*) ** This interface is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SNAPSHOT] option. */ -SQLITE_API SQLITE_EXPERIMENTAL int tdsqlite3_snapshot_cmp( - tdsqlite3_snapshot *p1, - tdsqlite3_snapshot *p2 +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_cmp( + sqlite3_snapshot *p1, + sqlite3_snapshot *p2 ); /* ** CAPI3REF: Recover snapshots from a wal file -** METHOD: tdsqlite3_snapshot +** METHOD: sqlite3_snapshot ** ** If a [WAL file] remains on disk after all database connections close ** (either through the use of the [SQLITE_FCNTL_PERSIST_WAL] [file control] ** or because the last process to have the database opened exited without -** calling [tdsqlite3_close()]) and a new connection is subsequently opened -** on that database and [WAL file], the [tdsqlite3_snapshot_open()] interface +** calling [sqlite3_close()]) and a new connection is subsequently opened +** on that database and [WAL file], the [sqlite3_snapshot_open()] interface ** will only be able to open the last transaction added to the WAL file ** even though the WAL file contains other valid transactions. ** ** This function attempts to scan the WAL file associated with database zDb ** of database handle db and make all valid snapshots available to -** tdsqlite3_snapshot_open(). It is an error if there is already a read +** sqlite3_snapshot_open(). It is an error if there is already a read ** transaction open on the database, or if the database is not a WAL mode ** database. ** @@ -10645,12 +10645,12 @@ SQLITE_API SQLITE_EXPERIMENTAL int tdsqlite3_snapshot_cmp( ** This interface is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SNAPSHOT] option. */ -SQLITE_API SQLITE_EXPERIMENTAL int tdsqlite3_snapshot_recover(tdsqlite3 *db, const char *zDb); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /* ** CAPI3REF: Serialize a database ** -** The tdsqlite3_serialize(D,S,P,F) interface returns a pointer to memory +** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory ** that is a serialization of the S database on [database connection] D. ** If P is not a NULL pointer, then the size of the database in bytes ** is written into *P. @@ -10660,56 +10660,56 @@ SQLITE_API SQLITE_EXPERIMENTAL int tdsqlite3_snapshot_recover(tdsqlite3 *db, con ** the serialization is the same sequence of bytes which would be written ** to disk if that database where backed up to disk. ** -** The usual case is that tdsqlite3_serialize() copies the serialization of -** the database into memory obtained from [tdsqlite3_malloc64()] and returns +** The usual case is that sqlite3_serialize() copies the serialization of +** the database into memory obtained from [sqlite3_malloc64()] and returns ** a pointer to that memory. The caller is responsible for freeing the ** returned value to avoid a memory leak. However, if the F argument ** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations -** are made, and the tdsqlite3_serialize() function will return a pointer +** are made, and the sqlite3_serialize() function will return a pointer ** to the contiguous memory representation of the database that SQLite ** is currently using for that database, or NULL if the no such contiguous ** memory representation of the database exists. A contiguous memory ** representation of the database will usually only exist if there has -** been a prior call to [tdsqlite3_deserialize(D,S,...)] with the same +** been a prior call to [sqlite3_deserialize(D,S,...)] with the same ** values of D and S. ** The size of the database is written into *P even if the ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. ** -** A call to tdsqlite3_serialize(D,S,P,F) might return NULL even if the +** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. ** ** This interface is only available if SQLite is compiled with the ** [SQLITE_ENABLE_DESERIALIZE] option. */ -SQLITE_API unsigned char *tdsqlite3_serialize( - tdsqlite3 *db, /* The database connection */ +SQLITE_API unsigned char *sqlite3_serialize( + sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */ - tdsqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */ + sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */ unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */ ); /* -** CAPI3REF: Flags for tdsqlite3_serialize +** CAPI3REF: Flags for sqlite3_serialize ** ** Zero or more of the following constants can be OR-ed together for -** the F argument to [tdsqlite3_serialize(D,S,P,F)]. +** the F argument to [sqlite3_serialize(D,S,P,F)]. ** -** SQLITE_SERIALIZE_NOCOPY means that [tdsqlite3_serialize()] will return +** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return ** a pointer to contiguous in-memory database that it is currently using, ** without making a copy of the database. If SQLite is not currently using ** a contiguous in-memory database, then this option causes -** [tdsqlite3_serialize()] to return a NULL pointer. SQLite will only be +** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be ** using a contiguous in-memory database if it has been initialized by a -** prior call to [tdsqlite3_deserialize()]. +** prior call to [sqlite3_deserialize()]. */ #define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */ /* ** CAPI3REF: Deserialize a database ** -** The tdsqlite3_deserialize(D,S,P,N,M,F) interface causes the +** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the ** [database connection] D to disconnect from database S and then ** reopen S as an in-memory database based on the serialization contained ** in P. The serialized database P is N bytes in size. M is the size of @@ -10719,45 +10719,45 @@ SQLITE_API unsigned char *tdsqlite3_serialize( ** size does not exceed M bytes. ** ** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will -** invoke tdsqlite3_free() on the serialization buffer when the database +** invoke sqlite3_free() on the serialization buffer when the database ** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then -** SQLite will try to increase the buffer size using tdsqlite3_realloc64() +** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. ** -** The tdsqlite3_deserialize() interface will fail with SQLITE_BUSY if the +** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. ** -** If tdsqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the +** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then -** [tdsqlite3_free()] is invoked on argument P prior to returning. +** [sqlite3_free()] is invoked on argument P prior to returning. ** ** This interface is only available if SQLite is compiled with the ** [SQLITE_ENABLE_DESERIALIZE] option. */ -SQLITE_API int tdsqlite3_deserialize( - tdsqlite3 *db, /* The database connection */ +SQLITE_API int sqlite3_deserialize( + sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ - tdsqlite3_int64 szDb, /* Number bytes in the deserialization */ - tdsqlite3_int64 szBuf, /* Total size of buffer pData[] */ + sqlite3_int64 szDb, /* Number bytes in the deserialization */ + sqlite3_int64 szBuf, /* Total size of buffer pData[] */ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ ); /* -** CAPI3REF: Flags for tdsqlite3_deserialize() +** CAPI3REF: Flags for sqlite3_deserialize() ** ** The following are allowed values for 6th argument (the F argument) to -** the [tdsqlite3_deserialize(D,S,P,N,M,F)] interface. +** the [sqlite3_deserialize(D,S,P,N,M,F)] interface. ** ** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization -** in the P argument is held in memory obtained from [tdsqlite3_malloc64()] +** in the P argument is held in memory obtained from [sqlite3_malloc64()] ** and that SQLite should take ownership of this memory and automatically ** free it when it has finished using it. Without this flag, the caller ** is responsible for freeing any dynamically allocated memory. ** ** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to -** grow the size of the database using calls to [tdsqlite3_realloc64()]. This +** grow the size of the database using calls to [sqlite3_realloc64()]. This ** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used. ** Without this flag, the deserialized database cannot increase in size beyond ** the number of bytes specified by the M parameter. @@ -10765,8 +10765,8 @@ SQLITE_API int tdsqlite3_deserialize( ** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database ** should be treated as read-only. */ -#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call tdsqlite3_free() on close */ -#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using tdsqlite3_realloc64() */ +#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ +#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ /* @@ -10782,7 +10782,7 @@ SQLITE_API int tdsqlite3_deserialize( #endif #endif /* SQLITE3_H */ -/******** Begin file tdsqlite3rtree.h *********/ +/******** Begin file sqlite3rtree.h *********/ /* ** 2010 August 30 ** @@ -10804,16 +10804,16 @@ SQLITE_API int tdsqlite3_deserialize( extern "C" { #endif -typedef struct tdsqlite3_rtree_geometry tdsqlite3_rtree_geometry; -typedef struct tdsqlite3_rtree_query_info tdsqlite3_rtree_query_info; +typedef struct sqlite3_rtree_geometry sqlite3_rtree_geometry; +typedef struct sqlite3_rtree_query_info sqlite3_rtree_query_info; /* The double-precision datatype used by RTree depends on the ** SQLITE_RTREE_INT_ONLY compile-time option. */ #ifdef SQLITE_RTREE_INT_ONLY - typedef tdsqlite3_int64 tdsqlite3_rtree_dbl; + typedef sqlite3_int64 sqlite3_rtree_dbl; #else - typedef double tdsqlite3_rtree_dbl; + typedef double sqlite3_rtree_dbl; #endif /* @@ -10822,10 +10822,10 @@ typedef struct tdsqlite3_rtree_query_info tdsqlite3_rtree_query_info; ** ** SELECT ... FROM WHERE MATCH $zGeom(... params ...) */ -SQLITE_API int tdsqlite3_rtree_geometry_callback( - tdsqlite3 *db, +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, const char *zGeom, - int (*xGeom)(tdsqlite3_rtree_geometry*, int, tdsqlite3_rtree_dbl*,int*), + int (*xGeom)(sqlite3_rtree_geometry*, int, sqlite3_rtree_dbl*,int*), void *pContext ); @@ -10834,10 +10834,10 @@ SQLITE_API int tdsqlite3_rtree_geometry_callback( ** A pointer to a structure of the following type is passed as the first ** argument to callbacks registered using rtree_geometry_callback(). */ -struct tdsqlite3_rtree_geometry { +struct sqlite3_rtree_geometry { void *pContext; /* Copy of pContext passed to s_r_g_c() */ int nParam; /* Size of array aParam[] */ - tdsqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ + sqlite3_rtree_dbl *aParam; /* Parameters passed to SQL geom function */ void *pUser; /* Callback implementation user data */ void (*xDelUser)(void *); /* Called by SQLite to clean up pUser */ }; @@ -10848,10 +10848,10 @@ struct tdsqlite3_rtree_geometry { ** ** SELECT ... FROM WHERE MATCH $zQueryFunc(... params ...) */ -SQLITE_API int tdsqlite3_rtree_query_callback( - tdsqlite3 *db, +SQLITE_API int sqlite3_rtree_query_callback( + sqlite3 *db, const char *zQueryFunc, - int (*xQueryFunc)(tdsqlite3_rtree_query_info*), + int (*xQueryFunc)(sqlite3_rtree_query_info*), void *pContext, void (*xDestructor)(void*) ); @@ -10860,34 +10860,34 @@ SQLITE_API int tdsqlite3_rtree_query_callback( /* ** A pointer to a structure of the following type is passed as the ** argument to scored geometry callback registered using -** tdsqlite3_rtree_query_callback(). +** sqlite3_rtree_query_callback(). ** ** Note that the first 5 fields of this structure are identical to -** tdsqlite3_rtree_geometry. This structure is a subclass of -** tdsqlite3_rtree_geometry. +** sqlite3_rtree_geometry. This structure is a subclass of +** sqlite3_rtree_geometry. */ -struct tdsqlite3_rtree_query_info { +struct sqlite3_rtree_query_info { void *pContext; /* pContext from when function registered */ int nParam; /* Number of function parameters */ - tdsqlite3_rtree_dbl *aParam; /* value of function parameters */ + sqlite3_rtree_dbl *aParam; /* value of function parameters */ void *pUser; /* callback can use this, if desired */ void (*xDelUser)(void*); /* function to free pUser */ - tdsqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ + sqlite3_rtree_dbl *aCoord; /* Coordinates of node or entry to check */ unsigned int *anQueue; /* Number of pending entries in the queue */ int nCoord; /* Number of coordinates */ int iLevel; /* Level of current node or entry */ int mxLevel; /* The largest iLevel value in the tree */ - tdsqlite3_int64 iRowid; /* Rowid for current entry */ - tdsqlite3_rtree_dbl rParentScore; /* Score of parent node */ + sqlite3_int64 iRowid; /* Rowid for current entry */ + sqlite3_rtree_dbl rParentScore; /* Score of parent node */ int eParentWithin; /* Visibility of parent node */ int eWithin; /* OUT: Visibility */ - tdsqlite3_rtree_dbl rScore; /* OUT: Write the score here */ + sqlite3_rtree_dbl rScore; /* OUT: Write the score here */ /* The following fields are only available in 3.8.11 and later */ - tdsqlite3_value **apSqlParam; /* Original SQL values of parameters */ + sqlite3_value **apSqlParam; /* Original SQL values of parameters */ }; /* -** Allowed values for tdsqlite3_rtree_query.eWithin and .eParentWithin. +** Allowed values for sqlite3_rtree_query.eWithin and .eParentWithin. */ #define NOT_WITHIN 0 /* Object completely outside of query region */ #define PARTLY_WITHIN 1 /* Object partially overlaps query region */ @@ -10900,8 +10900,8 @@ struct tdsqlite3_rtree_query_info { #endif /* ifndef _SQLITE3RTREE_H_ */ -/******** End of tdsqlite3rtree.h *********/ -/******** Begin file tdsqlite3session.h *********/ +/******** End of sqlite3rtree.h *********/ +/******** Begin file sqlite3session.h *********/ #if !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) #define __SQLITESESSION_H_ 1 @@ -10920,7 +10920,7 @@ extern "C" { ** An instance of this object is a [session] that can be used to ** record changes to a database. */ -typedef struct tdsqlite3_session tdsqlite3_session; +typedef struct sqlite3_session sqlite3_session; /* ** CAPI3REF: Changeset Iterator Handle @@ -10928,11 +10928,11 @@ typedef struct tdsqlite3_session tdsqlite3_session; ** An instance of this object acts as a cursor for iterating ** over the elements of a [changeset] or [patchset]. */ -typedef struct tdsqlite3_changeset_iter tdsqlite3_changeset_iter; +typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; /* ** CAPI3REF: Create A New Session Object -** CONSTRUCTOR: tdsqlite3_session +** CONSTRUCTOR: sqlite3_session ** ** Create a new session object attached to database handle db. If successful, ** a pointer to the new object is written to *ppSession and SQLITE_OK is @@ -10943,13 +10943,13 @@ typedef struct tdsqlite3_changeset_iter tdsqlite3_changeset_iter; ** database handle. ** ** Session objects created using this function should be deleted using the -** [tdsqlite3session_delete()] function before the database handle that they +** [sqlite3session_delete()] function before the database handle that they ** are attached to is itself closed. If the database handle is closed before ** the session object is deleted, then the results of calling any session -** module function, including [tdsqlite3session_delete()] on the session object +** module function, including [sqlite3session_delete()] on the session object ** are undefined. ** -** Because the session module uses the [tdsqlite3_preupdate_hook()] API, it +** Because the session module uses the [sqlite3_preupdate_hook()] API, it ** is not possible for an application to register a pre-update hook on a ** database handle that has one or more session objects attached. Nor is ** it possible to create a session object attached to a database handle for @@ -10961,36 +10961,36 @@ typedef struct tdsqlite3_changeset_iter tdsqlite3_changeset_iter; ** attached database. It is not an error if database zDb is not attached ** to the database when the session object is created. */ -SQLITE_API int tdsqlite3session_create( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3session_create( + sqlite3 *db, /* Database handle */ const char *zDb, /* Name of db (e.g. "main") */ - tdsqlite3_session **ppSession /* OUT: New session object */ + sqlite3_session **ppSession /* OUT: New session object */ ); /* ** CAPI3REF: Delete A Session Object -** DESTRUCTOR: tdsqlite3_session +** DESTRUCTOR: sqlite3_session ** ** Delete a session object previously allocated using -** [tdsqlite3session_create()]. Once a session object has been deleted, the +** [sqlite3session_create()]. Once a session object has been deleted, the ** results of attempting to use pSession with any other session module ** function are undefined. ** ** Session objects must be deleted before the database handle to which they ** are attached is closed. Refer to the documentation for -** [tdsqlite3session_create()] for details. +** [sqlite3session_create()] for details. */ -SQLITE_API void tdsqlite3session_delete(tdsqlite3_session *pSession); +SQLITE_API void sqlite3session_delete(sqlite3_session *pSession); /* ** CAPI3REF: Enable Or Disable A Session Object -** METHOD: tdsqlite3_session +** METHOD: sqlite3_session ** ** Enable or disable the recording of changes by a session object. When ** enabled, a session object records changes made to the database. When ** disabled - it does not. A newly created session object is enabled. -** Refer to the documentation for [tdsqlite3session_changeset()] for further +** Refer to the documentation for [sqlite3session_changeset()] for further ** details regarding how enabling and disabling a session object affects ** the eventual changesets. ** @@ -11001,11 +11001,11 @@ SQLITE_API void tdsqlite3session_delete(tdsqlite3_session *pSession); ** The return value indicates the final state of the session object: 0 if ** the session is disabled, or 1 if it is enabled. */ -SQLITE_API int tdsqlite3session_enable(tdsqlite3_session *pSession, int bEnable); +SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable); /* ** CAPI3REF: Set Or Clear the Indirect Change Flag -** METHOD: tdsqlite3_session +** METHOD: sqlite3_session ** ** Each change recorded by a session object is marked as either direct or ** indirect. A change is marked as indirect if either: @@ -11031,16 +11031,16 @@ SQLITE_API int tdsqlite3session_enable(tdsqlite3_session *pSession, int bEnable) ** The return value indicates the final state of the indirect flag: 0 if ** it is clear, or 1 if it is set. */ -SQLITE_API int tdsqlite3session_indirect(tdsqlite3_session *pSession, int bIndirect); +SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect); /* ** CAPI3REF: Attach A Table To A Session Object -** METHOD: tdsqlite3_session +** METHOD: sqlite3_session ** ** If argument zTab is not NULL, then it is the name of a table to attach ** to the session object passed as the first argument. All subsequent changes ** made to the table while the session object is enabled will be recorded. See -** documentation for [tdsqlite3session_changeset()] for further details. +** documentation for [sqlite3session_changeset()] for further details. ** ** Or, if argument zTab is NULL, then changes are recorded for all tables ** in the database. If additional tables are added to the database (by @@ -11075,30 +11075,30 @@ SQLITE_API int tdsqlite3session_indirect(tdsqlite3_session *pSession, int bIndir ** are recorded for rows for which (idx IS NULL) is true. However, for such ** rows a zero-length blob (SQL value X'') is stored in the changeset or ** patchset instead of a NULL value. This allows such changesets to be -** manipulated by legacy implementations of tdsqlite3changeset_invert(), +** manipulated by legacy implementations of sqlite3changeset_invert(), ** concat() and similar. ** -** The tdsqlite3changeset_apply() function automatically converts the +** The sqlite3changeset_apply() function automatically converts the ** zero-length blob back to a NULL value when updating the sqlite_stat1 -** table. However, if the application calls tdsqlite3changeset_new(), -** tdsqlite3changeset_old() or tdsqlite3changeset_conflict on a changeset +** table. However, if the application calls sqlite3changeset_new(), +** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset ** iterator directly (including on a changeset iterator passed to a ** conflict-handler callback) then the X'' value is returned. The application ** must translate X'' to NULL itself if required. ** ** Legacy (older than 3.22.0) versions of the sessions module cannot capture ** changes made to the sqlite_stat1 table. Legacy versions of the -** tdsqlite3changeset_apply() function silently ignore any modifications to the +** sqlite3changeset_apply() function silently ignore any modifications to the ** sqlite_stat1 table that are part of a changeset or patchset. */ -SQLITE_API int tdsqlite3session_attach( - tdsqlite3_session *pSession, /* Session object */ +SQLITE_API int sqlite3session_attach( + sqlite3_session *pSession, /* Session object */ const char *zTab /* Table name */ ); /* ** CAPI3REF: Set a table filter on a Session Object. -** METHOD: tdsqlite3_session +** METHOD: sqlite3_session ** ** The second argument (xFilter) is the "filter callback". For changes to rows ** in tables that are not attached to the Session object, the filter is called @@ -11106,8 +11106,8 @@ SQLITE_API int tdsqlite3session_attach( ** If xFilter returns 0, changes are not tracked. Note that once a table is ** attached, xFilter will not be called again. */ -SQLITE_API void tdsqlite3session_table_filter( - tdsqlite3_session *pSession, /* Session object */ +SQLITE_API void sqlite3session_table_filter( + sqlite3_session *pSession, /* Session object */ int(*xFilter)( void *pCtx, /* Copy of third arg to _filter_table() */ const char *zTab /* Table name */ @@ -11117,7 +11117,7 @@ SQLITE_API void tdsqlite3session_table_filter( /* ** CAPI3REF: Generate A Changeset From A Session Object -** METHOD: tdsqlite3_session +** METHOD: sqlite3_session ** ** Obtain a changeset containing changes to the tables attached to the ** session object passed as the first argument. If successful, @@ -11147,8 +11147,8 @@ SQLITE_API void tdsqlite3session_table_filter( ** DELETE change only. ** ** The contents of a changeset may be traversed using an iterator created -** using the [tdsqlite3changeset_start()] API. A changeset may be applied to -** a database with a compatible schema using the [tdsqlite3changeset_apply()] +** using the [sqlite3changeset_start()] API. A changeset may be applied to +** a database with a compatible schema using the [sqlite3changeset_apply()] ** API. ** ** Within a changeset generated by this function, all changes related to a @@ -11156,12 +11156,12 @@ SQLITE_API void tdsqlite3session_table_filter( ** a changeset or when applying a changeset to a database, all changes related ** to a single table are processed before moving on to the next table. Tables ** are sorted in the same order in which they were attached (or auto-attached) -** to the tdsqlite3_session object. The order in which the changes related to +** to the sqlite3_session object. The order in which the changes related to ** a single table are stored is undefined. ** ** Following a successful call to this function, it is the responsibility of ** the caller to eventually free the buffer that *ppChangeset points to using -** [tdsqlite3_free()]. +** [sqlite3_free()]. ** **

    Changeset Generation

    ** @@ -11209,7 +11209,7 @@ SQLITE_API void tdsqlite3session_table_filter( ** active, the resulting changeset will contain an UPDATE change instead of ** a DELETE and an INSERT. ** -** When a session object is disabled (see the [tdsqlite3session_enable()] API), +** When a session object is disabled (see the [sqlite3session_enable()] API), ** it does not accumulate records when rows are inserted, updated or deleted. ** This may appear to have some counter-intuitive effects if a single row ** is written to more than once during a session. For example, if a row @@ -11220,19 +11220,19 @@ SQLITE_API void tdsqlite3session_table_filter( ** another field of the same row is updated while the session is enabled, the ** resulting changeset will contain an UPDATE change that updates both fields. */ -SQLITE_API int tdsqlite3session_changeset( - tdsqlite3_session *pSession, /* Session object */ +SQLITE_API int sqlite3session_changeset( + sqlite3_session *pSession, /* Session object */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ); /* ** CAPI3REF: Load The Difference Between Tables Into A Session -** METHOD: tdsqlite3_session +** METHOD: sqlite3_session ** ** If it is not already attached to the session object passed as the first ** argument, this function attaches table zTbl in the same manner as the -** [tdsqlite3session_attach()] function. If zTbl does not exist, or if it +** [sqlite3session_attach()] function. If zTbl does not exist, or if it ** does not have a primary key, this function is a no-op (but does not return ** an error). ** @@ -11270,7 +11270,7 @@ SQLITE_API int tdsqlite3session_changeset( **
** ** To clarify, if this function is called and then a changeset constructed -** using [tdsqlite3session_changeset()], then after applying that changeset to +** using [sqlite3session_changeset()], then after applying that changeset to ** database zFrom the contents of the two compatible tables would be ** identical. ** @@ -11281,10 +11281,10 @@ SQLITE_API int tdsqlite3session_changeset( ** error code. In this case, if argument pzErrMsg is not NULL, *pzErrMsg ** may be set to point to a buffer containing an English language error ** message. It is the responsibility of the caller to free this buffer using -** tdsqlite3_free(). +** sqlite3_free(). */ -SQLITE_API int tdsqlite3session_diff( - tdsqlite3_session *pSession, +SQLITE_API int sqlite3session_diff( + sqlite3_session *pSession, const char *zFromDb, const char *zTbl, char **pzErrMsg @@ -11293,7 +11293,7 @@ SQLITE_API int tdsqlite3session_diff( /* ** CAPI3REF: Generate A Patchset From A Session Object -** METHOD: tdsqlite3_session +** METHOD: sqlite3_session ** ** The differences between a patchset and a changeset are that: ** @@ -11305,23 +11305,23 @@ SQLITE_API int tdsqlite3session_diff( ** ** ** A patchset blob may be used with up to date versions of all -** tdsqlite3changeset_xxx API functions except for tdsqlite3changeset_invert(), +** sqlite3changeset_xxx API functions except for sqlite3changeset_invert(), ** which returns SQLITE_CORRUPT if it is passed a patchset. Similarly, ** attempting to use a patchset blob with old versions of the -** tdsqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. +** sqlite3changeset_xxx APIs also provokes an SQLITE_CORRUPT error. ** ** Because the non-primary key "old.*" fields are omitted, no ** SQLITE_CHANGESET_DATA conflicts can be detected or reported if a patchset -** is passed to the tdsqlite3changeset_apply() API. Other conflict types work +** is passed to the sqlite3changeset_apply() API. Other conflict types work ** in the same way as for changesets. ** ** Changes within a patchset are ordered in the same way as for changesets -** generated by the tdsqlite3session_changeset() function (i.e. all changes for +** generated by the sqlite3session_changeset() function (i.e. all changes for ** a single table are grouped together, tables appear in the order in which ** they were attached to the session object). */ -SQLITE_API int tdsqlite3session_patchset( - tdsqlite3_session *pSession, /* Session object */ +SQLITE_API int sqlite3session_patchset( + sqlite3_session *pSession, /* Session object */ int *pnPatchset, /* OUT: Size of buffer at *ppPatchset */ void **ppPatchset /* OUT: Buffer containing patchset */ ); @@ -11334,18 +11334,18 @@ SQLITE_API int tdsqlite3session_patchset( ** more changes have been recorded, return zero. ** ** Even if this function returns zero, it is possible that calling -** [tdsqlite3session_changeset()] on the session handle may still return a +** [sqlite3session_changeset()] on the session handle may still return a ** changeset that contains no changes. This can happen when a row in ** an attached table is modified and then later on the original values ** are restored. However, if this function returns non-zero, then it is -** guaranteed that a call to tdsqlite3session_changeset() will return a +** guaranteed that a call to sqlite3session_changeset() will return a ** changeset containing zero changes. */ -SQLITE_API int tdsqlite3session_isempty(tdsqlite3_session *pSession); +SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession); /* ** CAPI3REF: Create An Iterator To Traverse A Changeset -** CONSTRUCTOR: tdsqlite3_changeset_iter +** CONSTRUCTOR: sqlite3_changeset_iter ** ** Create an iterator used to iterate through the contents of a changeset. ** If successful, *pp is set to point to the iterator handle and SQLITE_OK @@ -11356,20 +11356,20 @@ SQLITE_API int tdsqlite3session_isempty(tdsqlite3_session *pSession); ** iterator created by this function: ** **
    -**
  • [tdsqlite3changeset_next()] -**
  • [tdsqlite3changeset_op()] -**
  • [tdsqlite3changeset_new()] -**
  • [tdsqlite3changeset_old()] +**
  • [sqlite3changeset_next()] +**
  • [sqlite3changeset_op()] +**
  • [sqlite3changeset_new()] +**
  • [sqlite3changeset_old()] **
** ** It is the responsibility of the caller to eventually destroy the iterator -** by passing it to [tdsqlite3changeset_finalize()]. The buffer containing the +** by passing it to [sqlite3changeset_finalize()]. The buffer containing the ** changeset (pChangeset) must remain valid until after the iterator is ** destroyed. ** ** Assuming the changeset blob was created by one of the -** [tdsqlite3session_changeset()], [tdsqlite3changeset_concat()] or -** [tdsqlite3changeset_invert()] functions, all changes within the changeset +** [sqlite3session_changeset()], [sqlite3changeset_concat()] or +** [sqlite3changeset_invert()] functions, all changes within the changeset ** that apply to a single table are grouped together. This means that when ** an application iterates through a changeset using an iterator created by ** this function, all changes that relate to a single table are visited @@ -11377,34 +11377,34 @@ SQLITE_API int tdsqlite3session_isempty(tdsqlite3_session *pSession); ** the applies to table X, then one for table Y, and then later on visit ** another change for table X. ** -** The behavior of tdsqlite3changeset_start_v2() and its streaming equivalent +** The behavior of sqlite3changeset_start_v2() and its streaming equivalent ** may be modified by passing a combination of ** [SQLITE_CHANGESETSTART_INVERT | supported flags] as the 4th parameter. ** -** Note that the tdsqlite3changeset_start_v2() API is still experimental +** Note that the sqlite3changeset_start_v2() API is still experimental ** and therefore subject to change. */ -SQLITE_API int tdsqlite3changeset_start( - tdsqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ +SQLITE_API int sqlite3changeset_start( + sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ int nChangeset, /* Size of changeset blob in bytes */ void *pChangeset /* Pointer to blob containing changeset */ ); -SQLITE_API int tdsqlite3changeset_start_v2( - tdsqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ +SQLITE_API int sqlite3changeset_start_v2( + sqlite3_changeset_iter **pp, /* OUT: New changeset iterator handle */ int nChangeset, /* Size of changeset blob in bytes */ void *pChangeset, /* Pointer to blob containing changeset */ int flags /* SESSION_CHANGESETSTART_* flags */ ); /* -** CAPI3REF: Flags for tdsqlite3changeset_start_v2 +** CAPI3REF: Flags for sqlite3changeset_start_v2 ** ** The following flags may passed via the 4th parameter to -** [tdsqlite3changeset_start_v2] and [tdsqlite3changeset_start_v2_strm]: +** [sqlite3changeset_start_v2] and [sqlite3changeset_start_v2_strm]: ** **
SQLITE_CHANGESETAPPLY_INVERT
** Invert the changeset while iterating through it. This is equivalent to -** inverting a changeset using tdsqlite3changeset_invert() before applying it. +** inverting a changeset using sqlite3changeset_invert() before applying it. ** It is an error to specify this flag with a patchset. */ #define SQLITE_CHANGESETSTART_INVERT 0x0002 @@ -11412,20 +11412,20 @@ SQLITE_API int tdsqlite3changeset_start_v2( /* ** CAPI3REF: Advance A Changeset Iterator -** METHOD: tdsqlite3_changeset_iter +** METHOD: sqlite3_changeset_iter ** ** This function may only be used with iterators created by the function -** [tdsqlite3changeset_start()]. If it is called on an iterator passed to -** a conflict-handler callback by [tdsqlite3changeset_apply()], SQLITE_MISUSE +** [sqlite3changeset_start()]. If it is called on an iterator passed to +** a conflict-handler callback by [sqlite3changeset_apply()], SQLITE_MISUSE ** is returned and the call has no effect. ** -** Immediately after an iterator is created by tdsqlite3changeset_start(), it +** Immediately after an iterator is created by sqlite3changeset_start(), it ** does not point to any change in the changeset. Assuming the changeset ** is not empty, the first call to this function advances the iterator to ** point to the first change in the changeset. Each subsequent call advances ** the iterator to point to the next change in the changeset (if any). If ** no error occurs and the iterator points to a valid change after a call -** to tdsqlite3changeset_next() has advanced it, SQLITE_ROW is returned. +** to sqlite3changeset_next() has advanced it, SQLITE_ROW is returned. ** Otherwise, if all changes in the changeset have already been visited, ** SQLITE_DONE is returned. ** @@ -11433,27 +11433,27 @@ SQLITE_API int tdsqlite3changeset_start_v2( ** codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or ** SQLITE_NOMEM. */ -SQLITE_API int tdsqlite3changeset_next(tdsqlite3_changeset_iter *pIter); +SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *pIter); /* ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator -** METHOD: tdsqlite3_changeset_iter +** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator -** passed to a conflict-handler by [tdsqlite3changeset_apply()], or an iterator -** created by [tdsqlite3changeset_start()]. In the latter case, the most recent -** call to [tdsqlite3changeset_next()] must have returned [SQLITE_ROW]. If this +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned [SQLITE_ROW]. If this ** is not the case, this function returns [SQLITE_MISUSE]. ** ** If argument pzTab is not NULL, then *pzTab is set to point to a ** nul-terminated utf-8 encoded string containing the name of the table ** affected by the current change. The buffer remains valid until either -** tdsqlite3changeset_next() is called on the iterator or until the +** sqlite3changeset_next() is called on the iterator or until the ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is ** set to the number of columns in the table affected by the change. If ** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change ** is an indirect change, or false (0) otherwise. See the documentation for -** [tdsqlite3session_indirect()] for a description of direct and indirect +** [sqlite3session_indirect()] for a description of direct and indirect ** changes. Finally, if pOp is not NULL, then *pOp is set to one of ** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the ** type of change that the iterator currently points to. @@ -11462,8 +11462,8 @@ SQLITE_API int tdsqlite3changeset_next(tdsqlite3_changeset_iter *pIter); ** SQLite error code is returned. The values of the output variables may not ** be trusted in this case. */ -SQLITE_API int tdsqlite3changeset_op( - tdsqlite3_changeset_iter *pIter, /* Iterator object */ +SQLITE_API int sqlite3changeset_op( + sqlite3_changeset_iter *pIter, /* Iterator object */ const char **pzTab, /* OUT: Pointer to table name */ int *pnCol, /* OUT: Number of columns in table */ int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */ @@ -11472,7 +11472,7 @@ SQLITE_API int tdsqlite3changeset_op( /* ** CAPI3REF: Obtain The Primary Key Definition Of A Table -** METHOD: tdsqlite3_changeset_iter +** METHOD: sqlite3_changeset_iter ** ** For each modified table, a changeset includes the following: ** @@ -11496,20 +11496,20 @@ SQLITE_API int tdsqlite3changeset_op( ** SQLITE_OK is returned and the output variables populated as described ** above. */ -SQLITE_API int tdsqlite3changeset_pk( - tdsqlite3_changeset_iter *pIter, /* Iterator object */ +SQLITE_API int sqlite3changeset_pk( + sqlite3_changeset_iter *pIter, /* Iterator object */ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ int *pnCol /* OUT: Number of entries in output array */ ); /* ** CAPI3REF: Obtain old.* Values From A Changeset Iterator -** METHOD: tdsqlite3_changeset_iter +** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator -** passed to a conflict-handler by [tdsqlite3changeset_apply()], or an iterator -** created by [tdsqlite3changeset_start()]. In the latter case, the most recent -** call to [tdsqlite3changeset_next()] must have returned SQLITE_ROW. +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. ** Furthermore, it may only be called if the type of change that the iterator ** currently points to is either [SQLITE_DELETE] or [SQLITE_UPDATE]. Otherwise, ** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. @@ -11519,7 +11519,7 @@ SQLITE_API int tdsqlite3changeset_pk( ** [SQLITE_RANGE] is returned and *ppValue is set to NULL. ** ** If successful, this function sets *ppValue to point to a protected -** tdsqlite3_value object containing the iVal'th value from the vector of +** sqlite3_value object containing the iVal'th value from the vector of ** original row values stored as part of the UPDATE or DELETE change and ** returns SQLITE_OK. The name of the function comes from the fact that this ** is similar to the "old.*" columns available to update or delete triggers. @@ -11527,20 +11527,20 @@ SQLITE_API int tdsqlite3changeset_pk( ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -SQLITE_API int tdsqlite3changeset_old( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ +SQLITE_API int sqlite3changeset_old( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ - tdsqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ + sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ ); /* ** CAPI3REF: Obtain new.* Values From A Changeset Iterator -** METHOD: tdsqlite3_changeset_iter +** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator -** passed to a conflict-handler by [tdsqlite3changeset_apply()], or an iterator -** created by [tdsqlite3changeset_start()]. In the latter case, the most recent -** call to [tdsqlite3changeset_next()] must have returned SQLITE_ROW. +** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator +** created by [sqlite3changeset_start()]. In the latter case, the most recent +** call to [sqlite3changeset_next()] must have returned SQLITE_ROW. ** Furthermore, it may only be called if the type of change that the iterator ** currently points to is either [SQLITE_UPDATE] or [SQLITE_INSERT]. Otherwise, ** this function returns [SQLITE_MISUSE] and sets *ppValue to NULL. @@ -11550,7 +11550,7 @@ SQLITE_API int tdsqlite3changeset_old( ** [SQLITE_RANGE] is returned and *ppValue is set to NULL. ** ** If successful, this function sets *ppValue to point to a protected -** tdsqlite3_value object containing the iVal'th value from the vector of +** sqlite3_value object containing the iVal'th value from the vector of ** new row values stored as part of the UPDATE or INSERT change and ** returns SQLITE_OK. If the change is an UPDATE and does not include ** a new value for the requested column, *ppValue is set to NULL and @@ -11561,18 +11561,18 @@ SQLITE_API int tdsqlite3changeset_old( ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -SQLITE_API int tdsqlite3changeset_new( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ +SQLITE_API int sqlite3changeset_new( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ - tdsqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ + sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ ); /* ** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator -** METHOD: tdsqlite3_changeset_iter +** METHOD: sqlite3_changeset_iter ** ** This function should only be used with iterator objects passed to a -** conflict-handler callback by [tdsqlite3changeset_apply()] with either +** conflict-handler callback by [sqlite3changeset_apply()] with either ** [SQLITE_CHANGESET_DATA] or [SQLITE_CHANGESET_CONFLICT]. If this function ** is called on any other iterator, [SQLITE_MISUSE] is returned and *ppValue ** is set to NULL. @@ -11582,22 +11582,22 @@ SQLITE_API int tdsqlite3changeset_new( ** [SQLITE_RANGE] is returned and *ppValue is set to NULL. ** ** If successful, this function sets *ppValue to point to a protected -** tdsqlite3_value object containing the iVal'th value from the +** sqlite3_value object containing the iVal'th value from the ** "conflicting row" associated with the current conflict-handler callback ** and returns SQLITE_OK. ** ** If some other error occurs (e.g. an OOM condition), an SQLite error code ** is returned and *ppValue is set to NULL. */ -SQLITE_API int tdsqlite3changeset_conflict( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ +SQLITE_API int sqlite3changeset_conflict( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Column number */ - tdsqlite3_value **ppValue /* OUT: Value from conflicting row */ + sqlite3_value **ppValue /* OUT: Value from conflicting row */ ); /* ** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations -** METHOD: tdsqlite3_changeset_iter +** METHOD: sqlite3_changeset_iter ** ** This function may only be called with an iterator passed to an ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case @@ -11606,43 +11606,43 @@ SQLITE_API int tdsqlite3changeset_conflict( ** ** In all other cases this function returns SQLITE_MISUSE. */ -SQLITE_API int tdsqlite3changeset_fk_conflicts( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ +SQLITE_API int sqlite3changeset_fk_conflicts( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ int *pnOut /* OUT: Number of FK violations */ ); /* ** CAPI3REF: Finalize A Changeset Iterator -** METHOD: tdsqlite3_changeset_iter +** METHOD: sqlite3_changeset_iter ** ** This function is used to finalize an iterator allocated with -** [tdsqlite3changeset_start()]. +** [sqlite3changeset_start()]. ** ** This function should only be called on iterators created using the -** [tdsqlite3changeset_start()] function. If an application calls this +** [sqlite3changeset_start()] function. If an application calls this ** function with an iterator passed to a conflict-handler by -** [tdsqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the +** [sqlite3changeset_apply()], [SQLITE_MISUSE] is immediately returned and the ** call has no effect. ** -** If an error was encountered within a call to an tdsqlite3changeset_xxx() -** function (for example an [SQLITE_CORRUPT] in [tdsqlite3changeset_next()] or an -** [SQLITE_NOMEM] in [tdsqlite3changeset_new()]) then an error code corresponding +** If an error was encountered within a call to an sqlite3changeset_xxx() +** function (for example an [SQLITE_CORRUPT] in [sqlite3changeset_next()] or an +** [SQLITE_NOMEM] in [sqlite3changeset_new()]) then an error code corresponding ** to that error is returned by this function. Otherwise, SQLITE_OK is ** returned. This is to allow the following pattern (pseudo-code): ** **
-**   tdsqlite3changeset_start();
-**   while( SQLITE_ROW==tdsqlite3changeset_next() ){
+**   sqlite3changeset_start();
+**   while( SQLITE_ROW==sqlite3changeset_next() ){
 **     // Do something with change.
 **   }
-**   rc = tdsqlite3changeset_finalize();
+**   rc = sqlite3changeset_finalize();
 **   if( rc!=SQLITE_OK ){
 **     // An error has occurred 
 **   }
 ** 
*/ -SQLITE_API int tdsqlite3changeset_finalize(tdsqlite3_changeset_iter *pIter); +SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); /* ** CAPI3REF: Invert A Changeset @@ -11665,14 +11665,14 @@ SQLITE_API int tdsqlite3changeset_finalize(tdsqlite3_changeset_iter *pIter); ** SQLITE_OK is returned. If an error occurs, both *pnOut and *ppOut are ** zeroed and an SQLite error code returned. ** -** It is the responsibility of the caller to eventually call tdsqlite3_free() +** It is the responsibility of the caller to eventually call sqlite3_free() ** on the *ppOut pointer to free the buffer allocation following a successful ** call to this function. ** ** WARNING/TODO: This function currently assumes that the input is a valid ** changeset. If it is not, the results are undefined. */ -SQLITE_API int tdsqlite3changeset_invert( +SQLITE_API int sqlite3changeset_invert( int nIn, const void *pIn, /* Input changeset */ int *pnOut, void **ppOut /* OUT: Inverse of input */ ); @@ -11685,25 +11685,25 @@ SQLITE_API int tdsqlite3changeset_invert( ** changeset A followed by changeset B. ** ** This function combines the two input changesets using an -** tdsqlite3_changegroup object. Calling it produces similar results as the +** sqlite3_changegroup object. Calling it produces similar results as the ** following code fragment: ** **
-**   tdsqlite3_changegroup *pGrp;
-**   rc = tdsqlite3_changegroup_new(&pGrp);
-**   if( rc==SQLITE_OK ) rc = tdsqlite3changegroup_add(pGrp, nA, pA);
-**   if( rc==SQLITE_OK ) rc = tdsqlite3changegroup_add(pGrp, nB, pB);
+**   sqlite3_changegroup *pGrp;
+**   rc = sqlite3_changegroup_new(&pGrp);
+**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);
+**   if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nB, pB);
 **   if( rc==SQLITE_OK ){
-**     rc = tdsqlite3changegroup_output(pGrp, pnOut, ppOut);
+**     rc = sqlite3changegroup_output(pGrp, pnOut, ppOut);
 **   }else{
 **     *ppOut = 0;
 **     *pnOut = 0;
 **   }
 ** 
** -** Refer to the tdsqlite3_changegroup documentation below for details. +** Refer to the sqlite3_changegroup documentation below for details. */ -SQLITE_API int tdsqlite3changeset_concat( +SQLITE_API int sqlite3changeset_concat( int nA, /* Number of bytes in buffer pA */ void *pA, /* Pointer to buffer containing changeset A */ int nB, /* Number of bytes in buffer pB */ @@ -11719,49 +11719,49 @@ SQLITE_API int tdsqlite3changeset_concat( ** A changegroup is an object used to combine two or more ** [changesets] or [patchsets] */ -typedef struct tdsqlite3_changegroup tdsqlite3_changegroup; +typedef struct sqlite3_changegroup sqlite3_changegroup; /* ** CAPI3REF: Create A New Changegroup Object -** CONSTRUCTOR: tdsqlite3_changegroup +** CONSTRUCTOR: sqlite3_changegroup ** -** An tdsqlite3_changegroup object is used to combine two or more changesets +** An sqlite3_changegroup object is used to combine two or more changesets ** (or patchsets) into a single changeset (or patchset). A single changegroup ** object may combine changesets or patchsets, but not both. The output is ** always in the same format as the input. ** ** If successful, this function returns SQLITE_OK and populates (*pp) with -** a pointer to a new tdsqlite3_changegroup object before returning. The caller +** a pointer to a new sqlite3_changegroup object before returning. The caller ** should eventually free the returned object using a call to -** tdsqlite3changegroup_delete(). If an error occurs, an SQLite error code +** sqlite3changegroup_delete(). If an error occurs, an SQLite error code ** (i.e. SQLITE_NOMEM) is returned and *pp is set to NULL. ** -** The usual usage pattern for an tdsqlite3_changegroup object is as follows: +** The usual usage pattern for an sqlite3_changegroup object is as follows: ** **
    -**
  • It is created using a call to tdsqlite3changegroup_new(). +**
  • It is created using a call to sqlite3changegroup_new(). ** **
  • Zero or more changesets (or patchsets) are added to the object -** by calling tdsqlite3changegroup_add(). +** by calling sqlite3changegroup_add(). ** **
  • The result of combining all input changesets together is obtained -** by the application via a call to tdsqlite3changegroup_output(). +** by the application via a call to sqlite3changegroup_output(). ** -**
  • The object is deleted using a call to tdsqlite3changegroup_delete(). +**
  • The object is deleted using a call to sqlite3changegroup_delete(). **
** ** Any number of calls to add() and output() may be made between the calls to ** new() and delete(), and in any order. ** -** As well as the regular tdsqlite3changegroup_add() and -** tdsqlite3changegroup_output() functions, also available are the streaming -** versions tdsqlite3changegroup_add_strm() and tdsqlite3changegroup_output_strm(). +** As well as the regular sqlite3changegroup_add() and +** sqlite3changegroup_output() functions, also available are the streaming +** versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm(). */ -SQLITE_API int tdsqlite3changegroup_new(tdsqlite3_changegroup **pp); +SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp); /* ** CAPI3REF: Add A Changeset To A Changegroup -** METHOD: tdsqlite3_changegroup +** METHOD: sqlite3_changegroup ** ** Add all changes within the changeset (or patchset) in buffer pData (size ** nData bytes) to the changegroup. @@ -11835,19 +11835,19 @@ SQLITE_API int tdsqlite3changegroup_new(tdsqlite3_changegroup **pp); ** ** If no error occurs, SQLITE_OK is returned. */ -SQLITE_API int tdsqlite3changegroup_add(tdsqlite3_changegroup*, int nData, void *pData); +SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); /* ** CAPI3REF: Obtain A Composite Changeset From A Changegroup -** METHOD: tdsqlite3_changegroup +** METHOD: sqlite3_changegroup ** ** Obtain a buffer containing a changeset (or patchset) representing the ** current contents of the changegroup. If the inputs to the changegroup ** were themselves changesets, the output is a changeset. Or, if the ** inputs were patchsets, the output is also a patchset. ** -** As with the output of the tdsqlite3session_changeset() and -** tdsqlite3session_patchset() functions, all changes related to a single +** As with the output of the sqlite3session_changeset() and +** sqlite3session_patchset() functions, all changes related to a single ** table are grouped together in the output of this function. Tables appear ** in the same order as for the very first changeset added to the changegroup. ** If the second or subsequent changesets added to the changegroup contain @@ -11860,19 +11860,19 @@ SQLITE_API int tdsqlite3changegroup_add(tdsqlite3_changegroup*, int nData, void ** is returned and the output variables are set to the size of and a ** pointer to the output buffer, respectively. In this case it is the ** responsibility of the caller to eventually free the buffer using a -** call to tdsqlite3_free(). +** call to sqlite3_free(). */ -SQLITE_API int tdsqlite3changegroup_output( - tdsqlite3_changegroup*, +SQLITE_API int sqlite3changegroup_output( + sqlite3_changegroup*, int *pnData, /* OUT: Size of output buffer in bytes */ void **ppData /* OUT: Pointer to output buffer */ ); /* ** CAPI3REF: Delete A Changegroup Object -** DESTRUCTOR: tdsqlite3_changegroup +** DESTRUCTOR: sqlite3_changegroup */ -SQLITE_API void tdsqlite3changegroup_delete(tdsqlite3_changegroup*); +SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); /* ** CAPI3REF: Apply A Changeset To A Database @@ -11905,13 +11905,13 @@ SQLITE_API void tdsqlite3changegroup_delete(tdsqlite3_changegroup*); ** ** If there is no compatible table, it is not an error, but none of the ** changes associated with the table are applied. A warning message is issued -** via the tdsqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most +** via the sqlite3_log() mechanism with the error code SQLITE_SCHEMA. At most ** one such warning is issued for each table in the changeset. ** ** For each change for which there is a compatible table, an attempt is made ** to modify the table contents according to the UPDATE, INSERT or DELETE ** change. If a change cannot be applied cleanly, the conflict handler -** function passed as the fifth argument to tdsqlite3changeset_apply() may be +** function passed as the fifth argument to sqlite3changeset_apply() may be ** invoked. A description of exactly when the conflict handler is invoked for ** each type of change is below. ** @@ -11925,8 +11925,8 @@ SQLITE_API void tdsqlite3changegroup_delete(tdsqlite3_changegroup*); ** if the second argument passed to the conflict handler is either ** SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If the conflict-handler ** returns an illegal value, any changes already made are rolled back and -** the call to tdsqlite3changeset_apply() returns SQLITE_MISUSE. Different -** actions are taken by tdsqlite3changeset_apply() depending on the value +** the call to sqlite3changeset_apply() returns SQLITE_MISUSE. Different +** actions are taken by sqlite3changeset_apply() depending on the value ** returned by each invocation of the conflict-handler function. Refer to ** the documentation for the three ** [SQLITE_CHANGESET_OMIT|available return values] for details. @@ -12016,24 +12016,24 @@ SQLITE_API void tdsqlite3changegroup_delete(tdsqlite3_changegroup*); ** SQLite error code returned. ** ** If the output parameters (ppRebase) and (pnRebase) are non-NULL and -** the input is a changeset (not a patchset), then tdsqlite3changeset_apply_v2() +** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2() ** may set (*ppRebase) to point to a "rebase" that may be used with the -** tdsqlite3_rebaser APIs buffer before returning. In this case (*pnRebase) +** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase) ** is set to the size of the buffer in bytes. It is the responsibility of the -** caller to eventually free any such buffer using tdsqlite3_free(). The buffer +** caller to eventually free any such buffer using sqlite3_free(). The buffer ** is only allocated and populated if one or more conflicts were encountered -** while applying the patchset. See comments surrounding the tdsqlite3_rebaser +** while applying the patchset. See comments surrounding the sqlite3_rebaser ** APIs for further details. ** -** The behavior of tdsqlite3changeset_apply_v2() and its streaming equivalent +** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent ** may be modified by passing a combination of ** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter. ** -** Note that the tdsqlite3changeset_apply_v2() API is still experimental +** Note that the sqlite3changeset_apply_v2() API is still experimental ** and therefore subject to change. */ -SQLITE_API int tdsqlite3changeset_apply( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ +SQLITE_API int sqlite3changeset_apply( + sqlite3 *db, /* Apply change to "main" db of this handle */ int nChangeset, /* Size of changeset in bytes */ void *pChangeset, /* Changeset blob */ int(*xFilter)( @@ -12043,12 +12043,12 @@ SQLITE_API int tdsqlite3changeset_apply( int(*xConflict)( void *pCtx, /* Copy of sixth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx /* First argument passed to xConflict */ ); -SQLITE_API int tdsqlite3changeset_apply_v2( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ +SQLITE_API int sqlite3changeset_apply_v2( + sqlite3 *db, /* Apply change to "main" db of this handle */ int nChangeset, /* Size of changeset in bytes */ void *pChangeset, /* Changeset blob */ int(*xFilter)( @@ -12058,7 +12058,7 @@ SQLITE_API int tdsqlite3changeset_apply_v2( int(*xConflict)( void *pCtx, /* Copy of sixth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, /* OUT: Rebase data */ @@ -12066,10 +12066,10 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ); /* -** CAPI3REF: Flags for tdsqlite3changeset_apply_v2 +** CAPI3REF: Flags for sqlite3changeset_apply_v2 ** ** The following flags may passed via the 9th parameter to -** [tdsqlite3changeset_apply_v2] and [tdsqlite3changeset_apply_v2_strm]: +** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]: ** **
**
SQLITE_CHANGESETAPPLY_NOSAVEPOINT
@@ -12083,7 +12083,7 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ** **
SQLITE_CHANGESETAPPLY_INVERT
** Invert the changeset before applying it. This is equivalent to inverting -** a changeset using tdsqlite3changeset_invert() before applying it. It is +** a changeset using sqlite3changeset_invert() before applying it. It is ** an error to specify this flag with a patchset. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 @@ -12111,7 +12111,7 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ** required PRIMARY KEY fields is not present in the database. ** ** There is no conflicting row in this case. The results of invoking the -** tdsqlite3changeset_conflict() API are undefined. +** sqlite3changeset_conflict() API are undefined. ** **
SQLITE_CHANGESET_CONFLICT
** CHANGESET_CONFLICT is passed as the second argument to the conflict @@ -12131,8 +12131,8 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ** CHANGESET_ABORT, the changeset is rolled back. ** ** No current or conflicting row information is provided. The only function -** it is possible to call on the supplied tdsqlite3_changeset_iter handle -** is tdsqlite3changeset_fk_conflicts(). +** it is possible to call on the supplied sqlite3_changeset_iter handle +** is sqlite3changeset_fk_conflicts(). ** **
SQLITE_CHANGESET_CONSTRAINT
** If any other constraint violation occurs while applying a change (i.e. @@ -12140,7 +12140,7 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ** invoked with CHANGESET_CONSTRAINT as the second argument. ** ** There is no conflicting row in this case. The results of invoking the -** tdsqlite3changeset_conflict() API are undefined. +** sqlite3changeset_conflict() API are undefined. ** **
*/ @@ -12165,7 +12165,7 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ** This value may only be returned if the second argument to the conflict ** handler was SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT. If this ** is not the case, any changes applied so far are rolled back and the -** call to tdsqlite3changeset_apply() returns SQLITE_MISUSE. +** call to sqlite3changeset_apply() returns SQLITE_MISUSE. ** ** If CHANGESET_REPLACE is returned by an SQLITE_CHANGESET_DATA conflict ** handler, then the conflicting row is either updated or deleted, depending @@ -12178,7 +12178,7 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ** **
SQLITE_CHANGESET_ABORT
** If this value is returned, any changes applied so far are rolled back -** and the call to tdsqlite3changeset_apply() returns SQLITE_ABORT. +** and the call to sqlite3changeset_apply() returns SQLITE_ABORT. ** */ #define SQLITE_CHANGESET_OMIT 0 @@ -12266,24 +12266,24 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ** OMIT. ** ** In order to rebase a local changeset, the remote changeset must first -** be applied to the local database using tdsqlite3changeset_apply_v2() and +** be applied to the local database using sqlite3changeset_apply_v2() and ** the buffer of rebase information captured. Then: ** **
    -**
  1. An tdsqlite3_rebaser object is created by calling -** tdsqlite3rebaser_create(). +**
  2. An sqlite3_rebaser object is created by calling +** sqlite3rebaser_create(). **
  3. The new object is configured with the rebase buffer obtained from -** tdsqlite3changeset_apply_v2() by calling tdsqlite3rebaser_configure(). +** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure(). ** If the local changeset is to be rebased against multiple remote -** changesets, then tdsqlite3rebaser_configure() should be called +** changesets, then sqlite3rebaser_configure() should be called ** multiple times, in the same order that the multiple -** tdsqlite3changeset_apply_v2() calls were made. -**
  4. Each local changeset is rebased by calling tdsqlite3rebaser_rebase(). -**
  5. The tdsqlite3_rebaser object is deleted by calling -** tdsqlite3rebaser_delete(). +** sqlite3changeset_apply_v2() calls were made. +**
  6. Each local changeset is rebased by calling sqlite3rebaser_rebase(). +**
  7. The sqlite3_rebaser object is deleted by calling +** sqlite3rebaser_delete(). **
*/ -typedef struct tdsqlite3_rebaser tdsqlite3_rebaser; +typedef struct sqlite3_rebaser sqlite3_rebaser; /* ** CAPI3REF: Create a changeset rebaser object. @@ -12294,7 +12294,7 @@ typedef struct tdsqlite3_rebaser tdsqlite3_rebaser; ** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) ** to NULL. */ -SQLITE_API int tdsqlite3rebaser_create(tdsqlite3_rebaser **ppNew); +SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew); /* ** CAPI3REF: Configure a changeset rebaser object. @@ -12303,10 +12303,10 @@ SQLITE_API int tdsqlite3rebaser_create(tdsqlite3_rebaser **ppNew); ** Configure the changeset rebaser object to rebase changesets according ** to the conflict resolutions described by buffer pRebase (size nRebase ** bytes), which must have been obtained from a previous call to -** tdsqlite3changeset_apply_v2(). +** sqlite3changeset_apply_v2(). */ -SQLITE_API int tdsqlite3rebaser_configure( - tdsqlite3_rebaser*, +SQLITE_API int sqlite3rebaser_configure( + sqlite3_rebaser*, int nRebase, const void *pRebase ); @@ -12321,11 +12321,11 @@ SQLITE_API int tdsqlite3rebaser_configure( ** is set to point to the new buffer containing the rebased changeset and ** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the ** responsibility of the caller to eventually free the new buffer using -** tdsqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut) +** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut) ** are set to zero and an SQLite error code returned. */ -SQLITE_API int tdsqlite3rebaser_rebase( - tdsqlite3_rebaser*, +SQLITE_API int sqlite3rebaser_rebase( + sqlite3_rebaser*, int nIn, const void *pIn, int *pnOut, void **ppOut ); @@ -12336,9 +12336,9 @@ SQLITE_API int tdsqlite3rebaser_rebase( ** ** Delete the changeset rebaser object and all associated resources. There ** should be one call to this function for each successful invocation -** of tdsqlite3rebaser_create(). +** of sqlite3rebaser_create(). */ -SQLITE_API void tdsqlite3rebaser_delete(tdsqlite3_rebaser *p); +SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); /* ** CAPI3REF: Streaming Versions of API functions. @@ -12348,19 +12348,19 @@ SQLITE_API void tdsqlite3rebaser_delete(tdsqlite3_rebaser *p); ** ** ** -**
Streaming functionNon-streaming equivalent
tdsqlite3changeset_apply_strm[tdsqlite3changeset_apply] -**
tdsqlite3changeset_apply_strm_v2[tdsqlite3changeset_apply_v2] -**
tdsqlite3changeset_concat_strm[tdsqlite3changeset_concat] -**
tdsqlite3changeset_invert_strm[tdsqlite3changeset_invert] -**
tdsqlite3changeset_start_strm[tdsqlite3changeset_start] -**
tdsqlite3session_changeset_strm[tdsqlite3session_changeset] -**
tdsqlite3session_patchset_strm[tdsqlite3session_patchset] +**
sqlite3changeset_apply_strm[sqlite3changeset_apply] +**
sqlite3changeset_apply_strm_v2[sqlite3changeset_apply_v2] +**
sqlite3changeset_concat_strm[sqlite3changeset_concat] +**
sqlite3changeset_invert_strm[sqlite3changeset_invert] +**
sqlite3changeset_start_strm[sqlite3changeset_start] +**
sqlite3session_changeset_strm[sqlite3session_changeset] +**
sqlite3session_patchset_strm[sqlite3session_patchset] **
** ** Non-streaming functions that accept changesets (or patchsets) as input ** require that the entire changeset be stored in a single buffer in memory. ** Similarly, those that return a changeset or patchset do so by returning -** a pointer to a single large buffer allocated using tdsqlite3_malloc(). +** a pointer to a single large buffer allocated using sqlite3_malloc(). ** Normally this is convenient. However, if an application running in a ** low-memory environment is required to handle very large changesets, the ** large contiguous memory allocations required can become onerous. @@ -12393,7 +12393,7 @@ SQLITE_API void tdsqlite3rebaser_delete(tdsqlite3_rebaser *p); ** an error, all processing is abandoned and the streaming API function ** returns a copy of the error code to the caller. ** -** In the case of tdsqlite3changeset_start_strm(), the xInput callback may be +** In the case of sqlite3changeset_start_strm(), the xInput callback may be ** invoked by the sessions module at any point during the lifetime of the ** iterator. If such an xInput callback returns an error, the iterator enters ** an error state, whereby all subsequent calls to iterator functions @@ -12430,8 +12430,8 @@ SQLITE_API void tdsqlite3rebaser_delete(tdsqlite3_rebaser *p); ** parameter set to a value less than or equal to zero. Other than this, ** no guarantees are made as to the size of the chunks of data returned. */ -SQLITE_API int tdsqlite3changeset_apply_strm( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ +SQLITE_API int sqlite3changeset_apply_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ void *pIn, /* First arg for xInput */ int(*xFilter)( @@ -12441,12 +12441,12 @@ SQLITE_API int tdsqlite3changeset_apply_strm( int(*xConflict)( void *pCtx, /* Copy of sixth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx /* First argument passed to xConflict */ ); -SQLITE_API int tdsqlite3changeset_apply_v2_strm( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ +SQLITE_API int sqlite3changeset_apply_v2_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ void *pIn, /* First arg for xInput */ int(*xFilter)( @@ -12456,13 +12456,13 @@ SQLITE_API int tdsqlite3changeset_apply_v2_strm( int(*xConflict)( void *pCtx, /* Copy of sixth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, int flags ); -SQLITE_API int tdsqlite3changeset_concat_strm( +SQLITE_API int sqlite3changeset_concat_strm( int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA, int (*xInputB)(void *pIn, void *pData, int *pnData), @@ -12470,43 +12470,43 @@ SQLITE_API int tdsqlite3changeset_concat_strm( int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -SQLITE_API int tdsqlite3changeset_invert_strm( +SQLITE_API int sqlite3changeset_invert_strm( int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -SQLITE_API int tdsqlite3changeset_start_strm( - tdsqlite3_changeset_iter **pp, +SQLITE_API int sqlite3changeset_start_strm( + sqlite3_changeset_iter **pp, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ); -SQLITE_API int tdsqlite3changeset_start_v2_strm( - tdsqlite3_changeset_iter **pp, +SQLITE_API int sqlite3changeset_start_v2_strm( + sqlite3_changeset_iter **pp, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int flags ); -SQLITE_API int tdsqlite3session_changeset_strm( - tdsqlite3_session *pSession, +SQLITE_API int sqlite3session_changeset_strm( + sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -SQLITE_API int tdsqlite3session_patchset_strm( - tdsqlite3_session *pSession, +SQLITE_API int sqlite3session_patchset_strm( + sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -SQLITE_API int tdsqlite3changegroup_add_strm(tdsqlite3_changegroup*, +SQLITE_API int sqlite3changegroup_add_strm(sqlite3_changegroup*, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ); -SQLITE_API int tdsqlite3changegroup_output_strm(tdsqlite3_changegroup*, +SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ); -SQLITE_API int tdsqlite3rebaser_rebase_strm( - tdsqlite3_rebaser *pRebaser, +SQLITE_API int sqlite3rebaser_rebase_strm( + sqlite3_rebaser *pRebaser, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int (*xOutput)(void *pOut, const void *pData, int nData), @@ -12516,16 +12516,16 @@ SQLITE_API int tdsqlite3rebaser_rebase_strm( /* ** CAPI3REF: Configure global parameters ** -** The tdsqlite3session_config() interface is used to make global configuration +** The sqlite3session_config() interface is used to make global configuration ** changes to the sessions module in order to tune it to the specific needs ** of the application. ** -** The tdsqlite3session_config() interface is not threadsafe. If it is invoked +** The sqlite3session_config() interface is not threadsafe. If it is invoked ** while any other thread is inside any other sessions method then the ** results are undefined. Furthermore, if it is invoked after any sessions ** related objects have been created, the results are also undefined. ** -** The first argument to the tdsqlite3session_config() function must be one +** The first argument to the sqlite3session_config() function must be one ** of the SQLITE_SESSION_CONFIG_XXX constants defined below. The ** interpretation of the (void*) value passed as the second parameter and ** the effect of calling this function depends on the value of the first @@ -12546,10 +12546,10 @@ SQLITE_API int tdsqlite3rebaser_rebase_strm( ** This function returns SQLITE_OK if successful, or an SQLite error code ** otherwise. */ -SQLITE_API int tdsqlite3session_config(int op, void *pArg); +SQLITE_API int sqlite3session_config(int op, void *pArg); /* -** CAPI3REF: Values for tdsqlite3session_config(). +** CAPI3REF: Values for sqlite3session_config(). */ #define SQLITE_SESSION_CONFIG_STRMSIZE 1 @@ -12562,7 +12562,7 @@ SQLITE_API int tdsqlite3session_config(int op, void *pArg); #endif /* !defined(__SQLITESESSION_H_) && defined(SQLITE_ENABLE_SESSION) */ -/******** End of tdsqlite3session.h *********/ +/******** End of sqlite3session.h *********/ /******** Begin file fts5.h *********/ /* ** 2014 May 31 @@ -12596,7 +12596,7 @@ extern "C" { ** CUSTOM AUXILIARY FUNCTIONS ** ** Virtual table implementations may overload SQL functions by implementing -** the tdsqlite3_module.xFindFunction() method. +** the sqlite3_module.xFindFunction() method. */ typedef struct Fts5ExtensionApi Fts5ExtensionApi; @@ -12606,9 +12606,9 @@ typedef struct Fts5PhraseIter Fts5PhraseIter; typedef void (*fts5_extension_function)( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ - tdsqlite3_context *pCtx, /* Context for returning result/error */ + sqlite3_context *pCtx, /* Context for returning result/error */ int nVal, /* Number of values in apVal[] array */ - tdsqlite3_value **apVal /* Array of trailing arguments */ + sqlite3_value **apVal /* Array of trailing arguments */ ); struct Fts5PhraseIter { @@ -12833,8 +12833,8 @@ struct Fts5ExtensionApi { void *(*xUserData)(Fts5Context*); int (*xColumnCount)(Fts5Context*); - int (*xRowCount)(Fts5Context*, tdsqlite3_int64 *pnRow); - int (*xColumnTotalSize)(Fts5Context*, int iCol, tdsqlite3_int64 *pnToken); + int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); + int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); int (*xTokenize)(Fts5Context*, const char *pText, int nText, /* Text to tokenize */ @@ -12848,7 +12848,7 @@ struct Fts5ExtensionApi { int (*xInstCount)(Fts5Context*, int *pnInst); int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff); - tdsqlite3_int64 (*xRowid)(Fts5Context*); + sqlite3_int64 (*xRowid)(Fts5Context*); int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn); int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken); @@ -13582,8 +13582,8 @@ struct fts5_api { ** */ #ifdef SQLITE_COVERAGE_TEST -SQLITE_PRIVATE void tdsqlite3Coverage(int); -# define testcase(X) if( X ){ tdsqlite3Coverage(__LINE__); } +SQLITE_PRIVATE void sqlite3Coverage(int); +# define testcase(X) if( X ){ sqlite3Coverage(__LINE__); } #else # define testcase(X) #endif @@ -13694,8 +13694,8 @@ SQLITE_PRIVATE void tdsqlite3Coverage(int); */ #if defined(SQLITE_FORCE_OS_TRACE) || defined(SQLITE_TEST) || \ (defined(SQLITE_DEBUG) && SQLITE_OS_WIN) - extern int tdsqlite3OSTrace; -# define OSTRACE(X) if( tdsqlite3OSTrace ) tdsqlite3DebugPrintf X + extern int sqlite3OSTrace; +# define OSTRACE(X) if( sqlite3OSTrace ) sqlite3DebugPrintf X # define SQLITE_HAVE_OS_TRACE #else # define OSTRACE(X) @@ -13703,7 +13703,7 @@ SQLITE_PRIVATE void tdsqlite3Coverage(int); #endif /* -** Is the tdsqlite3ErrName() function needed in the build? Currently, +** Is the sqlite3ErrName() function needed in the build? Currently, ** it is needed by "mutex_w32.c" (when debugging), "os_win.c" (when ** OSTRACE is enabled), and by several "test*.c" files (which are ** compiled using SQLITE_TEST). @@ -13808,10 +13808,10 @@ struct HashElem { /* ** Access routines. To delete, insert a NULL pointer. */ -SQLITE_PRIVATE void tdsqlite3HashInit(Hash*); -SQLITE_PRIVATE void *tdsqlite3HashInsert(Hash*, const char *pKey, void *pData); -SQLITE_PRIVATE void *tdsqlite3HashFind(const Hash*, const char *pKey); -SQLITE_PRIVATE void tdsqlite3HashClear(Hash*); +SQLITE_PRIVATE void sqlite3HashInit(Hash*); +SQLITE_PRIVATE void *sqlite3HashInsert(Hash*, const char *pKey, void *pData); +SQLITE_PRIVATE void *sqlite3HashFind(const Hash*, const char *pKey); +SQLITE_PRIVATE void sqlite3HashClear(Hash*); /* ** Macros for looping over all elements of a hash table. The idiom is @@ -14052,7 +14052,7 @@ SQLITE_PRIVATE void tdsqlite3HashClear(Hash*); # define float sqlite_int64 # define LONGDOUBLE_TYPE sqlite_int64 # ifndef SQLITE_BIG_DBL -# define SQLITE_BIG_DBL (((tdsqlite3_int64)1)<<50) +# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) # endif # define SQLITE_OMIT_DATETIME_FUNCS 1 # define SQLITE_OMIT_TRACE 1 @@ -14349,12 +14349,12 @@ typedef INT16_TYPE LogEst; # define SQLITE_UTF16NATIVE SQLITE_UTF16LE #else # ifdef SQLITE_AMALGAMATION - const int tdsqlite3one = 1; + const int sqlite3one = 1; # else - extern const int tdsqlite3one; + extern const int sqlite3one; # endif -# define SQLITE_BIGENDIAN (*(char *)(&tdsqlite3one)==0) -# define SQLITE_LITTLEENDIAN (*(char *)(&tdsqlite3one)==1) +# define SQLITE_BIGENDIAN (*(char *)(&sqlite3one)==0) +# define SQLITE_LITTLEENDIAN (*(char *)(&sqlite3one)==1) # define SQLITE_UTF16NATIVE (SQLITE_BIGENDIAN?SQLITE_UTF16BE:SQLITE_UTF16LE) #endif @@ -14456,7 +14456,7 @@ struct BusyHandler { int (*xBusyHandler)(void *,int); /* The busy callback */ void *pBusyArg; /* First arg to busy callback */ int nBusy; /* Incremented with each busy call */ - u8 bExtraFileArg; /* Include tdsqlite3_file as callback arg */ + u8 bExtraFileArg; /* Include sqlite3_file as callback arg */ }; /* @@ -14489,14 +14489,14 @@ struct BusyHandler { #define IsPowerOfTwo(X) (((X)&((X)-1))==0) /* -** The following value as a destructor means to use tdsqlite3DbFree(). -** The tdsqlite3DbFree() routine requires two parameters instead of the +** The following value as a destructor means to use sqlite3DbFree(). +** The sqlite3DbFree() routine requires two parameters instead of the ** one parameter that destructors normally want. So we have to introduce ** this magic value that the code knows to handle differently. Any ** pointer will work here as long as it is distinct from SQLITE_STATIC ** and SQLITE_TRANSIENT. */ -#define SQLITE_DYNAMIC ((tdsqlite3_destructor_type)tdsqlite3MallocSize) +#define SQLITE_DYNAMIC ((sqlite3_destructor_type)sqlite3MallocSize) /* ** When SQLITE_OMIT_WSD is defined, it means that the target platform does @@ -14514,14 +14514,14 @@ struct BusyHandler { */ #ifdef SQLITE_OMIT_WSD #define SQLITE_WSD const - #define GLOBAL(t,v) (*(t*)tdsqlite3_wsd_find((void*)&(v), sizeof(v))) - #define tdsqlite3GlobalConfig GLOBAL(struct Sqlite3Config, tdsqlite3Config) -SQLITE_API int tdsqlite3_wsd_init(int N, int J); -SQLITE_API void *tdsqlite3_wsd_find(void *K, int L); + #define GLOBAL(t,v) (*(t*)sqlite3_wsd_find((void*)&(v), sizeof(v))) + #define sqlite3GlobalConfig GLOBAL(struct Sqlite3Config, sqlite3Config) +SQLITE_API int sqlite3_wsd_init(int N, int J); +SQLITE_API void *sqlite3_wsd_find(void *K, int L); #else #define SQLITE_WSD #define GLOBAL(t,v) v - #define tdsqlite3GlobalConfig tdsqlite3Config + #define sqlite3GlobalConfig sqlite3Config #endif /* @@ -14579,7 +14579,7 @@ typedef struct Select Select; typedef struct SQLiteThread SQLiteThread; typedef struct SelectDest SelectDest; typedef struct SrcList SrcList; -typedef struct tdsqlite3_str StrAccum; /* Internal alias for tdsqlite3_str */ +typedef struct sqlite3_str StrAccum; /* Internal alias for sqlite3_str */ typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; @@ -14626,7 +14626,7 @@ typedef struct With With; /* A VList object records a mapping between parameters/variables/wildcards ** in the SQL statement (such as $abc, @pqr, or :xyz) and the integer ** variable number associated with that parameter. See the format description -** on the tdsqlite3VListAdd() routine for more information. A VList is really +** on the sqlite3VListAdd() routine for more information. A VList is really ** just an array of integers. */ typedef int VList; @@ -14682,16 +14682,16 @@ typedef struct BtShared BtShared; typedef struct BtreePayload BtreePayload; -SQLITE_PRIVATE int tdsqlite3BtreeOpen( - tdsqlite3_vfs *pVfs, /* VFS to use with this b-tree */ +SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use with this b-tree */ const char *zFilename, /* Name of database file to open */ - tdsqlite3 *db, /* Associated database connection */ + sqlite3 *db, /* Associated database connection */ Btree **ppBtree, /* Return open Btree* here */ int flags, /* Flags */ int vfsFlags /* Flags passed through to VFS open */ ); -/* The flags parameter to tdsqlite3BtreeOpen can be the bitwise or of the +/* The flags parameter to sqlite3BtreeOpen can be the bitwise or of the ** following values. ** ** NOTE: These values must match the corresponding PAGER_ values in @@ -14702,46 +14702,46 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( #define BTREE_SINGLE 4 /* The file contains at most 1 b-tree */ #define BTREE_UNORDERED 8 /* Use of a hash implementation is OK */ -SQLITE_PRIVATE int tdsqlite3BtreeClose(Btree*); -SQLITE_PRIVATE int tdsqlite3BtreeSetCacheSize(Btree*,int); -SQLITE_PRIVATE int tdsqlite3BtreeSetSpillSize(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeClose(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree*,int); #if SQLITE_MAX_MMAP_SIZE>0 -SQLITE_PRIVATE int tdsqlite3BtreeSetMmapLimit(Btree*,tdsqlite3_int64); -#endif -SQLITE_PRIVATE int tdsqlite3BtreeSetPagerFlags(Btree*,unsigned); -SQLITE_PRIVATE int tdsqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); -SQLITE_PRIVATE int tdsqlite3BtreeGetPageSize(Btree*); -SQLITE_PRIVATE int tdsqlite3BtreeMaxPageCount(Btree*,int); -SQLITE_PRIVATE u32 tdsqlite3BtreeLastPage(Btree*); -SQLITE_PRIVATE int tdsqlite3BtreeSecureDelete(Btree*,int); -SQLITE_PRIVATE int tdsqlite3BtreeGetOptimalReserve(Btree*); -SQLITE_PRIVATE int tdsqlite3BtreeGetReserveNoMutex(Btree *p); -SQLITE_PRIVATE int tdsqlite3BtreeSetAutoVacuum(Btree *, int); -SQLITE_PRIVATE int tdsqlite3BtreeGetAutoVacuum(Btree *); -SQLITE_PRIVATE int tdsqlite3BtreeBeginTrans(Btree*,int,int*); -SQLITE_PRIVATE int tdsqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); -SQLITE_PRIVATE int tdsqlite3BtreeCommitPhaseTwo(Btree*, int); -SQLITE_PRIVATE int tdsqlite3BtreeCommit(Btree*); -SQLITE_PRIVATE int tdsqlite3BtreeRollback(Btree*,int,int); -SQLITE_PRIVATE int tdsqlite3BtreeBeginStmt(Btree*,int); -SQLITE_PRIVATE int tdsqlite3BtreeCreateTable(Btree*, int*, int flags); -SQLITE_PRIVATE int tdsqlite3BtreeIsInTrans(Btree*); -SQLITE_PRIVATE int tdsqlite3BtreeIsInReadTrans(Btree*); -SQLITE_PRIVATE int tdsqlite3BtreeIsInBackup(Btree*); -SQLITE_PRIVATE void *tdsqlite3BtreeSchema(Btree *, int, void(*)(void *)); -SQLITE_PRIVATE int tdsqlite3BtreeSchemaLocked(Btree *pBtree); +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree*,sqlite3_int64); +#endif +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags(Btree*,unsigned); +SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int nPagesize, int nReserve, int eFix); +SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree*); +SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree*,int); +SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree*); +SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree*); +SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p); +SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *, int); +SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *); +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree*,int,int*); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree*, const char *zMaster); +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree*, int); +SQLITE_PRIVATE int sqlite3BtreeCommit(Btree*); +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree*,int,int); +SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree*,int); +SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree*, int*, int flags); +SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*); +SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*); +SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); +SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree); #ifndef SQLITE_OMIT_SHARED_CACHE -SQLITE_PRIVATE int tdsqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); #endif -SQLITE_PRIVATE int tdsqlite3BtreeSavepoint(Btree *, int, int); +SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int); -SQLITE_PRIVATE const char *tdsqlite3BtreeGetFilename(Btree *); -SQLITE_PRIVATE const char *tdsqlite3BtreeGetJournalname(Btree *); -SQLITE_PRIVATE int tdsqlite3BtreeCopyFile(Btree *, Btree *); +SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); +SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *); +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *, Btree *); -SQLITE_PRIVATE int tdsqlite3BtreeIncrVacuum(Btree *); +SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *); -/* The flags parameter to tdsqlite3BtreeCreateTable can be the bitwise OR +/* The flags parameter to sqlite3BtreeCreateTable can be the bitwise OR ** of the flags shown below. ** ** Every SQLite table must have either BTREE_INTKEY or BTREE_BLOBKEY set. @@ -14754,18 +14754,18 @@ SQLITE_PRIVATE int tdsqlite3BtreeIncrVacuum(Btree *); #define BTREE_INTKEY 1 /* Table has only 64-bit signed integer keys */ #define BTREE_BLOBKEY 2 /* Table has keys only - no data */ -SQLITE_PRIVATE int tdsqlite3BtreeDropTable(Btree*, int, int*); -SQLITE_PRIVATE int tdsqlite3BtreeClearTable(Btree*, int, int*); -SQLITE_PRIVATE int tdsqlite3BtreeClearTableOfCursor(BtCursor*); -SQLITE_PRIVATE int tdsqlite3BtreeTripAllCursors(Btree*, int, int); +SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree*, int, int); -SQLITE_PRIVATE void tdsqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); -SQLITE_PRIVATE int tdsqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); +SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); -SQLITE_PRIVATE int tdsqlite3BtreeNewDb(Btree *p); +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p); /* -** The second parameter to tdsqlite3BtreeGetMeta or tdsqlite3BtreeUpdateMeta +** The second parameter to sqlite3BtreeGetMeta or sqlite3BtreeUpdateMeta ** should be one of the following values. The integer values are assigned ** to constants so that the offset of the corresponding field in an ** SQLite database header may be found using the following formula: @@ -14793,7 +14793,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeNewDb(Btree *p); #define BTREE_DATA_VERSION 15 /* A virtual meta-value */ /* -** Kinds of hints that can be passed into the tdsqlite3BtreeCursorHint() +** Kinds of hints that can be passed into the sqlite3BtreeCursorHint() ** interface. ** ** BTREE_HINT_RANGE (arguments: Expr*, Mem*) @@ -14823,7 +14823,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeNewDb(Btree *p); /* ** Values that may be OR'd together to form the argument to the -** BTREE_HINT_FLAGS hint for tdsqlite3BtreeCursorHint(): +** BTREE_HINT_FLAGS hint for sqlite3BtreeCursorHint(): ** ** The BTREE_BULKLOAD flag is set on index cursors when the index is going ** to be filled with content that is already in sorted order. @@ -14838,7 +14838,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeNewDb(Btree *p); #define BTREE_SEEK_EQ 0x00000002 /* EQ seeks only - no range seeks */ /* -** Flags passed as the third argument to tdsqlite3BtreeCursor(). +** Flags passed as the third argument to sqlite3BtreeCursor(). ** ** For read-only cursors the wrFlag argument is always zero. For read-write ** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or just @@ -14863,34 +14863,34 @@ SQLITE_PRIVATE int tdsqlite3BtreeNewDb(Btree *p); #define BTREE_WRCSR 0x00000004 /* read-write cursor */ #define BTREE_FORDELETE 0x00000008 /* Cursor is for seek/delete only */ -SQLITE_PRIVATE int tdsqlite3BtreeCursor( +SQLITE_PRIVATE int sqlite3BtreeCursor( Btree*, /* BTree containing table to open */ int iTable, /* Index of root page */ int wrFlag, /* 1 for writing. 0 for read-only */ struct KeyInfo*, /* First argument to compare function */ BtCursor *pCursor /* Space to write cursor structure */ ); -SQLITE_PRIVATE BtCursor *tdsqlite3BtreeFakeValidCursor(void); -SQLITE_PRIVATE int tdsqlite3BtreeCursorSize(void); -SQLITE_PRIVATE void tdsqlite3BtreeCursorZero(BtCursor*); -SQLITE_PRIVATE void tdsqlite3BtreeCursorHintFlags(BtCursor*, unsigned); +SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void); +SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); +SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor*, unsigned); #ifdef SQLITE_ENABLE_CURSOR_HINTS -SQLITE_PRIVATE void tdsqlite3BtreeCursorHint(BtCursor*, int, ...); +SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor*, int, ...); #endif -SQLITE_PRIVATE int tdsqlite3BtreeCloseCursor(BtCursor*); -SQLITE_PRIVATE int tdsqlite3BtreeMovetoUnpacked( +SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( BtCursor*, UnpackedRecord *pUnKey, i64 intKey, int bias, int *pRes ); -SQLITE_PRIVATE int tdsqlite3BtreeCursorHasMoved(BtCursor*); -SQLITE_PRIVATE int tdsqlite3BtreeCursorRestore(BtCursor*, int*); -SQLITE_PRIVATE int tdsqlite3BtreeDelete(BtCursor*, u8 flags); +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor*, int*); +SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*, u8 flags); -/* Allowed flags for tdsqlite3BtreeDelete() and tdsqlite3BtreeInsert() */ +/* Allowed flags for sqlite3BtreeDelete() and sqlite3BtreeInsert() */ #define BTREE_SAVEPOSITION 0x02 /* Leave cursor pointing at NEXT or PREV */ #define BTREE_AUXDELETE 0x04 /* not the primary delete operation */ #define BTREE_APPEND 0x08 /* Insert is likely an append */ @@ -14922,7 +14922,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeDelete(BtCursor*, u8 flags); ** nData length of pData not used ** nZero extra zeros after pData not used ** -** This object is used to pass information into tdsqlite3BtreeInsert(). The +** This object is used to pass information into sqlite3BtreeInsert(). The ** same information used to be passed as five separate parameters. But placing ** the information into this object helps to keep the interface more ** organized and understandable, and it also helps the resulting code to @@ -14930,63 +14930,63 @@ SQLITE_PRIVATE int tdsqlite3BtreeDelete(BtCursor*, u8 flags); */ struct BtreePayload { const void *pKey; /* Key content for indexes. NULL for tables */ - tdsqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ + sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ const void *pData; /* Data for tables. */ - tdsqlite3_value *aMem; /* First of nMem value in the unpacked pKey */ + sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */ u16 nMem; /* Number of aMem[] value. Might be zero */ int nData; /* Size of pData. 0 if none. */ int nZero; /* Extra zero data appended after pData,nData */ }; -SQLITE_PRIVATE int tdsqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, +SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload, int flags, int seekResult); -SQLITE_PRIVATE int tdsqlite3BtreeFirst(BtCursor*, int *pRes); -SQLITE_PRIVATE int tdsqlite3BtreeLast(BtCursor*, int *pRes); -SQLITE_PRIVATE int tdsqlite3BtreeNext(BtCursor*, int flags); -SQLITE_PRIVATE int tdsqlite3BtreeEof(BtCursor*); -SQLITE_PRIVATE int tdsqlite3BtreePrevious(BtCursor*, int flags); -SQLITE_PRIVATE i64 tdsqlite3BtreeIntegerKey(BtCursor*); -SQLITE_PRIVATE void tdsqlite3BtreeCursorPin(BtCursor*); -SQLITE_PRIVATE void tdsqlite3BtreeCursorUnpin(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int flags); +SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int flags); +SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor*); #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC -SQLITE_PRIVATE i64 tdsqlite3BtreeOffset(BtCursor*); +SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor*); #endif -SQLITE_PRIVATE int tdsqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); -SQLITE_PRIVATE const void *tdsqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); -SQLITE_PRIVATE u32 tdsqlite3BtreePayloadSize(BtCursor*); -SQLITE_PRIVATE tdsqlite3_int64 tdsqlite3BtreeMaxRecordSize(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); +SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor*); +SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor*); -SQLITE_PRIVATE char *tdsqlite3BtreeIntegrityCheck(tdsqlite3*,Btree*,int*aRoot,int nRoot,int,int*); -SQLITE_PRIVATE struct Pager *tdsqlite3BtreePager(Btree*); -SQLITE_PRIVATE i64 tdsqlite3BtreeRowCountEst(BtCursor*); +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck(sqlite3*,Btree*,int*aRoot,int nRoot,int,int*); +SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); +SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor*); #ifndef SQLITE_OMIT_INCRBLOB -SQLITE_PRIVATE int tdsqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*); -SQLITE_PRIVATE int tdsqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); -SQLITE_PRIVATE void tdsqlite3BtreeIncrblobCursor(BtCursor *); +SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *); #endif -SQLITE_PRIVATE void tdsqlite3BtreeClearCursor(BtCursor *); -SQLITE_PRIVATE int tdsqlite3BtreeSetVersion(Btree *pBt, int iVersion); -SQLITE_PRIVATE int tdsqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); -SQLITE_PRIVATE int tdsqlite3BtreeIsReadonly(Btree *pBt); -SQLITE_PRIVATE int tdsqlite3HeaderSizeBtree(void); +SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor*, unsigned int mask); +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *pBt); +SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void); #ifndef NDEBUG -SQLITE_PRIVATE int tdsqlite3BtreeCursorIsValid(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); #endif -SQLITE_PRIVATE int tdsqlite3BtreeCursorIsValidNN(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor*); #ifndef SQLITE_OMIT_BTREECOUNT -SQLITE_PRIVATE int tdsqlite3BtreeCount(tdsqlite3*, BtCursor*, i64*); +SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3*, BtCursor*, i64*); #endif #ifdef SQLITE_TEST -SQLITE_PRIVATE int tdsqlite3BtreeCursorInfo(BtCursor*, int*, int); -SQLITE_PRIVATE void tdsqlite3BtreeCursorList(Btree*); +SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int); +SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*); #endif #ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int tdsqlite3BtreeCheckpoint(Btree*, int, int *, int *); +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree*, int, int *, int *); #endif /* @@ -14995,38 +14995,38 @@ SQLITE_PRIVATE int tdsqlite3BtreeCheckpoint(Btree*, int, int *, int *); ** Enter and Leave procedures no-ops. */ #ifndef SQLITE_OMIT_SHARED_CACHE -SQLITE_PRIVATE void tdsqlite3BtreeEnter(Btree*); -SQLITE_PRIVATE void tdsqlite3BtreeEnterAll(tdsqlite3*); -SQLITE_PRIVATE int tdsqlite3BtreeSharable(Btree*); -SQLITE_PRIVATE void tdsqlite3BtreeEnterCursor(BtCursor*); -SQLITE_PRIVATE int tdsqlite3BtreeConnectionCount(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3*); +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree*); +SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor*); +SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree*); #else -# define tdsqlite3BtreeEnter(X) -# define tdsqlite3BtreeEnterAll(X) -# define tdsqlite3BtreeSharable(X) 0 -# define tdsqlite3BtreeEnterCursor(X) -# define tdsqlite3BtreeConnectionCount(X) 1 +# define sqlite3BtreeEnter(X) +# define sqlite3BtreeEnterAll(X) +# define sqlite3BtreeSharable(X) 0 +# define sqlite3BtreeEnterCursor(X) +# define sqlite3BtreeConnectionCount(X) 1 #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE -SQLITE_PRIVATE void tdsqlite3BtreeLeave(Btree*); -SQLITE_PRIVATE void tdsqlite3BtreeLeaveCursor(BtCursor*); -SQLITE_PRIVATE void tdsqlite3BtreeLeaveAll(tdsqlite3*); +SQLITE_PRIVATE void sqlite3BtreeLeave(Btree*); +SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor*); +SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3*); #ifndef NDEBUG /* These routines are used inside assert() statements only. */ -SQLITE_PRIVATE int tdsqlite3BtreeHoldsMutex(Btree*); -SQLITE_PRIVATE int tdsqlite3BtreeHoldsAllMutexes(tdsqlite3*); -SQLITE_PRIVATE int tdsqlite3SchemaMutexHeld(tdsqlite3*,int,Schema*); +SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree*); +SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*); +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*); #endif #else -# define tdsqlite3BtreeLeave(X) -# define tdsqlite3BtreeLeaveCursor(X) -# define tdsqlite3BtreeLeaveAll(X) +# define sqlite3BtreeLeave(X) +# define sqlite3BtreeLeaveCursor(X) +# define sqlite3BtreeLeaveAll(X) -# define tdsqlite3BtreeHoldsMutex(X) 1 -# define tdsqlite3BtreeHoldsAllMutexes(X) 1 -# define tdsqlite3SchemaMutexHeld(X,Y,Z) 1 +# define sqlite3BtreeHoldsMutex(X) 1 +# define sqlite3BtreeHoldsAllMutexes(X) 1 +# define sqlite3SchemaMutexHeld(X,Y,Z) 1 #endif @@ -15068,7 +15068,7 @@ typedef struct Vdbe Vdbe; ** The names of the following types declared in vdbeInt.h are required ** for the VdbeOp definition. */ -typedef struct tdsqlite3_value Mem; +typedef struct sqlite3_value Mem; typedef struct SubProgram SubProgram; /* @@ -15090,7 +15090,7 @@ struct VdbeOp { i64 *pI64; /* Used when p4type is P4_INT64 */ double *pReal; /* Used when p4type is P4_REAL */ FuncDef *pFunc; /* Used when p4type is P4_FUNCDEF */ - tdsqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */ + sqlite3_context *pCtx; /* Used when p4type is P4_FUNCCTX */ CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ Mem *pMem; /* Used when p4type is P4_MEM */ VTable *pVtab; /* Used when p4type is P4_VTAB */ @@ -15161,11 +15161,11 @@ typedef struct VdbeOpList VdbeOpList; #define P4_KEYINFO (-9) /* P4 is a pointer to a KeyInfo structure */ #define P4_EXPR (-10) /* P4 is a pointer to an Expr tree */ #define P4_MEM (-11) /* P4 is a pointer to a Mem* structure */ -#define P4_VTAB (-12) /* P4 is a pointer to an tdsqlite3_vtab structure */ +#define P4_VTAB (-12) /* P4 is a pointer to an sqlite3_vtab structure */ #define P4_REAL (-13) /* P4 is a 64-bit floating point value */ #define P4_INT64 (-14) /* P4 is a 64-bit signed integer */ #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ -#define P4_FUNCCTX (-16) /* P4 is a pointer to an tdsqlite3_context object */ +#define P4_FUNCCTX (-16) /* P4 is a pointer to an sqlite3_context object */ #define P4_DYNBLOB (-17) /* Pointer to memory from sqliteMalloc() */ /* Error message codes for OP_Halt */ @@ -15194,7 +15194,7 @@ typedef struct VdbeOpList VdbeOpList; #endif /* -** The following macro converts a label returned by tdsqlite3VdbeMakeLabel() +** The following macro converts a label returned by sqlite3VdbeMakeLabel() ** into an index into the Parse.aLabel[] array that contains the resolved ** address of that label. */ @@ -15420,7 +15420,7 @@ typedef struct VdbeOpList VdbeOpList; /* 168 */ 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ } -/* The tdsqlite3P2Values() routine is able to run faster if it knows +/* The sqlite3P2Values() routine is able to run faster if it knows ** the value of the largest JUMP opcode. The smaller the maximum ** JUMP opcode the better, so the mkopcodeh.tcl script that ** generated this include file strives to group all JUMP opcodes @@ -15441,117 +15441,117 @@ typedef struct VdbeOpList VdbeOpList; ** Prototypes for the VDBE interface. See comments on the implementation ** for a description of what each of these routines does. */ -SQLITE_PRIVATE Vdbe *tdsqlite3VdbeCreate(Parse*); -SQLITE_PRIVATE Parse *tdsqlite3VdbeParser(Vdbe*); -SQLITE_PRIVATE int tdsqlite3VdbeAddOp0(Vdbe*,int); -SQLITE_PRIVATE int tdsqlite3VdbeAddOp1(Vdbe*,int,int); -SQLITE_PRIVATE int tdsqlite3VdbeAddOp2(Vdbe*,int,int,int); -SQLITE_PRIVATE int tdsqlite3VdbeGoto(Vdbe*,int); -SQLITE_PRIVATE int tdsqlite3VdbeLoadString(Vdbe*,int,const char*); -SQLITE_PRIVATE void tdsqlite3VdbeMultiLoad(Vdbe*,int,const char*,...); -SQLITE_PRIVATE int tdsqlite3VdbeAddOp3(Vdbe*,int,int,int,int); -SQLITE_PRIVATE int tdsqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); -SQLITE_PRIVATE int tdsqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); -SQLITE_PRIVATE int tdsqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); -SQLITE_PRIVATE int tdsqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int); -SQLITE_PRIVATE void tdsqlite3VdbeEndCoroutine(Vdbe*,int); +SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse*); +SQLITE_PRIVATE Parse *sqlite3VdbeParser(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe*,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe*,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe*,int,const char*); +SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe*,int,const char*,...); +SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe*,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4(Vdbe*,int,int,int,int,const char *zP4,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8(Vdbe*,int,int,int,int,const u8*,int); +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int(Vdbe*,int,int,int,int,int); +SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall(Parse*,int,int,int,int,const FuncDef*,int); +SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe*,int); #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) -SQLITE_PRIVATE void tdsqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); -SQLITE_PRIVATE void tdsqlite3VdbeVerifyNoResultRow(Vdbe *p); +SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N); +SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p); #else -# define tdsqlite3VdbeVerifyNoMallocRequired(A,B) -# define tdsqlite3VdbeVerifyNoResultRow(A) +# define sqlite3VdbeVerifyNoMallocRequired(A,B) +# define sqlite3VdbeVerifyNoResultRow(A) #endif #if defined(SQLITE_DEBUG) -SQLITE_PRIVATE void tdsqlite3VdbeVerifyAbortable(Vdbe *p, int); +SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int); #else -# define tdsqlite3VdbeVerifyAbortable(A,B) +# define sqlite3VdbeVerifyAbortable(A,B) #endif -SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList(Vdbe*, int nOp, VdbeOpList const *aOp,int iLineno); #ifndef SQLITE_OMIT_EXPLAIN -SQLITE_PRIVATE void tdsqlite3VdbeExplain(Parse*,u8,const char*,...); -SQLITE_PRIVATE void tdsqlite3VdbeExplainPop(Parse*); -SQLITE_PRIVATE int tdsqlite3VdbeExplainParent(Parse*); -# define ExplainQueryPlan(P) tdsqlite3VdbeExplain P -# define ExplainQueryPlanPop(P) tdsqlite3VdbeExplainPop(P) -# define ExplainQueryPlanParent(P) tdsqlite3VdbeExplainParent(P) +SQLITE_PRIVATE void sqlite3VdbeExplain(Parse*,u8,const char*,...); +SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse*); +SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse*); +# define ExplainQueryPlan(P) sqlite3VdbeExplain P +# define ExplainQueryPlanPop(P) sqlite3VdbeExplainPop(P) +# define ExplainQueryPlanParent(P) sqlite3VdbeExplainParent(P) #else # define ExplainQueryPlan(P) # define ExplainQueryPlanPop(P) # define ExplainQueryPlanParent(P) 0 -# define tdsqlite3ExplainBreakpoint(A,B) /*no-op*/ +# define sqlite3ExplainBreakpoint(A,B) /*no-op*/ #endif #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN) -SQLITE_PRIVATE void tdsqlite3ExplainBreakpoint(const char*,const char*); -#else -# define tdsqlite3ExplainBreakpoint(A,B) /*no-op*/ -#endif -SQLITE_PRIVATE void tdsqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); -SQLITE_PRIVATE void tdsqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); -SQLITE_PRIVATE void tdsqlite3VdbeChangeP1(Vdbe*, int addr, int P1); -SQLITE_PRIVATE void tdsqlite3VdbeChangeP2(Vdbe*, int addr, int P2); -SQLITE_PRIVATE void tdsqlite3VdbeChangeP3(Vdbe*, int addr, int P3); -SQLITE_PRIVATE void tdsqlite3VdbeChangeP5(Vdbe*, u16 P5); -SQLITE_PRIVATE void tdsqlite3VdbeJumpHere(Vdbe*, int addr); -SQLITE_PRIVATE int tdsqlite3VdbeChangeToNoop(Vdbe*, int addr); -SQLITE_PRIVATE int tdsqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); +SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char*,const char*); +#else +# define sqlite3ExplainBreakpoint(A,B) /*no-op*/ +#endif +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*); +SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe*, int addr, u8); +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe*, int addr, int P1); +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe*, int addr, int P2); +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe*, int addr, int P3); +SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe*, u16 P5); +SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe*, int addr); +SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe*, int addr); +SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE void tdsqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int); -#else -# define tdsqlite3VdbeReleaseRegisters(P,A,N,M,F) -#endif -SQLITE_PRIVATE void tdsqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); -SQLITE_PRIVATE void tdsqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); -SQLITE_PRIVATE void tdsqlite3VdbeSetP4KeyInfo(Parse*, Index*); -SQLITE_PRIVATE void tdsqlite3VdbeUsesBtree(Vdbe*, int); -SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeGetOp(Vdbe*, int); -SQLITE_PRIVATE int tdsqlite3VdbeMakeLabel(Parse*); -SQLITE_PRIVATE void tdsqlite3VdbeRunOnlyOnce(Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeReusable(Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeDelete(Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeClearObject(tdsqlite3*,Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeMakeReady(Vdbe*,Parse*); -SQLITE_PRIVATE int tdsqlite3VdbeFinalize(Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeResolveLabel(Vdbe*, int); -SQLITE_PRIVATE int tdsqlite3VdbeCurrentAddr(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters(Parse*,int addr, int n, u32 mask, int); +#else +# define sqlite3VdbeReleaseRegisters(P,A,N,M,F) +#endif +SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N); +SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type); +SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse*, Index*); +SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse*); +SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3*,Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); +SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); +SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3VdbeAssertMayAbort(Vdbe *, int); -#endif -SQLITE_PRIVATE void tdsqlite3VdbeResetStepResult(Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeRewind(Vdbe*); -SQLITE_PRIVATE int tdsqlite3VdbeReset(Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeSetNumCols(Vdbe*,int); -SQLITE_PRIVATE int tdsqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); -SQLITE_PRIVATE void tdsqlite3VdbeCountChanges(Vdbe*); -SQLITE_PRIVATE tdsqlite3 *tdsqlite3VdbeDb(Vdbe*); -SQLITE_PRIVATE u8 tdsqlite3VdbePrepareFlags(Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8); +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); +#endif +SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); +SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); +SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); +SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8); #ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE void tdsqlite3VdbeAddDblquoteStr(tdsqlite3*,Vdbe*,const char*); -SQLITE_PRIVATE int tdsqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*); +SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*); +SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString(Vdbe*,const char*); #endif -SQLITE_PRIVATE void tdsqlite3VdbeSwap(Vdbe*,Vdbe*); -SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeTakeOpArray(Vdbe*, int*, int*); -SQLITE_PRIVATE tdsqlite3_value *tdsqlite3VdbeGetBoundValue(Vdbe*, int, u8); -SQLITE_PRIVATE void tdsqlite3VdbeSetVarmask(Vdbe*, int); +SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); +SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); +SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE -SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql(Vdbe*, const char*); +SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif -SQLITE_PRIVATE int tdsqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); -SQLITE_PRIVATE int tdsqlite3BlobCompare(const Mem*, const Mem*); +SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); +SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); -SQLITE_PRIVATE void tdsqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); -SQLITE_PRIVATE int tdsqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); -SQLITE_PRIVATE int tdsqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); -SQLITE_PRIVATE UnpackedRecord *tdsqlite3VdbeAllocUnpackedRecord(KeyInfo*); +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(KeyInfo*,int,const void*,UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); -SQLITE_PRIVATE RecordCompare tdsqlite3VdbeFindCompare(UnpackedRecord*); +SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord*); -SQLITE_PRIVATE void tdsqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); -SQLITE_PRIVATE int tdsqlite3VdbeHasSubProgram(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *, SubProgram *); +SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe*); -SQLITE_PRIVATE int tdsqlite3NotPureFunc(tdsqlite3_context*); +SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context*); /* Use SQLITE_ENABLE_COMMENTS to enable generation of extra comments on ** each VDBE opcode. @@ -15561,12 +15561,12 @@ SQLITE_PRIVATE int tdsqlite3NotPureFunc(tdsqlite3_context*); ** generator. */ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS -SQLITE_PRIVATE void tdsqlite3VdbeComment(Vdbe*, const char*, ...); -# define VdbeComment(X) tdsqlite3VdbeComment X -SQLITE_PRIVATE void tdsqlite3VdbeNoopComment(Vdbe*, const char*, ...); -# define VdbeNoopComment(X) tdsqlite3VdbeNoopComment X +SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe*, const char*, ...); +# define VdbeComment(X) sqlite3VdbeComment X +SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); +# define VdbeNoopComment(X) sqlite3VdbeNoopComment X # ifdef SQLITE_ENABLE_MODULE_COMMENTS -# define VdbeModuleComment(X) tdsqlite3VdbeNoopComment X +# define VdbeModuleComment(X) sqlite3VdbeNoopComment X # else # define VdbeModuleComment(X) # endif @@ -15606,7 +15606,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeNoopComment(Vdbe*, const char*, ...); ** routine in vdbe.c, alerting the developer to the missed tag. ** ** During testing, the test application will invoke -** tdsqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback +** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback ** routine that is invoked as each bytecode branch is taken. The callback ** contains the sqlite3.c source line number ov the VdbeCoverage macro and ** flags to indicate whether or not the branch was taken. The test application @@ -15617,19 +15617,19 @@ SQLITE_PRIVATE void tdsqlite3VdbeNoopComment(Vdbe*, const char*, ...); ** vdbe.c source file for additional information. */ #ifdef SQLITE_VDBE_COVERAGE -SQLITE_PRIVATE void tdsqlite3VdbeSetLineNumber(Vdbe*,int); -# define VdbeCoverage(v) tdsqlite3VdbeSetLineNumber(v,__LINE__) -# define VdbeCoverageIf(v,x) if(x)tdsqlite3VdbeSetLineNumber(v,__LINE__) +SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe*,int); +# define VdbeCoverage(v) sqlite3VdbeSetLineNumber(v,__LINE__) +# define VdbeCoverageIf(v,x) if(x)sqlite3VdbeSetLineNumber(v,__LINE__) # define VdbeCoverageAlwaysTaken(v) \ - tdsqlite3VdbeSetLineNumber(v,__LINE__|0x5000000); + sqlite3VdbeSetLineNumber(v,__LINE__|0x5000000); # define VdbeCoverageNeverTaken(v) \ - tdsqlite3VdbeSetLineNumber(v,__LINE__|0x6000000); + sqlite3VdbeSetLineNumber(v,__LINE__|0x6000000); # define VdbeCoverageNeverNull(v) \ - tdsqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); + sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); # define VdbeCoverageNeverNullIf(v,x) \ - if(x)tdsqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); + if(x)sqlite3VdbeSetLineNumber(v,__LINE__|0x4000000); # define VdbeCoverageEqNe(v) \ - tdsqlite3VdbeSetLineNumber(v,__LINE__|0x8000000); + sqlite3VdbeSetLineNumber(v,__LINE__|0x8000000); # define VDBE_OFFSET_LINENO(x) (__LINE__+x) #else # define VdbeCoverage(v) @@ -15643,13 +15643,13 @@ SQLITE_PRIVATE void tdsqlite3VdbeSetLineNumber(Vdbe*,int); #endif #ifdef SQLITE_ENABLE_STMT_SCANSTATUS -SQLITE_PRIVATE void tdsqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); +SQLITE_PRIVATE void sqlite3VdbeScanStatus(Vdbe*, int, int, int, LogEst, const char*); #else -# define tdsqlite3VdbeScanStatus(a,b,c,d,e) +# define sqlite3VdbeScanStatus(a,b,c,d,e) #endif #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) -SQLITE_PRIVATE void tdsqlite3VdbePrintOp(FILE*, int, VdbeOp*); +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE*, int, VdbeOp*); #endif #endif /* SQLITE_VDBE_H */ @@ -15680,7 +15680,7 @@ SQLITE_PRIVATE void tdsqlite3VdbePrintOp(FILE*, int, VdbeOp*); /* ** Default maximum size for persistent journal files. A negative ** value means no limit. This value may be overridden using the -** tdsqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit". +** sqlite3PagerJournalSizeLimit() API. See also "PRAGMA journal_size_limit". */ #ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1 @@ -15713,7 +15713,7 @@ typedef struct PgHdr DbPage; #define PAGER_MJ_PGNO(x) ((Pgno)((PENDING_BYTE/((x)->pageSize))+1)) /* -** Allowed values for the flags parameter to tdsqlite3PagerOpen(). +** Allowed values for the flags parameter to sqlite3PagerOpen(). ** ** NOTE: These values must match the corresponding BTREE_ values in btree.h. */ @@ -15721,7 +15721,7 @@ typedef struct PgHdr DbPage; #define PAGER_MEMORY 0x0002 /* In-memory database */ /* -** Valid values for the second argument to tdsqlite3PagerLockingMode(). +** Valid values for the second argument to sqlite3PagerLockingMode(). */ #define PAGER_LOCKINGMODE_QUERY -1 #define PAGER_LOCKINGMODE_NORMAL 0 @@ -15743,13 +15743,13 @@ typedef struct PgHdr DbPage; #define PAGER_JOURNALMODE_WAL 5 /* Use write-ahead logging */ /* -** Flags that make up the mask passed to tdsqlite3PagerGet(). +** Flags that make up the mask passed to sqlite3PagerGet(). */ #define PAGER_GET_NOCONTENT 0x01 /* Do not load data from disk */ #define PAGER_GET_READONLY 0x02 /* Read-only page is acceptable */ /* -** Flags for tdsqlite3PagerSetFlags() +** Flags for sqlite3PagerSetFlags() ** ** Value constraints (enforced via assert()): ** PAGER_FULLFSYNC == SQLITE_FullFSync @@ -15773,8 +15773,8 @@ typedef struct PgHdr DbPage; */ /* Open and close a Pager connection. */ -SQLITE_PRIVATE int tdsqlite3PagerOpen( - tdsqlite3_vfs*, +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs*, Pager **ppPager, const char*, int, @@ -15782,120 +15782,120 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( int, void(*)(DbPage*) ); -SQLITE_PRIVATE int tdsqlite3PagerClose(Pager *pPager, tdsqlite3*); -SQLITE_PRIVATE int tdsqlite3PagerReadFileheader(Pager*, int, unsigned char*); +SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3*); +SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); /* Functions used to configure a Pager object. */ -SQLITE_PRIVATE void tdsqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *); -SQLITE_PRIVATE int tdsqlite3PagerSetPagesize(Pager*, u32*, int); +SQLITE_PRIVATE void sqlite3PagerSetBusyHandler(Pager*, int(*)(void *), void *); +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u32*, int); #ifdef SQLITE_HAS_CODEC -SQLITE_PRIVATE void tdsqlite3PagerAlignReserve(Pager*,Pager*); -#endif -SQLITE_PRIVATE int tdsqlite3PagerMaxPageCount(Pager*, int); -SQLITE_PRIVATE void tdsqlite3PagerSetCachesize(Pager*, int); -SQLITE_PRIVATE int tdsqlite3PagerSetSpillsize(Pager*, int); -SQLITE_PRIVATE void tdsqlite3PagerSetMmapLimit(Pager *, tdsqlite3_int64); -SQLITE_PRIVATE void tdsqlite3PagerShrink(Pager*); -SQLITE_PRIVATE void tdsqlite3PagerSetFlags(Pager*,unsigned); -SQLITE_PRIVATE int tdsqlite3PagerLockingMode(Pager *, int); -SQLITE_PRIVATE int tdsqlite3PagerSetJournalMode(Pager *, int); -SQLITE_PRIVATE int tdsqlite3PagerGetJournalMode(Pager*); -SQLITE_PRIVATE int tdsqlite3PagerOkToChangeJournalMode(Pager*); -SQLITE_PRIVATE i64 tdsqlite3PagerJournalSizeLimit(Pager *, i64); -SQLITE_PRIVATE tdsqlite3_backup **tdsqlite3PagerBackupPtr(Pager*); -SQLITE_PRIVATE int tdsqlite3PagerFlush(Pager*); +SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager*,Pager*); +#endif +SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); +SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); +SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager*, int); +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *, sqlite3_int64); +SQLITE_PRIVATE void sqlite3PagerShrink(Pager*); +SQLITE_PRIVATE void sqlite3PagerSetFlags(Pager*,unsigned); +SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *, int); +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager*); +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager*); +SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64); +SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager*); +SQLITE_PRIVATE int sqlite3PagerFlush(Pager*); /* Functions used to obtain and release page references. */ -SQLITE_PRIVATE int tdsqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); -SQLITE_PRIVATE DbPage *tdsqlite3PagerLookup(Pager *pPager, Pgno pgno); -SQLITE_PRIVATE void tdsqlite3PagerRef(DbPage*); -SQLITE_PRIVATE void tdsqlite3PagerUnref(DbPage*); -SQLITE_PRIVATE void tdsqlite3PagerUnrefNotNull(DbPage*); -SQLITE_PRIVATE void tdsqlite3PagerUnrefPageOne(DbPage*); +SQLITE_PRIVATE int sqlite3PagerGet(Pager *pPager, Pgno pgno, DbPage **ppPage, int clrFlag); +SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno); +SQLITE_PRIVATE void sqlite3PagerRef(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnref(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage*); +SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage*); /* Operations on page references. */ -SQLITE_PRIVATE int tdsqlite3PagerWrite(DbPage*); -SQLITE_PRIVATE void tdsqlite3PagerDontWrite(DbPage*); -SQLITE_PRIVATE int tdsqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); -SQLITE_PRIVATE int tdsqlite3PagerPageRefcount(DbPage*); -SQLITE_PRIVATE void *tdsqlite3PagerGetData(DbPage *); -SQLITE_PRIVATE void *tdsqlite3PagerGetExtra(DbPage *); +SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*); +SQLITE_PRIVATE void sqlite3PagerDontWrite(DbPage*); +SQLITE_PRIVATE int sqlite3PagerMovepage(Pager*,DbPage*,Pgno,int); +SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage*); +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *); +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); /* Functions used to manage pager transactions and savepoints. */ -SQLITE_PRIVATE void tdsqlite3PagerPagecount(Pager*, int*); -SQLITE_PRIVATE int tdsqlite3PagerBegin(Pager*, int exFlag, int); -SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); -SQLITE_PRIVATE int tdsqlite3PagerExclusiveLock(Pager*); -SQLITE_PRIVATE int tdsqlite3PagerSync(Pager *pPager, const char *zMaster); -SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseTwo(Pager*); -SQLITE_PRIVATE int tdsqlite3PagerRollback(Pager*); -SQLITE_PRIVATE int tdsqlite3PagerOpenSavepoint(Pager *pPager, int n); -SQLITE_PRIVATE int tdsqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); -SQLITE_PRIVATE int tdsqlite3PagerSharedLock(Pager *pPager); +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager*, int*); +SQLITE_PRIVATE int sqlite3PagerBegin(Pager*, int exFlag, int); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, int); +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager*); +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster); +SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); +SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); +SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n); +SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager); #ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int tdsqlite3PagerCheckpoint(Pager *pPager, tdsqlite3*, int, int*, int*); -SQLITE_PRIVATE int tdsqlite3PagerWalSupported(Pager *pPager); -SQLITE_PRIVATE int tdsqlite3PagerWalCallback(Pager *pPager); -SQLITE_PRIVATE int tdsqlite3PagerOpenWal(Pager *pPager, int *pisOpen); -SQLITE_PRIVATE int tdsqlite3PagerCloseWal(Pager *pPager, tdsqlite3*); +SQLITE_PRIVATE int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*); +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen); +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3*); # ifdef SQLITE_ENABLE_SNAPSHOT -SQLITE_PRIVATE int tdsqlite3PagerSnapshotGet(Pager *pPager, tdsqlite3_snapshot **ppSnapshot); -SQLITE_PRIVATE int tdsqlite3PagerSnapshotOpen(Pager *pPager, tdsqlite3_snapshot *pSnapshot); -SQLITE_PRIVATE int tdsqlite3PagerSnapshotRecover(Pager *pPager); -SQLITE_PRIVATE int tdsqlite3PagerSnapshotCheck(Pager *pPager, tdsqlite3_snapshot *pSnapshot); -SQLITE_PRIVATE void tdsqlite3PagerSnapshotUnlock(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot); +SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager); # endif #endif #ifdef SQLITE_DIRECT_OVERFLOW_READ -SQLITE_PRIVATE int tdsqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno); +SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno); #endif #ifdef SQLITE_ENABLE_ZIPVFS -SQLITE_PRIVATE int tdsqlite3PagerWalFramesize(Pager *pPager); +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager); #endif /* Functions used to query pager state and configuration. */ -SQLITE_PRIVATE u8 tdsqlite3PagerIsreadonly(Pager*); -SQLITE_PRIVATE u32 tdsqlite3PagerDataVersion(Pager*); +SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); +SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager*); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3PagerRefcount(Pager*); -#endif -SQLITE_PRIVATE int tdsqlite3PagerMemUsed(Pager*); -SQLITE_PRIVATE const char *tdsqlite3PagerFilename(const Pager*, int); -SQLITE_PRIVATE tdsqlite3_vfs *tdsqlite3PagerVfs(Pager*); -SQLITE_PRIVATE tdsqlite3_file *tdsqlite3PagerFile(Pager*); -SQLITE_PRIVATE tdsqlite3_file *tdsqlite3PagerJrnlFile(Pager*); -SQLITE_PRIVATE const char *tdsqlite3PagerJournalname(Pager*); -SQLITE_PRIVATE void *tdsqlite3PagerTempSpace(Pager*); -SQLITE_PRIVATE int tdsqlite3PagerIsMemdb(Pager*); -SQLITE_PRIVATE void tdsqlite3PagerCacheStat(Pager *, int, int, int *); -SQLITE_PRIVATE void tdsqlite3PagerClearCache(Pager*); -SQLITE_PRIVATE int tdsqlite3SectorSize(tdsqlite3_file *); +SQLITE_PRIVATE int sqlite3PagerRefcount(Pager*); +#endif +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager*); +SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager*, int); +SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager*); +SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager*); +SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager*); +SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager*); +SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*); +SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *, int, int, int *); +SQLITE_PRIVATE void sqlite3PagerClearCache(Pager*); +SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *); #ifdef SQLITE_ENABLE_SETLK_TIMEOUT -SQLITE_PRIVATE void tdsqlite3PagerResetLockTimeout(Pager *pPager); +SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager); #else -# define tdsqlite3PagerResetLockTimeout(X) +# define sqlite3PagerResetLockTimeout(X) #endif /* Functions used to truncate the database file. */ -SQLITE_PRIVATE void tdsqlite3PagerTruncateImage(Pager*,Pgno); +SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); -SQLITE_PRIVATE void tdsqlite3PagerRekey(DbPage*, Pgno, u16); +SQLITE_PRIVATE void sqlite3PagerRekey(DbPage*, Pgno, u16); #if defined(SQLITE_HAS_CODEC) && !defined(SQLITE_OMIT_WAL) -SQLITE_PRIVATE void *tdsqlite3PagerCodec(DbPage *); +SQLITE_PRIVATE void *sqlite3PagerCodec(DbPage *); #endif /* Functions to support testing and debugging. */ #if !defined(NDEBUG) || defined(SQLITE_TEST) -SQLITE_PRIVATE Pgno tdsqlite3PagerPagenumber(DbPage*); -SQLITE_PRIVATE int tdsqlite3PagerIswriteable(DbPage*); +SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*); +SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage*); #endif #ifdef SQLITE_TEST -SQLITE_PRIVATE int *tdsqlite3PagerStats(Pager*); -SQLITE_PRIVATE void tdsqlite3PagerRefdump(Pager*); +SQLITE_PRIVATE int *sqlite3PagerStats(Pager*); +SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); void disable_simulated_io_errors(void); void enable_simulated_io_errors(void); #else @@ -15934,7 +15934,7 @@ typedef struct PCache PCache; ** structure. */ struct PgHdr { - tdsqlite3_pcache_page *pPage; /* Pcache object page handle */ + sqlite3_pcache_page *pPage; /* Pcache object page handle */ void *pData; /* Page data */ void *pExtra; /* Extra content */ PCache *pCache; /* PRIVATE: Cache that owns this page */ @@ -15970,19 +15970,19 @@ struct PgHdr { #define PGHDR_WAL_APPEND 0x040 /* Appended to wal file */ /* Initialize and shutdown the page cache subsystem */ -SQLITE_PRIVATE int tdsqlite3PcacheInitialize(void); -SQLITE_PRIVATE void tdsqlite3PcacheShutdown(void); +SQLITE_PRIVATE int sqlite3PcacheInitialize(void); +SQLITE_PRIVATE void sqlite3PcacheShutdown(void); /* Page cache buffer management: ** These routines implement SQLITE_CONFIG_PAGECACHE. */ -SQLITE_PRIVATE void tdsqlite3PCacheBufferSetup(void *, int sz, int n); +SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *, int sz, int n); /* Create a new pager cache. ** Under memory stress, invoke xStress to try to make pages clean. ** Only clean and unpinned pages can be reclaimed. */ -SQLITE_PRIVATE int tdsqlite3PcacheOpen( +SQLITE_PRIVATE int sqlite3PcacheOpen( int szPage, /* Size of every page */ int szExtra, /* Extra space associated with each page */ int bPurgeable, /* True if pages are on backing store */ @@ -15992,67 +15992,67 @@ SQLITE_PRIVATE int tdsqlite3PcacheOpen( ); /* Modify the page-size after the cache has been created. */ -SQLITE_PRIVATE int tdsqlite3PcacheSetPageSize(PCache *, int); +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *, int); /* Return the size in bytes of a PCache object. Used to preallocate ** storage space. */ -SQLITE_PRIVATE int tdsqlite3PcacheSize(void); +SQLITE_PRIVATE int sqlite3PcacheSize(void); /* One release per successful fetch. Page is pinned until released. ** Reference counted. */ -SQLITE_PRIVATE tdsqlite3_pcache_page *tdsqlite3PcacheFetch(PCache*, Pgno, int createFlag); -SQLITE_PRIVATE int tdsqlite3PcacheFetchStress(PCache*, Pgno, tdsqlite3_pcache_page**); -SQLITE_PRIVATE PgHdr *tdsqlite3PcacheFetchFinish(PCache*, Pgno, tdsqlite3_pcache_page *pPage); -SQLITE_PRIVATE void tdsqlite3PcacheRelease(PgHdr*); +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch(PCache*, Pgno, int createFlag); +SQLITE_PRIVATE int sqlite3PcacheFetchStress(PCache*, Pgno, sqlite3_pcache_page**); +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish(PCache*, Pgno, sqlite3_pcache_page *pPage); +SQLITE_PRIVATE void sqlite3PcacheRelease(PgHdr*); -SQLITE_PRIVATE void tdsqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ -SQLITE_PRIVATE void tdsqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ -SQLITE_PRIVATE void tdsqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ -SQLITE_PRIVATE void tdsqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ -SQLITE_PRIVATE void tdsqlite3PcacheClearWritable(PCache*); +SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr*); /* Remove page from cache */ +SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr*); /* Make sure page is marked dirty */ +SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr*); /* Mark a single page as clean */ +SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache*); /* Mark all dirty list pages as clean */ +SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache*); /* Change a page number. Used by incr-vacuum. */ -SQLITE_PRIVATE void tdsqlite3PcacheMove(PgHdr*, Pgno); +SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr*, Pgno); /* Remove all pages with pgno>x. Reset the cache if x==0 */ -SQLITE_PRIVATE void tdsqlite3PcacheTruncate(PCache*, Pgno x); +SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache*, Pgno x); /* Get a list of all dirty pages in the cache, sorted by page number */ -SQLITE_PRIVATE PgHdr *tdsqlite3PcacheDirtyList(PCache*); +SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache*); /* Reset and close the cache object */ -SQLITE_PRIVATE void tdsqlite3PcacheClose(PCache*); +SQLITE_PRIVATE void sqlite3PcacheClose(PCache*); /* Clear flags from pages of the page cache */ -SQLITE_PRIVATE void tdsqlite3PcacheClearSyncFlags(PCache *); +SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *); /* Discard the contents of the cache */ -SQLITE_PRIVATE void tdsqlite3PcacheClear(PCache*); +SQLITE_PRIVATE void sqlite3PcacheClear(PCache*); /* Return the total number of outstanding page references */ -SQLITE_PRIVATE int tdsqlite3PcacheRefCount(PCache*); +SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache*); /* Increment the reference count of an existing page */ -SQLITE_PRIVATE void tdsqlite3PcacheRef(PgHdr*); +SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr*); -SQLITE_PRIVATE int tdsqlite3PcachePageRefcount(PgHdr*); +SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*); /* Return the total number of pages stored in the cache */ -SQLITE_PRIVATE int tdsqlite3PcachePagecount(PCache*); +SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); #if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) /* Iterate through all dirty pages currently stored in the cache. This ** interface is only available if SQLITE_CHECK_PAGES is defined when the ** library is built. */ -SQLITE_PRIVATE void tdsqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); +SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)); #endif #if defined(SQLITE_DEBUG) /* Check invariants on a PgHdr object */ -SQLITE_PRIVATE int tdsqlite3PcachePageSanity(PgHdr*); +SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr*); #endif /* Set and get the suggested cache-size for the specified pager-cache. @@ -16061,9 +16061,9 @@ SQLITE_PRIVATE int tdsqlite3PcachePageSanity(PgHdr*); ** the total number of pages cached by purgeable pager-caches to the sum ** of the suggested cache-sizes. */ -SQLITE_PRIVATE void tdsqlite3PcacheSetCachesize(PCache *, int); +SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *, int); #ifdef SQLITE_TEST -SQLITE_PRIVATE int tdsqlite3PcacheGetCachesize(PCache *); +SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *); #endif /* Set or get the suggested spill-size for the specified pager-cache. @@ -16071,31 +16071,31 @@ SQLITE_PRIVATE int tdsqlite3PcacheGetCachesize(PCache *); ** The spill-size is the minimum number of pages in cache before the cache ** will attempt to spill dirty pages by calling xStress. */ -SQLITE_PRIVATE int tdsqlite3PcacheSetSpillsize(PCache *, int); +SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *, int); /* Free up as much memory as possible from the page cache */ -SQLITE_PRIVATE void tdsqlite3PcacheShrink(PCache*); +SQLITE_PRIVATE void sqlite3PcacheShrink(PCache*); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* Try to return memory used by the pcache module to the main memory heap */ -SQLITE_PRIVATE int tdsqlite3PcacheReleaseMemory(int); +SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int); #endif #ifdef SQLITE_TEST -SQLITE_PRIVATE void tdsqlite3PcacheStats(int*,int*,int*,int*); +SQLITE_PRIVATE void sqlite3PcacheStats(int*,int*,int*,int*); #endif -SQLITE_PRIVATE void tdsqlite3PCacheSetDefault(void); +SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); /* Return the header size */ -SQLITE_PRIVATE int tdsqlite3HeaderSizePcache(void); -SQLITE_PRIVATE int tdsqlite3HeaderSizePcache1(void); +SQLITE_PRIVATE int sqlite3HeaderSizePcache(void); +SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void); /* Number of dirty pages as a percentage of the configured cache size */ -SQLITE_PRIVATE int tdsqlite3PCachePercentDirty(PCache*); +SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache*); #ifdef SQLITE_DIRECT_OVERFLOW_READ -SQLITE_PRIVATE int tdsqlite3PCacheIsDirty(PCache *pCache); +SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache); #endif #endif /* _PCACHE_H_ */ @@ -16234,7 +16234,7 @@ SQLITE_PRIVATE int tdsqlite3PCacheIsDirty(PCache *pCache); /* ** The following values may be passed as the second argument to -** tdsqlite3OsLock(). The various locks exhibit the following semantics: +** sqlite3OsLock(). The various locks exhibit the following semantics: ** ** SHARED: Any number of processes may hold a SHARED lock simultaneously. ** RESERVED: A single process may hold a RESERVED lock on a file at @@ -16244,10 +16244,10 @@ SQLITE_PRIVATE int tdsqlite3PCacheIsDirty(PCache *pCache); ** SHARED locks may be obtained by other processes. ** EXCLUSIVE: An EXCLUSIVE lock precludes all other locks. ** -** PENDING_LOCK may not be passed directly to tdsqlite3OsLock(). Instead, a +** PENDING_LOCK may not be passed directly to sqlite3OsLock(). Instead, a ** process that requests an EXCLUSIVE lock may actually obtain a PENDING ** lock. This can be upgraded to an EXCLUSIVE lock by a subsequent call to -** tdsqlite3OsLock(). +** sqlite3OsLock(). */ #define NO_LOCK 0 #define SHARED_LOCK 1 @@ -16313,68 +16313,68 @@ SQLITE_PRIVATE int tdsqlite3PCacheIsDirty(PCache *pCache); #ifdef SQLITE_OMIT_WSD # define PENDING_BYTE (0x40000000) #else -# define PENDING_BYTE tdsqlite3PendingByte +# define PENDING_BYTE sqlite3PendingByte #endif #define RESERVED_BYTE (PENDING_BYTE+1) #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 /* -** Wrapper around OS specific tdsqlite3_os_init() function. +** Wrapper around OS specific sqlite3_os_init() function. */ -SQLITE_PRIVATE int tdsqlite3OsInit(void); +SQLITE_PRIVATE int sqlite3OsInit(void); /* -** Functions for accessing tdsqlite3_file methods -*/ -SQLITE_PRIVATE void tdsqlite3OsClose(tdsqlite3_file*); -SQLITE_PRIVATE int tdsqlite3OsRead(tdsqlite3_file*, void*, int amt, i64 offset); -SQLITE_PRIVATE int tdsqlite3OsWrite(tdsqlite3_file*, const void*, int amt, i64 offset); -SQLITE_PRIVATE int tdsqlite3OsTruncate(tdsqlite3_file*, i64 size); -SQLITE_PRIVATE int tdsqlite3OsSync(tdsqlite3_file*, int); -SQLITE_PRIVATE int tdsqlite3OsFileSize(tdsqlite3_file*, i64 *pSize); -SQLITE_PRIVATE int tdsqlite3OsLock(tdsqlite3_file*, int); -SQLITE_PRIVATE int tdsqlite3OsUnlock(tdsqlite3_file*, int); -SQLITE_PRIVATE int tdsqlite3OsCheckReservedLock(tdsqlite3_file *id, int *pResOut); -SQLITE_PRIVATE int tdsqlite3OsFileControl(tdsqlite3_file*,int,void*); -SQLITE_PRIVATE void tdsqlite3OsFileControlHint(tdsqlite3_file*,int,void*); +** Functions for accessing sqlite3_file methods +*/ +SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file*); +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file*, void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file*, const void*, int amt, i64 offset); +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file*, i64 size); +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize); +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int); +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*); +SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file*,int,void*); #define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0 -SQLITE_PRIVATE int tdsqlite3OsSectorSize(tdsqlite3_file *id); -SQLITE_PRIVATE int tdsqlite3OsDeviceCharacteristics(tdsqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id); #ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int tdsqlite3OsShmMap(tdsqlite3_file *,int,int,int,void volatile **); -SQLITE_PRIVATE int tdsqlite3OsShmLock(tdsqlite3_file *id, int, int, int); -SQLITE_PRIVATE void tdsqlite3OsShmBarrier(tdsqlite3_file *id); -SQLITE_PRIVATE int tdsqlite3OsShmUnmap(tdsqlite3_file *id, int); +SQLITE_PRIVATE int sqlite3OsShmMap(sqlite3_file *,int,int,int,void volatile **); +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int, int, int); +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id); +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int); #endif /* SQLITE_OMIT_WAL */ -SQLITE_PRIVATE int tdsqlite3OsFetch(tdsqlite3_file *id, i64, int, void **); -SQLITE_PRIVATE int tdsqlite3OsUnfetch(tdsqlite3_file *, i64, void *); +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64, int, void **); +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *, i64, void *); /* -** Functions for accessing tdsqlite3_vfs methods +** Functions for accessing sqlite3_vfs methods */ -SQLITE_PRIVATE int tdsqlite3OsOpen(tdsqlite3_vfs *, const char *, tdsqlite3_file*, int, int *); -SQLITE_PRIVATE int tdsqlite3OsDelete(tdsqlite3_vfs *, const char *, int); -SQLITE_PRIVATE int tdsqlite3OsAccess(tdsqlite3_vfs *, const char *, int, int *pResOut); -SQLITE_PRIVATE int tdsqlite3OsFullPathname(tdsqlite3_vfs *, const char *, int, char *); +SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *); +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int); +SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut); +SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *); #ifndef SQLITE_OMIT_LOAD_EXTENSION -SQLITE_PRIVATE void *tdsqlite3OsDlOpen(tdsqlite3_vfs *, const char *); -SQLITE_PRIVATE void tdsqlite3OsDlError(tdsqlite3_vfs *, int, char *); -SQLITE_PRIVATE void (*tdsqlite3OsDlSym(tdsqlite3_vfs *, void *, const char *))(void); -SQLITE_PRIVATE void tdsqlite3OsDlClose(tdsqlite3_vfs *, void *); +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *); +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); #endif /* SQLITE_OMIT_LOAD_EXTENSION */ -SQLITE_PRIVATE int tdsqlite3OsRandomness(tdsqlite3_vfs *, int, char *); -SQLITE_PRIVATE int tdsqlite3OsSleep(tdsqlite3_vfs *, int); -SQLITE_PRIVATE int tdsqlite3OsGetLastError(tdsqlite3_vfs*); -SQLITE_PRIVATE int tdsqlite3OsCurrentTimeInt64(tdsqlite3_vfs *, tdsqlite3_int64*); +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); +SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); /* ** Convenience functions for opening and closing files using -** tdsqlite3_malloc() to obtain space for the file-handle structure. +** sqlite3_malloc() to obtain space for the file-handle structure. */ -SQLITE_PRIVATE int tdsqlite3OsOpenMalloc(tdsqlite3_vfs *, const char *, tdsqlite3_file **, int,int*); -SQLITE_PRIVATE void tdsqlite3OsCloseFree(tdsqlite3_file *); +SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*); +SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *); #endif /* _SQLITE_OS_H_ */ @@ -16438,20 +16438,20 @@ SQLITE_PRIVATE void tdsqlite3OsCloseFree(tdsqlite3_file *); /* ** If this is a no-op implementation, implement everything as macros. */ -#define tdsqlite3_mutex_alloc(X) ((tdsqlite3_mutex*)8) -#define tdsqlite3_mutex_free(X) -#define tdsqlite3_mutex_enter(X) -#define tdsqlite3_mutex_try(X) SQLITE_OK -#define tdsqlite3_mutex_leave(X) -#define tdsqlite3_mutex_held(X) ((void)(X),1) -#define tdsqlite3_mutex_notheld(X) ((void)(X),1) -#define tdsqlite3MutexAlloc(X) ((tdsqlite3_mutex*)8) -#define tdsqlite3MutexInit() SQLITE_OK -#define tdsqlite3MutexEnd() +#define sqlite3_mutex_alloc(X) ((sqlite3_mutex*)8) +#define sqlite3_mutex_free(X) +#define sqlite3_mutex_enter(X) +#define sqlite3_mutex_try(X) SQLITE_OK +#define sqlite3_mutex_leave(X) +#define sqlite3_mutex_held(X) ((void)(X),1) +#define sqlite3_mutex_notheld(X) ((void)(X),1) +#define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) +#define sqlite3MutexInit() SQLITE_OK +#define sqlite3MutexEnd() #define MUTEX_LOGIC(X) #else #define MUTEX_LOGIC(X) X -SQLITE_API int tdsqlite3_mutex_held(tdsqlite3_mutex*); +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); #endif /* defined(SQLITE_MUTEX_OMIT) */ /************** End of mutex.h ***********************************************/ @@ -16513,11 +16513,11 @@ struct Db { ** ** Schema objects are automatically deallocated when the last Btree that ** references them is destroyed. The TEMP Schema is manually freed by -** tdsqlite3_close(). +** sqlite3_close(). * ** A thread must be holding a mutex on the corresponding Btree in order ** to access Schema content. This implies that the thread must also be -** holding a mutex on the tdsqlite3 connection pointer that owns the Btree. +** holding a mutex on the sqlite3 connection pointer that owns the Btree. ** For a TEMP Schema, only the connection mutex is required. */ struct Schema { @@ -16560,7 +16560,7 @@ struct Schema { /* ** The number of different kinds of things that can be limited -** using the tdsqlite3_limit() interface. +** using the sqlite3_limit() interface. */ #define SQLITE_N_LIMIT (SQLITE_LIMIT_WORKER_THREADS+1) @@ -16613,7 +16613,7 @@ struct Lookaside { u32 bDisable; /* Only operate the lookaside when zero */ u16 sz; /* Size of each buffer in bytes */ u16 szTrue; /* True value of sz, even if disabled */ - u8 bMalloced; /* True if pStart obtained from tdsqlite3_malloc() */ + u8 bMalloced; /* True if pStart obtained from sqlite3_malloc() */ u32 nSlot; /* Number of lookaside slots allocated */ u32 anStat[3]; /* 0: hits. 1: size misses. 2: full misses */ LookasideSlot *pInit; /* List of buffers not previously used */ @@ -16658,28 +16658,28 @@ struct FuncDefHash { #ifdef SQLITE_USER_AUTHENTICATION /* -** Information held in the "tdsqlite3" database connection object and used +** Information held in the "sqlite3" database connection object and used ** to manage user authentication. */ -typedef struct tdsqlite3_userauth tdsqlite3_userauth; -struct tdsqlite3_userauth { +typedef struct sqlite3_userauth sqlite3_userauth; +struct sqlite3_userauth { u8 authLevel; /* Current authentication level */ int nAuthPW; /* Size of the zAuthPW in bytes */ char *zAuthPW; /* Password used to authenticate */ char *zAuthUser; /* User name used to authenticate */ }; -/* Allowed values for tdsqlite3_userauth.authLevel */ +/* Allowed values for sqlite3_userauth.authLevel */ #define UAUTH_Unknown 0 /* Authentication not yet checked */ #define UAUTH_Fail 1 /* User authentication failed */ #define UAUTH_User 2 /* Authenticated as a normal user */ #define UAUTH_Admin 3 /* Authenticated as an administrator */ /* Functions used only by user authorization logic */ -SQLITE_PRIVATE int tdsqlite3UserAuthTable(const char*); -SQLITE_PRIVATE int tdsqlite3UserAuthCheckLogin(tdsqlite3*,const char*,u8*); -SQLITE_PRIVATE void tdsqlite3UserAuthInit(tdsqlite3*); -SQLITE_PRIVATE void tdsqlite3CryptFunc(tdsqlite3_context*,int,tdsqlite3_value**); +SQLITE_PRIVATE int sqlite3UserAuthTable(const char*); +SQLITE_PRIVATE int sqlite3UserAuthCheckLogin(sqlite3*,const char*,u8*); +SQLITE_PRIVATE void sqlite3UserAuthInit(sqlite3*); +SQLITE_PRIVATE void sqlite3CryptFunc(sqlite3_context*,int,sqlite3_value**); #endif /* SQLITE_USER_AUTHENTICATION */ @@ -16687,16 +16687,16 @@ SQLITE_PRIVATE void tdsqlite3CryptFunc(tdsqlite3_context*,int,tdsqlite3_value**) ** typedef for the authorization callback function. */ #ifdef SQLITE_USER_AUTHENTICATION - typedef int (*tdsqlite3_xauth)(void*,int,const char*,const char*,const char*, + typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, const char*, const char*); #else - typedef int (*tdsqlite3_xauth)(void*,int,const char*,const char*,const char*, + typedef int (*sqlite3_xauth)(void*,int,const char*,const char*,const char*, const char*); #endif #ifndef SQLITE_OMIT_DEPRECATED /* This is an extra SQLITE_TRACE macro that indicates "legacy" tracing -** in the style of tdsqlite3_trace() +** in the style of sqlite3_trace() */ #define SQLITE_TRACE_LEGACY 0x40 /* Use the legacy xTrace */ #define SQLITE_TRACE_XPROFILE 0x80 /* Use the legacy xProfile */ @@ -16710,11 +16710,11 @@ SQLITE_PRIVATE void tdsqlite3CryptFunc(tdsqlite3_context*,int,tdsqlite3_value**) /* ** Each database connection is an instance of the following structure. */ -struct tdsqlite3 { - tdsqlite3_vfs *pVfs; /* OS Interface */ +struct sqlite3 { + sqlite3_vfs *pVfs; /* OS Interface */ struct Vdbe *pVdbe; /* List of active virtual machines */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ - tdsqlite3_mutex *mutex; /* Connection mutex */ + sqlite3_mutex *mutex; /* Connection mutex */ Db *aDb; /* All backends */ int nDb; /* Number of backends currently in use */ u32 mDbFlags; /* flags recording internal state */ @@ -16722,7 +16722,7 @@ struct tdsqlite3 { i64 lastRowid; /* ROWID of most recent insert (see above) */ i64 szMmap; /* Default mmap_size setting */ u32 nSchemaLock; /* Do not reset the schema when non-zero */ - unsigned int openFlags; /* Flags passed to tdsqlite3_vfs.xOpen() */ + unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ int errCode; /* Most recent error code (SQLITE_*) */ int errMask; /* & result codes with this before returning */ int iSysErrno; /* Errno value from last system error */ @@ -16742,11 +16742,11 @@ struct tdsqlite3 { u8 nSqlExec; /* Number of pending OP_SqlExec opcodes */ int nextPagesize; /* Pagesize after VACUUM if >0 */ u32 magic; /* Magic number for detect library misuse */ - int nChange; /* Value returned by tdsqlite3_changes() */ - int nTotalChange; /* Value returned by tdsqlite3_total_changes() */ + int nChange; /* Value returned by sqlite3_changes() */ + int nTotalChange; /* Value returned by sqlite3_total_changes() */ int aLimit[SQLITE_N_LIMIT]; /* Limits */ int nMaxSorterMmap; /* Maximum size of regions mapped by sorter */ - struct tdsqlite3InitInfo { /* Information used during initialization */ + struct sqlite3InitInfo { /* Information used during initialization */ int newTnum; /* Rootpage of table being initialized */ u8 iDb; /* Which db file is being initialized */ u8 busy; /* TRUE if currently initializing */ @@ -16777,26 +16777,26 @@ struct tdsqlite3 { Parse *pParse; /* Current parse */ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK void *pPreUpdateArg; /* First argument to xPreUpdateCallback */ - void (*xPreUpdateCallback)( /* Registered using tdsqlite3_preupdate_hook() */ - void*,tdsqlite3*,int,char const*,char const*,tdsqlite3_int64,tdsqlite3_int64 + void (*xPreUpdateCallback)( /* Registered using sqlite3_preupdate_hook() */ + void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64 ); PreUpdate *pPreUpdate; /* Context for active pre-update callback */ #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifndef SQLITE_OMIT_WAL - int (*xWalCallback)(void *, tdsqlite3 *, const char *, int); + int (*xWalCallback)(void *, sqlite3 *, const char *, int); void *pWalArg; #endif - void(*xCollNeeded)(void*,tdsqlite3*,int eTextRep,const char*); - void(*xCollNeeded16)(void*,tdsqlite3*,int eTextRep,const void*); + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*); + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*); void *pCollNeededArg; - tdsqlite3_value *pErr; /* Most recent error message */ + sqlite3_value *pErr; /* Most recent error message */ union { - volatile int isInterrupted; /* True if tdsqlite3_interrupt has been called */ + volatile int isInterrupted; /* True if sqlite3_interrupt has been called */ double notUsed1; /* Spacer */ } u1; Lookaside lookaside; /* Lookaside malloc configuration */ #ifndef SQLITE_OMIT_AUTHORIZATION - tdsqlite3_xauth xAuth; /* Access authorization function */ + sqlite3_xauth xAuth; /* Access authorization function */ void *pAuthArg; /* 1st argument to the access auth function */ #endif #ifndef SQLITE_OMIT_PROGRESS_CALLBACK @@ -16806,10 +16806,10 @@ struct tdsqlite3 { #endif #ifndef SQLITE_OMIT_VIRTUALTABLE int nVTrans; /* Allocated size of aVTrans */ - Hash aModule; /* populated by tdsqlite3_create_module() */ + Hash aModule; /* populated by sqlite3_create_module() */ VtabCtx *pVtabCtx; /* Context for active vtab connect/create */ VTable **aVTrans; /* Virtual tables with open transactions */ - VTable *pDisconnect; /* Disconnect these in next tdsqlite3_prepare() */ + VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ #endif Hash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ @@ -16833,14 +16833,14 @@ struct tdsqlite3 { ** tried to do recently failed with an SQLITE_LOCKED error due to locks ** held by Y. */ - tdsqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */ - tdsqlite3 *pUnlockConnection; /* Connection to watch for unlock */ + sqlite3 *pBlockingConnection; /* Connection that caused SQLITE_LOCKED */ + sqlite3 *pUnlockConnection; /* Connection to watch for unlock */ void *pUnlockArg; /* Argument to xUnlockNotify */ void (*xUnlockNotify)(void **, int); /* Unlock notify callback */ - tdsqlite3 *pNextBlocked; /* Next in list of all blocked connections */ + sqlite3 *pNextBlocked; /* Next in list of all blocked connections */ #endif #ifdef SQLITE_USER_AUTHENTICATION - tdsqlite3_userauth auth; /* User authentication information */ + sqlite3_userauth auth; /* User authentication information */ #endif }; @@ -16908,7 +16908,7 @@ struct tdsqlite3 { #define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */ #define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */ #define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */ -#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace tdsqlite3VdbeAddOp() calls */ +#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */ #define SQLITE_VdbeEQP HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */ #define SQLITE_ParserTrace HI(0x2000000) /* PRAGMA parser_trace=ON */ #endif @@ -16925,7 +16925,7 @@ struct tdsqlite3 { /* ** Bits of the sqlite3.dbOptFlags field that are used by the -** tdsqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to +** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to ** selectively disable various optimizations. */ #define SQLITE_QueryFlattener 0x0001 /* Query flattening */ @@ -16974,7 +16974,7 @@ struct tdsqlite3 { /* ** Each SQL function is defined by an instance of the following ** structure. For global built-in functions (ex: substr(), max(), count()) -** a pointer to this structure is held in the tdsqlite3BuiltinFunctions object. +** a pointer to this structure is held in the sqlite3BuiltinFunctions object. ** For per-connection application-defined functions, a pointer to this ** structure is held in the db->aHash hash table. ** @@ -16986,10 +16986,10 @@ struct FuncDef { u32 funcFlags; /* Some combination of SQLITE_FUNC_* */ void *pUserData; /* User data parameter */ FuncDef *pNext; /* Next function with same name */ - void (*xSFunc)(tdsqlite3_context*,int,tdsqlite3_value**); /* func or agg-step */ - void (*xFinalize)(tdsqlite3_context*); /* Agg finalizer */ - void (*xValue)(tdsqlite3_context*); /* Current agg value */ - void (*xInverse)(tdsqlite3_context*,int,tdsqlite3_value**); /* inverse agg-step */ + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**); /* func or agg-step */ + void (*xFinalize)(sqlite3_context*); /* Agg finalizer */ + void (*xValue)(sqlite3_context*); /* Current agg value */ + void (*xInverse)(sqlite3_context*,int,sqlite3_value**); /* inverse agg-step */ const char *zName; /* SQL name of the function. */ union { FuncDef *pHash; /* Next with a different name but the same hash */ @@ -17036,7 +17036,7 @@ struct FuncDestructor { #define SQLITE_FUNC_LIKE 0x0004 /* Candidate for the LIKE optimization */ #define SQLITE_FUNC_CASE 0x0008 /* Case-sensitive LIKE-type function */ #define SQLITE_FUNC_EPHEM 0x0010 /* Ephemeral. Delete with VDBE */ -#define SQLITE_FUNC_NEEDCOLL 0x0020 /* tdsqlite3GetFuncCollSeq() might be called*/ +#define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ #define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ #define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ #define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ @@ -17071,7 +17071,7 @@ struct FuncDestructor { ** Used to create a scalar function definition of a function zName ** implemented by C function xFunc that accepts nArg arguments. The ** value passed as iArg is cast to a (void*) and made available -** as the user-data (tdsqlite3_user_data()) for the function. If +** as the user-data (sqlite3_user_data()) for the function. If ** argument bNC is true, then the SQLITE_FUNC_NEEDCOLL flag is set. ** ** VFUNCTION(zName, nArg, iArg, bNC, xFunc) @@ -17122,7 +17122,7 @@ struct FuncDestructor { ** Used to create a scalar function definition of a function zName ** that accepts nArg arguments and is implemented by a call to C ** function likeFunc. Argument pArg is cast to a (void *) and made -** available as the function user-data (tdsqlite3_user_data()). The +** available as the function user-data (sqlite3_user_data()). The ** FuncDef.flags variable is set to the value passed as the flags ** parameter. */ @@ -17147,7 +17147,7 @@ struct FuncDestructor { 0, 0, xFunc, 0, 0, 0, #zName, {0} } #define PURE_DATE(zName, nArg, iArg, bNC, xFunc) \ {nArg, SQLITE_FUNC_SLOCHNG|SQLITE_UTF8|SQLITE_FUNC_CONSTANT, \ - (void*)&tdsqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } + (void*)&sqlite3Config, 0, xFunc, 0, 0, 0, #zName, {0} } #define FUNCTION2(zName, nArg, iArg, bNC, xFunc, extraFlags) \ {nArg,SQLITE_FUNC_CONSTANT|SQLITE_UTF8|(bNC*SQLITE_FUNC_NEEDCOLL)|extraFlags,\ SQLITE_INT_TO_PTR(iArg), 0, xFunc, 0, 0, 0, #zName, {0} } @@ -17179,7 +17179,7 @@ struct Savepoint { }; /* -** The following are used as the second parameter to tdsqlite3Savepoint(), +** The following are used as the second parameter to sqlite3Savepoint(), ** and as the P1 argument to the OP_Savepoint instruction. */ #define SAVEPOINT_BEGIN 0 @@ -17193,7 +17193,7 @@ struct Savepoint { ** hash table. */ struct Module { - const tdsqlite3_module *pModule; /* Callback pointers */ + const sqlite3_module *pModule; /* Callback pointers */ const char *zName; /* Name passed to create_module() */ int nRefModule; /* Number of pointers to this object */ void *pAux; /* pAux passed to create_module() */ @@ -17287,7 +17287,7 @@ struct CollSeq { #define SQLITE_AFF_INTEGER 0x44 /* 'D' */ #define SQLITE_AFF_REAL 0x45 /* 'E' */ -#define tdsqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) +#define sqlite3IsNumericAffinity(X) ((X)>=SQLITE_AFF_NUMERIC) /* ** The SQLITE_AFF_MASK values masks off the significant bits of an @@ -17315,10 +17315,10 @@ struct CollSeq { ** the database schema. ** ** If the database schema is shared, then there is one instance of this -** structure for each database connection (tdsqlite3*) that uses the shared +** structure for each database connection (sqlite3*) that uses the shared ** schema. This is because each database connection requires its own unique -** instance of the tdsqlite3_vtab* handle used to access the virtual table -** implementation. tdsqlite3_vtab* handles can not be shared between +** instance of the sqlite3_vtab* handle used to access the virtual table +** implementation. sqlite3_vtab* handles can not be shared between ** database connections, even when the rest of the in-memory database ** schema is shared, as the implementation often stores the database ** connection handle passed to it via the xConnect() or xCreate() method @@ -17331,31 +17331,31 @@ struct CollSeq { ** All VTable objects that correspond to a single table in a shared ** database schema are initially stored in a linked-list pointed to by ** the Table.pVTable member variable of the corresponding Table object. -** When an tdsqlite3_prepare() operation is required to access the virtual +** When an sqlite3_prepare() operation is required to access the virtual ** table, it searches the list for the VTable that corresponds to the ** database connection doing the preparing so as to use the correct -** tdsqlite3_vtab* handle in the compiled query. +** sqlite3_vtab* handle in the compiled query. ** ** When an in-memory Table object is deleted (for example when the ** schema is being reloaded for some reason), the VTable objects are not -** deleted and the tdsqlite3_vtab* handles are not xDisconnect()ed +** deleted and the sqlite3_vtab* handles are not xDisconnect()ed ** immediately. Instead, they are moved from the Table.pVTable list to ** another linked list headed by the sqlite3.pDisconnect member of the -** corresponding tdsqlite3 structure. They are then deleted/xDisconnected -** next time a statement is prepared using said tdsqlite3*. This is done +** corresponding sqlite3 structure. They are then deleted/xDisconnected +** next time a statement is prepared using said sqlite3*. This is done ** to avoid deadlock issues involving multiple sqlite3.mutex mutexes. -** Refer to comments above function tdsqlite3VtabUnlockList() for an +** Refer to comments above function sqlite3VtabUnlockList() for an ** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect ** list without holding the corresponding sqlite3.mutex mutex. ** ** The memory for objects of this type is always allocated by -** tdsqlite3DbMalloc(), using the connection handle stored in VTable.db as +** sqlite3DbMalloc(), using the connection handle stored in VTable.db as ** the first argument. */ struct VTable { - tdsqlite3 *db; /* Database connection associated with this table */ + sqlite3 *db; /* Database connection associated with this table */ Module *pMod; /* Pointer to module implementation */ - tdsqlite3_vtab *pVtab; /* Pointer to vtab instance */ + sqlite3_vtab *pVtab; /* Pointer to vtab instance */ int nRef; /* Number of pointers to this structure */ u8 bConstraint; /* True if constraints are supported */ u8 eVtabRisk; /* Riskiness of allowing hacker access */ @@ -17556,7 +17556,7 @@ struct FKey { /* ** An instance of the following structure is passed as the first -** argument to tdsqlite3VdbeKeyCompare and is used to control the +** argument to sqlite3VdbeKeyCompare and is used to control the ** comparison of the two index keys. ** ** Note that aSortOrder[] and aColl[] have nField+1 slots. There @@ -17568,7 +17568,7 @@ struct KeyInfo { u8 enc; /* Text encoding - one of the SQLITE_UTF* values */ u16 nKeyField; /* Number of key columns in the index */ u16 nAllField; /* Total columns, including key plus others */ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ u8 *aSortFlags; /* Sort order for each column. */ CollSeq *aColl[1]; /* Collating sequence for each term of the key */ }; @@ -17732,7 +17732,7 @@ struct IndexSample { }; /* -** Possible values to use within the flags argument to tdsqlite3GetToken(). +** Possible values to use within the flags argument to sqlite3GetToken(). */ #define SQLITE_TOKEN_QUOTED 0x1 /* Token is a quoted identifier. */ #define SQLITE_TOKEN_KEYWORD 0x2 /* Token is a keyword. */ @@ -17955,7 +17955,7 @@ struct Expr { #define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ -#define EP_MemToken 0x010000 /* Need to tdsqlite3DbFree() Expr.zToken */ +#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ #define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ #define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ @@ -18008,8 +18008,8 @@ struct Expr { #define EXPR_TOKENONLYSIZE offsetof(Expr,pLeft) /* Fewer features */ /* -** Flags passed to the tdsqlite3ExprDup() function. See the header comment -** above tdsqlite3ExprDup() for details. +** Flags passed to the sqlite3ExprDup() function. See the header comment +** above sqlite3ExprDup() for details. */ #define EXPRDUP_REDUCE 0x0001 /* Used reduced-size Expr nodes */ @@ -18111,7 +18111,7 @@ struct IdList { ** ** The jointype starts out showing the join type between the current table ** and the next table on the list. The parser builds the list this way. -** But tdsqlite3SrcListShiftJoinType() later shifts the jointypes so that each +** But sqlite3SrcListShiftJoinType() later shifts the jointypes so that each ** jointype expresses the join between the table and the previous table. ** ** In the colUsed field, the high-order bit (bit 63) is set if the table @@ -18165,7 +18165,7 @@ struct SrcList { /* -** Flags appropriate for the wctrlFlags parameter of tdsqlite3WhereBegin() +** Flags appropriate for the wctrlFlags parameter of sqlite3WhereBegin() ** and the WhereInfo.wctrlFlags member. ** ** Value constraints (enforced via assert()): @@ -18182,7 +18182,7 @@ struct SrcList { #define WHERE_GROUPBY 0x0040 /* pOrderBy is really a GROUP BY */ #define WHERE_DISTINCTBY 0x0080 /* pOrderby is really a DISTINCT clause */ #define WHERE_WANT_DISTINCT 0x0100 /* All output needs to be distinct */ -#define WHERE_SORTBYGROUP 0x0200 /* Support tdsqlite3WhereIsSorted() */ +#define WHERE_SORTBYGROUP 0x0200 /* Support sqlite3WhereIsSorted() */ #define WHERE_SEEK_TABLE 0x0400 /* Do not defer seeks on main table */ #define WHERE_ORDERBY_LIMIT 0x0800 /* ORDERBY+LIMIT on the inner loop */ #define WHERE_SEEK_UNIQ_TABLE 0x1000 /* Do not defer seeks if unique */ @@ -18190,7 +18190,7 @@ struct SrcList { #define WHERE_USE_LIMIT 0x4000 /* Use the LIMIT in cost estimates */ /* 0x8000 not currently used */ -/* Allowed return values from tdsqlite3WhereIsDistinct() +/* Allowed return values from sqlite3WhereIsDistinct() */ #define WHERE_DISTINCT_NOOP 0 /* DISTINCT keyword not used */ #define WHERE_DISTINCT_UNIQUE 1 /* No duplicates */ @@ -18346,7 +18346,7 @@ struct Select { #define SF_Aggregate 0x0000008 /* Contains agg functions or a GROUP BY */ #define SF_HasAgg 0x0000010 /* Contains aggregate functions */ #define SF_UsesEphemeral 0x0000020 /* Uses the OpenEphemeral opcode */ -#define SF_Expanded 0x0000040 /* tdsqlite3SelectExpand() called on this */ +#define SF_Expanded 0x0000040 /* sqlite3SelectExpand() called on this */ #define SF_HasTypeInfo 0x0000080 /* FROM subqueries have Table metadata */ #define SF_Compound 0x0000100 /* Part of a compound query */ #define SF_Values 0x0000200 /* Synthesized from VALUES clause */ @@ -18509,8 +18509,8 @@ struct TriggerPrg { # define DbMaskTest(M,I) (((M)[(I)/8]&(1<<((I)&7)))!=0) # define DbMaskZero(M) memset((M),0,sizeof(M)) # define DbMaskSet(M,I) (M)[(I)/8]|=(1<<((I)&7)) -# define DbMaskAllZero(M) tdsqlite3DbMaskAllZero(M) -# define DbMaskNonZero(M) (tdsqlite3DbMaskAllZero(M)==0) +# define DbMaskAllZero(M) sqlite3DbMaskAllZero(M) +# define DbMaskNonZero(M) (sqlite3DbMaskAllZero(M)==0) #else typedef unsigned int yDbMask; # define DbMaskTest(M,I) (((M)&(((yDbMask)1)<<(I)))!=0) @@ -18531,13 +18531,13 @@ struct TriggerPrg { ** each recursion. ** ** The nTableLock and aTableLock variables are only used if the shared-cache -** feature is enabled (if tdsqlite3Tsd()->useSharedData is true). They are +** feature is enabled (if sqlite3Tsd()->useSharedData is true). They are ** used to store the set of table-locks required by the statement being -** compiled. Function tdsqlite3TableLock() is used to add entries to the +** compiled. Function sqlite3TableLock() is used to add entries to the ** list. */ struct Parse { - tdsqlite3 *db; /* The main database structure */ + sqlite3 *db; /* The main database structure */ char *zErrMsg; /* An error message */ Vdbe *pVdbe; /* An engine for executing database bytecode */ int rc; /* Return code from execution */ @@ -18618,7 +18618,7 @@ struct Parse { int addrExplain; /* Address of current OP_Explain opcode */ #endif VList *pVList; /* Mapping between variable names and numbers */ - Vdbe *pReprepare; /* VM being reprepared (tdsqlite3Reprepare()) */ + Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ Index *pNewIndex; /* An index being constructed by CREATE INDEX. @@ -18653,7 +18653,7 @@ struct Parse { #define PARSE_TAIL(X) (((char*)(X))+PARSE_RECURSE_SZ) /* Pointer to tail */ /* -** Return true if currently inside an tdsqlite3_declare_vtab() call. +** Return true if currently inside an sqlite3_declare_vtab() call. */ #ifdef SQLITE_OMIT_VIRTUALTABLE #define IN_DECLARE_VTAB 0 @@ -18719,7 +18719,7 @@ struct AuthContext { * struct Trigger. * * Pointers to instances of struct Trigger are stored in two ways. - * 1. In the "trigHash" hash table (part of the tdsqlite3* that represents the + * 1. In the "trigHash" hash table (part of the sqlite3* that represents the * database). This allows Trigger structures to be retrieved by name. * 2. All triggers associated with a single table form a linked list, using the * pNext member of struct Trigger. A pointer to the first element of the @@ -18787,7 +18787,7 @@ struct Trigger { * pWhere -> The WHERE clause of the UPDATE statement if one is specified. * Otherwise NULL. * pExprList -> A list of the columns to update and the expressions to update - * them to. See tdsqlite3Update() documentation of "pChanges" + * them to. See sqlite3Update() documentation of "pChanges" * argument. * */ @@ -18825,8 +18825,8 @@ struct DbFixer { ** An objected used to accumulate the text of a string where we ** do not necessarily know how big the string will be in the end. */ -struct tdsqlite3_str { - tdsqlite3 *db; /* Optional database for lookaside. Can be NULL */ +struct sqlite3_str { + sqlite3 *db; /* Optional database for lookaside. Can be NULL */ char *zText; /* The string collected so far */ u32 nAlloc; /* Amount of space allocated in zText */ u32 mxAlloc; /* Maximum allowed allocation. 0 for no malloc usage */ @@ -18843,10 +18843,10 @@ struct tdsqlite3_str { /* ** A pointer to this structure is used to communicate information -** from tdsqlite3Init and OP_ParseSchema into the tdsqlite3InitCallback. +** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback. */ typedef struct { - tdsqlite3 *db; /* The database being initialized */ + sqlite3 *db; /* The database being initialized */ char **pzErrMsg; /* Error message stored here */ int iDb; /* 0 for main database. 1 for TEMP, 2.. for ATTACHed */ int rc; /* Result code stored here */ @@ -18877,14 +18877,14 @@ struct Sqlite3Config { int szLookaside; /* Default lookaside buffer size */ int nLookaside; /* Default lookaside buffer count */ int nStmtSpill; /* Stmt-journal spill-to-disk threshold */ - tdsqlite3_mem_methods m; /* Low-level memory allocation interface */ - tdsqlite3_mutex_methods mutex; /* Low-level mutex interface */ - tdsqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ + sqlite3_mem_methods m; /* Low-level memory allocation interface */ + sqlite3_mutex_methods mutex; /* Low-level mutex interface */ + sqlite3_pcache_methods2 pcache2; /* Low-level page-cache interface */ void *pHeap; /* Heap storage space */ int nHeap; /* Size of pHeap[] */ int mnReq, mxReq; /* Min and max heap requests sizes */ - tdsqlite3_int64 szMmap; /* mmap() space per open file */ - tdsqlite3_int64 mxMmap; /* Maximum value for szMmap */ + sqlite3_int64 szMmap; /* mmap() space per open file */ + sqlite3_int64 mxMmap; /* Maximum value for szMmap */ void *pPage; /* Page cache memory */ int szPage; /* Size of each page in pPage[] */ int nPage; /* Number of pages in pPage[] */ @@ -18899,11 +18899,11 @@ struct Sqlite3Config { int isMallocInit; /* True after malloc is initialized */ int isPCacheInit; /* True after malloc is initialized */ int nRefInitMutex; /* Number of users of pInitMutex */ - tdsqlite3_mutex *pInitMutex; /* Mutex used by tdsqlite3_initialize() */ + sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ void (*xLog)(void*,int,const char*); /* Function for logging */ void *pLogArg; /* First argument to xLog() */ #ifdef SQLITE_ENABLE_SQLLOG - void(*xSqllog)(void*,tdsqlite3*,const char*, int); + void(*xSqllog)(void*,sqlite3*,const char*, int); void *pSqllogArg; #endif #ifdef SQLITE_VDBE_COVERAGE @@ -18914,10 +18914,10 @@ struct Sqlite3Config { void *pVdbeBranchArg; /* 1st argument */ #endif #ifdef SQLITE_ENABLE_DESERIALIZE - tdsqlite3_int64 mxMemdbSize; /* Default max memdb size */ + sqlite3_int64 mxMemdbSize; /* Default max memdb size */ #endif #ifndef SQLITE_UNTESTABLE - int (*xTestCallback)(int); /* Invoked by tdsqlite3FaultSim() */ + int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */ #endif int bLocaltimeFault; /* True to fail localtime() calls */ int iOnceResetThreshold; /* When to reset OP_Once counters */ @@ -18938,10 +18938,10 @@ struct Sqlite3Config { ** CORRUPT_DB is true during normal operation. CORRUPT_DB does not indicate ** that the database is definitely corrupt, only that it might be corrupt. ** For most test cases, CORRUPT_DB is set to false using a special -** tdsqlite3_test_control(). This enables assert() statements to prove +** sqlite3_test_control(). This enables assert() statements to prove ** things that are always true for well-formed databases. */ -#define CORRUPT_DB (tdsqlite3Config.neverCorrupt==0) +#define CORRUPT_DB (sqlite3Config.neverCorrupt==0) /* ** Context pointer passed down through the tree-walk. @@ -18973,16 +18973,16 @@ struct Walker { }; /* Forward declarations */ -SQLITE_PRIVATE int tdsqlite3WalkExpr(Walker*, Expr*); -SQLITE_PRIVATE int tdsqlite3WalkExprList(Walker*, ExprList*); -SQLITE_PRIVATE int tdsqlite3WalkSelect(Walker*, Select*); -SQLITE_PRIVATE int tdsqlite3WalkSelectExpr(Walker*, Select*); -SQLITE_PRIVATE int tdsqlite3WalkSelectFrom(Walker*, Select*); -SQLITE_PRIVATE int tdsqlite3ExprWalkNoop(Walker*, Expr*); -SQLITE_PRIVATE int tdsqlite3SelectWalkNoop(Walker*, Select*); -SQLITE_PRIVATE int tdsqlite3SelectWalkFail(Walker*, Select*); +SQLITE_PRIVATE int sqlite3WalkExpr(Walker*, Expr*); +SQLITE_PRIVATE int sqlite3WalkExprList(Walker*, ExprList*); +SQLITE_PRIVATE int sqlite3WalkSelect(Walker*, Select*); +SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker*, Select*); +SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker*, Select*); +SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker*, Expr*); +SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker*, Select*); +SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker*, Select*); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE void tdsqlite3SelectWalkAssert2(Walker*, Select*); +SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker*, Select*); #endif /* @@ -19011,7 +19011,7 @@ struct With { #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of -** data structures on tdsqlite3DebugPrintf() using a tree-like view. +** data structures on sqlite3DebugPrintf() using a tree-like view. */ struct TreeView { int iLevel; /* Which level of the tree we are on */ @@ -19075,27 +19075,27 @@ struct Window { }; #ifndef SQLITE_OMIT_WINDOWFUNC -SQLITE_PRIVATE void tdsqlite3WindowDelete(tdsqlite3*, Window*); -SQLITE_PRIVATE void tdsqlite3WindowUnlinkFromSelect(Window*); -SQLITE_PRIVATE void tdsqlite3WindowListDelete(tdsqlite3 *db, Window *p); -SQLITE_PRIVATE Window *tdsqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); -SQLITE_PRIVATE void tdsqlite3WindowAttach(Parse*, Expr*, Window*); -SQLITE_PRIVATE void tdsqlite3WindowLink(Select *pSel, Window *pWin); -SQLITE_PRIVATE int tdsqlite3WindowCompare(Parse*, Window*, Window*, int); -SQLITE_PRIVATE void tdsqlite3WindowCodeInit(Parse*, Select*); -SQLITE_PRIVATE void tdsqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); -SQLITE_PRIVATE int tdsqlite3WindowRewrite(Parse*, Select*); -SQLITE_PRIVATE int tdsqlite3ExpandSubquery(Parse*, struct SrcList_item*); -SQLITE_PRIVATE void tdsqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); -SQLITE_PRIVATE Window *tdsqlite3WindowDup(tdsqlite3 *db, Expr *pOwner, Window *p); -SQLITE_PRIVATE Window *tdsqlite3WindowListDup(tdsqlite3 *db, Window *p); -SQLITE_PRIVATE void tdsqlite3WindowFunctions(void); -SQLITE_PRIVATE void tdsqlite3WindowChain(Parse*, Window*, Window*); -SQLITE_PRIVATE Window *tdsqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*); -#else -# define tdsqlite3WindowDelete(a,b) -# define tdsqlite3WindowFunctions() -# define tdsqlite3WindowAttach(a,b,c) +SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3*, Window*); +SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window*); +SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p); +SQLITE_PRIVATE Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); +SQLITE_PRIVATE void sqlite3WindowAttach(Parse*, Expr*, Window*); +SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin); +SQLITE_PRIVATE int sqlite3WindowCompare(Parse*, Window*, Window*, int); +SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse*, Select*); +SQLITE_PRIVATE void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); +SQLITE_PRIVATE int sqlite3WindowRewrite(Parse*, Select*); +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, struct SrcList_item*); +SQLITE_PRIVATE void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*); +SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p); +SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p); +SQLITE_PRIVATE void sqlite3WindowFunctions(void); +SQLITE_PRIVATE void sqlite3WindowChain(Parse*, Window*, Window*); +SQLITE_PRIVATE Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*); +#else +# define sqlite3WindowDelete(a,b) +# define sqlite3WindowFunctions() +# define sqlite3WindowAttach(a,b,c) #endif /* @@ -19112,27 +19112,27 @@ SQLITE_PRIVATE Window *tdsqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprL ** The SQLITE_*_BKPT macros are substitutes for the error codes with ** the same name but without the _BKPT suffix. These macros invoke ** routines that report the line-number on which the error originated -** using tdsqlite3_log(). The routines also provide a convenient place +** using sqlite3_log(). The routines also provide a convenient place ** to set a debugger breakpoint. */ -SQLITE_PRIVATE int tdsqlite3ReportError(int iErr, int lineno, const char *zType); -SQLITE_PRIVATE int tdsqlite3CorruptError(int); -SQLITE_PRIVATE int tdsqlite3MisuseError(int); -SQLITE_PRIVATE int tdsqlite3CantopenError(int); -#define SQLITE_CORRUPT_BKPT tdsqlite3CorruptError(__LINE__) -#define SQLITE_MISUSE_BKPT tdsqlite3MisuseError(__LINE__) -#define SQLITE_CANTOPEN_BKPT tdsqlite3CantopenError(__LINE__) +SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType); +SQLITE_PRIVATE int sqlite3CorruptError(int); +SQLITE_PRIVATE int sqlite3MisuseError(int); +SQLITE_PRIVATE int sqlite3CantopenError(int); +#define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__) +#define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__) +#define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__) #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3NomemError(int); -SQLITE_PRIVATE int tdsqlite3IoerrnomemError(int); -SQLITE_PRIVATE int tdsqlite3CorruptPgnoError(int,Pgno); -# define SQLITE_NOMEM_BKPT tdsqlite3NomemError(__LINE__) -# define SQLITE_IOERR_NOMEM_BKPT tdsqlite3IoerrnomemError(__LINE__) -# define SQLITE_CORRUPT_PGNO(P) tdsqlite3CorruptPgnoError(__LINE__,(P)) +SQLITE_PRIVATE int sqlite3NomemError(int); +SQLITE_PRIVATE int sqlite3IoerrnomemError(int); +SQLITE_PRIVATE int sqlite3CorruptPgnoError(int,Pgno); +# define SQLITE_NOMEM_BKPT sqlite3NomemError(__LINE__) +# define SQLITE_IOERR_NOMEM_BKPT sqlite3IoerrnomemError(__LINE__) +# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptPgnoError(__LINE__,(P)) #else # define SQLITE_NOMEM_BKPT SQLITE_NOMEM # define SQLITE_IOERR_NOMEM_BKPT SQLITE_IOERR_NOMEM -# define SQLITE_CORRUPT_PGNO(P) tdsqlite3CorruptError(__LINE__) +# define SQLITE_CORRUPT_PGNO(P) sqlite3CorruptError(__LINE__) #endif /* @@ -19167,59 +19167,59 @@ SQLITE_PRIVATE int tdsqlite3CorruptPgnoError(int,Pgno); ** sqlite versions only work for ASCII characters, regardless of locale. */ #ifdef SQLITE_ASCII -# define tdsqlite3Toupper(x) ((x)&~(tdsqlite3CtypeMap[(unsigned char)(x)]&0x20)) -# define tdsqlite3Isspace(x) (tdsqlite3CtypeMap[(unsigned char)(x)]&0x01) -# define tdsqlite3Isalnum(x) (tdsqlite3CtypeMap[(unsigned char)(x)]&0x06) -# define tdsqlite3Isalpha(x) (tdsqlite3CtypeMap[(unsigned char)(x)]&0x02) -# define tdsqlite3Isdigit(x) (tdsqlite3CtypeMap[(unsigned char)(x)]&0x04) -# define tdsqlite3Isxdigit(x) (tdsqlite3CtypeMap[(unsigned char)(x)]&0x08) -# define tdsqlite3Tolower(x) (tdsqlite3UpperToLower[(unsigned char)(x)]) -# define tdsqlite3Isquote(x) (tdsqlite3CtypeMap[(unsigned char)(x)]&0x80) -#else -# define tdsqlite3Toupper(x) toupper((unsigned char)(x)) -# define tdsqlite3Isspace(x) isspace((unsigned char)(x)) -# define tdsqlite3Isalnum(x) isalnum((unsigned char)(x)) -# define tdsqlite3Isalpha(x) isalpha((unsigned char)(x)) -# define tdsqlite3Isdigit(x) isdigit((unsigned char)(x)) -# define tdsqlite3Isxdigit(x) isxdigit((unsigned char)(x)) -# define tdsqlite3Tolower(x) tolower((unsigned char)(x)) -# define tdsqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') -#endif -SQLITE_PRIVATE int tdsqlite3IsIdChar(u8); +# define sqlite3Toupper(x) ((x)&~(sqlite3CtypeMap[(unsigned char)(x)]&0x20)) +# define sqlite3Isspace(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x01) +# define sqlite3Isalnum(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x06) +# define sqlite3Isalpha(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x02) +# define sqlite3Isdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x04) +# define sqlite3Isxdigit(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x08) +# define sqlite3Tolower(x) (sqlite3UpperToLower[(unsigned char)(x)]) +# define sqlite3Isquote(x) (sqlite3CtypeMap[(unsigned char)(x)]&0x80) +#else +# define sqlite3Toupper(x) toupper((unsigned char)(x)) +# define sqlite3Isspace(x) isspace((unsigned char)(x)) +# define sqlite3Isalnum(x) isalnum((unsigned char)(x)) +# define sqlite3Isalpha(x) isalpha((unsigned char)(x)) +# define sqlite3Isdigit(x) isdigit((unsigned char)(x)) +# define sqlite3Isxdigit(x) isxdigit((unsigned char)(x)) +# define sqlite3Tolower(x) tolower((unsigned char)(x)) +# define sqlite3Isquote(x) ((x)=='"'||(x)=='\''||(x)=='['||(x)=='`') +#endif +SQLITE_PRIVATE int sqlite3IsIdChar(u8); /* ** Internal function prototypes */ -SQLITE_PRIVATE int tdsqlite3StrICmp(const char*,const char*); -SQLITE_PRIVATE int tdsqlite3Strlen30(const char*); -#define tdsqlite3Strlen30NN(C) (strlen(C)&0x3fffffff) -SQLITE_PRIVATE char *tdsqlite3ColumnType(Column*,char*); -#define tdsqlite3StrNICmp tdsqlite3_strnicmp - -SQLITE_PRIVATE int tdsqlite3MallocInit(void); -SQLITE_PRIVATE void tdsqlite3MallocEnd(void); -SQLITE_PRIVATE void *tdsqlite3Malloc(u64); -SQLITE_PRIVATE void *tdsqlite3MallocZero(u64); -SQLITE_PRIVATE void *tdsqlite3DbMallocZero(tdsqlite3*, u64); -SQLITE_PRIVATE void *tdsqlite3DbMallocRaw(tdsqlite3*, u64); -SQLITE_PRIVATE void *tdsqlite3DbMallocRawNN(tdsqlite3*, u64); -SQLITE_PRIVATE char *tdsqlite3DbStrDup(tdsqlite3*,const char*); -SQLITE_PRIVATE char *tdsqlite3DbStrNDup(tdsqlite3*,const char*, u64); -SQLITE_PRIVATE char *tdsqlite3DbSpanDup(tdsqlite3*,const char*,const char*); -SQLITE_PRIVATE void *tdsqlite3Realloc(void*, u64); -SQLITE_PRIVATE void *tdsqlite3DbReallocOrFree(tdsqlite3 *, void *, u64); -SQLITE_PRIVATE void *tdsqlite3DbRealloc(tdsqlite3 *, void *, u64); -SQLITE_PRIVATE void tdsqlite3DbFree(tdsqlite3*, void*); -SQLITE_PRIVATE void tdsqlite3DbFreeNN(tdsqlite3*, void*); -SQLITE_PRIVATE int tdsqlite3MallocSize(void*); -SQLITE_PRIVATE int tdsqlite3DbMallocSize(tdsqlite3*, void*); -SQLITE_PRIVATE void *tdsqlite3PageMalloc(int); -SQLITE_PRIVATE void tdsqlite3PageFree(void*); -SQLITE_PRIVATE void tdsqlite3MemSetDefault(void); +SQLITE_PRIVATE int sqlite3StrICmp(const char*,const char*); +SQLITE_PRIVATE int sqlite3Strlen30(const char*); +#define sqlite3Strlen30NN(C) (strlen(C)&0x3fffffff) +SQLITE_PRIVATE char *sqlite3ColumnType(Column*,char*); +#define sqlite3StrNICmp sqlite3_strnicmp + +SQLITE_PRIVATE int sqlite3MallocInit(void); +SQLITE_PRIVATE void sqlite3MallocEnd(void); +SQLITE_PRIVATE void *sqlite3Malloc(u64); +SQLITE_PRIVATE void *sqlite3MallocZero(u64); +SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, u64); +SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, u64); +SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3*, u64); +SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*); +SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, u64); +SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3*,const char*,const char*); +SQLITE_PRIVATE void *sqlite3Realloc(void*, u64); +SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64); +SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, u64); +SQLITE_PRIVATE void sqlite3DbFree(sqlite3*, void*); +SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3*, void*); +SQLITE_PRIVATE int sqlite3MallocSize(void*); +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3*, void*); +SQLITE_PRIVATE void *sqlite3PageMalloc(int); +SQLITE_PRIVATE void sqlite3PageFree(void*); +SQLITE_PRIVATE void sqlite3MemSetDefault(void); #ifndef SQLITE_UNTESTABLE -SQLITE_PRIVATE void tdsqlite3BenignMallocHooks(void (*)(void), void (*)(void)); +SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void)); #endif -SQLITE_PRIVATE int tdsqlite3HeapNearlyFull(void); +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void); /* ** On systems with ample stack space and that support alloca(), make @@ -19227,67 +19227,67 @@ SQLITE_PRIVATE int tdsqlite3HeapNearlyFull(void); ** obtain space from malloc(). ** ** The alloca() routine never returns NULL. This will cause code paths -** that deal with tdsqlite3StackAlloc() failures to be unreachable. +** that deal with sqlite3StackAlloc() failures to be unreachable. */ #ifdef SQLITE_USE_ALLOCA -# define tdsqlite3StackAllocRaw(D,N) alloca(N) -# define tdsqlite3StackAllocZero(D,N) memset(alloca(N), 0, N) -# define tdsqlite3StackFree(D,P) +# define sqlite3StackAllocRaw(D,N) alloca(N) +# define sqlite3StackAllocZero(D,N) memset(alloca(N), 0, N) +# define sqlite3StackFree(D,P) #else -# define tdsqlite3StackAllocRaw(D,N) tdsqlite3DbMallocRaw(D,N) -# define tdsqlite3StackAllocZero(D,N) tdsqlite3DbMallocZero(D,N) -# define tdsqlite3StackFree(D,P) tdsqlite3DbFree(D,P) +# define sqlite3StackAllocRaw(D,N) sqlite3DbMallocRaw(D,N) +# define sqlite3StackAllocZero(D,N) sqlite3DbMallocZero(D,N) +# define sqlite3StackFree(D,P) sqlite3DbFree(D,P) #endif /* Do not allow both MEMSYS5 and MEMSYS3 to be defined together. If they ** are, disable MEMSYS3 */ #ifdef SQLITE_ENABLE_MEMSYS5 -SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetMemsys5(void); +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void); #undef SQLITE_ENABLE_MEMSYS3 #endif #ifdef SQLITE_ENABLE_MEMSYS3 -SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetMemsys3(void); +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void); #endif #ifndef SQLITE_MUTEX_OMIT -SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void); -SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3NoopMutex(void); -SQLITE_PRIVATE tdsqlite3_mutex *tdsqlite3MutexAlloc(int); -SQLITE_PRIVATE int tdsqlite3MutexInit(void); -SQLITE_PRIVATE int tdsqlite3MutexEnd(void); +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void); +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void); +SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int); +SQLITE_PRIVATE int sqlite3MutexInit(void); +SQLITE_PRIVATE int sqlite3MutexEnd(void); #endif #if !defined(SQLITE_MUTEX_OMIT) && !defined(SQLITE_MUTEX_NOOP) -SQLITE_PRIVATE void tdsqlite3MemoryBarrier(void); +SQLITE_PRIVATE void sqlite3MemoryBarrier(void); #else -# define tdsqlite3MemoryBarrier() +# define sqlite3MemoryBarrier() #endif -SQLITE_PRIVATE tdsqlite3_int64 tdsqlite3StatusValue(int); -SQLITE_PRIVATE void tdsqlite3StatusUp(int, int); -SQLITE_PRIVATE void tdsqlite3StatusDown(int, int); -SQLITE_PRIVATE void tdsqlite3StatusHighwater(int, int); -SQLITE_PRIVATE int tdsqlite3LookasideUsed(tdsqlite3*,int*); +SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int); +SQLITE_PRIVATE void sqlite3StatusUp(int, int); +SQLITE_PRIVATE void sqlite3StatusDown(int, int); +SQLITE_PRIVATE void sqlite3StatusHighwater(int, int); +SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3*,int*); -/* Access to mutexes used by tdsqlite3_status() */ -SQLITE_PRIVATE tdsqlite3_mutex *tdsqlite3Pcache1Mutex(void); -SQLITE_PRIVATE tdsqlite3_mutex *tdsqlite3MallocMutex(void); +/* Access to mutexes used by sqlite3_status() */ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void); +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void); #if defined(SQLITE_ENABLE_MULTITHREADED_CHECKS) && !defined(SQLITE_MUTEX_OMIT) -SQLITE_PRIVATE void tdsqlite3MutexWarnOnContention(tdsqlite3_mutex*); +SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex*); #else -# define tdsqlite3MutexWarnOnContention(x) +# define sqlite3MutexWarnOnContention(x) #endif #ifndef SQLITE_OMIT_FLOATING_POINT # define EXP754 (((u64)0x7ff)<<52) # define MAN754 ((((u64)1)<<52)-1) # define IsNaN(X) (((X)&EXP754)==EXP754 && ((X)&MAN754)!=0) -SQLITE_PRIVATE int tdsqlite3IsNaN(double); +SQLITE_PRIVATE int sqlite3IsNaN(double); #else # define IsNaN(X) 0 -# define tdsqlite3IsNaN(X) 0 +# define sqlite3IsNaN(X) 0 #endif /* @@ -19297,418 +19297,418 @@ SQLITE_PRIVATE int tdsqlite3IsNaN(double); struct PrintfArguments { int nArg; /* Total number of arguments */ int nUsed; /* Number of arguments used so far */ - tdsqlite3_value **apArg; /* The argument values */ + sqlite3_value **apArg; /* The argument values */ }; -SQLITE_PRIVATE char *tdsqlite3MPrintf(tdsqlite3*,const char*, ...); -SQLITE_PRIVATE char *tdsqlite3VMPrintf(tdsqlite3*,const char*, va_list); +SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...); +SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) -SQLITE_PRIVATE void tdsqlite3DebugPrintf(const char*, ...); +SQLITE_PRIVATE void sqlite3DebugPrintf(const char*, ...); #endif #if defined(SQLITE_TEST) -SQLITE_PRIVATE void *tdsqlite3TestTextToPtr(const char*); +SQLITE_PRIVATE void *sqlite3TestTextToPtr(const char*); #endif #if defined(SQLITE_DEBUG) -SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView*, const Expr*, u8); -SQLITE_PRIVATE void tdsqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); -SQLITE_PRIVATE void tdsqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); -SQLITE_PRIVATE void tdsqlite3TreeViewSrcList(TreeView*, const SrcList*); -SQLITE_PRIVATE void tdsqlite3TreeViewSelect(TreeView*, const Select*, u8); -SQLITE_PRIVATE void tdsqlite3TreeViewWith(TreeView*, const With*, u8); +SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView*, const Expr*, u8); +SQLITE_PRIVATE void sqlite3TreeViewBareExprList(TreeView*, const ExprList*, const char*); +SQLITE_PRIVATE void sqlite3TreeViewExprList(TreeView*, const ExprList*, u8, const char*); +SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView*, const SrcList*); +SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView*, const Select*, u8); +SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView*, const With*, u8); #ifndef SQLITE_OMIT_WINDOWFUNC -SQLITE_PRIVATE void tdsqlite3TreeViewWindow(TreeView*, const Window*, u8); -SQLITE_PRIVATE void tdsqlite3TreeViewWinFunc(TreeView*, const Window*, u8); -#endif -#endif - - -SQLITE_PRIVATE void tdsqlite3SetString(char **, tdsqlite3*, const char*); -SQLITE_PRIVATE void tdsqlite3ErrorMsg(Parse*, const char*, ...); -SQLITE_PRIVATE int tdsqlite3ErrorToParser(tdsqlite3*,int); -SQLITE_PRIVATE void tdsqlite3Dequote(char*); -SQLITE_PRIVATE void tdsqlite3DequoteExpr(Expr*); -SQLITE_PRIVATE void tdsqlite3TokenInit(Token*,char*); -SQLITE_PRIVATE int tdsqlite3KeywordCode(const unsigned char*, int); -SQLITE_PRIVATE int tdsqlite3RunParser(Parse*, const char*, char **); -SQLITE_PRIVATE void tdsqlite3FinishCoding(Parse*); -SQLITE_PRIVATE int tdsqlite3GetTempReg(Parse*); -SQLITE_PRIVATE void tdsqlite3ReleaseTempReg(Parse*,int); -SQLITE_PRIVATE int tdsqlite3GetTempRange(Parse*,int); -SQLITE_PRIVATE void tdsqlite3ReleaseTempRange(Parse*,int,int); -SQLITE_PRIVATE void tdsqlite3ClearTempRegCache(Parse*); +SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView*, const Window*, u8); +SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8); +#endif +#endif + + +SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*); +SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...); +SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3*,int); +SQLITE_PRIVATE void sqlite3Dequote(char*); +SQLITE_PRIVATE void sqlite3DequoteExpr(Expr*); +SQLITE_PRIVATE void sqlite3TokenInit(Token*,char*); +SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char*, int); +SQLITE_PRIVATE int sqlite3RunParser(Parse*, const char*, char **); +SQLITE_PRIVATE void sqlite3FinishCoding(Parse*); +SQLITE_PRIVATE int sqlite3GetTempReg(Parse*); +SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse*,int); +SQLITE_PRIVATE int sqlite3GetTempRange(Parse*,int); +SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse*,int,int); +SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse*); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3NoTempsInRange(Parse*,int,int); -#endif -SQLITE_PRIVATE Expr *tdsqlite3ExprAlloc(tdsqlite3*,int,const Token*,int); -SQLITE_PRIVATE Expr *tdsqlite3Expr(tdsqlite3*,int,const char*); -SQLITE_PRIVATE void tdsqlite3ExprAttachSubtrees(tdsqlite3*,Expr*,Expr*,Expr*); -SQLITE_PRIVATE Expr *tdsqlite3PExpr(Parse*, int, Expr*, Expr*); -SQLITE_PRIVATE void tdsqlite3PExprAddSelect(Parse*, Expr*, Select*); -SQLITE_PRIVATE Expr *tdsqlite3ExprAnd(Parse*,Expr*, Expr*); -SQLITE_PRIVATE Expr *tdsqlite3ExprSimplifiedAndOr(Expr*); -SQLITE_PRIVATE Expr *tdsqlite3ExprFunction(Parse*,ExprList*, Token*, int); -SQLITE_PRIVATE void tdsqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*); -SQLITE_PRIVATE void tdsqlite3ExprAssignVarNumber(Parse*, Expr*, u32); -SQLITE_PRIVATE void tdsqlite3ExprDelete(tdsqlite3*, Expr*); -SQLITE_PRIVATE void tdsqlite3ExprUnmapAndDelete(Parse*, Expr*); -SQLITE_PRIVATE ExprList *tdsqlite3ExprListAppend(Parse*,ExprList*,Expr*); -SQLITE_PRIVATE ExprList *tdsqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); -SQLITE_PRIVATE void tdsqlite3ExprListSetSortOrder(ExprList*,int,int); -SQLITE_PRIVATE void tdsqlite3ExprListSetName(Parse*,ExprList*,Token*,int); -SQLITE_PRIVATE void tdsqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); -SQLITE_PRIVATE void tdsqlite3ExprListDelete(tdsqlite3*, ExprList*); -SQLITE_PRIVATE u32 tdsqlite3ExprListFlags(const ExprList*); -SQLITE_PRIVATE int tdsqlite3IndexHasDuplicateRootPage(Index*); -SQLITE_PRIVATE int tdsqlite3Init(tdsqlite3*, char**); -SQLITE_PRIVATE int tdsqlite3InitCallback(void*, int, char**, char**); -SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3*, int, char**, u32); -SQLITE_PRIVATE void tdsqlite3Pragma(Parse*,Token*,Token*,Token*,int); +SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse*,int,int); +#endif +SQLITE_PRIVATE Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int); +SQLITE_PRIVATE Expr *sqlite3Expr(sqlite3*,int,const char*); +SQLITE_PRIVATE void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*); +SQLITE_PRIVATE Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*); +SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse*, Expr*, Select*); +SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int); +SQLITE_PRIVATE void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*); +SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); +SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3*, Expr*); +SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse*, Expr*); +SQLITE_PRIVATE ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); +SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); +SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList*,int,int); +SQLITE_PRIVATE void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); +SQLITE_PRIVATE void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); +SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3*, ExprList*); +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList*); +SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index*); +SQLITE_PRIVATE int sqlite3Init(sqlite3*, char**); +SQLITE_PRIVATE int sqlite3InitCallback(void*, int, char**, char**); +SQLITE_PRIVATE int sqlite3InitOne(sqlite3*, int, char**, u32); +SQLITE_PRIVATE void sqlite3Pragma(Parse*,Token*,Token*,Token*,int); #ifndef SQLITE_OMIT_VIRTUALTABLE -SQLITE_PRIVATE Module *tdsqlite3PragmaVtabRegister(tdsqlite3*,const char *zName); -#endif -SQLITE_PRIVATE void tdsqlite3ResetAllSchemasOfConnection(tdsqlite3*); -SQLITE_PRIVATE void tdsqlite3ResetOneSchema(tdsqlite3*,int); -SQLITE_PRIVATE void tdsqlite3CollapseDatabaseArray(tdsqlite3*); -SQLITE_PRIVATE void tdsqlite3CommitInternalChanges(tdsqlite3*); -SQLITE_PRIVATE void tdsqlite3DeleteColumnNames(tdsqlite3*,Table*); -SQLITE_PRIVATE int tdsqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); -SQLITE_PRIVATE void tdsqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); -SQLITE_PRIVATE Table *tdsqlite3ResultSetOfSelect(Parse*,Select*,char); -SQLITE_PRIVATE void tdsqlite3OpenMasterTable(Parse *, int); -SQLITE_PRIVATE Index *tdsqlite3PrimaryKeyIndex(Table*); -SQLITE_PRIVATE i16 tdsqlite3TableColumnToIndex(Index*, i16); +SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3*,const char *zName); +#endif +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3*); +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3*,int); +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3*); +SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3*); +SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3*,Table*); +SQLITE_PRIVATE int sqlite3ColumnsFromExprList(Parse*,ExprList*,i16*,Column**); +SQLITE_PRIVATE void sqlite3SelectAddColumnTypeAndCollation(Parse*,Table*,Select*,char); +SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse*,Select*,char); +SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *, int); +SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table*); +SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index*, i16); #ifdef SQLITE_OMIT_GENERATED_COLUMNS -# define tdsqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ -# define tdsqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ +# define sqlite3TableColumnToStorage(T,X) (X) /* No-op pass-through */ +# define sqlite3StorageColumnToTable(T,X) (X) /* No-op pass-through */ #else -SQLITE_PRIVATE i16 tdsqlite3TableColumnToStorage(Table*, i16); -SQLITE_PRIVATE i16 tdsqlite3StorageColumnToTable(Table*, i16); +SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table*, i16); +SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table*, i16); #endif -SQLITE_PRIVATE void tdsqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); +SQLITE_PRIVATE void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int); #if SQLITE_ENABLE_HIDDEN_COLUMNS -SQLITE_PRIVATE void tdsqlite3ColumnPropertiesFromName(Table*, Column*); -#else -# define tdsqlite3ColumnPropertiesFromName(T,C) /* no-op */ -#endif -SQLITE_PRIVATE void tdsqlite3AddColumn(Parse*,Token*,Token*); -SQLITE_PRIVATE void tdsqlite3AddNotNull(Parse*, int); -SQLITE_PRIVATE void tdsqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); -SQLITE_PRIVATE void tdsqlite3AddCheckConstraint(Parse*, Expr*); -SQLITE_PRIVATE void tdsqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); -SQLITE_PRIVATE void tdsqlite3AddCollateType(Parse*, Token*); -SQLITE_PRIVATE void tdsqlite3AddGenerated(Parse*,Expr*,Token*); -SQLITE_PRIVATE void tdsqlite3EndTable(Parse*,Token*,Token*,u8,Select*); -SQLITE_PRIVATE int tdsqlite3ParseUri(const char*,const char*,unsigned int*, - tdsqlite3_vfs**,char**,char **); +SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table*, Column*); +#else +# define sqlite3ColumnPropertiesFromName(T,C) /* no-op */ +#endif +SQLITE_PRIVATE void sqlite3AddColumn(Parse*,Token*,Token*); +SQLITE_PRIVATE void sqlite3AddNotNull(Parse*, int); +SQLITE_PRIVATE void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int); +SQLITE_PRIVATE void sqlite3AddCheckConstraint(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*); +SQLITE_PRIVATE void sqlite3AddCollateType(Parse*, Token*); +SQLITE_PRIVATE void sqlite3AddGenerated(Parse*,Expr*,Token*); +SQLITE_PRIVATE void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*); +SQLITE_PRIVATE int sqlite3ParseUri(const char*,const char*,unsigned int*, + sqlite3_vfs**,char**,char **); #ifdef SQLITE_HAS_CODEC -SQLITE_PRIVATE int tdsqlite3CodecQueryParameters(tdsqlite3*,const char*,const char*); +SQLITE_PRIVATE int sqlite3CodecQueryParameters(sqlite3*,const char*,const char*); #else -# define tdsqlite3CodecQueryParameters(A,B,C) 0 +# define sqlite3CodecQueryParameters(A,B,C) 0 #endif -SQLITE_PRIVATE Btree *tdsqlite3DbNameToBtree(tdsqlite3*,const char*); +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3*,const char*); #ifdef SQLITE_UNTESTABLE -# define tdsqlite3FaultSim(X) SQLITE_OK +# define sqlite3FaultSim(X) SQLITE_OK #else -SQLITE_PRIVATE int tdsqlite3FaultSim(int); +SQLITE_PRIVATE int sqlite3FaultSim(int); #endif -SQLITE_PRIVATE Bitvec *tdsqlite3BitvecCreate(u32); -SQLITE_PRIVATE int tdsqlite3BitvecTest(Bitvec*, u32); -SQLITE_PRIVATE int tdsqlite3BitvecTestNotNull(Bitvec*, u32); -SQLITE_PRIVATE int tdsqlite3BitvecSet(Bitvec*, u32); -SQLITE_PRIVATE void tdsqlite3BitvecClear(Bitvec*, u32, void*); -SQLITE_PRIVATE void tdsqlite3BitvecDestroy(Bitvec*); -SQLITE_PRIVATE u32 tdsqlite3BitvecSize(Bitvec*); +SQLITE_PRIVATE Bitvec *sqlite3BitvecCreate(u32); +SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec*, u32); +SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec*, u32); +SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec*, u32); +SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec*, u32, void*); +SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec*); +SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec*); #ifndef SQLITE_UNTESTABLE -SQLITE_PRIVATE int tdsqlite3BitvecBuiltinTest(int,int*); +SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int,int*); #endif -SQLITE_PRIVATE RowSet *tdsqlite3RowSetInit(tdsqlite3*); -SQLITE_PRIVATE void tdsqlite3RowSetDelete(void*); -SQLITE_PRIVATE void tdsqlite3RowSetClear(void*); -SQLITE_PRIVATE void tdsqlite3RowSetInsert(RowSet*, i64); -SQLITE_PRIVATE int tdsqlite3RowSetTest(RowSet*, int iBatch, i64); -SQLITE_PRIVATE int tdsqlite3RowSetNext(RowSet*, i64*); +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3*); +SQLITE_PRIVATE void sqlite3RowSetDelete(void*); +SQLITE_PRIVATE void sqlite3RowSetClear(void*); +SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet*, i64); +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet*, int iBatch, i64); +SQLITE_PRIVATE int sqlite3RowSetNext(RowSet*, i64*); -SQLITE_PRIVATE void tdsqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int); +SQLITE_PRIVATE void sqlite3CreateView(Parse*,Token*,Token*,Token*,ExprList*,Select*,int,int); #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) -SQLITE_PRIVATE int tdsqlite3ViewGetColumnNames(Parse*,Table*); +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); #else -# define tdsqlite3ViewGetColumnNames(A,B) 0 +# define sqlite3ViewGetColumnNames(A,B) 0 #endif #if SQLITE_MAX_ATTACHED>30 -SQLITE_PRIVATE int tdsqlite3DbMaskAllZero(yDbMask); +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask); #endif -SQLITE_PRIVATE void tdsqlite3DropTable(Parse*, SrcList*, int, int); -SQLITE_PRIVATE void tdsqlite3CodeDropTable(Parse*, Table*, int, int); -SQLITE_PRIVATE void tdsqlite3DeleteTable(tdsqlite3*, Table*); -SQLITE_PRIVATE void tdsqlite3FreeIndex(tdsqlite3*, Index*); +SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); +SQLITE_PRIVATE void sqlite3CodeDropTable(Parse*, Table*, int, int); +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3*, Table*); +SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3*, Index*); #ifndef SQLITE_OMIT_AUTOINCREMENT -SQLITE_PRIVATE void tdsqlite3AutoincrementBegin(Parse *pParse); -SQLITE_PRIVATE void tdsqlite3AutoincrementEnd(Parse *pParse); +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); #else -# define tdsqlite3AutoincrementBegin(X) -# define tdsqlite3AutoincrementEnd(X) +# define sqlite3AutoincrementBegin(X) +# define sqlite3AutoincrementEnd(X) #endif -SQLITE_PRIVATE void tdsqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); +SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int, Upsert*); #ifndef SQLITE_OMIT_GENERATED_COLUMNS -SQLITE_PRIVATE void tdsqlite3ComputeGeneratedColumns(Parse*, int, Table*); -#endif -SQLITE_PRIVATE void *tdsqlite3ArrayAllocate(tdsqlite3*,void*,int,int*,int*); -SQLITE_PRIVATE IdList *tdsqlite3IdListAppend(Parse*, IdList*, Token*); -SQLITE_PRIVATE int tdsqlite3IdListIndex(IdList*,const char*); -SQLITE_PRIVATE SrcList *tdsqlite3SrcListEnlarge(Parse*, SrcList*, int, int); -SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); -SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, +SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns(Parse*, int, Table*); +#endif +SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*); +SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse*, IdList*, Token*); +SQLITE_PRIVATE int sqlite3IdListIndex(IdList*,const char*); +SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge(Parse*, SrcList*, int, int); +SQLITE_PRIVATE SrcList *sqlite3SrcListAppend(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm(Parse*, SrcList*, Token*, Token*, Token*, Select*, Expr*, IdList*); -SQLITE_PRIVATE void tdsqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); -SQLITE_PRIVATE void tdsqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); -SQLITE_PRIVATE int tdsqlite3IndexedByLookup(Parse *, struct SrcList_item *); -SQLITE_PRIVATE void tdsqlite3SrcListShiftJoinType(SrcList*); -SQLITE_PRIVATE void tdsqlite3SrcListAssignCursors(Parse*, SrcList*); -SQLITE_PRIVATE void tdsqlite3IdListDelete(tdsqlite3*, IdList*); -SQLITE_PRIVATE void tdsqlite3SrcListDelete(tdsqlite3*, SrcList*); -SQLITE_PRIVATE Index *tdsqlite3AllocateIndexObject(tdsqlite3*,i16,int,char**); -SQLITE_PRIVATE void tdsqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, +SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *, SrcList *, Token *); +SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse*, SrcList*, ExprList*); +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *, struct SrcList_item *); +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*); +SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); +SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); +SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); +SQLITE_PRIVATE Index *sqlite3AllocateIndexObject(sqlite3*,i16,int,char**); +SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Expr*, int, int, u8); -SQLITE_PRIVATE void tdsqlite3DropIndex(Parse*, SrcList*, int); -SQLITE_PRIVATE int tdsqlite3Select(Parse*, Select*, SelectDest*); -SQLITE_PRIVATE Select *tdsqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, +SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); +SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); +SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*, Expr*,ExprList*,u32,Expr*); -SQLITE_PRIVATE void tdsqlite3SelectDelete(tdsqlite3*, Select*); -SQLITE_PRIVATE void tdsqlite3SelectReset(Parse*, Select*); -SQLITE_PRIVATE Table *tdsqlite3SrcListLookup(Parse*, SrcList*); -SQLITE_PRIVATE int tdsqlite3IsReadOnly(Parse*, Table*, int); -SQLITE_PRIVATE void tdsqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); +SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3*, Select*); +SQLITE_PRIVATE void sqlite3SelectReset(Parse*, Select*); +SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse*, SrcList*); +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse*, Table*, int); +SQLITE_PRIVATE void sqlite3OpenTable(Parse*, int iCur, int iDb, Table*, int); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) && !defined(SQLITE_OMIT_SUBQUERY) -SQLITE_PRIVATE Expr *tdsqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); +SQLITE_PRIVATE Expr *sqlite3LimitWhere(Parse*,SrcList*,Expr*,ExprList*,Expr*,char*); #endif -SQLITE_PRIVATE void tdsqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); -SQLITE_PRIVATE void tdsqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, +SQLITE_PRIVATE void sqlite3DeleteFrom(Parse*, SrcList*, Expr*, ExprList*, Expr*); +SQLITE_PRIVATE void sqlite3Update(Parse*, SrcList*, ExprList*,Expr*,int,ExprList*,Expr*, Upsert*); -SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); -SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo*); -SQLITE_PRIVATE LogEst tdsqlite3WhereOutputRowCount(WhereInfo*); -SQLITE_PRIVATE int tdsqlite3WhereIsDistinct(WhereInfo*); -SQLITE_PRIVATE int tdsqlite3WhereIsOrdered(WhereInfo*); -SQLITE_PRIVATE int tdsqlite3WhereOrderByLimitOptLabel(WhereInfo*); -SQLITE_PRIVATE int tdsqlite3WhereIsSorted(WhereInfo*); -SQLITE_PRIVATE int tdsqlite3WhereContinueLabel(WhereInfo*); -SQLITE_PRIVATE int tdsqlite3WhereBreakLabel(WhereInfo*); -SQLITE_PRIVATE int tdsqlite3WhereOkOnePass(WhereInfo*, int*); +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*,SrcList*,Expr*,ExprList*,ExprList*,u16,int); +SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*); +SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo*); +SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo*, int*); #define ONEPASS_OFF 0 /* Use of ONEPASS not allowed */ #define ONEPASS_SINGLE 1 /* ONEPASS valid for a single row update */ #define ONEPASS_MULTI 2 /* ONEPASS is valid for multiple rows */ -SQLITE_PRIVATE int tdsqlite3WhereUsesDeferredSeek(WhereInfo*); -SQLITE_PRIVATE void tdsqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); -SQLITE_PRIVATE int tdsqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); -SQLITE_PRIVATE void tdsqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); -SQLITE_PRIVATE void tdsqlite3ExprCodeMove(Parse*, int, int, int); -SQLITE_PRIVATE void tdsqlite3ExprCode(Parse*, Expr*, int); +SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo*); +SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn(Parse*, Index*, int, int, int); +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, u8); +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable(Vdbe*, Table*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int); +SQLITE_PRIVATE void sqlite3ExprCode(Parse*, Expr*, int); #ifndef SQLITE_OMIT_GENERATED_COLUMNS -SQLITE_PRIVATE void tdsqlite3ExprCodeGeneratedColumn(Parse*, Column*, int); -#endif -SQLITE_PRIVATE void tdsqlite3ExprCodeCopy(Parse*, Expr*, int); -SQLITE_PRIVATE void tdsqlite3ExprCodeFactorable(Parse*, Expr*, int); -SQLITE_PRIVATE int tdsqlite3ExprCodeAtInit(Parse*, Expr*, int); -SQLITE_PRIVATE int tdsqlite3ExprCodeTemp(Parse*, Expr*, int*); -SQLITE_PRIVATE int tdsqlite3ExprCodeTarget(Parse*, Expr*, int); -SQLITE_PRIVATE int tdsqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); +SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn(Parse*, Column*, int); +#endif +SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, Expr*, int); +SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCodeAtInit(Parse*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse*, Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCodeExprList(Parse*, ExprList*, int, int, u8); #define SQLITE_ECEL_DUP 0x01 /* Deep, not shallow copies */ #define SQLITE_ECEL_FACTOR 0x02 /* Factor out constant terms */ #define SQLITE_ECEL_REF 0x04 /* Use ExprList.u.x.iOrderByCol */ #define SQLITE_ECEL_OMITREF 0x08 /* Omit if ExprList.u.x.iOrderByCol */ -SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse*, Expr*, int, int); -SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse*, Expr*, int, int); -SQLITE_PRIVATE void tdsqlite3ExprIfFalseDup(Parse*, Expr*, int, int); -SQLITE_PRIVATE Table *tdsqlite3FindTable(tdsqlite3*,const char*, const char*); +SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse*, Expr*, int, int); +SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse*, Expr*, int, int); +SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse*, Expr*, int, int); +SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3*,const char*, const char*); #define LOCATE_VIEW 0x01 #define LOCATE_NOERR 0x02 -SQLITE_PRIVATE Table *tdsqlite3LocateTable(Parse*,u32 flags,const char*, const char*); -SQLITE_PRIVATE Table *tdsqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); -SQLITE_PRIVATE Index *tdsqlite3FindIndex(tdsqlite3*,const char*, const char*); -SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteTable(tdsqlite3*,int,const char*); -SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteIndex(tdsqlite3*,int,const char*); -SQLITE_PRIVATE void tdsqlite3Vacuum(Parse*,Token*,Expr*); -SQLITE_PRIVATE int tdsqlite3RunVacuum(char**, tdsqlite3*, int, tdsqlite3_value*); -SQLITE_PRIVATE char *tdsqlite3NameFromToken(tdsqlite3*, Token*); -SQLITE_PRIVATE int tdsqlite3ExprCompare(Parse*,Expr*, Expr*, int); -SQLITE_PRIVATE int tdsqlite3ExprCompareSkip(Expr*, Expr*, int); -SQLITE_PRIVATE int tdsqlite3ExprListCompare(ExprList*, ExprList*, int); -SQLITE_PRIVATE int tdsqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int); -SQLITE_PRIVATE int tdsqlite3ExprImpliesNonNullRow(Expr*,int); -SQLITE_PRIVATE void tdsqlite3ExprAnalyzeAggregates(NameContext*, Expr*); -SQLITE_PRIVATE void tdsqlite3ExprAnalyzeAggList(NameContext*,ExprList*); -SQLITE_PRIVATE int tdsqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); -SQLITE_PRIVATE int tdsqlite3FunctionUsesThisSrc(Expr*, SrcList*); -SQLITE_PRIVATE Vdbe *tdsqlite3GetVdbe(Parse*); +SQLITE_PRIVATE Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*); +SQLITE_PRIVATE Table *sqlite3LocateTableItem(Parse*,u32 flags,struct SrcList_item *); +SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3*,const char*, const char*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*); +SQLITE_PRIVATE void sqlite3Vacuum(Parse*,Token*,Expr*); +SQLITE_PRIVATE int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*); +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3*, Token*); +SQLITE_PRIVATE int sqlite3ExprCompare(Parse*,Expr*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprListCompare(ExprList*, ExprList*, int); +SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int); +SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr*,int); +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); +SQLITE_PRIVATE int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx); +SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr*, SrcList*); +SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse*); #ifndef SQLITE_UNTESTABLE -SQLITE_PRIVATE void tdsqlite3PrngSaveState(void); -SQLITE_PRIVATE void tdsqlite3PrngRestoreState(void); -#endif -SQLITE_PRIVATE void tdsqlite3RollbackAll(tdsqlite3*,int); -SQLITE_PRIVATE void tdsqlite3CodeVerifySchema(Parse*, int); -SQLITE_PRIVATE void tdsqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); -SQLITE_PRIVATE void tdsqlite3BeginTransaction(Parse*, int); -SQLITE_PRIVATE void tdsqlite3EndTransaction(Parse*,int); -SQLITE_PRIVATE void tdsqlite3Savepoint(Parse*, int, Token*); -SQLITE_PRIVATE void tdsqlite3CloseSavepoints(tdsqlite3 *); -SQLITE_PRIVATE void tdsqlite3LeaveMutexAndCloseZombie(tdsqlite3*); -SQLITE_PRIVATE u32 tdsqlite3IsTrueOrFalse(const char*); -SQLITE_PRIVATE int tdsqlite3ExprIdToTrueFalse(Expr*); -SQLITE_PRIVATE int tdsqlite3ExprTruthValue(const Expr*); -SQLITE_PRIVATE int tdsqlite3ExprIsConstant(Expr*); -SQLITE_PRIVATE int tdsqlite3ExprIsConstantNotJoin(Expr*); -SQLITE_PRIVATE int tdsqlite3ExprIsConstantOrFunction(Expr*, u8); -SQLITE_PRIVATE int tdsqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); -SQLITE_PRIVATE int tdsqlite3ExprIsTableConstant(Expr*,int); +SQLITE_PRIVATE void sqlite3PrngSaveState(void); +SQLITE_PRIVATE void sqlite3PrngRestoreState(void); +#endif +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3*,int); +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse*, int); +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb); +SQLITE_PRIVATE void sqlite3BeginTransaction(Parse*, int); +SQLITE_PRIVATE void sqlite3EndTransaction(Parse*,int); +SQLITE_PRIVATE void sqlite3Savepoint(Parse*, int, Token*); +SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *); +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3*); +SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char*); +SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr*); +SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr*); +SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr*); +SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); +SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*, u8); +SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*); +SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr*,int); #ifdef SQLITE_ENABLE_CURSOR_HINTS -SQLITE_PRIVATE int tdsqlite3ExprContainsSubquery(Expr*); +SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr*); #endif -SQLITE_PRIVATE int tdsqlite3ExprIsInteger(Expr*, int*); -SQLITE_PRIVATE int tdsqlite3ExprCanBeNull(const Expr*); -SQLITE_PRIVATE int tdsqlite3ExprNeedsNoAffinityChange(const Expr*, char); -SQLITE_PRIVATE int tdsqlite3IsRowid(const char*); -SQLITE_PRIVATE void tdsqlite3GenerateRowDelete( +SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); +SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr*); +SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); +SQLITE_PRIVATE int sqlite3IsRowid(const char*); +SQLITE_PRIVATE void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); -SQLITE_PRIVATE void tdsqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); -SQLITE_PRIVATE int tdsqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); -SQLITE_PRIVATE void tdsqlite3ResolvePartIdxLabel(Parse*,int); -SQLITE_PRIVATE int tdsqlite3ExprReferencesUpdatedColumn(Expr*,int*,int); -SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, +SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); +SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int); +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse*,int); +SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn(Expr*,int*,int); +SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int, u8,u8,int,int*,int*,Upsert*); #ifdef SQLITE_ENABLE_NULL_TRIM -SQLITE_PRIVATE void tdsqlite3SetMakeRecordP5(Vdbe*,Table*); -#else -# define tdsqlite3SetMakeRecordP5(A,B) -#endif -SQLITE_PRIVATE void tdsqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); -SQLITE_PRIVATE int tdsqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*); -SQLITE_PRIVATE void tdsqlite3BeginWriteOperation(Parse*, int, int); -SQLITE_PRIVATE void tdsqlite3MultiWrite(Parse*); -SQLITE_PRIVATE void tdsqlite3MayAbort(Parse*); -SQLITE_PRIVATE void tdsqlite3HaltConstraint(Parse*, int, int, char*, i8, u8); -SQLITE_PRIVATE void tdsqlite3UniqueConstraint(Parse*, int, Index*); -SQLITE_PRIVATE void tdsqlite3RowidConstraint(Parse*, int, Table*); -SQLITE_PRIVATE Expr *tdsqlite3ExprDup(tdsqlite3*,Expr*,int); -SQLITE_PRIVATE ExprList *tdsqlite3ExprListDup(tdsqlite3*,ExprList*,int); -SQLITE_PRIVATE SrcList *tdsqlite3SrcListDup(tdsqlite3*,SrcList*,int); -SQLITE_PRIVATE IdList *tdsqlite3IdListDup(tdsqlite3*,IdList*); -SQLITE_PRIVATE Select *tdsqlite3SelectDup(tdsqlite3*,Select*,int); -SQLITE_PRIVATE FuncDef *tdsqlite3FunctionSearch(int,const char*); -SQLITE_PRIVATE void tdsqlite3InsertBuiltinFuncs(FuncDef*,int); -SQLITE_PRIVATE FuncDef *tdsqlite3FindFunction(tdsqlite3*,const char*,int,u8,u8); -SQLITE_PRIVATE void tdsqlite3RegisterBuiltinFunctions(void); -SQLITE_PRIVATE void tdsqlite3RegisterDateTimeFunctions(void); -SQLITE_PRIVATE void tdsqlite3RegisterPerConnectionBuiltinFunctions(tdsqlite3*); -SQLITE_PRIVATE int tdsqlite3SafetyCheckOk(tdsqlite3*); -SQLITE_PRIVATE int tdsqlite3SafetyCheckSickOrOk(tdsqlite3*); -SQLITE_PRIVATE void tdsqlite3ChangeCookie(Parse*, int); +SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe*,Table*); +#else +# define sqlite3SetMakeRecordP5(A,B) +#endif +SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int); +SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*); +SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); +SQLITE_PRIVATE void sqlite3MultiWrite(Parse*); +SQLITE_PRIVATE void sqlite3MayAbort(Parse*); +SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8); +SQLITE_PRIVATE void sqlite3UniqueConstraint(Parse*, int, Index*); +SQLITE_PRIVATE void sqlite3RowidConstraint(Parse*, int, Table*); +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3*,IdList*); +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3*,Select*,int); +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch(int,const char*); +SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs(FuncDef*,int); +SQLITE_PRIVATE FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8); +SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); +SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); +SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); +SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); +SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); +SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) -SQLITE_PRIVATE void tdsqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); +SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif #ifndef SQLITE_OMIT_TRIGGER -SQLITE_PRIVATE void tdsqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, +SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, Expr*,int, int); -SQLITE_PRIVATE void tdsqlite3FinishTrigger(Parse*, TriggerStep*, Token*); -SQLITE_PRIVATE void tdsqlite3DropTrigger(Parse*, SrcList*, int); -SQLITE_PRIVATE void tdsqlite3DropTriggerPtr(Parse*, Trigger*); -SQLITE_PRIVATE Trigger *tdsqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask); -SQLITE_PRIVATE Trigger *tdsqlite3TriggerList(Parse *, Table *); -SQLITE_PRIVATE void tdsqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *, +SQLITE_PRIVATE void sqlite3FinishTrigger(Parse*, TriggerStep*, Token*); +SQLITE_PRIVATE void sqlite3DropTrigger(Parse*, SrcList*, int); +SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse*, Trigger*); +SQLITE_PRIVATE Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask); +SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *, Table *); +SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *, int, int, int); -SQLITE_PRIVATE void tdsqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); -SQLITE_PRIVATE void tdsqlite3DeleteTriggerStep(tdsqlite3*, TriggerStep*); -SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerSelectStep(tdsqlite3*,Select*, +SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*, const char*,const char*); -SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerInsertStep(Parse*,Token*, IdList*, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(Parse*,Token*, IdList*, Select*,u8,Upsert*, const char*,const char*); -SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(Parse*,Token*,ExprList*, Expr*, u8, const char*,const char*); -SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerDeleteStep(Parse*,Token*, Expr*, +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(Parse*,Token*, Expr*, const char*,const char*); -SQLITE_PRIVATE void tdsqlite3DeleteTrigger(tdsqlite3*, Trigger*); -SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteTrigger(tdsqlite3*,int,const char*); -SQLITE_PRIVATE u32 tdsqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); -# define tdsqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p)) -# define tdsqlite3IsToplevel(p) ((p)->pToplevel==0) -#else -# define tdsqlite3TriggersExist(B,C,D,E,F) 0 -# define tdsqlite3DeleteTrigger(A,B) -# define tdsqlite3DropTriggerPtr(A,B) -# define tdsqlite3UnlinkAndDeleteTrigger(A,B,C) -# define tdsqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) -# define tdsqlite3CodeRowTriggerDirect(A,B,C,D,E,F) -# define tdsqlite3TriggerList(X, Y) 0 -# define tdsqlite3ParseToplevel(p) p -# define tdsqlite3IsToplevel(p) 1 -# define tdsqlite3TriggerColmask(A,B,C,D,E,F,G) 0 -#endif - -SQLITE_PRIVATE int tdsqlite3JoinType(Parse*, Token*, Token*, Token*); -SQLITE_PRIVATE void tdsqlite3SetJoinExpr(Expr*,int); -SQLITE_PRIVATE void tdsqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); -SQLITE_PRIVATE void tdsqlite3DeferForeignKey(Parse*, int); +SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); +SQLITE_PRIVATE u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int); +# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p)) +# define sqlite3IsToplevel(p) ((p)->pToplevel==0) +#else +# define sqlite3TriggersExist(B,C,D,E,F) 0 +# define sqlite3DeleteTrigger(A,B) +# define sqlite3DropTriggerPtr(A,B) +# define sqlite3UnlinkAndDeleteTrigger(A,B,C) +# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) +# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F) +# define sqlite3TriggerList(X, Y) 0 +# define sqlite3ParseToplevel(p) p +# define sqlite3IsToplevel(p) 1 +# define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0 +#endif + +SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); +SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr*,int); +SQLITE_PRIVATE void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int); +SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse*, int); #ifndef SQLITE_OMIT_AUTHORIZATION -SQLITE_PRIVATE void tdsqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); -SQLITE_PRIVATE int tdsqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); -SQLITE_PRIVATE void tdsqlite3AuthContextPush(Parse*, AuthContext*, const char*); -SQLITE_PRIVATE void tdsqlite3AuthContextPop(AuthContext*); -SQLITE_PRIVATE int tdsqlite3AuthReadCol(Parse*, const char *, const char *, int); -#else -# define tdsqlite3AuthRead(a,b,c,d) -# define tdsqlite3AuthCheck(a,b,c,d,e) SQLITE_OK -# define tdsqlite3AuthContextPush(a,b,c) -# define tdsqlite3AuthContextPop(a) ((void)(a)) -#endif -SQLITE_PRIVATE void tdsqlite3Attach(Parse*, Expr*, Expr*, Expr*); -SQLITE_PRIVATE void tdsqlite3Detach(Parse*, Expr*); -SQLITE_PRIVATE void tdsqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); -SQLITE_PRIVATE int tdsqlite3FixSrcList(DbFixer*, SrcList*); -SQLITE_PRIVATE int tdsqlite3FixSelect(DbFixer*, Select*); -SQLITE_PRIVATE int tdsqlite3FixExpr(DbFixer*, Expr*); -SQLITE_PRIVATE int tdsqlite3FixExprList(DbFixer*, ExprList*); -SQLITE_PRIVATE int tdsqlite3FixTriggerStep(DbFixer*, TriggerStep*); -SQLITE_PRIVATE int tdsqlite3RealSameAsInt(double,tdsqlite3_int64); -SQLITE_PRIVATE int tdsqlite3AtoF(const char *z, double*, int, u8); -SQLITE_PRIVATE int tdsqlite3GetInt32(const char *, int*); -SQLITE_PRIVATE int tdsqlite3Atoi(const char*); +SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); +SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); +SQLITE_PRIVATE void sqlite3AuthContextPush(Parse*, AuthContext*, const char*); +SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext*); +SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int); +#else +# define sqlite3AuthRead(a,b,c,d) +# define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK +# define sqlite3AuthContextPush(a,b,c) +# define sqlite3AuthContextPop(a) ((void)(a)) +#endif +SQLITE_PRIVATE void sqlite3Attach(Parse*, Expr*, Expr*, Expr*); +SQLITE_PRIVATE void sqlite3Detach(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3FixInit(DbFixer*, Parse*, int, const char*, const Token*); +SQLITE_PRIVATE int sqlite3FixSrcList(DbFixer*, SrcList*); +SQLITE_PRIVATE int sqlite3FixSelect(DbFixer*, Select*); +SQLITE_PRIVATE int sqlite3FixExpr(DbFixer*, Expr*); +SQLITE_PRIVATE int sqlite3FixExprList(DbFixer*, ExprList*); +SQLITE_PRIVATE int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); +SQLITE_PRIVATE int sqlite3RealSameAsInt(double,sqlite3_int64); +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double*, int, u8); +SQLITE_PRIVATE int sqlite3GetInt32(const char *, int*); +SQLITE_PRIVATE int sqlite3Atoi(const char*); #ifndef SQLITE_OMIT_UTF16 -SQLITE_PRIVATE int tdsqlite3Utf16ByteLen(const void *pData, int nChar); +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *pData, int nChar); #endif -SQLITE_PRIVATE int tdsqlite3Utf8CharLen(const char *pData, int nByte); -SQLITE_PRIVATE u32 tdsqlite3Utf8Read(const u8**); -SQLITE_PRIVATE LogEst tdsqlite3LogEst(u64); -SQLITE_PRIVATE LogEst tdsqlite3LogEstAdd(LogEst,LogEst); +SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *pData, int nByte); +SQLITE_PRIVATE u32 sqlite3Utf8Read(const u8**); +SQLITE_PRIVATE LogEst sqlite3LogEst(u64); +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst,LogEst); #ifndef SQLITE_OMIT_VIRTUALTABLE -SQLITE_PRIVATE LogEst tdsqlite3LogEstFromDouble(double); +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double); #endif #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || \ defined(SQLITE_ENABLE_STAT4) || \ defined(SQLITE_EXPLAIN_ESTIMATED_ROWS) -SQLITE_PRIVATE u64 tdsqlite3LogEstToInt(LogEst); +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst); #endif -SQLITE_PRIVATE VList *tdsqlite3VListAdd(tdsqlite3*,VList*,const char*,int,int); -SQLITE_PRIVATE const char *tdsqlite3VListNumToName(VList*,int); -SQLITE_PRIVATE int tdsqlite3VListNameToNum(VList*,const char*,int); +SQLITE_PRIVATE VList *sqlite3VListAdd(sqlite3*,VList*,const char*,int,int); +SQLITE_PRIVATE const char *sqlite3VListNumToName(VList*,int); +SQLITE_PRIVATE int sqlite3VListNameToNum(VList*,const char*,int); /* ** Routines to read and write variable-length integers. These used to ** be defined locally, but now we use the varint routines in the util.c ** file. */ -SQLITE_PRIVATE int tdsqlite3PutVarint(unsigned char*, u64); -SQLITE_PRIVATE u8 tdsqlite3GetVarint(const unsigned char *, u64 *); -SQLITE_PRIVATE u8 tdsqlite3GetVarint32(const unsigned char *, u32 *); -SQLITE_PRIVATE int tdsqlite3VarintLen(u64 v); +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char*, u64); +SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *, u64 *); +SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *, u32 *); +SQLITE_PRIVATE int sqlite3VarintLen(u64 v); /* ** The common case is for a varint to be a single byte. They following @@ -19716,301 +19716,301 @@ SQLITE_PRIVATE int tdsqlite3VarintLen(u64 v); ** the procedure for larger varints. */ #define getVarint32(A,B) \ - (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:tdsqlite3GetVarint32((A),(u32 *)&(B))) + (u8)((*(A)<(u8)0x80)?((B)=(u32)*(A)),1:sqlite3GetVarint32((A),(u32 *)&(B))) #define putVarint32(A,B) \ (u8)(((u32)(B)<(u32)0x80)?(*(A)=(unsigned char)(B)),1:\ - tdsqlite3PutVarint((A),(B))) -#define getVarint tdsqlite3GetVarint -#define putVarint tdsqlite3PutVarint - - -SQLITE_PRIVATE const char *tdsqlite3IndexAffinityStr(tdsqlite3*, Index*); -SQLITE_PRIVATE void tdsqlite3TableAffinity(Vdbe*, Table*, int); -SQLITE_PRIVATE char tdsqlite3CompareAffinity(Expr *pExpr, char aff2); -SQLITE_PRIVATE int tdsqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); -SQLITE_PRIVATE char tdsqlite3TableColumnAffinity(Table*,int); -SQLITE_PRIVATE char tdsqlite3ExprAffinity(Expr *pExpr); -SQLITE_PRIVATE int tdsqlite3Atoi64(const char*, i64*, int, u8); -SQLITE_PRIVATE int tdsqlite3DecOrHexToI64(const char*, i64*); -SQLITE_PRIVATE void tdsqlite3ErrorWithMsg(tdsqlite3*, int, const char*,...); -SQLITE_PRIVATE void tdsqlite3Error(tdsqlite3*,int); -SQLITE_PRIVATE void tdsqlite3SystemError(tdsqlite3*,int); -SQLITE_PRIVATE void *tdsqlite3HexToBlob(tdsqlite3*, const char *z, int n); -SQLITE_PRIVATE u8 tdsqlite3HexToInt(int h); -SQLITE_PRIVATE int tdsqlite3TwoPartName(Parse *, Token *, Token *, Token **); + sqlite3PutVarint((A),(B))) +#define getVarint sqlite3GetVarint +#define putVarint sqlite3PutVarint + + +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3*, Index*); +SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe*, Table*, int); +SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); +SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); +SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table*,int); +SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); +SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); +SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); +SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); +SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); +SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); +SQLITE_PRIVATE u8 sqlite3HexToInt(int h); +SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); #if defined(SQLITE_NEED_ERR_NAME) -SQLITE_PRIVATE const char *tdsqlite3ErrName(int); +SQLITE_PRIVATE const char *sqlite3ErrName(int); #endif #ifdef SQLITE_ENABLE_DESERIALIZE -SQLITE_PRIVATE int tdsqlite3MemdbInit(void); -#endif - -SQLITE_PRIVATE const char *tdsqlite3ErrStr(int); -SQLITE_PRIVATE int tdsqlite3ReadSchema(Parse *pParse); -SQLITE_PRIVATE CollSeq *tdsqlite3FindCollSeq(tdsqlite3*,u8 enc, const char*,int); -SQLITE_PRIVATE int tdsqlite3IsBinary(const CollSeq*); -SQLITE_PRIVATE CollSeq *tdsqlite3LocateCollSeq(Parse *pParse, const char*zName); -SQLITE_PRIVATE CollSeq *tdsqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); -SQLITE_PRIVATE CollSeq *tdsqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr); -SQLITE_PRIVATE int tdsqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*); -SQLITE_PRIVATE Expr *tdsqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); -SQLITE_PRIVATE Expr *tdsqlite3ExprAddCollateString(Parse*,Expr*,const char*); -SQLITE_PRIVATE Expr *tdsqlite3ExprSkipCollate(Expr*); -SQLITE_PRIVATE Expr *tdsqlite3ExprSkipCollateAndLikely(Expr*); -SQLITE_PRIVATE int tdsqlite3CheckCollSeq(Parse *, CollSeq *); -SQLITE_PRIVATE int tdsqlite3WritableSchema(tdsqlite3*); -SQLITE_PRIVATE int tdsqlite3CheckObjectName(Parse*, const char*,const char*,const char*); -SQLITE_PRIVATE void tdsqlite3VdbeSetChanges(tdsqlite3 *, int); -SQLITE_PRIVATE int tdsqlite3AddInt64(i64*,i64); -SQLITE_PRIVATE int tdsqlite3SubInt64(i64*,i64); -SQLITE_PRIVATE int tdsqlite3MulInt64(i64*,i64); -SQLITE_PRIVATE int tdsqlite3AbsInt32(int); +SQLITE_PRIVATE int sqlite3MemdbInit(void); +#endif + +SQLITE_PRIVATE const char *sqlite3ErrStr(int); +SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); +SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); +SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq*); +SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); +SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); +SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr); +SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr*); +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr*); +SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *, CollSeq *); +SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3*); +SQLITE_PRIVATE int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*); +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *, int); +SQLITE_PRIVATE int sqlite3AddInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3SubInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3MulInt64(i64*,i64); +SQLITE_PRIVATE int sqlite3AbsInt32(int); #ifdef SQLITE_ENABLE_8_3_NAMES -SQLITE_PRIVATE void tdsqlite3FileSuffix3(const char*, char*); +SQLITE_PRIVATE void sqlite3FileSuffix3(const char*, char*); #else -# define tdsqlite3FileSuffix3(X,Y) +# define sqlite3FileSuffix3(X,Y) #endif -SQLITE_PRIVATE u8 tdsqlite3GetBoolean(const char *z,u8); +SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z,u8); -SQLITE_PRIVATE const void *tdsqlite3ValueText(tdsqlite3_value*, u8); -SQLITE_PRIVATE int tdsqlite3ValueBytes(tdsqlite3_value*, u8); -SQLITE_PRIVATE void tdsqlite3ValueSetStr(tdsqlite3_value*, int, const void *,u8, +SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value*, u8); +SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value*, u8); +SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); -SQLITE_PRIVATE void tdsqlite3ValueSetNull(tdsqlite3_value*); -SQLITE_PRIVATE void tdsqlite3ValueFree(tdsqlite3_value*); +SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value*); +SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); #ifndef SQLITE_UNTESTABLE -SQLITE_PRIVATE void tdsqlite3ResultIntReal(tdsqlite3_context*); +SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context*); #endif -SQLITE_PRIVATE tdsqlite3_value *tdsqlite3ValueNew(tdsqlite3 *); +SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); #ifndef SQLITE_OMIT_UTF16 -SQLITE_PRIVATE char *tdsqlite3Utf16to8(tdsqlite3 *, const void*, int, u8); +SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); #endif -SQLITE_PRIVATE int tdsqlite3ValueFromExpr(tdsqlite3 *, Expr *, u8, u8, tdsqlite3_value **); -SQLITE_PRIVATE void tdsqlite3ValueApplyAffinity(tdsqlite3_value *, u8, u8); +SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); +SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); #ifndef SQLITE_AMALGAMATION -SQLITE_PRIVATE const unsigned char tdsqlite3OpcodeProperty[]; -SQLITE_PRIVATE const char tdsqlite3StrBINARY[]; -SQLITE_PRIVATE const unsigned char tdsqlite3UpperToLower[]; -SQLITE_PRIVATE const unsigned char tdsqlite3CtypeMap[]; -SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config tdsqlite3Config; -SQLITE_PRIVATE FuncDefHash tdsqlite3BuiltinFunctions; +SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; +SQLITE_PRIVATE const char sqlite3StrBINARY[]; +SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; +SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[]; +SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config; +SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; #ifndef SQLITE_OMIT_WSD -SQLITE_PRIVATE int tdsqlite3PendingByte; +SQLITE_PRIVATE int sqlite3PendingByte; #endif #endif #ifdef VDBE_PROFILE -SQLITE_PRIVATE tdsqlite3_uint64 tdsqlite3NProfileCnt; -#endif -SQLITE_PRIVATE void tdsqlite3RootPageMoved(tdsqlite3*, int, int, int); -SQLITE_PRIVATE void tdsqlite3Reindex(Parse*, Token*, Token*); -SQLITE_PRIVATE void tdsqlite3AlterFunctions(void); -SQLITE_PRIVATE void tdsqlite3AlterRenameTable(Parse*, SrcList*, Token*); -SQLITE_PRIVATE void tdsqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); -SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *, int *); -SQLITE_PRIVATE void tdsqlite3NestedParse(Parse*, const char*, ...); -SQLITE_PRIVATE void tdsqlite3ExpirePreparedStatements(tdsqlite3*, int); -SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN(Parse*, Expr*, int); -SQLITE_PRIVATE int tdsqlite3CodeSubselect(Parse*, Expr*); -SQLITE_PRIVATE void tdsqlite3SelectPrep(Parse*, Select*, NameContext*); -SQLITE_PRIVATE void tdsqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); -SQLITE_PRIVATE int tdsqlite3MatchEName( +SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt; +#endif +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, int, int); +SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); +SQLITE_PRIVATE void sqlite3AlterFunctions(void); +SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); +SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); +SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *); +SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); +SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int); +SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); +SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); +SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item*, const char*, const char*, const char* ); -SQLITE_PRIVATE int tdsqlite3ResolveExprNames(NameContext*, Expr*); -SQLITE_PRIVATE int tdsqlite3ResolveExprListNames(NameContext*, ExprList*); -SQLITE_PRIVATE void tdsqlite3ResolveSelectNames(Parse*, Select*, NameContext*); -SQLITE_PRIVATE int tdsqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); -SQLITE_PRIVATE int tdsqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); -SQLITE_PRIVATE void tdsqlite3ColumnDefault(Vdbe *, Table *, int, int); -SQLITE_PRIVATE void tdsqlite3AlterFinishAddColumn(Parse *, Token *); -SQLITE_PRIVATE void tdsqlite3AlterBeginAddColumn(Parse *, SrcList *); -SQLITE_PRIVATE void *tdsqlite3RenameTokenMap(Parse*, void*, Token*); -SQLITE_PRIVATE void tdsqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); -SQLITE_PRIVATE void tdsqlite3RenameExprUnmap(Parse*, Expr*); -SQLITE_PRIVATE void tdsqlite3RenameExprlistUnmap(Parse*, ExprList*); -SQLITE_PRIVATE CollSeq *tdsqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); -SQLITE_PRIVATE char tdsqlite3AffinityType(const char*, Column*); -SQLITE_PRIVATE void tdsqlite3Analyze(Parse*, Token*, Token*); -SQLITE_PRIVATE int tdsqlite3InvokeBusyHandler(BusyHandler*, tdsqlite3_file*); -SQLITE_PRIVATE int tdsqlite3FindDb(tdsqlite3*, Token*); -SQLITE_PRIVATE int tdsqlite3FindDbName(tdsqlite3 *, const char *); -SQLITE_PRIVATE int tdsqlite3AnalysisLoad(tdsqlite3*,int iDB); -SQLITE_PRIVATE void tdsqlite3DeleteIndexSamples(tdsqlite3*,Index*); -SQLITE_PRIVATE void tdsqlite3DefaultRowEst(Index*); -SQLITE_PRIVATE void tdsqlite3RegisterLikeFunctions(tdsqlite3*, int); -SQLITE_PRIVATE int tdsqlite3IsLikeFunction(tdsqlite3*,Expr*,int*,char*); -SQLITE_PRIVATE void tdsqlite3SchemaClear(void *); -SQLITE_PRIVATE Schema *tdsqlite3SchemaGet(tdsqlite3 *, Btree *); -SQLITE_PRIVATE int tdsqlite3SchemaToIndex(tdsqlite3 *db, Schema *); -SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoAlloc(tdsqlite3*,int,int); -SQLITE_PRIVATE void tdsqlite3KeyInfoUnref(KeyInfo*); -SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoRef(KeyInfo*); -SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoOfIndex(Parse*, Index*); -SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); -SQLITE_PRIVATE int tdsqlite3HasExplicitNulls(Parse*, ExprList*); +SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*); +SQLITE_PRIVATE int sqlite3ResolveExprListNames(NameContext*, ExprList*); +SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); +SQLITE_PRIVATE int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*); +SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); +SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); +SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); +SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse*, void*, Token*); +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom); +SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse*, Expr*); +SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse*, ExprList*); +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*); +SQLITE_PRIVATE char sqlite3AffinityType(const char*, Column*); +SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); +SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*, sqlite3_file*); +SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); +SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); +SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3*,Index*); +SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*); +SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int); +SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); +SQLITE_PRIVATE void sqlite3SchemaClear(void *); +SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *, Btree *); +SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int); +SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); +SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse*, ExprList*); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3KeyInfoIsWriteable(KeyInfo*); -#endif -SQLITE_PRIVATE int tdsqlite3CreateFunc(tdsqlite3 *, const char *, int, int, void *, - void (*)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*)(tdsqlite3_context*), - void (*)(tdsqlite3_context*), - void (*)(tdsqlite3_context*,int,tdsqlite3_value **), +SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo*); +#endif +SQLITE_PRIVATE int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*), + void (*)(sqlite3_context*,int,sqlite3_value **), FuncDestructor *pDestructor ); -SQLITE_PRIVATE void tdsqlite3NoopDestructor(void*); -SQLITE_PRIVATE void tdsqlite3OomFault(tdsqlite3*); -SQLITE_PRIVATE void tdsqlite3OomClear(tdsqlite3*); -SQLITE_PRIVATE int tdsqlite3ApiExit(tdsqlite3 *db, int); -SQLITE_PRIVATE int tdsqlite3OpenTempDatabase(Parse *); +SQLITE_PRIVATE void sqlite3NoopDestructor(void*); +SQLITE_PRIVATE void sqlite3OomFault(sqlite3*); +SQLITE_PRIVATE void sqlite3OomClear(sqlite3*); +SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int); +SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *); -SQLITE_PRIVATE void tdsqlite3StrAccumInit(StrAccum*, tdsqlite3*, char*, int, int); -SQLITE_PRIVATE char *tdsqlite3StrAccumFinish(StrAccum*); -SQLITE_PRIVATE void tdsqlite3SelectDestInit(SelectDest*,int,int); -SQLITE_PRIVATE Expr *tdsqlite3CreateColumnExpr(tdsqlite3 *, SrcList *, int, int); +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); +SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*); +SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); +SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); -SQLITE_PRIVATE void tdsqlite3BackupRestart(tdsqlite3_backup *); -SQLITE_PRIVATE void tdsqlite3BackupUpdate(tdsqlite3_backup *, Pgno, const u8 *); +SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); +SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); #ifndef SQLITE_OMIT_SUBQUERY -SQLITE_PRIVATE int tdsqlite3ExprCheckIN(Parse*, Expr*); +SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse*, Expr*); #else -# define tdsqlite3ExprCheckIN(x,y) SQLITE_OK +# define sqlite3ExprCheckIN(x,y) SQLITE_OK #endif #ifdef SQLITE_ENABLE_STAT4 -SQLITE_PRIVATE int tdsqlite3Stat4ProbeSetValue( +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( Parse*,Index*,UnpackedRecord**,Expr*,int,int,int*); -SQLITE_PRIVATE int tdsqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, tdsqlite3_value**); -SQLITE_PRIVATE void tdsqlite3Stat4ProbeFree(UnpackedRecord*); -SQLITE_PRIVATE int tdsqlite3Stat4Column(tdsqlite3*, const void*, int, int, tdsqlite3_value**); -SQLITE_PRIVATE char tdsqlite3IndexColumnAffinity(tdsqlite3*, Index*, int); +SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr(Parse*, Expr*, u8, sqlite3_value**); +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*); +SQLITE_PRIVATE int sqlite3Stat4Column(sqlite3*, const void*, int, int, sqlite3_value**); +SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3*, Index*, int); #endif /* ** The interface to the LEMON-generated parser */ #ifndef SQLITE_AMALGAMATION -SQLITE_PRIVATE void *tdsqlite3ParserAlloc(void*(*)(u64), Parse*); -SQLITE_PRIVATE void tdsqlite3ParserFree(void*, void(*)(void*)); +SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(u64), Parse*); +SQLITE_PRIVATE void sqlite3ParserFree(void*, void(*)(void*)); #endif -SQLITE_PRIVATE void tdsqlite3Parser(void*, int, Token); -SQLITE_PRIVATE int tdsqlite3ParserFallback(int); +SQLITE_PRIVATE void sqlite3Parser(void*, int, Token); +SQLITE_PRIVATE int sqlite3ParserFallback(int); #ifdef YYTRACKMAXSTACKDEPTH -SQLITE_PRIVATE int tdsqlite3ParserStackPeak(void*); +SQLITE_PRIVATE int sqlite3ParserStackPeak(void*); #endif -SQLITE_PRIVATE void tdsqlite3AutoLoadExtensions(tdsqlite3*); +SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3*); #ifndef SQLITE_OMIT_LOAD_EXTENSION -SQLITE_PRIVATE void tdsqlite3CloseExtensions(tdsqlite3*); +SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3*); #else -# define tdsqlite3CloseExtensions(X) +# define sqlite3CloseExtensions(X) #endif #ifndef SQLITE_OMIT_SHARED_CACHE -SQLITE_PRIVATE void tdsqlite3TableLock(Parse *, int, int, u8, const char *); +SQLITE_PRIVATE void sqlite3TableLock(Parse *, int, int, u8, const char *); #else - #define tdsqlite3TableLock(v,w,x,y,z) + #define sqlite3TableLock(v,w,x,y,z) #endif #ifdef SQLITE_TEST -SQLITE_PRIVATE int tdsqlite3Utf8To8(unsigned char*); +SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*); #endif #ifdef SQLITE_OMIT_VIRTUALTABLE -# define tdsqlite3VtabClear(Y) -# define tdsqlite3VtabSync(X,Y) SQLITE_OK -# define tdsqlite3VtabRollback(X) -# define tdsqlite3VtabCommit(X) -# define tdsqlite3VtabInSync(db) 0 -# define tdsqlite3VtabLock(X) -# define tdsqlite3VtabUnlock(X) -# define tdsqlite3VtabModuleUnref(D,X) -# define tdsqlite3VtabUnlockList(X) -# define tdsqlite3VtabSavepoint(X, Y, Z) SQLITE_OK -# define tdsqlite3GetVTable(X,Y) ((VTable*)0) -#else -SQLITE_PRIVATE void tdsqlite3VtabClear(tdsqlite3 *db, Table*); -SQLITE_PRIVATE void tdsqlite3VtabDisconnect(tdsqlite3 *db, Table *p); -SQLITE_PRIVATE int tdsqlite3VtabSync(tdsqlite3 *db, Vdbe*); -SQLITE_PRIVATE int tdsqlite3VtabRollback(tdsqlite3 *db); -SQLITE_PRIVATE int tdsqlite3VtabCommit(tdsqlite3 *db); -SQLITE_PRIVATE void tdsqlite3VtabLock(VTable *); -SQLITE_PRIVATE void tdsqlite3VtabUnlock(VTable *); -SQLITE_PRIVATE void tdsqlite3VtabModuleUnref(tdsqlite3*,Module*); -SQLITE_PRIVATE void tdsqlite3VtabUnlockList(tdsqlite3*); -SQLITE_PRIVATE int tdsqlite3VtabSavepoint(tdsqlite3 *, int, int); -SQLITE_PRIVATE void tdsqlite3VtabImportErrmsg(Vdbe*, tdsqlite3_vtab*); -SQLITE_PRIVATE VTable *tdsqlite3GetVTable(tdsqlite3*, Table*); -SQLITE_PRIVATE Module *tdsqlite3VtabCreateModule( - tdsqlite3*, +# define sqlite3VtabClear(Y) +# define sqlite3VtabSync(X,Y) SQLITE_OK +# define sqlite3VtabRollback(X) +# define sqlite3VtabCommit(X) +# define sqlite3VtabInSync(db) 0 +# define sqlite3VtabLock(X) +# define sqlite3VtabUnlock(X) +# define sqlite3VtabModuleUnref(D,X) +# define sqlite3VtabUnlockList(X) +# define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK +# define sqlite3GetVTable(X,Y) ((VTable*)0) +#else +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table*); +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p); +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe*); +SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); +SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); +SQLITE_PRIVATE void sqlite3VtabLock(VTable *); +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); +SQLITE_PRIVATE void sqlite3VtabModuleUnref(sqlite3*,Module*); +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *, int, int); +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); +SQLITE_PRIVATE Module *sqlite3VtabCreateModule( + sqlite3*, const char*, - const tdsqlite3_module*, + const sqlite3_module*, void*, void(*)(void*) ); -# define tdsqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) +# define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif -SQLITE_PRIVATE int tdsqlite3ReadOnlyShadowTables(tdsqlite3 *db); +SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db); #ifndef SQLITE_OMIT_VIRTUALTABLE -SQLITE_PRIVATE int tdsqlite3ShadowTableName(tdsqlite3 *db, const char *zName); -#else -# define tdsqlite3ShadowTableName(A,B) 0 -#endif -SQLITE_PRIVATE int tdsqlite3VtabEponymousTableInit(Parse*,Module*); -SQLITE_PRIVATE void tdsqlite3VtabEponymousTableClear(tdsqlite3*,Module*); -SQLITE_PRIVATE void tdsqlite3VtabMakeWritable(Parse*,Table*); -SQLITE_PRIVATE void tdsqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); -SQLITE_PRIVATE void tdsqlite3VtabFinishParse(Parse*, Token*); -SQLITE_PRIVATE void tdsqlite3VtabArgInit(Parse*); -SQLITE_PRIVATE void tdsqlite3VtabArgExtend(Parse*, Token*); -SQLITE_PRIVATE int tdsqlite3VtabCallCreate(tdsqlite3*, int, const char *, char **); -SQLITE_PRIVATE int tdsqlite3VtabCallConnect(Parse*, Table*); -SQLITE_PRIVATE int tdsqlite3VtabCallDestroy(tdsqlite3*, int, const char *); -SQLITE_PRIVATE int tdsqlite3VtabBegin(tdsqlite3 *, VTable *); -SQLITE_PRIVATE FuncDef *tdsqlite3VtabOverloadFunction(tdsqlite3 *,FuncDef*, int nArg, Expr*); -SQLITE_PRIVATE tdsqlite3_int64 tdsqlite3StmtCurrentTime(tdsqlite3_context*); -SQLITE_PRIVATE int tdsqlite3VdbeParameterIndex(Vdbe*, const char*, int); -SQLITE_PRIVATE int tdsqlite3TransferBindings(tdsqlite3_stmt *, tdsqlite3_stmt *); -SQLITE_PRIVATE void tdsqlite3ParserReset(Parse*); +SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName); +#else +# define sqlite3ShadowTableName(A,B) 0 +#endif +SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse*,Module*); +SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3*,Module*); +SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); +SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*, int); +SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*); +SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*); +SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*); +SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); +SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); +SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); +SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context*); +SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe*, const char*, int); +SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); +SQLITE_PRIVATE void sqlite3ParserReset(Parse*); #ifdef SQLITE_ENABLE_NORMALIZE -SQLITE_PRIVATE char *tdsqlite3Normalize(Vdbe*, const char*); -#endif -SQLITE_PRIVATE int tdsqlite3Reprepare(Vdbe*); -SQLITE_PRIVATE void tdsqlite3ExprListCheckLength(Parse*, ExprList*, const char*); -SQLITE_PRIVATE CollSeq *tdsqlite3ExprCompareCollSeq(Parse*,Expr*); -SQLITE_PRIVATE CollSeq *tdsqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); -SQLITE_PRIVATE int tdsqlite3TempInMemory(const tdsqlite3*); -SQLITE_PRIVATE const char *tdsqlite3JournalModename(int); +SQLITE_PRIVATE char *sqlite3Normalize(Vdbe*, const char*); +#endif +SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); +SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); +SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse*,Expr*); +SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); +SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); +SQLITE_PRIVATE const char *sqlite3JournalModename(int); #ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int tdsqlite3Checkpoint(tdsqlite3*, int, int, int*, int*); -SQLITE_PRIVATE int tdsqlite3WalDefaultHook(void*,tdsqlite3*,const char*,int); +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3*, int, int, int*, int*); +SQLITE_PRIVATE int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int); #endif #ifndef SQLITE_OMIT_CTE -SQLITE_PRIVATE With *tdsqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); -SQLITE_PRIVATE void tdsqlite3WithDelete(tdsqlite3*,With*); -SQLITE_PRIVATE void tdsqlite3WithPush(Parse*, With*, u8); +SQLITE_PRIVATE With *sqlite3WithAdd(Parse*,With*,Token*,ExprList*,Select*); +SQLITE_PRIVATE void sqlite3WithDelete(sqlite3*,With*); +SQLITE_PRIVATE void sqlite3WithPush(Parse*, With*, u8); #else -#define tdsqlite3WithPush(x,y,z) -#define tdsqlite3WithDelete(x,y) +#define sqlite3WithPush(x,y,z) +#define sqlite3WithDelete(x,y) #endif #ifndef SQLITE_OMIT_UPSERT -SQLITE_PRIVATE Upsert *tdsqlite3UpsertNew(tdsqlite3*,ExprList*,Expr*,ExprList*,Expr*); -SQLITE_PRIVATE void tdsqlite3UpsertDelete(tdsqlite3*,Upsert*); -SQLITE_PRIVATE Upsert *tdsqlite3UpsertDup(tdsqlite3*,Upsert*); -SQLITE_PRIVATE int tdsqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); -SQLITE_PRIVATE void tdsqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); +SQLITE_PRIVATE Upsert *sqlite3UpsertNew(sqlite3*,ExprList*,Expr*,ExprList*,Expr*); +SQLITE_PRIVATE void sqlite3UpsertDelete(sqlite3*,Upsert*); +SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3*,Upsert*); +SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget(Parse*,SrcList*,Upsert*); +SQLITE_PRIVATE void sqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); #else -#define tdsqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0) -#define tdsqlite3UpsertDelete(x,y) -#define tdsqlite3UpsertDup(x,y) ((Upsert*)0) +#define sqlite3UpsertNew(v,w,x,y,z) ((Upsert*)0) +#define sqlite3UpsertDelete(x,y) +#define sqlite3UpsertDup(x,y) ((Upsert*)0) #endif @@ -20022,26 +20022,26 @@ SQLITE_PRIVATE void tdsqlite3UpsertDoUpdate(Parse*,Upsert*,Table*,Index*,int); ** provided (enforcement of FK constraints requires the triggers sub-system). */ #if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) -SQLITE_PRIVATE void tdsqlite3FkCheck(Parse*, Table*, int, int, int*, int); -SQLITE_PRIVATE void tdsqlite3FkDropTable(Parse*, SrcList *, Table*); -SQLITE_PRIVATE void tdsqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); -SQLITE_PRIVATE int tdsqlite3FkRequired(Parse*, Table*, int*, int); -SQLITE_PRIVATE u32 tdsqlite3FkOldmask(Parse*, Table*); -SQLITE_PRIVATE FKey *tdsqlite3FkReferences(Table *); -#else - #define tdsqlite3FkActions(a,b,c,d,e,f) - #define tdsqlite3FkCheck(a,b,c,d,e,f) - #define tdsqlite3FkDropTable(a,b,c) - #define tdsqlite3FkOldmask(a,b) 0 - #define tdsqlite3FkRequired(a,b,c,d) 0 - #define tdsqlite3FkReferences(a) 0 +SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int, int*, int); +SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*); +SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); +SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); +SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); +#else + #define sqlite3FkActions(a,b,c,d,e,f) + #define sqlite3FkCheck(a,b,c,d,e,f) + #define sqlite3FkDropTable(a,b,c) + #define sqlite3FkOldmask(a,b) 0 + #define sqlite3FkRequired(a,b,c,d) 0 + #define sqlite3FkReferences(a) 0 #endif #ifndef SQLITE_OMIT_FOREIGN_KEY -SQLITE_PRIVATE void tdsqlite3FkDelete(tdsqlite3 *, Table*); -SQLITE_PRIVATE int tdsqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); +SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); #else - #define tdsqlite3FkDelete(a,b) - #define tdsqlite3FkLocateIndex(a,b,c,d,e) + #define sqlite3FkDelete(a,b) + #define sqlite3FkLocateIndex(a,b,c,d,e) #endif @@ -20057,15 +20057,15 @@ SQLITE_PRIVATE int tdsqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); ** is not defined. */ #ifndef SQLITE_UNTESTABLE -SQLITE_PRIVATE void tdsqlite3BeginBenignMalloc(void); -SQLITE_PRIVATE void tdsqlite3EndBenignMalloc(void); +SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void); +SQLITE_PRIVATE void sqlite3EndBenignMalloc(void); #else - #define tdsqlite3BeginBenignMalloc() - #define tdsqlite3EndBenignMalloc() + #define sqlite3BeginBenignMalloc() + #define sqlite3EndBenignMalloc() #endif /* -** Allowed return values from tdsqlite3FindInIndex() +** Allowed return values from sqlite3FindInIndex() */ #define IN_INDEX_ROWID 1 /* Search the rowid of the table */ #define IN_INDEX_EPH 2 /* Search an ephemeral b-tree */ @@ -20073,64 +20073,64 @@ SQLITE_PRIVATE void tdsqlite3EndBenignMalloc(void); #define IN_INDEX_INDEX_DESC 4 /* Existing index DESCENDING */ #define IN_INDEX_NOOP 5 /* No table available. Use comparisons */ /* -** Allowed flags for the 3rd parameter to tdsqlite3FindInIndex(). +** Allowed flags for the 3rd parameter to sqlite3FindInIndex(). */ #define IN_INDEX_NOOP_OK 0x0001 /* OK to return IN_INDEX_NOOP */ #define IN_INDEX_MEMBERSHIP 0x0002 /* IN operator used for membership test */ #define IN_INDEX_LOOP 0x0004 /* IN operator used as a loop */ -SQLITE_PRIVATE int tdsqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); +SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*); -SQLITE_PRIVATE int tdsqlite3JournalOpen(tdsqlite3_vfs *, const char *, tdsqlite3_file *, int, int); -SQLITE_PRIVATE int tdsqlite3JournalSize(tdsqlite3_vfs *); +SQLITE_PRIVATE int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int); +SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *); #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) -SQLITE_PRIVATE int tdsqlite3JournalCreate(tdsqlite3_file *); +SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *); #endif -SQLITE_PRIVATE int tdsqlite3JournalIsInMemory(tdsqlite3_file *p); -SQLITE_PRIVATE void tdsqlite3MemJournalOpen(tdsqlite3_file *); +SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p); +SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *); -SQLITE_PRIVATE void tdsqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p); #if SQLITE_MAX_EXPR_DEPTH>0 -SQLITE_PRIVATE int tdsqlite3SelectExprHeight(Select *); -SQLITE_PRIVATE int tdsqlite3ExprCheckHeight(Parse*, int); +SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *); +SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse*, int); #else - #define tdsqlite3SelectExprHeight(x) 0 - #define tdsqlite3ExprCheckHeight(x,y) + #define sqlite3SelectExprHeight(x) 0 + #define sqlite3ExprCheckHeight(x,y) #endif -SQLITE_PRIVATE u32 tdsqlite3Get4byte(const u8*); -SQLITE_PRIVATE void tdsqlite3Put4byte(u8*, u32); +SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*); +SQLITE_PRIVATE void sqlite3Put4byte(u8*, u32); #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY -SQLITE_PRIVATE void tdsqlite3ConnectionBlocked(tdsqlite3 *, tdsqlite3 *); -SQLITE_PRIVATE void tdsqlite3ConnectionUnlocked(tdsqlite3 *db); -SQLITE_PRIVATE void tdsqlite3ConnectionClosed(tdsqlite3 *db); +SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *, sqlite3 *); +SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db); +SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db); #else - #define tdsqlite3ConnectionBlocked(x,y) - #define tdsqlite3ConnectionUnlocked(x) - #define tdsqlite3ConnectionClosed(x) + #define sqlite3ConnectionBlocked(x,y) + #define sqlite3ConnectionUnlocked(x) + #define sqlite3ConnectionClosed(x) #endif #ifdef SQLITE_DEBUG -SQLITE_PRIVATE void tdsqlite3ParserTrace(FILE*, char *); +SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); #endif #if defined(YYCOVERAGE) -SQLITE_PRIVATE int tdsqlite3ParserCoverage(FILE*); +SQLITE_PRIVATE int sqlite3ParserCoverage(FILE*); #endif /* ** If the SQLITE_ENABLE IOTRACE exists then the global variable -** tdsqlite3IoTrace is a pointer to a printf-like routine used to +** sqlite3IoTrace is a pointer to a printf-like routine used to ** print I/O tracing messages. */ #ifdef SQLITE_ENABLE_IOTRACE -# define IOTRACE(A) if( tdsqlite3IoTrace ){ tdsqlite3IoTrace A; } -SQLITE_PRIVATE void tdsqlite3VdbeIOTraceSql(Vdbe*); -SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *tdsqlite3IoTrace)(const char*,...); +# define IOTRACE(A) if( sqlite3IoTrace ){ sqlite3IoTrace A; } +SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe*); +SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *sqlite3IoTrace)(const char*,...); #else # define IOTRACE(A) -# define tdsqlite3VdbeIOTraceSql(X) +# define sqlite3VdbeIOTraceSql(X) #endif /* @@ -20138,16 +20138,16 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *tdsqlite3IoTrace)(const char*,...); ** only. They are used to verify that different "types" of memory ** allocations are properly tracked by the system. ** -** tdsqlite3MemdebugSetType() sets the "type" of an allocation to one of +** sqlite3MemdebugSetType() sets the "type" of an allocation to one of ** the MEMTYPE_* macros defined below. The type must be a bitmask with ** a single bit set. ** -** tdsqlite3MemdebugHasType() returns true if any of the bits in its second -** argument match the type set by the previous tdsqlite3MemdebugSetType(). -** tdsqlite3MemdebugHasType() is intended for use inside assert() statements. +** sqlite3MemdebugHasType() returns true if any of the bits in its second +** argument match the type set by the previous sqlite3MemdebugSetType(). +** sqlite3MemdebugHasType() is intended for use inside assert() statements. ** -** tdsqlite3MemdebugNoType() returns true if none of the bits in its second -** argument match the type set by the previous tdsqlite3MemdebugSetType(). +** sqlite3MemdebugNoType() returns true if none of the bits in its second +** argument match the type set by the previous sqlite3MemdebugSetType(). ** ** Perhaps the most important point is the difference between MEMTYPE_HEAP ** and MEMTYPE_LOOKASIDE. If an allocation is MEMTYPE_LOOKASIDE, that means @@ -20162,13 +20162,13 @@ SQLITE_API SQLITE_EXTERN void (SQLITE_CDECL *tdsqlite3IoTrace)(const char*,...); ** play when the SQLITE_MEMDEBUG compile-time option is used. */ #ifdef SQLITE_MEMDEBUG -SQLITE_PRIVATE void tdsqlite3MemdebugSetType(void*,u8); -SQLITE_PRIVATE int tdsqlite3MemdebugHasType(void*,u8); -SQLITE_PRIVATE int tdsqlite3MemdebugNoType(void*,u8); +SQLITE_PRIVATE void sqlite3MemdebugSetType(void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugHasType(void*,u8); +SQLITE_PRIVATE int sqlite3MemdebugNoType(void*,u8); #else -# define tdsqlite3MemdebugSetType(X,Y) /* no-op */ -# define tdsqlite3MemdebugHasType(X,Y) 1 -# define tdsqlite3MemdebugNoType(X,Y) 1 +# define sqlite3MemdebugSetType(X,Y) /* no-op */ +# define sqlite3MemdebugHasType(X,Y) 1 +# define sqlite3MemdebugNoType(X,Y) 1 #endif #define MEMTYPE_HEAP 0x01 /* General heap allocations */ #define MEMTYPE_LOOKASIDE 0x02 /* Heap that might have been lookaside */ @@ -20178,25 +20178,25 @@ SQLITE_PRIVATE int tdsqlite3MemdebugNoType(void*,u8); ** Threading interface */ #if SQLITE_MAX_WORKER_THREADS>0 -SQLITE_PRIVATE int tdsqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); -SQLITE_PRIVATE int tdsqlite3ThreadJoin(SQLiteThread*, void**); +SQLITE_PRIVATE int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*); +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread*, void**); #endif #if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST) -SQLITE_PRIVATE int tdsqlite3DbpageRegister(tdsqlite3*); +SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3*); #endif #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST) -SQLITE_PRIVATE int tdsqlite3DbstatRegister(tdsqlite3*); +SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3*); #endif -SQLITE_PRIVATE int tdsqlite3ExprVectorSize(Expr *pExpr); -SQLITE_PRIVATE int tdsqlite3ExprIsVector(Expr *pExpr); -SQLITE_PRIVATE Expr *tdsqlite3VectorFieldSubexpr(Expr*, int); -SQLITE_PRIVATE Expr *tdsqlite3ExprForVectorField(Parse*,Expr*,int); -SQLITE_PRIVATE void tdsqlite3VectorErrorMsg(Parse*, Expr*); +SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr); +SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr); +SQLITE_PRIVATE Expr *sqlite3VectorFieldSubexpr(Expr*, int); +SQLITE_PRIVATE Expr *sqlite3ExprForVectorField(Parse*,Expr*,int); +SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse*, Expr*); #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS -SQLITE_PRIVATE const char **tdsqlite3CompileOptions(int *pnOpt); +SQLITE_PRIVATE const char **sqlite3CompileOptions(int *pnOpt); #endif #endif /* SQLITEINT_H */ @@ -20334,7 +20334,7 @@ SQLITE_PRIVATE sqlcipher_provider* sqlcipher_get_provider(void); #define SQLCIPHER_MUTEX_RESERVED3 5 #define SQLCIPHER_MUTEX_COUNT 6 -SQLITE_PRIVATE tdsqlite3_mutex* sqlcipher_mutex(int); +SQLITE_PRIVATE sqlite3_mutex* sqlcipher_mutex(int); #endif #endif @@ -20729,13 +20729,13 @@ struct BtLock { ** they often do so without holding sqlite3.mutex. */ struct Btree { - tdsqlite3 *db; /* The database connection holding this btree */ + sqlite3 *db; /* The database connection holding this btree */ BtShared *pBt; /* Sharable content of this btree */ u8 inTrans; /* TRANS_NONE, TRANS_READ or TRANS_WRITE */ u8 sharable; /* True if we can share pBt with another db */ u8 locked; /* True if db currently has pBt locked */ u8 hasIncrblobCur; /* True if there are one or more Incrblob cursors */ - int wantToLock; /* Number of nested calls to tdsqlite3BtreeEnter() */ + int wantToLock; /* Number of nested calls to sqlite3BtreeEnter() */ int nBackup; /* Number of backup operations reading this btree */ u32 iDataVersion; /* Combines with pBt->pPager->iDataVersion */ Btree *pNext; /* List of other sharable Btrees from the same db */ @@ -20793,10 +20793,10 @@ struct Btree { */ struct BtShared { Pager *pPager; /* The page cache */ - tdsqlite3 *db; /* Database connection currently using this Btree */ + sqlite3 *db; /* Database connection currently using this Btree */ BtCursor *pCursor; /* A list of all open cursors */ MemPage *pPage1; /* First page of the database */ - u8 openFlags; /* Flags to tdsqlite3BtreeOpen() */ + u8 openFlags; /* Flags to sqlite3BtreeOpen() */ #ifndef SQLITE_OMIT_AUTOVACUUM u8 autoVacuum; /* True if auto-vacuum is enabled */ u8 incrVacuum; /* True if incr-vacuum is enabled */ @@ -20816,9 +20816,9 @@ struct BtShared { u32 usableSize; /* Number of usable bytes on each page */ int nTransaction; /* Number of open transactions (read + write) */ u32 nPage; /* Number of pages in the database */ - void *pSchema; /* Pointer to space allocated by tdsqlite3BtreeSchema() */ + void *pSchema; /* Pointer to space allocated by sqlite3BtreeSchema() */ void (*xFreeSchema)(void*); /* Destructor for BtShared.pSchema */ - tdsqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */ + sqlite3_mutex *mutex; /* Non-recursive mutex required to access this object */ Bitvec *pHasContent; /* Set of pages moved to free-list this transaction */ #ifndef SQLITE_OMIT_SHARED_CACHE int nRef; /* Number of references to this structure */ @@ -20886,8 +20886,8 @@ struct CellInfo { ** eState Meaning of skipNext ** VALID skipNext is meaningless and is ignored ** INVALID skipNext is meaningless and is ignored -** SKIPNEXT tdsqlite3BtreeNext() is a no-op if skipNext>0 and -** tdsqlite3BtreePrevious() is no-op if skipNext<0. +** SKIPNEXT sqlite3BtreeNext() is a no-op if skipNext>0 and +** sqlite3BtreePrevious() is no-op if skipNext<0. ** REQUIRESEEK restoreCursorPosition() restores the cursor to ** eState=SKIPNEXT if skipNext!=0 ** FAULT skipNext holds the cursor fault error code. @@ -20895,7 +20895,7 @@ struct CellInfo { struct BtCursor { u8 eState; /* One of the CURSOR_XXX constants (see below) */ u8 curFlags; /* zero or more BTCF_* flags defined below */ - u8 curPagerFlags; /* Flags to send to tdsqlite3PagerGet() */ + u8 curPagerFlags; /* Flags to send to sqlite3PagerGet() */ u8 hints; /* As configured by CursorSetHints() */ int skipNext; /* Prev() is noop if negative. Next() is noop if positive. ** Error code if eState==CURSOR_FAULT */ @@ -20903,7 +20903,7 @@ struct BtCursor { Pgno *aOverflow; /* Cache of overflow page locations */ void *pKey; /* Saved key that was cursor last known position */ /* All fields above are zeroed when the cursor is allocated. See - ** tdsqlite3BtreeCursorZero(). Fields that follow must be manually + ** sqlite3BtreeCursorZero(). Fields that follow must be manually ** initialized. */ #define BTCURSOR_FIRST_UNINIT pBt /* Name of first uninitialized field */ BtShared *pBt; /* The BtShared this cursor points to */ @@ -20944,7 +20944,7 @@ struct BtCursor { ** ** CURSOR_SKIPNEXT: ** Cursor is valid except that the Cursor.skipNext field is non-zero -** indicating that the next tdsqlite3BtreeNext() or tdsqlite3BtreePrevious() +** indicating that the next sqlite3BtreeNext() or sqlite3BtreePrevious() ** operation should be a no-op. ** ** CURSOR_REQUIRESEEK: @@ -21073,7 +21073,7 @@ struct IntegrityCk { int v1, v2; /* Values for up to two %d fields in zPfx */ StrAccum errMsg; /* Accumulate the error message text here */ u32 *heap; /* Min-heap used for analyzing cell coverage */ - tdsqlite3 *db; /* Database connection running the check */ + sqlite3 *db; /* Database connection running the check */ }; /* @@ -21081,8 +21081,8 @@ struct IntegrityCk { */ #define get2byte(x) ((x)[0]<<8 | (x)[1]) #define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v)) -#define get4byte tdsqlite3Get4byte -#define put4byte tdsqlite3Put4byte +#define get4byte sqlite3Get4byte +#define put4byte sqlite3Put4byte /* ** get2byteAligned(), unlike get2byte(), requires that its argument point to a @@ -21104,11 +21104,11 @@ struct IntegrityCk { /* #include "pager.h" */ /* extensions defined in pager.c */ -SQLITE_PRIVATE void *tdsqlite3PagerGetCodec(Pager*); -SQLITE_PRIVATE void tdsqlite3PagerSetCodec(Pager*, void *(*)(void*,void*,Pgno,int), void (*)(void*,int,int), void (*)(void*), void *); -SQLITE_API int tdsqlite3pager_is_mj_pgno(Pager*, Pgno); -SQLITE_API void tdsqlite3pager_error(Pager*, int); -SQLITE_API void tdsqlite3pager_reset(Pager *pPager); +SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager*); +SQLITE_PRIVATE void sqlite3PagerSetCodec(Pager*, void *(*)(void*,void*,Pgno,int), void (*)(void*,int,int), void (*)(void*), void *); +SQLITE_API int sqlite3pager_is_mj_pgno(Pager*, Pgno); +SQLITE_API void sqlite3pager_error(Pager*, int); +SQLITE_API void sqlite3pager_reset(Pager *pPager); #define FILE_HEADER_SZ 16 @@ -21231,7 +21231,7 @@ static void cipher_hex2bin(const unsigned char *hex, int sz, unsigned char *out) static void cipher_bin2hex(const unsigned char* in, int sz, char *out) { int i; for(i=0; i < sz; i++) { - tdsqlite3_snprintf(3, out + (i*2), "%02x ", in[i]); + sqlite3_snprintf(3, out + (i*2), "%02x ", in[i]); } } @@ -21291,10 +21291,10 @@ typedef struct { } codec_ctx ; /* crypto.c functions */ -SQLITE_PRIVATE int sqlcipher_codec_pragma(tdsqlite3*, int, Parse*, const char *, const char*); -SQLITE_PRIVATE int tdsqlite3CodecAttach(tdsqlite3*, int, const void *, int); -SQLITE_PRIVATE void tdsqlite3CodecGetKey(tdsqlite3*, int, void**, int*); -SQLITE_PRIVATE void sqlcipher_exportFunc(tdsqlite3_context *, int, tdsqlite3_value **); +SQLITE_PRIVATE int sqlcipher_codec_pragma(sqlite3*, int, Parse*, const char *, const char*); +SQLITE_PRIVATE int sqlite3CodecAttach(sqlite3*, int, const void *, int); +SQLITE_PRIVATE void sqlite3CodecGetKey(sqlite3*, int, void**, int*); +SQLITE_PRIVATE void sqlcipher_exportFunc(sqlite3_context *, int, sqlite3_value **); /* crypto_impl.c functions */ @@ -21357,7 +21357,7 @@ SQLITE_PRIVATE int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int fla SQLITE_PRIVATE const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx); SQLITE_PRIVATE int sqlcipher_codec_ctx_migrate(codec_ctx *ctx); SQLITE_PRIVATE int sqlcipher_codec_add_random(codec_ctx *ctx, const char *data, int random_sz); -SQLITE_PRIVATE int sqlcipher_cipher_profile(tdsqlite3 *db, const char *destination); +SQLITE_PRIVATE int sqlcipher_cipher_profile(sqlite3 *db, const char *destination); SQLITE_PRIVATE int sqlcipher_codec_get_store_pass(codec_ctx *ctx); SQLITE_PRIVATE void sqlcipher_codec_get_pass(codec_ctx *ctx, void **zKey, int *nKey); SQLITE_PRIVATE void sqlcipher_codec_set_store_pass(codec_ctx *ctx, int value); @@ -21382,7 +21382,7 @@ SQLITE_PRIVATE int sqlcipher_codec_ctx_get_kdf_algorithm(codec_ctx *ctx); SQLITE_PRIVATE void sqlcipher_set_mem_security(int); SQLITE_PRIVATE int sqlcipher_get_mem_security(void); -SQLITE_PRIVATE int sqlcipher_find_db_index(tdsqlite3 *db, const char *zDb); +SQLITE_PRIVATE int sqlcipher_find_db_index(sqlite3 *db, const char *zDb); SQLITE_PRIVATE int sqlcipher_codec_ctx_integrity_check(codec_ctx *, Parse *, char *); @@ -21399,175 +21399,175 @@ SQLITE_PRIVATE int sqlcipher_codec_ctx_integrity_check(codec_ctx *, Parse *, cha /* Generate code to return a string value */ static void codec_vdbe_return_string(Parse *pParse, const char *zLabel, const char *value, int value_type){ - Vdbe *v = tdsqlite3GetVdbe(pParse); - tdsqlite3VdbeSetNumCols(v, 1); - tdsqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, value, value_type); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLabel, SQLITE_STATIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, value, value_type); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } -static int codec_set_btree_to_codec_pagesize(tdsqlite3 *db, Db *pDb, codec_ctx *ctx) { +static int codec_set_btree_to_codec_pagesize(sqlite3 *db, Db *pDb, codec_ctx *ctx) { int rc, page_sz, reserve_sz; page_sz = sqlcipher_codec_ctx_get_pagesize(ctx); reserve_sz = sqlcipher_codec_ctx_get_reservesize(ctx); - CODEC_TRACE("codec_set_btree_to_codec_pagesize: tdsqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, reserve_sz); + CODEC_TRACE("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize() size=%d reserve=%d\n", page_sz, reserve_sz); CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: entering database mutex %p\n", db->mutex); - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: entered database mutex %p\n", db->mutex); db->nextPagesize = page_sz; /* before forcing the page size we need to unset the BTS_PAGESIZE_FIXED flag, else sqliteBtreeSetPageSize will block the change */ pDb->pBt->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; - rc = tdsqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0); + rc = sqlite3BtreeSetPageSize(pDb->pBt, page_sz, reserve_sz, 0); - CODEC_TRACE("codec_set_btree_to_codec_pagesize: tdsqlite3BtreeSetPageSize returned %d\n", rc); + CODEC_TRACE("codec_set_btree_to_codec_pagesize: sqlite3BtreeSetPageSize returned %d\n", rc); CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: leaving database mutex %p\n", db->mutex); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); CODEC_TRACE_MUTEX("codec_set_btree_to_codec_pagesize: left database mutex %p\n", db->mutex); return rc; } -static int codec_set_pass_key(tdsqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) { +static int codec_set_pass_key(sqlite3* db, int nDb, const void *zKey, int nKey, int for_ctx) { struct Db *pDb = &db->aDb[nDb]; CODEC_TRACE("codec_set_pass_key: entered db=%p nDb=%d zKey=%s nKey=%d for_ctx=%d\n", db, nDb, (char *)zKey, nKey, for_ctx); if(pDb->pBt) { - codec_ctx *ctx = (codec_ctx*) tdsqlite3PagerGetCodec(pDb->pBt->pBt->pPager); + codec_ctx *ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager); if(ctx) return sqlcipher_codec_ctx_set_pass(ctx, zKey, nKey, for_ctx); } return SQLITE_ERROR; } -int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) { +int sqlcipher_codec_pragma(sqlite3* db, int iDb, Parse *pParse, const char *zLeft, const char *zRight) { struct Db *pDb = &db->aDb[iDb]; codec_ctx *ctx = NULL; int rc; if(pDb->pBt) { - ctx = (codec_ctx*) tdsqlite3PagerGetCodec(pDb->pBt->pBt->pPager); + ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager); } CODEC_TRACE("sqlcipher_codec_pragma: entered db=%p iDb=%d pParse=%p zLeft=%s zRight=%s ctx=%p\n", db, iDb, pParse, zLeft, zRight, ctx); #ifdef SQLCIPHER_EXT - if( tdsqlite3StrICmp(zLeft, "cipher_license")==0 && zRight ){ - char *license_result = tdsqlite3_mprintf("%d", sqlcipher_license_key(zRight)); + if( sqlite3StrICmp(zLeft, "cipher_license")==0 && zRight ){ + char *license_result = sqlite3_mprintf("%d", sqlcipher_license_key(zRight)); codec_vdbe_return_string(pParse, "cipher_license", license_result, P4_DYNAMIC); } else - if( tdsqlite3StrICmp(zLeft, "cipher_license")==0 && !zRight ){ + if( sqlite3StrICmp(zLeft, "cipher_license")==0 && !zRight ){ if(ctx) { - char *license_result = tdsqlite3_mprintf("%d", ctx + char *license_result = sqlite3_mprintf("%d", ctx ? sqlcipher_license_key_status(ctx->provider) : SQLITE_ERROR); codec_vdbe_return_string(pParse, "cipher_license", license_result, P4_DYNAMIC); } } else #endif - if( tdsqlite3StrICmp(zLeft, "cipher_fips_status")== 0 && !zRight ){ + if( sqlite3StrICmp(zLeft, "cipher_fips_status")== 0 && !zRight ){ if(ctx) { - char *fips_mode_status = tdsqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx)); + char *fips_mode_status = sqlite3_mprintf("%d", sqlcipher_codec_fips_status(ctx)); codec_vdbe_return_string(pParse, "cipher_fips_status", fips_mode_status, P4_DYNAMIC); } } else - if( tdsqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) { + if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && zRight ) { if(ctx) { - sqlcipher_codec_set_store_pass(ctx, tdsqlite3GetBoolean(zRight, 1)); + sqlcipher_codec_set_store_pass(ctx, sqlite3GetBoolean(zRight, 1)); } } else - if( tdsqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) { + if( sqlite3StrICmp(zLeft, "cipher_store_pass")==0 && !zRight ) { if(ctx){ - char *store_pass_value = tdsqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx)); + char *store_pass_value = sqlite3_mprintf("%d", sqlcipher_codec_get_store_pass(ctx)); codec_vdbe_return_string(pParse, "cipher_store_pass", store_pass_value, P4_DYNAMIC); } } - if( tdsqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){ - char *profile_status = tdsqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight)); + if( sqlite3StrICmp(zLeft, "cipher_profile")== 0 && zRight ){ + char *profile_status = sqlite3_mprintf("%d", sqlcipher_cipher_profile(db, zRight)); codec_vdbe_return_string(pParse, "cipher_profile", profile_status, P4_DYNAMIC); } else - if( tdsqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){ + if( sqlite3StrICmp(zLeft, "cipher_add_random")==0 && zRight ){ if(ctx) { - char *add_random_status = tdsqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, tdsqlite3Strlen30(zRight))); + char *add_random_status = sqlite3_mprintf("%d", sqlcipher_codec_add_random(ctx, zRight, sqlite3Strlen30(zRight))); codec_vdbe_return_string(pParse, "cipher_add_random", add_random_status, P4_DYNAMIC); } } else - if( tdsqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){ + if( sqlite3StrICmp(zLeft, "cipher_migrate")==0 && !zRight ){ if(ctx){ - char *migrate_status = tdsqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx)); + char *migrate_status = sqlite3_mprintf("%d", sqlcipher_codec_ctx_migrate(ctx)); codec_vdbe_return_string(pParse, "cipher_migrate", migrate_status, P4_DYNAMIC); } } else - if( tdsqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){ + if( sqlite3StrICmp(zLeft, "cipher_provider")==0 && !zRight ){ if(ctx) { codec_vdbe_return_string(pParse, "cipher_provider", sqlcipher_codec_get_cipher_provider(ctx), P4_TRANSIENT); } } else - if( tdsqlite3StrICmp(zLeft, "cipher_provider_version")==0 && !zRight){ + if( sqlite3StrICmp(zLeft, "cipher_provider_version")==0 && !zRight){ if(ctx) { codec_vdbe_return_string(pParse, "cipher_provider_version", sqlcipher_codec_get_provider_version(ctx), P4_TRANSIENT); } } else - if( tdsqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){ + if( sqlite3StrICmp(zLeft, "cipher_version")==0 && !zRight ){ codec_vdbe_return_string(pParse, "cipher_version", sqlcipher_version(), P4_DYNAMIC); }else - if( tdsqlite3StrICmp(zLeft, "cipher")==0 ){ + if( sqlite3StrICmp(zLeft, "cipher")==0 ){ if(ctx) { if( zRight ) { const char* message = "PRAGMA cipher is no longer supported."; codec_vdbe_return_string(pParse, "cipher", message, P4_TRANSIENT); - tdsqlite3_log(SQLITE_WARNING, message); + sqlite3_log(SQLITE_WARNING, message); }else { codec_vdbe_return_string(pParse, "cipher", sqlcipher_codec_ctx_get_cipher(ctx), P4_TRANSIENT); } } }else - if( tdsqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){ + if( sqlite3StrICmp(zLeft, "rekey_cipher")==0 && zRight ){ const char* message = "PRAGMA rekey_cipher is no longer supported."; codec_vdbe_return_string(pParse, "rekey_cipher", message, P4_TRANSIENT); - tdsqlite3_log(SQLITE_WARNING, message); + sqlite3_log(SQLITE_WARNING, message); }else - if( tdsqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_default_kdf_iter")==0 ){ if( zRight ) { sqlcipher_set_default_kdf_iter(atoi(zRight)); /* change default KDF iterations */ } else { - char *kdf_iter = tdsqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter()); + char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_get_default_kdf_iter()); codec_vdbe_return_string(pParse, "cipher_default_kdf_iter", kdf_iter, P4_DYNAMIC); } }else - if( tdsqlite3StrICmp(zLeft, "kdf_iter")==0 ){ + if( sqlite3StrICmp(zLeft, "kdf_iter")==0 ){ if(ctx) { if( zRight ) { sqlcipher_codec_ctx_set_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */ } else { - char *kdf_iter = tdsqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx)); + char *kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_kdf_iter(ctx)); codec_vdbe_return_string(pParse, "kdf_iter", kdf_iter, P4_DYNAMIC); } } }else - if( tdsqlite3StrICmp(zLeft, "fast_kdf_iter")==0){ + if( sqlite3StrICmp(zLeft, "fast_kdf_iter")==0){ if(ctx) { if( zRight ) { char *deprecation = "PRAGMA fast_kdf_iter is deprecated, please remove from use"; sqlcipher_codec_ctx_set_fast_kdf_iter(ctx, atoi(zRight)); /* change of RW PBKDF2 iteration */ codec_vdbe_return_string(pParse, "fast_kdf_iter", deprecation, P4_TRANSIENT); - tdsqlite3_log(SQLITE_WARNING, deprecation); + sqlite3_log(SQLITE_WARNING, deprecation); } else { - char *fast_kdf_iter = tdsqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx)); + char *fast_kdf_iter = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_fast_kdf_iter(ctx)); codec_vdbe_return_string(pParse, "fast_kdf_iter", fast_kdf_iter, P4_DYNAMIC); } } }else - if( tdsqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){ + if( sqlite3StrICmp(zLeft, "rekey_kdf_iter")==0 && zRight ){ const char* message = "PRAGMA rekey_kdf_iter is no longer supported."; codec_vdbe_return_string(pParse, "rekey_kdf_iter", message, P4_TRANSIENT); - tdsqlite3_log(SQLITE_WARNING, message); + sqlite3_log(SQLITE_WARNING, message); }else - if( tdsqlite3StrICmp(zLeft,"cipher_page_size")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_page_size")==0 ){ if(ctx) { if( zRight ) { int size = atoi(zRight); @@ -21576,58 +21576,58 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx); if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc); } else { - char * page_size = tdsqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx)); + char * page_size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_pagesize(ctx)); codec_vdbe_return_string(pParse, "cipher_page_size", page_size, P4_DYNAMIC); } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_default_page_size")==0 ){ if( zRight ) { sqlcipher_set_default_pagesize(atoi(zRight)); } else { - char *default_page_size = tdsqlite3_mprintf("%d", sqlcipher_get_default_pagesize()); + char *default_page_size = sqlite3_mprintf("%d", sqlcipher_get_default_pagesize()); codec_vdbe_return_string(pParse, "cipher_default_page_size", default_page_size, P4_DYNAMIC); } }else - if( tdsqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_default_use_hmac")==0 ){ if( zRight ) { - sqlcipher_set_default_use_hmac(tdsqlite3GetBoolean(zRight,1)); + sqlcipher_set_default_use_hmac(sqlite3GetBoolean(zRight,1)); } else { - char *default_use_hmac = tdsqlite3_mprintf("%d", sqlcipher_get_default_use_hmac()); + char *default_use_hmac = sqlite3_mprintf("%d", sqlcipher_get_default_use_hmac()); codec_vdbe_return_string(pParse, "cipher_default_use_hmac", default_use_hmac, P4_DYNAMIC); } }else - if( tdsqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_use_hmac")==0 ){ if(ctx) { if( zRight ) { - rc = sqlcipher_codec_ctx_set_use_hmac(ctx, tdsqlite3GetBoolean(zRight,1)); + rc = sqlcipher_codec_ctx_set_use_hmac(ctx, sqlite3GetBoolean(zRight,1)); if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc); /* since the use of hmac has changed, the page size may also change */ rc = codec_set_btree_to_codec_pagesize(db, pDb, ctx); if(rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, rc); } else { - char *hmac_flag = tdsqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx)); + char *hmac_flag = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_use_hmac(ctx)); codec_vdbe_return_string(pParse, "cipher_use_hmac", hmac_flag, P4_DYNAMIC); } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_hmac_pgno")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_hmac_pgno")==0 ){ if(ctx) { if(zRight) { char *deprecation = "PRAGMA cipher_hmac_pgno is deprecated, please remove from use"; /* clear both pgno endian flags */ - if(tdsqlite3StrICmp(zRight, "le") == 0) { + if(sqlite3StrICmp(zRight, "le") == 0) { sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO); sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_LE_PGNO); - } else if(tdsqlite3StrICmp(zRight, "be") == 0) { + } else if(sqlite3StrICmp(zRight, "be") == 0) { sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO); sqlcipher_codec_ctx_set_flag(ctx, CIPHER_FLAG_BE_PGNO); - } else if(tdsqlite3StrICmp(zRight, "native") == 0) { + } else if(sqlite3StrICmp(zRight, "native") == 0) { sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_LE_PGNO); sqlcipher_codec_ctx_unset_flag(ctx, CIPHER_FLAG_BE_PGNO); } codec_vdbe_return_string(pParse, "cipher_hmac_pgno", deprecation, P4_TRANSIENT); - tdsqlite3_log(SQLITE_WARNING, deprecation); + sqlite3_log(SQLITE_WARNING, deprecation); } else { if(sqlcipher_codec_ctx_get_flag(ctx, CIPHER_FLAG_LE_PGNO)) { @@ -21640,77 +21640,77 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_hmac_salt_mask")==0 ){ if(ctx) { if(zRight) { char *deprecation = "PRAGMA cipher_hmac_salt_mask is deprecated, please remove from use"; - if (tdsqlite3StrNICmp(zRight ,"x'", 2) == 0 && tdsqlite3Strlen30(zRight) == 5) { + if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == 5) { unsigned char mask = 0; const unsigned char *hex = (const unsigned char *)zRight+2; cipher_hex2bin(hex,2,&mask); sqlcipher_set_hmac_salt_mask(mask); } codec_vdbe_return_string(pParse, "cipher_hmac_salt_mask", deprecation, P4_TRANSIENT); - tdsqlite3_log(SQLITE_WARNING, deprecation); + sqlite3_log(SQLITE_WARNING, deprecation); } else { - char *hmac_salt_mask = tdsqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask()); + char *hmac_salt_mask = sqlite3_mprintf("%02x", sqlcipher_get_hmac_salt_mask()); codec_vdbe_return_string(pParse, "cipher_hmac_salt_mask", hmac_salt_mask, P4_DYNAMIC); } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_plaintext_header_size")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_plaintext_header_size")==0 ){ if(ctx) { if( zRight ) { int size = atoi(zRight); if((rc = sqlcipher_codec_ctx_set_plaintext_header_size(ctx, size)) != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR); } else { - char *size = tdsqlite3_mprintf("%d", sqlcipher_codec_ctx_get_plaintext_header_size(ctx)); + char *size = sqlite3_mprintf("%d", sqlcipher_codec_ctx_get_plaintext_header_size(ctx)); codec_vdbe_return_string(pParse, "cipher_plaintext_header_size", size, P4_DYNAMIC); } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_default_plaintext_header_size")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_default_plaintext_header_size")==0 ){ if( zRight ) { sqlcipher_set_default_plaintext_header_size(atoi(zRight)); } else { - char *size = tdsqlite3_mprintf("%d", sqlcipher_get_default_plaintext_header_size()); + char *size = sqlite3_mprintf("%d", sqlcipher_get_default_plaintext_header_size()); codec_vdbe_return_string(pParse, "cipher_default_plaintext_header_size", size, P4_DYNAMIC); - tdsqlite3_free(size); + sqlite3_free(size); } }else - if( tdsqlite3StrICmp(zLeft,"cipher_salt")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_salt")==0 ){ if(ctx) { if(zRight) { - if (tdsqlite3StrNICmp(zRight ,"x'", 2) == 0 && tdsqlite3Strlen30(zRight) == (FILE_HEADER_SZ*2)+3) { - unsigned char *salt = (unsigned char*) tdsqlite3_malloc(FILE_HEADER_SZ); + if (sqlite3StrNICmp(zRight ,"x'", 2) == 0 && sqlite3Strlen30(zRight) == (FILE_HEADER_SZ*2)+3) { + unsigned char *salt = (unsigned char*) sqlite3_malloc(FILE_HEADER_SZ); const unsigned char *hex = (const unsigned char *)zRight+2; cipher_hex2bin(hex,FILE_HEADER_SZ*2,salt); sqlcipher_codec_ctx_set_kdf_salt(ctx, salt, FILE_HEADER_SZ); - tdsqlite3_free(salt); + sqlite3_free(salt); } } else { void *salt; - char *hexsalt = (char*) tdsqlite3_malloc((FILE_HEADER_SZ*2)+1); + char *hexsalt = (char*) sqlite3_malloc((FILE_HEADER_SZ*2)+1); if((rc = sqlcipher_codec_ctx_get_kdf_salt(ctx, &salt)) == SQLITE_OK) { cipher_bin2hex(salt, FILE_HEADER_SZ, hexsalt); codec_vdbe_return_string(pParse, "cipher_salt", hexsalt, P4_DYNAMIC); } else { - tdsqlite3_free(hexsalt); + sqlite3_free(hexsalt); sqlcipher_codec_ctx_set_error(ctx, rc); } } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_hmac_algorithm")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_hmac_algorithm")==0 ){ if(ctx) { if(zRight) { rc = SQLITE_ERROR; - if(tdsqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) { + if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) { rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA1); - } else if(tdsqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) { + } else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) { rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA256); - } else if(tdsqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) { + } else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) { rc = sqlcipher_codec_ctx_set_hmac_algorithm(ctx, SQLCIPHER_HMAC_SHA512); } if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR); @@ -21728,14 +21728,14 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_default_hmac_algorithm")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_default_hmac_algorithm")==0 ){ if(zRight) { rc = SQLITE_ERROR; - if(tdsqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) { + if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA1_LABEL) == 0) { rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA1); - } else if(tdsqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) { + } else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA256_LABEL) == 0) { rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA256); - } else if(tdsqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) { + } else if(sqlite3StrICmp(zRight, SQLCIPHER_HMAC_SHA512_LABEL) == 0) { rc = sqlcipher_set_default_hmac_algorithm(SQLCIPHER_HMAC_SHA512); } } else { @@ -21749,15 +21749,15 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_kdf_algorithm")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_kdf_algorithm")==0 ){ if(ctx) { if(zRight) { rc = SQLITE_ERROR; - if(tdsqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) { + if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) { rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA1); - } else if(tdsqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) { + } else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) { rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA256); - } else if(tdsqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) { + } else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) { rc = sqlcipher_codec_ctx_set_kdf_algorithm(ctx, SQLCIPHER_PBKDF2_HMAC_SHA512); } if (rc != SQLITE_OK) sqlcipher_codec_ctx_set_error(ctx, SQLITE_ERROR); @@ -21773,14 +21773,14 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_default_kdf_algorithm")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_default_kdf_algorithm")==0 ){ if(zRight) { rc = SQLITE_ERROR; - if(tdsqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) { + if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL) == 0) { rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA1); - } else if(tdsqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) { + } else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL) == 0) { rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA256); - } else if(tdsqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) { + } else if(sqlite3StrICmp(zRight, SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL) == 0) { rc = sqlcipher_set_default_kdf_algorithm(SQLCIPHER_PBKDF2_HMAC_SHA512); } } else { @@ -21794,7 +21794,7 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_compatibility")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_compatibility")==0 ){ if(ctx) { if(zRight) { int version = atoi(zRight); @@ -21858,7 +21858,7 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_default_compatibility")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_default_compatibility")==0 ){ if(zRight) { int version = atoi(zRight); switch(version) { @@ -21896,94 +21896,94 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL } } }else - if( tdsqlite3StrICmp(zLeft,"cipher_memory_security")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_memory_security")==0 ){ if( zRight ) { - sqlcipher_set_mem_security(tdsqlite3GetBoolean(zRight,1)); + sqlcipher_set_mem_security(sqlite3GetBoolean(zRight,1)); } else { - char *on = tdsqlite3_mprintf("%d", sqlcipher_get_mem_security()); + char *on = sqlite3_mprintf("%d", sqlcipher_get_mem_security()); codec_vdbe_return_string(pParse, "cipher_memory_security", on, P4_DYNAMIC); } }else - if( tdsqlite3StrICmp(zLeft,"cipher_settings")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_settings")==0 ){ if(ctx) { int algorithm; char *pragma; - pragma = tdsqlite3_mprintf("PRAGMA kdf_iter = %d;", sqlcipher_codec_ctx_get_kdf_iter(ctx)); + pragma = sqlite3_mprintf("PRAGMA kdf_iter = %d;", sqlcipher_codec_ctx_get_kdf_iter(ctx)); codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); - pragma = tdsqlite3_mprintf("PRAGMA cipher_page_size = %d;", sqlcipher_codec_ctx_get_pagesize(ctx)); + pragma = sqlite3_mprintf("PRAGMA cipher_page_size = %d;", sqlcipher_codec_ctx_get_pagesize(ctx)); codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); - pragma = tdsqlite3_mprintf("PRAGMA cipher_use_hmac = %d;", sqlcipher_codec_ctx_get_use_hmac(ctx)); + pragma = sqlite3_mprintf("PRAGMA cipher_use_hmac = %d;", sqlcipher_codec_ctx_get_use_hmac(ctx)); codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); - pragma = tdsqlite3_mprintf("PRAGMA cipher_plaintext_header_size = %d;", sqlcipher_codec_ctx_get_plaintext_header_size(ctx)); + pragma = sqlite3_mprintf("PRAGMA cipher_plaintext_header_size = %d;", sqlcipher_codec_ctx_get_plaintext_header_size(ctx)); codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); algorithm = sqlcipher_codec_ctx_get_hmac_algorithm(ctx); pragma = NULL; if(algorithm == SQLCIPHER_HMAC_SHA1) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL); } else if(algorithm == SQLCIPHER_HMAC_SHA256) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL); } else if(algorithm == SQLCIPHER_HMAC_SHA512) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL); } codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); algorithm = sqlcipher_codec_ctx_get_kdf_algorithm(ctx); pragma = NULL; if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL); } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL); } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL); } codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); } }else - if( tdsqlite3StrICmp(zLeft,"cipher_default_settings")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_default_settings")==0 ){ int algorithm; char *pragma; - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_kdf_iter = %d;", sqlcipher_get_default_kdf_iter()); + pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_iter = %d;", sqlcipher_get_default_kdf_iter()); codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_page_size = %d;", sqlcipher_get_default_pagesize()); + pragma = sqlite3_mprintf("PRAGMA cipher_default_page_size = %d;", sqlcipher_get_default_pagesize()); codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_use_hmac = %d;", sqlcipher_get_default_use_hmac()); + pragma = sqlite3_mprintf("PRAGMA cipher_default_use_hmac = %d;", sqlcipher_get_default_use_hmac()); codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_plaintext_header_size = %d;", sqlcipher_get_default_plaintext_header_size()); + pragma = sqlite3_mprintf("PRAGMA cipher_default_plaintext_header_size = %d;", sqlcipher_get_default_plaintext_header_size()); codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); algorithm = sqlcipher_get_default_hmac_algorithm(); pragma = NULL; if(algorithm == SQLCIPHER_HMAC_SHA1) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA1_LABEL); } else if(algorithm == SQLCIPHER_HMAC_SHA256) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA256_LABEL); } else if(algorithm == SQLCIPHER_HMAC_SHA512) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_default_hmac_algorithm = %s;", SQLCIPHER_HMAC_SHA512_LABEL); } codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); algorithm = sqlcipher_get_default_kdf_algorithm(); pragma = NULL; if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA1) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA1_LABEL); } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA256) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA256_LABEL); } else if(algorithm == SQLCIPHER_PBKDF2_HMAC_SHA512) { - pragma = tdsqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL); + pragma = sqlite3_mprintf("PRAGMA cipher_default_kdf_algorithm = %s;", SQLCIPHER_PBKDF2_HMAC_SHA512_LABEL); } codec_vdbe_return_string(pParse, "pragma", pragma, P4_DYNAMIC); }else - if( tdsqlite3StrICmp(zLeft,"cipher_integrity_check")==0 ){ + if( sqlite3StrICmp(zLeft,"cipher_integrity_check")==0 ){ if(ctx) { sqlcipher_codec_ctx_integrity_check(ctx, pParse, "cipher_integrity_check"); } @@ -22003,13 +22003,13 @@ int sqlcipher_codec_pragma(tdsqlite3* db, int iDb, Parse *pParse, const char *zL #define CODEC_JOURNAL_OP 7 /* - * tdsqlite3Codec can be called in multiple modes. + * sqlite3Codec can be called in multiple modes. * encrypt mode - expected to return a pointer to the * encrypted data without altering pData. * decrypt mode - expected to return a pointer to pData, with * the data decrypted in the input buffer */ -static void* tdsqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { +static void* sqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { codec_ctx *ctx = (codec_ctx *) iCtx; int offset = 0, rc = 0; int page_sz = sqlcipher_codec_ctx_get_pagesize(ctx); @@ -22018,7 +22018,7 @@ static void* tdsqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { int plaintext_header_sz = sqlcipher_codec_ctx_get_plaintext_header_size(ctx); int cctx = CIPHER_READ_CTX; - CODEC_TRACE("tdsqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz); + CODEC_TRACE("sqlite3Codec: entered pgno=%d, mode=%d, page_sz=%d\n", pgno, mode, page_sz); #ifdef SQLCIPHER_EXT if(sqlcipher_license_check(ctx) != SQLITE_OK) return NULL; @@ -22034,7 +22034,7 @@ static void* tdsqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { offset = plaintext_header_sz ? plaintext_header_sz : FILE_HEADER_SZ; - CODEC_TRACE("tdsqlite3Codec: switch mode=%d offset=%d\n", mode, offset); + CODEC_TRACE("sqlite3Codec: switch mode=%d offset=%d\n", mode, offset); switch(mode) { case CODEC_READ_OP: /* decrypt */ if(pgno == 1) /* copy initial part of file header or SQLite magic to buffer */ @@ -22077,86 +22077,86 @@ static void* tdsqlite3Codec(void *iCtx, void *data, Pgno pgno, int mode) { } } -static void tdsqlite3FreeCodecArg(void *pCodecArg) { +static void sqlite3FreeCodecArg(void *pCodecArg) { codec_ctx *ctx = (codec_ctx *) pCodecArg; if(pCodecArg == NULL) return; sqlcipher_codec_ctx_free(&ctx); /* wipe and free allocated memory for the context */ sqlcipher_deactivate(); /* cleanup related structures, OpenSSL etc, when codec is detatched */ } -SQLITE_PRIVATE int tdsqlite3CodecAttach(tdsqlite3* db, int nDb, const void *zKey, int nKey) { +SQLITE_PRIVATE int sqlite3CodecAttach(sqlite3* db, int nDb, const void *zKey, int nKey) { struct Db *pDb = &db->aDb[nDb]; - CODEC_TRACE("tdsqlite3CodecAttach: entered db=%p, nDb=%d zKey=%s, nKey=%d\n", db, nDb, (char *)zKey, nKey); + CODEC_TRACE("sqlite3CodecAttach: entered db=%p, nDb=%d zKey=%s, nKey=%d\n", db, nDb, (char *)zKey, nKey); if(nKey && zKey && pDb->pBt) { int rc; Pager *pPager = pDb->pBt->pBt->pPager; - tdsqlite3_file *fd; + sqlite3_file *fd; codec_ctx *ctx; - /* check if the tdsqlite3_file is open, and if not force handle to NULL */ - if((fd = tdsqlite3PagerFile(pPager))->pMethods == 0) fd = NULL; + /* check if the sqlite3_file is open, and if not force handle to NULL */ + if((fd = sqlite3PagerFile(pPager))->pMethods == 0) fd = NULL; - CODEC_TRACE("tdsqlite3CodecAttach: calling sqlcipher_activate()\n"); + CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_activate()\n"); sqlcipher_activate(); /* perform internal initialization for sqlcipher */ - CODEC_TRACE_MUTEX("tdsqlite3CodecAttach: entering database mutex %p\n", db->mutex); - tdsqlite3_mutex_enter(db->mutex); - CODEC_TRACE_MUTEX("tdsqlite3CodecAttach: entered database mutex %p\n", db->mutex); + CODEC_TRACE_MUTEX("sqlite3CodecAttach: entering database mutex %p\n", db->mutex); + sqlite3_mutex_enter(db->mutex); + CODEC_TRACE_MUTEX("sqlite3CodecAttach: entered database mutex %p\n", db->mutex); #ifdef SQLCIPHER_EXT - if((rc = tdsqlite3_set_authorizer(db, sqlcipher_license_authorizer, db)) != SQLITE_OK) { - tdsqlite3_mutex_leave(db->mutex); + if((rc = sqlite3_set_authorizer(db, sqlcipher_license_authorizer, db)) != SQLITE_OK) { + sqlite3_mutex_leave(db->mutex); return rc; } #endif /* point the internal codec argument against the contet to be prepared */ - CODEC_TRACE("tdsqlite3CodecAttach: calling sqlcipher_codec_ctx_init()\n"); + CODEC_TRACE("sqlite3CodecAttach: calling sqlcipher_codec_ctx_init()\n"); rc = sqlcipher_codec_ctx_init(&ctx, pDb, pDb->pBt->pBt->pPager, zKey, nKey); if(rc != SQLITE_OK) { /* initialization failed, do not attach potentially corrupted context */ - CODEC_TRACE("tdsqlite3CodecAttach: context initialization failed with rc=%d\n", rc); + CODEC_TRACE("sqlite3CodecAttach: context initialization failed with rc=%d\n", rc); /* force an error at the pager level, such that even the upstream caller ignores the return code the pager will be in an error state and will process no further operations */ - tdsqlite3pager_error(pPager, rc); + sqlite3pager_error(pPager, rc); pDb->pBt->pBt->db->errCode = rc; - CODEC_TRACE_MUTEX("tdsqlite3CodecAttach: leaving database mutex %p (early return on rc=%d)\n", db->mutex, rc); - tdsqlite3_mutex_leave(db->mutex); - CODEC_TRACE_MUTEX("tdsqlite3CodecAttach: left database mutex %p (early return on rc=%d)\n", db->mutex, rc); + CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p (early return on rc=%d)\n", db->mutex, rc); + sqlite3_mutex_leave(db->mutex); + CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p (early return on rc=%d)\n", db->mutex, rc); return rc; } - CODEC_TRACE("tdsqlite3CodecAttach: calling tdsqlite3PagerSetCodec()\n"); - tdsqlite3PagerSetCodec(tdsqlite3BtreePager(pDb->pBt), tdsqlite3Codec, NULL, tdsqlite3FreeCodecArg, (void *) ctx); + CODEC_TRACE("sqlite3CodecAttach: calling sqlite3PagerSetCodec()\n"); + sqlite3PagerSetCodec(sqlite3BtreePager(pDb->pBt), sqlite3Codec, NULL, sqlite3FreeCodecArg, (void *) ctx); - CODEC_TRACE("tdsqlite3CodecAttach: calling codec_set_btree_to_codec_pagesize()\n"); + CODEC_TRACE("sqlite3CodecAttach: calling codec_set_btree_to_codec_pagesize()\n"); codec_set_btree_to_codec_pagesize(db, pDb, ctx); /* force secure delete. This has the benefit of wiping internal data when deleted and also ensures that all pages are written to disk (i.e. not skipped by - tdsqlite3PagerDontWrite optimizations) */ - CODEC_TRACE("tdsqlite3CodecAttach: calling tdsqlite3BtreeSecureDelete()\n"); - tdsqlite3BtreeSecureDelete(pDb->pBt, 1); + sqlite3PagerDontWrite optimizations) */ + CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSecureDelete()\n"); + sqlite3BtreeSecureDelete(pDb->pBt, 1); /* if fd is null, then this is an in-memory database and we dont' want to overwrite the AutoVacuum settings if not null, then set to the default */ if(fd != NULL) { - CODEC_TRACE("tdsqlite3CodecAttach: calling tdsqlite3BtreeSetAutoVacuum()\n"); - tdsqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM); + CODEC_TRACE("sqlite3CodecAttach: calling sqlite3BtreeSetAutoVacuum()\n"); + sqlite3BtreeSetAutoVacuum(pDb->pBt, SQLITE_DEFAULT_AUTOVACUUM); } - CODEC_TRACE_MUTEX("tdsqlite3CodecAttach: leaving database mutex %p\n", db->mutex); - tdsqlite3_mutex_leave(db->mutex); - CODEC_TRACE_MUTEX("tdsqlite3CodecAttach: left database mutex %p\n", db->mutex); + CODEC_TRACE_MUTEX("sqlite3CodecAttach: leaving database mutex %p\n", db->mutex); + sqlite3_mutex_leave(db->mutex); + CODEC_TRACE_MUTEX("sqlite3CodecAttach: left database mutex %p\n", db->mutex); } return SQLITE_OK; } -int sqlcipher_find_db_index(tdsqlite3 *db, const char *zDb) { +int sqlcipher_find_db_index(sqlite3 *db, const char *zDb) { int db_index; if(zDb == NULL){ return 0; @@ -22170,31 +22170,31 @@ int sqlcipher_find_db_index(tdsqlite3 *db, const char *zDb) { return 0; } -SQLITE_API void tdsqlite3_activate_see(const char* in) { +SQLITE_API void sqlite3_activate_see(const char* in) { /* do nothing, security enhancements are always active */ } -SQLITE_API int tdsqlite3_key(tdsqlite3 *db, const void *pKey, int nKey) { - CODEC_TRACE("tdsqlite3_key entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey); - return tdsqlite3_key_v2(db, "main", pKey, nKey); +SQLITE_API int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) { + CODEC_TRACE("sqlite3_key entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey); + return sqlite3_key_v2(db, "main", pKey, nKey); } -SQLITE_API int tdsqlite3_key_v2(tdsqlite3 *db, const char *zDb, const void *pKey, int nKey) { - CODEC_TRACE("tdsqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db, zDb, (char *)pKey, nKey); +SQLITE_API int sqlite3_key_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) { + CODEC_TRACE("sqlite3_key_v2: entered db=%p zDb=%s pKey=%s nKey=%d\n", db, zDb, (char *)pKey, nKey); /* attach key if db and pKey are not null and nKey is > 0 */ if(db && pKey && nKey) { int db_index = sqlcipher_find_db_index(db, zDb); - return tdsqlite3CodecAttach(db, db_index, pKey, nKey); + return sqlite3CodecAttach(db, db_index, pKey, nKey); } return SQLITE_ERROR; } -SQLITE_API int tdsqlite3_rekey(tdsqlite3 *db, const void *pKey, int nKey) { - CODEC_TRACE("tdsqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey); - return tdsqlite3_rekey_v2(db, "main", pKey, nKey); +SQLITE_API int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey) { + CODEC_TRACE("sqlite3_rekey entered: db=%p pKey=%s nKey=%d\n", db, (char *)pKey, nKey); + return sqlite3_rekey_v2(db, "main", pKey, nKey); } -/* tdsqlite3_rekey_v2 +/* sqlite3_rekey_v2 ** Given a database, this will reencrypt the database using a new key. ** There is only one possible modes of operation - to encrypt a database ** that is already encrpyted. If the database is not already encrypted @@ -22204,12 +22204,12 @@ SQLITE_API int tdsqlite3_rekey(tdsqlite3 *db, const void *pKey, int nKey) { ** 2. If there is NOT already a key present do nothing ** 3. If there is a key present, re-encrypt the database with the new key */ -SQLITE_API int tdsqlite3_rekey_v2(tdsqlite3 *db, const char *zDb, const void *pKey, int nKey) { - CODEC_TRACE("tdsqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db, zDb, (char *)pKey, nKey); +SQLITE_API int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey) { + CODEC_TRACE("sqlite3_rekey_v2: entered db=%p zDb=%s pKey=%s, nKey=%d\n", db, zDb, (char *)pKey, nKey); if(db && pKey && nKey) { int db_index = sqlcipher_find_db_index(db, zDb); struct Db *pDb = &db->aDb[db_index]; - CODEC_TRACE("tdsqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb, db_index); + CODEC_TRACE("sqlite3_rekey_v2: database pDb=%p db_index:%d\n", pDb, db_index); if(pDb->pBt) { codec_ctx *ctx; int rc, page_count; @@ -22217,17 +22217,17 @@ SQLITE_API int tdsqlite3_rekey_v2(tdsqlite3 *db, const char *zDb, const void *pK PgHdr *page; Pager *pPager = pDb->pBt->pBt->pPager; - ctx = (codec_ctx*) tdsqlite3PagerGetCodec(pDb->pBt->pBt->pPager); + ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager); if(ctx == NULL) { /* there was no codec attached to this database, so this should do nothing! */ - CODEC_TRACE("tdsqlite3_rekey_v2: no codec attached to db, exiting\n"); + CODEC_TRACE("sqlite3_rekey_v2: no codec attached to db, exiting\n"); return SQLITE_OK; } - CODEC_TRACE_MUTEX("tdsqlite3_rekey_v2: entering database mutex %p\n", db->mutex); - tdsqlite3_mutex_enter(db->mutex); - CODEC_TRACE_MUTEX("tdsqlite3_rekey_v2: entered database mutex %p\n", db->mutex); + CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entering database mutex %p\n", db->mutex); + sqlite3_mutex_enter(db->mutex); + CODEC_TRACE_MUTEX("sqlite3_rekey_v2: entered database mutex %p\n", db->mutex); codec_set_pass_key(db, db_index, pKey, nKey, CIPHER_WRITE_CTX); @@ -22237,48 +22237,48 @@ SQLITE_API int tdsqlite3_rekey_v2(tdsqlite3 *db, const char *zDb, const void *pK ** 3. If that goes ok then commit and put ctx->rekey into ctx->key ** note: don't deallocate rekey since it may be used in a subsequent iteration */ - rc = tdsqlite3BtreeBeginTrans(pDb->pBt, 1, 0); /* begin write transaction */ - tdsqlite3PagerPagecount(pPager, &page_count); + rc = sqlite3BtreeBeginTrans(pDb->pBt, 1, 0); /* begin write transaction */ + sqlite3PagerPagecount(pPager, &page_count); for(pgno = 1; rc == SQLITE_OK && pgno <= (unsigned int)page_count; pgno++) { /* pgno's start at 1 see pager.c:pagerAcquire */ - if(!tdsqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */ - rc = tdsqlite3PagerGet(pPager, pgno, &page, 0); + if(!sqlite3pager_is_mj_pgno(pPager, pgno)) { /* skip this page (see pager.c:pagerAcquire for reasoning) */ + rc = sqlite3PagerGet(pPager, pgno, &page, 0); if(rc == SQLITE_OK) { /* write page see pager_incr_changecounter for example */ - rc = tdsqlite3PagerWrite(page); + rc = sqlite3PagerWrite(page); if(rc == SQLITE_OK) { - tdsqlite3PagerUnref(page); + sqlite3PagerUnref(page); } else { - CODEC_TRACE("tdsqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno); + CODEC_TRACE("sqlite3_rekey_v2: error %d occurred writing page %d\n", rc, pgno); } } else { - CODEC_TRACE("tdsqlite3_rekey_v2: error %d occurred getting page %d\n", rc, pgno); + CODEC_TRACE("sqlite3_rekey_v2: error %d occurred getting page %d\n", rc, pgno); } } } /* if commit was successful commit and copy the rekey data to current key, else rollback to release locks */ if(rc == SQLITE_OK) { - CODEC_TRACE("tdsqlite3_rekey_v2: committing\n"); - rc = tdsqlite3BtreeCommit(pDb->pBt); + CODEC_TRACE("sqlite3_rekey_v2: committing\n"); + rc = sqlite3BtreeCommit(pDb->pBt); sqlcipher_codec_key_copy(ctx, CIPHER_WRITE_CTX); } else { - CODEC_TRACE("tdsqlite3_rekey_v2: rollback\n"); - tdsqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0); + CODEC_TRACE("sqlite3_rekey_v2: rollback\n"); + sqlite3BtreeRollback(pDb->pBt, SQLITE_ABORT_ROLLBACK, 0); } - CODEC_TRACE_MUTEX("tdsqlite3_rekey_v2: leaving database mutex %p\n", db->mutex); - tdsqlite3_mutex_leave(db->mutex); - CODEC_TRACE_MUTEX("tdsqlite3_rekey_v2: left database mutex %p\n", db->mutex); + CODEC_TRACE_MUTEX("sqlite3_rekey_v2: leaving database mutex %p\n", db->mutex); + sqlite3_mutex_leave(db->mutex); + CODEC_TRACE_MUTEX("sqlite3_rekey_v2: left database mutex %p\n", db->mutex); } return SQLITE_OK; } return SQLITE_ERROR; } -SQLITE_PRIVATE void tdsqlite3CodecGetKey(tdsqlite3* db, int nDb, void **zKey, int *nKey) { +SQLITE_PRIVATE void sqlite3CodecGetKey(sqlite3* db, int nDb, void **zKey, int *nKey) { struct Db *pDb = &db->aDb[nDb]; - CODEC_TRACE("tdsqlite3CodecGetKey: entered db=%p, nDb=%d\n", db, nDb); + CODEC_TRACE("sqlite3CodecGetKey: entered db=%p, nDb=%d\n", db, nDb); if( pDb->pBt ) { - codec_ctx *ctx = (codec_ctx*) tdsqlite3PagerGetCodec(pDb->pBt->pBt->pPager); + codec_ctx *ctx = (codec_ctx*) sqlite3PagerGetCodec(pDb->pBt->pBt->pPager); if(ctx) { /* pass back the keyspec from the codec, unless PRAGMA cipher_store_pass @@ -22317,11 +22317,11 @@ SQLITE_PRIVATE void tdsqlite3CodecGetKey(tdsqlite3* db, int nDb, void **zKey, in ** ** Based on vacuumFinalize from vacuum.c */ -static int sqlcipher_finalize(tdsqlite3 *db, tdsqlite3_stmt *pStmt, char **pzErrMsg){ +static int sqlcipher_finalize(sqlite3 *db, sqlite3_stmt *pStmt, char **pzErrMsg){ int rc; - rc = tdsqlite3VdbeFinalize((Vdbe*)pStmt); + rc = sqlite3VdbeFinalize((Vdbe*)pStmt); if( rc ){ - tdsqlite3SetString(pzErrMsg, db, tdsqlite3_errmsg(db)); + sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); } return rc; } @@ -22331,17 +22331,17 @@ static int sqlcipher_finalize(tdsqlite3 *db, tdsqlite3_stmt *pStmt, char **pzErr ** ** Based on execSql from vacuum.c */ -static int sqlcipher_execSql(tdsqlite3 *db, char **pzErrMsg, const char *zSql){ - tdsqlite3_stmt *pStmt; +static int sqlcipher_execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ + sqlite3_stmt *pStmt; VVA_ONLY( int rc; ) if( !zSql ){ return SQLITE_NOMEM; } - if( SQLITE_OK!=tdsqlite3_prepare(db, zSql, -1, &pStmt, 0) ){ - tdsqlite3SetString(pzErrMsg, db, tdsqlite3_errmsg(db)); - return tdsqlite3_errcode(db); + if( SQLITE_OK!=sqlite3_prepare(db, zSql, -1, &pStmt, 0) ){ + sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); + return sqlite3_errcode(db); } - VVA_ONLY( rc = ) tdsqlite3_step(pStmt); + VVA_ONLY( rc = ) sqlite3_step(pStmt); assert( rc!=SQLITE_ROW ); return sqlcipher_finalize(db, pStmt, pzErrMsg); } @@ -22352,15 +22352,15 @@ static int sqlcipher_execSql(tdsqlite3 *db, char **pzErrMsg, const char *zSql){ ** ** Based on execExecSql from vacuum.c */ -static int sqlcipher_execExecSql(tdsqlite3 *db, char **pzErrMsg, const char *zSql){ - tdsqlite3_stmt *pStmt; +static int sqlcipher_execExecSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ + sqlite3_stmt *pStmt; int rc; - rc = tdsqlite3_prepare(db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; - while( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - rc = sqlcipher_execSql(db, pzErrMsg, (char*)tdsqlite3_column_text(pStmt, 0)); + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + rc = sqlcipher_execSql(db, pzErrMsg, (char*)sqlite3_column_text(pStmt, 0)); if( rc!=SQLITE_OK ){ sqlcipher_finalize(db, pStmt, pzErrMsg); return rc; @@ -22373,10 +22373,10 @@ static int sqlcipher_execExecSql(tdsqlite3 *db, char **pzErrMsg, const char *zSq /* * copy database and schema from the main database to an attached database * - * Based on tdsqlite3RunVacuum from vacuum.c + * Based on sqlite3RunVacuum from vacuum.c */ -void sqlcipher_exportFunc(tdsqlite3_context *context, int argc, tdsqlite3_value **argv) { - tdsqlite3 *db = tdsqlite3_context_db_handle(context); +void sqlcipher_exportFunc(sqlite3_context *context, int argc, sqlite3_value **argv) { + sqlite3 *db = sqlite3_context_db_handle(context); const char* targetDb, *sourceDb; int targetDb_idx = 0; u64 saved_flags = db->flags; /* Saved value of the db->flags */ @@ -22391,19 +22391,19 @@ void sqlcipher_exportFunc(tdsqlite3_context *context, int argc, tdsqlite3_value if(argc != 1 && argc != 2) { rc = SQLITE_ERROR; - pzErrMsg = tdsqlite3_mprintf("invalid number of arguments (%d) passed to sqlcipher_export", argc); + pzErrMsg = sqlite3_mprintf("invalid number of arguments (%d) passed to sqlcipher_export", argc); goto end_of_export; } - targetDb = (const char*) tdsqlite3_value_text(argv[0]); - sourceDb = (argc == 2) ? (char *) tdsqlite3_value_text(argv[1]) : "main"; + targetDb = (const char*) sqlite3_value_text(argv[0]); + sourceDb = (argc == 2) ? (char *) sqlite3_value_text(argv[1]) : "main"; /* if the name of the target is not main, but the index returned is zero there is a mismatch and we should not proceed */ targetDb_idx = sqlcipher_find_db_index(db, targetDb); - if(targetDb_idx == 0 && tdsqlite3StrICmp("main", targetDb) != 0) { + if(targetDb_idx == 0 && sqlite3StrICmp("main", targetDb) != 0) { rc = SQLITE_ERROR; - pzErrMsg = tdsqlite3_mprintf("unknown database %s", targetDb); + pzErrMsg = sqlite3_mprintf("unknown database %s", targetDb); goto end_of_export; } db->init.iDb = targetDb_idx; @@ -22417,36 +22417,36 @@ void sqlcipher_exportFunc(tdsqlite3_context *context, int argc, tdsqlite3_value /* Query the schema of the main database. Create a mirror schema ** in the temporary database. */ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT sql " " FROM %s.sqlite_master WHERE type='table' AND name!='sqlite_sequence'" " AND rootpage>0" , sourceDb); rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); if( rc!=SQLITE_OK ) goto end_of_export; - tdsqlite3_free(zSql); + sqlite3_free(zSql); - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT sql " " FROM %s.sqlite_master WHERE sql LIKE 'CREATE INDEX %%' " , sourceDb); rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); if( rc!=SQLITE_OK ) goto end_of_export; - tdsqlite3_free(zSql); + sqlite3_free(zSql); - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT sql " " FROM %s.sqlite_master WHERE sql LIKE 'CREATE UNIQUE INDEX %%'" , sourceDb); rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); if( rc!=SQLITE_OK ) goto end_of_export; - tdsqlite3_free(zSql); + sqlite3_free(zSql); /* Loop through the tables in the main database. For each, do ** an "INSERT INTO rekey_db.xxx SELECT * FROM main.xxx;" to copy ** the contents to the temporary database. */ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT 'INSERT INTO %s.' || quote(name) " "|| ' SELECT * FROM %s.' || quote(name) || ';'" "FROM %s.sqlite_master " @@ -22455,25 +22455,25 @@ void sqlcipher_exportFunc(tdsqlite3_context *context, int argc, tdsqlite3_value , targetDb, sourceDb, sourceDb); rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); if( rc!=SQLITE_OK ) goto end_of_export; - tdsqlite3_free(zSql); + sqlite3_free(zSql); /* Copy over the contents of the sequence table */ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT 'INSERT INTO %s.' || quote(name) " "|| ' SELECT * FROM %s.' || quote(name) || ';' " "FROM %s.sqlite_master WHERE name=='sqlite_sequence';" , targetDb, sourceDb, targetDb); rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execExecSql(db, &pzErrMsg, zSql); if( rc!=SQLITE_OK ) goto end_of_export; - tdsqlite3_free(zSql); + sqlite3_free(zSql); /* Copy the triggers, views, and virtual tables from the main database ** over to the temporary database. None of these objects has any ** associated storage, so all we have to do is copy their entries ** from the SQLITE_MASTER table. */ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "INSERT INTO %s.sqlite_master " " SELECT type, name, tbl_name, rootpage, sql" " FROM %s.sqlite_master" @@ -22482,7 +22482,7 @@ void sqlcipher_exportFunc(tdsqlite3_context *context, int argc, tdsqlite3_value , targetDb, sourceDb); rc = (zSql == NULL) ? SQLITE_NOMEM : sqlcipher_execSql(db, &pzErrMsg, zSql); if( rc!=SQLITE_OK ) goto end_of_export; - tdsqlite3_free(zSql); + sqlite3_free(zSql); zSql = NULL; end_of_export: @@ -22494,14 +22494,14 @@ end_of_export: db->xTrace = saved_xTrace; db->mTrace = saved_mTrace; - if(zSql) tdsqlite3_free(zSql); + if(zSql) sqlite3_free(zSql); if(rc) { if(pzErrMsg != NULL) { - tdsqlite3_result_error(context, pzErrMsg, -1); - tdsqlite3DbFree(db, pzErrMsg); + sqlite3_result_error(context, pzErrMsg, -1); + sqlite3DbFree(db, pzErrMsg); } else { - tdsqlite3_result_error(context, tdsqlite3ErrStr(rc), -1); + sqlite3_result_error(context, sqlite3ErrStr(rc), -1); } } } @@ -22581,12 +22581,12 @@ static volatile int mem_security_on = 1; static volatile int mem_security_initialized = 0; static volatile int mem_security_activated = 0; static volatile unsigned int sqlcipher_activate_count = 0; -static volatile tdsqlite3_mem_methods default_mem_methods; +static volatile sqlite3_mem_methods default_mem_methods; static sqlcipher_provider *default_provider = NULL; -static tdsqlite3_mutex* sqlcipher_static_mutex[SQLCIPHER_MUTEX_COUNT]; +static sqlite3_mutex* sqlcipher_static_mutex[SQLCIPHER_MUTEX_COUNT]; -tdsqlite3_mutex* sqlcipher_mutex(int mutex) { +sqlite3_mutex* sqlcipher_mutex(int mutex) { if(mutex < 0 || mutex >= SQLCIPHER_MUTEX_COUNT) return NULL; return sqlcipher_static_mutex[mutex]; } @@ -22627,7 +22627,7 @@ static int sqlcipher_mem_roundup(int n) { return default_mem_methods.xRoundup(n); } -static tdsqlite3_mem_methods sqlcipher_mem_methods = { +static sqlite3_mem_methods sqlcipher_mem_methods = { sqlcipher_mem_malloc, sqlcipher_mem_free, sqlcipher_mem_realloc, @@ -22640,8 +22640,8 @@ static tdsqlite3_mem_methods sqlcipher_mem_methods = { void sqlcipher_init_memmethods() { if(mem_security_initialized) return; - if(tdsqlite3_config(SQLITE_CONFIG_GETMALLOC, &default_mem_methods) != SQLITE_OK || - tdsqlite3_config(SQLITE_CONFIG_MALLOC, &sqlcipher_mem_methods) != SQLITE_OK) { + if(sqlite3_config(SQLITE_CONFIG_GETMALLOC, &default_mem_methods) != SQLITE_OK || + sqlite3_config(SQLITE_CONFIG_MALLOC, &sqlcipher_mem_methods) != SQLITE_OK) { mem_security_on = mem_security_activated = 0; } mem_security_initialized = 1; @@ -22649,7 +22649,7 @@ void sqlcipher_init_memmethods() { int sqlcipher_register_provider(sqlcipher_provider *p) { CODEC_TRACE_MUTEX("sqlcipher_register_provider: entering SQLCIPHER_MUTEX_PROVIDER\n"); - tdsqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); CODEC_TRACE_MUTEX("sqlcipher_register_provider: entered SQLCIPHER_MUTEX_PROVIDER\n"); if(default_provider != NULL && default_provider != p) { @@ -22660,7 +22660,7 @@ int sqlcipher_register_provider(sqlcipher_provider *p) { } default_provider = p; CODEC_TRACE_MUTEX("sqlcipher_register_provider: leaving SQLCIPHER_MUTEX_PROVIDER\n"); - tdsqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); CODEC_TRACE_MUTEX("sqlcipher_register_provider: left SQLCIPHER_MUTEX_PROVIDER\n"); return SQLITE_OK; @@ -22675,7 +22675,7 @@ sqlcipher_provider* sqlcipher_get_provider() { void sqlcipher_deactivate() { CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering static master mutex\n"); - tdsqlite3_mutex_enter(tdsqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered static master mutex\n"); sqlcipher_activate_count--; @@ -22683,7 +22683,7 @@ void sqlcipher_deactivate() { if(sqlcipher_activate_count < 1) { CODEC_TRACE_MUTEX("sqlcipher_deactivate: entering SQLCIPHER_MUTEX_PROVIDER\n"); - tdsqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); CODEC_TRACE_MUTEX("sqlcipher_deactivate: entered SQLCIPHER_MUTEX_PROVIDER\n"); if(default_provider != NULL) { @@ -22692,7 +22692,7 @@ void sqlcipher_deactivate() { } CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER\n"); - tdsqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); CODEC_TRACE_MUTEX("sqlcipher_deactivate: left SQLCIPHER_MUTEX_PROVIDER\n"); #ifdef SQLCIPHER_EXT @@ -22703,14 +22703,14 @@ void sqlcipher_deactivate() { if(sqlcipher_activate_count == 0) { int i; for(i = 0; i < SQLCIPHER_MUTEX_COUNT; i++) { - tdsqlite3_mutex_free(sqlcipher_static_mutex[i]); + sqlite3_mutex_free(sqlcipher_static_mutex[i]); } } sqlcipher_activate_count = 0; /* reset activation count */ } CODEC_TRACE_MUTEX("sqlcipher_deactivate: leaving static master mutex\n"); - tdsqlite3_mutex_leave(tdsqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); CODEC_TRACE_MUTEX("sqlcipher_deactivate: left static master mutex\n"); } @@ -22814,7 +22814,7 @@ void sqlcipher_munlock(void *ptr, u64 sz) { } /** - * Free and wipe memory. Uses SQLites internal tdsqlite3_free so that memory + * Free and wipe memory. Uses SQLites internal sqlite3_free so that memory * can be countend and memory leak detection works in the test suite. * If ptr is not null memory will be freed. * If sz is greater than zero, the memory will be overwritten with zero before it is freed @@ -22825,7 +22825,7 @@ void sqlcipher_free(void *ptr, u64 sz) { CODEC_TRACE_MEMORY("sqlcipher_free: calling sqlcipher_memset(%p,0,%llu)\n", ptr, sz); sqlcipher_memset(ptr, 0, sz); sqlcipher_munlock(ptr, sz); - tdsqlite3_free(ptr); + sqlite3_free(ptr); } /** @@ -22835,8 +22835,8 @@ void sqlcipher_free(void *ptr, u64 sz) { */ void* sqlcipher_malloc(u64 sz) { void *ptr; - CODEC_TRACE_MEMORY("sqlcipher_malloc: calling tdsqlite3Malloc(%llu)\n", sz); - ptr = tdsqlite3Malloc(sz); + CODEC_TRACE_MEMORY("sqlcipher_malloc: calling sqlite3Malloc(%llu)\n", sz); + ptr = sqlite3Malloc(sz); CODEC_TRACE_MEMORY("sqlcipher_malloc: calling sqlcipher_memset(%p,0,%llu)\n", ptr, sz); sqlcipher_memset(ptr, 0, sz); sqlcipher_mlock(ptr, sz); @@ -22845,9 +22845,9 @@ void* sqlcipher_malloc(u64 sz) { char* sqlcipher_version() { #ifdef CIPHER_VERSION_QUALIFIER - char *version = tdsqlite3_mprintf("%s %s %s", CIPHER_XSTR(CIPHER_VERSION_NUMBER), CIPHER_XSTR(CIPHER_VERSION_QUALIFIER), CIPHER_XSTR(CIPHER_VERSION_BUILD)); + char *version = sqlite3_mprintf("%s %s %s", CIPHER_XSTR(CIPHER_VERSION_NUMBER), CIPHER_XSTR(CIPHER_VERSION_QUALIFIER), CIPHER_XSTR(CIPHER_VERSION_BUILD)); #else - char *version = tdsqlite3_mprintf("%s %s", CIPHER_XSTR(CIPHER_VERSION_NUMBER), CIPHER_XSTR(CIPHER_VERSION_BUILD)); + char *version = sqlite3_mprintf("%s %s", CIPHER_XSTR(CIPHER_VERSION_NUMBER), CIPHER_XSTR(CIPHER_VERSION_BUILD)); #endif return version; } @@ -23208,7 +23208,7 @@ int sqlcipher_codec_ctx_get_flag(codec_ctx *ctx, unsigned int flag) { void sqlcipher_codec_ctx_set_error(codec_ctx *ctx, int error) { CODEC_TRACE("sqlcipher_codec_ctx_set_error: ctx=%p, error=%d\n", ctx, error); - tdsqlite3pager_error(ctx->pBt->pBt->pPager, error); + sqlite3pager_error(ctx->pBt->pBt->pPager, error); ctx->pBt->pBt->db->errCode = error; } @@ -23221,7 +23221,7 @@ void* sqlcipher_codec_ctx_get_data(codec_ctx *ctx) { } static int sqlcipher_codec_ctx_init_kdf_salt(codec_ctx *ctx) { - tdsqlite3_file *fd = tdsqlite3PagerFile(ctx->pBt->pBt->pPager); + sqlite3_file *fd = sqlite3PagerFile(ctx->pBt->pBt->pPager); if(!ctx->need_kdf_salt) { return SQLITE_OK; /* don't reload salt when not needed */ @@ -23229,7 +23229,7 @@ static int sqlcipher_codec_ctx_init_kdf_salt(codec_ctx *ctx) { /* read salt from header, if present, otherwise generate a new random salt */ CODEC_TRACE("sqlcipher_codec_ctx_init_kdf_salt: obtaining salt\n"); - if(fd == NULL || fd->pMethods == 0 || tdsqlite3OsRead(fd, ctx->kdf_salt, ctx->kdf_salt_sz, 0) != SQLITE_OK) { + if(fd == NULL || fd->pMethods == 0 || sqlite3OsRead(fd, ctx->kdf_salt, ctx->kdf_salt_sz, 0) != SQLITE_OK) { CODEC_TRACE("sqlcipher_codec_ctx_init_kdf_salt: unable to read salt from file header, generating random\n"); if(ctx->provider->random(ctx->provider_ctx, ctx->kdf_salt, ctx->kdf_salt_sz) != SQLITE_OK) return SQLITE_ERROR; } @@ -23342,13 +23342,13 @@ int sqlcipher_codec_ctx_init(codec_ctx **iCtx, Db *pDb, Pager *pPager, const voi /* make a copy of the provider to be used for the duration of the context */ CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entering SQLCIPHER_MUTEX_PROVIDER\n"); - tdsqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: entered SQLCIPHER_MUTEX_PROVIDER\n"); memcpy(ctx->provider, default_provider, sizeof(sqlcipher_provider)); CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: leaving SQLCIPHER_MUTEX_PROVIDER\n"); - tdsqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER)); CODEC_TRACE_MUTEX("sqlcipher_codec_ctx_init: left SQLCIPHER_MUTEX_PROVIDER\n"); CODEC_TRACE("sqlcipher_codec_ctx_init: calling provider ctx_init\n"); @@ -23451,7 +23451,7 @@ static int sqlcipher_page_hmac(codec_ctx *ctx, cipher_ctx *c_ctx, Pgno pgno, uns if(ctx->flags & CIPHER_FLAG_LE_PGNO) { /* compute hmac using little endian pgno*/ sqlcipher_put4byte_le(pgno_raw, pgno); } else if(ctx->flags & CIPHER_FLAG_BE_PGNO) { /* compute hmac using big endian pgno */ - tdsqlite3Put4byte(pgno_raw, pgno); /* tdsqlite3Put4byte converts 32bit uint to big endian */ + sqlite3Put4byte(pgno_raw, pgno); /* sqlite3Put4byte converts 32bit uint to big endian */ } else { /* use native byte ordering */ memcpy(pgno_raw, &pgno, sizeof(pgno)); } @@ -23583,12 +23583,12 @@ static int sqlcipher_cipher_ctx_key_derive(codec_ctx *ctx, cipher_ctx *c_ctx) { if((rc = sqlcipher_codec_ctx_init_kdf_salt(ctx)) != SQLITE_OK) return rc; } - if (c_ctx->pass_sz == ((ctx->key_sz * 2) + 3) && tdsqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) == 0 && cipher_isHex(c_ctx->pass + 2, ctx->key_sz * 2)) { + if (c_ctx->pass_sz == ((ctx->key_sz * 2) + 3) && sqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) == 0 && cipher_isHex(c_ctx->pass + 2, ctx->key_sz * 2)) { int n = c_ctx->pass_sz - 3; /* adjust for leading x' and tailing ' */ const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */ CODEC_TRACE("cipher_ctx_key_derive: using raw key from hex\n"); cipher_hex2bin(z, n, c_ctx->key); - } else if (c_ctx->pass_sz == (((ctx->key_sz + ctx->kdf_salt_sz) * 2) + 3) && tdsqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) == 0 && cipher_isHex(c_ctx->pass + 2, (ctx->key_sz + ctx->kdf_salt_sz) * 2)) { + } else if (c_ctx->pass_sz == (((ctx->key_sz + ctx->kdf_salt_sz) * 2) + 3) && sqlite3StrNICmp((const char *)c_ctx->pass ,"x'", 2) == 0 && cipher_isHex(c_ctx->pass + 2, (ctx->key_sz + ctx->kdf_salt_sz) * 2)) { const unsigned char *z = c_ctx->pass + 2; /* adjust lead offset of x' */ CODEC_TRACE("cipher_ctx_key_derive: using raw key from hex\n"); cipher_hex2bin(z, (ctx->key_sz * 2), c_ctx->key); @@ -23673,39 +23673,39 @@ const char* sqlcipher_codec_get_cipher_provider(codec_ctx *ctx) { static int sqlcipher_check_connection(const char *filename, char *key, int key_sz, char *sql, int *user_version, char** journal_mode) { int rc; - tdsqlite3 *db = NULL; - tdsqlite3_stmt *statement = NULL; + sqlite3 *db = NULL; + sqlite3_stmt *statement = NULL; char *query_journal_mode = "PRAGMA journal_mode;"; char *query_user_version = "PRAGMA user_version;"; - rc = tdsqlite3_open(filename, &db); + rc = sqlite3_open(filename, &db); if(rc != SQLITE_OK) goto cleanup; - rc = tdsqlite3_key(db, key, key_sz); + rc = sqlite3_key(db, key, key_sz); if(rc != SQLITE_OK) goto cleanup; - rc = tdsqlite3_exec(db, sql, NULL, NULL, NULL); + rc = sqlite3_exec(db, sql, NULL, NULL, NULL); if(rc != SQLITE_OK) goto cleanup; /* start by querying the user version. this will fail if the key is incorrect */ - rc = tdsqlite3_prepare(db, query_user_version, -1, &statement, NULL); + rc = sqlite3_prepare(db, query_user_version, -1, &statement, NULL); if(rc != SQLITE_OK) goto cleanup; - rc = tdsqlite3_step(statement); + rc = sqlite3_step(statement); if(rc == SQLITE_ROW) { - *user_version = tdsqlite3_column_int(statement, 0); + *user_version = sqlite3_column_int(statement, 0); } else { goto cleanup; } - tdsqlite3_finalize(statement); + sqlite3_finalize(statement); - rc = tdsqlite3_prepare(db, query_journal_mode, -1, &statement, NULL); + rc = sqlite3_prepare(db, query_journal_mode, -1, &statement, NULL); if(rc != SQLITE_OK) goto cleanup; - rc = tdsqlite3_step(statement); + rc = sqlite3_step(statement); if(rc == SQLITE_ROW) { - *journal_mode = tdsqlite3_mprintf("%s", tdsqlite3_column_text(statement, 0)); + *journal_mode = sqlite3_mprintf("%s", sqlite3_column_text(statement, 0)); } else { goto cleanup; } @@ -23713,8 +23713,8 @@ static int sqlcipher_check_connection(const char *filename, char *key, int key_s /* cleanup will finalize open statement */ cleanup: - if(statement) tdsqlite3_finalize(statement); - if(db) tdsqlite3_close(db); + if(statement) sqlite3_finalize(statement); + if(db) sqlite3_close(db); return rc; } @@ -23723,32 +23723,32 @@ int sqlcipher_codec_ctx_integrity_check(codec_ctx *ctx, Parse *pParse, char *col int rc = 0; char *result; unsigned char *hmac_out = NULL; - tdsqlite3_file *fd = tdsqlite3PagerFile(ctx->pBt->pBt->pPager); + sqlite3_file *fd = sqlite3PagerFile(ctx->pBt->pBt->pPager); i64 file_sz; - Vdbe *v = tdsqlite3GetVdbe(pParse); - tdsqlite3VdbeSetNumCols(v, 1); - tdsqlite3VdbeSetColName(v, 0, COLNAME_NAME, column, SQLITE_STATIC); + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, column, SQLITE_STATIC); if(fd == NULL || fd->pMethods == 0) { - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, "database file is undefined", P4_TRANSIENT); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, "database file is undefined", P4_TRANSIENT); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); goto cleanup; } if(!(ctx->flags & CIPHER_FLAG_HMAC)) { - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, "HMAC is not enabled, unable to integrity check", P4_TRANSIENT); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, "HMAC is not enabled, unable to integrity check", P4_TRANSIENT); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); goto cleanup; } if((rc = sqlcipher_codec_key_derive(ctx)) != SQLITE_OK) { - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, "unable to derive keys", P4_TRANSIENT); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, "unable to derive keys", P4_TRANSIENT); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); goto cleanup; } - tdsqlite3OsFileSize(fd, &file_sz); + sqlite3OsFileSize(fd, &file_sz); hmac_out = sqlcipher_malloc(ctx->hmac_sz); for(page = 1; page <= file_sz / ctx->page_sz; page++) { @@ -23765,25 +23765,25 @@ int sqlcipher_codec_ctx_integrity_check(codec_ctx *ctx, Parse *pParse, char *col sqlcipher_memset(ctx->buffer, 0, ctx->page_sz); sqlcipher_memset(hmac_out, 0, ctx->hmac_sz); - if(tdsqlite3OsRead(fd, ctx->buffer, read_sz, offset) != SQLITE_OK) { - result = tdsqlite3_mprintf("error reading %d bytes from file page %d at offset %d\n", read_sz, page, offset); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, result, P4_DYNAMIC); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + if(sqlite3OsRead(fd, ctx->buffer, read_sz, offset) != SQLITE_OK) { + result = sqlite3_mprintf("error reading %d bytes from file page %d at offset %d\n", read_sz, page, offset); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, result, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } else if(sqlcipher_page_hmac(ctx, ctx->read_ctx, page, ctx->buffer, payload_sz, hmac_out) != SQLITE_OK) { - result = tdsqlite3_mprintf("HMAC operation failed for page %d", page); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, result, P4_DYNAMIC); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + result = sqlite3_mprintf("HMAC operation failed for page %d", page); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, result, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } else if(sqlcipher_memcmp(ctx->buffer + payload_sz, hmac_out, ctx->hmac_sz) != 0) { - result = tdsqlite3_mprintf("HMAC verification failed for page %d", page); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, result, P4_DYNAMIC); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + result = sqlite3_mprintf("HMAC verification failed for page %d", page); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, result, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } } if(file_sz % ctx->page_sz != 0) { - result = tdsqlite3_mprintf("page %d has an invalid size of %lld bytes", page, file_sz - ((file_sz / ctx->page_sz) * ctx->page_sz)); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, result, P4_DYNAMIC); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + result = sqlite3_mprintf("page %d has an invalid size of %lld bytes", page, file_sz - ((file_sz / ctx->page_sz) * ctx->page_sz)); + sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, result, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } cleanup: @@ -23794,18 +23794,18 @@ cleanup: int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { int i, pass_sz, keyspec_sz, nRes, user_version, rc, oflags; Db *pDb = 0; - tdsqlite3 *db = ctx->pBt->db; - const char *db_filename = tdsqlite3_db_filename(db, "main"); + sqlite3 *db = ctx->pBt->db; + const char *db_filename = sqlite3_db_filename(db, "main"); char *set_user_version = NULL, *pass = NULL, *attach_command = NULL, *migrated_db_filename = NULL, *keyspec = NULL, *temp = NULL, *journal_mode = NULL, *set_journal_mode = NULL, *pragma_compat = NULL; Btree *pDest = NULL, *pSrc = NULL; - tdsqlite3_file *srcfile, *destfile; + sqlite3_file *srcfile, *destfile; #if defined(_WIN32) || defined(SQLITE_OS_WINRT) LPWSTR w_db_filename = NULL, w_migrated_db_filename = NULL; int w_db_filename_sz = 0, w_migrated_db_filename_sz = 0; #endif pass_sz = keyspec_sz = rc = user_version = 0; - if(!db_filename || tdsqlite3Strlen30(db_filename) < 1) + if(!db_filename || sqlite3Strlen30(db_filename) < 1) goto cleanup; /* exit immediately if this is an in memory database */ /* pull the provided password / key material off the current codec context */ @@ -23822,13 +23822,13 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { } for(i = 3; i > 0; i--) { - pragma_compat = tdsqlite3_mprintf("PRAGMA cipher_compatibility = %d;", i); + pragma_compat = sqlite3_mprintf("PRAGMA cipher_compatibility = %d;", i); rc = sqlcipher_check_connection(db_filename, pass, pass_sz, pragma_compat, &user_version, &journal_mode); if(rc == SQLITE_OK) { CODEC_TRACE("Version %d format found\n", i); goto migrate; } - if(pragma_compat) sqlcipher_free(pragma_compat, tdsqlite3Strlen30(pragma_compat)); + if(pragma_compat) sqlcipher_free(pragma_compat, sqlite3Strlen30(pragma_compat)); pragma_compat = NULL; } /* if we exit the loop normally we failed to determine the version, this is an error */ @@ -23837,48 +23837,48 @@ int sqlcipher_codec_ctx_migrate(codec_ctx *ctx) { migrate: - temp = tdsqlite3_mprintf("%s-migrated", db_filename); - /* overallocate migrated_db_filename, because tdsqlite3OsOpen will read past the null terminator + temp = sqlite3_mprintf("%s-migrated", db_filename); + /* overallocate migrated_db_filename, because sqlite3OsOpen will read past the null terminator * to determine whether the filename was URI formatted */ - migrated_db_filename = sqlcipher_malloc(tdsqlite3Strlen30(temp)+2); - memcpy(migrated_db_filename, temp, tdsqlite3Strlen30(temp)); - sqlcipher_free(temp, tdsqlite3Strlen30(temp)); + migrated_db_filename = sqlcipher_malloc(sqlite3Strlen30(temp)+2); + memcpy(migrated_db_filename, temp, sqlite3Strlen30(temp)); + sqlcipher_free(temp, sqlite3Strlen30(temp)); - attach_command = tdsqlite3_mprintf("ATTACH DATABASE '%s' as migrate;", migrated_db_filename, pass); - set_user_version = tdsqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version); + attach_command = sqlite3_mprintf("ATTACH DATABASE '%s' as migrate;", migrated_db_filename, pass); + set_user_version = sqlite3_mprintf("PRAGMA migrate.user_version = %d;", user_version); - rc = tdsqlite3_exec(db, pragma_compat, NULL, NULL, NULL); + rc = sqlite3_exec(db, pragma_compat, NULL, NULL, NULL); if(rc != SQLITE_OK){ CODEC_TRACE("set compatibility mode failed, error code %d\n", rc); goto handle_error; } /* force journal mode to DELETE, we will set it back later if different */ - rc = tdsqlite3_exec(db, "PRAGMA journal_mode = delete;", NULL, NULL, NULL); + rc = sqlite3_exec(db, "PRAGMA journal_mode = delete;", NULL, NULL, NULL); if(rc != SQLITE_OK){ CODEC_TRACE("force journal mode DELETE failed, error code %d\n", rc); goto handle_error; } - rc = tdsqlite3_exec(db, attach_command, NULL, NULL, NULL); + rc = sqlite3_exec(db, attach_command, NULL, NULL, NULL); if(rc != SQLITE_OK){ CODEC_TRACE("attach failed, error code %d\n", rc); goto handle_error; } - rc = tdsqlite3_key_v2(db, "migrate", pass, pass_sz); + rc = sqlite3_key_v2(db, "migrate", pass, pass_sz); if(rc != SQLITE_OK){ CODEC_TRACE("keying attached database failed, error code %d\n", rc); goto handle_error; } - rc = tdsqlite3_exec(db, "SELECT sqlcipher_export('migrate');", NULL, NULL, NULL); + rc = sqlite3_exec(db, "SELECT sqlcipher_export('migrate');", NULL, NULL, NULL); if(rc != SQLITE_OK){ CODEC_TRACE("sqlcipher_export failed, error code %d\n", rc); goto handle_error; } - rc = tdsqlite3_exec(db, set_user_version, NULL, NULL, NULL); + rc = sqlite3_exec(db, set_user_version, NULL, NULL, NULL); if(rc != SQLITE_OK){ CODEC_TRACE("set user version failed, error code %d\n", rc); goto handle_error; @@ -23897,21 +23897,21 @@ migrate: pDb = &(db->aDb[db->nDb-1]); pSrc = pDb->pBt; - nRes = tdsqlite3BtreeGetOptimalReserve(pSrc); + nRes = sqlite3BtreeGetOptimalReserve(pSrc); /* unset the BTS_PAGESIZE_FIXED flag to avoid SQLITE_READONLY */ pDest->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; - rc = tdsqlite3BtreeSetPageSize(pDest, default_page_size, nRes, 0); + rc = sqlite3BtreeSetPageSize(pDest, default_page_size, nRes, 0); CODEC_TRACE("set btree page size to %d res %d rc %d\n", default_page_size, nRes, rc); if( rc!=SQLITE_OK ) goto handle_error; - tdsqlite3CodecGetKey(db, db->nDb - 1, (void**)&keyspec, &keyspec_sz); - tdsqlite3CodecAttach(db, 0, keyspec, keyspec_sz); + sqlite3CodecGetKey(db, db->nDb - 1, (void**)&keyspec, &keyspec_sz); + sqlite3CodecAttach(db, 0, keyspec, keyspec_sz); - srcfile = tdsqlite3PagerFile(pSrc->pBt->pPager); - destfile = tdsqlite3PagerFile(pDest->pBt->pPager); + srcfile = sqlite3PagerFile(pSrc->pBt->pPager); + destfile = sqlite3PagerFile(pDest->pBt->pPager); - tdsqlite3OsClose(srcfile); - tdsqlite3OsClose(destfile); + sqlite3OsClose(srcfile); + sqlite3OsClose(destfile); #if defined(_WIN32) || defined(SQLITE_OS_WINRT) CODEC_TRACE("performing windows MoveFileExA\n"); @@ -23939,30 +23939,30 @@ migrate: #endif CODEC_TRACE("renamed migration database %s to main database %s: %d\n", migrated_db_filename, db_filename, rc); - rc = tdsqlite3OsOpen(db->pVfs, migrated_db_filename, srcfile, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_DB, &oflags); + rc = sqlite3OsOpen(db->pVfs, migrated_db_filename, srcfile, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_DB, &oflags); CODEC_TRACE("reopened migration database: %d\n", rc); if( rc!=SQLITE_OK ) goto handle_error; - rc = tdsqlite3OsOpen(db->pVfs, db_filename, destfile, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_DB, &oflags); + rc = sqlite3OsOpen(db->pVfs, db_filename, destfile, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_DB, &oflags); CODEC_TRACE("reopened main database: %d\n", rc); if( rc!=SQLITE_OK ) goto handle_error; - tdsqlite3pager_reset(pDest->pBt->pPager); + sqlite3pager_reset(pDest->pBt->pPager); CODEC_TRACE("reset pager\n"); - rc = tdsqlite3_exec(db, "DETACH DATABASE migrate;", NULL, NULL, NULL); + rc = sqlite3_exec(db, "DETACH DATABASE migrate;", NULL, NULL, NULL); CODEC_TRACE("DETACH DATABASE called %d\n", rc); if(rc != SQLITE_OK) goto cleanup; - rc = tdsqlite3OsDelete(db->pVfs, migrated_db_filename, 0); + rc = sqlite3OsDelete(db->pVfs, migrated_db_filename, 0); CODEC_TRACE("deleted migration database: %d\n", rc); if( rc!=SQLITE_OK ) goto handle_error; - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ResetAllSchemasOfConnection(db); CODEC_TRACE("reset all schemas\n"); - set_journal_mode = tdsqlite3_mprintf("PRAGMA journal_mode = %s;", journal_mode); - rc = tdsqlite3_exec(db, set_journal_mode, NULL, NULL, NULL); + set_journal_mode = sqlite3_mprintf("PRAGMA journal_mode = %s;", journal_mode); + rc = sqlite3_exec(db, set_journal_mode, NULL, NULL, NULL); CODEC_TRACE("%s: %d\n", set_journal_mode, rc); if( rc!=SQLITE_OK ) goto handle_error; @@ -23974,12 +23974,12 @@ handle_error: cleanup: if(pass) sqlcipher_free(pass, pass_sz); - if(attach_command) sqlcipher_free(attach_command, tdsqlite3Strlen30(attach_command)); - if(migrated_db_filename) sqlcipher_free(migrated_db_filename, tdsqlite3Strlen30(migrated_db_filename)); - if(set_user_version) sqlcipher_free(set_user_version, tdsqlite3Strlen30(set_user_version)); - if(set_journal_mode) sqlcipher_free(set_journal_mode, tdsqlite3Strlen30(set_journal_mode)); - if(journal_mode) sqlcipher_free(journal_mode, tdsqlite3Strlen30(journal_mode)); - if(pragma_compat) sqlcipher_free(pragma_compat, tdsqlite3Strlen30(pragma_compat)); + if(attach_command) sqlcipher_free(attach_command, sqlite3Strlen30(attach_command)); + if(migrated_db_filename) sqlcipher_free(migrated_db_filename, sqlite3Strlen30(migrated_db_filename)); + if(set_user_version) sqlcipher_free(set_user_version, sqlite3Strlen30(set_user_version)); + if(set_journal_mode) sqlcipher_free(set_journal_mode, sqlite3Strlen30(set_journal_mode)); + if(journal_mode) sqlcipher_free(journal_mode, sqlite3Strlen30(journal_mode)); + if(pragma_compat) sqlcipher_free(pragma_compat, sqlite3Strlen30(pragma_compat)); #if defined(_WIN32) || defined(SQLITE_OS_WINRT) if(w_db_filename) sqlcipher_free(w_db_filename, w_db_filename_sz); if(w_migrated_db_filename) sqlcipher_free(w_migrated_db_filename, w_migrated_db_filename_sz); @@ -23991,8 +23991,8 @@ int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int random_sz const char *suffix = &zRight[random_sz-1]; int n = random_sz - 3; /* adjust for leading x' and tailing ' */ if (n > 0 && - tdsqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 && - tdsqlite3StrNICmp(suffix, "'", 1) == 0 && + sqlite3StrNICmp((const char *)zRight ,"x'", 2) == 0 && + sqlite3StrNICmp(suffix, "'", 1) == 0 && n % 2 == 0) { int rc = 0; int buffer_sz = n / 2; @@ -24009,22 +24009,22 @@ int sqlcipher_codec_add_random(codec_ctx *ctx, const char *zRight, int random_sz return SQLITE_ERROR; } -static void sqlcipher_profile_callback(void *file, const char *sql, tdsqlite3_uint64 run_time){ +static void sqlcipher_profile_callback(void *file, const char *sql, sqlite3_uint64 run_time){ FILE *f = (FILE*)file; double elapsed = run_time/1000000.0; if(f) fprintf(f, "Elapsed time:%.3f ms - %s\n", elapsed, sql); } -int sqlcipher_cipher_profile(tdsqlite3 *db, const char *destination){ +int sqlcipher_cipher_profile(sqlite3 *db, const char *destination){ #if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED) return SQLITE_ERROR; #else FILE *f; - if(tdsqlite3StrICmp(destination, "stdout") == 0){ + if(sqlite3StrICmp(destination, "stdout") == 0){ f = stdout; - }else if(tdsqlite3StrICmp(destination, "stderr") == 0){ + }else if(sqlite3StrICmp(destination, "stderr") == 0){ f = stderr; - }else if(tdsqlite3StrICmp(destination, "off") == 0){ + }else if(sqlite3StrICmp(destination, "off") == 0){ f = 0; }else{ #if !defined(SQLCIPHER_PROFILE_USE_FOPEN) && (defined(_WIN32) && (__STDC_VERSION__ > 199901L) || defined(SQLITE_OS_WINRT)) @@ -24033,7 +24033,7 @@ int sqlcipher_cipher_profile(tdsqlite3 *db, const char *destination){ if((f = fopen(destination, "a")) == 0) return SQLITE_ERROR; #endif } - tdsqlite3_profile(db, sqlcipher_profile_callback, f); + sqlite3_profile(db, sqlcipher_profile_callback, f); return SQLITE_OK; #endif } @@ -24136,13 +24136,13 @@ static void HMAC_CTX_free(HMAC_CTX *ctx) static int sqlcipher_openssl_add_random(void *ctx, void *buffer, int length) { #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n"); - tdsqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n"); #endif RAND_add(buffer, length, 0); #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n"); - tdsqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); CODEC_TRACE_MUTEX("sqlcipher_openssl_add_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n"); #endif return SQLITE_OK; @@ -24163,7 +24163,7 @@ static int sqlcipher_openssl_activate(void *ctx) { e.g. on startup */ CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); - tdsqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); if(openssl_init_count == 0 && EVP_get_cipherbyname(OPENSSL_CIPHER) != NULL) { @@ -24198,7 +24198,7 @@ static int sqlcipher_openssl_activate(void *ctx) { openssl_init_count++; CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); - tdsqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); CODEC_TRACE_MUTEX("sqlcipher_openssl_activate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); return SQLITE_OK; } @@ -24208,7 +24208,7 @@ static int sqlcipher_openssl_activate(void *ctx) { OpenSSL memory is cleaned up */ static int sqlcipher_openssl_deactivate(void *ctx) { CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entering SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); - tdsqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: entered SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); openssl_init_count--; @@ -24228,7 +24228,7 @@ static int sqlcipher_openssl_deactivate(void *ctx) { } CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: leaving SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); - tdsqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_ACTIVATE)); CODEC_TRACE_MUTEX("sqlcipher_openssl_deactivate: left SQLCIPHER_MUTEX_PROVIDER_ACTIVATE\n"); return SQLITE_OK; } @@ -24252,13 +24252,13 @@ static int sqlcipher_openssl_random (void *ctx, void *buffer, int length) { thread saftey in openssl externally */ #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entering SQLCIPHER_MUTEX_PROVIDER_RAND\n"); - tdsqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + sqlite3_mutex_enter(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); CODEC_TRACE_MUTEX("sqlcipher_openssl_random: entered SQLCIPHER_MUTEX_PROVIDER_RAND\n"); #endif rc = RAND_bytes((unsigned char *)buffer, length); #ifndef SQLCIPHER_OPENSSL_NO_MUTEX_RAND CODEC_TRACE_MUTEX("sqlcipher_openssl_random: leaving SQLCIPHER_MUTEX_PROVIDER_RAND\n"); - tdsqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); + sqlite3_mutex_leave(sqlcipher_mutex(SQLCIPHER_MUTEX_PROVIDER_RAND)); CODEC_TRACE_MUTEX("sqlcipher_openssl_random: left SQLCIPHER_MUTEX_PROVIDER_RAND\n"); #endif return (rc == 1) ? SQLITE_OK : SQLITE_ERROR; @@ -24435,14 +24435,14 @@ SQLITE_PRIVATE int sqlcipher_openssl_setup(sqlcipher_provider *p) { void sqlcipher_activate() { CODEC_TRACE_MUTEX("sqlcipher_activate: entering static master mutex\n"); - tdsqlite3_mutex_enter(tdsqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); CODEC_TRACE_MUTEX("sqlcipher_activate: entered static master mutex\n"); /* allocate new mutexes */ if(sqlcipher_activate_count == 0) { int i; for(i = 0; i < SQLCIPHER_MUTEX_COUNT; i++) { - sqlcipher_static_mutex[i] = tdsqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + sqlcipher_static_mutex[i] = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); } } @@ -24463,7 +24463,7 @@ void sqlcipher_activate() { sqlcipher_activate_count++; /* increment activation count */ CODEC_TRACE_MUTEX("sqlcipher_activate: leaving static master mutex\n"); - tdsqlite3_mutex_leave(tdsqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); + sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)); CODEC_TRACE_MUTEX("sqlcipher_activate: left static master mutex\n"); } @@ -24495,7 +24495,7 @@ void sqlcipher_activate() { ** handle case conversions for the UTF character set since the tables ** involved are nearly as big or bigger than SQLite itself. */ -SQLITE_PRIVATE const unsigned char tdsqlite3UpperToLower[] = { +SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = { #ifdef SQLITE_ASCII 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -24553,7 +24553,7 @@ SQLITE_PRIVATE const unsigned char tdsqlite3UpperToLower[] = { ** ** (x & ~(map[x]&0x20)) ** -** The equivalent of tolower() is implemented using the tdsqlite3UpperToLower[] +** The equivalent of tolower() is implemented using the sqlite3UpperToLower[] ** array. tolower() is used more often than toupper() by SQLite. ** ** Bit 0x40 is set if the character is non-alphanumeric and can be used in an @@ -24561,7 +24561,7 @@ SQLITE_PRIVATE const unsigned char tdsqlite3UpperToLower[] = { ** non-ASCII UTF character. Hence the test for whether or not a character is ** part of an identifier is 0x46. */ -SQLITE_PRIVATE const unsigned char tdsqlite3CtypeMap[256] = { +SQLITE_PRIVATE const unsigned char sqlite3CtypeMap[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 00..07 ........ */ 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, /* 08..0f ........ */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10..17 ........ */ @@ -24659,9 +24659,9 @@ SQLITE_PRIVATE const unsigned char tdsqlite3CtypeMap[256] = { ** The default lookaside-configuration, the format "SZ,N". SZ is the ** number of bytes in each lookaside slot (should be a multiple of 8) ** and N is the number of slots. The lookaside-configuration can be -** changed as start-time using tdsqlite3_config(SQLITE_CONFIG_LOOKASIDE) +** changed as start-time using sqlite3_config(SQLITE_CONFIG_LOOKASIDE) ** or at run-time for an individual database connection using -** tdsqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE); +** sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE); ** ** With the two-size-lookaside enhancement, less lookaside is required. ** The default configuration of 1200,40 actually provides 30 1200-byte slots @@ -24678,7 +24678,7 @@ SQLITE_PRIVATE const unsigned char tdsqlite3CtypeMap[256] = { /* The default maximum size of an in-memory database created using -** tdsqlite3_deserialize() +** sqlite3_deserialize() */ #ifndef SQLITE_MEMDB_DEFAULT_MAXSIZE # define SQLITE_MEMDB_DEFAULT_MAXSIZE 1073741824 @@ -24688,7 +24688,7 @@ SQLITE_PRIVATE const unsigned char tdsqlite3CtypeMap[256] = { ** The following singleton contains the global configuration for ** the SQLite library. */ -SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config tdsqlite3Config = { +SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { SQLITE_DEFAULT_MEMSTATUS, /* bMemstat */ 1, /* bCoreMutex */ SQLITE_THREADSAFE==1, /* bFullMutex */ @@ -24749,14 +24749,14 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config tdsqlite3Config = { ** database connections. After initialization, this table is ** read-only. */ -SQLITE_PRIVATE FuncDefHash tdsqlite3BuiltinFunctions; +SQLITE_PRIVATE FuncDefHash sqlite3BuiltinFunctions; #ifdef VDBE_PROFILE /* ** The following performance counter can be used in place of -** tdsqlite3Hwtime() for profiling. This is a no-op on standard builds. +** sqlite3Hwtime() for profiling. This is a no-op on standard builds. */ -SQLITE_PRIVATE tdsqlite3_uint64 tdsqlite3NProfileCnt = 0; +SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt = 0; #endif /* @@ -24769,7 +24769,7 @@ SQLITE_PRIVATE tdsqlite3_uint64 tdsqlite3NProfileCnt = 0; ** During testing, it is often desirable to move the pending byte to ** a different position in the file. This allows code that has to ** deal with the pending byte to run on files that are much smaller -** than 1 GiB. The tdsqlite3_test_control() interface can be used to +** than 1 GiB. The sqlite3_test_control() interface can be used to ** move the pending byte. ** ** IMPORTANT: Changing the pending byte to any value other than @@ -24778,7 +24778,7 @@ SQLITE_PRIVATE tdsqlite3_uint64 tdsqlite3NProfileCnt = 0; ** and incorrect behavior. */ #ifndef SQLITE_OMIT_WSD -SQLITE_PRIVATE int tdsqlite3PendingByte = 0x40000000; +SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; #endif /* #include "opcodes.h" */ @@ -24788,12 +24788,12 @@ SQLITE_PRIVATE int tdsqlite3PendingByte = 0x40000000; ** from the comments following the "case OP_xxxx:" statements in ** the vdbe.c file. */ -SQLITE_PRIVATE const unsigned char tdsqlite3OpcodeProperty[] = OPFLG_INITIALIZER; +SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[] = OPFLG_INITIALIZER; /* ** Name of the default collating sequence */ -SQLITE_PRIVATE const char tdsqlite3StrBINARY[] = "BINARY"; +SQLITE_PRIVATE const char sqlite3StrBINARY[] = "BINARY"; /************** End of global.c **********************************************/ /************** Begin file status.c ******************************************/ @@ -24809,7 +24809,7 @@ SQLITE_PRIVATE const char tdsqlite3StrBINARY[] = "BINARY"; ** ************************************************************************* ** -** This module implements the tdsqlite3_status() interface and related +** This module implements the sqlite3_status() interface and related ** functionality. */ /* #include "sqliteInt.h" */ @@ -24893,11 +24893,11 @@ struct VdbeCursor { u8 eCurType; /* One of the CURTYPE_* values above */ i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ u8 nullRow; /* True if pointing to a row with no data */ - u8 deferredMoveto; /* A call to tdsqlite3BtreeMoveto() is needed */ + u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ u8 isTable; /* True for rowid tables. False for indexes */ #ifdef SQLITE_DEBUG u8 seekOp; /* Most recent seek operation on this cursor */ - u8 wrFlag; /* The wrFlag argument to tdsqlite3BtreeCursor() */ + u8 wrFlag; /* The wrFlag argument to sqlite3BtreeCursor() */ #endif Bool isEphemeral:1; /* True for an ephemeral table */ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ @@ -24912,7 +24912,7 @@ struct VdbeCursor { ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that ** the cache is out of date. */ u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ - int seekResult; /* Result of previous tdsqlite3BtreeMoveto() or 0 + int seekResult; /* Result of previous sqlite3BtreeMoveto() or 0 ** if there have been no prior seeks on the cursor. */ /* seekResult does not distinguish between "no seeks have ever occurred ** on this cursor" and "the most recent seek was an exact match". @@ -24924,7 +24924,7 @@ struct VdbeCursor { VdbeCursor *pAltCursor; /* Associated index cursor from which to read */ union { BtCursor *pCursor; /* CURTYPE_BTREE or _PSEUDO. Btree cursor */ - tdsqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ + sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB. Vtab cursor */ VdbeSorter *pSorter; /* CURTYPE_SORTER. Sorter object */ } uc; KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ @@ -24932,7 +24932,7 @@ struct VdbeCursor { Pgno pgnoRoot; /* Root page of the open btree cursor */ i16 nField; /* Number of fields in the header */ u16 nHdrParsed; /* Number of header fields parsed so far */ - i64 movetoTarget; /* Argument to the deferred tdsqlite3BtreeMoveto() */ + i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ u32 *aOffset; /* Pointer to aType[nField] */ const u8 *aRow; /* Data for the current row, if all on one page */ u32 payloadSize; /* Total number of bytes in the record */ @@ -24968,7 +24968,7 @@ struct VdbeCursor { ** is linked into the Vdbe.pDelFrame list. The contents of the Vdbe.pDelFrame ** list is deleted when the VM is reset in VdbeHalt(). The reason for doing ** this instead of deleting the VdbeFrame immediately is to avoid recursive -** calls to tdsqlite3VdbeMemRelease() when the memory cells belonging to the +** calls to sqlite3VdbeMemRelease() when the memory cells belonging to the ** child frame are released. ** ** The currently executing frame is stored in Vdbe.pFrame. Vdbe.pFrame is @@ -25013,7 +25013,7 @@ struct VdbeFrame { ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. */ -struct tdsqlite3_value { +struct sqlite3_value { union MemValue { double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ @@ -25030,7 +25030,7 @@ struct tdsqlite3_value { char *zMalloc; /* Space to hold MEM_Str or MEM_Blob if szMalloc>0 */ int szMalloc; /* Size of the zMalloc allocation */ u32 uTemp; /* Transient storage for serial_type in OP_MakeRecord */ - tdsqlite3 *db; /* The associated database connection */ + sqlite3 *db; /* The associated database connection */ void (*xDel)(void*);/* Destructor for Mem.z - only valid if MEM_Dyn */ #ifdef SQLITE_DEBUG Mem *pScopyFrom; /* This Mem is a shallow copy of pScopyFrom */ @@ -25048,8 +25048,8 @@ struct tdsqlite3_value { ** representations of the value stored in the Mem struct. ** ** If the MEM_Null flag is set, then the value is an SQL NULL value. -** For a pointer type created using tdsqlite3_bind_pointer() or -** tdsqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. +** For a pointer type created using sqlite3_bind_pointer() or +** sqlite3_result_pointer() the MEM_Term and MEM_Subtype flags are also set. ** ** If the MEM_Str flag is set then Mem.z points at a string representation. ** Usually this is encoded in the same unicode encoding as the main @@ -25064,7 +25064,7 @@ struct tdsqlite3_value { #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_IntReal 0x0020 /* MEM_Int that stringifies like MEM_Real */ #define MEM_AffMask 0x003f /* Mask of affinity bits */ -#define MEM_FromBind 0x0040 /* Value originates from tdsqlite3_bind() */ +#define MEM_FromBind 0x0040 /* Value originates from sqlite3_bind() */ #define MEM_Undefined 0x0080 /* Value is undefined */ #define MEM_Cleared 0x0100 /* NULL set by OP_Null, not from data */ #define MEM_TypeMask 0xc1bf /* Mask of type bits */ @@ -25116,7 +25116,7 @@ struct tdsqlite3_value { /* ** Each auxiliary data pointer stored by a user defined function -** implementation calling tdsqlite3_set_auxdata() is stored in an instance +** implementation calling sqlite3_set_auxdata() is stored in an instance ** of this structure. All such structures associated with a single VM ** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed ** when the VM is halted (if not before). @@ -25142,7 +25142,7 @@ struct AuxData { ** This structure is defined inside of vdbeInt.h because it uses substructures ** (Mem) which are only defined there. */ -struct tdsqlite3_context { +struct sqlite3_context { Mem *pOut; /* The return value is stored here */ FuncDef *pFunc; /* Pointer to function information */ Mem *pMem; /* Memory cell used to store aggregate context */ @@ -25151,7 +25151,7 @@ struct tdsqlite3_context { int isError; /* Error code returned by the function. */ u8 skipFlag; /* Skip accumulator loading if true */ u8 argc; /* Number of arguments */ - tdsqlite3_value *argv[1]; /* Argument set */ + sqlite3_value *argv[1]; /* Argument set */ }; /* A bitfield type for use inside of structures. Always follow with :N where @@ -25160,7 +25160,7 @@ struct tdsqlite3_context { typedef unsigned bft; /* Bit Field Type */ /* The ScanStatus object holds a single value for the -** tdsqlite3_stmt_scanstatus() interface. +** sqlite3_stmt_scanstatus() interface. */ typedef struct ScanStatus ScanStatus; struct ScanStatus { @@ -25189,11 +25189,11 @@ struct DblquoteStr { ** An instance of the virtual machine. This structure contains the complete ** state of the virtual machine. ** -** The "tdsqlite3_stmt" structure pointer that is returned by tdsqlite3_prepare() +** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare() ** is really a pointer to an instance of this structure. */ struct Vdbe { - tdsqlite3 *db; /* The database connection that owns this statement */ + sqlite3 *db; /* The database connection that owns this statement */ Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ Parse *pParse; /* Parsing context used to create this Vdbe */ ynVar nVar; /* Number of entries in aVar[] */ @@ -25228,7 +25228,7 @@ struct Vdbe { i64 startTime; /* Time when query started - used for profiling */ #endif #ifdef SQLITE_DEBUG - int rcApp; /* errcode set by tdsqlite3_result_error_code() */ + int rcApp; /* errcode set by sqlite3_result_error_code() */ u32 nWrite; /* Number of write operations that have occurred */ #endif u16 nResColumn; /* Number of columns in one row of the result set */ @@ -25245,7 +25245,7 @@ struct Vdbe { bft bIsReader:1; /* True for statements that read */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ - u32 aCounter[7]; /* Counters used by tdsqlite3_stmt_status() */ + u32 aCounter[7]; /* Counters used by sqlite3_stmt_status() */ char *zSql; /* Text of the SQL statement that generated this */ #ifdef SQLITE_ENABLE_NORMALIZE char *zNormSql; /* Normalization of the associated SQL statement */ @@ -25261,7 +25261,7 @@ struct Vdbe { #ifdef SQLITE_ENABLE_STMT_SCANSTATUS i64 *anExec; /* Number of times each op has been executed */ int nScan; /* Entries in aScan[] */ - ScanStatus *aScan; /* Scan definitions for tdsqlite3_stmt_scanstatus() */ + ScanStatus *aScan; /* Scan definitions for sqlite3_stmt_scanstatus() */ #endif }; @@ -25276,7 +25276,7 @@ struct Vdbe { /* ** Structure used to store the context required by the -** tdsqlite3_preupdate_*() API functions. +** sqlite3_preupdate_*() API functions. */ struct PreUpdate { Vdbe *v; @@ -25297,134 +25297,134 @@ struct PreUpdate { /* ** Function prototypes */ -SQLITE_PRIVATE void tdsqlite3VdbeError(Vdbe*, const char *, ...); -SQLITE_PRIVATE void tdsqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); +SQLITE_PRIVATE void sqlite3VdbeError(Vdbe*, const char *, ...); +SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*); void sqliteVdbePopStack(Vdbe*,int); -SQLITE_PRIVATE int SQLITE_NOINLINE tdsqlite3VdbeFinishMoveto(VdbeCursor*); -SQLITE_PRIVATE int tdsqlite3VdbeCursorMoveto(VdbeCursor**, int*); -SQLITE_PRIVATE int tdsqlite3VdbeCursorRestore(VdbeCursor*); -SQLITE_PRIVATE u32 tdsqlite3VdbeSerialTypeLen(u32); -SQLITE_PRIVATE u8 tdsqlite3VdbeOneByteSerialTypeLen(u8); -SQLITE_PRIVATE u32 tdsqlite3VdbeSerialPut(unsigned char*, Mem*, u32); -SQLITE_PRIVATE u32 tdsqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); -SQLITE_PRIVATE void tdsqlite3VdbeDeleteAuxData(tdsqlite3*, AuxData**, int, int); +SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor*); +SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor**, int*); +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor*); +SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32); +SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8); +SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(unsigned char*, Mem*, u32); +SQLITE_PRIVATE u32 sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*); +SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3*, AuxData**, int, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); -SQLITE_PRIVATE int tdsqlite3VdbeIdxKeyCompare(tdsqlite3*,VdbeCursor*,UnpackedRecord*,int*); -SQLITE_PRIVATE int tdsqlite3VdbeIdxRowid(tdsqlite3*, BtCursor*, i64*); -SQLITE_PRIVATE int tdsqlite3VdbeExec(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(sqlite3*,VdbeCursor*,UnpackedRecord*,int*); +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor*, i64*); +SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); #ifndef SQLITE_OMIT_EXPLAIN -SQLITE_PRIVATE int tdsqlite3VdbeList(Vdbe*); -#endif -SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe*); -SQLITE_PRIVATE int tdsqlite3VdbeChangeEncoding(Mem *, int); -SQLITE_PRIVATE int tdsqlite3VdbeMemTooBig(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemCopy(Mem*, const Mem*); -SQLITE_PRIVATE void tdsqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); -SQLITE_PRIVATE void tdsqlite3VdbeMemMove(Mem*, Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemNulTerminate(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); -SQLITE_PRIVATE void tdsqlite3VdbeMemSetInt64(Mem*, i64); +SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); +#endif +SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe*); +SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *, int); +SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem*, const Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem*, const Mem*, int); +SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem*, Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemSetStr(Mem*, const char*, int, u8, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem*, i64); #ifdef SQLITE_OMIT_FLOATING_POINT -# define tdsqlite3VdbeMemSetDouble tdsqlite3VdbeMemSetInt64 +# define sqlite3VdbeMemSetDouble sqlite3VdbeMemSetInt64 #else -SQLITE_PRIVATE void tdsqlite3VdbeMemSetDouble(Mem*, double); +SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem*, double); #endif -SQLITE_PRIVATE void tdsqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*)); -SQLITE_PRIVATE void tdsqlite3VdbeMemInit(Mem*,tdsqlite3*,u16); -SQLITE_PRIVATE void tdsqlite3VdbeMemSetNull(Mem*); -SQLITE_PRIVATE void tdsqlite3VdbeMemSetZeroBlob(Mem*,int); +SQLITE_PRIVATE void sqlite3VdbeMemSetPointer(Mem*, void*, const char*, void(*)(void*)); +SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem*,sqlite3*,u16); +SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem*,int); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3VdbeMemIsRowSet(const Mem*); -#endif -SQLITE_PRIVATE int tdsqlite3VdbeMemSetRowSet(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemMakeWriteable(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemStringify(Mem*, u8, u8); -SQLITE_PRIVATE i64 tdsqlite3VdbeIntValue(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemIntegerify(Mem*); -SQLITE_PRIVATE double tdsqlite3VdbeRealValue(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeBooleanValue(Mem*, int ifNull); -SQLITE_PRIVATE void tdsqlite3VdbeIntegerAffinity(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemRealify(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemNumerify(Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeMemCast(Mem*,u8,u8); -SQLITE_PRIVATE int tdsqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); -SQLITE_PRIVATE void tdsqlite3VdbeMemRelease(Mem *p); -SQLITE_PRIVATE int tdsqlite3VdbeMemFinalize(Mem*, FuncDef*); +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem*); +#endif +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem*, u8, u8); +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem*); +SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem*); +SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem*, int ifNull); +SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem*); +SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem*,u8,u8); +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p); +SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem*, FuncDef*); #ifndef SQLITE_OMIT_WINDOWFUNC -SQLITE_PRIVATE int tdsqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); +SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem*, Mem*, FuncDef*); #endif #ifndef SQLITE_OMIT_EXPLAIN -SQLITE_PRIVATE const char *tdsqlite3OpcodeName(int); +SQLITE_PRIVATE const char *sqlite3OpcodeName(int); #endif -SQLITE_PRIVATE int tdsqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); -SQLITE_PRIVATE int tdsqlite3VdbeMemClearAndResize(Mem *pMem, int n); -SQLITE_PRIVATE int tdsqlite3VdbeCloseStatement(Vdbe *, int); +SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); +SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int n); +SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3VdbeFrameIsValid(VdbeFrame*); +SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame*); #endif -SQLITE_PRIVATE void tdsqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ -SQLITE_PRIVATE void tdsqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ -SQLITE_PRIVATE int tdsqlite3VdbeFrameRestore(VdbeFrame *); +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void*); /* Destructor on Mem */ +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); /* Actually deletes the Frame */ +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK -SQLITE_PRIVATE void tdsqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); +SQLITE_PRIVATE void sqlite3VdbePreUpdateHook(Vdbe*,VdbeCursor*,int,const char*,Table*,i64,int); #endif -SQLITE_PRIVATE int tdsqlite3VdbeTransferError(Vdbe *p); +SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p); -SQLITE_PRIVATE int tdsqlite3VdbeSorterInit(tdsqlite3 *, int, VdbeCursor *); -SQLITE_PRIVATE void tdsqlite3VdbeSorterReset(tdsqlite3 *, VdbeSorter *); -SQLITE_PRIVATE void tdsqlite3VdbeSorterClose(tdsqlite3 *, VdbeCursor *); -SQLITE_PRIVATE int tdsqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); -SQLITE_PRIVATE int tdsqlite3VdbeSorterNext(tdsqlite3 *, const VdbeCursor *); -SQLITE_PRIVATE int tdsqlite3VdbeSorterRewind(const VdbeCursor *, int *); -SQLITE_PRIVATE int tdsqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); -SQLITE_PRIVATE int tdsqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, int, VdbeCursor *); +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *, VdbeSorter *); +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *); +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *, int *); +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(const VdbeCursor *, Mem *); +SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int, int *); #ifdef SQLITE_DEBUG -SQLITE_PRIVATE void tdsqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); -SQLITE_PRIVATE void tdsqlite3VdbeAssertAbortable(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe*, VdbeCursor*); +SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe*); #else -# define tdsqlite3VdbeIncrWriteCounter(V,C) -# define tdsqlite3VdbeAssertAbortable(V) +# define sqlite3VdbeIncrWriteCounter(V,C) +# define sqlite3VdbeAssertAbortable(V) #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) -SQLITE_PRIVATE void tdsqlite3VdbeEnter(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); #else -# define tdsqlite3VdbeEnter(X) +# define sqlite3VdbeEnter(X) #endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 -SQLITE_PRIVATE void tdsqlite3VdbeLeave(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); #else -# define tdsqlite3VdbeLeave(X) +# define sqlite3VdbeLeave(X) #endif #ifdef SQLITE_DEBUG -SQLITE_PRIVATE void tdsqlite3VdbeMemAboutToChange(Vdbe*,Mem*); -SQLITE_PRIVATE int tdsqlite3VdbeCheckMemInvariants(Mem*); +SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe*,Mem*); +SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem*); #endif #ifndef SQLITE_OMIT_FOREIGN_KEY -SQLITE_PRIVATE int tdsqlite3VdbeCheckFk(Vdbe *, int); +SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int); #else -# define tdsqlite3VdbeCheckFk(p,i) 0 +# define sqlite3VdbeCheckFk(p,i) 0 #endif #ifdef SQLITE_DEBUG -SQLITE_PRIVATE void tdsqlite3VdbePrintSql(Vdbe*); -SQLITE_PRIVATE void tdsqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr); +SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe*); +SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr); #endif #ifndef SQLITE_OMIT_UTF16 -SQLITE_PRIVATE int tdsqlite3VdbeMemTranslate(Mem*, u8); -SQLITE_PRIVATE int tdsqlite3VdbeMemHandleBom(Mem *pMem); +SQLITE_PRIVATE int sqlite3VdbeMemTranslate(Mem*, u8); +SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem); #endif #ifndef SQLITE_OMIT_INCRBLOB -SQLITE_PRIVATE int tdsqlite3VdbeMemExpandBlob(Mem *); - #define ExpandBlob(P) (((P)->flags&MEM_Zero)?tdsqlite3VdbeMemExpandBlob(P):0) +SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *); + #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0) #else - #define tdsqlite3VdbeMemExpandBlob(x) SQLITE_OK + #define sqlite3VdbeMemExpandBlob(x) SQLITE_OK #define ExpandBlob(P) SQLITE_OK #endif @@ -25437,18 +25437,18 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemExpandBlob(Mem *); ** Variables in which to record status information. */ #if SQLITE_PTRSIZE>4 -typedef tdsqlite3_int64 tdsqlite3StatValueType; +typedef sqlite3_int64 sqlite3StatValueType; #else -typedef u32 tdsqlite3StatValueType; +typedef u32 sqlite3StatValueType; #endif -typedef struct tdsqlite3StatType tdsqlite3StatType; -static SQLITE_WSD struct tdsqlite3StatType { - tdsqlite3StatValueType nowValue[10]; /* Current value */ - tdsqlite3StatValueType mxValue[10]; /* Maximum value */ -} tdsqlite3Stat = { {0,}, {0,} }; +typedef struct sqlite3StatType sqlite3StatType; +static SQLITE_WSD struct sqlite3StatType { + sqlite3StatValueType nowValue[10]; /* Current value */ + sqlite3StatValueType mxValue[10]; /* Maximum value */ +} sqlite3Stat = { {0,}, {0,} }; /* -** Elements of tdsqlite3Stat[] are protected by either the memory allocator +** Elements of sqlite3Stat[] are protected by either the memory allocator ** mutex, or by the pcache1 mutex. The following array determines which. */ static const char statMutex[] = { @@ -25469,26 +25469,26 @@ static const char statMutex[] = { ** state vector. If writable static data is unsupported on the target, ** we have to locate the state vector at run-time. In the more common ** case where writable static data is supported, wsdStat can refer directly -** to the "tdsqlite3Stat" state vector declared above. +** to the "sqlite3Stat" state vector declared above. */ #ifdef SQLITE_OMIT_WSD -# define wsdStatInit tdsqlite3StatType *x = &GLOBAL(tdsqlite3StatType,tdsqlite3Stat) +# define wsdStatInit sqlite3StatType *x = &GLOBAL(sqlite3StatType,sqlite3Stat) # define wsdStat x[0] #else # define wsdStatInit -# define wsdStat tdsqlite3Stat +# define wsdStat sqlite3Stat #endif /* ** Return the current value of a status parameter. The caller must ** be holding the appropriate mutex. */ -SQLITE_PRIVATE tdsqlite3_int64 tdsqlite3StatusValue(int op){ +SQLITE_PRIVATE sqlite3_int64 sqlite3StatusValue(int op){ wsdStatInit; assert( op>=0 && op=0 && op=0 && op=0 && opwsdStat.mxValue[op] ){ wsdStat.mxValue[op] = wsdStat.nowValue[op]; } } -SQLITE_PRIVATE void tdsqlite3StatusDown(int op, int N){ +SQLITE_PRIVATE void sqlite3StatusDown(int op, int N){ wsdStatInit; assert( N>=0 ); assert( op>=0 && op=0 && op=0 ); - newValue = (tdsqlite3StatValueType)X; + newValue = (sqlite3StatValueType)X; assert( op>=0 && op=0 && op=ArraySize(wsdStat.nowValue) ){ return SQLITE_MISUSE_BKPT; @@ -25562,24 +25562,24 @@ SQLITE_API int tdsqlite3_status64( #ifdef SQLITE_ENABLE_API_ARMOR if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; #endif - pMutex = statMutex[op] ? tdsqlite3Pcache1Mutex() : tdsqlite3MallocMutex(); - tdsqlite3_mutex_enter(pMutex); + pMutex = statMutex[op] ? sqlite3Pcache1Mutex() : sqlite3MallocMutex(); + sqlite3_mutex_enter(pMutex); *pCurrent = wsdStat.nowValue[op]; *pHighwater = wsdStat.mxValue[op]; if( resetFlag ){ wsdStat.mxValue[op] = wsdStat.nowValue[op]; } - tdsqlite3_mutex_leave(pMutex); + sqlite3_mutex_leave(pMutex); (void)pMutex; /* Prevent warning when SQLITE_THREADSAFE=0 */ return SQLITE_OK; } -SQLITE_API int tdsqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ - tdsqlite3_int64 iCur = 0, iHwtr = 0; +SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){ + sqlite3_int64 iCur = 0, iHwtr = 0; int rc; #ifdef SQLITE_ENABLE_API_ARMOR if( pCurrent==0 || pHighwater==0 ) return SQLITE_MISUSE_BKPT; #endif - rc = tdsqlite3_status64(op, &iCur, &iHwtr, resetFlag); + rc = sqlite3_status64(op, &iCur, &iHwtr, resetFlag); if( rc==0 ){ *pCurrent = (int)iCur; *pHighwater = (int)iHwtr; @@ -25602,7 +25602,7 @@ static u32 countLookasideSlots(LookasideSlot *p){ /* ** Count the number of slots of lookaside memory that are outstanding */ -SQLITE_PRIVATE int tdsqlite3LookasideUsed(tdsqlite3 *db, int *pHighwater){ +SQLITE_PRIVATE int sqlite3LookasideUsed(sqlite3 *db, int *pHighwater){ u32 nInit = countLookasideSlots(db->lookaside.pInit); u32 nFree = countLookasideSlots(db->lookaside.pFree); #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE @@ -25616,8 +25616,8 @@ SQLITE_PRIVATE int tdsqlite3LookasideUsed(tdsqlite3 *db, int *pHighwater){ /* ** Query status information for a single database connection */ -SQLITE_API int tdsqlite3_db_status( - tdsqlite3 *db, /* The database connection whose status is desired */ +SQLITE_API int sqlite3_db_status( + sqlite3 *db, /* The database connection whose status is desired */ int op, /* Status verb */ int *pCurrent, /* Write current value here */ int *pHighwater, /* Write high-water mark here */ @@ -25625,14 +25625,14 @@ SQLITE_API int tdsqlite3_db_status( ){ int rc = SQLITE_OK; /* Return code */ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){ + if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwater==0 ){ return SQLITE_MISUSE_BKPT; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); switch( op ){ case SQLITE_DBSTATUS_LOOKASIDE_USED: { - *pCurrent = tdsqlite3LookasideUsed(db, pHighwater); + *pCurrent = sqlite3LookasideUsed(db, pHighwater); if( resetFlag ){ LookasideSlot *p = db->lookaside.pFree; if( p ){ @@ -25679,19 +25679,19 @@ SQLITE_API int tdsqlite3_db_status( case SQLITE_DBSTATUS_CACHE_USED: { int totalUsed = 0; int i; - tdsqlite3BtreeEnterAll(db); + sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ - Pager *pPager = tdsqlite3BtreePager(pBt); - int nByte = tdsqlite3PagerMemUsed(pPager); + Pager *pPager = sqlite3BtreePager(pBt); + int nByte = sqlite3PagerMemUsed(pPager); if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){ - nByte = nByte / tdsqlite3BtreeConnectionCount(pBt); + nByte = nByte / sqlite3BtreeConnectionCount(pBt); } totalUsed += nByte; } } - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); *pCurrent = totalUsed; *pHighwater = 0; break; @@ -25706,34 +25706,34 @@ SQLITE_API int tdsqlite3_db_status( int i; /* Used to iterate through schemas */ int nByte = 0; /* Used to accumulate return value */ - tdsqlite3BtreeEnterAll(db); + sqlite3BtreeEnterAll(db); db->pnBytesFreed = &nByte; for(i=0; inDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( ALWAYS(pSchema!=0) ){ HashElem *p; - nByte += tdsqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( + nByte += sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( pSchema->tblHash.count + pSchema->trigHash.count + pSchema->idxHash.count + pSchema->fkeyHash.count ); - nByte += tdsqlite3_msize(pSchema->tblHash.ht); - nByte += tdsqlite3_msize(pSchema->trigHash.ht); - nByte += tdsqlite3_msize(pSchema->idxHash.ht); - nByte += tdsqlite3_msize(pSchema->fkeyHash.ht); + nByte += sqlite3_msize(pSchema->tblHash.ht); + nByte += sqlite3_msize(pSchema->trigHash.ht); + nByte += sqlite3_msize(pSchema->idxHash.ht); + nByte += sqlite3_msize(pSchema->fkeyHash.ht); for(p=sqliteHashFirst(&pSchema->trigHash); p; p=sqliteHashNext(p)){ - tdsqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); + sqlite3DeleteTrigger(db, (Trigger*)sqliteHashData(p)); } for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ - tdsqlite3DeleteTable(db, (Table *)sqliteHashData(p)); + sqlite3DeleteTable(db, (Table *)sqliteHashData(p)); } } } db->pnBytesFreed = 0; - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); *pHighwater = 0; *pCurrent = nByte; @@ -25751,8 +25751,8 @@ SQLITE_API int tdsqlite3_db_status( db->pnBytesFreed = &nByte; for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pNext){ - tdsqlite3VdbeClearObject(db, pVdbe); - tdsqlite3DbFree(db, pVdbe); + sqlite3VdbeClearObject(db, pVdbe); + sqlite3DbFree(db, pVdbe); } db->pnBytesFreed = 0; @@ -25780,8 +25780,8 @@ SQLITE_API int tdsqlite3_db_status( for(i=0; inDb; i++){ if( db->aDb[i].pBt ){ - Pager *pPager = tdsqlite3BtreePager(db->aDb[i].pBt); - tdsqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); + Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt); + sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet); } } *pHighwater = 0; /* IMP: R-42420-56072 */ @@ -25805,7 +25805,7 @@ SQLITE_API int tdsqlite3_db_status( rc = SQLITE_ERROR; } } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -25826,7 +25826,7 @@ SQLITE_API int tdsqlite3_db_status( ** functions for SQLite. ** ** There is only one exported symbol in this file - the function -** tdsqlite3RegisterDateTimeFunctions() found at the bottom of the file. +** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** ** SQLite processes all times and dates as julian day numbers. The @@ -25878,7 +25878,7 @@ struct tm *__cdecl localtime(const time_t *); */ typedef struct DateTime DateTime; struct DateTime { - tdsqlite3_int64 iJD; /* The julian day number times 86400000 */ + sqlite3_int64 iJD; /* The julian day number times 86400000 */ int Y, M, D; /* Year, month, and day */ int h, m; /* Hour and minutes */ int tz; /* Timezone offset in minutes */ @@ -25939,7 +25939,7 @@ static int getDigits(const char *zDate, const char *zFormat, ...){ nextC = zFormat[3]; val = 0; while( N-- ){ - if( !tdsqlite3Isdigit(*zDate) ){ + if( !sqlite3Isdigit(*zDate) ){ goto end_getDigits; } val = val*10 + *zDate - '0'; @@ -25978,7 +25978,7 @@ static int parseTimezone(const char *zDate, DateTime *p){ int sgn = 0; int nHr, nMn; int c; - while( tdsqlite3Isspace(*zDate) ){ zDate++; } + while( sqlite3Isspace(*zDate) ){ zDate++; } p->tz = 0; c = *zDate; if( c=='-' ){ @@ -25998,7 +25998,7 @@ static int parseTimezone(const char *zDate, DateTime *p){ zDate += 5; p->tz = sgn*(nMn + nHr*60); zulu_time: - while( tdsqlite3Isspace(*zDate) ){ zDate++; } + while( sqlite3Isspace(*zDate) ){ zDate++; } p->tzSet = 1; return *zDate!=0; } @@ -26023,10 +26023,10 @@ static int parseHhMmSs(const char *zDate, DateTime *p){ return 1; } zDate += 2; - if( *zDate=='.' && tdsqlite3Isdigit(zDate[1]) ){ + if( *zDate=='.' && sqlite3Isdigit(zDate[1]) ){ double rScale = 1.0; zDate++; - while( tdsqlite3Isdigit(*zDate) ){ + while( sqlite3Isdigit(*zDate) ){ ms = ms*10.0 + *zDate - '0'; rScale *= 10.0; zDate++; @@ -26086,10 +26086,10 @@ static void computeJD(DateTime *p){ B = 2 - A + (A/4); X1 = 36525*(Y+4716)/100; X2 = 306001*(M+1)/10000; - p->iJD = (tdsqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); + p->iJD = (sqlite3_int64)((X1 + X2 + D + B - 1524.5 ) * 86400000); p->validJD = 1; if( p->validHMS ){ - p->iJD += p->h*3600000 + p->m*60000 + (tdsqlite3_int64)(p->s*1000); + p->iJD += p->h*3600000 + p->m*60000 + (sqlite3_int64)(p->s*1000); if( p->validTZ ){ p->iJD -= p->tz*60000; p->validYMD = 0; @@ -26124,7 +26124,7 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ return 1; } zDate += 10; - while( tdsqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; } + while( sqlite3Isspace(*zDate) || 'T'==*(u8*)zDate ){ zDate++; } if( parseHhMmSs(zDate, p)==0 ){ /* We got the time */ }else if( *zDate==0 ){ @@ -26148,8 +26148,8 @@ static int parseYyyyMmDd(const char *zDate, DateTime *p){ ** ** Return the number of errors. */ -static int setDateTimeToCurrent(tdsqlite3_context *context, DateTime *p){ - p->iJD = tdsqlite3StmtCurrentTime(context); +static int setDateTimeToCurrent(sqlite3_context *context, DateTime *p){ + p->iJD = sqlite3StmtCurrentTime(context); if( p->iJD>0 ){ p->validJD = 1; return 0; @@ -26168,7 +26168,7 @@ static void setRawDateNumber(DateTime *p, double r){ p->s = r; p->rawS = 1; if( r>=0.0 && r<5373484.5 ){ - p->iJD = (tdsqlite3_int64)(r*86400000.0 + 0.5); + p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5); p->validJD = 1; } } @@ -26190,7 +26190,7 @@ static void setRawDateNumber(DateTime *p, double r){ ** as there is a year and date. */ static int parseDateOrTime( - tdsqlite3_context *context, + sqlite3_context *context, const char *zDate, DateTime *p ){ @@ -26199,9 +26199,9 @@ static int parseDateOrTime( return 0; }else if( parseHhMmSs(zDate, p)==0 ){ return 0; - }else if( tdsqlite3StrICmp(zDate,"now")==0 && tdsqlite3NotPureFunc(context) ){ + }else if( sqlite3StrICmp(zDate,"now")==0 && sqlite3NotPureFunc(context) ){ return setDateTimeToCurrent(context, p); - }else if( tdsqlite3AtoF(zDate, &r, tdsqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ + }else if( sqlite3AtoF(zDate, &r, sqlite3Strlen30(zDate), SQLITE_UTF8)>0 ){ setRawDateNumber(p, r); return 0; } @@ -26222,7 +26222,7 @@ static int parseDateOrTime( ** ** The input is the JulianDay times 86400000. */ -static int validJulianDay(tdsqlite3_int64 iJD){ +static int validJulianDay(sqlite3_int64 iJD){ return iJD>=0 && iJD<=INT_464269060799999; } @@ -26316,7 +26316,7 @@ static void clearYMD_HMS_TZ(DateTime *p){ ** is available. This routine returns 0 on success and ** non-zero on any kind of error. ** -** If the tdsqlite3GlobalConfig.bLocaltimeFault variable is true then this +** If the sqlite3GlobalConfig.bLocaltimeFault variable is true then this ** routine will always fail. ** ** EVIDENCE-OF: R-62172-00036 In this implementation, the standard C @@ -26328,19 +26328,19 @@ static int osLocaltime(time_t *t, struct tm *pTm){ #if !HAVE_LOCALTIME_R && !HAVE_LOCALTIME_S struct tm *pX; #if SQLITE_THREADSAFE>0 - tdsqlite3_mutex *mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif - tdsqlite3_mutex_enter(mutex); + sqlite3_mutex_enter(mutex); pX = localtime(t); #ifndef SQLITE_UNTESTABLE - if( tdsqlite3GlobalConfig.bLocaltimeFault ) pX = 0; + if( sqlite3GlobalConfig.bLocaltimeFault ) pX = 0; #endif if( pX ) *pTm = *pX; - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); rc = pX==0; #else #ifndef SQLITE_UNTESTABLE - if( tdsqlite3GlobalConfig.bLocaltimeFault ) return 1; + if( sqlite3GlobalConfig.bLocaltimeFault ) return 1; #endif #if HAVE_LOCALTIME_R rc = localtime_r(t, pTm)==0; @@ -26362,9 +26362,9 @@ static int osLocaltime(time_t *t, struct tm *pTm){ ** Or, if an error does occur, set *pRc to SQLITE_ERROR. The returned value ** is undefined in this case. */ -static tdsqlite3_int64 localtimeOffset( +static sqlite3_int64 localtimeOffset( DateTime *p, /* Date at which to calculate offset */ - tdsqlite3_context *pCtx, /* Write error here if one occurs */ + sqlite3_context *pCtx, /* Write error here if one occurs */ int *pRc /* OUT: Error code. SQLITE_OK or ERROR */ ){ DateTime x, y; @@ -26397,7 +26397,7 @@ static tdsqlite3_int64 localtimeOffset( computeJD(&x); t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); if( osLocaltime(&t, &sLocal) ){ - tdsqlite3_result_error(pCtx, "local time unavailable", -1); + sqlite3_result_error(pCtx, "local time unavailable", -1); *pRc = SQLITE_ERROR; return 0; } @@ -26467,14 +26467,14 @@ static const struct { ** written to pCtx. */ static int parseModifier( - tdsqlite3_context *pCtx, /* Function context */ + sqlite3_context *pCtx, /* Function context */ const char *z, /* The text of the modifier */ int n, /* Length of zMod in bytes */ DateTime *p /* The date/time value to be modified */ ){ int rc = 1; double r; - switch(tdsqlite3UpperToLower[(u8)z[0]] ){ + switch(sqlite3UpperToLower[(u8)z[0]] ){ #ifndef SQLITE_OMIT_LOCALTIME case 'l': { /* localtime @@ -26482,7 +26482,7 @@ static int parseModifier( ** Assuming the current time value is UTC (a.k.a. GMT), shift it to ** show local time. */ - if( tdsqlite3_stricmp(z, "localtime")==0 && tdsqlite3NotPureFunc(pCtx) ){ + if( sqlite3_stricmp(z, "localtime")==0 && sqlite3NotPureFunc(pCtx) ){ computeJD(p); p->iJD += localtimeOffset(p, pCtx, &rc); clearYMD_HMS_TZ(p); @@ -26497,20 +26497,20 @@ static int parseModifier( ** Treat the current value of p->s as the number of ** seconds since 1970. Convert to a real julian day number. */ - if( tdsqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){ + if( sqlite3_stricmp(z, "unixepoch")==0 && p->rawS ){ r = p->s*1000.0 + 210866760000000.0; if( r>=0.0 && r<464269060800000.0 ){ clearYMD_HMS_TZ(p); - p->iJD = (tdsqlite3_int64)(r + 0.5); + p->iJD = (sqlite3_int64)(r + 0.5); p->validJD = 1; p->rawS = 0; rc = 0; } } #ifndef SQLITE_OMIT_LOCALTIME - else if( tdsqlite3_stricmp(z, "utc")==0 && tdsqlite3NotPureFunc(pCtx) ){ + else if( sqlite3_stricmp(z, "utc")==0 && sqlite3NotPureFunc(pCtx) ){ if( p->tzSet==0 ){ - tdsqlite3_int64 c1; + sqlite3_int64 c1; computeJD(p); c1 = localtimeOffset(p, pCtx, &rc); if( rc==SQLITE_OK ){ @@ -26534,10 +26534,10 @@ static int parseModifier( ** weekday N where 0==Sunday, 1==Monday, and so forth. If the ** date is already on the appropriate weekday, this is a no-op. */ - if( tdsqlite3_strnicmp(z, "weekday ", 8)==0 - && tdsqlite3AtoF(&z[8], &r, tdsqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 + if( sqlite3_strnicmp(z, "weekday ", 8)==0 + && sqlite3AtoF(&z[8], &r, sqlite3Strlen30(&z[8]), SQLITE_UTF8)>0 && (n=(int)r)==r && n>=0 && r<7 ){ - tdsqlite3_int64 Z; + sqlite3_int64 Z; computeYMD_HMS(p); p->validTZ = 0; p->validJD = 0; @@ -26557,7 +26557,7 @@ static int parseModifier( ** Move the date backwards to the beginning of the current day, ** or month or year. */ - if( tdsqlite3_strnicmp(z, "start of ", 9)!=0 ) break; + if( sqlite3_strnicmp(z, "start of ", 9)!=0 ) break; if( !p->validJD && !p->validYMD && !p->validHMS ) break; z += 9; computeYMD(p); @@ -26567,14 +26567,14 @@ static int parseModifier( p->rawS = 0; p->validTZ = 0; p->validJD = 0; - if( tdsqlite3_stricmp(z,"month")==0 ){ + if( sqlite3_stricmp(z,"month")==0 ){ p->D = 1; rc = 0; - }else if( tdsqlite3_stricmp(z,"year")==0 ){ + }else if( sqlite3_stricmp(z,"year")==0 ){ p->M = 1; p->D = 1; rc = 0; - }else if( tdsqlite3_stricmp(z,"day")==0 ){ + }else if( sqlite3_stricmp(z,"day")==0 ){ rc = 0; } break; @@ -26593,8 +26593,8 @@ static int parseModifier( case '9': { double rRounder; int i; - for(n=1; z[n] && z[n]!=':' && !tdsqlite3Isspace(z[n]); n++){} - if( tdsqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ + for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} + if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ rc = 1; break; } @@ -26606,8 +26606,8 @@ static int parseModifier( */ const char *z2 = z; DateTime tx; - tdsqlite3_int64 day; - if( !tdsqlite3Isdigit(*z2) ) z2++; + sqlite3_int64 day; + if( !sqlite3Isdigit(*z2) ) z2++; memset(&tx, 0, sizeof(tx)); if( parseHhMmSs(z2, &tx) ) break; computeJD(&tx); @@ -26625,16 +26625,16 @@ static int parseModifier( /* If control reaches this point, it means the transformation is ** one of the forms like "+NNN days". */ z += n; - while( tdsqlite3Isspace(*z) ) z++; - n = tdsqlite3Strlen30(z); + while( sqlite3Isspace(*z) ) z++; + n = sqlite3Strlen30(z); if( n>10 || n<3 ) break; - if( tdsqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; + if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; computeJD(p); rc = 1; rRounder = r<0 ? -0.5 : +0.5; for(i=0; i-aXformType[i].rLimit && riJD += (tdsqlite3_int64)(r*aXformType[i].rXform + rRounder); + p->iJD += (sqlite3_int64)(r*aXformType[i].rXform + rRounder); rc = 0; break; } @@ -26684,9 +26684,9 @@ static int parseModifier( ** then assume a default value of "now" for argv[0]. */ static int isDate( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv, + sqlite3_value **argv, DateTime *p ){ int i, n; @@ -26696,18 +26696,18 @@ static int isDate( if( argc==0 ){ return setDateTimeToCurrent(context, p); } - if( (eType = tdsqlite3_value_type(argv[0]))==SQLITE_FLOAT + if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT || eType==SQLITE_INTEGER ){ - setRawDateNumber(p, tdsqlite3_value_double(argv[0])); + setRawDateNumber(p, sqlite3_value_double(argv[0])); }else{ - z = tdsqlite3_value_text(argv[0]); + z = sqlite3_value_text(argv[0]); if( !z || parseDateOrTime(context, (char*)z, p) ){ return 1; } } for(i=1; i(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){ - tdsqlite3_result_error_toobig(context); + sqlite3_result_error_toobig(context); return; }else{ - z = tdsqlite3DbMallocRawNN(db, (int)n); + z = sqlite3DbMallocRawNN(db, (int)n); if( z==0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); return; } } @@ -26888,15 +26888,15 @@ static void strftimeFunc( }else{ i++; switch( zFmt[i] ){ - case 'd': tdsqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break; + case 'd': sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break; case 'f': { double s = x.s; if( s>59.999 ) s = 59.999; - tdsqlite3_snprintf(7, &z[j],"%06.3f", s); - j += tdsqlite3Strlen30(&z[j]); + sqlite3_snprintf(7, &z[j],"%06.3f", s); + j += sqlite3Strlen30(&z[j]); break; } - case 'H': tdsqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break; + case 'H': sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break; case 'W': /* Fall thru */ case 'j': { int nDay; /* Number of days since 1st day of year */ @@ -26909,34 +26909,34 @@ static void strftimeFunc( if( zFmt[i]=='W' ){ int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ wd = (int)(((x.iJD+43200000)/86400000)%7); - tdsqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7); + sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7); j += 2; }else{ - tdsqlite3_snprintf(4, &z[j],"%03d",nDay+1); + sqlite3_snprintf(4, &z[j],"%03d",nDay+1); j += 3; } break; } case 'J': { - tdsqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0); - j+=tdsqlite3Strlen30(&z[j]); + sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0); + j+=sqlite3Strlen30(&z[j]); break; } - case 'm': tdsqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break; - case 'M': tdsqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break; + case 'm': sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break; + case 'M': sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break; case 's': { - tdsqlite3_snprintf(30,&z[j],"%lld", + sqlite3_snprintf(30,&z[j],"%lld", (i64)(x.iJD/1000 - 21086676*(i64)10000)); - j += tdsqlite3Strlen30(&z[j]); + j += sqlite3Strlen30(&z[j]); break; } - case 'S': tdsqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break; + case 'S': sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break; case 'w': { z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; break; } case 'Y': { - tdsqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=tdsqlite3Strlen30(&z[j]); + sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]); break; } default: z[j++] = '%'; break; @@ -26944,7 +26944,7 @@ static void strftimeFunc( } } z[j] = 0; - tdsqlite3_result_text(context, z, -1, + sqlite3_result_text(context, z, -1, z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC); } @@ -26954,9 +26954,9 @@ static void strftimeFunc( ** This function returns the same value as time('now'). */ static void ctimeFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **NotUsed2 + sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); timeFunc(context, 0, 0); @@ -26968,9 +26968,9 @@ static void ctimeFunc( ** This function returns the same value as date('now'). */ static void cdateFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **NotUsed2 + sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); dateFunc(context, 0, 0); @@ -26982,9 +26982,9 @@ static void cdateFunc( ** This function returns the same value as datetime('now'). */ static void ctimestampFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **NotUsed2 + sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); datetimeFunc(context, 0, 0); @@ -27004,13 +27004,13 @@ static void ctimestampFunc( ** as the user-data for the function. */ static void currentTimeFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ time_t t; - char *zFormat = (char *)tdsqlite3_user_data(context); - tdsqlite3_int64 iT; + char *zFormat = (char *)sqlite3_user_data(context); + sqlite3_int64 iT; struct tm *pTm; struct tm sNow; char zBuf[20]; @@ -27018,20 +27018,20 @@ static void currentTimeFunc( UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); - iT = tdsqlite3StmtCurrentTime(context); + iT = sqlite3StmtCurrentTime(context); if( iT<=0 ) return; - t = iT/1000 - 10000*(tdsqlite3_int64)21086676; + t = iT/1000 - 10000*(sqlite3_int64)21086676; #if HAVE_GMTIME_R pTm = gmtime_r(&t, &sNow); #else - tdsqlite3_mutex_enter(tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); pTm = gmtime(&t); if( pTm ) memcpy(&sNow, pTm, sizeof(sNow)); - tdsqlite3_mutex_leave(tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); #endif if( pTm ){ strftime(zBuf, 20, zFormat, &sNow); - tdsqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); } } #endif @@ -27041,7 +27041,7 @@ static void currentTimeFunc( ** functions. This should be the only routine in this file with ** external linkage. */ -SQLITE_PRIVATE void tdsqlite3RegisterDateTimeFunctions(void){ +SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ static FuncDef aDateTimeFuncs[] = { #ifndef SQLITE_OMIT_DATETIME_FUNCS PURE_DATE(julianday, -1, 0, 0, juliandayFunc ), @@ -27058,7 +27058,7 @@ SQLITE_PRIVATE void tdsqlite3RegisterDateTimeFunctions(void){ STR_FUNCTION(current_timestamp, 0, "%Y-%m-%d %H:%M:%S", 0, currentTimeFunc), #endif }; - tdsqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs)); + sqlite3InsertBuiltinFuncs(aDateTimeFuncs, ArraySize(aDateTimeFuncs)); } /************** End of date.c ************************************************/ @@ -27086,53 +27086,53 @@ SQLITE_PRIVATE void tdsqlite3RegisterDateTimeFunctions(void){ ** is used for testing the I/O recovery logic. */ #if defined(SQLITE_TEST) -SQLITE_API int tdsqlite3_io_error_hit = 0; /* Total number of I/O Errors */ -SQLITE_API int tdsqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ -SQLITE_API int tdsqlite3_io_error_pending = 0; /* Count down to first I/O error */ -SQLITE_API int tdsqlite3_io_error_persist = 0; /* True if I/O errors persist */ -SQLITE_API int tdsqlite3_io_error_benign = 0; /* True if errors are benign */ -SQLITE_API int tdsqlite3_diskfull_pending = 0; -SQLITE_API int tdsqlite3_diskfull = 0; +SQLITE_API int sqlite3_io_error_hit = 0; /* Total number of I/O Errors */ +SQLITE_API int sqlite3_io_error_hardhit = 0; /* Number of non-benign errors */ +SQLITE_API int sqlite3_io_error_pending = 0; /* Count down to first I/O error */ +SQLITE_API int sqlite3_io_error_persist = 0; /* True if I/O errors persist */ +SQLITE_API int sqlite3_io_error_benign = 0; /* True if errors are benign */ +SQLITE_API int sqlite3_diskfull_pending = 0; +SQLITE_API int sqlite3_diskfull = 0; #endif /* defined(SQLITE_TEST) */ /* ** When testing, also keep a count of the number of open files. */ #if defined(SQLITE_TEST) -SQLITE_API int tdsqlite3_open_file_count = 0; +SQLITE_API int sqlite3_open_file_count = 0; #endif /* defined(SQLITE_TEST) */ /* -** The default SQLite tdsqlite3_vfs implementations do not allocate +** The default SQLite sqlite3_vfs implementations do not allocate ** memory (actually, os_unix.c allocates a small amount of memory ** from within OsOpen()), but some third-party implementations may. -** So we test the effects of a malloc() failing and the tdsqlite3OsXXX() +** So we test the effects of a malloc() failing and the sqlite3OsXXX() ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro. ** ** The following functions are instrumented for malloc() failure ** testing: ** -** tdsqlite3OsRead() -** tdsqlite3OsWrite() -** tdsqlite3OsSync() -** tdsqlite3OsFileSize() -** tdsqlite3OsLock() -** tdsqlite3OsCheckReservedLock() -** tdsqlite3OsFileControl() -** tdsqlite3OsShmMap() -** tdsqlite3OsOpen() -** tdsqlite3OsDelete() -** tdsqlite3OsAccess() -** tdsqlite3OsFullPathname() +** sqlite3OsRead() +** sqlite3OsWrite() +** sqlite3OsSync() +** sqlite3OsFileSize() +** sqlite3OsLock() +** sqlite3OsCheckReservedLock() +** sqlite3OsFileControl() +** sqlite3OsShmMap() +** sqlite3OsOpen() +** sqlite3OsDelete() +** sqlite3OsAccess() +** sqlite3OsFullPathname() ** */ #if defined(SQLITE_TEST) -SQLITE_API int tdsqlite3_memdebug_vfs_oom_test = 1; +SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1; #define DO_OS_MALLOC_TEST(x) \ - if (tdsqlite3_memdebug_vfs_oom_test && (!x || !tdsqlite3JournalIsInMemory(x))) { \ - void *pTstAlloc = tdsqlite3Malloc(10); \ + if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \ + void *pTstAlloc = sqlite3Malloc(10); \ if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT; \ - tdsqlite3_free(pTstAlloc); \ + sqlite3_free(pTstAlloc); \ } #else #define DO_OS_MALLOC_TEST(x) @@ -27140,56 +27140,56 @@ SQLITE_API int tdsqlite3_memdebug_vfs_oom_test = 1; /* ** The following routines are convenience wrappers around methods -** of the tdsqlite3_file object. This is mostly just syntactic sugar. All +** of the sqlite3_file object. This is mostly just syntactic sugar. All ** of this would be completely automatic if SQLite were coded using ** C++ instead of plain old C. */ -SQLITE_PRIVATE void tdsqlite3OsClose(tdsqlite3_file *pId){ +SQLITE_PRIVATE void sqlite3OsClose(sqlite3_file *pId){ if( pId->pMethods ){ pId->pMethods->xClose(pId); pId->pMethods = 0; } } -SQLITE_PRIVATE int tdsqlite3OsRead(tdsqlite3_file *id, void *pBuf, int amt, i64 offset){ +SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ DO_OS_MALLOC_TEST(id); return id->pMethods->xRead(id, pBuf, amt, offset); } -SQLITE_PRIVATE int tdsqlite3OsWrite(tdsqlite3_file *id, const void *pBuf, int amt, i64 offset){ +SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ DO_OS_MALLOC_TEST(id); return id->pMethods->xWrite(id, pBuf, amt, offset); } -SQLITE_PRIVATE int tdsqlite3OsTruncate(tdsqlite3_file *id, i64 size){ +SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){ return id->pMethods->xTruncate(id, size); } -SQLITE_PRIVATE int tdsqlite3OsSync(tdsqlite3_file *id, int flags){ +SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){ DO_OS_MALLOC_TEST(id); return flags ? id->pMethods->xSync(id, flags) : SQLITE_OK; } -SQLITE_PRIVATE int tdsqlite3OsFileSize(tdsqlite3_file *id, i64 *pSize){ +SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ DO_OS_MALLOC_TEST(id); return id->pMethods->xFileSize(id, pSize); } -SQLITE_PRIVATE int tdsqlite3OsLock(tdsqlite3_file *id, int lockType){ +SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ DO_OS_MALLOC_TEST(id); return id->pMethods->xLock(id, lockType); } -SQLITE_PRIVATE int tdsqlite3OsUnlock(tdsqlite3_file *id, int lockType){ +SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ return id->pMethods->xUnlock(id, lockType); } -SQLITE_PRIVATE int tdsqlite3OsCheckReservedLock(tdsqlite3_file *id, int *pResOut){ +SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ DO_OS_MALLOC_TEST(id); return id->pMethods->xCheckReservedLock(id, pResOut); } /* -** Use tdsqlite3OsFileControl() when we are doing something that might fail -** and we need to know about the failures. Use tdsqlite3OsFileControlHint() +** Use sqlite3OsFileControl() when we are doing something that might fail +** and we need to know about the failures. Use sqlite3OsFileControlHint() ** when simply tossing information over the wall to the VFS and we do not ** really care if the VFS receives and understands the information since it -** is only a hint and can be safely ignored. The tdsqlite3OsFileControlHint() +** is only a hint and can be safely ignored. The sqlite3OsFileControlHint() ** routine has no return value since the return value would be meaningless. */ -SQLITE_PRIVATE int tdsqlite3OsFileControl(tdsqlite3_file *id, int op, void *pArg){ +SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ if( id->pMethods==0 ) return SQLITE_NOTFOUND; #ifdef SQLITE_TEST if( op!=SQLITE_FCNTL_COMMIT_PHASETWO @@ -27210,29 +27210,29 @@ SQLITE_PRIVATE int tdsqlite3OsFileControl(tdsqlite3_file *id, int op, void *pArg #endif return id->pMethods->xFileControl(id, op, pArg); } -SQLITE_PRIVATE void tdsqlite3OsFileControlHint(tdsqlite3_file *id, int op, void *pArg){ +SQLITE_PRIVATE void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){ if( id->pMethods ) (void)id->pMethods->xFileControl(id, op, pArg); } -SQLITE_PRIVATE int tdsqlite3OsSectorSize(tdsqlite3_file *id){ - int (*xSectorSize)(tdsqlite3_file*) = id->pMethods->xSectorSize; +SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){ + int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize; return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE); } -SQLITE_PRIVATE int tdsqlite3OsDeviceCharacteristics(tdsqlite3_file *id){ +SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id){ return id->pMethods->xDeviceCharacteristics(id); } #ifndef SQLITE_OMIT_WAL -SQLITE_PRIVATE int tdsqlite3OsShmLock(tdsqlite3_file *id, int offset, int n, int flags){ +SQLITE_PRIVATE int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){ return id->pMethods->xShmLock(id, offset, n, flags); } -SQLITE_PRIVATE void tdsqlite3OsShmBarrier(tdsqlite3_file *id){ +SQLITE_PRIVATE void sqlite3OsShmBarrier(sqlite3_file *id){ id->pMethods->xShmBarrier(id); } -SQLITE_PRIVATE int tdsqlite3OsShmUnmap(tdsqlite3_file *id, int deleteFlag){ +SQLITE_PRIVATE int sqlite3OsShmUnmap(sqlite3_file *id, int deleteFlag){ return id->pMethods->xShmUnmap(id, deleteFlag); } -SQLITE_PRIVATE int tdsqlite3OsShmMap( - tdsqlite3_file *id, /* Database file handle */ +SQLITE_PRIVATE int sqlite3OsShmMap( + sqlite3_file *id, /* Database file handle */ int iPage, int pgsz, int bExtend, /* True to extend file if necessary */ @@ -27245,20 +27245,20 @@ SQLITE_PRIVATE int tdsqlite3OsShmMap( #if SQLITE_MAX_MMAP_SIZE>0 /* The real implementation of xFetch and xUnfetch */ -SQLITE_PRIVATE int tdsqlite3OsFetch(tdsqlite3_file *id, i64 iOff, int iAmt, void **pp){ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ DO_OS_MALLOC_TEST(id); return id->pMethods->xFetch(id, iOff, iAmt, pp); } -SQLITE_PRIVATE int tdsqlite3OsUnfetch(tdsqlite3_file *id, i64 iOff, void *p){ +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ return id->pMethods->xUnfetch(id, iOff, p); } #else /* No-op stubs to use when memory-mapped I/O is disabled */ -SQLITE_PRIVATE int tdsqlite3OsFetch(tdsqlite3_file *id, i64 iOff, int iAmt, void **pp){ +SQLITE_PRIVATE int sqlite3OsFetch(sqlite3_file *id, i64 iOff, int iAmt, void **pp){ *pp = 0; return SQLITE_OK; } -SQLITE_PRIVATE int tdsqlite3OsUnfetch(tdsqlite3_file *id, i64 iOff, void *p){ +SQLITE_PRIVATE int sqlite3OsUnfetch(sqlite3_file *id, i64 iOff, void *p){ return SQLITE_OK; } #endif @@ -27267,10 +27267,10 @@ SQLITE_PRIVATE int tdsqlite3OsUnfetch(tdsqlite3_file *id, i64 iOff, void *p){ ** The next group of routines are convenience wrappers around the ** VFS methods. */ -SQLITE_PRIVATE int tdsqlite3OsOpen( - tdsqlite3_vfs *pVfs, +SQLITE_PRIVATE int sqlite3OsOpen( + sqlite3_vfs *pVfs, const char *zPath, - tdsqlite3_file *pFile, + sqlite3_file *pFile, int flags, int *pFlagsOut ){ @@ -27284,13 +27284,13 @@ SQLITE_PRIVATE int tdsqlite3OsOpen( assert( rc==SQLITE_OK || pFile->pMethods==0 ); return rc; } -SQLITE_PRIVATE int tdsqlite3OsDelete(tdsqlite3_vfs *pVfs, const char *zPath, int dirSync){ +SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ DO_OS_MALLOC_TEST(0); assert( dirSync==0 || dirSync==1 ); return pVfs->xDelete(pVfs, zPath, dirSync); } -SQLITE_PRIVATE int tdsqlite3OsAccess( - tdsqlite3_vfs *pVfs, +SQLITE_PRIVATE int sqlite3OsAccess( + sqlite3_vfs *pVfs, const char *zPath, int flags, int *pResOut @@ -27298,8 +27298,8 @@ SQLITE_PRIVATE int tdsqlite3OsAccess( DO_OS_MALLOC_TEST(0); return pVfs->xAccess(pVfs, zPath, flags, pResOut); } -SQLITE_PRIVATE int tdsqlite3OsFullPathname( - tdsqlite3_vfs *pVfs, +SQLITE_PRIVATE int sqlite3OsFullPathname( + sqlite3_vfs *pVfs, const char *zPath, int nPathOut, char *zPathOut @@ -27309,37 +27309,37 @@ SQLITE_PRIVATE int tdsqlite3OsFullPathname( return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); } #ifndef SQLITE_OMIT_LOAD_EXTENSION -SQLITE_PRIVATE void *tdsqlite3OsDlOpen(tdsqlite3_vfs *pVfs, const char *zPath){ +SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ return pVfs->xDlOpen(pVfs, zPath); } -SQLITE_PRIVATE void tdsqlite3OsDlError(tdsqlite3_vfs *pVfs, int nByte, char *zBufOut){ +SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ pVfs->xDlError(pVfs, nByte, zBufOut); } -SQLITE_PRIVATE void (*tdsqlite3OsDlSym(tdsqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ +SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *pVfs, void *pHdle, const char *zSym))(void){ return pVfs->xDlSym(pVfs, pHdle, zSym); } -SQLITE_PRIVATE void tdsqlite3OsDlClose(tdsqlite3_vfs *pVfs, void *pHandle){ +SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){ pVfs->xDlClose(pVfs, pHandle); } #endif /* SQLITE_OMIT_LOAD_EXTENSION */ -SQLITE_PRIVATE int tdsqlite3OsRandomness(tdsqlite3_vfs *pVfs, int nByte, char *zBufOut){ - if( tdsqlite3Config.iPrngSeed ){ +SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + if( sqlite3Config.iPrngSeed ){ memset(zBufOut, 0, nByte); if( ALWAYS(nByte>(signed)sizeof(unsigned)) ) nByte = sizeof(unsigned int); - memcpy(zBufOut, &tdsqlite3Config.iPrngSeed, nByte); + memcpy(zBufOut, &sqlite3Config.iPrngSeed, nByte); return SQLITE_OK; }else{ return pVfs->xRandomness(pVfs, nByte, zBufOut); } } -SQLITE_PRIVATE int tdsqlite3OsSleep(tdsqlite3_vfs *pVfs, int nMicro){ +SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ return pVfs->xSleep(pVfs, nMicro); } -SQLITE_PRIVATE int tdsqlite3OsGetLastError(tdsqlite3_vfs *pVfs){ +SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){ return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0; } -SQLITE_PRIVATE int tdsqlite3OsCurrentTimeInt64(tdsqlite3_vfs *pVfs, tdsqlite3_int64 *pTimeOut){ +SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ int rc; /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() ** method to get the current date and time if that method is available @@ -27352,25 +27352,25 @@ SQLITE_PRIVATE int tdsqlite3OsCurrentTimeInt64(tdsqlite3_vfs *pVfs, tdsqlite3_in }else{ double r; rc = pVfs->xCurrentTime(pVfs, &r); - *pTimeOut = (tdsqlite3_int64)(r*86400000.0); + *pTimeOut = (sqlite3_int64)(r*86400000.0); } return rc; } -SQLITE_PRIVATE int tdsqlite3OsOpenMalloc( - tdsqlite3_vfs *pVfs, +SQLITE_PRIVATE int sqlite3OsOpenMalloc( + sqlite3_vfs *pVfs, const char *zFile, - tdsqlite3_file **ppFile, + sqlite3_file **ppFile, int flags, int *pOutFlags ){ int rc; - tdsqlite3_file *pFile; - pFile = (tdsqlite3_file *)tdsqlite3MallocZero(pVfs->szOsFile); + sqlite3_file *pFile; + pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile); if( pFile ){ - rc = tdsqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); + rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags); if( rc!=SQLITE_OK ){ - tdsqlite3_free(pFile); + sqlite3_free(pFile); }else{ *ppFile = pFile; } @@ -27379,67 +27379,67 @@ SQLITE_PRIVATE int tdsqlite3OsOpenMalloc( } return rc; } -SQLITE_PRIVATE void tdsqlite3OsCloseFree(tdsqlite3_file *pFile){ +SQLITE_PRIVATE void sqlite3OsCloseFree(sqlite3_file *pFile){ assert( pFile ); - tdsqlite3OsClose(pFile); - tdsqlite3_free(pFile); + sqlite3OsClose(pFile); + sqlite3_free(pFile); } /* ** This function is a wrapper around the OS specific implementation of -** tdsqlite3_os_init(). The purpose of the wrapper is to provide the +** sqlite3_os_init(). The purpose of the wrapper is to provide the ** ability to simulate a malloc failure, so that the handling of an -** error in tdsqlite3_os_init() by the upper layers can be tested. +** error in sqlite3_os_init() by the upper layers can be tested. */ -SQLITE_PRIVATE int tdsqlite3OsInit(void){ - void *p = tdsqlite3_malloc(10); +SQLITE_PRIVATE int sqlite3OsInit(void){ + void *p = sqlite3_malloc(10); if( p==0 ) return SQLITE_NOMEM_BKPT; - tdsqlite3_free(p); - return tdsqlite3_os_init(); + sqlite3_free(p); + return sqlite3_os_init(); } /* ** The list of all registered VFS implementations. */ -static tdsqlite3_vfs * SQLITE_WSD vfsList = 0; -#define vfsList GLOBAL(tdsqlite3_vfs *, vfsList) +static sqlite3_vfs * SQLITE_WSD vfsList = 0; +#define vfsList GLOBAL(sqlite3_vfs *, vfsList) /* ** Locate a VFS by name. If no name is given, simply return the ** first VFS on the list. */ -SQLITE_API tdsqlite3_vfs *tdsqlite3_vfs_find(const char *zVfs){ - tdsqlite3_vfs *pVfs = 0; +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){ + sqlite3_vfs *pVfs = 0; #if SQLITE_THREADSAFE - tdsqlite3_mutex *mutex; + sqlite3_mutex *mutex; #endif #ifndef SQLITE_OMIT_AUTOINIT - int rc = tdsqlite3_initialize(); + int rc = sqlite3_initialize(); if( rc ) return 0; #endif #if SQLITE_THREADSAFE - mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif - tdsqlite3_mutex_enter(mutex); + sqlite3_mutex_enter(mutex); for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){ if( zVfs==0 ) break; if( strcmp(zVfs, pVfs->zName)==0 ) break; } - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); return pVfs; } /* ** Unlink a VFS from the linked list */ -static void vfsUnlink(tdsqlite3_vfs *pVfs){ - assert( tdsqlite3_mutex_held(tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); +static void vfsUnlink(sqlite3_vfs *pVfs){ + assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) ); if( pVfs==0 ){ /* No-op */ }else if( vfsList==pVfs ){ vfsList = pVfs->pNext; }else if( vfsList ){ - tdsqlite3_vfs *p = vfsList; + sqlite3_vfs *p = vfsList; while( p->pNext && p->pNext!=pVfs ){ p = p->pNext; } @@ -27454,18 +27454,18 @@ static void vfsUnlink(tdsqlite3_vfs *pVfs){ ** VFS multiple times. The new VFS becomes the default if makeDflt is ** true. */ -SQLITE_API int tdsqlite3_vfs_register(tdsqlite3_vfs *pVfs, int makeDflt){ - MUTEX_LOGIC(tdsqlite3_mutex *mutex;) +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){ + MUTEX_LOGIC(sqlite3_mutex *mutex;) #ifndef SQLITE_OMIT_AUTOINIT - int rc = tdsqlite3_initialize(); + int rc = sqlite3_initialize(); if( rc ) return rc; #endif #ifdef SQLITE_ENABLE_API_ARMOR if( pVfs==0 ) return SQLITE_MISUSE_BKPT; #endif - MUTEX_LOGIC( mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - tdsqlite3_mutex_enter(mutex); + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); if( makeDflt || vfsList==0 ){ pVfs->pNext = vfsList; @@ -27475,23 +27475,23 @@ SQLITE_API int tdsqlite3_vfs_register(tdsqlite3_vfs *pVfs, int makeDflt){ vfsList->pNext = pVfs; } assert(vfsList); - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); return SQLITE_OK; } /* ** Unregister a VFS so that it is no longer accessible. */ -SQLITE_API int tdsqlite3_vfs_unregister(tdsqlite3_vfs *pVfs){ - MUTEX_LOGIC(tdsqlite3_mutex *mutex;) +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ + MUTEX_LOGIC(sqlite3_mutex *mutex;) #ifndef SQLITE_OMIT_AUTOINIT - int rc = tdsqlite3_initialize(); + int rc = sqlite3_initialize(); if( rc ) return rc; #endif - MUTEX_LOGIC( mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - tdsqlite3_mutex_enter(mutex); + MUTEX_LOGIC( mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(mutex); vfsUnlink(pVfs); - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); return SQLITE_OK; } @@ -27511,7 +27511,7 @@ SQLITE_API int tdsqlite3_vfs_unregister(tdsqlite3_vfs *pVfs){ ** ** This file contains code to support the concept of "benign" ** malloc failures (when the xMalloc() or xRealloc() method of the -** tdsqlite3_mem_methods structure fails to allocate a block of memory +** sqlite3_mem_methods structure fails to allocate a block of memory ** and returns 0). ** ** Most malloc failures are non-benign. After they occur, SQLite @@ -27534,29 +27534,29 @@ typedef struct BenignMallocHooks BenignMallocHooks; static SQLITE_WSD struct BenignMallocHooks { void (*xBenignBegin)(void); void (*xBenignEnd)(void); -} tdsqlite3Hooks = { 0, 0 }; +} sqlite3Hooks = { 0, 0 }; /* The "wsdHooks" macro will resolve to the appropriate BenignMallocHooks ** structure. If writable static data is unsupported on the target, ** we have to locate the state vector at run-time. In the more common ** case where writable static data is supported, wsdHooks can refer directly -** to the "tdsqlite3Hooks" state vector declared above. +** to the "sqlite3Hooks" state vector declared above. */ #ifdef SQLITE_OMIT_WSD # define wsdHooksInit \ - BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,tdsqlite3Hooks) + BenignMallocHooks *x = &GLOBAL(BenignMallocHooks,sqlite3Hooks) # define wsdHooks x[0] #else # define wsdHooksInit -# define wsdHooks tdsqlite3Hooks +# define wsdHooks sqlite3Hooks #endif /* -** Register hooks to call when tdsqlite3BeginBenignMalloc() and -** tdsqlite3EndBenignMalloc() are called, respectively. +** Register hooks to call when sqlite3BeginBenignMalloc() and +** sqlite3EndBenignMalloc() are called, respectively. */ -SQLITE_PRIVATE void tdsqlite3BenignMallocHooks( +SQLITE_PRIVATE void sqlite3BenignMallocHooks( void (*xBenignBegin)(void), void (*xBenignEnd)(void) ){ @@ -27566,17 +27566,17 @@ SQLITE_PRIVATE void tdsqlite3BenignMallocHooks( } /* -** This (tdsqlite3EndBenignMalloc()) is called by SQLite code to indicate that -** subsequent malloc failures are benign. A call to tdsqlite3EndBenignMalloc() +** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that +** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc() ** indicates that subsequent malloc failures are non-benign. */ -SQLITE_PRIVATE void tdsqlite3BeginBenignMalloc(void){ +SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){ wsdHooksInit; if( wsdHooks.xBenignBegin ){ wsdHooks.xBenignBegin(); } } -SQLITE_PRIVATE void tdsqlite3EndBenignMalloc(void){ +SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){ wsdHooksInit; if( wsdHooks.xBenignEnd ){ wsdHooks.xBenignEnd(); @@ -27603,7 +27603,7 @@ SQLITE_PRIVATE void tdsqlite3EndBenignMalloc(void){ ** SQLITE_ZERO_MALLOC is defined. The allocation drivers implemented ** here always fail. SQLite will not operate with these drivers. These ** are merely placeholders. Real drivers must be substituted using -** tdsqlite3_config() before SQLite will operate. +** sqlite3_config() before SQLite will operate. */ /* #include "sqliteInt.h" */ @@ -27617,32 +27617,32 @@ SQLITE_PRIVATE void tdsqlite3EndBenignMalloc(void){ /* ** No-op versions of all memory allocation routines */ -static void *tdsqlite3MemMalloc(int nByte){ return 0; } -static void tdsqlite3MemFree(void *pPrior){ return; } -static void *tdsqlite3MemRealloc(void *pPrior, int nByte){ return 0; } -static int tdsqlite3MemSize(void *pPrior){ return 0; } -static int tdsqlite3MemRoundup(int n){ return n; } -static int tdsqlite3MemInit(void *NotUsed){ return SQLITE_OK; } -static void tdsqlite3MemShutdown(void *NotUsed){ return; } +static void *sqlite3MemMalloc(int nByte){ return 0; } +static void sqlite3MemFree(void *pPrior){ return; } +static void *sqlite3MemRealloc(void *pPrior, int nByte){ return 0; } +static int sqlite3MemSize(void *pPrior){ return 0; } +static int sqlite3MemRoundup(int n){ return n; } +static int sqlite3MemInit(void *NotUsed){ return SQLITE_OK; } +static void sqlite3MemShutdown(void *NotUsed){ return; } /* ** This routine is the only routine in this file with external linkage. ** ** Populate the low-level memory allocation function pointers in -** tdsqlite3GlobalConfig.m with pointers to the routines in this file. -*/ -SQLITE_PRIVATE void tdsqlite3MemSetDefault(void){ - static const tdsqlite3_mem_methods defaultMethods = { - tdsqlite3MemMalloc, - tdsqlite3MemFree, - tdsqlite3MemRealloc, - tdsqlite3MemSize, - tdsqlite3MemRoundup, - tdsqlite3MemInit, - tdsqlite3MemShutdown, +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, 0 }; - tdsqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); } #endif /* SQLITE_ZERO_MALLOC */ @@ -27666,7 +27666,7 @@ SQLITE_PRIVATE void tdsqlite3MemSetDefault(void){ ** to obtain the memory it needs. ** ** This file contains implementations of the low-level memory allocation -** routines specified in the tdsqlite3_mem_methods object. The content of +** routines specified in the sqlite3_mem_methods object. The content of ** this file is only used if SQLITE_SYSTEM_MALLOC is defined. The ** SQLITE_SYSTEM_MALLOC macro is defined automatically if neither the ** SQLITE_MEMDEBUG nor the SQLITE_WIN32_MALLOC macros are defined. The @@ -27770,24 +27770,24 @@ static malloc_zone_t* _sqliteZone_; /* ** Like malloc(), but remember the size of the allocation -** so that we can find it later using tdsqlite3MemSize(). +** so that we can find it later using sqlite3MemSize(). ** ** For this low-level routine, we are guaranteed that nByte>0 because ** cases of nByte<=0 will be intercepted and dealt with by higher level ** routines. */ -static void *tdsqlite3MemMalloc(int nByte){ +static void *sqlite3MemMalloc(int nByte){ #ifdef SQLITE_MALLOCSIZE void *p; testcase( ROUND8(nByte)==nByte ); p = SQLITE_MALLOC( nByte ); if( p==0 ){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - tdsqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); } return p; #else - tdsqlite3_int64 *p; + sqlite3_int64 *p; assert( nByte>0 ); testcase( ROUND8(nByte)!=nByte ); p = SQLITE_MALLOC( nByte+8 ); @@ -27795,26 +27795,26 @@ static void *tdsqlite3MemMalloc(int nByte){ p[0] = nByte; p++; }else{ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - tdsqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes of memory", nByte); } return (void *)p; #endif } /* -** Like free() but works for allocations obtained from tdsqlite3MemMalloc() -** or tdsqlite3MemRealloc(). +** Like free() but works for allocations obtained from sqlite3MemMalloc() +** or sqlite3MemRealloc(). ** ** For this low-level routine, we already know that pPrior!=0 since ** cases where pPrior==0 will have been intecepted and dealt with ** by higher-level routines. */ -static void tdsqlite3MemFree(void *pPrior){ +static void sqlite3MemFree(void *pPrior){ #ifdef SQLITE_MALLOCSIZE SQLITE_FREE(pPrior); #else - tdsqlite3_int64 *p = (tdsqlite3_int64*)pPrior; + sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 ); p--; SQLITE_FREE(p); @@ -27825,14 +27825,14 @@ static void tdsqlite3MemFree(void *pPrior){ ** Report the allocated size of a prior return from xMalloc() ** or xRealloc(). */ -static int tdsqlite3MemSize(void *pPrior){ +static int sqlite3MemSize(void *pPrior){ #ifdef SQLITE_MALLOCSIZE assert( pPrior!=0 ); return (int)SQLITE_MALLOCSIZE(pPrior); #else - tdsqlite3_int64 *p; + sqlite3_int64 *p; assert( pPrior!=0 ); - p = (tdsqlite3_int64*)pPrior; + p = (sqlite3_int64*)pPrior; p--; return (int)p[0]; #endif @@ -27840,7 +27840,7 @@ static int tdsqlite3MemSize(void *pPrior){ /* ** Like realloc(). Resize an allocation previously obtained from -** tdsqlite3MemMalloc(). +** sqlite3MemMalloc(). ** ** For this low-level interface, we know that pPrior!=0. Cases where ** pPrior==0 while have been intercepted by higher-level routine and @@ -27848,18 +27848,18 @@ static int tdsqlite3MemSize(void *pPrior){ ** cases where nByte<=0 will have been intercepted by higher-level ** routines and redirected to xFree. */ -static void *tdsqlite3MemRealloc(void *pPrior, int nByte){ +static void *sqlite3MemRealloc(void *pPrior, int nByte){ #ifdef SQLITE_MALLOCSIZE void *p = SQLITE_REALLOC(pPrior, nByte); if( p==0 ){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - tdsqlite3_log(SQLITE_NOMEM, + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed memory resize %u to %u bytes", SQLITE_MALLOCSIZE(pPrior), nByte); } return p; #else - tdsqlite3_int64 *p = (tdsqlite3_int64*)pPrior; + sqlite3_int64 *p = (sqlite3_int64*)pPrior; assert( pPrior!=0 && nByte>0 ); assert( nByte==ROUND8(nByte) ); /* EV: R-46199-30249 */ p--; @@ -27868,10 +27868,10 @@ static void *tdsqlite3MemRealloc(void *pPrior, int nByte){ p[0] = nByte; p++; }else{ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - tdsqlite3_log(SQLITE_NOMEM, + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed memory resize %u to %u bytes", - tdsqlite3MemSize(pPrior), nByte); + sqlite3MemSize(pPrior), nByte); } return (void*)p; #endif @@ -27880,14 +27880,14 @@ static void *tdsqlite3MemRealloc(void *pPrior, int nByte){ /* ** Round up a request size to the next valid allocation size. */ -static int tdsqlite3MemRoundup(int n){ +static int sqlite3MemRoundup(int n){ return ROUND8(n); } /* ** Initialize this module. */ -static int tdsqlite3MemInit(void *NotUsed){ +static int sqlite3MemInit(void *NotUsed){ #if defined(__APPLE__) && !defined(SQLITE_WITHOUT_ZONEMALLOC) int cpuCount; size_t len; @@ -27914,7 +27914,7 @@ static int tdsqlite3MemInit(void *NotUsed){ /* ** Deinitialize this module. */ -static void tdsqlite3MemShutdown(void *NotUsed){ +static void sqlite3MemShutdown(void *NotUsed){ UNUSED_PARAMETER(NotUsed); return; } @@ -27923,20 +27923,20 @@ static void tdsqlite3MemShutdown(void *NotUsed){ ** This routine is the only routine in this file with external linkage. ** ** Populate the low-level memory allocation function pointers in -** tdsqlite3GlobalConfig.m with pointers to the routines in this file. -*/ -SQLITE_PRIVATE void tdsqlite3MemSetDefault(void){ - static const tdsqlite3_mem_methods defaultMethods = { - tdsqlite3MemMalloc, - tdsqlite3MemFree, - tdsqlite3MemRealloc, - tdsqlite3MemSize, - tdsqlite3MemRoundup, - tdsqlite3MemInit, - tdsqlite3MemShutdown, +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, 0 }; - tdsqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); } #endif /* SQLITE_SYSTEM_MALLOC */ @@ -27962,7 +27962,7 @@ SQLITE_PRIVATE void tdsqlite3MemSetDefault(void){ ** leaks and memory usage errors. ** ** This file contains implementations of the low-level memory allocation -** routines specified in the tdsqlite3_mem_methods object. +** routines specified in the sqlite3_mem_methods object. */ /* #include "sqliteInt.h" */ @@ -28029,7 +28029,7 @@ static struct { /* ** Mutex to control access to the memory allocation subsystem. */ - tdsqlite3_mutex *mutex; + sqlite3_mutex *mutex; /* ** Head and tail of a linked list of all outstanding allocations @@ -28050,8 +28050,8 @@ static struct { char zTitle[100]; /* The title text */ /* - ** tdsqlite3MallocDisallow() increments the following counter. - ** tdsqlite3MallocAllow() decrements it. + ** sqlite3MallocDisallow() increments the following counter. + ** sqlite3MallocAllow() decrements it. */ int disallow; /* Do not allow memory allocation */ @@ -28094,7 +28094,7 @@ static void adjustStats(int iSize, int increment){ ** This routine checks the guards at either end of the allocation and ** if they are incorrect it asserts. */ -static struct MemBlockHdr *tdsqlite3MemsysGetHeader(void *pAllocation){ +static struct MemBlockHdr *sqlite3MemsysGetHeader(void *pAllocation){ struct MemBlockHdr *p; int *pInt; u8 *pU8; @@ -28118,25 +28118,25 @@ static struct MemBlockHdr *tdsqlite3MemsysGetHeader(void *pAllocation){ /* ** Return the number of bytes currently allocated at address p. */ -static int tdsqlite3MemSize(void *p){ +static int sqlite3MemSize(void *p){ struct MemBlockHdr *pHdr; if( !p ){ return 0; } - pHdr = tdsqlite3MemsysGetHeader(p); + pHdr = sqlite3MemsysGetHeader(p); return (int)pHdr->iSize; } /* ** Initialize the memory allocation subsystem. */ -static int tdsqlite3MemInit(void *NotUsed){ +static int sqlite3MemInit(void *NotUsed){ UNUSED_PARAMETER(NotUsed); assert( (sizeof(struct MemBlockHdr)&7) == 0 ); - if( !tdsqlite3GlobalConfig.bMemstat ){ + if( !sqlite3GlobalConfig.bMemstat ){ /* If memory status is enabled, then the malloc.c wrapper will already ** hold the STATIC_MEM mutex when the routines here are invoked. */ - mem.mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } return SQLITE_OK; } @@ -28144,7 +28144,7 @@ static int tdsqlite3MemInit(void *NotUsed){ /* ** Deinitialize the memory allocation subsystem. */ -static void tdsqlite3MemShutdown(void *NotUsed){ +static void sqlite3MemShutdown(void *NotUsed){ UNUSED_PARAMETER(NotUsed); mem.mutex = 0; } @@ -28152,7 +28152,7 @@ static void tdsqlite3MemShutdown(void *NotUsed){ /* ** Round up a request size to the next valid allocation size. */ -static int tdsqlite3MemRoundup(int n){ +static int sqlite3MemRoundup(int n){ return ROUND8(n); } @@ -28184,7 +28184,7 @@ static void randomFill(char *pBuf, int nByte){ /* ** Allocate nByte bytes of memory. */ -static void *tdsqlite3MemMalloc(int nByte){ +static void *sqlite3MemMalloc(int nByte){ struct MemBlockHdr *pHdr; void **pBt; char *z; @@ -28192,7 +28192,7 @@ static void *tdsqlite3MemMalloc(int nByte){ void *p = 0; int totalSize; int nReserve; - tdsqlite3_mutex_enter(mem.mutex); + sqlite3_mutex_enter(mem.mutex); assert( mem.disallow==0 ); nReserve = ROUND8(nByte); totalSize = nReserve + sizeof(*pHdr) + sizeof(int) + @@ -28236,23 +28236,23 @@ static void *tdsqlite3MemMalloc(int nByte){ memset(((char*)pInt)+nByte, 0x65, nReserve-nByte); p = (void*)pInt; } - tdsqlite3_mutex_leave(mem.mutex); + sqlite3_mutex_leave(mem.mutex); return p; } /* ** Free memory. */ -static void tdsqlite3MemFree(void *pPrior){ +static void sqlite3MemFree(void *pPrior){ struct MemBlockHdr *pHdr; void **pBt; char *z; - assert( tdsqlite3GlobalConfig.bMemstat || tdsqlite3GlobalConfig.bCoreMutex==0 + assert( sqlite3GlobalConfig.bMemstat || sqlite3GlobalConfig.bCoreMutex==0 || mem.mutex!=0 ); - pHdr = tdsqlite3MemsysGetHeader(pPrior); + pHdr = sqlite3MemsysGetHeader(pPrior); pBt = (void**)pHdr; pBt -= pHdr->nBacktraceSlots; - tdsqlite3_mutex_enter(mem.mutex); + sqlite3_mutex_enter(mem.mutex); if( pHdr->pPrev ){ assert( pHdr->pPrev->pNext==pHdr ); pHdr->pPrev->pNext = pHdr->pNext; @@ -28273,7 +28273,7 @@ static void tdsqlite3MemFree(void *pPrior){ randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + (int)pHdr->iSize + sizeof(int) + pHdr->nTitle); free(z); - tdsqlite3_mutex_leave(mem.mutex); + sqlite3_mutex_leave(mem.mutex); } /* @@ -28285,48 +28285,48 @@ static void tdsqlite3MemFree(void *pPrior){ ** much more likely to break and we are much more liking to find ** the error. */ -static void *tdsqlite3MemRealloc(void *pPrior, int nByte){ +static void *sqlite3MemRealloc(void *pPrior, int nByte){ struct MemBlockHdr *pOldHdr; void *pNew; assert( mem.disallow==0 ); assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ - pOldHdr = tdsqlite3MemsysGetHeader(pPrior); - pNew = tdsqlite3MemMalloc(nByte); + pOldHdr = sqlite3MemsysGetHeader(pPrior); + pNew = sqlite3MemMalloc(nByte); if( pNew ){ memcpy(pNew, pPrior, (int)(nByteiSize ? nByte : pOldHdr->iSize)); if( nByte>pOldHdr->iSize ){ randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); } - tdsqlite3MemFree(pPrior); + sqlite3MemFree(pPrior); } return pNew; } /* ** Populate the low-level memory allocation function pointers in -** tdsqlite3GlobalConfig.m with pointers to the routines in this file. -*/ -SQLITE_PRIVATE void tdsqlite3MemSetDefault(void){ - static const tdsqlite3_mem_methods defaultMethods = { - tdsqlite3MemMalloc, - tdsqlite3MemFree, - tdsqlite3MemRealloc, - tdsqlite3MemSize, - tdsqlite3MemRoundup, - tdsqlite3MemInit, - tdsqlite3MemShutdown, +** sqlite3GlobalConfig.m with pointers to the routines in this file. +*/ +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + static const sqlite3_mem_methods defaultMethods = { + sqlite3MemMalloc, + sqlite3MemFree, + sqlite3MemRealloc, + sqlite3MemSize, + sqlite3MemRoundup, + sqlite3MemInit, + sqlite3MemShutdown, 0 }; - tdsqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); + sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods); } /* ** Set the "type" of an allocation. */ -SQLITE_PRIVATE void tdsqlite3MemdebugSetType(void *p, u8 eType){ - if( p && tdsqlite3GlobalConfig.m.xMalloc==tdsqlite3MemMalloc ){ +SQLITE_PRIVATE void sqlite3MemdebugSetType(void *p, u8 eType){ + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ struct MemBlockHdr *pHdr; - pHdr = tdsqlite3MemsysGetHeader(p); + pHdr = sqlite3MemsysGetHeader(p); assert( pHdr->iForeGuard==FOREGUARD ); pHdr->eType = eType; } @@ -28339,13 +28339,13 @@ SQLITE_PRIVATE void tdsqlite3MemdebugSetType(void *p, u8 eType){ ** This routine is designed for use within an assert() statement, to ** verify the type of an allocation. For example: ** -** assert( tdsqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); +** assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); */ -SQLITE_PRIVATE int tdsqlite3MemdebugHasType(void *p, u8 eType){ +SQLITE_PRIVATE int sqlite3MemdebugHasType(void *p, u8 eType){ int rc = 1; - if( p && tdsqlite3GlobalConfig.m.xMalloc==tdsqlite3MemMalloc ){ + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ struct MemBlockHdr *pHdr; - pHdr = tdsqlite3MemsysGetHeader(p); + pHdr = sqlite3MemsysGetHeader(p); assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ if( (pHdr->eType&eType)==0 ){ rc = 0; @@ -28361,13 +28361,13 @@ SQLITE_PRIVATE int tdsqlite3MemdebugHasType(void *p, u8 eType){ ** This routine is designed for use within an assert() statement, to ** verify the type of an allocation. For example: ** -** assert( tdsqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); +** assert( sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); */ -SQLITE_PRIVATE int tdsqlite3MemdebugNoType(void *p, u8 eType){ +SQLITE_PRIVATE int sqlite3MemdebugNoType(void *p, u8 eType){ int rc = 1; - if( p && tdsqlite3GlobalConfig.m.xMalloc==tdsqlite3MemMalloc ){ + if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){ struct MemBlockHdr *pHdr; - pHdr = tdsqlite3MemsysGetHeader(p); + pHdr = sqlite3MemsysGetHeader(p); assert( pHdr->iForeGuard==FOREGUARD ); /* Allocation is valid */ if( (pHdr->eType&eType)!=0 ){ rc = 0; @@ -28381,31 +28381,31 @@ SQLITE_PRIVATE int tdsqlite3MemdebugNoType(void *p, u8 eType){ ** A value of zero turns off backtracing. The number is always rounded ** up to a multiple of 2. */ -SQLITE_PRIVATE void tdsqlite3MemdebugBacktrace(int depth){ +SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){ if( depth<0 ){ depth = 0; } if( depth>20 ){ depth = 20; } depth = (depth+1)&0xfe; mem.nBacktrace = depth; } -SQLITE_PRIVATE void tdsqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){ +SQLITE_PRIVATE void sqlite3MemdebugBacktraceCallback(void (*xBacktrace)(int, int, void **)){ mem.xBacktrace = xBacktrace; } /* ** Set the title string for subsequent allocations. */ -SQLITE_PRIVATE void tdsqlite3MemdebugSettitle(const char *zTitle){ - unsigned int n = tdsqlite3Strlen30(zTitle) + 1; - tdsqlite3_mutex_enter(mem.mutex); +SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){ + unsigned int n = sqlite3Strlen30(zTitle) + 1; + sqlite3_mutex_enter(mem.mutex); if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1; memcpy(mem.zTitle, zTitle, n); mem.zTitle[n] = 0; mem.nTitle = ROUND8(n); - tdsqlite3_mutex_leave(mem.mutex); + sqlite3_mutex_leave(mem.mutex); } -SQLITE_PRIVATE void tdsqlite3MemdebugSync(){ +SQLITE_PRIVATE void sqlite3MemdebugSync(){ struct MemBlockHdr *pHdr; for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ void **pBt = (void**)pHdr; @@ -28418,7 +28418,7 @@ SQLITE_PRIVATE void tdsqlite3MemdebugSync(){ ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ -SQLITE_PRIVATE void tdsqlite3MemdebugDump(const char *zFilename){ +SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){ FILE *out; struct MemBlockHdr *pHdr; void **pBt; @@ -28458,9 +28458,9 @@ SQLITE_PRIVATE void tdsqlite3MemdebugDump(const char *zFilename){ } /* -** Return the number of times tdsqlite3MemMalloc() has been called. +** Return the number of times sqlite3MemMalloc() has been called. */ -SQLITE_PRIVATE int tdsqlite3MemdebugMallocCount(){ +SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){ int i; int nTotal = 0; for(i=0; i=1 ); size = mem3.aPool[i-1].u.hdr.size4x/4; @@ -28661,7 +28661,7 @@ static void memsys3Unlink(u32 i){ ** at *pRoot. */ static void memsys3LinkIntoList(u32 i, u32 *pRoot){ - assert( tdsqlite3_mutex_held(mem3.mutex) ); + assert( sqlite3_mutex_held(mem3.mutex) ); mem3.aPool[i].u.list.next = *pRoot; mem3.aPool[i].u.list.prev = 0; if( *pRoot ){ @@ -28676,7 +28676,7 @@ static void memsys3LinkIntoList(u32 i, u32 *pRoot){ */ static void memsys3Link(u32 i){ u32 size, hash; - assert( tdsqlite3_mutex_held(mem3.mutex) ); + assert( sqlite3_mutex_held(mem3.mutex) ); assert( i>=1 ); assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 ); size = mem3.aPool[i-1].u.hdr.size4x/4; @@ -28693,16 +28693,16 @@ static void memsys3Link(u32 i){ /* ** If the STATIC_MEM mutex is not already held, obtain it now. The mutex ** will already be held (obtained by code in malloc.c) if -** tdsqlite3GlobalConfig.bMemStat is true. +** sqlite3GlobalConfig.bMemStat is true. */ static void memsys3Enter(void){ - if( tdsqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){ - mem3.mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + if( sqlite3GlobalConfig.bMemstat==0 && mem3.mutex==0 ){ + mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } - tdsqlite3_mutex_enter(mem3.mutex); + sqlite3_mutex_enter(mem3.mutex); } static void memsys3Leave(void){ - tdsqlite3_mutex_leave(mem3.mutex); + sqlite3_mutex_leave(mem3.mutex); } /* @@ -28711,10 +28711,10 @@ static void memsys3Leave(void){ static void memsys3OutOfMemory(int nByte){ if( !mem3.alarmBusy ){ mem3.alarmBusy = 1; - assert( tdsqlite3_mutex_held(mem3.mutex) ); - tdsqlite3_mutex_leave(mem3.mutex); - tdsqlite3_release_memory(nByte); - tdsqlite3_mutex_enter(mem3.mutex); + assert( sqlite3_mutex_held(mem3.mutex) ); + sqlite3_mutex_leave(mem3.mutex); + sqlite3_release_memory(nByte); + sqlite3_mutex_enter(mem3.mutex); mem3.alarmBusy = 0; } } @@ -28727,7 +28727,7 @@ static void memsys3OutOfMemory(int nByte){ */ static void *memsys3Checkout(u32 i, u32 nBlock){ u32 x; - assert( tdsqlite3_mutex_held(mem3.mutex) ); + assert( sqlite3_mutex_held(mem3.mutex) ); assert( i>=1 ); assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ); assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock ); @@ -28744,7 +28744,7 @@ static void *memsys3Checkout(u32 i, u32 nBlock){ ** is not large enough, return 0. */ static void *memsys3FromMaster(u32 nBlock){ - assert( tdsqlite3_mutex_held(mem3.mutex) ); + assert( sqlite3_mutex_held(mem3.mutex) ); assert( mem3.szMaster>=nBlock ); if( nBlock>=mem3.szMaster-1 ){ /* Use the entire master */ @@ -28791,7 +28791,7 @@ static void *memsys3FromMaster(u32 nBlock){ static void memsys3Merge(u32 *pRoot){ u32 iNext, prev, size, i, x; - assert( tdsqlite3_mutex_held(mem3.mutex) ); + assert( sqlite3_mutex_held(mem3.mutex) ); for(i=*pRoot; i>0; i=iNext){ iNext = mem3.aPool[i].u.list.next; size = mem3.aPool[i-1].u.hdr.size4x; @@ -28832,7 +28832,7 @@ static void *memsys3MallocUnsafe(int nByte){ u32 nBlock; u32 toFree; - assert( tdsqlite3_mutex_held(mem3.mutex) ); + assert( sqlite3_mutex_held(mem3.mutex) ); assert( sizeof(Mem3Block)==8 ); if( nByte<=12 ){ nBlock = 2; @@ -28913,7 +28913,7 @@ static void memsys3FreeUnsafe(void *pOld){ Mem3Block *p = (Mem3Block*)pOld; int i; u32 size, x; - assert( tdsqlite3_mutex_held(mem3.mutex) ); + assert( sqlite3_mutex_held(mem3.mutex) ); assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] ); i = p - mem3.aPool; assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 ); @@ -28973,7 +28973,7 @@ static int memsys3Roundup(int n){ ** Allocate nBytes of memory. */ static void *memsys3Malloc(int nBytes){ - tdsqlite3_int64 *p; + sqlite3_int64 *p; assert( nBytes>0 ); /* malloc.c filters out 0 byte requests */ memsys3Enter(); p = memsys3MallocUnsafe(nBytes); @@ -28998,10 +28998,10 @@ static void *memsys3Realloc(void *pPrior, int nBytes){ int nOld; void *p; if( pPrior==0 ){ - return tdsqlite3_malloc(nBytes); + return sqlite3_malloc(nBytes); } if( nBytes<=0 ){ - tdsqlite3_free(pPrior); + sqlite3_free(pPrior); return 0; } nOld = memsys3Size(pPrior); @@ -29027,14 +29027,14 @@ static void *memsys3Realloc(void *pPrior, int nBytes){ */ static int memsys3Init(void *NotUsed){ UNUSED_PARAMETER(NotUsed); - if( !tdsqlite3GlobalConfig.pHeap ){ + if( !sqlite3GlobalConfig.pHeap ){ return SQLITE_ERROR; } /* Store a pointer to the memory block in global structure mem3. */ assert( sizeof(Mem3Block)==8 ); - mem3.aPool = (Mem3Block *)tdsqlite3GlobalConfig.pHeap; - mem3.nPool = (tdsqlite3GlobalConfig.nHeap / sizeof(Mem3Block)) - 2; + mem3.aPool = (Mem3Block *)sqlite3GlobalConfig.pHeap; + mem3.nPool = (sqlite3GlobalConfig.nHeap / sizeof(Mem3Block)) - 2; /* Initialize the master block. */ mem3.szMaster = mem3.nPool; @@ -29062,7 +29062,7 @@ static void memsys3Shutdown(void *NotUsed){ ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ -SQLITE_PRIVATE void tdsqlite3Memsys3Dump(const char *zFilename){ +SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){ #ifdef SQLITE_DEBUG FILE *out; u32 i, j; @@ -29124,7 +29124,7 @@ SQLITE_PRIVATE void tdsqlite3Memsys3Dump(const char *zFilename){ fprintf(out, "master=%d\n", mem3.iMaster); fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8); fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8); - tdsqlite3_mutex_leave(mem3.mutex); + sqlite3_mutex_leave(mem3.mutex); if( out==stdout ){ fflush(stdout); }else{ @@ -29140,14 +29140,14 @@ SQLITE_PRIVATE void tdsqlite3Memsys3Dump(const char *zFilename){ ** linkage. ** ** Populate the low-level memory allocation function pointers in -** tdsqlite3GlobalConfig.m with pointers to the routines in this file. The +** sqlite3GlobalConfig.m with pointers to the routines in this file. The ** arguments specify the block of memory to manage. ** -** This routine is only called by tdsqlite3_config(), and therefore +** This routine is only called by sqlite3_config(), and therefore ** is not required to be threadsafe (it is not). */ -SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetMemsys3(void){ - static const tdsqlite3_mem_methods mempoolMethods = { +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ + static const sqlite3_mem_methods mempoolMethods = { memsys3Malloc, memsys3Free, memsys3Realloc, @@ -29180,9 +29180,9 @@ SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetMemsys3(void){ ** ** This version of the memory allocation subsystem omits all ** use of malloc(). The application gives SQLite a block of memory -** before calling tdsqlite3_initialize() from which allocations +** before calling sqlite3_initialize() from which allocations ** are made and returned by the xMalloc() and xRealloc() -** implementations. Once tdsqlite3_initialize() has been called, +** implementations. Once sqlite3_initialize() has been called, ** the amount of memory available to SQLite is fixed and cannot ** be changed. ** @@ -29211,7 +29211,7 @@ SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetMemsys3(void){ ** ** N >= M*(1 + log2(n)/2) - n + 1 ** -** The tdsqlite3_status() logic tracks the maximum values of n and M so +** The sqlite3_status() logic tracks the maximum values of n and M so ** that an application can, at any time, verify this constraint. */ /* #include "sqliteInt.h" */ @@ -29266,7 +29266,7 @@ static SQLITE_WSD struct Mem5Global { /* ** Mutex to control access to the memory allocation subsystem. */ - tdsqlite3_mutex *mutex; + sqlite3_mutex *mutex; #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) /* @@ -29336,7 +29336,7 @@ static void memsys5Unlink(int i, int iLogsize){ */ static void memsys5Link(int i, int iLogsize){ int x; - assert( tdsqlite3_mutex_held(mem5.mutex) ); + assert( sqlite3_mutex_held(mem5.mutex) ); assert( i>=0 && i=0 && iLogsize<=LOGMAX ); assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize ); @@ -29354,10 +29354,10 @@ static void memsys5Link(int i, int iLogsize){ ** Obtain or release the mutex needed to access global data structures. */ static void memsys5Enter(void){ - tdsqlite3_mutex_enter(mem5.mutex); + sqlite3_mutex_enter(mem5.mutex); } static void memsys5Leave(void){ - tdsqlite3_mutex_leave(mem5.mutex); + sqlite3_mutex_leave(mem5.mutex); } /* @@ -29413,8 +29413,8 @@ static void *memsys5MallocUnsafe(int nByte){ */ for(iBin=iLogsize; iBin<=LOGMAX && mem5.aiFreelist[iBin]<0; iBin++){} if( iBin>LOGMAX ){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - tdsqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte); return 0; } i = mem5.aiFreelist[iBin]; @@ -29520,7 +29520,7 @@ static void memsys5FreeUnsafe(void *pOld){ ** Allocate nBytes of memory. */ static void *memsys5Malloc(int nBytes){ - tdsqlite3_int64 *p = 0; + sqlite3_int64 *p = 0; if( nBytes>0 ){ memsys5Enter(); p = memsys5MallocUnsafe(nBytes); @@ -29630,12 +29630,12 @@ static int memsys5Init(void *NotUsed){ */ assert( (sizeof(Mem5Link)&(sizeof(Mem5Link)-1))==0 ); - nByte = tdsqlite3GlobalConfig.nHeap; - zByte = (u8*)tdsqlite3GlobalConfig.pHeap; - assert( zByte!=0 ); /* tdsqlite3_config() does not allow otherwise */ + nByte = sqlite3GlobalConfig.nHeap; + zByte = (u8*)sqlite3GlobalConfig.pHeap; + assert( zByte!=0 ); /* sqlite3_config() does not allow otherwise */ - /* boundaries on tdsqlite3GlobalConfig.mnReq are enforced in tdsqlite3_config() */ - nMinLog = memsys5Log(tdsqlite3GlobalConfig.mnReq); + /* boundaries on sqlite3GlobalConfig.mnReq are enforced in sqlite3_config() */ + nMinLog = memsys5Log(sqlite3GlobalConfig.mnReq); mem5.szAtom = (1<mem5.szAtom ){ mem5.szAtom = mem5.szAtom << 1; @@ -29661,8 +29661,8 @@ static int memsys5Init(void *NotUsed){ } /* If a mutex is required for normal operation, allocate one */ - if( tdsqlite3GlobalConfig.bMemstat==0 ){ - mem5.mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + if( sqlite3GlobalConfig.bMemstat==0 ){ + mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); } return SQLITE_OK; @@ -29682,7 +29682,7 @@ static void memsys5Shutdown(void *NotUsed){ ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ -SQLITE_PRIVATE void tdsqlite3Memsys5Dump(const char *zFilename){ +SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ FILE *out; int i, j, n; int nMinLog; @@ -29722,11 +29722,11 @@ SQLITE_PRIVATE void tdsqlite3Memsys5Dump(const char *zFilename){ /* ** This routine is the only routine in this file with external -** linkage. It returns a pointer to a static tdsqlite3_mem_methods +** linkage. It returns a pointer to a static sqlite3_mem_methods ** struct populated with the memsys5 methods. */ -SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetMemsys5(void){ - static const tdsqlite3_mem_methods memsys5Methods = { +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){ + static const sqlite3_mem_methods memsys5Methods = { memsys5Malloc, memsys5Free, memsys5Realloc, @@ -29776,12 +29776,12 @@ static SQLITE_WSD int mutexIsInit = 0; /* ** This block (enclosed by SQLITE_ENABLE_MULTITHREADED_CHECKS) contains ** the implementation of a wrapper around the system default mutex -** implementation (tdsqlite3DefaultMutex()). +** implementation (sqlite3DefaultMutex()). ** ** Most calls are passed directly through to the underlying default ** mutex implementation. Except, if a mutex is configured by calling -** tdsqlite3MutexWarnOnContention() on it, then if contention is ever -** encountered within xMutexEnter() a warning is emitted via tdsqlite3_log(). +** sqlite3MutexWarnOnContention() on it, then if contention is ever +** encountered within xMutexEnter() a warning is emitted via sqlite3_log(). ** ** This type of mutex is used as the database handle mutex when testing ** apps that usually use SQLITE_CONFIG_MULTITHREAD mode. @@ -29793,13 +29793,13 @@ static SQLITE_WSD int mutexIsInit = 0; ** allocated by the system mutex implementation. Variable iType is usually set ** to the type of mutex requested - SQLITE_MUTEX_RECURSIVE, SQLITE_MUTEX_FAST ** or one of the static mutex identifiers. Or, if this is a recursive mutex -** that has been configured using tdsqlite3MutexWarnOnContention(), it is +** that has been configured using sqlite3MutexWarnOnContention(), it is ** set to SQLITE_MUTEX_WARNONCONTENTION. */ typedef struct CheckMutex CheckMutex; struct CheckMutex { int iType; - tdsqlite3_mutex *mutex; + sqlite3_mutex *mutex; }; #define SQLITE_MUTEX_WARNONCONTENTION (-1) @@ -29808,13 +29808,13 @@ struct CheckMutex { ** Pointer to real mutex methods object used by the CheckMutex ** implementation. Set by checkMutexInit(). */ -static SQLITE_WSD const tdsqlite3_mutex_methods *pGlobalMutexMethods; +static SQLITE_WSD const sqlite3_mutex_methods *pGlobalMutexMethods; #ifdef SQLITE_DEBUG -static int checkMutexHeld(tdsqlite3_mutex *p){ +static int checkMutexHeld(sqlite3_mutex *p){ return pGlobalMutexMethods->xMutexHeld(((CheckMutex*)p)->mutex); } -static int checkMutexNotheld(tdsqlite3_mutex *p){ +static int checkMutexNotheld(sqlite3_mutex *p){ return pGlobalMutexMethods->xMutexNotheld(((CheckMutex*)p)->mutex); } #endif @@ -29823,7 +29823,7 @@ static int checkMutexNotheld(tdsqlite3_mutex *p){ ** Initialize and deinitialize the mutex subsystem. */ static int checkMutexInit(void){ - pGlobalMutexMethods = tdsqlite3DefaultMutex(); + pGlobalMutexMethods = sqlite3DefaultMutex(); return SQLITE_OK; } static int checkMutexEnd(void){ @@ -29834,7 +29834,7 @@ static int checkMutexEnd(void){ /* ** Allocate a mutex. */ -static tdsqlite3_mutex *checkMutexAlloc(int iType){ +static sqlite3_mutex *checkMutexAlloc(int iType){ static CheckMutex staticMutexes[] = { {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0}, {7, 0}, {8, 0}, {9, 0}, @@ -29844,7 +29844,7 @@ static tdsqlite3_mutex *checkMutexAlloc(int iType){ assert( SQLITE_MUTEX_RECURSIVE==1 && SQLITE_MUTEX_FAST==0 ); if( iType<2 ){ - p = tdsqlite3MallocZero(sizeof(CheckMutex)); + p = sqlite3MallocZero(sizeof(CheckMutex)); if( p==0 ) return 0; p->iType = iType; }else{ @@ -29861,19 +29861,19 @@ static tdsqlite3_mutex *checkMutexAlloc(int iType){ p->mutex = pGlobalMutexMethods->xMutexAlloc(iType); if( p->mutex==0 ){ if( iType<2 ){ - tdsqlite3_free(p); + sqlite3_free(p); } p = 0; } } - return (tdsqlite3_mutex*)p; + return (sqlite3_mutex*)p; } /* ** Free a mutex. */ -static void checkMutexFree(tdsqlite3_mutex *p){ +static void checkMutexFree(sqlite3_mutex *p){ assert( SQLITE_MUTEX_RECURSIVE<2 ); assert( SQLITE_MUTEX_FAST<2 ); assert( SQLITE_MUTEX_WARNONCONTENTION<2 ); @@ -29884,7 +29884,7 @@ static void checkMutexFree(tdsqlite3_mutex *p){ { CheckMutex *pCheck = (CheckMutex*)p; pGlobalMutexMethods->xMutexFree(pCheck->mutex); - tdsqlite3_free(pCheck); + sqlite3_free(pCheck); } #ifdef SQLITE_ENABLE_API_ARMOR else{ @@ -29896,13 +29896,13 @@ static void checkMutexFree(tdsqlite3_mutex *p){ /* ** Enter the mutex. */ -static void checkMutexEnter(tdsqlite3_mutex *p){ +static void checkMutexEnter(sqlite3_mutex *p){ CheckMutex *pCheck = (CheckMutex*)p; if( pCheck->iType==SQLITE_MUTEX_WARNONCONTENTION ){ if( SQLITE_OK==pGlobalMutexMethods->xMutexTry(pCheck->mutex) ){ return; } - tdsqlite3_log(SQLITE_MISUSE, + sqlite3_log(SQLITE_MISUSE, "illegal multi-threaded access to database connection" ); } @@ -29912,7 +29912,7 @@ static void checkMutexEnter(tdsqlite3_mutex *p){ /* ** Enter the mutex (do not block). */ -static int checkMutexTry(tdsqlite3_mutex *p){ +static int checkMutexTry(sqlite3_mutex *p){ CheckMutex *pCheck = (CheckMutex*)p; return pGlobalMutexMethods->xMutexTry(pCheck->mutex); } @@ -29920,13 +29920,13 @@ static int checkMutexTry(tdsqlite3_mutex *p){ /* ** Leave the mutex. */ -static void checkMutexLeave(tdsqlite3_mutex *p){ +static void checkMutexLeave(sqlite3_mutex *p){ CheckMutex *pCheck = (CheckMutex*)p; pGlobalMutexMethods->xMutexLeave(pCheck->mutex); } -tdsqlite3_mutex_methods const *multiThreadedCheckMutex(void){ - static const tdsqlite3_mutex_methods sMutex = { +sqlite3_mutex_methods const *multiThreadedCheckMutex(void){ + static const sqlite3_mutex_methods sMutex = { checkMutexInit, checkMutexEnd, checkMutexAlloc, @@ -29949,8 +29949,8 @@ tdsqlite3_mutex_methods const *multiThreadedCheckMutex(void){ ** Mark the SQLITE_MUTEX_RECURSIVE mutex passed as the only argument as ** one on which there should be no contention. */ -SQLITE_PRIVATE void tdsqlite3MutexWarnOnContention(tdsqlite3_mutex *p){ - if( tdsqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){ +SQLITE_PRIVATE void sqlite3MutexWarnOnContention(sqlite3_mutex *p){ + if( sqlite3GlobalConfig.mutex.xMutexAlloc==checkMutexAlloc ){ CheckMutex *pCheck = (CheckMutex*)p; assert( pCheck->iType==SQLITE_MUTEX_RECURSIVE ); pCheck->iType = SQLITE_MUTEX_WARNONCONTENTION; @@ -29961,25 +29961,25 @@ SQLITE_PRIVATE void tdsqlite3MutexWarnOnContention(tdsqlite3_mutex *p){ /* ** Initialize the mutex system. */ -SQLITE_PRIVATE int tdsqlite3MutexInit(void){ +SQLITE_PRIVATE int sqlite3MutexInit(void){ int rc = SQLITE_OK; - if( !tdsqlite3GlobalConfig.mutex.xMutexAlloc ){ + if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ /* If the xMutexAlloc method has not been set, then the user did not - ** install a mutex implementation via tdsqlite3_config() prior to - ** tdsqlite3_initialize() being called. This block copies pointers to - ** the default implementation into the tdsqlite3GlobalConfig structure. + ** install a mutex implementation via sqlite3_config() prior to + ** sqlite3_initialize() being called. This block copies pointers to + ** the default implementation into the sqlite3GlobalConfig structure. */ - tdsqlite3_mutex_methods const *pFrom; - tdsqlite3_mutex_methods *pTo = &tdsqlite3GlobalConfig.mutex; + sqlite3_mutex_methods const *pFrom; + sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; - if( tdsqlite3GlobalConfig.bCoreMutex ){ + if( sqlite3GlobalConfig.bCoreMutex ){ #ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS pFrom = multiThreadedCheckMutex(); #else - pFrom = tdsqlite3DefaultMutex(); + pFrom = sqlite3DefaultMutex(); #endif }else{ - pFrom = tdsqlite3NoopMutex(); + pFrom = sqlite3NoopMutex(); } pTo->xMutexInit = pFrom->xMutexInit; pTo->xMutexEnd = pFrom->xMutexEnd; @@ -29989,11 +29989,11 @@ SQLITE_PRIVATE int tdsqlite3MutexInit(void){ pTo->xMutexLeave = pFrom->xMutexLeave; pTo->xMutexHeld = pFrom->xMutexHeld; pTo->xMutexNotheld = pFrom->xMutexNotheld; - tdsqlite3MemoryBarrier(); + sqlite3MemoryBarrier(); pTo->xMutexAlloc = pFrom->xMutexAlloc; } - assert( tdsqlite3GlobalConfig.mutex.xMutexInit ); - rc = tdsqlite3GlobalConfig.mutex.xMutexInit(); + assert( sqlite3GlobalConfig.mutex.xMutexInit ); + rc = sqlite3GlobalConfig.mutex.xMutexInit(); #ifdef SQLITE_DEBUG GLOBAL(int, mutexIsInit) = 1; @@ -30004,12 +30004,12 @@ SQLITE_PRIVATE int tdsqlite3MutexInit(void){ /* ** Shutdown the mutex system. This call frees resources allocated by -** tdsqlite3MutexInit(). +** sqlite3MutexInit(). */ -SQLITE_PRIVATE int tdsqlite3MutexEnd(void){ +SQLITE_PRIVATE int sqlite3MutexEnd(void){ int rc = SQLITE_OK; - if( tdsqlite3GlobalConfig.mutex.xMutexEnd ){ - rc = tdsqlite3GlobalConfig.mutex.xMutexEnd(); + if( sqlite3GlobalConfig.mutex.xMutexEnd ){ + rc = sqlite3GlobalConfig.mutex.xMutexEnd(); } #ifdef SQLITE_DEBUG @@ -30022,31 +30022,31 @@ SQLITE_PRIVATE int tdsqlite3MutexEnd(void){ /* ** Retrieve a pointer to a static mutex or allocate a new dynamic one. */ -SQLITE_API tdsqlite3_mutex *tdsqlite3_mutex_alloc(int id){ +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){ #ifndef SQLITE_OMIT_AUTOINIT - if( id<=SQLITE_MUTEX_RECURSIVE && tdsqlite3_initialize() ) return 0; - if( id>SQLITE_MUTEX_RECURSIVE && tdsqlite3MutexInit() ) return 0; + if( id<=SQLITE_MUTEX_RECURSIVE && sqlite3_initialize() ) return 0; + if( id>SQLITE_MUTEX_RECURSIVE && sqlite3MutexInit() ) return 0; #endif - assert( tdsqlite3GlobalConfig.mutex.xMutexAlloc ); - return tdsqlite3GlobalConfig.mutex.xMutexAlloc(id); + assert( sqlite3GlobalConfig.mutex.xMutexAlloc ); + return sqlite3GlobalConfig.mutex.xMutexAlloc(id); } -SQLITE_PRIVATE tdsqlite3_mutex *tdsqlite3MutexAlloc(int id){ - if( !tdsqlite3GlobalConfig.bCoreMutex ){ +SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ + if( !sqlite3GlobalConfig.bCoreMutex ){ return 0; } assert( GLOBAL(int, mutexIsInit) ); - assert( tdsqlite3GlobalConfig.mutex.xMutexAlloc ); - return tdsqlite3GlobalConfig.mutex.xMutexAlloc(id); + assert( sqlite3GlobalConfig.mutex.xMutexAlloc ); + return sqlite3GlobalConfig.mutex.xMutexAlloc(id); } /* ** Free a dynamic mutex. */ -SQLITE_API void tdsqlite3_mutex_free(tdsqlite3_mutex *p){ +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){ if( p ){ - assert( tdsqlite3GlobalConfig.mutex.xMutexFree ); - tdsqlite3GlobalConfig.mutex.xMutexFree(p); + assert( sqlite3GlobalConfig.mutex.xMutexFree ); + sqlite3GlobalConfig.mutex.xMutexFree(p); } } @@ -30054,10 +30054,10 @@ SQLITE_API void tdsqlite3_mutex_free(tdsqlite3_mutex *p){ ** Obtain the mutex p. If some other thread already has the mutex, block ** until it can be obtained. */ -SQLITE_API void tdsqlite3_mutex_enter(tdsqlite3_mutex *p){ +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){ if( p ){ - assert( tdsqlite3GlobalConfig.mutex.xMutexEnter ); - tdsqlite3GlobalConfig.mutex.xMutexEnter(p); + assert( sqlite3GlobalConfig.mutex.xMutexEnter ); + sqlite3GlobalConfig.mutex.xMutexEnter(p); } } @@ -30065,40 +30065,40 @@ SQLITE_API void tdsqlite3_mutex_enter(tdsqlite3_mutex *p){ ** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another ** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY. */ -SQLITE_API int tdsqlite3_mutex_try(tdsqlite3_mutex *p){ +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){ int rc = SQLITE_OK; if( p ){ - assert( tdsqlite3GlobalConfig.mutex.xMutexTry ); - return tdsqlite3GlobalConfig.mutex.xMutexTry(p); + assert( sqlite3GlobalConfig.mutex.xMutexTry ); + return sqlite3GlobalConfig.mutex.xMutexTry(p); } return rc; } /* -** The tdsqlite3_mutex_leave() routine exits a mutex that was previously +** The sqlite3_mutex_leave() routine exits a mutex that was previously ** entered by the same thread. The behavior is undefined if the mutex ** is not currently entered. If a NULL pointer is passed as an argument ** this function is a no-op. */ -SQLITE_API void tdsqlite3_mutex_leave(tdsqlite3_mutex *p){ +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){ if( p ){ - assert( tdsqlite3GlobalConfig.mutex.xMutexLeave ); - tdsqlite3GlobalConfig.mutex.xMutexLeave(p); + assert( sqlite3GlobalConfig.mutex.xMutexLeave ); + sqlite3GlobalConfig.mutex.xMutexLeave(p); } } #ifndef NDEBUG /* -** The tdsqlite3_mutex_held() and tdsqlite3_mutex_notheld() routine are +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. */ -SQLITE_API int tdsqlite3_mutex_held(tdsqlite3_mutex *p){ - assert( p==0 || tdsqlite3GlobalConfig.mutex.xMutexHeld ); - return p==0 || tdsqlite3GlobalConfig.mutex.xMutexHeld(p); +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){ + assert( p==0 || sqlite3GlobalConfig.mutex.xMutexHeld ); + return p==0 || sqlite3GlobalConfig.mutex.xMutexHeld(p); } -SQLITE_API int tdsqlite3_mutex_notheld(tdsqlite3_mutex *p){ - assert( p==0 || tdsqlite3GlobalConfig.mutex.xMutexNotheld ); - return p==0 || tdsqlite3GlobalConfig.mutex.xMutexNotheld(p); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ + assert( p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld ); + return p==0 || sqlite3GlobalConfig.mutex.xMutexNotheld(p); } #endif @@ -30125,7 +30125,7 @@ SQLITE_API int tdsqlite3_mutex_notheld(tdsqlite3_mutex *p){ ** here are place-holders. Applications can substitute working ** mutex routines at start-time using the ** -** tdsqlite3_config(SQLITE_CONFIG_MUTEX,...) +** sqlite3_config(SQLITE_CONFIG_MUTEX,...) ** ** interface. ** @@ -30145,20 +30145,20 @@ SQLITE_API int tdsqlite3_mutex_notheld(tdsqlite3_mutex *p){ */ static int noopMutexInit(void){ return SQLITE_OK; } static int noopMutexEnd(void){ return SQLITE_OK; } -static tdsqlite3_mutex *noopMutexAlloc(int id){ +static sqlite3_mutex *noopMutexAlloc(int id){ UNUSED_PARAMETER(id); - return (tdsqlite3_mutex*)8; + return (sqlite3_mutex*)8; } -static void noopMutexFree(tdsqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } -static void noopMutexEnter(tdsqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } -static int noopMutexTry(tdsqlite3_mutex *p){ +static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static int noopMutexTry(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return SQLITE_OK; } -static void noopMutexLeave(tdsqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } +static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } -SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3NoopMutex(void){ - static const tdsqlite3_mutex_methods sMutex = { +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { noopMutexInit, noopMutexEnd, noopMutexAlloc, @@ -30185,21 +30185,21 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3NoopMutex(void){ /* ** The mutex object */ -typedef struct tdsqlite3_debug_mutex { +typedef struct sqlite3_debug_mutex { int id; /* The mutex type */ int cnt; /* Number of entries without a matching leave */ -} tdsqlite3_debug_mutex; +} sqlite3_debug_mutex; /* -** The tdsqlite3_mutex_held() and tdsqlite3_mutex_notheld() routine are +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use inside assert() statements. */ -static int debugMutexHeld(tdsqlite3_mutex *pX){ - tdsqlite3_debug_mutex *p = (tdsqlite3_debug_mutex*)pX; +static int debugMutexHeld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; return p==0 || p->cnt>0; } -static int debugMutexNotheld(tdsqlite3_mutex *pX){ - tdsqlite3_debug_mutex *p = (tdsqlite3_debug_mutex*)pX; +static int debugMutexNotheld(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; return p==0 || p->cnt==0; } @@ -30210,17 +30210,17 @@ static int debugMutexInit(void){ return SQLITE_OK; } static int debugMutexEnd(void){ return SQLITE_OK; } /* -** The tdsqlite3_mutex_alloc() routine allocates a new +** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. */ -static tdsqlite3_mutex *debugMutexAlloc(int id){ - static tdsqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_VFS3 - 1]; - tdsqlite3_debug_mutex *pNew = 0; +static sqlite3_mutex *debugMutexAlloc(int id){ + static sqlite3_debug_mutex aStatic[SQLITE_MUTEX_STATIC_VFS3 - 1]; + sqlite3_debug_mutex *pNew = 0; switch( id ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { - pNew = tdsqlite3Malloc(sizeof(*pNew)); + pNew = sqlite3Malloc(sizeof(*pNew)); if( pNew ){ pNew->id = id; pNew->cnt = 0; @@ -30239,17 +30239,17 @@ static tdsqlite3_mutex *debugMutexAlloc(int id){ break; } } - return (tdsqlite3_mutex*)pNew; + return (sqlite3_mutex*)pNew; } /* ** This routine deallocates a previously allocated mutex. */ -static void debugMutexFree(tdsqlite3_mutex *pX){ - tdsqlite3_debug_mutex *p = (tdsqlite3_debug_mutex*)pX; +static void debugMutexFree(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; assert( p->cnt==0 ); if( p->id==SQLITE_MUTEX_RECURSIVE || p->id==SQLITE_MUTEX_FAST ){ - tdsqlite3_free(p); + sqlite3_free(p); }else{ #ifdef SQLITE_ENABLE_API_ARMOR (void)SQLITE_MISUSE_BKPT; @@ -30258,43 +30258,43 @@ static void debugMutexFree(tdsqlite3_mutex *pX){ } /* -** The tdsqlite3_mutex_enter() and tdsqlite3_mutex_try() routines attempt +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt ** to enter a mutex. If another thread is already within the mutex, -** tdsqlite3_mutex_enter() will block and tdsqlite3_mutex_try() will return -** SQLITE_BUSY. The tdsqlite3_mutex_try() interface returns SQLITE_OK +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ -static void debugMutexEnter(tdsqlite3_mutex *pX){ - tdsqlite3_debug_mutex *p = (tdsqlite3_debug_mutex*)pX; +static void debugMutexEnter(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); p->cnt++; } -static int debugMutexTry(tdsqlite3_mutex *pX){ - tdsqlite3_debug_mutex *p = (tdsqlite3_debug_mutex*)pX; +static int debugMutexTry(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); p->cnt++; return SQLITE_OK; } /* -** The tdsqlite3_mutex_leave() routine exits a mutex that was +** The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ -static void debugMutexLeave(tdsqlite3_mutex *pX){ - tdsqlite3_debug_mutex *p = (tdsqlite3_debug_mutex*)pX; +static void debugMutexLeave(sqlite3_mutex *pX){ + sqlite3_debug_mutex *p = (sqlite3_debug_mutex*)pX; assert( debugMutexHeld(pX) ); p->cnt--; assert( p->id==SQLITE_MUTEX_RECURSIVE || debugMutexNotheld(pX) ); } -SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3NoopMutex(void){ - static const tdsqlite3_mutex_methods sMutex = { +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ + static const sqlite3_mutex_methods sMutex = { debugMutexInit, debugMutexEnd, debugMutexAlloc, @@ -30316,8 +30316,8 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3NoopMutex(void){ ** is used regardless of the run-time threadsafety setting. */ #ifdef SQLITE_MUTEX_NOOP -SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ - return tdsqlite3NoopMutex(); +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + return sqlite3NoopMutex(); } #endif /* defined(SQLITE_MUTEX_NOOP) */ #endif /* !defined(SQLITE_MUTEX_OMIT) */ @@ -30351,7 +30351,7 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ #include /* -** The tdsqlite3_mutex.id, tdsqlite3_mutex.nRef, and tdsqlite3_mutex.owner fields +** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields ** are necessary under two condidtions: (1) Debug builds and (2) using ** home-grown mutexes. Encapsulate these conditions into a single #define. */ @@ -30364,7 +30364,7 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ /* ** Each recursive mutex is an instance of the following structure. */ -struct tdsqlite3_mutex { +struct sqlite3_mutex { pthread_mutex_t mutex; /* Mutex controlling the lock */ #if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) int id; /* Mutex type */ @@ -30385,7 +30385,7 @@ struct tdsqlite3_mutex { #endif /* -** The tdsqlite3_mutex_held() and tdsqlite3_mutex_notheld() routine are +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use only inside assert() statements. On some platforms, ** there might be race conditions that can cause these routines to ** deliver incorrect results. In particular, if pthread_equal() is @@ -30401,10 +30401,10 @@ struct tdsqlite3_mutex { ** routines are never called. */ #if !defined(NDEBUG) || defined(SQLITE_DEBUG) -static int pthreadMutexHeld(tdsqlite3_mutex *p){ +static int pthreadMutexHeld(sqlite3_mutex *p){ return (p->nRef!=0 && pthread_equal(p->owner, pthread_self())); } -static int pthreadMutexNotheld(tdsqlite3_mutex *p){ +static int pthreadMutexNotheld(sqlite3_mutex *p){ return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0; } #endif @@ -30414,7 +30414,7 @@ static int pthreadMutexNotheld(tdsqlite3_mutex *p){ ** and also for the implementation of xShmBarrier in the VFS in cases ** where SQLite is compiled without mutexes. */ -SQLITE_PRIVATE void tdsqlite3MemoryBarrier(void){ +SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ #if defined(SQLITE_MEMORY_BARRIER) SQLITE_MEMORY_BARRIER; #elif defined(__GNUC__) && GCC_VERSION>=4001000 @@ -30429,11 +30429,11 @@ static int pthreadMutexInit(void){ return SQLITE_OK; } static int pthreadMutexEnd(void){ return SQLITE_OK; } /* -** The tdsqlite3_mutex_alloc() routine allocates a new +** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. SQLite ** will unwind its stack and return an error. The argument -** to tdsqlite3_mutex_alloc() is one of these integer constants: +** to sqlite3_mutex_alloc() is one of these integer constants: ** **
    **
  • SQLITE_MUTEX_FAST @@ -30452,7 +30452,7 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } **
  • SQLITE_MUTEX_STATIC_VFS3 **
** -** The first two constants cause tdsqlite3_mutex_alloc() to create +** The first two constants cause sqlite3_mutex_alloc() to create ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. ** The mutex implementation does not need to make a distinction @@ -30462,7 +30462,7 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } ** implementation is available on the host platform, the mutex subsystem ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** -** The other allowed parameters to tdsqlite3_mutex_alloc() each return +** The other allowed parameters to sqlite3_mutex_alloc() each return ** a pointer to a static preexisting mutex. Six static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal @@ -30471,13 +30471,13 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } ** SQLITE_MUTEX_RECURSIVE. ** ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then tdsqlite3_mutex_alloc() +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() ** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ -static tdsqlite3_mutex *pthreadMutexAlloc(int iType){ - static tdsqlite3_mutex staticMutexes[] = { +static sqlite3_mutex *pthreadMutexAlloc(int iType){ + static sqlite3_mutex staticMutexes[] = { SQLITE3_MUTEX_INITIALIZER(2), SQLITE3_MUTEX_INITIALIZER(3), SQLITE3_MUTEX_INITIALIZER(4), @@ -30491,10 +30491,10 @@ static tdsqlite3_mutex *pthreadMutexAlloc(int iType){ SQLITE3_MUTEX_INITIALIZER(12), SQLITE3_MUTEX_INITIALIZER(13) }; - tdsqlite3_mutex *p; + sqlite3_mutex *p; switch( iType ){ case SQLITE_MUTEX_RECURSIVE: { - p = tdsqlite3MallocZero( sizeof(*p) ); + p = sqlite3MallocZero( sizeof(*p) ); if( p ){ #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX /* If recursive mutexes are not available, we will have to @@ -30515,7 +30515,7 @@ static tdsqlite3_mutex *pthreadMutexAlloc(int iType){ break; } case SQLITE_MUTEX_FAST: { - p = tdsqlite3MallocZero( sizeof(*p) ); + p = sqlite3MallocZero( sizeof(*p) ); if( p ){ pthread_mutex_init(&p->mutex, 0); #if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR) @@ -30547,14 +30547,14 @@ static tdsqlite3_mutex *pthreadMutexAlloc(int iType){ ** allocated mutex. SQLite is careful to deallocate every ** mutex that it allocates. */ -static void pthreadMutexFree(tdsqlite3_mutex *p){ +static void pthreadMutexFree(sqlite3_mutex *p){ assert( p->nRef==0 ); #if SQLITE_ENABLE_API_ARMOR if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) #endif { pthread_mutex_destroy(&p->mutex); - tdsqlite3_free(p); + sqlite3_free(p); } #ifdef SQLITE_ENABLE_API_ARMOR else{ @@ -30564,17 +30564,17 @@ static void pthreadMutexFree(tdsqlite3_mutex *p){ } /* -** The tdsqlite3_mutex_enter() and tdsqlite3_mutex_try() routines attempt +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt ** to enter a mutex. If another thread is already within the mutex, -** tdsqlite3_mutex_enter() will block and tdsqlite3_mutex_try() will return -** SQLITE_BUSY. The tdsqlite3_mutex_try() interface returns SQLITE_OK +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ -static void pthreadMutexEnter(tdsqlite3_mutex *p){ +static void pthreadMutexEnter(sqlite3_mutex *p){ assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX @@ -30616,7 +30616,7 @@ static void pthreadMutexEnter(tdsqlite3_mutex *p){ } #endif } -static int pthreadMutexTry(tdsqlite3_mutex *p){ +static int pthreadMutexTry(sqlite3_mutex *p){ int rc; assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) ); @@ -30668,12 +30668,12 @@ static int pthreadMutexTry(tdsqlite3_mutex *p){ } /* -** The tdsqlite3_mutex_leave() routine exits a mutex that was +** The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ -static void pthreadMutexLeave(tdsqlite3_mutex *p){ +static void pthreadMutexLeave(sqlite3_mutex *p){ assert( pthreadMutexHeld(p) ); #if SQLITE_MUTEX_NREF p->nRef--; @@ -30696,8 +30696,8 @@ static void pthreadMutexLeave(tdsqlite3_mutex *p){ #endif } -SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ - static const tdsqlite3_mutex_methods sMutex = { +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { pthreadMutexInit, pthreadMutexEnd, pthreadMutexAlloc, @@ -30815,7 +30815,7 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ #if defined(__GNUC__) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned int lo, hi; __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); return (sqlite_uint64)hi << 32 | lo; @@ -30823,7 +30823,7 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ #elif defined(_MSC_VER) - __declspec(naked) __inline sqlite_uint64 __cdecl tdsqlite3Hwtime(void){ + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ __asm { rdtsc ret ; return value at EDX:EAX @@ -30834,7 +30834,7 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long val; __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; @@ -30842,7 +30842,7 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long long retval; unsigned long junk; __asm__ __volatile__ ("\n\ @@ -30859,13 +30859,13 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ /* ** asm() is needed for hardware timing support. Without asm(), - ** disable the tdsqlite3Hwtime() routine. + ** disable the sqlite3Hwtime() routine. ** - ** tdsqlite3Hwtime() is only used for some obscure debugging + ** sqlite3Hwtime() is only used for some obscure debugging ** and analysis configurations, not in any deliverable, so this ** should not be a great loss. */ -SQLITE_PRIVATE sqlite_uint64 tdsqlite3Hwtime(void){ return ((sqlite_uint64)0); } +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } #endif @@ -30876,8 +30876,8 @@ SQLITE_PRIVATE sqlite_uint64 tdsqlite3Hwtime(void){ return ((sqlite_uint64)0); static sqlite_uint64 g_start; static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=tdsqlite3Hwtime() -#define TIMER_END g_elapsed=tdsqlite3Hwtime()-g_start +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start #define TIMER_ELAPSED g_elapsed #else #define TIMER_START @@ -30891,32 +30891,32 @@ static sqlite_uint64 g_elapsed; ** is used for testing the I/O recovery logic. */ #if defined(SQLITE_TEST) -SQLITE_API extern int tdsqlite3_io_error_hit; -SQLITE_API extern int tdsqlite3_io_error_hardhit; -SQLITE_API extern int tdsqlite3_io_error_pending; -SQLITE_API extern int tdsqlite3_io_error_persist; -SQLITE_API extern int tdsqlite3_io_error_benign; -SQLITE_API extern int tdsqlite3_diskfull_pending; -SQLITE_API extern int tdsqlite3_diskfull; -#define SimulateIOErrorBenign(X) tdsqlite3_io_error_benign=(X) +SQLITE_API extern int sqlite3_io_error_hit; +SQLITE_API extern int sqlite3_io_error_hardhit; +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_persist; +SQLITE_API extern int sqlite3_io_error_benign; +SQLITE_API extern int sqlite3_diskfull_pending; +SQLITE_API extern int sqlite3_diskfull; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) #define SimulateIOError(CODE) \ - if( (tdsqlite3_io_error_persist && tdsqlite3_io_error_hit) \ - || tdsqlite3_io_error_pending-- == 1 ) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ { local_ioerr(); CODE; } static void local_ioerr(){ IOTRACE(("IOERR\n")); - tdsqlite3_io_error_hit++; - if( !tdsqlite3_io_error_benign ) tdsqlite3_io_error_hardhit++; + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; } #define SimulateDiskfullError(CODE) \ - if( tdsqlite3_diskfull_pending ){ \ - if( tdsqlite3_diskfull_pending == 1 ){ \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ local_ioerr(); \ - tdsqlite3_diskfull = 1; \ - tdsqlite3_io_error_hit = 1; \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ CODE; \ }else{ \ - tdsqlite3_diskfull_pending--; \ + sqlite3_diskfull_pending--; \ } \ } #else @@ -30929,8 +30929,8 @@ static void local_ioerr(){ ** When testing, keep a count of the number of open files. */ #if defined(SQLITE_TEST) -SQLITE_API extern int tdsqlite3_open_file_count; -#define OpenCounter(X) tdsqlite3_open_file_count+=(X) +SQLITE_API extern int sqlite3_open_file_count; +#define OpenCounter(X) sqlite3_open_file_count+=(X) #else #define OpenCounter(X) #endif /* defined(SQLITE_TEST) */ @@ -31050,7 +31050,7 @@ SQLITE_API extern int tdsqlite3_open_file_count; /* ** Each recursive mutex is an instance of the following structure. */ -struct tdsqlite3_mutex { +struct sqlite3_mutex { CRITICAL_SECTION mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ #ifdef SQLITE_DEBUG @@ -31076,18 +31076,18 @@ struct tdsqlite3_mutex { #ifdef SQLITE_DEBUG /* -** The tdsqlite3_mutex_held() and tdsqlite3_mutex_notheld() routine are +** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are ** intended for use only inside assert() statements. */ -static int winMutexHeld(tdsqlite3_mutex *p){ +static int winMutexHeld(sqlite3_mutex *p){ return p->nRef!=0 && p->owner==GetCurrentThreadId(); } -static int winMutexNotheld2(tdsqlite3_mutex *p, DWORD tid){ +static int winMutexNotheld2(sqlite3_mutex *p, DWORD tid){ return p->nRef==0 || p->owner!=tid; } -static int winMutexNotheld(tdsqlite3_mutex *p){ +static int winMutexNotheld(sqlite3_mutex *p){ DWORD tid = GetCurrentThreadId(); return winMutexNotheld2(p, tid); } @@ -31098,7 +31098,7 @@ static int winMutexNotheld(tdsqlite3_mutex *p){ ** and also for the xShmBarrier method of the VFS in cases when SQLite is ** compiled without mutexes (SQLITE_THREADSAFE=0). */ -SQLITE_PRIVATE void tdsqlite3MemoryBarrier(void){ +SQLITE_PRIVATE void sqlite3MemoryBarrier(void){ #if defined(SQLITE_MEMORY_BARRIER) SQLITE_MEMORY_BARRIER; #elif defined(__GNUC__) @@ -31113,7 +31113,7 @@ SQLITE_PRIVATE void tdsqlite3MemoryBarrier(void){ /* ** Initialize and deinitialize the mutex subsystem. */ -static tdsqlite3_mutex winMutex_staticMutexes[] = { +static sqlite3_mutex winMutex_staticMutexes[] = { SQLITE3_MUTEX_INITIALIZER(2), SQLITE3_MUTEX_INITIALIZER(3), SQLITE3_MUTEX_INITIALIZER(4), @@ -31132,13 +31132,13 @@ static int winMutex_isInit = 0; static int winMutex_isNt = -1; /* <0 means "need to query" */ /* As the winMutexInit() and winMutexEnd() functions are called as part -** of the tdsqlite3_initialize() and tdsqlite3_shutdown() processing, the +** of the sqlite3_initialize() and sqlite3_shutdown() processing, the ** "interlocked" magic used here is probably not strictly necessary. */ static LONG SQLITE_WIN32_VOLATILE winMutex_lock = 0; -SQLITE_API int tdsqlite3_win32_is_nt(void); /* os_win.c */ -SQLITE_API void tdsqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ +SQLITE_API int sqlite3_win32_is_nt(void); /* os_win.c */ +SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ static int winMutexInit(void){ /* The first to increment to 1 does actual initialization */ @@ -31156,7 +31156,7 @@ static int winMutexInit(void){ /* Another thread is (in the process of) initializing the static ** mutexes */ while( !winMutex_isInit ){ - tdsqlite3_win32_sleep(1); + sqlite3_win32_sleep(1); } } return SQLITE_OK; @@ -31178,11 +31178,11 @@ static int winMutexEnd(void){ } /* -** The tdsqlite3_mutex_alloc() routine allocates a new +** The sqlite3_mutex_alloc() routine allocates a new ** mutex and returns a pointer to it. If it returns NULL ** that means that a mutex could not be allocated. SQLite ** will unwind its stack and return an error. The argument -** to tdsqlite3_mutex_alloc() is one of these integer constants: +** to sqlite3_mutex_alloc() is one of these integer constants: ** **
    **
  • SQLITE_MUTEX_FAST @@ -31201,7 +31201,7 @@ static int winMutexEnd(void){ **
  • SQLITE_MUTEX_STATIC_VFS3 **
** -** The first two constants cause tdsqlite3_mutex_alloc() to create +** The first two constants cause sqlite3_mutex_alloc() to create ** a new mutex. The new mutex is recursive when SQLITE_MUTEX_RECURSIVE ** is used but not necessarily so when SQLITE_MUTEX_FAST is used. ** The mutex implementation does not need to make a distinction @@ -31211,7 +31211,7 @@ static int winMutexEnd(void){ ** implementation is available on the host platform, the mutex subsystem ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** -** The other allowed parameters to tdsqlite3_mutex_alloc() each return +** The other allowed parameters to sqlite3_mutex_alloc() each return ** a pointer to a static preexisting mutex. Six static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal @@ -31220,18 +31220,18 @@ static int winMutexEnd(void){ ** SQLITE_MUTEX_RECURSIVE. ** ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST -** or SQLITE_MUTEX_RECURSIVE) is used then tdsqlite3_mutex_alloc() +** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() ** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ -static tdsqlite3_mutex *winMutexAlloc(int iType){ - tdsqlite3_mutex *p; +static sqlite3_mutex *winMutexAlloc(int iType){ + sqlite3_mutex *p; switch( iType ){ case SQLITE_MUTEX_FAST: case SQLITE_MUTEX_RECURSIVE: { - p = tdsqlite3MallocZero( sizeof(*p) ); + p = sqlite3MallocZero( sizeof(*p) ); if( p ){ p->id = iType; #ifdef SQLITE_DEBUG @@ -31273,12 +31273,12 @@ static tdsqlite3_mutex *winMutexAlloc(int iType){ ** allocated mutex. SQLite is careful to deallocate every ** mutex that it allocates. */ -static void winMutexFree(tdsqlite3_mutex *p){ +static void winMutexFree(sqlite3_mutex *p){ assert( p ); assert( p->nRef==0 && p->owner==0 ); if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ){ DeleteCriticalSection(&p->mutex); - tdsqlite3_free(p); + sqlite3_free(p); }else{ #ifdef SQLITE_ENABLE_API_ARMOR (void)SQLITE_MISUSE_BKPT; @@ -31287,17 +31287,17 @@ static void winMutexFree(tdsqlite3_mutex *p){ } /* -** The tdsqlite3_mutex_enter() and tdsqlite3_mutex_try() routines attempt +** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt ** to enter a mutex. If another thread is already within the mutex, -** tdsqlite3_mutex_enter() will block and tdsqlite3_mutex_try() will return -** SQLITE_BUSY. The tdsqlite3_mutex_try() interface returns SQLITE_OK +** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return +** SQLITE_BUSY. The sqlite3_mutex_try() interface returns SQLITE_OK ** upon successful entry. Mutexes created using SQLITE_MUTEX_RECURSIVE can ** be entered multiple times by the same thread. In such cases the, ** mutex must be exited an equal number of times before another thread ** can enter. If the same thread tries to enter any other kind of mutex ** more than once, the behavior is undefined. */ -static void winMutexEnter(tdsqlite3_mutex *p){ +static void winMutexEnter(sqlite3_mutex *p){ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) DWORD tid = GetCurrentThreadId(); #endif @@ -31320,7 +31320,7 @@ static void winMutexEnter(tdsqlite3_mutex *p){ #endif } -static int winMutexTry(tdsqlite3_mutex *p){ +static int winMutexTry(sqlite3_mutex *p){ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) DWORD tid = GetCurrentThreadId(); #endif @@ -31328,7 +31328,7 @@ static int winMutexTry(tdsqlite3_mutex *p){ assert( p ); assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld2(p, tid) ); /* - ** The tdsqlite3_mutex_try() routine is very rarely used, and when it + ** The sqlite3_mutex_try() routine is very rarely used, and when it ** is used it is merely an optimization. So it is OK for it to always ** fail. ** @@ -31342,7 +31342,7 @@ static int winMutexTry(tdsqlite3_mutex *p){ assert( winMutex_isInit==1 ); assert( winMutex_isNt>=-1 && winMutex_isNt<=1 ); if( winMutex_isNt<0 ){ - winMutex_isNt = tdsqlite3_win32_is_nt(); + winMutex_isNt = sqlite3_win32_is_nt(); } assert( winMutex_isNt==0 || winMutex_isNt==1 ); if( winMutex_isNt && TryEnterCriticalSection(&p->mutex) ){ @@ -31358,19 +31358,19 @@ static int winMutexTry(tdsqlite3_mutex *p){ #ifdef SQLITE_DEBUG if( p->trace ){ OSTRACE(("TRY-MUTEX tid=%lu, mutex(%d)=%p (%d), owner=%lu, nRef=%d, rc=%s\n", - tid, p->id, p, p->trace, p->owner, p->nRef, tdsqlite3ErrName(rc))); + tid, p->id, p, p->trace, p->owner, p->nRef, sqlite3ErrName(rc))); } #endif return rc; } /* -** The tdsqlite3_mutex_leave() routine exits a mutex that was +** The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread. The behavior ** is undefined if the mutex is not currently entered or ** is not currently allocated. SQLite will never do either. */ -static void winMutexLeave(tdsqlite3_mutex *p){ +static void winMutexLeave(sqlite3_mutex *p){ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) DWORD tid = GetCurrentThreadId(); #endif @@ -31392,8 +31392,8 @@ static void winMutexLeave(tdsqlite3_mutex *p){ #endif } -SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ - static const tdsqlite3_mutex_methods sMutex = { +SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ + static const sqlite3_mutex_methods sMutex = { winMutexInit, winMutexEnd, winMutexAlloc, @@ -31438,11 +31438,11 @@ SQLITE_PRIVATE tdsqlite3_mutex_methods const *tdsqlite3DefaultMutex(void){ ** held by SQLite. An example of non-essential memory is memory used to ** cache database pages that are not currently in use. */ -SQLITE_API int tdsqlite3_release_memory(int n){ +SQLITE_API int sqlite3_release_memory(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - return tdsqlite3PcacheReleaseMemory(n); + return sqlite3PcacheReleaseMemory(n); #else - /* IMPLEMENTATION-OF: R-34391-24921 The tdsqlite3_release_memory() routine + /* IMPLEMENTATION-OF: R-34391-24921 The sqlite3_release_memory() routine ** is a no-op returning zero if SQLite is not compiled with ** SQLITE_ENABLE_MEMORY_MANAGEMENT. */ UNUSED_PARAMETER(n); @@ -31461,13 +31461,13 @@ SQLITE_API int tdsqlite3_release_memory(int n){ ** State information local to the memory allocation subsystem. */ static SQLITE_WSD struct Mem0Global { - tdsqlite3_mutex *mutex; /* Mutex to serialize access */ - tdsqlite3_int64 alarmThreshold; /* The soft heap limit */ - tdsqlite3_int64 hardLimit; /* The hard upper bound on memory */ + sqlite3_mutex *mutex; /* Mutex to serialize access */ + sqlite3_int64 alarmThreshold; /* The soft heap limit */ + sqlite3_int64 hardLimit; /* The hard upper bound on memory */ /* ** True if heap is nearly "full" where "full" is defined by the - ** tdsqlite3_soft_heap_limit() setting. + ** sqlite3_soft_heap_limit() setting. */ int nearlyFull; } mem0 = { 0, SQLITE_MAX_MEMORY, SQLITE_MAX_MEMORY, 0 }; @@ -31475,9 +31475,9 @@ static SQLITE_WSD struct Mem0Global { #define mem0 GLOBAL(struct Mem0Global, mem0) /* -** Return the memory allocator mutex. tdsqlite3_status() needs it. +** Return the memory allocator mutex. sqlite3_status() needs it. */ -SQLITE_PRIVATE tdsqlite3_mutex *tdsqlite3MallocMutex(void){ +SQLITE_PRIVATE sqlite3_mutex *sqlite3MallocMutex(void){ return mem0.mutex; } @@ -31487,10 +31487,10 @@ SQLITE_PRIVATE tdsqlite3_mutex *tdsqlite3MallocMutex(void){ ** that was invoked when memory usage grew too large. Now it is a ** no-op. */ -SQLITE_API int tdsqlite3_memory_alarm( - void(*xCallback)(void *pArg, tdsqlite3_int64 used,int N), +SQLITE_API int sqlite3_memory_alarm( + void(*xCallback)(void *pArg, sqlite3_int64 used,int N), void *pArg, - tdsqlite3_int64 iThreshold + sqlite3_int64 iThreshold ){ (void)xCallback; (void)pArg; @@ -31510,34 +31510,34 @@ SQLITE_API int tdsqlite3_memory_alarm( ** If the hard heap limit is enabled, then the soft heap limit cannot ** be disabled nor raised above the hard heap limit. */ -SQLITE_API tdsqlite3_int64 tdsqlite3_soft_heap_limit64(tdsqlite3_int64 n){ - tdsqlite3_int64 priorLimit; - tdsqlite3_int64 excess; - tdsqlite3_int64 nUsed; +SQLITE_API sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; + sqlite3_int64 excess; + sqlite3_int64 nUsed; #ifndef SQLITE_OMIT_AUTOINIT - int rc = tdsqlite3_initialize(); + int rc = sqlite3_initialize(); if( rc ) return -1; #endif - tdsqlite3_mutex_enter(mem0.mutex); + sqlite3_mutex_enter(mem0.mutex); priorLimit = mem0.alarmThreshold; if( n<0 ){ - tdsqlite3_mutex_leave(mem0.mutex); + sqlite3_mutex_leave(mem0.mutex); return priorLimit; } if( mem0.hardLimit>0 && (n>mem0.hardLimit || n==0) ){ n = mem0.hardLimit; } mem0.alarmThreshold = n; - nUsed = tdsqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); mem0.nearlyFull = (n>0 && n<=nUsed); - tdsqlite3_mutex_leave(mem0.mutex); - excess = tdsqlite3_memory_used() - n; - if( excess>0 ) tdsqlite3_release_memory((int)(excess & 0x7fffffff)); + sqlite3_mutex_leave(mem0.mutex); + excess = sqlite3_memory_used() - n; + if( excess>0 ) sqlite3_release_memory((int)(excess & 0x7fffffff)); return priorLimit; } -SQLITE_API void tdsqlite3_soft_heap_limit(int n){ +SQLITE_API void sqlite3_soft_heap_limit(int n){ if( n<0 ) n = 0; - tdsqlite3_soft_heap_limit64(n); + sqlite3_soft_heap_limit64(n); } /* @@ -31552,13 +31552,13 @@ SQLITE_API void tdsqlite3_soft_heap_limit(int n){ ** and constrain the soft heap limit to be no more than the hard heap ** limit. */ -SQLITE_API tdsqlite3_int64 tdsqlite3_hard_heap_limit64(tdsqlite3_int64 n){ - tdsqlite3_int64 priorLimit; +SQLITE_API sqlite3_int64 sqlite3_hard_heap_limit64(sqlite3_int64 n){ + sqlite3_int64 priorLimit; #ifndef SQLITE_OMIT_AUTOINIT - int rc = tdsqlite3_initialize(); + int rc = sqlite3_initialize(); if( rc ) return -1; #endif - tdsqlite3_mutex_enter(mem0.mutex); + sqlite3_mutex_enter(mem0.mutex); priorLimit = mem0.hardLimit; if( n>=0 ){ mem0.hardLimit = n; @@ -31566,7 +31566,7 @@ SQLITE_API tdsqlite3_int64 tdsqlite3_hard_heap_limit64(tdsqlite3_int64 n){ mem0.alarmThreshold = n; } } - tdsqlite3_mutex_leave(mem0.mutex); + sqlite3_mutex_leave(mem0.mutex); return priorLimit; } @@ -31574,19 +31574,19 @@ SQLITE_API tdsqlite3_int64 tdsqlite3_hard_heap_limit64(tdsqlite3_int64 n){ /* ** Initialize the memory allocation subsystem. */ -SQLITE_PRIVATE int tdsqlite3MallocInit(void){ +SQLITE_PRIVATE int sqlite3MallocInit(void){ int rc; - if( tdsqlite3GlobalConfig.m.xMalloc==0 ){ - tdsqlite3MemSetDefault(); + if( sqlite3GlobalConfig.m.xMalloc==0 ){ + sqlite3MemSetDefault(); } memset(&mem0, 0, sizeof(mem0)); - mem0.mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); - if( tdsqlite3GlobalConfig.pPage==0 || tdsqlite3GlobalConfig.szPage<512 - || tdsqlite3GlobalConfig.nPage<=0 ){ - tdsqlite3GlobalConfig.pPage = 0; - tdsqlite3GlobalConfig.szPage = 0; + mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + if( sqlite3GlobalConfig.pPage==0 || sqlite3GlobalConfig.szPage<512 + || sqlite3GlobalConfig.nPage<=0 ){ + sqlite3GlobalConfig.pPage = 0; + sqlite3GlobalConfig.szPage = 0; } - rc = tdsqlite3GlobalConfig.m.xInit(tdsqlite3GlobalConfig.m.pAppData); + rc = sqlite3GlobalConfig.m.xInit(sqlite3GlobalConfig.m.pAppData); if( rc!=SQLITE_OK ) memset(&mem0, 0, sizeof(mem0)); /* BEGIN SQLCIPHER */ #ifdef SQLITE_HAS_CODEC @@ -31604,18 +31604,18 @@ SQLITE_PRIVATE int tdsqlite3MallocInit(void){ /* ** Return true if the heap is currently under memory pressure - in other ** words if the amount of heap used is close to the limit set by -** tdsqlite3_soft_heap_limit(). +** sqlite3_soft_heap_limit(). */ -SQLITE_PRIVATE int tdsqlite3HeapNearlyFull(void){ +SQLITE_PRIVATE int sqlite3HeapNearlyFull(void){ return mem0.nearlyFull; } /* ** Deinitialize the memory allocation subsystem. */ -SQLITE_PRIVATE void tdsqlite3MallocEnd(void){ - if( tdsqlite3GlobalConfig.m.xShutdown ){ - tdsqlite3GlobalConfig.m.xShutdown(tdsqlite3GlobalConfig.m.pAppData); +SQLITE_PRIVATE void sqlite3MallocEnd(void){ + if( sqlite3GlobalConfig.m.xShutdown ){ + sqlite3GlobalConfig.m.xShutdown(sqlite3GlobalConfig.m.pAppData); } memset(&mem0, 0, sizeof(mem0)); } @@ -31623,9 +31623,9 @@ SQLITE_PRIVATE void tdsqlite3MallocEnd(void){ /* ** Return the amount of memory currently checked out. */ -SQLITE_API tdsqlite3_int64 tdsqlite3_memory_used(void){ - tdsqlite3_int64 res, mx; - tdsqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0); +SQLITE_API sqlite3_int64 sqlite3_memory_used(void){ + sqlite3_int64 res, mx; + sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, 0); return res; } @@ -31634,20 +31634,20 @@ SQLITE_API tdsqlite3_int64 tdsqlite3_memory_used(void){ ** checked out since either the beginning of this process ** or since the most recent reset. */ -SQLITE_API tdsqlite3_int64 tdsqlite3_memory_highwater(int resetFlag){ - tdsqlite3_int64 res, mx; - tdsqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){ + sqlite3_int64 res, mx; + sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &res, &mx, resetFlag); return mx; } /* ** Trigger the alarm */ -static void tdsqlite3MallocAlarm(int nByte){ +static void sqlite3MallocAlarm(int nByte){ if( mem0.alarmThreshold<=0 ) return; - tdsqlite3_mutex_leave(mem0.mutex); - tdsqlite3_release_memory(nByte); - tdsqlite3_mutex_enter(mem0.mutex); + sqlite3_mutex_leave(mem0.mutex); + sqlite3_release_memory(nByte); + sqlite3_mutex_enter(mem0.mutex); } /* @@ -31657,7 +31657,7 @@ static void tdsqlite3MallocAlarm(int nByte){ static void mallocWithAlarm(int n, void **pp){ void *p; int nFull; - assert( tdsqlite3_mutex_held(mem0.mutex) ); + assert( sqlite3_mutex_held(mem0.mutex) ); assert( n>0 ); /* In Firefox (circa 2017-02-08), xRoundup() is remapped to an internal @@ -31665,16 +31665,16 @@ static void mallocWithAlarm(int n, void **pp){ ** mode and specifically when the DMD "Dark Matter Detector" is enabled ** or else a crash results. Hence, do not attempt to optimize out the ** following xRoundup() call. */ - nFull = tdsqlite3GlobalConfig.m.xRoundup(n); + nFull = sqlite3GlobalConfig.m.xRoundup(n); - tdsqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); + sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, n); if( mem0.alarmThreshold>0 ){ - tdsqlite3_int64 nUsed = tdsqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + sqlite3_int64 nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed >= mem0.alarmThreshold - nFull ){ mem0.nearlyFull = 1; - tdsqlite3MallocAlarm(nFull); + sqlite3MallocAlarm(nFull); if( mem0.hardLimit ){ - nUsed = tdsqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); + nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); if( nUsed >= mem0.hardLimit - nFull ){ *pp = 0; return; @@ -31684,40 +31684,40 @@ static void mallocWithAlarm(int n, void **pp){ mem0.nearlyFull = 0; } } - p = tdsqlite3GlobalConfig.m.xMalloc(nFull); + p = sqlite3GlobalConfig.m.xMalloc(nFull); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT if( p==0 && mem0.alarmThreshold>0 ){ - tdsqlite3MallocAlarm(nFull); - p = tdsqlite3GlobalConfig.m.xMalloc(nFull); + sqlite3MallocAlarm(nFull); + p = sqlite3GlobalConfig.m.xMalloc(nFull); } #endif if( p ){ - nFull = tdsqlite3MallocSize(p); - tdsqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); - tdsqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); + nFull = sqlite3MallocSize(p); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nFull); + sqlite3StatusUp(SQLITE_STATUS_MALLOC_COUNT, 1); } *pp = p; } /* -** Allocate memory. This routine is like tdsqlite3_malloc() except that it +** Allocate memory. This routine is like sqlite3_malloc() except that it ** assumes the memory subsystem has already been initialized. */ -SQLITE_PRIVATE void *tdsqlite3Malloc(u64 n){ +SQLITE_PRIVATE void *sqlite3Malloc(u64 n){ void *p; if( n==0 || n>=0x7fffff00 ){ /* A memory allocation of a number of bytes which is near the maximum ** signed integer value might cause an integer overflow inside of the ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving ** 255 bytes of overhead. SQLite itself will never use anything near - ** this amount. The only way to reach the limit is with tdsqlite3_malloc() */ + ** this amount. The only way to reach the limit is with sqlite3_malloc() */ p = 0; - }else if( tdsqlite3GlobalConfig.bMemstat ){ - tdsqlite3_mutex_enter(mem0.mutex); + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); mallocWithAlarm((int)n, &p); - tdsqlite3_mutex_leave(mem0.mutex); + sqlite3_mutex_leave(mem0.mutex); }else{ - p = tdsqlite3GlobalConfig.m.xMalloc((int)n); + p = sqlite3GlobalConfig.m.xMalloc((int)n); } assert( EIGHT_BYTE_ALIGNMENT(p) ); /* IMP: R-11148-40995 */ return p; @@ -31728,24 +31728,24 @@ SQLITE_PRIVATE void *tdsqlite3Malloc(u64 n){ ** First make sure the memory subsystem is initialized, then do the ** allocation. */ -SQLITE_API void *tdsqlite3_malloc(int n){ +SQLITE_API void *sqlite3_malloc(int n){ #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif - return n<=0 ? 0 : tdsqlite3Malloc(n); + return n<=0 ? 0 : sqlite3Malloc(n); } -SQLITE_API void *tdsqlite3_malloc64(tdsqlite3_uint64 n){ +SQLITE_API void *sqlite3_malloc64(sqlite3_uint64 n){ #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif - return tdsqlite3Malloc(n); + return sqlite3Malloc(n); } /* ** TRUE if p is a lookaside memory allocation from db */ #ifndef SQLITE_OMIT_LOOKASIDE -static int isLookaside(tdsqlite3 *db, void *p){ +static int isLookaside(sqlite3 *db, void *p){ return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd); } #else @@ -31754,29 +31754,29 @@ static int isLookaside(tdsqlite3 *db, void *p){ /* ** Return the size of a memory allocation previously obtained from -** tdsqlite3Malloc() or tdsqlite3_malloc(). +** sqlite3Malloc() or sqlite3_malloc(). */ -SQLITE_PRIVATE int tdsqlite3MallocSize(void *p){ - assert( tdsqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - return tdsqlite3GlobalConfig.m.xSize(p); +SQLITE_PRIVATE int sqlite3MallocSize(void *p){ + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return sqlite3GlobalConfig.m.xSize(p); } -static int lookasideMallocSize(tdsqlite3 *db, void *p){ +static int lookasideMallocSize(sqlite3 *db, void *p){ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE return plookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL; #else return db->lookaside.szTrue; #endif } -SQLITE_PRIVATE int tdsqlite3DbMallocSize(tdsqlite3 *db, void *p){ +SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ assert( p!=0 ); #ifdef SQLITE_DEBUG if( db==0 || !isLookaside(db,p) ){ if( db==0 ){ - assert( tdsqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); - assert( tdsqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); }else{ - assert( tdsqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( tdsqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); } } #endif @@ -31784,39 +31784,39 @@ SQLITE_PRIVATE int tdsqlite3DbMallocSize(tdsqlite3 *db, void *p){ if( ((uptr)p)<(uptr)(db->lookaside.pEnd) ){ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE if( ((uptr)p)>=(uptr)(db->lookaside.pMiddle) ){ - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); return LOOKASIDE_SMALL; } #endif if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){ - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); return db->lookaside.szTrue; } } } - return tdsqlite3GlobalConfig.m.xSize(p); + return sqlite3GlobalConfig.m.xSize(p); } -SQLITE_API tdsqlite3_uint64 tdsqlite3_msize(void *p){ - assert( tdsqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); - assert( tdsqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - return p ? tdsqlite3GlobalConfig.m.xSize(p) : 0; +SQLITE_API sqlite3_uint64 sqlite3_msize(void *p){ + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + return p ? sqlite3GlobalConfig.m.xSize(p) : 0; } /* -** Free memory previously obtained from tdsqlite3Malloc(). +** Free memory previously obtained from sqlite3Malloc(). */ -SQLITE_API void tdsqlite3_free(void *p){ +SQLITE_API void sqlite3_free(void *p){ if( p==0 ) return; /* IMP: R-49053-54554 */ - assert( tdsqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); - assert( tdsqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); - if( tdsqlite3GlobalConfig.bMemstat ){ - tdsqlite3_mutex_enter(mem0.mutex); - tdsqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, tdsqlite3MallocSize(p)); - tdsqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); - tdsqlite3GlobalConfig.m.xFree(p); - tdsqlite3_mutex_leave(mem0.mutex); + assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) ); + if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusDown(SQLITE_STATUS_MEMORY_USED, sqlite3MallocSize(p)); + sqlite3StatusDown(SQLITE_STATUS_MALLOC_COUNT, 1); + sqlite3GlobalConfig.m.xFree(p); + sqlite3_mutex_leave(mem0.mutex); }else{ - tdsqlite3GlobalConfig.m.xFree(p); + sqlite3GlobalConfig.m.xFree(p); } } @@ -31824,17 +31824,17 @@ SQLITE_API void tdsqlite3_free(void *p){ ** Add the size of memory allocation "p" to the count in ** *db->pnBytesFreed. */ -static SQLITE_NOINLINE void measureAllocationSize(tdsqlite3 *db, void *p){ - *db->pnBytesFreed += tdsqlite3DbMallocSize(db,p); +static SQLITE_NOINLINE void measureAllocationSize(sqlite3 *db, void *p){ + *db->pnBytesFreed += sqlite3DbMallocSize(db,p); } /* ** Free memory that might be associated with a particular database -** connection. Calling tdsqlite3DbFree(D,X) for X==0 is a harmless no-op. -** The tdsqlite3DbFreeNN(D,X) version requires that X be non-NULL. +** connection. Calling sqlite3DbFree(D,X) for X==0 is a harmless no-op. +** The sqlite3DbFreeNN(D,X) version requires that X be non-NULL. */ -SQLITE_PRIVATE void tdsqlite3DbFreeNN(tdsqlite3 *db, void *p){ - assert( db==0 || tdsqlite3_mutex_held(db->mutex) ); +SQLITE_PRIVATE void sqlite3DbFreeNN(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); assert( p!=0 ); if( db ){ if( db->pnBytesFreed ){ @@ -31864,92 +31864,92 @@ SQLITE_PRIVATE void tdsqlite3DbFreeNN(tdsqlite3 *db, void *p){ } } } - assert( tdsqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( tdsqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( db!=0 || tdsqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); - tdsqlite3MemdebugSetType(p, MEMTYPE_HEAP); - tdsqlite3_free(p); + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( db!=0 || sqlite3MemdebugNoType(p, MEMTYPE_LOOKASIDE) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + sqlite3_free(p); } -SQLITE_PRIVATE void tdsqlite3DbFree(tdsqlite3 *db, void *p){ - assert( db==0 || tdsqlite3_mutex_held(db->mutex) ); - if( p ) tdsqlite3DbFreeNN(db, p); +SQLITE_PRIVATE void sqlite3DbFree(sqlite3 *db, void *p){ + assert( db==0 || sqlite3_mutex_held(db->mutex) ); + if( p ) sqlite3DbFreeNN(db, p); } /* ** Change the size of an existing memory allocation */ -SQLITE_PRIVATE void *tdsqlite3Realloc(void *pOld, u64 nBytes){ +SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, u64 nBytes){ int nOld, nNew, nDiff; void *pNew; - assert( tdsqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); - assert( tdsqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) ); + assert( sqlite3MemdebugHasType(pOld, MEMTYPE_HEAP) ); + assert( sqlite3MemdebugNoType(pOld, (u8)~MEMTYPE_HEAP) ); if( pOld==0 ){ - return tdsqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ + return sqlite3Malloc(nBytes); /* IMP: R-04300-56712 */ } if( nBytes==0 ){ - tdsqlite3_free(pOld); /* IMP: R-26507-47431 */ + sqlite3_free(pOld); /* IMP: R-26507-47431 */ return 0; } if( nBytes>=0x7fffff00 ){ - /* The 0x7ffff00 limit term is explained in comments on tdsqlite3Malloc() */ + /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ return 0; } - nOld = tdsqlite3MallocSize(pOld); + nOld = sqlite3MallocSize(pOld); /* IMPLEMENTATION-OF: R-46199-30249 SQLite guarantees that the second ** argument to xRealloc is always a value returned by a prior call to ** xRoundup. */ - nNew = tdsqlite3GlobalConfig.m.xRoundup((int)nBytes); + nNew = sqlite3GlobalConfig.m.xRoundup((int)nBytes); if( nOld==nNew ){ pNew = pOld; - }else if( tdsqlite3GlobalConfig.bMemstat ){ - tdsqlite3_mutex_enter(mem0.mutex); - tdsqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); + }else if( sqlite3GlobalConfig.bMemstat ){ + sqlite3_mutex_enter(mem0.mutex); + sqlite3StatusHighwater(SQLITE_STATUS_MALLOC_SIZE, (int)nBytes); nDiff = nNew - nOld; - if( nDiff>0 && tdsqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= + if( nDiff>0 && sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED) >= mem0.alarmThreshold-nDiff ){ - tdsqlite3MallocAlarm(nDiff); + sqlite3MallocAlarm(nDiff); } - pNew = tdsqlite3GlobalConfig.m.xRealloc(pOld, nNew); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); if( pNew==0 && mem0.alarmThreshold>0 ){ - tdsqlite3MallocAlarm((int)nBytes); - pNew = tdsqlite3GlobalConfig.m.xRealloc(pOld, nNew); + sqlite3MallocAlarm((int)nBytes); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); } if( pNew ){ - nNew = tdsqlite3MallocSize(pNew); - tdsqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld); + nNew = sqlite3MallocSize(pNew); + sqlite3StatusUp(SQLITE_STATUS_MEMORY_USED, nNew-nOld); } - tdsqlite3_mutex_leave(mem0.mutex); + sqlite3_mutex_leave(mem0.mutex); }else{ - pNew = tdsqlite3GlobalConfig.m.xRealloc(pOld, nNew); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); } assert( EIGHT_BYTE_ALIGNMENT(pNew) ); /* IMP: R-11148-40995 */ return pNew; } /* -** The public interface to tdsqlite3Realloc. Make sure that the memory +** The public interface to sqlite3Realloc. Make sure that the memory ** subsystem is initialized prior to invoking sqliteRealloc. */ -SQLITE_API void *tdsqlite3_realloc(void *pOld, int n){ +SQLITE_API void *sqlite3_realloc(void *pOld, int n){ #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif if( n<0 ) n = 0; /* IMP: R-26507-47431 */ - return tdsqlite3Realloc(pOld, n); + return sqlite3Realloc(pOld, n); } -SQLITE_API void *tdsqlite3_realloc64(void *pOld, tdsqlite3_uint64 n){ +SQLITE_API void *sqlite3_realloc64(void *pOld, sqlite3_uint64 n){ #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif - return tdsqlite3Realloc(pOld, n); + return sqlite3Realloc(pOld, n); } /* ** Allocate and zero memory. */ -SQLITE_PRIVATE void *tdsqlite3MallocZero(u64 n){ - void *p = tdsqlite3Malloc(n); +SQLITE_PRIVATE void *sqlite3MallocZero(u64 n){ + void *p = sqlite3Malloc(n); if( p ){ memset(p, 0, (size_t)n); } @@ -31960,24 +31960,24 @@ SQLITE_PRIVATE void *tdsqlite3MallocZero(u64 n){ ** Allocate and zero memory. If the allocation fails, make ** the mallocFailed flag in the connection pointer. */ -SQLITE_PRIVATE void *tdsqlite3DbMallocZero(tdsqlite3 *db, u64 n){ +SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, u64 n){ void *p; testcase( db==0 ); - p = tdsqlite3DbMallocRaw(db, n); + p = sqlite3DbMallocRaw(db, n); if( p ) memset(p, 0, (size_t)n); return p; } -/* Finish the work of tdsqlite3DbMallocRawNN for the unusual and +/* Finish the work of sqlite3DbMallocRawNN for the unusual and ** slower case when the allocation cannot be fulfilled using lookaside. */ -static SQLITE_NOINLINE void *dbMallocRawFinish(tdsqlite3 *db, u64 n){ +static SQLITE_NOINLINE void *dbMallocRawFinish(sqlite3 *db, u64 n){ void *p; assert( db!=0 ); - p = tdsqlite3Malloc(n); - if( !p ) tdsqlite3OomFault(db); - tdsqlite3MemdebugSetType(p, + p = sqlite3Malloc(n); + if( !p ) sqlite3OomFault(db); + sqlite3MemdebugSetType(p, (db->lookaside.bDisable==0) ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP); return p; } @@ -31994,28 +31994,28 @@ static SQLITE_NOINLINE void *dbMallocRawFinish(tdsqlite3 *db, u64 n){ ** This is an important assumption. There are many places in the ** code that do things like this: ** -** int *a = (int*)tdsqlite3DbMallocRaw(db, 100); -** int *b = (int*)tdsqlite3DbMallocRaw(db, 200); +** int *a = (int*)sqlite3DbMallocRaw(db, 100); +** int *b = (int*)sqlite3DbMallocRaw(db, 200); ** if( b ) a[10] = 9; ** ** In other words, if a subsequent malloc (ex: "b") worked, it is assumed ** that all prior mallocs (ex: "a") worked too. ** -** The tdsqlite3MallocRawNN() variant guarantees that the "db" parameter is +** The sqlite3MallocRawNN() variant guarantees that the "db" parameter is ** not a NULL pointer. */ -SQLITE_PRIVATE void *tdsqlite3DbMallocRaw(tdsqlite3 *db, u64 n){ +SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, u64 n){ void *p; - if( db ) return tdsqlite3DbMallocRawNN(db, n); - p = tdsqlite3Malloc(n); - tdsqlite3MemdebugSetType(p, MEMTYPE_HEAP); + if( db ) return sqlite3DbMallocRawNN(db, n); + p = sqlite3Malloc(n); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); return p; } -SQLITE_PRIVATE void *tdsqlite3DbMallocRawNN(tdsqlite3 *db, u64 n){ +SQLITE_PRIVATE void *sqlite3DbMallocRawNN(sqlite3 *db, u64 n){ #ifndef SQLITE_OMIT_LOOKASIDE LookasideSlot *pBuf; assert( db!=0 ); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); if( n>db->lookaside.sz ){ if( !db->lookaside.bDisable ){ @@ -32051,7 +32051,7 @@ SQLITE_PRIVATE void *tdsqlite3DbMallocRawNN(tdsqlite3 *db, u64 n){ } #else assert( db!=0 ); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); assert( db->pnBytesFreed==0 ); if( db->mallocFailed ){ return 0; @@ -32061,16 +32061,16 @@ SQLITE_PRIVATE void *tdsqlite3DbMallocRawNN(tdsqlite3 *db, u64 n){ } /* Forward declaration */ -static SQLITE_NOINLINE void *dbReallocFinish(tdsqlite3 *db, void *p, u64 n); +static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n); /* ** Resize the block of memory pointed to by p to n bytes. If the ** resize fails, set the mallocFailed flag in the connection object. */ -SQLITE_PRIVATE void *tdsqlite3DbRealloc(tdsqlite3 *db, void *p, u64 n){ +SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *db, void *p, u64 n){ assert( db!=0 ); - if( p==0 ) return tdsqlite3DbMallocRawNN(db, n); - assert( tdsqlite3_mutex_held(db->mutex) ); + if( p==0 ) return sqlite3DbMallocRawNN(db, n); + assert( sqlite3_mutex_held(db->mutex) ); if( ((uptr)p)<(uptr)db->lookaside.pEnd ){ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE if( ((uptr)p)>=(uptr)db->lookaside.pMiddle ){ @@ -32083,26 +32083,26 @@ SQLITE_PRIVATE void *tdsqlite3DbRealloc(tdsqlite3 *db, void *p, u64 n){ } return dbReallocFinish(db, p, n); } -static SQLITE_NOINLINE void *dbReallocFinish(tdsqlite3 *db, void *p, u64 n){ +static SQLITE_NOINLINE void *dbReallocFinish(sqlite3 *db, void *p, u64 n){ void *pNew = 0; assert( db!=0 ); assert( p!=0 ); if( db->mallocFailed==0 ){ if( isLookaside(db, p) ){ - pNew = tdsqlite3DbMallocRawNN(db, n); + pNew = sqlite3DbMallocRawNN(db, n); if( pNew ){ memcpy(pNew, p, lookasideMallocSize(db, p)); - tdsqlite3DbFree(db, p); + sqlite3DbFree(db, p); } }else{ - assert( tdsqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - assert( tdsqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); - tdsqlite3MemdebugSetType(p, MEMTYPE_HEAP); - pNew = tdsqlite3_realloc64(p, n); + assert( sqlite3MemdebugHasType(p, (MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + assert( sqlite3MemdebugNoType(p, (u8)~(MEMTYPE_LOOKASIDE|MEMTYPE_HEAP)) ); + sqlite3MemdebugSetType(p, MEMTYPE_HEAP); + pNew = sqlite3_realloc64(p, n); if( !pNew ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); } - tdsqlite3MemdebugSetType(pNew, + sqlite3MemdebugSetType(pNew, (db->lookaside.bDisable==0 ? MEMTYPE_LOOKASIDE : MEMTYPE_HEAP)); } } @@ -32113,43 +32113,43 @@ static SQLITE_NOINLINE void *dbReallocFinish(tdsqlite3 *db, void *p, u64 n){ ** Attempt to reallocate p. If the reallocation fails, then free p ** and set the mallocFailed flag in the database connection. */ -SQLITE_PRIVATE void *tdsqlite3DbReallocOrFree(tdsqlite3 *db, void *p, u64 n){ +SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *db, void *p, u64 n){ void *pNew; - pNew = tdsqlite3DbRealloc(db, p, n); + pNew = sqlite3DbRealloc(db, p, n); if( !pNew ){ - tdsqlite3DbFree(db, p); + sqlite3DbFree(db, p); } return pNew; } /* ** Make a copy of a string in memory obtained from sqliteMalloc(). These -** functions call tdsqlite3MallocRaw() directly instead of sqliteMalloc(). This +** functions call sqlite3MallocRaw() directly instead of sqliteMalloc(). This ** is because when memory debugging is turned on, these two functions are ** called via macros that record the current file and line number in the ** ThreadData structure. */ -SQLITE_PRIVATE char *tdsqlite3DbStrDup(tdsqlite3 *db, const char *z){ +SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3 *db, const char *z){ char *zNew; size_t n; if( z==0 ){ return 0; } n = strlen(z) + 1; - zNew = tdsqlite3DbMallocRaw(db, n); + zNew = sqlite3DbMallocRaw(db, n); if( zNew ){ memcpy(zNew, z, n); } return zNew; } -SQLITE_PRIVATE char *tdsqlite3DbStrNDup(tdsqlite3 *db, const char *z, u64 n){ +SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3 *db, const char *z, u64 n){ char *zNew; assert( db!=0 ); if( z==0 ){ return 0; } assert( (n&0x7fffffff)==n ); - zNew = tdsqlite3DbMallocRawNN(db, n+1); + zNew = sqlite3DbMallocRawNN(db, n+1); if( zNew ){ memcpy(zNew, z, (size_t)n); zNew[n] = 0; @@ -32160,22 +32160,22 @@ SQLITE_PRIVATE char *tdsqlite3DbStrNDup(tdsqlite3 *db, const char *z, u64 n){ /* ** The text between zStart and zEnd represents a phrase within a larger ** SQL statement. Make a copy of this phrase in space obtained form -** tdsqlite3DbMalloc(). Omit leading and trailing whitespace. +** sqlite3DbMalloc(). Omit leading and trailing whitespace. */ -SQLITE_PRIVATE char *tdsqlite3DbSpanDup(tdsqlite3 *db, const char *zStart, const char *zEnd){ +SQLITE_PRIVATE char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ int n; - while( tdsqlite3Isspace(zStart[0]) ) zStart++; + while( sqlite3Isspace(zStart[0]) ) zStart++; n = (int)(zEnd - zStart); - while( ALWAYS(n>0) && tdsqlite3Isspace(zStart[n-1]) ) n--; - return tdsqlite3DbStrNDup(db, zStart, n); + while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--; + return sqlite3DbStrNDup(db, zStart, n); } /* ** Free any prior content in *pz and replace it with a copy of zNew. */ -SQLITE_PRIVATE void tdsqlite3SetString(char **pz, tdsqlite3 *db, const char *zNew){ - tdsqlite3DbFree(db, *pz); - *pz = tdsqlite3DbStrDup(db, zNew); +SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){ + sqlite3DbFree(db, *pz); + *pz = sqlite3DbStrDup(db, zNew); } /* @@ -32184,7 +32184,7 @@ SQLITE_PRIVATE void tdsqlite3SetString(char **pz, tdsqlite3 *db, const char *zNe ** temporarily disable the lookaside memory allocator and interrupt ** any running VDBEs. */ -SQLITE_PRIVATE void tdsqlite3OomFault(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3OomFault(sqlite3 *db){ if( db->mallocFailed==0 && db->bBenignMalloc==0 ){ db->mallocFailed = 1; if( db->nVdbeExec>0 ){ @@ -32204,7 +32204,7 @@ SQLITE_PRIVATE void tdsqlite3OomFault(tdsqlite3 *db){ ** The memory allocator is not restarted if there are running ** VDBEs. */ -SQLITE_PRIVATE void tdsqlite3OomClear(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3OomClear(sqlite3 *db){ if( db->mallocFailed && db->nVdbeExec==0 ){ db->mallocFailed = 0; db->u1.isInterrupted = 0; @@ -32216,31 +32216,31 @@ SQLITE_PRIVATE void tdsqlite3OomClear(tdsqlite3 *db){ /* ** Take actions at the end of an API call to indicate an OOM error */ -static SQLITE_NOINLINE int apiOomError(tdsqlite3 *db){ - tdsqlite3OomClear(db); - tdsqlite3Error(db, SQLITE_NOMEM); +static SQLITE_NOINLINE int apiOomError(sqlite3 *db){ + sqlite3OomClear(db); + sqlite3Error(db, SQLITE_NOMEM); return SQLITE_NOMEM_BKPT; } /* ** This function must be called before exiting any API function (i.e. -** returning control to the user) that has called tdsqlite3_malloc or -** tdsqlite3_realloc. +** returning control to the user) that has called sqlite3_malloc or +** sqlite3_realloc. ** ** The returned value is normally a copy of the second argument to this ** function. However, if a malloc() failure has occurred since the previous ** invocation SQLITE_NOMEM is returned instead. ** ** If an OOM as occurred, then the connection error-code (the value -** returned by tdsqlite3_errcode()) is set to SQLITE_NOMEM. +** returned by sqlite3_errcode()) is set to SQLITE_NOMEM. */ -SQLITE_PRIVATE int tdsqlite3ApiExit(tdsqlite3* db, int rc){ +SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ /* If the db handle must hold the connection handle mutex here. ** Otherwise the read (and possible write) of db->mallocFailed - ** is unsafe, as is the call to tdsqlite3Error(). + ** is unsafe, as is the call to sqlite3Error(). */ assert( db!=0 ); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); if( db->mallocFailed || rc==SQLITE_IOERR_NOMEM ){ return apiOomError(db); } @@ -32393,24 +32393,24 @@ static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ static void setStrAccumError(StrAccum *p, u8 eError){ assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG ); p->accError = eError; - if( p->mxAlloc ) tdsqlite3_str_reset(p); - if( eError==SQLITE_TOOBIG ) tdsqlite3ErrorToParser(p->db, eError); + if( p->mxAlloc ) sqlite3_str_reset(p); + if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError); } /* ** Extra argument values from a PrintfArguments object */ -static tdsqlite3_int64 getIntArg(PrintfArguments *p){ +static sqlite3_int64 getIntArg(PrintfArguments *p){ if( p->nArg<=p->nUsed ) return 0; - return tdsqlite3_value_int64(p->apArg[p->nUsed++]); + return sqlite3_value_int64(p->apArg[p->nUsed++]); } static double getDoubleArg(PrintfArguments *p){ if( p->nArg<=p->nUsed ) return 0.0; - return tdsqlite3_value_double(p->apArg[p->nUsed++]); + return sqlite3_value_double(p->apArg[p->nUsed++]); } static char *getTextArg(PrintfArguments *p){ if( p->nArg<=p->nUsed ) return 0; - return (char*)tdsqlite3_value_text(p->apArg[p->nUsed++]); + return (char*)sqlite3_value_text(p->apArg[p->nUsed++]); } /* @@ -32422,14 +32422,14 @@ static char *getTextArg(PrintfArguments *p){ ** SQL from requesting large allocations using the precision or width ** field of the printf() function. */ -static char *printfTempBuf(tdsqlite3_str *pAccum, tdsqlite3_int64 n){ +static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){ char *z; if( pAccum->accError ) return 0; if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){ setStrAccumError(pAccum, SQLITE_TOOBIG); return 0; } - z = tdsqlite3DbMallocRaw(pAccum->db, n); + z = sqlite3DbMallocRaw(pAccum->db, n); if( z==0 ){ setStrAccumError(pAccum, SQLITE_NOMEM); } @@ -32448,8 +32448,8 @@ static char *printfTempBuf(tdsqlite3_str *pAccum, tdsqlite3_int64 n){ /* ** Render a string given by "fmt" into the StrAccum object. */ -SQLITE_API void tdsqlite3_str_vappendf( - tdsqlite3_str *pAccum, /* Accumulate results here */ +SQLITE_API void sqlite3_str_vappendf( + sqlite3_str *pAccum, /* Accumulate results here */ const char *fmt, /* Format string */ va_list ap /* arguments */ ){ @@ -32506,11 +32506,11 @@ SQLITE_API void tdsqlite3_str_vappendf( #else do{ fmt++; }while( *fmt && *fmt != '%' ); #endif - tdsqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); + sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt)); if( *fmt==0 ) break; } if( (c=(*++fmt))==0 ){ - tdsqlite3_str_append(pAccum, "%", 1); + sqlite3_str_append(pAccum, "%", 1); break; } /* Find out what flags are present */ @@ -32779,7 +32779,7 @@ SQLITE_API void tdsqlite3_str_vappendf( while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; } if( xtype==etFLOAT ){ double rx = (double)realvalue; - tdsqlite3_uint64 u; + sqlite3_uint64 u; int ex; memcpy(&u, &rx, sizeof(u)); ex = -1023 + (int)((u>>52)&0x7ff); @@ -32788,7 +32788,7 @@ SQLITE_API void tdsqlite3_str_vappendf( } /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ exp = 0; - if( tdsqlite3IsNaN((double)realvalue) ){ + if( sqlite3IsNaN((double)realvalue) ){ bufpt = "NaN"; length = 3; break; @@ -32970,11 +32970,11 @@ SQLITE_API void tdsqlite3_str_vappendf( if( precision>1 ){ width -= precision-1; if( width>1 && !flag_leftjustify ){ - tdsqlite3_str_appendchar(pAccum, width-1, ' '); + sqlite3_str_appendchar(pAccum, width-1, ' '); width = 0; } while( precision-- > 1 ){ - tdsqlite3_str_append(pAccum, buf, length); + sqlite3_str_append(pAccum, buf, length); } } bufpt = buf; @@ -32997,12 +32997,12 @@ SQLITE_API void tdsqlite3_str_vappendf( && precision<0 && pAccum->accError==0 ){ - /* Special optimization for tdsqlite3_mprintf("%z..."): + /* Special optimization for sqlite3_mprintf("%z..."): ** Extend an existing memory allocation rather than creating ** a new one. */ assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 ); pAccum->zText = bufpt; - pAccum->nAlloc = tdsqlite3DbMallocSize(pAccum->db, bufpt); + pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt); pAccum->nChar = 0x7fffffff & (int)strlen(bufpt); pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED; length = 0; @@ -33086,7 +33086,7 @@ SQLITE_API void tdsqlite3_str_vappendf( pToken = va_arg(ap, Token*); assert( bArgList==0 ); if( pToken && pToken->n ){ - tdsqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); + sqlite3_str_append(pAccum, (const char*)pToken->z, pToken->n); } length = width = 0; break; @@ -33102,10 +33102,10 @@ SQLITE_API void tdsqlite3_str_vappendf( assert( bArgList==0 ); assert( k>=0 && knSrc ); if( pItem->zDatabase ){ - tdsqlite3_str_appendall(pAccum, pItem->zDatabase); - tdsqlite3_str_append(pAccum, ".", 1); + sqlite3_str_appendall(pAccum, pItem->zDatabase); + sqlite3_str_append(pAccum, ".", 1); } - tdsqlite3_str_appendall(pAccum, pItem->zName); + sqlite3_str_appendall(pAccum, pItem->zName); length = width = 0; break; } @@ -33124,15 +33124,15 @@ SQLITE_API void tdsqlite3_str_vappendf( */ width -= length; if( width>0 ){ - if( !flag_leftjustify ) tdsqlite3_str_appendchar(pAccum, width, ' '); - tdsqlite3_str_append(pAccum, bufpt, length); - if( flag_leftjustify ) tdsqlite3_str_appendchar(pAccum, width, ' '); + if( !flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); + sqlite3_str_append(pAccum, bufpt, length); + if( flag_leftjustify ) sqlite3_str_appendchar(pAccum, width, ' '); }else{ - tdsqlite3_str_append(pAccum, bufpt, length); + sqlite3_str_append(pAccum, bufpt, length); } if( zExtra ){ - tdsqlite3DbFree(pAccum->db, zExtra); + sqlite3DbFree(pAccum->db, zExtra); zExtra = 0; } }/* End for loop over the format string */ @@ -33145,7 +33145,7 @@ SQLITE_API void tdsqlite3_str_vappendf( ** Return the number of bytes of text that StrAccum is able to accept ** after the attempted enlargement. The value returned might be zero. */ -static int tdsqlite3StrAccumEnlarge(StrAccum *p, int N){ +static int sqlite3StrAccumEnlarge(StrAccum *p, int N){ char *zNew; assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */ if( p->accError ){ @@ -33166,25 +33166,25 @@ static int tdsqlite3StrAccumEnlarge(StrAccum *p, int N){ szNew += p->nChar; } if( szNew > p->mxAlloc ){ - tdsqlite3_str_reset(p); + sqlite3_str_reset(p); setStrAccumError(p, SQLITE_TOOBIG); return 0; }else{ p->nAlloc = (int)szNew; } if( p->db ){ - zNew = tdsqlite3DbRealloc(p->db, zOld, p->nAlloc); + zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc); }else{ - zNew = tdsqlite3_realloc64(zOld, p->nAlloc); + zNew = sqlite3_realloc64(zOld, p->nAlloc); } if( zNew ){ assert( p->zText!=0 || p->nChar==0 ); if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar); p->zText = zNew; - p->nAlloc = tdsqlite3DbMallocSize(p->db, zNew); + p->nAlloc = sqlite3DbMallocSize(p->db, zNew); p->printfFlags |= SQLITE_PRINTF_MALLOCED; }else{ - tdsqlite3_str_reset(p); + sqlite3_str_reset(p); setStrAccumError(p, SQLITE_NOMEM); return 0; } @@ -33195,9 +33195,9 @@ static int tdsqlite3StrAccumEnlarge(StrAccum *p, int N){ /* ** Append N copies of character c to the given string buffer. */ -SQLITE_API void tdsqlite3_str_appendchar(tdsqlite3_str *p, int N, char c){ +SQLITE_API void sqlite3_str_appendchar(sqlite3_str *p, int N, char c){ testcase( p->nChar + (i64)N > 0x7fffffff ); - if( p->nChar+(i64)N >= p->nAlloc && (N = tdsqlite3StrAccumEnlarge(p, N))<=0 ){ + if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){ return; } while( (N--)>0 ) p->zText[p->nChar++] = c; @@ -33207,12 +33207,12 @@ SQLITE_API void tdsqlite3_str_appendchar(tdsqlite3_str *p, int N, char c){ ** The StrAccum "p" is not large enough to accept N new bytes of z[]. ** So enlarge if first, then do the append. ** -** This is a helper routine to tdsqlite3_str_append() that does special-case +** This is a helper routine to sqlite3_str_append() that does special-case ** work (enlarging the buffer) using tail recursion, so that the -** tdsqlite3_str_append() routine can use fast calling semantics. +** sqlite3_str_append() routine can use fast calling semantics. */ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ - N = tdsqlite3StrAccumEnlarge(p, N); + N = sqlite3StrAccumEnlarge(p, N); if( N>0 ){ memcpy(&p->zText[p->nChar], z, N); p->nChar += N; @@ -33223,7 +33223,7 @@ static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){ ** Append N bytes of text from z to the StrAccum object. Increase the ** size of the memory allocation for StrAccum if necessary. */ -SQLITE_API void tdsqlite3_str_append(tdsqlite3_str *p, const char *z, int N){ +SQLITE_API void sqlite3_str_append(sqlite3_str *p, const char *z, int N){ assert( z!=0 || N==0 ); assert( p->zText!=0 || p->nChar==0 || p->accError ); assert( N>=0 ); @@ -33240,8 +33240,8 @@ SQLITE_API void tdsqlite3_str_append(tdsqlite3_str *p, const char *z, int N){ /* ** Append the complete text of zero-terminated string z[] to the p string. */ -SQLITE_API void tdsqlite3_str_appendall(tdsqlite3_str *p, const char *z){ - tdsqlite3_str_append(p, z, tdsqlite3Strlen30(z)); +SQLITE_API void sqlite3_str_appendall(sqlite3_str *p, const char *z){ + sqlite3_str_append(p, z, sqlite3Strlen30(z)); } @@ -33253,7 +33253,7 @@ SQLITE_API void tdsqlite3_str_appendall(tdsqlite3_str *p, const char *z){ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ char *zText; assert( p->mxAlloc>0 && !isMalloced(p) ); - zText = tdsqlite3DbMallocRaw(p->db, p->nChar+1 ); + zText = sqlite3DbMallocRaw(p->db, p->nChar+1 ); if( zText ){ memcpy(zText, p->zText, p->nChar+1); p->printfFlags |= SQLITE_PRINTF_MALLOCED; @@ -33263,7 +33263,7 @@ static SQLITE_NOINLINE char *strAccumFinishRealloc(StrAccum *p){ p->zText = zText; return zText; } -SQLITE_PRIVATE char *tdsqlite3StrAccumFinish(StrAccum *p){ +SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum *p){ if( p->zText ){ p->zText[p->nChar] = 0; if( p->mxAlloc>0 && !isMalloced(p) ){ @@ -33274,22 +33274,22 @@ SQLITE_PRIVATE char *tdsqlite3StrAccumFinish(StrAccum *p){ } /* -** This singleton is an tdsqlite3_str object that is returned if -** tdsqlite3_malloc() fails to provide space for a real one. This -** tdsqlite3_str object accepts no new text and always returns +** This singleton is an sqlite3_str object that is returned if +** sqlite3_malloc() fails to provide space for a real one. This +** sqlite3_str object accepts no new text and always returns ** an SQLITE_NOMEM error. */ -static tdsqlite3_str tdsqlite3OomStr = { +static sqlite3_str sqlite3OomStr = { 0, 0, 0, 0, 0, SQLITE_NOMEM, 0 }; -/* Finalize a string created using tdsqlite3_str_new(). +/* Finalize a string created using sqlite3_str_new(). */ -SQLITE_API char *tdsqlite3_str_finish(tdsqlite3_str *p){ +SQLITE_API char *sqlite3_str_finish(sqlite3_str *p){ char *z; - if( p!=0 && p!=&tdsqlite3OomStr ){ - z = tdsqlite3StrAccumFinish(p); - tdsqlite3_free(p); + if( p!=0 && p!=&sqlite3OomStr ){ + z = sqlite3StrAccumFinish(p); + sqlite3_free(p); }else{ z = 0; } @@ -33297,17 +33297,17 @@ SQLITE_API char *tdsqlite3_str_finish(tdsqlite3_str *p){ } /* Return any error code associated with p */ -SQLITE_API int tdsqlite3_str_errcode(tdsqlite3_str *p){ +SQLITE_API int sqlite3_str_errcode(sqlite3_str *p){ return p ? p->accError : SQLITE_NOMEM; } /* Return the current length of p in bytes */ -SQLITE_API int tdsqlite3_str_length(tdsqlite3_str *p){ +SQLITE_API int sqlite3_str_length(sqlite3_str *p){ return p ? p->nChar : 0; } /* Return the current value for p */ -SQLITE_API char *tdsqlite3_str_value(tdsqlite3_str *p){ +SQLITE_API char *sqlite3_str_value(sqlite3_str *p){ if( p==0 || p->nChar==0 ) return 0; p->zText[p->nChar] = 0; return p->zText; @@ -33316,9 +33316,9 @@ SQLITE_API char *tdsqlite3_str_value(tdsqlite3_str *p){ /* ** Reset an StrAccum string. Reclaim all malloced memory. */ -SQLITE_API void tdsqlite3_str_reset(StrAccum *p){ +SQLITE_API void sqlite3_str_reset(StrAccum *p){ if( isMalloced(p) ){ - tdsqlite3DbFree(p->db, p->zText); + sqlite3DbFree(p->db, p->zText); p->printfFlags &= ~SQLITE_PRINTF_MALLOCED; } p->nAlloc = 0; @@ -33340,7 +33340,7 @@ SQLITE_API void tdsqlite3_str_reset(StrAccum *p){ ** mx: Maximum number of bytes to accumulate. If mx==0 then no memory ** allocations will ever occur. */ -SQLITE_PRIVATE void tdsqlite3StrAccumInit(StrAccum *p, tdsqlite3 *db, char *zBase, int n, int mx){ +SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){ p->zText = zBase; p->db = db; p->nAlloc = n; @@ -33351,13 +33351,13 @@ SQLITE_PRIVATE void tdsqlite3StrAccumInit(StrAccum *p, tdsqlite3 *db, char *zBas } /* Allocate and initialize a new dynamic string object */ -SQLITE_API tdsqlite3_str *tdsqlite3_str_new(tdsqlite3 *db){ - tdsqlite3_str *p = tdsqlite3_malloc64(sizeof(*p)); +SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3 *db){ + sqlite3_str *p = sqlite3_malloc64(sizeof(*p)); if( p ){ - tdsqlite3StrAccumInit(p, 0, 0, 0, + sqlite3StrAccumInit(p, 0, 0, 0, db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH); }else{ - p = &tdsqlite3OomStr; + p = &sqlite3OomStr; } return p; } @@ -33366,18 +33366,18 @@ SQLITE_API tdsqlite3_str *tdsqlite3_str_new(tdsqlite3 *db){ ** Print into memory obtained from sqliteMalloc(). Use the internal ** %-conversion extensions. */ -SQLITE_PRIVATE char *tdsqlite3VMPrintf(tdsqlite3 *db, const char *zFormat, va_list ap){ +SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){ char *z; char zBase[SQLITE_PRINT_BUF_SIZE]; StrAccum acc; assert( db!=0 ); - tdsqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), + sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); acc.printfFlags = SQLITE_PRINTF_INTERNAL; - tdsqlite3_str_vappendf(&acc, zFormat, ap); - z = tdsqlite3StrAccumFinish(&acc); + sqlite3_str_vappendf(&acc, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); if( acc.accError==SQLITE_NOMEM ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); } return z; } @@ -33386,20 +33386,20 @@ SQLITE_PRIVATE char *tdsqlite3VMPrintf(tdsqlite3 *db, const char *zFormat, va_li ** Print into memory obtained from sqliteMalloc(). Use the internal ** %-conversion extensions. */ -SQLITE_PRIVATE char *tdsqlite3MPrintf(tdsqlite3 *db, const char *zFormat, ...){ +SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3 *db, const char *zFormat, ...){ va_list ap; char *z; va_start(ap, zFormat); - z = tdsqlite3VMPrintf(db, zFormat, ap); + z = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); return z; } /* -** Print into memory obtained from tdsqlite3_malloc(). Omit the internal +** Print into memory obtained from sqlite3_malloc(). Omit the internal ** %-conversion extensions. */ -SQLITE_API char *tdsqlite3_vmprintf(const char *zFormat, va_list ap){ +SQLITE_API char *sqlite3_vmprintf(const char *zFormat, va_list ap){ char *z; char zBase[SQLITE_PRINT_BUF_SIZE]; StrAccum acc; @@ -33411,44 +33411,44 @@ SQLITE_API char *tdsqlite3_vmprintf(const char *zFormat, va_list ap){ } #endif #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif - tdsqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); - tdsqlite3_str_vappendf(&acc, zFormat, ap); - z = tdsqlite3StrAccumFinish(&acc); + sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH); + sqlite3_str_vappendf(&acc, zFormat, ap); + z = sqlite3StrAccumFinish(&acc); return z; } /* -** Print into memory obtained from tdsqlite3_malloc()(). Omit the internal +** Print into memory obtained from sqlite3_malloc()(). Omit the internal ** %-conversion extensions. */ -SQLITE_API char *tdsqlite3_mprintf(const char *zFormat, ...){ +SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){ va_list ap; char *z; #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif va_start(ap, zFormat); - z = tdsqlite3_vmprintf(zFormat, ap); + z = sqlite3_vmprintf(zFormat, ap); va_end(ap); return z; } /* -** tdsqlite3_snprintf() works like snprintf() except that it ignores the +** sqlite3_snprintf() works like snprintf() except that it ignores the ** current locale settings. This is important for SQLite because we ** are not able to use a "," as the decimal point in place of "." as ** specified by some locales. ** -** Oops: The first two arguments of tdsqlite3_snprintf() are backwards +** Oops: The first two arguments of sqlite3_snprintf() are backwards ** from the snprintf() standard. Unfortunately, it is too late to change ** this without breaking compatibility, so we just have to live with the ** mistake. ** -** tdsqlite3_vsnprintf() is the varargs version. +** sqlite3_vsnprintf() is the varargs version. */ -SQLITE_API char *tdsqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ +SQLITE_API char *sqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_list ap){ StrAccum acc; if( n<=0 ) return zBuf; #ifdef SQLITE_ENABLE_API_ARMOR @@ -33458,50 +33458,50 @@ SQLITE_API char *tdsqlite3_vsnprintf(int n, char *zBuf, const char *zFormat, va_ return zBuf; } #endif - tdsqlite3StrAccumInit(&acc, 0, zBuf, n, 0); - tdsqlite3_str_vappendf(&acc, zFormat, ap); + sqlite3StrAccumInit(&acc, 0, zBuf, n, 0); + sqlite3_str_vappendf(&acc, zFormat, ap); zBuf[acc.nChar] = 0; return zBuf; } -SQLITE_API char *tdsqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ +SQLITE_API char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){ char *z; va_list ap; va_start(ap,zFormat); - z = tdsqlite3_vsnprintf(n, zBuf, zFormat, ap); + z = sqlite3_vsnprintf(n, zBuf, zFormat, ap); va_end(ap); return z; } /* -** This is the routine that actually formats the tdsqlite3_log() message. -** We house it in a separate routine from tdsqlite3_log() to avoid using +** This is the routine that actually formats the sqlite3_log() message. +** We house it in a separate routine from sqlite3_log() to avoid using ** stack space on small-stack systems when logging is disabled. ** -** tdsqlite3_log() must render into a static buffer. It cannot dynamically +** sqlite3_log() must render into a static buffer. It cannot dynamically ** allocate memory because it might be called while the memory allocator ** mutex is held. ** -** tdsqlite3_str_vappendf() might ask for *temporary* memory allocations for +** sqlite3_str_vappendf() might ask for *temporary* memory allocations for ** certain format characters (%q) or for very large precisions or widths. -** Care must be taken that any tdsqlite3_log() calls that occur while the +** Care must be taken that any sqlite3_log() calls that occur while the ** memory mutex is held do not use these mechanisms. */ static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){ StrAccum acc; /* String accumulator */ char zMsg[SQLITE_PRINT_BUF_SIZE*3]; /* Complete log message */ - tdsqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); - tdsqlite3_str_vappendf(&acc, zFormat, ap); - tdsqlite3GlobalConfig.xLog(tdsqlite3GlobalConfig.pLogArg, iErrCode, - tdsqlite3StrAccumFinish(&acc)); + sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0); + sqlite3_str_vappendf(&acc, zFormat, ap); + sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode, + sqlite3StrAccumFinish(&acc)); } /* ** Format and write a message to the log if logging is enabled. */ -SQLITE_API void tdsqlite3_log(int iErrCode, const char *zFormat, ...){ +SQLITE_API void sqlite3_log(int iErrCode, const char *zFormat, ...){ va_list ap; /* Vararg list */ - if( tdsqlite3GlobalConfig.xLog ){ + if( sqlite3GlobalConfig.xLog ){ va_start(ap, zFormat); renderLogMsg(iErrCode, zFormat, ap); va_end(ap); @@ -33514,15 +33514,15 @@ SQLITE_API void tdsqlite3_log(int iErrCode, const char *zFormat, ...){ ** The printf() built into some versions of windows does not understand %lld ** and segfaults if you give it a long long int. */ -SQLITE_PRIVATE void tdsqlite3DebugPrintf(const char *zFormat, ...){ +SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ va_list ap; StrAccum acc; char zBuf[500]; - tdsqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); va_start(ap,zFormat); - tdsqlite3_str_vappendf(&acc, zFormat, ap); + sqlite3_str_vappendf(&acc, zFormat, ap); va_end(ap); - tdsqlite3StrAccumFinish(&acc); + sqlite3StrAccumFinish(&acc); #ifdef SQLITE_OS_TRACE_PROC { extern void SQLITE_OS_TRACE_PROC(const char *zBuf, int nBuf); @@ -33537,13 +33537,13 @@ SQLITE_PRIVATE void tdsqlite3DebugPrintf(const char *zFormat, ...){ /* -** variable-argument wrapper around tdsqlite3_str_vappendf(). The bFlags argument +** variable-argument wrapper around sqlite3_str_vappendf(). The bFlags argument ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats. */ -SQLITE_API void tdsqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ +SQLITE_API void sqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ va_list ap; va_start(ap,zFormat); - tdsqlite3_str_vappendf(p, zFormat, ap); + sqlite3_str_vappendf(p, zFormat, ap); va_end(ap); } @@ -33575,9 +33575,9 @@ SQLITE_API void tdsqlite3_str_appendf(StrAccum *p, const char *zFormat, ...){ ** Add a new subitem to the tree. The moreToFollow flag indicates that this ** is not the last item in the tree. */ -static TreeView *tdsqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ +static TreeView *sqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ if( p==0 ){ - p = tdsqlite3_malloc64( sizeof(*p) ); + p = sqlite3_malloc64( sizeof(*p) ); if( p==0 ) return 0; memset(p, 0, sizeof(*p)); }else{ @@ -33591,36 +33591,36 @@ static TreeView *tdsqlite3TreeViewPush(TreeView *p, u8 moreToFollow){ /* ** Finished with one layer of the tree */ -static void tdsqlite3TreeViewPop(TreeView *p){ +static void sqlite3TreeViewPop(TreeView *p){ if( p==0 ) return; p->iLevel--; - if( p->iLevel<0 ) tdsqlite3_free(p); + if( p->iLevel<0 ) sqlite3_free(p); } /* ** Generate a single line of output for the tree, with a prefix that contains ** all the appropriate tree lines */ -static void tdsqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ +static void sqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ va_list ap; int i; StrAccum acc; char zBuf[500]; - tdsqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); if( p ){ for(i=0; iiLevel && ibLine)-1; i++){ - tdsqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4); + sqlite3_str_append(&acc, p->bLine[i] ? "| " : " ", 4); } - tdsqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); + sqlite3_str_append(&acc, p->bLine[i] ? "|-- " : "'-- ", 4); } if( zFormat!=0 ){ va_start(ap, zFormat); - tdsqlite3_str_vappendf(&acc, zFormat, ap); + sqlite3_str_vappendf(&acc, zFormat, ap); va_end(ap); assert( acc.nChar>0 || acc.accError ); - tdsqlite3_str_append(&acc, "\n", 1); + sqlite3_str_append(&acc, "\n", 1); } - tdsqlite3StrAccumFinish(&acc); + sqlite3StrAccumFinish(&acc); fprintf(stdout,"%s", zBuf); fflush(stdout); } @@ -33628,112 +33628,112 @@ static void tdsqlite3TreeViewLine(TreeView *p, const char *zFormat, ...){ /* ** Shorthand for starting a new tree item that consists of a single label */ -static void tdsqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ - p = tdsqlite3TreeViewPush(p, moreFollows); - tdsqlite3TreeViewLine(p, "%s", zLabel); +static void sqlite3TreeViewItem(TreeView *p, const char *zLabel,u8 moreFollows){ + p = sqlite3TreeViewPush(p, moreFollows); + sqlite3TreeViewLine(p, "%s", zLabel); } /* ** Generate a human-readable description of a WITH clause. */ -SQLITE_PRIVATE void tdsqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ +SQLITE_PRIVATE void sqlite3TreeViewWith(TreeView *pView, const With *pWith, u8 moreToFollow){ int i; if( pWith==0 ) return; if( pWith->nCte==0 ) return; if( pWith->pOuter ){ - tdsqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter); + sqlite3TreeViewLine(pView, "WITH (0x%p, pOuter=0x%p)",pWith,pWith->pOuter); }else{ - tdsqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); + sqlite3TreeViewLine(pView, "WITH (0x%p)", pWith); } if( pWith->nCte>0 ){ - pView = tdsqlite3TreeViewPush(pView, 1); + pView = sqlite3TreeViewPush(pView, 1); for(i=0; inCte; i++){ StrAccum x; char zLine[1000]; const struct Cte *pCte = &pWith->a[i]; - tdsqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - tdsqlite3_str_appendf(&x, "%s", pCte->zName); + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + sqlite3_str_appendf(&x, "%s", pCte->zName); if( pCte->pCols && pCte->pCols->nExpr>0 ){ char cSep = '('; int j; for(j=0; jpCols->nExpr; j++){ - tdsqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName); + sqlite3_str_appendf(&x, "%c%s", cSep, pCte->pCols->a[j].zEName); cSep = ','; } - tdsqlite3_str_appendf(&x, ")"); + sqlite3_str_appendf(&x, ")"); } - tdsqlite3_str_appendf(&x, " AS"); - tdsqlite3StrAccumFinish(&x); - tdsqlite3TreeViewItem(pView, zLine, inCte-1); - tdsqlite3TreeViewSelect(pView, pCte->pSelect, 0); - tdsqlite3TreeViewPop(pView); + sqlite3_str_appendf(&x, " AS"); + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, inCte-1); + sqlite3TreeViewSelect(pView, pCte->pSelect, 0); + sqlite3TreeViewPop(pView); } - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } } /* ** Generate a human-readable description of a SrcList object. */ -SQLITE_PRIVATE void tdsqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ +SQLITE_PRIVATE void sqlite3TreeViewSrcList(TreeView *pView, const SrcList *pSrc){ int i; for(i=0; inSrc; i++){ const struct SrcList_item *pItem = &pSrc->a[i]; StrAccum x; char zLine[100]; - tdsqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); - tdsqlite3_str_appendf(&x, "{%d:*}", pItem->iCursor); + sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0); + sqlite3_str_appendf(&x, "{%d:*}", pItem->iCursor); if( pItem->zDatabase ){ - tdsqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName); + sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName); }else if( pItem->zName ){ - tdsqlite3_str_appendf(&x, " %s", pItem->zName); + sqlite3_str_appendf(&x, " %s", pItem->zName); } if( pItem->pTab ){ - tdsqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p", + sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p", pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab); } if( pItem->zAlias ){ - tdsqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); + sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias); } if( pItem->fg.jointype & JT_LEFT ){ - tdsqlite3_str_appendf(&x, " LEFT-JOIN"); + sqlite3_str_appendf(&x, " LEFT-JOIN"); } if( pItem->fg.fromDDL ){ - tdsqlite3_str_appendf(&x, " DDL"); + sqlite3_str_appendf(&x, " DDL"); } - tdsqlite3StrAccumFinish(&x); - tdsqlite3TreeViewItem(pView, zLine, inSrc-1); + sqlite3StrAccumFinish(&x); + sqlite3TreeViewItem(pView, zLine, inSrc-1); if( pItem->pSelect ){ - tdsqlite3TreeViewSelect(pView, pItem->pSelect, 0); + sqlite3TreeViewSelect(pView, pItem->pSelect, 0); } if( pItem->fg.isTabFunc ){ - tdsqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); + sqlite3TreeViewExprList(pView, pItem->u1.pFuncArg, 0, "func-args:"); } - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } } /* ** Generate a human-readable description of a Select object. */ -SQLITE_PRIVATE void tdsqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ +SQLITE_PRIVATE void sqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 moreToFollow){ int n = 0; int cnt = 0; if( p==0 ){ - tdsqlite3TreeViewLine(pView, "nil-SELECT"); + sqlite3TreeViewLine(pView, "nil-SELECT"); return; } - pView = tdsqlite3TreeViewPush(pView, moreToFollow); + pView = sqlite3TreeViewPush(pView, moreToFollow); if( p->pWith ){ - tdsqlite3TreeViewWith(pView, p->pWith, 1); + sqlite3TreeViewWith(pView, p->pWith, 1); cnt = 1; - tdsqlite3TreeViewPush(pView, 1); + sqlite3TreeViewPush(pView, 1); } do{ if( p->selFlags & SF_WhereBegin ){ - tdsqlite3TreeViewLine(pView, "tdsqlite3WhereBegin()"); + sqlite3TreeViewLine(pView, "sqlite3WhereBegin()"); }else{ - tdsqlite3TreeViewLine(pView, + sqlite3TreeViewLine(pView, "SELECT%s%s (%u/%p) selFlags=0x%x nSelectRow=%d", ((p->selFlags & SF_Distinct) ? " DISTINCT" : ""), ((p->selFlags & SF_Aggregate) ? " agg_flag" : ""), @@ -33741,7 +33741,7 @@ SQLITE_PRIVATE void tdsqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 (int)p->nSelectRow ); } - if( cnt++ ) tdsqlite3TreeViewPop(pView); + if( cnt++ ) sqlite3TreeViewPop(pView); if( p->pPrior ){ n = 1000; }else{ @@ -33758,61 +33758,61 @@ SQLITE_PRIVATE void tdsqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 #endif } if( p->pEList ){ - tdsqlite3TreeViewExprList(pView, p->pEList, n>0, "result-set"); + sqlite3TreeViewExprList(pView, p->pEList, n>0, "result-set"); } n--; #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin ){ Window *pX; - pView = tdsqlite3TreeViewPush(pView, (n--)>0); - tdsqlite3TreeViewLine(pView, "window-functions"); + pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewLine(pView, "window-functions"); for(pX=p->pWin; pX; pX=pX->pNextWin){ - tdsqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); + sqlite3TreeViewWinFunc(pView, pX, pX->pNextWin!=0); } - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } #endif if( p->pSrc && p->pSrc->nSrc ){ - pView = tdsqlite3TreeViewPush(pView, (n--)>0); - tdsqlite3TreeViewLine(pView, "FROM"); - tdsqlite3TreeViewSrcList(pView, p->pSrc); - tdsqlite3TreeViewPop(pView); + pView = sqlite3TreeViewPush(pView, (n--)>0); + sqlite3TreeViewLine(pView, "FROM"); + sqlite3TreeViewSrcList(pView, p->pSrc); + sqlite3TreeViewPop(pView); } if( p->pWhere ){ - tdsqlite3TreeViewItem(pView, "WHERE", (n--)>0); - tdsqlite3TreeViewExpr(pView, p->pWhere, 0); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, "WHERE", (n--)>0); + sqlite3TreeViewExpr(pView, p->pWhere, 0); + sqlite3TreeViewPop(pView); } if( p->pGroupBy ){ - tdsqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); + sqlite3TreeViewExprList(pView, p->pGroupBy, (n--)>0, "GROUPBY"); } if( p->pHaving ){ - tdsqlite3TreeViewItem(pView, "HAVING", (n--)>0); - tdsqlite3TreeViewExpr(pView, p->pHaving, 0); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, "HAVING", (n--)>0); + sqlite3TreeViewExpr(pView, p->pHaving, 0); + sqlite3TreeViewPop(pView); } #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWinDefn ){ Window *pX; - tdsqlite3TreeViewItem(pView, "WINDOW", (n--)>0); + sqlite3TreeViewItem(pView, "WINDOW", (n--)>0); for(pX=p->pWinDefn; pX; pX=pX->pNextWin){ - tdsqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); + sqlite3TreeViewWindow(pView, pX, pX->pNextWin!=0); } - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } #endif if( p->pOrderBy ){ - tdsqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); + sqlite3TreeViewExprList(pView, p->pOrderBy, (n--)>0, "ORDERBY"); } if( p->pLimit ){ - tdsqlite3TreeViewItem(pView, "LIMIT", (n--)>0); - tdsqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); + sqlite3TreeViewItem(pView, "LIMIT", (n--)>0); + sqlite3TreeViewExpr(pView, p->pLimit->pLeft, p->pLimit->pRight!=0); if( p->pLimit->pRight ){ - tdsqlite3TreeViewItem(pView, "OFFSET", (n--)>0); - tdsqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, "OFFSET", (n--)>0); + sqlite3TreeViewExpr(pView, p->pLimit->pRight, 0); + sqlite3TreeViewPop(pView); } - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } if( p->pPrior ){ const char *zOp = "UNION"; @@ -33821,18 +33821,18 @@ SQLITE_PRIVATE void tdsqlite3TreeViewSelect(TreeView *pView, const Select *p, u8 case TK_INTERSECT: zOp = "INTERSECT"; break; case TK_EXCEPT: zOp = "EXCEPT"; break; } - tdsqlite3TreeViewItem(pView, zOp, 1); + sqlite3TreeViewItem(pView, zOp, 1); } p = p->pPrior; }while( p!=0 ); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } #ifndef SQLITE_OMIT_WINDOWFUNC /* ** Generate a description of starting or stopping bounds */ -SQLITE_PRIVATE void tdsqlite3TreeViewBound( +SQLITE_PRIVATE void sqlite3TreeViewBound( TreeView *pView, /* View context */ u8 eBound, /* UNBOUNDED, CURRENT, PRECEDING, FOLLOWING */ Expr *pExpr, /* Value for PRECEDING or FOLLOWING */ @@ -33840,25 +33840,25 @@ SQLITE_PRIVATE void tdsqlite3TreeViewBound( ){ switch( eBound ){ case TK_UNBOUNDED: { - tdsqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, "UNBOUNDED", moreToFollow); + sqlite3TreeViewPop(pView); break; } case TK_CURRENT: { - tdsqlite3TreeViewItem(pView, "CURRENT", moreToFollow); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, "CURRENT", moreToFollow); + sqlite3TreeViewPop(pView); break; } case TK_PRECEDING: { - tdsqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); - tdsqlite3TreeViewExpr(pView, pExpr, 0); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, "PRECEDING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(pView); break; } case TK_FOLLOWING: { - tdsqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); - tdsqlite3TreeViewExpr(pView, pExpr, 0); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, "FOLLOWING", moreToFollow); + sqlite3TreeViewExpr(pView, pExpr, 0); + sqlite3TreeViewPop(pView); break; } } @@ -33869,45 +33869,45 @@ SQLITE_PRIVATE void tdsqlite3TreeViewBound( /* ** Generate a human-readable explanation for a Window object */ -SQLITE_PRIVATE void tdsqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ +SQLITE_PRIVATE void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){ int nElement = 0; if( pWin->pFilter ){ - tdsqlite3TreeViewItem(pView, "FILTER", 1); - tdsqlite3TreeViewExpr(pView, pWin->pFilter, 0); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, "FILTER", 1); + sqlite3TreeViewExpr(pView, pWin->pFilter, 0); + sqlite3TreeViewPop(pView); } - pView = tdsqlite3TreeViewPush(pView, more); + pView = sqlite3TreeViewPush(pView, more); if( pWin->zName ){ - tdsqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin); + sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin); }else{ - tdsqlite3TreeViewLine(pView, "OVER (%p)", pWin); + sqlite3TreeViewLine(pView, "OVER (%p)", pWin); } if( pWin->zBase ) nElement++; if( pWin->pOrderBy ) nElement++; if( pWin->eFrmType ) nElement++; if( pWin->eExclude ) nElement++; if( pWin->zBase ){ - tdsqlite3TreeViewPush(pView, (--nElement)>0); - tdsqlite3TreeViewLine(pView, "window: %s", pWin->zBase); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPush(pView, (--nElement)>0); + sqlite3TreeViewLine(pView, "window: %s", pWin->zBase); + sqlite3TreeViewPop(pView); } if( pWin->pPartition ){ - tdsqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY"); + sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY"); } if( pWin->pOrderBy ){ - tdsqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY"); + sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY"); } if( pWin->eFrmType ){ char zBuf[30]; const char *zFrmType = "ROWS"; if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE"; if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS"; - tdsqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType, + sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType, pWin->bImplicitFrame ? " (implied)" : ""); - tdsqlite3TreeViewItem(pView, zBuf, (--nElement)>0); - tdsqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); - tdsqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewItem(pView, zBuf, (--nElement)>0); + sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1); + sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0); + sqlite3TreeViewPop(pView); } if( pWin->eExclude ){ char zBuf[30]; @@ -33918,15 +33918,15 @@ SQLITE_PRIVATE void tdsqlite3TreeViewWindow(TreeView *pView, const Window *pWin, case TK_GROUP: zExclude = "GROUP"; break; case TK_TIES: zExclude = "TIES"; break; default: - tdsqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude); + sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude); zExclude = zBuf; break; } - tdsqlite3TreeViewPush(pView, 0); - tdsqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPush(pView, 0); + sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude); + sqlite3TreeViewPop(pView); } - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -33934,46 +33934,46 @@ SQLITE_PRIVATE void tdsqlite3TreeViewWindow(TreeView *pView, const Window *pWin, /* ** Generate a human-readable explanation for a Window Function object */ -SQLITE_PRIVATE void tdsqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ - pView = tdsqlite3TreeViewPush(pView, more); - tdsqlite3TreeViewLine(pView, "WINFUNC %s(%d)", +SQLITE_PRIVATE void sqlite3TreeViewWinFunc(TreeView *pView, const Window *pWin, u8 more){ + pView = sqlite3TreeViewPush(pView, more); + sqlite3TreeViewLine(pView, "WINFUNC %s(%d)", pWin->pFunc->zName, pWin->pFunc->nArg); - tdsqlite3TreeViewWindow(pView, pWin, 0); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewWindow(pView, pWin, 0); + sqlite3TreeViewPop(pView); } #endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** Generate a human-readable explanation of an expression tree. */ -SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ +SQLITE_PRIVATE void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ const char *zBinOp = 0; /* Binary operator */ const char *zUniOp = 0; /* Unary operator */ char zFlgs[60]; - pView = tdsqlite3TreeViewPush(pView, moreToFollow); + pView = sqlite3TreeViewPush(pView, moreToFollow); if( pExpr==0 ){ - tdsqlite3TreeViewLine(pView, "nil"); - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewLine(pView, "nil"); + sqlite3TreeViewPop(pView); return; } if( pExpr->flags || pExpr->affExpr ){ StrAccum x; - tdsqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); - tdsqlite3_str_appendf(&x, " fg.af=%x.%c", + sqlite3StrAccumInit(&x, 0, zFlgs, sizeof(zFlgs), 0); + sqlite3_str_appendf(&x, " fg.af=%x.%c", pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n'); if( ExprHasProperty(pExpr, EP_FromJoin) ){ - tdsqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable); + sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable); } if( ExprHasProperty(pExpr, EP_FromDDL) ){ - tdsqlite3_str_appendf(&x, " DDL"); + sqlite3_str_appendf(&x, " DDL"); } - tdsqlite3StrAccumFinish(&x); + sqlite3StrAccumFinish(&x); }else{ zFlgs[0] = 0; } switch( pExpr->op ){ case TK_AGG_COLUMN: { - tdsqlite3TreeViewLine(pView, "AGG{%d:%d}%s", + sqlite3TreeViewLine(pView, "AGG{%d:%d}%s", pExpr->iTable, pExpr->iColumn, zFlgs); break; } @@ -33982,73 +33982,73 @@ SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 /* This only happens when coding check constraints */ char zOp2[16]; if( pExpr->op2 ){ - tdsqlite3_snprintf(sizeof(zOp2),zOp2," op2=0x%02x",pExpr->op2); + sqlite3_snprintf(sizeof(zOp2),zOp2," op2=0x%02x",pExpr->op2); }else{ zOp2[0] = 0; } - tdsqlite3TreeViewLine(pView, "COLUMN(%d)%s%s", + sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s", pExpr->iColumn, zFlgs, zOp2); }else{ - tdsqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s", + sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s", pExpr->iTable, pExpr->iColumn, pExpr->y.pTab, zFlgs); } if( ExprHasProperty(pExpr, EP_FixedCol) ){ - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); } break; } case TK_INTEGER: { if( pExpr->flags & EP_IntValue ){ - tdsqlite3TreeViewLine(pView, "%d", pExpr->u.iValue); + sqlite3TreeViewLine(pView, "%d", pExpr->u.iValue); }else{ - tdsqlite3TreeViewLine(pView, "%s", pExpr->u.zToken); + sqlite3TreeViewLine(pView, "%s", pExpr->u.zToken); } break; } #ifndef SQLITE_OMIT_FLOATING_POINT case TK_FLOAT: { - tdsqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); + sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); break; } #endif case TK_STRING: { - tdsqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken); + sqlite3TreeViewLine(pView,"%Q", pExpr->u.zToken); break; } case TK_NULL: { - tdsqlite3TreeViewLine(pView,"NULL"); + sqlite3TreeViewLine(pView,"NULL"); break; } case TK_TRUEFALSE: { - tdsqlite3TreeViewLine(pView, - tdsqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE"); + sqlite3TreeViewLine(pView, + sqlite3ExprTruthValue(pExpr) ? "TRUE" : "FALSE"); break; } #ifndef SQLITE_OMIT_BLOB_LITERAL case TK_BLOB: { - tdsqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); + sqlite3TreeViewLine(pView,"%s", pExpr->u.zToken); break; } #endif case TK_VARIABLE: { - tdsqlite3TreeViewLine(pView,"VARIABLE(%s,%d)", + sqlite3TreeViewLine(pView,"VARIABLE(%s,%d)", pExpr->u.zToken, pExpr->iColumn); break; } case TK_REGISTER: { - tdsqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable); + sqlite3TreeViewLine(pView,"REGISTER(%d)", pExpr->iTable); break; } case TK_ID: { - tdsqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); + sqlite3TreeViewLine(pView,"ID \"%w\"", pExpr->u.zToken); break; } #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ - tdsqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken); - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + sqlite3TreeViewLine(pView,"CAST %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } #endif /* SQLITE_OMIT_CAST */ @@ -34088,15 +34088,15 @@ SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 }; assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); assert( pExpr->pRight ); - assert( tdsqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE ); - x = (pExpr->op2==TK_ISNOT)*2 + tdsqlite3ExprTruthValue(pExpr->pRight); + assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE ); + x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); zUniOp = azOp[x]; break; } case TK_SPAN: { - tdsqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } @@ -34106,10 +34106,10 @@ SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 ** up in the treeview output as "SOFT-COLLATE". Explicit COLLATE ** operators that appear in the original SQL always have the ** EP_Collate bit set and appear in treeview output as just "COLLATE" */ - tdsqlite3TreeViewLine(pView, "%sCOLLATE %Q%s", + sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s", !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "", pExpr->u.zToken, zFlgs); - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } @@ -34129,50 +34129,50 @@ SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 #endif } if( pExpr->op==TK_AGG_FUNCTION ){ - tdsqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s", + sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s", pExpr->op2, pExpr->u.zToken, zFlgs); }else if( pExpr->op2!=0 ){ const char *zOp2; char zBuf[8]; - tdsqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2); + sqlite3_snprintf(sizeof(zBuf),zBuf,"0x%02x",pExpr->op2); zOp2 = zBuf; if( pExpr->op2==NC_IsCheck ) zOp2 = "NC_IsCheck"; if( pExpr->op2==NC_IdxExpr ) zOp2 = "NC_IdxExpr"; if( pExpr->op2==NC_PartIdx ) zOp2 = "NC_PartIdx"; if( pExpr->op2==NC_GenCol ) zOp2 = "NC_GenCol"; - tdsqlite3TreeViewLine(pView, "FUNCTION %Q%s op2=%s", + sqlite3TreeViewLine(pView, "FUNCTION %Q%s op2=%s", pExpr->u.zToken, zFlgs, zOp2); }else{ - tdsqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); + sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } if( pFarg ){ - tdsqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); + sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ - tdsqlite3TreeViewWindow(pView, pWin, 0); + sqlite3TreeViewWindow(pView, pWin, 0); } #endif break; } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: { - tdsqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags); - tdsqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + sqlite3TreeViewLine(pView, "EXISTS-expr flags=0x%x", pExpr->flags); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); break; } case TK_SELECT: { - tdsqlite3TreeViewLine(pView, "SELECT-expr flags=0x%x", pExpr->flags); - tdsqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + sqlite3TreeViewLine(pView, "SELECT-expr flags=0x%x", pExpr->flags); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); break; } case TK_IN: { - tdsqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags); - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + sqlite3TreeViewLine(pView, "IN flags=0x%x", pExpr->flags); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - tdsqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); + sqlite3TreeViewSelect(pView, pExpr->x.pSelect, 0); }else{ - tdsqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); } break; } @@ -34193,10 +34193,10 @@ SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 Expr *pX = pExpr->pLeft; Expr *pY = pExpr->x.pList->a[0].pExpr; Expr *pZ = pExpr->x.pList->a[1].pExpr; - tdsqlite3TreeViewLine(pView, "BETWEEN"); - tdsqlite3TreeViewExpr(pView, pX, 1); - tdsqlite3TreeViewExpr(pView, pY, 1); - tdsqlite3TreeViewExpr(pView, pZ, 0); + sqlite3TreeViewLine(pView, "BETWEEN"); + sqlite3TreeViewExpr(pView, pX, 1); + sqlite3TreeViewExpr(pView, pY, 1); + sqlite3TreeViewExpr(pView, pZ, 0); break; } case TK_TRIGGER: { @@ -34207,14 +34207,14 @@ SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 ** is set to the column of the pseudo-table to read, or to -1 to ** read the rowid field. */ - tdsqlite3TreeViewLine(pView, "%s(%d)", + sqlite3TreeViewLine(pView, "%s(%d)", pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn); break; } case TK_CASE: { - tdsqlite3TreeViewLine(pView, "CASE"); - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 1); - tdsqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); + sqlite3TreeViewLine(pView, "CASE"); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, 0); break; } #ifndef SQLITE_OMIT_TRIGGER @@ -34226,72 +34226,72 @@ SQLITE_PRIVATE void tdsqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 case OE_Fail: zType = "fail"; break; case OE_Ignore: zType = "ignore"; break; } - tdsqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); + sqlite3TreeViewLine(pView, "RAISE %s(%Q)", zType, pExpr->u.zToken); break; } #endif case TK_MATCH: { - tdsqlite3TreeViewLine(pView, "MATCH {%d:%d}%s", + sqlite3TreeViewLine(pView, "MATCH {%d:%d}%s", pExpr->iTable, pExpr->iColumn, zFlgs); - tdsqlite3TreeViewExpr(pView, pExpr->pRight, 0); + sqlite3TreeViewExpr(pView, pExpr->pRight, 0); break; } case TK_VECTOR: { - char *z = tdsqlite3_mprintf("VECTOR%s",zFlgs); - tdsqlite3TreeViewBareExprList(pView, pExpr->x.pList, z); - tdsqlite3_free(z); + char *z = sqlite3_mprintf("VECTOR%s",zFlgs); + sqlite3TreeViewBareExprList(pView, pExpr->x.pList, z); + sqlite3_free(z); break; } case TK_SELECT_COLUMN: { - tdsqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn); - tdsqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0); + sqlite3TreeViewLine(pView, "SELECT-COLUMN %d", pExpr->iColumn); + sqlite3TreeViewSelect(pView, pExpr->pLeft->x.pSelect, 0); break; } case TK_IF_NULL_ROW: { - tdsqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable); - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + sqlite3TreeViewLine(pView, "IF-NULL-ROW %d", pExpr->iTable); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } default: { - tdsqlite3TreeViewLine(pView, "op=%d", pExpr->op); + sqlite3TreeViewLine(pView, "op=%d", pExpr->op); break; } } if( zBinOp ){ - tdsqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs); - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 1); - tdsqlite3TreeViewExpr(pView, pExpr->pRight, 0); + sqlite3TreeViewLine(pView, "%s%s", zBinOp, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 1); + sqlite3TreeViewExpr(pView, pExpr->pRight, 0); }else if( zUniOp ){ - tdsqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); - tdsqlite3TreeViewExpr(pView, pExpr->pLeft, 0); + sqlite3TreeViewLine(pView, "%s%s", zUniOp, zFlgs); + sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); } - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } /* ** Generate a human-readable explanation of an expression list. */ -SQLITE_PRIVATE void tdsqlite3TreeViewBareExprList( +SQLITE_PRIVATE void sqlite3TreeViewBareExprList( TreeView *pView, const ExprList *pList, const char *zLabel ){ if( zLabel==0 || zLabel[0]==0 ) zLabel = "LIST"; if( pList==0 ){ - tdsqlite3TreeViewLine(pView, "%s (empty)", zLabel); + sqlite3TreeViewLine(pView, "%s (empty)", zLabel); }else{ int i; - tdsqlite3TreeViewLine(pView, "%s", zLabel); + sqlite3TreeViewLine(pView, "%s", zLabel); for(i=0; inExpr; i++){ int j = pList->a[i].u.x.iOrderByCol; char *zName = pList->a[i].zEName; int moreToFollow = inExpr - 1; if( pList->a[i].eEName!=ENAME_NAME ) zName = 0; if( j || zName ){ - tdsqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewPush(pView, moreToFollow); moreToFollow = 0; - tdsqlite3TreeViewLine(pView, 0); + sqlite3TreeViewLine(pView, 0); if( zName ){ fprintf(stdout, "AS %s ", zName); } @@ -34301,22 +34301,22 @@ SQLITE_PRIVATE void tdsqlite3TreeViewBareExprList( fprintf(stdout, "\n"); fflush(stdout); } - tdsqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); + sqlite3TreeViewExpr(pView, pList->a[i].pExpr, moreToFollow); if( j || zName ){ - tdsqlite3TreeViewPop(pView); + sqlite3TreeViewPop(pView); } } } } -SQLITE_PRIVATE void tdsqlite3TreeViewExprList( +SQLITE_PRIVATE void sqlite3TreeViewExprList( TreeView *pView, const ExprList *pList, u8 moreToFollow, const char *zLabel ){ - pView = tdsqlite3TreeViewPush(pView, moreToFollow); - tdsqlite3TreeViewBareExprList(pView, pList, zLabel); - tdsqlite3TreeViewPop(pView); + pView = sqlite3TreeViewPush(pView, moreToFollow); + sqlite3TreeViewBareExprList(pView, pList, zLabel); + sqlite3TreeViewPop(pView); } #endif /* SQLITE_DEBUG */ @@ -34346,16 +34346,16 @@ SQLITE_PRIVATE void tdsqlite3TreeViewExprList( /* All threads share a single random number generator. ** This structure is the current state of the generator. */ -static SQLITE_WSD struct tdsqlite3PrngType { +static SQLITE_WSD struct sqlite3PrngType { unsigned char isInit; /* True if initialized */ unsigned char i, j; /* State variables */ unsigned char s[256]; /* State variables */ -} tdsqlite3Prng; +} sqlite3Prng; /* ** Return N random bytes. */ -SQLITE_API void tdsqlite3_randomness(int N, void *pBuf){ +SQLITE_API void sqlite3_randomness(int N, void *pBuf){ unsigned char t; unsigned char *zBuf = pBuf; @@ -34363,31 +34363,31 @@ SQLITE_API void tdsqlite3_randomness(int N, void *pBuf){ ** state vector. If writable static data is unsupported on the target, ** we have to locate the state vector at run-time. In the more common ** case where writable static data is supported, wsdPrng can refer directly - ** to the "tdsqlite3Prng" state vector declared above. + ** to the "sqlite3Prng" state vector declared above. */ #ifdef SQLITE_OMIT_WSD - struct tdsqlite3PrngType *p = &GLOBAL(struct tdsqlite3PrngType, tdsqlite3Prng); + struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng); # define wsdPrng p[0] #else -# define wsdPrng tdsqlite3Prng +# define wsdPrng sqlite3Prng #endif #if SQLITE_THREADSAFE - tdsqlite3_mutex *mutex; + sqlite3_mutex *mutex; #endif #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return; + if( sqlite3_initialize() ) return; #endif #if SQLITE_THREADSAFE - mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); + mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG); #endif - tdsqlite3_mutex_enter(mutex); + sqlite3_mutex_enter(mutex); if( N<=0 || pBuf==0 ){ wsdPrng.isInit = 0; - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); return; } @@ -34405,7 +34405,7 @@ SQLITE_API void tdsqlite3_randomness(int N, void *pBuf){ char k[256]; wsdPrng.j = 0; wsdPrng.i = 0; - tdsqlite3OsRandomness(tdsqlite3_vfs_find(0), 256, k); + sqlite3OsRandomness(sqlite3_vfs_find(0), 256, k); for(i=0; i<256; i++){ wsdPrng.s[i] = (u8)i; } @@ -34428,7 +34428,7 @@ SQLITE_API void tdsqlite3_randomness(int N, void *pBuf){ t += wsdPrng.s[wsdPrng.i]; *(zBuf++) = wsdPrng.s[t]; }while( --N ); - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); } #ifndef SQLITE_UNTESTABLE @@ -34438,22 +34438,22 @@ SQLITE_API void tdsqlite3_randomness(int N, void *pBuf){ ** to reset the PRNG to its initial state. These routines accomplish ** those tasks. ** -** The tdsqlite3_test_control() interface calls these routines to +** The sqlite3_test_control() interface calls these routines to ** control the PRNG. */ -static SQLITE_WSD struct tdsqlite3PrngType tdsqlite3SavedPrng; -SQLITE_PRIVATE void tdsqlite3PrngSaveState(void){ +static SQLITE_WSD struct sqlite3PrngType sqlite3SavedPrng; +SQLITE_PRIVATE void sqlite3PrngSaveState(void){ memcpy( - &GLOBAL(struct tdsqlite3PrngType, tdsqlite3SavedPrng), - &GLOBAL(struct tdsqlite3PrngType, tdsqlite3Prng), - sizeof(tdsqlite3Prng) + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + sizeof(sqlite3Prng) ); } -SQLITE_PRIVATE void tdsqlite3PrngRestoreState(void){ +SQLITE_PRIVATE void sqlite3PrngRestoreState(void){ memcpy( - &GLOBAL(struct tdsqlite3PrngType, tdsqlite3Prng), - &GLOBAL(struct tdsqlite3PrngType, tdsqlite3SavedPrng), - sizeof(tdsqlite3Prng) + &GLOBAL(struct sqlite3PrngType, sqlite3Prng), + &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng), + sizeof(sqlite3Prng) ); } #endif /* SQLITE_UNTESTABLE */ @@ -34475,13 +34475,13 @@ SQLITE_PRIVATE void tdsqlite3PrngRestoreState(void){ ** This file presents a simple cross-platform threading interface for ** use internally by SQLite. ** -** A "thread" can be created using tdsqlite3ThreadCreate(). This thread +** A "thread" can be created using sqlite3ThreadCreate(). This thread ** runs independently of its creator until it is joined using -** tdsqlite3ThreadJoin(), at which point it terminates. +** sqlite3ThreadJoin(), at which point it terminates. ** ** Threads do not have to be real. It could be that the work of the -** "thread" is done by the main thread at either the tdsqlite3ThreadCreate() -** or tdsqlite3ThreadJoin() call. This is, in fact, what happens in +** "thread" is done by the main thread at either the sqlite3ThreadCreate() +** or sqlite3ThreadJoin() call. This is, in fact, what happens in ** single threaded systems. Nothing in SQLite requires multiple threads. ** This interface exists so that applications that want to take advantage ** of multiple cores can do so, while also allowing applications to stay @@ -34510,7 +34510,7 @@ struct SQLiteThread { }; /* Create a new thread */ -SQLITE_PRIVATE int tdsqlite3ThreadCreate( +SQLITE_PRIVATE int sqlite3ThreadCreate( SQLiteThread **ppThread, /* OUT: Write the thread object here */ void *(*xTask)(void*), /* Routine to run in a separate thread */ void *pIn /* Argument passed into xTask() */ @@ -34521,10 +34521,10 @@ SQLITE_PRIVATE int tdsqlite3ThreadCreate( assert( ppThread!=0 ); assert( xTask!=0 ); /* This routine is never used in single-threaded mode */ - assert( tdsqlite3GlobalConfig.bCoreMutex!=0 ); + assert( sqlite3GlobalConfig.bCoreMutex!=0 ); *ppThread = 0; - p = tdsqlite3Malloc(sizeof(*p)); + p = sqlite3Malloc(sizeof(*p)); if( p==0 ) return SQLITE_NOMEM_BKPT; memset(p, 0, sizeof(*p)); p->xTask = xTask; @@ -34533,7 +34533,7 @@ SQLITE_PRIVATE int tdsqlite3ThreadCreate( ** function that returns SQLITE_ERROR when passed the argument 200, that ** forces worker threads to run sequentially and deterministically ** for testing purposes. */ - if( tdsqlite3FaultSim(200) ){ + if( sqlite3FaultSim(200) ){ rc = 1; }else{ rc = pthread_create(&p->tid, 0, xTask, pIn); @@ -34547,7 +34547,7 @@ SQLITE_PRIVATE int tdsqlite3ThreadCreate( } /* Get the results of the thread */ -SQLITE_PRIVATE int tdsqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ int rc; assert( ppOut!=0 ); @@ -34558,7 +34558,7 @@ SQLITE_PRIVATE int tdsqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ }else{ rc = pthread_join(p->tid, ppOut) ? SQLITE_ERROR : SQLITE_OK; } - tdsqlite3_free(p); + sqlite3_free(p); return rc; } @@ -34582,7 +34582,7 @@ struct SQLiteThread { }; /* Thread procedure Win32 compatibility shim */ -static unsigned __stdcall tdsqlite3ThreadProc( +static unsigned __stdcall sqlite3ThreadProc( void *pArg /* IN: Pointer to the SQLiteThread structure */ ){ SQLiteThread *p = (SQLiteThread *)pArg; @@ -34605,7 +34605,7 @@ static unsigned __stdcall tdsqlite3ThreadProc( } /* Create a new thread */ -SQLITE_PRIVATE int tdsqlite3ThreadCreate( +SQLITE_PRIVATE int sqlite3ThreadCreate( SQLiteThread **ppThread, /* OUT: Write the thread object here */ void *(*xTask)(void*), /* Routine to run in a separate thread */ void *pIn /* Argument passed into xTask() */ @@ -34615,19 +34615,19 @@ SQLITE_PRIVATE int tdsqlite3ThreadCreate( assert( ppThread!=0 ); assert( xTask!=0 ); *ppThread = 0; - p = tdsqlite3Malloc(sizeof(*p)); + p = sqlite3Malloc(sizeof(*p)); if( p==0 ) return SQLITE_NOMEM_BKPT; /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a ** function that returns SQLITE_ERROR when passed the argument 200, that ** forces worker threads to run sequentially and deterministically - ** (via the tdsqlite3FaultSim() term of the conditional) for testing + ** (via the sqlite3FaultSim() term of the conditional) for testing ** purposes. */ - if( tdsqlite3GlobalConfig.bCoreMutex==0 || tdsqlite3FaultSim(200) ){ + if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){ memset(p, 0, sizeof(*p)); }else{ p->xTask = xTask; p->pIn = pIn; - p->tid = (void*)_beginthreadex(0, 0, tdsqlite3ThreadProc, p, 0, &p->id); + p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id); if( p->tid==0 ){ memset(p, 0, sizeof(*p)); } @@ -34640,10 +34640,10 @@ SQLITE_PRIVATE int tdsqlite3ThreadCreate( return SQLITE_OK; } -SQLITE_PRIVATE DWORD tdsqlite3Win32Wait(HANDLE hObject); /* os_win.c */ +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject); /* os_win.c */ /* Get the results of the thread */ -SQLITE_PRIVATE int tdsqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ DWORD rc; BOOL bRc; @@ -34655,13 +34655,13 @@ SQLITE_PRIVATE int tdsqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ assert( p->tid==0 ); }else{ assert( p->id!=0 && p->id!=GetCurrentThreadId() ); - rc = tdsqlite3Win32Wait((HANDLE)p->tid); + rc = sqlite3Win32Wait((HANDLE)p->tid); assert( rc!=WAIT_IO_COMPLETION ); bRc = CloseHandle((HANDLE)p->tid); assert( bRc ); } if( rc==WAIT_OBJECT_0 ) *ppOut = p->pResult; - tdsqlite3_free(p); + sqlite3_free(p); return (rc==WAIT_OBJECT_0) ? SQLITE_OK : SQLITE_ERROR; } @@ -34685,7 +34685,7 @@ struct SQLiteThread { }; /* Create a new thread */ -SQLITE_PRIVATE int tdsqlite3ThreadCreate( +SQLITE_PRIVATE int sqlite3ThreadCreate( SQLiteThread **ppThread, /* OUT: Write the thread object here */ void *(*xTask)(void*), /* Routine to run in a separate thread */ void *pIn /* Argument passed into xTask() */ @@ -34695,7 +34695,7 @@ SQLITE_PRIVATE int tdsqlite3ThreadCreate( assert( ppThread!=0 ); assert( xTask!=0 ); *ppThread = 0; - p = tdsqlite3Malloc(sizeof(*p)); + p = sqlite3Malloc(sizeof(*p)); if( p==0 ) return SQLITE_NOMEM_BKPT; if( (SQLITE_PTR_TO_INT(p)/17)&1 ){ p->xTask = xTask; @@ -34709,7 +34709,7 @@ SQLITE_PRIVATE int tdsqlite3ThreadCreate( } /* Get the results of the thread */ -SQLITE_PRIVATE int tdsqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ +SQLITE_PRIVATE int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ assert( ppOut!=0 ); if( NEVER(p==0) ) return SQLITE_NOMEM_BKPT; @@ -34718,13 +34718,13 @@ SQLITE_PRIVATE int tdsqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ }else{ *ppOut = p->pResult; } - tdsqlite3_free(p); + sqlite3_free(p); #if defined(SQLITE_TEST) { - void *pTstAlloc = tdsqlite3Malloc(10); + void *pTstAlloc = sqlite3Malloc(10); if (!pTstAlloc) return SQLITE_NOMEM_BKPT; - tdsqlite3_free(pTstAlloc); + sqlite3_free(pTstAlloc); } #endif @@ -34781,14 +34781,14 @@ SQLITE_PRIVATE int tdsqlite3ThreadJoin(SQLiteThread *p, void **ppOut){ ** The following constant value is used by the SQLITE_BIGENDIAN and ** SQLITE_LITTLEENDIAN macros. */ -SQLITE_PRIVATE const int tdsqlite3one = 1; +SQLITE_PRIVATE const int sqlite3one = 1; #endif /* SQLITE_AMALGAMATION && SQLITE_BYTEORDER==0 */ /* ** This lookup table is used to help decode the first byte of ** a multi-byte UTF8 character. */ -static const unsigned char tdsqlite3Utf8Trans1[] = { +static const unsigned char sqlite3Utf8Trans1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, @@ -34894,7 +34894,7 @@ static const unsigned char tdsqlite3Utf8Trans1[] = { #define READ_UTF8(zIn, zTerm, c) \ c = *(zIn++); \ if( c>=0xc0 ){ \ - c = tdsqlite3Utf8Trans1[c-0xc0]; \ + c = sqlite3Utf8Trans1[c-0xc0]; \ while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ c = (c<<6) + (0x3f & *(zIn++)); \ } \ @@ -34902,7 +34902,7 @@ static const unsigned char tdsqlite3Utf8Trans1[] = { || (c&0xFFFFF800)==0xD800 \ || (c&0xFFFFFFFE)==0xFFFE ){ c = 0xFFFD; } \ } -SQLITE_PRIVATE u32 tdsqlite3Utf8Read( +SQLITE_PRIVATE u32 sqlite3Utf8Read( const unsigned char **pz /* Pointer to string from which to read char */ ){ unsigned int c; @@ -34912,7 +34912,7 @@ SQLITE_PRIVATE u32 tdsqlite3Utf8Read( */ c = *((*pz)++); if( c>=0xc0 ){ - c = tdsqlite3Utf8Trans1[c-0xc0]; + c = sqlite3Utf8Trans1[c-0xc0]; while( (*(*pz) & 0xc0)==0x80 ){ c = (c<<6) + (0x3f & *((*pz)++)); } @@ -34928,7 +34928,7 @@ SQLITE_PRIVATE u32 tdsqlite3Utf8Read( /* ** If the TRANSLATE_TRACE macro is defined, the value of each Mem is -** printed on stderr on the way into and out of tdsqlite3VdbeMemTranslate(). +** printed on stderr on the way into and out of sqlite3VdbeMemTranslate(). */ /* #define TRANSLATE_TRACE 1 */ @@ -34938,15 +34938,15 @@ SQLITE_PRIVATE u32 tdsqlite3Utf8Read( ** desiredEnc. It is an error if the string is already of the desired ** encoding, or if *pMem does not contain a string value. */ -SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ - tdsqlite3_int64 len; /* Maximum length of output string in bytes */ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){ + sqlite3_int64 len; /* Maximum length of output string in bytes */ unsigned char *zOut; /* Output buffer */ unsigned char *zIn; /* Input iterator */ unsigned char *zTerm; /* End of input */ unsigned char *z; /* Output iterator */ unsigned int c; - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( pMem->flags&MEM_Str ); assert( pMem->enc!=desiredEnc ); assert( pMem->enc!=0 ); @@ -34956,9 +34956,9 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3VdbeMemTranslate(Mem *pMem, u8 desir { StrAccum acc; char zBuf[1000]; - tdsqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - tdsqlite3VdbeMemPrettyPrint(pMem, &acc); - fprintf(stderr, "INPUT: %s\n", tdsqlite3StrAccumFinish(&acc)); + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(pMem, &acc); + fprintf(stderr, "INPUT: %s\n", sqlite3StrAccumFinish(&acc)); } #endif @@ -34969,7 +34969,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3VdbeMemTranslate(Mem *pMem, u8 desir if( pMem->enc!=SQLITE_UTF8 && desiredEnc!=SQLITE_UTF8 ){ u8 temp; int rc; - rc = tdsqlite3VdbeMemMakeWriteable(pMem); + rc = sqlite3VdbeMemMakeWriteable(pMem); if( rc!=SQLITE_OK ){ assert( rc==SQLITE_NOMEM ); return SQLITE_NOMEM_BKPT; @@ -34994,25 +34994,25 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3VdbeMemTranslate(Mem *pMem, u8 desir ** nul-terminator. */ pMem->n &= ~1; - len = 2 * (tdsqlite3_int64)pMem->n + 1; + len = 2 * (sqlite3_int64)pMem->n + 1; }else{ /* When converting from UTF-8 to UTF-16 the maximum growth is caused ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16 ** character. Two bytes are required in the output buffer for the ** nul-terminator. */ - len = 2 * (tdsqlite3_int64)pMem->n + 2; + len = 2 * (sqlite3_int64)pMem->n + 2; } /* Set zIn to point at the start of the input buffer and zTerm to point 1 ** byte past the end. ** ** Variable zOut is set to point at the output buffer, space obtained - ** from tdsqlite3_malloc(). + ** from sqlite3_malloc(). */ zIn = (u8*)pMem->z; zTerm = &zIn[pMem->n]; - zOut = tdsqlite3DbMallocRaw(pMem->db, len); + zOut = sqlite3DbMallocRaw(pMem->db, len); if( !zOut ){ return SQLITE_NOMEM_BKPT; } @@ -35056,21 +35056,21 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3VdbeMemTranslate(Mem *pMem, u8 desir assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len ); c = pMem->flags; - tdsqlite3VdbeMemRelease(pMem); + sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype)); pMem->enc = desiredEnc; pMem->z = (char*)zOut; pMem->zMalloc = pMem->z; - pMem->szMalloc = tdsqlite3DbMallocSize(pMem->db, pMem->z); + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z); translate_out: #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG) { StrAccum acc; char zBuf[1000]; - tdsqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - tdsqlite3VdbeMemPrettyPrint(pMem, &acc); - fprintf(stderr, "OUTPUT: %s\n", tdsqlite3StrAccumFinish(&acc)); + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(pMem, &acc); + fprintf(stderr, "OUTPUT: %s\n", sqlite3StrAccumFinish(&acc)); } #endif return SQLITE_OK; @@ -35087,7 +35087,7 @@ translate_out: ** The allocation (static, dynamic etc.) and encoding of the Mem may be ** changed by this function. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemHandleBom(Mem *pMem){ +SQLITE_PRIVATE int sqlite3VdbeMemHandleBom(Mem *pMem){ int rc = SQLITE_OK; u8 bom = 0; @@ -35104,7 +35104,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemHandleBom(Mem *pMem){ } if( bom ){ - rc = tdsqlite3VdbeMemMakeWriteable(pMem); + rc = sqlite3VdbeMemMakeWriteable(pMem); if( rc==SQLITE_OK ){ pMem->n -= 2; memmove(pMem->z, &pMem->z[2], pMem->n); @@ -35125,7 +35125,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemHandleBom(Mem *pMem){ ** number of unicode characters in the first nByte of pZ (or up to ** the first 0x00, whichever comes first). */ -SQLITE_PRIVATE int tdsqlite3Utf8CharLen(const char *zIn, int nByte){ +SQLITE_PRIVATE int sqlite3Utf8CharLen(const char *zIn, int nByte){ int r = 0; const u8 *z = (const u8*)zIn; const u8 *zTerm; @@ -35155,13 +35155,13 @@ SQLITE_PRIVATE int tdsqlite3Utf8CharLen(const char *zIn, int nByte){ ** The translation is done in-place and aborted if the output ** overruns the input. */ -SQLITE_PRIVATE int tdsqlite3Utf8To8(unsigned char *zIn){ +SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char *zIn){ unsigned char *zOut = zIn; unsigned char *zStart = zIn; u32 c; while( zIn[0] && zOut<=zIn ){ - c = tdsqlite3Utf8Read((const u8**)&zIn); + c = sqlite3Utf8Read((const u8**)&zIn); if( c!=0xfffd ){ WRITE_UTF8(zOut, c); } @@ -35174,19 +35174,19 @@ SQLITE_PRIVATE int tdsqlite3Utf8To8(unsigned char *zIn){ #ifndef SQLITE_OMIT_UTF16 /* ** Convert a UTF-16 string in the native encoding into a UTF-8 string. -** Memory to hold the UTF-8 string is obtained from tdsqlite3_malloc and must +** Memory to hold the UTF-8 string is obtained from sqlite3_malloc and must ** be freed by the calling function. ** ** NULL is returned if there is an allocation error. */ -SQLITE_PRIVATE char *tdsqlite3Utf16to8(tdsqlite3 *db, const void *z, int nByte, u8 enc){ +SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte, u8 enc){ Mem m; memset(&m, 0, sizeof(m)); m.db = db; - tdsqlite3VdbeMemSetStr(&m, z, nByte, enc, SQLITE_STATIC); - tdsqlite3VdbeChangeEncoding(&m, SQLITE_UTF8); + sqlite3VdbeMemSetStr(&m, z, nByte, enc, SQLITE_STATIC); + sqlite3VdbeChangeEncoding(&m, SQLITE_UTF8); if( db->mallocFailed ){ - tdsqlite3VdbeMemRelease(&m); + sqlite3VdbeMemRelease(&m); m.z = 0; } assert( (m.flags & MEM_Term)!=0 || db->mallocFailed ); @@ -35200,7 +35200,7 @@ SQLITE_PRIVATE char *tdsqlite3Utf16to8(tdsqlite3 *db, const void *z, int nByte, ** Return the number of bytes in the first nChar unicode characters ** in pZ. nChar must be non-negative. */ -SQLITE_PRIVATE int tdsqlite3Utf16ByteLen(const void *zIn, int nChar){ +SQLITE_PRIVATE int sqlite3Utf16ByteLen(const void *zIn, int nChar){ int c; unsigned char const *z = zIn; int n = 0; @@ -35225,7 +35225,7 @@ SQLITE_PRIVATE int tdsqlite3Utf16ByteLen(const void *zIn, int nChar){ ** It checks that the primitives for serializing and deserializing ** characters in each encoding are inverses of each other. */ -SQLITE_PRIVATE void tdsqlite3UtfSelfTest(void){ +SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ unsigned int i, t; unsigned char zBuf[20]; unsigned char *z; @@ -35239,7 +35239,7 @@ SQLITE_PRIVATE void tdsqlite3UtfSelfTest(void){ assert( n>0 && n<=4 ); z[0] = 0; z = zBuf; - c = tdsqlite3Utf8Read((const u8**)&z); + c = sqlite3Utf8Read((const u8**)&z); t = i; if( i>=0xD800 && i<=0xDFFF ) t = 0xFFFD; if( (i&0xFFFFFFFE)==0xFFFE ) t = 0xFFFD; @@ -35303,34 +35303,34 @@ SQLITE_PRIVATE void tdsqlite3UtfSelfTest(void){ ** Routine needed to support the testcase() macro. */ #ifdef SQLITE_COVERAGE_TEST -SQLITE_PRIVATE void tdsqlite3Coverage(int x){ +SQLITE_PRIVATE void sqlite3Coverage(int x){ static unsigned dummy = 0; dummy += (unsigned)x; } #endif /* -** Calls to tdsqlite3FaultSim() are used to simulate a failure during testing, +** Calls to sqlite3FaultSim() are used to simulate a failure during testing, ** or to bypass normal error detection during testing in order to let ** execute proceed futher downstream. ** -** In deployment, tdsqlite3FaultSim() *always* return SQLITE_OK (0). The -** tdsqlite3FaultSim() function only returns non-zero during testing. +** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0). The +** sqlite3FaultSim() function only returns non-zero during testing. ** ** During testing, if the test harness has set a fault-sim callback using -** a call to tdsqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL), then -** each call to tdsqlite3FaultSim() is relayed to that application-supplied +** a call to sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL), then +** each call to sqlite3FaultSim() is relayed to that application-supplied ** callback and the integer return value form the application-supplied -** callback is returned by tdsqlite3FaultSim(). +** callback is returned by sqlite3FaultSim(). ** -** The integer argument to tdsqlite3FaultSim() is a code to identify which -** tdsqlite3FaultSim() instance is being invoked. Each call to tdsqlite3FaultSim() +** The integer argument to sqlite3FaultSim() is a code to identify which +** sqlite3FaultSim() instance is being invoked. Each call to sqlite3FaultSim() ** should have a unique code. To prevent legacy testing applications from ** breaking, the codes should not be changed or reused. */ #ifndef SQLITE_UNTESTABLE -SQLITE_PRIVATE int tdsqlite3FaultSim(int iTest){ - int (*xCallback)(int) = tdsqlite3GlobalConfig.xTestCallback; +SQLITE_PRIVATE int sqlite3FaultSim(int iTest){ + int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback; return xCallback ? xCallback(iTest) : SQLITE_OK; } #endif @@ -35339,7 +35339,7 @@ SQLITE_PRIVATE int tdsqlite3FaultSim(int iTest){ /* ** Return true if the floating point value is Not a Number (NaN). */ -SQLITE_PRIVATE int tdsqlite3IsNaN(double x){ +SQLITE_PRIVATE int sqlite3IsNaN(double x){ u64 y; memcpy(&y,&x,sizeof(y)); return IsNaN(y); @@ -35354,7 +35354,7 @@ SQLITE_PRIVATE int tdsqlite3IsNaN(double x){ ** than the actual length of the string. For very long strings (greater ** than 1GiB) the value returned might be less than the true string length. */ -SQLITE_PRIVATE int tdsqlite3Strlen30(const char *z){ +SQLITE_PRIVATE int sqlite3Strlen30(const char *z){ if( z==0 ) return 0; return 0x3fffffff & (int)strlen(z); } @@ -35366,41 +35366,41 @@ SQLITE_PRIVATE int tdsqlite3Strlen30(const char *z){ ** The column type is an extra string stored after the zero-terminator on ** the column name if and only if the COLFLAG_HASTYPE flag is set. */ -SQLITE_PRIVATE char *tdsqlite3ColumnType(Column *pCol, char *zDflt){ +SQLITE_PRIVATE char *sqlite3ColumnType(Column *pCol, char *zDflt){ if( (pCol->colFlags & COLFLAG_HASTYPE)==0 ) return zDflt; return pCol->zName + strlen(pCol->zName) + 1; } /* -** Helper function for tdsqlite3Error() - called rarely. Broken out into +** Helper function for sqlite3Error() - called rarely. Broken out into ** a separate routine to avoid unnecessary register saves on entry to -** tdsqlite3Error(). +** sqlite3Error(). */ -static SQLITE_NOINLINE void tdsqlite3ErrorFinish(tdsqlite3 *db, int err_code){ - if( db->pErr ) tdsqlite3ValueSetNull(db->pErr); - tdsqlite3SystemError(db, err_code); +static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ + if( db->pErr ) sqlite3ValueSetNull(db->pErr); + sqlite3SystemError(db, err_code); } /* ** Set the current error code to err_code and clear any prior error message. -** Also set iSysErrno (by calling tdsqlite3System) if the err_code indicates +** Also set iSysErrno (by calling sqlite3System) if the err_code indicates ** that would be appropriate. */ -SQLITE_PRIVATE void tdsqlite3Error(tdsqlite3 *db, int err_code){ +SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ assert( db!=0 ); db->errCode = err_code; - if( err_code || db->pErr ) tdsqlite3ErrorFinish(db, err_code); + if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); } /* ** Load the sqlite3.iSysErrno field if that is an appropriate thing ** to do based on the SQLite error code in rc. */ -SQLITE_PRIVATE void tdsqlite3SystemError(tdsqlite3 *db, int rc){ +SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ if( rc==SQLITE_IOERR_NOMEM ) return; rc &= 0xff; if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ - db->iSysErrno = tdsqlite3OsGetLastError(db->pVfs); + db->iSysErrno = sqlite3OsGetLastError(db->pVfs); } } @@ -35421,23 +35421,23 @@ SQLITE_PRIVATE void tdsqlite3SystemError(tdsqlite3 *db, int rc){ ** zFormat and any string tokens that follow it are assumed to be ** encoded in UTF-8. ** -** To clear the most recent error for sqlite handle "db", tdsqlite3Error +** To clear the most recent error for sqlite handle "db", sqlite3Error ** should be called with err_code set to SQLITE_OK and zFormat set ** to NULL. */ -SQLITE_PRIVATE void tdsqlite3ErrorWithMsg(tdsqlite3 *db, int err_code, const char *zFormat, ...){ +SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ assert( db!=0 ); db->errCode = err_code; - tdsqlite3SystemError(db, err_code); + sqlite3SystemError(db, err_code); if( zFormat==0 ){ - tdsqlite3Error(db, err_code); - }else if( db->pErr || (db->pErr = tdsqlite3ValueNew(db))!=0 ){ + sqlite3Error(db, err_code); + }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ char *z; va_list ap; va_start(ap, zFormat); - z = tdsqlite3VMPrintf(db, zFormat, ap); + z = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); - tdsqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); + sqlite3ValueSetStr(db->pErr, -1, z, SQLITE_UTF8, SQLITE_DYNAMIC); } } @@ -35452,24 +35452,24 @@ SQLITE_PRIVATE void tdsqlite3ErrorWithMsg(tdsqlite3 *db, int err_code, const cha ** %S Insert the first element of a SrcList ** ** This function should be used to report any error that occurs while -** compiling an SQL statement (i.e. within tdsqlite3_prepare()). The -** last thing the tdsqlite3_prepare() function does is copy the error -** stored by this function into the database handle using tdsqlite3Error(). -** Functions tdsqlite3Error() or tdsqlite3ErrorWithMsg() should be used -** during statement execution (tdsqlite3_step() etc.). +** compiling an SQL statement (i.e. within sqlite3_prepare()). The +** last thing the sqlite3_prepare() function does is copy the error +** stored by this function into the database handle using sqlite3Error(). +** Functions sqlite3Error() or sqlite3ErrorWithMsg() should be used +** during statement execution (sqlite3_step() etc.). */ -SQLITE_PRIVATE void tdsqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ +SQLITE_PRIVATE void sqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ char *zMsg; va_list ap; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; va_start(ap, zFormat); - zMsg = tdsqlite3VMPrintf(db, zFormat, ap); + zMsg = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); if( db->suppressErr ){ - tdsqlite3DbFree(db, zMsg); + sqlite3DbFree(db, zMsg); }else{ pParse->nErr++; - tdsqlite3DbFree(db, pParse->zErrMsg); + sqlite3DbFree(db, pParse->zErrMsg); pParse->zErrMsg = zMsg; pParse->rc = SQLITE_ERROR; pParse->pWith = 0; @@ -35481,7 +35481,7 @@ SQLITE_PRIVATE void tdsqlite3ErrorMsg(Parse *pParse, const char *zFormat, ...){ ** error code errCode to that parser if the parser has not already ** encountered some other kind of error. */ -SQLITE_PRIVATE int tdsqlite3ErrorToParser(tdsqlite3 *db, int errCode){ +SQLITE_PRIVATE int sqlite3ErrorToParser(sqlite3 *db, int errCode){ Parse *pParse; if( db==0 || (pParse = db->pParse)==0 ) return errCode; pParse->rc = errCode; @@ -35506,12 +35506,12 @@ SQLITE_PRIVATE int tdsqlite3ErrorToParser(tdsqlite3 *db, int errCode){ ** brackets from around identifiers. For example: "[a-b-c]" becomes ** "a-b-c". */ -SQLITE_PRIVATE void tdsqlite3Dequote(char *z){ +SQLITE_PRIVATE void sqlite3Dequote(char *z){ char quote; int i, j; if( z==0 ) return; quote = z[0]; - if( !tdsqlite3Isquote(quote) ) return; + if( !sqlite3Isquote(quote) ) return; if( quote=='[' ) quote = ']'; for(i=1, j=0;; i++){ assert( z[i] ); @@ -35528,42 +35528,42 @@ SQLITE_PRIVATE void tdsqlite3Dequote(char *z){ } z[j] = 0; } -SQLITE_PRIVATE void tdsqlite3DequoteExpr(Expr *p){ - assert( tdsqlite3Isquote(p->u.zToken[0]) ); +SQLITE_PRIVATE void sqlite3DequoteExpr(Expr *p){ + assert( sqlite3Isquote(p->u.zToken[0]) ); p->flags |= p->u.zToken[0]=='"' ? EP_Quoted|EP_DblQuoted : EP_Quoted; - tdsqlite3Dequote(p->u.zToken); + sqlite3Dequote(p->u.zToken); } /* ** Generate a Token object from a string */ -SQLITE_PRIVATE void tdsqlite3TokenInit(Token *p, char *z){ +SQLITE_PRIVATE void sqlite3TokenInit(Token *p, char *z){ p->z = z; - p->n = tdsqlite3Strlen30(z); + p->n = sqlite3Strlen30(z); } /* Convenient short-hand */ -#define UpperToLower tdsqlite3UpperToLower +#define UpperToLower sqlite3UpperToLower /* ** Some systems have stricmp(). Others have strcasecmp(). Because ** there is no consistency, we will define our own. ** -** IMPLEMENTATION-OF: R-30243-02494 The tdsqlite3_stricmp() and -** tdsqlite3_strnicmp() APIs allow applications and extensions to compare +** IMPLEMENTATION-OF: R-30243-02494 The sqlite3_stricmp() and +** sqlite3_strnicmp() APIs allow applications and extensions to compare ** the contents of two buffers containing UTF-8 strings in a ** case-independent fashion, using the same definition of "case ** independence" that SQLite uses internally when comparing identifiers. */ -SQLITE_API int tdsqlite3_stricmp(const char *zLeft, const char *zRight){ +SQLITE_API int sqlite3_stricmp(const char *zLeft, const char *zRight){ if( zLeft==0 ){ return zRight ? -1 : 0; }else if( zRight==0 ){ return 1; } - return tdsqlite3StrICmp(zLeft, zRight); + return sqlite3StrICmp(zLeft, zRight); } -SQLITE_PRIVATE int tdsqlite3StrICmp(const char *zLeft, const char *zRight){ +SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){ unsigned char *a, *b; int c, x; a = (unsigned char *)zLeft; @@ -35582,7 +35582,7 @@ SQLITE_PRIVATE int tdsqlite3StrICmp(const char *zLeft, const char *zRight){ } return c; } -SQLITE_API int tdsqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ +SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ register unsigned char *a, *b; if( zLeft==0 ){ return zRight ? -1 : 0; @@ -35601,7 +35601,7 @@ SQLITE_API int tdsqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ ** ** This routine only works for values of E between 1 and 341. */ -static LONGDOUBLE_TYPE tdsqlite3Pow10(int E){ +static LONGDOUBLE_TYPE sqlite3Pow10(int E){ #if defined(_MSC_VER) static const LONGDOUBLE_TYPE x[] = { 1.0e+001L, @@ -35666,7 +35666,7 @@ static LONGDOUBLE_TYPE tdsqlite3Pow10(int E){ #if defined(_MSC_VER) #pragma warning(disable : 4756) #endif -SQLITE_PRIVATE int tdsqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ +SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult, int length, u8 enc){ #ifndef SQLITE_OMIT_FLOATING_POINT int incr; const char *zEnd; @@ -35702,7 +35702,7 @@ SQLITE_PRIVATE int tdsqlite3AtoF(const char *z, double *pResult, int length, u8 } /* skip leading spaces */ - while( z=zEnd ) return 0; /* get sign of significand */ @@ -35714,13 +35714,13 @@ SQLITE_PRIVATE int tdsqlite3AtoF(const char *z, double *pResult, int length, u8 } /* copy max significant digits to significand */ - while( z=((LARGEST_INT64-9)/10) ){ /* skip non-significant significand digits ** (increase exponent by d to shift decimal left) */ - while( z=zEnd ) goto do_atof_calc; @@ -35731,7 +35731,7 @@ SQLITE_PRIVATE int tdsqlite3AtoF(const char *z, double *pResult, int length, u8 eType++; /* copy digits from after decimal to significand ** (decrease exponent by d to shift decimal right) */ - while( z307 ){ /*OPTIMIZATION-IF-TRUE*/ if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ - LONGDOUBLE_TYPE scale = tdsqlite3Pow10(e-308); + LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308); if( esign<0 ){ result = s / scale; result /= 1.0e+308; @@ -35831,7 +35831,7 @@ do_atof_calc: } } }else{ - LONGDOUBLE_TYPE scale = tdsqlite3Pow10(e); + LONGDOUBLE_TYPE scale = sqlite3Pow10(e); if( esign<0 ){ result = s / scale; }else{ @@ -35853,7 +35853,7 @@ do_atof_calc: return 0; } #else - return !tdsqlite3Atoi64(z, pResult, length, enc); + return !sqlite3Atoi64(z, pResult, length, enc); #endif /* SQLITE_OMIT_FLOATING_POINT */ } #if defined(_MSC_VER) @@ -35907,7 +35907,7 @@ static int compare2pow63(const char *zNum, int incr){ ** The string is not necessarily zero-terminated. The encoding is ** given by enc. */ -SQLITE_PRIVATE int tdsqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ +SQLITE_PRIVATE int sqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 enc){ int incr; u64 u = 0; int neg = 0; /* assume positive */ @@ -35928,7 +35928,7 @@ SQLITE_PRIVATE int tdsqlite3Atoi64(const char *zNum, i64 *pNum, int length, u8 e zEnd = &zNum[i^1]; zNum += (enc&1); } - while( zNum=0 && c<=9; i++){ v = v*10 + c; @@ -36098,9 +36098,9 @@ SQLITE_PRIVATE int tdsqlite3GetInt32(const char *zNum, int *pValue){ ** Return a 32-bit integer value extracted from a string. If the ** string is not an integer, just return 0. */ -SQLITE_PRIVATE int tdsqlite3Atoi(const char *z){ +SQLITE_PRIVATE int sqlite3Atoi(const char *z){ int x = 0; - if( z ) tdsqlite3GetInt32(z, &x); + if( z ) sqlite3GetInt32(z, &x); return x; } @@ -36157,7 +36157,7 @@ static int SQLITE_NOINLINE putVarint64(unsigned char *p, u64 v){ } return n; } -SQLITE_PRIVATE int tdsqlite3PutVarint(unsigned char *p, u64 v){ +SQLITE_PRIVATE int sqlite3PutVarint(unsigned char *p, u64 v){ if( v<=0x7f ){ p[0] = v&0x7f; return 1; @@ -36171,7 +36171,7 @@ SQLITE_PRIVATE int tdsqlite3PutVarint(unsigned char *p, u64 v){ } /* -** Bitmasks used by tdsqlite3GetVarint(). These precomputed constants +** Bitmasks used by sqlite3GetVarint(). These precomputed constants ** are defined here rather than simply putting the constant expressions ** inline in order to work around bugs in the RVT compiler. ** @@ -36187,7 +36187,7 @@ SQLITE_PRIVATE int tdsqlite3PutVarint(unsigned char *p, u64 v){ ** Read a 64-bit variable-length integer from memory starting at p[0]. ** Return the number of bytes read. The value is stored in *v. */ -SQLITE_PRIVATE u8 tdsqlite3GetVarint(const unsigned char *p, u64 *v){ +SQLITE_PRIVATE u8 sqlite3GetVarint(const unsigned char *p, u64 *v){ u32 a,b,s; if( ((signed char*)p)[0]>=0 ){ @@ -36348,7 +36348,7 @@ SQLITE_PRIVATE u8 tdsqlite3GetVarint(const unsigned char *p, u64 *v){ ** single-byte case. All code should use the MACRO version as ** this function assumes the single-byte case has already been handled. */ -SQLITE_PRIVATE u8 tdsqlite3GetVarint32(const unsigned char *p, u32 *v){ +SQLITE_PRIVATE u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ u32 a,b; /* The 1-byte case. Overwhelmingly the most common. Handled inline @@ -36407,7 +36407,7 @@ SQLITE_PRIVATE u8 tdsqlite3GetVarint32(const unsigned char *p, u32 *v){ u8 n; p -= 2; - n = tdsqlite3GetVarint(p, &v64); + n = sqlite3GetVarint(p, &v64); assert( n>3 && n<=9 ); if( (v64 & SQLITE_MAX_U32)!=v64 ){ *v = 0xffffffff; @@ -36452,14 +36452,14 @@ SQLITE_PRIVATE u8 tdsqlite3GetVarint32(const unsigned char *p, u32 *v){ /* We can only reach this point when reading a corrupt database ** file. In that case we are not in any hurry. Use the (relatively - ** slow) general-purpose tdsqlite3GetVarint() routine to extract the + ** slow) general-purpose sqlite3GetVarint() routine to extract the ** value. */ { u64 v64; u8 n; p -= 4; - n = tdsqlite3GetVarint(p, &v64); + n = sqlite3GetVarint(p, &v64); assert( n>5 && n<=9 ); *v = (u32)v64; return n; @@ -36471,7 +36471,7 @@ SQLITE_PRIVATE u8 tdsqlite3GetVarint32(const unsigned char *p, u32 *v){ ** Return the number of bytes that will be needed to store the given ** 64-bit integer. */ -SQLITE_PRIVATE int tdsqlite3VarintLen(u64 v){ +SQLITE_PRIVATE int sqlite3VarintLen(u64 v){ int i; for(i=1; (v >>= 7)!=0; i++){ assert( i<10 ); } return i; @@ -36481,7 +36481,7 @@ SQLITE_PRIVATE int tdsqlite3VarintLen(u64 v){ /* ** Read or write a four-byte big-endian integer value. */ -SQLITE_PRIVATE u32 tdsqlite3Get4byte(const u8 *p){ +SQLITE_PRIVATE u32 sqlite3Get4byte(const u8 *p){ #if SQLITE_BYTEORDER==4321 u32 x; memcpy(&x,p,4); @@ -36499,7 +36499,7 @@ SQLITE_PRIVATE u32 tdsqlite3Get4byte(const u8 *p){ return ((unsigned)p[0]<<24) | (p[1]<<16) | (p[2]<<8) | p[3]; #endif } -SQLITE_PRIVATE void tdsqlite3Put4byte(unsigned char *p, u32 v){ +SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ #if SQLITE_BYTEORDER==4321 memcpy(p,&v,4); #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 @@ -36523,7 +36523,7 @@ SQLITE_PRIVATE void tdsqlite3Put4byte(unsigned char *p, u32 v){ ** This routine only works if h really is a valid hexadecimal ** character: 0..9a..fA..F */ -SQLITE_PRIVATE u8 tdsqlite3HexToInt(int h){ +SQLITE_PRIVATE u8 sqlite3HexToInt(int h){ assert( (h>='0' && h<='9') || (h>='a' && h<='f') || (h>='A' && h<='F') ); #ifdef SQLITE_ASCII h += 9*(1&(h>>6)); @@ -36541,15 +36541,15 @@ SQLITE_PRIVATE u8 tdsqlite3HexToInt(int h){ ** binary value has been obtained from malloc and must be freed by ** the calling routine. */ -SQLITE_PRIVATE void *tdsqlite3HexToBlob(tdsqlite3 *db, const char *z, int n){ +SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3 *db, const char *z, int n){ char *zBlob; int i; - zBlob = (char *)tdsqlite3DbMallocRawNN(db, n/2 + 1); + zBlob = (char *)sqlite3DbMallocRawNN(db, n/2 + 1); n--; if( zBlob ){ for(i=0; imagic; if( magic!=SQLITE_MAGIC_OPEN ){ - if( tdsqlite3SafetyCheckSickOrOk(db) ){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); + if( sqlite3SafetyCheckSickOrOk(db) ){ + testcase( sqlite3GlobalConfig.xLog!=0 ); logBadConnection("unopened"); } return 0; @@ -36600,13 +36600,13 @@ SQLITE_PRIVATE int tdsqlite3SafetyCheckOk(tdsqlite3 *db){ return 1; } } -SQLITE_PRIVATE int tdsqlite3SafetyCheckSickOrOk(tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ u32 magic; magic = db->magic; if( magic!=SQLITE_MAGIC_SICK && magic!=SQLITE_MAGIC_OPEN && magic!=SQLITE_MAGIC_BUSY ){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); + testcase( sqlite3GlobalConfig.xLog!=0 ); logBadConnection("invalid"); return 0; }else{ @@ -36620,7 +36620,7 @@ SQLITE_PRIVATE int tdsqlite3SafetyCheckSickOrOk(tdsqlite3 *db){ ** Return 0 on success. Or if the operation would have resulted in an ** overflow, leave *pA unchanged and return 1. */ -SQLITE_PRIVATE int tdsqlite3AddInt64(i64 *pA, i64 iB){ +SQLITE_PRIVATE int sqlite3AddInt64(i64 *pA, i64 iB){ #if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) return __builtin_add_overflow(*pA, iB, pA); #else @@ -36640,7 +36640,7 @@ SQLITE_PRIVATE int tdsqlite3AddInt64(i64 *pA, i64 iB){ return 0; #endif } -SQLITE_PRIVATE int tdsqlite3SubInt64(i64 *pA, i64 iB){ +SQLITE_PRIVATE int sqlite3SubInt64(i64 *pA, i64 iB){ #if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) return __builtin_sub_overflow(*pA, iB, pA); #else @@ -36651,11 +36651,11 @@ SQLITE_PRIVATE int tdsqlite3SubInt64(i64 *pA, i64 iB){ *pA -= iB; return 0; }else{ - return tdsqlite3AddInt64(pA, -iB); + return sqlite3AddInt64(pA, -iB); } #endif } -SQLITE_PRIVATE int tdsqlite3MulInt64(i64 *pA, i64 iB){ +SQLITE_PRIVATE int sqlite3MulInt64(i64 *pA, i64 iB){ #if GCC_VERSION>=5004000 && !defined(__INTEL_COMPILER) return __builtin_mul_overflow(*pA, iB, pA); #else @@ -36681,7 +36681,7 @@ SQLITE_PRIVATE int tdsqlite3MulInt64(i64 *pA, i64 iB){ ** Compute the absolute value of a 32-bit signed integer, of possible. Or ** if the integer has a value of -2147483648, return +2147483647 */ -SQLITE_PRIVATE int tdsqlite3AbsInt32(int x){ +SQLITE_PRIVATE int sqlite3AbsInt32(int x){ if( x>=0 ) return x; if( x==(int)0x80000000 ) return 0x7fffffff; return -x; @@ -36705,13 +36705,13 @@ SQLITE_PRIVATE int tdsqlite3AbsInt32(int x){ ** test.db-shm => test.shm ** test.db-mj7f3319fa => test.9fa */ -SQLITE_PRIVATE void tdsqlite3FileSuffix3(const char *zBaseFilename, char *z){ +SQLITE_PRIVATE void sqlite3FileSuffix3(const char *zBaseFilename, char *z){ #if SQLITE_ENABLE_8_3_NAMES<2 - if( tdsqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) + if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) ) #endif { int i, sz; - sz = tdsqlite3Strlen30(z); + sz = sqlite3Strlen30(z); for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){} if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4); } @@ -36724,7 +36724,7 @@ SQLITE_PRIVATE void tdsqlite3FileSuffix3(const char *zBaseFilename, char *z){ ** value. ** */ -SQLITE_PRIVATE LogEst tdsqlite3LogEstAdd(LogEst a, LogEst b){ +SQLITE_PRIVATE LogEst sqlite3LogEstAdd(LogEst a, LogEst b){ static const unsigned char x[] = { 10, 10, /* 0,1 */ 9, 9, /* 2,3 */ @@ -36751,7 +36751,7 @@ SQLITE_PRIVATE LogEst tdsqlite3LogEstAdd(LogEst a, LogEst b){ ** Convert an integer into a LogEst. In other words, compute an ** approximation for 10*log2(x). */ -SQLITE_PRIVATE LogEst tdsqlite3LogEst(u64 x){ +SQLITE_PRIVATE LogEst sqlite3LogEst(u64 x){ static LogEst a[] = { 0, 2, 3, 5, 6, 7, 8, 9 }; LogEst y = 40; if( x<8 ){ @@ -36775,12 +36775,12 @@ SQLITE_PRIVATE LogEst tdsqlite3LogEst(u64 x){ ** Convert a double into a LogEst ** In other words, compute an approximation for 10*log2(x). */ -SQLITE_PRIVATE LogEst tdsqlite3LogEstFromDouble(double x){ +SQLITE_PRIVATE LogEst sqlite3LogEstFromDouble(double x){ u64 a; LogEst e; assert( sizeof(x)==8 && sizeof(a)==8 ); if( x<=1 ) return 0; - if( x<=2000000000 ) return tdsqlite3LogEst((u64)x); + if( x<=2000000000 ) return sqlite3LogEst((u64)x); memcpy(&a, &x, 8); e = (a>>52) - 1022; return e*10; @@ -36796,7 +36796,7 @@ SQLITE_PRIVATE LogEst tdsqlite3LogEstFromDouble(double x){ ** Note that this routine is only used when one or more of various ** non-standard compile-time options is enabled. */ -SQLITE_PRIVATE u64 tdsqlite3LogEstToInt(LogEst x){ +SQLITE_PRIVATE u64 sqlite3LogEstToInt(LogEst x){ u64 n; n = x%10; x /= 10; @@ -36821,7 +36821,7 @@ SQLITE_PRIVATE u64 tdsqlite3LogEstToInt(LogEst x){ ** db->mallocFailed flag is set. ** ** A VList is really just an array of integers. To destroy a VList, -** simply pass it to tdsqlite3DbFree(). +** simply pass it to sqlite3DbFree(). ** ** The first integer is the number of integers allocated for the whole ** VList. The second integer is the number of integers actually used. @@ -36850,8 +36850,8 @@ SQLITE_PRIVATE u64 tdsqlite3LogEstToInt(LogEst x){ ** indication that the VList may never again be enlarged, since the ** accompanying realloc() would invalidate the pointers. */ -SQLITE_PRIVATE VList *tdsqlite3VListAdd( - tdsqlite3 *db, /* The database connection used for malloc() */ +SQLITE_PRIVATE VList *sqlite3VListAdd( + sqlite3 *db, /* The database connection used for malloc() */ VList *pIn, /* The input VList. Might be NULL */ const char *zName, /* Name of symbol to add */ int nName, /* Bytes of text in zName */ @@ -36865,8 +36865,8 @@ SQLITE_PRIVATE VList *tdsqlite3VListAdd( assert( pIn==0 || pIn[0]>=3 ); /* Verify ok to add new elements */ if( pIn==0 || pIn[1]+nInt > pIn[0] ){ /* Enlarge the allocation */ - tdsqlite3_int64 nAlloc = (pIn ? 2*(tdsqlite3_int64)pIn[0] : 10) + nInt; - VList *pOut = tdsqlite3DbRealloc(db, pIn, nAlloc*sizeof(int)); + sqlite3_int64 nAlloc = (pIn ? 2*(sqlite3_int64)pIn[0] : 10) + nInt; + VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int)); if( pOut==0 ) return pIn; if( pIn==0 ) pOut[1] = 2; pIn = pOut; @@ -36888,7 +36888,7 @@ SQLITE_PRIVATE VList *tdsqlite3VListAdd( ** has the value iVal. Or return a NULL if there is no such variable in ** the list */ -SQLITE_PRIVATE const char *tdsqlite3VListNumToName(VList *pIn, int iVal){ +SQLITE_PRIVATE const char *sqlite3VListNumToName(VList *pIn, int iVal){ int i, mx; if( pIn==0 ) return 0; mx = pIn[1]; @@ -36904,7 +36904,7 @@ SQLITE_PRIVATE const char *tdsqlite3VListNumToName(VList *pIn, int iVal){ ** Return the number of the variable named zName, if it is in VList. ** or return 0 if there is no such variable. */ -SQLITE_PRIVATE int tdsqlite3VListNameToNum(VList *pIn, const char *zName, int nName){ +SQLITE_PRIVATE int sqlite3VListNameToNum(VList *pIn, const char *zName, int nName){ int i, mx; if( pIn==0 ) return 0; mx = pIn[1]; @@ -36941,7 +36941,7 @@ SQLITE_PRIVATE int tdsqlite3VListNameToNum(VList *pIn, const char *zName, int nN ** ** "pNew" is a pointer to the hash table that is to be initialized. */ -SQLITE_PRIVATE void tdsqlite3HashInit(Hash *pNew){ +SQLITE_PRIVATE void sqlite3HashInit(Hash *pNew){ assert( pNew!=0 ); pNew->first = 0; pNew->count = 0; @@ -36953,18 +36953,18 @@ SQLITE_PRIVATE void tdsqlite3HashInit(Hash *pNew){ ** Call this routine to delete a hash table or to reset a hash table ** to the empty state. */ -SQLITE_PRIVATE void tdsqlite3HashClear(Hash *pH){ +SQLITE_PRIVATE void sqlite3HashClear(Hash *pH){ HashElem *elem; /* For looping over all elements of the table */ assert( pH!=0 ); elem = pH->first; pH->first = 0; - tdsqlite3_free(pH->ht); + sqlite3_free(pH->ht); pH->ht = 0; pH->htsize = 0; while( elem ){ HashElem *next_elem = elem->next; - tdsqlite3_free(elem); + sqlite3_free(elem); elem = next_elem; } pH->count = 0; @@ -36980,7 +36980,7 @@ static unsigned int strHash(const char *z){ /* Knuth multiplicative hashing. (Sorting & Searching, p. 510). ** 0x9e3779b1 is 2654435761 which is the closest prime number to ** (2**32)*golden_ratio, where golden_ratio = (sqrt(5) - 1)/2. */ - h += tdsqlite3UpperToLower[c]; + h += sqlite3UpperToLower[c]; h *= 0x9e3779b1; } return h; @@ -37020,7 +37020,7 @@ static void insertElement( /* Resize the hash table so that it cantains "new_size" buckets. ** -** The hash table might fail to resize if tdsqlite3_malloc() fails or +** The hash table might fail to resize if sqlite3_malloc() fails or ** if the new size is the same as the prior size. ** Return TRUE if the resize occurs and false if not. */ @@ -37037,20 +37037,20 @@ static int rehash(Hash *pH, unsigned int new_size){ /* The inability to allocates space for a larger hash table is ** a performance hit but it is not a fatal error. So mark the - ** allocation as a benign. Use tdsqlite3Malloc()/memset(0) instead of - ** tdsqlite3MallocZero() to make the allocation, as tdsqlite3MallocZero() + ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of + ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() ** only zeroes the requested number of bytes whereas this module will ** use the actual amount of space allocated for the hash table (which ** may be larger than the requested amount). */ - tdsqlite3BeginBenignMalloc(); - new_ht = (struct _ht *)tdsqlite3Malloc( new_size*sizeof(struct _ht) ); - tdsqlite3EndBenignMalloc(); + sqlite3BeginBenignMalloc(); + new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); + sqlite3EndBenignMalloc(); if( new_ht==0 ) return 0; - tdsqlite3_free(pH->ht); + sqlite3_free(pH->ht); pH->ht = new_ht; - pH->htsize = new_size = tdsqlite3MallocSize(new_ht)/sizeof(struct _ht); + pH->htsize = new_size = sqlite3MallocSize(new_ht)/sizeof(struct _ht); memset(new_ht, 0, new_size*sizeof(struct _ht)); for(elem=pH->first, pH->first=0; elem; elem = next_elem){ unsigned int h = strHash(elem->pKey) % new_size; @@ -37089,7 +37089,7 @@ static HashElem *findElementWithHash( if( pHash ) *pHash = h; while( count-- ){ assert( elem!=0 ); - if( tdsqlite3StrICmp(elem->pKey,pKey)==0 ){ + if( sqlite3StrICmp(elem->pKey,pKey)==0 ){ return elem; } elem = elem->next; @@ -37122,12 +37122,12 @@ static void removeElementGivenHash( assert( pEntry->count>0 ); pEntry->count--; } - tdsqlite3_free( elem ); + sqlite3_free( elem ); pH->count--; if( pH->count==0 ){ assert( pH->first==0 ); assert( pH->count==0 ); - tdsqlite3HashClear(pH); + sqlite3HashClear(pH); } } @@ -37135,7 +37135,7 @@ static void removeElementGivenHash( ** that matches pKey. Return the data for this element if it is ** found, or NULL if there is no match. */ -SQLITE_PRIVATE void *tdsqlite3HashFind(const Hash *pH, const char *pKey){ +SQLITE_PRIVATE void *sqlite3HashFind(const Hash *pH, const char *pKey){ assert( pH!=0 ); assert( pKey!=0 ); return findElementWithHash(pH, pKey, 0)->data; @@ -37155,7 +37155,7 @@ SQLITE_PRIVATE void *tdsqlite3HashFind(const Hash *pH, const char *pKey){ ** If the "data" parameter to this function is NULL, then the ** element corresponding to "key" is removed from the hash table. */ -SQLITE_PRIVATE void *tdsqlite3HashInsert(Hash *pH, const char *pKey, void *data){ +SQLITE_PRIVATE void *sqlite3HashInsert(Hash *pH, const char *pKey, void *data){ unsigned int h; /* the hash of the key modulo hash table size */ HashElem *elem; /* Used to loop thru the element list */ HashElem *new_elem; /* New element added to the pH */ @@ -37174,7 +37174,7 @@ SQLITE_PRIVATE void *tdsqlite3HashInsert(Hash *pH, const char *pKey, void *data) return old_data; } if( data==0 ) return 0; - new_elem = (HashElem*)tdsqlite3Malloc( sizeof(HashElem) ); + new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) ); if( new_elem==0 ) return data; new_elem->pKey = pKey; new_elem->data = data; @@ -37201,7 +37201,7 @@ SQLITE_PRIVATE void *tdsqlite3HashInsert(Hash *pH, const char *pKey, void *data) #else # define OpHelp(X) #endif -SQLITE_PRIVATE const char *tdsqlite3OpcodeName(int i){ +SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ static const char *const azName[] = { /* 0 */ "Savepoint" OpHelp(""), /* 1 */ "AutoCommit" OpHelp(""), @@ -37423,13 +37423,13 @@ SQLITE_PRIVATE const char *tdsqlite3OpcodeName(int i){ ** + for flock() locking ** + for named semaphore locks (VxWorks only) ** + for AFP filesystem locks (MacOSX only) -** * tdsqlite3_file methods not associated with locking. -** * Definitions of tdsqlite3_io_methods objects for all locking +** * sqlite3_file methods not associated with locking. +** * Definitions of sqlite3_io_methods objects for all locking ** methods plus "finder" functions for each locking method. -** * tdsqlite3_vfs method implementations. +** * sqlite3_vfs method implementations. ** * Locking primitives for the proxy uber-locking-method. (MacOSX only) -** * Definitions of tdsqlite3_vfs objects for all locking methods -** plus implementations of tdsqlite3_os_init() and tdsqlite3_os_end(). +** * Definitions of sqlite3_vfs objects for all locking methods +** plus implementations of sqlite3_os_init() and sqlite3_os_end(). */ /* #include "sqliteInt.h" */ #if SQLITE_OS_UNIX /* This file is used on unix only */ @@ -37599,13 +37599,13 @@ struct UnixUnusedFd { }; /* -** The unixFile structure is subclass of tdsqlite3_file specific to the unix +** The unixFile structure is subclass of sqlite3_file specific to the unix ** VFS implementations. */ typedef struct unixFile unixFile; struct unixFile { - tdsqlite3_io_methods const *pMethod; /* Always the first entry */ - tdsqlite3_vfs *pVfs; /* The VFS that created this unixFile */ + sqlite3_io_methods const *pMethod; /* Always the first entry */ + sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ @@ -37618,9 +37618,9 @@ struct unixFile { int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ #if SQLITE_MAX_MMAP_SIZE>0 int nFetchOut; /* Number of outstanding xFetch refs */ - tdsqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ - tdsqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ - tdsqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ + sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ + sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ void *pMapRegion; /* Memory mapped region */ #endif int sectorSize; /* Device sector size */ @@ -37759,7 +37759,7 @@ static pid_t randomnessPid = 0; #if defined(__GNUC__) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned int lo, hi; __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); return (sqlite_uint64)hi << 32 | lo; @@ -37767,7 +37767,7 @@ static pid_t randomnessPid = 0; #elif defined(_MSC_VER) - __declspec(naked) __inline sqlite_uint64 __cdecl tdsqlite3Hwtime(void){ + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ __asm { rdtsc ret ; return value at EDX:EAX @@ -37778,7 +37778,7 @@ static pid_t randomnessPid = 0; #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long val; __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; @@ -37786,7 +37786,7 @@ static pid_t randomnessPid = 0; #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long long retval; unsigned long junk; __asm__ __volatile__ ("\n\ @@ -37803,13 +37803,13 @@ static pid_t randomnessPid = 0; /* ** asm() is needed for hardware timing support. Without asm(), - ** disable the tdsqlite3Hwtime() routine. + ** disable the sqlite3Hwtime() routine. ** - ** tdsqlite3Hwtime() is only used for some obscure debugging + ** sqlite3Hwtime() is only used for some obscure debugging ** and analysis configurations, not in any deliverable, so this ** should not be a great loss. */ -SQLITE_PRIVATE sqlite_uint64 tdsqlite3Hwtime(void){ return ((sqlite_uint64)0); } +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } #endif @@ -37820,8 +37820,8 @@ SQLITE_PRIVATE sqlite_uint64 tdsqlite3Hwtime(void){ return ((sqlite_uint64)0); static sqlite_uint64 g_start; static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=tdsqlite3Hwtime() -#define TIMER_END g_elapsed=tdsqlite3Hwtime()-g_start +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start #define TIMER_ELAPSED g_elapsed #else #define TIMER_START @@ -37835,32 +37835,32 @@ static sqlite_uint64 g_elapsed; ** is used for testing the I/O recovery logic. */ #if defined(SQLITE_TEST) -SQLITE_API extern int tdsqlite3_io_error_hit; -SQLITE_API extern int tdsqlite3_io_error_hardhit; -SQLITE_API extern int tdsqlite3_io_error_pending; -SQLITE_API extern int tdsqlite3_io_error_persist; -SQLITE_API extern int tdsqlite3_io_error_benign; -SQLITE_API extern int tdsqlite3_diskfull_pending; -SQLITE_API extern int tdsqlite3_diskfull; -#define SimulateIOErrorBenign(X) tdsqlite3_io_error_benign=(X) +SQLITE_API extern int sqlite3_io_error_hit; +SQLITE_API extern int sqlite3_io_error_hardhit; +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_persist; +SQLITE_API extern int sqlite3_io_error_benign; +SQLITE_API extern int sqlite3_diskfull_pending; +SQLITE_API extern int sqlite3_diskfull; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) #define SimulateIOError(CODE) \ - if( (tdsqlite3_io_error_persist && tdsqlite3_io_error_hit) \ - || tdsqlite3_io_error_pending-- == 1 ) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ { local_ioerr(); CODE; } static void local_ioerr(){ IOTRACE(("IOERR\n")); - tdsqlite3_io_error_hit++; - if( !tdsqlite3_io_error_benign ) tdsqlite3_io_error_hardhit++; + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; } #define SimulateDiskfullError(CODE) \ - if( tdsqlite3_diskfull_pending ){ \ - if( tdsqlite3_diskfull_pending == 1 ){ \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ local_ioerr(); \ - tdsqlite3_diskfull = 1; \ - tdsqlite3_io_error_hit = 1; \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ CODE; \ }else{ \ - tdsqlite3_diskfull_pending--; \ + sqlite3_diskfull_pending--; \ } \ } #else @@ -37873,8 +37873,8 @@ static void local_ioerr(){ ** When testing, keep a count of the number of open files. */ #if defined(SQLITE_TEST) -SQLITE_API extern int tdsqlite3_open_file_count; -#define OpenCounter(X) tdsqlite3_open_file_count+=(X) +SQLITE_API extern int sqlite3_open_file_count; +#define OpenCounter(X) sqlite3_open_file_count+=(X) #else #define OpenCounter(X) #endif /* defined(SQLITE_TEST) */ @@ -37968,22 +37968,22 @@ static int unixGetpagesize(void); */ static struct unix_syscall { const char *zName; /* Name of the system call */ - tdsqlite3_syscall_ptr pCurrent; /* Current value of the system call */ - tdsqlite3_syscall_ptr pDefault; /* Default value */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ } aSyscall[] = { - { "open", (tdsqlite3_syscall_ptr)posixOpen, 0 }, + { "open", (sqlite3_syscall_ptr)posixOpen, 0 }, #define osOpen ((int(*)(const char*,int,int))aSyscall[0].pCurrent) - { "close", (tdsqlite3_syscall_ptr)close, 0 }, + { "close", (sqlite3_syscall_ptr)close, 0 }, #define osClose ((int(*)(int))aSyscall[1].pCurrent) - { "access", (tdsqlite3_syscall_ptr)access, 0 }, + { "access", (sqlite3_syscall_ptr)access, 0 }, #define osAccess ((int(*)(const char*,int))aSyscall[2].pCurrent) - { "getcwd", (tdsqlite3_syscall_ptr)getcwd, 0 }, + { "getcwd", (sqlite3_syscall_ptr)getcwd, 0 }, #define osGetcwd ((char*(*)(char*,size_t))aSyscall[3].pCurrent) - { "stat", (tdsqlite3_syscall_ptr)stat, 0 }, + { "stat", (sqlite3_syscall_ptr)stat, 0 }, #define osStat ((int(*)(const char*,struct stat*))aSyscall[4].pCurrent) /* @@ -37996,140 +37996,140 @@ static struct unix_syscall { { "fstat", 0, 0 }, #define osFstat(a,b,c) 0 #else - { "fstat", (tdsqlite3_syscall_ptr)fstat, 0 }, + { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, #define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) #endif - { "ftruncate", (tdsqlite3_syscall_ptr)ftruncate, 0 }, + { "ftruncate", (sqlite3_syscall_ptr)ftruncate, 0 }, #define osFtruncate ((int(*)(int,off_t))aSyscall[6].pCurrent) - { "fcntl", (tdsqlite3_syscall_ptr)fcntl, 0 }, + { "fcntl", (sqlite3_syscall_ptr)fcntl, 0 }, #define osFcntl ((int(*)(int,int,...))aSyscall[7].pCurrent) - { "read", (tdsqlite3_syscall_ptr)read, 0 }, + { "read", (sqlite3_syscall_ptr)read, 0 }, #define osRead ((ssize_t(*)(int,void*,size_t))aSyscall[8].pCurrent) #if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE - { "pread", (tdsqlite3_syscall_ptr)pread, 0 }, + { "pread", (sqlite3_syscall_ptr)pread, 0 }, #else - { "pread", (tdsqlite3_syscall_ptr)0, 0 }, + { "pread", (sqlite3_syscall_ptr)0, 0 }, #endif #define osPread ((ssize_t(*)(int,void*,size_t,off_t))aSyscall[9].pCurrent) #if defined(USE_PREAD64) - { "pread64", (tdsqlite3_syscall_ptr)pread64, 0 }, + { "pread64", (sqlite3_syscall_ptr)pread64, 0 }, #else - { "pread64", (tdsqlite3_syscall_ptr)0, 0 }, + { "pread64", (sqlite3_syscall_ptr)0, 0 }, #endif #define osPread64 ((ssize_t(*)(int,void*,size_t,off64_t))aSyscall[10].pCurrent) - { "write", (tdsqlite3_syscall_ptr)write, 0 }, + { "write", (sqlite3_syscall_ptr)write, 0 }, #define osWrite ((ssize_t(*)(int,const void*,size_t))aSyscall[11].pCurrent) #if defined(USE_PREAD) || SQLITE_ENABLE_LOCKING_STYLE - { "pwrite", (tdsqlite3_syscall_ptr)pwrite, 0 }, + { "pwrite", (sqlite3_syscall_ptr)pwrite, 0 }, #else - { "pwrite", (tdsqlite3_syscall_ptr)0, 0 }, + { "pwrite", (sqlite3_syscall_ptr)0, 0 }, #endif #define osPwrite ((ssize_t(*)(int,const void*,size_t,off_t))\ aSyscall[12].pCurrent) #if defined(USE_PREAD64) - { "pwrite64", (tdsqlite3_syscall_ptr)pwrite64, 0 }, + { "pwrite64", (sqlite3_syscall_ptr)pwrite64, 0 }, #else - { "pwrite64", (tdsqlite3_syscall_ptr)0, 0 }, + { "pwrite64", (sqlite3_syscall_ptr)0, 0 }, #endif #define osPwrite64 ((ssize_t(*)(int,const void*,size_t,off64_t))\ aSyscall[13].pCurrent) - { "fchmod", (tdsqlite3_syscall_ptr)fchmod, 0 }, + { "fchmod", (sqlite3_syscall_ptr)fchmod, 0 }, #define osFchmod ((int(*)(int,mode_t))aSyscall[14].pCurrent) #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE - { "fallocate", (tdsqlite3_syscall_ptr)posix_fallocate, 0 }, + { "fallocate", (sqlite3_syscall_ptr)posix_fallocate, 0 }, #else - { "fallocate", (tdsqlite3_syscall_ptr)0, 0 }, + { "fallocate", (sqlite3_syscall_ptr)0, 0 }, #endif #define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent) - { "unlink", (tdsqlite3_syscall_ptr)unlink, 0 }, + { "unlink", (sqlite3_syscall_ptr)unlink, 0 }, #define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent) - { "openDirectory", (tdsqlite3_syscall_ptr)openDirectory, 0 }, + { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 }, #define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent) - { "mkdir", (tdsqlite3_syscall_ptr)mkdir, 0 }, + { "mkdir", (sqlite3_syscall_ptr)mkdir, 0 }, #define osMkdir ((int(*)(const char*,mode_t))aSyscall[18].pCurrent) - { "rmdir", (tdsqlite3_syscall_ptr)rmdir, 0 }, + { "rmdir", (sqlite3_syscall_ptr)rmdir, 0 }, #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) #if defined(HAVE_FCHOWN) - { "fchown", (tdsqlite3_syscall_ptr)fchown, 0 }, + { "fchown", (sqlite3_syscall_ptr)fchown, 0 }, #else - { "fchown", (tdsqlite3_syscall_ptr)0, 0 }, + { "fchown", (sqlite3_syscall_ptr)0, 0 }, #endif #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) #if defined(HAVE_FCHOWN) - { "geteuid", (tdsqlite3_syscall_ptr)geteuid, 0 }, + { "geteuid", (sqlite3_syscall_ptr)geteuid, 0 }, #else - { "geteuid", (tdsqlite3_syscall_ptr)0, 0 }, + { "geteuid", (sqlite3_syscall_ptr)0, 0 }, #endif #define osGeteuid ((uid_t(*)(void))aSyscall[21].pCurrent) #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 - { "mmap", (tdsqlite3_syscall_ptr)mmap, 0 }, + { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, #else - { "mmap", (tdsqlite3_syscall_ptr)0, 0 }, + { "mmap", (sqlite3_syscall_ptr)0, 0 }, #endif #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[22].pCurrent) #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 - { "munmap", (tdsqlite3_syscall_ptr)munmap, 0 }, + { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, #else - { "munmap", (tdsqlite3_syscall_ptr)0, 0 }, + { "munmap", (sqlite3_syscall_ptr)0, 0 }, #endif #define osMunmap ((int(*)(void*,size_t))aSyscall[23].pCurrent) #if HAVE_MREMAP && (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) - { "mremap", (tdsqlite3_syscall_ptr)mremap, 0 }, + { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, #else - { "mremap", (tdsqlite3_syscall_ptr)0, 0 }, + { "mremap", (sqlite3_syscall_ptr)0, 0 }, #endif #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[24].pCurrent) #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 - { "getpagesize", (tdsqlite3_syscall_ptr)unixGetpagesize, 0 }, + { "getpagesize", (sqlite3_syscall_ptr)unixGetpagesize, 0 }, #else - { "getpagesize", (tdsqlite3_syscall_ptr)0, 0 }, + { "getpagesize", (sqlite3_syscall_ptr)0, 0 }, #endif #define osGetpagesize ((int(*)(void))aSyscall[25].pCurrent) #if defined(HAVE_READLINK) - { "readlink", (tdsqlite3_syscall_ptr)readlink, 0 }, + { "readlink", (sqlite3_syscall_ptr)readlink, 0 }, #else - { "readlink", (tdsqlite3_syscall_ptr)0, 0 }, + { "readlink", (sqlite3_syscall_ptr)0, 0 }, #endif #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent) #if defined(HAVE_LSTAT) - { "lstat", (tdsqlite3_syscall_ptr)lstat, 0 }, + { "lstat", (sqlite3_syscall_ptr)lstat, 0 }, #else - { "lstat", (tdsqlite3_syscall_ptr)0, 0 }, + { "lstat", (sqlite3_syscall_ptr)0, 0 }, #endif #define osLstat ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent) #if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) # ifdef __ANDROID__ - { "ioctl", (tdsqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, + { "ioctl", (sqlite3_syscall_ptr)(int(*)(int, int, ...))ioctl, 0 }, #define osIoctl ((int(*)(int,int,...))aSyscall[28].pCurrent) # else - { "ioctl", (tdsqlite3_syscall_ptr)ioctl, 0 }, + { "ioctl", (sqlite3_syscall_ptr)ioctl, 0 }, #define osIoctl ((int(*)(int,unsigned long,...))aSyscall[28].pCurrent) # endif #else - { "ioctl", (tdsqlite3_syscall_ptr)0, 0 }, + { "ioctl", (sqlite3_syscall_ptr)0, 0 }, #endif }; /* End of the overrideable system calls */ @@ -38149,15 +38149,15 @@ static int robustFchown(int fd, uid_t uid, gid_t gid){ } /* -** This is the xSetSystemCall() method of tdsqlite3_vfs for all of the +** This is the xSetSystemCall() method of sqlite3_vfs for all of the ** "unix" VFSes. Return SQLITE_OK opon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable ** system call named zName. */ static int unixSetSystemCall( - tdsqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ const char *zName, /* Name of system call to override */ - tdsqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ ){ unsigned int i; int rc = SQLITE_NOTFOUND; @@ -38197,8 +38197,8 @@ static int unixSetSystemCall( ** recognized system call name. NULL is also returned if the system call ** is currently undefined. */ -static tdsqlite3_syscall_ptr unixGetSystemCall( - tdsqlite3_vfs *pNotUsed, +static sqlite3_syscall_ptr unixGetSystemCall( + sqlite3_vfs *pNotUsed, const char *zName ){ unsigned int i; @@ -38216,7 +38216,7 @@ static tdsqlite3_syscall_ptr unixGetSystemCall( ** is the last system call or if zName is not the name of a valid ** system call. */ -static const char *unixNextSystemCall(tdsqlite3_vfs *p, const char *zName){ +static const char *unixNextSystemCall(sqlite3_vfs *p, const char *zName){ int i = -1; UNUSED_PARAMETER(p); @@ -38272,7 +38272,7 @@ static int robust_open(const char *z, int f, mode_t m){ } if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; osClose(fd); - tdsqlite3_log(SQLITE_WARNING, + sqlite3_log(SQLITE_WARNING, "attempt to open \"%s\" as file descriptor %d", z, fd); fd = -1; if( osOpen("/dev/null", f, m)<0 ) break; @@ -38319,18 +38319,18 @@ static int robust_open(const char *z, int f, mode_t m){ ** OK: enter(pLockInfo) ** ERROR: enter(pLockInfo), enter(unixBigLock) */ -static tdsqlite3_mutex *unixBigLock = 0; +static sqlite3_mutex *unixBigLock = 0; static void unixEnterMutex(void){ - assert( tdsqlite3_mutex_notheld(unixBigLock) ); /* Not a recursive mutex */ - tdsqlite3_mutex_enter(unixBigLock); + assert( sqlite3_mutex_notheld(unixBigLock) ); /* Not a recursive mutex */ + sqlite3_mutex_enter(unixBigLock); } static void unixLeaveMutex(void){ - assert( tdsqlite3_mutex_held(unixBigLock) ); - tdsqlite3_mutex_leave(unixBigLock); + assert( sqlite3_mutex_held(unixBigLock) ); + sqlite3_mutex_leave(unixBigLock); } #ifdef SQLITE_DEBUG static int unixMutexHeld(void) { - return tdsqlite3_mutex_held(unixBigLock); + return sqlite3_mutex_held(unixBigLock); } #endif @@ -38372,7 +38372,7 @@ static int lockTrace(int fd, int op, struct flock *p){ zOpName = "SETLK"; }else{ s = osFcntl(fd, op, p); - tdsqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); + sqlite3DebugPrintf("fcntl unknown %d %d %d\n", fd, op, s); return s; } if( p->l_type==F_RDLCK ){ @@ -38387,7 +38387,7 @@ static int lockTrace(int fd, int op, struct flock *p){ assert( p->l_whence==SEEK_SET ); s = osFcntl(fd, op, p); savedErrno = errno; - tdsqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", + sqlite3DebugPrintf("fcntl %d %d %s %s %d %d %d %d\n", threadid, fd, zOpName, zType, (int)p->l_start, (int)p->l_len, (int)p->l_pid, s); if( s==(-1) && op==F_SETLK && (p->l_type==F_RDLCK || p->l_type==F_WRLCK) ){ @@ -38403,7 +38403,7 @@ static int lockTrace(int fd, int op, struct flock *p){ }else{ assert( 0 ); } - tdsqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", + sqlite3DebugPrintf("fcntl-failure-reason: %s %d %d %d\n", zType, (int)l2.l_start, (int)l2.l_len, (int)l2.l_pid); } errno = savedErrno; @@ -38420,14 +38420,14 @@ static int lockTrace(int fd, int op, struct flock *p){ ** this wrapper. On the Android platform, bypassing the logic below ** could lead to a corrupt database. */ -static int robust_ftruncate(int h, tdsqlite3_int64 sz){ +static int robust_ftruncate(int h, sqlite3_int64 sz){ int rc; #ifdef __ANDROID__ /* On Android, ftruncate() always uses 32-bit offsets, even if ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to ** truncate a file to any size larger than 2GiB. Silently ignore any ** such attempts. */ - if( sz>(tdsqlite3_int64)0x7FFFFFFF ){ + if( sz>(sqlite3_int64)0x7FFFFFFF ){ rc = SQLITE_OK; }else #endif @@ -38437,7 +38437,7 @@ static int robust_ftruncate(int h, tdsqlite3_int64 sz){ /* ** This routine translates a standard POSIX errno code into something -** useful to the clients of the tdsqlite3 functions. Specifically, it is +** useful to the clients of the sqlite3 functions. Specifically, it is ** intended to translate a variety of "try again" errors into SQLITE_BUSY ** and a variety of "please close the file descriptor NOW" errors into ** SQLITE_IOERR @@ -38555,7 +38555,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ assert( zAbsoluteName[0]=='/' ); n = (int)strlen(zAbsoluteName); - pNew = tdsqlite3_malloc64( sizeof(*pNew) + (n+1) ); + pNew = sqlite3_malloc64( sizeof(*pNew) + (n+1) ); if( pNew==0 ) return 0; pNew->zCanonicalName = (char*)&pNew[1]; memcpy(pNew->zCanonicalName, zAbsoluteName, n+1); @@ -38570,7 +38570,7 @@ static struct vxworksFileId *vxworksFindFileId(const char *zAbsoluteName){ if( pCandidate->nName==n && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 ){ - tdsqlite3_free(pNew); + sqlite3_free(pNew); pCandidate->nRef++; unixLeaveMutex(); return pCandidate; @@ -38599,7 +38599,7 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ for(pp=&vxworksFileList; *pp && *pp!=pId; pp = &((*pp)->pNext)){} assert( *pp==pId ); *pp = pId->pNext; - tdsqlite3_free(pId); + sqlite3_free(pId); } unixLeaveMutex(); } @@ -38648,7 +38648,7 @@ static void vxworksReleaseFileId(struct vxworksFileId *pId){ ** For VxWorks, we have to use the alternative unique ID system based on ** canonical filename and implemented in the previous division.) ** -** The tdsqlite3_file structure for POSIX is no longer just an integer file +** The sqlite3_file structure for POSIX is no longer just an integer file ** descriptor. It is now a structure that holds the integer file ** descriptor and a pointer to a structure that describes the internal ** locks on the corresponding inode. There is one locking structure @@ -38745,7 +38745,7 @@ struct unixFileId { */ struct unixInodeInfo { struct unixFileId fileId; /* The lookup key */ - tdsqlite3_mutex *pLockMutex; /* Hold this mutex for... */ + sqlite3_mutex *pLockMutex; /* Hold this mutex for... */ int nShared; /* Number of SHARED locks held */ int nLock; /* Number of outstanding file locks */ unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ @@ -38779,11 +38779,11 @@ static unixInodeInfo *inodeList = 0; /* All unixInodeInfo objects */ */ int unixFileMutexHeld(unixFile *pFile){ assert( pFile->pInode ); - return tdsqlite3_mutex_held(pFile->pInode->pLockMutex); + return sqlite3_mutex_held(pFile->pInode->pLockMutex); } int unixFileMutexNotheld(unixFile *pFile){ assert( pFile->pInode ); - return tdsqlite3_mutex_notheld(pFile->pInode->pLockMutex); + return sqlite3_mutex_notheld(pFile->pInode->pLockMutex); } #endif @@ -38793,7 +38793,7 @@ int unixFileMutexNotheld(unixFile *pFile){ ** unixLogError(). ** ** It is invoked after an error occurs in an OS function and errno has been -** set. It logs a message using tdsqlite3_log() containing the current value of +** set. It logs a message using sqlite3_log() containing the current value of ** errno and, if possible, the human-readable equivalent from strerror() or ** strerror_r(). ** @@ -38848,7 +38848,7 @@ static int unixLogErrorAtLine( #endif if( zPath==0 ) zPath = ""; - tdsqlite3_log(errcode, + sqlite3_log(errcode, "os_unix.c:%d: (%d) %s(%s) - %s", iLine, iErrno, zFunc, zPath, zErr ); @@ -38895,7 +38895,7 @@ static void closePendingFds(unixFile *pFile){ for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; robust_close(pFile, p->fd, __LINE__); - tdsqlite3_free(p); + sqlite3_free(p); } pInode->pUnused = 0; } @@ -38914,9 +38914,9 @@ static void releaseInodeInfo(unixFile *pFile){ pInode->nRef--; if( pInode->nRef==0 ){ assert( pInode->pShmNode==0 ); - tdsqlite3_mutex_enter(pInode->pLockMutex); + sqlite3_mutex_enter(pInode->pLockMutex); closePendingFds(pFile); - tdsqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_mutex_leave(pInode->pLockMutex); if( pInode->pPrev ){ assert( pInode->pPrev->pNext==pInode ); pInode->pPrev->pNext = pInode->pNext; @@ -38928,8 +38928,8 @@ static void releaseInodeInfo(unixFile *pFile){ assert( pInode->pNext->pPrev==pInode ); pInode->pNext->pPrev = pInode->pPrev; } - tdsqlite3_mutex_free(pInode->pLockMutex); - tdsqlite3_free(pInode); + sqlite3_mutex_free(pInode->pLockMutex); + sqlite3_free(pInode); } } } @@ -39006,16 +39006,16 @@ static int findInodeInfo( pInode = pInode->pNext; } if( pInode==0 ){ - pInode = tdsqlite3_malloc64( sizeof(*pInode) ); + pInode = sqlite3_malloc64( sizeof(*pInode) ); if( pInode==0 ){ return SQLITE_NOMEM_BKPT; } memset(pInode, 0, sizeof(*pInode)); memcpy(&pInode->fileId, &fileId, sizeof(fileId)); - if( tdsqlite3GlobalConfig.bCoreMutex ){ - pInode->pLockMutex = tdsqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( sqlite3GlobalConfig.bCoreMutex ){ + pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pInode->pLockMutex==0 ){ - tdsqlite3_free(pInode); + sqlite3_free(pInode); return SQLITE_NOMEM_BKPT; } } @@ -39054,7 +39054,7 @@ static int fileHasMoved(unixFile *pFile){ ** (2) The file is not a symbolic link ** (3) The file has not been renamed or unlinked ** -** Issue tdsqlite3_log(SQLITE_WARNING,...) messages if anything is not right. +** Issue sqlite3_log(SQLITE_WARNING,...) messages if anything is not right. */ static void verifyDbFile(unixFile *pFile){ struct stat buf; @@ -39065,19 +39065,19 @@ static void verifyDbFile(unixFile *pFile){ rc = osFstat(pFile->h, &buf); if( rc!=0 ){ - tdsqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); + sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); return; } if( buf.st_nlink==0 ){ - tdsqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); + sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); return; } if( buf.st_nlink>1 ){ - tdsqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); + sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); return; } if( fileHasMoved(pFile) ){ - tdsqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); + sqlite3_log(SQLITE_WARNING, "file renamed while open: %s", pFile->zPath); return; } } @@ -39089,7 +39089,7 @@ static void verifyDbFile(unixFile *pFile){ ** to a non-zero value otherwise *pResOut is set to zero. The return value ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ -static int unixCheckReservedLock(tdsqlite3_file *id, int *pResOut){ +static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; @@ -39098,7 +39098,7 @@ static int unixCheckReservedLock(tdsqlite3_file *id, int *pResOut){ assert( pFile ); assert( pFile->eFileLock<=SHARED_LOCK ); - tdsqlite3_mutex_enter(pFile->pInode->pLockMutex); + sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ @@ -39123,7 +39123,7 @@ static int unixCheckReservedLock(tdsqlite3_file *id, int *pResOut){ } #endif - tdsqlite3_mutex_leave(pFile->pInode->pLockMutex); + sqlite3_mutex_leave(pFile->pInode->pLockMutex); OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); *pResOut = reserved; @@ -39190,7 +39190,7 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ int rc; unixInodeInfo *pInode = pFile->pInode; assert( pInode!=0 ); - assert( tdsqlite3_mutex_held(pInode->pLockMutex) ); + assert( sqlite3_mutex_held(pInode->pLockMutex) ); if( (pFile->ctrlFlags & (UNIXFILE_EXCL|UNIXFILE_RDONLY))==UNIXFILE_EXCL ){ if( pInode->bProcessLock==0 ){ struct flock lock; @@ -39233,10 +39233,10 @@ static int unixFileLock(unixFile *pFile, struct flock *pLock){ ** RESERVED -> (PENDING) -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** -** This routine will only increase a lock. Use the tdsqlite3OsUnlock() +** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int unixLock(tdsqlite3_file *id, int eFileLock){ +static int unixLock(sqlite3_file *id, int eFileLock){ /* The following describes the implementation of the various locks and ** lock transitions in terms of the POSIX advisory shared and exclusive ** lock primitives (called read-locks and write-locks below, to avoid @@ -39310,7 +39310,7 @@ static int unixLock(tdsqlite3_file *id, int eFileLock){ /* This mutex is needed because pFile->pInode is shared across threads */ pInode = pFile->pInode; - tdsqlite3_mutex_enter(pInode->pLockMutex); + sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. @@ -39453,7 +39453,7 @@ static int unixLock(tdsqlite3_file *id, int eFileLock){ } end_lock: - tdsqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_mutex_leave(pInode->pLockMutex); OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; @@ -39486,7 +39486,7 @@ static void setPendingFd(unixFile *pFile){ ** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to ** remove the write lock on a region when a read lock is set. */ -static int posixUnlock(tdsqlite3_file *id, int eFileLock, int handleNFSUnlock){ +static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ unixFile *pFile = (unixFile*)id; unixInodeInfo *pInode; struct flock lock; @@ -39502,7 +39502,7 @@ static int posixUnlock(tdsqlite3_file *id, int eFileLock, int handleNFSUnlock){ return SQLITE_OK; } pInode = pFile->pInode; - tdsqlite3_mutex_enter(pInode->pLockMutex); + sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); @@ -39632,7 +39632,7 @@ static int posixUnlock(tdsqlite3_file *id, int eFileLock, int handleNFSUnlock){ } end_unlock: - tdsqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_mutex_leave(pInode->pLockMutex); if( rc==SQLITE_OK ){ pFile->eFileLock = eFileLock; } @@ -39646,7 +39646,7 @@ end_unlock: ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int unixUnlock(tdsqlite3_file *id, int eFileLock){ +static int unixUnlock(sqlite3_file *id, int eFileLock){ #if SQLITE_MAX_MMAP_SIZE>0 assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); #endif @@ -39668,7 +39668,7 @@ static void unixUnmapfile(unixFile *pFd); ** even on VxWorks. A mutex will be acquired on VxWorks by the ** vxworksReleaseFileId() routine. */ -static int closeUnixFile(tdsqlite3_file *id){ +static int closeUnixFile(sqlite3_file *id){ unixFile *pFile = (unixFile*)id; #if SQLITE_MAX_MMAP_SIZE>0 unixUnmapfile(pFile); @@ -39689,13 +39689,13 @@ static int closeUnixFile(tdsqlite3_file *id){ #ifdef SQLITE_UNLINK_AFTER_CLOSE if( pFile->ctrlFlags & UNIXFILE_DELETE ){ osUnlink(pFile->zPath); - tdsqlite3_free(*(char**)&pFile->zPath); + sqlite3_free(*(char**)&pFile->zPath); pFile->zPath = 0; } #endif OSTRACE(("CLOSE %-3d\n", pFile->h)); OpenCounter(-1); - tdsqlite3_free(pFile->pPreallocatedUnused); + sqlite3_free(pFile->pPreallocatedUnused); memset(pFile, 0, sizeof(unixFile)); return SQLITE_OK; } @@ -39703,7 +39703,7 @@ static int closeUnixFile(tdsqlite3_file *id){ /* ** Close a file. */ -static int unixClose(tdsqlite3_file *id){ +static int unixClose(sqlite3_file *id){ int rc = SQLITE_OK; unixFile *pFile = (unixFile *)id; unixInodeInfo *pInode = pFile->pInode; @@ -39718,7 +39718,7 @@ static int unixClose(tdsqlite3_file *id){ ** routine (e.g. nolockClose()) would be called instead. */ assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); - tdsqlite3_mutex_enter(pInode->pLockMutex); + sqlite3_mutex_enter(pInode->pLockMutex); if( pInode->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file @@ -39727,7 +39727,7 @@ static int unixClose(tdsqlite3_file *id){ */ setPendingFd(pFile); } - tdsqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_mutex_leave(pInode->pLockMutex); releaseInodeInfo(pFile); rc = closeUnixFile(id); unixLeaveMutex(); @@ -39754,16 +39754,16 @@ static int unixClose(tdsqlite3_file *id){ ** time and one or more of those connections are writing. */ -static int nolockCheckReservedLock(tdsqlite3_file *NotUsed, int *pResOut){ +static int nolockCheckReservedLock(sqlite3_file *NotUsed, int *pResOut){ UNUSED_PARAMETER(NotUsed); *pResOut = 0; return SQLITE_OK; } -static int nolockLock(tdsqlite3_file *NotUsed, int NotUsed2){ +static int nolockLock(sqlite3_file *NotUsed, int NotUsed2){ UNUSED_PARAMETER2(NotUsed, NotUsed2); return SQLITE_OK; } -static int nolockUnlock(tdsqlite3_file *NotUsed, int NotUsed2){ +static int nolockUnlock(sqlite3_file *NotUsed, int NotUsed2){ UNUSED_PARAMETER2(NotUsed, NotUsed2); return SQLITE_OK; } @@ -39771,7 +39771,7 @@ static int nolockUnlock(tdsqlite3_file *NotUsed, int NotUsed2){ /* ** Close the file. */ -static int nolockClose(tdsqlite3_file *id) { +static int nolockClose(sqlite3_file *id) { return closeUnixFile(id); } @@ -39816,7 +39816,7 @@ static int nolockClose(tdsqlite3_file *id) { ** variation of CheckReservedLock(), *pResOut is set to true if any lock ** is held on the file and false if the file is unlocked. */ -static int dotlockCheckReservedLock(tdsqlite3_file *id, int *pResOut) { +static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) { int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; @@ -39851,13 +39851,13 @@ static int dotlockCheckReservedLock(tdsqlite3_file *id, int *pResOut) { ** RESERVED -> (PENDING) -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** -** This routine will only increase a lock. Use the tdsqlite3OsUnlock() +** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. ** ** With dotfile locking, we really only support state (4): EXCLUSIVE. ** But we track the other locking levels internally. */ -static int dotlockLock(tdsqlite3_file *id, int eFileLock) { +static int dotlockLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; char *zLockFile = (char *)pFile->lockingContext; int rc = SQLITE_OK; @@ -39907,7 +39907,7 @@ static int dotlockLock(tdsqlite3_file *id, int eFileLock) { ** ** When the locking level reaches NO_LOCK, delete the lock file. */ -static int dotlockUnlock(tdsqlite3_file *id, int eFileLock) { +static int dotlockUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; char *zLockFile = (char *)pFile->lockingContext; int rc; @@ -39950,11 +39950,11 @@ static int dotlockUnlock(tdsqlite3_file *id, int eFileLock) { /* ** Close a file. Make sure the lock has been released before closing. */ -static int dotlockClose(tdsqlite3_file *id) { +static int dotlockClose(sqlite3_file *id) { unixFile *pFile = (unixFile*)id; assert( id!=0 ); dotlockUnlock(id, NO_LOCK); - tdsqlite3_free(pFile->lockingContext); + sqlite3_free(pFile->lockingContext); return closeUnixFile(id); } /****************** End of the dot-file lock implementation ******************* @@ -39996,7 +39996,7 @@ static int robust_flock(int fd, int op){ ** to a non-zero value otherwise *pResOut is set to zero. The return value ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ -static int flockCheckReservedLock(tdsqlite3_file *id, int *pResOut){ +static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; @@ -40069,14 +40069,14 @@ static int flockCheckReservedLock(tdsqlite3_file *id, int *pResOut){ ** PENDING -> EXCLUSIVE ** ** flock() only really support EXCLUSIVE locks. We track intermediate -** lock states in the tdsqlite3_file structure, but all locks SHARED or +** lock states in the sqlite3_file structure, but all locks SHARED or ** above are really EXCLUSIVE locks and exclude all other processes from ** access the file. ** -** This routine will only increase a lock. Use the tdsqlite3OsUnlock() +** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int flockLock(tdsqlite3_file *id, int eFileLock) { +static int flockLock(sqlite3_file *id, int eFileLock) { int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; @@ -40120,7 +40120,7 @@ static int flockLock(tdsqlite3_file *id, int eFileLock) { ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int flockUnlock(tdsqlite3_file *id, int eFileLock) { +static int flockUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; assert( pFile ); @@ -40154,7 +40154,7 @@ static int flockUnlock(tdsqlite3_file *id, int eFileLock) { /* ** Close a file. */ -static int flockClose(tdsqlite3_file *id) { +static int flockClose(sqlite3_file *id) { assert( id!=0 ); flockUnlock(id, NO_LOCK); return closeUnixFile(id); @@ -40183,7 +40183,7 @@ static int flockClose(tdsqlite3_file *id) { ** to a non-zero value otherwise *pResOut is set to zero. The return value ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ -static int semXCheckReservedLock(tdsqlite3_file *id, int *pResOut) { +static int semXCheckReservedLock(sqlite3_file *id, int *pResOut) { int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; @@ -40243,14 +40243,14 @@ static int semXCheckReservedLock(tdsqlite3_file *id, int *pResOut) { ** PENDING -> EXCLUSIVE ** ** Semaphore locks only really support EXCLUSIVE locks. We track intermediate -** lock states in the tdsqlite3_file structure, but all locks SHARED or +** lock states in the sqlite3_file structure, but all locks SHARED or ** above are really EXCLUSIVE locks and exclude all other processes from ** access the file. ** -** This routine will only increase a lock. Use the tdsqlite3OsUnlock() +** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int semXLock(tdsqlite3_file *id, int eFileLock) { +static int semXLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; sem_t *pSem = pFile->pInode->pSem; int rc = SQLITE_OK; @@ -40283,7 +40283,7 @@ static int semXLock(tdsqlite3_file *id, int eFileLock) { ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int semXUnlock(tdsqlite3_file *id, int eFileLock) { +static int semXUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; sem_t *pSem = pFile->pInode->pSem; @@ -40320,7 +40320,7 @@ static int semXUnlock(tdsqlite3_file *id, int eFileLock) { /* ** Close a file. */ -static int semXClose(tdsqlite3_file *id) { +static int semXClose(sqlite3_file *id) { if( id ){ unixFile *pFile = (unixFile*)id; semXUnlock(id, NO_LOCK); @@ -40426,7 +40426,7 @@ static int afpSetLock( ** to a non-zero value otherwise *pResOut is set to zero. The return value ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ -static int afpCheckReservedLock(tdsqlite3_file *id, int *pResOut){ +static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){ int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; @@ -40440,7 +40440,7 @@ static int afpCheckReservedLock(tdsqlite3_file *id, int *pResOut){ *pResOut = 1; return SQLITE_OK; } - tdsqlite3_mutex_enter(pFile->pInode->pLockMutex); + sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ reserved = 1; @@ -40464,7 +40464,7 @@ static int afpCheckReservedLock(tdsqlite3_file *id, int *pResOut){ } } - tdsqlite3_mutex_leave(pFile->pInode->pLockMutex); + sqlite3_mutex_leave(pFile->pInode->pLockMutex); OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); *pResOut = reserved; @@ -40492,10 +40492,10 @@ static int afpCheckReservedLock(tdsqlite3_file *id, int *pResOut){ ** RESERVED -> (PENDING) -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** -** This routine will only increase a lock. Use the tdsqlite3OsUnlock() +** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int afpLock(tdsqlite3_file *id, int eFileLock){ +static int afpLock(sqlite3_file *id, int eFileLock){ int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; unixInodeInfo *pInode = pFile->pInode; @@ -40528,7 +40528,7 @@ static int afpLock(tdsqlite3_file *id, int eFileLock){ /* This mutex is needed because pFile->pInode is shared across threads */ pInode = pFile->pInode; - tdsqlite3_mutex_enter(pInode->pLockMutex); + sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. @@ -40664,7 +40664,7 @@ static int afpLock(tdsqlite3_file *id, int eFileLock){ } afp_end_lock: - tdsqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_mutex_leave(pInode->pLockMutex); OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; @@ -40677,7 +40677,7 @@ afp_end_lock: ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int afpUnlock(tdsqlite3_file *id, int eFileLock) { +static int afpUnlock(sqlite3_file *id, int eFileLock) { int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; unixInodeInfo *pInode; @@ -40697,7 +40697,7 @@ static int afpUnlock(tdsqlite3_file *id, int eFileLock) { return SQLITE_OK; } pInode = pFile->pInode; - tdsqlite3_mutex_enter(pInode->pLockMutex); + sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); @@ -40770,7 +40770,7 @@ static int afpUnlock(tdsqlite3_file *id, int eFileLock) { } } - tdsqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_mutex_leave(pInode->pLockMutex); if( rc==SQLITE_OK ){ pFile->eFileLock = eFileLock; } @@ -40780,7 +40780,7 @@ static int afpUnlock(tdsqlite3_file *id, int eFileLock) { /* ** Close a file & cleanup AFP specific locking context */ -static int afpClose(tdsqlite3_file *id) { +static int afpClose(sqlite3_file *id) { int rc = SQLITE_OK; unixFile *pFile = (unixFile*)id; assert( id!=0 ); @@ -40789,7 +40789,7 @@ static int afpClose(tdsqlite3_file *id) { unixEnterMutex(); if( pFile->pInode ){ unixInodeInfo *pInode = pFile->pInode; - tdsqlite3_mutex_enter(pInode->pLockMutex); + sqlite3_mutex_enter(pInode->pLockMutex); if( pInode->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file @@ -40798,10 +40798,10 @@ static int afpClose(tdsqlite3_file *id) { */ setPendingFd(pFile); } - tdsqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_mutex_leave(pInode->pLockMutex); } releaseInodeInfo(pFile); - tdsqlite3_free(pFile->lockingContext); + sqlite3_free(pFile->lockingContext); rc = closeUnixFile(id); unixLeaveMutex(); return rc; @@ -40828,7 +40828,7 @@ static int afpClose(tdsqlite3_file *id) { ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int nfsUnlock(tdsqlite3_file *id, int eFileLock){ +static int nfsUnlock(sqlite3_file *id, int eFileLock){ return posixUnlock(id, eFileLock, 1); } @@ -40842,10 +40842,10 @@ static int nfsUnlock(tdsqlite3_file *id, int eFileLock){ ******************************************************************************/ /****************************************************************************** -**************** Non-locking tdsqlite3_file methods ***************************** +**************** Non-locking sqlite3_file methods ***************************** ** ** The next division contains implementations for all methods of the -** tdsqlite3_file object other than the locking methods. The locking +** sqlite3_file object other than the locking methods. The locking ** methods were defined in divisions above (one locking method per ** division). Those methods that are common to all locking modes ** are gather together into this division. @@ -40864,7 +40864,7 @@ static int nfsUnlock(tdsqlite3_file *id, int eFileLock){ ** To avoid stomping the errno value on a failed read the lastErrno value ** is set before returning. */ -static int seekAndRead(unixFile *id, tdsqlite3_int64 offset, void *pBuf, int cnt){ +static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ int got; int prior = 0; #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) @@ -40914,10 +40914,10 @@ static int seekAndRead(unixFile *id, tdsqlite3_int64 offset, void *pBuf, int cnt ** wrong. */ static int unixRead( - tdsqlite3_file *id, + sqlite3_file *id, void *pBuf, int amt, - tdsqlite3_int64 offset + sqlite3_int64 offset ){ unixFile *pFile = (unixFile *)id; int got; @@ -41028,10 +41028,10 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ ** or some other error code on failure. */ static int unixWrite( - tdsqlite3_file *id, + sqlite3_file *id, const void *pBuf, int amt, - tdsqlite3_int64 offset + sqlite3_int64 offset ){ unixFile *pFile = (unixFile*)id; int wrote = 0; @@ -41112,8 +41112,8 @@ static int unixWrite( ** Count the number of fullsyncs and normal syncs. This is used to test ** that syncs and fullsyncs are occurring at the right times. */ -SQLITE_API int tdsqlite3_sync_count = 0; -SQLITE_API int tdsqlite3_fullsync_count = 0; +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; #endif /* @@ -41185,8 +41185,8 @@ static int full_fsync(int fd, int fullSync, int dataOnly){ ** gets called with the correct arguments. */ #ifdef SQLITE_TEST - if( fullSync ) tdsqlite3_fullsync_count++; - tdsqlite3_sync_count++; + if( fullSync ) sqlite3_fullsync_count++; + sqlite3_sync_count++; #endif /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a @@ -41263,7 +41263,7 @@ static int openDirectory(const char *zFilename, int *pFd){ int fd = -1; char zDirname[MAX_PATHNAME+1]; - tdsqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); + sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename); for(ii=(int)strlen(zDirname); ii>0 && zDirname[ii]!='/'; ii--); if( ii>0 ){ zDirname[ii] = '\0'; @@ -41295,7 +41295,7 @@ static int openDirectory(const char *zFilename, int *pFd){ ** the directory entry for the journal was never created) and the transaction ** will not roll back - possibly leading to database corruption. */ -static int unixSync(tdsqlite3_file *id, int flags){ +static int unixSync(sqlite3_file *id, int flags){ int rc; unixFile *pFile = (unixFile*)id; @@ -41345,7 +41345,7 @@ static int unixSync(tdsqlite3_file *id, int flags){ /* ** Truncate an open file to a specified size */ -static int unixTruncate(tdsqlite3_file *id, i64 nByte){ +static int unixTruncate(sqlite3_file *id, i64 nByte){ unixFile *pFile = (unixFile *)id; int rc; assert( pFile ); @@ -41395,7 +41395,7 @@ static int unixTruncate(tdsqlite3_file *id, i64 nByte){ /* ** Determine the current size of a file in bytes */ -static int unixFileSize(tdsqlite3_file *id, i64 *pSize){ +static int unixFileSize(sqlite3_file *id, i64 *pSize){ int rc; struct stat buf; assert( id ); @@ -41424,7 +41424,7 @@ static int unixFileSize(tdsqlite3_file *id, i64 *pSize){ ** Handler for proxy-locking file-control verbs. Defined below in the ** proxying locking division. */ -static int proxyFileControl(tdsqlite3_file*,int,void*); +static int proxyFileControl(sqlite3_file*,int,void*); #endif /* @@ -41518,7 +41518,7 @@ static int unixGetTempname(int nBuf, char *zBuf); /* ** Information and control of an open file handle. */ -static int unixFileControl(tdsqlite3_file *id, int op, void *pArg){ +static int unixFileControl(sqlite3_file *id, int op, void *pArg){ unixFile *pFile = (unixFile*)id; switch( op ){ #if defined(__linux__) && defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) @@ -41564,11 +41564,11 @@ static int unixFileControl(tdsqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { - *(char**)pArg = tdsqlite3_mprintf("%s", pFile->pVfs->zName); + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); return SQLITE_OK; } case SQLITE_FCNTL_TEMPFILENAME: { - char *zTFile = tdsqlite3_malloc64( pFile->pVfs->mxPathname ); + char *zTFile = sqlite3_malloc64( pFile->pVfs->mxPathname ); if( zTFile ){ unixGetTempname(pFile->pVfs->mxPathname, zTFile); *(char**)pArg = zTFile; @@ -41589,8 +41589,8 @@ static int unixFileControl(tdsqlite3_file *id, int op, void *pArg){ case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; int rc = SQLITE_OK; - if( newLimit>tdsqlite3GlobalConfig.mxMmap ){ - newLimit = tdsqlite3GlobalConfig.mxMmap; + if( newLimit>sqlite3GlobalConfig.mxMmap ){ + newLimit = sqlite3GlobalConfig.mxMmap; } /* The value of newLimit may be eventually cast to (size_t) and passed @@ -41749,7 +41749,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ ** a database and its journal file) that the sector size will be the ** same for both. */ -static int unixSectorSize(tdsqlite3_file *id){ +static int unixSectorSize(sqlite3_file *id){ unixFile *pFd = (unixFile*)id; setDeviceCharacteristics(pFd); return pFd->sectorSize; @@ -41768,7 +41768,7 @@ static int unixSectorSize(tdsqlite3_file *id){ ** Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control ** available to turn it off and URI query parameter available to turn it off. */ -static int unixDeviceCharacteristics(tdsqlite3_file *id){ +static int unixDeviceCharacteristics(sqlite3_file *id){ unixFile *pFd = (unixFile*)id; setDeviceCharacteristics(pFd); return pFd->deviceCharacteristics; @@ -41827,7 +41827,7 @@ static int unixGetpagesize(void){ */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ - tdsqlite3_mutex *pShmMutex; /* Mutex to access this object */ + sqlite3_mutex *pShmMutex; /* Mutex to access this object */ char *zFilename; /* Name of the mmapped file */ int hShm; /* Open file descriptor */ int szRegion; /* Size of shared-memory regions */ @@ -41890,7 +41890,7 @@ static int unixShmSystemLock( /* Access to the unixShmNode object is serialized by the caller */ pShmNode = pFile->pInode->pShmNode; - assert( pShmNode->nRef==0 || tdsqlite3_mutex_held(pShmNode->pShmMutex) ); + assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) ); assert( pShmNode->nRef>0 || unixMutexHeld() ); /* Shared locks never span more than one byte */ @@ -41977,21 +41977,21 @@ static void unixShmPurge(unixFile *pFd){ int nShmPerMap = unixShmRegionPerMap(); int i; assert( p->pInode==pFd->pInode ); - tdsqlite3_mutex_free(p->pShmMutex); + sqlite3_mutex_free(p->pShmMutex); for(i=0; inRegion; i+=nShmPerMap){ if( p->hShm>=0 ){ osMunmap(p->apRegion[i], p->szRegion); }else{ - tdsqlite3_free(p->apRegion[i]); + sqlite3_free(p->apRegion[i]); } } - tdsqlite3_free(p->apRegion); + sqlite3_free(p->apRegion); if( p->hShm>=0 ){ robust_close(pFd, p->hShm, __LINE__); p->hShm = -1; } p->pInode->pShmNode = 0; - tdsqlite3_free(p); + sqlite3_free(p); } } @@ -42107,7 +42107,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ int nShmFilename; /* Size of the SHM filename in bytes */ /* Allocate space for the new unixShm object. */ - p = tdsqlite3_malloc64( sizeof(*p) ); + p = sqlite3_malloc64( sizeof(*p) ); if( p==0 ) return SQLITE_NOMEM_BKPT; memset(p, 0, sizeof(*p)); assert( pDbFd->pShm==0 ); @@ -42139,7 +42139,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ #else nShmFilename = 6 + (int)strlen(zBasePath); #endif - pShmNode = tdsqlite3_malloc64( sizeof(*pShmNode) + nShmFilename ); + pShmNode = sqlite3_malloc64( sizeof(*pShmNode) + nShmFilename ); if( pShmNode==0 ){ rc = SQLITE_NOMEM_BKPT; goto shm_open_err; @@ -42147,18 +42147,18 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); zShm = pShmNode->zFilename = (char*)&pShmNode[1]; #ifdef SQLITE_SHM_DIRECTORY - tdsqlite3_snprintf(nShmFilename, zShm, + sqlite3_snprintf(nShmFilename, zShm, SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", (u32)sStat.st_ino, (u32)sStat.st_dev); #else - tdsqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath); - tdsqlite3FileSuffix3(pDbFd->zPath, zShm); + sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath); + sqlite3FileSuffix3(pDbFd->zPath, zShm); #endif pShmNode->hShm = -1; pDbFd->pInode->pShmNode = pShmNode; pShmNode->pInode = pDbFd->pInode; - if( tdsqlite3GlobalConfig.bCoreMutex ){ - pShmNode->pShmMutex = tdsqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( sqlite3GlobalConfig.bCoreMutex ){ + pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->pShmMutex==0 ){ rc = SQLITE_NOMEM_BKPT; goto shm_open_err; @@ -42166,7 +42166,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ } if( pInode->bProcessLock==0 ){ - if( 0==tdsqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ pShmNode->hShm = robust_open(zShm, O_RDWR|O_CREAT|O_NOFOLLOW, (sStat.st_mode&0777)); } @@ -42207,16 +42207,16 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** at pShmNode->pFirst. This must be done while holding the ** pShmNode->pShmMutex. */ - tdsqlite3_mutex_enter(pShmNode->pShmMutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); p->pNext = pShmNode->pFirst; pShmNode->pFirst = p; - tdsqlite3_mutex_leave(pShmNode->pShmMutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); return rc; /* Jump here on any error */ shm_open_err: unixShmPurge(pDbFd); /* This call frees pShmNode if required */ - tdsqlite3_free(p); + sqlite3_free(p); unixLeaveMutex(); return rc; } @@ -42241,7 +42241,7 @@ shm_open_err: ** memory and SQLITE_OK returned. */ static int unixShmMap( - tdsqlite3_file *fd, /* Handle open on database file */ + sqlite3_file *fd, /* Handle open on database file */ int iRegion, /* Region to retrieve */ int szRegion, /* Size of regions */ int bExtend, /* True to extend file if necessary */ @@ -42262,7 +42262,7 @@ static int unixShmMap( p = pDbFd->pShm; pShmNode = p->pShmNode; - tdsqlite3_mutex_enter(pShmNode->pShmMutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); if( pShmNode->isUnlocked ){ rc = unixLockSharedMemory(pDbFd, pShmNode); if( rc!=SQLITE_OK ) goto shmpage_out; @@ -42327,7 +42327,7 @@ static int unixShmMap( } /* Map the requested memory region into this processes address space. */ - apNew = (char **)tdsqlite3_realloc( + apNew = (char **)sqlite3_realloc( pShmNode->apRegion, nReqRegion*sizeof(char *) ); if( !apNew ){ @@ -42349,7 +42349,7 @@ static int unixShmMap( goto shmpage_out; } }else{ - pMem = tdsqlite3_malloc64(nMap); + pMem = sqlite3_malloc64(nMap); if( pMem==0 ){ rc = SQLITE_NOMEM_BKPT; goto shmpage_out; @@ -42371,7 +42371,7 @@ shmpage_out: *pp = 0; } if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; - tdsqlite3_mutex_leave(pShmNode->pShmMutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); return rc; } @@ -42384,7 +42384,7 @@ shmpage_out: ** not go from shared to exclusive or from exclusive to shared. */ static int unixShmLock( - tdsqlite3_file *fd, /* Database file holding the shared memory */ + sqlite3_file *fd, /* Database file holding the shared memory */ int ofst, /* First lock to acquire or release */ int n, /* Number of locks to acquire or release */ int flags /* What to do with the lock */ @@ -42410,7 +42410,7 @@ static int unixShmLock( mask = (1<<(ofst+n)) - (1<1 || mask==(1<pShmMutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); if( flags & SQLITE_SHM_UNLOCK ){ u16 allMask = 0; /* Mask of locks held by siblings */ @@ -42483,7 +42483,7 @@ static int unixShmLock( } } } - tdsqlite3_mutex_leave(pShmNode->pShmMutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n", p->id, osGetpid(0), p->sharedMask, p->exclMask)); return rc; @@ -42496,10 +42496,10 @@ static int unixShmLock( ** any load or store begun after the barrier. */ static void unixShmBarrier( - tdsqlite3_file *fd /* Database file holding the shared memory */ + sqlite3_file *fd /* Database file holding the shared memory */ ){ UNUSED_PARAMETER(fd); - tdsqlite3MemoryBarrier(); /* compiler-defined memory barrier */ + sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ assert( fd->pMethods->xLock==nolockLock || unixFileMutexNotheld((unixFile*)fd) ); @@ -42515,7 +42515,7 @@ static void unixShmBarrier( ** routine is a harmless no-op. */ static int unixShmUnmap( - tdsqlite3_file *fd, /* The underlying database file */ + sqlite3_file *fd, /* The underlying database file */ int deleteFlag /* Delete shared-memory if true */ ){ unixShm *p; /* The connection to be closed */ @@ -42533,14 +42533,14 @@ static int unixShmUnmap( /* Remove connection p from the set of connections associated ** with pShmNode */ - tdsqlite3_mutex_enter(pShmNode->pShmMutex); + sqlite3_mutex_enter(pShmNode->pShmMutex); for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} *pp = p->pNext; /* Free the connection p */ - tdsqlite3_free(p); + sqlite3_free(p); pDbFd->pShm = 0; - tdsqlite3_mutex_leave(pShmNode->pShmMutex); + sqlite3_mutex_leave(pShmNode->pShmMutex); /* If pShmNode->nRef has reached 0, then close the underlying ** shared-memory file, too */ @@ -42591,7 +42591,7 @@ static void unixUnmapfile(unixFile *pFd){ ** unixFile.mmapSize ** unixFile.mmapSizeActual ** -** If unsuccessful, an error message is logged via tdsqlite3_log() and +** If unsuccessful, an error message is logged via sqlite3_log() and ** the three variables above are zeroed. In this case SQLite should ** continue accessing the database using the xRead() and xWrite() ** methods. @@ -42725,7 +42725,7 @@ static int unixMapfile(unixFile *pFd, i64 nMap){ ** If this function does return a pointer, the caller must eventually ** release the reference by calling unixUnfetch(). */ -static int unixFetch(tdsqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ #if SQLITE_MAX_MMAP_SIZE>0 unixFile *pFd = (unixFile *)fd; /* The underlying database file */ #endif @@ -42756,7 +42756,7 @@ static int unixFetch(tdsqlite3_file *fd, i64 iOff, int nAmt, void **pp){ ** to inform the VFS layer that, according to POSIX, any existing mapping ** may now be invalid and should be unmapped. */ -static int unixUnfetch(tdsqlite3_file *fd, i64 iOff, void *p){ +static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ #if SQLITE_MAX_MMAP_SIZE>0 unixFile *pFd = (unixFile *)fd; /* The underlying database file */ UNUSED_PARAMETER(iOff); @@ -42785,20 +42785,20 @@ static int unixUnfetch(tdsqlite3_file *fd, i64 iOff, void *p){ } /* -** Here ends the implementation of all tdsqlite3_file methods. +** Here ends the implementation of all sqlite3_file methods. ** -********************** End tdsqlite3_file Methods ******************************* +********************** End sqlite3_file Methods ******************************* ******************************************************************************/ /* -** This division contains definitions of tdsqlite3_io_methods objects that +** This division contains definitions of sqlite3_io_methods objects that ** implement various file locking strategies. It also contains definitions ** of "finder" functions. A finder-function is used to locate the appropriate -** tdsqlite3_io_methods object for a particular database file. The pAppData -** field of the tdsqlite3_vfs VFS objects are initialized to be pointers to +** sqlite3_io_methods object for a particular database file. The pAppData +** field of the sqlite3_vfs VFS objects are initialized to be pointers to ** the correct finder-function for that VFS. ** -** Most finder functions return a pointer to a fixed tdsqlite3_io_methods +** Most finder functions return a pointer to a fixed sqlite3_io_methods ** object. The only interesting finder-function is autolockIoFinder, which ** looks at the filesystem type and tries to guess the best locking ** strategy from that. @@ -42818,14 +42818,14 @@ static int unixUnfetch(tdsqlite3_file *fd, i64 iOff, void *p){ ** ** Each instance of this macro generates two objects: ** -** * A constant tdsqlite3_io_methods object call METHOD that has locking +** * A constant sqlite3_io_methods object call METHOD that has locking ** methods CLOSE, LOCK, UNLOCK, CKRESLOCK. ** ** * An I/O method finder function called FINDER that returns a pointer ** to the METHOD object in the previous bullet. */ #define IOMETHODS(FINDER,METHOD,VERSION,CLOSE,LOCK,UNLOCK,CKLOCK,SHMMAP) \ -static const tdsqlite3_io_methods METHOD = { \ +static const sqlite3_io_methods METHOD = { \ VERSION, /* iVersion */ \ CLOSE, /* xClose */ \ unixRead, /* xRead */ \ @@ -42846,21 +42846,21 @@ static const tdsqlite3_io_methods METHOD = { \ unixFetch, /* xFetch */ \ unixUnfetch, /* xUnfetch */ \ }; \ -static const tdsqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ +static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ return &METHOD; \ } \ -static const tdsqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ +static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ = FINDER##Impl; /* -** Here are all of the tdsqlite3_io_methods objects for each of the +** Here are all of the sqlite3_io_methods objects for each of the ** locking strategies. Functions that return pointers to these methods ** are also created. */ IOMETHODS( posixIoFinder, /* Finder function name */ - posixIoMethods, /* tdsqlite3_io_methods object name */ + posixIoMethods, /* sqlite3_io_methods object name */ 3, /* shared memory and mmap are enabled */ unixClose, /* xClose method */ unixLock, /* xLock method */ @@ -42870,7 +42870,7 @@ IOMETHODS( ) IOMETHODS( nolockIoFinder, /* Finder function name */ - nolockIoMethods, /* tdsqlite3_io_methods object name */ + nolockIoMethods, /* sqlite3_io_methods object name */ 3, /* shared memory and mmap are enabled */ nolockClose, /* xClose method */ nolockLock, /* xLock method */ @@ -42880,7 +42880,7 @@ IOMETHODS( ) IOMETHODS( dotlockIoFinder, /* Finder function name */ - dotlockIoMethods, /* tdsqlite3_io_methods object name */ + dotlockIoMethods, /* sqlite3_io_methods object name */ 1, /* shared memory is disabled */ dotlockClose, /* xClose method */ dotlockLock, /* xLock method */ @@ -42892,7 +42892,7 @@ IOMETHODS( #if SQLITE_ENABLE_LOCKING_STYLE IOMETHODS( flockIoFinder, /* Finder function name */ - flockIoMethods, /* tdsqlite3_io_methods object name */ + flockIoMethods, /* sqlite3_io_methods object name */ 1, /* shared memory is disabled */ flockClose, /* xClose method */ flockLock, /* xLock method */ @@ -42905,7 +42905,7 @@ IOMETHODS( #if OS_VXWORKS IOMETHODS( semIoFinder, /* Finder function name */ - semIoMethods, /* tdsqlite3_io_methods object name */ + semIoMethods, /* sqlite3_io_methods object name */ 1, /* shared memory is disabled */ semXClose, /* xClose method */ semXLock, /* xLock method */ @@ -42918,7 +42918,7 @@ IOMETHODS( #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE IOMETHODS( afpIoFinder, /* Finder function name */ - afpIoMethods, /* tdsqlite3_io_methods object name */ + afpIoMethods, /* sqlite3_io_methods object name */ 1, /* shared memory is disabled */ afpClose, /* xClose method */ afpLock, /* xLock method */ @@ -42934,17 +42934,17 @@ IOMETHODS( ** it uses proxy, dot-file, AFP, and flock() locking methods on those ** secondary files. For this reason, the division that implements ** proxy locking is located much further down in the file. But we need -** to go ahead and define the tdsqlite3_io_methods and finder function +** to go ahead and define the sqlite3_io_methods and finder function ** for proxy locking here. So we forward declare the I/O methods. */ #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -static int proxyClose(tdsqlite3_file*); -static int proxyLock(tdsqlite3_file*, int); -static int proxyUnlock(tdsqlite3_file*, int); -static int proxyCheckReservedLock(tdsqlite3_file*, int*); +static int proxyClose(sqlite3_file*); +static int proxyLock(sqlite3_file*, int); +static int proxyUnlock(sqlite3_file*, int); +static int proxyCheckReservedLock(sqlite3_file*, int*); IOMETHODS( proxyIoFinder, /* Finder function name */ - proxyIoMethods, /* tdsqlite3_io_methods object name */ + proxyIoMethods, /* sqlite3_io_methods object name */ 1, /* shared memory is disabled */ proxyClose, /* xClose method */ proxyLock, /* xLock method */ @@ -42958,7 +42958,7 @@ IOMETHODS( #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE IOMETHODS( nfsIoFinder, /* Finder function name */ - nfsIoMethods, /* tdsqlite3_io_methods object name */ + nfsIoMethods, /* sqlite3_io_methods object name */ 1, /* shared memory is disabled */ unixClose, /* xClose method */ unixLock, /* xLock method */ @@ -42971,18 +42971,18 @@ IOMETHODS( #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE /* ** This "finder" function attempts to determine the best locking strategy -** for the database file "filePath". It then returns the tdsqlite3_io_methods +** for the database file "filePath". It then returns the sqlite3_io_methods ** object that implements that strategy. ** ** This is for MacOSX only. */ -static const tdsqlite3_io_methods *autolockIoFinderImpl( +static const sqlite3_io_methods *autolockIoFinderImpl( const char *filePath, /* name of the database file */ unixFile *pNew /* open file object for the database file */ ){ static const struct Mapping { const char *zFilesystem; /* Filesystem type name */ - const tdsqlite3_io_methods *pMethods; /* Appropriate locking method */ + const sqlite3_io_methods *pMethods; /* Appropriate locking method */ } aMap[] = { { "hfs", &posixIoMethods }, { "ufs", &posixIoMethods }, @@ -43029,7 +43029,7 @@ static const tdsqlite3_io_methods *autolockIoFinderImpl( return &dotlockIoMethods; } } -static const tdsqlite3_io_methods +static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ @@ -43040,7 +43040,7 @@ static const tdsqlite3_io_methods ** locking works. If it does, then that is what is used. If it does not ** work, then fallback to named semaphore locking. */ -static const tdsqlite3_io_methods *vxworksIoFinderImpl( +static const sqlite3_io_methods *vxworksIoFinderImpl( const char *filePath, /* name of the database file */ unixFile *pNew /* the open file object */ ){ @@ -43065,7 +43065,7 @@ static const tdsqlite3_io_methods *vxworksIoFinderImpl( return &semIoMethods; } } -static const tdsqlite3_io_methods +static const sqlite3_io_methods *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; #endif /* OS_VXWORKS */ @@ -43073,27 +43073,27 @@ static const tdsqlite3_io_methods /* ** An abstract type for a pointer to an IO method finder function: */ -typedef const tdsqlite3_io_methods *(*finder_type)(const char*,unixFile*); +typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); /**************************************************************************** -**************************** tdsqlite3_vfs methods **************************** +**************************** sqlite3_vfs methods **************************** ** ** This division contains the implementation of methods on the -** tdsqlite3_vfs object. +** sqlite3_vfs object. */ /* ** Initialize the contents of the unixFile structure pointed to by pId. */ static int fillInUnixFile( - tdsqlite3_vfs *pVfs, /* Pointer to vfs object */ + sqlite3_vfs *pVfs, /* Pointer to vfs object */ int h, /* Open file descriptor of file being opened */ - tdsqlite3_file *pId, /* Write to the unixFile structure here */ + sqlite3_file *pId, /* Write to the unixFile structure here */ const char *zFilename, /* Name of the file being opened */ int ctrlFlags /* Zero or more UNIXFILE_* values */ ){ - const tdsqlite3_io_methods *pLockingStyle; + const sqlite3_io_methods *pLockingStyle; unixFile *pNew = (unixFile *)pId; int rc = SQLITE_OK; @@ -43108,9 +43108,9 @@ static int fillInUnixFile( pNew->zPath = zFilename; pNew->ctrlFlags = (u8)ctrlFlags; #if SQLITE_MAX_MMAP_SIZE>0 - pNew->mmapSizeMax = tdsqlite3GlobalConfig.szMmap; + pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; #endif - if( tdsqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), + if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), "psow", SQLITE_POWERSAFE_OVERWRITE) ){ pNew->ctrlFlags |= UNIXFILE_PSOW; } @@ -43176,7 +43176,7 @@ static int fillInUnixFile( ** the afpLockingContext. */ afpLockingContext *pCtx; - pNew->lockingContext = pCtx = tdsqlite3_malloc64( sizeof(*pCtx) ); + pNew->lockingContext = pCtx = sqlite3_malloc64( sizeof(*pCtx) ); if( pCtx==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ @@ -43189,7 +43189,7 @@ static int fillInUnixFile( unixEnterMutex(); rc = findInodeInfo(pNew, &pNew->pInode); if( rc!=SQLITE_OK ){ - tdsqlite3_free(pNew->lockingContext); + sqlite3_free(pNew->lockingContext); robust_close(pNew, h, __LINE__); h = -1; } @@ -43206,11 +43206,11 @@ static int fillInUnixFile( int nFilename; assert( zFilename!=0 ); nFilename = (int)strlen(zFilename) + 6; - zLockFile = (char *)tdsqlite3_malloc64(nFilename); + zLockFile = (char *)sqlite3_malloc64(nFilename); if( zLockFile==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ - tdsqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); + sqlite3_snprintf(nFilename, zLockFile, "%s" DOTLOCK_SUFFIX, zFilename); } pNew->lockingContext = zLockFile; } @@ -43225,7 +43225,7 @@ static int fillInUnixFile( if( (rc==SQLITE_OK) && (pNew->pInode->pSem==NULL) ){ char *zSemName = pNew->pInode->aSemName; int n; - tdsqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", + sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", pNew->pId->zCanonicalName); for( n=1; zSemName[n]; n++ ) if( zSemName[n]=='/' ) zSemName[n] = '_'; @@ -43273,7 +43273,7 @@ static const char *unixTempFileDir(void){ }; unsigned int i = 0; struct stat buf; - const char *zDir = tdsqlite3_temp_directory; + const char *zDir = sqlite3_temp_directory; if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); @@ -43311,10 +43311,10 @@ static int unixGetTempname(int nBuf, char *zBuf){ if( zDir==0 ) return SQLITE_IOERR_GETTEMPPATH; do{ u64 r; - tdsqlite3_randomness(sizeof(r), &r); + sqlite3_randomness(sizeof(r), &r); assert( nBuf>2 ); zBuf[nBuf-2] = 0; - tdsqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", + sqlite3_snprintf(nBuf, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX"%llx%c", zDir, r, 0); if( zBuf[nBuf-2]!=0 || (iLimit++)>10 ) return SQLITE_ERROR; }while( osAccess(zBuf,0)==0 ); @@ -43377,15 +43377,15 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ } if( pInode ){ UnixUnusedFd **pp; - assert( tdsqlite3_mutex_notheld(pInode->pLockMutex) ); - tdsqlite3_mutex_enter(pInode->pLockMutex); + assert( sqlite3_mutex_notheld(pInode->pLockMutex) ); + sqlite3_mutex_enter(pInode->pLockMutex); flags &= (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE); for(pp=&pInode->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); pUnused = *pp; if( pUnused ){ *pp = pUnused->pNext; } - tdsqlite3_mutex_leave(pInode->pLockMutex); + sqlite3_mutex_leave(pInode->pLockMutex); } } unixLeaveMutex(); @@ -43462,7 +43462,7 @@ static int findCreateFileMode( ** where NN is a decimal number. The NN naming schemes are ** used by the test_multiplex.c module. */ - nDb = tdsqlite3Strlen30(zPath) - 1; + nDb = sqlite3Strlen30(zPath) - 1; while( zPath[nDb]!='-' ){ /* In normal operation, the journal file name will always contain ** a '-' character. However in 8+3 filename mode, or if a corrupt @@ -43482,7 +43482,7 @@ static int findCreateFileMode( ** filename, check for the "modeof" parameter. If present, interpret ** its value as a filename and try to copy the mode, uid and gid from ** that file. */ - const char *z = tdsqlite3_uri_parameter(zPath, "modeof"); + const char *z = sqlite3_uri_parameter(zPath, "modeof"); if( z ){ rc = getFileMode(z, pMode, pUid, pGid); } @@ -43496,9 +43496,9 @@ static int findCreateFileMode( ** Previously, the SQLite OS layer used three functions in place of this ** one: ** -** tdsqlite3OsOpenReadWrite(); -** tdsqlite3OsOpenReadOnly(); -** tdsqlite3OsOpenExclusive(); +** sqlite3OsOpenReadWrite(); +** sqlite3OsOpenReadOnly(); +** sqlite3OsOpenExclusive(); ** ** These calls correspond to the following combinations of flags: ** @@ -43513,9 +43513,9 @@ static int findCreateFileMode( ** OpenExclusive(). */ static int unixOpen( - tdsqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */ + sqlite3_vfs *pVfs, /* The VFS for which this is the xOpen method */ const char *zPath, /* Pathname of file to be opened */ - tdsqlite3_file *pFile, /* The file descriptor to be filled in */ + sqlite3_file *pFile, /* The file descriptor to be filled in */ int flags, /* Input flags to control the opening */ int *pOutFlags /* Output flags returned to SQLite core */ ){ @@ -43588,7 +43588,7 @@ static int unixOpen( */ if( randomnessPid!=osGetpid(0) ){ randomnessPid = osGetpid(0); - tdsqlite3_randomness(0,0); + sqlite3_randomness(0,0); } memset(p, 0, sizeof(unixFile)); @@ -43598,7 +43598,7 @@ static int unixOpen( if( pUnused ){ fd = pUnused->fd; }else{ - pUnused = tdsqlite3_malloc64(sizeof(*pUnused)); + pUnused = sqlite3_malloc64(sizeof(*pUnused)); if( !pUnused ){ return SQLITE_NOMEM_BKPT; } @@ -43607,7 +43607,7 @@ static int unixOpen( /* Database filenames are double-zero terminated if they are not ** URIs with parameters. Hence, they can always be passed into - ** tdsqlite3_uri_parameter(). */ + ** sqlite3_uri_parameter(). */ assert( (flags & SQLITE_OPEN_URI) || zName[strlen(zName)+1]==0 ); }else if( !zName ){ @@ -43620,7 +43620,7 @@ static int unixOpen( zName = zTmpname; /* Generated temporary filenames are always double-zero terminated - ** for use by tdsqlite3_uri_parameter(). */ + ** for use by sqlite3_uri_parameter(). */ assert( zName[strlen(zName)+1]==0 ); } @@ -43699,7 +43699,7 @@ static int unixOpen( #if OS_VXWORKS zPath = zName; #elif defined(SQLITE_UNLINK_AFTER_CLOSE) - zPath = tdsqlite3_mprintf("%s", zName); + zPath = sqlite3_mprintf("%s", zName); if( zPath==0 ){ robust_close(p, fd, __LINE__); return SQLITE_NOMEM_BKPT; @@ -43758,7 +43758,7 @@ static int unixOpen( if( rc!=SQLITE_OK ){ /* Use unixClose to clean up the resources added in fillInUnixFile ** and clear all the structure's references. Specifically, - ** pFile->pMethods will be NULL so tdsqlite3OsClose will be a no-op + ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op */ unixClose(pFile); return rc; @@ -43776,7 +43776,7 @@ static int unixOpen( open_finished: if( rc!=SQLITE_OK ){ - tdsqlite3_free(p->pPreallocatedUnused); + sqlite3_free(p->pPreallocatedUnused); } return rc; } @@ -43787,7 +43787,7 @@ open_finished: ** the directory after deleting the file. */ static int unixDelete( - tdsqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */ + sqlite3_vfs *NotUsed, /* VFS containing this as the xDelete method */ const char *zPath, /* Name of file to be deleted */ int dirSync /* If true, fsync() directory after deleting file */ ){ @@ -43835,7 +43835,7 @@ static int unixDelete( ** Otherwise return 0. */ static int unixAccess( - tdsqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ + sqlite3_vfs *NotUsed, /* The VFS containing this xAccess method */ const char *zPath, /* Path of the file to examine */ int flags, /* What do we want to learn about the zPath file? */ int *pResOut /* Write result boolean here */ @@ -43866,13 +43866,13 @@ static int mkFullPathname( char *zOut, /* Output buffer */ int nOut /* Allocated size of buffer zOut */ ){ - int nPath = tdsqlite3Strlen30(zPath); + int nPath = sqlite3Strlen30(zPath); int iOff = 0; if( zPath[0]!='/' ){ if( osGetcwd(zOut, nOut-2)==0 ){ return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath); } - iOff = tdsqlite3Strlen30(zOut); + iOff = sqlite3Strlen30(zOut); zOut[iOff++] = '/'; } if( (iOff+nPath+1)>nOut ){ @@ -43881,7 +43881,7 @@ static int mkFullPathname( zOut[iOff] = '\0'; return SQLITE_CANTOPEN_BKPT; } - tdsqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); + sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath); return SQLITE_OK; } @@ -43890,12 +43890,12 @@ static int mkFullPathname( ** is stored as a nul-terminated string in the buffer pointed to by ** zPath. ** -** zOut points to a buffer of at least tdsqlite3_vfs.mxPathname bytes +** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes ** (in this case, MAX_PATHNAME bytes). The full-path is written to ** this buffer before returning. */ static int unixFullPathname( - tdsqlite3_vfs *pVfs, /* Pointer to vfs object */ + sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zPath, /* Possibly relative input path */ int nOut, /* Size of output buffer in bytes */ char *zOut /* Output buffer */ @@ -43936,7 +43936,7 @@ static int unixFullPathname( if( bLink ){ nLink++; if( zDel==0 ){ - zDel = tdsqlite3_malloc(nOut); + zDel = sqlite3_malloc(nOut); if( zDel==0 ) rc = SQLITE_NOMEM_BKPT; }else if( nLink>=SQLITE_MAX_SYMLINKS ){ rc = SQLITE_CANTOPEN_BKPT; @@ -43949,7 +43949,7 @@ static int unixFullPathname( }else{ if( zDel[0]!='/' ){ int n; - for(n = tdsqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); + for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--); if( nByte+n+1>nOut ){ rc = SQLITE_CANTOPEN_BKPT; }else{ @@ -43973,7 +43973,7 @@ static int unixFullPathname( zIn = zOut; }while( rc==SQLITE_OK ); - tdsqlite3_free(zDel); + sqlite3_free(zDel); if( rc==SQLITE_OK && nLink ) rc = SQLITE_OK_SYMLINK; return rc; #endif /* HAVE_READLINK && HAVE_LSTAT */ @@ -43986,7 +43986,7 @@ static int unixFullPathname( ** within the shared library, and closing the shared library. */ #include -static void *unixDlOpen(tdsqlite3_vfs *NotUsed, const char *zFilename){ +static void *unixDlOpen(sqlite3_vfs *NotUsed, const char *zFilename){ UNUSED_PARAMETER(NotUsed); return dlopen(zFilename, RTLD_NOW | RTLD_GLOBAL); } @@ -43998,17 +43998,17 @@ static void *unixDlOpen(tdsqlite3_vfs *NotUsed, const char *zFilename){ ** is available, zBufOut is left unmodified and SQLite uses a default ** error message. */ -static void unixDlError(tdsqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ +static void unixDlError(sqlite3_vfs *NotUsed, int nBuf, char *zBufOut){ const char *zErr; UNUSED_PARAMETER(NotUsed); unixEnterMutex(); zErr = dlerror(); if( zErr ){ - tdsqlite3_snprintf(nBuf, zBufOut, "%s", zErr); + sqlite3_snprintf(nBuf, zBufOut, "%s", zErr); } unixLeaveMutex(); } -static void (*unixDlSym(tdsqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ +static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ /* ** GCC with -pedantic-errors says that C90 does not allow a void* to be ** cast into a pointer to a function. And yet the library dlsym() routine @@ -44031,7 +44031,7 @@ static void (*unixDlSym(tdsqlite3_vfs *NotUsed, void *p, const char*zSym))(void) x = (void(*(*)(void*,const char*))(void))dlsym; return (*x)(p, zSym); } -static void unixDlClose(tdsqlite3_vfs *NotUsed, void *pHandle){ +static void unixDlClose(sqlite3_vfs *NotUsed, void *pHandle){ UNUSED_PARAMETER(NotUsed); dlclose(pHandle); } @@ -44045,7 +44045,7 @@ static void unixDlClose(tdsqlite3_vfs *NotUsed, void *pHandle){ /* ** Write nBuf bytes of random data to the supplied buffer zBuf. */ -static int unixRandomness(tdsqlite3_vfs *NotUsed, int nBuf, char *zBuf){ +static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ UNUSED_PARAMETER(NotUsed); assert((size_t)nBuf>=(sizeof(time_t)+sizeof(int))); @@ -44092,7 +44092,7 @@ static int unixRandomness(tdsqlite3_vfs *NotUsed, int nBuf, char *zBuf){ ** might be greater than or equal to the argument, but not less ** than the argument. */ -static int unixSleep(tdsqlite3_vfs *NotUsed, int microseconds){ +static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ #if OS_VXWORKS struct timespec sp; @@ -44116,10 +44116,10 @@ static int unixSleep(tdsqlite3_vfs *NotUsed, int microseconds){ /* ** The following variable, if set to a non-zero value, is interpreted as ** the number of seconds since 1970 and is used to set the result of -** tdsqlite3OsCurrentTime() during testing. +** sqlite3OsCurrentTime() during testing. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ #endif /* @@ -44132,26 +44132,26 @@ SQLITE_API int tdsqlite3_current_time = 0; /* Fake system time in seconds since ** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date ** cannot be found. */ -static int unixCurrentTimeInt64(tdsqlite3_vfs *NotUsed, tdsqlite3_int64 *piNow){ - static const tdsqlite3_int64 unixEpoch = 24405875*(tdsqlite3_int64)8640000; +static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; int rc = SQLITE_OK; #if defined(NO_GETTOD) time_t t; time(&t); - *piNow = ((tdsqlite3_int64)t)*1000 + unixEpoch; + *piNow = ((sqlite3_int64)t)*1000 + unixEpoch; #elif OS_VXWORKS struct timespec sNow; clock_gettime(CLOCK_REALTIME, &sNow); - *piNow = unixEpoch + 1000*(tdsqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_nsec/1000000; #else struct timeval sNow; (void)gettimeofday(&sNow, 0); /* Cannot fail given valid arguments */ - *piNow = unixEpoch + 1000*(tdsqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; + *piNow = unixEpoch + 1000*(sqlite3_int64)sNow.tv_sec + sNow.tv_usec/1000; #endif #ifdef SQLITE_TEST - if( tdsqlite3_current_time ){ - *piNow = 1000*(tdsqlite3_int64)tdsqlite3_current_time + unixEpoch; + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; } #endif UNUSED_PARAMETER(NotUsed); @@ -44164,8 +44164,8 @@ static int unixCurrentTimeInt64(tdsqlite3_vfs *NotUsed, tdsqlite3_int64 *piNow){ ** current time and date as a Julian Day number into *prNow and ** return 0. Return 1 if the time and date cannot be found. */ -static int unixCurrentTime(tdsqlite3_vfs *NotUsed, double *prNow){ - tdsqlite3_int64 i = 0; +static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ + sqlite3_int64 i = 0; int rc; UNUSED_PARAMETER(NotUsed); rc = unixCurrentTimeInt64(0, &i); @@ -44182,7 +44182,7 @@ static int unixCurrentTime(tdsqlite3_vfs *NotUsed, double *prNow){ ** during SQLite operation. Only the integer return code is currently ** used. */ -static int unixGetLastError(tdsqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ +static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ UNUSED_PARAMETER(NotUsed); UNUSED_PARAMETER(NotUsed2); UNUSED_PARAMETER(NotUsed3); @@ -44191,7 +44191,7 @@ static int unixGetLastError(tdsqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3 /* -************************ End of tdsqlite3_vfs methods *************************** +************************ End of sqlite3_vfs methods *************************** ******************************************************************************/ /****************************************************************************** @@ -44244,9 +44244,9 @@ static int unixGetLastError(tdsqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3 ** ** C APIs ** -** tdsqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE, +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_SET_LOCKPROXYFILE, ** | ":auto:"); -** tdsqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE, +** sqlite3_file_control(db, dbname, SQLITE_FCNTL_GET_LOCKPROXYFILE, ** &); ** ** @@ -44363,7 +44363,7 @@ struct proxyLockingContext { int conchHeld; /* 1 if the conch is held, -1 if lockless */ int nFails; /* Number of conch taking failures */ void *oldLockingContext; /* Original lockingcontext to restore on close */ - tdsqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ + sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ }; /* @@ -44447,7 +44447,7 @@ static int proxyCreateLockPath(const char *lockPath){ /* ** Create a new VFS file descriptor (stored in memory obtained from -** tdsqlite3_malloc) and open the file named "path" in the file descriptor. +** sqlite3_malloc) and open the file named "path" in the file descriptor. ** ** The caller is responsible not only for closing the file descriptor ** but also for freeing the memory associated with the file descriptor. @@ -44461,7 +44461,7 @@ static int proxyCreateUnixFile( unixFile *pNew; int rc = SQLITE_OK; int openFlags = O_RDWR | O_CREAT | O_NOFOLLOW; - tdsqlite3_vfs dummyVfs; + sqlite3_vfs dummyVfs; int terrno = 0; UnixUnusedFd *pUnused = NULL; @@ -44475,7 +44475,7 @@ static int proxyCreateUnixFile( if( pUnused ){ fd = pUnused->fd; }else{ - pUnused = tdsqlite3_malloc64(sizeof(*pUnused)); + pUnused = sqlite3_malloc64(sizeof(*pUnused)); if( !pUnused ){ return SQLITE_NOMEM_BKPT; } @@ -44508,7 +44508,7 @@ static int proxyCreateUnixFile( } } - pNew = (unixFile *)tdsqlite3_malloc64(sizeof(*pNew)); + pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew)); if( pNew==NULL ){ rc = SQLITE_NOMEM_BKPT; goto end_create_proxy; @@ -44522,21 +44522,21 @@ static int proxyCreateUnixFile( pUnused->flags = openFlags; pNew->pPreallocatedUnused = pUnused; - rc = fillInUnixFile(&dummyVfs, fd, (tdsqlite3_file*)pNew, path, 0); + rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); if( rc==SQLITE_OK ){ *ppFile = pNew; return SQLITE_OK; } end_create_proxy: robust_close(pNew, fd, __LINE__); - tdsqlite3_free(pNew); - tdsqlite3_free(pUnused); + sqlite3_free(pNew); + sqlite3_free(pUnused); return rc; } #ifdef SQLITE_TEST /* simulate multiple hosts by creating unique hostid file paths */ -SQLITE_API int tdsqlite3_hostid_num = 0; +SQLITE_API int sqlite3_hostid_num = 0; #endif #define PROXY_HOSTIDLEN 16 /* conch file host id length */ @@ -44568,8 +44568,8 @@ static int proxyGetHostID(unsigned char *pHostID, int *pError){ #endif #ifdef SQLITE_TEST /* simulate multiple hosts by creating unique hostid file paths */ - if( tdsqlite3_hostid_num != 0){ - pHostID[0] = (char)(pHostID[0] + (char)(tdsqlite3_hostid_num & 0xFF)); + if( sqlite3_hostid_num != 0){ + pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF)); } #endif @@ -44606,27 +44606,27 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ pathLen = strlcpy(tPath, cPath, MAXPATHLEN); if( pathLen>MAXPATHLEN || pathLen<6 || (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ - tdsqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); + sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); goto end_breaklock; } /* read the conch content */ readLen = osPread(conchFile->h, buf, PROXY_MAXCONCHLEN, 0); if( readLenpMethod->xLock((tdsqlite3_file*)conchFile, lockType); + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); nTries ++; if( rc==SQLITE_BUSY ){ /* If the lock failed (busy): @@ -44709,10 +44709,10 @@ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ if( 0==proxyBreakConchLock(pFile, myHostID) ){ rc = SQLITE_OK; if( lockType==EXCLUSIVE_LOCK ){ - rc = conchFile->pMethod->xLock((tdsqlite3_file*)conchFile, SHARED_LOCK); + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, SHARED_LOCK); } if( !rc ){ - rc = conchFile->pMethod->xLock((tdsqlite3_file*)conchFile, lockType); + rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); } } } @@ -44852,7 +44852,7 @@ static int proxyTakeConch(unixFile *pFile){ } writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); robust_ftruncate(conchFile->h, writeSize); - rc = unixWrite((tdsqlite3_file *)conchFile, writeBuffer, writeSize, 0); + rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); full_fsync(conchFile->h,0,0); /* If we created a new conch file (not just updated the contents of a ** valid conch file), try to match the permissions of the database @@ -44885,7 +44885,7 @@ static int proxyTakeConch(unixFile *pFile){ } } } - conchFile->pMethod->xUnlock((tdsqlite3_file*)conchFile, SHARED_LOCK); + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); end_takeconch: OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); @@ -44921,7 +44921,7 @@ static int proxyTakeConch(unixFile *pFile){ ** from the conch file or the path was allocated on the stack */ if( tempLockPath ){ - pCtx->lockProxyPath = tdsqlite3DbStrDup(0, tempLockPath); + pCtx->lockProxyPath = sqlite3DbStrDup(0, tempLockPath); if( !pCtx->lockProxyPath ){ rc = SQLITE_NOMEM_BKPT; } @@ -44936,7 +44936,7 @@ static int proxyTakeConch(unixFile *pFile){ afpCtx->dbPath = pCtx->lockProxyPath; } } else { - conchFile->pMethod->xUnlock((tdsqlite3_file*)conchFile, NO_LOCK); + conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); } OSTRACE(("TAKECONCH %d %s\n", conchFile->h, rc==SQLITE_OK?"ok":"failed")); @@ -44960,7 +44960,7 @@ static int proxyReleaseConch(unixFile *pFile){ (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), osGetpid(0))); if( pCtx->conchHeld>0 ){ - rc = conchFile->pMethod->xUnlock((tdsqlite3_file*)conchFile, NO_LOCK); + rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); } pCtx->conchHeld = 0; OSTRACE(("RELEASECONCH %d %s\n", conchFile->h, @@ -44970,7 +44970,7 @@ static int proxyReleaseConch(unixFile *pFile){ /* ** Given the name of a database file, compute the name of its conch file. -** Store the conch filename in memory obtained from tdsqlite3_malloc64(). +** Store the conch filename in memory obtained from sqlite3_malloc64(). ** Make *pConchPath point to the new name. Return SQLITE_OK on success ** or SQLITE_NOMEM if unable to obtain memory. ** @@ -44986,7 +44986,7 @@ static int proxyCreateConchPathname(char *dbPath, char **pConchPath){ /* Allocate space for the conch filename and initialize the name to ** the name of the original database file. */ - *pConchPath = conchPath = (char *)tdsqlite3_malloc64(len + 8); + *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8); if( conchPath==0 ){ return SQLITE_NOMEM_BKPT; } @@ -45034,12 +45034,12 @@ static int switchLockProxyPath(unixFile *pFile, const char *path) { pCtx->lockProxy=NULL; pCtx->conchHeld = 0; if( lockProxy!=NULL ){ - rc=lockProxy->pMethod->xClose((tdsqlite3_file *)lockProxy); + rc=lockProxy->pMethod->xClose((sqlite3_file *)lockProxy); if( rc ) return rc; - tdsqlite3_free(lockProxy); + sqlite3_free(lockProxy); } - tdsqlite3_free(oldPath); - pCtx->lockProxyPath = tdsqlite3DbStrDup(0, path); + sqlite3_free(oldPath); + pCtx->lockProxyPath = sqlite3DbStrDup(0, path); } return rc; @@ -45102,7 +45102,7 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, (lockPath ? lockPath : ":auto:"), osGetpid(0))); - pCtx = tdsqlite3_malloc64( sizeof(*pCtx) ); + pCtx = sqlite3_malloc64( sizeof(*pCtx) ); if( pCtx==0 ){ return SQLITE_NOMEM_BKPT; } @@ -45134,11 +45134,11 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { } } if( rc==SQLITE_OK && lockPath ){ - pCtx->lockProxyPath = tdsqlite3DbStrDup(0, lockPath); + pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath); } if( rc==SQLITE_OK ){ - pCtx->dbPath = tdsqlite3DbStrDup(0, dbPath); + pCtx->dbPath = sqlite3DbStrDup(0, dbPath); if( pCtx->dbPath==NULL ){ rc = SQLITE_NOMEM_BKPT; } @@ -45153,12 +45153,12 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { pFile->pMethod = &proxyIoMethods; }else{ if( pCtx->conchFile ){ - pCtx->conchFile->pMethod->xClose((tdsqlite3_file *)pCtx->conchFile); - tdsqlite3_free(pCtx->conchFile); + pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); + sqlite3_free(pCtx->conchFile); } - tdsqlite3DbFree(0, pCtx->lockProxyPath); - tdsqlite3_free(pCtx->conchFilePath); - tdsqlite3_free(pCtx); + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3_free(pCtx); } OSTRACE(("TRANSPROXY %d %s\n", pFile->h, (rc==SQLITE_OK ? "ok" : "failed"))); @@ -45167,10 +45167,10 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) { /* -** This routine handles tdsqlite3_file_control() calls that are specific +** This routine handles sqlite3_file_control() calls that are specific ** to proxy locking. */ -static int proxyFileControl(tdsqlite3_file *id, int op, void *pArg){ +static int proxyFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ case SQLITE_FCNTL_GET_LOCKPROXYFILE: { unixFile *pFile = (unixFile*)id; @@ -45233,7 +45233,7 @@ static int proxyFileControl(tdsqlite3_file *id, int op, void *pArg){ /* ** Within this division (the proxying locking implementation) the procedures ** above this point are all utilities. The lock-related methods of the -** proxy-locking tdsqlite3_io_method object follow. +** proxy-locking sqlite3_io_method object follow. */ @@ -45243,14 +45243,14 @@ static int proxyFileControl(tdsqlite3_file *id, int op, void *pArg){ ** to a non-zero value otherwise *pResOut is set to zero. The return value ** is set to SQLITE_OK unless an I/O error occurs during lock checking. */ -static int proxyCheckReservedLock(tdsqlite3_file *id, int *pResOut) { +static int proxyCheckReservedLock(sqlite3_file *id, int *pResOut) { unixFile *pFile = (unixFile*)id; int rc = proxyTakeConch(pFile); if( rc==SQLITE_OK ){ proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; if( pCtx->conchHeld>0 ){ unixFile *proxy = pCtx->lockProxy; - return proxy->pMethod->xCheckReservedLock((tdsqlite3_file*)proxy, pResOut); + return proxy->pMethod->xCheckReservedLock((sqlite3_file*)proxy, pResOut); }else{ /* conchHeld < 0 is lockless */ pResOut=0; } @@ -45279,17 +45279,17 @@ static int proxyCheckReservedLock(tdsqlite3_file *id, int *pResOut) { ** RESERVED -> (PENDING) -> EXCLUSIVE ** PENDING -> EXCLUSIVE ** -** This routine will only increase a lock. Use the tdsqlite3OsUnlock() +** This routine will only increase a lock. Use the sqlite3OsUnlock() ** routine to lower a locking level. */ -static int proxyLock(tdsqlite3_file *id, int eFileLock) { +static int proxyLock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; int rc = proxyTakeConch(pFile); if( rc==SQLITE_OK ){ proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; if( pCtx->conchHeld>0 ){ unixFile *proxy = pCtx->lockProxy; - rc = proxy->pMethod->xLock((tdsqlite3_file*)proxy, eFileLock); + rc = proxy->pMethod->xLock((sqlite3_file*)proxy, eFileLock); pFile->eFileLock = proxy->eFileLock; }else{ /* conchHeld < 0 is lockless */ @@ -45306,14 +45306,14 @@ static int proxyLock(tdsqlite3_file *id, int eFileLock) { ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. */ -static int proxyUnlock(tdsqlite3_file *id, int eFileLock) { +static int proxyUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; int rc = proxyTakeConch(pFile); if( rc==SQLITE_OK ){ proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; if( pCtx->conchHeld>0 ){ unixFile *proxy = pCtx->lockProxy; - rc = proxy->pMethod->xUnlock((tdsqlite3_file*)proxy, eFileLock); + rc = proxy->pMethod->xUnlock((sqlite3_file*)proxy, eFileLock); pFile->eFileLock = proxy->eFileLock; }else{ /* conchHeld < 0 is lockless */ @@ -45325,7 +45325,7 @@ static int proxyUnlock(tdsqlite3_file *id, int eFileLock) { /* ** Close a file that uses proxy locks. */ -static int proxyClose(tdsqlite3_file *id) { +static int proxyClose(sqlite3_file *id) { if( ALWAYS(id) ){ unixFile *pFile = (unixFile*)id; proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; @@ -45334,11 +45334,11 @@ static int proxyClose(tdsqlite3_file *id) { int rc = SQLITE_OK; if( lockProxy ){ - rc = lockProxy->pMethod->xUnlock((tdsqlite3_file*)lockProxy, NO_LOCK); + rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); if( rc ) return rc; - rc = lockProxy->pMethod->xClose((tdsqlite3_file*)lockProxy); + rc = lockProxy->pMethod->xClose((sqlite3_file*)lockProxy); if( rc ) return rc; - tdsqlite3_free(lockProxy); + sqlite3_free(lockProxy); pCtx->lockProxy = 0; } if( conchFile ){ @@ -45346,17 +45346,17 @@ static int proxyClose(tdsqlite3_file *id) { rc = proxyReleaseConch(pFile); if( rc ) return rc; } - rc = conchFile->pMethod->xClose((tdsqlite3_file*)conchFile); + rc = conchFile->pMethod->xClose((sqlite3_file*)conchFile); if( rc ) return rc; - tdsqlite3_free(conchFile); + sqlite3_free(conchFile); } - tdsqlite3DbFree(0, pCtx->lockProxyPath); - tdsqlite3_free(pCtx->conchFilePath); - tdsqlite3DbFree(0, pCtx->dbPath); + sqlite3DbFree(0, pCtx->lockProxyPath); + sqlite3_free(pCtx->conchFilePath); + sqlite3DbFree(0, pCtx->dbPath); /* restore the original locking context and pMethod then close it */ pFile->lockingContext = pCtx->oldLockingContext; pFile->pMethod = pCtx->pOldMethod; - tdsqlite3_free(pCtx); + sqlite3_free(pCtx); return pFile->pMethod->xClose(id); } return SQLITE_OK; @@ -45378,7 +45378,7 @@ static int proxyClose(tdsqlite3_file *id) { ** Initialize the operating system interface. ** ** This routine registers all VFS implementations for unix-like operating -** systems. This routine, and the tdsqlite3_os_end() routine that follows, +** systems. This routine, and the sqlite3_os_end() routine that follows, ** should be the only routines in this file that are visible from other ** files. ** @@ -45387,9 +45387,9 @@ static int proxyClose(tdsqlite3_file *id) { ** necessarily been initialized when this routine is called, and so they ** should not be used. */ -SQLITE_API int tdsqlite3_os_init(void){ +SQLITE_API int sqlite3_os_init(void){ /* - ** The following macro defines an initializer for an tdsqlite3_vfs object. + ** The following macro defines an initializer for an sqlite3_vfs object. ** The name of the VFS is NAME. The pAppData is a pointer to a pointer ** to the "finder" function. (pAppData is a pointer to a pointer because ** silly C90 rules prohibit a void* from being cast to a function pointer @@ -45402,7 +45402,7 @@ SQLITE_API int tdsqlite3_os_init(void){ ** behaviors. See the division above that contains the IOMETHODS ** macro for addition information on finder-functions. ** - ** Most finders simply return a pointer to a fixed tdsqlite3_io_methods + ** Most finders simply return a pointer to a fixed sqlite3_io_methods ** object. But the "autolockIoFinder" available on MacOSX does a little ** more than that; it looks at the filesystem type that hosts the ** database file and tries to choose an locking method appropriate for @@ -45436,11 +45436,11 @@ SQLITE_API int tdsqlite3_os_init(void){ /* ** All default VFSes for unix are contained in the following array. ** - ** Note that the tdsqlite3_vfs.pNext field of the VFS object is modified + ** Note that the sqlite3_vfs.pNext field of the VFS object is modified ** by the SQLite core when the VFS is registered. So the following ** array cannot be const. */ - static tdsqlite3_vfs aVfs[] = { + static sqlite3_vfs aVfs[] = { #if SQLITE_ENABLE_LOCKING_STYLE && defined(__APPLE__) UNIXVFS("unix", autolockIoFinder ), #elif OS_VXWORKS @@ -45473,10 +45473,10 @@ SQLITE_API int tdsqlite3_os_init(void){ assert( ArraySize(aSyscall)==29 ); /* Register all VFSes defined in the aVfs[] array */ - for(i=0; i<(sizeof(aVfs)/sizeof(tdsqlite3_vfs)); i++){ - tdsqlite3_vfs_register(&aVfs[i], i==0); + for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){ + sqlite3_vfs_register(&aVfs[i], i==0); } - unixBigLock = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); + unixBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); return SQLITE_OK; } @@ -45487,7 +45487,7 @@ SQLITE_API int tdsqlite3_os_init(void){ ** to release dynamically allocated objects. But not on unix. ** This routine is a no-op for unix. */ -SQLITE_API int tdsqlite3_os_end(void){ +SQLITE_API int sqlite3_os_end(void){ unixBigLock = 0; return SQLITE_OK; } @@ -45591,7 +45591,7 @@ SQLITE_API int tdsqlite3_os_end(void){ #if defined(__GNUC__) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned int lo, hi; __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); return (sqlite_uint64)hi << 32 | lo; @@ -45599,7 +45599,7 @@ SQLITE_API int tdsqlite3_os_end(void){ #elif defined(_MSC_VER) - __declspec(naked) __inline sqlite_uint64 __cdecl tdsqlite3Hwtime(void){ + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ __asm { rdtsc ret ; return value at EDX:EAX @@ -45610,7 +45610,7 @@ SQLITE_API int tdsqlite3_os_end(void){ #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long val; __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; @@ -45618,7 +45618,7 @@ SQLITE_API int tdsqlite3_os_end(void){ #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long long retval; unsigned long junk; __asm__ __volatile__ ("\n\ @@ -45635,13 +45635,13 @@ SQLITE_API int tdsqlite3_os_end(void){ /* ** asm() is needed for hardware timing support. Without asm(), - ** disable the tdsqlite3Hwtime() routine. + ** disable the sqlite3Hwtime() routine. ** - ** tdsqlite3Hwtime() is only used for some obscure debugging + ** sqlite3Hwtime() is only used for some obscure debugging ** and analysis configurations, not in any deliverable, so this ** should not be a great loss. */ -SQLITE_PRIVATE sqlite_uint64 tdsqlite3Hwtime(void){ return ((sqlite_uint64)0); } +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } #endif @@ -45652,8 +45652,8 @@ SQLITE_PRIVATE sqlite_uint64 tdsqlite3Hwtime(void){ return ((sqlite_uint64)0); static sqlite_uint64 g_start; static sqlite_uint64 g_elapsed; -#define TIMER_START g_start=tdsqlite3Hwtime() -#define TIMER_END g_elapsed=tdsqlite3Hwtime()-g_start +#define TIMER_START g_start=sqlite3Hwtime() +#define TIMER_END g_elapsed=sqlite3Hwtime()-g_start #define TIMER_ELAPSED g_elapsed #else #define TIMER_START @@ -45667,32 +45667,32 @@ static sqlite_uint64 g_elapsed; ** is used for testing the I/O recovery logic. */ #if defined(SQLITE_TEST) -SQLITE_API extern int tdsqlite3_io_error_hit; -SQLITE_API extern int tdsqlite3_io_error_hardhit; -SQLITE_API extern int tdsqlite3_io_error_pending; -SQLITE_API extern int tdsqlite3_io_error_persist; -SQLITE_API extern int tdsqlite3_io_error_benign; -SQLITE_API extern int tdsqlite3_diskfull_pending; -SQLITE_API extern int tdsqlite3_diskfull; -#define SimulateIOErrorBenign(X) tdsqlite3_io_error_benign=(X) +SQLITE_API extern int sqlite3_io_error_hit; +SQLITE_API extern int sqlite3_io_error_hardhit; +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_persist; +SQLITE_API extern int sqlite3_io_error_benign; +SQLITE_API extern int sqlite3_diskfull_pending; +SQLITE_API extern int sqlite3_diskfull; +#define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X) #define SimulateIOError(CODE) \ - if( (tdsqlite3_io_error_persist && tdsqlite3_io_error_hit) \ - || tdsqlite3_io_error_pending-- == 1 ) \ + if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \ + || sqlite3_io_error_pending-- == 1 ) \ { local_ioerr(); CODE; } static void local_ioerr(){ IOTRACE(("IOERR\n")); - tdsqlite3_io_error_hit++; - if( !tdsqlite3_io_error_benign ) tdsqlite3_io_error_hardhit++; + sqlite3_io_error_hit++; + if( !sqlite3_io_error_benign ) sqlite3_io_error_hardhit++; } #define SimulateDiskfullError(CODE) \ - if( tdsqlite3_diskfull_pending ){ \ - if( tdsqlite3_diskfull_pending == 1 ){ \ + if( sqlite3_diskfull_pending ){ \ + if( sqlite3_diskfull_pending == 1 ){ \ local_ioerr(); \ - tdsqlite3_diskfull = 1; \ - tdsqlite3_io_error_hit = 1; \ + sqlite3_diskfull = 1; \ + sqlite3_io_error_hit = 1; \ CODE; \ }else{ \ - tdsqlite3_diskfull_pending--; \ + sqlite3_diskfull_pending--; \ } \ } #else @@ -45705,8 +45705,8 @@ static void local_ioerr(){ ** When testing, keep a count of the number of open files. */ #if defined(SQLITE_TEST) -SQLITE_API extern int tdsqlite3_open_file_count; -#define OpenCounter(X) tdsqlite3_open_file_count+=(X) +SQLITE_API extern int sqlite3_open_file_count; +#define OpenCounter(X) sqlite3_open_file_count+=(X) #else #define OpenCounter(X) #endif /* defined(SQLITE_TEST) */ @@ -45952,13 +45952,13 @@ typedef struct winceLock { #endif /* -** The winFile structure is a subclass of tdsqlite3_file* specific to the win32 +** The winFile structure is a subclass of sqlite3_file* specific to the win32 ** portability layer. */ typedef struct winFile winFile; struct winFile { - const tdsqlite3_io_methods *pMethod; /*** Must be first ***/ - tdsqlite3_vfs *pVfs; /* The VFS used to open this file */ + const sqlite3_io_methods *pMethod; /*** Must be first ***/ + sqlite3_vfs *pVfs; /* The VFS used to open this file */ HANDLE h; /* Handle for accessing the file */ u8 locktype; /* Type of lock currently held on this file */ short sharedLockByte; /* Randomly chosen byte used as a shared lock */ @@ -45980,8 +45980,8 @@ struct winFile { int nFetchOut; /* Number of outstanding xFetch references */ HANDLE hMap; /* Handle for accessing memory mapping */ void *pMapRegion; /* Area memory mapped */ - tdsqlite3_int64 mmapSize; /* Size of mapped region */ - tdsqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ + sqlite3_int64 mmapSize; /* Size of mapped region */ + sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ #endif }; @@ -45991,7 +45991,7 @@ struct winFile { */ typedef struct winVfsAppData winVfsAppData; struct winVfsAppData { - const tdsqlite3_io_methods *pMethod; /* The file I/O methods to use. */ + const sqlite3_io_methods *pMethod; /* The file I/O methods to use. */ void *pAppData; /* The extra pAppData, if any. */ BOOL bNoLock; /* Non-zero if locking is disabled. */ }; @@ -46004,7 +46004,7 @@ struct winVfsAppData { #define WINFILE_PSOW 0x10 /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */ /* - * The size of the buffer used by tdsqlite3_win32_write_debug(). + * The size of the buffer used by sqlite3_win32_write_debug(). */ #ifndef SQLITE_WIN32_DBG_BUF_SIZE # define SQLITE_WIN32_DBG_BUF_SIZE ((int)(4096-sizeof(DWORD))) @@ -46024,7 +46024,7 @@ struct winVfsAppData { * ****************************************************************************** * WARNING: It is important to note that when this setting is non-zero and the - * winMemShutdown function is called (e.g. by the tdsqlite3_shutdown + * winMemShutdown function is called (e.g. by the sqlite3_shutdown * function), all data that was allocated using the isolated heap will * be freed immediately and any attempt to access any of that freed * data will almost certainly result in an immediate access violation. @@ -46110,7 +46110,7 @@ struct winVfsAppData { /* ** The winMemData structure stores information required by the Win32-specific -** tdsqlite3_mem_methods implementation. +** sqlite3_mem_methods implementation. */ typedef struct winMemData winMemData; struct winMemData { @@ -46159,7 +46159,7 @@ static int winMemRoundup(int n); static int winMemInit(void *pAppData); static void winMemShutdown(void *pAppData); -SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetWin32(void); +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void); #endif /* SQLITE_WIN32_MALLOC */ /* @@ -46175,13 +46175,13 @@ SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetWin32(void); ** can manually set this value to 1 to emulate Win98 behavior. */ #ifdef SQLITE_TEST -SQLITE_API LONG SQLITE_WIN32_VOLATILE tdsqlite3_os_type = 0; +SQLITE_API LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; #else -static LONG SQLITE_WIN32_VOLATILE tdsqlite3_os_type = 0; +static LONG SQLITE_WIN32_VOLATILE sqlite3_os_type = 0; #endif #ifndef SYSCALL -# define SYSCALL tdsqlite3_syscall_ptr +# define SYSCALL sqlite3_syscall_ptr #endif /* @@ -46200,8 +46200,8 @@ static LONG SQLITE_WIN32_VOLATILE tdsqlite3_os_type = 0; */ static struct win_syscall { const char *zName; /* Name of the system call */ - tdsqlite3_syscall_ptr pCurrent; /* Current value of the system call */ - tdsqlite3_syscall_ptr pDefault; /* Default value */ + sqlite3_syscall_ptr pCurrent; /* Current value of the system call */ + sqlite3_syscall_ptr pDefault; /* Default value */ } aSyscall[] = { #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT { "AreFileApisANSI", (SYSCALL)AreFileApisANSI, 0 }, @@ -46854,15 +46854,15 @@ static struct win_syscall { }; /* End of the overrideable system calls */ /* -** This is the xSetSystemCall() method of tdsqlite3_vfs for all of the +** This is the xSetSystemCall() method of sqlite3_vfs for all of the ** "win32" VFSes. Return SQLITE_OK opon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable ** system call named zName. */ static int winSetSystemCall( - tdsqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ + sqlite3_vfs *pNotUsed, /* The VFS pointer. Not used */ const char *zName, /* Name of system call to override */ - tdsqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ + sqlite3_syscall_ptr pNewFunc /* Pointer to new system call value */ ){ unsigned int i; int rc = SQLITE_NOTFOUND; @@ -46902,8 +46902,8 @@ static int winSetSystemCall( ** recognized system call name. NULL is also returned if the system call ** is currently undefined. */ -static tdsqlite3_syscall_ptr winGetSystemCall( - tdsqlite3_vfs *pNotUsed, +static sqlite3_syscall_ptr winGetSystemCall( + sqlite3_vfs *pNotUsed, const char *zName ){ unsigned int i; @@ -46921,7 +46921,7 @@ static tdsqlite3_syscall_ptr winGetSystemCall( ** is the last system call or if zName is not the name of a valid ** system call. */ -static const char *winNextSystemCall(tdsqlite3_vfs *p, const char *zName){ +static const char *winNextSystemCall(sqlite3_vfs *p, const char *zName){ int i = -1; UNUSED_PARAMETER(p); @@ -46944,7 +46944,7 @@ static const char *winNextSystemCall(tdsqlite3_vfs *p, const char *zName){ ** "pnLargest" argument, if non-zero, will be used to return the size of the ** largest committed free block in the heap, in bytes. */ -SQLITE_API int tdsqlite3_win32_compact_heap(LPUINT pnLargest){ +SQLITE_API int sqlite3_win32_compact_heap(LPUINT pnLargest){ int rc = SQLITE_OK; UINT nLargest = 0; HANDLE hHeap; @@ -46960,17 +46960,17 @@ SQLITE_API int tdsqlite3_win32_compact_heap(LPUINT pnLargest){ if( (nLargest=osHeapCompact(hHeap, SQLITE_WIN32_HEAP_FLAGS))==0 ){ DWORD lastErrno = osGetLastError(); if( lastErrno==NO_ERROR ){ - tdsqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p", + sqlite3_log(SQLITE_NOMEM, "failed to HeapCompact (no space), heap=%p", (void*)hHeap); rc = SQLITE_NOMEM_BKPT; }else{ - tdsqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p", + sqlite3_log(SQLITE_ERROR, "failed to HeapCompact (%lu), heap=%p", osGetLastError(), (void*)hHeap); rc = SQLITE_ERROR; } } #else - tdsqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p", + sqlite3_log(SQLITE_NOTFOUND, "failed to HeapCompact, heap=%p", (void*)hHeap); rc = SQLITE_NOTFOUND; #endif @@ -46981,19 +46981,19 @@ SQLITE_API int tdsqlite3_win32_compact_heap(LPUINT pnLargest){ /* ** If a Win32 native heap has been configured, this function will attempt to ** destroy and recreate it. If the Win32 native heap is not isolated and/or -** the tdsqlite3_memory_used() function does not return zero, SQLITE_BUSY will +** the sqlite3_memory_used() function does not return zero, SQLITE_BUSY will ** be returned and no changes will be made to the Win32 native heap. */ -SQLITE_API int tdsqlite3_win32_reset_heap(){ +SQLITE_API int sqlite3_win32_reset_heap(){ int rc; - MUTEX_LOGIC( tdsqlite3_mutex *pMaster; ) /* The main static mutex */ - MUTEX_LOGIC( tdsqlite3_mutex *pMem; ) /* The memsys static mutex */ - MUTEX_LOGIC( pMaster = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - MUTEX_LOGIC( pMem = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); ) - tdsqlite3_mutex_enter(pMaster); - tdsqlite3_mutex_enter(pMem); + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ + MUTEX_LOGIC( sqlite3_mutex *pMem; ) /* The memsys static mutex */ + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + MUTEX_LOGIC( pMem = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); ) + sqlite3_mutex_enter(pMaster); + sqlite3_mutex_enter(pMem); winMemAssertMagic(); - if( winMemGetHeap()!=NULL && winMemGetOwned() && tdsqlite3_memory_used()==0 ){ + if( winMemGetHeap()!=NULL && winMemGetOwned() && sqlite3_memory_used()==0 ){ /* ** At this point, there should be no outstanding memory allocations on ** the heap. Also, since both the master and memsys locks are currently @@ -47003,23 +47003,23 @@ SQLITE_API int tdsqlite3_win32_reset_heap(){ */ assert( winMemGetHeap()!=NULL ); assert( winMemGetOwned() ); - assert( tdsqlite3_memory_used()==0 ); + assert( sqlite3_memory_used()==0 ); winMemShutdown(winMemGetDataPtr()); assert( winMemGetHeap()==NULL ); assert( !winMemGetOwned() ); - assert( tdsqlite3_memory_used()==0 ); + assert( sqlite3_memory_used()==0 ); rc = winMemInit(winMemGetDataPtr()); assert( rc!=SQLITE_OK || winMemGetHeap()!=NULL ); assert( rc!=SQLITE_OK || winMemGetOwned() ); - assert( rc!=SQLITE_OK || tdsqlite3_memory_used()==0 ); + assert( rc!=SQLITE_OK || sqlite3_memory_used()==0 ); }else{ /* ** The Win32 native heap cannot be modified because it may be in use. */ rc = SQLITE_BUSY; } - tdsqlite3_mutex_leave(pMem); - tdsqlite3_mutex_leave(pMaster); + sqlite3_mutex_leave(pMem); + sqlite3_mutex_leave(pMaster); return rc; } #endif /* SQLITE_WIN32_MALLOC */ @@ -47029,7 +47029,7 @@ SQLITE_API int tdsqlite3_win32_reset_heap(){ ** (if available). */ -SQLITE_API void tdsqlite3_win32_write_debug(const char *zBuf, int nBuf){ +SQLITE_API void sqlite3_win32_write_debug(const char *zBuf, int nBuf){ char zDbgBuf[SQLITE_WIN32_DBG_BUF_SIZE]; int nMin = MIN(nBuf, (SQLITE_WIN32_DBG_BUF_SIZE - 1)); /* may be negative. */ if( nMin<-1 ) nMin = -1; /* all negative values become -1. */ @@ -47075,7 +47075,7 @@ SQLITE_API void tdsqlite3_win32_write_debug(const char *zBuf, int nBuf){ static HANDLE sleepObj = NULL; #endif -SQLITE_API void tdsqlite3_win32_sleep(DWORD milliseconds){ +SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds){ #if SQLITE_OS_WINRT if ( sleepObj==NULL ){ sleepObj = osCreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, @@ -47090,7 +47090,7 @@ SQLITE_API void tdsqlite3_win32_sleep(DWORD milliseconds){ #if SQLITE_MAX_WORKER_THREADS>0 && !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && \ SQLITE_THREADSAFE>0 -SQLITE_PRIVATE DWORD tdsqlite3Win32Wait(HANDLE hObject){ +SQLITE_PRIVATE DWORD sqlite3Win32Wait(HANDLE hObject){ DWORD rc; while( (rc = osWaitForSingleObjectEx(hObject, INFINITE, TRUE))==WAIT_IO_COMPLETION ){} @@ -47117,14 +47117,14 @@ SQLITE_PRIVATE DWORD tdsqlite3Win32Wait(HANDLE hObject){ #elif !defined(SQLITE_WIN32_HAS_WIDE) # define osIsNT() (0) #else -# define osIsNT() ((tdsqlite3_os_type==2) || tdsqlite3_win32_is_nt()) +# define osIsNT() ((sqlite3_os_type==2) || sqlite3_win32_is_nt()) #endif /* ** This function determines if the machine is running a version of Windows ** based on the NT kernel. */ -SQLITE_API int tdsqlite3_win32_is_nt(void){ +SQLITE_API int sqlite3_win32_is_nt(void){ #if SQLITE_OS_WINRT /* ** NOTE: The WinRT sub-platform is always assumed to be based on the NT @@ -47132,24 +47132,24 @@ SQLITE_API int tdsqlite3_win32_is_nt(void){ */ return 1; #elif SQLITE_WIN32_GETVERSIONEX - if( osInterlockedCompareExchange(&tdsqlite3_os_type, 0, 0)==0 ){ + if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){ #if defined(SQLITE_WIN32_HAS_ANSI) OSVERSIONINFOA sInfo; sInfo.dwOSVersionInfoSize = sizeof(sInfo); osGetVersionExA(&sInfo); - osInterlockedCompareExchange(&tdsqlite3_os_type, + osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); #elif defined(SQLITE_WIN32_HAS_WIDE) OSVERSIONINFOW sInfo; sInfo.dwOSVersionInfoSize = sizeof(sInfo); osGetVersionExW(&sInfo); - osInterlockedCompareExchange(&tdsqlite3_os_type, + osInterlockedCompareExchange(&sqlite3_os_type, (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0); #endif } - return osInterlockedCompareExchange(&tdsqlite3_os_type, 2, 2)==2; + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #elif SQLITE_TEST - return osInterlockedCompareExchange(&tdsqlite3_os_type, 2, 2)==2; + return osInterlockedCompareExchange(&sqlite3_os_type, 2, 2)==2; #else /* ** NOTE: All sub-platforms where the GetVersionEx[AW] functions are @@ -47177,7 +47177,7 @@ static void *winMemMalloc(int nBytes){ assert( nBytes>=0 ); p = osHeapAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, (SIZE_T)nBytes); if( !p ){ - tdsqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p", + sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%lu), heap=%p", nBytes, osGetLastError(), (void*)hHeap); } return p; @@ -47198,7 +47198,7 @@ static void winMemFree(void *pPrior){ #endif if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */ if( !osHeapFree(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior) ){ - tdsqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p", + sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%lu), heap=%p", pPrior, osGetLastError(), (void*)hHeap); } } @@ -47224,7 +47224,7 @@ static void *winMemRealloc(void *pPrior, int nBytes){ p = osHeapReAlloc(hHeap, SQLITE_WIN32_HEAP_FLAGS, pPrior, (SIZE_T)nBytes); } if( !p ){ - tdsqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p", + sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%lu), heap=%p", pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, osGetLastError(), (void*)hHeap); } @@ -47248,7 +47248,7 @@ static int winMemSize(void *p){ if( !p ) return 0; n = osHeapSize(hHeap, SQLITE_WIN32_HEAP_FLAGS, p); if( n==(SIZE_T)-1 ){ - tdsqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p", + sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%lu), heap=%p", p, osGetLastError(), (void*)hHeap); return 0; } @@ -47275,7 +47275,7 @@ static int winMemInit(void *pAppData){ #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE if( !pWinMemData->hHeap ){ DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; - DWORD dwMaximumSize = (DWORD)tdsqlite3GlobalConfig.nHeap; + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; if( dwMaximumSize==0 ){ dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; }else if( dwInitialSize>dwMaximumSize ){ @@ -47284,7 +47284,7 @@ static int winMemInit(void *pAppData){ pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, dwMaximumSize); if( !pWinMemData->hHeap ){ - tdsqlite3_log(SQLITE_NOMEM, + sqlite3_log(SQLITE_NOMEM, "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, dwMaximumSize); @@ -47296,7 +47296,7 @@ static int winMemInit(void *pAppData){ #else pWinMemData->hHeap = osGetProcessHeap(); if( !pWinMemData->hHeap ){ - tdsqlite3_log(SQLITE_NOMEM, + sqlite3_log(SQLITE_NOMEM, "failed to GetProcessHeap (%lu)", osGetLastError()); return SQLITE_NOMEM_BKPT; } @@ -47328,7 +47328,7 @@ static void winMemShutdown(void *pAppData){ #endif if( pWinMemData->bOwned ){ if( !osHeapDestroy(pWinMemData->hHeap) ){ - tdsqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p", + sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%lu), heap=%p", osGetLastError(), (void*)pWinMemData->hHeap); } pWinMemData->bOwned = FALSE; @@ -47339,14 +47339,14 @@ static void winMemShutdown(void *pAppData){ /* ** Populate the low-level memory allocation function pointers in -** tdsqlite3GlobalConfig.m with pointers to the routines in this file. The +** sqlite3GlobalConfig.m with pointers to the routines in this file. The ** arguments specify the block of memory to manage. ** -** This routine is only called by tdsqlite3_config(), and therefore +** This routine is only called by sqlite3_config(), and therefore ** is not required to be threadsafe (it is not). */ -SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetWin32(void){ - static const tdsqlite3_mem_methods winMemMethods = { +SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetWin32(void){ + static const sqlite3_mem_methods winMemMethods = { winMemMalloc, winMemFree, winMemRealloc, @@ -47359,15 +47359,15 @@ SQLITE_PRIVATE const tdsqlite3_mem_methods *tdsqlite3MemGetWin32(void){ return &winMemMethods; } -SQLITE_PRIVATE void tdsqlite3MemSetDefault(void){ - tdsqlite3_config(SQLITE_CONFIG_MALLOC, tdsqlite3MemGetWin32()); +SQLITE_PRIVATE void sqlite3MemSetDefault(void){ + sqlite3_config(SQLITE_CONFIG_MALLOC, sqlite3MemGetWin32()); } #endif /* SQLITE_WIN32_MALLOC */ /* ** Convert a UTF-8 string to Microsoft Unicode. ** -** Space to hold the returned string is obtained from tdsqlite3_malloc(). +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winUtf8ToUnicode(const char *zText){ int nChar; @@ -47377,14 +47377,14 @@ static LPWSTR winUtf8ToUnicode(const char *zText){ if( nChar==0 ){ return 0; } - zWideText = tdsqlite3MallocZero( nChar*sizeof(WCHAR) ); + zWideText = sqlite3MallocZero( nChar*sizeof(WCHAR) ); if( zWideText==0 ){ return 0; } nChar = osMultiByteToWideChar(CP_UTF8, 0, zText, -1, zWideText, nChar); if( nChar==0 ){ - tdsqlite3_free(zWideText); + sqlite3_free(zWideText); zWideText = 0; } return zWideText; @@ -47393,7 +47393,7 @@ static LPWSTR winUtf8ToUnicode(const char *zText){ /* ** Convert a Microsoft Unicode string to UTF-8. ** -** Space to hold the returned string is obtained from tdsqlite3_malloc(). +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUnicodeToUtf8(LPCWSTR zWideText){ int nByte; @@ -47403,14 +47403,14 @@ static char *winUnicodeToUtf8(LPCWSTR zWideText){ if( nByte == 0 ){ return 0; } - zText = tdsqlite3MallocZero( nByte ); + zText = sqlite3MallocZero( nByte ); if( zText==0 ){ return 0; } nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideText, -1, zText, nByte, 0, 0); if( nByte == 0 ){ - tdsqlite3_free(zText); + sqlite3_free(zText); zText = 0; } return zText; @@ -47420,7 +47420,7 @@ static char *winUnicodeToUtf8(LPCWSTR zWideText){ ** Convert an ANSI string to Microsoft Unicode, using the ANSI or OEM ** code page. ** -** Space to hold the returned string is obtained from tdsqlite3_malloc(). +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ int nByte; @@ -47432,14 +47432,14 @@ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ if( nByte==0 ){ return 0; } - zMbcsText = tdsqlite3MallocZero( nByte*sizeof(WCHAR) ); + zMbcsText = sqlite3MallocZero( nByte*sizeof(WCHAR) ); if( zMbcsText==0 ){ return 0; } nByte = osMultiByteToWideChar(codepage, 0, zText, -1, zMbcsText, nByte); if( nByte==0 ){ - tdsqlite3_free(zMbcsText); + sqlite3_free(zMbcsText); zMbcsText = 0; } return zMbcsText; @@ -47449,7 +47449,7 @@ static LPWSTR winMbcsToUnicode(const char *zText, int useAnsi){ ** Convert a Microsoft Unicode string to a multi-byte character string, ** using the ANSI or OEM code page. ** -** Space to hold the returned string is obtained from tdsqlite3_malloc(). +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ int nByte; @@ -47460,14 +47460,14 @@ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ if( nByte == 0 ){ return 0; } - zText = tdsqlite3MallocZero( nByte ); + zText = sqlite3MallocZero( nByte ); if( zText==0 ){ return 0; } nByte = osWideCharToMultiByte(codepage, 0, zWideText, -1, zText, nByte, 0, 0); if( nByte == 0 ){ - tdsqlite3_free(zText); + sqlite3_free(zText); zText = 0; } return zText; @@ -47476,7 +47476,7 @@ static char *winUnicodeToMbcs(LPCWSTR zWideText, int useAnsi){ /* ** Convert a multi-byte character string to UTF-8. ** -** Space to hold the returned string is obtained from tdsqlite3_malloc(). +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winMbcsToUtf8(const char *zText, int useAnsi){ char *zTextUtf8; @@ -47487,14 +47487,14 @@ static char *winMbcsToUtf8(const char *zText, int useAnsi){ return 0; } zTextUtf8 = winUnicodeToUtf8(zTmpWide); - tdsqlite3_free(zTmpWide); + sqlite3_free(zTmpWide); return zTextUtf8; } /* ** Convert a UTF-8 string to a multi-byte character string. ** -** Space to hold the returned string is obtained from tdsqlite3_malloc(). +** Space to hold the returned string is obtained from sqlite3_malloc(). */ static char *winUtf8ToMbcs(const char *zText, int useAnsi){ char *zTextMbcs; @@ -47505,14 +47505,14 @@ static char *winUtf8ToMbcs(const char *zText, int useAnsi){ return 0; } zTextMbcs = winUnicodeToMbcs(zTmpWide, useAnsi); - tdsqlite3_free(zTmpWide); + sqlite3_free(zTmpWide); return zTextMbcs; } /* ** This is a public wrapper for the winUtf8ToUnicode() function. */ -SQLITE_API LPWSTR tdsqlite3_win32_utf8_to_unicode(const char *zText){ +SQLITE_API LPWSTR sqlite3_win32_utf8_to_unicode(const char *zText){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; @@ -47520,7 +47520,7 @@ SQLITE_API LPWSTR tdsqlite3_win32_utf8_to_unicode(const char *zText){ } #endif #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif return winUtf8ToUnicode(zText); } @@ -47528,7 +47528,7 @@ SQLITE_API LPWSTR tdsqlite3_win32_utf8_to_unicode(const char *zText){ /* ** This is a public wrapper for the winUnicodeToUtf8() function. */ -SQLITE_API char *tdsqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ +SQLITE_API char *sqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zWideText ){ (void)SQLITE_MISUSE_BKPT; @@ -47536,7 +47536,7 @@ SQLITE_API char *tdsqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ } #endif #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif return winUnicodeToUtf8(zWideText); } @@ -47544,7 +47544,7 @@ SQLITE_API char *tdsqlite3_win32_unicode_to_utf8(LPCWSTR zWideText){ /* ** This is a public wrapper for the winMbcsToUtf8() function. */ -SQLITE_API char *tdsqlite3_win32_mbcs_to_utf8(const char *zText){ +SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zText){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; @@ -47552,7 +47552,7 @@ SQLITE_API char *tdsqlite3_win32_mbcs_to_utf8(const char *zText){ } #endif #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif return winMbcsToUtf8(zText, osAreFileApisANSI()); } @@ -47560,7 +47560,7 @@ SQLITE_API char *tdsqlite3_win32_mbcs_to_utf8(const char *zText){ /* ** This is a public wrapper for the winMbcsToUtf8() function. */ -SQLITE_API char *tdsqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ +SQLITE_API char *sqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; @@ -47568,7 +47568,7 @@ SQLITE_API char *tdsqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi) } #endif #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif return winMbcsToUtf8(zText, useAnsi); } @@ -47576,7 +47576,7 @@ SQLITE_API char *tdsqlite3_win32_mbcs_to_utf8_v2(const char *zText, int useAnsi) /* ** This is a public wrapper for the winUtf8ToMbcs() function. */ -SQLITE_API char *tdsqlite3_win32_utf8_to_mbcs(const char *zText){ +SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zText){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; @@ -47584,7 +47584,7 @@ SQLITE_API char *tdsqlite3_win32_utf8_to_mbcs(const char *zText){ } #endif #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif return winUtf8ToMbcs(zText, osAreFileApisANSI()); } @@ -47592,7 +47592,7 @@ SQLITE_API char *tdsqlite3_win32_utf8_to_mbcs(const char *zText){ /* ** This is a public wrapper for the winUtf8ToMbcs() function. */ -SQLITE_API char *tdsqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ +SQLITE_API char *sqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi){ #ifdef SQLITE_ENABLE_API_ARMOR if( !zText ){ (void)SQLITE_MISUSE_BKPT; @@ -47600,42 +47600,42 @@ SQLITE_API char *tdsqlite3_win32_utf8_to_mbcs_v2(const char *zText, int useAnsi) } #endif #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize() ) return 0; + if( sqlite3_initialize() ) return 0; #endif return winUtf8ToMbcs(zText, useAnsi); } /* -** This function is the same as tdsqlite3_win32_set_directory (below); however, +** This function is the same as sqlite3_win32_set_directory (below); however, ** it accepts a UTF-8 string. */ -SQLITE_API int tdsqlite3_win32_set_directory8( +SQLITE_API int sqlite3_win32_set_directory8( unsigned long type, /* Identifier for directory being set or reset */ const char *zValue /* New value for directory being set or reset */ ){ char **ppDirectory = 0; #ifndef SQLITE_OMIT_AUTOINIT - int rc = tdsqlite3_initialize(); + int rc = sqlite3_initialize(); if( rc ) return rc; #endif if( type==SQLITE_WIN32_DATA_DIRECTORY_TYPE ){ - ppDirectory = &tdsqlite3_data_directory; + ppDirectory = &sqlite3_data_directory; }else if( type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ){ - ppDirectory = &tdsqlite3_temp_directory; + ppDirectory = &sqlite3_temp_directory; } assert( !ppDirectory || type==SQLITE_WIN32_DATA_DIRECTORY_TYPE || type==SQLITE_WIN32_TEMP_DIRECTORY_TYPE ); - assert( !ppDirectory || tdsqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); + assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); if( ppDirectory ){ char *zCopy = 0; if( zValue && zValue[0] ){ - zCopy = tdsqlite3_mprintf("%s", zValue); + zCopy = sqlite3_mprintf("%s", zValue); if ( zCopy==0 ){ return SQLITE_NOMEM_BKPT; } } - tdsqlite3_free(*ppDirectory); + sqlite3_free(*ppDirectory); *ppDirectory = zCopy; return SQLITE_OK; } @@ -47643,21 +47643,21 @@ SQLITE_API int tdsqlite3_win32_set_directory8( } /* -** This function is the same as tdsqlite3_win32_set_directory (below); however, +** This function is the same as sqlite3_win32_set_directory (below); however, ** it accepts a UTF-16 string. */ -SQLITE_API int tdsqlite3_win32_set_directory16( +SQLITE_API int sqlite3_win32_set_directory16( unsigned long type, /* Identifier for directory being set or reset */ const void *zValue /* New value for directory being set or reset */ ){ int rc; char *zUtf8 = 0; if( zValue ){ - zUtf8 = tdsqlite3_win32_unicode_to_utf8(zValue); + zUtf8 = sqlite3_win32_unicode_to_utf8(zValue); if( zUtf8==0 ) return SQLITE_NOMEM_BKPT; } - rc = tdsqlite3_win32_set_directory8(type, zUtf8); - if( zUtf8 ) tdsqlite3_free(zUtf8); + rc = sqlite3_win32_set_directory8(type, zUtf8); + if( zUtf8 ) sqlite3_free(zUtf8); return rc; } @@ -47668,11 +47668,11 @@ SQLITE_API int tdsqlite3_win32_set_directory16( ** argument is the name of the directory to use. The return value will be ** SQLITE_OK if successful. */ -SQLITE_API int tdsqlite3_win32_set_directory( +SQLITE_API int sqlite3_win32_set_directory( unsigned long type, /* Identifier for directory being set or reset */ void *zValue /* New value for directory being set or reset */ ){ - return tdsqlite3_win32_set_directory16(type, zValue); + return sqlite3_win32_set_directory16(type, zValue); } /* @@ -47713,9 +47713,9 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ #endif if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); zOut = winUnicodeToUtf8(zTempWide); - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); #if !SQLITE_OS_WINRT /* free the system buffer allocated by FormatMessage */ osLocalFree(zTempWide); @@ -47736,21 +47736,21 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ 0); if( dwLen > 0 ){ /* allocate a buffer and convert to UTF8 */ - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); /* free the system buffer allocated by FormatMessage */ osLocalFree(zTemp); } } #endif if( 0 == dwLen ){ - tdsqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); }else{ /* copy a maximum of nBuf chars to output buffer */ - tdsqlite3_snprintf(nBuf, zBuf, "%s", zOut); + sqlite3_snprintf(nBuf, zBuf, "%s", zOut); /* free the UTF8 buffer */ - tdsqlite3_free(zOut); + sqlite3_free(zOut); } return 0; } @@ -47761,7 +47761,7 @@ static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ ** winLogError(). ** ** This routine is invoked after an error occurs in an OS function. -** It logs a message using tdsqlite3_log() containing the current value of +** It logs a message using sqlite3_log() containing the current value of ** error code and, if possible, the human-readable equivalent from ** FormatMessage. ** @@ -47787,7 +47787,7 @@ static int winLogErrorAtLine( if( zPath==0 ) zPath = ""; for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} zMsg[i] = 0; - tdsqlite3_log(errcode, + sqlite3_log(errcode, "os_win.c:%d: (%lu) %s(%s) - %s", iLine, lastErrno, zFunc, zPath, zMsg ); @@ -47850,13 +47850,13 @@ static int winRetryIoerr(int *pnRetry, DWORD *pError){ return 0; } if( winIoerrCanRetry1(e) ){ - tdsqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); ++*pnRetry; return 1; } #if defined(winIoerrCanRetry2) else if( winIoerrCanRetry2(e) ){ - tdsqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); ++*pnRetry; return 1; } @@ -47872,7 +47872,7 @@ static int winRetryIoerr(int *pnRetry, DWORD *pError){ */ static void winLogIoerr(int nRetry, int lineno){ if( nRetry ){ - tdsqlite3_log(SQLITE_NOTICE, + sqlite3_log(SQLITE_NOTICE, "delayed %dms for lock/sharing conflict at line %d", winIoerrRetryDelay*nRetry*(nRetry+1)/2, lineno ); @@ -47895,7 +47895,7 @@ struct tm *__cdecl localtime(const time_t *t) static struct tm y; FILETIME uTm, lTm; SYSTEMTIME pTm; - tdsqlite3_int64 t64; + sqlite3_int64 t64; t64 = *t; t64 = (t64 + 11644473600)*10000000; uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); @@ -47964,7 +47964,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){ pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); if (!pFile->hMutex){ pFile->lastErrno = osGetLastError(); - tdsqlite3_free(zName); + sqlite3_free(zName); return winLogError(SQLITE_IOERR, pFile->lastErrno, "winceCreateLock1", zFilename); } @@ -47988,7 +47988,7 @@ static int winceCreateLock(const char *zFilename, winFile *pFile){ bInit = FALSE; } - tdsqlite3_free(zName); + sqlite3_free(zName); /* If we succeeded in making the shared memory handle, map it. */ if( pFile->hShared ){ @@ -48262,7 +48262,7 @@ static BOOL winUnlockFile( /***************************************************************************** ** The next group of routines implement the I/O methods specified -** by the tdsqlite3_io_methods object. +** by the sqlite3_io_methods object. ******************************************************************************/ /* @@ -48277,7 +48277,7 @@ static BOOL winUnlockFile( ** argument to offset iOffset within the file. If successful, return 0. ** Otherwise, set pFile->lastErrno and return non-zero. */ -static int winSeekFile(winFile *pFile, tdsqlite3_int64 iOffset){ +static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ #if !SQLITE_OS_WINRT LONG upperBits; /* Most sig. 32 bits of new offset */ LONG lowerBits; /* Least sig. 32 bits of new offset */ @@ -48335,7 +48335,7 @@ static int winSeekFile(winFile *pFile, tdsqlite3_int64 iOffset){ #if SQLITE_MAX_MMAP_SIZE>0 /* Forward references to VFS helper methods used for memory mapped files */ -static int winMapfile(winFile*, tdsqlite3_int64); +static int winMapfile(winFile*, sqlite3_int64); static int winUnmapfile(winFile*); #endif @@ -48350,7 +48350,7 @@ static int winUnmapfile(winFile*); ** giving up and returning an error. */ #define MX_CLOSE_ATTEMPT 3 -static int winClose(tdsqlite3_file *id){ +static int winClose(sqlite3_file *id){ int rc, cnt = 0; winFile *pFile = (winFile*)id; @@ -48369,7 +48369,7 @@ static int winClose(tdsqlite3_file *id){ do{ rc = osCloseHandle(pFile->h); /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ - }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (tdsqlite3_win32_sleep(100), 1) ); + }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (sqlite3_win32_sleep(100), 1) ); #if SQLITE_OS_WINCE #define WINCE_DELETION_ATTEMPTS 3 { @@ -48385,9 +48385,9 @@ static int winClose(tdsqlite3_file *id){ && osGetFileAttributesW(pFile->zDeleteOnClose)!=0xffffffff && cnt++ < WINCE_DELETION_ATTEMPTS ){ - tdsqlite3_win32_sleep(100); /* Wait a little before trying again */ + sqlite3_win32_sleep(100); /* Wait a little before trying again */ } - tdsqlite3_free(pFile->zDeleteOnClose); + sqlite3_free(pFile->zDeleteOnClose); } #endif if( rc ){ @@ -48407,10 +48407,10 @@ static int winClose(tdsqlite3_file *id){ ** wrong. */ static int winRead( - tdsqlite3_file *id, /* File to read from */ + sqlite3_file *id, /* File to read from */ void *pBuf, /* Write content into this buffer */ int amt, /* Number of bytes to read */ - tdsqlite3_int64 offset /* Begin reading at this offset */ + sqlite3_int64 offset /* Begin reading at this offset */ ){ #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED) OVERLAPPED overlapped; /* The offset for ReadFile. */ @@ -48487,10 +48487,10 @@ static int winRead( ** or some other error code on failure. */ static int winWrite( - tdsqlite3_file *id, /* File to write into */ + sqlite3_file *id, /* File to write into */ const void *pBuf, /* The bytes to be written */ int amt, /* Number of bytes to write */ - tdsqlite3_int64 offset /* Offset into the file to begin writing at */ + sqlite3_int64 offset /* Offset into the file to begin writing at */ ){ int rc = 0; /* True if error has occurred, else false */ winFile *pFile = (winFile*)id; /* File handle */ @@ -48595,12 +48595,12 @@ static int winWrite( /* ** Truncate an open file to a specified size */ -static int winTruncate(tdsqlite3_file *id, tdsqlite3_int64 nByte){ +static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){ winFile *pFile = (winFile*)id; /* File handle object */ int rc = SQLITE_OK; /* Return code for this function */ DWORD lastErrno; #if SQLITE_MAX_MMAP_SIZE>0 - tdsqlite3_int64 oldMmapSize; + sqlite3_int64 oldMmapSize; if( pFile->nFetchOut>0 ){ /* File truncation is a no-op if there are outstanding memory mapped ** pages. This is because truncating the file means temporarily unmapping @@ -48668,7 +48668,7 @@ static int winTruncate(tdsqlite3_file *id, tdsqlite3_int64 nByte){ #endif OSTRACE(("TRUNCATE pid=%lu, pFile=%p, file=%p, rc=%s\n", - osGetCurrentProcessId(), pFile, pFile->h, tdsqlite3ErrName(rc))); + osGetCurrentProcessId(), pFile, pFile->h, sqlite3ErrName(rc))); return rc; } @@ -48677,14 +48677,14 @@ static int winTruncate(tdsqlite3_file *id, tdsqlite3_int64 nByte){ ** Count the number of fullsyncs and normal syncs. This is used to test ** that syncs and fullsyncs are occuring at the right times. */ -SQLITE_API int tdsqlite3_sync_count = 0; -SQLITE_API int tdsqlite3_fullsync_count = 0; +SQLITE_API int sqlite3_sync_count = 0; +SQLITE_API int sqlite3_fullsync_count = 0; #endif /* ** Make sure all writes to a particular file are committed to disk. */ -static int winSync(tdsqlite3_file *id, int flags){ +static int winSync(sqlite3_file *id, int flags){ #ifndef SQLITE_NO_SYNC /* ** Used only when SQLITE_NO_SYNC is not defined. @@ -48721,9 +48721,9 @@ static int winSync(tdsqlite3_file *id, int flags){ UNUSED_PARAMETER(flags); #else if( (flags&0x0F)==SQLITE_SYNC_FULL ){ - tdsqlite3_fullsync_count++; + sqlite3_fullsync_count++; } - tdsqlite3_sync_count++; + sqlite3_sync_count++; #endif /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a @@ -48769,7 +48769,7 @@ static int winSync(tdsqlite3_file *id, int flags){ /* ** Determine the current size of a file in bytes */ -static int winFileSize(tdsqlite3_file *id, tdsqlite3_int64 *pSize){ +static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ winFile *pFile = (winFile*)id; int rc = SQLITE_OK; @@ -48797,7 +48797,7 @@ static int winFileSize(tdsqlite3_file *id, tdsqlite3_int64 *pSize){ DWORD lastErrno; lowerBits = osGetFileSize(pFile->h, &upperBits); - *pSize = (((tdsqlite3_int64)upperBits)<<32) + lowerBits; + *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; if( (lowerBits == INVALID_FILE_SIZE) && ((lastErrno = osGetLastError())!=NO_ERROR) ){ pFile->lastErrno = lastErrno; @@ -48807,7 +48807,7 @@ static int winFileSize(tdsqlite3_file *id, tdsqlite3_int64 *pSize){ } #endif OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", - pFile->h, pSize, *pSize, tdsqlite3ErrName(rc))); + pFile->h, pSize, *pSize, sqlite3ErrName(rc))); return rc; } @@ -48865,7 +48865,7 @@ static int winGetReadLock(winFile *pFile){ #ifdef SQLITE_WIN32_HAS_ANSI else{ int lk; - tdsqlite3_randomness(sizeof(lk), &lk); + sqlite3_randomness(sizeof(lk), &lk); pFile->sharedLockByte = (short)((lk & 0x7fffffff)%(SHARED_SIZE - 1)); res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); @@ -48929,7 +48929,7 @@ static int winUnlockReadLock(winFile *pFile){ ** It is not possible to lower the locking level one step at a time. You ** must go straight to locking level 0. */ -static int winLock(tdsqlite3_file *id, int locktype){ +static int winLock(sqlite3_file *id, int locktype){ int rc = SQLITE_OK; /* Return code from subroutines */ int res = 1; /* Result of a Windows lock call */ int newLocktype; /* Set pFile->locktype to this value before exiting */ @@ -48943,7 +48943,7 @@ static int winLock(tdsqlite3_file *id, int locktype){ /* If there is already a lock of this type or more restrictive on the ** OsFile, do nothing. Don't use the end_lock: exit path, as - ** tdsqlite3OsEnterMutex() hasn't been called yet. + ** sqlite3OsEnterMutex() hasn't been called yet. */ if( pFile->locktype>=locktype ){ OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); @@ -48986,10 +48986,10 @@ static int winLock(tdsqlite3_file *id, int locktype){ pFile->lastErrno = lastErrno; rc = SQLITE_IOERR_LOCK; OSTRACE(("LOCK-FAIL file=%p, count=%d, rc=%s\n", - pFile->h, cnt, tdsqlite3ErrName(rc))); + pFile->h, cnt, sqlite3ErrName(rc))); return rc; } - if( cnt ) tdsqlite3_win32_sleep(1); + if( cnt ) sqlite3_win32_sleep(1); } gotPendingLock = res; if( !res ){ @@ -49063,7 +49063,7 @@ static int winLock(tdsqlite3_file *id, int locktype){ } pFile->locktype = (u8)newLocktype; OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", - pFile->h, pFile->locktype, tdsqlite3ErrName(rc))); + pFile->h, pFile->locktype, sqlite3ErrName(rc))); return rc; } @@ -49072,7 +49072,7 @@ static int winLock(tdsqlite3_file *id, int locktype){ ** file by this or any other process. If such a lock is held, return ** non-zero, otherwise zero. */ -static int winCheckReservedLock(tdsqlite3_file *id, int *pResOut){ +static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ int res; winFile *pFile = (winFile*)id; @@ -49108,7 +49108,7 @@ static int winCheckReservedLock(tdsqlite3_file *id, int *pResOut){ ** is NO_LOCK. If the second argument is SHARED_LOCK then this routine ** might return SQLITE_IOERR; */ -static int winUnlock(tdsqlite3_file *id, int locktype){ +static int winUnlock(sqlite3_file *id, int locktype){ int type; winFile *pFile = (winFile*)id; int rc = SQLITE_OK; @@ -49137,7 +49137,7 @@ static int winUnlock(tdsqlite3_file *id, int locktype){ } pFile->locktype = (u8)locktype; OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", - pFile->h, pFile->locktype, tdsqlite3ErrName(rc))); + pFile->h, pFile->locktype, sqlite3ErrName(rc))); return rc; } @@ -49158,19 +49158,19 @@ static int winUnlock(tdsqlite3_file *id, int locktype){ ** time and one or more of those connections are writing. */ -static int winNolockLock(tdsqlite3_file *id, int locktype){ +static int winNolockLock(sqlite3_file *id, int locktype){ UNUSED_PARAMETER(id); UNUSED_PARAMETER(locktype); return SQLITE_OK; } -static int winNolockCheckReservedLock(tdsqlite3_file *id, int *pResOut){ +static int winNolockCheckReservedLock(sqlite3_file *id, int *pResOut){ UNUSED_PARAMETER(id); UNUSED_PARAMETER(pResOut); return SQLITE_OK; } -static int winNolockUnlock(tdsqlite3_file *id, int locktype){ +static int winNolockUnlock(sqlite3_file *id, int locktype){ UNUSED_PARAMETER(id); UNUSED_PARAMETER(locktype); return SQLITE_OK; @@ -49196,14 +49196,14 @@ static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){ } /* Forward references to VFS helper methods used for temporary files */ -static int winGetTempname(tdsqlite3_vfs *, char **); +static int winGetTempname(sqlite3_vfs *, char **); static int winIsDir(const void *); static BOOL winIsDriveLetterAndColon(const char *); /* ** Control and query of the open file handle. */ -static int winFileControl(tdsqlite3_file *id, int op, void *pArg){ +static int winFileControl(sqlite3_file *id, int op, void *pArg){ winFile *pFile = (winFile*)id; OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); switch( op ){ @@ -49224,17 +49224,17 @@ static int winFileControl(tdsqlite3_file *id, int op, void *pArg){ } case SQLITE_FCNTL_SIZE_HINT: { if( pFile->szChunk>0 ){ - tdsqlite3_int64 oldSz; + sqlite3_int64 oldSz; int rc = winFileSize(id, &oldSz); if( rc==SQLITE_OK ){ - tdsqlite3_int64 newSz = *(tdsqlite3_int64*)pArg; + sqlite3_int64 newSz = *(sqlite3_int64*)pArg; if( newSz>oldSz ){ SimulateIOErrorBenign(1); rc = winTruncate(id, newSz); SimulateIOErrorBenign(0); } } - OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, tdsqlite3ErrName(rc))); + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); return rc; } OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); @@ -49251,7 +49251,7 @@ static int winFileControl(tdsqlite3_file *id, int op, void *pArg){ return SQLITE_OK; } case SQLITE_FCNTL_VFSNAME: { - *(char**)pArg = tdsqlite3_mprintf("%s", pFile->pVfs->zName); + *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName); OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); return SQLITE_OK; } @@ -49293,15 +49293,15 @@ static int winFileControl(tdsqlite3_file *id, int op, void *pArg){ if( rc==SQLITE_OK ){ *(char**)pArg = zTFile; } - OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, tdsqlite3ErrName(rc))); + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); return rc; } #if SQLITE_MAX_MMAP_SIZE>0 case SQLITE_FCNTL_MMAP_SIZE: { i64 newLimit = *(i64*)pArg; int rc = SQLITE_OK; - if( newLimit>tdsqlite3GlobalConfig.mxMmap ){ - newLimit = tdsqlite3GlobalConfig.mxMmap; + if( newLimit>sqlite3GlobalConfig.mxMmap ){ + newLimit = sqlite3GlobalConfig.mxMmap; } /* The value of newLimit may be eventually cast to (SIZE_T) and passed @@ -49319,7 +49319,7 @@ static int winFileControl(tdsqlite3_file *id, int op, void *pArg){ rc = winMapfile(pFile, -1); } } - OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, tdsqlite3ErrName(rc))); + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); return rc; } #endif @@ -49338,7 +49338,7 @@ static int winFileControl(tdsqlite3_file *id, int op, void *pArg){ ** a database and its journal file) that the sector size will be the ** same for both. */ -static int winSectorSize(tdsqlite3_file *id){ +static int winSectorSize(sqlite3_file *id){ (void)id; return SQLITE_DEFAULT_SECTOR_SIZE; } @@ -49346,7 +49346,7 @@ static int winSectorSize(tdsqlite3_file *id){ /* ** Return a vector of device characteristics. */ -static int winDeviceCharacteristics(tdsqlite3_file *id){ +static int winDeviceCharacteristics(sqlite3_file *id){ winFile *p = (winFile*)id; return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN | ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0); @@ -49355,7 +49355,7 @@ static int winDeviceCharacteristics(tdsqlite3_file *id){ /* ** Windows will only let you create file view mappings ** on allocation size granularity boundaries. -** During tdsqlite3_os_init() we do a GetSystemInfo() +** During sqlite3_os_init() we do a GetSystemInfo() ** to get the granularity size. */ static SYSTEM_INFO winSysInfo; @@ -49375,16 +49375,16 @@ static SYSTEM_INFO winSysInfo; ** assert( winShmMutexHeld() ); ** winShmLeaveMutex() */ -static tdsqlite3_mutex *winBigLock = 0; +static sqlite3_mutex *winBigLock = 0; static void winShmEnterMutex(void){ - tdsqlite3_mutex_enter(winBigLock); + sqlite3_mutex_enter(winBigLock); } static void winShmLeaveMutex(void){ - tdsqlite3_mutex_leave(winBigLock); + sqlite3_mutex_leave(winBigLock); } #ifndef NDEBUG static int winShmMutexHeld(void) { - return tdsqlite3_mutex_held(winBigLock); + return sqlite3_mutex_held(winBigLock); } #endif @@ -49412,7 +49412,7 @@ static int winShmMutexHeld(void) { ** */ struct winShmNode { - tdsqlite3_mutex *mutex; /* Mutex to access this object */ + sqlite3_mutex *mutex; /* Mutex to access this object */ char *zFilename; /* Name of the file */ winFile hFile; /* File handle from winOpen */ @@ -49487,7 +49487,7 @@ static int winShmSystemLock( int rc = 0; /* Result code form Lock/UnlockFileEx() */ /* Access to the winShmNode object is serialized by the caller */ - assert( pFile->nRef==0 || tdsqlite3_mutex_held(pFile->mutex) ); + assert( pFile->nRef==0 || sqlite3_mutex_held(pFile->mutex) ); OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", pFile->hFile.h, lockType, ofst, nByte)); @@ -49511,14 +49511,14 @@ static int winShmSystemLock( OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", pFile->hFile.h, (lockType == WINSHM_UNLCK) ? "winUnlockFile" : - "winLockFile", pFile->lastErrno, tdsqlite3ErrName(rc))); + "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); return rc; } /* Forward references to VFS methods */ -static int winOpen(tdsqlite3_vfs*,const char*,tdsqlite3_file*,int,int*); -static int winDelete(tdsqlite3_vfs *,const char*,int); +static int winOpen(sqlite3_vfs*,const char*,sqlite3_file*,int,int*); +static int winDelete(sqlite3_vfs *,const char*,int); /* ** Purge the winShmNodeList list of all entries with winShmNode.nRef==0. @@ -49526,7 +49526,7 @@ static int winDelete(tdsqlite3_vfs *,const char*,int); ** This is not a VFS shared-memory method; it is a utility function called ** by VFS shared-memory methods. */ -static void winShmPurge(tdsqlite3_vfs *pVfs, int deleteFlag){ +static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ winShmNode **pp; winShmNode *p; assert( winShmMutexHeld() ); @@ -49536,7 +49536,7 @@ static void winShmPurge(tdsqlite3_vfs *pVfs, int deleteFlag){ while( (p = *pp)!=0 ){ if( p->nRef==0 ){ int i; - if( p->mutex ){ tdsqlite3_mutex_free(p->mutex); } + if( p->mutex ){ sqlite3_mutex_free(p->mutex); } for(i=0; inRegion; i++){ BOOL bRc = osUnmapViewOfFile(p->aRegion[i].pMap); OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", @@ -49549,19 +49549,19 @@ static void winShmPurge(tdsqlite3_vfs *pVfs, int deleteFlag){ } if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ SimulateIOErrorBenign(1); - winClose((tdsqlite3_file *)&p->hFile); + winClose((sqlite3_file *)&p->hFile); SimulateIOErrorBenign(0); } if( deleteFlag ){ SimulateIOErrorBenign(1); - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); winDelete(pVfs, p->zFilename, 0); - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); SimulateIOErrorBenign(0); } *pp = p->pNext; - tdsqlite3_free(p->aRegion); - tdsqlite3_free(p); + sqlite3_free(p->aRegion); + sqlite3_free(p); }else{ pp = &p->pNext; } @@ -49585,7 +49585,7 @@ static int winLockSharedMemory(winShmNode *pShmNode){ pShmNode->isUnlocked = 1; winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); return SQLITE_READONLY_CANTINIT; - }else if( winTruncate((tdsqlite3_file*)&pShmNode->hFile, 0) ){ + }else if( winTruncate((sqlite3_file*)&pShmNode->hFile, 0) ){ winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); return winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), "winLockSharedMemory", pShmNode->zFilename); @@ -49615,20 +49615,20 @@ static int winOpenSharedMemory(winFile *pDbFd){ assert( pDbFd->pShm==0 ); /* Not previously opened */ - /* Allocate space for the new tdsqlite3_shm object. Also speculatively + /* Allocate space for the new sqlite3_shm object. Also speculatively ** allocate space for a new winShmNode and filename. */ - p = tdsqlite3MallocZero( sizeof(*p) ); + p = sqlite3MallocZero( sizeof(*p) ); if( p==0 ) return SQLITE_IOERR_NOMEM_BKPT; - nName = tdsqlite3Strlen30(pDbFd->zPath); - pNew = tdsqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); + nName = sqlite3Strlen30(pDbFd->zPath); + pNew = sqlite3MallocZero( sizeof(*pShmNode) + nName + 17 ); if( pNew==0 ){ - tdsqlite3_free(p); + sqlite3_free(p); return SQLITE_IOERR_NOMEM_BKPT; } pNew->zFilename = (char*)&pNew[1]; - tdsqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); - tdsqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); + sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); + sqlite3FileSuffix3(pDbFd->zPath, pNew->zFilename); /* Look to see if there is an existing winShmNode that can be used. ** If no matching winShmNode currently exists, create a new one. @@ -49638,10 +49638,10 @@ static int winOpenSharedMemory(winFile *pDbFd){ /* TBD need to come up with better match here. Perhaps ** use FILE_ID_BOTH_DIR_INFO Structure. */ - if( tdsqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; + if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break; } if( pShmNode ){ - tdsqlite3_free(pNew); + sqlite3_free(pNew); }else{ int inFlags = SQLITE_OPEN_WAL; int outFlags = 0; @@ -49652,21 +49652,21 @@ static int winOpenSharedMemory(winFile *pDbFd){ pShmNode->pNext = winShmNodeList; winShmNodeList = pShmNode; - if( tdsqlite3GlobalConfig.bCoreMutex ){ - pShmNode->mutex = tdsqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + if( sqlite3GlobalConfig.bCoreMutex ){ + pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); if( pShmNode->mutex==0 ){ rc = SQLITE_IOERR_NOMEM_BKPT; goto shm_open_err; } } - if( 0==tdsqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ + if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){ inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; }else{ inFlags |= SQLITE_OPEN_READONLY; } rc = winOpen(pDbFd->pVfs, pShmNode->zFilename, - (tdsqlite3_file*)&pShmNode->hFile, + (sqlite3_file*)&pShmNode->hFile, inFlags, &outFlags); if( rc!=SQLITE_OK ){ rc = winLogError(rc, osGetLastError(), "winOpenShm", @@ -49695,18 +49695,18 @@ static int winOpenSharedMemory(winFile *pDbFd){ ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex ** mutex. */ - tdsqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->mutex); p->pNext = pShmNode->pFirst; pShmNode->pFirst = p; - tdsqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->mutex); return rc; /* Jump here on any error */ shm_open_err: winShmSystemLock(pShmNode, WINSHM_UNLCK, WIN_SHM_DMS, 1); winShmPurge(pDbFd->pVfs, 0); /* This call frees pShmNode if required */ - tdsqlite3_free(p); - tdsqlite3_free(pNew); + sqlite3_free(p); + sqlite3_free(pNew); winShmLeaveMutex(); return rc; } @@ -49716,7 +49716,7 @@ shm_open_err: ** storage if deleteFlag is true. */ static int winShmUnmap( - tdsqlite3_file *fd, /* Database holding shared memory */ + sqlite3_file *fd, /* Database holding shared memory */ int deleteFlag /* Delete after closing if true */ ){ winFile *pDbFd; /* Database holding shared-memory */ @@ -49731,14 +49731,14 @@ static int winShmUnmap( /* Remove connection p from the set of connections associated ** with pShmNode */ - tdsqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->mutex); for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} *pp = p->pNext; /* Free the connection p */ - tdsqlite3_free(p); + sqlite3_free(p); pDbFd->pShm = 0; - tdsqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->mutex); /* If pShmNode->nRef has reached 0, then close the underlying ** shared-memory file, too */ @@ -49757,7 +49757,7 @@ static int winShmUnmap( ** Change the lock state for a shared-memory segment. */ static int winShmLock( - tdsqlite3_file *fd, /* Database file holding the shared memory */ + sqlite3_file *fd, /* Database file holding the shared memory */ int ofst, /* First lock to acquire or release */ int n, /* Number of locks to acquire or release */ int flags /* What to do with the lock */ @@ -49779,7 +49779,7 @@ static int winShmLock( mask = (u16)((1U<<(ofst+n)) - (1U<1 || mask==(1<mutex); + sqlite3_mutex_enter(pShmNode->mutex); if( flags & SQLITE_SHM_UNLOCK ){ u16 allMask = 0; /* Mask of locks held by siblings */ @@ -49852,10 +49852,10 @@ static int winShmLock( } } } - tdsqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->mutex); OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, - tdsqlite3ErrName(rc))); + sqlite3ErrName(rc))); return rc; } @@ -49866,10 +49866,10 @@ static int winShmLock( ** any load or store begun after the barrier. */ static void winShmBarrier( - tdsqlite3_file *fd /* Database holding the shared memory */ + sqlite3_file *fd /* Database holding the shared memory */ ){ UNUSED_PARAMETER(fd); - tdsqlite3MemoryBarrier(); /* compiler-defined memory barrier */ + sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ winShmEnterMutex(); /* Also mutex, for redundancy */ winShmLeaveMutex(); } @@ -49894,7 +49894,7 @@ static void winShmBarrier( ** memory and SQLITE_OK returned. */ static int winShmMap( - tdsqlite3_file *fd, /* Handle open on database file */ + sqlite3_file *fd, /* Handle open on database file */ int iRegion, /* Region to retrieve */ int szRegion, /* Size of regions */ int isWrite, /* True to extend file if necessary */ @@ -49915,7 +49915,7 @@ static int winShmMap( } pShmNode = pShm->pShmNode; - tdsqlite3_mutex_enter(pShmNode->mutex); + sqlite3_mutex_enter(pShmNode->mutex); if( pShmNode->isUnlocked ){ rc = winLockSharedMemory(pShmNode); if( rc!=SQLITE_OK ) goto shmpage_out; @@ -49926,7 +49926,7 @@ static int winShmMap( if( pShmNode->nRegion<=iRegion ){ struct ShmRegion *apNew; /* New aRegion[] array */ int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ - tdsqlite3_int64 sz; /* Current size of wal-index file */ + sqlite3_int64 sz; /* Current size of wal-index file */ pShmNode->szRegion = szRegion; @@ -49934,7 +49934,7 @@ static int winShmMap( ** Check to see if it has been allocated (i.e. if the wal-index file is ** large enough to contain the requested region). */ - rc = winFileSize((tdsqlite3_file *)&pShmNode->hFile, &sz); + rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); if( rc!=SQLITE_OK ){ rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), "winShmMap1", pDbFd->zPath); @@ -49949,7 +49949,7 @@ static int winShmMap( ** the requested memory region. */ if( !isWrite ) goto shmpage_out; - rc = winTruncate((tdsqlite3_file *)&pShmNode->hFile, nByte); + rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); if( rc!=SQLITE_OK ){ rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), "winShmMap2", pDbFd->zPath); @@ -49958,7 +49958,7 @@ static int winShmMap( } /* Map the requested memory region into this processes address space. */ - apNew = (struct ShmRegion *)tdsqlite3_realloc64( + apNew = (struct ShmRegion *)sqlite3_realloc64( pShmNode->aRegion, (iRegion+1)*sizeof(apNew[0]) ); if( !apNew ){ @@ -50032,7 +50032,7 @@ shmpage_out: *pp = 0; } if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; - tdsqlite3_mutex_leave(pShmNode->mutex); + sqlite3_mutex_leave(pShmNode->mutex); return rc; } @@ -50096,8 +50096,8 @@ static int winUnmapfile(winFile *pFile){ ** recreated as a result of outstanding references) or an SQLite error ** code otherwise. */ -static int winMapfile(winFile *pFd, tdsqlite3_int64 nByte){ - tdsqlite3_int64 nMap = nByte; +static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ + sqlite3_int64 nMap = nByte; int rc; assert( nMap>=0 || pFd->nFetchOut==0 ); @@ -50107,7 +50107,7 @@ static int winMapfile(winFile *pFd, tdsqlite3_int64 nByte){ if( pFd->nFetchOut>0 ) return SQLITE_OK; if( nMap<0 ){ - rc = winFileSize((tdsqlite3_file*)pFd, &nMap); + rc = winFileSize((sqlite3_file*)pFd, &nMap); if( rc ){ OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", osGetCurrentProcessId(), pFd)); @@ -50117,7 +50117,7 @@ static int winMapfile(winFile *pFd, tdsqlite3_int64 nByte){ if( nMap>pFd->mmapSizeMax ){ nMap = pFd->mmapSizeMax; } - nMap &= ~(tdsqlite3_int64)(winSysInfo.dwPageSize - 1); + nMap &= ~(sqlite3_int64)(winSysInfo.dwPageSize - 1); if( nMap==0 && pFd->mmapSize>0 ){ winUnmapfile(pFd); @@ -50151,11 +50151,11 @@ static int winMapfile(winFile *pFd, tdsqlite3_int64 nByte){ "winMapfile1", pFd->zPath); /* Log the error, but continue normal operation using xRead/xWrite */ OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", - osGetCurrentProcessId(), pFd, tdsqlite3ErrName(rc))); + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); return SQLITE_OK; } assert( (nMap % winSysInfo.dwPageSize)==0 ); - assert( sizeof(SIZE_T)==sizeof(tdsqlite3_int64) || nMap<=0xffffffff ); + assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); #if SQLITE_OS_WINRT pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, (SIZE_T)nMap); #else @@ -50169,7 +50169,7 @@ static int winMapfile(winFile *pFd, tdsqlite3_int64 nByte){ "winMapfile2", pFd->zPath); /* Log the error, but continue normal operation using xRead/xWrite */ OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", - osGetCurrentProcessId(), pFd, tdsqlite3ErrName(rc))); + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); return SQLITE_OK; } pFd->pMapRegion = pNew; @@ -50194,7 +50194,7 @@ static int winMapfile(winFile *pFd, tdsqlite3_int64 nByte){ ** If this function does return a pointer, the caller must eventually ** release the reference by calling winUnfetch(). */ -static int winFetch(tdsqlite3_file *fd, i64 iOff, int nAmt, void **pp){ +static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ #if SQLITE_MAX_MMAP_SIZE>0 winFile *pFd = (winFile*)fd; /* The underlying database file */ #endif @@ -50209,7 +50209,7 @@ static int winFetch(tdsqlite3_file *fd, i64 iOff, int nAmt, void **pp){ int rc = winMapfile(pFd, -1); if( rc!=SQLITE_OK ){ OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", - osGetCurrentProcessId(), pFd, tdsqlite3ErrName(rc))); + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); return rc; } } @@ -50236,7 +50236,7 @@ static int winFetch(tdsqlite3_file *fd, i64 iOff, int nAmt, void **pp){ ** to inform the VFS layer that, according to POSIX, any existing mapping ** may now be invalid and should be unmapped. */ -static int winUnfetch(tdsqlite3_file *fd, i64 iOff, void *p){ +static int winUnfetch(sqlite3_file *fd, i64 iOff, void *p){ #if SQLITE_MAX_MMAP_SIZE>0 winFile *pFd = (winFile*)fd; /* The underlying database file */ @@ -50270,16 +50270,16 @@ static int winUnfetch(tdsqlite3_file *fd, i64 iOff, void *p){ } /* -** Here ends the implementation of all tdsqlite3_file methods. +** Here ends the implementation of all sqlite3_file methods. ** -********************** End tdsqlite3_file Methods ******************************* +********************** End sqlite3_file Methods ******************************* ******************************************************************************/ /* ** This vector defines all the methods that can operate on an -** tdsqlite3_file for win32. +** sqlite3_file for win32. */ -static const tdsqlite3_io_methods winIoMethod = { +static const sqlite3_io_methods winIoMethod = { 3, /* iVersion */ winClose, /* xClose */ winRead, /* xRead */ @@ -50303,9 +50303,9 @@ static const tdsqlite3_io_methods winIoMethod = { /* ** This vector defines all the methods that can operate on an -** tdsqlite3_file for win32 without performing any locking. +** sqlite3_file for win32 without performing any locking. */ -static const tdsqlite3_io_methods winIoNolockMethod = { +static const sqlite3_io_methods winIoNolockMethod = { 3, /* iVersion */ winClose, /* xClose */ winRead, /* xRead */ @@ -50340,10 +50340,10 @@ static winVfsAppData winNolockAppData = { }; /**************************************************************************** -**************************** tdsqlite3_vfs methods **************************** +**************************** sqlite3_vfs methods **************************** ** ** This division contains the implementation of methods on the -** tdsqlite3_vfs object. +** sqlite3_vfs object. */ #if defined(__CYGWIN__) @@ -50394,7 +50394,7 @@ static void *winConvertFromUtf8Filename(const char *zFilename){ */ static int winMakeEndInDirSep(int nBuf, char *zBuf){ if( zBuf ){ - int nLen = tdsqlite3Strlen30(zBuf); + int nLen = sqlite3Strlen30(zBuf); if( nLen>0 ){ if( winIsDirSep(zBuf[nLen-1]) ){ return 1; @@ -50410,15 +50410,15 @@ static int winMakeEndInDirSep(int nBuf, char *zBuf){ /* ** Create a temporary file name and store the resulting pointer into pzBuf. -** The pointer returned in pzBuf must be freed via tdsqlite3_free(). +** The pointer returned in pzBuf must be freed via sqlite3_free(). */ -static int winGetTempname(tdsqlite3_vfs *pVfs, char **pzBuf){ +static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ static char zChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; size_t i, j; - int nPre = tdsqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); + int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); int nMax, nBuf, nDir, nLen; char *zBuf; @@ -50432,7 +50432,7 @@ static int winGetTempname(tdsqlite3_vfs *pVfs, char **pzBuf){ ** name for the temporary file. If this fails, we cannot continue. */ nMax = pVfs->mxPathname; nBuf = nMax + 2; - zBuf = tdsqlite3MallocZero( nBuf ); + zBuf = sqlite3MallocZero( nBuf ); if( !zBuf ){ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; @@ -50444,18 +50444,18 @@ static int winGetTempname(tdsqlite3_vfs *pVfs, char **pzBuf){ */ nDir = nMax - (nPre + 15); assert( nDir>0 ); - if( tdsqlite3_temp_directory ){ - int nDirLen = tdsqlite3Strlen30(tdsqlite3_temp_directory); + if( sqlite3_temp_directory ){ + int nDirLen = sqlite3Strlen30(sqlite3_temp_directory); if( nDirLen>0 ){ - if( !winIsDirSep(tdsqlite3_temp_directory[nDirLen-1]) ){ + if( !winIsDirSep(sqlite3_temp_directory[nDirLen-1]) ){ nDirLen++; } if( nDirLen>nDir ){ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); return winLogError(SQLITE_ERROR, 0, "winGetTempname1", 0); } - tdsqlite3_snprintf(nMax, zBuf, "%s", tdsqlite3_temp_directory); + sqlite3_snprintf(nMax, zBuf, "%s", sqlite3_temp_directory); } } #if defined(__CYGWIN__) @@ -50491,28 +50491,28 @@ static int winGetTempname(tdsqlite3_vfs *pVfs, char **pzBuf){ if( winIsDriveLetterAndColon(zDir) ){ zConverted = winConvertFromUtf8Filename(zDir); if( !zConverted ){ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } if( winIsDir(zConverted) ){ - tdsqlite3_snprintf(nMax, zBuf, "%s", zDir); - tdsqlite3_free(zConverted); + sqlite3_snprintf(nMax, zBuf, "%s", zDir); + sqlite3_free(zConverted); break; } - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); }else{ - zConverted = tdsqlite3MallocZero( nMax+1 ); + zConverted = sqlite3MallocZero( nMax+1 ); if( !zConverted ){ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } if( cygwin_conv_path( osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, zConverted, nMax+1)<0 ){ - tdsqlite3_free(zConverted); - tdsqlite3_free(zBuf); + sqlite3_free(zConverted); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, "winGetTempname2", zDir); @@ -50524,44 +50524,44 @@ static int winGetTempname(tdsqlite3_vfs *pVfs, char **pzBuf){ */ char *zUtf8 = winConvertToUtf8Filename(zConverted); if( !zUtf8 ){ - tdsqlite3_free(zConverted); - tdsqlite3_free(zBuf); + sqlite3_free(zConverted); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } - tdsqlite3_snprintf(nMax, zBuf, "%s", zUtf8); - tdsqlite3_free(zUtf8); - tdsqlite3_free(zConverted); + sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zConverted); break; } - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); } } } #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) else if( osIsNT() ){ char *zMulti; - LPWSTR zWidePath = tdsqlite3MallocZero( nMax*sizeof(WCHAR) ); + LPWSTR zWidePath = sqlite3MallocZero( nMax*sizeof(WCHAR) ); if( !zWidePath ){ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } if( osGetTempPathW(nMax, zWidePath)==0 ){ - tdsqlite3_free(zWidePath); - tdsqlite3_free(zBuf); + sqlite3_free(zWidePath); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), "winGetTempname2", 0); } zMulti = winUnicodeToUtf8(zWidePath); if( zMulti ){ - tdsqlite3_snprintf(nMax, zBuf, "%s", zMulti); - tdsqlite3_free(zMulti); - tdsqlite3_free(zWidePath); + sqlite3_snprintf(nMax, zBuf, "%s", zMulti); + sqlite3_free(zMulti); + sqlite3_free(zWidePath); }else{ - tdsqlite3_free(zWidePath); - tdsqlite3_free(zBuf); + sqlite3_free(zWidePath); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } @@ -50569,24 +50569,24 @@ static int winGetTempname(tdsqlite3_vfs *pVfs, char **pzBuf){ #ifdef SQLITE_WIN32_HAS_ANSI else{ char *zUtf8; - char *zMbcsPath = tdsqlite3MallocZero( nMax ); + char *zMbcsPath = sqlite3MallocZero( nMax ); if( !zMbcsPath ){ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } if( osGetTempPathA(nMax, zMbcsPath)==0 ){ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), "winGetTempname3", 0); } zUtf8 = winMbcsToUtf8(zMbcsPath, osAreFileApisANSI()); if( zUtf8 ){ - tdsqlite3_snprintf(nMax, zBuf, "%s", zUtf8); - tdsqlite3_free(zUtf8); + sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); + sqlite3_free(zUtf8); }else{ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); return SQLITE_IOERR_NOMEM_BKPT; } @@ -50600,7 +50600,7 @@ static int winGetTempname(tdsqlite3_vfs *pVfs, char **pzBuf){ ** one, fail. */ if( !winMakeEndInDirSep(nDir+1, zBuf) ){ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); return winLogError(SQLITE_ERROR, 0, "winGetTempname4", 0); } @@ -50616,17 +50616,17 @@ static int winGetTempname(tdsqlite3_vfs *pVfs, char **pzBuf){ ** two trailing NUL characters. The final directory separator character ** has already added if it was not already present. */ - nLen = tdsqlite3Strlen30(zBuf); + nLen = sqlite3Strlen30(zBuf); if( (nLen + nPre + 17) > nBuf ){ - tdsqlite3_free(zBuf); + sqlite3_free(zBuf); OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); return winLogError(SQLITE_ERROR, 0, "winGetTempname5", 0); } - tdsqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); + sqlite3_snprintf(nBuf-16-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); - j = tdsqlite3Strlen30(zBuf); - tdsqlite3_randomness(15, &zBuf[j]); + j = sqlite3Strlen30(zBuf); + sqlite3_randomness(15, &zBuf[j]); for(i=0; i<15; i++, j++){ zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } @@ -50669,7 +50669,7 @@ static int winIsDir(const void *zConverted){ /* forward reference */ static int winAccess( - tdsqlite3_vfs *pVfs, /* Not used on win32 */ + sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ @@ -50679,9 +50679,9 @@ static int winAccess( ** Open a file. */ static int winOpen( - tdsqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ + sqlite3_vfs *pVfs, /* Used to get maximum path length and AppData */ const char *zName, /* Name of the file (UTF-8) */ - tdsqlite3_file *id, /* Write the SQLite file handle here */ + sqlite3_file *id, /* Write the SQLite file handle here */ int flags, /* Open mode flags */ int *pOutFlags /* Status return flags */ ){ @@ -50758,9 +50758,9 @@ static int winOpen( pFile->h = INVALID_HANDLE_VALUE; #if SQLITE_OS_WINRT - if( !zUtf8Name && !tdsqlite3_temp_directory ){ - tdsqlite3_log(SQLITE_ERROR, - "tdsqlite3_temp_directory variable should be set for WinRT"); + if( !zUtf8Name && !sqlite3_temp_directory ){ + sqlite3_log(SQLITE_ERROR, + "sqlite3_temp_directory variable should be set for WinRT"); } #endif @@ -50771,7 +50771,7 @@ static int winOpen( assert( isDelete && !isOpenJournal ); rc = winGetTempname(pVfs, &zTmpname); if( rc!=SQLITE_OK ){ - OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, tdsqlite3ErrName(rc))); + OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); return rc; } zUtf8Name = zTmpname; @@ -50779,22 +50779,22 @@ static int winOpen( /* Database filenames are double-zero terminated if they are not ** URIs with parameters. Hence, they can always be passed into - ** tdsqlite3_uri_parameter(). + ** sqlite3_uri_parameter(). */ assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || - zUtf8Name[tdsqlite3Strlen30(zUtf8Name)+1]==0 ); + zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); /* Convert the filename to the system encoding. */ zConverted = winConvertFromUtf8Filename(zUtf8Name); if( zConverted==0 ){ - tdsqlite3_free(zTmpname); + sqlite3_free(zTmpname); OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); return SQLITE_IOERR_NOMEM_BKPT; } if( winIsDir(zConverted) ){ - tdsqlite3_free(zConverted); - tdsqlite3_free(zTmpname); + sqlite3_free(zConverted); + sqlite3_free(zTmpname); OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); return SQLITE_CANTOPEN_ISDIR; } @@ -50863,9 +50863,9 @@ static int winOpen( if( h!=INVALID_HANDLE_VALUE ) break; if( isReadWrite ){ int rc2, isRO = 0; - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } }while( winRetryIoerr(&cnt, &lastErrno) ); @@ -50880,9 +50880,9 @@ static int winOpen( if( h!=INVALID_HANDLE_VALUE ) break; if( isReadWrite ){ int rc2, isRO = 0; - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } }while( winRetryIoerr(&cnt, &lastErrno) ); @@ -50900,9 +50900,9 @@ static int winOpen( if( h!=INVALID_HANDLE_VALUE ) break; if( isReadWrite ){ int rc2, isRO = 0; - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO); - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); if( rc2==SQLITE_OK && isRO ) break; } }while( winRetryIoerr(&cnt, &lastErrno) ); @@ -50914,8 +50914,8 @@ static int winOpen( dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); if( h==INVALID_HANDLE_VALUE ){ - tdsqlite3_free(zConverted); - tdsqlite3_free(zTmpname); + sqlite3_free(zConverted); + sqlite3_free(zTmpname); if( isReadWrite && !isExclusive ){ return winOpen(pVfs, zName, id, ((flags|SQLITE_OPEN_READONLY) & @@ -50949,9 +50949,9 @@ static int winOpen( && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK ){ osCloseHandle(h); - tdsqlite3_free(zConverted); - tdsqlite3_free(zTmpname); - OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, tdsqlite3ErrName(rc))); + sqlite3_free(zConverted); + sqlite3_free(zTmpname); + OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); return rc; } } @@ -50960,17 +50960,17 @@ static int winOpen( }else #endif { - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); } - tdsqlite3_free(zTmpname); + sqlite3_free(zTmpname); pFile->pMethod = pAppData ? pAppData->pMethod : &winIoMethod; pFile->pVfs = pVfs; pFile->h = h; if( isReadonly ){ pFile->ctrlFlags |= WINFILE_RDONLY; } - if( tdsqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ + if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){ pFile->ctrlFlags |= WINFILE_PSOW; } pFile->lastErrno = NO_ERROR; @@ -50979,7 +50979,7 @@ static int winOpen( pFile->hMap = NULL; pFile->pMapRegion = 0; pFile->mmapSize = 0; - pFile->mmapSizeMax = tdsqlite3GlobalConfig.szMmap; + pFile->mmapSizeMax = sqlite3GlobalConfig.szMmap; #endif OpenCounter(+1); @@ -50999,7 +50999,7 @@ static int winOpen( ** up and returning an error. */ static int winDelete( - tdsqlite3_vfs *pVfs, /* Not used on win32 */ + sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to delete */ int syncDir /* Not used on win32 */ ){ @@ -51098,8 +51098,8 @@ static int winDelete( }else{ winLogIoerr(cnt, __LINE__); } - tdsqlite3_free(zConverted); - OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, tdsqlite3ErrName(rc))); + sqlite3_free(zConverted); + OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); return rc; } @@ -51107,7 +51107,7 @@ static int winDelete( ** Check the existence and status of a file. */ static int winAccess( - tdsqlite3_vfs *pVfs, /* Not used on win32 */ + sqlite3_vfs *pVfs, /* Not used on win32 */ const char *zFilename, /* Name of file to check */ int flags, /* Type of test to make on this file */ int *pResOut /* OUT: Result */ @@ -51148,7 +51148,7 @@ static int winAccess( }else{ winLogIoerr(cnt, __LINE__); if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); }else{ @@ -51161,7 +51161,7 @@ static int winAccess( attr = osGetFileAttributesA((char*)zConverted); } #endif - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); switch( flags ){ case SQLITE_ACCESS_READ: case SQLITE_ACCESS_EXISTS: @@ -51187,7 +51187,7 @@ static int winAccess( static BOOL winIsDriveLetterAndColon( const char *zPathname ){ - return ( tdsqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); + return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); } /* @@ -51233,7 +51233,7 @@ static BOOL winIsVerbatimPathname( ** bytes in size. */ static int winFullPathname( - tdsqlite3_vfs *pVfs, /* Pointer to vfs object */ + sqlite3_vfs *pVfs, /* Pointer to vfs object */ const char *zRelative, /* Possibly relative input path */ int nFull, /* Size of output buffer in bytes */ char *zFull /* Output buffer */ @@ -51255,54 +51255,54 @@ static int winFullPathname( SimulateIOError( return SQLITE_ERROR ); UNUSED_PARAMETER(nFull); assert( nFull>=pVfs->mxPathname ); - if ( tdsqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data ** directory has been set. Therefore, use it as the basis ** for converting the relative path name to an absolute ** one by prepending the data directory and a slash. */ - char *zOut = tdsqlite3MallocZero( pVfs->mxPathname+1 ); + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); if( !zOut ){ return SQLITE_IOERR_NOMEM_BKPT; } if( cygwin_conv_path( (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ - tdsqlite3_free(zOut); + sqlite3_free(zOut); return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, "winFullPathname1", zRelative); }else{ char *zUtf8 = winConvertToUtf8Filename(zOut); if( !zUtf8 ){ - tdsqlite3_free(zOut); + sqlite3_free(zOut); return SQLITE_IOERR_NOMEM_BKPT; } - tdsqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", - tdsqlite3_data_directory, winGetDirSep(), zUtf8); - tdsqlite3_free(zUtf8); - tdsqlite3_free(zOut); + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); } }else{ - char *zOut = tdsqlite3MallocZero( pVfs->mxPathname+1 ); + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); if( !zOut ){ return SQLITE_IOERR_NOMEM_BKPT; } if( cygwin_conv_path( (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), zRelative, zOut, pVfs->mxPathname+1)<0 ){ - tdsqlite3_free(zOut); + sqlite3_free(zOut); return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, "winFullPathname2", zRelative); }else{ char *zUtf8 = winConvertToUtf8Filename(zOut); if( !zUtf8 ){ - tdsqlite3_free(zOut); + sqlite3_free(zOut); return SQLITE_IOERR_NOMEM_BKPT; } - tdsqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); - tdsqlite3_free(zUtf8); - tdsqlite3_free(zOut); + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); + sqlite3_free(zUtf8); + sqlite3_free(zOut); } } return SQLITE_OK; @@ -51312,17 +51312,17 @@ static int winFullPathname( SimulateIOError( return SQLITE_ERROR ); /* WinCE has no concept of a relative pathname, or so I am told. */ /* WinRT has no way to convert a relative path to an absolute one. */ - if ( tdsqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data ** directory has been set. Therefore, use it as the basis ** for converting the relative path name to an absolute ** one by prepending the data directory and a backslash. */ - tdsqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", - tdsqlite3_data_directory, winGetDirSep(), zRelative); + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zRelative); }else{ - tdsqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); } return SQLITE_OK; #endif @@ -51334,15 +51334,15 @@ static int winFullPathname( ** current working directory has been unlinked. */ SimulateIOError( return SQLITE_ERROR ); - if ( tdsqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ + if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ /* ** NOTE: We are dealing with a relative path name and the data ** directory has been set. Therefore, use it as the basis ** for converting the relative path name to an absolute ** one by prepending the data directory and a backslash. */ - tdsqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", - tdsqlite3_data_directory, winGetDirSep(), zRelative); + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", + sqlite3_data_directory, winGetDirSep(), zRelative); return SQLITE_OK; } zConverted = winConvertFromUtf8Filename(zRelative); @@ -51353,57 +51353,57 @@ static int winFullPathname( LPWSTR zTemp; nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); if( nByte==0 ){ - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), "winFullPathname1", zRelative); } nByte += 3; - zTemp = tdsqlite3MallocZero( nByte*sizeof(zTemp[0]) ); + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); return SQLITE_IOERR_NOMEM_BKPT; } nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); if( nByte==0 ){ - tdsqlite3_free(zConverted); - tdsqlite3_free(zTemp); + sqlite3_free(zConverted); + sqlite3_free(zTemp); return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), "winFullPathname2", zRelative); } - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); zOut = winUnicodeToUtf8(zTemp); - tdsqlite3_free(zTemp); + sqlite3_free(zTemp); } #ifdef SQLITE_WIN32_HAS_ANSI else{ char *zTemp; nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); if( nByte==0 ){ - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), "winFullPathname3", zRelative); } nByte += 3; - zTemp = tdsqlite3MallocZero( nByte*sizeof(zTemp[0]) ); + zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); if( zTemp==0 ){ - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); return SQLITE_IOERR_NOMEM_BKPT; } nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); if( nByte==0 ){ - tdsqlite3_free(zConverted); - tdsqlite3_free(zTemp); + sqlite3_free(zConverted); + sqlite3_free(zTemp); return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), "winFullPathname4", zRelative); } - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); zOut = winMbcsToUtf8(zTemp, osAreFileApisANSI()); - tdsqlite3_free(zTemp); + sqlite3_free(zTemp); } #endif if( zOut ){ - tdsqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); - tdsqlite3_free(zOut); + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zOut); + sqlite3_free(zOut); return SQLITE_OK; }else{ return SQLITE_IOERR_NOMEM_BKPT; @@ -51416,23 +51416,23 @@ static int winFullPathname( ** Interfaces for opening a shared library, finding entry points ** within the shared library, and closing the shared library. */ -static void *winDlOpen(tdsqlite3_vfs *pVfs, const char *zFilename){ +static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ HANDLE h; #if defined(__CYGWIN__) int nFull = pVfs->mxPathname+1; - char *zFull = tdsqlite3MallocZero( nFull ); + char *zFull = sqlite3MallocZero( nFull ); void *zConverted = 0; if( zFull==0 ){ OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); return 0; } if( winFullPathname(pVfs, zFilename, nFull, zFull)!=SQLITE_OK ){ - tdsqlite3_free(zFull); + sqlite3_free(zFull); OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)0)); return 0; } zConverted = winConvertFromUtf8Filename(zFull); - tdsqlite3_free(zFull); + sqlite3_free(zFull); #else void *zConverted = winConvertFromUtf8Filename(zFilename); UNUSED_PARAMETER(pVfs); @@ -51454,14 +51454,14 @@ static void *winDlOpen(tdsqlite3_vfs *pVfs, const char *zFilename){ } #endif OSTRACE(("DLOPEN name=%s, handle=%p\n", zFilename, (void*)h)); - tdsqlite3_free(zConverted); + sqlite3_free(zConverted); return (void*)h; } -static void winDlError(tdsqlite3_vfs *pVfs, int nBuf, char *zBufOut){ +static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ UNUSED_PARAMETER(pVfs); winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); } -static void (*winDlSym(tdsqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ +static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ FARPROC proc; UNUSED_PARAMETER(pVfs); proc = osGetProcAddressA((HANDLE)pH, zSym); @@ -51469,7 +51469,7 @@ static void (*winDlSym(tdsqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ (void*)pH, zSym, (void*)proc)); return (void(*)(void))proc; } -static void winDlClose(tdsqlite3_vfs *pVfs, void *pHandle){ +static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){ UNUSED_PARAMETER(pVfs); osFreeLibrary((HANDLE)pHandle); OSTRACE(("DLCLOSE handle=%p\n", (void*)pHandle)); @@ -51506,7 +51506,7 @@ static void xorMemory(EntropyGatherer *p, unsigned char *x, int sz){ /* ** Write up to nBuf bytes of randomness into zBuf. */ -static int winRandomness(tdsqlite3_vfs *pVfs, int nBuf, char *zBuf){ +static int winRandomness(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ #if defined(SQLITE_TEST) || defined(SQLITE_OMIT_RANDOMNESS) UNUSED_PARAMETER(pVfs); memset(zBuf, 0, nBuf); @@ -51563,8 +51563,8 @@ static int winRandomness(tdsqlite3_vfs *pVfs, int nBuf, char *zBuf){ /* ** Sleep for a little while. Return the amount of time slept. */ -static int winSleep(tdsqlite3_vfs *pVfs, int microsec){ - tdsqlite3_win32_sleep((microsec+999)/1000); +static int winSleep(sqlite3_vfs *pVfs, int microsec){ + sqlite3_win32_sleep((microsec+999)/1000); UNUSED_PARAMETER(pVfs); return ((microsec+999)/1000)*1000; } @@ -51572,10 +51572,10 @@ static int winSleep(tdsqlite3_vfs *pVfs, int microsec){ /* ** The following variable, if set to a non-zero value, is interpreted as ** the number of seconds since 1970 and is used to set the result of -** tdsqlite3OsCurrentTime() during testing. +** sqlite3OsCurrentTime() during testing. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ +SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1970. */ #endif /* @@ -51588,19 +51588,19 @@ SQLITE_API int tdsqlite3_current_time = 0; /* Fake system time in seconds since ** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date ** cannot be found. */ -static int winCurrentTimeInt64(tdsqlite3_vfs *pVfs, tdsqlite3_int64 *piNow){ +static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){ /* FILETIME structure is a 64-bit value representing the number of 100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). */ FILETIME ft; - static const tdsqlite3_int64 winFiletimeEpoch = 23058135*(tdsqlite3_int64)8640000; + static const sqlite3_int64 winFiletimeEpoch = 23058135*(sqlite3_int64)8640000; #ifdef SQLITE_TEST - static const tdsqlite3_int64 unixEpoch = 24405875*(tdsqlite3_int64)8640000; + static const sqlite3_int64 unixEpoch = 24405875*(sqlite3_int64)8640000; #endif /* 2^32 - to avoid use of LL and warnings in gcc */ - static const tdsqlite3_int64 max32BitValue = - (tdsqlite3_int64)2000000000 + (tdsqlite3_int64)2000000000 + - (tdsqlite3_int64)294967296; + static const sqlite3_int64 max32BitValue = + (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + + (sqlite3_int64)294967296; #if SQLITE_OS_WINCE SYSTEMTIME time; @@ -51614,12 +51614,12 @@ static int winCurrentTimeInt64(tdsqlite3_vfs *pVfs, tdsqlite3_int64 *piNow){ #endif *piNow = winFiletimeEpoch + - ((((tdsqlite3_int64)ft.dwHighDateTime)*max32BitValue) + - (tdsqlite3_int64)ft.dwLowDateTime)/(tdsqlite3_int64)10000; + ((((sqlite3_int64)ft.dwHighDateTime)*max32BitValue) + + (sqlite3_int64)ft.dwLowDateTime)/(sqlite3_int64)10000; #ifdef SQLITE_TEST - if( tdsqlite3_current_time ){ - *piNow = 1000*(tdsqlite3_int64)tdsqlite3_current_time + unixEpoch; + if( sqlite3_current_time ){ + *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch; } #endif UNUSED_PARAMETER(pVfs); @@ -51631,9 +51631,9 @@ static int winCurrentTimeInt64(tdsqlite3_vfs *pVfs, tdsqlite3_int64 *piNow){ ** current time and date as a Julian Day number into *prNow and ** return 0. Return 1 if the time and date cannot be found. */ -static int winCurrentTime(tdsqlite3_vfs *pVfs, double *prNow){ +static int winCurrentTime(sqlite3_vfs *pVfs, double *prNow){ int rc; - tdsqlite3_int64 i; + sqlite3_int64 i; rc = winCurrentTimeInt64(pVfs, &i); if( !rc ){ *prNow = i/86400000.0; @@ -51662,16 +51662,16 @@ static int winCurrentTime(tdsqlite3_vfs *pVfs, double *prNow){ ** on SQLite. It is fine to have an implementation that never ** returns an error message: ** -** int xGetLastError(tdsqlite3_vfs *pVfs, int nBuf, char *zBuf){ +** int xGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ ** assert(zBuf[0]=='\0'); ** return 0; ** } ** ** However if an error message is supplied, it will be incorporated ** by sqlite into the error message available to the user using -** tdsqlite3_errmsg(), possibly making IO errors easier to debug. +** sqlite3_errmsg(), possibly making IO errors easier to debug. */ -static int winGetLastError(tdsqlite3_vfs *pVfs, int nBuf, char *zBuf){ +static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ DWORD e = osGetLastError(); UNUSED_PARAMETER(pVfs); if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); @@ -51681,8 +51681,8 @@ static int winGetLastError(tdsqlite3_vfs *pVfs, int nBuf, char *zBuf){ /* ** Initialize and deinitialize the operating system interface. */ -SQLITE_API int tdsqlite3_os_init(void){ - static tdsqlite3_vfs winVfs = { +SQLITE_API int sqlite3_os_init(void){ + static sqlite3_vfs winVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ @@ -51707,7 +51707,7 @@ SQLITE_API int tdsqlite3_os_init(void){ winNextSystemCall, /* xNextSystemCall */ }; #if defined(SQLITE_WIN32_HAS_WIDE) - static tdsqlite3_vfs winLongPathVfs = { + static sqlite3_vfs winLongPathVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ @@ -51732,7 +51732,7 @@ SQLITE_API int tdsqlite3_os_init(void){ winNextSystemCall, /* xNextSystemCall */ }; #endif - static tdsqlite3_vfs winNolockVfs = { + static sqlite3_vfs winNolockVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ @@ -51757,7 +51757,7 @@ SQLITE_API int tdsqlite3_os_init(void){ winNextSystemCall, /* xNextSystemCall */ }; #if defined(SQLITE_WIN32_HAS_WIDE) - static tdsqlite3_vfs winLongPathNolockVfs = { + static sqlite3_vfs winLongPathNolockVfs = { 3, /* iVersion */ sizeof(winFile), /* szOsFile */ SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ @@ -51797,26 +51797,26 @@ SQLITE_API int tdsqlite3_os_init(void){ assert( winSysInfo.dwAllocationGranularity>0 ); assert( winSysInfo.dwPageSize>0 ); - tdsqlite3_vfs_register(&winVfs, 1); + sqlite3_vfs_register(&winVfs, 1); #if defined(SQLITE_WIN32_HAS_WIDE) - tdsqlite3_vfs_register(&winLongPathVfs, 0); + sqlite3_vfs_register(&winLongPathVfs, 0); #endif - tdsqlite3_vfs_register(&winNolockVfs, 0); + sqlite3_vfs_register(&winNolockVfs, 0); #if defined(SQLITE_WIN32_HAS_WIDE) - tdsqlite3_vfs_register(&winLongPathNolockVfs, 0); + sqlite3_vfs_register(&winLongPathNolockVfs, 0); #endif #ifndef SQLITE_OMIT_WAL - winBigLock = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); + winBigLock = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1); #endif return SQLITE_OK; } -SQLITE_API int tdsqlite3_os_end(void){ +SQLITE_API int sqlite3_os_end(void){ #if SQLITE_OS_WINRT if( sleepObj!=NULL ){ osCloseHandle(sleepObj); @@ -51850,8 +51850,8 @@ SQLITE_API int tdsqlite3_os_end(void){ ** This file implements an in-memory VFS. A database is held as a contiguous ** block of memory. ** -** This file also implements interface tdsqlite3_serialize() and -** tdsqlite3_deserialize(). +** This file also implements interface sqlite3_serialize() and +** sqlite3_deserialize(). */ /* #include "sqliteInt.h" */ #ifdef SQLITE_ENABLE_DESERIALIZE @@ -51859,20 +51859,20 @@ SQLITE_API int tdsqlite3_os_end(void){ /* ** Forward declaration of objects used by this utility */ -typedef struct tdsqlite3_vfs MemVfs; +typedef struct sqlite3_vfs MemVfs; typedef struct MemFile MemFile; /* Access to a lower-level VFS that (might) implement dynamic loading, ** access to randomness, etc. */ -#define ORIGVFS(p) ((tdsqlite3_vfs*)((p)->pAppData)) +#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData)) /* An open file */ struct MemFile { - tdsqlite3_file base; /* IO methods */ - tdsqlite3_int64 sz; /* Size of the file */ - tdsqlite3_int64 szAlloc; /* Space allocated to aData */ - tdsqlite3_int64 szMax; /* Maximum allowed size of the file */ + sqlite3_file base; /* IO methods */ + sqlite3_int64 sz; /* Size of the file */ + sqlite3_int64 szAlloc; /* Space allocated to aData */ + sqlite3_int64 szMax; /* Maximum allowed size of the file */ unsigned char *aData; /* content of the file */ int nMmap; /* Number of memory mapped pages */ unsigned mFlags; /* Flags */ @@ -51882,38 +51882,38 @@ struct MemFile { /* ** Methods for MemFile */ -static int memdbClose(tdsqlite3_file*); -static int memdbRead(tdsqlite3_file*, void*, int iAmt, tdsqlite3_int64 iOfst); -static int memdbWrite(tdsqlite3_file*,const void*,int iAmt, tdsqlite3_int64 iOfst); -static int memdbTruncate(tdsqlite3_file*, tdsqlite3_int64 size); -static int memdbSync(tdsqlite3_file*, int flags); -static int memdbFileSize(tdsqlite3_file*, tdsqlite3_int64 *pSize); -static int memdbLock(tdsqlite3_file*, int); -/* static int memdbCheckReservedLock(tdsqlite3_file*, int *pResOut);// not used */ -static int memdbFileControl(tdsqlite3_file*, int op, void *pArg); -/* static int memdbSectorSize(tdsqlite3_file*); // not used */ -static int memdbDeviceCharacteristics(tdsqlite3_file*); -static int memdbFetch(tdsqlite3_file*, tdsqlite3_int64 iOfst, int iAmt, void **pp); -static int memdbUnfetch(tdsqlite3_file*, tdsqlite3_int64 iOfst, void *p); +static int memdbClose(sqlite3_file*); +static int memdbRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst); +static int memdbWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst); +static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); +static int memdbSync(sqlite3_file*, int flags); +static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); +static int memdbLock(sqlite3_file*, int); +/* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ +static int memdbFileControl(sqlite3_file*, int op, void *pArg); +/* static int memdbSectorSize(sqlite3_file*); // not used */ +static int memdbDeviceCharacteristics(sqlite3_file*); +static int memdbFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp); +static int memdbUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p); /* ** Methods for MemVfs */ -static int memdbOpen(tdsqlite3_vfs*, const char *, tdsqlite3_file*, int , int *); -/* static int memdbDelete(tdsqlite3_vfs*, const char *zName, int syncDir); */ -static int memdbAccess(tdsqlite3_vfs*, const char *zName, int flags, int *); -static int memdbFullPathname(tdsqlite3_vfs*, const char *zName, int, char *zOut); -static void *memdbDlOpen(tdsqlite3_vfs*, const char *zFilename); -static void memdbDlError(tdsqlite3_vfs*, int nByte, char *zErrMsg); -static void (*memdbDlSym(tdsqlite3_vfs *pVfs, void *p, const char*zSym))(void); -static void memdbDlClose(tdsqlite3_vfs*, void*); -static int memdbRandomness(tdsqlite3_vfs*, int nByte, char *zOut); -static int memdbSleep(tdsqlite3_vfs*, int microseconds); -/* static int memdbCurrentTime(tdsqlite3_vfs*, double*); */ -static int memdbGetLastError(tdsqlite3_vfs*, int, char *); -static int memdbCurrentTimeInt64(tdsqlite3_vfs*, tdsqlite3_int64*); - -static tdsqlite3_vfs memdb_vfs = { +static int memdbOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *); +/* static int memdbDelete(sqlite3_vfs*, const char *zName, int syncDir); */ +static int memdbAccess(sqlite3_vfs*, const char *zName, int flags, int *); +static int memdbFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut); +static void *memdbDlOpen(sqlite3_vfs*, const char *zFilename); +static void memdbDlError(sqlite3_vfs*, int nByte, char *zErrMsg); +static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void); +static void memdbDlClose(sqlite3_vfs*, void*); +static int memdbRandomness(sqlite3_vfs*, int nByte, char *zOut); +static int memdbSleep(sqlite3_vfs*, int microseconds); +/* static int memdbCurrentTime(sqlite3_vfs*, double*); */ +static int memdbGetLastError(sqlite3_vfs*, int, char *); +static int memdbCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*); + +static sqlite3_vfs memdb_vfs = { 2, /* iVersion */ 0, /* szOsFile (set when registered) */ 1024, /* mxPathname */ @@ -51935,7 +51935,7 @@ static tdsqlite3_vfs memdb_vfs = { memdbCurrentTimeInt64 /* xCurrentTimeInt64 */ }; -static const tdsqlite3_io_methods memdb_io_methods = { +static const sqlite3_io_methods memdb_io_methods = { 3, /* iVersion */ memdbClose, /* xClose */ memdbRead, /* xRead */ @@ -51965,9 +51965,9 @@ static const tdsqlite3_io_methods memdb_io_methods = { ** The pData pointer is owned by the application, so there is nothing ** to free. */ -static int memdbClose(tdsqlite3_file *pFile){ +static int memdbClose(sqlite3_file *pFile){ MemFile *p = (MemFile *)pFile; - if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) tdsqlite3_free(p->aData); + if( p->mFlags & SQLITE_DESERIALIZE_FREEONCLOSE ) sqlite3_free(p->aData); return SQLITE_OK; } @@ -51975,7 +51975,7 @@ static int memdbClose(tdsqlite3_file *pFile){ ** Read data from an memdb-file. */ static int memdbRead( - tdsqlite3_file *pFile, + sqlite3_file *pFile, void *zBuf, int iAmt, sqlite_int64 iOfst @@ -51993,7 +51993,7 @@ static int memdbRead( /* ** Try to enlarge the memory allocation to hold at least sz bytes */ -static int memdbEnlarge(MemFile *p, tdsqlite3_int64 newSz){ +static int memdbEnlarge(MemFile *p, sqlite3_int64 newSz){ unsigned char *pNew; if( (p->mFlags & SQLITE_DESERIALIZE_RESIZEABLE)==0 || p->nMmap>0 ){ return SQLITE_FULL; @@ -52003,7 +52003,7 @@ static int memdbEnlarge(MemFile *p, tdsqlite3_int64 newSz){ } newSz *= 2; if( newSz>p->szMax ) newSz = p->szMax; - pNew = tdsqlite3_realloc64(p->aData, newSz); + pNew = sqlite3_realloc64(p->aData, newSz); if( pNew==0 ) return SQLITE_NOMEM; p->aData = pNew; p->szAlloc = newSz; @@ -52014,7 +52014,7 @@ static int memdbEnlarge(MemFile *p, tdsqlite3_int64 newSz){ ** Write data to an memdb-file. */ static int memdbWrite( - tdsqlite3_file *pFile, + sqlite3_file *pFile, const void *z, int iAmt, sqlite_int64 iOfst @@ -52042,7 +52042,7 @@ static int memdbWrite( ** support WAL mode) the truncate() method is only used to reduce ** the size of a file, never to increase the size. */ -static int memdbTruncate(tdsqlite3_file *pFile, sqlite_int64 size){ +static int memdbTruncate(sqlite3_file *pFile, sqlite_int64 size){ MemFile *p = (MemFile *)pFile; if( NEVER(size>p->sz) ) return SQLITE_FULL; p->sz = size; @@ -52052,14 +52052,14 @@ static int memdbTruncate(tdsqlite3_file *pFile, sqlite_int64 size){ /* ** Sync an memdb-file. */ -static int memdbSync(tdsqlite3_file *pFile, int flags){ +static int memdbSync(sqlite3_file *pFile, int flags){ return SQLITE_OK; } /* ** Return the current file-size of an memdb-file. */ -static int memdbFileSize(tdsqlite3_file *pFile, sqlite_int64 *pSize){ +static int memdbFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ MemFile *p = (MemFile *)pFile; *pSize = p->sz; return SQLITE_OK; @@ -52068,7 +52068,7 @@ static int memdbFileSize(tdsqlite3_file *pFile, sqlite_int64 *pSize){ /* ** Lock an memdb-file. */ -static int memdbLock(tdsqlite3_file *pFile, int eLock){ +static int memdbLock(sqlite3_file *pFile, int eLock){ MemFile *p = (MemFile *)pFile; if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY)!=0 @@ -52083,7 +52083,7 @@ static int memdbLock(tdsqlite3_file *pFile, int eLock){ /* ** Check if another file-handle holds a RESERVED lock on an memdb-file. */ -static int memdbCheckReservedLock(tdsqlite3_file *pFile, int *pResOut){ +static int memdbCheckReservedLock(sqlite3_file *pFile, int *pResOut){ *pResOut = 0; return SQLITE_OK; } @@ -52092,15 +52092,15 @@ static int memdbCheckReservedLock(tdsqlite3_file *pFile, int *pResOut){ /* ** File control method. For custom operations on an memdb-file. */ -static int memdbFileControl(tdsqlite3_file *pFile, int op, void *pArg){ +static int memdbFileControl(sqlite3_file *pFile, int op, void *pArg){ MemFile *p = (MemFile *)pFile; int rc = SQLITE_NOTFOUND; if( op==SQLITE_FCNTL_VFSNAME ){ - *(char**)pArg = tdsqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz); + *(char**)pArg = sqlite3_mprintf("memdb(%p,%lld)", p->aData, p->sz); rc = SQLITE_OK; } if( op==SQLITE_FCNTL_SIZE_LIMIT ){ - tdsqlite3_int64 iLimit = *(tdsqlite3_int64*)pArg; + sqlite3_int64 iLimit = *(sqlite3_int64*)pArg; if( iLimitsz ){ if( iLimit<0 ){ iLimit = p->szMax; @@ -52109,7 +52109,7 @@ static int memdbFileControl(tdsqlite3_file *pFile, int op, void *pArg){ } } p->szMax = iLimit; - *(tdsqlite3_int64*)pArg = iLimit; + *(sqlite3_int64*)pArg = iLimit; rc = SQLITE_OK; } return rc; @@ -52119,7 +52119,7 @@ static int memdbFileControl(tdsqlite3_file *pFile, int op, void *pArg){ /* ** Return the sector-size in bytes for an memdb-file. */ -static int memdbSectorSize(tdsqlite3_file *pFile){ +static int memdbSectorSize(sqlite3_file *pFile){ return 1024; } #endif @@ -52127,7 +52127,7 @@ static int memdbSectorSize(tdsqlite3_file *pFile){ /* ** Return the device characteristic flags supported by an memdb-file. */ -static int memdbDeviceCharacteristics(tdsqlite3_file *pFile){ +static int memdbDeviceCharacteristics(sqlite3_file *pFile){ return SQLITE_IOCAP_ATOMIC | SQLITE_IOCAP_POWERSAFE_OVERWRITE | SQLITE_IOCAP_SAFE_APPEND | @@ -52136,8 +52136,8 @@ static int memdbDeviceCharacteristics(tdsqlite3_file *pFile){ /* Fetch a page of a memory-mapped file */ static int memdbFetch( - tdsqlite3_file *pFile, - tdsqlite3_int64 iOfst, + sqlite3_file *pFile, + sqlite3_int64 iOfst, int iAmt, void **pp ){ @@ -52152,7 +52152,7 @@ static int memdbFetch( } /* Release a memory-mapped page */ -static int memdbUnfetch(tdsqlite3_file *pFile, tdsqlite3_int64 iOfst, void *pPage){ +static int memdbUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){ MemFile *p = (MemFile *)pFile; p->nMmap--; return SQLITE_OK; @@ -52162,9 +52162,9 @@ static int memdbUnfetch(tdsqlite3_file *pFile, tdsqlite3_int64 iOfst, void *pPag ** Open an mem file handle. */ static int memdbOpen( - tdsqlite3_vfs *pVfs, + sqlite3_vfs *pVfs, const char *zName, - tdsqlite3_file *pFile, + sqlite3_file *pFile, int flags, int *pOutFlags ){ @@ -52177,7 +52177,7 @@ static int memdbOpen( assert( pOutFlags!=0 ); /* True because flags==SQLITE_OPEN_MAIN_DB */ *pOutFlags = flags | SQLITE_OPEN_MEMORY; p->base.pMethods = &memdb_io_methods; - p->szMax = tdsqlite3GlobalConfig.mxMemdbSize; + p->szMax = sqlite3GlobalConfig.mxMemdbSize; return SQLITE_OK; } @@ -52188,7 +52188,7 @@ static int memdbOpen( ** ensure the file-system modifications are synced to disk before ** returning. */ -static int memdbDelete(tdsqlite3_vfs *pVfs, const char *zPath, int dirSync){ +static int memdbDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ return SQLITE_IOERR_DELETE; } #endif @@ -52200,7 +52200,7 @@ static int memdbDelete(tdsqlite3_vfs *pVfs, const char *zPath, int dirSync){ ** With memdb, no files ever exist on disk. So always return false. */ static int memdbAccess( - tdsqlite3_vfs *pVfs, + sqlite3_vfs *pVfs, const char *zPath, int flags, int *pResOut @@ -52215,19 +52215,19 @@ static int memdbAccess( ** of at least (INST_MAX_PATHNAME+1) bytes. */ static int memdbFullPathname( - tdsqlite3_vfs *pVfs, + sqlite3_vfs *pVfs, const char *zPath, int nOut, char *zOut ){ - tdsqlite3_snprintf(nOut, zOut, "%s", zPath); + sqlite3_snprintf(nOut, zOut, "%s", zPath); return SQLITE_OK; } /* ** Open the dynamic library located at zPath and return a handle. */ -static void *memdbDlOpen(tdsqlite3_vfs *pVfs, const char *zPath){ +static void *memdbDlOpen(sqlite3_vfs *pVfs, const char *zPath){ return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath); } @@ -52236,21 +52236,21 @@ static void *memdbDlOpen(tdsqlite3_vfs *pVfs, const char *zPath){ ** utf-8 string describing the most recent error encountered associated ** with dynamic libraries. */ -static void memdbDlError(tdsqlite3_vfs *pVfs, int nByte, char *zErrMsg){ +static void memdbDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg); } /* ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. */ -static void (*memdbDlSym(tdsqlite3_vfs *pVfs, void *p, const char *zSym))(void){ +static void (*memdbDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){ return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym); } /* ** Close the dynamic library handle pHandle. */ -static void memdbDlClose(tdsqlite3_vfs *pVfs, void *pHandle){ +static void memdbDlClose(sqlite3_vfs *pVfs, void *pHandle){ ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle); } @@ -52258,7 +52258,7 @@ static void memdbDlClose(tdsqlite3_vfs *pVfs, void *pHandle){ ** Populate the buffer pointed to by zBufOut with nByte bytes of ** random data. */ -static int memdbRandomness(tdsqlite3_vfs *pVfs, int nByte, char *zBufOut){ +static int memdbRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut); } @@ -52266,7 +52266,7 @@ static int memdbRandomness(tdsqlite3_vfs *pVfs, int nByte, char *zBufOut){ ** Sleep for nMicro microseconds. Return the number of microseconds ** actually slept. */ -static int memdbSleep(tdsqlite3_vfs *pVfs, int nMicro){ +static int memdbSleep(sqlite3_vfs *pVfs, int nMicro){ return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro); } @@ -52274,15 +52274,15 @@ static int memdbSleep(tdsqlite3_vfs *pVfs, int nMicro){ /* ** Return the current time as a Julian Day number in *pTimeOut. */ -static int memdbCurrentTime(tdsqlite3_vfs *pVfs, double *pTimeOut){ +static int memdbCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut); } #endif -static int memdbGetLastError(tdsqlite3_vfs *pVfs, int a, char *b){ +static int memdbGetLastError(sqlite3_vfs *pVfs, int a, char *b){ return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b); } -static int memdbCurrentTimeInt64(tdsqlite3_vfs *pVfs, tdsqlite3_int64 *p){ +static int memdbCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){ return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p); } @@ -52290,9 +52290,9 @@ static int memdbCurrentTimeInt64(tdsqlite3_vfs *pVfs, tdsqlite3_int64 *p){ ** Translate a database connection pointer and schema name into a ** MemFile pointer. */ -static MemFile *memdbFromDbSchema(tdsqlite3 *db, const char *zSchema){ +static MemFile *memdbFromDbSchema(sqlite3 *db, const char *zSchema){ MemFile *p = 0; - int rc = tdsqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); + int rc = sqlite3_file_control(db, zSchema, SQLITE_FCNTL_FILE_POINTER, &p); if( rc ) return 0; if( p->base.pMethods!=&memdb_io_methods ) return 0; return p; @@ -52301,24 +52301,24 @@ static MemFile *memdbFromDbSchema(tdsqlite3 *db, const char *zSchema){ /* ** Return the serialization of a database */ -SQLITE_API unsigned char *tdsqlite3_serialize( - tdsqlite3 *db, /* The database connection */ +SQLITE_API unsigned char *sqlite3_serialize( + sqlite3 *db, /* The database connection */ const char *zSchema, /* Which database within the connection */ - tdsqlite3_int64 *piSize, /* Write size here, if not NULL */ + sqlite3_int64 *piSize, /* Write size here, if not NULL */ unsigned int mFlags /* Maybe SQLITE_SERIALIZE_NOCOPY */ ){ MemFile *p; int iDb; Btree *pBt; - tdsqlite3_int64 sz; + sqlite3_int64 sz; int szPage = 0; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; unsigned char *pOut; char *zSql; int rc; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } @@ -52326,7 +52326,7 @@ SQLITE_API unsigned char *tdsqlite3_serialize( if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; p = memdbFromDbSchema(db, zSchema); - iDb = tdsqlite3FindDbName(db, zSchema); + iDb = sqlite3FindDbName(db, zSchema); if( piSize ) *piSize = -1; if( iDb<0 ) return 0; if( p ){ @@ -52334,88 +52334,88 @@ SQLITE_API unsigned char *tdsqlite3_serialize( if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ pOut = p->aData; }else{ - pOut = tdsqlite3_malloc64( p->sz ); + pOut = sqlite3_malloc64( p->sz ); if( pOut ) memcpy(pOut, p->aData, p->sz); } return pOut; } pBt = db->aDb[iDb].pBt; if( pBt==0 ) return 0; - szPage = tdsqlite3BtreeGetPageSize(pBt); - zSql = tdsqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema); - rc = zSql ? tdsqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM; - tdsqlite3_free(zSql); + szPage = sqlite3BtreeGetPageSize(pBt); + zSql = sqlite3_mprintf("PRAGMA \"%w\".page_count", zSchema); + rc = zSql ? sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0) : SQLITE_NOMEM; + sqlite3_free(zSql); if( rc ) return 0; - rc = tdsqlite3_step(pStmt); + rc = sqlite3_step(pStmt); if( rc!=SQLITE_ROW ){ pOut = 0; }else{ - sz = tdsqlite3_column_int64(pStmt, 0)*szPage; + sz = sqlite3_column_int64(pStmt, 0)*szPage; if( piSize ) *piSize = sz; if( mFlags & SQLITE_SERIALIZE_NOCOPY ){ pOut = 0; }else{ - pOut = tdsqlite3_malloc64( sz ); + pOut = sqlite3_malloc64( sz ); if( pOut ){ - int nPage = tdsqlite3_column_int(pStmt, 0); - Pager *pPager = tdsqlite3BtreePager(pBt); + int nPage = sqlite3_column_int(pStmt, 0); + Pager *pPager = sqlite3BtreePager(pBt); int pgno; for(pgno=1; pgno<=nPage; pgno++){ DbPage *pPage = 0; - unsigned char *pTo = pOut + szPage*(tdsqlite3_int64)(pgno-1); - rc = tdsqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0); + unsigned char *pTo = pOut + szPage*(sqlite3_int64)(pgno-1); + rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pPage, 0); if( rc==SQLITE_OK ){ - memcpy(pTo, tdsqlite3PagerGetData(pPage), szPage); + memcpy(pTo, sqlite3PagerGetData(pPage), szPage); }else{ memset(pTo, 0, szPage); } - tdsqlite3PagerUnref(pPage); + sqlite3PagerUnref(pPage); } } } } - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); return pOut; } /* Convert zSchema to a MemDB and initialize its content. */ -SQLITE_API int tdsqlite3_deserialize( - tdsqlite3 *db, /* The database connection */ +SQLITE_API int sqlite3_deserialize( + sqlite3 *db, /* The database connection */ const char *zSchema, /* Which DB to reopen with the deserialization */ unsigned char *pData, /* The serialized database content */ - tdsqlite3_int64 szDb, /* Number bytes in the deserialization */ - tdsqlite3_int64 szBuf, /* Total size of buffer pData[] */ + sqlite3_int64 szDb, /* Number bytes in the deserialization */ + sqlite3_int64 szBuf, /* Total size of buffer pData[] */ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */ ){ MemFile *p; char *zSql; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; int rc; int iDb; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } if( szDb<0 ) return SQLITE_MISUSE_BKPT; if( szBuf<0 ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( zSchema==0 ) zSchema = db->aDb[0].zDbSName; - iDb = tdsqlite3FindDbName(db, zSchema); + iDb = sqlite3FindDbName(db, zSchema); if( iDb<0 ){ rc = SQLITE_ERROR; goto end_deserialize; } - zSql = tdsqlite3_mprintf("ATTACH x AS %Q", zSchema); - rc = tdsqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - tdsqlite3_free(zSql); + zSql = sqlite3_mprintf("ATTACH x AS %Q", zSchema); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); if( rc ) goto end_deserialize; db->init.iDb = (u8)iDb; db->init.reopenMemdb = 1; - rc = tdsqlite3_step(pStmt); + rc = sqlite3_step(pStmt); db->init.reopenMemdb = 0; if( rc!=SQLITE_DONE ){ rc = SQLITE_ERROR; @@ -52429,16 +52429,16 @@ SQLITE_API int tdsqlite3_deserialize( p->sz = szDb; p->szAlloc = szBuf; p->szMax = szBuf; - if( p->szMaxszMax = tdsqlite3GlobalConfig.mxMemdbSize; + if( p->szMaxszMax = sqlite3GlobalConfig.mxMemdbSize; } p->mFlags = mFlags; rc = SQLITE_OK; } end_deserialize: - tdsqlite3_finalize(pStmt); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_finalize(pStmt); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -52446,16 +52446,16 @@ end_deserialize: ** This routine is called when the extension is loaded. ** Register the new VFS. */ -SQLITE_PRIVATE int tdsqlite3MemdbInit(void){ - tdsqlite3_vfs *pLower = tdsqlite3_vfs_find(0); +SQLITE_PRIVATE int sqlite3MemdbInit(void){ + sqlite3_vfs *pLower = sqlite3_vfs_find(0); int sz = pLower->szOsFile; memdb_vfs.pAppData = pLower; /* In all known configurations of SQLite, the size of a default - ** tdsqlite3_file is greater than the size of a memdb tdsqlite3_file. + ** sqlite3_file is greater than the size of a memdb sqlite3_file. ** Should that ever change, remove the following NEVER() */ if( NEVER(sziSize = iSize; } @@ -52590,7 +52590,7 @@ SQLITE_PRIVATE Bitvec *tdsqlite3BitvecCreate(u32 iSize){ ** If p is NULL (if the bitmap has not been created) or if ** i is out of range, then return false. */ -SQLITE_PRIVATE int tdsqlite3BitvecTestNotNull(Bitvec *p, u32 i){ +SQLITE_PRIVATE int sqlite3BitvecTestNotNull(Bitvec *p, u32 i){ assert( p!=0 ); i--; if( i>=p->iSize ) return 0; @@ -52613,8 +52613,8 @@ SQLITE_PRIVATE int tdsqlite3BitvecTestNotNull(Bitvec *p, u32 i){ return 0; } } -SQLITE_PRIVATE int tdsqlite3BitvecTest(Bitvec *p, u32 i){ - return p!=0 && tdsqlite3BitvecTestNotNull(p,i); +SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){ + return p!=0 && sqlite3BitvecTestNotNull(p,i); } /* @@ -52629,7 +52629,7 @@ SQLITE_PRIVATE int tdsqlite3BitvecTest(Bitvec *p, u32 i){ ** and that the value for "i" is within range of the Bitvec object. ** Otherwise the behavior is undefined. */ -SQLITE_PRIVATE int tdsqlite3BitvecSet(Bitvec *p, u32 i){ +SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ u32 h; if( p==0 ) return SQLITE_OK; assert( i>0 ); @@ -52639,7 +52639,7 @@ SQLITE_PRIVATE int tdsqlite3BitvecSet(Bitvec *p, u32 i){ u32 bin = i/p->iDivisor; i = i%p->iDivisor; if( p->u.apSub[bin]==0 ){ - p->u.apSub[bin] = tdsqlite3BitvecCreate( p->iDivisor ); + p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor ); if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM_BKPT; } p = p->u.apSub[bin]; @@ -52673,18 +52673,18 @@ bitvec_set_rehash: if( p->nSet>=BITVEC_MXHASH ){ unsigned int j; int rc; - u32 *aiValues = tdsqlite3StackAllocRaw(0, sizeof(p->u.aHash)); + u32 *aiValues = sqlite3StackAllocRaw(0, sizeof(p->u.aHash)); if( aiValues==0 ){ return SQLITE_NOMEM_BKPT; }else{ memcpy(aiValues, p->u.aHash, sizeof(p->u.aHash)); memset(p->u.apSub, 0, sizeof(p->u.apSub)); p->iDivisor = (p->iSize + BITVEC_NPTR - 1)/BITVEC_NPTR; - rc = tdsqlite3BitvecSet(p, i); + rc = sqlite3BitvecSet(p, i); for(j=0; j0 ); i--; @@ -52737,22 +52737,22 @@ SQLITE_PRIVATE void tdsqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ /* ** Destroy a bitmap object. Reclaim all memory used. */ -SQLITE_PRIVATE void tdsqlite3BitvecDestroy(Bitvec *p){ +SQLITE_PRIVATE void sqlite3BitvecDestroy(Bitvec *p){ if( p==0 ) return; if( p->iDivisor ){ unsigned int i; for(i=0; iu.apSub[i]); + sqlite3BitvecDestroy(p->u.apSub[i]); } } - tdsqlite3_free(p); + sqlite3_free(p); } /* ** Return the value of the iSize parameter specified when Bitvec *p ** was created. */ -SQLITE_PRIVATE u32 tdsqlite3BitvecSize(Bitvec *p){ +SQLITE_PRIVATE u32 sqlite3BitvecSize(Bitvec *p){ return p->iSize; } @@ -52797,7 +52797,7 @@ SQLITE_PRIVATE u32 tdsqlite3BitvecSize(Bitvec *p){ ** ** If a memory allocation error occurs, return -1. */ -SQLITE_PRIVATE int tdsqlite3BitvecBuiltinTest(int sz, int *aOp){ +SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ Bitvec *pBitvec = 0; unsigned char *pV = 0; int rc = -1; @@ -52806,14 +52806,14 @@ SQLITE_PRIVATE int tdsqlite3BitvecBuiltinTest(int sz, int *aOp){ /* Allocate the Bitvec to be tested and a linear array of ** bits to act as the reference */ - pBitvec = tdsqlite3BitvecCreate( sz ); - pV = tdsqlite3MallocZero( (sz+7)/8 + 1 ); - pTmpSpace = tdsqlite3_malloc64(BITVEC_SZ); + pBitvec = sqlite3BitvecCreate( sz ); + pV = sqlite3MallocZero( (sz+7)/8 + 1 ); + pTmpSpace = sqlite3_malloc64(BITVEC_SZ); if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; /* NULL pBitvec tests */ - tdsqlite3BitvecSet(0, 1); - tdsqlite3BitvecClear(0, 1, pTmpSpace); + sqlite3BitvecSet(0, 1); + sqlite3BitvecClear(0, 1, pTmpSpace); /* Run the program */ pc = 0; @@ -52831,7 +52831,7 @@ SQLITE_PRIVATE int tdsqlite3BitvecBuiltinTest(int sz, int *aOp){ case 4: default: { nx = 2; - tdsqlite3_randomness(sizeof(i), &i); + sqlite3_randomness(sizeof(i), &i); break; } } @@ -52841,11 +52841,11 @@ SQLITE_PRIVATE int tdsqlite3BitvecBuiltinTest(int sz, int *aOp){ if( (op & 1)!=0 ){ SETBIT(pV, (i+1)); if( op!=5 ){ - if( tdsqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; + if( sqlite3BitvecSet(pBitvec, i+1) ) goto bitvec_end; } }else{ CLEARBIT(pV, (i+1)); - tdsqlite3BitvecClear(pBitvec, i+1, pTmpSpace); + sqlite3BitvecClear(pBitvec, i+1, pTmpSpace); } } @@ -52854,11 +52854,11 @@ SQLITE_PRIVATE int tdsqlite3BitvecBuiltinTest(int sz, int *aOp){ ** match (rc==0). Change rc to non-zero if a discrepancy ** is found. */ - rc = tdsqlite3BitvecTest(0,0) + tdsqlite3BitvecTest(pBitvec, sz+1) - + tdsqlite3BitvecTest(pBitvec, 0) - + (tdsqlite3BitvecSize(pBitvec) - sz); + rc = sqlite3BitvecTest(0,0) + sqlite3BitvecTest(pBitvec, sz+1) + + sqlite3BitvecTest(pBitvec, 0) + + (sqlite3BitvecSize(pBitvec) - sz); for(i=1; i<=sz; i++){ - if( (TESTBIT(pV,i))!=tdsqlite3BitvecTest(pBitvec,i) ){ + if( (TESTBIT(pV,i))!=sqlite3BitvecTest(pBitvec,i) ){ rc = i; break; } @@ -52866,9 +52866,9 @@ SQLITE_PRIVATE int tdsqlite3BitvecBuiltinTest(int sz, int *aOp){ /* Free allocated structure */ bitvec_end: - tdsqlite3_free(pTmpSpace); - tdsqlite3_free(pV); - tdsqlite3BitvecDestroy(pBitvec); + sqlite3_free(pTmpSpace); + sqlite3_free(pV); + sqlite3BitvecDestroy(pBitvec); return rc; } #endif /* SQLITE_UNTESTABLE */ @@ -52927,7 +52927,7 @@ struct PCache { u8 eCreate; /* eCreate value for for xFetch() */ int (*xStress)(void*,PgHdr*); /* Call to try make a page clean */ void *pStress; /* Argument to xStress */ - tdsqlite3_pcache *pCache; /* Pluggable cache module */ + sqlite3_pcache *pCache; /* Pluggable cache module */ }; /********************************** Test and Debug Logic **********************/ @@ -52935,27 +52935,27 @@ struct PCache { ** Debug tracing macros. Enable by by changing the "0" to "1" and ** recompiling. ** -** When tdsqlite3PcacheTrace is 1, single line trace messages are issued. -** When tdsqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries +** When sqlite3PcacheTrace is 1, single line trace messages are issued. +** When sqlite3PcacheTrace is 2, a dump of the pcache showing all cache entries ** is displayed for many operations, resulting in a lot of output. */ #if defined(SQLITE_DEBUG) && 0 - int tdsqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ - int tdsqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ -# define pcacheTrace(X) if(tdsqlite3PcacheTrace){tdsqlite3DebugPrintf X;} + int sqlite3PcacheTrace = 2; /* 0: off 1: simple 2: cache dumps */ + int sqlite3PcacheMxDump = 9999; /* Max cache entries for pcacheDump() */ +# define pcacheTrace(X) if(sqlite3PcacheTrace){sqlite3DebugPrintf X;} void pcacheDump(PCache *pCache){ int N; int i, j; - tdsqlite3_pcache_page *pLower; + sqlite3_pcache_page *pLower; PgHdr *pPg; unsigned char *a; - if( tdsqlite3PcacheTrace<2 ) return; + if( sqlite3PcacheTrace<2 ) return; if( pCache->pCache==0 ) return; - N = tdsqlite3PcachePagecount(pCache); - if( N>tdsqlite3PcacheMxDump ) N = tdsqlite3PcacheMxDump; + N = sqlite3PcachePagecount(pCache); + if( N>sqlite3PcacheMxDump ) N = sqlite3PcacheMxDump; for(i=1; i<=N; i++){ - pLower = tdsqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); + pLower = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, i, 0); if( pLower==0 ) continue; pPg = (PgHdr*)pLower->pExtra; printf("%3d: nRef %2d flgs %02x data ", i, pPg->nRef, pPg->flags); @@ -52963,7 +52963,7 @@ struct PCache { for(j=0; j<12; j++) printf("%02x", a[j]); printf("\n"); if( pPg->pPage==0 ){ - tdsqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); + sqlite3GlobalConfig.pcache2.xUnpin(pCache->pCache, pLower, 0); } } } @@ -52979,10 +52979,10 @@ struct PCache { ** This routine is for use inside of assert() statements only. For ** example: ** -** assert( tdsqlite3PcachePageSanity(pPg) ); +** assert( sqlite3PcachePageSanity(pPg) ); */ #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3PcachePageSanity(PgHdr *pPg){ +SQLITE_PRIVATE int sqlite3PcachePageSanity(PgHdr *pPg){ PCache *pCache; assert( pPg!=0 ); assert( pPg->pgno>0 || pPg->pPager==0 ); /* Page number is 1 or more */ @@ -52998,7 +52998,7 @@ SQLITE_PRIVATE int tdsqlite3PcachePageSanity(PgHdr *pPg){ assert( pPg->flags & PGHDR_DIRTY ); /* WRITEABLE implies DIRTY */ } /* NEED_SYNC can be set independently of WRITEABLE. This can happen, - ** for example, when using the tdsqlite3PagerDontWrite() optimization: + ** for example, when using the sqlite3PagerDontWrite() optimization: ** (1) Page X is journalled, and gets WRITEABLE and NEED_SEEK. ** (2) Page X moved to freelist, WRITEABLE is cleared ** (3) Page X reused, WRITEABLE is set again @@ -53057,7 +53057,7 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ pPage->pDirtyPrev->pDirtyNext = pPage->pDirtyNext; }else{ /* If there are now no dirty pages in the cache, set eCreate to 2. - ** This is an optimization that allows tdsqlite3PcacheFetch() to skip + ** This is an optimization that allows sqlite3PcacheFetch() to skip ** searching for a dirty page to eject from the cache when it might ** otherwise have to. */ assert( pPage==p->pDirty ); @@ -53087,7 +53087,7 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ /* If pSynced is NULL and this page has a clear NEED_SYNC flag, set ** pSynced to point to it. Checking the NEED_SYNC flag is an ** optimization, as if pSynced points to a page with the NEED_SYNC - ** flag set tdsqlite3PcacheFetchStress() searches through all newer + ** flag set sqlite3PcacheFetchStress() searches through all newer ** entries of the dirty-list for a page with NEED_SYNC clear anyway. */ if( !p->pSynced && 0==(pPage->flags&PGHDR_NEED_SYNC) /*OPTIMIZATION-IF-FALSE*/ @@ -53105,7 +53105,7 @@ static void pcacheManageDirtyList(PgHdr *pPage, u8 addRemove){ static void pcacheUnpin(PgHdr *p){ if( p->pCache->bPurgeable ){ pcacheTrace(("%p.UNPIN %d\n", p->pCache, p->pgno)); - tdsqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 0); pcacheDump(p->pCache); } } @@ -53133,33 +53133,33 @@ static int numberOfCachePages(PCache *p){ ** Initialize and shutdown the page cache subsystem. Neither of these ** functions are threadsafe. */ -SQLITE_PRIVATE int tdsqlite3PcacheInitialize(void){ - if( tdsqlite3GlobalConfig.pcache2.xInit==0 ){ +SQLITE_PRIVATE int sqlite3PcacheInitialize(void){ + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ /* IMPLEMENTATION-OF: R-26801-64137 If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache. */ - tdsqlite3PCacheSetDefault(); - assert( tdsqlite3GlobalConfig.pcache2.xInit!=0 ); + sqlite3PCacheSetDefault(); + assert( sqlite3GlobalConfig.pcache2.xInit!=0 ); } - return tdsqlite3GlobalConfig.pcache2.xInit(tdsqlite3GlobalConfig.pcache2.pArg); + return sqlite3GlobalConfig.pcache2.xInit(sqlite3GlobalConfig.pcache2.pArg); } -SQLITE_PRIVATE void tdsqlite3PcacheShutdown(void){ - if( tdsqlite3GlobalConfig.pcache2.xShutdown ){ +SQLITE_PRIVATE void sqlite3PcacheShutdown(void){ + if( sqlite3GlobalConfig.pcache2.xShutdown ){ /* IMPLEMENTATION-OF: R-26000-56589 The xShutdown() method may be NULL. */ - tdsqlite3GlobalConfig.pcache2.xShutdown(tdsqlite3GlobalConfig.pcache2.pArg); + sqlite3GlobalConfig.pcache2.xShutdown(sqlite3GlobalConfig.pcache2.pArg); } } /* ** Return the size in bytes of a PCache object. */ -SQLITE_PRIVATE int tdsqlite3PcacheSize(void){ return sizeof(PCache); } +SQLITE_PRIVATE int sqlite3PcacheSize(void){ return sizeof(PCache); } /* ** Create a new PCache object. Storage space to hold the object ** has already been allocated and is passed in as the p pointer. ** The caller discovers how much space needs to be allocated by -** calling tdsqlite3PcacheSize(). +** calling sqlite3PcacheSize(). ** ** szExtra is some extra space allocated for each page. The first ** 8 bytes of the extra space will be zeroed as the page is allocated, @@ -53167,7 +53167,7 @@ SQLITE_PRIVATE int tdsqlite3PcacheSize(void){ return sizeof(PCache); } ** to this module, the extra space really ends up being the MemPage ** structure in the pager. */ -SQLITE_PRIVATE int tdsqlite3PcacheOpen( +SQLITE_PRIVATE int sqlite3PcacheOpen( int szPage, /* Size of every page */ int szExtra, /* Extra space associated with each page */ int bPurgeable, /* True if pages are on backing store */ @@ -53186,25 +53186,25 @@ SQLITE_PRIVATE int tdsqlite3PcacheOpen( p->szCache = 100; p->szSpill = 1; pcacheTrace(("%p.OPEN szPage %d bPurgeable %d\n",p,szPage,bPurgeable)); - return tdsqlite3PcacheSetPageSize(p, szPage); + return sqlite3PcacheSetPageSize(p, szPage); } /* ** Change the page size for PCache object. The caller must ensure that there ** are no outstanding page references when this function is called. */ -SQLITE_PRIVATE int tdsqlite3PcacheSetPageSize(PCache *pCache, int szPage){ +SQLITE_PRIVATE int sqlite3PcacheSetPageSize(PCache *pCache, int szPage){ assert( pCache->nRefSum==0 && pCache->pDirty==0 ); if( pCache->szPage ){ - tdsqlite3_pcache *pNew; - pNew = tdsqlite3GlobalConfig.pcache2.xCreate( + sqlite3_pcache *pNew; + pNew = sqlite3GlobalConfig.pcache2.xCreate( szPage, pCache->szExtra + ROUND8(sizeof(PgHdr)), pCache->bPurgeable ); if( pNew==0 ) return SQLITE_NOMEM_BKPT; - tdsqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); + sqlite3GlobalConfig.pcache2.xCachesize(pNew, numberOfCachePages(pCache)); if( pCache->pCache ){ - tdsqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); } pCache->pCache = pNew; pCache->szPage = szPage; @@ -53216,7 +53216,7 @@ SQLITE_PRIVATE int tdsqlite3PcacheSetPageSize(PCache *pCache, int szPage){ /* ** Try to obtain a page from the cache. ** -** This routine returns a pointer to an tdsqlite3_pcache_page object if +** This routine returns a pointer to an sqlite3_pcache_page object if ** such an object is already in cache, or if a new one is created. ** This routine returns a NULL pointer if the object was not in cache ** and could not be created. @@ -53229,21 +53229,21 @@ SQLITE_PRIVATE int tdsqlite3PcacheSetPageSize(PCache *pCache, int szPage){ ** is created only if that can be done without spilling dirty pages ** and without exceeding the cache size limit. ** -** The caller needs to invoke tdsqlite3PcacheFetchFinish() to properly -** initialize the tdsqlite3_pcache_page object and convert it into a -** PgHdr object. The tdsqlite3PcacheFetch() and tdsqlite3PcacheFetchFinish() +** The caller needs to invoke sqlite3PcacheFetchFinish() to properly +** initialize the sqlite3_pcache_page object and convert it into a +** PgHdr object. The sqlite3PcacheFetch() and sqlite3PcacheFetchFinish() ** routines are split this way for performance reasons. When separated ** they can both (usually) operate without having to push values to ** the stack on entry and pop them back off on exit, which saves a ** lot of pushing and popping. */ -SQLITE_PRIVATE tdsqlite3_pcache_page *tdsqlite3PcacheFetch( +SQLITE_PRIVATE sqlite3_pcache_page *sqlite3PcacheFetch( PCache *pCache, /* Obtain the page from this cache */ Pgno pgno, /* Page number to obtain */ int createFlag /* If true, create page if it does not exist already */ ){ int eCreate; - tdsqlite3_pcache_page *pRes; + sqlite3_pcache_page *pRes; assert( pCache!=0 ); assert( pCache->pCache!=0 ); @@ -53261,14 +53261,14 @@ SQLITE_PRIVATE tdsqlite3_pcache_page *tdsqlite3PcacheFetch( assert( eCreate==0 || eCreate==1 || eCreate==2 ); assert( createFlag==0 || pCache->eCreate==eCreate ); assert( createFlag==0 || eCreate==1+(!pCache->bPurgeable||!pCache->pDirty) ); - pRes = tdsqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); + pRes = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, eCreate); pcacheTrace(("%p.FETCH %d%s (result: %p)\n",pCache,pgno, createFlag?" create":"",pRes)); return pRes; } /* -** If the tdsqlite3PcacheFetch() routine is unable to allocate a new +** If the sqlite3PcacheFetch() routine is unable to allocate a new ** page because no clean pages are available for reuse and the cache ** size limit has been reached, then this routine can be invoked to ** try harder to allocate a page. This routine might invoke the stress @@ -53276,17 +53276,17 @@ SQLITE_PRIVATE tdsqlite3_pcache_page *tdsqlite3PcacheFetch( ** allocate the new page and will only fail to allocate a new page on ** an OOM error. ** -** This routine should be invoked only after tdsqlite3PcacheFetch() fails. +** This routine should be invoked only after sqlite3PcacheFetch() fails. */ -SQLITE_PRIVATE int tdsqlite3PcacheFetchStress( +SQLITE_PRIVATE int sqlite3PcacheFetchStress( PCache *pCache, /* Obtain the page from this cache */ Pgno pgno, /* Page number to obtain */ - tdsqlite3_pcache_page **ppPage /* Write result here */ + sqlite3_pcache_page **ppPage /* Write result here */ ){ PgHdr *pPg; if( pCache->eCreate==2 ) return 0; - if( tdsqlite3PcachePagecount(pCache)>pCache->szSpill ){ + if( sqlite3PcachePagecount(pCache)>pCache->szSpill ){ /* Find a dirty page to write-out and recycle. First try to find a ** page that does not require a journal-sync (one with PGHDR_NEED_SYNC ** cleared), but if that is not possible settle for any other @@ -53307,10 +53307,10 @@ SQLITE_PRIVATE int tdsqlite3PcacheFetchStress( if( pPg ){ int rc; #ifdef SQLITE_LOG_CACHE_SPILL - tdsqlite3_log(SQLITE_FULL, + sqlite3_log(SQLITE_FULL, "spill page %d making room for %d - cache used: %d/%d", pPg->pgno, pgno, - tdsqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache), + sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache), numberOfCachePages(pCache)); #endif pcacheTrace(("%p.SPILL %d\n",pCache,pPg->pgno)); @@ -53321,12 +53321,12 @@ SQLITE_PRIVATE int tdsqlite3PcacheFetchStress( } } } - *ppPage = tdsqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); + *ppPage = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache, pgno, 2); return *ppPage==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; } /* -** This is a helper routine for tdsqlite3PcacheFetchFinish() +** This is a helper routine for sqlite3PcacheFetchFinish() ** ** In the uncommon case where the page being fetched has not been ** initialized, this routine is invoked to do the initialization. @@ -53337,7 +53337,7 @@ SQLITE_PRIVATE int tdsqlite3PcacheFetchStress( static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( PCache *pCache, /* Obtain the page from this cache */ Pgno pgno, /* Page number obtained */ - tdsqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ ){ PgHdr *pPgHdr; assert( pPage!=0 ); @@ -53351,19 +53351,19 @@ static SQLITE_NOINLINE PgHdr *pcacheFetchFinishWithInit( pPgHdr->pCache = pCache; pPgHdr->pgno = pgno; pPgHdr->flags = PGHDR_CLEAN; - return tdsqlite3PcacheFetchFinish(pCache,pgno,pPage); + return sqlite3PcacheFetchFinish(pCache,pgno,pPage); } /* -** This routine converts the tdsqlite3_pcache_page object returned by -** tdsqlite3PcacheFetch() into an initialized PgHdr object. This routine -** must be called after tdsqlite3PcacheFetch() in order to get a usable +** This routine converts the sqlite3_pcache_page object returned by +** sqlite3PcacheFetch() into an initialized PgHdr object. This routine +** must be called after sqlite3PcacheFetch() in order to get a usable ** result. */ -SQLITE_PRIVATE PgHdr *tdsqlite3PcacheFetchFinish( +SQLITE_PRIVATE PgHdr *sqlite3PcacheFetchFinish( PCache *pCache, /* Obtain the page from this cache */ Pgno pgno, /* Page number obtained */ - tdsqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ + sqlite3_pcache_page *pPage /* Page obtained by prior PcacheFetch() call */ ){ PgHdr *pPgHdr; @@ -53375,7 +53375,7 @@ SQLITE_PRIVATE PgHdr *tdsqlite3PcacheFetchFinish( } pCache->nRefSum++; pPgHdr->nRef++; - assert( tdsqlite3PcachePageSanity(pPgHdr) ); + assert( sqlite3PcachePageSanity(pPgHdr) ); return pPgHdr; } @@ -53383,7 +53383,7 @@ SQLITE_PRIVATE PgHdr *tdsqlite3PcacheFetchFinish( ** Decrement the reference count on a page. If the page is clean and the ** reference count drops to 0, then it is made eligible for recycling. */ -SQLITE_PRIVATE void SQLITE_NOINLINE tdsqlite3PcacheRelease(PgHdr *p){ +SQLITE_PRIVATE void SQLITE_NOINLINE sqlite3PcacheRelease(PgHdr *p){ assert( p->nRef>0 ); p->pCache->nRefSum--; if( (--p->nRef)==0 ){ @@ -53398,9 +53398,9 @@ SQLITE_PRIVATE void SQLITE_NOINLINE tdsqlite3PcacheRelease(PgHdr *p){ /* ** Increase the reference count of a supplied page by 1. */ -SQLITE_PRIVATE void tdsqlite3PcacheRef(PgHdr *p){ +SQLITE_PRIVATE void sqlite3PcacheRef(PgHdr *p){ assert(p->nRef>0); - assert( tdsqlite3PcachePageSanity(p) ); + assert( sqlite3PcachePageSanity(p) ); p->nRef++; p->pCache->nRefSum++; } @@ -53410,23 +53410,23 @@ SQLITE_PRIVATE void tdsqlite3PcacheRef(PgHdr *p){ ** page. This function deletes that reference, so after it returns the ** page pointed to by p is invalid. */ -SQLITE_PRIVATE void tdsqlite3PcacheDrop(PgHdr *p){ +SQLITE_PRIVATE void sqlite3PcacheDrop(PgHdr *p){ assert( p->nRef==1 ); - assert( tdsqlite3PcachePageSanity(p) ); + assert( sqlite3PcachePageSanity(p) ); if( p->flags&PGHDR_DIRTY ){ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); } p->pCache->nRefSum--; - tdsqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); + sqlite3GlobalConfig.pcache2.xUnpin(p->pCache->pCache, p->pPage, 1); } /* ** Make sure the page is marked as dirty. If it isn't dirty already, ** make it so. */ -SQLITE_PRIVATE void tdsqlite3PcacheMakeDirty(PgHdr *p){ +SQLITE_PRIVATE void sqlite3PcacheMakeDirty(PgHdr *p){ assert( p->nRef>0 ); - assert( tdsqlite3PcachePageSanity(p) ); + assert( sqlite3PcachePageSanity(p) ); if( p->flags & (PGHDR_CLEAN|PGHDR_DONT_WRITE) ){ /*OPTIMIZATION-IF-FALSE*/ p->flags &= ~PGHDR_DONT_WRITE; if( p->flags & PGHDR_CLEAN ){ @@ -53435,7 +53435,7 @@ SQLITE_PRIVATE void tdsqlite3PcacheMakeDirty(PgHdr *p){ assert( (p->flags & (PGHDR_DIRTY|PGHDR_CLEAN))==PGHDR_DIRTY ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_ADD); } - assert( tdsqlite3PcachePageSanity(p) ); + assert( sqlite3PcachePageSanity(p) ); } } @@ -53443,15 +53443,15 @@ SQLITE_PRIVATE void tdsqlite3PcacheMakeDirty(PgHdr *p){ ** Make sure the page is marked as clean. If it isn't clean already, ** make it so. */ -SQLITE_PRIVATE void tdsqlite3PcacheMakeClean(PgHdr *p){ - assert( tdsqlite3PcachePageSanity(p) ); +SQLITE_PRIVATE void sqlite3PcacheMakeClean(PgHdr *p){ + assert( sqlite3PcachePageSanity(p) ); assert( (p->flags & PGHDR_DIRTY)!=0 ); assert( (p->flags & PGHDR_CLEAN)==0 ); pcacheManageDirtyList(p, PCACHE_DIRTYLIST_REMOVE); p->flags &= ~(PGHDR_DIRTY|PGHDR_NEED_SYNC|PGHDR_WRITEABLE); p->flags |= PGHDR_CLEAN; pcacheTrace(("%p.CLEAN %d\n",p->pCache,p->pgno)); - assert( tdsqlite3PcachePageSanity(p) ); + assert( sqlite3PcachePageSanity(p) ); if( p->nRef==0 ){ pcacheUnpin(p); } @@ -53460,18 +53460,18 @@ SQLITE_PRIVATE void tdsqlite3PcacheMakeClean(PgHdr *p){ /* ** Make every page in the cache clean. */ -SQLITE_PRIVATE void tdsqlite3PcacheCleanAll(PCache *pCache){ +SQLITE_PRIVATE void sqlite3PcacheCleanAll(PCache *pCache){ PgHdr *p; pcacheTrace(("%p.CLEAN-ALL\n",pCache)); while( (p = pCache->pDirty)!=0 ){ - tdsqlite3PcacheMakeClean(p); + sqlite3PcacheMakeClean(p); } } /* ** Clear the PGHDR_NEED_SYNC and PGHDR_WRITEABLE flag from all dirty pages. */ -SQLITE_PRIVATE void tdsqlite3PcacheClearWritable(PCache *pCache){ +SQLITE_PRIVATE void sqlite3PcacheClearWritable(PCache *pCache){ PgHdr *p; pcacheTrace(("%p.CLEAR-WRITEABLE\n",pCache)); for(p=pCache->pDirty; p; p=p->pDirtyNext){ @@ -53483,7 +53483,7 @@ SQLITE_PRIVATE void tdsqlite3PcacheClearWritable(PCache *pCache){ /* ** Clear the PGHDR_NEED_SYNC flag from all dirty pages. */ -SQLITE_PRIVATE void tdsqlite3PcacheClearSyncFlags(PCache *pCache){ +SQLITE_PRIVATE void sqlite3PcacheClearSyncFlags(PCache *pCache){ PgHdr *p; for(p=pCache->pDirty; p; p=p->pDirtyNext){ p->flags &= ~PGHDR_NEED_SYNC; @@ -53494,13 +53494,13 @@ SQLITE_PRIVATE void tdsqlite3PcacheClearSyncFlags(PCache *pCache){ /* ** Change the page number of page p to newPgno. */ -SQLITE_PRIVATE void tdsqlite3PcacheMove(PgHdr *p, Pgno newPgno){ +SQLITE_PRIVATE void sqlite3PcacheMove(PgHdr *p, Pgno newPgno){ PCache *pCache = p->pCache; assert( p->nRef>0 ); assert( newPgno>0 ); - assert( tdsqlite3PcachePageSanity(p) ); + assert( sqlite3PcachePageSanity(p) ); pcacheTrace(("%p.MOVE %d -> %d\n",pCache,p->pgno,newPgno)); - tdsqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); + sqlite3GlobalConfig.pcache2.xRekey(pCache->pCache, p->pPage, p->pgno,newPgno); p->pgno = newPgno; if( (p->flags&PGHDR_DIRTY) && (p->flags&PGHDR_NEED_SYNC) ){ pcacheManageDirtyList(p, PCACHE_DIRTYLIST_FRONT); @@ -53516,7 +53516,7 @@ SQLITE_PRIVATE void tdsqlite3PcacheMove(PgHdr *p, Pgno newPgno){ ** function is 0, then the data area associated with page 1 is zeroed, but ** the page object is not dropped. */ -SQLITE_PRIVATE void tdsqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ +SQLITE_PRIVATE void sqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ if( pCache->pCache ){ PgHdr *p; PgHdr *pNext; @@ -53524,42 +53524,42 @@ SQLITE_PRIVATE void tdsqlite3PcacheTruncate(PCache *pCache, Pgno pgno){ for(p=pCache->pDirty; p; p=pNext){ pNext = p->pDirtyNext; /* This routine never gets call with a positive pgno except right - ** after tdsqlite3PcacheCleanAll(). So if there are dirty pages, + ** after sqlite3PcacheCleanAll(). So if there are dirty pages, ** it must be that pgno==0. */ assert( p->pgno>0 ); if( p->pgno>pgno ){ assert( p->flags&PGHDR_DIRTY ); - tdsqlite3PcacheMakeClean(p); + sqlite3PcacheMakeClean(p); } } if( pgno==0 && pCache->nRefSum ){ - tdsqlite3_pcache_page *pPage1; - pPage1 = tdsqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0); + sqlite3_pcache_page *pPage1; + pPage1 = sqlite3GlobalConfig.pcache2.xFetch(pCache->pCache,1,0); if( ALWAYS(pPage1) ){ /* Page 1 is always available in cache, because ** pCache->nRefSum>0 */ memset(pPage1->pBuf, 0, pCache->szPage); pgno = 1; } } - tdsqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); + sqlite3GlobalConfig.pcache2.xTruncate(pCache->pCache, pgno+1); } } /* ** Close a cache. */ -SQLITE_PRIVATE void tdsqlite3PcacheClose(PCache *pCache){ +SQLITE_PRIVATE void sqlite3PcacheClose(PCache *pCache){ assert( pCache->pCache!=0 ); pcacheTrace(("%p.CLOSE\n",pCache)); - tdsqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); + sqlite3GlobalConfig.pcache2.xDestroy(pCache->pCache); } /* ** Discard the contents of the cache. */ -SQLITE_PRIVATE void tdsqlite3PcacheClear(PCache *pCache){ - tdsqlite3PcacheTruncate(pCache, 0); +SQLITE_PRIVATE void sqlite3PcacheClear(PCache *pCache){ + sqlite3PcacheTruncate(pCache, 0); } /* @@ -53638,7 +53638,7 @@ static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ /* ** Return a list of all dirty pages in the cache, sorted by page number. */ -SQLITE_PRIVATE PgHdr *tdsqlite3PcacheDirtyList(PCache *pCache){ +SQLITE_PRIVATE PgHdr *sqlite3PcacheDirtyList(PCache *pCache){ PgHdr *p; for(p=pCache->pDirty; p; p=p->pDirtyNext){ p->pDirty = p->pDirtyNext; @@ -53652,30 +53652,30 @@ SQLITE_PRIVATE PgHdr *tdsqlite3PcacheDirtyList(PCache *pCache){ ** This is not the total number of pages referenced, but the sum of the ** reference count for all pages. */ -SQLITE_PRIVATE int tdsqlite3PcacheRefCount(PCache *pCache){ +SQLITE_PRIVATE int sqlite3PcacheRefCount(PCache *pCache){ return pCache->nRefSum; } /* ** Return the number of references to the page supplied as an argument. */ -SQLITE_PRIVATE int tdsqlite3PcachePageRefcount(PgHdr *p){ +SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr *p){ return p->nRef; } /* ** Return the total number of pages in the cache. */ -SQLITE_PRIVATE int tdsqlite3PcachePagecount(PCache *pCache){ +SQLITE_PRIVATE int sqlite3PcachePagecount(PCache *pCache){ assert( pCache->pCache!=0 ); - return tdsqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); + return sqlite3GlobalConfig.pcache2.xPagecount(pCache->pCache); } #ifdef SQLITE_TEST /* ** Get the suggested cache-size value. */ -SQLITE_PRIVATE int tdsqlite3PcacheGetCachesize(PCache *pCache){ +SQLITE_PRIVATE int sqlite3PcacheGetCachesize(PCache *pCache){ return numberOfCachePages(pCache); } #endif @@ -53683,10 +53683,10 @@ SQLITE_PRIVATE int tdsqlite3PcacheGetCachesize(PCache *pCache){ /* ** Set the suggested cache-size value. */ -SQLITE_PRIVATE void tdsqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ +SQLITE_PRIVATE void sqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ assert( pCache->pCache!=0 ); pCache->szCache = mxPage; - tdsqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, + sqlite3GlobalConfig.pcache2.xCachesize(pCache->pCache, numberOfCachePages(pCache)); } @@ -53695,7 +53695,7 @@ SQLITE_PRIVATE void tdsqlite3PcacheSetCachesize(PCache *pCache, int mxPage){ ** argument is zero. Return the effective cache-spill size, which will ** be the larger of the szSpill and szCache. */ -SQLITE_PRIVATE int tdsqlite3PcacheSetSpillsize(PCache *p, int mxPage){ +SQLITE_PRIVATE int sqlite3PcacheSetSpillsize(PCache *p, int mxPage){ int res; assert( p->pCache!=0 ); if( mxPage ){ @@ -53712,22 +53712,22 @@ SQLITE_PRIVATE int tdsqlite3PcacheSetSpillsize(PCache *p, int mxPage){ /* ** Free up as much memory as possible from the page cache. */ -SQLITE_PRIVATE void tdsqlite3PcacheShrink(PCache *pCache){ +SQLITE_PRIVATE void sqlite3PcacheShrink(PCache *pCache){ assert( pCache->pCache!=0 ); - tdsqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); + sqlite3GlobalConfig.pcache2.xShrink(pCache->pCache); } /* ** Return the size of the header added by this middleware layer ** in the page-cache hierarchy. */ -SQLITE_PRIVATE int tdsqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); } +SQLITE_PRIVATE int sqlite3HeaderSizePcache(void){ return ROUND8(sizeof(PgHdr)); } /* ** Return the number of dirty pages currently in the cache, as a percentage ** of the configured cache size. */ -SQLITE_PRIVATE int tdsqlite3PCachePercentDirty(PCache *pCache){ +SQLITE_PRIVATE int sqlite3PCachePercentDirty(PCache *pCache){ PgHdr *pDirty; int nDirty = 0; int nCache = numberOfCachePages(pCache); @@ -53739,7 +53739,7 @@ SQLITE_PRIVATE int tdsqlite3PCachePercentDirty(PCache *pCache){ /* ** Return true if there are one or more dirty pages in the cache. Else false. */ -SQLITE_PRIVATE int tdsqlite3PCacheIsDirty(PCache *pCache){ +SQLITE_PRIVATE int sqlite3PCacheIsDirty(PCache *pCache){ return (pCache->pDirty!=0); } #endif @@ -53750,7 +53750,7 @@ SQLITE_PRIVATE int tdsqlite3PCacheIsDirty(PCache *pCache){ ** callback. This is only used if the SQLITE_CHECK_PAGES macro is ** defined. */ -SQLITE_PRIVATE void tdsqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ +SQLITE_PRIVATE void sqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(PgHdr *)){ PgHdr *pDirty; for(pDirty=pCache->pDirty; pDirty; pDirty=pDirty->pDirtyNext){ xIter(pDirty); @@ -53773,8 +53773,8 @@ SQLITE_PRIVATE void tdsqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(Pg ************************************************************************* ** ** This file implements the default page cache implementation (the -** tdsqlite3_pcache interface). It also contains part of the implementation -** of the SQLITE_CONFIG_PAGECACHE and tdsqlite3_release_memory() features. +** sqlite3_pcache interface). It also contains part of the implementation +** of the SQLITE_CONFIG_PAGECACHE and sqlite3_release_memory() features. ** If the default page cache implementation is overridden, then neither of ** these two features are available. ** @@ -53790,13 +53790,13 @@ SQLITE_PRIVATE void tdsqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(Pg ** as the database page number and how that database page is used. PgHdr ** is added by the pcache.c layer and contains information used to keep track ** of which pages are "dirty". PgHdr1 is an extension added by this -** module (pcache1.c). The PgHdr1 header is a subclass of tdsqlite3_pcache_page. +** module (pcache1.c). The PgHdr1 header is a subclass of sqlite3_pcache_page. ** PgHdr1 contains information needed to look up a page by its page number. -** The superclass tdsqlite3_pcache_page.pBuf points to the start of the -** database page content and tdsqlite3_pcache_page.pExtra points to PgHdr. +** The superclass sqlite3_pcache_page.pBuf points to the start of the +** database page content and sqlite3_pcache_page.pExtra points to PgHdr. ** ** The size of the extension (MemPage+PgHdr+PgHdr1) can be determined at -** runtime using tdsqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size). The +** runtime using sqlite3_config(SQLITE_CONFIG_PCACHE_HDRSZ, &size). The ** sizes of the extensions sum to 272 bytes on x64 for 3.8.10, but this ** size can vary according to architecture, compile-time options, and ** SQLite library version number. @@ -53818,8 +53818,8 @@ SQLITE_PRIVATE void tdsqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(Pg ** ** Memory for a page might come from any of three sources: ** -** (1) The general-purpose memory allocator - tdsqlite3Malloc() -** (2) Global page-cache memory provided using tdsqlite3_config() with +** (1) The general-purpose memory allocator - sqlite3Malloc() +** (2) Global page-cache memory provided using sqlite3_config() with ** SQLITE_CONFIG_PAGECACHE. ** (3) PCache-local bulk allocation. ** @@ -53827,10 +53827,10 @@ SQLITE_PRIVATE void tdsqlite3PcacheIterateDirty(PCache *pCache, void (*xIter)(Pg ** that is allocated when the page cache is created. The size of the local ** bulk allocation can be adjusted using ** -** tdsqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N). +** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N). ** ** If N is positive, then N pages worth of memory are allocated using a single -** tdsqlite3Malloc() call and that memory is used for the first N pages allocated. +** sqlite3Malloc() call and that memory is used for the first N pages allocated. ** Or if N is negative, then -1024*N bytes of memory are allocated and used ** for as many pages as can be accomodated. ** @@ -53866,7 +53866,7 @@ typedef struct PGroup PGroup; ** in the structure. */ struct PgHdr1 { - tdsqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ + sqlite3_pcache_page page; /* Base class. Must be first. pBuf & pExtra */ unsigned int iKey; /* Key value (page number) */ u16 isBulkLocal; /* This page from bulk local storage */ u16 isAnchor; /* This is the PGroup.lru element */ @@ -53907,7 +53907,7 @@ struct PgHdr1 { ** SQLITE_MUTEX_STATIC_LRU. */ struct PGroup { - tdsqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ + sqlite3_mutex *mutex; /* MUTEX_STATIC_LRU or NULL */ unsigned int nMaxPage; /* Sum of nMax for purgeable caches */ unsigned int nMinPage; /* Sum of nMin for purgeable caches */ unsigned int mxPinned; /* nMaxpage + 10 - nMinPage */ @@ -53921,7 +53921,7 @@ struct PGroup { ** is an instance of this object. ** ** Pointers to structures of this type are cast and returned as -** opaque tdsqlite3_pcache* handles. +** opaque sqlite3_pcache* handles. */ struct PCache1 { /* Cache configuration parameters. Page size (szPage) and the purgeable @@ -53969,7 +53969,7 @@ static SQLITE_WSD struct PCacheGlobal { /* Variables related to SQLITE_CONFIG_PAGECACHE settings. The ** szSlot, nSlot, pStart, pEnd, nReserve, and isInit values are all - ** fixed at tdsqlite3_initialize() time and do not require mutex protection. + ** fixed at sqlite3_initialize() time and do not require mutex protection. ** The nFreeSlot and pFree values do require mutex protection. */ int isInit; /* True if initialized */ @@ -53980,7 +53980,7 @@ static SQLITE_WSD struct PCacheGlobal { int nReserve; /* Try to keep nFreeSlot above this */ void *pStart, *pEnd; /* Bounds of global page cache memory */ /* Above requires no mutex. Use mutex below for variable that follow. */ - tdsqlite3_mutex *mutex; /* Mutex for accessing the following: */ + sqlite3_mutex *mutex; /* Mutex for accessing the following: */ PgFreeslot *pFree; /* Free page blocks */ int nFreeSlot; /* Number of unused pcache slots */ /* The following value requires a mutex to change. We skip the mutex on @@ -54005,8 +54005,8 @@ static SQLITE_WSD struct PCacheGlobal { # define pcache1LeaveMutex(X) assert((X)->mutex==0) # define PCACHE1_MIGHT_USE_GROUP_MUTEX 0 #else -# define pcache1EnterMutex(X) tdsqlite3_mutex_enter((X)->mutex) -# define pcache1LeaveMutex(X) tdsqlite3_mutex_leave((X)->mutex) +# define pcache1EnterMutex(X) sqlite3_mutex_enter((X)->mutex) +# define pcache1LeaveMutex(X) sqlite3_mutex_leave((X)->mutex) # define PCACHE1_MIGHT_USE_GROUP_MUTEX 1 #endif @@ -54017,13 +54017,13 @@ static SQLITE_WSD struct PCacheGlobal { /* ** This function is called during initialization if a static buffer is ** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE -** verb to tdsqlite3_config(). Parameter pBuf points to an allocation large +** verb to sqlite3_config(). Parameter pBuf points to an allocation large ** enough to contain 'n' buffers of 'sz' bytes each. ** -** This routine is called from tdsqlite3_initialize() and so it is guaranteed +** This routine is called from sqlite3_initialize() and so it is guaranteed ** to be serialized already. There is no need for further mutexing. */ -SQLITE_PRIVATE void tdsqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ +SQLITE_PRIVATE void sqlite3PCacheBufferSetup(void *pBuf, int sz, int n){ if( pcache1.isInit ){ PgFreeslot *p; if( pBuf==0 ) sz = n = 0; @@ -54055,7 +54055,7 @@ static int pcache1InitBulk(PCache1 *pCache){ if( pcache1.nInitPage==0 ) return 0; /* Do not bother with a bulk allocation if the cache size very small */ if( pCache->nMax<3 ) return 0; - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); if( pcache1.nInitPage>0 ){ szBulk = pCache->szAlloc * (i64)pcache1.nInitPage; }else{ @@ -54064,10 +54064,10 @@ static int pcache1InitBulk(PCache1 *pCache){ if( szBulk > pCache->szAlloc*(i64)pCache->nMax ){ szBulk = pCache->szAlloc*(i64)pCache->nMax; } - zBulk = pCache->pBulk = tdsqlite3Malloc( szBulk ); - tdsqlite3EndBenignMalloc(); + zBulk = pCache->pBulk = sqlite3Malloc( szBulk ); + sqlite3EndBenignMalloc(); if( zBulk ){ - int nBulk = tdsqlite3MallocSize(zBulk)/pCache->szAlloc; + int nBulk = sqlite3MallocSize(zBulk)/pCache->szAlloc; do{ PgHdr1 *pX = (PgHdr1*)&zBulk[pCache->szPage]; pX->page.pBuf = zBulk; @@ -54085,44 +54085,44 @@ static int pcache1InitBulk(PCache1 *pCache){ /* ** Malloc function used within this file to allocate space from the buffer -** configured using tdsqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no +** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no ** such buffer exists or there is no space left in it, this function falls -** back to tdsqlite3Malloc(). +** back to sqlite3Malloc(). ** ** Multiple threads can run this routine at the same time. Global variables ** in pcache1 need to be protected via mutex. */ static void *pcache1Alloc(int nByte){ void *p = 0; - assert( tdsqlite3_mutex_notheld(pcache1.grp.mutex) ); + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); if( nByte<=pcache1.szSlot ){ - tdsqlite3_mutex_enter(pcache1.mutex); + sqlite3_mutex_enter(pcache1.mutex); p = (PgHdr1 *)pcache1.pFree; if( p ){ pcache1.pFree = pcache1.pFree->pNext; pcache1.nFreeSlot--; pcache1.bUnderPressure = pcache1.nFreeSlot=0 ); - tdsqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); - tdsqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); + sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_USED, 1); } - tdsqlite3_mutex_leave(pcache1.mutex); + sqlite3_mutex_leave(pcache1.mutex); } if( p==0 ){ /* Memory is not available in the SQLITE_CONFIG_PAGECACHE pool. Get - ** it from tdsqlite3Malloc instead. + ** it from sqlite3Malloc instead. */ - p = tdsqlite3Malloc(nByte); + p = sqlite3Malloc(nByte); #ifndef SQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS if( p ){ - int sz = tdsqlite3MallocSize(p); - tdsqlite3_mutex_enter(pcache1.mutex); - tdsqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); - tdsqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); - tdsqlite3_mutex_leave(pcache1.mutex); + int sz = sqlite3MallocSize(p); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusHighwater(SQLITE_STATUS_PAGECACHE_SIZE, nByte); + sqlite3StatusUp(SQLITE_STATUS_PAGECACHE_OVERFLOW, sz); + sqlite3_mutex_leave(pcache1.mutex); } #endif - tdsqlite3MemdebugSetType(p, MEMTYPE_PCACHE); + sqlite3MemdebugSetType(p, MEMTYPE_PCACHE); } return p; } @@ -54134,28 +54134,28 @@ static void pcache1Free(void *p){ if( p==0 ) return; if( SQLITE_WITHIN(p, pcache1.pStart, pcache1.pEnd) ){ PgFreeslot *pSlot; - tdsqlite3_mutex_enter(pcache1.mutex); - tdsqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); + sqlite3_mutex_enter(pcache1.mutex); + sqlite3StatusDown(SQLITE_STATUS_PAGECACHE_USED, 1); pSlot = (PgFreeslot*)p; pSlot->pNext = pcache1.pFree; pcache1.pFree = pSlot; pcache1.nFreeSlot++; pcache1.bUnderPressure = pcache1.nFreeSlotpGroup->mutex) ); + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); if( pCache->pFree || (pCache->nPage==0 && pcache1InitBulk(pCache)) ){ assert( pCache->pFree!=0 ); p = pCache->pFree; @@ -54193,25 +54193,25 @@ static PgHdr1 *pcache1AllocPage(PCache1 *pCache, int benignMalloc){ }else{ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* The group mutex must be released before pcache1Alloc() is called. This - ** is because it might call tdsqlite3_release_memory(), which assumes that + ** is because it might call sqlite3_release_memory(), which assumes that ** this mutex is not held. */ assert( pcache1.separateCache==0 ); assert( pCache->pGroup==&pcache1.grp ); pcache1LeaveMutex(pCache->pGroup); #endif - if( benignMalloc ){ tdsqlite3BeginBenignMalloc(); } + if( benignMalloc ){ sqlite3BeginBenignMalloc(); } #ifdef SQLITE_PCACHE_SEPARATE_HEADER pPg = pcache1Alloc(pCache->szPage); - p = tdsqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); + p = sqlite3Malloc(sizeof(PgHdr1) + pCache->szExtra); if( !pPg || !p ){ pcache1Free(pPg); - tdsqlite3_free(p); + sqlite3_free(p); pPg = 0; } #else pPg = pcache1Alloc(pCache->szAlloc); #endif - if( benignMalloc ){ tdsqlite3EndBenignMalloc(); } + if( benignMalloc ){ sqlite3EndBenignMalloc(); } #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT pcache1EnterMutex(pCache->pGroup); #endif @@ -54235,14 +54235,14 @@ static void pcache1FreePage(PgHdr1 *p){ PCache1 *pCache; assert( p!=0 ); pCache = p->pCache; - assert( tdsqlite3_mutex_held(p->pCache->pGroup->mutex) ); + assert( sqlite3_mutex_held(p->pCache->pGroup->mutex) ); if( p->isBulkLocal ){ p->pNext = pCache->pFree; pCache->pFree = p; }else{ pcache1Free(p->page.pBuf); #ifdef SQLITE_PCACHE_SEPARATE_HEADER - tdsqlite3_free(p); + sqlite3_free(p); #endif } (*pCache->pnPurgeable)--; @@ -54250,18 +54250,18 @@ static void pcache1FreePage(PgHdr1 *p){ /* ** Malloc function used by SQLite to obtain space from the buffer configured -** using tdsqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer -** exists, this function falls back to tdsqlite3Malloc(). +** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer +** exists, this function falls back to sqlite3Malloc(). */ -SQLITE_PRIVATE void *tdsqlite3PageMalloc(int sz){ +SQLITE_PRIVATE void *sqlite3PageMalloc(int sz){ assert( sz<=65536+8 ); /* These allocations are never very large */ return pcache1Alloc(sz); } /* -** Free an allocated buffer obtained from tdsqlite3PageMalloc(). +** Free an allocated buffer obtained from sqlite3PageMalloc(). */ -SQLITE_PRIVATE void tdsqlite3PageFree(void *p){ +SQLITE_PRIVATE void sqlite3PageFree(void *p){ pcache1Free(p); } @@ -54286,7 +54286,7 @@ static int pcache1UnderMemoryPressure(PCache1 *pCache){ if( pcache1.nSlot && (pCache->szPage+pCache->szExtra)<=pcache1.szSlot ){ return pcache1.bUnderPressure; }else{ - return tdsqlite3HeapNearlyFull(); + return sqlite3HeapNearlyFull(); } } @@ -54304,7 +54304,7 @@ static void pcache1ResizeHash(PCache1 *p){ unsigned int nNew; unsigned int i; - assert( tdsqlite3_mutex_held(p->pGroup->mutex) ); + assert( sqlite3_mutex_held(p->pGroup->mutex) ); nNew = p->nHash*2; if( nNew<256 ){ @@ -54312,9 +54312,9 @@ static void pcache1ResizeHash(PCache1 *p){ } pcache1LeaveMutex(p->pGroup); - if( p->nHash ){ tdsqlite3BeginBenignMalloc(); } - apNew = (PgHdr1 **)tdsqlite3MallocZero(sizeof(PgHdr1 *)*nNew); - if( p->nHash ){ tdsqlite3EndBenignMalloc(); } + if( p->nHash ){ sqlite3BeginBenignMalloc(); } + apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); + if( p->nHash ){ sqlite3EndBenignMalloc(); } pcache1EnterMutex(p->pGroup); if( apNew ){ for(i=0; inHash; i++){ @@ -54327,7 +54327,7 @@ static void pcache1ResizeHash(PCache1 *p){ apNew[h] = pPage; } } - tdsqlite3_free(p->apHash); + sqlite3_free(p->apHash); p->apHash = apNew; p->nHash = nNew; } @@ -54345,7 +54345,7 @@ static PgHdr1 *pcache1PinPage(PgHdr1 *pPage){ assert( PAGE_IS_UNPINNED(pPage) ); assert( pPage->pLruNext ); assert( pPage->pLruPrev ); - assert( tdsqlite3_mutex_held(pPage->pCache->pGroup->mutex) ); + assert( sqlite3_mutex_held(pPage->pCache->pGroup->mutex) ); pPage->pLruPrev->pLruNext = pPage->pLruNext; pPage->pLruNext->pLruPrev = pPage->pLruPrev; pPage->pLruNext = 0; @@ -54370,7 +54370,7 @@ static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){ PCache1 *pCache = pPage->pCache; PgHdr1 **pp; - assert( tdsqlite3_mutex_held(pCache->pGroup->mutex) ); + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); h = pPage->iKey % pCache->nHash; for(pp=&pCache->apHash[h]; (*pp)!=pPage; pp=&(*pp)->pNext); *pp = (*pp)->pNext; @@ -54386,7 +54386,7 @@ static void pcache1RemoveFromHash(PgHdr1 *pPage, int freeFlag){ static void pcache1EnforceMaxPage(PCache1 *pCache){ PGroup *pGroup = pCache->pGroup; PgHdr1 *p; - assert( tdsqlite3_mutex_held(pGroup->mutex) ); + assert( sqlite3_mutex_held(pGroup->mutex) ); while( pGroup->nPurgeable>pGroup->nMaxPage && (p=pGroup->lru.pLruPrev)->isAnchor==0 ){ @@ -54396,7 +54396,7 @@ static void pcache1EnforceMaxPage(PCache1 *pCache){ pcache1RemoveFromHash(p, 1); } if( pCache->nPage==0 && pCache->pBulk ){ - tdsqlite3_free(pCache->pBulk); + sqlite3_free(pCache->pBulk); pCache->pBulk = pCache->pFree = 0; } } @@ -54414,7 +54414,7 @@ static void pcache1TruncateUnsafe( ){ TESTONLY( int nPage = 0; ) /* To assert pCache->nPage is correct */ unsigned int h, iStop; - assert( tdsqlite3_mutex_held(pCache->pGroup->mutex) ); + assert( sqlite3_mutex_held(pCache->pGroup->mutex) ); assert( pCache->iMaxKey >= iLimit ); assert( pCache->nHash > 0 ); if( pCache->iMaxKey - iLimit < pCache->nHash ){ @@ -54454,10 +54454,10 @@ static void pcache1TruncateUnsafe( } /******************************************************************************/ -/******** tdsqlite3_pcache Methods **********************************************/ +/******** sqlite3_pcache Methods **********************************************/ /* -** Implementation of the tdsqlite3_pcache.xInit method. +** Implementation of the sqlite3_pcache.xInit method. */ static int pcache1Init(void *NotUsed){ UNUSED_PARAMETER(NotUsed); @@ -54474,7 +54474,7 @@ static int pcache1Init(void *NotUsed){ ** ** * Use a unified cache in single-threaded applications that have ** configured a start-time buffer for use as page-cache memory using - ** tdsqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL + ** sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL ** pBuf argument. ** ** * Otherwise use separate caches (mode-1) @@ -54482,23 +54482,23 @@ static int pcache1Init(void *NotUsed){ #if defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) pcache1.separateCache = 0; #elif SQLITE_THREADSAFE - pcache1.separateCache = tdsqlite3GlobalConfig.pPage==0 - || tdsqlite3GlobalConfig.bCoreMutex>0; + pcache1.separateCache = sqlite3GlobalConfig.pPage==0 + || sqlite3GlobalConfig.bCoreMutex>0; #else - pcache1.separateCache = tdsqlite3GlobalConfig.pPage==0; + pcache1.separateCache = sqlite3GlobalConfig.pPage==0; #endif #if SQLITE_THREADSAFE - if( tdsqlite3GlobalConfig.bCoreMutex ){ - pcache1.grp.mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU); - pcache1.mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM); + if( sqlite3GlobalConfig.bCoreMutex ){ + pcache1.grp.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU); + pcache1.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PMEM); } #endif if( pcache1.separateCache - && tdsqlite3GlobalConfig.nPage!=0 - && tdsqlite3GlobalConfig.pPage==0 + && sqlite3GlobalConfig.nPage!=0 + && sqlite3GlobalConfig.pPage==0 ){ - pcache1.nInitPage = tdsqlite3GlobalConfig.nPage; + pcache1.nInitPage = sqlite3GlobalConfig.nPage; }else{ pcache1.nInitPage = 0; } @@ -54508,7 +54508,7 @@ static int pcache1Init(void *NotUsed){ } /* -** Implementation of the tdsqlite3_pcache.xShutdown method. +** Implementation of the sqlite3_pcache.xShutdown method. ** Note that the static mutex allocated in xInit does ** not need to be freed. */ @@ -54519,14 +54519,14 @@ static void pcache1Shutdown(void *NotUsed){ } /* forward declaration */ -static void pcache1Destroy(tdsqlite3_pcache *p); +static void pcache1Destroy(sqlite3_pcache *p); /* -** Implementation of the tdsqlite3_pcache.xCreate method. +** Implementation of the sqlite3_pcache.xCreate method. ** ** Allocate a new cache. */ -static tdsqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ +static sqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ PCache1 *pCache; /* The newly created page cache */ PGroup *pGroup; /* The group the new page cache will belong to */ int sz; /* Bytes of memory required to allocate the new cache */ @@ -54535,7 +54535,7 @@ static tdsqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ assert( szExtra < 300 ); sz = sizeof(PCache1) + sizeof(PGroup)*pcache1.separateCache; - pCache = (PCache1 *)tdsqlite3MallocZero(sz); + pCache = (PCache1 *)sqlite3MallocZero(sz); if( pCache ){ if( pcache1.separateCache ){ pGroup = (PGroup*)&pCache[1]; @@ -54564,19 +54564,19 @@ static tdsqlite3_pcache *pcache1Create(int szPage, int szExtra, int bPurgeable){ } pcache1LeaveMutex(pGroup); if( pCache->nHash==0 ){ - pcache1Destroy((tdsqlite3_pcache*)pCache); + pcache1Destroy((sqlite3_pcache*)pCache); pCache = 0; } } - return (tdsqlite3_pcache *)pCache; + return (sqlite3_pcache *)pCache; } /* -** Implementation of the tdsqlite3_pcache.xCachesize method. +** Implementation of the sqlite3_pcache.xCachesize method. ** ** Configure the cache_size limit for a cache. */ -static void pcache1Cachesize(tdsqlite3_pcache *p, int nMax){ +static void pcache1Cachesize(sqlite3_pcache *p, int nMax){ PCache1 *pCache = (PCache1 *)p; if( pCache->bPurgeable ){ PGroup *pGroup = pCache->pGroup; @@ -54591,11 +54591,11 @@ static void pcache1Cachesize(tdsqlite3_pcache *p, int nMax){ } /* -** Implementation of the tdsqlite3_pcache.xShrink method. +** Implementation of the sqlite3_pcache.xShrink method. ** ** Free up as much memory as possible. */ -static void pcache1Shrink(tdsqlite3_pcache *p){ +static void pcache1Shrink(sqlite3_pcache *p){ PCache1 *pCache = (PCache1*)p; if( pCache->bPurgeable ){ PGroup *pGroup = pCache->pGroup; @@ -54610,9 +54610,9 @@ static void pcache1Shrink(tdsqlite3_pcache *p){ } /* -** Implementation of the tdsqlite3_pcache.xPagecount method. +** Implementation of the sqlite3_pcache.xPagecount method. */ -static int pcache1Pagecount(tdsqlite3_pcache *p){ +static int pcache1Pagecount(sqlite3_pcache *p){ int n; PCache1 *pCache = (PCache1*)p; pcache1EnterMutex(pCache->pGroup); @@ -54700,7 +54700,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( } /* -** Implementation of the tdsqlite3_pcache.xFetch method. +** Implementation of the sqlite3_pcache.xFetch method. ** ** Fetch a page by key value. ** @@ -54759,7 +54759,7 @@ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( ** invokes the appropriate routine. */ static PgHdr1 *pcache1FetchNoMutex( - tdsqlite3_pcache *p, + sqlite3_pcache *p, unsigned int iKey, int createFlag ){ @@ -54789,7 +54789,7 @@ static PgHdr1 *pcache1FetchNoMutex( } #if PCACHE1_MIGHT_USE_GROUP_MUTEX static PgHdr1 *pcache1FetchWithMutex( - tdsqlite3_pcache *p, + sqlite3_pcache *p, unsigned int iKey, int createFlag ){ @@ -54803,8 +54803,8 @@ static PgHdr1 *pcache1FetchWithMutex( return pPage; } #endif -static tdsqlite3_pcache_page *pcache1Fetch( - tdsqlite3_pcache *p, +static sqlite3_pcache_page *pcache1Fetch( + sqlite3_pcache *p, unsigned int iKey, int createFlag ){ @@ -54820,23 +54820,23 @@ static tdsqlite3_pcache_page *pcache1Fetch( assert( pCache->nHash>0 ); #if PCACHE1_MIGHT_USE_GROUP_MUTEX if( pCache->pGroup->mutex ){ - return (tdsqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag); + return (sqlite3_pcache_page*)pcache1FetchWithMutex(p, iKey, createFlag); }else #endif { - return (tdsqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag); + return (sqlite3_pcache_page*)pcache1FetchNoMutex(p, iKey, createFlag); } } /* -** Implementation of the tdsqlite3_pcache.xUnpin method. +** Implementation of the sqlite3_pcache.xUnpin method. ** ** Mark a page as unpinned (eligible for asynchronous recycling). */ static void pcache1Unpin( - tdsqlite3_pcache *p, - tdsqlite3_pcache_page *pPg, + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, int reuseUnlikely ){ PCache1 *pCache = (PCache1 *)p; @@ -54867,11 +54867,11 @@ static void pcache1Unpin( } /* -** Implementation of the tdsqlite3_pcache.xRekey method. +** Implementation of the sqlite3_pcache.xRekey method. */ static void pcache1Rekey( - tdsqlite3_pcache *p, - tdsqlite3_pcache_page *pPg, + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, unsigned int iOld, unsigned int iNew ){ @@ -54903,13 +54903,13 @@ static void pcache1Rekey( } /* -** Implementation of the tdsqlite3_pcache.xTruncate method. +** Implementation of the sqlite3_pcache.xTruncate method. ** ** Discard all unpinned pages in the cache with a page number equal to ** or greater than parameter iLimit. Any pinned pages with a page number ** equal to or greater than iLimit are implicitly unpinned. */ -static void pcache1Truncate(tdsqlite3_pcache *p, unsigned int iLimit){ +static void pcache1Truncate(sqlite3_pcache *p, unsigned int iLimit){ PCache1 *pCache = (PCache1 *)p; pcache1EnterMutex(pCache->pGroup); if( iLimit<=pCache->iMaxKey ){ @@ -54920,11 +54920,11 @@ static void pcache1Truncate(tdsqlite3_pcache *p, unsigned int iLimit){ } /* -** Implementation of the tdsqlite3_pcache.xDestroy method. +** Implementation of the sqlite3_pcache.xDestroy method. ** ** Destroy a cache allocated using pcache1Create(). */ -static void pcache1Destroy(tdsqlite3_pcache *p){ +static void pcache1Destroy(sqlite3_pcache *p){ PCache1 *pCache = (PCache1 *)p; PGroup *pGroup = pCache->pGroup; assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) ); @@ -54937,18 +54937,18 @@ static void pcache1Destroy(tdsqlite3_pcache *p){ pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage; pcache1EnforceMaxPage(pCache); pcache1LeaveMutex(pGroup); - tdsqlite3_free(pCache->pBulk); - tdsqlite3_free(pCache->apHash); - tdsqlite3_free(pCache); + sqlite3_free(pCache->pBulk); + sqlite3_free(pCache->apHash); + sqlite3_free(pCache); } /* -** This function is called during initialization (tdsqlite3_initialize()) to +** This function is called during initialization (sqlite3_initialize()) to ** install the default pluggable cache module, assuming the user has not ** already provided an alternative. */ -SQLITE_PRIVATE void tdsqlite3PCacheSetDefault(void){ - static const tdsqlite3_pcache_methods2 defaultMethods = { +SQLITE_PRIVATE void sqlite3PCacheSetDefault(void){ + static const sqlite3_pcache_methods2 defaultMethods = { 1, /* iVersion */ 0, /* pArg */ pcache1Init, /* xInit */ @@ -54963,19 +54963,19 @@ SQLITE_PRIVATE void tdsqlite3PCacheSetDefault(void){ pcache1Destroy, /* xDestroy */ pcache1Shrink /* xShrink */ }; - tdsqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); + sqlite3_config(SQLITE_CONFIG_PCACHE2, &defaultMethods); } /* ** Return the size of the header on each page of this PCACHE implementation. */ -SQLITE_PRIVATE int tdsqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); } +SQLITE_PRIVATE int sqlite3HeaderSizePcache1(void){ return ROUND8(sizeof(PgHdr1)); } /* ** Return the global mutex used by this PCACHE implementation. The -** tdsqlite3_status() routine needs access to this mutex. +** sqlite3_status() routine needs access to this mutex. */ -SQLITE_PRIVATE tdsqlite3_mutex *tdsqlite3Pcache1Mutex(void){ +SQLITE_PRIVATE sqlite3_mutex *sqlite3Pcache1Mutex(void){ return pcache1.mutex; } @@ -54983,17 +54983,17 @@ SQLITE_PRIVATE tdsqlite3_mutex *tdsqlite3Pcache1Mutex(void){ /* ** This function is called to free superfluous dynamically allocated memory ** held by the pager system. Memory in use by any SQLite pager allocated -** by the current thread may be tdsqlite3_free()ed. +** by the current thread may be sqlite3_free()ed. ** ** nReq is the number of bytes of memory required. Once this much has ** been released, the function returns. The return value is the total number ** of bytes of memory released. */ -SQLITE_PRIVATE int tdsqlite3PcacheReleaseMemory(int nReq){ +SQLITE_PRIVATE int sqlite3PcacheReleaseMemory(int nReq){ int nFree = 0; - assert( tdsqlite3_mutex_notheld(pcache1.grp.mutex) ); - assert( tdsqlite3_mutex_notheld(pcache1.mutex) ); - if( tdsqlite3GlobalConfig.pPage==0 ){ + assert( sqlite3_mutex_notheld(pcache1.grp.mutex) ); + assert( sqlite3_mutex_notheld(pcache1.mutex) ); + if( sqlite3GlobalConfig.pPage==0 ){ PgHdr1 *p; pcache1EnterMutex(&pcache1.grp); while( (nReq<0 || nFreepage.pBuf); #ifdef SQLITE_PCACHE_SEPARATE_HEADER - nFree += tdsqlite3MemSize(p); + nFree += sqlite3MemSize(p); #endif assert( PAGE_IS_UNPINNED(p) ); pcache1PinPage(p); @@ -55019,7 +55019,7 @@ SQLITE_PRIVATE int tdsqlite3PcacheReleaseMemory(int nReq){ ** This function is used by test procedures to inspect the internal state ** of the global cache. */ -SQLITE_PRIVATE void tdsqlite3PcacheStats( +SQLITE_PRIVATE void sqlite3PcacheStats( int *pnCurrent, /* OUT: Total number of pages cached */ int *pnMax, /* OUT: Global maximum cache size */ int *pnMin, /* OUT: Sum of PCache1.nMin for purgeable caches */ @@ -55149,7 +55149,7 @@ struct RowSetChunk { */ struct RowSet { struct RowSetChunk *pChunk; /* List of all chunk allocations */ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ struct RowSetEntry *pEntry; /* List of entries using pRight */ struct RowSetEntry *pLast; /* Last entry on the pEntry list */ struct RowSetEntry *pFresh; /* Source of new entry objects */ @@ -55163,16 +55163,16 @@ struct RowSet { ** Allowed values for RowSet.rsFlags */ #define ROWSET_SORTED 0x01 /* True if RowSet.pEntry is sorted */ -#define ROWSET_NEXT 0x02 /* True if tdsqlite3RowSetNext() has been called */ +#define ROWSET_NEXT 0x02 /* True if sqlite3RowSetNext() has been called */ /* ** Allocate a RowSet object. Return NULL if a memory allocation ** error occurs. */ -SQLITE_PRIVATE RowSet *tdsqlite3RowSetInit(tdsqlite3 *db){ - RowSet *p = tdsqlite3DbMallocRawNN(db, sizeof(*p)); +SQLITE_PRIVATE RowSet *sqlite3RowSetInit(sqlite3 *db){ + RowSet *p = sqlite3DbMallocRawNN(db, sizeof(*p)); if( p ){ - int N = tdsqlite3DbMallocSize(db, p); + int N = sqlite3DbMallocSize(db, p); p->pChunk = 0; p->db = db; p->pEntry = 0; @@ -55191,12 +55191,12 @@ SQLITE_PRIVATE RowSet *tdsqlite3RowSetInit(tdsqlite3 *db){ ** the RowSet has allocated over its lifetime. This routine is ** the destructor for the RowSet. */ -SQLITE_PRIVATE void tdsqlite3RowSetClear(void *pArg){ +SQLITE_PRIVATE void sqlite3RowSetClear(void *pArg){ RowSet *p = (RowSet*)pArg; struct RowSetChunk *pChunk, *pNextChunk; for(pChunk=p->pChunk; pChunk; pChunk = pNextChunk){ pNextChunk = pChunk->pNextChunk; - tdsqlite3DbFree(p->db, pChunk); + sqlite3DbFree(p->db, pChunk); } p->pChunk = 0; p->nFresh = 0; @@ -55211,9 +55211,9 @@ SQLITE_PRIVATE void tdsqlite3RowSetClear(void *pArg){ ** the RowSet has allocated over its lifetime. This routine is ** the destructor for the RowSet. */ -SQLITE_PRIVATE void tdsqlite3RowSetDelete(void *pArg){ - tdsqlite3RowSetClear(pArg); - tdsqlite3DbFree(((RowSet*)pArg)->db, pArg); +SQLITE_PRIVATE void sqlite3RowSetDelete(void *pArg){ + sqlite3RowSetClear(pArg); + sqlite3DbFree(((RowSet*)pArg)->db, pArg); } /* @@ -55230,7 +55230,7 @@ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ /* We could allocate a fresh RowSetEntry each time one is needed, but it ** is more efficient to pull a preallocated entry from the pool */ struct RowSetChunk *pNew; - pNew = tdsqlite3DbMallocRawNN(p->db, sizeof(*pNew)); + pNew = sqlite3DbMallocRawNN(p->db, sizeof(*pNew)); if( pNew==0 ){ return 0; } @@ -55249,11 +55249,11 @@ static struct RowSetEntry *rowSetEntryAlloc(RowSet *p){ ** The mallocFailed flag of the database connection is set if a ** memory allocation fails. */ -SQLITE_PRIVATE void tdsqlite3RowSetInsert(RowSet *p, i64 rowid){ +SQLITE_PRIVATE void sqlite3RowSetInsert(RowSet *p, i64 rowid){ struct RowSetEntry *pEntry; /* The new entry */ struct RowSetEntry *pLast; /* The last prior entry */ - /* This routine is never called after tdsqlite3RowSetNext() */ + /* This routine is never called after sqlite3RowSetNext() */ assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 ); pEntry = rowSetEntryAlloc(p); @@ -55439,17 +55439,17 @@ static struct RowSetEntry *rowSetListToTree(struct RowSetEntry *pList){ ** Write the element into *pRowid. Return 1 on success. Return ** 0 if the RowSet is already empty. ** -** After this routine has been called, the tdsqlite3RowSetInsert() +** After this routine has been called, the sqlite3RowSetInsert() ** routine may not be called again. ** -** This routine may not be called after tdsqlite3RowSetTest() has +** This routine may not be called after sqlite3RowSetTest() has ** been used. Older versions of RowSet allowed that, but as the ** capability was not used by the code generator, it was removed ** for code economy. */ -SQLITE_PRIVATE int tdsqlite3RowSetNext(RowSet *p, i64 *pRowid){ +SQLITE_PRIVATE int sqlite3RowSetNext(RowSet *p, i64 *pRowid){ assert( p!=0 ); - assert( p->pForest==0 ); /* Cannot be used with tdsqlite3RowSetText() */ + assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */ /* Merge the forest into a single sorted list on first call */ if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/ @@ -55464,8 +55464,8 @@ SQLITE_PRIVATE int tdsqlite3RowSetNext(RowSet *p, i64 *pRowid){ *pRowid = p->pEntry->v; p->pEntry = p->pEntry->pRight; if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/ - /* Free memory immediately, rather than waiting on tdsqlite3_finalize() */ - tdsqlite3RowSetClear(p); + /* Free memory immediately, rather than waiting on sqlite3_finalize() */ + sqlite3RowSetClear(p); } return 1; }else{ @@ -55481,10 +55481,10 @@ SQLITE_PRIVATE int tdsqlite3RowSetNext(RowSet *p, i64 *pRowid){ ** on pRowSet->pEntry, then sort those entries into the forest at ** pRowSet->pForest so that they can be tested. */ -SQLITE_PRIVATE int tdsqlite3RowSetTest(RowSet *pRowSet, int iBatch, tdsqlite3_int64 iRowid){ +SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, int iBatch, sqlite3_int64 iRowid){ struct RowSetEntry *p, *pTree; - /* This routine is never called after tdsqlite3RowSetNext() */ + /* This routine is never called after sqlite3RowSetNext() */ assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 ); /* Sort entries into the forest on the first test of a new batch. @@ -55597,25 +55597,25 @@ SQLITE_PRIVATE int tdsqlite3RowSetTest(RowSet *pRowSet, int iBatch, tdsqlite3_in #define CKPT_SYNC_FLAGS(X) (((X)>>2)&0x03) #ifdef SQLITE_OMIT_WAL -# define tdsqlite3WalOpen(x,y,z) 0 -# define tdsqlite3WalLimit(x,y) -# define tdsqlite3WalClose(v,w,x,y,z) 0 -# define tdsqlite3WalBeginReadTransaction(y,z) 0 -# define tdsqlite3WalEndReadTransaction(z) -# define tdsqlite3WalDbsize(y) 0 -# define tdsqlite3WalBeginWriteTransaction(y) 0 -# define tdsqlite3WalEndWriteTransaction(x) 0 -# define tdsqlite3WalUndo(x,y,z) 0 -# define tdsqlite3WalSavepoint(y,z) -# define tdsqlite3WalSavepointUndo(y,z) 0 -# define tdsqlite3WalFrames(u,v,w,x,y,z) 0 -# define tdsqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0 -# define tdsqlite3WalCallback(z) 0 -# define tdsqlite3WalExclusiveMode(y,z) 0 -# define tdsqlite3WalHeapMemory(z) 0 -# define tdsqlite3WalFramesize(z) 0 -# define tdsqlite3WalFindFrame(x,y,z) 0 -# define tdsqlite3WalFile(x) 0 +# define sqlite3WalOpen(x,y,z) 0 +# define sqlite3WalLimit(x,y) +# define sqlite3WalClose(v,w,x,y,z) 0 +# define sqlite3WalBeginReadTransaction(y,z) 0 +# define sqlite3WalEndReadTransaction(z) +# define sqlite3WalDbsize(y) 0 +# define sqlite3WalBeginWriteTransaction(y) 0 +# define sqlite3WalEndWriteTransaction(x) 0 +# define sqlite3WalUndo(x,y,z) 0 +# define sqlite3WalSavepoint(y,z) +# define sqlite3WalSavepointUndo(y,z) 0 +# define sqlite3WalFrames(u,v,w,x,y,z) 0 +# define sqlite3WalCheckpoint(q,r,s,t,u,v,w,x,y,z) 0 +# define sqlite3WalCallback(z) 0 +# define sqlite3WalExclusiveMode(y,z) 0 +# define sqlite3WalHeapMemory(z) 0 +# define sqlite3WalFramesize(z) 0 +# define sqlite3WalFindFrame(x,y,z) 0 +# define sqlite3WalFile(x) 0 #else #define WAL_SAVEPOINT_NDATA 4 @@ -55626,51 +55626,51 @@ SQLITE_PRIVATE int tdsqlite3RowSetTest(RowSet *pRowSet, int iBatch, tdsqlite3_in typedef struct Wal Wal; /* Open and close a connection to a write-ahead log. */ -SQLITE_PRIVATE int tdsqlite3WalOpen(tdsqlite3_vfs*, tdsqlite3_file*, const char *, int, i64, Wal**); -SQLITE_PRIVATE int tdsqlite3WalClose(Wal *pWal, tdsqlite3*, int sync_flags, int, u8 *); +SQLITE_PRIVATE int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *, int, i64, Wal**); +SQLITE_PRIVATE int sqlite3WalClose(Wal *pWal, sqlite3*, int sync_flags, int, u8 *); /* Set the limiting size of a WAL file. */ -SQLITE_PRIVATE void tdsqlite3WalLimit(Wal*, i64); +SQLITE_PRIVATE void sqlite3WalLimit(Wal*, i64); /* Used by readers to open (lock) and close (unlock) a snapshot. A ** snapshot is like a read-transaction. It is the state of the database -** at an instant in time. tdsqlite3WalOpenSnapshot gets a read lock and +** at an instant in time. sqlite3WalOpenSnapshot gets a read lock and ** preserves the current state even if the other threads or processes -** write to or checkpoint the WAL. tdsqlite3WalCloseSnapshot() closes the +** write to or checkpoint the WAL. sqlite3WalCloseSnapshot() closes the ** transaction and releases the lock. */ -SQLITE_PRIVATE int tdsqlite3WalBeginReadTransaction(Wal *pWal, int *); -SQLITE_PRIVATE void tdsqlite3WalEndReadTransaction(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *); +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal); /* Read a page from the write-ahead log, if it is present. */ -SQLITE_PRIVATE int tdsqlite3WalFindFrame(Wal *, Pgno, u32 *); -SQLITE_PRIVATE int tdsqlite3WalReadFrame(Wal *, u32, int, u8 *); +SQLITE_PRIVATE int sqlite3WalFindFrame(Wal *, Pgno, u32 *); +SQLITE_PRIVATE int sqlite3WalReadFrame(Wal *, u32, int, u8 *); /* If the WAL is not empty, return the size of the database. */ -SQLITE_PRIVATE Pgno tdsqlite3WalDbsize(Wal *pWal); +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal); /* Obtain or release the WRITER lock. */ -SQLITE_PRIVATE int tdsqlite3WalBeginWriteTransaction(Wal *pWal); -SQLITE_PRIVATE int tdsqlite3WalEndWriteTransaction(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal); /* Undo any frames written (but not committed) to the log */ -SQLITE_PRIVATE int tdsqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx); /* Return an integer that records the current (uncommitted) write ** position in the WAL */ -SQLITE_PRIVATE void tdsqlite3WalSavepoint(Wal *pWal, u32 *aWalData); +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData); /* Move the write position of the WAL back to iFrame. Called in ** response to a ROLLBACK TO command. */ -SQLITE_PRIVATE int tdsqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData); /* Write a frame or frames to the log. */ -SQLITE_PRIVATE int tdsqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); +SQLITE_PRIVATE int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int); /* Copy pages from the log to the database file */ -SQLITE_PRIVATE int tdsqlite3WalCheckpoint( +SQLITE_PRIVATE int sqlite3WalCheckpoint( Wal *pWal, /* Write-ahead log connection */ - tdsqlite3 *db, /* Check this handle's interrupt flag */ + sqlite3 *db, /* Check this handle's interrupt flag */ int eMode, /* One of PASSIVE, FULL and RESTART */ int (*xBusy)(void*), /* Function to call when busy */ void *pBusyArg, /* Context argument for xBusyHandler */ @@ -55681,41 +55681,41 @@ SQLITE_PRIVATE int tdsqlite3WalCheckpoint( int *pnCkpt /* OUT: Number of backfilled frames in WAL */ ); -/* Return the value to pass to a tdsqlite3_wal_hook callback, the +/* Return the value to pass to a sqlite3_wal_hook callback, the ** number of frames in the WAL at the point of the last commit since -** tdsqlite3WalCallback() was called. If no commits have occurred since +** sqlite3WalCallback() was called. If no commits have occurred since ** the last call, then return 0. */ -SQLITE_PRIVATE int tdsqlite3WalCallback(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal); /* Tell the wal layer that an EXCLUSIVE lock has been obtained (or released) ** by the pager layer on the database file. */ -SQLITE_PRIVATE int tdsqlite3WalExclusiveMode(Wal *pWal, int op); +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op); /* Return true if the argument is non-NULL and the WAL module is using ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the ** WAL module is using shared-memory, return false. */ -SQLITE_PRIVATE int tdsqlite3WalHeapMemory(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal); #ifdef SQLITE_ENABLE_SNAPSHOT -SQLITE_PRIVATE int tdsqlite3WalSnapshotGet(Wal *pWal, tdsqlite3_snapshot **ppSnapshot); -SQLITE_PRIVATE void tdsqlite3WalSnapshotOpen(Wal *pWal, tdsqlite3_snapshot *pSnapshot); -SQLITE_PRIVATE int tdsqlite3WalSnapshotRecover(Wal *pWal); -SQLITE_PRIVATE int tdsqlite3WalSnapshotCheck(Wal *pWal, tdsqlite3_snapshot *pSnapshot); -SQLITE_PRIVATE void tdsqlite3WalSnapshotUnlock(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot); +SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot); +SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal); #endif #ifdef SQLITE_ENABLE_ZIPVFS /* If the WAL file is not empty, return the number of bytes of content ** stored in each frame (i.e. the db page-size when the WAL was created). */ -SQLITE_PRIVATE int tdsqlite3WalFramesize(Wal *pWal); +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal); #endif -/* Return the tdsqlite3_file object for the WAL file */ -SQLITE_PRIVATE tdsqlite3_file *tdsqlite3WalFile(Wal *pWal); +/* Return the sqlite3_file object for the WAL file */ +SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal); #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ @@ -55814,9 +55814,9 @@ SQLITE_PRIVATE tdsqlite3_file *tdsqlite3WalFile(Wal *pWal); ** Macros for troubleshooting. Normally turned off */ #if 0 -int tdsqlite3PagerTrace=1; /* True to enable tracing */ -#define tdsqlite3DebugPrintf printf -#define PAGERTRACE(X) if( tdsqlite3PagerTrace ){ tdsqlite3DebugPrintf X; } +int sqlite3PagerTrace=1; /* True to enable tracing */ +#define sqlite3DebugPrintf printf +#define PAGERTRACE(X) if( sqlite3PagerTrace ){ sqlite3DebugPrintf X; } #else #define PAGERTRACE(X) #endif @@ -55826,7 +55826,7 @@ int tdsqlite3PagerTrace=1; /* True to enable tracing */ ** to print out file-descriptors. ** ** PAGERID() takes a pointer to a Pager struct as its argument. The -** associated file-descriptor is returned. FILEHANDLEID() takes an tdsqlite3_file +** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file ** struct as its argument. */ #define PAGERID(p) (SQLITE_PTR_TO_INT(p->fd)) @@ -55857,13 +55857,13 @@ int tdsqlite3PagerTrace=1; /* True to enable tracing */ ** ** List of state transitions and the C [function] that performs each: ** -** OPEN -> READER [tdsqlite3PagerSharedLock] +** OPEN -> READER [sqlite3PagerSharedLock] ** READER -> OPEN [pager_unlock] ** -** READER -> WRITER_LOCKED [tdsqlite3PagerBegin] +** READER -> WRITER_LOCKED [sqlite3PagerBegin] ** WRITER_LOCKED -> WRITER_CACHEMOD [pager_open_journal] ** WRITER_CACHEMOD -> WRITER_DBMOD [syncJournal] -** WRITER_DBMOD -> WRITER_FINISHED [tdsqlite3PagerCommitPhaseOne] +** WRITER_DBMOD -> WRITER_FINISHED [sqlite3PagerCommitPhaseOne] ** WRITER_*** -> READER [pager_end_transaction] ** ** WRITER_*** -> ERROR [pager_error] @@ -55926,7 +55926,7 @@ int tdsqlite3PagerTrace=1; /* True to enable tracing */ ** * If the connection is open in rollback-mode, a RESERVED or greater ** lock is held on the database file. ** * If the connection is open in WAL-mode, a WAL write transaction -** is open (i.e. tdsqlite3WalBeginWriteTransaction() has been successfully +** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully ** called). ** * The dbSize, dbOrigSize and dbFileSize variables are all valid. ** * The contents of the pager cache have not been modified. @@ -56010,10 +56010,10 @@ int tdsqlite3PagerTrace=1; /* True to enable tracing */ ** Specifically, the pager jumps into the ERROR state if: ** ** 1. An error occurs while attempting a rollback. This happens in -** function tdsqlite3PagerRollback(). +** function sqlite3PagerRollback(). ** ** 2. An error occurs while attempting to finalize a journal file -** following a commit in function tdsqlite3PagerCommitPhaseTwo(). +** following a commit in function sqlite3PagerCommitPhaseTwo(). ** ** 3. An error occurs while attempting to write to the journal or ** database file in function pagerStress() in order to free up @@ -56134,7 +56134,7 @@ int tdsqlite3PagerTrace=1; /* True to enable tracing */ ** An instance of the following structure is allocated for each active ** savepoint and statement transaction in the system. All such structures ** are stored in the Pager.aSavepoint[] array, which is allocated and -** resized using tdsqlite3Realloc(). +** resized using sqlite3Realloc(). ** ** When a savepoint is created, the PagerSavepoint.iHdrOffset field is ** set to 0. If a journal-header is written into the main journal while @@ -56244,7 +56244,7 @@ struct PagerSavepoint { ** ** If the SPILLFLAG_NOSYNC bit is set, writing to the database from ** pagerStress() is permitted, but syncing the journal file is not. -** This flag is set by tdsqlite3PagerWrite() when the file-system sector-size +** This flag is set by sqlite3PagerWrite() when the file-system sector-size ** is larger than the database page-size in order to prevent a journal sync ** from happening in between the journalling of two pages on the same sector. ** @@ -56331,7 +56331,7 @@ struct PagerSavepoint { ** meaning that the 0x04 and 0x08 bits are both zero. */ struct Pager { - tdsqlite3_vfs *pVfs; /* OS functions to use for IO */ + sqlite3_vfs *pVfs; /* OS functions to use for IO */ u8 exclusiveMode; /* Boolean. True if locking_mode==EXCLUSIVE */ u8 journalMode; /* One of the PAGER_JOURNALMODE_* values */ u8 useJournal; /* Use a rollback journal on this file */ @@ -56371,19 +56371,19 @@ struct Pager { u32 cksumInit; /* Quasi-random value added to every checksum */ u32 nSubRec; /* Number of records written to sub-journal */ Bitvec *pInJournal; /* One bit for each page in the database file */ - tdsqlite3_file *fd; /* File descriptor for database */ - tdsqlite3_file *jfd; /* File descriptor for main journal */ - tdsqlite3_file *sjfd; /* File descriptor for sub-journal */ + sqlite3_file *fd; /* File descriptor for database */ + sqlite3_file *jfd; /* File descriptor for main journal */ + sqlite3_file *sjfd; /* File descriptor for sub-journal */ i64 journalOff; /* Current write offset in the journal file */ i64 journalHdr; /* Byte offset to previous journal header */ - tdsqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ + sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ PagerSavepoint *aSavepoint; /* Array of active savepoints */ int nSavepoint; /* Number of elements in aSavepoint[] */ u32 iDataVersion; /* Changes whenever database content changes */ char dbFileVers[16]; /* Changes whenever database file changes */ int nMmapOut; /* Number of mmap pages currently outstanding */ - tdsqlite3_int64 szMmap; /* Desired maximum mmap size */ + sqlite3_int64 szMmap; /* Desired maximum mmap size */ PgHdr *pMmapFreelist; /* List of free mmap page headers (pDirty) */ /* ** End of the routinely-changing class members @@ -56391,7 +56391,7 @@ struct Pager { u16 nExtra; /* Add this many bytes to each in-memory page */ i16 nReserve; /* Number of unused bytes at end of each page */ - u32 vfsFlags; /* Flags for tdsqlite3_vfs.xOpen() */ + u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ u32 sectorSize; /* Assumed sector size during rollback */ int pageSize; /* Number of bytes in a page */ Pgno mxPgno; /* Maximum allowed size of the database */ @@ -56423,7 +56423,7 @@ struct Pager { /* ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains ** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS -** or CACHE_WRITE to tdsqlite3_db_status(). +** or CACHE_WRITE to sqlite3_db_status(). */ #define PAGER_STAT_HIT 0 #define PAGER_STAT_MISS 1 @@ -56436,9 +56436,9 @@ struct Pager { ** a non-testing build. These variables are not thread-safe. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ -SQLITE_API int tdsqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */ -SQLITE_API int tdsqlite3_pager_writej_count = 0; /* Number of pages written to journal */ +SQLITE_API int sqlite3_pager_readdb_count = 0; /* Number of full pages read from DB */ +SQLITE_API int sqlite3_pager_writedb_count = 0; /* Number of full pages written to DB */ +SQLITE_API int sqlite3_pager_writej_count = 0; /* Number of pages written to journal */ # define PAGER_INCR(v) v++ #else # define PAGER_INCR(v) @@ -56513,7 +56513,7 @@ static const unsigned char aJournalMagic[] = { #define PAGER_MAX_PGNO 2147483647 /* -** The argument to this macro is a file descriptor (type tdsqlite3_file*). +** The argument to this macro is a file descriptor (type sqlite3_file*). ** Return 0 if it is not open, or non-zero (but not 1) if it is. ** ** This is so that expressions can be written as: @@ -56535,9 +56535,9 @@ static const unsigned char aJournalMagic[] = { ** * there are no dirty pages in the cache, and ** * the desired page is not currently in the wal file. */ -SQLITE_PRIVATE int tdsqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ +SQLITE_PRIVATE int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ if( pPager->fd->pMethods==0 ) return 0; - if( tdsqlite3PCacheIsDirty(pPager->pPCache) ) return 0; + if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; #ifdef SQLITE_HAS_CODEC if( pPager->xCodec!=0 ) return 0; #endif @@ -56545,7 +56545,7 @@ SQLITE_PRIVATE int tdsqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno){ if( pPager->pWal ){ u32 iRead = 0; int rc; - rc = tdsqlite3WalFindFrame(pPager->pWal, pgno, &iRead); + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead); return (rc==SQLITE_OK && iRead==0); } #endif @@ -56626,7 +56626,7 @@ static int assert_pager_state(Pager *p){ case PAGER_OPEN: assert( !MEMDB ); assert( pPager->errCode==SQLITE_OK ); - assert( tdsqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile ); + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 || pPager->tempFile ); break; case PAGER_READER: @@ -56674,7 +56674,7 @@ static int assert_pager_state(Pager *p){ assert( isOpen(p->jfd) || p->journalMode==PAGER_JOURNALMODE_OFF || p->journalMode==PAGER_JOURNALMODE_WAL - || (tdsqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) ); assert( pPager->dbOrigSize<=pPager->dbHintSize ); break; @@ -56686,7 +56686,7 @@ static int assert_pager_state(Pager *p){ assert( isOpen(p->jfd) || p->journalMode==PAGER_JOURNALMODE_OFF || p->journalMode==PAGER_JOURNALMODE_WAL - || (tdsqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) ); break; @@ -56696,7 +56696,7 @@ static int assert_pager_state(Pager *p){ ** back to OPEN state. */ assert( pPager->errCode!=SQLITE_OK ); - assert( tdsqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile ); + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 || pPager->tempFile ); break; } @@ -56720,7 +56720,7 @@ static int assert_pager_state(Pager *p){ char *print_pager_state(Pager *p){ static char zRet[1024]; - tdsqlite3_snprintf(1024, zRet, + sqlite3_snprintf(1024, zRet, "Filename: %s\n" "State: %s errCode=%d\n" "Lock: %s\n" @@ -56802,7 +56802,7 @@ static int subjRequiresPage(PgHdr *pPg){ int i; for(i=0; inSavepoint; i++){ p = &pPager->aSavepoint[i]; - if( p->nOrig>=pgno && 0==tdsqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ + if( p->nOrig>=pgno && 0==sqlite3BitvecTestNotNull(p->pInSavepoint, pgno) ){ return 1; } } @@ -56814,7 +56814,7 @@ static int subjRequiresPage(PgHdr *pPg){ ** Return true if the page is already in the journal file. */ static int pageInJournal(Pager *pPager, PgHdr *pPg){ - return tdsqlite3BitvecTest(pPager->pInJournal, pPg->pgno); + return sqlite3BitvecTest(pPager->pInJournal, pPg->pgno); } #endif @@ -56825,11 +56825,11 @@ static int pageInJournal(Pager *pPager, PgHdr *pPg){ ** ** All values are stored on disk as big-endian. */ -static int read32bits(tdsqlite3_file *fd, i64 offset, u32 *pRes){ +static int read32bits(sqlite3_file *fd, i64 offset, u32 *pRes){ unsigned char ac[4]; - int rc = tdsqlite3OsRead(fd, ac, sizeof(ac), offset); + int rc = sqlite3OsRead(fd, ac, sizeof(ac), offset); if( rc==SQLITE_OK ){ - *pRes = tdsqlite3Get4byte(ac); + *pRes = sqlite3Get4byte(ac); } return rc; } @@ -56837,17 +56837,17 @@ static int read32bits(tdsqlite3_file *fd, i64 offset, u32 *pRes){ /* ** Write a 32-bit integer into a string buffer in big-endian byte order. */ -#define put32bits(A,B) tdsqlite3Put4byte((u8*)A,B) +#define put32bits(A,B) sqlite3Put4byte((u8*)A,B) /* ** Write a 32-bit integer into the given file descriptor. Return SQLITE_OK ** on success or an error code is something goes wrong. */ -static int write32bits(tdsqlite3_file *fd, i64 offset, u32 val){ +static int write32bits(sqlite3_file *fd, i64 offset, u32 val){ char ac[4]; put32bits(ac, val); - return tdsqlite3OsWrite(fd, ac, 4, offset); + return sqlite3OsWrite(fd, ac, 4, offset); } /* @@ -56867,7 +56867,7 @@ static int pagerUnlockDb(Pager *pPager, int eLock){ assert( eLock!=NO_LOCK || pagerUseWal(pPager)==0 ); if( isOpen(pPager->fd) ){ assert( pPager->eLock>=eLock ); - rc = pPager->noLock ? SQLITE_OK : tdsqlite3OsUnlock(pPager->fd, eLock); + rc = pPager->noLock ? SQLITE_OK : sqlite3OsUnlock(pPager->fd, eLock); if( pPager->eLock!=UNKNOWN_LOCK ){ pPager->eLock = (u8)eLock; } @@ -56892,7 +56892,7 @@ static int pagerLockDb(Pager *pPager, int eLock){ assert( eLock==SHARED_LOCK || eLock==RESERVED_LOCK || eLock==EXCLUSIVE_LOCK ); if( pPager->eLockeLock==UNKNOWN_LOCK ){ - rc = pPager->noLock ? SQLITE_OK : tdsqlite3OsLock(pPager->fd, eLock); + rc = pPager->noLock ? SQLITE_OK : sqlite3OsLock(pPager->fd, eLock); if( rc==SQLITE_OK && (pPager->eLock!=UNKNOWN_LOCK||eLock==EXCLUSIVE_LOCK) ){ pPager->eLock = (u8)eLock; IOTRACE(("LOCK %p %d\n", pPager, eLock)) @@ -56928,7 +56928,7 @@ static int jrnlBufferSize(Pager *pPager){ int dc; /* Device characteristics */ assert( isOpen(pPager->fd) ); - dc = tdsqlite3OsDeviceCharacteristics(pPager->fd); + dc = sqlite3OsDeviceCharacteristics(pPager->fd); #else UNUSED_PARAMETER(pPager); #endif @@ -57008,7 +57008,7 @@ static void checkPage(PgHdr *pPg){ ** used to store a master journal file name at the end of a journal file. ** ** zMaster must point to a buffer of at least nMaster bytes allocated by -** the caller. This should be tdsqlite3_vfs.mxPathname+1 (to ensure there is +** the caller. This should be sqlite3_vfs.mxPathname+1 (to ensure there is ** enough space to write the master journal name). If the master journal ** name in the journal is longer than nMaster bytes (including a ** nul-terminator), then this is handled as if no master journal name @@ -57025,7 +57025,7 @@ static void checkPage(PgHdr *pPg){ ** If an error occurs while reading from the journal file, an SQLite ** error code is returned. */ -static int readMasterJournal(tdsqlite3_file *pJrnl, char *zMaster, u32 nMaster){ +static int readMasterJournal(sqlite3_file *pJrnl, char *zMaster, u32 nMaster){ int rc; /* Return code */ u32 len; /* Length in bytes of master journal name */ i64 szJ; /* Total size in bytes of journal file pJrnl */ @@ -57034,16 +57034,16 @@ static int readMasterJournal(tdsqlite3_file *pJrnl, char *zMaster, u32 nMaster){ unsigned char aMagic[8]; /* A buffer to hold the magic header */ zMaster[0] = '\0'; - if( SQLITE_OK!=(rc = tdsqlite3OsFileSize(pJrnl, &szJ)) + if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) || szJ<16 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) || len>=nMaster || len>szJ-16 || len==0 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) - || SQLITE_OK!=(rc = tdsqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) || memcmp(aMagic, aJournalMagic, 8) - || SQLITE_OK!=(rc = tdsqlite3OsRead(pJrnl, zMaster, len, szJ-16-len)) + || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, zMaster, len, szJ-16-len)) ){ return rc; } @@ -57117,19 +57117,19 @@ static i64 journalHdrOffset(Pager *pPager){ static int zeroJournalHdr(Pager *pPager, int doTruncate){ int rc = SQLITE_OK; /* Return code */ assert( isOpen(pPager->jfd) ); - assert( !tdsqlite3JournalIsInMemory(pPager->jfd) ); + assert( !sqlite3JournalIsInMemory(pPager->jfd) ); if( pPager->journalOff ){ const i64 iLimit = pPager->journalSizeLimit; /* Local cache of jsl */ IOTRACE(("JZEROHDR %p\n", pPager)) if( doTruncate || iLimit==0 ){ - rc = tdsqlite3OsTruncate(pPager->jfd, 0); + rc = sqlite3OsTruncate(pPager->jfd, 0); }else{ static const char zeroHdr[28] = {0}; - rc = tdsqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); + rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0); } if( rc==SQLITE_OK && !pPager->noSync ){ - rc = tdsqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); } /* At this point the transaction is committed but the write lock @@ -57140,9 +57140,9 @@ static int zeroJournalHdr(Pager *pPager, int doTruncate){ */ if( rc==SQLITE_OK && iLimit>0 ){ i64 sz; - rc = tdsqlite3OsFileSize(pPager->jfd, &sz); + rc = sqlite3OsFileSize(pPager->jfd, &sz); if( rc==SQLITE_OK && sz>iLimit ){ - rc = tdsqlite3OsTruncate(pPager->jfd, iLimit); + rc = sqlite3OsTruncate(pPager->jfd, iLimit); } } } @@ -57211,7 +57211,7 @@ static int writeJournalHdr(Pager *pPager){ */ assert( isOpen(pPager->fd) || pPager->noSync ); if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) - || (tdsqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) ){ memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); @@ -57220,7 +57220,7 @@ static int writeJournalHdr(Pager *pPager){ } /* The random check-hash initializer */ - tdsqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); /* The initial database size */ put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); @@ -57252,12 +57252,12 @@ static int writeJournalHdr(Pager *pPager){ ** ** The loop is required here in case the sector-size is larger than the ** database page size. Since the zHeader buffer is only Pager.pageSize - ** bytes in size, more than one call to tdsqlite3OsWrite() may be required + ** bytes in size, more than one call to sqlite3OsWrite() may be required ** to populate the entire journal header sector. */ for(nWrite=0; rc==SQLITE_OK&&nWritejournalHdr, nHeader)) - rc = tdsqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); + rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); assert( pPager->journalHdr <= pPager->journalOff ); pPager->journalOff += nHeader; } @@ -57311,7 +57311,7 @@ static int readJournalHdr( ** proceed. */ if( isHot || iHdrOff!=pPager->journalHdr ){ - rc = tdsqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); + rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); if( rc ){ return rc; } @@ -57371,7 +57371,7 @@ static int readJournalHdr( ** Use a testcase() macro to make sure that malloc failure within ** PagerSetPagesize() is tested. */ - rc = tdsqlite3PagerSetPagesize(pPager, &iPageSize, -1); + rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); testcase( rc!=SQLITE_OK ); /* Update the assumed sector-size to match the value used by @@ -57444,10 +57444,10 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ ** an error occurs, return the error code to the caller. */ if( (0 != (rc = write32bits(pPager->jfd, iHdrOff, PAGER_MJ_PGNO(pPager)))) - || (0 != (rc = tdsqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4))) + || (0 != (rc = sqlite3OsWrite(pPager->jfd, zMaster, nMaster, iHdrOff+4))) || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster, nMaster))) || (0 != (rc = write32bits(pPager->jfd, iHdrOff+4+nMaster+4, cksum))) - || (0 != (rc = tdsqlite3OsWrite(pPager->jfd, aJournalMagic, 8, + || (0 != (rc = sqlite3OsWrite(pPager->jfd, aJournalMagic, 8, iHdrOff+4+nMaster+8))) ){ return rc; @@ -57464,10 +57464,10 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ ** Easiest thing to do in this scenario is to truncate the journal ** file to the required size. */ - if( SQLITE_OK==(rc = tdsqlite3OsFileSize(pPager->jfd, &jrnlSize)) + if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) && jrnlSize>pPager->journalOff ){ - rc = tdsqlite3OsTruncate(pPager->jfd, pPager->journalOff); + rc = sqlite3OsTruncate(pPager->jfd, pPager->journalOff); } return rc; } @@ -57477,14 +57477,14 @@ static int writeMasterJournal(Pager *pPager, const char *zMaster){ */ static void pager_reset(Pager *pPager){ pPager->iDataVersion++; - tdsqlite3BackupRestart(pPager->pBackup); - tdsqlite3PcacheClear(pPager->pPCache); + sqlite3BackupRestart(pPager->pBackup); + sqlite3PcacheClear(pPager->pPCache); } /* ** Return the pPager->iDataVersion value */ -SQLITE_PRIVATE u32 tdsqlite3PagerDataVersion(Pager *pPager){ +SQLITE_PRIVATE u32 sqlite3PagerDataVersion(Pager *pPager){ return pPager->iDataVersion; } @@ -57496,12 +57496,12 @@ SQLITE_PRIVATE u32 tdsqlite3PagerDataVersion(Pager *pPager){ static void releaseAllSavepoints(Pager *pPager){ int ii; /* Iterator for looping through Pager.aSavepoint */ for(ii=0; iinSavepoint; ii++){ - tdsqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); } - if( !pPager->exclusiveMode || tdsqlite3JournalIsInMemory(pPager->sjfd) ){ - tdsqlite3OsClose(pPager->sjfd); + if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){ + sqlite3OsClose(pPager->sjfd); } - tdsqlite3_free(pPager->aSavepoint); + sqlite3_free(pPager->aSavepoint); pPager->aSavepoint = 0; pPager->nSavepoint = 0; pPager->nSubRec = 0; @@ -57519,7 +57519,7 @@ static int addToSavepointBitvecs(Pager *pPager, Pgno pgno){ for(ii=0; iinSavepoint; ii++){ PagerSavepoint *p = &pPager->aSavepoint[ii]; if( pgno<=p->nOrig ){ - rc |= tdsqlite3BitvecSet(p->pInSavepoint, pgno); + rc |= sqlite3BitvecSet(p->pInSavepoint, pgno); testcase( rc==SQLITE_NOMEM ); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); } @@ -57551,17 +57551,17 @@ static void pager_unlock(Pager *pPager){ || pPager->eState==PAGER_ERROR ); - tdsqlite3BitvecDestroy(pPager->pInJournal); + sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; releaseAllSavepoints(pPager); if( pagerUseWal(pPager) ){ assert( !isOpen(pPager->jfd) ); - tdsqlite3WalEndReadTransaction(pPager->pWal); + sqlite3WalEndReadTransaction(pPager->pWal); pPager->eState = PAGER_OPEN; }else if( !pPager->exclusiveMode ){ int rc; /* Error code returned by pagerUnlockDb() */ - int iDc = isOpen(pPager->fd)?tdsqlite3OsDeviceCharacteristics(pPager->fd):0; + int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0; /* If the operating system support deletion of open files, then ** close the journal file when dropping the database lock. Otherwise @@ -57577,7 +57577,7 @@ static void pager_unlock(Pager *pPager){ if( 0==(iDc & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN) || 1!=(pPager->journalMode & 5) ){ - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); } /* If the pager is in the ERROR state and the call to unlock the database @@ -57612,7 +57612,7 @@ static void pager_unlock(Pager *pPager){ }else{ pPager->eState = (isOpen(pPager->jfd) ? PAGER_OPEN : PAGER_READER); } - if( USEFETCH(pPager) ) tdsqlite3OsUnfetch(pPager->fd, 0, 0); + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); pPager->errCode = SQLITE_OK; setGetterMethod(pPager); } @@ -57679,7 +57679,7 @@ static int pagerFlushOnCommit(Pager *pPager, int bCommit){ if( pPager->tempFile==0 ) return 1; if( !bCommit ) return 0; if( !isOpen(pPager->fd) ) return 0; - return (tdsqlite3PCachePercentDirty(pPager->pPCache)>=25); + return (sqlite3PCachePercentDirty(pPager->pPCache)>=25); } /* @@ -57715,7 +57715,7 @@ static int pagerFlushOnCommit(Pager *pPager, int bCommit){ ** file. An invalid journal file cannot be rolled back. ** ** journalMode==DELETE -** The journal file is closed and deleted using tdsqlite3OsDelete(). +** The journal file is closed and deleted using sqlite3OsDelete(). ** ** If the pager is running in exclusive mode, this method of finalizing ** the journal file is never used. Instead, if the journalMode is @@ -57760,27 +57760,27 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ releaseAllSavepoints(pPager); assert( isOpen(pPager->jfd) || pPager->pInJournal==0 - || (tdsqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC) + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC) ); if( isOpen(pPager->jfd) ){ assert( !pagerUseWal(pPager) ); /* Finalize the journal file. */ - if( tdsqlite3JournalIsInMemory(pPager->jfd) ){ + if( sqlite3JournalIsInMemory(pPager->jfd) ){ /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */ - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ if( pPager->journalOff==0 ){ rc = SQLITE_OK; }else{ - rc = tdsqlite3OsTruncate(pPager->jfd, 0); + rc = sqlite3OsTruncate(pPager->jfd, 0); if( rc==SQLITE_OK && pPager->fullSync ){ /* Make sure the new file size is written into the inode right away. ** Otherwise the journal might resurrect following a power loss and ** cause the last transaction to roll back. See ** https://bugzilla.mozilla.org/show_bug.cgi?id=1072773 */ - rc = tdsqlite3OsSync(pPager->jfd, pPager->syncFlags); + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); } } pPager->journalOff = 0; @@ -57796,39 +57796,39 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ ** the database file, it will do so using an in-memory journal. */ int bDelete = !pPager->tempFile; - assert( tdsqlite3JournalIsInMemory(pPager->jfd)==0 ); + assert( sqlite3JournalIsInMemory(pPager->jfd)==0 ); assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE || pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->journalMode==PAGER_JOURNALMODE_WAL ); - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); if( bDelete ){ - rc = tdsqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync); + rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync); } } } #ifdef SQLITE_CHECK_PAGES - tdsqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); - if( pPager->dbSize==0 && tdsqlite3PcacheRefCount(pPager->pPCache)>0 ){ - PgHdr *p = tdsqlite3PagerLookup(pPager, 1); + sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash); + if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){ + PgHdr *p = sqlite3PagerLookup(pPager, 1); if( p ){ p->pageHash = 0; - tdsqlite3PagerUnrefNotNull(p); + sqlite3PagerUnrefNotNull(p); } } #endif - tdsqlite3BitvecDestroy(pPager->pInJournal); + sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; pPager->nRec = 0; if( rc==SQLITE_OK ){ if( MEMDB || pagerFlushOnCommit(pPager, bCommit) ){ - tdsqlite3PcacheCleanAll(pPager->pPCache); + sqlite3PcacheCleanAll(pPager->pPCache); }else{ - tdsqlite3PcacheClearWritable(pPager->pPCache); + sqlite3PcacheClearWritable(pPager->pPCache); } - tdsqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); + sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); } if( pagerUseWal(pPager) ){ @@ -57836,7 +57836,7 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE ** lock held on the database file. */ - rc2 = tdsqlite3WalEndWriteTransaction(pPager->pWal); + rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); assert( rc2==SQLITE_OK ); }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){ /* This branch is taken when committing a transaction in rollback-journal @@ -57850,12 +57850,12 @@ static int pager_end_transaction(Pager *pPager, int hasMaster, int bCommit){ } if( rc==SQLITE_OK && bCommit ){ - rc = tdsqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_COMMIT_PHASETWO, 0); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; } if( !pPager->exclusiveMode - && (!pagerUseWal(pPager) || tdsqlite3WalExclusiveMode(pPager->pWal, 0)) + && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) ){ rc2 = pagerUnlockDb(pPager, SHARED_LOCK); } @@ -57886,9 +57886,9 @@ static void pagerUnlockAndRollback(Pager *pPager){ if( pPager->eState!=PAGER_ERROR && pPager->eState!=PAGER_OPEN ){ assert( assert_pager_state(pPager) ); if( pPager->eState>=PAGER_WRITER_LOCKED ){ - tdsqlite3BeginBenignMalloc(); - tdsqlite3PagerRollback(pPager); - tdsqlite3EndBenignMalloc(); + sqlite3BeginBenignMalloc(); + sqlite3PagerRollback(pPager); + sqlite3EndBenignMalloc(); }else if( !pPager->exclusiveMode ){ assert( pPager->eState==PAGER_READER ); pager_end_transaction(pPager, 0, 0); @@ -57947,7 +57947,7 @@ static void pagerReportSize(Pager *pPager){ ** pager as it is in the source. This comes up when a VACUUM changes the ** number of reserved bits to the "optimal" amount. */ -SQLITE_PRIVATE void tdsqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){ +SQLITE_PRIVATE void sqlite3PagerAlignReserve(Pager *pDest, Pager *pSrc){ if( pDest->nReserve!=pSrc->nReserve ){ pDest->nReserve = pSrc->nReserve; pagerReportSize(pDest); @@ -58004,7 +58004,7 @@ static int pager_playback_one_page( Pgno pgno; /* The page number of a page in journal */ u32 cksum; /* Checksum used for sanity checking */ char *aData; /* Temporary storage for the page */ - tdsqlite3_file *jfd; /* The file descriptor for the journal file */ + sqlite3_file *jfd; /* The file descriptor for the journal file */ int isSynced; /* True if journal page is synced */ #ifdef SQLITE_HAS_CODEC /* The jrnlEnc flag is true if Journal pages should be passed through @@ -58038,7 +58038,7 @@ static int pager_playback_one_page( jfd = isMainJrnl ? pPager->jfd : pPager->sjfd; rc = read32bits(jfd, *pOffset, &pgno); if( rc!=SQLITE_OK ) return rc; - rc = tdsqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4); + rc = sqlite3OsRead(jfd, (u8*)aData, pPager->pageSize, (*pOffset)+4); if( rc!=SQLITE_OK ) return rc; *pOffset += pPager->pageSize + 4 + isMainJrnl*4; @@ -58051,7 +58051,7 @@ static int pager_playback_one_page( assert( !isSavepnt ); return SQLITE_DONE; } - if( pgno>(Pgno)pPager->dbSize || tdsqlite3BitvecTest(pDone, pgno) ){ + if( pgno>(Pgno)pPager->dbSize || sqlite3BitvecTest(pDone, pgno) ){ return SQLITE_OK; } if( isMainJrnl ){ @@ -58065,7 +58065,7 @@ static int pager_playback_one_page( /* If this page has already been played back before during the current ** rollback, then don't bother to play it back again. */ - if( pDone && (rc = tdsqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ + if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ return rc; } @@ -58114,7 +58114,7 @@ static int pager_playback_one_page( if( pagerUseWal(pPager) ){ pPg = 0; }else{ - pPg = tdsqlite3PagerLookup(pPager, pgno); + pPg = sqlite3PagerLookup(pPager, pgno); } assert( pPg || !MEMDB ); assert( pPager->eState!=PAGER_OPEN || pPg==0 || pPager->tempFile ); @@ -58144,11 +58144,11 @@ static int pager_playback_one_page( #ifdef SQLITE_HAS_CODEC if( !jrnlEnc ){ CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT, aData); - rc = tdsqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); + rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT); }else #endif - rc = tdsqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); + rc = sqlite3OsWrite(pPager->fd, (u8 *)aData, pPager->pageSize, ofst); if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; @@ -58157,11 +58157,11 @@ static int pager_playback_one_page( #ifdef SQLITE_HAS_CODEC if( jrnlEnc ){ CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM_BKPT); - tdsqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); CODEC2(pPager, aData, pgno, 7, rc=SQLITE_NOMEM_BKPT,aData); }else #endif - tdsqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)aData); } }else if( !isMainJrnl && pPg==0 ){ /* If this is a rollback of a savepoint and data was not written to @@ -58173,7 +58173,7 @@ static int pager_playback_one_page( ** There are a couple of different ways this can happen. All are quite ** obscure. When running in synchronous mode, this can only happen ** if the page is on the free-list at the start of the transaction, then - ** populated, then moved using tdsqlite3PagerMovepage(). + ** populated, then moved using sqlite3PagerMovepage(). ** ** The solution is to add an in-memory page to the cache containing ** the data just read from the sub-journal. Mark the page as dirty @@ -58183,26 +58183,26 @@ static int pager_playback_one_page( assert( isSavepnt ); assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)==0 ); pPager->doNotSpill |= SPILLFLAG_ROLLBACK; - rc = tdsqlite3PagerGet(pPager, pgno, &pPg, 1); + rc = sqlite3PagerGet(pPager, pgno, &pPg, 1); assert( (pPager->doNotSpill & SPILLFLAG_ROLLBACK)!=0 ); pPager->doNotSpill &= ~SPILLFLAG_ROLLBACK; if( rc!=SQLITE_OK ) return rc; - tdsqlite3PcacheMakeDirty(pPg); + sqlite3PcacheMakeDirty(pPg); } if( pPg ){ /* No page should ever be explicitly rolled back that is in use, except ** for page 1 which is held in use in order to keep the lock on the ** database active. However such a page may be rolled back as a result ** of an internal error resulting in an automatic call to - ** tdsqlite3PagerRollback(). + ** sqlite3PagerRollback(). */ void *pData; pData = pPg->pData; memcpy(pData, (u8*)aData, pPager->pageSize); pPager->xReiniter(pPg); - /* It used to be that tdsqlite3PcacheMakeClean(pPg) was called here. But + /* It used to be that sqlite3PcacheMakeClean(pPg) was called here. But ** that call was dangerous and had no detectable benefit since the cache - ** is normally cleaned by tdsqlite3PcacheCleanAll() after rollback and so + ** is normally cleaned by sqlite3PcacheCleanAll() after rollback and so ** has been removed. */ pager_set_pagehash(pPg); @@ -58216,7 +58216,7 @@ static int pager_playback_one_page( #if SQLITE_HAS_CODEC if( jrnlEnc ){ CODEC1(pPager, pData, pPg->pgno, 3, rc=SQLITE_NOMEM_BKPT); } #endif - tdsqlite3PcacheRelease(pPg); + sqlite3PcacheRelease(pPg); } return rc; } @@ -58252,10 +58252,10 @@ static int pager_playback_one_page( ** If a child journal can be found that matches both of the criteria ** above, this function returns without doing anything. Otherwise, if ** no such child journal can be found, file zMaster is deleted from -** the file-system using tdsqlite3OsDelete(). +** the file-system using sqlite3OsDelete(). ** ** If an IO error within this function, an error code is returned. This -** function allocates memory by calling tdsqlite3Malloc(). If an allocation +** function allocates memory by calling sqlite3Malloc(). If an allocation ** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors ** occur, SQLITE_OK is returned. ** @@ -58265,10 +58265,10 @@ static int pager_playback_one_page( ** size. */ static int pager_delmaster(Pager *pPager, const char *zMaster){ - tdsqlite3_vfs *pVfs = pPager->pVfs; + sqlite3_vfs *pVfs = pPager->pVfs; int rc; /* Return code */ - tdsqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */ - tdsqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ + sqlite3_file *pMaster; /* Malloc'd master-journal file descriptor */ + sqlite3_file *pJournal; /* Malloc'd child-journal file descriptor */ char *zMasterJournal = 0; /* Contents of master journal file */ i64 nMasterJournal; /* Size of master journal file */ char *zJournal; /* Pointer to one journal within MJ file */ @@ -58278,31 +58278,31 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ /* Allocate space for both the pJournal and pMaster file descriptors. ** If successful, open the master journal file for reading. */ - pMaster = (tdsqlite3_file *)tdsqlite3MallocZero(pVfs->szOsFile * 2); - pJournal = (tdsqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); + pMaster = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile * 2); + pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile); if( !pMaster ){ rc = SQLITE_NOMEM_BKPT; }else{ const int flags = (SQLITE_OPEN_READONLY|SQLITE_OPEN_MASTER_JOURNAL); - rc = tdsqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); + rc = sqlite3OsOpen(pVfs, zMaster, pMaster, flags, 0); } if( rc!=SQLITE_OK ) goto delmaster_out; /* Load the entire master journal file into space obtained from - ** tdsqlite3_malloc() and pointed to by zMasterJournal. Also obtain + ** sqlite3_malloc() and pointed to by zMasterJournal. Also obtain ** sufficient space (in zMasterPtr) to hold the names of master ** journal files extracted from regular rollback-journals. */ - rc = tdsqlite3OsFileSize(pMaster, &nMasterJournal); + rc = sqlite3OsFileSize(pMaster, &nMasterJournal); if( rc!=SQLITE_OK ) goto delmaster_out; nMasterPtr = pVfs->mxPathname+1; - zMasterJournal = tdsqlite3Malloc(nMasterJournal + nMasterPtr + 2); + zMasterJournal = sqlite3Malloc(nMasterJournal + nMasterPtr + 2); if( !zMasterJournal ){ rc = SQLITE_NOMEM_BKPT; goto delmaster_out; } zMasterPtr = &zMasterJournal[nMasterJournal+2]; - rc = tdsqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); + rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); if( rc!=SQLITE_OK ) goto delmaster_out; zMasterJournal[nMasterJournal] = 0; zMasterJournal[nMasterJournal+1] = 0; @@ -58310,7 +58310,7 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ zJournal = zMasterJournal; while( (zJournal-zMasterJournal)pageSize; assert( pPager->eLock==EXCLUSIVE_LOCK ); /* TODO: Is it safe to use Pager.dbFileSize here? */ - rc = tdsqlite3OsFileSize(pPager->fd, ¤tSize); + rc = sqlite3OsFileSize(pPager->fd, ¤tSize); newSize = szPage*(i64)nPage; if( rc==SQLITE_OK && currentSize!=newSize ){ if( currentSize>newSize ){ - rc = tdsqlite3OsTruncate(pPager->fd, newSize); + rc = sqlite3OsTruncate(pPager->fd, newSize); }else if( (currentSize+szPage)<=newSize ){ char *pTmp = pPager->pTmpSpace; memset(pTmp, 0, szPage); testcase( (newSize-szPage) == currentSize ); testcase( (newSize-szPage) > currentSize ); - rc = tdsqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, newSize-szPage); } if( rc==SQLITE_OK ){ pPager->dbFileSize = nPage; @@ -58411,8 +58411,8 @@ static int pager_truncate(Pager *pPager, Pgno nPage){ ** Return a sanitized version of the sector-size of OS file pFile. The ** return value is guaranteed to lie between 32 and MAX_SECTOR_SIZE. */ -SQLITE_PRIVATE int tdsqlite3SectorSize(tdsqlite3_file *pFile){ - int iRet = tdsqlite3OsSectorSize(pFile); +SQLITE_PRIVATE int sqlite3SectorSize(sqlite3_file *pFile){ + int iRet = sqlite3OsSectorSize(pFile); if( iRet<32 ){ iRet = 512; }else if( iRet>MAX_SECTOR_SIZE ){ @@ -58449,7 +58449,7 @@ static void setSectorSize(Pager *pPager){ assert( isOpen(pPager->fd) || pPager->tempFile ); if( pPager->tempFile - || (tdsqlite3OsDeviceCharacteristics(pPager->fd) & + || (sqlite3OsDeviceCharacteristics(pPager->fd) & SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 ){ /* Sector size doesn't matter for temporary files. Also, the file @@ -58457,7 +58457,7 @@ static void setSectorSize(Pager *pPager){ ** call will segfault. */ pPager->sectorSize = 512; }else{ - pPager->sectorSize = tdsqlite3SectorSize(pPager->fd); + pPager->sectorSize = sqlite3SectorSize(pPager->fd); } } @@ -58519,13 +58519,13 @@ static void setSectorSize(Pager *pPager){ ** needed. */ static int pager_playback(Pager *pPager, int isHot){ - tdsqlite3_vfs *pVfs = pPager->pVfs; + sqlite3_vfs *pVfs = pPager->pVfs; i64 szJ; /* Size of the journal file in bytes */ u32 nRec; /* Number of Records in the journal */ u32 u; /* Unsigned loop counter */ Pgno mxPg = 0; /* Size of the original file in pages */ int rc; /* Result code of a subroutine */ - int res = 1; /* Value returned by tdsqlite3OsAccess() */ + int res = 1; /* Value returned by sqlite3OsAccess() */ char *zMaster = 0; /* Name of master journal file if any */ int needPagerReset; /* True to reset page prior to first page rollback */ int nPlayback = 0; /* Total number of pages restored from journal */ @@ -58535,7 +58535,7 @@ static int pager_playback(Pager *pPager, int isHot){ ** the journal is empty. */ assert( isOpen(pPager->jfd) ); - rc = tdsqlite3OsFileSize(pPager->jfd, &szJ); + rc = sqlite3OsFileSize(pPager->jfd, &szJ); if( rc!=SQLITE_OK ){ goto end_playback; } @@ -58554,7 +58554,7 @@ static int pager_playback(Pager *pPager, int isHot){ zMaster = pPager->pTmpSpace; rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1); if( rc==SQLITE_OK && zMaster[0] ){ - rc = tdsqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); + rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); } zMaster = 0; if( rc!=SQLITE_OK || !res ){ @@ -58660,7 +58660,7 @@ static int pager_playback(Pager *pPager, int isHot){ end_playback: if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerSetPagesize(pPager, &savedPageSize, -1); + rc = sqlite3PagerSetPagesize(pPager, &savedPageSize, -1); } /* Following a rollback, the database file should be back in its original ** state prior to the start of the transaction, so invoke the @@ -58668,7 +58668,7 @@ end_playback: ** assertion that the transaction counter was modified. */ #ifdef SQLITE_DEBUG - tdsqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); + sqlite3OsFileControlHint(pPager->fd,SQLITE_FCNTL_DB_UNCHANGED,0); #endif /* If this playback is happening automatically as a result of an IO or @@ -58690,7 +58690,7 @@ end_playback: if( rc==SQLITE_OK && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) ){ - rc = tdsqlite3PagerSync(pPager, 0); + rc = sqlite3PagerSync(pPager, 0); } if( rc==SQLITE_OK ){ rc = pager_end_transaction(pPager, zMaster[0]!='\0', 0); @@ -58704,7 +58704,7 @@ end_playback: testcase( rc!=SQLITE_OK ); } if( isHot && nPlayback ){ - tdsqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", + sqlite3_log(SQLITE_NOTICE_RECOVER_ROLLBACK, "recovered %d pages from %s", nPlayback, pPager->zJournal); } @@ -58740,16 +58740,16 @@ static int readDbPage(PgHdr *pPg){ assert( isOpen(pPager->fd) ); if( pagerUseWal(pPager) ){ - rc = tdsqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); + rc = sqlite3WalFindFrame(pPager->pWal, pPg->pgno, &iFrame); if( rc ) return rc; } if( iFrame ){ - rc = tdsqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); + rc = sqlite3WalReadFrame(pPager->pWal, iFrame,pPager->pageSize,pPg->pData); }else #endif { i64 iOffset = (pPg->pgno-1)*(i64)pPager->pageSize; - rc = tdsqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); + rc = sqlite3OsRead(pPager->fd, pPg->pData, pPager->pageSize, iOffset); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } @@ -58777,7 +58777,7 @@ static int readDbPage(PgHdr *pPg){ } CODEC1(pPager, pPg->pData, pPg->pgno, 3, rc = SQLITE_NOMEM_BKPT); - PAGER_INCR(tdsqlite3_pager_readdb_count); + PAGER_INCR(sqlite3_pager_readdb_count); PAGER_INCR(pPager->nRead); IOTRACE(("PGIN %p %d\n", pPager, pPg->pgno)); PAGERTRACE(("FETCH %d page %d hash(%08x)\n", @@ -58798,7 +58798,7 @@ static void pager_write_changecounter(PgHdr *pPg){ u32 change_counter; /* Increment the value just read and write it back to byte 24. */ - change_counter = tdsqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; + change_counter = sqlite3Get4byte((u8*)pPg->pPager->dbFileVers)+1; put32bits(((char*)pPg->pData)+24, change_counter); /* Also store the SQLite version number in bytes 96..99 and in @@ -58827,16 +58827,16 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){ PgHdr *pPg; assert( pagerUseWal(pPager) ); - pPg = tdsqlite3PagerLookup(pPager, iPg); + pPg = sqlite3PagerLookup(pPager, iPg); if( pPg ){ - if( tdsqlite3PcachePageRefcount(pPg)==1 ){ - tdsqlite3PcacheDrop(pPg); + if( sqlite3PcachePageRefcount(pPg)==1 ){ + sqlite3PcacheDrop(pPg); }else{ rc = readDbPage(pPg); if( rc==SQLITE_OK ){ pPager->xReiniter(pPg); } - tdsqlite3PagerUnrefNotNull(pPg); + sqlite3PagerUnrefNotNull(pPg); } } @@ -58848,7 +58848,7 @@ static int pagerUndoCallback(void *pCtx, Pgno iPg){ ** also copied into the backup databases) as part of this transaction, ** the backups must be restarted. */ - tdsqlite3BackupRestart(pPager->pBackup); + sqlite3BackupRestart(pPager->pBackup); return rc; } @@ -58868,8 +58868,8 @@ static int pagerRollbackWal(Pager *pPager){ ** + Reload page content from the database (if refcount>0). */ pPager->dbSize = pPager->dbOrigSize; - rc = tdsqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); - pList = tdsqlite3PcacheDirtyList(pPager->pPCache); + rc = sqlite3WalUndo(pPager->pWal, pagerUndoCallback, (void *)pPager); + pList = sqlite3PcacheDirtyList(pPager->pPCache); while( pList && rc==SQLITE_OK ){ PgHdr *pNext = pList->pDirty; rc = pagerUndoCallback((void *)pPager, pList->pgno); @@ -58880,7 +58880,7 @@ static int pagerRollbackWal(Pager *pPager){ } /* -** This function is a wrapper around tdsqlite3WalFrames(). As well as logging +** This function is a wrapper around sqlite3WalFrames(). As well as logging ** the contents of the list of pages headed by pList (connected by pDirty), ** this function notifies any active backup processes that the pages have ** changed. @@ -58928,17 +58928,17 @@ static int pagerWalFrames( pPager->aStat[PAGER_STAT_WRITE] += nList; if( pList->pgno==1 ) pager_write_changecounter(pList); - rc = tdsqlite3WalFrames(pPager->pWal, + rc = sqlite3WalFrames(pPager->pWal, pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ for(p=pList; p; p=p->pDirty){ - tdsqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); + sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData); } } #ifdef SQLITE_CHECK_PAGES - pList = tdsqlite3PcacheDirtyList(pPager->pPCache); + pList = sqlite3PcacheDirtyList(pPager->pPCache); for(p=pList; p; p=p->pDirty){ pager_set_pagehash(p); } @@ -58962,17 +58962,17 @@ static int pagerBeginReadTransaction(Pager *pPager){ assert( pagerUseWal(pPager) ); assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); - /* tdsqlite3WalEndReadTransaction() was not called for the previous + /* sqlite3WalEndReadTransaction() was not called for the previous ** transaction in locking_mode=EXCLUSIVE. So call it now. If we ** are in locking_mode=NORMAL and EndRead() was previously called, ** the duplicate call is harmless. */ - tdsqlite3WalEndReadTransaction(pPager->pWal); + sqlite3WalEndReadTransaction(pPager->pWal); - rc = tdsqlite3WalBeginReadTransaction(pPager->pWal, &changed); + rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed); if( rc!=SQLITE_OK || changed ){ pager_reset(pPager); - if( USEFETCH(pPager) ) tdsqlite3OsUnfetch(pPager->fd, 0, 0); + if( USEFETCH(pPager) ) sqlite3OsUnfetch(pPager->fd, 0, 0); } return rc; @@ -59001,7 +59001,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){ assert( pPager->eLock>=SHARED_LOCK ); assert( isOpen(pPager->fd) ); assert( pPager->tempFile==0 ); - nPage = tdsqlite3WalDbsize(pPager->pWal); + nPage = sqlite3WalDbsize(pPager->pWal); /* If the number of pages in the database is not available from the ** WAL sub-system, determine the page count based on the size of @@ -59010,7 +59010,7 @@ static int pagerPagecount(Pager *pPager, Pgno *pnPage){ */ if( nPage==0 && ALWAYS(isOpen(pPager->fd)) ){ i64 n = 0; /* Size of db file in bytes */ - int rc = tdsqlite3OsFileSize(pPager->fd, &n); + int rc = sqlite3OsFileSize(pPager->fd, &n); if( rc!=SQLITE_OK ){ return rc; } @@ -59055,7 +59055,7 @@ static int pagerOpenWalIfPresent(Pager *pPager){ if( !pPager->tempFile ){ int isWal; /* True if WAL file exists */ - rc = tdsqlite3OsAccess( + rc = sqlite3OsAccess( pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal ); if( rc==SQLITE_OK ){ @@ -59065,10 +59065,10 @@ static int pagerOpenWalIfPresent(Pager *pPager){ rc = pagerPagecount(pPager, &nPage); if( rc ) return rc; if( nPage==0 ){ - rc = tdsqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); + rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); }else{ - testcase( tdsqlite3PcachePagecount(pPager->pPCache)==0 ); - rc = tdsqlite3PagerOpenWal(pPager, 0); + testcase( sqlite3PcachePagecount(pPager->pPCache)==0 ); + rc = sqlite3PagerOpenWal(pPager, 0); } }else if( pPager->journalMode==PAGER_JOURNALMODE_WAL ){ pPager->journalMode = PAGER_JOURNALMODE_DELETE; @@ -59126,7 +59126,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ /* Allocate a bitvec to use to store the set of pages rolled back */ if( pSavepoint ){ - pDone = tdsqlite3BitvecCreate(pSavepoint->nOrig); + pDone = sqlite3BitvecCreate(pSavepoint->nOrig); if( !pDone ){ return SQLITE_NOMEM_BKPT; } @@ -59206,7 +59206,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize); if( pagerUseWal(pPager) ){ - rc = tdsqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); + rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData); } for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && iinSubRec; ii++){ assert( offset==(i64)ii*(4+pPager->pageSize) ); @@ -59215,7 +59215,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ assert( rc!=SQLITE_DONE ); } - tdsqlite3BitvecDestroy(pDone); + sqlite3BitvecDestroy(pDone); if( rc==SQLITE_OK ){ pPager->journalOff = szJ; } @@ -59227,16 +59227,16 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ ** Change the maximum number of in-memory pages that are allowed ** before attempting to recycle clean and unused pages. */ -SQLITE_PRIVATE void tdsqlite3PagerSetCachesize(Pager *pPager, int mxPage){ - tdsqlite3PcacheSetCachesize(pPager->pPCache, mxPage); +SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager *pPager, int mxPage){ + sqlite3PcacheSetCachesize(pPager->pPCache, mxPage); } /* ** Change the maximum number of in-memory pages that are allowed ** before attempting to spill pages to journal. */ -SQLITE_PRIVATE int tdsqlite3PagerSetSpillsize(Pager *pPager, int mxPage){ - return tdsqlite3PcacheSetSpillsize(pPager->pPCache, mxPage); +SQLITE_PRIVATE int sqlite3PagerSetSpillsize(Pager *pPager, int mxPage){ + return sqlite3PcacheSetSpillsize(pPager->pPCache, mxPage); } /* @@ -59244,13 +59244,13 @@ SQLITE_PRIVATE int tdsqlite3PagerSetSpillsize(Pager *pPager, int mxPage){ */ static void pagerFixMaplimit(Pager *pPager){ #if SQLITE_MAX_MMAP_SIZE>0 - tdsqlite3_file *fd = pPager->fd; + sqlite3_file *fd = pPager->fd; if( isOpen(fd) && fd->pMethods->iVersion>=3 ){ - tdsqlite3_int64 sz; + sqlite3_int64 sz; sz = pPager->szMmap; pPager->bUseFetch = (sz>0); setGetterMethod(pPager); - tdsqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_SIZE, &sz); } #endif } @@ -59258,7 +59258,7 @@ static void pagerFixMaplimit(Pager *pPager){ /* ** Change the maximum size of any memory mapping made of the database file. */ -SQLITE_PRIVATE void tdsqlite3PagerSetMmapLimit(Pager *pPager, tdsqlite3_int64 szMmap){ +SQLITE_PRIVATE void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 szMmap){ pPager->szMmap = szMmap; pagerFixMaplimit(pPager); } @@ -59266,8 +59266,8 @@ SQLITE_PRIVATE void tdsqlite3PagerSetMmapLimit(Pager *pPager, tdsqlite3_int64 sz /* ** Free as much memory as possible from the pager. */ -SQLITE_PRIVATE void tdsqlite3PagerShrink(Pager *pPager){ - tdsqlite3PcacheShrink(pPager->pPCache); +SQLITE_PRIVATE void sqlite3PagerShrink(Pager *pPager){ + sqlite3PcacheShrink(pPager->pPCache); } /* @@ -59278,7 +59278,7 @@ SQLITE_PRIVATE void tdsqlite3PagerShrink(Pager *pPager){ ** changing the number of syncs()s when writing the journals. ** There are four levels: ** -** OFF tdsqlite3OsSync() is never called. This is the default +** OFF sqlite3OsSync() is never called. This is the default ** for temporary and transient files. ** ** NORMAL The journal is synced once before writes begin on the @@ -59322,7 +59322,7 @@ SQLITE_PRIVATE void tdsqlite3PagerShrink(Pager *pPager){ ** and FULL=3. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS -SQLITE_PRIVATE void tdsqlite3PagerSetFlags( +SQLITE_PRIVATE void sqlite3PagerSetFlags( Pager *pPager, /* The pager to set safety level for */ unsigned pgFlags /* Various flags */ ){ @@ -59364,7 +59364,7 @@ SQLITE_PRIVATE void tdsqlite3PagerSetFlags( ** testing and analysis only. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_opentemp_count = 0; +SQLITE_API int sqlite3_opentemp_count = 0; #endif /* @@ -59384,18 +59384,18 @@ SQLITE_API int tdsqlite3_opentemp_count = 0; */ static int pagerOpentemp( Pager *pPager, /* The pager object */ - tdsqlite3_file *pFile, /* Write the file descriptor here */ + sqlite3_file *pFile, /* Write the file descriptor here */ int vfsFlags /* Flags passed through to the VFS */ ){ int rc; /* Return code */ #ifdef SQLITE_TEST - tdsqlite3_opentemp_count++; /* Used for testing and analysis only */ + sqlite3_opentemp_count++; /* Used for testing and analysis only */ #endif vfsFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; - rc = tdsqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0); + rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0); assert( rc!=SQLITE_OK || isOpen(pFile) ); return rc; } @@ -59403,7 +59403,7 @@ static int pagerOpentemp( /* ** Set the busy handler function. ** -** The pager invokes the busy-handler if tdsqlite3OsLock() returns +** The pager invokes the busy-handler if sqlite3OsLock() returns ** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, ** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE ** lock. It does *not* invoke the busy handler when upgrading from @@ -59421,7 +59421,7 @@ static int pagerOpentemp( ** retried. If it returns zero, then the SQLITE_BUSY error is ** returned to the caller of the pager API function. */ -SQLITE_PRIVATE void tdsqlite3PagerSetBusyHandler( +SQLITE_PRIVATE void sqlite3PagerSetBusyHandler( Pager *pPager, /* Pager object */ int (*xBusyHandler)(void *), /* Pointer to busy-handler function */ void *pBusyHandlerArg /* Argument to pass to xBusyHandler */ @@ -59432,7 +59432,7 @@ SQLITE_PRIVATE void tdsqlite3PagerSetBusyHandler( ap = (void **)&pPager->xBusyHandler; assert( ((int(*)(void *))(ap[0]))==xBusyHandler ); assert( ap[1]==pBusyHandlerArg ); - tdsqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_BUSYHANDLER, (void *)ap); } /* @@ -59455,7 +59455,7 @@ SQLITE_PRIVATE void tdsqlite3PagerSetBusyHandler( ** ** then the pager object page size is set to *pPageSize. ** -** If the page size is changed, then this function uses tdsqlite3PagerMalloc() +** If the page size is changed, then this function uses sqlite3PagerMalloc() ** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt ** fails, SQLITE_NOMEM is returned and the page size remains unchanged. ** In all other cases, SQLITE_OK is returned. @@ -59465,7 +59465,7 @@ SQLITE_PRIVATE void tdsqlite3PagerSetBusyHandler( ** function was called, or because the memory allocation attempt failed, ** then *pPageSize is set to the old, retained page size before returning. */ -SQLITE_PRIVATE int tdsqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ int rc = SQLITE_OK; /* It is not possible to do a full assert_pager_state() here, as this @@ -59481,19 +59481,19 @@ SQLITE_PRIVATE int tdsqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int u32 pageSize = *pPageSize; assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); if( (pPager->memDb==0 || pPager->dbSize==0) - && tdsqlite3PcacheRefCount(pPager->pPCache)==0 + && sqlite3PcacheRefCount(pPager->pPCache)==0 && pageSize && pageSize!=(u32)pPager->pageSize ){ char *pNew = NULL; /* New temp space */ i64 nByte = 0; if( pPager->eState>PAGER_OPEN && isOpen(pPager->fd) ){ - rc = tdsqlite3OsFileSize(pPager->fd, &nByte); + rc = sqlite3OsFileSize(pPager->fd, &nByte); } if( rc==SQLITE_OK ){ /* 8 bytes of zeroed overrun space is sufficient so that the b-tree * cell header parser will never run off the end of the allocation */ - pNew = (char *)tdsqlite3PageMalloc(pageSize+8); + pNew = (char *)sqlite3PageMalloc(pageSize+8); if( !pNew ){ rc = SQLITE_NOMEM_BKPT; }else{ @@ -59503,15 +59503,15 @@ SQLITE_PRIVATE int tdsqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int if( rc==SQLITE_OK ){ pager_reset(pPager); - rc = tdsqlite3PcacheSetPageSize(pPager->pPCache, pageSize); + rc = sqlite3PcacheSetPageSize(pPager->pPCache, pageSize); } if( rc==SQLITE_OK ){ - tdsqlite3PageFree(pPager->pTmpSpace); + sqlite3PageFree(pPager->pTmpSpace); pPager->pTmpSpace = pNew; pPager->dbSize = (Pgno)((nByte+pageSize-1)/pageSize); pPager->pageSize = pageSize; }else{ - tdsqlite3PageFree(pNew); + sqlite3PageFree(pNew); } } @@ -59534,7 +59534,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int ** occurs. But other modules are free to use it too, as long as ** no rollbacks are happening. */ -SQLITE_PRIVATE void *tdsqlite3PagerTempSpace(Pager *pPager){ +SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager *pPager){ return pPager->pTmpSpace; } @@ -59545,7 +59545,7 @@ SQLITE_PRIVATE void *tdsqlite3PagerTempSpace(Pager *pPager){ ** ** Regardless of mxPage, return the current maximum page count. */ -SQLITE_PRIVATE int tdsqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ +SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ if( mxPage>0 ){ pPager->mxPgno = mxPage; } @@ -59566,15 +59566,15 @@ SQLITE_PRIVATE int tdsqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ ** and generate no code. */ #ifdef SQLITE_TEST -SQLITE_API extern int tdsqlite3_io_error_pending; -SQLITE_API extern int tdsqlite3_io_error_hit; +SQLITE_API extern int sqlite3_io_error_pending; +SQLITE_API extern int sqlite3_io_error_hit; static int saved_cnt; void disable_simulated_io_errors(void){ - saved_cnt = tdsqlite3_io_error_pending; - tdsqlite3_io_error_pending = -1; + saved_cnt = sqlite3_io_error_pending; + sqlite3_io_error_pending = -1; } void enable_simulated_io_errors(void){ - tdsqlite3_io_error_pending = saved_cnt; + sqlite3_io_error_pending = saved_cnt; } #else # define disable_simulated_io_errors() @@ -59595,7 +59595,7 @@ void enable_simulated_io_errors(void){ ** the error code is returned to the caller and the contents of the ** output buffer undefined. */ -SQLITE_PRIVATE int tdsqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ +SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager *pPager, int N, unsigned char *pDest){ int rc = SQLITE_OK; memset(pDest, 0, N); assert( isOpen(pPager->fd) || pPager->tempFile ); @@ -59608,7 +59608,7 @@ SQLITE_PRIVATE int tdsqlite3PagerReadFileheader(Pager *pPager, int N, unsigned c if( isOpen(pPager->fd) ){ IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) - rc = tdsqlite3OsRead(pPager->fd, pDest, N, 0); + rc = sqlite3OsRead(pPager->fd, pDest, N, 0); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } @@ -59623,7 +59623,7 @@ SQLITE_PRIVATE int tdsqlite3PagerReadFileheader(Pager *pPager, int N, unsigned c ** However, if the file is between 1 and bytes in size, then ** this is considered a 1 page file. */ -SQLITE_PRIVATE void tdsqlite3PagerPagecount(Pager *pPager, int *pnPage){ +SQLITE_PRIVATE void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ assert( pPager->eState>=PAGER_READER ); assert( pPager->eState!=PAGER_WRITER_FINISHED ); *pnPage = (int)pPager->dbSize; @@ -59635,7 +59635,7 @@ SQLITE_PRIVATE void tdsqlite3PagerPagecount(Pager *pPager, int *pnPage){ ** a similar or greater lock is already held, this function is a no-op ** (returning SQLITE_OK immediately). ** -** Otherwise, attempt to obtain the lock using tdsqlite3OsLock(). Invoke +** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke ** the busy callback if the lock is currently not available. Repeat ** until the busy callback returns false or until the attempt to ** obtain the lock succeeds. @@ -59650,7 +59650,7 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ /* Check that this is either a no-op (because the requested lock is ** already held), or one of the transitions that the busy-handler ** may be invoked during, according to the comment above - ** tdsqlite3PagerSetBusyhandler(). + ** sqlite3PagerSetBusyhandler(). */ assert( (pPager->eLock>=locktype) || (pPager->eLock==NO_LOCK && locktype==SHARED_LOCK) @@ -59691,7 +59691,7 @@ static void assertTruncateConstraintCb(PgHdr *pPg){ assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize ); } static void assertTruncateConstraint(Pager *pPager){ - tdsqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); + sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); } #else # define assertTruncateConstraint(pPager) @@ -59708,7 +59708,7 @@ static void assertTruncateConstraint(Pager *pPager){ ** rolled back or committed. It is not safe to call this function and ** then continue writing to the database. */ -SQLITE_PRIVATE void tdsqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ +SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ assert( pPager->dbSize>=nPage ); assert( pPager->eState>=PAGER_WRITER_CACHEMOD ); pPager->dbSize = nPage; @@ -59742,10 +59742,10 @@ SQLITE_PRIVATE void tdsqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ static int pagerSyncHotJournal(Pager *pPager){ int rc = SQLITE_OK; if( !pPager->noSync ){ - rc = tdsqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL); + rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_NORMAL); } if( rc==SQLITE_OK ){ - rc = tdsqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); + rc = sqlite3OsFileSize(pPager->jfd, &pPager->journalHdr); } return rc; } @@ -59776,9 +59776,9 @@ static int pagerAcquireMapPage( assert( pPager->nExtra>=8 ); memset(p->pExtra, 0, 8); }else{ - *ppPage = p = (PgHdr *)tdsqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); + *ppPage = p = (PgHdr *)sqlite3MallocZero(sizeof(PgHdr) + pPager->nExtra); if( p==0 ){ - tdsqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pData); return SQLITE_NOMEM_BKPT; } p->pExtra = (void *)&p[1]; @@ -59812,7 +59812,7 @@ static void pagerReleaseMapPage(PgHdr *pPg){ pPager->pMmapFreelist = pPg; assert( pPager->fd->pMethods->iVersion>=3 ); - tdsqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData); + sqlite3OsUnfetch(pPager->fd, (i64)(pPg->pgno-1)*pPager->pageSize, pPg->pData); } /* @@ -59823,14 +59823,14 @@ static void pagerFreeMapHdrs(Pager *pPager){ PgHdr *pNext; for(p=pPager->pMmapFreelist; p; p=pNext){ pNext = p->pDirty; - tdsqlite3_free(p); + sqlite3_free(p); } } /* Verify that the database file has not be deleted or renamed out from ** under the pager. Return SQLITE_OK if the database is still where it ought ** to be on disk. Return non-zero (SQLITE_READONLY_DBMOVED or some other error -** code from tdsqlite3OsAccess()) if the database has gone missing. +** code from sqlite3OsAccess()) if the database has gone missing. */ static int databaseIsUnmoved(Pager *pPager){ int bHasMoved = 0; @@ -59839,7 +59839,7 @@ static int databaseIsUnmoved(Pager *pPager){ if( pPager->tempFile ) return SQLITE_OK; if( pPager->dbSize==0 ) return SQLITE_OK; assert( pPager->zFilename && pPager->zFilename[0] ); - rc = tdsqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_HAS_MOVED, &bHasMoved); if( rc==SQLITE_NOTFOUND ){ /* If the HAS_MOVED file-control is unimplemented, assume that the file ** has not been moved. That is the historical behavior of SQLite: prior to @@ -59866,12 +59866,12 @@ static int databaseIsUnmoved(Pager *pPager){ ** a hot journal may be left in the filesystem but no error is returned ** to the caller. */ -SQLITE_PRIVATE int tdsqlite3PagerClose(Pager *pPager, tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ u8 *pTmp = (u8*)pPager->pTmpSpace; assert( db || pagerUseWal(pPager)==0 ); assert( assert_pager_state(pPager) ); disable_simulated_io_errors(); - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); pagerFreeMapHdrs(pPager); /* pPager->errCode = 0; */ pPager->exclusiveMode = 0; @@ -59884,7 +59884,7 @@ SQLITE_PRIVATE int tdsqlite3PagerClose(Pager *pPager, tdsqlite3 *db){ ){ a = pTmp; } - tdsqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); + sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a); pPager->pWal = 0; } #endif @@ -59908,14 +59908,14 @@ SQLITE_PRIVATE int tdsqlite3PagerClose(Pager *pPager, tdsqlite3 *db){ } pagerUnlockAndRollback(pPager); } - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); enable_simulated_io_errors(); PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); IOTRACE(("CLOSE %p\n", pPager)) - tdsqlite3OsClose(pPager->jfd); - tdsqlite3OsClose(pPager->fd); - tdsqlite3PageFree(pTmp); - tdsqlite3PcacheClose(pPager->pPCache); + sqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pTmp); + sqlite3PcacheClose(pPager->pPCache); #ifdef SQLITE_HAS_CODEC if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); @@ -59924,7 +59924,7 @@ SQLITE_PRIVATE int tdsqlite3PagerClose(Pager *pPager, tdsqlite3 *db){ assert( !pPager->aSavepoint && !pPager->pInJournal ); assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); - tdsqlite3_free(pPager); + sqlite3_free(pPager); return SQLITE_OK; } @@ -59932,7 +59932,7 @@ SQLITE_PRIVATE int tdsqlite3PagerClose(Pager *pPager, tdsqlite3 *db){ /* ** Return the page number for page pPg. */ -SQLITE_PRIVATE Pgno tdsqlite3PagerPagenumber(DbPage *pPg){ +SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage *pPg){ return pPg->pgno; } #endif @@ -59940,8 +59940,8 @@ SQLITE_PRIVATE Pgno tdsqlite3PagerPagenumber(DbPage *pPg){ /* ** Increment the reference count for page pPg. */ -SQLITE_PRIVATE void tdsqlite3PagerRef(DbPage *pPg){ - tdsqlite3PcacheRef(pPg); +SQLITE_PRIVATE void sqlite3PagerRef(DbPage *pPg){ + sqlite3PcacheRef(pPg); } /* @@ -59988,13 +59988,13 @@ static int syncJournal(Pager *pPager, int newHdr){ assert( assert_pager_state(pPager) ); assert( !pagerUseWal(pPager) ); - rc = tdsqlite3PagerExclusiveLock(pPager); + rc = sqlite3PagerExclusiveLock(pPager); if( rc!=SQLITE_OK ) return rc; if( !pPager->noSync ){ assert( !pPager->tempFile ); if( isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ - const int iDc = tdsqlite3OsDeviceCharacteristics(pPager->fd); + const int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); assert( isOpen(pPager->jfd) ); if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ @@ -60028,10 +60028,10 @@ static int syncJournal(Pager *pPager, int newHdr){ put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); iNextHdrOffset = journalHdrOffset(pPager); - rc = tdsqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); + rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){ static const u8 zerobyte = 0; - rc = tdsqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset); + rc = sqlite3OsWrite(pPager->jfd, &zerobyte, 1, iNextHdrOffset); } if( rc!=SQLITE_OK && rc!=SQLITE_IOERR_SHORT_READ ){ return rc; @@ -60051,11 +60051,11 @@ static int syncJournal(Pager *pPager, int newHdr){ if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); IOTRACE(("JSYNC %p\n", pPager)) - rc = tdsqlite3OsSync(pPager->jfd, pPager->syncFlags); + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags); if( rc!=SQLITE_OK ) return rc; } IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); - rc = tdsqlite3OsWrite( + rc = sqlite3OsWrite( pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr ); if( rc!=SQLITE_OK ) return rc; @@ -60063,7 +60063,7 @@ static int syncJournal(Pager *pPager, int newHdr){ if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); IOTRACE(("JSYNC %p\n", pPager)) - rc = tdsqlite3OsSync(pPager->jfd, pPager->syncFlags| + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) ); if( rc!=SQLITE_OK ) return rc; @@ -60084,7 +60084,7 @@ static int syncJournal(Pager *pPager, int newHdr){ ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on ** all pages. */ - tdsqlite3PcacheClearSyncFlags(pPager->pPCache); + sqlite3PcacheClearSyncFlags(pPager->pPCache); pPager->eState = PAGER_WRITER_DBMOD; assert( assert_pager_state(pPager) ); return SQLITE_OK; @@ -60148,8 +60148,8 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ && pPager->dbHintSizedbSize && (pList->pDirty || pList->pgno>pPager->dbHintSize) ){ - tdsqlite3_int64 szFile = pPager->pageSize * (tdsqlite3_int64)pPager->dbSize; - tdsqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); + sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; + sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); pPager->dbHintSize = pPager->dbSize; } @@ -60157,12 +60157,12 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ Pgno pgno = pList->pgno; /* If there are dirty pages in the page cache with page numbers greater - ** than Pager.dbSize, this means tdsqlite3PagerTruncateImage() was called to + ** than Pager.dbSize, this means sqlite3PagerTruncateImage() was called to ** make the file smaller (presumably by auto-vacuum code). Do not write ** any such pages to the file. ** ** Also, do not write out any page that has the PGHDR_DONT_WRITE flag - ** set (set by tdsqlite3PagerDontWrite()). + ** set (set by sqlite3PagerDontWrite()). */ if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ @@ -60175,7 +60175,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM_BKPT, pData); /* Write out the page data. */ - rc = tdsqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); + rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); /* If page 1 was just written, update Pager.dbFileVers to match ** the value now stored in the database file. If writing this @@ -60190,12 +60190,12 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ pPager->aStat[PAGER_STAT_WRITE]++; /* Update any backup objects copying the contents of this pager. */ - tdsqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); PAGERTRACE(("STORE %d page %d hash(%08x)\n", PAGERID(pPager), pgno, pager_pagehash(pList))); IOTRACE(("PGOUT %p %d\n", pPager, pgno)); - PAGER_INCR(tdsqlite3_pager_writedb_count); + PAGER_INCR(sqlite3_pager_writedb_count); }else{ PAGERTRACE(("NOSTORE %d page %d\n", PAGERID(pPager), pgno)); } @@ -60211,7 +60211,7 @@ static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ ** function is a no-op. ** ** SQLITE_OK is returned if everything goes according to plan. An -** SQLITE_IOERR_XXX error code is returned if a call to tdsqlite3OsOpen() +** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() ** fails. */ static int openSubJournal(Pager *pPager){ @@ -60220,11 +60220,11 @@ static int openSubJournal(Pager *pPager){ const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; - int nStmtSpill = tdsqlite3Config.nStmtSpill; + int nStmtSpill = sqlite3Config.nStmtSpill; if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ nStmtSpill = -1; } - rc = tdsqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill); + rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nStmtSpill); } return rc; } @@ -60271,7 +60271,7 @@ static int subjournalPage(PgHdr *pPg){ PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno)); rc = write32bits(pPager->sjfd, offset, pPg->pgno); if( rc==SQLITE_OK ){ - rc = tdsqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); + rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4); } } } @@ -60303,11 +60303,11 @@ static int subjournalPageIfRequired(PgHdr *pPg){ ** out to the database file, if possible. This may involve syncing the ** journal file. ** -** If successful, tdsqlite3PcacheMakeClean() is called on the page and +** If successful, sqlite3PcacheMakeClean() is called on the page and ** SQLITE_OK returned. If an IO error occurs while trying to make the ** page clean, the IO error code is returned. If the page cannot be ** made clean for some other reason, but no error occurs, then SQLITE_OK -** is returned by tdsqlite3PcacheMakeClean() is not called. +** is returned by sqlite3PcacheMakeClean() is not called. */ static int pagerStress(void *p, PgHdr *pPg){ Pager *pPager = (Pager *)p; @@ -60318,7 +60318,7 @@ static int pagerStress(void *p, PgHdr *pPg){ /* The doNotSpill NOSYNC bit is set during times when doing a sync of ** journal (and adding a new header) is not allowed. This occurs - ** during calls to tdsqlite3PagerWrite() while trying to journal multiple + ** during calls to sqlite3PagerWrite() while trying to journal multiple ** pages belonging to the same sector. ** ** The doNotSpill ROLLBACK and OFF bits inhibits all cache spilling @@ -60327,7 +60327,7 @@ static int pagerStress(void *p, PgHdr *pPg){ ** ** Spilling is also prohibited when in an error state since that could ** lead to database corruption. In the current implementation it - ** is impossible for tdsqlite3PcacheFetch() to be called with createFlag==3 + ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 ** while in the error state, hence it is impossible for this routine to ** be called in the error state. Nevertheless, we include a NEVER() ** test for the error state as a safeguard against future changes. @@ -60355,7 +60355,7 @@ static int pagerStress(void *p, PgHdr *pPg){ #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE if( pPager->tempFile==0 ){ - rc = tdsqlite3JournalCreate(pPager->jfd); + rc = sqlite3JournalCreate(pPager->jfd); if( rc!=SQLITE_OK ) return pager_error(pPager, rc); } #endif @@ -60377,7 +60377,7 @@ static int pagerStress(void *p, PgHdr *pPg){ /* Mark the page as clean. */ if( rc==SQLITE_OK ){ PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno)); - tdsqlite3PcacheMakeClean(pPg); + sqlite3PcacheMakeClean(pPg); } return pager_error(pPager, rc); @@ -60386,10 +60386,10 @@ static int pagerStress(void *p, PgHdr *pPg){ /* ** Flush all unreferenced dirty pages to disk. */ -SQLITE_PRIVATE int tdsqlite3PagerFlush(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerFlush(Pager *pPager){ int rc = pPager->errCode; if( !MEMDB ){ - PgHdr *pList = tdsqlite3PcacheDirtyList(pPager->pPCache); + PgHdr *pList = sqlite3PcacheDirtyList(pPager->pPCache); assert( assert_pager_state(pPager) ); while( rc==SQLITE_OK && pList ){ PgHdr *pNext = pList->pDirty; @@ -60406,7 +60406,7 @@ SQLITE_PRIVATE int tdsqlite3PagerFlush(Pager *pPager){ /* ** Allocate and initialize a new Pager object and put a pointer to it ** in *ppPager. The pager should eventually be freed by passing it -** to tdsqlite3PagerClose(). +** to sqlite3PagerClose(). ** ** The zFilename argument is the path to the database file to open. ** If zFilename is NULL then a randomly-named temporary file is created @@ -60417,7 +60417,7 @@ SQLITE_PRIVATE int tdsqlite3PagerFlush(Pager *pPager){ ** ** The nExtra parameter specifies the number of bytes of space allocated ** along with each page reference. This space is available to the user -** via the tdsqlite3PagerGetExtra() API. When a new page is allocated, the +** via the sqlite3PagerGetExtra() API. When a new page is allocated, the ** first 8 bytes of this space are zeroed but the remainder is uninitialized. ** (The extra space is used by btree as the MemPage object.) ** @@ -60432,16 +60432,16 @@ SQLITE_PRIVATE int tdsqlite3PagerFlush(Pager *pPager){ ** successfully, SQLITE_OK is returned and *ppPager set to point to ** the new pager object. If an error occurs, *ppPager is set to NULL ** and error code returned. This function may return SQLITE_NOMEM -** (tdsqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or +** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or ** various SQLITE_IO_XXX errors. */ -SQLITE_PRIVATE int tdsqlite3PagerOpen( - tdsqlite3_vfs *pVfs, /* The virtual file system to use */ +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs *pVfs, /* The virtual file system to use */ Pager **ppPager, /* OUT: Return the Pager structure here */ const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */ int flags, /* flags controlling this file */ - int vfsFlags, /* flags passed through to tdsqlite3_vfs.xOpen() */ + int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ void (*xReinit)(DbPage*) /* Function to reinitialize pages */ ){ u8 *pPtr; @@ -60459,7 +60459,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( char *zPathname = 0; /* Full path to database file */ int nPathname = 0; /* Number of bytes in zPathname */ int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */ - int pcacheSize = tdsqlite3PcacheSize(); /* Bytes to allocate for PCache */ + int pcacheSize = sqlite3PcacheSize(); /* Bytes to allocate for PCache */ u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE; /* Default page size */ const char *zUri = 0; /* URI args to copy */ int nUriByte = 1; /* Number of bytes of URI args at *zUri */ @@ -60467,7 +60467,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( /* Figure out how much space is required for each journal file-handle ** (there are two of them, the main journal and the sub-journal). */ - journalFileSize = ROUND8(tdsqlite3JournalSize(pVfs)); + journalFileSize = ROUND8(sqlite3JournalSize(pVfs)); /* Set the output variable to NULL in case an error occurs. */ *ppPager = 0; @@ -60476,9 +60476,9 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( if( flags & PAGER_MEMORY ){ memDb = 1; if( zFilename && zFilename[0] ){ - zPathname = tdsqlite3DbStrDup(0, zFilename); + zPathname = sqlite3DbStrDup(0, zFilename); if( zPathname==0 ) return SQLITE_NOMEM_BKPT; - nPathname = tdsqlite3Strlen30(zPathname); + nPathname = sqlite3Strlen30(zPathname); zFilename = 0; } } @@ -60491,12 +60491,12 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( if( zFilename && zFilename[0] ){ const char *z; nPathname = pVfs->mxPathname+1; - zPathname = tdsqlite3DbMallocRaw(0, nPathname*2); + zPathname = sqlite3DbMallocRaw(0, nPathname*2); if( zPathname==0 ){ return SQLITE_NOMEM_BKPT; } zPathname[0] = 0; /* Make sure initialized even if FullPathname() fails */ - rc = tdsqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); + rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname); if( rc!=SQLITE_OK ){ if( rc==SQLITE_OK_SYMLINK ){ if( vfsFlags & SQLITE_OPEN_NOFOLLOW ){ @@ -60506,8 +60506,8 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( } } } - nPathname = tdsqlite3Strlen30(zPathname); - z = zUri = &zFilename[tdsqlite3Strlen30(zFilename)+1]; + nPathname = sqlite3Strlen30(zPathname); + z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1]; while( *z ){ z += strlen(z)+1; z += strlen(z)+1; @@ -60525,7 +60525,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( rc = SQLITE_CANTOPEN_BKPT; } if( rc!=SQLITE_OK ){ - tdsqlite3DbFree(0, zPathname); + sqlite3DbFree(0, zPathname); return rc; } } @@ -60535,7 +60535,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( ** file name. The layout in memory is as follows: ** ** Pager object (sizeof(Pager) bytes) - ** PCache object (tdsqlite3PcacheSize() bytes) + ** PCache object (sqlite3PcacheSize() bytes) ** Database file handle (pVfs->szOsFile bytes) ** Sub-journal file handle (journalFileSize bytes) ** Main journal file handle (journalFileSize bytes) @@ -60548,7 +60548,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( ** URI query parameters (nUriByte bytes) ** \0\0 terminator (2 bytes) */ - pPtr = (u8 *)tdsqlite3MallocZero( + pPtr = (u8 *)sqlite3MallocZero( ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(pcacheSize) + /* PCache object */ ROUND8(pVfs->szOsFile) + /* The main db file */ @@ -60566,14 +60566,14 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( ); assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); if( !pPtr ){ - tdsqlite3DbFree(0, zPathname); + sqlite3DbFree(0, zPathname); return SQLITE_NOMEM_BKPT; } pPager = (Pager*)pPtr; pPtr += ROUND8(sizeof(*pPager)); pPager->pPCache = (PCache*)pPtr; pPtr += ROUND8(pcacheSize); - pPager->fd = (tdsqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); - pPager->sjfd = (tdsqlite3_file*)pPtr; pPtr += journalFileSize; - pPager->jfd = (tdsqlite3_file*)pPtr; pPtr += journalFileSize; + pPager->fd = (sqlite3_file*)pPtr; pPtr += ROUND8(pVfs->szOsFile); + pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; + pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); @@ -60584,8 +60584,8 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; memcpy(pPtr, "-journal",8); pPtr += 8 + 1; #ifdef SQLITE_ENABLE_8_3_NAMES - tdsqlite3FileSuffix3(zFilename,pPager->zJournal); - pPtr = (u8*)(pPager->zJournal + tdsqlite3Strlen30(pPager->zJournal)+1); + sqlite3FileSuffix3(zFilename,pPager->zJournal); + pPtr = (u8*)(pPager->zJournal + sqlite3Strlen30(pPager->zJournal)+1); #endif }else{ pPager->zJournal = 0; @@ -60600,8 +60600,8 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( memcpy(pPtr, zPathname, nPathname); pPtr += nPathname; memcpy(pPtr, "-wal", 4); pPtr += 4 + 1; #ifdef SQLITE_ENABLE_8_3_NAMES - tdsqlite3FileSuffix3(zFilename, pPager->zWal); - pPtr = (u8*)(pPager->zWal + tdsqlite3Strlen30(pPager->zWal)+1); + sqlite3FileSuffix3(zFilename, pPager->zWal); + pPtr = (u8*)(pPager->zWal + sqlite3Strlen30(pPager->zWal)+1); #endif }else{ pPager->zWal = 0; @@ -60617,10 +60617,10 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( if( zUri ){ memcpy(pPtr, zUri, nUriByte); /* pPtr += nUriByte; // not needed */ } - /* Double-zero terminator implied by the tdsqlite3MallocZero */ + /* Double-zero terminator implied by the sqlite3MallocZero */ } - if( nPathname ) tdsqlite3DbFree(0, zPathname); + if( nPathname ) sqlite3DbFree(0, zPathname); pPager->pVfs = pVfs; pPager->vfsFlags = vfsFlags; @@ -60628,7 +60628,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( */ if( zFilename && zFilename[0] ){ int fout = 0; /* VFS flags returned by xOpen() */ - rc = tdsqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); + rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); assert( !memDb ); #ifdef SQLITE_ENABLE_DESERIALIZE memJM = (fout&SQLITE_OPEN_MEMORY)!=0; @@ -60640,11 +60640,11 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( ** database file. The default page size is the maximum of: ** ** + SQLITE_DEFAULT_PAGE_SIZE, - ** + The value returned by tdsqlite3OsSectorSize() + ** + The value returned by sqlite3OsSectorSize() ** + The largest page size that can be written atomically. */ if( rc==SQLITE_OK ){ - int iDc = tdsqlite3OsDeviceCharacteristics(pPager->fd); + int iDc = sqlite3OsDeviceCharacteristics(pPager->fd); if( !readOnly ){ setSectorSize(pPager); assert(SQLITE_DEFAULT_PAGE_SIZE<=SQLITE_MAX_DEFAULT_PAGE_SIZE); @@ -60669,9 +60669,9 @@ SQLITE_PRIVATE int tdsqlite3PagerOpen( } #endif } - pPager->noLock = tdsqlite3_uri_boolean(pPager->zFilename, "nolock", 0); + pPager->noLock = sqlite3_uri_boolean(pPager->zFilename, "nolock", 0); if( (iDc & SQLITE_IOCAP_IMMUTABLE)!=0 - || tdsqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ + || sqlite3_uri_boolean(pPager->zFilename, "immutable", 0) ){ vfsFlags |= SQLITE_OPEN_READONLY; goto act_like_temp_file; } @@ -60700,7 +60700,7 @@ act_like_temp_file: */ if( rc==SQLITE_OK ){ assert( pPager->memDb==0 ); - rc = tdsqlite3PagerSetPagesize(pPager, &szPageDflt, -1); + rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); testcase( rc!=SQLITE_OK ); } @@ -60708,16 +60708,16 @@ act_like_temp_file: if( rc==SQLITE_OK ){ nExtra = ROUND8(nExtra); assert( nExtra>=8 && nExtra<1000 ); - rc = tdsqlite3PcacheOpen(szPageDflt, nExtra, !memDb, + rc = sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); } /* If an error occurred above, free the Pager structure and close the file. */ if( rc!=SQLITE_OK ){ - tdsqlite3OsClose(pPager->fd); - tdsqlite3PageFree(pPager->pTmpSpace); - tdsqlite3_free(pPager); + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pPager->pTmpSpace); + sqlite3_free(pPager); return rc; } @@ -60819,7 +60819,7 @@ act_like_temp_file: ** code is returned and the value of *pExists is undefined. */ static int hasHotJournal(Pager *pPager, int *pExists){ - tdsqlite3_vfs * const pVfs = pPager->pVfs; + sqlite3_vfs * const pVfs = pPager->pVfs; int rc = SQLITE_OK; /* Return code */ int exists = 1; /* True if a journal file is present */ int jrnlOpen = !!isOpen(pPager->jfd); @@ -60828,26 +60828,26 @@ static int hasHotJournal(Pager *pPager, int *pExists){ assert( isOpen(pPager->fd) ); assert( pPager->eState==PAGER_OPEN ); - assert( jrnlOpen==0 || ( tdsqlite3OsDeviceCharacteristics(pPager->jfd) & + assert( jrnlOpen==0 || ( sqlite3OsDeviceCharacteristics(pPager->jfd) & SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN )); *pExists = 0; if( !jrnlOpen ){ - rc = tdsqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); + rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); } if( rc==SQLITE_OK && exists ){ int locked = 0; /* True if some process holds a RESERVED lock */ /* Race condition here: Another process might have been holding the - ** the RESERVED lock and have a journal open at the tdsqlite3OsAccess() + ** the RESERVED lock and have a journal open at the sqlite3OsAccess() ** call above, but then delete the journal and drop the lock before - ** we get to the following tdsqlite3OsCheckReservedLock() call. If that + ** we get to the following sqlite3OsCheckReservedLock() call. If that ** is the case, this routine might think there is a hot journal when ** in fact there is none. This results in a false-positive which will ** be dealt with by the playback routine. Ticket #3883. */ - rc = tdsqlite3OsCheckReservedLock(pPager->fd, &locked); + rc = sqlite3OsCheckReservedLock(pPager->fd, &locked); if( rc==SQLITE_OK && !locked ){ Pgno nPage; /* Number of pages in database file */ @@ -60863,12 +60863,12 @@ static int hasHotJournal(Pager *pPager, int *pExists){ ** journal_mode=PERSIST. */ if( nPage==0 && !jrnlOpen ){ - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); if( pagerLockDb(pPager, RESERVED_LOCK)==SQLITE_OK ){ - tdsqlite3OsDelete(pVfs, pPager->zJournal, 0); + sqlite3OsDelete(pVfs, pPager->zJournal, 0); if( !pPager->exclusiveMode ) pagerUnlockDb(pPager, SHARED_LOCK); } - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); }else{ /* The journal file exists and no other connection has a reserved ** or greater lock on the database file. Now check that there is @@ -60878,16 +60878,16 @@ static int hasHotJournal(Pager *pPager, int *pExists){ */ if( !jrnlOpen ){ int f = SQLITE_OPEN_READONLY|SQLITE_OPEN_MAIN_JOURNAL; - rc = tdsqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &f); } if( rc==SQLITE_OK ){ u8 first = 0; - rc = tdsqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); + rc = sqlite3OsRead(pPager->jfd, (void *)&first, 1, 0); if( rc==SQLITE_IOERR_SHORT_READ ){ rc = SQLITE_OK; } if( !jrnlOpen ){ - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); } *pExists = (first!=0); }else if( rc==SQLITE_CANTOPEN ){ @@ -60913,7 +60913,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){ /* ** This function is called to obtain a shared lock on the database file. -** It is illegal to call tdsqlite3PagerGet() until after this function +** It is illegal to call sqlite3PagerGet() until after this function ** has been successfully called. If a shared-lock is already held when ** this function is called, it is a no-op. ** @@ -60938,14 +60938,14 @@ static int hasHotJournal(Pager *pPager, int *pExists){ ** occurs while locking the database, checking for a hot-journal file or ** rolling back a journal file, the IO error code is returned. */ -SQLITE_PRIVATE int tdsqlite3PagerSharedLock(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ /* This routine is only called from b-tree and only when there are no ** outstanding pages. This implies that the pager state should either ** be OPEN or READER. READER is only possible if the pager is or was in ** exclusive access mode. */ - assert( tdsqlite3PcacheRefCount(pPager->pPCache)==0 ); + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); assert( assert_pager_state(pPager) ); assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER ); assert( pPager->errCode==SQLITE_OK ); @@ -61011,19 +61011,19 @@ SQLITE_PRIVATE int tdsqlite3PagerSharedLock(Pager *pPager){ ** function was called and the journal file does not exist. */ if( !isOpen(pPager->jfd) ){ - tdsqlite3_vfs * const pVfs = pPager->pVfs; + sqlite3_vfs * const pVfs = pPager->pVfs; int bExists; /* True if journal file exists */ - rc = tdsqlite3OsAccess( + rc = sqlite3OsAccess( pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); if( rc==SQLITE_OK && bExists ){ int fout = 0; int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL; assert( !pPager->tempFile ); - rc = tdsqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); + rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout); assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); if( rc==SQLITE_OK && fout&SQLITE_OPEN_READONLY ){ rc = SQLITE_CANTOPEN_BKPT; - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); } } } @@ -61079,7 +61079,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSharedLock(Pager *pPager){ ** see if the database has been modified. If the database has changed, ** flush the cache. The hasHeldSharedLock flag prevents this from ** occurring on the very first access to a file, in order to save a - ** single unnecessary tdsqlite3OsRead() call at the start-up. + ** single unnecessary sqlite3OsRead() call at the start-up. ** ** Database changes are detected by looking at 15 bytes beginning ** at offset 24 into the file. The first 4 of these 16 bytes are @@ -61094,7 +61094,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSharedLock(Pager *pPager){ char dbFileVers[sizeof(pPager->dbFileVers)]; IOTRACE(("CKVERS %p %d\n", pPager, sizeof(dbFileVers))); - rc = tdsqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); + rc = sqlite3OsRead(pPager->fd, &dbFileVers, sizeof(dbFileVers), 24); if( rc!=SQLITE_OK ){ if( rc!=SQLITE_IOERR_SHORT_READ ){ goto failed; @@ -61112,7 +61112,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSharedLock(Pager *pPager){ ** to be the right size but is not actually valid. Avoid this ** possibility by unmapping the db here. */ if( USEFETCH(pPager) ){ - tdsqlite3OsUnfetch(pPager->fd, 0, 0); + sqlite3OsUnfetch(pPager->fd, 0, 0); } } } @@ -61156,7 +61156,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSharedLock(Pager *pPager){ ** nothing to rollback, so this routine is a no-op. */ static void pagerUnlockIfUnused(Pager *pPager){ - if( tdsqlite3PcacheRefCount(pPager->pPCache)==0 ){ + if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){ assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */ pagerUnlockAndRollback(pPager); } @@ -61205,13 +61205,13 @@ static void pagerUnlockIfUnused(Pager *pPager){ ** to pgno in Pager.pInJournal (bitvec of pages already written to the ** journal file) and the PagerSavepoint.pInSavepoint bitvecs of any open ** savepoints are set. This means if the page is made writable at any -** point in the future, using a call to tdsqlite3PagerWrite(), its contents +** point in the future, using a call to sqlite3PagerWrite(), its contents ** will not be journaled. This saves IO. ** ** The acquisition might fail for several reasons. In all cases, ** an appropriate error code is returned and *ppPage is set to NULL. ** -** See also tdsqlite3PagerLookup(). Both this routine and Lookup() attempt +** See also sqlite3PagerLookup(). Both this routine and Lookup() attempt ** to find a page in the in-memory cache first. If the page is not already ** in memory, this routine goes to disk to read it in whereas Lookup() ** just returns 0. This routine acquires a read-lock the first time it @@ -61228,7 +61228,7 @@ static int getPageNormal( int rc = SQLITE_OK; PgHdr *pPg; u8 noContent; /* True if PAGER_GET_NOCONTENT is set */ - tdsqlite3_pcache_page *pBase; + sqlite3_pcache_page *pBase; assert( pPager->errCode==SQLITE_OK ); assert( pPager->eState>=PAGER_READER ); @@ -61236,17 +61236,17 @@ static int getPageNormal( assert( pPager->hasHeldSharedLock==1 ); if( pgno==0 ) return SQLITE_CORRUPT_BKPT; - pBase = tdsqlite3PcacheFetch(pPager->pPCache, pgno, 3); + pBase = sqlite3PcacheFetch(pPager->pPCache, pgno, 3); if( pBase==0 ){ pPg = 0; - rc = tdsqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); + rc = sqlite3PcacheFetchStress(pPager->pPCache, pgno, &pBase); if( rc!=SQLITE_OK ) goto pager_acquire_err; if( pBase==0 ){ rc = SQLITE_NOMEM_BKPT; goto pager_acquire_err; } } - pPg = *ppPage = tdsqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); + pPg = *ppPage = sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pBase); assert( pPg==(*ppPage) ); assert( pPg->pgno==pgno ); assert( pPg->pPager==pPager || pPg->pPager==0 ); @@ -61286,14 +61286,14 @@ static int getPageNormal( ** to test the case where a malloc error occurs while trying to set ** a bit in a bit vector. */ - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); if( pgno<=pPager->dbOrigSize ){ - TESTONLY( rc = ) tdsqlite3BitvecSet(pPager->pInJournal, pgno); + TESTONLY( rc = ) sqlite3BitvecSet(pPager->pInJournal, pgno); testcase( rc==SQLITE_NOMEM ); } TESTONLY( rc = ) addToSavepointBitvecs(pPager, pgno); testcase( rc==SQLITE_NOMEM ); - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); } memset(pPg->pData, 0, pPager->pageSize); IOTRACE(("ZERO %p %d\n", pPager, pgno)); @@ -61312,7 +61312,7 @@ static int getPageNormal( pager_acquire_err: assert( rc!=SQLITE_OK ); if( pPg ){ - tdsqlite3PcacheDrop(pPg); + sqlite3PcacheDrop(pPg); } pagerUnlockIfUnused(pPager); *ppPage = 0; @@ -61357,7 +61357,7 @@ static int getPageMMap( assert( pPager->errCode==SQLITE_OK ); if( bMmapOk && pagerUseWal(pPager) ){ - rc = tdsqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); + rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iFrame); if( rc!=SQLITE_OK ){ *ppPage = 0; return rc; @@ -61365,17 +61365,17 @@ static int getPageMMap( } if( bMmapOk && iFrame==0 ){ void *pData = 0; - rc = tdsqlite3OsFetch(pPager->fd, + rc = sqlite3OsFetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData ); if( rc==SQLITE_OK && pData ){ if( pPager->eState>PAGER_READER || pPager->tempFile ){ - pPg = tdsqlite3PagerLookup(pPager, pgno); + pPg = sqlite3PagerLookup(pPager, pgno); } if( pPg==0 ){ rc = pagerAcquireMapPage(pPager, pgno, pData, &pPg); }else{ - tdsqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); + sqlite3OsUnfetch(pPager->fd, (i64)(pgno-1)*pPager->pageSize, pData); } if( pPg ){ assert( rc==SQLITE_OK ); @@ -61409,7 +61409,7 @@ static int getPageError( /* Dispatch all page fetch requests to the appropriate getter method. */ -SQLITE_PRIVATE int tdsqlite3PagerGet( +SQLITE_PRIVATE int sqlite3PagerGet( Pager *pPager, /* The pager open on the database file */ Pgno pgno, /* Page number to fetch */ DbPage **ppPage, /* Write a pointer to the page here */ @@ -61423,58 +61423,58 @@ SQLITE_PRIVATE int tdsqlite3PagerGet( ** not read the page from disk. Return a pointer to the page, ** or 0 if the page is not in cache. ** -** See also tdsqlite3PagerGet(). The difference between this routine -** and tdsqlite3PagerGet() is that _get() will go to the disk and read +** See also sqlite3PagerGet(). The difference between this routine +** and sqlite3PagerGet() is that _get() will go to the disk and read ** in the page if the page is not already in cache. This routine ** returns NULL if the page is not in cache or if a disk I/O error ** has ever happened. */ -SQLITE_PRIVATE DbPage *tdsqlite3PagerLookup(Pager *pPager, Pgno pgno){ - tdsqlite3_pcache_page *pPage; +SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ + sqlite3_pcache_page *pPage; assert( pPager!=0 ); assert( pgno!=0 ); assert( pPager->pPCache!=0 ); - pPage = tdsqlite3PcacheFetch(pPager->pPCache, pgno, 0); + pPage = sqlite3PcacheFetch(pPager->pPCache, pgno, 0); assert( pPage==0 || pPager->hasHeldSharedLock ); if( pPage==0 ) return 0; - return tdsqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); + return sqlite3PcacheFetchFinish(pPager->pPCache, pgno, pPage); } /* ** Release a page reference. ** -** The tdsqlite3PagerUnref() and tdsqlite3PagerUnrefNotNull() may only be +** The sqlite3PagerUnref() and sqlite3PagerUnrefNotNull() may only be ** used if we know that the page being released is not the last page. ** The btree layer always holds page1 open until the end, so these first ** to routines can be used to release any page other than BtShared.pPage1. ** -** Use tdsqlite3PagerUnrefPageOne() to release page1. This latter routine +** Use sqlite3PagerUnrefPageOne() to release page1. This latter routine ** checks the total number of outstanding pages and if the number of ** pages reaches zero it drops the database lock. */ -SQLITE_PRIVATE void tdsqlite3PagerUnrefNotNull(DbPage *pPg){ +SQLITE_PRIVATE void sqlite3PagerUnrefNotNull(DbPage *pPg){ TESTONLY( Pager *pPager = pPg->pPager; ) assert( pPg!=0 ); if( pPg->flags & PGHDR_MMAP ){ assert( pPg->pgno!=1 ); /* Page1 is never memory mapped */ pagerReleaseMapPage(pPg); }else{ - tdsqlite3PcacheRelease(pPg); + sqlite3PcacheRelease(pPg); } /* Do not use this routine to release the last reference to page1 */ - assert( tdsqlite3PcacheRefCount(pPager->pPCache)>0 ); + assert( sqlite3PcacheRefCount(pPager->pPCache)>0 ); } -SQLITE_PRIVATE void tdsqlite3PagerUnref(DbPage *pPg){ - if( pPg ) tdsqlite3PagerUnrefNotNull(pPg); +SQLITE_PRIVATE void sqlite3PagerUnref(DbPage *pPg){ + if( pPg ) sqlite3PagerUnrefNotNull(pPg); } -SQLITE_PRIVATE void tdsqlite3PagerUnrefPageOne(DbPage *pPg){ +SQLITE_PRIVATE void sqlite3PagerUnrefPageOne(DbPage *pPg){ Pager *pPager; assert( pPg!=0 ); assert( pPg->pgno==1 ); assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */ pPager = pPg->pPager; - tdsqlite3PagerResetLockTimeout(pPager); - tdsqlite3PcacheRelease(pPg); + sqlite3PagerResetLockTimeout(pPager); + sqlite3PcacheRelease(pPg); pagerUnlockIfUnused(pPager); } @@ -61502,7 +61502,7 @@ SQLITE_PRIVATE void tdsqlite3PagerUnrefPageOne(DbPage *pPg){ */ static int pager_open_journal(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ - tdsqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */ + sqlite3_vfs * const pVfs = pPager->pVfs; /* Local cache of vfs pointer */ assert( pPager->eState==PAGER_WRITER_LOCKED ); assert( assert_pager_state(pPager) ); @@ -61514,7 +61514,7 @@ static int pager_open_journal(Pager *pPager){ if( NEVER(pPager->errCode) ) return pPager->errCode; if( !pagerUseWal(pPager) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ - pPager->pInJournal = tdsqlite3BitvecCreate(pPager->dbSize); + pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize); if( pPager->pInJournal==0 ){ return SQLITE_NOMEM_BKPT; } @@ -61522,14 +61522,14 @@ static int pager_open_journal(Pager *pPager){ /* Open the journal file if it is not already open. */ if( !isOpen(pPager->jfd) ){ if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ - tdsqlite3MemJournalOpen(pPager->jfd); + sqlite3MemJournalOpen(pPager->jfd); }else{ int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE; int nSpill; if( pPager->tempFile ){ flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL); - nSpill = tdsqlite3Config.nStmtSpill; + nSpill = sqlite3Config.nStmtSpill; }else{ flags |= SQLITE_OPEN_MAIN_JOURNAL; nSpill = jrnlBufferSize(pPager); @@ -61539,7 +61539,7 @@ static int pager_open_journal(Pager *pPager){ ** it was originally opened. */ rc = databaseIsUnmoved(pPager); if( rc==SQLITE_OK ){ - rc = tdsqlite3JournalOpen ( + rc = sqlite3JournalOpen ( pVfs, pPager->zJournal, pPager->jfd, flags, nSpill ); } @@ -61562,7 +61562,7 @@ static int pager_open_journal(Pager *pPager){ } if( rc!=SQLITE_OK ){ - tdsqlite3BitvecDestroy(pPager->pInJournal); + sqlite3BitvecDestroy(pPager->pInJournal); pPager->pInJournal = 0; }else{ assert( pPager->eState==PAGER_WRITER_LOCKED ); @@ -61589,7 +61589,7 @@ static int pager_open_journal(Pager *pPager){ ** sub-journal is implemented in-memory if pPager is an in-memory database, ** or using a temporary file otherwise. */ -SQLITE_PRIVATE int tdsqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ +SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ int rc = SQLITE_OK; if( pPager->errCode ) return pPager->errCode; @@ -61603,12 +61603,12 @@ SQLITE_PRIVATE int tdsqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemo /* If the pager is configured to use locking_mode=exclusive, and an ** exclusive lock on the database is not already held, obtain it now. */ - if( pPager->exclusiveMode && tdsqlite3WalExclusiveMode(pPager->pWal, -1) ){ + if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){ rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ return rc; } - (void)tdsqlite3WalExclusiveMode(pPager->pWal, 1); + (void)sqlite3WalExclusiveMode(pPager->pWal, 1); } /* Grab the write lock on the log file. If successful, upgrade to @@ -61616,7 +61616,7 @@ SQLITE_PRIVATE int tdsqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemo ** The busy-handler is not invoked if another connection already ** holds the write-lock. If possible, the upper layer will call it. */ - rc = tdsqlite3WalBeginWriteTransaction(pPager->pWal); + rc = sqlite3WalBeginWriteTransaction(pPager->pWal); }else{ /* Obtain a RESERVED lock on the database file. If the exFlag parameter ** is true, then immediately upgrade this to an EXCLUSIVE lock. The @@ -61685,14 +61685,14 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){ rc = write32bits(pPager->jfd, iOff, pPg->pgno); if( rc!=SQLITE_OK ) return rc; - rc = tdsqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); + rc = sqlite3OsWrite(pPager->jfd, pData2, pPager->pageSize, iOff+4); if( rc!=SQLITE_OK ) return rc; rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); if( rc!=SQLITE_OK ) return rc; IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, pPager->journalOff, pPager->pageSize)); - PAGER_INCR(tdsqlite3_pager_writej_count); + PAGER_INCR(sqlite3_pager_writej_count); PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", PAGERID(pPager), pPg->pgno, ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); @@ -61700,7 +61700,7 @@ static SQLITE_NOINLINE int pagerAddPageToRollbackJournal(PgHdr *pPg){ pPager->journalOff += 8 + pPager->pageSize; pPager->nRec++; assert( pPager->pInJournal!=0 ); - rc = tdsqlite3BitvecSet(pPager->pInJournal, pPg->pgno); + rc = sqlite3BitvecSet(pPager->pInJournal, pPg->pgno); testcase( rc==SQLITE_NOMEM ); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); rc |= addToSavepointBitvecs(pPager, pPg->pgno); @@ -61736,8 +61736,8 @@ static int pager_write(PgHdr *pPg){ ** obtained the necessary locks to begin the write-transaction, but the ** rollback journal might not yet be open. Open it now if this is the case. ** - ** This is done before calling tdsqlite3PcacheMakeDirty() on the page. - ** Otherwise, if it were done after calling tdsqlite3PcacheMakeDirty(), then + ** This is done before calling sqlite3PcacheMakeDirty() on the page. + ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then ** an error might occur and the pager would end up in WRITER_LOCKED state ** with pages marked as dirty in the cache. */ @@ -61749,7 +61749,7 @@ static int pager_write(PgHdr *pPg){ assert( assert_pager_state(pPager) ); /* Mark the page that is about to be modified as dirty. */ - tdsqlite3PcacheMakeDirty(pPg); + sqlite3PcacheMakeDirty(pPg); /* If a rollback journal is in use, them make sure the page that is about ** to change is in the rollback journal, or if the page is a new page off @@ -61757,7 +61757,7 @@ static int pager_write(PgHdr *pPg){ */ assert( (pPager->pInJournal!=0) == isOpen(pPager->jfd) ); if( pPager->pInJournal!=0 - && tdsqlite3BitvecTestNotNull(pPager->pInJournal, pPg->pgno)==0 + && sqlite3BitvecTestNotNull(pPager->pInJournal, pPg->pgno)==0 ){ assert( pagerUseWal(pPager)==0 ); if( pPg->pgno<=pPager->dbOrigSize ){ @@ -61797,7 +61797,7 @@ static int pager_write(PgHdr *pPg){ } /* -** This is a variant of tdsqlite3PagerWrite() that runs when the sector size +** This is a variant of sqlite3PagerWrite() that runs when the sector size ** is larger than the page size. SQLite makes the (reasonable) assumption that ** all bytes of a sector are written together by hardware. Hence, all bytes of ** a sector need to be journalled in case of a power loss in the middle of @@ -61846,22 +61846,22 @@ static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ for(ii=0; iipgno || !tdsqlite3BitvecTest(pPager->pInJournal, pg) ){ + if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ if( pg!=PAGER_MJ_PGNO(pPager) ){ - rc = tdsqlite3PagerGet(pPager, pg, &pPage, 0); + rc = sqlite3PagerGet(pPager, pg, &pPage, 0); if( rc==SQLITE_OK ){ rc = pager_write(pPage); if( pPage->flags&PGHDR_NEED_SYNC ){ needSync = 1; } - tdsqlite3PagerUnrefNotNull(pPage); + sqlite3PagerUnrefNotNull(pPage); } } - }else if( (pPage = tdsqlite3PagerLookup(pPager, pg))!=0 ){ + }else if( (pPage = sqlite3PagerLookup(pPager, pg))!=0 ){ if( pPage->flags&PGHDR_NEED_SYNC ){ needSync = 1; } - tdsqlite3PagerUnrefNotNull(pPage); + sqlite3PagerUnrefNotNull(pPage); } } @@ -61874,10 +61874,10 @@ static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ if( rc==SQLITE_OK && needSync ){ assert( !MEMDB ); for(ii=0; iiflags |= PGHDR_NEED_SYNC; - tdsqlite3PagerUnrefNotNull(pPage); + sqlite3PagerUnrefNotNull(pPage); } } } @@ -61901,7 +61901,7 @@ static SQLITE_NOINLINE int pagerWriteLargeSector(PgHdr *pPg){ ** If an error occurs, SQLITE_NOMEM or an IO error code is returned ** as appropriate. Otherwise, SQLITE_OK. */ -SQLITE_PRIVATE int tdsqlite3PagerWrite(PgHdr *pPg){ +SQLITE_PRIVATE int sqlite3PagerWrite(PgHdr *pPg){ Pager *pPager = pPg->pPager; assert( (pPg->flags & PGHDR_MMAP)==0 ); assert( pPager->eState>=PAGER_WRITER_LOCKED ); @@ -61921,11 +61921,11 @@ SQLITE_PRIVATE int tdsqlite3PagerWrite(PgHdr *pPg){ /* ** Return TRUE if the page given in the argument was previously passed -** to tdsqlite3PagerWrite(). In other words, return TRUE if it is ok +** to sqlite3PagerWrite(). In other words, return TRUE if it is ok ** to change the content of the page. */ #ifndef NDEBUG -SQLITE_PRIVATE int tdsqlite3PagerIswriteable(DbPage *pPg){ +SQLITE_PRIVATE int sqlite3PagerIswriteable(DbPage *pPg){ return pPg->flags & PGHDR_WRITEABLE; } #endif @@ -61950,7 +61950,7 @@ SQLITE_PRIVATE int tdsqlite3PagerIswriteable(DbPage *pPg){ ** to be written out to disk so that it may be read back in if the ** current transaction is rolled back. */ -SQLITE_PRIVATE void tdsqlite3PagerDontWrite(PgHdr *pPg){ +SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ Pager *pPager = pPg->pPager; if( !pPager->tempFile && (pPg->flags&PGHDR_DIRTY) && pPager->nSavepoint==0 ){ PAGERTRACE(("DONT_WRITE page %d of %d\n", pPg->pgno, PAGERID(pPager))); @@ -61974,7 +61974,7 @@ SQLITE_PRIVATE void tdsqlite3PagerDontWrite(PgHdr *pPg){ ** unconditional update of the change counters. ** ** If the isDirectMode flag is zero, then this is done by calling -** tdsqlite3PagerWrite() on page 1, then modifying the contents of the +** sqlite3PagerWrite() on page 1, then modifying the contents of the ** page data. In this case the file will be updated when the current ** transaction is committed. ** @@ -61982,7 +61982,7 @@ SQLITE_PRIVATE void tdsqlite3PagerDontWrite(PgHdr *pPg){ ** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, ** if isDirect is non-zero, then the database file is updated directly ** by writing an updated version of page 1 using a call to the -** tdsqlite3OsWrite() function. +** sqlite3OsWrite() function. */ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ int rc = SQLITE_OK; @@ -62016,7 +62016,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ assert( !pPager->tempFile && isOpen(pPager->fd) ); /* Open page 1 of the file for writing. */ - rc = tdsqlite3PagerGet(pPager, 1, &pPgHdr, 0); + rc = sqlite3PagerGet(pPager, 1, &pPgHdr, 0); assert( pPgHdr==0 || rc==SQLITE_OK ); /* If page one was fetched successfully, and this function is not @@ -62025,7 +62025,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. */ if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ - rc = tdsqlite3PagerWrite(pPgHdr); + rc = sqlite3PagerWrite(pPgHdr); } if( rc==SQLITE_OK ){ @@ -62038,7 +62038,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ assert( pPager->dbFileSize>0 ); CODEC2(pPager, pPgHdr->pData, 1, 6, rc=SQLITE_NOMEM_BKPT, zBuf); if( rc==SQLITE_OK ){ - rc = tdsqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); + rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); pPager->aStat[PAGER_STAT_WRITE]++; } if( rc==SQLITE_OK ){ @@ -62055,7 +62055,7 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ } /* Release the page reference. */ - tdsqlite3PagerUnref(pPgHdr); + sqlite3PagerUnref(pPgHdr); } return rc; } @@ -62067,14 +62067,14 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ ** If successful, or if called on a pager for which it is a no-op, this ** function returns SQLITE_OK. Otherwise, an IO error code is returned. */ -SQLITE_PRIVATE int tdsqlite3PagerSync(Pager *pPager, const char *zMaster){ +SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager, const char *zMaster){ int rc = SQLITE_OK; void *pArg = (void*)zMaster; - rc = tdsqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); + rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC, pArg); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; if( rc==SQLITE_OK && !pPager->noSync ){ assert( !MEMDB ); - rc = tdsqlite3OsSync(pPager->fd, pPager->syncFlags); + rc = sqlite3OsSync(pPager->fd, pPager->syncFlags); } return rc; } @@ -62090,7 +62090,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSync(Pager *pPager, const char *zMaster){ ** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is ** returned. */ -SQLITE_PRIVATE int tdsqlite3PagerExclusiveLock(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerExclusiveLock(Pager *pPager){ int rc = pPager->errCode; assert( assert_pager_state(pPager) ); if( rc==SQLITE_OK ){ @@ -62125,14 +62125,14 @@ SQLITE_PRIVATE int tdsqlite3PagerExclusiveLock(Pager *pPager){ ** delete the master journal file if specified). ** ** Note that if zMaster==NULL, this does not overwrite a previous value -** passed to an tdsqlite3PagerCommitPhaseOne() call. +** passed to an sqlite3PagerCommitPhaseOne() call. ** ** If the final parameter - noSync - is true, then the database file itself -** is not synced. The caller must call tdsqlite3PagerSync() directly to +** is not synced. The caller must call sqlite3PagerSync() directly to ** sync the database file before calling CommitPhaseTwo() to delete the ** journal file in this case. */ -SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( +SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( Pager *pPager, /* Pager object */ const char *zMaster, /* If not NULL, the master journal name */ int noSync /* True to omit the xSync on the db file */ @@ -62150,7 +62150,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( if( NEVER(pPager->errCode) ) return pPager->errCode; /* Provide the ability to easily simulate an I/O error during testing */ - if( tdsqlite3FaultSim(400) ) return SQLITE_IOERR; + if( sqlite3FaultSim(400) ) return SQLITE_IOERR; PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", pPager->zFilename, zMaster, pPager->dbSize)); @@ -62164,16 +62164,16 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( /* If this is an in-memory db, or no pages have been written to, or this ** function has already been called, it is mostly a no-op. However, any ** backup in progress needs to be restarted. */ - tdsqlite3BackupRestart(pPager->pBackup); + sqlite3BackupRestart(pPager->pBackup); }else{ PgHdr *pList; if( pagerUseWal(pPager) ){ PgHdr *pPageOne = 0; - pList = tdsqlite3PcacheDirtyList(pPager->pPCache); + pList = sqlite3PcacheDirtyList(pPager->pPCache); if( pList==0 ){ /* Must have at least one page for the WAL commit flag. ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */ - rc = tdsqlite3PagerGet(pPager, 1, &pPageOne, 0); + rc = sqlite3PagerGet(pPager, 1, &pPageOne, 0); pList = pPageOne; pList->pDirty = 0; } @@ -62181,9 +62181,9 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( if( ALWAYS(pList) ){ rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1); } - tdsqlite3PagerUnref(pPageOne); + sqlite3PagerUnref(pPageOne); if( rc==SQLITE_OK ){ - tdsqlite3PcacheCleanAll(pPager->pPCache); + sqlite3PcacheCleanAll(pPager->pPCache); } }else{ /* The bBatch boolean is true if the batch-atomic-write commit method @@ -62191,11 +62191,11 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( ** is enabled. */ #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE - tdsqlite3_file *fd = pPager->fd; + sqlite3_file *fd = pPager->fd; int bBatch = zMaster==0 /* An SQLITE_IOCAP_BATCH_ATOMIC commit */ - && (tdsqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC) + && (sqlite3OsDeviceCharacteristics(fd) & SQLITE_IOCAP_BATCH_ATOMIC) && !pPager->noSync - && tdsqlite3JournalIsInMemory(pPager->jfd); + && sqlite3JournalIsInMemory(pPager->jfd); #else # define bBatch 0 #endif @@ -62214,7 +62214,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( ** If the optimization was not enabled at compile time, then the ** pager_incr_changecounter() function is called to update the change ** counter in 'indirect-mode'. If the optimization is compiled in but - ** is not applicable to this transaction, call tdsqlite3JournalCreate() + ** is not applicable to this transaction, call sqlite3JournalCreate() ** to make sure the journal file has actually been created, then call ** pager_incr_changecounter() to update the change-counter in indirect ** mode. @@ -62233,7 +62233,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( if( !zMaster && isOpen(pPager->jfd) && pPager->journalOff==jrnlBufferSize(pPager) && pPager->dbSize>=pPager->dbOrigSize - && (!(pPg = tdsqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) + && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) ){ /* Update the db file change counter via the direct-write method. The ** following call will modify the in-memory representation of page 1 @@ -62243,7 +62243,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( */ rc = pager_incr_changecounter(pPager, 1); }else{ - rc = tdsqlite3JournalCreate(pPager->jfd); + rc = sqlite3JournalCreate(pPager->jfd); if( rc==SQLITE_OK ){ rc = pager_incr_changecounter(pPager, 0); } @@ -62252,7 +62252,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( #else /* SQLITE_ENABLE_ATOMIC_WRITE */ #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE if( zMaster ){ - rc = tdsqlite3JournalCreate(pPager->jfd); + rc = sqlite3JournalCreate(pPager->jfd); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; assert( bBatch==0 ); } @@ -62282,29 +62282,29 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( rc = syncJournal(pPager, 0); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - pList = tdsqlite3PcacheDirtyList(pPager->pPCache); + pList = sqlite3PcacheDirtyList(pPager->pPCache); #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE if( bBatch ){ - rc = tdsqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); if( rc==SQLITE_OK ){ rc = pager_write_pagelist(pPager, pList); if( rc==SQLITE_OK ){ - rc = tdsqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); + rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); } if( rc!=SQLITE_OK ){ - tdsqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); + sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0); } } if( (rc&0xFF)==SQLITE_IOERR && rc!=SQLITE_IOERR_NOMEM ){ - rc = tdsqlite3JournalCreate(pPager->jfd); + rc = sqlite3JournalCreate(pPager->jfd); if( rc!=SQLITE_OK ){ - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); goto commit_phase_one_exit; } bBatch = 0; }else{ - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); } } #endif /* SQLITE_ENABLE_BATCH_ATOMIC_WRITE */ @@ -62316,7 +62316,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( assert( rc!=SQLITE_IOERR_BLOCKED ); goto commit_phase_one_exit; } - tdsqlite3PcacheCleanAll(pPager->pPCache); + sqlite3PcacheCleanAll(pPager->pPCache); /* If the file on disk is smaller than the database image, use ** pager_truncate to grow the file here. This can happen if the database @@ -62333,7 +62333,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseOne( /* Finally, sync the database file. */ if( !noSync ){ - rc = tdsqlite3PagerSync(pPager, zMaster); + rc = sqlite3PagerSync(pPager, zMaster); } IOTRACE(("DBSYNC %p\n", pPager)) } @@ -62362,7 +62362,7 @@ commit_phase_one_exit: ** If an error occurs, an IO error code is returned and the pager ** moves into the error state. Otherwise, SQLITE_OK is returned. */ -SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseTwo(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ /* This routine should not be called if a prior error has occurred. @@ -62428,7 +62428,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCommitPhaseTwo(Pager *pPager){ ** their pre-transaction state by re-reading data from the database or ** WAL files. The WAL transaction is then closed. */ -SQLITE_PRIVATE int tdsqlite3PagerRollback(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerRollback(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); @@ -62442,7 +62442,7 @@ SQLITE_PRIVATE int tdsqlite3PagerRollback(Pager *pPager){ if( pagerUseWal(pPager) ){ int rc2; - rc = tdsqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); + rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, -1); rc2 = pager_end_transaction(pPager, pPager->setMaster, 0); if( rc==SQLITE_OK ) rc = rc2; }else if( !isOpen(pPager->jfd) || pPager->eState==PAGER_WRITER_LOCKED ){ @@ -62478,7 +62478,7 @@ SQLITE_PRIVATE int tdsqlite3PagerRollback(Pager *pPager){ ** Return TRUE if the database file is opened read-only. Return FALSE ** if the database is (in theory) writable. */ -SQLITE_PRIVATE u8 tdsqlite3PagerIsreadonly(Pager *pPager){ +SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager *pPager){ return pPager->readOnly; } @@ -62486,8 +62486,8 @@ SQLITE_PRIVATE u8 tdsqlite3PagerIsreadonly(Pager *pPager){ /* ** Return the sum of the reference counts for all pages held by pPager. */ -SQLITE_PRIVATE int tdsqlite3PagerRefcount(Pager *pPager){ - return tdsqlite3PcacheRefCount(pPager->pPCache); +SQLITE_PRIVATE int sqlite3PagerRefcount(Pager *pPager){ + return sqlite3PcacheRefCount(pPager->pPCache); } #endif @@ -62495,30 +62495,30 @@ SQLITE_PRIVATE int tdsqlite3PagerRefcount(Pager *pPager){ ** Return the approximate number of bytes of memory currently ** used by the pager and its associated cache. */ -SQLITE_PRIVATE int tdsqlite3PagerMemUsed(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerMemUsed(Pager *pPager){ int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr) + 5*sizeof(void*); - return perPageSize*tdsqlite3PcachePagecount(pPager->pPCache) - + tdsqlite3MallocSize(pPager) + return perPageSize*sqlite3PcachePagecount(pPager->pPCache) + + sqlite3MallocSize(pPager) + pPager->pageSize; } /* ** Return the number of references to the specified page. */ -SQLITE_PRIVATE int tdsqlite3PagerPageRefcount(DbPage *pPage){ - return tdsqlite3PcachePageRefcount(pPage); +SQLITE_PRIVATE int sqlite3PagerPageRefcount(DbPage *pPage){ + return sqlite3PcachePageRefcount(pPage); } #ifdef SQLITE_TEST /* ** This routine is used for testing and analysis only. */ -SQLITE_PRIVATE int *tdsqlite3PagerStats(Pager *pPager){ +SQLITE_PRIVATE int *sqlite3PagerStats(Pager *pPager){ static int a[11]; - a[0] = tdsqlite3PcacheRefCount(pPager->pPCache); - a[1] = tdsqlite3PcachePagecount(pPager->pPCache); - a[2] = tdsqlite3PcacheGetCachesize(pPager->pPCache); + a[0] = sqlite3PcacheRefCount(pPager->pPCache); + a[1] = sqlite3PcachePagecount(pPager->pPCache); + a[2] = sqlite3PcacheGetCachesize(pPager->pPCache); a[3] = pPager->eState==PAGER_OPEN ? -1 : (int) pPager->dbSize; a[4] = pPager->eState; a[5] = pPager->errCode; @@ -62542,7 +62542,7 @@ SQLITE_PRIVATE int *tdsqlite3PagerStats(Pager *pPager){ ** reset parameter is non-zero, the cache hit or miss count is zeroed before ** returning. */ -SQLITE_PRIVATE void tdsqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ +SQLITE_PRIVATE void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ assert( eStat==SQLITE_DBSTATUS_CACHE_HIT || eStat==SQLITE_DBSTATUS_CACHE_MISS @@ -62565,7 +62565,7 @@ SQLITE_PRIVATE void tdsqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, /* ** Return true if this is an in-memory or temp-file backed pager. */ -SQLITE_PRIVATE int tdsqlite3PagerIsMemdb(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){ return pPager->tempFile; } @@ -62593,7 +62593,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ ** if the allocation fails. Otherwise, zero the new portion in case a ** malloc failure occurs while populating it in the for(...) loop below. */ - aNew = (PagerSavepoint *)tdsqlite3Realloc( + aNew = (PagerSavepoint *)sqlite3Realloc( pPager->aSavepoint, sizeof(PagerSavepoint)*nSavepoint ); if( !aNew ){ @@ -62611,12 +62611,12 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); } aNew[ii].iSubRec = pPager->nSubRec; - aNew[ii].pInSavepoint = tdsqlite3BitvecCreate(pPager->dbSize); + aNew[ii].pInSavepoint = sqlite3BitvecCreate(pPager->dbSize); if( !aNew[ii].pInSavepoint ){ return SQLITE_NOMEM_BKPT; } if( pagerUseWal(pPager) ){ - tdsqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); + sqlite3WalSavepoint(pPager->pWal, aNew[ii].aWalData); } pPager->nSavepoint = ii+1; } @@ -62624,7 +62624,7 @@ static SQLITE_NOINLINE int pagerOpenSavepoint(Pager *pPager, int nSavepoint){ assertTruncateConstraint(pPager); return rc; } -SQLITE_PRIVATE int tdsqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ +SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ assert( pPager->eState>=PAGER_WRITER_LOCKED ); assert( assert_pager_state(pPager) ); @@ -62654,7 +62654,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ ** ** If a negative value is passed to this function, then the current ** transaction is rolled back. This is different to calling -** tdsqlite3PagerRollback() because this function does not terminate +** sqlite3PagerRollback() because this function does not terminate ** the transaction or unlock the database, it just restores the ** contents of the database to its original state. ** @@ -62666,7 +62666,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ ** or an IO error code if an IO error occurs while rolling back a ** savepoint. If no errors occur, SQLITE_OK is returned. */ -SQLITE_PRIVATE int tdsqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ +SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ int rc = pPager->errCode; #ifdef SQLITE_ENABLE_ZIPVFS @@ -62686,7 +62686,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint */ nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); for(ii=nNew; iinSavepoint; ii++){ - tdsqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); + sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint); } pPager->nSavepoint = nNew; @@ -62695,8 +62695,8 @@ SQLITE_PRIVATE int tdsqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint if( op==SAVEPOINT_RELEASE ){ if( nNew==0 && isOpen(pPager->sjfd) ){ /* Only truncate if it is an in-memory sub-journal. */ - if( tdsqlite3JournalIsInMemory(pPager->sjfd) ){ - rc = tdsqlite3OsTruncate(pPager->sjfd, 0); + if( sqlite3JournalIsInMemory(pPager->sjfd) ){ + rc = sqlite3OsTruncate(pPager->sjfd, 0); assert( rc==SQLITE_OK ); } pPager->nSubRec = 0; @@ -62743,9 +62743,9 @@ SQLITE_PRIVATE int tdsqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint ** participate in shared-cache. ** ** The return value to this routine is always safe to use with -** tdsqlite3_uri_parameter() and tdsqlite3_filename_database() and friends. +** sqlite3_uri_parameter() and sqlite3_filename_database() and friends. */ -SQLITE_PRIVATE const char *tdsqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ +SQLITE_PRIVATE const char *sqlite3PagerFilename(const Pager *pPager, int nullIfMemDb){ static const char zFake[] = { 0x00, 0x01, 0x00, 0x00, 0x00 }; return (nullIfMemDb && pPager->memDb) ? &zFake[3] : pPager->zFilename; } @@ -62753,7 +62753,7 @@ SQLITE_PRIVATE const char *tdsqlite3PagerFilename(const Pager *pPager, int nullI /* ** Return the VFS structure for the pager. */ -SQLITE_PRIVATE tdsqlite3_vfs *tdsqlite3PagerVfs(Pager *pPager){ +SQLITE_PRIVATE sqlite3_vfs *sqlite3PagerVfs(Pager *pPager){ return pPager->pVfs; } @@ -62762,7 +62762,7 @@ SQLITE_PRIVATE tdsqlite3_vfs *tdsqlite3PagerVfs(Pager *pPager){ ** with the pager. This might return NULL if the file has ** not yet been opened. */ -SQLITE_PRIVATE tdsqlite3_file *tdsqlite3PagerFile(Pager *pPager){ +SQLITE_PRIVATE sqlite3_file *sqlite3PagerFile(Pager *pPager){ return pPager->fd; } @@ -62770,9 +62770,9 @@ SQLITE_PRIVATE tdsqlite3_file *tdsqlite3PagerFile(Pager *pPager){ /* ** Reset the lock timeout for pager. */ -SQLITE_PRIVATE void tdsqlite3PagerResetLockTimeout(Pager *pPager){ +SQLITE_PRIVATE void sqlite3PagerResetLockTimeout(Pager *pPager){ int x = 0; - tdsqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x); + sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x); } #endif @@ -62780,18 +62780,18 @@ SQLITE_PRIVATE void tdsqlite3PagerResetLockTimeout(Pager *pPager){ ** Return the file handle for the journal file (if it exists). ** This will be either the rollback journal or the WAL file. */ -SQLITE_PRIVATE tdsqlite3_file *tdsqlite3PagerJrnlFile(Pager *pPager){ +SQLITE_PRIVATE sqlite3_file *sqlite3PagerJrnlFile(Pager *pPager){ #if SQLITE_OMIT_WAL return pPager->jfd; #else - return pPager->pWal ? tdsqlite3WalFile(pPager->pWal) : pPager->jfd; + return pPager->pWal ? sqlite3WalFile(pPager->pWal) : pPager->jfd; #endif } /* ** Return the full pathname of the journal file. */ -SQLITE_PRIVATE const char *tdsqlite3PagerJournalname(Pager *pPager){ +SQLITE_PRIVATE const char *sqlite3PagerJournalname(Pager *pPager){ return pPager->zJournal; } @@ -62799,7 +62799,7 @@ SQLITE_PRIVATE const char *tdsqlite3PagerJournalname(Pager *pPager){ /* ** Set or retrieve the codec for this pager */ -SQLITE_PRIVATE void tdsqlite3PagerSetCodec( +SQLITE_PRIVATE void sqlite3PagerSetCodec( Pager *pPager, void *(*xCodec)(void*,void*,Pgno,int), void (*xCodecSizeChng)(void*,int,int), @@ -62818,7 +62818,7 @@ SQLITE_PRIVATE void tdsqlite3PagerSetCodec( setGetterMethod(pPager); pagerReportSize(pPager); } -SQLITE_PRIVATE void *tdsqlite3PagerGetCodec(Pager *pPager){ +SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){ return pPager->pCodec; } @@ -62829,7 +62829,7 @@ SQLITE_PRIVATE void *tdsqlite3PagerGetCodec(Pager *pPager){ ** This function returns a pointer to a buffer containing the encrypted ** page content. If a malloc fails, this function may return NULL. */ -SQLITE_PRIVATE void *tdsqlite3PagerCodec(PgHdr *pPg){ +SQLITE_PRIVATE void *sqlite3PagerCodec(PgHdr *pPg){ void *aData = 0; CODEC2(pPg->pPager, pPg->pData, pPg->pgno, 6, return 0, aData); return aData; @@ -62838,7 +62838,7 @@ SQLITE_PRIVATE void *tdsqlite3PagerCodec(PgHdr *pPg){ /* ** Return the current pager state */ -SQLITE_PRIVATE int tdsqlite3PagerState(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerState(Pager *pPager){ return pPager->eState; } #endif /* SQLITE_HAS_CODEC */ @@ -62869,7 +62869,7 @@ SQLITE_PRIVATE int tdsqlite3PagerState(Pager *pPager){ ** This function may return SQLITE_NOMEM or an IO error code if an error ** occurs. Otherwise, it returns SQLITE_OK. */ -SQLITE_PRIVATE int tdsqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ +SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, int isCommit){ PgHdr *pPgOld; /* The page being overwritten. */ Pgno needSyncPgno = 0; /* Old value of pPg->pgno, if sync is required */ int rc; /* Return code */ @@ -62886,7 +62886,7 @@ SQLITE_PRIVATE int tdsqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, */ assert( pPager->tempFile || !MEMDB ); if( pPager->tempFile ){ - rc = tdsqlite3PagerWrite(pPg); + rc = sqlite3PagerWrite(pPg); if( rc ) return rc; } @@ -62938,34 +62938,34 @@ SQLITE_PRIVATE int tdsqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, ** for the page moved there. */ pPg->flags &= ~PGHDR_NEED_SYNC; - pPgOld = tdsqlite3PagerLookup(pPager, pgno); + pPgOld = sqlite3PagerLookup(pPager, pgno); assert( !pPgOld || pPgOld->nRef==1 || CORRUPT_DB ); if( pPgOld ){ if( pPgOld->nRef>1 ){ - tdsqlite3PagerUnrefNotNull(pPgOld); + sqlite3PagerUnrefNotNull(pPgOld); return SQLITE_CORRUPT_BKPT; } pPg->flags |= (pPgOld->flags&PGHDR_NEED_SYNC); if( pPager->tempFile ){ /* Do not discard pages from an in-memory database since we might ** need to rollback later. Just move the page out of the way. */ - tdsqlite3PcacheMove(pPgOld, pPager->dbSize+1); + sqlite3PcacheMove(pPgOld, pPager->dbSize+1); }else{ - tdsqlite3PcacheDrop(pPgOld); + sqlite3PcacheDrop(pPgOld); } } origPgno = pPg->pgno; - tdsqlite3PcacheMove(pPg, pgno); - tdsqlite3PcacheMakeDirty(pPg); + sqlite3PcacheMove(pPg, pgno); + sqlite3PcacheMakeDirty(pPg); /* For an in-memory database, make sure the original page continues ** to exist, in case the transaction needs to roll back. Use pPgOld ** as the original page since it has already been allocated. */ if( pPager->tempFile && pPgOld ){ - tdsqlite3PcacheMove(pPgOld, origPgno); - tdsqlite3PagerUnrefNotNull(pPgOld); + sqlite3PcacheMove(pPgOld, origPgno); + sqlite3PagerUnrefNotNull(pPgOld); } if( needSyncPgno ){ @@ -62984,17 +62984,17 @@ SQLITE_PRIVATE int tdsqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, ** the journal file twice, but that is not a problem. */ PgHdr *pPgHdr; - rc = tdsqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0); + rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr, 0); if( rc!=SQLITE_OK ){ if( needSyncPgno<=pPager->dbOrigSize ){ assert( pPager->pTmpSpace!=0 ); - tdsqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); + sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); } return rc; } pPgHdr->flags |= PGHDR_NEED_SYNC; - tdsqlite3PcacheMakeDirty(pPgHdr); - tdsqlite3PagerUnrefNotNull(pPgHdr); + sqlite3PcacheMakeDirty(pPgHdr); + sqlite3PagerUnrefNotNull(pPgHdr); } return SQLITE_OK; @@ -63007,16 +63007,16 @@ SQLITE_PRIVATE int tdsqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, ** page number to iNew and sets the value of the PgHdr.flags field to ** the value passed as the third parameter. */ -SQLITE_PRIVATE void tdsqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ +SQLITE_PRIVATE void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ assert( pPg->pgno!=iNew ); pPg->flags = flags; - tdsqlite3PcacheMove(pPg, iNew); + sqlite3PcacheMove(pPg, iNew); } /* ** Return a pointer to the data for the specified page. */ -SQLITE_PRIVATE void *tdsqlite3PagerGetData(DbPage *pPg){ +SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){ assert( pPg->nRef>0 || pPg->pPager->memDb ); return pPg->pData; } @@ -63025,7 +63025,7 @@ SQLITE_PRIVATE void *tdsqlite3PagerGetData(DbPage *pPg){ ** Return a pointer to the Pager.nExtra bytes of "extra" space ** allocated along with the specified page. */ -SQLITE_PRIVATE void *tdsqlite3PagerGetExtra(DbPage *pPg){ +SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ return pPg->pExtra; } @@ -63039,14 +63039,14 @@ SQLITE_PRIVATE void *tdsqlite3PagerGetExtra(DbPage *pPg){ ** PAGER_LOCKINGMODE_EXCLUSIVE, indicating the current (possibly updated) ** locking-mode. */ -SQLITE_PRIVATE int tdsqlite3PagerLockingMode(Pager *pPager, int eMode){ +SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *pPager, int eMode){ assert( eMode==PAGER_LOCKINGMODE_QUERY || eMode==PAGER_LOCKINGMODE_NORMAL || eMode==PAGER_LOCKINGMODE_EXCLUSIVE ); assert( PAGER_LOCKINGMODE_QUERY<0 ); assert( PAGER_LOCKINGMODE_NORMAL>=0 && PAGER_LOCKINGMODE_EXCLUSIVE>=0 ); - assert( pPager->exclusiveMode || 0==tdsqlite3WalHeapMemory(pPager->pWal) ); - if( eMode>=0 && !pPager->tempFile && !tdsqlite3WalHeapMemory(pPager->pWal) ){ + assert( pPager->exclusiveMode || 0==sqlite3WalHeapMemory(pPager->pWal) ); + if( eMode>=0 && !pPager->tempFile && !sqlite3WalHeapMemory(pPager->pWal) ){ pPager->exclusiveMode = (u8)eMode; } return (int)pPager->exclusiveMode; @@ -63072,7 +63072,7 @@ SQLITE_PRIVATE int tdsqlite3PagerLockingMode(Pager *pPager, int eMode){ ** ** The returned indicate the current (possibly updated) journal-mode. */ -SQLITE_PRIVATE int tdsqlite3PagerSetJournalMode(Pager *pPager, int eMode){ +SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ u8 eOld = pPager->journalMode; /* Prior journalmode */ /* The eMode parameter is always valid */ @@ -63127,22 +63127,22 @@ SQLITE_PRIVATE int tdsqlite3PagerSetJournalMode(Pager *pPager, int eMode){ ** database file. This ensures that the journal file is not deleted ** while it is in use by some other client. */ - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); if( pPager->eLock>=RESERVED_LOCK ){ - tdsqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); }else{ int rc = SQLITE_OK; int state = pPager->eState; assert( state==PAGER_OPEN || state==PAGER_READER ); if( state==PAGER_OPEN ){ - rc = tdsqlite3PagerSharedLock(pPager); + rc = sqlite3PagerSharedLock(pPager); } if( pPager->eState==PAGER_READER ){ assert( rc==SQLITE_OK ); rc = pagerLockDb(pPager, RESERVED_LOCK); } if( rc==SQLITE_OK ){ - tdsqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); + sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); } if( rc==SQLITE_OK && state==PAGER_READER ){ pagerUnlockDb(pPager, SHARED_LOCK); @@ -63152,7 +63152,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSetJournalMode(Pager *pPager, int eMode){ assert( state==pPager->eState ); } }else if( eMode==PAGER_JOURNALMODE_OFF ){ - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); } } @@ -63163,7 +63163,7 @@ SQLITE_PRIVATE int tdsqlite3PagerSetJournalMode(Pager *pPager, int eMode){ /* ** Return the current journal mode. */ -SQLITE_PRIVATE int tdsqlite3PagerGetJournalMode(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerGetJournalMode(Pager *pPager){ return (int)pPager->journalMode; } @@ -63172,7 +63172,7 @@ SQLITE_PRIVATE int tdsqlite3PagerGetJournalMode(Pager *pPager){ ** journalmode. Journalmode changes can only happen when the database ** is unmodified. */ -SQLITE_PRIVATE int tdsqlite3PagerOkToChangeJournalMode(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ assert( assert_pager_state(pPager) ); if( pPager->eState>=PAGER_WRITER_CACHEMOD ) return 0; if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; @@ -63185,10 +63185,10 @@ SQLITE_PRIVATE int tdsqlite3PagerOkToChangeJournalMode(Pager *pPager){ ** Setting the size limit to -1 means no limit is enforced. ** An attempt to set a limit smaller than -1 is a no-op. */ -SQLITE_PRIVATE i64 tdsqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ +SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ if( iLimit>=-1 ){ pPager->journalSizeLimit = iLimit; - tdsqlite3WalLimit(pPager->pWal, iLimit); + sqlite3WalLimit(pPager->pWal, iLimit); } return pPager->journalSizeLimit; } @@ -63196,10 +63196,10 @@ SQLITE_PRIVATE i64 tdsqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){ /* ** Return a pointer to the pPager->pBackup variable. The backup module ** in backup.c maintains the content of this variable. This module -** uses it opaquely as an argument to tdsqlite3BackupRestart() and -** tdsqlite3BackupUpdate() only. +** uses it opaquely as an argument to sqlite3BackupRestart() and +** sqlite3BackupUpdate() only. */ -SQLITE_PRIVATE tdsqlite3_backup **tdsqlite3PagerBackupPtr(Pager *pPager){ +SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ return &pPager->pBackup; } @@ -63207,7 +63207,7 @@ SQLITE_PRIVATE tdsqlite3_backup **tdsqlite3PagerBackupPtr(Pager *pPager){ /* ** Unless this is an in-memory or temporary database, clear the pager cache. */ -SQLITE_PRIVATE void tdsqlite3PagerClearCache(Pager *pPager){ +SQLITE_PRIVATE void sqlite3PagerClearCache(Pager *pPager){ assert( MEMDB==0 || pPager->tempFile ); if( pPager->tempFile==0 ) pager_reset(pPager); } @@ -63217,41 +63217,41 @@ SQLITE_PRIVATE void tdsqlite3PagerClearCache(Pager *pPager){ #ifndef SQLITE_OMIT_WAL /* ** This function is called when the user invokes "PRAGMA wal_checkpoint", -** "PRAGMA wal_blocking_checkpoint" or calls the tdsqlite3_wal_checkpoint() +** "PRAGMA wal_blocking_checkpoint" or calls the sqlite3_wal_checkpoint() ** or wal_blocking_checkpoint() API functions. ** ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. */ -SQLITE_PRIVATE int tdsqlite3PagerCheckpoint( +SQLITE_PRIVATE int sqlite3PagerCheckpoint( Pager *pPager, /* Checkpoint on this pager */ - tdsqlite3 *db, /* Db handle used to check for interrupts */ + sqlite3 *db, /* Db handle used to check for interrupts */ int eMode, /* Type of checkpoint */ int *pnLog, /* OUT: Final number of frames in log */ int *pnCkpt /* OUT: Final number of checkpointed frames */ ){ int rc = SQLITE_OK; if( pPager->pWal ){ - rc = tdsqlite3WalCheckpoint(pPager->pWal, db, eMode, + rc = sqlite3WalCheckpoint(pPager->pWal, db, eMode, (eMode==SQLITE_CHECKPOINT_PASSIVE ? 0 : pPager->xBusyHandler), pPager->pBusyHandlerArg, pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, pnLog, pnCkpt ); - tdsqlite3PagerResetLockTimeout(pPager); + sqlite3PagerResetLockTimeout(pPager); } return rc; } -SQLITE_PRIVATE int tdsqlite3PagerWalCallback(Pager *pPager){ - return tdsqlite3WalCallback(pPager->pWal); +SQLITE_PRIVATE int sqlite3PagerWalCallback(Pager *pPager){ + return sqlite3WalCallback(pPager->pWal); } /* ** Return true if the underlying VFS for the given pager supports the ** primitives necessary for write-ahead logging. */ -SQLITE_PRIVATE int tdsqlite3PagerWalSupported(Pager *pPager){ - const tdsqlite3_io_methods *pMethods = pPager->fd->pMethods; +SQLITE_PRIVATE int sqlite3PagerWalSupported(Pager *pPager){ + const sqlite3_io_methods *pMethods = pPager->fd->pMethods; if( pPager->noLock ) return 0; return pPager->exclusiveMode || (pMethods->iVersion>=2 && pMethods->xShmMap); } @@ -63275,7 +63275,7 @@ static int pagerExclusiveLock(Pager *pPager){ } /* -** Call tdsqlite3WalOpen() to open the WAL handle. If the pager is in +** Call sqlite3WalOpen() to open the WAL handle. If the pager is in ** exclusive-locking mode when this function is called, take an EXCLUSIVE ** lock on the database file and use heap-memory to store the wal-index ** in. Otherwise, use the normal shared-memory. @@ -63299,7 +63299,7 @@ static int pagerOpenWal(Pager *pPager){ ** (e.g. due to malloc() failure), return an error code. */ if( rc==SQLITE_OK ){ - rc = tdsqlite3WalOpen(pPager->pVfs, + rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, pPager->exclusiveMode, pPager->journalSizeLimit, &pPager->pWal ); @@ -63325,7 +63325,7 @@ static int pagerOpenWal(Pager *pPager){ ** the WAL file is already open, set *pbOpen to 1 and return SQLITE_OK ** without doing anything. */ -SQLITE_PRIVATE int tdsqlite3PagerOpenWal( +SQLITE_PRIVATE int sqlite3PagerOpenWal( Pager *pPager, /* Pager object */ int *pbOpen /* OUT: Set to true if call is a no-op */ ){ @@ -63338,10 +63338,10 @@ SQLITE_PRIVATE int tdsqlite3PagerOpenWal( assert( pbOpen!=0 || (!pPager->tempFile && !pPager->pWal) ); if( !pPager->tempFile && !pPager->pWal ){ - if( !tdsqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; + if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; /* Close any rollback journal previously open */ - tdsqlite3OsClose(pPager->jfd); + sqlite3OsClose(pPager->jfd); rc = pagerOpenWal(pPager); if( rc==SQLITE_OK ){ @@ -63364,7 +63364,7 @@ SQLITE_PRIVATE int tdsqlite3PagerOpenWal( ** error (SQLITE_BUSY) is returned and the log connection is not closed. ** If successful, the EXCLUSIVE lock is not released before returning. */ -SQLITE_PRIVATE int tdsqlite3PagerCloseWal(Pager *pPager, tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3PagerCloseWal(Pager *pPager, sqlite3 *db){ int rc = SQLITE_OK; assert( pPager->journalMode==PAGER_JOURNALMODE_WAL ); @@ -63377,7 +63377,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCloseWal(Pager *pPager, tdsqlite3 *db){ int logexists = 0; rc = pagerLockDb(pPager, SHARED_LOCK); if( rc==SQLITE_OK ){ - rc = tdsqlite3OsAccess( + rc = sqlite3OsAccess( pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists ); } @@ -63392,7 +63392,7 @@ SQLITE_PRIVATE int tdsqlite3PagerCloseWal(Pager *pPager, tdsqlite3 *db){ if( rc==SQLITE_OK && pPager->pWal ){ rc = pagerExclusiveLock(pPager); if( rc==SQLITE_OK ){ - rc = tdsqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, + rc = sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize, (u8*)pPager->pTmpSpace); pPager->pWal = 0; pagerFixMaplimit(pPager); @@ -63409,10 +63409,10 @@ SQLITE_PRIVATE int tdsqlite3PagerCloseWal(Pager *pPager, tdsqlite3 *db){ ** If this is a WAL database, obtain a snapshot handle for the snapshot ** currently open. Otherwise, return an error. */ -SQLITE_PRIVATE int tdsqlite3PagerSnapshotGet(Pager *pPager, tdsqlite3_snapshot **ppSnapshot){ +SQLITE_PRIVATE int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot){ int rc = SQLITE_ERROR; if( pPager->pWal ){ - rc = tdsqlite3WalSnapshotGet(pPager->pWal, ppSnapshot); + rc = sqlite3WalSnapshotGet(pPager->pWal, ppSnapshot); } return rc; } @@ -63422,10 +63422,10 @@ SQLITE_PRIVATE int tdsqlite3PagerSnapshotGet(Pager *pPager, tdsqlite3_snapshot * ** read transaction is opened, attempt to read from the snapshot it ** identifies. If this is not a WAL database, return an error. */ -SQLITE_PRIVATE int tdsqlite3PagerSnapshotOpen(Pager *pPager, tdsqlite3_snapshot *pSnapshot){ +SQLITE_PRIVATE int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot){ int rc = SQLITE_OK; if( pPager->pWal ){ - tdsqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); + sqlite3WalSnapshotOpen(pPager->pWal, pSnapshot); }else{ rc = SQLITE_ERROR; } @@ -63433,13 +63433,13 @@ SQLITE_PRIVATE int tdsqlite3PagerSnapshotOpen(Pager *pPager, tdsqlite3_snapshot } /* -** If this is a WAL database, call tdsqlite3WalSnapshotRecover(). If this +** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this ** is not a WAL database, return an error. */ -SQLITE_PRIVATE int tdsqlite3PagerSnapshotRecover(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerSnapshotRecover(Pager *pPager){ int rc; if( pPager->pWal ){ - rc = tdsqlite3WalSnapshotRecover(pPager->pWal); + rc = sqlite3WalSnapshotRecover(pPager->pWal); }else{ rc = SQLITE_ERROR; } @@ -63458,10 +63458,10 @@ SQLITE_PRIVATE int tdsqlite3PagerSnapshotRecover(Pager *pPager){ ** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER ** lock is released before returning. */ -SQLITE_PRIVATE int tdsqlite3PagerSnapshotCheck(Pager *pPager, tdsqlite3_snapshot *pSnapshot){ +SQLITE_PRIVATE int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot){ int rc; if( pPager->pWal ){ - rc = tdsqlite3WalSnapshotCheck(pPager->pWal, pSnapshot); + rc = sqlite3WalSnapshotCheck(pPager->pWal, pSnapshot); }else{ rc = SQLITE_ERROR; } @@ -63470,11 +63470,11 @@ SQLITE_PRIVATE int tdsqlite3PagerSnapshotCheck(Pager *pPager, tdsqlite3_snapshot /* ** Release a lock obtained by an earlier successful call to -** tdsqlite3PagerSnapshotCheck(). +** sqlite3PagerSnapshotCheck(). */ -SQLITE_PRIVATE void tdsqlite3PagerSnapshotUnlock(Pager *pPager){ +SQLITE_PRIVATE void sqlite3PagerSnapshotUnlock(Pager *pPager){ assert( pPager->pWal ); - tdsqlite3WalSnapshotUnlock(pPager->pWal); + sqlite3WalSnapshotUnlock(pPager->pWal); } #endif /* SQLITE_ENABLE_SNAPSHOT */ @@ -63488,9 +63488,9 @@ SQLITE_PRIVATE void tdsqlite3PagerSnapshotUnlock(Pager *pPager){ ** WAL frames. Otherwise, if this is not a WAL database or the WAL file ** is empty, return 0. */ -SQLITE_PRIVATE int tdsqlite3PagerWalFramesize(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerWalFramesize(Pager *pPager){ assert( pPager->eState>=PAGER_READER ); - return tdsqlite3WalFramesize(pPager->pWal); + return sqlite3WalFramesize(pPager->pWal); } #endif @@ -63499,17 +63499,17 @@ SQLITE_PRIVATE int tdsqlite3PagerWalFramesize(Pager *pPager){ /* BEGIN SQLCIPHER */ #ifdef SQLITE_HAS_CODEC -SQLITE_API int tdsqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) { +SQLITE_API int sqlite3pager_is_mj_pgno(Pager *pPager, Pgno pgno) { return (PAGER_MJ_PGNO(pPager) == pgno) ? 1 : 0; } -SQLITE_API void tdsqlite3pager_error(Pager *pPager, int error) { +SQLITE_API void sqlite3pager_error(Pager *pPager, int error) { pPager->errCode = error; pPager->eState = PAGER_ERROR; setGetterMethod(pPager); } -SQLITE_API void tdsqlite3pager_reset(Pager *pPager){ +SQLITE_API void sqlite3pager_reset(Pager *pPager){ pager_reset(pPager); } @@ -63773,8 +63773,8 @@ SQLITE_API void tdsqlite3pager_reset(Pager *pPager){ ** Trace output macros */ #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG) -SQLITE_PRIVATE int tdsqlite3WalTrace = 0; -# define WALTRACE(X) if(tdsqlite3WalTrace) tdsqlite3DebugPrintf X +SQLITE_PRIVATE int sqlite3WalTrace = 0; +# define WALTRACE(X) if(sqlite3WalTrace) sqlite3DebugPrintf X #else # define WALTRACE(X) #endif @@ -63970,9 +63970,9 @@ struct WalCkptInfo { ** following object. */ struct Wal { - tdsqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ - tdsqlite3_file *pDbFd; /* File handle for the database file */ - tdsqlite3_file *pWalFd; /* File handle for WAL file */ + sqlite3_vfs *pVfs; /* The VFS used to create pDbFd */ + sqlite3_file *pDbFd; /* File handle for the database file */ + sqlite3_file *pWalFd; /* File handle for WAL file */ u32 iCallback; /* Value to pass to log callback (or 0) */ i64 mxWalSize; /* Truncate WAL to this size upon reset */ int nWiData; /* Size of array apWiData */ @@ -64096,9 +64096,9 @@ static SQLITE_NOINLINE int walIndexPageRealloc( /* Enlarge the pWal->apWiData[] array if required */ if( pWal->nWiData<=iPage ){ - tdsqlite3_int64 nByte = sizeof(u32*)*(iPage+1); + sqlite3_int64 nByte = sizeof(u32*)*(iPage+1); volatile u32 **apNew; - apNew = (volatile u32 **)tdsqlite3_realloc64((void *)pWal->apWiData, nByte); + apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte); if( !apNew ){ *ppPage = 0; return SQLITE_NOMEM_BKPT; @@ -64112,10 +64112,10 @@ static SQLITE_NOINLINE int walIndexPageRealloc( /* Request a pointer to the required page from the VFS */ assert( pWal->apWiData[iPage]==0 ); if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){ - pWal->apWiData[iPage] = (u32 volatile *)tdsqlite3MallocZero(WALINDEX_PGSZ); + pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; }else{ - rc = tdsqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, + rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 ); @@ -64221,7 +64221,7 @@ static void walChecksumBytes( static void walShmBarrier(Wal *pWal){ if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){ - tdsqlite3OsShmBarrier(pWal->pDbFd); + sqlite3OsShmBarrier(pWal->pDbFd); } } @@ -64266,8 +64266,8 @@ static void walEncodeFrame( int nativeCksum; /* True for native byte-order checksums */ u32 *aCksum = pWal->hdr.aFrameCksum; assert( WAL_FRAME_HDRSIZE==24 ); - tdsqlite3Put4byte(&aFrame[0], iPage); - tdsqlite3Put4byte(&aFrame[4], nTruncate); + sqlite3Put4byte(&aFrame[0], iPage); + sqlite3Put4byte(&aFrame[4], nTruncate); if( pWal->iReCksum==0 ){ memcpy(&aFrame[8], pWal->hdr.aSalt, 8); @@ -64275,8 +64275,8 @@ static void walEncodeFrame( walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); - tdsqlite3Put4byte(&aFrame[16], aCksum[0]); - tdsqlite3Put4byte(&aFrame[20], aCksum[1]); + sqlite3Put4byte(&aFrame[16], aCksum[0]); + sqlite3Put4byte(&aFrame[20], aCksum[1]); }else{ memset(&aFrame[8], 0, 16); } @@ -64308,7 +64308,7 @@ static int walDecodeFrame( /* A frame is only valid if the page number is creater than zero. */ - pgno = tdsqlite3Get4byte(&aFrame[0]); + pgno = sqlite3Get4byte(&aFrame[0]); if( pgno==0 ){ return 0; } @@ -64321,8 +64321,8 @@ static int walDecodeFrame( nativeCksum = (pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN); walChecksumBytes(nativeCksum, aFrame, 8, aCksum, aCksum); walChecksumBytes(nativeCksum, aData, pWal->szPage, aCksum, aCksum); - if( aCksum[0]!=tdsqlite3Get4byte(&aFrame[16]) - || aCksum[1]!=tdsqlite3Get4byte(&aFrame[20]) + if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) + || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) ){ /* Checksum failed. */ return 0; @@ -64332,7 +64332,7 @@ static int walDecodeFrame( ** and the new database size. */ *piPage = pgno; - *pnTruncate = tdsqlite3Get4byte(&aFrame[4]); + *pnTruncate = sqlite3Get4byte(&aFrame[4]); return 1; } @@ -64351,7 +64351,7 @@ static const char *walLockName(int lockIdx){ return "RECOVER-LOCK"; }else{ static char zName[15]; - tdsqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]", + sqlite3_snprintf(sizeof(zName), zName, "READ-LOCK[%d]", lockIdx-WAL_READ_LOCK(0)); return zName; } @@ -64369,7 +64369,7 @@ static const char *walLockName(int lockIdx){ static int walLockShared(Wal *pWal, int lockIdx){ int rc; if( pWal->exclusiveMode ) return SQLITE_OK; - rc = tdsqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, walLockName(lockIdx), rc ? "failed" : "ok")); @@ -64378,14 +64378,14 @@ static int walLockShared(Wal *pWal, int lockIdx){ } static void walUnlockShared(Wal *pWal, int lockIdx){ if( pWal->exclusiveMode ) return; - (void)tdsqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } static int walLockExclusive(Wal *pWal, int lockIdx, int n){ int rc; if( pWal->exclusiveMode ) return SQLITE_OK; - rc = tdsqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, walLockName(lockIdx), n, rc ? "failed" : "ok")); @@ -64394,7 +64394,7 @@ static int walLockExclusive(Wal *pWal, int lockIdx, int n){ } static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ if( pWal->exclusiveMode ) return; - (void)tdsqlite3OsShmLock(pWal->pDbFd, lockIdx, n, + (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal, walLockName(lockIdx), n)); @@ -64687,7 +64687,7 @@ static int walIndexRecover(Wal *pWal){ memset(&pWal->hdr, 0, sizeof(WalIndexHdr)); - rc = tdsqlite3OsFileSize(pWal->pWalFd, &nSize); + rc = sqlite3OsFileSize(pWal->pWalFd, &nSize); if( rc!=SQLITE_OK ){ goto recovery_error; } @@ -64705,7 +64705,7 @@ static int walIndexRecover(Wal *pWal){ int isValid; /* True if this frame is valid */ /* Read in the WAL header. */ - rc = tdsqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); if( rc!=SQLITE_OK ){ goto recovery_error; } @@ -64715,8 +64715,8 @@ static int walIndexRecover(Wal *pWal){ ** data. Similarly, if the 'magic' value is invalid, ignore the whole ** WAL file. */ - magic = tdsqlite3Get4byte(&aBuf[0]); - szPage = tdsqlite3Get4byte(&aBuf[8]); + magic = sqlite3Get4byte(&aBuf[0]); + szPage = sqlite3Get4byte(&aBuf[8]); if( (magic&0xFFFFFFFE)!=WAL_MAGIC || szPage&(szPage-1) || szPage>SQLITE_MAX_PAGE_SIZE @@ -64726,22 +64726,22 @@ static int walIndexRecover(Wal *pWal){ } pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); pWal->szPage = szPage; - pWal->nCkpt = tdsqlite3Get4byte(&aBuf[12]); + pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); /* Verify that the WAL header checksum is correct */ walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum ); - if( pWal->hdr.aFrameCksum[0]!=tdsqlite3Get4byte(&aBuf[24]) - || pWal->hdr.aFrameCksum[1]!=tdsqlite3Get4byte(&aBuf[28]) + if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24]) + || pWal->hdr.aFrameCksum[1]!=sqlite3Get4byte(&aBuf[28]) ){ goto finished; } /* Verify that the version number on the WAL format is one that ** are able to understand */ - version = tdsqlite3Get4byte(&aBuf[4]); + version = sqlite3Get4byte(&aBuf[4]); if( version!=WAL_MAX_VERSION ){ rc = SQLITE_CANTOPEN_BKPT; goto finished; @@ -64749,7 +64749,7 @@ static int walIndexRecover(Wal *pWal){ /* Malloc a buffer to read frames into. */ szFrame = szPage + WAL_FRAME_HDRSIZE; - aFrame = (u8 *)tdsqlite3_malloc64(szFrame); + aFrame = (u8 *)sqlite3_malloc64(szFrame); if( !aFrame ){ rc = SQLITE_NOMEM_BKPT; goto recovery_error; @@ -64764,7 +64764,7 @@ static int walIndexRecover(Wal *pWal){ /* Read and decode the next log frame. */ iFrame++; - rc = tdsqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); if( rc!=SQLITE_OK ) break; isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame); if( !isValid ) break; @@ -64783,7 +64783,7 @@ static int walIndexRecover(Wal *pWal){ } } - tdsqlite3_free(aFrame); + sqlite3_free(aFrame); } finished: @@ -64806,12 +64806,12 @@ finished: if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame; /* If more than one frame was recovered from the log file, report an - ** event via tdsqlite3_log(). This is to help with identifying performance + ** event via sqlite3_log(). This is to help with identifying performance ** problems caused by applications routinely shutting down without ** checkpointing the log file. */ if( pWal->hdr.nPage ){ - tdsqlite3_log(SQLITE_NOTICE_RECOVER_WAL, + sqlite3_log(SQLITE_NOTICE_RECOVER_WAL, "recovered %d frames from WAL file %s", pWal->hdr.mxFrame, pWal->zWalName ); @@ -64832,12 +64832,12 @@ static void walIndexClose(Wal *pWal, int isDelete){ if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE || pWal->bShmUnreliable ){ int i; for(i=0; inWiData; i++){ - tdsqlite3_free((void *)pWal->apWiData[i]); + sqlite3_free((void *)pWal->apWiData[i]); pWal->apWiData[i] = 0; } } if( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE ){ - tdsqlite3OsShmUnmap(pWal->pDbFd, isDelete); + sqlite3OsShmUnmap(pWal->pDbFd, isDelete); } } @@ -64856,9 +64856,9 @@ static void walIndexClose(Wal *pWal, int isDelete){ ** *ppWal is set to point to a new WAL handle. If an error occurs, ** an SQLite error code is returned and *ppWal is left unmodified. */ -SQLITE_PRIVATE int tdsqlite3WalOpen( - tdsqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ - tdsqlite3_file *pDbFd, /* The open database file */ +SQLITE_PRIVATE int sqlite3WalOpen( + sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ + sqlite3_file *pDbFd, /* The open database file */ const char *zWalName, /* Name of the WAL file */ int bNoShm, /* True to run in heap-memory mode */ i64 mxWalSize, /* Truncate WAL to this size on reset */ @@ -64889,13 +64889,13 @@ SQLITE_PRIVATE int tdsqlite3WalOpen( /* Allocate an instance of struct Wal to return. */ *ppWal = 0; - pRet = (Wal*)tdsqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); + pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); if( !pRet ){ return SQLITE_NOMEM_BKPT; } pRet->pVfs = pVfs; - pRet->pWalFd = (tdsqlite3_file *)&pRet[1]; + pRet->pWalFd = (sqlite3_file *)&pRet[1]; pRet->pDbFd = pDbFd; pRet->readLock = -1; pRet->mxWalSize = mxWalSize; @@ -64906,17 +64906,17 @@ SQLITE_PRIVATE int tdsqlite3WalOpen( /* Open file handle on the write-ahead log file. */ flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); - rc = tdsqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); + rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ pRet->readOnly = WAL_RDONLY; } if( rc!=SQLITE_OK ){ walIndexClose(pRet, 0); - tdsqlite3OsClose(pRet->pWalFd); - tdsqlite3_free(pRet); + sqlite3OsClose(pRet->pWalFd); + sqlite3_free(pRet); }else{ - int iDC = tdsqlite3OsDeviceCharacteristics(pDbFd); + int iDC = sqlite3OsDeviceCharacteristics(pDbFd); if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; } if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){ pRet->padToSectorBoundary = 0; @@ -64930,7 +64930,7 @@ SQLITE_PRIVATE int tdsqlite3WalOpen( /* ** Change the size to which the WAL file is trucated on each reset. */ -SQLITE_PRIVATE void tdsqlite3WalLimit(Wal *pWal, i64 iLimit){ +SQLITE_PRIVATE void sqlite3WalLimit(Wal *pWal, i64 iLimit){ if( pWal ) pWal->mxWalSize = iLimit; } @@ -65118,7 +65118,7 @@ static void walMergesort( ** Free an iterator allocated by walIteratorInit(). */ static void walIteratorFree(WalIterator *p){ - tdsqlite3_free(p); + sqlite3_free(p); } /* @@ -65138,7 +65138,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ WalIterator *p; /* Return value */ int nSegment; /* Number of segments to merge */ u32 iLast; /* Last frame in log */ - tdsqlite3_int64 nByte; /* Number of bytes to allocate */ + sqlite3_int64 nByte; /* Number of bytes to allocate */ int i; /* Iterator variable */ ht_slot *aTmp; /* Temp space used by merge-sort */ int rc = SQLITE_OK; /* Return Code */ @@ -65154,7 +65154,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ nByte = sizeof(WalIterator) + (nSegment-1)*sizeof(struct WalSegment) + iLast*sizeof(ht_slot); - p = (WalIterator *)tdsqlite3_malloc64(nByte); + p = (WalIterator *)sqlite3_malloc64(nByte); if( !p ){ return SQLITE_NOMEM_BKPT; } @@ -65164,7 +65164,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ /* Allocate temporary space used by the merge-sort routine. This block ** of memory will be freed before this function returns. */ - aTmp = (ht_slot *)tdsqlite3_malloc64( + aTmp = (ht_slot *)sqlite3_malloc64( sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) ); if( !aTmp ){ @@ -65199,7 +65199,7 @@ static int walIteratorInit(Wal *pWal, u32 nBackfill, WalIterator **pp){ p->aSegment[i].aPgno = (u32 *)sLoc.aPgno; } } - tdsqlite3_free(aTmp); + sqlite3_free(aTmp); if( rc!=SQLITE_OK ){ walIteratorFree(p); @@ -65252,7 +65252,7 @@ static int walPagesize(Wal *pWal){ ** ** The value of parameter salt1 is used as the aSalt[1] value in the ** new wal-index header. It should be passed a pseudo-random value (i.e. -** one obtained from tdsqlite3_randomness()). +** one obtained from sqlite3_randomness()). */ static void walRestartHdr(Wal *pWal, u32 salt1){ volatile WalCkptInfo *pInfo = walCkptInfo(pWal); @@ -65260,7 +65260,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){ u32 *aSalt = pWal->hdr.aSalt; /* Big-endian salt values */ pWal->nCkpt++; pWal->hdr.mxFrame = 0; - tdsqlite3Put4byte((u8*)&aSalt[0], 1 + tdsqlite3Get4byte((u8*)&aSalt[0])); + sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); memcpy(&pWal->hdr.aSalt[1], &salt1, 4); walIndexWriteHdr(pWal); pInfo->nBackfill = 0; @@ -65272,7 +65272,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){ /* ** Copy as much content as we can from the WAL back into the database file -** in response to an tdsqlite3_wal_checkpoint() request or the equivalent. +** in response to an sqlite3_wal_checkpoint() request or the equivalent. ** ** The amount of information copies from WAL to database might be limited ** by active readers. This routine will never overwrite a database page @@ -65303,7 +65303,7 @@ static void walRestartHdr(Wal *pWal, u32 salt1){ */ static int walCheckpoint( Wal *pWal, /* Wal connection */ - tdsqlite3 *db, /* Check for interrupts on this handle */ + sqlite3 *db, /* Check for interrupts on this handle */ int eMode, /* One of PASSIVE, FULL or RESTART */ int (*xBusy)(void*), /* Function to call when busy */ void *pBusyArg, /* Context argument for xBusyHandler */ @@ -65388,7 +65388,7 @@ static int walCheckpoint( pInfo->nBackfillAttempted = mxSafeFrame; /* Sync the WAL to disk */ - rc = tdsqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); /* If the database may grow as a result of this checkpoint, hint ** about the eventual size of the db file to the VFS layer. @@ -65396,9 +65396,9 @@ static int walCheckpoint( if( rc==SQLITE_OK ){ i64 nReq = ((i64)mxPage * szPage); i64 nSize; /* Current size of database file */ - rc = tdsqlite3OsFileSize(pWal->pDbFd, &nSize); + rc = sqlite3OsFileSize(pWal->pDbFd, &nSize); if( rc==SQLITE_OK && nSizepDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); + sqlite3OsFileControlHint(pWal->pDbFd, SQLITE_FCNTL_SIZE_HINT, &nReq); } } @@ -65416,11 +65416,11 @@ static int walCheckpoint( } iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ - rc = tdsqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); + rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); if( rc!=SQLITE_OK ) break; iOffset = (iDbpage-1)*(i64)szPage; testcase( IS_BIG_INT(iOffset) ); - rc = tdsqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); + rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); if( rc!=SQLITE_OK ) break; } @@ -65429,13 +65429,13 @@ static int walCheckpoint( if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ i64 szDb = pWal->hdr.nPage*(i64)szPage; testcase( IS_BIG_INT(szDb) ); - rc = tdsqlite3OsTruncate(pWal->pDbFd, szDb); + rc = sqlite3OsTruncate(pWal->pDbFd, szDb); if( rc==SQLITE_OK ){ - rc = tdsqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); + rc = sqlite3OsSync(pWal->pDbFd, CKPT_SYNC_FLAGS(sync_flags)); } } if( rc==SQLITE_OK ){ - rc = tdsqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); + rc = sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_CKPT_DONE, 0); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; } if( rc==SQLITE_OK ){ @@ -65465,7 +65465,7 @@ static int walCheckpoint( rc = SQLITE_BUSY; }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ u32 salt1; - tdsqlite3_randomness(4, &salt1); + sqlite3_randomness(4, &salt1); assert( pInfo->nBackfill==pWal->hdr.mxFrame ); rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); if( rc==SQLITE_OK ){ @@ -65484,7 +65484,7 @@ static int walCheckpoint( ** file-system. To avoid this, update the wal-index header to ** indicate that the log file contains zero valid frames. */ walRestartHdr(pWal, salt1); - rc = tdsqlite3OsTruncate(pWal->pWalFd, 0); + rc = sqlite3OsTruncate(pWal->pWalFd, 0); } walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); } @@ -65503,23 +65503,23 @@ static int walCheckpoint( static void walLimitSize(Wal *pWal, i64 nMax){ i64 sz; int rx; - tdsqlite3BeginBenignMalloc(); - rx = tdsqlite3OsFileSize(pWal->pWalFd, &sz); + sqlite3BeginBenignMalloc(); + rx = sqlite3OsFileSize(pWal->pWalFd, &sz); if( rx==SQLITE_OK && (sz > nMax ) ){ - rx = tdsqlite3OsTruncate(pWal->pWalFd, nMax); + rx = sqlite3OsTruncate(pWal->pWalFd, nMax); } - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); if( rx ){ - tdsqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); + sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); } } /* ** Close a connection to a log file. */ -SQLITE_PRIVATE int tdsqlite3WalClose( +SQLITE_PRIVATE int sqlite3WalClose( Wal *pWal, /* Wal to close */ - tdsqlite3 *db, /* For interrupt flag */ + sqlite3 *db, /* For interrupt flag */ int sync_flags, /* Flags to pass to OsSync() (or 0) */ int nBuf, u8 *zBuf /* Buffer of at least nBuf bytes */ @@ -65537,17 +65537,17 @@ SQLITE_PRIVATE int tdsqlite3WalClose( ** The EXCLUSIVE lock is not released before returning. */ if( zBuf!=0 - && SQLITE_OK==(rc = tdsqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE)) + && SQLITE_OK==(rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE)) ){ if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; } - rc = tdsqlite3WalCheckpoint(pWal, db, + rc = sqlite3WalCheckpoint(pWal, db, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 ); if( rc==SQLITE_OK ){ int bPersist = -1; - tdsqlite3OsFileControlHint( + sqlite3OsFileControlHint( pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist ); if( bPersist!=1 ){ @@ -65568,15 +65568,15 @@ SQLITE_PRIVATE int tdsqlite3WalClose( } walIndexClose(pWal, isDelete); - tdsqlite3OsClose(pWal->pWalFd); + sqlite3OsClose(pWal->pWalFd); if( isDelete ){ - tdsqlite3BeginBenignMalloc(); - tdsqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); - tdsqlite3EndBenignMalloc(); + sqlite3BeginBenignMalloc(); + sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); + sqlite3EndBenignMalloc(); } WALTRACE(("WAL%p: closed\n", pWal)); - tdsqlite3_free((void *)pWal->apWiData); - tdsqlite3_free(pWal); + sqlite3_free((void *)pWal->apWiData); + sqlite3_free(pWal); } return rc; } @@ -65822,14 +65822,14 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ ** is active, wrap the WAL and start overwriting frames that this ** process wants to use. ** - ** Once tdsqlite3OsShmMap() has been called for an tdsqlite3_file and has + ** Once sqlite3OsShmMap() has been called for an sqlite3_file and has ** returned any SQLITE_READONLY value, it must return only SQLITE_READONLY ** or SQLITE_READONLY_CANTINIT or some error for all subsequent invocations, ** even if some external agent does a "chmod" to make the shared-memory - ** writable by us, until tdsqlite3OsShmUnmap() has been called. + ** writable by us, until sqlite3OsShmUnmap() has been called. ** This is a requirement on the VFS implementation. */ - rc = tdsqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy); + rc = sqlite3OsShmMap(pWal->pDbFd, 0, WALINDEX_PGSZ, 0, &pDummy); assert( rc!=SQLITE_OK ); /* SQLITE_OK not possible for read-only connection */ if( rc!=SQLITE_READONLY_CANTINIT ){ rc = (rc==SQLITE_READONLY ? WAL_RETRY : rc); @@ -65845,7 +65845,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ /* Make sure some writer hasn't come in and changed the WAL file out ** from under us, then disconnected, while we were not looking. */ - rc = tdsqlite3OsFileSize(pWal->pWalFd, &szWal); + rc = sqlite3OsFileSize(pWal->pWalFd, &szWal); if( rc!=SQLITE_OK ){ goto begin_unreliable_shm_out; } @@ -65862,7 +65862,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ } /* Check the salt keys at the start of the wal file still match. */ - rc = tdsqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); + rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0); if( rc!=SQLITE_OK ){ goto begin_unreliable_shm_out; } @@ -65876,7 +65876,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ /* Allocate a buffer to read frames into */ szFrame = pWal->hdr.szPage + WAL_FRAME_HDRSIZE; - aFrame = (u8 *)tdsqlite3_malloc64(szFrame); + aFrame = (u8 *)sqlite3_malloc64(szFrame); if( aFrame==0 ){ rc = SQLITE_NOMEM_BKPT; goto begin_unreliable_shm_out; @@ -65897,7 +65897,7 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ u32 nTruncate; /* dbsize field from frame header */ /* Read and decode the next log frame. */ - rc = tdsqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); + rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset); if( rc!=SQLITE_OK ) break; if( !walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame) ) break; @@ -65913,15 +65913,15 @@ static int walBeginShmUnreliable(Wal *pWal, int *pChanged){ pWal->hdr.aFrameCksum[1] = aSaveCksum[1]; begin_unreliable_shm_out: - tdsqlite3_free(aFrame); + sqlite3_free(aFrame); if( rc!=SQLITE_OK ){ int i; for(i=0; inWiData; i++){ - tdsqlite3_free((void*)pWal->apWiData[i]); + sqlite3_free((void*)pWal->apWiData[i]); pWal->apWiData[i] = 0; } pWal->bShmUnreliable = 0; - tdsqlite3WalEndReadTransaction(pWal); + sqlite3WalEndReadTransaction(pWal); *pChanged = 1; } return rc; @@ -66000,8 +66000,8 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** during the few nanoseconds that it is holding the lock. In that case, ** it might take longer than normal for the lock to free. ** - ** After 5 RETRYs, we begin calling tdsqlite3OsSleep(). The first few - ** calls to tdsqlite3OsSleep() have a delay of 1 microsecond. Really this + ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few + ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this ** is more of a scheduler yield than an actual delay. But on the 10th ** an subsequent retries, the delays start becoming longer and longer, ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. @@ -66014,7 +66014,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ return SQLITE_PROTOCOL; } if( cnt>=10 ) nDelay = (cnt-9)*(cnt-9)*39; - tdsqlite3OsSleep(pWal->pVfs, nDelay); + sqlite3OsSleep(pWal->pVfs, nDelay); } if( !useWal ){ @@ -66206,7 +66206,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){ ** error occurs. It is not an error if nBackfillAttempted cannot be ** decreased at all. */ -SQLITE_PRIVATE int tdsqlite3WalSnapshotRecover(Wal *pWal){ +SQLITE_PRIVATE int sqlite3WalSnapshotRecover(Wal *pWal){ int rc; assert( pWal->readLock>=0 ); @@ -66216,10 +66216,10 @@ SQLITE_PRIVATE int tdsqlite3WalSnapshotRecover(Wal *pWal){ int szPage = (int)pWal->szPage; i64 szDb; /* Size of db file in bytes */ - rc = tdsqlite3OsFileSize(pWal->pDbFd, &szDb); + rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); if( rc==SQLITE_OK ){ - void *pBuf1 = tdsqlite3_malloc(szPage); - void *pBuf2 = tdsqlite3_malloc(szPage); + void *pBuf1 = sqlite3_malloc(szPage); + void *pBuf2 = sqlite3_malloc(szPage); if( pBuf1==0 || pBuf2==0 ){ rc = SQLITE_NOMEM; }else{ @@ -66237,10 +66237,10 @@ SQLITE_PRIVATE int tdsqlite3WalSnapshotRecover(Wal *pWal){ if( iDbOff+szPage<=szDb ){ iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; - rc = tdsqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); + rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); if( rc==SQLITE_OK ){ - rc = tdsqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); + rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); } if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ @@ -66252,8 +66252,8 @@ SQLITE_PRIVATE int tdsqlite3WalSnapshotRecover(Wal *pWal){ } } - tdsqlite3_free(pBuf1); - tdsqlite3_free(pBuf2); + sqlite3_free(pBuf1); + sqlite3_free(pBuf2); } walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); } @@ -66265,7 +66265,7 @@ SQLITE_PRIVATE int tdsqlite3WalSnapshotRecover(Wal *pWal){ /* ** Begin a read transaction on the database. ** -** This routine used to be called tdsqlite3OpenSnapshot() and with good reason: +** This routine used to be called sqlite3OpenSnapshot() and with good reason: ** it takes a snapshot of the state of the WAL and wal-index for the current ** instant in time. The current thread will continue to use this snapshot. ** Other threads might append new content to the WAL and wal-index but @@ -66276,7 +66276,7 @@ SQLITE_PRIVATE int tdsqlite3WalSnapshotRecover(Wal *pWal){ ** Pager layer will use this to know that its cache is stale and ** needs to be flushed. */ -SQLITE_PRIVATE int tdsqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ +SQLITE_PRIVATE int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ int rc; /* Return code */ int cnt = 0; /* Number of TryBeginRead attempts */ @@ -66355,7 +66355,7 @@ SQLITE_PRIVATE int tdsqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ if( rc!=SQLITE_OK ){ - tdsqlite3WalEndReadTransaction(pWal); + sqlite3WalEndReadTransaction(pWal); } } } @@ -66367,8 +66367,8 @@ SQLITE_PRIVATE int tdsqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ ** Finish with a read transaction. All this does is release the ** read-lock. */ -SQLITE_PRIVATE void tdsqlite3WalEndReadTransaction(Wal *pWal){ - tdsqlite3WalEndWriteTransaction(pWal); +SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){ + sqlite3WalEndWriteTransaction(pWal); if( pWal->readLock>=0 ){ walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock)); pWal->readLock = -1; @@ -66383,7 +66383,7 @@ SQLITE_PRIVATE void tdsqlite3WalEndReadTransaction(Wal *pWal){ ** Return SQLITE_OK if successful, or an error code if an error occurs. If an ** error does occur, the final value of *piRead is undefined. */ -SQLITE_PRIVATE int tdsqlite3WalFindFrame( +SQLITE_PRIVATE int sqlite3WalFindFrame( Wal *pWal, /* WAL handle */ Pgno pgno, /* Database page number to read data for */ u32 *piRead /* OUT: Frame number (or zero) */ @@ -66485,7 +66485,7 @@ SQLITE_PRIVATE int tdsqlite3WalFindFrame( ** (which is nOut bytes in size). Return SQLITE_OK if successful, or an ** error code otherwise. */ -SQLITE_PRIVATE int tdsqlite3WalReadFrame( +SQLITE_PRIVATE int sqlite3WalReadFrame( Wal *pWal, /* WAL handle */ u32 iRead, /* Frame to read */ int nOut, /* Size of buffer pOut in bytes */ @@ -66499,13 +66499,13 @@ SQLITE_PRIVATE int tdsqlite3WalReadFrame( testcase( sz>=65536 ); iOffset = walFrameOffset(iRead, sz) + WAL_FRAME_HDRSIZE; /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ - return tdsqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); + return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); } /* ** Return the size of the database in pages (or zero, if unknown). */ -SQLITE_PRIVATE Pgno tdsqlite3WalDbsize(Wal *pWal){ +SQLITE_PRIVATE Pgno sqlite3WalDbsize(Wal *pWal){ if( pWal && ALWAYS(pWal->readLock>=0) ){ return pWal->hdr.nPage; } @@ -66517,7 +66517,7 @@ SQLITE_PRIVATE Pgno tdsqlite3WalDbsize(Wal *pWal){ ** This function starts a write transaction on the WAL. ** ** A read transaction must have already been started by a prior call -** to tdsqlite3WalBeginReadTransaction(). +** to sqlite3WalBeginReadTransaction(). ** ** If another thread or process has written into the database since ** the read transaction was started, then it is not possible for this @@ -66526,7 +66526,7 @@ SQLITE_PRIVATE Pgno tdsqlite3WalDbsize(Wal *pWal){ ** ** There can only be a single writer active at a time. */ -SQLITE_PRIVATE int tdsqlite3WalBeginWriteTransaction(Wal *pWal){ +SQLITE_PRIVATE int sqlite3WalBeginWriteTransaction(Wal *pWal){ int rc; /* Cannot start a write transaction without first holding a read @@ -66564,7 +66564,7 @@ SQLITE_PRIVATE int tdsqlite3WalBeginWriteTransaction(Wal *pWal){ ** End a write transaction. The commit has already been done. This ** routine merely releases the lock. */ -SQLITE_PRIVATE int tdsqlite3WalEndWriteTransaction(Wal *pWal){ +SQLITE_PRIVATE int sqlite3WalEndWriteTransaction(Wal *pWal){ if( pWal->writeLock ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); pWal->writeLock = 0; @@ -66586,7 +66586,7 @@ SQLITE_PRIVATE int tdsqlite3WalEndWriteTransaction(Wal *pWal){ ** Otherwise, if the callback function does not return an error, this ** function returns SQLITE_OK. */ -SQLITE_PRIVATE int tdsqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ +SQLITE_PRIVATE int sqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void *pUndoCtx){ int rc = SQLITE_OK; if( ALWAYS(pWal->writeLock) ){ Pgno iMax = pWal->hdr.mxFrame; @@ -66626,7 +66626,7 @@ SQLITE_PRIVATE int tdsqlite3WalUndo(Wal *pWal, int (*xUndo)(void *, Pgno), void ** "rollback" the write position of the WAL handle back to the current ** point in the event of a savepoint rollback (via WalSavepointUndo()). */ -SQLITE_PRIVATE void tdsqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ +SQLITE_PRIVATE void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ assert( pWal->writeLock ); aWalData[0] = pWal->hdr.mxFrame; aWalData[1] = pWal->hdr.aFrameCksum[0]; @@ -66640,7 +66640,7 @@ SQLITE_PRIVATE void tdsqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ ** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated ** by a call to WalSavepoint(). */ -SQLITE_PRIVATE int tdsqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ +SQLITE_PRIVATE int sqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ int rc = SQLITE_OK; assert( pWal->writeLock ); @@ -66667,7 +66667,7 @@ SQLITE_PRIVATE int tdsqlite3WalSavepointUndo(Wal *pWal, u32 *aWalData){ /* ** This function is called just before writing a set of frames to the log -** file (see tdsqlite3WalFrames()). It checks to see if, instead of appending +** file (see sqlite3WalFrames()). It checks to see if, instead of appending ** to the current log file, it is possible to overwrite the start of the ** existing log file with the new frames (i.e. "reset" the log). If so, ** it sets pWal->hdr.mxFrame to 0. Otherwise, pWal->hdr.mxFrame is left @@ -66686,7 +66686,7 @@ static int walRestartLog(Wal *pWal){ assert( pInfo->nBackfill==pWal->hdr.mxFrame ); if( pInfo->nBackfill>0 ){ u32 salt1; - tdsqlite3_randomness(4, &salt1); + sqlite3_randomness(4, &salt1); rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); if( rc==SQLITE_OK ){ /* If all readers are using WAL_READ_LOCK(0) (in other words if no @@ -66696,7 +66696,7 @@ static int walRestartLog(Wal *pWal){ ** ** In theory it would be Ok to update the cache of the header only ** at this point. But updating the actual wal-index header is also - ** safe and means there is no special case for tdsqlite3WalUndo() + ** safe and means there is no special case for sqlite3WalUndo() ** to handle if this transaction is rolled back. */ walRestartHdr(pWal, salt1); walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); @@ -66721,13 +66721,13 @@ static int walRestartLog(Wal *pWal){ /* ** Information about the current state of the WAL file and where -** the next fsync should occur - passed from tdsqlite3WalFrames() into +** the next fsync should occur - passed from sqlite3WalFrames() into ** walWriteToLog(). */ typedef struct WalWriter { Wal *pWal; /* The complete WAL information */ - tdsqlite3_file *pFd; /* The WAL file to which we write */ - tdsqlite3_int64 iSyncPoint; /* Fsync at this offset */ + sqlite3_file *pFd; /* The WAL file to which we write */ + sqlite3_int64 iSyncPoint; /* Fsync at this offset */ int syncFlags; /* Flags for the fsync */ int szPage; /* Size of one page */ } WalWriter; @@ -66744,21 +66744,21 @@ static int walWriteToLog( WalWriter *p, /* WAL to write to */ void *pContent, /* Content to be written */ int iAmt, /* Number of bytes to write */ - tdsqlite3_int64 iOffset /* Start writing at this offset */ + sqlite3_int64 iOffset /* Start writing at this offset */ ){ int rc; if( iOffsetiSyncPoint && iOffset+iAmt>=p->iSyncPoint ){ int iFirstAmt = (int)(p->iSyncPoint - iOffset); - rc = tdsqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); + rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset); if( rc ) return rc; iOffset += iFirstAmt; iAmt -= iFirstAmt; pContent = (void*)(iFirstAmt + (char*)pContent); assert( WAL_SYNC_FLAGS(p->syncFlags)!=0 ); - rc = tdsqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); + rc = sqlite3OsSync(p->pFd, WAL_SYNC_FLAGS(p->syncFlags)); if( iAmt==0 || rc ) return rc; } - rc = tdsqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); + rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset); return rc; } @@ -66769,13 +66769,13 @@ static int walWriteOneFrame( WalWriter *p, /* Where to write the frame */ PgHdr *pPage, /* The page of the frame to be written */ int nTruncate, /* The commit flag. Usually 0. >0 for commit */ - tdsqlite3_int64 iOffset /* Byte offset at which to write */ + sqlite3_int64 iOffset /* Byte offset at which to write */ ){ int rc; /* Result code from subfunctions */ void *pData; /* Data actually written */ u8 aFrame[WAL_FRAME_HDRSIZE]; /* Buffer to assemble frame-header in */ #if defined(SQLITE_HAS_CODEC) - if( (pData = tdsqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT; + if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM_BKPT; #else pData = pPage->pData; #endif @@ -66803,7 +66803,7 @@ static int walRewriteChecksums(Wal *pWal, u32 iLast){ u32 iRead; /* Next frame to read from wal file */ i64 iCksumOff; - aBuf = tdsqlite3_malloc(szPage + WAL_FRAME_HDRSIZE); + aBuf = sqlite3_malloc(szPage + WAL_FRAME_HDRSIZE); if( aBuf==0 ) return SQLITE_NOMEM_BKPT; /* Find the checksum values to use as input for the recalculating the @@ -66817,34 +66817,34 @@ static int walRewriteChecksums(Wal *pWal, u32 iLast){ }else{ iCksumOff = walFrameOffset(pWal->iReCksum-1, szPage) + 16; } - rc = tdsqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff); - pWal->hdr.aFrameCksum[0] = tdsqlite3Get4byte(aBuf); - pWal->hdr.aFrameCksum[1] = tdsqlite3Get4byte(&aBuf[sizeof(u32)]); + rc = sqlite3OsRead(pWal->pWalFd, aBuf, sizeof(u32)*2, iCksumOff); + pWal->hdr.aFrameCksum[0] = sqlite3Get4byte(aBuf); + pWal->hdr.aFrameCksum[1] = sqlite3Get4byte(&aBuf[sizeof(u32)]); iRead = pWal->iReCksum; pWal->iReCksum = 0; for(; rc==SQLITE_OK && iRead<=iLast; iRead++){ i64 iOff = walFrameOffset(iRead, szPage); - rc = tdsqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff); + rc = sqlite3OsRead(pWal->pWalFd, aBuf, szPage+WAL_FRAME_HDRSIZE, iOff); if( rc==SQLITE_OK ){ u32 iPgno, nDbSize; - iPgno = tdsqlite3Get4byte(aBuf); - nDbSize = tdsqlite3Get4byte(&aBuf[4]); + iPgno = sqlite3Get4byte(aBuf); + nDbSize = sqlite3Get4byte(&aBuf[4]); walEncodeFrame(pWal, iPgno, nDbSize, &aBuf[WAL_FRAME_HDRSIZE], aFrame); - rc = tdsqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff); + rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOff); } } - tdsqlite3_free(aBuf); + sqlite3_free(aBuf); return rc; } /* ** Write a set of frames to the log. The caller must hold the write-lock -** on the log file (obtained using tdsqlite3WalBeginWriteTransaction()). +** on the log file (obtained using sqlite3WalBeginWriteTransaction()). */ -SQLITE_PRIVATE int tdsqlite3WalFrames( +SQLITE_PRIVATE int sqlite3WalFrames( Wal *pWal, /* Wal handle to write to */ int szPage, /* Database page-size in bytes */ PgHdr *pList, /* List of dirty pages to write */ @@ -66898,15 +66898,15 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( u8 aWalHdr[WAL_HDRSIZE]; /* Buffer to assemble wal-header in */ u32 aCksum[2]; /* Checksum for wal-header */ - tdsqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); - tdsqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); - tdsqlite3Put4byte(&aWalHdr[8], szPage); - tdsqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); - if( pWal->nCkpt==0 ) tdsqlite3_randomness(8, pWal->hdr.aSalt); + sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); + sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); + sqlite3Put4byte(&aWalHdr[8], szPage); + sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); + if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt); memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); - tdsqlite3Put4byte(&aWalHdr[24], aCksum[0]); - tdsqlite3Put4byte(&aWalHdr[28], aCksum[1]); + sqlite3Put4byte(&aWalHdr[24], aCksum[0]); + sqlite3Put4byte(&aWalHdr[28], aCksum[1]); pWal->szPage = szPage; pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; @@ -66914,7 +66914,7 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( pWal->hdr.aFrameCksum[1] = aCksum[1]; pWal->truncateOnCommit = 1; - rc = tdsqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); + rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok")); if( rc!=SQLITE_OK ){ return rc; @@ -66928,7 +66928,7 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( ** https://sqlite.org/src/info/ff5be73dee */ if( pWal->syncHeader ){ - rc = tdsqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); + rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); if( rc ) return rc; } } @@ -66953,7 +66953,7 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( ** checksums must be recomputed when the transaction is committed. */ if( iFirst && (p->pDirty || isCommit==0) ){ u32 iWrite = 0; - VVA_ONLY(rc =) tdsqlite3WalFindFrame(pWal, p->pgno, &iWrite); + VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite); assert( rc==SQLITE_OK || iWrite==0 ); if( iWrite>=iFirst ){ i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; @@ -66962,11 +66962,11 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( pWal->iReCksum = iWrite; } #if defined(SQLITE_HAS_CODEC) - if( (pData = tdsqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; + if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; #else pData = p->pData; #endif - rc = tdsqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff); + rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOff); if( rc ) return rc; p->flags &= ~PGHDR_WAL_APPEND; continue; @@ -67006,7 +67006,7 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( if( isCommit && WAL_SYNC_FLAGS(sync_flags)!=0 ){ int bSync = 1; if( pWal->padToSectorBoundary ){ - int sectorSize = tdsqlite3SectorSize(pWal->pWalFd); + int sectorSize = sqlite3SectorSize(pWal->pWalFd); w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize; bSync = (w.iSyncPoint==iOffset); testcase( bSync ); @@ -67020,7 +67020,7 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( } if( bSync ){ assert( rc==SQLITE_OK ); - rc = tdsqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags)); + rc = sqlite3OsSync(w.pFd, WAL_SYNC_FLAGS(sync_flags)); } } @@ -67077,7 +67077,7 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( } /* -** This routine is called to implement tdsqlite3_wal_checkpoint() and +** This routine is called to implement sqlite3_wal_checkpoint() and ** related interfaces. ** ** Obtain a CHECKPOINT lock and then backfill as much information as @@ -67086,9 +67086,9 @@ SQLITE_PRIVATE int tdsqlite3WalFrames( ** If parameter xBusy is not NULL, it is a pointer to a busy-handler ** callback. In this case this function runs a blocking checkpoint. */ -SQLITE_PRIVATE int tdsqlite3WalCheckpoint( +SQLITE_PRIVATE int sqlite3WalCheckpoint( Wal *pWal, /* Wal connection */ - tdsqlite3 *db, /* Check this handle's interrupt flag */ + sqlite3 *db, /* Check this handle's interrupt flag */ int eMode, /* PASSIVE, FULL, RESTART, or TRUNCATE */ int (*xBusy)(void*), /* Function to call when busy */ void *pBusyArg, /* Context argument for xBusyHandler */ @@ -67153,7 +67153,7 @@ SQLITE_PRIVATE int tdsqlite3WalCheckpoint( if( rc==SQLITE_OK ){ rc = walIndexReadHdr(pWal, &isChanged); if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ - tdsqlite3OsUnfetch(pWal->pDbFd, 0, 0); + sqlite3OsUnfetch(pWal->pDbFd, 0, 0); } } @@ -67184,19 +67184,19 @@ SQLITE_PRIVATE int tdsqlite3WalCheckpoint( } /* Release the locks. */ - tdsqlite3WalEndWriteTransaction(pWal); + sqlite3WalEndWriteTransaction(pWal); walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); pWal->ckptLock = 0; WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok")); return (rc==SQLITE_OK && eMode!=eMode2 ? SQLITE_BUSY : rc); } -/* Return the value to pass to a tdsqlite3_wal_hook callback, the +/* Return the value to pass to a sqlite3_wal_hook callback, the ** number of frames in the WAL at the point of the last commit since -** tdsqlite3WalCallback() was called. If no commits have occurred since +** sqlite3WalCallback() was called. If no commits have occurred since ** the last call, then return 0. */ -SQLITE_PRIVATE int tdsqlite3WalCallback(Wal *pWal){ +SQLITE_PRIVATE int sqlite3WalCallback(Wal *pWal){ u32 ret = 0; if( pWal ){ ret = pWal->iCallback; @@ -67229,7 +67229,7 @@ SQLITE_PRIVATE int tdsqlite3WalCallback(Wal *pWal){ ** should acquire the database exclusive lock prior to invoking ** the op==1 case. */ -SQLITE_PRIVATE int tdsqlite3WalExclusiveMode(Wal *pWal, int op){ +SQLITE_PRIVATE int sqlite3WalExclusiveMode(Wal *pWal, int op){ int rc; assert( pWal->writeLock==0 ); assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 ); @@ -67271,7 +67271,7 @@ SQLITE_PRIVATE int tdsqlite3WalExclusiveMode(Wal *pWal, int op){ ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the ** WAL module is using shared-memory, return false. */ -SQLITE_PRIVATE int tdsqlite3WalHeapMemory(Wal *pWal){ +SQLITE_PRIVATE int sqlite3WalHeapMemory(Wal *pWal){ return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); } @@ -67280,7 +67280,7 @@ SQLITE_PRIVATE int tdsqlite3WalHeapMemory(Wal *pWal){ ** every other subsystem, so the WAL module can put whatever it needs ** in the object. */ -SQLITE_PRIVATE int tdsqlite3WalSnapshotGet(Wal *pWal, tdsqlite3_snapshot **ppSnapshot){ +SQLITE_PRIVATE int sqlite3WalSnapshotGet(Wal *pWal, sqlite3_snapshot **ppSnapshot){ int rc = SQLITE_OK; WalIndexHdr *pRet; static const u32 aZero[4] = { 0, 0, 0, 0 }; @@ -67291,12 +67291,12 @@ SQLITE_PRIVATE int tdsqlite3WalSnapshotGet(Wal *pWal, tdsqlite3_snapshot **ppSna *ppSnapshot = 0; return SQLITE_ERROR; } - pRet = (WalIndexHdr*)tdsqlite3_malloc(sizeof(WalIndexHdr)); + pRet = (WalIndexHdr*)sqlite3_malloc(sizeof(WalIndexHdr)); if( pRet==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ memcpy(pRet, &pWal->hdr, sizeof(WalIndexHdr)); - *ppSnapshot = (tdsqlite3_snapshot*)pRet; + *ppSnapshot = (sqlite3_snapshot*)pRet; } return rc; @@ -67304,7 +67304,7 @@ SQLITE_PRIVATE int tdsqlite3WalSnapshotGet(Wal *pWal, tdsqlite3_snapshot **ppSna /* Try to open on pSnapshot when the next read-transaction starts */ -SQLITE_PRIVATE void tdsqlite3WalSnapshotOpen(Wal *pWal, tdsqlite3_snapshot *pSnapshot){ +SQLITE_PRIVATE void sqlite3WalSnapshotOpen(Wal *pWal, sqlite3_snapshot *pSnapshot){ pWal->pSnapshot = (WalIndexHdr*)pSnapshot; } @@ -67312,7 +67312,7 @@ SQLITE_PRIVATE void tdsqlite3WalSnapshotOpen(Wal *pWal, tdsqlite3_snapshot *pSna ** Return a +ve value if snapshot p1 is newer than p2. A -ve value if ** p1 is older than p2 and zero if p1 and p2 are the same snapshot. */ -SQLITE_API int tdsqlite3_snapshot_cmp(tdsqlite3_snapshot *p1, tdsqlite3_snapshot *p2){ +SQLITE_API int sqlite3_snapshot_cmp(sqlite3_snapshot *p1, sqlite3_snapshot *p2){ WalIndexHdr *pHdr1 = (WalIndexHdr*)p1; WalIndexHdr *pHdr2 = (WalIndexHdr*)p2; @@ -67336,7 +67336,7 @@ SQLITE_API int tdsqlite3_snapshot_cmp(tdsqlite3_snapshot *p1, tdsqlite3_snapshot ** occurs (any value other than SQLITE_OK is returned), the CHECKPOINTER ** lock is released before returning. */ -SQLITE_PRIVATE int tdsqlite3WalSnapshotCheck(Wal *pWal, tdsqlite3_snapshot *pSnapshot){ +SQLITE_PRIVATE int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ int rc; rc = walLockShared(pWal, WAL_CKPT_LOCK); if( rc==SQLITE_OK ){ @@ -67353,9 +67353,9 @@ SQLITE_PRIVATE int tdsqlite3WalSnapshotCheck(Wal *pWal, tdsqlite3_snapshot *pSna /* ** Release a lock obtained by an earlier successful call to -** tdsqlite3WalSnapshotCheck(). +** sqlite3WalSnapshotCheck(). */ -SQLITE_PRIVATE void tdsqlite3WalSnapshotUnlock(Wal *pWal){ +SQLITE_PRIVATE void sqlite3WalSnapshotUnlock(Wal *pWal){ assert( pWal ); walUnlockShared(pWal, WAL_CKPT_LOCK); } @@ -67369,15 +67369,15 @@ SQLITE_PRIVATE void tdsqlite3WalSnapshotUnlock(Wal *pWal){ ** read-lock. This function returns the database page-size if it is known, ** or zero if it is not (or if pWal is NULL). */ -SQLITE_PRIVATE int tdsqlite3WalFramesize(Wal *pWal){ +SQLITE_PRIVATE int sqlite3WalFramesize(Wal *pWal){ assert( pWal==0 || pWal->readLock>=0 ); return (pWal ? pWal->szPage : 0); } #endif -/* Return the tdsqlite3_file object for the WAL file +/* Return the sqlite3_file object for the WAL file */ -SQLITE_PRIVATE tdsqlite3_file *tdsqlite3WalFile(Wal *pWal){ +SQLITE_PRIVATE sqlite3_file *sqlite3WalFile(Wal *pWal){ return pWal->pWalFd; } @@ -67413,10 +67413,10 @@ SQLITE_PRIVATE tdsqlite3_file *tdsqlite3WalFile(Wal *pWal){ */ static void lockBtreeMutex(Btree *p){ assert( p->locked==0 ); - assert( tdsqlite3_mutex_notheld(p->pBt->mutex) ); - assert( tdsqlite3_mutex_held(p->db->mutex) ); + assert( sqlite3_mutex_notheld(p->pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); - tdsqlite3_mutex_enter(p->pBt->mutex); + sqlite3_mutex_enter(p->pBt->mutex); p->pBt->db = p->db; p->locked = 1; } @@ -67428,11 +67428,11 @@ static void lockBtreeMutex(Btree *p){ static void SQLITE_NOINLINE unlockBtreeMutex(Btree *p){ BtShared *pBt = p->pBt; assert( p->locked==1 ); - assert( tdsqlite3_mutex_held(pBt->mutex) ); - assert( tdsqlite3_mutex_held(p->db->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); assert( p->db==pBt->db ); - tdsqlite3_mutex_leave(pBt->mutex); + sqlite3_mutex_leave(pBt->mutex); p->locked = 0; } @@ -67455,7 +67455,7 @@ static void SQLITE_NOINLINE btreeLockCarefully(Btree *p); ** for the lock to become available on p, then relock all of the ** subsequent Btrees that desire a lock. */ -SQLITE_PRIVATE void tdsqlite3BtreeEnter(Btree *p){ +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ /* Some basic sanity checking on the Btree. The list of Btrees ** connected by pNext and pPrev should be in sorted order by ** Btree.pBt value. All elements of the list should belong to @@ -67471,7 +67471,7 @@ SQLITE_PRIVATE void tdsqlite3BtreeEnter(Btree *p){ assert( p->sharable || p->wantToLock==0 ); /* We should already hold a lock on the database connection */ - assert( tdsqlite3_mutex_held(p->db->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); /* Unless the database is sharable and unlocked, then BtShared.db ** should already be set correctly. */ @@ -67483,10 +67483,10 @@ SQLITE_PRIVATE void tdsqlite3BtreeEnter(Btree *p){ btreeLockCarefully(p); } -/* This is a helper function for tdsqlite3BtreeLock(). By moving -** complex, but seldom used logic, out of tdsqlite3BtreeLock() and +/* This is a helper function for sqlite3BtreeLock(). By moving +** complex, but seldom used logic, out of sqlite3BtreeLock() and ** into this routine, we avoid unnecessary stack pointer changes -** and thus help the tdsqlite3BtreeLock() routine to run much faster +** and thus help the sqlite3BtreeLock() routine to run much faster ** in the common case. */ static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ @@ -67496,7 +67496,7 @@ static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ ** want without having to go through the ascending lock ** procedure that follows. Just be sure not to block. */ - if( tdsqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ + if( sqlite3_mutex_try(p->pBt->mutex)==SQLITE_OK ){ p->pBt->db = p->db; p->locked = 1; return; @@ -67527,8 +67527,8 @@ static void SQLITE_NOINLINE btreeLockCarefully(Btree *p){ /* ** Exit the recursive mutex on a Btree. */ -SQLITE_PRIVATE void tdsqlite3BtreeLeave(Btree *p){ - assert( tdsqlite3_mutex_held(p->db->mutex) ); +SQLITE_PRIVATE void sqlite3BtreeLeave(Btree *p){ + assert( sqlite3_mutex_held(p->db->mutex) ); if( p->sharable ){ assert( p->wantToLock>0 ); p->wantToLock--; @@ -67545,11 +67545,11 @@ SQLITE_PRIVATE void tdsqlite3BtreeLeave(Btree *p){ ** ** This routine is used only from within assert() statements. */ -SQLITE_PRIVATE int tdsqlite3BtreeHoldsMutex(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeHoldsMutex(Btree *p){ assert( p->sharable==0 || p->locked==0 || p->wantToLock>0 ); assert( p->sharable==0 || p->locked==0 || p->db==p->pBt->db ); - assert( p->sharable==0 || p->locked==0 || tdsqlite3_mutex_held(p->pBt->mutex) ); - assert( p->sharable==0 || p->locked==0 || tdsqlite3_mutex_held(p->db->mutex) ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->pBt->mutex) ); + assert( p->sharable==0 || p->locked==0 || sqlite3_mutex_held(p->db->mutex) ); return (p->sharable==0 || p->locked); } @@ -67570,33 +67570,33 @@ SQLITE_PRIVATE int tdsqlite3BtreeHoldsMutex(Btree *p){ ** two or more btrees in common both try to lock all their btrees ** at the same instant. */ -static void SQLITE_NOINLINE btreeEnterAll(tdsqlite3 *db){ +static void SQLITE_NOINLINE btreeEnterAll(sqlite3 *db){ int i; int skipOk = 1; Btree *p; - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); for(i=0; inDb; i++){ p = db->aDb[i].pBt; if( p && p->sharable ){ - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); skipOk = 0; } } db->noSharedCache = skipOk; } -SQLITE_PRIVATE void tdsqlite3BtreeEnterAll(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ if( db->noSharedCache==0 ) btreeEnterAll(db); } -static void SQLITE_NOINLINE btreeLeaveAll(tdsqlite3 *db){ +static void SQLITE_NOINLINE btreeLeaveAll(sqlite3 *db){ int i; Btree *p; - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); for(i=0; inDb; i++){ p = db->aDb[i].pBt; - if( p ) tdsqlite3BtreeLeave(p); + if( p ) sqlite3BtreeLeave(p); } } -SQLITE_PRIVATE void tdsqlite3BtreeLeaveAll(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3BtreeLeaveAll(sqlite3 *db){ if( db->noSharedCache==0 ) btreeLeaveAll(db); } @@ -67607,16 +67607,16 @@ SQLITE_PRIVATE void tdsqlite3BtreeLeaveAll(tdsqlite3 *db){ ** ** This routine is used inside assert() statements only. */ -SQLITE_PRIVATE int tdsqlite3BtreeHoldsAllMutexes(tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3 *db){ int i; - if( !tdsqlite3_mutex_held(db->mutex) ){ + if( !sqlite3_mutex_held(db->mutex) ){ return 0; } for(i=0; inDb; i++){ Btree *p; p = db->aDb[i].pBt; if( p && p->sharable && - (p->wantToLock==0 || !tdsqlite3_mutex_held(p->pBt->mutex)) ){ + (p->wantToLock==0 || !sqlite3_mutex_held(p->pBt->mutex)) ){ return 0; } } @@ -67634,14 +67634,14 @@ SQLITE_PRIVATE int tdsqlite3BtreeHoldsAllMutexes(tdsqlite3 *db){ ** (2) if iDb!=1, then the mutex on db->aDb[iDb].pBt. ** ** If pSchema is not NULL, then iDb is computed from pSchema and -** db using tdsqlite3SchemaToIndex(). +** db using sqlite3SchemaToIndex(). */ -SQLITE_PRIVATE int tdsqlite3SchemaMutexHeld(tdsqlite3 *db, int iDb, Schema *pSchema){ +SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3 *db, int iDb, Schema *pSchema){ Btree *p; assert( db!=0 ); - if( pSchema ) iDb = tdsqlite3SchemaToIndex(db, pSchema); + if( pSchema ) iDb = sqlite3SchemaToIndex(db, pSchema); assert( iDb>=0 && iDbnDb ); - if( !tdsqlite3_mutex_held(db->mutex) ) return 0; + if( !sqlite3_mutex_held(db->mutex) ) return 0; if( iDb==1 ) return 1; p = db->aDb[iDb].pBt; assert( p!=0 ); @@ -67660,10 +67660,10 @@ SQLITE_PRIVATE int tdsqlite3SchemaMutexHeld(tdsqlite3 *db, int iDb, Schema *pSch ** the ones below, are no-ops and are null #defines in btree.h. */ -SQLITE_PRIVATE void tdsqlite3BtreeEnter(Btree *p){ +SQLITE_PRIVATE void sqlite3BtreeEnter(Btree *p){ p->pBt->db = p->db; } -SQLITE_PRIVATE void tdsqlite3BtreeEnterAll(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ int i; for(i=0; inDb; i++){ Btree *p = db->aDb[i].pBt; @@ -67682,12 +67682,12 @@ SQLITE_PRIVATE void tdsqlite3BtreeEnterAll(tdsqlite3 *db){ ** any time OMIT_SHARED_CACHE is not defined, regardless of whether or not ** the build is threadsafe. Leave() is only required by threadsafe builds. */ -SQLITE_PRIVATE void tdsqlite3BtreeEnterCursor(BtCursor *pCur){ - tdsqlite3BtreeEnter(pCur->pBtree); +SQLITE_PRIVATE void sqlite3BtreeEnterCursor(BtCursor *pCur){ + sqlite3BtreeEnter(pCur->pBtree); } # if SQLITE_THREADSAFE -SQLITE_PRIVATE void tdsqlite3BtreeLeaveCursor(BtCursor *pCur){ - tdsqlite3BtreeLeave(pCur->pBtree); +SQLITE_PRIVATE void sqlite3BtreeLeaveCursor(BtCursor *pCur){ + sqlite3BtreeLeave(pCur->pBtree); } # endif #endif /* ifndef SQLITE_OMIT_INCRBLOB */ @@ -67724,8 +67724,8 @@ static const char zMagicHeader[] = SQLITE_FILE_HEADER; ** macro. */ #if 0 -int tdsqlite3BtreeTrace=1; /* True to enable tracing */ -# define TRACE(X) if(tdsqlite3BtreeTrace){printf X;fflush(stdout);} +int sqlite3BtreeTrace=1; /* True to enable tracing */ +# define TRACE(X) if(sqlite3BtreeTrace){printf X;fflush(stdout);} #else # define TRACE(X) #endif @@ -67770,9 +67770,9 @@ int tdsqlite3BtreeTrace=1; /* True to enable tracing */ ** Access to this variable is protected by SQLITE_MUTEX_STATIC_MASTER. */ #ifdef SQLITE_TEST -SQLITE_PRIVATE BtShared *SQLITE_WSD tdsqlite3SharedCacheList = 0; +SQLITE_PRIVATE BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; #else -static BtShared *SQLITE_WSD tdsqlite3SharedCacheList = 0; +static BtShared *SQLITE_WSD sqlite3SharedCacheList = 0; #endif #endif /* SQLITE_OMIT_SHARED_CACHE */ @@ -67782,10 +67782,10 @@ static BtShared *SQLITE_WSD tdsqlite3SharedCacheList = 0; ** ** This routine has no effect on existing database connections. ** The shared cache setting effects only future calls to -** tdsqlite3_open(), tdsqlite3_open16(), or tdsqlite3_open_v2(). +** sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2(). */ -SQLITE_API int tdsqlite3_enable_shared_cache(int enable){ - tdsqlite3GlobalConfig.sharedCacheEnabled = enable; +SQLITE_API int sqlite3_enable_shared_cache(int enable){ + sqlite3GlobalConfig.sharedCacheEnabled = enable; return SQLITE_OK; } #endif @@ -67822,15 +67822,15 @@ SQLITE_API int tdsqlite3_enable_shared_cache(int enable){ #ifdef SQLITE_DEBUG int corruptPageError(int lineno, MemPage *p){ char *zMsg; - tdsqlite3BeginBenignMalloc(); - zMsg = tdsqlite3_mprintf("database corruption page %d of %s", - (int)p->pgno, tdsqlite3PagerFilename(p->pBt->pPager, 0) + sqlite3BeginBenignMalloc(); + zMsg = sqlite3_mprintf("database corruption page %d of %s", + (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0) ); - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); if( zMsg ){ - tdsqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); + sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); } - tdsqlite3_free(zMsg); + sqlite3_free(zMsg); return SQLITE_CORRUPT_BKPT; } # define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage) @@ -67974,7 +67974,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ BtShared *pBt = p->pBt; BtLock *pIter; - assert( tdsqlite3BtreeHoldsMutex(p) ); + assert( sqlite3BtreeHoldsMutex(p) ); assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); assert( p->db!=0 ); assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 ); @@ -67995,7 +67995,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ ** requested lock may not be obtained. */ if( pBt->pWriter!=p && (pBt->btsFlags & BTS_EXCLUSIVE)!=0 ){ - tdsqlite3ConnectionBlocked(p->db, pBt->pWriter->db); + sqlite3ConnectionBlocked(p->db, pBt->pWriter->db); return SQLITE_LOCKED_SHAREDCACHE; } @@ -68012,7 +68012,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK ); assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK); if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ - tdsqlite3ConnectionBlocked(p->db, pIter->pBtree->db); + sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); if( eLock==WRITE_LOCK ){ assert( p==pBt->pWriter ); pBt->btsFlags |= BTS_PENDING; @@ -68047,7 +68047,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ BtLock *pLock = 0; BtLock *pIter; - assert( tdsqlite3BtreeHoldsMutex(p) ); + assert( sqlite3BtreeHoldsMutex(p) ); assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); assert( p->db!=0 ); @@ -68074,7 +68074,7 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ ** with table iTable, allocate one and link it into the list. */ if( !pLock ){ - pLock = (BtLock *)tdsqlite3MallocZero(sizeof(BtLock)); + pLock = (BtLock *)sqlite3MallocZero(sizeof(BtLock)); if( !pLock ){ return SQLITE_NOMEM_BKPT; } @@ -68110,7 +68110,7 @@ static void clearAllSharedCacheTableLocks(Btree *p){ BtShared *pBt = p->pBt; BtLock **ppIter = &pBt->pLock; - assert( tdsqlite3BtreeHoldsMutex(p) ); + assert( sqlite3BtreeHoldsMutex(p) ); assert( p->sharable || 0==*ppIter ); assert( p->inTrans>0 ); @@ -68122,7 +68122,7 @@ static void clearAllSharedCacheTableLocks(Btree *p){ *ppIter = pLock->pNext; assert( pLock->iTable!=1 || pLock==&p->lock ); if( pLock->iTable!=1 ){ - tdsqlite3_free(pLock); + sqlite3_free(pLock); } }else{ ppIter = &pLock->pNext; @@ -68176,7 +68176,7 @@ static void releasePageNotNull(MemPage *pPage); /* Forward reference */ */ #ifdef SQLITE_DEBUG static int cursorHoldsMutex(BtCursor *p){ - return tdsqlite3_mutex_held(p->pBt->mutex); + return sqlite3_mutex_held(p->pBt->mutex); } /* Verify that the cursor and the BtShared agree about what is the current @@ -68205,7 +68205,7 @@ static int cursorOwnsBtShared(BtCursor *p){ */ static void invalidateAllOverflowCache(BtShared *pBt){ BtCursor *p; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); for(p=pBt->pCursor; p; p=p->pNext){ invalidateOverflowCache(p); } @@ -68233,7 +68233,7 @@ static void invalidateIncrblobCursors( ){ BtCursor *p; if( pBtree->hasIncrblobCur==0 ) return; - assert( tdsqlite3BtreeHoldsMutex(pBtree) ); + assert( sqlite3BtreeHoldsMutex(pBtree) ); pBtree->hasIncrblobCur = 0; for(p=pBtree->pBt->pCursor; p; p=p->pNext){ if( (p->curFlags & BTCF_Incrblob)!=0 ){ @@ -68289,13 +68289,13 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ int rc = SQLITE_OK; if( !pBt->pHasContent ){ assert( pgno<=pBt->nPage ); - pBt->pHasContent = tdsqlite3BitvecCreate(pBt->nPage); + pBt->pHasContent = sqlite3BitvecCreate(pBt->nPage); if( !pBt->pHasContent ){ rc = SQLITE_NOMEM_BKPT; } } - if( rc==SQLITE_OK && pgno<=tdsqlite3BitvecSize(pBt->pHasContent) ){ - rc = tdsqlite3BitvecSet(pBt->pHasContent, pgno); + if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){ + rc = sqlite3BitvecSet(pBt->pHasContent, pgno); } return rc; } @@ -68309,7 +68309,7 @@ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ */ static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ Bitvec *p = pBt->pHasContent; - return (p && (pgno>tdsqlite3BitvecSize(p) || tdsqlite3BitvecTest(p, pgno))); + return (p && (pgno>sqlite3BitvecSize(p) || sqlite3BitvecTest(p, pgno))); } /* @@ -68317,7 +68317,7 @@ static int btreeGetHasContent(BtShared *pBt, Pgno pgno){ ** invoked at the conclusion of each write-transaction. */ static void btreeClearHasContent(BtShared *pBt){ - tdsqlite3BitvecDestroy(pBt->pHasContent); + sqlite3BitvecDestroy(pBt->pHasContent); pBt->pHasContent = 0; } @@ -68356,24 +68356,24 @@ static int saveCursorKey(BtCursor *pCur){ if( pCur->curIntKey ){ /* Only the rowid is required for a table btree */ - pCur->nKey = tdsqlite3BtreeIntegerKey(pCur); + pCur->nKey = sqlite3BtreeIntegerKey(pCur); }else{ /* For an index btree, save the complete key content. It is possible ** that the current key is corrupt. In that case, it is possible that - ** the tdsqlite3VdbeRecordUnpack() function may overread the buffer by + ** the sqlite3VdbeRecordUnpack() function may overread the buffer by ** up to the size of 1 varint plus 1 8-byte value when the cursor ** position is restored. Hence the 17 bytes of padding allocated ** below. */ void *pKey; - pCur->nKey = tdsqlite3BtreePayloadSize(pCur); - pKey = tdsqlite3Malloc( pCur->nKey + 9 + 8 ); + pCur->nKey = sqlite3BtreePayloadSize(pCur); + pKey = sqlite3Malloc( pCur->nKey + 9 + 8 ); if( pKey ){ - rc = tdsqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); + rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); if( rc==SQLITE_OK ){ memset(((u8*)pKey)+pCur->nKey, 0, 9+8); pCur->pKey = pKey; }else{ - tdsqlite3_free(pKey); + sqlite3_free(pKey); } }else{ rc = SQLITE_NOMEM_BKPT; @@ -68442,7 +68442,7 @@ static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*); */ static int saveAllCursors(BtShared *pBt, Pgno iRoot, BtCursor *pExcept){ BtCursor *p; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( pExcept==0 || pExcept->pBt==pBt ); for(p=pBt->pCursor; p; p=p->pNext){ if( p!=pExcept && (0==iRoot || p->pgnoRoot==iRoot) ) break; @@ -68482,9 +68482,9 @@ static int SQLITE_NOINLINE saveCursorsOnList( /* ** Clear the current cursor position. */ -SQLITE_PRIVATE void tdsqlite3BtreeClearCursor(BtCursor *pCur){ +SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); - tdsqlite3_free(pCur->pKey); + sqlite3_free(pCur->pKey); pCur->pKey = 0; pCur->eState = CURSOR_INVALID; } @@ -68507,9 +68507,9 @@ static int btreeMoveto( if( pKey ){ KeyInfo *pKeyInfo = pCur->pKeyInfo; assert( nKey==(i64)(int)nKey ); - pIdxKey = tdsqlite3VdbeAllocUnpackedRecord(pKeyInfo); + pIdxKey = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); if( pIdxKey==0 ) return SQLITE_NOMEM_BKPT; - tdsqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); + sqlite3VdbeRecordUnpack(pKeyInfo, (int)nKey, pKey, pIdxKey); if( pIdxKey->nField==0 || pIdxKey->nField>pKeyInfo->nAllField ){ rc = SQLITE_CORRUPT_BKPT; goto moveto_done; @@ -68517,10 +68517,10 @@ static int btreeMoveto( }else{ pIdxKey = 0; } - rc = tdsqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); + rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); moveto_done: if( pIdxKey ){ - tdsqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); + sqlite3DbFree(pCur->pKeyInfo->db, pIdxKey); } return rc; } @@ -68541,13 +68541,13 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){ return pCur->skipNext; } pCur->eState = CURSOR_INVALID; - if( tdsqlite3FaultSim(410) ){ + if( sqlite3FaultSim(410) ){ rc = SQLITE_IOERR; }else{ rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext); } if( rc==SQLITE_OK ){ - tdsqlite3_free(pCur->pKey); + sqlite3_free(pCur->pKey); pCur->pKey = 0; assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID ); if( skipNext ) pCur->skipNext = skipNext; @@ -68572,12 +68572,12 @@ static int btreeRestoreCursorPosition(BtCursor *pCur){ ** ** Calling this routine with a NULL cursor pointer returns false. ** -** Use the separate tdsqlite3BtreeCursorRestore() routine to restore a cursor +** Use the separate sqlite3BtreeCursorRestore() routine to restore a cursor ** back to where it ought to be if this routine returns true. */ -SQLITE_PRIVATE int tdsqlite3BtreeCursorHasMoved(BtCursor *pCur){ +SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur){ assert( EIGHT_BYTE_ALIGNMENT(pCur) - || pCur==tdsqlite3BtreeFakeValidCursor() ); + || pCur==sqlite3BtreeFakeValidCursor() ); assert( offsetof(BtCursor, eState)==0 ); assert( sizeof(pCur->eState)==1 ); return CURSOR_VALID != *(u8*)pCur; @@ -68585,10 +68585,10 @@ SQLITE_PRIVATE int tdsqlite3BtreeCursorHasMoved(BtCursor *pCur){ /* ** Return a pointer to a fake BtCursor object that will always answer -** false to the tdsqlite3BtreeCursorHasMoved() routine above. The fake +** false to the sqlite3BtreeCursorHasMoved() routine above. The fake ** cursor returned must not be used with any other Btree interface. */ -SQLITE_PRIVATE BtCursor *tdsqlite3BtreeFakeValidCursor(void){ +SQLITE_PRIVATE BtCursor *sqlite3BtreeFakeValidCursor(void){ static u8 fakeCursor = CURSOR_VALID; assert( offsetof(BtCursor, eState)==0 ); return (BtCursor*)&fakeCursor; @@ -68605,9 +68605,9 @@ SQLITE_PRIVATE BtCursor *tdsqlite3BtreeFakeValidCursor(void){ ** nearby row. ** ** This routine should only be called for a cursor that just returned -** TRUE from tdsqlite3BtreeCursorHasMoved(). +** TRUE from sqlite3BtreeCursorHasMoved(). */ -SQLITE_PRIVATE int tdsqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ +SQLITE_PRIVATE int sqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRow){ int rc; assert( pCur!=0 ); @@ -68631,7 +68631,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeCursorRestore(BtCursor *pCur, int *pDifferentRo ** and number of the varargs parameters) is determined by the eHintType ** parameter. See the definitions of the BTREE_HINT_* macros for details. */ -SQLITE_PRIVATE void tdsqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ +SQLITE_PRIVATE void sqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...){ /* Used only by system that substitute their own storage engine */ } #endif @@ -68639,7 +68639,7 @@ SQLITE_PRIVATE void tdsqlite3BtreeCursorHint(BtCursor *pCur, int eHintType, ...) /* ** Provide flag hints to the cursor. */ -SQLITE_PRIVATE void tdsqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ +SQLITE_PRIVATE void sqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ assert( x==BTREE_SEEK_EQ || x==BTREE_BULKLOAD || x==0 ); pCur->hints = x; } @@ -68658,7 +68658,7 @@ SQLITE_PRIVATE void tdsqlite3BtreeCursorHintFlags(BtCursor *pCur, unsigned x){ static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ int nPagesPerMapPage; Pgno iPtrMap, ret; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); if( pgno<2 ) return 0; nPagesPerMapPage = (pBt->usableSize/5)+1; iPtrMap = (pgno-2)/nPagesPerMapPage; @@ -68688,7 +68688,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ if( *pRC ) return; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); /* The master-journal page number must never be used as a pointer map page */ assert( 0==PTRMAP_ISPAGE(pBt, PENDING_BYTE_PAGE(pBt)) ); @@ -68698,12 +68698,12 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ return; } iPtrmap = PTRMAP_PAGENO(pBt, key); - rc = tdsqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); if( rc!=SQLITE_OK ){ *pRC = rc; return; } - if( ((char*)tdsqlite3PagerGetExtra(pDbPage))[0]!=0 ){ + if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){ /* The first byte of the extra data is the MemPage.isInit byte. ** If that byte is set, it means this page is also being used ** as a btree page. */ @@ -68716,11 +68716,11 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ goto ptrmap_exit; } assert( offset <= (int)pBt->usableSize-5 ); - pPtrmap = (u8 *)tdsqlite3PagerGetData(pDbPage); + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); - *pRC= rc = tdsqlite3PagerWrite(pDbPage); + *pRC= rc = sqlite3PagerWrite(pDbPage); if( rc==SQLITE_OK ){ pPtrmap[offset] = eType; put4byte(&pPtrmap[offset+1], parent); @@ -68728,7 +68728,7 @@ static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ } ptrmap_exit: - tdsqlite3PagerUnref(pDbPage); + sqlite3PagerUnref(pDbPage); } /* @@ -68745,18 +68745,18 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ int offset; /* Offset of entry in pointer map */ int rc; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); iPtrmap = PTRMAP_PAGENO(pBt, key); - rc = tdsqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); + rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); if( rc!=0 ){ return rc; } - pPtrmap = (u8 *)tdsqlite3PagerGetData(pDbPage); + pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); offset = PTRMAP_PTROFFSET(iPtrmap, key); if( offset<0 ){ - tdsqlite3PagerUnref(pDbPage); + sqlite3PagerUnref(pDbPage); return SQLITE_CORRUPT_BKPT; } assert( offset <= (int)pBt->usableSize-5 ); @@ -68764,7 +68764,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ *pEType = pPtrmap[offset]; if( pPgno ) *pPgno = get4byte(&pPtrmap[offset+1]); - tdsqlite3PagerUnref(pDbPage); + sqlite3PagerUnref(pDbPage); if( *pEType<1 || *pEType>5 ) return SQLITE_CORRUPT_PGNO(iPtrmap); return SQLITE_OK; } @@ -68847,7 +68847,7 @@ static void btreeParseCellPtrNoPayload( u8 *pCell, /* Pointer to the cell text. */ CellInfo *pInfo /* Fill in this structure */ ){ - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( pPage->leaf==0 ); assert( pPage->childPtrSize==4 ); #ifndef SQLITE_DEBUG @@ -68868,7 +68868,7 @@ static void btreeParseCellPtr( u32 nPayload; /* Number of bytes of cell payload */ u64 iKey; /* Extracted Key value */ - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( pPage->leaf==0 || pPage->leaf==1 ); assert( pPage->intKeyLeaf ); assert( pPage->childPtrSize==0 ); @@ -68935,7 +68935,7 @@ static void btreeParseCellPtrIndex( u8 *pIter; /* For scanning through pCell */ u32 nPayload; /* Number of bytes of cell payload */ - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( pPage->leaf==0 || pPage->leaf==1 ); assert( pPage->intKeyLeaf==0 ); pIter = pCell + pPage->childPtrSize; @@ -69116,11 +69116,11 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ int iCellFirst; /* First allowable cell index */ int iCellLast; /* Last possible cell index */ - assert( tdsqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE ); assert( pPage->nOverflow==0 ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); temp = 0; src = data = pPage->aData; hdr = pPage->hdrOffset; @@ -69200,7 +69200,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ if( temp==0 ){ int x; if( cbrk==pc ) continue; - temp = tdsqlite3PagerTempSpace(pPage->pBt->pPager); + temp = sqlite3PagerTempSpace(pPage->pBt->pPager); x = get2byte(&data[hdr+5]); memcpy(&temp[x], &data[x], (cbrk+size) - x); src = temp; @@ -69219,7 +69219,7 @@ static int defragmentPage(MemPage *pPage, int nMaxFrag){ data[hdr+1] = 0; data[hdr+2] = 0; memset(&data[iCellFirst], 0, cbrk-iCellFirst); - assert( tdsqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); return SQLITE_OK; } @@ -69312,9 +69312,9 @@ static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ int rc = SQLITE_OK; /* Integer return code */ int gap; /* First byte of gap between cell pointers and cell content */ - assert( tdsqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( nByte>=0 ); /* Minimum cell size is 4 */ assert( pPage->nFree>=nByte ); assert( pPage->nOverflow==0 ); @@ -69412,10 +69412,10 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){ unsigned char *data = pPage->aData; /* Page content */ assert( pPage->pBt!=0 ); - assert( tdsqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( CORRUPT_DB || iStart>=pPage->hdrOffset+6+pPage->childPtrSize ); assert( CORRUPT_DB || iEnd <= pPage->pBt->usableSize ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( iSize>=4 ); /* Minimum cell size is 4 */ assert( iStart<=pPage->pBt->usableSize-4 ); @@ -69512,7 +69512,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){ BtShared *pBt; /* A copy of pPage->pBt */ assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pPage->leaf = (u8)(flagByte>>3); assert( PTF_LEAF == 1<<3 ); flagByte &= ~PTF_LEAF; pPage->childPtrSize = 4-4*pPage->leaf; @@ -69573,10 +69573,10 @@ static int btreeComputeFreeSpace(MemPage *pPage){ assert( pPage->pBt!=0 ); assert( pPage->pBt->db!=0 ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); - assert( pPage->pgno==tdsqlite3PagerPagenumber(pPage->pDbPage) ); - assert( pPage == tdsqlite3PagerGetExtra(pPage->pDbPage) ); - assert( pPage->aData == tdsqlite3PagerGetData(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); assert( pPage->isInit==1 ); assert( pPage->nFree<0 ); @@ -69690,10 +69690,10 @@ static int btreeInitPage(MemPage *pPage){ assert( pPage->pBt!=0 ); assert( pPage->pBt->db!=0 ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); - assert( pPage->pgno==tdsqlite3PagerPagenumber(pPage->pDbPage) ); - assert( pPage == tdsqlite3PagerGetExtra(pPage->pDbPage) ); - assert( pPage->aData == tdsqlite3PagerGetData(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) ); + assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) ); + assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) ); assert( pPage->isInit==0 ); pBt = pPage->pBt; @@ -69743,11 +69743,11 @@ static void zeroPage(MemPage *pPage, int flags){ u8 hdr = pPage->hdrOffset; u16 first; - assert( tdsqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); - assert( tdsqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); - assert( tdsqlite3PagerGetData(pPage->pDbPage) == data ); - assert( tdsqlite3PagerIswriteable(pPage->pDbPage) ); - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerPagenumber(pPage->pDbPage)==pPage->pgno ); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage) == data ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pBt->mutex) ); if( pBt->btsFlags & BTS_FAST_SECURE ){ memset(&data[hdr], 0, pBt->usableSize - hdr); } @@ -69775,15 +69775,15 @@ static void zeroPage(MemPage *pPage, int flags){ ** the btree layer. */ static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ - MemPage *pPage = (MemPage*)tdsqlite3PagerGetExtra(pDbPage); + MemPage *pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); if( pgno!=pPage->pgno ){ - pPage->aData = tdsqlite3PagerGetData(pDbPage); + pPage->aData = sqlite3PagerGetData(pDbPage); pPage->pDbPage = pDbPage; pPage->pBt = pBt; pPage->pgno = pgno; pPage->hdrOffset = pgno==1 ? 100 : 0; } - assert( pPage->aData==tdsqlite3PagerGetData(pDbPage) ); + assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); return pPage; } @@ -69794,7 +69794,7 @@ static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ ** If the PAGER_GET_NOCONTENT flag is set, it means that we do not care ** about the content of the page at this time. So do not go to the disk ** to fetch the content. Just fill in the content with zeros for now. -** If in the future we call tdsqlite3PagerWrite() on this page, that +** If in the future we call sqlite3PagerWrite() on this page, that ** means we have started to be concerned about content and the disk ** read should occur at that point. */ @@ -69808,8 +69808,8 @@ static int btreeGetPage( DbPage *pDbPage; assert( flags==0 || flags==PAGER_GET_NOCONTENT || flags==PAGER_GET_READONLY ); - assert( tdsqlite3_mutex_held(pBt->mutex) ); - rc = tdsqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); + assert( sqlite3_mutex_held(pBt->mutex) ); + rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, flags); if( rc ) return rc; *ppPage = btreePageFromDbPage(pDbPage, pgno, pBt); return SQLITE_OK; @@ -69822,8 +69822,8 @@ static int btreeGetPage( */ static MemPage *btreePageLookup(BtShared *pBt, Pgno pgno){ DbPage *pDbPage; - assert( tdsqlite3_mutex_held(pBt->mutex) ); - pDbPage = tdsqlite3PagerLookup(pBt->pPager, pgno); + assert( sqlite3_mutex_held(pBt->mutex) ); + pDbPage = sqlite3PagerLookup(pBt->pPager, pgno); if( pDbPage ){ return btreePageFromDbPage(pDbPage, pgno, pBt); } @@ -69838,8 +69838,8 @@ static Pgno btreePagecount(BtShared *pBt){ assert( (pBt->nPage & 0x80000000)==0 || CORRUPT_DB ); return pBt->nPage; } -SQLITE_PRIVATE u32 tdsqlite3BtreeLastPage(Btree *p){ - assert( tdsqlite3BtreeHoldsMutex(p) ); +SQLITE_PRIVATE u32 sqlite3BtreeLastPage(Btree *p){ + assert( sqlite3BtreeHoldsMutex(p) ); return btreePagecount(p->pBt) & 0x7fffffff; } @@ -69865,7 +69865,7 @@ static int getAndInitPage( ){ int rc; DbPage *pDbPage; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( pCur==0 || ppPage==&pCur->pPage ); assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); assert( pCur==0 || pCur->iPage>0 ); @@ -69874,11 +69874,11 @@ static int getAndInitPage( rc = SQLITE_CORRUPT_BKPT; goto getAndInitPage_error1; } - rc = tdsqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); + rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); if( rc ){ goto getAndInitPage_error1; } - *ppPage = (MemPage*)tdsqlite3PagerGetExtra(pDbPage); + *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); if( (*ppPage)->isInit==0 ){ btreePageFromDbPage(pDbPage, pgno, pBt); rc = btreeInitPage(*ppPage); @@ -69887,7 +69887,7 @@ static int getAndInitPage( } } assert( (*ppPage)->pgno==pgno ); - assert( (*ppPage)->aData==tdsqlite3PagerGetData(pDbPage) ); + assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); /* If obtaining a child page for a cursor, we must verify that the page is ** compatible with the root page. */ @@ -69919,10 +69919,10 @@ static void releasePageNotNull(MemPage *pPage){ assert( pPage->aData ); assert( pPage->pBt ); assert( pPage->pDbPage!=0 ); - assert( tdsqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); - assert( tdsqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); - tdsqlite3PagerUnrefNotNull(pPage->pDbPage); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefNotNull(pPage->pDbPage); } static void releasePage(MemPage *pPage){ if( pPage ) releasePageNotNull(pPage); @@ -69932,10 +69932,10 @@ static void releasePageOne(MemPage *pPage){ assert( pPage->aData ); assert( pPage->pBt ); assert( pPage->pDbPage!=0 ); - assert( tdsqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); - assert( tdsqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); - tdsqlite3PagerUnrefPageOne(pPage->pDbPage); + assert( sqlite3PagerGetExtra(pPage->pDbPage) == (void*)pPage ); + assert( sqlite3PagerGetData(pPage->pDbPage)==pPage->aData ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + sqlite3PagerUnrefPageOne(pPage->pDbPage); } /* @@ -69955,7 +69955,7 @@ static int btreeGetUnusedPage( ){ int rc = btreeGetPage(pBt, pgno, ppPage, flags); if( rc==SQLITE_OK ){ - if( tdsqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ + if( sqlite3PagerPageRefcount((*ppPage)->pDbPage)>1 ){ releasePage(*ppPage); *ppPage = 0; return SQLITE_CORRUPT_BKPT; @@ -69978,12 +69978,12 @@ static int btreeGetUnusedPage( */ static void pageReinit(DbPage *pData){ MemPage *pPage; - pPage = (MemPage *)tdsqlite3PagerGetExtra(pData); - assert( tdsqlite3PagerPageRefcount(pData)>0 ); + pPage = (MemPage *)sqlite3PagerGetExtra(pData); + assert( sqlite3PagerPageRefcount(pData)>0 ); if( pPage->isInit ){ - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pPage->isInit = 0; - if( tdsqlite3PagerPageRefcount(pData)>1 ){ + if( sqlite3PagerPageRefcount(pData)>1 ){ /* pPage might not be a btree page; it might be an overflow page ** or ptrmap page or a free page. In those cases, the following ** call to btreeInitPage() will likely return SQLITE_CORRUPT. @@ -70001,9 +70001,9 @@ static void pageReinit(DbPage *pData){ static int btreeInvokeBusyHandler(void *pArg){ BtShared *pBt = (BtShared*)pArg; assert( pBt->db ); - assert( tdsqlite3_mutex_held(pBt->db->mutex) ); - return tdsqlite3InvokeBusyHandler(&pBt->db->busyHandler, - tdsqlite3PagerFile(pBt->pPager)); + assert( sqlite3_mutex_held(pBt->db->mutex) ); + return sqlite3InvokeBusyHandler(&pBt->db->busyHandler, + sqlite3PagerFile(pBt->pPager)); } /* @@ -70013,7 +70013,7 @@ static int btreeInvokeBusyHandler(void *pArg){ ** then an ephemeral database is created. The ephemeral database might ** be exclusively in memory, or it might use a disk-based memory cache. ** Either way, the ephemeral database will be automatically deleted -** when tdsqlite3BtreeClose() is called. +** when sqlite3BtreeClose() is called. ** ** If zFilename is ":memory:" then an in-memory database is created ** that is automatically destroyed when it is closed. @@ -70027,17 +70027,17 @@ static int btreeInvokeBusyHandler(void *pArg){ ** objects in the same database connection since doing so will lead ** to problems with locking. */ -SQLITE_PRIVATE int tdsqlite3BtreeOpen( - tdsqlite3_vfs *pVfs, /* VFS to use for this b-tree */ +SQLITE_PRIVATE int sqlite3BtreeOpen( + sqlite3_vfs *pVfs, /* VFS to use for this b-tree */ const char *zFilename, /* Name of the file containing the BTree database */ - tdsqlite3 *db, /* Associated database handle */ + sqlite3 *db, /* Associated database handle */ Btree **ppBtree, /* Pointer to new Btree object written here */ int flags, /* Options */ - int vfsFlags /* Flags passed through to tdsqlite3_vfs.xOpen() */ + int vfsFlags /* Flags passed through to sqlite3_vfs.xOpen() */ ){ BtShared *pBt = 0; /* Shared part of btree structure */ Btree *p; /* Handle to return */ - tdsqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ + sqlite3_mutex *mutexOpen = 0; /* Prevents a race condition. Ticket #3537 */ int rc = SQLITE_OK; /* Result code from this function */ u8 nReserve; /* Byte of unused space on each page */ unsigned char zDbHeader[100]; /* Database header content */ @@ -70052,13 +70052,13 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( const int isMemdb = 0; #else const int isMemdb = (zFilename && strcmp(zFilename, ":memory:")==0) - || (isTempDb && tdsqlite3TempInMemory(db)) + || (isTempDb && sqlite3TempInMemory(db)) || (vfsFlags & SQLITE_OPEN_MEMORY)!=0; #endif assert( db!=0 ); assert( pVfs!=0 ); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); assert( (flags&0xff)==flags ); /* flags fit in 8 bits */ /* Only a BTREE_SINGLE database can be BTREE_UNORDERED */ @@ -70073,7 +70073,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( if( (vfsFlags & SQLITE_OPEN_MAIN_DB)!=0 && (isMemdb || isTempDb) ){ vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB; } - p = tdsqlite3MallocZero(sizeof(Btree)); + p = sqlite3MallocZero(sizeof(Btree)); if( !p ){ return SQLITE_NOMEM_BKPT; } @@ -70091,49 +70091,49 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( */ if( isTempDb==0 && (isMemdb==0 || (vfsFlags&SQLITE_OPEN_URI)!=0) ){ if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ - int nFilename = tdsqlite3Strlen30(zFilename)+1; + int nFilename = sqlite3Strlen30(zFilename)+1; int nFullPathname = pVfs->mxPathname+1; - char *zFullPathname = tdsqlite3Malloc(MAX(nFullPathname,nFilename)); - MUTEX_LOGIC( tdsqlite3_mutex *mutexShared; ) + char *zFullPathname = sqlite3Malloc(MAX(nFullPathname,nFilename)); + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) p->sharable = 1; if( !zFullPathname ){ - tdsqlite3_free(p); + sqlite3_free(p); return SQLITE_NOMEM_BKPT; } if( isMemdb ){ memcpy(zFullPathname, zFilename, nFilename); }else{ - rc = tdsqlite3OsFullPathname(pVfs, zFilename, + rc = sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname); if( rc ){ if( rc==SQLITE_OK_SYMLINK ){ rc = SQLITE_OK; }else{ - tdsqlite3_free(zFullPathname); - tdsqlite3_free(p); + sqlite3_free(zFullPathname); + sqlite3_free(p); return rc; } } } #if SQLITE_THREADSAFE - mutexOpen = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); - tdsqlite3_mutex_enter(mutexOpen); - mutexShared = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); - tdsqlite3_mutex_enter(mutexShared); + mutexOpen = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_OPEN); + sqlite3_mutex_enter(mutexOpen); + mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex_enter(mutexShared); #endif - for(pBt=GLOBAL(BtShared*,tdsqlite3SharedCacheList); pBt; pBt=pBt->pNext){ + for(pBt=GLOBAL(BtShared*,sqlite3SharedCacheList); pBt; pBt=pBt->pNext){ assert( pBt->nRef>0 ); - if( 0==strcmp(zFullPathname, tdsqlite3PagerFilename(pBt->pPager, 0)) - && tdsqlite3PagerVfs(pBt->pPager)==pVfs ){ + if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager, 0)) + && sqlite3PagerVfs(pBt->pPager)==pVfs ){ int iDb; for(iDb=db->nDb-1; iDb>=0; iDb--){ Btree *pExisting = db->aDb[iDb].pBt; if( pExisting && pExisting->pBt==pBt ){ - tdsqlite3_mutex_leave(mutexShared); - tdsqlite3_mutex_leave(mutexOpen); - tdsqlite3_free(zFullPathname); - tdsqlite3_free(p); + sqlite3_mutex_leave(mutexShared); + sqlite3_mutex_leave(mutexOpen); + sqlite3_free(zFullPathname); + sqlite3_free(p); return SQLITE_CONSTRAINT; } } @@ -70142,14 +70142,14 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( break; } } - tdsqlite3_mutex_leave(mutexShared); - tdsqlite3_free(zFullPathname); + sqlite3_mutex_leave(mutexShared); + sqlite3_free(zFullPathname); } #ifdef SQLITE_DEBUG else{ /* In debug mode, we mark all persistent databases as sharable ** even when they are not. This exercises the locking code and - ** gives more opportunity for asserts(tdsqlite3_mutex_held()) + ** gives more opportunity for asserts(sqlite3_mutex_held()) ** statements to find locking problems. */ p->sharable = 1; @@ -70169,28 +70169,28 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( assert( sizeof(u16)==2 ); assert( sizeof(Pgno)==4 ); - pBt = tdsqlite3MallocZero( sizeof(*pBt) ); + pBt = sqlite3MallocZero( sizeof(*pBt) ); if( pBt==0 ){ rc = SQLITE_NOMEM_BKPT; goto btree_open_out; } - rc = tdsqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, + rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, sizeof(MemPage), flags, vfsFlags, pageReinit); if( rc==SQLITE_OK ){ - tdsqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); - rc = tdsqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); + sqlite3PagerSetMmapLimit(pBt->pPager, db->szMmap); + rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); } if( rc!=SQLITE_OK ){ goto btree_open_out; } pBt->openFlags = (u8)flags; pBt->db = db; - tdsqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); + sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); p->pBt = pBt; pBt->pCursor = 0; pBt->pPage1 = 0; - if( tdsqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; + if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; #if defined(SQLITE_SECURE_DELETE) pBt->btsFlags |= BTS_SECURE_DELETE; #elif defined(SQLITE_FAST_SECURE_DELETE) @@ -70227,7 +70227,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); #endif } - rc = tdsqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); if( rc ) goto btree_open_out; pBt->usableSize = pBt->pageSize - nReserve; assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ @@ -70237,19 +70237,19 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( */ pBt->nRef = 1; if( p->sharable ){ - MUTEX_LOGIC( tdsqlite3_mutex *mutexShared; ) - MUTEX_LOGIC( mutexShared = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) - if( SQLITE_THREADSAFE && tdsqlite3GlobalConfig.bCoreMutex ){ - pBt->mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_FAST); + MUTEX_LOGIC( sqlite3_mutex *mutexShared; ) + MUTEX_LOGIC( mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);) + if( SQLITE_THREADSAFE && sqlite3GlobalConfig.bCoreMutex ){ + pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST); if( pBt->mutex==0 ){ rc = SQLITE_NOMEM_BKPT; goto btree_open_out; } } - tdsqlite3_mutex_enter(mutexShared); - pBt->pNext = GLOBAL(BtShared*,tdsqlite3SharedCacheList); - GLOBAL(BtShared*,tdsqlite3SharedCacheList) = pBt; - tdsqlite3_mutex_leave(mutexShared); + sqlite3_mutex_enter(mutexShared); + pBt->pNext = GLOBAL(BtShared*,sqlite3SharedCacheList); + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt; + sqlite3_mutex_leave(mutexShared); } #endif } @@ -70290,32 +70290,32 @@ SQLITE_PRIVATE int tdsqlite3BtreeOpen( btree_open_out: if( rc!=SQLITE_OK ){ if( pBt && pBt->pPager ){ - tdsqlite3PagerClose(pBt->pPager, 0); + sqlite3PagerClose(pBt->pPager, 0); } - tdsqlite3_free(pBt); - tdsqlite3_free(p); + sqlite3_free(pBt); + sqlite3_free(p); *ppBtree = 0; }else{ - tdsqlite3_file *pFile; + sqlite3_file *pFile; /* If the B-Tree was successfully opened, set the pager-cache size to the ** default value. Except, when opening on an existing shared pager-cache, ** do not change the pager-cache size. */ - if( tdsqlite3BtreeSchema(p, 0, 0)==0 ){ - tdsqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); + if( sqlite3BtreeSchema(p, 0, 0)==0 ){ + sqlite3PagerSetCachesize(p->pBt->pPager, SQLITE_DEFAULT_CACHE_SIZE); } - pFile = tdsqlite3PagerFile(pBt->pPager); + pFile = sqlite3PagerFile(pBt->pPager); if( pFile->pMethods ){ - tdsqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db); + sqlite3OsFileControlHint(pFile, SQLITE_FCNTL_PDB, (void*)&pBt->db); } } if( mutexOpen ){ - assert( tdsqlite3_mutex_held(mutexOpen) ); - tdsqlite3_mutex_leave(mutexOpen); + assert( sqlite3_mutex_held(mutexOpen) ); + sqlite3_mutex_leave(mutexOpen); } - assert( rc!=SQLITE_OK || tdsqlite3BtreeConnectionCount(*ppBtree)>0 ); + assert( rc!=SQLITE_OK || sqlite3BtreeConnectionCount(*ppBtree)>0 ); return rc; } @@ -70327,19 +70327,19 @@ btree_open_out: */ static int removeFromSharingList(BtShared *pBt){ #ifndef SQLITE_OMIT_SHARED_CACHE - MUTEX_LOGIC( tdsqlite3_mutex *pMaster; ) + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) BtShared *pList; int removed = 0; - assert( tdsqlite3_mutex_notheld(pBt->mutex) ); - MUTEX_LOGIC( pMaster = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - tdsqlite3_mutex_enter(pMaster); + assert( sqlite3_mutex_notheld(pBt->mutex) ); + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(pMaster); pBt->nRef--; if( pBt->nRef<=0 ){ - if( GLOBAL(BtShared*,tdsqlite3SharedCacheList)==pBt ){ - GLOBAL(BtShared*,tdsqlite3SharedCacheList) = pBt->pNext; + if( GLOBAL(BtShared*,sqlite3SharedCacheList)==pBt ){ + GLOBAL(BtShared*,sqlite3SharedCacheList) = pBt->pNext; }else{ - pList = GLOBAL(BtShared*,tdsqlite3SharedCacheList); + pList = GLOBAL(BtShared*,sqlite3SharedCacheList); while( ALWAYS(pList) && pList->pNext!=pBt ){ pList=pList->pNext; } @@ -70348,11 +70348,11 @@ static int removeFromSharingList(BtShared *pBt){ } } if( SQLITE_THREADSAFE ){ - tdsqlite3_mutex_free(pBt->mutex); + sqlite3_mutex_free(pBt->mutex); } removed = 1; } - tdsqlite3_mutex_leave(pMaster); + sqlite3_mutex_leave(pMaster); return removed; #else return 1; @@ -70366,7 +70366,7 @@ static int removeFromSharingList(BtShared *pBt){ */ static void allocateTempSpace(BtShared *pBt){ if( !pBt->pTmpSpace ){ - pBt->pTmpSpace = tdsqlite3PageMalloc( pBt->pageSize ); + pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize ); /* One of the uses of pBt->pTmpSpace is to format cells before ** inserting them into a leaf page (function fillInCell()). If @@ -70396,7 +70396,7 @@ static void allocateTempSpace(BtShared *pBt){ static void freeTempSpace(BtShared *pBt){ if( pBt->pTmpSpace ){ pBt->pTmpSpace -= 4; - tdsqlite3PageFree(pBt->pTmpSpace); + sqlite3PageFree(pBt->pTmpSpace); pBt->pTmpSpace = 0; } } @@ -70404,28 +70404,28 @@ static void freeTempSpace(BtShared *pBt){ /* ** Close an open database and invalidate all cursors. */ -SQLITE_PRIVATE int tdsqlite3BtreeClose(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){ BtShared *pBt = p->pBt; BtCursor *pCur; /* Close all cursors opened via this handle. */ - assert( tdsqlite3_mutex_held(p->db->mutex) ); - tdsqlite3BtreeEnter(p); + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); pCur = pBt->pCursor; while( pCur ){ BtCursor *pTmp = pCur; pCur = pCur->pNext; if( pTmp->pBtree==p ){ - tdsqlite3BtreeCloseCursor(pTmp); + sqlite3BtreeCloseCursor(pTmp); } } /* Rollback any active transaction and free the handle structure. - ** The call to tdsqlite3BtreeRollback() drops any table-locks held by + ** The call to sqlite3BtreeRollback() drops any table-locks held by ** this handle. */ - tdsqlite3BtreeRollback(p, SQLITE_OK, 0); - tdsqlite3BtreeLeave(p); + sqlite3BtreeRollback(p, SQLITE_OK, 0); + sqlite3BtreeLeave(p); /* If there are still other outstanding references to the shared-btree ** structure, return now. The remainder of this procedure cleans @@ -70439,13 +70439,13 @@ SQLITE_PRIVATE int tdsqlite3BtreeClose(Btree *p){ ** Clean out and delete the BtShared object. */ assert( !pBt->pCursor ); - tdsqlite3PagerClose(pBt->pPager, p->db); + sqlite3PagerClose(pBt->pPager, p->db); if( pBt->xFreeSchema && pBt->pSchema ){ pBt->xFreeSchema(pBt->pSchema); } - tdsqlite3DbFree(0, pBt->pSchema); + sqlite3DbFree(0, pBt->pSchema); freeTempSpace(pBt); - tdsqlite3_free(pBt); + sqlite3_free(pBt); } #ifndef SQLITE_OMIT_SHARED_CACHE @@ -70455,7 +70455,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeClose(Btree *p){ if( p->pNext ) p->pNext->pPrev = p->pPrev; #endif - tdsqlite3_free(p); + sqlite3_free(p); return SQLITE_OK; } @@ -70466,12 +70466,12 @@ SQLITE_PRIVATE int tdsqlite3BtreeClose(Btree *p){ ** cache is allowed to grow larger than this limit if it contains ** dirty pages or pages still in active use. */ -SQLITE_PRIVATE int tdsqlite3BtreeSetCacheSize(Btree *p, int mxPage){ +SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree *p, int mxPage){ BtShared *pBt = p->pBt; - assert( tdsqlite3_mutex_held(p->db->mutex) ); - tdsqlite3BtreeEnter(p); - tdsqlite3PagerSetCachesize(pBt->pPager, mxPage); - tdsqlite3BtreeLeave(p); + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetCachesize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); return SQLITE_OK; } @@ -70485,13 +70485,13 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetCacheSize(Btree *p, int mxPage){ ** as an argument, no changes are made to the spill size setting, so ** using mxPage of 0 is a way to query the current spill size. */ -SQLITE_PRIVATE int tdsqlite3BtreeSetSpillSize(Btree *p, int mxPage){ +SQLITE_PRIVATE int sqlite3BtreeSetSpillSize(Btree *p, int mxPage){ BtShared *pBt = p->pBt; int res; - assert( tdsqlite3_mutex_held(p->db->mutex) ); - tdsqlite3BtreeEnter(p); - res = tdsqlite3PagerSetSpillsize(pBt->pPager, mxPage); - tdsqlite3BtreeLeave(p); + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + res = sqlite3PagerSetSpillsize(pBt->pPager, mxPage); + sqlite3BtreeLeave(p); return res; } @@ -70500,12 +70500,12 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetSpillSize(Btree *p, int mxPage){ ** Change the limit on the amount of the database file that may be ** memory mapped. */ -SQLITE_PRIVATE int tdsqlite3BtreeSetMmapLimit(Btree *p, tdsqlite3_int64 szMmap){ +SQLITE_PRIVATE int sqlite3BtreeSetMmapLimit(Btree *p, sqlite3_int64 szMmap){ BtShared *pBt = p->pBt; - assert( tdsqlite3_mutex_held(p->db->mutex) ); - tdsqlite3BtreeEnter(p); - tdsqlite3PagerSetMmapLimit(pBt->pPager, szMmap); - tdsqlite3BtreeLeave(p); + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetMmapLimit(pBt->pPager, szMmap); + sqlite3BtreeLeave(p); return SQLITE_OK; } #endif /* SQLITE_MAX_MMAP_SIZE>0 */ @@ -70519,15 +70519,15 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetMmapLimit(Btree *p, tdsqlite3_int64 szMmap){ ** probability of damage to near zero but with a write performance reduction. */ #ifndef SQLITE_OMIT_PAGER_PRAGMAS -SQLITE_PRIVATE int tdsqlite3BtreeSetPagerFlags( +SQLITE_PRIVATE int sqlite3BtreeSetPagerFlags( Btree *p, /* The btree to set the safety level on */ unsigned pgFlags /* Various PAGER_* flags */ ){ BtShared *pBt = p->pBt; - assert( tdsqlite3_mutex_held(p->db->mutex) ); - tdsqlite3BtreeEnter(p); - tdsqlite3PagerSetFlags(pBt->pPager, pgFlags); - tdsqlite3BtreeLeave(p); + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); + sqlite3PagerSetFlags(pBt->pPager, pgFlags); + sqlite3BtreeLeave(p); return SQLITE_OK; } #endif @@ -70552,16 +70552,16 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetPagerFlags( ** If the iFix!=0 then the BTS_PAGESIZE_FIXED flag is set so that the page size ** and autovacuum mode can no longer be changed. */ -SQLITE_PRIVATE int tdsqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ +SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, int iFix){ int rc = SQLITE_OK; BtShared *pBt = p->pBt; assert( nReserve>=-1 && nReserve<=255 ); - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); #if SQLITE_HAS_CODEC if( nReserve>pBt->optimalReserve ) pBt->optimalReserve = (u8)nReserve; #endif if( pBt->btsFlags & BTS_PAGESIZE_FIXED ){ - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return SQLITE_READONLY; } if( nReserve<0 ){ @@ -70575,34 +70575,34 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserv pBt->pageSize = (u32)pageSize; freeTempSpace(pBt); } - rc = tdsqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); pBt->usableSize = pBt->pageSize - (u16)nReserve; if( iFix ) pBt->btsFlags |= BTS_PAGESIZE_FIXED; - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } /* ** Return the currently defined page size */ -SQLITE_PRIVATE int tdsqlite3BtreeGetPageSize(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeGetPageSize(Btree *p){ return p->pBt->pageSize; } /* -** This function is similar to tdsqlite3BtreeGetReserve(), except that it +** This function is similar to sqlite3BtreeGetReserve(), except that it ** may only be called if it is guaranteed that the b-tree mutex is already ** held. ** ** This is useful in one special case in the backup API code where it is ** known that the shared b-tree mutex is held, but the mutex on the -** database handle that owns *p is not. In this case if tdsqlite3BtreeEnter() +** database handle that owns *p is not. In this case if sqlite3BtreeEnter() ** were to be called, it might collide with some other operation on the ** database handle that owns *p, causing undefined behavior. */ -SQLITE_PRIVATE int tdsqlite3BtreeGetReserveNoMutex(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeGetReserveNoMutex(Btree *p){ int n; - assert( tdsqlite3_mutex_held(p->pBt->mutex) ); + assert( sqlite3_mutex_held(p->pBt->mutex) ); n = p->pBt->pageSize - p->pBt->usableSize; return n; } @@ -70616,14 +70616,14 @@ SQLITE_PRIVATE int tdsqlite3BtreeGetReserveNoMutex(Btree *p){ ** greater of the current reserved space and the maximum requested ** reserve space. */ -SQLITE_PRIVATE int tdsqlite3BtreeGetOptimalReserve(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeGetOptimalReserve(Btree *p){ int n; - tdsqlite3BtreeEnter(p); - n = tdsqlite3BtreeGetReserveNoMutex(p); + sqlite3BtreeEnter(p); + n = sqlite3BtreeGetReserveNoMutex(p); #ifdef SQLITE_HAS_CODEC if( npBt->optimalReserve ) n = p->pBt->optimalReserve; #endif - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return n; } @@ -70633,11 +70633,11 @@ SQLITE_PRIVATE int tdsqlite3BtreeGetOptimalReserve(Btree *p){ ** No changes are made if mxPage is 0 or negative. ** Regardless of the value of mxPage, return the maximum page count. */ -SQLITE_PRIVATE int tdsqlite3BtreeMaxPageCount(Btree *p, int mxPage){ +SQLITE_PRIVATE int sqlite3BtreeMaxPageCount(Btree *p, int mxPage){ int n; - tdsqlite3BtreeEnter(p); - n = tdsqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); - tdsqlite3BtreeLeave(p); + sqlite3BtreeEnter(p); + n = sqlite3PagerMaxPageCount(p->pBt->pPager, mxPage); + sqlite3BtreeLeave(p); return n; } @@ -70659,10 +70659,10 @@ SQLITE_PRIVATE int tdsqlite3BtreeMaxPageCount(Btree *p, int mxPage){ ** that freelist leaf pages are written back into the database, increasing ** the amount of disk I/O. */ -SQLITE_PRIVATE int tdsqlite3BtreeSecureDelete(Btree *p, int newFlag){ +SQLITE_PRIVATE int sqlite3BtreeSecureDelete(Btree *p, int newFlag){ int b; if( p==0 ) return 0; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); assert( BTS_OVERWRITE==BTS_SECURE_DELETE*2 ); assert( BTS_FAST_SECURE==(BTS_OVERWRITE|BTS_SECURE_DELETE) ); if( newFlag>=0 ){ @@ -70670,7 +70670,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeSecureDelete(Btree *p, int newFlag){ p->pBt->btsFlags |= BTS_SECURE_DELETE*newFlag; } b = (p->pBt->btsFlags & BTS_FAST_SECURE)/BTS_SECURE_DELETE; - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return b; } @@ -70680,7 +70680,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeSecureDelete(Btree *p, int newFlag){ ** is disabled. The default value for the auto-vacuum property is ** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. */ -SQLITE_PRIVATE int tdsqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ +SQLITE_PRIVATE int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ #ifdef SQLITE_OMIT_AUTOVACUUM return SQLITE_READONLY; #else @@ -70688,14 +70688,14 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ int rc = SQLITE_OK; u8 av = (u8)autoVacuum; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); if( (pBt->btsFlags & BTS_PAGESIZE_FIXED)!=0 && (av ?1:0)!=pBt->autoVacuum ){ rc = SQLITE_READONLY; }else{ pBt->autoVacuum = av ?1:0; pBt->incrVacuum = av==2 ?1:0; } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; #endif } @@ -70704,18 +70704,18 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ ** Return the value of the 'auto-vacuum' property. If auto-vacuum is ** enabled 1 is returned. Otherwise 0. */ -SQLITE_PRIVATE int tdsqlite3BtreeGetAutoVacuum(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeGetAutoVacuum(Btree *p){ #ifdef SQLITE_OMIT_AUTOVACUUM return BTREE_AUTOVACUUM_NONE; #else int rc; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); rc = ( (!p->pBt->autoVacuum)?BTREE_AUTOVACUUM_NONE: (!p->pBt->incrVacuum)?BTREE_AUTOVACUUM_FULL: BTREE_AUTOVACUUM_INCR ); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; #endif } @@ -70729,7 +70729,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeGetAutoVacuum(Btree *p){ #if SQLITE_DEFAULT_SYNCHRONOUS!=SQLITE_DEFAULT_WAL_SYNCHRONOUS \ && !defined(SQLITE_OMIT_WAL) static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ - tdsqlite3 *db; + sqlite3 *db; Db *pDb; if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } @@ -70738,7 +70738,7 @@ static void setDefaultSyncFlag(BtShared *pBt, u8 safety_level){ && pDb!=&db->aDb[1] ){ pDb->safety_level = safety_level; - tdsqlite3PagerSetFlags(pBt->pPager, + sqlite3PagerSetFlags(pBt->pPager, pDb->safety_level | (db->flags & PAGER_FLAGS_MASK)); } } @@ -70767,9 +70767,9 @@ static int lockBtree(BtShared *pBt){ u32 nPageFile = 0; /* Number of pages in the database file */ u32 nPageHeader; /* Number of pages in the database according to hdr */ - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( pBt->pPage1==0 ); - rc = tdsqlite3PagerSharedLock(pBt->pPager); + rc = sqlite3PagerSharedLock(pBt->pPager); if( rc!=SQLITE_OK ) return rc; rc = btreeGetPage(pBt, 1, &pPage1, 0); if( rc!=SQLITE_OK ) return rc; @@ -70778,7 +70778,7 @@ static int lockBtree(BtShared *pBt){ ** a valid database file. */ nPage = nPageHeader = get4byte(28+(u8*)pPage1->aData); - tdsqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); + sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); if( nPage==0 || memcmp(24+(u8*)pPage1->aData, 92+(u8*)pPage1->aData,4)!=0 ){ nPage = nPageFile; } @@ -70822,7 +70822,7 @@ static int lockBtree(BtShared *pBt){ */ if( page1[19]==2 && (pBt->btsFlags & BTS_NO_WAL)==0 ){ int isOpen = 0; - rc = tdsqlite3PagerOpenWal(pBt->pPager, &isOpen); + rc = sqlite3PagerOpenWal(pBt->pPager, &isOpen); if( rc!=SQLITE_OK ){ goto page1_init_failed; }else{ @@ -70880,11 +70880,11 @@ static int lockBtree(BtShared *pBt){ pBt->usableSize = usableSize; pBt->pageSize = pageSize; freeTempSpace(pBt); - rc = tdsqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, pageSize-usableSize); return rc; } - if( tdsqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){ + if( sqlite3WritableSchema(pBt->db)==0 && nPage>nPageFile ){ rc = SQLITE_CORRUPT_BKPT; goto page1_init_failed; } @@ -70968,12 +70968,12 @@ static int countValidCursors(BtShared *pBt, int wrOnly){ ** If there is a transaction in progress, this routine is a no-op. */ static void unlockBtreeIfUnused(BtShared *pBt){ - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ MemPage *pPage1 = pBt->pPage1; assert( pPage1->aData ); - assert( tdsqlite3PagerRefcount(pBt->pPager)==1 ); + assert( sqlite3PagerRefcount(pBt->pPager)==1 ); pBt->pPage1 = 0; releasePageOne(pPage1); } @@ -70989,14 +70989,14 @@ static int newDatabase(BtShared *pBt){ unsigned char *data; int rc; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); if( pBt->nPage>0 ){ return SQLITE_OK; } pP1 = pBt->pPage1; assert( pP1!=0 ); data = pP1->aData; - rc = tdsqlite3PagerWrite(pP1->pDbPage); + rc = sqlite3PagerWrite(pP1->pDbPage); if( rc ) return rc; memcpy(data, zMagicHeader, sizeof(zMagicHeader)); assert( sizeof(zMagicHeader)==16 ); @@ -71028,12 +71028,12 @@ static int newDatabase(BtShared *pBt){ ** consisting of a single page and no schema objects). Return SQLITE_OK ** if successful, or an SQLite error code otherwise. */ -SQLITE_PRIVATE int tdsqlite3BtreeNewDb(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeNewDb(Btree *p){ int rc; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); p->pBt->nPage = 0; rc = newDatabase(p->pBt); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -71050,13 +71050,13 @@ SQLITE_PRIVATE int tdsqlite3BtreeNewDb(Btree *p){ ** changes to the database. None of the following routines ** will work unless a transaction is started first: ** -** tdsqlite3BtreeCreateTable() -** tdsqlite3BtreeCreateIndex() -** tdsqlite3BtreeClearTable() -** tdsqlite3BtreeDropTable() -** tdsqlite3BtreeInsert() -** tdsqlite3BtreeDelete() -** tdsqlite3BtreeUpdateMeta() +** sqlite3BtreeCreateTable() +** sqlite3BtreeCreateIndex() +** sqlite3BtreeClearTable() +** sqlite3BtreeDropTable() +** sqlite3BtreeInsert() +** sqlite3BtreeDelete() +** sqlite3BtreeUpdateMeta() ** ** If an initial attempt to acquire the lock fails because of lock contention ** and the database was previously unlocked, then invoke the busy handler @@ -71072,11 +71072,11 @@ SQLITE_PRIVATE int tdsqlite3BtreeNewDb(Btree *p){ ** when A already has a read lock, we encourage A to give up and let B ** proceed. */ -SQLITE_PRIVATE int tdsqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ +SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ BtShared *pBt = p->pBt; int rc = SQLITE_OK; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); btreeIntegrity(p); /* If the btree is already in a write-transaction, or it @@ -71089,7 +71089,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVe assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); if( (p->db->flags & SQLITE_ResetDatabase) - && tdsqlite3PagerIsreadonly(pBt->pPager)==0 + && sqlite3PagerIsreadonly(pBt->pPager)==0 ){ pBt->btsFlags &= ~BTS_READ_ONLY; } @@ -71102,7 +71102,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVe #ifndef SQLITE_OMIT_SHARED_CACHE { - tdsqlite3 *pBlock = 0; + sqlite3 *pBlock = 0; /* If another database handle has already opened a write transaction ** on this shared-btree structure and a second write transaction is ** requested, return SQLITE_LOCKED. @@ -71121,7 +71121,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVe } } if( pBlock ){ - tdsqlite3ConnectionBlocked(p->db, pBlock); + sqlite3ConnectionBlocked(p->db, pBlock); rc = SQLITE_LOCKED_SHAREDCACHE; goto trans_begun; } @@ -71150,7 +71150,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVe if( (pBt->btsFlags & BTS_READ_ONLY)!=0 ){ rc = SQLITE_READONLY; }else{ - rc = tdsqlite3PagerBegin(pBt->pPager,wrflag>1,tdsqlite3TempInMemory(p->db)); + rc = sqlite3PagerBegin(pBt->pPager,wrflag>1,sqlite3TempInMemory(p->db)); if( rc==SQLITE_OK ){ rc = newDatabase(pBt); }else if( rc==SQLITE_BUSY_SNAPSHOT && pBt->inTransaction==TRANS_NONE ){ @@ -71167,7 +71167,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVe } }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && btreeInvokeBusyHandler(pBt) ); - tdsqlite3PagerResetLockTimeout(pBt->pPager); + sqlite3PagerResetLockTimeout(pBt->pPager); if( rc==SQLITE_OK ){ if( p->inTrans==TRANS_NONE ){ @@ -71201,7 +71201,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVe ** rollback occurs within the transaction. */ if( pBt->nPage!=get4byte(&pPage1->aData[28]) ){ - rc = tdsqlite3PagerWrite(pPage1->pDbPage); + rc = sqlite3PagerWrite(pPage1->pDbPage); if( rc==SQLITE_OK ){ put4byte(&pPage1->aData[28], pBt->nPage); } @@ -71219,12 +71219,12 @@ trans_begun: ** open savepoints. If the second parameter is greater than 0 and ** the sub-journal is not already open, then it will be opened here. */ - rc = tdsqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + rc = sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); } } btreeIntegrity(p); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -71242,7 +71242,7 @@ static int setChildPtrmaps(MemPage *pPage){ BtShared *pBt = pPage->pBt; Pgno pgno = pPage->pgno; - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); rc = pPage->isInit ? SQLITE_OK : btreeInitPage(pPage); if( rc!=SQLITE_OK ) return rc; nCell = pPage->nCell; @@ -71281,8 +71281,8 @@ static int setChildPtrmaps(MemPage *pPage){ ** overflow page in the list. */ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); - assert( tdsqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); if( eType==PTRMAP_OVERFLOW2 ){ /* The pointer is always the first 4 bytes of the page in this case. */ if( get4byte(pPage->aData)!=iFrom ){ @@ -71347,7 +71347,7 @@ static int relocatePage( u8 eType, /* Pointer map 'type' entry for pDbPage */ Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ Pgno iFreePage, /* The location to move pDbPage to */ - int isCommit /* isCommit flag passed to tdsqlite3PagerMovepage */ + int isCommit /* isCommit flag passed to sqlite3PagerMovepage */ ){ MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ Pgno iDbPage = pDbPage->pgno; @@ -71356,14 +71356,14 @@ static int relocatePage( assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( pDbPage->pBt==pBt ); if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; /* Move page iDbPage from its current location to page number iFreePage */ TRACE(("AUTOVACUUM: Moving %d to free page %d (ptr page %d type %d)\n", iDbPage, iFreePage, iPtrPage, eType)); - rc = tdsqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); + rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); if( rc!=SQLITE_OK ){ return rc; } @@ -71401,7 +71401,7 @@ static int relocatePage( if( rc!=SQLITE_OK ){ return rc; } - rc = tdsqlite3PagerWrite(pPtrPage->pDbPage); + rc = sqlite3PagerWrite(pPtrPage->pDbPage); if( rc!=SQLITE_OK ){ releasePage(pPtrPage); return rc; @@ -71439,7 +71439,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){ Pgno nFreeList; /* Number of pages still on the free-list */ int rc; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( iLastPg>nFin ); if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){ @@ -71557,11 +71557,11 @@ static Pgno finalDbSize(BtShared *pBt, Pgno nOrig, Pgno nFree){ ** SQLITE_DONE is returned. If it is not finished, but no error occurred, ** SQLITE_OK is returned. Otherwise an SQLite error code. */ -SQLITE_PRIVATE int tdsqlite3BtreeIncrVacuum(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeIncrVacuum(Btree *p){ int rc; BtShared *pBt = p->pBt; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); assert( pBt->inTransaction==TRANS_WRITE && p->inTrans==TRANS_WRITE ); if( !pBt->autoVacuum ){ rc = SQLITE_DONE; @@ -71579,19 +71579,19 @@ SQLITE_PRIVATE int tdsqlite3BtreeIncrVacuum(Btree *p){ rc = incrVacuumStep(pBt, nFin, nOrig, 0); } if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerWrite(pBt->pPage1->pDbPage); + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); put4byte(&pBt->pPage1->aData[28], pBt->nPage); } }else{ rc = SQLITE_DONE; } } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } /* -** This routine is called prior to tdsqlite3PagerCommit when a transaction +** This routine is called prior to sqlite3PagerCommit when a transaction ** is committed for an auto-vacuum database. ** ** If SQLITE_OK is returned, then *pnTrunc is set to the number of pages @@ -71602,9 +71602,9 @@ SQLITE_PRIVATE int tdsqlite3BtreeIncrVacuum(Btree *p){ static int autoVacuumCommit(BtShared *pBt){ int rc = SQLITE_OK; Pager *pPager = pBt->pPager; - VVA_ONLY( int nRef = tdsqlite3PagerRefcount(pPager); ) + VVA_ONLY( int nRef = sqlite3PagerRefcount(pPager); ) - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); invalidateAllOverflowCache(pBt); assert(pBt->autoVacuum); if( !pBt->incrVacuum ){ @@ -71632,7 +71632,7 @@ static int autoVacuumCommit(BtShared *pBt){ rc = incrVacuumStep(pBt, nFin, iFree, 1); } if( (rc==SQLITE_DONE || rc==SQLITE_OK) && nFree>0 ){ - rc = tdsqlite3PagerWrite(pBt->pPage1->pDbPage); + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); put4byte(&pBt->pPage1->aData[32], 0); put4byte(&pBt->pPage1->aData[36], 0); put4byte(&pBt->pPage1->aData[28], nFin); @@ -71640,11 +71640,11 @@ static int autoVacuumCommit(BtShared *pBt){ pBt->nPage = nFin; } if( rc!=SQLITE_OK ){ - tdsqlite3PagerRollback(pPager); + sqlite3PagerRollback(pPager); } } - assert( nRef>=tdsqlite3PagerRefcount(pPager) ); + assert( nRef>=sqlite3PagerRefcount(pPager) ); return rc; } @@ -71662,7 +71662,7 @@ static int autoVacuumCommit(BtShared *pBt){ ** database are written into the database file and flushed to oxide. ** At the end of this call, the rollback journal still exists on the ** disk and we are still holding all locks, so the transaction has not -** committed. See tdsqlite3BtreeCommitPhaseTwo() for the second phase of the +** committed. See sqlite3BtreeCommitPhaseTwo() for the second phase of the ** commit process. ** ** This call is a no-op if no write-transaction is currently active on pBt. @@ -71678,25 +71678,25 @@ static int autoVacuumCommit(BtShared *pBt){ ** Once this is routine has returned, the only thing required to commit ** the write-transaction for this database file is to delete the journal. */ -SQLITE_PRIVATE int tdsqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ int rc = SQLITE_OK; if( p->inTrans==TRANS_WRITE ){ BtShared *pBt = p->pBt; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); #ifndef SQLITE_OMIT_AUTOVACUUM if( pBt->autoVacuum ){ rc = autoVacuumCommit(pBt); if( rc!=SQLITE_OK ){ - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } } if( pBt->bDoTruncate ){ - tdsqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); + sqlite3PagerTruncateImage(pBt->pPager, pBt->nPage); } #endif - rc = tdsqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0); - tdsqlite3BtreeLeave(p); + rc = sqlite3PagerCommitPhaseOne(pBt->pPager, zMaster, 0); + sqlite3BtreeLeave(p); } return rc; } @@ -71707,8 +71707,8 @@ SQLITE_PRIVATE int tdsqlite3BtreeCommitPhaseOne(Btree *p, const char *zMaster){ */ static void btreeEndTransaction(Btree *p){ BtShared *pBt = p->pBt; - tdsqlite3 *db = p->db; - assert( tdsqlite3BtreeHoldsMutex(p) ); + sqlite3 *db = p->db; + assert( sqlite3BtreeHoldsMutex(p) ); #ifndef SQLITE_OMIT_AUTOVACUUM pBt->bDoTruncate = 0; @@ -71745,8 +71745,8 @@ static void btreeEndTransaction(Btree *p){ ** Commit the transaction currently in progress. ** ** This routine implements the second phase of a 2-phase commit. The -** tdsqlite3BtreeCommitPhaseOne() routine does the first phase and should -** be invoked prior to calling this routine. The tdsqlite3BtreeCommitPhaseOne() +** sqlite3BtreeCommitPhaseOne() routine does the first phase and should +** be invoked prior to calling this routine. The sqlite3BtreeCommitPhaseOne() ** routine did all the work of writing information out to disk and flushing the ** contents so that they are written onto the disk platter. All this ** routine has to do is delete or truncate or zero the header in the @@ -71767,10 +71767,10 @@ static void btreeEndTransaction(Btree *p){ ** This will release the write lock on the database file. If there ** are no active cursors, it also releases the read lock. */ -SQLITE_PRIVATE int tdsqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ +SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ if( p->inTrans==TRANS_NONE ) return SQLITE_OK; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); btreeIntegrity(p); /* If the handle has a write-transaction open, commit the shared-btrees @@ -71781,9 +71781,9 @@ SQLITE_PRIVATE int tdsqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ BtShared *pBt = p->pBt; assert( pBt->inTransaction==TRANS_WRITE ); assert( pBt->nTransaction>0 ); - rc = tdsqlite3PagerCommitPhaseTwo(pBt->pPager); + rc = sqlite3PagerCommitPhaseTwo(pBt->pPager); if( rc!=SQLITE_OK && bCleanup==0 ){ - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } p->iDataVersion--; /* Compensate for pPager->iDataVersion++; */ @@ -71792,21 +71792,21 @@ SQLITE_PRIVATE int tdsqlite3BtreeCommitPhaseTwo(Btree *p, int bCleanup){ } btreeEndTransaction(p); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return SQLITE_OK; } /* ** Do both phases of a commit. */ -SQLITE_PRIVATE int tdsqlite3BtreeCommit(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeCommit(Btree *p){ int rc; - tdsqlite3BtreeEnter(p); - rc = tdsqlite3BtreeCommitPhaseOne(p, 0); + sqlite3BtreeEnter(p); + rc = sqlite3BtreeCommitPhaseOne(p, 0); if( rc==SQLITE_OK ){ - rc = tdsqlite3BtreeCommitPhaseTwo(p, 0); + rc = sqlite3BtreeCommitPhaseTwo(p, 0); } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -71836,30 +71836,30 @@ SQLITE_PRIVATE int tdsqlite3BtreeCommit(Btree *p){ ** SQLITE_OK is returned if successful, or if an error occurs while ** saving a cursor position, an SQLite error code. */ -SQLITE_PRIVATE int tdsqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){ +SQLITE_PRIVATE int sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int writeOnly){ BtCursor *p; int rc = SQLITE_OK; assert( (writeOnly==0 || writeOnly==1) && BTCF_WriteFlag==1 ); if( pBtree ){ - tdsqlite3BtreeEnter(pBtree); + sqlite3BtreeEnter(pBtree); for(p=pBtree->pBt->pCursor; p; p=p->pNext){ if( writeOnly && (p->curFlags & BTCF_WriteFlag)==0 ){ if( p->eState==CURSOR_VALID || p->eState==CURSOR_SKIPNEXT ){ rc = saveCursorPosition(p); if( rc!=SQLITE_OK ){ - (void)tdsqlite3BtreeTripAllCursors(pBtree, rc, 0); + (void)sqlite3BtreeTripAllCursors(pBtree, rc, 0); break; } } }else{ - tdsqlite3BtreeClearCursor(p); + sqlite3BtreeClearCursor(p); p->eState = CURSOR_FAULT; p->skipNext = errCode; } btreeReleaseAllCursorPages(p); } - tdsqlite3BtreeLeave(pBtree); + sqlite3BtreeLeave(pBtree); } return rc; } @@ -71871,7 +71871,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeTripAllCursors(Btree *pBtree, int errCode, int static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){ int nPage = get4byte(&pPage1->aData[28]); testcase( nPage==0 ); - if( nPage==0 ) tdsqlite3PagerPagecount(pBt->pPager, &nPage); + if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); testcase( pBt->nPage!=nPage ); pBt->nPage = nPage; } @@ -71887,14 +71887,14 @@ static void btreeSetNPage(BtShared *pBt, MemPage *pPage1){ ** This will release the write lock on the database file. If there ** are no active cursors, it also releases the read lock. */ -SQLITE_PRIVATE int tdsqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ +SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly){ int rc; BtShared *pBt = p->pBt; MemPage *pPage1; assert( writeOnly==1 || writeOnly==0 ); assert( tripCode==SQLITE_ABORT_ROLLBACK || tripCode==SQLITE_OK ); - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); if( tripCode==SQLITE_OK ){ rc = tripCode = saveAllCursors(pBt, 0, 0); if( rc ) writeOnly = 0; @@ -71902,7 +71902,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly) rc = SQLITE_OK; } if( tripCode ){ - int rc2 = tdsqlite3BtreeTripAllCursors(p, tripCode, writeOnly); + int rc2 = sqlite3BtreeTripAllCursors(p, tripCode, writeOnly); assert( rc==SQLITE_OK || (writeOnly==0 && rc2==SQLITE_OK) ); if( rc2!=SQLITE_OK ) rc = rc2; } @@ -71912,7 +71912,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly) int rc2; assert( TRANS_WRITE==pBt->inTransaction ); - rc2 = tdsqlite3PagerRollback(pBt->pPager); + rc2 = sqlite3PagerRollback(pBt->pPager); if( rc2!=SQLITE_OK ){ rc = rc2; } @@ -71930,7 +71930,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly) } btreeEndTransaction(p); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -71950,12 +71950,12 @@ SQLITE_PRIVATE int tdsqlite3BtreeRollback(Btree *p, int tripCode, int writeOnly) ** including the new anonymous savepoint, open on the B-Tree. i.e. if there ** are no active savepoints and no other statement-transactions open, ** iStatement is 1. This anonymous savepoint can be released or rolled back -** using the tdsqlite3BtreeSavepoint() function. +** using the sqlite3BtreeSavepoint() function. */ -SQLITE_PRIVATE int tdsqlite3BtreeBeginStmt(Btree *p, int iStatement){ +SQLITE_PRIVATE int sqlite3BtreeBeginStmt(Btree *p, int iStatement){ int rc; BtShared *pBt = p->pBt; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); assert( iStatement>0 ); @@ -71966,8 +71966,8 @@ SQLITE_PRIVATE int tdsqlite3BtreeBeginStmt(Btree *p, int iStatement){ ** SQL statements. It is illegal to open, release or rollback any ** such savepoints while the statement transaction savepoint is active. */ - rc = tdsqlite3PagerOpenSavepoint(pBt->pPager, iStatement); - tdsqlite3BtreeLeave(p); + rc = sqlite3PagerOpenSavepoint(pBt->pPager, iStatement); + sqlite3BtreeLeave(p); return rc; } @@ -71983,18 +71983,18 @@ SQLITE_PRIVATE int tdsqlite3BtreeBeginStmt(Btree *p, int iStatement){ ** from a normal transaction rollback, as no locks are released and the ** transaction remains open. */ -SQLITE_PRIVATE int tdsqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ +SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ int rc = SQLITE_OK; if( p && p->inTrans==TRANS_WRITE ){ BtShared *pBt = p->pBt; assert( op==SAVEPOINT_RELEASE || op==SAVEPOINT_ROLLBACK ); assert( iSavepoint>=0 || (iSavepoint==-1 && op==SAVEPOINT_ROLLBACK) ); - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); if( op==SAVEPOINT_ROLLBACK ){ rc = saveAllCursors(pBt, 0, 0); } if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); + rc = sqlite3PagerSavepoint(pBt->pPager, op, iSavepoint); } if( rc==SQLITE_OK ){ if( iSavepoint<0 && (pBt->btsFlags & BTS_INITIALLY_EMPTY)!=0 ){ @@ -72007,7 +72007,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ ** the transaction was started. Otherwise, it must be at least 1. */ assert( CORRUPT_DB || pBt->nPage>0 ); } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); } return rc; } @@ -72051,7 +72051,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ ** root page of a b-tree. If it is not, then the cursor acquired ** will not work correctly. ** -** It is assumed that the tdsqlite3BtreeCursorZero() has been called +** It is assumed that the sqlite3BtreeCursorZero() has been called ** on pCur to initialize the memory space prior to invoking this routine. */ static int btreeCursor( @@ -72064,7 +72064,7 @@ static int btreeCursor( BtShared *pBt = p->pBt; /* Shared b-tree handle */ BtCursor *pX; /* Looping over other all cursors */ - assert( tdsqlite3BtreeHoldsMutex(p) ); + assert( sqlite3BtreeHoldsMutex(p) ); assert( wrFlag==0 || wrFlag==BTREE_WRCSR || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) @@ -72127,12 +72127,12 @@ static int btreeCursorWithLock( BtCursor *pCur /* Space for new cursor */ ){ int rc; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, pCur); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } -SQLITE_PRIVATE int tdsqlite3BtreeCursor( +SQLITE_PRIVATE int sqlite3BtreeCursor( Btree *p, /* The btree */ int iTable, /* Root page of table to open */ int wrFlag, /* 1 to write. 0 read-only */ @@ -72154,7 +72154,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeCursor( ** to users so they cannot do the sizeof() themselves - they must call ** this routine. */ -SQLITE_PRIVATE int tdsqlite3BtreeCursorSize(void){ +SQLITE_PRIVATE int sqlite3BtreeCursorSize(void){ return ROUND8(sizeof(BtCursor)); } @@ -72166,7 +72166,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeCursorSize(void){ ** do not need to be zeroed and they are large, so we can save a lot ** of run-time by skipping the initialization of those elements. */ -SQLITE_PRIVATE void tdsqlite3BtreeCursorZero(BtCursor *p){ +SQLITE_PRIVATE void sqlite3BtreeCursorZero(BtCursor *p){ memset(p, 0, offsetof(BtCursor, BTCURSOR_FIRST_UNINIT)); } @@ -72174,11 +72174,11 @@ SQLITE_PRIVATE void tdsqlite3BtreeCursorZero(BtCursor *p){ ** Close a cursor. The read lock on the database file is released ** when the last cursor is closed. */ -SQLITE_PRIVATE int tdsqlite3BtreeCloseCursor(BtCursor *pCur){ +SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ Btree *pBtree = pCur->pBtree; if( pBtree ){ BtShared *pBt = pCur->pBt; - tdsqlite3BtreeEnter(pBtree); + sqlite3BtreeEnter(pBtree); assert( pBt->pCursor!=0 ); if( pBt->pCursor==pCur ){ pBt->pCursor = pCur->pNext; @@ -72194,9 +72194,9 @@ SQLITE_PRIVATE int tdsqlite3BtreeCloseCursor(BtCursor *pCur){ } btreeReleaseAllCursorPages(pCur); unlockBtreeIfUnused(pBt); - tdsqlite3_free(pCur->aOverflow); - tdsqlite3_free(pCur->pKey); - tdsqlite3BtreeLeave(pBtree); + sqlite3_free(pCur->aOverflow); + sqlite3_free(pCur->pKey); + sqlite3BtreeLeave(pBtree); pCur->pBtree = 0; } return SQLITE_OK; @@ -72243,11 +72243,11 @@ static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){ ** that is currently pointing to a row in a (non-empty) table. ** This is a verification routine is used only within assert() statements. */ -SQLITE_PRIVATE int tdsqlite3BtreeCursorIsValid(BtCursor *pCur){ +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){ return pCur && pCur->eState==CURSOR_VALID; } #endif /* NDEBUG */ -SQLITE_PRIVATE int tdsqlite3BtreeCursorIsValidNN(BtCursor *pCur){ +SQLITE_PRIVATE int sqlite3BtreeCursorIsValidNN(BtCursor *pCur){ assert( pCur!=0 ); return pCur->eState==CURSOR_VALID; } @@ -72258,7 +72258,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeCursorIsValidNN(BtCursor *pCur){ ** ordinary table btree. If the cursor points to an index btree or ** is invalid, the result of this routine is undefined. */ -SQLITE_PRIVATE i64 tdsqlite3BtreeIntegerKey(BtCursor *pCur){ +SQLITE_PRIVATE i64 sqlite3BtreeIntegerKey(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->curIntKey ); @@ -72269,11 +72269,11 @@ SQLITE_PRIVATE i64 tdsqlite3BtreeIntegerKey(BtCursor *pCur){ /* ** Pin or unpin a cursor. */ -SQLITE_PRIVATE void tdsqlite3BtreeCursorPin(BtCursor *pCur){ +SQLITE_PRIVATE void sqlite3BtreeCursorPin(BtCursor *pCur){ assert( (pCur->curFlags & BTCF_Pinned)==0 ); pCur->curFlags |= BTCF_Pinned; } -SQLITE_PRIVATE void tdsqlite3BtreeCursorUnpin(BtCursor *pCur){ +SQLITE_PRIVATE void sqlite3BtreeCursorUnpin(BtCursor *pCur){ assert( (pCur->curFlags & BTCF_Pinned)!=0 ); pCur->curFlags &= ~BTCF_Pinned; } @@ -72283,7 +72283,7 @@ SQLITE_PRIVATE void tdsqlite3BtreeCursorUnpin(BtCursor *pCur){ ** Return the offset into the database file for the start of the ** payload to which the cursor is pointing. */ -SQLITE_PRIVATE i64 tdsqlite3BtreeOffset(BtCursor *pCur){ +SQLITE_PRIVATE i64 sqlite3BtreeOffset(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); getCellInfo(pCur); @@ -72301,7 +72301,7 @@ SQLITE_PRIVATE i64 tdsqlite3BtreeOffset(BtCursor *pCur){ ** valid entry. In other words, the calling procedure must guarantee ** that the cursor has Cursor.eState==CURSOR_VALID. */ -SQLITE_PRIVATE u32 tdsqlite3BtreePayloadSize(BtCursor *pCur){ +SQLITE_PRIVATE u32 sqlite3BtreePayloadSize(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); getCellInfo(pCur); @@ -72321,10 +72321,10 @@ SQLITE_PRIVATE u32 tdsqlite3BtreePayloadSize(BtCursor *pCur){ ** The current implementation merely returns the size of the underlying ** database file. */ -SQLITE_PRIVATE tdsqlite3_int64 tdsqlite3BtreeMaxRecordSize(BtCursor *pCur){ +SQLITE_PRIVATE sqlite3_int64 sqlite3BtreeMaxRecordSize(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); - return pCur->pBt->pageSize * (tdsqlite3_int64)pCur->pBt->nPage; + return pCur->pBt->pageSize * (sqlite3_int64)pCur->pBt->nPage; } /* @@ -72356,7 +72356,7 @@ static int getOverflowPage( MemPage *pPage = 0; int rc = SQLITE_OK; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert(pPgnoNext); #ifndef SQLITE_OMIT_AUTOVACUUM @@ -72409,7 +72409,7 @@ static int getOverflowPage( ** pPayload is a pointer to data stored on database page pDbPage. ** If argument eOp is false, then nByte bytes of data are copied ** from pPayload to the buffer pointed at by pBuf. If eOp is true, -** then tdsqlite3PagerWrite() is called on pDbPage and nByte bytes +** then sqlite3PagerWrite() is called on pDbPage and nByte bytes ** of data are copied from the buffer pBuf to pPayload. ** ** SQLITE_OK is returned on success, otherwise an error code. @@ -72423,7 +72423,7 @@ static int copyPayload( ){ if( eOp ){ /* Copy data from buffer to page (a write operation) */ - int rc = tdsqlite3PagerWrite(pDbPage); + int rc = sqlite3PagerWrite(pDbPage); if( rc!=SQLITE_OK ){ return rc; } @@ -72531,9 +72531,9 @@ static int accessPayload( if( (pCur->curFlags & BTCF_ValidOvfl)==0 ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; if( pCur->aOverflow==0 - || nOvfl*(int)sizeof(Pgno) > tdsqlite3MallocSize(pCur->aOverflow) + || nOvfl*(int)sizeof(Pgno) > sqlite3MallocSize(pCur->aOverflow) ){ - Pgno *aNew = (Pgno*)tdsqlite3Realloc( + Pgno *aNew = (Pgno*)sqlite3Realloc( pCur->aOverflow, nOvfl*2*sizeof(Pgno) ); if( aNew==0 ){ @@ -72604,15 +72604,15 @@ static int accessPayload( */ if( eOp==0 /* (1) */ && offset==0 /* (2) */ - && tdsqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */ + && sqlite3PagerDirectReadOk(pBt->pPager, nextPage) /* (3,4,5) */ && &pBuf[-4]>=pBufStart /* (6) */ ){ - tdsqlite3_file *fd = tdsqlite3PagerFile(pBt->pPager); + sqlite3_file *fd = sqlite3PagerFile(pBt->pPager); u8 aSave[4]; u8 *aWrite = &pBuf[-4]; assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); - rc = tdsqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); + rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT; nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); @@ -72621,14 +72621,14 @@ static int accessPayload( { DbPage *pDbPage; - rc = tdsqlite3PagerGet(pBt->pPager, nextPage, &pDbPage, + rc = sqlite3PagerGet(pBt->pPager, nextPage, &pDbPage, (eOp==0 ? PAGER_GET_READONLY : 0) ); if( rc==SQLITE_OK ){ - aPayload = tdsqlite3PagerGetData(pDbPage); + aPayload = sqlite3PagerGetData(pDbPage); nextPage = get4byte(aPayload); rc = copyPayload(&aPayload[offset+4], pBuf, a, eOp, pDbPage); - tdsqlite3PagerUnref(pDbPage); + sqlite3PagerUnref(pDbPage); offset = 0; } } @@ -72657,15 +72657,15 @@ static int accessPayload( ** If pointing to a table btree, then the content section is read. If ** pCur is pointing to an index b-tree then the key section is read. ** -** For tdsqlite3BtreePayload(), the caller must ensure that pCur is pointing -** to a valid row in the table. For tdsqlite3BtreePayloadChecked(), the +** For sqlite3BtreePayload(), the caller must ensure that pCur is pointing +** to a valid row in the table. For sqlite3BtreePayloadChecked(), the ** cursor might be invalid or might need to be restored before being read. ** ** Return SQLITE_OK on success or an error code if anything goes ** wrong. An error is returned if "offset+amt" is larger than ** the available payload. */ -SQLITE_PRIVATE int tdsqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ +SQLITE_PRIVATE int sqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>=0 && pCur->pPage ); @@ -72674,8 +72674,8 @@ SQLITE_PRIVATE int tdsqlite3BtreePayload(BtCursor *pCur, u32 offset, u32 amt, vo } /* -** This variant of tdsqlite3BtreePayload() works even if the cursor has not -** in the CURSOR_VALID state. It is only used by the tdsqlite3_blob_read() +** This variant of sqlite3BtreePayload() works even if the cursor has not +** in the CURSOR_VALID state. It is only used by the sqlite3_blob_read() ** interface. */ #ifndef SQLITE_OMIT_INCRBLOB @@ -72693,7 +72693,7 @@ static SQLITE_NOINLINE int accessPayloadChecked( rc = btreeRestoreCursorPosition(pCur); return rc ? rc : accessPayload(pCur, offset, amt, pBuf, 0); } -SQLITE_PRIVATE int tdsqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ +SQLITE_PRIVATE int sqlite3BtreePayloadChecked(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ if( pCur->eState==CURSOR_VALID ){ assert( cursorOwnsBtShared(pCur) ); return accessPayload(pCur, offset, amt, pBuf, 0); @@ -72729,7 +72729,7 @@ static const void *fetchPayload( int amt; assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage); assert( pCur->eState==CURSOR_VALID ); - assert( tdsqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorOwnsBtShared(pCur) ); assert( pCur->ixpPage->nCell ); assert( pCur->info.nSize>0 ); @@ -72761,7 +72761,7 @@ static const void *fetchPayload( ** These routines is used to get quick access to key and data ** in the common case where no overflow pages are used. */ -SQLITE_PRIVATE const void *tdsqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ +SQLITE_PRIVATE const void *sqlite3BtreePayloadFetch(BtCursor *pCur, u32 *pAmt){ return fetchPayload(pCur, pAmt); } @@ -72895,7 +72895,7 @@ static int moveToRoot(BtCursor *pCur){ assert( pCur->skipNext!=SQLITE_OK ); return pCur->skipNext; } - tdsqlite3BtreeClearCursor(pCur); + sqlite3BtreeClearCursor(pCur); } rc = getAndInitPage(pCur->pBtree->pBt, pCur->pgnoRoot, &pCur->pPage, 0, pCur->curPagerFlags); @@ -73000,11 +73000,11 @@ static int moveToRightmost(BtCursor *pCur){ ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. */ -SQLITE_PRIVATE int tdsqlite3BtreeFirst(BtCursor *pCur, int *pRes){ +SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor *pCur, int *pRes){ int rc; assert( cursorOwnsBtShared(pCur) ); - assert( tdsqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); rc = moveToRoot(pCur); if( rc==SQLITE_OK ){ assert( pCur->pPage->nCell>0 ); @@ -73022,11 +73022,11 @@ SQLITE_PRIVATE int tdsqlite3BtreeFirst(BtCursor *pCur, int *pRes){ ** on success. Set *pRes to 0 if the cursor actually points to something ** or set *pRes to 1 if the table is empty. */ -SQLITE_PRIVATE int tdsqlite3BtreeLast(BtCursor *pCur, int *pRes){ +SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor *pCur, int *pRes){ int rc; assert( cursorOwnsBtShared(pCur) ); - assert( tdsqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); /* If the cursor already points to the last entry, this is a no-op. */ if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ @@ -73092,7 +73092,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeLast(BtCursor *pCur, int *pRes){ ** For index tables, the pIdxKey->eqSeen field is set to 1 if there ** exists an entry in the table that exactly matches pIdxKey. */ -SQLITE_PRIVATE int tdsqlite3BtreeMovetoUnpacked( +SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( BtCursor *pCur, /* The cursor to be moved */ UnpackedRecord *pIdxKey, /* Unpacked index key */ i64 intKey, /* The table key */ @@ -73103,7 +73103,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeMovetoUnpacked( RecordCompare xRecordCompare; assert( cursorOwnsBtShared(pCur) ); - assert( tdsqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( pRes ); assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); assert( pCur->eState!=CURSOR_VALID || (pIdxKey==0)==(pCur->curIntKey!=0) ); @@ -73123,12 +73123,12 @@ SQLITE_PRIVATE int tdsqlite3BtreeMovetoUnpacked( return SQLITE_OK; } /* If the requested key is one more than the previous key, then - ** try to get there using tdsqlite3BtreeNext() rather than a full + ** try to get there using sqlite3BtreeNext() rather than a full ** binary search. This is an optimization only. The correct answer ** is still obtained without this case, only a little more slowely */ if( pCur->info.nKey+1==intKey ){ *pRes = 0; - rc = tdsqlite3BtreeNext(pCur, 0); + rc = sqlite3BtreeNext(pCur, 0); if( rc==SQLITE_OK ){ getCellInfo(pCur); if( pCur->info.nKey==intKey ){ @@ -73144,7 +73144,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeMovetoUnpacked( } if( pIdxKey ){ - xRecordCompare = tdsqlite3VdbeFindCompare(pIdxKey); + xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); pIdxKey->errCode = 0; assert( pIdxKey->default_rc==1 || pIdxKey->default_rc==0 @@ -73273,7 +73273,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeMovetoUnpacked( rc = SQLITE_CORRUPT_PAGE(pPage); goto moveto_finish; } - pCellKey = tdsqlite3Malloc( nCell+nOverrun ); + pCellKey = sqlite3Malloc( nCell+nOverrun ); if( pCellKey==0 ){ rc = SQLITE_NOMEM_BKPT; goto moveto_finish; @@ -73283,11 +73283,11 @@ SQLITE_PRIVATE int tdsqlite3BtreeMovetoUnpacked( memset(((u8*)pCellKey)+nCell,0,nOverrun); /* Fix uninit warnings */ pCur->curFlags &= ~BTCF_ValidOvfl; if( rc ){ - tdsqlite3_free(pCellKey); + sqlite3_free(pCellKey); goto moveto_finish; } - c = tdsqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); - tdsqlite3_free(pCellKey); + c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); + sqlite3_free(pCellKey); } assert( (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) @@ -73339,11 +73339,11 @@ moveto_finish: /* ** Return TRUE if the cursor is not pointing at an entry of the table. ** -** TRUE will be returned after a call to tdsqlite3BtreeNext() moves -** past the last entry in the table or tdsqlite3BtreePrev() moves past +** TRUE will be returned after a call to sqlite3BtreeNext() moves +** past the last entry in the table or sqlite3BtreePrev() moves past ** the first entry. TRUE is also returned if the table is empty. */ -SQLITE_PRIVATE int tdsqlite3BtreeEof(BtCursor *pCur){ +SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor *pCur){ /* TODO: What if the cursor is in CURSOR_REQUIRESEEK but all table entries ** have been deleted? This API will need to change to return an error code ** as well as the boolean result value. @@ -73356,12 +73356,12 @@ SQLITE_PRIVATE int tdsqlite3BtreeEof(BtCursor *pCur){ ** pointing to. Return a negative number if no estimate is currently ** available. */ -SQLITE_PRIVATE i64 tdsqlite3BtreeRowCountEst(BtCursor *pCur){ +SQLITE_PRIVATE i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ i64 n; u8 i; assert( cursorOwnsBtShared(pCur) ); - assert( tdsqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); /* Currently this interface is only called by the OP_IfSmaller ** opcode, and it that case the cursor will always be valid and @@ -73384,13 +73384,13 @@ SQLITE_PRIVATE i64 tdsqlite3BtreeRowCountEst(BtCursor *pCur){ ** SQLITE_DONE cursor is already pointing at the last element ** otherwise some kind of error occurred ** -** The main entry point is tdsqlite3BtreeNext(). That routine is optimized +** The main entry point is sqlite3BtreeNext(). That routine is optimized ** for the common case of merely incrementing the cell counter BtCursor.aiIdx ** to the next cell on the current page. The (slower) btreeNext() helper ** routine is called when it is necessary to move to a different page or ** to restore the cursor. ** -** If bit 0x01 of the F argument in tdsqlite3BtreeNext(C,F) is 1, then the +** If bit 0x01 of the F argument in sqlite3BtreeNext(C,F) is 1, then the ** cursor corresponds to an SQL index and this routine could have been ** skipped if the SQL index had been a unique index. The F argument ** is a hint to the implement. SQLite btree implementation does not use @@ -73455,7 +73455,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ pPage = pCur->pPage; }while( pCur->ix>=pPage->nCell ); if( pPage->intKey ){ - return tdsqlite3BtreeNext(pCur, 0); + return sqlite3BtreeNext(pCur, 0); }else{ return SQLITE_OK; } @@ -73466,7 +73466,7 @@ static SQLITE_NOINLINE int btreeNext(BtCursor *pCur){ return moveToLeftmost(pCur); } } -SQLITE_PRIVATE int tdsqlite3BtreeNext(BtCursor *pCur, int flags){ +SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int flags){ MemPage *pPage; UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ assert( cursorOwnsBtShared(pCur) ); @@ -73494,13 +73494,13 @@ SQLITE_PRIVATE int tdsqlite3BtreeNext(BtCursor *pCur, int flags){ ** SQLITE_DONE the cursor is already on the first element of the table ** otherwise some kind of error occurred ** -** The main entry point is tdsqlite3BtreePrevious(). That routine is optimized +** The main entry point is sqlite3BtreePrevious(). That routine is optimized ** for the common case of merely decrementing the cell counter BtCursor.aiIdx ** to the previous cell on the current page. The (slower) btreePrevious() ** helper routine is called when it is necessary to move to a different page ** or to restore the cursor. ** -** If bit 0x01 of the F argument to tdsqlite3BtreePrevious(C,F) is 1, then +** If bit 0x01 of the F argument to sqlite3BtreePrevious(C,F) is 1, then ** the cursor corresponds to an SQL index and this routine could have been ** skipped if the SQL index had been a unique index. The F argument is a ** hint to the implement. The native SQLite btree implementation does not @@ -73548,14 +73548,14 @@ static SQLITE_NOINLINE int btreePrevious(BtCursor *pCur){ pCur->ix--; pPage = pCur->pPage; if( pPage->intKey && !pPage->leaf ){ - rc = tdsqlite3BtreePrevious(pCur, 0); + rc = sqlite3BtreePrevious(pCur, 0); }else{ rc = SQLITE_OK; } } return rc; } -SQLITE_PRIVATE int tdsqlite3BtreePrevious(BtCursor *pCur, int flags){ +SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int flags){ assert( cursorOwnsBtShared(pCur) ); assert( flags==0 || flags==1 ); UNUSED_PARAMETER( flags ); /* Used in COMDB2 but not native SQLite */ @@ -73574,10 +73574,10 @@ SQLITE_PRIVATE int tdsqlite3BtreePrevious(BtCursor *pCur, int flags){ /* ** Allocate a new page from the database file. ** -** The new page is marked as dirty. (In other words, tdsqlite3PagerWrite() +** The new page is marked as dirty. (In other words, sqlite3PagerWrite() ** has already been called on the new page.) The new page has also ** been referenced and the calling routine is responsible for calling -** tdsqlite3PagerUnref() on the new page when it is done. +** sqlite3PagerUnref() on the new page when it is done. ** ** SQLITE_OK is returned on success. Any other return value indicates ** an error. *ppPage is set to NULL in the event of an error. @@ -73608,7 +73608,7 @@ static int allocateBtreePage( MemPage *pPrevTrunk = 0; Pgno mxPage; /* Total size of the database file */ - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( eMode==BTALLOC_ANY || (nearby>0 && IfNotOmitAV(pBt->autoVacuum)) ); pPage1 = pBt->pPage1; mxPage = btreePagecount(pBt); @@ -73649,7 +73649,7 @@ static int allocateBtreePage( /* Decrement the free-list count by 1. Set iTrunk to the index of the ** first free-list trunk page. iPrevTrunk is initially 1. */ - rc = tdsqlite3PagerWrite(pPage1->pDbPage); + rc = sqlite3PagerWrite(pPage1->pDbPage); if( rc ) return rc; put4byte(&pPage1->aData[36], n-1); @@ -73691,7 +73691,7 @@ static int allocateBtreePage( ** So extract the trunk page itself and use it as the newly ** allocated page */ assert( pPrevTrunk==0 ); - rc = tdsqlite3PagerWrite(pTrunk->pDbPage); + rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ){ goto end_allocate_page; } @@ -73714,7 +73714,7 @@ static int allocateBtreePage( *pPgno = iTrunk; *ppPage = pTrunk; searchList = 0; - rc = tdsqlite3PagerWrite(pTrunk->pDbPage); + rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ){ goto end_allocate_page; } @@ -73722,7 +73722,7 @@ static int allocateBtreePage( if( !pPrevTrunk ){ memcpy(&pPage1->aData[32], &pTrunk->aData[0], 4); }else{ - rc = tdsqlite3PagerWrite(pPrevTrunk->pDbPage); + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); if( rc!=SQLITE_OK ){ goto end_allocate_page; } @@ -73744,7 +73744,7 @@ static int allocateBtreePage( if( rc!=SQLITE_OK ){ goto end_allocate_page; } - rc = tdsqlite3PagerWrite(pNewTrunk->pDbPage); + rc = sqlite3PagerWrite(pNewTrunk->pDbPage); if( rc!=SQLITE_OK ){ releasePage(pNewTrunk); goto end_allocate_page; @@ -73754,10 +73754,10 @@ static int allocateBtreePage( memcpy(&pNewTrunk->aData[8], &pTrunk->aData[12], (k-1)*4); releasePage(pNewTrunk); if( !pPrevTrunk ){ - assert( tdsqlite3PagerIswriteable(pPage1->pDbPage) ); + assert( sqlite3PagerIswriteable(pPage1->pDbPage) ); put4byte(&pPage1->aData[32], iNewTrunk); }else{ - rc = tdsqlite3PagerWrite(pPrevTrunk->pDbPage); + rc = sqlite3PagerWrite(pPrevTrunk->pDbPage); if( rc ){ goto end_allocate_page; } @@ -73785,9 +73785,9 @@ static int allocateBtreePage( } }else{ int dist; - dist = tdsqlite3AbsInt32(get4byte(&aData[8]) - nearby); + dist = sqlite3AbsInt32(get4byte(&aData[8]) - nearby); for(i=1; ipgno, n-1)); - rc = tdsqlite3PagerWrite(pTrunk->pDbPage); + rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc ) goto end_allocate_page; if( closestpDbPage); + rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ releasePage(*ppPage); *ppPage = 0; @@ -73855,7 +73855,7 @@ static int allocateBtreePage( */ int bNoContent = (0==IfNotOmitAV(pBt->bDoTruncate))? PAGER_GET_NOCONTENT:0; - rc = tdsqlite3PagerWrite(pBt->pPage1->pDbPage); + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc ) return rc; pBt->nPage++; if( pBt->nPage==PENDING_BYTE_PAGE(pBt) ) pBt->nPage++; @@ -73871,7 +73871,7 @@ static int allocateBtreePage( assert( pBt->nPage!=PENDING_BYTE_PAGE(pBt) ); rc = btreeGetUnusedPage(pBt, pBt->nPage, &pPg, bNoContent); if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerWrite(pPg->pDbPage); + rc = sqlite3PagerWrite(pPg->pDbPage); releasePage(pPg); } if( rc ) return rc; @@ -73885,7 +73885,7 @@ static int allocateBtreePage( assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); rc = btreeGetUnusedPage(pBt, *pPgno, ppPage, bNoContent); if( rc ) return rc; - rc = tdsqlite3PagerWrite((*ppPage)->pDbPage); + rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ releasePage(*ppPage); *ppPage = 0; @@ -73898,7 +73898,7 @@ static int allocateBtreePage( end_allocate_page: releasePage(pTrunk); releasePage(pPrevTrunk); - assert( rc!=SQLITE_OK || tdsqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 ); + assert( rc!=SQLITE_OK || sqlite3PagerPageRefcount((*ppPage)->pDbPage)<=1 ); assert( rc!=SQLITE_OK || (*ppPage)->isInit==0 ); return rc; } @@ -73923,7 +73923,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ int rc; /* Return Code */ u32 nFree; /* Initial number of pages on free-list */ - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); assert( CORRUPT_DB || iPage>1 ); assert( !pMemPage || pMemPage->pgno==iPage ); @@ -73932,13 +73932,13 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ } if( pMemPage ){ pPage = pMemPage; - tdsqlite3PagerRef(pPage->pDbPage); + sqlite3PagerRef(pPage->pDbPage); }else{ pPage = btreePageLookup(pBt, iPage); } /* Increment the free page count on pPage1 */ - rc = tdsqlite3PagerWrite(pPage1->pDbPage); + rc = sqlite3PagerWrite(pPage1->pDbPage); if( rc ) goto freepage_out; nFree = get4byte(&pPage1->aData[36]); put4byte(&pPage1->aData[36], nFree+1); @@ -73948,7 +73948,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ ** always fully overwrite deleted information with zeros. */ if( (!pPage && ((rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0) ) - || ((rc = tdsqlite3PagerWrite(pPage->pDbPage))!=0) + || ((rc = sqlite3PagerWrite(pPage->pDbPage))!=0) ){ goto freepage_out; } @@ -74005,12 +74005,12 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ ** order that database files created by newer versions of SQLite can be ** read by older versions of SQLite. */ - rc = tdsqlite3PagerWrite(pTrunk->pDbPage); + rc = sqlite3PagerWrite(pTrunk->pDbPage); if( rc==SQLITE_OK ){ put4byte(&pTrunk->aData[4], nLeaf+1); put4byte(&pTrunk->aData[8+nLeaf*4], iPage); if( pPage && (pBt->btsFlags & BTS_SECURE_DELETE)==0 ){ - tdsqlite3PagerDontWrite(pPage->pDbPage); + sqlite3PagerDontWrite(pPage->pDbPage); } rc = btreeSetHasContent(pBt, iPage); } @@ -74028,7 +74028,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ goto freepage_out; } - rc = tdsqlite3PagerWrite(pPage->pDbPage); + rc = sqlite3PagerWrite(pPage->pDbPage); if( rc!=SQLITE_OK ){ goto freepage_out; } @@ -74066,7 +74066,7 @@ static int clearCell( int nOvfl; u32 ovflPageSize; - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); pPage->xParseCell(pPage, pCell, pInfo); if( pInfo->nLocal==pInfo->nPayload ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ @@ -74100,7 +74100,7 @@ static int clearCell( } if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) - && tdsqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 + && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 ){ /* There is no reason any cursor should have an outstanding reference ** to an overflow page belonging to a cell that is being deleted/updated. @@ -74118,7 +74118,7 @@ static int clearCell( } if( pOvfl ){ - tdsqlite3PagerUnref(pOvfl->pDbPage); + sqlite3PagerUnref(pOvfl->pDbPage); } if( rc ) return rc; ovflPgno = iNext; @@ -74155,12 +74155,12 @@ static int fillInCell( Pgno pgnoOvfl; int nHeader; - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); /* pPage is not necessarily writeable since pCell might be auxiliary ** buffer space that is separate from the pPage buffer area */ assert( pCellaData || pCell>=&pPage->aData[pPage->pBt->pageSize] - || tdsqlite3PagerIswriteable(pPage->pDbPage) ); + || sqlite3PagerIswriteable(pPage->pDbPage) ); /* Fill in the header. */ nHeader = pPage->childPtrSize; @@ -74240,12 +74240,12 @@ static int fillInCell( /* If pToRelease is not zero than pPayload points into the data area ** of pToRelease. Make sure pToRelease is still writeable. */ - assert( pToRelease==0 || tdsqlite3PagerIswriteable(pToRelease->pDbPage) ); + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); /* If pPayload is part of the data area of pPage, then make sure pPage ** is still writeable */ assert( pPayloadaData || pPayload>=&pPage->aData[pBt->pageSize] - || tdsqlite3PagerIswriteable(pPage->pDbPage) ); + || sqlite3PagerIswriteable(pPage->pDbPage) ); if( nSrc>=n ){ memcpy(pPayload, pSrc, n); @@ -74300,12 +74300,12 @@ static int fillInCell( /* If pToRelease is not zero than pPrior points into the data area ** of pToRelease. Make sure pToRelease is still writeable. */ - assert( pToRelease==0 || tdsqlite3PagerIswriteable(pToRelease->pDbPage) ); + assert( pToRelease==0 || sqlite3PagerIswriteable(pToRelease->pDbPage) ); /* If pPrior is part of the data area of pPage, then make sure pPage ** is still writeable */ assert( pPrioraData || pPrior>=&pPage->aData[pBt->pageSize] - || tdsqlite3PagerIswriteable(pPage->pDbPage) ); + || sqlite3PagerIswriteable(pPage->pDbPage) ); put4byte(pPrior, pgnoOvfl); releasePage(pToRelease); @@ -74338,8 +74338,8 @@ static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ if( *pRC ) return; assert( idx>=0 && idxnCell ); assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); - assert( tdsqlite3PagerIswriteable(pPage->pDbPage) ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( pPage->nFree>=0 ); data = pPage->aData; ptr = &pPage->aCellIdx[2*idx]; @@ -74404,7 +74404,7 @@ static void insertCell( assert( pPage->nCell<=MX_CELL(pPage->pBt) || CORRUPT_DB ); assert( pPage->nOverflow<=ArraySize(pPage->apOvfl) ); assert( ArraySize(pPage->apOvfl)==ArraySize(pPage->aiOvfl) ); - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sz==pPage->xCellSize(pPage, pCell) || CORRUPT_DB ); assert( pPage->nFree>=0 ); if( pPage->nOverflow || sz+2>pPage->nFree ){ @@ -74431,12 +74431,12 @@ static void insertCell( assert( j==0 || pPage->aiOvfl[j-1]<(u16)i ); /* Overflows in sorted order */ assert( j==0 || i==pPage->aiOvfl[j-1]+1 ); /* Overflows are sequential */ }else{ - int rc = tdsqlite3PagerWrite(pPage->pDbPage); + int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc!=SQLITE_OK ){ *pRC = rc; return; } - assert( tdsqlite3PagerIswriteable(pPage->pDbPage) ); + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); data = pPage->aData; assert( &data[pPage->cellOffset]==pPage->aCellIdx ); rc = allocateSpace(pPage, sz, &idx); @@ -74630,7 +74630,7 @@ static int rebuildPage( u32 j; /* Start of cell content area */ int iEnd = i+nCell; /* Loop terminator */ u8 *pCellptr = pPg->aCellIdx; - u8 *pTmp = tdsqlite3PagerTempSpace(pPg->pBt->pPager); + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); u8 *pData; int k; /* Current slot in pCArray->apEnd[] */ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ @@ -74847,7 +74847,7 @@ static int editPage( int iNewEnd = iNew + nNew; #ifdef SQLITE_DEBUG - u8 *pTmp = tdsqlite3PagerTempSpace(pPg->pBt->pPager); + u8 *pTmp = sqlite3PagerTempSpace(pPg->pBt->pPager); memcpy(pTmp, aData, pPg->pBt->usableSize); #endif @@ -74963,8 +74963,8 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ int rc; /* Return Code */ Pgno pgnoNew; /* Page number of pNew */ - assert( tdsqlite3_mutex_held(pPage->pBt->mutex) ); - assert( tdsqlite3PagerIswriteable(pParent->pDbPage) ); + assert( sqlite3_mutex_held(pPage->pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); assert( pPage->nOverflow==1 ); if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* dbfuzz001.test */ @@ -74985,7 +74985,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ u8 *pStop; CellArray b; - assert( tdsqlite3PagerIswriteable(pNew->pDbPage) ); + assert( sqlite3PagerIswriteable(pNew->pDbPage) ); assert( CORRUPT_DB || pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); b.nCell = 1; @@ -75234,13 +75234,13 @@ static int balance_nonroot( b.nCell = 0; b.apCell = 0; pBt = pParent->pBt; - assert( tdsqlite3_mutex_held(pBt->mutex) ); - assert( tdsqlite3PagerIswriteable(pParent->pDbPage) ); + assert( sqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); /* At this point pParent may have at most one overflow cell. And if ** this overflow cell is present, it must be the cell with ** index iParentIdx. This scenario comes about when this function - ** is called (indirectly) from tdsqlite3BtreeDelete(). + ** is called (indirectly) from sqlite3BtreeDelete(). */ assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); assert( pParent->nOverflow==0 || pParent->aiOvfl[0]==iParentIdx ); @@ -75350,7 +75350,7 @@ static int balance_nonroot( + pBt->pageSize; /* aSpace1 */ assert( szScratch<=7*(int)pBt->pageSize ); - b.apCell = tdsqlite3StackAllocRaw(0, szScratch ); + b.apCell = sqlite3StackAllocRaw(0, szScratch ); if( b.apCell==0 ){ rc = SQLITE_NOMEM_BKPT; goto balance_cleanup; @@ -75619,7 +75619,7 @@ static int balance_nonroot( if( ipDbPage); + rc = sqlite3PagerWrite(pNew->pDbPage); nNew++; if( rc ) goto balance_cleanup; }else{ @@ -75679,9 +75679,9 @@ static int balance_nonroot( aPgOrder[iBest] = 0xffffffff; if( iBest!=i ){ if( iBest>i ){ - tdsqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0); + sqlite3PagerRekey(apNew[iBest]->pDbPage, pBt->nPage+iBest+1, 0); } - tdsqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]); + sqlite3PagerRekey(apNew[i]->pDbPage, pgno, aPgFlags[iBest]); apNew[i]->pgno = pgno; } } @@ -75699,7 +75699,7 @@ static int balance_nonroot( nNew>=5 ? cntNew[4] - cntNew[3] - !leafData : 0 )); - assert( tdsqlite3PagerIswriteable(pParent->pDbPage) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); assert( nNew>=1 && nNew<=ArraySize(apNew) ); assert( apNew[nNew-1]!=0 ); put4byte(pRight, apNew[nNew-1]->pgno); @@ -75820,7 +75820,7 @@ static int balance_nonroot( assert( iOvflSpace <= (int)pBt->pageSize ); insertCell(pParent, nxDiv+i, pCell, sz, pTemp, pNew->pgno, &rc); if( rc!=SQLITE_OK ) goto balance_cleanup; - assert( tdsqlite3PagerIswriteable(pParent->pDbPage) ); + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); } /* Now update the actual sibling pages. The order in which they are updated @@ -75949,7 +75949,7 @@ static int balance_nonroot( ** Cleanup before returning. */ balance_cleanup: - tdsqlite3StackFree(0, b.apCell); + sqlite3StackFree(0, b.apCell); for(i=0; ipBt; /* The BTree */ assert( pRoot->nOverflow>0 ); - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); /* Make pRoot, the root page of the b-tree, writable. Allocate a new ** page that will become the new right-child of pPage. Copy the contents ** of the node stored on pRoot into the new child page. */ - rc = tdsqlite3PagerWrite(pRoot->pDbPage); + rc = sqlite3PagerWrite(pRoot->pDbPage); if( rc==SQLITE_OK ){ rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); copyNodeContent(pRoot, pChild, &rc); @@ -76006,8 +76006,8 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ releasePage(pChild); return rc; } - assert( tdsqlite3PagerIswriteable(pChild->pDbPage) ); - assert( tdsqlite3PagerIswriteable(pRoot->pDbPage) ); + assert( sqlite3PagerIswriteable(pChild->pDbPage) ); + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); assert( pChild->nCell==pRoot->nCell || CORRUPT_DB ); TRACE(("BALANCE: copy root %d into %d\n", pRoot->pgno, pChild->pgno)); @@ -76102,7 +76102,7 @@ static int balance(BtCursor *pCur){ MemPage * const pParent = pCur->apPage[iPage-1]; int const iIdx = pCur->aiIdx[iPage-1]; - rc = tdsqlite3PagerWrite(pParent->pDbPage); + rc = sqlite3PagerWrite(pParent->pDbPage); if( rc==SQLITE_OK && pParent->nFree<0 ){ rc = btreeComputeFreeSpace(pParent); } @@ -76150,7 +76150,7 @@ static int balance(BtCursor *pCur){ ** copied either into the body of a database page or into the new ** pSpace buffer passed to the latter call to balance_nonroot(). */ - u8 *pSpace = tdsqlite3PageMalloc(pCur->pBt->pageSize); + u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints&BTREE_BULKLOAD); if( pFree ){ @@ -76158,7 +76158,7 @@ static int balance(BtCursor *pCur){ ** by a previous call to balance_nonroot(). Its contents are ** now stored either on real database pages or within the ** new pSpace buffer, so it may be safely freed here. */ - tdsqlite3PageFree(pFree); + sqlite3PageFree(pFree); } /* The pSpace buffer will be freed after the next call to @@ -76179,7 +76179,7 @@ static int balance(BtCursor *pCur){ }while( rc==SQLITE_OK ); if( pFree ){ - tdsqlite3PageFree(pFree); + sqlite3PageFree(pFree); } return rc; } @@ -76200,7 +76200,7 @@ static int btreeOverwriteContent( int i; for(i=0; ipDbPage); + int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; memset(pDest + i, 0, iAmt - i); } @@ -76214,7 +76214,7 @@ static int btreeOverwriteContent( iAmt = nData; } if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){ - int rc = tdsqlite3PagerWrite(pPage->pDbPage); + int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; /* In a corrupt database, it is possible for the source and destination ** buffers to overlap. This is harmless since the database is already @@ -76260,7 +76260,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ do{ rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); if( rc ) return rc; - if( tdsqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){ + if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){ rc = SQLITE_CORRUPT_BKPT; }else{ if( iOffset+ovflPageSize<(u32)nTotal ){ @@ -76271,7 +76271,7 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ rc = btreeOverwriteContent(pPage, pPage->aData+4, pX, iOffset, ovflPageSize); } - tdsqlite3PagerUnref(pPage->pDbPage); + sqlite3PagerUnref(pPage->pDbPage); if( rc ) return rc; iOffset += ovflPageSize; }while( iOffsetaMem can be used instead of pX->pKey to avoid having ** to decode the key. */ -SQLITE_PRIVATE int tdsqlite3BtreeInsert( +SQLITE_PRIVATE int sqlite3BtreeInsert( BtCursor *pCur, /* Insert data into the table of this cursor */ const BtreePayload *pX, /* Content of the row to be inserted */ int flags, /* True if this is likely an append */ @@ -76349,7 +76349,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeInsert( ** ** In some cases, the call to btreeMoveto() below is a no-op. For ** example, when inserting data into a table with auto-generated integer - ** keys, the VDBE layer invokes tdsqlite3BtreeLast() to figure out the + ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the ** integer key to use. It then calls this function to actually insert the ** data into the intkey B-Tree. In this case btreeMoveto() recognizes ** that the cursor is already where it needs to be and returns without @@ -76398,7 +76398,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeInsert( ** to an adjacent cell. Move the cursor so that it is pointing either ** to the cell to be overwritten or an adjacent cell. */ - rc = tdsqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); + rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } }else{ @@ -76425,7 +76425,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeInsert( r.r1 = 0; r.r2 = 0; r.eqSeen = 0; - rc = tdsqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); + rc = sqlite3BtreeMovetoUnpacked(pCur, &r, 0, flags!=0, &loc); }else{ rc = btreeMoveto(pCur, pX->pKey, pX->nKey, flags!=0, &loc); } @@ -76474,7 +76474,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeInsert( if( loc==0 ){ CellInfo info; assert( idxnCell ); - rc = tdsqlite3PagerWrite(pPage->pDbPage); + rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ){ goto end_insert; } @@ -76556,7 +76556,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeInsert( btreeReleaseAllCursorPages(pCur); if( pCur->pKeyInfo ){ assert( pCur->pKey==0 ); - pCur->pKey = tdsqlite3Malloc( pX->nKey ); + pCur->pKey = sqlite3Malloc( pX->nKey ); if( pCur->pKey==0 ){ rc = SQLITE_NOMEM; }else{ @@ -76590,7 +76590,7 @@ end_insert: ** The BTREE_AUXDELETE bit is a hint that is not used by this implementation, ** but which might be used by alternative storage engines. */ -SQLITE_PRIVATE int tdsqlite3BtreeDelete(BtCursor *pCur, u8 flags){ +SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ Btree *p = pCur->pBtree; BtShared *pBt = p->pBt; int rc; /* Return code */ @@ -76652,7 +76652,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeDelete(BtCursor *pCur, u8 flags){ ** sub-tree headed by the child page of the cell being deleted. This makes ** balancing the tree following the delete operation easier. */ if( !pPage->leaf ){ - rc = tdsqlite3BtreePrevious(pCur, 0); + rc = sqlite3BtreePrevious(pCur, 0); assert( rc!=SQLITE_DONE ); if( rc ) return rc; } @@ -76673,7 +76673,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeDelete(BtCursor *pCur, u8 flags){ /* Make the page containing the entry to be deleted writable. Then free any ** overflow pages associated with the entry and finally remove the cell ** itself from within the page. */ - rc = tdsqlite3PagerWrite(pPage->pDbPage); + rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; rc = clearCell(pPage, pCell, &info); dropCell(pPage, iCellIdx, info.nSize, &rc); @@ -76705,7 +76705,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeDelete(BtCursor *pCur, u8 flags){ assert( MX_CELL_SIZE(pBt) >= nCell ); pTmp = pBt->pTmpSpace; assert( pTmp!=0 ); - rc = tdsqlite3PagerWrite(pLeaf->pDbPage); + rc = sqlite3PagerWrite(pLeaf->pDbPage); if( rc==SQLITE_OK ){ insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); } @@ -76781,7 +76781,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ int rc; int ptfFlags; /* Page-type flage for the root page of new table */ - assert( tdsqlite3BtreeHoldsMutex(p) ); + assert( sqlite3BtreeHoldsMutex(p) ); assert( pBt->inTransaction==TRANS_WRITE ); assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); @@ -76806,7 +76806,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ ** root page of the new table should go. meta[3] is the largest root-page ** created so far, so the new root-page is (meta[3]+1). */ - tdsqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); pgnoRoot++; /* The new root-page may not be allocated on a pointer-map page, or the @@ -76873,7 +76873,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ if( rc!=SQLITE_OK ){ return rc; } - rc = tdsqlite3PagerWrite(pRoot->pDbPage); + rc = sqlite3PagerWrite(pRoot->pDbPage); if( rc!=SQLITE_OK ){ releasePage(pRoot); return rc; @@ -76891,10 +76891,10 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ /* When the new root page was allocated, page 1 was made writable in ** order either to increase the database filesize, or to decrement the - ** freelist count. Hence, the tdsqlite3BtreeUpdateMeta() call cannot fail. + ** freelist count. Hence, the sqlite3BtreeUpdateMeta() call cannot fail. */ - assert( tdsqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); - rc = tdsqlite3BtreeUpdateMeta(p, 4, pgnoRoot); + assert( sqlite3PagerIswriteable(pBt->pPage1->pDbPage) ); + rc = sqlite3BtreeUpdateMeta(p, 4, pgnoRoot); if( NEVER(rc) ){ releasePage(pRoot); return rc; @@ -76905,23 +76905,23 @@ static int btreeCreateTable(Btree *p, int *piTable, int createTabFlags){ if( rc ) return rc; } #endif - assert( tdsqlite3PagerIswriteable(pRoot->pDbPage) ); + assert( sqlite3PagerIswriteable(pRoot->pDbPage) ); if( createTabFlags & BTREE_INTKEY ){ ptfFlags = PTF_INTKEY | PTF_LEAFDATA | PTF_LEAF; }else{ ptfFlags = PTF_ZERODATA | PTF_LEAF; } zeroPage(pRoot, ptfFlags); - tdsqlite3PagerUnref(pRoot->pDbPage); + sqlite3PagerUnref(pRoot->pDbPage); assert( (pBt->openFlags & BTREE_SINGLE)==0 || pgnoRoot==2 ); *piTable = (int)pgnoRoot; return SQLITE_OK; } -SQLITE_PRIVATE int tdsqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ +SQLITE_PRIVATE int sqlite3BtreeCreateTable(Btree *p, int *piTable, int flags){ int rc; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); rc = btreeCreateTable(p, piTable, flags); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -76942,7 +76942,7 @@ static int clearDatabasePage( int hdr; CellInfo info; - assert( tdsqlite3_mutex_held(pBt->mutex) ); + assert( sqlite3_mutex_held(pBt->mutex) ); if( pgno>btreePagecount(pBt) ){ return SQLITE_CORRUPT_BKPT; } @@ -76973,7 +76973,7 @@ static int clearDatabasePage( } if( freePageFlag ){ freePage(pPage, &rc); - }else if( (rc = tdsqlite3PagerWrite(pPage->pDbPage))==0 ){ + }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ zeroPage(pPage, pPage->aData[hdr] | PTF_LEAF); } @@ -76996,10 +76996,10 @@ cleardatabasepage_out: ** integer value pointed to by pnChange is incremented by the number of ** entries in the table. */ -SQLITE_PRIVATE int tdsqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ +SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ int rc; BtShared *pBt = p->pBt; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); rc = saveAllCursors(pBt, (Pgno)iTable, 0); @@ -77011,7 +77011,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange) invalidateIncrblobCursors(p, (Pgno)iTable, 0, 1); rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -77020,8 +77020,8 @@ SQLITE_PRIVATE int tdsqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange) ** ** This routine only work for pCur on an ephemeral table. */ -SQLITE_PRIVATE int tdsqlite3BtreeClearTableOfCursor(BtCursor *pCur){ - return tdsqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0); +SQLITE_PRIVATE int sqlite3BtreeClearTableOfCursor(BtCursor *pCur){ + return sqlite3BtreeClearTable(pCur->pBtree, pCur->pgnoRoot, 0); } /* @@ -77049,7 +77049,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ MemPage *pPage = 0; BtShared *pBt = p->pBt; - assert( tdsqlite3BtreeHoldsMutex(p) ); + assert( sqlite3BtreeHoldsMutex(p) ); assert( p->inTrans==TRANS_WRITE ); assert( iTable>=2 ); if( iTable>btreePagecount(pBt) ){ @@ -77058,7 +77058,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); if( rc ) return rc; - rc = tdsqlite3BtreeClearTable(p, iTable, 0); + rc = sqlite3BtreeClearTable(p, iTable, 0); if( rc ){ releasePage(pPage); return rc; @@ -77072,7 +77072,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ #else if( pBt->autoVacuum ){ Pgno maxRootPgno; - tdsqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); if( iTable==maxRootPgno ){ /* If the table being dropped is the table with the largest root-page @@ -77121,7 +77121,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ } assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); - rc = tdsqlite3BtreeUpdateMeta(p, 4, maxRootPgno); + rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); }else{ freePage(pPage, &rc); releasePage(pPage); @@ -77129,11 +77129,11 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ #endif return rc; } -SQLITE_PRIVATE int tdsqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ +SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ int rc; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); rc = btreeDropTable(p, iTable, piMoved); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -77158,17 +77158,17 @@ SQLITE_PRIVATE int tdsqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ ** pattern is the same as header meta values, and so it is convenient to ** read it from this routine. */ -SQLITE_PRIVATE void tdsqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ BtShared *pBt = p->pBt; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE ); assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) ); assert( pBt->pPage1 ); assert( idx>=0 && idx<=15 ); if( idx==BTREE_DATA_VERSION ){ - *pMeta = tdsqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion; + *pMeta = sqlite3PagerDataVersion(pBt->pPager) + p->iDataVersion; }else{ *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); } @@ -77181,23 +77181,23 @@ SQLITE_PRIVATE void tdsqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ } #endif - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); } /* ** Write meta-information back into the database. Meta[0] is ** read-only and may not be written. */ -SQLITE_PRIVATE int tdsqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ +SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ BtShared *pBt = p->pBt; unsigned char *pP1; int rc; assert( idx>=1 && idx<=15 ); - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); assert( pBt->pPage1!=0 ); pP1 = pBt->pPage1->aData; - rc = tdsqlite3PagerWrite(pBt->pPage1->pDbPage); + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc==SQLITE_OK ){ put4byte(&pP1[36 + idx*4], iMeta); #ifndef SQLITE_OMIT_AUTOVACUUM @@ -77208,7 +77208,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ } #endif } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -77221,7 +77221,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ ** Otherwise, if an error is encountered (i.e. an IO error or database ** corruption) an SQLite error code is returned. */ -SQLITE_PRIVATE int tdsqlite3BtreeCount(tdsqlite3 *db, BtCursor *pCur, i64 *pnEntry){ +SQLITE_PRIVATE int sqlite3BtreeCount(sqlite3 *db, BtCursor *pCur, i64 *pnEntry){ i64 nEntry = 0; /* Value to return in *pnEntry */ int rc; /* Return code */ @@ -77291,7 +77291,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeCount(tdsqlite3 *db, BtCursor *pCur, i64 *pnEnt ** Return the pager associated with a BTree. This routine is used for ** testing and debugging only. */ -SQLITE_PRIVATE Pager *tdsqlite3BtreePager(Btree *p){ +SQLITE_PRIVATE Pager *sqlite3BtreePager(Btree *p){ return p->pBt->pPager; } @@ -77310,12 +77310,12 @@ static void checkAppendMsg( pCheck->nErr++; va_start(ap, zFormat); if( pCheck->errMsg.nChar ){ - tdsqlite3_str_append(&pCheck->errMsg, "\n", 1); + sqlite3_str_append(&pCheck->errMsg, "\n", 1); } if( pCheck->zPfx ){ - tdsqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); + sqlite3_str_appendf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2); } - tdsqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); + sqlite3_str_vappendf(&pCheck->errMsg, zFormat, ap); va_end(ap); if( pCheck->errMsg.accError==SQLITE_NOMEM ){ pCheck->mallocFailed = 1; @@ -77414,11 +77414,11 @@ static void checkList( unsigned char *pOvflData; if( checkRef(pCheck, iPage) ) break; N--; - if( tdsqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ + if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ checkAppendMsg(pCheck, "failed to get page %d", iPage); break; } - pOvflData = (unsigned char *)tdsqlite3PagerGetData(pOvflPage); + pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); if( isFreeList ){ u32 n = (u32)get4byte(&pOvflData[4]); #ifndef SQLITE_OMIT_AUTOVACUUM @@ -77456,7 +77456,7 @@ static void checkList( } #endif iPage = get4byte(pOvflData); - tdsqlite3PagerUnref(pOvflPage); + sqlite3PagerUnref(pOvflPage); } if( N && nErrAtStart==pCheck->nErr ){ checkAppendMsg(pCheck, @@ -77803,8 +77803,8 @@ end_of_check: ** malloc is returned if *pnErr is non-zero. If *pnErr==0 then NULL is ** returned. If a memory allocation error occurs, NULL is returned. */ -SQLITE_PRIVATE char *tdsqlite3BtreeIntegrityCheck( - tdsqlite3 *db, /* Database connection that is running the check */ +SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( + sqlite3 *db, /* Database connection that is running the check */ Btree *p, /* The btree to be checked */ int *aRoot, /* An array of root pages numbers for individual trees */ int nRoot, /* Number of entries in aRoot[] */ @@ -77818,9 +77818,9 @@ SQLITE_PRIVATE char *tdsqlite3BtreeIntegrityCheck( char zErr[100]; VVA_ONLY( int nRef ); - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); assert( p->inTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); - VVA_ONLY( nRef = tdsqlite3PagerRefcount(pBt->pPager) ); + VVA_ONLY( nRef = sqlite3PagerRefcount(pBt->pPager) ); assert( nRef>=0 ); sCheck.db = db; sCheck.pBt = pBt; @@ -77834,18 +77834,18 @@ SQLITE_PRIVATE char *tdsqlite3BtreeIntegrityCheck( sCheck.v2 = 0; sCheck.aPgRef = 0; sCheck.heap = 0; - tdsqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); + sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; if( sCheck.nPage==0 ){ goto integrity_ck_cleanup; } - sCheck.aPgRef = tdsqlite3MallocZero((sCheck.nPage / 8)+ 1); + sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); if( !sCheck.aPgRef ){ sCheck.mallocFailed = 1; goto integrity_ck_cleanup; } - sCheck.heap = (u32*)tdsqlite3PageMalloc( pBt->pageSize ); + sCheck.heap = (u32*)sqlite3PageMalloc( pBt->pageSize ); if( sCheck.heap==0 ){ sCheck.mallocFailed = 1; goto integrity_ck_cleanup; @@ -77920,18 +77920,18 @@ SQLITE_PRIVATE char *tdsqlite3BtreeIntegrityCheck( /* Clean up and report errors. */ integrity_ck_cleanup: - tdsqlite3PageFree(sCheck.heap); - tdsqlite3_free(sCheck.aPgRef); + sqlite3PageFree(sCheck.heap); + sqlite3_free(sCheck.aPgRef); if( sCheck.mallocFailed ){ - tdsqlite3_str_reset(&sCheck.errMsg); + sqlite3_str_reset(&sCheck.errMsg); sCheck.nErr++; } *pnErr = sCheck.nErr; - if( sCheck.nErr==0 ) tdsqlite3_str_reset(&sCheck.errMsg); + if( sCheck.nErr==0 ) sqlite3_str_reset(&sCheck.errMsg); /* Make sure this analysis did not leave any unref() pages. */ - assert( nRef==tdsqlite3PagerRefcount(pBt->pPager) ); - tdsqlite3BtreeLeave(p); - return tdsqlite3StrAccumFinish(&sCheck.errMsg); + assert( nRef==sqlite3PagerRefcount(pBt->pPager) ); + sqlite3BtreeLeave(p); + return sqlite3StrAccumFinish(&sCheck.errMsg); } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -77942,9 +77942,9 @@ integrity_ck_cleanup: ** The pager filename is invariant as long as the pager is ** open so it is safe to access without the BtShared mutex. */ -SQLITE_PRIVATE const char *tdsqlite3BtreeGetFilename(Btree *p){ +SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *p){ assert( p->pBt->pPager!=0 ); - return tdsqlite3PagerFilename(p->pBt->pPager, 1); + return sqlite3PagerFilename(p->pBt->pPager, 1); } /* @@ -77955,16 +77955,16 @@ SQLITE_PRIVATE const char *tdsqlite3BtreeGetFilename(Btree *p){ ** The pager journal filename is invariant as long as the pager is ** open so it is safe to access without the BtShared mutex. */ -SQLITE_PRIVATE const char *tdsqlite3BtreeGetJournalname(Btree *p){ +SQLITE_PRIVATE const char *sqlite3BtreeGetJournalname(Btree *p){ assert( p->pBt->pPager!=0 ); - return tdsqlite3PagerJournalname(p->pBt->pPager); + return sqlite3PagerJournalname(p->pBt->pPager); } /* ** Return non-zero if a transaction is active. */ -SQLITE_PRIVATE int tdsqlite3BtreeIsInTrans(Btree *p){ - assert( p==0 || tdsqlite3_mutex_held(p->db->mutex) ); +SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree *p){ + assert( p==0 || sqlite3_mutex_held(p->db->mutex) ); return (p && (p->inTrans==TRANS_WRITE)); } @@ -77977,17 +77977,17 @@ SQLITE_PRIVATE int tdsqlite3BtreeIsInTrans(Btree *p){ ** ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. */ -SQLITE_PRIVATE int tdsqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ +SQLITE_PRIVATE int sqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int *pnCkpt){ int rc = SQLITE_OK; if( p ){ BtShared *pBt = p->pBt; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); if( pBt->inTransaction!=TRANS_NONE ){ rc = SQLITE_LOCKED; }else{ - rc = tdsqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt); + rc = sqlite3PagerCheckpoint(pBt->pPager, p->db, eMode, pnLog, pnCkpt); } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); } return rc; } @@ -77996,15 +77996,15 @@ SQLITE_PRIVATE int tdsqlite3BtreeCheckpoint(Btree *p, int eMode, int *pnLog, int /* ** Return non-zero if a read (or write) transaction is active. */ -SQLITE_PRIVATE int tdsqlite3BtreeIsInReadTrans(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree *p){ assert( p ); - assert( tdsqlite3_mutex_held(p->db->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); return p->inTrans!=TRANS_NONE; } -SQLITE_PRIVATE int tdsqlite3BtreeIsInBackup(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree *p){ assert( p ); - assert( tdsqlite3_mutex_held(p->db->mutex) ); + assert( sqlite3_mutex_held(p->db->mutex) ); return p->nBackup!=0; } @@ -78025,17 +78025,17 @@ SQLITE_PRIVATE int tdsqlite3BtreeIsInBackup(Btree *p){ ** ** Just before the shared-btree is closed, the function passed as the ** xFree argument when the memory allocation was made is invoked on the -** blob of allocated memory. The xFree function should not call tdsqlite3_free() +** blob of allocated memory. The xFree function should not call sqlite3_free() ** on the memory, the btree layer does that. */ -SQLITE_PRIVATE void *tdsqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ +SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){ BtShared *pBt = p->pBt; - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); if( !pBt->pSchema && nBytes ){ - pBt->pSchema = tdsqlite3DbMallocZero(0, nBytes); + pBt->pSchema = sqlite3DbMallocZero(0, nBytes); pBt->xFreeSchema = xFree; } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return pBt->pSchema; } @@ -78044,13 +78044,13 @@ SQLITE_PRIVATE void *tdsqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(voi ** btree as the argument handle holds an exclusive lock on the ** sqlite_master table. Otherwise SQLITE_OK. */ -SQLITE_PRIVATE int tdsqlite3BtreeSchemaLocked(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ int rc; - assert( tdsqlite3_mutex_held(p->db->mutex) ); - tdsqlite3BtreeEnter(p); + assert( sqlite3_mutex_held(p->db->mutex) ); + sqlite3BtreeEnter(p); rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); assert( rc==SQLITE_OK || rc==SQLITE_LOCKED_SHAREDCACHE ); - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); return rc; } @@ -78061,7 +78061,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeSchemaLocked(Btree *p){ ** lock is a write lock if isWritelock is true or a read lock ** if it is false. */ -SQLITE_PRIVATE int tdsqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ int rc = SQLITE_OK; assert( p->inTrans!=TRANS_NONE ); if( p->sharable ){ @@ -78069,12 +78069,12 @@ SQLITE_PRIVATE int tdsqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ assert( READ_LOCK+1==WRITE_LOCK ); assert( isWriteLock==0 || isWriteLock==1 ); - tdsqlite3BtreeEnter(p); + sqlite3BtreeEnter(p); rc = querySharedCacheTableLock(p, iTab, lockType); if( rc==SQLITE_OK ){ rc = setSharedCacheTableLock(p, iTab, lockType); } - tdsqlite3BtreeLeave(p); + sqlite3BtreeLeave(p); } return rc; } @@ -78091,10 +78091,10 @@ SQLITE_PRIVATE int tdsqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ ** parameters that attempt to write past the end of the existing data, ** no modifications are made and SQLITE_CORRUPT is returned. */ -SQLITE_PRIVATE int tdsqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ +SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ int rc; assert( cursorOwnsBtShared(pCsr) ); - assert( tdsqlite3_mutex_held(pCsr->pBtree->db->mutex) ); + assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); assert( pCsr->curFlags & BTCF_Incrblob ); rc = restoreCursorPosition(pCsr); @@ -78139,7 +78139,7 @@ SQLITE_PRIVATE int tdsqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, vo /* ** Mark this cursor as an incremental blob cursor. */ -SQLITE_PRIVATE void tdsqlite3BtreeIncrblobCursor(BtCursor *pCur){ +SQLITE_PRIVATE void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ pCur->curFlags |= BTCF_Incrblob; pCur->pBtree->hasIncrblobCur = 1; } @@ -78150,7 +78150,7 @@ SQLITE_PRIVATE void tdsqlite3BtreeIncrblobCursor(BtCursor *pCur){ ** "write version" (single byte at byte offset 19) fields in the database ** header to iVersion. */ -SQLITE_PRIVATE int tdsqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ +SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ BtShared *pBt = pBtree->pBt; int rc; /* Return code */ @@ -78162,13 +78162,13 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ pBt->btsFlags &= ~BTS_NO_WAL; if( iVersion==1 ) pBt->btsFlags |= BTS_NO_WAL; - rc = tdsqlite3BtreeBeginTrans(pBtree, 0, 0); + rc = sqlite3BtreeBeginTrans(pBtree, 0, 0); if( rc==SQLITE_OK ){ u8 *aData = pBt->pPage1->aData; if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ - rc = tdsqlite3BtreeBeginTrans(pBtree, 2, 0); + rc = sqlite3BtreeBeginTrans(pBtree, 2, 0); if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerWrite(pBt->pPage1->pDbPage); + rc = sqlite3PagerWrite(pBt->pPage1->pDbPage); if( rc==SQLITE_OK ){ aData[18] = (u8)iVersion; aData[19] = (u8)iVersion; @@ -78185,27 +78185,27 @@ SQLITE_PRIVATE int tdsqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ ** Return true if the cursor has a hint specified. This routine is ** only used from within assert() statements */ -SQLITE_PRIVATE int tdsqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){ +SQLITE_PRIVATE int sqlite3BtreeCursorHasHint(BtCursor *pCsr, unsigned int mask){ return (pCsr->hints & mask)!=0; } /* ** Return true if the given Btree is read-only. */ -SQLITE_PRIVATE int tdsqlite3BtreeIsReadonly(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeIsReadonly(Btree *p){ return (p->pBt->btsFlags & BTS_READ_ONLY)!=0; } /* ** Return the size of the header added to each page by this module. */ -SQLITE_PRIVATE int tdsqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } +SQLITE_PRIVATE int sqlite3HeaderSizeBtree(void){ return ROUND8(sizeof(MemPage)); } #if !defined(SQLITE_OMIT_SHARED_CACHE) /* ** Return true if the Btree passed as the only argument is sharable. */ -SQLITE_PRIVATE int tdsqlite3BtreeSharable(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeSharable(Btree *p){ return p->sharable; } @@ -78214,7 +78214,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeSharable(Btree *p){ ** the Btree handle passed as the only argument. For private caches ** this is always 1. For shared caches it may be 1 or greater. */ -SQLITE_PRIVATE int tdsqlite3BtreeConnectionCount(Btree *p){ +SQLITE_PRIVATE int sqlite3BtreeConnectionCount(Btree *p){ testcase( p->sharable ); return p->pBt->nRef; } @@ -78233,7 +78233,7 @@ SQLITE_PRIVATE int tdsqlite3BtreeConnectionCount(Btree *p){ ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file contains the implementation of the tdsqlite3_backup_XXX() +** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. */ /* #include "sqliteInt.h" */ @@ -78242,14 +78242,14 @@ SQLITE_PRIVATE int tdsqlite3BtreeConnectionCount(Btree *p){ /* ** Structure allocated for each backup operation. */ -struct tdsqlite3_backup { - tdsqlite3* pDestDb; /* Destination database handle */ +struct sqlite3_backup { + sqlite3* pDestDb; /* Destination database handle */ Btree *pDest; /* Destination b-tree file */ u32 iDestSchema; /* Original schema cookie in destination */ int bDestLocked; /* True once a write-transaction is open on pDest */ Pgno iNext; /* Page number of the next source page to copy */ - tdsqlite3* pSrcDb; /* Source database handle */ + sqlite3* pSrcDb; /* Source database handle */ Btree *pSrc; /* Source b-tree file */ int rc; /* Backup process error code */ @@ -78261,16 +78261,16 @@ struct tdsqlite3_backup { Pgno nPagecount; /* Total number of pages to copy */ int isAttached; /* True once backup has been registered with pager */ - tdsqlite3_backup *pNext; /* Next backup associated with source pager */ + sqlite3_backup *pNext; /* Next backup associated with source pager */ }; /* ** THREAD SAFETY NOTES: ** -** Once it has been created using backup_init(), a single tdsqlite3_backup +** Once it has been created using backup_init(), a single sqlite3_backup ** structure may be accessed via two groups of thread-safe entry points: ** -** * Via the tdsqlite3_backup_XXX() API function backup_step() and +** * Via the sqlite3_backup_XXX() API function backup_step() and ** backup_finish(). Both these functions obtain the source database ** handle mutex and the mutex associated with the source BtShared ** structure, in that order. @@ -78281,7 +78281,7 @@ struct tdsqlite3_backup { ** associated with the source database BtShared structure will always ** be held when either of these functions are invoked. ** -** The other tdsqlite3_backup_XXX() API functions, backup_remaining() and +** The other sqlite3_backup_XXX() API functions, backup_remaining() and ** backup_pagecount() are not thread-safe functions. If they are called ** while some other thread is calling backup_step() or backup_finish(), ** the values returned may be invalid. There is no way for a call to @@ -78303,27 +78303,27 @@ struct tdsqlite3_backup { ** function. If an error occurs while doing so, return 0 and write an ** error message to pErrorDb. */ -static Btree *findBtree(tdsqlite3 *pErrorDb, tdsqlite3 *pDb, const char *zDb){ - int i = tdsqlite3FindDbName(pDb, zDb); +static Btree *findBtree(sqlite3 *pErrorDb, sqlite3 *pDb, const char *zDb){ + int i = sqlite3FindDbName(pDb, zDb); if( i==1 ){ Parse sParse; int rc = 0; memset(&sParse, 0, sizeof(sParse)); sParse.db = pDb; - if( tdsqlite3OpenTempDatabase(&sParse) ){ - tdsqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); + if( sqlite3OpenTempDatabase(&sParse) ){ + sqlite3ErrorWithMsg(pErrorDb, sParse.rc, "%s", sParse.zErrMsg); rc = SQLITE_ERROR; } - tdsqlite3DbFree(pErrorDb, sParse.zErrMsg); - tdsqlite3ParserReset(&sParse); + sqlite3DbFree(pErrorDb, sParse.zErrMsg); + sqlite3ParserReset(&sParse); if( rc ){ return 0; } } if( i<0 ){ - tdsqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); + sqlite3ErrorWithMsg(pErrorDb, SQLITE_ERROR, "unknown database %s", zDb); return 0; } @@ -78334,9 +78334,9 @@ static Btree *findBtree(tdsqlite3 *pErrorDb, tdsqlite3 *pDb, const char *zDb){ ** Attempt to set the page size of the destination to match the page size ** of the source. */ -static int setDestPgsz(tdsqlite3_backup *p){ +static int setDestPgsz(sqlite3_backup *p){ int rc; - rc = tdsqlite3BtreeSetPageSize(p->pDest,tdsqlite3BtreeGetPageSize(p->pSrc),-1,0); + rc = sqlite3BtreeSetPageSize(p->pDest,sqlite3BtreeGetPageSize(p->pSrc),-1,0); return rc; } @@ -78346,32 +78346,32 @@ static int setDestPgsz(tdsqlite3_backup *p){ ** is an open read-transaction, return SQLITE_ERROR and leave an error ** message in database handle db. */ -static int checkReadTransaction(tdsqlite3 *db, Btree *p){ - if( tdsqlite3BtreeIsInReadTrans(p) ){ - tdsqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use"); +static int checkReadTransaction(sqlite3 *db, Btree *p){ + if( sqlite3BtreeIsInReadTrans(p) ){ + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "destination database is in use"); return SQLITE_ERROR; } return SQLITE_OK; } /* -** Create an tdsqlite3_backup process to copy the contents of zSrcDb from +** Create an sqlite3_backup process to copy the contents of zSrcDb from ** connection handle pSrcDb to zDestDb in pDestDb. If successful, return -** a pointer to the new tdsqlite3_backup object. +** a pointer to the new sqlite3_backup object. ** ** If an error occurs, NULL is returned and an error code and error message ** stored in database handle pDestDb. */ -SQLITE_API tdsqlite3_backup *tdsqlite3_backup_init( - tdsqlite3* pDestDb, /* Database to write to */ +SQLITE_API sqlite3_backup *sqlite3_backup_init( + sqlite3* pDestDb, /* Database to write to */ const char *zDestDb, /* Name of database within pDestDb */ - tdsqlite3* pSrcDb, /* Database connection to read from */ + sqlite3* pSrcDb, /* Database connection to read from */ const char *zSrcDb /* Name of database within pSrcDb */ ){ - tdsqlite3_backup *p; /* Value to return */ + sqlite3_backup *p; /* Value to return */ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(pSrcDb)||!tdsqlite3SafetyCheckOk(pDestDb) ){ + if( !sqlite3SafetyCheckOk(pSrcDb)||!sqlite3SafetyCheckOk(pDestDb) ){ (void)SQLITE_MISUSE_BKPT; return 0; } @@ -78383,13 +78383,13 @@ SQLITE_API tdsqlite3_backup *tdsqlite3_backup_init( int srcNKey, destNKey; void *zKey; - tdsqlite3CodecGetKey(pSrcDb, sqlcipher_find_db_index(pSrcDb, zSrcDb), &zKey, &srcNKey); - tdsqlite3CodecGetKey(pDestDb, sqlcipher_find_db_index(pDestDb, zDestDb), &zKey, &destNKey); + sqlite3CodecGetKey(pSrcDb, sqlcipher_find_db_index(pSrcDb, zSrcDb), &zKey, &srcNKey); + sqlite3CodecGetKey(pDestDb, sqlcipher_find_db_index(pDestDb, zDestDb), &zKey, &destNKey); zKey = NULL; /* either both databases must be plaintext, or both must be encrypted */ if((srcNKey == 0 && destNKey > 0) || (srcNKey > 0 && destNKey == 0)) { - tdsqlite3ErrorWithMsg(pDestDb, SQLITE_ERROR, "backup is not supported with encrypted databases"); + sqlite3ErrorWithMsg(pDestDb, SQLITE_ERROR, "backup is not supported with encrypted databases"); return NULL; } } @@ -78398,28 +78398,28 @@ SQLITE_API tdsqlite3_backup *tdsqlite3_backup_init( /* Lock the source database handle. The destination database ** handle is not locked in this routine, but it is locked in - ** tdsqlite3_backup_step(). The user is required to ensure that no + ** sqlite3_backup_step(). The user is required to ensure that no ** other thread accesses the destination handle for the duration ** of the backup operation. Any attempt to use the destination ** database connection while a backup is in progress may cause ** a malfunction or a deadlock. */ - tdsqlite3_mutex_enter(pSrcDb->mutex); - tdsqlite3_mutex_enter(pDestDb->mutex); + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3_mutex_enter(pDestDb->mutex); if( pSrcDb==pDestDb ){ - tdsqlite3ErrorWithMsg( + sqlite3ErrorWithMsg( pDestDb, SQLITE_ERROR, "source and destination must be distinct" ); p = 0; }else { - /* Allocate space for a new tdsqlite3_backup object... - ** EVIDENCE-OF: R-64852-21591 The tdsqlite3_backup object is created by a - ** call to tdsqlite3_backup_init() and is destroyed by a call to - ** tdsqlite3_backup_finish(). */ - p = (tdsqlite3_backup *)tdsqlite3MallocZero(sizeof(tdsqlite3_backup)); + /* Allocate space for a new sqlite3_backup object... + ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); if( !p ){ - tdsqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); + sqlite3Error(pDestDb, SQLITE_NOMEM_BKPT); } } @@ -78438,9 +78438,9 @@ SQLITE_API tdsqlite3_backup *tdsqlite3_backup_init( /* One (or both) of the named databases did not exist or an OOM ** error was hit. Or there is a transaction open on the destination ** database. The error has already been written into the pDestDb - ** handle. All that is left to do here is free the tdsqlite3_backup + ** handle. All that is left to do here is free the sqlite3_backup ** structure. */ - tdsqlite3_free(p); + sqlite3_free(p); p = 0; } } @@ -78448,8 +78448,8 @@ SQLITE_API tdsqlite3_backup *tdsqlite3_backup_init( p->pSrc->nBackup++; } - tdsqlite3_mutex_leave(pDestDb->mutex); - tdsqlite3_mutex_leave(pSrcDb->mutex); + sqlite3_mutex_leave(pDestDb->mutex); + sqlite3_mutex_leave(pSrcDb->mutex); return p; } @@ -78468,27 +78468,27 @@ static int isFatalError(int rc){ ** destination database. */ static int backupOnePage( - tdsqlite3_backup *p, /* Backup handle */ + sqlite3_backup *p, /* Backup handle */ Pgno iSrcPg, /* Source database page to backup */ const u8 *zSrcData, /* Source database page data */ int bUpdate /* True for an update, false otherwise */ ){ - Pager * const pDestPager = tdsqlite3BtreePager(p->pDest); - const int nSrcPgsz = tdsqlite3BtreeGetPageSize(p->pSrc); - int nDestPgsz = tdsqlite3BtreeGetPageSize(p->pDest); + Pager * const pDestPager = sqlite3BtreePager(p->pDest); + const int nSrcPgsz = sqlite3BtreeGetPageSize(p->pSrc); + int nDestPgsz = sqlite3BtreeGetPageSize(p->pDest); const int nCopy = MIN(nSrcPgsz, nDestPgsz); const i64 iEnd = (i64)iSrcPg*(i64)nSrcPgsz; #ifdef SQLITE_HAS_CODEC /* Use BtreeGetReserveNoMutex() for the source b-tree, as although it is ** guaranteed that the shared-mutex is held by this thread, handle ** p->pSrc may not actually be the owner. */ - int nSrcReserve = tdsqlite3BtreeGetReserveNoMutex(p->pSrc); - int nDestReserve = tdsqlite3BtreeGetOptimalReserve(p->pDest); + int nSrcReserve = sqlite3BtreeGetReserveNoMutex(p->pSrc); + int nDestReserve = sqlite3BtreeGetOptimalReserve(p->pDest); #endif int rc = SQLITE_OK; i64 iOff; - assert( tdsqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 ); + assert( sqlite3BtreeGetReserveNoMutex(p->pSrc)>=0 ); assert( p->bDestLocked ); assert( !isFatalError(p->rc) ); assert( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ); @@ -78497,7 +78497,7 @@ static int backupOnePage( /* Catch the case where the destination is an in-memory database and the ** page sizes of the source and destination differ. */ - if( nSrcPgsz!=nDestPgsz && tdsqlite3PagerIsMemdb(pDestPager) ){ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerIsMemdb(pDestPager) ){ rc = SQLITE_READONLY; } @@ -78505,7 +78505,7 @@ static int backupOnePage( /* Backup is not possible if the page size of the destination is changing ** and a codec is in use. */ - if( nSrcPgsz!=nDestPgsz && tdsqlite3PagerGetCodec(pDestPager)!=0 ){ + if( nSrcPgsz!=nDestPgsz && sqlite3PagerGetCodec(pDestPager)!=0 ){ rc = SQLITE_READONLY; } @@ -78516,7 +78516,7 @@ static int backupOnePage( */ if( nSrcReserve!=nDestReserve ){ u32 newPgsz = nSrcPgsz; - rc = tdsqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); + rc = sqlite3PagerSetPagesize(pDestPager, &newPgsz, nSrcReserve); if( rc==SQLITE_OK && newPgsz!=(u32)nSrcPgsz ) rc = SQLITE_READONLY; } #endif @@ -78529,11 +78529,11 @@ static int backupOnePage( DbPage *pDestPg = 0; Pgno iDest = (Pgno)(iOff/nDestPgsz)+1; if( iDest==PENDING_BYTE_PAGE(p->pDest->pBt) ) continue; - if( SQLITE_OK==(rc = tdsqlite3PagerGet(pDestPager, iDest, &pDestPg, 0)) - && SQLITE_OK==(rc = tdsqlite3PagerWrite(pDestPg)) + if( SQLITE_OK==(rc = sqlite3PagerGet(pDestPager, iDest, &pDestPg, 0)) + && SQLITE_OK==(rc = sqlite3PagerWrite(pDestPg)) ){ const u8 *zIn = &zSrcData[iOff%nSrcPgsz]; - u8 *zDestData = tdsqlite3PagerGetData(pDestPg); + u8 *zDestData = sqlite3PagerGetData(pDestPg); u8 *zOut = &zDestData[iOff%nDestPgsz]; /* Copy the data from the source page into the destination page. @@ -78544,12 +78544,12 @@ static int backupOnePage( ** "MUST BE FIRST" for this purpose. */ memcpy(zOut, zIn, nCopy); - ((u8 *)tdsqlite3PagerGetExtra(pDestPg))[0] = 0; + ((u8 *)sqlite3PagerGetExtra(pDestPg))[0] = 0; if( iOff==0 && bUpdate==0 ){ - tdsqlite3Put4byte(&zOut[28], tdsqlite3BtreeLastPage(p->pSrc)); + sqlite3Put4byte(&zOut[28], sqlite3BtreeLastPage(p->pSrc)); } } - tdsqlite3PagerUnref(pDestPg); + sqlite3PagerUnref(pDestPg); } return rc; @@ -78563,11 +78563,11 @@ static int backupOnePage( ** Return SQLITE_OK if everything is successful, or an SQLite error ** code if an error occurs. */ -static int backupTruncateFile(tdsqlite3_file *pFile, i64 iSize){ +static int backupTruncateFile(sqlite3_file *pFile, i64 iSize){ i64 iCurrent; - int rc = tdsqlite3OsFileSize(pFile, &iCurrent); + int rc = sqlite3OsFileSize(pFile, &iCurrent); if( rc==SQLITE_OK && iCurrent>iSize ){ - rc = tdsqlite3OsTruncate(pFile, iSize); + rc = sqlite3OsTruncate(pFile, iSize); } return rc; } @@ -78576,10 +78576,10 @@ static int backupTruncateFile(tdsqlite3_file *pFile, i64 iSize){ ** Register this backup object with the associated source pager for ** callbacks when pages are changed or the cache invalidated. */ -static void attachBackupObject(tdsqlite3_backup *p){ - tdsqlite3_backup **pp; - assert( tdsqlite3BtreeHoldsMutex(p->pSrc) ); - pp = tdsqlite3PagerBackupPtr(tdsqlite3BtreePager(p->pSrc)); +static void attachBackupObject(sqlite3_backup *p){ + sqlite3_backup **pp; + assert( sqlite3BtreeHoldsMutex(p->pSrc) ); + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); p->pNext = *pp; *pp = p; p->isAttached = 1; @@ -78588,7 +78588,7 @@ static void attachBackupObject(tdsqlite3_backup *p){ /* ** Copy nPage pages from the source b-tree to the destination. */ -SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ int rc; int destMode; /* Destination journal mode */ int pgszSrc = 0; /* Source page size */ @@ -78597,16 +78597,16 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ #ifdef SQLITE_ENABLE_API_ARMOR if( p==0 ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(p->pSrcDb->mutex); - tdsqlite3BtreeEnter(p->pSrc); + sqlite3_mutex_enter(p->pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); if( p->pDestDb ){ - tdsqlite3_mutex_enter(p->pDestDb->mutex); + sqlite3_mutex_enter(p->pDestDb->mutex); } rc = p->rc; if( !isFatalError(rc) ){ - Pager * const pSrcPager = tdsqlite3BtreePager(p->pSrc); /* Source pager */ - Pager * const pDestPager = tdsqlite3BtreePager(p->pDest); /* Dest pager */ + Pager * const pSrcPager = sqlite3BtreePager(p->pSrc); /* Source pager */ + Pager * const pDestPager = sqlite3BtreePager(p->pDest); /* Dest pager */ int ii; /* Iterator variable */ int nSrcPage = -1; /* Size of source db in pages */ int bCloseTrans = 0; /* True if src db requires unlocking */ @@ -78624,8 +78624,8 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ ** one now. If a transaction is opened here, then it will be closed ** before this function exits. */ - if( rc==SQLITE_OK && 0==tdsqlite3BtreeIsInReadTrans(p->pSrc) ){ - rc = tdsqlite3BtreeBeginTrans(p->pSrc, 0, 0); + if( rc==SQLITE_OK && 0==sqlite3BtreeIsInReadTrans(p->pSrc) ){ + rc = sqlite3BtreeBeginTrans(p->pSrc, 0, 0); bCloseTrans = 1; } @@ -78641,7 +78641,7 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ /* Lock the destination database, if it is not locked already. */ if( SQLITE_OK==rc && p->bDestLocked==0 - && SQLITE_OK==(rc = tdsqlite3BtreeBeginTrans(p->pDest, 2, + && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2, (int*)&p->iDestSchema)) ){ p->bDestLocked = 1; @@ -78649,9 +78649,9 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ /* Do not allow backup if the destination database is in WAL mode ** and the page sizes are different between source and destination */ - pgszSrc = tdsqlite3BtreeGetPageSize(p->pSrc); - pgszDest = tdsqlite3BtreeGetPageSize(p->pDest); - destMode = tdsqlite3PagerGetJournalMode(tdsqlite3BtreePager(p->pDest)); + pgszSrc = sqlite3BtreeGetPageSize(p->pSrc); + pgszDest = sqlite3BtreeGetPageSize(p->pDest); + destMode = sqlite3PagerGetJournalMode(sqlite3BtreePager(p->pDest)); if( SQLITE_OK==rc && destMode==PAGER_JOURNALMODE_WAL && pgszSrc!=pgszDest ){ rc = SQLITE_READONLY; } @@ -78659,16 +78659,16 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ /* Now that there is a read-lock on the source database, query the ** source pager for the number of pages in the database. */ - nSrcPage = (int)tdsqlite3BtreeLastPage(p->pSrc); + nSrcPage = (int)sqlite3BtreeLastPage(p->pSrc); assert( nSrcPage>=0 ); for(ii=0; (nPage<0 || iiiNext<=(Pgno)nSrcPage && !rc; ii++){ const Pgno iSrcPg = p->iNext; /* Source page number */ if( iSrcPg!=PENDING_BYTE_PAGE(p->pSrc->pBt) ){ DbPage *pSrcPg; /* Source page object */ - rc = tdsqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY); + rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg,PAGER_GET_READONLY); if( rc==SQLITE_OK ){ - rc = backupOnePage(p, iSrcPg, tdsqlite3PagerGetData(pSrcPg), 0); - tdsqlite3PagerUnref(pSrcPg); + rc = backupOnePage(p, iSrcPg, sqlite3PagerGetData(pSrcPg), 0); + sqlite3PagerUnref(pSrcPg); } } p->iNext++; @@ -78690,18 +78690,18 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ */ if( rc==SQLITE_DONE ){ if( nSrcPage==0 ){ - rc = tdsqlite3BtreeNewDb(p->pDest); + rc = sqlite3BtreeNewDb(p->pDest); nSrcPage = 1; } if( rc==SQLITE_OK || rc==SQLITE_DONE ){ - rc = tdsqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); + rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1); } if( rc==SQLITE_OK ){ if( p->pDestDb ){ - tdsqlite3ResetAllSchemasOfConnection(p->pDestDb); + sqlite3ResetAllSchemasOfConnection(p->pDestDb); } if( destMode==PAGER_JOURNALMODE_WAL ){ - rc = tdsqlite3BtreeSetVersion(p->pDest, 2); + rc = sqlite3BtreeSetVersion(p->pDest, 2); } } if( rc==SQLITE_OK ){ @@ -78711,15 +78711,15 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ ** size may be different to the source page size. ** ** If the source page size is smaller than the destination page size, - ** round up. In this case the call to tdsqlite3OsTruncate() below will + ** round up. In this case the call to sqlite3OsTruncate() below will ** fix the size of the file. However it is important to call - ** tdsqlite3PagerTruncateImage() here so that any pages in the + ** sqlite3PagerTruncateImage() here so that any pages in the ** destination file that lie beyond the nDestTruncate page mark are ** journalled by PagerCommitPhaseOne() before they are destroyed ** by the file truncation. */ - assert( pgszSrc==tdsqlite3BtreeGetPageSize(p->pSrc) ); - assert( pgszDest==tdsqlite3BtreeGetPageSize(p->pDest) ); + assert( pgszSrc==sqlite3BtreeGetPageSize(p->pSrc) ); + assert( pgszDest==sqlite3BtreeGetPageSize(p->pDest) ); if( pgszSrcpDest->pBt) ){ DbPage *pPg; - rc = tdsqlite3PagerGet(pDestPager, iPg, &pPg, 0); + rc = sqlite3PagerGet(pDestPager, iPg, &pPg, 0); if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerWrite(pPg); - tdsqlite3PagerUnref(pPg); + rc = sqlite3PagerWrite(pPg); + sqlite3PagerUnref(pPg); } } } if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerCommitPhaseOne(pDestPager, 0, 1); + rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 1); } /* Write the extra pages and truncate the database file as required */ @@ -78785,12 +78785,12 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ ){ PgHdr *pSrcPg = 0; const Pgno iSrcPg = (Pgno)((iOff/pgszSrc)+1); - rc = tdsqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0); + rc = sqlite3PagerGet(pSrcPager, iSrcPg, &pSrcPg, 0); if( rc==SQLITE_OK ){ - u8 *zData = tdsqlite3PagerGetData(pSrcPg); - rc = tdsqlite3OsWrite(pFile, zData, pgszSrc, iOff); + u8 *zData = sqlite3PagerGetData(pSrcPg); + rc = sqlite3OsWrite(pFile, zData, pgszSrc, iOff); } - tdsqlite3PagerUnref(pSrcPg); + sqlite3PagerUnref(pSrcPg); } if( rc==SQLITE_OK ){ rc = backupTruncateFile(pFile, iSize); @@ -78798,16 +78798,16 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ /* Sync the database file to disk. */ if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerSync(pDestPager, 0); + rc = sqlite3PagerSync(pDestPager, 0); } }else{ - tdsqlite3PagerTruncateImage(pDestPager, nDestTruncate); - rc = tdsqlite3PagerCommitPhaseOne(pDestPager, 0, 0); + sqlite3PagerTruncateImage(pDestPager, nDestTruncate); + rc = sqlite3PagerCommitPhaseOne(pDestPager, 0, 0); } /* Finish committing the transaction to the destination database. */ if( SQLITE_OK==rc - && SQLITE_OK==(rc = tdsqlite3BtreeCommitPhaseTwo(p->pDest, 0)) + && SQLITE_OK==(rc = sqlite3BtreeCommitPhaseTwo(p->pDest, 0)) ){ rc = SQLITE_DONE; } @@ -78821,8 +78821,8 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ */ if( bCloseTrans ){ TESTONLY( int rc2 ); - TESTONLY( rc2 = ) tdsqlite3BtreeCommitPhaseOne(p->pSrc, 0); - TESTONLY( rc2 |= ) tdsqlite3BtreeCommitPhaseTwo(p->pSrc, 0); + TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); + TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc, 0); assert( rc2==SQLITE_OK ); } @@ -78832,28 +78832,28 @@ SQLITE_API int tdsqlite3_backup_step(tdsqlite3_backup *p, int nPage){ p->rc = rc; } if( p->pDestDb ){ - tdsqlite3_mutex_leave(p->pDestDb->mutex); + sqlite3_mutex_leave(p->pDestDb->mutex); } - tdsqlite3BtreeLeave(p->pSrc); - tdsqlite3_mutex_leave(p->pSrcDb->mutex); + sqlite3BtreeLeave(p->pSrc); + sqlite3_mutex_leave(p->pSrcDb->mutex); return rc; } /* -** Release all resources associated with an tdsqlite3_backup* handle. +** Release all resources associated with an sqlite3_backup* handle. */ -SQLITE_API int tdsqlite3_backup_finish(tdsqlite3_backup *p){ - tdsqlite3_backup **pp; /* Ptr to head of pagers backup list */ - tdsqlite3 *pSrcDb; /* Source database connection */ +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p){ + sqlite3_backup **pp; /* Ptr to head of pagers backup list */ + sqlite3 *pSrcDb; /* Source database connection */ int rc; /* Value to return */ /* Enter the mutexes */ if( p==0 ) return SQLITE_OK; pSrcDb = p->pSrcDb; - tdsqlite3_mutex_enter(pSrcDb->mutex); - tdsqlite3BtreeEnter(p->pSrc); + sqlite3_mutex_enter(pSrcDb->mutex); + sqlite3BtreeEnter(p->pSrc); if( p->pDestDb ){ - tdsqlite3_mutex_enter(p->pDestDb->mutex); + sqlite3_mutex_enter(p->pDestDb->mutex); } /* Detach this backup from the source pager. */ @@ -78861,7 +78861,7 @@ SQLITE_API int tdsqlite3_backup_finish(tdsqlite3_backup *p){ p->pSrc->nBackup--; } if( p->isAttached ){ - pp = tdsqlite3PagerBackupPtr(tdsqlite3BtreePager(p->pSrc)); + pp = sqlite3PagerBackupPtr(sqlite3BtreePager(p->pSrc)); assert( pp!=0 ); while( *pp!=p ){ pp = &(*pp)->pNext; @@ -78871,32 +78871,32 @@ SQLITE_API int tdsqlite3_backup_finish(tdsqlite3_backup *p){ } /* If a transaction is still open on the Btree, roll it back. */ - tdsqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); + sqlite3BtreeRollback(p->pDest, SQLITE_OK, 0); /* Set the error code of the destination database handle. */ rc = (p->rc==SQLITE_DONE) ? SQLITE_OK : p->rc; if( p->pDestDb ){ - tdsqlite3Error(p->pDestDb, rc); + sqlite3Error(p->pDestDb, rc); /* Exit the mutexes and free the backup context structure. */ - tdsqlite3LeaveMutexAndCloseZombie(p->pDestDb); + sqlite3LeaveMutexAndCloseZombie(p->pDestDb); } - tdsqlite3BtreeLeave(p->pSrc); + sqlite3BtreeLeave(p->pSrc); if( p->pDestDb ){ - /* EVIDENCE-OF: R-64852-21591 The tdsqlite3_backup object is created by a - ** call to tdsqlite3_backup_init() and is destroyed by a call to - ** tdsqlite3_backup_finish(). */ - tdsqlite3_free(p); + /* EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a + ** call to sqlite3_backup_init() and is destroyed by a call to + ** sqlite3_backup_finish(). */ + sqlite3_free(p); } - tdsqlite3LeaveMutexAndCloseZombie(pSrcDb); + sqlite3LeaveMutexAndCloseZombie(pSrcDb); return rc; } /* ** Return the number of pages still to be backed up as of the most recent -** call to tdsqlite3_backup_step(). +** call to sqlite3_backup_step(). */ -SQLITE_API int tdsqlite3_backup_remaining(tdsqlite3_backup *p){ +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p){ #ifdef SQLITE_ENABLE_API_ARMOR if( p==0 ){ (void)SQLITE_MISUSE_BKPT; @@ -78908,9 +78908,9 @@ SQLITE_API int tdsqlite3_backup_remaining(tdsqlite3_backup *p){ /* ** Return the total number of pages in the source database as of the most -** recent call to tdsqlite3_backup_step(). +** recent call to sqlite3_backup_step(). */ -SQLITE_API int tdsqlite3_backup_pagecount(tdsqlite3_backup *p){ +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p){ #ifdef SQLITE_ENABLE_API_ARMOR if( p==0 ){ (void)SQLITE_MISUSE_BKPT; @@ -78933,13 +78933,13 @@ SQLITE_API int tdsqlite3_backup_pagecount(tdsqlite3_backup *p){ ** called. */ static SQLITE_NOINLINE void backupUpdate( - tdsqlite3_backup *p, + sqlite3_backup *p, Pgno iPage, const u8 *aData ){ assert( p!=0 ); do{ - assert( tdsqlite3_mutex_held(p->pSrc->pBt->mutex) ); + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); if( !isFatalError(p->rc) && iPageiNext ){ /* The backup process p has already copied page iPage. But now it ** has been modified by a transaction on the source pager. Copy @@ -78947,9 +78947,9 @@ static SQLITE_NOINLINE void backupUpdate( */ int rc; assert( p->pDestDb ); - tdsqlite3_mutex_enter(p->pDestDb->mutex); + sqlite3_mutex_enter(p->pDestDb->mutex); rc = backupOnePage(p, iPage, aData, 1); - tdsqlite3_mutex_leave(p->pDestDb->mutex); + sqlite3_mutex_leave(p->pDestDb->mutex); assert( rc!=SQLITE_BUSY && rc!=SQLITE_LOCKED ); if( rc!=SQLITE_OK ){ p->rc = rc; @@ -78957,7 +78957,7 @@ static SQLITE_NOINLINE void backupUpdate( } }while( (p = p->pNext)!=0 ); } -SQLITE_PRIVATE void tdsqlite3BackupUpdate(tdsqlite3_backup *pBackup, Pgno iPage, const u8 *aData){ +SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *pBackup, Pgno iPage, const u8 *aData){ if( pBackup ) backupUpdate(pBackup, iPage, aData); } @@ -78972,10 +78972,10 @@ SQLITE_PRIVATE void tdsqlite3BackupUpdate(tdsqlite3_backup *pBackup, Pgno iPage, ** corresponding to the source database is held when this function is ** called. */ -SQLITE_PRIVATE void tdsqlite3BackupRestart(tdsqlite3_backup *pBackup){ - tdsqlite3_backup *p; /* Iterator variable */ +SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *pBackup){ + sqlite3_backup *p; /* Iterator variable */ for(p=pBackup; p; p=p->pNext){ - assert( tdsqlite3_mutex_held(p->pSrc->pBt->mutex) ); + assert( sqlite3_mutex_held(p->pSrc->pBt->mutex) ); p->iNext = 1; } } @@ -78989,25 +78989,25 @@ SQLITE_PRIVATE void tdsqlite3BackupRestart(tdsqlite3_backup *pBackup){ ** goes wrong, the transaction on pTo is rolled back. If successful, the ** transaction is committed before returning. */ -SQLITE_PRIVATE int tdsqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ +SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ int rc; - tdsqlite3_file *pFd; /* File descriptor for database pTo */ - tdsqlite3_backup b; - tdsqlite3BtreeEnter(pTo); - tdsqlite3BtreeEnter(pFrom); + sqlite3_file *pFd; /* File descriptor for database pTo */ + sqlite3_backup b; + sqlite3BtreeEnter(pTo); + sqlite3BtreeEnter(pFrom); - assert( tdsqlite3BtreeIsInTrans(pTo) ); - pFd = tdsqlite3PagerFile(tdsqlite3BtreePager(pTo)); + assert( sqlite3BtreeIsInTrans(pTo) ); + pFd = sqlite3PagerFile(sqlite3BtreePager(pTo)); if( pFd->pMethods ){ - i64 nByte = tdsqlite3BtreeGetPageSize(pFrom)*(i64)tdsqlite3BtreeLastPage(pFrom); - rc = tdsqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); + i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom); + rc = sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte); if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; if( rc ) goto copy_finished; } - /* Set up an tdsqlite3_backup object. tdsqlite3_backup.pDestDb must be set - ** to 0. This is used by the implementations of tdsqlite3_backup_step() - ** and tdsqlite3_backup_finish() to detect that they are being called + /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set + ** to 0. This is used by the implementations of sqlite3_backup_step() + ** and sqlite3_backup_finish() to detect that they are being called ** from this function, not directly by the user. */ memset(&b, 0, sizeof(b)); @@ -79017,29 +79017,29 @@ SQLITE_PRIVATE int tdsqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ b.iNext = 1; #ifdef SQLITE_HAS_CODEC - tdsqlite3PagerAlignReserve(tdsqlite3BtreePager(pTo), tdsqlite3BtreePager(pFrom)); + sqlite3PagerAlignReserve(sqlite3BtreePager(pTo), sqlite3BtreePager(pFrom)); #endif /* 0x7FFFFFFF is the hard limit for the number of pages in a database ** file. By passing this as the number of pages to copy to - ** tdsqlite3_backup_step(), we can guarantee that the copy finishes + ** sqlite3_backup_step(), we can guarantee that the copy finishes ** within a single call (unless an error occurs). The assert() statement ** checks this assumption - (p->rc) should be set to either SQLITE_DONE ** or an error code. */ - tdsqlite3_backup_step(&b, 0x7FFFFFFF); + sqlite3_backup_step(&b, 0x7FFFFFFF); assert( b.rc!=SQLITE_OK ); - rc = tdsqlite3_backup_finish(&b); + rc = sqlite3_backup_finish(&b); if( rc==SQLITE_OK ){ pTo->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; }else{ - tdsqlite3PagerClearCache(tdsqlite3BtreePager(b.pDest)); + sqlite3PagerClearCache(sqlite3BtreePager(b.pDest)); } - assert( tdsqlite3BtreeIsInTrans(pTo)==0 ); + assert( sqlite3BtreeIsInTrans(pTo)==0 ); copy_finished: - tdsqlite3BtreeLeave(pFrom); - tdsqlite3BtreeLeave(pTo); + sqlite3BtreeLeave(pFrom); + sqlite3BtreeLeave(pTo); return rc; } #endif /* SQLITE_OMIT_VACUUM */ @@ -79076,9 +79076,9 @@ copy_finished: ** Check invariants on a Mem object. ** ** This routine is intended for use inside of assert() statements, like -** this: assert( tdsqlite3VdbeCheckMemInvariants(pMem) ); +** this: assert( sqlite3VdbeCheckMemInvariants(pMem) ); */ -SQLITE_PRIVATE int tdsqlite3VdbeCheckMemInvariants(Mem *p){ +SQLITE_PRIVATE int sqlite3VdbeCheckMemInvariants(Mem *p){ /* If MEM_Dyn is set then Mem.xDel!=0. ** Mem.xDel might not be initialized if MEM_Dyn is clear. */ @@ -79098,8 +79098,8 @@ SQLITE_PRIVATE int tdsqlite3VdbeCheckMemInvariants(Mem *p){ assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob|MEM_Agg))==0 ); /* If MEM_Null is set, then either the value is a pure NULL (the usual - ** case) or it is a pointer set using tdsqlite3_bind_pointer() or - ** tdsqlite3_result_pointer(). If a pointer, then MEM_Term must also be + ** case) or it is a pointer set using sqlite3_bind_pointer() or + ** sqlite3_result_pointer(). If a pointer, then MEM_Term must also be ** set. */ if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){ @@ -79123,7 +79123,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeCheckMemInvariants(Mem *p){ /* The szMalloc field holds the correct memory allocation size */ assert( p->szMalloc==0 - || p->szMalloc==tdsqlite3DbMallocSize(p->db,p->zMalloc) ); + || p->szMalloc==sqlite3DbMallocSize(p->db,p->zMalloc) ); /* If p holds a string or blob, the Mem.z must point to exactly ** one of the following: @@ -79152,16 +79152,16 @@ SQLITE_PRIVATE int tdsqlite3VdbeCheckMemInvariants(Mem *p){ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ StrAccum acc; assert( p->flags & (MEM_Int|MEM_Real|MEM_IntReal) ); - tdsqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); + sqlite3StrAccumInit(&acc, 0, zBuf, sz, 0); if( p->flags & MEM_Int ){ - tdsqlite3_str_appendf(&acc, "%lld", p->u.i); + sqlite3_str_appendf(&acc, "%lld", p->u.i); }else if( p->flags & MEM_IntReal ){ - tdsqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i); + sqlite3_str_appendf(&acc, "%!.15g", (double)p->u.i); }else{ - tdsqlite3_str_appendf(&acc, "%!.15g", p->u.r); + sqlite3_str_appendf(&acc, "%!.15g", p->u.r); } assert( acc.zText==zBuf && acc.mxAlloc<=0 ); - zBuf[acc.nChar] = 0; /* Fast version of tdsqlite3StrAccumFinish(&acc) */ + zBuf[acc.nChar] = 0; /* Fast version of sqlite3StrAccumFinish(&acc) */ } #ifdef SQLITE_DEBUG @@ -79187,7 +79187,7 @@ static void vdbeMemRenderNum(int sz, char *zBuf, Mem *p){ ** ** This routine is for use inside of assert() statements only. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemValidStrRep(Mem *p){ +SQLITE_PRIVATE int sqlite3VdbeMemValidStrRep(Mem *p){ char zBuf[100]; char *z; int i, j, incr; @@ -79233,17 +79233,17 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemValidStrRep(Mem *p){ ** SQLITE_NOMEM may be returned if a malloc() fails during conversion ** between formats. */ -SQLITE_PRIVATE int tdsqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ +SQLITE_PRIVATE int sqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ #ifndef SQLITE_OMIT_UTF16 int rc; #endif - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( desiredEnc==SQLITE_UTF8 || desiredEnc==SQLITE_UTF16LE || desiredEnc==SQLITE_UTF16BE ); if( !(pMem->flags&MEM_Str) || pMem->enc==desiredEnc ){ return SQLITE_OK; } - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); #ifdef SQLITE_OMIT_UTF16 return SQLITE_ERROR; #else @@ -79251,7 +79251,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ /* MemTranslate() may return SQLITE_OK or SQLITE_NOMEM. If NOMEM is returned, ** then the encoding of the value may not have changed. */ - rc = tdsqlite3VdbeMemTranslate(pMem, (u8)desiredEnc); + rc = sqlite3VdbeMemTranslate(pMem, (u8)desiredEnc); assert(rc==SQLITE_OK || rc==SQLITE_NOMEM); assert(rc==SQLITE_OK || pMem->enc!=desiredEnc); assert(rc==SQLITE_NOMEM || pMem->enc==desiredEnc); @@ -79267,9 +79267,9 @@ SQLITE_PRIVATE int tdsqlite3VdbeChangeEncoding(Mem *pMem, int desiredEnc){ ** blob if bPreserve is true. If bPreserve is false, any prior content ** in pMem->z is discarded. */ -SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ - assert( tdsqlite3VdbeCheckMemInvariants(pMem) ); - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ + assert( sqlite3VdbeCheckMemInvariants(pMem) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); testcase( pMem->db==0 ); /* If the bPreserve flag is set to true, then the memory cell must already @@ -79278,27 +79278,27 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3VdbeMemGrow(Mem *pMem, int n, int bP testcase( bPreserve && pMem->z==0 ); assert( pMem->szMalloc==0 - || pMem->szMalloc==tdsqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); + || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); if( pMem->szMalloc>0 && bPreserve && pMem->z==pMem->zMalloc ){ if( pMem->db ){ - pMem->z = pMem->zMalloc = tdsqlite3DbReallocOrFree(pMem->db, pMem->z, n); + pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); }else{ - pMem->zMalloc = tdsqlite3Realloc(pMem->z, n); - if( pMem->zMalloc==0 ) tdsqlite3_free(pMem->z); + pMem->zMalloc = sqlite3Realloc(pMem->z, n); + if( pMem->zMalloc==0 ) sqlite3_free(pMem->z); pMem->z = pMem->zMalloc; } bPreserve = 0; }else{ - if( pMem->szMalloc>0 ) tdsqlite3DbFreeNN(pMem->db, pMem->zMalloc); - pMem->zMalloc = tdsqlite3DbMallocRaw(pMem->db, n); + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); } if( pMem->zMalloc==0 ){ - tdsqlite3VdbeMemSetNull(pMem); + sqlite3VdbeMemSetNull(pMem); pMem->z = 0; pMem->szMalloc = 0; return SQLITE_NOMEM_BKPT; }else{ - pMem->szMalloc = tdsqlite3DbMallocSize(pMem->db, pMem->zMalloc); + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); } if( bPreserve && pMem->z ){ @@ -79328,11 +79328,11 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3VdbeMemGrow(Mem *pMem, int n, int bP ** Return SQLITE_OK on success or an error code (probably SQLITE_NOMEM) ** if unable to complete the resizing. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ +SQLITE_PRIVATE int sqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ assert( CORRUPT_DB || szNew>0 ); assert( (pMem->flags & MEM_Dyn)==0 || pMem->szMalloc==0 ); if( pMem->szMallocflags & MEM_Dyn)==0 ); pMem->z = pMem->zMalloc; @@ -79350,7 +79350,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemClearAndResize(Mem *pMem, int szNew){ ** is an odd number of bytes. */ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ - if( tdsqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){ + if( sqlite3VdbeMemGrow(pMem, pMem->n+3, 1) ){ return SQLITE_NOMEM_BKPT; } pMem->z[pMem->n] = 0; @@ -79366,9 +79366,9 @@ static SQLITE_NOINLINE int vdbeMemAddTerminator(Mem *pMem){ ** ** Return SQLITE_OK on success or SQLITE_NOMEM if malloc fails. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemMakeWriteable(Mem *pMem){ - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); +SQLITE_PRIVATE int sqlite3VdbeMemMakeWriteable(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); if( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ){ if( ExpandBlob(pMem) ) return SQLITE_NOMEM; if( pMem->szMalloc==0 || pMem->z!=pMem->zMalloc ){ @@ -79389,13 +79389,13 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemMakeWriteable(Mem *pMem){ ** blob stored in dynamically allocated space. */ #ifndef SQLITE_OMIT_INCRBLOB -SQLITE_PRIVATE int tdsqlite3VdbeMemExpandBlob(Mem *pMem){ +SQLITE_PRIVATE int sqlite3VdbeMemExpandBlob(Mem *pMem){ int nByte; assert( pMem->flags & MEM_Zero ); assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) ); - testcase( tdsqlite3_value_nochange(pMem) ); - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); + testcase( sqlite3_value_nochange(pMem) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); /* Set nByte to the number of bytes required to store the expanded blob. */ nByte = pMem->n + pMem->u.nZero; @@ -79403,7 +79403,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemExpandBlob(Mem *pMem){ if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK; nByte = 1; } - if( tdsqlite3VdbeMemGrow(pMem, nByte, 1) ){ + if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){ return SQLITE_NOMEM_BKPT; } @@ -79417,8 +79417,8 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemExpandBlob(Mem *pMem){ /* ** Make sure the given Mem is \u0000 terminated. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemNulTerminate(Mem *pMem){ - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); +SQLITE_PRIVATE int sqlite3VdbeMemNulTerminate(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); testcase( (pMem->flags & (MEM_Term|MEM_Str))==(MEM_Term|MEM_Str) ); testcase( (pMem->flags & (MEM_Term|MEM_Str))==0 ); if( (pMem->flags & (MEM_Term|MEM_Str))!=MEM_Str ){ @@ -79438,33 +79438,33 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemNulTerminate(Mem *pMem){ ** ** A MEM_Null value will never be passed to this function. This function is ** used for converting values to text for returning to the user (i.e. via -** tdsqlite3_value_text()), or for ensuring that values to be used as btree +** sqlite3_value_text()), or for ensuring that values to be used as btree ** keys are strings. In the former case a NULL pointer is returned the ** user and the latter is an internal programming error. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ +SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ const int nByte = 32; - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( !(pMem->flags&MEM_Zero) ); assert( !(pMem->flags&(MEM_Str|MEM_Blob)) ); assert( pMem->flags&(MEM_Int|MEM_Real|MEM_IntReal) ); - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - if( tdsqlite3VdbeMemClearAndResize(pMem, nByte) ){ + if( sqlite3VdbeMemClearAndResize(pMem, nByte) ){ pMem->enc = 0; return SQLITE_NOMEM_BKPT; } vdbeMemRenderNum(nByte, pMem->z, pMem); assert( pMem->z!=0 ); - pMem->n = tdsqlite3Strlen30NN(pMem->z); + pMem->n = sqlite3Strlen30NN(pMem->z); pMem->enc = SQLITE_UTF8; pMem->flags |= MEM_Str|MEM_Term; if( bForce ) pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal); - tdsqlite3VdbeChangeEncoding(pMem, enc); + sqlite3VdbeChangeEncoding(pMem, enc); return SQLITE_OK; } @@ -79476,13 +79476,13 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemStringify(Mem *pMem, u8 enc, u8 bForce){ ** Return SQLITE_ERROR if the finalizer reports an error. SQLITE_OK ** otherwise. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ - tdsqlite3_context ctx; +SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ + sqlite3_context ctx; Mem t; assert( pFunc!=0 ); assert( pFunc->xFinalize!=0 ); assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); memset(&ctx, 0, sizeof(ctx)); memset(&t, 0, sizeof(t)); t.flags = MEM_Null; @@ -79492,7 +79492,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ ctx.pFunc = pFunc; pFunc->xFinalize(&ctx); /* IMP: R-24505-23230 */ assert( (pMem->flags & MEM_Dyn)==0 ); - if( pMem->szMalloc>0 ) tdsqlite3DbFreeNN(pMem->db, pMem->zMalloc); + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); memcpy(pMem, &t, sizeof(t)); return ctx.isError; } @@ -79506,14 +79506,14 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ ** otherwise. */ #ifndef SQLITE_OMIT_WINDOWFUNC -SQLITE_PRIVATE int tdsqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ - tdsqlite3_context ctx; +SQLITE_PRIVATE int sqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFunc){ + sqlite3_context ctx; assert( pFunc!=0 ); assert( pFunc->xValue!=0 ); assert( (pAccum->flags & MEM_Null)!=0 || pFunc==pAccum->u.pDef ); - assert( pAccum->db==0 || tdsqlite3_mutex_held(pAccum->db->mutex) ); + assert( pAccum->db==0 || sqlite3_mutex_held(pAccum->db->mutex) ); memset(&ctx, 0, sizeof(ctx)); - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); ctx.pOut = pOut; ctx.pMem = pAccum; ctx.pFunc = pFunc; @@ -79527,15 +79527,15 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemAggValue(Mem *pAccum, Mem *pOut, FuncDef *pFu ** invoking the external callback in Mem.xDel, then this routine ** will free that value. It also sets Mem.flags to MEM_Null. ** -** This is a helper routine for tdsqlite3VdbeMemSetNull() and -** for tdsqlite3VdbeMemRelease(). Use those other routines as the +** This is a helper routine for sqlite3VdbeMemSetNull() and +** for sqlite3VdbeMemRelease(). Use those other routines as the ** entry point for releasing Mem resources. */ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ - assert( p->db==0 || tdsqlite3_mutex_held(p->db->mutex) ); + assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); assert( VdbeMemDynamic(p) ); if( p->flags&MEM_Agg ){ - tdsqlite3VdbeMemFinalize(p, p->u.pDef); + sqlite3VdbeMemFinalize(p, p->u.pDef); assert( (p->flags & MEM_Agg)==0 ); testcase( p->flags & MEM_Dyn ); } @@ -79550,7 +79550,7 @@ static SQLITE_NOINLINE void vdbeMemClearExternAndSetNull(Mem *p){ ** Release memory held by the Mem p, both external memory cleared ** by p->xDel and memory in p->zMalloc. ** -** This is a helper routine invoked by tdsqlite3VdbeMemRelease() in +** This is a helper routine invoked by sqlite3VdbeMemRelease() in ** the unusual case where there really is memory in p that needs ** to be freed. */ @@ -79559,7 +79559,7 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ vdbeMemClearExternAndSetNull(p); } if( p->szMalloc ){ - tdsqlite3DbFreeNN(p->db, p->zMalloc); + sqlite3DbFreeNN(p->db, p->zMalloc); p->szMalloc = 0; } p->z = 0; @@ -79572,11 +79572,11 @@ static SQLITE_NOINLINE void vdbeMemClear(Mem *p){ ** Use this routine prior to clean up prior to abandoning a Mem, or to ** reset a Mem back to its minimum memory utilization. ** -** Use tdsqlite3VdbeMemSetNull() to release just the Mem.xDel space +** Use sqlite3VdbeMemSetNull() to release just the Mem.xDel space ** prior to inserting new content into the Mem. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemRelease(Mem *p){ - assert( tdsqlite3VdbeCheckMemInvariants(p) ); +SQLITE_PRIVATE void sqlite3VdbeMemRelease(Mem *p){ + assert( sqlite3VdbeCheckMemInvariants(p) ); if( VdbeMemDynamic(p) || p->szMalloc ){ vdbeMemClear(p); } @@ -79625,12 +79625,12 @@ static SQLITE_NOINLINE i64 doubleToInt64(double r){ */ static SQLITE_NOINLINE i64 memIntValue(Mem *pMem){ i64 value = 0; - tdsqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); + sqlite3Atoi64(pMem->z, &value, pMem->n, pMem->enc); return value; } -SQLITE_PRIVATE i64 tdsqlite3VdbeIntValue(Mem *pMem){ +SQLITE_PRIVATE i64 sqlite3VdbeIntValue(Mem *pMem){ int flags; - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); flags = pMem->flags; if( flags & (MEM_Int|MEM_IntReal) ){ @@ -79654,11 +79654,11 @@ SQLITE_PRIVATE i64 tdsqlite3VdbeIntValue(Mem *pMem){ static SQLITE_NOINLINE double memRealValue(Mem *pMem){ /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ double val = (double)0; - tdsqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); + sqlite3AtoF(pMem->z, &val, pMem->n, pMem->enc); return val; } -SQLITE_PRIVATE double tdsqlite3VdbeRealValue(Mem *pMem){ - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); +SQLITE_PRIVATE double sqlite3VdbeRealValue(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); if( pMem->flags & MEM_Real ){ return pMem->u.r; @@ -79677,22 +79677,22 @@ SQLITE_PRIVATE double tdsqlite3VdbeRealValue(Mem *pMem){ ** Return 1 if pMem represents true, and return 0 if pMem represents false. ** Return the value ifNull if pMem is NULL. */ -SQLITE_PRIVATE int tdsqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ +SQLITE_PRIVATE int sqlite3VdbeBooleanValue(Mem *pMem, int ifNull){ testcase( pMem->flags & MEM_IntReal ); if( pMem->flags & (MEM_Int|MEM_IntReal) ) return pMem->u.i!=0; if( pMem->flags & MEM_Null ) return ifNull; - return tdsqlite3VdbeRealValue(pMem)!=0.0; + return sqlite3VdbeRealValue(pMem)!=0.0; } /* ** The MEM structure is already a MEM_Real. Try to also make it a ** MEM_Int if we can. */ -SQLITE_PRIVATE void tdsqlite3VdbeIntegerAffinity(Mem *pMem){ +SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ i64 ix; assert( pMem->flags & MEM_Real ); - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); ix = doubleToInt64(pMem->u.r); @@ -79716,12 +79716,12 @@ SQLITE_PRIVATE void tdsqlite3VdbeIntegerAffinity(Mem *pMem){ /* ** Convert pMem to type integer. Invalidate any prior representations. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemIntegerify(Mem *pMem){ - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); +SQLITE_PRIVATE int sqlite3VdbeMemIntegerify(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - pMem->u.i = tdsqlite3VdbeIntValue(pMem); + pMem->u.i = sqlite3VdbeIntValue(pMem); MemSetTypeFlag(pMem, MEM_Int); return SQLITE_OK; } @@ -79730,11 +79730,11 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemIntegerify(Mem *pMem){ ** Convert pMem so that it is of type MEM_Real. ** Invalidate any prior representations. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemRealify(Mem *pMem){ - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); +SQLITE_PRIVATE int sqlite3VdbeMemRealify(Mem *pMem){ + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); assert( EIGHT_BYTE_ALIGNMENT(pMem) ); - pMem->u.r = tdsqlite3VdbeRealValue(pMem); + pMem->u.r = sqlite3VdbeRealValue(pMem); MemSetTypeFlag(pMem, MEM_Real); return SQLITE_OK; } @@ -79748,7 +79748,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemRealify(Mem *pMem){ ** comparison of "r1==(double)i" you sometimes get an answer of false even ** though the r1 and (double)i values are bit-for-bit the same. */ -SQLITE_PRIVATE int tdsqlite3RealSameAsInt(double r1, tdsqlite3_int64 i){ +SQLITE_PRIVATE int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){ double r2 = (double)i; return r1==0.0 || (memcmp(&r1, &r2, sizeof(r1))==0 @@ -79763,19 +79763,19 @@ SQLITE_PRIVATE int tdsqlite3RealSameAsInt(double r1, tdsqlite3_int64 i){ ** is a string that does not look completely like a number. Convert ** as much of the string as we can and ignore the rest. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemNumerify(Mem *pMem){ +SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ testcase( pMem->flags & MEM_Int ); testcase( pMem->flags & MEM_Real ); testcase( pMem->flags & MEM_IntReal ); testcase( pMem->flags & MEM_Null ); if( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Null))==0 ){ int rc; - tdsqlite3_int64 ix; + sqlite3_int64 ix; assert( (pMem->flags & (MEM_Blob|MEM_Str))!=0 ); - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); - rc = tdsqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); - if( ((rc==0 || rc==1) && tdsqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1) - || tdsqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r)) + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); + if( ((rc==0 || rc==1) && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1) + || sqlite3RealSameAsInt(pMem->u.r, (ix = (i64)pMem->u.r)) ){ pMem->u.i = ix; MemSetTypeFlag(pMem, MEM_Int); @@ -79795,12 +79795,12 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemNumerify(Mem *pMem){ ** affinity even if that results in loss of data. This routine is ** used (for example) to implement the SQL "cast()" operator. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ +SQLITE_PRIVATE int sqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ if( pMem->flags & MEM_Null ) return SQLITE_OK; switch( aff ){ case SQLITE_AFF_BLOB: { /* Really a cast to BLOB */ if( (pMem->flags & MEM_Blob)==0 ){ - tdsqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); if( pMem->flags & MEM_Str ) MemSetTypeFlag(pMem, MEM_Blob); }else{ @@ -79809,25 +79809,25 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ break; } case SQLITE_AFF_NUMERIC: { - tdsqlite3VdbeMemNumerify(pMem); + sqlite3VdbeMemNumerify(pMem); break; } case SQLITE_AFF_INTEGER: { - tdsqlite3VdbeMemIntegerify(pMem); + sqlite3VdbeMemIntegerify(pMem); break; } case SQLITE_AFF_REAL: { - tdsqlite3VdbeMemRealify(pMem); + sqlite3VdbeMemRealify(pMem); break; } default: { assert( aff==SQLITE_AFF_TEXT ); assert( MEM_Str==(MEM_Blob>>3) ); pMem->flags |= (pMem->flags&MEM_Blob)>>3; - tdsqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); + sqlite3ValueApplyAffinity(pMem, SQLITE_AFF_TEXT, encoding); assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); - return tdsqlite3VdbeChangeEncoding(pMem, encoding); + return sqlite3VdbeChangeEncoding(pMem, encoding); } } return SQLITE_OK; @@ -79838,7 +79838,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemCast(Mem *pMem, u8 aff, u8 encoding){ ** ** The minimum amount of initialization feasible is performed. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemInit(Mem *pMem, tdsqlite3 *db, u16 flags){ +SQLITE_PRIVATE void sqlite3VdbeMemInit(Mem *pMem, sqlite3 *db, u16 flags){ assert( (flags & ~MEM_TypeMask)==0 ); pMem->flags = flags; pMem->db = db; @@ -79851,30 +79851,30 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemInit(Mem *pMem, tdsqlite3 *db, u16 flags){ ** ** This routine calls the Mem.xDel destructor to dispose of values that ** require the destructor. But it preserves the Mem.zMalloc memory allocation. -** To free all resources, use tdsqlite3VdbeMemRelease(), which both calls this +** To free all resources, use sqlite3VdbeMemRelease(), which both calls this ** routine to invoke the destructor and deallocates Mem.zMalloc. ** ** Use this routine to reset the Mem prior to insert a new value. ** -** Use tdsqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it. +** Use sqlite3VdbeMemRelease() to complete erase the Mem prior to abandoning it. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemSetNull(Mem *pMem){ +SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ if( VdbeMemDynamic(pMem) ){ vdbeMemClearExternAndSetNull(pMem); }else{ pMem->flags = MEM_Null; } } -SQLITE_PRIVATE void tdsqlite3ValueSetNull(tdsqlite3_value *p){ - tdsqlite3VdbeMemSetNull((Mem*)p); +SQLITE_PRIVATE void sqlite3ValueSetNull(sqlite3_value *p){ + sqlite3VdbeMemSetNull((Mem*)p); } /* ** Delete any previous value and set the value to be a BLOB of length ** n containing all zeros. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ - tdsqlite3VdbeMemRelease(pMem); +SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ + sqlite3VdbeMemRelease(pMem); pMem->flags = MEM_Blob|MEM_Zero; pMem->n = 0; if( n<0 ) n = 0; @@ -79889,7 +79889,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ ** a 64-bit integer. */ static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ - tdsqlite3VdbeMemSetNull(pMem); + sqlite3VdbeMemSetNull(pMem); pMem->u.i = val; pMem->flags = MEM_Int; } @@ -79898,7 +79898,7 @@ static SQLITE_NOINLINE void vdbeReleaseAndSetInt64(Mem *pMem, i64 val){ ** Delete any previous value and set the value stored in *pMem to val, ** manifest type INTEGER. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ +SQLITE_PRIVATE void sqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ if( VdbeMemDynamic(pMem) ){ vdbeReleaseAndSetInt64(pMem, val); }else{ @@ -79908,13 +79908,13 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemSetInt64(Mem *pMem, i64 val){ } /* A no-op destructor */ -SQLITE_PRIVATE void tdsqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } +SQLITE_PRIVATE void sqlite3NoopDestructor(void *p){ UNUSED_PARAMETER(p); } /* ** Set the value stored in *pMem should already be a NULL. ** Also store a pointer to go with it. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemSetPointer( +SQLITE_PRIVATE void sqlite3VdbeMemSetPointer( Mem *pMem, void *pPtr, const char *zPType, @@ -79925,7 +79925,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemSetPointer( pMem->z = pPtr; pMem->flags = MEM_Null|MEM_Dyn|MEM_Subtype|MEM_Term; pMem->eSubtype = 'p'; - pMem->xDel = xDestructor ? xDestructor : tdsqlite3NoopDestructor; + pMem->xDel = xDestructor ? xDestructor : sqlite3NoopDestructor; } #ifndef SQLITE_OMIT_FLOATING_POINT @@ -79933,9 +79933,9 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemSetPointer( ** Delete any previous value and set the value stored in *pMem to val, ** manifest type REAL. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemSetDouble(Mem *pMem, double val){ - tdsqlite3VdbeMemSetNull(pMem); - if( !tdsqlite3IsNaN(val) ){ +SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ + sqlite3VdbeMemSetNull(pMem); + if( !sqlite3IsNaN(val) ){ pMem->u.r = val; pMem->flags = MEM_Real; } @@ -79947,9 +79947,9 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemSetDouble(Mem *pMem, double val){ ** Return true if the Mem holds a RowSet object. This routine is intended ** for use inside of assert() statements. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemIsRowSet(const Mem *pMem){ +SQLITE_PRIVATE int sqlite3VdbeMemIsRowSet(const Mem *pMem){ return (pMem->flags&(MEM_Blob|MEM_Dyn))==(MEM_Blob|MEM_Dyn) - && pMem->xDel==tdsqlite3RowSetDelete; + && pMem->xDel==sqlite3RowSetDelete; } #endif @@ -79960,17 +79960,17 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemIsRowSet(const Mem *pMem){ ** Return SQLITE_OK on success and SQLITE_NOMEM if a memory allocation ** error occurs. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemSetRowSet(Mem *pMem){ - tdsqlite3 *db = pMem->db; +SQLITE_PRIVATE int sqlite3VdbeMemSetRowSet(Mem *pMem){ + sqlite3 *db = pMem->db; RowSet *p; assert( db!=0 ); - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); - tdsqlite3VdbeMemRelease(pMem); - p = tdsqlite3RowSetInit(db); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + sqlite3VdbeMemRelease(pMem); + p = sqlite3RowSetInit(db); if( p==0 ) return SQLITE_NOMEM; pMem->z = (char*)p; pMem->flags = MEM_Blob|MEM_Dyn; - pMem->xDel = tdsqlite3RowSetDelete; + pMem->xDel = sqlite3RowSetDelete; return SQLITE_OK; } @@ -79978,7 +79978,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemSetRowSet(Mem *pMem){ ** Return true if the Mem object contains a TEXT or BLOB that is ** too large - whose size exceeds SQLITE_MAX_LENGTH. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemTooBig(Mem *p){ +SQLITE_PRIVATE int sqlite3VdbeMemTooBig(Mem *p){ assert( p->db!=0 ); if( p->flags & (MEM_Str|MEM_Blob) ){ int n = p->n; @@ -79999,14 +79999,14 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemTooBig(Mem *p){ ** This is used for testing and debugging only - to help ensure that shallow ** copies (created by OP_SCopy) are not misused. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ +SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ int i; Mem *pX; for(i=1, pX=pVdbe->aMem+1; inMem; i++, pX++){ if( pX->pScopyFrom==pMem ){ u16 mFlags; if( pVdbe->db->flags & SQLITE_VdbeTrace ){ - tdsqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n", + sqlite3DebugPrintf("Invalidate R[%d] due to change in R[%d]\n", (int)(pX - pVdbe->aMem), (int)(pMem - pVdbe->aMem)); } /* If pX is marked as a shallow copy of pMem, then verify that @@ -80021,7 +80021,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ /* ^^ */ /* Cannot reliably compare doubles for equality */ assert( (mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z) ); - assert( (mFlags&MEM_Blob)==0 || tdsqlite3BlobCompare(pMem,pX)==0 ); + assert( (mFlags&MEM_Blob)==0 || sqlite3BlobCompare(pMem,pX)==0 ); /* pMem is the register that is changing. But also mark pX as ** undefined so that we can quickly detect the shallow-copy error */ @@ -80042,10 +80042,10 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ static SQLITE_NOINLINE void vdbeClrCopy(Mem *pTo, const Mem *pFrom, int eType){ vdbeMemClearExternAndSetNull(pTo); assert( !VdbeMemDynamic(pTo) ); - tdsqlite3VdbeMemShallowCopy(pTo, pFrom, eType); + sqlite3VdbeMemShallowCopy(pTo, pFrom, eType); } -SQLITE_PRIVATE void tdsqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ - assert( !tdsqlite3VdbeMemIsRowSet(pFrom) ); +SQLITE_PRIVATE void sqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int srcType){ + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); assert( pTo->db==pFrom->db ); if( VdbeMemDynamic(pTo) ){ vdbeClrCopy(pTo,pFrom,srcType); return; } memcpy(pTo, pFrom, MEMCELLSIZE); @@ -80060,17 +80060,17 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemShallowCopy(Mem *pTo, const Mem *pFrom, int ** Make a full copy of pFrom into pTo. Prior contents of pTo are ** freed before the copy is made. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ +SQLITE_PRIVATE int sqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ int rc = SQLITE_OK; - assert( !tdsqlite3VdbeMemIsRowSet(pFrom) ); + assert( !sqlite3VdbeMemIsRowSet(pFrom) ); if( VdbeMemDynamic(pTo) ) vdbeMemClearExternAndSetNull(pTo); memcpy(pTo, pFrom, MEMCELLSIZE); pTo->flags &= ~MEM_Dyn; if( pTo->flags&(MEM_Str|MEM_Blob) ){ if( 0==(pFrom->flags&MEM_Static) ){ pTo->flags |= MEM_Ephem; - rc = tdsqlite3VdbeMemMakeWriteable(pTo); + rc = sqlite3VdbeMemMakeWriteable(pTo); } } @@ -80083,12 +80083,12 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemCopy(Mem *pTo, const Mem *pFrom){ ** ** pFrom contains an SQL NULL when this routine returns. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ - assert( pFrom->db==0 || tdsqlite3_mutex_held(pFrom->db->mutex) ); - assert( pTo->db==0 || tdsqlite3_mutex_held(pTo->db->mutex) ); +SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ + assert( pFrom->db==0 || sqlite3_mutex_held(pFrom->db->mutex) ); + assert( pTo->db==0 || sqlite3_mutex_held(pTo->db->mutex) ); assert( pFrom->db==0 || pTo->db==0 || pFrom->db==pTo->db ); - tdsqlite3VdbeMemRelease(pTo); + sqlite3VdbeMemRelease(pTo); memcpy(pTo, pFrom, sizeof(Mem)); pFrom->flags = MEM_Null; pFrom->szMalloc = 0; @@ -80109,7 +80109,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ ** is required to store the string, then value of pMem is unchanged. In ** either case, SQLITE_TOOBIG is returned. */ -SQLITE_PRIVATE int tdsqlite3VdbeMemSetStr( +SQLITE_PRIVATE int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ const char *z, /* String pointer */ int n, /* Bytes in string, or negative */ @@ -80120,12 +80120,12 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemSetStr( int iLimit; /* Maximum allowed string or blob size */ u16 flags = 0; /* New value for pMem->flags */ - assert( pMem->db==0 || tdsqlite3_mutex_held(pMem->db->mutex) ); - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); + assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); /* If z is a NULL pointer, set pMem to contain an SQL NULL. */ if( !z ){ - tdsqlite3VdbeMemSetNull(pMem); + sqlite3VdbeMemSetNull(pMem); return SQLITE_OK; } @@ -80155,21 +80155,21 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemSetStr( nAlloc += (enc==SQLITE_UTF8?1:2); } if( nByte>iLimit ){ - return tdsqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); + return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG); } testcase( nAlloc==0 ); testcase( nAlloc==31 ); testcase( nAlloc==32 ); - if( tdsqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){ + if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){ return SQLITE_NOMEM_BKPT; } memcpy(pMem->z, z, nAlloc); }else{ - tdsqlite3VdbeMemRelease(pMem); + sqlite3VdbeMemRelease(pMem); pMem->z = (char *)z; if( xDel==SQLITE_DYNAMIC ){ pMem->zMalloc = pMem->z; - pMem->szMalloc = tdsqlite3DbMallocSize(pMem->db, pMem->zMalloc); + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); }else{ pMem->xDel = xDel; flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); @@ -80190,7 +80190,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemSetStr( } #ifndef SQLITE_OMIT_UTF16 - if( enc>SQLITE_UTF8 && tdsqlite3VdbeMemHandleBom(pMem) ){ + if( enc>SQLITE_UTF8 && sqlite3VdbeMemHandleBom(pMem) ){ return SQLITE_NOMEM_BKPT; } #endif @@ -80225,22 +80225,22 @@ static SQLITE_NOINLINE int vdbeMemFromBtreeResize( ){ int rc; pMem->flags = MEM_Null; - if( tdsqlite3BtreeMaxRecordSize(pCur)z); + if( SQLITE_OK==(rc = sqlite3VdbeMemClearAndResize(pMem, amt+1)) ){ + rc = sqlite3BtreePayload(pCur, offset, amt, pMem->z); if( rc==SQLITE_OK ){ pMem->z[amt] = 0; /* Overrun area used when reading malformed records */ pMem->flags = MEM_Blob; pMem->n = (int)amt; }else{ - tdsqlite3VdbeMemRelease(pMem); + sqlite3VdbeMemRelease(pMem); } } return rc; } -SQLITE_PRIVATE int tdsqlite3VdbeMemFromBtree( +SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( BtCursor *pCur, /* Cursor pointing at record to retrieve. */ u32 offset, /* Offset from the start of data to return bytes from. */ u32 amt, /* Number of bytes to return. */ @@ -80250,13 +80250,13 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemFromBtree( u32 available = 0; /* Number of bytes available on the local btree page */ int rc = SQLITE_OK; /* Return code */ - assert( tdsqlite3BtreeCursorIsValid(pCur) ); + assert( sqlite3BtreeCursorIsValid(pCur) ); assert( !VdbeMemDynamic(pMem) ); /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ - assert( !tdsqlite3VdbeMemIsRowSet(pMem) ); - zData = (char *)tdsqlite3BtreePayloadFetch(pCur, &available); + assert( !sqlite3VdbeMemIsRowSet(pMem) ); + zData = (char *)sqlite3BtreePayloadFetch(pCur, &available); assert( zData!=0 ); if( offset+amt<=available ){ @@ -80275,33 +80275,33 @@ SQLITE_PRIVATE int tdsqlite3VdbeMemFromBtree( ** Convert it into a string with encoding enc and return a pointer ** to a zero-terminated version of that string. */ -static SQLITE_NOINLINE const void *valueToText(tdsqlite3_value* pVal, u8 enc){ +static SQLITE_NOINLINE const void *valueToText(sqlite3_value* pVal, u8 enc){ assert( pVal!=0 ); - assert( pVal->db==0 || tdsqlite3_mutex_held(pVal->db->mutex) ); + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); - assert( !tdsqlite3VdbeMemIsRowSet(pVal) ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); assert( (pVal->flags & (MEM_Null))==0 ); if( pVal->flags & (MEM_Blob|MEM_Str) ){ if( ExpandBlob(pVal) ) return 0; pVal->flags |= MEM_Str; if( pVal->enc != (enc & ~SQLITE_UTF16_ALIGNED) ){ - tdsqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); + sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED); } if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){ assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 ); - if( tdsqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ + if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){ return 0; } } - tdsqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ + sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */ }else{ - tdsqlite3VdbeMemStringify(pVal, enc, 0); + sqlite3VdbeMemStringify(pVal, enc, 0); assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) ); } assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0 || pVal->db->mallocFailed ); if( pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) ){ - assert( tdsqlite3VdbeMemValidStrRep(pVal) ); + assert( sqlite3VdbeMemValidStrRep(pVal) ); return pVal->z; }else{ return 0; @@ -80309,7 +80309,7 @@ static SQLITE_NOINLINE const void *valueToText(tdsqlite3_value* pVal, u8 enc){ } /* This function is only available internally, it is not part of the -** external API. It works in a similar way to tdsqlite3_value_text(), +** external API. It works in a similar way to sqlite3_value_text(), ** except the data returned is in the encoding specified by the second ** parameter, which must be one of SQLITE_UTF16BE, SQLITE_UTF16LE or ** SQLITE_UTF8. @@ -80318,13 +80318,13 @@ static SQLITE_NOINLINE const void *valueToText(tdsqlite3_value* pVal, u8 enc){ ** If that is the case, then the result must be aligned on an even byte ** boundary. */ -SQLITE_PRIVATE const void *tdsqlite3ValueText(tdsqlite3_value* pVal, u8 enc){ +SQLITE_PRIVATE const void *sqlite3ValueText(sqlite3_value* pVal, u8 enc){ if( !pVal ) return 0; - assert( pVal->db==0 || tdsqlite3_mutex_held(pVal->db->mutex) ); + assert( pVal->db==0 || sqlite3_mutex_held(pVal->db->mutex) ); assert( (enc&3)==(enc&~SQLITE_UTF16_ALIGNED) ); - assert( !tdsqlite3VdbeMemIsRowSet(pVal) ); + assert( !sqlite3VdbeMemIsRowSet(pVal) ); if( (pVal->flags&(MEM_Str|MEM_Term))==(MEM_Str|MEM_Term) && pVal->enc==enc ){ - assert( tdsqlite3VdbeMemValidStrRep(pVal) ); + assert( sqlite3VdbeMemValidStrRep(pVal) ); return pVal->z; } if( pVal->flags&MEM_Null ){ @@ -80334,10 +80334,10 @@ SQLITE_PRIVATE const void *tdsqlite3ValueText(tdsqlite3_value* pVal, u8 enc){ } /* -** Create a new tdsqlite3_value object. +** Create a new sqlite3_value object. */ -SQLITE_PRIVATE tdsqlite3_value *tdsqlite3ValueNew(tdsqlite3 *db){ - Mem *p = tdsqlite3DbMallocZero(db, sizeof(*p)); +SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *db){ + Mem *p = sqlite3DbMallocZero(db, sizeof(*p)); if( p ){ p->flags = MEM_Null; p->db = db; @@ -80346,7 +80346,7 @@ SQLITE_PRIVATE tdsqlite3_value *tdsqlite3ValueNew(tdsqlite3 *db){ } /* -** Context object passed by tdsqlite3Stat4ProbeSetValue() through to +** Context object passed by sqlite3Stat4ProbeSetValue() through to ** valueNew(). See comments above valueNew() for details. */ struct ValueNewStat4Ctx { @@ -80357,17 +80357,17 @@ struct ValueNewStat4Ctx { }; /* -** Allocate and return a pointer to a new tdsqlite3_value object. If +** Allocate and return a pointer to a new sqlite3_value object. If ** the second argument to this function is NULL, the object is allocated -** by calling tdsqlite3ValueNew(). +** by calling sqlite3ValueNew(). ** ** Otherwise, if the second argument is non-zero, then this function is -** being called indirectly by tdsqlite3Stat4ProbeSetValue(). If it has not +** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not ** already been allocated, allocate the UnpackedRecord structure that ** that function will return to its caller here. Then return a pointer to -** an tdsqlite3_value within the UnpackedRecord.a[] array. +** an sqlite3_value within the UnpackedRecord.a[] array. */ -static tdsqlite3_value *valueNew(tdsqlite3 *db, struct ValueNewStat4Ctx *p){ +static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ #ifdef SQLITE_ENABLE_STAT4 if( p ){ UnpackedRecord *pRec = p->ppRec[0]; @@ -80379,9 +80379,9 @@ static tdsqlite3_value *valueNew(tdsqlite3 *db, struct ValueNewStat4Ctx *p){ int nCol = pIdx->nColumn; /* Number of index columns including rowid */ nByte = sizeof(Mem) * nCol + ROUND8(sizeof(UnpackedRecord)); - pRec = (UnpackedRecord*)tdsqlite3DbMallocZero(db, nByte); + pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); if( pRec ){ - pRec->pKeyInfo = tdsqlite3KeyInfoOfIndex(p->pParse, pIdx); + pRec->pKeyInfo = sqlite3KeyInfoOfIndex(p->pParse, pIdx); if( pRec->pKeyInfo ){ assert( pRec->pKeyInfo->nAllField==nCol ); assert( pRec->pKeyInfo->enc==ENC(db) ); @@ -80391,7 +80391,7 @@ static tdsqlite3_value *valueNew(tdsqlite3 *db, struct ValueNewStat4Ctx *p){ pRec->aMem[i].db = db; } }else{ - tdsqlite3DbFreeNN(db, pRec); + sqlite3DbFreeNN(db, pRec); pRec = 0; } } @@ -80405,7 +80405,7 @@ static tdsqlite3_value *valueNew(tdsqlite3 *db, struct ValueNewStat4Ctx *p){ #else UNUSED_PARAMETER(p); #endif /* defined(SQLITE_ENABLE_STAT4) */ - return tdsqlite3ValueNew(db); + return sqlite3ValueNew(db); } /* @@ -80421,7 +80421,7 @@ static tdsqlite3_value *valueNew(tdsqlite3 *db, struct ValueNewStat4Ctx *p){ ** object containing the result before returning SQLITE_OK. ** ** Affinity aff is applied to the result of the function before returning. -** If the result is a text value, the tdsqlite3_value object uses encoding +** If the result is a text value, the sqlite3_value object uses encoding ** enc. ** ** If the conditions above are not met, this function returns SQLITE_OK @@ -80430,18 +80430,18 @@ static tdsqlite3_value *valueNew(tdsqlite3 *db, struct ValueNewStat4Ctx *p){ */ #ifdef SQLITE_ENABLE_STAT4 static int valueFromFunction( - tdsqlite3 *db, /* The database connection */ + sqlite3 *db, /* The database connection */ Expr *p, /* The expression to evaluate */ u8 enc, /* Encoding to use */ u8 aff, /* Affinity to use */ - tdsqlite3_value **ppVal, /* Write the new value here */ + sqlite3_value **ppVal, /* Write the new value here */ struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ ){ - tdsqlite3_context ctx; /* Context object for function invocation */ - tdsqlite3_value **apVal = 0; /* Function arguments */ + sqlite3_context ctx; /* Context object for function invocation */ + sqlite3_value **apVal = 0; /* Function arguments */ int nVal = 0; /* Size of apVal[] array */ FuncDef *pFunc = 0; /* Function definition */ - tdsqlite3_value *pVal = 0; /* New value */ + sqlite3_value *pVal = 0; /* New value */ int rc = SQLITE_OK; /* Return code */ ExprList *pList = 0; /* Function arguments */ int i; /* Iterator variable */ @@ -80450,7 +80450,7 @@ static int valueFromFunction( assert( (p->flags & EP_TokenOnly)==0 ); pList = p->x.pList; if( pList ) nVal = pList->nExpr; - pFunc = tdsqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); + pFunc = sqlite3FindFunction(db, p->u.zToken, nVal, enc, 0); assert( pFunc ); if( (pFunc->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0 || (pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) @@ -80459,13 +80459,13 @@ static int valueFromFunction( } if( pList ){ - apVal = (tdsqlite3_value**)tdsqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); + apVal = (sqlite3_value**)sqlite3DbMallocZero(db, sizeof(apVal[0]) * nVal); if( apVal==0 ){ rc = SQLITE_NOMEM_BKPT; goto value_from_function_out; } for(i=0; ia[i].pExpr, enc, aff, &apVal[i]); + rc = sqlite3ValueFromExpr(db, pList->a[i].pExpr, enc, aff, &apVal[i]); if( apVal[i]==0 || rc!=SQLITE_OK ) goto value_from_function_out; } } @@ -80483,12 +80483,12 @@ static int valueFromFunction( pFunc->xSFunc(&ctx, nVal, apVal); if( ctx.isError ){ rc = ctx.isError; - tdsqlite3ErrorMsg(pCtx->pParse, "%s", tdsqlite3_value_text(pVal)); + sqlite3ErrorMsg(pCtx->pParse, "%s", sqlite3_value_text(pVal)); }else{ - tdsqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); + sqlite3ValueApplyAffinity(pVal, aff, SQLITE_UTF8); assert( rc==SQLITE_OK ); - rc = tdsqlite3VdbeChangeEncoding(pVal, enc); - if( rc==SQLITE_OK && tdsqlite3VdbeMemTooBig(pVal) ){ + rc = sqlite3VdbeChangeEncoding(pVal, enc); + if( rc==SQLITE_OK && sqlite3VdbeMemTooBig(pVal) ){ rc = SQLITE_TOOBIG; pCtx->pParse->nErr++; } @@ -80501,9 +80501,9 @@ static int valueFromFunction( } if( apVal ){ for(i=0; iflags & EP_TokenOnly)==0 || pCtx==0 ); if( op==TK_CAST ){ - u8 aff = tdsqlite3AffinityType(pExpr->u.zToken,0); + u8 aff = sqlite3AffinityType(pExpr->u.zToken,0); rc = valueFromExpr(db, pExpr->pLeft, enc, aff, ppVal, pCtx); testcase( rc!=SQLITE_OK ); if( *ppVal ){ - tdsqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8); - tdsqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8); + sqlite3VdbeMemCast(*ppVal, aff, SQLITE_UTF8); + sqlite3ValueApplyAffinity(*ppVal, affinity, SQLITE_UTF8); } return rc; } @@ -80578,16 +80578,16 @@ static int valueFromExpr( pVal = valueNew(db, pCtx); if( pVal==0 ) goto no_mem; if( ExprHasProperty(pExpr, EP_IntValue) ){ - tdsqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); + sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); }else{ - zVal = tdsqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); + zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); if( zVal==0 ) goto no_mem; - tdsqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); } if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_BLOB ){ - tdsqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); + sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); }else{ - tdsqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); + sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); } assert( (pVal->flags & MEM_IntReal)==0 ); if( pVal->flags & (MEM_Int|MEM_IntReal|MEM_Real) ){ @@ -80596,14 +80596,14 @@ static int valueFromExpr( pVal->flags &= ~MEM_Str; } if( enc!=SQLITE_UTF8 ){ - rc = tdsqlite3VdbeChangeEncoding(pVal, enc); + rc = sqlite3VdbeChangeEncoding(pVal, enc); } }else if( op==TK_UMINUS ) { /* This branch happens for multiple negative signs. Ex: -(-5) */ if( SQLITE_OK==valueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal,pCtx) && pVal!=0 ){ - tdsqlite3VdbeMemNumerify(pVal); + sqlite3VdbeMemNumerify(pVal); if( pVal->flags & MEM_Real ){ pVal->u.r = -pVal->u.r; }else if( pVal->u.i==SMALLEST_INT64 ){ @@ -80616,12 +80616,12 @@ static int valueFromExpr( }else{ pVal->u.i = -pVal->u.i; } - tdsqlite3ValueApplyAffinity(pVal, affinity, enc); + sqlite3ValueApplyAffinity(pVal, affinity, enc); } }else if( op==TK_NULL ){ pVal = valueNew(db, pCtx); if( pVal==0 ) goto no_mem; - tdsqlite3VdbeMemSetNull(pVal); + sqlite3VdbeMemSetNull(pVal); } #ifndef SQLITE_OMIT_BLOB_LITERAL else if( op==TK_BLOB ){ @@ -80631,9 +80631,9 @@ static int valueFromExpr( pVal = valueNew(db, pCtx); if( !pVal ) goto no_mem; zVal = &pExpr->u.zToken[2]; - nVal = tdsqlite3Strlen30(zVal)-1; + nVal = sqlite3Strlen30(zVal)-1; assert( zVal[nVal]=='\'' ); - tdsqlite3VdbeMemSetStr(pVal, tdsqlite3HexToBlob(db, zVal, nVal), nVal/2, + sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, 0, SQLITE_DYNAMIC); } #endif @@ -80657,33 +80657,33 @@ no_mem: #ifdef SQLITE_ENABLE_STAT4 if( pCtx==0 || pCtx->pParse->nErr==0 ) #endif - tdsqlite3OomFault(db); - tdsqlite3DbFree(db, zVal); + sqlite3OomFault(db); + sqlite3DbFree(db, zVal); assert( *ppVal==0 ); #ifdef SQLITE_ENABLE_STAT4 - if( pCtx==0 ) tdsqlite3ValueFree(pVal); + if( pCtx==0 ) sqlite3ValueFree(pVal); #else - assert( pCtx==0 ); tdsqlite3ValueFree(pVal); + assert( pCtx==0 ); sqlite3ValueFree(pVal); #endif return SQLITE_NOMEM_BKPT; } /* -** Create a new tdsqlite3_value object, containing the value of pExpr. +** Create a new sqlite3_value object, containing the value of pExpr. ** ** This only works for very simple expressions that consist of one constant ** token (i.e. "5", "5.1", "'a string'"). If the expression can ** be converted directly into a value, then the value is allocated and ** a pointer written to *ppVal. The caller is responsible for deallocating -** the value by passing it to tdsqlite3ValueFree() later on. If the expression +** the value by passing it to sqlite3ValueFree() later on. If the expression ** cannot be converted to a value, then *ppVal is set to NULL. */ -SQLITE_PRIVATE int tdsqlite3ValueFromExpr( - tdsqlite3 *db, /* The database connection */ +SQLITE_PRIVATE int sqlite3ValueFromExpr( + sqlite3 *db, /* The database connection */ Expr *pExpr, /* The expression to evaluate */ u8 enc, /* Encoding to use */ u8 affinity, /* Affinity to use */ - tdsqlite3_value **ppVal /* Write the new value here */ + sqlite3_value **ppVal /* Write the new value here */ ){ return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0; } @@ -80712,30 +80712,30 @@ static int stat4ValueFromExpr( Expr *pExpr, /* The expression to extract a value from */ u8 affinity, /* Affinity to use */ struct ValueNewStat4Ctx *pAlloc,/* How to allocate space. Or NULL */ - tdsqlite3_value **ppVal /* OUT: New value object (or NULL) */ + sqlite3_value **ppVal /* OUT: New value object (or NULL) */ ){ int rc = SQLITE_OK; - tdsqlite3_value *pVal = 0; - tdsqlite3 *db = pParse->db; + sqlite3_value *pVal = 0; + sqlite3 *db = pParse->db; /* Skip over any TK_COLLATE nodes */ - pExpr = tdsqlite3ExprSkipCollate(pExpr); + pExpr = sqlite3ExprSkipCollate(pExpr); assert( pExpr==0 || pExpr->op!=TK_REGISTER || pExpr->op2!=TK_VARIABLE ); if( !pExpr ){ pVal = valueNew(db, pAlloc); if( pVal ){ - tdsqlite3VdbeMemSetNull((Mem*)pVal); + sqlite3VdbeMemSetNull((Mem*)pVal); } }else if( pExpr->op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){ Vdbe *v; int iBindVar = pExpr->iColumn; - tdsqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); + sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); if( (v = pParse->pReprepare)!=0 ){ pVal = valueNew(db, pAlloc); if( pVal ){ - rc = tdsqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); - tdsqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); + rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); + sqlite3ValueApplyAffinity(pVal, affinity, ENC(db)); pVal->db = pParse->db; } } @@ -80761,7 +80761,7 @@ static int stat4ValueFromExpr( ** ** * The expression is a bound variable, and this is a reprepare, or ** -** * The tdsqlite3ValueFromExpr() function is able to extract a value +** * The sqlite3ValueFromExpr() function is able to extract a value ** from the expression (i.e. the expression is a literal value). ** ** Or, if pExpr is a TK_VECTOR, one field is populated for each of the @@ -80782,7 +80782,7 @@ static int stat4ValueFromExpr( ** error if a value cannot be extracted from pExpr. If an error does ** occur, an SQLite error code is returned. */ -SQLITE_PRIVATE int tdsqlite3Stat4ProbeSetValue( +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( Parse *pParse, /* Parse context */ Index *pIdx, /* Index being probed */ UnpackedRecord **ppRec, /* IN/OUT: Probe record */ @@ -80803,9 +80803,9 @@ SQLITE_PRIVATE int tdsqlite3Stat4ProbeSetValue( alloc.ppRec = ppRec; for(i=0; idb, pIdx, iVal+i); + sqlite3_value *pVal = 0; + Expr *pElem = (pExpr ? sqlite3VectorFieldSubexpr(pExpr, i) : 0); + u8 aff = sqlite3IndexColumnAffinity(pParse->db, pIdx, iVal+i); alloc.iVal = iVal+i; rc = stat4ValueFromExpr(pParse, pElem, aff, &alloc, &pVal); if( !pVal ) break; @@ -80819,7 +80819,7 @@ SQLITE_PRIVATE int tdsqlite3Stat4ProbeSetValue( /* ** Attempt to extract a value from expression pExpr using the methods -** as described for tdsqlite3Stat4ProbeSetValue() above. +** as described for sqlite3Stat4ProbeSetValue() above. ** ** If successful, set *ppVal to point to a new value object and return ** SQLITE_OK. If no value can be extracted, but no other error occurs @@ -80827,11 +80827,11 @@ SQLITE_PRIVATE int tdsqlite3Stat4ProbeSetValue( ** does occur, return an SQLite error code. The final value of *ppVal ** is undefined in this case. */ -SQLITE_PRIVATE int tdsqlite3Stat4ValueFromExpr( +SQLITE_PRIVATE int sqlite3Stat4ValueFromExpr( Parse *pParse, /* Parse context */ Expr *pExpr, /* The expression to extract a value from */ u8 affinity, /* Affinity to use */ - tdsqlite3_value **ppVal /* OUT: New value object (or NULL) */ + sqlite3_value **ppVal /* OUT: New value object (or NULL) */ ){ return stat4ValueFromExpr(pParse, pExpr, affinity, 0, ppVal); } @@ -80839,17 +80839,17 @@ SQLITE_PRIVATE int tdsqlite3Stat4ValueFromExpr( /* ** Extract the iCol-th column from the nRec-byte record in pRec. Write ** the column value into *ppVal. If *ppVal is initially NULL then a new -** tdsqlite3_value object is allocated. +** sqlite3_value object is allocated. ** ** If *ppVal is initially NULL then the caller is responsible for ** ensuring that the value written into *ppVal is eventually freed. */ -SQLITE_PRIVATE int tdsqlite3Stat4Column( - tdsqlite3 *db, /* Database handle */ +SQLITE_PRIVATE int sqlite3Stat4Column( + sqlite3 *db, /* Database handle */ const void *pRec, /* Pointer to buffer containing record */ int nRec, /* Size of buffer pRec in bytes */ int iCol, /* Column to extract */ - tdsqlite3_value **ppVal /* OUT: Extracted value */ + sqlite3_value **ppVal /* OUT: Extracted value */ ){ u32 t = 0; /* a column type code */ int nHdr; /* Size of the header in the record */ @@ -80869,72 +80869,72 @@ SQLITE_PRIVATE int tdsqlite3Stat4Column( testcase( iHdr==nHdr ); testcase( iHdr==nHdr+1 ); if( iHdr>nHdr ) return SQLITE_CORRUPT_BKPT; - szField = tdsqlite3VdbeSerialTypeLen(t); + szField = sqlite3VdbeSerialTypeLen(t); iField += szField; } testcase( iField==nRec ); testcase( iField==nRec+1 ); if( iField>nRec ) return SQLITE_CORRUPT_BKPT; if( pMem==0 ){ - pMem = *ppVal = tdsqlite3ValueNew(db); + pMem = *ppVal = sqlite3ValueNew(db); if( pMem==0 ) return SQLITE_NOMEM_BKPT; } - tdsqlite3VdbeSerialGet(&a[iField-szField], t, pMem); + sqlite3VdbeSerialGet(&a[iField-szField], t, pMem); pMem->enc = ENC(db); return SQLITE_OK; } /* ** Unless it is NULL, the argument must be an UnpackedRecord object returned -** by an earlier call to tdsqlite3Stat4ProbeSetValue(). This call deletes +** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes ** the object. */ -SQLITE_PRIVATE void tdsqlite3Stat4ProbeFree(UnpackedRecord *pRec){ +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ if( pRec ){ int i; int nCol = pRec->pKeyInfo->nAllField; Mem *aMem = pRec->aMem; - tdsqlite3 *db = aMem[0].db; + sqlite3 *db = aMem[0].db; for(i=0; ipKeyInfo); - tdsqlite3DbFreeNN(db, pRec); + sqlite3KeyInfoUnref(pRec->pKeyInfo); + sqlite3DbFreeNN(db, pRec); } } #endif /* ifdef SQLITE_ENABLE_STAT4 */ /* -** Change the string value of an tdsqlite3_value object +** Change the string value of an sqlite3_value object */ -SQLITE_PRIVATE void tdsqlite3ValueSetStr( - tdsqlite3_value *v, /* Value to be set */ +SQLITE_PRIVATE void sqlite3ValueSetStr( + sqlite3_value *v, /* Value to be set */ int n, /* Length of string z */ const void *z, /* Text of the new string */ u8 enc, /* Encoding to use */ void (*xDel)(void*) /* Destructor for the string */ ){ - if( v ) tdsqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel); + if( v ) sqlite3VdbeMemSetStr((Mem *)v, z, n, enc, xDel); } /* -** Free an tdsqlite3_value object +** Free an sqlite3_value object */ -SQLITE_PRIVATE void tdsqlite3ValueFree(tdsqlite3_value *v){ +SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value *v){ if( !v ) return; - tdsqlite3VdbeMemRelease((Mem *)v); - tdsqlite3DbFreeNN(((Mem*)v)->db, v); + sqlite3VdbeMemRelease((Mem *)v); + sqlite3DbFreeNN(((Mem*)v)->db, v); } /* -** The tdsqlite3ValueBytes() routine returns the number of bytes in the -** tdsqlite3_value object assuming that it uses the encoding "enc". +** The sqlite3ValueBytes() routine returns the number of bytes in the +** sqlite3_value object assuming that it uses the encoding "enc". ** The valueBytes() routine is a helper function. */ -static SQLITE_NOINLINE int valueBytes(tdsqlite3_value *pVal, u8 enc){ +static SQLITE_NOINLINE int valueBytes(sqlite3_value *pVal, u8 enc){ return valueToText(pVal, enc)!=0 ? pVal->n : 0; } -SQLITE_PRIVATE int tdsqlite3ValueBytes(tdsqlite3_value *pVal, u8 enc){ +SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ Mem *p = (Mem*)pVal; assert( (p->flags & MEM_Null)==0 || (p->flags & (MEM_Str|MEM_Blob))==0 ); if( (p->flags & MEM_Str)!=0 && pVal->enc==enc ){ @@ -80965,22 +80965,22 @@ SQLITE_PRIVATE int tdsqlite3ValueBytes(tdsqlite3_value *pVal, u8 enc){ ** ************************************************************************* ** This file contains code used for creating, destroying, and populating -** a VDBE (or an "tdsqlite3_stmt" as it is known to the outside world.) +** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) */ /* #include "sqliteInt.h" */ /* #include "vdbeInt.h" */ /* Forward references */ -static void freeEphemeralFunction(tdsqlite3 *db, FuncDef *pDef); -static void vdbeFreeOpArray(tdsqlite3 *, Op *, int); +static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef); +static void vdbeFreeOpArray(sqlite3 *, Op *, int); /* ** Create a new virtual database engine. */ -SQLITE_PRIVATE Vdbe *tdsqlite3VdbeCreate(Parse *pParse){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE Vdbe *sqlite3VdbeCreate(Parse *pParse){ + sqlite3 *db = pParse->db; Vdbe *p; - p = tdsqlite3DbMallocRawNN(db, sizeof(Vdbe) ); + p = sqlite3DbMallocRawNN(db, sizeof(Vdbe) ); if( p==0 ) return 0; memset(&p->aOp, 0, sizeof(Vdbe)-offsetof(Vdbe,aOp)); p->db = db; @@ -80997,49 +80997,49 @@ SQLITE_PRIVATE Vdbe *tdsqlite3VdbeCreate(Parse *pParse){ assert( pParse->nLabel==0 ); assert( p->nOpAlloc==0 ); assert( pParse->szOpAlloc==0 ); - tdsqlite3VdbeAddOp2(p, OP_Init, 0, 1); + sqlite3VdbeAddOp2(p, OP_Init, 0, 1); return p; } /* ** Return the Parse object that owns a Vdbe object. */ -SQLITE_PRIVATE Parse *tdsqlite3VdbeParser(Vdbe *p){ +SQLITE_PRIVATE Parse *sqlite3VdbeParser(Vdbe *p){ return p->pParse; } /* ** Change the error string stored in Vdbe.zErrMsg */ -SQLITE_PRIVATE void tdsqlite3VdbeError(Vdbe *p, const char *zFormat, ...){ +SQLITE_PRIVATE void sqlite3VdbeError(Vdbe *p, const char *zFormat, ...){ va_list ap; - tdsqlite3DbFree(p->db, p->zErrMsg); + sqlite3DbFree(p->db, p->zErrMsg); va_start(ap, zFormat); - p->zErrMsg = tdsqlite3VMPrintf(p->db, zFormat, ap); + p->zErrMsg = sqlite3VMPrintf(p->db, zFormat, ap); va_end(ap); } /* ** Remember the SQL string for a prepared statement. */ -SQLITE_PRIVATE void tdsqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){ +SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){ if( p==0 ) return; p->prepFlags = prepFlags; if( (prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ p->expmask = 0; } assert( p->zSql==0 ); - p->zSql = tdsqlite3DbStrNDup(p->db, z, n); + p->zSql = sqlite3DbStrNDup(p->db, z, n); } #ifdef SQLITE_ENABLE_NORMALIZE /* ** Add a new element to the Vdbe->pDblStr list. */ -SQLITE_PRIVATE void tdsqlite3VdbeAddDblquoteStr(tdsqlite3 *db, Vdbe *p, const char *z){ +SQLITE_PRIVATE void sqlite3VdbeAddDblquoteStr(sqlite3 *db, Vdbe *p, const char *z){ if( p ){ - int n = tdsqlite3Strlen30(z); - DblquoteStr *pStr = tdsqlite3DbMallocRawNN(db, + int n = sqlite3Strlen30(z); + DblquoteStr *pStr = sqlite3DbMallocRawNN(db, sizeof(*pStr)+n+1-sizeof(pStr->z)); if( pStr ){ pStr->pNextStr = p->pDblStr; @@ -81055,7 +81055,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeAddDblquoteStr(tdsqlite3 *db, Vdbe *p, const ch ** zId of length nId is a double-quoted identifier. Check to see if ** that identifier is really used as a string literal. */ -SQLITE_PRIVATE int tdsqlite3VdbeUsesDoubleQuotedString( +SQLITE_PRIVATE int sqlite3VdbeUsesDoubleQuotedString( Vdbe *pVdbe, /* The prepared statement */ const char *zId /* The double-quoted identifier, already dequoted */ ){ @@ -81072,7 +81072,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeUsesDoubleQuotedString( /* ** Swap all content between two VDBE structures. */ -SQLITE_PRIVATE void tdsqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ +SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){ Vdbe tmp, *pTmp; char *zTmp; assert( pA->db==pB->db ); @@ -81121,25 +81121,25 @@ static int growOpArray(Vdbe *v, int nOp){ ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current ** size of the op array or add 1KB of space, whichever is smaller. */ #ifdef SQLITE_TEST_REALLOC_STRESS - tdsqlite3_int64 nNew = (v->nOpAlloc>=512 ? 2*(tdsqlite3_int64)v->nOpAlloc - : (tdsqlite3_int64)v->nOpAlloc+nOp); + sqlite3_int64 nNew = (v->nOpAlloc>=512 ? 2*(sqlite3_int64)v->nOpAlloc + : (sqlite3_int64)v->nOpAlloc+nOp); #else - tdsqlite3_int64 nNew = (v->nOpAlloc ? 2*(tdsqlite3_int64)v->nOpAlloc - : (tdsqlite3_int64)(1024/sizeof(Op))); + sqlite3_int64 nNew = (v->nOpAlloc ? 2*(sqlite3_int64)v->nOpAlloc + : (sqlite3_int64)(1024/sizeof(Op))); UNUSED_PARAMETER(nOp); #endif /* Ensure that the size of a VDBE does not grow too large */ if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){ - tdsqlite3OomFault(p->db); + sqlite3OomFault(p->db); return SQLITE_NOMEM; } assert( nOp<=(1024/sizeof(Op)) ); assert( nNew>=(v->nOpAlloc+nOp) ); - pNew = tdsqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); + pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op)); if( pNew ){ - p->szOpAlloc = tdsqlite3DbMallocSize(p->db, pNew); + p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew); v->nOpAlloc = p->szOpAlloc/sizeof(Op); v->aOp = pNew; } @@ -81154,9 +81154,9 @@ static int growOpArray(Vdbe *v, int nOp){ ** ** Other useful labels for breakpoints include: ** test_trace_breakpoint(pc,pOp) -** tdsqlite3CorruptError(lineno) -** tdsqlite3MisuseError(lineno) -** tdsqlite3CantopenError(lineno) +** sqlite3CorruptError(lineno) +** sqlite3MisuseError(lineno) +** sqlite3CantopenError(lineno) */ static void test_addop_breakpoint(int pc, Op *pOp){ static int n = 0; @@ -81176,17 +81176,17 @@ static void test_addop_breakpoint(int pc, Op *pOp){ ** ** p1, p2, p3 Operands ** -** Use the tdsqlite3VdbeResolveLabel() function to fix an address and -** the tdsqlite3VdbeChangeP4() function to change the value of the P4 +** Use the sqlite3VdbeResolveLabel() function to fix an address and +** the sqlite3VdbeChangeP4() function to change the value of the P4 ** operand. */ static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ assert( p->nOpAlloc<=p->nOp ); if( growOpArray(p, 1) ) return 1; assert( p->nOpAlloc>p->nOp ); - return tdsqlite3VdbeAddOp3(p, op, p1, p2, p3); + return sqlite3VdbeAddOp3(p, op, p1, p2, p3); } -SQLITE_PRIVATE int tdsqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ +SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ int i; VdbeOp *pOp; @@ -81210,7 +81210,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ #endif #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ - tdsqlite3VdbePrintOp(0, i, &p->aOp[i]); + sqlite3VdbePrintOp(0, i, &p->aOp[i]); test_addop_breakpoint(i, &p->aOp[i]); } #endif @@ -81223,27 +81223,27 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ #endif return i; } -SQLITE_PRIVATE int tdsqlite3VdbeAddOp0(Vdbe *p, int op){ - return tdsqlite3VdbeAddOp3(p, op, 0, 0, 0); +SQLITE_PRIVATE int sqlite3VdbeAddOp0(Vdbe *p, int op){ + return sqlite3VdbeAddOp3(p, op, 0, 0, 0); } -SQLITE_PRIVATE int tdsqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ - return tdsqlite3VdbeAddOp3(p, op, p1, 0, 0); +SQLITE_PRIVATE int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ + return sqlite3VdbeAddOp3(p, op, p1, 0, 0); } -SQLITE_PRIVATE int tdsqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ - return tdsqlite3VdbeAddOp3(p, op, p1, p2, 0); +SQLITE_PRIVATE int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ + return sqlite3VdbeAddOp3(p, op, p1, p2, 0); } /* Generate code for an unconditional jump to instruction iDest */ -SQLITE_PRIVATE int tdsqlite3VdbeGoto(Vdbe *p, int iDest){ - return tdsqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0); +SQLITE_PRIVATE int sqlite3VdbeGoto(Vdbe *p, int iDest){ + return sqlite3VdbeAddOp3(p, OP_Goto, 0, iDest, 0); } /* Generate code to cause the string zStr to be loaded into ** register iDest */ -SQLITE_PRIVATE int tdsqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){ - return tdsqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0); +SQLITE_PRIVATE int sqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr){ + return sqlite3VdbeAddOp4(p, OP_String8, 0, iDest, 0, zStr, 0); } /* @@ -81257,7 +81257,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeLoadString(Vdbe *p, int iDest, const char *zStr) ** If the input string does not end with "X" then an OP_ResultRow instruction ** is generated for the values inserted. */ -SQLITE_PRIVATE void tdsqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){ +SQLITE_PRIVATE void sqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zTypes, ...){ va_list ap; int i; char c; @@ -81265,14 +81265,14 @@ SQLITE_PRIVATE void tdsqlite3VdbeMultiLoad(Vdbe *p, int iDest, const char *zType for(i=0; (c = zTypes[i])!=0; i++){ if( c=='s' ){ const char *z = va_arg(ap, const char*); - tdsqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest+i, 0, z, 0); + sqlite3VdbeAddOp4(p, z==0 ? OP_Null : OP_String8, 0, iDest+i, 0, z, 0); }else if( c=='i' ){ - tdsqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest+i); + sqlite3VdbeAddOp2(p, OP_Integer, va_arg(ap, int), iDest+i); }else{ goto skip_op_resultrow; } } - tdsqlite3VdbeAddOp2(p, OP_ResultRow, iDest, i); + sqlite3VdbeAddOp2(p, OP_ResultRow, iDest, i); skip_op_resultrow: va_end(ap); } @@ -81280,7 +81280,7 @@ skip_op_resultrow: /* ** Add an opcode that includes the p4 value as a pointer. */ -SQLITE_PRIVATE int tdsqlite3VdbeAddOp4( +SQLITE_PRIVATE int sqlite3VdbeAddOp4( Vdbe *p, /* Add the opcode to this VM */ int op, /* The new opcode */ int p1, /* The P1 operand */ @@ -81289,8 +81289,8 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddOp4( const char *zP4, /* The P4 operand */ int p4type /* P4 operand type */ ){ - int addr = tdsqlite3VdbeAddOp3(p, op, p1, p2, p3); - tdsqlite3VdbeChangeP4(p, addr, zP4, p4type); + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + sqlite3VdbeChangeP4(p, addr, zP4, p4type); return addr; } @@ -81304,7 +81304,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddOp4( ** means in the WHERE clause of a partial index. NC_GenCol means called ** while computing a generated column value. 0 is the usual case. */ -SQLITE_PRIVATE int tdsqlite3VdbeAddFunctionCall( +SQLITE_PRIVATE int sqlite3VdbeAddFunctionCall( Parse *pParse, /* Parsing context */ int p1, /* Constant argument mask */ int p2, /* First argument register */ @@ -81316,10 +81316,10 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddFunctionCall( Vdbe *v = pParse->pVdbe; int nByte; int addr; - tdsqlite3_context *pCtx; + sqlite3_context *pCtx; assert( v ); - nByte = sizeof(*pCtx) + (nArg-1)*sizeof(tdsqlite3_value*); - pCtx = tdsqlite3DbMallocRawNN(pParse->db, nByte); + nByte = sizeof(*pCtx) + (nArg-1)*sizeof(sqlite3_value*); + pCtx = sqlite3DbMallocRawNN(pParse->db, nByte); if( pCtx==0 ){ assert( pParse->db->mallocFailed ); freeEphemeralFunction(pParse->db, (FuncDef*)pFunc); @@ -81330,10 +81330,10 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddFunctionCall( pCtx->pVdbe = 0; pCtx->isError = 0; pCtx->argc = nArg; - pCtx->iOp = tdsqlite3VdbeCurrentAddr(v); - addr = tdsqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function, + pCtx->iOp = sqlite3VdbeCurrentAddr(v); + addr = sqlite3VdbeAddOp4(v, eCallCtx ? OP_PureFunc : OP_Function, p1, p2, p3, (char*)pCtx, P4_FUNCCTX); - tdsqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef); + sqlite3VdbeChangeP5(v, eCallCtx & NC_SelfRef); return addr; } @@ -81341,7 +81341,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddFunctionCall( ** Add an opcode that includes the p4 value with a P4_INT64 or ** P4_REAL type. */ -SQLITE_PRIVATE int tdsqlite3VdbeAddOp4Dup8( +SQLITE_PRIVATE int sqlite3VdbeAddOp4Dup8( Vdbe *p, /* Add the opcode to this VM */ int op, /* The new opcode */ int p1, /* The P1 operand */ @@ -81350,9 +81350,9 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddOp4Dup8( const u8 *zP4, /* The P4 operand */ int p4type /* P4 operand type */ ){ - char *p4copy = tdsqlite3DbMallocRawNN(tdsqlite3VdbeDb(p), 8); + char *p4copy = sqlite3DbMallocRawNN(sqlite3VdbeDb(p), 8); if( p4copy ) memcpy(p4copy, zP4, 8); - return tdsqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); + return sqlite3VdbeAddOp4(p, op, p1, p2, p3, p4copy, p4type); } #ifndef SQLITE_OMIT_EXPLAIN @@ -81360,10 +81360,10 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddOp4Dup8( ** Return the address of the current EXPLAIN QUERY PLAN baseline. ** 0 means "none". */ -SQLITE_PRIVATE int tdsqlite3VdbeExplainParent(Parse *pParse){ +SQLITE_PRIVATE int sqlite3VdbeExplainParent(Parse *pParse){ VdbeOp *pOp; if( pParse->addrExplain==0 ) return 0; - pOp = tdsqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain); + pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain); return pOp->p2; } @@ -81372,7 +81372,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeExplainParent(Parse *pParse){ ** monitor the EXPLAIN QUERY PLAN code generation. */ #if defined(SQLITE_DEBUG) -SQLITE_PRIVATE void tdsqlite3ExplainBreakpoint(const char *z1, const char *z2){ +SQLITE_PRIVATE void sqlite3ExplainBreakpoint(const char *z1, const char *z2){ (void)z1; (void)z2; } @@ -81382,9 +81382,9 @@ SQLITE_PRIVATE void tdsqlite3ExplainBreakpoint(const char *z1, const char *z2){ ** Add a new OP_ opcode. ** ** If the bPush flag is true, then make this opcode the parent for -** subsequent Explains until tdsqlite3VdbeExplainPop() is called. +** subsequent Explains until sqlite3VdbeExplainPop() is called. */ -SQLITE_PRIVATE void tdsqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ +SQLITE_PRIVATE void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){ #ifndef SQLITE_DEBUG /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined. ** But omit them (for performance) during production builds */ @@ -81396,13 +81396,13 @@ SQLITE_PRIVATE void tdsqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zF va_list ap; int iThis; va_start(ap, zFmt); - zMsg = tdsqlite3VMPrintf(pParse->db, zFmt, ap); + zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap); va_end(ap); v = pParse->pVdbe; iThis = v->nOp; - tdsqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, + sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0, zMsg, P4_DYNAMIC); - tdsqlite3ExplainBreakpoint(bPush?"PUSH":"", tdsqlite3VdbeGetOp(v,-1)->p4.z); + sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z); if( bPush){ pParse->addrExplain = iThis; } @@ -81412,30 +81412,30 @@ SQLITE_PRIVATE void tdsqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zF /* ** Pop the EXPLAIN QUERY PLAN stack one level. */ -SQLITE_PRIVATE void tdsqlite3VdbeExplainPop(Parse *pParse){ - tdsqlite3ExplainBreakpoint("POP", 0); - pParse->addrExplain = tdsqlite3VdbeExplainParent(pParse); +SQLITE_PRIVATE void sqlite3VdbeExplainPop(Parse *pParse){ + sqlite3ExplainBreakpoint("POP", 0); + pParse->addrExplain = sqlite3VdbeExplainParent(pParse); } #endif /* SQLITE_OMIT_EXPLAIN */ /* ** Add an OP_ParseSchema opcode. This routine is broken out from -** tdsqlite3VdbeAddOp4() since it needs to also needs to mark all btrees +** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees ** as having been used. ** -** The zWhere string must have been obtained from tdsqlite3_malloc(). +** The zWhere string must have been obtained from sqlite3_malloc(). ** This routine will take ownership of the allocated memory. */ -SQLITE_PRIVATE void tdsqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ +SQLITE_PRIVATE void sqlite3VdbeAddParseSchemaOp(Vdbe *p, int iDb, char *zWhere){ int j; - tdsqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); - for(j=0; jdb->nDb; j++) tdsqlite3VdbeUsesBtree(p, j); + sqlite3VdbeAddOp4(p, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); + for(j=0; jdb->nDb; j++) sqlite3VdbeUsesBtree(p, j); } /* ** Add an opcode that includes the p4 value as an integer. */ -SQLITE_PRIVATE int tdsqlite3VdbeAddOp4Int( +SQLITE_PRIVATE int sqlite3VdbeAddOp4Int( Vdbe *p, /* Add the opcode to this VM */ int op, /* The new opcode */ int p1, /* The P1 operand */ @@ -81443,7 +81443,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddOp4Int( int p3, /* The P3 operand */ int p4 /* The P4 operand as an integer */ ){ - int addr = tdsqlite3VdbeAddOp3(p, op, p1, p2, p3); + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); if( p->db->mallocFailed==0 ){ VdbeOp *pOp = &p->aOp[addr]; pOp->p4type = P4_INT32; @@ -81454,8 +81454,8 @@ SQLITE_PRIVATE int tdsqlite3VdbeAddOp4Int( /* Insert the end of a co-routine */ -SQLITE_PRIVATE void tdsqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ - tdsqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); +SQLITE_PRIVATE void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ + sqlite3VdbeAddOp1(v, OP_EndCoroutine, regYield); /* Clear the temporary register cache, thereby ensuring that each ** co-routine has its own independent set of registers, because co-routines @@ -81492,18 +81492,18 @@ SQLITE_PRIVATE void tdsqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ ** that gives a performance improvement over storing ** the equivalent positive value. */ -SQLITE_PRIVATE int tdsqlite3VdbeMakeLabel(Parse *pParse){ +SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Parse *pParse){ return --pParse->nLabel; } /* ** Resolve label "x" to be the address of the next instruction to ** be inserted. The parameter "x" must have been obtained from -** a prior call to tdsqlite3VdbeMakeLabel(). +** a prior call to sqlite3VdbeMakeLabel(). */ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ int nNewSize = 10 - p->nLabel; - p->aLabel = tdsqlite3DbReallocOrFree(p->db, p->aLabel, + p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, nNewSize*sizeof(p->aLabel[0])); if( p->aLabel==0 ){ p->nLabelAlloc = 0; @@ -81516,7 +81516,7 @@ static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){ p->aLabel[j] = v->nOp; } } -SQLITE_PRIVATE void tdsqlite3VdbeResolveLabel(Vdbe *v, int x){ +SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *v, int x){ Parse *p = v->pParse; int j = ADDR(x); assert( v->magic==VDBE_MAGIC_INIT ); @@ -81538,18 +81538,18 @@ SQLITE_PRIVATE void tdsqlite3VdbeResolveLabel(Vdbe *v, int x){ /* ** Mark the VDBE as one that can only be run one time. */ -SQLITE_PRIVATE void tdsqlite3VdbeRunOnlyOnce(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe *p){ p->runOnlyOnce = 1; } /* ** Mark the VDBE as one that can only be run multiple times. */ -SQLITE_PRIVATE void tdsqlite3VdbeReusable(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeReusable(Vdbe *p){ p->runOnlyOnce = 0; } -#ifdef SQLITE_DEBUG /* tdsqlite3AssertMayAbort() logic */ +#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ /* ** The following type and function are used to iterate through all opcodes @@ -81564,7 +81564,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeReusable(Vdbe *p){ ** while( (pOp = opIterNext(&sIter)) ){ ** // Do something with pOp ** } -** tdsqlite3DbFree(v->db, sIter.apSub); +** sqlite3DbFree(v->db, sIter.apSub); ** */ typedef struct VdbeOpIter VdbeOpIter; @@ -81606,7 +81606,7 @@ static Op *opIterNext(VdbeOpIter *p){ if( p->apSub[j]==pRet->p4.pProgram ) break; } if( j==p->nSub ){ - p->apSub = tdsqlite3DbReallocOrFree(v->db, p->apSub, nByte); + p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte); if( !p->apSub ){ pRet = 0; }else{ @@ -81640,9 +81640,9 @@ static Op *opIterNext(VdbeOpIter *p){ ** match, or false otherwise. This function is intended to be used as ** part of an assert statement in the compiler. Similar to: ** -** assert( tdsqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) ); +** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) ); */ -SQLITE_PRIVATE int tdsqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ int hasAbort = 0; int hasFkCounter = 0; int hasCreateTable = 0; @@ -81681,7 +81681,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ } #endif } - tdsqlite3DbFree(v->db, sIter.apSub); + sqlite3DbFree(v->db, sIter.apSub); /* Return true if hasAbort==mayAbort. Or if a malloc failure occurred. ** If malloc failed, then the while() loop above may not have iterated @@ -81692,14 +81692,14 @@ SQLITE_PRIVATE int tdsqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ || (hasCreateTable && hasInitCoroutine) || hasCreateIndex ); } -#endif /* SQLITE_DEBUG - the tdsqlite3AssertMayAbort() function */ +#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ #ifdef SQLITE_DEBUG /* ** Increment the nWrite counter in the VDBE if the cursor is not an ** ephemeral cursor, or if the cursor argument is NULL. */ -SQLITE_PRIVATE void tdsqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){ +SQLITE_PRIVATE void sqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){ if( pC==0 || (pC->eCurType!=CURTYPE_SORTER && pC->eCurType!=CURTYPE_PSEUDO @@ -81715,7 +81715,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeIncrWriteCounter(Vdbe *p, VdbeCursor *pC){ ** Assert if an Abort at this point in time might result in a corrupt ** database. */ -SQLITE_PRIVATE void tdsqlite3VdbeAssertAbortable(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeAssertAbortable(Vdbe *p){ assert( p->nWrite==0 || p->usesStmtJournal ); } #endif @@ -81781,7 +81781,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ } case OP_Next: case OP_SorterNext: { - pOp->p4.xAdvance = tdsqlite3BtreeNext; + pOp->p4.xAdvance = sqlite3BtreeNext; pOp->p4type = P4_ADVANCE; /* The code generator never codes any of these opcodes as a jump ** to a label. They are always coded as a jump backwards to a @@ -81790,7 +81790,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ break; } case OP_Prev: { - pOp->p4.xAdvance = tdsqlite3BtreePrevious; + pOp->p4.xAdvance = sqlite3BtreePrevious; pOp->p4type = P4_ADVANCE; /* The code generator never codes any of these opcodes as a jump ** to a label. They are always coded as a jump backwards to a @@ -81817,7 +81817,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ /* The mkopcodeh.tcl script has so arranged things that the only ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to ** have non-negative values for P2. */ - assert( (tdsqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); + assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 ); assert( ADDR(pOp->p2)<-pParse->nLabel ); pOp->p2 = aLabel[ADDR(pOp->p2)]; } @@ -81827,12 +81827,12 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ /* The mkopcodeh.tcl script has so arranged things that the only ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to ** have non-negative values for P2. */ - assert( (tdsqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); + assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); } if( pOp==p->aOp ) break; pOp--; } - tdsqlite3DbFree(p->db, pParse->aLabel); + sqlite3DbFree(p->db, pParse->aLabel); pParse->aLabel = 0; pParse->nLabel = 0; *pMaxFuncArgs = nMaxArgs; @@ -81842,7 +81842,7 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ /* ** Return the address of the next instruction to be inserted. */ -SQLITE_PRIVATE int tdsqlite3VdbeCurrentAddr(Vdbe *p){ +SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ assert( p->magic==VDBE_MAGIC_INIT ); return p->nOp; } @@ -81851,12 +81851,12 @@ SQLITE_PRIVATE int tdsqlite3VdbeCurrentAddr(Vdbe *p){ ** Verify that at least N opcode slots are available in p without ** having to malloc for more space (except when compiled using ** SQLITE_TEST_REALLOC_STRESS). This interface is used during testing -** to verify that certain calls to tdsqlite3VdbeAddOpList() can never +** to verify that certain calls to sqlite3VdbeAddOpList() can never ** fail due to a OOM fault and hence that the return value from -** tdsqlite3VdbeAddOpList() will always be non-NULL. +** sqlite3VdbeAddOpList() will always be non-NULL. */ #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) -SQLITE_PRIVATE void tdsqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ +SQLITE_PRIVATE void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ assert( p->nOp + N <= p->nOpAlloc ); } #endif @@ -81869,7 +81869,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){ ** script. */ #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS) -SQLITE_PRIVATE void tdsqlite3VdbeVerifyNoResultRow(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeVerifyNoResultRow(Vdbe *p){ int i; for(i=0; inOp; i++){ assert( p->aOp[i].opcode!=OP_ResultRow ); @@ -81883,8 +81883,8 @@ SQLITE_PRIVATE void tdsqlite3VdbeVerifyNoResultRow(Vdbe *p){ ** context. */ #if defined(SQLITE_DEBUG) -SQLITE_PRIVATE void tdsqlite3VdbeVerifyAbortable(Vdbe *p, int onError){ - if( onError==OE_Abort ) tdsqlite3VdbeAddOp0(p, OP_Abortable); +SQLITE_PRIVATE void sqlite3VdbeVerifyAbortable(Vdbe *p, int onError){ + if( onError==OE_Abort ) sqlite3VdbeAddOp0(p, OP_Abortable); } #endif @@ -81899,11 +81899,11 @@ SQLITE_PRIVATE void tdsqlite3VdbeVerifyAbortable(Vdbe *p, int onError){ ** the number of entries in the Vdbe.apArg[] array required to execute the ** returned program. */ -SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ VdbeOp *aOp = p->aOp; assert( aOp && !p->db->mallocFailed ); - /* Check that tdsqlite3VdbeUsesBtree() was not called on this VM */ + /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ assert( DbMaskAllZero(p->btreeMask) ); resolveP2Values(p, pnMaxArg); @@ -81919,7 +81919,7 @@ SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxAr ** Non-zero P2 arguments to jump instructions are automatically adjusted ** so that the jump target is relative to the first operation inserted. */ -SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeAddOpList( +SQLITE_PRIVATE VdbeOp *sqlite3VdbeAddOpList( Vdbe *p, /* Add opcodes to the prepared statement */ int nOp, /* Number of opcodes to add */ VdbeOpList const *aOp, /* The opcodes to be added */ @@ -81938,7 +81938,7 @@ SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeAddOpList( pOut->p1 = aOp->p1; pOut->p2 = aOp->p2; assert( aOp->p2>=0 ); - if( (tdsqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){ + if( (sqlite3OpcodeProperty[aOp->opcode] & OPFLG_JUMP)!=0 && aOp->p2>0 ){ pOut->p2 += p->nOp; } pOut->p3 = aOp->p3; @@ -81955,7 +81955,7 @@ SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeAddOpList( #endif #ifdef SQLITE_DEBUG if( p->db->flags & SQLITE_VdbeAddopTrace ){ - tdsqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]); + sqlite3VdbePrintOp(0, i+p->nOp, &p->aOp[i+p->nOp]); } #endif } @@ -81965,9 +81965,9 @@ SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeAddOpList( #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) /* -** Add an entry to the array of counters managed by tdsqlite3_stmt_scanstatus(). +** Add an entry to the array of counters managed by sqlite3_stmt_scanstatus(). */ -SQLITE_PRIVATE void tdsqlite3VdbeScanStatus( +SQLITE_PRIVATE void sqlite3VdbeScanStatus( Vdbe *p, /* VM to add scanstatus() to */ int addrExplain, /* Address of OP_Explain (or 0) */ int addrLoop, /* Address of loop counter */ @@ -81975,16 +81975,16 @@ SQLITE_PRIVATE void tdsqlite3VdbeScanStatus( LogEst nEst, /* Estimated number of output rows */ const char *zName /* Name of table or index being scanned */ ){ - tdsqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); + sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus); ScanStatus *aNew; - aNew = (ScanStatus*)tdsqlite3DbRealloc(p->db, p->aScan, nByte); + aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte); if( aNew ){ ScanStatus *pNew = &aNew[p->nScan++]; pNew->addrExplain = addrExplain; pNew->addrLoop = addrLoop; pNew->addrVisit = addrVisit; pNew->nEst = nEst; - pNew->zName = tdsqlite3DbStrDup(p->db, zName); + pNew->zName = sqlite3DbStrDup(p->db, zName); p->aScan = aNew; } } @@ -81995,19 +81995,19 @@ SQLITE_PRIVATE void tdsqlite3VdbeScanStatus( ** Change the value of the opcode, or P1, P2, P3, or P5 operands ** for a specific instruction. */ -SQLITE_PRIVATE void tdsqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ - tdsqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; +SQLITE_PRIVATE void sqlite3VdbeChangeOpcode(Vdbe *p, int addr, u8 iNewOpcode){ + sqlite3VdbeGetOp(p,addr)->opcode = iNewOpcode; } -SQLITE_PRIVATE void tdsqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ - tdsqlite3VdbeGetOp(p,addr)->p1 = val; +SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ + sqlite3VdbeGetOp(p,addr)->p1 = val; } -SQLITE_PRIVATE void tdsqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ - tdsqlite3VdbeGetOp(p,addr)->p2 = val; +SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ + sqlite3VdbeGetOp(p,addr)->p2 = val; } -SQLITE_PRIVATE void tdsqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ - tdsqlite3VdbeGetOp(p,addr)->p3 = val; +SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ + sqlite3VdbeGetOp(p,addr)->p3 = val; } -SQLITE_PRIVATE void tdsqlite3VdbeChangeP5(Vdbe *p, u16 p5){ +SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u16 p5){ assert( p->nOp>0 || p->db->mallocFailed ); if( p->nOp>0 ) p->aOp[p->nOp-1].p5 = p5; } @@ -82016,8 +82016,8 @@ SQLITE_PRIVATE void tdsqlite3VdbeChangeP5(Vdbe *p, u16 p5){ ** Change the P2 operand of instruction addr so that it points to ** the address of the next instruction to be coded. */ -SQLITE_PRIVATE void tdsqlite3VdbeJumpHere(Vdbe *p, int addr){ - tdsqlite3VdbeChangeP2(p, addr, p->nOp); +SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ + sqlite3VdbeChangeP2(p, addr, p->nOp); } @@ -82025,28 +82025,28 @@ SQLITE_PRIVATE void tdsqlite3VdbeJumpHere(Vdbe *p, int addr){ ** If the input FuncDef structure is ephemeral, then free it. If ** the FuncDef is not ephermal, then do nothing. */ -static void freeEphemeralFunction(tdsqlite3 *db, FuncDef *pDef){ +static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ if( (pDef->funcFlags & SQLITE_FUNC_EPHEM)!=0 ){ - tdsqlite3DbFreeNN(db, pDef); + sqlite3DbFreeNN(db, pDef); } } /* ** Delete a P4 value if necessary. */ -static SQLITE_NOINLINE void freeP4Mem(tdsqlite3 *db, Mem *p){ - if( p->szMalloc ) tdsqlite3DbFree(db, p->zMalloc); - tdsqlite3DbFreeNN(db, p); +static SQLITE_NOINLINE void freeP4Mem(sqlite3 *db, Mem *p){ + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); + sqlite3DbFreeNN(db, p); } -static SQLITE_NOINLINE void freeP4FuncCtx(tdsqlite3 *db, tdsqlite3_context *p){ +static SQLITE_NOINLINE void freeP4FuncCtx(sqlite3 *db, sqlite3_context *p){ freeEphemeralFunction(db, p->pFunc); - tdsqlite3DbFreeNN(db, p); + sqlite3DbFreeNN(db, p); } -static void freeP4(tdsqlite3 *db, int p4type, void *p4){ +static void freeP4(sqlite3 *db, int p4type, void *p4){ assert( db ); switch( p4type ){ case P4_FUNCCTX: { - freeP4FuncCtx(db, (tdsqlite3_context*)p4); + freeP4FuncCtx(db, (sqlite3_context*)p4); break; } case P4_REAL: @@ -82054,16 +82054,16 @@ static void freeP4(tdsqlite3 *db, int p4type, void *p4){ case P4_DYNAMIC: case P4_DYNBLOB: case P4_INTARRAY: { - tdsqlite3DbFree(db, p4); + sqlite3DbFree(db, p4); break; } case P4_KEYINFO: { - if( db->pnBytesFreed==0 ) tdsqlite3KeyInfoUnref((KeyInfo*)p4); + if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4); break; } #ifdef SQLITE_ENABLE_CURSOR_HINTS case P4_EXPR: { - tdsqlite3ExprDelete(db, (Expr*)p4); + sqlite3ExprDelete(db, (Expr*)p4); break; } #endif @@ -82073,14 +82073,14 @@ static void freeP4(tdsqlite3 *db, int p4type, void *p4){ } case P4_MEM: { if( db->pnBytesFreed==0 ){ - tdsqlite3ValueFree((tdsqlite3_value*)p4); + sqlite3ValueFree((sqlite3_value*)p4); }else{ freeP4Mem(db, (Mem*)p4); } break; } case P4_VTAB : { - if( db->pnBytesFreed==0 ) tdsqlite3VtabUnlock((VTable *)p4); + if( db->pnBytesFreed==0 ) sqlite3VtabUnlock((VTable *)p4); break; } } @@ -82091,16 +82091,16 @@ static void freeP4(tdsqlite3 *db, int p4type, void *p4){ ** opcodes contained within. If aOp is not NULL it is assumed to contain ** nOp entries. */ -static void vdbeFreeOpArray(tdsqlite3 *db, Op *aOp, int nOp){ +static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ if( aOp ){ Op *pOp; for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){ if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - tdsqlite3DbFree(db, pOp->zComment); + sqlite3DbFree(db, pOp->zComment); #endif } - tdsqlite3DbFreeNN(db, aOp); + sqlite3DbFreeNN(db, aOp); } } @@ -82109,7 +82109,7 @@ static void vdbeFreeOpArray(tdsqlite3 *db, Op *aOp, int nOp){ ** list at Vdbe.pSubProgram. This list is used to delete all sub-program ** objects when the VM is no longer required. */ -SQLITE_PRIVATE void tdsqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ +SQLITE_PRIVATE void sqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ p->pNext = pVdbe->pProgram; pVdbe->pProgram = p; } @@ -82117,14 +82117,14 @@ SQLITE_PRIVATE void tdsqlite3VdbeLinkSubProgram(Vdbe *pVdbe, SubProgram *p){ /* ** Return true if the given Vdbe has any SubPrograms. */ -SQLITE_PRIVATE int tdsqlite3VdbeHasSubProgram(Vdbe *pVdbe){ +SQLITE_PRIVATE int sqlite3VdbeHasSubProgram(Vdbe *pVdbe){ return pVdbe->pProgram!=0; } /* ** Change the opcode at addr into OP_Noop */ -SQLITE_PRIVATE int tdsqlite3VdbeChangeToNoop(Vdbe *p, int addr){ +SQLITE_PRIVATE int sqlite3VdbeChangeToNoop(Vdbe *p, int addr){ VdbeOp *pOp; if( p->db->mallocFailed ) return 0; assert( addr>=0 && addrnOp ); @@ -82140,9 +82140,9 @@ SQLITE_PRIVATE int tdsqlite3VdbeChangeToNoop(Vdbe *p, int addr){ ** If the last opcode is "op" and it is not a jump destination, ** then remove it. Return true if and only if an opcode was removed. */ -SQLITE_PRIVATE int tdsqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ +SQLITE_PRIVATE int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ if( p->nOp>0 && p->aOp[p->nOp-1].opcode==op ){ - return tdsqlite3VdbeChangeToNoop(p, p->nOp-1); + return sqlite3VdbeChangeToNoop(p, p->nOp-1); }else{ return 0; } @@ -82153,7 +82153,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){ ** Generate an OP_ReleaseReg opcode to indicate that a range of ** registers, except any identified by mask, are no longer in use. */ -SQLITE_PRIVATE void tdsqlite3VdbeReleaseRegisters( +SQLITE_PRIVATE void sqlite3VdbeReleaseRegisters( Parse *pParse, /* Parsing context */ int iFirst, /* Index of first register to be released */ int N, /* Number of registers to release */ @@ -82176,8 +82176,8 @@ SQLITE_PRIVATE void tdsqlite3VdbeReleaseRegisters( } } if( N>0 ){ - tdsqlite3VdbeAddOp3(pParse->pVdbe, OP_ReleaseReg, iFirst, N, *(int*)&mask); - if( bUndefine ) tdsqlite3VdbeChangeP5(pParse->pVdbe, 1); + sqlite3VdbeAddOp3(pParse->pVdbe, OP_ReleaseReg, iFirst, N, *(int*)&mask); + if( bUndefine ) sqlite3VdbeChangeP5(pParse->pVdbe, 1); } } #endif /* SQLITE_DEBUG */ @@ -82186,11 +82186,11 @@ SQLITE_PRIVATE void tdsqlite3VdbeReleaseRegisters( /* ** Change the value of the P4 operand for a specific instruction. ** This routine is useful when a large program is loaded from a -** static array using tdsqlite3VdbeAddOpList but we want to make a +** static array using sqlite3VdbeAddOpList but we want to make a ** few minor changes to the program. ** ** If n>=0 then the P4 operand is dynamic, meaning that a copy of -** the string is made into memory obtained from tdsqlite3_malloc(). +** the string is made into memory obtained from sqlite3_malloc(). ** A value of n==0 means copy bytes of zP4 up to and including the ** first null byte. If n>0 then copy n+1 bytes of zP4. ** @@ -82212,16 +82212,16 @@ static void SQLITE_NOINLINE vdbeChangeP4Full( pOp->p4.p = 0; } if( n<0 ){ - tdsqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n); + sqlite3VdbeChangeP4(p, (int)(pOp - p->aOp), zP4, n); }else{ - if( n==0 ) n = tdsqlite3Strlen30(zP4); - pOp->p4.z = tdsqlite3DbStrNDup(p->db, zP4, n); + if( n==0 ) n = sqlite3Strlen30(zP4); + pOp->p4.z = sqlite3DbStrNDup(p->db, zP4, n); pOp->p4type = P4_DYNAMIC; } } -SQLITE_PRIVATE void tdsqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ +SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int n){ Op *pOp; - tdsqlite3 *db; + sqlite3 *db; assert( p!=0 ); db = p->db; assert( p->magic==VDBE_MAGIC_INIT ); @@ -82249,20 +82249,20 @@ SQLITE_PRIVATE void tdsqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, in assert( n<0 ); pOp->p4.p = (void*)zP4; pOp->p4type = (signed char)n; - if( n==P4_VTAB ) tdsqlite3VtabLock((VTable*)zP4); + if( n==P4_VTAB ) sqlite3VtabLock((VTable*)zP4); } } /* ** Change the P4 operand of the most recently coded instruction ** to the value defined by the arguments. This is a high-speed -** version of tdsqlite3VdbeChangeP4(). +** version of sqlite3VdbeChangeP4(). ** ** The P4 operand must not have been previously defined. And the new -** P4 must not be P4_INT32. Use tdsqlite3VdbeChangeP4() in either of +** P4 must not be P4_INT32. Use sqlite3VdbeChangeP4() in either of ** those cases. */ -SQLITE_PRIVATE void tdsqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){ +SQLITE_PRIVATE void sqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){ VdbeOp *pOp; assert( n!=P4_INT32 && n!=P4_VTAB ); assert( n<=0 ); @@ -82282,13 +82282,13 @@ SQLITE_PRIVATE void tdsqlite3VdbeAppendP4(Vdbe *p, void *pP4, int n){ ** Set the P4 on the most recently added opcode to the KeyInfo for the ** index given. */ -SQLITE_PRIVATE void tdsqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ +SQLITE_PRIVATE void sqlite3VdbeSetP4KeyInfo(Parse *pParse, Index *pIdx){ Vdbe *v = pParse->pVdbe; KeyInfo *pKeyInfo; assert( v!=0 ); assert( pIdx!=0 ); - pKeyInfo = tdsqlite3KeyInfoOfIndex(pParse, pIdx); - if( pKeyInfo ) tdsqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); + pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pIdx); + if( pKeyInfo ) sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); } #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS @@ -82304,11 +82304,11 @@ static void vdbeVComment(Vdbe *p, const char *zFormat, va_list ap){ || p->pParse->nErr>0 ); if( p->nOp ){ assert( p->aOp ); - tdsqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); - p->aOp[p->nOp-1].zComment = tdsqlite3VMPrintf(p->db, zFormat, ap); + sqlite3DbFree(p->db, p->aOp[p->nOp-1].zComment); + p->aOp[p->nOp-1].zComment = sqlite3VMPrintf(p->db, zFormat, ap); } } -SQLITE_PRIVATE void tdsqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ +SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ va_list ap; if( p ){ va_start(ap, zFormat); @@ -82316,10 +82316,10 @@ SQLITE_PRIVATE void tdsqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ va_end(ap); } } -SQLITE_PRIVATE void tdsqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ +SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ va_list ap; if( p ){ - tdsqlite3VdbeAddOp0(p, OP_Noop); + sqlite3VdbeAddOp0(p, OP_Noop); va_start(ap, zFormat); vdbeVComment(p, zFormat, ap); va_end(ap); @@ -82331,8 +82331,8 @@ SQLITE_PRIVATE void tdsqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ /* ** Set the value if the iSrcLine field for the previously coded instruction. */ -SQLITE_PRIVATE void tdsqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ - tdsqlite3VdbeGetOp(v,-1)->iSrcLine = iLine; +SQLITE_PRIVATE void sqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ + sqlite3VdbeGetOp(v,-1)->iSrcLine = iLine; } #endif /* SQLITE_VDBE_COVERAGE */ @@ -82349,7 +82349,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeSetLineNumber(Vdbe *v, int iLine){ ** dummy will never be written to. This is verified by code inspection and ** by running with Valgrind. */ -SQLITE_PRIVATE VdbeOp *tdsqlite3VdbeGetOp(Vdbe *p, int addr){ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ /* C89 specifies that the constant "dummy" will be initialized to all ** zeros, which is correct. MSVC generates a warning, nevertheless. */ static VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ @@ -82382,7 +82382,7 @@ static int translateP(char c, const Op *pOp){ ** Compute a string for the "comment" field of a VDBE opcode listing. ** ** The Synopsis: field in comments in the vdbe.c source file gets converted -** to an extra string that is appended to the tdsqlite3OpcodeName(). In the +** to an extra string that is appended to the sqlite3OpcodeName(). In the ** absence of other comments, this synopsis becomes the comment on the opcode. ** Some translation occurs: ** @@ -82402,17 +82402,17 @@ static int displayComment( int nOpName; int ii, jj; char zAlt[50]; - zOpName = tdsqlite3OpcodeName(pOp->opcode); - nOpName = tdsqlite3Strlen30(zOpName); + zOpName = sqlite3OpcodeName(pOp->opcode); + nOpName = sqlite3Strlen30(zOpName); if( zOpName[nOpName+1] ){ int seenCom = 0; char c; zSynopsis = zOpName += nOpName + 1; if( strncmp(zSynopsis,"IF ",3)==0 ){ if( pOp->p5 & SQLITE_STOREP2 ){ - tdsqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3); + sqlite3_snprintf(sizeof(zAlt), zAlt, "r[P2] = (%s)", zSynopsis+3); }else{ - tdsqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); + sqlite3_snprintf(sizeof(zAlt), zAlt, "if %s goto P2", zSynopsis+3); } zSynopsis = zAlt; } @@ -82420,42 +82420,42 @@ static int displayComment( if( c=='P' ){ c = zSynopsis[++ii]; if( c=='4' ){ - tdsqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", zP4); + sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", zP4); }else if( c=='X' ){ - tdsqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", pOp->zComment); + sqlite3_snprintf(nTemp-jj, zTemp+jj, "%s", pOp->zComment); seenCom = 1; }else{ int v1 = translateP(c, pOp); int v2; - tdsqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1); + sqlite3_snprintf(nTemp-jj, zTemp+jj, "%d", v1); if( strncmp(zSynopsis+ii+1, "@P", 2)==0 ){ ii += 3; - jj += tdsqlite3Strlen30(zTemp+jj); + jj += sqlite3Strlen30(zTemp+jj); v2 = translateP(zSynopsis[ii], pOp); if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){ ii += 2; v2++; } if( v2>1 ){ - tdsqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1); + sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1); } }else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){ ii += 4; } } - jj += tdsqlite3Strlen30(zTemp+jj); + jj += sqlite3Strlen30(zTemp+jj); }else{ zTemp[jj++] = c; } } if( !seenCom && jjzComment ){ - tdsqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment); - jj += tdsqlite3Strlen30(zTemp+jj); + sqlite3_snprintf(nTemp-jj, zTemp+jj, "; %s", pOp->zComment); + jj += sqlite3Strlen30(zTemp+jj); } if( jjzComment ){ - tdsqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment); - jj = tdsqlite3Strlen30(zTemp); + sqlite3_snprintf(nTemp, zTemp, "%s", pOp->zComment); + jj = sqlite3Strlen30(zTemp); }else{ zTemp[0] = 0; jj = 0; @@ -82473,23 +82473,23 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){ const char *zOp = 0; switch( pExpr->op ){ case TK_STRING: - tdsqlite3_str_appendf(p, "%Q", pExpr->u.zToken); + sqlite3_str_appendf(p, "%Q", pExpr->u.zToken); break; case TK_INTEGER: - tdsqlite3_str_appendf(p, "%d", pExpr->u.iValue); + sqlite3_str_appendf(p, "%d", pExpr->u.iValue); break; case TK_NULL: - tdsqlite3_str_appendf(p, "NULL"); + sqlite3_str_appendf(p, "NULL"); break; case TK_REGISTER: { - tdsqlite3_str_appendf(p, "r[%d]", pExpr->iTable); + sqlite3_str_appendf(p, "r[%d]", pExpr->iTable); break; } case TK_COLUMN: { if( pExpr->iColumn<0 ){ - tdsqlite3_str_appendf(p, "rowid"); + sqlite3_str_appendf(p, "rowid"); }else{ - tdsqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn); + sqlite3_str_appendf(p, "c%d", (int)pExpr->iColumn); } break; } @@ -82521,18 +82521,18 @@ static void displayP4Expr(StrAccum *p, Expr *pExpr){ case TK_NOTNULL: zOp = "NOTNULL"; break; default: - tdsqlite3_str_appendf(p, "%s", "expr"); + sqlite3_str_appendf(p, "%s", "expr"); break; } if( zOp ){ - tdsqlite3_str_appendf(p, "%s(", zOp); + sqlite3_str_appendf(p, "%s(", zOp); displayP4Expr(p, pExpr->pLeft); if( pExpr->pRight ){ - tdsqlite3_str_append(p, ",", 1); + sqlite3_str_append(p, ",", 1); displayP4Expr(p, pExpr->pRight); } - tdsqlite3_str_append(p, ")", 1); + sqlite3_str_append(p, ")", 1); } } #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */ @@ -82547,23 +82547,23 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ char *zP4 = zTemp; StrAccum x; assert( nTemp>=20 ); - tdsqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0); + sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0); switch( pOp->p4type ){ case P4_KEYINFO: { int j; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; assert( pKeyInfo->aSortFlags!=0 ); - tdsqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField); + sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField); for(j=0; jnKeyField; j++){ CollSeq *pColl = pKeyInfo->aColl[j]; const char *zColl = pColl ? pColl->zName : ""; if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; - tdsqlite3_str_appendf(&x, ",%s%s%s", + sqlite3_str_appendf(&x, ",%s%s%s", (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "", (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "", zColl); } - tdsqlite3_str_append(&x, ")", 1); + sqlite3_str_append(&x, ")", 1); break; } #ifdef SQLITE_ENABLE_CURSOR_HINTS @@ -82574,29 +82574,29 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ #endif case P4_COLLSEQ: { CollSeq *pColl = pOp->p4.pColl; - tdsqlite3_str_appendf(&x, "(%.20s)", pColl->zName); + sqlite3_str_appendf(&x, "(%.20s)", pColl->zName); break; } case P4_FUNCDEF: { FuncDef *pDef = pOp->p4.pFunc; - tdsqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); + sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } case P4_FUNCCTX: { FuncDef *pDef = pOp->p4.pCtx->pFunc; - tdsqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); + sqlite3_str_appendf(&x, "%s(%d)", pDef->zName, pDef->nArg); break; } case P4_INT64: { - tdsqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); + sqlite3_str_appendf(&x, "%lld", *pOp->p4.pI64); break; } case P4_INT32: { - tdsqlite3_str_appendf(&x, "%d", pOp->p4.i); + sqlite3_str_appendf(&x, "%d", pOp->p4.i); break; } case P4_REAL: { - tdsqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); + sqlite3_str_appendf(&x, "%.16g", *pOp->p4.pReal); break; } case P4_MEM: { @@ -82604,9 +82604,9 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ if( pMem->flags & MEM_Str ){ zP4 = pMem->z; }else if( pMem->flags & (MEM_Int|MEM_IntReal) ){ - tdsqlite3_str_appendf(&x, "%lld", pMem->u.i); + sqlite3_str_appendf(&x, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ - tdsqlite3_str_appendf(&x, "%.16g", pMem->u.r); + sqlite3_str_appendf(&x, "%.16g", pMem->u.r); }else if( pMem->flags & MEM_Null ){ zP4 = "NULL"; }else{ @@ -82617,8 +82617,8 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ } #ifndef SQLITE_OMIT_VIRTUALTABLE case P4_VTAB: { - tdsqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; - tdsqlite3_str_appendf(&x, "vtab:%p", pVtab); + sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; + sqlite3_str_appendf(&x, "vtab:%p", pVtab); break; } #endif @@ -82628,14 +82628,14 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ int n = ai[0]; /* The first element of an INTARRAY is always the ** count of the number of elements to follow */ for(i=1; i<=n; i++){ - tdsqlite3_str_appendf(&x, ",%d", ai[i]); + sqlite3_str_appendf(&x, ",%d", ai[i]); } zTemp[0] = '['; - tdsqlite3_str_append(&x, "]", 1); + sqlite3_str_append(&x, "]", 1); break; } case P4_SUBPROGRAM: { - tdsqlite3_str_appendf(&x, "program"); + sqlite3_str_appendf(&x, "program"); break; } case P4_DYNBLOB: @@ -82644,7 +82644,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ break; } case P4_TABLE: { - tdsqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName); + sqlite3_str_appendf(&x, "%s", pOp->p4.pTab->zName); break; } default: { @@ -82655,7 +82655,7 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ } } } - tdsqlite3StrAccumFinish(&x); + sqlite3StrAccumFinish(&x); assert( zP4!=0 ); return zP4; } @@ -82669,11 +82669,11 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ ** is maintained in p->btreeMask. The p->lockMask value is the subset of ** p->btreeMask of databases that will require a lock. */ -SQLITE_PRIVATE void tdsqlite3VdbeUsesBtree(Vdbe *p, int i){ +SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ assert( i>=0 && idb->nDb && i<(int)sizeof(yDbMask)*8 ); assert( i<(int)sizeof(p->btreeMask)*8 ); DbMaskSet(p->btreeMask, i); - if( i!=1 && tdsqlite3BtreeSharable(p->db->aDb[i].pBt) ){ + if( i!=1 && sqlite3BtreeSharable(p->db->aDb[i].pBt) ){ DbMaskSet(p->lockMask, i); } } @@ -82687,7 +82687,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeUsesBtree(Vdbe *p, int i){ ** that the correct busy-handler callback is invoked if required. ** ** If SQLite is not threadsafe but does support shared-cache mode, then -** tdsqlite3BtreeEnter() is invoked to set the BtShared.db variables +** sqlite3BtreeEnter() is invoked to set the BtShared.db variables ** of all of BtShared structures accessible via the database handle ** associated with the VM. ** @@ -82700,9 +82700,9 @@ SQLITE_PRIVATE void tdsqlite3VdbeUsesBtree(Vdbe *p, int i){ ** this routine is N*N. But as N is rarely more than 1, this should not ** be a problem. */ -SQLITE_PRIVATE void tdsqlite3VdbeEnter(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe *p){ int i; - tdsqlite3 *db; + sqlite3 *db; Db *aDb; int nDb; if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ @@ -82711,7 +82711,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeEnter(Vdbe *p){ nDb = db->nDb; for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ - tdsqlite3BtreeEnter(aDb[i].pBt); + sqlite3BtreeEnter(aDb[i].pBt); } } } @@ -82719,11 +82719,11 @@ SQLITE_PRIVATE void tdsqlite3VdbeEnter(Vdbe *p){ #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 /* -** Unlock all of the btrees previously locked by a call to tdsqlite3VdbeEnter(). +** Unlock all of the btrees previously locked by a call to sqlite3VdbeEnter(). */ static SQLITE_NOINLINE void vdbeLeave(Vdbe *p){ int i; - tdsqlite3 *db; + sqlite3 *db; Db *aDb; int nDb; db = p->db; @@ -82731,11 +82731,11 @@ static SQLITE_NOINLINE void vdbeLeave(Vdbe *p){ nDb = db->nDb; for(i=0; ilockMask,i) && ALWAYS(aDb[i].pBt!=0) ){ - tdsqlite3BtreeLeave(aDb[i].pBt); + sqlite3BtreeLeave(aDb[i].pBt); } } } -SQLITE_PRIVATE void tdsqlite3VdbeLeave(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe *p){ if( DbMaskAllZero(p->lockMask) ) return; /* The common case */ vdbeLeave(p); } @@ -82745,7 +82745,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeLeave(Vdbe *p){ /* ** Print a single opcode. This routine is used for debugging only. */ -SQLITE_PRIVATE void tdsqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ +SQLITE_PRIVATE void sqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ char *zP4; char zPtr[50]; char zCom[100]; @@ -82757,11 +82757,11 @@ SQLITE_PRIVATE void tdsqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ #else zCom[0] = 0; #endif - /* NB: The tdsqlite3OpcodeName() function is implemented by code created + /* NB: The sqlite3OpcodeName() function is implemented by code created ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the ** information from the vdbe.c source text */ fprintf(pOut, zFormat1, pc, - tdsqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5, + sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5, zCom ); fflush(pOut); @@ -82771,7 +82771,7 @@ SQLITE_PRIVATE void tdsqlite3VdbePrintOp(FILE *pOut, int pc, VdbeOp *pOp){ /* ** Initialize an array of N Mem element. */ -static void initMemArray(Mem *p, int N, tdsqlite3 *db, u16 flags){ +static void initMemArray(Mem *p, int N, sqlite3 *db, u16 flags){ while( (N--)>0 ){ p->db = db; p->flags = flags; @@ -82789,36 +82789,36 @@ static void initMemArray(Mem *p, int N, tdsqlite3 *db, u16 flags){ static void releaseMemArray(Mem *p, int N){ if( p && N ){ Mem *pEnd = &p[N]; - tdsqlite3 *db = p->db; + sqlite3 *db = p->db; if( db->pnBytesFreed ){ do{ - if( p->szMalloc ) tdsqlite3DbFree(db, p->zMalloc); + if( p->szMalloc ) sqlite3DbFree(db, p->zMalloc); }while( (++p)flags & MEM_Agg ); testcase( p->flags & MEM_Dyn ); - testcase( p->xDel==tdsqlite3VdbeFrameMemDel ); + testcase( p->xDel==sqlite3VdbeFrameMemDel ); if( p->flags&(MEM_Agg|MEM_Dyn) ){ - tdsqlite3VdbeMemRelease(p); + sqlite3VdbeMemRelease(p); }else if( p->szMalloc ){ - tdsqlite3DbFreeNN(db, p->zMalloc); + sqlite3DbFreeNN(db, p->zMalloc); p->szMalloc = 0; } @@ -82834,7 +82834,7 @@ static void releaseMemArray(Mem *p, int N){ ** ** This routine is intended for use inside of assert() statements only. */ -SQLITE_PRIVATE int tdsqlite3VdbeFrameIsValid(VdbeFrame *pFrame){ +SQLITE_PRIVATE int sqlite3VdbeFrameIsValid(VdbeFrame *pFrame){ if( pFrame->iFrameMagic!=SQLITE_FRAME_MAGIC ) return 0; return 1; } @@ -82842,15 +82842,15 @@ SQLITE_PRIVATE int tdsqlite3VdbeFrameIsValid(VdbeFrame *pFrame){ /* -** This is a destructor on a Mem object (which is really an tdsqlite3_value) +** This is a destructor on a Mem object (which is really an sqlite3_value) ** that deletes the Frame object that is attached to it as a blob. ** ** This routine does not delete the Frame right away. It merely adds the ** frame to a list of frames to be deleted when the Vdbe halts. */ -SQLITE_PRIVATE void tdsqlite3VdbeFrameMemDel(void *pArg){ +SQLITE_PRIVATE void sqlite3VdbeFrameMemDel(void *pArg){ VdbeFrame *pFrame = (VdbeFrame*)pArg; - assert( tdsqlite3VdbeFrameIsValid(pFrame) ); + assert( sqlite3VdbeFrameIsValid(pFrame) ); pFrame->pParent = pFrame->v->pDelFrame; pFrame->v->pDelFrame = pFrame; } @@ -82858,26 +82858,26 @@ SQLITE_PRIVATE void tdsqlite3VdbeFrameMemDel(void *pArg){ /* ** Delete a VdbeFrame object and its contents. VdbeFrame objects are -** allocated by the OP_Program opcode in tdsqlite3VdbeExec(). +** allocated by the OP_Program opcode in sqlite3VdbeExec(). */ -SQLITE_PRIVATE void tdsqlite3VdbeFrameDelete(VdbeFrame *p){ +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){ int i; Mem *aMem = VdbeFrameMem(p); VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; - assert( tdsqlite3VdbeFrameIsValid(p) ); + assert( sqlite3VdbeFrameIsValid(p) ); for(i=0; inChildCsr; i++){ - tdsqlite3VdbeFreeCursor(p->v, apCsr[i]); + sqlite3VdbeFreeCursor(p->v, apCsr[i]); } releaseMemArray(aMem, p->nChildMem); - tdsqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0); - tdsqlite3DbFree(p->v->db, p); + sqlite3VdbeDeleteAuxData(p->v->db, &p->pAuxData, -1, 0); + sqlite3DbFree(p->v->db, p); } #ifndef SQLITE_OMIT_EXPLAIN /* ** Give a listing of the program in the virtual machine. ** -** The interface is the same as tdsqlite3VdbeExec(). But instead of +** The interface is the same as sqlite3VdbeExec(). But instead of ** running the code, it invokes the callback once for each instruction. ** This feature is used to implement "EXPLAIN". ** @@ -82892,14 +82892,14 @@ SQLITE_PRIVATE void tdsqlite3VdbeFrameDelete(VdbeFrame *p){ ** When p->explain==1, first the main program is listed, then each of ** the trigger subprograms are listed one by one. */ -SQLITE_PRIVATE int tdsqlite3VdbeList( +SQLITE_PRIVATE int sqlite3VdbeList( Vdbe *p /* The VDBE */ ){ int nRow; /* Stop when row count reaches this */ int nSub = 0; /* Number of sub-vdbes seen so far */ SubProgram **apSub = 0; /* Array of sub-vdbes */ Mem *pSub = 0; /* Memory cell hold array of subprogs */ - tdsqlite3 *db = p->db; /* The database connection */ + sqlite3 *db = p->db; /* The database connection */ int i; /* Loop counter */ int rc = SQLITE_OK; /* Return code */ Mem *pMem = &p->aMem[1]; /* First Mem of result set */ @@ -82912,20 +82912,20 @@ SQLITE_PRIVATE int tdsqlite3VdbeList( /* Even though this opcode does not use dynamic strings for ** the result, result columns may become dynamic if the user calls - ** tdsqlite3_column_text16(), causing a translation to UTF-16 encoding. + ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ releaseMemArray(pMem, 8); p->pResultSet = 0; if( p->rc==SQLITE_NOMEM ){ - /* This happens if a malloc() inside a call to tdsqlite3_column_text() or - ** tdsqlite3_column_text16() failed. */ - tdsqlite3OomFault(db); + /* This happens if a malloc() inside a call to sqlite3_column_text() or + ** sqlite3_column_text16() failed. */ + sqlite3OomFault(db); return SQLITE_ERROR; } /* When the number of output rows reaches nRow, that means the - ** listing has finished and tdsqlite3_step() should return SQLITE_DONE. + ** listing has finished and sqlite3_step() should return SQLITE_DONE. ** nRow is the sum of the number of rows in the main program, plus ** the sum of the number of rows in all trigger subprograms encountered ** so far. The nRow value will increase as new trigger subprograms are @@ -82940,7 +82940,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeList( assert( p->nMem>9 ); pSub = &p->aMem[9]; if( pSub->flags&MEM_Blob ){ - /* On the first call to tdsqlite3_step(), pSub will hold a NULL. It is + /* On the first call to sqlite3_step(), pSub will hold a NULL. It is ** initialized to a BLOB by the P4_SUBPROGRAM processing logic below */ nSub = pSub->n/sizeof(Vdbe*); apSub = (SubProgram **)pSub->z; @@ -82987,7 +82987,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeList( if( apSub[j]==pOp->p4.pProgram ) break; } if( j==nSub ){ - p->rc = tdsqlite3VdbeMemGrow(pSub, nByte, nSub!=0); + p->rc = sqlite3VdbeMemGrow(pSub, nByte, nSub!=0); if( p->rc!=SQLITE_OK ){ rc = SQLITE_ERROR; break; @@ -83008,7 +83008,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeList( if( db->u1.isInterrupted ){ p->rc = SQLITE_INTERRUPT; rc = SQLITE_ERROR; - tdsqlite3VdbeError(p, tdsqlite3ErrStr(p->rc)); + sqlite3VdbeError(p, sqlite3ErrStr(p->rc)); }else{ char *zP4; if( p->explain==1 ){ @@ -83017,9 +83017,9 @@ SQLITE_PRIVATE int tdsqlite3VdbeList( pMem++; pMem->flags = MEM_Static|MEM_Str|MEM_Term; - pMem->z = (char*)tdsqlite3OpcodeName(pOp->opcode); /* Opcode */ + pMem->z = (char*)sqlite3OpcodeName(pOp->opcode); /* Opcode */ assert( pMem->z!=0 ); - pMem->n = tdsqlite3Strlen30(pMem->z); + pMem->n = sqlite3Strlen30(pMem->z); pMem->enc = SQLITE_UTF8; pMem++; } @@ -83036,7 +83036,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeList( pMem->u.i = pOp->p3; /* P3 */ pMem++; - if( tdsqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */ + if( sqlite3VdbeMemClearAndResize(pMem, 100) ){ /* P4 */ assert( p->db->mallocFailed ); return SQLITE_ERROR; } @@ -83044,27 +83044,27 @@ SQLITE_PRIVATE int tdsqlite3VdbeList( zP4 = displayP4(pOp, pMem->z, pMem->szMalloc); if( zP4!=pMem->z ){ pMem->n = 0; - tdsqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); + sqlite3VdbeMemSetStr(pMem, zP4, -1, SQLITE_UTF8, 0); }else{ assert( pMem->z!=0 ); - pMem->n = tdsqlite3Strlen30(pMem->z); + pMem->n = sqlite3Strlen30(pMem->z); pMem->enc = SQLITE_UTF8; } pMem++; if( p->explain==1 ){ - if( tdsqlite3VdbeMemClearAndResize(pMem, 4) ){ + if( sqlite3VdbeMemClearAndResize(pMem, 4) ){ assert( p->db->mallocFailed ); return SQLITE_ERROR; } pMem->flags = MEM_Str|MEM_Term; pMem->n = 2; - tdsqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ + sqlite3_snprintf(3, pMem->z, "%.2x", pOp->p5); /* P5 */ pMem->enc = SQLITE_UTF8; pMem++; #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS - if( tdsqlite3VdbeMemClearAndResize(pMem, 500) ){ + if( sqlite3VdbeMemClearAndResize(pMem, 500) ){ assert( p->db->mallocFailed ); return SQLITE_ERROR; } @@ -83090,7 +83090,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeList( /* ** Print the SQL that was used to generate a VDBE program. */ -SQLITE_PRIVATE void tdsqlite3VdbePrintSql(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbePrintSql(Vdbe *p){ const char *z = 0; if( p->zSql ){ z = p->zSql; @@ -83098,7 +83098,7 @@ SQLITE_PRIVATE void tdsqlite3VdbePrintSql(Vdbe *p){ const VdbeOp *pOp = &p->aOp[0]; if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ z = pOp->p4.z; - while( tdsqlite3Isspace(*z) ) z++; + while( sqlite3Isspace(*z) ) z++; } } if( z ) printf("SQL: [%s]\n", z); @@ -83109,19 +83109,19 @@ SQLITE_PRIVATE void tdsqlite3VdbePrintSql(Vdbe *p){ /* ** Print an IOTRACE message showing SQL content. */ -SQLITE_PRIVATE void tdsqlite3VdbeIOTraceSql(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeIOTraceSql(Vdbe *p){ int nOp = p->nOp; VdbeOp *pOp; - if( tdsqlite3IoTrace==0 ) return; + if( sqlite3IoTrace==0 ) return; if( nOp<1 ) return; pOp = &p->aOp[0]; if( pOp->opcode==OP_Init && pOp->p4.z!=0 ){ int i, j; char z[1000]; - tdsqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z); - for(i=0; tdsqlite3Isspace(z[i]); i++){} + sqlite3_snprintf(sizeof(z), z, "%s", pOp->p4.z); + for(i=0; sqlite3Isspace(z[i]); i++){} for(j=0; z[i]; i++){ - if( tdsqlite3Isspace(z[i]) ){ + if( sqlite3Isspace(z[i]) ){ if( z[i-1]!=' ' ){ z[j++] = ' '; } @@ -83130,7 +83130,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeIOTraceSql(Vdbe *p){ } } z[j] = 0; - tdsqlite3IoTrace("SQL %s\n", z); + sqlite3IoTrace("SQL %s\n", z); } } #endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */ @@ -83141,8 +83141,8 @@ SQLITE_PRIVATE void tdsqlite3VdbeIOTraceSql(Vdbe *p){ */ struct ReusableSpace { u8 *pSpace; /* Available memory */ - tdsqlite3_int64 nFree; /* Bytes of available memory */ - tdsqlite3_int64 nNeeded; /* Total bytes that could not be allocated */ + sqlite3_int64 nFree; /* Bytes of available memory */ + sqlite3_int64 nNeeded; /* Total bytes that could not be allocated */ }; /* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf @@ -83162,7 +83162,7 @@ struct ReusableSpace { static void *allocSpace( struct ReusableSpace *p, /* Bulk memory available for allocation */ void *pBuf, /* Pointer to a prior allocation */ - tdsqlite3_int64 nByte /* Bytes of memory needed */ + sqlite3_int64 nByte /* Bytes of memory needed */ ){ assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) ); if( pBuf==0 ){ @@ -83182,7 +83182,7 @@ static void *allocSpace( ** Rewind the VDBE back to the beginning in preparation for ** running it. */ -SQLITE_PRIVATE void tdsqlite3VdbeRewind(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) int i; #endif @@ -83222,24 +83222,24 @@ SQLITE_PRIVATE void tdsqlite3VdbeRewind(Vdbe *p){ ** creating the virtual machine. This involves things such ** as allocating registers and initializing the program counter. ** After the VDBE has be prepped, it can be executed by one or more -** calls to tdsqlite3VdbeExec(). +** calls to sqlite3VdbeExec(). ** ** This function may be called exactly once on each virtual machine. ** After this routine is called the VM has been "packaged" and is ready ** to run. After this routine is called, further calls to -** tdsqlite3VdbeAddOp() functions are prohibited. This routine disconnects +** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects ** the Vdbe from the Parse object that helped generate it so that the ** the Vdbe becomes an independent entity and the Parse object can be ** destroyed. ** -** Use the tdsqlite3VdbeRewind() procedure to restore a virtual machine back +** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back ** to its initial state after it has been run. */ -SQLITE_PRIVATE void tdsqlite3VdbeMakeReady( +SQLITE_PRIVATE void sqlite3VdbeMakeReady( Vdbe *p, /* The VDBE */ Parse *pParse /* Parsing context */ ){ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ int nVar; /* Number of parameters */ int nMem; /* Number of VM memory registers */ int nCursor; /* Number of cursors required */ @@ -83288,16 +83288,16 @@ SQLITE_PRIVATE void tdsqlite3VdbeMakeReady( int iFirst, mx, i; if( nMem<10 ) nMem = 10; if( pParse->explain==2 ){ - tdsqlite3VdbeSetNumCols(p, 4); + sqlite3VdbeSetNumCols(p, 4); iFirst = 8; mx = 12; }else{ - tdsqlite3VdbeSetNumCols(p, 8); + sqlite3VdbeSetNumCols(p, 8); iFirst = 0; mx = 8; } for(i=iFirst; ianExec = allocSpace(&x, 0, p->nOp*sizeof(i64)); #endif if( x.nNeeded ){ - x.pSpace = p->pFree = tdsqlite3DbMallocRawNN(db, x.nNeeded); + x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded); x.nFree = x.nNeeded; if( !db->mallocFailed ){ p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem)); @@ -83353,38 +83353,38 @@ SQLITE_PRIVATE void tdsqlite3VdbeMakeReady( memset(p->anExec, 0, p->nOp*sizeof(i64)); #endif } - tdsqlite3VdbeRewind(p); + sqlite3VdbeRewind(p); } /* ** Close a VDBE cursor and release all the resources that cursor ** happens to hold. */ -SQLITE_PRIVATE void tdsqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ +SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx==0 ){ return; } assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); switch( pCx->eCurType ){ case CURTYPE_SORTER: { - tdsqlite3VdbeSorterClose(p->db, pCx); + sqlite3VdbeSorterClose(p->db, pCx); break; } case CURTYPE_BTREE: { if( pCx->isEphemeral ){ - if( pCx->pBtx ) tdsqlite3BtreeClose(pCx->pBtx); + if( pCx->pBtx ) sqlite3BtreeClose(pCx->pBtx); /* The pCx->pCursor will be close automatically, if it exists, by ** the call above. */ }else{ assert( pCx->uc.pCursor!=0 ); - tdsqlite3BtreeCloseCursor(pCx->uc.pCursor); + sqlite3BtreeCloseCursor(pCx->uc.pCursor); } break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case CURTYPE_VTAB: { - tdsqlite3_vtab_cursor *pVCur = pCx->uc.pVCur; - const tdsqlite3_module *pModule = pVCur->pVtab->pModule; + sqlite3_vtab_cursor *pVCur = pCx->uc.pVCur; + const sqlite3_module *pModule = pVCur->pVtab->pModule; assert( pVCur->pVtab->nRef>0 ); pVCur->pVtab->nRef--; pModule->xClose(pVCur); @@ -83403,7 +83403,7 @@ static void closeCursorsInFrame(Vdbe *p){ for(i=0; inCursor; i++){ VdbeCursor *pC = p->apCsr[i]; if( pC ){ - tdsqlite3VdbeFreeCursor(p, pC); + sqlite3VdbeFreeCursor(p, pC); p->apCsr[i] = 0; } } @@ -83415,7 +83415,7 @@ static void closeCursorsInFrame(Vdbe *p){ ** is used, for example, when a trigger sub-program is halted to restore ** control to the main program. */ -SQLITE_PRIVATE int tdsqlite3VdbeFrameRestore(VdbeFrame *pFrame){ +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ Vdbe *v = pFrame->v; closeCursorsInFrame(v); #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -83430,7 +83430,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeFrameRestore(VdbeFrame *pFrame){ v->db->lastRowid = pFrame->lastRowid; v->nChange = pFrame->nChange; v->db->nChange = pFrame->nDbChange; - tdsqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0); + sqlite3VdbeDeleteAuxData(v->db, &v->pAuxData, -1, 0); v->pAuxData = pFrame->pAuxData; pFrame->pAuxData = 0; return pFrame->pc; @@ -83448,7 +83448,7 @@ static void closeAllCursors(Vdbe *p){ if( p->pFrame ){ VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); - tdsqlite3VdbeFrameRestore(pFrame); + sqlite3VdbeFrameRestore(pFrame); p->pFrame = 0; p->nFrame = 0; } @@ -83460,31 +83460,31 @@ static void closeAllCursors(Vdbe *p){ while( p->pDelFrame ){ VdbeFrame *pDel = p->pDelFrame; p->pDelFrame = pDel->pParent; - tdsqlite3VdbeFrameDelete(pDel); + sqlite3VdbeFrameDelete(pDel); } /* Delete any auxdata allocations made by the VM */ - if( p->pAuxData ) tdsqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0); + if( p->pAuxData ) sqlite3VdbeDeleteAuxData(p->db, &p->pAuxData, -1, 0); assert( p->pAuxData==0 ); } /* ** Set the number of result columns that will be returned by this SQL ** statement. This is now set at compile time, rather than during -** execution of the vdbe program so that tdsqlite3_column_count() can -** be called on an SQL statement before tdsqlite3_step(). +** execution of the vdbe program so that sqlite3_column_count() can +** be called on an SQL statement before sqlite3_step(). */ -SQLITE_PRIVATE void tdsqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ +SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ int n; - tdsqlite3 *db = p->db; + sqlite3 *db = p->db; if( p->nResColumn ){ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); - tdsqlite3DbFree(db, p->aColName); + sqlite3DbFree(db, p->aColName); } n = nResColumn*COLNAME_N; p->nResColumn = (u16)nResColumn; - p->aColName = (Mem*)tdsqlite3DbMallocRawNN(db, sizeof(Mem)*n ); + p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); if( p->aColName==0 ) return; initMemArray(p->aColName, n, db, MEM_Null); } @@ -83493,13 +83493,13 @@ SQLITE_PRIVATE void tdsqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ ** Set the name of the idx'th column to be returned by the SQL statement. ** zName must be a pointer to a nul terminated string. ** -** This call must be made after a call to tdsqlite3VdbeSetNumCols(). +** This call must be made after a call to sqlite3VdbeSetNumCols(). ** ** The final parameter, xDel, must be one of SQLITE_DYNAMIC, SQLITE_STATIC ** or SQLITE_TRANSIENT. If it is SQLITE_DYNAMIC, then the buffer pointed -** to by zName will be freed by tdsqlite3DbFree() when the vdbe is destroyed. +** to by zName will be freed by sqlite3DbFree() when the vdbe is destroyed. */ -SQLITE_PRIVATE int tdsqlite3VdbeSetColName( +SQLITE_PRIVATE int sqlite3VdbeSetColName( Vdbe *p, /* Vdbe being configured */ int idx, /* Index of column zName applies to */ int var, /* One of the COLNAME_* constants */ @@ -83516,7 +83516,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSetColName( } assert( p->aColName!=0 ); pColName = &(p->aColName[idx+var*p->nResColumn]); - rc = tdsqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); + rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); return rc; } @@ -83527,7 +83527,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSetColName( ** write-transaction spanning more than one database file, this routine ** takes care of the master journal trickery. */ -static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ +static int vdbeCommit(sqlite3 *db, Vdbe *p){ int i; int nTrans = 0; /* Number of databases with an active write-transaction ** that are candidates for a two-phase commit using a @@ -83536,7 +83536,7 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ int needXcommit = 0; #ifdef SQLITE_OMIT_VIRTUALTABLE - /* With this option, tdsqlite3VtabSync() is defined to be simply + /* With this option, sqlite3VtabSync() is defined to be simply ** SQLITE_OK so p is not used. */ UNUSED_PARAMETER(p); @@ -83548,7 +83548,7 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ ** required, as an xSync() callback may add an attached database ** to the transaction. */ - rc = tdsqlite3VtabSync(db, p); + rc = sqlite3VtabSync(db, p); /* This loop determines (a) if the commit hook should be invoked and ** (b) how many database files have open write transactions, not @@ -83558,7 +83558,7 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ */ for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( tdsqlite3BtreeIsInTrans(pBt) ){ + if( sqlite3BtreeIsInTrans(pBt) ){ /* Whether or not a database might need a master journal depends upon ** its journal mode (among other things). This matrix determines which ** journal modes use a master journal and which do not */ @@ -83572,17 +83572,17 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ }; Pager *pPager; /* Pager associated with pBt */ needXcommit = 1; - tdsqlite3BtreeEnter(pBt); - pPager = tdsqlite3BtreePager(pBt); + sqlite3BtreeEnter(pBt); + pPager = sqlite3BtreePager(pBt); if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF - && aMJNeeded[tdsqlite3PagerGetJournalMode(pPager)] - && tdsqlite3PagerIsMemdb(pPager)==0 + && aMJNeeded[sqlite3PagerGetJournalMode(pPager)] + && sqlite3PagerIsMemdb(pPager)==0 ){ assert( i!=1 ); nTrans++; } - rc = tdsqlite3PagerExclusiveLock(pPager); - tdsqlite3BtreeLeave(pBt); + rc = sqlite3PagerExclusiveLock(pPager); + sqlite3BtreeLeave(pBt); } } if( rc!=SQLITE_OK ){ @@ -83601,18 +83601,18 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ ** TEMP database) has a transaction active. There is no need for the ** master-journal. ** - ** If the return value of tdsqlite3BtreeGetFilename() is a zero length + ** If the return value of sqlite3BtreeGetFilename() is a zero length ** string, it means the main database is :memory: or a temp file. In ** that case we do not support atomic multi-file commits, so use the ** simple case then too. */ - if( 0==tdsqlite3Strlen30(tdsqlite3BtreeGetFilename(db->aDb[0].pBt)) + if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){ for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ - rc = tdsqlite3BtreeCommitPhaseOne(pBt, 0); + rc = sqlite3BtreeCommitPhaseOne(pBt, 0); } } @@ -83624,11 +83624,11 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ - rc = tdsqlite3BtreeCommitPhaseTwo(pBt, 0); + rc = sqlite3BtreeCommitPhaseTwo(pBt, 0); } } if( rc==SQLITE_OK ){ - tdsqlite3VtabCommit(db); + sqlite3VtabCommit(db); } } @@ -83638,49 +83638,49 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ */ #ifndef SQLITE_OMIT_DISKIO else{ - tdsqlite3_vfs *pVfs = db->pVfs; + sqlite3_vfs *pVfs = db->pVfs; char *zMaster = 0; /* File-name for the master journal */ - char const *zMainFile = tdsqlite3BtreeGetFilename(db->aDb[0].pBt); - tdsqlite3_file *pMaster = 0; + char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt); + sqlite3_file *pMaster = 0; i64 offset = 0; int res; int retryCount = 0; int nMainFile; /* Select a master journal file name */ - nMainFile = tdsqlite3Strlen30(zMainFile); - zMaster = tdsqlite3MPrintf(db, "%s-mjXXXXXX9XXz%c%c", zMainFile, 0, 0); + nMainFile = sqlite3Strlen30(zMainFile); + zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz%c%c", zMainFile, 0, 0); if( zMaster==0 ) return SQLITE_NOMEM_BKPT; do { u32 iRandom; if( retryCount ){ if( retryCount>100 ){ - tdsqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster); - tdsqlite3OsDelete(pVfs, zMaster, 0); + sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster); + sqlite3OsDelete(pVfs, zMaster, 0); break; }else if( retryCount==1 ){ - tdsqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster); + sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster); } } retryCount++; - tdsqlite3_randomness(sizeof(iRandom), &iRandom); - tdsqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X", + sqlite3_randomness(sizeof(iRandom), &iRandom); + sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X", (iRandom>>8)&0xffffff, iRandom&0xff); /* The antipenultimate character of the master journal name must ** be "9" to avoid name collisions when using 8+3 filenames. */ - assert( zMaster[tdsqlite3Strlen30(zMaster)-3]=='9' ); - tdsqlite3FileSuffix3(zMainFile, zMaster); - rc = tdsqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); + assert( zMaster[sqlite3Strlen30(zMaster)-3]=='9' ); + sqlite3FileSuffix3(zMainFile, zMaster); + rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res); }while( rc==SQLITE_OK && res ); if( rc==SQLITE_OK ){ /* Open the master journal. */ - rc = tdsqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, + rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_MASTER_JOURNAL, 0 ); } if( rc!=SQLITE_OK ){ - tdsqlite3DbFree(db, zMaster); + sqlite3DbFree(db, zMaster); return rc; } @@ -83692,18 +83692,18 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ */ for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( tdsqlite3BtreeIsInTrans(pBt) ){ - char const *zFile = tdsqlite3BtreeGetJournalname(pBt); + if( sqlite3BtreeIsInTrans(pBt) ){ + char const *zFile = sqlite3BtreeGetJournalname(pBt); if( zFile==0 ){ continue; /* Ignore TEMP and :memory: databases */ } assert( zFile[0]!=0 ); - rc = tdsqlite3OsWrite(pMaster, zFile, tdsqlite3Strlen30(zFile)+1, offset); - offset += tdsqlite3Strlen30(zFile)+1; + rc = sqlite3OsWrite(pMaster, zFile, sqlite3Strlen30(zFile)+1, offset); + offset += sqlite3Strlen30(zFile)+1; if( rc!=SQLITE_OK ){ - tdsqlite3OsCloseFree(pMaster); - tdsqlite3OsDelete(pVfs, zMaster, 0); - tdsqlite3DbFree(db, zMaster); + sqlite3OsCloseFree(pMaster); + sqlite3OsDelete(pVfs, zMaster, 0); + sqlite3DbFree(db, zMaster); return rc; } } @@ -83712,12 +83712,12 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ /* Sync the master journal file. If the IOCAP_SEQUENTIAL device ** flag is set this is not required. */ - if( 0==(tdsqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL) - && SQLITE_OK!=(rc = tdsqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL)) + if( 0==(sqlite3OsDeviceCharacteristics(pMaster)&SQLITE_IOCAP_SEQUENTIAL) + && SQLITE_OK!=(rc = sqlite3OsSync(pMaster, SQLITE_SYNC_NORMAL)) ){ - tdsqlite3OsCloseFree(pMaster); - tdsqlite3OsDelete(pVfs, zMaster, 0); - tdsqlite3DbFree(db, zMaster); + sqlite3OsCloseFree(pMaster); + sqlite3OsDelete(pVfs, zMaster, 0); + sqlite3DbFree(db, zMaster); return rc; } @@ -83726,7 +83726,7 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ ** an error occurs here, do not delete the master journal file. ** ** If the error occurs during the first call to - ** tdsqlite3BtreeCommitPhaseOne(), then there is a chance that the + ** sqlite3BtreeCommitPhaseOne(), then there is a chance that the ** master journal file will be orphaned. But we cannot delete it, ** in case the master journal file name was written into the journal ** file before the failure occurred. @@ -83734,13 +83734,13 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ - rc = tdsqlite3BtreeCommitPhaseOne(pBt, zMaster); + rc = sqlite3BtreeCommitPhaseOne(pBt, zMaster); } } - tdsqlite3OsCloseFree(pMaster); + sqlite3OsCloseFree(pMaster); assert( rc!=SQLITE_BUSY ); if( rc!=SQLITE_OK ){ - tdsqlite3DbFree(db, zMaster); + sqlite3DbFree(db, zMaster); return rc; } @@ -83748,32 +83748,32 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ ** doing this the directory is synced again before any individual ** transaction files are deleted. */ - rc = tdsqlite3OsDelete(pVfs, zMaster, 1); - tdsqlite3DbFree(db, zMaster); + rc = sqlite3OsDelete(pVfs, zMaster, 1); + sqlite3DbFree(db, zMaster); zMaster = 0; if( rc ){ return rc; } /* All files and directories have already been synced, so the following - ** calls to tdsqlite3BtreeCommitPhaseTwo() are only closing files and + ** calls to sqlite3BtreeCommitPhaseTwo() are only closing files and ** deleting or truncating journals. If something goes wrong while ** this is happening we don't really care. The integrity of the ** transaction is already guaranteed, but some stray 'cold' journals ** may be lying around. Returning an error code won't help matters. */ disable_simulated_io_errors(); - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ - tdsqlite3BtreeCommitPhaseTwo(pBt, 1); + sqlite3BtreeCommitPhaseTwo(pBt, 1); } } - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); enable_simulated_io_errors(); - tdsqlite3VtabCommit(db); + sqlite3VtabCommit(db); } #endif @@ -83790,14 +83790,14 @@ static int vdbeCommit(tdsqlite3 *db, Vdbe *p){ ** This is a no-op if NDEBUG is defined. */ #ifndef NDEBUG -static void checkActiveVdbeCnt(tdsqlite3 *db){ +static void checkActiveVdbeCnt(sqlite3 *db){ Vdbe *p; int cnt = 0; int nWrite = 0; int nRead = 0; p = db->pVdbe; while( p ){ - if( tdsqlite3_stmt_busy((tdsqlite3_stmt*)p) ){ + if( sqlite3_stmt_busy((sqlite3_stmt*)p) ){ cnt++; if( p->readOnly==0 ) nWrite++; if( p->bIsReader ) nRead++; @@ -83823,7 +83823,7 @@ static void checkActiveVdbeCnt(tdsqlite3 *db){ ** Otherwise SQLITE_OK. */ static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){ - tdsqlite3 *const db = p->db; + sqlite3 *const db = p->db; int rc = SQLITE_OK; int i; const int iSavepoint = p->iStatement-1; @@ -83837,10 +83837,10 @@ static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ if( eOp==SAVEPOINT_ROLLBACK ){ - rc2 = tdsqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint); + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_ROLLBACK, iSavepoint); } if( rc2==SQLITE_OK ){ - rc2 = tdsqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint); + rc2 = sqlite3BtreeSavepoint(pBt, SAVEPOINT_RELEASE, iSavepoint); } if( rc==SQLITE_OK ){ rc = rc2; @@ -83852,10 +83852,10 @@ static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){ if( rc==SQLITE_OK ){ if( eOp==SAVEPOINT_ROLLBACK ){ - rc = tdsqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); + rc = sqlite3VtabSavepoint(db, SAVEPOINT_ROLLBACK, iSavepoint); } if( rc==SQLITE_OK ){ - rc = tdsqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); + rc = sqlite3VtabSavepoint(db, SAVEPOINT_RELEASE, iSavepoint); } } @@ -83868,7 +83868,7 @@ static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){ } return rc; } -SQLITE_PRIVATE int tdsqlite3VdbeCloseStatement(Vdbe *p, int eOp){ +SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ if( p->db->nStatement && p->iStatement ){ return vdbeCloseStatement(p, eOp); } @@ -83887,14 +83887,14 @@ SQLITE_PRIVATE int tdsqlite3VdbeCloseStatement(Vdbe *p, int eOp){ ** and write an error message to it. Then return SQLITE_ERROR. */ #ifndef SQLITE_OMIT_FOREIGN_KEY -SQLITE_PRIVATE int tdsqlite3VdbeCheckFk(Vdbe *p, int deferred){ - tdsqlite3 *db = p->db; +SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ + sqlite3 *db = p->db; if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) || (!deferred && p->nFkConstraint>0) ){ p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; p->errorAction = OE_Abort; - tdsqlite3VdbeError(p, "FOREIGN KEY constraint failed"); + sqlite3VdbeError(p, "FOREIGN KEY constraint failed"); return SQLITE_ERROR; } return SQLITE_OK; @@ -83914,9 +83914,9 @@ SQLITE_PRIVATE int tdsqlite3VdbeCheckFk(Vdbe *p, int deferred){ ** lock contention, return SQLITE_BUSY. If SQLITE_BUSY is returned, it ** means the close did not happen and needs to be repeated. */ -SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ +SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ int rc; /* Used to store transient return codes */ - tdsqlite3 *db = p->db; + sqlite3 *db = p->db; /* This function contains the logic that determines if a statement or ** transaction will be committed or rolled back as a result of the @@ -83951,7 +83951,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ int isSpecialError; /* Set to true if a 'special' error */ /* Lock all btrees used by the statement */ - tdsqlite3VdbeEnter(p); + sqlite3VdbeEnter(p); /* Check for one of the special errors */ mrc = p->rc & 0xff; @@ -83977,8 +83977,8 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ /* We are forced to roll back the active transaction. Before doing ** so, abort any other statements this handle currently has active. */ - tdsqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - tdsqlite3CloseSavepoints(db); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); db->autoCommit = 1; p->nChange = 0; } @@ -83987,7 +83987,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ /* Check for immediate foreign key violations. */ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ - tdsqlite3VdbeCheckFk(p, 0); + sqlite3VdbeCheckFk(p, 0); } /* If the auto-commit flag is set and this is the only active writer @@ -83996,15 +83996,15 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ ** Note: This block also runs if one of the special errors handled ** above has occurred. */ - if( !tdsqlite3VtabInSync(db) + if( !sqlite3VtabInSync(db) && db->autoCommit && db->nVdbeWrite==(p->readOnly==0) ){ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ - rc = tdsqlite3VdbeCheckFk(p, 1); + rc = sqlite3VdbeCheckFk(p, 1); if( rc!=SQLITE_OK ){ if( NEVER(p->readOnly) ){ - tdsqlite3VdbeLeave(p); + sqlite3VdbeLeave(p); return SQLITE_ERROR; } rc = SQLITE_CONSTRAINT_FOREIGNKEY; @@ -84016,20 +84016,20 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ rc = vdbeCommit(db, p); } if( rc==SQLITE_BUSY && p->readOnly ){ - tdsqlite3VdbeLeave(p); + sqlite3VdbeLeave(p); return SQLITE_BUSY; }else if( rc!=SQLITE_OK ){ p->rc = rc; - tdsqlite3RollbackAll(db, SQLITE_OK); + sqlite3RollbackAll(db, SQLITE_OK); p->nChange = 0; }else{ db->nDeferredCons = 0; db->nDeferredImmCons = 0; db->flags &= ~(u64)SQLITE_DeferFKs; - tdsqlite3CommitInternalChanges(db); + sqlite3CommitInternalChanges(db); } }else{ - tdsqlite3RollbackAll(db, SQLITE_OK); + sqlite3RollbackAll(db, SQLITE_OK); p->nChange = 0; } db->nStatement = 0; @@ -84039,29 +84039,29 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ }else if( p->errorAction==OE_Abort ){ eStatementOp = SAVEPOINT_ROLLBACK; }else{ - tdsqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - tdsqlite3CloseSavepoints(db); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); db->autoCommit = 1; p->nChange = 0; } } /* If eStatementOp is non-zero, then a statement transaction needs to - ** be committed or rolled back. Call tdsqlite3VdbeCloseStatement() to + ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to ** do so. If this operation returns an error, and the current statement ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the ** current statement error code. */ if( eStatementOp ){ - rc = tdsqlite3VdbeCloseStatement(p, eStatementOp); + rc = sqlite3VdbeCloseStatement(p, eStatementOp); if( rc ){ if( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_CONSTRAINT ){ p->rc = rc; - tdsqlite3DbFree(db, p->zErrMsg); + sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; } - tdsqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); - tdsqlite3CloseSavepoints(db); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3CloseSavepoints(db); db->autoCommit = 1; p->nChange = 0; } @@ -84072,15 +84072,15 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ */ if( p->changeCntOn ){ if( eStatementOp!=SAVEPOINT_ROLLBACK ){ - tdsqlite3VdbeSetChanges(db, p->nChange); + sqlite3VdbeSetChanges(db, p->nChange); }else{ - tdsqlite3VdbeSetChanges(db, 0); + sqlite3VdbeSetChanges(db, 0); } p->nChange = 0; } /* Release the locks */ - tdsqlite3VdbeLeave(p); + sqlite3VdbeLeave(p); } /* We have successfully halted and closed the VM. Record this fact. */ @@ -84099,11 +84099,11 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ } /* If the auto-commit flag is set to true, then any locks that were held - ** by connection db have now been released. Call tdsqlite3ConnectionUnlocked() + ** by connection db have now been released. Call sqlite3ConnectionUnlocked() ** to invoke any required unlock-notify callbacks. */ if( db->autoCommit ){ - tdsqlite3ConnectionUnlocked(db); + sqlite3ConnectionUnlocked(db); } assert( db->nVdbeActive>0 || db->autoCommit==0 || db->nStatement==0 ); @@ -84112,33 +84112,33 @@ SQLITE_PRIVATE int tdsqlite3VdbeHalt(Vdbe *p){ /* -** Each VDBE holds the result of the most recent tdsqlite3_step() call +** Each VDBE holds the result of the most recent sqlite3_step() call ** in p->rc. This routine sets that result back to SQLITE_OK. */ -SQLITE_PRIVATE void tdsqlite3VdbeResetStepResult(Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe *p){ p->rc = SQLITE_OK; } /* ** Copy the error code and error message belonging to the VDBE passed ** as the first argument to its database handle (so that they will be -** returned by calls to tdsqlite3_errcode() and tdsqlite3_errmsg()). +** returned by calls to sqlite3_errcode() and sqlite3_errmsg()). ** ** This function does not clear the VDBE error code or message, just ** copies them to the database handle. */ -SQLITE_PRIVATE int tdsqlite3VdbeTransferError(Vdbe *p){ - tdsqlite3 *db = p->db; +SQLITE_PRIVATE int sqlite3VdbeTransferError(Vdbe *p){ + sqlite3 *db = p->db; int rc = p->rc; if( p->zErrMsg ){ db->bBenignMalloc++; - tdsqlite3BeginBenignMalloc(); - if( db->pErr==0 ) db->pErr = tdsqlite3ValueNew(db); - tdsqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); - tdsqlite3EndBenignMalloc(); + sqlite3BeginBenignMalloc(); + if( db->pErr==0 ) db->pErr = sqlite3ValueNew(db); + sqlite3ValueSetStr(db->pErr, -1, p->zErrMsg, SQLITE_UTF8, SQLITE_TRANSIENT); + sqlite3EndBenignMalloc(); db->bBenignMalloc--; }else if( db->pErr ){ - tdsqlite3ValueSetNull(db->pErr); + sqlite3ValueSetNull(db->pErr); } db->errCode = rc; return rc; @@ -84150,14 +84150,14 @@ SQLITE_PRIVATE int tdsqlite3VdbeTransferError(Vdbe *p){ ** invoke it. */ static void vdbeInvokeSqllog(Vdbe *v){ - if( tdsqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){ - char *zExpanded = tdsqlite3VdbeExpandSql(v, v->zSql); + if( sqlite3GlobalConfig.xSqllog && v->rc==SQLITE_OK && v->zSql && v->pc>=0 ){ + char *zExpanded = sqlite3VdbeExpandSql(v, v->zSql); assert( v->db->init.busy==0 ); if( zExpanded ){ - tdsqlite3GlobalConfig.xSqllog( - tdsqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1 + sqlite3GlobalConfig.xSqllog( + sqlite3GlobalConfig.pSqllogArg, v->db, zExpanded, 1 ); - tdsqlite3DbFree(v->db, zExpanded); + sqlite3DbFree(v->db, zExpanded); } } } @@ -84176,19 +84176,19 @@ static void vdbeInvokeSqllog(Vdbe *v){ ** virtual machine from VDBE_MAGIC_RUN or VDBE_MAGIC_HALT back to ** VDBE_MAGIC_INIT. */ -SQLITE_PRIVATE int tdsqlite3VdbeReset(Vdbe *p){ +SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe *p){ #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) int i; #endif - tdsqlite3 *db; + sqlite3 *db; db = p->db; /* If the VM did not run to completion or if it encountered an ** error, then it might not have been halted properly. So halt ** it now. */ - tdsqlite3VdbeHalt(p); + sqlite3VdbeHalt(p); /* If the VDBE has been run even partially, then transfer the error code ** and error message from the VDBE into the main database structure. But @@ -84197,14 +84197,14 @@ SQLITE_PRIVATE int tdsqlite3VdbeReset(Vdbe *p){ */ if( p->pc>=0 ){ vdbeInvokeSqllog(p); - tdsqlite3VdbeTransferError(p); + sqlite3VdbeTransferError(p); if( p->runOnlyOnce ) p->expired = 1; }else if( p->rc && p->expired ){ /* The expired flag was set on the VDBE before the first call - ** to tdsqlite3_step(). For consistency (since tdsqlite3_step() was + ** to sqlite3_step(). For consistency (since sqlite3_step() was ** called), set the database error in this case as well. */ - tdsqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); + sqlite3ErrorWithMsg(db, p->rc, p->zErrMsg ? "%s" : 0, p->zErrMsg); } /* Reset register contents and reclaim error message memory. @@ -84217,7 +84217,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeReset(Vdbe *p){ for(i=0; inMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); } #endif - tdsqlite3DbFree(db, p->zErrMsg); + sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; p->pResultSet = 0; #ifdef SQLITE_DEBUG @@ -84247,13 +84247,13 @@ SQLITE_PRIVATE int tdsqlite3VdbeReset(Vdbe *p){ } for(i=0; inOp; i++){ char zHdr[100]; - tdsqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", + sqlite3_snprintf(sizeof(zHdr), zHdr, "%6u %12llu %8llu ", p->aOp[i].cnt, p->aOp[i].cycles, p->aOp[i].cnt>0 ? p->aOp[i].cycles/p->aOp[i].cnt : 0 ); fprintf(out, "%s", zHdr); - tdsqlite3VdbePrintOp(out, i, &p->aOp[i]); + sqlite3VdbePrintOp(out, i, &p->aOp[i]); } fclose(out); } @@ -84267,13 +84267,13 @@ SQLITE_PRIVATE int tdsqlite3VdbeReset(Vdbe *p){ ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. */ -SQLITE_PRIVATE int tdsqlite3VdbeFinalize(Vdbe *p){ +SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ int rc = SQLITE_OK; if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ - rc = tdsqlite3VdbeReset(p); + rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); } - tdsqlite3VdbeDelete(p); + sqlite3VdbeDelete(p); return rc; } @@ -84293,7 +84293,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeFinalize(Vdbe *p){ ** * the corresponding bit in argument mask is clear (where the first ** function parameter corresponds to bit 0 etc.). */ -SQLITE_PRIVATE void tdsqlite3VdbeDeleteAuxData(tdsqlite3 *db, AuxData **pp, int iOp, int mask){ +SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(sqlite3 *db, AuxData **pp, int iOp, int mask){ while( *pp ){ AuxData *pAux = *pp; if( (iOp<0) @@ -84306,7 +84306,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeDeleteAuxData(tdsqlite3 *db, AuxData **pp, int pAux->xDeleteAux(pAux->pAux); } *pp = pAux->pNextAux; - tdsqlite3DbFree(db, pAux); + sqlite3DbFree(db, pAux); }else{ pp= &pAux->pNextAux; } @@ -84317,34 +84317,34 @@ SQLITE_PRIVATE void tdsqlite3VdbeDeleteAuxData(tdsqlite3 *db, AuxData **pp, int ** Free all memory associated with the Vdbe passed as the second argument, ** except for object itself, which is preserved. ** -** The difference between this function and tdsqlite3VdbeDelete() is that +** The difference between this function and sqlite3VdbeDelete() is that ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with ** the database connection and frees the object itself. */ -SQLITE_PRIVATE void tdsqlite3VdbeClearObject(tdsqlite3 *db, Vdbe *p){ +SQLITE_PRIVATE void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){ SubProgram *pSub, *pNext; assert( p->db==0 || p->db==db ); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); for(pSub=p->pProgram; pSub; pSub=pNext){ pNext = pSub->pNext; vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); - tdsqlite3DbFree(db, pSub); + sqlite3DbFree(db, pSub); } if( p->magic!=VDBE_MAGIC_INIT ){ releaseMemArray(p->aVar, p->nVar); - tdsqlite3DbFree(db, p->pVList); - tdsqlite3DbFree(db, p->pFree); + sqlite3DbFree(db, p->pVList); + sqlite3DbFree(db, p->pFree); } vdbeFreeOpArray(db, p->aOp, p->nOp); - tdsqlite3DbFree(db, p->aColName); - tdsqlite3DbFree(db, p->zSql); + sqlite3DbFree(db, p->aColName); + sqlite3DbFree(db, p->zSql); #ifdef SQLITE_ENABLE_NORMALIZE - tdsqlite3DbFree(db, p->zNormSql); + sqlite3DbFree(db, p->zNormSql); { DblquoteStr *pThis, *pNext; for(pThis=p->pDblStr; pThis; pThis=pNext){ pNext = pThis->pNextStr; - tdsqlite3DbFree(db, pThis); + sqlite3DbFree(db, pThis); } } #endif @@ -84352,9 +84352,9 @@ SQLITE_PRIVATE void tdsqlite3VdbeClearObject(tdsqlite3 *db, Vdbe *p){ { int i; for(i=0; inScan; i++){ - tdsqlite3DbFree(db, p->aScan[i].zName); + sqlite3DbFree(db, p->aScan[i].zName); } - tdsqlite3DbFree(db, p->aScan); + sqlite3DbFree(db, p->aScan); } #endif } @@ -84362,13 +84362,13 @@ SQLITE_PRIVATE void tdsqlite3VdbeClearObject(tdsqlite3 *db, Vdbe *p){ /* ** Delete an entire VDBE. */ -SQLITE_PRIVATE void tdsqlite3VdbeDelete(Vdbe *p){ - tdsqlite3 *db; +SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ + sqlite3 *db; assert( p!=0 ); db = p->db; - assert( tdsqlite3_mutex_held(db->mutex) ); - tdsqlite3VdbeClearObject(db, p); + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3VdbeClearObject(db, p); if( p->pPrev ){ p->pPrev->pNext = p->pNext; }else{ @@ -84380,7 +84380,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeDelete(Vdbe *p){ } p->magic = VDBE_MAGIC_DEAD; p->db = 0; - tdsqlite3DbFreeNN(db, p); + sqlite3DbFreeNN(db, p); } /* @@ -84388,19 +84388,19 @@ SQLITE_PRIVATE void tdsqlite3VdbeDelete(Vdbe *p){ ** carried out. Seek the cursor now. If an error occurs, return ** the appropriate error code. */ -SQLITE_PRIVATE int SQLITE_NOINLINE tdsqlite3VdbeFinishMoveto(VdbeCursor *p){ +SQLITE_PRIVATE int SQLITE_NOINLINE sqlite3VdbeFinishMoveto(VdbeCursor *p){ int res, rc; #ifdef SQLITE_TEST - extern int tdsqlite3_search_count; + extern int sqlite3_search_count; #endif assert( p->deferredMoveto ); assert( p->isTable ); assert( p->eCurType==CURTYPE_BTREE ); - rc = tdsqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->movetoTarget, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(p->uc.pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; if( res!=0 ) return SQLITE_CORRUPT_BKPT; #ifdef SQLITE_TEST - tdsqlite3_search_count++; + sqlite3_search_count++; #endif p->deferredMoveto = 0; p->cacheStatus = CACHE_STALE; @@ -84418,8 +84418,8 @@ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ int isDifferentRow, rc; assert( p->eCurType==CURTYPE_BTREE ); assert( p->uc.pCursor!=0 ); - assert( tdsqlite3BtreeCursorHasMoved(p->uc.pCursor) ); - rc = tdsqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow); + assert( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ); + rc = sqlite3BtreeCursorRestore(p->uc.pCursor, &isDifferentRow); p->cacheStatus = CACHE_STALE; if( isDifferentRow ) p->nullRow = 1; return rc; @@ -84429,9 +84429,9 @@ static int SQLITE_NOINLINE handleMovedCursor(VdbeCursor *p){ ** Check to ensure that the cursor is valid. Restore the cursor ** if need be. Return any I/O error from the restore operation. */ -SQLITE_PRIVATE int tdsqlite3VdbeCursorRestore(VdbeCursor *p){ +SQLITE_PRIVATE int sqlite3VdbeCursorRestore(VdbeCursor *p){ assert( p->eCurType==CURTYPE_BTREE ); - if( tdsqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ return handleMovedCursor(p); } return SQLITE_OK; @@ -84450,7 +84450,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeCursorRestore(VdbeCursor *p){ ** If the cursor is already pointing to the correct row and that row has ** not been deleted out from under the cursor, then this routine is a no-op. */ -SQLITE_PRIVATE int tdsqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ +SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ VdbeCursor *p = *pp; assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); if( p->deferredMoveto ){ @@ -84460,9 +84460,9 @@ SQLITE_PRIVATE int tdsqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ *piCol = iMap - 1; return SQLITE_OK; } - return tdsqlite3VdbeFinishMoveto(p); + return sqlite3VdbeFinishMoveto(p); } - if( tdsqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ + if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){ return handleMovedCursor(p); } return SQLITE_OK; @@ -84471,11 +84471,11 @@ SQLITE_PRIVATE int tdsqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ /* ** The following functions: ** -** tdsqlite3VdbeSerialType() -** tdsqlite3VdbeSerialTypeLen() -** tdsqlite3VdbeSerialLen() -** tdsqlite3VdbeSerialPut() -** tdsqlite3VdbeSerialGet() +** sqlite3VdbeSerialType() +** sqlite3VdbeSerialTypeLen() +** sqlite3VdbeSerialLen() +** sqlite3VdbeSerialPut() +** sqlite3VdbeSerialGet() ** ** encapsulate the code that serializes values for storage in SQLite ** data and index records. Each serialized value consists of a @@ -84522,7 +84522,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){ ** this routine is now only used by the STAT3 logic and STAT3 support has ** ended. The code is kept here for historical reference only. */ -SQLITE_PRIVATE u32 tdsqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ +SQLITE_PRIVATE u32 sqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen){ int flags = pMem->flags; u32 n; @@ -84586,7 +84586,7 @@ SQLITE_PRIVATE u32 tdsqlite3VdbeSerialType(Mem *pMem, int file_format, u32 *pLen /* ** The sizes for serial types less than 128 */ -static const u8 tdsqlite3SmallTypeSizes[] = { +static const u8 sqlite3SmallTypeSizes[] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, /* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, @@ -84606,18 +84606,18 @@ static const u8 tdsqlite3SmallTypeSizes[] = { /* ** Return the length of the data corresponding to the supplied serial-type. */ -SQLITE_PRIVATE u32 tdsqlite3VdbeSerialTypeLen(u32 serial_type){ +SQLITE_PRIVATE u32 sqlite3VdbeSerialTypeLen(u32 serial_type){ if( serial_type>=128 ){ return (serial_type-12)/2; }else{ assert( serial_type<12 - || tdsqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 ); - return tdsqlite3SmallTypeSizes[serial_type]; + || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 ); + return sqlite3SmallTypeSizes[serial_type]; } } -SQLITE_PRIVATE u8 tdsqlite3VdbeOneByteSerialTypeLen(u8 serial_type){ +SQLITE_PRIVATE u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){ assert( serial_type<128 ); - return tdsqlite3SmallTypeSizes[serial_type]; + return sqlite3SmallTypeSizes[serial_type]; } /* @@ -84686,7 +84686,7 @@ static u64 floatSwap(u64 in){ ** of bytes in the zero-filled tail is included in the return value only ** if those bytes were zeroed in buf[]. */ -SQLITE_PRIVATE u32 tdsqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ +SQLITE_PRIVATE u32 sqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ u32 len; /* Integer and Real */ @@ -84700,7 +84700,7 @@ SQLITE_PRIVATE u32 tdsqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ }else{ v = pMem->u.i; } - len = i = tdsqlite3SmallTypeSizes[serial_type]; + len = i = sqlite3SmallTypeSizes[serial_type]; assert( i>0 ); do{ buf[--i] = (u8)(v&0xFF); @@ -84712,7 +84712,7 @@ SQLITE_PRIVATE u32 tdsqlite3VdbeSerialPut(u8 *buf, Mem *pMem, u32 serial_type){ /* String or blob */ if( serial_type>=12 ){ assert( pMem->n + ((pMem->flags & MEM_Zero)?pMem->u.nZero:0) - == (int)tdsqlite3VdbeSerialTypeLen(serial_type) ); + == (int)sqlite3VdbeSerialTypeLen(serial_type) ); len = pMem->n; if( len>0 ) memcpy(buf, pMem->z, len); return len; @@ -84776,7 +84776,7 @@ static u32 serialGet( } return 8; } -SQLITE_PRIVATE u32 tdsqlite3VdbeSerialGet( +SQLITE_PRIVATE u32 sqlite3VdbeSerialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ Mem *pMem /* Memory cell to write value into */ @@ -84869,25 +84869,25 @@ SQLITE_PRIVATE u32 tdsqlite3VdbeSerialGet( } /* ** This routine is used to allocate sufficient space for an UnpackedRecord -** structure large enough to be used with tdsqlite3VdbeRecordUnpack() if +** structure large enough to be used with sqlite3VdbeRecordUnpack() if ** the first argument is a pointer to KeyInfo structure pKeyInfo. ** -** The space is either allocated using tdsqlite3DbMallocRaw() or from within +** The space is either allocated using sqlite3DbMallocRaw() or from within ** the unaligned buffer passed via the second and third arguments (presumably ** stack space). If the former, then *ppFree is set to a pointer that should -** be eventually freed by the caller using tdsqlite3DbFree(). Or, if the +** be eventually freed by the caller using sqlite3DbFree(). Or, if the ** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL ** before returning. ** ** If an OOM error occurs, NULL is returned. */ -SQLITE_PRIVATE UnpackedRecord *tdsqlite3VdbeAllocUnpackedRecord( +SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( KeyInfo *pKeyInfo /* Description of the record */ ){ UnpackedRecord *p; /* Unpacked record to return */ int nByte; /* Number of bytes required for *p */ nByte = ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*(pKeyInfo->nKeyField+1); - p = (UnpackedRecord *)tdsqlite3DbMallocRaw(pKeyInfo->db, nByte); + p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( !p ) return 0; p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; assert( pKeyInfo->aSortFlags!=0 ); @@ -84901,7 +84901,7 @@ SQLITE_PRIVATE UnpackedRecord *tdsqlite3VdbeAllocUnpackedRecord( ** UnpackedRecord structure indicated by the fourth argument with the ** contents of the decoded record. */ -SQLITE_PRIVATE void tdsqlite3VdbeRecordUnpack( +SQLITE_PRIVATE void sqlite3VdbeRecordUnpack( KeyInfo *pKeyInfo, /* Information about the record format */ int nKey, /* Size of the binary record */ const void *pKey, /* The binary record */ @@ -84925,10 +84925,10 @@ SQLITE_PRIVATE void tdsqlite3VdbeRecordUnpack( idx += getVarint32(&aKey[idx], serial_type); pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; - /* pMem->flags = 0; // tdsqlite3VdbeSerialGet() will set this for us */ + /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ pMem->szMalloc = 0; pMem->z = 0; - d += tdsqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); + d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); pMem++; if( (++u)>=p->nField ) break; } @@ -84937,7 +84937,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeRecordUnpack( /* In a corrupt record entry, the last pMem might have been set up using ** uninitialized memory. Overwrite its value with NULL, to prevent ** warnings from MSAN. */ - tdsqlite3VdbeMemSetNull(pMem-1); + sqlite3VdbeMemSetNull(pMem-1); } assert( u<=pKeyInfo->nKeyField + 1 ); p->nField = u; @@ -84946,11 +84946,11 @@ SQLITE_PRIVATE void tdsqlite3VdbeRecordUnpack( #ifdef SQLITE_DEBUG /* ** This function compares two index or table record keys in the same way -** as the tdsqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), +** as the sqlite3VdbeRecordCompare() routine. Unlike VdbeRecordCompare(), ** this function deserializes and compares values using the -** tdsqlite3VdbeSerialGet() and tdsqlite3MemCompare() functions. It is used +** sqlite3VdbeSerialGet() and sqlite3MemCompare() functions. It is used ** in assert() statements to ensure that the optimized code in -** tdsqlite3VdbeRecordCompare() returns results with these two primitives. +** sqlite3VdbeRecordCompare() returns results with these two primitives. ** ** Return true if the result of comparison is equivalent to desiredResult. ** Return false if there is a disagreement. @@ -84973,7 +84973,7 @@ static int vdbeRecordCompareDebug( if( pKeyInfo->db==0 ) return 1; mem1.enc = pKeyInfo->enc; mem1.db = pKeyInfo->db; - /* mem1.flags = 0; // Will be initialized by tdsqlite3VdbeSerialGet() */ + /* mem1.flags = 0; // Will be initialized by sqlite3VdbeSerialGet() */ VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ /* Compilers may complain that mem1.u.i is potentially uninitialized. @@ -85002,21 +85002,21 @@ static int vdbeRecordCompareDebug( ** a buffer overread. The "d1+serial_type1+2" subexpression will ** always be greater than or equal to the amount of required key space. ** Use that approximation to avoid the more expensive call to - ** tdsqlite3VdbeSerialTypeLen() in the common case. + ** sqlite3VdbeSerialTypeLen() in the common case. */ if( d1+(u64)serial_type1+2>(u64)nKey1 - && d1+(u64)tdsqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 ){ break; } /* Extract the values to be compared. */ - d1 += tdsqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); + d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1); /* Do the comparison */ - rc = tdsqlite3MemCompare(&mem1, &pPKey2->aMem[i], + rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0); if( rc!=0 ){ assert( mem1.szMalloc==0 ); /* See comment below */ @@ -85035,7 +85035,7 @@ static int vdbeRecordCompareDebug( /* No memory allocation is ever used on mem1. Prove this using ** the following assert(). If the assert() fails, it indicates a - ** memory leak and a need to call tdsqlite3VdbeMemRelease(&mem1). + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ assert( mem1.szMalloc==0 ); @@ -85111,20 +85111,20 @@ static int vdbeCompareMemString( const void *v1, *v2; Mem c1; Mem c2; - tdsqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); - tdsqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); - tdsqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); - tdsqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); - v1 = tdsqlite3ValueText((tdsqlite3_value*)&c1, pColl->enc); - v2 = tdsqlite3ValueText((tdsqlite3_value*)&c2, pColl->enc); + sqlite3VdbeMemInit(&c1, pMem1->db, MEM_Null); + sqlite3VdbeMemInit(&c2, pMem1->db, MEM_Null); + sqlite3VdbeMemShallowCopy(&c1, pMem1, MEM_Ephem); + sqlite3VdbeMemShallowCopy(&c2, pMem2, MEM_Ephem); + v1 = sqlite3ValueText((sqlite3_value*)&c1, pColl->enc); + v2 = sqlite3ValueText((sqlite3_value*)&c2, pColl->enc); if( (v1==0 || v2==0) ){ if( prcErr ) *prcErr = SQLITE_NOMEM_BKPT; rc = 0; }else{ rc = pColl->xCmp(pColl->pUser, c1.n, v1, c2.n, v2); } - tdsqlite3VdbeMemRelease(&c1); - tdsqlite3VdbeMemRelease(&c2); + sqlite3VdbeMemRelease(&c1); + sqlite3VdbeMemRelease(&c2); return rc; } } @@ -85146,7 +85146,7 @@ static int isAllZero(const char *z, int n){ ** is less than, equal to, or greater than the second, respectively. ** If one blob is a prefix of the other, then the shorter is the lessor. */ -SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3BlobCompare(const Mem *pB1, const Mem *pB2){ int c; int n1 = pB1->n; int n2 = pB2->n; @@ -85154,7 +85154,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3BlobCompare(const Mem *pB1, const Me /* It is possible to have a Blob value that has some non-zero content ** followed by zero content. But that only comes up for Blobs formed ** by the OP_MakeRecord opcode, and such Blobs never get passed into - ** tdsqlite3MemCompare(). */ + ** sqlite3MemCompare(). */ assert( (pB1->flags & MEM_Zero)==0 || n1==0 ); assert( (pB2->flags & MEM_Zero)==0 || n2==0 ); @@ -85179,7 +85179,7 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3BlobCompare(const Mem *pB1, const Me ** number. Return negative, zero, or positive if the first (i64) is less than, ** equal to, or greater than the second (double). */ -static int tdsqlite3IntFloatCompare(i64 i, double r){ +static int sqlite3IntFloatCompare(i64 i, double r){ if( sizeof(LONGDOUBLE_TYPE)>8 ){ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; if( xflags; f2 = pMem2->flags; combined_flags = f1|f2; - assert( !tdsqlite3VdbeMemIsRowSet(pMem1) && !tdsqlite3VdbeMemIsRowSet(pMem2) ); + assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) ); /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. @@ -85247,7 +85247,7 @@ SQLITE_PRIVATE int tdsqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const testcase( f1 & MEM_Int ); testcase( f1 & MEM_IntReal ); if( (f2&MEM_Real)!=0 ){ - return tdsqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); + return sqlite3IntFloatCompare(pMem1->u.i, pMem2->u.r); }else if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ if( pMem1->u.i < pMem2->u.i ) return -1; if( pMem1->u.i > pMem2->u.i ) return +1; @@ -85260,7 +85260,7 @@ SQLITE_PRIVATE int tdsqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const if( (f2&(MEM_Int|MEM_IntReal))!=0 ){ testcase( f2 & MEM_Int ); testcase( f2 & MEM_IntReal ); - return -tdsqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); + return -sqlite3IntFloatCompare(pMem2->u.i, pMem1->u.r); }else{ return -1; } @@ -85297,7 +85297,7 @@ SQLITE_PRIVATE int tdsqlite3MemCompare(const Mem *pMem1, const Mem *pMem2, const } /* Both values must be blobs. Compare using memcmp(). */ - return tdsqlite3BlobCompare(pMem1, pMem2); + return sqlite3BlobCompare(pMem1, pMem2); } @@ -85349,7 +85349,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ ** greater than key2. The {nKey1, pKey1} key must be a blob ** created by the OP_MakeRecord opcode of the VDBE. The pPKey2 ** key must be a parsed key such as obtained from -** tdsqlite3VdbeParseRecord. +** sqlite3VdbeParseRecord. ** ** If argument bSkip is non-zero, it is assumed that the caller has already ** determined that the first fields of the keys are equal. @@ -85363,7 +85363,7 @@ static i64 vdbeRecordDecodeInt(u32 serial_type, const u8 *aKey){ ** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the ** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). */ -SQLITE_PRIVATE int tdsqlite3VdbeRecordCompareWithSkip( +SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip( int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2, /* Right key */ int bSkip /* If true, skip the first field */ @@ -85385,7 +85385,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeRecordCompareWithSkip( u32 s1; idx1 = 1 + getVarint32(&aKey1[1], s1); szHdr1 = aKey1[0]; - d1 = szHdr1 + tdsqlite3VdbeSerialTypeLen(s1); + d1 = szHdr1 + sqlite3VdbeSerialTypeLen(s1); i = 1; pRhs++; }else{ @@ -85418,8 +85418,8 @@ SQLITE_PRIVATE int tdsqlite3VdbeRecordCompareWithSkip( }else if( serial_type==0 ){ rc = -1; }else if( serial_type==7 ){ - tdsqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); - rc = -tdsqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); + sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); + rc = -sqlite3IntFloatCompare(pRhs->u.i, mem1.u.r); }else{ i64 lhs = vdbeRecordDecodeInt(serial_type, &aKey1[d1]); i64 rhs = pRhs->u.i; @@ -85443,7 +85443,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeRecordCompareWithSkip( }else if( serial_type==0 ){ rc = -1; }else{ - tdsqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); + sqlite3VdbeSerialGet(&aKey1[d1], serial_type, &mem1); if( serial_type==7 ){ if( mem1.u.ru.r ){ rc = -1; @@ -85451,7 +85451,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeRecordCompareWithSkip( rc = +1; } }else{ - rc = tdsqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); + rc = sqlite3IntFloatCompare(mem1.u.i, pRhs->u.r); } } } @@ -85541,13 +85541,13 @@ SQLITE_PRIVATE int tdsqlite3VdbeRecordCompareWithSkip( i++; if( i==pPKey2->nField ) break; pRhs++; - d1 += tdsqlite3VdbeSerialTypeLen(serial_type); - idx1 += tdsqlite3VarintLen(serial_type); + d1 += sqlite3VdbeSerialTypeLen(serial_type); + idx1 += sqlite3VarintLen(serial_type); }while( idx1<(unsigned)szHdr1 && d1<=(unsigned)nKey1 ); /* No memory allocation is ever used on mem1. Prove this using ** the following assert(). If the assert() fails, it indicates a - ** memory leak and a need to call tdsqlite3VdbeMemRelease(&mem1). */ + ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). */ assert( mem1.szMalloc==0 ); /* rc==0 here means that one or both of the keys ran out of fields and @@ -85560,16 +85560,16 @@ SQLITE_PRIVATE int tdsqlite3VdbeRecordCompareWithSkip( pPKey2->eqSeen = 1; return pPKey2->default_rc; } -SQLITE_PRIVATE int tdsqlite3VdbeRecordCompare( +SQLITE_PRIVATE int sqlite3VdbeRecordCompare( int nKey1, const void *pKey1, /* Left key */ UnpackedRecord *pPKey2 /* Right key */ ){ - return tdsqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 0); } /* -** This function is an optimized version of tdsqlite3VdbeRecordCompare() +** This function is an optimized version of sqlite3VdbeRecordCompare() ** that (a) the first field of pPKey2 is an integer, and (b) the ** size-of-header varint at the start of (pKey1/nKey1) fits in a single ** byte (i.e. is less than 128). @@ -85639,10 +85639,10 @@ static int vdbeRecordCompareInt( ** (as gcc is clever enough to combine the two like cases). Other ** compilers might be similar. */ case 0: case 7: - return tdsqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); default: - return tdsqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); + return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); } v = pPKey2->aMem[0].u.i; @@ -85653,7 +85653,7 @@ static int vdbeRecordCompareInt( }else if( pPKey2->nField>1 ){ /* The first fields of the two keys are equal. Compare the trailing ** fields. */ - res = tdsqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ /* The first fields of the two keys are equal and there are no trailing ** fields. Return pPKey2->default_rc in this case. */ @@ -85666,7 +85666,7 @@ static int vdbeRecordCompareInt( } /* -** This function is an optimized version of tdsqlite3VdbeRecordCompare() +** This function is an optimized version of sqlite3VdbeRecordCompare() ** that (a) the first field of pPKey2 is a string, that (b) the first field ** uses the collation sequence BINARY and (c) that the size-of-header varint ** at the start of (pKey1/nKey1) fits in a single byte. @@ -85707,7 +85707,7 @@ static int vdbeRecordCompareString( res = nStr - pPKey2->aMem[0].n; if( res==0 ){ if( pPKey2->nField>1 ){ - res = tdsqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); + res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ res = pPKey2->default_rc; pPKey2->eqSeen = 1; @@ -85728,11 +85728,11 @@ static int vdbeRecordCompareString( } /* -** Return a pointer to an tdsqlite3VdbeRecordCompare() compatible function +** Return a pointer to an sqlite3VdbeRecordCompare() compatible function ** suitable for comparing serialized records to the unpacked record passed ** as the only argument. */ -SQLITE_PRIVATE RecordCompare tdsqlite3VdbeFindCompare(UnpackedRecord *p){ +SQLITE_PRIVATE RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ /* varintRecordCompareInt() and varintRecordCompareString() both assume ** that the size-of-header varint that occurs at the start of each record ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt() @@ -85750,7 +85750,7 @@ SQLITE_PRIVATE RecordCompare tdsqlite3VdbeFindCompare(UnpackedRecord *p){ int flags = p->aMem[0].flags; if( p->pKeyInfo->aSortFlags[0] ){ if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ - return tdsqlite3VdbeRecordCompare; + return sqlite3VdbeRecordCompare; } p->r1 = 1; p->r2 = -1; @@ -85772,7 +85772,7 @@ SQLITE_PRIVATE RecordCompare tdsqlite3VdbeFindCompare(UnpackedRecord *p){ } } - return tdsqlite3VdbeRecordCompare; + return sqlite3VdbeRecordCompare; } /* @@ -85783,7 +85783,7 @@ SQLITE_PRIVATE RecordCompare tdsqlite3VdbeFindCompare(UnpackedRecord *p){ ** pCur might be pointing to text obtained from a corrupt database file. ** So the content cannot be trusted. Do appropriate checks on the content. */ -SQLITE_PRIVATE int tdsqlite3VdbeIdxRowid(tdsqlite3 *db, BtCursor *pCur, i64 *rowid){ +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ i64 nCellKey = 0; int rc; u32 szHdr; /* Size of the header */ @@ -85793,16 +85793,16 @@ SQLITE_PRIVATE int tdsqlite3VdbeIdxRowid(tdsqlite3 *db, BtCursor *pCur, i64 *row /* Get the size of the index entry. Only indices entries of less ** than 2GiB are support - anything large must be database corruption. - ** Any corruption is detected in tdsqlite3BtreeParseCellPtr(), though, so + ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so ** this code can safely assume that nCellKey is 32-bits */ - assert( tdsqlite3BtreeCursorIsValid(pCur) ); - nCellKey = tdsqlite3BtreePayloadSize(pCur); + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); /* Read in the complete content of the index entry */ - tdsqlite3VdbeMemInit(&m, db, 0); - rc = tdsqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m); + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m); if( rc ){ return rc; } @@ -85831,23 +85831,23 @@ SQLITE_PRIVATE int tdsqlite3VdbeIdxRowid(tdsqlite3 *db, BtCursor *pCur, i64 *row if( unlikely(typeRowid<1 || typeRowid>9 || typeRowid==7) ){ goto idx_rowid_corruption; } - lenRowid = tdsqlite3SmallTypeSizes[typeRowid]; + lenRowid = sqlite3SmallTypeSizes[typeRowid]; testcase( (u32)m.n==szHdr+lenRowid ); if( unlikely((u32)m.neCurType==CURTYPE_BTREE ); pCur = pC->uc.pCursor; - assert( tdsqlite3BtreeCursorIsValid(pCur) ); - nCellKey = tdsqlite3BtreePayloadSize(pCur); + assert( sqlite3BtreeCursorIsValid(pCur) ); + nCellKey = sqlite3BtreePayloadSize(pCur); /* nCellKey will always be between 0 and 0xffffffff because of the way - ** that btreeParseCellPtr() and tdsqlite3GetVarint32() are implemented */ + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ if( nCellKey<=0 || nCellKey>0x7fffffff ){ *res = 0; return SQLITE_CORRUPT_BKPT; } - tdsqlite3VdbeMemInit(&m, db, 0); - rc = tdsqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m); + sqlite3VdbeMemInit(&m, db, 0); + rc = sqlite3VdbeMemFromBtree(pCur, 0, (u32)nCellKey, &m); if( rc ){ return rc; } - *res = tdsqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); - tdsqlite3VdbeMemRelease(&m); + *res = sqlite3VdbeRecordCompareWithSkip(m.n, m.z, pUnpacked, 0); + sqlite3VdbeMemRelease(&m); return SQLITE_OK; } /* ** This routine sets the value to be returned by subsequent calls to -** tdsqlite3_changes() on the database handle 'db'. +** sqlite3_changes() on the database handle 'db'. */ -SQLITE_PRIVATE void tdsqlite3VdbeSetChanges(tdsqlite3 *db, int nChange){ - assert( tdsqlite3_mutex_held(db->mutex) ); +SQLITE_PRIVATE void sqlite3VdbeSetChanges(sqlite3 *db, int nChange){ + assert( sqlite3_mutex_held(db->mutex) ); db->nChange = nChange; db->nTotalChange += nChange; } @@ -85907,7 +85907,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeSetChanges(tdsqlite3 *db, int nChange){ ** Set a flag in the vdbe to update the change counter when it is finalised ** or reset. */ -SQLITE_PRIVATE void tdsqlite3VdbeCountChanges(Vdbe *v){ +SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe *v){ v->changeCntOn = 1; } @@ -85929,7 +85929,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeCountChanges(Vdbe *v){ ** prepared statements. The flag is set to 1 for an immediate expiration ** and set to 2 for an advisory expiration. */ -SQLITE_PRIVATE void tdsqlite3ExpirePreparedStatements(tdsqlite3 *db, int iCode){ +SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3 *db, int iCode){ Vdbe *p; for(p = db->pVdbe; p; p=p->pNext){ p->expired = iCode+1; @@ -85939,35 +85939,35 @@ SQLITE_PRIVATE void tdsqlite3ExpirePreparedStatements(tdsqlite3 *db, int iCode){ /* ** Return the database associated with the Vdbe. */ -SQLITE_PRIVATE tdsqlite3 *tdsqlite3VdbeDb(Vdbe *v){ +SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){ return v->db; } /* ** Return the SQLITE_PREPARE flags for a Vdbe. */ -SQLITE_PRIVATE u8 tdsqlite3VdbePrepareFlags(Vdbe *v){ +SQLITE_PRIVATE u8 sqlite3VdbePrepareFlags(Vdbe *v){ return v->prepFlags; } /* -** Return a pointer to an tdsqlite3_value structure containing the value bound +** Return a pointer to an sqlite3_value structure containing the value bound ** parameter iVar of VM v. Except, if the value is an SQL NULL, return ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_* ** constants) to the value before returning it. ** -** The returned value must be freed by the caller using tdsqlite3ValueFree(). +** The returned value must be freed by the caller using sqlite3ValueFree(). */ -SQLITE_PRIVATE tdsqlite3_value *tdsqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ +SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 aff){ assert( iVar>0 ); if( v ){ Mem *pMem = &v->aVar[iVar-1]; assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); if( 0==(pMem->flags & MEM_Null) ){ - tdsqlite3_value *pRet = tdsqlite3ValueNew(v->db); + sqlite3_value *pRet = sqlite3ValueNew(v->db); if( pRet ){ - tdsqlite3VdbeMemCopy((Mem *)pRet, pMem); - tdsqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8); + sqlite3VdbeMemCopy((Mem *)pRet, pMem); + sqlite3ValueApplyAffinity(pRet, aff, SQLITE_UTF8); } return pRet; } @@ -85977,10 +85977,10 @@ SQLITE_PRIVATE tdsqlite3_value *tdsqlite3VdbeGetBoundValue(Vdbe *v, int iVar, u8 /* ** Configure SQL variable iVar so that binding a new value to it signals -** to tdsqlite3_reoptimize() that re-preparing the statement may result +** to sqlite3_reoptimize() that re-preparing the statement may result ** in a better query plan. */ -SQLITE_PRIVATE void tdsqlite3VdbeSetVarmask(Vdbe *v, int iVar){ +SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe *v, int iVar){ assert( iVar>0 ); assert( (v->db->flags & SQLITE_EnableQPSG)==0 ); if( iVar>=32 ){ @@ -85999,7 +85999,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeSetVarmask(Vdbe *v, int iVar){ ** This routine is invoked by date/time functions that use non-deterministic ** features such as 'now'. */ -SQLITE_PRIVATE int tdsqlite3NotPureFunc(tdsqlite3_context *pCtx){ +SQLITE_PRIVATE int sqlite3NotPureFunc(sqlite3_context *pCtx){ const VdbeOp *pOp; #ifdef SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 1; @@ -86015,10 +86015,10 @@ SQLITE_PRIVATE int tdsqlite3NotPureFunc(tdsqlite3_context *pCtx){ }else{ zContext = "an index"; } - zMsg = tdsqlite3_mprintf("non-deterministic use of %s() in %s", + zMsg = sqlite3_mprintf("non-deterministic use of %s() in %s", pCtx->pFunc->zName, zContext); - tdsqlite3_result_error(pCtx, zMsg, -1); - tdsqlite3_free(zMsg); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); return 0; } return 1; @@ -86026,16 +86026,16 @@ SQLITE_PRIVATE int tdsqlite3NotPureFunc(tdsqlite3_context *pCtx){ #ifndef SQLITE_OMIT_VIRTUALTABLE /* -** Transfer error message text from an tdsqlite3_vtab.zErrMsg (text stored -** in memory obtained from tdsqlite3_malloc) into a Vdbe.zErrMsg (text stored -** in memory obtained from tdsqlite3DbMalloc). +** Transfer error message text from an sqlite3_vtab.zErrMsg (text stored +** in memory obtained from sqlite3_malloc) into a Vdbe.zErrMsg (text stored +** in memory obtained from sqlite3DbMalloc). */ -SQLITE_PRIVATE void tdsqlite3VtabImportErrmsg(Vdbe *p, tdsqlite3_vtab *pVtab){ +SQLITE_PRIVATE void sqlite3VtabImportErrmsg(Vdbe *p, sqlite3_vtab *pVtab){ if( pVtab->zErrMsg ){ - tdsqlite3 *db = p->db; - tdsqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = tdsqlite3DbStrDup(db, pVtab->zErrMsg); - tdsqlite3_free(pVtab->zErrMsg); + sqlite3 *db = p->db; + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = 0; } } @@ -86046,19 +86046,19 @@ SQLITE_PRIVATE void tdsqlite3VtabImportErrmsg(Vdbe *p, tdsqlite3_vtab *pVtab){ /* ** If the second argument is not NULL, release any allocations associated ** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord -** structure itself, using tdsqlite3DbFree(). +** structure itself, using sqlite3DbFree(). ** ** This function is used to free UnpackedRecord structures allocated by ** the vdbeUnpackRecord() function found in vdbeapi.c. */ -static void vdbeFreeUnpacked(tdsqlite3 *db, int nField, UnpackedRecord *p){ +static void vdbeFreeUnpacked(sqlite3 *db, int nField, UnpackedRecord *p){ if( p ){ int i; for(i=0; iaMem[i]; - if( pMem->zMalloc ) tdsqlite3VdbeMemRelease(pMem); + if( pMem->zMalloc ) sqlite3VdbeMemRelease(pMem); } - tdsqlite3DbFreeNN(db, p); + sqlite3DbFreeNN(db, p); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -86067,10 +86067,10 @@ static void vdbeFreeUnpacked(tdsqlite3 *db, int nField, UnpackedRecord *p){ /* ** Invoke the pre-update hook. If this is an UPDATE or DELETE pre-update call, ** then cursor passed as the second argument should point to the row about -** to be update or deleted. If the application calls tdsqlite3_preupdate_old(), +** to be update or deleted. If the application calls sqlite3_preupdate_old(), ** the required value will be read from the row the cursor points to. */ -SQLITE_PRIVATE void tdsqlite3VdbePreUpdateHook( +SQLITE_PRIVATE void sqlite3VdbePreUpdateHook( Vdbe *v, /* Vdbe pre-update hook is invoked by */ VdbeCursor *pCsr, /* Cursor to grab old.* values from */ int op, /* SQLITE_INSERT, UPDATE or DELETE */ @@ -86079,7 +86079,7 @@ SQLITE_PRIVATE void tdsqlite3VdbePreUpdateHook( i64 iKey1, /* Initial key value */ int iReg /* Register for new.* record */ ){ - tdsqlite3 *db = v->db; + sqlite3 *db = v->db; i64 iKey2; PreUpdate preupdate; const char *zTbl = pTab->zName; @@ -86089,7 +86089,7 @@ SQLITE_PRIVATE void tdsqlite3VdbePreUpdateHook( memset(&preupdate, 0, sizeof(PreUpdate)); if( HasRowid(pTab)==0 ){ iKey1 = iKey2 = 0; - preupdate.pPk = tdsqlite3PrimaryKeyIndex(pTab); + preupdate.pPk = sqlite3PrimaryKeyIndex(pTab); }else{ if( op==SQLITE_UPDATE ){ iKey2 = v->aMem[iReg].u.i; @@ -86117,15 +86117,15 @@ SQLITE_PRIVATE void tdsqlite3VdbePreUpdateHook( db->pPreUpdate = &preupdate; db->xPreUpdateCallback(db->pPreUpdateArg, db, op, zDb, zTbl, iKey1, iKey2); db->pPreUpdate = 0; - tdsqlite3DbFree(db, preupdate.aRecord); + sqlite3DbFree(db, preupdate.aRecord); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pUnpacked); vdbeFreeUnpacked(db, preupdate.keyinfo.nKeyField+1, preupdate.pNewUnpacked); if( preupdate.aNew ){ int i; for(i=0; inField; i++){ - tdsqlite3VdbeMemRelease(&preupdate.aNew[i]); + sqlite3VdbeMemRelease(&preupdate.aNew[i]); } - tdsqlite3DbFreeNN(db, preupdate.aNew); + sqlite3DbFreeNN(db, preupdate.aNew); } } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -86155,11 +86155,11 @@ SQLITE_PRIVATE void tdsqlite3VdbePreUpdateHook( ** Return TRUE (non-zero) of the statement supplied as an argument needs ** to be recompiled. A statement needs to be recompiled whenever the ** execution environment changes in a way that would alter the program -** that tdsqlite3_prepare() generates. For example, if new functions or +** that sqlite3_prepare() generates. For example, if new functions or ** collating sequences are registered or if an authorizer function is ** added or changed. */ -SQLITE_API int tdsqlite3_expired(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_expired(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; return p==0 || p->expired; } @@ -86172,7 +86172,7 @@ SQLITE_API int tdsqlite3_expired(tdsqlite3_stmt *pStmt){ */ static int vdbeSafety(Vdbe *p){ if( p->db==0 ){ - tdsqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement"); + sqlite3_log(SQLITE_MISUSE, "API called with finalized prepared statement"); return 1; }else{ return 0; @@ -86180,7 +86180,7 @@ static int vdbeSafety(Vdbe *p){ } static int vdbeSafetyNotNull(Vdbe *p){ if( p==0 ){ - tdsqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); + sqlite3_log(SQLITE_MISUSE, "API called with NULL prepared statement"); return 1; }else{ return vdbeSafety(p); @@ -86192,14 +86192,14 @@ static int vdbeSafetyNotNull(Vdbe *p){ ** Invoke the profile callback. This routine is only called if we already ** know that the profile callback is defined and needs to be invoked. */ -static SQLITE_NOINLINE void invokeProfileCallback(tdsqlite3 *db, Vdbe *p){ - tdsqlite3_int64 iNow; - tdsqlite3_int64 iElapse; +static SQLITE_NOINLINE void invokeProfileCallback(sqlite3 *db, Vdbe *p){ + sqlite3_int64 iNow; + sqlite3_int64 iElapse; assert( p->startTime>0 ); assert( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 ); assert( db->init.busy==0 ); assert( p->zSql!=0 ); - tdsqlite3OsCurrentTimeInt64(db->pVfs, &iNow); + sqlite3OsCurrentTimeInt64(db->pVfs, &iNow); iElapse = (iNow - p->startTime)*1000000; #ifndef SQLITE_OMIT_DEPRECATED if( db->xProfile ){ @@ -86223,28 +86223,28 @@ static SQLITE_NOINLINE void invokeProfileCallback(tdsqlite3 *db, Vdbe *p){ /* ** The following routine destroys a virtual machine that is created by -** the tdsqlite3_compile() routine. The integer returned is an SQLITE_ +** the sqlite3_compile() routine. The integer returned is an SQLITE_ ** success/failure code that describes the result of executing the virtual ** machine. ** ** This routine sets the error code and string returned by -** tdsqlite3_errcode(), tdsqlite3_errmsg() and tdsqlite3_errmsg16(). +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ -SQLITE_API int tdsqlite3_finalize(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ - /* IMPLEMENTATION-OF: R-57228-12904 Invoking tdsqlite3_finalize() on a NULL + /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL ** pointer is a harmless no-op. */ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; - tdsqlite3 *db = v->db; + sqlite3 *db = v->db; if( vdbeSafety(v) ) return SQLITE_MISUSE_BKPT; - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); checkProfileCallback(db, v); - rc = tdsqlite3VdbeFinalize(v); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3LeaveMutexAndCloseZombie(db); + rc = sqlite3VdbeFinalize(v); + rc = sqlite3ApiExit(db, rc); + sqlite3LeaveMutexAndCloseZombie(db); } return rc; } @@ -86255,22 +86255,22 @@ SQLITE_API int tdsqlite3_finalize(tdsqlite3_stmt *pStmt){ ** the prior execution is returned. ** ** This routine sets the error code and string returned by -** tdsqlite3_errcode(), tdsqlite3_errmsg() and tdsqlite3_errmsg16(). +** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). */ -SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ int rc; if( pStmt==0 ){ rc = SQLITE_OK; }else{ Vdbe *v = (Vdbe*)pStmt; - tdsqlite3 *db = v->db; - tdsqlite3_mutex_enter(db->mutex); + sqlite3 *db = v->db; + sqlite3_mutex_enter(db->mutex); checkProfileCallback(db, v); - rc = tdsqlite3VdbeReset(v); - tdsqlite3VdbeRewind(v); + rc = sqlite3VdbeReset(v); + sqlite3VdbeRewind(v); assert( (rc & (db->errMask))==rc ); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); } return rc; } @@ -86278,32 +86278,32 @@ SQLITE_API int tdsqlite3_reset(tdsqlite3_stmt *pStmt){ /* ** Set all the parameters in the compiled SQL statement to NULL. */ -SQLITE_API int tdsqlite3_clear_bindings(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt *pStmt){ int i; int rc = SQLITE_OK; Vdbe *p = (Vdbe*)pStmt; #if SQLITE_THREADSAFE - tdsqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; + sqlite3_mutex *mutex = ((Vdbe*)pStmt)->db->mutex; #endif - tdsqlite3_mutex_enter(mutex); + sqlite3_mutex_enter(mutex); for(i=0; inVar; i++){ - tdsqlite3VdbeMemRelease(&p->aVar[i]); + sqlite3VdbeMemRelease(&p->aVar[i]); p->aVar[i].flags = MEM_Null; } assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 ); if( p->expmask ){ p->expired = 1; } - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); return rc; } -/**************************** tdsqlite3_value_ ******************************* -** The following routines extract information from a Mem or tdsqlite3_value +/**************************** sqlite3_value_ ******************************* +** The following routines extract information from a Mem or sqlite3_value ** structure. */ -SQLITE_API const void *tdsqlite3_value_blob(tdsqlite3_value *pVal){ +SQLITE_API const void *sqlite3_value_blob(sqlite3_value *pVal){ Mem *p = (Mem*)pVal; if( p->flags & (MEM_Blob|MEM_Str) ){ if( ExpandBlob(p)!=SQLITE_OK ){ @@ -86313,29 +86313,29 @@ SQLITE_API const void *tdsqlite3_value_blob(tdsqlite3_value *pVal){ p->flags |= MEM_Blob; return p->n ? p->z : 0; }else{ - return tdsqlite3_value_text(pVal); + return sqlite3_value_text(pVal); } } -SQLITE_API int tdsqlite3_value_bytes(tdsqlite3_value *pVal){ - return tdsqlite3ValueBytes(pVal, SQLITE_UTF8); +SQLITE_API int sqlite3_value_bytes(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF8); } -SQLITE_API int tdsqlite3_value_bytes16(tdsqlite3_value *pVal){ - return tdsqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value *pVal){ + return sqlite3ValueBytes(pVal, SQLITE_UTF16NATIVE); } -SQLITE_API double tdsqlite3_value_double(tdsqlite3_value *pVal){ - return tdsqlite3VdbeRealValue((Mem*)pVal); +SQLITE_API double sqlite3_value_double(sqlite3_value *pVal){ + return sqlite3VdbeRealValue((Mem*)pVal); } -SQLITE_API int tdsqlite3_value_int(tdsqlite3_value *pVal){ - return (int)tdsqlite3VdbeIntValue((Mem*)pVal); +SQLITE_API int sqlite3_value_int(sqlite3_value *pVal){ + return (int)sqlite3VdbeIntValue((Mem*)pVal); } -SQLITE_API sqlite_int64 tdsqlite3_value_int64(tdsqlite3_value *pVal){ - return tdsqlite3VdbeIntValue((Mem*)pVal); +SQLITE_API sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){ + return sqlite3VdbeIntValue((Mem*)pVal); } -SQLITE_API unsigned int tdsqlite3_value_subtype(tdsqlite3_value *pVal){ +SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value *pVal){ Mem *pMem = (Mem*)pVal; return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0); } -SQLITE_API void *tdsqlite3_value_pointer(tdsqlite3_value *pVal, const char *zPType){ +SQLITE_API void *sqlite3_value_pointer(sqlite3_value *pVal, const char *zPType){ Mem *p = (Mem*)pVal; if( (p->flags&(MEM_TypeMask|MEM_Term|MEM_Subtype)) == (MEM_Null|MEM_Term|MEM_Subtype) @@ -86348,25 +86348,25 @@ SQLITE_API void *tdsqlite3_value_pointer(tdsqlite3_value *pVal, const char *zPTy return 0; } } -SQLITE_API const unsigned char *tdsqlite3_value_text(tdsqlite3_value *pVal){ - return (const unsigned char *)tdsqlite3ValueText(pVal, SQLITE_UTF8); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value *pVal){ + return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *tdsqlite3_value_text16(tdsqlite3_value* pVal){ - return tdsqlite3ValueText(pVal, SQLITE_UTF16NATIVE); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value* pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); } -SQLITE_API const void *tdsqlite3_value_text16be(tdsqlite3_value *pVal){ - return tdsqlite3ValueText(pVal, SQLITE_UTF16BE); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16BE); } -SQLITE_API const void *tdsqlite3_value_text16le(tdsqlite3_value *pVal){ - return tdsqlite3ValueText(pVal, SQLITE_UTF16LE); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value *pVal){ + return sqlite3ValueText(pVal, SQLITE_UTF16LE); } #endif /* SQLITE_OMIT_UTF16 */ /* EVIDENCE-OF: R-12793-43283 Every value in SQLite has one of five ** fundamental datatypes: 64-bit signed integer 64-bit IEEE floating ** point number string BLOB NULL */ -SQLITE_API int tdsqlite3_value_type(tdsqlite3_value* pVal){ +SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ static const u8 aType[] = { SQLITE_BLOB, /* 0x00 (not possible) */ SQLITE_NULL, /* 0x01 NULL */ @@ -86452,21 +86452,21 @@ SQLITE_API int tdsqlite3_value_type(tdsqlite3_value* pVal){ } /* Return true if a parameter to xUpdate represents an unchanged column */ -SQLITE_API int tdsqlite3_value_nochange(tdsqlite3_value *pVal){ +SQLITE_API int sqlite3_value_nochange(sqlite3_value *pVal){ return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero); } -/* Return true if a parameter value originated from an tdsqlite3_bind() */ -SQLITE_API int tdsqlite3_value_frombind(tdsqlite3_value *pVal){ +/* Return true if a parameter value originated from an sqlite3_bind() */ +SQLITE_API int sqlite3_value_frombind(sqlite3_value *pVal){ return (pVal->flags&MEM_FromBind)!=0; } -/* Make a copy of an tdsqlite3_value object +/* Make a copy of an sqlite3_value object */ -SQLITE_API tdsqlite3_value *tdsqlite3_value_dup(const tdsqlite3_value *pOrig){ - tdsqlite3_value *pNew; +SQLITE_API sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){ + sqlite3_value *pNew; if( pOrig==0 ) return 0; - pNew = tdsqlite3_malloc( sizeof(*pNew) ); + pNew = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return 0; memset(pNew, 0, sizeof(*pNew)); memcpy(pNew, pOrig, MEMCELLSIZE); @@ -86475,27 +86475,27 @@ SQLITE_API tdsqlite3_value *tdsqlite3_value_dup(const tdsqlite3_value *pOrig){ if( pNew->flags&(MEM_Str|MEM_Blob) ){ pNew->flags &= ~(MEM_Static|MEM_Dyn); pNew->flags |= MEM_Ephem; - if( tdsqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){ - tdsqlite3ValueFree(pNew); + if( sqlite3VdbeMemMakeWriteable(pNew)!=SQLITE_OK ){ + sqlite3ValueFree(pNew); pNew = 0; } } return pNew; } -/* Destroy an tdsqlite3_value object previously obtained from -** tdsqlite3_value_dup(). +/* Destroy an sqlite3_value object previously obtained from +** sqlite3_value_dup(). */ -SQLITE_API void tdsqlite3_value_free(tdsqlite3_value *pOld){ - tdsqlite3ValueFree(pOld); +SQLITE_API void sqlite3_value_free(sqlite3_value *pOld){ + sqlite3ValueFree(pOld); } -/**************************** tdsqlite3_result_ ******************************* +/**************************** sqlite3_result_ ******************************* ** The following routines are used by user-defined functions to specify ** the function result. ** -** The setStrOrError() function calls tdsqlite3VdbeMemSetStr() to store the +** The setStrOrError() function calls sqlite3VdbeMemSetStr() to store the ** result as a string or blob but if the string or blob is too large, it ** then sets the error code to SQLITE_TOOBIG ** @@ -86503,20 +86503,20 @@ SQLITE_API void tdsqlite3_value_free(tdsqlite3_value *pOld){ ** on value P is not going to be used and need to be destroyed. */ static void setResultStrOrError( - tdsqlite3_context *pCtx, /* Function context */ + sqlite3_context *pCtx, /* Function context */ const char *z, /* String pointer */ int n, /* Bytes in string, or negative */ u8 enc, /* Encoding of z. 0 for BLOBs */ void (*xDel)(void*) /* Destructor function */ ){ - if( tdsqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){ - tdsqlite3_result_error_toobig(pCtx); + if( sqlite3VdbeMemSetStr(pCtx->pOut, z, n, enc, xDel)==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(pCtx); } } static int invokeValueDestructor( const void *p, /* Value to destroy */ void (*xDel)(void*), /* The destructor */ - tdsqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ ){ assert( xDel!=SQLITE_DYNAMIC ); if( xDel==0 ){ @@ -86526,26 +86526,26 @@ static int invokeValueDestructor( }else{ xDel((void*)p); } - if( pCtx ) tdsqlite3_result_error_toobig(pCtx); + if( pCtx ) sqlite3_result_error_toobig(pCtx); return SQLITE_TOOBIG; } -SQLITE_API void tdsqlite3_result_blob( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_result_blob( + sqlite3_context *pCtx, const void *z, int n, void (*xDel)(void *) ){ assert( n>=0 ); - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, 0, xDel); } -SQLITE_API void tdsqlite3_result_blob64( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_result_blob64( + sqlite3_context *pCtx, const void *z, - tdsqlite3_uint64 n, + sqlite3_uint64 n, void (*xDel)(void *) ){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); @@ -86553,69 +86553,69 @@ SQLITE_API void tdsqlite3_result_blob64( setResultStrOrError(pCtx, z, (int)n, 0, xDel); } } -SQLITE_API void tdsqlite3_result_double(tdsqlite3_context *pCtx, double rVal){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); - tdsqlite3VdbeMemSetDouble(pCtx->pOut, rVal); +SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); } -SQLITE_API void tdsqlite3_result_error(tdsqlite3_context *pCtx, const char *z, int n){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); +SQLITE_API void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; - tdsqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API void tdsqlite3_result_error16(tdsqlite3_context *pCtx, const void *z, int n){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); +SQLITE_API void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; - tdsqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); + sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif -SQLITE_API void tdsqlite3_result_int(tdsqlite3_context *pCtx, int iVal){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); - tdsqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); +SQLITE_API void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); } -SQLITE_API void tdsqlite3_result_int64(tdsqlite3_context *pCtx, i64 iVal){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); - tdsqlite3VdbeMemSetInt64(pCtx->pOut, iVal); +SQLITE_API void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } -SQLITE_API void tdsqlite3_result_null(tdsqlite3_context *pCtx){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); - tdsqlite3VdbeMemSetNull(pCtx->pOut); +SQLITE_API void sqlite3_result_null(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); } -SQLITE_API void tdsqlite3_result_pointer( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_result_pointer( + sqlite3_context *pCtx, void *pPtr, const char *zPType, void (*xDestructor)(void*) ){ Mem *pOut = pCtx->pOut; - assert( tdsqlite3_mutex_held(pOut->db->mutex) ); - tdsqlite3VdbeMemRelease(pOut); + assert( sqlite3_mutex_held(pOut->db->mutex) ); + sqlite3VdbeMemRelease(pOut); pOut->flags = MEM_Null; - tdsqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); + sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); } -SQLITE_API void tdsqlite3_result_subtype(tdsqlite3_context *pCtx, unsigned int eSubtype){ +SQLITE_API void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ Mem *pOut = pCtx->pOut; - assert( tdsqlite3_mutex_held(pOut->db->mutex) ); + assert( sqlite3_mutex_held(pOut->db->mutex) ); pOut->eSubtype = eSubtype & 0xff; pOut->flags |= MEM_Subtype; } -SQLITE_API void tdsqlite3_result_text( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_result_text( + sqlite3_context *pCtx, const char *z, int n, void (*xDel)(void *) ){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } -SQLITE_API void tdsqlite3_result_text64( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_result_text64( + sqlite3_context *pCtx, const char *z, - tdsqlite3_uint64 n, + sqlite3_uint64 n, void (*xDel)(void *), unsigned char enc ){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); if( enc==SQLITE_UTF16 ) enc = SQLITE_UTF16NATIVE; if( n>0x7fffffff ){ @@ -86625,76 +86625,76 @@ SQLITE_API void tdsqlite3_result_text64( } } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API void tdsqlite3_result_text16( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_result_text16( + sqlite3_context *pCtx, const void *z, int n, void (*xDel)(void *) ){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); } -SQLITE_API void tdsqlite3_result_text16be( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_result_text16be( + sqlite3_context *pCtx, const void *z, int n, void (*xDel)(void *) ){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); } -SQLITE_API void tdsqlite3_result_text16le( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_result_text16le( + sqlite3_context *pCtx, const void *z, int n, void (*xDel)(void *) ){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); } #endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API void tdsqlite3_result_value(tdsqlite3_context *pCtx, tdsqlite3_value *pValue){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); - tdsqlite3VdbeMemCopy(pCtx->pOut, pValue); +SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemCopy(pCtx->pOut, pValue); } -SQLITE_API void tdsqlite3_result_zeroblob(tdsqlite3_context *pCtx, int n){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); - tdsqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context *pCtx, int n){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetZeroBlob(pCtx->pOut, n); } -SQLITE_API int tdsqlite3_result_zeroblob64(tdsqlite3_context *pCtx, u64 n){ +SQLITE_API int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ Mem *pOut = pCtx->pOut; - assert( tdsqlite3_mutex_held(pOut->db->mutex) ); + assert( sqlite3_mutex_held(pOut->db->mutex) ); if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ return SQLITE_TOOBIG; } - tdsqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); + sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n); return SQLITE_OK; } -SQLITE_API void tdsqlite3_result_error_code(tdsqlite3_context *pCtx, int errCode){ +SQLITE_API void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ pCtx->isError = errCode ? errCode : -1; #ifdef SQLITE_DEBUG if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; #endif if( pCtx->pOut->flags & MEM_Null ){ - tdsqlite3VdbeMemSetStr(pCtx->pOut, tdsqlite3ErrStr(errCode), -1, + sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, SQLITE_UTF8, SQLITE_STATIC); } } /* Force an SQLITE_TOOBIG error. */ -SQLITE_API void tdsqlite3_result_error_toobig(tdsqlite3_context *pCtx){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_TOOBIG; - tdsqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, + sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, SQLITE_UTF8, SQLITE_STATIC); } /* An SQLITE_NOMEM error. */ -SQLITE_API void tdsqlite3_result_error_nomem(tdsqlite3_context *pCtx){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); - tdsqlite3VdbeMemSetNull(pCtx->pOut); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); + sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM_BKPT; - tdsqlite3OomFault(pCtx->pOut->db); + sqlite3OomFault(pCtx->pOut->db); } #ifndef SQLITE_UNTESTABLE @@ -86702,8 +86702,8 @@ SQLITE_API void tdsqlite3_result_error_nomem(tdsqlite3_context *pCtx){ ** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL ** test-control. */ -SQLITE_PRIVATE void tdsqlite3ResultIntReal(tdsqlite3_context *pCtx){ - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); +SQLITE_PRIVATE void sqlite3ResultIntReal(sqlite3_context *pCtx){ + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); if( pCtx->pOut->flags & MEM_Int ){ pCtx->pOut->flags &= ~MEM_Int; pCtx->pOut->flags |= MEM_IntReal; @@ -86714,9 +86714,9 @@ SQLITE_PRIVATE void tdsqlite3ResultIntReal(tdsqlite3_context *pCtx){ /* ** This function is called after a transaction has been committed. It -** invokes callbacks registered with tdsqlite3_wal_hook() as required. +** invokes callbacks registered with sqlite3_wal_hook() as required. */ -static int doWalCallbacks(tdsqlite3 *db){ +static int doWalCallbacks(sqlite3 *db){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_WAL int i; @@ -86724,9 +86724,9 @@ static int doWalCallbacks(tdsqlite3 *db){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ int nEntry; - tdsqlite3BtreeEnter(pBt); - nEntry = tdsqlite3PagerWalCallback(tdsqlite3BtreePager(pBt)); - tdsqlite3BtreeLeave(pBt); + sqlite3BtreeEnter(pBt); + nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); + sqlite3BtreeLeave(pBt); if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){ rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry); } @@ -86744,17 +86744,17 @@ static int doWalCallbacks(tdsqlite3 *db){ ** This routine implements the bulk of the logic behind the sqlite_step() ** API. The only thing omitted is the automatic recompile if a ** schema change has occurred. That detail is handled by the -** outer tdsqlite3_step() wrapper procedure. +** outer sqlite3_step() wrapper procedure. */ -static int tdsqlite3Step(Vdbe *p){ - tdsqlite3 *db; +static int sqlite3Step(Vdbe *p){ + sqlite3 *db; int rc; assert(p); if( p->magic!=VDBE_MAGIC_RUN ){ - /* We used to require that tdsqlite3_reset() be called before retrying - ** tdsqlite3_step() after any error or after SQLITE_DONE. But beginning - ** with version 3.7.0, we changed this so that tdsqlite3_reset() would + /* We used to require that sqlite3_reset() be called before retrying + ** sqlite3_step() after any error or after SQLITE_DONE. But beginning + ** with version 3.7.0, we changed this so that sqlite3_reset() would ** be called automatically instead of throwing the SQLITE_MISUSE error. ** This "automatic-reset" change is not technically an incompatibility, ** since any application that receives an SQLITE_MISUSE is broken by @@ -86765,17 +86765,17 @@ static int tdsqlite3Step(Vdbe *p){ ** returns, and those were broken by the automatic-reset change. As a ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the ** legacy behavior of returning SQLITE_MISUSE for cases where the - ** previous tdsqlite3_step() returned something other than a SQLITE_LOCKED + ** previous sqlite3_step() returned something other than a SQLITE_LOCKED ** or SQLITE_BUSY error. */ #ifdef SQLITE_OMIT_AUTORESET if( (rc = p->rc&0xff)==SQLITE_BUSY || rc==SQLITE_LOCKED ){ - tdsqlite3_reset((tdsqlite3_stmt*)p); + sqlite3_reset((sqlite3_stmt*)p); }else{ return SQLITE_MISUSE_BKPT; } #else - tdsqlite3_reset((tdsqlite3_stmt*)p); + sqlite3_reset((sqlite3_stmt*)p); #endif } @@ -86793,7 +86793,7 @@ static int tdsqlite3Step(Vdbe *p){ } if( p->pc<0 ){ /* If there are no other statements currently running, then - ** reset the interrupt flag. This prevents a call to tdsqlite3_interrupt + ** reset the interrupt flag. This prevents a call to sqlite3_interrupt ** from interrupting a statement that has not yet started. */ if( db->nVdbeActive==0 ){ @@ -86807,7 +86807,7 @@ static int tdsqlite3Step(Vdbe *p){ #ifndef SQLITE_OMIT_TRACE if( (db->mTrace & (SQLITE_TRACE_PROFILE|SQLITE_TRACE_XPROFILE))!=0 && !db->init.busy && p->zSql ){ - tdsqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); + sqlite3OsCurrentTimeInt64(db->pVfs, &p->startTime); }else{ assert( p->startTime==0 ); } @@ -86823,12 +86823,12 @@ static int tdsqlite3Step(Vdbe *p){ #endif #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ - rc = tdsqlite3VdbeList(p); + rc = sqlite3VdbeList(p); }else #endif /* SQLITE_OMIT_EXPLAIN */ { db->nVdbeExec++; - rc = tdsqlite3VdbeExec(p); + rc = sqlite3VdbeExec(p); db->nVdbeExec--; } @@ -86848,15 +86848,15 @@ static int tdsqlite3Step(Vdbe *p){ } db->errCode = rc; - if( SQLITE_NOMEM==tdsqlite3ApiExit(p->db, p->rc) ){ + if( SQLITE_NOMEM==sqlite3ApiExit(p->db, p->rc) ){ p->rc = SQLITE_NOMEM_BKPT; } end_of_step: /* At this point local variable rc holds the value that should be ** returned if this statement was compiled using the legacy - ** tdsqlite3_prepare() interface. According to the docs, this can only + ** sqlite3_prepare() interface. According to the docs, this can only ** be one of the values in the first assert() below. Variable p->rc - ** contains the value that would be returned if tdsqlite3_finalize() + ** contains the value that would be returned if sqlite3_finalize() ** were called on statement p. */ assert( rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR @@ -86871,32 +86871,32 @@ end_of_step: ** error has occurred, then return the error code in p->rc to the ** caller. Set the error code in the database handle to the same value. */ - rc = tdsqlite3VdbeTransferError(p); + rc = sqlite3VdbeTransferError(p); } return (rc&db->errMask); } /* -** This is the top-level implementation of tdsqlite3_step(). Call -** tdsqlite3Step() to do most of the work. If a schema error occurs, -** call tdsqlite3Reprepare() and try again. +** This is the top-level implementation of sqlite3_step(). Call +** sqlite3Step() to do most of the work. If a schema error occurs, +** call sqlite3Reprepare() and try again. */ -SQLITE_API int tdsqlite3_step(tdsqlite3_stmt *pStmt){ - int rc = SQLITE_OK; /* Result from tdsqlite3Step() */ +SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ + int rc = SQLITE_OK; /* Result from sqlite3Step() */ Vdbe *v = (Vdbe*)pStmt; /* the prepared statement */ int cnt = 0; /* Counter to prevent infinite loop of reprepares */ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ if( vdbeSafetyNotNull(v) ){ return SQLITE_MISUSE_BKPT; } db = v->db; - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); v->doingRerun = 0; - while( (rc = tdsqlite3Step(v))==SQLITE_SCHEMA + while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < SQLITE_MAX_SCHEMA_RETRY ){ int savedPc = v->pc; - rc = tdsqlite3Reprepare(v); + rc = sqlite3Reprepare(v); if( rc!=SQLITE_OK ){ /* This case occurs after failing to recompile an sql statement. ** The error message from the SQL compiler has already been loaded @@ -86904,48 +86904,48 @@ SQLITE_API int tdsqlite3_step(tdsqlite3_stmt *pStmt){ ** from the database handle into the statement and sets the statement ** program counter to 0 to ensure that when the statement is ** finalized or reset the parser error message is available via - ** tdsqlite3_errmsg() and tdsqlite3_errcode(). + ** sqlite3_errmsg() and sqlite3_errcode(). */ - const char *zErr = (const char *)tdsqlite3_value_text(db->pErr); - tdsqlite3DbFree(db, v->zErrMsg); + const char *zErr = (const char *)sqlite3_value_text(db->pErr); + sqlite3DbFree(db, v->zErrMsg); if( !db->mallocFailed ){ - v->zErrMsg = tdsqlite3DbStrDup(db, zErr); - v->rc = rc = tdsqlite3ApiExit(db, rc); + v->zErrMsg = sqlite3DbStrDup(db, zErr); + v->rc = rc = sqlite3ApiExit(db, rc); } else { v->zErrMsg = 0; v->rc = rc = SQLITE_NOMEM_BKPT; } break; } - tdsqlite3_reset(pStmt); + sqlite3_reset(pStmt); if( savedPc>=0 ) v->doingRerun = 1; assert( v->expired==0 ); } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return rc; } /* -** Extract the user data from a tdsqlite3_context structure and return a +** Extract the user data from a sqlite3_context structure and return a ** pointer to it. */ -SQLITE_API void *tdsqlite3_user_data(tdsqlite3_context *p){ +SQLITE_API void *sqlite3_user_data(sqlite3_context *p){ assert( p && p->pFunc ); return p->pFunc->pUserData; } /* -** Extract the user data from a tdsqlite3_context structure and return a +** Extract the user data from a sqlite3_context structure and return a ** pointer to it. ** -** IMPLEMENTATION-OF: R-46798-50301 The tdsqlite3_context_db_handle() interface +** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface ** returns a copy of the pointer to the database connection (the 1st -** parameter) of the tdsqlite3_create_function() and -** tdsqlite3_create_function16() routines that originally registered the +** parameter) of the sqlite3_create_function() and +** sqlite3_create_function16() routines that originally registered the ** application defined function. */ -SQLITE_API tdsqlite3 *tdsqlite3_context_db_handle(tdsqlite3_context *p){ +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ assert( p && p->pOut ); return p->pOut->db; } @@ -86964,9 +86964,9 @@ SQLITE_API tdsqlite3 *tdsqlite3_context_db_handle(tdsqlite3_context *p){ ** performance by substituting a NULL result, or some other light-weight ** value, as a signal to the xUpdate routine that the column is unchanged. */ -SQLITE_API int tdsqlite3_vtab_nochange(tdsqlite3_context *p){ +SQLITE_API int sqlite3_vtab_nochange(sqlite3_context *p){ assert( p ); - return tdsqlite3_value_nochange(p->pOut); + return sqlite3_value_nochange(p->pOut); } /* @@ -86976,17 +86976,17 @@ SQLITE_API int tdsqlite3_vtab_nochange(tdsqlite3_context *p){ ** of the amount of time that elapses between invocations. In other words, ** the time returned is always the time of the first call. */ -SQLITE_PRIVATE tdsqlite3_int64 tdsqlite3StmtCurrentTime(tdsqlite3_context *p){ +SQLITE_PRIVATE sqlite3_int64 sqlite3StmtCurrentTime(sqlite3_context *p){ int rc; #ifndef SQLITE_ENABLE_STAT4 - tdsqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; + sqlite3_int64 *piTime = &p->pVdbe->iCurrentTime; assert( p->pVdbe!=0 ); #else - tdsqlite3_int64 iTime = 0; - tdsqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; + sqlite3_int64 iTime = 0; + sqlite3_int64 *piTime = p->pVdbe!=0 ? &p->pVdbe->iCurrentTime : &iTime; #endif if( *piTime==0 ){ - rc = tdsqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); + rc = sqlite3OsCurrentTimeInt64(p->pOut->db->pVfs, piTime); if( rc ) *piTime = 0; } return *piTime; @@ -86996,14 +86996,14 @@ SQLITE_PRIVATE tdsqlite3_int64 tdsqlite3StmtCurrentTime(tdsqlite3_context *p){ ** Create a new aggregate context for p and return a pointer to ** its pMem->z element. */ -static SQLITE_NOINLINE void *createAggContext(tdsqlite3_context *p, int nByte){ +static SQLITE_NOINLINE void *createAggContext(sqlite3_context *p, int nByte){ Mem *pMem = p->pMem; assert( (pMem->flags & MEM_Agg)==0 ); if( nByte<=0 ){ - tdsqlite3VdbeMemSetNull(pMem); + sqlite3VdbeMemSetNull(pMem); pMem->z = 0; }else{ - tdsqlite3VdbeMemClearAndResize(pMem, nByte); + sqlite3VdbeMemClearAndResize(pMem, nByte); pMem->flags = MEM_Agg; pMem->u.pDef = p->pFunc; if( pMem->z ){ @@ -87018,9 +87018,9 @@ static SQLITE_NOINLINE void *createAggContext(tdsqlite3_context *p, int nByte){ ** context is allocated on the first call. Subsequent calls return the ** same context that was returned on prior calls. */ -SQLITE_API void *tdsqlite3_aggregate_context(tdsqlite3_context *p, int nByte){ +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context *p, int nByte){ assert( p && p->pFunc && p->pFunc->xFinalize ); - assert( tdsqlite3_mutex_held(p->pOut->db->mutex) ); + assert( sqlite3_mutex_held(p->pOut->db->mutex) ); testcase( nByte<0 ); if( (p->pMem->flags & MEM_Agg)==0 ){ return createAggContext(p, nByte); @@ -87039,10 +87039,10 @@ SQLITE_API void *tdsqlite3_aggregate_context(tdsqlite3_context *p, int nByte){ ** auxiliary data pointers that is available to all functions within a ** single prepared statement. The iArg values must match. */ -SQLITE_API void *tdsqlite3_get_auxdata(tdsqlite3_context *pCtx, int iArg){ +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #if SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 0; #else @@ -87067,8 +87067,8 @@ SQLITE_API void *tdsqlite3_get_auxdata(tdsqlite3_context *pCtx, int iArg){ ** to all functions within the current prepared statement using iArg as an ** access code. */ -SQLITE_API void tdsqlite3_set_auxdata( - tdsqlite3_context *pCtx, +SQLITE_API void sqlite3_set_auxdata( + sqlite3_context *pCtx, int iArg, void *pAux, void (*xDelete)(void*) @@ -87076,7 +87076,7 @@ SQLITE_API void tdsqlite3_set_auxdata( AuxData *pAuxData; Vdbe *pVdbe = pCtx->pVdbe; - assert( tdsqlite3_mutex_held(pCtx->pOut->db->mutex) ); + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #ifdef SQLITE_ENABLE_STAT4 if( pVdbe==0 ) goto failed; #else @@ -87089,7 +87089,7 @@ SQLITE_API void tdsqlite3_set_auxdata( } } if( pAuxData==0 ){ - pAuxData = tdsqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); + pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData)); if( !pAuxData ) goto failed; pAuxData->iAuxOp = pCtx->iOp; pAuxData->iAuxArg = iArg; @@ -87120,7 +87120,7 @@ failed: ** implementations should keep their own counts within their aggregate ** context. */ -SQLITE_API int tdsqlite3_aggregate_count(tdsqlite3_context *p){ +SQLITE_API int sqlite3_aggregate_count(sqlite3_context *p){ assert( p && p->pMem && p->pFunc && p->pFunc->xFinalize ); return p->pMem->n; } @@ -87129,7 +87129,7 @@ SQLITE_API int tdsqlite3_aggregate_count(tdsqlite3_context *p){ /* ** Return the number of columns in the result set for the statement pStmt. */ -SQLITE_API int tdsqlite3_column_count(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; return pVm ? pVm->nResColumn : 0; } @@ -87138,7 +87138,7 @@ SQLITE_API int tdsqlite3_column_count(tdsqlite3_stmt *pStmt){ ** Return the number of values available from the current row of the ** currently executing statement pStmt. */ -SQLITE_API int tdsqlite3_data_count(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; if( pVm==0 || pVm->pResultSet==0 ) return 0; return pVm->nResColumn; @@ -87171,7 +87171,7 @@ static const Mem *columnNullValue(void){ /* .zMalloc = */ (char*)0, /* .szMalloc = */ (int)0, /* .uTemp = */ (u32)0, - /* .db = */ (tdsqlite3*)0, + /* .db = */ (sqlite3*)0, /* .xDel = */ (void(*)(void*))0, #ifdef SQLITE_DEBUG /* .pScopyFrom = */ (Mem*)0, @@ -87187,25 +87187,25 @@ static const Mem *columnNullValue(void){ ** If iCol is not valid, return a pointer to a Mem which has a value ** of NULL. */ -static Mem *columnMem(tdsqlite3_stmt *pStmt, int i){ +static Mem *columnMem(sqlite3_stmt *pStmt, int i){ Vdbe *pVm; Mem *pOut; pVm = (Vdbe *)pStmt; if( pVm==0 ) return (Mem*)columnNullValue(); assert( pVm->db ); - tdsqlite3_mutex_enter(pVm->db->mutex); + sqlite3_mutex_enter(pVm->db->mutex); if( pVm->pResultSet!=0 && inResColumn && i>=0 ){ pOut = &pVm->pResultSet[i]; }else{ - tdsqlite3Error(pVm->db, SQLITE_RANGE); + sqlite3Error(pVm->db, SQLITE_RANGE); pOut = (Mem*)columnNullValue(); } return pOut; } /* -** This function is called after invoking an tdsqlite3_value_XXX function on a +** This function is called after invoking an sqlite3_value_XXX function on a ** column value (i.e. a value returned by evaluating an SQL expression in the ** select list of a SELECT statement) that may cause a malloc() failure. If ** malloc() has failed, the threads mallocFailed flag is cleared and the result @@ -87213,38 +87213,38 @@ static Mem *columnMem(tdsqlite3_stmt *pStmt, int i){ ** ** Specifically, this is called from within: ** -** tdsqlite3_column_int() -** tdsqlite3_column_int64() -** tdsqlite3_column_text() -** tdsqlite3_column_text16() -** tdsqlite3_column_real() -** tdsqlite3_column_bytes() -** tdsqlite3_column_bytes16() +** sqlite3_column_int() +** sqlite3_column_int64() +** sqlite3_column_text() +** sqlite3_column_text16() +** sqlite3_column_real() +** sqlite3_column_bytes() +** sqlite3_column_bytes16() ** sqiite3_column_blob() */ -static void columnMallocFailure(tdsqlite3_stmt *pStmt) +static void columnMallocFailure(sqlite3_stmt *pStmt) { /* If malloc() failed during an encoding conversion within an - ** tdsqlite3_column_XXX API, then set the return code of the statement to + ** sqlite3_column_XXX API, then set the return code of the statement to ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR ** and _finalize() will return NOMEM. */ Vdbe *p = (Vdbe *)pStmt; if( p ){ assert( p->db!=0 ); - assert( tdsqlite3_mutex_held(p->db->mutex) ); - p->rc = tdsqlite3ApiExit(p->db, p->rc); - tdsqlite3_mutex_leave(p->db->mutex); + assert( sqlite3_mutex_held(p->db->mutex) ); + p->rc = sqlite3ApiExit(p->db, p->rc); + sqlite3_mutex_leave(p->db->mutex); } } -/**************************** tdsqlite3_column_ ******************************* +/**************************** sqlite3_column_ ******************************* ** The following routines are used to access elements of the current row ** in the result set. */ -SQLITE_API const void *tdsqlite3_column_blob(tdsqlite3_stmt *pStmt, int i){ +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt *pStmt, int i){ const void *val; - val = tdsqlite3_value_blob( columnMem(pStmt,i) ); + val = sqlite3_value_blob( columnMem(pStmt,i) ); /* Even though there is no encoding conversion, value_blob() might ** need to call malloc() to expand the result of a zeroblob() ** expression. @@ -87252,54 +87252,54 @@ SQLITE_API const void *tdsqlite3_column_blob(tdsqlite3_stmt *pStmt, int i){ columnMallocFailure(pStmt); return val; } -SQLITE_API int tdsqlite3_column_bytes(tdsqlite3_stmt *pStmt, int i){ - int val = tdsqlite3_value_bytes( columnMem(pStmt,i) ); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API int tdsqlite3_column_bytes16(tdsqlite3_stmt *pStmt, int i){ - int val = tdsqlite3_value_bytes16( columnMem(pStmt,i) ); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_bytes16( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API double tdsqlite3_column_double(tdsqlite3_stmt *pStmt, int i){ - double val = tdsqlite3_value_double( columnMem(pStmt,i) ); +SQLITE_API double sqlite3_column_double(sqlite3_stmt *pStmt, int i){ + double val = sqlite3_value_double( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API int tdsqlite3_column_int(tdsqlite3_stmt *pStmt, int i){ - int val = tdsqlite3_value_int( columnMem(pStmt,i) ); +SQLITE_API int sqlite3_column_int(sqlite3_stmt *pStmt, int i){ + int val = sqlite3_value_int( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API sqlite_int64 tdsqlite3_column_int64(tdsqlite3_stmt *pStmt, int i){ - sqlite_int64 val = tdsqlite3_value_int64( columnMem(pStmt,i) ); +SQLITE_API sqlite_int64 sqlite3_column_int64(sqlite3_stmt *pStmt, int i){ + sqlite_int64 val = sqlite3_value_int64( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API const unsigned char *tdsqlite3_column_text(tdsqlite3_stmt *pStmt, int i){ - const unsigned char *val = tdsqlite3_value_text( columnMem(pStmt,i) ); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt *pStmt, int i){ + const unsigned char *val = sqlite3_value_text( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } -SQLITE_API tdsqlite3_value *tdsqlite3_column_value(tdsqlite3_stmt *pStmt, int i){ +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt *pStmt, int i){ Mem *pOut = columnMem(pStmt, i); if( pOut->flags&MEM_Static ){ pOut->flags &= ~MEM_Static; pOut->flags |= MEM_Ephem; } columnMallocFailure(pStmt); - return (tdsqlite3_value *)pOut; + return (sqlite3_value *)pOut; } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *tdsqlite3_column_text16(tdsqlite3_stmt *pStmt, int i){ - const void *val = tdsqlite3_value_text16( columnMem(pStmt,i) ); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt *pStmt, int i){ + const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return val; } #endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API int tdsqlite3_column_type(tdsqlite3_stmt *pStmt, int i){ - int iType = tdsqlite3_value_type( columnMem(pStmt,i) ); +SQLITE_API int sqlite3_column_type(sqlite3_stmt *pStmt, int i){ + int iType = sqlite3_value_type( columnMem(pStmt,i) ); columnMallocFailure(pStmt); return iType; } @@ -87321,7 +87321,7 @@ SQLITE_API int tdsqlite3_column_type(tdsqlite3_stmt *pStmt, int i){ ** or a constant) then useTypes 2, 3, and 4 return NULL. */ static const void *columnName( - tdsqlite3_stmt *pStmt, /* The statement */ + sqlite3_stmt *pStmt, /* The statement */ int N, /* Which column to get the name for */ int useUtf16, /* True to return the name as UTF16 */ int useType /* What type of name */ @@ -87329,7 +87329,7 @@ static const void *columnName( const void *ret; Vdbe *p; int n; - tdsqlite3 *db; + sqlite3 *db; #ifdef SQLITE_ENABLE_API_ARMOR if( pStmt==0 ){ (void)SQLITE_MISUSE_BKPT; @@ -87340,27 +87340,27 @@ static const void *columnName( p = (Vdbe *)pStmt; db = p->db; assert( db!=0 ); - n = tdsqlite3_column_count(pStmt); + n = sqlite3_column_count(pStmt); if( N=0 ){ N += useType*n; - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); assert( db->mallocFailed==0 ); #ifndef SQLITE_OMIT_UTF16 if( useUtf16 ){ - ret = tdsqlite3_value_text16((tdsqlite3_value*)&p->aColName[N]); + ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]); }else #endif { - ret = tdsqlite3_value_text((tdsqlite3_value*)&p->aColName[N]); + ret = sqlite3_value_text((sqlite3_value*)&p->aColName[N]); } /* A malloc may have failed inside of the _text() call. If this ** is the case, clear the mallocFailed flag and return NULL. */ if( db->mallocFailed ){ - tdsqlite3OomClear(db); + sqlite3OomClear(db); ret = 0; } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); } return ret; } @@ -87369,11 +87369,11 @@ static const void *columnName( ** Return the name of the Nth column of the result set returned by SQL ** statement pStmt. */ -SQLITE_API const char *tdsqlite3_column_name(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 0, COLNAME_NAME); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *tdsqlite3_column_name16(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 1, COLNAME_NAME); } #endif @@ -87392,11 +87392,11 @@ SQLITE_API const void *tdsqlite3_column_name16(tdsqlite3_stmt *pStmt, int N){ ** Return the column declaration type (if applicable) of the 'i'th column ** of the result set of SQL statement pStmt. */ -SQLITE_API const char *tdsqlite3_column_decltype(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 0, COLNAME_DECLTYPE); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *tdsqlite3_column_decltype16(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 1, COLNAME_DECLTYPE); } #endif /* SQLITE_OMIT_UTF16 */ @@ -87408,11 +87408,11 @@ SQLITE_API const void *tdsqlite3_column_decltype16(tdsqlite3_stmt *pStmt, int N) ** NULL is returned if the result column is an expression or constant or ** anything else which is not an unambiguous reference to a database column. */ -SQLITE_API const char *tdsqlite3_column_database_name(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 0, COLNAME_DATABASE); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *tdsqlite3_column_database_name16(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 1, COLNAME_DATABASE); } #endif /* SQLITE_OMIT_UTF16 */ @@ -87422,11 +87422,11 @@ SQLITE_API const void *tdsqlite3_column_database_name16(tdsqlite3_stmt *pStmt, i ** NULL is returned if the result column is an expression or constant or ** anything else which is not an unambiguous reference to a database column. */ -SQLITE_API const char *tdsqlite3_column_table_name(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 0, COLNAME_TABLE); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *tdsqlite3_column_table_name16(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 1, COLNAME_TABLE); } #endif /* SQLITE_OMIT_UTF16 */ @@ -87436,18 +87436,18 @@ SQLITE_API const void *tdsqlite3_column_table_name16(tdsqlite3_stmt *pStmt, int ** NULL is returned if the result column is an expression or constant or ** anything else which is not an unambiguous reference to a database column. */ -SQLITE_API const char *tdsqlite3_column_origin_name(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 0, COLNAME_COLUMN); } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API const void *tdsqlite3_column_origin_name16(tdsqlite3_stmt *pStmt, int N){ +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt *pStmt, int N){ return columnName(pStmt, N, 1, COLNAME_COLUMN); } #endif /* SQLITE_OMIT_UTF16 */ #endif /* SQLITE_ENABLE_COLUMN_METADATA */ -/******************************* tdsqlite3_bind_ *************************** +/******************************* sqlite3_bind_ *************************** ** ** Routines used to attach values to wildcards in a compiled SQL statement. */ @@ -87467,22 +87467,22 @@ static int vdbeUnbind(Vdbe *p, int i){ if( vdbeSafetyNotNull(p) ){ return SQLITE_MISUSE_BKPT; } - tdsqlite3_mutex_enter(p->db->mutex); + sqlite3_mutex_enter(p->db->mutex); if( p->magic!=VDBE_MAGIC_RUN || p->pc>=0 ){ - tdsqlite3Error(p->db, SQLITE_MISUSE); - tdsqlite3_mutex_leave(p->db->mutex); - tdsqlite3_log(SQLITE_MISUSE, + sqlite3Error(p->db, SQLITE_MISUSE); + sqlite3_mutex_leave(p->db->mutex); + sqlite3_log(SQLITE_MISUSE, "bind on a busy prepared statement: [%s]", p->zSql); return SQLITE_MISUSE_BKPT; } if( i<1 || i>p->nVar ){ - tdsqlite3Error(p->db, SQLITE_RANGE); - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3Error(p->db, SQLITE_RANGE); + sqlite3_mutex_leave(p->db->mutex); return SQLITE_RANGE; } i--; pVar = &p->aVar[i]; - tdsqlite3VdbeMemRelease(pVar); + sqlite3VdbeMemRelease(pVar); pVar->flags = MEM_Null; p->db->errCode = SQLITE_OK; @@ -87492,7 +87492,7 @@ static int vdbeUnbind(Vdbe *p, int i){ ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host ** parameter in the WHERE clause might influence the choice of query plan ** for a statement, then the statement will be automatically recompiled, - ** as if there had been a schema change, on the first tdsqlite3_step() call + ** as if there had been a schema change, on the first sqlite3_step() call ** following any change to the bindings of that parameter. */ assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 || p->expmask==0 ); @@ -87506,7 +87506,7 @@ static int vdbeUnbind(Vdbe *p, int i){ ** Bind a text or BLOB value. */ static int bindText( - tdsqlite3_stmt *pStmt, /* The statement to bind against */ + sqlite3_stmt *pStmt, /* The statement to bind against */ int i, /* Index of the parameter to bind */ const void *zData, /* Pointer to the data to be bound */ int nData, /* Number of bytes of data to be bound */ @@ -87521,16 +87521,16 @@ static int bindText( if( rc==SQLITE_OK ){ if( zData!=0 ){ pVar = &p->aVar[i-1]; - rc = tdsqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); + rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel); if( rc==SQLITE_OK && encoding!=0 ){ - rc = tdsqlite3VdbeChangeEncoding(pVar, ENC(p->db)); + rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db)); } if( rc ){ - tdsqlite3Error(p->db, rc); - rc = tdsqlite3ApiExit(p->db, rc); + sqlite3Error(p->db, rc); + rc = sqlite3ApiExit(p->db, rc); } } - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3_mutex_leave(p->db->mutex); }else if( xDel!=SQLITE_STATIC && xDel!=SQLITE_TRANSIENT ){ xDel((void*)zData); } @@ -87541,8 +87541,8 @@ static int bindText( /* ** Bind a blob value to an SQL statement variable. */ -SQLITE_API int tdsqlite3_bind_blob( - tdsqlite3_stmt *pStmt, +SQLITE_API int sqlite3_bind_blob( + sqlite3_stmt *pStmt, int i, const void *zData, int nData, @@ -87553,11 +87553,11 @@ SQLITE_API int tdsqlite3_bind_blob( #endif return bindText(pStmt, i, zData, nData, xDel, 0); } -SQLITE_API int tdsqlite3_bind_blob64( - tdsqlite3_stmt *pStmt, +SQLITE_API int sqlite3_bind_blob64( + sqlite3_stmt *pStmt, int i, const void *zData, - tdsqlite3_uint64 nData, + sqlite3_uint64 nData, void (*xDel)(void*) ){ assert( xDel!=SQLITE_DYNAMIC ); @@ -87567,40 +87567,40 @@ SQLITE_API int tdsqlite3_bind_blob64( return bindText(pStmt, i, zData, (int)nData, xDel, 0); } } -SQLITE_API int tdsqlite3_bind_double(tdsqlite3_stmt *pStmt, int i, double rValue){ +SQLITE_API int sqlite3_bind_double(sqlite3_stmt *pStmt, int i, double rValue){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ - tdsqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3VdbeMemSetDouble(&p->aVar[i-1], rValue); + sqlite3_mutex_leave(p->db->mutex); } return rc; } -SQLITE_API int tdsqlite3_bind_int(tdsqlite3_stmt *p, int i, int iValue){ - return tdsqlite3_bind_int64(p, i, (i64)iValue); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt *p, int i, int iValue){ + return sqlite3_bind_int64(p, i, (i64)iValue); } -SQLITE_API int tdsqlite3_bind_int64(tdsqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt *pStmt, int i, sqlite_int64 iValue){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ - tdsqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3VdbeMemSetInt64(&p->aVar[i-1], iValue); + sqlite3_mutex_leave(p->db->mutex); } return rc; } -SQLITE_API int tdsqlite3_bind_null(tdsqlite3_stmt *pStmt, int i){ +SQLITE_API int sqlite3_bind_null(sqlite3_stmt *pStmt, int i){ int rc; Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3_mutex_leave(p->db->mutex); } return rc; } -SQLITE_API int tdsqlite3_bind_pointer( - tdsqlite3_stmt *pStmt, +SQLITE_API int sqlite3_bind_pointer( + sqlite3_stmt *pStmt, int i, void *pPtr, const char *zPTtype, @@ -87610,15 +87610,15 @@ SQLITE_API int tdsqlite3_bind_pointer( Vdbe *p = (Vdbe*)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ - tdsqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3VdbeMemSetPointer(&p->aVar[i-1], pPtr, zPTtype, xDestructor); + sqlite3_mutex_leave(p->db->mutex); }else if( xDestructor ){ xDestructor(pPtr); } return rc; } -SQLITE_API int tdsqlite3_bind_text( - tdsqlite3_stmt *pStmt, +SQLITE_API int sqlite3_bind_text( + sqlite3_stmt *pStmt, int i, const char *zData, int nData, @@ -87626,11 +87626,11 @@ SQLITE_API int tdsqlite3_bind_text( ){ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); } -SQLITE_API int tdsqlite3_bind_text64( - tdsqlite3_stmt *pStmt, +SQLITE_API int sqlite3_bind_text64( + sqlite3_stmt *pStmt, int i, const char *zData, - tdsqlite3_uint64 nData, + sqlite3_uint64 nData, void (*xDel)(void*), unsigned char enc ){ @@ -87643,8 +87643,8 @@ SQLITE_API int tdsqlite3_bind_text64( } } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API int tdsqlite3_bind_text16( - tdsqlite3_stmt *pStmt, +SQLITE_API int sqlite3_bind_text16( + sqlite3_stmt *pStmt, int i, const void *zData, int nData, @@ -87653,22 +87653,22 @@ SQLITE_API int tdsqlite3_bind_text16( return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); } #endif /* SQLITE_OMIT_UTF16 */ -SQLITE_API int tdsqlite3_bind_value(tdsqlite3_stmt *pStmt, int i, const tdsqlite3_value *pValue){ +SQLITE_API int sqlite3_bind_value(sqlite3_stmt *pStmt, int i, const sqlite3_value *pValue){ int rc; - switch( tdsqlite3_value_type((tdsqlite3_value*)pValue) ){ + switch( sqlite3_value_type((sqlite3_value*)pValue) ){ case SQLITE_INTEGER: { - rc = tdsqlite3_bind_int64(pStmt, i, pValue->u.i); + rc = sqlite3_bind_int64(pStmt, i, pValue->u.i); break; } case SQLITE_FLOAT: { - rc = tdsqlite3_bind_double(pStmt, i, pValue->u.r); + rc = sqlite3_bind_double(pStmt, i, pValue->u.r); break; } case SQLITE_BLOB: { if( pValue->flags & MEM_Zero ){ - rc = tdsqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero); + rc = sqlite3_bind_zeroblob(pStmt, i, pValue->u.nZero); }else{ - rc = tdsqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT); + rc = sqlite3_bind_blob(pStmt, i, pValue->z, pValue->n,SQLITE_TRANSIENT); } break; } @@ -87678,34 +87678,34 @@ SQLITE_API int tdsqlite3_bind_value(tdsqlite3_stmt *pStmt, int i, const tdsqlite break; } default: { - rc = tdsqlite3_bind_null(pStmt, i); + rc = sqlite3_bind_null(pStmt, i); break; } } return rc; } -SQLITE_API int tdsqlite3_bind_zeroblob(tdsqlite3_stmt *pStmt, int i, int n){ +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt *pStmt, int i, int n){ int rc; Vdbe *p = (Vdbe *)pStmt; rc = vdbeUnbind(p, i); if( rc==SQLITE_OK ){ - tdsqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3VdbeMemSetZeroBlob(&p->aVar[i-1], n); + sqlite3_mutex_leave(p->db->mutex); } return rc; } -SQLITE_API int tdsqlite3_bind_zeroblob64(tdsqlite3_stmt *pStmt, int i, tdsqlite3_uint64 n){ +SQLITE_API int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){ int rc; Vdbe *p = (Vdbe *)pStmt; - tdsqlite3_mutex_enter(p->db->mutex); + sqlite3_mutex_enter(p->db->mutex); if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){ rc = SQLITE_TOOBIG; }else{ assert( (n & 0x7FFFFFFF)==n ); - rc = tdsqlite3_bind_zeroblob(pStmt, i, n); + rc = sqlite3_bind_zeroblob(pStmt, i, n); } - rc = tdsqlite3ApiExit(p->db, rc); - tdsqlite3_mutex_leave(p->db->mutex); + rc = sqlite3ApiExit(p->db, rc); + sqlite3_mutex_leave(p->db->mutex); return rc; } @@ -87713,7 +87713,7 @@ SQLITE_API int tdsqlite3_bind_zeroblob64(tdsqlite3_stmt *pStmt, int i, tdsqlite3 ** Return the number of wildcards that can be potentially bound to. ** This routine is added to support DBD::SQLite. */ -SQLITE_API int tdsqlite3_bind_parameter_count(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; return p ? p->nVar : 0; } @@ -87724,10 +87724,10 @@ SQLITE_API int tdsqlite3_bind_parameter_count(tdsqlite3_stmt *pStmt){ ** ** The result is always UTF-8. */ -SQLITE_API const char *tdsqlite3_bind_parameter_name(tdsqlite3_stmt *pStmt, int i){ +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ Vdbe *p = (Vdbe*)pStmt; if( p==0 ) return 0; - return tdsqlite3VListNumToName(p->pVList, i); + return sqlite3VListNumToName(p->pVList, i); } /* @@ -87735,35 +87735,35 @@ SQLITE_API const char *tdsqlite3_bind_parameter_name(tdsqlite3_stmt *pStmt, int ** with that name. If there is no variable with the given name, ** return 0. */ -SQLITE_PRIVATE int tdsqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ +SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ if( p==0 || zName==0 ) return 0; - return tdsqlite3VListNameToNum(p->pVList, zName, nName); + return sqlite3VListNameToNum(p->pVList, zName, nName); } -SQLITE_API int tdsqlite3_bind_parameter_index(tdsqlite3_stmt *pStmt, const char *zName){ - return tdsqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, tdsqlite3Strlen30(zName)); +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt *pStmt, const char *zName){ + return sqlite3VdbeParameterIndex((Vdbe*)pStmt, zName, sqlite3Strlen30(zName)); } /* ** Transfer all bindings from the first statement over to the second. */ -SQLITE_PRIVATE int tdsqlite3TransferBindings(tdsqlite3_stmt *pFromStmt, tdsqlite3_stmt *pToStmt){ +SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ Vdbe *pFrom = (Vdbe*)pFromStmt; Vdbe *pTo = (Vdbe*)pToStmt; int i; assert( pTo->db==pFrom->db ); assert( pTo->nVar==pFrom->nVar ); - tdsqlite3_mutex_enter(pTo->db->mutex); + sqlite3_mutex_enter(pTo->db->mutex); for(i=0; inVar; i++){ - tdsqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); + sqlite3VdbeMemMove(&pTo->aVar[i], &pFrom->aVar[i]); } - tdsqlite3_mutex_leave(pTo->db->mutex); + sqlite3_mutex_leave(pTo->db->mutex); return SQLITE_OK; } #ifndef SQLITE_OMIT_DEPRECATED /* ** Deprecated external interface. Internal/core SQLite code -** should call tdsqlite3TransferBindings. +** should call sqlite3TransferBindings. ** ** It is misuse to call this routine with statements from different ** database connections. But as this is a deprecated interface, we @@ -87773,7 +87773,7 @@ SQLITE_PRIVATE int tdsqlite3TransferBindings(tdsqlite3_stmt *pFromStmt, tdsqlite ** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise ** SQLITE_OK is returned. */ -SQLITE_API int tdsqlite3_transfer_bindings(tdsqlite3_stmt *pFromStmt, tdsqlite3_stmt *pToStmt){ +SQLITE_API int sqlite3_transfer_bindings(sqlite3_stmt *pFromStmt, sqlite3_stmt *pToStmt){ Vdbe *pFrom = (Vdbe*)pFromStmt; Vdbe *pTo = (Vdbe*)pToStmt; if( pFrom->nVar!=pTo->nVar ){ @@ -87787,17 +87787,17 @@ SQLITE_API int tdsqlite3_transfer_bindings(tdsqlite3_stmt *pFromStmt, tdsqlite3_ if( pFrom->expmask ){ pFrom->expired = 1; } - return tdsqlite3TransferBindings(pFromStmt, pToStmt); + return sqlite3TransferBindings(pFromStmt, pToStmt); } #endif /* -** Return the tdsqlite3* database handle to which the prepared statement given +** Return the sqlite3* database handle to which the prepared statement given ** in the argument belongs. This is the same database handle that was -** the first argument to the tdsqlite3_prepare() that was used to create +** the first argument to the sqlite3_prepare() that was used to create ** the statement in the first place. */ -SQLITE_API tdsqlite3 *tdsqlite3_db_handle(tdsqlite3_stmt *pStmt){ +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->db : 0; } @@ -87805,7 +87805,7 @@ SQLITE_API tdsqlite3 *tdsqlite3_db_handle(tdsqlite3_stmt *pStmt){ ** Return true if the prepared statement is guaranteed to not modify the ** database. */ -SQLITE_API int tdsqlite3_stmt_readonly(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->readOnly : 1; } @@ -87813,14 +87813,14 @@ SQLITE_API int tdsqlite3_stmt_readonly(tdsqlite3_stmt *pStmt){ ** Return 1 if the statement is an EXPLAIN and return 2 if the ** statement is an EXPLAIN QUERY PLAN */ -SQLITE_API int tdsqlite3_stmt_isexplain(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt){ return pStmt ? ((Vdbe*)pStmt)->explain : 0; } /* ** Return true if the prepared statement is in need of being reset. */ -SQLITE_API int tdsqlite3_stmt_busy(tdsqlite3_stmt *pStmt){ +SQLITE_API int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; return v!=0 && v->magic==VDBE_MAGIC_RUN && v->pc>=0; } @@ -87831,28 +87831,28 @@ SQLITE_API int tdsqlite3_stmt_busy(tdsqlite3_stmt *pStmt){ ** prepared statement for the database connection. Return NULL if there ** are no more. */ -SQLITE_API tdsqlite3_stmt *tdsqlite3_next_stmt(tdsqlite3 *pDb, tdsqlite3_stmt *pStmt){ - tdsqlite3_stmt *pNext; +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){ + sqlite3_stmt *pNext; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(pDb) ){ + if( !sqlite3SafetyCheckOk(pDb) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - tdsqlite3_mutex_enter(pDb->mutex); + sqlite3_mutex_enter(pDb->mutex); if( pStmt==0 ){ - pNext = (tdsqlite3_stmt*)pDb->pVdbe; + pNext = (sqlite3_stmt*)pDb->pVdbe; }else{ - pNext = (tdsqlite3_stmt*)((Vdbe*)pStmt)->pNext; + pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext; } - tdsqlite3_mutex_leave(pDb->mutex); + sqlite3_mutex_leave(pDb->mutex); return pNext; } /* ** Return the value of a status counter for a prepared statement */ -SQLITE_API int tdsqlite3_stmt_status(tdsqlite3_stmt *pStmt, int op, int resetFlag){ +SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ Vdbe *pVdbe = (Vdbe*)pStmt; u32 v; #ifdef SQLITE_ENABLE_API_ARMOR @@ -87864,14 +87864,14 @@ SQLITE_API int tdsqlite3_stmt_status(tdsqlite3_stmt *pStmt, int op, int resetFla } #endif if( op==SQLITE_STMTSTATUS_MEMUSED ){ - tdsqlite3 *db = pVdbe->db; - tdsqlite3_mutex_enter(db->mutex); + sqlite3 *db = pVdbe->db; + sqlite3_mutex_enter(db->mutex); v = 0; db->pnBytesFreed = (int*)&v; - tdsqlite3VdbeClearObject(db, pVdbe); - tdsqlite3DbFree(db, pVdbe); + sqlite3VdbeClearObject(db, pVdbe); + sqlite3DbFree(db, pVdbe); db->pnBytesFreed = 0; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); }else{ v = pVdbe->aCounter[op]; if( resetFlag ) pVdbe->aCounter[op] = 0; @@ -87882,7 +87882,7 @@ SQLITE_API int tdsqlite3_stmt_status(tdsqlite3_stmt *pStmt, int op, int resetFla /* ** Return the SQL associated with a prepared statement */ -SQLITE_API const char *tdsqlite3_sql(tdsqlite3_stmt *pStmt){ +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe *)pStmt; return p ? p->zSql : 0; } @@ -87890,23 +87890,23 @@ SQLITE_API const char *tdsqlite3_sql(tdsqlite3_stmt *pStmt){ /* ** Return the SQL associated with a prepared statement with ** bound parameters expanded. Space to hold the returned string is -** obtained from tdsqlite3_malloc(). The caller is responsible for -** freeing the returned string by passing it to tdsqlite3_free(). +** obtained from sqlite3_malloc(). The caller is responsible for +** freeing the returned string by passing it to sqlite3_free(). ** ** The SQLITE_TRACE_SIZE_LIMIT puts an upper bound on the size of ** expanded bound parameters. */ -SQLITE_API char *tdsqlite3_expanded_sql(tdsqlite3_stmt *pStmt){ +SQLITE_API char *sqlite3_expanded_sql(sqlite3_stmt *pStmt){ #ifdef SQLITE_OMIT_TRACE return 0; #else char *z = 0; - const char *zSql = tdsqlite3_sql(pStmt); + const char *zSql = sqlite3_sql(pStmt); if( zSql ){ Vdbe *p = (Vdbe *)pStmt; - tdsqlite3_mutex_enter(p->db->mutex); - z = tdsqlite3VdbeExpandSql(p, zSql); - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3_mutex_enter(p->db->mutex); + z = sqlite3VdbeExpandSql(p, zSql); + sqlite3_mutex_leave(p->db->mutex); } return z; #endif @@ -87916,13 +87916,13 @@ SQLITE_API char *tdsqlite3_expanded_sql(tdsqlite3_stmt *pStmt){ /* ** Return the normalized SQL associated with a prepared statement. */ -SQLITE_API const char *tdsqlite3_normalized_sql(tdsqlite3_stmt *pStmt){ +SQLITE_API const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe *)pStmt; if( p==0 ) return 0; if( p->zNormSql==0 && ALWAYS(p->zSql!=0) ){ - tdsqlite3_mutex_enter(p->db->mutex); - p->zNormSql = tdsqlite3Normalize(p, p->zSql); - tdsqlite3_mutex_leave(p->db->mutex); + sqlite3_mutex_enter(p->db->mutex); + p->zNormSql = sqlite3Normalize(p, p->zSql); + sqlite3_mutex_leave(p->db->mutex); } return p->zNormSql; } @@ -87941,10 +87941,10 @@ static UnpackedRecord *vdbeUnpackRecord( ){ UnpackedRecord *pRet; /* Return value */ - pRet = tdsqlite3VdbeAllocUnpackedRecord(pKeyInfo); + pRet = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); if( pRet ){ memset(pRet->aMem, 0, sizeof(Mem)*(pKeyInfo->nKeyField+1)); - tdsqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); + sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, pRet); } return pRet; } @@ -87953,7 +87953,7 @@ static UnpackedRecord *vdbeUnpackRecord( ** This function is called from within a pre-update callback to retrieve ** a field of the row currently being updated or deleted. */ -SQLITE_API int tdsqlite3_preupdate_old(tdsqlite3 *db, int iIdx, tdsqlite3_value **ppValue){ +SQLITE_API int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ PreUpdate *p = db->pPreUpdate; Mem *pMem; int rc = SQLITE_OK; @@ -87965,7 +87965,7 @@ SQLITE_API int tdsqlite3_preupdate_old(tdsqlite3 *db, int iIdx, tdsqlite3_value goto preupdate_old_out; } if( p->pPk ){ - iIdx = tdsqlite3TableColumnToIndex(p->pPk, iIdx); + iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx); } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; @@ -87977,16 +87977,16 @@ SQLITE_API int tdsqlite3_preupdate_old(tdsqlite3 *db, int iIdx, tdsqlite3_value u32 nRec; u8 *aRec; - nRec = tdsqlite3BtreePayloadSize(p->pCsr->uc.pCursor); - aRec = tdsqlite3DbMallocRaw(db, nRec); + nRec = sqlite3BtreePayloadSize(p->pCsr->uc.pCursor); + aRec = sqlite3DbMallocRaw(db, nRec); if( !aRec ) goto preupdate_old_out; - rc = tdsqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); + rc = sqlite3BtreePayload(p->pCsr->uc.pCursor, 0, nRec, aRec); if( rc==SQLITE_OK ){ p->pUnpacked = vdbeUnpackRecord(&p->keyinfo, nRec, aRec); if( !p->pUnpacked ) rc = SQLITE_NOMEM; } if( rc!=SQLITE_OK ){ - tdsqlite3DbFree(db, aRec); + sqlite3DbFree(db, aRec); goto preupdate_old_out; } p->aRecord = aRec; @@ -87994,20 +87994,20 @@ SQLITE_API int tdsqlite3_preupdate_old(tdsqlite3 *db, int iIdx, tdsqlite3_value pMem = *ppValue = &p->pUnpacked->aMem[iIdx]; if( iIdx==p->pTab->iPKey ){ - tdsqlite3VdbeMemSetInt64(pMem, p->iKey1); + sqlite3VdbeMemSetInt64(pMem, p->iKey1); }else if( iIdx>=p->pUnpacked->nField ){ - *ppValue = (tdsqlite3_value *)columnNullValue(); + *ppValue = (sqlite3_value *)columnNullValue(); }else if( p->pTab->aCol[iIdx].affinity==SQLITE_AFF_REAL ){ if( pMem->flags & (MEM_Int|MEM_IntReal) ){ testcase( pMem->flags & MEM_Int ); testcase( pMem->flags & MEM_IntReal ); - tdsqlite3VdbeMemRealify(pMem); + sqlite3VdbeMemRealify(pMem); } } preupdate_old_out: - tdsqlite3Error(db, rc); - return tdsqlite3ApiExit(db, rc); + sqlite3Error(db, rc); + return sqlite3ApiExit(db, rc); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -88016,7 +88016,7 @@ SQLITE_API int tdsqlite3_preupdate_old(tdsqlite3 *db, int iIdx, tdsqlite3_value ** This function is called from within a pre-update callback to retrieve ** the number of columns in the row being updated, deleted or inserted. */ -SQLITE_API int tdsqlite3_preupdate_count(tdsqlite3 *db){ +SQLITE_API int sqlite3_preupdate_count(sqlite3 *db){ PreUpdate *p = db->pPreUpdate; return (p ? p->keyinfo.nKeyField : 0); } @@ -88034,7 +88034,7 @@ SQLITE_API int tdsqlite3_preupdate_count(tdsqlite3 *db){ ** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL ** or SET DEFAULT action is considered a trigger. */ -SQLITE_API int tdsqlite3_preupdate_depth(tdsqlite3 *db){ +SQLITE_API int sqlite3_preupdate_depth(sqlite3 *db){ PreUpdate *p = db->pPreUpdate; return (p ? p->v->nFrame : 0); } @@ -88045,7 +88045,7 @@ SQLITE_API int tdsqlite3_preupdate_depth(tdsqlite3 *db){ ** This function is called from within a pre-update callback to retrieve ** a field of the row currently being updated or inserted. */ -SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *db, int iIdx, tdsqlite3_value **ppValue){ +SQLITE_API int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ PreUpdate *p = db->pPreUpdate; int rc = SQLITE_OK; Mem *pMem; @@ -88055,7 +88055,7 @@ SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *db, int iIdx, tdsqlite3_value goto preupdate_new_out; } if( p->pPk && p->op!=SQLITE_UPDATE ){ - iIdx = tdsqlite3TableColumnToIndex(p->pPk, iIdx); + iIdx = sqlite3TableColumnToIndex(p->pPk, iIdx); } if( iIdx>=p->pCsr->nField || iIdx<0 ){ rc = SQLITE_RANGE; @@ -88079,9 +88079,9 @@ SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *db, int iIdx, tdsqlite3_value } pMem = &pUnpack->aMem[iIdx]; if( iIdx==p->pTab->iPKey ){ - tdsqlite3VdbeMemSetInt64(pMem, p->iKey2); + sqlite3VdbeMemSetInt64(pMem, p->iKey2); }else if( iIdx>=pUnpack->nField ){ - pMem = (tdsqlite3_value *)columnNullValue(); + pMem = (sqlite3_value *)columnNullValue(); } }else{ /* For an UPDATE, memory cell (p->iNewReg+1+iIdx) contains the required @@ -88091,7 +88091,7 @@ SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *db, int iIdx, tdsqlite3_value */ assert( p->op==SQLITE_UPDATE ); if( !p->aNew ){ - p->aNew = (Mem *)tdsqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField); + p->aNew = (Mem *)sqlite3DbMallocZero(db, sizeof(Mem) * p->pCsr->nField); if( !p->aNew ){ rc = SQLITE_NOMEM; goto preupdate_new_out; @@ -88101,9 +88101,9 @@ SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *db, int iIdx, tdsqlite3_value pMem = &p->aNew[iIdx]; if( pMem->flags==0 ){ if( iIdx==p->pTab->iPKey ){ - tdsqlite3VdbeMemSetInt64(pMem, p->iKey2); + sqlite3VdbeMemSetInt64(pMem, p->iKey2); }else{ - rc = tdsqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); + rc = sqlite3VdbeMemCopy(pMem, &p->v->aMem[p->iNewReg+1+iIdx]); if( rc!=SQLITE_OK ) goto preupdate_new_out; } } @@ -88111,8 +88111,8 @@ SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *db, int iIdx, tdsqlite3_value *ppValue = pMem; preupdate_new_out: - tdsqlite3Error(db, rc); - return tdsqlite3ApiExit(db, rc); + sqlite3Error(db, rc); + return sqlite3ApiExit(db, rc); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -88120,8 +88120,8 @@ SQLITE_API int tdsqlite3_preupdate_new(tdsqlite3 *db, int iIdx, tdsqlite3_value /* ** Return status data for a single loop within query pStmt. */ -SQLITE_API int tdsqlite3_stmt_scanstatus( - tdsqlite3_stmt *pStmt, /* Prepared statement being queried */ +SQLITE_API int sqlite3_stmt_scanstatus( + sqlite3_stmt *pStmt, /* Prepared statement being queried */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Which metric to return */ void *pOut /* OUT: Write the answer here */ @@ -88132,11 +88132,11 @@ SQLITE_API int tdsqlite3_stmt_scanstatus( pScan = &p->aScan[idx]; switch( iScanStatusOp ){ case SQLITE_SCANSTAT_NLOOP: { - *(tdsqlite3_int64*)pOut = p->anExec[pScan->addrLoop]; + *(sqlite3_int64*)pOut = p->anExec[pScan->addrLoop]; break; } case SQLITE_SCANSTAT_NVISIT: { - *(tdsqlite3_int64*)pOut = p->anExec[pScan->addrVisit]; + *(sqlite3_int64*)pOut = p->anExec[pScan->addrVisit]; break; } case SQLITE_SCANSTAT_EST: { @@ -88146,7 +88146,7 @@ SQLITE_API int tdsqlite3_stmt_scanstatus( x += 10; r *= 0.5; } - *(double*)pOut = r*tdsqlite3LogEstToInt(x); + *(double*)pOut = r*sqlite3LogEstToInt(x); break; } case SQLITE_SCANSTAT_NAME: { @@ -88177,9 +88177,9 @@ SQLITE_API int tdsqlite3_stmt_scanstatus( } /* -** Zero all counters associated with the tdsqlite3_stmt_scanstatus() data. +** Zero all counters associated with the sqlite3_stmt_scanstatus() data. */ -SQLITE_API void tdsqlite3_stmt_scanstatus_reset(tdsqlite3_stmt *pStmt){ +SQLITE_API void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; memset(p->anExec, 0, p->nOp * sizeof(i64)); } @@ -88200,7 +88200,7 @@ SQLITE_API void tdsqlite3_stmt_scanstatus_reset(tdsqlite3_stmt *pStmt){ ************************************************************************* ** ** This file contains code used to insert the values of host parameters -** (aka "wildcards") into the SQL text output by tdsqlite3_trace(). +** (aka "wildcards") into the SQL text output by sqlite3_trace(). ** ** The Vdbe parse-tree explainer is also found here. */ @@ -88222,7 +88222,7 @@ static int findNextHostParameter(const char *zSql, int *pnToken){ *pnToken = 0; while( zSql[0] ){ - n = tdsqlite3GetToken((u8*)zSql, &tokenType); + n = sqlite3GetToken((u8*)zSql, &tokenType); assert( n>0 && tokenType!=TK_ILLEGAL ); if( tokenType==TK_VARIABLE ){ *pnToken = n; @@ -88236,7 +88236,7 @@ static int findNextHostParameter(const char *zSql, int *pnToken){ /* ** This function returns a pointer to a nul-terminated string in memory -** obtained from tdsqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the +** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the ** string contains a copy of zRawSql but with host parameters expanded to ** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1, ** then the returned string holds a copy of zRawSql with "-- " prepended @@ -88258,11 +88258,11 @@ static int findNextHostParameter(const char *zSql, int *pnToken){ ** parameter index is known, locate the value in p->aVar[]. Then render ** the value as a literal in place of the host parameter name. */ -SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql( +SQLITE_PRIVATE char *sqlite3VdbeExpandSql( Vdbe *p, /* The prepared statement being evaluated */ const char *zRawSql /* Raw text of the SQL statement */ ){ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ int idx = 0; /* Index of a host parameter */ int nextIndex = 1; /* Index of next ? host parameter */ int n; /* Length of a token prefix */ @@ -88276,30 +88276,30 @@ SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql( char zBase[100]; /* Initial working space */ db = p->db; - tdsqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), + sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), db->aLimit[SQLITE_LIMIT_LENGTH]); if( db->nVdbeExec>1 ){ while( *zRawSql ){ const char *zStart = zRawSql; while( *(zRawSql++)!='\n' && *zRawSql ); - tdsqlite3_str_append(&out, "-- ", 3); + sqlite3_str_append(&out, "-- ", 3); assert( (zRawSql - zStart) > 0 ); - tdsqlite3_str_append(&out, zStart, (int)(zRawSql-zStart)); + sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart)); } }else if( p->nVar==0 ){ - tdsqlite3_str_append(&out, zRawSql, tdsqlite3Strlen30(zRawSql)); + sqlite3_str_append(&out, zRawSql, sqlite3Strlen30(zRawSql)); }else{ while( zRawSql[0] ){ n = findNextHostParameter(zRawSql, &nToken); assert( n>0 ); - tdsqlite3_str_append(&out, zRawSql, n); + sqlite3_str_append(&out, zRawSql, n); zRawSql += n; assert( zRawSql[0] || nToken==0 ); if( nToken==0 ) break; if( zRawSql[0]=='?' ){ if( nToken>1 ){ - assert( tdsqlite3Isdigit(zRawSql[1]) ); - tdsqlite3GetInt32(&zRawSql[1], &idx); + assert( sqlite3Isdigit(zRawSql[1]) ); + sqlite3GetInt32(&zRawSql[1], &idx); }else{ idx = nextIndex; } @@ -88310,7 +88310,7 @@ SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql( testcase( zRawSql[0]=='$' ); testcase( zRawSql[0]=='@' ); testcase( zRawSql[0]=='#' ); - idx = tdsqlite3VdbeParameterIndex(p, zRawSql, nToken); + idx = sqlite3VdbeParameterIndex(p, zRawSql, nToken); assert( idx>0 ); } zRawSql += nToken; @@ -88318,11 +88318,11 @@ SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql( assert( idx>0 && idx<=p->nVar ); pVar = &p->aVar[idx-1]; if( pVar->flags & MEM_Null ){ - tdsqlite3_str_append(&out, "NULL", 4); + sqlite3_str_append(&out, "NULL", 4); }else if( pVar->flags & (MEM_Int|MEM_IntReal) ){ - tdsqlite3_str_appendf(&out, "%lld", pVar->u.i); + sqlite3_str_appendf(&out, "%lld", pVar->u.i); }else if( pVar->flags & MEM_Real ){ - tdsqlite3_str_appendf(&out, "%!.15g", pVar->u.r); + sqlite3_str_appendf(&out, "%!.15g", pVar->u.r); }else if( pVar->flags & MEM_Str ){ int nOut; /* Number of bytes of the string text to include in output */ #ifndef SQLITE_OMIT_UTF16 @@ -88330,8 +88330,8 @@ SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql( if( enc!=SQLITE_UTF8 ){ memset(&utf8, 0, sizeof(utf8)); utf8.db = db; - tdsqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); - if( SQLITE_NOMEM==tdsqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ + sqlite3VdbeMemSetStr(&utf8, pVar->z, pVar->n, enc, SQLITE_STATIC); + if( SQLITE_NOMEM==sqlite3VdbeChangeEncoding(&utf8, SQLITE_UTF8) ){ out.accError = SQLITE_NOMEM; out.nAlloc = 0; } @@ -88345,39 +88345,39 @@ SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql( while( nOutn && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; } } #endif - tdsqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z); + sqlite3_str_appendf(&out, "'%.*q'", nOut, pVar->z); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOutn ){ - tdsqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); + sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); } #endif #ifndef SQLITE_OMIT_UTF16 - if( enc!=SQLITE_UTF8 ) tdsqlite3VdbeMemRelease(&utf8); + if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8); #endif }else if( pVar->flags & MEM_Zero ){ - tdsqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero); + sqlite3_str_appendf(&out, "zeroblob(%d)", pVar->u.nZero); }else{ int nOut; /* Number of bytes of the blob to include in output */ assert( pVar->flags & MEM_Blob ); - tdsqlite3_str_append(&out, "x'", 2); + sqlite3_str_append(&out, "x'", 2); nOut = pVar->n; #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT; #endif for(i=0; iz[i]&0xff); + sqlite3_str_appendf(&out, "%02x", pVar->z[i]&0xff); } - tdsqlite3_str_append(&out, "'", 1); + sqlite3_str_append(&out, "'", 1); #ifdef SQLITE_TRACE_SIZE_LIMIT if( nOutn ){ - tdsqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); + sqlite3_str_appendf(&out, "/*+%d bytes*/", pVar->n-nOut); } #endif } } } - if( out.accError ) tdsqlite3_str_reset(&out); - return tdsqlite3StrAccumFinish(&out); + if( out.accError ) sqlite3_str_reset(&out); + return sqlite3StrAccumFinish(&out); } #endif /* #ifndef SQLITE_OMIT_TRACE */ @@ -88417,7 +88417,7 @@ SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql( ** like that ever happens. */ #ifdef SQLITE_DEBUG -# define memAboutToChange(P,M) tdsqlite3VdbeMemAboutToChange(P,M) +# define memAboutToChange(P,M) sqlite3VdbeMemAboutToChange(P,M) #else # define memAboutToChange(P,M) #endif @@ -88430,19 +88430,19 @@ SQLITE_PRIVATE char *tdsqlite3VdbeExpandSql( ** help verify the correct operation of the library. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_search_count = 0; +SQLITE_API int sqlite3_search_count = 0; #endif /* ** When this global variable is positive, it gets decremented once before ** each instruction in the VDBE. When it reaches zero, the u1.isInterrupted -** field of the tdsqlite3 structure is set in order to simulate an interrupt. +** field of the sqlite3 structure is set in order to simulate an interrupt. ** ** This facility is used for testing purposes only. It does not function ** in an ordinary build. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_interrupt_count = 0; +SQLITE_API int sqlite3_interrupt_count = 0; #endif /* @@ -88453,7 +88453,7 @@ SQLITE_API int tdsqlite3_interrupt_count = 0; ** library. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_sort_count = 0; +SQLITE_API int sqlite3_sort_count = 0; #endif /* @@ -88464,10 +88464,10 @@ SQLITE_API int tdsqlite3_sort_count = 0; ** help verify the correct operation of the library. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_max_blobsize = 0; +SQLITE_API int sqlite3_max_blobsize = 0; static void updateMaxBlobsize(Mem *p){ - if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>tdsqlite3_max_blobsize ){ - tdsqlite3_max_blobsize = p->n; + if( (p->flags & (MEM_Str|MEM_Blob))!=0 && p->n>sqlite3_max_blobsize ){ + sqlite3_max_blobsize = p->n; } } #endif @@ -88490,7 +88490,7 @@ static void updateMaxBlobsize(Mem *p){ ** library. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_found_count = 0; +SQLITE_API int sqlite3_found_count = 0; #endif /* @@ -88513,9 +88513,9 @@ SQLITE_API int tdsqlite3_found_count = 0; ** ** Other useful labels for breakpoints include: ** test_addop_breakpoint(pc,pOp) -** tdsqlite3CorruptError(lineno) -** tdsqlite3MisuseError(lineno) -** tdsqlite3CantopenError(lineno) +** sqlite3CorruptError(lineno) +** sqlite3MisuseError(lineno) +** sqlite3CantopenError(lineno) */ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ static int n = 0; @@ -88577,7 +88577,7 @@ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ ** away. */ mNever = iSrcLine >> 24; assert( (I & mNever)==0 ); - if( tdsqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ + if( sqlite3GlobalConfig.xVdbeBranch==0 ) return; /*NO_TEST*/ /* Invoke the branch coverage callback with three arguments: ** iSrcLine - the line number of the VdbeCoverage() macro, with ** flags removed. @@ -88596,7 +88596,7 @@ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ I |= 0x08; if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/ } - tdsqlite3GlobalConfig.xVdbeBranch(tdsqlite3GlobalConfig.pVdbeBranchArg, + sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg, iSrcLine&0xffffff, I, M); } #endif @@ -88614,7 +88614,7 @@ static void test_trace_breakpoint(int pc, Op *pOp, Vdbe *v){ */ #define Deephemeralize(P) \ if( ((P)->flags&MEM_Ephem)!=0 \ - && tdsqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} + && sqlite3VdbeMemMakeWriteable(P) ){ goto no_mem;} /* Return true if the cursor was opened using the OP_OpenSorter opcode. */ #define isSorter(x) ((x)->eCurType==CURTYPE_SORTER) @@ -88641,7 +88641,7 @@ static VdbeCursor *allocateCursor( ** allocations. ** ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can - ** be freed lazily via the tdsqlite3_release_memory() API. This + ** be freed lazily via the sqlite3_release_memory() API. This ** minimizes the number of malloc calls made by the system. ** ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from @@ -88654,19 +88654,19 @@ static VdbeCursor *allocateCursor( VdbeCursor *pCx = 0; nByte = ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + - (eCurType==CURTYPE_BTREE?tdsqlite3BtreeCursorSize():0); + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCur>=0 && iCurnCursor ); if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/ - /* Before calling tdsqlite3VdbeFreeCursor(), ensure the isEphemeral flag + /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag ** is clear. Otherwise, if this is an ephemeral cursor created by ** OP_OpenDup, the cursor will not be closed and will still be part ** of a BtShared.pCursor list. */ if( p->apCsr[iCur]->pBtx==0 ) p->apCsr[iCur]->isEphemeral = 0; - tdsqlite3VdbeFreeCursor(p, p->apCsr[iCur]); + sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); p->apCsr[iCur] = 0; } - if( SQLITE_OK==tdsqlite3VdbeMemClearAndResize(pMem, nByte) ){ + if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z; memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); pCx->eCurType = eCurType; @@ -88676,7 +88676,7 @@ static VdbeCursor *allocateCursor( if( eCurType==CURTYPE_BTREE ){ pCx->uc.pCursor = (BtCursor*) &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; - tdsqlite3BtreeCursorZero(pCx->uc.pCursor); + sqlite3BtreeCursorZero(pCx->uc.pCursor); } } return pCx; @@ -88690,11 +88690,11 @@ static VdbeCursor *allocateCursor( */ static int alsoAnInt(Mem *pRec, double rValue, i64 *piValue){ i64 iValue = (double)rValue; - if( tdsqlite3RealSameAsInt(rValue,iValue) ){ + if( sqlite3RealSameAsInt(rValue,iValue) ){ *piValue = iValue; return 1; } - return 0==tdsqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc); + return 0==sqlite3Atoi64(pRec->z, piValue, pRec->n, pRec->enc); } /* @@ -88717,14 +88717,14 @@ static void applyNumericAffinity(Mem *pRec, int bTryForInt){ u8 enc = pRec->enc; int rc; assert( (pRec->flags & (MEM_Str|MEM_Int|MEM_Real|MEM_IntReal))==MEM_Str ); - rc = tdsqlite3AtoF(pRec->z, &rValue, pRec->n, enc); + rc = sqlite3AtoF(pRec->z, &rValue, pRec->n, enc); if( rc<=0 ) return; if( rc==1 && alsoAnInt(pRec, rValue, &pRec->u.i) ){ pRec->flags |= MEM_Int; }else{ pRec->u.r = rValue; pRec->flags |= MEM_Real; - if( bTryForInt ) tdsqlite3VdbeIntegerAffinity(pRec); + if( bTryForInt ) sqlite3VdbeIntegerAffinity(pRec); } /* TEXT->NUMERIC is many->one. Hence, it is important to invalidate the ** string representation after computing a numeric equivalent, because the @@ -88764,7 +88764,7 @@ static void applyAffinity( if( (pRec->flags & MEM_Real)==0 ){ if( pRec->flags & MEM_Str ) applyNumericAffinity(pRec,1); }else{ - tdsqlite3VdbeIntegerAffinity(pRec); + sqlite3VdbeIntegerAffinity(pRec); } } }else if( affinity==SQLITE_AFF_TEXT ){ @@ -88778,7 +88778,7 @@ static void applyAffinity( testcase( pRec->flags & MEM_Int ); testcase( pRec->flags & MEM_Real ); testcase( pRec->flags & MEM_IntReal ); - tdsqlite3VdbeMemStringify(pRec, enc, 1); + sqlite3VdbeMemStringify(pRec, enc, 1); } } pRec->flags &= ~(MEM_Real|MEM_Int|MEM_IntReal); @@ -88791,22 +88791,22 @@ static void applyAffinity( ** is appropriate. But only do the conversion if it is possible without ** loss of information and return the revised type of the argument. */ -SQLITE_API int tdsqlite3_value_numeric_type(tdsqlite3_value *pVal){ - int eType = tdsqlite3_value_type(pVal); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value *pVal){ + int eType = sqlite3_value_type(pVal); if( eType==SQLITE_TEXT ){ Mem *pMem = (Mem*)pVal; applyNumericAffinity(pMem, 0); - eType = tdsqlite3_value_type(pVal); + eType = sqlite3_value_type(pVal); } return eType; } /* -** Exported version of applyAffinity(). This one works on tdsqlite3_value*, +** Exported version of applyAffinity(). This one works on sqlite3_value*, ** not the internal Mem* type. */ -SQLITE_PRIVATE void tdsqlite3ValueApplyAffinity( - tdsqlite3_value *pVal, +SQLITE_PRIVATE void sqlite3ValueApplyAffinity( + sqlite3_value *pVal, u8 affinity, u8 enc ){ @@ -88821,19 +88821,19 @@ SQLITE_PRIVATE void tdsqlite3ValueApplyAffinity( */ static u16 SQLITE_NOINLINE computeNumericType(Mem *pMem){ int rc; - tdsqlite3_int64 ix; + sqlite3_int64 ix; assert( (pMem->flags & (MEM_Int|MEM_Real|MEM_IntReal))==0 ); assert( (pMem->flags & (MEM_Str|MEM_Blob))!=0 ); ExpandBlob(pMem); - rc = tdsqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); + rc = sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc); if( rc<=0 ){ - if( rc==0 && tdsqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ + if( rc==0 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)<=1 ){ pMem->u.i = ix; return MEM_Int; }else{ return MEM_Real; } - }else if( rc==1 && tdsqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ + }else if( rc==1 && sqlite3Atoi64(pMem->z, &ix, pMem->n, pMem->enc)==0 ){ pMem->u.i = ix; return MEM_Int; } @@ -88867,7 +88867,7 @@ static u16 numericType(Mem *pMem){ ** Write a nice string representation of the contents of cell pMem ** into buffer zBuf, length nBuf. */ -SQLITE_PRIVATE void tdsqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ +SQLITE_PRIVATE void sqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ int f = pMem->flags; static const char *const encnames[] = {"(X)", "(8)", "(16LE)", "(16BE)"}; if( f&MEM_Blob ){ @@ -88885,18 +88885,18 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ }else{ c = 's'; } - tdsqlite3_str_appendf(pStr, "%cx[", c); + sqlite3_str_appendf(pStr, "%cx[", c); for(i=0; i<25 && in; i++){ - tdsqlite3_str_appendf(pStr, "%02X", ((int)pMem->z[i] & 0xFF)); + sqlite3_str_appendf(pStr, "%02X", ((int)pMem->z[i] & 0xFF)); } - tdsqlite3_str_appendf(pStr, "|"); + sqlite3_str_appendf(pStr, "|"); for(i=0; i<25 && in; i++){ char z = pMem->z[i]; - tdsqlite3_str_appendchar(pStr, 1, (z<32||z>126)?'.':z); + sqlite3_str_appendchar(pStr, 1, (z<32||z>126)?'.':z); } - tdsqlite3_str_appendf(pStr,"]"); + sqlite3_str_appendf(pStr,"]"); if( f & MEM_Zero ){ - tdsqlite3_str_appendf(pStr, "+%dz",pMem->u.nZero); + sqlite3_str_appendf(pStr, "+%dz",pMem->u.nZero); } }else if( f & MEM_Str ){ int j; @@ -88913,12 +88913,12 @@ SQLITE_PRIVATE void tdsqlite3VdbeMemPrettyPrint(Mem *pMem, StrAccum *pStr){ }else{ c = 's'; } - tdsqlite3_str_appendf(pStr, " %c%d[", c, pMem->n); + sqlite3_str_appendf(pStr, " %c%d[", c, pMem->n); for(j=0; j<25 && jn; j++){ c = pMem->z[j]; - tdsqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); + sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); } - tdsqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); + sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); } } #endif @@ -88942,14 +88942,14 @@ static void memTracePrint(Mem *p){ }else if( p->flags & MEM_Real ){ printf(" r:%.17g", p->u.r); #endif - }else if( tdsqlite3VdbeMemIsRowSet(p) ){ + }else if( sqlite3VdbeMemIsRowSet(p) ){ printf(" (rowset)"); }else{ StrAccum acc; char zBuf[1000]; - tdsqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - tdsqlite3VdbeMemPrettyPrint(p, &acc); - printf(" %s", tdsqlite3StrAccumFinish(&acc)); + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3VdbeMemPrettyPrint(p, &acc); + printf(" %s", sqlite3StrAccumFinish(&acc)); } if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype); } @@ -88960,7 +88960,7 @@ static void registerTrace(int iReg, Mem *p){ printf(" <== R[%d]", (int)(p->pScopyFrom - &p[-iReg])); } printf("\n"); - tdsqlite3VdbeCheckMemInvariants(p); + sqlite3VdbeCheckMemInvariants(p); } #endif @@ -88969,7 +88969,7 @@ static void registerTrace(int iReg, Mem *p){ ** Show the values of all registers in the virtual machine. Used for ** interactive debugging. */ -SQLITE_PRIVATE void tdsqlite3VdbeRegisterDump(Vdbe *v){ +SQLITE_PRIVATE void sqlite3VdbeRegisterDump(Vdbe *v){ int i; for(i=1; inMem; i++) registerTrace(i, v->aMem+i); } @@ -89021,7 +89021,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeRegisterDump(Vdbe *v){ #if defined(__GNUC__) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned int lo, hi; __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi)); return (sqlite_uint64)hi << 32 | lo; @@ -89029,7 +89029,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeRegisterDump(Vdbe *v){ #elif defined(_MSC_VER) - __declspec(naked) __inline sqlite_uint64 __cdecl tdsqlite3Hwtime(void){ + __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){ __asm { rdtsc ret ; return value at EDX:EAX @@ -89040,7 +89040,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeRegisterDump(Vdbe *v){ #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__)) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long val; __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; @@ -89048,7 +89048,7 @@ SQLITE_PRIVATE void tdsqlite3VdbeRegisterDump(Vdbe *v){ #elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__)) - __inline__ sqlite_uint64 tdsqlite3Hwtime(void){ + __inline__ sqlite_uint64 sqlite3Hwtime(void){ unsigned long long retval; unsigned long junk; __asm__ __volatile__ ("\n\ @@ -89065,13 +89065,13 @@ SQLITE_PRIVATE void tdsqlite3VdbeRegisterDump(Vdbe *v){ /* ** asm() is needed for hardware timing support. Without asm(), - ** disable the tdsqlite3Hwtime() routine. + ** disable the sqlite3Hwtime() routine. ** - ** tdsqlite3Hwtime() is only used for some obscure debugging + ** sqlite3Hwtime() is only used for some obscure debugging ** and analysis configurations, not in any deliverable, so this ** should not be a great loss. */ -SQLITE_PRIVATE sqlite_uint64 tdsqlite3Hwtime(void){ return ((sqlite_uint64)0); } +SQLITE_PRIVATE sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); } #endif @@ -89093,7 +89093,7 @@ SQLITE_PRIVATE sqlite_uint64 tdsqlite3Hwtime(void){ return ((sqlite_uint64)0); ** ** assert( checkSavepointCount(db) ); */ -static int checkSavepointCount(tdsqlite3 *db){ +static int checkSavepointCount(sqlite3 *db){ int n = 0; Savepoint *p; for(p=db->pSavepoint; p; p=p->pNext) n++; @@ -89107,7 +89107,7 @@ static int checkSavepointCount(tdsqlite3 *db){ ** overwritten with an integer value. */ static SQLITE_NOINLINE Mem *out2PrereleaseWithClear(Mem *pOut){ - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); pOut->flags = MEM_Int; return pOut; } @@ -89128,9 +89128,9 @@ static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ /* ** Execute as much of a VDBE program as we can. -** This is the core of tdsqlite3_step(). +** This is the core of sqlite3_step(). */ -SQLITE_PRIVATE int tdsqlite3VdbeExec( +SQLITE_PRIVATE int sqlite3VdbeExec( Vdbe *p /* The VDBE */ ){ Op *aOp = p->aOp; /* Copy of p->aOp */ @@ -89142,7 +89142,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( int nExtraDelete = 0; /* Verifies FORDELETE and AUXDELETE flags */ #endif int rc = SQLITE_OK; /* Value to return */ - tdsqlite3 *db = p->db; /* The database */ + sqlite3 *db = p->db; /* The database */ u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */ u8 encoding = ENC(db); /* The database encoding */ int iCompare = 0; /* Result of last comparison */ @@ -89160,8 +89160,8 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( #endif /*** INSERT STACK UNION HERE ***/ - assert( p->magic==VDBE_MAGIC_RUN ); /* tdsqlite3_step() verifies this */ - tdsqlite3VdbeEnter(p); + assert( p->magic==VDBE_MAGIC_RUN ); /* sqlite3_step() verifies this */ + sqlite3VdbeEnter(p); #ifndef SQLITE_OMIT_PROGRESS_CALLBACK if( db->xProgress ){ u32 iPrior = p->aCounter[SQLITE_STMTSTATUS_VM_STEP]; @@ -89172,8 +89172,8 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( } #endif if( p->rc==SQLITE_NOMEM ){ - /* This happens if a malloc() inside a call to tdsqlite3_column_text() or - ** tdsqlite3_column_text16() failed. */ + /* This happens if a malloc() inside a call to sqlite3_column_text() or + ** sqlite3_column_text16() failed. */ goto no_mem; } assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY ); @@ -89183,19 +89183,19 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( p->pResultSet = 0; db->busyHandler.nBusy = 0; if( db->u1.isInterrupted ) goto abort_due_to_interrupt; - tdsqlite3VdbeIOTraceSql(p); + sqlite3VdbeIOTraceSql(p); #ifdef SQLITE_DEBUG - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); if( p->pc==0 && (p->db->flags & (SQLITE_VdbeListing|SQLITE_VdbeEQP|SQLITE_VdbeTrace))!=0 ){ int i; int once = 1; - tdsqlite3VdbePrintSql(p); + sqlite3VdbePrintSql(p); if( p->db->flags & SQLITE_VdbeListing ){ printf("VDBE Program Listing:\n"); for(i=0; inOp; i++){ - tdsqlite3VdbePrintOp(stdout, i, &aOp[i]); + sqlite3VdbePrintOp(stdout, i, &aOp[i]); } } if( p->db->flags & SQLITE_VdbeEQP ){ @@ -89209,7 +89209,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( } if( p->db->flags & SQLITE_VdbeTrace ) printf("VDBE Trace:\n"); } - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); #endif for(pOp=&aOp[p->pc]; 1; pOp++){ /* Errors are detected by individual opcodes, with an immediate @@ -89218,7 +89218,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( assert( pOp>=aOp && pOp<&aOp[p->nOp]); #ifdef VDBE_PROFILE - start = tdsqlite3NProfileCnt ? tdsqlite3NProfileCnt : tdsqlite3Hwtime(); + start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); #endif nVmStep++; #ifdef SQLITE_ENABLE_STMT_SCANSTATUS @@ -89229,7 +89229,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( */ #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeTrace ){ - tdsqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp); + sqlite3VdbePrintOp(stdout, (int)(pOp - aOp), pOp); test_trace_breakpoint((int)(pOp - aOp),pOp,p); } #endif @@ -89239,10 +89239,10 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( ** if we have a special test build. */ #ifdef SQLITE_TEST - if( tdsqlite3_interrupt_count>0 ){ - tdsqlite3_interrupt_count--; - if( tdsqlite3_interrupt_count==0 ){ - tdsqlite3_interrupt(db); + if( sqlite3_interrupt_count>0 ){ + sqlite3_interrupt_count--; + if( sqlite3_interrupt_count==0 ){ + sqlite3_interrupt(db); } } #endif @@ -89250,26 +89250,26 @@ SQLITE_PRIVATE int tdsqlite3VdbeExec( /* Sanity checking on other operands */ #ifdef SQLITE_DEBUG { - u8 opProperty = tdsqlite3OpcodeProperty[pOp->opcode]; + u8 opProperty = sqlite3OpcodeProperty[pOp->opcode]; if( (opProperty & OPFLG_IN1)!=0 ){ assert( pOp->p1>0 ); assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); assert( memIsValid(&aMem[pOp->p1]) ); - assert( tdsqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); } if( (opProperty & OPFLG_IN2)!=0 ){ assert( pOp->p2>0 ); assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); assert( memIsValid(&aMem[pOp->p2]) ); - assert( tdsqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); } if( (opProperty & OPFLG_IN3)!=0 ){ assert( pOp->p3>0 ); assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( memIsValid(&aMem[pOp->p3]) ); - assert( tdsqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); + assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); } if( (opProperty & OPFLG_OUT2)!=0 ){ @@ -89357,20 +89357,20 @@ jump_to_p2_and_check_for_interrupt: /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, ** OP_VNext, or OP_SorterNext) all jump here upon - ** completion. Check to see if tdsqlite3_interrupt() has been called + ** completion. Check to see if sqlite3_interrupt() has been called ** or if the progress callback needs to be invoked. ** ** This code uses unstructured "goto" statements and does not look clean. ** But that is not due to sloppy coding habits. The code is written this ** way for performance, to avoid having to run the interrupt and progress - ** checks on every opcode. This helps tdsqlite3_step() to run about 1.5% + ** checks on every opcode. This helps sqlite3_step() to run about 1.5% ** faster according to "valgrind --tool=cachegrind" */ check_for_interrupt: if( db->u1.isInterrupted ) goto abort_due_to_interrupt; #ifndef SQLITE_OMIT_PROGRESS_CALLBACK /* Call the progress callback if it is configured and the required number ** of VDBE ops have been executed (either since this invocation of - ** tdsqlite3VdbeExec() or since last time the progress callback was called). + ** sqlite3VdbeExec() or since last time the progress callback was called). ** If the progress callback returns non-zero, exit the virtual machine with ** a return code SQLITE_ABORT. */ @@ -89502,7 +89502,7 @@ case OP_Yield: { /* in1, jump */ case OP_HaltIfNull: { /* in3 */ pIn3 = &aMem[pOp->p3]; #ifdef SQLITE_DEBUG - if( pOp->p2==OE_Abort ){ tdsqlite3VdbeAssertAbortable(p); } + if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif if( (pIn3->flags & MEM_Null)==0 ) break; /* Fall through into OP_Halt */ @@ -89513,8 +89513,8 @@ case OP_HaltIfNull: { /* in3 */ ** Exit immediately. All open cursors, etc are closed ** automatically. ** -** P1 is the result code returned by tdsqlite3_exec(), tdsqlite3_reset(), -** or tdsqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0). +** P1 is the result code returned by sqlite3_exec(), sqlite3_reset(), +** or sqlite3_finalize(). For a normal halt, this should be SQLITE_OK (0). ** For errors, it can be some other value. If P1!=0 then P2 will determine ** whether or not to rollback the current transaction. Do not rollback ** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort, @@ -89544,15 +89544,15 @@ case OP_Halt: { pcx = (int)(pOp - aOp); #ifdef SQLITE_DEBUG - if( pOp->p2==OE_Abort ){ tdsqlite3VdbeAssertAbortable(p); } + if( pOp->p2==OE_Abort ){ sqlite3VdbeAssertAbortable(p); } #endif if( pOp->p1==SQLITE_OK && p->pFrame ){ /* Halt the sub-program. Return control to the parent frame. */ pFrame = p->pFrame; p->pFrame = pFrame->pParent; p->nFrame--; - tdsqlite3VdbeSetChanges(db, p->nChange); - pcx = tdsqlite3VdbeFrameRestore(pFrame); + sqlite3VdbeSetChanges(db, p->nChange); + pcx = sqlite3VdbeFrameRestore(pFrame); if( pOp->p2==OE_Ignore ){ /* Instruction pcx is the OP_Program that invoked the sub-program ** currently being halted. If the p2 instruction of this OP_Halt @@ -89578,16 +89578,16 @@ case OP_Halt: { testcase( pOp->p5==2 ); testcase( pOp->p5==3 ); testcase( pOp->p5==4 ); - tdsqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]); + sqlite3VdbeError(p, "%s constraint failed", azType[pOp->p5-1]); if( pOp->p4.z ){ - p->zErrMsg = tdsqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); + p->zErrMsg = sqlite3MPrintf(db, "%z: %s", p->zErrMsg, pOp->p4.z); } }else{ - tdsqlite3VdbeError(p, "%s", pOp->p4.z); + sqlite3VdbeError(p, "%s", pOp->p4.z); } - tdsqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); + sqlite3_log(pOp->p1, "abort at %d in [%s]: %s", pcx, p->zSql, p->zErrMsg); } - rc = tdsqlite3VdbeHalt(p); + rc = sqlite3VdbeHalt(p); assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); if( rc==SQLITE_BUSY ){ p->rc = SQLITE_BUSY; @@ -89633,7 +89633,7 @@ case OP_Int64: { /* out2 */ case OP_Real: { /* same as TK_FLOAT, out2 */ pOut = out2Prerelease(p, pOp); pOut->flags = MEM_Real; - assert( !tdsqlite3IsNaN(*pOp->p4.pReal) ); + assert( !sqlite3IsNaN(*pOp->p4.pReal) ); pOut->u.r = *pOp->p4.pReal; break; } @@ -89650,20 +89650,20 @@ case OP_Real: { /* same as TK_FLOAT, out2 */ case OP_String8: { /* same as TK_STRING, out2 */ assert( pOp->p4.z!=0 ); pOut = out2Prerelease(p, pOp); - pOp->p1 = tdsqlite3Strlen30(pOp->p4.z); + pOp->p1 = sqlite3Strlen30(pOp->p4.z); #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ - rc = tdsqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); assert( rc==SQLITE_OK || rc==SQLITE_TOOBIG ); if( rc ) goto too_big; - if( SQLITE_OK!=tdsqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; + if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; assert( pOut->szMalloc>0 && pOut->zMalloc==pOut->z ); assert( VdbeMemDynamic(pOut)==0 ); pOut->szMalloc = 0; pOut->flags |= MEM_Static; if( pOp->p4type==P4_DYNAMIC ){ - tdsqlite3DbFree(db, pOp->p4.z); + sqlite3DbFree(db, pOp->p4.z); } pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; @@ -89735,7 +89735,7 @@ case OP_Null: { /* out2 */ while( cnt>0 ){ pOut++; memAboutToChange(p, pOut); - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); pOut->flags = nullFlag; pOut->n = 0; cnt--; @@ -89767,7 +89767,7 @@ case OP_SoftNull: { case OP_Blob: { /* out2 */ assert( pOp->p1 <= SQLITE_MAX_LENGTH ); pOut = out2Prerelease(p, pOp); - tdsqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); + sqlite3VdbeMemSetStr(pOut, pOp->p4.z, pOp->p1, 0, 0); pOut->enc = encoding; UPDATE_MAX_BLOBSIZE(pOut); break; @@ -89779,19 +89779,19 @@ case OP_Blob: { /* out2 */ ** Transfer the values of bound parameter P1 into register P2 ** ** If the parameter is named, then its name appears in P4. -** The P4 value is used by tdsqlite3_bind_parameter_name(). +** The P4 value is used by sqlite3_bind_parameter_name(). */ case OP_Variable: { /* out2 */ Mem *pVar; /* Value being transferred */ assert( pOp->p1>0 && pOp->p1<=p->nVar ); - assert( pOp->p4.z==0 || pOp->p4.z==tdsqlite3VListNumToName(p->pVList,pOp->p1) ); + assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) ); pVar = &p->aVar[pOp->p1 - 1]; - if( tdsqlite3VdbeMemTooBig(pVar) ){ + if( sqlite3VdbeMemTooBig(pVar) ){ goto too_big; } pOut = &aMem[pOp->p2]; - if( VdbeMemDynamic(pOut) ) tdsqlite3VdbeMemSetNull(pOut); + if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut); memcpy(pOut, pVar, MEMCELLSIZE); pOut->flags &= ~(MEM_Dyn|MEM_Ephem); pOut->flags |= MEM_Static|MEM_FromBind; @@ -89826,7 +89826,7 @@ case OP_Move: { assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] ); assert( memIsValid(pIn1) ); memAboutToChange(p, pOut); - tdsqlite3VdbeMemMove(pOut, pIn1); + sqlite3VdbeMemMove(pOut, pIn1); #ifdef SQLITE_DEBUG pIn1->pScopyFrom = 0; { int i; @@ -89862,7 +89862,7 @@ case OP_Copy: { assert( pOut!=pIn1 ); while( 1 ){ memAboutToChange(p, pOut); - tdsqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); Deephemeralize(pOut); #ifdef SQLITE_DEBUG pOut->pScopyFrom = 0; @@ -89892,7 +89892,7 @@ case OP_SCopy: { /* out2 */ pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; assert( pOut!=pIn1 ); - tdsqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); + sqlite3VdbeMemShallowCopy(pOut, pIn1, MEM_Ephem); #ifdef SQLITE_DEBUG pOut->pScopyFrom = pIn1; pOut->mScopyFlags = pIn1->flags; @@ -89912,7 +89912,7 @@ case OP_IntCopy: { /* out2 */ pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Int)!=0 ); pOut = &aMem[pOp->p2]; - tdsqlite3VdbeMemSetInt64(pOut, pIn1->u.i); + sqlite3VdbeMemSetInt64(pOut, pIn1->u.i); break; } @@ -89920,8 +89920,8 @@ case OP_IntCopy: { /* out2 */ ** Synopsis: output=r[P1@P2] ** ** The registers P1 through P1+P2-1 contain a single row of -** results. This opcode causes the tdsqlite3_step() call to terminate -** with an SQLITE_ROW return code and it sets up the tdsqlite3_stmt +** results. This opcode causes the sqlite3_step() call to terminate +** with an SQLITE_ROW return code and it sets up the sqlite3_stmt ** structure to provide access to the r(P1)..r(P1+P2-1) values as ** the result row. */ @@ -89935,7 +89935,7 @@ case OP_ResultRow: { /* If this statement has violated immediate foreign key constraints, do ** not return the number of rows modified. And do not RELEASE the statement ** transaction. It needs to be rolled back. */ - if( SQLITE_OK!=(rc = tdsqlite3VdbeCheckFk(p, 0)) ){ + if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ assert( db->flags&SQLITE_CountRows ); assert( p->usesStmtJournal ); goto abort_due_to_error; @@ -89957,7 +89957,7 @@ case OP_ResultRow: { ** the RELEASE call below can never fail. */ assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); - rc = tdsqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); + rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); assert( rc==SQLITE_OK ); /* Invalidate all ephemeral cursor row caches */ @@ -89973,11 +89973,11 @@ case OP_ResultRow: { Deephemeralize(&pMem[i]); assert( (pMem[i].flags & MEM_Ephem)==0 || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 ); - tdsqlite3VdbeMemNulTerminate(&pMem[i]); + sqlite3VdbeMemNulTerminate(&pMem[i]); REGISTER_TRACE(pOp->p1+i, &pMem[i]); #ifdef SQLITE_DEBUG /* The registers in the result will not be used again when the - ** prepared statement restarts. This is because tdsqlite3_column() + ** prepared statement restarts. This is because sqlite3_column() ** APIs might have caused type conversions of made other changes to ** the register values. Therefore, we can go ahead and break any ** OP_SCopy dependencies. */ @@ -90026,29 +90026,29 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ testcase( flags1 & MEM_Null ); testcase( pIn2->flags & MEM_Null ); if( (flags1 | pIn2->flags) & MEM_Null ){ - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); break; } if( (flags1 & (MEM_Str|MEM_Blob))==0 ){ - if( tdsqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem; + if( sqlite3VdbeMemStringify(pIn1,encoding,0) ) goto no_mem; flags1 = pIn1->flags & ~MEM_Str; }else if( (flags1 & MEM_Zero)!=0 ){ - if( tdsqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem; + if( sqlite3VdbeMemExpandBlob(pIn1) ) goto no_mem; flags1 = pIn1->flags & ~MEM_Str; } flags2 = pIn2->flags; if( (flags2 & (MEM_Str|MEM_Blob))==0 ){ - if( tdsqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem; + if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem; flags2 = pIn2->flags & ~MEM_Str; }else if( (flags2 & MEM_Zero)!=0 ){ - if( tdsqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem; + if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem; flags2 = pIn2->flags & ~MEM_Str; } nByte = pIn1->n + pIn2->n; if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - if( tdsqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){ + if( sqlite3VdbeMemGrow(pOut, (int)nByte+3, pOut==pIn2) ){ goto no_mem; } MemSetTypeFlag(pOut, MEM_Str); @@ -90131,9 +90131,9 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ iA = pIn1->u.i; iB = pIn2->u.i; switch( pOp->opcode ){ - case OP_Add: if( tdsqlite3AddInt64(&iB,iA) ) goto fp_math; break; - case OP_Subtract: if( tdsqlite3SubInt64(&iB,iA) ) goto fp_math; break; - case OP_Multiply: if( tdsqlite3MulInt64(&iB,iA) ) goto fp_math; break; + case OP_Add: if( sqlite3AddInt64(&iB,iA) ) goto fp_math; break; + case OP_Subtract: if( sqlite3SubInt64(&iB,iA) ) goto fp_math; break; + case OP_Multiply: if( sqlite3MulInt64(&iB,iA) ) goto fp_math; break; case OP_Divide: { if( iA==0 ) goto arithmetic_result_is_null; if( iA==-1 && iB==SMALLEST_INT64 ) goto fp_math; @@ -90153,8 +90153,8 @@ case OP_Remainder: { /* same as TK_REM, in1, in2, out3 */ goto arithmetic_result_is_null; }else{ fp_math: - rA = tdsqlite3VdbeRealValue(pIn1); - rB = tdsqlite3VdbeRealValue(pIn2); + rA = sqlite3VdbeRealValue(pIn1); + rB = sqlite3VdbeRealValue(pIn2); switch( pOp->opcode ){ case OP_Add: rB += rA; break; case OP_Subtract: rB -= rA; break; @@ -90166,8 +90166,8 @@ fp_math: break; } default: { - iA = tdsqlite3VdbeIntValue(pIn1); - iB = tdsqlite3VdbeIntValue(pIn2); + iA = sqlite3VdbeIntValue(pIn1); + iB = sqlite3VdbeIntValue(pIn2); if( iA==0 ) goto arithmetic_result_is_null; if( iA==-1 ) iA = 1; rB = (double)(iB % iA); @@ -90178,7 +90178,7 @@ fp_math: pOut->u.i = rB; MemSetTypeFlag(pOut, MEM_Int); #else - if( tdsqlite3IsNaN(rB) ){ + if( sqlite3IsNaN(rB) ){ goto arithmetic_result_is_null; } pOut->u.r = rB; @@ -90188,14 +90188,14 @@ fp_math: break; arithmetic_result_is_null: - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); break; } /* Opcode: CollSeq P1 * * P4 ** ** P4 is a pointer to a CollSeq object. If the next call to a user function -** or aggregate calls tdsqlite3GetFuncCollSeq(), this collation sequence will +** or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will ** be returned. This is used by the built-in min(), max() and nullif() ** functions. ** @@ -90210,7 +90210,7 @@ arithmetic_result_is_null: case OP_CollSeq: { assert( pOp->p4type==P4_COLLSEQ ); if( pOp->p1 ){ - tdsqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0); + sqlite3VdbeMemSetInt64(&aMem[pOp->p1], 0); } break; } @@ -90258,11 +90258,11 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ pIn2 = &aMem[pOp->p2]; pOut = &aMem[pOp->p3]; if( (pIn1->flags | pIn2->flags) & MEM_Null ){ - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); break; } - iA = tdsqlite3VdbeIntValue(pIn2); - iB = tdsqlite3VdbeIntValue(pIn1); + iA = sqlite3VdbeIntValue(pIn2); + iB = sqlite3VdbeIntValue(pIn1); op = pOp->opcode; if( op==OP_BitAnd ){ iA &= iB; @@ -90308,7 +90308,7 @@ case OP_ShiftRight: { /* same as TK_RSHIFT, in1, in2, out3 */ case OP_AddImm: { /* in1 */ pIn1 = &aMem[pOp->p1]; memAboutToChange(p, pIn1); - tdsqlite3VdbeMemIntegerify(pIn1); + sqlite3VdbeMemIntegerify(pIn1); pIn1->u.i += pOp->p2; break; } @@ -90354,7 +90354,7 @@ case OP_RealAffinity: { /* in1 */ if( pIn1->flags & (MEM_Int|MEM_IntReal) ){ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_IntReal ); - tdsqlite3VdbeMemRealify(pIn1); + sqlite3VdbeMemRealify(pIn1); REGISTER_TRACE(pOp->p1, pIn1); } break; @@ -90388,7 +90388,7 @@ case OP_Cast: { /* in1 */ memAboutToChange(p, pIn1); rc = ExpandBlob(pIn1); if( rc ) goto abort_due_to_error; - rc = tdsqlite3VdbeMemCast(pIn1, pOp->p2, encoding); + rc = sqlite3VdbeMemCast(pIn1, pOp->p2, encoding); if( rc ) goto abort_due_to_error; UPDATE_MAX_BLOBSIZE(pIn1); REGISTER_TRACE(pOp->p1, pIn1); @@ -90558,7 +90558,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ } } /* Handle the common case of integer comparison here, as an - ** optimization, to avoid a call to tdsqlite3MemCompare() */ + ** optimization, to avoid a call to sqlite3MemCompare() */ if( (pIn1->flags & pIn3->flags & MEM_Int)!=0 ){ if( pIn3->u.i > pIn1->u.i ){ res = +1; goto compare_op; } if( pIn3->u.i < pIn1->u.i ){ res = -1; goto compare_op; } @@ -90570,7 +90570,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_Real ); testcase( pIn1->flags & MEM_IntReal ); - tdsqlite3VdbeMemStringify(pIn1, encoding, 1); + sqlite3VdbeMemStringify(pIn1, encoding, 1); testcase( (flags1&MEM_Dyn) != (pIn1->flags&MEM_Dyn) ); flags1 = (pIn1->flags & ~MEM_TypeMask) | (flags1 & MEM_TypeMask); if( pIn1==pIn3 ) flags3 = flags1 | MEM_Str; @@ -90579,13 +90579,13 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ testcase( pIn3->flags & MEM_Int ); testcase( pIn3->flags & MEM_Real ); testcase( pIn3->flags & MEM_IntReal ); - tdsqlite3VdbeMemStringify(pIn3, encoding, 1); + sqlite3VdbeMemStringify(pIn3, encoding, 1); testcase( (flags3&MEM_Dyn) != (pIn3->flags&MEM_Dyn) ); flags3 = (pIn3->flags & ~MEM_TypeMask) | (flags3 & MEM_TypeMask); } } assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); - res = tdsqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); + res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } compare_op: /* At this point, res is negative, zero, or positive if reg[P1] is @@ -90764,7 +90764,7 @@ case OP_Compare: { assert( inKeyField ); pColl = pKeyInfo->aColl[i]; bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); - iCompare = tdsqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); + iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); if( iCompare ){ if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) @@ -90820,8 +90820,8 @@ case OP_Or: { /* same as TK_OR, in1, in2, out3 */ int v1; /* Left operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ int v2; /* Right operand: 0==FALSE, 1==TRUE, 2==UNKNOWN or NULL */ - v1 = tdsqlite3VdbeBooleanValue(&aMem[pOp->p1], 2); - v2 = tdsqlite3VdbeBooleanValue(&aMem[pOp->p2], 2); + v1 = sqlite3VdbeBooleanValue(&aMem[pOp->p1], 2); + v2 = sqlite3VdbeBooleanValue(&aMem[pOp->p2], 2); if( pOp->opcode==OP_And ){ static const unsigned char and_logic[] = { 0, 0, 0, 0, 1, 2, 0, 2, 2 }; v1 = and_logic[v1*3+v2]; @@ -90863,8 +90863,8 @@ case OP_IsTrue: { /* in1, out2 */ assert( pOp->p4type==P4_INT32 ); assert( pOp->p4.i==0 || pOp->p4.i==1 ); assert( pOp->p3==0 || pOp->p3==1 ); - tdsqlite3VdbeMemSetInt64(&aMem[pOp->p2], - tdsqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i); + sqlite3VdbeMemSetInt64(&aMem[pOp->p2], + sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3) ^ pOp->p4.i); break; } @@ -90879,9 +90879,9 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */ pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; if( (pIn1->flags & MEM_Null)==0 ){ - tdsqlite3VdbeMemSetInt64(pOut, !tdsqlite3VdbeBooleanValue(pIn1,0)); + sqlite3VdbeMemSetInt64(pOut, !sqlite3VdbeBooleanValue(pIn1,0)); }else{ - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); } break; } @@ -90896,10 +90896,10 @@ case OP_Not: { /* same as TK_NOT, in1, out2 */ case OP_BitNot: { /* same as TK_BITNOT, in1, out2 */ pIn1 = &aMem[pOp->p1]; pOut = &aMem[pOp->p2]; - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); if( (pIn1->flags & MEM_Null)==0 ){ pOut->flags = MEM_Int; - pOut->u.i = ~tdsqlite3VdbeIntValue(pIn1); + pOut->u.i = ~sqlite3VdbeIntValue(pIn1); } break; } @@ -90950,7 +90950,7 @@ case OP_Once: { /* jump */ */ case OP_If: { /* jump, in1 */ int c; - c = tdsqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3); + c = sqlite3VdbeBooleanValue(&aMem[pOp->p1], pOp->p3); VdbeBranchTaken(c!=0, 2); if( c ) goto jump_to_p2; break; @@ -90964,7 +90964,7 @@ case OP_If: { /* jump, in1 */ */ case OP_IfNot: { /* jump, in1 */ int c; - c = !tdsqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3); + c = !sqlite3VdbeBooleanValue(&aMem[pOp->p1], !pOp->p3); VdbeBranchTaken(c!=0, 2); if( c ) goto jump_to_p2; break; @@ -91010,7 +91010,7 @@ case OP_IfNullRow: { /* jump */ assert( pOp->p1>=0 && pOp->p1nCursor ); assert( p->apCsr[pOp->p1]!=0 ); if( p->apCsr[pOp->p1]->nullRow ){ - tdsqlite3VdbeMemSetNull(aMem + pOp->p3); + sqlite3VdbeMemSetNull(aMem + pOp->p3); goto jump_to_p2; } break; @@ -91038,9 +91038,9 @@ case OP_Offset: { /* out3 */ pC = p->apCsr[pOp->p1]; pOut = &p->aMem[pOp->p3]; if( NEVER(pC==0) || pC->eCurType!=CURTYPE_BTREE ){ - tdsqlite3VdbeMemSetNull(pOut); + sqlite3VdbeMemSetNull(pOut); }else{ - tdsqlite3VdbeMemSetInt64(pOut, tdsqlite3BtreeOffset(pC->uc.pCursor)); + sqlite3VdbeMemSetInt64(pOut, sqlite3BtreeOffset(pC->uc.pCursor)); } break; } @@ -91090,7 +91090,7 @@ case OP_Column: { /* If the cursor cache is stale (meaning it is not currently point at ** the correct row) then bring it up-to-date by doing the necessary ** B-Tree seek. */ - rc = tdsqlite3VdbeCursorMoveto(&pC, &p2); + rc = sqlite3VdbeCursorMoveto(&pC, &p2); if( rc ) goto abort_due_to_error; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); @@ -91115,16 +91115,16 @@ case OP_Column: { pC->payloadSize = pC->szRow = pReg->n; pC->aRow = (u8*)pReg->z; }else{ - tdsqlite3VdbeMemSetNull(pDest); + sqlite3VdbeMemSetNull(pDest); goto op_column_out; } }else{ pCrsr = pC->uc.pCursor; assert( pC->eCurType==CURTYPE_BTREE ); assert( pCrsr ); - assert( tdsqlite3BtreeCursorIsValid(pCrsr) ); - pC->payloadSize = tdsqlite3BtreePayloadSize(pCrsr); - pC->aRow = tdsqlite3BtreePayloadFetch(pCrsr, &pC->szRow); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); + pC->payloadSize = sqlite3BtreePayloadSize(pCrsr); + pC->aRow = sqlite3BtreePayloadFetch(pCrsr, &pC->szRow); assert( pC->szRow<=pC->payloadSize ); assert( pC->szRow<=65536 ); /* Maximum page size is 64KiB */ if( pC->payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ @@ -91188,7 +91188,7 @@ case OP_Column: { /* Make sure zData points to enough of the record to cover the header. */ if( pC->aRow==0 ){ memset(&sMem, 0, sizeof(sMem)); - rc = tdsqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem); + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, 0, aOffset[0], &sMem); if( rc!=SQLITE_OK ) goto abort_due_to_error; zData = (u8*)sMem.z; }else{ @@ -91205,11 +91205,11 @@ case OP_Column: { do{ if( (pC->aType[i] = t = zHdr[0])<0x80 ){ zHdr++; - offset64 += tdsqlite3VdbeOneByteSerialTypeLen(t); + offset64 += sqlite3VdbeOneByteSerialTypeLen(t); }else{ - zHdr += tdsqlite3GetVarint32(zHdr, &t); + zHdr += sqlite3GetVarint32(zHdr, &t); pC->aType[i] = t; - offset64 += tdsqlite3VdbeSerialTypeLen(t); + offset64 += sqlite3VdbeSerialTypeLen(t); } aOffset[++i] = (u32)(offset64 & 0xffffffff); }while( i<=p2 && zHdraRow==0 ) tdsqlite3VdbeMemRelease(&sMem); + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); goto op_column_corrupt; } } pC->nHdrParsed = i; pC->iHdrOffset = (u32)(zHdr - zData); - if( pC->aRow==0 ) tdsqlite3VdbeMemRelease(&sMem); + if( pC->aRow==0 ) sqlite3VdbeMemRelease(&sMem); }else{ t = 0; } @@ -91244,9 +91244,9 @@ case OP_Column: { */ if( pC->nHdrParsed<=p2 ){ if( pOp->p4type==P4_MEM ){ - tdsqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); + sqlite3VdbeMemShallowCopy(pDest, pOp->p4.pMem, MEM_Static); }else{ - tdsqlite3VdbeMemSetNull(pDest); + sqlite3VdbeMemSetNull(pDest); } goto op_column_out; } @@ -91260,9 +91260,9 @@ case OP_Column: { */ assert( p2nHdrParsed ); assert( rc==SQLITE_OK ); - assert( tdsqlite3VdbeCheckMemInvariants(pDest) ); + assert( sqlite3VdbeCheckMemInvariants(pDest) ); if( VdbeMemDynamic(pDest) ){ - tdsqlite3VdbeMemSetNull(pDest); + sqlite3VdbeMemSetNull(pDest); } assert( t==pC->aType[p2] ); if( pC->szRow>=aOffset[p2+1] ){ @@ -91270,18 +91270,18 @@ case OP_Column: { ** page - where the content is not on an overflow page */ zData = pC->aRow + aOffset[p2]; if( t<12 ){ - tdsqlite3VdbeSerialGet(zData, t, pDest); + sqlite3VdbeSerialGet(zData, t, pDest); }else{ /* If the column value is a string, we need a persistent value, not ** a MEM_Ephem value. This branch is a fast short-cut that is equivalent - ** to calling tdsqlite3VdbeSerialGet() and tdsqlite3VdbeDeephemeralize(). + ** to calling sqlite3VdbeSerialGet() and sqlite3VdbeDeephemeralize(). */ static const u16 aFlag[] = { MEM_Blob, MEM_Str|MEM_Term }; pDest->n = len = (t-12)/2; pDest->enc = encoding; if( pDest->szMalloc < len+2 ){ pDest->flags = MEM_Null; - if( tdsqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; + if( sqlite3VdbeMemGrow(pDest, len+2, 0) ) goto no_mem; }else{ pDest->z = pDest->zMalloc; } @@ -91295,7 +91295,7 @@ case OP_Column: { /* This branch happens only when content is on overflow pages */ if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) - || (len = tdsqlite3VdbeSerialTypeLen(t))==0 + || (len = sqlite3VdbeSerialTypeLen(t))==0 ){ /* Content is irrelevant for ** 1. the typeof() function, @@ -91304,17 +91304,17 @@ case OP_Column: { ** So we might as well use bogus content rather than reading ** content from disk. ** - ** Although tdsqlite3VdbeSerialGet() may read at most 8 bytes from the + ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the ** buffer passed to it, debugging function VdbeMemPrettyPrint() may - ** read more. Use the global constant tdsqlite3CtypeMap[] as the array, + ** read more. Use the global constant sqlite3CtypeMap[] as the array, ** as that array is 256 bytes long (plenty for VdbeMemPrettyPrint()) ** and it begins with a bunch of zeros. */ - tdsqlite3VdbeSerialGet((u8*)tdsqlite3CtypeMap, t, pDest); + sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ - rc = tdsqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); if( rc!=SQLITE_OK ) goto abort_due_to_error; - tdsqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); + sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); pDest->flags &= ~MEM_Ephem; } } @@ -91425,7 +91425,7 @@ case OP_MakeRecord: { ** and so forth. ** ** Each type field is a varint representing the serial type of the - ** corresponding data element (see tdsqlite3VdbeSerialType()). The + ** corresponding data element (see sqlite3VdbeSerialType()). The ** hdr-size field is also a varint which is the offset from the beginning ** of the record to data0. */ @@ -91509,11 +91509,11 @@ case OP_MakeRecord: { if( pRec->flags & MEM_Null ){ if( pRec->flags & MEM_Zero ){ /* Values with MEM_Null and MEM_Zero are created by xColumn virtual - ** table methods that never invoke tdsqlite3_result_xxxxx() while + ** table methods that never invoke sqlite3_result_xxxxx() while ** computing an unchanging column value in an UPDATE statement. ** Give such values a special internal-use-only serial-type of 10 ** so that they can be passed through to xUpdate and have - ** a true tdsqlite3_value_nochange(). */ + ** a true sqlite3_value_nochange(). */ assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB ); pRec->uTemp = 10; }else{ @@ -91582,14 +91582,14 @@ case OP_MakeRecord: { if( pRec->flags & MEM_Zero ){ serial_type += pRec->u.nZero*2; if( nData ){ - if( tdsqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; + if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem; len += pRec->u.nZero; }else{ nZero += pRec->u.nZero; } } nData += len; - nHdr += tdsqlite3VarintLen(serial_type); + nHdr += sqlite3VarintLen(serial_type); pRec->uTemp = serial_type; } if( pRec==pData0 ) break; @@ -91607,16 +91607,16 @@ case OP_MakeRecord: { nHdr += 1; }else{ /* Rare case of a really large header */ - nVarint = tdsqlite3VarintLen(nHdr); + nVarint = sqlite3VarintLen(nHdr); nHdr += nVarint; - if( nVarintp3) is not allowed to ** be one of the input registers (because the following call to - ** tdsqlite3VdbeMemClearAndResize() could clobber the value before it is used). + ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). */ if( nByte+nZero<=pOut->szMalloc ){ /* The output register is already large enough to hold the record. @@ -91628,7 +91628,7 @@ case OP_MakeRecord: { if( nByte+nZero>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - if( tdsqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ + if( sqlite3VdbeMemClearAndResize(pOut, (int)nByte) ){ goto no_mem; } } @@ -91653,7 +91653,7 @@ case OP_MakeRecord: { zHdr += putVarint32(zHdr, serial_type); /* serial type */ /* EVIDENCE-OF: R-64536-51728 The values for each column in the record ** immediately follow the header. */ - zPayload += tdsqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */ + zPayload += sqlite3VdbeSerialPut(zPayload, pRec, serial_type); /* content */ }while( (++pRec)<=pLast ); assert( nHdr==(int)(zHdr - (u8*)pOut->z) ); assert( nByte==(int)(zPayload - (u8*)pOut->z) ); @@ -91678,7 +91678,7 @@ case OP_Count: { /* out2 */ pCrsr = p->apCsr[pOp->p1]->uc.pCursor; assert( pCrsr ); nEntry = 0; /* Not needed. Only used to silence a warning. */ - rc = tdsqlite3BtreeCount(db, pCrsr, &nEntry); + rc = sqlite3BtreeCount(db, pCrsr, &nEntry); if( rc ) goto abort_due_to_error; pOut = out2Prerelease(p, pOp); pOut->u.i = nEntry; @@ -91720,10 +91720,10 @@ case OP_Savepoint: { /* A new savepoint cannot be created if there are active write ** statements (i.e. open read/write incremental blob handles). */ - tdsqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress"); + sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress"); rc = SQLITE_BUSY; }else{ - nName = tdsqlite3Strlen30(zName); + nName = sqlite3Strlen30(zName); #ifndef SQLITE_OMIT_VIRTUALTABLE /* This call is Ok even if this savepoint is actually a transaction @@ -91731,13 +91731,13 @@ case OP_Savepoint: { ** If this is a transaction savepoint being opened, it is guaranteed ** that the db->aVTrans[] array is empty. */ assert( db->autoCommit==0 || db->nVTrans==0 ); - rc = tdsqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, db->nStatement+db->nSavepoint); if( rc!=SQLITE_OK ) goto abort_due_to_error; #endif /* Create a new savepoint structure. */ - pNew = tdsqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1); + pNew = sqlite3DbMallocRawNN(db, sizeof(Savepoint)+nName+1); if( pNew ){ pNew->zName = (char *)&pNew[1]; memcpy(pNew->zName, zName, nName+1); @@ -91766,19 +91766,19 @@ case OP_Savepoint: { ** an error is returned to the user. */ for( pSavepoint = db->pSavepoint; - pSavepoint && tdsqlite3StrICmp(pSavepoint->zName, zName); + pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName); pSavepoint = pSavepoint->pNext ){ iSavepoint++; } if( !pSavepoint ){ - tdsqlite3VdbeError(p, "no such savepoint: %s", zName); + sqlite3VdbeError(p, "no such savepoint: %s", zName); rc = SQLITE_ERROR; }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){ /* It is not possible to release (commit) a savepoint if there are ** active write statements. */ - tdsqlite3VdbeError(p, "cannot release savepoint - " + sqlite3VdbeError(p, "cannot release savepoint - " "SQL statements in progress"); rc = SQLITE_BUSY; }else{ @@ -91789,11 +91789,11 @@ case OP_Savepoint: { */ int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; if( isTransaction && p1==SAVEPOINT_RELEASE ){ - if( (rc = tdsqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ + if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; } db->autoCommit = 1; - if( tdsqlite3VdbeHalt(p)==SQLITE_BUSY ){ + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = (int)(pOp - aOp); db->autoCommit = 0; p->rc = rc = SQLITE_BUSY; @@ -91811,7 +91811,7 @@ case OP_Savepoint: { if( p1==SAVEPOINT_ROLLBACK ){ isSchemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0; for(ii=0; iinDb; ii++){ - rc = tdsqlite3BtreeTripAllCursors(db->aDb[ii].pBt, + rc = sqlite3BtreeTripAllCursors(db->aDb[ii].pBt, SQLITE_ABORT_ROLLBACK, isSchemaChange==0); if( rc!=SQLITE_OK ) goto abort_due_to_error; @@ -91821,14 +91821,14 @@ case OP_Savepoint: { isSchemaChange = 0; } for(ii=0; iinDb; ii++){ - rc = tdsqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); + rc = sqlite3BtreeSavepoint(db->aDb[ii].pBt, p1, iSavepoint); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } } if( isSchemaChange ){ - tdsqlite3ExpirePreparedStatements(db, 0); - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ExpirePreparedStatements(db, 0); + sqlite3ResetAllSchemasOfConnection(db); db->mDbFlags |= DBFLAG_SchemaChange; } } @@ -91839,7 +91839,7 @@ case OP_Savepoint: { while( db->pSavepoint!=pSavepoint ){ pTmp = db->pSavepoint; db->pSavepoint = pTmp->pNext; - tdsqlite3DbFree(db, pTmp); + sqlite3DbFree(db, pTmp); db->nSavepoint--; } @@ -91850,7 +91850,7 @@ case OP_Savepoint: { if( p1==SAVEPOINT_RELEASE ){ assert( pSavepoint==db->pSavepoint ); db->pSavepoint = pSavepoint->pNext; - tdsqlite3DbFree(db, pSavepoint); + sqlite3DbFree(db, pSavepoint); if( !isTransaction ){ db->nSavepoint--; } @@ -91861,7 +91861,7 @@ case OP_Savepoint: { } if( !isTransaction || p1==SAVEPOINT_ROLLBACK ){ - rc = tdsqlite3VtabSavepoint(db, p1, iSavepoint); + rc = sqlite3VtabSavepoint(db, p1, iSavepoint); if( rc!=SQLITE_OK ) goto abort_due_to_error; } } @@ -91894,28 +91894,28 @@ case OP_AutoCommit: { if( desiredAutoCommit!=db->autoCommit ){ if( iRollback ){ assert( desiredAutoCommit==1 ); - tdsqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); + sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK); db->autoCommit = 1; }else if( desiredAutoCommit && db->nVdbeWrite>0 ){ /* If this instruction implements a COMMIT and other VMs are writing ** return an error indicating that the other VMs must complete first. */ - tdsqlite3VdbeError(p, "cannot commit transaction - " + sqlite3VdbeError(p, "cannot commit transaction - " "SQL statements in progress"); rc = SQLITE_BUSY; goto abort_due_to_error; - }else if( (rc = tdsqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ + }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ goto vdbe_return; }else{ db->autoCommit = (u8)desiredAutoCommit; } - if( tdsqlite3VdbeHalt(p)==SQLITE_BUSY ){ + if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = (int)(pOp - aOp); db->autoCommit = (u8)(1-desiredAutoCommit); p->rc = rc = SQLITE_BUSY; goto vdbe_return; } - tdsqlite3CloseSavepoints(db); + sqlite3CloseSavepoints(db); if( p->rc==SQLITE_OK ){ rc = SQLITE_DONE; }else{ @@ -91923,7 +91923,7 @@ case OP_AutoCommit: { } goto vdbe_return; }else{ - tdsqlite3VdbeError(p, + sqlite3VdbeError(p, (!desiredAutoCommit)?"cannot start a transaction within a transaction":( (iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); @@ -91965,7 +91965,7 @@ case OP_AutoCommit: { ** cookie in P3 differs from the schema cookie in the database header or ** if the schema generation counter in P4 differs from the current ** generation counter, then an SQLITE_SCHEMA error is raised and execution -** halts. The tdsqlite3_step() wrapper function might then reprepare the +** halts. The sqlite3_step() wrapper function might then reprepare the ** statement and rerun it from the beginning. */ case OP_Transaction: { @@ -91983,7 +91983,7 @@ case OP_Transaction: { pBt = db->aDb[pOp->p1].pBt; if( pBt ){ - rc = tdsqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); + rc = sqlite3BtreeBeginTrans(pBt, pOp->p2, &iMeta); testcase( rc==SQLITE_BUSY_SNAPSHOT ); testcase( rc==SQLITE_BUSY_RECOVERY ); if( rc!=SQLITE_OK ){ @@ -91999,16 +91999,16 @@ case OP_Transaction: { && pOp->p2 && (db->autoCommit==0 || db->nVdbeRead>1) ){ - assert( tdsqlite3BtreeIsInTrans(pBt) ); + assert( sqlite3BtreeIsInTrans(pBt) ); if( p->iStatement==0 ){ assert( db->nStatement>=0 && db->nSavepoint>=0 ); db->nStatement++; p->iStatement = db->nSavepoint + db->nStatement; } - rc = tdsqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); if( rc==SQLITE_OK ){ - rc = tdsqlite3BtreeBeginStmt(pBt, p->iStatement); + rc = sqlite3BtreeBeginStmt(pBt, p->iStatement); } /* Store the current value of the database handles deferred constraint @@ -92028,8 +92028,8 @@ case OP_Transaction: { ** version is checked to ensure that the schema has not changed since the ** SQL statement was prepared. */ - tdsqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = tdsqlite3DbStrDup(db, "database schema has changed"); + sqlite3DbFree(db, p->zErrMsg); + p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie ** stored with the in-memory representation of the schema, do ** not reload the schema from the database file. @@ -92039,12 +92039,12 @@ case OP_Transaction: { ** are queried from within xNext() and other v-table methods using ** prepared queries. If such a query is out-of-date, we do not want to ** discard the database schema, as the user code implementing the - ** v-table would have to be ready for the tdsqlite3_vtab structure itself - ** to be invalidated whenever tdsqlite3_step() is called from within + ** v-table would have to be ready for the sqlite3_vtab structure itself + ** to be invalidated whenever sqlite3_step() is called from within ** a v-table method. */ if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ - tdsqlite3ResetOneSchema(db, pOp->p1); + sqlite3ResetOneSchema(db, pOp->p1); } p->expired = 1; rc = SQLITE_SCHEMA; @@ -92078,7 +92078,7 @@ case OP_ReadCookie: { /* out2 */ assert( db->aDb[iDb].pBt!=0 ); assert( DbMaskTest(p->btreeMask, iDb) ); - tdsqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); + sqlite3BtreeGetMeta(db->aDb[iDb].pBt, iCookie, (u32 *)&iMeta); pOut = out2Prerelease(p, pOp); pOut->u.i = iMeta; break; @@ -92097,16 +92097,16 @@ case OP_ReadCookie: { /* out2 */ case OP_SetCookie: { Db *pDb; - tdsqlite3VdbeIncrWriteCounter(p, 0); + sqlite3VdbeIncrWriteCounter(p, 0); assert( pOp->p2p1>=0 && pOp->p1nDb ); assert( DbMaskTest(p->btreeMask, pOp->p1) ); assert( p->readOnly==0 ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); - assert( tdsqlite3SchemaMutexHeld(db, pOp->p1, 0) ); + assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) ); /* See note about index shifting on OP_ReadCookie */ - rc = tdsqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); + rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ pDb->pSchema->schema_cookie = pOp->p3; @@ -92118,7 +92118,7 @@ case OP_SetCookie: { if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database ** schema is changed. Ticket #1644 */ - tdsqlite3ExpirePreparedStatements(db, 0); + sqlite3ExpirePreparedStatements(db, 0); p->expired = 0; } if( rc ) goto abort_due_to_error; @@ -92253,7 +92253,7 @@ case OP_OpenWrite: if( pOp->opcode==OP_OpenWrite ){ assert( OPFLAG_FORDELETE==BTREE_FORDELETE ); wrFlag = BTREE_WRCSR | (pOp->p5 & OPFLAG_FORDELETE); - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( pDb->pSchema->file_format < p->minWriteFileFormat ){ p->minWriteFileFormat = pDb->pSchema->file_format; } @@ -92267,7 +92267,7 @@ case OP_OpenWrite: pIn2 = &aMem[p2]; assert( memIsValid(pIn2) ); assert( (pIn2->flags & MEM_Int)!=0 ); - tdsqlite3VdbeMemIntegerify(pIn2); + sqlite3VdbeMemIntegerify(pIn2); p2 = (int)pIn2->u.i; /* The p2 value always comes from a prior OP_CreateBtree opcode and ** that opcode will always set the p2 value to 2 or more or else fail. @@ -92294,7 +92294,7 @@ case OP_OpenWrite: #ifdef SQLITE_DEBUG pCur->wrFlag = wrFlag; #endif - rc = tdsqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); + rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor); pCur->pKeyInfo = pKeyInfo; /* Set the VdbeCursor.isTable variable. Previous versions of ** SQLite used to check if the root-page flags were sane at this point @@ -92309,7 +92309,7 @@ open_cursor_set_hints: #ifdef SQLITE_ENABLE_CURSOR_HINTS testcase( pOp->p2 & OPFLAG_SEEKEQ ); #endif - tdsqlite3BtreeCursorHintFlags(pCur->uc.pCursor, + sqlite3BtreeCursorHintFlags(pCur->uc.pCursor, (pOp->p5 & (OPFLAG_BULKCSR|OPFLAG_SEEKEQ))); if( rc ) goto abort_due_to_error; break; @@ -92339,11 +92339,11 @@ case OP_OpenDup: { pCx->isTable = pOrig->isTable; pCx->pgnoRoot = pOrig->pgnoRoot; pCx->isOrdered = pOrig->isOrdered; - rc = tdsqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR, pCx->pKeyInfo, pCx->uc.pCursor); - /* The tdsqlite3BtreeCursor() routine can only fail for the first cursor + /* The sqlite3BtreeCursor() routine can only fail for the first cursor ** opened for a database. Since there is already an open cursor when this - ** opcode is run, the tdsqlite3BtreeCursor() cannot fail */ + ** opcode is run, the sqlite3BtreeCursor() cannot fail */ assert( rc==SQLITE_OK ); break; } @@ -92398,38 +92398,38 @@ case OP_OpenEphemeral: { assert( pCx->isEphemeral ); pCx->seqCount = 0; pCx->cacheStatus = CACHE_STALE; - rc = tdsqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); + rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); }else{ pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; pCx->isEphemeral = 1; - rc = tdsqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ - rc = tdsqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); + rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling - ** tdsqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before + ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before ** opening it. If a transient table is required, just use the ** automatically created table with root-page 1 (an BLOB_INTKEY table). */ if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ assert( pOp->p4type==P4_KEYINFO ); - rc = tdsqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot, + rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot, BTREE_BLOBKEY | pOp->p5); if( rc==SQLITE_OK ){ assert( pCx->pgnoRoot==MASTER_ROOT+1 ); assert( pKeyInfo->db==db ); assert( pKeyInfo->enc==ENC(db) ); - rc = tdsqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, pKeyInfo, pCx->uc.pCursor); } pCx->isTable = 0; }else{ pCx->pgnoRoot = MASTER_ROOT; - rc = tdsqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR, 0, pCx->uc.pCursor); pCx->isTable = 1; } @@ -92461,7 +92461,7 @@ case OP_SorterOpen: { pCx->pKeyInfo = pOp->p4.pKeyInfo; assert( pCx->pKeyInfo->db==db ); assert( pCx->pKeyInfo->enc==ENC(db) ); - rc = tdsqlite3VdbeSorterInit(db, pOp->p3, pCx); + rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx); if( rc ) goto abort_due_to_error; break; } @@ -92511,10 +92511,10 @@ case OP_OpenPseudo: { pCx->seekResult = pOp->p2; pCx->isTable = 1; /* Give this pseudo-cursor a fake BtCursor pointer so that pCx - ** can be safely passed to tdsqlite3VdbeCursorMoveto(). This avoids a test - ** for pCx->eCurType==CURTYPE_BTREE inside of tdsqlite3VdbeCursorMoveto() + ** can be safely passed to sqlite3VdbeCursorMoveto(). This avoids a test + ** for pCx->eCurType==CURTYPE_BTREE inside of sqlite3VdbeCursorMoveto() ** which is a performance optimization */ - pCx->uc.pCursor = tdsqlite3BtreeFakeValidCursor(); + pCx->uc.pCursor = sqlite3BtreeFakeValidCursor(); assert( pOp->p5==0 ); break; } @@ -92526,7 +92526,7 @@ case OP_OpenPseudo: { */ case OP_Close: { assert( pOp->p1>=0 && pOp->p1nCursor ); - tdsqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); + sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); p->apCsr[pOp->p1] = 0; break; } @@ -92671,7 +92671,7 @@ case OP_SeekGT: { /* jump, in3, group */ if( pC->isTable ){ u16 flags3, newType; /* The BTREE_SEEK_EQ flag is only set on index cursors */ - assert( tdsqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 + assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 || CORRUPT_DB ); /* The input value in P3 might be of any type: integer, real, string, @@ -92682,7 +92682,7 @@ case OP_SeekGT: { /* jump, in3, group */ if( (flags3 & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3, 0); } - iKey = tdsqlite3VdbeIntValue(pIn3); /* Get the integer key value */ + iKey = sqlite3VdbeIntValue(pIn3); /* Get the integer key value */ newType = pIn3->flags; /* Record the type after applying numeric affinity */ pIn3->flags = flags3; /* But convert the type back to its original */ @@ -92694,7 +92694,7 @@ case OP_SeekGT: { /* jump, in3, group */ VdbeBranchTaken(1,2); goto jump_to_p2; }else{ - rc = tdsqlite3BtreeLast(pC->uc.pCursor, &res); + rc = sqlite3BtreeLast(pC->uc.pCursor, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; goto seek_not_found; } @@ -92723,7 +92723,7 @@ case OP_SeekGT: { /* jump, in3, group */ if( (oc & 0x0001)==(OP_SeekLT & 0x0001) ) oc++; } } - rc = tdsqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)iKey, 0, &res); pC->movetoTarget = iKey; /* Used by OP_Delete */ if( rc!=SQLITE_OK ){ goto abort_due_to_error; @@ -92733,7 +92733,7 @@ case OP_SeekGT: { /* jump, in3, group */ ** OP_SeekLE opcodes are allowed, and these must be immediately followed ** by an OP_IdxGT or OP_IdxLT opcode, respectively, with the same key. */ - if( tdsqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){ + if( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ) ){ eqOnly = 1; assert( pOp->opcode==OP_SeekGE || pOp->opcode==OP_SeekLE ); assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT ); @@ -92767,7 +92767,7 @@ case OP_SeekGT: { /* jump, in3, group */ { int i; for(i=0; iuc.pCursor, &r, 0, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, &r, 0, 0, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -92777,12 +92777,12 @@ case OP_SeekGT: { /* jump, in3, group */ } } #ifdef SQLITE_TEST - tdsqlite3_search_count++; + sqlite3_search_count++; #endif if( oc>=OP_SeekGE ){ assert( oc==OP_SeekGE || oc==OP_SeekGT ); if( res<0 || (res==0 && oc==OP_SeekGT) ){ res = 0; - rc = tdsqlite3BtreeNext(pC->uc.pCursor, 0); + rc = sqlite3BtreeNext(pC->uc.pCursor, 0); if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ rc = SQLITE_OK; @@ -92798,7 +92798,7 @@ case OP_SeekGT: { /* jump, in3, group */ assert( oc==OP_SeekLT || oc==OP_SeekLE ); if( res>0 || (res==0 && oc==OP_SeekLT) ){ res = 0; - rc = tdsqlite3BtreePrevious(pC->uc.pCursor, 0); + rc = sqlite3BtreePrevious(pC->uc.pCursor, 0); if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ rc = SQLITE_OK; @@ -92811,7 +92811,7 @@ case OP_SeekGT: { /* jump, in3, group */ /* res might be negative because the table is empty. Check to ** see if this is the case. */ - res = tdsqlite3BtreeEof(pC->uc.pCursor); + res = sqlite3BtreeEof(pC->uc.pCursor); } } seek_not_found: @@ -92966,7 +92966,7 @@ case OP_Found: { /* jump, in3 */ UnpackedRecord r; #ifdef SQLITE_TEST - if( pOp->opcode!=OP_NoConflict ) tdsqlite3_found_count++; + if( pOp->opcode!=OP_NoConflict ) sqlite3_found_count++; #endif assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -92998,9 +92998,9 @@ case OP_Found: { /* jump, in3 */ rc = ExpandBlob(pIn3); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc ) goto no_mem; - pFree = pIdxKey = tdsqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); + pFree = pIdxKey = sqlite3VdbeAllocUnpackedRecord(pC->pKeyInfo); if( pIdxKey==0 ) goto no_mem; - tdsqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); + sqlite3VdbeRecordUnpack(pC->pKeyInfo, pIn3->n, pIn3->z, pIdxKey); } pIdxKey->default_rc = 0; takeJump = 0; @@ -93015,8 +93015,8 @@ case OP_Found: { /* jump, in3 */ } } } - rc = tdsqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); - if( pFree ) tdsqlite3DbFreeNN(db, pFree); + rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, pIdxKey, 0, 0, &res); + if( pFree ) sqlite3DbFreeNN(db, pFree); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -93122,7 +93122,7 @@ notExistsWithKey: pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); res = 0; - rc = tdsqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pCrsr, 0, iKey, 0, &res); assert( rc==SQLITE_OK || res==0 ); pC->movetoTarget = iKey; /* Used by OP_Delete */ pC->nullRow = 0; @@ -93178,7 +93178,7 @@ case OP_Sequence: { /* out2 */ case OP_NewRowid: { /* out2 */ i64 v; /* The new rowid */ VdbeCursor *pC; /* Cursor of table to get the new rowid */ - int res; /* Result of an tdsqlite3BtreeLast() */ + int res; /* Result of an sqlite3BtreeLast() */ int cnt; /* Counter to limit the number of searches */ Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ VdbeFrame *pFrame; /* Root frame of VDBE */ @@ -93219,15 +93219,15 @@ case OP_NewRowid: { /* out2 */ #endif if( !pC->useRandomRowid ){ - rc = tdsqlite3BtreeLast(pC->uc.pCursor, &res); + rc = sqlite3BtreeLast(pC->uc.pCursor, &res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } if( res ){ v = 1; /* IMP: R-61914-48074 */ }else{ - assert( tdsqlite3BtreeCursorIsValid(pC->uc.pCursor) ); - v = tdsqlite3BtreeIntegerKey(pC->uc.pCursor); + assert( sqlite3BtreeCursorIsValid(pC->uc.pCursor) ); + v = sqlite3BtreeIntegerKey(pC->uc.pCursor); if( v>=MAX_ROWID ){ pC->useRandomRowid = 1; }else{ @@ -93254,7 +93254,7 @@ case OP_NewRowid: { /* out2 */ assert( memIsValid(pMem) ); REGISTER_TRACE(pOp->p3, pMem); - tdsqlite3VdbeMemIntegerify(pMem); + sqlite3VdbeMemIntegerify(pMem); assert( (pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ if( pMem->u.i==MAX_ROWID || pC->useRandomRowid ){ rc = SQLITE_FULL; /* IMP: R-17817-00630 */ @@ -93275,9 +93275,9 @@ case OP_NewRowid: { /* out2 */ ** an AUTOINCREMENT table. */ cnt = 0; do{ - tdsqlite3_randomness(sizeof(v), &v); + sqlite3_randomness(sizeof(v), &v); v &= (MAX_ROWID>>1); v++; /* Ensure that v is greater than zero */ - }while( ((rc = tdsqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)v, + }while( ((rc = sqlite3BtreeMovetoUnpacked(pC->uc.pCursor, 0, (u64)v, 0, &res))==SQLITE_OK) && (res==0) && (++cnt<100)); @@ -93307,7 +93307,7 @@ case OP_NewRowid: { /* out2 */ ** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is ** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set, ** then rowid is stored for subsequent return by the -** tdsqlite3_last_insert_rowid() function (otherwise it is unmodified). +** sqlite3_last_insert_rowid() function (otherwise it is unmodified). ** ** If the OPFLAG_USESEEKRESULT flag of P5 is set, the implementation might ** run faster by avoiding an unnecessary seek on cursor P1. However, @@ -93352,7 +93352,7 @@ case OP_Insert: { assert( (pOp->p5 & OPFLAG_ISNOOP) || pC->isTable ); assert( pOp->p4type==P4_TABLE || pOp->p4type>=P4_STATIC ); REGISTER_TRACE(pOp->p2, pData); - tdsqlite3VdbeIncrWriteCounter(p, pC); + sqlite3VdbeIncrWriteCounter(p, pC); pKey = &aMem[pOp->p3]; assert( pKey->flags & MEM_Int ); @@ -93374,7 +93374,7 @@ case OP_Insert: { /* Invoke the pre-update hook, if any */ if( pTab ){ if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){ - tdsqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2); + sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2); } if( db->xUpdateCallback==0 || pTab->aCol==0 ){ /* Prevent post-update hook from running in cases when it should not */ @@ -93396,7 +93396,7 @@ case OP_Insert: { x.nZero = 0; } x.pKey = 0; - rc = tdsqlite3BtreeInsert(pC->uc.pCursor, &x, + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult ); pC->deferredMoveto = 0; @@ -93462,18 +93462,18 @@ case OP_Delete: { assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); assert( pC->deferredMoveto==0 ); - tdsqlite3VdbeIncrWriteCounter(p, pC); + sqlite3VdbeIncrWriteCounter(p, pC); #ifdef SQLITE_DEBUG if( pOp->p4type==P4_TABLE && HasRowid(pOp->p4.pTab) && pOp->p5==0 - && tdsqlite3BtreeCursorIsValidNN(pC->uc.pCursor) + && sqlite3BtreeCursorIsValidNN(pC->uc.pCursor) ){ /* If p5 is zero, the seek operation that positioned the cursor prior to ** OP_Delete will have also set the pC->movetoTarget field to the rowid of ** the row that is being deleted */ - i64 iKey = tdsqlite3BtreeIntegerKey(pC->uc.pCursor); + i64 iKey = sqlite3BtreeIntegerKey(pC->uc.pCursor); assert( CORRUPT_DB || pC->movetoTarget==iKey ); } #endif @@ -93489,7 +93489,7 @@ case OP_Delete: { zDb = db->aDb[pC->iDb].zDbSName; pTab = pOp->p4.pTab; if( (pOp->p5 & OPFLAG_SAVEPOSITION)!=0 && pC->isTable ){ - pC->movetoTarget = tdsqlite3BtreeIntegerKey(pC->uc.pCursor); + pC->movetoTarget = sqlite3BtreeIntegerKey(pC->uc.pCursor); } }else{ zDb = 0; /* Not needed. Silence a compiler warning. */ @@ -93503,7 +93503,7 @@ case OP_Delete: { || HasRowid(pTab)==0 || (aMem[pOp->p3].flags & MEM_Int) ); - tdsqlite3VdbePreUpdateHook(p, pC, + sqlite3VdbePreUpdateHook(p, pC, (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, zDb, pTab, pC->movetoTarget, pOp->p3 @@ -93531,7 +93531,7 @@ case OP_Delete: { } #endif - rc = tdsqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); + rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; pC->seekResult = 0; if( rc ) goto abort_due_to_error; @@ -93551,12 +93551,12 @@ case OP_Delete: { /* Opcode: ResetCount * * * * * ** ** The value of the change counter is copied to the database handle -** change counter (returned by subsequent calls to tdsqlite3_changes()). +** change counter (returned by subsequent calls to sqlite3_changes()). ** Then the VMs internal change counter resets to 0. ** This is used by trigger programs. */ case OP_ResetCount: { - tdsqlite3VdbeSetChanges(db, p->nChange); + sqlite3VdbeSetChanges(db, p->nChange); p->nChange = 0; break; } @@ -93587,7 +93587,7 @@ case OP_SorterCompare: { pIn3 = &aMem[pOp->p3]; nKeyCol = pOp->p4.i; res = 0; - rc = tdsqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); + rc = sqlite3VdbeSorterCompare(pC, pIn3, nKeyCol, &res); VdbeBranchTaken(res!=0,2); if( rc ) goto abort_due_to_error; if( res ) goto jump_to_p2; @@ -93612,7 +93612,7 @@ case OP_SorterData: { pOut = &aMem[pOp->p2]; pC = p->apCsr[pOp->p1]; assert( isSorter(pC) ); - rc = tdsqlite3VdbeSorterRowkey(pC, pOut); + rc = sqlite3VdbeSorterRowkey(pC, pOut); assert( rc!=SQLITE_OK || (pOut->flags & MEM_Blob) ); assert( pOp->p1>=0 && pOp->p1nCursor ); if( rc ) goto abort_due_to_error; @@ -93670,21 +93670,21 @@ case OP_RowData: { ** If this where not the case, on of the following assert()s ** would fail. Should this ever change (because of changes in the code ** generator) then the fix would be to insert a call to - ** tdsqlite3VdbeCursorMoveto(). + ** sqlite3VdbeCursorMoveto(). */ assert( pC->deferredMoveto==0 ); - assert( tdsqlite3BtreeCursorIsValid(pCrsr) ); + assert( sqlite3BtreeCursorIsValid(pCrsr) ); #if 0 /* Not required due to the previous to assert() statements */ - rc = tdsqlite3VdbeCursorMoveto(pC); + rc = sqlite3VdbeCursorMoveto(pC); if( rc!=SQLITE_OK ) goto abort_due_to_error; #endif - n = tdsqlite3BtreePayloadSize(pCrsr); + n = sqlite3BtreePayloadSize(pCrsr); if( n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } testcase( n==0 ); - rc = tdsqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut); + rc = sqlite3VdbeMemFromBtree(pCrsr, 0, n, pOut); if( rc ) goto abort_due_to_error; if( !pOp->p3 ) Deephemeralize(pOut); UPDATE_MAX_BLOBSIZE(pOut); @@ -93705,8 +93705,8 @@ case OP_RowData: { case OP_Rowid: { /* out2 */ VdbeCursor *pC; i64 v; - tdsqlite3_vtab *pVtab; - const tdsqlite3_module *pModule; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; pOut = out2Prerelease(p, pOp); assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -93725,19 +93725,19 @@ case OP_Rowid: { /* out2 */ pModule = pVtab->pModule; assert( pModule->xRowid ); rc = pModule->xRowid(pC->uc.pVCur, &v); - tdsqlite3VtabImportErrmsg(p, pVtab); + sqlite3VtabImportErrmsg(p, pVtab); if( rc ) goto abort_due_to_error; #endif /* SQLITE_OMIT_VIRTUALTABLE */ }else{ assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->uc.pCursor!=0 ); - rc = tdsqlite3VdbeCursorRestore(pC); + rc = sqlite3VdbeCursorRestore(pC); if( rc ) goto abort_due_to_error; if( pC->nullRow ){ pOut->flags = MEM_Null; break; } - v = tdsqlite3BtreeIntegerKey(pC->uc.pCursor); + v = sqlite3BtreeIntegerKey(pC->uc.pCursor); } pOut->u.i = v; break; @@ -93759,7 +93759,7 @@ case OP_NullRow: { pC->cacheStatus = CACHE_STALE; if( pC->eCurType==CURTYPE_BTREE ){ assert( pC->uc.pCursor!=0 ); - tdsqlite3BtreeClearCursor(pC->uc.pCursor); + sqlite3BtreeClearCursor(pC->uc.pCursor); } #ifdef SQLITE_DEBUG if( pC->seekOp==0 ) pC->seekOp = OP_NullRow; @@ -93808,11 +93808,11 @@ case OP_Last: { /* jump */ if( pOp->opcode==OP_SeekEnd ){ assert( pOp->p2==0 ); pC->seekResult = -1; - if( tdsqlite3BtreeCursorIsValidNN(pCrsr) ){ + if( sqlite3BtreeCursorIsValidNN(pCrsr) ){ break; } } - rc = tdsqlite3BtreeLast(pCrsr, &res); + rc = sqlite3BtreeLast(pCrsr, &res); pC->nullRow = (u8)res; pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; @@ -93840,11 +93840,11 @@ case OP_IfSmaller: { /* jump */ assert( pC!=0 ); pCrsr = pC->uc.pCursor; assert( pCrsr ); - rc = tdsqlite3BtreeFirst(pCrsr, &res); + rc = sqlite3BtreeFirst(pCrsr, &res); if( rc ) goto abort_due_to_error; if( res==0 ){ - sz = tdsqlite3BtreeRowCountEst(pCrsr); - if( ALWAYS(sz>=0) && tdsqlite3LogEst((u64)sz)p3 ) res = 1; + sz = sqlite3BtreeRowCountEst(pCrsr); + if( ALWAYS(sz>=0) && sqlite3LogEst((u64)sz)p3 ) res = 1; } VdbeBranchTaken(res!=0,2); if( res ) goto jump_to_p2; @@ -93876,8 +93876,8 @@ case OP_IfSmaller: { /* jump */ case OP_SorterSort: /* jump */ case OP_Sort: { /* jump */ #ifdef SQLITE_TEST - tdsqlite3_sort_count++; - tdsqlite3_search_count--; + sqlite3_sort_count++; + sqlite3_search_count--; #endif p->aCounter[SQLITE_STMTSTATUS_SORT]++; /* Fall through into OP_Rewind */ @@ -93909,12 +93909,12 @@ case OP_Rewind: { /* jump */ pC->seekOp = OP_Rewind; #endif if( isSorter(pC) ){ - rc = tdsqlite3VdbeSorterRewind(pC, &res); + rc = sqlite3VdbeSorterRewind(pC, &res); }else{ assert( pC->eCurType==CURTYPE_BTREE ); pCrsr = pC->uc.pCursor; assert( pCrsr ); - rc = tdsqlite3BtreeFirst(pCrsr, &res); + rc = sqlite3BtreeFirst(pCrsr, &res); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; } @@ -93946,7 +93946,7 @@ case OP_Rewind: { /* jump */ ** always either 0 or 1. ** ** P4 is always of type P4_ADVANCE. The function pointer points to -** tdsqlite3BtreeNext(). +** sqlite3BtreeNext(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. @@ -93974,7 +93974,7 @@ case OP_Rewind: { /* jump */ ** always either 0 or 1. ** ** P4 is always of type P4_ADVANCE. The function pointer points to -** tdsqlite3BtreePrevious(). +** sqlite3BtreePrevious(). ** ** If P5 is positive and the jump is taken, then event counter ** number P5-1 in the prepared statement is incremented. @@ -93991,7 +93991,7 @@ case OP_SorterNext: { /* jump */ pC = p->apCsr[pOp->p1]; assert( isSorter(pC) ); - rc = tdsqlite3VdbeSorterNext(db, pC); + rc = sqlite3VdbeSorterNext(db, pC); goto next_tail; case OP_Prev: /* jump */ case OP_Next: /* jump */ @@ -94001,8 +94001,8 @@ case OP_Next: /* jump */ assert( pC!=0 ); assert( pC->deferredMoveto==0 ); assert( pC->eCurType==CURTYPE_BTREE ); - assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==tdsqlite3BtreeNext ); - assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==tdsqlite3BtreePrevious ); + assert( pOp->opcode!=OP_Next || pOp->p4.xAdvance==sqlite3BtreeNext ); + assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious ); /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found. ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ @@ -94024,7 +94024,7 @@ next_tail: pC->nullRow = 0; p->aCounter[pOp->p5]++; #ifdef SQLITE_TEST - tdsqlite3_search_count++; + sqlite3_search_count++; #endif goto jump_to_p2_and_check_for_interrupt; } @@ -94076,7 +94076,7 @@ case OP_IdxInsert: { /* in2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; - tdsqlite3VdbeIncrWriteCounter(p, pC); + sqlite3VdbeIncrWriteCounter(p, pC); assert( pC!=0 ); assert( isSorter(pC)==(pOp->opcode==OP_SorterInsert) ); pIn2 = &aMem[pOp->p2]; @@ -94087,13 +94087,13 @@ case OP_IdxInsert: { /* in2 */ rc = ExpandBlob(pIn2); if( rc ) goto abort_due_to_error; if( pOp->opcode==OP_SorterInsert ){ - rc = tdsqlite3VdbeSorterWrite(pC, pIn2); + rc = sqlite3VdbeSorterWrite(pC, pIn2); }else{ x.nKey = pIn2->n; x.pKey = pIn2->z; x.aMem = aMem + pOp->p3; x.nMem = (u16)pOp->p4.i; - rc = tdsqlite3BtreeInsert(pC->uc.pCursor, &x, + rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); @@ -94123,7 +94123,7 @@ case OP_IdxDelete: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); - tdsqlite3VdbeIncrWriteCounter(p, pC); + sqlite3VdbeIncrWriteCounter(p, pC); pCrsr = pC->uc.pCursor; assert( pCrsr!=0 ); assert( pOp->p5==0 ); @@ -94131,10 +94131,10 @@ case OP_IdxDelete: { r.nField = (u16)pOp->p3; r.default_rc = 0; r.aMem = &aMem[pOp->p2]; - rc = tdsqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); + rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res); if( rc ) goto abort_due_to_error; if( res==0 ){ - rc = tdsqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); + rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE); if( rc ) goto abort_due_to_error; } assert( pC->deferredMoveto==0 ); @@ -94187,17 +94187,17 @@ case OP_IdxRowid: { /* out2 */ assert( !pC->nullRow || pOp->opcode==OP_IdxRowid ); /* The IdxRowid and Seek opcodes are combined because of the commonality - ** of tdsqlite3VdbeCursorRestore() and tdsqlite3VdbeIdxRowid(). */ - rc = tdsqlite3VdbeCursorRestore(pC); + ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */ + rc = sqlite3VdbeCursorRestore(pC); - /* tdsqlite3VbeCursorRestore() can only fail if the record has been deleted + /* sqlite3VbeCursorRestore() can only fail if the record has been deleted ** out from under the cursor. That will never happens for an IdxRowid ** or Seek opcode */ if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; if( !pC->nullRow ){ rowid = 0; /* Not needed. Only used to silence a warning. */ - rc = tdsqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); + rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } @@ -94220,7 +94220,7 @@ case OP_IdxRowid: { /* out2 */ } }else{ assert( pOp->opcode==OP_IdxRowid ); - tdsqlite3VdbeMemSetNull(&aMem[pOp->p2]); + sqlite3VdbeMemSetNull(&aMem[pOp->p2]); } break; } @@ -94237,7 +94237,7 @@ case OP_FinishSeek: { assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; if( pC->deferredMoveto ){ - rc = tdsqlite3VdbeFinishMoveto(pC); + rc = sqlite3VdbeFinishMoveto(pC); if( rc ) goto abort_due_to_error; } break; @@ -94324,7 +94324,7 @@ case OP_IdxGE: { /* jump */ } #endif res = 0; /* Not needed. Only used to silence a warning. */ - rc = tdsqlite3VdbeIdxKeyCompare(db, pC, &r, &res); + rc = sqlite3VdbeIdxKeyCompare(db, pC, &r, &res); assert( (OP_IdxLE&1)==(OP_IdxLT&1) && (OP_IdxGE&1)==(OP_IdxGT&1) ); if( (pOp->opcode&1)==(OP_IdxLT&1) ){ assert( pOp->opcode==OP_IdxLE || pOp->opcode==OP_IdxLT ); @@ -94370,7 +94370,7 @@ case OP_Destroy: { /* out2 */ int iMoved; int iDb; - tdsqlite3VdbeIncrWriteCounter(p, 0); + sqlite3VdbeIncrWriteCounter(p, 0); assert( p->readOnly==0 ); assert( pOp->p1>1 ); pOut = out2Prerelease(p, pOp); @@ -94383,13 +94383,13 @@ case OP_Destroy: { /* out2 */ iDb = pOp->p3; assert( DbMaskTest(p->btreeMask, iDb) ); iMoved = 0; /* Not needed. Only to silence a warning. */ - rc = tdsqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); + rc = sqlite3BtreeDropTable(db->aDb[iDb].pBt, pOp->p1, &iMoved); pOut->flags = MEM_Int; pOut->u.i = iMoved; if( rc ) goto abort_due_to_error; #ifndef SQLITE_OMIT_AUTOVACUUM if( iMoved!=0 ){ - tdsqlite3RootPageMoved(db, iDb, iMoved, pOp->p1); + sqlite3RootPageMoved(db, iDb, iMoved, pOp->p1); /* All OP_Destroy operations occur on the same btree */ assert( resetSchemaOnFault==0 || resetSchemaOnFault==iDb+1 ); resetSchemaOnFault = iDb+1; @@ -94420,11 +94420,11 @@ case OP_Destroy: { /* out2 */ case OP_Clear: { int nChange; - tdsqlite3VdbeIncrWriteCounter(p, 0); + sqlite3VdbeIncrWriteCounter(p, 0); nChange = 0; assert( p->readOnly==0 ); assert( DbMaskTest(p->btreeMask, pOp->p2) ); - rc = tdsqlite3BtreeClearTable( + rc = sqlite3BtreeClearTable( db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &nChange : 0) ); if( pOp->p3 ){ @@ -94454,11 +94454,11 @@ case OP_ResetSorter: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); if( isSorter(pC) ){ - tdsqlite3VdbeSorterReset(db, pC->uc.pSorter); + sqlite3VdbeSorterReset(db, pC->uc.pSorter); }else{ assert( pC->eCurType==CURTYPE_BTREE ); assert( pC->isEphemeral ); - rc = tdsqlite3BtreeClearTableOfCursor(pC->uc.pCursor); + rc = sqlite3BtreeClearTableOfCursor(pC->uc.pCursor); if( rc ) goto abort_due_to_error; } break; @@ -94477,7 +94477,7 @@ case OP_CreateBtree: { /* out2 */ int pgno; Db *pDb; - tdsqlite3VdbeIncrWriteCounter(p, 0); + sqlite3VdbeIncrWriteCounter(p, 0); pOut = out2Prerelease(p, pOp); pgno = 0; assert( pOp->p3==BTREE_INTKEY || pOp->p3==BTREE_BLOBKEY ); @@ -94486,7 +94486,7 @@ case OP_CreateBtree: { /* out2 */ assert( p->readOnly==0 ); pDb = &db->aDb[pOp->p1]; assert( pDb->pBt!=0 ); - rc = tdsqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3); + rc = sqlite3BtreeCreateTable(pDb->pBt, &pgno, pOp->p3); if( rc ) goto abort_due_to_error; pOut->u.i = pgno; break; @@ -94497,9 +94497,9 @@ case OP_CreateBtree: { /* out2 */ ** Run the SQL statement or statements specified in the P4 string. */ case OP_SqlExec: { - tdsqlite3VdbeIncrWriteCounter(p, 0); + sqlite3VdbeIncrWriteCounter(p, 0); db->nSqlExec++; - rc = tdsqlite3_exec(db, pOp->p4.z, 0, 0, 0); + rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); db->nSqlExec--; if( rc ) goto abort_due_to_error; break; @@ -94522,11 +94522,11 @@ case OP_ParseSchema: { /* Any prepared statement that invokes this opcode will hold mutexes ** on every btree. This is a prerequisite for invoking - ** tdsqlite3InitCallback(). + ** sqlite3InitCallback(). */ #ifdef SQLITE_DEBUG for(iDb=0; iDbnDb; iDb++){ - assert( iDb==1 || tdsqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); } #endif @@ -94536,9 +94536,9 @@ case OP_ParseSchema: { #ifndef SQLITE_OMIT_ALTERTABLE if( pOp->p4.z==0 ){ - tdsqlite3SchemaClear(db->aDb[iDb].pSchema); + sqlite3SchemaClear(db->aDb[iDb].pSchema); db->mDbFlags &= ~DBFLAG_SchemaKnownOk; - rc = tdsqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); + rc = sqlite3InitOne(db, iDb, &p->zErrMsg, INITFLAG_AlterTable); db->mDbFlags |= DBFLAG_SchemaChange; p->expired = 0; }else @@ -94549,7 +94549,7 @@ case OP_ParseSchema: { initData.iDb = iDb; initData.pzErrMsg = &p->zErrMsg; initData.mInitFlags = 0; - zSql = tdsqlite3MPrintf(db, + zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\".%s WHERE %s ORDER BY rowid", db->aDb[iDb].zDbSName, zMaster, pOp->p4.z); if( zSql==0 ){ @@ -94560,7 +94560,7 @@ case OP_ParseSchema: { initData.rc = SQLITE_OK; initData.nInitRow = 0; assert( !db->mallocFailed ); - rc = tdsqlite3_exec(db, zSql, tdsqlite3InitCallback, &initData, 0); + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); if( rc==SQLITE_OK ) rc = initData.rc; if( rc==SQLITE_OK && initData.nInitRow==0 ){ /* The OP_ParseSchema opcode with a non-NULL P4 argument should parse @@ -94568,12 +94568,12 @@ case OP_ParseSchema: { ** the sqlite_master table is corrupt. */ rc = SQLITE_CORRUPT_BKPT; } - tdsqlite3DbFreeNN(db, zSql); + sqlite3DbFreeNN(db, zSql); db->init.busy = 0; } } if( rc ){ - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ResetAllSchemasOfConnection(db); if( rc==SQLITE_NOMEM ){ goto no_mem; } @@ -94591,7 +94591,7 @@ case OP_ParseSchema: { */ case OP_LoadAnalysis: { assert( pOp->p1>=0 && pOp->p1nDb ); - rc = tdsqlite3AnalysisLoad(db, pOp->p1); + rc = sqlite3AnalysisLoad(db, pOp->p1); if( rc ) goto abort_due_to_error; break; } @@ -94606,8 +94606,8 @@ case OP_LoadAnalysis: { ** schema consistent with what is on disk. */ case OP_DropTable: { - tdsqlite3VdbeIncrWriteCounter(p, 0); - tdsqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteTable(db, pOp->p1, pOp->p4.z); break; } @@ -94620,8 +94620,8 @@ case OP_DropTable: { ** schema consistent with what is on disk. */ case OP_DropIndex: { - tdsqlite3VdbeIncrWriteCounter(p, 0); - tdsqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteIndex(db, pOp->p1, pOp->p4.z); break; } @@ -94634,8 +94634,8 @@ case OP_DropIndex: { ** schema consistent with what is on disk. */ case OP_DropTrigger: { - tdsqlite3VdbeIncrWriteCounter(p, 0); - tdsqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); + sqlite3VdbeIncrWriteCounter(p, 0); + sqlite3UnlinkAndDeleteTrigger(db, pOp->p1, pOp->p4.z); break; } @@ -94679,19 +94679,19 @@ case OP_IntegrityCk: { pIn1 = &aMem[pOp->p1]; assert( pOp->p5nDb ); assert( DbMaskTest(p->btreeMask, pOp->p5) ); - z = tdsqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, + z = sqlite3BtreeIntegrityCheck(db, db->aDb[pOp->p5].pBt, &aRoot[1], nRoot, (int)pnErr->u.i+1, &nErr); - tdsqlite3VdbeMemSetNull(pIn1); + sqlite3VdbeMemSetNull(pIn1); if( nErr==0 ){ assert( z==0 ); }else if( z==0 ){ goto no_mem; }else{ pnErr->u.i -= nErr-1; - tdsqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, tdsqlite3_free); + sqlite3VdbeMemSetStr(pIn1, z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); - tdsqlite3VdbeChangeEncoding(pIn1, encoding); + sqlite3VdbeChangeEncoding(pIn1, encoding); goto check_for_interrupt; } #endif /* SQLITE_OMIT_INTEGRITY_CHECK */ @@ -94709,10 +94709,10 @@ case OP_RowSetAdd: { /* in1, in2 */ pIn2 = &aMem[pOp->p2]; assert( (pIn2->flags & MEM_Int)!=0 ); if( (pIn1->flags & MEM_Blob)==0 ){ - if( tdsqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; } - assert( tdsqlite3VdbeMemIsRowSet(pIn1) ); - tdsqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i); + assert( sqlite3VdbeMemIsRowSet(pIn1) ); + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn2->u.i); break; } @@ -94728,18 +94728,18 @@ case OP_RowSetRead: { /* jump, in1, out3 */ i64 val; pIn1 = &aMem[pOp->p1]; - assert( (pIn1->flags & MEM_Blob)==0 || tdsqlite3VdbeMemIsRowSet(pIn1) ); + assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) ); if( (pIn1->flags & MEM_Blob)==0 - || tdsqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 + || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 ){ /* The boolean index is empty */ - tdsqlite3VdbeMemSetNull(pIn1); + sqlite3VdbeMemSetNull(pIn1); VdbeBranchTaken(1,2); goto jump_to_p2_and_check_for_interrupt; }else{ /* A value was pulled from the index */ VdbeBranchTaken(0,2); - tdsqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); + sqlite3VdbeMemSetInt64(&aMem[pOp->p3], val); } goto check_for_interrupt; } @@ -94780,18 +94780,18 @@ case OP_RowSetTest: { /* jump, in1, in3 */ ** delete it now and initialize P1 with an empty rowset */ if( (pIn1->flags & MEM_Blob)==0 ){ - if( tdsqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; + if( sqlite3VdbeMemSetRowSet(pIn1) ) goto no_mem; } - assert( tdsqlite3VdbeMemIsRowSet(pIn1) ); + assert( sqlite3VdbeMemIsRowSet(pIn1) ); assert( pOp->p4type==P4_INT32 ); assert( iSet==-1 || iSet>=0 ); if( iSet ){ - exists = tdsqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i); + exists = sqlite3RowSetTest((RowSet*)pIn1->z, iSet, pIn3->u.i); VdbeBranchTaken(exists!=0,2); if( exists ) goto jump_to_p2; } if( iSet>=0 ){ - tdsqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i); + sqlite3RowSetInsert((RowSet*)pIn1->z, pIn3->u.i); } break; } @@ -94847,7 +94847,7 @@ case OP_Program: { /* jump */ if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ rc = SQLITE_ERROR; - tdsqlite3VdbeError(p, "too many levels of trigger recursion"); + sqlite3VdbeError(p, "too many levels of trigger recursion"); goto abort_due_to_error; } @@ -94868,15 +94868,15 @@ case OP_Program: { /* jump */ + nMem * sizeof(Mem) + pProgram->nCsr * sizeof(VdbeCursor*) + (pProgram->nOp + 7)/8; - pFrame = tdsqlite3DbMallocZero(db, nByte); + pFrame = sqlite3DbMallocZero(db, nByte); if( !pFrame ){ goto no_mem; } - tdsqlite3VdbeMemRelease(pRt); + sqlite3VdbeMemRelease(pRt); pRt->flags = MEM_Blob|MEM_Dyn; pRt->z = (char*)pFrame; pRt->n = nByte; - pRt->xDel = tdsqlite3VdbeFrameMemDel; + pRt->xDel = sqlite3VdbeFrameMemDel; pFrame->v = p; pFrame->nChildMem = nMem; @@ -94903,7 +94903,7 @@ case OP_Program: { /* jump */ } }else{ pFrame = (VdbeFrame*)pRt->z; - assert( pRt->xDel==tdsqlite3VdbeFrameMemDel ); + assert( pRt->xDel==sqlite3VdbeFrameMemDel ); assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); assert( pProgram->nCsr==pFrame->nChildCsr ); @@ -94964,7 +94964,7 @@ case OP_Param: { /* out2 */ pOut = out2Prerelease(p, pOp); pFrame = p->pFrame; pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; - tdsqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); + sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); break; } @@ -95035,9 +95035,9 @@ case OP_MemMax: { /* in2 */ pIn1 = &aMem[pOp->p1]; } assert( memIsValid(pIn1) ); - tdsqlite3VdbeMemIntegerify(pIn1); + sqlite3VdbeMemIntegerify(pIn1); pIn2 = &aMem[pOp->p2]; - tdsqlite3VdbeMemIntegerify(pIn2); + sqlite3VdbeMemIntegerify(pIn2); if( pIn1->u.iu.i){ pIn1->u.i = pIn2->u.i; } @@ -95092,7 +95092,7 @@ case OP_OffsetLimit: { /* in1, out2, in3 */ assert( pIn1->flags & MEM_Int ); assert( pIn3->flags & MEM_Int ); x = pIn1->u.i; - if( x<=0 || tdsqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){ + if( x<=0 || sqlite3AddInt64(&x, pIn3->u.i>0?pIn3->u.i:0) ){ /* If the LIMIT is less than or equal to zero, loop forever. This ** is documented. But also, if the LIMIT+OFFSET exceeds 2^63 then ** also loop forever. This is undocumented. In fact, one could argue @@ -95176,27 +95176,27 @@ case OP_DecrJumpZero: { /* jump, in1 */ ** successors. ** ** This opcode is initially coded as OP_AggStep0. On first evaluation, -** the FuncDef stored in P4 is converted into an tdsqlite3_context and +** the FuncDef stored in P4 is converted into an sqlite3_context and ** the opcode is changed. In this way, the initialization of the -** tdsqlite3_context only happens once, instead of on each call to the +** sqlite3_context only happens once, instead of on each call to the ** step function. */ case OP_AggInverse: case OP_AggStep: { int n; - tdsqlite3_context *pCtx; + sqlite3_context *pCtx; assert( pOp->p4type==P4_FUNCDEF ); n = pOp->p5; assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); assert( pOp->p3p2 || pOp->p3>=pOp->p2+n ); - pCtx = tdsqlite3DbMallocRawNN(db, n*sizeof(tdsqlite3_value*) + - (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(tdsqlite3_value*))); + pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) + + (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*))); if( pCtx==0 ) goto no_mem; pCtx->pMem = 0; pCtx->pOut = (Mem*)&(pCtx->argv[n]); - tdsqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); + sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null); pCtx->pFunc = pOp->p4.pFunc; pCtx->iOp = (int)(pOp - aOp); pCtx->pVdbe = p; @@ -95214,7 +95214,7 @@ case OP_AggStep: { } case OP_AggStep1: { int i; - tdsqlite3_context *pCtx; + sqlite3_context *pCtx; Mem *pMem; assert( pOp->p4type==P4_FUNCCTX ); @@ -95235,7 +95235,7 @@ case OP_AggStep1: { /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it - ** reinitializes the relavant parts of the tdsqlite3_context object */ + ** reinitializes the relavant parts of the sqlite3_context object */ if( pCtx->pMem != pMem ){ pCtx->pMem = pMem; for(i=pCtx->argc-1; i>=0; i--) pCtx->argv[i] = &aMem[pOp->p2+i]; @@ -95261,16 +95261,16 @@ case OP_AggStep1: { if( pCtx->isError ){ if( pCtx->isError>0 ){ - tdsqlite3VdbeError(p, "%s", tdsqlite3_value_text(pCtx->pOut)); + sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut)); rc = pCtx->isError; } if( pCtx->skipFlag ){ assert( pOp[-1].opcode==OP_CollSeq ); i = pOp[-1].p1; - if( i ) tdsqlite3VdbeMemSetInt64(&aMem[i], 1); + if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1); pCtx->skipFlag = 0; } - tdsqlite3VdbeMemRelease(pCtx->pOut); + sqlite3VdbeMemRelease(pCtx->pOut); pCtx->pOut->flags = MEM_Null; pCtx->isError = 0; if( rc ) goto abort_due_to_error; @@ -95316,21 +95316,21 @@ case OP_AggFinal: { #ifndef SQLITE_OMIT_WINDOWFUNC if( pOp->p3 ){ memAboutToChange(p, &aMem[pOp->p3]); - rc = tdsqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc); + rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc); pMem = &aMem[pOp->p3]; }else #endif { - rc = tdsqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); + rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); } if( rc ){ - tdsqlite3VdbeError(p, "%s", tdsqlite3_value_text(pMem)); + sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); goto abort_due_to_error; } - tdsqlite3VdbeChangeEncoding(pMem, encoding); + sqlite3VdbeChangeEncoding(pMem, encoding); UPDATE_MAX_BLOBSIZE(pMem); - if( tdsqlite3VdbeMemTooBig(pMem) ){ + if( sqlite3VdbeMemTooBig(pMem) ){ goto too_big; } break; @@ -95361,14 +95361,14 @@ case OP_Checkpoint: { || pOp->p2==SQLITE_CHECKPOINT_RESTART || pOp->p2==SQLITE_CHECKPOINT_TRUNCATE ); - rc = tdsqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); + rc = sqlite3Checkpoint(db, pOp->p1, pOp->p2, &aRes[1], &aRes[2]); if( rc ){ if( rc!=SQLITE_BUSY ) goto abort_due_to_error; rc = SQLITE_OK; aRes[0] = 1; } for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){ - tdsqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); + sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); } break; }; @@ -95409,20 +95409,20 @@ case OP_JournalMode: { /* out2 */ assert( p->readOnly==0 ); pBt = db->aDb[pOp->p1].pBt; - pPager = tdsqlite3BtreePager(pBt); - eOld = tdsqlite3PagerGetJournalMode(pPager); + pPager = sqlite3BtreePager(pBt); + eOld = sqlite3PagerGetJournalMode(pPager); if( eNew==PAGER_JOURNALMODE_QUERY ) eNew = eOld; - if( !tdsqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; + if( !sqlite3PagerOkToChangeJournalMode(pPager) ) eNew = eOld; #ifndef SQLITE_OMIT_WAL - zFilename = tdsqlite3PagerFilename(pPager, 1); + zFilename = sqlite3PagerFilename(pPager, 1); /* Do not allow a transition to journal_mode=WAL for a database ** in temporary storage or if the VFS does not support shared memory */ if( eNew==PAGER_JOURNALMODE_WAL - && (tdsqlite3Strlen30(zFilename)==0 /* Temp file */ - || !tdsqlite3PagerWalSupported(pPager)) /* No shared-memory support */ + && (sqlite3Strlen30(zFilename)==0 /* Temp file */ + || !sqlite3PagerWalSupported(pPager)) /* No shared-memory support */ ){ eNew = eOld; } @@ -95432,7 +95432,7 @@ case OP_JournalMode: { /* out2 */ ){ if( !db->autoCommit || db->nVdbeRead>1 ){ rc = SQLITE_ERROR; - tdsqlite3VdbeError(p, + sqlite3VdbeError(p, "cannot change %s wal mode from within a transaction", (eNew==PAGER_JOURNALMODE_WAL ? "into" : "out of") ); @@ -95445,35 +95445,35 @@ case OP_JournalMode: { /* out2 */ ** file. An EXCLUSIVE lock may still be held on the database file ** after a successful return. */ - rc = tdsqlite3PagerCloseWal(pPager, db); + rc = sqlite3PagerCloseWal(pPager, db); if( rc==SQLITE_OK ){ - tdsqlite3PagerSetJournalMode(pPager, eNew); + sqlite3PagerSetJournalMode(pPager, eNew); } }else if( eOld==PAGER_JOURNALMODE_MEMORY ){ /* Cannot transition directly from MEMORY to WAL. Use mode OFF ** as an intermediate */ - tdsqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); + sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); } /* Open a transaction on the database file. Regardless of the journal ** mode, this transaction always uses a rollback journal. */ - assert( tdsqlite3BtreeIsInTrans(pBt)==0 ); + assert( sqlite3BtreeIsInTrans(pBt)==0 ); if( rc==SQLITE_OK ){ - rc = tdsqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); + rc = sqlite3BtreeSetVersion(pBt, (eNew==PAGER_JOURNALMODE_WAL ? 2 : 1)); } } } #endif /* ifndef SQLITE_OMIT_WAL */ if( rc ) eNew = eOld; - eNew = tdsqlite3PagerSetJournalMode(pPager, eNew); + eNew = sqlite3PagerSetJournalMode(pPager, eNew); pOut->flags = MEM_Str|MEM_Static|MEM_Term; - pOut->z = (char *)tdsqlite3JournalModename(eNew); - pOut->n = tdsqlite3Strlen30(pOut->z); + pOut->z = (char *)sqlite3JournalModename(eNew); + pOut->n = sqlite3Strlen30(pOut->z); pOut->enc = SQLITE_UTF8; - tdsqlite3VdbeChangeEncoding(pOut, encoding); + sqlite3VdbeChangeEncoding(pOut, encoding); if( rc ) goto abort_due_to_error; break; }; @@ -95491,7 +95491,7 @@ case OP_JournalMode: { /* out2 */ */ case OP_Vacuum: { assert( p->readOnly==0 ); - rc = tdsqlite3RunVacuum(&p->zErrMsg, db, pOp->p1, + rc = sqlite3RunVacuum(&p->zErrMsg, db, pOp->p1, pOp->p2 ? &aMem[pOp->p2] : 0); if( rc ) goto abort_due_to_error; break; @@ -95512,7 +95512,7 @@ case OP_IncrVacuum: { /* jump */ assert( DbMaskTest(p->btreeMask, pOp->p1) ); assert( p->readOnly==0 ); pBt = db->aDb[pOp->p1].pBt; - rc = tdsqlite3BtreeIncrVacuum(pBt); + rc = sqlite3BtreeIncrVacuum(pBt); VdbeBranchTaken(rc==SQLITE_DONE,2); if( rc ){ if( rc!=SQLITE_DONE ) goto abort_due_to_error; @@ -95526,8 +95526,8 @@ case OP_IncrVacuum: { /* jump */ /* Opcode: Expire P1 P2 * * * ** ** Cause precompiled statements to expire. When an expired statement -** is executed using tdsqlite3_step() it will either automatically -** reprepare itself (if it was originally created using tdsqlite3_prepare_v2()) +** is executed using sqlite3_step() it will either automatically +** reprepare itself (if it was originally created using sqlite3_prepare_v2()) ** or it will fail with SQLITE_SCHEMA. ** ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, @@ -95542,7 +95542,7 @@ case OP_IncrVacuum: { /* jump */ case OP_Expire: { assert( pOp->p2==0 || pOp->p2==1 ); if( !pOp->p1 ){ - tdsqlite3ExpirePreparedStatements(db, pOp->p2); + sqlite3ExpirePreparedStatements(db, pOp->p2); }else{ p->expired = pOp->p2+1; } @@ -95560,7 +95560,7 @@ case OP_CursorLock: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); - tdsqlite3BtreeCursorPin(pC->uc.pCursor); + sqlite3BtreeCursorPin(pC->uc.pCursor); break; } @@ -95575,7 +95575,7 @@ case OP_CursorUnlock: { pC = p->apCsr[pOp->p1]; assert( pC!=0 ); assert( pC->eCurType==CURTYPE_BTREE ); - tdsqlite3BtreeCursorUnpin(pC->uc.pCursor); + sqlite3BtreeCursorUnpin(pC->uc.pCursor); break; } @@ -95602,11 +95602,11 @@ case OP_TableLock: { assert( p1>=0 && p1nDb ); assert( DbMaskTest(p->btreeMask, p1) ); assert( isWriteLock==0 || isWriteLock==1 ); - rc = tdsqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); + rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock); if( rc ){ if( (rc&0xFF)==SQLITE_LOCKED ){ const char *z = pOp->p4.z; - tdsqlite3VdbeError(p, "database table is locked: %s", z); + sqlite3VdbeError(p, "database table is locked: %s", z); } goto abort_due_to_error; } @@ -95618,7 +95618,7 @@ case OP_TableLock: { #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VBegin * * * P4 * ** -** P4 may be a pointer to an tdsqlite3_vtab structure. If so, call the +** P4 may be a pointer to an sqlite3_vtab structure. If so, call the ** xBegin method for that table. ** ** Also, whether or not P4 is set, check that this is not being called from @@ -95628,8 +95628,8 @@ case OP_TableLock: { case OP_VBegin: { VTable *pVTab; pVTab = pOp->p4.pVtab; - rc = tdsqlite3VtabBegin(db, pVTab); - if( pVTab ) tdsqlite3VtabImportErrmsg(p, pVTab->pVtab); + rc = sqlite3VtabBegin(db, pVTab); + if( pVTab ) sqlite3VtabImportErrmsg(p, pVTab->pVtab); if( rc ) goto abort_due_to_error; break; } @@ -95648,17 +95648,17 @@ case OP_VCreate: { memset(&sMem, 0, sizeof(sMem)); sMem.db = db; /* Because P2 is always a static string, it is impossible for the - ** tdsqlite3VdbeMemCopy() to fail */ + ** sqlite3VdbeMemCopy() to fail */ assert( (aMem[pOp->p2].flags & MEM_Str)!=0 ); assert( (aMem[pOp->p2].flags & MEM_Static)!=0 ); - rc = tdsqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]); + rc = sqlite3VdbeMemCopy(&sMem, &aMem[pOp->p2]); assert( rc==SQLITE_OK ); - zTab = (const char*)tdsqlite3_value_text(&sMem); + zTab = (const char*)sqlite3_value_text(&sMem); assert( zTab || db->mallocFailed ); if( zTab ){ - rc = tdsqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg); + rc = sqlite3VtabCallCreate(db, pOp->p1, zTab, &p->zErrMsg); } - tdsqlite3VdbeMemRelease(&sMem); + sqlite3VdbeMemRelease(&sMem); if( rc ) goto abort_due_to_error; break; } @@ -95672,7 +95672,7 @@ case OP_VCreate: { */ case OP_VDestroy: { db->nVDestroy++; - rc = tdsqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z); + rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z); db->nVDestroy--; assert( p->errorAction==OE_Abort && p->usesStmtJournal ); if( rc ) goto abort_due_to_error; @@ -95683,15 +95683,15 @@ case OP_VDestroy: { #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VOpen P1 * * P4 * ** -** P4 is a pointer to a virtual table object, an tdsqlite3_vtab structure. +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** P1 is a cursor number. This opcode opens a cursor to the virtual ** table and stores that cursor in P1. */ case OP_VOpen: { VdbeCursor *pCur; - tdsqlite3_vtab_cursor *pVCur; - tdsqlite3_vtab *pVtab; - const tdsqlite3_module *pModule; + sqlite3_vtab_cursor *pVCur; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; assert( p->bIsReader ); pCur = 0; @@ -95703,10 +95703,10 @@ case OP_VOpen: { } pModule = pVtab->pModule; rc = pModule->xOpen(pVtab, &pVCur); - tdsqlite3VtabImportErrmsg(p, pVtab); + sqlite3VtabImportErrmsg(p, pVtab); if( rc ) goto abort_due_to_error; - /* Initialize tdsqlite3_vtab_cursor base class */ + /* Initialize sqlite3_vtab_cursor base class */ pVCur->pVtab = pVtab; /* Initialize vdbe cursor object */ @@ -95746,11 +95746,11 @@ case OP_VOpen: { case OP_VFilter: { /* jump */ int nArg; int iQuery; - const tdsqlite3_module *pModule; + const sqlite3_module *pModule; Mem *pQuery; Mem *pArgc; - tdsqlite3_vtab_cursor *pVCur; - tdsqlite3_vtab *pVtab; + sqlite3_vtab_cursor *pVCur; + sqlite3_vtab *pVtab; VdbeCursor *pCur; int res; int i; @@ -95778,7 +95778,7 @@ case OP_VFilter: { /* jump */ apArg[i] = &pArgc[i+1]; } rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg); - tdsqlite3VtabImportErrmsg(p, pVtab); + sqlite3VtabImportErrmsg(p, pVtab); if( rc ) goto abort_due_to_error; res = pModule->xEof(pVCur); pCur->nullRow = 0; @@ -95797,17 +95797,17 @@ case OP_VFilter: { /* jump */ ** ** If the VColumn opcode is being used to fetch the value of ** an unchanging column during an UPDATE operation, then the P5 -** value is OPFLAG_NOCHNG. This will cause the tdsqlite3_vtab_nochange() +** value is OPFLAG_NOCHNG. This will cause the sqlite3_vtab_nochange() ** function to return true inside the xColumn method of the virtual ** table implementation. The P5 column might also contain other ** bits (OPFLAG_LENGTHARG or OPFLAG_TYPEOFARG) but those bits are ** unused by OP_VColumn. */ case OP_VColumn: { - tdsqlite3_vtab *pVtab; - const tdsqlite3_module *pModule; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; Mem *pDest; - tdsqlite3_context sContext; + sqlite3_context sContext; VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->eCurType==CURTYPE_VTAB ); @@ -95815,7 +95815,7 @@ case OP_VColumn: { pDest = &aMem[pOp->p3]; memAboutToChange(p, pDest); if( pCur->nullRow ){ - tdsqlite3VdbeMemSetNull(pDest); + sqlite3VdbeMemSetNull(pDest); break; } pVtab = pCur->uc.pVCur->pVtab; @@ -95825,23 +95825,23 @@ case OP_VColumn: { sContext.pOut = pDest; assert( pOp->p5==OPFLAG_NOCHNG || pOp->p5==0 ); if( pOp->p5 & OPFLAG_NOCHNG ){ - tdsqlite3VdbeMemSetNull(pDest); + sqlite3VdbeMemSetNull(pDest); pDest->flags = MEM_Null|MEM_Zero; pDest->u.nZero = 0; }else{ MemSetTypeFlag(pDest, MEM_Null); } rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2); - tdsqlite3VtabImportErrmsg(p, pVtab); + sqlite3VtabImportErrmsg(p, pVtab); if( sContext.isError>0 ){ - tdsqlite3VdbeError(p, "%s", tdsqlite3_value_text(pDest)); + sqlite3VdbeError(p, "%s", sqlite3_value_text(pDest)); rc = sContext.isError; } - tdsqlite3VdbeChangeEncoding(pDest, encoding); + sqlite3VdbeChangeEncoding(pDest, encoding); REGISTER_TRACE(pOp->p3, pDest); UPDATE_MAX_BLOBSIZE(pDest); - if( tdsqlite3VdbeMemTooBig(pDest) ){ + if( sqlite3VdbeMemTooBig(pDest) ){ goto too_big; } if( rc ) goto abort_due_to_error; @@ -95857,8 +95857,8 @@ case OP_VColumn: { ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { /* jump */ - tdsqlite3_vtab *pVtab; - const tdsqlite3_module *pModule; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; int res; VdbeCursor *pCur; @@ -95879,7 +95879,7 @@ case OP_VNext: { /* jump */ ** some other method is next invoked on the save virtual table cursor. */ rc = pModule->xNext(pCur->uc.pVCur); - tdsqlite3VtabImportErrmsg(p, pVtab); + sqlite3VtabImportErrmsg(p, pVtab); if( rc ) goto abort_due_to_error; res = pModule->xEof(pCur->uc.pVCur); VdbeBranchTaken(!res,2); @@ -95894,12 +95894,12 @@ case OP_VNext: { /* jump */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VRename P1 * * P4 * ** -** P4 is a pointer to a virtual table object, an tdsqlite3_vtab structure. +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xRename method. The value ** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { - tdsqlite3_vtab *pVtab; + sqlite3_vtab *pVtab; Mem *pName; int isLegacy; @@ -95915,11 +95915,11 @@ case OP_VRename: { testcase( pName->enc==SQLITE_UTF8 ); testcase( pName->enc==SQLITE_UTF16BE ); testcase( pName->enc==SQLITE_UTF16LE ); - rc = tdsqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); + rc = sqlite3VdbeChangeEncoding(pName, SQLITE_UTF8); if( rc ) goto abort_due_to_error; rc = pVtab->pModule->xRename(pVtab, pName->z); if( isLegacy==0 ) db->flags &= ~(u64)SQLITE_LegacyAlter; - tdsqlite3VtabImportErrmsg(p, pVtab); + sqlite3VtabImportErrmsg(p, pVtab); p->expired = 0; if( rc ) goto abort_due_to_error; break; @@ -95930,7 +95930,7 @@ case OP_VRename: { /* Opcode: VUpdate P1 P2 P3 P4 P5 ** Synopsis: data=r[P3@P2] ** -** P4 is a pointer to a virtual table object, an tdsqlite3_vtab structure. +** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xUpdate method. P2 values ** are contiguous memory cells starting at P3 to pass to the xUpdate ** invocation. The value in register (P3+P2-1) corresponds to the @@ -95948,15 +95948,15 @@ case OP_VRename: { ** a row to delete. ** ** P1 is a boolean flag. If it is set to true and the xUpdate call -** is successful, then the value returned by tdsqlite3_last_insert_rowid() +** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. ** ** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to ** apply in the case of a constraint failure on an insert or update. */ case OP_VUpdate: { - tdsqlite3_vtab *pVtab; - const tdsqlite3_module *pModule; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; int nArg; int i; sqlite_int64 rowid; @@ -95968,7 +95968,7 @@ case OP_VUpdate: { ); assert( p->readOnly==0 ); if( db->mallocFailed ) goto no_mem; - tdsqlite3VdbeIncrWriteCounter(p, 0); + sqlite3VdbeIncrWriteCounter(p, 0); pVtab = pOp->p4.pVtab->pVtab; if( pVtab==0 || NEVER(pVtab->pModule==0) ){ rc = SQLITE_LOCKED; @@ -95990,7 +95990,7 @@ case OP_VUpdate: { db->vtabOnConflict = pOp->p5; rc = pModule->xUpdate(pVtab, nArg, apArg, &rowid); db->vtabOnConflict = vtabOnConflict; - tdsqlite3VtabImportErrmsg(p, pVtab); + sqlite3VtabImportErrmsg(p, pVtab); if( rc==SQLITE_OK && pOp->p1 ){ assert( nArg>1 && apArg[0] && (apArg[0]->flags&MEM_Null) ); db->lastRowid = rowid; @@ -96017,7 +96017,7 @@ case OP_VUpdate: { */ case OP_Pagecount: { /* out2 */ pOut = out2Prerelease(p, pOp); - pOut->u.i = tdsqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); + pOut->u.i = sqlite3BtreeLastPage(db->aDb[pOp->p1].pBt); break; } #endif @@ -96040,10 +96040,10 @@ case OP_MaxPgcnt: { /* out2 */ pBt = db->aDb[pOp->p1].pBt; newMax = 0; if( pOp->p3 ){ - newMax = tdsqlite3BtreeLastPage(pBt); + newMax = sqlite3BtreeLastPage(pBt); if( newMax < (unsigned)pOp->p3 ) newMax = (unsigned)pOp->p3; } - pOut->u.i = tdsqlite3BtreeMaxPageCount(pBt, newMax); + pOut->u.i = sqlite3BtreeMaxPageCount(pBt, newMax); break; } #endif @@ -96051,10 +96051,10 @@ case OP_MaxPgcnt: { /* out2 */ /* Opcode: Function P1 P2 P3 P4 * ** Synopsis: r[P3]=func(r[P2@P5]) ** -** Invoke a user function (P4 is a pointer to an tdsqlite3_context object that +** Invoke a user function (P4 is a pointer to an sqlite3_context object that ** contains a pointer to the function to be run) with arguments taken ** from register P2 and successors. The number of arguments is in -** the tdsqlite3_context object that P4 points to. +** the sqlite3_context object that P4 points to. ** The result of the function is stored ** in register P3. Register P3 must not be one of the function inputs. ** @@ -96062,7 +96062,7 @@ case OP_MaxPgcnt: { /* out2 */ ** function was determined to be constant at compile time. If the first ** argument was constant then bit 0 of P1 is set. This is used to determine ** whether meta data associated with a user function argument using the -** tdsqlite3_set_auxdata() API may be safely retained until the next +** sqlite3_set_auxdata() API may be safely retained until the next ** invocation of this opcode. ** ** See also: AggStep, AggFinal, PureFunc @@ -96070,10 +96070,10 @@ case OP_MaxPgcnt: { /* out2 */ /* Opcode: PureFunc P1 P2 P3 P4 * ** Synopsis: r[P3]=func(r[P2@P5]) ** -** Invoke a user function (P4 is a pointer to an tdsqlite3_context object that +** Invoke a user function (P4 is a pointer to an sqlite3_context object that ** contains a pointer to the function to be run) with arguments taken ** from register P2 and successors. The number of arguments is in -** the tdsqlite3_context object that P4 points to. +** the sqlite3_context object that P4 points to. ** The result of the function is stored ** in register P3. Register P3 must not be one of the function inputs. ** @@ -96081,7 +96081,7 @@ case OP_MaxPgcnt: { /* out2 */ ** function was determined to be constant at compile time. If the first ** argument was constant then bit 0 of P1 is set. This is used to determine ** whether meta data associated with a user function argument using the -** tdsqlite3_set_auxdata() API may be safely retained until the next +** sqlite3_set_auxdata() API may be safely retained until the next ** invocation of this opcode. ** ** This opcode works exactly like OP_Function. The only difference is in @@ -96097,7 +96097,7 @@ case OP_MaxPgcnt: { /* out2 */ case OP_PureFunc: /* group */ case OP_Function: { /* group */ int i; - tdsqlite3_context *pCtx; + sqlite3_context *pCtx; assert( pOp->p4type==P4_FUNCCTX ); pCtx = pOp->p4.pCtx; @@ -96105,7 +96105,7 @@ case OP_Function: { /* group */ /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it - ** reinitializes the relavant parts of the tdsqlite3_context object */ + ** reinitializes the relavant parts of the sqlite3_context object */ pOut = &aMem[pOp->p3]; if( pCtx->pOut != pOut ){ pCtx->pVdbe = p; @@ -96128,18 +96128,18 @@ case OP_Function: { /* group */ /* If the function returned an error, throw an exception */ if( pCtx->isError ){ if( pCtx->isError>0 ){ - tdsqlite3VdbeError(p, "%s", tdsqlite3_value_text(pOut)); + sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut)); rc = pCtx->isError; } - tdsqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); + sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1); pCtx->isError = 0; if( rc ) goto abort_due_to_error; } /* Copy the result of the function into register P3 */ if( pOut->flags & (MEM_Str|MEM_Blob) ){ - tdsqlite3VdbeChangeEncoding(pOut, encoding); - if( tdsqlite3VdbeMemTooBig(pOut) ) goto too_big; + sqlite3VdbeChangeEncoding(pOut, encoding); + if( sqlite3VdbeMemTooBig(pOut) ) goto too_big; } REGISTER_TRACE(pOp->p3, pOut); @@ -96160,9 +96160,9 @@ case OP_Function: { /* group */ ** Programs contain a single instance of this opcode as the very first ** opcode. ** -** If tracing is enabled (by the tdsqlite3_trace()) interface, then +** If tracing is enabled (by the sqlite3_trace()) interface, then ** the UTF-8 string contained in P4 is emitted on the trace callback. -** Or if P4 is blank, use the string returned by tdsqlite3_sql(). +** Or if P4 is blank, use the string returned by sqlite3_sql(). ** ** If P2 is not zero, jump to instruction P2. ** @@ -96184,9 +96184,9 @@ case OP_Init: { /* jump */ ** ** This assert() provides evidence for: ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that - ** would have been returned by the legacy tdsqlite3_trace() interface by + ** would have been returned by the legacy sqlite3_trace() interface by ** using the X argument when X begins with "--" and invoking - ** tdsqlite3_expanded_sql(P) otherwise. + ** sqlite3_expanded_sql(P) otherwise. */ assert( pOp->p4.z==0 || strncmp(pOp->p4.z, "-" "- ", 3)==0 ); @@ -96201,15 +96201,15 @@ case OP_Init: { /* jump */ #ifndef SQLITE_OMIT_DEPRECATED if( db->mTrace & SQLITE_TRACE_LEGACY ){ void (*x)(void*,const char*) = (void(*)(void*,const char*))db->xTrace; - char *z = tdsqlite3VdbeExpandSql(p, zTrace); + char *z = sqlite3VdbeExpandSql(p, zTrace); x(db->pTraceArg, z); - tdsqlite3_free(z); + sqlite3_free(z); }else #endif if( db->nVdbeExec>1 ){ - char *z = tdsqlite3MPrintf(db, "-- %s", zTrace); + char *z = sqlite3MPrintf(db, "-- %s", zTrace); (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, z); - tdsqlite3DbFree(db, z); + sqlite3DbFree(db, z); }else{ (void)db->xTrace(SQLITE_TRACE_STMT, db->pTraceArg, p, zTrace); } @@ -96220,7 +96220,7 @@ case OP_Init: { /* jump */ int j; for(j=0; jnDb; j++){ if( DbMaskTest(p->btreeMask, j)==0 ) continue; - tdsqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace); + sqlite3_file_control(db, db->aDb[j].zDbSName, SQLITE_FCNTL_TRACE, zTrace); } } #endif /* SQLITE_USE_FCNTL_TRACE */ @@ -96228,12 +96228,12 @@ case OP_Init: { /* jump */ if( (db->flags & SQLITE_SqlTrace)!=0 && (zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ - tdsqlite3DebugPrintf("SQL-trace: %s\n", zTrace); + sqlite3DebugPrintf("SQL-trace: %s\n", zTrace); } #endif /* SQLITE_DEBUG */ #endif /* SQLITE_OMIT_TRACE */ assert( pOp->p2>0 ); - if( pOp->p1>=tdsqlite3GlobalConfig.iOnceResetThreshold ){ + if( pOp->p1>=sqlite3GlobalConfig.iOnceResetThreshold ){ if( pOp->opcode==OP_Trace ) break; for(i=1; inOp; i++){ if( p->aOp[i].opcode==OP_Once ) p->aOp[i].p1 = 0; @@ -96261,7 +96261,7 @@ case OP_CursorHint: { pC = p->apCsr[pOp->p1]; if( pC ){ assert( pC->eCurType==CURTYPE_BTREE ); - tdsqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, + sqlite3BtreeCursorHint(pC->uc.pCursor, BTREE_HINT_RANGE, pOp->p4.pExpr, aMem); } break; @@ -96279,7 +96279,7 @@ case OP_CursorHint: { ** an active statement journal. */ case OP_Abortable: { - tdsqlite3VdbeAssertAbortable(p); + sqlite3VdbeAssertAbortable(p); break; } #endif @@ -96298,7 +96298,7 @@ case OP_Abortable: { ** Releasing a register clears the Mem.pScopyFrom pointer. That means ** that if the content of the released register was set using OP_SCopy, ** a change to the value of the source register for the OP_SCopy will no longer -** generate an assertion fault in tdsqlite3VdbeMemAboutToChange(). +** generate an assertion fault in sqlite3VdbeMemAboutToChange(). ** ** If P5 is set, then all released registers have their type set ** to MEM_Undefined so that any subsequent attempt to read the released @@ -96360,7 +96360,7 @@ default: { /* This is really OP_Noop, OP_Explain */ #ifdef VDBE_PROFILE { - u64 endTime = tdsqlite3NProfileCnt ? tdsqlite3NProfileCnt : tdsqlite3Hwtime(); + u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime(); if( endTime>start ) pOrigOp->cycles += endTime - start; pOrigOp->cnt++; } @@ -96376,7 +96376,7 @@ default: { /* This is really OP_Noop, OP_Explain */ #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeTrace ){ - u8 opProperty = tdsqlite3OpcodeProperty[pOrigOp->opcode]; + u8 opProperty = sqlite3OpcodeProperty[pOrigOp->opcode]; if( rc!=0 ) printf("rc=%d\n",rc); if( opProperty & (OPFLG_OUT2) ){ registerTrace(pOrigOp->p2, &aMem[pOrigOp->p2]); @@ -96386,9 +96386,9 @@ default: { /* This is really OP_Noop, OP_Explain */ } if( opProperty==0xff ){ /* Never happens. This code exists to avoid a harmless linkage - ** warning aboud tdsqlite3VdbeRegisterDump() being defined but not + ** warning aboud sqlite3VdbeRegisterDump() being defined but not ** used. */ - tdsqlite3VdbeRegisterDump(p); + sqlite3VdbeRegisterDump(p); } } #endif /* SQLITE_DEBUG */ @@ -96402,18 +96402,18 @@ abort_due_to_error: if( db->mallocFailed ) rc = SQLITE_NOMEM_BKPT; assert( rc ); if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ - tdsqlite3VdbeError(p, "%s", tdsqlite3ErrStr(rc)); + sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); } p->rc = rc; - tdsqlite3SystemError(db, rc); - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - tdsqlite3_log(rc, "statement aborts at %d: [%s] %s", + sqlite3SystemError(db, rc); + testcase( sqlite3GlobalConfig.xLog!=0 ); + sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); - tdsqlite3VdbeHalt(p); - if( rc==SQLITE_IOERR_NOMEM ) tdsqlite3OomFault(db); + sqlite3VdbeHalt(p); + if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); rc = SQLITE_ERROR; if( resetSchemaOnFault>0 ){ - tdsqlite3ResetOneSchema(db, resetSchemaOnFault-1); + sqlite3ResetOneSchema(db, resetSchemaOnFault-1); } /* This is the only way out of this procedure. We have to @@ -96431,9 +96431,9 @@ vdbe_return: } #endif p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep; - tdsqlite3VdbeLeave(p); + sqlite3VdbeLeave(p); assert( rc!=SQLITE_OK || nExtraDelete==0 - || tdsqlite3_strlike("DELETE%",p->zSql,0)!=0 + || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); return rc; @@ -96441,26 +96441,26 @@ vdbe_return: ** is encountered. */ too_big: - tdsqlite3VdbeError(p, "string or blob too big"); + sqlite3VdbeError(p, "string or blob too big"); rc = SQLITE_TOOBIG; goto abort_due_to_error; /* Jump to here if a malloc() fails. */ no_mem: - tdsqlite3OomFault(db); - tdsqlite3VdbeError(p, "out of memory"); + sqlite3OomFault(db); + sqlite3VdbeError(p, "out of memory"); rc = SQLITE_NOMEM_BKPT; goto abort_due_to_error; - /* Jump to here if the tdsqlite3_interrupt() API sets the interrupt + /* Jump to here if the sqlite3_interrupt() API sets the interrupt ** flag. */ abort_due_to_interrupt: assert( db->u1.isInterrupted ); rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; p->rc = rc; - tdsqlite3VdbeError(p, "%s", tdsqlite3ErrStr(rc)); + sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); goto abort_due_to_error; } @@ -96488,7 +96488,7 @@ abort_due_to_interrupt: #ifndef SQLITE_OMIT_INCRBLOB /* -** Valid tdsqlite3_blob* handles point to Incrblob structures. +** Valid sqlite3_blob* handles point to Incrblob structures. */ typedef struct Incrblob Incrblob; struct Incrblob { @@ -96496,8 +96496,8 @@ struct Incrblob { int iOffset; /* Byte offset of blob in cursor data */ u16 iCol; /* Table column this handle is open on */ BtCursor *pCsr; /* Cursor pointing at blob row */ - tdsqlite3_stmt *pStmt; /* Statement holding cursor open */ - tdsqlite3 *db; /* The associated database */ + sqlite3_stmt *pStmt; /* Statement holding cursor open */ + sqlite3 *db; /* The associated database */ char *zDb; /* Database name */ Table *pTab; /* Table object */ }; @@ -96507,20 +96507,20 @@ struct Incrblob { ** This function is used by both blob_open() and blob_reopen(). It seeks ** the b-tree cursor associated with blob handle p to point to row iRow. ** If successful, SQLITE_OK is returned and subsequent calls to -** tdsqlite3_blob_read() or tdsqlite3_blob_write() access the specified row. +** sqlite3_blob_read() or sqlite3_blob_write() access the specified row. ** ** If an error occurs, or if the specified row does not exist or does not ** contain a value of type TEXT or BLOB in the column nominated when the ** blob handle was opened, then an error code is returned and *pzErr may ** be set to point to a buffer containing an error message. It is the ** responsibility of the caller to free the error message buffer using -** tdsqlite3DbFree(). +** sqlite3DbFree(). ** ** If an error does occur, then the b-tree cursor is closed. All subsequent -** calls to tdsqlite3_blob_read(), blob_write() or blob_reopen() will +** calls to sqlite3_blob_read(), blob_write() or blob_reopen() will ** immediately return SQLITE_ABORT. */ -static int blobSeekToRow(Incrblob *p, tdsqlite3_int64 iRow, char **pzErr){ +static int blobSeekToRow(Incrblob *p, sqlite3_int64 iRow, char **pzErr){ int rc; /* Error code */ char *zErr = 0; /* Error message */ Vdbe *v = (Vdbe *)p->pStmt; @@ -96538,9 +96538,9 @@ static int blobSeekToRow(Incrblob *p, tdsqlite3_int64 iRow, char **pzErr){ if( v->pc>4 ){ v->pc = 4; assert( v->aOp[v->pc].opcode==OP_NotExists ); - rc = tdsqlite3VdbeExec(v); + rc = sqlite3VdbeExec(v); }else{ - rc = tdsqlite3_step(p->pStmt); + rc = sqlite3_step(p->pStmt); } if( rc==SQLITE_ROW ){ VdbeCursor *pC = v->apCsr[0]; @@ -96548,30 +96548,30 @@ static int blobSeekToRow(Incrblob *p, tdsqlite3_int64 iRow, char **pzErr){ testcase( pC->nHdrParsed==p->iCol ); testcase( pC->nHdrParsed==p->iCol+1 ); if( type<12 ){ - zErr = tdsqlite3MPrintf(p->db, "cannot open value of type %s", + zErr = sqlite3MPrintf(p->db, "cannot open value of type %s", type==0?"null": type==7?"real": "integer" ); rc = SQLITE_ERROR; - tdsqlite3_finalize(p->pStmt); + sqlite3_finalize(p->pStmt); p->pStmt = 0; }else{ p->iOffset = pC->aType[p->iCol + pC->nField]; - p->nByte = tdsqlite3VdbeSerialTypeLen(type); + p->nByte = sqlite3VdbeSerialTypeLen(type); p->pCsr = pC->uc.pCursor; - tdsqlite3BtreeIncrblobCursor(p->pCsr); + sqlite3BtreeIncrblobCursor(p->pCsr); } } if( rc==SQLITE_ROW ){ rc = SQLITE_OK; }else if( p->pStmt ){ - rc = tdsqlite3_finalize(p->pStmt); + rc = sqlite3_finalize(p->pStmt); p->pStmt = 0; if( rc==SQLITE_OK ){ - zErr = tdsqlite3MPrintf(p->db, "no such rowid: %lld", iRow); + zErr = sqlite3MPrintf(p->db, "no such rowid: %lld", iRow); rc = SQLITE_ERROR; }else{ - zErr = tdsqlite3MPrintf(p->db, "%s", tdsqlite3_errmsg(p->db)); + zErr = sqlite3MPrintf(p->db, "%s", sqlite3_errmsg(p->db)); } } @@ -96585,14 +96585,14 @@ static int blobSeekToRow(Incrblob *p, tdsqlite3_int64 iRow, char **pzErr){ /* ** Open a blob handle. */ -SQLITE_API int tdsqlite3_blob_open( - tdsqlite3* db, /* The database connection */ +SQLITE_API int sqlite3_blob_open( + sqlite3* db, /* The database connection */ const char *zDb, /* The attached database containing the blob */ const char *zTable, /* The table containing the blob */ const char *zColumn, /* The column containing the blob */ sqlite_int64 iRow, /* The row containing the glob */ int wrFlag, /* True -> read/write access, false -> read-only */ - tdsqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ + sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ ){ int nAttempt = 0; int iCol; /* Index of zColumn in row-record */ @@ -96609,62 +96609,62 @@ SQLITE_API int tdsqlite3_blob_open( #endif *ppBlob = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zTable==0 ){ + if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ return SQLITE_MISUSE_BKPT; } #endif wrFlag = !!wrFlag; /* wrFlag = (wrFlag ? 1 : 0); */ - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); - pBlob = (Incrblob *)tdsqlite3DbMallocZero(db, sizeof(Incrblob)); + pBlob = (Incrblob *)sqlite3DbMallocZero(db, sizeof(Incrblob)); do { memset(&sParse, 0, sizeof(Parse)); if( !pBlob ) goto blob_open_out; sParse.db = db; - tdsqlite3DbFree(db, zErr); + sqlite3DbFree(db, zErr); zErr = 0; - tdsqlite3BtreeEnterAll(db); - pTab = tdsqlite3LocateTable(&sParse, 0, zTable, zDb); + sqlite3BtreeEnterAll(db); + pTab = sqlite3LocateTable(&sParse, 0, zTable, zDb); if( pTab && IsVirtual(pTab) ){ pTab = 0; - tdsqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable); + sqlite3ErrorMsg(&sParse, "cannot open virtual table: %s", zTable); } if( pTab && !HasRowid(pTab) ){ pTab = 0; - tdsqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); + sqlite3ErrorMsg(&sParse, "cannot open table without rowid: %s", zTable); } #ifndef SQLITE_OMIT_VIEW if( pTab && pTab->pSelect ){ pTab = 0; - tdsqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); + sqlite3ErrorMsg(&sParse, "cannot open view: %s", zTable); } #endif if( !pTab ){ if( sParse.zErrMsg ){ - tdsqlite3DbFree(db, zErr); + sqlite3DbFree(db, zErr); zErr = sParse.zErrMsg; sParse.zErrMsg = 0; } rc = SQLITE_ERROR; - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); goto blob_open_out; } pBlob->pTab = pTab; - pBlob->zDb = db->aDb[tdsqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; + pBlob->zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName; /* Now search pTab for the exact column. */ for(iCol=0; iColnCol; iCol++) { - if( tdsqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ + if( sqlite3StrICmp(pTab->aCol[iCol].zName, zColumn)==0 ){ break; } } if( iCol==pTab->nCol ){ - tdsqlite3DbFree(db, zErr); - zErr = tdsqlite3MPrintf(db, "no such column: \"%s\"", zColumn); + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "no such column: \"%s\"", zColumn); rc = SQLITE_ERROR; - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); goto blob_open_out; } @@ -96701,15 +96701,15 @@ SQLITE_API int tdsqlite3_blob_open( } } if( zFault ){ - tdsqlite3DbFree(db, zErr); - zErr = tdsqlite3MPrintf(db, "cannot open %s column for writing", zFault); + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); rc = SQLITE_ERROR; - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); goto blob_open_out; } } - pBlob->pStmt = (tdsqlite3_stmt *)tdsqlite3VdbeCreate(&sParse); + pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(&sParse); assert( pBlob->pStmt || db->mallocFailed ); if( pBlob->pStmt ){ @@ -96724,7 +96724,7 @@ SQLITE_API int tdsqlite3_blob_open( ** uses it to implement the blob_read(), blob_write() and ** blob_bytes() functions. ** - ** The tdsqlite3_blob_close() function finalizes the vdbe program, + ** The sqlite3_blob_close() function finalizes the vdbe program, ** which closes the b-tree cursor and (possibly) commits the ** transaction. */ @@ -96739,18 +96739,18 @@ SQLITE_API int tdsqlite3_blob_open( {OP_Halt, 0, 0, 0}, /* 5 */ }; Vdbe *v = (Vdbe *)pBlob->pStmt; - int iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); VdbeOp *aOp; - tdsqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, + sqlite3VdbeAddOp4Int(v, OP_Transaction, iDb, wrFlag, pTab->pSchema->schema_cookie, pTab->pSchema->iGeneration); - tdsqlite3VdbeChangeP5(v, 1); - assert( tdsqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed ); - aOp = tdsqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); + sqlite3VdbeChangeP5(v, 1); + assert( sqlite3VdbeCurrentAddr(v)==2 || db->mallocFailed ); + aOp = sqlite3VdbeAddOpList(v, ArraySize(openBlob), openBlob, iLn); /* Make sure a mutex is held on the table to be accessed */ - tdsqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeUsesBtree(v, iDb); if( db->mallocFailed==0 ){ assert( aOp!=0 ); @@ -96761,7 +96761,7 @@ SQLITE_API int tdsqlite3_blob_open( aOp[0].p1 = iDb; aOp[0].p2 = pTab->tnum; aOp[0].p3 = wrFlag; - tdsqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); + sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); } if( db->mallocFailed==0 ){ #endif @@ -96786,13 +96786,13 @@ SQLITE_API int tdsqlite3_blob_open( sParse.nVar = 0; sParse.nMem = 1; sParse.nTab = 1; - tdsqlite3VdbeMakeReady(v, &sParse); + sqlite3VdbeMakeReady(v, &sParse); } } pBlob->iCol = iCol; pBlob->db = db; - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); if( db->mallocFailed ){ goto blob_open_out; } @@ -96801,35 +96801,35 @@ SQLITE_API int tdsqlite3_blob_open( blob_open_out: if( rc==SQLITE_OK && db->mallocFailed==0 ){ - *ppBlob = (tdsqlite3_blob *)pBlob; + *ppBlob = (sqlite3_blob *)pBlob; }else{ - if( pBlob && pBlob->pStmt ) tdsqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); - tdsqlite3DbFree(db, pBlob); + if( pBlob && pBlob->pStmt ) sqlite3VdbeFinalize((Vdbe *)pBlob->pStmt); + sqlite3DbFree(db, pBlob); } - tdsqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); - tdsqlite3DbFree(db, zErr); - tdsqlite3ParserReset(&sParse); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); + sqlite3DbFree(db, zErr); + sqlite3ParserReset(&sParse); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } /* ** Close a blob handle that was previously created using -** tdsqlite3_blob_open(). +** sqlite3_blob_open(). */ -SQLITE_API int tdsqlite3_blob_close(tdsqlite3_blob *pBlob){ +SQLITE_API int sqlite3_blob_close(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; int rc; - tdsqlite3 *db; + sqlite3 *db; if( p ){ - tdsqlite3_stmt *pStmt = p->pStmt; + sqlite3_stmt *pStmt = p->pStmt; db = p->db; - tdsqlite3_mutex_enter(db->mutex); - tdsqlite3DbFree(db, p); - tdsqlite3_mutex_leave(db->mutex); - rc = tdsqlite3_finalize(pStmt); + sqlite3_mutex_enter(db->mutex); + sqlite3DbFree(db, p); + sqlite3_mutex_leave(db->mutex); + rc = sqlite3_finalize(pStmt); }else{ rc = SQLITE_OK; } @@ -96840,7 +96840,7 @@ SQLITE_API int tdsqlite3_blob_close(tdsqlite3_blob *pBlob){ ** Perform a read or write operation on a blob */ static int blobReadWrite( - tdsqlite3_blob *pBlob, + sqlite3_blob *pBlob, void *z, int n, int iOffset, @@ -96849,14 +96849,14 @@ static int blobReadWrite( int rc; Incrblob *p = (Incrblob *)pBlob; Vdbe *v; - tdsqlite3 *db; + sqlite3 *db; if( p==0 ) return SQLITE_MISUSE_BKPT; db = p->db; - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); v = (Vdbe*)p->pStmt; - if( n<0 || iOffset<0 || ((tdsqlite3_int64)iOffset+n)>p->nByte ){ + if( n<0 || iOffset<0 || ((sqlite3_int64)iOffset+n)>p->nByte ){ /* Request is out of range. Return a transient error. */ rc = SQLITE_ERROR; }else if( v==0 ){ @@ -96869,10 +96869,10 @@ static int blobReadWrite( ** returned, clean-up the statement handle. */ assert( db == v->db ); - tdsqlite3BtreeEnterCursor(p->pCsr); + sqlite3BtreeEnterCursor(p->pCsr); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - if( xCall==tdsqlite3BtreePutData && db->xPreUpdateCallback ){ + if( xCall==sqlite3BtreePutData && db->xPreUpdateCallback ){ /* If a pre-update hook is registered and this is a write cursor, ** invoke it here. ** @@ -96886,41 +96886,41 @@ static int blobReadWrite( ** using the incremental-blob API, this works. For the sessions module ** anyhow. */ - tdsqlite3_int64 iKey; - iKey = tdsqlite3BtreeIntegerKey(p->pCsr); - tdsqlite3VdbePreUpdateHook( + sqlite3_int64 iKey; + iKey = sqlite3BtreeIntegerKey(p->pCsr); + sqlite3VdbePreUpdateHook( v, v->apCsr[0], SQLITE_DELETE, p->zDb, p->pTab, iKey, -1 ); } #endif rc = xCall(p->pCsr, iOffset+p->iOffset, n, z); - tdsqlite3BtreeLeaveCursor(p->pCsr); + sqlite3BtreeLeaveCursor(p->pCsr); if( rc==SQLITE_ABORT ){ - tdsqlite3VdbeFinalize(v); + sqlite3VdbeFinalize(v); p->pStmt = 0; }else{ v->rc = rc; } } - tdsqlite3Error(db, rc); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + sqlite3Error(db, rc); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } /* ** Read data from a blob handle. */ -SQLITE_API int tdsqlite3_blob_read(tdsqlite3_blob *pBlob, void *z, int n, int iOffset){ - return blobReadWrite(pBlob, z, n, iOffset, tdsqlite3BtreePayloadChecked); +SQLITE_API int sqlite3_blob_read(sqlite3_blob *pBlob, void *z, int n, int iOffset){ + return blobReadWrite(pBlob, z, n, iOffset, sqlite3BtreePayloadChecked); } /* ** Write data to a blob handle. */ -SQLITE_API int tdsqlite3_blob_write(tdsqlite3_blob *pBlob, const void *z, int n, int iOffset){ - return blobReadWrite(pBlob, (void *)z, n, iOffset, tdsqlite3BtreePutData); +SQLITE_API int sqlite3_blob_write(sqlite3_blob *pBlob, const void *z, int n, int iOffset){ + return blobReadWrite(pBlob, (void *)z, n, iOffset, sqlite3BtreePutData); } /* @@ -96929,7 +96929,7 @@ SQLITE_API int tdsqlite3_blob_write(tdsqlite3_blob *pBlob, const void *z, int n, ** The Incrblob.nByte field is fixed for the lifetime of the Incrblob ** so no mutex is required for access. */ -SQLITE_API int tdsqlite3_blob_bytes(tdsqlite3_blob *pBlob){ +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ Incrblob *p = (Incrblob *)pBlob; return (p && p->pStmt) ? p->nByte : 0; } @@ -96941,17 +96941,17 @@ SQLITE_API int tdsqlite3_blob_bytes(tdsqlite3_blob *pBlob){ ** If an error occurs, or if the specified row does not exist or does not ** contain a blob or text value, then an error code is returned and the ** database handle error code and message set. If this happens, then all -** subsequent calls to tdsqlite3_blob_xxx() functions (except blob_close()) +** subsequent calls to sqlite3_blob_xxx() functions (except blob_close()) ** immediately return SQLITE_ABORT. */ -SQLITE_API int tdsqlite3_blob_reopen(tdsqlite3_blob *pBlob, tdsqlite3_int64 iRow){ +SQLITE_API int sqlite3_blob_reopen(sqlite3_blob *pBlob, sqlite3_int64 iRow){ int rc; Incrblob *p = (Incrblob *)pBlob; - tdsqlite3 *db; + sqlite3 *db; if( p==0 ) return SQLITE_MISUSE_BKPT; db = p->db; - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( p->pStmt==0 ){ /* If there is no statement handle, then the blob-handle has @@ -96962,15 +96962,15 @@ SQLITE_API int tdsqlite3_blob_reopen(tdsqlite3_blob *pBlob, tdsqlite3_int64 iRow char *zErr; rc = blobSeekToRow(p, iRow, &zErr); if( rc!=SQLITE_OK ){ - tdsqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); - tdsqlite3DbFree(db, zErr); + sqlite3ErrorWithMsg(db, rc, (zErr ? "%s" : 0), zErr); + sqlite3DbFree(db, zErr); } assert( rc!=SQLITE_SCHEMA ); } - rc = tdsqlite3ApiExit(db, rc); + rc = sqlite3ApiExit(db, rc); assert( rc==SQLITE_OK || p->pStmt==0 ); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -97001,9 +97001,9 @@ SQLITE_API int tdsqlite3_blob_reopen(tdsqlite3_blob *pBlob, tdsqlite3_int64 iRow ** Here is the (internal, non-API) interface between this module and the ** rest of the SQLite system: ** -** tdsqlite3VdbeSorterInit() Create a new VdbeSorter object. +** sqlite3VdbeSorterInit() Create a new VdbeSorter object. ** -** tdsqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter +** sqlite3VdbeSorterWrite() Add a single new row to the VdbeSorter ** object. The row is a binary blob in the ** OP_MakeRecord format that contains both ** the ORDER BY key columns and result columns @@ -97011,27 +97011,27 @@ SQLITE_API int tdsqlite3_blob_reopen(tdsqlite3_blob *pBlob, tdsqlite3_int64 iRow ** the complete record for an index entry ** in the case of a CREATE INDEX. ** -** tdsqlite3VdbeSorterRewind() Sort all content previously added. +** sqlite3VdbeSorterRewind() Sort all content previously added. ** Position the read cursor on the ** first sorted element. ** -** tdsqlite3VdbeSorterNext() Advance the read cursor to the next sorted +** sqlite3VdbeSorterNext() Advance the read cursor to the next sorted ** element. ** -** tdsqlite3VdbeSorterRowkey() Return the complete binary blob for the +** sqlite3VdbeSorterRowkey() Return the complete binary blob for the ** row currently under the read cursor. ** -** tdsqlite3VdbeSorterCompare() Compare the binary blob for the row +** sqlite3VdbeSorterCompare() Compare the binary blob for the row ** currently under the read cursor against ** another binary blob X and report if ** X is strictly less than the read cursor. ** Used to enforce uniqueness in a ** CREATE UNIQUE INDEX statement. ** -** tdsqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim +** sqlite3VdbeSorterClose() Close the VdbeSorter object and reclaim ** all resources. ** -** tdsqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This +** sqlite3VdbeSorterReset() Refurbish the VdbeSorter for reuse. This ** is like Close() followed by Init() only ** much faster. ** @@ -97151,7 +97151,7 @@ typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ ** stored in the file. */ struct SorterFile { - tdsqlite3_file *pFd; /* File handle */ + sqlite3_file *pFd; /* File handle */ i64 iEof; /* Bytes of data stored in pFd */ }; @@ -97264,7 +97264,7 @@ struct MergeEngine { ** to block until it finishes). ** ** 2. If SQLITE_DEBUG_SORTER_THREADS is defined, to determine if a call -** to tdsqlite3ThreadJoin() is likely to block. Cases that are likely to +** to sqlite3ThreadJoin() is likely to block. Cases that are likely to ** block provoke debugging output. ** ** In both cases, the effects of the main thread seeing (bDone==0) even @@ -97290,7 +97290,7 @@ struct SortSubtask { ** sorter cursor created by the VDBE. ** ** mxKeysize: -** As records are added to the sorter by calls to tdsqlite3VdbeSorterWrite(), +** As records are added to the sorter by calls to sqlite3VdbeSorterWrite(), ** this variable is updated so as to be set to the size on disk of the ** largest record in the sorter. */ @@ -97301,7 +97301,7 @@ struct VdbeSorter { int pgsz; /* Main database page size */ PmaReader *pReader; /* Readr data from here after Rewind() */ MergeEngine *pMerger; /* Or here, if bUseThreads==0 */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ KeyInfo *pKeyInfo; /* How to compare records */ UnpackedRecord *pUnpacked; /* Used by VdbeSorterCompare() */ SorterList list; /* List of in-memory records */ @@ -97332,7 +97332,7 @@ struct PmaReader { i64 iEof; /* 1 byte past EOF for this PmaReader */ int nAlloc; /* Bytes of space at aAlloc */ int nKey; /* Number of bytes in key */ - tdsqlite3_file *pFd; /* File handle we are reading from */ + sqlite3_file *pFd; /* File handle we are reading from */ u8 *aAlloc; /* Space for aKey if aBuffer and pMap wont work */ u8 *aKey; /* Pointer to current key */ u8 *aBuffer; /* Current read buffer */ @@ -97398,7 +97398,7 @@ struct PmaWriter { int iBufStart; /* First byte of buffer to write */ int iBufEnd; /* Last byte of buffer to write */ i64 iWriteOff; /* Offset of start of buffer in file */ - tdsqlite3_file *pFd; /* File handle to write to */ + sqlite3_file *pFd; /* File handle to write to */ }; /* @@ -97413,7 +97413,7 @@ struct PmaWriter { ** Or, if using the single large allocation method (VdbeSorter.list.aMemory!=0), ** then while records are being accumulated the list is linked using the ** SorterRecord.u.iNext offset. This is because the aMemory[] array may -** be tdsqlite3Realloc()ed while records are being accumulated. Once the VM +** be sqlite3Realloc()ed while records are being accumulated. Once the VM ** has finished passing records to the sorter, or when the in-memory buffer ** is full, the list is sorted. As part of the sorting process, it is ** converted to use the SorterRecord.u.pNext pointers. See function @@ -97447,9 +97447,9 @@ static void vdbeIncrFree(IncrMerger *); ** argument. All structure fields are set to zero before returning. */ static void vdbePmaReaderClear(PmaReader *pReadr){ - tdsqlite3_free(pReadr->aAlloc); - tdsqlite3_free(pReadr->aBuffer); - if( pReadr->aMap ) tdsqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); + sqlite3_free(pReadr->aAlloc); + sqlite3_free(pReadr->aBuffer); + if( pReadr->aMap ) sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); vdbeIncrFree(pReadr->pIncr); memset(pReadr, 0, sizeof(PmaReader)); } @@ -97485,7 +97485,7 @@ static int vdbePmaReadBlob( iBuf = p->iReadOff % p->nBuffer; if( iBuf==0 ){ int nRead; /* Bytes to read from disk */ - int rc; /* tdsqlite3OsRead() return code */ + int rc; /* sqlite3OsRead() return code */ /* Determine how many bytes of data to read. */ if( (p->iEof - p->iReadOff) > (i64)p->nBuffer ){ @@ -97496,7 +97496,7 @@ static int vdbePmaReadBlob( assert( nRead>0 ); /* Readr data from the file. Return early if an error occurs. */ - rc = tdsqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff); + rc = sqlite3OsRead(p->pFd, p->aBuffer, nRead, p->iReadOff); assert( rc!=SQLITE_IOERR_SHORT_READ ); if( rc!=SQLITE_OK ) return rc; } @@ -97517,9 +97517,9 @@ static int vdbePmaReadBlob( /* Extend the p->aAlloc[] allocation if required. */ if( p->nAllocnAlloc); + sqlite3_int64 nNew = MAX(128, 2*(sqlite3_int64)p->nAlloc); while( nByte>nNew ) nNew = nNew*2; - aNew = tdsqlite3Realloc(p->aAlloc, nNew); + aNew = sqlite3Realloc(p->aAlloc, nNew); if( !aNew ) return SQLITE_NOMEM_BKPT; p->nAlloc = nNew; p->aAlloc = aNew; @@ -97561,11 +97561,11 @@ static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ int iBuf; if( p->aMap ){ - p->iReadOff += tdsqlite3GetVarint(&p->aMap[p->iReadOff], pnOut); + p->iReadOff += sqlite3GetVarint(&p->aMap[p->iReadOff], pnOut); }else{ iBuf = p->iReadOff % p->nBuffer; if( iBuf && (p->nBuffer-iBuf)>=9 ){ - p->iReadOff += tdsqlite3GetVarint(&p->aBuffer[iBuf], pnOut); + p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); }else{ u8 aVarint[16], *a; int i = 0, rc; @@ -97574,7 +97574,7 @@ static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ if( rc ) return rc; aVarint[(i++)&0xf] = a[0]; }while( (a[0]&0x80)!=0 ); - tdsqlite3GetVarint(aVarint, pnOut); + sqlite3GetVarint(aVarint, pnOut); } } @@ -97593,9 +97593,9 @@ static int vdbePmaReadVarint(PmaReader *p, u64 *pnOut){ static int vdbeSorterMapFile(SortSubtask *pTask, SorterFile *pFile, u8 **pp){ int rc = SQLITE_OK; if( pFile->iEof<=(i64)(pTask->pSorter->db->nMaxSorterMmap) ){ - tdsqlite3_file *pFd = pFile->pFd; + sqlite3_file *pFd = pFile->pFd; if( pFd->pMethods->iVersion>=3 ){ - rc = tdsqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp); + rc = sqlite3OsFetch(pFd, 0, (int)pFile->iEof, (void**)pp); testcase( rc!=SQLITE_OK ); } } @@ -97617,9 +97617,9 @@ static int vdbePmaReaderSeek( assert( pReadr->pIncr==0 || pReadr->pIncr->bEof==0 ); - if( tdsqlite3FaultSim(201) ) return SQLITE_IOERR_READ; + if( sqlite3FaultSim(201) ) return SQLITE_IOERR_READ; if( pReadr->aMap ){ - tdsqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); + sqlite3OsUnfetch(pReadr->pFd, 0, pReadr->aMap); pReadr->aMap = 0; } pReadr->iReadOff = iOff; @@ -97631,7 +97631,7 @@ static int vdbePmaReaderSeek( int pgsz = pTask->pSorter->pgsz; int iBuf = pReadr->iReadOff % pgsz; if( pReadr->aBuffer==0 ){ - pReadr->aBuffer = (u8*)tdsqlite3Malloc(pgsz); + pReadr->aBuffer = (u8*)sqlite3Malloc(pgsz); if( pReadr->aBuffer==0 ) rc = SQLITE_NOMEM_BKPT; pReadr->nBuffer = pgsz; } @@ -97640,7 +97640,7 @@ static int vdbePmaReaderSeek( if( (pReadr->iReadOff + nRead) > pReadr->iEof ){ nRead = (int)(pReadr->iEof - pReadr->iReadOff); } - rc = tdsqlite3OsRead( + rc = sqlite3OsRead( pReadr->pFd, &pReadr->aBuffer[iBuf], nRead, pReadr->iReadOff ); testcase( rc!=SQLITE_OK ); @@ -97742,10 +97742,10 @@ static int vdbeSorterCompareTail( ){ UnpackedRecord *r2 = pTask->pUnpacked; if( *pbKey2Cached==0 ){ - tdsqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); *pbKey2Cached = 1; } - return tdsqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); + return sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, r2, 1); } /* @@ -97769,10 +97769,10 @@ static int vdbeSorterCompare( ){ UnpackedRecord *r2 = pTask->pUnpacked; if( !*pbKey2Cached ){ - tdsqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); + sqlite3VdbeRecordUnpack(pTask->pSorter->pKeyInfo, nKey2, pKey2, r2); *pbKey2Cached = 1; } - return tdsqlite3VdbeRecordCompare(nKey1, pKey1, r2); + return sqlite3VdbeRecordCompare(nKey1, pKey1, r2); } /* @@ -97905,8 +97905,8 @@ static int vdbeSorterCompareInt( ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. */ -SQLITE_PRIVATE int tdsqlite3VdbeSorterInit( - tdsqlite3 *db, /* Database connection (for malloc()) */ +SQLITE_PRIVATE int sqlite3VdbeSorterInit( + sqlite3 *db, /* Database connection (for malloc()) */ int nField, /* Number of key fields in each record */ VdbeCursor *pCsr /* Cursor that holds the new sorter */ ){ @@ -97925,7 +97925,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterInit( /* Initialize the upper limit on the number of worker threads */ #if SQLITE_MAX_WORKER_THREADS>0 - if( tdsqlite3TempInMemory(db) || tdsqlite3GlobalConfig.bCoreMutex==0 ){ + if( sqlite3TempInMemory(db) || sqlite3GlobalConfig.bCoreMutex==0 ){ nWorker = 0; }else{ nWorker = db->aLimit[SQLITE_LIMIT_WORKER_THREADS]; @@ -97945,7 +97945,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterInit( szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); - pSorter = (VdbeSorter*)tdsqlite3DbMallocZero(db, sz + szKeyInfo); + pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); pCsr->uc.pSorter = pSorter; if( pSorter==0 ){ rc = SQLITE_NOMEM_BKPT; @@ -97956,7 +97956,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterInit( if( nField && nWorker==0 ){ pKeyInfo->nKeyField = nField; } - pSorter->pgsz = pgsz = tdsqlite3BtreeGetPageSize(db->aDb[0].pBt); + pSorter->pgsz = pgsz = sqlite3BtreeGetPageSize(db->aDb[0].pBt); pSorter->nTask = nWorker + 1; pSorter->iPrev = (u8)(nWorker - 1); pSorter->bUseThreads = (pSorter->nTask>1); @@ -97966,9 +97966,9 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterInit( pTask->pSorter = pSorter; } - if( !tdsqlite3TempInMemory(db) ){ + if( !sqlite3TempInMemory(db) ){ i64 mxCache; /* Cache size in bytes*/ - u32 szPma = tdsqlite3GlobalConfig.szPma; + u32 szPma = sqlite3GlobalConfig.szPma; pSorter->mnPmaSize = szPma * pgsz; mxCache = db->aDb[0].pSchema->cache_size; @@ -97984,10 +97984,10 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterInit( /* Avoid large memory allocations if the application has requested ** SQLITE_CONFIG_SMALL_MALLOC. */ - if( tdsqlite3GlobalConfig.bSmallMalloc==0 ){ + if( sqlite3GlobalConfig.bSmallMalloc==0 ){ assert( pSorter->iMemory==0 ); pSorter->nMemory = pgsz; - pSorter->list.aMemory = (u8*)tdsqlite3Malloc(pgsz); + pSorter->list.aMemory = (u8*)sqlite3Malloc(pgsz); if( !pSorter->list.aMemory ) rc = SQLITE_NOMEM_BKPT; } } @@ -98007,12 +98007,12 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterInit( /* ** Free the list of sorted records starting at pRecord. */ -static void vdbeSorterRecordFree(tdsqlite3 *db, SorterRecord *pRecord){ +static void vdbeSorterRecordFree(sqlite3 *db, SorterRecord *pRecord){ SorterRecord *p; SorterRecord *pNext; for(p=pRecord; p; p=pNext){ pNext = p->u.pNext; - tdsqlite3DbFree(db, p); + sqlite3DbFree(db, p); } } @@ -98020,13 +98020,13 @@ static void vdbeSorterRecordFree(tdsqlite3 *db, SorterRecord *pRecord){ ** Free all resources owned by the object indicated by argument pTask. All ** fields of *pTask are zeroed before returning. */ -static void vdbeSortSubtaskCleanup(tdsqlite3 *db, SortSubtask *pTask){ - tdsqlite3DbFree(db, pTask->pUnpacked); +static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ + sqlite3DbFree(db, pTask->pUnpacked); #if SQLITE_MAX_WORKER_THREADS>0 /* pTask->list.aMemory can only be non-zero if it was handed memory ** from the main thread. That only occurs SQLITE_MAX_WORKER_THREADS>0 */ if( pTask->list.aMemory ){ - tdsqlite3_free(pTask->list.aMemory); + sqlite3_free(pTask->list.aMemory); }else #endif { @@ -98034,10 +98034,10 @@ static void vdbeSortSubtaskCleanup(tdsqlite3 *db, SortSubtask *pTask){ vdbeSorterRecordFree(0, pTask->list.pList); } if( pTask->file.pFd ){ - tdsqlite3OsCloseFree(pTask->file.pFd); + sqlite3OsCloseFree(pTask->file.pFd); } if( pTask->file2.pFd ){ - tdsqlite3OsCloseFree(pTask->file2.pFd); + sqlite3OsCloseFree(pTask->file2.pFd); } memset(pTask, 0, sizeof(SortSubtask)); } @@ -98046,12 +98046,12 @@ static void vdbeSortSubtaskCleanup(tdsqlite3 *db, SortSubtask *pTask){ static void vdbeSorterWorkDebug(SortSubtask *pTask, const char *zEvent){ i64 t; int iTask = (pTask - pTask->pSorter->aTask); - tdsqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); fprintf(stderr, "%lld:%d %s\n", t, iTask, zEvent); } static void vdbeSorterRewindDebug(const char *zEvent){ i64 t; - tdsqlite3OsCurrentTimeInt64(tdsqlite3_vfs_find(0), &t); + sqlite3OsCurrentTimeInt64(sqlite3_vfs_find(0), &t); fprintf(stderr, "%lld:X %s\n", t, zEvent); } static void vdbeSorterPopulateDebug( @@ -98060,7 +98060,7 @@ static void vdbeSorterPopulateDebug( ){ i64 t; int iTask = (pTask - pTask->pSorter->aTask); - tdsqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); fprintf(stderr, "%lld:bg%d %s\n", t, iTask, zEvent); } static void vdbeSorterBlockDebug( @@ -98070,7 +98070,7 @@ static void vdbeSorterBlockDebug( ){ if( bBlocked ){ i64 t; - tdsqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); + sqlite3OsCurrentTimeInt64(pTask->pSorter->db->pVfs, &t); fprintf(stderr, "%lld:main %s\n", t, zEvent); } } @@ -98093,7 +98093,7 @@ static int vdbeSorterJoinThread(SortSubtask *pTask){ #endif void *pRet = SQLITE_INT_TO_PTR(SQLITE_ERROR); vdbeSorterBlockDebug(pTask, !bDone, "enter"); - (void)tdsqlite3ThreadJoin(pTask->pThread, &pRet); + (void)sqlite3ThreadJoin(pTask->pThread, &pRet); vdbeSorterBlockDebug(pTask, !bDone, "exit"); rc = SQLITE_PTR_TO_INT(pRet); assert( pTask->bDone==1 ); @@ -98112,7 +98112,7 @@ static int vdbeSorterCreateThread( void *pIn /* Argument passed into xTask() */ ){ assert( pTask->pThread==0 && pTask->bDone==0 ); - return tdsqlite3ThreadCreate(&pTask->pThread, xTask, pIn); + return sqlite3ThreadCreate(&pTask->pThread, xTask, pIn); } /* @@ -98159,7 +98159,7 @@ static MergeEngine *vdbeMergeEngineNew(int nReader){ while( NnTree = N; pNew->pTask = 0; @@ -98179,7 +98179,7 @@ static void vdbeMergeEngineFree(MergeEngine *pMerger){ vdbePmaReaderClear(&pMerger->aReadr[i]); } } - tdsqlite3_free(pMerger); + sqlite3_free(pMerger); } /* @@ -98191,26 +98191,26 @@ static void vdbeIncrFree(IncrMerger *pIncr){ #if SQLITE_MAX_WORKER_THREADS>0 if( pIncr->bUseThread ){ vdbeSorterJoinThread(pIncr->pTask); - if( pIncr->aFile[0].pFd ) tdsqlite3OsCloseFree(pIncr->aFile[0].pFd); - if( pIncr->aFile[1].pFd ) tdsqlite3OsCloseFree(pIncr->aFile[1].pFd); + if( pIncr->aFile[0].pFd ) sqlite3OsCloseFree(pIncr->aFile[0].pFd); + if( pIncr->aFile[1].pFd ) sqlite3OsCloseFree(pIncr->aFile[1].pFd); } #endif vdbeMergeEngineFree(pIncr->pMerger); - tdsqlite3_free(pIncr); + sqlite3_free(pIncr); } } /* ** Reset a sorting cursor back to its original empty state. */ -SQLITE_PRIVATE void tdsqlite3VdbeSorterReset(tdsqlite3 *db, VdbeSorter *pSorter){ +SQLITE_PRIVATE void sqlite3VdbeSorterReset(sqlite3 *db, VdbeSorter *pSorter){ int i; (void)vdbeSorterJoinAll(pSorter, SQLITE_OK); assert( pSorter->bUseThreads || pSorter->pReader==0 ); #if SQLITE_MAX_WORKER_THREADS>0 if( pSorter->pReader ){ vdbePmaReaderClear(pSorter->pReader); - tdsqlite3DbFree(db, pSorter->pReader); + sqlite3DbFree(db, pSorter->pReader); pSorter->pReader = 0; } #endif @@ -98229,21 +98229,21 @@ SQLITE_PRIVATE void tdsqlite3VdbeSorterReset(tdsqlite3 *db, VdbeSorter *pSorter) pSorter->bUsePMA = 0; pSorter->iMemory = 0; pSorter->mxKeysize = 0; - tdsqlite3DbFree(db, pSorter->pUnpacked); + sqlite3DbFree(db, pSorter->pUnpacked); pSorter->pUnpacked = 0; } /* -** Free any cursor components allocated by tdsqlite3VdbeSorterXXX routines. +** Free any cursor components allocated by sqlite3VdbeSorterXXX routines. */ -SQLITE_PRIVATE void tdsqlite3VdbeSorterClose(tdsqlite3 *db, VdbeCursor *pCsr){ +SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){ VdbeSorter *pSorter; assert( pCsr->eCurType==CURTYPE_SORTER ); pSorter = pCsr->uc.pSorter; if( pSorter ){ - tdsqlite3VdbeSorterReset(db, pSorter); - tdsqlite3_free(pSorter->list.aMemory); - tdsqlite3DbFree(db, pSorter); + sqlite3VdbeSorterReset(db, pSorter); + sqlite3_free(pSorter->list.aMemory); + sqlite3DbFree(db, pSorter); pCsr->uc.pSorter = 0; } } @@ -98258,14 +98258,14 @@ SQLITE_PRIVATE void tdsqlite3VdbeSorterClose(tdsqlite3 *db, VdbeCursor *pCsr){ ** Whether or not the file does end up memory mapped of course depends on ** the specific VFS implementation. */ -static void vdbeSorterExtendFile(tdsqlite3 *db, tdsqlite3_file *pFd, i64 nByte){ +static void vdbeSorterExtendFile(sqlite3 *db, sqlite3_file *pFd, i64 nByte){ if( nByte<=(i64)(db->nMaxSorterMmap) && pFd->pMethods->iVersion>=3 ){ void *p = 0; int chunksize = 4*1024; - tdsqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize); - tdsqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte); - tdsqlite3OsFetch(pFd, 0, (int)nByte, &p); - tdsqlite3OsUnfetch(pFd, 0, p); + sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_CHUNK_SIZE, &chunksize); + sqlite3OsFileControlHint(pFd, SQLITE_FCNTL_SIZE_HINT, &nByte); + sqlite3OsFetch(pFd, 0, (int)nByte, &p); + sqlite3OsUnfetch(pFd, 0, p); } } #else @@ -98278,20 +98278,20 @@ static void vdbeSorterExtendFile(tdsqlite3 *db, tdsqlite3_file *pFd, i64 nByte){ ** Otherwise, set *ppFd to 0 and return an SQLite error code. */ static int vdbeSorterOpenTempFile( - tdsqlite3 *db, /* Database handle doing sort */ + sqlite3 *db, /* Database handle doing sort */ i64 nExtend, /* Attempt to extend file to this size */ - tdsqlite3_file **ppFd + sqlite3_file **ppFd ){ int rc; - if( tdsqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS; - rc = tdsqlite3OsOpenMalloc(db->pVfs, 0, ppFd, + if( sqlite3FaultSim(202) ) return SQLITE_IOERR_ACCESS; + rc = sqlite3OsOpenMalloc(db->pVfs, 0, ppFd, SQLITE_OPEN_TEMP_JOURNAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE, &rc ); if( rc==SQLITE_OK ){ i64 max = SQLITE_MAX_MMAP_SIZE; - tdsqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max); + sqlite3OsFileControlHint(*ppFd, SQLITE_FCNTL_MMAP_SIZE, (void*)&max); if( nExtend>0 ){ vdbeSorterExtendFile(db, *ppFd, nExtend); } @@ -98306,7 +98306,7 @@ static int vdbeSorterOpenTempFile( */ static int vdbeSortAllocUnpacked(SortSubtask *pTask){ if( pTask->pUnpacked==0 ){ - pTask->pUnpacked = tdsqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo); + pTask->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pTask->pSorter->pKeyInfo); if( pTask->pUnpacked==0 ) return SQLITE_NOMEM_BKPT; pTask->pUnpacked->nField = pTask->pSorter->pKeyInfo->nKeyField; pTask->pUnpacked->errCode = 0; @@ -98393,7 +98393,7 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ if( (u8*)p==pList->aMemory ){ pNext = 0; }else{ - assert( p->u.iNextaMemory) ); + assert( p->u.iNextaMemory) ); pNext = (SorterRecord*)&pList->aMemory[p->u.iNext]; } }else{ @@ -98426,13 +98426,13 @@ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ ** Initialize a PMA-writer object. */ static void vdbePmaWriterInit( - tdsqlite3_file *pFd, /* File handle to write to */ + sqlite3_file *pFd, /* File handle to write to */ PmaWriter *p, /* Object to populate */ int nBuf, /* Buffer size */ i64 iStart /* Offset of pFd to begin writing at */ ){ memset(p, 0, sizeof(PmaWriter)); - p->aBuffer = (u8*)tdsqlite3Malloc(nBuf); + p->aBuffer = (u8*)sqlite3Malloc(nBuf); if( !p->aBuffer ){ p->eFWErr = SQLITE_NOMEM_BKPT; }else{ @@ -98458,7 +98458,7 @@ static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){ memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); p->iBufEnd += nCopy; if( p->iBufEnd==p->nBuffer ){ - p->eFWErr = tdsqlite3OsWrite(p->pFd, + p->eFWErr = sqlite3OsWrite(p->pFd, &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, p->iWriteOff + p->iBufStart ); @@ -98483,13 +98483,13 @@ static void vdbePmaWriteBlob(PmaWriter *p, u8 *pData, int nData){ static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){ int rc; if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ - p->eFWErr = tdsqlite3OsWrite(p->pFd, + p->eFWErr = sqlite3OsWrite(p->pFd, &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, p->iWriteOff + p->iBufStart ); } *piEof = (p->iWriteOff + p->iBufEnd); - tdsqlite3_free(p->aBuffer); + sqlite3_free(p->aBuffer); rc = p->eFWErr; memset(p, 0, sizeof(PmaWriter)); return rc; @@ -98502,7 +98502,7 @@ static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){ static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){ int nByte; u8 aByte[10]; - nByte = tdsqlite3PutVarint(aByte, iVal); + nByte = sqlite3PutVarint(aByte, iVal); vdbePmaWriteBlob(p, aByte, nByte); } @@ -98521,14 +98521,14 @@ static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){ ** key). The varint is the number of bytes in the blob of data. */ static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){ - tdsqlite3 *db = pTask->pSorter->db; + sqlite3 *db = pTask->pSorter->db; int rc = SQLITE_OK; /* Return code */ PmaWriter writer; /* Object used to write to the file */ #ifdef SQLITE_DEBUG /* Set iSz to the expected size of file pTask->file after writing the PMA. ** This is used by an assert() statement at the end of this function. */ - i64 iSz = pList->szPMA + tdsqlite3VarintLen(pList->szPMA) + pTask->file.iEof; + i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof; #endif vdbeSorterWorkDebug(pTask, "enter"); @@ -98565,7 +98565,7 @@ static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){ pNext = p->u.pNext; vdbePmaWriteVarint(&writer, p->nVal); vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal); - if( pList->aMemory==0 ) tdsqlite3_free(p); + if( pList->aMemory==0 ) sqlite3_free(p); } pList->pList = p; rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof); @@ -98722,9 +98722,9 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ pSorter->list.szPMA = 0; if( aMem ){ pSorter->list.aMemory = aMem; - pSorter->nMemory = tdsqlite3MallocSize(aMem); + pSorter->nMemory = sqlite3MallocSize(aMem); }else if( pSorter->list.aMemory ){ - pSorter->list.aMemory = tdsqlite3Malloc(pSorter->nMemory); + pSorter->list.aMemory = sqlite3Malloc(pSorter->nMemory); if( !pSorter->list.aMemory ) return SQLITE_NOMEM_BKPT; } @@ -98739,7 +98739,7 @@ static int vdbeSorterFlushPMA(VdbeSorter *pSorter){ /* ** Add a record to the sorter. */ -SQLITE_PRIVATE int tdsqlite3VdbeSorterWrite( +SQLITE_PRIVATE int sqlite3VdbeSorterWrite( const VdbeCursor *pCsr, /* Sorter cursor */ Mem *pVal /* Memory cell containing record */ ){ @@ -98778,17 +98778,17 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterWrite( ** than (page-size * cache-size), or ** ** * The total memory allocated for the in-memory list is greater - ** than (page-size * 10) and tdsqlite3HeapNearlyFull() returns true. + ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. */ nReq = pVal->n + sizeof(SorterRecord); - nPMA = pVal->n + tdsqlite3VarintLen(pVal->n); + nPMA = pVal->n + sqlite3VarintLen(pVal->n); if( pSorter->mxPmaSize ){ if( pSorter->list.aMemory ){ bFlush = pSorter->iMemory && (pSorter->iMemory+nReq) > pSorter->mxPmaSize; }else{ bFlush = ( (pSorter->list.szPMA > pSorter->mxPmaSize) - || (pSorter->list.szPMA > pSorter->mnPmaSize && tdsqlite3HeapNearlyFull()) + || (pSorter->list.szPMA > pSorter->mnPmaSize && sqlite3HeapNearlyFull()) ); } if( bFlush ){ @@ -98809,7 +98809,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterWrite( if( nMin>pSorter->nMemory ){ u8 *aNew; - tdsqlite3_int64 nNew = 2 * (tdsqlite3_int64)pSorter->nMemory; + sqlite3_int64 nNew = 2 * (sqlite3_int64)pSorter->nMemory; int iListOff = -1; if( pSorter->list.pList ){ iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory; @@ -98817,7 +98817,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterWrite( while( nNew < nMin ) nNew = nNew*2; if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize; if( nNew < nMin ) nNew = nMin; - aNew = tdsqlite3Realloc(pSorter->list.aMemory, nNew); + aNew = sqlite3Realloc(pSorter->list.aMemory, nNew); if( !aNew ) return SQLITE_NOMEM_BKPT; if( iListOff>=0 ){ pSorter->list.pList = (SorterRecord*)&aNew[iListOff]; @@ -98832,7 +98832,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterWrite( pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory); } }else{ - pNew = (SorterRecord *)tdsqlite3Malloc(nReq); + pNew = (SorterRecord *)sqlite3Malloc(nReq); if( pNew==0 ){ return SQLITE_NOMEM_BKPT; } @@ -98873,7 +98873,7 @@ static int vdbeIncrPopulate(IncrMerger *pIncr){ /* Check if the output file is full or if the input has been exhausted. ** In either case exit the loop. */ if( pReader->pFd==0 ) break; - if( (iEof + nKey + tdsqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break; + if( (iEof + nKey + sqlite3VarintLen(nKey))>(iStart + pIncr->mxSz) ) break; /* Write the next key to the output. */ vdbePmaWriteVarint(&writer, nKey); @@ -98973,7 +98973,7 @@ static int vdbeIncrMergerNew( ){ int rc = SQLITE_OK; IncrMerger *pIncr = *ppOut = (IncrMerger*) - (tdsqlite3FaultSim(100) ? 0 : tdsqlite3MallocZero(sizeof(*pIncr))); + (sqlite3FaultSim(100) ? 0 : sqlite3MallocZero(sizeof(*pIncr))); if( pIncr ){ pIncr->pMerger = pMerger; pIncr->pTask = pTask; @@ -99165,7 +99165,7 @@ static int vdbePmaReaderIncrMergeInit(PmaReader *pReadr, int eMode){ int rc = SQLITE_OK; IncrMerger *pIncr = pReadr->pIncr; SortSubtask *pTask = pIncr->pTask; - tdsqlite3 *db = pTask->pSorter->db; + sqlite3 *db = pTask->pSorter->db; /* eMode is always INCRINIT_NORMAL in single-threaded mode */ assert( SQLITE_MAX_WORKER_THREADS>0 || eMode==INCRINIT_NORMAL ); @@ -99463,7 +99463,7 @@ static int vdbeSorterMergeTreeBuild( } /* -** This function is called as part of an tdsqlite3VdbeSorterRewind() operation +** This function is called as part of an sqlite3VdbeSorterRewind() operation ** on a sorter that has written two or more PMAs to temporary files. It sets ** up either VdbeSorter.pMerger (for single threaded sorters) or pReader ** (for multi-threaded sorters) so that it can be used to iterate through @@ -99476,7 +99476,7 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ SortSubtask *pTask0 = &pSorter->aTask[0]; MergeEngine *pMain = 0; #if SQLITE_MAX_WORKER_THREADS - tdsqlite3 *db = pTask0->pSorter->db; + sqlite3 *db = pTask0->pSorter->db; int i; SorterCompare xCompare = vdbeSorterGetCompare(pSorter); for(i=0; inTask; i++){ @@ -99494,7 +99494,7 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ SortSubtask *pLast = &pSorter->aTask[pSorter->nTask-1]; rc = vdbeSortAllocUnpacked(pLast); if( rc==SQLITE_OK ){ - pReadr = (PmaReader*)tdsqlite3DbMallocZero(db, sizeof(PmaReader)); + pReadr = (PmaReader*)sqlite3DbMallocZero(db, sizeof(PmaReader)); pSorter->pReader = pReadr; if( pReadr==0 ) rc = SQLITE_NOMEM_BKPT; } @@ -99549,11 +99549,11 @@ static int vdbeSorterSetupMerge(VdbeSorter *pSorter){ /* -** Once the sorter has been populated by calls to tdsqlite3VdbeSorterWrite, +** Once the sorter has been populated by calls to sqlite3VdbeSorterWrite, ** this function is called to prepare for iterating through the records ** in sorted order. */ -SQLITE_PRIVATE int tdsqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof){ VdbeSorter *pSorter; int rc = SQLITE_OK; /* Return code */ @@ -99605,7 +99605,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterRewind(const VdbeCursor *pCsr, int *pbEof) ** SQLITE_DONE end of data ** otherwise some kind of error. */ -SQLITE_PRIVATE int tdsqlite3VdbeSorterNext(tdsqlite3 *db, const VdbeCursor *pCsr){ +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr){ VdbeSorter *pSorter; int rc; /* Return code */ @@ -99670,14 +99670,14 @@ static void *vdbeSorterRowkey( /* ** Copy the current sorter key into the memory cell pOut. */ -SQLITE_PRIVATE int tdsqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ VdbeSorter *pSorter; void *pKey; int nKey; /* Sorter key to copy into pOut */ assert( pCsr->eCurType==CURTYPE_SORTER ); pSorter = pCsr->uc.pSorter; pKey = vdbeSorterRowkey(pSorter, &nKey); - if( tdsqlite3VdbeMemClearAndResize(pOut, nKey) ){ + if( sqlite3VdbeMemClearAndResize(pOut, nKey) ){ return SQLITE_NOMEM_BKPT; } pOut->n = nKey; @@ -99703,7 +99703,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ ** This routine forms the core of the OP_SorterCompare opcode, which in ** turn is used to verify uniqueness when constructing a UNIQUE INDEX. */ -SQLITE_PRIVATE int tdsqlite3VdbeSorterCompare( +SQLITE_PRIVATE int sqlite3VdbeSorterCompare( const VdbeCursor *pCsr, /* Sorter cursor */ Mem *pVal, /* Value to compare to current sorter key */ int nKeyCol, /* Compare this many columns */ @@ -99720,14 +99720,14 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterCompare( r2 = pSorter->pUnpacked; pKeyInfo = pCsr->pKeyInfo; if( r2==0 ){ - r2 = pSorter->pUnpacked = tdsqlite3VdbeAllocUnpackedRecord(pKeyInfo); + r2 = pSorter->pUnpacked = sqlite3VdbeAllocUnpackedRecord(pKeyInfo); if( r2==0 ) return SQLITE_NOMEM_BKPT; r2->nField = nKeyCol; } assert( r2->nField==nKeyCol ); pKey = vdbeSorterRowkey(pSorter, &nKey); - tdsqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); + sqlite3VdbeRecordUnpack(pKeyInfo, nKey, pKey, r2); for(i=0; iaMem[i].flags & MEM_Null ){ *pRes = -1; @@ -99735,7 +99735,7 @@ SQLITE_PRIVATE int tdsqlite3VdbeSorterCompare( } } - *pRes = tdsqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); + *pRes = sqlite3VdbeRecordCompare(pVal->n, pVal->z, r2); return SQLITE_OK; } @@ -99800,16 +99800,16 @@ struct FileChunk { ** The cursor can be either for reading or writing. */ struct FilePoint { - tdsqlite3_int64 iOffset; /* Offset from the beginning of the file */ + sqlite3_int64 iOffset; /* Offset from the beginning of the file */ FileChunk *pChunk; /* Specific chunk into which cursor points */ }; /* -** This structure is a subclass of tdsqlite3_file. Each open memory-journal +** This structure is a subclass of sqlite3_file. Each open memory-journal ** is an instance of this class. */ struct MemJournal { - const tdsqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */ + const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */ int nChunkSize; /* In-memory chunk-size */ int nSpill; /* Bytes of data before flushing */ @@ -99819,16 +99819,16 @@ struct MemJournal { FilePoint readpoint; /* Pointer to the end of the last xRead() */ int flags; /* xOpen flags */ - tdsqlite3_vfs *pVfs; /* The "real" underlying VFS */ + sqlite3_vfs *pVfs; /* The "real" underlying VFS */ const char *zJournal; /* Name of the journal file */ }; /* ** Read data from the in-memory journal file. This is the implementation -** of the tdsqlite3_vfs.xRead method. +** of the sqlite3_vfs.xRead method. */ static int memjrnlRead( - tdsqlite3_file *pJfd, /* The journal file from which to read */ + sqlite3_file *pJfd, /* The journal file from which to read */ void *zBuf, /* Put the results here */ int iAmt, /* Number of bytes to read */ sqlite_int64 iOfst /* Begin reading at this offset */ @@ -99844,7 +99844,7 @@ static int memjrnlRead( } assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 ); if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ - tdsqlite3_int64 iOff = 0; + sqlite3_int64 iOff = 0; for(pChunk=p->pFirst; ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst; pChunk=pChunk->pNext @@ -99879,7 +99879,7 @@ static void memjrnlFreeChunks(MemJournal *p){ FileChunk *pNext; for(pIter=p->pFirst; pIter; pIter=pNext){ pNext = pIter->pNext; - tdsqlite3_free(pIter); + sqlite3_free(pIter); } p->pFirst = 0; } @@ -99889,11 +99889,11 @@ static void memjrnlFreeChunks(MemJournal *p){ */ static int memjrnlCreateFile(MemJournal *p){ int rc; - tdsqlite3_file *pReal = (tdsqlite3_file*)p; + sqlite3_file *pReal = (sqlite3_file*)p; MemJournal copy = *p; memset(p, 0, sizeof(MemJournal)); - rc = tdsqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0); + rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0); if( rc==SQLITE_OK ){ int nChunk = copy.nChunkSize; i64 iOff = 0; @@ -99902,7 +99902,7 @@ static int memjrnlCreateFile(MemJournal *p){ if( iOff + nChunk > copy.endpoint.iOffset ){ nChunk = copy.endpoint.iOffset - iOff; } - rc = tdsqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff); + rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nChunk, iOff); if( rc ) break; iOff += nChunk; } @@ -99916,7 +99916,7 @@ static int memjrnlCreateFile(MemJournal *p){ ** the original before returning. This way, SQLite uses the in-memory ** journal data to roll back changes made to the internal page-cache ** before this function was called. */ - tdsqlite3OsClose(pReal); + sqlite3OsClose(pReal); *p = copy; } return rc; @@ -99927,7 +99927,7 @@ static int memjrnlCreateFile(MemJournal *p){ ** Write data to the file. */ static int memjrnlWrite( - tdsqlite3_file *pJfd, /* The journal file into which to write */ + sqlite3_file *pJfd, /* The journal file into which to write */ const void *zBuf, /* Take data to be written from here */ int iAmt, /* Number of bytes to write */ sqlite_int64 iOfst /* Begin writing at this offset into the file */ @@ -99941,7 +99941,7 @@ static int memjrnlWrite( if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){ int rc = memjrnlCreateFile(p); if( rc==SQLITE_OK ){ - rc = tdsqlite3OsWrite(pJfd, zBuf, iAmt, iOfst); + rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst); } return rc; } @@ -99971,7 +99971,7 @@ static int memjrnlWrite( if( iChunkOffset==0 ){ /* New chunk is required to extend the file. */ - FileChunk *pNew = tdsqlite3_malloc(fileChunkSize(p->nChunkSize)); + FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize)); if( !pNew ){ return SQLITE_IOERR_NOMEM_BKPT; } @@ -100005,7 +100005,7 @@ static int memjrnlWrite( ** is still in main memory but is being truncated to zero bytes in size, ** ignore */ -static int memjrnlTruncate(tdsqlite3_file *pJfd, sqlite_int64 size){ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ MemJournal *p = (MemJournal *)pJfd; if( ALWAYS(size==0) ){ memjrnlFreeChunks(p); @@ -100021,7 +100021,7 @@ static int memjrnlTruncate(tdsqlite3_file *pJfd, sqlite_int64 size){ /* ** Close the file. */ -static int memjrnlClose(tdsqlite3_file *pJfd){ +static int memjrnlClose(sqlite3_file *pJfd){ MemJournal *p = (MemJournal *)pJfd; memjrnlFreeChunks(p); return SQLITE_OK; @@ -100033,7 +100033,7 @@ static int memjrnlClose(tdsqlite3_file *pJfd){ ** If the real file has been created, call its xSync method. Otherwise, ** syncing an in-memory journal is a no-op. */ -static int memjrnlSync(tdsqlite3_file *pJfd, int flags){ +static int memjrnlSync(sqlite3_file *pJfd, int flags){ UNUSED_PARAMETER2(pJfd, flags); return SQLITE_OK; } @@ -100041,16 +100041,16 @@ static int memjrnlSync(tdsqlite3_file *pJfd, int flags){ /* ** Query the size of the file in bytes. */ -static int memjrnlFileSize(tdsqlite3_file *pJfd, sqlite_int64 *pSize){ +static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ MemJournal *p = (MemJournal *)pJfd; *pSize = (sqlite_int64) p->endpoint.iOffset; return SQLITE_OK; } /* -** Table of methods for MemJournal tdsqlite3_file object. +** Table of methods for MemJournal sqlite3_file object. */ -static const struct tdsqlite3_io_methods MemJournalMethods = { +static const struct sqlite3_io_methods MemJournalMethods = { 1, /* iVersion */ memjrnlClose, /* xClose */ memjrnlRead, /* xRead */ @@ -100082,24 +100082,24 @@ static const struct tdsqlite3_io_methods MemJournalMethods = { ** positive value, then the journal file is initially created in-memory ** but may be flushed to disk later on. In this case the journal file is ** flushed to disk either when it grows larger than nSpill bytes in size, -** or when tdsqlite3JournalCreate() is called. +** or when sqlite3JournalCreate() is called. */ -SQLITE_PRIVATE int tdsqlite3JournalOpen( - tdsqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ +SQLITE_PRIVATE int sqlite3JournalOpen( + sqlite3_vfs *pVfs, /* The VFS to use for actual file I/O */ const char *zName, /* Name of the journal file */ - tdsqlite3_file *pJfd, /* Preallocated, blank file handle */ + sqlite3_file *pJfd, /* Preallocated, blank file handle */ int flags, /* Opening flags */ int nSpill /* Bytes buffered before opening the file */ ){ MemJournal *p = (MemJournal*)pJfd; /* Zero the file-handle object. If nSpill was passed zero, initialize - ** it using the tdsqlite3OsOpen() function of the underlying VFS. In this + ** it using the sqlite3OsOpen() function of the underlying VFS. In this ** case none of the code in this module is executed as a result of calls ** made on the journal file-handle. */ memset(p, 0, sizeof(MemJournal)); if( nSpill==0 ){ - return tdsqlite3OsOpen(pVfs, zName, pJfd, flags, 0); + return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0); } if( nSpill>0 ){ @@ -100109,7 +100109,7 @@ SQLITE_PRIVATE int tdsqlite3JournalOpen( assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) ); } - p->pMethod = (const tdsqlite3_io_methods*)&MemJournalMethods; + p->pMethod = (const sqlite3_io_methods*)&MemJournalMethods; p->nSpill = nSpill; p->flags = flags; p->zJournal = zName; @@ -100120,8 +100120,8 @@ SQLITE_PRIVATE int tdsqlite3JournalOpen( /* ** Open an in-memory journal file. */ -SQLITE_PRIVATE void tdsqlite3MemJournalOpen(tdsqlite3_file *pJfd){ - tdsqlite3JournalOpen(0, 0, pJfd, 0, -1); +SQLITE_PRIVATE void sqlite3MemJournalOpen(sqlite3_file *pJfd){ + sqlite3JournalOpen(0, 0, pJfd, 0, -1); } #if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ @@ -100132,7 +100132,7 @@ SQLITE_PRIVATE void tdsqlite3MemJournalOpen(tdsqlite3_file *pJfd){ ** nSpill parameter or as SQLITE_OPEN_MAIN_JOURNAL), and the underlying ** file has not yet been created, create it now. */ -SQLITE_PRIVATE int tdsqlite3JournalCreate(tdsqlite3_file *pJfd){ +SQLITE_PRIVATE int sqlite3JournalCreate(sqlite3_file *pJfd){ int rc = SQLITE_OK; MemJournal *p = (MemJournal*)pJfd; if( p->pMethod==&MemJournalMethods && ( @@ -100159,7 +100159,7 @@ SQLITE_PRIVATE int tdsqlite3JournalCreate(tdsqlite3_file *pJfd){ ** Return true if this "journal file" is currently stored in heap memory, ** or false otherwise. */ -SQLITE_PRIVATE int tdsqlite3JournalIsInMemory(tdsqlite3_file *p){ +SQLITE_PRIVATE int sqlite3JournalIsInMemory(sqlite3_file *p){ return p->pMethods==&MemJournalMethods; } @@ -100167,7 +100167,7 @@ SQLITE_PRIVATE int tdsqlite3JournalIsInMemory(tdsqlite3_file *p){ ** Return the number of bytes required to store a JournalFile that uses vfs ** pVfs to create the underlying on-disk files. */ -SQLITE_PRIVATE int tdsqlite3JournalSize(tdsqlite3_vfs *pVfs){ +SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ return MAX(pVfs->szOsFile, (int)sizeof(MemJournal)); } @@ -100201,20 +100201,20 @@ static int walkWindowList(Walker *pWalker, Window *pList){ Window *pWin; for(pWin=pList; pWin; pWin=pWin->pNextWin){ int rc; - rc = tdsqlite3WalkExprList(pWalker, pWin->pOrderBy); + rc = sqlite3WalkExprList(pWalker, pWin->pOrderBy); if( rc ) return WRC_Abort; - rc = tdsqlite3WalkExprList(pWalker, pWin->pPartition); + rc = sqlite3WalkExprList(pWalker, pWin->pPartition); if( rc ) return WRC_Abort; - rc = tdsqlite3WalkExpr(pWalker, pWin->pFilter); + rc = sqlite3WalkExpr(pWalker, pWin->pFilter); if( rc ) return WRC_Abort; - /* The next two are purely for calls to tdsqlite3RenameExprUnmap() - ** within tdsqlite3WindowOffsetExpr(). Because of constraints imposed - ** by tdsqlite3WindowOffsetExpr(), they can never fail. The results do + /* The next two are purely for calls to sqlite3RenameExprUnmap() + ** within sqlite3WindowOffsetExpr(). Because of constraints imposed + ** by sqlite3WindowOffsetExpr(), they can never fail. The results do ** not matter anyhow. */ - rc = tdsqlite3WalkExpr(pWalker, pWin->pStart); + rc = sqlite3WalkExpr(pWalker, pWin->pStart); if( NEVER(rc) ) return WRC_Abort; - rc = tdsqlite3WalkExpr(pWalker, pWin->pEnd); + rc = sqlite3WalkExpr(pWalker, pWin->pEnd); if( NEVER(rc) ) return WRC_Abort; } return WRC_Continue; @@ -100256,10 +100256,10 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ continue; }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ assert( !ExprHasProperty(pExpr, EP_WinFunc) ); - if( tdsqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; + if( sqlite3WalkSelect(pWalker, pExpr->x.pSelect) ) return WRC_Abort; }else{ if( pExpr->x.pList ){ - if( tdsqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, pExpr->x.pList) ) return WRC_Abort; } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ @@ -100272,20 +100272,20 @@ static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ } return WRC_Continue; } -SQLITE_PRIVATE int tdsqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ +SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue; } /* -** Call tdsqlite3WalkExpr() for every expression in list p or until +** Call sqlite3WalkExpr() for every expression in list p or until ** an abort request is seen. */ -SQLITE_PRIVATE int tdsqlite3WalkExprList(Walker *pWalker, ExprList *p){ +SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ int i; struct ExprList_item *pItem; if( p ){ for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ - if( tdsqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; } } return WRC_Continue; @@ -100297,13 +100297,13 @@ SQLITE_PRIVATE int tdsqlite3WalkExprList(Walker *pWalker, ExprList *p){ ** any expr callbacks and SELECT callbacks that come from subqueries. ** Return WRC_Abort or WRC_Continue. */ -SQLITE_PRIVATE int tdsqlite3WalkSelectExpr(Walker *pWalker, Select *p){ - if( tdsqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; - if( tdsqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; - if( tdsqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; - if( tdsqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; - if( tdsqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; - if( tdsqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; +SQLITE_PRIVATE int sqlite3WalkSelectExpr(Walker *pWalker, Select *p){ + if( sqlite3WalkExprList(pWalker, p->pEList) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pWhere) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, p->pGroupBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pHaving) ) return WRC_Abort; + if( sqlite3WalkExprList(pWalker, p->pOrderBy) ) return WRC_Abort; + if( sqlite3WalkExpr(pWalker, p->pLimit) ) return WRC_Abort; #if !defined(SQLITE_OMIT_WINDOWFUNC) && !defined(SQLITE_OMIT_ALTERTABLE) { Parse *pParse = pWalker->pParse; @@ -100325,7 +100325,7 @@ SQLITE_PRIVATE int tdsqlite3WalkSelectExpr(Walker *pWalker, Select *p){ ** and on any subqueries further down in the tree. Return ** WRC_Abort or WRC_Continue; */ -SQLITE_PRIVATE int tdsqlite3WalkSelectFrom(Walker *pWalker, Select *p){ +SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ SrcList *pSrc; int i; struct SrcList_item *pItem; @@ -100333,11 +100333,11 @@ SQLITE_PRIVATE int tdsqlite3WalkSelectFrom(Walker *pWalker, Select *p){ pSrc = p->pSrc; assert( pSrc!=0 ); for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ - if( pItem->pSelect && tdsqlite3WalkSelect(pWalker, pItem->pSelect) ){ + if( pItem->pSelect && sqlite3WalkSelect(pWalker, pItem->pSelect) ){ return WRC_Abort; } if( pItem->fg.isTabFunc - && tdsqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) + && sqlite3WalkExprList(pWalker, pItem->u1.pFuncArg) ){ return WRC_Abort; } @@ -100346,8 +100346,8 @@ SQLITE_PRIVATE int tdsqlite3WalkSelectFrom(Walker *pWalker, Select *p){ } /* -** Call tdsqlite3WalkExpr() for every expression in Select statement p. -** Invoke tdsqlite3WalkSelect() for subqueries in the FROM clause and +** Call sqlite3WalkExpr() for every expression in Select statement p. +** Invoke sqlite3WalkSelect() for subqueries in the FROM clause and ** on the compound select chain, p->pPrior. ** ** If it is not NULL, the xSelectCallback() callback is invoked before @@ -100362,15 +100362,15 @@ SQLITE_PRIVATE int tdsqlite3WalkSelectFrom(Walker *pWalker, Select *p){ ** If the Walker does not have an xSelectCallback() then this routine ** is a no-op returning WRC_Continue. */ -SQLITE_PRIVATE int tdsqlite3WalkSelect(Walker *pWalker, Select *p){ +SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ int rc; if( p==0 ) return WRC_Continue; if( pWalker->xSelectCallback==0 ) return WRC_Continue; do{ rc = pWalker->xSelectCallback(pWalker, p); if( rc ) return rc & WRC_Abort; - if( tdsqlite3WalkSelectExpr(pWalker, p) - || tdsqlite3WalkSelectFrom(pWalker, p) + if( sqlite3WalkSelectExpr(pWalker, p) + || sqlite3WalkSelectFrom(pWalker, p) ){ return WRC_Abort; } @@ -100421,7 +100421,7 @@ static void incrAggFunctionDepth(Expr *pExpr, int N){ memset(&w, 0, sizeof(w)); w.xExprCallback = incrAggDepth; w.u.n = N; - tdsqlite3WalkExpr(&w, pExpr); + sqlite3WalkExpr(&w, pExpr); } } @@ -100454,32 +100454,32 @@ static void resolveAlias( ){ Expr *pOrig; /* The iCol-th column of the result set */ Expr *pDup; /* Copy of pOrig */ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ assert( iCol>=0 && iColnExpr ); pOrig = pEList->a[iCol].pExpr; assert( pOrig!=0 ); db = pParse->db; - pDup = tdsqlite3ExprDup(db, pOrig, 0); + pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ - pDup = tdsqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); + pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } - /* Before calling tdsqlite3ExprDelete(), set the EP_Static flag. This + /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This ** prevents ExprDelete() from deleting the Expr structure itself, ** allowing it to be repopulated by the memcpy() on the following line. ** The pExpr->u.zToken might point into memory that will be freed by the - ** tdsqlite3DbFree(db, pDup) on the last line of this block, so be sure to - ** make a copy of the token before doing the tdsqlite3DbFree(). + ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to + ** make a copy of the token before doing the sqlite3DbFree(). */ ExprSetProperty(pExpr, EP_Static); - tdsqlite3ExprDelete(db, pExpr); + sqlite3ExprDelete(db, pExpr); memcpy(pExpr, pDup, sizeof(*pExpr)); if( !ExprHasProperty(pExpr, EP_IntValue) && pExpr->u.zToken!=0 ){ assert( (pExpr->flags & (EP_Reduced|EP_TokenOnly))==0 ); - pExpr->u.zToken = tdsqlite3DbStrDup(db, pExpr->u.zToken); + pExpr->u.zToken = sqlite3DbStrDup(db, pExpr->u.zToken); pExpr->flags |= EP_MemToken; } if( ExprHasProperty(pExpr, EP_WinFunc) ){ @@ -100489,7 +100489,7 @@ static void resolveAlias( assert( db->mallocFailed ); } } - tdsqlite3DbFree(db, pDup); + sqlite3DbFree(db, pDup); } ExprSetProperty(pExpr, EP_Alias); } @@ -100505,7 +100505,7 @@ static int nameInUsingClause(IdList *pUsing, const char *zCol){ if( pUsing ){ int k; for(k=0; knId; k++){ - if( tdsqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; + if( sqlite3StrICmp(pUsing->a[k].zName, zCol)==0 ) return 1; } } return 0; @@ -100518,7 +100518,7 @@ static int nameInUsingClause(IdList *pUsing, const char *zCol){ ** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will ** match anything. */ -SQLITE_PRIVATE int tdsqlite3MatchEName( +SQLITE_PRIVATE int sqlite3MatchEName( const struct ExprList_item *pItem, const char *zCol, const char *zTab, @@ -100529,16 +100529,16 @@ SQLITE_PRIVATE int tdsqlite3MatchEName( if( NEVER(pItem->eEName!=ENAME_TAB) ) return 0; zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} - if( zDb && (tdsqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ + if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ return 0; } zSpan += n+1; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} - if( zTab && (tdsqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){ + if( zTab && (sqlite3StrNICmp(zSpan, zTab, n)!=0 || zTab[n]!=0) ){ return 0; } zSpan += n+1; - if( zCol && tdsqlite3StrICmp(zSpan, zCol)!=0 ){ + if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){ return 0; } return 1; @@ -100547,11 +100547,11 @@ SQLITE_PRIVATE int tdsqlite3MatchEName( /* ** Return TRUE if the double-quoted string mis-feature should be supported. */ -static int areDoubleQuotedStringsEnabled(tdsqlite3 *db, NameContext *pTopNC){ +static int areDoubleQuotedStringsEnabled(sqlite3 *db, NameContext *pTopNC){ if( db->init.busy ) return 1; /* Always support for legacy schemas */ if( pTopNC->ncFlags & NC_IsDDL ){ /* Currently parsing a DDL statement */ - if( tdsqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){ + if( sqlite3WritableSchema(db) && (db->flags & SQLITE_DqsDML)!=0 ){ return 1; } return (db->flags & SQLITE_DqsDDL)!=0; @@ -100600,7 +100600,7 @@ static int lookupName( int cnt = 0; /* Number of matching column names */ int cntTab = 0; /* Number of matching table names */ int nSubquery = 0; /* How many levels of subquery */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ struct SrcList_item *pItem; /* Use for looping over pSrcList items */ struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ @@ -100633,7 +100633,7 @@ static int lookupName( }else{ for(i=0; inDb; i++){ assert( db->aDb[i].zDbSName ); - if( tdsqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){ + if( sqlite3StrICmp(db->aDb[i].zDbSName,zDb)==0 ){ pSchema = db->aDb[i].pSchema; break; } @@ -100656,7 +100656,7 @@ static int lookupName( int hit = 0; pEList = pItem->pSelect->pEList; for(j=0; jnExpr; j++){ - if( tdsqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ + if( sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ cnt++; cntTab = 2; pMatch = pItem; @@ -100672,18 +100672,18 @@ static int lookupName( if( zTab ){ const char *zTabName = pItem->zAlias ? pItem->zAlias : pTab->zName; assert( zTabName!=0 ); - if( tdsqlite3StrICmp(zTabName, zTab)!=0 ){ + if( sqlite3StrICmp(zTabName, zTab)!=0 ){ continue; } if( IN_RENAME_OBJECT && pItem->zAlias ){ - tdsqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); + sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); } } if( 0==(cntTab++) ){ pMatch = pItem; } for(j=0, pCol=pTab->aCol; jnCol; j++, pCol++){ - if( tdsqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ /* If there has been exactly one prior match and this match ** is for the right-hand table of a NATURAL JOIN or is in a ** USING clause, then skip this match. @@ -100723,10 +100723,10 @@ static int lookupName( if( pParse->pTriggerTab!=0 ){ int op = pParse->eTriggerOp; assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); - if( op!=TK_DELETE && tdsqlite3StrICmp("new",zTab) == 0 ){ + if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ pExpr->iTable = 1; pTab = pParse->pTriggerTab; - }else if( op!=TK_INSERT && tdsqlite3StrICmp("old",zTab)==0 ){ + }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ pExpr->iTable = 0; pTab = pParse->pTriggerTab; } @@ -100735,7 +100735,7 @@ static int lookupName( #ifndef SQLITE_OMIT_UPSERT if( (pNC->ncFlags & NC_UUpsert)!=0 ){ Upsert *pUpsert = pNC->uNC.pUpsert; - if( pUpsert && tdsqlite3StrICmp("excluded",zTab)==0 ){ + if( pUpsert && sqlite3StrICmp("excluded",zTab)==0 ){ pTab = pUpsert->pUpsertSrc->a[0].pTab; pExpr->iTable = 2; } @@ -100747,14 +100747,14 @@ static int lookupName( pSchema = pTab->pSchema; cntTab++; for(iCol=0, pCol=pTab->aCol; iColnCol; iCol++, pCol++){ - if( tdsqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ if( iCol==pTab->iPKey ){ iCol = -1; } break; } } - if( iCol>=pTab->nCol && tdsqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ + if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && VisibleRowid(pTab) ){ /* IMP: R-51414-32910 */ iCol = -1; } @@ -100804,7 +100804,7 @@ static int lookupName( && cntTab==1 && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 - && tdsqlite3IsRowid(zCol) + && sqlite3IsRowid(zCol) && VisibleRowid(pMatch->pTab) ){ cnt = 1; @@ -100828,7 +100828,7 @@ static int lookupName( ** or HAVING clauses, or as part of a larger expression in the ORDER BY ** clause is not standard SQL. This is a (goofy) SQLite extension, that ** is supported for backwards compatibility only. Hence, we issue a warning - ** on tdsqlite3_log() whenever the capability is used. + ** on sqlite3_log() whenever the capability is used. */ if( (pNC->ncFlags & NC_UEList)!=0 && cnt==0 @@ -100839,7 +100839,7 @@ static int lookupName( for(j=0; jnExpr; j++){ char *zAs = pEList->a[j].zEName; if( pEList->a[j].eEName==ENAME_NAME - && tdsqlite3_stricmp(zAs, zCol)==0 + && sqlite3_stricmp(zAs, zCol)==0 ){ Expr *pOrig; assert( pExpr->pLeft==0 && pExpr->pRight==0 ); @@ -100847,17 +100847,17 @@ static int lookupName( assert( pExpr->x.pSelect==0 ); pOrig = pEList->a[j].pExpr; if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){ - tdsqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); + sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); return WRC_Abort; } if( ExprHasProperty(pOrig, EP_Win) && ((pNC->ncFlags&NC_AllowWin)==0 || pNC!=pTopNC ) ){ - tdsqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs); + sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs); return WRC_Abort; } - if( tdsqlite3ExprVectorSize(pOrig)!=1 ){ - tdsqlite3ErrorMsg(pParse, "row value misused"); + if( sqlite3ExprVectorSize(pOrig)!=1 ){ + sqlite3ErrorMsg(pParse, "row value misused"); return WRC_Abort; } resolveAlias(pParse, pEList, j, pExpr, "", nSubquery); @@ -100865,7 +100865,7 @@ static int lookupName( pMatch = 0; assert( zTab==0 && zDb==0 ); if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); } goto lookupname_end; } @@ -100910,16 +100910,16 @@ static int lookupName( ** a huge amount of legacy SQL that uses it. So for now, we just ** issue a warning. */ - tdsqlite3_log(SQLITE_WARNING, + sqlite3_log(SQLITE_WARNING, "double-quoted string literal: \"%w\"", zCol); #ifdef SQLITE_ENABLE_NORMALIZE - tdsqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol); + sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol); #endif pExpr->op = TK_STRING; pExpr->y.pTab = 0; return WRC_Prune; } - if( tdsqlite3ExprIdToTrueFalse(pExpr) ){ + if( sqlite3ExprIdToTrueFalse(pExpr) ){ return WRC_Prune; } } @@ -100932,11 +100932,11 @@ static int lookupName( const char *zErr; zErr = cnt==0 ? "no such column" : "ambiguous column name"; if( zDb ){ - tdsqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); + sqlite3ErrorMsg(pParse, "%s: %s.%s.%s", zErr, zDb, zTab, zCol); }else if( zTab ){ - tdsqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); + sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); }else{ - tdsqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); + sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); } pParse->checkSchema = 1; pTopNC->nErr++; @@ -100977,9 +100977,9 @@ static int lookupName( /* Clean up and return */ - tdsqlite3ExprDelete(db, pExpr->pLeft); + sqlite3ExprDelete(db, pExpr->pLeft); pExpr->pLeft = 0; - tdsqlite3ExprDelete(db, pExpr->pRight); + sqlite3ExprDelete(db, pExpr->pRight); pExpr->pRight = 0; pExpr->op = eNewExprOp; ExprSetProperty(pExpr, EP_Leaf); @@ -100987,7 +100987,7 @@ lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); if( !ExprHasProperty(pExpr, EP_Alias) ){ - tdsqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); + sqlite3AuthRead(pParse, pExpr, pSchema, pNC->pSrcList); } /* Increment the nRef value on all name contexts from TopNC up to ** the point where the name matched. */ @@ -101007,8 +101007,8 @@ lookupname_end: ** Allocate and return a pointer to an expression to load the column iCol ** from datasource iSrc in SrcList pSrc. */ -SQLITE_PRIVATE Expr *tdsqlite3CreateColumnExpr(tdsqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ - Expr *p = tdsqlite3ExprAlloc(db, TK_COLUMN, 0, 0); +SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){ + Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); if( p ){ struct SrcList_item *pItem = &pSrc->a[iSrc]; Table *pTab = p->y.pTab = pItem->pTab; @@ -101063,10 +101063,10 @@ static void notValidImpl( #ifndef SQLITE_OMIT_GENERATED_COLUMNS else if( pNC->ncFlags & NC_GenCol ) zIn = "generated columns"; #endif - tdsqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); + sqlite3ErrorMsg(pParse, "%s prohibited in %s", zMsg, zIn); if( pExpr ) pExpr->op = TK_NULL; } -#define tdsqlite3ResolveNotValid(P,N,M,X,E) \ +#define sqlite3ResolveNotValid(P,N,M,X,E) \ assert( ((X)&~(NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol))==0 ); \ if( ((N)->ncFlags & (X))!=0 ) notValidImpl(P,N,M,E); @@ -101078,14 +101078,14 @@ static void notValidImpl( static int exprProbability(Expr *p){ double r = -1.0; if( p->op!=TK_FLOAT ) return -1; - tdsqlite3AtoF(p->u.zToken, &r, tdsqlite3Strlen30(p->u.zToken), SQLITE_UTF8); + sqlite3AtoF(p->u.zToken, &r, sqlite3Strlen30(p->u.zToken), SQLITE_UTF8); assert( r>=0.0 ); if( r>1.0 ) return -1; return (int)(r*134217728.0); } /* -** This routine is callback for tdsqlite3WalkExpr(). +** This routine is callback for sqlite3WalkExpr(). ** ** Resolve symbolic names into TK_COLUMN operators for the current ** node in the expression tree. Return 0 to continue the search down @@ -101159,7 +101159,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ Expr *pLeft = pExpr->pLeft; testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); - tdsqlite3ResolveNotValid(pParse, pNC, "the \".\" operator", + sqlite3ResolveNotValid(pParse, pNC, "the \".\" operator", NC_IdxExpr|NC_GenCol, 0); pRight = pExpr->pRight; if( pRight->op==TK_ID ){ @@ -101173,8 +101173,8 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ zTable = pLeft->u.zToken; zColumn = pRight->u.zToken; if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); - tdsqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); + sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); + sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); } } return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); @@ -101198,10 +101198,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); zId = pExpr->u.zToken; - nId = tdsqlite3Strlen30(zId); - pDef = tdsqlite3FindFunction(pParse->db, zId, n, enc, 0); + nId = sqlite3Strlen30(zId); + pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ - pDef = tdsqlite3FindFunction(pParse->db, zId, -2, enc, 0); + pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0); if( pDef==0 ){ no_such_func = 1; }else{ @@ -101214,7 +101214,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( n==2 ){ pExpr->iTable = exprProbability(pList->a[1].pExpr); if( pExpr->iTable<0 ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "second argument to likelihood() must be a " "constant between 0.0 and 1.0"); pNC->nErr++; @@ -101234,10 +101234,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } #ifndef SQLITE_OMIT_AUTHORIZATION { - int auth = tdsqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0); + int auth = sqlite3AuthCheck(pParse, SQLITE_FUNCTION, 0,pDef->zName,0); if( auth!=SQLITE_OK ){ if( auth==SQLITE_DENY ){ - tdsqlite3ErrorMsg(pParse, "not authorized to use function: %s", + sqlite3ErrorMsg(pParse, "not authorized to use function: %s", pDef->zName); pNC->nErr++; } @@ -101260,7 +101260,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** in an index or generated column. Curiously, they can be used ** in a CHECK constraint. SQLServer, MySQL, and PostgreSQL all ** all this. */ - tdsqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", + sqlite3ResolveNotValid(pParse, pNC, "non-deterministic functions", NC_IdxExpr|NC_PartIdx|NC_GenCol, 0); }else{ assert( (NC_SelfRef & 0xff)==NC_SelfRef ); /* Must fit in 8 bits */ @@ -101272,7 +101272,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ && (pParse->db->mDbFlags & DBFLAG_InternalFunc)==0 ){ /* Internal-use-only functions are disallowed unless the - ** SQL is being compiled using tdsqlite3NestedParse() or + ** SQL is being compiled using sqlite3NestedParse() or ** the SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test-control has be ** used to activate internal functionsn for testing purposes */ no_such_func = 1; @@ -101281,7 +101281,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ if( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 && !IN_RENAME_OBJECT ){ - tdsqlite3ExprFunctionUsable(pParse, pExpr, pDef); + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); } } @@ -101292,7 +101292,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) ); if( pDef && pDef->xValue==0 && pWin ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "%.*s() may not be used as a window function", nId, zId ); pNC->nErr++; @@ -101307,13 +101307,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ }else{ zType = "aggregate"; } - tdsqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); + sqlite3ErrorMsg(pParse, "misuse of %s function %.*s()",zType,nId,zId); pNC->nErr++; is_agg = 0; } #else if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) ){ - tdsqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId); + sqlite3ErrorMsg(pParse,"misuse of aggregate function %.*s()",nId,zId); pNC->nErr++; is_agg = 0; } @@ -101323,16 +101323,16 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ && pParse->explain==0 #endif ){ - tdsqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); + sqlite3ErrorMsg(pParse, "no such function: %.*s", nId, zId); pNC->nErr++; }else if( wrong_num_args ){ - tdsqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", + sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()", nId, zId); pNC->nErr++; } #ifndef SQLITE_OMIT_WINDOWFUNC else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "FILTER may not be used with non-aggregate %.*s()", nId, zId ); @@ -101355,19 +101355,19 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ is_agg = 1; } #endif - tdsqlite3WalkExprList(pWalker, pList); + sqlite3WalkExprList(pWalker, pList); if( is_agg ){ #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ Select *pSel = pNC->pWinSelect; assert( pWin==pExpr->y.pWin ); if( IN_RENAME_OBJECT==0 ){ - tdsqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); + sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); } - tdsqlite3WalkExprList(pWalker, pWin->pPartition); - tdsqlite3WalkExprList(pWalker, pWin->pOrderBy); - tdsqlite3WalkExpr(pWalker, pWin->pFilter); - tdsqlite3WindowLink(pSel, pWin); + sqlite3WalkExprList(pWalker, pWin->pPartition); + sqlite3WalkExprList(pWalker, pWin->pOrderBy); + sqlite3WalkExpr(pWalker, pWin->pFilter); + sqlite3WindowLink(pSel, pWin); pNC->ncFlags |= NC_HasWin; }else #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -101377,10 +101377,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ pExpr->op2 = 0; #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ - tdsqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); + sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter); } #endif - while( pNC2 && !tdsqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ + while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){ pExpr->op2++; pNC2 = pNC2->pNext; } @@ -101411,9 +101411,9 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_PartIdx ); testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); - tdsqlite3ResolveNotValid(pParse, pNC, "subqueries", + sqlite3ResolveNotValid(pParse, pNC, "subqueries", NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr); - tdsqlite3WalkSelect(pWalker, pExpr->x.pSelect); + sqlite3WalkSelect(pWalker, pExpr->x.pSelect); assert( pNC->nRef>=nRef ); if( nRef!=pNC->nRef ){ ExprSetProperty(pExpr, EP_VarSelect); @@ -101427,13 +101427,13 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pNC->ncFlags & NC_PartIdx ); testcase( pNC->ncFlags & NC_IdxExpr ); testcase( pNC->ncFlags & NC_GenCol ); - tdsqlite3ResolveNotValid(pParse, pNC, "parameters", + sqlite3ResolveNotValid(pParse, pNC, "parameters", NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr); break; } case TK_IS: case TK_ISNOT: { - Expr *pRight = tdsqlite3ExprSkipCollateAndLikely(pExpr->pRight); + Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight); assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ @@ -101458,15 +101458,15 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ int nLeft, nRight; if( pParse->db->mallocFailed ) break; assert( pExpr->pLeft!=0 ); - nLeft = tdsqlite3ExprVectorSize(pExpr->pLeft); + nLeft = sqlite3ExprVectorSize(pExpr->pLeft); if( pExpr->op==TK_BETWEEN ){ - nRight = tdsqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr); + nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[0].pExpr); if( nRight==nLeft ){ - nRight = tdsqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr); + nRight = sqlite3ExprVectorSize(pExpr->x.pList->a[1].pExpr); } }else{ assert( pExpr->pRight!=0 ); - nRight = tdsqlite3ExprVectorSize(pExpr->pRight); + nRight = sqlite3ExprVectorSize(pExpr->pRight); } if( nLeft!=nRight ){ testcase( pExpr->op==TK_EQ ); @@ -101478,7 +101478,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ testcase( pExpr->op==TK_IS ); testcase( pExpr->op==TK_ISNOT ); testcase( pExpr->op==TK_BETWEEN ); - tdsqlite3ErrorMsg(pParse, "row value misused"); + sqlite3ErrorMsg(pParse, "row value misused"); } break; } @@ -101511,7 +101511,7 @@ static int resolveAsName( char *zCol = pE->u.zToken; for(i=0; inExpr; i++){ if( pEList->a[i].eEName==ENAME_NAME - && tdsqlite3_stricmp(pEList->a[i].zEName, zCol)==0 + && sqlite3_stricmp(pEList->a[i].zEName, zCol)==0 ){ return i+1; } @@ -101546,11 +101546,11 @@ static int resolveOrderByTermToExprList( int i; /* Loop counter */ ExprList *pEList; /* The columns of the result set */ NameContext nc; /* Name context for resolving pE */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ int rc; /* Return code from subprocedures */ u8 savedSuppErr; /* Saved value of db->suppressErr */ - assert( tdsqlite3ExprIsInteger(pE, &i)==0 ); + assert( sqlite3ExprIsInteger(pE, &i)==0 ); pEList = pSelect->pEList; /* Resolve all names in the ORDER BY term expression @@ -101564,7 +101564,7 @@ static int resolveOrderByTermToExprList( db = pParse->db; savedSuppErr = db->suppressErr; db->suppressErr = 1; - rc = tdsqlite3ResolveExprNames(&nc, pE); + rc = sqlite3ResolveExprNames(&nc, pE); db->suppressErr = savedSuppErr; if( rc ) return 0; @@ -101573,7 +101573,7 @@ static int resolveOrderByTermToExprList( ** result-set entry. */ for(i=0; inExpr; i++){ - if( tdsqlite3ExprCompare(0, pEList->a[i].pExpr, pE, -1)<2 ){ + if( sqlite3ExprCompare(0, pEList->a[i].pExpr, pE, -1)<2 ){ return i+1; } } @@ -101591,7 +101591,7 @@ static void resolveOutOfRangeError( int i, /* The index (1-based) of the term out of range */ int mx /* Largest permissible value of i */ ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "%r %s BY term out of range - should be " "between 1 and %d", i, zType, mx); } @@ -101618,14 +101618,14 @@ static int resolveCompoundOrderBy( int i; ExprList *pOrderBy; ExprList *pEList; - tdsqlite3 *db; + sqlite3 *db; int moreToDo = 1; pOrderBy = pSelect->pOrderBy; if( pOrderBy==0 ) return 0; db = pParse->db; if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - tdsqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); + sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); return 1; } for(i=0; inExpr; i++){ @@ -101645,8 +101645,8 @@ static int resolveCompoundOrderBy( int iCol = -1; Expr *pE, *pDup; if( pItem->done ) continue; - pE = tdsqlite3ExprSkipCollateAndLikely(pItem->pExpr); - if( tdsqlite3ExprIsInteger(pE, &iCol) ){ + pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); + if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); return 1; @@ -101670,14 +101670,14 @@ static int resolveCompoundOrderBy( if( IN_RENAME_OBJECT ){ pDup = pE; }else{ - pDup = tdsqlite3ExprDup(db, pE, 0); + pDup = sqlite3ExprDup(db, pE, 0); } if( !db->mallocFailed ){ assert(pDup); iCol = resolveOrderByTermToExprList(pParse, pSelect, pDup); } if( !IN_RENAME_OBJECT ){ - tdsqlite3ExprDelete(db, pDup); + sqlite3ExprDelete(db, pDup); } } } @@ -101685,7 +101685,7 @@ static int resolveCompoundOrderBy( /* Convert the ORDER BY term into an integer column number iCol, ** taking care to preserve the COLLATE clause if it exists */ if( !IN_RENAME_OBJECT ){ - Expr *pNew = tdsqlite3Expr(db, TK_INTEGER, 0); + Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); if( pNew==0 ) return 1; pNew->flags |= EP_IntValue; pNew->u.iValue = iCol; @@ -101698,7 +101698,7 @@ static int resolveCompoundOrderBy( assert( pParent->pLeft==pE ); pParent->pLeft = pNew; } - tdsqlite3ExprDelete(db, pE); + sqlite3ExprDelete(db, pE); pItem->u.x.iOrderByCol = (u16)iCol; } pItem->done = 1; @@ -101710,7 +101710,7 @@ static int resolveCompoundOrderBy( } for(i=0; inExpr; i++){ if( pOrderBy->a[i].done==0 ){ - tdsqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " + sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " "column in the result set", i+1); return 1; } @@ -101728,24 +101728,24 @@ static int resolveCompoundOrderBy( ** If any errors are detected, add an error message to pParse and ** return non-zero. Return zero if no errors are seen. */ -SQLITE_PRIVATE int tdsqlite3ResolveOrderGroupBy( +SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy( Parse *pParse, /* Parsing context. Leave error messages here */ Select *pSelect, /* The SELECT statement containing the clause */ ExprList *pOrderBy, /* The ORDER BY or GROUP BY clause to be processed */ const char *zType /* "ORDER" or "GROUP" */ ){ int i; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; ExprList *pEList; struct ExprList_item *pItem; if( pOrderBy==0 || pParse->db->mallocFailed || IN_RENAME_OBJECT ) return 0; if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - tdsqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); + sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); return 1; } pEList = pSelect->pEList; - assert( pEList!=0 ); /* tdsqlite3SelectNew() guarantees this */ + assert( pEList!=0 ); /* sqlite3SelectNew() guarantees this */ for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ if( pItem->u.x.iOrderByCol ){ if( pItem->u.x.iOrderByCol>pEList->nExpr ){ @@ -101767,7 +101767,7 @@ static int resolveRemoveWindowsCb(Walker *pWalker, Expr *pExpr){ UNUSED_PARAMETER(pWalker); if( ExprHasProperty(pExpr, EP_WinFunc) ){ Window *pWin = pExpr->y.pWin; - tdsqlite3WindowUnlinkFromSelect(pWin); + sqlite3WindowUnlinkFromSelect(pWin); } return WRC_Continue; } @@ -101782,7 +101782,7 @@ static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){ memset(&sWalker, 0, sizeof(Walker)); sWalker.xExprCallback = resolveRemoveWindowsCb; sWalker.u.pSelect = pSelect; - tdsqlite3WalkExpr(&sWalker, pExpr); + sqlite3WalkExpr(&sWalker, pExpr); } } #else @@ -101801,7 +101801,7 @@ static void windowRemoveExprFromSelect(Select *pSelect, Expr *pExpr){ ** the order-by term is an identifier that corresponds to the AS-name of ** a result-set expression, then the term resolves to a copy of the ** result-set expression. Otherwise, the expression is resolved in -** the usual way - using tdsqlite3ResolveExprNames(). +** the usual way - using sqlite3ResolveExprNames(). ** ** This routine returns the number of errors. If errors occur, then ** an appropriate error message might be left in pParse. (OOM errors @@ -101824,21 +101824,21 @@ static int resolveOrderGroupBy( pParse = pNC->pParse; for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ Expr *pE = pItem->pExpr; - Expr *pE2 = tdsqlite3ExprSkipCollateAndLikely(pE); + Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE); if( zType[0]!='G' ){ iCol = resolveAsName(pParse, pSelect->pEList, pE2); if( iCol>0 ){ /* If an AS-name match is found, mark this ORDER BY column as being ** a copy of the iCol-th result-set column. The subsequent call to - ** tdsqlite3ResolveOrderGroupBy() will convert the expression to a + ** sqlite3ResolveOrderGroupBy() will convert the expression to a ** copy of the iCol-th result-set expression. */ pItem->u.x.iOrderByCol = (u16)iCol; continue; } } - if( tdsqlite3ExprIsInteger(pE2, &iCol) ){ + if( sqlite3ExprIsInteger(pE2, &iCol) ){ /* The ORDER BY term is an integer constant. Again, set the column - ** number so that tdsqlite3ResolveOrderGroupBy() will convert the + ** number so that sqlite3ResolveOrderGroupBy() will convert the ** order-by term to a copy of the result-set expression */ if( iCol<1 || iCol>0xffff ){ resolveOutOfRangeError(pParse, zType, i+1, nResult); @@ -101850,11 +101850,11 @@ static int resolveOrderGroupBy( /* Otherwise, treat the ORDER BY term as an ordinary expression */ pItem->u.x.iOrderByCol = 0; - if( tdsqlite3ResolveExprNames(pNC, pE) ){ + if( sqlite3ResolveExprNames(pNC, pE) ){ return 1; } for(j=0; jpEList->nExpr; j++){ - if( tdsqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ + if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ /* Since this expresion is being changed into a reference ** to an identical expression in the result set, remove all Window ** objects belonging to the expression from the Select.pWin list. */ @@ -101863,7 +101863,7 @@ static int resolveOrderGroupBy( } } } - return tdsqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); + return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType); } /* @@ -101878,7 +101878,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ int i; /* Loop counter */ ExprList *pGroupBy; /* The GROUP BY clause */ Select *pLeftmost; /* Left-most of SELECT of a compound */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ assert( p!=0 ); @@ -101889,16 +101889,16 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ pParse = pWalker->pParse; db = pParse->db; - /* Normally tdsqlite3SelectExpand() will be called first and will have + /* Normally sqlite3SelectExpand() will be called first and will have ** already expanded this SELECT. However, if this is a subquery within - ** an expression, tdsqlite3ResolveExprNames() will be called without a - ** prior call to tdsqlite3SelectExpand(). When that happens, let - ** tdsqlite3SelectPrep() do all of the processing for this SELECT. - ** tdsqlite3SelectPrep() will invoke both tdsqlite3SelectExpand() and + ** an expression, sqlite3ResolveExprNames() will be called without a + ** prior call to sqlite3SelectExpand(). When that happens, let + ** sqlite3SelectPrep() do all of the processing for this SELECT. + ** sqlite3SelectPrep() will invoke both sqlite3SelectExpand() and ** this routine in the correct order. */ if( (p->selFlags & SF_Expanded)==0 ){ - tdsqlite3SelectPrep(pParse, p, pOuterNC); + sqlite3SelectPrep(pParse, p, pOuterNC); return (pParse->nErr || db->mallocFailed) ? WRC_Abort : WRC_Prune; } @@ -101916,7 +101916,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pWinSelect = p; - if( tdsqlite3ResolveExprNames(&sNC, p->pLimit) ){ + if( sqlite3ResolveExprNames(&sNC, p->pLimit) ){ return WRC_Abort; } @@ -101951,7 +101951,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ for(pNC=pOuterNC; pNC; pNC=pNC->pNext) nRef += pNC->nRef; if( pItem->zName ) pParse->zAuthContext = pItem->zName; - tdsqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); + sqlite3ResolveSelectNames(pParse, pItem->pSelect, pOuterNC); pParse->zAuthContext = zSavedContext; if( pParse->nErr || db->mallocFailed ) return WRC_Abort; @@ -101961,7 +101961,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } } - /* Set up the local name-context to pass to tdsqlite3ResolveExprNames() to + /* Set up the local name-context to pass to sqlite3ResolveExprNames() to ** resolve the result-set expression list. */ sNC.ncFlags = NC_AllowAgg|NC_AllowWin; @@ -101969,7 +101969,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ sNC.pNext = pOuterNC; /* Resolve names in the result set. */ - if( tdsqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; + if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; sNC.ncFlags &= ~NC_AllowWin; /* If there are no aggregate functions in the result-set, and no GROUP BY @@ -101987,7 +101987,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* If a HAVING clause is present, then there must be a GROUP BY clause. */ if( p->pHaving && !pGroupBy ){ - tdsqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); + sqlite3ErrorMsg(pParse, "a GROUP BY clause is required before HAVING"); return WRC_Abort; } @@ -102002,14 +102002,14 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ assert( (sNC.ncFlags & (NC_UAggInfo|NC_UUpsert))==0 ); sNC.uNC.pEList = p->pEList; sNC.ncFlags |= NC_UEList; - if( tdsqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; - if( tdsqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; + if( sqlite3ResolveExprNames(&sNC, p->pHaving) ) return WRC_Abort; + if( sqlite3ResolveExprNames(&sNC, p->pWhere) ) return WRC_Abort; /* Resolve names in table-valued-function arguments */ for(i=0; ipSrc->nSrc; i++){ struct SrcList_item *pItem = &p->pSrc->a[i]; if( pItem->fg.isTabFunc - && tdsqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) + && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) ){ return WRC_Abort; } @@ -102063,7 +102063,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ } for(i=0, pItem=pGroupBy->a; inExpr; i++, pItem++){ if( ExprHasProperty(pItem->pExpr, EP_Agg) ){ - tdsqlite3ErrorMsg(pParse, "aggregate functions are not allowed in " + sqlite3ErrorMsg(pParse, "aggregate functions are not allowed in " "the GROUP BY clause"); return WRC_Abort; } @@ -102074,8 +102074,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ if( IN_RENAME_OBJECT ){ Window *pWin; for(pWin=p->pWinDefn; pWin; pWin=pWin->pNextWin){ - if( tdsqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) - || tdsqlite3ResolveExprListNames(&sNC, pWin->pPartition) + if( sqlite3ResolveExprListNames(&sNC, pWin->pOrderBy) + || sqlite3ResolveExprListNames(&sNC, pWin->pPartition) ){ return WRC_Abort; } @@ -102086,7 +102086,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ /* If this is part of a compound SELECT, check that it has the right ** number of expressions in the select list. */ if( p->pNext && p->pEList->nExpr!=p->pNext->pEList->nExpr ){ - tdsqlite3SelectWrongNumTermsError(pParse, p->pNext); + sqlite3SelectWrongNumTermsError(pParse, p->pNext); return WRC_Abort; } @@ -102154,7 +102154,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){ ** An error message is left in pParse if anything is amiss. The number ** if errors is returned. */ -SQLITE_PRIVATE int tdsqlite3ResolveExprNames( +SQLITE_PRIVATE int sqlite3ResolveExprNames( NameContext *pNC, /* Namespace to resolve expressions in. */ Expr *pExpr /* The expression to be analyzed. */ ){ @@ -102171,11 +102171,11 @@ SQLITE_PRIVATE int tdsqlite3ResolveExprNames( w.u.pNC = pNC; #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight += pExpr->nHeight; - if( tdsqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ + if( sqlite3ExprCheckHeight(w.pParse, w.pParse->nHeight) ){ return SQLITE_ERROR; } #endif - tdsqlite3WalkExpr(&w, pExpr); + sqlite3WalkExpr(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight -= pExpr->nHeight; #endif @@ -102190,17 +102190,17 @@ SQLITE_PRIVATE int tdsqlite3ResolveExprNames( /* ** Resolve all names for all expression in an expression list. This is -** just like tdsqlite3ResolveExprNames() except that it works for an expression +** just like sqlite3ResolveExprNames() except that it works for an expression ** list rather than a single expression. */ -SQLITE_PRIVATE int tdsqlite3ResolveExprListNames( +SQLITE_PRIVATE int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ ExprList *pList /* The expression list to be analyzed. */ ){ int i; if( pList ){ for(i=0; inExpr; i++){ - if( tdsqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; + if( sqlite3ResolveExprNames(pNC, pList->a[i].pExpr) ) return WRC_Abort; } } return WRC_Continue; @@ -102212,13 +102212,13 @@ SQLITE_PRIVATE int tdsqlite3ResolveExprListNames( ** subqueries in expressions, and subqueries used as FROM clause ** terms. ** -** See tdsqlite3ResolveExprNames() for a description of the kinds of +** See sqlite3ResolveExprNames() for a description of the kinds of ** transformations that occur. ** ** All SELECT statements should have been expanded using -** tdsqlite3SelectExpand() prior to invoking this routine. +** sqlite3SelectExpand() prior to invoking this routine. */ -SQLITE_PRIVATE void tdsqlite3ResolveSelectNames( +SQLITE_PRIVATE void sqlite3ResolveSelectNames( Parse *pParse, /* The parser context */ Select *p, /* The SELECT statement being coded. */ NameContext *pOuterNC /* Name context for parent SELECT statement */ @@ -102231,7 +102231,7 @@ SQLITE_PRIVATE void tdsqlite3ResolveSelectNames( w.xSelectCallback2 = 0; w.pParse = pParse; w.u.pNC = pOuterNC; - tdsqlite3WalkSelect(&w, p); + sqlite3WalkSelect(&w, p); } /* @@ -102252,7 +102252,7 @@ SQLITE_PRIVATE void tdsqlite3ResolveSelectNames( ** ** Any errors cause an error message to be set in pParse. */ -SQLITE_PRIVATE int tdsqlite3ResolveSelfReference( +SQLITE_PRIVATE int sqlite3ResolveSelfReference( Parse *pParse, /* Parsing context */ Table *pTab, /* The table being referenced, or NULL */ int type, /* NC_IsCheck, NC_PartIdx, NC_IdxExpr, NC_GenCol, or 0 */ @@ -102282,8 +102282,8 @@ SQLITE_PRIVATE int tdsqlite3ResolveSelfReference( sNC.pParse = pParse; sNC.pSrcList = &sSrc; sNC.ncFlags = type | NC_IsDDL; - if( (rc = tdsqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; - if( pList ) rc = tdsqlite3ResolveExprListNames(&sNC, pList); + if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc; + if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList); return rc; } @@ -102312,7 +102312,7 @@ static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree); /* ** Return the affinity character for a single column of a table. */ -SQLITE_PRIVATE char tdsqlite3TableColumnAffinity(Table *pTab, int iCol){ +SQLITE_PRIVATE char sqlite3TableColumnAffinity(Table *pTab, int iCol){ assert( iColnCol ); return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER; } @@ -102333,7 +102333,7 @@ SQLITE_PRIVATE char tdsqlite3TableColumnAffinity(Table *pTab, int iCol){ ** SELECT a AS b FROM t1 WHERE b; ** SELECT * FROM t1 WHERE (select a from t1); */ -SQLITE_PRIVATE char tdsqlite3ExprAffinity(Expr *pExpr){ +SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr){ int op; while( ExprHasProperty(pExpr, EP_Skip) ){ assert( pExpr->op==TK_COLLATE ); @@ -102343,26 +102343,26 @@ SQLITE_PRIVATE char tdsqlite3ExprAffinity(Expr *pExpr){ op = pExpr->op; if( op==TK_SELECT ){ assert( pExpr->flags&EP_xIsSelect ); - return tdsqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); + return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr); } if( op==TK_REGISTER ) op = pExpr->op2; #ifndef SQLITE_OMIT_CAST if( op==TK_CAST ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); - return tdsqlite3AffinityType(pExpr->u.zToken, 0); + return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->y.pTab ){ - return tdsqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); } if( op==TK_SELECT_COLUMN ){ assert( pExpr->pLeft->flags&EP_xIsSelect ); - return tdsqlite3ExprAffinity( + return sqlite3ExprAffinity( pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr ); } if( op==TK_VECTOR ){ - return tdsqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); + return sqlite3ExprAffinity(pExpr->x.pList->a[0].pExpr); } return pExpr->affExpr; } @@ -102375,14 +102375,14 @@ SQLITE_PRIVATE char tdsqlite3ExprAffinity(Expr *pExpr){ ** If a memory allocation error occurs, that fact is recorded in pParse->db ** and the pExpr parameter is returned unchanged. */ -SQLITE_PRIVATE Expr *tdsqlite3ExprAddCollateToken( +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateToken( Parse *pParse, /* Parsing context */ Expr *pExpr, /* Add the "COLLATE" clause to this expression */ const Token *pCollName, /* Name of collating sequence */ int dequote /* True to dequote pCollName */ ){ if( pCollName->n>0 ){ - Expr *pNew = tdsqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); + Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote); if( pNew ){ pNew->pLeft = pExpr; pNew->flags |= EP_Collate|EP_Skip; @@ -102391,17 +102391,17 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprAddCollateToken( } return pExpr; } -SQLITE_PRIVATE Expr *tdsqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ +SQLITE_PRIVATE Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ Token s; assert( zC!=0 ); - tdsqlite3TokenInit(&s, (char*)zC); - return tdsqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); + sqlite3TokenInit(&s, (char*)zC); + return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0); } /* ** Skip over any TK_COLLATE operators. */ -SQLITE_PRIVATE Expr *tdsqlite3ExprSkipCollate(Expr *pExpr){ +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollate(Expr *pExpr){ while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; @@ -102414,7 +102414,7 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprSkipCollate(Expr *pExpr){ ** or likelihood() or likely() functions at the root of an ** expression. */ -SQLITE_PRIVATE Expr *tdsqlite3ExprSkipCollateAndLikely(Expr *pExpr){ +SQLITE_PRIVATE Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){ if( ExprHasProperty(pExpr, EP_Unlikely) ){ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); @@ -102433,9 +102433,9 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprSkipCollateAndLikely(Expr *pExpr){ ** Return the collation sequence for the expression pExpr. If ** there is no defined collating sequence, return NULL. ** -** See also: tdsqlite3ExprNNCollSeq() +** See also: sqlite3ExprNNCollSeq() ** -** The tdsqlite3ExprNNCollSeq() works the same exact that it returns the +** The sqlite3ExprNNCollSeq() works the same exact that it returns the ** default collation if pExpr has no defined collation. ** ** The collating sequence might be determined by a COLLATE operator @@ -102443,8 +102443,8 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprSkipCollateAndLikely(Expr *pExpr){ ** COLLATE operators take first precedence. Left operands take ** precedence over right operands. */ -SQLITE_PRIVATE CollSeq *tdsqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ + sqlite3 *db = pParse->db; CollSeq *pColl = 0; Expr *p = pExpr; while( p ){ @@ -102458,7 +102458,7 @@ SQLITE_PRIVATE CollSeq *tdsqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ int j = p->iColumn; if( j>=0 ){ const char *zColl = p->y.pTab->aCol[j].zColl; - pColl = tdsqlite3FindCollSeq(db, ENC(db), zColl, 0); + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); } break; } @@ -102471,7 +102471,7 @@ SQLITE_PRIVATE CollSeq *tdsqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ continue; } if( op==TK_COLLATE ){ - pColl = tdsqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); + pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } if( p->flags & EP_Collate ){ @@ -102499,7 +102499,7 @@ SQLITE_PRIVATE CollSeq *tdsqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ break; } } - if( tdsqlite3CheckCollSeq(pParse, pColl) ){ + if( sqlite3CheckCollSeq(pParse, pColl) ){ pColl = 0; } return pColl; @@ -102510,13 +102510,13 @@ SQLITE_PRIVATE CollSeq *tdsqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ ** there is no defined collating sequence, return a pointer to the ** defautl collation sequence. ** -** See also: tdsqlite3ExprCollSeq() +** See also: sqlite3ExprCollSeq() ** -** The tdsqlite3ExprCollSeq() routine works the same except that it +** The sqlite3ExprCollSeq() routine works the same except that it ** returns NULL if there is no defined collation. */ -SQLITE_PRIVATE CollSeq *tdsqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){ - CollSeq *p = tdsqlite3ExprCollSeq(pParse, pExpr); +SQLITE_PRIVATE CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){ + CollSeq *p = sqlite3ExprCollSeq(pParse, pExpr); if( p==0 ) p = pParse->db->pDfltColl; assert( p!=0 ); return p; @@ -102525,10 +102525,10 @@ SQLITE_PRIVATE CollSeq *tdsqlite3ExprNNCollSeq(Parse *pParse, Expr *pExpr){ /* ** Return TRUE if the two expressions have equivalent collating sequences. */ -SQLITE_PRIVATE int tdsqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){ - CollSeq *pColl1 = tdsqlite3ExprNNCollSeq(pParse, pE1); - CollSeq *pColl2 = tdsqlite3ExprNNCollSeq(pParse, pE2); - return tdsqlite3StrICmp(pColl1->zName, pColl2->zName)==0; +SQLITE_PRIVATE int sqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2){ + CollSeq *pColl1 = sqlite3ExprNNCollSeq(pParse, pE1); + CollSeq *pColl2 = sqlite3ExprNNCollSeq(pParse, pE2); + return sqlite3StrICmp(pColl1->zName, pColl2->zName)==0; } /* @@ -102536,13 +102536,13 @@ SQLITE_PRIVATE int tdsqlite3ExprCollSeqMatch(Parse *pParse, Expr *pE1, Expr *pE2 ** type affinity of the other operand. This routine returns the ** type affinity that should be used for the comparison operator. */ -SQLITE_PRIVATE char tdsqlite3CompareAffinity(Expr *pExpr, char aff2){ - char aff1 = tdsqlite3ExprAffinity(pExpr); +SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2){ + char aff1 = sqlite3ExprAffinity(pExpr); if( aff1>SQLITE_AFF_NONE && aff2>SQLITE_AFF_NONE ){ /* Both sides of the comparison are columns. If one has numeric ** affinity, use that. Otherwise use no affinity. */ - if( tdsqlite3IsNumericAffinity(aff1) || tdsqlite3IsNumericAffinity(aff2) ){ + if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ return SQLITE_AFF_NUMERIC; }else{ return SQLITE_AFF_BLOB; @@ -102564,11 +102564,11 @@ static char comparisonAffinity(Expr *pExpr){ pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT ); assert( pExpr->pLeft ); - aff = tdsqlite3ExprAffinity(pExpr->pLeft); + aff = sqlite3ExprAffinity(pExpr->pLeft); if( pExpr->pRight ){ - aff = tdsqlite3CompareAffinity(pExpr->pRight, aff); + aff = sqlite3CompareAffinity(pExpr->pRight, aff); }else if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - aff = tdsqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); + aff = sqlite3CompareAffinity(pExpr->x.pSelect->pEList->a[0].pExpr, aff); }else if( aff==0 ){ aff = SQLITE_AFF_BLOB; } @@ -102581,7 +102581,7 @@ static char comparisonAffinity(Expr *pExpr){ ** if the index with affinity idx_affinity may be used to implement ** the comparison in pExpr. */ -SQLITE_PRIVATE int tdsqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ +SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ char aff = comparisonAffinity(pExpr); if( affflags & EP_Collate ){ - pColl = tdsqlite3ExprCollSeq(pParse, pLeft); + pColl = sqlite3ExprCollSeq(pParse, pLeft); }else if( pRight && (pRight->flags & EP_Collate)!=0 ){ - pColl = tdsqlite3ExprCollSeq(pParse, pRight); + pColl = sqlite3ExprCollSeq(pParse, pRight); }else{ - pColl = tdsqlite3ExprCollSeq(pParse, pLeft); + pColl = sqlite3ExprCollSeq(pParse, pLeft); if( !pColl ){ - pColl = tdsqlite3ExprCollSeq(pParse, pRight); + pColl = sqlite3ExprCollSeq(pParse, pRight); } } return pColl; @@ -102637,16 +102637,16 @@ SQLITE_PRIVATE CollSeq *tdsqlite3BinaryCompareCollSeq( /* Expresssion p is a comparison operator. Return a collation sequence ** appropriate for the comparison operator. ** -** This is normally just a wrapper around tdsqlite3BinaryCompareCollSeq(). +** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). ** However, if the OP_Commuted flag is set, then the order of the operands -** is reversed in the tdsqlite3BinaryCompareCollSeq() call so that the +** is reversed in the sqlite3BinaryCompareCollSeq() call so that the ** correct collating sequence is found. */ -SQLITE_PRIVATE CollSeq *tdsqlite3ExprCompareCollSeq(Parse *pParse, Expr *p){ +SQLITE_PRIVATE CollSeq *sqlite3ExprCompareCollSeq(Parse *pParse, Expr *p){ if( ExprHasProperty(p, EP_Commuted) ){ - return tdsqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft); + return sqlite3BinaryCompareCollSeq(pParse, p->pRight, p->pLeft); }else{ - return tdsqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight); + return sqlite3BinaryCompareCollSeq(pParse, p->pLeft, p->pRight); } } @@ -102669,14 +102669,14 @@ static int codeCompare( if( pParse->nErr ) return 0; if( isCommuted ){ - p4 = tdsqlite3BinaryCompareCollSeq(pParse, pRight, pLeft); + p4 = sqlite3BinaryCompareCollSeq(pParse, pRight, pLeft); }else{ - p4 = tdsqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); + p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); } p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); - addr = tdsqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, + addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); - tdsqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); + sqlite3VdbeChangeP5(pParse->pVdbe, (u8)p5); return addr; } @@ -102689,8 +102689,8 @@ static int codeCompare( ** But a TK_SELECT might be either a vector or a scalar. It is only ** considered a vector if it has two or more result columns. */ -SQLITE_PRIVATE int tdsqlite3ExprIsVector(Expr *pExpr){ - return tdsqlite3ExprVectorSize(pExpr)>1; +SQLITE_PRIVATE int sqlite3ExprIsVector(Expr *pExpr){ + return sqlite3ExprVectorSize(pExpr)>1; } /* @@ -102699,7 +102699,7 @@ SQLITE_PRIVATE int tdsqlite3ExprIsVector(Expr *pExpr){ ** is a sub-select, return the number of columns in the sub-select. For ** any other type of expression, return 1. */ -SQLITE_PRIVATE int tdsqlite3ExprVectorSize(Expr *pExpr){ +SQLITE_PRIVATE int sqlite3ExprVectorSize(Expr *pExpr){ u8 op = pExpr->op; if( op==TK_REGISTER ) op = pExpr->op2; if( op==TK_VECTOR ){ @@ -102726,9 +102726,9 @@ SQLITE_PRIVATE int tdsqlite3ExprVectorSize(Expr *pExpr){ ** not be ready for evaluation because the table cursor has not yet ** been positioned. */ -SQLITE_PRIVATE Expr *tdsqlite3VectorFieldSubexpr(Expr *pVector, int i){ - assert( iop2==0 || pVector->op==TK_REGISTER ); if( pVector->op==TK_SELECT || pVector->op2==TK_SELECT ){ return pVector->x.pSelect->pEList->a[i].pExpr; @@ -102741,11 +102741,11 @@ SQLITE_PRIVATE Expr *tdsqlite3VectorFieldSubexpr(Expr *pVector, int i){ /* ** Compute and return a new Expr object which when passed to -** tdsqlite3ExprCode() will generate all necessary code to compute +** sqlite3ExprCode() will generate all necessary code to compute ** the iField-th column of the vector expression pVector. ** ** It is ok for pVector to be a scalar (as long as iField==0). -** In that case, this routine works like tdsqlite3ExprDup(). +** In that case, this routine works like sqlite3ExprDup(). ** ** The caller owns the returned Expr object and is responsible for ** ensuring that the returned value eventually gets freed. @@ -102760,7 +102760,7 @@ SQLITE_PRIVATE Expr *tdsqlite3VectorFieldSubexpr(Expr *pVector, int i){ ** the returned Expr object is to attach the pVector to the pRight field ** of the returned TK_SELECT_COLUMN Expr object. */ -SQLITE_PRIVATE Expr *tdsqlite3ExprForVectorField( +SQLITE_PRIVATE Expr *sqlite3ExprForVectorField( Parse *pParse, /* Parsing context */ Expr *pVector, /* The vector. List of expressions or a sub-SELECT */ int iField /* Which column of the vector to return */ @@ -102777,14 +102777,14 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprForVectorField( ** pLeft->iTable: First in an array of register holding result, or 0 ** if the result is not yet computed. ** - ** tdsqlite3ExprDelete() specifically skips the recursive delete of + ** sqlite3ExprDelete() specifically skips the recursive delete of ** pLeft on TK_SELECT_COLUMN nodes. But pRight is followed, so pVector ** can be attached to pRight to cause this node to take ownership of ** pVector. Typically there will be multiple TK_SELECT_COLUMN nodes ** with the same pLeft pointer to the pVector, but only one of them ** will own the pVector. */ - pRet = tdsqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); + pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); if( pRet ){ pRet->iColumn = iField; pRet->pLeft = pVector; @@ -102792,8 +102792,8 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprForVectorField( assert( pRet==0 || pRet->iTable==0 ); }else{ if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr; - pRet = tdsqlite3ExprDup(pParse->db, pVector, 0); - tdsqlite3RenameTokenRemap(pParse, pRet, pVector); + pRet = sqlite3ExprDup(pParse->db, pVector, 0); + sqlite3RenameTokenRemap(pParse, pRet, pVector); } return pRet; } @@ -102810,7 +102810,7 @@ static int exprCodeSubselect(Parse *pParse, Expr *pExpr){ int reg = 0; #ifndef SQLITE_OMIT_SUBQUERY if( pExpr->op==TK_SELECT ){ - reg = tdsqlite3CodeSubselect(pParse, pExpr); + reg = sqlite3CodeSubselect(pParse, pExpr); } #endif return reg; @@ -102845,7 +102845,7 @@ static int exprVectorRegister( u8 op = pVector->op; assert( op==TK_VECTOR || op==TK_REGISTER || op==TK_SELECT ); if( op==TK_REGISTER ){ - *ppExpr = tdsqlite3VectorFieldSubexpr(pVector, iField); + *ppExpr = sqlite3VectorFieldSubexpr(pVector, iField); return pVector->iTable+iField; } if( op==TK_SELECT ){ @@ -102853,7 +102853,7 @@ static int exprVectorRegister( return regSelect+iField; } *ppExpr = pVector->x.pList->a[iField].pExpr; - return tdsqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); + return sqlite3ExprCodeTemp(pParse, *ppExpr, pRegFree); } /* @@ -102877,17 +102877,17 @@ static void codeVectorCompare( Vdbe *v = pParse->pVdbe; Expr *pLeft = pExpr->pLeft; Expr *pRight = pExpr->pRight; - int nLeft = tdsqlite3ExprVectorSize(pLeft); + int nLeft = sqlite3ExprVectorSize(pLeft); int i; int regLeft = 0; int regRight = 0; u8 opx = op; - int addrDone = tdsqlite3VdbeMakeLabel(pParse); + int addrDone = sqlite3VdbeMakeLabel(pParse); int isCommuted = ExprHasProperty(pExpr,EP_Commuted); if( pParse->nErr ) return; - if( nLeft!=tdsqlite3ExprVectorSize(pRight) ){ - tdsqlite3ErrorMsg(pParse, "row value misused"); + if( nLeft!=sqlite3ExprVectorSize(pRight) ){ + sqlite3ErrorMsg(pParse, "row value misused"); return; } assert( pExpr->op==TK_EQ || pExpr->op==TK_NE @@ -102921,20 +102921,20 @@ static void codeVectorCompare( testcase(op==OP_Ge); VdbeCoverageIf(v,op==OP_Ge); testcase(op==OP_Eq); VdbeCoverageIf(v,op==OP_Eq); testcase(op==OP_Ne); VdbeCoverageIf(v,op==OP_Ne); - tdsqlite3ReleaseTempReg(pParse, regFree1); - tdsqlite3ReleaseTempReg(pParse, regFree2); + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); if( i==nLeft-1 ){ break; } if( opx==TK_EQ ){ - tdsqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IfNot, dest, addrDone); VdbeCoverage(v); p5 |= SQLITE_KEEPNULL; }else if( opx==TK_NE ){ - tdsqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_If, dest, addrDone); VdbeCoverage(v); p5 |= SQLITE_KEEPNULL; }else{ assert( op==TK_LT || op==TK_GT || op==TK_LE || op==TK_GE ); - tdsqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone); + sqlite3VdbeAddOp2(v, OP_ElseNotEq, 0, addrDone); VdbeCoverageIf(v, op==TK_LT); VdbeCoverageIf(v, op==TK_GT); VdbeCoverageIf(v, op==TK_LE); @@ -102942,7 +102942,7 @@ static void codeVectorCompare( if( i==nLeft-2 ) opx = op; } } - tdsqlite3VdbeResolveLabel(v, addrDone); + sqlite3VdbeResolveLabel(v, addrDone); } #if SQLITE_MAX_EXPR_DEPTH>0 @@ -102951,11 +102951,11 @@ static void codeVectorCompare( ** expression depth allowed. If it is not, leave an error message in ** pParse. */ -SQLITE_PRIVATE int tdsqlite3ExprCheckHeight(Parse *pParse, int nHeight){ +SQLITE_PRIVATE int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ int rc = SQLITE_OK; int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; if( nHeight>mxHeight ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Expression tree is too large (maximum depth %d)", mxHeight ); rc = SQLITE_ERROR; @@ -103017,7 +103017,7 @@ static void exprSetHeight(Expr *p){ heightOfSelect(p->x.pSelect, &nHeight); }else if( p->x.pList ){ heightOfExprList(p->x.pList, &nHeight); - p->flags |= EP_Propagate & tdsqlite3ExprListFlags(p->x.pList); + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); } p->nHeight = nHeight + 1; } @@ -103030,17 +103030,17 @@ static void exprSetHeight(Expr *p){ ** Also propagate all EP_Propagate flags from the Expr.x.pList into ** Expr.flags. */ -SQLITE_PRIVATE void tdsqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ if( pParse->nErr ) return; exprSetHeight(p); - tdsqlite3ExprCheckHeight(pParse, p->nHeight); + sqlite3ExprCheckHeight(pParse, p->nHeight); } /* ** Return the maximum height of any expression tree referenced ** by the select statement passed as an argument. */ -SQLITE_PRIVATE int tdsqlite3SelectExprHeight(Select *p){ +SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){ int nHeight = 0; heightOfSelect(p, &nHeight); return nHeight; @@ -103050,9 +103050,9 @@ SQLITE_PRIVATE int tdsqlite3SelectExprHeight(Select *p){ ** Propagate all EP_Propagate flags from the Expr.x.pList into ** Expr.flags. */ -SQLITE_PRIVATE void tdsqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ +SQLITE_PRIVATE void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ if( p && p->x.pList && !ExprHasProperty(p, EP_xIsSelect) ){ - p->flags |= EP_Propagate & tdsqlite3ExprListFlags(p->x.pList); + p->flags |= EP_Propagate & sqlite3ExprListFlags(p->x.pList); } } #define exprSetHeight(y) @@ -103063,7 +103063,7 @@ SQLITE_PRIVATE void tdsqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ ** ** Construct a new expression node and return a pointer to it. Memory ** for this node and for the pToken argument is a single allocation -** obtained from tdsqlite3DbMalloc(). The calling function +** obtained from sqlite3DbMalloc(). The calling function ** is responsible for making sure the node eventually gets freed. ** ** If dequote is true, then the token (if it exists) is dequoted. @@ -103078,8 +103078,8 @@ SQLITE_PRIVATE void tdsqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ ** into u.iValue and the EP_IntValue flag is set. No extra storage ** is allocated to hold the integer text and the dequote flag is ignored. */ -SQLITE_PRIVATE Expr *tdsqlite3ExprAlloc( - tdsqlite3 *db, /* Handle for tdsqlite3DbMallocRawNN() */ +SQLITE_PRIVATE Expr *sqlite3ExprAlloc( + sqlite3 *db, /* Handle for sqlite3DbMallocRawNN() */ int op, /* Expression opcode */ const Token *pToken, /* Token argument. Might be NULL */ int dequote /* True to dequote */ @@ -103091,12 +103091,12 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprAlloc( assert( db!=0 ); if( pToken ){ if( op!=TK_INTEGER || pToken->z==0 - || tdsqlite3GetInt32(pToken->z, &iValue)==0 ){ + || sqlite3GetInt32(pToken->z, &iValue)==0 ){ nExtra = pToken->n+1; assert( iValue>=0 ); } } - pNew = tdsqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra); + pNew = sqlite3DbMallocRawNN(db, sizeof(Expr)+nExtra); if( pNew ){ memset(pNew, 0, sizeof(Expr)); pNew->op = (u8)op; @@ -103110,8 +103110,8 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprAlloc( assert( pToken->z!=0 || pToken->n==0 ); if( pToken->n ) memcpy(pNew->u.zToken, pToken->z, pToken->n); pNew->u.zToken[pToken->n] = 0; - if( dequote && tdsqlite3Isquote(pNew->u.zToken[0]) ){ - tdsqlite3DequoteExpr(pNew); + if( dequote && sqlite3Isquote(pNew->u.zToken[0]) ){ + sqlite3DequoteExpr(pNew); } } } @@ -103126,15 +103126,15 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprAlloc( ** Allocate a new expression node from a zero-terminated token that has ** already been dequoted. */ -SQLITE_PRIVATE Expr *tdsqlite3Expr( - tdsqlite3 *db, /* Handle for tdsqlite3DbMallocZero() (may be null) */ +SQLITE_PRIVATE Expr *sqlite3Expr( + sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ int op, /* Expression opcode */ const char *zToken /* Token argument. Might be NULL */ ){ Token x; x.z = zToken; - x.n = tdsqlite3Strlen30(zToken); - return tdsqlite3ExprAlloc(db, op, &x, 0); + x.n = sqlite3Strlen30(zToken); + return sqlite3ExprAlloc(db, op, &x, 0); } /* @@ -103143,16 +103143,16 @@ SQLITE_PRIVATE Expr *tdsqlite3Expr( ** If pRoot==NULL that means that a memory allocation error has occurred. ** In that case, delete the subtrees pLeft and pRight. */ -SQLITE_PRIVATE void tdsqlite3ExprAttachSubtrees( - tdsqlite3 *db, +SQLITE_PRIVATE void sqlite3ExprAttachSubtrees( + sqlite3 *db, Expr *pRoot, Expr *pLeft, Expr *pRight ){ if( pRoot==0 ){ assert( db->mallocFailed ); - tdsqlite3ExprDelete(db, pLeft); - tdsqlite3ExprDelete(db, pRight); + sqlite3ExprDelete(db, pLeft); + sqlite3ExprDelete(db, pRight); }else{ if( pRight ){ pRoot->pRight = pRight; @@ -103173,23 +103173,23 @@ SQLITE_PRIVATE void tdsqlite3ExprAttachSubtrees( ** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, ** free the subtrees and return NULL. */ -SQLITE_PRIVATE Expr *tdsqlite3PExpr( +SQLITE_PRIVATE Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight /* Right operand */ ){ Expr *p; - p = tdsqlite3DbMallocRawNN(pParse->db, sizeof(Expr)); + p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)); if( p ){ memset(p, 0, sizeof(Expr)); p->op = op & 0xff; p->iAgg = -1; - tdsqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); - tdsqlite3ExprCheckHeight(pParse, p->nHeight); + sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight); + sqlite3ExprCheckHeight(pParse, p->nHeight); }else{ - tdsqlite3ExprDelete(pParse->db, pLeft); - tdsqlite3ExprDelete(pParse->db, pRight); + sqlite3ExprDelete(pParse->db, pLeft); + sqlite3ExprDelete(pParse->db, pRight); } return p; } @@ -103198,14 +103198,14 @@ SQLITE_PRIVATE Expr *tdsqlite3PExpr( ** Add pSelect to the Expr.x.pSelect field. Or, if pExpr is NULL (due ** do a memory allocation failure) then delete the pSelect object. */ -SQLITE_PRIVATE void tdsqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){ +SQLITE_PRIVATE void sqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select *pSelect){ if( pExpr ){ pExpr->x.pSelect = pSelect; ExprSetProperty(pExpr, EP_xIsSelect|EP_Subquery); - tdsqlite3ExprSetHeightAndFlags(pParse, pExpr); + sqlite3ExprSetHeightAndFlags(pParse, pExpr); }else{ assert( pParse->db->mallocFailed ); - tdsqlite3SelectDelete(pParse->db, pSelect); + sqlite3SelectDelete(pParse->db, pSelect); } } @@ -103218,8 +103218,8 @@ SQLITE_PRIVATE void tdsqlite3PExprAddSelect(Parse *pParse, Expr *pExpr, Select * ** of returning an AND expression, just return a constant expression with ** a value of false. */ -SQLITE_PRIVATE Expr *tdsqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE Expr *sqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ + sqlite3 *db = pParse->db; if( pLeft==0 ){ return pRight; }else if( pRight==0 ){ @@ -103227,11 +103227,11 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ }else if( (ExprAlwaysFalse(pLeft) || ExprAlwaysFalse(pRight)) && !IN_RENAME_OBJECT ){ - tdsqlite3ExprDelete(db, pLeft); - tdsqlite3ExprDelete(db, pRight); - return tdsqlite3Expr(db, TK_INTEGER, "0"); + sqlite3ExprDelete(db, pLeft); + sqlite3ExprDelete(db, pRight); + return sqlite3Expr(db, TK_INTEGER, "0"); }else{ - return tdsqlite3PExpr(pParse, TK_AND, pLeft, pRight); + return sqlite3PExpr(pParse, TK_AND, pLeft, pRight); } } @@ -103239,27 +103239,27 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprAnd(Parse *pParse, Expr *pLeft, Expr *pRight){ ** Construct a new expression node for a function with multiple ** arguments. */ -SQLITE_PRIVATE Expr *tdsqlite3ExprFunction( +SQLITE_PRIVATE Expr *sqlite3ExprFunction( Parse *pParse, /* Parsing context */ ExprList *pList, /* Argument list */ Token *pToken, /* Name of the function */ int eDistinct /* SF_Distinct or SF_ALL or 0 */ ){ Expr *pNew; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; assert( pToken ); - pNew = tdsqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1); + pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1); if( pNew==0 ){ - tdsqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ + sqlite3ExprListDelete(db, pList); /* Avoid memory leak when malloc fails */ return 0; } if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ - tdsqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken); + sqlite3ErrorMsg(pParse, "too many arguments on function %T", pToken); } pNew->x.pList = pList; ExprSetProperty(pNew, EP_HasFunc); assert( !ExprHasProperty(pNew, EP_xIsSelect) ); - tdsqlite3ExprSetHeightAndFlags(pParse, pNew); + sqlite3ExprSetHeightAndFlags(pParse, pNew); if( eDistinct==SF_Distinct ) ExprSetProperty(pNew, EP_Distinct); return pNew; } @@ -103275,7 +103275,7 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprFunction( ** ** If the function is not usable, create an error. */ -SQLITE_PRIVATE void tdsqlite3ExprFunctionUsable( +SQLITE_PRIVATE void sqlite3ExprFunctionUsable( Parse *pParse, /* Parsing and code generating context */ Expr *pExpr, /* The function invocation */ FuncDef *pDef /* The function being invoked */ @@ -103293,7 +103293,7 @@ SQLITE_PRIVATE void tdsqlite3ExprFunctionUsable( ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning ** that the schema is possibly tainted). */ - tdsqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName); + sqlite3ErrorMsg(pParse, "unsafe use of %s()", pDef->zName); } } } @@ -103314,8 +103314,8 @@ SQLITE_PRIVATE void tdsqlite3ExprFunctionUsable( ** instance of the wildcard, the next sequential variable number is ** assigned. */ -SQLITE_PRIVATE void tdsqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){ + sqlite3 *db = pParse->db; const char *z; ynVar x; @@ -103324,7 +103324,7 @@ SQLITE_PRIVATE void tdsqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 z = pExpr->u.zToken; assert( z!=0 ); assert( z[0]!=0 ); - assert( n==(u32)tdsqlite3Strlen30(z) ); + assert( n==(u32)sqlite3Strlen30(z) ); if( z[1]==0 ){ /* Wildcard of the form "?". Assign the next variable number */ assert( z[0]=='?' ); @@ -103340,14 +103340,14 @@ SQLITE_PRIVATE void tdsqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 i = z[1]-'0'; /* The common case of ?N for a single digit N */ bOk = 1; }else{ - bOk = 0==tdsqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); + bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); } testcase( i==0 ); testcase( i==1 ); testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ - tdsqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); return; } @@ -103355,7 +103355,7 @@ SQLITE_PRIVATE void tdsqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 if( x>pParse->nVar ){ pParse->nVar = (int)x; doAdd = 1; - }else if( tdsqlite3VListNumToName(pParse->pVList, x)==0 ){ + }else if( sqlite3VListNumToName(pParse->pVList, x)==0 ){ doAdd = 1; } }else{ @@ -103363,26 +103363,26 @@ SQLITE_PRIVATE void tdsqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 ** number as the prior appearance of the same name, or if the name ** has never appeared before, reuse the same variable number */ - x = (ynVar)tdsqlite3VListNameToNum(pParse->pVList, z, n); + x = (ynVar)sqlite3VListNameToNum(pParse->pVList, z, n); if( x==0 ){ x = (ynVar)(++pParse->nVar); doAdd = 1; } } if( doAdd ){ - pParse->pVList = tdsqlite3VListAdd(db, pParse->pVList, z, n, x); + pParse->pVList = sqlite3VListAdd(db, pParse->pVList, z, n, x); } } pExpr->iColumn = x; if( x>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ - tdsqlite3ErrorMsg(pParse, "too many SQL variables"); + sqlite3ErrorMsg(pParse, "too many SQL variables"); } } /* ** Recursively delete an expression tree. */ -static SQLITE_NOINLINE void tdsqlite3ExprDeleteNN(tdsqlite3 *db, Expr *p){ +static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ assert( p!=0 ); /* Sanity check: Assert that the IntValue is non-negative if it exists */ assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); @@ -103400,40 +103400,40 @@ static SQLITE_NOINLINE void tdsqlite3ExprDeleteNN(tdsqlite3 *db, Expr *p){ if( !ExprHasProperty(p, (EP_TokenOnly|EP_Leaf)) ){ /* The Expr.x union is never used at the same time as Expr.pRight */ assert( p->x.pList==0 || p->pRight==0 ); - if( p->pLeft && p->op!=TK_SELECT_COLUMN ) tdsqlite3ExprDeleteNN(db, p->pLeft); + if( p->pLeft && p->op!=TK_SELECT_COLUMN ) sqlite3ExprDeleteNN(db, p->pLeft); if( p->pRight ){ assert( !ExprHasProperty(p, EP_WinFunc) ); - tdsqlite3ExprDeleteNN(db, p->pRight); + sqlite3ExprDeleteNN(db, p->pRight); }else if( ExprHasProperty(p, EP_xIsSelect) ){ assert( !ExprHasProperty(p, EP_WinFunc) ); - tdsqlite3SelectDelete(db, p->x.pSelect); + sqlite3SelectDelete(db, p->x.pSelect); }else{ - tdsqlite3ExprListDelete(db, p->x.pList); + sqlite3ExprListDelete(db, p->x.pList); #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(p, EP_WinFunc) ){ - tdsqlite3WindowDelete(db, p->y.pWin); + sqlite3WindowDelete(db, p->y.pWin); } #endif } } - if( ExprHasProperty(p, EP_MemToken) ) tdsqlite3DbFree(db, p->u.zToken); + if( ExprHasProperty(p, EP_MemToken) ) sqlite3DbFree(db, p->u.zToken); if( !ExprHasProperty(p, EP_Static) ){ - tdsqlite3DbFreeNN(db, p); + sqlite3DbFreeNN(db, p); } } -SQLITE_PRIVATE void tdsqlite3ExprDelete(tdsqlite3 *db, Expr *p){ - if( p ) tdsqlite3ExprDeleteNN(db, p); +SQLITE_PRIVATE void sqlite3ExprDelete(sqlite3 *db, Expr *p){ + if( p ) sqlite3ExprDeleteNN(db, p); } -/* Invoke tdsqlite3RenameExprUnmap() and tdsqlite3ExprDelete() on the +/* Invoke sqlite3RenameExprUnmap() and sqlite3ExprDelete() on the ** expression. */ -SQLITE_PRIVATE void tdsqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){ +SQLITE_PRIVATE void sqlite3ExprUnmapAndDelete(Parse *pParse, Expr *p){ if( p ){ if( IN_RENAME_OBJECT ){ - tdsqlite3RenameExprUnmap(pParse, p); + sqlite3RenameExprUnmap(pParse, p); } - tdsqlite3ExprDeleteNN(pParse->db, p); + sqlite3ExprDeleteNN(pParse->db, p); } } @@ -103516,7 +103516,7 @@ static int dupedExprStructSize(Expr *p, int flags){ static int dupedExprNodeSize(Expr *p, int flags){ int nByte = dupedExprStructSize(p, flags) & 0xfff; if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nByte += tdsqlite3Strlen30NN(p->u.zToken)+1; + nByte += sqlite3Strlen30NN(p->u.zToken)+1; } return ROUND8(nByte); } @@ -103546,14 +103546,14 @@ static int dupedExprSize(Expr *p, int flags){ } /* -** This function is similar to tdsqlite3ExprDup(), except that if pzBuffer +** This function is similar to sqlite3ExprDup(), except that if pzBuffer ** is not NULL then *pzBuffer is assumed to point to a buffer large enough ** to store the copy of expression p, the copies of p->u.zToken ** (if applicable), and the copies of the p->pLeft and p->pRight expressions, ** if any. Before returning, *pzBuffer is set to the first byte past the ** portion of the buffer copied into by this function. */ -static Expr *exprDup(tdsqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ +static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ Expr *pNew; /* Value to return */ u8 *zAlloc; /* Memory space from which to build Expr object */ u32 staticFlag; /* EP_Static if space not obtained from malloc */ @@ -103568,7 +103568,7 @@ static Expr *exprDup(tdsqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ zAlloc = *pzBuffer; staticFlag = EP_Static; }else{ - zAlloc = tdsqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); + zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); staticFlag = 0; } pNew = (Expr *)zAlloc; @@ -103583,7 +103583,7 @@ static Expr *exprDup(tdsqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ const int nNewSize = nStructSize & 0xfff; int nToken; if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nToken = tdsqlite3Strlen30(p->u.zToken) + 1; + nToken = sqlite3Strlen30(p->u.zToken) + 1; }else{ nToken = 0; } @@ -103612,9 +103612,9 @@ static Expr *exprDup(tdsqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ if( ExprHasProperty(p, EP_xIsSelect) ){ - pNew->x.pSelect = tdsqlite3SelectDup(db, p->x.pSelect, dupFlags); + pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); }else{ - pNew->x.pList = tdsqlite3ExprListDup(db, p->x.pList, dupFlags); + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags); } } @@ -103629,7 +103629,7 @@ static Expr *exprDup(tdsqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(p, EP_WinFunc) ){ - pNew->y.pWin = tdsqlite3WindowDup(db, pNew, p->y.pWin); + pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); assert( ExprHasProperty(pNew, EP_WinFunc) ); } #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -103643,9 +103643,9 @@ static Expr *exprDup(tdsqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ assert( p->iColumn==0 || p->pRight==0 ); assert( p->pRight==0 || p->pRight==p->pLeft ); }else{ - pNew->pLeft = tdsqlite3ExprDup(db, p->pLeft, 0); + pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); } - pNew->pRight = tdsqlite3ExprDup(db, p->pRight, 0); + pNew->pRight = sqlite3ExprDup(db, p->pRight, 0); } } } @@ -103658,18 +103658,18 @@ static Expr *exprDup(tdsqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){ ** and the db->mallocFailed flag set. */ #ifndef SQLITE_OMIT_CTE -static With *withDup(tdsqlite3 *db, With *p){ +static With *withDup(sqlite3 *db, With *p){ With *pRet = 0; if( p ){ - tdsqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); - pRet = tdsqlite3DbMallocZero(db, nByte); + sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1); + pRet = sqlite3DbMallocZero(db, nByte); if( pRet ){ int i; pRet->nCte = p->nCte; for(i=0; inCte; i++){ - pRet->a[i].pSelect = tdsqlite3SelectDup(db, p->a[i].pSelect, 0); - pRet->a[i].pCols = tdsqlite3ExprListDup(db, p->a[i].pCols, 0); - pRet->a[i].zName = tdsqlite3DbStrDup(db, p->a[i].zName); + pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0); + pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0); + pRet->a[i].zName = sqlite3DbStrDup(db, p->a[i].zName); } } } @@ -103693,7 +103693,7 @@ static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ assert( pWin ); assert( IsWindowFunc(pExpr) ); assert( pWin->ppThis==0 ); - tdsqlite3WindowLink(pSelect, pWin); + sqlite3WindowLink(pSelect, pWin); } return WRC_Continue; } @@ -103707,7 +103707,7 @@ static void gatherSelectWindows(Select *p){ w.xSelectCallback2 = 0; w.pParse = 0; w.u.pSelect = p; - tdsqlite3WalkSelect(&w, p); + sqlite3WalkSelect(&w, p); } #endif @@ -103718,8 +103718,8 @@ static void gatherSelectWindows(Select *p){ ** be deleted (by being passed to their respective ...Delete() routines) ** without effecting the originals. ** -** The expression list, ID, and source lists return by tdsqlite3ExprListDup(), -** tdsqlite3IdListDup(), and tdsqlite3SrcListDup() can not be further expanded +** The expression list, ID, and source lists return by sqlite3ExprListDup(), +** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded ** by subsequent calls to sqlite*ListAppend() routines. ** ** Any tables that the SrcList might point to are not duplicated. @@ -103729,18 +103729,18 @@ static void gatherSelectWindows(Select *p){ ** truncated version of the usual Expr structure that will be stored as ** part of the in-memory representation of the database schema. */ -SQLITE_PRIVATE Expr *tdsqlite3ExprDup(tdsqlite3 *db, Expr *p, int flags){ +SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){ assert( flags==0 || flags==EXPRDUP_REDUCE ); return p ? exprDup(db, p, flags, 0) : 0; } -SQLITE_PRIVATE ExprList *tdsqlite3ExprListDup(tdsqlite3 *db, ExprList *p, int flags){ +SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ ExprList *pNew; struct ExprList_item *pItem, *pOldItem; int i; Expr *pPriorSelectCol = 0; assert( db!=0 ); if( p==0 ) return 0; - pNew = tdsqlite3DbMallocRawNN(db, tdsqlite3DbMallocSize(db, p)); + pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p)); if( pNew==0 ) return 0; pNew->nExpr = p->nExpr; pItem = pNew->a; @@ -103748,7 +103748,7 @@ SQLITE_PRIVATE ExprList *tdsqlite3ExprListDup(tdsqlite3 *db, ExprList *p, int fl for(i=0; inExpr; i++, pItem++, pOldItem++){ Expr *pOldExpr = pOldItem->pExpr; Expr *pNewExpr; - pItem->pExpr = tdsqlite3ExprDup(db, pOldExpr, flags); + pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); if( pOldExpr && pOldExpr->op==TK_SELECT_COLUMN && (pNewExpr = pItem->pExpr)!=0 @@ -103765,7 +103765,7 @@ SQLITE_PRIVATE ExprList *tdsqlite3ExprListDup(tdsqlite3 *db, ExprList *p, int fl pNewExpr->pLeft = pPriorSelectCol; } } - pItem->zEName = tdsqlite3DbStrDup(db, pOldItem->zEName); + pItem->zEName = sqlite3DbStrDup(db, pOldItem->zEName); pItem->sortFlags = pOldItem->sortFlags; pItem->eEName = pOldItem->eEName; pItem->done = 0; @@ -103779,19 +103779,19 @@ SQLITE_PRIVATE ExprList *tdsqlite3ExprListDup(tdsqlite3 *db, ExprList *p, int fl /* ** If cursors, triggers, views and subqueries are all omitted from ** the build, then none of the following routines, except for -** tdsqlite3SelectDup(), can be called. tdsqlite3SelectDup() is sometimes +** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes ** called with a NULL argument. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \ || !defined(SQLITE_OMIT_SUBQUERY) -SQLITE_PRIVATE SrcList *tdsqlite3SrcListDup(tdsqlite3 *db, SrcList *p, int flags){ +SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){ SrcList *pNew; int i; int nByte; assert( db!=0 ); if( p==0 ) return 0; nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0); - pNew = tdsqlite3DbMallocRawNN(db, nByte ); + pNew = sqlite3DbMallocRawNN(db, nByte ); if( pNew==0 ) return 0; pNew->nSrc = pNew->nAlloc = p->nSrc; for(i=0; inSrc; i++){ @@ -103799,57 +103799,57 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListDup(tdsqlite3 *db, SrcList *p, int flags struct SrcList_item *pOldItem = &p->a[i]; Table *pTab; pNewItem->pSchema = pOldItem->pSchema; - pNewItem->zDatabase = tdsqlite3DbStrDup(db, pOldItem->zDatabase); - pNewItem->zName = tdsqlite3DbStrDup(db, pOldItem->zName); - pNewItem->zAlias = tdsqlite3DbStrDup(db, pOldItem->zAlias); + pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase); + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); + pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias); pNewItem->fg = pOldItem->fg; pNewItem->iCursor = pOldItem->iCursor; pNewItem->addrFillSub = pOldItem->addrFillSub; pNewItem->regReturn = pOldItem->regReturn; if( pNewItem->fg.isIndexedBy ){ - pNewItem->u1.zIndexedBy = tdsqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); + pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy); } pNewItem->pIBIndex = pOldItem->pIBIndex; if( pNewItem->fg.isTabFunc ){ pNewItem->u1.pFuncArg = - tdsqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); + sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); } pTab = pNewItem->pTab = pOldItem->pTab; if( pTab ){ pTab->nTabRef++; } - pNewItem->pSelect = tdsqlite3SelectDup(db, pOldItem->pSelect, flags); - pNewItem->pOn = tdsqlite3ExprDup(db, pOldItem->pOn, flags); - pNewItem->pUsing = tdsqlite3IdListDup(db, pOldItem->pUsing); + pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags); + pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags); + pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing); pNewItem->colUsed = pOldItem->colUsed; } return pNew; } -SQLITE_PRIVATE IdList *tdsqlite3IdListDup(tdsqlite3 *db, IdList *p){ +SQLITE_PRIVATE IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){ IdList *pNew; int i; assert( db!=0 ); if( p==0 ) return 0; - pNew = tdsqlite3DbMallocRawNN(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); if( pNew==0 ) return 0; pNew->nId = p->nId; - pNew->a = tdsqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); + pNew->a = sqlite3DbMallocRawNN(db, p->nId*sizeof(p->a[0]) ); if( pNew->a==0 ){ - tdsqlite3DbFreeNN(db, pNew); + sqlite3DbFreeNN(db, pNew); return 0; } /* Note that because the size of the allocation for p->a[] is not - ** necessarily a power of two, tdsqlite3IdListAppend() may not be called + ** necessarily a power of two, sqlite3IdListAppend() may not be called ** on the duplicate created by this function. */ for(i=0; inId; i++){ struct IdList_item *pNewItem = &pNew->a[i]; struct IdList_item *pOldItem = &p->a[i]; - pNewItem->zName = tdsqlite3DbStrDup(db, pOldItem->zName); + pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pNewItem->idx = pOldItem->idx; } return pNew; } -SQLITE_PRIVATE Select *tdsqlite3SelectDup(tdsqlite3 *db, Select *pDup, int flags){ +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ Select *pRet = 0; Select *pNext = 0; Select **pp = &pRet; @@ -103857,18 +103857,18 @@ SQLITE_PRIVATE Select *tdsqlite3SelectDup(tdsqlite3 *db, Select *pDup, int flags assert( db!=0 ); for(p=pDup; p; p=p->pPrior){ - Select *pNew = tdsqlite3DbMallocRawNN(db, sizeof(*p) ); + Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) ); if( pNew==0 ) break; - pNew->pEList = tdsqlite3ExprListDup(db, p->pEList, flags); - pNew->pSrc = tdsqlite3SrcListDup(db, p->pSrc, flags); - pNew->pWhere = tdsqlite3ExprDup(db, p->pWhere, flags); - pNew->pGroupBy = tdsqlite3ExprListDup(db, p->pGroupBy, flags); - pNew->pHaving = tdsqlite3ExprDup(db, p->pHaving, flags); - pNew->pOrderBy = tdsqlite3ExprListDup(db, p->pOrderBy, flags); + pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags); + pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags); + pNew->pWhere = sqlite3ExprDup(db, p->pWhere, flags); + pNew->pGroupBy = sqlite3ExprListDup(db, p->pGroupBy, flags); + pNew->pHaving = sqlite3ExprDup(db, p->pHaving, flags); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, flags); pNew->op = p->op; pNew->pNext = pNext; pNew->pPrior = 0; - pNew->pLimit = tdsqlite3ExprDup(db, p->pLimit, flags); + pNew->pLimit = sqlite3ExprDup(db, p->pLimit, flags); pNew->iLimit = 0; pNew->iOffset = 0; pNew->selFlags = p->selFlags & ~SF_UsesEphemeral; @@ -103878,7 +103878,7 @@ SQLITE_PRIVATE Select *tdsqlite3SelectDup(tdsqlite3 *db, Select *pDup, int flags pNew->pWith = withDup(db, p->pWith); #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; - pNew->pWinDefn = tdsqlite3WindowListDup(db, p->pWinDefn); + pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew); #endif pNew->selId = p->selId; @@ -103890,7 +103890,7 @@ SQLITE_PRIVATE Select *tdsqlite3SelectDup(tdsqlite3 *db, Select *pDup, int flags return pRet; } #else -SQLITE_PRIVATE Select *tdsqlite3SelectDup(tdsqlite3 *db, Select *p, int flags){ +SQLITE_PRIVATE Select *sqlite3SelectDup(sqlite3 *db, Select *p, int flags){ assert( p==0 ); return 0; } @@ -103902,34 +103902,34 @@ SQLITE_PRIVATE Select *tdsqlite3SelectDup(tdsqlite3 *db, Select *p, int flags){ ** initially NULL, then create a new expression list. ** ** The pList argument must be either NULL or a pointer to an ExprList -** obtained from a prior call to tdsqlite3ExprListAppend(). This routine -** may not be used with an ExprList obtained from tdsqlite3ExprListDup(). +** obtained from a prior call to sqlite3ExprListAppend(). This routine +** may not be used with an ExprList obtained from sqlite3ExprListDup(). ** Reason: This routine assumes that the number of slots in pList->a[] -** is a power of two. That is true for tdsqlite3ExprListAppend() returns -** but is not necessarily true from the return value of tdsqlite3ExprListDup(). +** is a power of two. That is true for sqlite3ExprListAppend() returns +** but is not necessarily true from the return value of sqlite3ExprListDup(). ** ** If a memory allocation error occurs, the entire list is freed and ** NULL is returned. If non-NULL is returned, then it is guaranteed ** that the new entry was successfully appended. */ -SQLITE_PRIVATE ExprList *tdsqlite3ExprListAppend( +SQLITE_PRIVATE ExprList *sqlite3ExprListAppend( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ Expr *pExpr /* Expression to be appended. Might be NULL */ ){ struct ExprList_item *pItem; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; assert( db!=0 ); if( pList==0 ){ - pList = tdsqlite3DbMallocRawNN(db, sizeof(ExprList) ); + pList = sqlite3DbMallocRawNN(db, sizeof(ExprList) ); if( pList==0 ){ goto no_mem; } pList->nExpr = 0; }else if( (pList->nExpr & (pList->nExpr-1))==0 ){ ExprList *pNew; - pNew = tdsqlite3DbRealloc(db, pList, - sizeof(*pList)+(2*(tdsqlite3_int64)pList->nExpr-1)*sizeof(pList->a[0])); + pNew = sqlite3DbRealloc(db, pList, + sizeof(*pList)+(2*(sqlite3_int64)pList->nExpr-1)*sizeof(pList->a[0])); if( pNew==0 ){ goto no_mem; } @@ -103944,8 +103944,8 @@ SQLITE_PRIVATE ExprList *tdsqlite3ExprListAppend( no_mem: /* Avoid leaking memory if malloc has failed. */ - tdsqlite3ExprDelete(db, pExpr); - tdsqlite3ExprListDelete(db, pList); + sqlite3ExprDelete(db, pExpr); + sqlite3ExprListDelete(db, pList); return 0; } @@ -103960,13 +103960,13 @@ no_mem: ** expression list pList. In the case of a subquery on the RHS, append ** TK_SELECT_COLUMN expressions. */ -SQLITE_PRIVATE ExprList *tdsqlite3ExprListAppendVector( +SQLITE_PRIVATE ExprList *sqlite3ExprListAppendVector( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to append. Might be NULL */ IdList *pColumns, /* List of names of LHS of the assignment */ Expr *pExpr /* Vector expression to be appended. Might be NULL */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int n; int i; int iFirst = pList ? pList->nExpr : 0; @@ -103980,19 +103980,19 @@ SQLITE_PRIVATE ExprList *tdsqlite3ExprListAppendVector( ** wildcards ("*") in the result set of the SELECT must be expanded before ** we can do the size check, so defer the size check until code generation. */ - if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=tdsqlite3ExprVectorSize(pExpr)) ){ - tdsqlite3ErrorMsg(pParse, "%d columns assigned %d values", + if( pExpr->op!=TK_SELECT && pColumns->nId!=(n=sqlite3ExprVectorSize(pExpr)) ){ + sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pColumns->nId, n); goto vector_append_error; } for(i=0; inId; i++){ - Expr *pSubExpr = tdsqlite3ExprForVectorField(pParse, pExpr, i); + Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i); assert( pSubExpr!=0 || db->mallocFailed ); assert( pSubExpr==0 || pSubExpr->iTable==0 ); if( pSubExpr==0 ) continue; pSubExpr->iTable = pColumns->nId; - pList = tdsqlite3ExprListAppend(pParse, pList, pSubExpr); + pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); if( pList ){ assert( pList->nExpr==iFirst+i+1 ); pList->a[pList->nExpr-1].zEName = pColumns->a[i].zName; @@ -104006,7 +104006,7 @@ SQLITE_PRIVATE ExprList *tdsqlite3ExprListAppendVector( assert( pFirst->op==TK_SELECT_COLUMN ); /* Store the SELECT statement in pRight so it will be deleted when - ** tdsqlite3ExprListDelete() is called */ + ** sqlite3ExprListDelete() is called */ pFirst->pRight = pExpr; pExpr = 0; @@ -104016,15 +104016,15 @@ SQLITE_PRIVATE ExprList *tdsqlite3ExprListAppendVector( } vector_append_error: - tdsqlite3ExprUnmapAndDelete(pParse, pExpr); - tdsqlite3IdListDelete(db, pColumns); + sqlite3ExprUnmapAndDelete(pParse, pExpr); + sqlite3IdListDelete(db, pColumns); return pList; } /* ** Set the sort order for the last element on the given ExprList. */ -SQLITE_PRIVATE void tdsqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ +SQLITE_PRIVATE void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ struct ExprList_item *pItem; if( p==0 ) return; assert( p->nExpr>0 ); @@ -104062,7 +104062,7 @@ SQLITE_PRIVATE void tdsqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, i ** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag ** is set. */ -SQLITE_PRIVATE void tdsqlite3ExprListSetName( +SQLITE_PRIVATE void sqlite3ExprListSetName( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to add the span. */ Token *pName, /* Name to be added */ @@ -104075,10 +104075,10 @@ SQLITE_PRIVATE void tdsqlite3ExprListSetName( pItem = &pList->a[pList->nExpr-1]; assert( pItem->zEName==0 ); assert( pItem->eEName==ENAME_NAME ); - pItem->zEName = tdsqlite3DbStrNDup(pParse->db, pName->z, pName->n); - if( dequote ) tdsqlite3Dequote(pItem->zEName); + pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n); + if( dequote ) sqlite3Dequote(pItem->zEName); if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName); + sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName); } } } @@ -104091,19 +104091,19 @@ SQLITE_PRIVATE void tdsqlite3ExprListSetName( ** NULL. If a memory allocation fails, the pParse->db->mallocFailed flag ** is set. */ -SQLITE_PRIVATE void tdsqlite3ExprListSetSpan( +SQLITE_PRIVATE void sqlite3ExprListSetSpan( Parse *pParse, /* Parsing context */ ExprList *pList, /* List to which to add the span. */ const char *zStart, /* Start of the span */ const char *zEnd /* End of the span */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; assert( pList!=0 || db->mallocFailed!=0 ); if( pList ){ struct ExprList_item *pItem = &pList->a[pList->nExpr-1]; assert( pList->nExpr>0 ); if( pItem->zEName==0 ){ - pItem->zEName = tdsqlite3DbSpanDup(db, zStart, zEnd); + pItem->zEName = sqlite3DbSpanDup(db, zStart, zEnd); pItem->eEName = ENAME_SPAN; } } @@ -104113,7 +104113,7 @@ SQLITE_PRIVATE void tdsqlite3ExprListSetSpan( ** If the expression list pEList contains more than iLimit elements, ** leave an error message in pParse. */ -SQLITE_PRIVATE void tdsqlite3ExprListCheckLength( +SQLITE_PRIVATE void sqlite3ExprListCheckLength( Parse *pParse, ExprList *pEList, const char *zObject @@ -104122,25 +104122,25 @@ SQLITE_PRIVATE void tdsqlite3ExprListCheckLength( testcase( pEList && pEList->nExpr==mx ); testcase( pEList && pEList->nExpr==mx+1 ); if( pEList && pEList->nExpr>mx ){ - tdsqlite3ErrorMsg(pParse, "too many columns in %s", zObject); + sqlite3ErrorMsg(pParse, "too many columns in %s", zObject); } } /* ** Delete an entire expression list. */ -static SQLITE_NOINLINE void exprListDeleteNN(tdsqlite3 *db, ExprList *pList){ +static SQLITE_NOINLINE void exprListDeleteNN(sqlite3 *db, ExprList *pList){ int i = pList->nExpr; struct ExprList_item *pItem = pList->a; assert( pList->nExpr>0 ); do{ - tdsqlite3ExprDelete(db, pItem->pExpr); - tdsqlite3DbFree(db, pItem->zEName); + sqlite3ExprDelete(db, pItem->pExpr); + sqlite3DbFree(db, pItem->zEName); pItem++; }while( --i>0 ); - tdsqlite3DbFreeNN(db, pList); + sqlite3DbFreeNN(db, pList); } -SQLITE_PRIVATE void tdsqlite3ExprListDelete(tdsqlite3 *db, ExprList *pList){ +SQLITE_PRIVATE void sqlite3ExprListDelete(sqlite3 *db, ExprList *pList){ if( pList ) exprListDeleteNN(db, pList); } @@ -104148,7 +104148,7 @@ SQLITE_PRIVATE void tdsqlite3ExprListDelete(tdsqlite3 *db, ExprList *pList){ ** Return the bitwise-OR of all Expr.flags fields in the given ** ExprList. */ -SQLITE_PRIVATE u32 tdsqlite3ExprListFlags(const ExprList *pList){ +SQLITE_PRIVATE u32 sqlite3ExprListFlags(const ExprList *pList){ int i; u32 m = 0; assert( pList!=0 ); @@ -104167,7 +104167,7 @@ SQLITE_PRIVATE u32 tdsqlite3ExprListFlags(const ExprList *pList){ ** ** This callback is used by multiple expression walkers. */ -SQLITE_PRIVATE int tdsqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ +SQLITE_PRIVATE int sqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ UNUSED_PARAMETER(NotUsed); pWalker->eCode = 0; return WRC_Abort; @@ -104181,9 +104181,9 @@ SQLITE_PRIVATE int tdsqlite3SelectWalkFail(Walker *pWalker, Select *NotUsed){ ** "false" EP_IsFalse ** anything else 0 */ -SQLITE_PRIVATE u32 tdsqlite3IsTrueOrFalse(const char *zIn){ - if( tdsqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue; - if( tdsqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse; +SQLITE_PRIVATE u32 sqlite3IsTrueOrFalse(const char *zIn){ + if( sqlite3StrICmp(zIn, "true")==0 ) return EP_IsTrue; + if( sqlite3StrICmp(zIn, "false")==0 ) return EP_IsFalse; return 0; } @@ -104193,11 +104193,11 @@ SQLITE_PRIVATE u32 tdsqlite3IsTrueOrFalse(const char *zIn){ ** then convert it into an TK_TRUEFALSE term. Return non-zero if ** the conversion happened, and zero if the expression is unaltered. */ -SQLITE_PRIVATE int tdsqlite3ExprIdToTrueFalse(Expr *pExpr){ +SQLITE_PRIVATE int sqlite3ExprIdToTrueFalse(Expr *pExpr){ u32 v; assert( pExpr->op==TK_ID || pExpr->op==TK_STRING ); if( !ExprHasProperty(pExpr, EP_Quoted) - && (v = tdsqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 + && (v = sqlite3IsTrueOrFalse(pExpr->u.zToken))!=0 ){ pExpr->op = TK_TRUEFALSE; ExprSetProperty(pExpr, v); @@ -104210,11 +104210,11 @@ SQLITE_PRIVATE int tdsqlite3ExprIdToTrueFalse(Expr *pExpr){ ** The argument must be a TK_TRUEFALSE Expr node. Return 1 if it is TRUE ** and 0 if it is FALSE. */ -SQLITE_PRIVATE int tdsqlite3ExprTruthValue(const Expr *pExpr){ - pExpr = tdsqlite3ExprSkipCollate((Expr*)pExpr); +SQLITE_PRIVATE int sqlite3ExprTruthValue(const Expr *pExpr){ + pExpr = sqlite3ExprSkipCollate((Expr*)pExpr); assert( pExpr->op==TK_TRUEFALSE ); - assert( tdsqlite3StrICmp(pExpr->u.zToken,"true")==0 - || tdsqlite3StrICmp(pExpr->u.zToken,"false")==0 ); + assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 + || sqlite3StrICmp(pExpr->u.zToken,"false")==0 ); return pExpr->u.zToken[4]==0; } @@ -104231,11 +104231,11 @@ SQLITE_PRIVATE int tdsqlite3ExprTruthValue(const Expr *pExpr){ ** (x<10) AND (y=22 OR true) => (x<10) ** (y=22) OR true => true */ -SQLITE_PRIVATE Expr *tdsqlite3ExprSimplifiedAndOr(Expr *pExpr){ +SQLITE_PRIVATE Expr *sqlite3ExprSimplifiedAndOr(Expr *pExpr){ assert( pExpr!=0 ); if( pExpr->op==TK_AND || pExpr->op==TK_OR ){ - Expr *pRight = tdsqlite3ExprSimplifiedAndOr(pExpr->pRight); - Expr *pLeft = tdsqlite3ExprSimplifiedAndOr(pExpr->pLeft); + Expr *pRight = sqlite3ExprSimplifiedAndOr(pExpr->pRight); + Expr *pLeft = sqlite3ExprSimplifiedAndOr(pExpr->pLeft); if( ExprAlwaysTrue(pLeft) || ExprAlwaysFalse(pRight) ){ pExpr = pExpr->op==TK_AND ? pRight : pLeft; }else if( ExprAlwaysTrue(pRight) || ExprAlwaysFalse(pLeft) ){ @@ -104254,15 +104254,15 @@ SQLITE_PRIVATE Expr *tdsqlite3ExprSimplifiedAndOr(Expr *pExpr){ ** ** These callback routines are used to implement the following: ** -** tdsqlite3ExprIsConstant() pWalker->eCode==1 -** tdsqlite3ExprIsConstantNotJoin() pWalker->eCode==2 -** tdsqlite3ExprIsTableConstant() pWalker->eCode==3 -** tdsqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5 +** sqlite3ExprIsConstant() pWalker->eCode==1 +** sqlite3ExprIsConstantNotJoin() pWalker->eCode==2 +** sqlite3ExprIsTableConstant() pWalker->eCode==3 +** sqlite3ExprIsConstantOrFunction() pWalker->eCode==4 or 5 ** ** In all cases, the callbacks set Walker.eCode=0 and abort if the expression ** is found to not be a constant. ** -** The tdsqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT +** The sqlite3ExprIsConstantOrFunction() is used for evaluating DEFAULT ** expressions in a CREATE TABLE statement. The Walker.eCode value is 5 ** when parsing an existing schema out of the sqlite_master table and 4 ** when processing a new CREATE TABLE statement. A bound parameter raises @@ -104299,7 +104299,7 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ case TK_ID: /* Convert "true" or "false" in a DEFAULT clause into the ** appropriate TK_TRUEFALSE operator */ - if( tdsqlite3ExprIdToTrueFalse(pExpr) ){ + if( sqlite3ExprIdToTrueFalse(pExpr) ){ return WRC_Prune; } /* Fall thru */ @@ -104331,14 +104331,14 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){ pExpr->op = TK_NULL; }else if( pWalker->eCode==4 ){ /* A bound parameter in a CREATE statement that originates from - ** tdsqlite3_prepare() causes an error */ + ** sqlite3_prepare() causes an error */ pWalker->eCode = 0; return WRC_Abort; } /* Fall through */ default: - testcase( pExpr->op==TK_SELECT ); /* tdsqlite3SelectWalkFail() disallows */ - testcase( pExpr->op==TK_EXISTS ); /* tdsqlite3SelectWalkFail() disallows */ + testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */ + testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */ return WRC_Continue; } } @@ -104346,12 +104346,12 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){ Walker w; w.eCode = initFlag; w.xExprCallback = exprNodeIsConstant; - w.xSelectCallback = tdsqlite3SelectWalkFail; + w.xSelectCallback = sqlite3SelectWalkFail; #ifdef SQLITE_DEBUG - w.xSelectCallback2 = tdsqlite3SelectWalkAssert2; + w.xSelectCallback2 = sqlite3SelectWalkAssert2; #endif w.u.iCur = iCur; - tdsqlite3WalkExpr(&w, p); + sqlite3WalkExpr(&w, p); return w.eCode; } @@ -104363,7 +104363,7 @@ static int exprIsConst(Expr *p, int initFlag, int iCur){ ** is considered a variable but a single-quoted string (ex: 'abc') is ** a constant. */ -SQLITE_PRIVATE int tdsqlite3ExprIsConstant(Expr *p){ +SQLITE_PRIVATE int sqlite3ExprIsConstant(Expr *p){ return exprIsConst(p, 1, 0); } @@ -104378,9 +104378,9 @@ SQLITE_PRIVATE int tdsqlite3ExprIsConstant(Expr *p){ ** ** When this routine returns true, it indicates that the expression ** can be added to the pParse->pConstExpr list and evaluated once when -** the prepared statement starts up. See tdsqlite3ExprCodeAtInit(). +** the prepared statement starts up. See sqlite3ExprCodeAtInit(). */ -SQLITE_PRIVATE int tdsqlite3ExprIsConstantNotJoin(Expr *p){ +SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr *p){ return exprIsConst(p, 2, 0); } @@ -104390,13 +104390,13 @@ SQLITE_PRIVATE int tdsqlite3ExprIsConstantNotJoin(Expr *p){ ** expression must not refer to any non-deterministic function nor any ** table other than iCur. */ -SQLITE_PRIVATE int tdsqlite3ExprIsTableConstant(Expr *p, int iCur){ +SQLITE_PRIVATE int sqlite3ExprIsTableConstant(Expr *p, int iCur){ return exprIsConst(p, 3, iCur); } /* -** tdsqlite3WalkExpr() callback used by tdsqlite3ExprIsConstantOrGroupBy(). +** sqlite3WalkExpr() callback used by sqlite3ExprIsConstantOrGroupBy(). */ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ ExprList *pGroupBy = pWalker->u.pGroupBy; @@ -104406,9 +104406,9 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ ** it constant. */ for(i=0; inExpr; i++){ Expr *p = pGroupBy->a[i].pExpr; - if( tdsqlite3ExprCompare(0, pExpr, p, -1)<2 ){ - CollSeq *pColl = tdsqlite3ExprNNCollSeq(pWalker->pParse, p); - if( tdsqlite3IsBinary(pColl) ){ + if( sqlite3ExprCompare(0, pExpr, p, -1)<2 ){ + CollSeq *pColl = sqlite3ExprNNCollSeq(pWalker->pParse, p); + if( sqlite3IsBinary(pColl) ){ return WRC_Prune; } } @@ -104442,14 +104442,14 @@ static int exprNodeIsConstantOrGroupBy(Walker *pWalker, Expr *pExpr){ ** optimization, so we take the easy way out and simply require the ** GROUP BY to use the BINARY collating sequence. */ -SQLITE_PRIVATE int tdsqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ +SQLITE_PRIVATE int sqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, ExprList *pGroupBy){ Walker w; w.eCode = 1; w.xExprCallback = exprNodeIsConstantOrGroupBy; w.xSelectCallback = 0; w.u.pGroupBy = pGroupBy; w.pParse = pParse; - tdsqlite3WalkExpr(&w, p); + sqlite3WalkExpr(&w, p); return w.eCode; } @@ -104474,7 +104474,7 @@ SQLITE_PRIVATE int tdsqlite3ExprIsConstantOrGroupBy(Parse *pParse, Expr *p, Expr ** is considered a variable but a single-quoted string (ex: 'abc') is ** a constant. */ -SQLITE_PRIVATE int tdsqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ +SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ assert( isInit==0 || isInit==1 ); return exprIsConst(p, 4+isInit, 0); } @@ -104484,15 +104484,15 @@ SQLITE_PRIVATE int tdsqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){ ** Walk an expression tree. Return 1 if the expression contains a ** subquery of some kind. Return 0 if there are no subqueries. */ -SQLITE_PRIVATE int tdsqlite3ExprContainsSubquery(Expr *p){ +SQLITE_PRIVATE int sqlite3ExprContainsSubquery(Expr *p){ Walker w; w.eCode = 1; - w.xExprCallback = tdsqlite3ExprWalkNoop; - w.xSelectCallback = tdsqlite3SelectWalkFail; + w.xExprCallback = sqlite3ExprWalkNoop; + w.xSelectCallback = sqlite3SelectWalkFail; #ifdef SQLITE_DEBUG - w.xSelectCallback2 = tdsqlite3SelectWalkAssert2; + w.xSelectCallback2 = sqlite3SelectWalkAssert2; #endif - tdsqlite3WalkExpr(&w, p); + sqlite3WalkExpr(&w, p); return w.eCode==0; } #endif @@ -104503,14 +104503,14 @@ SQLITE_PRIVATE int tdsqlite3ExprContainsSubquery(Expr *p){ ** in *pValue. If the expression is not an integer or if it is too big ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged. */ -SQLITE_PRIVATE int tdsqlite3ExprIsInteger(Expr *p, int *pValue){ +SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){ int rc = 0; if( NEVER(p==0) ) return 0; /* Used to only happen following on OOM */ /* If an expression is an integer literal that fits in a signed 32-bit ** integer, then the EP_IntValue flag will have already been set */ assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0 - || tdsqlite3GetInt32(p->u.zToken, &rc)==0 ); + || sqlite3GetInt32(p->u.zToken, &rc)==0 ); if( p->flags & EP_IntValue ){ *pValue = p->u.iValue; @@ -104518,12 +104518,12 @@ SQLITE_PRIVATE int tdsqlite3ExprIsInteger(Expr *p, int *pValue){ } switch( p->op ){ case TK_UPLUS: { - rc = tdsqlite3ExprIsInteger(p->pLeft, pValue); + rc = sqlite3ExprIsInteger(p->pLeft, pValue); break; } case TK_UMINUS: { int v; - if( tdsqlite3ExprIsInteger(p->pLeft, &v) ){ + if( sqlite3ExprIsInteger(p->pLeft, &v) ){ assert( v!=(-2147483647-1) ); *pValue = -v; rc = 1; @@ -104549,7 +104549,7 @@ SQLITE_PRIVATE int tdsqlite3ExprIsInteger(Expr *p, int *pValue){ ** will likely result in an incorrect answer. So when in doubt, return ** TRUE. */ -SQLITE_PRIVATE int tdsqlite3ExprCanBeNull(const Expr *p){ +SQLITE_PRIVATE int sqlite3ExprCanBeNull(const Expr *p){ u8 op; while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; @@ -104583,7 +104583,7 @@ SQLITE_PRIVATE int tdsqlite3ExprCanBeNull(const Expr *p){ ** is harmless. A false positive, however, can result in the wrong ** answer. */ -SQLITE_PRIVATE int tdsqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ +SQLITE_PRIVATE int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ u8 op; int unaryMinus = 0; if( aff==SQLITE_AFF_BLOB ) return 1; @@ -104619,10 +104619,10 @@ SQLITE_PRIVATE int tdsqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ /* ** Return TRUE if the given string is a row-id column name. */ -SQLITE_PRIVATE int tdsqlite3IsRowid(const char *z){ - if( tdsqlite3StrICmp(z, "_ROWID_")==0 ) return 1; - if( tdsqlite3StrICmp(z, "ROWID")==0 ) return 1; - if( tdsqlite3StrICmp(z, "OID")==0 ) return 1; +SQLITE_PRIVATE int sqlite3IsRowid(const char *z){ + if( sqlite3StrICmp(z, "_ROWID_")==0 ) return 1; + if( sqlite3StrICmp(z, "ROWID")==0 ) return 1; + if( sqlite3StrICmp(z, "OID")==0 ) return 1; return 0; } @@ -104679,14 +104679,14 @@ static Select *isCandidateForInOpt(Expr *pX){ ** to a non-NULL value if iCur contains no NULLs. Cause register regHasNull ** to be set to NULL if iCur contains one or more NULL values. */ -static void tdsqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ +static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ int addr1; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); - addr1 = tdsqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); - tdsqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull); + addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); VdbeComment((v, "first_entry_in(%d)", iCur)); - tdsqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeJumpHere(v, addr1); } #endif @@ -104696,13 +104696,13 @@ static void tdsqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){ ** The argument is an IN operator with a list (not a subquery) on the ** right-hand side. Return TRUE if that list is constant. */ -static int tdsqlite3InRhsIsConstant(Expr *pIn){ +static int sqlite3InRhsIsConstant(Expr *pIn){ Expr *pLHS; int res; assert( !ExprHasProperty(pIn, EP_xIsSelect) ); pLHS = pIn->pLeft; pIn->pLeft = 0; - res = tdsqlite3ExprIsConstant(pIn); + res = sqlite3ExprIsConstant(pIn); pIn->pLeft = pLHS; return res; } @@ -104789,7 +104789,7 @@ static int tdsqlite3InRhsIsConstant(Expr *pIn){ ** then aiMap[] is populated with {2, 0, 1}. */ #ifndef SQLITE_OMIT_SUBQUERY -SQLITE_PRIVATE int tdsqlite3FindInIndex( +SQLITE_PRIVATE int sqlite3FindInIndex( Parse *pParse, /* Parsing context */ Expr *pX, /* The IN expression */ u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */ @@ -104801,7 +104801,7 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( int eType = 0; /* Type of RHS table. IN_INDEX_* */ int iTab = pParse->nTab++; /* Cursor of the RHS table */ int mustBeUnique; /* True if RHS must be unique */ - Vdbe *v = tdsqlite3GetVdbe(pParse); /* Virtual machine being coded */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Virtual machine being coded */ assert( pX->op==TK_IN ); mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; @@ -104815,7 +104815,7 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( int i; ExprList *pEList = pX->x.pSelect->pEList; for(i=0; inExpr; i++){ - if( tdsqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break; + if( sqlite3ExprCanBeNull(pEList->a[i].pExpr) ) break; } if( i==pEList->nExpr ){ prRhsHasNull = 0; @@ -104826,7 +104826,7 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( ** satisfy the query. This is preferable to generating a new ** ephemeral table. */ if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){ - tdsqlite3 *db = pParse->db; /* Database connection */ + sqlite3 *db = pParse->db; /* Database connection */ Table *pTab; /* Table . */ i16 iDb; /* Database idx for pTab */ ExprList *pEList = p->pEList; @@ -104838,21 +104838,21 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( pTab = p->pSrc->a[0].pTab; /* Code an OP_Transaction and OP_TableLock for
. */ - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); - tdsqlite3CodeVerifySchema(pParse, iDb); - tdsqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); - assert(v); /* tdsqlite3GetVdbe() has always been previously called */ + assert(v); /* sqlite3GetVdbe() has always been previously called */ if( nExpr==1 && pEList->a[0].pExpr->iColumn<0 ){ /* The "x IN (SELECT rowid FROM table)" case */ - int iAddr = tdsqlite3VdbeAddOp0(v, OP_Once); + int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); - tdsqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); eType = IN_INDEX_ROWID; ExplainQueryPlan((pParse, 0, "USING ROWID SEARCH ON TABLE %s FOR IN-OPERATOR",pTab->zName)); - tdsqlite3VdbeJumpHere(v, iAddr); + sqlite3VdbeJumpHere(v, iAddr); }else{ Index *pIdx; /* Iterator variable */ int affinity_ok = 1; @@ -104863,24 +104863,24 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( ** on the RHS of the IN operator. If it not, it is not possible to ** use any index of the RHS table. */ for(i=0; ipLeft, i); + Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i); int iCol = pEList->a[i].pExpr->iColumn; - char idxaff = tdsqlite3TableColumnAffinity(pTab,iCol); /* RHS table */ - char cmpaff = tdsqlite3CompareAffinity(pLhs, idxaff); + char idxaff = sqlite3TableColumnAffinity(pTab,iCol); /* RHS table */ + char cmpaff = sqlite3CompareAffinity(pLhs, idxaff); testcase( cmpaff==SQLITE_AFF_BLOB ); testcase( cmpaff==SQLITE_AFF_TEXT ); switch( cmpaff ){ case SQLITE_AFF_BLOB: break; case SQLITE_AFF_TEXT: - /* tdsqlite3CompareAffinity() only returns TEXT if one side or the + /* sqlite3CompareAffinity() only returns TEXT if one side or the ** other has no affinity and the other side is TEXT. Hence, ** the only way for cmpaff to be TEXT is for idxaff to be TEXT ** and for the term on the LHS of the IN to have no affinity. */ assert( idxaff==SQLITE_AFF_TEXT ); break; default: - affinity_ok = tdsqlite3IsNumericAffinity(idxaff); + affinity_ok = sqlite3IsNumericAffinity(idxaff); } } @@ -104906,16 +104906,16 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( colUsed = 0; /* Columns of index used so far */ for(i=0; ipLeft, i); + Expr *pLhs = sqlite3VectorFieldSubexpr(pX->pLeft, i); Expr *pRhs = pEList->a[i].pExpr; - CollSeq *pReq = tdsqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; assert( pReq!=0 || pRhs->iColumn==XN_ROWID || pParse->nErr ); for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; assert( pIdx->azColl[j] ); - if( pReq!=0 && tdsqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){ + if( pReq!=0 && sqlite3StrICmp(pReq->zName, pIdx->azColl[j])!=0 ){ continue; } break; @@ -104930,11 +104930,11 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); if( colUsed==(MASKBIT(nExpr)-1) ){ /* If we reach this point, that means the index pIdx is usable */ - int iAddr = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + int iAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); ExplainQueryPlan((pParse, 0, "USING INDEX %s FOR IN-OPERATOR",pIdx->zName)); - tdsqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); - tdsqlite3VdbeSetP4KeyInfo(pParse, pIdx); + sqlite3VdbeAddOp3(v, OP_OpenRead, iTab, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; @@ -104942,15 +104942,15 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( if( prRhsHasNull ){ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK i64 mask = (1<nMem; if( nExpr==1 ){ - tdsqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); + sqlite3SetHasNullFlag(v, iTab, *prRhsHasNull); } } - tdsqlite3VdbeJumpHere(v, iAddr); + sqlite3VdbeJumpHere(v, iAddr); } } /* End loop over indexes */ } /* End if( affinity_ok ) */ @@ -104967,7 +104967,7 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( if( eType==0 && (inFlags & IN_INDEX_NOOP_OK) && !ExprHasProperty(pX, EP_xIsSelect) - && (!tdsqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) + && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2) ){ eType = IN_INDEX_NOOP; } @@ -104985,16 +104985,16 @@ SQLITE_PRIVATE int tdsqlite3FindInIndex( *prRhsHasNull = rMayHaveNull = ++pParse->nMem; } assert( pX->op==TK_IN ); - tdsqlite3CodeRhsOfIN(pParse, pX, iTab); + sqlite3CodeRhsOfIN(pParse, pX, iTab); if( rMayHaveNull ){ - tdsqlite3SetHasNullFlag(v, iTab, rMayHaveNull); + sqlite3SetHasNullFlag(v, iTab, rMayHaveNull); } pParse->nQueryLoop = savedNQueryLoop; } if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){ int i, n; - n = tdsqlite3ExprVectorSize(pX->pLeft); + n = sqlite3ExprVectorSize(pX->pLeft); for(i=0; ipLeft; - int nVal = tdsqlite3ExprVectorSize(pLeft); + int nVal = sqlite3ExprVectorSize(pLeft); Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0; char *zRet; assert( pExpr->op==TK_IN ); - zRet = tdsqlite3DbMallocRaw(pParse->db, nVal+1); + zRet = sqlite3DbMallocRaw(pParse->db, nVal+1); if( zRet ){ int i; for(i=0; ipEList->a[i].pExpr, a); + zRet[i] = sqlite3CompareAffinity(pSelect->pEList->a[i].pExpr, a); }else{ zRet[i] = a; } @@ -105043,10 +105043,10 @@ static char *exprINAffinity(Parse *pParse, Expr *pExpr){ ** ** "sub-select returns N columns - expected M" */ -SQLITE_PRIVATE void tdsqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ +SQLITE_PRIVATE void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ if( pParse->nErr==0 ){ const char *zFmt = "sub-select returns %d columns - expected %d"; - tdsqlite3ErrorMsg(pParse, zFmt, nActual, nExpect); + sqlite3ErrorMsg(pParse, zFmt, nActual, nExpect); } } #endif @@ -105062,14 +105062,14 @@ SQLITE_PRIVATE void tdsqlite3SubselectError(Parse *pParse, int nActual, int nExp ** ** "row value misused" */ -SQLITE_PRIVATE void tdsqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ +SQLITE_PRIVATE void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ #ifndef SQLITE_OMIT_SUBQUERY if( pExpr->flags & EP_xIsSelect ){ - tdsqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1); + sqlite3SubselectError(pParse, pExpr->x.pSelect->pEList->nExpr, 1); }else #endif { - tdsqlite3ErrorMsg(pParse, "row value misused"); + sqlite3ErrorMsg(pParse, "row value misused"); } } @@ -105096,7 +105096,7 @@ SQLITE_PRIVATE void tdsqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ ** 'x' nor the SELECT... statement are columns, then numeric affinity ** is used. */ -SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN( +SQLITE_PRIVATE void sqlite3CodeRhsOfIN( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The IN operator */ int iTab /* Use this cursor number */ @@ -105127,15 +105127,15 @@ SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN( ** might not have been invoked yet, so invoke it now as a subroutine. */ if( ExprHasProperty(pExpr, EP_Subrtn) ){ - addrOnce = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", pExpr->x.pSelect->selId)); } - tdsqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); - tdsqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); - tdsqlite3VdbeJumpHere(v, addrOnce); + sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); + sqlite3VdbeJumpHere(v, addrOnce); return; } @@ -105143,21 +105143,21 @@ SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN( ExprSetProperty(pExpr, EP_Subrtn); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; VdbeComment((v, "return address")); - addrOnce = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } /* Check to see if this is a vector IN operator */ pLeft = pExpr->pLeft; - nVal = tdsqlite3ExprVectorSize(pLeft); + nVal = sqlite3ExprVectorSize(pLeft); /* Construct the ephemeral table that will contain the content of ** RHS of the IN operator. */ pExpr->iTable = iTab; - addr = tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS if( ExprHasProperty(pExpr, EP_xIsSelect) ){ VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId)); @@ -105165,7 +105165,7 @@ SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN( VdbeComment((v, "RHS of IN operator")); } #endif - pKeyInfo = tdsqlite3KeyInfoAlloc(pParse->db, nVal, 1); + pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* Case 1: expr IN (SELECT ...) @@ -105184,24 +105184,24 @@ SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN( if( ALWAYS(pEList->nExpr==nVal) ){ SelectDest dest; int i; - tdsqlite3SelectDestInit(&dest, SRT_Set, iTab); + sqlite3SelectDestInit(&dest, SRT_Set, iTab); dest.zAffSdst = exprINAffinity(pParse, pExpr); pSelect->iLimit = 0; testcase( pSelect->selFlags & SF_Distinct ); - testcase( pKeyInfo==0 ); /* Caused by OOM in tdsqlite3KeyInfoAlloc() */ - if( tdsqlite3Select(pParse, pSelect, &dest) ){ - tdsqlite3DbFree(pParse->db, dest.zAffSdst); - tdsqlite3KeyInfoUnref(pKeyInfo); + testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */ + if( sqlite3Select(pParse, pSelect, &dest) ){ + sqlite3DbFree(pParse->db, dest.zAffSdst); + sqlite3KeyInfoUnref(pKeyInfo); return; } - tdsqlite3DbFree(pParse->db, dest.zAffSdst); - assert( pKeyInfo!=0 ); /* OOM will cause exit after tdsqlite3Select() */ + sqlite3DbFree(pParse->db, dest.zAffSdst); + assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ assert( pEList!=0 ); assert( pEList->nExpr>0 ); - assert( tdsqlite3KeyInfoIsWriteable(pKeyInfo) ); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); for(i=0; iaColl[i] = tdsqlite3BinaryCompareCollSeq( + Expr *p = sqlite3VectorFieldSubexpr(pLeft, i); + pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq( pParse, p, pEList->a[i].pExpr ); } @@ -105219,18 +105219,18 @@ SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN( ExprList *pList = pExpr->x.pList; struct ExprList_item *pItem; int r1, r2; - affinity = tdsqlite3ExprAffinity(pLeft); + affinity = sqlite3ExprAffinity(pLeft); if( affinity<=SQLITE_AFF_NONE ){ affinity = SQLITE_AFF_BLOB; } if( pKeyInfo ){ - assert( tdsqlite3KeyInfoIsWriteable(pKeyInfo) ); - pKeyInfo->aColl[0] = tdsqlite3ExprCollSeq(pParse, pExpr->pLeft); + assert( sqlite3KeyInfoIsWriteable(pKeyInfo) ); + pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft); } /* Loop through each expression in . */ - r1 = tdsqlite3GetTempReg(pParse); - r2 = tdsqlite3GetTempReg(pParse); + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempReg(pParse); for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){ Expr *pE2 = pItem->pExpr; @@ -105239,29 +105239,29 @@ SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN( ** this code only executes once. Because for a non-constant ** expression we need to rerun this code each time. */ - if( addrOnce && !tdsqlite3ExprIsConstant(pE2) ){ - tdsqlite3VdbeChangeToNoop(v, addrOnce); + if( addrOnce && !sqlite3ExprIsConstant(pE2) ){ + sqlite3VdbeChangeToNoop(v, addrOnce); ExprClearProperty(pExpr, EP_Subrtn); addrOnce = 0; } /* Evaluate the expression and insert it into the temp table */ - tdsqlite3ExprCode(pParse, pE2, r1); - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); + sqlite3ExprCode(pParse, pE2, r1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); } - tdsqlite3ReleaseTempReg(pParse, r1); - tdsqlite3ReleaseTempReg(pParse, r2); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r2); } if( pKeyInfo ){ - tdsqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); + sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO); } if( addrOnce ){ - tdsqlite3VdbeJumpHere(v, addrOnce); + sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ - tdsqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); - tdsqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, tdsqlite3VdbeCurrentAddr(v)-1); - tdsqlite3ClearTempRegCache(pParse); + sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); + sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); + sqlite3ClearTempRegCache(pParse); } } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -105281,7 +105281,7 @@ SQLITE_PRIVATE void tdsqlite3CodeRhsOfIN( ** Return 0 if an error occurs. */ #ifndef SQLITE_OMIT_SUBQUERY -SQLITE_PRIVATE int tdsqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ +SQLITE_PRIVATE int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ int addrOnce = 0; /* Address of OP_Once at top of subroutine */ int rReg = 0; /* Register storing resulting */ Select *pSel; /* SELECT statement to encode */ @@ -105312,7 +105312,7 @@ SQLITE_PRIVATE int tdsqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** subroutine. */ if( ExprHasProperty(pExpr, EP_Subrtn) ){ ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId)); - tdsqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, + sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, pExpr->y.sub.iAddr); return pExpr->iTable; } @@ -105321,10 +105321,10 @@ SQLITE_PRIVATE int tdsqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ExprSetProperty(pExpr, EP_Subrtn); pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.iAddr = - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; + sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1; VdbeComment((v, "return address")); - addrOnce = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } /* For a SELECT, generate code to put the values for all columns of @@ -105340,49 +105340,49 @@ SQLITE_PRIVATE int tdsqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d", addrOnce?"":"CORRELATED ", pSel->selId)); nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1; - tdsqlite3SelectDestInit(&dest, 0, pParse->nMem+1); + sqlite3SelectDestInit(&dest, 0, pParse->nMem+1); pParse->nMem += nReg; if( pExpr->op==TK_SELECT ){ dest.eDest = SRT_Mem; dest.iSdst = dest.iSDParm; dest.nSdst = nReg; - tdsqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1); + sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1); VdbeComment((v, "Init subquery result")); }else{ dest.eDest = SRT_Exists; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); + sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); VdbeComment((v, "Init EXISTS result")); } if( pSel->pLimit ){ /* The subquery already has a limit. If the pre-existing limit is X ** then make the new limit X<>0 so that the new limit is either 1 or 0 */ - tdsqlite3 *db = pParse->db; - pLimit = tdsqlite3Expr(db, TK_INTEGER, "0"); + sqlite3 *db = pParse->db; + pLimit = sqlite3Expr(db, TK_INTEGER, "0"); if( pLimit ){ pLimit->affExpr = SQLITE_AFF_NUMERIC; - pLimit = tdsqlite3PExpr(pParse, TK_NE, - tdsqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); + pLimit = sqlite3PExpr(pParse, TK_NE, + sqlite3ExprDup(db, pSel->pLimit->pLeft, 0), pLimit); } - tdsqlite3ExprDelete(db, pSel->pLimit->pLeft); + sqlite3ExprDelete(db, pSel->pLimit->pLeft); pSel->pLimit->pLeft = pLimit; }else{ /* If there is no pre-existing limit add a limit of 1 */ - pLimit = tdsqlite3Expr(pParse->db, TK_INTEGER, "1"); - pSel->pLimit = tdsqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); + pLimit = sqlite3Expr(pParse->db, TK_INTEGER, "1"); + pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0); } pSel->iLimit = 0; - if( tdsqlite3Select(pParse, pSel, &dest) ){ + if( sqlite3Select(pParse, pSel, &dest) ){ return 0; } pExpr->iTable = rReg = dest.iSDParm; ExprSetVVAProperty(pExpr, EP_NoReduce); if( addrOnce ){ - tdsqlite3VdbeJumpHere(v, addrOnce); + sqlite3VdbeJumpHere(v, addrOnce); /* Subroutine return */ - tdsqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); - tdsqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, tdsqlite3VdbeCurrentAddr(v)-1); - tdsqlite3ClearTempRegCache(pParse); + sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); + sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); + sqlite3ClearTempRegCache(pParse); } return rReg; @@ -105396,15 +105396,15 @@ SQLITE_PRIVATE int tdsqlite3CodeSubselect(Parse *pParse, Expr *pExpr){ ** columns as the vector on the LHS. Or, if the RHS of the IN() is not ** a sub-query, that the LHS is a vector of size 1. */ -SQLITE_PRIVATE int tdsqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ - int nVector = tdsqlite3ExprVectorSize(pIn->pLeft); +SQLITE_PRIVATE int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ + int nVector = sqlite3ExprVectorSize(pIn->pLeft); if( (pIn->flags & EP_xIsSelect) ){ if( nVector!=pIn->x.pSelect->pEList->nExpr ){ - tdsqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); + sqlite3SubselectError(pParse, pIn->x.pSelect->pEList->nExpr, nVector); return 1; } }else if( nVector!=1 ){ - tdsqlite3VectorErrorMsg(pParse, pIn->pLeft); + sqlite3VectorErrorMsg(pParse, pIn->pLeft); return 1; } return 0; @@ -105437,7 +105437,7 @@ SQLITE_PRIVATE int tdsqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ ** See the separate in-operator.md documentation file in the canonical ** SQLite source tree for additional information. */ -static void tdsqlite3ExprCodeIN( +static void sqlite3ExprCodeIN( Parse *pParse, /* Parsing and code generating context */ Expr *pExpr, /* The IN expression */ int destIfFalse, /* Jump here if LHS is not contained in the RHS */ @@ -105462,13 +105462,13 @@ static void tdsqlite3ExprCodeIN( int iTab = 0; /* Index to use */ pLeft = pExpr->pLeft; - if( tdsqlite3ExprCheckIN(pParse, pExpr) ) return; + if( sqlite3ExprCheckIN(pParse, pExpr) ) return; zAff = exprINAffinity(pParse, pExpr); - nVector = tdsqlite3ExprVectorSize(pExpr->pLeft); - aiMap = (int*)tdsqlite3DbMallocZero( + nVector = sqlite3ExprVectorSize(pExpr->pLeft); + aiMap = (int*)sqlite3DbMallocZero( pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1 ); - if( pParse->db->mallocFailed ) goto tdsqlite3ExprCodeIN_oom_error; + if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error; /* Attempt to compute the RHS. After this step, if anything other than ** IN_INDEX_NOOP is returned, the table opened with cursor iTab @@ -105477,7 +105477,7 @@ static void tdsqlite3ExprCodeIN( v = pParse->pVdbe; assert( v!=0 ); /* OOM detected prior to this routine */ VdbeNoopComment((v, "begin IN expr")); - eType = tdsqlite3FindInIndex(pParse, pExpr, + eType = sqlite3FindInIndex(pParse, pExpr, IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK, destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap, &iTab); @@ -105499,7 +105499,7 @@ static void tdsqlite3ExprCodeIN( ** vector, then it is stored in an array of nVector registers starting ** at r1. ** - ** tdsqlite3FindInIndex() might have reordered the fields of the LHS vector + ** sqlite3FindInIndex() might have reordered the fields of the LHS vector ** so that the fields are in the same order as an existing index. The ** aiMap[] array contains a mapping from the original LHS field order to ** the field order that matches the RHS index. @@ -105511,13 +105511,13 @@ static void tdsqlite3ExprCodeIN( rLhs = rLhsOrig; }else{ /* Need to reorder the LHS fields according to aiMap */ - rLhs = tdsqlite3GetTempRange(pParse, nVector); + rLhs = sqlite3GetTempRange(pParse, nVector); for(i=0; ix.pList; - CollSeq *pColl = tdsqlite3ExprCollSeq(pParse, pExpr->pLeft); - int labelOk = tdsqlite3VdbeMakeLabel(pParse); + CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft); + int labelOk = sqlite3VdbeMakeLabel(pParse); int r2, regToFree; int regCkNull = 0; int ii; int bLhsReal; /* True if the LHS of the IN has REAL affinity */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( destIfNull!=destIfFalse ){ - regCkNull = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); + regCkNull = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); } - bLhsReal = tdsqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL; + bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL; for(ii=0; iinExpr; ii++){ if( bLhsReal ){ - r2 = regToFree = tdsqlite3GetTempReg(pParse); - tdsqlite3ExprCode(pParse, pList->a[ii].pExpr, r2); - tdsqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC); + r2 = regToFree = sqlite3GetTempReg(pParse); + sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2); + sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC); }else{ - r2 = tdsqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); + r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); } - if( regCkNull && tdsqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ - tdsqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); + if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ + sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); } - tdsqlite3ReleaseTempReg(pParse, regToFree); + sqlite3ReleaseTempReg(pParse, regToFree); if( iinExpr-1 || destIfNull!=destIfFalse ){ int op = rLhs!=r2 ? OP_Eq : OP_NotNull; - tdsqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2, + sqlite3VdbeAddOp4(v, op, rLhs, labelOk, r2, (void*)pColl, P4_COLLSEQ); VdbeCoverageIf(v, iinExpr-1 && op==OP_Eq); VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_Eq); VdbeCoverageIf(v, iinExpr-1 && op==OP_NotNull); VdbeCoverageIf(v, ii==pList->nExpr-1 && op==OP_NotNull); - tdsqlite3VdbeChangeP5(v, zAff[0]); + sqlite3VdbeChangeP5(v, zAff[0]); }else{ int op = rLhs!=r2 ? OP_Ne : OP_IsNull; assert( destIfNull==destIfFalse ); - tdsqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2, + sqlite3VdbeAddOp4(v, op, rLhs, destIfFalse, r2, (void*)pColl, P4_COLLSEQ); VdbeCoverageIf(v, op==OP_Ne); VdbeCoverageIf(v, op==OP_IsNull); - tdsqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL); + sqlite3VdbeChangeP5(v, zAff[0] | SQLITE_JUMPIFNULL); } } if( regCkNull ){ - tdsqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); - tdsqlite3VdbeGoto(v, destIfFalse); + sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v); + sqlite3VdbeGoto(v, destIfFalse); } - tdsqlite3VdbeResolveLabel(v, labelOk); - tdsqlite3ReleaseTempReg(pParse, regCkNull); - goto tdsqlite3ExprCodeIN_finished; + sqlite3VdbeResolveLabel(v, labelOk); + sqlite3ReleaseTempReg(pParse, regCkNull); + goto sqlite3ExprCodeIN_finished; } /* Step 2: Check to see if the LHS contains any NULL columns. If the @@ -105584,13 +105584,13 @@ static void tdsqlite3ExprCodeIN( if( destIfNull==destIfFalse ){ destStep2 = destIfFalse; }else{ - destStep2 = destStep6 = tdsqlite3VdbeMakeLabel(pParse); + destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse); } - if( pParse->nErr ) goto tdsqlite3ExprCodeIN_finished; + if( pParse->nErr ) goto sqlite3ExprCodeIN_finished; for(i=0; ipLeft, i); - if( tdsqlite3ExprCanBeNull(p) ){ - tdsqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); + Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i); + if( sqlite3ExprCanBeNull(p) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2); VdbeCoverage(v); } } @@ -105603,19 +105603,19 @@ static void tdsqlite3ExprCodeIN( /* In this case, the RHS is the ROWID of table b-tree and so we also ** know that the RHS is non-NULL. Hence, we combine steps 3 and 4 ** into a single opcode. */ - tdsqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs); VdbeCoverage(v); - addrTruthOp = tdsqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ + addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto); /* Return True */ }else{ - tdsqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); + sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector); if( destIfFalse==destIfNull ){ /* Combine Step 3 and Step 5 into a single opcode */ - tdsqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, + sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse, rLhs, nVector); VdbeCoverage(v); - goto tdsqlite3ExprCodeIN_finished; + goto sqlite3ExprCodeIN_finished; } /* Ordinary Step 3, for the case where FALSE and NULL are distinct */ - addrTruthOp = tdsqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0, + addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0, rLhs, nVector); VdbeCoverage(v); } @@ -105623,14 +105623,14 @@ static void tdsqlite3ExprCodeIN( ** an match on the search above, then the result must be FALSE. */ if( rRhsHasNull && nVector==1 ){ - tdsqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse); + sqlite3VdbeAddOp2(v, OP_NotNull, rRhsHasNull, destIfFalse); VdbeCoverage(v); } /* Step 5. If we do not care about the difference between NULL and ** FALSE, then just return false. */ - if( destIfFalse==destIfNull ) tdsqlite3VdbeGoto(v, destIfFalse); + if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse); /* Step 6: Loop through rows of the RHS. Compare each row to the LHS. ** If any comparison is NULL, then the result is NULL. If all @@ -105639,11 +105639,11 @@ static void tdsqlite3ExprCodeIN( ** For a scalar LHS, it is sufficient to check just the first row ** of the RHS. */ - if( destStep6 ) tdsqlite3VdbeResolveLabel(v, destStep6); - addrTop = tdsqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse); + if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse); VdbeCoverage(v); if( nVector>1 ){ - destNotNull = tdsqlite3VdbeMakeLabel(pParse); + destNotNull = sqlite3VdbeMakeLabel(pParse); }else{ /* For nVector==1, combine steps 6 and 7 by immediately returning ** FALSE if the first comparison is not NULL */ @@ -105652,35 +105652,35 @@ static void tdsqlite3ExprCodeIN( for(i=0; i1 ){ - tdsqlite3VdbeResolveLabel(v, destNotNull); - tdsqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1); + sqlite3VdbeResolveLabel(v, destNotNull); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1); VdbeCoverage(v); /* Step 7: If we reach this point, we know that the result must ** be false. */ - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); + sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse); } /* Jumps here in order to return true. */ - tdsqlite3VdbeJumpHere(v, addrTruthOp); + sqlite3VdbeJumpHere(v, addrTruthOp); -tdsqlite3ExprCodeIN_finished: - if( rLhs!=rLhsOrig ) tdsqlite3ReleaseTempReg(pParse, rLhs); +sqlite3ExprCodeIN_finished: + if( rLhs!=rLhsOrig ) sqlite3ReleaseTempReg(pParse, rLhs); VdbeComment((v, "end IN expr")); -tdsqlite3ExprCodeIN_oom_error: - tdsqlite3DbFree(pParse->db, aiMap); - tdsqlite3DbFree(pParse->db, zAff); +sqlite3ExprCodeIN_oom_error: + sqlite3DbFree(pParse->db, aiMap); + sqlite3DbFree(pParse->db, zAff); } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -105696,10 +105696,10 @@ tdsqlite3ExprCodeIN_oom_error: static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ if( ALWAYS(z!=0) ){ double value; - tdsqlite3AtoF(z, &value, tdsqlite3Strlen30(z), SQLITE_UTF8); - assert( !tdsqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ + sqlite3AtoF(z, &value, sqlite3Strlen30(z), SQLITE_UTF8); + assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ if( negateFlag ) value = -value; - tdsqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); + sqlite3VdbeAddOp4Dup8(v, OP_Real, 0, iMem, 0, (u8*)&value, P4_REAL); } } #endif @@ -105717,20 +105717,20 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ int i = pExpr->u.iValue; assert( i>=0 ); if( negFlag ) i = -i; - tdsqlite3VdbeAddOp2(v, OP_Integer, i, iMem); + sqlite3VdbeAddOp2(v, OP_Integer, i, iMem); }else{ int c; i64 value; const char *z = pExpr->u.zToken; assert( z!=0 ); - c = tdsqlite3DecOrHexToI64(z, &value); + c = sqlite3DecOrHexToI64(z, &value); if( (c==3 && !negFlag) || (c==2) || (negFlag && value==SMALLEST_INT64)){ #ifdef SQLITE_OMIT_FLOATING_POINT - tdsqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); + sqlite3ErrorMsg(pParse, "oversized integer: %s%s", negFlag ? "-" : "", z); #else #ifndef SQLITE_OMIT_HEX_INTEGER - if( tdsqlite3_strnicmp(z,"0x",2)==0 ){ - tdsqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z); + if( sqlite3_strnicmp(z,"0x",2)==0 ){ + sqlite3ErrorMsg(pParse, "hex literal too big: %s%s", negFlag?"-":"",z); }else #endif { @@ -105739,7 +105739,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ #endif }else{ if( negFlag ){ value = c==3 ? SMALLEST_INT64 : -value; } - tdsqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); + sqlite3VdbeAddOp4Dup8(v, OP_Int64, 0, iMem, 0, (u8*)&value, P4_INT64); } } } @@ -105748,7 +105748,7 @@ static void codeInteger(Parse *pParse, Expr *pExpr, int negFlag, int iMem){ /* Generate code that will load into register regOut a value that is ** appropriate for the iIdxCol-th column of index pIdx. */ -SQLITE_PRIVATE void tdsqlite3ExprCodeLoadIndexColumn( +SQLITE_PRIVATE void sqlite3ExprCodeLoadIndexColumn( Parse *pParse, /* The parsing context */ Index *pIdx, /* The index whose column is to be loaded */ int iTabCur, /* Cursor pointing to a table row */ @@ -105760,10 +105760,10 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeLoadIndexColumn( assert( pIdx->aColExpr ); assert( pIdx->aColExpr->nExpr>iIdxCol ); pParse->iSelfTab = iTabCur + 1; - tdsqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut); + sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut); pParse->iSelfTab = 0; }else{ - tdsqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur, + sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur, iTabCol, regOut); } } @@ -105773,7 +105773,7 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeLoadIndexColumn( ** Generate code that will compute the value of generated column pCol ** and store the result in register regOut */ -SQLITE_PRIVATE void tdsqlite3ExprCodeGeneratedColumn( +SQLITE_PRIVATE void sqlite3ExprCodeGeneratedColumn( Parse *pParse, Column *pCol, int regOut @@ -105783,22 +105783,22 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeGeneratedColumn( assert( v!=0 ); assert( pParse->iSelfTab!=0 ); if( pParse->iSelfTab>0 ){ - iAddr = tdsqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); + iAddr = sqlite3VdbeAddOp3(v, OP_IfNullRow, pParse->iSelfTab-1, 0, regOut); }else{ iAddr = 0; } - tdsqlite3ExprCode(pParse, pCol->pDflt, regOut); + sqlite3ExprCode(pParse, pCol->pDflt, regOut); if( pCol->affinity>=SQLITE_AFF_TEXT ){ - tdsqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); + sqlite3VdbeAddOp4(v, OP_Affinity, regOut, 1, 0, &pCol->affinity, 1); } - if( iAddr ) tdsqlite3VdbeJumpHere(v, iAddr); + if( iAddr ) sqlite3VdbeJumpHere(v, iAddr); } #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ /* ** Generate code to extract the value of the iCol-th column of a table. */ -SQLITE_PRIVATE void tdsqlite3ExprCodeGetColumnOfTable( +SQLITE_PRIVATE void sqlite3ExprCodeGetColumnOfTable( Vdbe *v, /* Parsing context */ Table *pTab, /* The table containing the value */ int iTabCur, /* The table cursor. Or the PK cursor for WITHOUT ROWID */ @@ -105808,11 +105808,11 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeGetColumnOfTable( Column *pCol; assert( v!=0 ); if( pTab==0 ){ - tdsqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); + sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); return; } if( iCol<0 || iCol==pTab->iPKey ){ - tdsqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); + sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); }else{ int op; int x; @@ -105821,30 +105821,30 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeGetColumnOfTable( x = iCol; #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( (pCol = &pTab->aCol[iCol])->colFlags & COLFLAG_VIRTUAL ){ - Parse *pParse = tdsqlite3VdbeParser(v); + Parse *pParse = sqlite3VdbeParser(v); if( pCol->colFlags & COLFLAG_BUSY ){ - tdsqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName); + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName); }else{ int savedSelfTab = pParse->iSelfTab; pCol->colFlags |= COLFLAG_BUSY; pParse->iSelfTab = iTabCur+1; - tdsqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut); + sqlite3ExprCodeGeneratedColumn(pParse, pCol, regOut); pParse->iSelfTab = savedSelfTab; pCol->colFlags &= ~COLFLAG_BUSY; } return; #endif }else if( !HasRowid(pTab) ){ - testcase( iCol!=tdsqlite3TableColumnToStorage(pTab, iCol) ); - x = tdsqlite3TableColumnToIndex(tdsqlite3PrimaryKeyIndex(pTab), iCol); + testcase( iCol!=sqlite3TableColumnToStorage(pTab, iCol) ); + x = sqlite3TableColumnToIndex(sqlite3PrimaryKeyIndex(pTab), iCol); op = OP_Column; }else{ - x = tdsqlite3TableColumnToStorage(pTab,iCol); + x = sqlite3TableColumnToStorage(pTab,iCol); testcase( x!=iCol ); op = OP_Column; } - tdsqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); - tdsqlite3ColumnDefault(v, pTab, iCol, regOut); + sqlite3VdbeAddOp3(v, op, iTabCur, x, regOut); + sqlite3ColumnDefault(v, pTab, iCol, regOut); } } @@ -105855,7 +105855,7 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeGetColumnOfTable( ** There must be an open cursor to pTab in iTable when this routine ** is called. If iColumn<0 then code is generated that extracts the rowid. */ -SQLITE_PRIVATE int tdsqlite3ExprCodeGetColumn( +SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( Parse *pParse, /* Parsing and code generating context */ Table *pTab, /* Description of the table we are reading from */ int iColumn, /* Index of the table column */ @@ -105864,9 +105864,9 @@ SQLITE_PRIVATE int tdsqlite3ExprCodeGetColumn( u8 p5 /* P5 value for OP_Column + FLAGS */ ){ assert( pParse->pVdbe!=0 ); - tdsqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); + sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); if( p5 ){ - VdbeOp *pOp = tdsqlite3VdbeGetOp(pParse->pVdbe,-1); + VdbeOp *pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1); if( pOp->opcode==OP_Column ) pOp->p5 = p5; } return iReg; @@ -105876,8 +105876,8 @@ SQLITE_PRIVATE int tdsqlite3ExprCodeGetColumn( ** Generate code to move content from registers iFrom...iFrom+nReg-1 ** over to iTo..iTo+nReg-1. */ -SQLITE_PRIVATE void tdsqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ - tdsqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); +SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ + sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg); } /* @@ -105886,7 +105886,7 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int ** the correct value for the expression. */ static void exprToRegister(Expr *pExpr, int iReg){ - Expr *p = tdsqlite3ExprSkipCollateAndLikely(pExpr); + Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); p->op2 = p->op; p->op = TK_REGISTER; p->iTable = iReg; @@ -105905,23 +105905,23 @@ static void exprToRegister(Expr *pExpr, int iReg){ */ static int exprCodeVector(Parse *pParse, Expr *p, int *piFreeable){ int iResult; - int nResult = tdsqlite3ExprVectorSize(p); + int nResult = sqlite3ExprVectorSize(p); if( nResult==1 ){ - iResult = tdsqlite3ExprCodeTemp(pParse, p, piFreeable); + iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable); }else{ *piFreeable = 0; if( p->op==TK_SELECT ){ #if SQLITE_OMIT_SUBQUERY iResult = 0; #else - iResult = tdsqlite3CodeSubselect(pParse, p); + iResult = sqlite3CodeSubselect(pParse, p); #endif }else{ int i; iResult = pParse->nMem+1; pParse->nMem += nResult; for(i=0; ix.pList->a[i].pExpr, i+iResult); + sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult); } } } @@ -105950,19 +105950,19 @@ static int exprCodeInlineFunction( ** IFNULL() functions. This avoids unnecessary evaluation of ** arguments past the first non-NULL argument. */ - int endCoalesce = tdsqlite3VdbeMakeLabel(pParse); + int endCoalesce = sqlite3VdbeMakeLabel(pParse); int i; assert( nFarg>=2 ); - tdsqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); + sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target); for(i=1; ia[i].pExpr, target); + sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target); } - if( tdsqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){ - tdsqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */ + if( sqlite3VdbeGetOp(v, -1)->opcode==OP_Copy ){ + sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */ } - tdsqlite3VdbeResolveLabel(v, endCoalesce); + sqlite3VdbeResolveLabel(v, endCoalesce); break; } @@ -105971,7 +105971,7 @@ static int exprCodeInlineFunction( ** of the first argument. */ assert( nFarg==1 || nFarg==2 ); - target = tdsqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); + target = sqlite3ExprCodeTarget(pParse, pFarg->a[0].pExpr, target); break; } @@ -105980,34 +105980,34 @@ static int exprCodeInlineFunction( ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS */ case INLINEFUNC_expr_compare: { - /* Compare two expressions using tdsqlite3ExprCompare() */ + /* Compare two expressions using sqlite3ExprCompare() */ assert( nFarg==2 ); - tdsqlite3VdbeAddOp2(v, OP_Integer, - tdsqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), target); break; } case INLINEFUNC_expr_implies_expr: { - /* Compare two expressions using tdsqlite3ExprImpliesExpr() */ + /* Compare two expressions using sqlite3ExprImpliesExpr() */ assert( nFarg==2 ); - tdsqlite3VdbeAddOp2(v, OP_Integer, - tdsqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), target); break; } case INLINEFUNC_implies_nonnull_row: { - /* REsult of tdsqlite3ExprImpliesNonNullRow() */ + /* REsult of sqlite3ExprImpliesNonNullRow() */ Expr *pA1; assert( nFarg==2 ); pA1 = pFarg->a[1].pExpr; if( pA1->op==TK_COLUMN ){ - tdsqlite3VdbeAddOp2(v, OP_Integer, - tdsqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable), + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable), target); }else{ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); } break; } @@ -106021,8 +106021,8 @@ static int exprCodeInlineFunction( const char *azAff[] = { "blob", "text", "numeric", "integer", "real" }; char aff; assert( nFarg==1 ); - aff = tdsqlite3ExprAffinity(pFarg->a[0].pExpr); - tdsqlite3VdbeLoadString(v, target, + aff = sqlite3ExprAffinity(pFarg->a[0].pExpr); + sqlite3VdbeLoadString(v, target, (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]); break; } @@ -106043,7 +106043,7 @@ static int exprCodeInlineFunction( ** must check the return code and move the results to the desired ** register. */ -SQLITE_PRIVATE int tdsqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ +SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){ Vdbe *v = pParse->pVdbe; /* The VM under construction */ int op; /* The opcode being coded */ int inReg = target; /* Results stored in register inReg */ @@ -106073,7 +106073,7 @@ expr_code_doover: assert( pCol->iMem>0 ); return pCol->iMem; }else if( pAggInfo->useSortingIdx ){ - tdsqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, + sqlite3VdbeAddOp3(v, OP_Column, pAggInfo->sortingIdxPTab, pCol->iSorterColumn, target); return target; } @@ -106090,9 +106090,9 @@ expr_code_doover: ** constant. */ int aff; - iReg = tdsqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); + iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); if( pExpr->y.pTab ){ - aff = tdsqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); + aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); }else{ aff = pExpr->affExpr; } @@ -106101,10 +106101,10 @@ expr_code_doover: assert( SQLITE_AFF_BLOB=='A' ); assert( SQLITE_AFF_TEXT=='B' ); if( iReg!=target ){ - tdsqlite3VdbeAddOp2(v, OP_SCopy, iReg, target); + sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target); iReg = target; } - tdsqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0, &zAff[(aff-'B')*2], P4_STATIC); } return iReg; @@ -106128,26 +106128,26 @@ expr_code_doover: return -1-pParse->iSelfTab; } pCol = pTab->aCol + iCol; - testcase( iCol!=tdsqlite3TableColumnToStorage(pTab,iCol) ); - iSrc = tdsqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab; + testcase( iCol!=sqlite3TableColumnToStorage(pTab,iCol) ); + iSrc = sqlite3TableColumnToStorage(pTab, iCol) - pParse->iSelfTab; #ifndef SQLITE_OMIT_GENERATED_COLUMNS if( pCol->colFlags & COLFLAG_GENERATED ){ if( pCol->colFlags & COLFLAG_BUSY ){ - tdsqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pCol->zName); return 0; } pCol->colFlags |= COLFLAG_BUSY; if( pCol->colFlags & COLFLAG_NOTAVAIL ){ - tdsqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc); + sqlite3ExprCodeGeneratedColumn(pParse, pCol, iSrc); } pCol->colFlags &= ~(COLFLAG_BUSY|COLFLAG_NOTAVAIL); return iSrc; }else #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ if( pCol->affinity==SQLITE_AFF_REAL ){ - tdsqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target); - tdsqlite3VdbeAddOp1(v, OP_RealAffinity, target); + sqlite3VdbeAddOp2(v, OP_SCopy, iSrc, target); + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); return target; }else{ return iSrc; @@ -106158,11 +106158,11 @@ expr_code_doover: iTab = pParse->iSelfTab - 1; } } - iReg = tdsqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, + iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, pExpr->iColumn, iTab, target, pExpr->op2); if( pExpr->y.pTab==0 && pExpr->affExpr==SQLITE_AFF_REAL ){ - tdsqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } return iReg; } @@ -106171,7 +106171,7 @@ expr_code_doover: return target; } case TK_TRUEFALSE: { - tdsqlite3VdbeAddOp2(v, OP_Integer, tdsqlite3ExprTruthValue(pExpr), target); + sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprTruthValue(pExpr), target); return target; } #ifndef SQLITE_OMIT_FLOATING_POINT @@ -106183,7 +106183,7 @@ expr_code_doover: #endif case TK_STRING: { assert( !ExprHasProperty(pExpr, EP_IntValue) ); - tdsqlite3VdbeLoadString(v, target, pExpr->u.zToken); + sqlite3VdbeLoadString(v, target, pExpr->u.zToken); return target; } default: { @@ -106192,7 +106192,7 @@ expr_code_doover: ** sanely and not crash. But keep the assert() to bring the problem ** to the attention of the developers. */ assert( op==TK_NULL ); - tdsqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); return target; } #ifndef SQLITE_OMIT_BLOB_LITERAL @@ -106204,10 +106204,10 @@ expr_code_doover: assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); assert( pExpr->u.zToken[1]=='\'' ); z = &pExpr->u.zToken[2]; - n = tdsqlite3Strlen30(z) - 1; + n = sqlite3Strlen30(z) - 1; assert( z[n]=='\'' ); - zBlob = tdsqlite3HexToBlob(tdsqlite3VdbeDb(v), z, n); - tdsqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); + zBlob = sqlite3HexToBlob(sqlite3VdbeDb(v), z, n); + sqlite3VdbeAddOp4(v, OP_Blob, n/2, target, 0, zBlob, P4_DYNAMIC); return target; } #endif @@ -106215,12 +106215,12 @@ expr_code_doover: assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( pExpr->u.zToken!=0 ); assert( pExpr->u.zToken[0]!=0 ); - tdsqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); + sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); if( pExpr->u.zToken[1]!=0 ){ - const char *z = tdsqlite3VListNumToName(pParse->pVList, pExpr->iColumn); + const char *z = sqlite3VListNumToName(pParse->pVList, pExpr->iColumn); assert( pExpr->u.zToken[0]=='?' || (z && !strcmp(pExpr->u.zToken, z)) ); pParse->pVList[0] = 0; /* Indicate VList may no longer be enlarged */ - tdsqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); + sqlite3VdbeAppendP4(v, (char*)z, P4_STATIC); } return target; } @@ -106230,13 +106230,13 @@ expr_code_doover: #ifndef SQLITE_OMIT_CAST case TK_CAST: { /* Expressions of the form: CAST(pLeft AS token) */ - inReg = tdsqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); if( inReg!=target ){ - tdsqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); + sqlite3VdbeAddOp2(v, OP_SCopy, inReg, target); inReg = target; } - tdsqlite3VdbeAddOp2(v, OP_Cast, target, - tdsqlite3AffinityType(pExpr->u.zToken, 0)); + sqlite3VdbeAddOp2(v, OP_Cast, target, + sqlite3AffinityType(pExpr->u.zToken, 0)); return inReg; } #endif /* SQLITE_OMIT_CAST */ @@ -106252,11 +106252,11 @@ expr_code_doover: case TK_NE: case TK_EQ: { Expr *pLeft = pExpr->pLeft; - if( tdsqlite3ExprIsVector(pLeft) ){ + if( sqlite3ExprIsVector(pLeft) ){ codeVectorCompare(pParse, pExpr, target, op, p5); }else{ - r1 = tdsqlite3ExprCodeTemp(pParse, pLeft, ®Free1); - r2 = tdsqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + r1 = sqlite3ExprCodeTemp(pParse, pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pLeft, pExpr->pRight, op, r1, r2, inReg, SQLITE_STOREP2 | p5, ExprHasProperty(pExpr,EP_Commuted)); @@ -106294,9 +106294,9 @@ expr_code_doover: assert( TK_LSHIFT==OP_ShiftLeft ); testcase( op==TK_LSHIFT ); assert( TK_RSHIFT==OP_ShiftRight ); testcase( op==TK_RSHIFT ); assert( TK_CONCAT==OP_Concat ); testcase( op==TK_CONCAT ); - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = tdsqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); - tdsqlite3VdbeAddOp3(v, op, r2, r1, target); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + sqlite3VdbeAddOp3(v, op, r2, r1, target); testcase( regFree1==0 ); testcase( regFree2==0 ); break; @@ -106317,9 +106317,9 @@ expr_code_doover: tempX.op = TK_INTEGER; tempX.flags = EP_IntValue|EP_TokenOnly; tempX.u.iValue = 0; - r1 = tdsqlite3ExprCodeTemp(pParse, &tempX, ®Free1); - r2 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); - tdsqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); + r1 = sqlite3ExprCodeTemp(pParse, &tempX, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free2); + sqlite3VdbeAddOp3(v, OP_Subtract, r2, r1, target); testcase( regFree2==0 ); } break; @@ -106328,21 +106328,21 @@ expr_code_doover: case TK_NOT: { assert( TK_BITNOT==OP_BitNot ); testcase( op==TK_BITNOT ); assert( TK_NOT==OP_Not ); testcase( op==TK_NOT ); - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); - tdsqlite3VdbeAddOp2(v, op, r1, inReg); + sqlite3VdbeAddOp2(v, op, r1, inReg); break; } case TK_TRUTH: { int isTrue; /* IS TRUE or IS NOT TRUE */ int bNormal; /* IS TRUE or IS FALSE */ - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); - isTrue = tdsqlite3ExprTruthValue(pExpr->pRight); + isTrue = sqlite3ExprTruthValue(pExpr->pRight); bNormal = pExpr->op2==TK_IS; testcase( isTrue && bNormal); testcase( !isTrue && bNormal); - tdsqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal); + sqlite3VdbeAddOp4Int(v, OP_IsTrue, r1, inReg, !isTrue, isTrue ^ bNormal); break; } case TK_ISNULL: @@ -106350,21 +106350,21 @@ expr_code_doover: int addr; assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, target); - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); testcase( regFree1==0 ); - addr = tdsqlite3VdbeAddOp1(v, op, r1); + addr = sqlite3VdbeAddOp1(v, op, r1); VdbeCoverageIf(v, op==TK_ISNULL); VdbeCoverageIf(v, op==TK_NOTNULL); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, target); - tdsqlite3VdbeJumpHere(v, addr); + sqlite3VdbeAddOp2(v, OP_Integer, 0, target); + sqlite3VdbeJumpHere(v, addr); break; } case TK_AGG_FUNCTION: { AggInfo *pInfo = pExpr->pAggInfo; if( pInfo==0 ){ assert( !ExprHasProperty(pExpr, EP_IntValue) ); - tdsqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); + sqlite3ErrorMsg(pParse, "misuse of aggregate: %s()", pExpr->u.zToken); }else{ return pInfo->aFunc[pExpr->iAgg].iMem; } @@ -106377,7 +106377,7 @@ expr_code_doover: const char *zId; /* The function name */ u32 constMask = 0; /* Mask of function arguments that are constant */ int i; /* Loop counter */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ u8 enc = ENC(db); /* The text encoding used by this database */ CollSeq *pColl = 0; /* A collating sequence */ @@ -106387,10 +106387,10 @@ expr_code_doover: } #endif - if( ConstFactorOk(pParse) && tdsqlite3ExprIsConstantNotJoin(pExpr) ){ + if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){ /* SQL functions can be expensive. So try to move constant functions ** out of the inner loop, even if that means an extra OP_Copy. */ - return tdsqlite3ExprCodeAtInit(pParse, pExpr, -1); + return sqlite3ExprCodeAtInit(pParse, pExpr, -1); } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( ExprHasProperty(pExpr, EP_TokenOnly) ){ @@ -106401,14 +106401,14 @@ expr_code_doover: nFarg = pFarg ? pFarg->nExpr : 0; assert( !ExprHasProperty(pExpr, EP_IntValue) ); zId = pExpr->u.zToken; - pDef = tdsqlite3FindFunction(db, zId, nFarg, enc, 0); + pDef = sqlite3FindFunction(db, zId, nFarg, enc, 0); #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION if( pDef==0 && pParse->explain ){ - pDef = tdsqlite3FindFunction(db, "unknown", nFarg, enc, 0); + pDef = sqlite3FindFunction(db, "unknown", nFarg, enc, 0); } #endif if( pDef==0 || pDef->xFinalize!=0 ){ - tdsqlite3ErrorMsg(pParse, "unknown function: %s()", zId); + sqlite3ErrorMsg(pParse, "unknown function: %s()", zId); break; } if( pDef->funcFlags & SQLITE_FUNC_INLINE ){ @@ -106417,16 +106417,16 @@ expr_code_doover: return exprCodeInlineFunction(pParse, pFarg, SQLITE_PTR_TO_INT(pDef->pUserData), target); }else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){ - tdsqlite3ExprFunctionUsable(pParse, pExpr, pDef); + sqlite3ExprFunctionUsable(pParse, pExpr, pDef); } for(i=0; ia[i].pExpr) ){ + if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){ testcase( i==31 ); constMask |= MASKBIT32(i); } if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){ - pColl = tdsqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); + pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr); } } if( pFarg ){ @@ -106434,7 +106434,7 @@ expr_code_doover: r1 = pParse->nMem+1; pParse->nMem += nFarg; }else{ - r1 = tdsqlite3GetTempRange(pParse, nFarg); + r1 = sqlite3GetTempRange(pParse, nFarg); } /* For length() and typeof() functions with a column argument, @@ -106456,7 +106456,7 @@ expr_code_doover: } } - tdsqlite3ExprCodeExprList(pParse, pFarg, r1, 0, + sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); }else{ r1 = 0; @@ -106475,34 +106475,34 @@ expr_code_doover: ** for function overloading. But we use the B term in "glob(B,A)". */ if( nFarg>=2 && ExprHasProperty(pExpr, EP_InfixFunc) ){ - pDef = tdsqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[1].pExpr); }else if( nFarg>0 ){ - pDef = tdsqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); + pDef = sqlite3VtabOverloadFunction(db, pDef, nFarg, pFarg->a[0].pExpr); } #endif if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ if( !pColl ) pColl = db->pDfltColl; - tdsqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); + sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); } #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC if( pDef->funcFlags & SQLITE_FUNC_OFFSET ){ Expr *pArg = pFarg->a[0].pExpr; if( pArg->op==TK_COLUMN ){ - tdsqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); + sqlite3VdbeAddOp3(v, OP_Offset, pArg->iTable, pArg->iColumn, target); }else{ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); } }else #endif { - tdsqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, + sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, pDef, pExpr->op2); } if( nFarg ){ if( constMask==0 ){ - tdsqlite3ReleaseTempRange(pParse, r1, nFarg); + sqlite3ReleaseTempRange(pParse, r1, nFarg); }else{ - tdsqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1); + sqlite3VdbeReleaseRegisters(pParse, r1, nFarg, constMask, 1); } } return target; @@ -106514,35 +106514,35 @@ expr_code_doover: testcase( op==TK_EXISTS ); testcase( op==TK_SELECT ); if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){ - tdsqlite3SubselectError(pParse, nCol, 1); + sqlite3SubselectError(pParse, nCol, 1); }else{ - return tdsqlite3CodeSubselect(pParse, pExpr); + return sqlite3CodeSubselect(pParse, pExpr); } break; } case TK_SELECT_COLUMN: { int n; if( pExpr->pLeft->iTable==0 ){ - pExpr->pLeft->iTable = tdsqlite3CodeSubselect(pParse, pExpr->pLeft); + pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); } assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT ); if( pExpr->iTable!=0 - && pExpr->iTable!=(n = tdsqlite3ExprVectorSize(pExpr->pLeft)) + && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) ){ - tdsqlite3ErrorMsg(pParse, "%d columns assigned %d values", + sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pExpr->iTable, n); } return pExpr->pLeft->iTable + pExpr->iColumn; } case TK_IN: { - int destIfFalse = tdsqlite3VdbeMakeLabel(pParse); - int destIfNull = tdsqlite3VdbeMakeLabel(pParse); - tdsqlite3VdbeAddOp2(v, OP_Null, 0, target); - tdsqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, target); - tdsqlite3VdbeResolveLabel(v, destIfFalse); - tdsqlite3VdbeAddOp2(v, OP_AddImm, target, 0); - tdsqlite3VdbeResolveLabel(v, destIfNull); + int destIfFalse = sqlite3VdbeMakeLabel(pParse); + int destIfNull = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeAddOp2(v, OP_Integer, 1, target); + sqlite3VdbeResolveLabel(v, destIfFalse); + sqlite3VdbeAddOp2(v, OP_AddImm, target, 0); + sqlite3VdbeResolveLabel(v, destIfNull); return target; } #endif /* SQLITE_OMIT_SUBQUERY */ @@ -106599,14 +106599,14 @@ expr_code_doover: Table *pTab = pExpr->y.pTab; int iCol = pExpr->iColumn; int p1 = pExpr->iTable * (pTab->nCol+1) + 1 - + tdsqlite3TableColumnToStorage(pTab, iCol); + + sqlite3TableColumnToStorage(pTab, iCol); assert( pExpr->iTable==0 || pExpr->iTable==1 ); assert( iCol>=-1 && iColnCol ); assert( pTab->iPKey<0 || iCol!=pTab->iPKey ); assert( p1>=0 && p1<(pTab->nCol*2+2) ); - tdsqlite3VdbeAddOp2(v, OP_Param, p1, target); + sqlite3VdbeAddOp2(v, OP_Param, p1, target); VdbeComment((v, "r[%d]=%s.%s", target, (pExpr->iTable ? "new" : "old"), (pExpr->iColumn<0 ? "rowid" : pExpr->y.pTab->aCol[iCol].zName) @@ -106619,14 +106619,14 @@ expr_code_doover: ** EVIDENCE-OF: R-60985-57662 SQLite will convert the value back to ** floating point when extracting it from the record. */ if( iCol>=0 && pTab->aCol[iCol].affinity==SQLITE_AFF_REAL ){ - tdsqlite3VdbeAddOp1(v, OP_RealAffinity, target); + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); } #endif break; } case TK_VECTOR: { - tdsqlite3ErrorMsg(pParse, "row value misused"); + sqlite3ErrorMsg(pParse, "row value misused"); break; } @@ -106639,16 +106639,16 @@ expr_code_doover: case TK_IF_NULL_ROW: { int addrINR; u8 okConstFactor = pParse->okConstFactor; - addrINR = tdsqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); + addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); /* Temporarily disable factoring of constant expressions, since ** even though expressions may appear to be constant, they are not ** really constant because they originate from the right-hand side ** of a LEFT JOIN. */ pParse->okConstFactor = 0; - inReg = tdsqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); pParse->okConstFactor = okConstFactor; - tdsqlite3VdbeJumpHere(v, addrINR); - tdsqlite3VdbeChangeP3(v, addrINR, inReg); + sqlite3VdbeJumpHere(v, addrINR); + sqlite3VdbeChangeP3(v, addrINR, inReg); break; } @@ -106684,18 +106684,18 @@ expr_code_doover: Expr *pX; /* The X expression */ Expr *pTest = 0; /* X==Ei (form A) or just Ei (form B) */ Expr *pDel = 0; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList ); assert(pExpr->x.pList->nExpr > 0); pEList = pExpr->x.pList; aListelem = pEList->a; nExpr = pEList->nExpr; - endLabel = tdsqlite3VdbeMakeLabel(pParse); + endLabel = sqlite3VdbeMakeLabel(pParse); if( (pX = pExpr->pLeft)!=0 ){ - pDel = tdsqlite3ExprDup(db, pX, 0); + pDel = sqlite3ExprDup(db, pX, 0); if( db->mallocFailed ){ - tdsqlite3ExprDelete(db, pDel); + sqlite3ExprDelete(db, pDel); break; } testcase( pX->op==TK_COLUMN ); @@ -106718,21 +106718,21 @@ expr_code_doover: }else{ pTest = aListelem[i].pExpr; } - nextCase = tdsqlite3VdbeMakeLabel(pParse); + nextCase = sqlite3VdbeMakeLabel(pParse); testcase( pTest->op==TK_COLUMN ); - tdsqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL); testcase( aListelem[i+1].pExpr->op==TK_COLUMN ); - tdsqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); - tdsqlite3VdbeGoto(v, endLabel); - tdsqlite3VdbeResolveLabel(v, nextCase); + sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target); + sqlite3VdbeGoto(v, endLabel); + sqlite3VdbeResolveLabel(v, nextCase); } if( (nExpr&1)!=0 ){ - tdsqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); + sqlite3ExprCode(pParse, pEList->a[nExpr-1].pExpr, target); }else{ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, target); + sqlite3VdbeAddOp2(v, OP_Null, 0, target); } - tdsqlite3ExprDelete(db, pDel); - tdsqlite3VdbeResolveLabel(v, endLabel); + sqlite3ExprDelete(db, pDel); + sqlite3VdbeResolveLabel(v, endLabel); break; } #ifndef SQLITE_OMIT_TRIGGER @@ -106743,20 +106743,20 @@ expr_code_doover: || pExpr->affExpr==OE_Ignore ); if( !pParse->pTriggerTab ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "RAISE() may only be used within a trigger-program"); return 0; } if( pExpr->affExpr==OE_Abort ){ - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); } assert( !ExprHasProperty(pExpr, EP_IntValue) ); if( pExpr->affExpr==OE_Ignore ){ - tdsqlite3VdbeAddOp4( + sqlite3VdbeAddOp4( v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); VdbeCoverage(v); }else{ - tdsqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER, + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_TRIGGER, pExpr->affExpr, pExpr->u.zToken, 0, 0); } @@ -106764,8 +106764,8 @@ expr_code_doover: } #endif } - tdsqlite3ReleaseTempReg(pParse, regFree1); - tdsqlite3ReleaseTempReg(pParse, regFree2); + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); return inReg; } @@ -106778,7 +106778,7 @@ expr_code_doover: ** is stored is returned. When regDest<0, two identical expressions will ** code to the same register. */ -SQLITE_PRIVATE int tdsqlite3ExprCodeAtInit( +SQLITE_PRIVATE int sqlite3ExprCodeAtInit( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The expression to code when the VDBE initializes */ int regDest /* Store the value in this register */ @@ -106790,13 +106790,13 @@ SQLITE_PRIVATE int tdsqlite3ExprCodeAtInit( struct ExprList_item *pItem; int i; for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){ - if( pItem->reusable && tdsqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){ + if( pItem->reusable && sqlite3ExprCompare(0,pItem->pExpr,pExpr,-1)==0 ){ return pItem->u.iConstExprReg; } } } - pExpr = tdsqlite3ExprDup(pParse->db, pExpr, 0); - p = tdsqlite3ExprListAppend(pParse, p, pExpr); + pExpr = sqlite3ExprDup(pParse->db, pExpr, 0); + p = sqlite3ExprListAppend(pParse, p, pExpr); if( p ){ struct ExprList_item *pItem = &p->a[p->nExpr-1]; pItem->reusable = regDest<0; @@ -106820,22 +106820,22 @@ SQLITE_PRIVATE int tdsqlite3ExprCodeAtInit( ** code to fill the register in the initialization section of the ** VDBE program, in order to factor it out of the evaluation loop. */ -SQLITE_PRIVATE int tdsqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ +SQLITE_PRIVATE int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; - pExpr = tdsqlite3ExprSkipCollateAndLikely(pExpr); + pExpr = sqlite3ExprSkipCollateAndLikely(pExpr); if( ConstFactorOk(pParse) && pExpr->op!=TK_REGISTER - && tdsqlite3ExprIsConstantNotJoin(pExpr) + && sqlite3ExprIsConstantNotJoin(pExpr) ){ *pReg = 0; - r2 = tdsqlite3ExprCodeAtInit(pParse, pExpr, -1); + r2 = sqlite3ExprCodeAtInit(pParse, pExpr, -1); }else{ - int r1 = tdsqlite3GetTempReg(pParse); - r2 = tdsqlite3ExprCodeTarget(pParse, pExpr, r1); + int r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); if( r2==r1 ){ *pReg = r1; }else{ - tdsqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r1); *pReg = 0; } } @@ -106847,11 +106847,11 @@ SQLITE_PRIVATE int tdsqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ ** results in register target. The results are guaranteed to appear ** in register target. */ -SQLITE_PRIVATE void tdsqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ +SQLITE_PRIVATE void sqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ int inReg; assert( target>0 && target<=pParse->nMem ); - inReg = tdsqlite3ExprCodeTarget(pParse, pExpr, target); + inReg = sqlite3ExprCodeTarget(pParse, pExpr, target); assert( pParse->pVdbe!=0 || pParse->db->mallocFailed ); if( inReg!=target && pParse->pVdbe ){ u8 op; @@ -106860,20 +106860,20 @@ SQLITE_PRIVATE void tdsqlite3ExprCode(Parse *pParse, Expr *pExpr, int target){ }else{ op = OP_SCopy; } - tdsqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target); + sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target); } } /* ** Make a transient copy of expression pExpr and then code it using -** tdsqlite3ExprCode(). This routine works just like tdsqlite3ExprCode() +** sqlite3ExprCode(). This routine works just like sqlite3ExprCode() ** except that the input expression is guaranteed to be unchanged. */ -SQLITE_PRIVATE void tdsqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ - tdsqlite3 *db = pParse->db; - pExpr = tdsqlite3ExprDup(db, pExpr, 0); - if( !db->mallocFailed ) tdsqlite3ExprCode(pParse, pExpr, target); - tdsqlite3ExprDelete(db, pExpr); +SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target){ + sqlite3 *db = pParse->db; + pExpr = sqlite3ExprDup(db, pExpr, 0); + if( !db->mallocFailed ) sqlite3ExprCode(pParse, pExpr, target); + sqlite3ExprDelete(db, pExpr); } /* @@ -106882,11 +106882,11 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeCopy(Parse *pParse, Expr *pExpr, int target ** in register target. If the expression is constant, then this routine ** might choose to code the expression at initialization time. */ -SQLITE_PRIVATE void tdsqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ - if( pParse->okConstFactor && tdsqlite3ExprIsConstantNotJoin(pExpr) ){ - tdsqlite3ExprCodeAtInit(pParse, pExpr, target); +SQLITE_PRIVATE void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){ + if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){ + sqlite3ExprCodeAtInit(pParse, pExpr, target); }else{ - tdsqlite3ExprCode(pParse, pExpr, target); + sqlite3ExprCode(pParse, pExpr, target); } } @@ -106910,7 +106910,7 @@ SQLITE_PRIVATE void tdsqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int ** If SQLITE_ECEL_OMITREF is also set, then the values with u.x.iOrderByCol>0 ** are simply omitted rather than being copied from srcReg. */ -SQLITE_PRIVATE int tdsqlite3ExprCodeExprList( +SQLITE_PRIVATE int sqlite3ExprCodeExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* The expression list to be coded */ int target, /* Where to write results */ @@ -106939,25 +106939,25 @@ SQLITE_PRIVATE int tdsqlite3ExprCodeExprList( i--; n--; }else{ - tdsqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); + sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i); } }else if( (flags & SQLITE_ECEL_FACTOR)!=0 - && tdsqlite3ExprIsConstantNotJoin(pExpr) + && sqlite3ExprIsConstantNotJoin(pExpr) ){ - tdsqlite3ExprCodeAtInit(pParse, pExpr, target+i); + sqlite3ExprCodeAtInit(pParse, pExpr, target+i); }else{ - int inReg = tdsqlite3ExprCodeTarget(pParse, pExpr, target+i); + int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i); if( inReg!=target+i ){ VdbeOp *pOp; if( copyOp==OP_Copy - && (pOp=tdsqlite3VdbeGetOp(v, -1))->opcode==OP_Copy + && (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy && pOp->p1+pOp->p3+1==inReg && pOp->p2+pOp->p3+1==target+i && pOp->p5==0 /* The do-not-merge flag must be clear */ ){ pOp->p3++; }else{ - tdsqlite3VdbeAddOp2(v, copyOp, inReg, target+i); + sqlite3VdbeAddOp2(v, copyOp, inReg, target+i); } } } @@ -106980,8 +106980,8 @@ SQLITE_PRIVATE int tdsqlite3ExprCodeExprList( ** The xJumpIf parameter determines details: ** ** NULL: Store the boolean result in reg[dest] -** tdsqlite3ExprIfTrue: Jump to dest if true -** tdsqlite3ExprIfFalse: Jump to dest if false +** sqlite3ExprIfTrue: Jump to dest if true +** sqlite3ExprIfFalse: Jump to dest if false ** ** The jumpIfNull parameter is ignored if xJumpIf is NULL. */ @@ -106997,14 +106997,14 @@ static void exprCodeBetween( Expr compRight; /* The x<=z term */ int regFree1 = 0; /* Temporary use register */ Expr *pDel = 0; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; memset(&compLeft, 0, sizeof(Expr)); memset(&compRight, 0, sizeof(Expr)); memset(&exprAnd, 0, sizeof(Expr)); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); - pDel = tdsqlite3ExprDup(db, pExpr->pLeft, 0); + pDel = sqlite3ExprDup(db, pExpr->pLeft, 0); if( db->mallocFailed==0 ){ exprAnd.op = TK_AND; exprAnd.pLeft = &compLeft; @@ -107020,26 +107020,26 @@ static void exprCodeBetween( xJump(pParse, &exprAnd, dest, jumpIfNull); }else{ /* Mark the expression is being from the ON or USING clause of a join - ** so that the tdsqlite3ExprCodeTarget() routine will not attempt to move + ** so that the sqlite3ExprCodeTarget() routine will not attempt to move ** it into the Parse.pConstExpr list. We should use a new bit for this, ** for clarity, but we are out of bits in the Expr.flags field so we ** have to reuse the EP_FromJoin bit. Bummer. */ pDel->flags |= EP_FromJoin; - tdsqlite3ExprCodeTarget(pParse, &exprAnd, dest); + sqlite3ExprCodeTarget(pParse, &exprAnd, dest); } - tdsqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree1); } - tdsqlite3ExprDelete(db, pDel); + sqlite3ExprDelete(db, pDel); /* Ensure adequate test coverage */ - testcase( xJump==tdsqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 ); - testcase( xJump==tdsqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 ); - testcase( xJump==tdsqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 ); - testcase( xJump==tdsqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 ); - testcase( xJump==tdsqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 ); - testcase( xJump==tdsqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 ); - testcase( xJump==tdsqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 ); - testcase( xJump==tdsqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull==0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfTrue && jumpIfNull!=0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull==0 && regFree1!=0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1==0 ); + testcase( xJump==sqlite3ExprIfFalse && jumpIfNull!=0 && regFree1!=0 ); testcase( xJump==0 ); } @@ -107057,7 +107057,7 @@ static void exprCodeBetween( ** the make process cause these values to align. Assert()s in the code ** below verify that the numbers are aligned correctly. */ -SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ +SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ Vdbe *v = pParse->pVdbe; int op = 0; int regFree1 = 0; @@ -107071,26 +107071,26 @@ SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, in switch( op ){ case TK_AND: case TK_OR: { - Expr *pAlt = tdsqlite3ExprSimplifiedAndOr(pExpr); + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); if( pAlt!=pExpr ){ - tdsqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pAlt, dest, jumpIfNull); }else if( op==TK_AND ){ - int d2 = tdsqlite3VdbeMakeLabel(pParse); + int d2 = sqlite3VdbeMakeLabel(pParse); testcase( jumpIfNull==0 ); - tdsqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, + sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); - tdsqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); - tdsqlite3VdbeResolveLabel(v, d2); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); }else{ testcase( jumpIfNull==0 ); - tdsqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); - tdsqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull); } break; } case TK_NOT: { testcase( jumpIfNull==0 ); - tdsqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); break; } case TK_TRUTH: { @@ -107098,14 +107098,14 @@ SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, in int isTrue; /* IS TRUE or IS NOT TRUE */ testcase( jumpIfNull==0 ); isNot = pExpr->op2==TK_ISNOT; - isTrue = tdsqlite3ExprTruthValue(pExpr->pRight); + isTrue = sqlite3ExprTruthValue(pExpr->pRight); testcase( isTrue && isNot ); testcase( !isTrue && isNot ); if( isTrue ^ isNot ){ - tdsqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, isNot ? SQLITE_JUMPIFNULL : 0); }else{ - tdsqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, isNot ? SQLITE_JUMPIFNULL : 0); } break; @@ -107123,10 +107123,10 @@ SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, in case TK_GE: case TK_NE: case TK_EQ: { - if( tdsqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; testcase( jumpIfNull==0 ); - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = tdsqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, dest, jumpIfNull, ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); @@ -107147,8 +107147,8 @@ SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, in case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); testcase( op==TK_ISNULL ); assert( TK_NOTNULL==OP_NotNull ); testcase( op==TK_NOTNULL ); - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - tdsqlite3VdbeAddOp2(v, op, r1, dest); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp2(v, op, r1, dest); VdbeCoverageIf(v, op==TK_ISNULL); VdbeCoverageIf(v, op==TK_NOTNULL); testcase( regFree1==0 ); @@ -107156,28 +107156,28 @@ SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, in } case TK_BETWEEN: { testcase( jumpIfNull==0 ); - exprCodeBetween(pParse, pExpr, dest, tdsqlite3ExprIfTrue, jumpIfNull); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull); break; } #ifndef SQLITE_OMIT_SUBQUERY case TK_IN: { - int destIfFalse = tdsqlite3VdbeMakeLabel(pParse); + int destIfFalse = sqlite3VdbeMakeLabel(pParse); int destIfNull = jumpIfNull ? dest : destIfFalse; - tdsqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); - tdsqlite3VdbeGoto(v, dest); - tdsqlite3VdbeResolveLabel(v, destIfFalse); + sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull); + sqlite3VdbeGoto(v, dest); + sqlite3VdbeResolveLabel(v, destIfFalse); break; } #endif default: { default_expr: if( ExprAlwaysTrue(pExpr) ){ - tdsqlite3VdbeGoto(v, dest); + sqlite3VdbeGoto(v, dest); }else if( ExprAlwaysFalse(pExpr) ){ /* No-op */ }else{ - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr, ®Free1); - tdsqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0); VdbeCoverage(v); testcase( regFree1==0 ); testcase( jumpIfNull==0 ); @@ -107185,8 +107185,8 @@ SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, in break; } } - tdsqlite3ReleaseTempReg(pParse, regFree1); - tdsqlite3ReleaseTempReg(pParse, regFree2); + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); } /* @@ -107198,7 +107198,7 @@ SQLITE_PRIVATE void tdsqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, in ** jump if jumpIfNull is SQLITE_JUMPIFNULL or fall through if jumpIfNull ** is 0. */ -SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ +SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){ Vdbe *v = pParse->pVdbe; int op = 0; int regFree1 = 0; @@ -107243,26 +107243,26 @@ SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, i switch( pExpr->op ){ case TK_AND: case TK_OR: { - Expr *pAlt = tdsqlite3ExprSimplifiedAndOr(pExpr); + Expr *pAlt = sqlite3ExprSimplifiedAndOr(pExpr); if( pAlt!=pExpr ){ - tdsqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pAlt, dest, jumpIfNull); }else if( pExpr->op==TK_AND ){ testcase( jumpIfNull==0 ); - tdsqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); - tdsqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); }else{ - int d2 = tdsqlite3VdbeMakeLabel(pParse); + int d2 = sqlite3VdbeMakeLabel(pParse); testcase( jumpIfNull==0 ); - tdsqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, + sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL); - tdsqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); - tdsqlite3VdbeResolveLabel(v, d2); + sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull); + sqlite3VdbeResolveLabel(v, d2); } break; } case TK_NOT: { testcase( jumpIfNull==0 ); - tdsqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull); break; } case TK_TRUTH: { @@ -107270,17 +107270,17 @@ SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, i int isTrue; /* IS TRUE or IS NOT TRUE */ testcase( jumpIfNull==0 ); isNot = pExpr->op2==TK_ISNOT; - isTrue = tdsqlite3ExprTruthValue(pExpr->pRight); + isTrue = sqlite3ExprTruthValue(pExpr->pRight); testcase( isTrue && isNot ); testcase( !isTrue && isNot ); if( isTrue ^ isNot ){ /* IS TRUE and IS NOT FALSE */ - tdsqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, + sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, isNot ? 0 : SQLITE_JUMPIFNULL); }else{ /* IS FALSE and IS NOT TRUE */ - tdsqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, + sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, isNot ? 0 : SQLITE_JUMPIFNULL); } break; @@ -107298,10 +107298,10 @@ SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, i case TK_GE: case TK_NE: case TK_EQ: { - if( tdsqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; + if( sqlite3ExprIsVector(pExpr->pLeft) ) goto default_expr; testcase( jumpIfNull==0 ); - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - r2 = tdsqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + r2 = sqlite3ExprCodeTemp(pParse, pExpr->pRight, ®Free2); codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, r1, r2, dest, jumpIfNull,ExprHasProperty(pExpr,EP_Commuted)); assert(TK_LT==OP_Lt); testcase(op==OP_Lt); VdbeCoverageIf(v,op==OP_Lt); @@ -107320,8 +107320,8 @@ SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, i } case TK_ISNULL: case TK_NOTNULL: { - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); - tdsqlite3VdbeAddOp2(v, op, r1, dest); + r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, ®Free1); + sqlite3VdbeAddOp2(v, op, r1, dest); testcase( op==TK_ISNULL ); VdbeCoverageIf(v, op==TK_ISNULL); testcase( op==TK_NOTNULL ); VdbeCoverageIf(v, op==TK_NOTNULL); testcase( regFree1==0 ); @@ -107329,17 +107329,17 @@ SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, i } case TK_BETWEEN: { testcase( jumpIfNull==0 ); - exprCodeBetween(pParse, pExpr, dest, tdsqlite3ExprIfFalse, jumpIfNull); + exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfFalse, jumpIfNull); break; } #ifndef SQLITE_OMIT_SUBQUERY case TK_IN: { if( jumpIfNull ){ - tdsqlite3ExprCodeIN(pParse, pExpr, dest, dest); + sqlite3ExprCodeIN(pParse, pExpr, dest, dest); }else{ - int destIfNull = tdsqlite3VdbeMakeLabel(pParse); - tdsqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull); - tdsqlite3VdbeResolveLabel(v, destIfNull); + int destIfNull = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull); + sqlite3VdbeResolveLabel(v, destIfNull); } break; } @@ -107347,12 +107347,12 @@ SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, i default: { default_expr: if( ExprAlwaysFalse(pExpr) ){ - tdsqlite3VdbeGoto(v, dest); + sqlite3VdbeGoto(v, dest); }else if( ExprAlwaysTrue(pExpr) ){ /* no-op */ }else{ - r1 = tdsqlite3ExprCodeTemp(pParse, pExpr, ®Free1); - tdsqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); + r1 = sqlite3ExprCodeTemp(pParse, pExpr, ®Free1); + sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0); VdbeCoverage(v); testcase( regFree1==0 ); testcase( jumpIfNull==0 ); @@ -107360,22 +107360,22 @@ SQLITE_PRIVATE void tdsqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, i break; } } - tdsqlite3ReleaseTempReg(pParse, regFree1); - tdsqlite3ReleaseTempReg(pParse, regFree2); + sqlite3ReleaseTempReg(pParse, regFree1); + sqlite3ReleaseTempReg(pParse, regFree2); } /* -** Like tdsqlite3ExprIfFalse() except that a copy is made of pExpr before +** Like sqlite3ExprIfFalse() except that a copy is made of pExpr before ** code generation, and that copy is deleted after code generation. This ** ensures that the original pExpr is unchanged. */ -SQLITE_PRIVATE void tdsqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){ - tdsqlite3 *db = pParse->db; - Expr *pCopy = tdsqlite3ExprDup(db, pExpr, 0); +SQLITE_PRIVATE void sqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest,int jumpIfNull){ + sqlite3 *db = pParse->db; + Expr *pCopy = sqlite3ExprDup(db, pExpr, 0); if( db->mallocFailed==0 ){ - tdsqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull); + sqlite3ExprIfFalse(pParse, pCopy, dest, jumpIfNull); } - tdsqlite3ExprDelete(db, pCopy); + sqlite3ExprDelete(db, pCopy); } /* @@ -107394,21 +107394,21 @@ SQLITE_PRIVATE void tdsqlite3ExprIfFalseDup(Parse *pParse, Expr *pExpr, int dest static int exprCompareVariable(Parse *pParse, Expr *pVar, Expr *pExpr){ int res = 0; int iVar; - tdsqlite3_value *pL, *pR = 0; + sqlite3_value *pL, *pR = 0; - tdsqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); + sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); if( pR ){ iVar = pVar->iColumn; - tdsqlite3VdbeSetVarmask(pParse->pVdbe, iVar); - pL = tdsqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB); + sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); + pL = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, SQLITE_AFF_BLOB); if( pL ){ - if( tdsqlite3_value_type(pL)==SQLITE_TEXT ){ - tdsqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */ + if( sqlite3_value_type(pL)==SQLITE_TEXT ){ + sqlite3_value_text(pL); /* Make sure the encoding is UTF-8 */ } - res = 0==tdsqlite3MemCompare(pL, pR, 0); + res = 0==sqlite3MemCompare(pL, pR, 0); } - tdsqlite3ValueFree(pR); - tdsqlite3ValueFree(pL); + sqlite3ValueFree(pR); + sqlite3ValueFree(pL); } return res; @@ -107443,7 +107443,7 @@ static int exprCompareVariable(Parse *pParse, Expr *pVar, Expr *pExpr){ ** Argument pParse should normally be NULL. If it is not NULL and pA or ** pB causes a return value of 2. */ -SQLITE_PRIVATE int tdsqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){ +SQLITE_PRIVATE int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){ u32 combinedFlags; if( pA==0 || pB==0 ){ return pB==pA ? 0 : 2; @@ -107459,24 +107459,24 @@ SQLITE_PRIVATE int tdsqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int i return 2; } if( pA->op!=pB->op || pA->op==TK_RAISE ){ - if( pA->op==TK_COLLATE && tdsqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){ + if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){ return 1; } - if( pB->op==TK_COLLATE && tdsqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ + if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ return 1; } return 2; } if( pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN && pA->u.zToken ){ if( pA->op==TK_FUNCTION || pA->op==TK_AGG_FUNCTION ){ - if( tdsqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; + if( sqlite3StrICmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; #ifndef SQLITE_OMIT_WINDOWFUNC assert( pA->op==pB->op ); if( ExprHasProperty(pA,EP_WinFunc)!=ExprHasProperty(pB,EP_WinFunc) ){ return 2; } if( ExprHasProperty(pA,EP_WinFunc) ){ - if( tdsqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){ + if( sqlite3WindowCompare(pParse, pA->y.pWin, pB->y.pWin, 1)!=0 ){ return 2; } } @@ -107484,7 +107484,7 @@ SQLITE_PRIVATE int tdsqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int i }else if( pA->op==TK_NULL ){ return 0; }else if( pA->op==TK_COLLATE ){ - if( tdsqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; + if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; }else if( ALWAYS(pB->u.zToken!=0) && strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ return 2; } @@ -107494,9 +107494,9 @@ SQLITE_PRIVATE int tdsqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int i if( (combinedFlags & EP_TokenOnly)==0 ){ if( combinedFlags & EP_xIsSelect ) return 2; if( (combinedFlags & EP_FixedCol)==0 - && tdsqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; - if( tdsqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; - if( tdsqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; + && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; + if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; + if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE && (combinedFlags & EP_Reduced)==0 @@ -107507,9 +107507,9 @@ SQLITE_PRIVATE int tdsqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int i if( pA->op==TK_FUNCTION && iTab<0 ){ /* Ex: CREATE TABLE t1(a CHECK( aa[i].pExpr; Expr *pExprB = pB->a[i].pExpr; if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1; - if( (res = tdsqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res; + if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res; } return 0; } /* -** Like tdsqlite3ExprCompare() except COLLATE operators at the top-level +** Like sqlite3ExprCompare() except COLLATE operators at the top-level ** are ignored. */ -SQLITE_PRIVATE int tdsqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ - return tdsqlite3ExprCompare(0, - tdsqlite3ExprSkipCollateAndLikely(pA), - tdsqlite3ExprSkipCollateAndLikely(pB), +SQLITE_PRIVATE int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ + return sqlite3ExprCompare(0, + sqlite3ExprSkipCollateAndLikely(pA), + sqlite3ExprSkipCollateAndLikely(pB), iTab); } @@ -107582,7 +107582,7 @@ static int exprImpliesNotNull( ){ assert( p ); assert( pNN ); - if( tdsqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){ + if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){ return pNN->op!=TK_NULL; } switch( p->op ){ @@ -107669,13 +107669,13 @@ static int exprImpliesNotNull( ** improvement. Returning false might cause a performance reduction, but ** it will always give the correct answer and is hence always safe. */ -SQLITE_PRIVATE int tdsqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ - if( tdsqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){ +SQLITE_PRIVATE int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){ + if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){ return 1; } if( pE2->op==TK_OR - && (tdsqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab) - || tdsqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) ) + && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab) + || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) ) ){ return 1; } @@ -107688,7 +107688,7 @@ SQLITE_PRIVATE int tdsqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, } /* -** This is the Expr node callback for tdsqlite3ExprImpliesNonNullRow(). +** This is the Expr node callback for sqlite3ExprImpliesNonNullRow(). ** If the expression node requires that the table at pWalker->iCur ** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. ** @@ -107731,16 +107731,16 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ case TK_AND: if( pWalker->eCode==0 ){ - tdsqlite3WalkExpr(pWalker, pExpr->pLeft); + sqlite3WalkExpr(pWalker, pExpr->pLeft); if( pWalker->eCode ){ pWalker->eCode = 0; - tdsqlite3WalkExpr(pWalker, pExpr->pRight); + sqlite3WalkExpr(pWalker, pExpr->pRight); } } return WRC_Prune; case TK_BETWEEN: - if( tdsqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){ + if( sqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){ assert( pWalker->eCode ); return WRC_Abort; } @@ -107794,15 +107794,15 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ ** be non-NULL, then the LEFT JOIN can be safely converted into an ** ordinary join. */ -SQLITE_PRIVATE int tdsqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ +SQLITE_PRIVATE int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ Walker w; - p = tdsqlite3ExprSkipCollateAndLikely(p); + p = sqlite3ExprSkipCollateAndLikely(p); if( p==0 ) return 0; if( p->op==TK_NOTNULL ){ p = p->pLeft; }else{ while( p->op==TK_AND ){ - if( tdsqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1; + if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1; p = p->pRight; } } @@ -107811,7 +107811,7 @@ SQLITE_PRIVATE int tdsqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ w.xSelectCallback2 = 0; w.eCode = 0; w.u.iCur = iTab; - tdsqlite3WalkExpr(&w, p); + sqlite3WalkExpr(&w, p); return w.eCode; } @@ -107835,7 +107835,7 @@ struct IdxCover { static int exprIdxCover(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN && pExpr->iTable==pWalker->u.pIdxCover->iCur - && tdsqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 + && sqlite3TableColumnToIndex(pWalker->u.pIdxCover->pIdx, pExpr->iColumn)<0 ){ pWalker->eCode = 1; return WRC_Abort; @@ -107853,7 +107853,7 @@ static int exprIdxCover(Walker *pWalker, Expr *pExpr){ ** evaluated using only the index and without having to lookup the ** corresponding table entry. */ -SQLITE_PRIVATE int tdsqlite3ExprCoveredByIndex( +SQLITE_PRIVATE int sqlite3ExprCoveredByIndex( Expr *pExpr, /* The index to be tested */ int iCur, /* The cursor number for the corresponding table */ Index *pIdx /* The index that might be used for coverage */ @@ -107865,7 +107865,7 @@ SQLITE_PRIVATE int tdsqlite3ExprCoveredByIndex( xcov.pIdx = pIdx; w.xExprCallback = exprIdxCover; w.u.pIdxCover = &xcov; - tdsqlite3WalkExpr(&w, pExpr); + sqlite3WalkExpr(&w, pExpr); return !w.eCode; } @@ -107874,7 +107874,7 @@ SQLITE_PRIVATE int tdsqlite3ExprCoveredByIndex( ** An instance of the following structure is used by the tree walker ** to count references to table columns in the arguments of an ** aggregate function, in order to implement the -** tdsqlite3FunctionThisSrc() routine. +** sqlite3FunctionThisSrc() routine. */ struct SrcCount { SrcList *pSrc; /* One particular FROM clause in a nested query */ @@ -107887,10 +107887,10 @@ struct SrcCount { */ static int exprSrcCount(Walker *pWalker, Expr *pExpr){ /* There was once a NEVER() on the second term on the grounds that - ** tdsqlite3FunctionUsesThisSrc() was always called before - ** tdsqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet + ** sqlite3FunctionUsesThisSrc() was always called before + ** sqlite3ExprAnalyzeAggregates() and so the TK_COLUMNs have not yet ** been converted into TK_AGG_COLUMN. But this is no longer true due - ** to window functions - tdsqlite3WindowRewrite() may now indirectly call + ** to window functions - sqlite3WindowRewrite() may now indirectly call ** FunctionUsesThisSrc() when creating a new sub-select. */ if( pExpr->op==TK_COLUMN || pExpr->op==TK_AGG_COLUMN ){ int i; @@ -107918,21 +107918,21 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){ ** has no arguments or has only constant arguments. Return false if pExpr ** references columns but not columns of tables found in pSrcList. */ -SQLITE_PRIVATE int tdsqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ +SQLITE_PRIVATE int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ Walker w; struct SrcCount cnt; assert( pExpr->op==TK_AGG_FUNCTION ); memset(&w, 0, sizeof(w)); w.xExprCallback = exprSrcCount; - w.xSelectCallback = tdsqlite3SelectWalkNoop; + w.xSelectCallback = sqlite3SelectWalkNoop; w.u.pSrcCount = &cnt; cnt.pSrc = pSrcList; cnt.nThis = 0; cnt.nOther = 0; - tdsqlite3WalkExprList(&w, pExpr->x.pList); + sqlite3WalkExprList(&w, pExpr->x.pList); #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ - tdsqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); + sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); } #endif return cnt.nThis>0 || cnt.nOther==0; @@ -107942,9 +107942,9 @@ SQLITE_PRIVATE int tdsqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ ** Add a new element to the pAggInfo->aCol[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ -static int addAggInfoColumn(tdsqlite3 *db, AggInfo *pInfo){ +static int addAggInfoColumn(sqlite3 *db, AggInfo *pInfo){ int i; - pInfo->aCol = tdsqlite3ArrayAllocate( + pInfo->aCol = sqlite3ArrayAllocate( db, pInfo->aCol, sizeof(pInfo->aCol[0]), @@ -107958,9 +107958,9 @@ static int addAggInfoColumn(tdsqlite3 *db, AggInfo *pInfo){ ** Add a new element to the pAggInfo->aFunc[] array. Return the index of ** the new element. Return a negative number if malloc fails. */ -static int addAggInfoFunc(tdsqlite3 *db, AggInfo *pInfo){ +static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ int i; - pInfo->aFunc = tdsqlite3ArrayAllocate( + pInfo->aFunc = sqlite3ArrayAllocate( db, pInfo->aFunc, sizeof(pInfo->aFunc[0]), @@ -107972,7 +107972,7 @@ static int addAggInfoFunc(tdsqlite3 *db, AggInfo *pInfo){ /* ** This is the xExprCallback for a tree walker. It is used to -** implement tdsqlite3ExprAnalyzeAggregates(). See tdsqlite3ExprAnalyzeAggregates +** implement sqlite3ExprAnalyzeAggregates(). See sqlite3ExprAnalyzeAggregates ** for additional information. */ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ @@ -108062,7 +108062,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ */ struct AggInfo_func *pItem = pAggInfo->aFunc; for(i=0; inFunc; i++, pItem++){ - if( tdsqlite3ExprCompare(0, pItem->pExpr, pExpr, -1)==0 ){ + if( sqlite3ExprCompare(0, pItem->pExpr, pExpr, -1)==0 ){ break; } } @@ -108077,7 +108077,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){ pItem->pExpr = pExpr; pItem->iMem = ++pParse->nMem; assert( !ExprHasProperty(pExpr, EP_IntValue) ); - pItem->pFunc = tdsqlite3FindFunction(pParse->db, + pItem->pFunc = sqlite3FindFunction(pParse->db, pExpr->u.zToken, pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); if( pExpr->flags & EP_Distinct ){ @@ -108118,9 +108118,9 @@ static void analyzeAggregatesInSelectEnd(Walker *pWalker, Select *pSelect){ ** necessary. ** ** This routine should only be called after the expression has been -** analyzed by tdsqlite3ResolveExprNames(). +** analyzed by sqlite3ResolveExprNames(). */ -SQLITE_PRIVATE void tdsqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr){ Walker w; w.xExprCallback = analyzeAggregate; w.xSelectCallback = analyzeAggregatesInSelect; @@ -108129,21 +108129,21 @@ SQLITE_PRIVATE void tdsqlite3ExprAnalyzeAggregates(NameContext *pNC, Expr *pExpr w.u.pNC = pNC; w.pParse = 0; assert( pNC->pSrcList!=0 ); - tdsqlite3WalkExpr(&w, pExpr); + sqlite3WalkExpr(&w, pExpr); } /* -** Call tdsqlite3ExprAnalyzeAggregates() for every expression in an +** Call sqlite3ExprAnalyzeAggregates() for every expression in an ** expression list. Return the number of errors. ** ** If an error is found, the analysis is cut short. */ -SQLITE_PRIVATE void tdsqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ +SQLITE_PRIVATE void sqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pList){ struct ExprList_item *pItem; int i; if( pList ){ for(pItem=pList->a, i=0; inExpr; i++, pItem++){ - tdsqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); + sqlite3ExprAnalyzeAggregates(pNC, pItem->pExpr); } } } @@ -108151,7 +108151,7 @@ SQLITE_PRIVATE void tdsqlite3ExprAnalyzeAggList(NameContext *pNC, ExprList *pLis /* ** Allocate a single new register for use to hold some intermediate result. */ -SQLITE_PRIVATE int tdsqlite3GetTempReg(Parse *pParse){ +SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){ if( pParse->nTempReg==0 ){ return ++pParse->nMem; } @@ -108162,9 +108162,9 @@ SQLITE_PRIVATE int tdsqlite3GetTempReg(Parse *pParse){ ** Deallocate a register, making available for reuse for some other ** purpose. */ -SQLITE_PRIVATE void tdsqlite3ReleaseTempReg(Parse *pParse, int iReg){ +SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){ if( iReg ){ - tdsqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0); + sqlite3VdbeReleaseRegisters(pParse, iReg, 1, 0, 0); if( pParse->nTempRegaTempReg) ){ pParse->aTempReg[pParse->nTempReg++] = iReg; } @@ -108174,9 +108174,9 @@ SQLITE_PRIVATE void tdsqlite3ReleaseTempReg(Parse *pParse, int iReg){ /* ** Allocate or deallocate a block of nReg consecutive registers. */ -SQLITE_PRIVATE int tdsqlite3GetTempRange(Parse *pParse, int nReg){ +SQLITE_PRIVATE int sqlite3GetTempRange(Parse *pParse, int nReg){ int i, n; - if( nReg==1 ) return tdsqlite3GetTempReg(pParse); + if( nReg==1 ) return sqlite3GetTempReg(pParse); i = pParse->iRangeReg; n = pParse->nRangeReg; if( nReg<=n ){ @@ -108188,12 +108188,12 @@ SQLITE_PRIVATE int tdsqlite3GetTempRange(Parse *pParse, int nReg){ } return i; } -SQLITE_PRIVATE void tdsqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ +SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ if( nReg==1 ){ - tdsqlite3ReleaseTempReg(pParse, iReg); + sqlite3ReleaseTempReg(pParse, iReg); return; } - tdsqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0); + sqlite3VdbeReleaseRegisters(pParse, iReg, nReg, 0, 0); if( nReg>pParse->nRangeReg ){ pParse->nRangeReg = nReg; pParse->iRangeReg = iReg; @@ -108208,7 +108208,7 @@ SQLITE_PRIVATE void tdsqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg) ** the sub/co-routine does not use registers in common with the code that ** invokes the sub/co-routine. */ -SQLITE_PRIVATE void tdsqlite3ClearTempRegCache(Parse *pParse){ +SQLITE_PRIVATE void sqlite3ClearTempRegCache(Parse *pParse){ pParse->nTempReg = 0; pParse->nRangeReg = 0; } @@ -108219,7 +108219,7 @@ SQLITE_PRIVATE void tdsqlite3ClearTempRegCache(Parse *pParse){ ** statements. */ #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ +SQLITE_PRIVATE int sqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast){ int i; if( pParse->nRangeReg>0 && pParse->iRangeReg+pParse->nRangeReg > iFirst @@ -108269,14 +108269,14 @@ SQLITE_PRIVATE int tdsqlite3NoTempsInRange(Parse *pParse, int iFirst, int iLast) ** Or, if zName is not a system table, zero is returned. */ static int isAlterableTable(Parse *pParse, Table *pTab){ - if( 0==tdsqlite3StrNICmp(pTab->zName, "sqlite_", 7) + if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) #ifndef SQLITE_OMIT_VIRTUALTABLE || ( (pTab->tabFlags & TF_Shadow)!=0 - && tdsqlite3ReadOnlyShadowTables(pParse->db) + && sqlite3ReadOnlyShadowTables(pParse->db) ) #endif ){ - tdsqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); + sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName); return 1; } return 0; @@ -108290,7 +108290,7 @@ static int isAlterableTable(Parse *pParse, Table *pTab){ ** objects unusable. */ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\".%s " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" @@ -108301,7 +108301,7 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ ); if( bTemp==0 ){ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "SELECT 1 " "FROM temp.%s " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" @@ -108319,9 +108319,9 @@ static void renameTestSchema(Parse *pParse, const char *zDb, int bTemp){ static void renameReloadSchema(Parse *pParse, int iDb){ Vdbe *v = pParse->pVdbe; if( v ){ - tdsqlite3ChangeCookie(pParse, iDb); - tdsqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0); - if( iDb!=1 ) tdsqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, iDb, 0); + if( iDb!=1 ) sqlite3VdbeAddParseSchemaOp(pParse->pVdbe, 1, 0); } } @@ -108329,7 +108329,7 @@ static void renameReloadSchema(Parse *pParse, int iDb){ ** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" ** command. */ -SQLITE_PRIVATE void tdsqlite3AlterRenameTable( +SQLITE_PRIVATE void sqlite3AlterRenameTable( Parse *pParse, /* Parser context. */ SrcList *pSrc, /* The table to rename. */ Token *pName /* The new table name. */ @@ -108338,7 +108338,7 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( char *zDb; /* Name of database iDb */ Table *pTab; /* Table being renamed */ char *zName = 0; /* NULL-terminated version of pName */ - tdsqlite3 *db = pParse->db; /* Database connection */ + sqlite3 *db = pParse->db; /* Database connection */ int nTabName; /* Number of UTF-8 characters in zTabName */ const char *zTabName; /* Original name of the table */ Vdbe *v; @@ -108348,23 +108348,23 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( savedDbFlags = db->mDbFlags; if( NEVER(db->mallocFailed) ) goto exit_rename_table; assert( pSrc->nSrc==1 ); - assert( tdsqlite3BtreeHoldsAllMutexes(pParse->db) ); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - pTab = tdsqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_rename_table; - iDb = tdsqlite3SchemaToIndex(pParse->db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); zDb = db->aDb[iDb].zDbSName; db->mDbFlags |= DBFLAG_PreferBuiltin; /* Get a NULL terminated version of the new table name. */ - zName = tdsqlite3NameFromToken(db, pName); + zName = sqlite3NameFromToken(db, pName); if( !zName ) goto exit_rename_table; /* Check that a table or index named 'zName' does not already exist ** in database iDb. If so, this is an error. */ - if( tdsqlite3FindTable(db, zName, zDb) || tdsqlite3FindIndex(db, zName, zDb) ){ - tdsqlite3ErrorMsg(pParse, + if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){ + sqlite3ErrorMsg(pParse, "there is already another table or index with this name: %s", zName); goto exit_rename_table; } @@ -108375,30 +108375,30 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ goto exit_rename_table; } - if( SQLITE_OK!=tdsqlite3CheckObjectName(pParse,zName,"table",zName) ){ + if( SQLITE_OK!=sqlite3CheckObjectName(pParse,zName,"table",zName) ){ goto exit_rename_table; } #ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ - tdsqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); + sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName); goto exit_rename_table; } #endif #ifndef SQLITE_OMIT_AUTHORIZATION /* Invoke the authorization callback. */ - if( tdsqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ goto exit_rename_table; } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - if( tdsqlite3ViewGetColumnNames(pParse, pTab) ){ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto exit_rename_table; } if( IsVirtual(pTab) ){ - pVTab = tdsqlite3GetVTable(db, pTab); + pVTab = sqlite3GetVTable(db, pTab); if( pVTab->pVtab->pModule->xRename==0 ){ pVTab = 0; } @@ -108406,22 +108406,22 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( #endif /* Begin a transaction for database iDb. Then modify the schema cookie - ** (since the ALTER TABLE modifies the schema). Call tdsqlite3MayAbort(), + ** (since the ALTER TABLE modifies the schema). Call sqlite3MayAbort(), ** as the scalar functions (e.g. sqlite_rename_table()) invoked by the ** nested SQL may raise an exception. */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v==0 ){ goto exit_rename_table; } - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); /* figure out how many UTF-8 characters are in zName */ zTabName = pTab->zName; - nTabName = tdsqlite3Utf8CharLen(zTabName, -1); + nTabName = sqlite3Utf8CharLen(zTabName, -1); /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in ** the schema to use the new table name. */ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" @@ -108431,7 +108431,7 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( /* Update the tbl_name and name columns of the sqlite_master table ** as required. */ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE %Q.%s SET " "tbl_name = %Q, " "name = CASE " @@ -108451,8 +108451,8 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( /* If the sqlite_sequence table exists in this database, then update ** it with the new table name. */ - if( tdsqlite3FindTable(db, "sqlite_sequence", zDb) ){ - tdsqlite3NestedParse(pParse, + if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ + sqlite3NestedParse(pParse, "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", zDb, zName, pTab->zName); } @@ -108462,7 +108462,7 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( ** edit view and trigger definitions within the temp database ** as required. */ if( iDb!=1 ){ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE sqlite_temp_master SET " "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " "tbl_name = " @@ -108481,8 +108481,8 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( #ifndef SQLITE_OMIT_VIRTUALTABLE if( pVTab ){ int i = ++pParse->nMem; - tdsqlite3VdbeLoadString(v, i, zName); - tdsqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); + sqlite3VdbeLoadString(v, i, zName); + sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); } #endif @@ -108490,8 +108490,8 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameTable( renameTestSchema(pParse, zDb, iDb==1); exit_rename_table: - tdsqlite3SrcListDelete(db, pSrc); - tdsqlite3DbFree(db, zName); + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zName); db->mDbFlags = savedDbFlags; } @@ -108503,7 +108503,7 @@ exit_rename_table: ** The Table structure pParse->pNewTable was extended to include ** the new column during parsing. */ -SQLITE_PRIVATE void tdsqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ +SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ Table *pNew; /* Copy of pParse->pNewTable */ Table *pTab; /* Table being altered */ int iDb; /* Database number */ @@ -108512,7 +108512,7 @@ SQLITE_PRIVATE void tdsqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef) char *zCol; /* Null-terminated column definition */ Column *pCol; /* The new column */ Expr *pDflt; /* Default value for the new column */ - tdsqlite3 *db; /* The database connection; */ + sqlite3 *db; /* The database connection; */ Vdbe *v; /* The prepared statement under construction */ int r1; /* Temporary registers */ @@ -108521,18 +108521,18 @@ SQLITE_PRIVATE void tdsqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef) pNew = pParse->pNewTable; assert( pNew ); - assert( tdsqlite3BtreeHoldsAllMutexes(db) ); - iDb = tdsqlite3SchemaToIndex(db, pNew->pSchema); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pNew->pSchema); zDb = db->aDb[iDb].zDbSName; zTab = &pNew->zName[16]; /* Skip the "sqlite_altertab_" prefix on the name */ pCol = &pNew->aCol[pNew->nCol-1]; pDflt = pCol->pDflt; - pTab = tdsqlite3FindTable(db, zTab, zDb); + pTab = sqlite3FindTable(db, zTab, zDb); assert( pTab ); #ifndef SQLITE_OMIT_AUTHORIZATION /* Invoke the authorization callback. */ - if( tdsqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ return; } #endif @@ -108543,11 +108543,11 @@ SQLITE_PRIVATE void tdsqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef) ** column must not be NULL. */ if( pCol->colFlags & COLFLAG_PRIMKEY ){ - tdsqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); + sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); return; } if( pNew->pIndex ){ - tdsqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); + sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); return; } if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){ @@ -108560,57 +108560,57 @@ SQLITE_PRIVATE void tdsqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef) pDflt = 0; } if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Cannot add a REFERENCES column with non-NULL default value"); return; } if( pCol->notNull && !pDflt ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Cannot add a NOT NULL column with default value NULL"); return; } - /* Ensure the default expression is something that tdsqlite3ValueFromExpr() + /* Ensure the default expression is something that sqlite3ValueFromExpr() ** can handle (i.e. not CURRENT_TIME etc.) */ if( pDflt ){ - tdsqlite3_value *pVal = 0; + sqlite3_value *pVal = 0; int rc; - rc = tdsqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); + rc = sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_BLOB, &pVal); assert( rc==SQLITE_OK || rc==SQLITE_NOMEM ); if( rc!=SQLITE_OK ){ assert( db->mallocFailed == 1 ); return; } if( !pVal ){ - tdsqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default"); + sqlite3ErrorMsg(pParse,"Cannot add a column with non-constant default"); return; } - tdsqlite3ValueFree(pVal); + sqlite3ValueFree(pVal); } }else if( pCol->colFlags & COLFLAG_STORED ){ - tdsqlite3ErrorMsg(pParse, "cannot add a STORED column"); + sqlite3ErrorMsg(pParse, "cannot add a STORED column"); return; } /* Modify the CREATE TABLE statement. */ - zCol = tdsqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); + zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n); if( zCol ){ char *zEnd = &zCol[pColDef->n-1]; u32 savedDbFlags = db->mDbFlags; - while( zEnd>zCol && (*zEnd==';' || tdsqlite3Isspace(*zEnd)) ){ + while( zEnd>zCol && (*zEnd==';' || sqlite3Isspace(*zEnd)) ){ *zEnd-- = '\0'; } db->mDbFlags |= DBFLAG_PreferBuiltin; - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) " "WHERE type = 'table' AND name = %Q", zDb, MASTER_NAME, pNew->addColOffset, zCol, pNew->addColOffset+1, zTab ); - tdsqlite3DbFree(db, zCol); + sqlite3DbFree(db, zCol); db->mDbFlags = savedDbFlags; } @@ -108618,16 +108618,16 @@ SQLITE_PRIVATE void tdsqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef) ** from less than 3 to 4, as that will corrupt any preexisting DESC ** index. */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v ){ - r1 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); - tdsqlite3VdbeUsesBtree(v, iDb); - tdsqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); - tdsqlite3VdbeAddOp2(v, OP_IfPos, r1, tdsqlite3VdbeCurrentAddr(v)+2); + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_AddImm, r1, -2); + sqlite3VdbeAddOp2(v, OP_IfPos, r1, sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); - tdsqlite3ReleaseTempReg(pParse, r1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 3); + sqlite3ReleaseTempReg(pParse, r1); } /* Reload the table definition */ @@ -108642,56 +108642,56 @@ SQLITE_PRIVATE void tdsqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef) ** This routine makes a (partial) copy of the Table structure ** for the table being altered and sets Parse.pNewTable to point ** to it. Routines called by the parser as the column definition -** is parsed (i.e. tdsqlite3AddColumn()) add the new Column data to +** is parsed (i.e. sqlite3AddColumn()) add the new Column data to ** the copy. The copy of the Table structure is deleted by tokenize.c ** after parsing is finished. ** -** Routine tdsqlite3AlterFinishAddColumn() will be called to complete +** Routine sqlite3AlterFinishAddColumn() will be called to complete ** coding the "ALTER TABLE ... ADD" statement. */ -SQLITE_PRIVATE void tdsqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ +SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ Table *pNew; Table *pTab; int iDb; int i; int nAlloc; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; /* Look up the table being altered. */ assert( pParse->pNewTable==0 ); - assert( tdsqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); if( db->mallocFailed ) goto exit_begin_add_column; - pTab = tdsqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_begin_add_column; #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ - tdsqlite3ErrorMsg(pParse, "virtual tables may not be altered"); + sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); goto exit_begin_add_column; } #endif /* Make sure this is not an attempt to ALTER a view. */ if( pTab->pSelect ){ - tdsqlite3ErrorMsg(pParse, "Cannot add a column to a view"); + sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); goto exit_begin_add_column; } if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){ goto exit_begin_add_column; } - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); assert( pTab->addColOffset>0 ); - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); /* Put a copy of the Table struct in Parse.pNewTable for the - ** tdsqlite3AddColumn() function and friends to modify. But modify + ** sqlite3AddColumn() function and friends to modify. But modify ** the name by adding an "sqlite_altertab_" prefix. By adding this ** prefix, we insure that the name will not collide with an existing ** table because user table are not allowed to have the "sqlite_" ** prefix on their name. */ - pNew = (Table*)tdsqlite3DbMallocZero(db, sizeof(Table)); + pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table)); if( !pNew ) goto exit_begin_add_column; pParse->pNewTable = pNew; pNew->nTabRef = 1; @@ -108699,8 +108699,8 @@ SQLITE_PRIVATE void tdsqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ assert( pNew->nCol>0 ); nAlloc = (((pNew->nCol-1)/8)*8)+8; assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 ); - pNew->aCol = (Column*)tdsqlite3DbMallocZero(db, sizeof(Column)*nAlloc); - pNew->zName = tdsqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); + pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc); + pNew->zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab->zName); if( !pNew->aCol || !pNew->zName ){ assert( db->mallocFailed ); goto exit_begin_add_column; @@ -108708,7 +108708,7 @@ SQLITE_PRIVATE void tdsqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol); for(i=0; inCol; i++){ Column *pCol = &pNew->aCol[i]; - pCol->zName = tdsqlite3DbStrDup(db, pCol->zName); + pCol->zName = sqlite3DbStrDup(db, pCol->zName); pCol->zColl = 0; pCol->pDflt = 0; } @@ -108717,7 +108717,7 @@ SQLITE_PRIVATE void tdsqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){ pNew->nTabRef = 1; exit_begin_add_column: - tdsqlite3SrcListDelete(db, pSrc); + sqlite3SrcListDelete(db, pSrc); return; } @@ -108743,7 +108743,7 @@ static int isRealTable(Parse *pParse, Table *pTab){ } #endif if( zType ){ - tdsqlite3ErrorMsg( + sqlite3ErrorMsg( pParse, "cannot rename columns of %s \"%s\"", zType, pTab->zName ); return 1; @@ -108759,13 +108759,13 @@ static int isRealTable(Parse *pParse, Table *pTab){ ** ** cmd ::= ALTER TABLE pSrc RENAME COLUMN pOld TO pNew */ -SQLITE_PRIVATE void tdsqlite3AlterRenameColumn( +SQLITE_PRIVATE void sqlite3AlterRenameColumn( Parse *pParse, /* Parsing context */ SrcList *pSrc, /* Table being altered. pSrc->nSrc==1 */ Token *pOld, /* Name of column being changed */ Token *pNew /* New column name */ ){ - tdsqlite3 *db = pParse->db; /* Database connection */ + sqlite3 *db = pParse->db; /* Database connection */ Table *pTab; /* Table being updated */ int iCol; /* Index of column being renamed */ char *zOld = 0; /* Old column name */ @@ -108775,7 +108775,7 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameColumn( int bQuote; /* True to quote the new name */ /* Locate the table to be altered */ - pTab = tdsqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); + pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_rename_column; /* Cannot alter a system table */ @@ -108783,26 +108783,26 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameColumn( if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column; /* Which schema holds the table to be altered */ - iSchema = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iSchema>=0 ); zDb = db->aDb[iSchema].zDbSName; #ifndef SQLITE_OMIT_AUTHORIZATION /* Invoke the authorization callback. */ - if( tdsqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ + if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){ goto exit_rename_column; } #endif /* Make sure the old name really is a column name in the table to be ** altered. Set iCol to be the index of the column being renamed */ - zOld = tdsqlite3NameFromToken(db, pOld); + zOld = sqlite3NameFromToken(db, pOld); if( !zOld ) goto exit_rename_column; for(iCol=0; iColnCol; iCol++){ - if( 0==tdsqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break; + if( 0==sqlite3StrICmp(pTab->aCol[iCol].zName, zOld) ) break; } if( iCol==pTab->nCol ){ - tdsqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld); + sqlite3ErrorMsg(pParse, "no such column: \"%s\"", zOld); goto exit_rename_column; } @@ -108810,12 +108810,12 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameColumn( ** uses the sqlite_rename_column() SQL function to compute the new ** CREATE statement text for the sqlite_master table. */ - tdsqlite3MayAbort(pParse); - zNew = tdsqlite3NameFromToken(db, pNew); + sqlite3MayAbort(pParse); + zNew = sqlite3NameFromToken(db, pNew); if( !zNew ) goto exit_rename_column; assert( pNew->n>0 ); - bQuote = tdsqlite3Isquote(pNew->z[0]); - tdsqlite3NestedParse(pParse, + bQuote = sqlite3Isquote(pNew->z[0]); + sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' " @@ -108826,7 +108826,7 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameColumn( pTab->zName ); - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE temp.%s SET " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " "WHERE type IN ('trigger', 'view')", @@ -108839,9 +108839,9 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameColumn( renameTestSchema(pParse, zDb, iSchema==1); exit_rename_column: - tdsqlite3SrcListDelete(db, pSrc); - tdsqlite3DbFree(db, zOld); - tdsqlite3DbFree(db, zNew); + sqlite3SrcListDelete(db, pSrc); + sqlite3DbFree(db, zOld); + sqlite3DbFree(db, zNew); return; } @@ -108854,8 +108854,8 @@ SQLITE_PRIVATE void tdsqlite3AlterRenameColumn( ** * The name of a table column in Column.zName ** ** A list of RenameToken objects can be constructed during parsing. -** Each new object is created by tdsqlite3RenameTokenMap(). -** As the parse tree is transformed, the tdsqlite3RenameTokenRemap() +** Each new object is created by sqlite3RenameTokenMap(). +** As the parse tree is transformed, the sqlite3RenameTokenRemap() ** routine is used to keep the mapping current. ** ** After the parse finishes, renameTokenFind() routine can be used @@ -108899,7 +108899,7 @@ struct RenameCtx { ** Even though this always seems to work, it is undefined according to the ** C standard. Example of undefined comparison: ** -** tdsqlite3_free(x); +** sqlite3_free(x); ** if( x==y ) ... ** ** Technically, as x no longer points into a valid object or to the byte @@ -108933,12 +108933,12 @@ static void renameTokenCheckAll(Parse *pParse, void *pPtr){ ** with tail recursion in tokenExpr() routine, for a small performance ** improvement. */ -SQLITE_PRIVATE void *tdsqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){ +SQLITE_PRIVATE void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){ RenameToken *pNew; assert( pPtr || pParse->db->mallocFailed ); renameTokenCheckAll(pParse, pPtr); if( pParse->eParseMode!=PARSE_MODE_UNMAP ){ - pNew = tdsqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); + pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken)); if( pNew ){ pNew->p = pPtr; pNew->t = *pToken; @@ -108955,7 +108955,7 @@ SQLITE_PRIVATE void *tdsqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *p ** with parse tree element pFrom. This function remaps the associated token ** to parse tree element pTo. */ -SQLITE_PRIVATE void tdsqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){ +SQLITE_PRIVATE void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){ RenameToken *p; renameTokenCheckAll(pParse, pTo); for(p=pParse->pRename; p; p=p->pNext){ @@ -108967,11 +108967,11 @@ SQLITE_PRIVATE void tdsqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pF } /* -** Walker callback used by tdsqlite3RenameExprUnmap(). +** Walker callback used by sqlite3RenameExprUnmap(). */ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ Parse *pParse = pWalker->pParse; - tdsqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); + sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr); return WRC_Continue; } @@ -108988,15 +108988,15 @@ static void renameWalkWith(Walker *pWalker, Select *pSelect){ NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pWalker->pParse; - tdsqlite3SelectPrep(sNC.pParse, p, &sNC); - tdsqlite3WalkSelect(pWalker, p); - tdsqlite3RenameExprlistUnmap(pWalker->pParse, pWith->a[i].pCols); + sqlite3SelectPrep(sNC.pParse, p, &sNC); + sqlite3WalkSelect(pWalker, p); + sqlite3RenameExprlistUnmap(pWalker->pParse, pWith->a[i].pCols); } } } /* -** Walker callback used by tdsqlite3RenameExprUnmap(). +** Walker callback used by sqlite3RenameExprUnmap(). */ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; @@ -109007,15 +109007,15 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ ExprList *pList = p->pEList; for(i=0; inExpr; i++){ if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){ - tdsqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName); + sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName); } } } if( ALWAYS(p->pSrc) ){ /* Every Select as a SrcList, even if it is empty */ SrcList *pSrc = p->pSrc; for(i=0; inSrc; i++){ - tdsqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); - if( tdsqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort; + sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName); + if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort; } } @@ -109026,7 +109026,7 @@ static int renameUnmapSelectCb(Walker *pWalker, Select *p){ /* ** Remove all nodes that are part of expression pExpr from the rename list. */ -SQLITE_PRIVATE void tdsqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ +SQLITE_PRIVATE void sqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ u8 eMode = pParse->eParseMode; Walker sWalker; memset(&sWalker, 0, sizeof(Walker)); @@ -109034,7 +109034,7 @@ SQLITE_PRIVATE void tdsqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ sWalker.xExprCallback = renameUnmapExprCb; sWalker.xSelectCallback = renameUnmapSelectCb; pParse->eParseMode = PARSE_MODE_UNMAP; - tdsqlite3WalkExpr(&sWalker, pExpr); + sqlite3WalkExpr(&sWalker, pExpr); pParse->eParseMode = eMode; } @@ -109042,17 +109042,17 @@ SQLITE_PRIVATE void tdsqlite3RenameExprUnmap(Parse *pParse, Expr *pExpr){ ** Remove all nodes that are part of expression-list pEList from the ** rename list. */ -SQLITE_PRIVATE void tdsqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ +SQLITE_PRIVATE void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ if( pEList ){ int i; Walker sWalker; memset(&sWalker, 0, sizeof(Walker)); sWalker.pParse = pParse; sWalker.xExprCallback = renameUnmapExprCb; - tdsqlite3WalkExprList(&sWalker, pEList); + sqlite3WalkExprList(&sWalker, pEList); for(i=0; inExpr; i++){ if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) ){ - tdsqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName); + sqlite3RenameTokenRemap(pParse, 0, (void*)pEList->a[i].zEName); } } } @@ -109061,12 +109061,12 @@ SQLITE_PRIVATE void tdsqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList /* ** Free the list of RenameToken objects given in the second argument */ -static void renameTokenFree(tdsqlite3 *db, RenameToken *pToken){ +static void renameTokenFree(sqlite3 *db, RenameToken *pToken){ RenameToken *pNext; RenameToken *p; for(p=pToken; p; p=pNext){ pNext = p->pNext; - tdsqlite3DbFree(db, p); + sqlite3DbFree(db, p); } } @@ -109093,7 +109093,7 @@ static void renameTokenFind(Parse *pParse, struct RenameCtx *pCtx, void *pPtr){ /* ** This is a Walker select callback. It does nothing. It is only required -** because without a dummy callback, tdsqlite3WalkExpr() and similar do not +** because without a dummy callback, sqlite3WalkExpr() and similar do not ** descend into sub-select statements. */ static int renameColumnSelectCb(Walker *pWalker, Select *p){ @@ -109158,22 +109158,22 @@ static RenameToken *renameColumnTokenNext(RenameCtx *pCtx){ ** adds context to the error message and then stores it in pCtx. */ static void renameColumnParseError( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int bPost, - tdsqlite3_value *pType, - tdsqlite3_value *pObject, + sqlite3_value *pType, + sqlite3_value *pObject, Parse *pParse ){ - const char *zT = (const char*)tdsqlite3_value_text(pType); - const char *zN = (const char*)tdsqlite3_value_text(pObject); + const char *zT = (const char*)sqlite3_value_text(pType); + const char *zN = (const char*)sqlite3_value_text(pObject); char *zErr; - zErr = tdsqlite3_mprintf("error in %s %s%s: %s", + zErr = sqlite3_mprintf("error in %s %s%s: %s", zT, zN, (bPost ? " after rename" : ""), pParse->zErrMsg ); - tdsqlite3_result_error(pCtx, zErr, -1); - tdsqlite3_free(zErr); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); } /* @@ -109194,7 +109194,7 @@ static void renameColumnElistNames( char *zName = pEList->a[i].zEName; if( ALWAYS(pEList->a[i].eEName==ENAME_NAME) && ALWAYS(zName!=0) - && 0==tdsqlite3_stricmp(zName, zOld) + && 0==sqlite3_stricmp(zName, zOld) ){ renameTokenFind(pParse, pCtx, (void*)zName); } @@ -109217,7 +109217,7 @@ static void renameColumnIdlistNames( int i; for(i=0; inId; i++){ char *zName = pIdList->a[i].zName; - if( 0==tdsqlite3_stricmp(zName, zOld) ){ + if( 0==sqlite3_stricmp(zName, zOld) ){ renameTokenFind(pParse, pCtx, (void*)zName); } } @@ -109231,14 +109231,14 @@ static void renameColumnIdlistNames( static int renameParseSql( Parse *p, /* Memory to use for Parse object */ const char *zDb, /* Name of schema SQL belongs to */ - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ const char *zSql, /* SQL to parse */ int bTemp /* True if SQL is from temp schema */ ){ int rc; char *zErr = 0; - db->init.iDb = bTemp ? 1 : tdsqlite3FindDbName(db, zDb); + db->init.iDb = bTemp ? 1 : sqlite3FindDbName(db, zDb); /* Parse the SQL statement passed as the first argument. If no error ** occurs and the parse does not result in a new table, index or @@ -109247,7 +109247,7 @@ static int renameParseSql( p->eParseMode = PARSE_MODE_RENAME; p->db = db; p->nQueryLoop = 1; - rc = tdsqlite3RunParser(p, zSql, &zErr); + rc = sqlite3RunParser(p, zSql, &zErr); assert( p->zErrMsg==0 ); assert( rc!=SQLITE_OK || zErr==0 ); p->zErrMsg = zErr; @@ -109262,7 +109262,7 @@ static int renameParseSql( /* Ensure that all mappings in the Parse.pRename list really do map to ** a part of the input string. */ if( rc==SQLITE_OK ){ - int nSql = tdsqlite3Strlen30(zSql); + int nSql = sqlite3Strlen30(zSql); RenameToken *pToken; for(pToken=p->pRename; pToken; pToken=pToken->pNext){ assert( pToken->t.z>=zSql && &pToken->t.z[pToken->t.n]<=&zSql[nSql] ); @@ -109284,15 +109284,15 @@ static int renameParseSql( ** pCtx and an SQLite error code returned. */ static int renameEditSql( - tdsqlite3_context *pCtx, /* Return result here */ + sqlite3_context *pCtx, /* Return result here */ RenameCtx *pRename, /* Rename context */ const char *zSql, /* SQL statement to edit */ const char *zNew, /* New token text */ int bQuote /* True to always quote token */ ){ - int nNew = tdsqlite3Strlen30(zNew); - int nSql = tdsqlite3Strlen30(zSql); - tdsqlite3 *db = tdsqlite3_context_db_handle(pCtx); + int nNew = sqlite3Strlen30(zNew); + int nSql = sqlite3Strlen30(zSql); + sqlite3 *db = sqlite3_context_db_handle(pCtx); int rc = SQLITE_OK; char *zQuot; char *zOut; @@ -109303,11 +109303,11 @@ static int renameEditSql( ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to ** point to zQuot so that all substitutions are made using the ** quoted version of the new column name. */ - zQuot = tdsqlite3MPrintf(db, "\"%w\"", zNew); + zQuot = sqlite3MPrintf(db, "\"%w\"", zNew); if( zQuot==0 ){ return SQLITE_NOMEM; }else{ - nQuot = tdsqlite3Strlen30(zQuot); + nQuot = sqlite3Strlen30(zQuot); } if( bQuote ){ zNew = zQuot; @@ -109319,7 +109319,7 @@ static int renameEditSql( ** with the new column name. All that remains is to construct and ** return the edited SQL string. */ assert( nQuot>=nNew ); - zOut = tdsqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); + zOut = sqlite3DbMallocZero(db, nSql + pRename->nList*nQuot + 1); if( zOut ){ int nOut = nSql; memcpy(zOut, zSql, nSql); @@ -109329,7 +109329,7 @@ static int renameEditSql( u32 nReplace; const char *zReplace; - if( tdsqlite3IsIdChar(*pBest->t.z) ){ + if( sqlite3IsIdChar(*pBest->t.z) ){ nReplace = nNew; zReplace = zNew; }else{ @@ -109346,16 +109346,16 @@ static int renameEditSql( zOut[nOut] = '\0'; } memcpy(&zOut[iOff], zReplace, nReplace); - tdsqlite3DbFree(db, pBest); + sqlite3DbFree(db, pBest); } - tdsqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT); - tdsqlite3DbFree(db, zOut); + sqlite3_result_text(pCtx, zOut, -1, SQLITE_TRANSIENT); + sqlite3DbFree(db, zOut); }else{ rc = SQLITE_NOMEM; } - tdsqlite3_free(zQuot); + sqlite3_free(zQuot); return rc; } @@ -109366,7 +109366,7 @@ static int renameEditSql( ** message in the Parse object. */ static int renameResolveTrigger(Parse *pParse, const char *zDb){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Trigger *pNew = pParse->pNewTrigger; TriggerStep *pStep; NameContext sNC; @@ -109375,31 +109375,31 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; assert( pNew->pTabSchema ); - pParse->pTriggerTab = tdsqlite3FindTable(db, pNew->table, - db->aDb[tdsqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName + pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, + db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; /* ALWAYS() because if the table of the trigger does not exist, the ** error would have been hit before this point */ if( ALWAYS(pParse->pTriggerTab) ){ - rc = tdsqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); + rc = sqlite3ViewGetColumnNames(pParse, pParse->pTriggerTab); } /* Resolve symbols in WHEN clause */ if( rc==SQLITE_OK && pNew->pWhen ){ - rc = tdsqlite3ResolveExprNames(&sNC, pNew->pWhen); + rc = sqlite3ResolveExprNames(&sNC, pNew->pWhen); } for(pStep=pNew->step_list; rc==SQLITE_OK && pStep; pStep=pStep->pNext){ if( pStep->pSelect ){ - tdsqlite3SelectPrep(pParse, pStep->pSelect, &sNC); + sqlite3SelectPrep(pParse, pStep->pSelect, &sNC); if( pParse->nErr ) rc = pParse->rc; } if( rc==SQLITE_OK && pStep->zTarget ){ - Table *pTarget = tdsqlite3LocateTable(pParse, 0, pStep->zTarget, zDb); + Table *pTarget = sqlite3LocateTable(pParse, 0, pStep->zTarget, zDb); if( pTarget==0 ){ rc = SQLITE_ERROR; - }else if( SQLITE_OK==(rc = tdsqlite3ViewGetColumnNames(pParse, pTarget)) ){ + }else if( SQLITE_OK==(rc = sqlite3ViewGetColumnNames(pParse, pTarget)) ){ SrcList sSrc; memset(&sSrc, 0, sizeof(sSrc)); sSrc.nSrc = 1; @@ -109407,10 +109407,10 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){ sSrc.a[0].pTab = pTarget; sNC.pSrcList = &sSrc; if( pStep->pWhere ){ - rc = tdsqlite3ResolveExprNames(&sNC, pStep->pWhere); + rc = sqlite3ResolveExprNames(&sNC, pStep->pWhere); } if( rc==SQLITE_OK ){ - rc = tdsqlite3ResolveExprListNames(&sNC, pStep->pExprList); + rc = sqlite3ResolveExprListNames(&sNC, pStep->pExprList); } assert( !pStep->pUpsert || (!pStep->pWhere && !pStep->pExprList) ); if( pStep->pUpsert ){ @@ -109419,16 +109419,16 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){ pUpsert->pUpsertSrc = &sSrc; sNC.uNC.pUpsert = pUpsert; sNC.ncFlags = NC_UUpsert; - rc = tdsqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); if( rc==SQLITE_OK ){ ExprList *pUpsertSet = pUpsert->pUpsertSet; - rc = tdsqlite3ResolveExprListNames(&sNC, pUpsertSet); + rc = sqlite3ResolveExprListNames(&sNC, pUpsertSet); } if( rc==SQLITE_OK ){ - rc = tdsqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere); + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertWhere); } if( rc==SQLITE_OK ){ - rc = tdsqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); } sNC.ncFlags = 0; } @@ -109440,26 +109440,26 @@ static int renameResolveTrigger(Parse *pParse, const char *zDb){ } /* -** Invoke tdsqlite3WalkExpr() or tdsqlite3WalkSelect() on all Select or Expr +** Invoke sqlite3WalkExpr() or sqlite3WalkSelect() on all Select or Expr ** objects that are part of the trigger passed as the second argument. */ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ TriggerStep *pStep; /* Find tokens to edit in WHEN clause */ - tdsqlite3WalkExpr(pWalker, pTrigger->pWhen); + sqlite3WalkExpr(pWalker, pTrigger->pWhen); /* Find tokens to edit in trigger steps */ for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ - tdsqlite3WalkSelect(pWalker, pStep->pSelect); - tdsqlite3WalkExpr(pWalker, pStep->pWhere); - tdsqlite3WalkExprList(pWalker, pStep->pExprList); + sqlite3WalkSelect(pWalker, pStep->pSelect); + sqlite3WalkExpr(pWalker, pStep->pWhere); + sqlite3WalkExprList(pWalker, pStep->pExprList); if( pStep->pUpsert ){ Upsert *pUpsert = pStep->pUpsert; - tdsqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); - tdsqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); - tdsqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); - tdsqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); + sqlite3WalkExprList(pWalker, pUpsert->pUpsertTarget); + sqlite3WalkExprList(pWalker, pUpsert->pUpsertSet); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertWhere); + sqlite3WalkExpr(pWalker, pUpsert->pUpsertTargetWhere); } } } @@ -109469,20 +109469,20 @@ static void renameWalkTrigger(Walker *pWalker, Trigger *pTrigger){ ** occupied by the Parse object itself. */ static void renameParseCleanup(Parse *pParse){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Index *pIdx; if( pParse->pVdbe ){ - tdsqlite3VdbeFinalize(pParse->pVdbe); + sqlite3VdbeFinalize(pParse->pVdbe); } - tdsqlite3DeleteTable(db, pParse->pNewTable); + sqlite3DeleteTable(db, pParse->pNewTable); while( (pIdx = pParse->pNewIndex)!=0 ){ pParse->pNewIndex = pIdx->pNext; - tdsqlite3FreeIndex(db, pIdx); + sqlite3FreeIndex(db, pIdx); } - tdsqlite3DeleteTrigger(db, pParse->pNewTrigger); - tdsqlite3DbFree(db, pParse->zErrMsg); + sqlite3DeleteTrigger(db, pParse->pNewTrigger); + sqlite3DbFree(db, pParse->zErrMsg); renameTokenFree(db, pParse->pRename); - tdsqlite3ParserReset(pParse); + sqlite3ParserReset(pParse); } /* @@ -109505,23 +109505,23 @@ static void renameParseCleanup(Parse *pParse){ ** into zNew. The name should be quoted if bQuote is true. ** ** This function is used internally by the ALTER TABLE RENAME COLUMN command. -** It is only accessible to SQL created using tdsqlite3NestedParse(). It is -** not reachable from ordinary SQL passed into tdsqlite3_prepare(). +** It is only accessible to SQL created using sqlite3NestedParse(). It is +** not reachable from ordinary SQL passed into sqlite3_prepare(). */ static void renameColumnFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **argv + sqlite3_value **argv ){ - tdsqlite3 *db = tdsqlite3_context_db_handle(context); + sqlite3 *db = sqlite3_context_db_handle(context); RenameCtx sCtx; - const char *zSql = (const char*)tdsqlite3_value_text(argv[0]); - const char *zDb = (const char*)tdsqlite3_value_text(argv[3]); - const char *zTable = (const char*)tdsqlite3_value_text(argv[4]); - int iCol = tdsqlite3_value_int(argv[5]); - const char *zNew = (const char*)tdsqlite3_value_text(argv[6]); - int bQuote = tdsqlite3_value_int(argv[7]); - int bTemp = tdsqlite3_value_int(argv[8]); + const char *zSql = (const char*)sqlite3_value_text(argv[0]); + const char *zDb = (const char*)sqlite3_value_text(argv[3]); + const char *zTable = (const char*)sqlite3_value_text(argv[4]); + int iCol = sqlite3_value_int(argv[5]); + const char *zNew = (const char*)sqlite3_value_text(argv[6]); + int bQuote = sqlite3_value_int(argv[7]); + int bTemp = sqlite3_value_int(argv[8]); const char *zOld; int rc; Parse sParse; @@ -109530,7 +109530,7 @@ static void renameColumnFunc( int i; Table *pTab; #ifndef SQLITE_OMIT_AUTHORIZATION - tdsqlite3_xauth xAuth = db->xAuth; + sqlite3_xauth xAuth = db->xAuth; #endif UNUSED_PARAMETER(NotUsed); @@ -109538,10 +109538,10 @@ static void renameColumnFunc( if( zTable==0 ) return; if( zNew==0 ) return; if( iCol<0 ) return; - tdsqlite3BtreeEnterAll(db); - pTab = tdsqlite3FindTable(db, zTable, zDb); + sqlite3BtreeEnterAll(db); + pTab = sqlite3FindTable(db, zTable, zDb); if( pTab==0 || iCol>=pTab->nCol ){ - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); return; } zOld = pTab->aCol[iCol].zName; @@ -109567,15 +109567,15 @@ static void renameColumnFunc( if( pSelect ){ pSelect->selFlags &= ~SF_View; sParse.rc = SQLITE_OK; - tdsqlite3SelectPrep(&sParse, pSelect, 0); + sqlite3SelectPrep(&sParse, pSelect, 0); rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc); if( rc==SQLITE_OK ){ - tdsqlite3WalkSelect(&sWalker, pSelect); + sqlite3WalkSelect(&sWalker, pSelect); } if( rc!=SQLITE_OK ) goto renameColumnFunc_done; }else{ /* A regular table */ - int bFKOnly = tdsqlite3_stricmp(zTable, sParse.pNewTable->zName); + int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName); FKey *pFKey; assert( sParse.pNewTable->pSelect==0 ); sCtx.pTab = sParse.pNewTable; @@ -109586,17 +109586,17 @@ static void renameColumnFunc( if( sCtx.iCol<0 ){ renameTokenFind(&sParse, &sCtx, (void*)&sParse.pNewTable->iPKey); } - tdsqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); + sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); for(pIdx=sParse.pNewTable->pIndex; pIdx; pIdx=pIdx->pNext){ - tdsqlite3WalkExprList(&sWalker, pIdx->aColExpr); + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } for(pIdx=sParse.pNewIndex; pIdx; pIdx=pIdx->pNext){ - tdsqlite3WalkExprList(&sWalker, pIdx->aColExpr); + sqlite3WalkExprList(&sWalker, pIdx->aColExpr); } } #ifndef SQLITE_OMIT_GENERATED_COLUMNS for(i=0; inCol; i++){ - tdsqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); + sqlite3WalkExpr(&sWalker, sParse.pNewTable->aCol[i].pDflt); } #endif @@ -109605,8 +109605,8 @@ static void renameColumnFunc( if( bFKOnly==0 && pFKey->aCol[i].iFrom==iCol ){ renameTokenFind(&sParse, &sCtx, (void*)&pFKey->aCol[i]); } - if( 0==tdsqlite3_stricmp(pFKey->zTo, zTable) - && 0==tdsqlite3_stricmp(pFKey->aCol[i].zCol, zOld) + if( 0==sqlite3_stricmp(pFKey->zTo, zTable) + && 0==sqlite3_stricmp(pFKey->aCol[i].zCol, zOld) ){ renameTokenFind(&sParse, &sCtx, (void*)pFKey->aCol[i].zCol); } @@ -109614,8 +109614,8 @@ static void renameColumnFunc( } } }else if( sParse.pNewIndex ){ - tdsqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); - tdsqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + sqlite3WalkExprList(&sWalker, sParse.pNewIndex->aColExpr); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); }else{ /* A trigger */ TriggerStep *pStep; @@ -109624,7 +109624,7 @@ static void renameColumnFunc( for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){ if( pStep->zTarget ){ - Table *pTarget = tdsqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb); + Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb); if( pTarget==pTab ){ if( pStep->pUpsert ){ ExprList *pUpsertSet = pStep->pUpsert->pUpsertSet; @@ -109654,7 +109654,7 @@ renameColumnFunc_done: if( sParse.zErrMsg ){ renameColumnParseError(context, 0, argv[1], argv[2], &sParse); }else{ - tdsqlite3_result_error_code(context, rc); + sqlite3_result_error_code(context, rc); } } @@ -109663,7 +109663,7 @@ renameColumnFunc_done: #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; #endif - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); } /* @@ -109721,16 +109721,16 @@ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ ** -> 'CREATE TABLE t1(a REFERENCES t3)' */ static void renameTableFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **argv -){ - tdsqlite3 *db = tdsqlite3_context_db_handle(context); - const char *zDb = (const char*)tdsqlite3_value_text(argv[0]); - const char *zInput = (const char*)tdsqlite3_value_text(argv[3]); - const char *zOld = (const char*)tdsqlite3_value_text(argv[4]); - const char *zNew = (const char*)tdsqlite3_value_text(argv[5]); - int bTemp = tdsqlite3_value_int(argv[6]); + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + const char *zDb = (const char*)sqlite3_value_text(argv[0]); + const char *zInput = (const char*)sqlite3_value_text(argv[3]); + const char *zOld = (const char*)sqlite3_value_text(argv[4]); + const char *zNew = (const char*)sqlite3_value_text(argv[5]); + int bTemp = sqlite3_value_int(argv[6]); UNUSED_PARAMETER(NotUsed); if( zInput && zOld && zNew ){ @@ -109741,14 +109741,14 @@ static void renameTableFunc( Walker sWalker; #ifndef SQLITE_OMIT_AUTHORIZATION - tdsqlite3_xauth xAuth = db->xAuth; + sqlite3_xauth xAuth = db->xAuth; db->xAuth = 0; #endif - tdsqlite3BtreeEnterAll(db); + sqlite3BtreeEnterAll(db); memset(&sCtx, 0, sizeof(RenameCtx)); - sCtx.pTab = tdsqlite3FindTable(db, zOld, zDb); + sCtx.pTab = sqlite3FindTable(db, zOld, zDb); memset(&sWalker, 0, sizeof(Walker)); sWalker.pParse = &sParse; sWalker.xExprCallback = renameTableExprCb; @@ -109771,11 +109771,11 @@ static void renameTableFunc( assert( pSelect->selFlags & SF_View ); pSelect->selFlags &= ~SF_View; - tdsqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); + sqlite3SelectPrep(&sParse, pTab->pSelect, &sNC); if( sParse.nErr ){ rc = sParse.rc; }else{ - tdsqlite3WalkSelect(&sWalker, pTab->pSelect); + sqlite3WalkSelect(&sWalker, pTab->pSelect); } } }else{ @@ -109784,7 +109784,7 @@ static void renameTableFunc( if( isLegacy==0 || (db->flags & SQLITE_ForeignKeys) ){ FKey *pFKey; for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ - if( tdsqlite3_stricmp(pFKey->zTo, zOld)==0 ){ + if( sqlite3_stricmp(pFKey->zTo, zOld)==0 ){ renameTokenFind(&sParse, &sCtx, (void*)pFKey->zTo); } } @@ -109794,10 +109794,10 @@ static void renameTableFunc( /* If this is the table being altered, fix any table refs in CHECK ** expressions. Also update the name that appears right after the ** "CREATE [VIRTUAL] TABLE" bit. */ - if( tdsqlite3_stricmp(zOld, pTab->zName)==0 ){ + if( sqlite3_stricmp(zOld, pTab->zName)==0 ){ sCtx.pTab = pTab; if( isLegacy==0 ){ - tdsqlite3WalkExprList(&sWalker, pTab->pCheck); + sqlite3WalkExprList(&sWalker, pTab->pCheck); } renameTokenFind(&sParse, &sCtx, pTab->zName); } @@ -109807,7 +109807,7 @@ static void renameTableFunc( else if( sParse.pNewIndex ){ renameTokenFind(&sParse, &sCtx, sParse.pNewIndex->zName); if( isLegacy==0 ){ - tdsqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); + sqlite3WalkExpr(&sWalker, sParse.pNewIndex->pPartIdxWhere); } } @@ -109815,7 +109815,7 @@ static void renameTableFunc( else{ Trigger *pTrigger = sParse.pNewTrigger; TriggerStep *pStep; - if( 0==tdsqlite3_stricmp(sParse.pNewTrigger->table, zOld) + if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) && sCtx.pTab->pSchema==pTrigger->pTabSchema ){ renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); @@ -109826,7 +109826,7 @@ static void renameTableFunc( if( rc==SQLITE_OK ){ renameWalkTrigger(&sWalker, pTrigger); for(pStep=pTrigger->step_list; pStep; pStep=pStep->pNext){ - if( pStep->zTarget && 0==tdsqlite3_stricmp(pStep->zTarget, zOld) ){ + if( pStep->zTarget && 0==sqlite3_stricmp(pStep->zTarget, zOld) ){ renameTokenFind(&sParse, &sCtx, pStep->zTarget); } } @@ -109843,13 +109843,13 @@ static void renameTableFunc( if( sParse.zErrMsg ){ renameColumnParseError(context, 0, argv[1], argv[2], &sParse); }else{ - tdsqlite3_result_error_code(context, rc); + sqlite3_result_error_code(context, rc); } } renameParseCleanup(&sParse); renameTokenFree(db, sCtx.pList); - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; #endif @@ -109878,18 +109878,18 @@ static void renameTableFunc( ** * the table that the trigger is attached to is in database zDb. */ static void renameTableTest( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **argv + sqlite3_value **argv ){ - tdsqlite3 *db = tdsqlite3_context_db_handle(context); - char const *zDb = (const char*)tdsqlite3_value_text(argv[0]); - char const *zInput = (const char*)tdsqlite3_value_text(argv[1]); - int bTemp = tdsqlite3_value_int(argv[4]); + sqlite3 *db = sqlite3_context_db_handle(context); + char const *zDb = (const char*)sqlite3_value_text(argv[0]); + char const *zInput = (const char*)sqlite3_value_text(argv[1]); + int bTemp = sqlite3_value_int(argv[4]); int isLegacy = (db->flags & SQLITE_LegacyAlter); #ifndef SQLITE_OMIT_AUTHORIZATION - tdsqlite3_xauth xAuth = db->xAuth; + sqlite3_xauth xAuth = db->xAuth; db->xAuth = 0; #endif @@ -109903,7 +109903,7 @@ static void renameTableTest( NameContext sNC; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = &sParse; - tdsqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC); + sqlite3SelectPrep(&sParse, sParse.pNewTable->pSelect, &sNC); if( sParse.nErr ) rc = sParse.rc; } @@ -109912,9 +109912,9 @@ static void renameTableTest( rc = renameResolveTrigger(&sParse, bTemp ? 0 : zDb); } if( rc==SQLITE_OK ){ - int i1 = tdsqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); - int i2 = tdsqlite3FindDbName(db, zDb); - if( i1==i2 ) tdsqlite3_result_int(context, 1); + int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema); + int i2 = sqlite3FindDbName(db, zDb); + if( i1==i2 ) sqlite3_result_int(context, 1); } } } @@ -109933,13 +109933,13 @@ static void renameTableTest( /* ** Register built-in functions used to help implement ALTER TABLE */ -SQLITE_PRIVATE void tdsqlite3AlterFunctions(void){ +SQLITE_PRIVATE void sqlite3AlterFunctions(void){ static FuncDef aAlterTableFuncs[] = { INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc), INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc), INTERNAL_FUNCTION(sqlite_rename_test, 5, renameTableTest), }; - tdsqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); + sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs)); } #endif /* SQLITE_ALTER_TABLE */ @@ -110130,15 +110130,15 @@ static void openStatTable( { "sqlite_stat3", 0 }, }; int i; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Db *pDb; - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); int aRoot[ArraySize(aTable)]; u8 aCreateTbl[ArraySize(aTable)]; if( v==0 ) return; - assert( tdsqlite3BtreeHoldsAllMutexes(db) ); - assert( tdsqlite3VdbeDb(v)==db ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3VdbeDb(v)==db ); pDb = &db->aDb[iDb]; /* Create new statistic tables if they do not exist, or clear them @@ -110147,13 +110147,13 @@ static void openStatTable( for(i=0; izDbSName))==0 ){ + if( (pStat = sqlite3FindTable(db, zTab, pDb->zDbSName))==0 ){ if( aTable[i].zCols ){ /* The sqlite_statN table does not exist. Create it. Note that a ** side-effect of the CREATE TABLE statement is to leave the rootpage ** of the new table in register pParse->regRoot. This is important ** because the OpenWrite opcode below will be needing it. */ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "CREATE TABLE %Q.%s(%s)", pDb->zDbSName, zTab, aTable[i].zCols ); aRoot[i] = pParse->regRoot; @@ -110165,19 +110165,19 @@ static void openStatTable( ** entire contents of the table. */ aRoot[i] = pStat->tnum; aCreateTbl[i] = 0; - tdsqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); + sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); if( zWhere ){ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zDbSName, zTab, zWhereType, zWhere ); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK }else if( db->xPreUpdateCallback ){ - tdsqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab); + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab); #endif }else{ /* The sqlite_stat[134] table already exists. Delete all rows. */ - tdsqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); + sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); } } } @@ -110185,8 +110185,8 @@ static void openStatTable( /* Open the sqlite_stat[134] tables for writing. */ for(i=0; aTable[i].zCols; i++){ assert( inRowid ){ - tdsqlite3DbFree(db, p->u.aRowid); + sqlite3DbFree(db, p->u.aRowid); p->nRowid = 0; } } @@ -110252,10 +110252,10 @@ static void sampleClear(tdsqlite3 *db, Stat4Sample *p){ /* Initialize the BLOB value of a ROWID */ #ifdef SQLITE_ENABLE_STAT4 -static void sampleSetRowid(tdsqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ +static void sampleSetRowid(sqlite3 *db, Stat4Sample *p, int n, const u8 *pData){ assert( db!=0 ); - if( p->nRowid ) tdsqlite3DbFree(db, p->u.aRowid); - p->u.aRowid = tdsqlite3DbMallocRawNN(db, n); + if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); + p->u.aRowid = sqlite3DbMallocRawNN(db, n); if( p->u.aRowid ){ p->nRowid = n; memcpy(p->u.aRowid, pData, n); @@ -110268,9 +110268,9 @@ static void sampleSetRowid(tdsqlite3 *db, Stat4Sample *p, int n, const u8 *pData /* Initialize the INTEGER value of a ROWID. */ #ifdef SQLITE_ENABLE_STAT4 -static void sampleSetRowidInt64(tdsqlite3 *db, Stat4Sample *p, i64 iRowid){ +static void sampleSetRowidInt64(sqlite3 *db, Stat4Sample *p, i64 iRowid){ assert( db!=0 ); - if( p->nRowid ) tdsqlite3DbFree(db, p->u.aRowid); + if( p->nRowid ) sqlite3DbFree(db, p->u.aRowid); p->nRowid = 0; p->u.iRowid = iRowid; } @@ -110307,7 +110307,7 @@ static void stat4Destructor(void *pOld){ for(i=0; imxSample; i++) sampleClear(p->db, p->a+i); sampleClear(p->db, &p->current); #endif - tdsqlite3DbFree(p->db, p); + sqlite3DbFree(p->db, p); } /* @@ -110334,26 +110334,26 @@ static void stat4Destructor(void *pOld){ ** object. */ static void statInit( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ Stat4Accum *p; int nCol; /* Number of columns in index being sampled */ int nKeyCol; /* Number of key columns */ int nColUp; /* nCol rounded up for alignment */ int n; /* Bytes of space to allocate */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ #ifdef SQLITE_ENABLE_STAT4 int mxSample = SQLITE_STAT4_SAMPLES; #endif /* Decode the three function arguments */ UNUSED_PARAMETER(argc); - nCol = tdsqlite3_value_int(argv[0]); + nCol = sqlite3_value_int(argv[0]); assert( nCol>0 ); nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; - nKeyCol = tdsqlite3_value_int(argv[1]); + nKeyCol = sqlite3_value_int(argv[1]); assert( nKeyCol<=nCol ); assert( nKeyCol>0 ); @@ -110367,10 +110367,10 @@ static void statInit( + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) #endif ; - db = tdsqlite3_context_db_handle(context); - p = tdsqlite3DbMallocZero(db, n); + db = sqlite3_context_db_handle(context); + p = sqlite3DbMallocZero(db, n); if( p==0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); return; } @@ -110388,9 +110388,9 @@ static void statInit( p->iGet = -1; p->mxSample = mxSample; - p->nPSample = (tRowcnt)(tdsqlite3_value_int64(argv[2])/(mxSample/3+1) + 1); + p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[2])/(mxSample/3+1) + 1); p->current.anLt = &p->current.anEq[nColUp]; - p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)tdsqlite3_value_int(argv[2]); + p->iPrn = 0x689e962d*(u32)nCol ^ 0xd0944565*(u32)sqlite3_value_int(argv[2]); /* Set up the Stat4Accum.a[] and aBest[] arrays */ p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; @@ -110413,7 +110413,7 @@ static void statInit( ** only the pointer (the 2nd parameter) matters. The size of the object ** (given by the 3rd parameter) is never used and can be any positive ** value. */ - tdsqlite3_result_blob(context, p, sizeof(*p), stat4Destructor); + sqlite3_result_blob(context, p, sizeof(*p), stat4Destructor); } static const FuncDef statInitFuncdef = { 2+IsStat4, /* nArg */ @@ -110633,15 +110633,15 @@ static void samplePushPrevious(Stat4Accum *p, int iChng){ ** The R parameter is only used for STAT4 */ static void statPush( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ int i; /* The three function arguments */ - Stat4Accum *p = (Stat4Accum*)tdsqlite3_value_blob(argv[0]); - int iChng = tdsqlite3_value_int(argv[1]); + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); + int iChng = sqlite3_value_int(argv[1]); UNUSED_PARAMETER( argc ); UNUSED_PARAMETER( context ); @@ -110670,11 +110670,11 @@ static void statPush( } p->nRow++; #ifdef SQLITE_ENABLE_STAT4 - if( tdsqlite3_value_type(argv[2])==SQLITE_INTEGER ){ - sampleSetRowidInt64(p->db, &p->current, tdsqlite3_value_int64(argv[2])); + if( sqlite3_value_type(argv[2])==SQLITE_INTEGER ){ + sampleSetRowidInt64(p->db, &p->current, sqlite3_value_int64(argv[2])); }else{ - sampleSetRowid(p->db, &p->current, tdsqlite3_value_bytes(argv[2]), - tdsqlite3_value_blob(argv[2])); + sampleSetRowid(p->db, &p->current, sqlite3_value_bytes(argv[2]), + sqlite3_value_blob(argv[2])); } p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; #endif @@ -110739,14 +110739,14 @@ static const FuncDef statPushFuncdef = { ** stat1 table entry information. */ static void statGet( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ - Stat4Accum *p = (Stat4Accum*)tdsqlite3_value_blob(argv[0]); + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); #ifdef SQLITE_ENABLE_STAT4 /* STAT4 has a parameter on this routine. */ - int eCall = tdsqlite3_value_int(argv[1]); + int eCall = sqlite3_value_int(argv[1]); assert( argc==2 ); assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT @@ -110781,24 +110781,24 @@ static void statGet( char *z; int i; - char *zRet = tdsqlite3MallocZero( (p->nKeyCol+1)*25 ); + char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 ); if( zRet==0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); return; } - tdsqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow); - z = zRet + tdsqlite3Strlen30(zRet); + sqlite3_snprintf(24, zRet, "%llu", (u64)p->nRow); + z = zRet + sqlite3Strlen30(zRet); for(i=0; inKeyCol; i++){ u64 nDistinct = p->current.anDLt[i] + 1; u64 iVal = (p->nRow + nDistinct - 1) / nDistinct; - tdsqlite3_snprintf(24, z, " %llu", iVal); - z += tdsqlite3Strlen30(z); + sqlite3_snprintf(24, z, " %llu", iVal); + z += sqlite3Strlen30(z); assert( p->current.anEq[i] ); } assert( z[0]=='\0' && z>zRet ); - tdsqlite3_result_text(context, zRet, -1, tdsqlite3_free); + sqlite3_result_text(context, zRet, -1, sqlite3_free); } #ifdef SQLITE_ENABLE_STAT4 else if( eCall==STAT_GET_ROWID ){ @@ -110809,9 +110809,9 @@ static void statGet( if( p->iGetnSample ){ Stat4Sample *pS = p->a + p->iGet; if( pS->nRowid==0 ){ - tdsqlite3_result_int64(context, pS->u.iRowid); + sqlite3_result_int64(context, pS->u.iRowid); }else{ - tdsqlite3_result_blob(context, pS->u.aRowid, pS->nRowid, + sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid, SQLITE_TRANSIENT); } } @@ -110830,19 +110830,19 @@ static void statGet( } { - char *zRet = tdsqlite3MallocZero(p->nCol * 25); + char *zRet = sqlite3MallocZero(p->nCol * 25); if( zRet==0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); }else{ int i; char *z = zRet; for(i=0; inCol; i++){ - tdsqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]); - z += tdsqlite3Strlen30(z); + sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]); + z += sqlite3Strlen30(z); } assert( z[0]=='\0' && z>zRet ); z[-1] = '\0'; - tdsqlite3_result_text(context, zRet, -1, tdsqlite3_free); + sqlite3_result_text(context, zRet, -1, sqlite3_free); } } } @@ -110865,14 +110865,14 @@ static const FuncDef statGetFuncdef = { static void callStatGet(Parse *pParse, int regStat4, int iParam, int regOut){ #ifdef SQLITE_ENABLE_STAT4 - tdsqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1); + sqlite3VdbeAddOp2(pParse->pVdbe, OP_Integer, iParam, regStat4+1); #elif SQLITE_DEBUG assert( iParam==STAT_GET_STAT1 ); #else UNUSED_PARAMETER( iParam ); #endif assert( regOut!=regStat4 && regOut!=regStat4+1 ); - tdsqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4, + sqlite3VdbeAddFunctionCall(pParse, 0, regStat4, regOut, 1+IsStat4, &statGetFuncdef, 0); } @@ -110888,7 +110888,7 @@ static void analyzeOneTable( int iMem, /* Available memory locations begin here */ int iTab /* Next available cursor */ ){ - tdsqlite3 *db = pParse->db; /* Database handle */ + sqlite3 *db = pParse->db; /* Database handle */ Index *pIdx; /* An index to being analyzed */ int iIdxCur; /* Cursor open on index being analyzed */ int iTabCur; /* Table cursor */ @@ -110913,7 +110913,7 @@ static void analyzeOneTable( #endif pParse->nMem = MAX(pParse->nMem, iMem); - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v==0 || NEVER(pTab==0) ){ return; } @@ -110921,16 +110921,16 @@ static void analyzeOneTable( /* Do not gather statistics on views or virtual tables */ return; } - if( tdsqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){ + if( sqlite3_strlike("sqlite\\_%", pTab->zName, '\\')==0 ){ /* Do not gather statistics on system tables */ return; } - assert( tdsqlite3BtreeHoldsAllMutexes(db) ); - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); #ifndef SQLITE_OMIT_AUTHORIZATION - if( tdsqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, + if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, db->aDb[iDb].zDbSName ) ){ return; } @@ -110938,13 +110938,13 @@ static void analyzeOneTable( #ifdef SQLITE_ENABLE_PREUPDATE_HOOK if( db->xPreUpdateCallback ){ - pStat1 = (Table*)tdsqlite3DbMallocZero(db, sizeof(Table) + 13); + pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13); if( pStat1==0 ) return; pStat1->zName = (char*)&pStat1[1]; memcpy(pStat1->zName, "sqlite_stat1", 13); pStat1->nCol = 3; pStat1->iPKey = -1; - tdsqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB); + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB); } #endif @@ -110952,12 +110952,12 @@ static void analyzeOneTable( ** Open a read-only cursor on the table. Also allocate a cursor number ** to use for scanning indexes (iIdxCur). No index cursor is opened at ** this time though. */ - tdsqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); iTabCur = iTab++; iIdxCur = iTab++; pParse->nTab = MAX(pParse->nTab, iTab); - tdsqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); - tdsqlite3VdbeLoadString(v, regTabname, pTab->zName); + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeLoadString(v, regTabname, pTab->zName); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int nCol; /* Number of columns in pIdx. "N" */ @@ -110979,7 +110979,7 @@ static void analyzeOneTable( } /* Populate the register containing the index name. */ - tdsqlite3VdbeLoadString(v, regIdxname, zIdxName); + sqlite3VdbeLoadString(v, regIdxname, zIdxName); VdbeComment((v, "Analysis for %s.%s", pTab->zName, zIdxName)); /* @@ -111021,9 +111021,9 @@ static void analyzeOneTable( pParse->nMem = MAX(pParse->nMem, regPrev+nColTest); /* Open a read-only cursor on the index being analyzed. */ - assert( iDb==tdsqlite3SchemaToIndex(db, pIdx->pSchema) ); - tdsqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); - tdsqlite3VdbeSetP4KeyInfo(pParse, pIdx); + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "%s", pIdx->zName)); /* Invoke the stat_init() function. The arguments are: @@ -111037,11 +111037,11 @@ static void analyzeOneTable( ** The third argument is only used for STAT4 */ #ifdef SQLITE_ENABLE_STAT4 - tdsqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+3); #endif - tdsqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); - tdsqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); - tdsqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4, + sqlite3VdbeAddOp2(v, OP_Integer, nCol, regStat4+1); + sqlite3VdbeAddOp2(v, OP_Integer, pIdx->nKeyCol, regStat4+2); + sqlite3VdbeAddFunctionCall(pParse, 0, regStat4+1, regStat4, 2+IsStat4, &statInitFuncdef, 0); /* Implementation of the following: @@ -111052,15 +111052,15 @@ static void analyzeOneTable( ** goto next_push_0; ** */ - addrRewind = tdsqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); + addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); VdbeCoverage(v); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); - addrNextRow = tdsqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); + addrNextRow = sqlite3VdbeCurrentAddr(v); if( nColTest>0 ){ - int endDistinctTest = tdsqlite3VdbeMakeLabel(pParse); + int endDistinctTest = sqlite3VdbeMakeLabel(pParse); int *aGotoChng; /* Array of jump instruction addresses */ - aGotoChng = tdsqlite3DbMallocRawNN(db, sizeof(int)*nColTest); + aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest); if( aGotoChng==0 ) continue; /* @@ -111073,26 +111073,26 @@ static void analyzeOneTable( ** regChng = N ** goto endDistinctTest */ - tdsqlite3VdbeAddOp0(v, OP_Goto); - addrNextRow = tdsqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp0(v, OP_Goto); + addrNextRow = sqlite3VdbeCurrentAddr(v); if( nColTest==1 && pIdx->nKeyCol==1 && IsUniqueIndex(pIdx) ){ /* For a single-column UNIQUE index, once we have found a non-NULL ** row, we know that all the rest will be distinct, so skip ** subsequent distinctness tests. */ - tdsqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); + sqlite3VdbeAddOp2(v, OP_NotNull, regPrev, endDistinctTest); VdbeCoverage(v); } for(i=0; iazColl[i]); - tdsqlite3VdbeAddOp2(v, OP_Integer, i, regChng); - tdsqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); + char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); aGotoChng[i] = - tdsqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); - tdsqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); VdbeCoverage(v); } - tdsqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); - tdsqlite3VdbeGoto(v, endDistinctTest); + sqlite3VdbeAddOp2(v, OP_Integer, nColTest, regChng); + sqlite3VdbeGoto(v, endDistinctTest); /* @@ -111102,13 +111102,13 @@ static void analyzeOneTable( ** regPrev(1) = idx(1) ** ... */ - tdsqlite3VdbeJumpHere(v, addrNextRow-1); + sqlite3VdbeJumpHere(v, addrNextRow-1); for(i=0; ipTable); + Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); int j, k, regKey; - regKey = tdsqlite3GetTempRange(pParse, pPk->nKeyCol); + regKey = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; jnKeyCol; j++){ - k = tdsqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); assert( k>=0 && knColumn ); - tdsqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, regKey+j); VdbeComment((v, "%s", pTab->aCol[pPk->aiColumn[j]].zName)); } - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); - tdsqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regKey, pPk->nKeyCol, regRowid); + sqlite3ReleaseTempRange(pParse, regKey, pPk->nKeyCol); } #endif assert( regChng==(regStat4+1) ); - tdsqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4, + sqlite3VdbeAddFunctionCall(pParse, 1, regStat4, regTemp, 2+IsStat4, &statPushFuncdef, 0); - tdsqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); VdbeCoverage(v); /* Add the entry to the stat1 table. */ callStatGet(pParse, regStat4, STAT_GET_STAT1, regStat1); assert( "BBB"[0]==SQLITE_AFF_TEXT ); - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); - tdsqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); - tdsqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - tdsqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); + sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); #endif - tdsqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); /* Add the entries to the stat4 table. */ #ifdef SQLITE_ENABLE_STAT4 @@ -111167,29 +111167,29 @@ static void analyzeOneTable( pParse->nMem = MAX(pParse->nMem, regCol+nCol); - addrNext = tdsqlite3VdbeCurrentAddr(v); + addrNext = sqlite3VdbeCurrentAddr(v); callStatGet(pParse, regStat4, STAT_GET_ROWID, regSampleRowid); - addrIsNull = tdsqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); VdbeCoverage(v); callStatGet(pParse, regStat4, STAT_GET_NEQ, regEq); callStatGet(pParse, regStat4, STAT_GET_NLT, regLt); callStatGet(pParse, regStat4, STAT_GET_NDLT, regDLt); - tdsqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); + sqlite3VdbeAddOp4Int(v, seekOp, iTabCur, addrNext, regSampleRowid, 0); VdbeCoverage(v); for(i=0; izName)); - tdsqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); - jZeroRows = tdsqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v); - tdsqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); + sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); + jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); assert( "BBB"[0]==SQLITE_AFF_TEXT ); - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); - tdsqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); - tdsqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); - tdsqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - tdsqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); + sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE); #endif - tdsqlite3VdbeJumpHere(v, jZeroRows); + sqlite3VdbeJumpHere(v, jZeroRows); } } @@ -111219,9 +111219,9 @@ static void analyzeOneTable( ** be loaded into internal hash tables where is can be used. */ static void loadAnalysis(Parse *pParse, int iDb){ - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); if( v ){ - tdsqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); + sqlite3VdbeAddOp1(v, OP_LoadAnalysis, iDb); } } @@ -111229,20 +111229,20 @@ static void loadAnalysis(Parse *pParse, int iDb){ ** Generate code that will do an analysis of an entire database */ static void analyzeDatabase(Parse *pParse, int iDb){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ HashElem *k; int iStatCur; int iMem; int iTab; - tdsqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab; pParse->nTab += 3; openStatTable(pParse, iDb, iStatCur, 0, 0); iMem = pParse->nMem+1; iTab = pParse->nTab; - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ Table *pTab = (Table*)sqliteHashData(k); analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); @@ -111260,9 +111260,9 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ int iStatCur; assert( pTab!=0 ); - assert( tdsqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = tdsqlite3SchemaToIndex(pParse->db, pTab->pSchema); - tdsqlite3BeginWriteOperation(pParse, 0, iDb); + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); iStatCur = pParse->nTab; pParse->nTab += 3; if( pOnlyIdx ){ @@ -111286,8 +111286,8 @@ static void analyzeTable(Parse *pParse, Table *pTab, Index *pOnlyIdx){ ** Form 2 analyzes all indices the single database named. ** Form 3 analyzes all indices associated with the named table. */ -SQLITE_PRIVATE void tdsqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE void sqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2){ + sqlite3 *db = pParse->db; int iDb; int i; char *z, *zDb; @@ -111298,8 +111298,8 @@ SQLITE_PRIVATE void tdsqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2 /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ - assert( tdsqlite3BtreeHoldsAllMutexes(pParse->db) ); - if( SQLITE_OK!=tdsqlite3ReadSchema(pParse) ){ + assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ return; } @@ -111310,27 +111310,27 @@ SQLITE_PRIVATE void tdsqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2 if( i==1 ) continue; /* Do not analyze the TEMP database */ analyzeDatabase(pParse, i); } - }else if( pName2->n==0 && (iDb = tdsqlite3FindDb(db, pName1))>=0 ){ + }else if( pName2->n==0 && (iDb = sqlite3FindDb(db, pName1))>=0 ){ /* Analyze the schema named as the argument */ analyzeDatabase(pParse, iDb); }else{ /* Form 3: Analyze the table or index named as an argument */ - iDb = tdsqlite3TwoPartName(pParse, pName1, pName2, &pTableName); + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pTableName); if( iDb>=0 ){ zDb = pName2->n ? db->aDb[iDb].zDbSName : 0; - z = tdsqlite3NameFromToken(db, pTableName); + z = sqlite3NameFromToken(db, pTableName); if( z ){ - if( (pIdx = tdsqlite3FindIndex(db, z, zDb))!=0 ){ + if( (pIdx = sqlite3FindIndex(db, z, zDb))!=0 ){ analyzeTable(pParse, pIdx->pTable, pIdx); - }else if( (pTab = tdsqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ + }else if( (pTab = sqlite3LocateTable(pParse, 0, z, zDb))!=0 ){ analyzeTable(pParse, pTab, 0); } - tdsqlite3DbFree(db, z); + sqlite3DbFree(db, z); } } } - if( db->nSqlExec==0 && (v = tdsqlite3GetVdbe(pParse))!=0 ){ - tdsqlite3VdbeAddOp0(v, OP_Expire); + if( db->nSqlExec==0 && (v = sqlite3GetVdbe(pParse))!=0 ){ + sqlite3VdbeAddOp0(v, OP_Expire); } } @@ -111340,7 +111340,7 @@ SQLITE_PRIVATE void tdsqlite3Analyze(Parse *pParse, Token *pName1, Token *pName2 */ typedef struct analysisInfo analysisInfo; struct analysisInfo { - tdsqlite3 *db; + sqlite3 *db; const char *zDatabase; }; @@ -111374,12 +111374,12 @@ static void decodeIntArray( } #ifdef SQLITE_ENABLE_STAT4 if( aOut ) aOut[i] = v; - if( aLog ) aLog[i] = tdsqlite3LogEst(v); + if( aLog ) aLog[i] = sqlite3LogEst(v); #else assert( aOut==0 ); UNUSED_PARAMETER(aOut); assert( aLog!=0 ); - aLog[i] = tdsqlite3LogEst(v); + aLog[i] = sqlite3LogEst(v); #endif if( *z==' ' ) z++; } @@ -111391,18 +111391,18 @@ static void decodeIntArray( pIndex->bUnordered = 0; pIndex->noSkipScan = 0; while( z[0] ){ - if( tdsqlite3_strglob("unordered*", z)==0 ){ + if( sqlite3_strglob("unordered*", z)==0 ){ pIndex->bUnordered = 1; - }else if( tdsqlite3_strglob("sz=[0-9]*", z)==0 ){ - int sz = tdsqlite3Atoi(z+3); + }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ + int sz = sqlite3Atoi(z+3); if( sz<2 ) sz = 2; - pIndex->szIdxRow = tdsqlite3LogEst(sz); - }else if( tdsqlite3_strglob("noskipscan*", z)==0 ){ + pIndex->szIdxRow = sqlite3LogEst(sz); + }else if( sqlite3_strglob("noskipscan*", z)==0 ){ pIndex->noSkipScan = 1; } #ifdef SQLITE_ENABLE_COSTMULT - else if( tdsqlite3_strglob("costmult=[0-9]*",z)==0 ){ - pIndex->pTable->costMult = tdsqlite3LogEst(tdsqlite3Atoi(z+9)); + else if( sqlite3_strglob("costmult=[0-9]*",z)==0 ){ + pIndex->pTable->costMult = sqlite3LogEst(sqlite3Atoi(z+9)); } #endif while( z[0]!=0 && z[0]!=' ' ) z++; @@ -111434,16 +111434,16 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ if( argv==0 || argv[0]==0 || argv[2]==0 ){ return 0; } - pTable = tdsqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); + pTable = sqlite3FindTable(pInfo->db, argv[0], pInfo->zDatabase); if( pTable==0 ){ return 0; } if( argv[1]==0 ){ pIndex = 0; - }else if( tdsqlite3_stricmp(argv[0],argv[1])==0 ){ - pIndex = tdsqlite3PrimaryKeyIndex(pTable); + }else if( sqlite3_stricmp(argv[0],argv[1])==0 ){ + pIndex = sqlite3PrimaryKeyIndex(pTable); }else{ - pIndex = tdsqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); + pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); } z = argv[2]; @@ -111455,8 +111455,8 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ ** sqlite_stat1 entries for this index. In that case just clobber ** the old data with the new instead of allocating a new array. */ if( pIndex->aiRowEst==0 ){ - pIndex->aiRowEst = (tRowcnt*)tdsqlite3MallocZero(sizeof(tRowcnt) * nCol); - if( pIndex->aiRowEst==0 ) tdsqlite3OomFault(pInfo->db); + pIndex->aiRowEst = (tRowcnt*)sqlite3MallocZero(sizeof(tRowcnt) * nCol); + if( pIndex->aiRowEst==0 ) sqlite3OomFault(pInfo->db); } aiRowEst = pIndex->aiRowEst; #endif @@ -111485,15 +111485,15 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ ** If the Index.aSample variable is not NULL, delete the aSample[] array ** and its contents. */ -SQLITE_PRIVATE void tdsqlite3DeleteIndexSamples(tdsqlite3 *db, Index *pIdx){ +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ #ifdef SQLITE_ENABLE_STAT4 if( pIdx->aSample ){ int j; for(j=0; jnSample; j++){ IndexSample *p = &pIdx->aSample[j]; - tdsqlite3DbFree(db, p->p); + sqlite3DbFree(db, p->p); } - tdsqlite3DbFree(db, pIdx->aSample); + sqlite3DbFree(db, pIdx->aSample); } if( db && db->pnBytesFreed==0 ){ pIdx->nSample = 0; @@ -111570,14 +111570,14 @@ static void initAvgEq(Index *pIdx){ ** is supplied instead, find the PRIMARY KEY index for that table. */ static Index *findIndexOrPrimaryKey( - tdsqlite3 *db, + sqlite3 *db, const char *zName, const char *zDb ){ - Index *pIdx = tdsqlite3FindIndex(db, zName, zDb); + Index *pIdx = sqlite3FindIndex(db, zName, zDb); if( pIdx==0 ){ - Table *pTab = tdsqlite3FindTable(db, zName, zDb); - if( pTab && !HasRowid(pTab) ) pIdx = tdsqlite3PrimaryKeyIndex(pTab); + Table *pTab = sqlite3FindTable(db, zName, zDb); + if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab); } return pIdx; } @@ -111595,27 +111595,27 @@ static Index *findIndexOrPrimaryKey( ** where %Q is replaced with the database name before the SQL is executed. */ static int loadStatTbl( - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ const char *zSql1, /* SQL statement 1 (see above) */ const char *zSql2, /* SQL statement 2 (see above) */ const char *zDb /* Database name (e.g. "main") */ ){ int rc; /* Result codes from subroutines */ - tdsqlite3_stmt *pStmt = 0; /* An SQL statement being run */ + sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ char *zSql; /* Text of the SQL statement */ Index *pPrevIdx = 0; /* Previous index in the loop */ IndexSample *pSample; /* A slot in pIdx->aSample[] */ assert( db->lookaside.bDisable ); - zSql = tdsqlite3MPrintf(db, zSql1, zDb); + zSql = sqlite3MPrintf(db, zSql1, zDb); if( !zSql ){ return SQLITE_NOMEM_BKPT; } - rc = tdsqlite3_prepare(db, zSql, -1, &pStmt, 0); - tdsqlite3DbFree(db, zSql); + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); if( rc ) return rc; - while( tdsqlite3_step(pStmt)==SQLITE_ROW ){ + while( sqlite3_step(pStmt)==SQLITE_ROW ){ int nIdxCol = 1; /* Number of columns in stat4 records */ char *zIndex; /* Index name */ @@ -111625,9 +111625,9 @@ static int loadStatTbl( int i; /* Bytes of space required */ tRowcnt *pSpace; - zIndex = (char *)tdsqlite3_column_text(pStmt, 0); + zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; - nSample = tdsqlite3_column_int(pStmt, 1); + nSample = sqlite3_column_int(pStmt, 1); pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); assert( pIdx==0 || pIdx->nSample==0 ); if( pIdx==0 ) continue; @@ -111642,9 +111642,9 @@ static int loadStatTbl( nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; nByte += nIdxCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ - pIdx->aSample = tdsqlite3DbMallocZero(db, nByte); + pIdx->aSample = sqlite3DbMallocZero(db, nByte); if( pIdx->aSample==0 ){ - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } pSpace = (tRowcnt*)&pIdx->aSample[nSample]; @@ -111656,23 +111656,23 @@ static int loadStatTbl( } assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); } - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); if( rc ) return rc; - zSql = tdsqlite3MPrintf(db, zSql2, zDb); + zSql = sqlite3MPrintf(db, zSql2, zDb); if( !zSql ){ return SQLITE_NOMEM_BKPT; } - rc = tdsqlite3_prepare(db, zSql, -1, &pStmt, 0); - tdsqlite3DbFree(db, zSql); + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + sqlite3DbFree(db, zSql); if( rc ) return rc; - while( tdsqlite3_step(pStmt)==SQLITE_ROW ){ + while( sqlite3_step(pStmt)==SQLITE_ROW ){ char *zIndex; /* Index name */ Index *pIdx; /* Pointer to the index object */ int nCol = 1; /* Number of columns in index */ - zIndex = (char *)tdsqlite3_column_text(pStmt, 0); + zIndex = (char *)sqlite3_column_text(pStmt, 0); if( zIndex==0 ) continue; pIdx = findIndexOrPrimaryKey(db, zIndex, zDb); if( pIdx==0 ) continue; @@ -111684,28 +111684,28 @@ static int loadStatTbl( pPrevIdx = pIdx; } pSample = &pIdx->aSample[pIdx->nSample]; - decodeIntArray((char*)tdsqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); - decodeIntArray((char*)tdsqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); - decodeIntArray((char*)tdsqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,1),nCol,pSample->anEq,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); + decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. ** This is in case the sample record is corrupted. In that case, the - ** tdsqlite3VdbeRecordCompare() may read up to two varints past the + ** sqlite3VdbeRecordCompare() may read up to two varints past the ** end of the allocated buffer before it realizes it is dealing with ** a corrupt record. Adding the two 0x00 bytes prevents this from causing ** a buffer overread. */ - pSample->n = tdsqlite3_column_bytes(pStmt, 4); - pSample->p = tdsqlite3DbMallocZero(db, pSample->n + 2); + pSample->n = sqlite3_column_bytes(pStmt, 4); + pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); if( pSample->p==0 ){ - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; } if( pSample->n ){ - memcpy(pSample->p, tdsqlite3_column_blob(pStmt, 4), pSample->n); + memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); } pIdx->nSample++; } - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); return rc; } @@ -111714,11 +111714,11 @@ static int loadStatTbl( ** Load content from the sqlite_stat4 table into ** the Index.aSample[] arrays of all indices. */ -static int loadStat4(tdsqlite3 *db, const char *zDb){ +static int loadStat4(sqlite3 *db, const char *zDb){ int rc = SQLITE_OK; /* Result codes from subroutines */ assert( db->lookaside.bDisable ); - if( tdsqlite3FindTable(db, "sqlite_stat4", zDb) ){ + if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ rc = loadStatTbl(db, "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", @@ -111749,7 +111749,7 @@ static int loadStat4(tdsqlite3 *db, const char *zDb){ ** This means if the caller does not care about other errors, the return ** code may be ignored. */ -SQLITE_PRIVATE int tdsqlite3AnalysisLoad(tdsqlite3 *db, int iDb){ +SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ analysisInfo sInfo; HashElem *i; char *zSql; @@ -111760,7 +111760,7 @@ SQLITE_PRIVATE int tdsqlite3AnalysisLoad(tdsqlite3 *db, int iDb){ assert( db->aDb[iDb].pBt!=0 ); /* Clear any prior statistics */ - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); pTab->tabFlags &= ~TF_HasStat1; @@ -111769,7 +111769,7 @@ SQLITE_PRIVATE int tdsqlite3AnalysisLoad(tdsqlite3 *db, int iDb){ Index *pIdx = sqliteHashData(i); pIdx->hasStat1 = 0; #ifdef SQLITE_ENABLE_STAT4 - tdsqlite3DeleteIndexSamples(db, pIdx); + sqlite3DeleteIndexSamples(db, pIdx); pIdx->aSample = 0; #endif } @@ -111777,22 +111777,22 @@ SQLITE_PRIVATE int tdsqlite3AnalysisLoad(tdsqlite3 *db, int iDb){ /* Load new statistics out of the sqlite_stat1 table */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zDbSName; - if( tdsqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ - zSql = tdsqlite3MPrintf(db, + if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){ + zSql = sqlite3MPrintf(db, "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ rc = SQLITE_NOMEM_BKPT; }else{ - rc = tdsqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); - tdsqlite3DbFree(db, zSql); + rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); + sqlite3DbFree(db, zSql); } } /* Set appropriate defaults on all indexes not in the sqlite_stat1 table */ - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); - if( !pIdx->hasStat1 ) tdsqlite3DefaultRowEst(pIdx); + if( !pIdx->hasStat1 ) sqlite3DefaultRowEst(pIdx); } /* Load the statistics from the sqlite_stat4 table. */ @@ -111804,13 +111804,13 @@ SQLITE_PRIVATE int tdsqlite3AnalysisLoad(tdsqlite3 *db, int iDb){ } for(i=sqliteHashFirst(&pSchema->idxHash); i; i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); - tdsqlite3_free(pIdx->aiRowEst); + sqlite3_free(pIdx->aiRowEst); pIdx->aiRowEst = 0; } #endif if( rc==SQLITE_NOMEM ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); } return rc; } @@ -111859,7 +111859,7 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr) int rc = SQLITE_OK; if( pExpr ){ if( pExpr->op!=TK_ID ){ - rc = tdsqlite3ResolveExprNames(pName, pExpr); + rc = sqlite3ResolveExprNames(pName, pExpr); }else{ pExpr->op = TK_STRING; } @@ -111883,13 +111883,13 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr) ** empty MemDB. */ static void attachFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **argv + sqlite3_value **argv ){ int i; int rc = 0; - tdsqlite3 *db = tdsqlite3_context_db_handle(context); + sqlite3 *db = sqlite3_context_db_handle(context); const char *zName; const char *zFile; char *zPath = 0; @@ -111898,11 +111898,11 @@ static void attachFunc( Db *aNew; /* New array of Db pointers */ Db *pNew; /* Db object for the newly attached database */ char *zErrDyn = 0; - tdsqlite3_vfs *pVfs; + sqlite3_vfs *pVfs; UNUSED_PARAMETER(NotUsed); - zFile = (const char *)tdsqlite3_value_text(argv[0]); - zName = (const char *)tdsqlite3_value_text(argv[1]); + zFile = (const char *)sqlite3_value_text(argv[0]); + zName = (const char *)sqlite3_value_text(argv[1]); if( zFile==0 ) zFile = ""; if( zName==0 ) zName = ""; @@ -111914,15 +111914,15 @@ static void attachFunc( if( REOPEN_AS_MEMDB(db) ){ /* This is not a real ATTACH. Instead, this routine is being called - ** from tdsqlite3_deserialize() to close database db->init.iDb and + ** from sqlite3_deserialize() to close database db->init.iDb and ** reopen it as a MemDB */ - pVfs = tdsqlite3_vfs_find("memdb"); + pVfs = sqlite3_vfs_find("memdb"); if( pVfs==0 ) return; pNew = &db->aDb[db->init.iDb]; - if( pNew->pBt ) tdsqlite3BtreeClose(pNew->pBt); + if( pNew->pBt ) sqlite3BtreeClose(pNew->pBt); pNew->pBt = 0; pNew->pSchema = 0; - rc = tdsqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); + rc = sqlite3BtreeOpen(pVfs, "x\0", db, &pNew->pBt, 0, SQLITE_OPEN_MAIN_DB); }else{ /* This is a real ATTACH ** @@ -111933,7 +111933,7 @@ static void attachFunc( ** * Specified database name already being used. */ if( db->nDb>=db->aLimit[SQLITE_LIMIT_ATTACHED]+2 ){ - zErrDyn = tdsqlite3MPrintf(db, "too many attached databases - max %d", + zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", db->aLimit[SQLITE_LIMIT_ATTACHED] ); goto attach_error; @@ -111941,8 +111941,8 @@ static void attachFunc( for(i=0; inDb; i++){ char *z = db->aDb[i].zDbSName; assert( z && zName ); - if( tdsqlite3StrICmp(z, zName)==0 ){ - zErrDyn = tdsqlite3MPrintf(db, "database %s is already in use", zName); + if( sqlite3StrICmp(z, zName)==0 ){ + zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); goto attach_error; } } @@ -111951,11 +111951,11 @@ static void attachFunc( ** hash tables. */ if( db->aDb==db->aDbStatic ){ - aNew = tdsqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); + aNew = sqlite3DbMallocRawNN(db, sizeof(db->aDb[0])*3 ); if( aNew==0 ) return; memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2); }else{ - aNew = tdsqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); + aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) ); if( aNew==0 ) return; } db->aDb = aNew; @@ -111967,43 +111967,43 @@ static void attachFunc( ** or may not be initialized. */ flags = db->openFlags; - rc = tdsqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); + rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr); if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) tdsqlite3OomFault(db); - tdsqlite3_result_error(context, zErr, -1); - tdsqlite3_free(zErr); + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); return; } assert( pVfs ); flags |= SQLITE_OPEN_MAIN_DB; - rc = tdsqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); + rc = sqlite3BtreeOpen(pVfs, zPath, db, &pNew->pBt, 0, flags); db->nDb++; - pNew->zDbSName = tdsqlite3DbStrDup(db, zName); + pNew->zDbSName = sqlite3DbStrDup(db, zName); } db->noSharedCache = 0; if( rc==SQLITE_CONSTRAINT ){ rc = SQLITE_ERROR; - zErrDyn = tdsqlite3MPrintf(db, "database is already attached"); + zErrDyn = sqlite3MPrintf(db, "database is already attached"); }else if( rc==SQLITE_OK ){ Pager *pPager; - pNew->pSchema = tdsqlite3SchemaGet(db, pNew->pBt); + pNew->pSchema = sqlite3SchemaGet(db, pNew->pBt); if( !pNew->pSchema ){ rc = SQLITE_NOMEM_BKPT; }else if( pNew->pSchema->file_format && pNew->pSchema->enc!=ENC(db) ){ - zErrDyn = tdsqlite3MPrintf(db, + zErrDyn = sqlite3MPrintf(db, "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } - tdsqlite3BtreeEnter(pNew->pBt); - pPager = tdsqlite3BtreePager(pNew->pBt); - tdsqlite3PagerLockingMode(pPager, db->dfltLockMode); - tdsqlite3BtreeSecureDelete(pNew->pBt, - tdsqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); + sqlite3BtreeEnter(pNew->pBt); + pPager = sqlite3BtreePager(pNew->pBt); + sqlite3PagerLockingMode(pPager, db->dfltLockMode); + sqlite3BtreeSecureDelete(pNew->pBt, + sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); #ifndef SQLITE_OMIT_PAGER_PRAGMAS - tdsqlite3BtreeSetPagerFlags(pNew->pBt, + sqlite3BtreeSetPagerFlags(pNew->pBt, PAGER_SYNCHRONOUS_FULL | (db->flags & PAGER_FLAGS_MASK)); #endif - tdsqlite3BtreeLeave(pNew->pBt); + sqlite3BtreeLeave(pNew->pBt); } pNew->safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; if( rc==SQLITE_OK && pNew->zDbSName==0 ){ @@ -112013,39 +112013,39 @@ static void attachFunc( #ifdef SQLITE_HAS_CODEC if( rc==SQLITE_OK ){ - extern int tdsqlite3CodecAttach(tdsqlite3*, int, const void*, int); - extern void tdsqlite3CodecGetKey(tdsqlite3*, int, void**, int*); + extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); + extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); int nKey; char *zKey; - int t = tdsqlite3_value_type(argv[2]); + int t = sqlite3_value_type(argv[2]); switch( t ){ case SQLITE_INTEGER: case SQLITE_FLOAT: - zErrDyn = tdsqlite3DbStrDup(db, "Invalid key value"); + zErrDyn = sqlite3DbStrDup(db, "Invalid key value"); rc = SQLITE_ERROR; break; case SQLITE_TEXT: case SQLITE_BLOB: - nKey = tdsqlite3_value_bytes(argv[2]); - zKey = (char *)tdsqlite3_value_blob(argv[2]); - rc = tdsqlite3CodecAttach(db, db->nDb-1, zKey, nKey); + nKey = sqlite3_value_bytes(argv[2]); + zKey = (char *)sqlite3_value_blob(argv[2]); + rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); break; case SQLITE_NULL: /* No key specified. Use the key from URI filename, or if none, ** use the key from the main database. */ - if( tdsqlite3CodecQueryParameters(db, zName, zPath)==0 ){ - tdsqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); - if( nKey || tdsqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ - rc = tdsqlite3CodecAttach(db, db->nDb-1, zKey, nKey); + if( sqlite3CodecQueryParameters(db, zName, zPath)==0 ){ + sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey); + if( nKey || sqlite3BtreeGetOptimalReserve(db->aDb[0].pBt)>0 ){ + rc = sqlite3CodecAttach(db, db->nDb-1, zKey, nKey); } } break; } } #endif - tdsqlite3_free( zPath ); + sqlite3_free( zPath ); /* If the file was opened successfully, read the schema for the new database. ** If this fails, or if opening the file failed, then close the file and @@ -112053,19 +112053,19 @@ static void attachFunc( ** way we found it. */ if( rc==SQLITE_OK ){ - tdsqlite3BtreeEnterAll(db); + sqlite3BtreeEnterAll(db); db->init.iDb = 0; db->mDbFlags &= ~(DBFLAG_SchemaKnownOk); if( !REOPEN_AS_MEMDB(db) ){ - rc = tdsqlite3Init(db, &zErrDyn); + rc = sqlite3Init(db, &zErrDyn); } - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); assert( zErrDyn==0 || rc!=SQLITE_OK ); } #ifdef SQLITE_USER_AUTHENTICATION if( rc==SQLITE_OK && !REOPEN_AS_MEMDB(db) ){ u8 newAuth = 0; - rc = tdsqlite3UserAuthCheckLogin(db, zName, &newAuth); + rc = sqlite3UserAuthCheckLogin(db, zName, &newAuth); if( newAuthauth.authLevel ){ rc = SQLITE_AUTH_USER; } @@ -112076,18 +112076,18 @@ static void attachFunc( int iDb = db->nDb - 1; assert( iDb>=2 ); if( db->aDb[iDb].pBt ){ - tdsqlite3BtreeClose(db->aDb[iDb].pBt); + sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; db->aDb[iDb].pSchema = 0; } - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ResetAllSchemasOfConnection(db); db->nDb = iDb; if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - tdsqlite3OomFault(db); - tdsqlite3DbFree(db, zErrDyn); - zErrDyn = tdsqlite3MPrintf(db, "out of memory"); + sqlite3OomFault(db); + sqlite3DbFree(db, zErrDyn); + zErrDyn = sqlite3MPrintf(db, "out of memory"); }else if( zErrDyn==0 ){ - zErrDyn = tdsqlite3MPrintf(db, "unable to open database: %s", zFile); + zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); } } goto attach_error; @@ -112098,10 +112098,10 @@ static void attachFunc( attach_error: /* Return an error if we get here */ if( zErrDyn ){ - tdsqlite3_result_error(context, zErrDyn, -1); - tdsqlite3DbFree(db, zErrDyn); + sqlite3_result_error(context, zErrDyn, -1); + sqlite3DbFree(db, zErrDyn); } - if( rc ) tdsqlite3_result_error_code(context, rc); + if( rc ) sqlite3_result_error_code(context, rc); } /* @@ -112113,12 +112113,12 @@ attach_error: ** SELECT sqlite_detach(x) */ static void detachFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **argv + sqlite3_value **argv ){ - const char *zName = (const char *)tdsqlite3_value_text(argv[0]); - tdsqlite3 *db = tdsqlite3_context_db_handle(context); + const char *zName = (const char *)sqlite3_value_text(argv[0]); + sqlite3 *db = sqlite3_context_db_handle(context); int i; Db *pDb = 0; HashElem *pEntry; @@ -112130,19 +112130,19 @@ static void detachFunc( for(i=0; inDb; i++){ pDb = &db->aDb[i]; if( pDb->pBt==0 ) continue; - if( tdsqlite3StrICmp(pDb->zDbSName, zName)==0 ) break; + if( sqlite3StrICmp(pDb->zDbSName, zName)==0 ) break; } if( i>=db->nDb ){ - tdsqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); + sqlite3_snprintf(sizeof(zErr),zErr, "no such database: %s", zName); goto detach_error; } if( i<2 ){ - tdsqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); + sqlite3_snprintf(sizeof(zErr),zErr, "cannot detach database %s", zName); goto detach_error; } - if( tdsqlite3BtreeIsInReadTrans(pDb->pBt) || tdsqlite3BtreeIsInBackup(pDb->pBt) ){ - tdsqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); + if( sqlite3BtreeIsInReadTrans(pDb->pBt) || sqlite3BtreeIsInBackup(pDb->pBt) ){ + sqlite3_snprintf(sizeof(zErr),zErr, "database %s is locked", zName); goto detach_error; } @@ -112158,14 +112158,14 @@ static void detachFunc( pEntry = sqliteHashNext(pEntry); } - tdsqlite3BtreeClose(pDb->pBt); + sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; - tdsqlite3CollapseDatabaseArray(db); + sqlite3CollapseDatabaseArray(db); return; detach_error: - tdsqlite3_result_error(context, zErr, -1); + sqlite3_result_error(context, zErr, -1); } /* @@ -112184,7 +112184,7 @@ static void codeAttach( int rc; NameContext sName; Vdbe *v; - tdsqlite3* db = pParse->db; + sqlite3* db = pParse->db; int regArgs; if( pParse->nErr ) goto attach_end; @@ -112207,7 +112207,7 @@ static void codeAttach( }else{ zAuthArg = 0; } - rc = tdsqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); + rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); if(rc!=SQLITE_OK ){ goto attach_end; } @@ -112215,27 +112215,27 @@ static void codeAttach( #endif /* SQLITE_OMIT_AUTHORIZATION */ - v = tdsqlite3GetVdbe(pParse); - regArgs = tdsqlite3GetTempRange(pParse, 4); - tdsqlite3ExprCode(pParse, pFilename, regArgs); - tdsqlite3ExprCode(pParse, pDbname, regArgs+1); - tdsqlite3ExprCode(pParse, pKey, regArgs+2); + v = sqlite3GetVdbe(pParse); + regArgs = sqlite3GetTempRange(pParse, 4); + sqlite3ExprCode(pParse, pFilename, regArgs); + sqlite3ExprCode(pParse, pDbname, regArgs+1); + sqlite3ExprCode(pParse, pKey, regArgs+2); assert( v || db->mallocFailed ); if( v ){ - tdsqlite3VdbeAddFunctionCall(pParse, 0, regArgs+3-pFunc->nArg, regArgs+3, + sqlite3VdbeAddFunctionCall(pParse, 0, regArgs+3-pFunc->nArg, regArgs+3, pFunc->nArg, pFunc, 0); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). */ - tdsqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); + sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); } attach_end: - tdsqlite3ExprDelete(db, pFilename); - tdsqlite3ExprDelete(db, pDbname); - tdsqlite3ExprDelete(db, pKey); + sqlite3ExprDelete(db, pFilename); + sqlite3ExprDelete(db, pDbname); + sqlite3ExprDelete(db, pKey); } /* @@ -112243,7 +112243,7 @@ attach_end: ** ** DETACH pDbname */ -SQLITE_PRIVATE void tdsqlite3Detach(Parse *pParse, Expr *pDbname){ +SQLITE_PRIVATE void sqlite3Detach(Parse *pParse, Expr *pDbname){ static const FuncDef detach_func = { 1, /* nArg */ SQLITE_UTF8, /* funcFlags */ @@ -112263,7 +112263,7 @@ SQLITE_PRIVATE void tdsqlite3Detach(Parse *pParse, Expr *pDbname){ ** ** ATTACH p AS pDbname KEY pKey */ -SQLITE_PRIVATE void tdsqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ +SQLITE_PRIVATE void sqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr *pKey){ static const FuncDef attach_func = { 3, /* nArg */ SQLITE_UTF8, /* funcFlags */ @@ -112283,14 +112283,14 @@ SQLITE_PRIVATE void tdsqlite3Attach(Parse *pParse, Expr *p, Expr *pDbname, Expr ** Initialize a DbFixer structure. This routine must be called prior ** to passing the structure to one of the sqliteFixAAAA() routines below. */ -SQLITE_PRIVATE void tdsqlite3FixInit( +SQLITE_PRIVATE void sqlite3FixInit( DbFixer *pFix, /* The fixer to be initialized */ Parse *pParse, /* Error messages will be written here */ int iDb, /* This is the database that must be used */ const char *zType, /* "view", "trigger", or "index" */ const Token *pName /* Name of the view, trigger, or index */ ){ - tdsqlite3 *db; + sqlite3 *db; db = pParse->db; assert( db->nDb>iDb ); @@ -112306,7 +112306,7 @@ SQLITE_PRIVATE void tdsqlite3FixInit( ** The following set of routines walk through the parse tree and assign ** a specific database to all table references where the database name ** was left unspecified in the original SQL statement. The pFix structure -** must have been initialized by a prior call to tdsqlite3FixInit(). +** must have been initialized by a prior call to sqlite3FixInit(). ** ** These routines are used to make sure that an index, trigger, or ** view in one database does not refer to objects in a different database. @@ -112316,7 +112316,7 @@ SQLITE_PRIVATE void tdsqlite3FixInit( ** pParse->zErrMsg and these routines return non-zero. If everything ** checks out, these routines return 0. */ -SQLITE_PRIVATE int tdsqlite3FixSrcList( +SQLITE_PRIVATE int sqlite3FixSrcList( DbFixer *pFix, /* Context of the fixation */ SrcList *pList /* The Source list to check and modify */ ){ @@ -112328,58 +112328,58 @@ SQLITE_PRIVATE int tdsqlite3FixSrcList( zDb = pFix->zDb; for(i=0, pItem=pList->a; inSrc; i++, pItem++){ if( pFix->bTemp==0 ){ - if( pItem->zDatabase && tdsqlite3StrICmp(pItem->zDatabase, zDb) ){ - tdsqlite3ErrorMsg(pFix->pParse, + if( pItem->zDatabase && sqlite3StrICmp(pItem->zDatabase, zDb) ){ + sqlite3ErrorMsg(pFix->pParse, "%s %T cannot reference objects in database %s", pFix->zType, pFix->pName, pItem->zDatabase); return 1; } - tdsqlite3DbFree(pFix->pParse->db, pItem->zDatabase); + sqlite3DbFree(pFix->pParse->db, pItem->zDatabase); pItem->zDatabase = 0; pItem->pSchema = pFix->pSchema; pItem->fg.fromDDL = 1; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) - if( tdsqlite3FixSelect(pFix, pItem->pSelect) ) return 1; - if( tdsqlite3FixExpr(pFix, pItem->pOn) ) return 1; + if( sqlite3FixSelect(pFix, pItem->pSelect) ) return 1; + if( sqlite3FixExpr(pFix, pItem->pOn) ) return 1; #endif - if( pItem->fg.isTabFunc && tdsqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){ + if( pItem->fg.isTabFunc && sqlite3FixExprList(pFix, pItem->u1.pFuncArg) ){ return 1; } } return 0; } #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) -SQLITE_PRIVATE int tdsqlite3FixSelect( +SQLITE_PRIVATE int sqlite3FixSelect( DbFixer *pFix, /* Context of the fixation */ Select *pSelect /* The SELECT statement to be fixed to one database */ ){ while( pSelect ){ - if( tdsqlite3FixExprList(pFix, pSelect->pEList) ){ + if( sqlite3FixExprList(pFix, pSelect->pEList) ){ return 1; } - if( tdsqlite3FixSrcList(pFix, pSelect->pSrc) ){ + if( sqlite3FixSrcList(pFix, pSelect->pSrc) ){ return 1; } - if( tdsqlite3FixExpr(pFix, pSelect->pWhere) ){ + if( sqlite3FixExpr(pFix, pSelect->pWhere) ){ return 1; } - if( tdsqlite3FixExprList(pFix, pSelect->pGroupBy) ){ + if( sqlite3FixExprList(pFix, pSelect->pGroupBy) ){ return 1; } - if( tdsqlite3FixExpr(pFix, pSelect->pHaving) ){ + if( sqlite3FixExpr(pFix, pSelect->pHaving) ){ return 1; } - if( tdsqlite3FixExprList(pFix, pSelect->pOrderBy) ){ + if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){ return 1; } - if( tdsqlite3FixExpr(pFix, pSelect->pLimit) ){ + if( sqlite3FixExpr(pFix, pSelect->pLimit) ){ return 1; } if( pSelect->pWith ){ int i; for(i=0; ipWith->nCte; i++){ - if( tdsqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ + if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){ return 1; } } @@ -112388,7 +112388,7 @@ SQLITE_PRIVATE int tdsqlite3FixSelect( } return 0; } -SQLITE_PRIVATE int tdsqlite3FixExpr( +SQLITE_PRIVATE int sqlite3FixExpr( DbFixer *pFix, /* Context of the fixation */ Expr *pExpr /* The expression to be fixed to one database */ ){ @@ -112398,24 +112398,24 @@ SQLITE_PRIVATE int tdsqlite3FixExpr( if( pFix->pParse->db->init.busy ){ pExpr->op = TK_NULL; }else{ - tdsqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); + sqlite3ErrorMsg(pFix->pParse, "%s cannot use variables", pFix->zType); return 1; } } if( ExprHasProperty(pExpr, EP_TokenOnly|EP_Leaf) ) break; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - if( tdsqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; + if( sqlite3FixSelect(pFix, pExpr->x.pSelect) ) return 1; }else{ - if( tdsqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; + if( sqlite3FixExprList(pFix, pExpr->x.pList) ) return 1; } - if( tdsqlite3FixExpr(pFix, pExpr->pRight) ){ + if( sqlite3FixExpr(pFix, pExpr->pRight) ){ return 1; } pExpr = pExpr->pLeft; } return 0; } -SQLITE_PRIVATE int tdsqlite3FixExprList( +SQLITE_PRIVATE int sqlite3FixExprList( DbFixer *pFix, /* Context of the fixation */ ExprList *pList /* The expression to be fixed to one database */ ){ @@ -112423,7 +112423,7 @@ SQLITE_PRIVATE int tdsqlite3FixExprList( struct ExprList_item *pItem; if( pList==0 ) return 0; for(i=0, pItem=pList->a; inExpr; i++, pItem++){ - if( tdsqlite3FixExpr(pFix, pItem->pExpr) ){ + if( sqlite3FixExpr(pFix, pItem->pExpr) ){ return 1; } } @@ -112432,27 +112432,27 @@ SQLITE_PRIVATE int tdsqlite3FixExprList( #endif #ifndef SQLITE_OMIT_TRIGGER -SQLITE_PRIVATE int tdsqlite3FixTriggerStep( +SQLITE_PRIVATE int sqlite3FixTriggerStep( DbFixer *pFix, /* Context of the fixation */ TriggerStep *pStep /* The trigger step be fixed to one database */ ){ while( pStep ){ - if( tdsqlite3FixSelect(pFix, pStep->pSelect) ){ + if( sqlite3FixSelect(pFix, pStep->pSelect) ){ return 1; } - if( tdsqlite3FixExpr(pFix, pStep->pWhere) ){ + if( sqlite3FixExpr(pFix, pStep->pWhere) ){ return 1; } - if( tdsqlite3FixExprList(pFix, pStep->pExprList) ){ + if( sqlite3FixExprList(pFix, pStep->pExprList) ){ return 1; } #ifndef SQLITE_OMIT_UPSERT if( pStep->pUpsert ){ Upsert *pUp = pStep->pUpsert; - if( tdsqlite3FixExprList(pFix, pUp->pUpsertTarget) - || tdsqlite3FixExpr(pFix, pUp->pUpsertTargetWhere) - || tdsqlite3FixExprList(pFix, pUp->pUpsertSet) - || tdsqlite3FixExpr(pFix, pUp->pUpsertWhere) + if( sqlite3FixExprList(pFix, pUp->pUpsertTarget) + || sqlite3FixExpr(pFix, pUp->pUpsertTargetWhere) + || sqlite3FixExprList(pFix, pUp->pUpsertSet) + || sqlite3FixExpr(pFix, pUp->pUpsertWhere) ){ return 1; } @@ -112477,7 +112477,7 @@ SQLITE_PRIVATE int tdsqlite3FixTriggerStep( ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file contains code used to implement the tdsqlite3_set_authorizer() +** This file contains code used to implement the sqlite3_set_authorizer() ** API. This facility is an optional feature of the library. Embedded ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 @@ -112527,7 +112527,7 @@ SQLITE_PRIVATE int tdsqlite3FixTriggerStep( ** the table and the column that are being accessed. The auth function ** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If ** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY -** means that the SQL statement will never-run - the tdsqlite3_exec() call +** means that the SQL statement will never-run - the sqlite3_exec() call ** will return with an error. SQLITE_IGNORE means that the SQL statement ** should run but attempts to read the specified column will return NULL ** and attempts to write the column will be ignored. @@ -112535,19 +112535,19 @@ SQLITE_PRIVATE int tdsqlite3FixTriggerStep( ** Setting the auth function to NULL disables this hook. The default ** setting of the auth function is NULL. */ -SQLITE_API int tdsqlite3_set_authorizer( - tdsqlite3 *db, +SQLITE_API int sqlite3_set_authorizer( + sqlite3 *db, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pArg ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); - db->xAuth = (tdsqlite3_xauth)xAuth; + sqlite3_mutex_enter(db->mutex); + db->xAuth = (sqlite3_xauth)xAuth; db->pAuthArg = pArg; - if( db->xAuth ) tdsqlite3ExpirePreparedStatements(db, 1); - tdsqlite3_mutex_leave(db->mutex); + if( db->xAuth ) sqlite3ExpirePreparedStatements(db, 1); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -112556,7 +112556,7 @@ SQLITE_API int tdsqlite3_set_authorizer( ** user-supplied authorization function returned an illegal value. */ static void sqliteAuthBadReturnCode(Parse *pParse){ - tdsqlite3ErrorMsg(pParse, "authorizer malfunction"); + sqlite3ErrorMsg(pParse, "authorizer malfunction"); pParse->rc = SQLITE_ERROR; } @@ -112569,13 +112569,13 @@ static void sqliteAuthBadReturnCode(Parse *pParse){ ** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE ** is treated as SQLITE_DENY. In this case an error is left in pParse. */ -SQLITE_PRIVATE int tdsqlite3AuthReadCol( +SQLITE_PRIVATE int sqlite3AuthReadCol( Parse *pParse, /* The parser context */ const char *zTab, /* Table name */ const char *zCol, /* Column name */ int iDb /* Index of containing database. */ ){ - tdsqlite3 *db = pParse->db; /* Database handle */ + sqlite3 *db = pParse->db; /* Database handle */ char *zDb = db->aDb[iDb].zDbSName; /* Schema name of attached database */ int rc; /* Auth callback return code */ @@ -112586,9 +112586,9 @@ SQLITE_PRIVATE int tdsqlite3AuthReadCol( #endif ); if( rc==SQLITE_DENY ){ - char *z = tdsqlite3_mprintf("%s.%s", zTab, zCol); - if( db->nDb>2 || iDb!=0 ) z = tdsqlite3_mprintf("%s.%z", zDb, z); - tdsqlite3ErrorMsg(pParse, "access to %z is prohibited", z); + char *z = sqlite3_mprintf("%s.%s", zTab, zCol); + if( db->nDb>2 || iDb!=0 ) z = sqlite3_mprintf("%s.%z", zDb, z); + sqlite3ErrorMsg(pParse, "access to %z is prohibited", z); pParse->rc = SQLITE_AUTH; }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ sqliteAuthBadReturnCode(pParse); @@ -112605,13 +112605,13 @@ SQLITE_PRIVATE int tdsqlite3AuthReadCol( ** instruction into a TK_NULL. If the auth function returns SQLITE_DENY, ** then generate an error. */ -SQLITE_PRIVATE void tdsqlite3AuthRead( +SQLITE_PRIVATE void sqlite3AuthRead( Parse *pParse, /* The parser context */ Expr *pExpr, /* The expression to check authorization on */ Schema *pSchema, /* The schema of the expression */ SrcList *pTabList /* All table that pExpr might refer to */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Table *pTab = 0; /* The table being read */ const char *zCol; /* Name of the column of the table */ int iSrc; /* Index in pTabList->a[] of table being read */ @@ -112621,7 +112621,7 @@ SQLITE_PRIVATE void tdsqlite3AuthRead( assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); assert( !IN_RENAME_OBJECT || db->xAuth==0 ); if( db->xAuth==0 ) return; - iDb = tdsqlite3SchemaToIndex(pParse->db, pSchema); + iDb = sqlite3SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ /* An attempt to read a column out of a subquery or other ** temporary table. */ @@ -112652,7 +112652,7 @@ SQLITE_PRIVATE void tdsqlite3AuthRead( zCol = "ROWID"; } assert( iDb>=0 && iDbnDb ); - if( SQLITE_IGNORE==tdsqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ + if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; } } @@ -112663,18 +112663,18 @@ SQLITE_PRIVATE void tdsqlite3AuthRead( ** is returned, then the error count and error message in pParse are ** modified appropriately. */ -SQLITE_PRIVATE int tdsqlite3AuthCheck( +SQLITE_PRIVATE int sqlite3AuthCheck( Parse *pParse, int code, const char *zArg1, const char *zArg2, const char *zArg3 ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int rc; /* Don't do any authorization checks if the database is initialising - ** or if the parser is being invoked from within tdsqlite3_declare_vtab. + ** or if the parser is being invoked from within sqlite3_declare_vtab. */ assert( !IN_RENAME_OBJECT || db->xAuth==0 ); if( db->init.busy || IN_SPECIAL_PARSE ){ @@ -112702,7 +112702,7 @@ SQLITE_PRIVATE int tdsqlite3AuthCheck( #endif ); if( rc==SQLITE_DENY ){ - tdsqlite3ErrorMsg(pParse, "not authorized"); + sqlite3ErrorMsg(pParse, "not authorized"); pParse->rc = SQLITE_AUTH; }else if( rc!=SQLITE_OK && rc!=SQLITE_IGNORE ){ rc = SQLITE_DENY; @@ -112716,7 +112716,7 @@ SQLITE_PRIVATE int tdsqlite3AuthCheck( ** zArg3 argument to authorization callbacks will be zContext until ** popped. Or if pParse==0, this routine is a no-op. */ -SQLITE_PRIVATE void tdsqlite3AuthContextPush( +SQLITE_PRIVATE void sqlite3AuthContextPush( Parse *pParse, AuthContext *pContext, const char *zContext @@ -112729,9 +112729,9 @@ SQLITE_PRIVATE void tdsqlite3AuthContextPush( /* ** Pop an authorization context that was previously pushed -** by tdsqlite3AuthContextPush +** by sqlite3AuthContextPush */ -SQLITE_PRIVATE void tdsqlite3AuthContextPop(AuthContext *pContext){ +SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){ if( pContext->pParse ){ pContext->pParse->zAuthContext = pContext->zAuthContext; pContext->pParse = 0; @@ -112770,7 +112770,7 @@ SQLITE_PRIVATE void tdsqlite3AuthContextPop(AuthContext *pContext){ #ifndef SQLITE_OMIT_SHARED_CACHE /* -** The TableLock structure is only used by the tdsqlite3TableLock() and +** The TableLock structure is only used by the sqlite3TableLock() and ** codeTableLocks() functions. */ struct TableLock { @@ -112788,23 +112788,23 @@ struct TableLock { ** ** This routine just records the fact that the lock is desired. The ** code to make the lock occur is generated by a later call to -** codeTableLocks() which occurs during tdsqlite3FinishCoding(). +** codeTableLocks() which occurs during sqlite3FinishCoding(). */ -SQLITE_PRIVATE void tdsqlite3TableLock( +SQLITE_PRIVATE void sqlite3TableLock( Parse *pParse, /* Parsing context */ int iDb, /* Index of the database containing the table to lock */ int iTab, /* Root page number of the table to be locked */ u8 isWriteLock, /* True for a write lock */ const char *zName /* Name of the table to be locked */ ){ - Parse *pToplevel = tdsqlite3ParseToplevel(pParse); + Parse *pToplevel = sqlite3ParseToplevel(pParse); int i; int nBytes; TableLock *p; assert( iDb>=0 ); if( iDb==1 ) return; - if( !tdsqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return; + if( !sqlite3BtreeSharable(pParse->db->aDb[iDb].pBt) ) return; for(i=0; inTableLock; i++){ p = &pToplevel->aTableLock[i]; if( p->iDb==iDb && p->iTab==iTab ){ @@ -112815,7 +112815,7 @@ SQLITE_PRIVATE void tdsqlite3TableLock( nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); pToplevel->aTableLock = - tdsqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); + sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); if( pToplevel->aTableLock ){ p = &pToplevel->aTableLock[pToplevel->nTableLock++]; p->iDb = iDb; @@ -112824,25 +112824,25 @@ SQLITE_PRIVATE void tdsqlite3TableLock( p->zLockName = zName; }else{ pToplevel->nTableLock = 0; - tdsqlite3OomFault(pToplevel->db); + sqlite3OomFault(pToplevel->db); } } /* ** Code an OP_TableLock instruction for each table locked by the -** statement (configured by calls to tdsqlite3TableLock()). +** statement (configured by calls to sqlite3TableLock()). */ static void codeTableLocks(Parse *pParse){ int i; Vdbe *pVdbe; - pVdbe = tdsqlite3GetVdbe(pParse); - assert( pVdbe!=0 ); /* tdsqlite3GetVdbe cannot fail: VDBE already allocated */ + pVdbe = sqlite3GetVdbe(pParse); + assert( pVdbe!=0 ); /* sqlite3GetVdbe cannot fail: VDBE already allocated */ for(i=0; inTableLock; i++){ TableLock *p = &pParse->aTableLock[i]; int p1 = p->iDb; - tdsqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, + sqlite3VdbeAddOp4(pVdbe, OP_TableLock, p1, p->iTab, p->isWriteLock, p->zLockName, P4_STATIC); } } @@ -112856,7 +112856,7 @@ static void codeTableLocks(Parse *pParse){ ** macros when SQLITE_MAX_ATTACHED is greater than 30. */ #if SQLITE_MAX_ATTACHED>30 -SQLITE_PRIVATE int tdsqlite3DbMaskAllZero(yDbMask m){ +SQLITE_PRIVATE int sqlite3DbMaskAllZero(yDbMask m){ int i; for(i=0; ipToplevel==0 ); @@ -112888,17 +112888,17 @@ SQLITE_PRIVATE void tdsqlite3FinishCoding(Parse *pParse){ /* Begin by generating some termination code at the end of the ** vdbe program */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); assert( !pParse->isMultiWrite - || tdsqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); + || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ - tdsqlite3VdbeAddOp0(v, OP_Halt); + sqlite3VdbeAddOp0(v, OP_Halt); #if SQLITE_USER_AUTHENTICATION if( pParse->nTableLock>0 && db->init.busy==0 ){ - tdsqlite3UserAuthInit(db); + sqlite3UserAuthInit(db); if( db->auth.authLevelrc = SQLITE_AUTH_USER; return; } @@ -112915,28 +112915,28 @@ SQLITE_PRIVATE void tdsqlite3FinishCoding(Parse *pParse){ && (DbMaskNonZero(pParse->cookieMask) || pParse->pConstExpr) ){ int iDb, i; - assert( tdsqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); - tdsqlite3VdbeJumpHere(v, 0); + assert( sqlite3VdbeGetOp(v, 0)->opcode==OP_Init ); + sqlite3VdbeJumpHere(v, 0); for(iDb=0; iDbnDb; iDb++){ Schema *pSchema; if( DbMaskTest(pParse->cookieMask, iDb)==0 ) continue; - tdsqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeUsesBtree(v, iDb); pSchema = db->aDb[iDb].pSchema; - tdsqlite3VdbeAddOp4Int(v, + sqlite3VdbeAddOp4Int(v, OP_Transaction, /* Opcode */ iDb, /* P1 */ DbMaskTest(pParse->writeMask,iDb), /* P2 */ pSchema->schema_cookie, /* P3 */ pSchema->iGeneration /* P4 */ ); - if( db->init.busy==0 ) tdsqlite3VdbeChangeP5(v, 1); + if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1); VdbeComment((v, "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite)); } #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=0; inVtabLock; i++){ - char *vtab = (char *)tdsqlite3GetVTable(db, pParse->apVtabLock[i]); - tdsqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); + sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); } pParse->nVtabLock = 0; #endif @@ -112949,19 +112949,19 @@ SQLITE_PRIVATE void tdsqlite3FinishCoding(Parse *pParse){ /* Initialize any AUTOINCREMENT data structures required. */ - tdsqlite3AutoincrementBegin(pParse); + sqlite3AutoincrementBegin(pParse); /* Code constant expressions that where factored out of inner loops */ if( pParse->pConstExpr ){ ExprList *pEL = pParse->pConstExpr; pParse->okConstFactor = 0; for(i=0; inExpr; i++){ - tdsqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); } } /* Finally, jump back to the beginning of the executable code. */ - tdsqlite3VdbeGoto(v, 1); + sqlite3VdbeGoto(v, 1); } } @@ -112972,7 +112972,7 @@ SQLITE_PRIVATE void tdsqlite3FinishCoding(Parse *pParse){ /* A minimum of one cursor is required if autoincrement is used * See ticket [a696379c1f08866] */ assert( pParse->pAinc==0 || pParse->nTab>0 ); - tdsqlite3VdbeMakeReady(v, pParse); + sqlite3VdbeMakeReady(v, pParse); pParse->rc = SQLITE_DONE; }else{ pParse->rc = SQLITE_ERROR; @@ -112991,17 +112991,17 @@ SQLITE_PRIVATE void tdsqlite3FinishCoding(Parse *pParse){ ** INSERT, UPDATE, and DELETE operations against SQLITE_MASTER. Use ** care if you decide to try to use this routine for some other purposes. */ -SQLITE_PRIVATE void tdsqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ +SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){ va_list ap; char *zSql; char *zErrMsg = 0; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; char saveBuf[PARSE_TAIL_SZ]; if( pParse->nErr ) return; assert( pParse->nested<10 ); /* Nesting should only be of limited depth */ va_start(ap, zFormat); - zSql = tdsqlite3VMPrintf(db, zFormat, ap); + zSql = sqlite3VMPrintf(db, zFormat, ap); va_end(ap); if( zSql==0 ){ /* This can result either from an OOM or because the formatted string @@ -113014,9 +113014,9 @@ SQLITE_PRIVATE void tdsqlite3NestedParse(Parse *pParse, const char *zFormat, ... pParse->nested++; memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ); memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ); - tdsqlite3RunParser(pParse, zSql, &zErrMsg); - tdsqlite3DbFree(db, zErrMsg); - tdsqlite3DbFree(db, zSql); + sqlite3RunParser(pParse, zSql, &zErrMsg); + sqlite3DbFree(db, zErrMsg); + sqlite3DbFree(db, zSql); memcpy(PARSE_TAIL(pParse), saveBuf, PARSE_TAIL_SZ); pParse->nested--; } @@ -113026,8 +113026,8 @@ SQLITE_PRIVATE void tdsqlite3NestedParse(Parse *pParse, const char *zFormat, ... ** Return TRUE if zTable is the name of the system table that stores the ** list of users and their access credentials. */ -SQLITE_PRIVATE int tdsqlite3UserAuthTable(const char *zTable){ - return tdsqlite3_stricmp(zTable, "sqlite_user")==0; +SQLITE_PRIVATE int sqlite3UserAuthTable(const char *zTable){ + return sqlite3_stricmp(zTable, "sqlite_user")==0; } #endif @@ -113041,34 +113041,34 @@ SQLITE_PRIVATE int tdsqlite3UserAuthTable(const char *zTable){ ** names is done.) The search order is TEMP first, then MAIN, then any ** auxiliary databases added using the ATTACH command. ** -** See also tdsqlite3LocateTable(). +** See also sqlite3LocateTable(). */ -SQLITE_PRIVATE Table *tdsqlite3FindTable(tdsqlite3 *db, const char *zName, const char *zDatabase){ +SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){ Table *p = 0; int i; /* All mutexes are required for schema access. Make sure we hold them. */ - assert( zDatabase!=0 || tdsqlite3BtreeHoldsAllMutexes(db) ); + assert( zDatabase!=0 || sqlite3BtreeHoldsAllMutexes(db) ); #if SQLITE_USER_AUTHENTICATION /* Only the admin user is allowed to know that the sqlite_user table ** exists */ - if( db->auth.authLevelauth.authLevelnDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDatabase==0 || tdsqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ - assert( tdsqlite3SchemaMutexHeld(db, j, 0) ); - p = tdsqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); + if( zDatabase==0 || sqlite3StrICmp(zDatabase, db->aDb[j].zDbSName)==0 ){ + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName); if( p ) return p; } } /* Not found. If the name we were looking for was temp.sqlite_master ** then change the name to sqlite_temp_master and try again. */ - if( tdsqlite3StrICmp(zName, MASTER_NAME)!=0 ) break; - if( tdsqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break; + if( sqlite3StrICmp(zName, MASTER_NAME)!=0 ) break; + if( sqlite3_stricmp(zDatabase, db->aDb[1].zDbSName)!=0 ) break; zName = TEMP_MASTER_NAME; } return 0; @@ -113080,39 +113080,39 @@ SQLITE_PRIVATE Table *tdsqlite3FindTable(tdsqlite3 *db, const char *zName, const ** database containing the table. Return NULL if not found. Also leave an ** error message in pParse->zErrMsg. ** -** The difference between this routine and tdsqlite3FindTable() is that this +** The difference between this routine and sqlite3FindTable() is that this ** routine leaves an error message in pParse->zErrMsg where -** tdsqlite3FindTable() does not. +** sqlite3FindTable() does not. */ -SQLITE_PRIVATE Table *tdsqlite3LocateTable( +SQLITE_PRIVATE Table *sqlite3LocateTable( Parse *pParse, /* context in which to report errors */ u32 flags, /* LOCATE_VIEW or LOCATE_NOERR */ const char *zName, /* Name of the table we are looking for */ const char *zDbase /* Name of the database. Might be NULL */ ){ Table *p; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 - && SQLITE_OK!=tdsqlite3ReadSchema(pParse) + && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ return 0; } - p = tdsqlite3FindTable(db, zName, zDbase); + p = sqlite3FindTable(db, zName, zDbase); if( p==0 ){ #ifndef SQLITE_OMIT_VIRTUALTABLE /* If zName is the not the name of a table in the schema created using ** CREATE, then check to see if it is the name of an virtual table that ** can be an eponymous virtual table. */ if( pParse->disableVtab==0 ){ - Module *pMod = (Module*)tdsqlite3HashFind(&db->aModule, zName); - if( pMod==0 && tdsqlite3_strnicmp(zName, "pragma_", 7)==0 ){ - pMod = tdsqlite3PragmaVtabRegister(db, zName); + Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName); + if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){ + pMod = sqlite3PragmaVtabRegister(db, zName); } - if( pMod && tdsqlite3VtabEponymousTableInit(pParse, pMod) ){ + if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){ return pMod->pEpoTab; } } @@ -113126,9 +113126,9 @@ SQLITE_PRIVATE Table *tdsqlite3LocateTable( if( p==0 ){ const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table"; if( zDbase ){ - tdsqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); + sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName); }else{ - tdsqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); + sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName); } } @@ -113138,13 +113138,13 @@ SQLITE_PRIVATE Table *tdsqlite3LocateTable( /* ** Locate the table identified by *p. ** -** This is a wrapper around tdsqlite3LocateTable(). The difference between -** tdsqlite3LocateTable() and this function is that this function restricts +** This is a wrapper around sqlite3LocateTable(). The difference between +** sqlite3LocateTable() and this function is that this function restricts ** the search to schema (p->pSchema) if it is not NULL. p->pSchema may be ** non-NULL if it is part of a view or trigger program definition. See -** tdsqlite3FixSrcList() for details. +** sqlite3FixSrcList() for details. */ -SQLITE_PRIVATE Table *tdsqlite3LocateTableItem( +SQLITE_PRIVATE Table *sqlite3LocateTableItem( Parse *pParse, u32 flags, struct SrcList_item *p @@ -113152,12 +113152,12 @@ SQLITE_PRIVATE Table *tdsqlite3LocateTableItem( const char *zDb; assert( p->pSchema==0 || p->zDatabase==0 ); if( p->pSchema ){ - int iDb = tdsqlite3SchemaToIndex(pParse->db, p->pSchema); + int iDb = sqlite3SchemaToIndex(pParse->db, p->pSchema); zDb = pParse->db->aDb[iDb].zDbSName; }else{ zDb = p->zDatabase; } - return tdsqlite3LocateTable(pParse, flags, p->zName, zDb); + return sqlite3LocateTable(pParse, flags, p->zName, zDb); } /* @@ -113172,18 +113172,18 @@ SQLITE_PRIVATE Table *tdsqlite3LocateTableItem( ** TEMP first, then MAIN, then any auxiliary databases added ** using the ATTACH command. */ -SQLITE_PRIVATE Index *tdsqlite3FindIndex(tdsqlite3 *db, const char *zName, const char *zDb){ +SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){ Index *p = 0; int i; /* All mutexes are required for schema access. Make sure we hold them. */ - assert( zDb!=0 || tdsqlite3BtreeHoldsAllMutexes(db) ); + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ Schema *pSchema = db->aDb[j].pSchema; assert( pSchema ); - if( zDb && tdsqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue; - assert( tdsqlite3SchemaMutexHeld(db, j, 0) ); - p = tdsqlite3HashFind(&pSchema->idxHash, zName); + if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zDbSName) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + p = sqlite3HashFind(&pSchema->idxHash, zName); if( p ) break; } return p; @@ -113192,18 +113192,18 @@ SQLITE_PRIVATE Index *tdsqlite3FindIndex(tdsqlite3 *db, const char *zName, const /* ** Reclaim the memory used by an index */ -SQLITE_PRIVATE void tdsqlite3FreeIndex(tdsqlite3 *db, Index *p){ +SQLITE_PRIVATE void sqlite3FreeIndex(sqlite3 *db, Index *p){ #ifndef SQLITE_OMIT_ANALYZE - tdsqlite3DeleteIndexSamples(db, p); + sqlite3DeleteIndexSamples(db, p); #endif - tdsqlite3ExprDelete(db, p->pPartIdxWhere); - tdsqlite3ExprListDelete(db, p->aColExpr); - tdsqlite3DbFree(db, p->zColAff); - if( p->isResized ) tdsqlite3DbFree(db, (void *)p->azColl); + sqlite3ExprDelete(db, p->pPartIdxWhere); + sqlite3ExprListDelete(db, p->aColExpr); + sqlite3DbFree(db, p->zColAff); + if( p->isResized ) sqlite3DbFree(db, (void *)p->azColl); #ifdef SQLITE_ENABLE_STAT4 - tdsqlite3_free(p->aiRowEst); + sqlite3_free(p->aiRowEst); #endif - tdsqlite3DbFree(db, p); + sqlite3DbFree(db, p); } /* @@ -113212,13 +113212,13 @@ SQLITE_PRIVATE void tdsqlite3FreeIndex(tdsqlite3 *db, Index *p){ ** the index hash table and free all memory structures associated ** with the index. */ -SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteIndex(tdsqlite3 *db, int iDb, const char *zIdxName){ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char *zIdxName){ Index *pIndex; Hash *pHash; - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pHash = &db->aDb[iDb].pSchema->idxHash; - pIndex = tdsqlite3HashInsert(pHash, zIdxName, 0); + pIndex = sqlite3HashInsert(pHash, zIdxName, 0); if( ALWAYS(pIndex) ){ if( pIndex->pTable->pIndex==pIndex ){ pIndex->pTable->pIndex = pIndex->pNext; @@ -113232,7 +113232,7 @@ SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteIndex(tdsqlite3 *db, int iDb, const p->pNext = pIndex->pNext; } } - tdsqlite3FreeIndex(db, pIndex); + sqlite3FreeIndex(db, pIndex); } db->mDbFlags |= DBFLAG_SchemaChange; } @@ -113245,12 +113245,12 @@ SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteIndex(tdsqlite3 *db, int iDb, const ** Entry 0 (the "main" database) and entry 1 (the "temp" database) ** are never candidates for being collapsed. */ -SQLITE_PRIVATE void tdsqlite3CollapseDatabaseArray(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3CollapseDatabaseArray(sqlite3 *db){ int i, j; for(i=j=2; inDb; i++){ struct Db *pDb = &db->aDb[i]; if( pDb->pBt==0 ){ - tdsqlite3DbFree(db, pDb->zDbSName); + sqlite3DbFree(db, pDb->zDbSName); pDb->zDbSName = 0; continue; } @@ -113262,7 +113262,7 @@ SQLITE_PRIVATE void tdsqlite3CollapseDatabaseArray(tdsqlite3 *db){ db->nDb = j; if( db->nDb<=2 && db->aDb!=db->aDbStatic ){ memcpy(db->aDbStatic, db->aDb, 2*sizeof(db->aDb[0])); - tdsqlite3DbFree(db, db->aDb); + sqlite3DbFree(db, db->aDb); db->aDb = db->aDbStatic; } } @@ -113272,12 +113272,12 @@ SQLITE_PRIVATE void tdsqlite3CollapseDatabaseArray(tdsqlite3 *db){ ** TEMP schema. The reset is deferred if db->nSchemaLock is not zero. ** Deferred resets may be run by calling with iDb<0. */ -SQLITE_PRIVATE void tdsqlite3ResetOneSchema(tdsqlite3 *db, int iDb){ +SQLITE_PRIVATE void sqlite3ResetOneSchema(sqlite3 *db, int iDb){ int i; assert( iDbnDb ); if( iDb>=0 ){ - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); DbSetProperty(db, iDb, DB_ResetWanted); DbSetProperty(db, 1, DB_ResetWanted); db->mDbFlags &= ~DBFLAG_SchemaKnownOk; @@ -113286,7 +113286,7 @@ SQLITE_PRIVATE void tdsqlite3ResetOneSchema(tdsqlite3 *db, int iDb){ if( db->nSchemaLock==0 ){ for(i=0; inDb; i++){ if( DbHasProperty(db, i, DB_ResetWanted) ){ - tdsqlite3SchemaClear(db->aDb[i].pSchema); + sqlite3SchemaClear(db->aDb[i].pSchema); } } } @@ -113296,31 +113296,31 @@ SQLITE_PRIVATE void tdsqlite3ResetOneSchema(tdsqlite3 *db, int iDb){ ** Erase all schema information from all attached databases (including ** "main" and "temp") for a single database connection. */ -SQLITE_PRIVATE void tdsqlite3ResetAllSchemasOfConnection(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){ int i; - tdsqlite3BtreeEnterAll(db); + sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Db *pDb = &db->aDb[i]; if( pDb->pSchema ){ if( db->nSchemaLock==0 ){ - tdsqlite3SchemaClear(pDb->pSchema); + sqlite3SchemaClear(pDb->pSchema); }else{ DbSetProperty(db, i, DB_ResetWanted); } } } db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk); - tdsqlite3VtabUnlockList(db); - tdsqlite3BtreeLeaveAll(db); + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); if( db->nSchemaLock==0 ){ - tdsqlite3CollapseDatabaseArray(db); + sqlite3CollapseDatabaseArray(db); } } /* ** This routine is called when a commit occurs. */ -SQLITE_PRIVATE void tdsqlite3CommitInternalChanges(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3CommitInternalChanges(sqlite3 *db){ db->mDbFlags &= ~DBFLAG_SchemaChange; } @@ -113328,17 +113328,17 @@ SQLITE_PRIVATE void tdsqlite3CommitInternalChanges(tdsqlite3 *db){ ** Delete memory allocated for the column names of a table or view (the ** Table.aCol[] array). */ -SQLITE_PRIVATE void tdsqlite3DeleteColumnNames(tdsqlite3 *db, Table *pTable){ +SQLITE_PRIVATE void sqlite3DeleteColumnNames(sqlite3 *db, Table *pTable){ int i; Column *pCol; assert( pTable!=0 ); if( (pCol = pTable->aCol)!=0 ){ for(i=0; inCol; i++, pCol++){ - tdsqlite3DbFree(db, pCol->zName); - tdsqlite3ExprDelete(db, pCol->pDflt); - tdsqlite3DbFree(db, pCol->zColl); + sqlite3DbFree(db, pCol->zName); + sqlite3ExprDelete(db, pCol->pDflt); + sqlite3DbFree(db, pCol->zColl); } - tdsqlite3DbFree(db, pTable->aCol); + sqlite3DbFree(db, pTable->aCol); } } @@ -113357,7 +113357,7 @@ SQLITE_PRIVATE void tdsqlite3DeleteColumnNames(tdsqlite3 *db, Table *pTable){ ** db parameter can be used with db->pnBytesFreed to measure the memory ** used by the Table object. */ -static void SQLITE_NOINLINE deleteTable(tdsqlite3 *db, Table *pTable){ +static void SQLITE_NOINLINE deleteTable(sqlite3 *db, Table *pTable){ Index *pIndex, *pNext; #ifdef SQLITE_DEBUG @@ -113370,7 +113370,7 @@ static void SQLITE_NOINLINE deleteTable(tdsqlite3 *db, Table *pTable){ ** that no lookaside memory is used in this case either. */ int nLookaside = 0; if( db && !db->mallocFailed && (pTable->tabFlags & TF_Ephemeral)==0 ){ - nLookaside = tdsqlite3LookasideUsed(db, 0); + nLookaside = sqlite3LookasideUsed(db, 0); } #endif @@ -113381,34 +113381,34 @@ static void SQLITE_NOINLINE deleteTable(tdsqlite3 *db, Table *pTable){ || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); if( (db==0 || db->pnBytesFreed==0) && !IsVirtual(pTable) ){ char *zName = pIndex->zName; - TESTONLY ( Index *pOld = ) tdsqlite3HashInsert( + TESTONLY ( Index *pOld = ) sqlite3HashInsert( &pIndex->pSchema->idxHash, zName, 0 ); - assert( db==0 || tdsqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); assert( pOld==pIndex || pOld==0 ); } - tdsqlite3FreeIndex(db, pIndex); + sqlite3FreeIndex(db, pIndex); } /* Delete any foreign keys attached to this table. */ - tdsqlite3FkDelete(db, pTable); + sqlite3FkDelete(db, pTable); /* Delete the Table structure itself. */ - tdsqlite3DeleteColumnNames(db, pTable); - tdsqlite3DbFree(db, pTable->zName); - tdsqlite3DbFree(db, pTable->zColAff); - tdsqlite3SelectDelete(db, pTable->pSelect); - tdsqlite3ExprListDelete(db, pTable->pCheck); + sqlite3DeleteColumnNames(db, pTable); + sqlite3DbFree(db, pTable->zName); + sqlite3DbFree(db, pTable->zColAff); + sqlite3SelectDelete(db, pTable->pSelect); + sqlite3ExprListDelete(db, pTable->pCheck); #ifndef SQLITE_OMIT_VIRTUALTABLE - tdsqlite3VtabClear(db, pTable); + sqlite3VtabClear(db, pTable); #endif - tdsqlite3DbFree(db, pTable); + sqlite3DbFree(db, pTable); /* Verify that no lookaside memory was used by schema tables */ - assert( nLookaside==0 || nLookaside==tdsqlite3LookasideUsed(db,0) ); + assert( nLookaside==0 || nLookaside==sqlite3LookasideUsed(db,0) ); } -SQLITE_PRIVATE void tdsqlite3DeleteTable(tdsqlite3 *db, Table *pTable){ +SQLITE_PRIVATE void sqlite3DeleteTable(sqlite3 *db, Table *pTable){ /* Do not delete the table until the reference count reaches zero. */ if( !pTable ) return; if( ((!db || db->pnBytesFreed==0) && (--pTable->nTabRef)>0) ) return; @@ -113420,18 +113420,18 @@ SQLITE_PRIVATE void tdsqlite3DeleteTable(tdsqlite3 *db, Table *pTable){ ** Unlink the given table from the hash tables and the delete the ** table structure with all its indices and foreign keys. */ -SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteTable(tdsqlite3 *db, int iDb, const char *zTabName){ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTable(sqlite3 *db, int iDb, const char *zTabName){ Table *p; Db *pDb; assert( db!=0 ); assert( iDb>=0 && iDbnDb ); assert( zTabName ); - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); testcase( zTabName[0]==0 ); /* Zero-length table names are allowed */ pDb = &db->aDb[iDb]; - p = tdsqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); - tdsqlite3DeleteTable(db, p); + p = sqlite3HashInsert(&pDb->pSchema->tblHash, zTabName, 0); + sqlite3DeleteTable(db, p); db->mDbFlags |= DBFLAG_SchemaChange; } @@ -113448,11 +113448,11 @@ SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteTable(tdsqlite3 *db, int iDb, const ** are not \000 terminated and are not persistent. The returned string ** is \000 terminated and is persistent. */ -SQLITE_PRIVATE char *tdsqlite3NameFromToken(tdsqlite3 *db, Token *pName){ +SQLITE_PRIVATE char *sqlite3NameFromToken(sqlite3 *db, Token *pName){ char *zName; if( pName ){ - zName = tdsqlite3DbStrNDup(db, (char*)pName->z, pName->n); - tdsqlite3Dequote(zName); + zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n); + sqlite3Dequote(zName); }else{ zName = 0; } @@ -113463,10 +113463,10 @@ SQLITE_PRIVATE char *tdsqlite3NameFromToken(tdsqlite3 *db, Token *pName){ ** Open the sqlite_master table stored in database number iDb for ** writing. The table is opened using cursor 0. */ -SQLITE_PRIVATE void tdsqlite3OpenMasterTable(Parse *p, int iDb){ - Vdbe *v = tdsqlite3GetVdbe(p); - tdsqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME); - tdsqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5); +SQLITE_PRIVATE void sqlite3OpenMasterTable(Parse *p, int iDb){ + Vdbe *v = sqlite3GetVdbe(p); + sqlite3TableLock(p, iDb, MASTER_ROOT, 1, MASTER_NAME); + sqlite3VdbeAddOp4Int(v, OP_OpenWrite, 0, MASTER_ROOT, iDb, 5); if( p->nTab==0 ){ p->nTab = 1; } @@ -113478,15 +113478,15 @@ SQLITE_PRIVATE void tdsqlite3OpenMasterTable(Parse *p, int iDb){ ** function returns the index of the named database in db->aDb[], or ** -1 if the named db cannot be found. */ -SQLITE_PRIVATE int tdsqlite3FindDbName(tdsqlite3 *db, const char *zName){ +SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *db, const char *zName){ int i = -1; /* Database number */ if( zName ){ Db *pDb; for(i=(db->nDb-1), pDb=&db->aDb[i]; i>=0; i--, pDb--){ - if( 0==tdsqlite3_stricmp(pDb->zDbSName, zName) ) break; + if( 0==sqlite3_stricmp(pDb->zDbSName, zName) ) break; /* "main" is always an acceptable alias for the primary database ** even if it has been renamed using SQLITE_DBCONFIG_MAINDBNAME. */ - if( i==0 && 0==tdsqlite3_stricmp("main", zName) ) break; + if( i==0 && 0==sqlite3_stricmp("main", zName) ) break; } } return i; @@ -113498,12 +113498,12 @@ SQLITE_PRIVATE int tdsqlite3FindDbName(tdsqlite3 *db, const char *zName){ ** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ -SQLITE_PRIVATE int tdsqlite3FindDb(tdsqlite3 *db, Token *pName){ +SQLITE_PRIVATE int sqlite3FindDb(sqlite3 *db, Token *pName){ int i; /* Database number */ char *zName; /* Name we are searching for */ - zName = tdsqlite3NameFromToken(db, pName); - i = tdsqlite3FindDbName(db, zName); - tdsqlite3DbFree(db, zName); + zName = sqlite3NameFromToken(db, pName); + i = sqlite3FindDbName(db, zName); + sqlite3DbFree(db, zName); return i; } @@ -113523,25 +113523,25 @@ SQLITE_PRIVATE int tdsqlite3FindDb(tdsqlite3 *db, Token *pName){ ** pName2) that stores the unqualified table name. The index of the ** database "xxx" is returned. */ -SQLITE_PRIVATE int tdsqlite3TwoPartName( +SQLITE_PRIVATE int sqlite3TwoPartName( Parse *pParse, /* Parsing and code generating context */ Token *pName1, /* The "xxx" in the name "xxx.yyy" or "xxx" */ Token *pName2, /* The "yyy" in the name "xxx.yyy" */ Token **pUnqual /* Write the unqualified object name here */ ){ int iDb; /* Database holding the object */ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; assert( pName2!=0 ); if( pName2->n>0 ){ if( db->init.busy ) { - tdsqlite3ErrorMsg(pParse, "corrupt database"); + sqlite3ErrorMsg(pParse, "corrupt database"); return -1; } *pUnqual = pName2; - iDb = tdsqlite3FindDb(db, pName1); + iDb = sqlite3FindDb(db, pName1); if( iDb<0 ){ - tdsqlite3ErrorMsg(pParse, "unknown database %T", pName1); + sqlite3ErrorMsg(pParse, "unknown database %T", pName1); return -1; } }else{ @@ -113556,7 +113556,7 @@ SQLITE_PRIVATE int tdsqlite3TwoPartName( /* ** True if PRAGMA writable_schema is ON */ -SQLITE_PRIVATE int tdsqlite3WritableSchema(tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3WritableSchema(sqlite3 *db){ testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))==0 ); testcase( (db->flags&(SQLITE_WriteSchema|SQLITE_Defensive))== SQLITE_WriteSchema ); @@ -113578,32 +113578,32 @@ SQLITE_PRIVATE int tdsqlite3WritableSchema(tdsqlite3 *db){ ** make sure the "type", "name", and "tbl_name" columns are consistent ** with the SQL. */ -SQLITE_PRIVATE int tdsqlite3CheckObjectName( +SQLITE_PRIVATE int sqlite3CheckObjectName( Parse *pParse, /* Parsing context */ const char *zName, /* Name of the object to check */ const char *zType, /* Type of this object */ const char *zTblName /* Parent table name for triggers and indexes */ ){ - tdsqlite3 *db = pParse->db; - if( tdsqlite3WritableSchema(db) || db->init.imposterTable ){ + sqlite3 *db = pParse->db; + if( sqlite3WritableSchema(db) || db->init.imposterTable ){ /* Skip these error checks for writable_schema=ON */ return SQLITE_OK; } if( db->init.busy ){ - if( tdsqlite3_stricmp(zType, db->init.azInit[0]) - || tdsqlite3_stricmp(zName, db->init.azInit[1]) - || tdsqlite3_stricmp(zTblName, db->init.azInit[2]) + if( sqlite3_stricmp(zType, db->init.azInit[0]) + || sqlite3_stricmp(zName, db->init.azInit[1]) + || sqlite3_stricmp(zTblName, db->init.azInit[2]) ){ - if( tdsqlite3Config.bExtraSchemaChecks ){ - tdsqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */ + if( sqlite3Config.bExtraSchemaChecks ){ + sqlite3ErrorMsg(pParse, ""); /* corruptSchema() will supply the error */ return SQLITE_ERROR; } } }else{ - if( (pParse->nested==0 && 0==tdsqlite3StrNICmp(zName, "sqlite_", 7)) - || (tdsqlite3ReadOnlyShadowTables(db) && tdsqlite3ShadowTableName(db, zName)) + if( (pParse->nested==0 && 0==sqlite3StrNICmp(zName, "sqlite_", 7)) + || (sqlite3ReadOnlyShadowTables(db) && sqlite3ShadowTableName(db, zName)) ){ - tdsqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", + sqlite3ErrorMsg(pParse, "object name reserved for internal use: %s", zName); return SQLITE_ERROR; } @@ -113615,7 +113615,7 @@ SQLITE_PRIVATE int tdsqlite3CheckObjectName( /* ** Return the PRIMARY KEY index of a table */ -SQLITE_PRIVATE Index *tdsqlite3PrimaryKeyIndex(Table *pTab){ +SQLITE_PRIVATE Index *sqlite3PrimaryKeyIndex(Table *pTab){ Index *p; for(p=pTab->pIndex; p && !IsPrimaryKeyIndex(p); p=p->pNext){} return p; @@ -113627,7 +113627,7 @@ SQLITE_PRIVATE Index *tdsqlite3PrimaryKeyIndex(Table *pTab){ ** find the (first) offset of that column in index pIdx. Or return -1 ** if column iCol is not used in index pIdx. */ -SQLITE_PRIVATE i16 tdsqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ +SQLITE_PRIVATE i16 sqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ int i; for(i=0; inColumn; i++){ if( iCol==pIdx->aiColumn[i] ) return i; @@ -113647,7 +113647,7 @@ SQLITE_PRIVATE i16 tdsqlite3TableColumnToIndex(Index *pIdx, i16 iCol){ ** ** If SQLITE_OMIT_GENERATED_COLUMNS, this routine is a no-op macro. */ -SQLITE_PRIVATE i16 tdsqlite3StorageColumnToTable(Table *pTab, i16 iCol){ +SQLITE_PRIVATE i16 sqlite3StorageColumnToTable(Table *pTab, i16 iCol){ if( pTab->tabFlags & TF_HasVirtual ){ int i; for(i=0; i<=iCol; i++){ @@ -113695,7 +113695,7 @@ SQLITE_PRIVATE i16 tdsqlite3StorageColumnToTable(Table *pTab, i16 iCol){ ** columns, then this routine is no-op that always return iCol. If iCol ** is negative (indicating the ROWID column) then this routine return iCol. */ -SQLITE_PRIVATE i16 tdsqlite3TableColumnToStorage(Table *pTab, i16 iCol){ +SQLITE_PRIVATE i16 sqlite3TableColumnToStorage(Table *pTab, i16 iCol){ int i; i16 n; assert( iColnCol ); @@ -113726,10 +113726,10 @@ SQLITE_PRIVATE i16 tdsqlite3TableColumnToStorage(Table *pTab, i16 iCol){ ** The new table record is initialized and put in pParse->pNewTable. ** As more of the CREATE TABLE statement is parsed, additional action ** routines will be called to add more information to this record. -** At the end of the CREATE TABLE statement, the tdsqlite3EndTable() routine +** At the end of the CREATE TABLE statement, the sqlite3EndTable() routine ** is called to complete the construction of the new table record. */ -SQLITE_PRIVATE void tdsqlite3StartTable( +SQLITE_PRIVATE void sqlite3StartTable( Parse *pParse, /* Parser context */ Token *pName1, /* First part of the name of the table or view */ Token *pName2, /* Second part of the name of the table or view */ @@ -113740,7 +113740,7 @@ SQLITE_PRIVATE void tdsqlite3StartTable( ){ Table *pTable; char *zName = 0; /* The name of the new table */ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Vdbe *v; int iDb; /* Database number to create the table in */ Token *pName; /* Unqualified name of the table to create */ @@ -113748,27 +113748,27 @@ SQLITE_PRIVATE void tdsqlite3StartTable( if( db->init.busy && db->init.newTnum==1 ){ /* Special case: Parsing the sqlite_master or sqlite_temp_master schema */ iDb = db->init.iDb; - zName = tdsqlite3DbStrDup(db, SCHEMA_TABLE(iDb)); + zName = sqlite3DbStrDup(db, SCHEMA_TABLE(iDb)); pName = pName1; }else{ /* The common case */ - iDb = tdsqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ) return; if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ /* If creating a temp table, the name may not be qualified. Unless ** the database name is "temp" anyway. */ - tdsqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); + sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); return; } if( !OMIT_TEMPDB && isTemp ) iDb = 1; - zName = tdsqlite3NameFromToken(db, pName); + zName = sqlite3NameFromToken(db, pName); if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenMap(pParse, (void*)zName, pName); + sqlite3RenameTokenMap(pParse, (void*)zName, pName); } } pParse->sNameToken = *pName; if( zName==0 ) return; - if( tdsqlite3CheckObjectName(pParse, zName, isView?"view":"table", zName) ){ + if( sqlite3CheckObjectName(pParse, zName, isView?"view":"table", zName) ){ goto begin_table_error; } if( db->init.iDb==1 ) isTemp = 1; @@ -113783,10 +113783,10 @@ SQLITE_PRIVATE void tdsqlite3StartTable( SQLITE_CREATE_TEMP_VIEW }; char *zDb = db->aDb[iDb].zDbSName; - if( tdsqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(isTemp), 0, zDb) ){ goto begin_table_error; } - if( !isVirtual && tdsqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView], + if( !isVirtual && sqlite3AuthCheck(pParse, (int)aCode[isTemp+2*isView], zName, 0, zDb) ){ goto begin_table_error; } @@ -113796,32 +113796,32 @@ SQLITE_PRIVATE void tdsqlite3StartTable( /* Make sure the new table name does not collide with an existing ** index or table name in the same database. Issue an error message if ** it does. The exception is if the statement being parsed was passed - ** to an tdsqlite3_declare_vtab() call. In that case only the column names + ** to an sqlite3_declare_vtab() call. In that case only the column names ** and types will be used, so there is no need to test for namespace ** collisions. */ if( !IN_SPECIAL_PARSE ){ char *zDb = db->aDb[iDb].zDbSName; - if( SQLITE_OK!=tdsqlite3ReadSchema(pParse) ){ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto begin_table_error; } - pTable = tdsqlite3FindTable(db, zName, zDb); + pTable = sqlite3FindTable(db, zName, zDb); if( pTable ){ if( !noErr ){ - tdsqlite3ErrorMsg(pParse, "table %T already exists", pName); + sqlite3ErrorMsg(pParse, "table %T already exists", pName); }else{ assert( !db->init.busy || CORRUPT_DB ); - tdsqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iDb); } goto begin_table_error; } - if( tdsqlite3FindIndex(db, zName, zDb)!=0 ){ - tdsqlite3ErrorMsg(pParse, "there is already an index named %s", zName); + if( sqlite3FindIndex(db, zName, zDb)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already an index named %s", zName); goto begin_table_error; } } - pTable = tdsqlite3DbMallocZero(db, sizeof(Table)); + pTable = sqlite3DbMallocZero(db, sizeof(Table)); if( pTable==0 ){ assert( db->mallocFailed ); pParse->rc = SQLITE_NOMEM_BKPT; @@ -113833,9 +113833,9 @@ SQLITE_PRIVATE void tdsqlite3StartTable( pTable->pSchema = db->aDb[iDb].pSchema; pTable->nTabRef = 1; #ifdef SQLITE_DEFAULT_ROWEST - pTable->nRowLogEst = tdsqlite3LogEst(SQLITE_DEFAULT_ROWEST); + pTable->nRowLogEst = sqlite3LogEst(SQLITE_DEFAULT_ROWEST); #else - pTable->nRowLogEst = 200; assert( 200==tdsqlite3LogEst(1048576) ); + pTable->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); #endif assert( pParse->pNewTable==0 ); pParse->pNewTable = pTable; @@ -113846,7 +113846,7 @@ SQLITE_PRIVATE void tdsqlite3StartTable( */ #ifndef SQLITE_OMIT_AUTOINCREMENT if( !pParse->nested && strcmp(zName, "sqlite_sequence")==0 ){ - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pTable->pSchema->pSeqTab = pTable; } #endif @@ -113859,17 +113859,17 @@ SQLITE_PRIVATE void tdsqlite3StartTable( ** indices. Hence, the record number for the table must be allocated ** now. */ - if( !db->init.busy && (v = tdsqlite3GetVdbe(pParse))!=0 ){ + if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){ int addr1; int fileFormat; int reg1, reg2, reg3; /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */ static const char nullRow[] = { 6, 0, 0, 0, 0, 0 }; - tdsqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3BeginWriteOperation(pParse, 1, iDb); #ifndef SQLITE_OMIT_VIRTUALTABLE if( isVirtual ){ - tdsqlite3VdbeAddOp0(v, OP_VBegin); + sqlite3VdbeAddOp0(v, OP_VBegin); } #endif @@ -113879,39 +113879,39 @@ SQLITE_PRIVATE void tdsqlite3StartTable( reg1 = pParse->regRowid = ++pParse->nMem; reg2 = pParse->regRoot = ++pParse->nMem; reg3 = ++pParse->nMem; - tdsqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); - tdsqlite3VdbeUsesBtree(v, iDb); - addr1 = tdsqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT); + sqlite3VdbeUsesBtree(v, iDb); + addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v); fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ? 1 : SQLITE_MAX_FILE_FORMAT; - tdsqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat); - tdsqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db)); - tdsqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db)); + sqlite3VdbeJumpHere(v, addr1); /* This just creates a place-holder record in the sqlite_master table. ** The record created does not contain anything yet. It will be replaced - ** by the real entry in code generated at tdsqlite3EndTable(). + ** by the real entry in code generated at sqlite3EndTable(). ** ** The rowid for the new entry is left in register pParse->regRowid. ** The root page number of the new table is left in reg pParse->regRoot. ** The rowid and root page number values are needed by the code that - ** tdsqlite3EndTable will generate. + ** sqlite3EndTable will generate. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) if( isView || isVirtual ){ - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, reg2); + sqlite3VdbeAddOp2(v, OP_Integer, 0, reg2); }else #endif { pParse->addrCrTab = - tdsqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, reg2, BTREE_INTKEY); } - tdsqlite3OpenMasterTable(pParse, iDb); - tdsqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); - tdsqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC); - tdsqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); - tdsqlite3VdbeChangeP5(v, OPFLAG_APPEND); - tdsqlite3VdbeAddOp0(v, OP_Close); + sqlite3OpenMasterTable(pParse, iDb); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, reg1); + sqlite3VdbeAddOp4(v, OP_Blob, 6, reg3, 0, nullRow, P4_STATIC); + sqlite3VdbeAddOp3(v, OP_Insert, 0, reg3, reg1); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp0(v, OP_Close); } /* Normal (non-error) return. */ @@ -113919,7 +113919,7 @@ SQLITE_PRIVATE void tdsqlite3StartTable( /* If an error occurs, we jump here */ begin_table_error: - tdsqlite3DbFree(db, zName); + sqlite3DbFree(db, zName); return; } @@ -113927,8 +113927,8 @@ begin_table_error: ** name of the column. */ #if SQLITE_ENABLE_HIDDEN_COLUMNS -SQLITE_PRIVATE void tdsqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ - if( tdsqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){ +SQLITE_PRIVATE void sqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol){ + if( sqlite3_strnicmp(pCol->zName, "__hidden__", 10)==0 ){ pCol->colFlags |= COLFLAG_HIDDEN; }else if( pTab && pCol!=pTab->aCol && (pCol[-1].colFlags & COLFLAG_HIDDEN) ){ pTab->tabFlags |= TF_OOOHidden; @@ -113941,40 +113941,40 @@ SQLITE_PRIVATE void tdsqlite3ColumnPropertiesFromName(Table *pTab, Column *pCol) ** Add a new column to the table currently being constructed. ** ** The parser calls this routine once for each column declaration -** in a CREATE TABLE statement. tdsqlite3StartTable() gets called +** in a CREATE TABLE statement. sqlite3StartTable() gets called ** first to get things going. Then this routine is called for each ** column. */ -SQLITE_PRIVATE void tdsqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ +SQLITE_PRIVATE void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){ Table *p; int i; char *z; char *zType; Column *pCol; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( (p = pParse->pNewTable)==0 ) return; if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - tdsqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); + sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName); return; } - z = tdsqlite3DbMallocRaw(db, pName->n + pType->n + 2); + z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2); if( z==0 ) return; - if( IN_RENAME_OBJECT ) tdsqlite3RenameTokenMap(pParse, (void*)z, pName); + if( IN_RENAME_OBJECT ) sqlite3RenameTokenMap(pParse, (void*)z, pName); memcpy(z, pName->z, pName->n); z[pName->n] = 0; - tdsqlite3Dequote(z); + sqlite3Dequote(z); for(i=0; inCol; i++){ - if( tdsqlite3_stricmp(z, p->aCol[i].zName)==0 ){ - tdsqlite3ErrorMsg(pParse, "duplicate column name: %s", z); - tdsqlite3DbFree(db, z); + if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){ + sqlite3ErrorMsg(pParse, "duplicate column name: %s", z); + sqlite3DbFree(db, z); return; } } if( (p->nCol & 0x7)==0 ){ Column *aNew; - aNew = tdsqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); + aNew = sqlite3DbRealloc(db,p->aCol,(p->nCol+8)*sizeof(p->aCol[0])); if( aNew==0 ){ - tdsqlite3DbFree(db, z); + sqlite3DbFree(db, z); return; } p->aCol = aNew; @@ -113982,7 +113982,7 @@ SQLITE_PRIVATE void tdsqlite3AddColumn(Parse *pParse, Token *pName, Token *pType pCol = &p->aCol[p->nCol]; memset(pCol, 0, sizeof(p->aCol[0])); pCol->zName = z; - tdsqlite3ColumnPropertiesFromName(p, pCol); + sqlite3ColumnPropertiesFromName(p, pCol); if( pType->n==0 ){ /* If there is no type specified, columns have the default affinity @@ -113990,16 +113990,16 @@ SQLITE_PRIVATE void tdsqlite3AddColumn(Parse *pParse, Token *pName, Token *pType pCol->affinity = SQLITE_AFF_BLOB; pCol->szEst = 1; #ifdef SQLITE_ENABLE_SORTER_REFERENCES - if( 4>=tdsqlite3GlobalConfig.szSorterRef ){ + if( 4>=sqlite3GlobalConfig.szSorterRef ){ pCol->colFlags |= COLFLAG_SORTERREF; } #endif }else{ - zType = z + tdsqlite3Strlen30(z) + 1; + zType = z + sqlite3Strlen30(z) + 1; memcpy(zType, pType->z, pType->n); zType[pType->n] = 0; - tdsqlite3Dequote(zType); - pCol->affinity = tdsqlite3AffinityType(zType, pCol); + sqlite3Dequote(zType); + pCol->affinity = sqlite3AffinityType(zType, pCol); pCol->colFlags |= COLFLAG_HASTYPE; } p->nCol++; @@ -114013,7 +114013,7 @@ SQLITE_PRIVATE void tdsqlite3AddColumn(Parse *pParse, Token *pName, Token *pType ** been seen on a column. This routine sets the notNull flag on ** the column currently under construction. */ -SQLITE_PRIVATE void tdsqlite3AddNotNull(Parse *pParse, int onError){ +SQLITE_PRIVATE void sqlite3AddNotNull(Parse *pParse, int onError){ Table *p; Column *pCol; p = pParse->pNewTable; @@ -114060,14 +114060,14 @@ SQLITE_PRIVATE void tdsqlite3AddNotNull(Parse *pParse, int onError){ ** If none of the substrings in the above table are found, ** SQLITE_AFF_NUMERIC is returned. */ -SQLITE_PRIVATE char tdsqlite3AffinityType(const char *zIn, Column *pCol){ +SQLITE_PRIVATE char sqlite3AffinityType(const char *zIn, Column *pCol){ u32 h = 0; char aff = SQLITE_AFF_NUMERIC; const char *zChar = 0; assert( zIn!=0 ); while( zIn[0] ){ - h = (h<<8) + tdsqlite3UpperToLower[(*zIn)&0xff]; + h = (h<<8) + sqlite3UpperToLower[(*zIn)&0xff]; zIn++; if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){ /* CHAR */ aff = SQLITE_AFF_TEXT; @@ -114104,9 +114104,9 @@ SQLITE_PRIVATE char tdsqlite3AffinityType(const char *zIn, Column *pCol){ if( aff r=(k/4+1) */ - tdsqlite3GetInt32(zChar, &v); + sqlite3GetInt32(zChar, &v); break; } zChar++; @@ -114116,7 +114116,7 @@ SQLITE_PRIVATE char tdsqlite3AffinityType(const char *zIn, Column *pCol){ } } #ifdef SQLITE_ENABLE_SORTER_REFERENCES - if( v>=tdsqlite3GlobalConfig.szSorterRef ){ + if( v>=sqlite3GlobalConfig.szSorterRef ){ pCol->colFlags |= COLFLAG_SORTERREF; } #endif @@ -114137,7 +114137,7 @@ SQLITE_PRIVATE char tdsqlite3AffinityType(const char *zIn, Column *pCol){ ** This routine is called by the parser while in the middle of ** parsing a CREATE TABLE statement. */ -SQLITE_PRIVATE void tdsqlite3AddDefaultValue( +SQLITE_PRIVATE void sqlite3AddDefaultValue( Parse *pParse, /* Parsing context */ Expr *pExpr, /* The parsed expression of the default value */ const char *zStart, /* Start of the default value text */ @@ -114145,39 +114145,39 @@ SQLITE_PRIVATE void tdsqlite3AddDefaultValue( ){ Table *p; Column *pCol; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; p = pParse->pNewTable; if( p!=0 ){ int isInit = db->init.busy && db->init.iDb!=1; pCol = &(p->aCol[p->nCol-1]); - if( !tdsqlite3ExprIsConstantOrFunction(pExpr, isInit) ){ - tdsqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", + if( !sqlite3ExprIsConstantOrFunction(pExpr, isInit) ){ + sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant", pCol->zName); #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( pCol->colFlags & COLFLAG_GENERATED ){ testcase( pCol->colFlags & COLFLAG_VIRTUAL ); testcase( pCol->colFlags & COLFLAG_STORED ); - tdsqlite3ErrorMsg(pParse, "cannot use DEFAULT on a generated column"); + sqlite3ErrorMsg(pParse, "cannot use DEFAULT on a generated column"); #endif }else{ /* A copy of pExpr is used instead of the original, as pExpr contains ** tokens that point to volatile memory. */ Expr x; - tdsqlite3ExprDelete(db, pCol->pDflt); + sqlite3ExprDelete(db, pCol->pDflt); memset(&x, 0, sizeof(x)); x.op = TK_SPAN; - x.u.zToken = tdsqlite3DbSpanDup(db, zStart, zEnd); + x.u.zToken = sqlite3DbSpanDup(db, zStart, zEnd); x.pLeft = pExpr; x.flags = EP_Skip; - pCol->pDflt = tdsqlite3ExprDup(db, &x, EXPRDUP_REDUCE); - tdsqlite3DbFree(db, x.u.zToken); + pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE); + sqlite3DbFree(db, x.u.zToken); } } if( IN_RENAME_OBJECT ){ - tdsqlite3RenameExprUnmap(pParse, pExpr); + sqlite3RenameExprUnmap(pParse, pExpr); } - tdsqlite3ExprDelete(db, pExpr); + sqlite3ExprDelete(db, pExpr); } /* @@ -114196,7 +114196,7 @@ SQLITE_PRIVATE void tdsqlite3AddDefaultValue( ** If the expression is anything other than TK_STRING, the expression is ** unchanged. */ -static void tdsqlite3StringToId(Expr *p){ +static void sqlite3StringToId(Expr *p){ if( p->op==TK_STRING ){ p->op = TK_ID; }else if( p->op==TK_COLLATE && p->pLeft->op==TK_STRING ){ @@ -114213,7 +114213,7 @@ static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){ if( pCol->colFlags & COLFLAG_GENERATED ){ testcase( pCol->colFlags & COLFLAG_VIRTUAL ); testcase( pCol->colFlags & COLFLAG_STORED ); - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "generated columns cannot be part of the PRIMARY KEY"); } #endif @@ -114237,7 +114237,7 @@ static void makeColumnPartOfPrimaryKey(Parse *pParse, Column *pCol){ ** If the key is not an INTEGER PRIMARY KEY, then create a unique ** index for the key. No index is created for INTEGER PRIMARY KEYs. */ -SQLITE_PRIVATE void tdsqlite3AddPrimaryKey( +SQLITE_PRIVATE void sqlite3AddPrimaryKey( Parse *pParse, /* Parsing context */ ExprList *pList, /* List of field names to be indexed */ int onError, /* What to do with a uniqueness conflict */ @@ -114250,7 +114250,7 @@ SQLITE_PRIVATE void tdsqlite3AddPrimaryKey( int nTerm; if( pTab==0 ) goto primary_key_exit; if( pTab->tabFlags & TF_HasPrimaryKey ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "table \"%s\" has more than one primary key", pTab->zName); goto primary_key_exit; } @@ -114263,13 +114263,13 @@ SQLITE_PRIVATE void tdsqlite3AddPrimaryKey( }else{ nTerm = pList->nExpr; for(i=0; ia[i].pExpr); + Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr); assert( pCExpr!=0 ); - tdsqlite3StringToId(pCExpr); + sqlite3StringToId(pCExpr); if( pCExpr->op==TK_ID ){ const char *zCName = pCExpr->u.zToken; for(iCol=0; iColnCol; iCol++){ - if( tdsqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ + if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){ pCol = &pTab->aCol[iCol]; makeColumnPartOfPrimaryKey(pParse, pCol); break; @@ -114280,56 +114280,56 @@ SQLITE_PRIVATE void tdsqlite3AddPrimaryKey( } if( nTerm==1 && pCol - && tdsqlite3StrICmp(tdsqlite3ColumnType(pCol,""), "INTEGER")==0 + && sqlite3StrICmp(sqlite3ColumnType(pCol,""), "INTEGER")==0 && sortOrder!=SQLITE_SO_DESC ){ if( IN_RENAME_OBJECT && pList ){ - Expr *pCExpr = tdsqlite3ExprSkipCollate(pList->a[0].pExpr); - tdsqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr); + Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr); + sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr); } pTab->iPKey = iCol; pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags; - (void)tdsqlite3HasExplicitNulls(pParse, pList); + (void)sqlite3HasExplicitNulls(pParse, pList); }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT - tdsqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " + sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " "INTEGER PRIMARY KEY"); #endif }else{ - tdsqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, + sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0, SQLITE_IDXTYPE_PRIMARYKEY); pList = 0; } primary_key_exit: - tdsqlite3ExprListDelete(pParse->db, pList); + sqlite3ExprListDelete(pParse->db, pList); return; } /* ** Add a new CHECK constraint to the table currently under construction. */ -SQLITE_PRIVATE void tdsqlite3AddCheckConstraint( +SQLITE_PRIVATE void sqlite3AddCheckConstraint( Parse *pParse, /* Parsing context */ Expr *pCheckExpr /* The check expression */ ){ #ifndef SQLITE_OMIT_CHECK Table *pTab = pParse->pNewTable; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( pTab && !IN_DECLARE_VTAB - && !tdsqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) + && !sqlite3BtreeIsReadonly(db->aDb[db->init.iDb].pBt) ){ - pTab->pCheck = tdsqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); + pTab->pCheck = sqlite3ExprListAppend(pParse, pTab->pCheck, pCheckExpr); if( pParse->constraintName.n ){ - tdsqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); + sqlite3ExprListSetName(pParse, pTab->pCheck, &pParse->constraintName, 1); } }else #endif { - tdsqlite3ExprDelete(pParse->db, pCheckExpr); + sqlite3ExprDelete(pParse->db, pCheckExpr); } } @@ -114337,21 +114337,21 @@ SQLITE_PRIVATE void tdsqlite3AddCheckConstraint( ** Set the collation function of the most recently parsed table column ** to the CollSeq given. */ -SQLITE_PRIVATE void tdsqlite3AddCollateType(Parse *pParse, Token *pToken){ +SQLITE_PRIVATE void sqlite3AddCollateType(Parse *pParse, Token *pToken){ Table *p; int i; char *zColl; /* Dequoted name of collation sequence */ - tdsqlite3 *db; + sqlite3 *db; if( (p = pParse->pNewTable)==0 ) return; i = p->nCol-1; db = pParse->db; - zColl = tdsqlite3NameFromToken(db, pToken); + zColl = sqlite3NameFromToken(db, pToken); if( !zColl ) return; - if( tdsqlite3LocateCollSeq(pParse, zColl) ){ + if( sqlite3LocateCollSeq(pParse, zColl) ){ Index *pIdx; - tdsqlite3DbFree(db, p->aCol[i].zColl); + sqlite3DbFree(db, p->aCol[i].zColl); p->aCol[i].zColl = zColl; /* If the column is declared as " PRIMARY KEY COLLATE ", @@ -114365,14 +114365,14 @@ SQLITE_PRIVATE void tdsqlite3AddCollateType(Parse *pParse, Token *pToken){ } } }else{ - tdsqlite3DbFree(db, zColl); + sqlite3DbFree(db, zColl); } } /* Change the most recently parsed column to be a GENERATED ALWAYS AS ** column. */ -SQLITE_PRIVATE void tdsqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ +SQLITE_PRIVATE void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){ #ifndef SQLITE_OMIT_GENERATED_COLUMNS u8 eType = COLFLAG_VIRTUAL; Table *pTab = pParse->pNewTable; @@ -114383,14 +114383,14 @@ SQLITE_PRIVATE void tdsqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pTy } pCol = &(pTab->aCol[pTab->nCol-1]); if( IN_DECLARE_VTAB ){ - tdsqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns"); + sqlite3ErrorMsg(pParse, "virtual tables cannot use computed columns"); goto generated_done; } if( pCol->pDflt ) goto generated_error; if( pType ){ - if( pType->n==7 && tdsqlite3StrNICmp("virtual",pType->z,7)==0 ){ + if( pType->n==7 && sqlite3StrNICmp("virtual",pType->z,7)==0 ){ /* no-op */ - }else if( pType->n==6 && tdsqlite3StrNICmp("stored",pType->z,6)==0 ){ + }else if( pType->n==6 && sqlite3StrNICmp("stored",pType->z,6)==0 ){ eType = COLFLAG_STORED; }else{ goto generated_error; @@ -114409,15 +114409,15 @@ SQLITE_PRIVATE void tdsqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pTy goto generated_done; generated_error: - tdsqlite3ErrorMsg(pParse, "error in generated column \"%s\"", + sqlite3ErrorMsg(pParse, "error in generated column \"%s\"", pCol->zName); generated_done: - tdsqlite3ExprDelete(pParse->db, pExpr); + sqlite3ExprDelete(pParse->db, pExpr); #else /* Throw and error for the GENERATED ALWAYS AS clause if the ** SQLITE_OMIT_GENERATED_COLUMNS compile-time option is used. */ - tdsqlite3ErrorMsg(pParse, "generated columns not supported"); - tdsqlite3ExprDelete(pParse->db, pExpr); + sqlite3ErrorMsg(pParse, "generated columns not supported"); + sqlite3ExprDelete(pParse->db, pExpr); #endif } @@ -114440,11 +114440,11 @@ generated_done: ** IMPLEMENTATION-OF: R-34230-56049 SQLite automatically increments ** the schema-version whenever the schema changes. */ -SQLITE_PRIVATE void tdsqlite3ChangeCookie(Parse *pParse, int iDb){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE void sqlite3ChangeCookie(Parse *pParse, int iDb){ + sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); - tdsqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie)); } @@ -114483,10 +114483,10 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){ i = *pIdx; for(j=0; zIdent[j]; j++){ - if( !tdsqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break; + if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break; } - needQuote = tdsqlite3Isdigit(zIdent[0]) - || tdsqlite3KeywordCode(zIdent, j)!=TK_ID + needQuote = sqlite3Isdigit(zIdent[0]) + || sqlite3KeywordCode(zIdent, j)!=TK_ID || zIdent[j]!=0 || j==0; @@ -114505,7 +114505,7 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){ ** table. Memory to hold the text of the statement is obtained ** from sqliteMalloc() and must be freed by the calling function. */ -static char *createTableStmt(tdsqlite3 *db, Table *p){ +static char *createTableStmt(sqlite3 *db, Table *p){ int i, k, n; char *zStmt; char *zSep, *zSep2, *zEnd; @@ -114525,13 +114525,13 @@ static char *createTableStmt(tdsqlite3 *db, Table *p){ zEnd = "\n)"; } n += 35 + 6*p->nCol; - zStmt = tdsqlite3DbMallocRaw(0, n); + zStmt = sqlite3DbMallocRaw(0, n); if( zStmt==0 ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); return 0; } - tdsqlite3_snprintf(n, zStmt, "CREATE TABLE "); - k = tdsqlite3Strlen30(zStmt); + sqlite3_snprintf(n, zStmt, "CREATE TABLE "); + k = sqlite3Strlen30(zStmt); identPut(zStmt, &k, p->zName); zStmt[k++] = '('; for(pCol=p->aCol, i=0; inCol; i++, pCol++){ @@ -114545,8 +114545,8 @@ static char *createTableStmt(tdsqlite3 *db, Table *p){ int len; const char *zType; - tdsqlite3_snprintf(n-k, &zStmt[k], zSep); - k += tdsqlite3Strlen30(&zStmt[k]); + sqlite3_snprintf(n-k, &zStmt[k], zSep); + k += sqlite3Strlen30(&zStmt[k]); zSep = zSep2; identPut(zStmt, &k, pCol->zName); assert( pCol->affinity-SQLITE_AFF_BLOB >= 0 ); @@ -114558,14 +114558,14 @@ static char *createTableStmt(tdsqlite3 *db, Table *p){ testcase( pCol->affinity==SQLITE_AFF_REAL ); zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; - len = tdsqlite3Strlen30(zType); + len = sqlite3Strlen30(zType); assert( pCol->affinity==SQLITE_AFF_BLOB - || pCol->affinity==tdsqlite3AffinityType(zType, 0) ); + || pCol->affinity==sqlite3AffinityType(zType, 0) ); memcpy(&zStmt[k], zType, len); k += len; assert( k<=n ); } - tdsqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); + sqlite3_snprintf(n-k, &zStmt[k], "%s", zEnd); return zStmt; } @@ -114573,13 +114573,13 @@ static char *createTableStmt(tdsqlite3 *db, Table *p){ ** Resize an Index object to hold N columns total. Return SQLITE_OK ** on success and SQLITE_NOMEM on an OOM error. */ -static int resizeIndexObject(tdsqlite3 *db, Index *pIdx, int N){ +static int resizeIndexObject(sqlite3 *db, Index *pIdx, int N){ char *zExtra; int nByte; if( pIdx->nColumn>=N ) return SQLITE_OK; assert( pIdx->isResized==0 ); nByte = (sizeof(char*) + sizeof(i16) + 1)*N; - zExtra = tdsqlite3DbMallocZero(db, nByte); + zExtra = sqlite3DbMallocZero(db, nByte); if( zExtra==0 ) return SQLITE_NOMEM_BKPT; memcpy(zExtra, pIdx->azColl, sizeof(char*)*pIdx->nColumn); pIdx->azColl = (const char**)zExtra; @@ -114605,7 +114605,7 @@ static void estimateTableWidth(Table *pTab){ wTable += pTabCol->szEst; } if( pTab->iPKey<0 ) wTable++; - pTab->szTabRow = tdsqlite3LogEst(wTable*4); + pTab->szTabRow = sqlite3LogEst(wTable*4); } /* @@ -114620,7 +114620,7 @@ static void estimateIndexWidth(Index *pIdx){ assert( xpTable->nCol ); wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst; } - pIdx->szIdxRow = tdsqlite3LogEst(wIndex*4); + pIdx->szIdxRow = sqlite3LogEst(wIndex*4); } /* Return true if column number x is any of the first nCol entries of aiCol[]. @@ -114663,7 +114663,7 @@ static int isDupColumn(Index *pIdx, int nKey, Index *pPk, int iCol){ for(i=0; iaiColumn[i]>=0 || j>=0 ); if( pIdx->aiColumn[i]==j - && tdsqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0 + && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0 ){ return 1; } @@ -114735,7 +114735,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ int nPk; int nExtra; int i, j; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables) @@ -114754,7 +114754,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ */ if( pParse->addrCrTab ){ assert( v ); - tdsqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY); + sqlite3VdbeChangeP3(v, pParse->addrCrTab, BTREE_BLOBKEY); } /* Locate the PRIMARY KEY index. Or, if this table was originally @@ -114763,23 +114763,23 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( pTab->iPKey>=0 ){ ExprList *pList; Token ipkToken; - tdsqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); - pList = tdsqlite3ExprListAppend(pParse, 0, - tdsqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); + sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName); + pList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ) return; if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); + sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); } pList->a[0].sortFlags = pParse->iPkSortOrder; assert( pParse->pNewTable==pTab ); pTab->iPKey = -1; - tdsqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, + sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, SQLITE_IDXTYPE_PRIMARYKEY); if( db->mallocFailed || pParse->nErr ) return; - pPk = tdsqlite3PrimaryKeyIndex(pTab); + pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk->nKeyCol==1 ); }else{ - pPk = tdsqlite3PrimaryKeyIndex(pTab); + pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); /* @@ -114810,7 +114810,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** a database schema). */ if( v && pPk->tnum>0 ){ assert( db->init.busy==0 ); - tdsqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto); + sqlite3VdbeChangeOpcode(v, pPk->tnum, OP_Goto); } /* The root page of the PRIMARY KEY is the table root page */ @@ -114864,7 +114864,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ){ assert( jnColumn ); pPk->aiColumn[j] = i; - pPk->azColl[j] = tdsqlite3StrBINARY; + pPk->azColl[j] = sqlite3StrBINARY; j++; } } @@ -114881,7 +114881,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ ** zName is temporarily modified while this routine is running, but is ** restored to its original value prior to this routine returning. */ -SQLITE_PRIVATE int tdsqlite3ShadowTableName(tdsqlite3 *db, const char *zName){ +SQLITE_PRIVATE int sqlite3ShadowTableName(sqlite3 *db, const char *zName){ char *zTail; /* Pointer to the last "_" in zName */ Table *pTab; /* Table that zName is a shadow of */ Module *pMod; /* Module for the virtual table */ @@ -114889,11 +114889,11 @@ SQLITE_PRIVATE int tdsqlite3ShadowTableName(tdsqlite3 *db, const char *zName){ zTail = strrchr(zName, '_'); if( zTail==0 ) return 0; *zTail = 0; - pTab = tdsqlite3FindTable(db, zName, 0); + pTab = sqlite3FindTable(db, zName, 0); *zTail = '_'; if( pTab==0 ) return 0; if( !IsVirtual(pTab) ) return 0; - pMod = (Module*)tdsqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); + pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]); if( pMod==0 ) return 0; if( pMod->pModule->iVersion<3 ) return 0; if( pMod->pModule->xShadowName==0 ) return 0; @@ -114921,7 +114921,7 @@ SQLITE_PRIVATE int tdsqlite3ShadowTableName(tdsqlite3 *db, const char *zName){ ** "CREATE TABLE ... AS SELECT ..." statement. The column names of ** the new table will match the result set of the SELECT. */ -SQLITE_PRIVATE void tdsqlite3EndTable( +SQLITE_PRIVATE void sqlite3EndTable( Parse *pParse, /* Parse context */ Token *pCons, /* The ',' token after the last column defn. */ Token *pEnd, /* The ')' before options in the CREATE TABLE */ @@ -114929,7 +114929,7 @@ SQLITE_PRIVATE void tdsqlite3EndTable( Select *pSelect /* Select from a "CREATE ... AS SELECT" */ ){ Table *p; /* The new table */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ int iDb; /* Database in which the table lives */ Index *pIdx; /* An implied index of the table */ @@ -114940,7 +114940,7 @@ SQLITE_PRIVATE void tdsqlite3EndTable( p = pParse->pNewTable; if( p==0 ) return; - if( pSelect==0 && tdsqlite3ShadowTableName(db, p->zName) ){ + if( pSelect==0 && sqlite3ShadowTableName(db, p->zName) ){ p->tabFlags |= TF_Shadow; } @@ -114955,7 +114955,7 @@ SQLITE_PRIVATE void tdsqlite3EndTable( */ if( db->init.busy ){ if( pSelect ){ - tdsqlite3ErrorMsg(pParse, ""); + sqlite3ErrorMsg(pParse, ""); return; } p->tnum = db->init.newTnum; @@ -114963,35 +114963,35 @@ SQLITE_PRIVATE void tdsqlite3EndTable( } assert( (p->tabFlags & TF_HasPrimaryKey)==0 - || p->iPKey>=0 || tdsqlite3PrimaryKeyIndex(p)!=0 ); + || p->iPKey>=0 || sqlite3PrimaryKeyIndex(p)!=0 ); assert( (p->tabFlags & TF_HasPrimaryKey)!=0 - || (p->iPKey<0 && tdsqlite3PrimaryKeyIndex(p)==0) ); + || (p->iPKey<0 && sqlite3PrimaryKeyIndex(p)==0) ); /* Special processing for WITHOUT ROWID Tables */ if( tabOpts & TF_WithoutRowid ){ if( (p->tabFlags & TF_Autoincrement) ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "AUTOINCREMENT not allowed on WITHOUT ROWID tables"); return; } if( (p->tabFlags & TF_HasPrimaryKey)==0 ){ - tdsqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName); + sqlite3ErrorMsg(pParse, "PRIMARY KEY missing on table %s", p->zName); return; } p->tabFlags |= TF_WithoutRowid | TF_NoVisibleRowid; convertToWithoutRowidTable(pParse, p); } - iDb = tdsqlite3SchemaToIndex(db, p->pSchema); + iDb = sqlite3SchemaToIndex(db, p->pSchema); #ifndef SQLITE_OMIT_CHECK /* Resolve names in all CHECK constraint expressions. */ if( p->pCheck ){ - tdsqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); + sqlite3ResolveSelfReference(pParse, p, NC_IsCheck, 0, p->pCheck); if( pParse->nErr ){ /* If errors are seen, delete the CHECK constraints now, else they might ** actually be used if PRAGMA writable_schema=ON is set. */ - tdsqlite3ExprListDelete(db, p->pCheck); + sqlite3ExprListDelete(db, p->pCheck); p->pCheck = 0; } } @@ -115007,22 +115007,22 @@ SQLITE_PRIVATE void tdsqlite3EndTable( Expr *pX = p->aCol[ii].pDflt; testcase( colFlags & COLFLAG_VIRTUAL ); testcase( colFlags & COLFLAG_STORED ); - if( tdsqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){ + if( sqlite3ResolveSelfReference(pParse, p, NC_GenCol, pX, 0) ){ /* If there are errors in resolving the expression, change the ** expression to a NULL. This prevents code generators that operate ** on the expression from inserting extra parts into the expression ** tree that have been allocated from lookaside memory, which is ** illegal in a schema and will lead to errors or heap corruption ** when the database connection closes. */ - tdsqlite3ExprDelete(db, pX); - p->aCol[ii].pDflt = tdsqlite3ExprAlloc(db, TK_NULL, 0, 0); + sqlite3ExprDelete(db, pX); + p->aCol[ii].pDflt = sqlite3ExprAlloc(db, TK_NULL, 0, 0); } }else{ nNG++; } } if( nNG==0 ){ - tdsqlite3ErrorMsg(pParse, "must have at least one non-generated column"); + sqlite3ErrorMsg(pParse, "must have at least one non-generated column"); return; } } @@ -115047,10 +115047,10 @@ SQLITE_PRIVATE void tdsqlite3EndTable( char *zType2; /* "VIEW" or "TABLE" */ char *zStmt; /* Text of the CREATE TABLE or CREATE VIEW statement */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( NEVER(v==0) ) return; - tdsqlite3VdbeAddOp1(v, OP_Close, 0); + sqlite3VdbeAddOp1(v, OP_Close, 0); /* ** Initialize zType for the new view or table. @@ -115071,7 +115071,7 @@ SQLITE_PRIVATE void tdsqlite3EndTable( ** statement to populate the new table. The root-page number for the ** new table is in register pParse->regRoot. ** - ** Once the SELECT has been coded by tdsqlite3Select(), it is in a + ** Once the SELECT has been coded by sqlite3Select(), it is in a ** suitable state to query for the column names and types to be used ** by the new table. ** @@ -115093,35 +115093,35 @@ SQLITE_PRIVATE void tdsqlite3EndTable( regRec = ++pParse->nMem; regRowid = ++pParse->nMem; assert(pParse->nTab==1); - tdsqlite3MayAbort(pParse); - tdsqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); - tdsqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); + sqlite3MayAbort(pParse); + sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); + sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); pParse->nTab = 2; - addrTop = tdsqlite3VdbeCurrentAddr(v) + 1; - tdsqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); if( pParse->nErr ) return; - pSelTab = tdsqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB); + pSelTab = sqlite3ResultSetOfSelect(pParse, pSelect, SQLITE_AFF_BLOB); if( pSelTab==0 ) return; assert( p->aCol==0 ); p->nCol = p->nNVCol = pSelTab->nCol; p->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; - tdsqlite3DeleteTable(db, pSelTab); - tdsqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); - tdsqlite3Select(pParse, pSelect, &dest); + sqlite3DeleteTable(db, pSelTab); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + sqlite3Select(pParse, pSelect, &dest); if( pParse->nErr ) return; - tdsqlite3VdbeEndCoroutine(v, regYield); - tdsqlite3VdbeJumpHere(v, addrTop - 1); - addrInsLoop = tdsqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); + addrInsLoop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); - tdsqlite3TableAffinity(v, p, 0); - tdsqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid); - tdsqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid); - tdsqlite3VdbeGoto(v, addrInsLoop); - tdsqlite3VdbeJumpHere(v, addrInsLoop); - tdsqlite3VdbeAddOp1(v, OP_Close, 1); + sqlite3VdbeAddOp3(v, OP_MakeRecord, dest.iSdst, dest.nSdst, regRec); + sqlite3TableAffinity(v, p, 0); + sqlite3VdbeAddOp2(v, OP_NewRowid, 1, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, 1, regRec, regRowid); + sqlite3VdbeGoto(v, addrInsLoop); + sqlite3VdbeJumpHere(v, addrInsLoop); + sqlite3VdbeAddOp1(v, OP_Close, 1); } /* Compute the complete text of the CREATE statement */ @@ -115131,7 +115131,7 @@ SQLITE_PRIVATE void tdsqlite3EndTable( Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd; n = (int)(pEnd2->z - pParse->sNameToken.z); if( pEnd2->z[0]!=';' ) n += pEnd2->n; - zStmt = tdsqlite3MPrintf(db, + zStmt = sqlite3MPrintf(db, "CREATE %s %.*s", zType2, n, pParse->sNameToken.z ); } @@ -115140,7 +115140,7 @@ SQLITE_PRIVATE void tdsqlite3EndTable( ** SQLITE_MASTER table. We just need to update that slot with all ** the information we've collected. */ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE %Q.%s " "SET type='%s', name=%Q, tbl_name=%Q, rootpage=#%d, sql=%Q " "WHERE rowid=#%d", @@ -115152,8 +115152,8 @@ SQLITE_PRIVATE void tdsqlite3EndTable( zStmt, pParse->regRowid ); - tdsqlite3DbFree(db, zStmt); - tdsqlite3ChangeCookie(pParse, iDb); + sqlite3DbFree(db, zStmt); + sqlite3ChangeCookie(pParse, iDb); #ifndef SQLITE_OMIT_AUTOINCREMENT /* Check to see if we need to create an sqlite_sequence table for @@ -115161,9 +115161,9 @@ SQLITE_PRIVATE void tdsqlite3EndTable( */ if( (p->tabFlags & TF_Autoincrement)!=0 ){ Db *pDb = &db->aDb[iDb]; - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( pDb->pSchema->pSeqTab==0 ){ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "CREATE TABLE %Q.sqlite_sequence(name,seq)", pDb->zDbSName ); @@ -115172,8 +115172,8 @@ SQLITE_PRIVATE void tdsqlite3EndTable( #endif /* Reparse everything to update our internal data structures */ - tdsqlite3VdbeAddParseSchemaOp(v, iDb, - tdsqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName)); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName)); } /* Add the table to the in-memory representation of the database. @@ -115181,11 +115181,11 @@ SQLITE_PRIVATE void tdsqlite3EndTable( if( db->init.busy ){ Table *pOld; Schema *pSchema = p->pSchema; - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); - pOld = tdsqlite3HashInsert(&pSchema->tblHash, p->zName, p); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); + pOld = sqlite3HashInsert(&pSchema->tblHash, p->zName, p); if( pOld ){ assert( p==pOld ); /* Malloc must have failed inside HashInsert() */ - tdsqlite3OomFault(db); + sqlite3OomFault(db); return; } pParse->pNewTable = 0; @@ -115200,7 +115200,7 @@ SQLITE_PRIVATE void tdsqlite3EndTable( pCons = pEnd; } nName = (int)((const char *)pCons->z - zName); - p->addColOffset = 13 + tdsqlite3Utf8CharLen(zName, nName); + p->addColOffset = 13 + sqlite3Utf8CharLen(zName, nName); } #endif } @@ -115210,7 +115210,7 @@ SQLITE_PRIVATE void tdsqlite3EndTable( /* ** The parser calls this routine in order to create a new VIEW */ -SQLITE_PRIVATE void tdsqlite3CreateView( +SQLITE_PRIVATE void sqlite3CreateView( Parse *pParse, /* The parsing context */ Token *pBegin, /* The CREATE token that begins the statement */ Token *pName1, /* The token that holds the name of the view */ @@ -115227,33 +115227,33 @@ SQLITE_PRIVATE void tdsqlite3CreateView( DbFixer sFix; Token *pName = 0; int iDb; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( pParse->nVar>0 ){ - tdsqlite3ErrorMsg(pParse, "parameters are not allowed in views"); + sqlite3ErrorMsg(pParse, "parameters are not allowed in views"); goto create_view_fail; } - tdsqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); + sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr); p = pParse->pNewTable; if( p==0 || pParse->nErr ) goto create_view_fail; - tdsqlite3TwoPartName(pParse, pName1, pName2, &pName); - iDb = tdsqlite3SchemaToIndex(db, p->pSchema); - tdsqlite3FixInit(&sFix, pParse, iDb, "view", pName); - if( tdsqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail; + sqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3SchemaToIndex(db, p->pSchema); + sqlite3FixInit(&sFix, pParse, iDb, "view", pName); + if( sqlite3FixSelect(&sFix, pSelect) ) goto create_view_fail; /* Make a copy of the entire SELECT statement that defines the view. ** This will force all the Expr.token.z values to be dynamically ** allocated rather than point to the input string - which means that - ** they will persist after the current tdsqlite3_exec() call returns. + ** they will persist after the current sqlite3_exec() call returns. */ pSelect->selFlags |= SF_View; if( IN_RENAME_OBJECT ){ p->pSelect = pSelect; pSelect = 0; }else{ - p->pSelect = tdsqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + p->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); } - p->pCheck = tdsqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); + p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE); if( db->mallocFailed ) goto create_view_fail; /* Locate the end of the CREATE VIEW statement. Make sEnd point to @@ -115268,19 +115268,19 @@ SQLITE_PRIVATE void tdsqlite3CreateView( n = (int)(sEnd.z - pBegin->z); assert( n>0 ); z = pBegin->z; - while( tdsqlite3Isspace(z[n-1]) ){ n--; } + while( sqlite3Isspace(z[n-1]) ){ n--; } sEnd.z = &z[n-1]; sEnd.n = 1; - /* Use tdsqlite3EndTable() to add the view to the SQLITE_MASTER table */ - tdsqlite3EndTable(pParse, 0, &sEnd, 0, 0); + /* Use sqlite3EndTable() to add the view to the SQLITE_MASTER table */ + sqlite3EndTable(pParse, 0, &sEnd, 0, 0); create_view_fail: - tdsqlite3SelectDelete(db, pSelect); + sqlite3SelectDelete(db, pSelect); if( IN_RENAME_OBJECT ){ - tdsqlite3RenameExprlistUnmap(pParse, pCNames); + sqlite3RenameExprlistUnmap(pParse, pCNames); } - tdsqlite3ExprListDelete(db, pCNames); + sqlite3ExprListDelete(db, pCNames); return; } #endif /* SQLITE_OMIT_VIEW */ @@ -115291,24 +115291,24 @@ create_view_fail: ** the columns of the view in the pTable structure. Return the number ** of errors. If an error is seen leave an error message in pParse->zErrMsg. */ -SQLITE_PRIVATE int tdsqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ +SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ Table *pSelTab; /* A fake table from which we get the result set */ Select *pSel; /* Copy of the SELECT that implements the view */ int nErr = 0; /* Number of errors encountered */ int n; /* Temporarily holds the number of cursors assigned */ - tdsqlite3 *db = pParse->db; /* Database connection for malloc errors */ + sqlite3 *db = pParse->db; /* Database connection for malloc errors */ #ifndef SQLITE_OMIT_VIRTUALTABLE int rc; #endif #ifndef SQLITE_OMIT_AUTHORIZATION - tdsqlite3_xauth xAuth; /* Saved xAuth pointer */ + sqlite3_xauth xAuth; /* Saved xAuth pointer */ #endif assert( pTable ); #ifndef SQLITE_OMIT_VIRTUALTABLE db->nSchemaLock++; - rc = tdsqlite3VtabCallConnect(pParse, pTable); + rc = sqlite3VtabCallConnect(pParse, pTable); db->nSchemaLock--; if( rc ){ return 1; @@ -115338,36 +115338,36 @@ SQLITE_PRIVATE int tdsqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** SELECT * FROM temp.ex1; */ if( pTable->nCol<0 ){ - tdsqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); + sqlite3ErrorMsg(pParse, "view %s is circularly defined", pTable->zName); return 1; } assert( pTable->nCol>=0 ); /* If we get this far, it means we need to compute the table names. - ** Note that the call to tdsqlite3ResultSetOfSelect() will expand any + ** Note that the call to sqlite3ResultSetOfSelect() will expand any ** "*" elements in the results set of the view and will assign cursors ** to the elements of the FROM clause. But we do not want these changes ** to be permanent. So the computation is done on a copy of the SELECT ** statement that defines the view. */ assert( pTable->pSelect ); - pSel = tdsqlite3SelectDup(db, pTable->pSelect, 0); + pSel = sqlite3SelectDup(db, pTable->pSelect, 0); if( pSel ){ #ifndef SQLITE_OMIT_ALTERTABLE u8 eParseMode = pParse->eParseMode; pParse->eParseMode = PARSE_MODE_NORMAL; #endif n = pParse->nTab; - tdsqlite3SrcListAssignCursors(pParse, pSel->pSrc); + sqlite3SrcListAssignCursors(pParse, pSel->pSrc); pTable->nCol = -1; DisableLookaside; #ifndef SQLITE_OMIT_AUTHORIZATION xAuth = db->xAuth; db->xAuth = 0; - pSelTab = tdsqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); db->xAuth = xAuth; #else - pSelTab = tdsqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); + pSelTab = sqlite3ResultSetOfSelect(pParse, pSel, SQLITE_AFF_NONE); #endif pParse->nTab = n; if( pSelTab==0 ){ @@ -115380,13 +115380,13 @@ SQLITE_PRIVATE int tdsqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ ** normally holds CHECK constraints on an ordinary table, but for ** a VIEW it holds the list of column names. */ - tdsqlite3ColumnsFromExprList(pParse, pTable->pCheck, + sqlite3ColumnsFromExprList(pParse, pTable->pCheck, &pTable->nCol, &pTable->aCol); if( db->mallocFailed==0 && pParse->nErr==0 && pTable->nCol==pSel->pEList->nExpr ){ - tdsqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, + sqlite3SelectAddColumnTypeAndCollation(pParse, pTable, pSel, SQLITE_AFF_NONE); } }else{ @@ -115398,11 +115398,11 @@ SQLITE_PRIVATE int tdsqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ pTable->aCol = pSelTab->aCol; pSelTab->nCol = 0; pSelTab->aCol = 0; - assert( tdsqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); + assert( sqlite3SchemaMutexHeld(db, 0, pTable->pSchema) ); } pTable->nNVCol = pTable->nCol; - tdsqlite3DeleteTable(db, pSelTab); - tdsqlite3SelectDelete(db, pSel); + sqlite3DeleteTable(db, pSelTab); + sqlite3SelectDelete(db, pSel); EnableLookaside; #ifndef SQLITE_OMIT_ALTERTABLE pParse->eParseMode = eParseMode; @@ -115412,7 +115412,7 @@ SQLITE_PRIVATE int tdsqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ } pTable->pSchema->schemaFlags |= DB_UnresetViews; if( db->mallocFailed ){ - tdsqlite3DeleteColumnNames(db, pTable); + sqlite3DeleteColumnNames(db, pTable); pTable->aCol = 0; pTable->nCol = 0; } @@ -115425,14 +115425,14 @@ SQLITE_PRIVATE int tdsqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ /* ** Clear the column names from every VIEW in database idx. */ -static void sqliteViewResetAll(tdsqlite3 *db, int idx){ +static void sqliteViewResetAll(sqlite3 *db, int idx){ HashElem *i; - assert( tdsqlite3SchemaMutexHeld(db, idx, 0) ); + assert( sqlite3SchemaMutexHeld(db, idx, 0) ); if( !DbHasProperty(db, idx, DB_UnresetViews) ) return; for(i=sqliteHashFirst(&db->aDb[idx].pSchema->tblHash); i;i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); if( pTab->pSelect ){ - tdsqlite3DeleteColumnNames(db, pTab); + sqlite3DeleteColumnNames(db, pTab); pTab->aCol = 0; pTab->nCol = 0; } @@ -115461,12 +115461,12 @@ static void sqliteViewResetAll(tdsqlite3 *db, int idx){ ** in order to be certain that we got the right one. */ #ifndef SQLITE_OMIT_AUTOVACUUM -SQLITE_PRIVATE void tdsqlite3RootPageMoved(tdsqlite3 *db, int iDb, int iFrom, int iTo){ +SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3 *db, int iDb, int iFrom, int iTo){ HashElem *pElem; Hash *pHash; Db *pDb; - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pDb = &db->aDb[iDb]; pHash = &pDb->pSchema->tblHash; for(pElem=sqliteHashFirst(pHash); pElem; pElem=sqliteHashNext(pElem)){ @@ -115492,11 +115492,11 @@ SQLITE_PRIVATE void tdsqlite3RootPageMoved(tdsqlite3 *db, int iDb, int iFrom, in ** erasing iTable (this can happen with an auto-vacuum database). */ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ - Vdbe *v = tdsqlite3GetVdbe(pParse); - int r1 = tdsqlite3GetTempReg(pParse); - if( iTable<2 ) tdsqlite3ErrorMsg(pParse, "corrupt schema"); - tdsqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); - tdsqlite3MayAbort(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); + int r1 = sqlite3GetTempReg(pParse); + if( iTable<2 ) sqlite3ErrorMsg(pParse, "corrupt schema"); + sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); + sqlite3MayAbort(pParse); #ifndef SQLITE_OMIT_AUTOVACUUM /* OP_Destroy stores an in integer r1. If this integer ** is non-zero, then it is the root page number of a table moved to @@ -115507,11 +115507,11 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ ** is in register NNN. See grammar rules associated with the TK_REGISTER ** token for additional information. */ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE %Q.%s SET rootpage=%d WHERE #%d AND rootpage=#%d", pParse->db->aDb[iDb].zDbSName, MASTER_NAME, iTable, r1, r1); #endif - tdsqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r1); } /* @@ -115557,7 +115557,7 @@ static void destroyTable(Parse *pParse, Table *pTab){ if( iLargest==0 ){ return; }else{ - int iDb = tdsqlite3SchemaToIndex(pParse->db, pTab->pSchema); + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); assert( iDb>=0 && iDbdb->nDb ); destroyRootPage(pParse, iLargest, iDb); iDestroyed = iLargest; @@ -115569,7 +115569,7 @@ static void destroyTable(Parse *pParse, Table *pTab){ ** Remove entries from the sqlite_statN tables (for N in (1,2,3)) ** after a DROP INDEX or DROP TABLE command. */ -static void tdsqlite3ClearStatTables( +static void sqlite3ClearStatTables( Parse *pParse, /* The parsing context */ int iDb, /* The database number */ const char *zType, /* "idx" or "tbl" */ @@ -115579,9 +115579,9 @@ static void tdsqlite3ClearStatTables( const char *zDbName = pParse->db->aDb[iDb].zDbSName; for(i=1; i<=4; i++){ char zTab[24]; - tdsqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); - if( tdsqlite3FindTable(pParse->db, zTab, zDbName) ){ - tdsqlite3NestedParse(pParse, + sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); + if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE %s=%Q", zDbName, zTab, zType, zName ); @@ -115592,19 +115592,19 @@ static void tdsqlite3ClearStatTables( /* ** Generate code to drop a table. */ -SQLITE_PRIVATE void tdsqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ +SQLITE_PRIVATE void sqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, int isView){ Vdbe *v; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Trigger *pTrigger; Db *pDb = &db->aDb[iDb]; - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); assert( v!=0 ); - tdsqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3BeginWriteOperation(pParse, 1, iDb); #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ - tdsqlite3VdbeAddOp0(v, OP_VBegin); + sqlite3VdbeAddOp0(v, OP_VBegin); } #endif @@ -115612,11 +115612,11 @@ SQLITE_PRIVATE void tdsqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, ** is generated to remove entries from sqlite_master and/or ** sqlite_temp_master if required. */ - pTrigger = tdsqlite3TriggerList(pParse, pTab); + pTrigger = sqlite3TriggerList(pParse, pTab); while( pTrigger ){ assert( pTrigger->pSchema==pTab->pSchema || pTrigger->pSchema==db->aDb[1].pSchema ); - tdsqlite3DropTriggerPtr(pParse, pTrigger); + sqlite3DropTriggerPtr(pParse, pTrigger); pTrigger = pTrigger->pNext; } @@ -115627,7 +115627,7 @@ SQLITE_PRIVATE void tdsqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, ** move as a result of the drop (can happen in auto-vacuum mode). */ if( pTab->tabFlags & TF_Autoincrement ){ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "DELETE FROM %Q.sqlite_sequence WHERE name=%Q", pDb->zDbSName, pTab->zName ); @@ -115641,7 +115641,7 @@ SQLITE_PRIVATE void tdsqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, ** created in the temp database that refers to a table in another ** database. */ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE tbl_name=%Q and type!='trigger'", pDb->zDbSName, MASTER_NAME, pTab->zName); if( !isView && !IsVirtual(pTab) ){ @@ -115652,11 +115652,11 @@ SQLITE_PRIVATE void tdsqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, ** the schema cookie. */ if( IsVirtual(pTab) ){ - tdsqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); - tdsqlite3MayAbort(pParse); + sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0); + sqlite3MayAbort(pParse); } - tdsqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); - tdsqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); + sqlite3ChangeCookie(pParse, iDb); sqliteViewResetAll(db, iDb); } @@ -115664,7 +115664,7 @@ SQLITE_PRIVATE void tdsqlite3CodeDropTable(Parse *pParse, Table *pTab, int iDb, ** Return TRUE if shadow tables should be read-only in the current ** context. */ -SQLITE_PRIVATE int tdsqlite3ReadOnlyShadowTables(tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3ReadOnlyShadowTables(sqlite3 *db){ #ifndef SQLITE_OMIT_VIRTUALTABLE if( (db->flags & SQLITE_Defensive)!=0 && db->pVtabCtx==0 @@ -115679,13 +115679,13 @@ SQLITE_PRIVATE int tdsqlite3ReadOnlyShadowTables(tdsqlite3 *db){ /* ** Return true if it is not allowed to drop the given table */ -static int tableMayNotBeDropped(tdsqlite3 *db, Table *pTab){ - if( tdsqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ - if( tdsqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0; - if( tdsqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0; +static int tableMayNotBeDropped(sqlite3 *db, Table *pTab){ + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + if( sqlite3StrNICmp(pTab->zName+7, "stat", 4)==0 ) return 0; + if( sqlite3StrNICmp(pTab->zName+7, "parameters", 10)==0 ) return 0; return 1; } - if( (pTab->tabFlags & TF_Shadow)!=0 && tdsqlite3ReadOnlyShadowTables(db) ){ + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ return 1; } return 0; @@ -115695,10 +115695,10 @@ static int tableMayNotBeDropped(tdsqlite3 *db, Table *pTab){ ** This routine is called to do the work of a DROP TABLE statement. ** pName is the name of the table to be dropped. */ -SQLITE_PRIVATE void tdsqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ +SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, int noErr){ Table *pTab; Vdbe *v; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int iDb; if( db->mallocFailed ){ @@ -115706,23 +115706,23 @@ SQLITE_PRIVATE void tdsqlite3DropTable(Parse *pParse, SrcList *pName, int isView } assert( pParse->nErr==0 ); assert( pName->nSrc==1 ); - if( tdsqlite3ReadSchema(pParse) ) goto exit_drop_table; + if( sqlite3ReadSchema(pParse) ) goto exit_drop_table; if( noErr ) db->suppressErr++; assert( isView==0 || isView==LOCATE_VIEW ); - pTab = tdsqlite3LocateTableItem(pParse, isView, &pName->a[0]); + pTab = sqlite3LocateTableItem(pParse, isView, &pName->a[0]); if( noErr ) db->suppressErr--; if( pTab==0 ){ - if( noErr ) tdsqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + if( noErr ) sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); goto exit_drop_table; } - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 && iDbnDb ); /* If pTab is a virtual table, call ViewGetColumnNames() to ensure ** it is initialized. */ - if( IsVirtual(pTab) && tdsqlite3ViewGetColumnNames(pParse, pTab) ){ + if( IsVirtual(pTab) && sqlite3ViewGetColumnNames(pParse, pTab) ){ goto exit_drop_table; } #ifndef SQLITE_OMIT_AUTHORIZATION @@ -115731,7 +115731,7 @@ SQLITE_PRIVATE void tdsqlite3DropTable(Parse *pParse, SrcList *pName, int isView const char *zTab = SCHEMA_TABLE(iDb); const char *zDb = db->aDb[iDb].zDbSName; const char *zArg2 = 0; - if( tdsqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb)){ goto exit_drop_table; } if( isView ){ @@ -115743,7 +115743,7 @@ SQLITE_PRIVATE void tdsqlite3DropTable(Parse *pParse, SrcList *pName, int isView #ifndef SQLITE_OMIT_VIRTUALTABLE }else if( IsVirtual(pTab) ){ code = SQLITE_DROP_VTABLE; - zArg2 = tdsqlite3GetVTable(db, pTab)->pMod->zName; + zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName; #endif }else{ if( !OMIT_TEMPDB && iDb==1 ){ @@ -115752,16 +115752,16 @@ SQLITE_PRIVATE void tdsqlite3DropTable(Parse *pParse, SrcList *pName, int isView code = SQLITE_DROP_TABLE; } } - if( tdsqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ + if( sqlite3AuthCheck(pParse, code, pTab->zName, zArg2, zDb) ){ goto exit_drop_table; } - if( tdsqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, zDb) ){ goto exit_drop_table; } } #endif if( tableMayNotBeDropped(db, pTab) ){ - tdsqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); + sqlite3ErrorMsg(pParse, "table %s may not be dropped", pTab->zName); goto exit_drop_table; } @@ -115770,11 +115770,11 @@ SQLITE_PRIVATE void tdsqlite3DropTable(Parse *pParse, SrcList *pName, int isView ** on a table. */ if( isView && pTab->pSelect==0 ){ - tdsqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); + sqlite3ErrorMsg(pParse, "use DROP TABLE to delete table %s", pTab->zName); goto exit_drop_table; } if( !isView && pTab->pSelect ){ - tdsqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); + sqlite3ErrorMsg(pParse, "use DROP VIEW to delete view %s", pTab->zName); goto exit_drop_table; } #endif @@ -115782,18 +115782,18 @@ SQLITE_PRIVATE void tdsqlite3DropTable(Parse *pParse, SrcList *pName, int isView /* Generate code to remove the table from the master table ** on disk. */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v ){ - tdsqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3BeginWriteOperation(pParse, 1, iDb); if( !isView ){ - tdsqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); - tdsqlite3FkDropTable(pParse, pName, pTab); + sqlite3ClearStatTables(pParse, iDb, "tbl", pTab->zName); + sqlite3FkDropTable(pParse, pName, pTab); } - tdsqlite3CodeDropTable(pParse, pTab, iDb, isView); + sqlite3CodeDropTable(pParse, pTab, iDb, isView); } exit_drop_table: - tdsqlite3SrcListDelete(db, pName); + sqlite3SrcListDelete(db, pName); } /* @@ -115810,16 +115810,16 @@ exit_drop_table: ** under construction in the pParse->pNewTable field. ** ** The foreign key is set for IMMEDIATE processing. A subsequent call -** to tdsqlite3DeferForeignKey() might change this to DEFERRED. +** to sqlite3DeferForeignKey() might change this to DEFERRED. */ -SQLITE_PRIVATE void tdsqlite3CreateForeignKey( +SQLITE_PRIVATE void sqlite3CreateForeignKey( Parse *pParse, /* Parsing context */ ExprList *pFromCol, /* Columns in this table that point to other table */ Token *pTo, /* Name of the other table */ ExprList *pToCol, /* Columns in the other table */ int flags /* Conflict resolution algorithms. */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; #ifndef SQLITE_OMIT_FOREIGN_KEY FKey *pFKey = 0; FKey *pNextTo; @@ -115835,14 +115835,14 @@ SQLITE_PRIVATE void tdsqlite3CreateForeignKey( int iCol = p->nCol-1; if( NEVER(iCol<0) ) goto fk_end; if( pToCol && pToCol->nExpr!=1 ){ - tdsqlite3ErrorMsg(pParse, "foreign key on %s" + sqlite3ErrorMsg(pParse, "foreign key on %s" " should reference only one column of table %T", p->aCol[iCol].zName, pTo); goto fk_end; } nCol = 1; }else if( pToCol && pToCol->nExpr!=pFromCol->nExpr ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "number of columns in foreign key does not match the number of " "columns in the referenced table"); goto fk_end; @@ -115852,10 +115852,10 @@ SQLITE_PRIVATE void tdsqlite3CreateForeignKey( nByte = sizeof(*pFKey) + (nCol-1)*sizeof(pFKey->aCol[0]) + pTo->n + 1; if( pToCol ){ for(i=0; inExpr; i++){ - nByte += tdsqlite3Strlen30(pToCol->a[i].zEName) + 1; + nByte += sqlite3Strlen30(pToCol->a[i].zEName) + 1; } } - pFKey = tdsqlite3DbMallocZero(db, nByte ); + pFKey = sqlite3DbMallocZero(db, nByte ); if( pFKey==0 ){ goto fk_end; } @@ -115864,11 +115864,11 @@ SQLITE_PRIVATE void tdsqlite3CreateForeignKey( z = (char*)&pFKey->aCol[nCol]; pFKey->zTo = z; if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenMap(pParse, (void*)z, pTo); + sqlite3RenameTokenMap(pParse, (void*)z, pTo); } memcpy(z, pTo->z, pTo->n); z[pTo->n] = 0; - tdsqlite3Dequote(z); + sqlite3Dequote(z); z += pTo->n+1; pFKey->nCol = nCol; if( pFromCol==0 ){ @@ -115877,28 +115877,28 @@ SQLITE_PRIVATE void tdsqlite3CreateForeignKey( for(i=0; inCol; j++){ - if( tdsqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zEName)==0 ){ + if( sqlite3StrICmp(p->aCol[j].zName, pFromCol->a[i].zEName)==0 ){ pFKey->aCol[i].iFrom = j; break; } } if( j>=p->nCol ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "unknown column \"%s\" in foreign key definition", pFromCol->a[i].zEName); goto fk_end; } if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zEName); + sqlite3RenameTokenRemap(pParse, &pFKey->aCol[i], pFromCol->a[i].zEName); } } } if( pToCol ){ for(i=0; ia[i].zEName); + int n = sqlite3Strlen30(pToCol->a[i].zEName); pFKey->aCol[i].zCol = z; if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zEName); + sqlite3RenameTokenRemap(pParse, z, pToCol->a[i].zEName); } memcpy(z, pToCol->a[i].zEName, n); z[n] = 0; @@ -115909,12 +115909,12 @@ SQLITE_PRIVATE void tdsqlite3CreateForeignKey( pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ - assert( tdsqlite3SchemaMutexHeld(db, 0, p->pSchema) ); - pNextTo = (FKey *)tdsqlite3HashInsert(&p->pSchema->fkeyHash, + assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, pFKey->zTo, (void *)pFKey ); if( pNextTo==pFKey ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); goto fk_end; } if( pNextTo ){ @@ -115929,10 +115929,10 @@ SQLITE_PRIVATE void tdsqlite3CreateForeignKey( pFKey = 0; fk_end: - tdsqlite3DbFree(db, pFKey); + sqlite3DbFree(db, pFKey); #endif /* !defined(SQLITE_OMIT_FOREIGN_KEY) */ - tdsqlite3ExprListDelete(db, pFromCol); - tdsqlite3ExprListDelete(db, pToCol); + sqlite3ExprListDelete(db, pFromCol); + sqlite3ExprListDelete(db, pToCol); } /* @@ -115942,7 +115942,7 @@ fk_end: ** The behavior of the most recently created foreign key is adjusted ** accordingly. */ -SQLITE_PRIVATE void tdsqlite3DeferForeignKey(Parse *pParse, int isDeferred){ +SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ #ifndef SQLITE_OMIT_FOREIGN_KEY Table *pTab; FKey *pFKey; @@ -115963,7 +115963,7 @@ SQLITE_PRIVATE void tdsqlite3DeferForeignKey(Parse *pParse, int isDeferred){ ** the index already exists and must be cleared before being refilled and ** the root page number of the index is taken from pIndex->tnum. */ -static void tdsqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ +static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ Table *pTab = pIndex->pTable; /* The table that is indexed */ int iTab = pParse->nTab++; /* Btree cursor used for pTab */ int iIdx = pParse->nTab++; /* Btree cursor used for pIndex */ @@ -115975,60 +115975,60 @@ static void tdsqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ Vdbe *v; /* Generate code into this virtual machine */ KeyInfo *pKey; /* KeyInfo for index */ int regRecord; /* Register holding assembled index record */ - tdsqlite3 *db = pParse->db; /* The database connection */ - int iDb = tdsqlite3SchemaToIndex(db, pIndex->pSchema); + sqlite3 *db = pParse->db; /* The database connection */ + int iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION - if( tdsqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, + if( sqlite3AuthCheck(pParse, SQLITE_REINDEX, pIndex->zName, 0, db->aDb[iDb].zDbSName ) ){ return; } #endif /* Require a write-lock on the table to perform this operation */ - tdsqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v==0 ) return; if( memRootPage>=0 ){ tnum = memRootPage; }else{ tnum = pIndex->tnum; } - pKey = tdsqlite3KeyInfoOfIndex(pParse, pIndex); + pKey = sqlite3KeyInfoOfIndex(pParse, pIndex); assert( pKey!=0 || db->mallocFailed || pParse->nErr ); /* Open the sorter cursor if we are to use one. */ iSorter = pParse->nTab++; - tdsqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*) - tdsqlite3KeyInfoRef(pKey), P4_KEYINFO); + sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, pIndex->nKeyCol, (char*) + sqlite3KeyInfoRef(pKey), P4_KEYINFO); /* Open the table. Loop through all rows of the table, inserting index ** records into the sorter. */ - tdsqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); - addr1 = tdsqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); - regRecord = tdsqlite3GetTempReg(pParse); - tdsqlite3MultiWrite(pParse); - - tdsqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); - tdsqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); - tdsqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); - tdsqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addr1); - if( memRootPage<0 ) tdsqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); - tdsqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, + sqlite3OpenTable(pParse, iTab, iDb, pTab, OP_OpenRead); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0); VdbeCoverage(v); + regRecord = sqlite3GetTempReg(pParse); + sqlite3MultiWrite(pParse); + + sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0); + sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); + sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, (char *)pKey, P4_KEYINFO); - tdsqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); - addr1 = tdsqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); + addr1 = sqlite3VdbeAddOp2(v, OP_SorterSort, iSorter, 0); VdbeCoverage(v); if( IsUniqueIndex(pIndex) ){ - int j2 = tdsqlite3VdbeGoto(v, 1); - addr2 = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeVerifyAbortable(v, OE_Abort); - tdsqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, + int j2 = sqlite3VdbeGoto(v, 1); + addr2 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeVerifyAbortable(v, OE_Abort); + sqlite3VdbeAddOp4Int(v, OP_SorterCompare, iSorter, j2, regRecord, pIndex->nKeyCol); VdbeCoverage(v); - tdsqlite3UniqueConstraint(pParse, OE_Abort, pIndex); - tdsqlite3VdbeJumpHere(v, j2); + sqlite3UniqueConstraint(pParse, OE_Abort, pIndex); + sqlite3VdbeJumpHere(v, j2); }else{ /* Most CREATE INDEX and REINDEX statements that are not UNIQUE can not ** abort. The exception is if one of the indexed expressions contains a @@ -116036,11 +116036,11 @@ static void tdsqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ ** overhead of adding a statement journal to a CREATE INDEX statement is ** very small (since most of the pages written do not contain content that ** needs to be restored if the statement aborts), so we call - ** tdsqlite3MayAbort() for all CREATE INDEX statements. */ - tdsqlite3MayAbort(pParse); - addr2 = tdsqlite3VdbeCurrentAddr(v); + ** sqlite3MayAbort() for all CREATE INDEX statements. */ + sqlite3MayAbort(pParse); + addr2 = sqlite3VdbeCurrentAddr(v); } - tdsqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); + sqlite3VdbeAddOp3(v, OP_SorterData, iSorter, regRecord, iIdx); if( !pIndex->bAscKeyBug ){ /* This OP_SeekEnd opcode makes index insert for a REINDEX go much ** faster by avoiding unnecessary seeks. But the optimization does @@ -116049,17 +116049,17 @@ static void tdsqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ ** a different order from the main table. ** See ticket: https://www.sqlite.org/src/info/bba7b69f9849b5bf */ - tdsqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); + sqlite3VdbeAddOp1(v, OP_SeekEnd, iIdx); } - tdsqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); - tdsqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - tdsqlite3ReleaseTempReg(pParse, regRecord); - tdsqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterNext, iSorter, addr2); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); - tdsqlite3VdbeAddOp1(v, OP_Close, iTab); - tdsqlite3VdbeAddOp1(v, OP_Close, iIdx); - tdsqlite3VdbeAddOp1(v, OP_Close, iSorter); + sqlite3VdbeAddOp1(v, OP_Close, iTab); + sqlite3VdbeAddOp1(v, OP_Close, iIdx); + sqlite3VdbeAddOp1(v, OP_Close, iSorter); } /* @@ -116069,8 +116069,8 @@ static void tdsqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ ** of 8-byte aligned space after the Index object and return a ** pointer to this extra space in *ppExtra. */ -SQLITE_PRIVATE Index *tdsqlite3AllocateIndexObject( - tdsqlite3 *db, /* Database connection */ +SQLITE_PRIVATE Index *sqlite3AllocateIndexObject( + sqlite3 *db, /* Database connection */ i16 nCol, /* Total number of columns in the index */ int nExtra, /* Number of bytes of extra space to alloc */ char **ppExtra /* Pointer to the "extra" space */ @@ -116083,7 +116083,7 @@ SQLITE_PRIVATE Index *tdsqlite3AllocateIndexObject( ROUND8(sizeof(LogEst)*(nCol+1) + /* Index.aiRowLogEst */ sizeof(i16)*nCol + /* Index.aiColumn */ sizeof(u8)*nCol); /* Index.aSortOrder */ - p = tdsqlite3DbMallocZero(db, nByte + nExtra); + p = sqlite3DbMallocZero(db, nByte + nExtra); if( p ){ char *pExtra = ((char*)p)+ROUND8(sizeof(Index)); p->azColl = (const char**)pExtra; pExtra += ROUND8(sizeof(char*)*nCol); @@ -116102,13 +116102,13 @@ SQLITE_PRIVATE Index *tdsqlite3AllocateIndexObject( ** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in ** pParse and return non-zero. Otherwise, return zero. */ -SQLITE_PRIVATE int tdsqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ +SQLITE_PRIVATE int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ if( pList ){ int i; for(i=0; inExpr; i++){ if( pList->a[i].bNulls ){ u8 sf = pList->a[i].sortFlags; - tdsqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", + sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", (sf==0 || sf==3) ? "FIRST" : "LAST" ); return 1; @@ -116130,7 +116130,7 @@ SQLITE_PRIVATE int tdsqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ ** is a primary key or unique-constraint on the most recent column added ** to the table currently under construction. */ -SQLITE_PRIVATE void tdsqlite3CreateIndex( +SQLITE_PRIVATE void sqlite3CreateIndex( Parse *pParse, /* All information about this parse */ Token *pName1, /* First part of index name. May be NULL */ Token *pName2, /* Second part of index name. May be NULL */ @@ -116150,7 +116150,7 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( int i, j; DbFixer sFix; /* For assigning database names to pTable */ int sortOrderMask; /* 1 to honor DESC in index. 0 to ignore. */ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Db *pDb; /* The specific table containing the indexed database */ int iDb; /* Index of the database that is being written */ Token *pName = 0; /* Unqualified name of the index to create */ @@ -116166,10 +116166,10 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( if( IN_DECLARE_VTAB && idxType!=SQLITE_IDXTYPE_PRIMARYKEY ){ goto exit_create_index; } - if( SQLITE_OK!=tdsqlite3ReadSchema(pParse) ){ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_create_index; } - if( tdsqlite3HasExplicitNulls(pParse, pList) ){ + if( sqlite3HasExplicitNulls(pParse, pList) ){ goto exit_create_index; } @@ -116183,7 +116183,7 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( ** before looking up the table. */ assert( pName1 && pName2 ); - iDb = tdsqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ) goto exit_create_index; assert( pName && pName->z ); @@ -116193,62 +116193,62 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( ** if initialising a database schema. */ if( !db->init.busy ){ - pTab = tdsqlite3SrcListLookup(pParse, pTblName); + pTab = sqlite3SrcListLookup(pParse, pTblName); if( pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ iDb = 1; } } #endif - tdsqlite3FixInit(&sFix, pParse, iDb, "index", pName); - if( tdsqlite3FixSrcList(&sFix, pTblName) ){ + sqlite3FixInit(&sFix, pParse, iDb, "index", pName); + if( sqlite3FixSrcList(&sFix, pTblName) ){ /* Because the parser constructs pTblName from a single identifier, - ** tdsqlite3FixSrcList can never fail. */ + ** sqlite3FixSrcList can never fail. */ assert(0); } - pTab = tdsqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); + pTab = sqlite3LocateTableItem(pParse, 0, &pTblName->a[0]); assert( db->mallocFailed==0 || pTab==0 ); if( pTab==0 ) goto exit_create_index; if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "cannot create a TEMP index on non-TEMP table \"%s\"", pTab->zName); goto exit_create_index; } - if( !HasRowid(pTab) ) pPk = tdsqlite3PrimaryKeyIndex(pTab); + if( !HasRowid(pTab) ) pPk = sqlite3PrimaryKeyIndex(pTab); }else{ assert( pName==0 ); assert( pStart==0 ); pTab = pParse->pNewTable; if( !pTab ) goto exit_create_index; - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); } pDb = &db->aDb[iDb]; assert( pTab!=0 ); assert( pParse->nErr==0 ); - if( tdsqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && db->init.busy==0 && pTblName!=0 #if SQLITE_USER_AUTHENTICATION - && tdsqlite3UserAuthTable(pTab->zName)==0 + && sqlite3UserAuthTable(pTab->zName)==0 #endif #ifdef SQLITE_ALLOW_SQLITE_MASTER_INDEX - && tdsqlite3StrICmp(&pTab->zName[7],"master")!=0 + && sqlite3StrICmp(&pTab->zName[7],"master")!=0 #endif ){ - tdsqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); + sqlite3ErrorMsg(pParse, "table %s may not be indexed", pTab->zName); goto exit_create_index; } #ifndef SQLITE_OMIT_VIEW if( pTab->pSelect ){ - tdsqlite3ErrorMsg(pParse, "views may not be indexed"); + sqlite3ErrorMsg(pParse, "views may not be indexed"); goto exit_create_index; } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ - tdsqlite3ErrorMsg(pParse, "virtual tables may not be indexed"); + sqlite3ErrorMsg(pParse, "virtual tables may not be indexed"); goto exit_create_index; } #endif @@ -116267,25 +116267,25 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( ** own name. */ if( pName ){ - zName = tdsqlite3NameFromToken(db, pName); + zName = sqlite3NameFromToken(db, pName); if( zName==0 ) goto exit_create_index; assert( pName->z!=0 ); - if( SQLITE_OK!=tdsqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){ + if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName,"index",pTab->zName) ){ goto exit_create_index; } if( !IN_RENAME_OBJECT ){ if( !db->init.busy ){ - if( tdsqlite3FindTable(db, zName, 0)!=0 ){ - tdsqlite3ErrorMsg(pParse, "there is already a table named %s", zName); + if( sqlite3FindTable(db, zName, 0)!=0 ){ + sqlite3ErrorMsg(pParse, "there is already a table named %s", zName); goto exit_create_index; } } - if( tdsqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ + if( sqlite3FindIndex(db, zName, pDb->zDbSName)!=0 ){ if( !ifNotExist ){ - tdsqlite3ErrorMsg(pParse, "index %s already exists", zName); + sqlite3ErrorMsg(pParse, "index %s already exists", zName); }else{ assert( !db->init.busy ); - tdsqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iDb); } goto exit_create_index; } @@ -116294,15 +116294,15 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( int n; Index *pLoop; for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){} - zName = tdsqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n); + zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n); if( zName==0 ){ goto exit_create_index; } - /* Automatic index names generated from within tdsqlite3_declare_vtab() + /* Automatic index names generated from within sqlite3_declare_vtab() ** must have names that are distinct from normal automatic index names. - ** The following statement converts "tdsqlite3_autoindex..." into - ** "tdsqlite3_butoindex..." in order to make the names distinct. + ** The following statement converts "sqlite3_autoindex..." into + ** "sqlite3_butoindex..." in order to make the names distinct. ** The "vtab_err.test" test demonstrates the need of this statement. */ if( IN_SPECIAL_PARSE ) zName[7]++; } @@ -116312,12 +116312,12 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( #ifndef SQLITE_OMIT_AUTHORIZATION if( !IN_RENAME_OBJECT ){ const char *zDb = pDb->zDbSName; - if( tdsqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iDb), 0, zDb) ){ goto exit_create_index; } i = SQLITE_CREATE_INDEX; if( !OMIT_TEMPDB && iDb==1 ) i = SQLITE_CREATE_TEMP_INDEX; - if( tdsqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){ + if( sqlite3AuthCheck(pParse, i, zName, pTab->zName, zDb) ){ goto exit_create_index; } } @@ -116331,14 +116331,14 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( Token prevCol; Column *pCol = &pTab->aCol[pTab->nCol-1]; pCol->colFlags |= COLFLAG_UNIQUE; - tdsqlite3TokenInit(&prevCol, pCol->zName); - pList = tdsqlite3ExprListAppend(pParse, 0, - tdsqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); + sqlite3TokenInit(&prevCol, pCol->zName); + pList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; assert( pList->nExpr==1 ); - tdsqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED); + sqlite3ExprListSetSortOrder(pList, sortOrder, SQLITE_SO_UNDEFINED); }else{ - tdsqlite3ExprListCheckLength(pParse, pList, "index"); + sqlite3ExprListCheckLength(pParse, pList, "index"); if( pParse->nErr ) goto exit_create_index; } @@ -116349,17 +116349,17 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( Expr *pExpr = pList->a[i].pExpr; assert( pExpr!=0 ); if( pExpr->op==TK_COLLATE ){ - nExtra += (1 + tdsqlite3Strlen30(pExpr->u.zToken)); + nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); } } /* ** Allocate the index structure. */ - nName = tdsqlite3Strlen30(zName); + nName = sqlite3Strlen30(zName); nExtraCol = pPk ? pPk->nKeyCol : 1; assert( pList->nExpr + nExtraCol <= 32767 /* Fits in i16 */ ); - pIndex = tdsqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, + pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol, nName + nExtra + 1, &zExtra); if( db->mallocFailed ){ goto exit_create_index; @@ -116376,11 +116376,11 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( pIndex->pSchema = db->aDb[iDb].pSchema; pIndex->nKeyCol = pList->nExpr; if( pPIWhere ){ - tdsqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0); + sqlite3ResolveSelfReference(pParse, pTab, NC_PartIdx, pPIWhere, 0); pIndex->pPartIdxWhere = pPIWhere; pPIWhere = 0; } - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); /* Check to see if we should honor DESC requests on index columns */ @@ -116409,13 +116409,13 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( int requestedSortOrder; /* ASC or DESC on the i-th expression */ const char *zColl; /* Collation sequence name */ - tdsqlite3StringToId(pListItem->pExpr); - tdsqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0); + sqlite3StringToId(pListItem->pExpr); + sqlite3ResolveSelfReference(pParse, pTab, NC_IdxExpr, pListItem->pExpr, 0); if( pParse->nErr ) goto exit_create_index; - pCExpr = tdsqlite3ExprSkipCollate(pListItem->pExpr); + pCExpr = sqlite3ExprSkipCollate(pListItem->pExpr); if( pCExpr->op!=TK_COLUMN ){ if( pTab==pParse->pNewTable ){ - tdsqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and " + sqlite3ErrorMsg(pParse, "expressions prohibited in PRIMARY KEY and " "UNIQUE constraints"); goto exit_create_index; } @@ -116445,7 +116445,7 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( if( pListItem->pExpr->op==TK_COLLATE ){ int nColl; zColl = pListItem->pExpr->u.zToken; - nColl = tdsqlite3Strlen30(zColl) + 1; + nColl = sqlite3Strlen30(zColl) + 1; assert( nExtra>=nColl ); memcpy(zExtra, zColl, nColl); zColl = zExtra; @@ -116454,8 +116454,8 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( }else if( j>=0 ){ zColl = pTab->aCol[j].zColl; } - if( !zColl ) zColl = tdsqlite3StrBINARY; - if( !db->init.busy && !tdsqlite3LocateCollSeq(pParse, zColl) ){ + if( !zColl ) zColl = sqlite3StrBINARY; + if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ goto exit_create_index; } pIndex->azColl[i] = zColl; @@ -116484,21 +116484,21 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( assert( i==pIndex->nColumn ); }else{ pIndex->aiColumn[i] = XN_ROWID; - pIndex->azColl[i] = tdsqlite3StrBINARY; + pIndex->azColl[i] = sqlite3StrBINARY; } - tdsqlite3DefaultRowEst(pIndex); + sqlite3DefaultRowEst(pIndex); if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex); /* If this index contains every column of its table, then mark ** it as a covering index */ assert( HasRowid(pTab) - || pTab->iPKey<0 || tdsqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 ); + || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 ); recomputeColumnsNotIndexed(pIndex); if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ pIndex->isCovering = 1; for(j=0; jnCol; j++){ if( j==pTab->iPKey ) continue; - if( tdsqlite3TableColumnToIndex(pIndex,j)>=0 ) continue; + if( sqlite3TableColumnToIndex(pIndex,j)>=0 ) continue; pIndex->isCovering = 0; break; } @@ -116541,7 +116541,7 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( if( pIdx->aiColumn[k]!=pIndex->aiColumn[k] ) break; z1 = pIdx->azColl[k]; z2 = pIndex->azColl[k]; - if( tdsqlite3StrICmp(z1, z2) ) break; + if( sqlite3StrICmp(z1, z2) ) break; } if( k==pIdx->nKeyCol ){ if( pIdx->onError!=pIndex->onError ){ @@ -116553,7 +116553,7 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( ** explicitly specified behavior for the index. */ if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "conflicting ON CONFLICT clauses specified", 0); } if( pIdx->onError==OE_Default ){ @@ -116580,20 +116580,20 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( if( db->init.busy ){ Index *p; assert( !IN_SPECIAL_PARSE ); - assert( tdsqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); + assert( sqlite3SchemaMutexHeld(db, 0, pIndex->pSchema) ); if( pTblName!=0 ){ pIndex->tnum = db->init.newTnum; - if( tdsqlite3IndexHasDuplicateRootPage(pIndex) ){ - tdsqlite3ErrorMsg(pParse, "invalid rootpage"); + if( sqlite3IndexHasDuplicateRootPage(pIndex) ){ + sqlite3ErrorMsg(pParse, "invalid rootpage"); pParse->rc = SQLITE_CORRUPT_BKPT; goto exit_create_index; } } - p = tdsqlite3HashInsert(&pIndex->pSchema->idxHash, + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ - tdsqlite3OomFault(db); + sqlite3OomFault(db); goto exit_create_index; } db->mDbFlags |= DBFLAG_SchemaChange; @@ -116617,10 +116617,10 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( char *zStmt; int iMem = ++pParse->nMem; - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v==0 ) goto exit_create_index; - tdsqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3BeginWriteOperation(pParse, 1, iDb); /* Create the rootpage for the index using CreateIndex. But before ** doing so, code a Noop instruction and store its address in @@ -116628,8 +116628,8 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In ** that case the convertToWithoutRowidTable() routine will replace ** the Noop with a Goto to jump over the VDBE code generated below. */ - pIndex->tnum = tdsqlite3VdbeAddOp0(v, OP_Noop); - tdsqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); + pIndex->tnum = sqlite3VdbeAddOp0(v, OP_Noop); + sqlite3VdbeAddOp3(v, OP_CreateBtree, iDb, iMem, BTREE_BLOBKEY); /* Gather the complete text of the CREATE INDEX statement into ** the zStmt variable @@ -116639,17 +116639,17 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( int n = (int)(pParse->sLastToken.z - pName->z) + pParse->sLastToken.n; if( pName->z[n-1]==';' ) n--; /* A named index with an explicit CREATE INDEX statement */ - zStmt = tdsqlite3MPrintf(db, "CREATE%s INDEX %.*s", + zStmt = sqlite3MPrintf(db, "CREATE%s INDEX %.*s", onError==OE_None ? "" : " UNIQUE", n, pName->z); }else{ /* An automatic index created by a PRIMARY KEY or UNIQUE constraint */ - /* zStmt = tdsqlite3MPrintf(""); */ + /* zStmt = sqlite3MPrintf(""); */ zStmt = 0; } /* Add an entry in sqlite_master for this index */ - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('index',%Q,%Q,#%d,%Q);", db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName, @@ -116657,20 +116657,20 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( iMem, zStmt ); - tdsqlite3DbFree(db, zStmt); + sqlite3DbFree(db, zStmt); /* Fill the index with data and reparse the schema. Code an OP_Expire ** to invalidate all pre-compiled statements. */ if( pTblName ){ - tdsqlite3RefillIndex(pParse, pIndex, iMem); - tdsqlite3ChangeCookie(pParse, iDb); - tdsqlite3VdbeAddParseSchemaOp(v, iDb, - tdsqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); - tdsqlite3VdbeAddOp2(v, OP_Expire, 0, 1); + sqlite3RefillIndex(pParse, pIndex, iMem); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "name='%q' AND type='index'", pIndex->zName)); + sqlite3VdbeAddOp2(v, OP_Expire, 0, 1); } - tdsqlite3VdbeJumpHere(v, pIndex->tnum); + sqlite3VdbeJumpHere(v, pIndex->tnum); } } if( db->init.busy || pTblName==0 ){ @@ -116686,7 +116686,7 @@ SQLITE_PRIVATE void tdsqlite3CreateIndex( /* Clean up before exiting */ exit_create_index: - if( pIndex ) tdsqlite3FreeIndex(db, pIndex); + if( pIndex ) sqlite3FreeIndex(db, pIndex); if( pTab ){ /* Ensure all REPLACE indexes are at the end of the list */ Index **ppFrom = &pTab->pIndex; Index *pThis; @@ -116702,10 +116702,10 @@ exit_create_index: break; } } - tdsqlite3ExprDelete(db, pPIWhere); - tdsqlite3ExprListDelete(db, pList); - tdsqlite3SrcListDelete(db, pTblName); - tdsqlite3DbFree(db, zName); + sqlite3ExprDelete(db, pPIWhere); + sqlite3ExprListDelete(db, pList); + sqlite3SrcListDelete(db, pTblName); + sqlite3DbFree(db, zName); } /* @@ -116726,7 +116726,7 @@ exit_create_index: ** how aiRowEst[] should be initialized. The numbers generated here ** are based on typical values found in actual indices. */ -SQLITE_PRIVATE void tdsqlite3DefaultRowEst(Index *pIdx){ +SQLITE_PRIVATE void sqlite3DefaultRowEst(Index *pIdx){ /* 10, 9, 8, 7, 6 */ LogEst aVal[] = { 33, 32, 30, 28, 26 }; LogEst *a = pIdx->aiRowLogEst; @@ -116740,17 +116740,17 @@ SQLITE_PRIVATE void tdsqlite3DefaultRowEst(Index *pIdx){ ** number of rows in the table, or half the number of rows in the table ** for a partial index. But do not let the estimate drop below 10. */ a[0] = pIdx->pTable->nRowLogEst; - if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10; assert( 10==tdsqlite3LogEst(2) ); - if( a[0]<33 ) a[0] = 33; assert( 33==tdsqlite3LogEst(10) ); + if( pIdx->pPartIdxWhere!=0 ) a[0] -= 10; assert( 10==sqlite3LogEst(2) ); + if( a[0]<33 ) a[0] = 33; assert( 33==sqlite3LogEst(10) ); /* Estimate that a[1] is 10, a[2] is 9, a[3] is 8, a[4] is 7, a[5] is ** 6 and each subsequent value (if any) is 5. */ memcpy(&a[1], aVal, nCopy*sizeof(LogEst)); for(i=nCopy+1; i<=pIdx->nKeyCol; i++){ - a[i] = 23; assert( 23==tdsqlite3LogEst(5) ); + a[i] = 23; assert( 23==sqlite3LogEst(5) ); } - assert( 0==tdsqlite3LogEst(1) ); + assert( 0==sqlite3LogEst(1) ); if( IsUniqueIndex(pIdx) ) a[pIdx->nKeyCol] = 0; } @@ -116758,10 +116758,10 @@ SQLITE_PRIVATE void tdsqlite3DefaultRowEst(Index *pIdx){ ** This routine will drop an existing named index. This routine ** implements the DROP INDEX statement. */ -SQLITE_PRIVATE void tdsqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ +SQLITE_PRIVATE void sqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExists){ Index *pIndex; Vdbe *v; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int iDb; assert( pParse->nErr==0 ); /* Never called with prior errors */ @@ -116769,62 +116769,62 @@ SQLITE_PRIVATE void tdsqlite3DropIndex(Parse *pParse, SrcList *pName, int ifExis goto exit_drop_index; } assert( pName->nSrc==1 ); - if( SQLITE_OK!=tdsqlite3ReadSchema(pParse) ){ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_drop_index; } - pIndex = tdsqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); + pIndex = sqlite3FindIndex(db, pName->a[0].zName, pName->a[0].zDatabase); if( pIndex==0 ){ if( !ifExists ){ - tdsqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); + sqlite3ErrorMsg(pParse, "no such index: %S", pName, 0); }else{ - tdsqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); + sqlite3CodeVerifyNamedSchema(pParse, pName->a[0].zDatabase); } pParse->checkSchema = 1; goto exit_drop_index; } if( pIndex->idxType!=SQLITE_IDXTYPE_APPDEF ){ - tdsqlite3ErrorMsg(pParse, "index associated with UNIQUE " + sqlite3ErrorMsg(pParse, "index associated with UNIQUE " "or PRIMARY KEY constraint cannot be dropped", 0); goto exit_drop_index; } - iDb = tdsqlite3SchemaToIndex(db, pIndex->pSchema); + iDb = sqlite3SchemaToIndex(db, pIndex->pSchema); #ifndef SQLITE_OMIT_AUTHORIZATION { int code = SQLITE_DROP_INDEX; Table *pTab = pIndex->pTable; const char *zDb = db->aDb[iDb].zDbSName; const char *zTab = SCHEMA_TABLE(iDb); - if( tdsqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ + if( sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ goto exit_drop_index; } if( !OMIT_TEMPDB && iDb ) code = SQLITE_DROP_TEMP_INDEX; - if( tdsqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){ + if( sqlite3AuthCheck(pParse, code, pIndex->zName, pTab->zName, zDb) ){ goto exit_drop_index; } } #endif /* Generate code to remove the index and from the master table */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v ){ - tdsqlite3BeginWriteOperation(pParse, 1, iDb); - tdsqlite3NestedParse(pParse, + sqlite3BeginWriteOperation(pParse, 1, iDb); + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='index'", db->aDb[iDb].zDbSName, MASTER_NAME, pIndex->zName ); - tdsqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); - tdsqlite3ChangeCookie(pParse, iDb); + sqlite3ClearStatTables(pParse, iDb, "idx", pIndex->zName); + sqlite3ChangeCookie(pParse, iDb); destroyRootPage(pParse, pIndex->tnum, iDb); - tdsqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); + sqlite3VdbeAddOp4(v, OP_DropIndex, iDb, 0, 0, pIndex->zName, 0); } exit_drop_index: - tdsqlite3SrcListDelete(db, pName); + sqlite3SrcListDelete(db, pName); } /* ** pArray is a pointer to an array of objects. Each object in the -** array is szEntry bytes in size. This routine uses tdsqlite3DbRealloc() +** array is szEntry bytes in size. This routine uses sqlite3DbRealloc() ** to extend the array so that there is space for a new object at the end. ** ** When this function is called, *pnEntry contains the current size of @@ -116839,18 +116839,18 @@ exit_drop_index: ** Otherwise, if the realloc() fails, *pIdx is set to -1, *pnEntry remains ** unchanged and a copy of pArray returned. */ -SQLITE_PRIVATE void *tdsqlite3ArrayAllocate( - tdsqlite3 *db, /* Connection to notify of malloc failures */ +SQLITE_PRIVATE void *sqlite3ArrayAllocate( + sqlite3 *db, /* Connection to notify of malloc failures */ void *pArray, /* Array of objects. Might be reallocated */ int szEntry, /* Size of each object in the array */ int *pnEntry, /* Number of objects currently in use */ int *pIdx /* Write the index of a new slot here */ ){ char *z; - tdsqlite3_int64 n = *pIdx = *pnEntry; + sqlite3_int64 n = *pIdx = *pnEntry; if( (n & (n-1))==0 ){ - tdsqlite3_int64 sz = (n==0) ? 1 : 2*n; - void *pNew = tdsqlite3DbRealloc(db, pArray, sz*szEntry); + sqlite3_int64 sz = (n==0) ? 1 : 2*n; + void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry); if( pNew==0 ){ *pIdx = -1; return pArray; @@ -116869,14 +116869,14 @@ SQLITE_PRIVATE void *tdsqlite3ArrayAllocate( ** ** A new IdList is returned, or NULL if malloc() fails. */ -SQLITE_PRIVATE IdList *tdsqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE IdList *sqlite3IdListAppend(Parse *pParse, IdList *pList, Token *pToken){ + sqlite3 *db = pParse->db; int i; if( pList==0 ){ - pList = tdsqlite3DbMallocZero(db, sizeof(IdList) ); + pList = sqlite3DbMallocZero(db, sizeof(IdList) ); if( pList==0 ) return 0; } - pList->a = tdsqlite3ArrayAllocate( + pList->a = sqlite3ArrayAllocate( db, pList->a, sizeof(pList->a[0]), @@ -116884,12 +116884,12 @@ SQLITE_PRIVATE IdList *tdsqlite3IdListAppend(Parse *pParse, IdList *pList, Token &i ); if( i<0 ){ - tdsqlite3IdListDelete(db, pList); + sqlite3IdListDelete(db, pList); return 0; } - pList->a[i].zName = tdsqlite3NameFromToken(db, pToken); + pList->a[i].zName = sqlite3NameFromToken(db, pToken); if( IN_RENAME_OBJECT && pList->a[i].zName ){ - tdsqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); + sqlite3RenameTokenMap(pParse, (void*)pList->a[i].zName, pToken); } return pList; } @@ -116897,25 +116897,25 @@ SQLITE_PRIVATE IdList *tdsqlite3IdListAppend(Parse *pParse, IdList *pList, Token /* ** Delete an IdList. */ -SQLITE_PRIVATE void tdsqlite3IdListDelete(tdsqlite3 *db, IdList *pList){ +SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3 *db, IdList *pList){ int i; if( pList==0 ) return; for(i=0; inId; i++){ - tdsqlite3DbFree(db, pList->a[i].zName); + sqlite3DbFree(db, pList->a[i].zName); } - tdsqlite3DbFree(db, pList->a); - tdsqlite3DbFreeNN(db, pList); + sqlite3DbFree(db, pList->a); + sqlite3DbFreeNN(db, pList); } /* ** Return the index in pList of the identifier named zId. Return -1 ** if not found. */ -SQLITE_PRIVATE int tdsqlite3IdListIndex(IdList *pList, const char *zName){ +SQLITE_PRIVATE int sqlite3IdListIndex(IdList *pList, const char *zName){ int i; if( pList==0 ) return -1; for(i=0; inId; i++){ - if( tdsqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; + if( sqlite3StrICmp(pList->a[i].zName, zName)==0 ) return i; } return -1; } @@ -116940,7 +116940,7 @@ SQLITE_PRIVATE int tdsqlite3IdListIndex(IdList *pList, const char *zName){ ** For example, suppose a SrcList initially contains two entries: A,B. ** To append 3 new entries onto the end, do this: ** -** tdsqlite3SrcListEnlarge(db, pSrclist, 3, 2); +** sqlite3SrcListEnlarge(db, pSrclist, 3, 2); ** ** After the call above it would contain: A, B, nil, nil, nil. ** If the iStart argument had been 1 instead of 2, then the result @@ -116952,7 +116952,7 @@ SQLITE_PRIVATE int tdsqlite3IdListIndex(IdList *pList, const char *zName){ ** the original SrcList unchanged, return NULL, and leave an error message ** in pParse. */ -SQLITE_PRIVATE SrcList *tdsqlite3SrcListEnlarge( +SQLITE_PRIVATE SrcList *sqlite3SrcListEnlarge( Parse *pParse, /* Parsing context into which errors are reported */ SrcList *pSrc, /* The SrcList to be enlarged */ int nExtra, /* Number of new slots to add to pSrc->a[] */ @@ -116969,16 +116969,16 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListEnlarge( /* Allocate additional space if needed */ if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){ SrcList *pNew; - tdsqlite3_int64 nAlloc = 2*(tdsqlite3_int64)pSrc->nSrc+nExtra; - tdsqlite3 *db = pParse->db; + sqlite3_int64 nAlloc = 2*(sqlite3_int64)pSrc->nSrc+nExtra; + sqlite3 *db = pParse->db; if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){ - tdsqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d", + sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d", SQLITE_MAX_SRCLIST); return 0; } if( nAlloc>SQLITE_MAX_SRCLIST ) nAlloc = SQLITE_MAX_SRCLIST; - pNew = tdsqlite3DbRealloc(db, pSrc, + pNew = sqlite3DbRealloc(db, pSrc, sizeof(*pSrc) + (nAlloc-1)*sizeof(pSrc->a[0]) ); if( pNew==0 ){ assert( db->mallocFailed ); @@ -117026,44 +117026,44 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListEnlarge( ** ** In other words, if call like this: ** -** tdsqlite3SrcListAppend(D,A,B,0); +** sqlite3SrcListAppend(D,A,B,0); ** ** Then B is a table name and the database name is unspecified. If called ** like this: ** -** tdsqlite3SrcListAppend(D,A,B,C); +** sqlite3SrcListAppend(D,A,B,C); ** ** Then C is the table name and B is the database name. If C is defined ** then so is B. In other words, we never have a case where: ** -** tdsqlite3SrcListAppend(D,A,0,C); +** sqlite3SrcListAppend(D,A,0,C); ** ** Both pTable and pDatabase are assumed to be quoted. They are dequoted ** before being added to the SrcList. */ -SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppend( +SQLITE_PRIVATE SrcList *sqlite3SrcListAppend( Parse *pParse, /* Parsing context, in which errors are reported */ SrcList *pList, /* Append to this SrcList. NULL creates a new SrcList */ Token *pTable, /* Table to append */ Token *pDatabase /* Database of the table */ ){ struct SrcList_item *pItem; - tdsqlite3 *db; + sqlite3 *db; assert( pDatabase==0 || pTable!=0 ); /* Cannot have C without B */ assert( pParse!=0 ); assert( pParse->db!=0 ); db = pParse->db; if( pList==0 ){ - pList = tdsqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) ); + pList = sqlite3DbMallocRawNN(pParse->db, sizeof(SrcList) ); if( pList==0 ) return 0; pList->nAlloc = 1; pList->nSrc = 1; memset(&pList->a[0], 0, sizeof(pList->a[0])); pList->a[0].iCursor = -1; }else{ - SrcList *pNew = tdsqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc); + SrcList *pNew = sqlite3SrcListEnlarge(pParse, pList, 1, pList->nSrc); if( pNew==0 ){ - tdsqlite3SrcListDelete(db, pList); + sqlite3SrcListDelete(db, pList); return 0; }else{ pList = pNew; @@ -117074,10 +117074,10 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppend( pDatabase = 0; } if( pDatabase ){ - pItem->zName = tdsqlite3NameFromToken(db, pDatabase); - pItem->zDatabase = tdsqlite3NameFromToken(db, pTable); + pItem->zName = sqlite3NameFromToken(db, pDatabase); + pItem->zDatabase = sqlite3NameFromToken(db, pTable); }else{ - pItem->zName = tdsqlite3NameFromToken(db, pTable); + pItem->zName = sqlite3NameFromToken(db, pTable); pItem->zDatabase = 0; } return pList; @@ -117086,7 +117086,7 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppend( /* ** Assign VdbeCursor index numbers to all tables in a SrcList */ -SQLITE_PRIVATE void tdsqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ +SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList){ int i; struct SrcList_item *pItem; assert(pList || pParse->db->mallocFailed ); @@ -117095,7 +117095,7 @@ SQLITE_PRIVATE void tdsqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList) if( pItem->iCursor>=0 ) break; pItem->iCursor = pParse->nTab++; if( pItem->pSelect ){ - tdsqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); + sqlite3SrcListAssignCursors(pParse, pItem->pSelect->pSrc); } } } @@ -117104,22 +117104,22 @@ SQLITE_PRIVATE void tdsqlite3SrcListAssignCursors(Parse *pParse, SrcList *pList) /* ** Delete an entire SrcList including all its substructure. */ -SQLITE_PRIVATE void tdsqlite3SrcListDelete(tdsqlite3 *db, SrcList *pList){ +SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3 *db, SrcList *pList){ int i; struct SrcList_item *pItem; if( pList==0 ) return; for(pItem=pList->a, i=0; inSrc; i++, pItem++){ - tdsqlite3DbFree(db, pItem->zDatabase); - tdsqlite3DbFree(db, pItem->zName); - tdsqlite3DbFree(db, pItem->zAlias); - if( pItem->fg.isIndexedBy ) tdsqlite3DbFree(db, pItem->u1.zIndexedBy); - if( pItem->fg.isTabFunc ) tdsqlite3ExprListDelete(db, pItem->u1.pFuncArg); - tdsqlite3DeleteTable(db, pItem->pTab); - tdsqlite3SelectDelete(db, pItem->pSelect); - tdsqlite3ExprDelete(db, pItem->pOn); - tdsqlite3IdListDelete(db, pItem->pUsing); + sqlite3DbFree(db, pItem->zDatabase); + sqlite3DbFree(db, pItem->zName); + sqlite3DbFree(db, pItem->zAlias); + if( pItem->fg.isIndexedBy ) sqlite3DbFree(db, pItem->u1.zIndexedBy); + if( pItem->fg.isTabFunc ) sqlite3ExprListDelete(db, pItem->u1.pFuncArg); + sqlite3DeleteTable(db, pItem->pTab); + sqlite3SelectDelete(db, pItem->pSelect); + sqlite3ExprDelete(db, pItem->pOn); + sqlite3IdListDelete(db, pItem->pUsing); } - tdsqlite3DbFreeNN(db, pList); + sqlite3DbFreeNN(db, pList); } /* @@ -117138,7 +117138,7 @@ SQLITE_PRIVATE void tdsqlite3SrcListDelete(tdsqlite3 *db, SrcList *pList){ ** Return a new SrcList which encodes is the FROM with the new ** term added. */ -SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppendFromTerm( +SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( Parse *pParse, /* Parsing context */ SrcList *p, /* The left part of the FROM clause already seen */ Token *pTable, /* Name of the table to add to the FROM clause */ @@ -117149,14 +117149,14 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppendFromTerm( IdList *pUsing /* The USING clause of a join */ ){ struct SrcList_item *pItem; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( !p && (pOn || pUsing) ){ - tdsqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", + sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", (pOn ? "ON" : "USING") ); goto append_from_error; } - p = tdsqlite3SrcListAppend(pParse, p, pTable, pDatabase); + p = sqlite3SrcListAppend(pParse, p, pTable, pDatabase); if( p==0 ){ goto append_from_error; } @@ -117166,11 +117166,11 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppendFromTerm( assert( pItem->zName==0 || pDatabase!=0 ); if( IN_RENAME_OBJECT && pItem->zName ){ Token *pToken = (ALWAYS(pDatabase) && pDatabase->z) ? pDatabase : pTable; - tdsqlite3RenameTokenMap(pParse, pItem->zName, pToken); + sqlite3RenameTokenMap(pParse, pItem->zName, pToken); } assert( pAlias!=0 ); if( pAlias->n ){ - pItem->zAlias = tdsqlite3NameFromToken(db, pAlias); + pItem->zAlias = sqlite3NameFromToken(db, pAlias); } pItem->pSelect = pSubquery; pItem->pOn = pOn; @@ -117179,9 +117179,9 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppendFromTerm( append_from_error: assert( p==0 ); - tdsqlite3ExprDelete(db, pOn); - tdsqlite3IdListDelete(db, pUsing); - tdsqlite3SelectDelete(db, pSubquery); + sqlite3ExprDelete(db, pOn); + sqlite3IdListDelete(db, pUsing); + sqlite3SelectDelete(db, pSubquery); return 0; } @@ -117189,7 +117189,7 @@ SQLITE_PRIVATE SrcList *tdsqlite3SrcListAppendFromTerm( ** Add an INDEXED BY or NOT INDEXED clause to the most recently added ** element of the source-list passed as the second argument. */ -SQLITE_PRIVATE void tdsqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ +SQLITE_PRIVATE void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ assert( pIndexedBy!=0 ); if( p && pIndexedBy->n>0 ){ struct SrcList_item *pItem; @@ -117203,7 +117203,7 @@ SQLITE_PRIVATE void tdsqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token * ** construct "indexed_opt" for details. */ pItem->fg.notIndexed = 1; }else{ - pItem->u1.zIndexedBy = tdsqlite3NameFromToken(pParse->db, pIndexedBy); + pItem->u1.zIndexedBy = sqlite3NameFromToken(pParse->db, pIndexedBy); pItem->fg.isIndexedBy = 1; } } @@ -117213,7 +117213,7 @@ SQLITE_PRIVATE void tdsqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token * ** Add the list of function arguments to the SrcList entry for a ** table-valued-function. */ -SQLITE_PRIVATE void tdsqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ +SQLITE_PRIVATE void sqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList *pList){ if( p ){ struct SrcList_item *pItem = &p->a[p->nSrc-1]; assert( pItem->fg.notIndexed==0 ); @@ -117222,7 +117222,7 @@ SQLITE_PRIVATE void tdsqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList pItem->u1.pFuncArg = pList; pItem->fg.isTabFunc = 1; }else{ - tdsqlite3ExprListDelete(pParse->db, pList); + sqlite3ExprListDelete(pParse->db, pList); } } @@ -117241,7 +117241,7 @@ SQLITE_PRIVATE void tdsqlite3SrcListFuncArgs(Parse *pParse, SrcList *p, ExprList ** in p->a[0] and p->a[1], respectively. The parser initially stores the ** operator with A. This routine shifts that operator over to B. */ -SQLITE_PRIVATE void tdsqlite3SrcListShiftJoinType(SrcList *p){ +SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList *p){ if( p ){ int i; for(i=p->nSrc-1; i>0; i--){ @@ -117254,26 +117254,26 @@ SQLITE_PRIVATE void tdsqlite3SrcListShiftJoinType(SrcList *p){ /* ** Generate VDBE code for a BEGIN statement. */ -SQLITE_PRIVATE void tdsqlite3BeginTransaction(Parse *pParse, int type){ - tdsqlite3 *db; +SQLITE_PRIVATE void sqlite3BeginTransaction(Parse *pParse, int type){ + sqlite3 *db; Vdbe *v; int i; assert( pParse!=0 ); db = pParse->db; assert( db!=0 ); - if( tdsqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){ return; } - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( !v ) return; if( type!=TK_DEFERRED ){ for(i=0; inDb; i++){ - tdsqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); - tdsqlite3VdbeUsesBtree(v, i); + sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1); + sqlite3VdbeUsesBtree(v, i); } } - tdsqlite3VdbeAddOp0(v, OP_AutoCommit); + sqlite3VdbeAddOp0(v, OP_AutoCommit); } /* @@ -117281,7 +117281,7 @@ SQLITE_PRIVATE void tdsqlite3BeginTransaction(Parse *pParse, int type){ ** Code for ROLLBACK is generated if eType==TK_ROLLBACK. Otherwise ** code is generated for a COMMIT. */ -SQLITE_PRIVATE void tdsqlite3EndTransaction(Parse *pParse, int eType){ +SQLITE_PRIVATE void sqlite3EndTransaction(Parse *pParse, int eType){ Vdbe *v; int isRollback; @@ -117289,13 +117289,13 @@ SQLITE_PRIVATE void tdsqlite3EndTransaction(Parse *pParse, int eType){ assert( pParse->db!=0 ); assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK ); isRollback = eType==TK_ROLLBACK; - if( tdsqlite3AuthCheck(pParse, SQLITE_TRANSACTION, + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){ return; } - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v ){ - tdsqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback); + sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, isRollback); } } @@ -117303,19 +117303,19 @@ SQLITE_PRIVATE void tdsqlite3EndTransaction(Parse *pParse, int eType){ ** This function is called by the parser when it parses a command to create, ** release or rollback an SQL savepoint. */ -SQLITE_PRIVATE void tdsqlite3Savepoint(Parse *pParse, int op, Token *pName){ - char *zName = tdsqlite3NameFromToken(pParse->db, pName); +SQLITE_PRIVATE void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ + char *zName = sqlite3NameFromToken(pParse->db, pName); if( zName ){ - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); #ifndef SQLITE_OMIT_AUTHORIZATION static const char * const az[] = { "BEGIN", "RELEASE", "ROLLBACK" }; assert( !SAVEPOINT_BEGIN && SAVEPOINT_RELEASE==1 && SAVEPOINT_ROLLBACK==2 ); #endif - if( !v || tdsqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){ - tdsqlite3DbFree(pParse->db, zName); + if( !v || sqlite3AuthCheck(pParse, SQLITE_SAVEPOINT, az[op], zName, 0) ){ + sqlite3DbFree(pParse->db, zName); return; } - tdsqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC); + sqlite3VdbeAddOp4(v, OP_Savepoint, op, 0, 0, zName, P4_DYNAMIC); } } @@ -117323,8 +117323,8 @@ SQLITE_PRIVATE void tdsqlite3Savepoint(Parse *pParse, int op, Token *pName){ ** Make sure the TEMP database is open and available for use. Return ** the number of errors. Leave any error messages in the pParse structure. */ -SQLITE_PRIVATE int tdsqlite3OpenTempDatabase(Parse *pParse){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ + sqlite3 *db = pParse->db; if( db->aDb[1].pBt==0 && !pParse->explain ){ int rc; Btree *pBt; @@ -117335,17 +117335,17 @@ SQLITE_PRIVATE int tdsqlite3OpenTempDatabase(Parse *pParse){ SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TEMP_DB; - rc = tdsqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pBt, 0, flags); if( rc!=SQLITE_OK ){ - tdsqlite3ErrorMsg(pParse, "unable to open a temporary database " + sqlite3ErrorMsg(pParse, "unable to open a temporary database " "file for storing temporary tables"); pParse->rc = rc; return 1; } db->aDb[1].pBt = pBt; assert( db->aDb[1].pSchema ); - if( SQLITE_NOMEM==tdsqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ - tdsqlite3OomFault(db); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ + sqlite3OomFault(db); return 1; } } @@ -117356,34 +117356,34 @@ SQLITE_PRIVATE int tdsqlite3OpenTempDatabase(Parse *pParse){ ** Record the fact that the schema cookie will need to be verified ** for database iDb. The code to actually verify the schema cookie ** will occur at the end of the top-level VDBE and will be generated -** later, by tdsqlite3FinishCoding(). +** later, by sqlite3FinishCoding(). */ -SQLITE_PRIVATE void tdsqlite3CodeVerifySchema(Parse *pParse, int iDb){ - Parse *pToplevel = tdsqlite3ParseToplevel(pParse); +SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); assert( iDb>=0 && iDbdb->nDb ); assert( pParse->db->aDb[iDb].pBt!=0 || iDb==1 ); assert( iDbdb, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(pParse->db, iDb, 0) ); if( DbMaskTest(pToplevel->cookieMask, iDb)==0 ){ DbMaskSet(pToplevel->cookieMask, iDb); if( !OMIT_TEMPDB && iDb==1 ){ - tdsqlite3OpenTempDatabase(pToplevel); + sqlite3OpenTempDatabase(pToplevel); } } } /* -** If argument zDb is NULL, then call tdsqlite3CodeVerifySchema() for each +** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each ** attached database. Otherwise, invoke it for the database named zDb only. */ -SQLITE_PRIVATE void tdsqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ + sqlite3 *db = pParse->db; int i; for(i=0; inDb; i++){ Db *pDb = &db->aDb[i]; - if( pDb->pBt && (!zDb || 0==tdsqlite3StrICmp(zDb, pDb->zDbSName)) ){ - tdsqlite3CodeVerifySchema(pParse, i); + if( pDb->pBt && (!zDb || 0==sqlite3StrICmp(zDb, pDb->zDbSName)) ){ + sqlite3CodeVerifySchema(pParse, i); } } } @@ -117401,9 +117401,9 @@ SQLITE_PRIVATE void tdsqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zD ** can be checked before any changes are made to the database, it is never ** necessary to undo a write and the checkpoint should not be set. */ -SQLITE_PRIVATE void tdsqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ - Parse *pToplevel = tdsqlite3ParseToplevel(pParse); - tdsqlite3CodeVerifySchema(pParse, iDb); +SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + sqlite3CodeVerifySchema(pParse, iDb); DbMaskSet(pToplevel->writeMask, iDb); pToplevel->isMultiWrite |= setStatement; } @@ -117415,8 +117415,8 @@ SQLITE_PRIVATE void tdsqlite3BeginWriteOperation(Parse *pParse, int setStatement ** If an abort occurs after some of these writes have completed, then it will ** be necessary to undo the completed writes. */ -SQLITE_PRIVATE void tdsqlite3MultiWrite(Parse *pParse){ - Parse *pToplevel = tdsqlite3ParseToplevel(pParse); +SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); pToplevel->isMultiWrite = 1; } @@ -117433,11 +117433,11 @@ SQLITE_PRIVATE void tdsqlite3MultiWrite(Parse *pParse){ ** go a little faster. But taking advantage of this time dependency ** makes it more difficult to prove that the code is correct (in ** particular, it prevents us from writing an effective -** implementation of tdsqlite3AssertMayAbort()) and so we have chosen +** implementation of sqlite3AssertMayAbort()) and so we have chosen ** to take the safe route and skip the optimization. */ -SQLITE_PRIVATE void tdsqlite3MayAbort(Parse *pParse){ - Parse *pToplevel = tdsqlite3ParseToplevel(pParse); +SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); pToplevel->mayAbort = 1; } @@ -117446,7 +117446,7 @@ SQLITE_PRIVATE void tdsqlite3MayAbort(Parse *pParse){ ** error. The onError parameter determines which (if any) of the statement ** and/or current transaction is rolled back. */ -SQLITE_PRIVATE void tdsqlite3HaltConstraint( +SQLITE_PRIVATE void sqlite3HaltConstraint( Parse *pParse, /* Parsing context */ int errCode, /* extended error code */ int onError, /* Constraint type */ @@ -117454,19 +117454,19 @@ SQLITE_PRIVATE void tdsqlite3HaltConstraint( i8 p4type, /* P4_STATIC or P4_TRANSIENT */ u8 p5Errmsg /* P5_ErrMsg type */ ){ - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); assert( (errCode&0xff)==SQLITE_CONSTRAINT ); if( onError==OE_Abort ){ - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); } - tdsqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type); - tdsqlite3VdbeChangeP5(v, p5Errmsg); + sqlite3VdbeAddOp4(v, OP_Halt, errCode, onError, 0, p4, p4type); + sqlite3VdbeChangeP5(v, p5Errmsg); } /* ** Code an OP_Halt due to UNIQUE or PRIMARY KEY constraint violation. */ -SQLITE_PRIVATE void tdsqlite3UniqueConstraint( +SQLITE_PRIVATE void sqlite3UniqueConstraint( Parse *pParse, /* Parsing context */ int onError, /* Constraint type */ Index *pIdx /* The index that triggers the constraint */ @@ -117476,23 +117476,23 @@ SQLITE_PRIVATE void tdsqlite3UniqueConstraint( StrAccum errMsg; Table *pTab = pIdx->pTable; - tdsqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, + sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, pParse->db->aLimit[SQLITE_LIMIT_LENGTH]); if( pIdx->aColExpr ){ - tdsqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName); + sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName); }else{ for(j=0; jnKeyCol; j++){ char *zCol; assert( pIdx->aiColumn[j]>=0 ); zCol = pTab->aCol[pIdx->aiColumn[j]].zName; - if( j ) tdsqlite3_str_append(&errMsg, ", ", 2); - tdsqlite3_str_appendall(&errMsg, pTab->zName); - tdsqlite3_str_append(&errMsg, ".", 1); - tdsqlite3_str_appendall(&errMsg, zCol); + if( j ) sqlite3_str_append(&errMsg, ", ", 2); + sqlite3_str_appendall(&errMsg, pTab->zName); + sqlite3_str_append(&errMsg, ".", 1); + sqlite3_str_appendall(&errMsg, zCol); } } - zErr = tdsqlite3StrAccumFinish(&errMsg); - tdsqlite3HaltConstraint(pParse, + zErr = sqlite3StrAccumFinish(&errMsg); + sqlite3HaltConstraint(pParse, IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY : SQLITE_CONSTRAINT_UNIQUE, onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); @@ -117502,7 +117502,7 @@ SQLITE_PRIVATE void tdsqlite3UniqueConstraint( /* ** Code an OP_Halt due to non-unique rowid. */ -SQLITE_PRIVATE void tdsqlite3RowidConstraint( +SQLITE_PRIVATE void sqlite3RowidConstraint( Parse *pParse, /* Parsing context */ int onError, /* Conflict resolution algorithm */ Table *pTab /* The table with the non-unique rowid */ @@ -117510,14 +117510,14 @@ SQLITE_PRIVATE void tdsqlite3RowidConstraint( char *zMsg; int rc; if( pTab->iPKey>=0 ){ - zMsg = tdsqlite3MPrintf(pParse->db, "%s.%s", pTab->zName, + zMsg = sqlite3MPrintf(pParse->db, "%s.%s", pTab->zName, pTab->aCol[pTab->iPKey].zName); rc = SQLITE_CONSTRAINT_PRIMARYKEY; }else{ - zMsg = tdsqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName); + zMsg = sqlite3MPrintf(pParse->db, "%s.rowid", pTab->zName); rc = SQLITE_CONSTRAINT_ROWID; } - tdsqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC, + sqlite3HaltConstraint(pParse, rc, onError, zMsg, P4_DYNAMIC, P5_ConstraintUnique); } @@ -117532,7 +117532,7 @@ static int collationMatch(const char *zColl, Index *pIndex){ for(i=0; inColumn; i++){ const char *z = pIndex->azColl[i]; assert( z!=0 || pIndex->aiColumn[i]<0 ); - if( pIndex->aiColumn[i]>=0 && 0==tdsqlite3StrICmp(z, zColl) ){ + if( pIndex->aiColumn[i]>=0 && 0==sqlite3StrICmp(z, zColl) ){ return 1; } } @@ -117551,9 +117551,9 @@ static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ for(pIndex=pTab->pIndex; pIndex; pIndex=pIndex->pNext){ if( zColl==0 || collationMatch(zColl, pIndex) ){ - int iDb = tdsqlite3SchemaToIndex(pParse->db, pTab->pSchema); - tdsqlite3BeginWriteOperation(pParse, 0, iDb); - tdsqlite3RefillIndex(pParse, pIndex, -1); + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); } } } @@ -117569,11 +117569,11 @@ static void reindexTable(Parse *pParse, Table *pTab, char const *zColl){ static void reindexDatabases(Parse *pParse, char const *zColl){ Db *pDb; /* A single database */ int iDb; /* The database index number */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ HashElem *k; /* For looping over tables in pDb */ Table *pTab; /* A table in the database */ - assert( tdsqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */ + assert( sqlite3BtreeHoldsAllMutexes(db) ); /* Needed for schema access */ for(iDb=0, pDb=db->aDb; iDbnDb; iDb++, pDb++){ assert( pDb!=0 ); for(k=sqliteHashFirst(&pDb->pSchema->tblHash); k; k=sqliteHashNext(k)){ @@ -117598,19 +117598,19 @@ static void reindexDatabases(Parse *pParse, char const *zColl){ ** indices associated with the named table. */ #ifndef SQLITE_OMIT_REINDEX -SQLITE_PRIVATE void tdsqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ +SQLITE_PRIVATE void sqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2){ CollSeq *pColl; /* Collating sequence to be reindexed, or NULL */ char *z; /* Name of a table or index */ const char *zDb; /* Name of the database */ Table *pTab; /* A table in the database */ Index *pIndex; /* An index associated with pTab */ int iDb; /* The database index number */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ Token *pObjName; /* Name of the table or index to be reindexed */ /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ - if( SQLITE_OK!=tdsqlite3ReadSchema(pParse) ){ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ return; } @@ -117620,61 +117620,61 @@ SQLITE_PRIVATE void tdsqlite3Reindex(Parse *pParse, Token *pName1, Token *pName2 }else if( NEVER(pName2==0) || pName2->z==0 ){ char *zColl; assert( pName1->z ); - zColl = tdsqlite3NameFromToken(pParse->db, pName1); + zColl = sqlite3NameFromToken(pParse->db, pName1); if( !zColl ) return; - pColl = tdsqlite3FindCollSeq(db, ENC(db), zColl, 0); + pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); if( pColl ){ reindexDatabases(pParse, zColl); - tdsqlite3DbFree(db, zColl); + sqlite3DbFree(db, zColl); return; } - tdsqlite3DbFree(db, zColl); + sqlite3DbFree(db, zColl); } - iDb = tdsqlite3TwoPartName(pParse, pName1, pName2, &pObjName); + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pObjName); if( iDb<0 ) return; - z = tdsqlite3NameFromToken(db, pObjName); + z = sqlite3NameFromToken(db, pObjName); if( z==0 ) return; zDb = db->aDb[iDb].zDbSName; - pTab = tdsqlite3FindTable(db, z, zDb); + pTab = sqlite3FindTable(db, z, zDb); if( pTab ){ reindexTable(pParse, pTab, 0); - tdsqlite3DbFree(db, z); + sqlite3DbFree(db, z); return; } - pIndex = tdsqlite3FindIndex(db, z, zDb); - tdsqlite3DbFree(db, z); + pIndex = sqlite3FindIndex(db, z, zDb); + sqlite3DbFree(db, z); if( pIndex ){ - tdsqlite3BeginWriteOperation(pParse, 0, iDb); - tdsqlite3RefillIndex(pParse, pIndex, -1); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3RefillIndex(pParse, pIndex, -1); return; } - tdsqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); + sqlite3ErrorMsg(pParse, "unable to identify the object to be reindexed"); } #endif /* ** Return a KeyInfo structure that is appropriate for the given Index. ** -** The caller should invoke tdsqlite3KeyInfoUnref() on the returned object +** The caller should invoke sqlite3KeyInfoUnref() on the returned object ** when it has finished using it. */ -SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ int i; int nCol = pIdx->nColumn; int nKey = pIdx->nKeyCol; KeyInfo *pKey; if( pParse->nErr ) return 0; if( pIdx->uniqNotNull ){ - pKey = tdsqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); + pKey = sqlite3KeyInfoAlloc(pParse->db, nKey, nCol-nKey); }else{ - pKey = tdsqlite3KeyInfoAlloc(pParse->db, nCol, 0); + pKey = sqlite3KeyInfoAlloc(pParse->db, nCol, 0); } if( pKey ){ - assert( tdsqlite3KeyInfoIsWriteable(pKey) ); + assert( sqlite3KeyInfoIsWriteable(pKey) ); for(i=0; iazColl[i]; - pKey->aColl[i] = zColl==tdsqlite3StrBINARY ? 0 : - tdsqlite3LocateCollSeq(pParse, zColl); + pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : + sqlite3LocateCollSeq(pParse, zColl); pKey->aSortFlags[i] = pIdx->aSortOrder[i]; assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) ); } @@ -117691,7 +117691,7 @@ SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ pIdx->bNoQuery = 1; pParse->rc = SQLITE_ERROR_RETRY; } - tdsqlite3KeyInfoUnref(pKey); + sqlite3KeyInfoUnref(pKey); pKey = 0; } } @@ -117703,41 +117703,41 @@ SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ ** This routine is invoked once per CTE by the parser while parsing a ** WITH clause. */ -SQLITE_PRIVATE With *tdsqlite3WithAdd( +SQLITE_PRIVATE With *sqlite3WithAdd( Parse *pParse, /* Parsing context */ With *pWith, /* Existing WITH clause, or NULL */ Token *pName, /* Name of the common-table */ ExprList *pArglist, /* Optional column name list for the table */ Select *pQuery /* Query used to initialize the table */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; With *pNew; char *zName; /* Check that the CTE name is unique within this WITH clause. If ** not, store an error in the Parse structure. */ - zName = tdsqlite3NameFromToken(pParse->db, pName); + zName = sqlite3NameFromToken(pParse->db, pName); if( zName && pWith ){ int i; for(i=0; inCte; i++){ - if( tdsqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ - tdsqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); + if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){ + sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName); } } } if( pWith ){ - tdsqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); - pNew = tdsqlite3DbRealloc(db, pWith, nByte); + sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte); + pNew = sqlite3DbRealloc(db, pWith, nByte); }else{ - pNew = tdsqlite3DbMallocZero(db, sizeof(*pWith)); + pNew = sqlite3DbMallocZero(db, sizeof(*pWith)); } assert( (pNew!=0 && zName!=0) || db->mallocFailed ); if( db->mallocFailed ){ - tdsqlite3ExprListDelete(db, pArglist); - tdsqlite3SelectDelete(db, pQuery); - tdsqlite3DbFree(db, zName); + sqlite3ExprListDelete(db, pArglist); + sqlite3SelectDelete(db, pQuery); + sqlite3DbFree(db, zName); pNew = pWith; }else{ pNew->a[pNew->nCte].pSelect = pQuery; @@ -117753,16 +117753,16 @@ SQLITE_PRIVATE With *tdsqlite3WithAdd( /* ** Free the contents of the With object passed as the second argument. */ -SQLITE_PRIVATE void tdsqlite3WithDelete(tdsqlite3 *db, With *pWith){ +SQLITE_PRIVATE void sqlite3WithDelete(sqlite3 *db, With *pWith){ if( pWith ){ int i; for(i=0; inCte; i++){ struct Cte *pCte = &pWith->a[i]; - tdsqlite3ExprListDelete(db, pCte->pCols); - tdsqlite3SelectDelete(db, pCte->pSelect); - tdsqlite3DbFree(db, pCte->zName); + sqlite3ExprListDelete(db, pCte->pCols); + sqlite3SelectDelete(db, pCte->pSelect); + sqlite3DbFree(db, pCte->zName); } - tdsqlite3DbFree(db, pWith); + sqlite3DbFree(db, pWith); } } #endif /* !defined(SQLITE_OMIT_CTE) */ @@ -117791,24 +117791,24 @@ SQLITE_PRIVATE void tdsqlite3WithDelete(tdsqlite3 *db, With *pWith){ ** Invoke the 'collation needed' callback to request a collation sequence ** in the encoding enc of name zName, length nName. */ -static void callCollNeeded(tdsqlite3 *db, int enc, const char *zName){ +static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); if( db->xCollNeeded ){ - char *zExternal = tdsqlite3DbStrDup(db, zName); + char *zExternal = sqlite3DbStrDup(db, zName); if( !zExternal ) return; db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal); - tdsqlite3DbFree(db, zExternal); + sqlite3DbFree(db, zExternal); } #ifndef SQLITE_OMIT_UTF16 if( db->xCollNeeded16 ){ char const *zExternal; - tdsqlite3_value *pTmp = tdsqlite3ValueNew(db); - tdsqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); - zExternal = tdsqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); + sqlite3_value *pTmp = sqlite3ValueNew(db); + sqlite3ValueSetStr(pTmp, -1, zName, SQLITE_UTF8, SQLITE_STATIC); + zExternal = sqlite3ValueText(pTmp, SQLITE_UTF16NATIVE); if( zExternal ){ db->xCollNeeded16(db->pCollNeededArg, db, (int)ENC(db), zExternal); } - tdsqlite3ValueFree(pTmp); + sqlite3ValueFree(pTmp); } #endif } @@ -117820,13 +117820,13 @@ static void callCollNeeded(tdsqlite3 *db, int enc, const char *zName){ ** of these instead if they exist. Avoid a UTF-8 <-> UTF-16 conversion if ** possible. */ -static int synthCollSeq(tdsqlite3 *db, CollSeq *pColl){ +static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ CollSeq *pColl2; char *z = pColl->zName; int i; static const u8 aEnc[] = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; for(i=0; i<3; i++){ - pColl2 = tdsqlite3FindCollSeq(db, aEnc[i], z, 0); + pColl2 = sqlite3FindCollSeq(db, aEnc[i], z, 0); if( pColl2->xCmp!=0 ){ memcpy(pColl, pColl2, sizeof(CollSeq)); pColl->xDel = 0; /* Do not copy the destructor */ @@ -117840,18 +117840,18 @@ static int synthCollSeq(tdsqlite3 *db, CollSeq *pColl){ ** This routine is called on a collation sequence before it is used to ** check that it is defined. An undefined collation sequence exists when ** a database is loaded that contains references to collation sequences -** that have not been defined by tdsqlite3_create_collation() etc. +** that have not been defined by sqlite3_create_collation() etc. ** ** If required, this routine calls the 'collation needed' callback to ** request a definition of the collating sequence. If this doesn't work, ** an equivalent collating sequence that uses a text encoding different ** from the main database is substituted, if one is available. */ -SQLITE_PRIVATE int tdsqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ +SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ if( pColl && pColl->xCmp==0 ){ const char *zName = pColl->zName; - tdsqlite3 *db = pParse->db; - CollSeq *p = tdsqlite3GetCollSeq(pParse, ENC(db), pColl, zName); + sqlite3 *db = pParse->db; + CollSeq *p = sqlite3GetCollSeq(pParse, ENC(db), pColl, zName); if( !p ){ return SQLITE_ERROR; } @@ -117876,16 +117876,16 @@ SQLITE_PRIVATE int tdsqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ ** each collation sequence structure. */ static CollSeq *findCollSeqEntry( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ const char *zName, /* Name of the collating sequence */ int create /* Create a new entry if true */ ){ CollSeq *pColl; - pColl = tdsqlite3HashFind(&db->aCollSeq, zName); + pColl = sqlite3HashFind(&db->aCollSeq, zName); if( 0==pColl && create ){ - int nName = tdsqlite3Strlen30(zName) + 1; - pColl = tdsqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName); + int nName = sqlite3Strlen30(zName) + 1; + pColl = sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName); if( pColl ){ CollSeq *pDel = 0; pColl[0].zName = (char*)&pColl[3]; @@ -117895,16 +117895,16 @@ static CollSeq *findCollSeqEntry( pColl[2].zName = (char*)&pColl[3]; pColl[2].enc = SQLITE_UTF16BE; memcpy(pColl[0].zName, zName, nName); - pDel = tdsqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl); + pDel = sqlite3HashInsert(&db->aCollSeq, pColl[0].zName, pColl); - /* If a malloc() failure occurred in tdsqlite3HashInsert(), it will + /* If a malloc() failure occurred in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ assert( pDel==0 || pDel==pColl ); if( pDel!=0 ){ - tdsqlite3OomFault(db); - tdsqlite3DbFree(db, pDel); + sqlite3OomFault(db); + sqlite3DbFree(db, pDel); pColl = 0; } } @@ -117920,15 +117920,15 @@ static CollSeq *findCollSeqEntry( ** If the entry specified is not found and 'create' is true, then create a ** new entry. Otherwise return NULL. ** -** A separate function tdsqlite3LocateCollSeq() is a wrapper around -** this routine. tdsqlite3LocateCollSeq() invokes the collation factory +** A separate function sqlite3LocateCollSeq() is a wrapper around +** this routine. sqlite3LocateCollSeq() invokes the collation factory ** if necessary and generates an error message if the collating sequence ** cannot be found. ** -** See also: tdsqlite3LocateCollSeq(), tdsqlite3GetCollSeq() +** See also: sqlite3LocateCollSeq(), sqlite3GetCollSeq() */ -SQLITE_PRIVATE CollSeq *tdsqlite3FindCollSeq( - tdsqlite3 *db, /* Database connection to search */ +SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq( + sqlite3 *db, /* Database connection to search */ u8 enc, /* Desired text encoding */ const char *zName, /* Name of the collating sequence. Might be NULL */ int create /* True to create CollSeq if doesn't already exist */ @@ -117957,34 +117957,34 @@ SQLITE_PRIVATE CollSeq *tdsqlite3FindCollSeq( ** db for collation type name zName, length nName, or NULL, if no collation ** sequence can be found. If no collation is found, leave an error message. ** -** See also: tdsqlite3LocateCollSeq(), tdsqlite3FindCollSeq() +** See also: sqlite3LocateCollSeq(), sqlite3FindCollSeq() */ -SQLITE_PRIVATE CollSeq *tdsqlite3GetCollSeq( +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( Parse *pParse, /* Parsing context */ u8 enc, /* The desired encoding for the collating sequence */ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ const char *zName /* Collating sequence name */ ){ CollSeq *p; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; p = pColl; if( !p ){ - p = tdsqlite3FindCollSeq(db, enc, zName, 0); + p = sqlite3FindCollSeq(db, enc, zName, 0); } if( !p || !p->xCmp ){ /* No collation sequence of this type for this encoding is registered. ** Call the collation factory to see if it can supply us with one. */ callCollNeeded(db, enc, zName); - p = tdsqlite3FindCollSeq(db, enc, zName, 0); + p = sqlite3FindCollSeq(db, enc, zName, 0); } if( p && !p->xCmp && synthCollSeq(db, p) ){ p = 0; } assert( !p || p->xCmp ); if( p==0 ){ - tdsqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); pParse->rc = SQLITE_ERROR_MISSING_COLLSEQ; } return p; @@ -118004,21 +118004,21 @@ SQLITE_PRIVATE CollSeq *tdsqlite3GetCollSeq( ** another error occurs, NULL is returned and an error message written into ** pParse. ** -** This routine is a wrapper around tdsqlite3FindCollSeq(). This routine +** This routine is a wrapper around sqlite3FindCollSeq(). This routine ** invokes the collation factory if the named collation cannot be found ** and generates an error message. ** -** See also: tdsqlite3FindCollSeq(), tdsqlite3GetCollSeq() +** See also: sqlite3FindCollSeq(), sqlite3GetCollSeq() */ -SQLITE_PRIVATE CollSeq *tdsqlite3LocateCollSeq(Parse *pParse, const char *zName){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ + sqlite3 *db = pParse->db; u8 enc = ENC(db); u8 initbusy = db->init.busy; CollSeq *pColl; - pColl = tdsqlite3FindCollSeq(db, enc, zName, initbusy); + pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); if( !initbusy && (!pColl || !pColl->xCmp) ){ - pColl = tdsqlite3GetCollSeq(pParse, enc, pColl, zName); + pColl = sqlite3GetCollSeq(pParse, enc, pColl, zName); } return pColl; @@ -118089,13 +118089,13 @@ static int matchQuality( ** Search a FuncDefHash for a function with the given name. Return ** a pointer to the matching FuncDef if found, or 0 if there is no match. */ -SQLITE_PRIVATE FuncDef *tdsqlite3FunctionSearch( +SQLITE_PRIVATE FuncDef *sqlite3FunctionSearch( int h, /* Hash of the name */ const char *zFunc /* Name of function */ ){ FuncDef *p; - for(p=tdsqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ - if( tdsqlite3StrICmp(p->zName, zFunc)==0 ){ + for(p=sqlite3BuiltinFunctions.a[h]; p; p=p->u.pHash){ + if( sqlite3StrICmp(p->zName, zFunc)==0 ){ return p; } } @@ -118105,7 +118105,7 @@ SQLITE_PRIVATE FuncDef *tdsqlite3FunctionSearch( /* ** Insert a new FuncDef into a FuncDefHash hash table. */ -SQLITE_PRIVATE void tdsqlite3InsertBuiltinFuncs( +SQLITE_PRIVATE void sqlite3InsertBuiltinFuncs( FuncDef *aDef, /* List of global functions to be inserted */ int nDef /* Length of the apDef[] list */ ){ @@ -118113,18 +118113,18 @@ SQLITE_PRIVATE void tdsqlite3InsertBuiltinFuncs( for(i=0; i='a' && zName[0]<='z' ); - pOther = tdsqlite3FunctionSearch(h, zName); + pOther = sqlite3FunctionSearch(h, zName); if( pOther ){ assert( pOther!=&aDef[i] && pOther->pNext!=&aDef[i] ); aDef[i].pNext = pOther->pNext; pOther->pNext = &aDef[i]; }else{ aDef[i].pNext = 0; - aDef[i].u.pHash = tdsqlite3BuiltinFunctions.a[h]; - tdsqlite3BuiltinFunctions.a[h] = &aDef[i]; + aDef[i].u.pHash = sqlite3BuiltinFunctions.a[h]; + sqlite3BuiltinFunctions.a[h] = &aDef[i]; } } } @@ -118150,8 +118150,8 @@ SQLITE_PRIVATE void tdsqlite3InsertBuiltinFuncs( ** number of arguments may be returned even if the eTextRep flag does not ** match that requested. */ -SQLITE_PRIVATE FuncDef *tdsqlite3FindFunction( - tdsqlite3 *db, /* An open database */ +SQLITE_PRIVATE FuncDef *sqlite3FindFunction( + sqlite3 *db, /* An open database */ const char *zName, /* Name of the function. zero-terminated */ int nArg, /* Number of arguments. -1 means any number */ u8 enc, /* Preferred text encoding */ @@ -118165,11 +118165,11 @@ SQLITE_PRIVATE FuncDef *tdsqlite3FindFunction( assert( nArg>=(-2) ); assert( nArg>=(-1) || createFlag==0 ); - nName = tdsqlite3Strlen30(zName); + nName = sqlite3Strlen30(zName); /* First search for a match amongst the application-defined functions. */ - p = (FuncDef*)tdsqlite3HashFind(&db->aFunc, zName); + p = (FuncDef*)sqlite3HashFind(&db->aFunc, zName); while( p ){ int score = matchQuality(p, nArg, enc); if( score>bestScore ){ @@ -118193,8 +118193,8 @@ SQLITE_PRIVATE FuncDef *tdsqlite3FindFunction( */ if( !createFlag && (pBest==0 || (db->mDbFlags & DBFLAG_PreferBuiltin)!=0) ){ bestScore = 0; - h = SQLITE_FUNC_HASH(tdsqlite3UpperToLower[(u8)zName[0]], nName); - p = tdsqlite3FunctionSearch(h, zName); + h = SQLITE_FUNC_HASH(sqlite3UpperToLower[(u8)zName[0]], nName); + p = sqlite3FunctionSearch(h, zName); while( p ){ int score = matchQuality(p, nArg, enc); if( score>bestScore ){ @@ -118210,18 +118210,18 @@ SQLITE_PRIVATE FuncDef *tdsqlite3FindFunction( ** new entry to the hash table and return it. */ if( createFlag && bestScorezName = (const char*)&pBest[1]; pBest->nArg = (u16)nArg; pBest->funcFlags = enc; memcpy((char*)&pBest[1], zName, nName+1); - for(z=(u8*)pBest->zName; *z; z++) *z = tdsqlite3UpperToLower[*z]; - pOther = (FuncDef*)tdsqlite3HashInsert(&db->aFunc, pBest->zName, pBest); + for(z=(u8*)pBest->zName; *z; z++) *z = sqlite3UpperToLower[*z]; + pOther = (FuncDef*)sqlite3HashInsert(&db->aFunc, pBest->zName, pBest); if( pOther==pBest ){ - tdsqlite3DbFree(db, pBest); - tdsqlite3OomFault(db); + sqlite3DbFree(db, pBest); + sqlite3OomFault(db); return 0; }else{ pBest->pNext = pOther; @@ -118236,13 +118236,13 @@ SQLITE_PRIVATE FuncDef *tdsqlite3FindFunction( /* ** Free all resources held by the schema structure. The void* argument points -** at a Schema struct. This function does not call tdsqlite3DbFree(db, ) on the +** at a Schema struct. This function does not call sqlite3DbFree(db, ) on the ** pointer itself, it just cleans up subsidiary resources (i.e. the contents ** of the schema hash tables). ** ** The Schema.cache_size variable is not cleared. */ -SQLITE_PRIVATE void tdsqlite3SchemaClear(void *p){ +SQLITE_PRIVATE void sqlite3SchemaClear(void *p){ Hash temp1; Hash temp2; HashElem *pElem; @@ -118250,19 +118250,19 @@ SQLITE_PRIVATE void tdsqlite3SchemaClear(void *p){ temp1 = pSchema->tblHash; temp2 = pSchema->trigHash; - tdsqlite3HashInit(&pSchema->trigHash); - tdsqlite3HashClear(&pSchema->idxHash); + sqlite3HashInit(&pSchema->trigHash); + sqlite3HashClear(&pSchema->idxHash); for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){ - tdsqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); + sqlite3DeleteTrigger(0, (Trigger*)sqliteHashData(pElem)); } - tdsqlite3HashClear(&temp2); - tdsqlite3HashInit(&pSchema->tblHash); + sqlite3HashClear(&temp2); + sqlite3HashInit(&pSchema->tblHash); for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){ Table *pTab = sqliteHashData(pElem); - tdsqlite3DeleteTable(0, pTab); + sqlite3DeleteTable(0, pTab); } - tdsqlite3HashClear(&temp1); - tdsqlite3HashClear(&pSchema->fkeyHash); + sqlite3HashClear(&temp1); + sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; if( pSchema->schemaFlags & DB_SchemaLoaded ){ pSchema->iGeneration++; @@ -118274,20 +118274,20 @@ SQLITE_PRIVATE void tdsqlite3SchemaClear(void *p){ ** Find and return the schema associated with a BTree. Create ** a new one if necessary. */ -SQLITE_PRIVATE Schema *tdsqlite3SchemaGet(tdsqlite3 *db, Btree *pBt){ +SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ Schema * p; if( pBt ){ - p = (Schema *)tdsqlite3BtreeSchema(pBt, sizeof(Schema), tdsqlite3SchemaClear); + p = (Schema *)sqlite3BtreeSchema(pBt, sizeof(Schema), sqlite3SchemaClear); }else{ - p = (Schema *)tdsqlite3DbMallocZero(0, sizeof(Schema)); + p = (Schema *)sqlite3DbMallocZero(0, sizeof(Schema)); } if( !p ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); }else if ( 0==p->file_format ){ - tdsqlite3HashInit(&p->tblHash); - tdsqlite3HashInit(&p->idxHash); - tdsqlite3HashInit(&p->trigHash); - tdsqlite3HashInit(&p->fkeyHash); + sqlite3HashInit(&p->tblHash); + sqlite3HashInit(&p->idxHash); + sqlite3HashInit(&p->trigHash); + sqlite3HashInit(&p->fkeyHash); p->enc = SQLITE_UTF8; } return p; @@ -118325,17 +118325,17 @@ SQLITE_PRIVATE Schema *tdsqlite3SchemaGet(tdsqlite3 *db, Btree *pBt){ ** pSrc->a[0].pIndex Pointer to the INDEXED BY index, if there is one ** */ -SQLITE_PRIVATE Table *tdsqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ +SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ struct SrcList_item *pItem = pSrc->a; Table *pTab; assert( pItem && pSrc->nSrc==1 ); - pTab = tdsqlite3LocateTableItem(pParse, 0, pItem); - tdsqlite3DeleteTable(pParse->db, pItem->pTab); + pTab = sqlite3LocateTableItem(pParse, 0, pItem); + sqlite3DeleteTable(pParse->db, pItem->pTab); pItem->pTab = pTab; if( pTab ){ pTab->nTabRef++; } - if( tdsqlite3IndexedByLookup(pParse, pItem) ){ + if( sqlite3IndexedByLookup(pParse, pItem) ){ pTab = 0; } return pTab; @@ -118353,21 +118353,21 @@ SQLITE_PRIVATE Table *tdsqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ ** been specified ** ** 3) The table is a shadow table, the database connection is in -** defensive mode, and the current tdsqlite3_prepare() +** defensive mode, and the current sqlite3_prepare() ** is for a top-level SQL statement. */ static int tabIsReadOnly(Parse *pParse, Table *pTab){ - tdsqlite3 *db; + sqlite3 *db; if( IsVirtual(pTab) ){ - return tdsqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0; + return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0; } if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0; db = pParse->db; if( (pTab->tabFlags & TF_Readonly)!=0 ){ - return tdsqlite3WritableSchema(db)==0 && pParse->nested==0; + return sqlite3WritableSchema(db)==0 && pParse->nested==0; } assert( pTab->tabFlags & TF_Shadow ); - return tdsqlite3ReadOnlyShadowTables(db); + return sqlite3ReadOnlyShadowTables(db); } /* @@ -118375,14 +118375,14 @@ static int tabIsReadOnly(Parse *pParse, Table *pTab){ ** writable, generate an error message and return 1. If it is ** writable return 0; */ -SQLITE_PRIVATE int tdsqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ +SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ if( tabIsReadOnly(pParse, pTab) ){ - tdsqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); + sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; } #ifndef SQLITE_OMIT_VIEW if( !viewOk && pTab->pSelect ){ - tdsqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); + sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); return 1; } #endif @@ -118396,7 +118396,7 @@ SQLITE_PRIVATE int tdsqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ ** pWhere argument is an optional WHERE clause that restricts the ** set of rows in the view that are to be added to the ephemeral table. */ -SQLITE_PRIVATE void tdsqlite3MaterializeView( +SQLITE_PRIVATE void sqlite3MaterializeView( Parse *pParse, /* Parsing context */ Table *pView, /* View definition */ Expr *pWhere, /* Optional WHERE clause to be added */ @@ -118407,22 +118407,22 @@ SQLITE_PRIVATE void tdsqlite3MaterializeView( SelectDest dest; Select *pSel; SrcList *pFrom; - tdsqlite3 *db = pParse->db; - int iDb = tdsqlite3SchemaToIndex(db, pView->pSchema); - pWhere = tdsqlite3ExprDup(db, pWhere, 0); - pFrom = tdsqlite3SrcListAppend(pParse, 0, 0, 0); + sqlite3 *db = pParse->db; + int iDb = sqlite3SchemaToIndex(db, pView->pSchema); + pWhere = sqlite3ExprDup(db, pWhere, 0); + pFrom = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pFrom ){ assert( pFrom->nSrc==1 ); - pFrom->a[0].zName = tdsqlite3DbStrDup(db, pView->zName); - pFrom->a[0].zDatabase = tdsqlite3DbStrDup(db, db->aDb[iDb].zDbSName); + pFrom->a[0].zName = sqlite3DbStrDup(db, pView->zName); + pFrom->a[0].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zDbSName); assert( pFrom->a[0].pOn==0 ); assert( pFrom->a[0].pUsing==0 ); } - pSel = tdsqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, + pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, SF_IncludeHidden, pLimit); - tdsqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); - tdsqlite3Select(pParse, pSel, &dest); - tdsqlite3SelectDelete(db, pSel); + sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); + sqlite3Select(pParse, pSel, &dest); + sqlite3SelectDelete(db, pSel); } #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */ @@ -118435,7 +118435,7 @@ SQLITE_PRIVATE void tdsqlite3MaterializeView( ** \__________________________/ ** pLimitWhere (pInClause) */ -SQLITE_PRIVATE Expr *tdsqlite3LimitWhere( +SQLITE_PRIVATE Expr *sqlite3LimitWhere( Parse *pParse, /* The parser context */ SrcList *pSrc, /* the FROM clause -- which tables to scan */ Expr *pWhere, /* The WHERE clause. May be null */ @@ -118443,7 +118443,7 @@ SQLITE_PRIVATE Expr *tdsqlite3LimitWhere( Expr *pLimit, /* The LIMIT clause. May be null */ char *zStmtType /* Either DELETE or UPDATE. For err msgs. */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ @@ -118454,9 +118454,9 @@ SQLITE_PRIVATE Expr *tdsqlite3LimitWhere( /* Check that there isn't an ORDER BY without a LIMIT clause. */ if( pOrderBy && pLimit==0 ) { - tdsqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); - tdsqlite3ExprDelete(pParse->db, pWhere); - tdsqlite3ExprListDelete(pParse->db, pOrderBy); + sqlite3ErrorMsg(pParse, "ORDER BY without LIMIT on %s", zStmtType); + sqlite3ExprDelete(pParse->db, pWhere); + sqlite3ExprListDelete(pParse->db, pOrderBy); return 0; } @@ -118478,25 +118478,25 @@ SQLITE_PRIVATE Expr *tdsqlite3LimitWhere( pTab = pSrc->a[0].pTab; if( HasRowid(pTab) ){ - pLhs = tdsqlite3PExpr(pParse, TK_ROW, 0, 0); - pEList = tdsqlite3ExprListAppend( - pParse, 0, tdsqlite3PExpr(pParse, TK_ROW, 0, 0) + pLhs = sqlite3PExpr(pParse, TK_ROW, 0, 0); + pEList = sqlite3ExprListAppend( + pParse, 0, sqlite3PExpr(pParse, TK_ROW, 0, 0) ); }else{ - Index *pPk = tdsqlite3PrimaryKeyIndex(pTab); + Index *pPk = sqlite3PrimaryKeyIndex(pTab); if( pPk->nKeyCol==1 ){ const char *zName = pTab->aCol[pPk->aiColumn[0]].zName; - pLhs = tdsqlite3Expr(db, TK_ID, zName); - pEList = tdsqlite3ExprListAppend(pParse, 0, tdsqlite3Expr(db, TK_ID, zName)); + pLhs = sqlite3Expr(db, TK_ID, zName); + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); }else{ int i; for(i=0; inKeyCol; i++){ - Expr *p = tdsqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName); - pEList = tdsqlite3ExprListAppend(pParse, pEList, p); + Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zName); + pEList = sqlite3ExprListAppend(pParse, pEList, p); } - pLhs = tdsqlite3PExpr(pParse, TK_VECTOR, 0, 0); + pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); if( pLhs ){ - pLhs->x.pList = tdsqlite3ExprListDup(db, pEList, 0); + pLhs->x.pList = sqlite3ExprListDup(db, pEList, 0); } } } @@ -118504,18 +118504,18 @@ SQLITE_PRIVATE Expr *tdsqlite3LimitWhere( /* duplicate the FROM clause as it is needed by both the DELETE/UPDATE tree ** and the SELECT subtree. */ pSrc->a[0].pTab = 0; - pSelectSrc = tdsqlite3SrcListDup(pParse->db, pSrc, 0); + pSelectSrc = sqlite3SrcListDup(pParse->db, pSrc, 0); pSrc->a[0].pTab = pTab; pSrc->a[0].pIBIndex = 0; /* generate the SELECT expression tree. */ - pSelect = tdsqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, + pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, pOrderBy,0,pLimit ); /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ - pInClause = tdsqlite3PExpr(pParse, TK_IN, pLhs, 0); - tdsqlite3PExprAddSelect(pParse, pInClause, pSelect); + pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); + sqlite3PExprAddSelect(pParse, pInClause, pSelect); return pInClause; } #endif /* defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) */ @@ -118528,7 +118528,7 @@ SQLITE_PRIVATE Expr *tdsqlite3LimitWhere( ** \________/ \________________/ ** pTabList pWhere */ -SQLITE_PRIVATE void tdsqlite3DeleteFrom( +SQLITE_PRIVATE void sqlite3DeleteFrom( Parse *pParse, /* The parser context */ SrcList *pTabList, /* The table from which we should delete things */ Expr *pWhere, /* The WHERE clause. May be null */ @@ -118544,7 +118544,7 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( int iDataCur = 0; /* VDBE cursor for the canonical data source */ int iIdxCur = 0; /* Cursor number of the first index */ int nIdx; /* Number of indices */ - tdsqlite3 *db; /* Main database structure */ + sqlite3 *db; /* Main database structure */ AuthContext sContext; /* Authorization context */ NameContext sNC; /* Name context to resolve expressions in */ int iDb; /* Database number */ @@ -118584,20 +118584,20 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( ** will be calling are designed to work with multiple tables and expect ** an SrcList* parameter instead of just a Table* parameter. */ - pTab = tdsqlite3SrcListLookup(pParse, pTabList); + pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto delete_from_cleanup; /* Figure out if we have any triggers and if the table being ** deleted from is a view */ #ifndef SQLITE_OMIT_TRIGGER - pTrigger = tdsqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); isView = pTab->pSelect!=0; #else # define pTrigger 0 # define isView 0 #endif - bComplex = pTrigger || tdsqlite3FkRequired(pParse, pTab, 0, 0); + bComplex = pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0); #ifdef SQLITE_OMIT_VIEW # undef isView # define isView 0 @@ -118605,7 +118605,7 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( !isView ){ - pWhere = tdsqlite3LimitWhere( + pWhere = sqlite3LimitWhere( pParse, pTabList, pWhere, pOrderBy, pLimit, "DELETE" ); pOrderBy = 0; @@ -118615,16 +118615,16 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( /* If pTab is really a view, make sure it has been initialized. */ - if( tdsqlite3ViewGetColumnNames(pParse, pTab) ){ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto delete_from_cleanup; } - if( tdsqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ + if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ goto delete_from_cleanup; } - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDbnDb ); - rcauth = tdsqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, + rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, db->aDb[iDb].zDbSName); assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); if( rcauth==SQLITE_DENY ){ @@ -118643,24 +118643,24 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( /* Start the view context */ if( isView ){ - tdsqlite3AuthContextPush(pParse, &sContext, pTab->zName); + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); } /* Begin generating code. */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v==0 ){ goto delete_from_cleanup; } - if( pParse->nested==0 ) tdsqlite3VdbeCountChanges(v); - tdsqlite3BeginWriteOperation(pParse, bComplex, iDb); + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, bComplex, iDb); /* If we are trying to delete from a view, realize that view into ** an ephemeral table. */ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ - tdsqlite3MaterializeView(pParse, pTab, + sqlite3MaterializeView(pParse, pTab, pWhere, pOrderBy, pLimit, iTabCur ); iDataCur = iIdxCur = iTabCur; @@ -118674,7 +118674,7 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; - if( tdsqlite3ResolveExprNames(&sNC, pWhere) ){ + if( sqlite3ResolveExprNames(&sNC, pWhere) ){ goto delete_from_cleanup; } @@ -118686,14 +118686,14 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( && !pParse->pTriggerTab ){ memCnt = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); + sqlite3VdbeAddOp2(v, OP_Integer, 0, memCnt); } #ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to erase the whole table. Prior to version 3.6.5, ** this optimization caused the row change count (the value returned by - ** API function tdsqlite3_count_changes) to be set incorrectly. + ** API function sqlite3_count_changes) to be set incorrectly. ** ** The "rcauth==SQLITE_OK" terms is the ** IMPLEMENTATION-OF: R-17228-37124 If the action code is SQLITE_DELETE and @@ -118710,14 +118710,14 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( #endif ){ assert( !isView ); - tdsqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); + sqlite3TableLock(pParse, iDb, pTab->tnum, 1, pTab->zName); if( HasRowid(pTab) ){ - tdsqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1, + sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt ? memCnt : -1, pTab->zName, P4_STATIC); } for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ assert( pIdx->pSchema==pTab->pSchema ); - tdsqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); + sqlite3VdbeAddOp2(v, OP_Clear, pIdx->tnum, iDb); } }else #endif /* SQLITE_OMIT_TRUNCATE_OPTIMIZATION */ @@ -118730,18 +118730,18 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( pPk = 0; nPk = 1; iRowSet = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); + sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); }else{ /* For a WITHOUT ROWID table, create an ephemeral table used to ** hold all primary keys for rows to be deleted. */ - pPk = tdsqlite3PrimaryKeyIndex(pTab); + pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); nPk = pPk->nKeyCol; iPk = pParse->nMem+1; pParse->nMem += nPk; iEphCur = pParse->nTab++; - addrEphOpen = tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); - tdsqlite3VdbeSetP4KeyInfo(pParse, pPk); + addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); } /* Construct a query to find the rowid or primary key for every row @@ -118752,29 +118752,29 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( ** ONEPASS_SINGLE: One-pass approach - at most one row deleted. ** ONEPASS_MULTI: One-pass approach - any number of rows may be deleted. */ - pWInfo = tdsqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1); if( pWInfo==0 ) goto delete_from_cleanup; - eOnePass = tdsqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); - if( eOnePass!=ONEPASS_SINGLE ) tdsqlite3MultiWrite(pParse); + if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); /* Keep track of the number of rows to be deleted */ if( memCnt ){ - tdsqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); } /* Extract the rowid or primary key for the current row */ if( pPk ){ for(i=0; iaiColumn[i]>=0 ); - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, pPk->aiColumn[i], iPk+i); } iKey = iPk; }else{ iKey = ++pParse->nMem; - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey); } if( eOnePass!=ONEPASS_OFF ){ @@ -118782,37 +118782,37 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( ** one, so just keep it in its register(s) and fall through to the ** delete code. */ nKey = nPk; /* OP_Found will use an unpacked key */ - aToOpen = tdsqlite3DbMallocRawNN(db, nIdx+2); + aToOpen = sqlite3DbMallocRawNN(db, nIdx+2); if( aToOpen==0 ){ - tdsqlite3WhereEnd(pWInfo); + sqlite3WhereEnd(pWInfo); goto delete_from_cleanup; } memset(aToOpen, 1, nIdx+1); aToOpen[nIdx+1] = 0; if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iTabCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iTabCur] = 0; - if( addrEphOpen ) tdsqlite3VdbeChangeToNoop(v, addrEphOpen); + if( addrEphOpen ) sqlite3VdbeChangeToNoop(v, addrEphOpen); }else{ if( pPk ){ /* Add the PK key for this row to the temporary table */ iKey = ++pParse->nMem; nKey = 0; /* Zero tells OP_Found to use a composite key */ - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, - tdsqlite3IndexAffinityStr(pParse->db, pPk), nPk); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk); + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, iKey, + sqlite3IndexAffinityStr(pParse->db, pPk), nPk); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEphCur, iKey, iPk, nPk); }else{ /* Add the rowid of the row to be deleted to the RowSet */ nKey = 1; /* OP_DeferredSeek always uses a single rowid */ - tdsqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); + sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey); } } /* If this DELETE cannot use the ONEPASS strategy, this is the ** end of the WHERE loop */ if( eOnePass!=ONEPASS_OFF ){ - addrBypass = tdsqlite3VdbeMakeLabel(pParse); + addrBypass = sqlite3VdbeMakeLabel(pParse); }else{ - tdsqlite3WhereEnd(pWInfo); + sqlite3WhereEnd(pWInfo); } /* Unless this is a view, open cursors for the table we are @@ -118823,14 +118823,14 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( if( !isView ){ int iAddrOnce = 0; if( eOnePass==ONEPASS_MULTI ){ - iAddrOnce = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + iAddrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } testcase( IsVirtual(pTab) ); - tdsqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE, + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE, iTabCur, aToOpen, &iDataCur, &iIdxCur); assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur ); assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 ); - if( eOnePass==ONEPASS_MULTI ) tdsqlite3VdbeJumpHere(v, iAddrOnce); + if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce); } /* Set up a loop over the rowids/primary-keys that were found in the @@ -118840,19 +118840,19 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( assert( nKey==nPk ); /* OP_Found will use an unpacked key */ if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){ assert( pPk!=0 || pTab->pSelect!=0 ); - tdsqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey); VdbeCoverage(v); } }else if( pPk ){ - addrLoop = tdsqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); + addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v); if( IsVirtual(pTab) ){ - tdsqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey); + sqlite3VdbeAddOp3(v, OP_Column, iEphCur, 0, iKey); }else{ - tdsqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); + sqlite3VdbeAddOp2(v, OP_RowData, iEphCur, iKey); } assert( nKey==0 ); /* OP_Found will use a composite key */ }else{ - addrLoop = tdsqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); + addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); VdbeCoverage(v); assert( nKey==1 ); } @@ -118860,36 +118860,36 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( /* Delete the row */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ - const char *pVTab = (const char *)tdsqlite3GetVTable(db, pTab); - tdsqlite3VtabMakeWritable(pParse, pTab); + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); if( eOnePass==ONEPASS_SINGLE ){ - tdsqlite3VdbeAddOp1(v, OP_Close, iTabCur); - if( tdsqlite3IsToplevel(pParse) ){ + sqlite3VdbeAddOp1(v, OP_Close, iTabCur); + if( sqlite3IsToplevel(pParse) ){ pParse->isMultiWrite = 0; } } - tdsqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); - tdsqlite3VdbeChangeP5(v, OE_Abort); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, OE_Abort); }else #endif { int count = (pParse->nested==0); /* True to count changes */ - tdsqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]); } /* End of the loop over all rowids/primary-keys. */ if( eOnePass!=ONEPASS_OFF ){ - tdsqlite3VdbeResolveLabel(v, addrBypass); - tdsqlite3WhereEnd(pWInfo); + sqlite3VdbeResolveLabel(v, addrBypass); + sqlite3WhereEnd(pWInfo); }else if( pPk ){ - tdsqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addrLoop); + sqlite3VdbeAddOp2(v, OP_Next, iEphCur, addrLoop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrLoop); }else{ - tdsqlite3VdbeGoto(v, addrLoop); - tdsqlite3VdbeJumpHere(v, addrLoop); + sqlite3VdbeGoto(v, addrLoop); + sqlite3VdbeJumpHere(v, addrLoop); } } /* End non-truncate path */ @@ -118898,28 +118898,28 @@ SQLITE_PRIVATE void tdsqlite3DeleteFrom( ** autoincrement tables. */ if( pParse->nested==0 && pParse->pTriggerTab==0 ){ - tdsqlite3AutoincrementEnd(pParse); + sqlite3AutoincrementEnd(pParse); } /* Return the number of rows that were deleted. If this routine is - ** generating code because of a call to tdsqlite3NestedParse(), do not + ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ if( memCnt ){ - tdsqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); - tdsqlite3VdbeSetNumCols(v, 1); - tdsqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); } delete_from_cleanup: - tdsqlite3AuthContextPop(&sContext); - tdsqlite3SrcListDelete(db, pTabList); - tdsqlite3ExprDelete(db, pWhere); + sqlite3AuthContextPop(&sContext); + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprDelete(db, pWhere); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) - tdsqlite3ExprListDelete(db, pOrderBy); - tdsqlite3ExprDelete(db, pLimit); + sqlite3ExprListDelete(db, pOrderBy); + sqlite3ExprDelete(db, pLimit); #endif - tdsqlite3DbFree(db, aToOpen); + sqlite3DbFree(db, aToOpen); return; } /* Make sure "isView" and other macros defined above are undefined. Otherwise @@ -118973,7 +118973,7 @@ delete_from_cleanup: ** Except, this optimization is disabled if there are BEFORE triggers since ** the trigger body might have moved the cursor. */ -SQLITE_PRIVATE void tdsqlite3GenerateRowDelete( +SQLITE_PRIVATE void sqlite3GenerateRowDelete( Parse *pParse, /* Parsing context */ Table *pTab, /* Table containing the row to be deleted */ Trigger *pTrigger, /* List of triggers to (potentially) fire */ @@ -118999,45 +118999,45 @@ SQLITE_PRIVATE void tdsqlite3GenerateRowDelete( /* Seek cursor iCur to the row to delete. If this row no longer exists ** (this can happen if a trigger program has already deleted it), do ** not attempt to delete it or fire any DELETE triggers. */ - iLabel = tdsqlite3VdbeMakeLabel(pParse); + iLabel = sqlite3VdbeMakeLabel(pParse); opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound; if( eMode==ONEPASS_OFF ){ - tdsqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); + sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk); VdbeCoverageIf(v, opSeek==OP_NotExists); VdbeCoverageIf(v, opSeek==OP_NotFound); } /* If there are any triggers to fire, allocate a range of registers to ** use for the old.* references in the triggers. */ - if( tdsqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ + if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ u32 mask; /* Mask of OLD.* columns in use */ int iCol; /* Iterator used while populating OLD.* */ int addrStart; /* Start of BEFORE trigger programs */ /* TODO: Could use temporary registers here. Also could attempt to ** avoid copying the contents of the rowid register. */ - mask = tdsqlite3TriggerColmask( + mask = sqlite3TriggerColmask( pParse, pTrigger, 0, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onconf ); - mask |= tdsqlite3FkOldmask(pParse, pTab); + mask |= sqlite3FkOldmask(pParse, pTab); iOld = pParse->nMem+1; pParse->nMem += (1 + pTab->nCol); /* Populate the OLD.* pseudo-table register array. These values will be ** used by any BEFORE and AFTER triggers that exist. */ - tdsqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); + sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); for(iCol=0; iColnCol; iCol++){ testcase( mask!=0xffffffff && iCol==31 ); testcase( mask!=0xffffffff && iCol==32 ); if( mask==0xffffffff || (iCol<=31 && (mask & MASKBIT32(iCol))!=0) ){ - int kk = tdsqlite3TableColumnToStorage(pTab, iCol); - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+kk+1); + int kk = sqlite3TableColumnToStorage(pTab, iCol); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, iCol, iOld+kk+1); } } /* Invoke BEFORE DELETE trigger programs. */ - addrStart = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3CodeRowTrigger(pParse, pTrigger, + addrStart = sqlite3VdbeCurrentAddr(v); + sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel ); @@ -119049,8 +119049,8 @@ SQLITE_PRIVATE void tdsqlite3GenerateRowDelete( ** Also disable the iIdxNoSeek optimization since the BEFORE trigger ** may have moved that cursor. */ - if( addrStart=0 ); @@ -119060,7 +119060,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateRowDelete( /* Do FK processing. This call checks that any FK constraints that ** refer to this table (i.e. constraints attached to other tables) ** are not violated by deleting this row. */ - tdsqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); + sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); } /* Delete the index and table entries. Skip this step if pTab is really @@ -119075,35 +119075,35 @@ SQLITE_PRIVATE void tdsqlite3GenerateRowDelete( */ if( pTab->pSelect==0 ){ u8 p5 = 0; - tdsqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); - tdsqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); - if( pParse->nested==0 || 0==tdsqlite3_stricmp(pTab->zName, "sqlite_stat1") ){ - tdsqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0)); + if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){ + sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE); } if( eMode!=ONEPASS_OFF ){ - tdsqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); + sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE); } if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){ - tdsqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); + sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek); } if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION; - tdsqlite3VdbeChangeP5(v, p5); + sqlite3VdbeChangeP5(v, p5); } /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to ** handle rows (possibly in other tables) that refer via a foreign key ** to the row just deleted. */ - tdsqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); + sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); /* Invoke AFTER DELETE trigger programs. */ - tdsqlite3CodeRowTrigger(pParse, pTrigger, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel ); /* Jump here if the row had already been deleted before any BEFORE ** trigger programs were invoked. Or if a trigger program throws a ** RAISE(IGNORE) exception. */ - tdsqlite3VdbeResolveLabel(v, iLabel); + sqlite3VdbeResolveLabel(v, iLabel); VdbeModuleComment((v, "END: GenRowDel()")); } @@ -119125,7 +119125,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateRowDelete( ** 3. The "iDataCur" cursor must be already be positioned on the row ** that is to be deleted. */ -SQLITE_PRIVATE void tdsqlite3GenerateRowIndexDelete( +SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete( Parse *pParse, /* Parsing and code generating context */ Table *pTab, /* Table containing the row to be deleted */ int iDataCur, /* Cursor of table holding data. */ @@ -119142,18 +119142,18 @@ SQLITE_PRIVATE void tdsqlite3GenerateRowIndexDelete( Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */ v = pParse->pVdbe; - pPk = HasRowid(pTab) ? 0 : tdsqlite3PrimaryKeyIndex(pTab); + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); for(i=0, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ assert( iIdxCur+i!=iDataCur || pPk==pIdx ); if( aRegIdx!=0 && aRegIdx[i]==0 ) continue; if( pIdx==pPk ) continue; if( iIdxCur+i==iIdxNoSeek ) continue; VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName)); - r1 = tdsqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel, pPrior, r1); - tdsqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, + sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1, pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn); - tdsqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); + sqlite3ResolvePartIdxLabel(pParse, iPartIdxLabel); pPrior = pIdx; } } @@ -119172,11 +119172,11 @@ SQLITE_PRIVATE void tdsqlite3GenerateRowIndexDelete( ** ** If *piPartIdxLabel is not NULL, fill it in with a label and jump ** to that label if pIdx is a partial index that should be skipped. -** The label should be resolved using tdsqlite3ResolvePartIdxLabel(). +** The label should be resolved using sqlite3ResolvePartIdxLabel(). ** A partial index should be skipped if its WHERE clause evaluates ** to false or null. If pIdx is not a partial index, *piPartIdxLabel ** will be set to zero which is an empty label that is ignored by -** tdsqlite3ResolvePartIdxLabel(). +** sqlite3ResolvePartIdxLabel(). ** ** The pPrior and regPrior parameters are used to implement a cache to ** avoid unnecessary register loads. If pPrior is not NULL, then it is @@ -119189,7 +119189,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateRowIndexDelete( ** on a table with multiple indices, and especially with the ROWID or ** PRIMARY KEY columns of the index. */ -SQLITE_PRIVATE int tdsqlite3GenerateIndexKey( +SQLITE_PRIVATE int sqlite3GenerateIndexKey( Parse *pParse, /* Parsing context */ Index *pIdx, /* The index for which to generate a key */ int iDataCur, /* Cursor number from which to take column data */ @@ -119206,9 +119206,9 @@ SQLITE_PRIVATE int tdsqlite3GenerateIndexKey( if( piPartIdxLabel ){ if( pIdx->pPartIdxWhere ){ - *piPartIdxLabel = tdsqlite3VdbeMakeLabel(pParse); + *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse); pParse->iSelfTab = iDataCur + 1; - tdsqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, + sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, SQLITE_JUMPIFNULL); pParse->iSelfTab = 0; pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02; @@ -119218,7 +119218,7 @@ SQLITE_PRIVATE int tdsqlite3GenerateIndexKey( } } nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn; - regBase = tdsqlite3GetTempRange(pParse, nCol); + regBase = sqlite3GetTempRange(pParse, nCol); if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0; for(j=0; jpTable->pSelect ){ - const char *zAff = tdsqlite3IndexAffinityStr(pParse->db, pIdx); - tdsqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); + const char *zAff = sqlite3IndexAffinityStr(pParse->db, pIdx); + sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT); } } - tdsqlite3ReleaseTempRange(pParse, regBase, nCol); + sqlite3ReleaseTempRange(pParse, regBase, nCol); return regBase; } /* -** If a prior call to tdsqlite3GenerateIndexKey() generated a jump-over label +** If a prior call to sqlite3GenerateIndexKey() generated a jump-over label ** because it was a partial index, then this routine should be called to ** resolve that label. */ -SQLITE_PRIVATE void tdsqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ +SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ if( iLabel ){ - tdsqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); + sqlite3VdbeResolveLabel(pParse->pVdbe, iLabel); } } @@ -119287,7 +119287,7 @@ SQLITE_PRIVATE void tdsqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){ /* ** Return the collating function associated with a function. */ -static CollSeq *tdsqlite3GetFuncCollSeq(tdsqlite3_context *context){ +static CollSeq *sqlite3GetFuncCollSeq(sqlite3_context *context){ VdbeOp *pOp; assert( context->pVdbe!=0 ); pOp = &context->pVdbe->aOp[context->iOp-1]; @@ -119300,7 +119300,7 @@ static CollSeq *tdsqlite3GetFuncCollSeq(tdsqlite3_context *context){ ** Indicate that the accumulator load should be skipped on this ** iteration of the aggregate loop. */ -static void tdsqlite3SkipAccumulatorLoad(tdsqlite3_context *context){ +static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){ assert( context->isError<=0 ); context->isError = -1; context->skipFlag = 1; @@ -119310,9 +119310,9 @@ static void tdsqlite3SkipAccumulatorLoad(tdsqlite3_context *context){ ** Implementation of the non-aggregate min() and max() functions */ static void minmaxFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ int i; int mask; /* 0 for min() or 0xffffffff for max() */ @@ -119320,32 +119320,32 @@ static void minmaxFunc( CollSeq *pColl; assert( argc>1 ); - mask = tdsqlite3_user_data(context)==0 ? 0 : -1; - pColl = tdsqlite3GetFuncCollSeq(context); + mask = sqlite3_user_data(context)==0 ? 0 : -1; + pColl = sqlite3GetFuncCollSeq(context); assert( pColl ); assert( mask==-1 || mask==0 ); iBest = 0; - if( tdsqlite3_value_type(argv[0])==SQLITE_NULL ) return; + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; for(i=1; i=0 ){ + if( sqlite3_value_type(argv[i])==SQLITE_NULL ) return; + if( (sqlite3MemCompare(argv[iBest], argv[i], pColl)^mask)>=0 ){ testcase( mask==0 ); iBest = i; } } - tdsqlite3_result_value(context, argv[iBest]); + sqlite3_result_value(context, argv[iBest]); } /* ** Return the type of the argument. */ static void typeofFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **argv + sqlite3_value **argv ){ static const char *azType[] = { "integer", "real", "text", "blob", "null" }; - int i = tdsqlite3_value_type(argv[0]) - 1; + int i = sqlite3_value_type(argv[0]) - 1; UNUSED_PARAMETER(NotUsed); assert( i>=0 && i0 ){ if( typeHaystack==SQLITE_BLOB && typeNeedle==SQLITE_BLOB ){ - zHaystack = tdsqlite3_value_blob(argv[0]); - zNeedle = tdsqlite3_value_blob(argv[1]); + zHaystack = sqlite3_value_blob(argv[0]); + zNeedle = sqlite3_value_blob(argv[1]); isText = 0; }else if( typeHaystack!=SQLITE_BLOB && typeNeedle!=SQLITE_BLOB ){ - zHaystack = tdsqlite3_value_text(argv[0]); - zNeedle = tdsqlite3_value_text(argv[1]); + zHaystack = sqlite3_value_text(argv[0]); + zNeedle = sqlite3_value_text(argv[1]); isText = 1; }else{ - pC1 = tdsqlite3_value_dup(argv[0]); - zHaystack = tdsqlite3_value_text(pC1); + pC1 = sqlite3_value_dup(argv[0]); + zHaystack = sqlite3_value_text(pC1); if( zHaystack==0 ) goto endInstrOOM; - nHaystack = tdsqlite3_value_bytes(pC1); - pC2 = tdsqlite3_value_dup(argv[1]); - zNeedle = tdsqlite3_value_text(pC2); + nHaystack = sqlite3_value_bytes(pC1); + pC2 = sqlite3_value_dup(argv[1]); + zNeedle = sqlite3_value_text(pC2); if( zNeedle==0 ) goto endInstrOOM; - nNeedle = tdsqlite3_value_bytes(pC2); + nNeedle = sqlite3_value_bytes(pC2); isText = 1; } if( zNeedle==0 || (nHaystack && zHaystack==0) ) goto endInstrOOM; @@ -119510,13 +119510,13 @@ static void instrFunc( } if( nNeedle>nHaystack ) N = 0; } - tdsqlite3_result_int(context, N); + sqlite3_result_int(context, N); endInstr: - tdsqlite3_value_free(pC1); - tdsqlite3_value_free(pC2); + sqlite3_value_free(pC1); + sqlite3_value_free(pC2); return; endInstrOOM: - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); goto endInstr; } @@ -119524,25 +119524,25 @@ endInstrOOM: ** Implementation of the printf() function. */ static void printfFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ PrintfArguments x; StrAccum str; const char *zFormat; int n; - tdsqlite3 *db = tdsqlite3_context_db_handle(context); + sqlite3 *db = sqlite3_context_db_handle(context); - if( argc>=1 && (zFormat = (const char*)tdsqlite3_value_text(argv[0]))!=0 ){ + if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){ x.nArg = argc-1; x.nUsed = 0; x.apArg = argv+1; - tdsqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); + sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]); str.printfFlags = SQLITE_PRINTF_SQLFUNC; - tdsqlite3_str_appendf(&str, zFormat, &x); + sqlite3_str_appendf(&str, zFormat, &x); n = str.nChar; - tdsqlite3_result_text(context, tdsqlite3StrAccumFinish(&str), n, + sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n, SQLITE_DYNAMIC); } } @@ -119560,9 +119560,9 @@ static void printfFunc( ** If p2 is negative, return the p2 characters preceding p1. */ static void substrFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ const unsigned char *z; const unsigned char *z2; @@ -119572,20 +119572,20 @@ static void substrFunc( int negP2 = 0; assert( argc==3 || argc==2 ); - if( tdsqlite3_value_type(argv[1])==SQLITE_NULL - || (argc==3 && tdsqlite3_value_type(argv[2])==SQLITE_NULL) + if( sqlite3_value_type(argv[1])==SQLITE_NULL + || (argc==3 && sqlite3_value_type(argv[2])==SQLITE_NULL) ){ return; } - p0type = tdsqlite3_value_type(argv[0]); - p1 = tdsqlite3_value_int(argv[1]); + p0type = sqlite3_value_type(argv[0]); + p1 = sqlite3_value_int(argv[1]); if( p0type==SQLITE_BLOB ){ - len = tdsqlite3_value_bytes(argv[0]); - z = tdsqlite3_value_blob(argv[0]); + len = sqlite3_value_bytes(argv[0]); + z = sqlite3_value_blob(argv[0]); if( z==0 ) return; - assert( len==tdsqlite3_value_bytes(argv[0]) ); + assert( len==sqlite3_value_bytes(argv[0]) ); }else{ - z = tdsqlite3_value_text(argv[0]); + z = sqlite3_value_text(argv[0]); if( z==0 ) return; len = 0; if( p1<0 ){ @@ -119603,13 +119603,13 @@ static void substrFunc( if( p1==0 ) p1 = 1; /* */ #endif if( argc==3 ){ - p2 = tdsqlite3_value_int(argv[2]); + p2 = sqlite3_value_int(argv[2]); if( p2<0 ){ p2 = -p2; negP2 = 1; } }else{ - p2 = tdsqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; + p2 = sqlite3_context_db_handle(context)->aLimit[SQLITE_LIMIT_LENGTH]; } if( p1<0 ){ p1 += len; @@ -119639,14 +119639,14 @@ static void substrFunc( for(z2=z; *z2 && p2; p2--){ SQLITE_SKIP_UTF8(z2); } - tdsqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, + sqlite3_result_text64(context, (char*)z, z2-z, SQLITE_TRANSIENT, SQLITE_UTF8); }else{ if( p1+p2>len ){ p2 = len-p1; if( p2<0 ) p2 = 0; } - tdsqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); + sqlite3_result_blob64(context, (char*)&z[p1], (u64)p2, SQLITE_TRANSIENT); } } @@ -119654,19 +119654,19 @@ static void substrFunc( ** Implementation of the round() function */ #ifndef SQLITE_OMIT_FLOATING_POINT -static void roundFunc(tdsqlite3_context *context, int argc, tdsqlite3_value **argv){ +static void roundFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ int n = 0; double r; char *zBuf; assert( argc==1 || argc==2 ); if( argc==2 ){ - if( SQLITE_NULL==tdsqlite3_value_type(argv[1]) ) return; - n = tdsqlite3_value_int(argv[1]); + if( SQLITE_NULL==sqlite3_value_type(argv[1]) ) return; + n = sqlite3_value_int(argv[1]); if( n>30 ) n = 30; if( n<0 ) n = 0; } - if( tdsqlite3_value_type(argv[0])==SQLITE_NULL ) return; - r = tdsqlite3_value_double(argv[0]); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + r = sqlite3_value_double(argv[0]); /* If Y==0 and X will fit in a 64-bit int, ** handle the rounding directly, ** otherwise use printf. @@ -119676,38 +119676,38 @@ static void roundFunc(tdsqlite3_context *context, int argc, tdsqlite3_value **ar }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ - zBuf = tdsqlite3_mprintf("%.*f",n,r); + zBuf = sqlite3_mprintf("%.*f",n,r); if( zBuf==0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); return; } - tdsqlite3AtoF(zBuf, &r, tdsqlite3Strlen30(zBuf), SQLITE_UTF8); - tdsqlite3_free(zBuf); + sqlite3AtoF(zBuf, &r, sqlite3Strlen30(zBuf), SQLITE_UTF8); + sqlite3_free(zBuf); } - tdsqlite3_result_double(context, r); + sqlite3_result_double(context, r); } #endif /* -** Allocate nByte bytes of space using tdsqlite3Malloc(). If the -** allocation fails, call tdsqlite3_result_error_nomem() to notify +** Allocate nByte bytes of space using sqlite3Malloc(). If the +** allocation fails, call sqlite3_result_error_nomem() to notify ** the database handle that malloc() has failed and return NULL. ** If nByte is larger than the maximum string or blob length, then ** raise an SQLITE_TOOBIG exception and return NULL. */ -static void *contextMalloc(tdsqlite3_context *context, i64 nByte){ +static void *contextMalloc(sqlite3_context *context, i64 nByte){ char *z; - tdsqlite3 *db = tdsqlite3_context_db_handle(context); + sqlite3 *db = sqlite3_context_db_handle(context); assert( nByte>0 ); testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] ); testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH]+1 ); if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - tdsqlite3_result_error_toobig(context); + sqlite3_result_error_toobig(context); z = 0; }else{ - z = tdsqlite3Malloc(nByte); + z = sqlite3Malloc(nByte); if( !z ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); } } return z; @@ -119716,41 +119716,41 @@ static void *contextMalloc(tdsqlite3_context *context, i64 nByte){ /* ** Implementation of the upper() and lower() SQL functions. */ -static void upperFunc(tdsqlite3_context *context, int argc, tdsqlite3_value **argv){ +static void upperFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ char *z1; const char *z2; int i, n; UNUSED_PARAMETER(argc); - z2 = (char*)tdsqlite3_value_text(argv[0]); - n = tdsqlite3_value_bytes(argv[0]); + z2 = (char*)sqlite3_value_text(argv[0]); + n = sqlite3_value_bytes(argv[0]); /* Verify that the call to _bytes() does not invalidate the _text() pointer */ - assert( z2==(char*)tdsqlite3_value_text(argv[0]) ); + assert( z2==(char*)sqlite3_value_text(argv[0]) ); if( z2 ){ z1 = contextMalloc(context, ((i64)n)+1); if( z1 ){ for(i=0; imatchSet==0 ){ - c = tdsqlite3Utf8Read(&zPattern); + c = sqlite3Utf8Read(&zPattern); if( c==0 ) return SQLITE_NOWILDCARDMATCH; }else{ /* "[...]" immediately follows the "*". We have to do a slow @@ -119994,8 +119994,8 @@ static int patternCompare( char zStop[3]; int bMatch; if( noCase ){ - zStop[0] = tdsqlite3Toupper(c); - zStop[1] = tdsqlite3Tolower(c); + zStop[0] = sqlite3Toupper(c); + zStop[1] = sqlite3Tolower(c); zStop[2] = 0; }else{ zStop[0] = c; @@ -120020,27 +120020,27 @@ static int patternCompare( } if( c==matchOther ){ if( pInfo->matchSet==0 ){ - c = tdsqlite3Utf8Read(&zPattern); + c = sqlite3Utf8Read(&zPattern); if( c==0 ) return SQLITE_NOMATCH; zEscaped = zPattern; }else{ u32 prior_c = 0; int seen = 0; int invert = 0; - c = tdsqlite3Utf8Read(&zString); + c = sqlite3Utf8Read(&zString); if( c==0 ) return SQLITE_NOMATCH; - c2 = tdsqlite3Utf8Read(&zPattern); + c2 = sqlite3Utf8Read(&zPattern); if( c2=='^' ){ invert = 1; - c2 = tdsqlite3Utf8Read(&zPattern); + c2 = sqlite3Utf8Read(&zPattern); } if( c2==']' ){ if( c==']' ) seen = 1; - c2 = tdsqlite3Utf8Read(&zPattern); + c2 = sqlite3Utf8Read(&zPattern); } while( c2 && c2!=']' ){ if( c2=='-' && zPattern[0]!=']' && zPattern[0]!=0 && prior_c>0 ){ - c2 = tdsqlite3Utf8Read(&zPattern); + c2 = sqlite3Utf8Read(&zPattern); if( c>=prior_c && c<=c2 ) seen = 1; prior_c = 0; }else{ @@ -120049,7 +120049,7 @@ static int patternCompare( } prior_c = c2; } - c2 = tdsqlite3Utf8Read(&zPattern); + c2 = sqlite3Utf8Read(&zPattern); } if( c2==0 || (seen ^ invert)==0 ){ return SQLITE_NOMATCH; @@ -120059,7 +120059,7 @@ static int patternCompare( } c2 = Utf8Read(zString); if( c==c2 ) continue; - if( noCase && tdsqlite3Tolower(c)==tdsqlite3Tolower(c2) && c<0x80 && c2<0x80 ){ + if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) && c<0x80 && c2<0x80 ){ continue; } if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue; @@ -120069,18 +120069,18 @@ static int patternCompare( } /* -** The tdsqlite3_strglob() interface. Return 0 on a match (like strcmp()) and +** The sqlite3_strglob() interface. Return 0 on a match (like strcmp()) and ** non-zero if there is no match. */ -SQLITE_API int tdsqlite3_strglob(const char *zGlobPattern, const char *zString){ +SQLITE_API int sqlite3_strglob(const char *zGlobPattern, const char *zString){ return patternCompare((u8*)zGlobPattern, (u8*)zString, &globInfo, '['); } /* -** The tdsqlite3_strlike() interface. Return 0 on a match and non-zero for +** The sqlite3_strlike() interface. Return 0 on a match and non-zero for ** a miss - like strcmp(). */ -SQLITE_API int tdsqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ +SQLITE_API int sqlite3_strlike(const char *zPattern, const char *zStr, unsigned int esc){ return patternCompare((u8*)zPattern, (u8*)zStr, &likeInfoNorm, esc); } @@ -120090,7 +120090,7 @@ SQLITE_API int tdsqlite3_strlike(const char *zPattern, const char *zStr, unsigne ** only. */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_like_count = 0; +SQLITE_API int sqlite3_like_count = 0; #endif @@ -120107,24 +120107,24 @@ SQLITE_API int tdsqlite3_like_count = 0; ** the GLOB operator. */ static void likeFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ const unsigned char *zA, *zB; u32 escape; int nPat; - tdsqlite3 *db = tdsqlite3_context_db_handle(context); - struct compareInfo *pInfo = tdsqlite3_user_data(context); + sqlite3 *db = sqlite3_context_db_handle(context); + struct compareInfo *pInfo = sqlite3_user_data(context); #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS - if( tdsqlite3_value_type(argv[0])==SQLITE_BLOB - || tdsqlite3_value_type(argv[1])==SQLITE_BLOB + if( sqlite3_value_type(argv[0])==SQLITE_BLOB + || sqlite3_value_type(argv[1])==SQLITE_BLOB ){ #ifdef SQLITE_TEST - tdsqlite3_like_count++; + sqlite3_like_count++; #endif - tdsqlite3_result_int(context, 0); + sqlite3_result_int(context, 0); return; } #endif @@ -120132,35 +120132,35 @@ static void likeFunc( /* Limit the length of the LIKE or GLOB pattern to avoid problems ** of deep recursion and N*N behavior in patternCompare(). */ - nPat = tdsqlite3_value_bytes(argv[0]); + nPat = sqlite3_value_bytes(argv[0]); testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ); testcase( nPat==db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]+1 ); if( nPat > db->aLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH] ){ - tdsqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); return; } if( argc==3 ){ /* The escape character string must consist of a single UTF-8 character. ** Otherwise, return an error. */ - const unsigned char *zEsc = tdsqlite3_value_text(argv[2]); + const unsigned char *zEsc = sqlite3_value_text(argv[2]); if( zEsc==0 ) return; - if( tdsqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ - tdsqlite3_result_error(context, + if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ + sqlite3_result_error(context, "ESCAPE expression must be a single character", -1); return; } - escape = tdsqlite3Utf8Read(&zEsc); + escape = sqlite3Utf8Read(&zEsc); }else{ escape = pInfo->matchSet; } - zB = tdsqlite3_value_text(argv[0]); - zA = tdsqlite3_value_text(argv[1]); + zB = sqlite3_value_text(argv[0]); + zA = sqlite3_value_text(argv[1]); if( zA && zB ){ #ifdef SQLITE_TEST - tdsqlite3_like_count++; + sqlite3_like_count++; #endif - tdsqlite3_result_int(context, + sqlite3_result_int(context, patternCompare(zB, zA, pInfo, escape)==SQLITE_MATCH); } } @@ -120171,14 +120171,14 @@ static void likeFunc( ** arguments are equal to each other. */ static void nullifFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **argv + sqlite3_value **argv ){ - CollSeq *pColl = tdsqlite3GetFuncCollSeq(context); + CollSeq *pColl = sqlite3GetFuncCollSeq(context); UNUSED_PARAMETER(NotUsed); - if( tdsqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){ - tdsqlite3_result_value(context, argv[0]); + if( sqlite3MemCompare(argv[0], argv[1], pColl)!=0 ){ + sqlite3_result_value(context, argv[0]); } } @@ -120187,14 +120187,14 @@ static void nullifFunc( ** of the SQLite library that is running. */ static void versionFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **NotUsed2 + sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); /* IMP: R-48699-48617 This function is an SQL wrapper around the - ** tdsqlite3_libversion() C-interface. */ - tdsqlite3_result_text(context, tdsqlite3_libversion(), -1, SQLITE_STATIC); + ** sqlite3_libversion() C-interface. */ + sqlite3_result_text(context, sqlite3_libversion(), -1, SQLITE_STATIC); } /* @@ -120203,29 +120203,29 @@ static void versionFunc( ** SQLite. */ static void sourceidFunc( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **NotUsed2 + sqlite3_value **NotUsed2 ){ UNUSED_PARAMETER2(NotUsed, NotUsed2); /* IMP: R-24470-31136 This function is an SQL wrapper around the - ** tdsqlite3_sourceid() C interface. */ - tdsqlite3_result_text(context, tdsqlite3_sourceid(), -1, SQLITE_STATIC); + ** sqlite3_sourceid() C interface. */ + sqlite3_result_text(context, sqlite3_sourceid(), -1, SQLITE_STATIC); } /* ** Implementation of the sqlite_log() function. This is a wrapper around -** tdsqlite3_log(). The return value is NULL. The function exists purely for +** sqlite3_log(). The return value is NULL. The function exists purely for ** its side-effects. */ static void errlogFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ UNUSED_PARAMETER(argc); UNUSED_PARAMETER(context); - tdsqlite3_log(tdsqlite3_value_int(argv[0]), "%s", tdsqlite3_value_text(argv[1])); + sqlite3_log(sqlite3_value_int(argv[0]), "%s", sqlite3_value_text(argv[1])); } /* @@ -120235,19 +120235,19 @@ static void errlogFunc( */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS static void compileoptionusedFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ const char *zOptName; assert( argc==1 ); UNUSED_PARAMETER(argc); /* IMP: R-39564-36305 The sqlite_compileoption_used() SQL - ** function is a wrapper around the tdsqlite3_compileoption_used() C/C++ + ** function is a wrapper around the sqlite3_compileoption_used() C/C++ ** function. */ - if( (zOptName = (const char*)tdsqlite3_value_text(argv[0]))!=0 ){ - tdsqlite3_result_int(context, tdsqlite3_compileoption_used(zOptName)); + if( (zOptName = (const char*)sqlite3_value_text(argv[0]))!=0 ){ + sqlite3_result_int(context, sqlite3_compileoption_used(zOptName)); } } #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ @@ -120259,18 +120259,18 @@ static void compileoptionusedFunc( */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS static void compileoptiongetFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ int n; assert( argc==1 ); UNUSED_PARAMETER(argc); /* IMP: R-04922-24076 The sqlite_compileoption_get() SQL function - ** is a wrapper around the tdsqlite3_compileoption_get() C/C++ function. + ** is a wrapper around the sqlite3_compileoption_get() C/C++ function. */ - n = tdsqlite3_value_int(argv[0]); - tdsqlite3_result_text(context, tdsqlite3_compileoption_get(n), -1, SQLITE_STATIC); + n = sqlite3_value_int(argv[0]); + sqlite3_result_text(context, sqlite3_compileoption_get(n), -1, SQLITE_STATIC); } #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ @@ -120288,31 +120288,31 @@ static const char hexdigits[] = { ** "NULL". Otherwise, the argument is enclosed in single quotes with ** single-quote escapes. */ -static void quoteFunc(tdsqlite3_context *context, int argc, tdsqlite3_value **argv){ +static void quoteFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ assert( argc==1 ); UNUSED_PARAMETER(argc); - switch( tdsqlite3_value_type(argv[0]) ){ + switch( sqlite3_value_type(argv[0]) ){ case SQLITE_FLOAT: { double r1, r2; char zBuf[50]; - r1 = tdsqlite3_value_double(argv[0]); - tdsqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); - tdsqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8); + r1 = sqlite3_value_double(argv[0]); + sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1); + sqlite3AtoF(zBuf, &r2, 20, SQLITE_UTF8); if( r1!=r2 ){ - tdsqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1); + sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.20e", r1); } - tdsqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); break; } case SQLITE_INTEGER: { - tdsqlite3_result_value(context, argv[0]); + sqlite3_result_value(context, argv[0]); break; } case SQLITE_BLOB: { char *zText = 0; - char const *zBlob = tdsqlite3_value_blob(argv[0]); - int nBlob = tdsqlite3_value_bytes(argv[0]); - assert( zBlob==tdsqlite3_value_blob(argv[0]) ); /* No encoding change */ + char const *zBlob = sqlite3_value_blob(argv[0]); + int nBlob = sqlite3_value_bytes(argv[0]); + assert( zBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ zText = (char *)contextMalloc(context, (2*(i64)nBlob)+4); if( zText ){ int i; @@ -120324,15 +120324,15 @@ static void quoteFunc(tdsqlite3_context *context, int argc, tdsqlite3_value **ar zText[(nBlob*2)+3] = '\0'; zText[0] = 'X'; zText[1] = '\''; - tdsqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); - tdsqlite3_free(zText); + sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); + sqlite3_free(zText); } break; } case SQLITE_TEXT: { int i,j; u64 n; - const unsigned char *zArg = tdsqlite3_value_text(argv[0]); + const unsigned char *zArg = sqlite3_value_text(argv[0]); char *z; if( zArg==0 ) return; @@ -120348,13 +120348,13 @@ static void quoteFunc(tdsqlite3_context *context, int argc, tdsqlite3_value **ar } z[j++] = '\''; z[j] = 0; - tdsqlite3_result_text(context, z, j, tdsqlite3_free); + sqlite3_result_text(context, z, j, sqlite3_free); } break; } default: { - assert( tdsqlite3_value_type(argv[0])==SQLITE_NULL ); - tdsqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); + assert( sqlite3_value_type(argv[0])==SQLITE_NULL ); + sqlite3_result_text(context, "NULL", 4, SQLITE_STATIC); break; } } @@ -120365,13 +120365,13 @@ static void quoteFunc(tdsqlite3_context *context, int argc, tdsqlite3_value **ar ** for the first character of the input string. */ static void unicodeFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ - const unsigned char *z = tdsqlite3_value_text(argv[0]); + const unsigned char *z = sqlite3_value_text(argv[0]); (void)argc; - if( z && z[0] ) tdsqlite3_result_int(context, tdsqlite3Utf8Read(&z)); + if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z)); } /* @@ -120380,21 +120380,21 @@ static void unicodeFunc( ** is the unicode character for the corresponding integer argument. */ static void charFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ unsigned char *z, *zOut; int i; - zOut = z = tdsqlite3_malloc64( argc*4+1 ); + zOut = z = sqlite3_malloc64( argc*4+1 ); if( z==0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); return; } for(i=0; i0x10ffff ) x = 0xfffd; c = (unsigned)(x & 0x1fffff); if( c<0x00080 ){ @@ -120413,7 +120413,7 @@ static void charFunc( *zOut++ = 0x80 + (u8)(c & 0x3F); } \ } - tdsqlite3_result_text64(context, (char*)z, zOut-z, tdsqlite3_free, SQLITE_UTF8); + sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); } /* @@ -120421,18 +120421,18 @@ static void charFunc( ** a hexadecimal rendering as text. */ static void hexFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ int i, n; const unsigned char *pBlob; char *zHex, *z; assert( argc==1 ); UNUSED_PARAMETER(argc); - pBlob = tdsqlite3_value_blob(argv[0]); - n = tdsqlite3_value_bytes(argv[0]); - assert( pBlob==tdsqlite3_value_blob(argv[0]) ); /* No encoding change */ + pBlob = sqlite3_value_blob(argv[0]); + n = sqlite3_value_bytes(argv[0]); + assert( pBlob==sqlite3_value_blob(argv[0]) ); /* No encoding change */ z = zHex = contextMalloc(context, ((i64)n)*2 + 1); if( zHex ){ for(i=0; imallocFailed ); + assert( sqlite3_value_type(argv[1])==SQLITE_NULL + || sqlite3_context_db_handle(context)->mallocFailed ); return; } if( zPattern[0]==0 ){ - assert( tdsqlite3_value_type(argv[1])!=SQLITE_NULL ); - tdsqlite3_result_value(context, argv[0]); + assert( sqlite3_value_type(argv[1])!=SQLITE_NULL ); + sqlite3_result_value(context, argv[0]); return; } - nPattern = tdsqlite3_value_bytes(argv[1]); - assert( zPattern==tdsqlite3_value_text(argv[1]) ); /* No encoding change */ - zRep = tdsqlite3_value_text(argv[2]); + nPattern = sqlite3_value_bytes(argv[1]); + assert( zPattern==sqlite3_value_text(argv[1]) ); /* No encoding change */ + zRep = sqlite3_value_text(argv[2]); if( zRep==0 ) return; - nRep = tdsqlite3_value_bytes(argv[2]); - assert( zRep==tdsqlite3_value_text(argv[2]) ); + nRep = sqlite3_value_bytes(argv[2]); + assert( zRep==sqlite3_value_text(argv[2]) ); nOut = nStr + 1; assert( nOutaLimit[SQLITE_LIMIT_LENGTH] ); testcase( nOut-2==db->aLimit[SQLITE_LIMIT_LENGTH] ); if( nOut-1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - tdsqlite3_result_error_toobig(context); - tdsqlite3_free(zOut); + sqlite3_result_error_toobig(context); + sqlite3_free(zOut); return; } cntExpand++; @@ -120539,10 +120539,10 @@ static void replaceFunc( ** whose index is a power of two: 1, 2, 4, 8, 16, 32, ... */ u8 *zOld; zOld = zOut; - zOut = tdsqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1)); + zOut = sqlite3_realloc64(zOut, (int)nOut + (nOut - nStr - 1)); if( zOut==0 ){ - tdsqlite3_result_error_nomem(context); - tdsqlite3_free(zOld); + sqlite3_result_error_nomem(context); + sqlite3_free(zOld); return; } } @@ -120557,7 +120557,7 @@ static void replaceFunc( j += nStr - i; assert( j<=nOut ); zOut[j] = 0; - tdsqlite3_result_text(context, (char*)zOut, j, tdsqlite3_free); + sqlite3_result_text(context, (char*)zOut, j, sqlite3_free); } /* @@ -120565,9 +120565,9 @@ static void replaceFunc( ** The userdata is 0x1 for left trim, 0x2 for right trim, 0x3 for both. */ static void trimFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ const unsigned char *zIn; /* Input string */ const unsigned char *zCharSet; /* Set of characters to trim */ @@ -120578,13 +120578,13 @@ static void trimFunc( unsigned char **azChar = 0; /* Individual characters in zCharSet */ int nChar; /* Number of characters in zCharSet */ - if( tdsqlite3_value_type(argv[0])==SQLITE_NULL ){ + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ return; } - zIn = tdsqlite3_value_text(argv[0]); + zIn = sqlite3_value_text(argv[0]); if( zIn==0 ) return; - nIn = tdsqlite3_value_bytes(argv[0]); - assert( zIn==tdsqlite3_value_text(argv[0]) ); + nIn = sqlite3_value_bytes(argv[0]); + assert( zIn==sqlite3_value_text(argv[0]) ); if( argc==1 ){ static const unsigned char lenOne[] = { 1 }; static unsigned char * const azOne[] = { (u8*)" " }; @@ -120592,7 +120592,7 @@ static void trimFunc( aLen = (u8*)lenOne; azChar = (unsigned char **)azOne; zCharSet = 0; - }else if( (zCharSet = tdsqlite3_value_text(argv[1]))==0 ){ + }else if( (zCharSet = sqlite3_value_text(argv[1]))==0 ){ return; }else{ const unsigned char *z; @@ -120613,7 +120613,7 @@ static void trimFunc( } } if( nChar>0 ){ - flags = SQLITE_PTR_TO_INT(tdsqlite3_user_data(context)); + flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context)); if( flags & 1 ){ while( nIn>0 ){ int len = 0; @@ -120638,10 +120638,10 @@ static void trimFunc( } } if( zCharSet ){ - tdsqlite3_free(azChar); + sqlite3_free(azChar); } } - tdsqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); + sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); } @@ -120650,15 +120650,15 @@ static void trimFunc( ** The "unknown" function is automatically substituted in place of ** any unrecognized function name when doing an EXPLAIN or EXPLAIN QUERY PLAN ** when the SQLITE_ENABLE_UNKNOWN_FUNCTION compile-time option is used. -** When the "tdsqlite3" command-line shell is built using this functionality, +** When the "sqlite3" command-line shell is built using this functionality, ** that allows an EXPLAIN or EXPLAIN QUERY PLAN for complex queries ** involving application-defined functions to be examined in a generic -** tdsqlite3 shell. +** sqlite3 shell. */ static void unknownFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ /* no-op */ } @@ -120677,9 +120677,9 @@ static void unknownFunc( ** soundex encoding of the string X. */ static void soundexFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ char zResult[8]; const u8 *zIn; @@ -120695,12 +120695,12 @@ static void soundexFunc( 1, 2, 6, 2, 3, 0, 1, 0, 2, 0, 2, 0, 0, 0, 0, 0, }; assert( argc==1 ); - zIn = (u8*)tdsqlite3_value_text(argv[0]); + zIn = (u8*)sqlite3_value_text(argv[0]); if( zIn==0 ) zIn = (u8*)""; - for(i=0; zIn[i] && !tdsqlite3Isalpha(zIn[i]); i++){} + for(i=0; zIn[i] && !sqlite3Isalpha(zIn[i]); i++){} if( zIn[i] ){ u8 prevcode = iCode[zIn[i]&0x7f]; - zResult[0] = tdsqlite3Toupper(zIn[i]); + zResult[0] = sqlite3Toupper(zIn[i]); for(j=1; j<4 && zIn[i]; i++){ int code = iCode[zIn[i]&0x7f]; if( code>0 ){ @@ -120716,11 +120716,11 @@ static void soundexFunc( zResult[j++] = '0'; } zResult[j] = 0; - tdsqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT); + sqlite3_result_text(context, zResult, 4, SQLITE_TRANSIENT); }else{ /* IMP: R-64894-50321 The string "?000" is returned if the argument ** is NULL or contains no ASCII alphabetic characters. */ - tdsqlite3_result_text(context, "?000", 4, SQLITE_STATIC); + sqlite3_result_text(context, "?000", 4, SQLITE_STATIC); } } #endif /* SQLITE_SOUNDEX */ @@ -120729,28 +120729,28 @@ static void soundexFunc( /* ** A function that loads a shared-library extension then returns NULL. */ -static void loadExt(tdsqlite3_context *context, int argc, tdsqlite3_value **argv){ - const char *zFile = (const char *)tdsqlite3_value_text(argv[0]); +static void loadExt(sqlite3_context *context, int argc, sqlite3_value **argv){ + const char *zFile = (const char *)sqlite3_value_text(argv[0]); const char *zProc; - tdsqlite3 *db = tdsqlite3_context_db_handle(context); + sqlite3 *db = sqlite3_context_db_handle(context); char *zErrMsg = 0; /* Disallow the load_extension() SQL function unless the SQLITE_LoadExtFunc - ** flag is set. See the tdsqlite3_enable_load_extension() API. + ** flag is set. See the sqlite3_enable_load_extension() API. */ if( (db->flags & SQLITE_LoadExtFunc)==0 ){ - tdsqlite3_result_error(context, "not authorized", -1); + sqlite3_result_error(context, "not authorized", -1); return; } if( argc==2 ){ - zProc = (const char *)tdsqlite3_value_text(argv[1]); + zProc = (const char *)sqlite3_value_text(argv[1]); }else{ zProc = 0; } - if( zFile && tdsqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ - tdsqlite3_result_error(context, zErrMsg, -1); - tdsqlite3_free(zErrMsg); + if( zFile && sqlite3_load_extension(db, zFile, zProc, &zErrMsg) ){ + sqlite3_result_error(context, zErrMsg, -1); + sqlite3_free(zErrMsg); } } #endif @@ -120779,35 +120779,35 @@ struct SumCtx { ** value. TOTAL never fails, but SUM might through an exception if ** it overflows an integer. */ -static void sumStep(tdsqlite3_context *context, int argc, tdsqlite3_value **argv){ +static void sumStep(sqlite3_context *context, int argc, sqlite3_value **argv){ SumCtx *p; int type; assert( argc==1 ); UNUSED_PARAMETER(argc); - p = tdsqlite3_aggregate_context(context, sizeof(*p)); - type = tdsqlite3_value_numeric_type(argv[0]); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); if( p && type!=SQLITE_NULL ){ p->cnt++; if( type==SQLITE_INTEGER ){ - i64 v = tdsqlite3_value_int64(argv[0]); + i64 v = sqlite3_value_int64(argv[0]); p->rSum += v; - if( (p->approx|p->overflow)==0 && tdsqlite3AddInt64(&p->iSum, v) ){ + if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ p->approx = p->overflow = 1; } }else{ - p->rSum += tdsqlite3_value_double(argv[0]); + p->rSum += sqlite3_value_double(argv[0]); p->approx = 1; } } } #ifndef SQLITE_OMIT_WINDOWFUNC -static void sumInverse(tdsqlite3_context *context, int argc, tdsqlite3_value**argv){ +static void sumInverse(sqlite3_context *context, int argc, sqlite3_value**argv){ SumCtx *p; int type; assert( argc==1 ); UNUSED_PARAMETER(argc); - p = tdsqlite3_aggregate_context(context, sizeof(*p)); - type = tdsqlite3_value_numeric_type(argv[0]); + p = sqlite3_aggregate_context(context, sizeof(*p)); + type = sqlite3_value_numeric_type(argv[0]); /* p is always non-NULL because sumStep() will have been called first ** to initialize it */ if( ALWAYS(p) && type!=SQLITE_NULL ){ @@ -120815,42 +120815,42 @@ static void sumInverse(tdsqlite3_context *context, int argc, tdsqlite3_value**ar p->cnt--; assert( type==SQLITE_INTEGER || p->approx ); if( type==SQLITE_INTEGER && p->approx==0 ){ - i64 v = tdsqlite3_value_int64(argv[0]); + i64 v = sqlite3_value_int64(argv[0]); p->rSum -= v; p->iSum -= v; }else{ - p->rSum -= tdsqlite3_value_double(argv[0]); + p->rSum -= sqlite3_value_double(argv[0]); } } } #else # define sumInverse 0 #endif /* SQLITE_OMIT_WINDOWFUNC */ -static void sumFinalize(tdsqlite3_context *context){ +static void sumFinalize(sqlite3_context *context){ SumCtx *p; - p = tdsqlite3_aggregate_context(context, 0); + p = sqlite3_aggregate_context(context, 0); if( p && p->cnt>0 ){ if( p->overflow ){ - tdsqlite3_result_error(context,"integer overflow",-1); + sqlite3_result_error(context,"integer overflow",-1); }else if( p->approx ){ - tdsqlite3_result_double(context, p->rSum); + sqlite3_result_double(context, p->rSum); }else{ - tdsqlite3_result_int64(context, p->iSum); + sqlite3_result_int64(context, p->iSum); } } } -static void avgFinalize(tdsqlite3_context *context){ +static void avgFinalize(sqlite3_context *context){ SumCtx *p; - p = tdsqlite3_aggregate_context(context, 0); + p = sqlite3_aggregate_context(context, 0); if( p && p->cnt>0 ){ - tdsqlite3_result_double(context, p->rSum/(double)p->cnt); + sqlite3_result_double(context, p->rSum/(double)p->cnt); } } -static void totalFinalize(tdsqlite3_context *context){ +static void totalFinalize(sqlite3_context *context){ SumCtx *p; - p = tdsqlite3_aggregate_context(context, 0); + p = sqlite3_aggregate_context(context, 0); /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - tdsqlite3_result_double(context, p ? p->rSum : (double)0); + sqlite3_result_double(context, p ? p->rSum : (double)0); } /* @@ -120868,33 +120868,33 @@ struct CountCtx { /* ** Routines to implement the count() aggregate function. */ -static void countStep(tdsqlite3_context *context, int argc, tdsqlite3_value **argv){ +static void countStep(sqlite3_context *context, int argc, sqlite3_value **argv){ CountCtx *p; - p = tdsqlite3_aggregate_context(context, sizeof(*p)); - if( (argc==0 || SQLITE_NULL!=tdsqlite3_value_type(argv[0])) && p ){ + p = sqlite3_aggregate_context(context, sizeof(*p)); + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && p ){ p->n++; } #ifndef SQLITE_OMIT_DEPRECATED - /* The tdsqlite3_aggregate_count() function is deprecated. But just to make + /* The sqlite3_aggregate_count() function is deprecated. But just to make ** sure it still operates correctly, verify that its count agrees with our ** internal count when using count(*) and when the total count can be ** expressed as a 32-bit integer. */ assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse - || p->n==tdsqlite3_aggregate_count(context) ); + || p->n==sqlite3_aggregate_count(context) ); #endif } -static void countFinalize(tdsqlite3_context *context){ +static void countFinalize(sqlite3_context *context){ CountCtx *p; - p = tdsqlite3_aggregate_context(context, 0); - tdsqlite3_result_int64(context, p ? p->n : 0); + p = sqlite3_aggregate_context(context, 0); + sqlite3_result_int64(context, p ? p->n : 0); } #ifndef SQLITE_OMIT_WINDOWFUNC -static void countInverse(tdsqlite3_context *ctx, int argc, tdsqlite3_value **argv){ +static void countInverse(sqlite3_context *ctx, int argc, sqlite3_value **argv){ CountCtx *p; - p = tdsqlite3_aggregate_context(ctx, sizeof(*p)); + p = sqlite3_aggregate_context(ctx, sizeof(*p)); /* p is always non-NULL since countStep() will have been called first */ - if( (argc==0 || SQLITE_NULL!=tdsqlite3_value_type(argv[0])) && ALWAYS(p) ){ + if( (argc==0 || SQLITE_NULL!=sqlite3_value_type(argv[0])) && ALWAYS(p) ){ p->n--; #ifdef SQLITE_DEBUG p->bInverse = 1; @@ -120909,61 +120909,61 @@ static void countInverse(tdsqlite3_context *ctx, int argc, tdsqlite3_value **arg ** Routines to implement min() and max() aggregate functions. */ static void minmaxStep( - tdsqlite3_context *context, + sqlite3_context *context, int NotUsed, - tdsqlite3_value **argv + sqlite3_value **argv ){ Mem *pArg = (Mem *)argv[0]; Mem *pBest; UNUSED_PARAMETER(NotUsed); - pBest = (Mem *)tdsqlite3_aggregate_context(context, sizeof(*pBest)); + pBest = (Mem *)sqlite3_aggregate_context(context, sizeof(*pBest)); if( !pBest ) return; - if( tdsqlite3_value_type(pArg)==SQLITE_NULL ){ - if( pBest->flags ) tdsqlite3SkipAccumulatorLoad(context); + if( sqlite3_value_type(pArg)==SQLITE_NULL ){ + if( pBest->flags ) sqlite3SkipAccumulatorLoad(context); }else if( pBest->flags ){ int max; int cmp; - CollSeq *pColl = tdsqlite3GetFuncCollSeq(context); + CollSeq *pColl = sqlite3GetFuncCollSeq(context); /* This step function is used for both the min() and max() aggregates, ** the only difference between the two being that the sense of the ** comparison is inverted. For the max() aggregate, the - ** tdsqlite3_user_data() function returns (void *)-1. For min() it - ** returns (void *)db, where db is the tdsqlite3* database pointer. + ** sqlite3_user_data() function returns (void *)-1. For min() it + ** returns (void *)db, where db is the sqlite3* database pointer. ** Therefore the next statement sets variable 'max' to 1 for the max() ** aggregate, or 0 for min(). */ - max = tdsqlite3_user_data(context)!=0; - cmp = tdsqlite3MemCompare(pBest, pArg, pColl); + max = sqlite3_user_data(context)!=0; + cmp = sqlite3MemCompare(pBest, pArg, pColl); if( (max && cmp<0) || (!max && cmp>0) ){ - tdsqlite3VdbeMemCopy(pBest, pArg); + sqlite3VdbeMemCopy(pBest, pArg); }else{ - tdsqlite3SkipAccumulatorLoad(context); + sqlite3SkipAccumulatorLoad(context); } }else{ - pBest->db = tdsqlite3_context_db_handle(context); - tdsqlite3VdbeMemCopy(pBest, pArg); + pBest->db = sqlite3_context_db_handle(context); + sqlite3VdbeMemCopy(pBest, pArg); } } -static void minMaxValueFinalize(tdsqlite3_context *context, int bValue){ - tdsqlite3_value *pRes; - pRes = (tdsqlite3_value *)tdsqlite3_aggregate_context(context, 0); +static void minMaxValueFinalize(sqlite3_context *context, int bValue){ + sqlite3_value *pRes; + pRes = (sqlite3_value *)sqlite3_aggregate_context(context, 0); if( pRes ){ if( pRes->flags ){ - tdsqlite3_result_value(context, pRes); + sqlite3_result_value(context, pRes); } - if( bValue==0 ) tdsqlite3VdbeMemRelease(pRes); + if( bValue==0 ) sqlite3VdbeMemRelease(pRes); } } #ifndef SQLITE_OMIT_WINDOWFUNC -static void minMaxValue(tdsqlite3_context *context){ +static void minMaxValue(sqlite3_context *context){ minMaxValueFinalize(context, 1); } #else # define minMaxValue 0 #endif /* SQLITE_OMIT_WINDOWFUNC */ -static void minMaxFinalize(tdsqlite3_context *context){ +static void minMaxFinalize(sqlite3_context *context){ minMaxValueFinalize(context, 0); } @@ -120971,54 +120971,54 @@ static void minMaxFinalize(tdsqlite3_context *context){ ** group_concat(EXPR, ?SEPARATOR?) */ static void groupConcatStep( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ const char *zVal; StrAccum *pAccum; const char *zSep; int nVal, nSep; assert( argc==1 || argc==2 ); - if( tdsqlite3_value_type(argv[0])==SQLITE_NULL ) return; - pAccum = (StrAccum*)tdsqlite3_aggregate_context(context, sizeof(*pAccum)); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); if( pAccum ){ - tdsqlite3 *db = tdsqlite3_context_db_handle(context); + sqlite3 *db = sqlite3_context_db_handle(context); int firstTerm = pAccum->mxAlloc==0; pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; if( !firstTerm ){ if( argc==2 ){ - zSep = (char*)tdsqlite3_value_text(argv[1]); - nSep = tdsqlite3_value_bytes(argv[1]); + zSep = (char*)sqlite3_value_text(argv[1]); + nSep = sqlite3_value_bytes(argv[1]); }else{ zSep = ","; nSep = 1; } - if( zSep ) tdsqlite3_str_append(pAccum, zSep, nSep); + if( zSep ) sqlite3_str_append(pAccum, zSep, nSep); } - zVal = (char*)tdsqlite3_value_text(argv[0]); - nVal = tdsqlite3_value_bytes(argv[0]); - if( zVal ) tdsqlite3_str_append(pAccum, zVal, nVal); + zVal = (char*)sqlite3_value_text(argv[0]); + nVal = sqlite3_value_bytes(argv[0]); + if( zVal ) sqlite3_str_append(pAccum, zVal, nVal); } } #ifndef SQLITE_OMIT_WINDOWFUNC static void groupConcatInverse( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ int n; StrAccum *pAccum; assert( argc==1 || argc==2 ); - if( tdsqlite3_value_type(argv[0])==SQLITE_NULL ) return; - pAccum = (StrAccum*)tdsqlite3_aggregate_context(context, sizeof(*pAccum)); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; + pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum)); /* pAccum is always non-NULL since groupConcatStep() will have always ** run frist to initialize it */ if( ALWAYS(pAccum) ){ - n = tdsqlite3_value_bytes(argv[0]); + n = sqlite3_value_bytes(argv[0]); if( argc==2 ){ - n += tdsqlite3_value_bytes(argv[1]); + n += sqlite3_value_bytes(argv[1]); }else{ n++; } @@ -121034,32 +121034,32 @@ static void groupConcatInverse( #else # define groupConcatInverse 0 #endif /* SQLITE_OMIT_WINDOWFUNC */ -static void groupConcatFinalize(tdsqlite3_context *context){ +static void groupConcatFinalize(sqlite3_context *context){ StrAccum *pAccum; - pAccum = tdsqlite3_aggregate_context(context, 0); + pAccum = sqlite3_aggregate_context(context, 0); if( pAccum ){ if( pAccum->accError==SQLITE_TOOBIG ){ - tdsqlite3_result_error_toobig(context); + sqlite3_result_error_toobig(context); }else if( pAccum->accError==SQLITE_NOMEM ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); }else{ - tdsqlite3_result_text(context, tdsqlite3StrAccumFinish(pAccum), -1, - tdsqlite3_free); + sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, + sqlite3_free); } } } #ifndef SQLITE_OMIT_WINDOWFUNC -static void groupConcatValue(tdsqlite3_context *context){ - tdsqlite3_str *pAccum; - pAccum = (tdsqlite3_str*)tdsqlite3_aggregate_context(context, 0); +static void groupConcatValue(sqlite3_context *context){ + sqlite3_str *pAccum; + pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0); if( pAccum ){ if( pAccum->accError==SQLITE_TOOBIG ){ - tdsqlite3_result_error_toobig(context); + sqlite3_result_error_toobig(context); }else if( pAccum->accError==SQLITE_NOMEM ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); }else{ - const char *zText = tdsqlite3_str_value(pAccum); - tdsqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); + const char *zText = sqlite3_str_value(pAccum); + sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT); } } } @@ -121072,17 +121072,17 @@ static void groupConcatValue(tdsqlite3_context *context){ ** of the built-in functions above are part of the global function set. ** This routine only deals with those that are not global. */ -SQLITE_PRIVATE void tdsqlite3RegisterPerConnectionBuiltinFunctions(tdsqlite3 *db){ - int rc = tdsqlite3_overload_function(db, "MATCH", 2); +SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3 *db){ + int rc = sqlite3_overload_function(db, "MATCH", 2); assert( rc==SQLITE_NOMEM || rc==SQLITE_OK ); if( rc==SQLITE_NOMEM ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); } /* BEGIN SQLCIPHER */ #ifdef SQLITE_HAS_CODEC #ifndef OMIT_EXPORT { - tdsqlite3CreateFunc(db, "sqlcipher_export", -1, SQLITE_TEXT, 0, sqlcipher_exportFunc, 0, 0, 0, 0, 0); + sqlite3CreateFunc(db, "sqlcipher_export", -1, SQLITE_TEXT, 0, sqlcipher_exportFunc, 0, 0, 0, 0, 0); } #endif #ifdef SQLCIPHER_EXT @@ -121097,7 +121097,7 @@ SQLITE_PRIVATE void tdsqlite3RegisterPerConnectionBuiltinFunctions(tdsqlite3 *db ** parameter determines whether or not the LIKE operator is case ** sensitive. */ -SQLITE_PRIVATE void tdsqlite3RegisterLikeFunctions(tdsqlite3 *db, int caseSensitive){ +SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ struct compareInfo *pInfo; int flags; if( caseSensitive ){ @@ -121107,10 +121107,10 @@ SQLITE_PRIVATE void tdsqlite3RegisterLikeFunctions(tdsqlite3 *db, int caseSensit pInfo = (struct compareInfo*)&likeInfoNorm; flags = SQLITE_FUNC_LIKE; } - tdsqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); - tdsqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); - tdsqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags; - tdsqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags; + sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); + sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); + sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags; + sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags; } /* @@ -121130,7 +121130,7 @@ SQLITE_PRIVATE void tdsqlite3RegisterLikeFunctions(tdsqlite3 *db, int caseSensit ** between uppercase and lowercase (as does GLOB) then *pIsNocase is set to ** false. */ -SQLITE_PRIVATE int tdsqlite3IsLikeFunction(tdsqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ +SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3 *db, Expr *pExpr, int *pIsNocase, char *aWc){ FuncDef *pDef; int nExpr; if( pExpr->op!=TK_FUNCTION || !pExpr->x.pList ){ @@ -121138,7 +121138,7 @@ SQLITE_PRIVATE int tdsqlite3IsLikeFunction(tdsqlite3 *db, Expr *pExpr, int *pIsN } assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); nExpr = pExpr->x.pList->nExpr; - pDef = tdsqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0); + pDef = sqlite3FindFunction(db, pExpr->u.zToken, nExpr, SQLITE_UTF8, 0); if( NEVER(pDef==0) || (pDef->funcFlags & SQLITE_FUNC_LIKE)==0 ){ return 0; } @@ -121168,11 +121168,11 @@ SQLITE_PRIVATE int tdsqlite3IsLikeFunction(tdsqlite3 *db, Expr *pExpr, int *pIsN /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as -** a consequence of calling tdsqlite3_initialize()). +** a consequence of calling sqlite3_initialize()). ** ** After this routine runs */ -SQLITE_PRIVATE void tdsqlite3RegisterBuiltinFunctions(void){ +SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void){ /* ** The following array holds FuncDef structures for all of the functions ** defined in this file. @@ -121200,7 +121200,7 @@ SQLITE_PRIVATE void tdsqlite3RegisterBuiltinFunctions(void){ SFUNCTION(load_extension, 2, 0, 0, loadExt ), #endif #if SQLITE_USER_AUTHENTICATION - FUNCTION(sqlite_crypt, 2, 0, 0, tdsqlite3CryptFunc ), + FUNCTION(sqlite_crypt, 2, 0, 0, sqlite3CryptFunc ), #endif #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS DFUNCTION(sqlite_compileoption_used,1, 0, 0, compileoptionusedFunc ), @@ -121284,11 +121284,11 @@ SQLITE_PRIVATE void tdsqlite3RegisterBuiltinFunctions(void){ INLINE_FUNC(coalesce, -1, INLINEFUNC_coalesce, SQLITE_FUNC_COALESCE), }; #ifndef SQLITE_OMIT_ALTERTABLE - tdsqlite3AlterFunctions(); + sqlite3AlterFunctions(); #endif - tdsqlite3WindowFunctions(); - tdsqlite3RegisterDateTimeFunctions(); - tdsqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc)); + sqlite3WindowFunctions(); + sqlite3RegisterDateTimeFunctions(); + sqlite3InsertBuiltinFuncs(aBuiltinFunc, ArraySize(aBuiltinFunc)); #if 0 /* Enable to print out how the built-in functions are hashed */ { @@ -121296,8 +121296,8 @@ SQLITE_PRIVATE void tdsqlite3RegisterBuiltinFunctions(void){ FuncDef *p; for(i=0; iu.pHash){ - int n = tdsqlite3Strlen30(p->zName); + for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash){ + int n = sqlite3Strlen30(p->zName); int h = p->zName[0] + n; printf(" %s(%d)", p->zName, h); } @@ -121422,16 +121422,16 @@ SQLITE_PRIVATE void tdsqlite3RegisterBuiltinFunctions(void){ ** coding an INSERT operation. The functions used by the UPDATE/DELETE ** generation code to query for this information are: ** -** tdsqlite3FkRequired() - Test to see if FK processing is required. -** tdsqlite3FkOldmask() - Query for the set of required old.* columns. +** sqlite3FkRequired() - Test to see if FK processing is required. +** sqlite3FkOldmask() - Query for the set of required old.* columns. ** ** ** Externally accessible module functions ** -------------------------------------- ** -** tdsqlite3FkCheck() - Check for foreign key violations. -** tdsqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions. -** tdsqlite3FkDelete() - Delete an FKey structure. +** sqlite3FkCheck() - Check for foreign key violations. +** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions. +** sqlite3FkDelete() - Delete an FKey structure. */ /* @@ -121491,7 +121491,7 @@ SQLITE_PRIVATE void tdsqlite3RegisterBuiltinFunctions(void){ ** into pParse. If an OOM error occurs, non-zero is returned and the ** pParse->db->mallocFailed flag is set. */ -SQLITE_PRIVATE int tdsqlite3FkLocateIndex( +SQLITE_PRIVATE int sqlite3FkLocateIndex( Parse *pParse, /* Parse context to store any error in */ Table *pParent, /* Parent table of FK constraint pFKey */ FKey *pFKey, /* Foreign key to find index for */ @@ -121526,11 +121526,11 @@ SQLITE_PRIVATE int tdsqlite3FkLocateIndex( */ if( pParent->iPKey>=0 ){ if( !zKey ) return 0; - if( !tdsqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; + if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; } }else if( paiCol ){ assert( nCol>1 ); - aiCol = (int *)tdsqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); + aiCol = (int *)sqlite3DbMallocRawNN(pParse->db, nCol*sizeof(int)); if( !aiCol ) return 1; *paiCol = aiCol; } @@ -121569,12 +121569,12 @@ SQLITE_PRIVATE int tdsqlite3FkLocateIndex( ** the default collation sequence for the column, this index is ** unusable. Bail out early in this case. */ zDfltColl = pParent->aCol[iCol].zColl; - if( !zDfltColl ) zDfltColl = tdsqlite3StrBINARY; - if( tdsqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; + if( !zDfltColl ) zDfltColl = sqlite3StrBINARY; + if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; zIdxCol = pParent->aCol[iCol].zName; for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ + if( sqlite3StrICmp(pFKey->aCol[j].zCol, zIdxCol)==0 ){ if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; break; } @@ -121588,11 +121588,11 @@ SQLITE_PRIVATE int tdsqlite3FkLocateIndex( if( !pIdx ){ if( !pParse->disableTriggers ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "foreign key mismatch - \"%w\" referencing \"%w\"", pFKey->pFrom->zName, pFKey->zTo); } - tdsqlite3DbFree(pParse->db, aiCol); + sqlite3DbFree(pParse->db, aiCol); return 1; } @@ -121638,11 +121638,11 @@ static void fkLookupParent( int isIgnore /* If true, pretend pTab contains all NULL values */ ){ int i; /* Iterator variable */ - Vdbe *v = tdsqlite3GetVdbe(pParse); /* Vdbe to add code to */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */ int iCur = pParse->nTab - 1; /* Cursor number to use */ - int iOk = tdsqlite3VdbeMakeLabel(pParse); /* jump here if parent key found */ + int iOk = sqlite3VdbeMakeLabel(pParse); /* jump here if parent key found */ - tdsqlite3VdbeVerifyAbortable(v, + sqlite3VdbeVerifyAbortable(v, (!pFKey->isDeferred && !(pParse->db->flags & SQLITE_DeferFKs) && !pParse->pToplevel @@ -121656,12 +121656,12 @@ static void fkLookupParent( ** any are, then the constraint is considered satisfied. No need to ** search for a matching row in the parent table. */ if( nIncr<0 ){ - tdsqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); + sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); VdbeCoverage(v); } for(i=0; inCol; i++){ - int iReg = tdsqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) + regData + 1; - tdsqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v); + int iReg = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) + regData + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); VdbeCoverage(v); } if( isIgnore==0 ){ @@ -121669,16 +121669,16 @@ static void fkLookupParent( /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY ** column of the parent table (table pTab). */ int iMustBeInt; /* Address of MustBeInt instruction */ - int regTemp = tdsqlite3GetTempReg(pParse); + int regTemp = sqlite3GetTempReg(pParse); /* Invoke MustBeInt to coerce the child key value to an integer (i.e. ** apply the affinity of the parent key). If this fails, then there ** is no matching parent key. Before using MustBeInt, make a copy of ** the value. Otherwise, the value inserted into the child key column ** will have INTEGER affinity applied to it, which may not be correct. */ - tdsqlite3VdbeAddOp2(v, OP_SCopy, - tdsqlite3TableColumnToStorage(pFKey->pFrom,aiCol[0])+1+regData, regTemp); - iMustBeInt = tdsqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); + sqlite3VdbeAddOp2(v, OP_SCopy, + sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[0])+1+regData, regTemp); + iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); VdbeCoverage(v); /* If the parent table is the same as the child table, and we are about @@ -121686,26 +121686,26 @@ static void fkLookupParent( ** then check if the row being inserted matches itself. If so, do not ** increment the constraint-counter. */ if( pTab==pFKey->pFrom && nIncr==1 ){ - tdsqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); - tdsqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); } - tdsqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); - tdsqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v); - tdsqlite3VdbeGoto(v, iOk); - tdsqlite3VdbeJumpHere(v, tdsqlite3VdbeCurrentAddr(v)-2); - tdsqlite3VdbeJumpHere(v, iMustBeInt); - tdsqlite3ReleaseTempReg(pParse, regTemp); + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); VdbeCoverage(v); + sqlite3VdbeGoto(v, iOk); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeJumpHere(v, iMustBeInt); + sqlite3ReleaseTempReg(pParse, regTemp); }else{ int nCol = pFKey->nCol; - int regTemp = tdsqlite3GetTempRange(pParse, nCol); - int regRec = tdsqlite3GetTempReg(pParse); + int regTemp = sqlite3GetTempRange(pParse, nCol); + int regRec = sqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); - tdsqlite3VdbeSetP4KeyInfo(pParse, pIdx); + sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); for(i=0; ipFrom, aiCol[i])+1+regData, + sqlite3VdbeAddOp2(v, OP_Copy, + sqlite3TableColumnToStorage(pFKey->pFrom, aiCol[i])+1+regData, regTemp+i); } @@ -121720,12 +121720,12 @@ static void fkLookupParent( ** none of the child key values are). */ if( pTab==pFKey->pFrom && nIncr==1 ){ - int iJump = tdsqlite3VdbeCurrentAddr(v) + nCol + 1; + int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; for(i=0; ipFrom,aiCol[i]) + int iChild = sqlite3TableColumnToStorage(pFKey->pFrom,aiCol[i]) +1+regData; int iParent = 1+regData; - iParent += tdsqlite3TableColumnToStorage(pIdx->pTable, + iParent += sqlite3TableColumnToStorage(pIdx->pTable, pIdx->aiColumn[i]); assert( pIdx->aiColumn[i]>=0 ); assert( aiCol[i]!=pTab->iPKey ); @@ -121733,18 +121733,18 @@ static void fkLookupParent( /* The parent key is a composite key that includes the IPK column */ iParent = regData; } - tdsqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v); - tdsqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); + sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); } - tdsqlite3VdbeGoto(v, iOk); + sqlite3VdbeGoto(v, iOk); } - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec, - tdsqlite3IndexAffinityStr(pParse->db,pIdx), nCol); - tdsqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTemp, nCol, regRec, + sqlite3IndexAffinityStr(pParse->db,pIdx), nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, iCur, iOk, regRec, 0); VdbeCoverage(v); - tdsqlite3ReleaseTempReg(pParse, regRec); - tdsqlite3ReleaseTempRange(pParse, regTemp, nCol); + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempRange(pParse, regTemp, nCol); } } @@ -121757,17 +121757,17 @@ static void fkLookupParent( ** incrementing a counter. This is necessary as the VM code is being ** generated for will not open a statement transaction. */ assert( nIncr==1 ); - tdsqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, OE_Abort, 0, P4_STATIC, P5_ConstraintFK); }else{ if( nIncr>0 && pFKey->isDeferred==0 ){ - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); } - tdsqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); } - tdsqlite3VdbeResolveLabel(v, iOk); - tdsqlite3VdbeAddOp1(v, OP_Close, iCur); + sqlite3VdbeResolveLabel(v, iOk); + sqlite3VdbeAddOp1(v, OP_Close, iCur); } @@ -121788,17 +121788,17 @@ static Expr *exprTableRegister( Expr *pExpr; Column *pCol; const char *zColl; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; - pExpr = tdsqlite3Expr(db, TK_REGISTER, 0); + pExpr = sqlite3Expr(db, TK_REGISTER, 0); if( pExpr ){ if( iCol>=0 && iCol!=pTab->iPKey ){ pCol = &pTab->aCol[iCol]; - pExpr->iTable = regBase + tdsqlite3TableColumnToStorage(pTab,iCol) + 1; + pExpr->iTable = regBase + sqlite3TableColumnToStorage(pTab,iCol) + 1; pExpr->affExpr = pCol->affinity; zColl = pCol->zColl; if( zColl==0 ) zColl = db->pDfltColl->zName; - pExpr = tdsqlite3ExprAddCollateString(pParse, pExpr, zColl); + pExpr = sqlite3ExprAddCollateString(pParse, pExpr, zColl); }else{ pExpr->iTable = regBase; pExpr->affExpr = SQLITE_AFF_INTEGER; @@ -121812,12 +121812,12 @@ static Expr *exprTableRegister( ** has cursor iCur. */ static Expr *exprTableColumn( - tdsqlite3 *db, /* The database connection */ + sqlite3 *db, /* The database connection */ Table *pTab, /* The table whose column is desired */ int iCursor, /* The open cursor on the table */ i16 iCol /* The column that is wanted */ ){ - Expr *pExpr = tdsqlite3Expr(db, TK_COLUMN, 0); + Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); if( pExpr ){ pExpr->y.pTab = pTab; pExpr->iTable = iCursor; @@ -121868,13 +121868,13 @@ static void fkScanChildren( int regData, /* Parent row data starts here */ int nIncr /* Amount to increment deferred counter by */ ){ - tdsqlite3 *db = pParse->db; /* Database handle */ + sqlite3 *db = pParse->db; /* Database handle */ int i; /* Iterator variable */ Expr *pWhere = 0; /* WHERE clause to scan with */ NameContext sNameContext; /* Context used to resolve WHERE clause */ - WhereInfo *pWInfo; /* Context used by tdsqlite3WhereXXX() */ + WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */ int iFkIfZero = 0; /* Address of OP_FkIfZero */ - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); assert( pIdx==0 || pIdx->pTable==pTab ); assert( pIdx==0 || pIdx->nKeyCol==pFKey->nCol ); @@ -121882,7 +121882,7 @@ static void fkScanChildren( assert( pIdx!=0 || HasRowid(pTab) ); if( nIncr<0 ){ - iFkIfZero = tdsqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); + iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); VdbeCoverage(v); } @@ -121906,9 +121906,9 @@ static void fkScanChildren( iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; assert( iCol>=0 ); zCol = pFKey->pFrom->aCol[iCol].zName; - pRight = tdsqlite3Expr(db, TK_ID, zCol); - pEq = tdsqlite3PExpr(pParse, TK_EQ, pLeft, pRight); - pWhere = tdsqlite3ExprAnd(pParse, pWhere, pEq); + pRight = sqlite3Expr(db, TK_ID, zCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight); + pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); } /* If the child table is the same as the parent table, then add terms @@ -121932,7 +121932,7 @@ static void fkScanChildren( if( HasRowid(pTab) ){ pLeft = exprTableRegister(pParse, pTab, regData, -1); pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1); - pNe = tdsqlite3PExpr(pParse, TK_NE, pLeft, pRight); + pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight); }else{ Expr *pEq, *pAll = 0; assert( pIdx!=0 ); @@ -121940,36 +121940,36 @@ static void fkScanChildren( i16 iCol = pIdx->aiColumn[i]; assert( iCol>=0 ); pLeft = exprTableRegister(pParse, pTab, regData, iCol); - pRight = tdsqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName); - pEq = tdsqlite3PExpr(pParse, TK_IS, pLeft, pRight); - pAll = tdsqlite3ExprAnd(pParse, pAll, pEq); + pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName); + pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight); + pAll = sqlite3ExprAnd(pParse, pAll, pEq); } - pNe = tdsqlite3PExpr(pParse, TK_NOT, pAll, 0); + pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0); } - pWhere = tdsqlite3ExprAnd(pParse, pWhere, pNe); + pWhere = sqlite3ExprAnd(pParse, pWhere, pNe); } /* Resolve the references in the WHERE clause. */ memset(&sNameContext, 0, sizeof(NameContext)); sNameContext.pSrcList = pSrc; sNameContext.pParse = pParse; - tdsqlite3ResolveExprNames(&sNameContext, pWhere); + sqlite3ResolveExprNames(&sNameContext, pWhere); /* Create VDBE to loop through the entries in pSrc that match the WHERE ** clause. For each row found, increment either the deferred or immediate ** foreign key constraint counter. */ if( pParse->nErr==0 ){ - pWInfo = tdsqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); - tdsqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0, 0, 0); + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); if( pWInfo ){ - tdsqlite3WhereEnd(pWInfo); + sqlite3WhereEnd(pWInfo); } } /* Clean up the WHERE clause constructed above. */ - tdsqlite3ExprDelete(db, pWhere); + sqlite3ExprDelete(db, pWhere); if( iFkIfZero ){ - tdsqlite3VdbeJumpHere(v, iFkIfZero); + sqlite3VdbeJumpHere(v, iFkIfZero); } } @@ -121987,8 +121987,8 @@ static void fkScanChildren( ** NULL pointer (as there are no FK constraints for which t2 is the parent ** table). */ -SQLITE_PRIVATE FKey *tdsqlite3FkReferences(Table *pTab){ - return (FKey *)tdsqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName); +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ + return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName); } /* @@ -121999,14 +121999,14 @@ SQLITE_PRIVATE FKey *tdsqlite3FkReferences(Table *pTab){ ** The Trigger structure or any of its sub-components may be allocated from ** the lookaside buffer belonging to database handle dbMem. */ -static void fkTriggerDelete(tdsqlite3 *dbMem, Trigger *p){ +static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ if( p ){ TriggerStep *pStep = p->step_list; - tdsqlite3ExprDelete(dbMem, pStep->pWhere); - tdsqlite3ExprListDelete(dbMem, pStep->pExprList); - tdsqlite3SelectDelete(dbMem, pStep->pSelect); - tdsqlite3ExprDelete(dbMem, p->pWhen); - tdsqlite3DbFree(dbMem, p); + sqlite3ExprDelete(dbMem, pStep->pWhere); + sqlite3ExprListDelete(dbMem, pStep->pExprList); + sqlite3SelectDelete(dbMem, pStep->pSelect); + sqlite3ExprDelete(dbMem, p->pWhen); + sqlite3DbFree(dbMem, p); } } @@ -122027,15 +122027,15 @@ static void fkTriggerDelete(tdsqlite3 *dbMem, Trigger *p){ ** the table from the database. Triggers are disabled while running this ** DELETE, but foreign key actions are not. */ -SQLITE_PRIVATE void tdsqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ - tdsqlite3 *db = pParse->db; +SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ + sqlite3 *db = pParse->db; if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) ){ int iSkip = 0; - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); assert( v ); /* VDBE has already been allocated */ assert( pTab->pSelect==0 ); /* Not a view */ - if( tdsqlite3FkReferences(pTab)==0 ){ + if( sqlite3FkReferences(pTab)==0 ){ /* Search for a deferred foreign key constraint for which this table ** is the child table. If one cannot be found, return without ** generating any VDBE code. If one can be found, then jump over @@ -122046,12 +122046,12 @@ SQLITE_PRIVATE void tdsqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *p if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break; } if( !p ) return; - iSkip = tdsqlite3VdbeMakeLabel(pParse); - tdsqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); + iSkip = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v); } pParse->disableTriggers = 1; - tdsqlite3DeleteFrom(pParse, tdsqlite3SrcListDup(db, pName, 0), 0, 0, 0); + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0); pParse->disableTriggers = 0; /* If the DELETE has generated immediate foreign key constraint @@ -122064,15 +122064,15 @@ SQLITE_PRIVATE void tdsqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *p ** constraints are violated. */ if( (db->flags & SQLITE_DeferFKs)==0 ){ - tdsqlite3VdbeVerifyAbortable(v, OE_Abort); - tdsqlite3VdbeAddOp2(v, OP_FkIfZero, 0, tdsqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeVerifyAbortable(v, OE_Abort); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); - tdsqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_FOREIGNKEY, OE_Abort, 0, P4_STATIC, P5_ConstraintFK); } if( iSkip ){ - tdsqlite3VdbeResolveLabel(v, iSkip); + sqlite3VdbeResolveLabel(v, iSkip); } } } @@ -122131,7 +122131,7 @@ static int fkParentIsModified( if( aChange[iKey]>=0 || (iKey==pTab->iPKey && bChngRowid) ){ Column *pCol = &pTab->aCol[iKey]; if( zKey ){ - if( 0==tdsqlite3StrICmp(pCol->zName, zKey) ) return 1; + if( 0==sqlite3StrICmp(pCol->zName, zKey) ) return 1; }else if( pCol->colFlags & COLFLAG_PRIMKEY ){ return 1; } @@ -122147,7 +122147,7 @@ static int fkParentIsModified( ** to trigger pFKey. */ static int isSetNullAction(Parse *pParse, FKey *pFKey){ - Parse *pTop = tdsqlite3ParseToplevel(pParse); + Parse *pTop = sqlite3ParseToplevel(pParse); if( pTop->pTriggerPrg ){ Trigger *p = pTop->pTriggerPrg->pTrigger; if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) @@ -122179,7 +122179,7 @@ static int isSetNullAction(Parse *pParse, FKey *pFKey){ ** described for DELETE. Then again after the original record is deleted ** but before the new record is inserted using the INSERT convention. */ -SQLITE_PRIVATE void tdsqlite3FkCheck( +SQLITE_PRIVATE void sqlite3FkCheck( Parse *pParse, /* Parse context */ Table *pTab, /* Row is being deleted from this table */ int regOld, /* Previous row data is stored here */ @@ -122187,7 +122187,7 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( int *aChange, /* Array indicating UPDATEd columns (or 0) */ int bChngRowid /* True if rowid is UPDATEd */ ){ - tdsqlite3 *db = pParse->db; /* Database handle */ + sqlite3 *db = pParse->db; /* Database handle */ FKey *pFKey; /* Used to iterate through FKs */ int iDb; /* Index of database containing pTab */ const char *zDb; /* Name of database containing pTab */ @@ -122199,7 +122199,7 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( /* If foreign-keys are disabled, this function is a no-op. */ if( (db->flags&SQLITE_ForeignKeys)==0 ) return; - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zDb = db->aDb[iDb].zDbSName; /* Loop through all the foreign key constraints for which pTab is the @@ -122214,7 +122214,7 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( int bIgnore = 0; if( aChange - && tdsqlite3_stricmp(pTab->zName, pFKey->zTo)!=0 + && sqlite3_stricmp(pTab->zName, pFKey->zTo)!=0 && fkChildIsModified(pTab, pFKey, aChange, bChngRowid)==0 ){ continue; @@ -122225,11 +122225,11 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( ** schema items cannot be located, set an error in pParse and return ** early. */ if( pParse->disableTriggers ){ - pTo = tdsqlite3FindTable(db, pFKey->zTo, zDb); + pTo = sqlite3FindTable(db, pFKey->zTo, zDb); }else{ - pTo = tdsqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); + pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); } - if( !pTo || tdsqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ + if( !pTo || sqlite3FkLocateIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ assert( isIgnoreErrors==0 || (regOld!=0 && regNew==0) ); if( !isIgnoreErrors || db->mallocFailed ) return; if( pTo==0 ){ @@ -122240,15 +122240,15 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( ** missing, behave as if it is empty. i.e. decrement the relevant ** FK counter for each row of the current table with non-NULL keys. */ - Vdbe *v = tdsqlite3GetVdbe(pParse); - int iJump = tdsqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; + Vdbe *v = sqlite3GetVdbe(pParse); + int iJump = sqlite3VdbeCurrentAddr(v) + pFKey->nCol + 1; for(i=0; inCol; i++){ int iFromCol, iReg; iFromCol = pFKey->aCol[i].iFrom; - iReg = tdsqlite3TableColumnToStorage(pFKey->pFrom,iFromCol) + regOld+1; - tdsqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v); + iReg = sqlite3TableColumnToStorage(pFKey->pFrom,iFromCol) + regOld+1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iJump); VdbeCoverage(v); } - tdsqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, -1); } continue; } @@ -122272,7 +122272,7 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( if( db->xAuth ){ int rcauth; char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName; - rcauth = tdsqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); + rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); bIgnore = (rcauth==SQLITE_IGNORE); } #endif @@ -122281,7 +122281,7 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( /* Take a shared-cache advisory read-lock on the parent table. Allocate ** a cursor to use to search the unique index on the parent key columns ** in the parent table. */ - tdsqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); + sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); pParse->nTab++; if( regOld!=0 ){ @@ -122302,12 +122302,12 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1, bIgnore); } - tdsqlite3DbFree(db, aiFree); + sqlite3DbFree(db, aiFree); } /* Loop through all the foreign key constraints that refer to this table. ** (the "child" constraints) */ - for(pFKey = tdsqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ Index *pIdx = 0; /* Foreign key index for pFKey */ SrcList *pSrc; int *aiCol = 0; @@ -122325,15 +122325,15 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( continue; } - if( tdsqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ + if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ if( !isIgnoreErrors || db->mallocFailed ) return; continue; } assert( aiCol || pFKey->nCol==1 ); /* Create a SrcList structure containing the child table. We need the - ** child table as a SrcList for tdsqlite3WhereBegin() */ - pSrc = tdsqlite3SrcListAppend(pParse, 0, 0, 0); + ** child table as a SrcList for sqlite3WhereBegin() */ + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ struct SrcList_item *pItem = pSrc->a; pItem->pTab = pFKey->pFrom; @@ -122365,13 +122365,13 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( ** might be set incorrectly if any OP_FkCounter related scans are ** omitted. */ if( !pFKey->isDeferred && eAction!=OE_Cascade && eAction!=OE_SetNull ){ - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); } } pItem->zName = 0; - tdsqlite3SrcListDelete(db, pSrc); + sqlite3SrcListDelete(db, pSrc); } - tdsqlite3DbFree(db, aiCol); + sqlite3DbFree(db, aiCol); } } @@ -122381,7 +122381,7 @@ SQLITE_PRIVATE void tdsqlite3FkCheck( ** This function is called before generating code to update or delete a ** row contained in table pTab. */ -SQLITE_PRIVATE u32 tdsqlite3FkOldmask( +SQLITE_PRIVATE u32 sqlite3FkOldmask( Parse *pParse, /* Parse context */ Table *pTab /* Table being modified */ ){ @@ -122392,9 +122392,9 @@ SQLITE_PRIVATE u32 tdsqlite3FkOldmask( for(p=pTab->pFKey; p; p=p->pNextFrom){ for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); } - for(p=tdsqlite3FkReferences(pTab); p; p=p->pNextTo){ + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ Index *pIdx = 0; - tdsqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0); + sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0); if( pIdx ){ for(i=0; inKeyCol; i++){ assert( pIdx->aiColumn[i]>=0 ); @@ -122429,7 +122429,7 @@ SQLITE_PRIVATE u32 tdsqlite3FkOldmask( ** ** Or, assuming some other foreign key processing is required, 1. */ -SQLITE_PRIVATE int tdsqlite3FkRequired( +SQLITE_PRIVATE int sqlite3FkRequired( Parse *pParse, /* Parse context */ Table *pTab, /* Table being modified */ int *aChange, /* Non-NULL for UPDATE operations */ @@ -122441,7 +122441,7 @@ SQLITE_PRIVATE int tdsqlite3FkRequired( /* A DELETE operation. Foreign key processing is required if the ** table in question is either the child or parent table for any ** foreign key constraint. */ - eRet = (tdsqlite3FkReferences(pTab) || pTab->pFKey); + eRet = (sqlite3FkReferences(pTab) || pTab->pFKey); }else{ /* This is an UPDATE. Foreign key processing is only required if the ** operation modifies one or more child or parent key columns. */ @@ -122449,14 +122449,14 @@ SQLITE_PRIVATE int tdsqlite3FkRequired( /* Check if any child key columns are being modified. */ for(p=pTab->pFKey; p; p=p->pNextFrom){ - if( 0==tdsqlite3_stricmp(pTab->zName, p->zTo) ) return 2; + if( 0==sqlite3_stricmp(pTab->zName, p->zTo) ) return 2; if( fkChildIsModified(pTab, p, aChange, chngRowid) ){ eRet = 1; } } /* Check if any parent key columns are being modified. */ - for(p=tdsqlite3FkReferences(pTab); p; p=p->pNextTo){ + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ if( p->aAction[1]!=OE_None ) return 2; eRet = 1; @@ -122494,7 +122494,7 @@ SQLITE_PRIVATE int tdsqlite3FkRequired( ** ** The returned pointer is cached as part of the foreign key object. It ** is eventually freed along with the rest of the foreign key object by -** tdsqlite3FkDelete(). +** sqlite3FkDelete(). */ static Trigger *fkActionTrigger( Parse *pParse, /* Parse context */ @@ -122502,7 +122502,7 @@ static Trigger *fkActionTrigger( FKey *pFKey, /* Foreign key to get action for */ ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ ){ - tdsqlite3 *db = pParse->db; /* Database handle */ + sqlite3 *db = pParse->db; /* Database handle */ int action; /* One of OE_None, OE_Cascade etc. */ Trigger *pTrigger; /* Trigger definition to return */ int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ @@ -122525,7 +122525,7 @@ static Trigger *fkActionTrigger( int i; /* Iterator variable */ Expr *pWhen = 0; /* WHEN clause for the trigger */ - if( tdsqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; + if( sqlite3FkLocateIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; assert( aiCol || pFKey->nCol==1 ); for(i=0; inCol; i++){ @@ -122540,21 +122540,21 @@ static Trigger *fkActionTrigger( assert( iFromCol>=0 ); assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKeynCol) ); assert( pIdx==0 || pIdx->aiColumn[i]>=0 ); - tdsqlite3TokenInit(&tToCol, + sqlite3TokenInit(&tToCol, pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName); - tdsqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); + sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName); /* Create the expression "OLD.zToCol = zFromCol". It is important ** that the "OLD.zToCol" term is on the LHS of the = operator, so ** that the affinity and collation sequence associated with the ** parent table are used for the comparison. */ - pEq = tdsqlite3PExpr(pParse, TK_EQ, - tdsqlite3PExpr(pParse, TK_DOT, - tdsqlite3ExprAlloc(db, TK_ID, &tOld, 0), - tdsqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), - tdsqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) + pEq = sqlite3PExpr(pParse, TK_EQ, + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), + sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0) ); - pWhere = tdsqlite3ExprAnd(pParse, pWhere, pEq); + pWhere = sqlite3ExprAnd(pParse, pWhere, pEq); /* For ON UPDATE, construct the next term of the WHEN clause. ** The final WHEN clause will be like this: @@ -122562,23 +122562,23 @@ static Trigger *fkActionTrigger( ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) */ if( pChanges ){ - pEq = tdsqlite3PExpr(pParse, TK_IS, - tdsqlite3PExpr(pParse, TK_DOT, - tdsqlite3ExprAlloc(db, TK_ID, &tOld, 0), - tdsqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), - tdsqlite3PExpr(pParse, TK_DOT, - tdsqlite3ExprAlloc(db, TK_ID, &tNew, 0), - tdsqlite3ExprAlloc(db, TK_ID, &tToCol, 0)) + pEq = sqlite3PExpr(pParse, TK_IS, + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tOld, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)), + sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)) ); - pWhen = tdsqlite3ExprAnd(pParse, pWhen, pEq); + pWhen = sqlite3ExprAnd(pParse, pWhen, pEq); } if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ Expr *pNew; if( action==OE_Cascade ){ - pNew = tdsqlite3PExpr(pParse, TK_DOT, - tdsqlite3ExprAlloc(db, TK_ID, &tNew, 0), - tdsqlite3ExprAlloc(db, TK_ID, &tToCol, 0)); + pNew = sqlite3PExpr(pParse, TK_DOT, + sqlite3ExprAlloc(db, TK_ID, &tNew, 0), + sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)); }else if( action==OE_SetDflt ){ Column *pCol = pFKey->pFrom->aCol + iFromCol; Expr *pDflt; @@ -122590,21 +122590,21 @@ static Trigger *fkActionTrigger( pDflt = pCol->pDflt; } if( pDflt ){ - pNew = tdsqlite3ExprDup(db, pDflt, 0); + pNew = sqlite3ExprDup(db, pDflt, 0); }else{ - pNew = tdsqlite3ExprAlloc(db, TK_NULL, 0, 0); + pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); } }else{ - pNew = tdsqlite3ExprAlloc(db, TK_NULL, 0, 0); + pNew = sqlite3ExprAlloc(db, TK_NULL, 0, 0); } - pList = tdsqlite3ExprListAppend(pParse, pList, pNew); - tdsqlite3ExprListSetName(pParse, pList, &tFromCol, 0); + pList = sqlite3ExprListAppend(pParse, pList, pNew); + sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); } } - tdsqlite3DbFree(db, aiCol); + sqlite3DbFree(db, aiCol); zFrom = pFKey->pFrom->zName; - nFrom = tdsqlite3Strlen30(zFrom); + nFrom = sqlite3Strlen30(zFrom); if( action==OE_Restrict ){ Token tFrom; @@ -122612,13 +122612,13 @@ static Trigger *fkActionTrigger( tFrom.z = zFrom; tFrom.n = nFrom; - pRaise = tdsqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); + pRaise = sqlite3Expr(db, TK_RAISE, "FOREIGN KEY constraint failed"); if( pRaise ){ pRaise->affExpr = OE_Abort; } - pSelect = tdsqlite3SelectNew(pParse, - tdsqlite3ExprListAppend(pParse, 0, pRaise), - tdsqlite3SrcListAppend(pParse, 0, &tFrom, 0), + pSelect = sqlite3SelectNew(pParse, + sqlite3ExprListAppend(pParse, 0, pRaise), + sqlite3SrcListAppend(pParse, 0, &tFrom, 0), pWhere, 0, 0, 0, 0, 0 ); @@ -122628,7 +122628,7 @@ static Trigger *fkActionTrigger( /* Disable lookaside memory allocation */ DisableLookaside; - pTrigger = (Trigger *)tdsqlite3DbMallocZero(db, + pTrigger = (Trigger *)sqlite3DbMallocZero(db, sizeof(Trigger) + /* struct Trigger */ sizeof(TriggerStep) + /* Single step in trigger program */ nFrom + 1 /* Space for pStep->zTarget */ @@ -122638,22 +122638,22 @@ static Trigger *fkActionTrigger( pStep->zTarget = (char *)&pStep[1]; memcpy((char *)pStep->zTarget, zFrom, nFrom); - pStep->pWhere = tdsqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); - pStep->pExprList = tdsqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); - pStep->pSelect = tdsqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); + pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); if( pWhen ){ - pWhen = tdsqlite3PExpr(pParse, TK_NOT, pWhen, 0); - pTrigger->pWhen = tdsqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0); + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); } } /* Re-enable the lookaside buffer, if it was disabled earlier. */ EnableLookaside; - tdsqlite3ExprDelete(db, pWhere); - tdsqlite3ExprDelete(db, pWhen); - tdsqlite3ExprListDelete(db, pList); - tdsqlite3SelectDelete(db, pSelect); + sqlite3ExprDelete(db, pWhere); + sqlite3ExprDelete(db, pWhen); + sqlite3ExprListDelete(db, pList); + sqlite3SelectDelete(db, pSelect); if( db->mallocFailed==1 ){ fkTriggerDelete(db, pTrigger); return 0; @@ -122687,7 +122687,7 @@ static Trigger *fkActionTrigger( ** This function is called when deleting or updating a row to implement ** any required CASCADE, SET NULL or SET DEFAULT actions. */ -SQLITE_PRIVATE void tdsqlite3FkActions( +SQLITE_PRIVATE void sqlite3FkActions( Parse *pParse, /* Parse context */ Table *pTab, /* Table being updated or deleted from */ ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ @@ -122701,11 +122701,11 @@ SQLITE_PRIVATE void tdsqlite3FkActions( ** trigger sub-program. */ if( pParse->db->flags&SQLITE_ForeignKeys ){ FKey *pFKey; /* Iterator variable */ - for(pFKey = tdsqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ if( aChange==0 || fkParentIsModified(pTab, pFKey, aChange, bChngRowid) ){ Trigger *pAct = fkActionTrigger(pParse, pTab, pFKey, pChanges); if( pAct ){ - tdsqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0); + sqlite3CodeRowTriggerDirect(pParse, pAct, pTab, regOld, OE_Abort, 0); } } } @@ -122719,12 +122719,12 @@ SQLITE_PRIVATE void tdsqlite3FkActions( ** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash ** hash table. */ -SQLITE_PRIVATE void tdsqlite3FkDelete(tdsqlite3 *db, Table *pTab){ +SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *db, Table *pTab){ FKey *pFKey; /* Iterator variable */ FKey *pNext; /* Copy of pFKey->pNextFrom */ assert( db==0 || IsVirtual(pTab) - || tdsqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); + || sqlite3SchemaMutexHeld(db, 0, pTab->pSchema) ); for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ /* Remove the FK from the fkeyHash hash table. */ @@ -122734,7 +122734,7 @@ SQLITE_PRIVATE void tdsqlite3FkDelete(tdsqlite3 *db, Table *pTab){ }else{ void *p = (void *)pFKey->pNextTo; const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); - tdsqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); } if( pFKey->pNextTo ){ pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; @@ -122753,7 +122753,7 @@ SQLITE_PRIVATE void tdsqlite3FkDelete(tdsqlite3 *db, Table *pTab){ #endif pNext = pFKey->pNextFrom; - tdsqlite3DbFree(db, pFKey); + sqlite3DbFree(db, pFKey); } } #endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ @@ -122785,7 +122785,7 @@ SQLITE_PRIVATE void tdsqlite3FkDelete(tdsqlite3 *db, Table *pTab){ ** If pTab is a WITHOUT ROWID table, then it is the PRIMARY KEY index ** for that table that is actually opened. */ -SQLITE_PRIVATE void tdsqlite3OpenTable( +SQLITE_PRIVATE void sqlite3OpenTable( Parse *pParse, /* Generate code into this VDBE */ int iCur, /* The cursor number of the table */ int iDb, /* The database index in sqlite3.aDb[] */ @@ -122794,19 +122794,19 @@ SQLITE_PRIVATE void tdsqlite3OpenTable( ){ Vdbe *v; assert( !IsVirtual(pTab) ); - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); - tdsqlite3TableLock(pParse, iDb, pTab->tnum, + sqlite3TableLock(pParse, iDb, pTab->tnum, (opcode==OP_OpenWrite)?1:0, pTab->zName); if( HasRowid(pTab) ){ - tdsqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); + sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); VdbeComment((v, "%s", pTab->zName)); }else{ - Index *pPk = tdsqlite3PrimaryKeyIndex(pTab); + Index *pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); assert( pPk->tnum==pTab->tnum ); - tdsqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); - tdsqlite3VdbeSetP4KeyInfo(pParse, pPk); + sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); VdbeComment((v, "%s", pTab->zName)); } } @@ -122829,9 +122829,9 @@ SQLITE_PRIVATE void tdsqlite3OpenTable( ** ** Memory for the buffer containing the column index affinity string ** is managed along with the rest of the Index structure. It will be -** released when tdsqlite3DeleteIndex() is called. +** released when sqlite3DeleteIndex() is called. */ -SQLITE_PRIVATE const char *tdsqlite3IndexAffinityStr(tdsqlite3 *db, Index *pIdx){ +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ if( !pIdx->zColAff ){ /* The first time a column affinity string for a particular index is ** required, it is allocated and populated here. It is then stored as @@ -122843,9 +122843,9 @@ SQLITE_PRIVATE const char *tdsqlite3IndexAffinityStr(tdsqlite3 *db, Index *pIdx) */ int n; Table *pTab = pIdx->pTable; - pIdx->zColAff = (char *)tdsqlite3DbMallocRaw(0, pIdx->nColumn+1); + pIdx->zColAff = (char *)sqlite3DbMallocRaw(0, pIdx->nColumn+1); if( !pIdx->zColAff ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); return 0; } for(n=0; nnColumn; n++){ @@ -122858,7 +122858,7 @@ SQLITE_PRIVATE const char *tdsqlite3IndexAffinityStr(tdsqlite3 *db, Index *pIdx) }else{ assert( x==XN_EXPR ); assert( pIdx->aColExpr!=0 ); - aff = tdsqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); + aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); } if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; @@ -122890,14 +122890,14 @@ SQLITE_PRIVATE const char *tdsqlite3IndexAffinityStr(tdsqlite3 *db, Index *pIdx) ** 'D' INTEGER ** 'E' REAL */ -SQLITE_PRIVATE void tdsqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ +SQLITE_PRIVATE void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ int i, j; char *zColAff = pTab->zColAff; if( zColAff==0 ){ - tdsqlite3 *db = tdsqlite3VdbeDb(v); - zColAff = (char *)tdsqlite3DbMallocRaw(0, pTab->nCol+1); + sqlite3 *db = sqlite3VdbeDb(v); + zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1); if( !zColAff ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); return; } @@ -122913,12 +122913,12 @@ SQLITE_PRIVATE void tdsqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ pTab->zColAff = zColAff; } assert( zColAff!=0 ); - i = tdsqlite3Strlen30NN(zColAff); + i = sqlite3Strlen30NN(zColAff); if( i ){ if( iReg ){ - tdsqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); + sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i); }else{ - tdsqlite3VdbeChangeP4(v, -1, zColAff, i); + sqlite3VdbeChangeP4(v, -1, zColAff, i); } } } @@ -122930,15 +122930,15 @@ SQLITE_PRIVATE void tdsqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){ ** run without using a temporary table for the results of the SELECT. */ static int readsTable(Parse *p, int iDb, Table *pTab){ - Vdbe *v = tdsqlite3GetVdbe(p); + Vdbe *v = sqlite3GetVdbe(p); int i; - int iEnd = tdsqlite3VdbeCurrentAddr(v); + int iEnd = sqlite3VdbeCurrentAddr(v); #ifndef SQLITE_OMIT_VIRTUALTABLE - VTable *pVTab = IsVirtual(pTab) ? tdsqlite3GetVTable(p->db, pTab) : 0; + VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0; #endif for(i=1; iopcode==OP_OpenRead && pOp->p3==iDb ){ Index *pIndex; @@ -122982,7 +122982,7 @@ static int exprColumnFlagUnion(Walker *pWalker, Expr *pExpr){ ** back and computes the values for those columns based on the previously ** computed normal columns. */ -SQLITE_PRIVATE void tdsqlite3ComputeGeneratedColumns( +SQLITE_PRIVATE void sqlite3ComputeGeneratedColumns( Parse *pParse, /* Parsing context */ int iRegStore, /* Register holding the first column */ Table *pTab /* The table */ @@ -123000,9 +123000,9 @@ SQLITE_PRIVATE void tdsqlite3ComputeGeneratedColumns( /* Before computing generated columns, first go through and make sure ** that appropriate affinity has been applied to the regular columns */ - tdsqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); + sqlite3TableAffinity(pParse->pVdbe, pTab, iRegStore); if( (pTab->tabFlags & TF_HasStored)!=0 - && (pOp = tdsqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity + && (pOp = sqlite3VdbeGetOp(pParse->pVdbe,-1))->opcode==OP_Affinity ){ /* Change the OP_Affinity argument to '@' (NONE) for all stored ** columns. '@' is the no-op affinity and those columns have not @@ -123040,7 +123040,7 @@ SQLITE_PRIVATE void tdsqlite3ComputeGeneratedColumns( w.xSelectCallback2 = 0; /* On the second pass, compute the value of each NOT-AVAILABLE column. - ** Companion code in the TK_COLUMN case of tdsqlite3ExprCodeTarget() will + ** Companion code in the TK_COLUMN case of sqlite3ExprCodeTarget() will ** compute dependencies and mark remove the COLSPAN_NOTAVAIL mark, as ** they are needed. */ @@ -123054,7 +123054,7 @@ SQLITE_PRIVATE void tdsqlite3ComputeGeneratedColumns( int x; pCol->colFlags |= COLFLAG_BUSY; w.eCode = 0; - tdsqlite3WalkExpr(&w, pCol->pDflt); + sqlite3WalkExpr(&w, pCol->pDflt); pCol->colFlags &= ~COLFLAG_BUSY; if( w.eCode & COLFLAG_NOTAVAIL ){ pRedo = pCol; @@ -123062,14 +123062,14 @@ SQLITE_PRIVATE void tdsqlite3ComputeGeneratedColumns( } eProgress = 1; assert( pCol->colFlags & COLFLAG_GENERATED ); - x = tdsqlite3TableColumnToStorage(pTab, i) + iRegStore; - tdsqlite3ExprCodeGeneratedColumn(pParse, pCol, x); + x = sqlite3TableColumnToStorage(pTab, i) + iRegStore; + sqlite3ExprCodeGeneratedColumn(pParse, pCol, x); pCol->colFlags &= ~COLFLAG_NOTAVAIL; } } }while( pRedo && eProgress ); if( pRedo ){ - tdsqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zName); + sqlite3ErrorMsg(pParse, "generated column loop on \"%s\"", pRedo->zName); } pParse->iSelfTab = 0; } @@ -123110,7 +123110,7 @@ static int autoIncBegin( if( (pTab->tabFlags & TF_Autoincrement)!=0 && (pParse->db->mDbFlags & DBFLAG_Vacuum)==0 ){ - Parse *pToplevel = tdsqlite3ParseToplevel(pParse); + Parse *pToplevel = sqlite3ParseToplevel(pParse); AutoincInfo *pInfo; Table *pSeqTab = pParse->db->aDb[iDb].pSchema->pSeqTab; @@ -123130,7 +123130,7 @@ static int autoIncBegin( pInfo = pToplevel->pAinc; while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } if( pInfo==0 ){ - pInfo = tdsqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); + pInfo = sqlite3DbMallocRawNN(pParse->db, sizeof(*pInfo)); if( pInfo==0 ) return 0; pInfo->pNext = pToplevel->pAinc; pToplevel->pAinc = pInfo; @@ -123149,9 +123149,9 @@ static int autoIncBegin( ** This routine generates code that will initialize all of the ** register used by the autoincrement tracker. */ -SQLITE_PRIVATE void tdsqlite3AutoincrementBegin(Parse *pParse){ +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ AutoincInfo *p; /* Information about an AUTOINCREMENT */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* Database only autoinc table */ int memId; /* Register holding max rowid */ Vdbe *v = pParse->pVdbe; /* VDBE under construction */ @@ -123159,7 +123159,7 @@ SQLITE_PRIVATE void tdsqlite3AutoincrementBegin(Parse *pParse){ /* This routine is never called during trigger-generation. It is ** only called from the top-level */ assert( pParse->pTriggerTab==0 ); - assert( tdsqlite3IsToplevel(pParse) ); + assert( sqlite3IsToplevel(pParse) ); assert( v ); /* We failed long ago if this is not so */ for(p = pParse->pAinc; p; p = p->pNext){ @@ -123181,10 +123181,10 @@ SQLITE_PRIVATE void tdsqlite3AutoincrementBegin(Parse *pParse){ VdbeOp *aOp; pDb = &db->aDb[p->iDb]; memId = p->regCtr; - assert( tdsqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); - tdsqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); - tdsqlite3VdbeLoadString(v, memId-1, p->pTab->zName); - aOp = tdsqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); + sqlite3VdbeLoadString(v, memId-1, p->pTab->zName); + aOp = sqlite3VdbeAddOpList(v, ArraySize(autoInc), autoInc, iLn); if( aOp==0 ) break; aOp[0].p2 = memId; aOp[0].p3 = memId+2; @@ -123212,7 +123212,7 @@ SQLITE_PRIVATE void tdsqlite3AutoincrementBegin(Parse *pParse){ */ static void autoIncStep(Parse *pParse, int memId, int regRowid){ if( memId>0 ){ - tdsqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); + sqlite3VdbeAddOp2(pParse->pVdbe, OP_MemMax, memId, regRowid); } } @@ -123226,7 +123226,7 @@ static void autoIncStep(Parse *pParse, int memId, int regRowid){ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ AutoincInfo *p; Vdbe *v = pParse->pVdbe; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; assert( v ); for(p = pParse->pAinc; p; p = p->pNext){ @@ -123243,12 +123243,12 @@ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ int iRec; int memId = p->regCtr; - iRec = tdsqlite3GetTempReg(pParse); - assert( tdsqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); - tdsqlite3VdbeAddOp3(v, OP_Le, memId+2, tdsqlite3VdbeCurrentAddr(v)+7, memId); + iRec = sqlite3GetTempReg(pParse); + assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) ); + sqlite3VdbeAddOp3(v, OP_Le, memId+2, sqlite3VdbeCurrentAddr(v)+7, memId); VdbeCoverage(v); - tdsqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); - aOp = tdsqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); + aOp = sqlite3VdbeAddOpList(v, ArraySize(autoIncEnd), autoIncEnd, iLn); if( aOp==0 ) break; aOp[0].p1 = memId+1; aOp[1].p2 = memId+1; @@ -123257,10 +123257,10 @@ static SQLITE_NOINLINE void autoIncrementEnd(Parse *pParse){ aOp[3].p2 = iRec; aOp[3].p3 = memId+1; aOp[3].p5 = OPFLAG_APPEND; - tdsqlite3ReleaseTempReg(pParse, iRec); + sqlite3ReleaseTempReg(pParse, iRec); } } -SQLITE_PRIVATE void tdsqlite3AutoincrementEnd(Parse *pParse){ +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ if( pParse->pAinc ) autoIncrementEnd(pParse); } #else @@ -123379,7 +123379,7 @@ static int xferOptimization( ** end loop ** D: cleanup */ -SQLITE_PRIVATE void tdsqlite3Insert( +SQLITE_PRIVATE void sqlite3Insert( Parse *pParse, /* Parser context */ SrcList *pTabList, /* Name of table into which we are inserting */ Select *pSelect, /* A SELECT statement to use as the data source */ @@ -123387,7 +123387,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( int onError, /* How to handle constraint errors */ Upsert *pUpsert /* ON CONFLICT clauses for upsert, or NULL */ ){ - tdsqlite3 *db; /* The main database structure */ + sqlite3 *db; /* The main database structure */ Table *pTab; /* The table to insert into. aka TABLE */ int i, j; /* Loop counters */ Vdbe *v; /* Generate code into this virtual machine */ @@ -123438,20 +123438,20 @@ SQLITE_PRIVATE void tdsqlite3Insert( if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){ pList = pSelect->pEList; pSelect->pEList = 0; - tdsqlite3SelectDelete(db, pSelect); + sqlite3SelectDelete(db, pSelect); pSelect = 0; } /* Locate the table into which we will be inserting new information. */ assert( pTabList->nSrc==1 ); - pTab = tdsqlite3SrcListLookup(pParse, pTabList); + pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ){ goto insert_cleanup; } - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDbnDb ); - if( tdsqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, pTab->zName, 0, db->aDb[iDb].zDbSName) ){ goto insert_cleanup; } @@ -123461,7 +123461,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** inserted into is a view */ #ifndef SQLITE_OMIT_TRIGGER - pTrigger = tdsqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_INSERT, 0, &tmask); isView = pTab->pSelect!=0; #else # define pTrigger 0 @@ -123477,22 +123477,22 @@ SQLITE_PRIVATE void tdsqlite3Insert( /* If pTab is really a view, make sure it has been initialized. ** ViewGetColumnNames() is a no-op if pTab is not a view. */ - if( tdsqlite3ViewGetColumnNames(pParse, pTab) ){ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto insert_cleanup; } /* Cannot insert into a read-only table. */ - if( tdsqlite3IsReadOnly(pParse, pTab, tmask) ){ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ goto insert_cleanup; } /* Allocate a VDBE */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v==0 ) goto insert_cleanup; - if( pParse->nested==0 ) tdsqlite3VdbeCountChanges(v); - tdsqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb); + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb); #ifndef SQLITE_OMIT_XFER_OPT /* If the statement is of the form @@ -123553,7 +123553,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( } for(i=0; inId; i++){ for(j=0; jnCol; j++){ - if( tdsqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ + if( sqlite3StrICmp(pColumn->a[i].zName, pTab->aCol[j].zName)==0 ){ pColumn->a[i].idx = j; if( i!=j ) bIdListInOrder = 0; if( j==pTab->iPKey ){ @@ -123561,7 +123561,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( } #ifndef SQLITE_OMIT_GENERATED_COLUMNS if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "cannot INSERT into generated column \"%s\"", pTab->aCol[j].zName); goto insert_cleanup; @@ -123571,11 +123571,11 @@ SQLITE_PRIVATE void tdsqlite3Insert( } } if( j>=pTab->nCol ){ - if( tdsqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ + if( sqlite3IsRowid(pColumn->a[i].zName) && !withoutRowid ){ ipkColumn = i; bIdListInOrder = 0; }else{ - tdsqlite3ErrorMsg(pParse, "table %S has no column named %s", + sqlite3ErrorMsg(pParse, "table %S has no column named %s", pTabList, 0, pColumn->a[i].zName); pParse->checkSchema = 1; goto insert_cleanup; @@ -123597,16 +123597,16 @@ SQLITE_PRIVATE void tdsqlite3Insert( int rc; /* Result code */ regYield = ++pParse->nMem; - addrTop = tdsqlite3VdbeCurrentAddr(v) + 1; - tdsqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); - tdsqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); + addrTop = sqlite3VdbeCurrentAddr(v) + 1; + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop); + sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield); dest.iSdst = bIdListInOrder ? regData : 0; dest.nSdst = pTab->nCol; - rc = tdsqlite3Select(pParse, pSelect, &dest); + rc = sqlite3Select(pParse, pSelect, &dest); regFromSelect = dest.iSdst; if( rc || db->mallocFailed || pParse->nErr ) goto insert_cleanup; - tdsqlite3VdbeEndCoroutine(v, regYield); - tdsqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ + sqlite3VdbeEndCoroutine(v, regYield); + sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */ assert( pSelect->pEList ); nColumn = pSelect->pEList->nExpr; @@ -123639,17 +123639,17 @@ SQLITE_PRIVATE void tdsqlite3Insert( int addrL; /* Label "L" */ srcTab = pParse->nTab++; - regRec = tdsqlite3GetTempReg(pParse); - regTempRowid = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); - addrL = tdsqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); - tdsqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); - tdsqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); - tdsqlite3VdbeGoto(v, addrL); - tdsqlite3VdbeJumpHere(v, addrL); - tdsqlite3ReleaseTempReg(pParse, regRec); - tdsqlite3ReleaseTempReg(pParse, regTempRowid); + regRec = sqlite3GetTempReg(pParse); + regTempRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); + addrL = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); + sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); + sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); + sqlite3VdbeGoto(v, addrL); + sqlite3VdbeJumpHere(v, addrL); + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempReg(pParse, regTempRowid); } }else{ /* This is the case if the data for the INSERT is coming from a @@ -123662,7 +123662,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( assert( useTempTable==0 ); if( pList ){ nColumn = pList->nExpr; - if( tdsqlite3ResolveExprListNames(&sNC, pList) ){ + if( sqlite3ResolveExprListNames(&sNC, pList) ){ goto insert_cleanup; } }else{ @@ -123698,13 +123698,13 @@ SQLITE_PRIVATE void tdsqlite3Insert( if( pTab->aCol[i].colFlags & COLFLAG_NOINSERT ) nHidden++; } if( pColumn==0 && nColumn && nColumn!=(pTab->nCol-nHidden) ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "table %S has %d columns but %d values were supplied", pTabList, 0, pTab->nCol-nHidden, nColumn); goto insert_cleanup; } if( pColumn!=0 && nColumn!=pColumn->nId ){ - tdsqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); + sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); goto insert_cleanup; } @@ -123715,15 +123715,15 @@ SQLITE_PRIVATE void tdsqlite3Insert( && !pParse->pTriggerTab ){ regRowCount = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); } /* If this is not a view, open the table and and all indices */ if( !isView ){ int nIdx; - nIdx = tdsqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, + nIdx = sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, -1, 0, &iDataCur, &iIdxCur); - aRegIdx = tdsqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2)); + aRegIdx = sqlite3DbMallocRawNN(db, sizeof(int)*(nIdx+2)); if( aRegIdx==0 ){ goto insert_cleanup; } @@ -123737,15 +123737,15 @@ SQLITE_PRIVATE void tdsqlite3Insert( #ifndef SQLITE_OMIT_UPSERT if( pUpsert ){ if( IsVirtual(pTab) ){ - tdsqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", + sqlite3ErrorMsg(pParse, "UPSERT not implemented for virtual table \"%s\"", pTab->zName); goto insert_cleanup; } if( pTab->pSelect ){ - tdsqlite3ErrorMsg(pParse, "cannot UPSERT a view"); + sqlite3ErrorMsg(pParse, "cannot UPSERT a view"); goto insert_cleanup; } - if( tdsqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){ + if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){ goto insert_cleanup; } pTabList->a[0].iCursor = iDataCur; @@ -123754,7 +123754,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( pUpsert->iDataCur = iDataCur; pUpsert->iIdxCur = iIdxCur; if( pUpsert->pUpsertTarget ){ - tdsqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert); + sqlite3UpsertAnalyzeTarget(pParse, pTabList, pUpsert); } } #endif @@ -123771,8 +123771,8 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** end loop ** D: ... */ - addrInsTop = tdsqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v); - addrCont = tdsqlite3VdbeCurrentAddr(v); + addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab); VdbeCoverage(v); + addrCont = sqlite3VdbeCurrentAddr(v); }else if( pSelect ){ /* This block codes the top of loop only. The complete loop is the ** following pseudocode (template 3): @@ -123782,14 +123782,14 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** goto C ** D: ... */ - tdsqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0, 0); - addrInsTop = addrCont = tdsqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); + sqlite3VdbeReleaseRegisters(pParse, regData, pTab->nCol, 0, 0); + addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); VdbeCoverage(v); if( ipkColumn>=0 ){ /* tag-20191021-001: If the INTEGER PRIMARY KEY is being generated by the ** SELECT, go ahead and copy the value into the rowid slot now, so that ** the value does not get overwritten by a NULL at tag-20191021-002. */ - tdsqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); + sqlite3VdbeAddOp2(v, OP_Copy, regFromSelect+ipkColumn, regRowid); } } @@ -123811,7 +123811,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** using the rowid. So put a NULL in the IPK slot of the record to avoid ** using excess space. The file format definition requires this extra ** NULL - we cannot optimize further by skipping the column completely */ - tdsqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); continue; } if( ((colFlags = pTab->aCol[i].colFlags) & COLFLAG_NOINSERT)!=0 ){ @@ -123828,13 +123828,13 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** to a second block of registers, so the register needs to be ** initialized to NULL to avoid an uninitialized register read */ if( tmask & TRIGGER_BEFORE ){ - tdsqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); + sqlite3VdbeAddOp1(v, OP_SoftNull, iRegStore); } continue; }else if( pColumn==0 ){ /* Hidden columns that are not explicitly named in the INSERT ** get there default value */ - tdsqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); continue; } } @@ -123843,35 +123843,35 @@ SQLITE_PRIVATE void tdsqlite3Insert( if( j>=pColumn->nId ){ /* A column not named in the insert column list gets its ** default value */ - tdsqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); continue; } k = j; }else if( nColumn==0 ){ /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */ - tdsqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); + sqlite3ExprCodeFactorable(pParse, pTab->aCol[i].pDflt, iRegStore); continue; }else{ k = i - nHidden; } if( useTempTable ){ - tdsqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore); + sqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore); }else if( pSelect ){ if( regFromSelect!=regData ){ - tdsqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); + sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); } }else{ - tdsqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore); + sqlite3ExprCode(pParse, pList->a[k].pExpr, iRegStore); } } /* Run the BEFORE and INSTEAD OF triggers, if there are any */ - endOfLoop = tdsqlite3VdbeMakeLabel(pParse); + endOfLoop = sqlite3VdbeMakeLabel(pParse); if( tmask & TRIGGER_BEFORE ){ - int regCols = tdsqlite3GetTempRange(pParse, pTab->nCol+1); + int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1); /* build the NEW.* reference row. Note that if there is an INTEGER ** PRIMARY KEY into which a NULL is being inserted, that NULL will be @@ -123880,20 +123880,20 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** not happened yet) so we substitute a rowid of -1 */ if( ipkColumn<0 ){ - tdsqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); }else{ int addr1; assert( !withoutRowid ); if( useTempTable ){ - tdsqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols); + sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols); }else{ assert( pSelect==0 ); /* Otherwise useTempTable is true */ - tdsqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols); + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols); } - addr1 = tdsqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v); - tdsqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); - tdsqlite3VdbeJumpHere(v, addr1); - tdsqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); + addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v); } /* Cannot have triggers on a virtual table. If it were possible, @@ -123903,7 +123903,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( /* Copy the new data already generated. */ assert( pTab->nNVCol>0 ); - tdsqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); + sqlite3VdbeAddOp3(v, OP_Copy, regRowid+1, regCols+1, pTab->nNVCol-1); #ifndef SQLITE_OMIT_GENERATED_COLUMNS /* Compute the new value for generated columns after all other @@ -123913,7 +123913,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( if( pTab->tabFlags & TF_HasGenerated ){ testcase( pTab->tabFlags & TF_HasVirtual ); testcase( pTab->tabFlags & TF_HasStored ); - tdsqlite3ComputeGeneratedColumns(pParse, regCols+1, pTab); + sqlite3ComputeGeneratedColumns(pParse, regCols+1, pTab); } #endif @@ -123923,34 +123923,34 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** table column affinities. */ if( !isView ){ - tdsqlite3TableAffinity(v, pTab, regCols+1); + sqlite3TableAffinity(v, pTab, regCols+1); } /* Fire BEFORE or INSTEAD OF triggers */ - tdsqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, pTab, regCols-pTab->nCol-1, onError, endOfLoop); - tdsqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); + sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); } if( !isView ){ if( IsVirtual(pTab) ){ /* The row that the VUpdate opcode will delete: none */ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, regIns); + sqlite3VdbeAddOp2(v, OP_Null, 0, regIns); } if( ipkColumn>=0 ){ /* Compute the new rowid */ if( useTempTable ){ - tdsqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid); + sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regRowid); }else if( pSelect ){ /* Rowid already initialized at tag-20191021-001 */ }else{ Expr *pIpk = pList->a[ipkColumn].pExpr; if( pIpk->op==TK_NULL && !IsVirtual(pTab) ){ - tdsqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); appendFlag = 1; }else{ - tdsqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); + sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regRowid); } } /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid @@ -123959,19 +123959,19 @@ SQLITE_PRIVATE void tdsqlite3Insert( if( !appendFlag ){ int addr1; if( !IsVirtual(pTab) ){ - addr1 = tdsqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); - tdsqlite3VdbeJumpHere(v, addr1); + addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeJumpHere(v, addr1); }else{ - addr1 = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v); + addr1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v); } - tdsqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v); } }else if( IsVirtual(pTab) || withoutRowid ){ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid); }else{ - tdsqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); + sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc); appendFlag = 1; } autoIncStep(pParse, regAutoinc, regRowid); @@ -123982,7 +123982,7 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** computing the ROWID in case one of the generated columns ** is derived from the INTEGER PRIMARY KEY. */ if( pTab->tabFlags & TF_HasGenerated ){ - tdsqlite3ComputeGeneratedColumns(pParse, regRowid+1, pTab); + sqlite3ComputeGeneratedColumns(pParse, regRowid+1, pTab); } #endif @@ -123991,20 +123991,20 @@ SQLITE_PRIVATE void tdsqlite3Insert( */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ - const char *pVTab = (const char *)tdsqlite3GetVTable(db, pTab); - tdsqlite3VtabMakeWritable(pParse, pTab); - tdsqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); - tdsqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); - tdsqlite3MayAbort(pParse); + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); + sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError); + sqlite3MayAbort(pParse); }else #endif { int isReplace; /* Set to true if constraints may cause a replace */ int bUseSeek; /* True to use OPFLAG_SEEKRESULT */ - tdsqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, + sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0, pUpsert ); - tdsqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); + sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0); /* Set the OPFLAG_USESEEKRESULT flag if either (a) there are no REPLACE ** constraints or (b) there are no triggers and this table is not a @@ -124014,8 +124014,8 @@ SQLITE_PRIVATE void tdsqlite3Insert( ** cursor that is disturbed. And these instructions both clear the ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT ** functionality. */ - bUseSeek = (isReplace==0 || !tdsqlite3VdbeHasSubProgram(v)); - tdsqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, + bUseSeek = (isReplace==0 || !sqlite3VdbeHasSubProgram(v)); + sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur, regIns, aRegIdx, 0, appendFlag, bUseSeek ); } @@ -124024,35 +124024,35 @@ SQLITE_PRIVATE void tdsqlite3Insert( /* Update the count of rows that are inserted */ if( regRowCount ){ - tdsqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } if( pTrigger ){ /* Code AFTER triggers */ - tdsqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, pTab, regData-2-pTab->nCol, onError, endOfLoop); } /* The bottom of the main insertion loop, if the data source ** is a SELECT statement. */ - tdsqlite3VdbeResolveLabel(v, endOfLoop); + sqlite3VdbeResolveLabel(v, endOfLoop); if( useTempTable ){ - tdsqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addrInsTop); - tdsqlite3VdbeAddOp1(v, OP_Close, srcTab); + sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrInsTop); + sqlite3VdbeAddOp1(v, OP_Close, srcTab); }else if( pSelect ){ - tdsqlite3VdbeGoto(v, addrCont); + sqlite3VdbeGoto(v, addrCont); #ifdef SQLITE_DEBUG /* If we are jumping back to an OP_Yield that is preceded by an ** OP_ReleaseReg, set the p5 flag on the OP_Goto so that the ** OP_ReleaseReg will be included in the loop. */ - if( tdsqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){ - assert( tdsqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield ); - tdsqlite3VdbeChangeP5(v, 1); + if( sqlite3VdbeGetOp(v, addrCont-1)->opcode==OP_ReleaseReg ){ + assert( sqlite3VdbeGetOp(v, addrCont)->opcode==OP_Yield ); + sqlite3VdbeChangeP5(v, 1); } #endif - tdsqlite3VdbeJumpHere(v, addrInsTop); + sqlite3VdbeJumpHere(v, addrInsTop); } insert_end: @@ -124061,27 +124061,27 @@ insert_end: ** autoincrement tables. */ if( pParse->nested==0 && pParse->pTriggerTab==0 ){ - tdsqlite3AutoincrementEnd(pParse); + sqlite3AutoincrementEnd(pParse); } /* ** Return the number of rows inserted. If this routine is - ** generating code because of a call to tdsqlite3NestedParse(), do not + ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ if( regRowCount ){ - tdsqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); - tdsqlite3VdbeSetNumCols(v, 1); - tdsqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); } insert_cleanup: - tdsqlite3SrcListDelete(db, pTabList); - tdsqlite3ExprListDelete(db, pList); - tdsqlite3UpsertDelete(db, pUpsert); - tdsqlite3SelectDelete(db, pSelect); - tdsqlite3IdListDelete(db, pColumn); - tdsqlite3DbFree(db, aRegIdx); + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pList); + sqlite3UpsertDelete(db, pUpsert); + sqlite3SelectDelete(db, pSelect); + sqlite3IdListDelete(db, pColumn); + sqlite3DbFree(db, aRegIdx); } /* Make sure "isView" and other macros defined above are undefined. Otherwise @@ -124099,12 +124099,12 @@ insert_cleanup: /* ** Meanings of bits in of pWalker->eCode for -** tdsqlite3ExprReferencesUpdatedColumn() +** sqlite3ExprReferencesUpdatedColumn() */ #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ #define CKCNSTRNT_ROWID 0x02 /* CHECK constraint references the ROWID */ -/* This is the Walker callback from tdsqlite3ExprReferencesUpdatedColumn(). +/* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). * Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this ** expression node references any of the ** columns that are being modifed by an UPDATE statement. @@ -124138,7 +124138,7 @@ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ ** the expression uses one or more of columns identified by the second and ** third arguments. */ -SQLITE_PRIVATE int tdsqlite3ExprReferencesUpdatedColumn( +SQLITE_PRIVATE int sqlite3ExprReferencesUpdatedColumn( Expr *pExpr, /* The expression to be checked */ int *aiChng, /* aiChng[x]>=0 if column x changed by the UPDATE */ int chngRowid /* True if UPDATE changes the rowid */ @@ -124148,7 +124148,7 @@ SQLITE_PRIVATE int tdsqlite3ExprReferencesUpdatedColumn( w.eCode = 0; w.xExprCallback = checkConstraintExprNode; w.u.aiCol = aiChng; - tdsqlite3WalkExpr(&w, pExpr); + sqlite3WalkExpr(&w, pExpr); if( !chngRowid ){ testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 ); w.eCode &= ~CKCNSTRNT_ROWID; @@ -124219,12 +124219,12 @@ SQLITE_PRIVATE int tdsqlite3ExprReferencesUpdatedColumn( ** Constraint type Action What Happens ** --------------- ---------- ---------------------------------------- ** any ROLLBACK The current transaction is rolled back and -** tdsqlite3_step() returns immediately with a +** sqlite3_step() returns immediately with a ** return code of SQLITE_CONSTRAINT. ** ** any ABORT Back out changes from the current command ** only (do not do a complete rollback) then -** cause tdsqlite3_step() to return immediately +** cause sqlite3_step() to return immediately ** with SQLITE_CONSTRAINT. ** ** any FAIL Sqlite3_step() returns immediately with a @@ -124251,7 +124251,7 @@ SQLITE_PRIVATE int tdsqlite3ExprReferencesUpdatedColumn( ** is used. Or if pParse->onError==OE_Default then the onError value ** for the constraint is used. */ -SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( +SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( Parse *pParse, /* The parser context */ Table *pTab, /* The table being inserted or updated */ int *aRegIdx, /* Use register aRegIdx[i] for index i. 0 for unused */ @@ -124269,7 +124269,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( Vdbe *v; /* VDBE under constrution */ Index *pIdx; /* Pointer to one of the indices */ Index *pPk = 0; /* The PRIMARY KEY index */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ int i; /* loop counter */ int ix; /* Index loop counter */ int nCol; /* Number of columns */ @@ -124293,7 +124293,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( isUpdate = regOldData!=0; db = pParse->db; - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ nCol = pTab->nCol; @@ -124306,7 +124306,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( pPk = 0; nPkField = 1; }else{ - pPk = tdsqlite3PrimaryKeyIndex(pTab); + pPk = sqlite3PrimaryKeyIndex(pTab); nPkField = pPk->nKeyCol; } @@ -124360,35 +124360,35 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( } assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail || onError==OE_Ignore || onError==OE_Replace ); - testcase( i!=tdsqlite3TableColumnToStorage(pTab, i) ); - iReg = tdsqlite3TableColumnToStorage(pTab, i) + regNewData + 1; + testcase( i!=sqlite3TableColumnToStorage(pTab, i) ); + iReg = sqlite3TableColumnToStorage(pTab, i) + regNewData + 1; switch( onError ){ case OE_Replace: { - int addr1 = tdsqlite3VdbeAddOp1(v, OP_NotNull, iReg); + int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, iReg); VdbeCoverage(v); assert( (pCol->colFlags & COLFLAG_GENERATED)==0 ); nSeenReplace++; - tdsqlite3ExprCode(pParse, pCol->pDflt, iReg); - tdsqlite3VdbeJumpHere(v, addr1); + sqlite3ExprCode(pParse, pCol->pDflt, iReg); + sqlite3VdbeJumpHere(v, addr1); break; } case OE_Abort: - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); /* Fall through */ case OE_Rollback: case OE_Fail: { - char *zMsg = tdsqlite3MPrintf(db, "%s.%s", pTab->zName, + char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName, pCol->zName); - tdsqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, + sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError, iReg); - tdsqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); - tdsqlite3VdbeChangeP5(v, P5_ConstraintNotNull); + sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC); + sqlite3VdbeChangeP5(v, P5_ConstraintNotNull); VdbeCoverage(v); break; } default: { assert( onError==OE_Ignore ); - tdsqlite3VdbeAddOp2(v, OP_IsNull, iReg, ignoreDest); + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, ignoreDest); VdbeCoverage(v); break; } @@ -124408,7 +124408,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** first pass, recomputed values for all generated columns, as ** those values might depend on columns affected by the REPLACE. */ - tdsqlite3ComputeGeneratedColumns(pParse, regNewData+1, pTab); + sqlite3ComputeGeneratedColumns(pParse, regNewData+1, pTab); } #endif } /* end of 2-pass loop */ @@ -124425,26 +124425,26 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( int allOk; Expr *pExpr = pCheck->a[i].pExpr; if( aiChng - && !tdsqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng) + && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng) ){ /* The check constraints do not reference any of the columns being ** updated so there is no point it verifying the check constraint */ continue; } - allOk = tdsqlite3VdbeMakeLabel(pParse); - tdsqlite3VdbeVerifyAbortable(v, onError); - tdsqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL); + allOk = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeVerifyAbortable(v, onError); + sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL); if( onError==OE_Ignore ){ - tdsqlite3VdbeGoto(v, ignoreDest); + sqlite3VdbeGoto(v, ignoreDest); }else{ char *zName = pCheck->a[i].zEName; if( zName==0 ) zName = pTab->zName; if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-26383-51744 */ - tdsqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, + sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK, onError, zName, P4_TRANSIENT, P5_ConstraintCheck); } - tdsqlite3VdbeResolveLabel(v, allOk); + sqlite3VdbeResolveLabel(v, allOk); } pParse->iSelfTab = 0; } @@ -124476,7 +124476,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** ** The ordering of (2) and (3) is accomplished by making sure the linked ** list of indexes attached to a table puts all OE_Replace indexes last - ** in the list. See tdsqlite3CreateIndex() for where that happens. + ** in the list. See sqlite3CreateIndex() for where that happens. */ if( pUpsert ){ @@ -124489,7 +124489,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( }else if( (pUpIdx = pUpsert->pUpsertIdx)!=0 ){ /* If the constraint-target uniqueness check must be run first. ** Jump to that uniqueness check now */ - upsertJump = tdsqlite3VdbeAddOp0(v, OP_Goto); + upsertJump = sqlite3VdbeAddOp0(v, OP_Goto); VdbeComment((v, "UPSERT constraint goes first")); } } @@ -124521,19 +124521,19 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( regTrigCnt = 0; }else{ if( db->flags&SQLITE_RecTriggers ){ - pTrigger = tdsqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); - regTrigCnt = pTrigger!=0 || tdsqlite3FkRequired(pParse, pTab, 0, 0); + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + regTrigCnt = pTrigger!=0 || sqlite3FkRequired(pParse, pTab, 0, 0); }else{ pTrigger = 0; - regTrigCnt = tdsqlite3FkRequired(pParse, pTab, 0, 0); + regTrigCnt = sqlite3FkRequired(pParse, pTab, 0, 0); } if( regTrigCnt ){ /* Replace triggers might exist. Allocate the counter and ** initialize it to zero. */ regTrigCnt = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regTrigCnt); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regTrigCnt); VdbeComment((v, "trigger count")); - lblRecheckOk = tdsqlite3VdbeMakeLabel(pParse); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); addrRecheck = lblRecheckOk; } } @@ -124542,7 +124542,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** exist in the table. */ if( pkChng && pPk==0 ){ - int addrRowidOk = tdsqlite3VdbeMakeLabel(pParse); + int addrRowidOk = sqlite3VdbeMakeLabel(pParse); /* Figure out what action to take in case of a rowid collision */ onError = pTab->keyConf; @@ -124570,7 +124570,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( && onError!=overrideError /* Rules for other contraints are different */ && pTab->pIndex /* There exist other constraints */ ){ - ipkTop = tdsqlite3VdbeAddOp0(v, OP_Goto)+1; + ipkTop = sqlite3VdbeAddOp0(v, OP_Goto)+1; VdbeComment((v, "defer IPK REPLACE until last")); } @@ -124578,16 +124578,16 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( /* pkChng!=0 does not mean that the rowid has changed, only that ** it might have changed. Skip the conflict logic below if the rowid ** is unchanged. */ - tdsqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); - tdsqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRowidOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); } /* Check to see if the new rowid already exists in the table. Skip ** the following conflict logic if it does not. */ VdbeNoopComment((v, "uniqueness check for ROWID")); - tdsqlite3VdbeVerifyAbortable(v, onError); - tdsqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); + sqlite3VdbeVerifyAbortable(v, onError); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRowidOk, regNewData); VdbeCoverage(v); switch( onError ){ @@ -124601,7 +124601,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( testcase( onError==OE_Rollback ); testcase( onError==OE_Abort ); testcase( onError==OE_Fail ); - tdsqlite3RowidConstraint(pParse, onError, pTab); + sqlite3RowidConstraint(pParse, onError, pTab); break; } case OE_Replace: { @@ -124619,7 +124619,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, ** also invoke MultiWrite() to indicate that this VDBE may require ** statement rollback (if the statement is aborted after the delete - ** takes place). Earlier versions called tdsqlite3MultiWrite() regardless, + ** takes place). Earlier versions called sqlite3MultiWrite() regardless, ** but being more selective here allows statements like: ** ** REPLACE INTO t(rowid) VALUES($newrowid) @@ -124628,10 +124628,10 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** table. */ if( regTrigCnt ){ - tdsqlite3MultiWrite(pParse); - tdsqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + sqlite3MultiWrite(pParse); + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regNewData, 1, 0, OE_Replace, 1, -1); - tdsqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ nReplaceTrig++; }else{ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK @@ -124640,12 +124640,12 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** not modify the b-tree. It is more efficient to let the coming ** OP_Insert replace the existing entry than it is to delete the ** existing entry and then insert a new one. */ - tdsqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); - tdsqlite3VdbeAppendP4(v, pTab, P4_TABLE); + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, OPFLAG_ISNOOP); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ if( pTab->pIndex ){ - tdsqlite3MultiWrite(pParse); - tdsqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1); + sqlite3MultiWrite(pParse); + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,-1); } } seenReplace = 1; @@ -124653,20 +124653,20 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( } #ifndef SQLITE_OMIT_UPSERT case OE_Update: { - tdsqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur); + sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, 0, iDataCur); /* Fall through */ } #endif case OE_Ignore: { testcase( onError==OE_Ignore ); - tdsqlite3VdbeGoto(v, ignoreDest); + sqlite3VdbeGoto(v, ignoreDest); break; } } - tdsqlite3VdbeResolveLabel(v, addrRowidOk); + sqlite3VdbeResolveLabel(v, addrRowidOk); if( ipkTop ){ - ipkBottom = tdsqlite3VdbeAddOp0(v, OP_Goto); - tdsqlite3VdbeJumpHere(v, ipkTop-1); + ipkBottom = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, ipkTop-1); } } @@ -124687,14 +124687,14 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( if( aRegIdx[ix]==0 ) continue; /* Skip indices that do not change */ if( pUpIdx==pIdx ){ addrUniqueOk = upsertJump+1; - upsertBypass = tdsqlite3VdbeGoto(v, 0); + upsertBypass = sqlite3VdbeGoto(v, 0); VdbeComment((v, "Skip upsert subroutine")); - tdsqlite3VdbeJumpHere(v, upsertJump); + sqlite3VdbeJumpHere(v, upsertJump); }else{ - addrUniqueOk = tdsqlite3VdbeMakeLabel(pParse); + addrUniqueOk = sqlite3VdbeMakeLabel(pParse); } if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){ - tdsqlite3TableAffinity(v, pTab, regNewData+1); + sqlite3TableAffinity(v, pTab, regNewData+1); bAffinityDone = 1; } VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName)); @@ -124703,9 +124703,9 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( /* Skip partial indices for which the WHERE clause is not true */ if( pIdx->pPartIdxWhere ){ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]); + sqlite3VdbeAddOp2(v, OP_Null, 0, aRegIdx[ix]); pParse->iSelfTab = -(regNewData+1); - tdsqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk, + sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, addrUniqueOk, SQLITE_JUMPIFNULL); pParse->iSelfTab = 0; } @@ -124719,42 +124719,42 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( int x; if( iField==XN_EXPR ){ pParse->iSelfTab = -(regNewData+1); - tdsqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i); + sqlite3ExprCodeCopy(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i); pParse->iSelfTab = 0; VdbeComment((v, "%s column %d", pIdx->zName, i)); }else if( iField==XN_ROWID || iField==pTab->iPKey ){ x = regNewData; - tdsqlite3VdbeAddOp2(v, OP_IntCopy, x, regIdx+i); + sqlite3VdbeAddOp2(v, OP_IntCopy, x, regIdx+i); VdbeComment((v, "rowid")); }else{ - testcase( tdsqlite3TableColumnToStorage(pTab, iField)!=iField ); - x = tdsqlite3TableColumnToStorage(pTab, iField) + regNewData + 1; - tdsqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); + testcase( sqlite3TableColumnToStorage(pTab, iField)!=iField ); + x = sqlite3TableColumnToStorage(pTab, iField) + regNewData + 1; + sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i); VdbeComment((v, "%s", pTab->aCol[iField].zName)); } } - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn, aRegIdx[ix]); VdbeComment((v, "for %s", pIdx->zName)); #ifdef SQLITE_ENABLE_NULL_TRIM if( pIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ - tdsqlite3SetMakeRecordP5(v, pIdx->pTable); + sqlite3SetMakeRecordP5(v, pIdx->pTable); } #endif - tdsqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0); + sqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0); /* In an UPDATE operation, if this index is the PRIMARY KEY index ** of a WITHOUT ROWID table and there has been no change the ** primary key, then no collision is possible. The collision detection ** logic below can all be skipped. */ if( isUpdate && pPk==pIdx && pkChng==0 ){ - tdsqlite3VdbeResolveLabel(v, addrUniqueOk); + sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; } /* Find out what action to take in case there is a uniqueness conflict */ onError = pIdx->onError; if( onError==OE_None ){ - tdsqlite3VdbeResolveLabel(v, addrUniqueOk); + sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; /* pIdx is not a UNIQUE index */ } if( overrideError!=OE_Default ){ @@ -124787,31 +124787,31 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( && pPk==pIdx /* Condition 2 */ && onError==OE_Replace /* Condition 1 */ && ( 0==(db->flags&SQLITE_RecTriggers) || /* Condition 4 */ - 0==tdsqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) + 0==sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0)) && ( 0==(db->flags&SQLITE_ForeignKeys) || /* Condition 5 */ - (0==pTab->pFKey && 0==tdsqlite3FkReferences(pTab))) + (0==pTab->pFKey && 0==sqlite3FkReferences(pTab))) ){ - tdsqlite3VdbeResolveLabel(v, addrUniqueOk); + sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; } #endif /* ifndef SQLITE_ENABLE_PREUPDATE_HOOK */ /* Check to see if the new index entry will be unique */ - tdsqlite3VdbeVerifyAbortable(v, onError); + sqlite3VdbeVerifyAbortable(v, onError); addrConflictCk = - tdsqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, + sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, regIdx, pIdx->nKeyCol); VdbeCoverage(v); /* Generate code to handle collisions */ - regR = (pIdx==pPk) ? regIdx : tdsqlite3GetTempRange(pParse, nPkField); + regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField); if( isUpdate || onError==OE_Replace ){ if( HasRowid(pTab) ){ - tdsqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); + sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR); /* Conflict only if the rowid of the existing index entry ** is different from old-rowid */ if( isUpdate ){ - tdsqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); - tdsqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); } }else{ @@ -124821,8 +124821,8 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( if( pIdx!=pPk ){ for(i=0; inKeyCol; i++){ assert( pPk->aiColumn[i]>=0 ); - x = tdsqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); - tdsqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); + x = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i); VdbeComment((v, "%s.%s", pTab->zName, pTab->aCol[pPk->aiColumn[i]].zName)); } @@ -124835,23 +124835,23 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** For a UNIQUE index, only conflict if the PRIMARY KEY values ** of the matched index row are different from the original PRIMARY ** KEY values of this row before the update. */ - int addrJump = tdsqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; + int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; int op = OP_Ne; int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR); for(i=0; inKeyCol; i++){ - char *p4 = (char*)tdsqlite3LocateCollSeq(pParse, pPk->azColl[i]); + char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); x = pPk->aiColumn[i]; assert( x>=0 ); if( i==(pPk->nKeyCol-1) ){ addrJump = addrUniqueOk; op = OP_Eq; } - x = tdsqlite3TableColumnToStorage(pTab, x); - tdsqlite3VdbeAddOp4(v, op, + x = sqlite3TableColumnToStorage(pTab, x); + sqlite3VdbeAddOp4(v, op, regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ ); - tdsqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverageIf(v, op==OP_Eq); VdbeCoverageIf(v, op==OP_Ne); } @@ -124869,56 +124869,56 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( testcase( onError==OE_Rollback ); testcase( onError==OE_Abort ); testcase( onError==OE_Fail ); - tdsqlite3UniqueConstraint(pParse, onError, pIdx); + sqlite3UniqueConstraint(pParse, onError, pIdx); break; } #ifndef SQLITE_OMIT_UPSERT case OE_Update: { - tdsqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix); + sqlite3UpsertDoUpdate(pParse, pUpsert, pTab, pIdx, iIdxCur+ix); /* Fall through */ } #endif case OE_Ignore: { testcase( onError==OE_Ignore ); - tdsqlite3VdbeGoto(v, ignoreDest); + sqlite3VdbeGoto(v, ignoreDest); break; } default: { int nConflictCk; /* Number of opcodes in conflict check logic */ assert( onError==OE_Replace ); - nConflictCk = tdsqlite3VdbeCurrentAddr(v) - addrConflictCk; + nConflictCk = sqlite3VdbeCurrentAddr(v) - addrConflictCk; assert( nConflictCk>0 ); testcase( nConflictCk>1 ); if( regTrigCnt ){ - tdsqlite3MultiWrite(pParse); + sqlite3MultiWrite(pParse); nReplaceTrig++; } if( pTrigger && isUpdate ){ - tdsqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur); + sqlite3VdbeAddOp1(v, OP_CursorLock, iDataCur); } - tdsqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, + sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, regR, nPkField, 0, OE_Replace, (pIdx==pPk ? ONEPASS_SINGLE : ONEPASS_OFF), iThisCur); if( pTrigger && isUpdate ){ - tdsqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur); + sqlite3VdbeAddOp1(v, OP_CursorUnlock, iDataCur); } if( regTrigCnt ){ int addrBypass; /* Jump destination to bypass recheck logic */ - tdsqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ - addrBypass = tdsqlite3VdbeAddOp0(v, OP_Goto); /* Bypass recheck */ + sqlite3VdbeAddOp2(v, OP_AddImm, regTrigCnt, 1); /* incr trigger cnt */ + addrBypass = sqlite3VdbeAddOp0(v, OP_Goto); /* Bypass recheck */ VdbeComment((v, "bypass recheck")); /* Here we insert code that will be invoked after all constraint ** checks have run, if and only if one or more replace triggers ** fired. */ - tdsqlite3VdbeResolveLabel(v, lblRecheckOk); - lblRecheckOk = tdsqlite3VdbeMakeLabel(pParse); + sqlite3VdbeResolveLabel(v, lblRecheckOk); + lblRecheckOk = sqlite3VdbeMakeLabel(pParse); if( pIdx->pPartIdxWhere ){ /* Bypass the recheck if this partial index is not defined ** for the current row */ - tdsqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk); + sqlite3VdbeAddOp2(v, OP_IsNull, regIdx-1, lblRecheckOk); VdbeCoverage(v); } /* Copy the constraint check code from above, except change @@ -124926,76 +124926,76 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** the next retest block */ while( nConflictCk>0 ){ VdbeOp x; /* Conflict check opcode to copy */ - /* The tdsqlite3VdbeAddOp4() call might reallocate the opcode array. + /* The sqlite3VdbeAddOp4() call might reallocate the opcode array. ** Hence, make a complete copy of the opcode, rather than using ** a pointer to the opcode. */ - x = *tdsqlite3VdbeGetOp(v, addrConflictCk); + x = *sqlite3VdbeGetOp(v, addrConflictCk); if( x.opcode!=OP_IdxRowid ){ int p2; /* New P2 value for copied conflict check opcode */ - if( tdsqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){ + if( sqlite3OpcodeProperty[x.opcode]&OPFLG_JUMP ){ p2 = lblRecheckOk; }else{ p2 = x.p2; } - tdsqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, x.p4.z, x.p4type); - tdsqlite3VdbeChangeP5(v, x.p5); + sqlite3VdbeAddOp4(v, x.opcode, x.p1, p2, x.p3, x.p4.z, x.p4type); + sqlite3VdbeChangeP5(v, x.p5); VdbeCoverageIf(v, p2!=x.p2); } nConflictCk--; addrConflictCk++; } /* If the retest fails, issue an abort */ - tdsqlite3UniqueConstraint(pParse, OE_Abort, pIdx); + sqlite3UniqueConstraint(pParse, OE_Abort, pIdx); - tdsqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */ + sqlite3VdbeJumpHere(v, addrBypass); /* Terminate the recheck bypass */ } seenReplace = 1; break; } } if( pUpIdx==pIdx ){ - tdsqlite3VdbeGoto(v, upsertJump+1); - tdsqlite3VdbeJumpHere(v, upsertBypass); + sqlite3VdbeGoto(v, upsertJump+1); + sqlite3VdbeJumpHere(v, upsertBypass); }else{ - tdsqlite3VdbeResolveLabel(v, addrUniqueOk); + sqlite3VdbeResolveLabel(v, addrUniqueOk); } - if( regR!=regIdx ) tdsqlite3ReleaseTempRange(pParse, regR, nPkField); + if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); } /* If the IPK constraint is a REPLACE, run it last */ if( ipkTop ){ - tdsqlite3VdbeGoto(v, ipkTop); + sqlite3VdbeGoto(v, ipkTop); VdbeComment((v, "Do IPK REPLACE")); - tdsqlite3VdbeJumpHere(v, ipkBottom); + sqlite3VdbeJumpHere(v, ipkBottom); } /* Recheck all uniqueness constraints after replace triggers have run */ testcase( regTrigCnt!=0 && nReplaceTrig==0 ); assert( regTrigCnt!=0 || nReplaceTrig==0 ); if( nReplaceTrig ){ - tdsqlite3VdbeAddOp2(v, OP_IfNot, regTrigCnt, lblRecheckOk);VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IfNot, regTrigCnt, lblRecheckOk);VdbeCoverage(v); if( !pPk ){ if( isUpdate ){ - tdsqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRecheck, regOldData); - tdsqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeAddOp3(v, OP_Eq, regNewData, addrRecheck, regOldData); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); } - tdsqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRecheck, regNewData); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, addrRecheck, regNewData); VdbeCoverage(v); - tdsqlite3RowidConstraint(pParse, OE_Abort, pTab); + sqlite3RowidConstraint(pParse, OE_Abort, pTab); }else{ - tdsqlite3VdbeGoto(v, addrRecheck); + sqlite3VdbeGoto(v, addrRecheck); } - tdsqlite3VdbeResolveLabel(v, lblRecheckOk); + sqlite3VdbeResolveLabel(v, lblRecheckOk); } /* Generate the table record */ if( HasRowid(pTab) ){ int regRec = aRegIdx[ix]; - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec); - tdsqlite3SetMakeRecordP5(v, pTab); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regNewData+1, pTab->nNVCol, regRec); + sqlite3SetMakeRecordP5(v, pTab); if( !bAffinityDone ){ - tdsqlite3TableAffinity(v, pTab, 0); + sqlite3TableAffinity(v, pTab, 0); } } @@ -125010,7 +125010,7 @@ SQLITE_PRIVATE void tdsqlite3GenerateConstraintChecks( ** ** Or if no columns of pTab may be NULL-trimmed, leave P5 at zero. */ -SQLITE_PRIVATE void tdsqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ +SQLITE_PRIVATE void sqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ u16 i; /* Records with omitted columns are only allowed for schema format @@ -125021,20 +125021,20 @@ SQLITE_PRIVATE void tdsqlite3SetMakeRecordP5(Vdbe *v, Table *pTab){ if( pTab->aCol[i].pDflt!=0 ) break; if( pTab->aCol[i].colFlags & COLFLAG_PRIMKEY ) break; } - tdsqlite3VdbeChangeP5(v, i+1); + sqlite3VdbeChangeP5(v, i+1); } #endif /* ** This routine generates code to finish the INSERT or UPDATE operation -** that was started by a prior call to tdsqlite3GenerateConstraintChecks. +** that was started by a prior call to sqlite3GenerateConstraintChecks. ** A consecutive range of registers starting at regNewData contains the ** rowid and the content to be inserted. ** ** The arguments to this routine should be the same as the first six -** arguments to tdsqlite3GenerateConstraintChecks. +** arguments to sqlite3GenerateConstraintChecks. */ -SQLITE_PRIVATE void tdsqlite3CompleteInsertion( +SQLITE_PRIVATE void sqlite3CompleteInsertion( Parse *pParse, /* The parser context */ Table *pTab, /* the table into which we are inserting */ int iDataCur, /* Cursor of the canonical data source */ @@ -125055,7 +125055,7 @@ SQLITE_PRIVATE void tdsqlite3CompleteInsertion( || update_flags==(OPFLAG_ISUPDATE|OPFLAG_SAVEPOSITION) ); - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); assert( v!=0 ); assert( pTab->pSelect==0 ); /* This table is not a VIEW */ for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ @@ -125065,7 +125065,7 @@ SQLITE_PRIVATE void tdsqlite3CompleteInsertion( || pIdx->pNext->onError==OE_Replace ); if( aRegIdx[i]==0 ) continue; if( pIdx->pPartIdxWhere ){ - tdsqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], tdsqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); } pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0); @@ -125075,20 +125075,20 @@ SQLITE_PRIVATE void tdsqlite3CompleteInsertion( pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK if( update_flags==0 ){ - int r = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, r); - tdsqlite3VdbeAddOp4(v, OP_Insert, + int r = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Integer, 0, r); + sqlite3VdbeAddOp4(v, OP_Insert, iIdxCur+i, aRegIdx[i], r, (char*)pTab, P4_TABLE ); - tdsqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); - tdsqlite3ReleaseTempReg(pParse, r); + sqlite3VdbeChangeP5(v, OPFLAG_ISNOOP); + sqlite3ReleaseTempReg(pParse, r); } #endif } - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iIdxCur+i, aRegIdx[i], aRegIdx[i]+1, pIdx->uniqNotNull ? pIdx->nKeyCol: pIdx->nColumn); - tdsqlite3VdbeChangeP5(v, pik_flags); + sqlite3VdbeChangeP5(v, pik_flags); } if( !HasRowid(pTab) ) return; if( pParse->nested ){ @@ -125103,11 +125103,11 @@ SQLITE_PRIVATE void tdsqlite3CompleteInsertion( if( useSeekResult ){ pik_flags |= OPFLAG_USESEEKRESULT; } - tdsqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData); + sqlite3VdbeAddOp3(v, OP_Insert, iDataCur, aRegIdx[i], regNewData); if( !pParse->nested ){ - tdsqlite3VdbeAppendP4(v, pTab, P4_TABLE); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } - tdsqlite3VdbeChangeP5(v, pik_flags); + sqlite3VdbeChangeP5(v, pik_flags); } /* @@ -125131,7 +125131,7 @@ SQLITE_PRIVATE void tdsqlite3CompleteInsertion( ** If pTab is a virtual table, then this routine is a no-op and the ** *piDataCur and *piIdxCur values are left uninitialized. */ -SQLITE_PRIVATE int tdsqlite3OpenTableAndIndices( +SQLITE_PRIVATE int sqlite3OpenTableAndIndices( Parse *pParse, /* Parsing context */ Table *pTab, /* Table to be opened */ int op, /* OP_OpenRead or OP_OpenWrite */ @@ -125155,16 +125155,16 @@ SQLITE_PRIVATE int tdsqlite3OpenTableAndIndices( ** can detect if they are used by mistake in the caller. */ return 0; } - iDb = tdsqlite3SchemaToIndex(pParse->db, pTab->pSchema); - v = tdsqlite3GetVdbe(pParse); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + v = sqlite3GetVdbe(pParse); assert( v!=0 ); if( iBase<0 ) iBase = pParse->nTab; iDataCur = iBase++; if( piDataCur ) *piDataCur = iDataCur; if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ - tdsqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); + sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); }else{ - tdsqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); + sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); } if( piIdxCur ) *piIdxCur = iBase; for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ @@ -125175,9 +125175,9 @@ SQLITE_PRIVATE int tdsqlite3OpenTableAndIndices( p5 = 0; } if( aToOpen==0 || aToOpen[i+1] ){ - tdsqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); - tdsqlite3VdbeSetP4KeyInfo(pParse, pIdx); - tdsqlite3VdbeChangeP5(v, p5); + sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); + sqlite3VdbeChangeP5(v, p5); VdbeComment((v, "%s", pIdx->zName)); } } @@ -125193,7 +125193,7 @@ SQLITE_PRIVATE int tdsqlite3OpenTableAndIndices( ** purposes only - to make sure the transfer optimization really ** is happening when it is supposed to. */ -SQLITE_API int tdsqlite3_xferopt_count; +SQLITE_API int sqlite3_xferopt_count; #endif /* SQLITE_TEST */ @@ -125225,7 +125225,7 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ } if( pSrc->aiColumn[i]==XN_EXPR ){ assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 ); - if( tdsqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr, + if( sqlite3ExprCompare(0, pSrc->aColExpr->a[i].pExpr, pDest->aColExpr->a[i].pExpr, -1)!=0 ){ return 0; /* Different expressions in the index */ } @@ -125233,11 +125233,11 @@ static int xferCompatibleIndex(Index *pDest, Index *pSrc){ if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){ return 0; /* Different sort orders */ } - if( tdsqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){ + if( sqlite3_stricmp(pSrc->azColl[i],pDest->azColl[i])!=0 ){ return 0; /* Different collating sequences */ } } - if( tdsqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){ + if( sqlite3ExprCompare(0, pSrc->pPartIdxWhere, pDest->pPartIdxWhere, -1) ){ return 0; /* Different WHERE clauses */ } @@ -125277,7 +125277,7 @@ static int xferOptimization( int onError, /* How to handle constraint errors */ int iDbDest /* The database of pDest */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; ExprList *pEList; /* The result set of the SELECT */ Table *pSrc; /* The table in the FROM clause of SELECT */ Index *pSrcIdx, *pDestIdx; /* Source and destination indices */ @@ -125302,7 +125302,7 @@ static int xferOptimization( ** error if pSelect reads from a CTE named "xxx". */ return 0; } - if( tdsqlite3TriggerList(pParse, pDest) ){ + if( sqlite3TriggerList(pParse, pDest) ){ return 0; /* tab1 must not have triggers */ } #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -125356,7 +125356,7 @@ static int xferOptimization( ** we have to check the semantics. */ pItem = pSelect->pSrc->a; - pSrc = tdsqlite3LocateTableItem(pParse, 0, pItem); + pSrc = sqlite3LocateTableItem(pParse, 0, pItem); if( pSrc==0 ){ return 0; /* FROM clause does not contain a real table */ } @@ -125417,7 +125417,7 @@ static int xferOptimization( ** This requirement could be relaxed for VIRTUAL columns, I suppose. */ if( (pDestCol->colFlags & COLFLAG_GENERATED)!=0 ){ - if( tdsqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){ + if( sqlite3ExprCompare(0, pSrcCol->pDflt, pDestCol->pDflt, -1)!=0 ){ testcase( pDestCol->colFlags & COLFLAG_VIRTUAL ); testcase( pDestCol->colFlags & COLFLAG_STORED ); return 0; /* Different generator expressions */ @@ -125427,7 +125427,7 @@ static int xferOptimization( if( pDestCol->affinity!=pSrcCol->affinity ){ return 0; /* Affinity must be the same on all columns */ } - if( tdsqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){ + if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){ return 0; /* Collating sequence must be the same on all columns */ } if( pDestCol->notNull && !pSrcCol->notNull ){ @@ -125456,15 +125456,15 @@ static int xferOptimization( return 0; /* pDestIdx has no corresponding index in pSrc */ } if( pSrcIdx->tnum==pDestIdx->tnum && pSrc->pSchema==pDest->pSchema - && tdsqlite3FaultSim(411)==SQLITE_OK ){ - /* The tdsqlite3FaultSim() call allows this corruption test to be + && sqlite3FaultSim(411)==SQLITE_OK ){ + /* The sqlite3FaultSim() call allows this corruption test to be ** bypassed during testing, in order to exercise other corruption tests ** further downstream. */ return 0; /* Corrupt schema - two indexes on the same btree */ } } #ifndef SQLITE_OMIT_CHECK - if( pDest->pCheck && tdsqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ + if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){ return 0; /* Tables have different CHECK constraints. Ticket #2252 */ } #endif @@ -125489,17 +125489,17 @@ static int xferOptimization( ** table (tab1) is initially empty. */ #ifdef SQLITE_TEST - tdsqlite3_xferopt_count++; + sqlite3_xferopt_count++; #endif - iDbSrc = tdsqlite3SchemaToIndex(db, pSrc->pSchema); - v = tdsqlite3GetVdbe(pParse); - tdsqlite3CodeVerifySchema(pParse, iDbSrc); + iDbSrc = sqlite3SchemaToIndex(db, pSrc->pSchema); + v = sqlite3GetVdbe(pParse); + sqlite3CodeVerifySchema(pParse, iDbSrc); iSrc = pParse->nTab++; iDest = pParse->nTab++; regAutoinc = autoIncBegin(pParse, iDbDest, pDest); - regData = tdsqlite3GetTempReg(pParse); - regRowid = tdsqlite3GetTempReg(pParse); - tdsqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); + regData = sqlite3GetTempReg(pParse); + regRowid = sqlite3GetTempReg(pParse); + sqlite3OpenTable(pParse, iDest, iDbDest, pDest, OP_OpenWrite); assert( HasRowid(pDest) || destHasUniqueIdx ); if( (db->mDbFlags & DBFLAG_Vacuum)==0 && ( (pDest->iPKey<0 && pDest->pIndex!=0) /* (1) */ @@ -125523,45 +125523,45 @@ static int xferOptimization( ** ** (3) onError is something other than OE_Abort and OE_Rollback. */ - addr1 = tdsqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v); - emptyDestTest = tdsqlite3VdbeAddOp0(v, OP_Goto); - tdsqlite3VdbeJumpHere(v, addr1); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iDest, 0); VdbeCoverage(v); + emptyDestTest = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, addr1); } if( HasRowid(pSrc) ){ u8 insFlags; - tdsqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); - emptySrcTest = tdsqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); + sqlite3OpenTable(pParse, iSrc, iDbSrc, pSrc, OP_OpenRead); + emptySrcTest = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); if( pDest->iPKey>=0 ){ - addr1 = tdsqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); - tdsqlite3VdbeVerifyAbortable(v, onError); - addr2 = tdsqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + sqlite3VdbeVerifyAbortable(v, onError); + addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); VdbeCoverage(v); - tdsqlite3RowidConstraint(pParse, onError, pDest); - tdsqlite3VdbeJumpHere(v, addr2); + sqlite3RowidConstraint(pParse, onError, pDest); + sqlite3VdbeJumpHere(v, addr2); autoIncStep(pParse, regAutoinc, regRowid); }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){ - addr1 = tdsqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); + addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid); }else{ - addr1 = tdsqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); + addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); assert( (pDest->tabFlags & TF_Autoincrement)==0 ); } - tdsqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); if( db->mDbFlags & DBFLAG_Vacuum ){ - tdsqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID| OPFLAG_APPEND|OPFLAG_USESEEKRESULT; }else{ insFlags = OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND; } - tdsqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, + sqlite3VdbeAddOp4(v, OP_Insert, iDest, regData, regRowid, (char*)pDest, P4_TABLE); - tdsqlite3VdbeChangeP5(v, insFlags); - tdsqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); - tdsqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); - tdsqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + sqlite3VdbeChangeP5(v, insFlags); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); }else{ - tdsqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName); - tdsqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName); + sqlite3TableLock(pParse, iDbDest, pDest->tnum, 1, pDest->zName); + sqlite3TableLock(pParse, iDbSrc, pSrc->tnum, 0, pSrc->zName); } for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ u8 idxInsFlags = 0; @@ -125569,15 +125569,15 @@ static int xferOptimization( if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; } assert( pSrcIdx ); - tdsqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc); - tdsqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx); + sqlite3VdbeAddOp3(v, OP_OpenRead, iSrc, pSrcIdx->tnum, iDbSrc); + sqlite3VdbeSetP4KeyInfo(pParse, pSrcIdx); VdbeComment((v, "%s", pSrcIdx->zName)); - tdsqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest); - tdsqlite3VdbeSetP4KeyInfo(pParse, pDestIdx); - tdsqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); + sqlite3VdbeAddOp3(v, OP_OpenWrite, iDest, pDestIdx->tnum, iDbDest); + sqlite3VdbeSetP4KeyInfo(pParse, pDestIdx); + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR); VdbeComment((v, "%s", pDestIdx->zName)); - addr1 = tdsqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); + addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iSrc, 0); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); if( db->mDbFlags & DBFLAG_Vacuum ){ /* This INSERT command is part of a VACUUM operation, which guarantees ** that the destination table is empty. If all indexed columns use @@ -125595,31 +125595,31 @@ static int xferOptimization( ** sorted order. */ for(i=0; inColumn; i++){ const char *zColl = pSrcIdx->azColl[i]; - if( tdsqlite3_stricmp(tdsqlite3StrBINARY, zColl) ) break; + if( sqlite3_stricmp(sqlite3StrBINARY, zColl) ) break; } if( i==pSrcIdx->nColumn ){ idxInsFlags = OPFLAG_USESEEKRESULT; - tdsqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); + sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest); } } if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){ idxInsFlags |= OPFLAG_NCHANGE; } - tdsqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); - tdsqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); - tdsqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addr1); - tdsqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); - tdsqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData); + sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND); + sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); } - if( emptySrcTest ) tdsqlite3VdbeJumpHere(v, emptySrcTest); - tdsqlite3ReleaseTempReg(pParse, regRowid); - tdsqlite3ReleaseTempReg(pParse, regData); + if( emptySrcTest ) sqlite3VdbeJumpHere(v, emptySrcTest); + sqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regData); if( emptyDestTest ){ - tdsqlite3AutoincrementEnd(pParse); - tdsqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0); - tdsqlite3VdbeJumpHere(v, emptyDestTest); - tdsqlite3VdbeAddOp2(v, OP_Close, iDest, 0); + sqlite3AutoincrementEnd(pParse); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_OK, 0); + sqlite3VdbeJumpHere(v, emptyDestTest); + sqlite3VdbeAddOp2(v, OP_Close, iDest, 0); return 0; }else{ return 1; @@ -125658,30 +125658,30 @@ static int xferOptimization( ** argument to xCallback(). If xCallback=NULL then no callback ** is invoked, even for queries. */ -SQLITE_API int tdsqlite3_exec( - tdsqlite3 *db, /* The database on which the SQL executes */ +SQLITE_API int sqlite3_exec( + sqlite3 *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ - tdsqlite3_callback xCallback, /* Invoke this callback routine */ + sqlite3_callback xCallback, /* Invoke this callback routine */ void *pArg, /* First argument to xCallback() */ char **pzErrMsg /* Write error messages here */ ){ int rc = SQLITE_OK; /* Return code */ const char *zLeftover; /* Tail of unprocessed SQL */ - tdsqlite3_stmt *pStmt = 0; /* The current SQL statement */ + sqlite3_stmt *pStmt = 0; /* The current SQL statement */ char **azCols = 0; /* Names of result columns */ int callbackIsInit; /* True if callback data is initialized */ - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; if( zSql==0 ) zSql = ""; - tdsqlite3_mutex_enter(db->mutex); - tdsqlite3Error(db, SQLITE_OK); + sqlite3_mutex_enter(db->mutex); + sqlite3Error(db, SQLITE_OK); while( rc==SQLITE_OK && zSql[0] ){ int nCol = 0; char **azVals = 0; pStmt = 0; - rc = tdsqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover); assert( rc==SQLITE_OK || pStmt==0 ); if( rc!=SQLITE_OK ){ continue; @@ -125695,22 +125695,22 @@ SQLITE_API int tdsqlite3_exec( while( 1 ){ int i; - rc = tdsqlite3_step(pStmt); + rc = sqlite3_step(pStmt); /* Invoke the callback function if required */ if( xCallback && (SQLITE_ROW==rc || (SQLITE_DONE==rc && !callbackIsInit && db->flags&SQLITE_NullCallback)) ){ if( !callbackIsInit ){ - nCol = tdsqlite3_column_count(pStmt); - azCols = tdsqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*)); + nCol = sqlite3_column_count(pStmt); + azCols = sqlite3DbMallocRaw(db, (2*nCol+1)*sizeof(const char*)); if( azCols==0 ){ goto exec_out; } for(i=0; ierrMask)==rc ); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -125789,10 +125789,10 @@ exec_out: */ #ifndef SQLITE_CORE - #define SQLITE_CORE 1 /* Disable the API redefinition in tdsqlite3ext.h */ + #define SQLITE_CORE 1 /* Disable the API redefinition in sqlite3ext.h */ #endif -/************** Include tdsqlite3ext.h in the middle of loadext.c **************/ -/************** Begin file tdsqlite3ext.h **************************************/ +/************** Include sqlite3ext.h in the middle of loadext.c **************/ +/************** Begin file sqlite3ext.h **************************************/ /* ** 2006 June 7 ** @@ -125824,303 +125824,303 @@ exec_out: ** versions of SQLite will not be able to load each other's shared ** libraries! */ -struct tdsqlite3_api_routines { - void * (*aggregate_context)(tdsqlite3_context*,int nBytes); - int (*aggregate_count)(tdsqlite3_context*); - int (*bind_blob)(tdsqlite3_stmt*,int,const void*,int n,void(*)(void*)); - int (*bind_double)(tdsqlite3_stmt*,int,double); - int (*bind_int)(tdsqlite3_stmt*,int,int); - int (*bind_int64)(tdsqlite3_stmt*,int,sqlite_int64); - int (*bind_null)(tdsqlite3_stmt*,int); - int (*bind_parameter_count)(tdsqlite3_stmt*); - int (*bind_parameter_index)(tdsqlite3_stmt*,const char*zName); - const char * (*bind_parameter_name)(tdsqlite3_stmt*,int); - int (*bind_text)(tdsqlite3_stmt*,int,const char*,int n,void(*)(void*)); - int (*bind_text16)(tdsqlite3_stmt*,int,const void*,int,void(*)(void*)); - int (*bind_value)(tdsqlite3_stmt*,int,const tdsqlite3_value*); - int (*busy_handler)(tdsqlite3*,int(*)(void*,int),void*); - int (*busy_timeout)(tdsqlite3*,int ms); - int (*changes)(tdsqlite3*); - int (*close)(tdsqlite3*); - int (*collation_needed)(tdsqlite3*,void*,void(*)(void*,tdsqlite3*, +struct sqlite3_api_routines { + void * (*aggregate_context)(sqlite3_context*,int nBytes); + int (*aggregate_count)(sqlite3_context*); + int (*bind_blob)(sqlite3_stmt*,int,const void*,int n,void(*)(void*)); + int (*bind_double)(sqlite3_stmt*,int,double); + int (*bind_int)(sqlite3_stmt*,int,int); + int (*bind_int64)(sqlite3_stmt*,int,sqlite_int64); + int (*bind_null)(sqlite3_stmt*,int); + int (*bind_parameter_count)(sqlite3_stmt*); + int (*bind_parameter_index)(sqlite3_stmt*,const char*zName); + const char * (*bind_parameter_name)(sqlite3_stmt*,int); + int (*bind_text)(sqlite3_stmt*,int,const char*,int n,void(*)(void*)); + int (*bind_text16)(sqlite3_stmt*,int,const void*,int,void(*)(void*)); + int (*bind_value)(sqlite3_stmt*,int,const sqlite3_value*); + int (*busy_handler)(sqlite3*,int(*)(void*,int),void*); + int (*busy_timeout)(sqlite3*,int ms); + int (*changes)(sqlite3*); + int (*close)(sqlite3*); + int (*collation_needed)(sqlite3*,void*,void(*)(void*,sqlite3*, int eTextRep,const char*)); - int (*collation_needed16)(tdsqlite3*,void*,void(*)(void*,tdsqlite3*, + int (*collation_needed16)(sqlite3*,void*,void(*)(void*,sqlite3*, int eTextRep,const void*)); - const void * (*column_blob)(tdsqlite3_stmt*,int iCol); - int (*column_bytes)(tdsqlite3_stmt*,int iCol); - int (*column_bytes16)(tdsqlite3_stmt*,int iCol); - int (*column_count)(tdsqlite3_stmt*pStmt); - const char * (*column_database_name)(tdsqlite3_stmt*,int); - const void * (*column_database_name16)(tdsqlite3_stmt*,int); - const char * (*column_decltype)(tdsqlite3_stmt*,int i); - const void * (*column_decltype16)(tdsqlite3_stmt*,int); - double (*column_double)(tdsqlite3_stmt*,int iCol); - int (*column_int)(tdsqlite3_stmt*,int iCol); - sqlite_int64 (*column_int64)(tdsqlite3_stmt*,int iCol); - const char * (*column_name)(tdsqlite3_stmt*,int); - const void * (*column_name16)(tdsqlite3_stmt*,int); - const char * (*column_origin_name)(tdsqlite3_stmt*,int); - const void * (*column_origin_name16)(tdsqlite3_stmt*,int); - const char * (*column_table_name)(tdsqlite3_stmt*,int); - const void * (*column_table_name16)(tdsqlite3_stmt*,int); - const unsigned char * (*column_text)(tdsqlite3_stmt*,int iCol); - const void * (*column_text16)(tdsqlite3_stmt*,int iCol); - int (*column_type)(tdsqlite3_stmt*,int iCol); - tdsqlite3_value* (*column_value)(tdsqlite3_stmt*,int iCol); - void * (*commit_hook)(tdsqlite3*,int(*)(void*),void*); + const void * (*column_blob)(sqlite3_stmt*,int iCol); + int (*column_bytes)(sqlite3_stmt*,int iCol); + int (*column_bytes16)(sqlite3_stmt*,int iCol); + int (*column_count)(sqlite3_stmt*pStmt); + const char * (*column_database_name)(sqlite3_stmt*,int); + const void * (*column_database_name16)(sqlite3_stmt*,int); + const char * (*column_decltype)(sqlite3_stmt*,int i); + const void * (*column_decltype16)(sqlite3_stmt*,int); + double (*column_double)(sqlite3_stmt*,int iCol); + int (*column_int)(sqlite3_stmt*,int iCol); + sqlite_int64 (*column_int64)(sqlite3_stmt*,int iCol); + const char * (*column_name)(sqlite3_stmt*,int); + const void * (*column_name16)(sqlite3_stmt*,int); + const char * (*column_origin_name)(sqlite3_stmt*,int); + const void * (*column_origin_name16)(sqlite3_stmt*,int); + const char * (*column_table_name)(sqlite3_stmt*,int); + const void * (*column_table_name16)(sqlite3_stmt*,int); + const unsigned char * (*column_text)(sqlite3_stmt*,int iCol); + const void * (*column_text16)(sqlite3_stmt*,int iCol); + int (*column_type)(sqlite3_stmt*,int iCol); + sqlite3_value* (*column_value)(sqlite3_stmt*,int iCol); + void * (*commit_hook)(sqlite3*,int(*)(void*),void*); int (*complete)(const char*sql); int (*complete16)(const void*sql); - int (*create_collation)(tdsqlite3*,const char*,int,void*, + int (*create_collation)(sqlite3*,const char*,int,void*, int(*)(void*,int,const void*,int,const void*)); - int (*create_collation16)(tdsqlite3*,const void*,int,void*, + int (*create_collation16)(sqlite3*,const void*,int,void*, int(*)(void*,int,const void*,int,const void*)); - int (*create_function)(tdsqlite3*,const char*,int,int,void*, - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*)); - int (*create_function16)(tdsqlite3*,const void*,int,int,void*, - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*)); - int (*create_module)(tdsqlite3*,const char*,const tdsqlite3_module*,void*); - int (*data_count)(tdsqlite3_stmt*pStmt); - tdsqlite3 * (*db_handle)(tdsqlite3_stmt*); - int (*declare_vtab)(tdsqlite3*,const char*); + int (*create_function)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_function16)(sqlite3*,const void*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*)); + int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*); + int (*data_count)(sqlite3_stmt*pStmt); + sqlite3 * (*db_handle)(sqlite3_stmt*); + int (*declare_vtab)(sqlite3*,const char*); int (*enable_shared_cache)(int); - int (*errcode)(tdsqlite3*db); - const char * (*errmsg)(tdsqlite3*); - const void * (*errmsg16)(tdsqlite3*); - int (*exec)(tdsqlite3*,const char*,tdsqlite3_callback,void*,char**); - int (*expired)(tdsqlite3_stmt*); - int (*finalize)(tdsqlite3_stmt*pStmt); + int (*errcode)(sqlite3*db); + const char * (*errmsg)(sqlite3*); + const void * (*errmsg16)(sqlite3*); + int (*exec)(sqlite3*,const char*,sqlite3_callback,void*,char**); + int (*expired)(sqlite3_stmt*); + int (*finalize)(sqlite3_stmt*pStmt); void (*free)(void*); void (*free_table)(char**result); - int (*get_autocommit)(tdsqlite3*); - void * (*get_auxdata)(tdsqlite3_context*,int); - int (*get_table)(tdsqlite3*,const char*,char***,int*,int*,char**); + int (*get_autocommit)(sqlite3*); + void * (*get_auxdata)(sqlite3_context*,int); + int (*get_table)(sqlite3*,const char*,char***,int*,int*,char**); int (*global_recover)(void); - void (*interruptx)(tdsqlite3*); - sqlite_int64 (*last_insert_rowid)(tdsqlite3*); + void (*interruptx)(sqlite3*); + sqlite_int64 (*last_insert_rowid)(sqlite3*); const char * (*libversion)(void); int (*libversion_number)(void); void *(*malloc)(int); char * (*mprintf)(const char*,...); - int (*open)(const char*,tdsqlite3**); - int (*open16)(const void*,tdsqlite3**); - int (*prepare)(tdsqlite3*,const char*,int,tdsqlite3_stmt**,const char**); - int (*prepare16)(tdsqlite3*,const void*,int,tdsqlite3_stmt**,const void**); - void * (*profile)(tdsqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); - void (*progress_handler)(tdsqlite3*,int,int(*)(void*),void*); + int (*open)(const char*,sqlite3**); + int (*open16)(const void*,sqlite3**); + int (*prepare)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + void * (*profile)(sqlite3*,void(*)(void*,const char*,sqlite_uint64),void*); + void (*progress_handler)(sqlite3*,int,int(*)(void*),void*); void *(*realloc)(void*,int); - int (*reset)(tdsqlite3_stmt*pStmt); - void (*result_blob)(tdsqlite3_context*,const void*,int,void(*)(void*)); - void (*result_double)(tdsqlite3_context*,double); - void (*result_error)(tdsqlite3_context*,const char*,int); - void (*result_error16)(tdsqlite3_context*,const void*,int); - void (*result_int)(tdsqlite3_context*,int); - void (*result_int64)(tdsqlite3_context*,sqlite_int64); - void (*result_null)(tdsqlite3_context*); - void (*result_text)(tdsqlite3_context*,const char*,int,void(*)(void*)); - void (*result_text16)(tdsqlite3_context*,const void*,int,void(*)(void*)); - void (*result_text16be)(tdsqlite3_context*,const void*,int,void(*)(void*)); - void (*result_text16le)(tdsqlite3_context*,const void*,int,void(*)(void*)); - void (*result_value)(tdsqlite3_context*,tdsqlite3_value*); - void * (*rollback_hook)(tdsqlite3*,void(*)(void*),void*); - int (*set_authorizer)(tdsqlite3*,int(*)(void*,int,const char*,const char*, + int (*reset)(sqlite3_stmt*pStmt); + void (*result_blob)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_double)(sqlite3_context*,double); + void (*result_error)(sqlite3_context*,const char*,int); + void (*result_error16)(sqlite3_context*,const void*,int); + void (*result_int)(sqlite3_context*,int); + void (*result_int64)(sqlite3_context*,sqlite_int64); + void (*result_null)(sqlite3_context*); + void (*result_text)(sqlite3_context*,const char*,int,void(*)(void*)); + void (*result_text16)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*)); + void (*result_value)(sqlite3_context*,sqlite3_value*); + void * (*rollback_hook)(sqlite3*,void(*)(void*),void*); + int (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*, const char*,const char*),void*); - void (*set_auxdata)(tdsqlite3_context*,int,void*,void (*)(void*)); + void (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*)); char * (*xsnprintf)(int,char*,const char*,...); - int (*step)(tdsqlite3_stmt*); - int (*table_column_metadata)(tdsqlite3*,const char*,const char*,const char*, + int (*step)(sqlite3_stmt*); + int (*table_column_metadata)(sqlite3*,const char*,const char*,const char*, char const**,char const**,int*,int*,int*); void (*thread_cleanup)(void); - int (*total_changes)(tdsqlite3*); - void * (*trace)(tdsqlite3*,void(*xTrace)(void*,const char*),void*); - int (*transfer_bindings)(tdsqlite3_stmt*,tdsqlite3_stmt*); - void * (*update_hook)(tdsqlite3*,void(*)(void*,int ,char const*,char const*, + int (*total_changes)(sqlite3*); + void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*); + int (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*); + void * (*update_hook)(sqlite3*,void(*)(void*,int ,char const*,char const*, sqlite_int64),void*); - void * (*user_data)(tdsqlite3_context*); - const void * (*value_blob)(tdsqlite3_value*); - int (*value_bytes)(tdsqlite3_value*); - int (*value_bytes16)(tdsqlite3_value*); - double (*value_double)(tdsqlite3_value*); - int (*value_int)(tdsqlite3_value*); - sqlite_int64 (*value_int64)(tdsqlite3_value*); - int (*value_numeric_type)(tdsqlite3_value*); - const unsigned char * (*value_text)(tdsqlite3_value*); - const void * (*value_text16)(tdsqlite3_value*); - const void * (*value_text16be)(tdsqlite3_value*); - const void * (*value_text16le)(tdsqlite3_value*); - int (*value_type)(tdsqlite3_value*); + void * (*user_data)(sqlite3_context*); + const void * (*value_blob)(sqlite3_value*); + int (*value_bytes)(sqlite3_value*); + int (*value_bytes16)(sqlite3_value*); + double (*value_double)(sqlite3_value*); + int (*value_int)(sqlite3_value*); + sqlite_int64 (*value_int64)(sqlite3_value*); + int (*value_numeric_type)(sqlite3_value*); + const unsigned char * (*value_text)(sqlite3_value*); + const void * (*value_text16)(sqlite3_value*); + const void * (*value_text16be)(sqlite3_value*); + const void * (*value_text16le)(sqlite3_value*); + int (*value_type)(sqlite3_value*); char *(*vmprintf)(const char*,va_list); /* Added ??? */ - int (*overload_function)(tdsqlite3*, const char *zFuncName, int nArg); + int (*overload_function)(sqlite3*, const char *zFuncName, int nArg); /* Added by 3.3.13 */ - int (*prepare_v2)(tdsqlite3*,const char*,int,tdsqlite3_stmt**,const char**); - int (*prepare16_v2)(tdsqlite3*,const void*,int,tdsqlite3_stmt**,const void**); - int (*clear_bindings)(tdsqlite3_stmt*); + int (*prepare_v2)(sqlite3*,const char*,int,sqlite3_stmt**,const char**); + int (*prepare16_v2)(sqlite3*,const void*,int,sqlite3_stmt**,const void**); + int (*clear_bindings)(sqlite3_stmt*); /* Added by 3.4.1 */ - int (*create_module_v2)(tdsqlite3*,const char*,const tdsqlite3_module*,void*, + int (*create_module_v2)(sqlite3*,const char*,const sqlite3_module*,void*, void (*xDestroy)(void *)); /* Added by 3.5.0 */ - int (*bind_zeroblob)(tdsqlite3_stmt*,int,int); - int (*blob_bytes)(tdsqlite3_blob*); - int (*blob_close)(tdsqlite3_blob*); - int (*blob_open)(tdsqlite3*,const char*,const char*,const char*,tdsqlite3_int64, - int,tdsqlite3_blob**); - int (*blob_read)(tdsqlite3_blob*,void*,int,int); - int (*blob_write)(tdsqlite3_blob*,const void*,int,int); - int (*create_collation_v2)(tdsqlite3*,const char*,int,void*, + int (*bind_zeroblob)(sqlite3_stmt*,int,int); + int (*blob_bytes)(sqlite3_blob*); + int (*blob_close)(sqlite3_blob*); + int (*blob_open)(sqlite3*,const char*,const char*,const char*,sqlite3_int64, + int,sqlite3_blob**); + int (*blob_read)(sqlite3_blob*,void*,int,int); + int (*blob_write)(sqlite3_blob*,const void*,int,int); + int (*create_collation_v2)(sqlite3*,const char*,int,void*, int(*)(void*,int,const void*,int,const void*), void(*)(void*)); - int (*file_control)(tdsqlite3*,const char*,int,void*); - tdsqlite3_int64 (*memory_highwater)(int); - tdsqlite3_int64 (*memory_used)(void); - tdsqlite3_mutex *(*mutex_alloc)(int); - void (*mutex_enter)(tdsqlite3_mutex*); - void (*mutex_free)(tdsqlite3_mutex*); - void (*mutex_leave)(tdsqlite3_mutex*); - int (*mutex_try)(tdsqlite3_mutex*); - int (*open_v2)(const char*,tdsqlite3**,int,const char*); + int (*file_control)(sqlite3*,const char*,int,void*); + sqlite3_int64 (*memory_highwater)(int); + sqlite3_int64 (*memory_used)(void); + sqlite3_mutex *(*mutex_alloc)(int); + void (*mutex_enter)(sqlite3_mutex*); + void (*mutex_free)(sqlite3_mutex*); + void (*mutex_leave)(sqlite3_mutex*); + int (*mutex_try)(sqlite3_mutex*); + int (*open_v2)(const char*,sqlite3**,int,const char*); int (*release_memory)(int); - void (*result_error_nomem)(tdsqlite3_context*); - void (*result_error_toobig)(tdsqlite3_context*); + void (*result_error_nomem)(sqlite3_context*); + void (*result_error_toobig)(sqlite3_context*); int (*sleep)(int); void (*soft_heap_limit)(int); - tdsqlite3_vfs *(*vfs_find)(const char*); - int (*vfs_register)(tdsqlite3_vfs*,int); - int (*vfs_unregister)(tdsqlite3_vfs*); + sqlite3_vfs *(*vfs_find)(const char*); + int (*vfs_register)(sqlite3_vfs*,int); + int (*vfs_unregister)(sqlite3_vfs*); int (*xthreadsafe)(void); - void (*result_zeroblob)(tdsqlite3_context*,int); - void (*result_error_code)(tdsqlite3_context*,int); + void (*result_zeroblob)(sqlite3_context*,int); + void (*result_error_code)(sqlite3_context*,int); int (*test_control)(int, ...); void (*randomness)(int,void*); - tdsqlite3 *(*context_db_handle)(tdsqlite3_context*); - int (*extended_result_codes)(tdsqlite3*,int); - int (*limit)(tdsqlite3*,int,int); - tdsqlite3_stmt *(*next_stmt)(tdsqlite3*,tdsqlite3_stmt*); - const char *(*sql)(tdsqlite3_stmt*); + sqlite3 *(*context_db_handle)(sqlite3_context*); + int (*extended_result_codes)(sqlite3*,int); + int (*limit)(sqlite3*,int,int); + sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*); + const char *(*sql)(sqlite3_stmt*); int (*status)(int,int*,int*,int); - int (*backup_finish)(tdsqlite3_backup*); - tdsqlite3_backup *(*backup_init)(tdsqlite3*,const char*,tdsqlite3*,const char*); - int (*backup_pagecount)(tdsqlite3_backup*); - int (*backup_remaining)(tdsqlite3_backup*); - int (*backup_step)(tdsqlite3_backup*,int); + int (*backup_finish)(sqlite3_backup*); + sqlite3_backup *(*backup_init)(sqlite3*,const char*,sqlite3*,const char*); + int (*backup_pagecount)(sqlite3_backup*); + int (*backup_remaining)(sqlite3_backup*); + int (*backup_step)(sqlite3_backup*,int); const char *(*compileoption_get)(int); int (*compileoption_used)(const char*); - int (*create_function_v2)(tdsqlite3*,const char*,int,int,void*, - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*), + int (*create_function_v2)(sqlite3*,const char*,int,int,void*, + void (*xFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), void(*xDestroy)(void*)); - int (*db_config)(tdsqlite3*,int,...); - tdsqlite3_mutex *(*db_mutex)(tdsqlite3*); - int (*db_status)(tdsqlite3*,int,int*,int*,int); - int (*extended_errcode)(tdsqlite3*); + int (*db_config)(sqlite3*,int,...); + sqlite3_mutex *(*db_mutex)(sqlite3*); + int (*db_status)(sqlite3*,int,int*,int*,int); + int (*extended_errcode)(sqlite3*); void (*log)(int,const char*,...); - tdsqlite3_int64 (*soft_heap_limit64)(tdsqlite3_int64); + sqlite3_int64 (*soft_heap_limit64)(sqlite3_int64); const char *(*sourceid)(void); - int (*stmt_status)(tdsqlite3_stmt*,int,int); + int (*stmt_status)(sqlite3_stmt*,int,int); int (*strnicmp)(const char*,const char*,int); - int (*unlock_notify)(tdsqlite3*,void(*)(void**,int),void*); - int (*wal_autocheckpoint)(tdsqlite3*,int); - int (*wal_checkpoint)(tdsqlite3*,const char*); - void *(*wal_hook)(tdsqlite3*,int(*)(void*,tdsqlite3*,const char*,int),void*); - int (*blob_reopen)(tdsqlite3_blob*,tdsqlite3_int64); - int (*vtab_config)(tdsqlite3*,int op,...); - int (*vtab_on_conflict)(tdsqlite3*); + int (*unlock_notify)(sqlite3*,void(*)(void**,int),void*); + int (*wal_autocheckpoint)(sqlite3*,int); + int (*wal_checkpoint)(sqlite3*,const char*); + void *(*wal_hook)(sqlite3*,int(*)(void*,sqlite3*,const char*,int),void*); + int (*blob_reopen)(sqlite3_blob*,sqlite3_int64); + int (*vtab_config)(sqlite3*,int op,...); + int (*vtab_on_conflict)(sqlite3*); /* Version 3.7.16 and later */ - int (*close_v2)(tdsqlite3*); - const char *(*db_filename)(tdsqlite3*,const char*); - int (*db_readonly)(tdsqlite3*,const char*); - int (*db_release_memory)(tdsqlite3*); + int (*close_v2)(sqlite3*); + const char *(*db_filename)(sqlite3*,const char*); + int (*db_readonly)(sqlite3*,const char*); + int (*db_release_memory)(sqlite3*); const char *(*errstr)(int); - int (*stmt_busy)(tdsqlite3_stmt*); - int (*stmt_readonly)(tdsqlite3_stmt*); + int (*stmt_busy)(sqlite3_stmt*); + int (*stmt_readonly)(sqlite3_stmt*); int (*stricmp)(const char*,const char*); int (*uri_boolean)(const char*,const char*,int); - tdsqlite3_int64 (*uri_int64)(const char*,const char*,tdsqlite3_int64); + sqlite3_int64 (*uri_int64)(const char*,const char*,sqlite3_int64); const char *(*uri_parameter)(const char*,const char*); char *(*xvsnprintf)(int,char*,const char*,va_list); - int (*wal_checkpoint_v2)(tdsqlite3*,const char*,int,int*,int*); + int (*wal_checkpoint_v2)(sqlite3*,const char*,int,int*,int*); /* Version 3.8.7 and later */ int (*auto_extension)(void(*)(void)); - int (*bind_blob64)(tdsqlite3_stmt*,int,const void*,tdsqlite3_uint64, + int (*bind_blob64)(sqlite3_stmt*,int,const void*,sqlite3_uint64, void(*)(void*)); - int (*bind_text64)(tdsqlite3_stmt*,int,const char*,tdsqlite3_uint64, + int (*bind_text64)(sqlite3_stmt*,int,const char*,sqlite3_uint64, void(*)(void*),unsigned char); int (*cancel_auto_extension)(void(*)(void)); - int (*load_extension)(tdsqlite3*,const char*,const char*,char**); - void *(*malloc64)(tdsqlite3_uint64); - tdsqlite3_uint64 (*msize)(void*); - void *(*realloc64)(void*,tdsqlite3_uint64); + int (*load_extension)(sqlite3*,const char*,const char*,char**); + void *(*malloc64)(sqlite3_uint64); + sqlite3_uint64 (*msize)(void*); + void *(*realloc64)(void*,sqlite3_uint64); void (*reset_auto_extension)(void); - void (*result_blob64)(tdsqlite3_context*,const void*,tdsqlite3_uint64, + void (*result_blob64)(sqlite3_context*,const void*,sqlite3_uint64, void(*)(void*)); - void (*result_text64)(tdsqlite3_context*,const char*,tdsqlite3_uint64, + void (*result_text64)(sqlite3_context*,const char*,sqlite3_uint64, void(*)(void*), unsigned char); int (*strglob)(const char*,const char*); /* Version 3.8.11 and later */ - tdsqlite3_value *(*value_dup)(const tdsqlite3_value*); - void (*value_free)(tdsqlite3_value*); - int (*result_zeroblob64)(tdsqlite3_context*,tdsqlite3_uint64); - int (*bind_zeroblob64)(tdsqlite3_stmt*, int, tdsqlite3_uint64); + sqlite3_value *(*value_dup)(const sqlite3_value*); + void (*value_free)(sqlite3_value*); + int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64); + int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64); /* Version 3.9.0 and later */ - unsigned int (*value_subtype)(tdsqlite3_value*); - void (*result_subtype)(tdsqlite3_context*,unsigned int); + unsigned int (*value_subtype)(sqlite3_value*); + void (*result_subtype)(sqlite3_context*,unsigned int); /* Version 3.10.0 and later */ - int (*status64)(int,tdsqlite3_int64*,tdsqlite3_int64*,int); + int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); int (*strlike)(const char*,const char*,unsigned int); - int (*db_cacheflush)(tdsqlite3*); + int (*db_cacheflush)(sqlite3*); /* Version 3.12.0 and later */ - int (*system_errno)(tdsqlite3*); + int (*system_errno)(sqlite3*); /* Version 3.14.0 and later */ - int (*trace_v2)(tdsqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); - char *(*expanded_sql)(tdsqlite3_stmt*); + int (*trace_v2)(sqlite3*,unsigned,int(*)(unsigned,void*,void*,void*),void*); + char *(*expanded_sql)(sqlite3_stmt*); /* Version 3.18.0 and later */ - void (*set_last_insert_rowid)(tdsqlite3*,tdsqlite3_int64); + void (*set_last_insert_rowid)(sqlite3*,sqlite3_int64); /* Version 3.20.0 and later */ - int (*prepare_v3)(tdsqlite3*,const char*,int,unsigned int, - tdsqlite3_stmt**,const char**); - int (*prepare16_v3)(tdsqlite3*,const void*,int,unsigned int, - tdsqlite3_stmt**,const void**); - int (*bind_pointer)(tdsqlite3_stmt*,int,void*,const char*,void(*)(void*)); - void (*result_pointer)(tdsqlite3_context*,void*,const char*,void(*)(void*)); - void *(*value_pointer)(tdsqlite3_value*,const char*); - int (*vtab_nochange)(tdsqlite3_context*); - int (*value_nochange)(tdsqlite3_value*); - const char *(*vtab_collation)(tdsqlite3_index_info*,int); + int (*prepare_v3)(sqlite3*,const char*,int,unsigned int, + sqlite3_stmt**,const char**); + int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int, + sqlite3_stmt**,const void**); + int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*)); + void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*)); + void *(*value_pointer)(sqlite3_value*,const char*); + int (*vtab_nochange)(sqlite3_context*); + int (*value_nochange)(sqlite3_value*); + const char *(*vtab_collation)(sqlite3_index_info*,int); /* Version 3.24.0 and later */ int (*keyword_count)(void); int (*keyword_name)(int,const char**,int*); int (*keyword_check)(const char*,int); - tdsqlite3_str *(*str_new)(tdsqlite3*); - char *(*str_finish)(tdsqlite3_str*); - void (*str_appendf)(tdsqlite3_str*, const char *zFormat, ...); - void (*str_vappendf)(tdsqlite3_str*, const char *zFormat, va_list); - void (*str_append)(tdsqlite3_str*, const char *zIn, int N); - void (*str_appendall)(tdsqlite3_str*, const char *zIn); - void (*str_appendchar)(tdsqlite3_str*, int N, char C); - void (*str_reset)(tdsqlite3_str*); - int (*str_errcode)(tdsqlite3_str*); - int (*str_length)(tdsqlite3_str*); - char *(*str_value)(tdsqlite3_str*); + sqlite3_str *(*str_new)(sqlite3*); + char *(*str_finish)(sqlite3_str*); + void (*str_appendf)(sqlite3_str*, const char *zFormat, ...); + void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list); + void (*str_append)(sqlite3_str*, const char *zIn, int N); + void (*str_appendall)(sqlite3_str*, const char *zIn); + void (*str_appendchar)(sqlite3_str*, int N, char C); + void (*str_reset)(sqlite3_str*); + int (*str_errcode)(sqlite3_str*); + int (*str_length)(sqlite3_str*); + char *(*str_value)(sqlite3_str*); /* Version 3.25.0 and later */ - int (*create_window_function)(tdsqlite3*,const char*,int,int,void*, - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*), - void (*xValue)(tdsqlite3_context*), - void (*xInv)(tdsqlite3_context*,int,tdsqlite3_value**), + int (*create_window_function)(sqlite3*,const char*,int,int,void*, + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInv)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*)); /* Version 3.26.0 and later */ - const char *(*normalized_sql)(tdsqlite3_stmt*); + const char *(*normalized_sql)(sqlite3_stmt*); /* Version 3.28.0 and later */ - int (*stmt_isexplain)(tdsqlite3_stmt*); - int (*value_frombind)(tdsqlite3_value*); + int (*stmt_isexplain)(sqlite3_stmt*); + int (*value_frombind)(sqlite3_value*); /* Version 3.30.0 and later */ - int (*drop_modules)(tdsqlite3*,const char**); + int (*drop_modules)(sqlite3*,const char**); /* Version 3.31.0 and later */ - tdsqlite3_int64 (*hard_heap_limit64)(tdsqlite3_int64); + sqlite3_int64 (*hard_heap_limit64)(sqlite3_int64); const char *(*uri_key)(const char*,int); const char *(*filename_database)(const char*); const char *(*filename_journal)(const char*); @@ -126131,309 +126131,309 @@ struct tdsqlite3_api_routines { ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ -typedef int (*tdsqlite3_loadext_entry)( - tdsqlite3 *db, /* Handle to the database. */ +typedef int (*sqlite3_loadext_entry)( + sqlite3 *db, /* Handle to the database. */ char **pzErrMsg, /* Used to set error string on failure. */ - const tdsqlite3_api_routines *pThunk /* Extension API function pointers. */ + const sqlite3_api_routines *pThunk /* Extension API function pointers. */ ); /* ** The following macros redefine the API routines so that they are -** redirected through the global tdsqlite3_api structure. +** redirected through the global sqlite3_api structure. ** ** This header file is also used by the loadext.c source file ** (part of the main SQLite library - not an extension) so that -** it can get access to the tdsqlite3_api_routines structure +** it can get access to the sqlite3_api_routines structure ** definition. But the main library does not want to redefine ** the API. So the redefinition macros are only valid if the ** SQLITE_CORE macros is undefined. */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) -#define tdsqlite3_aggregate_context tdsqlite3_api->aggregate_context +#define sqlite3_aggregate_context sqlite3_api->aggregate_context #ifndef SQLITE_OMIT_DEPRECATED -#define tdsqlite3_aggregate_count tdsqlite3_api->aggregate_count -#endif -#define tdsqlite3_bind_blob tdsqlite3_api->bind_blob -#define tdsqlite3_bind_double tdsqlite3_api->bind_double -#define tdsqlite3_bind_int tdsqlite3_api->bind_int -#define tdsqlite3_bind_int64 tdsqlite3_api->bind_int64 -#define tdsqlite3_bind_null tdsqlite3_api->bind_null -#define tdsqlite3_bind_parameter_count tdsqlite3_api->bind_parameter_count -#define tdsqlite3_bind_parameter_index tdsqlite3_api->bind_parameter_index -#define tdsqlite3_bind_parameter_name tdsqlite3_api->bind_parameter_name -#define tdsqlite3_bind_text tdsqlite3_api->bind_text -#define tdsqlite3_bind_text16 tdsqlite3_api->bind_text16 -#define tdsqlite3_bind_value tdsqlite3_api->bind_value -#define tdsqlite3_busy_handler tdsqlite3_api->busy_handler -#define tdsqlite3_busy_timeout tdsqlite3_api->busy_timeout -#define tdsqlite3_changes tdsqlite3_api->changes -#define tdsqlite3_close tdsqlite3_api->close -#define tdsqlite3_collation_needed tdsqlite3_api->collation_needed -#define tdsqlite3_collation_needed16 tdsqlite3_api->collation_needed16 -#define tdsqlite3_column_blob tdsqlite3_api->column_blob -#define tdsqlite3_column_bytes tdsqlite3_api->column_bytes -#define tdsqlite3_column_bytes16 tdsqlite3_api->column_bytes16 -#define tdsqlite3_column_count tdsqlite3_api->column_count -#define tdsqlite3_column_database_name tdsqlite3_api->column_database_name -#define tdsqlite3_column_database_name16 tdsqlite3_api->column_database_name16 -#define tdsqlite3_column_decltype tdsqlite3_api->column_decltype -#define tdsqlite3_column_decltype16 tdsqlite3_api->column_decltype16 -#define tdsqlite3_column_double tdsqlite3_api->column_double -#define tdsqlite3_column_int tdsqlite3_api->column_int -#define tdsqlite3_column_int64 tdsqlite3_api->column_int64 -#define tdsqlite3_column_name tdsqlite3_api->column_name -#define tdsqlite3_column_name16 tdsqlite3_api->column_name16 -#define tdsqlite3_column_origin_name tdsqlite3_api->column_origin_name -#define tdsqlite3_column_origin_name16 tdsqlite3_api->column_origin_name16 -#define tdsqlite3_column_table_name tdsqlite3_api->column_table_name -#define tdsqlite3_column_table_name16 tdsqlite3_api->column_table_name16 -#define tdsqlite3_column_text tdsqlite3_api->column_text -#define tdsqlite3_column_text16 tdsqlite3_api->column_text16 -#define tdsqlite3_column_type tdsqlite3_api->column_type -#define tdsqlite3_column_value tdsqlite3_api->column_value -#define tdsqlite3_commit_hook tdsqlite3_api->commit_hook -#define tdsqlite3_complete tdsqlite3_api->complete -#define tdsqlite3_complete16 tdsqlite3_api->complete16 -#define tdsqlite3_create_collation tdsqlite3_api->create_collation -#define tdsqlite3_create_collation16 tdsqlite3_api->create_collation16 -#define tdsqlite3_create_function tdsqlite3_api->create_function -#define tdsqlite3_create_function16 tdsqlite3_api->create_function16 -#define tdsqlite3_create_module tdsqlite3_api->create_module -#define tdsqlite3_create_module_v2 tdsqlite3_api->create_module_v2 -#define tdsqlite3_data_count tdsqlite3_api->data_count -#define tdsqlite3_db_handle tdsqlite3_api->db_handle -#define tdsqlite3_declare_vtab tdsqlite3_api->declare_vtab -#define tdsqlite3_enable_shared_cache tdsqlite3_api->enable_shared_cache -#define tdsqlite3_errcode tdsqlite3_api->errcode -#define tdsqlite3_errmsg tdsqlite3_api->errmsg -#define tdsqlite3_errmsg16 tdsqlite3_api->errmsg16 -#define tdsqlite3_exec tdsqlite3_api->exec +#define sqlite3_aggregate_count sqlite3_api->aggregate_count +#endif +#define sqlite3_bind_blob sqlite3_api->bind_blob +#define sqlite3_bind_double sqlite3_api->bind_double +#define sqlite3_bind_int sqlite3_api->bind_int +#define sqlite3_bind_int64 sqlite3_api->bind_int64 +#define sqlite3_bind_null sqlite3_api->bind_null +#define sqlite3_bind_parameter_count sqlite3_api->bind_parameter_count +#define sqlite3_bind_parameter_index sqlite3_api->bind_parameter_index +#define sqlite3_bind_parameter_name sqlite3_api->bind_parameter_name +#define sqlite3_bind_text sqlite3_api->bind_text +#define sqlite3_bind_text16 sqlite3_api->bind_text16 +#define sqlite3_bind_value sqlite3_api->bind_value +#define sqlite3_busy_handler sqlite3_api->busy_handler +#define sqlite3_busy_timeout sqlite3_api->busy_timeout +#define sqlite3_changes sqlite3_api->changes +#define sqlite3_close sqlite3_api->close +#define sqlite3_collation_needed sqlite3_api->collation_needed +#define sqlite3_collation_needed16 sqlite3_api->collation_needed16 +#define sqlite3_column_blob sqlite3_api->column_blob +#define sqlite3_column_bytes sqlite3_api->column_bytes +#define sqlite3_column_bytes16 sqlite3_api->column_bytes16 +#define sqlite3_column_count sqlite3_api->column_count +#define sqlite3_column_database_name sqlite3_api->column_database_name +#define sqlite3_column_database_name16 sqlite3_api->column_database_name16 +#define sqlite3_column_decltype sqlite3_api->column_decltype +#define sqlite3_column_decltype16 sqlite3_api->column_decltype16 +#define sqlite3_column_double sqlite3_api->column_double +#define sqlite3_column_int sqlite3_api->column_int +#define sqlite3_column_int64 sqlite3_api->column_int64 +#define sqlite3_column_name sqlite3_api->column_name +#define sqlite3_column_name16 sqlite3_api->column_name16 +#define sqlite3_column_origin_name sqlite3_api->column_origin_name +#define sqlite3_column_origin_name16 sqlite3_api->column_origin_name16 +#define sqlite3_column_table_name sqlite3_api->column_table_name +#define sqlite3_column_table_name16 sqlite3_api->column_table_name16 +#define sqlite3_column_text sqlite3_api->column_text +#define sqlite3_column_text16 sqlite3_api->column_text16 +#define sqlite3_column_type sqlite3_api->column_type +#define sqlite3_column_value sqlite3_api->column_value +#define sqlite3_commit_hook sqlite3_api->commit_hook +#define sqlite3_complete sqlite3_api->complete +#define sqlite3_complete16 sqlite3_api->complete16 +#define sqlite3_create_collation sqlite3_api->create_collation +#define sqlite3_create_collation16 sqlite3_api->create_collation16 +#define sqlite3_create_function sqlite3_api->create_function +#define sqlite3_create_function16 sqlite3_api->create_function16 +#define sqlite3_create_module sqlite3_api->create_module +#define sqlite3_create_module_v2 sqlite3_api->create_module_v2 +#define sqlite3_data_count sqlite3_api->data_count +#define sqlite3_db_handle sqlite3_api->db_handle +#define sqlite3_declare_vtab sqlite3_api->declare_vtab +#define sqlite3_enable_shared_cache sqlite3_api->enable_shared_cache +#define sqlite3_errcode sqlite3_api->errcode +#define sqlite3_errmsg sqlite3_api->errmsg +#define sqlite3_errmsg16 sqlite3_api->errmsg16 +#define sqlite3_exec sqlite3_api->exec #ifndef SQLITE_OMIT_DEPRECATED -#define tdsqlite3_expired tdsqlite3_api->expired -#endif -#define tdsqlite3_finalize tdsqlite3_api->finalize -#define tdsqlite3_free tdsqlite3_api->free -#define tdsqlite3_free_table tdsqlite3_api->free_table -#define tdsqlite3_get_autocommit tdsqlite3_api->get_autocommit -#define tdsqlite3_get_auxdata tdsqlite3_api->get_auxdata -#define tdsqlite3_get_table tdsqlite3_api->get_table +#define sqlite3_expired sqlite3_api->expired +#endif +#define sqlite3_finalize sqlite3_api->finalize +#define sqlite3_free sqlite3_api->free +#define sqlite3_free_table sqlite3_api->free_table +#define sqlite3_get_autocommit sqlite3_api->get_autocommit +#define sqlite3_get_auxdata sqlite3_api->get_auxdata +#define sqlite3_get_table sqlite3_api->get_table #ifndef SQLITE_OMIT_DEPRECATED -#define tdsqlite3_global_recover tdsqlite3_api->global_recover -#endif -#define tdsqlite3_interrupt tdsqlite3_api->interruptx -#define tdsqlite3_last_insert_rowid tdsqlite3_api->last_insert_rowid -#define tdsqlite3_libversion tdsqlite3_api->libversion -#define tdsqlite3_libversion_number tdsqlite3_api->libversion_number -#define tdsqlite3_malloc tdsqlite3_api->malloc -#define tdsqlite3_mprintf tdsqlite3_api->mprintf -#define tdsqlite3_open tdsqlite3_api->open -#define tdsqlite3_open16 tdsqlite3_api->open16 -#define tdsqlite3_prepare tdsqlite3_api->prepare -#define tdsqlite3_prepare16 tdsqlite3_api->prepare16 -#define tdsqlite3_prepare_v2 tdsqlite3_api->prepare_v2 -#define tdsqlite3_prepare16_v2 tdsqlite3_api->prepare16_v2 -#define tdsqlite3_profile tdsqlite3_api->profile -#define tdsqlite3_progress_handler tdsqlite3_api->progress_handler -#define tdsqlite3_realloc tdsqlite3_api->realloc -#define tdsqlite3_reset tdsqlite3_api->reset -#define tdsqlite3_result_blob tdsqlite3_api->result_blob -#define tdsqlite3_result_double tdsqlite3_api->result_double -#define tdsqlite3_result_error tdsqlite3_api->result_error -#define tdsqlite3_result_error16 tdsqlite3_api->result_error16 -#define tdsqlite3_result_int tdsqlite3_api->result_int -#define tdsqlite3_result_int64 tdsqlite3_api->result_int64 -#define tdsqlite3_result_null tdsqlite3_api->result_null -#define tdsqlite3_result_text tdsqlite3_api->result_text -#define tdsqlite3_result_text16 tdsqlite3_api->result_text16 -#define tdsqlite3_result_text16be tdsqlite3_api->result_text16be -#define tdsqlite3_result_text16le tdsqlite3_api->result_text16le -#define tdsqlite3_result_value tdsqlite3_api->result_value -#define tdsqlite3_rollback_hook tdsqlite3_api->rollback_hook -#define tdsqlite3_set_authorizer tdsqlite3_api->set_authorizer -#define tdsqlite3_set_auxdata tdsqlite3_api->set_auxdata -#define tdsqlite3_snprintf tdsqlite3_api->xsnprintf -#define tdsqlite3_step tdsqlite3_api->step -#define tdsqlite3_table_column_metadata tdsqlite3_api->table_column_metadata -#define tdsqlite3_thread_cleanup tdsqlite3_api->thread_cleanup -#define tdsqlite3_total_changes tdsqlite3_api->total_changes -#define tdsqlite3_trace tdsqlite3_api->trace +#define sqlite3_global_recover sqlite3_api->global_recover +#endif +#define sqlite3_interrupt sqlite3_api->interruptx +#define sqlite3_last_insert_rowid sqlite3_api->last_insert_rowid +#define sqlite3_libversion sqlite3_api->libversion +#define sqlite3_libversion_number sqlite3_api->libversion_number +#define sqlite3_malloc sqlite3_api->malloc +#define sqlite3_mprintf sqlite3_api->mprintf +#define sqlite3_open sqlite3_api->open +#define sqlite3_open16 sqlite3_api->open16 +#define sqlite3_prepare sqlite3_api->prepare +#define sqlite3_prepare16 sqlite3_api->prepare16 +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_profile sqlite3_api->profile +#define sqlite3_progress_handler sqlite3_api->progress_handler +#define sqlite3_realloc sqlite3_api->realloc +#define sqlite3_reset sqlite3_api->reset +#define sqlite3_result_blob sqlite3_api->result_blob +#define sqlite3_result_double sqlite3_api->result_double +#define sqlite3_result_error sqlite3_api->result_error +#define sqlite3_result_error16 sqlite3_api->result_error16 +#define sqlite3_result_int sqlite3_api->result_int +#define sqlite3_result_int64 sqlite3_api->result_int64 +#define sqlite3_result_null sqlite3_api->result_null +#define sqlite3_result_text sqlite3_api->result_text +#define sqlite3_result_text16 sqlite3_api->result_text16 +#define sqlite3_result_text16be sqlite3_api->result_text16be +#define sqlite3_result_text16le sqlite3_api->result_text16le +#define sqlite3_result_value sqlite3_api->result_value +#define sqlite3_rollback_hook sqlite3_api->rollback_hook +#define sqlite3_set_authorizer sqlite3_api->set_authorizer +#define sqlite3_set_auxdata sqlite3_api->set_auxdata +#define sqlite3_snprintf sqlite3_api->xsnprintf +#define sqlite3_step sqlite3_api->step +#define sqlite3_table_column_metadata sqlite3_api->table_column_metadata +#define sqlite3_thread_cleanup sqlite3_api->thread_cleanup +#define sqlite3_total_changes sqlite3_api->total_changes +#define sqlite3_trace sqlite3_api->trace #ifndef SQLITE_OMIT_DEPRECATED -#define tdsqlite3_transfer_bindings tdsqlite3_api->transfer_bindings -#endif -#define tdsqlite3_update_hook tdsqlite3_api->update_hook -#define tdsqlite3_user_data tdsqlite3_api->user_data -#define tdsqlite3_value_blob tdsqlite3_api->value_blob -#define tdsqlite3_value_bytes tdsqlite3_api->value_bytes -#define tdsqlite3_value_bytes16 tdsqlite3_api->value_bytes16 -#define tdsqlite3_value_double tdsqlite3_api->value_double -#define tdsqlite3_value_int tdsqlite3_api->value_int -#define tdsqlite3_value_int64 tdsqlite3_api->value_int64 -#define tdsqlite3_value_numeric_type tdsqlite3_api->value_numeric_type -#define tdsqlite3_value_text tdsqlite3_api->value_text -#define tdsqlite3_value_text16 tdsqlite3_api->value_text16 -#define tdsqlite3_value_text16be tdsqlite3_api->value_text16be -#define tdsqlite3_value_text16le tdsqlite3_api->value_text16le -#define tdsqlite3_value_type tdsqlite3_api->value_type -#define tdsqlite3_vmprintf tdsqlite3_api->vmprintf -#define tdsqlite3_vsnprintf tdsqlite3_api->xvsnprintf -#define tdsqlite3_overload_function tdsqlite3_api->overload_function -#define tdsqlite3_prepare_v2 tdsqlite3_api->prepare_v2 -#define tdsqlite3_prepare16_v2 tdsqlite3_api->prepare16_v2 -#define tdsqlite3_clear_bindings tdsqlite3_api->clear_bindings -#define tdsqlite3_bind_zeroblob tdsqlite3_api->bind_zeroblob -#define tdsqlite3_blob_bytes tdsqlite3_api->blob_bytes -#define tdsqlite3_blob_close tdsqlite3_api->blob_close -#define tdsqlite3_blob_open tdsqlite3_api->blob_open -#define tdsqlite3_blob_read tdsqlite3_api->blob_read -#define tdsqlite3_blob_write tdsqlite3_api->blob_write -#define tdsqlite3_create_collation_v2 tdsqlite3_api->create_collation_v2 -#define tdsqlite3_file_control tdsqlite3_api->file_control -#define tdsqlite3_memory_highwater tdsqlite3_api->memory_highwater -#define tdsqlite3_memory_used tdsqlite3_api->memory_used -#define tdsqlite3_mutex_alloc tdsqlite3_api->mutex_alloc -#define tdsqlite3_mutex_enter tdsqlite3_api->mutex_enter -#define tdsqlite3_mutex_free tdsqlite3_api->mutex_free -#define tdsqlite3_mutex_leave tdsqlite3_api->mutex_leave -#define tdsqlite3_mutex_try tdsqlite3_api->mutex_try -#define tdsqlite3_open_v2 tdsqlite3_api->open_v2 -#define tdsqlite3_release_memory tdsqlite3_api->release_memory -#define tdsqlite3_result_error_nomem tdsqlite3_api->result_error_nomem -#define tdsqlite3_result_error_toobig tdsqlite3_api->result_error_toobig -#define tdsqlite3_sleep tdsqlite3_api->sleep -#define tdsqlite3_soft_heap_limit tdsqlite3_api->soft_heap_limit -#define tdsqlite3_vfs_find tdsqlite3_api->vfs_find -#define tdsqlite3_vfs_register tdsqlite3_api->vfs_register -#define tdsqlite3_vfs_unregister tdsqlite3_api->vfs_unregister -#define tdsqlite3_threadsafe tdsqlite3_api->xthreadsafe -#define tdsqlite3_result_zeroblob tdsqlite3_api->result_zeroblob -#define tdsqlite3_result_error_code tdsqlite3_api->result_error_code -#define tdsqlite3_test_control tdsqlite3_api->test_control -#define tdsqlite3_randomness tdsqlite3_api->randomness -#define tdsqlite3_context_db_handle tdsqlite3_api->context_db_handle -#define tdsqlite3_extended_result_codes tdsqlite3_api->extended_result_codes -#define tdsqlite3_limit tdsqlite3_api->limit -#define tdsqlite3_next_stmt tdsqlite3_api->next_stmt -#define tdsqlite3_sql tdsqlite3_api->sql -#define tdsqlite3_status tdsqlite3_api->status -#define tdsqlite3_backup_finish tdsqlite3_api->backup_finish -#define tdsqlite3_backup_init tdsqlite3_api->backup_init -#define tdsqlite3_backup_pagecount tdsqlite3_api->backup_pagecount -#define tdsqlite3_backup_remaining tdsqlite3_api->backup_remaining -#define tdsqlite3_backup_step tdsqlite3_api->backup_step -#define tdsqlite3_compileoption_get tdsqlite3_api->compileoption_get -#define tdsqlite3_compileoption_used tdsqlite3_api->compileoption_used -#define tdsqlite3_create_function_v2 tdsqlite3_api->create_function_v2 -#define tdsqlite3_db_config tdsqlite3_api->db_config -#define tdsqlite3_db_mutex tdsqlite3_api->db_mutex -#define tdsqlite3_db_status tdsqlite3_api->db_status -#define tdsqlite3_extended_errcode tdsqlite3_api->extended_errcode -#define tdsqlite3_log tdsqlite3_api->log -#define tdsqlite3_soft_heap_limit64 tdsqlite3_api->soft_heap_limit64 -#define tdsqlite3_sourceid tdsqlite3_api->sourceid -#define tdsqlite3_stmt_status tdsqlite3_api->stmt_status -#define tdsqlite3_strnicmp tdsqlite3_api->strnicmp -#define tdsqlite3_unlock_notify tdsqlite3_api->unlock_notify -#define tdsqlite3_wal_autocheckpoint tdsqlite3_api->wal_autocheckpoint -#define tdsqlite3_wal_checkpoint tdsqlite3_api->wal_checkpoint -#define tdsqlite3_wal_hook tdsqlite3_api->wal_hook -#define tdsqlite3_blob_reopen tdsqlite3_api->blob_reopen -#define tdsqlite3_vtab_config tdsqlite3_api->vtab_config -#define tdsqlite3_vtab_on_conflict tdsqlite3_api->vtab_on_conflict +#define sqlite3_transfer_bindings sqlite3_api->transfer_bindings +#endif +#define sqlite3_update_hook sqlite3_api->update_hook +#define sqlite3_user_data sqlite3_api->user_data +#define sqlite3_value_blob sqlite3_api->value_blob +#define sqlite3_value_bytes sqlite3_api->value_bytes +#define sqlite3_value_bytes16 sqlite3_api->value_bytes16 +#define sqlite3_value_double sqlite3_api->value_double +#define sqlite3_value_int sqlite3_api->value_int +#define sqlite3_value_int64 sqlite3_api->value_int64 +#define sqlite3_value_numeric_type sqlite3_api->value_numeric_type +#define sqlite3_value_text sqlite3_api->value_text +#define sqlite3_value_text16 sqlite3_api->value_text16 +#define sqlite3_value_text16be sqlite3_api->value_text16be +#define sqlite3_value_text16le sqlite3_api->value_text16le +#define sqlite3_value_type sqlite3_api->value_type +#define sqlite3_vmprintf sqlite3_api->vmprintf +#define sqlite3_vsnprintf sqlite3_api->xvsnprintf +#define sqlite3_overload_function sqlite3_api->overload_function +#define sqlite3_prepare_v2 sqlite3_api->prepare_v2 +#define sqlite3_prepare16_v2 sqlite3_api->prepare16_v2 +#define sqlite3_clear_bindings sqlite3_api->clear_bindings +#define sqlite3_bind_zeroblob sqlite3_api->bind_zeroblob +#define sqlite3_blob_bytes sqlite3_api->blob_bytes +#define sqlite3_blob_close sqlite3_api->blob_close +#define sqlite3_blob_open sqlite3_api->blob_open +#define sqlite3_blob_read sqlite3_api->blob_read +#define sqlite3_blob_write sqlite3_api->blob_write +#define sqlite3_create_collation_v2 sqlite3_api->create_collation_v2 +#define sqlite3_file_control sqlite3_api->file_control +#define sqlite3_memory_highwater sqlite3_api->memory_highwater +#define sqlite3_memory_used sqlite3_api->memory_used +#define sqlite3_mutex_alloc sqlite3_api->mutex_alloc +#define sqlite3_mutex_enter sqlite3_api->mutex_enter +#define sqlite3_mutex_free sqlite3_api->mutex_free +#define sqlite3_mutex_leave sqlite3_api->mutex_leave +#define sqlite3_mutex_try sqlite3_api->mutex_try +#define sqlite3_open_v2 sqlite3_api->open_v2 +#define sqlite3_release_memory sqlite3_api->release_memory +#define sqlite3_result_error_nomem sqlite3_api->result_error_nomem +#define sqlite3_result_error_toobig sqlite3_api->result_error_toobig +#define sqlite3_sleep sqlite3_api->sleep +#define sqlite3_soft_heap_limit sqlite3_api->soft_heap_limit +#define sqlite3_vfs_find sqlite3_api->vfs_find +#define sqlite3_vfs_register sqlite3_api->vfs_register +#define sqlite3_vfs_unregister sqlite3_api->vfs_unregister +#define sqlite3_threadsafe sqlite3_api->xthreadsafe +#define sqlite3_result_zeroblob sqlite3_api->result_zeroblob +#define sqlite3_result_error_code sqlite3_api->result_error_code +#define sqlite3_test_control sqlite3_api->test_control +#define sqlite3_randomness sqlite3_api->randomness +#define sqlite3_context_db_handle sqlite3_api->context_db_handle +#define sqlite3_extended_result_codes sqlite3_api->extended_result_codes +#define sqlite3_limit sqlite3_api->limit +#define sqlite3_next_stmt sqlite3_api->next_stmt +#define sqlite3_sql sqlite3_api->sql +#define sqlite3_status sqlite3_api->status +#define sqlite3_backup_finish sqlite3_api->backup_finish +#define sqlite3_backup_init sqlite3_api->backup_init +#define sqlite3_backup_pagecount sqlite3_api->backup_pagecount +#define sqlite3_backup_remaining sqlite3_api->backup_remaining +#define sqlite3_backup_step sqlite3_api->backup_step +#define sqlite3_compileoption_get sqlite3_api->compileoption_get +#define sqlite3_compileoption_used sqlite3_api->compileoption_used +#define sqlite3_create_function_v2 sqlite3_api->create_function_v2 +#define sqlite3_db_config sqlite3_api->db_config +#define sqlite3_db_mutex sqlite3_api->db_mutex +#define sqlite3_db_status sqlite3_api->db_status +#define sqlite3_extended_errcode sqlite3_api->extended_errcode +#define sqlite3_log sqlite3_api->log +#define sqlite3_soft_heap_limit64 sqlite3_api->soft_heap_limit64 +#define sqlite3_sourceid sqlite3_api->sourceid +#define sqlite3_stmt_status sqlite3_api->stmt_status +#define sqlite3_strnicmp sqlite3_api->strnicmp +#define sqlite3_unlock_notify sqlite3_api->unlock_notify +#define sqlite3_wal_autocheckpoint sqlite3_api->wal_autocheckpoint +#define sqlite3_wal_checkpoint sqlite3_api->wal_checkpoint +#define sqlite3_wal_hook sqlite3_api->wal_hook +#define sqlite3_blob_reopen sqlite3_api->blob_reopen +#define sqlite3_vtab_config sqlite3_api->vtab_config +#define sqlite3_vtab_on_conflict sqlite3_api->vtab_on_conflict /* Version 3.7.16 and later */ -#define tdsqlite3_close_v2 tdsqlite3_api->close_v2 -#define tdsqlite3_db_filename tdsqlite3_api->db_filename -#define tdsqlite3_db_readonly tdsqlite3_api->db_readonly -#define tdsqlite3_db_release_memory tdsqlite3_api->db_release_memory -#define tdsqlite3_errstr tdsqlite3_api->errstr -#define tdsqlite3_stmt_busy tdsqlite3_api->stmt_busy -#define tdsqlite3_stmt_readonly tdsqlite3_api->stmt_readonly -#define tdsqlite3_stricmp tdsqlite3_api->stricmp -#define tdsqlite3_uri_boolean tdsqlite3_api->uri_boolean -#define tdsqlite3_uri_int64 tdsqlite3_api->uri_int64 -#define tdsqlite3_uri_parameter tdsqlite3_api->uri_parameter -#define tdsqlite3_uri_vsnprintf tdsqlite3_api->xvsnprintf -#define tdsqlite3_wal_checkpoint_v2 tdsqlite3_api->wal_checkpoint_v2 +#define sqlite3_close_v2 sqlite3_api->close_v2 +#define sqlite3_db_filename sqlite3_api->db_filename +#define sqlite3_db_readonly sqlite3_api->db_readonly +#define sqlite3_db_release_memory sqlite3_api->db_release_memory +#define sqlite3_errstr sqlite3_api->errstr +#define sqlite3_stmt_busy sqlite3_api->stmt_busy +#define sqlite3_stmt_readonly sqlite3_api->stmt_readonly +#define sqlite3_stricmp sqlite3_api->stricmp +#define sqlite3_uri_boolean sqlite3_api->uri_boolean +#define sqlite3_uri_int64 sqlite3_api->uri_int64 +#define sqlite3_uri_parameter sqlite3_api->uri_parameter +#define sqlite3_uri_vsnprintf sqlite3_api->xvsnprintf +#define sqlite3_wal_checkpoint_v2 sqlite3_api->wal_checkpoint_v2 /* Version 3.8.7 and later */ -#define tdsqlite3_auto_extension tdsqlite3_api->auto_extension -#define tdsqlite3_bind_blob64 tdsqlite3_api->bind_blob64 -#define tdsqlite3_bind_text64 tdsqlite3_api->bind_text64 -#define tdsqlite3_cancel_auto_extension tdsqlite3_api->cancel_auto_extension -#define tdsqlite3_load_extension tdsqlite3_api->load_extension -#define tdsqlite3_malloc64 tdsqlite3_api->malloc64 -#define tdsqlite3_msize tdsqlite3_api->msize -#define tdsqlite3_realloc64 tdsqlite3_api->realloc64 -#define tdsqlite3_reset_auto_extension tdsqlite3_api->reset_auto_extension -#define tdsqlite3_result_blob64 tdsqlite3_api->result_blob64 -#define tdsqlite3_result_text64 tdsqlite3_api->result_text64 -#define tdsqlite3_strglob tdsqlite3_api->strglob +#define sqlite3_auto_extension sqlite3_api->auto_extension +#define sqlite3_bind_blob64 sqlite3_api->bind_blob64 +#define sqlite3_bind_text64 sqlite3_api->bind_text64 +#define sqlite3_cancel_auto_extension sqlite3_api->cancel_auto_extension +#define sqlite3_load_extension sqlite3_api->load_extension +#define sqlite3_malloc64 sqlite3_api->malloc64 +#define sqlite3_msize sqlite3_api->msize +#define sqlite3_realloc64 sqlite3_api->realloc64 +#define sqlite3_reset_auto_extension sqlite3_api->reset_auto_extension +#define sqlite3_result_blob64 sqlite3_api->result_blob64 +#define sqlite3_result_text64 sqlite3_api->result_text64 +#define sqlite3_strglob sqlite3_api->strglob /* Version 3.8.11 and later */ -#define tdsqlite3_value_dup tdsqlite3_api->value_dup -#define tdsqlite3_value_free tdsqlite3_api->value_free -#define tdsqlite3_result_zeroblob64 tdsqlite3_api->result_zeroblob64 -#define tdsqlite3_bind_zeroblob64 tdsqlite3_api->bind_zeroblob64 +#define sqlite3_value_dup sqlite3_api->value_dup +#define sqlite3_value_free sqlite3_api->value_free +#define sqlite3_result_zeroblob64 sqlite3_api->result_zeroblob64 +#define sqlite3_bind_zeroblob64 sqlite3_api->bind_zeroblob64 /* Version 3.9.0 and later */ -#define tdsqlite3_value_subtype tdsqlite3_api->value_subtype -#define tdsqlite3_result_subtype tdsqlite3_api->result_subtype +#define sqlite3_value_subtype sqlite3_api->value_subtype +#define sqlite3_result_subtype sqlite3_api->result_subtype /* Version 3.10.0 and later */ -#define tdsqlite3_status64 tdsqlite3_api->status64 -#define tdsqlite3_strlike tdsqlite3_api->strlike -#define tdsqlite3_db_cacheflush tdsqlite3_api->db_cacheflush +#define sqlite3_status64 sqlite3_api->status64 +#define sqlite3_strlike sqlite3_api->strlike +#define sqlite3_db_cacheflush sqlite3_api->db_cacheflush /* Version 3.12.0 and later */ -#define tdsqlite3_system_errno tdsqlite3_api->system_errno +#define sqlite3_system_errno sqlite3_api->system_errno /* Version 3.14.0 and later */ -#define tdsqlite3_trace_v2 tdsqlite3_api->trace_v2 -#define tdsqlite3_expanded_sql tdsqlite3_api->expanded_sql +#define sqlite3_trace_v2 sqlite3_api->trace_v2 +#define sqlite3_expanded_sql sqlite3_api->expanded_sql /* Version 3.18.0 and later */ -#define tdsqlite3_set_last_insert_rowid tdsqlite3_api->set_last_insert_rowid +#define sqlite3_set_last_insert_rowid sqlite3_api->set_last_insert_rowid /* Version 3.20.0 and later */ -#define tdsqlite3_prepare_v3 tdsqlite3_api->prepare_v3 -#define tdsqlite3_prepare16_v3 tdsqlite3_api->prepare16_v3 -#define tdsqlite3_bind_pointer tdsqlite3_api->bind_pointer -#define tdsqlite3_result_pointer tdsqlite3_api->result_pointer -#define tdsqlite3_value_pointer tdsqlite3_api->value_pointer +#define sqlite3_prepare_v3 sqlite3_api->prepare_v3 +#define sqlite3_prepare16_v3 sqlite3_api->prepare16_v3 +#define sqlite3_bind_pointer sqlite3_api->bind_pointer +#define sqlite3_result_pointer sqlite3_api->result_pointer +#define sqlite3_value_pointer sqlite3_api->value_pointer /* Version 3.22.0 and later */ -#define tdsqlite3_vtab_nochange tdsqlite3_api->vtab_nochange -#define tdsqlite3_value_nochange tdsqlite3_api->value_nochange -#define tdsqlite3_vtab_collation tdsqlite3_api->vtab_collation +#define sqlite3_vtab_nochange sqlite3_api->vtab_nochange +#define sqlite3_value_nochange sqlite3_api->value_nochange +#define sqlite3_vtab_collation sqlite3_api->vtab_collation /* Version 3.24.0 and later */ -#define tdsqlite3_keyword_count tdsqlite3_api->keyword_count -#define tdsqlite3_keyword_name tdsqlite3_api->keyword_name -#define tdsqlite3_keyword_check tdsqlite3_api->keyword_check -#define tdsqlite3_str_new tdsqlite3_api->str_new -#define tdsqlite3_str_finish tdsqlite3_api->str_finish -#define tdsqlite3_str_appendf tdsqlite3_api->str_appendf -#define tdsqlite3_str_vappendf tdsqlite3_api->str_vappendf -#define tdsqlite3_str_append tdsqlite3_api->str_append -#define tdsqlite3_str_appendall tdsqlite3_api->str_appendall -#define tdsqlite3_str_appendchar tdsqlite3_api->str_appendchar -#define tdsqlite3_str_reset tdsqlite3_api->str_reset -#define tdsqlite3_str_errcode tdsqlite3_api->str_errcode -#define tdsqlite3_str_length tdsqlite3_api->str_length -#define tdsqlite3_str_value tdsqlite3_api->str_value +#define sqlite3_keyword_count sqlite3_api->keyword_count +#define sqlite3_keyword_name sqlite3_api->keyword_name +#define sqlite3_keyword_check sqlite3_api->keyword_check +#define sqlite3_str_new sqlite3_api->str_new +#define sqlite3_str_finish sqlite3_api->str_finish +#define sqlite3_str_appendf sqlite3_api->str_appendf +#define sqlite3_str_vappendf sqlite3_api->str_vappendf +#define sqlite3_str_append sqlite3_api->str_append +#define sqlite3_str_appendall sqlite3_api->str_appendall +#define sqlite3_str_appendchar sqlite3_api->str_appendchar +#define sqlite3_str_reset sqlite3_api->str_reset +#define sqlite3_str_errcode sqlite3_api->str_errcode +#define sqlite3_str_length sqlite3_api->str_length +#define sqlite3_str_value sqlite3_api->str_value /* Version 3.25.0 and later */ -#define tdsqlite3_create_window_function tdsqlite3_api->create_window_function +#define sqlite3_create_window_function sqlite3_api->create_window_function /* Version 3.26.0 and later */ -#define tdsqlite3_normalized_sql tdsqlite3_api->normalized_sql +#define sqlite3_normalized_sql sqlite3_api->normalized_sql /* Version 3.28.0 and later */ -#define tdsqlite3_stmt_isexplain tdsqlite3_api->isexplain -#define tdsqlite3_value_frombind tdsqlite3_api->frombind +#define sqlite3_stmt_isexplain sqlite3_api->isexplain +#define sqlite3_value_frombind sqlite3_api->frombind /* Version 3.30.0 and later */ -#define tdsqlite3_drop_modules tdsqlite3_api->drop_modules +#define sqlite3_drop_modules sqlite3_api->drop_modules /* Version 3.31.0 andn later */ -#define tdsqlite3_hard_heap_limit64 tdsqlite3_api->hard_heap_limit64 -#define tdsqlite3_uri_key tdsqlite3_api->uri_key -#define tdsqlite3_filename_database tdsqlite3_api->filename_database -#define tdsqlite3_filename_journal tdsqlite3_api->filename_journal -#define tdsqlite3_filename_wal tdsqlite3_api->filename_wal +#define sqlite3_hard_heap_limit64 sqlite3_api->hard_heap_limit64 +#define sqlite3_uri_key sqlite3_api->uri_key +#define sqlite3_filename_database sqlite3_api->filename_database +#define sqlite3_filename_journal sqlite3_api->filename_journal +#define sqlite3_filename_wal sqlite3_api->filename_wal #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ -# define SQLITE_EXTENSION_INIT1 const tdsqlite3_api_routines *tdsqlite3_api=0; -# define SQLITE_EXTENSION_INIT2(v) tdsqlite3_api=v; +# define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; +# define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; # define SQLITE_EXTENSION_INIT3 \ - extern const tdsqlite3_api_routines *tdsqlite3_api; + extern const sqlite3_api_routines *sqlite3_api; #else /* This case when the file is being statically linked into the ** application */ @@ -126444,7 +126444,7 @@ typedef int (*tdsqlite3_loadext_entry)( #endif /* SQLITE3EXT_H */ -/************** End of tdsqlite3ext.h ******************************************/ +/************** End of sqlite3ext.h ******************************************/ /************** Continuing where we left off in loadext.c ********************/ /* #include "sqliteInt.h" */ @@ -126455,93 +126455,93 @@ typedef int (*tdsqlite3_loadext_entry)( ** for any missing APIs. */ #ifndef SQLITE_ENABLE_COLUMN_METADATA -# define tdsqlite3_column_database_name 0 -# define tdsqlite3_column_database_name16 0 -# define tdsqlite3_column_table_name 0 -# define tdsqlite3_column_table_name16 0 -# define tdsqlite3_column_origin_name 0 -# define tdsqlite3_column_origin_name16 0 +# define sqlite3_column_database_name 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name 0 +# define sqlite3_column_origin_name16 0 #endif #ifdef SQLITE_OMIT_AUTHORIZATION -# define tdsqlite3_set_authorizer 0 +# define sqlite3_set_authorizer 0 #endif #ifdef SQLITE_OMIT_UTF16 -# define tdsqlite3_bind_text16 0 -# define tdsqlite3_collation_needed16 0 -# define tdsqlite3_column_decltype16 0 -# define tdsqlite3_column_name16 0 -# define tdsqlite3_column_text16 0 -# define tdsqlite3_complete16 0 -# define tdsqlite3_create_collation16 0 -# define tdsqlite3_create_function16 0 -# define tdsqlite3_errmsg16 0 -# define tdsqlite3_open16 0 -# define tdsqlite3_prepare16 0 -# define tdsqlite3_prepare16_v2 0 -# define tdsqlite3_prepare16_v3 0 -# define tdsqlite3_result_error16 0 -# define tdsqlite3_result_text16 0 -# define tdsqlite3_result_text16be 0 -# define tdsqlite3_result_text16le 0 -# define tdsqlite3_value_text16 0 -# define tdsqlite3_value_text16be 0 -# define tdsqlite3_value_text16le 0 -# define tdsqlite3_column_database_name16 0 -# define tdsqlite3_column_table_name16 0 -# define tdsqlite3_column_origin_name16 0 +# define sqlite3_bind_text16 0 +# define sqlite3_collation_needed16 0 +# define sqlite3_column_decltype16 0 +# define sqlite3_column_name16 0 +# define sqlite3_column_text16 0 +# define sqlite3_complete16 0 +# define sqlite3_create_collation16 0 +# define sqlite3_create_function16 0 +# define sqlite3_errmsg16 0 +# define sqlite3_open16 0 +# define sqlite3_prepare16 0 +# define sqlite3_prepare16_v2 0 +# define sqlite3_prepare16_v3 0 +# define sqlite3_result_error16 0 +# define sqlite3_result_text16 0 +# define sqlite3_result_text16be 0 +# define sqlite3_result_text16le 0 +# define sqlite3_value_text16 0 +# define sqlite3_value_text16be 0 +# define sqlite3_value_text16le 0 +# define sqlite3_column_database_name16 0 +# define sqlite3_column_table_name16 0 +# define sqlite3_column_origin_name16 0 #endif #ifdef SQLITE_OMIT_COMPLETE -# define tdsqlite3_complete 0 -# define tdsqlite3_complete16 0 +# define sqlite3_complete 0 +# define sqlite3_complete16 0 #endif #ifdef SQLITE_OMIT_DECLTYPE -# define tdsqlite3_column_decltype16 0 -# define tdsqlite3_column_decltype 0 +# define sqlite3_column_decltype16 0 +# define sqlite3_column_decltype 0 #endif #ifdef SQLITE_OMIT_PROGRESS_CALLBACK -# define tdsqlite3_progress_handler 0 +# define sqlite3_progress_handler 0 #endif #ifdef SQLITE_OMIT_VIRTUALTABLE -# define tdsqlite3_create_module 0 -# define tdsqlite3_create_module_v2 0 -# define tdsqlite3_declare_vtab 0 -# define tdsqlite3_vtab_config 0 -# define tdsqlite3_vtab_on_conflict 0 -# define tdsqlite3_vtab_collation 0 +# define sqlite3_create_module 0 +# define sqlite3_create_module_v2 0 +# define sqlite3_declare_vtab 0 +# define sqlite3_vtab_config 0 +# define sqlite3_vtab_on_conflict 0 +# define sqlite3_vtab_collation 0 #endif #ifdef SQLITE_OMIT_SHARED_CACHE -# define tdsqlite3_enable_shared_cache 0 +# define sqlite3_enable_shared_cache 0 #endif #if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED) -# define tdsqlite3_profile 0 -# define tdsqlite3_trace 0 +# define sqlite3_profile 0 +# define sqlite3_trace 0 #endif #ifdef SQLITE_OMIT_GET_TABLE -# define tdsqlite3_free_table 0 -# define tdsqlite3_get_table 0 +# define sqlite3_free_table 0 +# define sqlite3_get_table 0 #endif #ifdef SQLITE_OMIT_INCRBLOB -#define tdsqlite3_bind_zeroblob 0 -#define tdsqlite3_blob_bytes 0 -#define tdsqlite3_blob_close 0 -#define tdsqlite3_blob_open 0 -#define tdsqlite3_blob_read 0 -#define tdsqlite3_blob_write 0 -#define tdsqlite3_blob_reopen 0 +#define sqlite3_bind_zeroblob 0 +#define sqlite3_blob_bytes 0 +#define sqlite3_blob_close 0 +#define sqlite3_blob_open 0 +#define sqlite3_blob_read 0 +#define sqlite3_blob_write 0 +#define sqlite3_blob_reopen 0 #endif #if defined(SQLITE_OMIT_TRACE) -# define tdsqlite3_trace_v2 0 +# define sqlite3_trace_v2 0 #endif /* @@ -126554,178 +126554,178 @@ typedef int (*tdsqlite3_loadext_entry)( ** in order to preserve backwards compatibility. ** ** Extensions that use newer APIs should first call the -** tdsqlite3_libversion_number() to make sure that the API they +** sqlite3_libversion_number() to make sure that the API they ** intend to use is supported by the library. Extensions should ** also check to make sure that the pointer to the function is ** not NULL before calling it. */ -static const tdsqlite3_api_routines tdsqlite3Apis = { - tdsqlite3_aggregate_context, +static const sqlite3_api_routines sqlite3Apis = { + sqlite3_aggregate_context, #ifndef SQLITE_OMIT_DEPRECATED - tdsqlite3_aggregate_count, + sqlite3_aggregate_count, #else 0, #endif - tdsqlite3_bind_blob, - tdsqlite3_bind_double, - tdsqlite3_bind_int, - tdsqlite3_bind_int64, - tdsqlite3_bind_null, - tdsqlite3_bind_parameter_count, - tdsqlite3_bind_parameter_index, - tdsqlite3_bind_parameter_name, - tdsqlite3_bind_text, - tdsqlite3_bind_text16, - tdsqlite3_bind_value, - tdsqlite3_busy_handler, - tdsqlite3_busy_timeout, - tdsqlite3_changes, - tdsqlite3_close, - tdsqlite3_collation_needed, - tdsqlite3_collation_needed16, - tdsqlite3_column_blob, - tdsqlite3_column_bytes, - tdsqlite3_column_bytes16, - tdsqlite3_column_count, - tdsqlite3_column_database_name, - tdsqlite3_column_database_name16, - tdsqlite3_column_decltype, - tdsqlite3_column_decltype16, - tdsqlite3_column_double, - tdsqlite3_column_int, - tdsqlite3_column_int64, - tdsqlite3_column_name, - tdsqlite3_column_name16, - tdsqlite3_column_origin_name, - tdsqlite3_column_origin_name16, - tdsqlite3_column_table_name, - tdsqlite3_column_table_name16, - tdsqlite3_column_text, - tdsqlite3_column_text16, - tdsqlite3_column_type, - tdsqlite3_column_value, - tdsqlite3_commit_hook, - tdsqlite3_complete, - tdsqlite3_complete16, - tdsqlite3_create_collation, - tdsqlite3_create_collation16, - tdsqlite3_create_function, - tdsqlite3_create_function16, - tdsqlite3_create_module, - tdsqlite3_data_count, - tdsqlite3_db_handle, - tdsqlite3_declare_vtab, - tdsqlite3_enable_shared_cache, - tdsqlite3_errcode, - tdsqlite3_errmsg, - tdsqlite3_errmsg16, - tdsqlite3_exec, + sqlite3_bind_blob, + sqlite3_bind_double, + sqlite3_bind_int, + sqlite3_bind_int64, + sqlite3_bind_null, + sqlite3_bind_parameter_count, + sqlite3_bind_parameter_index, + sqlite3_bind_parameter_name, + sqlite3_bind_text, + sqlite3_bind_text16, + sqlite3_bind_value, + sqlite3_busy_handler, + sqlite3_busy_timeout, + sqlite3_changes, + sqlite3_close, + sqlite3_collation_needed, + sqlite3_collation_needed16, + sqlite3_column_blob, + sqlite3_column_bytes, + sqlite3_column_bytes16, + sqlite3_column_count, + sqlite3_column_database_name, + sqlite3_column_database_name16, + sqlite3_column_decltype, + sqlite3_column_decltype16, + sqlite3_column_double, + sqlite3_column_int, + sqlite3_column_int64, + sqlite3_column_name, + sqlite3_column_name16, + sqlite3_column_origin_name, + sqlite3_column_origin_name16, + sqlite3_column_table_name, + sqlite3_column_table_name16, + sqlite3_column_text, + sqlite3_column_text16, + sqlite3_column_type, + sqlite3_column_value, + sqlite3_commit_hook, + sqlite3_complete, + sqlite3_complete16, + sqlite3_create_collation, + sqlite3_create_collation16, + sqlite3_create_function, + sqlite3_create_function16, + sqlite3_create_module, + sqlite3_data_count, + sqlite3_db_handle, + sqlite3_declare_vtab, + sqlite3_enable_shared_cache, + sqlite3_errcode, + sqlite3_errmsg, + sqlite3_errmsg16, + sqlite3_exec, #ifndef SQLITE_OMIT_DEPRECATED - tdsqlite3_expired, + sqlite3_expired, #else 0, #endif - tdsqlite3_finalize, - tdsqlite3_free, - tdsqlite3_free_table, - tdsqlite3_get_autocommit, - tdsqlite3_get_auxdata, - tdsqlite3_get_table, - 0, /* Was tdsqlite3_global_recover(), but that function is deprecated */ - tdsqlite3_interrupt, - tdsqlite3_last_insert_rowid, - tdsqlite3_libversion, - tdsqlite3_libversion_number, - tdsqlite3_malloc, - tdsqlite3_mprintf, - tdsqlite3_open, - tdsqlite3_open16, - tdsqlite3_prepare, - tdsqlite3_prepare16, - tdsqlite3_profile, - tdsqlite3_progress_handler, - tdsqlite3_realloc, - tdsqlite3_reset, - tdsqlite3_result_blob, - tdsqlite3_result_double, - tdsqlite3_result_error, - tdsqlite3_result_error16, - tdsqlite3_result_int, - tdsqlite3_result_int64, - tdsqlite3_result_null, - tdsqlite3_result_text, - tdsqlite3_result_text16, - tdsqlite3_result_text16be, - tdsqlite3_result_text16le, - tdsqlite3_result_value, - tdsqlite3_rollback_hook, - tdsqlite3_set_authorizer, - tdsqlite3_set_auxdata, - tdsqlite3_snprintf, - tdsqlite3_step, - tdsqlite3_table_column_metadata, + sqlite3_finalize, + sqlite3_free, + sqlite3_free_table, + sqlite3_get_autocommit, + sqlite3_get_auxdata, + sqlite3_get_table, + 0, /* Was sqlite3_global_recover(), but that function is deprecated */ + sqlite3_interrupt, + sqlite3_last_insert_rowid, + sqlite3_libversion, + sqlite3_libversion_number, + sqlite3_malloc, + sqlite3_mprintf, + sqlite3_open, + sqlite3_open16, + sqlite3_prepare, + sqlite3_prepare16, + sqlite3_profile, + sqlite3_progress_handler, + sqlite3_realloc, + sqlite3_reset, + sqlite3_result_blob, + sqlite3_result_double, + sqlite3_result_error, + sqlite3_result_error16, + sqlite3_result_int, + sqlite3_result_int64, + sqlite3_result_null, + sqlite3_result_text, + sqlite3_result_text16, + sqlite3_result_text16be, + sqlite3_result_text16le, + sqlite3_result_value, + sqlite3_rollback_hook, + sqlite3_set_authorizer, + sqlite3_set_auxdata, + sqlite3_snprintf, + sqlite3_step, + sqlite3_table_column_metadata, #ifndef SQLITE_OMIT_DEPRECATED - tdsqlite3_thread_cleanup, + sqlite3_thread_cleanup, #else 0, #endif - tdsqlite3_total_changes, - tdsqlite3_trace, + sqlite3_total_changes, + sqlite3_trace, #ifndef SQLITE_OMIT_DEPRECATED - tdsqlite3_transfer_bindings, + sqlite3_transfer_bindings, #else 0, #endif - tdsqlite3_update_hook, - tdsqlite3_user_data, - tdsqlite3_value_blob, - tdsqlite3_value_bytes, - tdsqlite3_value_bytes16, - tdsqlite3_value_double, - tdsqlite3_value_int, - tdsqlite3_value_int64, - tdsqlite3_value_numeric_type, - tdsqlite3_value_text, - tdsqlite3_value_text16, - tdsqlite3_value_text16be, - tdsqlite3_value_text16le, - tdsqlite3_value_type, - tdsqlite3_vmprintf, + sqlite3_update_hook, + sqlite3_user_data, + sqlite3_value_blob, + sqlite3_value_bytes, + sqlite3_value_bytes16, + sqlite3_value_double, + sqlite3_value_int, + sqlite3_value_int64, + sqlite3_value_numeric_type, + sqlite3_value_text, + sqlite3_value_text16, + sqlite3_value_text16be, + sqlite3_value_text16le, + sqlite3_value_type, + sqlite3_vmprintf, /* ** The original API set ends here. All extensions can call any ** of the APIs above provided that the pointer is not NULL. But ** before calling APIs that follow, extension should check the - ** tdsqlite3_libversion_number() to make sure they are dealing with + ** sqlite3_libversion_number() to make sure they are dealing with ** a library that is new enough to support that API. ************************************************************************* */ - tdsqlite3_overload_function, + sqlite3_overload_function, /* ** Added after 3.3.13 */ - tdsqlite3_prepare_v2, - tdsqlite3_prepare16_v2, - tdsqlite3_clear_bindings, + sqlite3_prepare_v2, + sqlite3_prepare16_v2, + sqlite3_clear_bindings, /* ** Added for 3.4.1 */ - tdsqlite3_create_module_v2, + sqlite3_create_module_v2, /* ** Added for 3.5.0 */ - tdsqlite3_bind_zeroblob, - tdsqlite3_blob_bytes, - tdsqlite3_blob_close, - tdsqlite3_blob_open, - tdsqlite3_blob_read, - tdsqlite3_blob_write, - tdsqlite3_create_collation_v2, - tdsqlite3_file_control, - tdsqlite3_memory_highwater, - tdsqlite3_memory_used, + sqlite3_bind_zeroblob, + sqlite3_blob_bytes, + sqlite3_blob_close, + sqlite3_blob_open, + sqlite3_blob_read, + sqlite3_blob_write, + sqlite3_create_collation_v2, + sqlite3_file_control, + sqlite3_memory_highwater, + sqlite3_memory_used, #ifdef SQLITE_MUTEX_OMIT 0, 0, @@ -126733,204 +126733,204 @@ static const tdsqlite3_api_routines tdsqlite3Apis = { 0, 0, #else - tdsqlite3_mutex_alloc, - tdsqlite3_mutex_enter, - tdsqlite3_mutex_free, - tdsqlite3_mutex_leave, - tdsqlite3_mutex_try, -#endif - tdsqlite3_open_v2, - tdsqlite3_release_memory, - tdsqlite3_result_error_nomem, - tdsqlite3_result_error_toobig, - tdsqlite3_sleep, - tdsqlite3_soft_heap_limit, - tdsqlite3_vfs_find, - tdsqlite3_vfs_register, - tdsqlite3_vfs_unregister, + sqlite3_mutex_alloc, + sqlite3_mutex_enter, + sqlite3_mutex_free, + sqlite3_mutex_leave, + sqlite3_mutex_try, +#endif + sqlite3_open_v2, + sqlite3_release_memory, + sqlite3_result_error_nomem, + sqlite3_result_error_toobig, + sqlite3_sleep, + sqlite3_soft_heap_limit, + sqlite3_vfs_find, + sqlite3_vfs_register, + sqlite3_vfs_unregister, /* ** Added for 3.5.8 */ - tdsqlite3_threadsafe, - tdsqlite3_result_zeroblob, - tdsqlite3_result_error_code, - tdsqlite3_test_control, - tdsqlite3_randomness, - tdsqlite3_context_db_handle, + sqlite3_threadsafe, + sqlite3_result_zeroblob, + sqlite3_result_error_code, + sqlite3_test_control, + sqlite3_randomness, + sqlite3_context_db_handle, /* ** Added for 3.6.0 */ - tdsqlite3_extended_result_codes, - tdsqlite3_limit, - tdsqlite3_next_stmt, - tdsqlite3_sql, - tdsqlite3_status, + sqlite3_extended_result_codes, + sqlite3_limit, + sqlite3_next_stmt, + sqlite3_sql, + sqlite3_status, /* ** Added for 3.7.4 */ - tdsqlite3_backup_finish, - tdsqlite3_backup_init, - tdsqlite3_backup_pagecount, - tdsqlite3_backup_remaining, - tdsqlite3_backup_step, + sqlite3_backup_finish, + sqlite3_backup_init, + sqlite3_backup_pagecount, + sqlite3_backup_remaining, + sqlite3_backup_step, #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS - tdsqlite3_compileoption_get, - tdsqlite3_compileoption_used, + sqlite3_compileoption_get, + sqlite3_compileoption_used, #else 0, 0, #endif - tdsqlite3_create_function_v2, - tdsqlite3_db_config, - tdsqlite3_db_mutex, - tdsqlite3_db_status, - tdsqlite3_extended_errcode, - tdsqlite3_log, - tdsqlite3_soft_heap_limit64, - tdsqlite3_sourceid, - tdsqlite3_stmt_status, - tdsqlite3_strnicmp, + sqlite3_create_function_v2, + sqlite3_db_config, + sqlite3_db_mutex, + sqlite3_db_status, + sqlite3_extended_errcode, + sqlite3_log, + sqlite3_soft_heap_limit64, + sqlite3_sourceid, + sqlite3_stmt_status, + sqlite3_strnicmp, #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY - tdsqlite3_unlock_notify, + sqlite3_unlock_notify, #else 0, #endif #ifndef SQLITE_OMIT_WAL - tdsqlite3_wal_autocheckpoint, - tdsqlite3_wal_checkpoint, - tdsqlite3_wal_hook, + sqlite3_wal_autocheckpoint, + sqlite3_wal_checkpoint, + sqlite3_wal_hook, #else 0, 0, 0, #endif - tdsqlite3_blob_reopen, - tdsqlite3_vtab_config, - tdsqlite3_vtab_on_conflict, - tdsqlite3_close_v2, - tdsqlite3_db_filename, - tdsqlite3_db_readonly, - tdsqlite3_db_release_memory, - tdsqlite3_errstr, - tdsqlite3_stmt_busy, - tdsqlite3_stmt_readonly, - tdsqlite3_stricmp, - tdsqlite3_uri_boolean, - tdsqlite3_uri_int64, - tdsqlite3_uri_parameter, - tdsqlite3_vsnprintf, - tdsqlite3_wal_checkpoint_v2, + sqlite3_blob_reopen, + sqlite3_vtab_config, + sqlite3_vtab_on_conflict, + sqlite3_close_v2, + sqlite3_db_filename, + sqlite3_db_readonly, + sqlite3_db_release_memory, + sqlite3_errstr, + sqlite3_stmt_busy, + sqlite3_stmt_readonly, + sqlite3_stricmp, + sqlite3_uri_boolean, + sqlite3_uri_int64, + sqlite3_uri_parameter, + sqlite3_vsnprintf, + sqlite3_wal_checkpoint_v2, /* Version 3.8.7 and later */ - tdsqlite3_auto_extension, - tdsqlite3_bind_blob64, - tdsqlite3_bind_text64, - tdsqlite3_cancel_auto_extension, - tdsqlite3_load_extension, - tdsqlite3_malloc64, - tdsqlite3_msize, - tdsqlite3_realloc64, - tdsqlite3_reset_auto_extension, - tdsqlite3_result_blob64, - tdsqlite3_result_text64, - tdsqlite3_strglob, + sqlite3_auto_extension, + sqlite3_bind_blob64, + sqlite3_bind_text64, + sqlite3_cancel_auto_extension, + sqlite3_load_extension, + sqlite3_malloc64, + sqlite3_msize, + sqlite3_realloc64, + sqlite3_reset_auto_extension, + sqlite3_result_blob64, + sqlite3_result_text64, + sqlite3_strglob, /* Version 3.8.11 and later */ - (tdsqlite3_value*(*)(const tdsqlite3_value*))tdsqlite3_value_dup, - tdsqlite3_value_free, - tdsqlite3_result_zeroblob64, - tdsqlite3_bind_zeroblob64, + (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup, + sqlite3_value_free, + sqlite3_result_zeroblob64, + sqlite3_bind_zeroblob64, /* Version 3.9.0 and later */ - tdsqlite3_value_subtype, - tdsqlite3_result_subtype, + sqlite3_value_subtype, + sqlite3_result_subtype, /* Version 3.10.0 and later */ - tdsqlite3_status64, - tdsqlite3_strlike, - tdsqlite3_db_cacheflush, + sqlite3_status64, + sqlite3_strlike, + sqlite3_db_cacheflush, /* Version 3.12.0 and later */ - tdsqlite3_system_errno, + sqlite3_system_errno, /* Version 3.14.0 and later */ - tdsqlite3_trace_v2, - tdsqlite3_expanded_sql, + sqlite3_trace_v2, + sqlite3_expanded_sql, /* Version 3.18.0 and later */ - tdsqlite3_set_last_insert_rowid, + sqlite3_set_last_insert_rowid, /* Version 3.20.0 and later */ - tdsqlite3_prepare_v3, - tdsqlite3_prepare16_v3, - tdsqlite3_bind_pointer, - tdsqlite3_result_pointer, - tdsqlite3_value_pointer, + sqlite3_prepare_v3, + sqlite3_prepare16_v3, + sqlite3_bind_pointer, + sqlite3_result_pointer, + sqlite3_value_pointer, /* Version 3.22.0 and later */ - tdsqlite3_vtab_nochange, - tdsqlite3_value_nochange, - tdsqlite3_vtab_collation, + sqlite3_vtab_nochange, + sqlite3_value_nochange, + sqlite3_vtab_collation, /* Version 3.24.0 and later */ - tdsqlite3_keyword_count, - tdsqlite3_keyword_name, - tdsqlite3_keyword_check, - tdsqlite3_str_new, - tdsqlite3_str_finish, - tdsqlite3_str_appendf, - tdsqlite3_str_vappendf, - tdsqlite3_str_append, - tdsqlite3_str_appendall, - tdsqlite3_str_appendchar, - tdsqlite3_str_reset, - tdsqlite3_str_errcode, - tdsqlite3_str_length, - tdsqlite3_str_value, + sqlite3_keyword_count, + sqlite3_keyword_name, + sqlite3_keyword_check, + sqlite3_str_new, + sqlite3_str_finish, + sqlite3_str_appendf, + sqlite3_str_vappendf, + sqlite3_str_append, + sqlite3_str_appendall, + sqlite3_str_appendchar, + sqlite3_str_reset, + sqlite3_str_errcode, + sqlite3_str_length, + sqlite3_str_value, /* Version 3.25.0 and later */ - tdsqlite3_create_window_function, + sqlite3_create_window_function, /* Version 3.26.0 and later */ #ifdef SQLITE_ENABLE_NORMALIZE - tdsqlite3_normalized_sql, + sqlite3_normalized_sql, #else 0, #endif /* Version 3.28.0 and later */ - tdsqlite3_stmt_isexplain, - tdsqlite3_value_frombind, + sqlite3_stmt_isexplain, + sqlite3_value_frombind, /* Version 3.30.0 and later */ #ifndef SQLITE_OMIT_VIRTUALTABLE - tdsqlite3_drop_modules, + sqlite3_drop_modules, #else 0, #endif /* Version 3.31.0 and later */ - tdsqlite3_hard_heap_limit64, - tdsqlite3_uri_key, - tdsqlite3_filename_database, - tdsqlite3_filename_journal, - tdsqlite3_filename_wal, + sqlite3_hard_heap_limit64, + sqlite3_uri_key, + sqlite3_filename_database, + sqlite3_filename_journal, + sqlite3_filename_wal, }; /* ** Attempt to load an SQLite extension library contained in the file ** zFile. The entry point is zProc. zProc may be 0 in which case a -** default entry point name (tdsqlite3_extension_init) is used. Use +** default entry point name (sqlite3_extension_init) is used. Use ** of the default name is recommended. ** ** Return SQLITE_OK on success and SQLITE_ERROR if something goes wrong. ** ** If an error occurs and pzErrMsg is not 0, then fill *pzErrMsg with ** error message text. The calling function should free this memory -** by calling tdsqlite3DbFree(db, ). +** by calling sqlite3DbFree(db, ). */ -static int tdsqlite3LoadExtension( - tdsqlite3 *db, /* Load the extension into this database connection */ +static int sqlite3LoadExtension( + sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ - const char *zProc, /* Entry point. Use "tdsqlite3_extension_init" if 0 */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ char **pzErrMsg /* Put error message here if not 0 */ ){ - tdsqlite3_vfs *pVfs = db->pVfs; + sqlite3_vfs *pVfs = db->pVfs; void *handle; - tdsqlite3_loadext_entry xInit; + sqlite3_loadext_entry xInit; char *zErrmsg = 0; const char *zEntry; char *zAltEntry = 0; void **aHandle; - u64 nMsg = 300 + tdsqlite3Strlen30(zFile); + u64 nMsg = 300 + sqlite3Strlen30(zFile); int ii; int rc; @@ -126951,124 +126951,124 @@ static int tdsqlite3LoadExtension( /* Ticket #1863. To avoid a creating security problems for older ** applications that relink against newer versions of SQLite, the ** ability to run load_extension is turned off by default. One - ** must call either tdsqlite3_enable_load_extension(db) or - ** tdsqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0) + ** must call either sqlite3_enable_load_extension(db) or + ** sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, 1, 0) ** to turn on extension loading. */ if( (db->flags & SQLITE_LoadExtension)==0 ){ if( pzErrMsg ){ - *pzErrMsg = tdsqlite3_mprintf("not authorized"); + *pzErrMsg = sqlite3_mprintf("not authorized"); } return SQLITE_ERROR; } - zEntry = zProc ? zProc : "tdsqlite3_extension_init"; + zEntry = zProc ? zProc : "sqlite3_extension_init"; - handle = tdsqlite3OsDlOpen(pVfs, zFile); + handle = sqlite3OsDlOpen(pVfs, zFile); #if SQLITE_OS_UNIX || SQLITE_OS_WIN for(ii=0; ii tdsqlite3_example_init - ** C:/lib/mathfuncs.dll ==> tdsqlite3_mathfuncs_init + ** /usr/local/lib/libExample5.4.3.so ==> sqlite3_example_init + ** C:/lib/mathfuncs.dll ==> sqlite3_mathfuncs_init */ if( xInit==0 && zProc==0 ){ int iFile, iEntry, c; - int ncFile = tdsqlite3Strlen30(zFile); - zAltEntry = tdsqlite3_malloc64(ncFile+30); + int ncFile = sqlite3Strlen30(zFile); + zAltEntry = sqlite3_malloc64(ncFile+30); if( zAltEntry==0 ){ - tdsqlite3OsDlClose(pVfs, handle); + sqlite3OsDlClose(pVfs, handle); return SQLITE_NOMEM_BKPT; } - memcpy(zAltEntry, "tdsqlite3_", 8); + memcpy(zAltEntry, "sqlite3_", 8); for(iFile=ncFile-1; iFile>=0 && zFile[iFile]!='/'; iFile--){} iFile++; - if( tdsqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; + if( sqlite3_strnicmp(zFile+iFile, "lib", 3)==0 ) iFile += 3; for(iEntry=8; (c = zFile[iFile])!=0 && c!='.'; iFile++){ - if( tdsqlite3Isalpha(c) ){ - zAltEntry[iEntry++] = (char)tdsqlite3UpperToLower[(unsigned)c]; + if( sqlite3Isalpha(c) ){ + zAltEntry[iEntry++] = (char)sqlite3UpperToLower[(unsigned)c]; } } memcpy(zAltEntry+iEntry, "_init", 6); zEntry = zAltEntry; - xInit = (tdsqlite3_loadext_entry)tdsqlite3OsDlSym(pVfs, handle, zEntry); + xInit = (sqlite3_loadext_entry)sqlite3OsDlSym(pVfs, handle, zEntry); } if( xInit==0 ){ if( pzErrMsg ){ - nMsg += tdsqlite3Strlen30(zEntry); - *pzErrMsg = zErrmsg = tdsqlite3_malloc64(nMsg); + nMsg += sqlite3Strlen30(zEntry); + *pzErrMsg = zErrmsg = sqlite3_malloc64(nMsg); if( zErrmsg ){ - tdsqlite3_snprintf(nMsg, zErrmsg, + sqlite3_snprintf(nMsg, zErrmsg, "no entry point [%s] in shared library [%s]", zEntry, zFile); - tdsqlite3OsDlError(pVfs, nMsg-1, zErrmsg); + sqlite3OsDlError(pVfs, nMsg-1, zErrmsg); } } - tdsqlite3OsDlClose(pVfs, handle); - tdsqlite3_free(zAltEntry); + sqlite3OsDlClose(pVfs, handle); + sqlite3_free(zAltEntry); return SQLITE_ERROR; } - tdsqlite3_free(zAltEntry); - rc = xInit(db, &zErrmsg, &tdsqlite3Apis); + sqlite3_free(zAltEntry); + rc = xInit(db, &zErrmsg, &sqlite3Apis); if( rc ){ if( rc==SQLITE_OK_LOAD_PERMANENTLY ) return SQLITE_OK; if( pzErrMsg ){ - *pzErrMsg = tdsqlite3_mprintf("error during initialization: %s", zErrmsg); + *pzErrMsg = sqlite3_mprintf("error during initialization: %s", zErrmsg); } - tdsqlite3_free(zErrmsg); - tdsqlite3OsDlClose(pVfs, handle); + sqlite3_free(zErrmsg); + sqlite3OsDlClose(pVfs, handle); return SQLITE_ERROR; } /* Append the new shared library handle to the db->aExtension array. */ - aHandle = tdsqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1)); + aHandle = sqlite3DbMallocZero(db, sizeof(handle)*(db->nExtension+1)); if( aHandle==0 ){ return SQLITE_NOMEM_BKPT; } if( db->nExtension>0 ){ memcpy(aHandle, db->aExtension, sizeof(handle)*db->nExtension); } - tdsqlite3DbFree(db, db->aExtension); + sqlite3DbFree(db, db->aExtension); db->aExtension = aHandle; db->aExtension[db->nExtension++] = handle; return SQLITE_OK; } -SQLITE_API int tdsqlite3_load_extension( - tdsqlite3 *db, /* Load the extension into this database connection */ +SQLITE_API int sqlite3_load_extension( + sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ - const char *zProc, /* Entry point. Use "tdsqlite3_extension_init" if 0 */ + const char *zProc, /* Entry point. Use "sqlite3_extension_init" if 0 */ char **pzErrMsg /* Put error message here if not 0 */ ){ int rc; - tdsqlite3_mutex_enter(db->mutex); - rc = tdsqlite3LoadExtension(db, zFile, zProc, pzErrMsg); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_enter(db->mutex); + rc = sqlite3LoadExtension(db, zFile, zProc, pzErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -127076,27 +127076,27 @@ SQLITE_API int tdsqlite3_load_extension( ** Call this routine when the database connection is closing in order ** to clean up loaded extensions */ -SQLITE_PRIVATE void tdsqlite3CloseExtensions(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3CloseExtensions(sqlite3 *db){ int i; - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); for(i=0; inExtension; i++){ - tdsqlite3OsDlClose(db->pVfs, db->aExtension[i]); + sqlite3OsDlClose(db->pVfs, db->aExtension[i]); } - tdsqlite3DbFree(db, db->aExtension); + sqlite3DbFree(db, db->aExtension); } /* ** Enable or disable extension loading. Extension loading is disabled by ** default so as not to open security holes in older applications. */ -SQLITE_API int tdsqlite3_enable_load_extension(tdsqlite3 *db, int onoff){ - tdsqlite3_mutex_enter(db->mutex); +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ + sqlite3_mutex_enter(db->mutex); if( onoff ){ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; }else{ db->flags &= ~(u64)(SQLITE_LoadExtension|SQLITE_LoadExtFunc); } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -127109,25 +127109,25 @@ SQLITE_API int tdsqlite3_enable_load_extension(tdsqlite3 *db, int onoff){ ** This list is shared across threads. The SQLITE_MUTEX_STATIC_MASTER ** mutex must be held while accessing this list. */ -typedef struct tdsqlite3AutoExtList tdsqlite3AutoExtList; -static SQLITE_WSD struct tdsqlite3AutoExtList { +typedef struct sqlite3AutoExtList sqlite3AutoExtList; +static SQLITE_WSD struct sqlite3AutoExtList { u32 nExt; /* Number of entries in aExt[] */ void (**aExt)(void); /* Pointers to the extension init functions */ -} tdsqlite3Autoext = { 0, 0 }; +} sqlite3Autoext = { 0, 0 }; /* The "wsdAutoext" macro will resolve to the autoextension ** state vector. If writable static data is unsupported on the target, ** we have to locate the state vector at run-time. In the more common ** case where writable static data is supported, wsdStat can refer directly -** to the "tdsqlite3Autoext" state vector declared above. +** to the "sqlite3Autoext" state vector declared above. */ #ifdef SQLITE_OMIT_WSD # define wsdAutoextInit \ - tdsqlite3AutoExtList *x = &GLOBAL(tdsqlite3AutoExtList,tdsqlite3Autoext) + sqlite3AutoExtList *x = &GLOBAL(sqlite3AutoExtList,sqlite3Autoext) # define wsdAutoext x[0] #else # define wsdAutoextInit -# define wsdAutoext tdsqlite3Autoext +# define wsdAutoext sqlite3Autoext #endif @@ -127135,12 +127135,12 @@ static SQLITE_WSD struct tdsqlite3AutoExtList { ** Register a statically linked extension that is automatically ** loaded by every new database connection. */ -SQLITE_API int tdsqlite3_auto_extension( +SQLITE_API int sqlite3_auto_extension( void (*xInit)(void) ){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_AUTOINIT - rc = tdsqlite3_initialize(); + rc = sqlite3_initialize(); if( rc ){ return rc; }else @@ -127148,17 +127148,17 @@ SQLITE_API int tdsqlite3_auto_extension( { u32 i; #if SQLITE_THREADSAFE - tdsqlite3_mutex *mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif wsdAutoextInit; - tdsqlite3_mutex_enter(mutex); + sqlite3_mutex_enter(mutex); for(i=0; i=0; i--){ if( wsdAutoext.aExt[i]==xInit ){ wsdAutoext.nExt--; @@ -127200,27 +127200,27 @@ SQLITE_API int tdsqlite3_cancel_auto_extension( break; } } - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); return n; } /* ** Reset the automatic extension loading mechanism. */ -SQLITE_API void tdsqlite3_reset_auto_extension(void){ +SQLITE_API void sqlite3_reset_auto_extension(void){ #ifndef SQLITE_OMIT_AUTOINIT - if( tdsqlite3_initialize()==SQLITE_OK ) + if( sqlite3_initialize()==SQLITE_OK ) #endif { #if SQLITE_THREADSAFE - tdsqlite3_mutex *mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif wsdAutoextInit; - tdsqlite3_mutex_enter(mutex); - tdsqlite3_free(wsdAutoext.aExt); + sqlite3_mutex_enter(mutex); + sqlite3_free(wsdAutoext.aExt); wsdAutoext.aExt = 0; wsdAutoext.nExt = 0; - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); } } @@ -127229,11 +127229,11 @@ SQLITE_API void tdsqlite3_reset_auto_extension(void){ ** ** If anything goes wrong, set an error in the database connection. */ -SQLITE_PRIVATE void tdsqlite3AutoLoadExtensions(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ u32 i; int go = 1; int rc; - tdsqlite3_loadext_entry xInit; + sqlite3_loadext_entry xInit; wsdAutoextInit; if( wsdAutoext.nExt==0 ){ @@ -127243,28 +127243,28 @@ SQLITE_PRIVATE void tdsqlite3AutoLoadExtensions(tdsqlite3 *db){ for(i=0; go; i++){ char *zErrmsg; #if SQLITE_THREADSAFE - tdsqlite3_mutex *mutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); + sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); #endif #ifdef SQLITE_OMIT_LOAD_EXTENSION - const tdsqlite3_api_routines *pThunk = 0; + const sqlite3_api_routines *pThunk = 0; #else - const tdsqlite3_api_routines *pThunk = &tdsqlite3Apis; + const sqlite3_api_routines *pThunk = &sqlite3Apis; #endif - tdsqlite3_mutex_enter(mutex); + sqlite3_mutex_enter(mutex); if( i>=wsdAutoext.nExt ){ xInit = 0; go = 0; }else{ - xInit = (tdsqlite3_loadext_entry)wsdAutoext.aExt[i]; + xInit = (sqlite3_loadext_entry)wsdAutoext.aExt[i]; } - tdsqlite3_mutex_leave(mutex); + sqlite3_mutex_leave(mutex); zErrmsg = 0; if( xInit && (rc = xInit(db, &zErrmsg, pThunk))!=0 ){ - tdsqlite3ErrorWithMsg(db, rc, + sqlite3ErrorWithMsg(db, rc, "automatic extension loading failed: %s", zErrmsg); go = 0; } - tdsqlite3_free(zErrmsg); + sqlite3_free(zErrmsg); } } @@ -127996,7 +127996,7 @@ static const PragmaName aPragmaName[] = { ** if the omitFull parameter it 1. ** ** Note that the values returned are one less that the values that -** should be passed into tdsqlite3BtreeSetSafetyLevel(). The is done +** should be passed into sqlite3BtreeSetSafetyLevel(). The is done ** to support legacy SQL code. The safety level used to be boolean ** and older scripts may have used numbers 0 for OFF and 1 for ON. */ @@ -128008,12 +128008,12 @@ static u8 getSafetyLevel(const char *z, int omitFull, u8 dflt){ static const u8 iValue[] = {1, 0, 0, 0, 1, 1, 3, 2}; /* on no off false yes true extra full */ int i, n; - if( tdsqlite3Isdigit(*z) ){ - return (u8)tdsqlite3Atoi(z); + if( sqlite3Isdigit(*z) ){ + return (u8)sqlite3Atoi(z); } - n = tdsqlite3Strlen30(z); + n = sqlite3Strlen30(z); for(i=0; i=0&&i<=2)?i:0); } #endif /* ifndef SQLITE_OMIT_AUTOVACUUM */ @@ -128072,9 +128072,9 @@ static int getAutoVacuum(const char *z){ static int getTempStore(const char *z){ if( z[0]>='0' && z[0]<='2' ){ return z[0] - '0'; - }else if( tdsqlite3StrICmp(z, "file")==0 ){ + }else if( sqlite3StrICmp(z, "file")==0 ){ return 1; - }else if( tdsqlite3StrICmp(z, "memory")==0 ){ + }else if( sqlite3StrICmp(z, "memory")==0 ){ return 2; }else{ return 0; @@ -128088,16 +128088,16 @@ static int getTempStore(const char *z){ ** from default, or when 'file' and the temp_store_directory has changed */ static int invalidateTempStorage(Parse *pParse){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( db->aDb[1].pBt!=0 ){ - if( !db->autoCommit || tdsqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){ - tdsqlite3ErrorMsg(pParse, "temporary storage cannot be changed " + if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){ + sqlite3ErrorMsg(pParse, "temporary storage cannot be changed " "from within a transaction"); return SQLITE_ERROR; } - tdsqlite3BtreeClose(db->aDb[1].pBt); + sqlite3BtreeClose(db->aDb[1].pBt); db->aDb[1].pBt = 0; - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ResetAllSchemasOfConnection(db); } return SQLITE_OK; } @@ -128111,7 +128111,7 @@ static int invalidateTempStorage(Parse *pParse){ */ static int changeTempStorage(Parse *pParse, const char *zStorageType){ int ts = getTempStore(zStorageType); - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( db->temp_store==ts ) return SQLITE_OK; if( invalidateTempStorage( pParse ) != SQLITE_OK ){ return SQLITE_ERROR; @@ -128129,13 +128129,13 @@ static void setPragmaResultColumnNames( const PragmaName *pPragma /* The pragma */ ){ u8 n = pPragma->nPragCName; - tdsqlite3VdbeSetNumCols(v, n==0 ? 1 : n); + sqlite3VdbeSetNumCols(v, n==0 ? 1 : n); if( n==0 ){ - tdsqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, pPragma->zName, SQLITE_STATIC); }else{ int i, j; for(i=0, j=pPragma->iPragCName; iautoCommit ){ Db *pDb = db->aDb; int n = db->nDb; @@ -128179,7 +128179,7 @@ static void setAllPagerFlags(tdsqlite3 *db){ assert( (pDb->safety_level & PAGER_SYNCHRONOUS_MASK)==pDb->safety_level ); while( (n--) > 0 ){ if( pDb->pBt ){ - tdsqlite3BtreeSetPagerFlags(pDb->pBt, + sqlite3BtreeSetPagerFlags(pDb->pBt, pDb->safety_level | (db->flags & PAGER_FLAGS_MASK) ); } pDb++; @@ -128215,7 +128215,7 @@ static const char *actionName(u8 action){ ** defined in pager.h. This function returns the associated lowercase ** journal-mode name. */ -SQLITE_PRIVATE const char *tdsqlite3JournalModename(int eMode){ +SQLITE_PRIVATE const char *sqlite3JournalModename(int eMode){ static char * const azModeName[] = { "delete", "persist", "off", "truncate", "memory" #ifndef SQLITE_OMIT_WAL @@ -128243,7 +128243,7 @@ static const PragmaName *pragmaLocate(const char *zName){ upr = ArraySize(aPragmaName)-1; while( lwr<=upr ){ mid = (lwr+upr)/2; - rc = tdsqlite3_stricmp(zName, aPragmaName[mid].zName); + rc = sqlite3_stricmp(zName, aPragmaName[mid].zName); if( rc==0 ) break; if( rc<0 ){ upr = mid - 1; @@ -128293,7 +128293,7 @@ static void pragmaFunclistLine( }else{ zType = "s"; } - tdsqlite3VdbeMultiLoad(v, 1, "sissii", + sqlite3VdbeMultiLoad(v, 1, "sissii", p->zName, isBuiltin, zType, azEnc[p->funcFlags&SQLITE_FUNC_ENCMASK], p->nArg, @@ -128312,10 +128312,10 @@ static void pragmaFunclistLine( */ static int integrityCheckResultRow(Vdbe *v){ int addr; - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); - addr = tdsqlite3VdbeAddOp3(v, OP_IfPos, 1, tdsqlite3VdbeCurrentAddr(v)+2, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 3, 1); + addr = sqlite3VdbeAddOp3(v, OP_IfPos, 1, sqlite3VdbeCurrentAddr(v)+2, 1); VdbeCoverage(v); - tdsqlite3VdbeAddOp0(v, OP_Halt); + sqlite3VdbeAddOp0(v, OP_Halt); return addr; } @@ -128334,7 +128334,7 @@ static int integrityCheckResultRow(Vdbe *v){ ** and pId2 is the id. If the left side is just "id" then pId1 is the ** id and pId2 is any empty string. */ -SQLITE_PRIVATE void tdsqlite3Pragma( +SQLITE_PRIVATE void sqlite3Pragma( Parse *pParse, Token *pId1, /* First part of [schema.]id field */ Token *pId2, /* Second part of [schema.]id field, or NULL */ @@ -128348,39 +128348,39 @@ SQLITE_PRIVATE void tdsqlite3Pragma( char *aFcntl[4]; /* Argument to SQLITE_FCNTL_PRAGMA */ int iDb; /* Database index for */ int rc; /* return value form SQLITE_FCNTL_PRAGMA */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ Db *pDb; /* The specific database being pragmaed */ - Vdbe *v = tdsqlite3GetVdbe(pParse); /* Prepared statement */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Prepared statement */ const PragmaName *pPragma; /* The pragma */ if( v==0 ) return; - tdsqlite3VdbeRunOnlyOnce(v); + sqlite3VdbeRunOnlyOnce(v); pParse->nMem = 2; /* Interpret the [schema.] part of the pragma statement. iDb is the ** index of the database this pragma is being applied to in db.aDb[]. */ - iDb = tdsqlite3TwoPartName(pParse, pId1, pId2, &pId); + iDb = sqlite3TwoPartName(pParse, pId1, pId2, &pId); if( iDb<0 ) return; pDb = &db->aDb[iDb]; /* If the temp database has been explicitly named as part of the ** pragma, make sure it is open. */ - if( iDb==1 && tdsqlite3OpenTempDatabase(pParse) ){ + if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ return; } - zLeft = tdsqlite3NameFromToken(db, pId); + zLeft = sqlite3NameFromToken(db, pId); if( !zLeft ) return; if( minusFlag ){ - zRight = tdsqlite3MPrintf(db, "-%T", pValue); + zRight = sqlite3MPrintf(db, "-%T", pValue); }else{ - zRight = tdsqlite3NameFromToken(db, pValue); + zRight = sqlite3NameFromToken(db, pValue); } assert( pId2 ); zDb = pId2->n>0 ? pDb->zDbSName : 0; - if( tdsqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ + if( sqlite3AuthCheck(pParse, SQLITE_PRAGMA, zLeft, zRight, zDb) ){ goto pragma_out; } @@ -128389,7 +128389,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** handled the pragma and generate a no-op prepared statement. ** ** IMPLEMENTATION-OF: R-12238-55120 Whenever a PRAGMA statement is parsed, - ** an SQLITE_FCNTL_PRAGMA file control is sent to the open tdsqlite3_file + ** an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file ** object corresponding to the database file to which the pragma ** statement refers. ** @@ -128404,18 +128404,18 @@ SQLITE_PRIVATE void tdsqlite3Pragma( aFcntl[2] = zRight; aFcntl[3] = 0; db->busyHandler.nBusy = 0; - rc = tdsqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_PRAGMA, (void*)aFcntl); if( rc==SQLITE_OK ){ - tdsqlite3VdbeSetNumCols(v, 1); - tdsqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, aFcntl[0], SQLITE_TRANSIENT); returnSingleText(v, aFcntl[0]); - tdsqlite3_free(aFcntl[0]); + sqlite3_free(aFcntl[0]); goto pragma_out; } if( rc!=SQLITE_NOTFOUND ){ if( aFcntl[0] ){ - tdsqlite3ErrorMsg(pParse, "%s", aFcntl[0]); - tdsqlite3_free(aFcntl[0]); + sqlite3ErrorMsg(pParse, "%s", aFcntl[0]); + sqlite3_free(aFcntl[0]); } pParse->nErr++; pParse->rc = rc; @@ -128438,7 +128438,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( /* Make sure the database schema is loaded if the pragma requires that */ if( (pPragma->mPragFlg & PragFlg_NeedSchema)!=0 ){ - if( tdsqlite3ReadSchema(pParse) ) goto pragma_out; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; } /* Register the result column names for pragmas that return results */ @@ -128482,22 +128482,22 @@ SQLITE_PRIVATE void tdsqlite3Pragma( { OP_ResultRow, 1, 1, 0}, }; VdbeOp *aOp; - tdsqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeUsesBtree(v, iDb); if( !zRight ){ pParse->nMem += 2; - tdsqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); - aOp = tdsqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(getCacheSize)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize, iLn); if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE; }else{ - int size = tdsqlite3AbsInt32(tdsqlite3Atoi(zRight)); - tdsqlite3BeginWriteOperation(pParse, 0, iDb); - tdsqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size); - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + int size = sqlite3AbsInt32(sqlite3Atoi(zRight)); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pDb->pSchema->cache_size = size; - tdsqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } break; } @@ -128517,15 +128517,15 @@ SQLITE_PRIVATE void tdsqlite3Pragma( Btree *pBt = pDb->pBt; assert( pBt!=0 ); if( !zRight ){ - int size = ALWAYS(pBt) ? tdsqlite3BtreeGetPageSize(pBt) : 0; + int size = ALWAYS(pBt) ? sqlite3BtreeGetPageSize(pBt) : 0; returnSingleInt(v, size); }else{ /* Malloc may fail when setting the page-size, as there is an internal - ** buffer that the pager module resizes using tdsqlite3_realloc(). + ** buffer that the pager module resizes using sqlite3_realloc(). */ - db->nextPagesize = tdsqlite3Atoi(zRight); - if( SQLITE_NOMEM==tdsqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ - tdsqlite3OomFault(db); + db->nextPagesize = sqlite3Atoi(zRight); + if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize,-1,0) ){ + sqlite3OomFault(db); } } break; @@ -128544,19 +128544,19 @@ SQLITE_PRIVATE void tdsqlite3Pragma( int b = -1; assert( pBt!=0 ); if( zRight ){ - if( tdsqlite3_stricmp(zRight, "fast")==0 ){ + if( sqlite3_stricmp(zRight, "fast")==0 ){ b = 2; }else{ - b = tdsqlite3GetBoolean(zRight, 0); + b = sqlite3GetBoolean(zRight, 0); } } if( pId2->n==0 && b>=0 ){ int ii; for(ii=0; iinDb; ii++){ - tdsqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); + sqlite3BtreeSecureDelete(db->aDb[ii].pBt, b); } } - b = tdsqlite3BtreeSecureDelete(pBt, b); + b = sqlite3BtreeSecureDelete(pBt, b); returnSingleInt(v, b); break; } @@ -128572,7 +128572,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** ** The absolute value of N is used. This is undocumented and might ** change. The only purpose is to provide an easy way to test - ** the tdsqlite3AbsInt32() function. + ** the sqlite3AbsInt32() function. ** ** PRAGMA [schema.]page_count ** @@ -128580,15 +128580,15 @@ SQLITE_PRIVATE void tdsqlite3Pragma( */ case PragTyp_PAGE_COUNT: { int iReg; - tdsqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iDb); iReg = ++pParse->nMem; - if( tdsqlite3Tolower(zLeft[0])=='p' ){ - tdsqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); + if( sqlite3Tolower(zLeft[0])=='p' ){ + sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg); }else{ - tdsqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, - tdsqlite3AbsInt32(tdsqlite3Atoi(zRight))); + sqlite3VdbeAddOp3(v, OP_MaxPgcnt, iDb, iReg, + sqlite3AbsInt32(sqlite3Atoi(zRight))); } - tdsqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1); break; } @@ -128620,13 +128620,13 @@ SQLITE_PRIVATE void tdsqlite3Pragma( int ii; assert(pDb==&db->aDb[0]); for(ii=2; iinDb; ii++){ - pPager = tdsqlite3BtreePager(db->aDb[ii].pBt); - tdsqlite3PagerLockingMode(pPager, eMode); + pPager = sqlite3BtreePager(db->aDb[ii].pBt); + sqlite3PagerLockingMode(pPager, eMode); } db->dfltLockMode = (u8)eMode; } - pPager = tdsqlite3BtreePager(pDb->pBt); - eMode = tdsqlite3PagerLockingMode(pPager, eMode); + pPager = sqlite3BtreePager(pDb->pBt); + eMode = sqlite3PagerLockingMode(pPager, eMode); } assert( eMode==PAGER_LOCKINGMODE_NORMAL @@ -128653,9 +128653,9 @@ SQLITE_PRIVATE void tdsqlite3Pragma( eMode = PAGER_JOURNALMODE_QUERY; }else{ const char *zMode; - int n = tdsqlite3Strlen30(zRight); - for(eMode=0; (zMode = tdsqlite3JournalModename(eMode))!=0; eMode++){ - if( tdsqlite3StrNICmp(zRight, zMode, n)==0 ) break; + int n = sqlite3Strlen30(zRight); + for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ + if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; } if( !zMode ){ /* If the "=MODE" part does not match any known journal mode, @@ -128675,11 +128675,11 @@ SQLITE_PRIVATE void tdsqlite3Pragma( } for(ii=db->nDb-1; ii>=0; ii--){ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ - tdsqlite3VdbeUsesBtree(v, ii); - tdsqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); + sqlite3VdbeUsesBtree(v, ii); + sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); } } - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); break; } @@ -128690,13 +128690,13 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** Get or set the size limit on rollback journal files. */ case PragTyp_JOURNAL_SIZE_LIMIT: { - Pager *pPager = tdsqlite3BtreePager(pDb->pBt); + Pager *pPager = sqlite3BtreePager(pDb->pBt); i64 iLimit = -2; if( zRight ){ - tdsqlite3DecOrHexToI64(zRight, &iLimit); + sqlite3DecOrHexToI64(zRight, &iLimit); if( iLimit<-1 ) iLimit = -1; } - iLimit = tdsqlite3PagerJournalSizeLimit(pPager, iLimit); + iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); returnSingleInt(v, iLimit); break; } @@ -128715,7 +128715,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( Btree *pBt = pDb->pBt; assert( pBt!=0 ); if( !zRight ){ - returnSingleInt(v, tdsqlite3BtreeGetAutoVacuum(pBt)); + returnSingleInt(v, sqlite3BtreeGetAutoVacuum(pBt)); }else{ int eAuto = getAutoVacuum(zRight); assert( eAuto>=0 && eAuto<=2 ); @@ -128725,7 +128725,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** creates the database file. It is important that it is created ** as an auto-vacuum capable db. */ - rc = tdsqlite3BtreeSetAutoVacuum(pBt, eAuto); + rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ /* When setting the auto_vacuum mode to either "full" or ** "incremental", write the value of meta[6] in the database @@ -128741,16 +128741,16 @@ SQLITE_PRIVATE void tdsqlite3Pragma( { OP_SetCookie, 0, BTREE_INCR_VACUUM, 0}, /* 4 */ }; VdbeOp *aOp; - int iAddr = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6)); - aOp = tdsqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); + int iAddr = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn); if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[2].p2 = iAddr+4; aOp[4].p1 = iDb; aOp[4].p3 = eAuto - 1; - tdsqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeUsesBtree(v, iDb); } } break; @@ -128765,16 +128765,16 @@ SQLITE_PRIVATE void tdsqlite3Pragma( #ifndef SQLITE_OMIT_AUTOVACUUM case PragTyp_INCREMENTAL_VACUUM: { int iLimit, addr; - if( zRight==0 || !tdsqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ + if( zRight==0 || !sqlite3GetInt32(zRight, &iLimit) || iLimit<=0 ){ iLimit = 0x7fffffff; } - tdsqlite3BeginWriteOperation(pParse, 0, iDb); - tdsqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); - addr = tdsqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v); - tdsqlite3VdbeAddOp1(v, OP_ResultRow, 1); - tdsqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); - tdsqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addr); + sqlite3BeginWriteOperation(pParse, 0, iDb); + sqlite3VdbeAddOp2(v, OP_Integer, iLimit, 1); + addr = sqlite3VdbeAddOp1(v, OP_IncrVacuum, iDb); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_ResultRow, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, 1, -1); + sqlite3VdbeAddOp2(v, OP_IfPos, 1, addr); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); break; } #endif @@ -128792,13 +128792,13 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** of memory. */ case PragTyp_CACHE_SIZE: { - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ returnSingleInt(v, pDb->pSchema->cache_size); }else{ - int size = tdsqlite3Atoi(zRight); + int size = sqlite3Atoi(zRight); pDb->pSchema->cache_size = size; - tdsqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } break; } @@ -128826,17 +128826,17 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** not just the schema specified. */ case PragTyp_CACHE_SPILL: { - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ returnSingleInt(v, (db->flags & SQLITE_CacheSpill)==0 ? 0 : - tdsqlite3BtreeSetSpillSize(pDb->pBt,0)); + sqlite3BtreeSetSpillSize(pDb->pBt,0)); }else{ int size = 1; - if( tdsqlite3GetInt32(zRight, &size) ){ - tdsqlite3BtreeSetSpillSize(pDb->pBt, size); + if( sqlite3GetInt32(zRight, &size) ){ + sqlite3BtreeSetSpillSize(pDb->pBt, size); } - if( tdsqlite3GetBoolean(zRight, size!=0) ){ + if( sqlite3GetBoolean(zRight, size!=0) ){ db->flags |= SQLITE_CacheSpill; }else{ db->flags &= ~(u64)SQLITE_CacheSpill; @@ -128853,7 +128853,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** used to limit the aggregate size of all memory mapped regions of the ** database file. If this parameter is set to zero, then memory mapping ** is not used at all. If N is negative, then the default memory map - ** limit determined by tdsqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set. + ** limit determined by sqlite3_config(SQLITE_CONFIG_MMAP_SIZE) is set. ** The parameter N is measured in bytes. ** ** This value is advisory. The underlying VFS is free to memory map @@ -128861,22 +128861,22 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** upper layers will never invoke the xFetch interfaces to the VFS. */ case PragTyp_MMAP_SIZE: { - tdsqlite3_int64 sz; + sqlite3_int64 sz; #if SQLITE_MAX_MMAP_SIZE>0 - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( zRight ){ int ii; - tdsqlite3DecOrHexToI64(zRight, &sz); - if( sz<0 ) sz = tdsqlite3GlobalConfig.szMmap; + sqlite3DecOrHexToI64(zRight, &sz); + if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; if( pId2->n==0 ) db->szMmap = sz; for(ii=db->nDb-1; ii>=0; ii--){ if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ - tdsqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); + sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); } } } sz = -1; - rc = tdsqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); + rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); #else sz = 0; rc = SQLITE_OK; @@ -128922,14 +128922,14 @@ SQLITE_PRIVATE void tdsqlite3Pragma( */ case PragTyp_TEMP_STORE_DIRECTORY: { if( !zRight ){ - returnSingleText(v, tdsqlite3_temp_directory); + returnSingleText(v, sqlite3_temp_directory); }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ int res; - rc = tdsqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); if( rc!=SQLITE_OK || res==0 ){ - tdsqlite3ErrorMsg(pParse, "not a writable directory"); + sqlite3ErrorMsg(pParse, "not a writable directory"); goto pragma_out; } } @@ -128939,11 +128939,11 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ){ invalidateTempStorage(pParse); } - tdsqlite3_free(tdsqlite3_temp_directory); + sqlite3_free(sqlite3_temp_directory); if( zRight[0] ){ - tdsqlite3_temp_directory = tdsqlite3_mprintf("%s", zRight); + sqlite3_temp_directory = sqlite3_mprintf("%s", zRight); }else{ - tdsqlite3_temp_directory = 0; + sqlite3_temp_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } @@ -128966,22 +128966,22 @@ SQLITE_PRIVATE void tdsqlite3Pragma( */ case PragTyp_DATA_STORE_DIRECTORY: { if( !zRight ){ - returnSingleText(v, tdsqlite3_data_directory); + returnSingleText(v, sqlite3_data_directory); }else{ #ifndef SQLITE_OMIT_WSD if( zRight[0] ){ int res; - rc = tdsqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); + rc = sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res); if( rc!=SQLITE_OK || res==0 ){ - tdsqlite3ErrorMsg(pParse, "not a writable directory"); + sqlite3ErrorMsg(pParse, "not a writable directory"); goto pragma_out; } } - tdsqlite3_free(tdsqlite3_data_directory); + sqlite3_free(sqlite3_data_directory); if( zRight[0] ){ - tdsqlite3_data_directory = tdsqlite3_mprintf("%s", zRight); + sqlite3_data_directory = sqlite3_mprintf("%s", zRight); }else{ - tdsqlite3_data_directory = 0; + sqlite3_data_directory = 0; } #endif /* SQLITE_OMIT_WSD */ } @@ -129000,25 +129000,25 @@ SQLITE_PRIVATE void tdsqlite3Pragma( */ case PragTyp_LOCK_PROXY_FILE: { if( !zRight ){ - Pager *pPager = tdsqlite3BtreePager(pDb->pBt); + Pager *pPager = sqlite3BtreePager(pDb->pBt); char *proxy_file_path = NULL; - tdsqlite3_file *pFile = tdsqlite3PagerFile(pPager); - tdsqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, + sqlite3_file *pFile = sqlite3PagerFile(pPager); + sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, &proxy_file_path); returnSingleText(v, proxy_file_path); }else{ - Pager *pPager = tdsqlite3BtreePager(pDb->pBt); - tdsqlite3_file *pFile = tdsqlite3PagerFile(pPager); + Pager *pPager = sqlite3BtreePager(pDb->pBt); + sqlite3_file *pFile = sqlite3PagerFile(pPager); int res; if( zRight[0] ){ - res=tdsqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, zRight); } else { - res=tdsqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, NULL); } if( res!=SQLITE_OK ){ - tdsqlite3ErrorMsg(pParse, "failed to set lock proxy file"); + sqlite3ErrorMsg(pParse, "failed to set lock proxy file"); goto pragma_out; } } @@ -129040,7 +129040,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( returnSingleInt(v, pDb->safety_level-1); }else{ if( !db->autoCommit ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else if( iDb!=1 ){ int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; @@ -129073,7 +129073,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( } #endif - if( tdsqlite3GetBoolean(zRight, 0) ){ + if( sqlite3GetBoolean(zRight, 0) ){ db->flags |= mask; }else{ db->flags &= ~mask; @@ -129084,7 +129084,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** compiler (eg. count_changes). So add an opcode to expire all ** compiled SQL statements after modifying a pragma value. */ - tdsqlite3VdbeAddOp0(v, OP_Expire); + sqlite3VdbeAddOp0(v, OP_Expire); setAllPagerFlags(db); } break; @@ -129107,16 +129107,16 @@ SQLITE_PRIVATE void tdsqlite3Pragma( */ case PragTyp_TABLE_INFO: if( zRight ){ Table *pTab; - pTab = tdsqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); + pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); if( pTab ){ - int iTabDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int i, k; int nHidden = 0; Column *pCol; - Index *pPk = tdsqlite3PrimaryKeyIndex(pTab); + Index *pPk = sqlite3PrimaryKeyIndex(pTab); pParse->nMem = 7; - tdsqlite3CodeVerifySchema(pParse, iTabDb); - tdsqlite3ViewGetColumnNames(pParse, pTab); + sqlite3CodeVerifySchema(pParse, iTabDb); + sqlite3ViewGetColumnNames(pParse, pTab); for(i=0, pCol=pTab->aCol; inCol; i++, pCol++){ int isHidden = 0; if( pCol->colFlags & COLFLAG_NOINSERT ){ @@ -129140,10 +129140,10 @@ SQLITE_PRIVATE void tdsqlite3Pragma( for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){} } assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN || isHidden>=2 ); - tdsqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", + sqlite3VdbeMultiLoad(v, 1, pPragma->iArg ? "issisii" : "issisi", i-nHidden, pCol->zName, - tdsqlite3ColumnType(pCol,""), + sqlite3ColumnType(pCol,""), pCol->notNull ? 1 : 0, pCol->pDflt && isHidden<2 ? pCol->pDflt->u.zToken : 0, k, @@ -129158,22 +129158,22 @@ SQLITE_PRIVATE void tdsqlite3Pragma( Index *pIdx; HashElem *i; pParse->nMem = 5; - tdsqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iDb); for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){ Table *pTab = sqliteHashData(i); - tdsqlite3VdbeMultiLoad(v, 1, "ssiii", + sqlite3VdbeMultiLoad(v, 1, "ssiii", pTab->zName, 0, pTab->szTabRow, pTab->nRowLogEst, pTab->tabFlags); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - tdsqlite3VdbeMultiLoad(v, 2, "siiiX", + sqlite3VdbeMultiLoad(v, 2, "siiiX", pIdx->zName, pIdx->szIdxRow, pIdx->aiRowLogEst[0], pIdx->hasStat1); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 5); } } } @@ -129183,18 +129183,18 @@ SQLITE_PRIVATE void tdsqlite3Pragma( case PragTyp_INDEX_INFO: if( zRight ){ Index *pIdx; Table *pTab; - pIdx = tdsqlite3FindIndex(db, zRight, zDb); + pIdx = sqlite3FindIndex(db, zRight, zDb); if( pIdx==0 ){ /* If there is no index named zRight, check to see if there is a ** WITHOUT ROWID table named zRight, and if there is, show the ** structure of the PRIMARY KEY index for that table. */ - pTab = tdsqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); + pTab = sqlite3LocateTable(pParse, LOCATE_NOERR, zRight, zDb); if( pTab && !HasRowid(pTab) ){ - pIdx = tdsqlite3PrimaryKeyIndex(pTab); + pIdx = sqlite3PrimaryKeyIndex(pTab); } } if( pIdx ){ - int iIdxDb = tdsqlite3SchemaToIndex(db, pIdx->pSchema); + int iIdxDb = sqlite3SchemaToIndex(db, pIdx->pSchema); int i; int mx; if( pPragma->iArg ){ @@ -129207,19 +129207,19 @@ SQLITE_PRIVATE void tdsqlite3Pragma( pParse->nMem = 3; } pTab = pIdx->pTable; - tdsqlite3CodeVerifySchema(pParse, iIdxDb); + sqlite3CodeVerifySchema(pParse, iIdxDb); assert( pParse->nMem<=pPragma->nPragCName ); for(i=0; iaiColumn[i]; - tdsqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum, + sqlite3VdbeMultiLoad(v, 1, "iisX", i, cnum, cnum<0 ? 0 : pTab->aCol[cnum].zName); if( pPragma->iArg ){ - tdsqlite3VdbeMultiLoad(v, 4, "isiX", + sqlite3VdbeMultiLoad(v, 4, "isiX", pIdx->aSortOrder[i], pIdx->azColl[i], inKeyCol); } - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, pParse->nMem); } } } @@ -129229,14 +129229,14 @@ SQLITE_PRIVATE void tdsqlite3Pragma( Index *pIdx; Table *pTab; int i; - pTab = tdsqlite3FindTable(db, zRight, zDb); + pTab = sqlite3FindTable(db, zRight, zDb); if( pTab ){ - int iTabDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); pParse->nMem = 5; - tdsqlite3CodeVerifySchema(pParse, iTabDb); + sqlite3CodeVerifySchema(pParse, iTabDb); for(pIdx=pTab->pIndex, i=0; pIdx; pIdx=pIdx->pNext, i++){ const char *azOrigin[] = { "c", "u", "pk" }; - tdsqlite3VdbeMultiLoad(v, 1, "isisi", + sqlite3VdbeMultiLoad(v, 1, "isisi", i, pIdx->zName, IsUniqueIndex(pIdx), @@ -129253,10 +129253,10 @@ SQLITE_PRIVATE void tdsqlite3Pragma( for(i=0; inDb; i++){ if( db->aDb[i].pBt==0 ) continue; assert( db->aDb[i].zDbSName!=0 ); - tdsqlite3VdbeMultiLoad(v, 1, "iss", + sqlite3VdbeMultiLoad(v, 1, "iss", i, db->aDb[i].zDbSName, - tdsqlite3BtreeGetFilename(db->aDb[i].pBt)); + sqlite3BtreeGetFilename(db->aDb[i].pBt)); } } break; @@ -129267,7 +129267,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( pParse->nMem = 2; for(p=sqliteHashFirst(&db->aCollSeq); p; p=sqliteHashNext(p)){ CollSeq *pColl = (CollSeq *)sqliteHashData(p); - tdsqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); + sqlite3VdbeMultiLoad(v, 1, "is", i++, pColl->zName); } } break; @@ -129280,7 +129280,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( int showInternFunc = (db->mDbFlags & DBFLAG_InternalFunc)!=0; pParse->nMem = 6; for(i=0; iu.pHash ){ + for(p=sqlite3BuiltinFunctions.a[i]; p; p=p->u.pHash ){ pragmaFunclistLine(v, p, 1, showInternFunc); } } @@ -129297,7 +129297,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( pParse->nMem = 1; for(j=sqliteHashFirst(&db->aModule); j; j=sqliteHashNext(j)){ Module *pMod = (Module*)sqliteHashData(j); - tdsqlite3VdbeMultiLoad(v, 1, "s", pMod->zName); + sqlite3VdbeMultiLoad(v, 1, "s", pMod->zName); } } break; @@ -129306,7 +129306,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( case PragTyp_PRAGMA_LIST: { int i; for(i=0; ipFKey; if( pFK ){ - int iTabDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int i = 0; pParse->nMem = 8; - tdsqlite3CodeVerifySchema(pParse, iTabDb); + sqlite3CodeVerifySchema(pParse, iTabDb); while(pFK){ int j; for(j=0; jnCol; j++){ - tdsqlite3VdbeMultiLoad(v, 1, "iissssss", + sqlite3VdbeMultiLoad(v, 1, "iissssss", i, j, pFK->zTo, @@ -129374,31 +129374,31 @@ SQLITE_PRIVATE void tdsqlite3Pragma( while( k ){ int iTabDb; if( zRight ){ - pTab = tdsqlite3LocateTable(pParse, 0, zRight, zDb); + pTab = sqlite3LocateTable(pParse, 0, zRight, zDb); k = 0; }else{ pTab = (Table*)sqliteHashData(k); k = sqliteHashNext(k); } if( pTab==0 || pTab->pFKey==0 ) continue; - iTabDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); - tdsqlite3CodeVerifySchema(pParse, iTabDb); - tdsqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName); + iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3CodeVerifySchema(pParse, iTabDb); + sqlite3TableLock(pParse, iTabDb, pTab->tnum, 0, pTab->zName); if( pTab->nCol+regRow>pParse->nMem ) pParse->nMem = pTab->nCol + regRow; - tdsqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead); - tdsqlite3VdbeLoadString(v, regResult, pTab->zName); + sqlite3OpenTable(pParse, 0, iTabDb, pTab, OP_OpenRead); + sqlite3VdbeLoadString(v, regResult, pTab->zName); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = tdsqlite3FindTable(db, pFK->zTo, zDb); + pParent = sqlite3FindTable(db, pFK->zTo, zDb); if( pParent==0 ) continue; pIdx = 0; - tdsqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName); - x = tdsqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); + sqlite3TableLock(pParse, iTabDb, pParent->tnum, 0, pParent->zName); + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, 0); if( x==0 ){ if( pIdx==0 ){ - tdsqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead); + sqlite3OpenTable(pParse, i, iTabDb, pParent, OP_OpenRead); }else{ - tdsqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb); - tdsqlite3VdbeSetP4KeyInfo(pParse, pIdx); + sqlite3VdbeAddOp3(v, OP_OpenRead, i, pIdx->tnum, iTabDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); } }else{ k = 0; @@ -129408,16 +129408,16 @@ SQLITE_PRIVATE void tdsqlite3Pragma( assert( pParse->nErr>0 || pFK==0 ); if( pFK ) break; if( pParse->nTabnTab = i; - addrTop = tdsqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, 0); VdbeCoverage(v); for(i=1, pFK=pTab->pFKey; pFK; i++, pFK=pFK->pNextFrom){ - pParent = tdsqlite3FindTable(db, pFK->zTo, zDb); + pParent = sqlite3FindTable(db, pFK->zTo, zDb); pIdx = 0; aiCols = 0; if( pParent ){ - x = tdsqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); + x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols); assert( x==0 ); } - addrOk = tdsqlite3VdbeMakeLabel(pParse); + addrOk = sqlite3VdbeMakeLabel(pParse); /* Generate code to read the child key values into registers ** regRow..regRow+n. If any of the child key values are NULL, this @@ -129425,37 +129425,37 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** this case. */ for(j=0; jnCol; j++){ int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom; - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); - tdsqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); + sqlite3ExprCodeGetColumnOfTable(v, pTab, 0, iCol, regRow+j); + sqlite3VdbeAddOp2(v, OP_IsNull, regRow+j, addrOk); VdbeCoverage(v); } /* Generate code to query the parent index for a matching parent ** key. If a match is found, jump to addrOk. */ if( pIdx ){ - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, - tdsqlite3IndexAffinityStr(db,pIdx), pFK->nCol); - tdsqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, pFK->nCol, regKey, + sqlite3IndexAffinityStr(db,pIdx), pFK->nCol); + sqlite3VdbeAddOp4Int(v, OP_Found, i, addrOk, regKey, 0); VdbeCoverage(v); }else if( pParent ){ - int jmp = tdsqlite3VdbeCurrentAddr(v)+2; - tdsqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v); - tdsqlite3VdbeGoto(v, addrOk); + int jmp = sqlite3VdbeCurrentAddr(v)+2; + sqlite3VdbeAddOp3(v, OP_SeekRowid, i, jmp, regRow); VdbeCoverage(v); + sqlite3VdbeGoto(v, addrOk); assert( pFK->nCol==1 ); } /* Generate code to report an FK violation to the caller. */ if( HasRowid(pTab) ){ - tdsqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); + sqlite3VdbeAddOp2(v, OP_Rowid, 0, regResult+1); }else{ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1); + sqlite3VdbeAddOp2(v, OP_Null, 0, regResult+1); } - tdsqlite3VdbeMultiLoad(v, regResult+2, "siX", pFK->zTo, i-1); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); - tdsqlite3VdbeResolveLabel(v, addrOk); - tdsqlite3DbFree(db, aiCols); + sqlite3VdbeMultiLoad(v, regResult+2, "siX", pFK->zTo, i-1); + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, 4); + sqlite3VdbeResolveLabel(v, addrOk); + sqlite3DbFree(db, aiCols); } - tdsqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addrTop); + sqlite3VdbeAddOp2(v, OP_Next, 0, addrTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addrTop); } } break; @@ -129468,7 +129468,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( */ case PragTyp_CASE_SENSITIVE_LIKE: { if( zRight ){ - tdsqlite3RegisterLikeFunctions(db, tdsqlite3GetBoolean(zRight, 0)); + sqlite3RegisterLikeFunctions(db, sqlite3GetBoolean(zRight, 0)); } } break; @@ -129494,7 +129494,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( case PragTyp_INTEGRITY_CHECK: { int i, j, addr, mxErr; - int isQuick = (tdsqlite3Tolower(zLeft[0])=='q'); + int isQuick = (sqlite3Tolower(zLeft[0])=='q'); /* If the PRAGMA command was of the form "PRAGMA .integrity_check", ** then iDb is set to the index of the database identified by . @@ -129515,12 +129515,12 @@ SQLITE_PRIVATE void tdsqlite3Pragma( /* Set the maximum error count */ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; if( zRight ){ - tdsqlite3GetInt32(zRight, &mxErr); + sqlite3GetInt32(zRight, &mxErr); if( mxErr<=0 ){ mxErr = SQLITE_INTEGRITY_CHECK_ERROR_MAX; } } - tdsqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */ + sqlite3VdbeAddOp2(v, OP_Integer, mxErr-1, 1); /* reg[1] holds errors left */ /* Do an integrity check on each database file */ for(i=0; inDb; i++){ @@ -129533,14 +129533,14 @@ SQLITE_PRIVATE void tdsqlite3Pragma( if( OMIT_TEMPDB && i==1 ) continue; if( iDb>=0 && i!=iDb ) continue; - tdsqlite3CodeVerifySchema(pParse, i); + sqlite3CodeVerifySchema(pParse, i); /* Do an integrity check of the B-Tree ** ** Begin by finding the root pages numbers ** for all tables and indices in the database. */ - assert( tdsqlite3SchemaMutexHeld(db, i, 0) ); + assert( sqlite3SchemaMutexHeld(db, i, 0) ); pTbls = &db->aDb[i].pSchema->tblHash; for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); /* Current table */ @@ -129550,7 +129550,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ cnt++; } if( nIdx>mxIdx ) mxIdx = nIdx; } - aRoot = tdsqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1)); + aRoot = sqlite3DbMallocRawNN(db, sizeof(int)*(cnt+1)); if( aRoot==0 ) break; for(cnt=0, x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ Table *pTab = sqliteHashData(x); @@ -129564,18 +129564,18 @@ SQLITE_PRIVATE void tdsqlite3Pragma( /* Make sure sufficient number of registers have been allocated */ pParse->nMem = MAX( pParse->nMem, 8+mxIdx ); - tdsqlite3ClearTempRegCache(pParse); + sqlite3ClearTempRegCache(pParse); /* Do the b-tree integrity checks */ - tdsqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); - tdsqlite3VdbeChangeP5(v, (u8)i); - addr = tdsqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, - tdsqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), + sqlite3VdbeAddOp4(v, OP_IntegrityCk, 2, cnt, 1, (char*)aRoot,P4_INTARRAY); + sqlite3VdbeChangeP5(v, (u8)i); + addr = sqlite3VdbeAddOp1(v, OP_IsNull, 2); VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, + sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zDbSName), P4_DYNAMIC); - tdsqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3); + sqlite3VdbeAddOp3(v, OP_Concat, 2, 3, 3); integrityCheckResultRow(v); - tdsqlite3VdbeJumpHere(v, addr); + sqlite3VdbeJumpHere(v, addr); /* Make sure all the indices are constructed correctly. */ @@ -129588,24 +129588,24 @@ SQLITE_PRIVATE void tdsqlite3Pragma( int r1 = -1; if( pTab->tnum<1 ) continue; /* Skip VIEWs or VIRTUAL TABLEs */ - pPk = HasRowid(pTab) ? 0 : tdsqlite3PrimaryKeyIndex(pTab); - tdsqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); /* reg[7] counts the number of entries in the table. ** reg[8+i] counts the number of entries in the i-th index */ - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, 7); + sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ + sqlite3VdbeAddOp2(v, OP_Integer, 0, 8+j); /* index entries counter */ } assert( pParse->nMem>=8+j ); - assert( tdsqlite3NoTempsInRange(pParse,1,7+j) ); - tdsqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); - loopTop = tdsqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); + assert( sqlite3NoTempsInRange(pParse,1,7+j) ); + sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v); + loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1); if( !isQuick ){ /* Sanity check on record header decoding */ - tdsqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3); - tdsqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3); + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); } /* Verify that all NOT NULL columns really are NOT NULL */ for(j=0; jnCol; j++){ @@ -129613,103 +129613,103 @@ SQLITE_PRIVATE void tdsqlite3Pragma( int jmp2; if( j==pTab->iPKey ) continue; if( pTab->aCol[j].notNull==0 ) continue; - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); - if( tdsqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){ - tdsqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3); + if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){ + sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG); } - jmp2 = tdsqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); - zErr = tdsqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, + jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v); + zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pTab->aCol[j].zName); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); integrityCheckResultRow(v); - tdsqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeJumpHere(v, jmp2); } /* Verify CHECK constraints */ if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){ - ExprList *pCheck = tdsqlite3ExprListDup(db, pTab->pCheck, 0); + ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0); if( db->mallocFailed==0 ){ - int addrCkFault = tdsqlite3VdbeMakeLabel(pParse); - int addrCkOk = tdsqlite3VdbeMakeLabel(pParse); + int addrCkFault = sqlite3VdbeMakeLabel(pParse); + int addrCkOk = sqlite3VdbeMakeLabel(pParse); char *zErr; int k; pParse->iSelfTab = iDataCur + 1; for(k=pCheck->nExpr-1; k>0; k--){ - tdsqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); + sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); } - tdsqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, + sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, SQLITE_JUMPIFNULL); - tdsqlite3VdbeResolveLabel(v, addrCkFault); + sqlite3VdbeResolveLabel(v, addrCkFault); pParse->iSelfTab = 0; - zErr = tdsqlite3MPrintf(db, "CHECK constraint failed in %s", + zErr = sqlite3MPrintf(db, "CHECK constraint failed in %s", pTab->zName); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); + sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); integrityCheckResultRow(v); - tdsqlite3VdbeResolveLabel(v, addrCkOk); + sqlite3VdbeResolveLabel(v, addrCkOk); } - tdsqlite3ExprListDelete(db, pCheck); + sqlite3ExprListDelete(db, pCheck); } if( !isQuick ){ /* Omit the remaining tests for quick_check */ /* Validate index entries for the current row */ for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ int jmp2, jmp3, jmp4, jmp5; - int ckUniq = tdsqlite3VdbeMakeLabel(pParse); + int ckUniq = sqlite3VdbeMakeLabel(pParse); if( pPk==pIdx ) continue; - r1 = tdsqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, + r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3, pPrior, r1); pPrior = pIdx; - tdsqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */ + sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */ /* Verify that an index entry exists for the current table row */ - jmp2 = tdsqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, + jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1, pIdx->nColumn); VdbeCoverage(v); - tdsqlite3VdbeLoadString(v, 3, "row "); - tdsqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); - tdsqlite3VdbeLoadString(v, 4, " missing from index "); - tdsqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); - jmp5 = tdsqlite3VdbeLoadString(v, 4, pIdx->zName); - tdsqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + sqlite3VdbeLoadString(v, 3, "row "); + sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3); + sqlite3VdbeLoadString(v, 4, " missing from index "); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); + jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3); jmp4 = integrityCheckResultRow(v); - tdsqlite3VdbeJumpHere(v, jmp2); + sqlite3VdbeJumpHere(v, jmp2); /* For UNIQUE indexes, verify that only one entry exists with the ** current key. The entry is unique if (1) any column is NULL ** or (2) the next entry has a different key */ if( IsUniqueIndex(pIdx) ){ - int uniqOk = tdsqlite3VdbeMakeLabel(pParse); + int uniqOk = sqlite3VdbeMakeLabel(pParse); int jmp6; int kk; for(kk=0; kknKeyCol; kk++){ int iCol = pIdx->aiColumn[kk]; assert( iCol!=XN_ROWID && iColnCol ); if( iCol>=0 && pTab->aCol[iCol].notNull ) continue; - tdsqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); + sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk); VdbeCoverage(v); } - jmp6 = tdsqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); - tdsqlite3VdbeGoto(v, uniqOk); - tdsqlite3VdbeJumpHere(v, jmp6); - tdsqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, + jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v); + sqlite3VdbeGoto(v, uniqOk); + sqlite3VdbeJumpHere(v, jmp6); + sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1, pIdx->nKeyCol); VdbeCoverage(v); - tdsqlite3VdbeLoadString(v, 3, "non-unique entry in index "); - tdsqlite3VdbeGoto(v, jmp5); - tdsqlite3VdbeResolveLabel(v, uniqOk); + sqlite3VdbeLoadString(v, 3, "non-unique entry in index "); + sqlite3VdbeGoto(v, jmp5); + sqlite3VdbeResolveLabel(v, uniqOk); } - tdsqlite3VdbeJumpHere(v, jmp4); - tdsqlite3ResolvePartIdxLabel(pParse, jmp3); + sqlite3VdbeJumpHere(v, jmp4); + sqlite3ResolvePartIdxLabel(pParse, jmp3); } } - tdsqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, loopTop-1); + sqlite3VdbeAddOp2(v, OP_Next, iDataCur, loopTop); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, loopTop-1); #ifndef SQLITE_OMIT_BTREECOUNT if( !isQuick ){ - tdsqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); + sqlite3VdbeLoadString(v, 2, "wrong # of entries in index "); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ if( pPk==pIdx ) continue; - tdsqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); - addr = tdsqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); - tdsqlite3VdbeChangeP5(v, SQLITE_NOTNULL); - tdsqlite3VdbeLoadString(v, 4, pIdx->zName); - tdsqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur+j, 3); + addr = sqlite3VdbeAddOp3(v, OP_Eq, 8+j, 0, 3); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); + sqlite3VdbeLoadString(v, 4, pIdx->zName); + sqlite3VdbeAddOp3(v, OP_Concat, 4, 2, 3); integrityCheckResultRow(v); - tdsqlite3VdbeJumpHere(v, addr); + sqlite3VdbeJumpHere(v, addr); } } #endif /* SQLITE_OMIT_BTREECOUNT */ @@ -129728,15 +129728,15 @@ SQLITE_PRIVATE void tdsqlite3Pragma( }; VdbeOp *aOp; - aOp = tdsqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); + aOp = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn); if( aOp ){ aOp[0].p2 = 1-mxErr; aOp[2].p4type = P4_STATIC; aOp[2].p4.z = "ok"; aOp[5].p4type = P4_STATIC; - aOp[5].p4.z = (char*)tdsqlite3ErrStr(SQLITE_CORRUPT); + aOp[5].p4.z = (char*)sqlite3ErrStr(SQLITE_CORRUPT); } - tdsqlite3VdbeChangeP3(v, 0, tdsqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeChangeP3(v, 0, sqlite3VdbeCurrentAddr(v)-2); } } break; @@ -129782,7 +129782,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( }; const struct EncName *pEnc; if( !zRight ){ /* "PRAGMA encoding" */ - if( tdsqlite3ReadSchema(pParse) ) goto pragma_out; + if( sqlite3ReadSchema(pParse) ) goto pragma_out; assert( encnames[SQLITE_UTF8].enc==SQLITE_UTF8 ); assert( encnames[SQLITE_UTF16LE].enc==SQLITE_UTF16LE ); assert( encnames[SQLITE_UTF16BE].enc==SQLITE_UTF16BE ); @@ -129805,14 +129805,14 @@ SQLITE_PRIVATE void tdsqlite3Pragma( } if( canChangeEnc ){ for(pEnc=&encnames[0]; pEnc->zName; pEnc++){ - if( 0==tdsqlite3StrICmp(zRight, pEnc->zName) ){ + if( 0==sqlite3StrICmp(zRight, pEnc->zName) ){ SCHEMA_ENC(db) = ENC(db) = pEnc->enc ? pEnc->enc : SQLITE_UTF16NATIVE; break; } } if( !pEnc->zName ){ - tdsqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); + sqlite3ErrorMsg(pParse, "unsupported encoding: %s", zRight); } } } @@ -129855,7 +129855,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( */ case PragTyp_HEADER_VALUE: { int iCookie = pPragma->iArg; /* Which cookie to read or write */ - tdsqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeUsesBtree(v, iDb); if( zRight && (pPragma->mPragFlg & PragFlg_ReadOnly)==0 ){ /* Write the specified cookie value */ static const VdbeOpList setCookie[] = { @@ -129863,13 +129863,13 @@ SQLITE_PRIVATE void tdsqlite3Pragma( { OP_SetCookie, 0, 0, 0}, /* 1 */ }; VdbeOp *aOp; - tdsqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); - aOp = tdsqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0); if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[1].p2 = iCookie; - aOp[1].p3 = tdsqlite3Atoi(zRight); + aOp[1].p3 = sqlite3Atoi(zRight); }else{ /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { @@ -129878,13 +129878,13 @@ SQLITE_PRIVATE void tdsqlite3Pragma( { OP_ResultRow, 1, 1, 0} }; VdbeOp *aOp; - tdsqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie)); - aOp = tdsqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); + sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(readCookie)); + aOp = sqlite3VdbeAddOpList(v, ArraySize(readCookie),readCookie,0); if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break; aOp[0].p1 = iDb; aOp[1].p1 = iDb; aOp[1].p3 = iCookie; - tdsqlite3VdbeReusable(v); + sqlite3VdbeReusable(v); } } break; @@ -129901,11 +129901,11 @@ SQLITE_PRIVATE void tdsqlite3Pragma( int i = 0; const char *zOpt; pParse->nMem = 1; - while( (zOpt = tdsqlite3_compileoption_get(i++))!=0 ){ - tdsqlite3VdbeLoadString(v, 1, zOpt); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); + while( (zOpt = sqlite3_compileoption_get(i++))!=0 ){ + sqlite3VdbeLoadString(v, 1, zOpt); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); } - tdsqlite3VdbeReusable(v); + sqlite3VdbeReusable(v); } break; #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ @@ -129920,17 +129920,17 @@ SQLITE_PRIVATE void tdsqlite3Pragma( int iBt = (pId2->z?iDb:SQLITE_MAX_ATTACHED); int eMode = SQLITE_CHECKPOINT_PASSIVE; if( zRight ){ - if( tdsqlite3StrICmp(zRight, "full")==0 ){ + if( sqlite3StrICmp(zRight, "full")==0 ){ eMode = SQLITE_CHECKPOINT_FULL; - }else if( tdsqlite3StrICmp(zRight, "restart")==0 ){ + }else if( sqlite3StrICmp(zRight, "restart")==0 ){ eMode = SQLITE_CHECKPOINT_RESTART; - }else if( tdsqlite3StrICmp(zRight, "truncate")==0 ){ + }else if( sqlite3StrICmp(zRight, "truncate")==0 ){ eMode = SQLITE_CHECKPOINT_TRUNCATE; } } pParse->nMem = 3; - tdsqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); + sqlite3VdbeAddOp3(v, OP_Checkpoint, iBt, eMode, 1); + sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3); } break; @@ -129944,10 +129944,10 @@ SQLITE_PRIVATE void tdsqlite3Pragma( */ case PragTyp_WAL_AUTOCHECKPOINT: { if( zRight ){ - tdsqlite3_wal_autocheckpoint(db, tdsqlite3Atoi(zRight)); + sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); } returnSingleInt(v, - db->xWalCallback==tdsqlite3WalDefaultHook ? + db->xWalCallback==sqlite3WalDefaultHook ? SQLITE_PTR_TO_INT(db->pWalArg) : 0); } break; @@ -129958,10 +129958,10 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** ** IMPLEMENTATION-OF: R-23445-46109 This pragma causes the database ** connection on which it is invoked to free up as much memory as it - ** can, by calling tdsqlite3_db_release_memory(). + ** can, by calling sqlite3_db_release_memory(). */ case PragTyp_SHRINK_MEMORY: { - tdsqlite3_db_release_memory(db); + sqlite3_db_release_memory(db); break; } @@ -130031,7 +130031,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( u32 opMask; /* Mask of operations to perform */ if( zRight ){ - opMask = (u32)tdsqlite3Atoi(zRight); + opMask = (u32)sqlite3Atoi(zRight); if( (opMask & 0x02)==0 ) break; }else{ opMask = 0xfffe; @@ -130039,7 +130039,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( iTabCur = pParse->nTab++; for(iDbLast = zDb?iDb:db->nDb-1; iDb<=iDbLast; iDb++){ if( iDb==1 ) continue; - tdsqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iDb); pSchema = db->aDb[iDb].pSchema; for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ pTab = (Table*)sqliteHashData(k); @@ -130050,7 +130050,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( if( (pTab->tabFlags & TF_StatsUsed)==0 ) continue; /* Reanalyze if the table is 25 times larger than the last analysis */ - szThreshold = pTab->nRowLogEst + 46; assert( tdsqlite3LogEst(25)==46 ); + szThreshold = pTab->nRowLogEst + 46; assert( sqlite3LogEst(25)==46 ); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( !pIdx->hasStat1 ){ szThreshold = 0; /* Always analyze if any index lacks statistics */ @@ -130058,23 +130058,23 @@ SQLITE_PRIVATE void tdsqlite3Pragma( } } if( szThreshold ){ - tdsqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); - tdsqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, - tdsqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold); + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, + sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold); VdbeCoverage(v); } - zSubSql = tdsqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", + zSubSql = sqlite3MPrintf(db, "ANALYZE \"%w\".\"%w\"", db->aDb[iDb].zDbSName, pTab->zName); if( opMask & 0x01 ){ - int r1 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); + int r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_String8, 0, r1, 0, zSubSql, P4_DYNAMIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, r1, 1); }else{ - tdsqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); + sqlite3VdbeAddOp4(v, OP_SqlExec, 0, 0, 0, zSubSql, P4_DYNAMIC); } } } - tdsqlite3VdbeAddOp0(v, OP_Expire); + sqlite3VdbeAddOp0(v, OP_Expire); break; } @@ -130082,7 +130082,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** PRAGMA busy_timeout ** PRAGMA busy_timeout = N ** - ** Call tdsqlite3_busy_timeout(db, N). Return the current timeout value + ** Call sqlite3_busy_timeout(db, N). Return the current timeout value ** if one is set. If no busy handler or a different busy handler is set ** then 0 is returned. Setting the busy_timeout to 0 or negative ** disables the timeout. @@ -130090,7 +130090,7 @@ SQLITE_PRIVATE void tdsqlite3Pragma( /*case PragTyp_BUSY_TIMEOUT*/ default: { assert( pPragma->ePragTyp==PragTyp_BUSY_TIMEOUT ); if( zRight ){ - tdsqlite3_busy_timeout(db, tdsqlite3Atoi(zRight)); + sqlite3_busy_timeout(db, sqlite3Atoi(zRight)); } returnSingleInt(v, db->busyTimeout); break; @@ -130101,18 +130101,18 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** PRAGMA soft_heap_limit = N ** ** IMPLEMENTATION-OF: R-26343-45930 This pragma invokes the - ** tdsqlite3_soft_heap_limit64() interface with the argument N, if N is + ** sqlite3_soft_heap_limit64() interface with the argument N, if N is ** specified and is a non-negative integer. ** IMPLEMENTATION-OF: R-64451-07163 The soft_heap_limit pragma always ** returns the same integer that would be returned by the - ** tdsqlite3_soft_heap_limit64(-1) C-language function. + ** sqlite3_soft_heap_limit64(-1) C-language function. */ case PragTyp_SOFT_HEAP_LIMIT: { - tdsqlite3_int64 N; - if( zRight && tdsqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ - tdsqlite3_soft_heap_limit64(N); + sqlite3_int64 N; + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ + sqlite3_soft_heap_limit64(N); } - returnSingleInt(v, tdsqlite3_soft_heap_limit64(-1)); + returnSingleInt(v, sqlite3_soft_heap_limit64(-1)); break; } @@ -130120,20 +130120,20 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** PRAGMA hard_heap_limit ** PRAGMA hard_heap_limit = N ** - ** Invoke tdsqlite3_hard_heap_limit64() to query or set the hard heap + ** Invoke sqlite3_hard_heap_limit64() to query or set the hard heap ** limit. The hard heap limit can be activated or lowered by this ** pragma, but not raised or deactivated. Only the - ** tdsqlite3_hard_heap_limit64() C-language API can raise or deactivate + ** sqlite3_hard_heap_limit64() C-language API can raise or deactivate ** the hard heap limit. This allows an application to set a heap limit ** constraint that cannot be relaxed by an untrusted SQL script. */ case PragTyp_HARD_HEAP_LIMIT: { - tdsqlite3_int64 N; - if( zRight && tdsqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ - tdsqlite3_int64 iPrior = tdsqlite3_hard_heap_limit64(-1); - if( N>0 && (iPrior==0 || iPrior>N) ) tdsqlite3_hard_heap_limit64(N); + sqlite3_int64 N; + if( zRight && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK ){ + sqlite3_int64 iPrior = sqlite3_hard_heap_limit64(-1); + if( N>0 && (iPrior==0 || iPrior>N) ) sqlite3_hard_heap_limit64(N); } - returnSingleInt(v, tdsqlite3_hard_heap_limit64(-1)); + returnSingleInt(v, sqlite3_hard_heap_limit64(-1)); break; } @@ -130145,14 +130145,14 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** maximum, which might be less than requested. */ case PragTyp_THREADS: { - tdsqlite3_int64 N; + sqlite3_int64 N; if( zRight - && tdsqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK + && sqlite3DecOrHexToI64(zRight, &N)==SQLITE_OK && N>=0 ){ - tdsqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); + sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, (int)(N&0x7fffffff)); } - returnSingleInt(v, tdsqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); + returnSingleInt(v, sqlite3_limit(db, SQLITE_LIMIT_WORKER_THREADS, -1)); break; } @@ -130172,13 +130172,13 @@ SQLITE_PRIVATE void tdsqlite3Pragma( int j; if( db->aDb[i].zDbSName==0 ) continue; pBt = db->aDb[i].pBt; - if( pBt==0 || tdsqlite3BtreePager(pBt)==0 ){ + if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ zState = "closed"; - }else if( tdsqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, + }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ zState = azLockName[j]; } - tdsqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState); + sqlite3VdbeMultiLoad(v, 1, "ss", db->aDb[i].zDbSName, zState); } break; } @@ -130202,23 +130202,23 @@ SQLITE_PRIVATE void tdsqlite3Pragma( if( pPragma->iArg==2 || pPragma->iArg==3 ){ u8 iByte; int i; - for(i=0, iByte=0; iiArg<4 ? tdsqlite3Strlen30(zRight) : -1; + n = pPragma->iArg<4 ? sqlite3Strlen30(zRight) : -1; } if( (pPragma->iArg & 1)==0 ){ - rc = tdsqlite3_key_v2(db, zDb, zKey, n); + rc = sqlite3_key_v2(db, zDb, zKey, n); }else{ - rc = tdsqlite3_rekey_v2(db, zDb, zKey, n); + rc = sqlite3_rekey_v2(db, zDb, zKey, n); } if( rc==SQLITE_OK && n!=0 ){ - tdsqlite3VdbeSetNumCols(v, 1); - tdsqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "ok", SQLITE_STATIC); returnSingleText(v, "ok"); } } @@ -130228,13 +130228,13 @@ SQLITE_PRIVATE void tdsqlite3Pragma( #if defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD) case PragTyp_ACTIVATE_EXTENSIONS: if( zRight ){ #ifdef SQLITE_HAS_CODEC - if( tdsqlite3StrNICmp(zRight, "see-", 4)==0 ){ - tdsqlite3_activate_see(&zRight[4]); + if( sqlite3StrNICmp(zRight, "see-", 4)==0 ){ + sqlite3_activate_see(&zRight[4]); } #endif #ifdef SQLITE_ENABLE_CEROD - if( tdsqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ - tdsqlite3_activate_cerod(&zRight[6]); + if( sqlite3StrNICmp(zRight, "cerod-", 6)==0 ){ + sqlite3_activate_cerod(&zRight[6]); } #endif } @@ -130249,12 +130249,12 @@ SQLITE_PRIVATE void tdsqlite3Pragma( ** to the PRAGMA, the implementation has not added any OP_ResultRow ** instructions to the VM. */ if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){ - tdsqlite3VdbeVerifyNoResultRow(v); + sqlite3VdbeVerifyNoResultRow(v); } pragma_out: - tdsqlite3DbFree(db, zLeft); - tdsqlite3DbFree(db, zRight); + sqlite3DbFree(db, zLeft); + sqlite3DbFree(db, zRight); } #ifndef SQLITE_OMIT_VIRTUALTABLE /***************************************************************************** @@ -130264,15 +130264,15 @@ pragma_out: typedef struct PragmaVtab PragmaVtab; typedef struct PragmaVtabCursor PragmaVtabCursor; struct PragmaVtab { - tdsqlite3_vtab base; /* Base class. Must be first */ - tdsqlite3 *db; /* The database connection to which it belongs */ + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The database connection to which it belongs */ const PragmaName *pName; /* Name of the pragma */ u8 nHidden; /* Number of hidden columns */ u8 iHidden; /* Index of the first hidden column */ }; struct PragmaVtabCursor { - tdsqlite3_vtab_cursor base; /* Base class. Must be first */ - tdsqlite3_stmt *pPragma; /* The pragma statement to run */ + sqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_stmt *pPragma; /* The pragma statement to run */ sqlite_int64 iRowid; /* Current rowid */ char *azArg[2]; /* Value of the argument and schema */ }; @@ -130281,10 +130281,10 @@ struct PragmaVtabCursor { ** Pragma virtual table module xConnect method. */ static int pragmaVtabConnect( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ const PragmaName *pPragma = (const PragmaName*)pAux; @@ -130297,31 +130297,31 @@ static int pragmaVtabConnect( UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); - tdsqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); - tdsqlite3_str_appendall(&acc, "CREATE TABLE x"); + sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0); + sqlite3_str_appendall(&acc, "CREATE TABLE x"); for(i=0, j=pPragma->iPragCName; inPragCName; i++, j++){ - tdsqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]); + sqlite3_str_appendf(&acc, "%c\"%s\"", cSep, pragCName[j]); cSep = ','; } if( i==0 ){ - tdsqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName); + sqlite3_str_appendf(&acc, "(\"%s\"", pPragma->zName); i++; } j = 0; if( pPragma->mPragFlg & PragFlg_Result1 ){ - tdsqlite3_str_appendall(&acc, ",arg HIDDEN"); + sqlite3_str_appendall(&acc, ",arg HIDDEN"); j++; } if( pPragma->mPragFlg & (PragFlg_SchemaOpt|PragFlg_SchemaReq) ){ - tdsqlite3_str_appendall(&acc, ",schema HIDDEN"); + sqlite3_str_appendall(&acc, ",schema HIDDEN"); j++; } - tdsqlite3_str_append(&acc, ")", 1); - tdsqlite3StrAccumFinish(&acc); + sqlite3_str_append(&acc, ")", 1); + sqlite3StrAccumFinish(&acc); assert( strlen(zBuf) < sizeof(zBuf)-1 ); - rc = tdsqlite3_declare_vtab(db, zBuf); + rc = sqlite3_declare_vtab(db, zBuf); if( rc==SQLITE_OK ){ - pTab = (PragmaVtab*)tdsqlite3_malloc(sizeof(PragmaVtab)); + pTab = (PragmaVtab*)sqlite3_malloc(sizeof(PragmaVtab)); if( pTab==0 ){ rc = SQLITE_NOMEM; }else{ @@ -130332,19 +130332,19 @@ static int pragmaVtabConnect( pTab->nHidden = j; } }else{ - *pzErr = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); } - *ppVtab = (tdsqlite3_vtab*)pTab; + *ppVtab = (sqlite3_vtab*)pTab; return rc; } /* ** Pragma virtual table module xDisconnect method. */ -static int pragmaVtabDisconnect(tdsqlite3_vtab *pVtab){ +static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){ PragmaVtab *pTab = (PragmaVtab*)pVtab; - tdsqlite3_free(pTab); + sqlite3_free(pTab); return SQLITE_OK; } @@ -130355,9 +130355,9 @@ static int pragmaVtabDisconnect(tdsqlite3_vtab *pVtab){ ** possible, and especially on the first hidden parameter. So return a ** high cost if hidden parameters are unconstrained. */ -static int pragmaVtabBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ +static int pragmaVtabBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ PragmaVtab *pTab = (PragmaVtab*)tab; - const struct tdsqlite3_index_constraint *pConstraint; + const struct sqlite3_index_constraint *pConstraint; int i, j; int seen[2]; @@ -130392,9 +130392,9 @@ static int pragmaVtabBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxIn } /* Create a new cursor for the pragma virtual table */ -static int pragmaVtabOpen(tdsqlite3_vtab *pVtab, tdsqlite3_vtab_cursor **ppCursor){ +static int pragmaVtabOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){ PragmaVtabCursor *pCsr; - pCsr = (PragmaVtabCursor*)tdsqlite3_malloc(sizeof(*pCsr)); + pCsr = (PragmaVtabCursor*)sqlite3_malloc(sizeof(*pCsr)); if( pCsr==0 ) return SQLITE_NOMEM; memset(pCsr, 0, sizeof(PragmaVtabCursor)); pCsr->base.pVtab = pVtab; @@ -130405,32 +130405,32 @@ static int pragmaVtabOpen(tdsqlite3_vtab *pVtab, tdsqlite3_vtab_cursor **ppCurso /* Clear all content from pragma virtual table cursor. */ static void pragmaVtabCursorClear(PragmaVtabCursor *pCsr){ int i; - tdsqlite3_finalize(pCsr->pPragma); + sqlite3_finalize(pCsr->pPragma); pCsr->pPragma = 0; for(i=0; iazArg); i++){ - tdsqlite3_free(pCsr->azArg[i]); + sqlite3_free(pCsr->azArg[i]); pCsr->azArg[i] = 0; } } /* Close a pragma virtual table cursor */ -static int pragmaVtabClose(tdsqlite3_vtab_cursor *cur){ +static int pragmaVtabClose(sqlite3_vtab_cursor *cur){ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)cur; pragmaVtabCursorClear(pCsr); - tdsqlite3_free(pCsr); + sqlite3_free(pCsr); return SQLITE_OK; } /* Advance the pragma virtual table cursor to the next row */ -static int pragmaVtabNext(tdsqlite3_vtab_cursor *pVtabCursor){ +static int pragmaVtabNext(sqlite3_vtab_cursor *pVtabCursor){ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; int rc = SQLITE_OK; /* Increment the xRowid value */ pCsr->iRowid++; assert( pCsr->pPragma ); - if( SQLITE_ROW!=tdsqlite3_step(pCsr->pPragma) ){ - rc = tdsqlite3_finalize(pCsr->pPragma); + if( SQLITE_ROW!=sqlite3_step(pCsr->pPragma) ){ + rc = sqlite3_finalize(pCsr->pPragma); pCsr->pPragma = 0; pragmaVtabCursorClear(pCsr); } @@ -130441,9 +130441,9 @@ static int pragmaVtabNext(tdsqlite3_vtab_cursor *pVtabCursor){ ** Pragma virtual table module xFilter method. */ static int pragmaVtabFilter( - tdsqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, - int argc, tdsqlite3_value **argv + int argc, sqlite3_value **argv ){ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); @@ -130457,31 +130457,31 @@ static int pragmaVtabFilter( pragmaVtabCursorClear(pCsr); j = (pTab->pName->mPragFlg & PragFlg_Result1)!=0 ? 0 : 1; for(i=0; iazArg) ); assert( pCsr->azArg[j]==0 ); if( zText ){ - pCsr->azArg[j] = tdsqlite3_mprintf("%s", zText); + pCsr->azArg[j] = sqlite3_mprintf("%s", zText); if( pCsr->azArg[j]==0 ){ return SQLITE_NOMEM; } } } - tdsqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); - tdsqlite3_str_appendall(&acc, "PRAGMA "); + sqlite3StrAccumInit(&acc, 0, 0, 0, pTab->db->aLimit[SQLITE_LIMIT_SQL_LENGTH]); + sqlite3_str_appendall(&acc, "PRAGMA "); if( pCsr->azArg[1] ){ - tdsqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]); + sqlite3_str_appendf(&acc, "%Q.", pCsr->azArg[1]); } - tdsqlite3_str_appendall(&acc, pTab->pName->zName); + sqlite3_str_appendall(&acc, pTab->pName->zName); if( pCsr->azArg[0] ){ - tdsqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]); + sqlite3_str_appendf(&acc, "=%Q", pCsr->azArg[0]); } - zSql = tdsqlite3StrAccumFinish(&acc); + zSql = sqlite3StrAccumFinish(&acc); if( zSql==0 ) return SQLITE_NOMEM; - rc = tdsqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0); - tdsqlite3_free(zSql); + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pPragma, 0); + sqlite3_free(zSql); if( rc!=SQLITE_OK ){ - pTab->base.zErrMsg = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(pTab->db)); + pTab->base.zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pTab->db)); return rc; } return pragmaVtabNext(pVtabCursor); @@ -130490,7 +130490,7 @@ static int pragmaVtabFilter( /* ** Pragma virtual table module xEof method. */ -static int pragmaVtabEof(tdsqlite3_vtab_cursor *pVtabCursor){ +static int pragmaVtabEof(sqlite3_vtab_cursor *pVtabCursor){ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; return (pCsr->pPragma==0); } @@ -130499,16 +130499,16 @@ static int pragmaVtabEof(tdsqlite3_vtab_cursor *pVtabCursor){ ** the PRAGMA. */ static int pragmaVtabColumn( - tdsqlite3_vtab_cursor *pVtabCursor, - tdsqlite3_context *ctx, + sqlite3_vtab_cursor *pVtabCursor, + sqlite3_context *ctx, int i ){ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; PragmaVtab *pTab = (PragmaVtab*)(pVtabCursor->pVtab); if( iiHidden ){ - tdsqlite3_result_value(ctx, tdsqlite3_column_value(pCsr->pPragma, i)); + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pPragma, i)); }else{ - tdsqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT); + sqlite3_result_text(ctx, pCsr->azArg[i-pTab->iHidden],-1,SQLITE_TRANSIENT); } return SQLITE_OK; } @@ -130516,14 +130516,14 @@ static int pragmaVtabColumn( /* ** Pragma virtual table module xRowid method. */ -static int pragmaVtabRowid(tdsqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ +static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; *p = pCsr->iRowid; return SQLITE_OK; } /* The pragma virtual table object */ -static const tdsqlite3_module pragmaVtabModule = { +static const sqlite3_module pragmaVtabModule = { 0, /* iVersion */ 0, /* xCreate - create a table */ pragmaVtabConnect, /* xConnect - connect to an existing table */ @@ -130555,14 +130555,14 @@ static const tdsqlite3_module pragmaVtabModule = { ** then register an eponymous virtual table for that pragma and return ** a pointer to the Module object for the new virtual table. */ -SQLITE_PRIVATE Module *tdsqlite3PragmaVtabRegister(tdsqlite3 *db, const char *zName){ +SQLITE_PRIVATE Module *sqlite3PragmaVtabRegister(sqlite3 *db, const char *zName){ const PragmaName *pName; - assert( tdsqlite3_strnicmp(zName, "pragma_", 7)==0 ); + assert( sqlite3_strnicmp(zName, "pragma_", 7)==0 ); pName = pragmaLocate(zName+7); if( pName==0 ) return 0; if( (pName->mPragFlg & (PragFlg_Result0|PragFlg_Result1))==0 ) return 0; - assert( tdsqlite3HashFind(&db->aModule, zName)==0 ); - return tdsqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0); + assert( sqlite3HashFind(&db->aModule, zName)==0 ); + return sqlite3VtabCreateModule(db, zName, &pragmaVtabModule, (void*)pName, 0); } #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -130582,7 +130582,7 @@ SQLITE_PRIVATE Module *tdsqlite3PragmaVtabRegister(tdsqlite3 *db, const char *zN ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file contains the implementation of the tdsqlite3_prepare() +** This file contains the implementation of the sqlite3_prepare() ** interface, and routines that contribute to loading the database schema ** from disk. */ @@ -130597,21 +130597,21 @@ static void corruptSchema( const char *zObj, /* Object being parsed at the point of error */ const char *zExtra /* Error information */ ){ - tdsqlite3 *db = pData->db; + sqlite3 *db = pData->db; if( db->mallocFailed ){ pData->rc = SQLITE_NOMEM_BKPT; }else if( pData->pzErrMsg[0]!=0 ){ /* A error message has already been generated. Do not overwrite it */ }else if( pData->mInitFlags & INITFLAG_AlterTable ){ - *pData->pzErrMsg = tdsqlite3DbStrDup(db, zExtra); + *pData->pzErrMsg = sqlite3DbStrDup(db, zExtra); pData->rc = SQLITE_ERROR; }else if( db->flags & SQLITE_WriteSchema ){ pData->rc = SQLITE_CORRUPT_BKPT; }else{ char *z; if( zObj==0 ) zObj = "?"; - z = tdsqlite3MPrintf(db, "malformed database schema (%s)", zObj); - if( zExtra && zExtra[0] ) z = tdsqlite3MPrintf(db, "%z - %s", z, zExtra); + z = sqlite3MPrintf(db, "malformed database schema (%s)", zObj); + if( zExtra && zExtra[0] ) z = sqlite3MPrintf(db, "%z - %s", z, zExtra); *pData->pzErrMsg = z; pData->rc = SQLITE_CORRUPT_BKPT; } @@ -130622,7 +130622,7 @@ static void corruptSchema( ** of pIndex has the same root page number, and if it does, return true. ** This would indicate a corrupt schema. */ -SQLITE_PRIVATE int tdsqlite3IndexHasDuplicateRootPage(Index *pIndex){ +SQLITE_PRIVATE int sqlite3IndexHasDuplicateRootPage(Index *pIndex){ Index *p; for(p=pIndex->pTable->pIndex; p; p=p->pNext){ if( p->tnum==pIndex->tnum && p!=pIndex ) return 1; @@ -130631,20 +130631,20 @@ SQLITE_PRIVATE int tdsqlite3IndexHasDuplicateRootPage(Index *pIndex){ } /* forward declaration */ -static int tdsqlite3Prepare( - tdsqlite3 *db, /* Database handle. */ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ Vdbe *pReprepare, /* VM being reprepared */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ); /* ** This is the callback routine for the code that initializes the -** database. See tdsqlite3Init() below for additional information. +** database. See sqlite3Init() below for additional information. ** This routine is also called from the OP_ParseSchema opcode of the VDBE. ** ** Each callback contains the following information: @@ -130656,14 +130656,14 @@ static int tdsqlite3Prepare( ** argv[4] = SQL text for the CREATE statement. ** */ -SQLITE_PRIVATE int tdsqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ +SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ InitData *pData = (InitData*)pInit; - tdsqlite3 *db = pData->db; + sqlite3 *db = pData->db; int iDb = pData->iDb; assert( argc==5 ); UNUSED_PARAMETER2(NotUsed, argc); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); DbClearProperty(db, iDb, DB_Empty); pData->nInitRow++; if( db->mallocFailed ){ @@ -130675,7 +130675,7 @@ SQLITE_PRIVATE int tdsqlite3InitCallback(void *pInit, int argc, char **argv, cha if( argv==0 ) return 0; /* Might happen if EMPTY_RESULT_CALLBACKS are on */ if( argv[3]==0 ){ corruptSchema(pData, argv[1], 0); - }else if( tdsqlite3_strnicmp(argv[4],"create ",7)==0 ){ + }else if( sqlite3_strnicmp(argv[4],"create ",7)==0 ){ /* Call the parser to process a CREATE TABLE, INDEX or VIEW. ** But because db->init.busy is set to 1, no VDBE code is generated ** or executed. All the parser does is build the internal data @@ -130683,16 +130683,16 @@ SQLITE_PRIVATE int tdsqlite3InitCallback(void *pInit, int argc, char **argv, cha */ int rc; u8 saved_iDb = db->init.iDb; - tdsqlite3_stmt *pStmt; - TESTONLY(int rcp); /* Return code from tdsqlite3_prepare() */ + sqlite3_stmt *pStmt; + TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ assert( db->init.busy ); db->init.iDb = iDb; - db->init.newTnum = tdsqlite3Atoi(argv[3]); + db->init.newTnum = sqlite3Atoi(argv[3]); db->init.orphanTrigger = 0; db->init.azInit = argv; pStmt = 0; - TESTONLY(rcp = ) tdsqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0); + TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0); rc = db->errCode; assert( (rc&0xFF)==(rcp&0xFF) ); db->init.iDb = saved_iDb; @@ -130703,13 +130703,13 @@ SQLITE_PRIVATE int tdsqlite3InitCallback(void *pInit, int argc, char **argv, cha }else{ if( rc > pData->rc ) pData->rc = rc; if( rc==SQLITE_NOMEM ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ - corruptSchema(pData, argv[1], tdsqlite3_errmsg(db)); + corruptSchema(pData, argv[1], sqlite3_errmsg(db)); } } } - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){ corruptSchema(pData, argv[1], 0); }else{ @@ -130720,11 +130720,11 @@ SQLITE_PRIVATE int tdsqlite3InitCallback(void *pInit, int argc, char **argv, cha ** to do here is record the root page number for that index. */ Index *pIndex; - pIndex = tdsqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName); + pIndex = sqlite3FindIndex(db, argv[1], db->aDb[iDb].zDbSName); if( pIndex==0 - || tdsqlite3GetInt32(argv[3],&pIndex->tnum)==0 + || sqlite3GetInt32(argv[3],&pIndex->tnum)==0 || pIndex->tnum<2 - || tdsqlite3IndexHasDuplicateRootPage(pIndex) + || sqlite3IndexHasDuplicateRootPage(pIndex) ){ corruptSchema(pData, argv[1], pIndex?"invalid rootpage":"orphan index"); } @@ -130740,7 +130740,7 @@ SQLITE_PRIVATE int tdsqlite3InitCallback(void *pInit, int argc, char **argv, cha ** auxiliary databases. Return one of the SQLITE_ error codes to ** indicate success or failure. */ -SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ +SQLITE_PRIVATE int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg, u32 mFlags){ int rc; int i; #ifndef SQLITE_OMIT_DEPRECATED @@ -130756,8 +130756,8 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 assert( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ); assert( iDb>=0 && iDbnDb ); assert( db->aDb[iDb].pSchema ); - assert( tdsqlite3_mutex_held(db->mutex) ); - assert( iDb==1 || tdsqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( iDb==1 || sqlite3BtreeHoldsMutex(db->aDb[iDb].pBt) ); db->init.busy = 1; @@ -130779,7 +130779,7 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 initData.pzErrMsg = pzErrMsg; initData.mInitFlags = mFlags; initData.nInitRow = 0; - tdsqlite3InitCallback(&initData, 5, (char **)azArg, 0); + sqlite3InitCallback(&initData, 5, (char **)azArg, 0); if( initData.rc ){ rc = initData.rc; goto error_out; @@ -130798,11 +130798,11 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 /* If there is not already a read-only (or read-write) transaction opened ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed before this function returns. */ - tdsqlite3BtreeEnter(pDb->pBt); - if( !tdsqlite3BtreeIsInReadTrans(pDb->pBt) ){ - rc = tdsqlite3BtreeBeginTrans(pDb->pBt, 0, 0); + sqlite3BtreeEnter(pDb->pBt); + if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0, 0); if( rc!=SQLITE_OK ){ - tdsqlite3SetString(pzErrMsg, db, tdsqlite3ErrStr(rc)); + sqlite3SetString(pzErrMsg, db, sqlite3ErrStr(rc)); goto initone_error_out; } openedTransaction = 1; @@ -130826,7 +130826,7 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 ** the possible values of meta[4]. */ for(i=0; ipBt, i+1, (u32 *)&meta[i]); + sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]); } if( (db->flags & SQLITE_ResetDatabase)!=0 ){ memset(meta, 0, sizeof(meta)); @@ -130852,7 +130852,7 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 }else{ /* If opening an attached database, the encoding much match ENC(db) */ if( meta[BTREE_TEXT_ENCODING-1]!=ENC(db) ){ - tdsqlite3SetString(pzErrMsg, db, "attached databases must use the same" + sqlite3SetString(pzErrMsg, db, "attached databases must use the same" " text encoding as main database"); rc = SQLITE_ERROR; goto initone_error_out; @@ -130865,13 +130865,13 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 if( pDb->pSchema->cache_size==0 ){ #ifndef SQLITE_OMIT_DEPRECATED - size = tdsqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); + size = sqlite3AbsInt32(meta[BTREE_DEFAULT_CACHE_SIZE-1]); if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; } pDb->pSchema->cache_size = size; #else pDb->pSchema->cache_size = SQLITE_DEFAULT_CACHE_SIZE; #endif - tdsqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); + sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size); } /* @@ -130885,7 +130885,7 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 pDb->pSchema->file_format = 1; } if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){ - tdsqlite3SetString(pzErrMsg, db, "unsupported file format"); + sqlite3SetString(pzErrMsg, db, "unsupported file format"); rc = SQLITE_ERROR; goto initone_error_out; } @@ -130904,36 +130904,36 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 assert( db->init.busy ); { char *zSql; - zSql = tdsqlite3MPrintf(db, + zSql = sqlite3MPrintf(db, "SELECT*FROM\"%w\".%s ORDER BY rowid", db->aDb[iDb].zDbSName, zMasterName); #ifndef SQLITE_OMIT_AUTHORIZATION { - tdsqlite3_xauth xAuth; + sqlite3_xauth xAuth; xAuth = db->xAuth; db->xAuth = 0; #endif - rc = tdsqlite3_exec(db, zSql, tdsqlite3InitCallback, &initData, 0); + rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0); #ifndef SQLITE_OMIT_AUTHORIZATION db->xAuth = xAuth; } #endif if( rc==SQLITE_OK ) rc = initData.rc; - tdsqlite3DbFree(db, zSql); + sqlite3DbFree(db, zSql); #ifndef SQLITE_OMIT_ANALYZE if( rc==SQLITE_OK ){ - tdsqlite3AnalysisLoad(db, iDb); + sqlite3AnalysisLoad(db, iDb); } #endif } if( db->mallocFailed ){ rc = SQLITE_NOMEM_BKPT; - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ResetAllSchemasOfConnection(db); } if( rc==SQLITE_OK || (db->flags&SQLITE_NoSchemaError)){ /* Black magic: If the SQLITE_NoSchemaError flag is set, then consider ** the schema loaded, even if errors occurred. In this situation the - ** current tdsqlite3_prepare() operation will fail, but the following one + ** current sqlite3_prepare() operation will fail, but the following one ** will attempt to compile the supplied statement against whatever subset ** of the schema was loaded before the error occurred. The primary ** purpose of this is to allow access to the sqlite_master table @@ -130944,21 +130944,21 @@ SQLITE_PRIVATE int tdsqlite3InitOne(tdsqlite3 *db, int iDb, char **pzErrMsg, u32 } /* Jump here for an error that occurs after successfully allocating - ** curMain and calling tdsqlite3BtreeEnter(). For an error that occurs + ** curMain and calling sqlite3BtreeEnter(). For an error that occurs ** before that point, jump to error_out. */ initone_error_out: if( openedTransaction ){ - tdsqlite3BtreeCommit(pDb->pBt); + sqlite3BtreeCommit(pDb->pBt); } - tdsqlite3BtreeLeave(pDb->pBt); + sqlite3BtreeLeave(pDb->pBt); error_out: if( rc ){ if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); } - tdsqlite3ResetOneSchema(db, iDb); + sqlite3ResetOneSchema(db, iDb); } db->init.busy = 0; return rc; @@ -130974,30 +130974,30 @@ error_out: ** bit is set in the flags field of the Db structure. If the database ** file was of zero-length, then the DB_Empty flag is also set. */ -SQLITE_PRIVATE int tdsqlite3Init(tdsqlite3 *db, char **pzErrMsg){ +SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ int i, rc; int commit_internal = !(db->mDbFlags&DBFLAG_SchemaChange); - assert( tdsqlite3_mutex_held(db->mutex) ); - assert( tdsqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); + assert( sqlite3_mutex_held(db->mutex) ); + assert( sqlite3BtreeHoldsMutex(db->aDb[0].pBt) ); assert( db->init.busy==0 ); ENC(db) = SCHEMA_ENC(db); assert( db->nDb>0 ); /* Do the main schema first */ if( !DbHasProperty(db, 0, DB_SchemaLoaded) ){ - rc = tdsqlite3InitOne(db, 0, pzErrMsg, 0); + rc = sqlite3InitOne(db, 0, pzErrMsg, 0); if( rc ) return rc; } /* All other schemas after the main schema. The "temp" schema must be last */ for(i=db->nDb-1; i>0; i--){ - assert( i==1 || tdsqlite3BtreeHoldsMutex(db->aDb[i].pBt) ); + assert( i==1 || sqlite3BtreeHoldsMutex(db->aDb[i].pBt) ); if( !DbHasProperty(db, i, DB_SchemaLoaded) ){ - rc = tdsqlite3InitOne(db, i, pzErrMsg, 0); + rc = sqlite3InitOne(db, i, pzErrMsg, 0); if( rc ) return rc; } } if( commit_internal ){ - tdsqlite3CommitInternalChanges(db); + sqlite3CommitInternalChanges(db); } return SQLITE_OK; } @@ -131006,12 +131006,12 @@ SQLITE_PRIVATE int tdsqlite3Init(tdsqlite3 *db, char **pzErrMsg){ ** This routine is a no-op if the database schema is already initialized. ** Otherwise, the schema is loaded. An error code is returned. */ -SQLITE_PRIVATE int tdsqlite3ReadSchema(Parse *pParse){ +SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){ int rc = SQLITE_OK; - tdsqlite3 *db = pParse->db; - assert( tdsqlite3_mutex_held(db->mutex) ); + sqlite3 *db = pParse->db; + assert( sqlite3_mutex_held(db->mutex) ); if( !db->init.busy ){ - rc = tdsqlite3Init(db, &pParse->zErrMsg); + rc = sqlite3Init(db, &pParse->zErrMsg); if( rc!=SQLITE_OK ){ pParse->rc = rc; pParse->nErr++; @@ -131029,13 +131029,13 @@ SQLITE_PRIVATE int tdsqlite3ReadSchema(Parse *pParse){ ** make no changes to pParse->rc. */ static void schemaIsValid(Parse *pParse){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int iDb; int rc; int cookie; assert( pParse->checkSchema ); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); for(iDb=0; iDbnDb; iDb++){ int openedTransaction = 0; /* True if a transaction is opened */ Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */ @@ -131044,10 +131044,10 @@ static void schemaIsValid(Parse *pParse){ /* If there is not already a read-only (or read-write) transaction opened ** on the b-tree database, open one now. If a transaction is opened, it ** will be closed immediately after reading the meta-value. */ - if( !tdsqlite3BtreeIsInReadTrans(pBt) ){ - rc = tdsqlite3BtreeBeginTrans(pBt, 0, 0); + if( !sqlite3BtreeIsInReadTrans(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); } if( rc!=SQLITE_OK ) return; openedTransaction = 1; @@ -131056,16 +131056,16 @@ static void schemaIsValid(Parse *pParse){ /* Read the schema cookie from the database. If it does not match the ** value stored as part of the in-memory schema representation, ** set Parse.rc to SQLITE_SCHEMA. */ - tdsqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ - tdsqlite3ResetOneSchema(db, iDb); + sqlite3ResetOneSchema(db, iDb); pParse->rc = SQLITE_SCHEMA; } /* Close the transaction, if one was opened. */ if( openedTransaction ){ - tdsqlite3BtreeCommit(pBt); + sqlite3BtreeCommit(pBt); } } } @@ -131077,7 +131077,7 @@ static void schemaIsValid(Parse *pParse){ ** If the same database is attached more than once, the first ** attached database is returned. */ -SQLITE_PRIVATE int tdsqlite3SchemaToIndex(tdsqlite3 *db, Schema *pSchema){ +SQLITE_PRIVATE int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){ int i = -1000000; /* If pSchema is NULL, then return -1000000. This happens when code in @@ -131090,7 +131090,7 @@ SQLITE_PRIVATE int tdsqlite3SchemaToIndex(tdsqlite3 *db, Schema *pSchema){ ** more likely to cause a segfault than -1 (of course there are assert() ** statements too, but it never hurts to play the odds). */ - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); if( pSchema ){ for(i=0; 1; i++){ assert( inDb ); @@ -131106,10 +131106,10 @@ SQLITE_PRIVATE int tdsqlite3SchemaToIndex(tdsqlite3 *db, Schema *pSchema){ /* ** Free all memory allocations in the pParse object */ -SQLITE_PRIVATE void tdsqlite3ParserReset(Parse *pParse){ - tdsqlite3 *db = pParse->db; - tdsqlite3DbFree(db, pParse->aLabel); - tdsqlite3ExprListDelete(db, pParse->pConstExpr); +SQLITE_PRIVATE void sqlite3ParserReset(Parse *pParse){ + sqlite3 *db = pParse->db; + sqlite3DbFree(db, pParse->aLabel); + sqlite3ExprListDelete(db, pParse->pConstExpr); if( db ){ assert( db->lookaside.bDisable >= pParse->disableLookaside ); db->lookaside.bDisable -= pParse->disableLookaside; @@ -131121,13 +131121,13 @@ SQLITE_PRIVATE void tdsqlite3ParserReset(Parse *pParse){ /* ** Compile the UTF-8 encoded SQL statement zSql into a statement handle. */ -static int tdsqlite3Prepare( - tdsqlite3 *db, /* Database handle. */ +static int sqlite3Prepare( + sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ Vdbe *pReprepare, /* VM being reprepared */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ char *zErrMsg = 0; /* Error message */ @@ -131140,7 +131140,7 @@ static int tdsqlite3Prepare( sParse.pReprepare = pReprepare; assert( ppStmt && *ppStmt==0 ); /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */ - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); /* For a long-term use prepared statement avoid the use of ** lookaside memory. @@ -131164,7 +131164,7 @@ static int tdsqlite3Prepare( ** the schema change. Disaster would follow. ** ** This thread is currently holding mutexes on all Btrees (because - ** of the tdsqlite3BtreeEnterAll() in tdsqlite3LockAndPrepare()) so it + ** of the sqlite3BtreeEnterAll() in sqlite3LockAndPrepare()) so it ** is not possible for another thread to start a new schema change ** while this routine is running. Hence, we do not need to hold ** locks on the schema, we just need to make sure nobody else is @@ -131178,11 +131178,11 @@ static int tdsqlite3Prepare( for(i=0; inDb; i++) { Btree *pBt = db->aDb[i].pBt; if( pBt ){ - assert( tdsqlite3BtreeHoldsMutex(pBt) ); - rc = tdsqlite3BtreeSchemaLocked(pBt); + assert( sqlite3BtreeHoldsMutex(pBt) ); + rc = sqlite3BtreeSchemaLocked(pBt); if( rc ){ const char *zDb = db->aDb[i].zDbSName; - tdsqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); + sqlite3ErrorWithMsg(db, rc, "database schema is locked: %s", zDb); testcase( db->flags & SQLITE_ReadUncommit ); goto end_prepare; } @@ -131190,7 +131190,7 @@ static int tdsqlite3Prepare( } } - tdsqlite3VtabUnlockList(db); + sqlite3VtabUnlockList(db); sParse.db = db; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ @@ -131199,20 +131199,20 @@ static int tdsqlite3Prepare( testcase( nBytes==mxLen ); testcase( nBytes==mxLen+1 ); if( nBytes>mxLen ){ - tdsqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); - rc = tdsqlite3ApiExit(db, SQLITE_TOOBIG); + sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long"); + rc = sqlite3ApiExit(db, SQLITE_TOOBIG); goto end_prepare; } - zSqlCopy = tdsqlite3DbStrNDup(db, zSql, nBytes); + zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes); if( zSqlCopy ){ - tdsqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); + sqlite3RunParser(&sParse, zSqlCopy, &zErrMsg); sParse.zTail = &zSql[sParse.zTail-zSqlCopy]; - tdsqlite3DbFree(db, zSqlCopy); + sqlite3DbFree(db, zSqlCopy); }else{ sParse.zTail = &zSql[nBytes]; } }else{ - tdsqlite3RunParser(&sParse, zSql, &zErrMsg); + sqlite3RunParser(&sParse, zSql, &zErrMsg); } assert( 0==sParse.nQueryLoop ); @@ -131227,45 +131227,45 @@ static int tdsqlite3Prepare( } if( db->init.busy==0 ){ - tdsqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags); + sqlite3VdbeSetSql(sParse.pVdbe, zSql, (int)(sParse.zTail-zSql), prepFlags); } if( db->mallocFailed ){ sParse.rc = SQLITE_NOMEM_BKPT; } rc = sParse.rc; if( rc!=SQLITE_OK ){ - if( sParse.pVdbe ) tdsqlite3VdbeFinalize(sParse.pVdbe); + if( sParse.pVdbe ) sqlite3VdbeFinalize(sParse.pVdbe); assert(!(*ppStmt)); }else{ - *ppStmt = (tdsqlite3_stmt*)sParse.pVdbe; + *ppStmt = (sqlite3_stmt*)sParse.pVdbe; } if( zErrMsg ){ - tdsqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); - tdsqlite3DbFree(db, zErrMsg); + sqlite3ErrorWithMsg(db, rc, "%s", zErrMsg); + sqlite3DbFree(db, zErrMsg); }else{ - tdsqlite3Error(db, rc); + sqlite3Error(db, rc); } /* Delete any TriggerPrg structures allocated while parsing this statement. */ while( sParse.pTriggerPrg ){ TriggerPrg *pT = sParse.pTriggerPrg; sParse.pTriggerPrg = pT->pNext; - tdsqlite3DbFree(db, pT); + sqlite3DbFree(db, pT); } end_prepare: - tdsqlite3ParserReset(&sParse); + sqlite3ParserReset(&sParse); return rc; } -static int tdsqlite3LockAndPrepare( - tdsqlite3 *db, /* Database handle. */ +static int sqlite3LockAndPrepare( + sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ Vdbe *pOld, /* VM being reprepared */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ int rc; @@ -131275,23 +131275,23 @@ static int tdsqlite3LockAndPrepare( if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; #endif *ppStmt = 0; - if( !tdsqlite3SafetyCheckOk(db)||zSql==0 ){ + if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; } - tdsqlite3_mutex_enter(db->mutex); - tdsqlite3BtreeEnterAll(db); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); do{ /* Make multiple attempts to compile the SQL, until it either succeeds ** or encounters a permanent error. A schema problem after one schema ** reset is considered a permanent error. */ - rc = tdsqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); + rc = sqlite3Prepare(db, zSql, nBytes, prepFlags, pOld, ppStmt, pzTail); assert( rc==SQLITE_OK || *ppStmt==0 ); }while( rc==SQLITE_ERROR_RETRY - || (rc==SQLITE_SCHEMA && (tdsqlite3ResetOneSchema(db,-1), cnt++)==0) ); - tdsqlite3BtreeLeaveAll(db); - rc = tdsqlite3ApiExit(db, rc); + || (rc==SQLITE_SCHEMA && (sqlite3ResetOneSchema(db,-1), cnt++)==0) ); + sqlite3BtreeLeaveAll(db); + rc = sqlite3ApiExit(db, rc); assert( (rc&db->errMask)==rc ); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -131301,36 +131301,36 @@ static int tdsqlite3LockAndPrepare( ** ** If the statement is successfully recompiled, return SQLITE_OK. Otherwise, ** if the statement cannot be recompiled because another connection has -** locked the tdsqlite3_master table, return SQLITE_LOCKED. If any other error +** locked the sqlite3_master table, return SQLITE_LOCKED. If any other error ** occurs, return SQLITE_SCHEMA. */ -SQLITE_PRIVATE int tdsqlite3Reprepare(Vdbe *p){ +SQLITE_PRIVATE int sqlite3Reprepare(Vdbe *p){ int rc; - tdsqlite3_stmt *pNew; + sqlite3_stmt *pNew; const char *zSql; - tdsqlite3 *db; + sqlite3 *db; u8 prepFlags; - assert( tdsqlite3_mutex_held(tdsqlite3VdbeDb(p)->mutex) ); - zSql = tdsqlite3_sql((tdsqlite3_stmt *)p); + assert( sqlite3_mutex_held(sqlite3VdbeDb(p)->mutex) ); + zSql = sqlite3_sql((sqlite3_stmt *)p); assert( zSql!=0 ); /* Reprepare only called for prepare_v2() statements */ - db = tdsqlite3VdbeDb(p); - assert( tdsqlite3_mutex_held(db->mutex) ); - prepFlags = tdsqlite3VdbePrepareFlags(p); - rc = tdsqlite3LockAndPrepare(db, zSql, -1, prepFlags, p, &pNew, 0); + db = sqlite3VdbeDb(p); + assert( sqlite3_mutex_held(db->mutex) ); + prepFlags = sqlite3VdbePrepareFlags(p); + rc = sqlite3LockAndPrepare(db, zSql, -1, prepFlags, p, &pNew, 0); if( rc ){ if( rc==SQLITE_NOMEM ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); } assert( pNew==0 ); return rc; }else{ assert( pNew!=0 ); } - tdsqlite3VdbeSwap((Vdbe*)pNew, p); - tdsqlite3TransferBindings(pNew, (tdsqlite3_stmt*)p); - tdsqlite3VdbeResetStepResult((Vdbe*)pNew); - tdsqlite3VdbeFinalize((Vdbe*)pNew); + sqlite3VdbeSwap((Vdbe*)pNew, p); + sqlite3TransferBindings(pNew, (sqlite3_stmt*)p); + sqlite3VdbeResetStepResult((Vdbe*)pNew); + sqlite3VdbeFinalize((Vdbe*)pNew); return SQLITE_OK; } @@ -131339,57 +131339,57 @@ SQLITE_PRIVATE int tdsqlite3Reprepare(Vdbe *p){ ** Two versions of the official API. Legacy and new use. In the legacy ** version, the original SQL text is not saved in the prepared statement ** and so if a schema change occurs, SQLITE_SCHEMA is returned by -** tdsqlite3_step(). In the new version, the original SQL text is retained +** sqlite3_step(). In the new version, the original SQL text is retained ** and the statement is automatically recompiled if an schema change ** occurs. */ -SQLITE_API int tdsqlite3_prepare( - tdsqlite3 *db, /* Database handle. */ +SQLITE_API int sqlite3_prepare( + sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ int rc; - rc = tdsqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail); + rc = sqlite3LockAndPrepare(db,zSql,nBytes,0,0,ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; } -SQLITE_API int tdsqlite3_prepare_v2( - tdsqlite3 *db, /* Database handle. */ +SQLITE_API int sqlite3_prepare_v2( + sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ int rc; - /* EVIDENCE-OF: R-37923-12173 The tdsqlite3_prepare_v2() interface works - ** exactly the same as tdsqlite3_prepare_v3() with a zero prepFlags + /* EVIDENCE-OF: R-37923-12173 The sqlite3_prepare_v2() interface works + ** exactly the same as sqlite3_prepare_v3() with a zero prepFlags ** parameter. ** - ** Proof in that the 5th parameter to tdsqlite3LockAndPrepare is 0 */ - rc = tdsqlite3LockAndPrepare(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,0, + ** Proof in that the 5th parameter to sqlite3LockAndPrepare is 0 */ + rc = sqlite3LockAndPrepare(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,0, ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); return rc; } -SQLITE_API int tdsqlite3_prepare_v3( - tdsqlite3 *db, /* Database handle. */ +SQLITE_API int sqlite3_prepare_v3( + sqlite3 *db, /* Database handle. */ const char *zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const char **pzTail /* OUT: End of parsed string */ ){ int rc; - /* EVIDENCE-OF: R-56861-42673 tdsqlite3_prepare_v3() differs from - ** tdsqlite3_prepare_v2() only in having the extra prepFlags parameter, + /* EVIDENCE-OF: R-56861-42673 sqlite3_prepare_v3() differs from + ** sqlite3_prepare_v2() only in having the extra prepFlags parameter, ** which is a bit array consisting of zero or more of the ** SQLITE_PREPARE_* flags. ** - ** Proof by comparison to the implementation of tdsqlite3_prepare_v2() + ** Proof by comparison to the implementation of sqlite3_prepare_v2() ** directly above. */ - rc = tdsqlite3LockAndPrepare(db,zSql,nBytes, + rc = sqlite3LockAndPrepare(db,zSql,nBytes, SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK), 0,ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); @@ -131401,16 +131401,16 @@ SQLITE_API int tdsqlite3_prepare_v3( /* ** Compile the UTF-16 encoded SQL statement zSql into a statement handle. */ -static int tdsqlite3Prepare16( - tdsqlite3 *db, /* Database handle. */ +static int sqlite3Prepare16( + sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ u32 prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ /* This function currently works by first transforming the UTF-16 - ** encoded string to UTF-8, then invoking tdsqlite3_prepare(). The + ** encoded string to UTF-8, then invoking sqlite3_prepare(). The ** tricky bit is figuring out the pointer to return in *pzTail. */ char *zSql8; @@ -131421,7 +131421,7 @@ static int tdsqlite3Prepare16( if( ppStmt==0 ) return SQLITE_MISUSE_BKPT; #endif *ppStmt = 0; - if( !tdsqlite3SafetyCheckOk(db)||zSql==0 ){ + if( !sqlite3SafetyCheckOk(db)||zSql==0 ){ return SQLITE_MISUSE_BKPT; } if( nBytes>=0 ){ @@ -131430,24 +131430,24 @@ static int tdsqlite3Prepare16( for(sz=0; szmutex); - zSql8 = tdsqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); + sqlite3_mutex_enter(db->mutex); + zSql8 = sqlite3Utf16to8(db, zSql, nBytes, SQLITE_UTF16NATIVE); if( zSql8 ){ - rc = tdsqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8); + rc = sqlite3LockAndPrepare(db, zSql8, -1, prepFlags, 0, ppStmt, &zTail8); } if( zTail8 && pzTail ){ - /* If tdsqlite3_prepare returns a tail pointer, we calculate the + /* If sqlite3_prepare returns a tail pointer, we calculate the ** equivalent pointer into the UTF-16 string by counting the unicode ** characters between zSql8 and zTail8, and then returning a pointer ** the same number of characters into the UTF-16 string. */ - int chars_parsed = tdsqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); - *pzTail = (u8 *)zSql + tdsqlite3Utf16ByteLen(zSql, chars_parsed); + int chars_parsed = sqlite3Utf8CharLen(zSql8, (int)(zTail8-zSql8)); + *pzTail = (u8 *)zSql + sqlite3Utf16ByteLen(zSql, chars_parsed); } - tdsqlite3DbFree(db, zSql8); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + sqlite3DbFree(db, zSql8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -131455,44 +131455,44 @@ static int tdsqlite3Prepare16( ** Two versions of the official API. Legacy and new use. In the legacy ** version, the original SQL text is not saved in the prepared statement ** and so if a schema change occurs, SQLITE_SCHEMA is returned by -** tdsqlite3_step(). In the new version, the original SQL text is retained +** sqlite3_step(). In the new version, the original SQL text is retained ** and the statement is automatically recompiled if an schema change ** occurs. */ -SQLITE_API int tdsqlite3_prepare16( - tdsqlite3 *db, /* Database handle. */ +SQLITE_API int sqlite3_prepare16( + sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ int rc; - rc = tdsqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); + rc = sqlite3Prepare16(db,zSql,nBytes,0,ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; } -SQLITE_API int tdsqlite3_prepare16_v2( - tdsqlite3 *db, /* Database handle. */ +SQLITE_API int sqlite3_prepare16_v2( + sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ int rc; - rc = tdsqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail); + rc = sqlite3Prepare16(db,zSql,nBytes,SQLITE_PREPARE_SAVESQL,ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ return rc; } -SQLITE_API int tdsqlite3_prepare16_v3( - tdsqlite3 *db, /* Database handle. */ +SQLITE_API int sqlite3_prepare16_v3( + sqlite3 *db, /* Database handle. */ const void *zSql, /* UTF-16 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ unsigned int prepFlags, /* Zero or more SQLITE_PREPARE_* flags */ - tdsqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ + sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */ const void **pzTail /* OUT: End of parsed string */ ){ int rc; - rc = tdsqlite3Prepare16(db,zSql,nBytes, + rc = sqlite3Prepare16(db,zSql,nBytes, SQLITE_PREPARE_SAVESQL|(prepFlags&SQLITE_PREPARE_MASK), ppStmt,pzTail); assert( rc==SQLITE_OK || ppStmt==0 || *ppStmt==0 ); /* VERIFY: F13021 */ @@ -131523,11 +131523,11 @@ SQLITE_API int tdsqlite3_prepare16_v3( ** Trace output macros */ #if SELECTTRACE_ENABLED -/***/ int tdsqlite3SelectTrace = 0; +/***/ int sqlite3SelectTrace = 0; # define SELECTTRACE(K,P,S,X) \ - if(tdsqlite3SelectTrace&(K)) \ - tdsqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ - tdsqlite3DebugPrintf X + if(sqlite3SelectTrace&(K)) \ + sqlite3DebugPrintf("%u/%d/%p: ",(S)->selId,(P)->addrExplain,(S)),\ + sqlite3DebugPrintf X #else # define SELECTTRACE(K,P,S,X) #endif @@ -131591,27 +131591,27 @@ struct SortCtx { ** Delete all the content of a Select structure. Deallocate the structure ** itself depending on the value of bFree ** -** If bFree==1, call tdsqlite3DbFree() on the p object. +** If bFree==1, call sqlite3DbFree() on the p object. ** If bFree==0, Leave the first Select object unfreed */ -static void clearSelect(tdsqlite3 *db, Select *p, int bFree){ +static void clearSelect(sqlite3 *db, Select *p, int bFree){ while( p ){ Select *pPrior = p->pPrior; - tdsqlite3ExprListDelete(db, p->pEList); - tdsqlite3SrcListDelete(db, p->pSrc); - tdsqlite3ExprDelete(db, p->pWhere); - tdsqlite3ExprListDelete(db, p->pGroupBy); - tdsqlite3ExprDelete(db, p->pHaving); - tdsqlite3ExprListDelete(db, p->pOrderBy); - tdsqlite3ExprDelete(db, p->pLimit); + sqlite3ExprListDelete(db, p->pEList); + sqlite3SrcListDelete(db, p->pSrc); + sqlite3ExprDelete(db, p->pWhere); + sqlite3ExprListDelete(db, p->pGroupBy); + sqlite3ExprDelete(db, p->pHaving); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pLimit); #ifndef SQLITE_OMIT_WINDOWFUNC if( OK_IF_ALWAYS_TRUE(p->pWinDefn) ){ - tdsqlite3WindowListDelete(db, p->pWinDefn); + sqlite3WindowListDelete(db, p->pWinDefn); } assert( p->pWin==0 ); #endif - if( OK_IF_ALWAYS_TRUE(p->pWith) ) tdsqlite3WithDelete(db, p->pWith); - if( bFree ) tdsqlite3DbFreeNN(db, p); + if( OK_IF_ALWAYS_TRUE(p->pWith) ) sqlite3WithDelete(db, p->pWith); + if( bFree ) sqlite3DbFreeNN(db, p); p = pPrior; bFree = 1; } @@ -131620,7 +131620,7 @@ static void clearSelect(tdsqlite3 *db, Select *p, int bFree){ /* ** Initialize a SelectDest structure. */ -SQLITE_PRIVATE void tdsqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ +SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ pDest->eDest = (u8)eDest; pDest->iSDParm = iParm; pDest->zAffSdst = 0; @@ -131633,7 +131633,7 @@ SQLITE_PRIVATE void tdsqlite3SelectDestInit(SelectDest *pDest, int eDest, int iP ** Allocate a new Select structure and return a pointer to that ** structure. */ -SQLITE_PRIVATE Select *tdsqlite3SelectNew( +SQLITE_PRIVATE Select *sqlite3SelectNew( Parse *pParse, /* Parsing context */ ExprList *pEList, /* which columns to include in the result */ SrcList *pSrc, /* the FROM clause -- which tables to scan */ @@ -131646,14 +131646,14 @@ SQLITE_PRIVATE Select *tdsqlite3SelectNew( ){ Select *pNew; Select standin; - pNew = tdsqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) ); if( pNew==0 ){ assert( pParse->db->mallocFailed ); pNew = &standin; } if( pEList==0 ){ - pEList = tdsqlite3ExprListAppend(pParse, 0, - tdsqlite3Expr(pParse->db,TK_ASTERISK,0)); + pEList = sqlite3ExprListAppend(pParse, 0, + sqlite3Expr(pParse->db,TK_ASTERISK,0)); } pNew->pEList = pEList; pNew->op = TK_SELECT; @@ -131664,7 +131664,7 @@ SQLITE_PRIVATE Select *tdsqlite3SelectNew( pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; - if( pSrc==0 ) pSrc = tdsqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; @@ -131692,7 +131692,7 @@ SQLITE_PRIVATE Select *tdsqlite3SelectNew( /* ** Delete the given Select structure and all of its substructures. */ -SQLITE_PRIVATE void tdsqlite3SelectDelete(tdsqlite3 *db, Select *p){ +SQLITE_PRIVATE void sqlite3SelectDelete(sqlite3 *db, Select *p){ if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1); } @@ -131701,13 +131701,13 @@ SQLITE_PRIVATE void tdsqlite3SelectDelete(tdsqlite3 *db, Select *p){ ** p to be a single SELECT where every column of the result set has a ** value of NULL. */ -SQLITE_PRIVATE void tdsqlite3SelectReset(Parse *pParse, Select *p){ +SQLITE_PRIVATE void sqlite3SelectReset(Parse *pParse, Select *p){ if( ALWAYS(p) ){ clearSelect(pParse->db, p, 0); memset(&p->iLimit, 0, sizeof(Select) - offsetof(Select,iLimit)); - p->pEList = tdsqlite3ExprListAppend(pParse, 0, - tdsqlite3ExprAlloc(pParse->db,TK_NULL,0,0)); - p->pSrc = tdsqlite3DbMallocZero(pParse->db, sizeof(SrcList)); + p->pEList = sqlite3ExprListAppend(pParse, 0, + sqlite3ExprAlloc(pParse->db,TK_NULL,0,0)); + p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(SrcList)); } } @@ -131736,7 +131736,7 @@ static Select *findRightmost(Select *p){ ** If an illegal or unsupported join type is seen, then still return ** a join type, but put an error in the pParse structure. */ -SQLITE_PRIVATE int tdsqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ +SQLITE_PRIVATE int sqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token *pC){ int jointype = 0; Token *apAll[3]; Token *p; @@ -131763,7 +131763,7 @@ SQLITE_PRIVATE int tdsqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token p = apAll[i]; for(j=0; jn==aKeyword[j].nChar - && tdsqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ + && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ jointype |= aKeyword[j].code; break; } @@ -131781,12 +131781,12 @@ SQLITE_PRIVATE int tdsqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token const char *zSp = " "; assert( pB!=0 ); if( pC==0 ){ zSp++; } - tdsqlite3ErrorMsg(pParse, "unknown or unsupported join type: " + sqlite3ErrorMsg(pParse, "unknown or unsupported join type: " "%T %T%s%T", pA, pB, zSp, pC); jointype = JT_INNER; }else if( (jointype & JT_OUTER)!=0 && (jointype & (JT_LEFT|JT_RIGHT))!=JT_LEFT ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "RIGHT and FULL OUTER JOINs are not currently supported"); jointype = JT_INNER; } @@ -131800,7 +131800,7 @@ SQLITE_PRIVATE int tdsqlite3JoinType(Parse *pParse, Token *pA, Token *pB, Token static int columnIndex(Table *pTab, const char *zCol){ int i; for(i=0; inCol; i++){ - if( tdsqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; + if( sqlite3StrICmp(pTab->aCol[i].zName, zCol)==0 ) return i; } return -1; } @@ -131862,7 +131862,7 @@ static void addWhereTerm( int isOuterJoin, /* True if this is an OUTER join */ Expr **ppWhere /* IN/OUT: The WHERE clause to add to */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Expr *pE1; Expr *pE2; Expr *pEq; @@ -131872,17 +131872,17 @@ static void addWhereTerm( assert( pSrc->a[iLeft].pTab ); assert( pSrc->a[iRight].pTab ); - pE1 = tdsqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); - pE2 = tdsqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); + pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft); + pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight); - pEq = tdsqlite3PExpr(pParse, TK_EQ, pE1, pE2); + pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2); if( pEq && isOuterJoin ){ ExprSetProperty(pEq, EP_FromJoin); assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) ); ExprSetVVAProperty(pEq, EP_NoReduce); pEq->iRightJoinTable = (i16)pE2->iTable; } - *ppWhere = tdsqlite3ExprAnd(pParse, *ppWhere, pEq); + *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq); } /* @@ -131911,7 +131911,7 @@ static void addWhereTerm( ** after the t1 loop and rows with t1.x!=5 will never appear in ** the output, which is incorrect. */ -SQLITE_PRIVATE void tdsqlite3SetJoinExpr(Expr *p, int iTable){ +SQLITE_PRIVATE void sqlite3SetJoinExpr(Expr *p, int iTable){ while( p ){ ExprSetProperty(p, EP_FromJoin); assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); @@ -131920,15 +131920,15 @@ SQLITE_PRIVATE void tdsqlite3SetJoinExpr(Expr *p, int iTable){ if( p->op==TK_FUNCTION && p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ - tdsqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable); + sqlite3SetJoinExpr(p->x.pList->a[i].pExpr, iTable); } } - tdsqlite3SetJoinExpr(p->pLeft, iTable); + sqlite3SetJoinExpr(p->pLeft, iTable); p = p->pRight; } } -/* Undo the work of tdsqlite3SetJoinExpr(). In the expression p, convert every +/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every ** term that is marked with EP_FromJoin and iRightJoinTable==iTable into ** an ordinary term that omits the EP_FromJoin mark. ** @@ -131986,7 +131986,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ */ if( pRight->fg.jointype & JT_NATURAL ){ if( pRight->pOn || pRight->pUsing ){ - tdsqlite3ErrorMsg(pParse, "a NATURAL join may not have " + sqlite3ErrorMsg(pParse, "a NATURAL join may not have " "an ON or USING clause", 0); return 1; } @@ -132007,7 +132007,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ /* Disallow both ON and USING clauses in the same join */ if( pRight->pOn && pRight->pUsing ){ - tdsqlite3ErrorMsg(pParse, "cannot have both ON and USING " + sqlite3ErrorMsg(pParse, "cannot have both ON and USING " "clauses in the same join"); return 1; } @@ -132016,8 +132016,8 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ ** an AND operator. */ if( pRight->pOn ){ - if( isOuter ) tdsqlite3SetJoinExpr(pRight->pOn, pRight->iCursor); - p->pWhere = tdsqlite3ExprAnd(pParse, p->pWhere, pRight->pOn); + if( isOuter ) sqlite3SetJoinExpr(pRight->pOn, pRight->iCursor); + p->pWhere = sqlite3ExprAnd(pParse, p->pWhere, pRight->pOn); pRight->pOn = 0; } @@ -132041,7 +132041,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){ if( iRightCol<0 || !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0) ){ - tdsqlite3ErrorMsg(pParse, "cannot join using column %s - column " + sqlite3ErrorMsg(pParse, "cannot join using column %s - column " "not present in both tables", zName); return 1; } @@ -132076,12 +132076,12 @@ static void innerLoopLoadRow( Select *pSelect, /* The query being coded */ RowLoadInfo *pInfo /* Info needed to complete the row load */ ){ - tdsqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult, + sqlite3ExprCodeExprList(pParse, pSelect->pEList, pInfo->regResult, 0, pInfo->ecelFlags); #ifdef SQLITE_ENABLE_SORTER_REFERENCES if( pInfo->pExtra ){ - tdsqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0); - tdsqlite3ExprListDelete(pParse->db, pInfo->pExtra); + sqlite3ExprCodeExprList(pParse, pInfo->pExtra, pInfo->regExtraResult, 0, 0); + sqlite3ExprListDelete(pParse->db, pInfo->pExtra); } #endif } @@ -132105,7 +132105,7 @@ static int makeSorterRecord( if( pSort->pDeferredRowLoad ){ innerLoopLoadRow(pParse, pSelect, pSort->pDeferredRowLoad); } - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase+nOBSat, nBase-nOBSat, regOut); return regOut; } @@ -132159,14 +132159,14 @@ static void pushOntoSorter( } assert( pSelect->iOffset==0 || pSelect->iLimit!=0 ); iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit; - pSort->labelDone = tdsqlite3VdbeMakeLabel(pParse); - tdsqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, + pSort->labelDone = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData, SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0)); if( bSeq ){ - tdsqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); + sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr); } if( nPrefixReg==0 && nData>0 ){ - tdsqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); + sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData); } if( nOBSat>0 ){ int regPrevKey; /* The first nOBSat columns of the previous row */ @@ -132181,35 +132181,35 @@ static void pushOntoSorter( pParse->nMem += pSort->nOBSat; nKey = nExpr - pSort->nOBSat + bSeq; if( bSeq ){ - addrFirst = tdsqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); + addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); }else{ - addrFirst = tdsqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); + addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); } VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); - pOp = tdsqlite3VdbeGetOp(v, pSort->addrSortIndex); + sqlite3VdbeAddOp3(v, OP_Compare, regPrevKey, regBase, pSort->nOBSat); + pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); if( pParse->db->mallocFailed ) return; pOp->p2 = nKey + nData; pKI = pOp->p4.pKeyInfo; memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */ - tdsqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); + sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); testcase( pKI->nAllField > pKI->nKeyField+2 ); - pOp->p4.pKeyInfo = tdsqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, + pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, pKI->nAllField-pKI->nKeyField-1); pOp = 0; /* Ensure pOp not used after sqltie3VdbeAddOp3() */ - addrJmp = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); - pSort->labelBkOut = tdsqlite3VdbeMakeLabel(pParse); + addrJmp = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); + pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); pSort->regReturn = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); - tdsqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor); if( iLimit ){ - tdsqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone); + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone); VdbeCoverage(v); } - tdsqlite3VdbeJumpHere(v, addrFirst); - tdsqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); - tdsqlite3VdbeJumpHere(v, addrJmp); + sqlite3VdbeJumpHere(v, addrFirst); + sqlite3ExprCodeMove(pParse, regBase, regPrevKey, pSort->nOBSat); + sqlite3VdbeJumpHere(v, addrJmp); } if( iLimit ){ /* At this point the values for the new sorter entry are stored @@ -132225,16 +132225,16 @@ static void pushOntoSorter( ** jump to the next iteration of the loop. If the pSort->labelOBLopt ** value is not zero, then it is a label of where to jump. Otherwise, ** just bypass the row insert logic. See the header comment on the - ** tdsqlite3WhereOrderByLimitOptLabel() function for additional info. + ** sqlite3WhereOrderByLimitOptLabel() function for additional info. */ int iCsr = pSort->iECursor; - tdsqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, tdsqlite3VdbeCurrentAddr(v)+4); + sqlite3VdbeAddOp2(v, OP_IfNotZero, iLimit, sqlite3VdbeCurrentAddr(v)+4); VdbeCoverage(v); - tdsqlite3VdbeAddOp2(v, OP_Last, iCsr, 0); - iSkip = tdsqlite3VdbeAddOp4Int(v, OP_IdxLE, + sqlite3VdbeAddOp2(v, OP_Last, iCsr, 0); + iSkip = sqlite3VdbeAddOp4Int(v, OP_IdxLE, iCsr, 0, regBase+nOBSat, nExpr-nOBSat); VdbeCoverage(v); - tdsqlite3VdbeAddOp1(v, OP_Delete, iCsr); + sqlite3VdbeAddOp1(v, OP_Delete, iCsr); } if( regRecord==0 ){ regRecord = makeSorterRecord(pParse, pSort, pSelect, regBase, nBase); @@ -132244,11 +132244,11 @@ static void pushOntoSorter( }else{ op = OP_IdxInsert; } - tdsqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, + sqlite3VdbeAddOp4Int(v, op, pSort->iECursor, regRecord, regBase+nOBSat, nBase-nOBSat); if( iSkip ){ - tdsqlite3VdbeChangeP2(v, iSkip, - pSort->labelOBLopt ? pSort->labelOBLopt : tdsqlite3VdbeCurrentAddr(v)); + sqlite3VdbeChangeP2(v, iSkip, + pSort->labelOBLopt ? pSort->labelOBLopt : sqlite3VdbeCurrentAddr(v)); } } @@ -132261,7 +132261,7 @@ static void codeOffset( int iContinue /* Jump here to skip the current record */ ){ if( iOffset>0 ){ - tdsqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v); VdbeComment((v, "OFFSET")); } } @@ -132286,12 +132286,12 @@ static void codeDistinct( int r1; v = pParse->pVdbe; - r1 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N); - tdsqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - tdsqlite3ReleaseTempReg(pParse, r1); + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4Int(v, OP_Found, iTab, addrRepeat, iMem, N); VdbeCoverage(v); + sqlite3VdbeAddOp3(v, OP_MakeRecord, iMem, N, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r1, iMem, N); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3ReleaseTempReg(pParse, r1); } #ifdef SQLITE_ENABLE_SORTER_REFERENCES @@ -132348,16 +132348,16 @@ static void selectExprDefer( int k; Index *pPk = 0; if( !HasRowid(pTab) ){ - pPk = tdsqlite3PrimaryKeyIndex(pTab); + pPk = sqlite3PrimaryKeyIndex(pTab); nKey = pPk->nKeyCol; } for(k=0; kiTable = pExpr->iTable; pNew->y.pTab = pExpr->y.pTab; pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; - pExtra = tdsqlite3ExprListAppend(pParse, pExtra, pNew); + pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); } } pSort->aDefer[nDefer].pTab = pExpr->y.pTab; @@ -132444,7 +132444,7 @@ static void selectInnerLoop( regOrig = regResult = pDest->iSdst; if( srcTab>=0 ){ for(i=0; ipEList->a[i].zEName)); } }else if( eDest!=SRT_Exists ){ @@ -132484,7 +132484,7 @@ static void selectInnerLoop( ** instruction to account for the larger records. This is only ** required if there are one or more WITHOUT ROWID tables with ** composite primary keys in the SortCtx.aDefer[] array. */ - VdbeOp *pOp = tdsqlite3VdbeGetOp(v, pSort->addrSortIndex); + VdbeOp *pOp = sqlite3VdbeGetOp(v, pSort->addrSortIndex); pOp->p2 += (pExtra->nExpr - pSort->nDefer); pOp->p4.pKeyInfo->nAllField += (pExtra->nExpr - pSort->nDefer); pParse->nMem += pExtra->nExpr; @@ -132554,33 +132554,33 @@ static void selectInnerLoop( ** fail on the first iteration of the loop even if the first ** row is all NULLs. */ - tdsqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); - pOp = tdsqlite3VdbeGetOp(v, pDistinct->addrTnct); + sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); + pOp = sqlite3VdbeGetOp(v, pDistinct->addrTnct); pOp->opcode = OP_Null; pOp->p1 = 1; pOp->p2 = regPrev; - pOp = 0; /* Ensure pOp is not used after tdsqlite3VdbeAddOp() */ + pOp = 0; /* Ensure pOp is not used after sqlite3VdbeAddOp() */ - iJump = tdsqlite3VdbeCurrentAddr(v) + nResultCol; + iJump = sqlite3VdbeCurrentAddr(v) + nResultCol; for(i=0; ipEList->a[i].pExpr); + CollSeq *pColl = sqlite3ExprCollSeq(pParse, p->pEList->a[i].pExpr); if( idb->mallocFailed ); - tdsqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1); + assert( sqlite3VdbeCurrentAddr(v)==iJump || pParse->db->mallocFailed ); + sqlite3VdbeAddOp3(v, OP_Copy, regResult, regPrev, nResultCol-1); break; } case WHERE_DISTINCT_UNIQUE: { - tdsqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); + sqlite3VdbeChangeToNoop(v, pDistinct->addrTnct); break; } @@ -132603,10 +132603,10 @@ static void selectInnerLoop( #ifndef SQLITE_OMIT_COMPOUND_SELECT case SRT_Union: { int r1; - r1 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); - tdsqlite3ReleaseTempReg(pParse, r1); + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + sqlite3ReleaseTempReg(pParse, r1); break; } @@ -132615,7 +132615,7 @@ static void selectInnerLoop( ** the temporary table iParm. */ case SRT_Except: { - tdsqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol); + sqlite3VdbeAddOp3(v, OP_IdxDelete, iParm, regResult, nResultCol); break; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ @@ -132626,12 +132626,12 @@ static void selectInnerLoop( case SRT_DistFifo: case SRT_Table: case SRT_EphemTab: { - int r1 = tdsqlite3GetTempRange(pParse, nPrefixReg+1); + int r1 = sqlite3GetTempRange(pParse, nPrefixReg+1); testcase( eDest==SRT_Table ); testcase( eDest==SRT_EphemTab ); testcase( eDest==SRT_Fifo ); testcase( eDest==SRT_DistFifo ); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); #ifndef SQLITE_OMIT_CTE if( eDest==SRT_DistFifo ){ /* If the destination is DistFifo, then cursor (iParm+1) is open @@ -132639,10 +132639,10 @@ static void selectInnerLoop( ** in the index, do not write it to the output. If not, add the ** current row to the index and proceed with writing it to the ** output table as well. */ - int addr = tdsqlite3VdbeCurrentAddr(v) + 4; - tdsqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); + int addr = sqlite3VdbeCurrentAddr(v) + 4; + sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, addr, r1, 0); VdbeCoverage(v); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm+1, r1,regResult,nResultCol); assert( pSort==0 ); } #endif @@ -132650,13 +132650,13 @@ static void selectInnerLoop( assert( regResult==regOrig ); pushOntoSorter(pParse, pSort, p, r1+nPrefixReg, regOrig, 1, nPrefixReg); }else{ - int r2 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); - tdsqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); - tdsqlite3VdbeChangeP5(v, OPFLAG_APPEND); - tdsqlite3ReleaseTempReg(pParse, r2); + int r2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); } - tdsqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1); + sqlite3ReleaseTempRange(pParse, r1, nPrefixReg+1); break; } @@ -132674,12 +132674,12 @@ static void selectInnerLoop( pushOntoSorter( pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); }else{ - int r1 = tdsqlite3GetTempReg(pParse); - assert( tdsqlite3Strlen30(pDest->zAffSdst)==nResultCol ); - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, + int r1 = sqlite3GetTempReg(pParse); + assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); - tdsqlite3ReleaseTempReg(pParse, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); + sqlite3ReleaseTempReg(pParse, r1); } break; } @@ -132687,7 +132687,7 @@ static void selectInnerLoop( /* If any row exist in the result set, record that fact and abort. */ case SRT_Exists: { - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iParm); /* The LIMIT clause will terminate the loop for us */ break; } @@ -132718,9 +132718,9 @@ static void selectInnerLoop( pushOntoSorter(pParse, pSort, p, regResult, regOrig, nResultCol, nPrefixReg); }else if( eDest==SRT_Coroutine ){ - tdsqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); }else{ - tdsqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); + sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nResultCol); } break; } @@ -132741,33 +132741,33 @@ static void selectInnerLoop( pSO = pDest->pOrderBy; assert( pSO ); nKey = pSO->nExpr; - r1 = tdsqlite3GetTempReg(pParse); - r2 = tdsqlite3GetTempRange(pParse, nKey+2); + r1 = sqlite3GetTempReg(pParse); + r2 = sqlite3GetTempRange(pParse, nKey+2); r3 = r2+nKey+1; if( eDest==SRT_DistQueue ){ /* If the destination is DistQueue, then cursor (iParm+1) is open ** on a second ephemeral index that holds all values every previously ** added to the queue. */ - addrTest = tdsqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, + addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, regResult, nResultCol); VdbeCoverage(v); } - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r3); if( eDest==SRT_DistQueue ){ - tdsqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); - tdsqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm+1, r3); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); } for(i=0; ia[i].u.x.iOrderByCol - 1, r2+i); } - tdsqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); - if( addrTest ) tdsqlite3VdbeJumpHere(v, addrTest); - tdsqlite3ReleaseTempReg(pParse, r1); - tdsqlite3ReleaseTempRange(pParse, r2, nKey+2); + sqlite3VdbeAddOp2(v, OP_Sequence, iParm, r2+nKey); + sqlite3VdbeAddOp3(v, OP_MakeRecord, r2, nKey+2, r1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, r2, nKey+2); + if( addrTest ) sqlite3VdbeJumpHere(v, addrTest); + sqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempRange(pParse, r2, nKey+2); break; } #endif /* SQLITE_OMIT_CTE */ @@ -132792,7 +132792,7 @@ static void selectInnerLoop( ** the output for us. */ if( pSort==0 && p->iLimit ){ - tdsqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); } } @@ -132800,9 +132800,9 @@ static void selectInnerLoop( ** Allocate a KeyInfo object sufficient for an index of N key columns and ** X extra columns. */ -SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoAlloc(tdsqlite3 *db, int N, int X){ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*); - KeyInfo *p = tdsqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); + KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); if( p ){ p->aSortFlags = (u8*)&p->aColl[N+X]; p->nKeyField = (u16)N; @@ -132812,7 +132812,7 @@ SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoAlloc(tdsqlite3 *db, int N, int X){ p->nRef = 1; memset(&p[1], 0, nExtra); }else{ - tdsqlite3OomFault(db); + sqlite3OomFault(db); } return p; } @@ -132820,18 +132820,18 @@ SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoAlloc(tdsqlite3 *db, int N, int X){ /* ** Deallocate a KeyInfo object */ -SQLITE_PRIVATE void tdsqlite3KeyInfoUnref(KeyInfo *p){ +SQLITE_PRIVATE void sqlite3KeyInfoUnref(KeyInfo *p){ if( p ){ assert( p->nRef>0 ); p->nRef--; - if( p->nRef==0 ) tdsqlite3DbFreeNN(p->db, p); + if( p->nRef==0 ) sqlite3DbFreeNN(p->db, p); } } /* ** Make a new pointer to a KeyInfo object */ -SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoRef(KeyInfo *p){ +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoRef(KeyInfo *p){ if( p ){ assert( p->nRef>0 ); p->nRef++; @@ -132846,7 +132846,7 @@ SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoRef(KeyInfo *p){ ** ** This routine is used only inside of assert() statements. */ -SQLITE_PRIVATE int tdsqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } +SQLITE_PRIVATE int sqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } #endif /* SQLITE_DEBUG */ /* @@ -132863,7 +132863,7 @@ SQLITE_PRIVATE int tdsqlite3KeyInfoIsWriteable(KeyInfo *p){ return p->nRef==1; } ** function is responsible for seeing that this structure is eventually ** freed. */ -SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoFromExprList( +SQLITE_PRIVATE KeyInfo *sqlite3KeyInfoFromExprList( Parse *pParse, /* Parsing context */ ExprList *pList, /* Form the KeyInfo object from this ExprList */ int iStart, /* Begin with this column of pList */ @@ -132872,15 +132872,15 @@ SQLITE_PRIVATE KeyInfo *tdsqlite3KeyInfoFromExprList( int nExpr; KeyInfo *pInfo; struct ExprList_item *pItem; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int i; nExpr = pList->nExpr; - pInfo = tdsqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); + pInfo = sqlite3KeyInfoAlloc(db, nExpr-iStart, nExtra+1); if( pInfo ){ - assert( tdsqlite3KeyInfoIsWriteable(pInfo) ); + assert( sqlite3KeyInfoIsWriteable(pInfo) ); for(i=iStart, pItem=pList->a+iStart; iaColl[i-iStart] = tdsqlite3ExprNNCollSeq(pParse, pItem->pExpr); + pInfo->aColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); pInfo->aSortFlags[i-iStart] = pItem->sortFlags; } } @@ -132919,7 +132919,7 @@ static void explainTempTable(Parse *pParse, const char *zUsage){ /* ** Assign expression b to lvalue a. A second, no-op, version of this macro ** is provided when SQLITE_OMIT_EXPLAIN is defined. This allows the code -** in tdsqlite3Select() to assign values to structure member variables that +** in sqlite3Select() to assign values to structure member variables that ** only exist if SQLITE_OMIT_EXPLAIN is not defined without polluting the ** code with #ifndef directives. */ @@ -132947,7 +132947,7 @@ static void generateSortTail( ){ Vdbe *v = pParse->pVdbe; /* The prepared statement */ int addrBreak = pSort->labelDone; /* Jump here to exit loop */ - int addrContinue = tdsqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */ + int addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */ int addr; /* Top of output loop. Jump for Next. */ int addrOnce = 0; int iTab; @@ -132966,17 +132966,17 @@ static void generateSortTail( assert( addrBreak<0 ); if( pSort->labelBkOut ){ - tdsqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); - tdsqlite3VdbeGoto(v, addrBreak); - tdsqlite3VdbeResolveLabel(v, pSort->labelBkOut); + sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut); + sqlite3VdbeGoto(v, addrBreak); + sqlite3VdbeResolveLabel(v, pSort->labelBkOut); } #ifdef SQLITE_ENABLE_SORTER_REFERENCES /* Open any cursors needed for sorter-reference expressions */ for(i=0; inDefer; i++){ Table *pTab = pSort->aDefer[i].pTab; - int iDb = tdsqlite3SchemaToIndex(pParse->db, pTab->pSchema); - tdsqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead); + int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + sqlite3OpenTable(pParse, pSort->aDefer[i].iCsr, iDb, pTab, OP_OpenRead); nRefKey = MAX(nRefKey, pSort->aDefer[i].nKey); } #endif @@ -132986,12 +132986,12 @@ static void generateSortTail( regRowid = 0; regRow = pDest->iSdst; }else{ - regRowid = tdsqlite3GetTempReg(pParse); + regRowid = sqlite3GetTempReg(pParse); if( eDest==SRT_EphemTab || eDest==SRT_Table ){ - regRow = tdsqlite3GetTempReg(pParse); + regRow = sqlite3GetTempReg(pParse); nColumn = 0; }else{ - regRow = tdsqlite3GetTempRange(pParse, nColumn); + regRow = sqlite3GetTempRange(pParse, nColumn); } } nKey = pOrderBy->nExpr - pSort->nOBSat; @@ -132999,18 +132999,18 @@ static void generateSortTail( int regSortOut = ++pParse->nMem; iSortTab = pParse->nTab++; if( pSort->labelBkOut ){ - addrOnce = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } - tdsqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nColumn+nRefKey); - if( addrOnce ) tdsqlite3VdbeJumpHere(v, addrOnce); - addr = 1 + tdsqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); + addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); VdbeCoverage(v); codeOffset(v, p->iOffset, addrContinue); - tdsqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); + sqlite3VdbeAddOp3(v, OP_SorterData, iTab, regSortOut, iSortTab); bSeq = 0; }else{ - addr = 1 + tdsqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); + addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); VdbeCoverage(v); codeOffset(v, p->iOffset, addrContinue); iSortTab = iTab; bSeq = 1; @@ -133024,38 +133024,38 @@ static void generateSortTail( #ifdef SQLITE_ENABLE_SORTER_REFERENCES if( pSort->nDefer ){ int iKey = iCol+1; - int regKey = tdsqlite3GetTempRange(pParse, nRefKey); + int regKey = sqlite3GetTempRange(pParse, nRefKey); for(i=0; inDefer; i++){ int iCsr = pSort->aDefer[i].iCsr; Table *pTab = pSort->aDefer[i].pTab; int nKey = pSort->aDefer[i].nKey; - tdsqlite3VdbeAddOp1(v, OP_NullRow, iCsr); + sqlite3VdbeAddOp1(v, OP_NullRow, iCsr); if( HasRowid(pTab) ){ - tdsqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey); - tdsqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, - tdsqlite3VdbeCurrentAddr(v)+1, regKey); + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, + sqlite3VdbeCurrentAddr(v)+1, regKey); }else{ int k; int iJmp; - assert( tdsqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey ); + assert( sqlite3PrimaryKeyIndex(pTab)->nKeyCol==nKey ); for(k=0; k=0; i--){ #ifdef SQLITE_ENABLE_SORTER_REFERENCES if( aOutEx[i].bSorterRef ){ - tdsqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i); + sqlite3ExprCode(pParse, aOutEx[i].pExpr, regRow+i); }else #endif { @@ -133065,25 +133065,25 @@ static void generateSortTail( }else{ iRead = iCol--; } - tdsqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iRead, regRow+i); VdbeComment((v, "%s", aOutEx[i].zEName)); } } switch( eDest ){ case SRT_Table: case SRT_EphemTab: { - tdsqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow); - tdsqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); - tdsqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); - tdsqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3VdbeAddOp3(v, OP_Column, iSortTab, nKey+bSeq, regRow); + sqlite3VdbeAddOp2(v, OP_NewRowid, iParm, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, iParm, regRow, regRowid); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); break; } #ifndef SQLITE_OMIT_SUBQUERY case SRT_Set: { - assert( nColumn==tdsqlite3Strlen30(pDest->zAffSdst) ); - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, + assert( nColumn==sqlite3Strlen30(pDest->zAffSdst) ); + sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, nColumn, regRowid, pDest->zAffSdst, nColumn); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, regRowid, regRow, nColumn); break; } case SRT_Mem: { @@ -133096,31 +133096,31 @@ static void generateSortTail( testcase( eDest==SRT_Output ); testcase( eDest==SRT_Coroutine ); if( eDest==SRT_Output ){ - tdsqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); + sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); }else{ - tdsqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); } break; } } if( regRowid ){ if( eDest==SRT_Set ){ - tdsqlite3ReleaseTempRange(pParse, regRow, nColumn); + sqlite3ReleaseTempRange(pParse, regRow, nColumn); }else{ - tdsqlite3ReleaseTempReg(pParse, regRow); + sqlite3ReleaseTempReg(pParse, regRow); } - tdsqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regRowid); } /* The bottom of the loop */ - tdsqlite3VdbeResolveLabel(v, addrContinue); + sqlite3VdbeResolveLabel(v, addrContinue); if( pSort->sortFlags & SORTFLAG_UseSorter ){ - tdsqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_SorterNext, iTab, addr); VdbeCoverage(v); }else{ - tdsqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Next, iTab, addr); VdbeCoverage(v); } - if( pSort->regReturn ) tdsqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); - tdsqlite3VdbeResolveLabel(v, addrBreak); + if( pSort->regReturn ) sqlite3VdbeAddOp1(v, OP_Return, pSort->regReturn); + sqlite3VdbeResolveLabel(v, addrBreak); } /* @@ -133243,11 +133243,11 @@ static const char *columnTypeImpl( zOrigCol = "rowid"; }else{ zOrigCol = pTab->aCol[iCol].zName; - zType = tdsqlite3ColumnType(&pTab->aCol[iCol],0); + zType = sqlite3ColumnType(&pTab->aCol[iCol],0); } zOrigTab = pTab->zName; if( pNC->pParse && pTab->pSchema ){ - int iDb = tdsqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); + int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema); zOrigDb = pNC->pParse->db->aDb[iDb].zDbSName; } #else @@ -133255,7 +133255,7 @@ static const char *columnTypeImpl( if( iCol<0 ){ zType = "INTEGER"; }else{ - zType = tdsqlite3ColumnType(&pTab->aCol[iCol],0); + zType = sqlite3ColumnType(&pTab->aCol[iCol],0); } #endif } @@ -133320,13 +133320,13 @@ static void generateColumnTypes( ** column specific strings, in case the schema is reset before this ** virtual machine is deleted. */ - tdsqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT); - tdsqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); - tdsqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_DATABASE, zOrigDb, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_TABLE, zOrigTab, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_COLUMN, zOrigCol, SQLITE_TRANSIENT); #else zType = columnType(&sNC, p, 0, 0, 0); #endif - tdsqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_DECLTYPE, zType, SQLITE_TRANSIENT); } #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ } @@ -133342,7 +133342,7 @@ static void generateColumnTypes( ** and will break if those assumptions changes. Hence, use extreme caution ** when modifying this routine to avoid breaking legacy. ** -** See Also: tdsqlite3ColumnsFromExprList() +** See Also: sqlite3ColumnsFromExprList() ** ** The PRAGMA short_column_names and PRAGMA full_column_names settings are ** deprecated. The default setting is short=ON, full=OFF. 99.9% of all @@ -133371,7 +133371,7 @@ static void generateColumnNames( Table *pTab; SrcList *pTabList; ExprList *pEList; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */ int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */ @@ -133393,7 +133393,7 @@ static void generateColumnNames( pParse->colNamesSet = 1; fullName = (db->flags & SQLITE_FullColNames)!=0; srcName = (db->flags & SQLITE_ShortColNames)!=0 || fullName; - tdsqlite3VdbeSetNumCols(v, pEList->nExpr); + sqlite3VdbeSetNumCols(v, pEList->nExpr); for(i=0; inExpr; i++){ Expr *p = pEList->a[i].pExpr; @@ -133403,7 +133403,7 @@ static void generateColumnNames( if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){ /* An AS clause always takes first priority */ char *zName = pEList->a[i].zEName; - tdsqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); }else if( srcName && p->op==TK_COLUMN ){ char *zCol; int iCol = p->iColumn; @@ -133418,15 +133418,15 @@ static void generateColumnNames( } if( fullName ){ char *zName = 0; - zName = tdsqlite3MPrintf(db, "%s.%s", pTab->zName, zCol); - tdsqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC); + zName = sqlite3MPrintf(db, "%s.%s", pTab->zName, zCol); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_DYNAMIC); }else{ - tdsqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, SQLITE_TRANSIENT); } }else{ const char *z = pEList->a[i].zEName; - z = z==0 ? tdsqlite3MPrintf(db, "column%d", i+1) : tdsqlite3DbStrDup(db, z); - tdsqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC); + z = z==0 ? sqlite3MPrintf(db, "column%d", i+1) : sqlite3DbStrDup(db, z); + sqlite3VdbeSetColName(v, i, COLNAME_NAME, z, SQLITE_DYNAMIC); } } generateColumnTypes(pParse, pTabList, pEList); @@ -133454,13 +133454,13 @@ static void generateColumnNames( ** ** See Also: generateColumnNames() */ -SQLITE_PRIVATE int tdsqlite3ColumnsFromExprList( +SQLITE_PRIVATE int sqlite3ColumnsFromExprList( Parse *pParse, /* Parsing context */ ExprList *pEList, /* Expr list from which to derive column names */ i16 *pnCol, /* Write the number of columns here */ Column **paCol /* Write the new column list here */ ){ - tdsqlite3 *db = pParse->db; /* Database connection */ + sqlite3 *db = pParse->db; /* Database connection */ int i, j; /* Loop counters */ u32 cnt; /* Index added to make the name unique */ Column *aCol, *pCol; /* For looping over result columns */ @@ -133469,10 +133469,10 @@ SQLITE_PRIVATE int tdsqlite3ColumnsFromExprList( int nName; /* Size of name in zName[] */ Hash ht; /* Hash table of column names */ - tdsqlite3HashInit(&ht); + sqlite3HashInit(&ht); if( pEList ){ nCol = pEList->nExpr; - aCol = tdsqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); + aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol); testcase( aCol==0 ); if( nCol>32767 ) nCol = 32767; }else{ @@ -133489,7 +133489,7 @@ SQLITE_PRIVATE int tdsqlite3ColumnsFromExprList( if( (zName = pEList->a[i].zEName)!=0 && pEList->a[i].eEName==ENAME_NAME ){ /* If the column contains an "AS " phrase, use as the name */ }else{ - Expr *pColExpr = tdsqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); + Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); while( pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); @@ -133509,37 +133509,37 @@ SQLITE_PRIVATE int tdsqlite3ColumnsFromExprList( zName = pEList->a[i].zEName; } } - if( zName && !tdsqlite3IsTrueOrFalse(zName) ){ - zName = tdsqlite3DbStrDup(db, zName); + if( zName && !sqlite3IsTrueOrFalse(zName) ){ + zName = sqlite3DbStrDup(db, zName); }else{ - zName = tdsqlite3MPrintf(db,"column%d",i+1); + zName = sqlite3MPrintf(db,"column%d",i+1); } /* Make sure the column name is unique. If the name is not unique, ** append an integer to the name so that it becomes unique. */ cnt = 0; - while( zName && tdsqlite3HashFind(&ht, zName)!=0 ){ - nName = tdsqlite3Strlen30(zName); + while( zName && sqlite3HashFind(&ht, zName)!=0 ){ + nName = sqlite3Strlen30(zName); if( nName>0 ){ - for(j=nName-1; j>0 && tdsqlite3Isdigit(zName[j]); j--){} + for(j=nName-1; j>0 && sqlite3Isdigit(zName[j]); j--){} if( zName[j]==':' ) nName = j; } - zName = tdsqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); - if( cnt>3 ) tdsqlite3_randomness(sizeof(cnt), &cnt); + zName = sqlite3MPrintf(db, "%.*z:%u", nName, zName, ++cnt); + if( cnt>3 ) sqlite3_randomness(sizeof(cnt), &cnt); } pCol->zName = zName; - tdsqlite3ColumnPropertiesFromName(0, pCol); - if( zName && tdsqlite3HashInsert(&ht, zName, pCol)==pCol ){ - tdsqlite3OomFault(db); + sqlite3ColumnPropertiesFromName(0, pCol); + if( zName && sqlite3HashInsert(&ht, zName, pCol)==pCol ){ + sqlite3OomFault(db); } } - tdsqlite3HashClear(&ht); + sqlite3HashClear(&ht); if( db->mallocFailed ){ for(j=0; jdb; + sqlite3 *db = pParse->db; NameContext sNC; Column *pCol; CollSeq *pColl; @@ -133585,20 +133585,20 @@ SQLITE_PRIVATE void tdsqlite3SelectAddColumnTypeAndCollation( p = a[i].pExpr; zType = columnType(&sNC, p, 0, 0, 0); /* pCol->szEst = ... // Column size est for SELECT tables never used */ - pCol->affinity = tdsqlite3ExprAffinity(p); + pCol->affinity = sqlite3ExprAffinity(p); if( zType ){ - m = tdsqlite3Strlen30(zType); - n = tdsqlite3Strlen30(pCol->zName); - pCol->zName = tdsqlite3DbReallocOrFree(db, pCol->zName, n+m+2); + m = sqlite3Strlen30(zType); + n = sqlite3Strlen30(pCol->zName); + pCol->zName = sqlite3DbReallocOrFree(db, pCol->zName, n+m+2); if( pCol->zName ){ memcpy(&pCol->zName[n+1], zType, m+1); pCol->colFlags |= COLFLAG_HASTYPE; } } if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff; - pColl = tdsqlite3ExprCollSeq(pParse, p); + pColl = sqlite3ExprCollSeq(pParse, p); if( pColl && pCol->zColl==0 ){ - pCol->zColl = tdsqlite3DbStrDup(db, pColl->zName); + pCol->zColl = sqlite3DbStrDup(db, pColl->zName); } } pTab->szTabRow = 1; /* Any non-zero value works */ @@ -133608,30 +133608,30 @@ SQLITE_PRIVATE void tdsqlite3SelectAddColumnTypeAndCollation( ** Given a SELECT statement, generate a Table structure that describes ** the result set of that SELECT. */ -SQLITE_PRIVATE Table *tdsqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){ +SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, char aff){ Table *pTab; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; u64 savedFlags; savedFlags = db->flags; db->flags &= ~(u64)SQLITE_FullColNames; db->flags |= SQLITE_ShortColNames; - tdsqlite3SelectPrep(pParse, pSelect, 0); + sqlite3SelectPrep(pParse, pSelect, 0); db->flags = savedFlags; if( pParse->nErr ) return 0; while( pSelect->pPrior ) pSelect = pSelect->pPrior; - pTab = tdsqlite3DbMallocZero(db, sizeof(Table) ); + pTab = sqlite3DbMallocZero(db, sizeof(Table) ); if( pTab==0 ){ return 0; } pTab->nTabRef = 1; pTab->zName = 0; - pTab->nRowLogEst = 200; assert( 200==tdsqlite3LogEst(1048576) ); - tdsqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); - tdsqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff); + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); + sqlite3ColumnsFromExprList(pParse, pSelect->pEList, &pTab->nCol, &pTab->aCol); + sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSelect, aff); pTab->iPKey = -1; if( db->mallocFailed ){ - tdsqlite3DeleteTable(db, pTab); + sqlite3DeleteTable(db, pTab); return 0; } return pTab; @@ -133641,7 +133641,7 @@ SQLITE_PRIVATE Table *tdsqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect, ** Get a VDBE for the given parser context. Create a new one if necessary. ** If an error occurs, return NULL and leave a message in pParse. */ -SQLITE_PRIVATE Vdbe *tdsqlite3GetVdbe(Parse *pParse){ +SQLITE_PRIVATE Vdbe *sqlite3GetVdbe(Parse *pParse){ if( pParse->pVdbe ){ return pParse->pVdbe; } @@ -133650,7 +133650,7 @@ SQLITE_PRIVATE Vdbe *tdsqlite3GetVdbe(Parse *pParse){ ){ pParse->okConstFactor = 1; } - return tdsqlite3VdbeCreate(pParse); + return sqlite3VdbeCreate(pParse); } @@ -133696,30 +133696,30 @@ static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ assert( pLimit->op==TK_LIMIT ); assert( pLimit->pLeft!=0 ); p->iLimit = iLimit = ++pParse->nMem; - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); assert( v!=0 ); - if( tdsqlite3ExprIsInteger(pLimit->pLeft, &n) ){ - tdsqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); + if( sqlite3ExprIsInteger(pLimit->pLeft, &n) ){ + sqlite3VdbeAddOp2(v, OP_Integer, n, iLimit); VdbeComment((v, "LIMIT counter")); if( n==0 ){ - tdsqlite3VdbeGoto(v, iBreak); - }else if( n>=0 && p->nSelectRow>tdsqlite3LogEst((u64)n) ){ - p->nSelectRow = tdsqlite3LogEst((u64)n); + sqlite3VdbeGoto(v, iBreak); + }else if( n>=0 && p->nSelectRow>sqlite3LogEst((u64)n) ){ + p->nSelectRow = sqlite3LogEst((u64)n); p->selFlags |= SF_FixedLimit; } }else{ - tdsqlite3ExprCode(pParse, pLimit->pLeft, iLimit); - tdsqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); + sqlite3ExprCode(pParse, pLimit->pLeft, iLimit); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeCoverage(v); VdbeComment((v, "LIMIT counter")); - tdsqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, iBreak); VdbeCoverage(v); } if( pLimit->pRight ){ p->iOffset = iOffset = ++pParse->nMem; pParse->nMem++; /* Allocate an extra register for limit+offset */ - tdsqlite3ExprCode(pParse, pLimit->pRight, iOffset); - tdsqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); + sqlite3ExprCode(pParse, pLimit->pRight, iOffset); + sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v); VdbeComment((v, "OFFSET counter")); - tdsqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); + sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset); VdbeComment((v, "LIMIT+OFFSET")); } } @@ -133746,7 +133746,7 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ ** have been thrown during name resolution and we would not have gotten ** this far */ if( pRet==0 && ALWAYS(iColpEList->nExpr) ){ - pRet = tdsqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); + pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); } return pRet; } @@ -133763,8 +133763,8 @@ static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ ExprList *pOrderBy = p->pOrderBy; int nOrderBy = p->pOrderBy->nExpr; - tdsqlite3 *db = pParse->db; - KeyInfo *pRet = tdsqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); + sqlite3 *db = pParse->db; + KeyInfo *pRet = sqlite3KeyInfoAlloc(db, nOrderBy+nExtra, 1); if( pRet ){ int i; for(i=0; iflags & EP_Collate ){ - pColl = tdsqlite3ExprCollSeq(pParse, pTerm); + pColl = sqlite3ExprCollSeq(pParse, pTerm); }else{ pColl = multiSelectCollSeq(pParse, p, pItem->u.x.iOrderByCol-1); if( pColl==0 ) pColl = db->pDfltColl; pOrderBy->a[i].pExpr = - tdsqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); + sqlite3ExprAddCollateString(pParse, pTerm, pColl->zName); } - assert( tdsqlite3KeyInfoIsWriteable(pRet) ); + assert( sqlite3KeyInfoIsWriteable(pRet) ); pRet->aColl[i] = pColl; pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags; } @@ -133851,16 +133851,16 @@ static void generateWithRecursiveQuery( #ifndef SQLITE_OMIT_WINDOWFUNC if( p->pWin ){ - tdsqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries"); + sqlite3ErrorMsg(pParse, "cannot use window functions in recursive queries"); return; } #endif /* Obtain authorization to do a recursive query */ - if( tdsqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; + if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return; /* Process the LIMIT and OFFSET clauses, if they exist */ - addrBreak = tdsqlite3VdbeMakeLabel(pParse); + addrBreak = sqlite3VdbeMakeLabel(pParse); p->nSelectRow = 320; /* 4 billion rows */ computeLimitRegisters(pParse, p, addrBreak); pLimit = p->pLimit; @@ -133888,22 +133888,22 @@ static void generateWithRecursiveQuery( }else{ eDest = pOrderBy ? SRT_Queue : SRT_Fifo; } - tdsqlite3SelectDestInit(&destQueue, eDest, iQueue); + sqlite3SelectDestInit(&destQueue, eDest, iQueue); /* Allocate cursors for Current, Queue, and Distinct. */ regCurrent = ++pParse->nMem; - tdsqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iCurrent, regCurrent, nCol); if( pOrderBy ){ KeyInfo *pKeyInfo = multiSelectOrderByKeyInfo(pParse, p, 1); - tdsqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, iQueue, pOrderBy->nExpr+2, 0, (char*)pKeyInfo, P4_KEYINFO); destQueue.pOrderBy = pOrderBy; }else{ - tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iQueue, nCol); } VdbeComment((v, "Queue table")); if( iDistinct ){ - p->addrOpenEphm[0] = tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); + p->addrOpenEphm[0] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iDistinct, 0); p->selFlags |= SF_UsesEphemeral; } @@ -133913,52 +133913,52 @@ static void generateWithRecursiveQuery( /* Store the results of the setup-query in Queue. */ pSetup->pNext = 0; ExplainQueryPlan((pParse, 1, "SETUP")); - rc = tdsqlite3Select(pParse, pSetup, &destQueue); + rc = sqlite3Select(pParse, pSetup, &destQueue); pSetup->pNext = p; if( rc ) goto end_of_recursive_query; /* Find the next row in the Queue and output that row */ - addrTop = tdsqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v); + addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iQueue, addrBreak); VdbeCoverage(v); /* Transfer the next row in Queue over to Current */ - tdsqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ + sqlite3VdbeAddOp1(v, OP_NullRow, iCurrent); /* To reset column cache */ if( pOrderBy ){ - tdsqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent); + sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent); }else{ - tdsqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); + sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent); } - tdsqlite3VdbeAddOp1(v, OP_Delete, iQueue); + sqlite3VdbeAddOp1(v, OP_Delete, iQueue); /* Output the single row in Current */ - addrCont = tdsqlite3VdbeMakeLabel(pParse); + addrCont = sqlite3VdbeMakeLabel(pParse); codeOffset(v, regOffset, addrCont); selectInnerLoop(pParse, p, iCurrent, 0, 0, pDest, addrCont, addrBreak); if( regLimit ){ - tdsqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak); VdbeCoverage(v); } - tdsqlite3VdbeResolveLabel(v, addrCont); + sqlite3VdbeResolveLabel(v, addrCont); /* Execute the recursive SELECT taking the single row in Current as ** the value for the recursive-table. Store the results in the Queue. */ if( p->selFlags & SF_Aggregate ){ - tdsqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); + sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported"); }else{ p->pPrior = 0; ExplainQueryPlan((pParse, 1, "RECURSIVE STEP")); - tdsqlite3Select(pParse, p, &destQueue); + sqlite3Select(pParse, p, &destQueue); assert( p->pPrior==0 ); p->pPrior = pSetup; } /* Keep running the loop until the Queue is empty */ - tdsqlite3VdbeGoto(v, addrTop); - tdsqlite3VdbeResolveLabel(v, addrBreak); + sqlite3VdbeGoto(v, addrTop); + sqlite3VdbeResolveLabel(v, addrBreak); end_of_recursive_query: - tdsqlite3ExprListDelete(pParse->db, p->pOrderBy); + sqlite3ExprListDelete(pParse->db, p->pOrderBy); p->pOrderBy = pOrderBy; p->pLimit = pLimit; return; @@ -133985,7 +133985,7 @@ static int multiSelectOrderBy( ** ** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES ** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))"). -** The tdsqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. +** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case. ** Since the limit is exactly 1, we only need to evalutes the left-most VALUES. */ static int multiSelectValues( @@ -134061,7 +134061,7 @@ static int multiSelect( Vdbe *v; /* Generate code to this VDBE */ SelectDest dest; /* Alternative data destination */ Select *pDelete = 0; /* Chain of simple selects to delete */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. @@ -134073,20 +134073,20 @@ static int multiSelect( pPrior = p->pPrior; dest = *pDest; if( pPrior->pOrderBy || pPrior->pLimit ){ - tdsqlite3ErrorMsg(pParse,"%s clause should come after %s not before", + sqlite3ErrorMsg(pParse,"%s clause should come after %s not before", pPrior->pOrderBy!=0 ? "ORDER BY" : "LIMIT", selectOpName(p->op)); rc = 1; goto multi_select_end; } - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); assert( v!=0 ); /* The VDBE already created by calling function */ /* Create the destination temporary table if necessary */ if( dest.eDest==SRT_EphemTab ){ assert( p->pEList ); - tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); dest.eDest = SRT_Table; } @@ -134133,7 +134133,7 @@ static int multiSelect( pPrior->iLimit = p->iLimit; pPrior->iOffset = p->iOffset; pPrior->pLimit = p->pLimit; - rc = tdsqlite3Select(pParse, pPrior, &dest); + rc = sqlite3Select(pParse, pPrior, &dest); p->pLimit = 0; if( rc ){ goto multi_select_end; @@ -134142,27 +134142,27 @@ static int multiSelect( p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit ){ - addr = tdsqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); + addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v); VdbeComment((v, "Jump ahead if LIMIT reached")); if( p->iOffset ){ - tdsqlite3VdbeAddOp3(v, OP_OffsetLimit, + sqlite3VdbeAddOp3(v, OP_OffsetLimit, p->iLimit, p->iOffset+1, p->iOffset); } } ExplainQueryPlan((pParse, 1, "UNION ALL")); - rc = tdsqlite3Select(pParse, p, &dest); + rc = sqlite3Select(pParse, p, &dest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; - p->nSelectRow = tdsqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); if( pPrior->pLimit - && tdsqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit) - && nLimit>0 && p->nSelectRow > tdsqlite3LogEst((u64)nLimit) + && sqlite3ExprIsInteger(pPrior->pLimit->pLeft, &nLimit) + && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ - p->nSelectRow = tdsqlite3LogEst((u64)nLimit); + p->nSelectRow = sqlite3LogEst((u64)nLimit); } if( addr ){ - tdsqlite3VdbeJumpHere(v, addr); + sqlite3VdbeJumpHere(v, addr); } break; } @@ -134190,7 +134190,7 @@ static int multiSelect( */ unionTab = pParse->nTab++; assert( p->pOrderBy==0 ); - addr = tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); assert( p->addrOpenEphm[0] == -1 ); p->addrOpenEphm[0] = addr; findRightmost(p)->selFlags |= SF_UsesEphemeral; @@ -134200,8 +134200,8 @@ static int multiSelect( /* Code the SELECT statements to our left */ assert( !pPrior->pOrderBy ); - tdsqlite3SelectDestInit(&uniondest, priorOp, unionTab); - rc = tdsqlite3Select(pParse, pPrior, &uniondest); + sqlite3SelectDestInit(&uniondest, priorOp, unionTab); + rc = sqlite3Select(pParse, pPrior, &uniondest); if( rc ){ goto multi_select_end; } @@ -134220,18 +134220,18 @@ static int multiSelect( uniondest.eDest = op; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", selectOpName(p->op))); - rc = tdsqlite3Select(pParse, p, &uniondest); + rc = sqlite3Select(pParse, p, &uniondest); testcase( rc!=SQLITE_OK ); - /* Query flattening in tdsqlite3Select() might refill p->pOrderBy. + /* Query flattening in sqlite3Select() might refill p->pOrderBy. ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */ - tdsqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprListDelete(db, p->pOrderBy); pDelete = p->pPrior; p->pPrior = pPrior; p->pOrderBy = 0; if( p->op==TK_UNION ){ - p->nSelectRow = tdsqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); } - tdsqlite3ExprDelete(db, p->pLimit); + sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; p->iLimit = 0; p->iOffset = 0; @@ -134243,17 +134243,17 @@ static int multiSelect( assert( p->pEList || db->mallocFailed ); if( dest.eDest!=priorOp && db->mallocFailed==0 ){ int iCont, iBreak, iStart; - iBreak = tdsqlite3VdbeMakeLabel(pParse); - iCont = tdsqlite3VdbeMakeLabel(pParse); + iBreak = sqlite3VdbeMakeLabel(pParse); + iCont = sqlite3VdbeMakeLabel(pParse); computeLimitRegisters(pParse, p, iBreak); - tdsqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); - iStart = tdsqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v); + iStart = sqlite3VdbeCurrentAddr(v); selectInnerLoop(pParse, p, unionTab, 0, 0, &dest, iCont, iBreak); - tdsqlite3VdbeResolveLabel(v, iCont); - tdsqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); - tdsqlite3VdbeResolveLabel(v, iBreak); - tdsqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, unionTab, 0); } break; } @@ -134273,7 +134273,7 @@ static int multiSelect( tab2 = pParse->nTab++; assert( p->pOrderBy==0 ); - addr = tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); assert( p->addrOpenEphm[0] == -1 ); p->addrOpenEphm[0] = addr; findRightmost(p)->selFlags |= SF_UsesEphemeral; @@ -134281,15 +134281,15 @@ static int multiSelect( /* Code the SELECTs to our left into temporary table "tab1". */ - tdsqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); - rc = tdsqlite3Select(pParse, pPrior, &intersectdest); + sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); + rc = sqlite3Select(pParse, pPrior, &intersectdest); if( rc ){ goto multi_select_end; } /* Code the current SELECT into temporary table "tab2" */ - addr = tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); assert( p->addrOpenEphm[1] == -1 ); p->addrOpenEphm[1] = addr; p->pPrior = 0; @@ -134298,36 +134298,36 @@ static int multiSelect( intersectdest.iSDParm = tab2; ExplainQueryPlan((pParse, 1, "%s USING TEMP B-TREE", selectOpName(p->op))); - rc = tdsqlite3Select(pParse, p, &intersectdest); + rc = sqlite3Select(pParse, p, &intersectdest); testcase( rc!=SQLITE_OK ); pDelete = p->pPrior; p->pPrior = pPrior; if( p->nSelectRow>pPrior->nSelectRow ){ p->nSelectRow = pPrior->nSelectRow; } - tdsqlite3ExprDelete(db, p->pLimit); + sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; /* Generate code to take the intersection of the two temporary ** tables. */ assert( p->pEList ); - iBreak = tdsqlite3VdbeMakeLabel(pParse); - iCont = tdsqlite3VdbeMakeLabel(pParse); + iBreak = sqlite3VdbeMakeLabel(pParse); + iCont = sqlite3VdbeMakeLabel(pParse); computeLimitRegisters(pParse, p, iBreak); - tdsqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); - r1 = tdsqlite3GetTempReg(pParse); - iStart = tdsqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); - tdsqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); + sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v); + r1 = sqlite3GetTempReg(pParse); + iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1); + sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0); VdbeCoverage(v); - tdsqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r1); selectInnerLoop(pParse, p, tab1, 0, 0, &dest, iCont, iBreak); - tdsqlite3VdbeResolveLabel(v, iCont); - tdsqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); - tdsqlite3VdbeResolveLabel(v, iBreak); - tdsqlite3VdbeAddOp2(v, OP_Close, tab2, 0); - tdsqlite3VdbeAddOp2(v, OP_Close, tab1, 0); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart); VdbeCoverage(v); + sqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeAddOp2(v, OP_Close, tab2, 0); + sqlite3VdbeAddOp2(v, OP_Close, tab1, 0); break; } } @@ -134358,7 +134358,7 @@ static int multiSelect( assert( p->pNext==0 ); nCol = p->pEList->nExpr; - pKeyInfo = tdsqlite3KeyInfoAlloc(db, nCol, 1); + pKeyInfo = sqlite3KeyInfoAlloc(db, nCol, 1); if( !pKeyInfo ){ rc = SQLITE_NOMEM_BKPT; goto multi_select_end; @@ -134379,19 +134379,19 @@ static int multiSelect( assert( pLoop->addrOpenEphm[1]<0 ); break; } - tdsqlite3VdbeChangeP2(v, addr, nCol); - tdsqlite3VdbeChangeP4(v, addr, (char*)tdsqlite3KeyInfoRef(pKeyInfo), + sqlite3VdbeChangeP2(v, addr, nCol); + sqlite3VdbeChangeP4(v, addr, (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); pLoop->addrOpenEphm[i] = -1; } } - tdsqlite3KeyInfoUnref(pKeyInfo); + sqlite3KeyInfoUnref(pKeyInfo); } multi_select_end: pDest->iSdst = dest.iSdst; pDest->nSdst = dest.nSdst; - tdsqlite3SelectDelete(db, pDelete); + sqlite3SelectDelete(db, pDelete); return rc; } #endif /* SQLITE_OMIT_COMPOUND_SELECT */ @@ -134400,11 +134400,11 @@ multi_select_end: ** Error message for when two or more terms of a compound select have different ** size result sets. */ -SQLITE_PRIVATE void tdsqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ +SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p){ if( p->selFlags & SF_Values ){ - tdsqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); + sqlite3ErrorMsg(pParse, "all VALUES must have the same number of terms"); }else{ - tdsqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" + sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s" " do not have the same number of result columns", selectOpName(p->op)); } } @@ -134443,20 +134443,20 @@ static int generateOutputSubroutine( int iContinue; int addr; - addr = tdsqlite3VdbeCurrentAddr(v); - iContinue = tdsqlite3VdbeMakeLabel(pParse); + addr = sqlite3VdbeCurrentAddr(v); + iContinue = sqlite3VdbeMakeLabel(pParse); /* Suppress duplicates for UNION, EXCEPT, and INTERSECT */ if( regPrev ){ int addr1, addr2; - addr1 = tdsqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v); - addr2 = tdsqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, - (char*)tdsqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); - tdsqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addr1); - tdsqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); + addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v); + addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, + (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); } if( pParse->db->mallocFailed ) return 0; @@ -134470,14 +134470,14 @@ static int generateOutputSubroutine( /* Store the result as data using a unique key. */ case SRT_EphemTab: { - int r1 = tdsqlite3GetTempReg(pParse); - int r2 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); - tdsqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); - tdsqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); - tdsqlite3VdbeChangeP5(v, OPFLAG_APPEND); - tdsqlite3ReleaseTempReg(pParse, r2); - tdsqlite3ReleaseTempReg(pParse, r1); + int r1 = sqlite3GetTempReg(pParse); + int r2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); + sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); + sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); + sqlite3ReleaseTempReg(pParse, r2); + sqlite3ReleaseTempReg(pParse, r1); break; } @@ -134487,12 +134487,12 @@ static int generateOutputSubroutine( case SRT_Set: { int r1; testcase( pIn->nSdst>1 ); - r1 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, + r1 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); - tdsqlite3ReleaseTempReg(pParse, r1); + sqlite3ReleaseTempReg(pParse, r1); break; } @@ -134504,7 +134504,7 @@ static int generateOutputSubroutine( case SRT_Mem: { if( pParse->nErr==0 ){ testcase( pIn->nSdst>1 ); - tdsqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, pIn->nSdst); } /* The LIMIT clause will jump out of the loop for us */ break; @@ -134516,11 +134516,11 @@ static int generateOutputSubroutine( */ case SRT_Coroutine: { if( pDest->iSdst==0 ){ - pDest->iSdst = tdsqlite3GetTempRange(pParse, pIn->nSdst); + pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); pDest->nSdst = pIn->nSdst; } - tdsqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst); - tdsqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pIn->nSdst); + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); break; } @@ -134529,12 +134529,12 @@ static int generateOutputSubroutine( ** destination other than the ones handled above or SRT_Output. ** ** For SRT_Output, results are stored in a sequence of registers. - ** Then the OP_ResultRow opcode is used to cause tdsqlite3_step() to + ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to ** return the next row of result. */ default: { assert( pDest->eDest==SRT_Output ); - tdsqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); + sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); break; } } @@ -134542,13 +134542,13 @@ static int generateOutputSubroutine( /* Jump to the end of the loop if the LIMIT is reached. */ if( p->iLimit ){ - tdsqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, p->iLimit, iBreak); VdbeCoverage(v); } /* Generate the subroutine return */ - tdsqlite3VdbeResolveLabel(v, iContinue); - tdsqlite3VdbeAddOp1(v, OP_Return, regReturn); + sqlite3VdbeResolveLabel(v, iContinue); + sqlite3VdbeAddOp1(v, OP_Return, regReturn); return addr; } @@ -134674,7 +134674,7 @@ static int multiSelectOrderBy( int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ KeyInfo *pKeyMerge; /* Comparison information for merging rows */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ ExprList *pOrderBy; /* The ORDER BY clause */ int nOrderBy; /* Number of terms in the ORDER BY clause */ int *aPermute; /* Mapping from ORDER BY terms to result set columns */ @@ -134684,8 +134684,8 @@ static int multiSelectOrderBy( db = pParse->db; v = pParse->pVdbe; assert( v!=0 ); /* Already thrown the error if VDBE alloc failed */ - labelEnd = tdsqlite3VdbeMakeLabel(pParse); - labelCmpr = tdsqlite3VdbeMakeLabel(pParse); + labelEnd = sqlite3VdbeMakeLabel(pParse); + labelCmpr = sqlite3VdbeMakeLabel(pParse); /* Patch up the ORDER BY clause @@ -134709,11 +134709,11 @@ static int multiSelectOrderBy( if( pItem->u.x.iOrderByCol==i ) break; } if( j==nOrderBy ){ - Expr *pNew = tdsqlite3Expr(db, TK_INTEGER, 0); + Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0); if( pNew==0 ) return SQLITE_NOMEM_BKPT; pNew->flags |= EP_IntValue; pNew->u.iValue = i; - p->pOrderBy = pOrderBy = tdsqlite3ExprListAppend(pParse, pOrderBy, pNew); + p->pOrderBy = pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew); if( pOrderBy ) pOrderBy->a[nOrderBy++].u.x.iOrderByCol = (u16)i; } } @@ -134726,7 +134726,7 @@ static int multiSelectOrderBy( ** to the right and the left are evaluated, they use the correct ** collation. */ - aPermute = tdsqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1)); + aPermute = sqlite3DbMallocRawNN(db, sizeof(int)*(nOrderBy + 1)); if( aPermute ){ struct ExprList_item *pItem; aPermute[0] = nOrderBy; @@ -134743,7 +134743,7 @@ static int multiSelectOrderBy( /* Reattach the ORDER BY clause to the query. */ p->pOrderBy = pOrderBy; - pPrior->pOrderBy = tdsqlite3ExprListDup(pParse->db, pOrderBy, 0); + pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy, 0); /* Allocate a range of temporary registers and the KeyInfo needed ** for the logic that removes duplicate result rows when the @@ -134756,10 +134756,10 @@ static int multiSelectOrderBy( assert( nOrderBy>=nExpr || db->mallocFailed ); regPrev = pParse->nMem+1; pParse->nMem += nExpr+1; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); - pKeyDup = tdsqlite3KeyInfoAlloc(db, nExpr, 1); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev); + pKeyDup = sqlite3KeyInfoAlloc(db, nExpr, 1); if( pKeyDup ){ - assert( tdsqlite3KeyInfoIsWriteable(pKeyDup) ); + assert( sqlite3KeyInfoIsWriteable(pKeyDup) ); for(i=0; iaColl[i] = multiSelectCollSeq(pParse, p, i); pKeyDup->aSortFlags[i] = 0; @@ -134771,9 +134771,9 @@ static int multiSelectOrderBy( */ p->pPrior = 0; pPrior->pNext = 0; - tdsqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); + sqlite3ResolveOrderGroupBy(pParse, p, p->pOrderBy, "ORDER"); if( pPrior->pPrior==0 ){ - tdsqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); + sqlite3ResolveOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, "ORDER"); } /* Compute the limit registers */ @@ -134781,51 +134781,51 @@ static int multiSelectOrderBy( if( p->iLimit && op==TK_ALL ){ regLimitA = ++pParse->nMem; regLimitB = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, + sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit, regLimitA); - tdsqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB); + sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB); }else{ regLimitA = regLimitB = 0; } - tdsqlite3ExprDelete(db, p->pLimit); + sqlite3ExprDelete(db, p->pLimit); p->pLimit = 0; regAddrA = ++pParse->nMem; regAddrB = ++pParse->nMem; regOutA = ++pParse->nMem; regOutB = ++pParse->nMem; - tdsqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); - tdsqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); + sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA); + sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB); ExplainQueryPlan((pParse, 1, "MERGE (%s)", selectOpName(p->op))); /* Generate a coroutine to evaluate the SELECT statement to the ** left of the compound operator - the "A" select. */ - addrSelectA = tdsqlite3VdbeCurrentAddr(v) + 1; - addr1 = tdsqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); + addrSelectA = sqlite3VdbeCurrentAddr(v) + 1; + addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA); VdbeComment((v, "left SELECT")); pPrior->iLimit = regLimitA; ExplainQueryPlan((pParse, 1, "LEFT")); - tdsqlite3Select(pParse, pPrior, &destA); - tdsqlite3VdbeEndCoroutine(v, regAddrA); - tdsqlite3VdbeJumpHere(v, addr1); + sqlite3Select(pParse, pPrior, &destA); + sqlite3VdbeEndCoroutine(v, regAddrA); + sqlite3VdbeJumpHere(v, addr1); /* Generate a coroutine to evaluate the SELECT statement on ** the right - the "B" select */ - addrSelectB = tdsqlite3VdbeCurrentAddr(v) + 1; - addr1 = tdsqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); + addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; + addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB); VdbeComment((v, "right SELECT")); savedLimit = p->iLimit; savedOffset = p->iOffset; p->iLimit = regLimitB; p->iOffset = 0; ExplainQueryPlan((pParse, 1, "RIGHT")); - tdsqlite3Select(pParse, p, &destB); + sqlite3Select(pParse, p, &destB); p->iLimit = savedLimit; p->iOffset = savedOffset; - tdsqlite3VdbeEndCoroutine(v, regAddrB); + sqlite3VdbeEndCoroutine(v, regAddrB); /* Generate a subroutine that outputs the current row of the A ** select as the next output row of the compound select. @@ -134844,7 +134844,7 @@ static int multiSelectOrderBy( p, &destB, pDest, regOutB, regPrev, pKeyDup, labelEnd); } - tdsqlite3KeyInfoUnref(pKeyDup); + sqlite3KeyInfoUnref(pKeyDup); /* Generate a subroutine to run when the results from select A ** are exhausted and only data in select B remains. @@ -134853,11 +134853,11 @@ static int multiSelectOrderBy( addrEofA_noB = addrEofA = labelEnd; }else{ VdbeNoopComment((v, "eof-A subroutine")); - addrEofA = tdsqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); - addrEofA_noB = tdsqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); + addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); VdbeCoverage(v); - tdsqlite3VdbeGoto(v, addrEofA); - p->nSelectRow = tdsqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); + sqlite3VdbeGoto(v, addrEofA); + p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); } /* Generate a subroutine to run when the results from select B @@ -134868,17 +134868,17 @@ static int multiSelectOrderBy( if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; }else{ VdbeNoopComment((v, "eof-B subroutine")); - addrEofB = tdsqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); - tdsqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); - tdsqlite3VdbeGoto(v, addrEofB); + addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); + sqlite3VdbeGoto(v, addrEofB); } /* Generate code to handle the case of AB */ VdbeNoopComment((v, "A-gt-B subroutine")); - addrAgtB = tdsqlite3VdbeCurrentAddr(v); + addrAgtB = sqlite3VdbeCurrentAddr(v); if( op==TK_ALL || op==TK_UNION ){ - tdsqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); } - tdsqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); - tdsqlite3VdbeGoto(v, labelCmpr); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + sqlite3VdbeGoto(v, labelCmpr); /* This code runs once to initialize everything. */ - tdsqlite3VdbeJumpHere(v, addr1); - tdsqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); - tdsqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v); /* Implement the main merge loop */ - tdsqlite3VdbeResolveLabel(v, labelCmpr); - tdsqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); - tdsqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, + sqlite3VdbeResolveLabel(v, labelCmpr); + sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); + sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, (char*)pKeyMerge, P4_KEYINFO); - tdsqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); - tdsqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, OPFLAG_PERMUTE); + sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); VdbeCoverage(v); /* Jump to the this point in order to terminate the query. */ - tdsqlite3VdbeResolveLabel(v, labelEnd); + sqlite3VdbeResolveLabel(v, labelEnd); /* Reassembly the compound query so that it will be freed correctly ** by the calling function */ if( p->pPrior ){ - tdsqlite3SelectDelete(db, p->pPrior); + sqlite3SelectDelete(db, p->pPrior); } p->pPrior = pPrior; pPrior->pNext = p; @@ -134990,10 +134990,10 @@ static Expr *substExpr( Expr ifNullRow; assert( pSubst->pEList!=0 && pExpr->iColumnpEList->nExpr ); assert( pExpr->pRight==0 ); - if( tdsqlite3ExprIsVector(pCopy) ){ - tdsqlite3VectorErrorMsg(pSubst->pParse, pCopy); + if( sqlite3ExprIsVector(pCopy) ){ + sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ - tdsqlite3 *db = pSubst->pParse->db; + sqlite3 *db = pSubst->pParse->db; if( pSubst->isLeftJoin && pCopy->op!=TK_COLUMN ){ memset(&ifNullRow, 0, sizeof(ifNullRow)); ifNullRow.op = TK_IF_NULL_ROW; @@ -135002,7 +135002,7 @@ static Expr *substExpr( pCopy = &ifNullRow; } testcase( ExprHasProperty(pCopy, EP_Subquery) ); - pNew = tdsqlite3ExprDup(db, pCopy, 0); + pNew = sqlite3ExprDup(db, pCopy, 0); if( pNew && pSubst->isLeftJoin ){ ExprSetProperty(pNew, EP_CanBeNull); } @@ -135010,15 +135010,15 @@ static Expr *substExpr( pNew->iRightJoinTable = pExpr->iRightJoinTable; ExprSetProperty(pNew, EP_FromJoin); } - tdsqlite3ExprDelete(db, pExpr); + sqlite3ExprDelete(db, pExpr); pExpr = pNew; /* Ensure that the expression now has an implicit collation sequence, ** just as it did when it was a column of a view or sub-query. */ if( pExpr ){ if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ - CollSeq *pColl = tdsqlite3ExprCollSeq(pSubst->pParse, pExpr); - pExpr = tdsqlite3ExprAddCollateString(pSubst->pParse, pExpr, + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, (pColl ? pColl->zName : "BINARY") ); } @@ -135259,7 +135259,7 @@ static int flattenSubquery( int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ struct SrcList_item *pSubitem; /* The subquery */ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; /* Check to see if flattening is permitted. Return 0 if not. */ @@ -135398,7 +135398,7 @@ static int flattenSubquery( /* Authorize the subquery */ pParse->zAuthContext = pSubitem->zName; - TESTONLY(i =) tdsqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); + TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0); testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; @@ -135444,7 +135444,7 @@ static int flattenSubquery( p->pSrc = 0; p->pPrior = 0; p->pLimit = 0; - pNew = tdsqlite3SelectDup(db, p, 0); + pNew = sqlite3SelectDup(db, p, 0); p->pLimit = pLimit; p->pOrderBy = pOrderBy; p->pSrc = pSrc; @@ -135470,9 +135470,9 @@ static int flattenSubquery( /* Delete the transient table structure associated with the ** subquery */ - tdsqlite3DbFree(db, pSubitem->zDatabase); - tdsqlite3DbFree(db, pSubitem->zName); - tdsqlite3DbFree(db, pSubitem->zAlias); + sqlite3DbFree(db, pSubitem->zDatabase); + sqlite3DbFree(db, pSubitem->zName); + sqlite3DbFree(db, pSubitem->zAlias); pSubitem->zDatabase = 0; pSubitem->zName = 0; pSubitem->zAlias = 0; @@ -135488,7 +135488,7 @@ static int flattenSubquery( if( ALWAYS(pSubitem->pTab!=0) ){ Table *pTabToDel = pSubitem->pTab; if( pTabToDel->nTabRef==1 ){ - Parse *pToplevel = tdsqlite3ParseToplevel(pParse); + Parse *pToplevel = sqlite3ParseToplevel(pParse); pTabToDel->pNextZombie = pToplevel->pZombieTab; pToplevel->pZombieTab = pTabToDel; }else{ @@ -135523,7 +135523,7 @@ static int flattenSubquery( jointype = pSubitem->fg.jointype; }else{ assert( pParent!=p ); /* 2nd and subsequent times through the loop */ - pSrc = tdsqlite3SrcListAppend(pParse, 0, 0, 0); + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc==0 ) break; pParent->pSrc = pSrc; } @@ -135544,7 +135544,7 @@ static int flattenSubquery( ** for the two elements in the FROM clause of the subquery. */ if( nSubSrc>1 ){ - pSrc = tdsqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1); + pSrc = sqlite3SrcListEnlarge(pParse, pSrc, nSubSrc-1,iFrom+1); if( pSrc==0 ) break; pParent->pSrc = pSrc; } @@ -135553,7 +135553,7 @@ static int flattenSubquery( ** outer query. */ for(i=0; ia[i+iFrom].pUsing); + sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing); assert( pSrc->a[i+iFrom].fg.isTabFunc==0 ); pSrc->a[i+iFrom] = pSubSrc->a[i]; iNewParent = pSubSrc->a[i].iCursor; @@ -135595,9 +135595,9 @@ static int flattenSubquery( pWhere = pSub->pWhere; pSub->pWhere = 0; if( isLeftJoin>0 ){ - tdsqlite3SetJoinExpr(pWhere, iNewParent); + sqlite3SetJoinExpr(pWhere, iNewParent); } - pParent->pWhere = tdsqlite3ExprAnd(pParse, pWhere, pParent->pWhere); + pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere); if( db->mallocFailed==0 ){ SubstContext x; x.pParse = pParse; @@ -135628,12 +135628,12 @@ static int flattenSubquery( /* Finially, delete what is left of the subquery and return ** success. */ - tdsqlite3SelectDelete(db, pSub1); + sqlite3SelectDelete(db, pSub1); #if SELECTTRACE_ENABLED - if( tdsqlite3SelectTrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After flattening:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif @@ -135669,12 +135669,12 @@ static void constInsert( ){ int i; assert( pColumn->op==TK_COLUMN ); - assert( tdsqlite3ExprIsConstant(pValue) ); + assert( sqlite3ExprIsConstant(pValue) ); - if( !ExprHasProperty(pValue, EP_FixedCol) && tdsqlite3ExprAffinity(pValue)!=0 ){ + if( !ExprHasProperty(pValue, EP_FixedCol) && sqlite3ExprAffinity(pValue)!=0 ){ return; } - if( !tdsqlite3IsBinary(tdsqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){ return; } @@ -135691,7 +135691,7 @@ static void constInsert( } pConst->nConst++; - pConst->apExpr = tdsqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, + pConst->apExpr = sqlite3DbReallocOrFree(pConst->pParse->db, pConst->apExpr, pConst->nConst*2*sizeof(Expr*)); if( pConst->apExpr==0 ){ pConst->nConst = 0; @@ -135724,10 +135724,10 @@ static void findConstInWhere(WhereConst *pConst, Expr *pExpr){ pLeft = pExpr->pLeft; assert( pRight!=0 ); assert( pLeft!=0 ); - if( pRight->op==TK_COLUMN && tdsqlite3ExprIsConstant(pLeft) ){ + if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){ constInsert(pConst,pRight,pLeft,pExpr); } - if( pLeft->op==TK_COLUMN && tdsqlite3ExprIsConstant(pRight) ){ + if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){ constInsert(pConst,pLeft,pRight,pExpr); } } @@ -135758,7 +135758,7 @@ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ ExprClearProperty(pExpr, EP_Leaf); ExprSetProperty(pExpr, EP_FixedCol); assert( pExpr->pLeft==0 ); - pExpr->pLeft = tdsqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0); + pExpr->pLeft = sqlite3ExprDup(pConst->pParse->db, pConst->apExpr[i*2+1], 0); break; } return WRC_Prune; @@ -135817,12 +135817,12 @@ static int propagateConstants( memset(&w, 0, sizeof(w)); w.pParse = pParse; w.xExprCallback = propagateConstantExprRewrite; - w.xSelectCallback = tdsqlite3SelectWalkNoop; + w.xSelectCallback = sqlite3SelectWalkNoop; w.xSelectCallback2 = 0; w.walkerDepth = 0; w.u.pConst = &x; - tdsqlite3WalkExpr(&w, p->pWhere); - tdsqlite3DbFree(x.pParse->db, x.apExpr); + sqlite3WalkExpr(&w, p->pWhere); + sqlite3DbFree(x.pParse->db, x.apExpr); nChng += x.nChng; } }while( x.nChng ); @@ -135929,11 +135929,11 @@ static int pushDownWhereTerms( if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){ return 0; /* restriction (5) */ } - if( tdsqlite3ExprIsTableConstant(pWhere, iCursor) ){ + if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){ nChng++; while( pSubq ){ SubstContext x; - pNew = tdsqlite3ExprDup(pParse->db, pWhere, 0); + pNew = sqlite3ExprDup(pParse->db, pWhere, 0); unsetJoinExpr(pNew, -1); x.pParse = pParse; x.iTable = iCursor; @@ -135942,9 +135942,9 @@ static int pushDownWhereTerms( x.pEList = pSubq->pEList; pNew = substExpr(&x, pNew); if( pSubq->selFlags & SF_Aggregate ){ - pSubq->pHaving = tdsqlite3ExprAnd(pParse, pSubq->pHaving, pNew); + pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); }else{ - pSubq->pWhere = tdsqlite3ExprAnd(pParse, pSubq->pWhere, pNew); + pSubq->pWhere = sqlite3ExprAnd(pParse, pSubq->pWhere, pNew); } pSubq = pSubq->pPrior; } @@ -135969,7 +135969,7 @@ static int pushDownWhereTerms( ** located but before their arguments have been subjected to aggregate ** analysis. */ -static u8 minMaxQuery(tdsqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ +static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ int eRet = WHERE_ORDERBY_NORMAL; /* Return value */ ExprList *pEList = pFunc->x.pList; /* Arguments to agg function */ const char *zFunc; /* Name of aggregate function pFunc */ @@ -135983,16 +135983,16 @@ static u8 minMaxQuery(tdsqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ return eRet; } zFunc = pFunc->u.zToken; - if( tdsqlite3StrICmp(zFunc, "min")==0 ){ + if( sqlite3StrICmp(zFunc, "min")==0 ){ eRet = WHERE_ORDERBY_MIN; sortFlags = KEYINFO_ORDER_BIGNULL; - }else if( tdsqlite3StrICmp(zFunc, "max")==0 ){ + }else if( sqlite3StrICmp(zFunc, "max")==0 ){ eRet = WHERE_ORDERBY_MAX; sortFlags = KEYINFO_ORDER_DESC; }else{ return eRet; } - *ppMinMax = pOrderBy = tdsqlite3ExprListDup(db, pEList, 0); + *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); assert( pOrderBy!=0 || db->mallocFailed ); if( pOrderBy ) pOrderBy->a[0].sortFlags = sortFlags; return eRet; @@ -136040,17 +136040,17 @@ static Table *isSimpleCount(Select *p, AggInfo *pAggInfo){ ** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ -SQLITE_PRIVATE int tdsqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ +SQLITE_PRIVATE int sqlite3IndexedByLookup(Parse *pParse, struct SrcList_item *pFrom){ if( pFrom->pTab && pFrom->fg.isIndexedBy ){ Table *pTab = pFrom->pTab; char *zIndexedBy = pFrom->u1.zIndexedBy; Index *pIdx; for(pIdx=pTab->pIndex; - pIdx && tdsqlite3StrICmp(pIdx->zName, zIndexedBy); + pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); pIdx=pIdx->pNext ); if( !pIdx ){ - tdsqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); + sqlite3ErrorMsg(pParse, "no such index: %s", zIndexedBy, 0); pParse->checkSchema = 1; return SQLITE_ERROR; } @@ -136083,7 +136083,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ int i; Select *pNew; Select *pX; - tdsqlite3 *db; + sqlite3 *db; struct ExprList_item *a; SrcList *pNewSrc; Parse *pParse; @@ -136103,14 +136103,14 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ pParse = pWalker->pParse; db = pParse->db; - pNew = tdsqlite3DbMallocZero(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) ); if( pNew==0 ) return WRC_Abort; memset(&dummy, 0, sizeof(dummy)); - pNewSrc = tdsqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0); + pNewSrc = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&dummy,pNew,0,0); if( pNewSrc==0 ) return WRC_Abort; *pNew = *p; p->pSrc = pNewSrc; - p->pEList = tdsqlite3ExprListAppend(pParse, 0, tdsqlite3Expr(db, TK_ASTERISK, 0)); + p->pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ASTERISK, 0)); p->op = TK_SELECT; p->pWhere = 0; pNew->pGroupBy = 0; @@ -136138,7 +136138,7 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){ */ static int cannotBeFunction(Parse *pParse, struct SrcList_item *pFrom){ if( pFrom->fg.isTabFunc ){ - tdsqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); + sqlite3ErrorMsg(pParse, "'%s' is not a function", pFrom->zName); return 1; } return 0; @@ -136166,7 +136166,7 @@ static struct Cte *searchWith( for(p=pWith; p; p=p->pOuter){ int i; for(i=0; inCte; i++){ - if( tdsqlite3StrICmp(zName, p->a[i].zName)==0 ){ + if( sqlite3StrICmp(zName, p->a[i].zName)==0 ){ *ppContext = p; return &p->a[i]; } @@ -136186,7 +136186,7 @@ static struct Cte *searchWith( ** bFree==0, the With object will be freed along with the SELECT ** statement with which it is associated. */ -SQLITE_PRIVATE void tdsqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ +SQLITE_PRIVATE void sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ assert( bFree==0 || (pParse->pWith==0 && pParse->pWithToFree==0) ); if( pWith ){ assert( pParse->pWith!=pWith ); @@ -136216,7 +136216,7 @@ static int withExpand( struct SrcList_item *pFrom ){ Parse *pParse = pWalker->pParse; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; struct Cte *pCte; /* Matched CTE (or NULL if no match) */ With *pWith; /* WITH clause that pCte belongs to */ @@ -136239,20 +136239,20 @@ static int withExpand( ** early. If pCte->zCteErr is NULL, then this is not a recursive reference. ** In this case, proceed. */ if( pCte->zCteErr ){ - tdsqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); + sqlite3ErrorMsg(pParse, pCte->zCteErr, pCte->zName); return SQLITE_ERROR; } if( cannotBeFunction(pParse, pFrom) ) return SQLITE_ERROR; assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = tdsqlite3DbMallocZero(db, sizeof(Table)); + pFrom->pTab = pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return WRC_Abort; pTab->nTabRef = 1; - pTab->zName = tdsqlite3DbStrDup(db, pCte->zName); + pTab->zName = sqlite3DbStrDup(db, pCte->zName); pTab->iPKey = -1; - pTab->nRowLogEst = 200; assert( 200==tdsqlite3LogEst(1048576) ); + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid; - pFrom->pSelect = tdsqlite3SelectDup(db, pCte->pSelect, 0); + pFrom->pSelect = sqlite3SelectDup(db, pCte->pSelect, 0); if( db->mallocFailed ) return SQLITE_NOMEM_BKPT; assert( pFrom->pSelect ); @@ -136266,7 +136266,7 @@ static int withExpand( struct SrcList_item *pItem = &pSrc->a[i]; if( pItem->zDatabase==0 && pItem->zName!=0 - && 0==tdsqlite3StrICmp(pItem->zName, pCte->zName) + && 0==sqlite3StrICmp(pItem->zName, pCte->zName) ){ pItem->pTab = pTab; pItem->fg.isRecursive = 1; @@ -136278,7 +136278,7 @@ static int withExpand( /* Only one recursive reference is permitted. */ if( pTab->nTabRef>2 ){ - tdsqlite3ErrorMsg( + sqlite3ErrorMsg( pParse, "multiple references to recursive table: %s", pCte->zName ); return SQLITE_ERROR; @@ -136293,10 +136293,10 @@ static int withExpand( Select *pPrior = pSel->pPrior; assert( pPrior->pWith==0 ); pPrior->pWith = pSel->pWith; - tdsqlite3WalkSelect(pWalker, pPrior); + sqlite3WalkSelect(pWalker, pPrior); pPrior->pWith = 0; }else{ - tdsqlite3WalkSelect(pWalker, pSel); + sqlite3WalkSelect(pWalker, pSel); } pParse->pWith = pWith; @@ -136304,7 +136304,7 @@ static int withExpand( pEList = pLeft->pEList; if( pCte->pCols ){ if( pEList && pEList->nExpr!=pCte->pCols->nExpr ){ - tdsqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", + sqlite3ErrorMsg(pParse, "table %s has %d values for %d columns", pCte->zName, pEList->nExpr, pCte->pCols->nExpr ); pParse->pWith = pSavedWith; @@ -136313,14 +136313,14 @@ static int withExpand( pEList = pCte->pCols; } - tdsqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); + sqlite3ColumnsFromExprList(pParse, pEList, &pTab->nCol, &pTab->aCol); if( bMayRecursive ){ if( pSel->selFlags & SF_Recursive ){ pCte->zCteErr = "multiple recursive references: %s"; }else{ pCte->zCteErr = "recursive reference in a subquery: %s"; } - tdsqlite3WalkSelect(pWalker, pSel); + sqlite3WalkSelect(pWalker, pSel); } pCte->zCteErr = 0; pParse->pWith = pSavedWith; @@ -136336,7 +136336,7 @@ static int withExpand( ** clause, pop it from the stack stored as part of the Parse object. ** ** This function is used as the xSelectCallback2() callback by -** tdsqlite3SelectExpand() when walking a SELECT tree to resolve table +** sqlite3SelectExpand() when walking a SELECT tree to resolve table ** names and other FROM clause elements. */ static void selectPopWith(Walker *pWalker, Select *p){ @@ -136360,23 +136360,23 @@ static void selectPopWith(Walker *pWalker, Select *p){ ** SQLITE_OK is returned. Otherwise, if an OOM error is encountered, ** SQLITE_NOMEM. */ -SQLITE_PRIVATE int tdsqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ +SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse *pParse, struct SrcList_item *pFrom){ Select *pSel = pFrom->pSelect; Table *pTab; assert( pSel ); - pFrom->pTab = pTab = tdsqlite3DbMallocZero(pParse->db, sizeof(Table)); + pFrom->pTab = pTab = sqlite3DbMallocZero(pParse->db, sizeof(Table)); if( pTab==0 ) return SQLITE_NOMEM; pTab->nTabRef = 1; if( pFrom->zAlias ){ - pTab->zName = tdsqlite3DbStrDup(pParse->db, pFrom->zAlias); + pTab->zName = sqlite3DbStrDup(pParse->db, pFrom->zAlias); }else{ - pTab->zName = tdsqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId); + pTab->zName = sqlite3MPrintf(pParse->db, "subquery_%u", pSel->selId); } while( pSel->pPrior ){ pSel = pSel->pPrior; } - tdsqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); + sqlite3ColumnsFromExprList(pParse, pSel->pEList,&pTab->nCol,&pTab->aCol); pTab->iPKey = -1; - pTab->nRowLogEst = 200; assert( 200==tdsqlite3LogEst(1048576) ); + pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) ); pTab->tabFlags |= TF_Ephemeral; return pParse->nErr ? SQLITE_ERROR : SQLITE_OK; @@ -136412,7 +136412,7 @@ static int selectExpander(Walker *pWalker, Select *p){ SrcList *pTabList; ExprList *pEList; struct SrcList_item *pFrom; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Expr *pE, *pRight, *pExpr; u16 selFlags = p->selFlags; u32 elistFlags = 0; @@ -136431,12 +136431,12 @@ static int selectExpander(Walker *pWalker, Select *p){ } pTabList = p->pSrc; pEList = p->pEList; - tdsqlite3WithPush(pParse, p->pWith, 0); + sqlite3WithPush(pParse, p->pWith, 0); /* Make sure cursor numbers have been assigned to all entries in ** the FROM clause of the SELECT statement. */ - tdsqlite3SrcListAssignCursors(pParse, pTabList); + sqlite3SrcListAssignCursors(pParse, pTabList); /* Look up every table named in the FROM clause of the select. If ** an entry of the FROM clause is a subquery instead of a table or view, @@ -136457,16 +136457,16 @@ static int selectExpander(Walker *pWalker, Select *p){ /* A sub-query in the FROM clause of a SELECT */ assert( pSel!=0 ); assert( pFrom->pTab==0 ); - if( tdsqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; - if( tdsqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; + if( sqlite3WalkSelect(pWalker, pSel) ) return WRC_Abort; + if( sqlite3ExpandSubquery(pParse, pFrom) ) return WRC_Abort; #endif }else{ /* An ordinary table or view name in the FROM clause */ assert( pFrom->pTab==0 ); - pFrom->pTab = pTab = tdsqlite3LocateTableItem(pParse, 0, pFrom); + pFrom->pTab = pTab = sqlite3LocateTableItem(pParse, 0, pFrom); if( pTab==0 ) return WRC_Abort; if( pTab->nTabRef>=0xffff ){ - tdsqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", + sqlite3ErrorMsg(pParse, "too many references to \"%s\": max 65535", pTab->zName); pFrom->pTab = 0; return WRC_Abort; @@ -136479,10 +136479,10 @@ static int selectExpander(Walker *pWalker, Select *p){ if( IsVirtual(pTab) || pTab->pSelect ){ i16 nCol; u8 eCodeOrig = pWalker->eCode; - if( tdsqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; + if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ - tdsqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", + sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", pTab->zName); } #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -136491,15 +136491,15 @@ static int selectExpander(Walker *pWalker, Select *p){ && ALWAYS(pTab->pVTable!=0) && pTab->pVTable->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0) ){ - tdsqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", + sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", pTab->zName); } #endif - pFrom->pSelect = tdsqlite3SelectDup(db, pTab->pSelect, 0); + pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; pTab->nCol = -1; pWalker->eCode = 1; /* Turn on Select.selId renumbering */ - tdsqlite3WalkSelect(pWalker, pFrom->pSelect); + sqlite3WalkSelect(pWalker, pFrom->pSelect); pWalker->eCode = eCodeOrig; pTab->nCol = nCol; } @@ -136507,7 +136507,7 @@ static int selectExpander(Walker *pWalker, Select *p){ } /* Locate the index named by the INDEXED BY clause, if any. */ - if( tdsqlite3IndexedByLookup(pParse, pFrom) ){ + if( sqlite3IndexedByLookup(pParse, pFrom) ){ return WRC_Abort; } } @@ -136559,7 +136559,7 @@ static int selectExpander(Walker *pWalker, Select *p){ ){ /* This particular expression does not need to be expanded. */ - pNew = tdsqlite3ExprListAppend(pParse, pNew, a[k].pExpr); + pNew = sqlite3ExprListAppend(pParse, pNew, a[k].pExpr); if( pNew ){ pNew->a[pNew->nExpr-1].zEName = a[k].zEName; pNew->a[pNew->nExpr-1].eEName = a[k].eEName; @@ -136588,10 +136588,10 @@ static int selectExpander(Walker *pWalker, Select *p){ if( db->mallocFailed ) break; if( pSub==0 || (pSub->selFlags & SF_NestedFrom)==0 ){ pSub = 0; - if( zTName && tdsqlite3StrICmp(zTName, zTabName)!=0 ){ + if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; } - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); zSchemaName = iDb>=0 ? db->aDb[iDb].zDbSName : "*"; } for(j=0; jnCol; j++){ @@ -136602,7 +136602,7 @@ static int selectExpander(Walker *pWalker, Select *p){ assert( zName ); if( zTName && pSub - && tdsqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0 + && sqlite3MatchEName(&pSub->pEList->a[j], 0, zTName, 0)==0 ){ continue; } @@ -136626,64 +136626,64 @@ static int selectExpander(Walker *pWalker, Select *p){ ** table to the right of the join */ continue; } - if( tdsqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){ + if( sqlite3IdListIndex(pFrom->pUsing, zName)>=0 ){ /* In a join with a USING clause, omit columns in the ** using clause from the table on the right. */ continue; } } - pRight = tdsqlite3Expr(db, TK_ID, zName); + pRight = sqlite3Expr(db, TK_ID, zName); zColname = zName; zToFree = 0; if( longNames || pTabList->nSrc>1 ){ Expr *pLeft; - pLeft = tdsqlite3Expr(db, TK_ID, zTabName); - pExpr = tdsqlite3PExpr(pParse, TK_DOT, pLeft, pRight); + pLeft = sqlite3Expr(db, TK_ID, zTabName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); if( zSchemaName ){ - pLeft = tdsqlite3Expr(db, TK_ID, zSchemaName); - pExpr = tdsqlite3PExpr(pParse, TK_DOT, pLeft, pExpr); + pLeft = sqlite3Expr(db, TK_ID, zSchemaName); + pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pExpr); } if( longNames ){ - zColname = tdsqlite3MPrintf(db, "%s.%s", zTabName, zName); + zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName); zToFree = zColname; } }else{ pExpr = pRight; } - pNew = tdsqlite3ExprListAppend(pParse, pNew, pExpr); - tdsqlite3TokenInit(&sColname, zColname); - tdsqlite3ExprListSetName(pParse, pNew, &sColname, 0); + pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); + sqlite3TokenInit(&sColname, zColname); + sqlite3ExprListSetName(pParse, pNew, &sColname, 0); if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; - tdsqlite3DbFree(db, pX->zEName); + sqlite3DbFree(db, pX->zEName); if( pSub ){ - pX->zEName = tdsqlite3DbStrDup(db, pSub->pEList->a[j].zEName); + pX->zEName = sqlite3DbStrDup(db, pSub->pEList->a[j].zEName); testcase( pX->zEName==0 ); }else{ - pX->zEName = tdsqlite3MPrintf(db, "%s.%s.%s", + pX->zEName = sqlite3MPrintf(db, "%s.%s.%s", zSchemaName, zTabName, zColname); testcase( pX->zEName==0 ); } pX->eEName = ENAME_TAB; } - tdsqlite3DbFree(db, zToFree); + sqlite3DbFree(db, zToFree); } } if( !tableSeen ){ if( zTName ){ - tdsqlite3ErrorMsg(pParse, "no such table: %s", zTName); + sqlite3ErrorMsg(pParse, "no such table: %s", zTName); }else{ - tdsqlite3ErrorMsg(pParse, "no tables specified"); + sqlite3ErrorMsg(pParse, "no tables specified"); } } } } - tdsqlite3ExprListDelete(db, pEList); + sqlite3ExprListDelete(db, pEList); p->pEList = pNew; } if( p->pEList ){ if( p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){ - tdsqlite3ErrorMsg(pParse, "too many columns in result set"); + sqlite3ErrorMsg(pParse, "too many columns in result set"); return WRC_Abort; } if( (elistFlags & (EP_HasFunc|EP_Subquery))!=0 ){ @@ -136702,7 +136702,7 @@ static int selectExpander(Walker *pWalker, Select *p){ ** Walker.xSelectCallback is set to do something useful for every ** subquery in the parser tree. */ -SQLITE_PRIVATE int tdsqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ +SQLITE_PRIVATE int sqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ UNUSED_PARAMETER2(NotUsed, NotUsed2); return WRC_Continue; } @@ -136711,7 +136711,7 @@ SQLITE_PRIVATE int tdsqlite3ExprWalkNoop(Walker *NotUsed, Expr *NotUsed2){ ** No-op routine for the parse-tree walker for SELECT statements. ** subquery in the parser tree. */ -SQLITE_PRIVATE int tdsqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){ +SQLITE_PRIVATE int sqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){ UNUSED_PARAMETER2(NotUsed, NotUsed2); return WRC_Continue; } @@ -136721,7 +136721,7 @@ SQLITE_PRIVATE int tdsqlite3SelectWalkNoop(Walker *NotUsed, Select *NotUsed2){ ** Always assert. This xSelectCallback2 implementation proves that the ** xSelectCallback2 is never invoked. */ -SQLITE_PRIVATE void tdsqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){ +SQLITE_PRIVATE void sqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2){ UNUSED_PARAMETER2(NotUsed, NotUsed2); assert( 0 ); } @@ -136739,25 +136739,25 @@ SQLITE_PRIVATE void tdsqlite3SelectWalkAssert2(Walker *NotUsed, Select *NotUsed2 ** The calling function can detect the problem by looking at pParse->nErr ** and/or pParse->db->mallocFailed. */ -static void tdsqlite3SelectExpand(Parse *pParse, Select *pSelect){ +static void sqlite3SelectExpand(Parse *pParse, Select *pSelect){ Walker w; - w.xExprCallback = tdsqlite3ExprWalkNoop; + w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; if( OK_IF_ALWAYS_TRUE(pParse->hasCompound) ){ w.xSelectCallback = convertCompoundSelectToSubquery; w.xSelectCallback2 = 0; - tdsqlite3WalkSelect(&w, pSelect); + sqlite3WalkSelect(&w, pSelect); } w.xSelectCallback = selectExpander; w.xSelectCallback2 = selectPopWith; w.eCode = 0; - tdsqlite3WalkSelect(&w, pSelect); + sqlite3WalkSelect(&w, pSelect); } #ifndef SQLITE_OMIT_SUBQUERY /* -** This is a Walker.xSelectCallback callback for the tdsqlite3SelectTypeInfo() +** This is a Walker.xSelectCallback callback for the sqlite3SelectTypeInfo() ** interface. ** ** For each FROM-clause subquery, add Column.zType and Column.zColl @@ -136788,7 +136788,7 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ Select *pSel = pFrom->pSelect; if( pSel ){ while( pSel->pPrior ) pSel = pSel->pPrior; - tdsqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel, + sqlite3SelectAddColumnTypeAndCollation(pParse, pTab, pSel, SQLITE_AFF_NONE); } } @@ -136804,14 +136804,14 @@ static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){ ** ** Use this routine after name resolution. */ -static void tdsqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ +static void sqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ #ifndef SQLITE_OMIT_SUBQUERY Walker w; - w.xSelectCallback = tdsqlite3SelectWalkNoop; + w.xSelectCallback = sqlite3SelectWalkNoop; w.xSelectCallback2 = selectAddSubqueryTypeInfo; - w.xExprCallback = tdsqlite3ExprWalkNoop; + w.xExprCallback = sqlite3ExprWalkNoop; w.pParse = pParse; - tdsqlite3WalkSelect(&w, pSelect); + sqlite3WalkSelect(&w, pSelect); #endif } @@ -136828,7 +136828,7 @@ static void tdsqlite3SelectAddTypeInfo(Parse *pParse, Select *pSelect){ ** ** This routine acts recursively on all subqueries within the SELECT. */ -SQLITE_PRIVATE void tdsqlite3SelectPrep( +SQLITE_PRIVATE void sqlite3SelectPrep( Parse *pParse, /* The parser context */ Select *p, /* The SELECT statement being coded. */ NameContext *pOuterNC /* Name context for container */ @@ -136836,11 +136836,11 @@ SQLITE_PRIVATE void tdsqlite3SelectPrep( assert( p!=0 || pParse->db->mallocFailed ); if( pParse->db->mallocFailed ) return; if( p->selFlags & SF_HasTypeInfo ) return; - tdsqlite3SelectExpand(pParse, p); + sqlite3SelectExpand(pParse, p); if( pParse->nErr || pParse->db->mallocFailed ) return; - tdsqlite3ResolveSelectNames(pParse, p, pOuterNC); + sqlite3ResolveSelectNames(pParse, p, pOuterNC); if( pParse->nErr || pParse->db->mallocFailed ) return; - tdsqlite3SelectAddTypeInfo(pParse, p); + sqlite3SelectAddTypeInfo(pParse, p); } /* @@ -136870,18 +136870,18 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){ && pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg ); } #endif - tdsqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg); + sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg); for(pFunc=pAggInfo->aFunc, i=0; inFunc; i++, pFunc++){ if( pFunc->iDistinct>=0 ){ Expr *pE = pFunc->pExpr; assert( !ExprHasProperty(pE, EP_xIsSelect) ); if( pE->x.pList==0 || pE->x.pList->nExpr!=1 ){ - tdsqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " + sqlite3ErrorMsg(pParse, "DISTINCT aggregates must have exactly one " "argument"); pFunc->iDistinct = -1; }else{ - KeyInfo *pKeyInfo = tdsqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); - tdsqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO); } } @@ -136899,8 +136899,8 @@ static void finalizeAggFunctions(Parse *pParse, AggInfo *pAggInfo){ for(i=0, pF=pAggInfo->aFunc; inFunc; i++, pF++){ ExprList *pList = pF->pExpr->x.pList; assert( !ExprHasProperty(pF->pExpr, EP_xIsSelect) ); - tdsqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0); - tdsqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeAddOp2(v, OP_AggFinal, pF->iMem, pList ? pList->nExpr : 0); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); } } @@ -136943,22 +136943,22 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ ** the first row (regAcc==1), set the magnet register so that the ** accumulators are not populated unless the min()/max() is invoked and ** indicates that they should be. */ - tdsqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit); + sqlite3VdbeAddOp2(v, OP_Copy, regAcc, regHit); } - addrNext = tdsqlite3VdbeMakeLabel(pParse); - tdsqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); + addrNext = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); } if( pList ){ nArg = pList->nExpr; - regAgg = tdsqlite3GetTempRange(pParse, nArg); - tdsqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); + regAgg = sqlite3GetTempRange(pParse, nArg); + sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); }else{ nArg = 0; regAgg = 0; } if( pF->iDistinct>=0 ){ if( addrNext==0 ){ - addrNext = tdsqlite3VdbeMakeLabel(pParse); + addrNext = sqlite3VdbeMakeLabel(pParse); } testcase( nArg==0 ); /* Error condition */ testcase( nArg>1 ); /* Also an error */ @@ -136970,35 +136970,35 @@ static void updateAccumulator(Parse *pParse, int regAcc, AggInfo *pAggInfo){ int j; assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ for(j=0, pItem=pList->a; !pColl && jpExpr); + pColl = sqlite3ExprCollSeq(pParse, pItem->pExpr); } if( !pColl ){ pColl = pParse->db->pDfltColl; } if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; - tdsqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); } - tdsqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem); - tdsqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - tdsqlite3VdbeChangeP5(v, (u8)nArg); - tdsqlite3ReleaseTempRange(pParse, regAgg, nArg); + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, pF->iMem); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ - tdsqlite3VdbeResolveLabel(v, addrNext); + sqlite3VdbeResolveLabel(v, addrNext); } } if( regHit==0 && pAggInfo->nAccumulator ){ regHit = regAcc; } if( regHit ){ - addrHitTest = tdsqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); + addrHitTest = sqlite3VdbeAddOp1(v, OP_If, regHit); VdbeCoverage(v); } for(i=0, pC=pAggInfo->aCol; inAccumulator; i++, pC++){ - tdsqlite3ExprCode(pParse, pC->pExpr, pC->iMem); + sqlite3ExprCode(pParse, pC->pExpr, pC->iMem); } pAggInfo->directMode = 0; if( addrHitTest ){ - tdsqlite3VdbeJumpHere(v, addrHitTest); + sqlite3VdbeJumpHere(v, addrHitTest); } } @@ -137014,7 +137014,7 @@ static void explainSimpleCount( ){ if( pParse->explain==2 ){ int bCover = (pIdx!=0 && (HasRowid(pTab) || !IsPrimaryKeyIndex(pIdx))); - tdsqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s", + sqlite3VdbeExplain(pParse, 0, "SCAN TABLE %s%s%s", pTab->zName, bCover ? " USING COVERING INDEX " : "", bCover ? pIdx->zName : "" @@ -137026,10 +137026,10 @@ static void explainSimpleCount( #endif /* -** tdsqlite3WalkExpr() callback used by havingToWhere(). +** sqlite3WalkExpr() callback used by havingToWhere(). ** ** If the node passed to the callback is a TK_AND node, return -** WRC_Continue to tell tdsqlite3WalkExpr() to iterate through child nodes. +** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes. ** ** Otherwise, return WRC_Prune. In this case, also check if the ** sub-expression matches the criteria for being moved to the WHERE @@ -137039,13 +137039,13 @@ static void explainSimpleCount( static int havingToWhereExprCb(Walker *pWalker, Expr *pExpr){ if( pExpr->op!=TK_AND ){ Select *pS = pWalker->u.pSelect; - if( tdsqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){ - tdsqlite3 *db = pWalker->pParse->db; - Expr *pNew = tdsqlite3Expr(db, TK_INTEGER, "1"); + if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) ){ + sqlite3 *db = pWalker->pParse->db; + Expr *pNew = sqlite3Expr(db, TK_INTEGER, "1"); if( pNew ){ Expr *pWhere = pS->pWhere; SWAP(Expr, *pNew, *pExpr); - pNew = tdsqlite3ExprAnd(pWalker->pParse, pWhere, pNew); + pNew = sqlite3ExprAnd(pWalker->pParse, pWhere, pNew); pS->pWhere = pNew; pWalker->eCode = 1; } @@ -137076,11 +137076,11 @@ static void havingToWhere(Parse *pParse, Select *p){ sWalker.pParse = pParse; sWalker.xExprCallback = havingToWhereExprCb; sWalker.u.pSelect = p; - tdsqlite3WalkExpr(&sWalker, p->pHaving); + sqlite3WalkExpr(&sWalker, p->pHaving); #if SELECTTRACE_ENABLED - if( sWalker.eCode && (tdsqlite3SelectTrace & 0x100)!=0 ){ + if( sWalker.eCode && (sqlite3SelectTrace & 0x100)!=0 ){ SELECTTRACE(0x100,pParse,p,("Move HAVING terms into WHERE:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif } @@ -137103,15 +137103,15 @@ static struct SrcList_item *isSelfJoinView( assert( pItem->pTab!=0 ); assert( pThis->pTab!=0 ); if( pItem->pTab->pSchema!=pThis->pTab->pSchema ) continue; - if( tdsqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; + if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue; pS1 = pItem->pSelect; if( pItem->pTab->pSchema==0 && pThis->pSelect->selId!=pS1->selId ){ /* The query flattener left two different CTE tables with identical ** names in the same FROM clause. */ continue; } - if( tdsqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) - || tdsqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1) + if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) + || sqlite3ExprCompare(0, pThis->pSelect->pHaving, pS1->pHaving, -1) ){ /* The view was modified by some other optimization such as ** pushDownWhereTerms() */ @@ -137146,14 +137146,14 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ Select *pSub, *pPrior; Expr *pExpr; Expr *pCount; - tdsqlite3 *db; + sqlite3 *db; if( (p->selFlags & SF_Aggregate)==0 ) return 0; /* This is an aggregate */ if( p->pEList->nExpr!=1 ) return 0; /* Single result column */ if( p->pWhere ) return 0; if( p->pGroupBy ) return 0; pExpr = p->pEList->a[0].pExpr; if( pExpr->op!=TK_AGG_FUNCTION ) return 0; /* Result is an aggregate */ - if( tdsqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ + if( sqlite3_stricmp(pExpr->u.zToken,"count") ) return 0; /* Is count() */ if( pExpr->x.pList!=0 ) return 0; /* Must be count(*) */ if( p->pSrc->nSrc!=1 ) return 0; /* One table in FROM */ pSub = p->pSrc->a[0].pSelect; @@ -137174,8 +137174,8 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pExpr = 0; pSub = p->pSrc->a[0].pSelect; p->pSrc->a[0].pSelect = 0; - tdsqlite3SrcListDelete(db, p->pSrc); - p->pSrc = tdsqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); + sqlite3SrcListDelete(db, p->pSrc); + p->pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*p->pSrc)); while( pSub ){ Expr *pTerm; pPrior = pSub->pPrior; @@ -137184,15 +137184,15 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ pSub->selFlags |= SF_Aggregate; pSub->selFlags &= ~SF_Compound; pSub->nSelectRow = 0; - tdsqlite3ExprListDelete(db, pSub->pEList); - pTerm = pPrior ? tdsqlite3ExprDup(db, pCount, 0) : pCount; - pSub->pEList = tdsqlite3ExprListAppend(pParse, 0, pTerm); - pTerm = tdsqlite3PExpr(pParse, TK_SELECT, 0, 0); - tdsqlite3PExprAddSelect(pParse, pTerm, pSub); + sqlite3ExprListDelete(db, pSub->pEList); + pTerm = pPrior ? sqlite3ExprDup(db, pCount, 0) : pCount; + pSub->pEList = sqlite3ExprListAppend(pParse, 0, pTerm); + pTerm = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, pTerm, pSub); if( pExpr==0 ){ pExpr = pTerm; }else{ - pExpr = tdsqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr); + pExpr = sqlite3PExpr(pParse, TK_PLUS, pTerm, pExpr); } pSub = pPrior; } @@ -137200,9 +137200,9 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ p->selFlags &= ~SF_Aggregate; #if SELECTTRACE_ENABLED - if( tdsqlite3SelectTrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After count-of-view optimization:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif return 1; @@ -137222,13 +137222,13 @@ static int countOfViewOptimization(Parse *pParse, Select *p){ ** This routine does NOT free the Select structure passed in. The ** calling function needs to do that. */ -SQLITE_PRIVATE int tdsqlite3Select( +SQLITE_PRIVATE int sqlite3Select( Parse *pParse, /* The parser context */ Select *p, /* The SELECT statement being coded. */ SelectDest *pDest /* What to do with the query results */ ){ int i, j; /* Loop counters */ - WhereInfo *pWInfo; /* Return from tdsqlite3WhereBegin() */ + WhereInfo *pWInfo; /* Return from sqlite3WhereBegin() */ Vdbe *v; /* The virtual machine under construction */ int isAgg; /* True for select lists like "count(*)" */ ExprList *pEList = 0; /* List of columns to extract. */ @@ -137241,21 +137241,21 @@ SQLITE_PRIVATE int tdsqlite3Select( SortCtx sSort; /* Info on how to code the ORDER BY clause */ AggInfo sAggInfo; /* Information used by aggregate queries */ int iEnd; /* Address of the end of the query */ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */ u8 minMaxFlag; /* Flag for min/max queries */ db = pParse->db; - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( p==0 || db->mallocFailed || pParse->nErr ){ return 1; } - if( tdsqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; + if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1; memset(&sAggInfo, 0, sizeof(sAggInfo)); #if SELECTTRACE_ENABLED SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain)); - if( tdsqlite3SelectTrace & 0x100 ){ - tdsqlite3TreeViewSelect(0, p, 0); + if( sqlite3SelectTrace & 0x100 ){ + sqlite3TreeViewSelect(0, p, 0); } #endif @@ -137270,19 +137270,19 @@ SQLITE_PRIVATE int tdsqlite3Select( pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_Fifo); /* If ORDER BY makes no difference in the output then neither does ** DISTINCT so it can be removed too. */ - tdsqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprListDelete(db, p->pOrderBy); p->pOrderBy = 0; p->selFlags &= ~SF_Distinct; } - tdsqlite3SelectPrep(pParse, p, 0); + sqlite3SelectPrep(pParse, p, 0); if( pParse->nErr || db->mallocFailed ){ goto select_end; } assert( p->pEList!=0 ); #if SELECTTRACE_ENABLED - if( tdsqlite3SelectTrace & 0x104 ){ + if( sqlite3SelectTrace & 0x104 ){ SELECTTRACE(0x104,pParse,p, ("after name resolution:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif @@ -137291,15 +137291,15 @@ SQLITE_PRIVATE int tdsqlite3Select( } #ifndef SQLITE_OMIT_WINDOWFUNC - rc = tdsqlite3WindowRewrite(pParse, p); + rc = sqlite3WindowRewrite(pParse, p); if( rc ){ assert( db->mallocFailed || pParse->nErr>0 ); goto select_end; } #if SELECTTRACE_ENABLED - if( p->pWin && (tdsqlite3SelectTrace & 0x108)!=0 ){ + if( p->pWin && (sqlite3SelectTrace & 0x108)!=0 ){ SELECTTRACE(0x104,pParse,p, ("after window rewrite:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -137321,7 +137321,7 @@ SQLITE_PRIVATE int tdsqlite3Select( ** of the LEFT JOIN used in the WHERE clause. */ if( (pItem->fg.jointype & JT_LEFT)!=0 - && tdsqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) + && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) && OptimizationEnabled(db, SQLITE_SimplifyJoin) ){ SELECTTRACE(0x100,pParse,p, @@ -137336,7 +137336,7 @@ SQLITE_PRIVATE int tdsqlite3Select( /* Catch mismatch in the declared columns of a view and the number of ** columns in the SELECT on the RHS */ if( pTab->nCol!=pSub->pEList->nExpr ){ - tdsqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d", + sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d", pTab->nCol, pTab->zName, pSub->pEList->nExpr); goto select_end; } @@ -137399,8 +137399,8 @@ SQLITE_PRIVATE int tdsqlite3Select( rc = multiSelect(pParse, p, pDest); #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end compound-select processing\n")); - if( (tdsqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ - tdsqlite3TreeViewSelect(0, p, 0); + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + sqlite3TreeViewSelect(0, p, 0); } #endif if( p->pNext==0 ) ExplainQueryPlanPop(pParse); @@ -137411,16 +137411,16 @@ SQLITE_PRIVATE int tdsqlite3Select( /* Do the WHERE-clause constant propagation optimization if this is ** a join. No need to speed time on this operation for non-join queries ** as the equivalent optimization will be handled by query planner in - ** tdsqlite3WhereBegin(). + ** sqlite3WhereBegin(). */ if( pTabList->nSrc>1 && OptimizationEnabled(db, SQLITE_PropagateConst) && propagateConstants(pParse, p) ){ #if SELECTTRACE_ENABLED - if( tdsqlite3SelectTrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p,("After constant propagation:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif }else{ @@ -137466,7 +137466,7 @@ SQLITE_PRIVATE int tdsqlite3Select( ** string for the fake column name seems safer. */ if( pItem->colUsed==0 && pItem->zName!=0 ){ - tdsqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); + sqlite3AuthCheck(pParse, SQLITE_READ, pItem->zName, "", pItem->zDatabase); } #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) @@ -137496,7 +137496,7 @@ SQLITE_PRIVATE int tdsqlite3Select( ** more conservative than necessary, but much easier than enforcing ** an exact limit. */ - pParse->nHeight += tdsqlite3SelectExprHeight(p); + pParse->nHeight += sqlite3SelectExprHeight(p); /* Make copies of constant WHERE-clause terms in the outer query down ** inside the subquery. This can help the subquery to run more efficiently. @@ -137506,10 +137506,10 @@ SQLITE_PRIVATE int tdsqlite3Select( (pItem->fg.jointype & JT_OUTER)!=0) ){ #if SELECTTRACE_ENABLED - if( tdsqlite3SelectTrace & 0x100 ){ + if( sqlite3SelectTrace & 0x100 ){ SELECTTRACE(0x100,pParse,p, ("After WHERE-clause push-down into subquery %d:\n", pSub->selId)); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif }else{ @@ -137535,21 +137535,21 @@ SQLITE_PRIVATE int tdsqlite3Select( /* Implement a co-routine that will return a single row of the result ** set on each invocation. */ - int addrTop = tdsqlite3VdbeCurrentAddr(v)+1; + int addrTop = sqlite3VdbeCurrentAddr(v)+1; pItem->regReturn = ++pParse->nMem; - tdsqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); VdbeComment((v, "%s", pItem->pTab->zName)); pItem->addrFillSub = addrTop; - tdsqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); + sqlite3SelectDestInit(&dest, SRT_Coroutine, pItem->regReturn); ExplainQueryPlan((pParse, 1, "CO-ROUTINE %u", pSub->selId)); - tdsqlite3Select(pParse, pSub, &dest); + sqlite3Select(pParse, pSub, &dest); pItem->pTab->nRowLogEst = pSub->nSelectRow; pItem->fg.viaCoroutine = 1; pItem->regResult = dest.iSdst; - tdsqlite3VdbeEndCoroutine(v, pItem->regReturn); - tdsqlite3VdbeJumpHere(v, addrTop-1); - tdsqlite3ClearTempRegCache(pParse); + sqlite3VdbeEndCoroutine(v, pItem->regReturn); + sqlite3VdbeJumpHere(v, addrTop-1); + sqlite3ClearTempRegCache(pParse); }else{ /* Generate a subroutine that will fill an ephemeral table with ** the content of this subquery. pItem->addrFillSub will point @@ -137563,36 +137563,36 @@ SQLITE_PRIVATE int tdsqlite3Select( testcase( pItem->addrFillSub==0 ); /* Ticket c52b09c7f38903b1311 */ pItem->regReturn = ++pParse->nMem; - topAddr = tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); + topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn); pItem->addrFillSub = topAddr+1; if( pItem->fg.isCorrelated==0 ){ /* If the subquery is not correlated and if we are not inside of ** a trigger, then we only need to compute the value of the subquery ** once. */ - onceAddr = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + onceAddr = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); VdbeComment((v, "materialize \"%s\"", pItem->pTab->zName)); }else{ VdbeNoopComment((v, "materialize \"%s\"", pItem->pTab->zName)); } pPrior = isSelfJoinView(pTabList, pItem); if( pPrior ){ - tdsqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); + sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pPrior->iCursor); assert( pPrior->pSelect!=0 ); pSub->nSelectRow = pPrior->pSelect->nSelectRow; }else{ - tdsqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); + sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor); ExplainQueryPlan((pParse, 1, "MATERIALIZE %u", pSub->selId)); - tdsqlite3Select(pParse, pSub, &dest); + sqlite3Select(pParse, pSub, &dest); } pItem->pTab->nRowLogEst = pSub->nSelectRow; - if( onceAddr ) tdsqlite3VdbeJumpHere(v, onceAddr); - retAddr = tdsqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); + if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr); + retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn); VdbeComment((v, "end %s", pItem->pTab->zName)); - tdsqlite3VdbeChangeP1(v, topAddr, retAddr); - tdsqlite3ClearTempRegCache(pParse); + sqlite3VdbeChangeP1(v, topAddr, retAddr); + sqlite3ClearTempRegCache(pParse); } if( db->mallocFailed ) goto select_end; - pParse->nHeight -= tdsqlite3SelectExprHeight(p); + pParse->nHeight -= sqlite3SelectExprHeight(p); pParse->zAuthContext = zSavedAuthContext; #endif } @@ -137606,9 +137606,9 @@ SQLITE_PRIVATE int tdsqlite3Select( sDistinct.isTnct = (p->selFlags & SF_Distinct)!=0; #if SELECTTRACE_ENABLED - if( tdsqlite3SelectTrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("After all FROM-clause analysis:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif @@ -137628,13 +137628,13 @@ SQLITE_PRIVATE int tdsqlite3Select( ** BY and DISTINCT, and an index or separate temp-table for the other. */ if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct - && tdsqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 + && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 #endif ){ p->selFlags &= ~SF_Distinct; - pGroupBy = p->pGroupBy = tdsqlite3ExprListDup(db, pEList, 0); + pGroupBy = p->pGroupBy = sqlite3ExprListDup(db, pEList, 0); p->selFlags |= SF_Aggregate; /* Notice that even thought SF_Distinct has been cleared from p->selFlags, ** the sDistinct.isTnct is still set. Hence, isTnct represents the @@ -137642,9 +137642,9 @@ SQLITE_PRIVATE int tdsqlite3Select( assert( sDistinct.isTnct ); #if SELECTTRACE_ENABLED - if( tdsqlite3SelectTrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ SELECTTRACE(0x400,pParse,p,("Transform DISTINCT into GROUP BY:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); } #endif } @@ -137659,11 +137659,11 @@ SQLITE_PRIVATE int tdsqlite3Select( */ if( sSort.pOrderBy ){ KeyInfo *pKeyInfo; - pKeyInfo = tdsqlite3KeyInfoFromExprList( + pKeyInfo = sqlite3KeyInfoFromExprList( pParse, sSort.pOrderBy, 0, pEList->nExpr); sSort.iECursor = pParse->nTab++; sSort.addrSortIndex = - tdsqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sSort.iECursor, sSort.pOrderBy->nExpr+1+pEList->nExpr, 0, (char*)pKeyInfo, P4_KEYINFO ); @@ -137674,18 +137674,18 @@ SQLITE_PRIVATE int tdsqlite3Select( /* If the output is destined for a temporary table, open that table. */ if( pDest->eDest==SRT_EphemTab ){ - tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); } /* Set the limiter. */ - iEnd = tdsqlite3VdbeMakeLabel(pParse); + iEnd = sqlite3VdbeMakeLabel(pParse); if( (p->selFlags & SF_FixedLimit)==0 ){ p->nSelectRow = 320; /* 4 billion rows */ } computeLimitRegisters(pParse, p, iEnd); if( p->iLimit==0 && sSort.addrSortIndex>=0 ){ - tdsqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); + sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen); sSort.sortFlags |= SORTFLAG_UseSorter; } @@ -137693,11 +137693,11 @@ SQLITE_PRIVATE int tdsqlite3Select( */ if( p->selFlags & SF_Distinct ){ sDistinct.tabTnct = pParse->nTab++; - sDistinct.addrTnct = tdsqlite3VdbeAddOp4(v, OP_OpenEphemeral, + sDistinct.addrTnct = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, sDistinct.tabTnct, 0, 0, - (char*)tdsqlite3KeyInfoFromExprList(pParse, p->pEList,0,0), + (char*)sqlite3KeyInfoFromExprList(pParse, p->pEList,0,0), P4_KEYINFO); - tdsqlite3VdbeChangeP5(v, BTREE_UNORDERED); + sqlite3VdbeChangeP5(v, BTREE_UNORDERED); sDistinct.eTnctType = WHERE_DISTINCT_UNORDERED; }else{ sDistinct.eTnctType = WHERE_DISTINCT_NOOP; @@ -137710,7 +137710,7 @@ SQLITE_PRIVATE int tdsqlite3Select( #ifndef SQLITE_OMIT_WINDOWFUNC Window *pWin = p->pWin; /* Master window object (or NULL) */ if( pWin ){ - tdsqlite3WindowCodeInit(pParse, p); + sqlite3WindowCodeInit(pParse, p); } #endif assert( WHERE_USE_LIMIT==SF_FixedLimit ); @@ -137718,18 +137718,18 @@ SQLITE_PRIVATE int tdsqlite3Select( /* Begin the database scan. */ SELECTTRACE(1,pParse,p,("WhereBegin\n")); - pWInfo = tdsqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, sSort.pOrderBy, p->pEList, wctrlFlags, p->nSelectRow); if( pWInfo==0 ) goto select_end; - if( tdsqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ - p->nSelectRow = tdsqlite3WhereOutputRowCount(pWInfo); + if( sqlite3WhereOutputRowCount(pWInfo) < p->nSelectRow ){ + p->nSelectRow = sqlite3WhereOutputRowCount(pWInfo); } - if( sDistinct.isTnct && tdsqlite3WhereIsDistinct(pWInfo) ){ - sDistinct.eTnctType = tdsqlite3WhereIsDistinct(pWInfo); + if( sDistinct.isTnct && sqlite3WhereIsDistinct(pWInfo) ){ + sDistinct.eTnctType = sqlite3WhereIsDistinct(pWInfo); } if( sSort.pOrderBy ){ - sSort.nOBSat = tdsqlite3WhereIsOrdered(pWInfo); - sSort.labelOBLopt = tdsqlite3WhereOrderByLimitOptLabel(pWInfo); + sSort.nOBSat = sqlite3WhereIsOrdered(pWInfo); + sSort.labelOBLopt = sqlite3WhereOrderByLimitOptLabel(pWInfo); if( sSort.nOBSat==sSort.pOrderBy->nExpr ){ sSort.pOrderBy = 0; } @@ -137740,39 +137740,39 @@ SQLITE_PRIVATE int tdsqlite3Select( ** into an OP_Noop. */ if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){ - tdsqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); } assert( p->pEList==pEList ); #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ - int addrGosub = tdsqlite3VdbeMakeLabel(pParse); - int iCont = tdsqlite3VdbeMakeLabel(pParse); - int iBreak = tdsqlite3VdbeMakeLabel(pParse); + int addrGosub = sqlite3VdbeMakeLabel(pParse); + int iCont = sqlite3VdbeMakeLabel(pParse); + int iBreak = sqlite3VdbeMakeLabel(pParse); int regGosub = ++pParse->nMem; - tdsqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); + sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub); - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); - tdsqlite3VdbeResolveLabel(v, addrGosub); + sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak); + sqlite3VdbeResolveLabel(v, addrGosub); VdbeNoopComment((v, "inner-loop subroutine")); sSort.labelOBLopt = 0; selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, iCont, iBreak); - tdsqlite3VdbeResolveLabel(v, iCont); - tdsqlite3VdbeAddOp1(v, OP_Return, regGosub); + sqlite3VdbeResolveLabel(v, iCont); + sqlite3VdbeAddOp1(v, OP_Return, regGosub); VdbeComment((v, "end inner-loop subroutine")); - tdsqlite3VdbeResolveLabel(v, iBreak); + sqlite3VdbeResolveLabel(v, iBreak); }else #endif /* SQLITE_OMIT_WINDOWFUNC */ { /* Use the standard inner loop. */ selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, - tdsqlite3WhereContinueLabel(pWInfo), - tdsqlite3WhereBreakLabel(pWInfo)); + sqlite3WhereContinueLabel(pWInfo), + sqlite3WhereBreakLabel(pWInfo)); /* End the database scan loop. */ - tdsqlite3WhereEnd(pWInfo); + sqlite3WhereEnd(pWInfo); } }else{ /* This case when there exist aggregate functions or a GROUP BY clause @@ -137803,7 +137803,7 @@ SQLITE_PRIVATE int tdsqlite3Select( for(k=pGroupBy->nExpr, pItem=pGroupBy->a; k>0; k--, pItem++){ pItem->u.x.iAlias = 0; } - assert( 66==tdsqlite3LogEst(100) ); + assert( 66==sqlite3LogEst(100) ); if( p->nSelectRow>66 ) p->nSelectRow = 66; /* If there is both a GROUP BY and an ORDER BY clause and they are @@ -137825,17 +137825,17 @@ SQLITE_PRIVATE int tdsqlite3Select( u8 sortFlags = sSort.pOrderBy->a[ii].sortFlags & KEYINFO_ORDER_DESC; pGroupBy->a[ii].sortFlags = sortFlags; } - if( tdsqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ + if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){ orderByGrp = 1; } } }else{ - assert( 0==tdsqlite3LogEst(1) ); + assert( 0==sqlite3LogEst(1) ); p->nSelectRow = 0; } /* Create a label to jump to when we want to abort the query */ - addrEnd = tdsqlite3VdbeMakeLabel(pParse); + addrEnd = sqlite3VdbeMakeLabel(pParse); /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the @@ -137849,8 +137849,8 @@ SQLITE_PRIVATE int tdsqlite3Select( sAggInfo.mnReg = pParse->nMem+1; sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0; sAggInfo.pGroupBy = pGroupBy; - tdsqlite3ExprAnalyzeAggList(&sNC, pEList); - tdsqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); + sqlite3ExprAnalyzeAggList(&sNC, pEList); + sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy); if( pHaving ){ if( pGroupBy ){ assert( pWhere==p->pWhere ); @@ -137859,7 +137859,7 @@ SQLITE_PRIVATE int tdsqlite3Select( havingToWhere(pParse, p); pWhere = p->pWhere; } - tdsqlite3ExprAnalyzeAggregates(&sNC, pHaving); + sqlite3ExprAnalyzeAggregates(&sNC, pHaving); } sAggInfo.nAccumulator = sAggInfo.nColumn; if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){ @@ -137871,11 +137871,11 @@ SQLITE_PRIVATE int tdsqlite3Select( Expr *pExpr = sAggInfo.aFunc[i].pExpr; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); sNC.ncFlags |= NC_InAggFunc; - tdsqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList); + sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList); #ifndef SQLITE_OMIT_WINDOWFUNC assert( !IsWindowFunc(pExpr) ); if( ExprHasProperty(pExpr, EP_WinFunc) ){ - tdsqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter); + sqlite3ExprAnalyzeAggregates(&sNC, pExpr->y.pWin->pFilter); } #endif sNC.ncFlags &= ~NC_InAggFunc; @@ -137883,19 +137883,19 @@ SQLITE_PRIVATE int tdsqlite3Select( sAggInfo.mxReg = pParse->nMem; if( db->mallocFailed ) goto select_end; #if SELECTTRACE_ENABLED - if( tdsqlite3SelectTrace & 0x400 ){ + if( sqlite3SelectTrace & 0x400 ){ int ii; SELECTTRACE(0x400,pParse,p,("After aggregate analysis:\n")); - tdsqlite3TreeViewSelect(0, p, 0); + sqlite3TreeViewSelect(0, p, 0); for(ii=0; iinTab++; - pKeyInfo = tdsqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn); - addrSortingIdx = tdsqlite3VdbeAddOp4(v, OP_SorterOpen, + pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn); + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, sAggInfo.sortingIdx, sAggInfo.nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO); @@ -137931,29 +137931,29 @@ SQLITE_PRIVATE int tdsqlite3Select( iUseFlag = ++pParse->nMem; iAbortFlag = ++pParse->nMem; regOutputRow = ++pParse->nMem; - addrOutputRow = tdsqlite3VdbeMakeLabel(pParse); + addrOutputRow = sqlite3VdbeMakeLabel(pParse); regReset = ++pParse->nMem; - addrReset = tdsqlite3VdbeMakeLabel(pParse); + addrReset = sqlite3VdbeMakeLabel(pParse); iAMem = pParse->nMem + 1; pParse->nMem += pGroupBy->nExpr; iBMem = pParse->nMem + 1; pParse->nMem += pGroupBy->nExpr; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag); VdbeComment((v, "clear abort flag")); - tdsqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1); /* Begin a loop that will extract all source rows in GROUP BY order. ** This might involve two separate loops with an OP_Sort in between, or ** it might be a single loop that uses an index to extract information ** in the right order to begin with. */ - tdsqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); SELECTTRACE(1,pParse,p,("WhereBegin\n")); - pWInfo = tdsqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, 0, WHERE_GROUPBY | (orderByGrp ? WHERE_SORTBYGROUP : 0), 0 ); if( pWInfo==0 ) goto select_end; - if( tdsqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ + if( sqlite3WhereIsOrdered(pWInfo)==pGroupBy->nExpr ){ /* The optimizer is able to deliver rows in group by order so ** we do not have to sort. The OP_OpenEphemeral table will be ** cancelled later because we still need to use the pKeyInfo @@ -137984,28 +137984,28 @@ SQLITE_PRIVATE int tdsqlite3Select( j++; } } - regBase = tdsqlite3GetTempRange(pParse, nCol); - tdsqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); + regBase = sqlite3GetTempRange(pParse, nCol); + sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0); j = nGroupBy; for(i=0; iiSorterColumn>=j ){ int r1 = j + regBase; - tdsqlite3ExprCodeGetColumnOfTable(v, + sqlite3ExprCodeGetColumnOfTable(v, pCol->pTab, pCol->iTable, pCol->iColumn, r1); j++; } } - regRecord = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); - tdsqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); - tdsqlite3ReleaseTempReg(pParse, regRecord); - tdsqlite3ReleaseTempRange(pParse, regBase, nCol); - tdsqlite3WhereEnd(pWInfo); + regRecord = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); + sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord); + sqlite3ReleaseTempReg(pParse, regRecord); + sqlite3ReleaseTempRange(pParse, regBase, nCol); + sqlite3WhereEnd(pWInfo); sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++; - sortOut = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); - tdsqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); + sortOut = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); + sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); sAggInfo.useSortingIdx = 1; } @@ -138018,10 +138018,10 @@ SQLITE_PRIVATE int tdsqlite3Select( ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to ** disable this optimization for testing purposes. */ if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) - && (groupBySort || tdsqlite3WhereIsSorted(pWInfo)) + && (groupBySort || sqlite3WhereIsSorted(pWInfo)) ){ sSort.pOrderBy = 0; - tdsqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); + sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex); } /* Evaluate the current GROUP BY terms and store in b0, b1, b2... @@ -138029,23 +138029,23 @@ SQLITE_PRIVATE int tdsqlite3Select( ** Then compare the current GROUP BY terms against the GROUP BY terms ** from the previous row currently stored in a0, a1, a2... */ - addrTopOfLoop = tdsqlite3VdbeCurrentAddr(v); + addrTopOfLoop = sqlite3VdbeCurrentAddr(v); if( groupBySort ){ - tdsqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, + sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx, sortOut, sortPTab); } for(j=0; jnExpr; j++){ if( groupBySort ){ - tdsqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); + sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j); }else{ sAggInfo.directMode = 1; - tdsqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); + sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j); } } - tdsqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, - (char*)tdsqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); - addr1 = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v); + sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr, + (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO); + addr1 = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v); /* Generate code that runs whenever the GROUP BY changes. ** Changes in the GROUP BY are detected by the previous code @@ -138056,40 +138056,40 @@ SQLITE_PRIVATE int tdsqlite3Select( ** and resets the aggregate accumulator registers in preparation ** for the next GROUP BY batch. */ - tdsqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); - tdsqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output one row")); - tdsqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd); VdbeCoverage(v); VdbeComment((v, "check abort flag")); - tdsqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); + sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); VdbeComment((v, "reset accumulator")); /* Update the aggregate accumulators based on the content of ** the current row */ - tdsqlite3VdbeJumpHere(v, addr1); + sqlite3VdbeJumpHere(v, addr1); updateAccumulator(pParse, iUseFlag, &sAggInfo); - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag); VdbeComment((v, "indicate data in accumulator")); /* End of the loop */ if( groupBySort ){ - tdsqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); + sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop); VdbeCoverage(v); }else{ - tdsqlite3WhereEnd(pWInfo); - tdsqlite3VdbeChangeToNoop(v, addrSortingIdx); + sqlite3WhereEnd(pWInfo); + sqlite3VdbeChangeToNoop(v, addrSortingIdx); } /* Output the final row of result */ - tdsqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); + sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow); VdbeComment((v, "output final row")); /* Jump over the subroutines */ - tdsqlite3VdbeGoto(v, addrEnd); + sqlite3VdbeGoto(v, addrEnd); /* Generate a subroutine that outputs a single row of the result ** set. This subroutine first looks at the iUseFlag. If iUseFlag @@ -138098,31 +138098,31 @@ SQLITE_PRIVATE int tdsqlite3Select( ** increments the iAbortFlag memory location before returning in ** order to signal the caller to abort. */ - addrSetAbort = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); + addrSetAbort = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag); VdbeComment((v, "set abort flag")); - tdsqlite3VdbeAddOp1(v, OP_Return, regOutputRow); - tdsqlite3VdbeResolveLabel(v, addrOutputRow); - addrOutputRow = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + sqlite3VdbeResolveLabel(v, addrOutputRow); + addrOutputRow = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2); VdbeCoverage(v); VdbeComment((v, "Groupby result generator entry point")); - tdsqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); finalizeAggFunctions(pParse, &sAggInfo); - tdsqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL); selectInnerLoop(pParse, p, -1, &sSort, &sDistinct, pDest, addrOutputRow+1, addrSetAbort); - tdsqlite3VdbeAddOp1(v, OP_Return, regOutputRow); + sqlite3VdbeAddOp1(v, OP_Return, regOutputRow); VdbeComment((v, "end groupby result generator")); /* Generate a subroutine that will reset the group-by accumulator */ - tdsqlite3VdbeResolveLabel(v, addrReset); + sqlite3VdbeResolveLabel(v, addrReset); resetAccumulator(pParse, &sAggInfo); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); + sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag); VdbeComment((v, "indicate accumulator empty")); - tdsqlite3VdbeAddOp1(v, OP_Return, regReset); + sqlite3VdbeAddOp1(v, OP_Return, regReset); } /* endif pGroupBy. Begin aggregate queries without GROUP BY: */ else { @@ -138142,15 +138142,15 @@ SQLITE_PRIVATE int tdsqlite3Select( ** is better to execute the op on an index, as indexes are almost ** always spread across less pages than their corresponding tables. */ - const int iDb = tdsqlite3SchemaToIndex(pParse->db, pTab->pSchema); + const int iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); const int iCsr = pParse->nTab++; /* Cursor to scan b-tree */ Index *pIdx; /* Iterator variable */ KeyInfo *pKeyInfo = 0; /* Keyinfo for scanned index */ Index *pBest = 0; /* Best index found so far */ int iRoot = pTab->tnum; /* Root page of scanned b-tree */ - tdsqlite3CodeVerifySchema(pParse, iDb); - tdsqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + sqlite3CodeVerifySchema(pParse, iDb); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); /* Search for the index that has the lowest scan cost. ** @@ -138161,7 +138161,7 @@ SQLITE_PRIVATE int tdsqlite3Select( ** In practice the KeyInfo structure will not be used. It is only ** passed to keep OP_OpenRead happy. */ - if( !HasRowid(pTab) ) pBest = tdsqlite3PrimaryKeyIndex(pTab); + if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab); for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( pIdx->bUnordered==0 && pIdx->szIdxRowszTabRow @@ -138173,16 +138173,16 @@ SQLITE_PRIVATE int tdsqlite3Select( } if( pBest ){ iRoot = pBest->tnum; - pKeyInfo = tdsqlite3KeyInfoOfIndex(pParse, pBest); + pKeyInfo = sqlite3KeyInfoOfIndex(pParse, pBest); } /* Open a read-only cursor, execute the OP_Count, close the cursor. */ - tdsqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1); + sqlite3VdbeAddOp4Int(v, OP_OpenRead, iCsr, iRoot, iDb, 1); if( pKeyInfo ){ - tdsqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); + sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO); } - tdsqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem); - tdsqlite3VdbeAddOp1(v, OP_Close, iCsr); + sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); explainSimpleCount(pParse, pTab, pBest); }else #endif /* SQLITE_OMIT_BTREECOUNT */ @@ -138205,7 +138205,7 @@ SQLITE_PRIVATE int tdsqlite3Select( } if( i==sAggInfo.nFunc ){ regAcc = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc); } } @@ -138225,28 +138225,28 @@ SQLITE_PRIVATE int tdsqlite3Select( assert( pMinMaxOrderBy==0 || pMinMaxOrderBy->nExpr==1 ); SELECTTRACE(1,pParse,p,("WhereBegin\n")); - pWInfo = tdsqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pMinMaxOrderBy, 0, minMaxFlag, 0); if( pWInfo==0 ){ goto select_end; } updateAccumulator(pParse, regAcc, &sAggInfo); - if( regAcc ) tdsqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); - if( tdsqlite3WhereIsOrdered(pWInfo)>0 ){ - tdsqlite3VdbeGoto(v, tdsqlite3WhereBreakLabel(pWInfo)); + if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc); + if( sqlite3WhereIsOrdered(pWInfo)>0 ){ + sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo)); VdbeComment((v, "%s() by index", (minMaxFlag==WHERE_ORDERBY_MIN?"min":"max"))); } - tdsqlite3WhereEnd(pWInfo); + sqlite3WhereEnd(pWInfo); finalizeAggFunctions(pParse, &sAggInfo); } sSort.pOrderBy = 0; - tdsqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); selectInnerLoop(pParse, p, -1, 0, 0, pDest, addrEnd, addrEnd); } - tdsqlite3VdbeResolveLabel(v, addrEnd); + sqlite3VdbeResolveLabel(v, addrEnd); } /* endif aggregate query */ @@ -138266,7 +138266,7 @@ SQLITE_PRIVATE int tdsqlite3Select( /* Jump here to skip this query */ - tdsqlite3VdbeResolveLabel(v, iEnd); + sqlite3VdbeResolveLabel(v, iEnd); /* The SELECT has been coded. If there is an error in the Parse structure, ** set the return code to 1. Otherwise 0. */ @@ -138276,13 +138276,13 @@ SQLITE_PRIVATE int tdsqlite3Select( ** successful coding of the SELECT. */ select_end: - tdsqlite3ExprListDelete(db, pMinMaxOrderBy); - tdsqlite3DbFree(db, sAggInfo.aCol); - tdsqlite3DbFree(db, sAggInfo.aFunc); + sqlite3ExprListDelete(db, pMinMaxOrderBy); + sqlite3DbFree(db, sAggInfo.aCol); + sqlite3DbFree(db, sAggInfo.aFunc); #if SELECTTRACE_ENABLED SELECTTRACE(0x1,pParse,p,("end processing\n")); - if( (tdsqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ - tdsqlite3TreeViewSelect(0, p, 0); + if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){ + sqlite3TreeViewSelect(0, p, 0); } #endif ExplainQueryPlanPop(pParse); @@ -138302,9 +138302,9 @@ select_end: ** May you share freely, never taking more than you give. ** ************************************************************************* -** This file contains the tdsqlite3_get_table() and tdsqlite3_free_table() +** This file contains the sqlite3_get_table() and sqlite3_free_table() ** interface routines. These are just wrappers around the main -** interface routine of tdsqlite3_exec(). +** interface routine of sqlite3_exec(). ** ** These routines are in a separate files so that they will not be linked ** if they are not used. @@ -138314,7 +138314,7 @@ select_end: #ifndef SQLITE_OMIT_GET_TABLE /* -** This structure is used to pass data from tdsqlite3_get_table() through +** This structure is used to pass data from sqlite3_get_table() through ** to the callback function is uses to build the result. */ typedef struct TabResult { @@ -138324,7 +138324,7 @@ typedef struct TabResult { u32 nRow; /* Number of rows in the result */ u32 nColumn; /* Number of columns in the result */ u32 nData; /* Slots used in azResult[]. (nRow+1)*nColumn */ - int rc; /* Return code from tdsqlite3_exec() */ + int rc; /* Return code from sqlite3_exec() */ } TabResult; /* @@ -138332,7 +138332,7 @@ typedef struct TabResult { ** is to fill in the TabResult structure appropriately, allocating new ** memory as necessary. */ -static int tdsqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ +static int sqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv){ TabResult *p = (TabResult*)pArg; /* Result accumulator */ int need; /* Slots needed in p->azResult[] */ int i; /* Loop counter */ @@ -138349,7 +138349,7 @@ static int tdsqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv if( p->nData + need > p->nAlloc ){ char **azNew; p->nAlloc = p->nAlloc*2 + need; - azNew = tdsqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc ); + azNew = sqlite3_realloc64( p->azResult, sizeof(char*)*p->nAlloc ); if( azNew==0 ) goto malloc_failed; p->azResult = azNew; } @@ -138360,14 +138360,14 @@ static int tdsqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv if( p->nRow==0 ){ p->nColumn = nCol; for(i=0; iazResult[p->nData++] = z; } }else if( (int)p->nColumn!=nCol ){ - tdsqlite3_free(p->zErrMsg); - p->zErrMsg = tdsqlite3_mprintf( - "tdsqlite3_get_table() called with two or more incompatible queries" + sqlite3_free(p->zErrMsg); + p->zErrMsg = sqlite3_mprintf( + "sqlite3_get_table() called with two or more incompatible queries" ); p->rc = SQLITE_ERROR; return 1; @@ -138380,8 +138380,8 @@ static int tdsqlite3_get_table_cb(void *pArg, int nCol, char **argv, char **colv if( argv[i]==0 ){ z = 0; }else{ - int n = tdsqlite3Strlen30(argv[i])+1; - z = tdsqlite3_malloc64( n ); + int n = sqlite3Strlen30(argv[i])+1; + z = sqlite3_malloc64( n ); if( z==0 ) goto malloc_failed; memcpy(z, argv[i], n); } @@ -138403,11 +138403,11 @@ malloc_failed: ** ** The result that is written to ***pazResult is held in memory obtained ** from malloc(). But the caller cannot free this memory directly. -** Instead, the entire table should be passed to tdsqlite3_free_table() when +** Instead, the entire table should be passed to sqlite3_free_table() when ** the calling procedure is finished using it. */ -SQLITE_API int tdsqlite3_get_table( - tdsqlite3 *db, /* The database on which the SQL executes */ +SQLITE_API int sqlite3_get_table( + sqlite3 *db, /* The database on which the SQL executes */ const char *zSql, /* The SQL to be executed */ char ***pazResult, /* Write the result table here */ int *pnRow, /* Write the number of rows in the result here */ @@ -138418,7 +138418,7 @@ SQLITE_API int tdsqlite3_get_table( TabResult res; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) || pazResult==0 ) return SQLITE_MISUSE_BKPT; #endif *pazResult = 0; if( pnColumn ) *pnColumn = 0; @@ -138430,37 +138430,37 @@ SQLITE_API int tdsqlite3_get_table( res.nData = 1; res.nAlloc = 20; res.rc = SQLITE_OK; - res.azResult = tdsqlite3_malloc64(sizeof(char*)*res.nAlloc ); + res.azResult = sqlite3_malloc64(sizeof(char*)*res.nAlloc ); if( res.azResult==0 ){ db->errCode = SQLITE_NOMEM; return SQLITE_NOMEM_BKPT; } res.azResult[0] = 0; - rc = tdsqlite3_exec(db, zSql, tdsqlite3_get_table_cb, &res, pzErrMsg); + rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg); assert( sizeof(res.azResult[0])>= sizeof(res.nData) ); res.azResult[0] = SQLITE_INT_TO_PTR(res.nData); if( (rc&0xff)==SQLITE_ABORT ){ - tdsqlite3_free_table(&res.azResult[1]); + sqlite3_free_table(&res.azResult[1]); if( res.zErrMsg ){ if( pzErrMsg ){ - tdsqlite3_free(*pzErrMsg); - *pzErrMsg = tdsqlite3_mprintf("%s",res.zErrMsg); + sqlite3_free(*pzErrMsg); + *pzErrMsg = sqlite3_mprintf("%s",res.zErrMsg); } - tdsqlite3_free(res.zErrMsg); + sqlite3_free(res.zErrMsg); } db->errCode = res.rc; /* Assume 32-bit assignment is atomic */ return res.rc; } - tdsqlite3_free(res.zErrMsg); + sqlite3_free(res.zErrMsg); if( rc!=SQLITE_OK ){ - tdsqlite3_free_table(&res.azResult[1]); + sqlite3_free_table(&res.azResult[1]); return rc; } if( res.nAlloc>res.nData ){ char **azNew; - azNew = tdsqlite3_realloc64( res.azResult, sizeof(char*)*res.nData ); + azNew = sqlite3_realloc64( res.azResult, sizeof(char*)*res.nData ); if( azNew==0 ){ - tdsqlite3_free_table(&res.azResult[1]); + sqlite3_free_table(&res.azResult[1]); db->errCode = SQLITE_NOMEM; return SQLITE_NOMEM_BKPT; } @@ -138473,18 +138473,18 @@ SQLITE_API int tdsqlite3_get_table( } /* -** This routine frees the space the tdsqlite3_get_table() malloced. +** This routine frees the space the sqlite3_get_table() malloced. */ -SQLITE_API void tdsqlite3_free_table( - char **azResult /* Result returned from tdsqlite3_get_table() */ +SQLITE_API void sqlite3_free_table( + char **azResult /* Result returned from sqlite3_get_table() */ ){ if( azResult ){ int i, n; azResult--; assert( azResult!=0 ); n = SQLITE_PTR_TO_INT(azResult[0]); - for(i=1; ipNext; - tdsqlite3ExprDelete(db, pTmp->pWhere); - tdsqlite3ExprListDelete(db, pTmp->pExprList); - tdsqlite3SelectDelete(db, pTmp->pSelect); - tdsqlite3IdListDelete(db, pTmp->pIdList); - tdsqlite3UpsertDelete(db, pTmp->pUpsert); - tdsqlite3DbFree(db, pTmp->zSpan); + sqlite3ExprDelete(db, pTmp->pWhere); + sqlite3ExprListDelete(db, pTmp->pExprList); + sqlite3SelectDelete(db, pTmp->pSelect); + sqlite3IdListDelete(db, pTmp->pIdList); + sqlite3UpsertDelete(db, pTmp->pUpsert); + sqlite3DbFree(db, pTmp->zSpan); - tdsqlite3DbFree(db, pTmp); + sqlite3DbFree(db, pTmp); } } @@ -138540,7 +138540,7 @@ SQLITE_PRIVATE void tdsqlite3DeleteTriggerStep(tdsqlite3 *db, TriggerStep *pTrig ** that fire off of pTab. The list will include any TEMP triggers on ** pTab as well as the triggers lised in pTab->pTrigger. */ -SQLITE_PRIVATE Trigger *tdsqlite3TriggerList(Parse *pParse, Table *pTab){ +SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ Schema * const pTmpSchema = pParse->db->aDb[1].pSchema; Trigger *pList = 0; /* List of triggers to return */ @@ -138550,11 +138550,11 @@ SQLITE_PRIVATE Trigger *tdsqlite3TriggerList(Parse *pParse, Table *pTab){ if( pTmpSchema!=pTab->pSchema ){ HashElem *p; - assert( tdsqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); + assert( sqlite3SchemaMutexHeld(pParse->db, 0, pTmpSchema) ); for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ Trigger *pTrig = (Trigger *)sqliteHashData(p); if( pTrig->pTabSchema==pTab->pSchema - && 0==tdsqlite3StrICmp(pTrig->table, pTab->zName) + && 0==sqlite3StrICmp(pTrig->table, pTab->zName) ){ pTrig->pNext = (pList ? pList : pTab->pTrigger); pList = pTrig; @@ -138570,10 +138570,10 @@ SQLITE_PRIVATE Trigger *tdsqlite3TriggerList(Parse *pParse, Table *pTab){ ** up to the point of the BEGIN before the trigger actions. A Trigger ** structure is generated based on the information available and stored ** in pParse->pNewTrigger. After the trigger actions have been parsed, the -** tdsqlite3FinishTrigger() function is called to complete the trigger +** sqlite3FinishTrigger() function is called to complete the trigger ** construction process. */ -SQLITE_PRIVATE void tdsqlite3BeginTrigger( +SQLITE_PRIVATE void sqlite3BeginTrigger( Parse *pParse, /* The parse context of the CREATE TRIGGER statement */ Token *pName1, /* The name of the trigger */ Token *pName2, /* The name of the trigger */ @@ -138588,7 +138588,7 @@ SQLITE_PRIVATE void tdsqlite3BeginTrigger( Trigger *pTrigger = 0; /* The new trigger */ Table *pTab; /* Table that the trigger fires off of */ char *zName = 0; /* Name of the trigger */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ int iDb; /* The database to store the trigger in */ Token *pName; /* The unqualified db name */ DbFixer sFix; /* State vector for the DB fixer */ @@ -138600,14 +138600,14 @@ SQLITE_PRIVATE void tdsqlite3BeginTrigger( if( isTemp ){ /* If TEMP was specified, then the trigger name may not be qualified. */ if( pName2->n>0 ){ - tdsqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name"); + sqlite3ErrorMsg(pParse, "temporary trigger may not have qualified name"); goto trigger_cleanup; } iDb = 1; pName = pName1; }else{ /* Figure out the db that the trigger will be created in */ - iDb = tdsqlite3TwoPartName(pParse, pName1, pName2, &pName); + iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ){ goto trigger_cleanup; } @@ -138625,16 +138625,16 @@ SQLITE_PRIVATE void tdsqlite3BeginTrigger( ** name on pTableName if we are reparsing out of SQLITE_MASTER. */ if( db->init.busy && iDb!=1 ){ - tdsqlite3DbFree(db, pTableName->a[0].zDatabase); + sqlite3DbFree(db, pTableName->a[0].zDatabase); pTableName->a[0].zDatabase = 0; } /* If the trigger name was unqualified, and the table is a temp table, ** then set iDb to 1 to create the trigger in the temporary database. - ** If tdsqlite3SrcListLookup() returns 0, indicating the table does not + ** If sqlite3SrcListLookup() returns 0, indicating the table does not ** exist, the error is caught by the block below. */ - pTab = tdsqlite3SrcListLookup(pParse, pTableName); + pTab = sqlite3SrcListLookup(pParse, pTableName); if( db->init.busy==0 && pName2->n==0 && pTab && pTab->pSchema==db->aDb[1].pSchema ){ iDb = 1; @@ -138643,11 +138643,11 @@ SQLITE_PRIVATE void tdsqlite3BeginTrigger( /* Ensure the table name matches database name and that the table exists */ if( db->mallocFailed ) goto trigger_cleanup; assert( pTableName->nSrc==1 ); - tdsqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); - if( tdsqlite3FixSrcList(&sFix, pTableName) ){ + sqlite3FixInit(&sFix, pParse, iDb, "trigger", pName); + if( sqlite3FixSrcList(&sFix, pTableName) ){ goto trigger_cleanup; } - pTab = tdsqlite3SrcListLookup(pParse, pTableName); + pTab = sqlite3SrcListLookup(pParse, pTableName); if( !pTab ){ /* The table does not exist. */ if( db->init.iDb==1 ){ @@ -138664,36 +138664,36 @@ SQLITE_PRIVATE void tdsqlite3BeginTrigger( goto trigger_cleanup; } if( IsVirtual(pTab) ){ - tdsqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); + sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_cleanup; } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ - zName = tdsqlite3NameFromToken(db, pName); + zName = sqlite3NameFromToken(db, pName); if( zName==0 ){ assert( db->mallocFailed ); goto trigger_cleanup; } - if( tdsqlite3CheckObjectName(pParse, zName, "trigger", pTab->zName) ){ + if( sqlite3CheckObjectName(pParse, zName, "trigger", pTab->zName) ){ goto trigger_cleanup; } - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !IN_RENAME_OBJECT ){ - if( tdsqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ + if( sqlite3HashFind(&(db->aDb[iDb].pSchema->trigHash),zName) ){ if( !noErr ){ - tdsqlite3ErrorMsg(pParse, "trigger %T already exists", pName); + sqlite3ErrorMsg(pParse, "trigger %T already exists", pName); }else{ assert( !db->init.busy ); - tdsqlite3CodeVerifySchema(pParse, iDb); + sqlite3CodeVerifySchema(pParse, iDb); } goto trigger_cleanup; } } /* Do not create a trigger on a system table */ - if( tdsqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ - tdsqlite3ErrorMsg(pParse, "cannot create trigger on system table"); + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 ){ + sqlite3ErrorMsg(pParse, "cannot create trigger on system table"); goto trigger_cleanup; } @@ -138701,27 +138701,27 @@ SQLITE_PRIVATE void tdsqlite3BeginTrigger( ** of triggers. */ if( pTab->pSelect && tr_tm!=TK_INSTEAD ){ - tdsqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", + sqlite3ErrorMsg(pParse, "cannot create %s trigger on view: %S", (tr_tm == TK_BEFORE)?"BEFORE":"AFTER", pTableName, 0); goto trigger_cleanup; } if( !pTab->pSelect && tr_tm==TK_INSTEAD ){ - tdsqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" + sqlite3ErrorMsg(pParse, "cannot create INSTEAD OF" " trigger on table: %S", pTableName, 0); goto trigger_cleanup; } #ifndef SQLITE_OMIT_AUTHORIZATION if( !IN_RENAME_OBJECT ){ - int iTabDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); int code = SQLITE_CREATE_TRIGGER; const char *zDb = db->aDb[iTabDb].zDbSName; const char *zDbTrig = isTemp ? db->aDb[1].zDbSName : zDb; if( iTabDb==1 || isTemp ) code = SQLITE_CREATE_TEMP_TRIGGER; - if( tdsqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ + if( sqlite3AuthCheck(pParse, code, zName, pTab->zName, zDbTrig) ){ goto trigger_cleanup; } - if( tdsqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){ + if( sqlite3AuthCheck(pParse, SQLITE_INSERT, SCHEMA_TABLE(iTabDb),0,zDb)){ goto trigger_cleanup; } } @@ -138737,21 +138737,21 @@ SQLITE_PRIVATE void tdsqlite3BeginTrigger( } /* Build the Trigger object */ - pTrigger = (Trigger*)tdsqlite3DbMallocZero(db, sizeof(Trigger)); + pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; pTrigger->zName = zName; zName = 0; - pTrigger->table = tdsqlite3DbStrDup(db, pTableName->a[0].zName); + pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); pTrigger->pSchema = db->aDb[iDb].pSchema; pTrigger->pTabSchema = pTab->pSchema; pTrigger->op = (u8)op; pTrigger->tr_tm = tr_tm==TK_BEFORE ? TRIGGER_BEFORE : TRIGGER_AFTER; if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); + sqlite3RenameTokenRemap(pParse, pTrigger->table, pTableName->a[0].zName); pTrigger->pWhen = pWhen; pWhen = 0; }else{ - pTrigger->pWhen = tdsqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); } pTrigger->pColumns = pColumns; pColumns = 0; @@ -138759,12 +138759,12 @@ SQLITE_PRIVATE void tdsqlite3BeginTrigger( pParse->pNewTrigger = pTrigger; trigger_cleanup: - tdsqlite3DbFree(db, zName); - tdsqlite3SrcListDelete(db, pTableName); - tdsqlite3IdListDelete(db, pColumns); - tdsqlite3ExprDelete(db, pWhen); + sqlite3DbFree(db, zName); + sqlite3SrcListDelete(db, pTableName); + sqlite3IdListDelete(db, pColumns); + sqlite3ExprDelete(db, pWhen); if( !pParse->pNewTrigger ){ - tdsqlite3DeleteTrigger(db, pTrigger); + sqlite3DeleteTrigger(db, pTrigger); }else{ assert( pParse->pNewTrigger==pTrigger ); } @@ -138774,14 +138774,14 @@ trigger_cleanup: ** This routine is called after all of the trigger actions have been parsed ** in order to complete the process of building the trigger. */ -SQLITE_PRIVATE void tdsqlite3FinishTrigger( +SQLITE_PRIVATE void sqlite3FinishTrigger( Parse *pParse, /* Parser context */ TriggerStep *pStepList, /* The triggered program */ Token *pAll /* Token that describes the complete CREATE TRIGGER */ ){ Trigger *pTrig = pParse->pNewTrigger; /* Trigger being finished */ char *zName; /* Name of trigger */ - tdsqlite3 *db = pParse->db; /* The database */ + sqlite3 *db = pParse->db; /* The database */ DbFixer sFix; /* Fixer object */ int iDb; /* Database containing the trigger */ Token nameToken; /* Trigger name for error reporting */ @@ -138789,16 +138789,16 @@ SQLITE_PRIVATE void tdsqlite3FinishTrigger( pParse->pNewTrigger = 0; if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; zName = pTrig->zName; - iDb = tdsqlite3SchemaToIndex(pParse->db, pTrig->pSchema); + iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); pTrig->step_list = pStepList; while( pStepList ){ pStepList->pTrig = pTrig; pStepList = pStepList->pNext; } - tdsqlite3TokenInit(&nameToken, pTrig->zName); - tdsqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); - if( tdsqlite3FixTriggerStep(&sFix, pTrig->step_list) - || tdsqlite3FixExpr(&sFix, pTrig->pWhen) + sqlite3TokenInit(&nameToken, pTrig->zName); + sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken); + if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) + || sqlite3FixExpr(&sFix, pTrig->pWhen) ){ goto triggerfinish_cleanup; } @@ -138819,32 +138819,32 @@ SQLITE_PRIVATE void tdsqlite3FinishTrigger( char *z; /* Make an entry in the sqlite_master table */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v==0 ) goto triggerfinish_cleanup; - tdsqlite3BeginWriteOperation(pParse, 0, iDb); - z = tdsqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); + sqlite3BeginWriteOperation(pParse, 0, iDb); + z = sqlite3DbStrNDup(db, (char*)pAll->z, pAll->n); testcase( z==0 ); - tdsqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "INSERT INTO %Q.%s VALUES('trigger',%Q,%Q,0,'CREATE TRIGGER %q')", db->aDb[iDb].zDbSName, MASTER_NAME, zName, pTrig->table, z); - tdsqlite3DbFree(db, z); - tdsqlite3ChangeCookie(pParse, iDb); - tdsqlite3VdbeAddParseSchemaOp(v, iDb, - tdsqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); + sqlite3DbFree(db, z); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddParseSchemaOp(v, iDb, + sqlite3MPrintf(db, "type='trigger' AND name='%q'", zName)); } if( db->init.busy ){ Trigger *pLink = pTrig; Hash *pHash = &db->aDb[iDb].pSchema->trigHash; - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); assert( pLink!=0 ); - pTrig = tdsqlite3HashInsert(pHash, zName, pTrig); + pTrig = sqlite3HashInsert(pHash, zName, pTrig); if( pTrig ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); }else if( pLink->pSchema==pLink->pTabSchema ){ Table *pTab; - pTab = tdsqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); + pTab = sqlite3HashFind(&pLink->pTabSchema->tblHash, pLink->table); assert( pTab!=0 ); pLink->pNext = pTab->pTrigger; pTab->pTrigger = pLink; @@ -138852,19 +138852,19 @@ SQLITE_PRIVATE void tdsqlite3FinishTrigger( } triggerfinish_cleanup: - tdsqlite3DeleteTrigger(db, pTrig); + sqlite3DeleteTrigger(db, pTrig); assert( IN_RENAME_OBJECT || !pParse->pNewTrigger ); - tdsqlite3DeleteTriggerStep(db, pStepList); + sqlite3DeleteTriggerStep(db, pStepList); } /* ** Duplicate a range of text from an SQL statement, then convert all ** whitespace characters into ordinary space characters. */ -static char *triggerSpanDup(tdsqlite3 *db, const char *zStart, const char *zEnd){ - char *z = tdsqlite3DbSpanDup(db, zStart, zEnd); +static char *triggerSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){ + char *z = sqlite3DbSpanDup(db, zStart, zEnd); int i; - if( z ) for(i=0; z[i]; i++) if( tdsqlite3Isspace(z[i]) ) z[i] = ' '; + if( z ) for(i=0; z[i]; i++) if( sqlite3Isspace(z[i]) ) z[i] = ' '; return z; } @@ -138875,15 +138875,15 @@ static char *triggerSpanDup(tdsqlite3 *db, const char *zStart, const char *zEnd) ** The parser calls this routine when it finds a SELECT statement in ** body of a TRIGGER. */ -SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerSelectStep( - tdsqlite3 *db, /* Database connection */ +SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep( + sqlite3 *db, /* Database connection */ Select *pSelect, /* The SELECT statement */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ - TriggerStep *pTriggerStep = tdsqlite3DbMallocZero(db, sizeof(TriggerStep)); + TriggerStep *pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep)); if( pTriggerStep==0 ) { - tdsqlite3SelectDelete(db, pSelect); + sqlite3SelectDelete(db, pSelect); return 0; } pTriggerStep->op = TK_SELECT; @@ -138906,19 +138906,19 @@ static TriggerStep *triggerStepAllocate( const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; - pTriggerStep = tdsqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); + pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1); if( pTriggerStep ){ char *z = (char*)&pTriggerStep[1]; memcpy(z, pName->z, pName->n); - tdsqlite3Dequote(z); + sqlite3Dequote(z); pTriggerStep->zTarget = z; pTriggerStep->op = op; pTriggerStep->zSpan = triggerSpanDup(db, zStart, zEnd); if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName); + sqlite3RenameTokenMap(pParse, pTriggerStep->zTarget, pName); } } return pTriggerStep; @@ -138931,7 +138931,7 @@ static TriggerStep *triggerStepAllocate( ** The parser calls this routine when it sees an INSERT inside the ** body of a trigger. */ -SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerInsertStep( +SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( Parse *pParse, /* Parser */ Token *pTableName, /* Name of the table into which we insert */ IdList *pColumn, /* List of columns in pTableName to insert into */ @@ -138941,7 +138941,7 @@ SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerInsertStep( const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; assert(pSelect != 0 || db->mallocFailed); @@ -138952,21 +138952,21 @@ SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerInsertStep( pTriggerStep->pSelect = pSelect; pSelect = 0; }else{ - pTriggerStep->pSelect = tdsqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); } pTriggerStep->pIdList = pColumn; pTriggerStep->pUpsert = pUpsert; pTriggerStep->orconf = orconf; if( pUpsert ){ - tdsqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget); + sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget); } }else{ testcase( pColumn ); - tdsqlite3IdListDelete(db, pColumn); + sqlite3IdListDelete(db, pColumn); testcase( pUpsert ); - tdsqlite3UpsertDelete(db, pUpsert); + sqlite3UpsertDelete(db, pUpsert); } - tdsqlite3SelectDelete(db, pSelect); + sqlite3SelectDelete(db, pSelect); return pTriggerStep; } @@ -138976,7 +138976,7 @@ SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerInsertStep( ** a pointer to that trigger step. The parser calls this routine when it ** sees an UPDATE statement inside the body of a CREATE TRIGGER. */ -SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerUpdateStep( +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( Parse *pParse, /* Parser */ Token *pTableName, /* Name of the table to be updated */ ExprList *pEList, /* The SET clause: list of column and new values */ @@ -138985,7 +138985,7 @@ SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerUpdateStep( const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; pTriggerStep = triggerStepAllocate(pParse, TK_UPDATE, pTableName,zStart,zEnd); @@ -138996,13 +138996,13 @@ SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerUpdateStep( pEList = 0; pWhere = 0; }else{ - pTriggerStep->pExprList = tdsqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); - pTriggerStep->pWhere = tdsqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE); + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); } pTriggerStep->orconf = orconf; } - tdsqlite3ExprListDelete(db, pEList); - tdsqlite3ExprDelete(db, pWhere); + sqlite3ExprListDelete(db, pEList); + sqlite3ExprDelete(db, pWhere); return pTriggerStep; } @@ -139011,14 +139011,14 @@ SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerUpdateStep( ** a pointer to that trigger step. The parser calls this routine when it ** sees a DELETE statement inside the body of a CREATE TRIGGER. */ -SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerDeleteStep( +SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( Parse *pParse, /* Parser */ Token *pTableName, /* The table from which rows are deleted */ Expr *pWhere, /* The WHERE clause */ const char *zStart, /* Start of SQL text */ const char *zEnd /* End of SQL text */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; TriggerStep *pTriggerStep; pTriggerStep = triggerStepAllocate(pParse, TK_DELETE, pTableName,zStart,zEnd); @@ -139027,71 +139027,71 @@ SQLITE_PRIVATE TriggerStep *tdsqlite3TriggerDeleteStep( pTriggerStep->pWhere = pWhere; pWhere = 0; }else{ - pTriggerStep->pWhere = tdsqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pTriggerStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); } pTriggerStep->orconf = OE_Default; } - tdsqlite3ExprDelete(db, pWhere); + sqlite3ExprDelete(db, pWhere); return pTriggerStep; } /* ** Recursively delete a Trigger structure */ -SQLITE_PRIVATE void tdsqlite3DeleteTrigger(tdsqlite3 *db, Trigger *pTrigger){ +SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ if( pTrigger==0 ) return; - tdsqlite3DeleteTriggerStep(db, pTrigger->step_list); - tdsqlite3DbFree(db, pTrigger->zName); - tdsqlite3DbFree(db, pTrigger->table); - tdsqlite3ExprDelete(db, pTrigger->pWhen); - tdsqlite3IdListDelete(db, pTrigger->pColumns); - tdsqlite3DbFree(db, pTrigger); + sqlite3DeleteTriggerStep(db, pTrigger->step_list); + sqlite3DbFree(db, pTrigger->zName); + sqlite3DbFree(db, pTrigger->table); + sqlite3ExprDelete(db, pTrigger->pWhen); + sqlite3IdListDelete(db, pTrigger->pColumns); + sqlite3DbFree(db, pTrigger); } /* ** This function is called to drop a trigger from the database schema. ** ** This may be called directly from the parser and therefore identifies -** the trigger by name. The tdsqlite3DropTriggerPtr() routine does the +** the trigger by name. The sqlite3DropTriggerPtr() routine does the ** same job as this routine except it takes a pointer to the trigger ** instead of the trigger name. **/ -SQLITE_PRIVATE void tdsqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ +SQLITE_PRIVATE void sqlite3DropTrigger(Parse *pParse, SrcList *pName, int noErr){ Trigger *pTrigger = 0; int i; const char *zDb; const char *zName; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( db->mallocFailed ) goto drop_trigger_cleanup; - if( SQLITE_OK!=tdsqlite3ReadSchema(pParse) ){ + if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto drop_trigger_cleanup; } assert( pName->nSrc==1 ); zDb = pName->a[0].zDatabase; zName = pName->a[0].zName; - assert( zDb!=0 || tdsqlite3BtreeHoldsAllMutexes(db) ); + assert( zDb!=0 || sqlite3BtreeHoldsAllMutexes(db) ); for(i=OMIT_TEMPDB; inDb; i++){ int j = (i<2) ? i^1 : i; /* Search TEMP before MAIN */ - if( zDb && tdsqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue; - assert( tdsqlite3SchemaMutexHeld(db, j, 0) ); - pTrigger = tdsqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); + if( zDb && sqlite3StrICmp(db->aDb[j].zDbSName, zDb) ) continue; + assert( sqlite3SchemaMutexHeld(db, j, 0) ); + pTrigger = sqlite3HashFind(&(db->aDb[j].pSchema->trigHash), zName); if( pTrigger ) break; } if( !pTrigger ){ if( !noErr ){ - tdsqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); + sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); }else{ - tdsqlite3CodeVerifyNamedSchema(pParse, zDb); + sqlite3CodeVerifyNamedSchema(pParse, zDb); } pParse->checkSchema = 1; goto drop_trigger_cleanup; } - tdsqlite3DropTriggerPtr(pParse, pTrigger); + sqlite3DropTriggerPtr(pParse, pTrigger); drop_trigger_cleanup: - tdsqlite3SrcListDelete(db, pName); + sqlite3SrcListDelete(db, pName); } /* @@ -139099,20 +139099,20 @@ drop_trigger_cleanup: ** is set on. */ static Table *tableOfTrigger(Trigger *pTrigger){ - return tdsqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table); + return sqlite3HashFind(&pTrigger->pTabSchema->tblHash, pTrigger->table); } /* ** Drop a trigger given a pointer to that trigger. */ -SQLITE_PRIVATE void tdsqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ +SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ Table *pTable; Vdbe *v; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int iDb; - iDb = tdsqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); + iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); assert( iDb>=0 && iDbnDb ); pTable = tableOfTrigger(pTrigger); assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 ); @@ -139122,8 +139122,8 @@ SQLITE_PRIVATE void tdsqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ const char *zDb = db->aDb[iDb].zDbSName; const char *zTab = SCHEMA_TABLE(iDb); if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER; - if( tdsqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || - tdsqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ + if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || + sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ return; } } @@ -139131,26 +139131,26 @@ SQLITE_PRIVATE void tdsqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ /* Generate code to destroy the database record of the trigger. */ - if( (v = tdsqlite3GetVdbe(pParse))!=0 ){ - tdsqlite3NestedParse(pParse, + if( (v = sqlite3GetVdbe(pParse))!=0 ){ + sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", db->aDb[iDb].zDbSName, MASTER_NAME, pTrigger->zName ); - tdsqlite3ChangeCookie(pParse, iDb); - tdsqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); + sqlite3ChangeCookie(pParse, iDb); + sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); } } /* ** Remove a trigger from the hash tables of the sqlite* pointer. */ -SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteTrigger(tdsqlite3 *db, int iDb, const char *zName){ +SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ Trigger *pTrigger; Hash *pHash; - assert( tdsqlite3SchemaMutexHeld(db, iDb, 0) ); + assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); pHash = &(db->aDb[iDb].pSchema->trigHash); - pTrigger = tdsqlite3HashInsert(pHash, zName, 0); + pTrigger = sqlite3HashInsert(pHash, zName, 0); if( ALWAYS(pTrigger) ){ if( pTrigger->pSchema==pTrigger->pTabSchema ){ Table *pTab = tableOfTrigger(pTrigger); @@ -139164,7 +139164,7 @@ SQLITE_PRIVATE void tdsqlite3UnlinkAndDeleteTrigger(tdsqlite3 *db, int iDb, cons } } } - tdsqlite3DeleteTrigger(db, pTrigger); + sqlite3DeleteTrigger(db, pTrigger); db->mDbFlags |= DBFLAG_SchemaChange; } } @@ -139182,7 +139182,7 @@ static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ int e; if( pIdList==0 || NEVER(pEList==0) ) return 1; for(e=0; enExpr; e++){ - if( tdsqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1; + if( sqlite3IdListIndex(pIdList, pEList->a[e].zEName)>=0 ) return 1; } return 0; } @@ -139193,7 +139193,7 @@ static int checkColumnOverlap(IdList *pIdList, ExprList *pEList){ ** performed on the table, and, if that operation is an UPDATE, if at ** least one of the columns in pChanges is being modified. */ -SQLITE_PRIVATE Trigger *tdsqlite3TriggersExist( +SQLITE_PRIVATE Trigger *sqlite3TriggersExist( Parse *pParse, /* Parse context */ Table *pTab, /* The table the contains the triggers */ int op, /* one of TK_DELETE, TK_INSERT, TK_UPDATE */ @@ -139205,7 +139205,7 @@ SQLITE_PRIVATE Trigger *tdsqlite3TriggersExist( Trigger *p; if( (pParse->db->flags & SQLITE_EnableTrigger)!=0 ){ - pList = tdsqlite3TriggerList(pParse, pTab); + pList = sqlite3TriggerList(pParse, pTab); } assert( pList==0 || IsVirtual(pTab)==0 ); for(p=pList; p; p=p->pNext){ @@ -139233,20 +139233,20 @@ static SrcList *targetSrcList( Parse *pParse, /* The parsing context */ TriggerStep *pStep /* The trigger containing the target token */ ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int iDb; /* Index of the database to use */ SrcList *pSrc; /* SrcList to be returned */ - pSrc = tdsqlite3SrcListAppend(pParse, 0, 0, 0); + pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( pSrc ){ assert( pSrc->nSrc>0 ); - pSrc->a[pSrc->nSrc-1].zName = tdsqlite3DbStrDup(db, pStep->zTarget); - iDb = tdsqlite3SchemaToIndex(db, pStep->pTrig->pSchema); + pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget); + iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema); if( iDb==0 || iDb>=2 ){ const char *zDb; assert( iDbnDb ); zDb = db->aDb[iDb].zDbSName; - pSrc->a[pSrc->nSrc-1].zDatabase = tdsqlite3DbStrDup(db, zDb); + pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, zDb); } } return pSrc; @@ -139263,7 +139263,7 @@ static int codeTriggerProgram( ){ TriggerStep *pStep; Vdbe *v = pParse->pVdbe; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; assert( pParse->pTriggerTab && pParse->pToplevel ); assert( pStepList ); @@ -139287,50 +139287,50 @@ static int codeTriggerProgram( #ifndef SQLITE_OMIT_TRACE if( pStep->zSpan ){ - tdsqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0, - tdsqlite3MPrintf(db, "-- %s", pStep->zSpan), + sqlite3VdbeAddOp4(v, OP_Trace, 0x7fffffff, 1, 0, + sqlite3MPrintf(db, "-- %s", pStep->zSpan), P4_DYNAMIC); } #endif switch( pStep->op ){ case TK_UPDATE: { - tdsqlite3Update(pParse, + sqlite3Update(pParse, targetSrcList(pParse, pStep), - tdsqlite3ExprListDup(db, pStep->pExprList, 0), - tdsqlite3ExprDup(db, pStep->pWhere, 0), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), pParse->eOrconf, 0, 0, 0 ); break; } case TK_INSERT: { - tdsqlite3Insert(pParse, + sqlite3Insert(pParse, targetSrcList(pParse, pStep), - tdsqlite3SelectDup(db, pStep->pSelect, 0), - tdsqlite3IdListDup(db, pStep->pIdList), + sqlite3SelectDup(db, pStep->pSelect, 0), + sqlite3IdListDup(db, pStep->pIdList), pParse->eOrconf, - tdsqlite3UpsertDup(db, pStep->pUpsert) + sqlite3UpsertDup(db, pStep->pUpsert) ); break; } case TK_DELETE: { - tdsqlite3DeleteFrom(pParse, + sqlite3DeleteFrom(pParse, targetSrcList(pParse, pStep), - tdsqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 + sqlite3ExprDup(db, pStep->pWhere, 0), 0, 0 ); break; } default: assert( pStep->op==TK_SELECT ); { SelectDest sDest; - Select *pSelect = tdsqlite3SelectDup(db, pStep->pSelect, 0); - tdsqlite3SelectDestInit(&sDest, SRT_Discard, 0); - tdsqlite3Select(pParse, pSelect, &sDest); - tdsqlite3SelectDelete(db, pSelect); + Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); + sqlite3SelectDestInit(&sDest, SRT_Discard, 0); + sqlite3Select(pParse, pSelect, &sDest); + sqlite3SelectDelete(db, pSelect); break; } } if( pStep->op!=TK_SELECT ){ - tdsqlite3VdbeAddOp0(v, OP_ResetCount); + sqlite3VdbeAddOp0(v, OP_ResetCount); } } @@ -139368,7 +139368,7 @@ static void transferParseError(Parse *pTo, Parse *pFrom){ pTo->nErr = pFrom->nErr; pTo->rc = pFrom->rc; }else{ - tdsqlite3DbFree(pFrom->db, pFrom->zErrMsg); + sqlite3DbFree(pFrom->db, pFrom->zErrMsg); } } @@ -139382,8 +139382,8 @@ static TriggerPrg *codeRowTrigger( Table *pTab, /* The table pTrigger is attached to */ int orconf /* ON CONFLICT policy to code trigger program with */ ){ - Parse *pTop = tdsqlite3ParseToplevel(pParse); - tdsqlite3 *db = pParse->db; /* Database handle */ + Parse *pTop = sqlite3ParseToplevel(pParse); + sqlite3 *db = pParse->db; /* Database handle */ TriggerPrg *pPrg; /* Value to return */ Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ Vdbe *v; /* Temporary VM */ @@ -139398,13 +139398,13 @@ static TriggerPrg *codeRowTrigger( /* Allocate the TriggerPrg and SubProgram objects. To ensure that they ** are freed if an error occurs, link them into the Parse.pTriggerPrg ** list of the top-level Parse object sooner rather than later. */ - pPrg = tdsqlite3DbMallocZero(db, sizeof(TriggerPrg)); + pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); if( !pPrg ) return 0; pPrg->pNext = pTop->pTriggerPrg; pTop->pTriggerPrg = pPrg; - pPrg->pProgram = pProgram = tdsqlite3DbMallocZero(db, sizeof(SubProgram)); + pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); if( !pProgram ) return 0; - tdsqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); + sqlite3VdbeLinkSubProgram(pTop->pVdbe, pProgram); pPrg->pTrigger = pTrigger; pPrg->orconf = orconf; pPrg->aColmask[0] = 0xffffffff; @@ -139412,7 +139412,7 @@ static TriggerPrg *codeRowTrigger( /* Allocate and populate a new Parse context to use for coding the ** trigger sub-program. */ - pSubParse = tdsqlite3StackAllocZero(db, sizeof(Parse)); + pSubParse = sqlite3StackAllocZero(db, sizeof(Parse)); if( !pSubParse ) return 0; memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pSubParse; @@ -139424,7 +139424,7 @@ static TriggerPrg *codeRowTrigger( pSubParse->nQueryLoop = pParse->nQueryLoop; pSubParse->disableVtab = pParse->disableVtab; - v = tdsqlite3GetVdbe(pSubParse); + v = sqlite3GetVdbe(pSubParse); if( v ){ VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", pTrigger->zName, onErrorText(orconf), @@ -139436,8 +139436,8 @@ static TriggerPrg *codeRowTrigger( )); #ifndef SQLITE_OMIT_TRACE if( pTrigger->zName ){ - tdsqlite3VdbeChangeP4(v, -1, - tdsqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC + sqlite3VdbeChangeP4(v, -1, + sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC ); } #endif @@ -139446,14 +139446,14 @@ static TriggerPrg *codeRowTrigger( ** (or NULL) the sub-vdbe is immediately halted by jumping to the ** OP_Halt inserted at the end of the program. */ if( pTrigger->pWhen ){ - pWhen = tdsqlite3ExprDup(db, pTrigger->pWhen, 0); - if( SQLITE_OK==tdsqlite3ResolveExprNames(&sNC, pWhen) + pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); + if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) && db->mallocFailed==0 ){ - iEndTrigger = tdsqlite3VdbeMakeLabel(pSubParse); - tdsqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); + iEndTrigger = sqlite3VdbeMakeLabel(pSubParse); + sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); } - tdsqlite3ExprDelete(db, pWhen); + sqlite3ExprDelete(db, pWhen); } /* Code the trigger program into the sub-vdbe. */ @@ -139461,27 +139461,27 @@ static TriggerPrg *codeRowTrigger( /* Insert an OP_Halt at the end of the sub-program. */ if( iEndTrigger ){ - tdsqlite3VdbeResolveLabel(v, iEndTrigger); + sqlite3VdbeResolveLabel(v, iEndTrigger); } - tdsqlite3VdbeAddOp0(v, OP_Halt); + sqlite3VdbeAddOp0(v, OP_Halt); VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); transferParseError(pParse, pSubParse); if( db->mallocFailed==0 && pParse->nErr==0 ){ - pProgram->aOp = tdsqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); + pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); } pProgram->nMem = pSubParse->nMem; pProgram->nCsr = pSubParse->nTab; pProgram->token = (void *)pTrigger; pPrg->aColmask[0] = pSubParse->oldmask; pPrg->aColmask[1] = pSubParse->newmask; - tdsqlite3VdbeDelete(v); + sqlite3VdbeDelete(v); } assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); - tdsqlite3ParserReset(pSubParse); - tdsqlite3StackFree(db, pSubParse); + sqlite3ParserReset(pSubParse); + sqlite3StackFree(db, pSubParse); return pPrg; } @@ -139498,7 +139498,7 @@ static TriggerPrg *getRowTrigger( Table *pTab, /* The table trigger pTrigger is attached to */ int orconf /* ON CONFLICT algorithm. */ ){ - Parse *pRoot = tdsqlite3ParseToplevel(pParse); + Parse *pRoot = sqlite3ParseToplevel(pParse); TriggerPrg *pPrg; assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); @@ -139524,9 +139524,9 @@ static TriggerPrg *getRowTrigger( ** Generate code for the trigger program associated with trigger p on ** table pTab. The reg, orconf and ignoreJump parameters passed to this ** function are the same as those described in the header function for -** tdsqlite3CodeRowTrigger() +** sqlite3CodeRowTrigger() */ -SQLITE_PRIVATE void tdsqlite3CodeRowTriggerDirect( +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( Parse *pParse, /* Parse context */ Trigger *p, /* Trigger to code */ Table *pTab, /* The table to code triggers from */ @@ -139534,7 +139534,7 @@ SQLITE_PRIVATE void tdsqlite3CodeRowTriggerDirect( int orconf, /* ON CONFLICT policy */ int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ ){ - Vdbe *v = tdsqlite3GetVdbe(pParse); /* Main VM */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ TriggerPrg *pPrg; pPrg = getRowTrigger(pParse, p, pTab, orconf); assert( pPrg || pParse->nErr || pParse->db->mallocFailed ); @@ -139544,7 +139544,7 @@ SQLITE_PRIVATE void tdsqlite3CodeRowTriggerDirect( if( pPrg ){ int bRecursive = (p->zName && 0==(pParse->db->flags&SQLITE_RecTriggers)); - tdsqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem, + sqlite3VdbeAddOp4(v, OP_Program, reg, ignoreJump, ++pParse->nMem, (const char *)pPrg->pProgram, P4_SUBPROGRAM); VdbeComment( (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); @@ -139554,7 +139554,7 @@ SQLITE_PRIVATE void tdsqlite3CodeRowTriggerDirect( ** invocation is disallowed if (a) the sub-program is really a trigger, ** not a foreign key action, and (b) the flag to enable recursive triggers ** is clear. */ - tdsqlite3VdbeChangeP5(v, (u8)bRecursive); + sqlite3VdbeChangeP5(v, (u8)bRecursive); } } @@ -139598,7 +139598,7 @@ SQLITE_PRIVATE void tdsqlite3CodeRowTriggerDirect( ** is the instruction that control should jump to if a trigger program ** raises an IGNORE exception. */ -SQLITE_PRIVATE void tdsqlite3CodeRowTrigger( +SQLITE_PRIVATE void sqlite3CodeRowTrigger( Parse *pParse, /* Parse context */ Trigger *pTrigger, /* List of triggers on table pTab */ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ @@ -139630,7 +139630,7 @@ SQLITE_PRIVATE void tdsqlite3CodeRowTrigger( && p->tr_tm==tr_tm && checkColumnOverlap(p->pColumns, pChanges) ){ - tdsqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); + sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); } } } @@ -139660,7 +139660,7 @@ SQLITE_PRIVATE void tdsqlite3CodeRowTrigger( ** tr_tm parameter. Similarly, values accessed by AFTER triggers are only ** included in the returned mask if the TRIGGER_AFTER bit is set in tr_tm. */ -SQLITE_PRIVATE u32 tdsqlite3TriggerColmask( +SQLITE_PRIVATE u32 sqlite3TriggerColmask( Parse *pParse, /* Parse context */ Trigger *pTrigger, /* List of triggers on table pTab */ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ @@ -139744,32 +139744,32 @@ static void updateVirtualTable( ** into the sqlite_master table.) ** ** Therefore, the P4 parameter is only required if the default value for -** the column is a literal number, string or null. The tdsqlite3ValueFromExpr() +** the column is a literal number, string or null. The sqlite3ValueFromExpr() ** function is capable of transforming these types of expressions into -** tdsqlite3_value objects. +** sqlite3_value objects. ** ** If parameter iReg is not negative, code an OP_RealAffinity instruction ** on register iReg. This is used when an equivalent integer value is ** stored in place of an 8-byte floating point value in order to save ** space. */ -SQLITE_PRIVATE void tdsqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ assert( pTab!=0 ); if( !pTab->pSelect ){ - tdsqlite3_value *pValue = 0; - u8 enc = ENC(tdsqlite3VdbeDb(v)); + sqlite3_value *pValue = 0; + u8 enc = ENC(sqlite3VdbeDb(v)); Column *pCol = &pTab->aCol[i]; VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); assert( inCol ); - tdsqlite3ValueFromExpr(tdsqlite3VdbeDb(v), pCol->pDflt, enc, + sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, pCol->affinity, &pValue); if( pValue ){ - tdsqlite3VdbeAppendP4(v, pValue, P4_MEM); + sqlite3VdbeAppendP4(v, pValue, P4_MEM); } } #ifndef SQLITE_OMIT_FLOATING_POINT if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ - tdsqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); } #endif } @@ -139799,7 +139799,7 @@ static int indexColumnIsBeingUpdated( assert( iIdxCol==XN_EXPR ); assert( pIdx->aColExpr!=0 ); assert( pIdx->aColExpr->a[iCol].pExpr!=0 ); - return tdsqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr, + return sqlite3ExprReferencesUpdatedColumn(pIdx->aColExpr->a[iCol].pExpr, aXRef,chngRowid); } @@ -139821,7 +139821,7 @@ static int indexWhereClauseMightChange( int chngRowid /* true if the rowid is being updated */ ){ if( pIdx->pPartIdxWhere==0 ) return 0; - return tdsqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere, + return sqlite3ExprReferencesUpdatedColumn(pIdx->pPartIdxWhere, aXRef, chngRowid); } @@ -139832,7 +139832,7 @@ static int indexWhereClauseMightChange( ** \_______/ \________/ \______/ \________________/ * onError pTabList pChanges pWhere */ -SQLITE_PRIVATE void tdsqlite3Update( +SQLITE_PRIVATE void sqlite3Update( Parse *pParse, /* The parser context */ SrcList *pTabList, /* The table in which we should change things */ ExprList *pChanges, /* Things to be changed */ @@ -139854,7 +139854,7 @@ SQLITE_PRIVATE void tdsqlite3Update( int iBaseCur; /* Base cursor number */ int iDataCur; /* Cursor for the canonical data btree */ int iIdxCur; /* Cursor for the first index */ - tdsqlite3 *db; /* The database structure */ + sqlite3 *db; /* The database structure */ int *aRegIdx = 0; /* Registers for to each index and the main table */ int *aXRef = 0; /* aXRef[i] is the index in pChanges->a[] of the ** an expression for the i-th column of the table. @@ -139871,7 +139871,7 @@ SQLITE_PRIVATE void tdsqlite3Update( int hasFK; /* True if foreign key processing is required */ int labelBreak; /* Jump here to break out of UPDATE loop */ int labelContinue; /* Jump here to continue next step of UPDATE loop */ - int flags; /* Flags for tdsqlite3WhereBegin() */ + int flags; /* Flags for sqlite3WhereBegin() */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* True when updating a view (INSTEAD OF trigger) */ @@ -139906,15 +139906,15 @@ SQLITE_PRIVATE void tdsqlite3Update( /* Locate the table which we want to update. */ - pTab = tdsqlite3SrcListLookup(pParse, pTabList); + pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto update_cleanup; - iDb = tdsqlite3SchemaToIndex(pParse->db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); /* Figure out if we have any triggers and if the table being ** updated is a view. */ #ifndef SQLITE_OMIT_TRIGGER - pTrigger = tdsqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, &tmask); isView = pTab->pSelect!=0; assert( pTrigger || tmask==0 ); #else @@ -139929,7 +139929,7 @@ SQLITE_PRIVATE void tdsqlite3Update( #ifdef SQLITE_ENABLE_UPDATE_DELETE_LIMIT if( !isView ){ - pWhere = tdsqlite3LimitWhere( + pWhere = sqlite3LimitWhere( pParse, pTabList, pWhere, pOrderBy, pLimit, "UPDATE" ); pOrderBy = 0; @@ -139937,10 +139937,10 @@ SQLITE_PRIVATE void tdsqlite3Update( } #endif - if( tdsqlite3ViewGetColumnNames(pParse, pTab) ){ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto update_cleanup; } - if( tdsqlite3IsReadOnly(pParse, pTab, tmask) ){ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ goto update_cleanup; } @@ -139951,7 +139951,7 @@ SQLITE_PRIVATE void tdsqlite3Update( */ iBaseCur = iDataCur = pParse->nTab++; iIdxCur = iDataCur+1; - pPk = HasRowid(pTab) ? 0 : tdsqlite3PrimaryKeyIndex(pTab); + pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab); testcase( pPk!=0 && pPk!=pTab->pIndex ); for(nIdx=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, nIdx++){ if( pPk==pIdx ){ @@ -139970,7 +139970,7 @@ SQLITE_PRIVATE void tdsqlite3Update( /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. ** Initialize aXRef[] and aToOpen[] to their default values. */ - aXRef = tdsqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 ); + aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 ); if( aXRef==0 ) goto update_cleanup; aRegIdx = aXRef+pTab->nCol; aToOpen = (u8*)(aRegIdx+nIdx+1); @@ -139986,7 +139986,7 @@ SQLITE_PRIVATE void tdsqlite3Update( sNC.ncFlags = NC_UUpsert; /* Begin generating code. */ - v = tdsqlite3GetVdbe(pParse); + v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; /* Resolve the column names in all the expressions of the @@ -139997,11 +139997,11 @@ SQLITE_PRIVATE void tdsqlite3Update( */ chngRowid = chngPk = 0; for(i=0; inExpr; i++){ - if( tdsqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ + if( sqlite3ResolveExprNames(&sNC, pChanges->a[i].pExpr) ){ goto update_cleanup; } for(j=0; jnCol; j++){ - if( tdsqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zEName)==0 ){ + if( sqlite3StrICmp(pTab->aCol[j].zName, pChanges->a[i].zEName)==0 ){ if( j==pTab->iPKey ){ chngRowid = 1; pRowidExpr = pChanges->a[i].pExpr; @@ -140012,7 +140012,7 @@ SQLITE_PRIVATE void tdsqlite3Update( else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "cannot UPDATE generated column \"%s\"", pTab->aCol[j].zName); goto update_cleanup; @@ -140023,12 +140023,12 @@ SQLITE_PRIVATE void tdsqlite3Update( } } if( j>=pTab->nCol ){ - if( pPk==0 && tdsqlite3IsRowid(pChanges->a[i].zEName) ){ + if( pPk==0 && sqlite3IsRowid(pChanges->a[i].zEName) ){ j = -1; chngRowid = 1; pRowidExpr = pChanges->a[i].pExpr; }else{ - tdsqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zEName); + sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zEName); pParse->checkSchema = 1; goto update_cleanup; } @@ -140036,7 +140036,7 @@ SQLITE_PRIVATE void tdsqlite3Update( #ifndef SQLITE_OMIT_AUTHORIZATION { int rc; - rc = tdsqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, + rc = sqlite3AuthCheck(pParse, SQLITE_UPDATE, pTab->zName, j<0 ? "ROWID" : pTab->aCol[j].zName, db->aDb[iDb].zDbSName); if( rc==SQLITE_DENY ){ @@ -140069,7 +140069,7 @@ SQLITE_PRIVATE void tdsqlite3Update( for(i=0; inCol; i++){ if( aXRef[i]>=0 ) continue; if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ) continue; - if( tdsqlite3ExprReferencesUpdatedColumn(pTab->aCol[i].pDflt, + if( sqlite3ExprReferencesUpdatedColumn(pTab->aCol[i].pDflt, aXRef, chngRowid) ){ aXRef[i] = 99999; bProgress = 1; @@ -140086,7 +140086,7 @@ SQLITE_PRIVATE void tdsqlite3Update( */ pTabList->a[0].colUsed = IsVirtual(pTab) ? ALLBITS : 0; - hasFK = tdsqlite3FkRequired(pParse, pTab, aXRef, chngKey); + hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngKey); /* There is one entry in the aRegIdx[] array for each index on the table ** being updated. Fill in aRegIdx[] with a register number that will hold @@ -140123,8 +140123,8 @@ SQLITE_PRIVATE void tdsqlite3Update( memset(aToOpen, 1, nIdx+1); } - if( pParse->nested==0 ) tdsqlite3VdbeCountChanges(v); - tdsqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb); + if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); + sqlite3BeginWriteOperation(pParse, pTrigger || hasFK, iDb); /* Allocate required registers. */ if( !IsVirtual(pTab) ){ @@ -140149,7 +140149,7 @@ SQLITE_PRIVATE void tdsqlite3Update( /* Start the view context. */ if( isView ){ - tdsqlite3AuthContextPush(pParse, &sContext, pTab->zName); + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); } /* If we are trying to update a view, realize that view into @@ -140157,7 +140157,7 @@ SQLITE_PRIVATE void tdsqlite3Update( */ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ - tdsqlite3MaterializeView(pParse, pTab, + sqlite3MaterializeView(pParse, pTab, pWhere, pOrderBy, pLimit, iDataCur ); pOrderBy = 0; @@ -140168,7 +140168,7 @@ SQLITE_PRIVATE void tdsqlite3Update( /* Resolve the column names in all the expressions in the ** WHERE clause. */ - if( tdsqlite3ResolveExprNames(&sNC, pWhere) ){ + if( sqlite3ResolveExprNames(&sNC, pWhere) ){ goto update_cleanup; } @@ -140182,7 +140182,7 @@ SQLITE_PRIVATE void tdsqlite3Update( #endif /* Jump to labelBreak to abandon further processing of this UPDATE */ - labelContinue = labelBreak = tdsqlite3VdbeMakeLabel(pParse); + labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse); /* Not an UPSERT. Normal processing. Begin by ** initialize the count of updated rows */ @@ -140192,11 +140192,11 @@ SQLITE_PRIVATE void tdsqlite3Update( && pUpsert==0 ){ regRowCount = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); } if( HasRowid(pTab) ){ - tdsqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); + sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid); }else{ assert( pPk!=0 ); nPk = pPk->nKeyCol; @@ -140205,9 +140205,9 @@ SQLITE_PRIVATE void tdsqlite3Update( regKey = ++pParse->nMem; if( pUpsert==0 ){ iEph = pParse->nTab++; - tdsqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1); - addrOpen = tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); - tdsqlite3VdbeSetP4KeyInfo(pParse, pPk); + sqlite3VdbeAddOp3(v, OP_Null, 0, iPk, iPk+nPk-1); + addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); } } @@ -140219,7 +140219,7 @@ SQLITE_PRIVATE void tdsqlite3Update( */ pWInfo = 0; eOnePass = ONEPASS_SINGLE; - tdsqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL); bFinishSeek = 0; }else{ /* Begin the database scan. @@ -140233,7 +140233,7 @@ SQLITE_PRIVATE void tdsqlite3Update( if( !pParse->nested && !pTrigger && !hasFK && !chngKey && !bReplace ){ flags |= WHERE_ONEPASS_MULTIROW; } - pWInfo = tdsqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur); + pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, flags, iIdxCur); if( pWInfo==0 ) goto update_cleanup; /* A one-pass strategy that might update more than one row may not @@ -140246,10 +140246,10 @@ SQLITE_PRIVATE void tdsqlite3Update( ** Fall back to ONEPASS_OFF if where.c has selected a ONEPASS_MULTI ** strategy that uses an index for which one or more columns are being ** updated. */ - eOnePass = tdsqlite3WhereOkOnePass(pWInfo, aiCurOnePass); - bFinishSeek = tdsqlite3WhereUsesDeferredSeek(pWInfo); + eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); + bFinishSeek = sqlite3WhereUsesDeferredSeek(pWInfo); if( eOnePass!=ONEPASS_SINGLE ){ - tdsqlite3MultiWrite(pParse); + sqlite3MultiWrite(pParse); if( eOnePass==ONEPASS_MULTI ){ int iCur = aiCurOnePass[1]; if( iCur>=0 && iCur!=iDataCur && aToOpen[iCur-iBaseCur] ){ @@ -140264,11 +140264,11 @@ SQLITE_PRIVATE void tdsqlite3Update( /* Read the rowid of the current row of the WHERE scan. In ONEPASS_OFF ** mode, write the rowid into the FIFO. In either of the one-pass modes, ** leave it in register regOldRowid. */ - tdsqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); + sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regOldRowid); if( eOnePass==ONEPASS_OFF ){ /* We need to use regRowSet, so reallocate aRegIdx[nAllIdx] */ aRegIdx[nAllIdx] = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); + sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, regOldRowid); } }else{ /* Read the PK of the current row into an array of registers. In @@ -140278,23 +140278,23 @@ SQLITE_PRIVATE void tdsqlite3Update( ** is not required) and leave the PK fields in the array of registers. */ for(i=0; iaiColumn[i]>=0 ); - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i], iPk+i); } if( eOnePass ){ - if( addrOpen ) tdsqlite3VdbeChangeToNoop(v, addrOpen); + if( addrOpen ) sqlite3VdbeChangeToNoop(v, addrOpen); nKey = nPk; regKey = iPk; }else{ - tdsqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, - tdsqlite3IndexAffinityStr(db, pPk), nPk); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk); + sqlite3VdbeAddOp4(v, OP_MakeRecord, iPk, nPk, regKey, + sqlite3IndexAffinityStr(db, pPk), nPk); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iEph, regKey, iPk, nPk); } } if( pUpsert==0 ){ if( eOnePass!=ONEPASS_MULTI ){ - tdsqlite3WhereEnd(pWInfo); + sqlite3WhereEnd(pWInfo); } if( !isView ){ @@ -140307,37 +140307,37 @@ SQLITE_PRIVATE void tdsqlite3Update( } if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ - addrOnce = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } - tdsqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, + sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, aToOpen, 0, 0); - if( addrOnce ) tdsqlite3VdbeJumpHere(v, addrOnce); + if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); } /* Top of the update loop */ if( eOnePass!=ONEPASS_OFF ){ if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){ assert( pPk ); - tdsqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey); VdbeCoverage(v); } if( eOnePass!=ONEPASS_SINGLE ){ - labelContinue = tdsqlite3VdbeMakeLabel(pParse); + labelContinue = sqlite3VdbeMakeLabel(pParse); } - tdsqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); + sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak); VdbeCoverageIf(v, pPk==0); VdbeCoverageIf(v, pPk!=0); }else if( pPk ){ - labelContinue = tdsqlite3VdbeMakeLabel(pParse); - tdsqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); - addrTop = tdsqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey); - tdsqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); + labelContinue = sqlite3VdbeMakeLabel(pParse); + sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v); + addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0); VdbeCoverage(v); }else{ - labelContinue = tdsqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak, + labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak, regOldRowid); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); VdbeCoverage(v); } } @@ -140348,32 +140348,32 @@ SQLITE_PRIVATE void tdsqlite3Update( ** already populated. */ assert( chngKey || pTrigger || hasFK || regOldRowid==regNewRowid ); if( chngRowid ){ - tdsqlite3ExprCode(pParse, pRowidExpr, regNewRowid); - tdsqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v); + sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); VdbeCoverage(v); } /* Compute the old pre-UPDATE content of the row being changed, if that ** information is needed */ if( chngPk || hasFK || pTrigger ){ - u32 oldmask = (hasFK ? tdsqlite3FkOldmask(pParse, pTab) : 0); - oldmask |= tdsqlite3TriggerColmask(pParse, + u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0); + oldmask |= sqlite3TriggerColmask(pParse, pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError ); for(i=0; inCol; i++){ u32 colFlags = pTab->aCol[i].colFlags; - k = tdsqlite3TableColumnToStorage(pTab, i) + regOld; + k = sqlite3TableColumnToStorage(pTab, i) + regOld; if( oldmask==0xffffffff || (i<32 && (oldmask & MASKBIT32(i))!=0) || (colFlags & COLFLAG_PRIMKEY)!=0 ){ testcase( oldmask!=0xffffffff && i==31 ); - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); }else{ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, k); + sqlite3VdbeAddOp2(v, OP_Null, 0, k); } } if( chngRowid==0 && pPk==0 ){ - tdsqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); + sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); } } @@ -140390,18 +140390,18 @@ SQLITE_PRIVATE void tdsqlite3Update( ** may have modified them). So not loading those that are not going to ** be used eliminates some redundant opcodes. */ - newmask = tdsqlite3TriggerColmask( + newmask = sqlite3TriggerColmask( pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError ); for(i=0, k=regNew; inCol; i++, k++){ if( i==pTab->iPKey ){ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, k); + sqlite3VdbeAddOp2(v, OP_Null, 0, k); }else if( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)!=0 ){ if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--; }else{ j = aXRef[i]; if( j>=0 ){ - tdsqlite3ExprCode(pParse, pChanges->a[j].pExpr, k); + sqlite3ExprCode(pParse, pChanges->a[j].pExpr, k); }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){ /* This branch loads the value of a column that will not be changed ** into a register. This is done if there are no BEFORE triggers, or @@ -140410,10 +140410,10 @@ SQLITE_PRIVATE void tdsqlite3Update( */ testcase( i==31 ); testcase( i==32 ); - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); bFinishSeek = 0; }else{ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, k); + sqlite3VdbeAddOp2(v, OP_Null, 0, k); } } } @@ -140421,7 +140421,7 @@ SQLITE_PRIVATE void tdsqlite3Update( if( pTab->tabFlags & TF_HasGenerated ){ testcase( pTab->tabFlags & TF_HasVirtual ); testcase( pTab->tabFlags & TF_HasStored ); - tdsqlite3ComputeGeneratedColumns(pParse, regNew, pTab); + sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); } #endif @@ -140429,8 +140429,8 @@ SQLITE_PRIVATE void tdsqlite3Update( ** verified. One could argue that this is wrong. */ if( tmask&TRIGGER_BEFORE ){ - tdsqlite3TableAffinity(v, pTab, regNew); - tdsqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + sqlite3TableAffinity(v, pTab, regNew); + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue); /* The row-trigger may have deleted the row being updated. In this @@ -140440,10 +140440,10 @@ SQLITE_PRIVATE void tdsqlite3Update( ** documentation. */ if( pPk ){ - tdsqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey); + sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue,regKey,nKey); VdbeCoverage(v); }else{ - tdsqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue, regOldRowid); VdbeCoverage(v); } @@ -140460,14 +140460,14 @@ SQLITE_PRIVATE void tdsqlite3Update( if( pTab->aCol[i].colFlags & COLFLAG_GENERATED ){ if( pTab->aCol[i].colFlags & COLFLAG_VIRTUAL ) k--; }else if( aXRef[i]<0 && i!=pTab->iPKey ){ - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, k); } } #ifndef SQLITE_OMIT_GENERATED_COLUMNS if( pTab->tabFlags & TF_HasGenerated ){ testcase( pTab->tabFlags & TF_HasVirtual ); testcase( pTab->tabFlags & TF_HasStored ); - tdsqlite3ComputeGeneratedColumns(pParse, regNew, pTab); + sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); } #endif } @@ -140475,7 +140475,7 @@ SQLITE_PRIVATE void tdsqlite3Update( if( !isView ){ /* Do constraint checks. */ assert( regOldRowid>0 ); - tdsqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, + sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace, aXRef, 0); @@ -140484,20 +140484,20 @@ SQLITE_PRIVATE void tdsqlite3Update( ** moved cursor iDataCur. Reseek it. */ if( bReplace || chngKey ){ if( pPk ){ - tdsqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); + sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); }else{ - tdsqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); } VdbeCoverageNeverTaken(v); } /* Do FK constraint checks. */ if( hasFK ){ - tdsqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); + sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); } /* Delete the index entries associated with the current record. */ - tdsqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1); + sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1); /* We must run the OP_FinishSeek opcode to resolve a prior ** OP_DeferredSeek if there is any possibility that there have been @@ -140505,7 +140505,7 @@ SQLITE_PRIVATE void tdsqlite3Update( ** we want to avoid the OP_FinishSeek if possible, as running it ** costs CPU cycles. */ if( bFinishSeek ){ - tdsqlite3VdbeAddOp1(v, OP_FinishSeek, iDataCur); + sqlite3VdbeAddOp1(v, OP_FinishSeek, iDataCur); } /* If changing the rowid value, or if there are foreign key constraints @@ -140519,29 +140519,29 @@ SQLITE_PRIVATE void tdsqlite3Update( */ assert( regNew==regNewRowid+1 ); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK - tdsqlite3VdbeAddOp3(v, OP_Delete, iDataCur, + sqlite3VdbeAddOp3(v, OP_Delete, iDataCur, OPFLAG_ISUPDATE | ((hasFK>1 || chngKey) ? 0 : OPFLAG_ISNOOP), regNewRowid ); if( eOnePass==ONEPASS_MULTI ){ assert( hasFK==0 && chngKey==0 ); - tdsqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); } if( !pParse->nested ){ - tdsqlite3VdbeAppendP4(v, pTab, P4_TABLE); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); } #else if( hasFK>1 || chngKey ){ - tdsqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); + sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); } #endif if( hasFK ){ - tdsqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); + sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); } /* Insert the new index entries and the new record. */ - tdsqlite3CompleteInsertion( + sqlite3CompleteInsertion( pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx, OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0), 0, 0 @@ -140551,17 +140551,17 @@ SQLITE_PRIVATE void tdsqlite3Update( ** handle rows (possibly in other tables) that refer via a foreign key ** to the row just updated. */ if( hasFK ){ - tdsqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey); + sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey); } } /* Increment the row counter */ if( regRowCount ){ - tdsqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } - tdsqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); /* Repeat the above with the next record to be updated, until @@ -140570,22 +140570,22 @@ SQLITE_PRIVATE void tdsqlite3Update( if( eOnePass==ONEPASS_SINGLE ){ /* Nothing to do at end-of-loop for a single-pass */ }else if( eOnePass==ONEPASS_MULTI ){ - tdsqlite3VdbeResolveLabel(v, labelContinue); - tdsqlite3WhereEnd(pWInfo); + sqlite3VdbeResolveLabel(v, labelContinue); + sqlite3WhereEnd(pWInfo); }else if( pPk ){ - tdsqlite3VdbeResolveLabel(v, labelContinue); - tdsqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); + sqlite3VdbeResolveLabel(v, labelContinue); + sqlite3VdbeAddOp2(v, OP_Next, iEph, addrTop); VdbeCoverage(v); }else{ - tdsqlite3VdbeGoto(v, labelContinue); + sqlite3VdbeGoto(v, labelContinue); } - tdsqlite3VdbeResolveLabel(v, labelBreak); + sqlite3VdbeResolveLabel(v, labelBreak); /* Update the sqlite_sequence table by storing the content of the ** maximum rowid counter values recorded while inserting into ** autoincrement tables. */ if( pParse->nested==0 && pParse->pTriggerTab==0 && pUpsert==0 ){ - tdsqlite3AutoincrementEnd(pParse); + sqlite3AutoincrementEnd(pParse); } /* @@ -140593,20 +140593,20 @@ SQLITE_PRIVATE void tdsqlite3Update( ** that information. */ if( regRowCount ){ - tdsqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); - tdsqlite3VdbeSetNumCols(v, 1); - tdsqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); + sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); + sqlite3VdbeSetNumCols(v, 1); + sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); } update_cleanup: - tdsqlite3AuthContextPop(&sContext); - tdsqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ - tdsqlite3SrcListDelete(db, pTabList); - tdsqlite3ExprListDelete(db, pChanges); - tdsqlite3ExprDelete(db, pWhere); + sqlite3AuthContextPop(&sContext); + sqlite3DbFree(db, aXRef); /* Also frees aRegIdx[] and aToOpen[] */ + sqlite3SrcListDelete(db, pTabList); + sqlite3ExprListDelete(db, pChanges); + sqlite3ExprDelete(db, pWhere); #if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) - tdsqlite3ExprListDelete(db, pOrderBy); - tdsqlite3ExprDelete(db, pLimit); + sqlite3ExprListDelete(db, pOrderBy); + sqlite3ExprDelete(db, pLimit); #endif return; } @@ -140655,15 +140655,15 @@ static void updateVirtualTable( Vdbe *v = pParse->pVdbe; /* Virtual machine under construction */ int ephemTab; /* Table holding the result of the SELECT */ int i; /* Loop counter */ - tdsqlite3 *db = pParse->db; /* Database connection */ - const char *pVTab = (const char*)tdsqlite3GetVTable(db, pTab); + sqlite3 *db = pParse->db; /* Database connection */ + const char *pVTab = (const char*)sqlite3GetVTable(db, pTab); WhereInfo *pWInfo; int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */ int regArg; /* First register in VUpdate arg array */ int regRec; /* Register in which to assemble record */ int regRowid; /* Register for ephem table rowid */ int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ - int aDummy[2]; /* Unused arg for tdsqlite3WhereOkOnePass() */ + int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ int eOnePass; /* True to use onepass strategy */ int addr; /* Address of OP_OpenEphemeral */ @@ -140672,45 +140672,45 @@ static void updateVirtualTable( ** these arguments will be temporarily stored. */ assert( v ); ephemTab = pParse->nTab++; - addr= tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg); + addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg); regArg = pParse->nMem + 1; pParse->nMem += nArg; regRec = ++pParse->nMem; regRowid = ++pParse->nMem; /* Start scanning the virtual table */ - pWInfo = tdsqlite3WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0); + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0); if( pWInfo==0 ) return; /* Populate the argument registers. */ for(i=0; inCol; i++){ assert( (pTab->aCol[i].colFlags & COLFLAG_GENERATED)==0 ); if( aXRef[i]>=0 ){ - tdsqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); + sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i); }else{ - tdsqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); - tdsqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable tdsqlite3_vtab_nochange() */ + sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i); + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG);/* Enable sqlite3_vtab_nochange() */ } } if( HasRowid(pTab) ){ - tdsqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); + sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg); if( pRowid ){ - tdsqlite3ExprCode(pParse, pRowid, regArg+1); + sqlite3ExprCode(pParse, pRowid, regArg+1); }else{ - tdsqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); + sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1); } }else{ Index *pPk; /* PRIMARY KEY index */ i16 iPk; /* PRIMARY KEY column */ - pPk = tdsqlite3PrimaryKeyIndex(pTab); + pPk = sqlite3PrimaryKeyIndex(pTab); assert( pPk!=0 ); assert( pPk->nKeyCol==1 ); iPk = pPk->aiColumn[0]; - tdsqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg); - tdsqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1); + sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, iPk, regArg); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg+2+iPk, regArg+1); } - eOnePass = tdsqlite3WhereOkOnePass(pWInfo, aDummy); + eOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy); /* There is no ONEPASS_MULTI on virtual tables */ assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE ); @@ -140718,49 +140718,49 @@ static void updateVirtualTable( if( eOnePass ){ /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded ** above. */ - tdsqlite3VdbeChangeToNoop(v, addr); - tdsqlite3VdbeAddOp1(v, OP_Close, iCsr); + sqlite3VdbeChangeToNoop(v, addr); + sqlite3VdbeAddOp1(v, OP_Close, iCsr); }else{ /* Create a record from the argument register contents and insert it into ** the ephemeral table. */ - tdsqlite3MultiWrite(pParse); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); + sqlite3MultiWrite(pParse); + sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec); #ifdef SQLITE_DEBUG /* Signal an assert() within OP_MakeRecord that it is allowed to ** accept no-change records with serial_type 10 */ - tdsqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); #endif - tdsqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); - tdsqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); + sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid); } if( eOnePass==ONEPASS_OFF ){ /* End the virtual table scan */ - tdsqlite3WhereEnd(pWInfo); + sqlite3WhereEnd(pWInfo); /* Begin scannning through the ephemeral table. */ - addr = tdsqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); + addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v); /* Extract arguments from the current row of the ephemeral table and ** invoke the VUpdate method. */ for(i=0; ipUpsertTarget); - tdsqlite3ExprDelete(db, p->pUpsertTargetWhere); - tdsqlite3ExprListDelete(db, p->pUpsertSet); - tdsqlite3ExprDelete(db, p->pUpsertWhere); - tdsqlite3DbFree(db, p); + sqlite3ExprListDelete(db, p->pUpsertTarget); + sqlite3ExprDelete(db, p->pUpsertTargetWhere); + sqlite3ExprListDelete(db, p->pUpsertSet); + sqlite3ExprDelete(db, p->pUpsertWhere); + sqlite3DbFree(db, p); } } /* ** Duplicate an Upsert object. */ -SQLITE_PRIVATE Upsert *tdsqlite3UpsertDup(tdsqlite3 *db, Upsert *p){ +SQLITE_PRIVATE Upsert *sqlite3UpsertDup(sqlite3 *db, Upsert *p){ if( p==0 ) return 0; - return tdsqlite3UpsertNew(db, - tdsqlite3ExprListDup(db, p->pUpsertTarget, 0), - tdsqlite3ExprDup(db, p->pUpsertTargetWhere, 0), - tdsqlite3ExprListDup(db, p->pUpsertSet, 0), - tdsqlite3ExprDup(db, p->pUpsertWhere, 0) + return sqlite3UpsertNew(db, + sqlite3ExprListDup(db, p->pUpsertTarget, 0), + sqlite3ExprDup(db, p->pUpsertTargetWhere, 0), + sqlite3ExprListDup(db, p->pUpsertSet, 0), + sqlite3ExprDup(db, p->pUpsertWhere, 0) ); } /* ** Create a new Upsert object. */ -SQLITE_PRIVATE Upsert *tdsqlite3UpsertNew( - tdsqlite3 *db, /* Determines which memory allocator to use */ +SQLITE_PRIVATE Upsert *sqlite3UpsertNew( + sqlite3 *db, /* Determines which memory allocator to use */ ExprList *pTarget, /* Target argument to ON CONFLICT, or NULL */ Expr *pTargetWhere, /* Optional WHERE clause on the target */ ExprList *pSet, /* UPDATE columns, or NULL for a DO NOTHING */ Expr *pWhere /* WHERE clause for the ON CONFLICT UPDATE */ ){ Upsert *pNew; - pNew = tdsqlite3DbMallocRaw(db, sizeof(Upsert)); + pNew = sqlite3DbMallocRaw(db, sizeof(Upsert)); if( pNew==0 ){ - tdsqlite3ExprListDelete(db, pTarget); - tdsqlite3ExprDelete(db, pTargetWhere); - tdsqlite3ExprListDelete(db, pSet); - tdsqlite3ExprDelete(db, pWhere); + sqlite3ExprListDelete(db, pTarget); + sqlite3ExprDelete(db, pTargetWhere); + sqlite3ExprListDelete(db, pSet); + sqlite3ExprDelete(db, pWhere); return 0; }else{ pNew->pUpsertTarget = pTarget; @@ -140845,7 +140845,7 @@ SQLITE_PRIVATE Upsert *tdsqlite3UpsertNew( ** Return SQLITE_OK if everything works, or an error code is something ** is wrong. */ -SQLITE_PRIVATE int tdsqlite3UpsertAnalyzeTarget( +SQLITE_PRIVATE int sqlite3UpsertAnalyzeTarget( Parse *pParse, /* The parsing context */ SrcList *pTabList, /* Table into which we are inserting */ Upsert *pUpsert /* The ON CONFLICT clauses */ @@ -140871,9 +140871,9 @@ SQLITE_PRIVATE int tdsqlite3UpsertAnalyzeTarget( memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; sNC.pSrcList = pTabList; - rc = tdsqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); + rc = sqlite3ResolveExprListNames(&sNC, pUpsert->pUpsertTarget); if( rc ) return rc; - rc = tdsqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); + rc = sqlite3ResolveExprNames(&sNC, pUpsert->pUpsertTargetWhere); if( rc ) return rc; /* Check to see if the conflict target matches the rowid. */ @@ -140909,7 +140909,7 @@ SQLITE_PRIVATE int tdsqlite3UpsertAnalyzeTarget( if( pTarget->nExpr!=pIdx->nKeyCol ) continue; if( pIdx->pPartIdxWhere ){ if( pUpsert->pUpsertTargetWhere==0 ) continue; - if( tdsqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, + if( sqlite3ExprCompare(pParse, pUpsert->pUpsertTargetWhere, pIdx->pPartIdxWhere, iCursor)!=0 ){ continue; } @@ -140932,7 +140932,7 @@ SQLITE_PRIVATE int tdsqlite3UpsertAnalyzeTarget( pExpr = &sCol[0]; } for(jj=0; jja[jj].pExpr, pExpr,iCursor)<2 ){ + if( sqlite3ExprCompare(pParse, pTarget->a[jj].pExpr, pExpr,iCursor)<2 ){ break; /* Column ii of the index matches column jj of target */ } } @@ -140949,7 +140949,7 @@ SQLITE_PRIVATE int tdsqlite3UpsertAnalyzeTarget( pUpsert->pUpsertIdx = pIdx; return SQLITE_OK; } - tdsqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any " + sqlite3ErrorMsg(pParse, "ON CONFLICT clause does not match any " "PRIMARY KEY or UNIQUE constraint"); return SQLITE_ERROR; } @@ -140963,7 +140963,7 @@ SQLITE_PRIVATE int tdsqlite3UpsertAnalyzeTarget( ** is not NULL, then pIdx is the constraint that failed and iCur is a ** cursor points to the conflicting row. */ -SQLITE_PRIVATE void tdsqlite3UpsertDoUpdate( +SQLITE_PRIVATE void sqlite3UpsertDoUpdate( Parse *pParse, /* The parsing and code-generating context */ Upsert *pUpsert, /* The ON CONFLICT clause for the upsert */ Table *pTab, /* The table being updated */ @@ -140971,7 +140971,7 @@ SQLITE_PRIVATE void tdsqlite3UpsertDoUpdate( int iCur /* Cursor for pIdx (or pTab if pIdx==NULL) */ ){ Vdbe *v = pParse->pVdbe; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; SrcList *pSrc; /* FROM clause for the UPDATE */ int iDataCur; int i; @@ -140982,46 +140982,46 @@ SQLITE_PRIVATE void tdsqlite3UpsertDoUpdate( iDataCur = pUpsert->iDataCur; if( pIdx && iCur!=iDataCur ){ if( HasRowid(pTab) ){ - int regRowid = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid); - tdsqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid); + int regRowid = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_IdxRowid, iCur, regRowid); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iDataCur, 0, regRowid); VdbeCoverage(v); - tdsqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regRowid); }else{ - Index *pPk = tdsqlite3PrimaryKeyIndex(pTab); + Index *pPk = sqlite3PrimaryKeyIndex(pTab); int nPk = pPk->nKeyCol; int iPk = pParse->nMem+1; pParse->nMem += nPk; for(i=0; iaiColumn[i]>=0 ); - k = tdsqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); - tdsqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[i]); + sqlite3VdbeAddOp3(v, OP_Column, iCur, k, iPk+i); VdbeComment((v, "%s.%s", pIdx->zName, pTab->aCol[pPk->aiColumn[i]].zName)); } - tdsqlite3VdbeVerifyAbortable(v, OE_Abort); - i = tdsqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); + sqlite3VdbeVerifyAbortable(v, OE_Abort); + i = sqlite3VdbeAddOp4Int(v, OP_Found, iDataCur, 0, iPk, nPk); VdbeCoverage(v); - tdsqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CORRUPT, OE_Abort, 0, "corrupt database", P4_STATIC); - tdsqlite3MayAbort(pParse); - tdsqlite3VdbeJumpHere(v, i); + sqlite3MayAbort(pParse); + sqlite3VdbeJumpHere(v, i); } } /* pUpsert does not own pUpsertSrc - the outer INSERT statement does. So - ** we have to make a copy before passing it down into tdsqlite3Update() */ - pSrc = tdsqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0); + ** we have to make a copy before passing it down into sqlite3Update() */ + pSrc = sqlite3SrcListDup(db, pUpsert->pUpsertSrc, 0); /* excluded.* columns of type REAL need to be converted to a hard real */ for(i=0; inCol; i++){ if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ - tdsqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i); + sqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i); } } - tdsqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, + sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert); - pUpsert->pUpsertSet = 0; /* Will have been deleted by tdsqlite3Update() */ - pUpsert->pUpsertWhere = 0; /* Will have been deleted by tdsqlite3Update() */ + pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */ + pUpsert->pUpsertWhere = 0; /* Will have been deleted by sqlite3Update() */ VdbeNoopComment((v, "End DO UPDATE of UPSERT")); } @@ -141060,16 +141060,16 @@ SQLITE_PRIVATE void tdsqlite3UpsertDoUpdate( ** The execSqlF() routine does the same thing, except it accepts ** a format string as its third argument */ -static int execSql(tdsqlite3 *db, char **pzErrMsg, const char *zSql){ - tdsqlite3_stmt *pStmt; +static int execSql(sqlite3 *db, char **pzErrMsg, const char *zSql){ + sqlite3_stmt *pStmt; int rc; /* printf("SQL: [%s]\n", zSql); fflush(stdout); */ - rc = tdsqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; - while( SQLITE_ROW==(rc = tdsqlite3_step(pStmt)) ){ - const char *zSubSql = (const char*)tdsqlite3_column_text(pStmt,0); - assert( tdsqlite3_strnicmp(zSql,"SELECT",6)==0 ); + while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ + const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0); + assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 ); /* The secondary SQL must be one of CREATE TABLE, CREATE INDEX, ** or INSERT. Historically there have been attacks that first ** corrupt the sqlite_master.sql field with other kinds of statements @@ -141085,21 +141085,21 @@ static int execSql(tdsqlite3 *db, char **pzErrMsg, const char *zSql){ assert( rc!=SQLITE_ROW ); if( rc==SQLITE_DONE ) rc = SQLITE_OK; if( rc ){ - tdsqlite3SetString(pzErrMsg, db, tdsqlite3_errmsg(db)); + sqlite3SetString(pzErrMsg, db, sqlite3_errmsg(db)); } - (void)tdsqlite3_finalize(pStmt); + (void)sqlite3_finalize(pStmt); return rc; } -static int execSqlF(tdsqlite3 *db, char **pzErrMsg, const char *zSql, ...){ +static int execSqlF(sqlite3 *db, char **pzErrMsg, const char *zSql, ...){ char *z; va_list ap; int rc; va_start(ap, zSql); - z = tdsqlite3VMPrintf(db, zSql, ap); + z = sqlite3VMPrintf(db, zSql, ap); va_end(ap); if( z==0 ) return SQLITE_NOMEM; rc = execSql(db, pzErrMsg, z); - tdsqlite3DbFree(db, z); + sqlite3DbFree(db, z); return rc; } @@ -141133,8 +141133,8 @@ static int execSqlF(tdsqlite3 *db, char **pzErrMsg, const char *zSql, ...){ ** transient would cause the database file to appear to be deleted ** following reboot. */ -SQLITE_PRIVATE void tdsqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ - Vdbe *v = tdsqlite3GetVdbe(pParse); +SQLITE_PRIVATE void sqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ + Vdbe *v = sqlite3GetVdbe(pParse); int iDb = 0; if( v==0 ) goto build_vacuum_end; if( pParse->nErr ) goto build_vacuum_end; @@ -141142,7 +141142,7 @@ SQLITE_PRIVATE void tdsqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ #ifndef SQLITE_BUG_COMPATIBLE_20160819 /* Default behavior: Report an error if the argument to VACUUM is ** not recognized */ - iDb = tdsqlite3TwoPartName(pParse, pNm, pNm, &pNm); + iDb = sqlite3TwoPartName(pParse, pNm, pNm, &pNm); if( iDb<0 ) goto build_vacuum_end; #else /* When SQLITE_BUG_COMPATIBLE_20160819 is defined, unrecognized arguments @@ -141150,32 +141150,32 @@ SQLITE_PRIVATE void tdsqlite3Vacuum(Parse *pParse, Token *pNm, Expr *pInto){ ** occurred on 2016-08-19 (https://www.sqlite.org/src/info/083f9e6270). ** The buggy behavior is required for binary compatibility with some ** legacy applications. */ - iDb = tdsqlite3FindDb(pParse->db, pNm); + iDb = sqlite3FindDb(pParse->db, pNm); if( iDb<0 ) iDb = 0; #endif } if( iDb!=1 ){ int iIntoReg = 0; - if( pInto && tdsqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){ + if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){ iIntoReg = ++pParse->nMem; - tdsqlite3ExprCode(pParse, pInto, iIntoReg); + sqlite3ExprCode(pParse, pInto, iIntoReg); } - tdsqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg); - tdsqlite3VdbeUsesBtree(v, iDb); + sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg); + sqlite3VdbeUsesBtree(v, iDb); } build_vacuum_end: - tdsqlite3ExprDelete(pParse->db, pInto); + sqlite3ExprDelete(pParse->db, pInto); return; } /* ** This routine implements the OP_Vacuum opcode of the VDBE. */ -SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3RunVacuum( +SQLITE_PRIVATE SQLITE_NOINLINE int sqlite3RunVacuum( char **pzErrMsg, /* Write error message here */ - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ int iDb, /* Which attached DB to vacuum */ - tdsqlite3_value *pOut /* Write results here, if not NULL. VACUUM INTO */ + sqlite3_value *pOut /* Write results here, if not NULL. VACUUM INTO */ ){ int rc = SQLITE_OK; /* Return code from service routines */ Btree *pMain; /* The database being vacuumed */ @@ -141194,20 +141194,20 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3RunVacuum( const char *zOut; /* Name of output file */ if( !db->autoCommit ){ - tdsqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); + sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction"); return SQLITE_ERROR; /* IMP: R-12218-18073 */ } if( db->nVdbeActive>1 ){ - tdsqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); + sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress"); return SQLITE_ERROR; /* IMP: R-15610-35227 */ } saved_openFlags = db->openFlags; if( pOut ){ - if( tdsqlite3_value_type(pOut)!=SQLITE_TEXT ){ - tdsqlite3SetString(pzErrMsg, db, "non-text filename"); + if( sqlite3_value_type(pOut)!=SQLITE_TEXT ){ + sqlite3SetString(pzErrMsg, db, "non-text filename"); return SQLITE_ERROR; } - zOut = (const char*)tdsqlite3_value_text(pOut); + zOut = (const char*)sqlite3_value_text(pOut); db->openFlags &= ~SQLITE_OPEN_READONLY; db->openFlags |= SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE; }else{ @@ -141230,13 +141230,13 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3RunVacuum( zDbMain = db->aDb[iDb].zDbSName; pMain = db->aDb[iDb].pBt; - isMemDb = tdsqlite3PagerIsMemdb(tdsqlite3BtreePager(pMain)); + isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); /* Attach the temporary database as 'vacuum_db'. The synchronous pragma ** can be set to 'off' for this file, as it is not recovered if a crash ** occurs anyway. The integrity of the database is maintained by a ** (possibly synchronous) transaction opened on the main database before - ** tdsqlite3BtreeCopyFile() is called. + ** sqlite3BtreeCopyFile() is called. ** ** An optimisation would be to use a non-journaled pager. ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but @@ -141255,49 +141255,49 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3RunVacuum( assert( strcmp(pDb->zDbSName,"vacuum_db")==0 ); pTemp = pDb->pBt; if( pOut ){ - tdsqlite3_file *id = tdsqlite3PagerFile(tdsqlite3BtreePager(pTemp)); + sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp)); i64 sz = 0; - if( id->pMethods!=0 && (tdsqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){ + if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){ rc = SQLITE_ERROR; - tdsqlite3SetString(pzErrMsg, db, "output file already exists"); + sqlite3SetString(pzErrMsg, db, "output file already exists"); goto end_of_vacuum; } db->mDbFlags |= DBFLAG_VacuumInto; } - nRes = tdsqlite3BtreeGetOptimalReserve(pMain); + nRes = sqlite3BtreeGetOptimalReserve(pMain); /* A VACUUM cannot change the pagesize of an encrypted database. */ #ifdef SQLITE_HAS_CODEC if( db->nextPagesize ){ - extern void tdsqlite3CodecGetKey(tdsqlite3*, int, void**, int*); + extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); int nKey; char *zKey; - tdsqlite3CodecGetKey(db, iDb, (void**)&zKey, &nKey); + sqlite3CodecGetKey(db, iDb, (void**)&zKey, &nKey); if( nKey ) db->nextPagesize = 0; } #endif - tdsqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); - tdsqlite3BtreeSetSpillSize(pTemp, tdsqlite3BtreeSetSpillSize(pMain,0)); - tdsqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL); + sqlite3BtreeSetCacheSize(pTemp, db->aDb[iDb].pSchema->cache_size); + sqlite3BtreeSetSpillSize(pTemp, sqlite3BtreeSetSpillSize(pMain,0)); + sqlite3BtreeSetPagerFlags(pTemp, PAGER_SYNCHRONOUS_OFF|PAGER_CACHESPILL); /* Begin a transaction and take an exclusive lock on the main database - ** file. This is done before the tdsqlite3BtreeGetPageSize(pMain) call below, + ** file. This is done before the sqlite3BtreeGetPageSize(pMain) call below, ** to ensure that we do not try to change the page-size on a WAL database. */ rc = execSql(db, pzErrMsg, "BEGIN"); if( rc!=SQLITE_OK ) goto end_of_vacuum; - rc = tdsqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0); + rc = sqlite3BtreeBeginTrans(pMain, pOut==0 ? 2 : 0, 0); if( rc!=SQLITE_OK ) goto end_of_vacuum; /* Do not attempt to change the page size for a WAL database */ - if( tdsqlite3PagerGetJournalMode(tdsqlite3BtreePager(pMain)) + if( sqlite3PagerGetJournalMode(sqlite3BtreePager(pMain)) ==PAGER_JOURNALMODE_WAL ){ db->nextPagesize = 0; } - if( tdsqlite3BtreeSetPageSize(pTemp, tdsqlite3BtreeGetPageSize(pMain), nRes, 0) - || (!isMemDb && tdsqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0)) + if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes, 0) + || (!isMemDb && sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes, 0)) || NEVER(db->mallocFailed) ){ rc = SQLITE_NOMEM_BKPT; @@ -141305,8 +141305,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3RunVacuum( } #ifndef SQLITE_OMIT_AUTOVACUUM - tdsqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac : - tdsqlite3BtreeGetAutoVacuum(pMain)); + sqlite3BtreeSetAutoVacuum(pTemp, db->nextAutovac>=0 ? db->nextAutovac : + sqlite3BtreeGetAutoVacuum(pMain)); #endif /* Query the schema of the main database. Create a mirror schema @@ -141360,8 +141360,8 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3RunVacuum( /* At this point, there is a write transaction open on both the ** vacuum database and the main database. Assuming no error occurs, ** both transactions are closed by this block - the main database - ** transaction by tdsqlite3BtreeCopyFile() and the other by an explicit - ** call to tdsqlite3BtreeCommit(). + ** transaction by sqlite3BtreeCopyFile() and the other by an explicit + ** call to sqlite3BtreeCommit(). */ { u32 meta; @@ -141381,34 +141381,34 @@ SQLITE_PRIVATE SQLITE_NOINLINE int tdsqlite3RunVacuum( BTREE_APPLICATION_ID, 0, /* Preserve the application id */ }; - assert( 1==tdsqlite3BtreeIsInTrans(pTemp) ); - assert( pOut!=0 || 1==tdsqlite3BtreeIsInTrans(pMain) ); + assert( 1==sqlite3BtreeIsInTrans(pTemp) ); + assert( pOut!=0 || 1==sqlite3BtreeIsInTrans(pMain) ); /* Copy Btree meta values */ for(i=0; inChange = saved_nChange; db->nTotalChange = saved_nTotalChange; db->mTrace = saved_mTrace; - tdsqlite3BtreeSetPageSize(pMain, -1, -1, 1); + sqlite3BtreeSetPageSize(pMain, -1, -1, 1); /* Currently there is an SQL level transaction open on the vacuum ** database. No locks are held on any other files (since the main file @@ -141431,14 +141431,14 @@ end_of_vacuum: db->autoCommit = 1; if( pDb ){ - tdsqlite3BtreeClose(pDb->pBt); + sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; } /* This both clears the schemas and reduces the size of the db->aDb[] ** array. */ - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ResetAllSchemasOfConnection(db); return rc; } @@ -141467,14 +141467,14 @@ end_of_vacuum: ** Before a virtual table xCreate() or xConnect() method is invoked, the ** sqlite3.pVtabCtx member variable is set to point to an instance of ** this struct allocated on the stack. It is used by the implementation of -** the tdsqlite3_declare_vtab() and tdsqlite3_vtab_config() APIs, both of which +** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which ** are invoked only from within xCreate and xConnect methods. */ struct VtabCtx { VTable *pVTable; /* The virtual table being constructed */ Table *pTab; /* The Table object to which the virtual table belongs */ VtabCtx *pPrior; /* Parent context (if any) */ - int bDeclared; /* True after tdsqlite3_declare_vtab() is called */ + int bDeclared; /* True after sqlite3_declare_vtab() is called */ }; /* @@ -141485,10 +141485,10 @@ struct VtabCtx { ** If there already exists a module with zName, replace it with the new one. ** If pModule==0, then delete the module zName if it exists. */ -SQLITE_PRIVATE Module *tdsqlite3VtabCreateModule( - tdsqlite3 *db, /* Database in which module is registered */ +SQLITE_PRIVATE Module *sqlite3VtabCreateModule( + sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ - const tdsqlite3_module *pModule, /* The definition of the module */ + const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ @@ -141499,10 +141499,10 @@ SQLITE_PRIVATE Module *tdsqlite3VtabCreateModule( zCopy = (char*)zName; pMod = 0; }else{ - int nName = tdsqlite3Strlen30(zName); - pMod = (Module *)tdsqlite3Malloc(sizeof(Module) + nName + 1); + int nName = sqlite3Strlen30(zName); + pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); if( pMod==0 ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); return 0; } zCopy = (char *)(&pMod[1]); @@ -141514,15 +141514,15 @@ SQLITE_PRIVATE Module *tdsqlite3VtabCreateModule( pMod->pEpoTab = 0; pMod->nRefModule = 1; } - pDel = (Module *)tdsqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); if( pDel ){ if( pDel==pMod ){ - tdsqlite3OomFault(db); - tdsqlite3DbFree(db, pDel); + sqlite3OomFault(db); + sqlite3DbFree(db, pDel); pMod = 0; }else{ - tdsqlite3VtabEponymousTableClear(db, pDel); - tdsqlite3VtabModuleUnref(db, pDel); + sqlite3VtabEponymousTableClear(db, pDel); + sqlite3VtabModuleUnref(db, pDel); } } return pMod; @@ -141530,23 +141530,23 @@ SQLITE_PRIVATE Module *tdsqlite3VtabCreateModule( /* ** The actual function that does the work of creating a new module. -** This function implements the tdsqlite3_create_module() and -** tdsqlite3_create_module_v2() interfaces. +** This function implements the sqlite3_create_module() and +** sqlite3_create_module_v2() interfaces. */ static int createModule( - tdsqlite3 *db, /* Database in which module is registered */ + sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ - const tdsqlite3_module *pModule, /* The definition of the module */ + const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ int rc = SQLITE_OK; - tdsqlite3_mutex_enter(db->mutex); - (void)tdsqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); - rc = tdsqlite3ApiExit(db, rc); + sqlite3_mutex_enter(db->mutex); + (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); + rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -141554,14 +141554,14 @@ static int createModule( /* ** External API function used to create a new virtual-table module. */ -SQLITE_API int tdsqlite3_create_module( - tdsqlite3 *db, /* Database in which module is registered */ +SQLITE_API int sqlite3_create_module( + sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ - const tdsqlite3_module *pModule, /* The definition of the module */ + const sqlite3_module *pModule, /* The definition of the module */ void *pAux /* Context pointer for xCreate/xConnect */ ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; #endif return createModule(db, zName, pModule, pAux, 0); } @@ -141569,15 +141569,15 @@ SQLITE_API int tdsqlite3_create_module( /* ** External API function used to create a new virtual-table module. */ -SQLITE_API int tdsqlite3_create_module_v2( - tdsqlite3 *db, /* Database in which module is registered */ +SQLITE_API int sqlite3_create_module_v2( + sqlite3 *db, /* Database in which module is registered */ const char *zName, /* Name assigned to this module */ - const tdsqlite3_module *pModule, /* The definition of the module */ + const sqlite3_module *pModule, /* The definition of the module */ void *pAux, /* Context pointer for xCreate/xConnect */ void (*xDestroy)(void *) /* Module destructor function */ ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; #endif return createModule(db, zName, pModule, pAux, xDestroy); } @@ -141586,10 +141586,10 @@ SQLITE_API int tdsqlite3_create_module_v2( ** External API to drop all virtual-table modules, except those named ** on the azNames list. */ -SQLITE_API int tdsqlite3_drop_modules(tdsqlite3 *db, const char** azNames){ +SQLITE_API int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ HashElem *pThis, *pNext; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ Module *pMod = (Module*)sqliteHashData(pThis); @@ -141608,7 +141608,7 @@ SQLITE_API int tdsqlite3_drop_modules(tdsqlite3 *db, const char** azNames){ ** Decrement the reference count on a Module object. Destroy the ** module when the reference count reaches zero. */ -SQLITE_PRIVATE void tdsqlite3VtabModuleUnref(tdsqlite3 *db, Module *pMod){ +SQLITE_PRIVATE void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){ assert( pMod->nRefModule>0 ); pMod->nRefModule--; if( pMod->nRefModule==0 ){ @@ -141616,7 +141616,7 @@ SQLITE_PRIVATE void tdsqlite3VtabModuleUnref(tdsqlite3 *db, Module *pMod){ pMod->xDestroy(pMod->pAux); } assert( pMod->pEpoTab==0 ); - tdsqlite3DbFree(db, pMod); + sqlite3DbFree(db, pMod); } } @@ -141628,7 +141628,7 @@ SQLITE_PRIVATE void tdsqlite3VtabModuleUnref(tdsqlite3 *db, Module *pMod){ ** If a disconnect is attempted while a virtual table is locked, ** the disconnect is deferred until all locks have been removed. */ -SQLITE_PRIVATE void tdsqlite3VtabLock(VTable *pVTab){ +SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){ pVTab->nRef++; } @@ -141638,7 +141638,7 @@ SQLITE_PRIVATE void tdsqlite3VtabLock(VTable *pVTab){ ** Return a pointer to the VTable object used by connection db to access ** this virtual-table, if one has been created, or NULL otherwise. */ -SQLITE_PRIVATE VTable *tdsqlite3GetVTable(tdsqlite3 *db, Table *pTab){ +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ VTable *pVtab; assert( IsVirtual(pTab) ); for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); @@ -141649,8 +141649,8 @@ SQLITE_PRIVATE VTable *tdsqlite3GetVTable(tdsqlite3 *db, Table *pTab){ ** Decrement the ref-count on a virtual table object. When the ref-count ** reaches zero, call the xDisconnect() method to delete the object. */ -SQLITE_PRIVATE void tdsqlite3VtabUnlock(VTable *pVTab){ - tdsqlite3 *db = pVTab->db; +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ + sqlite3 *db = pVTab->db; assert( db ); assert( pVTab->nRef>0 ); @@ -141658,12 +141658,12 @@ SQLITE_PRIVATE void tdsqlite3VtabUnlock(VTable *pVTab){ pVTab->nRef--; if( pVTab->nRef==0 ){ - tdsqlite3_vtab *p = pVTab->pVtab; - tdsqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); + sqlite3_vtab *p = pVTab->pVtab; + sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); if( p ){ p->pModule->xDisconnect(p); } - tdsqlite3DbFree(db, pVTab); + sqlite3DbFree(db, pVTab); } } @@ -141674,21 +141674,21 @@ SQLITE_PRIVATE void tdsqlite3VtabUnlock(VTable *pVTab){ ** Except, if argument db is not NULL, then the entry associated with ** connection db is left in the p->pVTable list. */ -static VTable *vtabDisconnectAll(tdsqlite3 *db, Table *p){ +static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ VTable *pRet = 0; VTable *pVTable = p->pVTable; p->pVTable = 0; /* Assert that the mutex (if any) associated with the BtShared database ** that contains table p is held by the caller. See header comments - ** above function tdsqlite3VtabUnlockList() for an explanation of why + ** above function sqlite3VtabUnlockList() for an explanation of why ** this makes it safe to access the sqlite3.pDisconnect list of any ** database connection that may have an entry in the p->pVTable list. */ - assert( db==0 || tdsqlite3SchemaMutexHeld(db, 0, p->pSchema) ); + assert( db==0 || sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); while( pVTable ){ - tdsqlite3 *db2 = pVTable->db; + sqlite3 *db2 = pVTable->db; VTable *pNext = pVTable->pNext; assert( db2 ); if( db2==db ){ @@ -141714,18 +141714,18 @@ static VTable *vtabDisconnectAll(tdsqlite3 *db, Table *p){ ** objects without disturbing the rest of the Schema object (which may ** be being used by other shared-cache connections). */ -SQLITE_PRIVATE void tdsqlite3VtabDisconnect(tdsqlite3 *db, Table *p){ +SQLITE_PRIVATE void sqlite3VtabDisconnect(sqlite3 *db, Table *p){ VTable **ppVTab; assert( IsVirtual(p) ); - assert( tdsqlite3BtreeHoldsAllMutexes(db) ); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); for(ppVTab=&p->pVTable; *ppVTab; ppVTab=&(*ppVTab)->pNext){ if( (*ppVTab)->db==db ){ VTable *pVTab = *ppVTab; *ppVTab = pVTab->pNext; - tdsqlite3VtabUnlock(pVTab); + sqlite3VtabUnlock(pVTab); break; } } @@ -141752,18 +141752,18 @@ SQLITE_PRIVATE void tdsqlite3VtabDisconnect(tdsqlite3 *db, Table *p){ ** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously ** by multiple threads. It is thread-safe. */ -SQLITE_PRIVATE void tdsqlite3VtabUnlockList(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ VTable *p = db->pDisconnect; - assert( tdsqlite3BtreeHoldsAllMutexes(db) ); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); if( p ){ db->pDisconnect = 0; - tdsqlite3ExpirePreparedStatements(db, 0); + sqlite3ExpirePreparedStatements(db, 0); do { VTable *pNext = p->pNext; - tdsqlite3VtabUnlock(p); + sqlite3VtabUnlock(p); p = pNext; }while( p ); } @@ -141776,21 +141776,21 @@ SQLITE_PRIVATE void tdsqlite3VtabUnlockList(tdsqlite3 *db){ ** ** Since it is a virtual-table, the Table structure contains a pointer ** to the head of a linked list of VTable structures. Each VTable -** structure is associated with a single tdsqlite3* user of the schema. +** structure is associated with a single sqlite3* user of the schema. ** The reference count of the VTable structure associated with database ** connection db is decremented immediately (which may lead to the ** structure being xDisconnected and free). Any other VTable structures ** in the list are moved to the sqlite3.pDisconnect list of the associated ** database connection. */ -SQLITE_PRIVATE void tdsqlite3VtabClear(tdsqlite3 *db, Table *p){ +SQLITE_PRIVATE void sqlite3VtabClear(sqlite3 *db, Table *p){ if( !db || db->pnBytesFreed==0 ) vtabDisconnectAll(0, p); if( p->azModuleArg ){ int i; for(i=0; inModuleArg; i++){ - if( i!=1 ) tdsqlite3DbFree(db, p->azModuleArg[i]); + if( i!=1 ) sqlite3DbFree(db, p->azModuleArg[i]); } - tdsqlite3DbFree(db, p->azModuleArg); + sqlite3DbFree(db, p->azModuleArg); } } @@ -141801,15 +141801,15 @@ SQLITE_PRIVATE void tdsqlite3VtabClear(tdsqlite3 *db, Table *p){ ** deleted. */ static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){ - tdsqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg); + sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg); char **azModuleArg; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( pTable->nModuleArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){ - tdsqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName); + sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName); } - azModuleArg = tdsqlite3DbRealloc(db, pTable->azModuleArg, nBytes); + azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes); if( azModuleArg==0 ){ - tdsqlite3DbFree(db, zArg); + sqlite3DbFree(db, zArg); }else{ int i = pTable->nModuleArg++; azModuleArg[i] = zArg; @@ -141823,7 +141823,7 @@ static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){ ** statement. The module name has been parsed, but the optional list ** of parameters that follow the module name are still pending. */ -SQLITE_PRIVATE void tdsqlite3VtabBeginParse( +SQLITE_PRIVATE void sqlite3VtabBeginParse( Parse *pParse, /* Parsing context */ Token *pName1, /* Name of new table, or database name */ Token *pName2, /* Name of new table or NULL */ @@ -141831,9 +141831,9 @@ SQLITE_PRIVATE void tdsqlite3VtabBeginParse( int ifNotExists /* No error if the table already exists */ ){ Table *pTable; /* The new virtual table */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ - tdsqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); + sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, ifNotExists); pTable = pParse->pNewTable; if( pTable==0 ) return; assert( 0==pTable->pIndex ); @@ -141841,9 +141841,9 @@ SQLITE_PRIVATE void tdsqlite3VtabBeginParse( db = pParse->db; assert( pTable->nModuleArg==0 ); - addModuleArgument(pParse, pTable, tdsqlite3NameFromToken(db, pModuleName)); + addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName)); addModuleArgument(pParse, pTable, 0); - addModuleArgument(pParse, pTable, tdsqlite3DbStrDup(db, pTable->zName)); + addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName)); assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0) || (pParse->sNameToken.z==pName1->z && pName2->z==0) ); @@ -141854,13 +141854,13 @@ SQLITE_PRIVATE void tdsqlite3VtabBeginParse( #ifndef SQLITE_OMIT_AUTHORIZATION /* Creating a virtual table invokes the authorization callback twice. ** The first invocation, to obtain permission to INSERT a row into the - ** sqlite_master table, has already been made by tdsqlite3StartTable(). + ** sqlite_master table, has already been made by sqlite3StartTable(). ** The second call, to obtain permission to create the table, is made now. */ if( pTable->azModuleArg ){ - int iDb = tdsqlite3SchemaToIndex(db, pTable->pSchema); + int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); assert( iDb>=0 ); /* The database the table is being created in */ - tdsqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, + sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, pTable->azModuleArg[0], pParse->db->aDb[iDb].zDbSName); } #endif @@ -141875,8 +141875,8 @@ static void addArgumentToVtab(Parse *pParse){ if( pParse->sArg.z && pParse->pNewTable ){ const char *z = (const char*)pParse->sArg.z; int n = pParse->sArg.n; - tdsqlite3 *db = pParse->db; - addModuleArgument(pParse, pParse->pNewTable, tdsqlite3DbStrNDup(db, z, n)); + sqlite3 *db = pParse->db; + addModuleArgument(pParse, pParse->pNewTable, sqlite3DbStrNDup(db, z, n)); } } @@ -141884,9 +141884,9 @@ static void addArgumentToVtab(Parse *pParse){ ** The parser calls this routine after the CREATE VIRTUAL TABLE statement ** has been completely parsed. */ -SQLITE_PRIVATE void tdsqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ +SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ Table *pTab = pParse->pNewTable; /* The table being constructed */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ if( pTab==0 ) return; addArgumentToVtab(pParse); @@ -141906,13 +141906,13 @@ SQLITE_PRIVATE void tdsqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ int iReg; Vdbe *v; - tdsqlite3MayAbort(pParse); + sqlite3MayAbort(pParse); /* Compute the complete text of the CREATE VIRTUAL TABLE statement */ if( pEnd ){ pParse->sNameToken.n = (int)(pEnd->z - pParse->sNameToken.z) + pEnd->n; } - zStmt = tdsqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); + zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); /* A slot for the record has already been allocated in the ** SQLITE_MASTER table. We just need to update that slot with all @@ -141920,10 +141920,10 @@ SQLITE_PRIVATE void tdsqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ ** ** The VM register number pParse->regRowid holds the rowid of an ** entry in the sqlite_master table tht was created for this vtab - ** by tdsqlite3StartTable(). + ** by sqlite3StartTable(). */ - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); - tdsqlite3NestedParse(pParse, + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + sqlite3NestedParse(pParse, "UPDATE %Q.%s " "SET type='table', name=%Q, tbl_name=%Q, rootpage=0, sql=%Q " "WHERE rowid=#%d", @@ -141933,17 +141933,17 @@ SQLITE_PRIVATE void tdsqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ zStmt, pParse->regRowid ); - v = tdsqlite3GetVdbe(pParse); - tdsqlite3ChangeCookie(pParse, iDb); + v = sqlite3GetVdbe(pParse); + sqlite3ChangeCookie(pParse, iDb); - tdsqlite3VdbeAddOp0(v, OP_Expire); - zWhere = tdsqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt); - tdsqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); - tdsqlite3DbFree(db, zStmt); + sqlite3VdbeAddOp0(v, OP_Expire); + zWhere = sqlite3MPrintf(db, "name=%Q AND sql=%Q", pTab->zName, zStmt); + sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); + sqlite3DbFree(db, zStmt); iReg = ++pParse->nMem; - tdsqlite3VdbeLoadString(v, iReg, pTab->zName); - tdsqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg); + sqlite3VdbeLoadString(v, iReg, pTab->zName); + sqlite3VdbeAddOp2(v, OP_VCreate, iDb, iReg); } /* If we are rereading the sqlite_master table create the in-memory @@ -141955,10 +141955,10 @@ SQLITE_PRIVATE void tdsqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ Table *pOld; Schema *pSchema = pTab->pSchema; const char *zName = pTab->zName; - assert( tdsqlite3SchemaMutexHeld(db, 0, pSchema) ); - pOld = tdsqlite3HashInsert(&pSchema->tblHash, zName, pTab); + assert( sqlite3SchemaMutexHeld(db, 0, pSchema) ); + pOld = sqlite3HashInsert(&pSchema->tblHash, zName, pTab); if( pOld ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); assert( pTab==pOld ); /* Malloc must have failed inside HashInsert() */ return; } @@ -141970,7 +141970,7 @@ SQLITE_PRIVATE void tdsqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ ** The parser calls this routine when it sees the first token ** of an argument to the module name in a CREATE VIRTUAL TABLE statement. */ -SQLITE_PRIVATE void tdsqlite3VtabArgInit(Parse *pParse){ +SQLITE_PRIVATE void sqlite3VtabArgInit(Parse *pParse){ addArgumentToVtab(pParse); pParse->sArg.z = 0; pParse->sArg.n = 0; @@ -141980,7 +141980,7 @@ SQLITE_PRIVATE void tdsqlite3VtabArgInit(Parse *pParse){ ** The parser calls this routine for each token after the first token ** in an argument to the module name in a CREATE VIRTUAL TABLE statement. */ -SQLITE_PRIVATE void tdsqlite3VtabArgExtend(Parse *pParse, Token *p){ +SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse *pParse, Token *p){ Token *pArg = &pParse->sArg; if( pArg->z==0 ){ pArg->z = p->z; @@ -141997,10 +141997,10 @@ SQLITE_PRIVATE void tdsqlite3VtabArgExtend(Parse *pParse, Token *p){ ** to this procedure. */ static int vtabCallConstructor( - tdsqlite3 *db, + sqlite3 *db, Table *pTab, Module *pMod, - int (*xConstruct)(tdsqlite3*,void*,int,const char*const*,tdsqlite3_vtab**,char**), + int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ VtabCtx sCtx; @@ -142016,29 +142016,29 @@ static int vtabCallConstructor( /* Check that the virtual-table is not already being initialized */ for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ if( pCtx->pTab==pTab ){ - *pzErr = tdsqlite3MPrintf(db, + *pzErr = sqlite3MPrintf(db, "vtable constructor called recursively: %s", pTab->zName ); return SQLITE_LOCKED; } } - zModuleName = tdsqlite3DbStrDup(db, pTab->zName); + zModuleName = sqlite3DbStrDup(db, pTab->zName); if( !zModuleName ){ return SQLITE_NOMEM_BKPT; } - pVTable = tdsqlite3MallocZero(sizeof(VTable)); + pVTable = sqlite3MallocZero(sizeof(VTable)); if( !pVTable ){ - tdsqlite3OomFault(db); - tdsqlite3DbFree(db, zModuleName); + sqlite3OomFault(db); + sqlite3DbFree(db, zModuleName); return SQLITE_NOMEM_BKPT; } pVTable->db = db; pVTable->pMod = pMod; pVTable->eVtabRisk = SQLITE_VTABRISK_Normal; - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pTab->azModuleArg[1] = db->aDb[iDb].zDbSName; /* Invoke the virtual table constructor */ @@ -142051,28 +142051,28 @@ static int vtabCallConstructor( db->pVtabCtx = &sCtx; rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); db->pVtabCtx = sCtx.pPrior; - if( rc==SQLITE_NOMEM ) tdsqlite3OomFault(db); + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); assert( sCtx.pTab==pTab ); if( SQLITE_OK!=rc ){ if( zErr==0 ){ - *pzErr = tdsqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); + *pzErr = sqlite3MPrintf(db, "vtable constructor failed: %s", zModuleName); }else { - *pzErr = tdsqlite3MPrintf(db, "%s", zErr); - tdsqlite3_free(zErr); + *pzErr = sqlite3MPrintf(db, "%s", zErr); + sqlite3_free(zErr); } - tdsqlite3DbFree(db, pVTable); + sqlite3DbFree(db, pVTable); }else if( ALWAYS(pVTable->pVtab) ){ /* Justification of ALWAYS(): A correct vtab constructor must allocate - ** the tdsqlite3_vtab object if successful. */ + ** the sqlite3_vtab object if successful. */ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); pVTable->pVtab->pModule = pMod->pModule; pMod->nRefModule++; pVTable->nRef = 1; if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; - *pzErr = tdsqlite3MPrintf(db, zFormat, pTab->zName); - tdsqlite3VtabUnlock(pVTable); + *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); + sqlite3VtabUnlock(pVTable); rc = SQLITE_ERROR; }else{ int iCol; @@ -142086,12 +142086,12 @@ static int vtabCallConstructor( pTab->pVTable = pVTable; for(iCol=0; iColnCol; iCol++){ - char *zType = tdsqlite3ColumnType(&pTab->aCol[iCol], ""); + char *zType = sqlite3ColumnType(&pTab->aCol[iCol], ""); int nType; int i = 0; - nType = tdsqlite3Strlen30(zType); + nType = sqlite3Strlen30(zType); for(i=0; idb; +SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ + sqlite3 *db = pParse->db; const char *zMod; Module *pMod; int rc; assert( pTab ); - if( !IsVirtual(pTab) || tdsqlite3GetVTable(db, pTab) ){ + if( !IsVirtual(pTab) || sqlite3GetVTable(db, pTab) ){ return SQLITE_OK; } /* Locate the required virtual table module */ zMod = pTab->azModuleArg[0]; - pMod = (Module*)tdsqlite3HashFind(&db->aModule, zMod); + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); if( !pMod ){ const char *zModule = pTab->azModuleArg[0]; - tdsqlite3ErrorMsg(pParse, "no such module: %s", zModule); + sqlite3ErrorMsg(pParse, "no such module: %s", zModule); rc = SQLITE_ERROR; }else{ char *zErr = 0; rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); if( rc!=SQLITE_OK ){ - tdsqlite3ErrorMsg(pParse, "%s", zErr); + sqlite3ErrorMsg(pParse, "%s", zErr); pParse->rc = rc; } - tdsqlite3DbFree(db, zErr); + sqlite3DbFree(db, zErr); } return rc; @@ -142163,19 +142163,19 @@ SQLITE_PRIVATE int tdsqlite3VtabCallConnect(Parse *pParse, Table *pTab){ ** Grow the db->aVTrans[] array so that there is room for at least one ** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. */ -static int growVTrans(tdsqlite3 *db){ +static int growVTrans(sqlite3 *db){ const int ARRAY_INCR = 5; /* Grow the sqlite3.aVTrans array if required */ if( (db->nVTrans%ARRAY_INCR)==0 ){ VTable **aVTrans; - tdsqlite3_int64 nBytes = sizeof(tdsqlite3_vtab*)* - ((tdsqlite3_int64)db->nVTrans + ARRAY_INCR); - aVTrans = tdsqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); + sqlite3_int64 nBytes = sizeof(sqlite3_vtab*)* + ((sqlite3_int64)db->nVTrans + ARRAY_INCR); + aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); if( !aVTrans ){ return SQLITE_NOMEM_BKPT; } - memset(&aVTrans[db->nVTrans], 0, sizeof(tdsqlite3_vtab *)*ARRAY_INCR); + memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); db->aVTrans = aVTrans; } @@ -142186,10 +142186,10 @@ static int growVTrans(tdsqlite3 *db){ ** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should ** have already been reserved using growVTrans(). */ -static void addToVTrans(tdsqlite3 *db, VTable *pVTab){ +static void addToVTrans(sqlite3 *db, VTable *pVTab){ /* Add pVtab to the end of sqlite3.aVTrans */ db->aVTrans[db->nVTrans++] = pVTab; - tdsqlite3VtabLock(pVTab); + sqlite3VtabLock(pVTab); } /* @@ -142198,38 +142198,38 @@ static void addToVTrans(tdsqlite3 *db, VTable *pVTab){ ** ** If an error occurs, *pzErr is set to point to an English language ** description of the error and an SQLITE_XXX error code is returned. -** In this case the caller must call tdsqlite3DbFree(db, ) on *pzErr. +** In this case the caller must call sqlite3DbFree(db, ) on *pzErr. */ -SQLITE_PRIVATE int tdsqlite3VtabCallCreate(tdsqlite3 *db, int iDb, const char *zTab, char **pzErr){ +SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, char **pzErr){ int rc = SQLITE_OK; Table *pTab; Module *pMod; const char *zMod; - pTab = tdsqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); assert( pTab && IsVirtual(pTab) && !pTab->pVTable ); /* Locate the required virtual table module */ zMod = pTab->azModuleArg[0]; - pMod = (Module*)tdsqlite3HashFind(&db->aModule, zMod); + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); /* If the module has been registered and includes a Create method, ** invoke it now. If the module has not been registered, return an ** error. Otherwise, do nothing. */ if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){ - *pzErr = tdsqlite3MPrintf(db, "no such module: %s", zMod); + *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod); rc = SQLITE_ERROR; }else{ rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); } /* Justification of ALWAYS(): The xConstructor method is required to - ** create a valid tdsqlite3_vtab if it returns SQLITE_OK. */ - if( rc==SQLITE_OK && ALWAYS(tdsqlite3GetVTable(db, pTab)) ){ + ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ + if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ rc = growVTrans(db); if( rc==SQLITE_OK ){ - addToVTrans(db, tdsqlite3GetVTable(db, pTab)); + addToVTrans(db, sqlite3GetVTable(db, pTab)); } } @@ -142241,7 +142241,7 @@ SQLITE_PRIVATE int tdsqlite3VtabCallCreate(tdsqlite3 *db, int iDb, const char *z ** valid to call this function from within the xCreate() or xConnect() of a ** virtual table module. */ -SQLITE_API int tdsqlite3_declare_vtab(tdsqlite3 *db, const char *zCreateTable){ +SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ VtabCtx *pCtx; int rc = SQLITE_OK; Table *pTab; @@ -142249,15 +142249,15 @@ SQLITE_API int tdsqlite3_declare_vtab(tdsqlite3 *db, const char *zCreateTable){ Parse sParse; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zCreateTable==0 ){ + if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){ return SQLITE_MISUSE_BKPT; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); pCtx = db->pVtabCtx; if( !pCtx || pCtx->bDeclared ){ - tdsqlite3Error(db, SQLITE_MISUSE); - tdsqlite3_mutex_leave(db->mutex); + sqlite3Error(db, SQLITE_MISUSE); + sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE_BKPT; } pTab = pCtx->pTab; @@ -142267,7 +142267,7 @@ SQLITE_API int tdsqlite3_declare_vtab(tdsqlite3 *db, const char *zCreateTable){ sParse.eParseMode = PARSE_MODE_DECLARE_VTAB; sParse.db = db; sParse.nQueryLoop = 1; - if( SQLITE_OK==tdsqlite3RunParser(&sParse, zCreateTable, &zErr) + if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) && sParse.pNewTable && !db->mallocFailed && !sParse.pNewTable->pSelect @@ -142282,10 +142282,10 @@ SQLITE_API int tdsqlite3_declare_vtab(tdsqlite3 *db, const char *zCreateTable){ pNew->nCol = 0; pNew->aCol = 0; assert( pTab->pIndex==0 ); - assert( HasRowid(pNew) || tdsqlite3PrimaryKeyIndex(pNew)!=0 ); + assert( HasRowid(pNew) || sqlite3PrimaryKeyIndex(pNew)!=0 ); if( !HasRowid(pNew) && pCtx->pVTable->pMod->pModule->xUpdate!=0 - && tdsqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1 + && sqlite3PrimaryKeyIndex(pNew)->nKeyCol!=1 ){ /* WITHOUT ROWID virtual tables must either be read-only (xUpdate==0) ** or else must have a single-column PRIMARY KEY */ @@ -142301,21 +142301,21 @@ SQLITE_API int tdsqlite3_declare_vtab(tdsqlite3 *db, const char *zCreateTable){ } pCtx->bDeclared = 1; }else{ - tdsqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); - tdsqlite3DbFree(db, zErr); + sqlite3ErrorWithMsg(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr); + sqlite3DbFree(db, zErr); rc = SQLITE_ERROR; } sParse.eParseMode = PARSE_MODE_NORMAL; if( sParse.pVdbe ){ - tdsqlite3VdbeFinalize(sParse.pVdbe); + sqlite3VdbeFinalize(sParse.pVdbe); } - tdsqlite3DeleteTable(db, sParse.pNewTable); - tdsqlite3ParserReset(&sParse); + sqlite3DeleteTable(db, sParse.pNewTable); + sqlite3ParserReset(&sParse); assert( (rc&0xff)==rc ); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -142326,14 +142326,14 @@ SQLITE_API int tdsqlite3_declare_vtab(tdsqlite3 *db, const char *zCreateTable){ ** ** This call is a no-op if zTab is not a virtual table. */ -SQLITE_PRIVATE int tdsqlite3VtabCallDestroy(tdsqlite3 *db, int iDb, const char *zTab){ +SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab){ int rc = SQLITE_OK; Table *pTab; - pTab = tdsqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); + pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zDbSName); if( pTab!=0 && ALWAYS(pTab->pVTable!=0) ){ VTable *p; - int (*xDestroy)(tdsqlite3_vtab *); + int (*xDestroy)(sqlite3_vtab *); for(p=pTab->pVTable; p; p=p->pNext){ assert( p->pVtab ); if( p->pVtab->nRef>0 ){ @@ -142346,14 +142346,14 @@ SQLITE_PRIVATE int tdsqlite3VtabCallDestroy(tdsqlite3 *db, int iDb, const char * assert( xDestroy!=0 ); pTab->nTabRef++; rc = xDestroy(p->pVtab); - /* Remove the tdsqlite3_vtab* from the aVTrans[] array, if applicable */ + /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ assert( pTab->pVTable==p && p->pNext==0 ); p->pVtab = 0; pTab->pVTable = 0; - tdsqlite3VtabUnlock(p); + sqlite3VtabUnlock(p); } - tdsqlite3DeleteTable(db, pTab); + sqlite3DeleteTable(db, pTab); } return rc; @@ -142363,27 +142363,27 @@ SQLITE_PRIVATE int tdsqlite3VtabCallDestroy(tdsqlite3 *db, int iDb, const char * ** This function invokes either the xRollback or xCommit method ** of each of the virtual tables in the sqlite3.aVTrans array. The method ** called is identified by the second argument, "offset", which is -** the offset of the method to call in the tdsqlite3_module structure. +** the offset of the method to call in the sqlite3_module structure. ** ** The array is cleared after invoking the callbacks. */ -static void callFinaliser(tdsqlite3 *db, int offset){ +static void callFinaliser(sqlite3 *db, int offset){ int i; if( db->aVTrans ){ VTable **aVTrans = db->aVTrans; db->aVTrans = 0; for(i=0; inVTrans; i++){ VTable *pVTab = aVTrans[i]; - tdsqlite3_vtab *p = pVTab->pVtab; + sqlite3_vtab *p = pVTab->pVtab; if( p ){ - int (*x)(tdsqlite3_vtab *); - x = *(int (**)(tdsqlite3_vtab *))((char *)p->pModule + offset); + int (*x)(sqlite3_vtab *); + x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); if( x ) x(p); } pVTab->iSavepoint = 0; - tdsqlite3VtabUnlock(pVTab); + sqlite3VtabUnlock(pVTab); } - tdsqlite3DbFree(db, aVTrans); + sqlite3DbFree(db, aVTrans); db->nVTrans = 0; } } @@ -142395,18 +142395,18 @@ static void callFinaliser(tdsqlite3 *db, int offset){ ** ** If an error message is available, leave it in p->zErrMsg. */ -SQLITE_PRIVATE int tdsqlite3VtabSync(tdsqlite3 *db, Vdbe *p){ +SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, Vdbe *p){ int i; int rc = SQLITE_OK; VTable **aVTrans = db->aVTrans; db->aVTrans = 0; for(i=0; rc==SQLITE_OK && inVTrans; i++){ - int (*x)(tdsqlite3_vtab *); - tdsqlite3_vtab *pVtab = aVTrans[i]->pVtab; + int (*x)(sqlite3_vtab *); + sqlite3_vtab *pVtab = aVTrans[i]->pVtab; if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ rc = x(pVtab); - tdsqlite3VtabImportErrmsg(p, pVtab); + sqlite3VtabImportErrmsg(p, pVtab); } } db->aVTrans = aVTrans; @@ -142417,8 +142417,8 @@ SQLITE_PRIVATE int tdsqlite3VtabSync(tdsqlite3 *db, Vdbe *p){ ** Invoke the xRollback method of all virtual tables in the ** sqlite3.aVTrans array. Then clear the array itself. */ -SQLITE_PRIVATE int tdsqlite3VtabRollback(tdsqlite3 *db){ - callFinaliser(db, offsetof(tdsqlite3_module,xRollback)); +SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db){ + callFinaliser(db, offsetof(sqlite3_module,xRollback)); return SQLITE_OK; } @@ -142426,8 +142426,8 @@ SQLITE_PRIVATE int tdsqlite3VtabRollback(tdsqlite3 *db){ ** Invoke the xCommit method of all virtual tables in the ** sqlite3.aVTrans array. Then clear the array itself. */ -SQLITE_PRIVATE int tdsqlite3VtabCommit(tdsqlite3 *db){ - callFinaliser(db, offsetof(tdsqlite3_module,xCommit)); +SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){ + callFinaliser(db, offsetof(sqlite3_module,xCommit)); return SQLITE_OK; } @@ -142436,19 +142436,19 @@ SQLITE_PRIVATE int tdsqlite3VtabCommit(tdsqlite3 *db){ ** (xBegin/xRollback/xCommit and optionally xSync) and a transaction is ** not currently open, invoke the xBegin method now. ** -** If the xBegin call is successful, place the tdsqlite3_vtab pointer +** If the xBegin call is successful, place the sqlite3_vtab pointer ** in the sqlite3.aVTrans array. */ -SQLITE_PRIVATE int tdsqlite3VtabBegin(tdsqlite3 *db, VTable *pVTab){ +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ int rc = SQLITE_OK; - const tdsqlite3_module *pModule; + const sqlite3_module *pModule; /* Special case: If db->aVTrans is NULL and db->nVTrans is greater ** than zero, then this function is being called from within a ** virtual module xSync() callback. It is illegal to write to ** virtual module tables in this case, so return SQLITE_LOCKED. */ - if( tdsqlite3VtabInSync(db) ){ + if( sqlite3VtabInSync(db) ){ return SQLITE_LOCKED; } if( !pVTab ){ @@ -142499,7 +142499,7 @@ SQLITE_PRIVATE int tdsqlite3VtabBegin(tdsqlite3 *db, VTable *pVTab){ ** function immediately. If all calls to virtual table methods are successful, ** SQLITE_OK is returned. */ -SQLITE_PRIVATE int tdsqlite3VtabSavepoint(tdsqlite3 *db, int op, int iSavepoint){ +SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ int rc = SQLITE_OK; assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); @@ -142508,10 +142508,10 @@ SQLITE_PRIVATE int tdsqlite3VtabSavepoint(tdsqlite3 *db, int op, int iSavepoint) int i; for(i=0; rc==SQLITE_OK && inVTrans; i++){ VTable *pVTab = db->aVTrans[i]; - const tdsqlite3_module *pMod = pVTab->pMod->pModule; + const sqlite3_module *pMod = pVTab->pMod->pModule; if( pVTab->pVtab && pMod->iVersion>=2 ){ - int (*xMethod)(tdsqlite3_vtab *, int); - tdsqlite3VtabLock(pVTab); + int (*xMethod)(sqlite3_vtab *, int); + sqlite3VtabLock(pVTab); switch( op ){ case SAVEPOINT_BEGIN: xMethod = pMod->xSavepoint; @@ -142527,7 +142527,7 @@ SQLITE_PRIVATE int tdsqlite3VtabSavepoint(tdsqlite3 *db, int op, int iSavepoint) if( xMethod && pVTab->iSavepoint>iSavepoint ){ rc = xMethod(pVTab->pVtab, iSavepoint); } - tdsqlite3VtabUnlock(pVTab); + sqlite3VtabUnlock(pVTab); } } } @@ -142547,16 +142547,16 @@ SQLITE_PRIVATE int tdsqlite3VtabSavepoint(tdsqlite3 *db, int op, int iSavepoint) ** new FuncDef structure that is marked as ephemeral using the ** SQLITE_FUNC_EPHEM flag. */ -SQLITE_PRIVATE FuncDef *tdsqlite3VtabOverloadFunction( - tdsqlite3 *db, /* Database connection for reporting malloc problems */ +SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( + sqlite3 *db, /* Database connection for reporting malloc problems */ FuncDef *pDef, /* Function to possibly overload */ int nArg, /* Number of arguments to the function */ Expr *pExpr /* First argument to the function */ ){ Table *pTab; - tdsqlite3_vtab *pVtab; - tdsqlite3_module *pMod; - void (*xSFunc)(tdsqlite3_context*,int,tdsqlite3_value**) = 0; + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**) = 0; void *pArg = 0; FuncDef *pNew; int rc = 0; @@ -142567,10 +142567,10 @@ SQLITE_PRIVATE FuncDef *tdsqlite3VtabOverloadFunction( pTab = pExpr->y.pTab; if( pTab==0 ) return pDef; if( !IsVirtual(pTab) ) return pDef; - pVtab = tdsqlite3GetVTable(db, pTab)->pVtab; + pVtab = sqlite3GetVTable(db, pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); - pMod = (tdsqlite3_module *)pVtab->pModule; + pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; /* Call the xFindFunction method on the virtual table implementation @@ -142585,7 +142585,7 @@ SQLITE_PRIVATE FuncDef *tdsqlite3VtabOverloadFunction( int i; for(i=0; pDef->zName[i]; i++){ unsigned char x = (unsigned char)pDef->zName[i]; - assert( x==tdsqlite3UpperToLower[x] ); + assert( x==sqlite3UpperToLower[x] ); } } #endif @@ -142596,14 +142596,14 @@ SQLITE_PRIVATE FuncDef *tdsqlite3VtabOverloadFunction( /* Create a new ephemeral function definition for the overloaded ** function */ - pNew = tdsqlite3DbMallocZero(db, sizeof(*pNew) - + tdsqlite3Strlen30(pDef->zName) + 1); + pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + + sqlite3Strlen30(pDef->zName) + 1); if( pNew==0 ){ return pDef; } *pNew = *pDef; pNew->zName = (const char*)&pNew[1]; - memcpy((char*)&pNew[1], pDef->zName, tdsqlite3Strlen30(pDef->zName)+1); + memcpy((char*)&pNew[1], pDef->zName, sqlite3Strlen30(pDef->zName)+1); pNew->xSFunc = xSFunc; pNew->pUserData = pArg; pNew->funcFlags |= SQLITE_FUNC_EPHEM; @@ -142616,8 +142616,8 @@ SQLITE_PRIVATE FuncDef *tdsqlite3VtabOverloadFunction( ** array if it is missing. If pTab is already in the array, this routine ** is a no-op. */ -SQLITE_PRIVATE void tdsqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ - Parse *pToplevel = tdsqlite3ParseToplevel(pParse); +SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); int i, n; Table **apVtabLock; @@ -142626,12 +142626,12 @@ SQLITE_PRIVATE void tdsqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ if( pTab==pToplevel->apVtabLock[i] ) return; } n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); - apVtabLock = tdsqlite3_realloc64(pToplevel->apVtabLock, n); + apVtabLock = sqlite3_realloc64(pToplevel->apVtabLock, n); if( apVtabLock ){ pToplevel->apVtabLock = apVtabLock; pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; }else{ - tdsqlite3OomFault(pToplevel->db); + sqlite3OomFault(pToplevel->db); } } @@ -142649,19 +142649,19 @@ SQLITE_PRIVATE void tdsqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ ** Any virtual table module for which xConnect and xCreate are the same ** method can have an eponymous virtual table instance. */ -SQLITE_PRIVATE int tdsqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ - const tdsqlite3_module *pModule = pMod->pModule; +SQLITE_PRIVATE int sqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ + const sqlite3_module *pModule = pMod->pModule; Table *pTab; char *zErr = 0; int rc; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( pMod->pEpoTab ) return 1; if( pModule->xCreate!=0 && pModule->xCreate!=pModule->xConnect ) return 0; - pTab = tdsqlite3DbMallocZero(db, sizeof(Table)); + pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ) return 0; - pTab->zName = tdsqlite3DbStrDup(db, pMod->zName); + pTab->zName = sqlite3DbStrDup(db, pMod->zName); if( pTab->zName==0 ){ - tdsqlite3DbFree(db, pTab); + sqlite3DbFree(db, pTab); return 0; } pMod->pEpoTab = pTab; @@ -142669,14 +142669,14 @@ SQLITE_PRIVATE int tdsqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ pTab->pSchema = db->aDb[0].pSchema; assert( pTab->nModuleArg==0 ); pTab->iPKey = -1; - addModuleArgument(pParse, pTab, tdsqlite3DbStrDup(db, pTab->zName)); + addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); addModuleArgument(pParse, pTab, 0); - addModuleArgument(pParse, pTab, tdsqlite3DbStrDup(db, pTab->zName)); + addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName)); rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr); if( rc ){ - tdsqlite3ErrorMsg(pParse, "%s", zErr); - tdsqlite3DbFree(db, zErr); - tdsqlite3VtabEponymousTableClear(db, pMod); + sqlite3ErrorMsg(pParse, "%s", zErr); + sqlite3DbFree(db, zErr); + sqlite3VtabEponymousTableClear(db, pMod); return 0; } return 1; @@ -142686,14 +142686,14 @@ SQLITE_PRIVATE int tdsqlite3VtabEponymousTableInit(Parse *pParse, Module *pMod){ ** Erase the eponymous virtual table instance associated with ** virtual table module pMod, if it exists. */ -SQLITE_PRIVATE void tdsqlite3VtabEponymousTableClear(tdsqlite3 *db, Module *pMod){ +SQLITE_PRIVATE void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){ Table *pTab = pMod->pEpoTab; if( pTab!=0 ){ /* Mark the table as Ephemeral prior to deleting it, so that the - ** tdsqlite3DeleteTable() routine will know that it is not stored in + ** sqlite3DeleteTable() routine will know that it is not stored in ** the schema. */ pTab->tabFlags |= TF_Ephemeral; - tdsqlite3DeleteTable(db, pTab); + sqlite3DeleteTable(db, pTab); pMod->pEpoTab = 0; } } @@ -142705,12 +142705,12 @@ SQLITE_PRIVATE void tdsqlite3VtabEponymousTableClear(tdsqlite3 *db, Module *pMod ** The results of this routine are undefined unless it is called from ** within an xUpdate method. */ -SQLITE_API int tdsqlite3_vtab_on_conflict(tdsqlite3 *db){ +SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *db){ static const unsigned char aMap[] = { SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE }; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 ); assert( OE_Ignore==4 && OE_Replace==5 ); @@ -142723,15 +142723,15 @@ SQLITE_API int tdsqlite3_vtab_on_conflict(tdsqlite3 *db){ ** the SQLite core with additional information about the behavior ** of the virtual table being implemented. */ -SQLITE_API int tdsqlite3_vtab_config(tdsqlite3 *db, int op, ...){ +SQLITE_API int sqlite3_vtab_config(sqlite3 *db, int op, ...){ va_list ap; int rc = SQLITE_OK; VtabCtx *p; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); p = db->pVtabCtx; if( !p ){ rc = SQLITE_MISUSE_BKPT; @@ -142759,8 +142759,8 @@ SQLITE_API int tdsqlite3_vtab_config(tdsqlite3 *db, int op, ...){ va_end(ap); } - if( rc!=SQLITE_OK ) tdsqlite3Error(db, rc); - tdsqlite3_mutex_leave(db->mutex); + if( rc!=SQLITE_OK ) sqlite3Error(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -142813,11 +142813,11 @@ SQLITE_API int tdsqlite3_vtab_config(tdsqlite3 *db, int op, ...){ ** Trace output macros */ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ extern int tdsqlite3WhereTrace; +/***/ extern int sqlite3WhereTrace; #endif #if defined(SQLITE_DEBUG) \ && (defined(SQLITE_TEST) || defined(SQLITE_ENABLE_WHERETRACE)) -# define WHERETRACE(K,X) if(tdsqlite3WhereTrace&(K)) tdsqlite3DebugPrintf X +# define WHERETRACE(K,X) if(sqlite3WhereTrace&(K)) sqlite3DebugPrintf X # define WHERETRACE_ENABLED 1 #else # define WHERETRACE(K,X) @@ -142927,7 +142927,7 @@ struct WhereLoop { } btree; struct { /* Information for virtual tables */ int idxNum; /* Index number */ - u8 needFree; /* True if tdsqlite3_free(idxStr) is needed */ + u8 needFree; /* True if sqlite3_free(idxStr) is needed */ i8 isOrdered; /* True if satisfies ORDER BY */ u16 omitMask; /* Terms that may be omitted */ char *idxStr; /* Index identifier string */ @@ -143066,7 +143066,7 @@ struct WhereTerm { /* ** Allowed values of WhereTerm.wtFlags */ -#define TERM_DYNAMIC 0x0001 /* Need to call tdsqlite3ExprDelete(db, pExpr) */ +#define TERM_DYNAMIC 0x0001 /* Need to call sqlite3ExprDelete(db, pExpr) */ #define TERM_VIRTUAL 0x0002 /* Added by the optimizer. Do not code */ #define TERM_CODED 0x0004 /* This term is already coded */ #define TERM_COPIED 0x0008 /* Has a child */ @@ -143173,7 +143173,7 @@ struct WhereAndInfo { ** no gaps. */ struct WhereMaskSet { - int bVarSelect; /* Used by tdsqlite3WhereExprUsage() */ + int bVarSelect; /* Used by sqlite3WhereExprUsage() */ int n; /* Number of assigned cursor values */ int ix[BMS]; /* Cursor assigned to each bit */ }; @@ -143208,7 +143208,7 @@ struct WhereLoopBuilder { /* The WhereLoopBuilder.iPlanLimit is used to limit the number of ** index+constraint combinations the query planner will consider for a ** particular query. If this parameter is unlimited, then certain -** pathological queries can spend excess time in the tdsqlite3WhereBegin() +** pathological queries can spend excess time in the sqlite3WhereBegin() ** routine. The limit is high enough that is should not impact real-world ** queries. ** @@ -143259,7 +143259,7 @@ struct WhereInfo { int iContinue; /* Jump here to continue with next record */ int iBreak; /* Jump here to break out of the loop */ int savedNQueryLoop; /* pParse->nQueryLoop outside the WHERE loop */ - u16 wctrlFlags; /* Flags originally passed to tdsqlite3WhereBegin() */ + u16 wctrlFlags; /* Flags originally passed to sqlite3WhereBegin() */ LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ u8 nLevel; /* Number of nested loop */ i8 nOBSat; /* Number of ORDER BY terms satisfied by indices */ @@ -143284,13 +143284,13 @@ struct WhereInfo { ** ** where.c: */ -SQLITE_PRIVATE Bitmask tdsqlite3WhereGetMask(WhereMaskSet*,int); +SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet*,int); #ifdef WHERETRACE_ENABLED -SQLITE_PRIVATE void tdsqlite3WhereClausePrint(WhereClause *pWC); -SQLITE_PRIVATE void tdsqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); -SQLITE_PRIVATE void tdsqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC); +SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC); +SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm); +SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC); #endif -SQLITE_PRIVATE WhereTerm *tdsqlite3WhereFindTerm( +SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( WhereClause *pWC, /* The WHERE clause to be searched */ int iCur, /* Cursor number of LHS */ int iColumn, /* Column number of LHS */ @@ -143301,26 +143301,26 @@ SQLITE_PRIVATE WhereTerm *tdsqlite3WhereFindTerm( /* wherecode.c: */ #ifndef SQLITE_OMIT_EXPLAIN -SQLITE_PRIVATE int tdsqlite3WhereExplainOneScan( +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( Parse *pParse, /* Parse context */ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ - u16 wctrlFlags /* Flags passed to tdsqlite3WhereBegin() */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ); #else -# define tdsqlite3WhereExplainOneScan(u,v,w,x) 0 +# define sqlite3WhereExplainOneScan(u,v,w,x) 0 #endif /* SQLITE_OMIT_EXPLAIN */ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS -SQLITE_PRIVATE void tdsqlite3WhereAddScanStatus( +SQLITE_PRIVATE void sqlite3WhereAddScanStatus( Vdbe *v, /* Vdbe to add scanstatus entry to */ SrcList *pSrclist, /* FROM clause pLvl reads data from */ WhereLevel *pLvl, /* Level to add scanstatus() entry for */ int addrExplain /* Address of OP_Explain (or 0) */ ); #else -# define tdsqlite3WhereAddScanStatus(a, b, c, d) ((void)d) +# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d) #endif -SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( +SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( Parse *pParse, /* Parsing context */ Vdbe *v, /* Prepared statement under construction */ WhereInfo *pWInfo, /* Complete information about the WHERE clause */ @@ -143330,14 +143330,14 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( ); /* whereexpr.c: */ -SQLITE_PRIVATE void tdsqlite3WhereClauseInit(WhereClause*,WhereInfo*); -SQLITE_PRIVATE void tdsqlite3WhereClauseClear(WhereClause*); -SQLITE_PRIVATE void tdsqlite3WhereSplit(WhereClause*,Expr*,u8); -SQLITE_PRIVATE Bitmask tdsqlite3WhereExprUsage(WhereMaskSet*, Expr*); -SQLITE_PRIVATE Bitmask tdsqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); -SQLITE_PRIVATE Bitmask tdsqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); -SQLITE_PRIVATE void tdsqlite3WhereExprAnalyze(SrcList*, WhereClause*); -SQLITE_PRIVATE void tdsqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); +SQLITE_PRIVATE void sqlite3WhereClauseInit(WhereClause*,WhereInfo*); +SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause*); +SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause*,Expr*,u8); +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet*, Expr*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet*, Expr*); +SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet*, ExprList*); +SQLITE_PRIVATE void sqlite3WhereExprAnalyze(SrcList*, WhereClause*); +SQLITE_PRIVATE void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); @@ -143436,23 +143436,23 @@ static void explainAppendTerm( int i; assert( nTerm>=1 ); - if( bAnd ) tdsqlite3_str_append(pStr, " AND ", 5); + if( bAnd ) sqlite3_str_append(pStr, " AND ", 5); - if( nTerm>1 ) tdsqlite3_str_append(pStr, "(", 1); + if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); for(i=0; i1 ) tdsqlite3_str_append(pStr, ")", 1); + if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1); - tdsqlite3_str_append(pStr, zOp, 1); + sqlite3_str_append(pStr, zOp, 1); - if( nTerm>1 ) tdsqlite3_str_append(pStr, "(", 1); + if( nTerm>1 ) sqlite3_str_append(pStr, "(", 1); for(i=0; i1 ) tdsqlite3_str_append(pStr, ")", 1); + if( nTerm>1 ) sqlite3_str_append(pStr, ")", 1); } /* @@ -143476,11 +143476,11 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ int i, j; if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return; - tdsqlite3_str_append(pStr, " (", 2); + sqlite3_str_append(pStr, " (", 2); for(i=0; i=nSkip ? "%s=?" : "ANY(%s)", z); + if( i ) sqlite3_str_append(pStr, " AND ", 5); + sqlite3_str_appendf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z); } j = i; @@ -143491,7 +143491,7 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ if( pLoop->wsFlags&WHERE_TOP_LIMIT ){ explainAppendTerm(pStr, pIndex, pLoop->u.btree.nTop, j, i, "<"); } - tdsqlite3_str_append(pStr, ")", 1); + sqlite3_str_append(pStr, ")", 1); } /* @@ -143503,20 +143503,20 @@ static void explainIndexRange(StrAccum *pStr, WhereLoop *pLoop){ ** If an OP_Explain opcode is added to the VM, its address is returned. ** Otherwise, if no OP_Explain is coded, zero is returned. */ -SQLITE_PRIVATE int tdsqlite3WhereExplainOneScan( +SQLITE_PRIVATE int sqlite3WhereExplainOneScan( Parse *pParse, /* Parse context */ SrcList *pTabList, /* Table list this loop refers to */ WhereLevel *pLevel, /* Scan to write OP_Explain opcode for */ - u16 wctrlFlags /* Flags passed to tdsqlite3WhereBegin() */ + u16 wctrlFlags /* Flags passed to sqlite3WhereBegin() */ ){ int ret = 0; #if !defined(SQLITE_DEBUG) && !defined(SQLITE_ENABLE_STMT_SCANSTATUS) - if( tdsqlite3ParseToplevel(pParse)->explain==2 ) + if( sqlite3ParseToplevel(pParse)->explain==2 ) #endif { struct SrcList_item *pItem = &pTabList->a[pLevel->iFrom]; Vdbe *v = pParse->pVdbe; /* VM being constructed */ - tdsqlite3 *db = pParse->db; /* Database handle */ + sqlite3 *db = pParse->db; /* Database handle */ int isSearch; /* True for a SEARCH. False for SCAN. */ WhereLoop *pLoop; /* The controlling WhereLoop object */ u32 flags; /* Flags that describe this loop */ @@ -143532,16 +143532,16 @@ SQLITE_PRIVATE int tdsqlite3WhereExplainOneScan( || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0)) || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX)); - tdsqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); - tdsqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN"); + sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH); + sqlite3_str_appendall(&str, isSearch ? "SEARCH" : "SCAN"); if( pItem->pSelect ){ - tdsqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId); + sqlite3_str_appendf(&str, " SUBQUERY %u", pItem->pSelect->selId); }else{ - tdsqlite3_str_appendf(&str, " TABLE %s", pItem->zName); + sqlite3_str_appendf(&str, " TABLE %s", pItem->zName); } if( pItem->zAlias ){ - tdsqlite3_str_appendf(&str, " AS %s", pItem->zAlias); + sqlite3_str_appendf(&str, " AS %s", pItem->zAlias); } if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){ const char *zFmt = 0; @@ -143564,8 +143564,8 @@ SQLITE_PRIVATE int tdsqlite3WhereExplainOneScan( zFmt = "INDEX %s"; } if( zFmt ){ - tdsqlite3_str_append(&str, " USING ", 7); - tdsqlite3_str_appendf(&str, zFmt, pIdx->zName); + sqlite3_str_append(&str, " USING ", 7); + sqlite3_str_appendf(&str, zFmt, pIdx->zName); explainIndexRange(&str, pLoop); } }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){ @@ -143580,26 +143580,26 @@ SQLITE_PRIVATE int tdsqlite3WhereExplainOneScan( assert( flags&WHERE_TOP_LIMIT); zRangeOp = "<"; } - tdsqlite3_str_appendf(&str, + sqlite3_str_appendf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp); } #ifndef SQLITE_OMIT_VIRTUALTABLE else if( (flags & WHERE_VIRTUALTABLE)!=0 ){ - tdsqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", + sqlite3_str_appendf(&str, " VIRTUAL TABLE INDEX %d:%s", pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr); } #endif #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS if( pLoop->nOut>=10 ){ - tdsqlite3_str_appendf(&str, " (~%llu rows)", - tdsqlite3LogEstToInt(pLoop->nOut)); + sqlite3_str_appendf(&str, " (~%llu rows)", + sqlite3LogEstToInt(pLoop->nOut)); }else{ - tdsqlite3_str_append(&str, " (~1 row)", 9); + sqlite3_str_append(&str, " (~1 row)", 9); } #endif - zMsg = tdsqlite3StrAccumFinish(&str); - tdsqlite3ExplainBreakpoint("",zMsg); - ret = tdsqlite3VdbeAddOp4(v, OP_Explain, tdsqlite3VdbeCurrentAddr(v), + zMsg = sqlite3StrAccumFinish(&str); + sqlite3ExplainBreakpoint("",zMsg); + ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v), pParse->addrExplain, 0, zMsg,P4_DYNAMIC); } return ret; @@ -143609,14 +143609,14 @@ SQLITE_PRIVATE int tdsqlite3WhereExplainOneScan( #ifdef SQLITE_ENABLE_STMT_SCANSTATUS /* ** Configure the VM passed as the first argument with an -** tdsqlite3_stmt_scanstatus() entry corresponding to the scan used to +** sqlite3_stmt_scanstatus() entry corresponding to the scan used to ** implement level pLvl. Argument pSrclist is a pointer to the FROM ** clause that the scan reads data from. ** ** If argument addrExplain is not 0, it must be the address of an ** OP_Explain instruction that describes the same loop. */ -SQLITE_PRIVATE void tdsqlite3WhereAddScanStatus( +SQLITE_PRIVATE void sqlite3WhereAddScanStatus( Vdbe *v, /* Vdbe to add scanstatus entry to */ SrcList *pSrclist, /* FROM clause pLvl reads data from */ WhereLevel *pLvl, /* Level to add scanstatus() entry for */ @@ -143629,7 +143629,7 @@ SQLITE_PRIVATE void tdsqlite3WhereAddScanStatus( }else{ zObj = pSrclist->a[pLvl->iFrom].zName; } - tdsqlite3VdbeScanStatus( + sqlite3VdbeScanStatus( v, addrExplain, pLvl->addrBody, pLvl->addrVisit, pLoop->nOut, zObj ); } @@ -143733,7 +143733,7 @@ static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ /* Code the OP_Affinity opcode if there is anything left to do. */ if( n>0 ){ - tdsqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); + sqlite3VdbeAddOp4(v, OP_Affinity, base, n, 0, zAff, n); } } @@ -143754,9 +143754,9 @@ static void updateRangeAffinityStr( ){ int i; for(i=0; idb; + sqlite3 *db = pParse->db; Expr *pNew; - pNew = tdsqlite3ExprDup(db, pX, 0); + pNew = sqlite3ExprDup(db, pX, 0); if( db->mallocFailed==0 ){ ExprList *pOrigRhs = pNew->x.pSelect->pEList; /* Original unmodified RHS */ ExprList *pOrigLhs = pNew->pLeft->x.pList; /* Original unmodified LHS */ @@ -143814,15 +143814,15 @@ static Expr *removeUnindexableInClauseTerms( if( pLoop->aLTerm[i]->pExpr==pX ){ int iField = pLoop->aLTerm[i]->iField - 1; if( pOrigRhs->a[iField].pExpr==0 ) continue; /* Duplicate PK column */ - pRhs = tdsqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); + pRhs = sqlite3ExprListAppend(pParse, pRhs, pOrigRhs->a[iField].pExpr); pOrigRhs->a[iField].pExpr = 0; assert( pOrigLhs->a[iField].pExpr!=0 ); - pLhs = tdsqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr); + pLhs = sqlite3ExprListAppend(pParse, pLhs, pOrigLhs->a[iField].pExpr); pOrigLhs->a[iField].pExpr = 0; } } - tdsqlite3ExprListDelete(db, pOrigRhs); - tdsqlite3ExprListDelete(db, pOrigLhs); + sqlite3ExprListDelete(db, pOrigRhs); + sqlite3ExprListDelete(db, pOrigLhs); pNew->pLeft->x.pList = pLhs; pNew->x.pSelect->pEList = pRhs; if( pLhs && pLhs->nExpr==1 ){ @@ -143831,7 +143831,7 @@ static Expr *removeUnindexableInClauseTerms( ** of the subroutines do not handle this case. */ Expr *p = pLhs->a[0].pExpr; pLhs->a[0].pExpr = 0; - tdsqlite3ExprDelete(db, pNew->pLeft); + sqlite3ExprDelete(db, pNew->pLeft); pNew->pLeft = p; } pSelect = pNew->x.pSelect; @@ -143851,9 +143851,9 @@ static Expr *removeUnindexableInClauseTerms( #if 0 printf("For indexing, change the IN expr:\n"); - tdsqlite3TreeViewExpr(0, pX, 0); + sqlite3TreeViewExpr(0, pX, 0); printf("Into:\n"); - tdsqlite3TreeViewExpr(0, pNew, 0); + sqlite3TreeViewExpr(0, pNew, 0); #endif } return pNew; @@ -143890,10 +143890,10 @@ static int codeEqualityTerm( assert( pLevel->pWLoop->aLTerm[iEq]==pTerm ); assert( iTarget>0 ); if( pX->op==TK_EQ || pX->op==TK_IS ){ - iReg = tdsqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); + iReg = sqlite3ExprCodeTarget(pParse, pX->pRight, iTarget); }else if( pX->op==TK_ISNULL ){ iReg = iTarget; - tdsqlite3VdbeAddOp2(v, OP_Null, 0, iReg); + sqlite3VdbeAddOp2(v, OP_Null, 0, iReg); #ifndef SQLITE_OMIT_SUBQUERY }else{ int eType = IN_INDEX_NOOP; @@ -143928,17 +143928,17 @@ static int codeEqualityTerm( iTab = 0; if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){ - eType = tdsqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab); }else{ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX); if( !db->mallocFailed ){ - aiMap = (int*)tdsqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); - eType = tdsqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); + aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq); + eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab); pTerm->pExpr->iTable = iTab; } - tdsqlite3ExprDelete(db, pX); + sqlite3ExprDelete(db, pX); pX = pTerm->pExpr; } @@ -143946,20 +143946,20 @@ static int codeEqualityTerm( testcase( bRev ); bRev = !bRev; } - tdsqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0); VdbeCoverageIf(v, bRev); VdbeCoverageIf(v, !bRev); assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 ); pLoop->wsFlags |= WHERE_IN_ABLE; if( pLevel->u.in.nIn==0 ){ - pLevel->addrNxt = tdsqlite3VdbeMakeLabel(pParse); + pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); } i = pLevel->u.in.nIn; pLevel->u.in.nIn += nEq; pLevel->u.in.aInLoop = - tdsqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop, + sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop, sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn); pIn = pLevel->u.in.aInLoop; if( pIn ){ @@ -143969,12 +143969,12 @@ static int codeEqualityTerm( if( pLoop->aLTerm[i]->pExpr==pX ){ int iOut = iReg + i - iEq; if( eType==IN_INDEX_ROWID ){ - pIn->addrInTop = tdsqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); + pIn->addrInTop = sqlite3VdbeAddOp2(v, OP_Rowid, iTab, iOut); }else{ int iCol = aiMap ? aiMap[iMap++] : 0; - pIn->addrInTop = tdsqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); + pIn->addrInTop = sqlite3VdbeAddOp3(v,OP_Column,iTab, iCol, iOut); } - tdsqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); + sqlite3VdbeAddOp1(v, OP_IsNull, iOut); VdbeCoverage(v); if( i==iEq ){ pIn->iCur = iTab; pIn->eEndLoopOp = bRev ? OP_Prev : OP_Next; @@ -143994,7 +143994,7 @@ static int codeEqualityTerm( }else{ pLevel->u.in.nIn = 0; } - tdsqlite3DbFree(pParse->db, aiMap); + sqlite3DbFree(pParse->db, aiMap); #endif } disableTerm(pLevel, pTerm); @@ -144033,7 +144033,7 @@ static int codeEqualityTerm( ** ** Before returning, *pzAff is set to point to a buffer containing a ** copy of the column affinity string of the index allocated using -** tdsqlite3DbMalloc(). Except, entries in the copy of the string associated +** sqlite3DbMalloc(). Except, entries in the copy of the string associated ** with equality constraints that use BLOB or NONE affinity are set to ** SQLITE_AFF_BLOB. This is to deal with SQL such as the following: ** @@ -144078,23 +144078,23 @@ static int codeAllEqualityTerms( nReg = pLoop->u.btree.nEq + nExtraReg; pParse->nMem += nReg; - zAff = tdsqlite3DbStrDup(pParse->db,tdsqlite3IndexAffinityStr(pParse->db,pIdx)); + zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); assert( zAff!=0 || pParse->db->mallocFailed ); if( nSkip ){ int iIdxCur = pLevel->iIdxCur; - tdsqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); + sqlite3VdbeAddOp1(v, (bRev?OP_Last:OP_Rewind), iIdxCur); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); VdbeComment((v, "begin skip-scan on %s", pIdx->zName)); - j = tdsqlite3VdbeAddOp0(v, OP_Goto); - pLevel->addrSkip = tdsqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), + j = sqlite3VdbeAddOp0(v, OP_Goto); + pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT), iIdxCur, 0, regBase, nSkip); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); - tdsqlite3VdbeJumpHere(v, j); + sqlite3VdbeJumpHere(v, j); for(j=0; jaiColumn[j]==XN_EXPR ); VdbeComment((v, "%s", explainIndexColumnName(pIdx, j))); } @@ -144114,31 +144114,31 @@ static int codeAllEqualityTerms( r1 = codeEqualityTerm(pParse, pTerm, pLevel, j, bRev, regBase+j); if( r1!=regBase+j ){ if( nReg==1 ){ - tdsqlite3ReleaseTempReg(pParse, regBase); + sqlite3ReleaseTempReg(pParse, regBase); regBase = r1; }else{ - tdsqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); + sqlite3VdbeAddOp2(v, OP_SCopy, r1, regBase+j); } } if( pTerm->eOperator & WO_IN ){ if( pTerm->pExpr->flags & EP_xIsSelect ){ /* No affinity ever needs to be (or should be) applied to a value ** from the RHS of an "? IN (SELECT ...)" expression. The - ** tdsqlite3FindInIndex() routine has already ensured that the + ** sqlite3FindInIndex() routine has already ensured that the ** affinity of the comparison has been applied to the value. */ if( zAff ) zAff[j] = SQLITE_AFF_BLOB; } }else if( (pTerm->eOperator & WO_ISNULL)==0 ){ Expr *pRight = pTerm->pExpr->pRight; - if( (pTerm->wtFlags & TERM_IS)==0 && tdsqlite3ExprCanBeNull(pRight) ){ - tdsqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); + if( (pTerm->wtFlags & TERM_IS)==0 && sqlite3ExprCanBeNull(pRight) ){ + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); VdbeCoverage(v); } if( zAff ){ - if( tdsqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ + if( sqlite3CompareAffinity(pRight, zAff[j])==SQLITE_AFF_BLOB ){ zAff[j] = SQLITE_AFF_BLOB; } - if( tdsqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ + if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ zAff[j] = SQLITE_AFF_BLOB; } } @@ -144174,7 +144174,7 @@ static void whereLikeOptimizationStringFixup( if( pTerm->wtFlags & TERM_LIKEOPT ){ VdbeOp *pOp; assert( pLevel->iLikeRepCntr>0 ); - pOp = tdsqlite3VdbeGetOp(v, -1); + pOp = sqlite3VdbeGetOp(v, -1); assert( pOp!=0 ); assert( pOp->opcode==OP_String8 || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); @@ -144189,7 +144189,7 @@ static void whereLikeOptimizationStringFixup( #ifdef SQLITE_ENABLE_CURSOR_HINTS /* ** Information is passed from codeCursorHint() down to individual nodes of -** the expression tree (by tdsqlite3WalkExpr()) using an instance of this +** the expression tree (by sqlite3WalkExpr()) using an instance of this ** structure. */ struct CCurHint { @@ -144209,7 +144209,7 @@ static int codeCursorHintCheckExpr(Walker *pWalker, Expr *pExpr){ assert( pHint->pIdx!=0 ); if( pExpr->op==TK_COLUMN && pExpr->iTable==pHint->iTabCur - && tdsqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0 + && sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn)<0 ){ pWalker->eCode = 1; } @@ -144240,7 +144240,7 @@ static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ }else if( pExpr->op==TK_FUNCTION ){ int d1; char d2[4]; - if( 0==tdsqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){ + if( 0==sqlite3IsLikeFunction(pWalker->pParse->db, pExpr, &d1, d2) ){ pWalker->eCode = 1; } } @@ -144272,12 +144272,12 @@ static int codeCursorHintFixExpr(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN ){ if( pExpr->iTable!=pHint->iTabCur ){ int reg = ++pWalker->pParse->nMem; /* Register for column value */ - tdsqlite3ExprCode(pWalker->pParse, pExpr, reg); + sqlite3ExprCode(pWalker->pParse, pExpr, reg); pExpr->op = TK_REGISTER; pExpr->iTable = reg; }else if( pHint->pIdx!=0 ){ pExpr->iTable = pHint->iIdxCur; - pExpr->iColumn = tdsqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); + pExpr->iColumn = sqlite3TableColumnToIndex(pHint->pIdx, pExpr->iColumn); assert( pExpr->iColumn>=0 ); } }else if( pExpr->op==TK_AGG_FUNCTION ){ @@ -144303,7 +144303,7 @@ static void codeCursorHint( WhereTerm *pEndRange /* Hint this end-of-scan boundary term if not NULL */ ){ Parse *pParse = pWInfo->pParse; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; Expr *pExpr = 0; WhereLoop *pLoop = pLevel->pWLoop; @@ -144358,7 +144358,7 @@ static void codeCursorHint( ){ sWalker.eCode = 0; sWalker.xExprCallback = codeCursorHintIsOrFunction; - tdsqlite3WalkExpr(&sWalker, pTerm->pExpr); + sqlite3WalkExpr(&sWalker, pTerm->pExpr); if( sWalker.eCode ) continue; } }else{ @@ -144374,24 +144374,24 @@ static void codeCursorHint( } /* No subqueries or non-deterministic functions allowed */ - if( tdsqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; + if( sqlite3ExprContainsSubquery(pTerm->pExpr) ) continue; /* For an index scan, make sure referenced columns are actually in ** the index. */ if( sHint.pIdx!=0 ){ sWalker.eCode = 0; sWalker.xExprCallback = codeCursorHintCheckExpr; - tdsqlite3WalkExpr(&sWalker, pTerm->pExpr); + sqlite3WalkExpr(&sWalker, pTerm->pExpr); if( sWalker.eCode ) continue; } /* If we survive all prior tests, that means this term is worth hinting */ - pExpr = tdsqlite3ExprAnd(pParse, pExpr, tdsqlite3ExprDup(db, pTerm->pExpr, 0)); + pExpr = sqlite3ExprAnd(pParse, pExpr, sqlite3ExprDup(db, pTerm->pExpr, 0)); } if( pExpr!=0 ){ sWalker.xExprCallback = codeCursorHintFixExpr; - tdsqlite3WalkExpr(&sWalker, pExpr); - tdsqlite3VdbeAddOp4(v, OP_CursorHint, + sqlite3WalkExpr(&sWalker, pExpr); + sqlite3VdbeAddOp4(v, OP_CursorHint, (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, (const char*)pExpr, P4_EXPR); } @@ -144431,24 +144431,24 @@ static void codeDeferredSeek( assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); pWInfo->bDeferredSeek = 1; - tdsqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur); + sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur); if( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE) - && DbMaskAllZero(tdsqlite3ParseToplevel(pParse)->writeMask) + && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask) ){ int i; Table *pTab = pIdx->pTable; - int *ai = (int*)tdsqlite3DbMallocZero(pParse->db, sizeof(int)*(pTab->nCol+1)); + int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*(pTab->nCol+1)); if( ai ){ ai[0] = pTab->nCol; for(i=0; inColumn-1; i++){ int x1, x2; assert( pIdx->aiColumn[i]nCol ); x1 = pIdx->aiColumn[i]; - x2 = tdsqlite3TableColumnToStorage(pTab, x1); + x2 = sqlite3TableColumnToStorage(pTab, x1); testcase( x1!=x2 ); if( x1>=0 ) ai[x2+1] = i+1; } - tdsqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); + sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY); } } } @@ -144464,14 +144464,14 @@ static void codeDeferredSeek( */ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ assert( nReg>0 ); - if( p && tdsqlite3ExprIsVector(p) ){ + if( p && sqlite3ExprIsVector(p) ){ #ifndef SQLITE_OMIT_SUBQUERY if( (p->flags & EP_xIsSelect) ){ Vdbe *v = pParse->pVdbe; int iSelect; assert( p->op==TK_SELECT ); - iSelect = tdsqlite3CodeSubselect(pParse, p); - tdsqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); + iSelect = sqlite3CodeSubselect(pParse, p); + sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1); }else #endif { @@ -144479,12 +144479,12 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ ExprList *pList = p->x.pList; assert( nReg<=pList->nExpr ); for(i=0; ia[i].pExpr, iReg+i); + sqlite3ExprCode(pParse, pList->a[i].pExpr, iReg+i); } } }else{ assert( nReg==1 ); - tdsqlite3ExprCode(pParse, p, iReg); + sqlite3ExprCode(pParse, p, iReg); } } @@ -144499,7 +144499,7 @@ typedef struct IdxExprTrans { int iIdxCol; /* The column for the index */ int iTabCol; /* The column for the table */ WhereInfo *pWInfo; /* Complete WHERE clause information */ - tdsqlite3 *db; /* Database connection (for malloc()) */ + sqlite3 *db; /* Database connection (for malloc()) */ } IdxExprTrans; /* @@ -144507,7 +144507,7 @@ typedef struct IdxExprTrans { */ static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ WhereExprMod *pNew; - pNew = tdsqlite3DbMallocRaw(pTrans->db, sizeof(*pNew)); + pNew = sqlite3DbMallocRaw(pTrans->db, sizeof(*pNew)); if( pNew==0 ) return; pNew->pNext = pTrans->pWInfo->pExprMods; pTrans->pWInfo->pExprMods = pNew; @@ -144523,9 +144523,9 @@ static void preserveExpr(IdxExprTrans *pTrans, Expr *pExpr){ */ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; - if( tdsqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ preserveExpr(pX, pExpr); - pExpr->affExpr = tdsqlite3ExprAffinity(pExpr); + pExpr->affExpr = sqlite3ExprAffinity(pExpr); pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; @@ -144549,7 +144549,7 @@ static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){ if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){ assert( pExpr->y.pTab!=0 ); preserveExpr(pX, pExpr); - pExpr->affExpr = tdsqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn); + pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn); pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; pExpr->y.pTab = 0; @@ -144597,13 +144597,13 @@ static void whereIndexExprTrans( if( iRef==XN_EXPR ){ assert( aColExpr->a[iIdxCol].pExpr!=0 ); x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; - if( tdsqlite3ExprIsConstant(x.pIdxExpr) ) continue; + if( sqlite3ExprIsConstant(x.pIdxExpr) ) continue; w.xExprCallback = whereIndexExprTransNode; #ifndef SQLITE_OMIT_GENERATED_COLUMNS }else if( iRef>=0 && (pTab->aCol[iRef].colFlags & COLFLAG_VIRTUAL)!=0 && (pTab->aCol[iRef].zColl==0 - || tdsqlite3StrICmp(pTab->aCol[iRef].zColl, tdsqlite3StrBINARY)==0) + || sqlite3StrICmp(pTab->aCol[iRef].zColl, sqlite3StrBINARY)==0) ){ /* Check to see if there are direct references to generated columns ** that are contained in the index. Pulling the generated column @@ -144618,9 +144618,9 @@ static void whereIndexExprTrans( continue; } x.iIdxCol = iIdxCol; - tdsqlite3WalkExpr(&w, pWInfo->pWhere); - tdsqlite3WalkExprList(&w, pWInfo->pOrderBy); - tdsqlite3WalkExprList(&w, pWInfo->pResultSet); + sqlite3WalkExpr(&w, pWInfo->pWhere); + sqlite3WalkExprList(&w, pWInfo->pOrderBy); + sqlite3WalkExprList(&w, pWInfo->pResultSet); } } @@ -144646,7 +144646,7 @@ static void whereApplyPartialIndexConstraints( Expr *pExpr; if( pTerm->wtFlags & TERM_CODED ) continue; pExpr = pTerm->pExpr; - if( tdsqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){ + if( sqlite3ExprCompare(0, pExpr, pTruth, iTabCur)==0 ){ pTerm->wtFlags |= TERM_CODED; } } @@ -144656,7 +144656,7 @@ static void whereApplyPartialIndexConstraints( ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. */ -SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( +SQLITE_PRIVATE Bitmask sqlite3WhereCodeOneLoopStart( Parse *pParse, /* Parsing context */ Vdbe *v, /* Prepared statement under construction */ WhereInfo *pWInfo, /* Complete information about the WHERE clause */ @@ -144671,7 +144671,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( WhereLoop *pLoop; /* The WhereLoop object being coded */ WhereClause *pWC; /* Decomposition of the entire WHERE clause */ WhereTerm *pTerm; /* A WHERE clause term */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ struct SrcList_item *pTabItem; /* FROM clause term being coded */ int addrBrk; /* Jump here to break out of the loop */ int addrHalt; /* addrBrk for the outermost loop */ @@ -144686,22 +144686,22 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( pLoop = pLevel->pWLoop; pTabItem = &pWInfo->pTabList->a[pLevel->iFrom]; iCur = pTabItem->iCursor; - pLevel->notReady = notReady & ~tdsqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); + pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); bRev = (pWInfo->revMask>>iLevel)&1; VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName)); #if WHERETRACE_ENABLED /* 0x20800 */ - if( tdsqlite3WhereTrace & 0x800 ){ - tdsqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", + if( sqlite3WhereTrace & 0x800 ){ + sqlite3DebugPrintf("Coding level %d of %d: notReady=%llx iFrom=%d\n", iLevel, pWInfo->nLevel, (u64)notReady, pLevel->iFrom); - tdsqlite3WhereLoopPrint(pLoop, pWC); + sqlite3WhereLoopPrint(pLoop, pWC); } - if( tdsqlite3WhereTrace & 0x20000 ){ + if( sqlite3WhereTrace & 0x20000 ){ if( iLevel==0 ){ - tdsqlite3DebugPrintf("WHERE clause being coded:\n"); - tdsqlite3TreeViewExpr(0, pWInfo->pWhere, 0); + sqlite3DebugPrintf("WHERE clause being coded:\n"); + sqlite3TreeViewExpr(0, pWInfo->pWhere, 0); } - tdsqlite3DebugPrintf("All WHERE-clause terms before coding:\n"); - tdsqlite3WhereClausePrint(pWC); + sqlite3DebugPrintf("All WHERE-clause terms before coding:\n"); + sqlite3WhereClausePrint(pWC); } #endif @@ -144715,8 +144715,8 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( ** there are no IN operators in the constraints, the "addrNxt" label ** is the same as "addrBrk". */ - addrBrk = pLevel->addrBrk = pLevel->addrNxt = tdsqlite3VdbeMakeLabel(pParse); - addrCont = pLevel->addrCont = tdsqlite3VdbeMakeLabel(pParse); + addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse); + addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse); /* If this is the right table of a LEFT OUTER JOIN, allocate and ** initialize a memory cell that records if this table matches any @@ -144727,7 +144727,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( ); if( pLevel->iFrom>0 && (pTabItem[0].fg.jointype & JT_LEFT)!=0 ){ pLevel->iLeftJoin = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pLevel->iLeftJoin); VdbeComment((v, "init LEFT JOIN no-match flag")); } @@ -144739,8 +144739,8 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( /* Special case of a FROM clause subquery implemented as a co-routine */ if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; - tdsqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); - pLevel->p2 = tdsqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); + pLevel->p2 = sqlite3VdbeAddOp2(v, OP_Yield, regYield, addrBrk); VdbeCoverage(v); VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); pLevel->op = OP_Goto; @@ -144756,7 +144756,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( int nConstraint = pLoop->nLTerm; int iIn; /* Counter for IN constraints */ - iReg = tdsqlite3GetTempRange(pParse, nConstraint+2); + iReg = sqlite3GetTempRange(pParse, nConstraint+2); addrNotFound = pLevel->addrBrk; for(j=0; ju.vtab.idxNum, iReg); - tdsqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); - tdsqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, + sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg); + sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1); + sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg, pLoop->u.vtab.idxStr, pLoop->u.vtab.needFree ? P4_DYNAMIC : P4_STATIC); VdbeCoverage(v); pLoop->u.vtab.needFree = 0; pLevel->p1 = iCur; pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext; - pLevel->p2 = tdsqlite3VdbeCurrentAddr(v); + pLevel->p2 = sqlite3VdbeCurrentAddr(v); iIn = pLevel->u.in.nIn; for(j=nConstraint-1; j>=0; j--){ pTerm = pLoop->aLTerm[j]; @@ -144787,7 +144787,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){ disableTerm(pLevel, pTerm); }else if( (pTerm->eOperator & WO_IN)!=0 - && tdsqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1 + && sqlite3ExprVectorSize(pTerm->pExpr->pLeft)==1 ){ Expr *pCompare; /* The comparison operator */ Expr *pRight; /* RHS of the comparison */ @@ -144800,27 +144800,27 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed ); if( !db->mallocFailed ){ assert( iIn>=0 && iInu.in.nIn ); - pOp = tdsqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop); + pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[iIn].addrInTop); assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid ); assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 ); assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 ); testcase( pOp->opcode==OP_Rowid ); - tdsqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); + sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3); } /* Generate code that will continue to the next row if ** the IN constraint is not satisfied */ - pCompare = tdsqlite3PExpr(pParse, TK_EQ, 0, 0); + pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0); assert( pCompare!=0 || db->mallocFailed ); if( pCompare ){ pCompare->pLeft = pTerm->pExpr->pLeft; - pCompare->pRight = pRight = tdsqlite3Expr(db, TK_REGISTER, 0); + pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0); if( pRight ){ pRight->iTable = iReg+j+2; - tdsqlite3ExprIfFalse(pParse, pCompare, pLevel->addrCont, 0); + sqlite3ExprIfFalse(pParse, pCompare, pLevel->addrCont, 0); } pCompare->pLeft = 0; - tdsqlite3ExprDelete(db, pCompare); + sqlite3ExprDelete(db, pCompare); } } } @@ -144830,7 +144830,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( ** reuse them later) if (pLoop->wsFlags & WHERE_IN_ABLE)==0. But it seems ** simpler and safer to simply not reuse the registers. ** - ** tdsqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); + ** sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2); */ }else #endif /* SQLITE_OMIT_VIRTUALTABLE */ @@ -144850,9 +144850,9 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( testcase( pTerm->wtFlags & TERM_VIRTUAL ); iReleaseReg = ++pParse->nMem; iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg); - if( iRowidReg!=iReleaseReg ) tdsqlite3ReleaseTempReg(pParse, iReleaseReg); + if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg); addrNxt = pLevel->addrNxt; - tdsqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg); VdbeCoverage(v); pLevel->op = OP_Noop; if( (pTerm->prereqAll & pLevel->notReady)==0 ){ @@ -144902,8 +144902,8 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( pX = pStart->pExpr; assert( pX!=0 ); testcase( pStart->leftCursor!=iCur ); /* transitive constraints */ - if( tdsqlite3ExprIsVector(pX->pRight) ){ - r1 = rTemp = tdsqlite3GetTempReg(pParse); + if( sqlite3ExprIsVector(pX->pRight) ){ + r1 = rTemp = sqlite3GetTempReg(pParse); codeExprOrVector(pParse, pX->pRight, r1, 1); testcase( pX->op==TK_GT ); testcase( pX->op==TK_GE ); @@ -144915,19 +144915,19 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( assert( pX->op!=TK_LT || op==OP_SeekLE ); assert( pX->op!=TK_LE || op==OP_SeekLE ); }else{ - r1 = tdsqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); + r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp); disableTerm(pLevel, pStart); op = aMoveOp[(pX->op - TK_GT)]; } - tdsqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1); + sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1); VdbeComment((v, "pk")); VdbeCoverageIf(v, pX->op==TK_GT); VdbeCoverageIf(v, pX->op==TK_LE); VdbeCoverageIf(v, pX->op==TK_LT); VdbeCoverageIf(v, pX->op==TK_GE); - tdsqlite3ReleaseTempReg(pParse, rTemp); + sqlite3ReleaseTempReg(pParse, rTemp); }else{ - tdsqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); + sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iCur, addrHalt); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); } @@ -144940,31 +144940,31 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( testcase( pEnd->wtFlags & TERM_VIRTUAL ); memEndValue = ++pParse->nMem; codeExprOrVector(pParse, pX->pRight, memEndValue, 1); - if( 0==tdsqlite3ExprIsVector(pX->pRight) + if( 0==sqlite3ExprIsVector(pX->pRight) && (pX->op==TK_LT || pX->op==TK_GT) ){ testOp = bRev ? OP_Le : OP_Ge; }else{ testOp = bRev ? OP_Lt : OP_Gt; } - if( 0==tdsqlite3ExprIsVector(pX->pRight) ){ + if( 0==sqlite3ExprIsVector(pX->pRight) ){ disableTerm(pLevel, pEnd); } } - start = tdsqlite3VdbeCurrentAddr(v); + start = sqlite3VdbeCurrentAddr(v); pLevel->op = bRev ? OP_Prev : OP_Next; pLevel->p1 = iCur; pLevel->p2 = start; assert( pLevel->p5==0 ); if( testOp!=OP_Noop ){ iRowidReg = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); - tdsqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); + sqlite3VdbeAddOp2(v, OP_Rowid, iCur, iRowidReg); + sqlite3VdbeAddOp3(v, testOp, memEndValue, addrBrk, iRowidReg); VdbeCoverageIf(v, testOp==OP_Le); VdbeCoverageIf(v, testOp==OP_Lt); VdbeCoverageIf(v, testOp==OP_Ge); VdbeCoverageIf(v, testOp==OP_Gt); - tdsqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC | SQLITE_JUMPIFNULL); } }else if( pLoop->wsFlags & WHERE_INDEXED ){ /* Case 4: A scan using an index. @@ -145057,9 +145057,9 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( assert( pRangeStart!=0 ); /* LIKE opt constraints */ assert( pRangeStart->wtFlags & TERM_LIKEOPT ); /* occur in pairs */ pLevel->iLikeRepCntr = (u32)++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr); + sqlite3VdbeAddOp2(v, OP_Integer, 1, (int)pLevel->iLikeRepCntr); VdbeComment((v, "LIKE loop counter")); - pLevel->addrLikeRep = tdsqlite3VdbeCurrentAddr(v); + pLevel->addrLikeRep = sqlite3VdbeCurrentAddr(v); /* iLikeRepCntr actually stores 2x the counter register number. The ** bottom bit indicates whether the search order is ASC or DESC. */ testcase( bRev ); @@ -145094,7 +145094,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( nExtraReg = 1; bSeekPastNull = 1; pLevel->regBignull = regBignull = ++pParse->nMem; - pLevel->addrBignull = tdsqlite3VdbeMakeLabel(pParse); + pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse); } /* If we are doing a reverse order scan on an ascending index, or @@ -145115,9 +145115,9 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( */ codeCursorHint(pTabItem, pWInfo, pLevel, pRangeEnd); regBase = codeAllEqualityTerms(pParse,pLevel,bRev,nExtraReg,&zStartAff); - assert( zStartAff==0 || tdsqlite3Strlen30(zStartAff)>=nEq ); + assert( zStartAff==0 || sqlite3Strlen30(zStartAff)>=nEq ); if( zStartAff && nTop ){ - zEndAff = tdsqlite3DbStrDup(db, &zStartAff[nEq]); + zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); } addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt); @@ -145136,9 +145136,9 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( codeExprOrVector(pParse, pRight, regBase+nEq, nBtm); whereLikeOptimizationStringFixup(v, pLevel, pRangeStart); if( (pRangeStart->wtFlags & TERM_VNULL)==0 - && tdsqlite3ExprCanBeNull(pRight) + && sqlite3ExprCanBeNull(pRight) ){ - tdsqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); VdbeCoverage(v); } if( zStartAff ){ @@ -145146,7 +145146,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( } nConstraint += nBtm; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); - if( tdsqlite3ExprIsVector(pRight)==0 ){ + if( sqlite3ExprIsVector(pRight)==0 ){ disableTerm(pLevel, pRangeStart); }else{ startEq = 1; @@ -145154,11 +145154,11 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( bSeekPastNull = 0; }else if( bSeekPastNull ){ startEq = 0; - tdsqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); start_constraints = 1; nConstraint++; }else if( regBignull ){ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); start_constraints = 1; nConstraint++; } @@ -145169,16 +145169,16 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( ** so no further seeking is needed */ }else{ if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ - tdsqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); + sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); } if( regBignull ){ - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); VdbeComment((v, "NULL-scan pass ctr")); } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); - tdsqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); @@ -145192,9 +145192,9 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( assert( bSeekPastNull==1 || bStopAtNull==1 ); assert( bSeekPastNull==!bStopAtNull ); assert( bStopAtNull==startEq ); - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, tdsqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); op = aStartOp[(nConstraint>1)*4 + 2 + bRev]; - tdsqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint-startEq); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); @@ -145214,9 +145214,9 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( codeExprOrVector(pParse, pRight, regBase+nEq, nTop); whereLikeOptimizationStringFixup(v, pLevel, pRangeEnd); if( (pRangeEnd->wtFlags & TERM_VNULL)==0 - && tdsqlite3ExprCanBeNull(pRight) + && sqlite3ExprCanBeNull(pRight) ){ - tdsqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); VdbeCoverage(v); } if( zEndAff ){ @@ -145228,34 +145228,34 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( nConstraint += nTop; testcase( pRangeEnd->wtFlags & TERM_VIRTUAL ); - if( tdsqlite3ExprIsVector(pRight)==0 ){ + if( sqlite3ExprIsVector(pRight)==0 ){ disableTerm(pLevel, pRangeEnd); }else{ endEq = 1; } }else if( bStopAtNull ){ if( regBignull==0 ){ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); endEq = 0; } nConstraint++; } - tdsqlite3DbFree(db, zStartAff); - tdsqlite3DbFree(db, zEndAff); + sqlite3DbFree(db, zStartAff); + sqlite3DbFree(db, zEndAff); /* Top of the loop body */ - pLevel->p2 = tdsqlite3VdbeCurrentAddr(v); + pLevel->p2 = sqlite3VdbeCurrentAddr(v); /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ if( regBignull ){ /* Except, skip the end-of-range check while doing the NULL-scan */ - tdsqlite3VdbeAddOp2(v, OP_IfNot, regBignull, tdsqlite3VdbeCurrentAddr(v)+3); + sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3); VdbeComment((v, "If NULL-scan 2nd pass")); VdbeCoverage(v); } op = aEndOp[bRev*2 + endEq]; - tdsqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); @@ -145267,11 +145267,11 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( assert( bSeekPastNull==!bStopAtNull ); assert( bSeekPastNull+bStopAtNull==1 ); assert( nConstraint+bSeekPastNull>0 ); - tdsqlite3VdbeAddOp2(v, OP_If, regBignull, tdsqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2); VdbeComment((v, "If NULL-scan 1st pass")); VdbeCoverage(v); op = aEndOp[bRev*2 + bSeekPastNull]; - tdsqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint+bSeekPastNull); testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); @@ -145280,7 +145280,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( } if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ - tdsqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); + sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); } /* Seek the table cursor, if required */ @@ -145294,20 +145294,20 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( && (pWInfo->eOnePass==ONEPASS_SINGLE || pLoop->nLTerm==0) ) ){ iRowidReg = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); - tdsqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); + sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg); VdbeCoverage(v); }else{ codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur); } }else if( iCur!=iIdxCur ){ - Index *pPk = tdsqlite3PrimaryKeyIndex(pIdx->pTable); - iRowidReg = tdsqlite3GetTempRange(pParse, pPk->nKeyCol); + Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable); + iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol); for(j=0; jnKeyCol; j++){ - k = tdsqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); - tdsqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); + k = sqlite3TableColumnToIndex(pIdx, pPk->aiColumn[j]); + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j); } - tdsqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, + sqlite3VdbeAddOp4Int(v, OP_NotFound, iCur, addrCont, iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } @@ -145392,10 +145392,10 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( ** into the RowSet. If it is already present, control skips the ** Gosub opcode and jumps straight to the code generated by WhereEnd(). ** - ** tdsqlite3WhereBegin() + ** sqlite3WhereBegin() ** RowSetTest # Insert rowid into rowset ** Gosub 2 A - ** tdsqlite3WhereEnd() + ** sqlite3WhereEnd() ** ** Following the above, code to terminate the loop. Label A, the target ** of the Gosub above, jumps to the instruction right after the Goto. @@ -145422,7 +145422,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ int regRowset = 0; /* Register for RowSet object */ int regRowid = 0; /* Register holding rowid */ - int iLoopBody = tdsqlite3VdbeMakeLabel(pParse);/* Start of loop body */ + int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */ int iRetInit; /* Address of regReturn init */ int untestedTerms = 0; /* Some terms not completely tested */ int ii; /* Loop counter */ @@ -145440,13 +145440,13 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( /* Set up a new SrcList in pOrTab containing the table being scanned ** by this loop in the a[0] slot and all notReady tables in a[1..] slots. - ** This becomes the SrcList in the recursive call to tdsqlite3WhereBegin(). + ** This becomes the SrcList in the recursive call to sqlite3WhereBegin(). */ if( pWInfo->nLevel>1 ){ int nNotReady; /* The number of notReady tables */ struct SrcList_item *origSrc; /* Original list of tables */ nNotReady = pWInfo->nLevel - iLevel - 1; - pOrTab = tdsqlite3StackAllocRaw(db, + pOrTab = sqlite3StackAllocRaw(db, sizeof(*pOrTab)+ nNotReady*sizeof(pOrTab->a[0])); if( pOrTab==0 ) return notReady; pOrTab->nAlloc = (u8)(nNotReady + 1); @@ -145475,21 +145475,21 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ if( HasRowid(pTab) ){ regRowset = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); + sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset); }else{ - Index *pPk = tdsqlite3PrimaryKeyIndex(pTab); + Index *pPk = sqlite3PrimaryKeyIndex(pTab); regRowset = pParse->nTab++; - tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol); - tdsqlite3VdbeSetP4KeyInfo(pParse, pPk); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, regRowset, pPk->nKeyCol); + sqlite3VdbeSetP4KeyInfo(pParse, pPk); } regRowid = ++pParse->nMem; } - iRetInit = tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); + iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn); /* If the original WHERE clause is z of the form: (x1 OR x2 OR ...) AND y ** Then for every term xN, evaluate as the subexpression: xN AND z ** That way, terms in y that are factored into the disjunction will - ** be picked up by the recursive calls to tdsqlite3WhereBegin() below. + ** be picked up by the recursive calls to sqlite3WhereBegin() below. ** ** Actually, each subexpression is converted to "xN AND w" where w is ** the "interesting" terms of z - terms that did not originate in the @@ -145510,16 +145510,16 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue; if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue; testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO ); - pExpr = tdsqlite3ExprDup(db, pExpr, 0); - pAndExpr = tdsqlite3ExprAnd(pParse, pAndExpr, pExpr); + pExpr = sqlite3ExprDup(db, pExpr, 0); + pAndExpr = sqlite3ExprAnd(pParse, pAndExpr, pExpr); } if( pAndExpr ){ /* The extra 0x10000 bit on the opcode is masked off and does not ** become part of the new Expr.op. However, it does make the - ** op==TK_AND comparison inside of tdsqlite3PExpr() false, and this - ** prevents tdsqlite3PExpr() from implementing AND short-circuit + ** op==TK_AND comparison inside of sqlite3PExpr() false, and this + ** prevents sqlite3PExpr() from implementing AND short-circuit ** optimization, which we do not want here. */ - pAndExpr = tdsqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr); + pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr); } } @@ -145545,15 +145545,15 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( /* Loop through table entries that match term pOrTerm. */ ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1)); WHERETRACE(0xffff, ("Subplan for OR-clause:\n")); - pSubWInfo = tdsqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, + pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, wctrlFlags, iCovCur); assert( pSubWInfo || pParse->nErr || db->mallocFailed ); if( pSubWInfo ){ WhereLoop *pSubLoop; - int addrExplain = tdsqlite3WhereExplainOneScan( + int addrExplain = sqlite3WhereExplainOneScan( pParse, pOrTab, &pSubWInfo->a[0], 0 ); - tdsqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain); + sqlite3WhereAddScanStatus(v, pOrTab, &pSubWInfo->a[0], addrExplain); /* This is the sub-WHERE clause body. First skip over ** duplicate rows from prior sub-WHERE clauses, and record the @@ -145563,21 +145563,21 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){ int iSet = ((ii==pOrWc->nTerm-1)?-1:ii); if( HasRowid(pTab) ){ - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid); - jmp1 = tdsqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, -1, regRowid); + jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, regRowid, iSet); VdbeCoverage(v); }else{ - Index *pPk = tdsqlite3PrimaryKeyIndex(pTab); + Index *pPk = sqlite3PrimaryKeyIndex(pTab); int nPk = pPk->nKeyCol; int iPk; int r; /* Read the PK into an array of temp registers. */ - r = tdsqlite3GetTempRange(pParse, nPk); + r = sqlite3GetTempRange(pParse, nPk); for(iPk=0; iPkaiColumn[iPk]; - tdsqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); + sqlite3ExprCodeGetColumnOfTable(v, pTab, iCur, iCol,r+iPk); } /* Check if the temp table already contains this key. If so, @@ -145592,27 +145592,27 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( ** need to insert the key into the temp table, as it will never ** be tested for. */ if( iSet ){ - jmp1 = tdsqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); + jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); VdbeCoverage(v); } if( iSet>=0 ){ - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); - tdsqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid, + sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, regRowset, regRowid, r, nPk); - if( iSet ) tdsqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); } /* Release the array of temp registers */ - tdsqlite3ReleaseTempRange(pParse, r, nPk); + sqlite3ReleaseTempRange(pParse, r, nPk); } } /* Invoke the main loop body as a subroutine */ - tdsqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); + sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody); /* Jump here (skipping the main loop body subroutine) if the ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */ - if( jmp1 ) tdsqlite3VdbeJumpHere(v, jmp1); + if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1); /* The pSubWInfo->untestedTerms flag means that this OR term ** contained one or more AND term from a notReady table. The @@ -145623,10 +145623,10 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( /* If all of the OR-connected terms are optimized using the same ** index, and the index is opened using the same cursor number - ** by each call to tdsqlite3WhereBegin() made by this loop, it may + ** by each call to sqlite3WhereBegin() made by this loop, it may ** be possible to use that index as a covering index. ** - ** If the call to tdsqlite3WhereBegin() above resulted in a scan that + ** If the call to sqlite3WhereBegin() above resulted in a scan that ** uses an index, and this is either the first OR-connected term ** processed or the index is the same as that used by all previous ** terms, set pCov to the candidate covering index. Otherwise, set @@ -145646,7 +145646,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( } /* Finish the loop through table entries that match term pOrTerm. */ - tdsqlite3WhereEnd(pSubWInfo); + sqlite3WhereEnd(pSubWInfo); ExplainQueryPlanPop(pParse); } } @@ -145656,13 +145656,13 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( if( pCov ) pLevel->iIdxCur = iCovCur; if( pAndExpr ){ pAndExpr->pLeft = 0; - tdsqlite3ExprDelete(db, pAndExpr); + sqlite3ExprDelete(db, pAndExpr); } - tdsqlite3VdbeChangeP1(v, iRetInit, tdsqlite3VdbeCurrentAddr(v)); - tdsqlite3VdbeGoto(v, pLevel->addrBrk); - tdsqlite3VdbeResolveLabel(v, iLoopBody); + sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeGoto(v, pLevel->addrBrk); + sqlite3VdbeResolveLabel(v, iLoopBody); - if( pWInfo->nLevel>1 ){ tdsqlite3StackFree(db, pOrTab); } + if( pWInfo->nLevel>1 ){ sqlite3StackFree(db, pOrTab); } if( !untestedTerms ) disableTerm(pLevel, pTerm); }else #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ @@ -145682,7 +145682,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( codeCursorHint(pTabItem, pWInfo, pLevel, 0); pLevel->op = aStep[bRev]; pLevel->p1 = iCur; - pLevel->p2 = 1 + tdsqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt); + pLevel->p2 = 1 + sqlite3VdbeAddOp2(v, aStart[bRev], iCur, addrHalt); VdbeCoverageIf(v, bRev==0); VdbeCoverageIf(v, bRev!=0); pLevel->p5 = SQLITE_STMTSTATUS_FULLSCAN_STEP; @@ -145690,7 +145690,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( } #ifdef SQLITE_ENABLE_STMT_SCANSTATUS - pLevel->addrVisit = tdsqlite3VdbeCurrentAddr(v); + pLevel->addrVisit = sqlite3VdbeCurrentAddr(v); #endif /* Insert code to test every subexpression that can be completely @@ -145728,7 +145728,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( continue; } - if( iLoop==1 && !tdsqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ + if( iLoop==1 && !sqlite3ExprCoveredByIndex(pE, pLevel->iTabCur, pIdx) ){ iNext = 2; continue; } @@ -145748,24 +145748,24 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( #else u32 x = pLevel->iLikeRepCntr; if( x>0 ){ - skipLikeAddr = tdsqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1)); + skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1)); VdbeCoverageIf(v, (x&1)==1); VdbeCoverageIf(v, (x&1)==0); } #endif } #ifdef WHERETRACE_ENABLED /* 0xffff */ - if( tdsqlite3WhereTrace ){ + if( sqlite3WhereTrace ){ VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d", pWC->nTerm-j, pTerm, iLoop)); } - if( tdsqlite3WhereTrace & 0x800 ){ - tdsqlite3DebugPrintf("Coding auxiliary constraint:\n"); - tdsqlite3WhereTermPrint(pTerm, pWC->nTerm-j); + if( sqlite3WhereTrace & 0x800 ){ + sqlite3DebugPrintf("Coding auxiliary constraint:\n"); + sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); } #endif - tdsqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); - if( skipLikeAddr ) tdsqlite3VdbeJumpHere(v, skipLikeAddr); + sqlite3ExprIfFalse(pParse, pE, addrCont, SQLITE_JUMPIFNULL); + if( skipLikeAddr ) sqlite3VdbeJumpHere(v, skipLikeAddr); pTerm->wtFlags |= TERM_CODED; } iLoop = iNext; @@ -145789,14 +145789,14 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( if( pTabItem->fg.jointype & JT_LEFT ) continue; pE = pTerm->pExpr; #ifdef WHERETRACE_ENABLED /* 0x800 */ - if( tdsqlite3WhereTrace & 0x800 ){ - tdsqlite3DebugPrintf("Coding transitive constraint:\n"); - tdsqlite3WhereTermPrint(pTerm, pWC->nTerm-j); + if( sqlite3WhereTrace & 0x800 ){ + sqlite3DebugPrintf("Coding transitive constraint:\n"); + sqlite3WhereTermPrint(pTerm, pWC->nTerm-j); } #endif assert( !ExprHasProperty(pE, EP_FromJoin) ); assert( (pTerm->prereqRight & pLevel->notReady)!=0 ); - pAlt = tdsqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady, + pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady, WO_EQ|WO_IN|WO_IS, 0); if( pAlt==0 ) continue; if( pAlt->wtFlags & (TERM_CODED) ) continue; @@ -145812,15 +145812,15 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( VdbeModuleComment((v, "begin transitive constraint")); sEAlt = *pAlt->pExpr; sEAlt.pLeft = pE->pLeft; - tdsqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL); } /* For a LEFT OUTER JOIN, generate code that will record the fact that ** at least one row of the right table has matched the left table. */ if( pLevel->iLeftJoin ){ - pLevel->addrFirst = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); + pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->iLeftJoin); VdbeComment((v, "record LEFT JOIN hit")); for(pTerm=pWC->a, j=0; jnTerm; j++, pTerm++){ testcase( pTerm->wtFlags & TERM_VIRTUAL ); @@ -145831,19 +145831,19 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereCodeOneLoopStart( continue; } assert( pTerm->pExpr ); - tdsqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pTerm->pExpr, addrCont, SQLITE_JUMPIFNULL); pTerm->wtFlags |= TERM_CODED; } } #if WHERETRACE_ENABLED /* 0x20800 */ - if( tdsqlite3WhereTrace & 0x20000 ){ - tdsqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", + if( sqlite3WhereTrace & 0x20000 ){ + sqlite3DebugPrintf("All WHERE-clause terms after coding level %d:\n", iLevel); - tdsqlite3WhereClausePrint(pWC); + sqlite3WhereClausePrint(pWC); } - if( tdsqlite3WhereTrace & 0x800 ){ - tdsqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", + if( sqlite3WhereTrace & 0x800 ){ + sqlite3DebugPrintf("End Coding level %d: notReady=%llx\n", iLevel, (u64)pLevel->notReady); } #endif @@ -145879,17 +145879,17 @@ static void exprAnalyze(SrcList*, WhereClause*, int); /* ** Deallocate all memory associated with a WhereOrInfo object. */ -static void whereOrInfoDelete(tdsqlite3 *db, WhereOrInfo *p){ - tdsqlite3WhereClauseClear(&p->wc); - tdsqlite3DbFree(db, p); +static void whereOrInfoDelete(sqlite3 *db, WhereOrInfo *p){ + sqlite3WhereClauseClear(&p->wc); + sqlite3DbFree(db, p); } /* ** Deallocate all memory associated with a WhereAndInfo object. */ -static void whereAndInfoDelete(tdsqlite3 *db, WhereAndInfo *p){ - tdsqlite3WhereClauseClear(&p->wc); - tdsqlite3DbFree(db, p); +static void whereAndInfoDelete(sqlite3 *db, WhereAndInfo *p){ + sqlite3WhereClauseClear(&p->wc); + sqlite3DbFree(db, p); } /* @@ -145917,28 +145917,28 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ testcase( wtFlags & TERM_VIRTUAL ); if( pWC->nTerm>=pWC->nSlot ){ WhereTerm *pOld = pWC->a; - tdsqlite3 *db = pWC->pWInfo->pParse->db; - pWC->a = tdsqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); + sqlite3 *db = pWC->pWInfo->pParse->db; + pWC->a = sqlite3DbMallocRawNN(db, sizeof(pWC->a[0])*pWC->nSlot*2 ); if( pWC->a==0 ){ if( wtFlags & TERM_DYNAMIC ){ - tdsqlite3ExprDelete(db, p); + sqlite3ExprDelete(db, p); } pWC->a = pOld; return 0; } memcpy(pWC->a, pOld, sizeof(pWC->a[0])*pWC->nTerm); if( pOld!=pWC->aStatic ){ - tdsqlite3DbFree(db, pOld); + sqlite3DbFree(db, pOld); } - pWC->nSlot = tdsqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); + pWC->nSlot = sqlite3DbMallocSize(db, pWC->a)/sizeof(pWC->a[0]); } pTerm = &pWC->a[idx = pWC->nTerm++]; if( p && ExprHasProperty(p, EP_Unlikely) ){ - pTerm->truthProb = tdsqlite3LogEst(p->iTable) - 270; + pTerm->truthProb = sqlite3LogEst(p->iTable) - 270; }else{ pTerm->truthProb = 1; } - pTerm->pExpr = tdsqlite3ExprSkipCollateAndLikely(p); + pTerm->pExpr = sqlite3ExprSkipCollateAndLikely(p); pTerm->wtFlags = wtFlags; pTerm->pWC = pWC; pTerm->iParent = -1; @@ -145967,8 +145967,8 @@ static int allowedOp(int op){ static u16 exprCommute(Parse *pParse, Expr *pExpr){ if( pExpr->pLeft->op==TK_VECTOR || pExpr->pRight->op==TK_VECTOR - || tdsqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) != - tdsqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft) + || sqlite3BinaryCompareCollSeq(pParse, pExpr->pLeft, pExpr->pRight) != + sqlite3BinaryCompareCollSeq(pParse, pExpr->pRight, pExpr->pLeft) ){ pExpr->flags ^= EP_Commuted; } @@ -146038,12 +146038,12 @@ static int isLikeOrGlob( u8 c; /* One character in z[] */ int cnt; /* Number of non-wildcard prefix characters */ u8 wc[4]; /* Wildcard characters */ - tdsqlite3 *db = pParse->db; /* Database connection */ - tdsqlite3_value *pVal = 0; + sqlite3 *db = pParse->db; /* Database connection */ + sqlite3_value *pVal = 0; int op; /* Opcode of pRight */ int rc; /* Result code to return */ - if( !tdsqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){ + if( !sqlite3IsLikeFunction(db, pExpr, pnoCase, (char*)wc) ){ return 0; } #ifdef SQLITE_EBCDIC @@ -146052,16 +146052,16 @@ static int isLikeOrGlob( pList = pExpr->x.pList; pLeft = pList->a[1].pExpr; - pRight = tdsqlite3ExprSkipCollate(pList->a[0].pExpr); + pRight = sqlite3ExprSkipCollate(pList->a[0].pExpr); op = pRight->op; if( op==TK_VARIABLE && (db->flags & SQLITE_EnableQPSG)==0 ){ Vdbe *pReprepare = pParse->pReprepare; int iCol = pRight->iColumn; - pVal = tdsqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB); - if( pVal && tdsqlite3_value_type(pVal)==SQLITE_TEXT ){ - z = tdsqlite3_value_text(pVal); + pVal = sqlite3VdbeGetBoundValue(pReprepare, iCol, SQLITE_AFF_BLOB); + if( pVal && sqlite3_value_type(pVal)==SQLITE_TEXT ){ + z = sqlite3_value_text(pVal); } - tdsqlite3VdbeSetVarmask(pParse->pVdbe, iCol); + sqlite3VdbeSetVarmask(pParse->pVdbe, iCol); assert( pRight->op==TK_VARIABLE || pRight->op==TK_REGISTER ); }else if( op==TK_STRING ){ z = (u8*)pRight->u.zToken; @@ -146090,7 +146090,7 @@ static int isLikeOrGlob( *pisComplete = c==wc[0] && z[cnt+1]==0; /* Get the pattern prefix. Remove all escapes from the prefix. */ - pPrefix = tdsqlite3Expr(db, TK_STRING, (char*)z); + pPrefix = sqlite3Expr(db, TK_STRING, (char*)z); if( pPrefix ){ int iFrom, iTo; char *zNew = pPrefix->u.zToken; @@ -146116,24 +146116,24 @@ static int isLikeOrGlob( ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a */ if( pLeft->op!=TK_COLUMN - || tdsqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT + || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT || IsVirtual(pLeft->y.pTab) /* Value might be numeric */ ){ int isNum; double rDummy; - isNum = tdsqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); + isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); if( isNum<=0 ){ if( iTo==1 && zNew[0]=='-' ){ isNum = +1; }else{ zNew[iTo-1]++; - isNum = tdsqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); + isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8); zNew[iTo-1]--; } } if( isNum>0 ){ - tdsqlite3ExprDelete(db, pPrefix); - tdsqlite3ValueFree(pVal); + sqlite3ExprDelete(db, pPrefix); + sqlite3ValueFree(pVal); return 0; } } @@ -146144,18 +146144,18 @@ static int isLikeOrGlob( ** reprepare the statement when that parameter is rebound */ if( op==TK_VARIABLE ){ Vdbe *v = pParse->pVdbe; - tdsqlite3VdbeSetVarmask(v, pRight->iColumn); + sqlite3VdbeSetVarmask(v, pRight->iColumn); if( *pisComplete && pRight->u.zToken[1] ){ /* If the rhs of the LIKE expression is a variable, and the current ** value of the variable means there is no need to invoke the LIKE ** function, then no OP_Variable will be added to the program. - ** This causes problems for the tdsqlite3_bind_parameter_name() + ** This causes problems for the sqlite3_bind_parameter_name() ** API. To work around them, add a dummy OP_Variable here. */ - int r1 = tdsqlite3GetTempReg(pParse); - tdsqlite3ExprCodeTarget(pParse, pRight, r1); - tdsqlite3VdbeChangeP3(v, tdsqlite3VdbeCurrentAddr(v)-1, 0); - tdsqlite3ReleaseTempReg(pParse, r1); + int r1 = sqlite3GetTempReg(pParse); + sqlite3ExprCodeTarget(pParse, pRight, r1); + sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0); + sqlite3ReleaseTempReg(pParse, r1); } } }else{ @@ -146164,7 +146164,7 @@ static int isLikeOrGlob( } rc = (z!=0); - tdsqlite3ValueFree(pVal); + sqlite3ValueFree(pVal); return rc; } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ @@ -146198,7 +146198,7 @@ static int isLikeOrGlob( ** If the expression matches none of the patterns above, return 0. */ static int isAuxiliaryVtabOperator( - tdsqlite3 *db, /* Parsing context */ + sqlite3 *db, /* Parsing context */ Expr *pExpr, /* Test this expression */ unsigned char *peOp2, /* OUT: 0 for MATCH, or else an op2 value */ Expr **ppLeft, /* Column expression to left of MATCH/op2 */ @@ -146233,7 +146233,7 @@ static int isAuxiliaryVtabOperator( pCol = pList->a[1].pExpr; if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ for(i=0; iu.zToken, aOp[i].zOp)==0 ){ + if( sqlite3StrICmp(pExpr->u.zToken, aOp[i].zOp)==0 ){ *peOp2 = aOp[i].eOp2; *ppRight = pList->a[0].pExpr; *ppLeft = pCol; @@ -146254,14 +146254,14 @@ static int isAuxiliaryVtabOperator( */ pCol = pList->a[0].pExpr; if( pCol->op==TK_COLUMN && IsVirtual(pCol->y.pTab) ){ - tdsqlite3_vtab *pVtab; - tdsqlite3_module *pMod; - void (*xNotUsed)(tdsqlite3_context*,int,tdsqlite3_value**); + sqlite3_vtab *pVtab; + sqlite3_module *pMod; + void (*xNotUsed)(sqlite3_context*,int,sqlite3_value**); void *pNotUsed; - pVtab = tdsqlite3GetVTable(db, pCol->y.pTab)->pVtab; + pVtab = sqlite3GetVTable(db, pCol->y.pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); - pMod = (tdsqlite3_module *)pVtab->pModule; + pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction!=0 ){ i = pMod->xFindFunction(pVtab,2, pExpr->u.zToken, &xNotUsed, &pNotUsed); if( i>=SQLITE_INDEX_CONSTRAINT_FUNCTION ){ @@ -146356,7 +146356,7 @@ static void whereCombineDisjuncts( WhereTerm *pTwo /* Second disjunct */ ){ u16 eOp = pOne->eOperator | pTwo->eOperator; - tdsqlite3 *db; /* Database connection (for malloc) */ + sqlite3 *db; /* Database connection (for malloc) */ Expr *pNew; /* New virtual expression */ int op; /* Operator for the combined expression */ int idxNew; /* Index in pWC of the next virtual term */ @@ -146367,8 +146367,8 @@ static void whereCombineDisjuncts( && (eOp & (WO_EQ|WO_GT|WO_GE))!=eOp ) return; assert( pOne->pExpr->pLeft!=0 && pOne->pExpr->pRight!=0 ); assert( pTwo->pExpr->pLeft!=0 && pTwo->pExpr->pRight!=0 ); - if( tdsqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; - if( tdsqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return; + if( sqlite3ExprCompare(0,pOne->pExpr->pLeft, pTwo->pExpr->pLeft, -1) ) return; + if( sqlite3ExprCompare(0,pOne->pExpr->pRight, pTwo->pExpr->pRight,-1) )return; /* If we reach this point, it means the two subterms can be combined */ if( (eOp & (eOp-1))!=0 ){ if( eOp & (WO_LT|WO_LE) ){ @@ -146379,7 +146379,7 @@ static void whereCombineDisjuncts( } } db = pWC->pWInfo->pParse->db; - pNew = tdsqlite3ExprDup(db, pOne->pExpr, 0); + pNew = sqlite3ExprDup(db, pOne->pExpr, 0); if( pNew==0 ) return; for(op=TK_EQ; eOp!=(WO_EQ<<(op-TK_EQ)); op++){ assert( opop = op; @@ -146482,7 +146482,7 @@ static void exprAnalyzeOrTerm( ){ WhereInfo *pWInfo = pWC->pWInfo; /* WHERE clause processing context */ Parse *pParse = pWInfo->pParse; /* Parser context */ - tdsqlite3 *db = pParse->db; /* Database connection */ + sqlite3 *db = pParse->db; /* Database connection */ WhereTerm *pTerm = &pWC->a[idxTerm]; /* The term to be analyzed */ Expr *pExpr = pTerm->pExpr; /* The expression of the term */ int i; /* Loop counters */ @@ -146499,14 +146499,14 @@ static void exprAnalyzeOrTerm( */ assert( (pTerm->wtFlags & (TERM_DYNAMIC|TERM_ORINFO|TERM_ANDINFO))==0 ); assert( pExpr->op==TK_OR ); - pTerm->u.pOrInfo = pOrInfo = tdsqlite3DbMallocZero(db, sizeof(*pOrInfo)); + pTerm->u.pOrInfo = pOrInfo = sqlite3DbMallocZero(db, sizeof(*pOrInfo)); if( pOrInfo==0 ) return; pTerm->wtFlags |= TERM_ORINFO; pOrWc = &pOrInfo->wc; memset(pOrWc->aStatic, 0, sizeof(pOrWc->aStatic)); - tdsqlite3WhereClauseInit(pOrWc, pWInfo); - tdsqlite3WhereSplit(pOrWc, pExpr, TK_OR); - tdsqlite3WhereExprAnalyze(pSrc, pOrWc); + sqlite3WhereClauseInit(pOrWc, pWInfo); + sqlite3WhereSplit(pOrWc, pExpr, TK_OR); + sqlite3WhereExprAnalyze(pSrc, pOrWc); if( db->mallocFailed ) return; assert( pOrWc->nTerm>=2 ); @@ -146520,7 +146520,7 @@ static void exprAnalyzeOrTerm( WhereAndInfo *pAndInfo; assert( (pOrTerm->wtFlags & (TERM_ANDINFO|TERM_ORINFO))==0 ); chngToIN = 0; - pAndInfo = tdsqlite3DbMallocRawNN(db, sizeof(*pAndInfo)); + pAndInfo = sqlite3DbMallocRawNN(db, sizeof(*pAndInfo)); if( pAndInfo ){ WhereClause *pAndWC; WhereTerm *pAndTerm; @@ -146531,9 +146531,9 @@ static void exprAnalyzeOrTerm( pOrTerm->eOperator = WO_AND; pAndWC = &pAndInfo->wc; memset(pAndWC->aStatic, 0, sizeof(pAndWC->aStatic)); - tdsqlite3WhereClauseInit(pAndWC, pWC->pWInfo); - tdsqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND); - tdsqlite3WhereExprAnalyze(pSrc, pAndWC); + sqlite3WhereClauseInit(pAndWC, pWC->pWInfo); + sqlite3WhereSplit(pAndWC, pOrTerm->pExpr, TK_AND); + sqlite3WhereExprAnalyze(pSrc, pAndWC); pAndWC->pOuter = pWC; if( !db->mallocFailed ){ for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ @@ -146541,7 +146541,7 @@ static void exprAnalyzeOrTerm( if( allowedOp(pAndTerm->pExpr->op) || pAndTerm->eOperator==WO_AUX ){ - b |= tdsqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); + b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); } } } @@ -146552,10 +146552,10 @@ static void exprAnalyzeOrTerm( ** corresponding TERM_VIRTUAL term */ }else{ Bitmask b; - b = tdsqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor); + b = sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor); if( pOrTerm->wtFlags & TERM_VIRTUAL ){ WhereTerm *pOther = &pOrWc->a[pOrTerm->iParent]; - b |= tdsqlite3WhereGetMask(&pWInfo->sMaskSet, pOther->leftCursor); + b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pOther->leftCursor); } indexable &= b; if( (pOrTerm->eOperator & WO_EQ)==0 ){ @@ -146637,7 +146637,7 @@ static void exprAnalyzeOrTerm( assert( j==1 ); continue; } - if( (chngToIN & tdsqlite3WhereGetMask(&pWInfo->sMaskSet, + if( (chngToIN & sqlite3WhereGetMask(&pWInfo->sMaskSet, pOrTerm->leftCursor))==0 ){ /* This term must be of the form t1.a==t2.b where t2 is in the ** chngToIN set but t1 is not. This term will be either preceded @@ -146658,7 +146658,7 @@ static void exprAnalyzeOrTerm( ** on the second iteration */ assert( j==1 ); assert( IsPowerOfTwo(chngToIN) ); - assert( chngToIN==tdsqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) ); + assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) ); break; } testcase( j==1 ); @@ -146671,7 +146671,7 @@ static void exprAnalyzeOrTerm( if( pOrTerm->leftCursor!=iCursor ){ pOrTerm->wtFlags &= ~TERM_OR_OK; }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR - && tdsqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) + && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) )){ okToChngToIN = 0; }else{ @@ -146680,8 +146680,8 @@ static void exprAnalyzeOrTerm( ** of both right and left sides must be such that no type ** conversions are required on the right. (Ticket #2249) */ - affRight = tdsqlite3ExprAffinity(pOrTerm->pExpr->pRight); - affLeft = tdsqlite3ExprAffinity(pOrTerm->pExpr->pLeft); + affRight = sqlite3ExprAffinity(pOrTerm->pExpr->pRight); + affLeft = sqlite3ExprAffinity(pOrTerm->pExpr->pLeft); if( affRight!=0 && affRight!=affLeft ){ okToChngToIN = 0; }else{ @@ -146706,13 +146706,13 @@ static void exprAnalyzeOrTerm( assert( pOrTerm->eOperator & WO_EQ ); assert( pOrTerm->leftCursor==iCursor ); assert( pOrTerm->u.leftColumn==iColumn ); - pDup = tdsqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); - pList = tdsqlite3ExprListAppend(pWInfo->pParse, pList, pDup); + pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight, 0); + pList = sqlite3ExprListAppend(pWInfo->pParse, pList, pDup); pLeft = pOrTerm->pExpr->pLeft; } assert( pLeft!=0 ); - pDup = tdsqlite3ExprDup(db, pLeft, 0); - pNew = tdsqlite3PExpr(pParse, TK_IN, pDup, 0); + pDup = sqlite3ExprDup(db, pLeft, 0); + pNew = sqlite3PExpr(pParse, TK_IN, pDup, 0); if( pNew ){ int idxNew; transferJoinMarkings(pNew, pExpr); @@ -146724,7 +146724,7 @@ static void exprAnalyzeOrTerm( /* pTerm = &pWC->a[idxTerm]; // would be needed if pTerm where used again */ markTermAsChild(pWC, idxNew, idxTerm); }else{ - tdsqlite3ExprListDelete(db, pList); + sqlite3ExprListDelete(db, pList); } } } @@ -146752,16 +146752,16 @@ static int termIsEquivalence(Parse *pParse, Expr *pExpr){ if( !OptimizationEnabled(pParse->db, SQLITE_Transitive) ) return 0; if( pExpr->op!=TK_EQ && pExpr->op!=TK_IS ) return 0; if( ExprHasProperty(pExpr, EP_FromJoin) ) return 0; - aff1 = tdsqlite3ExprAffinity(pExpr->pLeft); - aff2 = tdsqlite3ExprAffinity(pExpr->pRight); + aff1 = sqlite3ExprAffinity(pExpr->pLeft); + aff2 = sqlite3ExprAffinity(pExpr->pRight); if( aff1!=aff2 - && (!tdsqlite3IsNumericAffinity(aff1) || !tdsqlite3IsNumericAffinity(aff2)) + && (!sqlite3IsNumericAffinity(aff1) || !sqlite3IsNumericAffinity(aff2)) ){ return 0; } - pColl = tdsqlite3ExprCompareCollSeq(pParse, pExpr); - if( tdsqlite3IsBinary(pColl) ) return 1; - return tdsqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); + pColl = sqlite3ExprCompareCollSeq(pParse, pExpr); + if( sqlite3IsBinary(pColl) ) return 1; + return sqlite3ExprCollSeqMatch(pParse, pExpr->pLeft, pExpr->pRight); } /* @@ -146773,18 +146773,18 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ Bitmask mask = 0; while( pS ){ SrcList *pSrc = pS->pSrc; - mask |= tdsqlite3WhereExprListUsage(pMaskSet, pS->pEList); - mask |= tdsqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy); - mask |= tdsqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy); - mask |= tdsqlite3WhereExprUsage(pMaskSet, pS->pWhere); - mask |= tdsqlite3WhereExprUsage(pMaskSet, pS->pHaving); + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pEList); + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pGroupBy); + mask |= sqlite3WhereExprListUsage(pMaskSet, pS->pOrderBy); + mask |= sqlite3WhereExprUsage(pMaskSet, pS->pWhere); + mask |= sqlite3WhereExprUsage(pMaskSet, pS->pHaving); if( ALWAYS(pSrc!=0) ){ int i; for(i=0; inSrc; i++){ mask |= exprSelectUsage(pMaskSet, pSrc->a[i].pSelect); - mask |= tdsqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn); + mask |= sqlite3WhereExprUsage(pMaskSet, pSrc->a[i].pOn); if( pSrc->a[i].fg.isTabFunc ){ - mask |= tdsqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); + mask |= sqlite3WhereExprListUsage(pMaskSet, pSrc->a[i].u1.pFuncArg); } } } @@ -146821,7 +146821,7 @@ static SQLITE_NOINLINE int exprMightBeIndexed2( if( pIdx->aColExpr==0 ) continue; for(i=0; inKeyCol; i++){ if( pIdx->aiColumn[i]!=XN_EXPR ) continue; - if( tdsqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ + if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ aiCurCol[0] = iCur; aiCurCol[1] = XN_EXPR; return 1; @@ -146892,7 +146892,7 @@ static void exprAnalyze( int noCase = 0; /* uppercase equivalent to lowercase */ int op; /* Top-level operator. pExpr->op */ Parse *pParse = pWInfo->pParse; /* Parsing context */ - tdsqlite3 *db = pParse->db; /* Database connection */ + sqlite3 *db = pParse->db; /* Database connection */ unsigned char eOp2 = 0; /* op2 value for LIKE/REGEXP/GLOB */ int nLeft; /* Number of elements on left side vector */ @@ -146903,31 +146903,31 @@ static void exprAnalyze( pMaskSet = &pWInfo->sMaskSet; pExpr = pTerm->pExpr; assert( pExpr->op!=TK_AS && pExpr->op!=TK_COLLATE ); - prereqLeft = tdsqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); + prereqLeft = sqlite3WhereExprUsage(pMaskSet, pExpr->pLeft); op = pExpr->op; if( op==TK_IN ){ assert( pExpr->pRight==0 ); - if( tdsqlite3ExprCheckIN(pParse, pExpr) ) return; + if( sqlite3ExprCheckIN(pParse, pExpr) ) return; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ pTerm->prereqRight = exprSelectUsage(pMaskSet, pExpr->x.pSelect); }else{ - pTerm->prereqRight = tdsqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList); + pTerm->prereqRight = sqlite3WhereExprListUsage(pMaskSet, pExpr->x.pList); } }else if( op==TK_ISNULL ){ pTerm->prereqRight = 0; }else{ - pTerm->prereqRight = tdsqlite3WhereExprUsage(pMaskSet, pExpr->pRight); + pTerm->prereqRight = sqlite3WhereExprUsage(pMaskSet, pExpr->pRight); } pMaskSet->bVarSelect = 0; - prereqAll = tdsqlite3WhereExprUsageNN(pMaskSet, pExpr); + prereqAll = sqlite3WhereExprUsageNN(pMaskSet, pExpr); if( pMaskSet->bVarSelect ) pTerm->wtFlags |= TERM_VARSELECT; if( ExprHasProperty(pExpr, EP_FromJoin) ){ - Bitmask x = tdsqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); + Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable); prereqAll |= x; extraRight = x-1; /* ON clause terms may not be used with an index ** on left table of a LEFT JOIN. Ticket #3015 */ if( (prereqAll>>1)>=x ){ - tdsqlite3ErrorMsg(pParse, "ON clause references tables to its right"); + sqlite3ErrorMsg(pParse, "ON clause references tables to its right"); return; } } @@ -146937,8 +146937,8 @@ static void exprAnalyze( pTerm->eOperator = 0; if( allowedOp(op) ){ int aiCurCol[2]; - Expr *pLeft = tdsqlite3ExprSkipCollate(pExpr->pLeft); - Expr *pRight = tdsqlite3ExprSkipCollate(pExpr->pRight); + Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); + Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; if( pTerm->iField>0 ){ @@ -146962,9 +146962,9 @@ static void exprAnalyze( assert( pTerm->iField==0 ); if( pTerm->leftCursor>=0 ){ int idxNew; - pDup = tdsqlite3ExprDup(db, pExpr, 0); + pDup = sqlite3ExprDup(db, pExpr, 0); if( db->mallocFailed ){ - tdsqlite3ExprDelete(db, pDup); + sqlite3ExprDelete(db, pDup); return; } idxNew = whereClauseInsert(pWC, pDup, TERM_VIRTUAL|TERM_DYNAMIC); @@ -147018,9 +147018,9 @@ static void exprAnalyze( for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; - pNewExpr = tdsqlite3PExpr(pParse, ops[i], - tdsqlite3ExprDup(db, pExpr->pLeft, 0), - tdsqlite3ExprDup(db, pList->a[i].pExpr, 0)); + pNewExpr = sqlite3PExpr(pParse, ops[i], + sqlite3ExprDup(db, pExpr->pLeft, 0), + sqlite3ExprDup(db, pList->a[i].pExpr, 0)); transferJoinMarkings(pNewExpr, pExpr); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC); testcase( idxNew==0 ); @@ -147069,7 +147069,7 @@ static void exprAnalyze( const u16 wtFlags = TERM_LIKEOPT | TERM_VIRTUAL | TERM_DYNAMIC; pLeft = pExpr->x.pList->a[1].pExpr; - pStr2 = tdsqlite3ExprDup(db, pStr1, 0); + pStr2 = sqlite3ExprDup(db, pStr1, 0); /* Convert the lower bound to upper-case and the upper bound to ** lower-case (upper-case is less than lower-case in ASCII) so that @@ -147080,14 +147080,14 @@ static void exprAnalyze( char c; pTerm->wtFlags |= TERM_LIKE; for(i=0; (c = pStr1->u.zToken[i])!=0; i++){ - pStr1->u.zToken[i] = tdsqlite3Toupper(c); - pStr2->u.zToken[i] = tdsqlite3Tolower(c); + pStr1->u.zToken[i] = sqlite3Toupper(c); + pStr2->u.zToken[i] = sqlite3Tolower(c); } } if( !db->mallocFailed ){ u8 c, *pC; /* Last character before the first wildcard */ - pC = (u8*)&pStr2->u.zToken[tdsqlite3Strlen30(pStr2->u.zToken)-1]; + pC = (u8*)&pStr2->u.zToken[sqlite3Strlen30(pStr2->u.zToken)-1]; c = *pC; if( noCase ){ /* The point is to increment the last character before the first @@ -147097,22 +147097,22 @@ static void exprAnalyze( ** LIKE on all candidate expressions by clearing the isComplete flag */ if( c=='A'-1 ) isComplete = 0; - c = tdsqlite3UpperToLower[c]; + c = sqlite3UpperToLower[c]; } *pC = c + 1; } - zCollSeqName = noCase ? "NOCASE" : tdsqlite3StrBINARY; - pNewExpr1 = tdsqlite3ExprDup(db, pLeft, 0); - pNewExpr1 = tdsqlite3PExpr(pParse, TK_GE, - tdsqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), + zCollSeqName = noCase ? "NOCASE" : sqlite3StrBINARY; + pNewExpr1 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr1 = sqlite3PExpr(pParse, TK_GE, + sqlite3ExprAddCollateString(pParse,pNewExpr1,zCollSeqName), pStr1); transferJoinMarkings(pNewExpr1, pExpr); idxNew1 = whereClauseInsert(pWC, pNewExpr1, wtFlags); testcase( idxNew1==0 ); exprAnalyze(pSrc, pWC, idxNew1); - pNewExpr2 = tdsqlite3ExprDup(db, pLeft, 0); - pNewExpr2 = tdsqlite3PExpr(pParse, TK_LT, - tdsqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), + pNewExpr2 = sqlite3ExprDup(db, pLeft, 0); + pNewExpr2 = sqlite3PExpr(pParse, TK_LT, + sqlite3ExprAddCollateString(pParse,pNewExpr2,zCollSeqName), pStr2); transferJoinMarkings(pNewExpr2, pExpr); idxNew2 = whereClauseInsert(pWC, pNewExpr2, wtFlags); @@ -147144,12 +147144,12 @@ static void exprAnalyze( WhereTerm *pNewTerm; Bitmask prereqColumn, prereqExpr; - prereqExpr = tdsqlite3WhereExprUsage(pMaskSet, pRight); - prereqColumn = tdsqlite3WhereExprUsage(pMaskSet, pLeft); + prereqExpr = sqlite3WhereExprUsage(pMaskSet, pRight); + prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; - pNewExpr = tdsqlite3PExpr(pParse, TK_MATCH, - 0, tdsqlite3ExprDup(db, pRight, 0)); + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + 0, sqlite3ExprDup(db, pRight, 0)); if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){ ExprSetProperty(pNewExpr, EP_FromJoin); pNewExpr->iRightJoinTable = pExpr->iRightJoinTable; @@ -147181,8 +147181,8 @@ static void exprAnalyze( ** is not a sub-select. */ if( pWC->op==TK_AND && (pExpr->op==TK_EQ || pExpr->op==TK_IS) - && (nLeft = tdsqlite3ExprVectorSize(pExpr->pLeft))>1 - && tdsqlite3ExprVectorSize(pExpr->pRight)==nLeft + && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 + && sqlite3ExprVectorSize(pExpr->pRight)==nLeft && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 || (pExpr->pRight->flags & EP_xIsSelect)==0) ){ @@ -147190,10 +147190,10 @@ static void exprAnalyze( for(i=0; ipLeft, i); - Expr *pRight = tdsqlite3ExprForVectorField(pParse, pExpr->pRight, i); + Expr *pLeft = sqlite3ExprForVectorField(pParse, pExpr->pLeft, i); + Expr *pRight = sqlite3ExprForVectorField(pParse, pExpr->pRight, i); - pNew = tdsqlite3PExpr(pParse, pExpr->op, pLeft, pRight); + pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight); transferJoinMarkings(pNew, pExpr); idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC); exprAnalyze(pSrc, pWC, idxNew); @@ -147220,7 +147220,7 @@ static void exprAnalyze( #endif ){ int i; - for(i=0; ipLeft); i++){ + for(i=0; ipLeft); i++){ int idxNew; idxNew = whereClauseInsert(pWC, pExpr, TERM_VIRTUAL); pWC->a[idxNew].iField = i+1; @@ -147248,9 +147248,9 @@ static void exprAnalyze( int idxNew; WhereTerm *pNewTerm; - pNewExpr = tdsqlite3PExpr(pParse, TK_GT, - tdsqlite3ExprDup(db, pLeft, 0), - tdsqlite3ExprAlloc(db, TK_NULL, 0, 0)); + pNewExpr = sqlite3PExpr(pParse, TK_GT, + sqlite3ExprDup(db, pLeft, 0), + sqlite3ExprAlloc(db, TK_NULL, 0, 0)); idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); @@ -147298,22 +147298,22 @@ static void exprAnalyze( ** the WhereClause.a[] array. The slot[] array grows as needed to contain ** all terms of the WHERE clause. */ -SQLITE_PRIVATE void tdsqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ - Expr *pE2 = tdsqlite3ExprSkipCollateAndLikely(pExpr); +SQLITE_PRIVATE void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ + Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr); pWC->op = op; if( pE2==0 ) return; if( pE2->op!=op ){ whereClauseInsert(pWC, pExpr, 0); }else{ - tdsqlite3WhereSplit(pWC, pE2->pLeft, op); - tdsqlite3WhereSplit(pWC, pE2->pRight, op); + sqlite3WhereSplit(pWC, pE2->pLeft, op); + sqlite3WhereSplit(pWC, pE2->pRight, op); } } /* ** Initialize a preallocated WhereClause structure. */ -SQLITE_PRIVATE void tdsqlite3WhereClauseInit( +SQLITE_PRIVATE void sqlite3WhereClauseInit( WhereClause *pWC, /* The WhereClause to be initialized */ WhereInfo *pWInfo /* The WHERE processing context */ ){ @@ -147328,15 +147328,15 @@ SQLITE_PRIVATE void tdsqlite3WhereClauseInit( /* ** Deallocate a WhereClause structure. The WhereClause structure ** itself is not freed. This routine is the inverse of -** tdsqlite3WhereClauseInit(). +** sqlite3WhereClauseInit(). */ -SQLITE_PRIVATE void tdsqlite3WhereClauseClear(WhereClause *pWC){ +SQLITE_PRIVATE void sqlite3WhereClauseClear(WhereClause *pWC){ int i; WhereTerm *a; - tdsqlite3 *db = pWC->pWInfo->pParse->db; + sqlite3 *db = pWC->pWInfo->pParse->db; for(i=pWC->nTerm-1, a=pWC->a; i>=0; i--, a++){ if( a->wtFlags & TERM_DYNAMIC ){ - tdsqlite3ExprDelete(db, a->pExpr); + sqlite3ExprDelete(db, a->pExpr); } if( a->wtFlags & TERM_ORINFO ){ whereOrInfoDelete(db, a->u.pOrInfo); @@ -147345,7 +147345,7 @@ SQLITE_PRIVATE void tdsqlite3WhereClauseClear(WhereClause *pWC){ } } if( pWC->a!=pWC->aStatic ){ - tdsqlite3DbFree(db, pWC->a); + sqlite3DbFree(db, pWC->a); } } @@ -147355,43 +147355,43 @@ SQLITE_PRIVATE void tdsqlite3WhereClauseClear(WhereClause *pWC){ ** a bitmask indicating which tables are used in that expression ** tree. */ -SQLITE_PRIVATE Bitmask tdsqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){ Bitmask mask; if( p->op==TK_COLUMN && !ExprHasProperty(p, EP_FixedCol) ){ - return tdsqlite3WhereGetMask(pMaskSet, p->iTable); + return sqlite3WhereGetMask(pMaskSet, p->iTable); }else if( ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ assert( p->op!=TK_IF_NULL_ROW ); return 0; } - mask = (p->op==TK_IF_NULL_ROW) ? tdsqlite3WhereGetMask(pMaskSet, p->iTable) : 0; - if( p->pLeft ) mask |= tdsqlite3WhereExprUsageNN(pMaskSet, p->pLeft); + mask = (p->op==TK_IF_NULL_ROW) ? sqlite3WhereGetMask(pMaskSet, p->iTable) : 0; + if( p->pLeft ) mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pLeft); if( p->pRight ){ - mask |= tdsqlite3WhereExprUsageNN(pMaskSet, p->pRight); + mask |= sqlite3WhereExprUsageNN(pMaskSet, p->pRight); assert( p->x.pList==0 ); }else if( ExprHasProperty(p, EP_xIsSelect) ){ if( ExprHasProperty(p, EP_VarSelect) ) pMaskSet->bVarSelect = 1; mask |= exprSelectUsage(pMaskSet, p->x.pSelect); }else if( p->x.pList ){ - mask |= tdsqlite3WhereExprListUsage(pMaskSet, p->x.pList); + mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); } #ifndef SQLITE_OMIT_WINDOWFUNC if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && p->y.pWin ){ - mask |= tdsqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition); - mask |= tdsqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy); - mask |= tdsqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter); + mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition); + mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy); + mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter); } #endif return mask; } -SQLITE_PRIVATE Bitmask tdsqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ - return p ? tdsqlite3WhereExprUsageNN(pMaskSet,p) : 0; +SQLITE_PRIVATE Bitmask sqlite3WhereExprUsage(WhereMaskSet *pMaskSet, Expr *p){ + return p ? sqlite3WhereExprUsageNN(pMaskSet,p) : 0; } -SQLITE_PRIVATE Bitmask tdsqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){ +SQLITE_PRIVATE Bitmask sqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprList *pList){ int i; Bitmask mask = 0; if( pList ){ for(i=0; inExpr; i++){ - mask |= tdsqlite3WhereExprUsage(pMaskSet, pList->a[i].pExpr); + mask |= sqlite3WhereExprUsage(pMaskSet, pList->a[i].pExpr); } } return mask; @@ -147406,7 +147406,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereExprListUsage(WhereMaskSet *pMaskSet, ExprL ** virtual terms, so start analyzing at the end and work forward ** so that the added virtual terms are never processed. */ -SQLITE_PRIVATE void tdsqlite3WhereExprAnalyze( +SQLITE_PRIVATE void sqlite3WhereExprAnalyze( SrcList *pTabList, /* the FROM clause */ WhereClause *pWC /* the WHERE clause to be analyzed */ ){ @@ -147423,7 +147423,7 @@ SQLITE_PRIVATE void tdsqlite3WhereExprAnalyze( ** Each function argument translates into an equality constraint against ** a HIDDEN column in the table. */ -SQLITE_PRIVATE void tdsqlite3WhereTabFuncArgs( +SQLITE_PRIVATE void sqlite3WhereTabFuncArgs( Parse *pParse, /* Parsing context */ struct SrcList_item *pItem, /* The FROM clause term to process */ WhereClause *pWC /* Xfer function arguments to here */ @@ -147442,20 +147442,20 @@ SQLITE_PRIVATE void tdsqlite3WhereTabFuncArgs( Expr *pRhs; while( knCol && (pTab->aCol[k].colFlags & COLFLAG_HIDDEN)==0 ){k++;} if( k>=pTab->nCol ){ - tdsqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", + sqlite3ErrorMsg(pParse, "too many arguments on %s() - max %d", pTab->zName, j); return; } - pColRef = tdsqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); + pColRef = sqlite3ExprAlloc(pParse->db, TK_COLUMN, 0, 0); if( pColRef==0 ) return; pColRef->iTable = pItem->iCursor; pColRef->iColumn = k++; pColRef->y.pTab = pTab; - pRhs = tdsqlite3PExpr(pParse, TK_UPLUS, - tdsqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); - pTerm = tdsqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); + pRhs = sqlite3PExpr(pParse, TK_UPLUS, + sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); + pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); if( pItem->fg.jointype & JT_LEFT ){ - tdsqlite3SetJoinExpr(pTerm, pItem->iCursor); + sqlite3SetJoinExpr(pTerm, pItem->iCursor); } whereClauseInsert(pWC, pTerm, TERM_DYNAMIC); } @@ -147485,12 +147485,12 @@ SQLITE_PRIVATE void tdsqlite3WhereTabFuncArgs( /* #include "whereInt.h" */ /* -** Extra information appended to the end of tdsqlite3_index_info but not +** Extra information appended to the end of sqlite3_index_info but not ** visible to the xBestIndex function, at least not directly. The -** tdsqlite3_vtab_collation() interface knows how to reach it, however. +** sqlite3_vtab_collation() interface knows how to reach it, however. ** ** This object is not an API and can be changed from one release to the -** next. As long as allocateIndexInfo() and tdsqlite3_vtab_collation() +** next. As long as allocateIndexInfo() and sqlite3_vtab_collation() ** agree on the structure, all will be well. */ typedef struct HiddenIndexInfo HiddenIndexInfo; @@ -147500,18 +147500,18 @@ struct HiddenIndexInfo { }; /* Forward declaration of methods */ -static int whereLoopResize(tdsqlite3*, WhereLoop*, int); +static int whereLoopResize(sqlite3*, WhereLoop*, int); /* Test variable that can be set to enable WHERE tracing */ #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) -/***/ int tdsqlite3WhereTrace = 0; +/***/ int sqlite3WhereTrace = 0; #endif /* ** Return the estimated number of output rows from a WHERE clause */ -SQLITE_PRIVATE LogEst tdsqlite3WhereOutputRowCount(WhereInfo *pWInfo){ +SQLITE_PRIVATE LogEst sqlite3WhereOutputRowCount(WhereInfo *pWInfo){ return pWInfo->nRowOut; } @@ -147519,7 +147519,7 @@ SQLITE_PRIVATE LogEst tdsqlite3WhereOutputRowCount(WhereInfo *pWInfo){ ** Return one of the WHERE_DISTINCT_xxxxx values to indicate how this ** WHERE clause returns outputs for DISTINCT processing. */ -SQLITE_PRIVATE int tdsqlite3WhereIsDistinct(WhereInfo *pWInfo){ +SQLITE_PRIVATE int sqlite3WhereIsDistinct(WhereInfo *pWInfo){ return pWInfo->eDistinct; } @@ -147527,7 +147527,7 @@ SQLITE_PRIVATE int tdsqlite3WhereIsDistinct(WhereInfo *pWInfo){ ** Return TRUE if the WHERE clause returns rows in ORDER BY order. ** Return FALSE if the output needs to be sorted. */ -SQLITE_PRIVATE int tdsqlite3WhereIsOrdered(WhereInfo *pWInfo){ +SQLITE_PRIVATE int sqlite3WhereIsOrdered(WhereInfo *pWInfo){ return pWInfo->nOBSat; } @@ -147554,7 +147554,7 @@ SQLITE_PRIVATE int tdsqlite3WhereIsOrdered(WhereInfo *pWInfo){ ** that might make the code run a little faster, but should not change ** the final answer. */ -SQLITE_PRIVATE int tdsqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ +SQLITE_PRIVATE int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ WhereLevel *pInner; if( !pWInfo->bOrderedInnerLoop ){ /* The ORDER BY LIMIT optimization does not apply. Jump to the @@ -147570,7 +147570,7 @@ SQLITE_PRIVATE int tdsqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ ** Return the VDBE address or label to jump to in order to continue ** immediately with the next row of a WHERE clause. */ -SQLITE_PRIVATE int tdsqlite3WhereContinueLabel(WhereInfo *pWInfo){ +SQLITE_PRIVATE int sqlite3WhereContinueLabel(WhereInfo *pWInfo){ assert( pWInfo->iContinue!=0 ); return pWInfo->iContinue; } @@ -147579,7 +147579,7 @@ SQLITE_PRIVATE int tdsqlite3WhereContinueLabel(WhereInfo *pWInfo){ ** Return the VDBE address or label to jump to in order to break ** out of a WHERE loop. */ -SQLITE_PRIVATE int tdsqlite3WhereBreakLabel(WhereInfo *pWInfo){ +SQLITE_PRIVATE int sqlite3WhereBreakLabel(WhereInfo *pWInfo){ return pWInfo->iBreak; } @@ -147600,11 +147600,11 @@ SQLITE_PRIVATE int tdsqlite3WhereBreakLabel(WhereInfo *pWInfo){ ** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is ** unable to use the ONEPASS optimization. */ -SQLITE_PRIVATE int tdsqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){ +SQLITE_PRIVATE int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){ memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2); #ifdef WHERETRACE_ENABLED - if( tdsqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){ - tdsqlite3DebugPrintf("%s cursors: %d %d\n", + if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){ + sqlite3DebugPrintf("%s cursors: %d %d\n", pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI", aiCur[0], aiCur[1]); } @@ -147616,7 +147616,7 @@ SQLITE_PRIVATE int tdsqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){ ** Return TRUE if the WHERE loop uses the OP_DeferredSeek opcode to move ** the data cursor to the row selected by the index cursor. */ -SQLITE_PRIVATE int tdsqlite3WhereUsesDeferredSeek(WhereInfo *pWInfo){ +SQLITE_PRIVATE int sqlite3WhereUsesDeferredSeek(WhereInfo *pWInfo){ return pWInfo->bDeferredSeek; } @@ -147672,7 +147672,7 @@ whereOrInsert_done: ** Return the bitmask for the given cursor number. Return 0 if ** iCursor is not in the set. */ -SQLITE_PRIVATE Bitmask tdsqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){ +SQLITE_PRIVATE Bitmask sqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor){ int i; assert( pMaskSet->n<=(int)sizeof(Bitmask)*8 ); for(i=0; in; i++){ @@ -147688,7 +147688,7 @@ SQLITE_PRIVATE Bitmask tdsqlite3WhereGetMask(WhereMaskSet *pMaskSet, int iCursor ** ** There is one cursor per table in the FROM clause. The number of ** tables in the FROM clause is limited by a test early in the -** tdsqlite3WhereBegin() routine. So we know that the pMaskSet->ix[] +** sqlite3WhereBegin() routine. So we know that the pMaskSet->ix[] ** array will never overflow. */ static void createMask(WhereMaskSet *pMaskSet, int iCursor){ @@ -147720,13 +147720,13 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ if( pTerm->leftCursor==iCur && pTerm->u.leftColumn==iColumn && (iColumn!=XN_EXPR - || tdsqlite3ExprCompareSkip(pTerm->pExpr->pLeft, + || sqlite3ExprCompareSkip(pTerm->pExpr->pLeft, pScan->pIdxExpr,iCur)==0) && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin)) ){ if( (pTerm->eOperator & WO_EQUIV)!=0 && pScan->nEquivaiCur) - && (pX = tdsqlite3ExprSkipCollateAndLikely(pTerm->pExpr->pRight))->op + && (pX = sqlite3ExprSkipCollateAndLikely(pTerm->pExpr->pRight))->op ==TK_COLUMN ){ int j; @@ -147748,13 +147748,13 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ CollSeq *pColl; Parse *pParse = pWC->pWInfo->pParse; pX = pTerm->pExpr; - if( !tdsqlite3IndexAffinityOk(pX, pScan->idxaff) ){ + if( !sqlite3IndexAffinityOk(pX, pScan->idxaff) ){ continue; } assert(pX->pLeft); - pColl = tdsqlite3ExprCompareCollSeq(pParse, pX); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); if( pColl==0 ) pColl = pParse->db->pDfltColl; - if( tdsqlite3StrICmp(pColl->zName, pScan->zCollName) ){ + if( sqlite3StrICmp(pColl->zName, pScan->zCollName) ){ continue; } } @@ -147790,7 +147790,7 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ ** need to push registers onto the stack as part of its prologue. */ static SQLITE_NOINLINE WhereTerm *whereScanInitIndexExpr(WhereScan *pScan){ - pScan->idxaff = tdsqlite3ExprAffinity(pScan->pIdxExpr); + pScan->idxaff = sqlite3ExprAffinity(pScan->pIdxExpr); return whereScanNext(pScan); } @@ -147877,7 +147877,7 @@ static WhereTerm *whereScanInit( ** the form "X " exist. If no terms with a constant RHS ** exist, try to return a term that does not use WO_EQUIV. */ -SQLITE_PRIVATE WhereTerm *tdsqlite3WhereFindTerm( +SQLITE_PRIVATE WhereTerm *sqlite3WhereFindTerm( WhereClause *pWC, /* The WHERE clause to be searched */ int iCur, /* Cursor number of LHS */ int iColumn, /* Column number of LHS */ @@ -147922,13 +147922,13 @@ static int findIndexCol( const char *zColl = pIdx->azColl[iCol]; for(i=0; inExpr; i++){ - Expr *p = tdsqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr); + Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr); if( p->op==TK_COLUMN && p->iColumn==pIdx->aiColumn[iCol] && p->iTable==iBase ){ - CollSeq *pColl = tdsqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr); - if( 0==tdsqlite3StrICmp(pColl->zName, zColl) ){ + CollSeq *pColl = sqlite3ExprNNCollSeq(pParse, pList->a[i].pExpr); + if( 0==sqlite3StrICmp(pColl->zName, zColl) ){ return i; } } @@ -147986,7 +147986,7 @@ static int isDistinctRedundant( ** current SELECT is a correlated sub-query. */ for(i=0; inExpr; i++){ - Expr *p = tdsqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); + Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; } @@ -148006,7 +148006,7 @@ static int isDistinctRedundant( for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ if( !IsUniqueIndex(pIdx) ) continue; for(i=0; inKeyCol; i++){ - if( 0==tdsqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){ + if( 0==sqlite3WhereFindTerm(pWC, iBase, i, ~(Bitmask)0, WO_EQ, pIdx) ){ if( findIndexCol(pParse, pDistinct, iBase, pIdx, i)<0 ) break; if( indexColumnNotNull(pIdx, i)==0 ) break; } @@ -148025,7 +148025,7 @@ static int isDistinctRedundant( ** Estimate the logarithm of the input value to base 2. */ static LogEst estLog(LogEst N){ - return N<=10 ? 0 : tdsqlite3LogEst(N) - 33; + return N<=10 ? 0 : sqlite3LogEst(N) - 33; } /* @@ -148048,8 +148048,8 @@ static void translateColumnToCopy( int iAutoidxCur /* If non-zero, cursor of autoindex being generated */ ){ Vdbe *v = pParse->pVdbe; - VdbeOp *pOp = tdsqlite3VdbeGetOp(v, iStart); - int iEnd = tdsqlite3VdbeCurrentAddr(v); + VdbeOp *pOp = sqlite3VdbeGetOp(v, iStart); + int iEnd = sqlite3VdbeCurrentAddr(v); if( pParse->db->mallocFailed ) return; for(; iStartp1!=iTabCur ) continue; @@ -148072,17 +148072,17 @@ static void translateColumnToCopy( } /* -** Two routines for printing the content of an tdsqlite3_index_info +** Two routines for printing the content of an sqlite3_index_info ** structure. Used for testing and debugging only. If neither ** SQLITE_TEST or SQLITE_DEBUG are defined, then these routines ** are no-ops. */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(WHERETRACE_ENABLED) -static void whereTraceIndexInfoInputs(tdsqlite3_index_info *p){ +static void whereTraceIndexInfoInputs(sqlite3_index_info *p){ int i; - if( !tdsqlite3WhereTrace ) return; + if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ - tdsqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", + sqlite3DebugPrintf(" constraint[%d]: col=%d termid=%d op=%d usabled=%d\n", i, p->aConstraint[i].iColumn, p->aConstraint[i].iTermOffset, @@ -148090,26 +148090,26 @@ static void whereTraceIndexInfoInputs(tdsqlite3_index_info *p){ p->aConstraint[i].usable); } for(i=0; inOrderBy; i++){ - tdsqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", + sqlite3DebugPrintf(" orderby[%d]: col=%d desc=%d\n", i, p->aOrderBy[i].iColumn, p->aOrderBy[i].desc); } } -static void whereTraceIndexInfoOutputs(tdsqlite3_index_info *p){ +static void whereTraceIndexInfoOutputs(sqlite3_index_info *p){ int i; - if( !tdsqlite3WhereTrace ) return; + if( !sqlite3WhereTrace ) return; for(i=0; inConstraint; i++){ - tdsqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", + sqlite3DebugPrintf(" usage[%d]: argvIdx=%d omit=%d\n", i, p->aConstraintUsage[i].argvIndex, p->aConstraintUsage[i].omit); } - tdsqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); - tdsqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); - tdsqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); - tdsqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); - tdsqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); + sqlite3DebugPrintf(" idxNum=%d\n", p->idxNum); + sqlite3DebugPrintf(" idxStr=%s\n", p->idxStr); + sqlite3DebugPrintf(" orderByConsumed=%d\n", p->orderByConsumed); + sqlite3DebugPrintf(" estimatedCost=%g\n", p->estimatedCost); + sqlite3DebugPrintf(" estimatedRows=%lld\n", p->estimatedRows); } #else #define whereTraceIndexInfoInputs(A) @@ -148142,7 +148142,7 @@ static int termCanDriveIndex( if( (pTerm->prereqRight & notReady)!=0 ) return 0; if( pTerm->u.leftColumn<0 ) return 0; aff = pSrc->pTab->aCol[pTerm->u.leftColumn].affinity; - if( !tdsqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; + if( !sqlite3IndexAffinityOk(pTerm->pExpr, aff) ) return 0; testcase( pTerm->pExpr->op==TK_IS ); return 1; } @@ -148190,7 +148190,7 @@ static void constructAutomaticIndex( ** transient index on 2nd and subsequent iterations of the loop. */ v = pParse->pVdbe; assert( v!=0 ); - addrInit = tdsqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); + addrInit = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); /* Count the number of columns that will be added to the index ** and used to match WHERE clause constraints */ @@ -148207,9 +148207,9 @@ static void constructAutomaticIndex( if( pLoop->prereq==0 && (pTerm->wtFlags & TERM_VIRTUAL)==0 && !ExprHasProperty(pExpr, EP_FromJoin) - && tdsqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ - pPartial = tdsqlite3ExprAnd(pParse, pPartial, - tdsqlite3ExprDup(pParse->db, pExpr, 0)); + && sqlite3ExprIsTableConstant(pExpr, pSrc->iCursor) ){ + pPartial = sqlite3ExprAnd(pParse, pPartial, + sqlite3ExprDup(pParse->db, pExpr, 0)); } if( termCanDriveIndex(pTerm, pSrc, notReady) ){ int iCol = pTerm->u.leftColumn; @@ -148217,7 +148217,7 @@ static void constructAutomaticIndex( testcase( iCol==BMS ); testcase( iCol==BMS-1 ); if( !sentWarning ){ - tdsqlite3_log(SQLITE_WARNING_AUTOINDEX, + sqlite3_log(SQLITE_WARNING_AUTOINDEX, "automatic index on %s(%s)", pTable->zName, pTable->aCol[iCol].zName); sentWarning = 1; @@ -148256,7 +148256,7 @@ static void constructAutomaticIndex( } /* Construct the Index object to describe this index */ - pIdx = tdsqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed); + pIdx = sqlite3AllocateIndexObject(pParse->db, nKeyCol+1, 0, &zNotUsed); if( pIdx==0 ) goto end_auto_index_create; pLoop->u.btree.pIndex = pIdx; pIdx->zName = "auto-index"; @@ -148273,9 +148273,9 @@ static void constructAutomaticIndex( Expr *pX = pTerm->pExpr; idxCols |= cMask; pIdx->aiColumn[n] = pTerm->u.leftColumn; - pColl = tdsqlite3ExprCompareCollSeq(pParse, pX); + pColl = sqlite3ExprCompareCollSeq(pParse, pX); assert( pColl!=0 || pParse->nErr>0 ); /* TH3 collate01.800 */ - pIdx->azColl[n] = pColl ? pColl->zName : tdsqlite3StrBINARY; + pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; n++; } } @@ -148287,82 +148287,82 @@ static void constructAutomaticIndex( for(i=0; iaiColumn[n] = i; - pIdx->azColl[n] = tdsqlite3StrBINARY; + pIdx->azColl[n] = sqlite3StrBINARY; n++; } } if( pSrc->colUsed & MASKBIT(BMS-1) ){ for(i=BMS-1; inCol; i++){ pIdx->aiColumn[n] = i; - pIdx->azColl[n] = tdsqlite3StrBINARY; + pIdx->azColl[n] = sqlite3StrBINARY; n++; } } assert( n==nKeyCol ); pIdx->aiColumn[n] = XN_ROWID; - pIdx->azColl[n] = tdsqlite3StrBINARY; + pIdx->azColl[n] = sqlite3StrBINARY; /* Create the automatic index */ assert( pLevel->iIdxCur>=0 ); pLevel->iIdxCur = pParse->nTab++; - tdsqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); - tdsqlite3VdbeSetP4KeyInfo(pParse, pIdx); + sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1); + sqlite3VdbeSetP4KeyInfo(pParse, pIdx); VdbeComment((v, "for %s", pTable->zName)); /* Fill the automatic index with content */ pTabItem = &pWC->pWInfo->pTabList->a[pLevel->iFrom]; if( pTabItem->fg.viaCoroutine ){ int regYield = pTabItem->regReturn; - addrCounter = tdsqlite3VdbeAddOp2(v, OP_Integer, 0, 0); - tdsqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); - addrTop = tdsqlite3VdbeAddOp1(v, OP_Yield, regYield); + addrCounter = sqlite3VdbeAddOp2(v, OP_Integer, 0, 0); + sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, pTabItem->addrFillSub); + addrTop = sqlite3VdbeAddOp1(v, OP_Yield, regYield); VdbeCoverage(v); VdbeComment((v, "next row of %s", pTabItem->pTab->zName)); }else{ - addrTop = tdsqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); + addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v); } if( pPartial ){ - iContinue = tdsqlite3VdbeMakeLabel(pParse); - tdsqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); + iContinue = sqlite3VdbeMakeLabel(pParse); + sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL); pLoop->wsFlags |= WHERE_PARTIALIDX; } - regRecord = tdsqlite3GetTempReg(pParse); - regBase = tdsqlite3GenerateIndexKey( + regRecord = sqlite3GetTempReg(pParse); + regBase = sqlite3GenerateIndexKey( pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0 ); - tdsqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); - tdsqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); - if( pPartial ) tdsqlite3VdbeResolveLabel(v, iContinue); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord); + sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); + if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue); if( pTabItem->fg.viaCoroutine ){ - tdsqlite3VdbeChangeP2(v, addrCounter, regBase+n); + sqlite3VdbeChangeP2(v, addrCounter, regBase+n); testcase( pParse->db->mallocFailed ); assert( pLevel->iIdxCur>0 ); translateColumnToCopy(pParse, addrTop, pLevel->iTabCur, pTabItem->regResult, pLevel->iIdxCur); - tdsqlite3VdbeGoto(v, addrTop); + sqlite3VdbeGoto(v, addrTop); pTabItem->fg.viaCoroutine = 0; }else{ - tdsqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); - tdsqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); + sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX); } - tdsqlite3VdbeJumpHere(v, addrTop); - tdsqlite3ReleaseTempReg(pParse, regRecord); + sqlite3VdbeJumpHere(v, addrTop); + sqlite3ReleaseTempReg(pParse, regRecord); /* Jump here when skipping the initialization */ - tdsqlite3VdbeJumpHere(v, addrInit); + sqlite3VdbeJumpHere(v, addrInit); end_auto_index_create: - tdsqlite3ExprDelete(pParse->db, pPartial); + sqlite3ExprDelete(pParse->db, pPartial); } #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ #ifndef SQLITE_OMIT_VIRTUALTABLE /* -** Allocate and populate an tdsqlite3_index_info structure. It is the +** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure -** by passing the pointer returned by this function to tdsqlite3_free(). +** by passing the pointer returned by this function to sqlite3_free(). */ -static tdsqlite3_index_info *allocateIndexInfo( +static sqlite3_index_info *allocateIndexInfo( Parse *pParse, /* The parsing context */ WhereClause *pWC, /* The WHERE clause being analyzed */ Bitmask mUnusable, /* Ignore terms with these prereqs */ @@ -148372,13 +148372,13 @@ static tdsqlite3_index_info *allocateIndexInfo( ){ int i, j; int nTerm; - struct tdsqlite3_index_constraint *pIdxCons; - struct tdsqlite3_index_orderby *pIdxOrderBy; - struct tdsqlite3_index_constraint_usage *pUsage; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_orderby *pIdxOrderBy; + struct sqlite3_index_constraint_usage *pUsage; struct HiddenIndexInfo *pHidden; WhereTerm *pTerm; int nOrderBy; - tdsqlite3_index_info *pIdxInfo; + sqlite3_index_info *pIdxInfo; u16 mNoOmit = 0; /* Count the number of possible WHERE clause constraints referring @@ -148399,7 +148399,7 @@ static tdsqlite3_index_info *allocateIndexInfo( /* If the ORDER BY clause contains only columns in the current ** virtual table then allocate space for the aOrderBy part of - ** the tdsqlite3_index_info structure. + ** the sqlite3_index_info structure. */ nOrderBy = 0; if( pOrderBy ){ @@ -148414,19 +148414,19 @@ static tdsqlite3_index_info *allocateIndexInfo( } } - /* Allocate the tdsqlite3_index_info structure + /* Allocate the sqlite3_index_info structure */ - pIdxInfo = tdsqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + pIdxInfo = sqlite3DbMallocZero(pParse->db, sizeof(*pIdxInfo) + (sizeof(*pIdxCons) + sizeof(*pUsage))*nTerm + sizeof(*pIdxOrderBy)*nOrderBy + sizeof(*pHidden) ); if( pIdxInfo==0 ){ - tdsqlite3ErrorMsg(pParse, "out of memory"); + sqlite3ErrorMsg(pParse, "out of memory"); return 0; } pHidden = (struct HiddenIndexInfo*)&pIdxInfo[1]; - pIdxCons = (struct tdsqlite3_index_constraint*)&pHidden[1]; - pIdxOrderBy = (struct tdsqlite3_index_orderby*)&pIdxCons[nTerm]; - pUsage = (struct tdsqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; + pIdxCons = (struct sqlite3_index_constraint*)&pHidden[1]; + pIdxOrderBy = (struct sqlite3_index_orderby*)&pIdxCons[nTerm]; + pUsage = (struct sqlite3_index_constraint_usage*)&pIdxOrderBy[nOrderBy]; pIdxInfo->nOrderBy = nOrderBy; pIdxInfo->aConstraint = pIdxCons; pIdxInfo->aOrderBy = pIdxOrderBy; @@ -148479,7 +148479,7 @@ static tdsqlite3_index_info *allocateIndexInfo( assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); if( op & (WO_LT|WO_LE|WO_GT|WO_GE) - && tdsqlite3ExprIsVector(pTerm->pExpr->pRight) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) ){ testcase( j!=i ); if( j<16 ) mNoOmit |= (1 << j); @@ -148504,21 +148504,21 @@ static tdsqlite3_index_info *allocateIndexInfo( /* ** The table object reference passed as the second argument to this function ** must represent a virtual table. This function invokes the xBestIndex() -** method of the virtual table with the tdsqlite3_index_info object that +** method of the virtual table with the sqlite3_index_info object that ** comes in as the 3rd argument to this function. ** ** If an error occurs, pParse is populated with an error message and an ** appropriate error code is returned. A return of SQLITE_CONSTRAINT from ** xBestIndex is not considered an error. SQLITE_CONSTRAINT indicates that -** the current configuration of "unusable" flags in tdsqlite3_index_info can +** the current configuration of "unusable" flags in sqlite3_index_info can ** not result in a valid plan. ** ** Whether or not an error is returned, it is the responsibility of the ** caller to eventually free p->idxStr if p->needToFreeIdxStr indicates ** that this is required. */ -static int vtabBestIndex(Parse *pParse, Table *pTab, tdsqlite3_index_info *p){ - tdsqlite3_vtab *pVtab = tdsqlite3GetVTable(pParse->db, pTab)->pVtab; +static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ + sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; int rc; whereTraceIndexInfoInputs(p); @@ -148527,14 +148527,14 @@ static int vtabBestIndex(Parse *pParse, Table *pTab, tdsqlite3_index_info *p){ if( rc!=SQLITE_OK && rc!=SQLITE_CONSTRAINT ){ if( rc==SQLITE_NOMEM ){ - tdsqlite3OomFault(pParse->db); + sqlite3OomFault(pParse->db); }else if( !pVtab->zErrMsg ){ - tdsqlite3ErrorMsg(pParse, "%s", tdsqlite3ErrStr(rc)); + sqlite3ErrorMsg(pParse, "%s", sqlite3ErrStr(rc)); }else{ - tdsqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); + sqlite3ErrorMsg(pParse, "%s", pVtab->zErrMsg); } } - tdsqlite3_free(pVtab->zErrMsg); + sqlite3_free(pVtab->zErrMsg); pVtab->zErrMsg = 0; return rc; } @@ -148643,7 +148643,7 @@ static int whereKeyStats( } pRec->nField = n; - res = tdsqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec); + res = sqlite3VdbeRecordCompare(aSample[iSamp].n, aSample[iSamp].p, pRec); if( res<0 ){ iLower = aSample[iSamp].anLt[n-1] + aSample[iSamp].anEq[n-1]; iMin = iTest+1; @@ -148668,7 +148668,7 @@ static int whereKeyStats( assert( inSample ); assert( iCol==nField-1 ); pRec->nField = nField; - assert( 0==tdsqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) || pParse->db->mallocFailed ); }else{ @@ -148678,7 +148678,7 @@ static int whereKeyStats( assert( i<=pIdx->nSample && i>=0 ); pRec->nField = iCol+1; assert( i==pIdx->nSample - || tdsqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 || pParse->db->mallocFailed ); /* if i==0 and iCol==0, then record pRec is smaller than all samples @@ -148687,12 +148687,12 @@ static int whereKeyStats( ** If (i>0), then pRec must also be greater than sample (i-1). */ if( iCol>0 ){ pRec->nField = iCol; - assert( tdsqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 + assert( sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)<=0 || pParse->db->mallocFailed ); } if( i>0 ){ pRec->nField = nField; - assert( tdsqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 + assert( sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 || pParse->db->mallocFailed ); } } @@ -148710,7 +148710,7 @@ static int whereKeyStats( ** is larger than all samples in the array. */ tRowcnt iUpper, iGap; if( i>=pIdx->nSample ){ - iUpper = tdsqlite3LogEstToInt(pIdx->aiRowLogEst[0]); + iUpper = sqlite3LogEstToInt(pIdx->aiRowLogEst[0]); }else{ iUpper = aSample[i].anLt[iCol]; } @@ -148752,7 +148752,7 @@ static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ if( pTerm->truthProb<=0 ){ nRet += pTerm->truthProb; }else if( (pTerm->wtFlags & TERM_VNULL)==0 ){ - nRet -= 20; assert( 20==tdsqlite3LogEst(4) ); + nRet -= 20; assert( 20==sqlite3LogEst(4) ); } } return nRet; @@ -148763,10 +148763,10 @@ static LogEst whereRangeAdjust(WhereTerm *pTerm, LogEst nNew){ /* ** Return the affinity for a single column of an index. */ -SQLITE_PRIVATE char tdsqlite3IndexColumnAffinity(tdsqlite3 *db, Index *pIdx, int iCol){ +SQLITE_PRIVATE char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){ assert( iCol>=0 && iColnColumn ); if( !pIdx->zColAff ){ - if( tdsqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB; + if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB; } assert( pIdx->zColAff[iCol]!=0 ); return pIdx->zColAff[iCol]; @@ -148819,24 +148819,24 @@ static int whereRangeSkipScanEst( ){ Index *p = pLoop->u.btree.pIndex; int nEq = pLoop->u.btree.nEq; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; int nLower = -1; int nUpper = p->nSample+1; int rc = SQLITE_OK; - u8 aff = tdsqlite3IndexColumnAffinity(db, p, nEq); + u8 aff = sqlite3IndexColumnAffinity(db, p, nEq); CollSeq *pColl; - tdsqlite3_value *p1 = 0; /* Value extracted from pLower */ - tdsqlite3_value *p2 = 0; /* Value extracted from pUpper */ - tdsqlite3_value *pVal = 0; /* Value extracted from record */ + sqlite3_value *p1 = 0; /* Value extracted from pLower */ + sqlite3_value *p2 = 0; /* Value extracted from pUpper */ + sqlite3_value *pVal = 0; /* Value extracted from record */ - pColl = tdsqlite3LocateCollSeq(pParse, p->azColl[nEq]); + pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]); if( pLower ){ - rc = tdsqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1); + rc = sqlite3Stat4ValueFromExpr(pParse, pLower->pExpr->pRight, aff, &p1); nLower = 0; } if( pUpper && rc==SQLITE_OK ){ - rc = tdsqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2); + rc = sqlite3Stat4ValueFromExpr(pParse, pUpper->pExpr->pRight, aff, &p2); nUpper = p2 ? 0 : p->nSample; } @@ -148844,13 +148844,13 @@ static int whereRangeSkipScanEst( int i; int nDiff; for(i=0; rc==SQLITE_OK && inSample; i++){ - rc = tdsqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal); + rc = sqlite3Stat4Column(db, p->aSample[i].p, p->aSample[i].n, nEq, &pVal); if( rc==SQLITE_OK && p1 ){ - int res = tdsqlite3MemCompare(p1, pVal, pColl); + int res = sqlite3MemCompare(p1, pVal, pColl); if( res>=0 ) nLower++; } if( rc==SQLITE_OK && p2 ){ - int res = tdsqlite3MemCompare(p2, pVal, pColl); + int res = sqlite3MemCompare(p2, pVal, pColl); if( res>=0 ) nUpper++; } } @@ -148863,7 +148863,7 @@ static int whereRangeSkipScanEst( ** the number of rows visited. Otherwise, estimate the number of rows ** using the method described in the header comment for this function. */ if( nDiff!=1 || pUpper==0 || pLower==0 ){ - int nAdjust = (tdsqlite3LogEst(p->nSample) - tdsqlite3LogEst(nDiff)); + int nAdjust = (sqlite3LogEst(p->nSample) - sqlite3LogEst(nDiff)); pLoop->nOut -= nAdjust; *pbDone = 1; WHERETRACE(0x10, ("range skip-scan regions: %u..%u adjust=%d est=%d\n", @@ -148874,9 +148874,9 @@ static int whereRangeSkipScanEst( assert( *pbDone==0 ); } - tdsqlite3ValueFree(p1); - tdsqlite3ValueFree(p2); - tdsqlite3ValueFree(pVal); + sqlite3ValueFree(p1); + sqlite3ValueFree(p2); + sqlite3ValueFree(pVal); return rc; } @@ -148911,7 +148911,7 @@ static int whereRangeSkipScanEst( ** ** then nEq is set to 0. ** -** When this function is called, *pnOut is set to the tdsqlite3LogEst() of the +** When this function is called, *pnOut is set to the sqlite3LogEst() of the ** number of rows that the index scan is expected to visit without ** considering the range constraints. If nEq is 0, then *pnOut is the number of ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) @@ -148999,11 +148999,11 @@ static int whereRangeScanEst( if( pLower ){ int n; /* Values extracted from pExpr */ Expr *pExpr = pLower->pExpr->pRight; - rc = tdsqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n); + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nBtm, nEq, &n); if( rc==SQLITE_OK && n ){ tRowcnt iNew; u16 mask = WO_GT|WO_LE; - if( tdsqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); + if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); iLwrIdx = whereKeyStats(pParse, p, pRec, 0, a); iNew = a[0] + ((pLower->eOperator & mask) ? a[1] : 0); if( iNew>iLower ) iLower = iNew; @@ -149016,11 +149016,11 @@ static int whereRangeScanEst( if( pUpper ){ int n; /* Values extracted from pExpr */ Expr *pExpr = pUpper->pExpr->pRight; - rc = tdsqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n); + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, nTop, nEq, &n); if( rc==SQLITE_OK && n ){ tRowcnt iNew; u16 mask = WO_GT|WO_LE; - if( tdsqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); + if( sqlite3ExprVectorSize(pExpr)>n ) mask = (WO_LE|WO_LT); iUprIdx = whereKeyStats(pParse, p, pRec, 1, a); iNew = a[0] + ((pUpper->eOperator & mask) ? a[1] : 0); if( iNewpRec = pRec; if( rc==SQLITE_OK ){ if( iUpper>iLower ){ - nNew = tdsqlite3LogEst(iUpper - iLower); + nNew = sqlite3LogEst(iUpper - iLower); /* TUNING: If both iUpper and iLower are derived from the same ** sample, then assume they are 4x more selective. This brings ** the estimated selectivity more in line with what it would be ** if estimated without the use of STAT4 tables. */ - if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==tdsqlite3LogEst(4) ); + if( iLwrIdx==iUprIdx ) nNew -= 20; assert( 20==sqlite3LogEst(4) ); }else{ - nNew = 10; assert( 10==tdsqlite3LogEst(2) ); + nNew = 10; assert( 10==sqlite3LogEst(2) ); } if( nNew=p->nColumn ){ *pnRow = 1; return SQLITE_OK; } - rc = tdsqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk); + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, 1, nEq-1, &bOk); pBuilder->pRec = pRec; if( rc!=SQLITE_OK ) return rc; if( bOk==0 ) return SQLITE_NOTFOUND; @@ -149174,7 +149174,7 @@ static int whereInScanEst( tRowcnt *pnRow /* Write the revised row estimate here */ ){ Index *p = pBuilder->pNew->u.btree.pIndex; - i64 nRow0 = tdsqlite3LogEstToInt(p->aiRowLogEst[0]); + i64 nRow0 = sqlite3LogEstToInt(p->aiRowLogEst[0]); int nRecValid = pBuilder->nRecValid; int rc = SQLITE_OK; /* Subfunction return code */ tRowcnt nEst; /* Number of rows for a single term */ @@ -149204,9 +149204,9 @@ static int whereInScanEst( /* ** Print the content of a WhereTerm object */ -SQLITE_PRIVATE void tdsqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ +SQLITE_PRIVATE void sqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ if( pTerm==0 ){ - tdsqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm); + sqlite3DebugPrintf("TERM-%-3d NULL\n", iTerm); }else{ char zType[8]; char zLeft[50]; @@ -149216,31 +149216,31 @@ SQLITE_PRIVATE void tdsqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ if( ExprHasProperty(pTerm->pExpr, EP_FromJoin) ) zType[2] = 'L'; if( pTerm->wtFlags & TERM_CODED ) zType[3] = 'C'; if( pTerm->eOperator & WO_SINGLE ){ - tdsqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", + sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", pTerm->leftCursor, pTerm->u.leftColumn); }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ - tdsqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", + sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%lld", pTerm->u.pOrInfo->indexable); }else{ - tdsqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); + sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); } - tdsqlite3DebugPrintf( + sqlite3DebugPrintf( "TERM-%-3d %p %s %-12s op=%03x wtFlags=%04x", iTerm, pTerm, zType, zLeft, pTerm->eOperator, pTerm->wtFlags); /* The 0x10000 .wheretrace flag causes extra information to be ** shown about each Term */ - if( tdsqlite3WhereTrace & 0x10000 ){ - tdsqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx", + if( sqlite3WhereTrace & 0x10000 ){ + sqlite3DebugPrintf(" prob=%-3d prereq=%llx,%llx", pTerm->truthProb, (u64)pTerm->prereqAll, (u64)pTerm->prereqRight); } if( pTerm->iField ){ - tdsqlite3DebugPrintf(" iField=%d", pTerm->iField); + sqlite3DebugPrintf(" iField=%d", pTerm->iField); } if( pTerm->iParent>=0 ){ - tdsqlite3DebugPrintf(" iParent=%d", pTerm->iParent); + sqlite3DebugPrintf(" iParent=%d", pTerm->iParent); } - tdsqlite3DebugPrintf("\n"); - tdsqlite3TreeViewExpr(0, pTerm->pExpr, 0); + sqlite3DebugPrintf("\n"); + sqlite3TreeViewExpr(0, pTerm->pExpr, 0); } } #endif @@ -149249,10 +149249,10 @@ SQLITE_PRIVATE void tdsqlite3WhereTermPrint(WhereTerm *pTerm, int iTerm){ /* ** Show the complete content of a WhereClause */ -SQLITE_PRIVATE void tdsqlite3WhereClausePrint(WhereClause *pWC){ +SQLITE_PRIVATE void sqlite3WhereClausePrint(WhereClause *pWC){ int i; for(i=0; inTerm; i++){ - tdsqlite3WhereTermPrint(&pWC->a[i], i); + sqlite3WhereTermPrint(&pWC->a[i], i); } } #endif @@ -149261,49 +149261,49 @@ SQLITE_PRIVATE void tdsqlite3WhereClausePrint(WhereClause *pWC){ /* ** Print a WhereLoop object for debugging purposes */ -SQLITE_PRIVATE void tdsqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ +SQLITE_PRIVATE void sqlite3WhereLoopPrint(WhereLoop *p, WhereClause *pWC){ WhereInfo *pWInfo = pWC->pWInfo; int nb = 1+(pWInfo->pTabList->nSrc+3)/4; struct SrcList_item *pItem = pWInfo->pTabList->a + p->iTab; Table *pTab = pItem->pTab; Bitmask mAll = (((Bitmask)1)<<(nb*4)) - 1; - tdsqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, + sqlite3DebugPrintf("%c%2d.%0*llx.%0*llx", p->cId, p->iTab, nb, p->maskSelf, nb, p->prereq & mAll); - tdsqlite3DebugPrintf(" %12s", + sqlite3DebugPrintf(" %12s", pItem->zAlias ? pItem->zAlias : pTab->zName); if( (p->wsFlags & WHERE_VIRTUALTABLE)==0 ){ const char *zName; if( p->u.btree.pIndex && (zName = p->u.btree.pIndex->zName)!=0 ){ if( strncmp(zName, "sqlite_autoindex_", 17)==0 ){ - int i = tdsqlite3Strlen30(zName) - 1; + int i = sqlite3Strlen30(zName) - 1; while( zName[i]!='_' ) i--; zName += i; } - tdsqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); + sqlite3DebugPrintf(".%-16s %2d", zName, p->u.btree.nEq); }else{ - tdsqlite3DebugPrintf("%20s",""); + sqlite3DebugPrintf("%20s",""); } }else{ char *z; if( p->u.vtab.idxStr ){ - z = tdsqlite3_mprintf("(%d,\"%s\",%#x)", + z = sqlite3_mprintf("(%d,\"%s\",%#x)", p->u.vtab.idxNum, p->u.vtab.idxStr, p->u.vtab.omitMask); }else{ - z = tdsqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); + z = sqlite3_mprintf("(%d,%x)", p->u.vtab.idxNum, p->u.vtab.omitMask); } - tdsqlite3DebugPrintf(" %-19s", z); - tdsqlite3_free(z); + sqlite3DebugPrintf(" %-19s", z); + sqlite3_free(z); } if( p->wsFlags & WHERE_SKIPSCAN ){ - tdsqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); + sqlite3DebugPrintf(" f %05x %d-%d", p->wsFlags, p->nLTerm,p->nSkip); }else{ - tdsqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); + sqlite3DebugPrintf(" f %05x N %d", p->wsFlags, p->nLTerm); } - tdsqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); - if( p->nLTerm && (tdsqlite3WhereTrace & 0x100)!=0 ){ + sqlite3DebugPrintf(" cost %d,%d,%d\n", p->rSetup, p->rRun, p->nOut); + if( p->nLTerm && (sqlite3WhereTrace & 0x100)!=0 ){ int i; for(i=0; inLTerm; i++){ - tdsqlite3WhereTermPrint(p->aLTerm[i], i); + sqlite3WhereTermPrint(p->aLTerm[i], i); } } } @@ -149323,15 +149323,15 @@ static void whereLoopInit(WhereLoop *p){ /* ** Clear the WhereLoop.u union. Leave WhereLoop.pLTerm intact. */ -static void whereLoopClearUnion(tdsqlite3 *db, WhereLoop *p){ +static void whereLoopClearUnion(sqlite3 *db, WhereLoop *p){ if( p->wsFlags & (WHERE_VIRTUALTABLE|WHERE_AUTO_INDEX) ){ if( (p->wsFlags & WHERE_VIRTUALTABLE)!=0 && p->u.vtab.needFree ){ - tdsqlite3_free(p->u.vtab.idxStr); + sqlite3_free(p->u.vtab.idxStr); p->u.vtab.needFree = 0; p->u.vtab.idxStr = 0; }else if( (p->wsFlags & WHERE_AUTO_INDEX)!=0 && p->u.btree.pIndex!=0 ){ - tdsqlite3DbFree(db, p->u.btree.pIndex->zColAff); - tdsqlite3DbFreeNN(db, p->u.btree.pIndex); + sqlite3DbFree(db, p->u.btree.pIndex->zColAff); + sqlite3DbFreeNN(db, p->u.btree.pIndex); p->u.btree.pIndex = 0; } } @@ -149340,8 +149340,8 @@ static void whereLoopClearUnion(tdsqlite3 *db, WhereLoop *p){ /* ** Deallocate internal memory used by a WhereLoop object */ -static void whereLoopClear(tdsqlite3 *db, WhereLoop *p){ - if( p->aLTerm!=p->aLTermSpace ) tdsqlite3DbFreeNN(db, p->aLTerm); +static void whereLoopClear(sqlite3 *db, WhereLoop *p){ + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); whereLoopClearUnion(db, p); whereLoopInit(p); } @@ -149349,14 +149349,14 @@ static void whereLoopClear(tdsqlite3 *db, WhereLoop *p){ /* ** Increase the memory allocation for pLoop->aLTerm[] to be at least n. */ -static int whereLoopResize(tdsqlite3 *db, WhereLoop *p, int n){ +static int whereLoopResize(sqlite3 *db, WhereLoop *p, int n){ WhereTerm **paNew; if( p->nLSlot>=n ) return SQLITE_OK; n = (n+7)&~7; - paNew = tdsqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); + paNew = sqlite3DbMallocRawNN(db, sizeof(p->aLTerm[0])*n); if( paNew==0 ) return SQLITE_NOMEM_BKPT; memcpy(paNew, p->aLTerm, sizeof(p->aLTerm[0])*p->nLSlot); - if( p->aLTerm!=p->aLTermSpace ) tdsqlite3DbFreeNN(db, p->aLTerm); + if( p->aLTerm!=p->aLTermSpace ) sqlite3DbFreeNN(db, p->aLTerm); p->aLTerm = paNew; p->nLSlot = n; return SQLITE_OK; @@ -149365,7 +149365,7 @@ static int whereLoopResize(tdsqlite3 *db, WhereLoop *p, int n){ /* ** Transfer content from the second pLoop into the first. */ -static int whereLoopXfer(tdsqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ +static int whereLoopXfer(sqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ whereLoopClearUnion(db, pTo); if( whereLoopResize(db, pTo, pFrom->nLTerm) ){ memset(&pTo->u, 0, sizeof(pTo->u)); @@ -149384,31 +149384,31 @@ static int whereLoopXfer(tdsqlite3 *db, WhereLoop *pTo, WhereLoop *pFrom){ /* ** Delete a WhereLoop object */ -static void whereLoopDelete(tdsqlite3 *db, WhereLoop *p){ +static void whereLoopDelete(sqlite3 *db, WhereLoop *p){ whereLoopClear(db, p); - tdsqlite3DbFreeNN(db, p); + sqlite3DbFreeNN(db, p); } /* ** Free a WhereInfo structure */ -static void whereInfoFree(tdsqlite3 *db, WhereInfo *pWInfo){ +static void whereInfoFree(sqlite3 *db, WhereInfo *pWInfo){ int i; assert( pWInfo!=0 ); for(i=0; inLevel; i++){ WhereLevel *pLevel = &pWInfo->a[i]; if( pLevel->pWLoop && (pLevel->pWLoop->wsFlags & WHERE_IN_ABLE) ){ - tdsqlite3DbFree(db, pLevel->u.in.aInLoop); + sqlite3DbFree(db, pLevel->u.in.aInLoop); } } - tdsqlite3WhereClauseClear(&pWInfo->sWC); + sqlite3WhereClauseClear(&pWInfo->sWC); while( pWInfo->pLoops ){ WhereLoop *p = pWInfo->pLoops; pWInfo->pLoops = p->pNextLoop; whereLoopDelete(db, p); } assert( pWInfo->pExprMods==0 ); - tdsqlite3DbFreeNN(db, pWInfo); + sqlite3DbFreeNN(db, pWInfo); } /* @@ -149598,7 +149598,7 @@ static WhereLoop **whereLoopFindLesser( static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ WhereLoop **ppPrev, *p; WhereInfo *pWInfo = pBuilder->pWInfo; - tdsqlite3 *db = pWInfo->pParse->db; + sqlite3 *db = pWInfo->pParse->db; int rc; /* Stop the search once we hit the query planner search limit */ @@ -149623,9 +149623,9 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ whereOrInsert(pBuilder->pOrSet, pTemplate->prereq, pTemplate->rRun, pTemplate->nOut); #if WHERETRACE_ENABLED /* 0x8 */ - if( tdsqlite3WhereTrace & 0x8 ){ - tdsqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n); - tdsqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(x?" or-%d: ":" or-X: ", n); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); } #endif } @@ -149640,9 +149640,9 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ /* There already exists a WhereLoop on the list that is better ** than pTemplate, so just ignore pTemplate */ #if WHERETRACE_ENABLED /* 0x8 */ - if( tdsqlite3WhereTrace & 0x8 ){ - tdsqlite3DebugPrintf(" skip: "); - tdsqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(" skip: "); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); } #endif return SQLITE_OK; @@ -149655,20 +149655,20 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ ** WhereLoop and insert it. */ #if WHERETRACE_ENABLED /* 0x8 */ - if( tdsqlite3WhereTrace & 0x8 ){ + if( sqlite3WhereTrace & 0x8 ){ if( p!=0 ){ - tdsqlite3DebugPrintf("replace: "); - tdsqlite3WhereLoopPrint(p, pBuilder->pWC); - tdsqlite3DebugPrintf(" with: "); + sqlite3DebugPrintf("replace: "); + sqlite3WhereLoopPrint(p, pBuilder->pWC); + sqlite3DebugPrintf(" with: "); }else{ - tdsqlite3DebugPrintf(" add: "); + sqlite3DebugPrintf(" add: "); } - tdsqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); + sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); } #endif if( p==0 ){ /* Allocate a new WhereLoop to add to the end of the list */ - *ppPrev = p = tdsqlite3DbMallocRawNN(db, sizeof(WhereLoop)); + *ppPrev = p = sqlite3DbMallocRawNN(db, sizeof(WhereLoop)); if( p==0 ) return SQLITE_NOMEM_BKPT; whereLoopInit(p); p->pNextLoop = 0; @@ -149685,9 +149685,9 @@ static int whereLoopInsert(WhereLoopBuilder *pBuilder, WhereLoop *pTemplate){ if( pToDel==0 ) break; *ppTail = pToDel->pNextLoop; #if WHERETRACE_ENABLED /* 0x8 */ - if( tdsqlite3WhereTrace & 0x8 ){ - tdsqlite3DebugPrintf(" delete: "); - tdsqlite3WhereLoopPrint(pToDel, pBuilder->pWC); + if( sqlite3WhereTrace & 0x8 ){ + sqlite3DebugPrintf(" delete: "); + sqlite3WhereLoopPrint(pToDel, pBuilder->pWC); } #endif whereLoopDelete(db, pToDel); @@ -149767,7 +149767,7 @@ static void whereLoopOutputAdjust( Expr *pRight = pTerm->pExpr->pRight; int k = 0; testcase( pTerm->pExpr->op==TK_IS ); - if( tdsqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ + if( sqlite3ExprIsInteger(pRight, &k) && k>=(-1) && k<=1 ){ k = 10; }else{ k = 20; @@ -149804,7 +149804,7 @@ static int whereRangeVectorLen( int nEq, /* Number of prior equality constraints on same index */ WhereTerm *pTerm /* The vector inequality constraint */ ){ - int nCmp = tdsqlite3ExprVectorSize(pTerm->pExpr->pLeft); + int nCmp = sqlite3ExprVectorSize(pTerm->pExpr->pLeft); int i; nCmp = MIN(nCmp, (pIdx->nColumn - nEq)); @@ -149835,13 +149835,13 @@ static int whereRangeVectorLen( } testcase( pLhs->iColumn==XN_ROWID ); - aff = tdsqlite3CompareAffinity(pRhs, tdsqlite3ExprAffinity(pLhs)); - idxaff = tdsqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); + aff = sqlite3CompareAffinity(pRhs, sqlite3ExprAffinity(pLhs)); + idxaff = sqlite3TableColumnAffinity(pIdx->pTable, pLhs->iColumn); if( aff!=idxaff ) break; - pColl = tdsqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); + pColl = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); if( pColl==0 ) break; - if( tdsqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; + if( sqlite3StrICmp(pColl->zName, pIdx->azColl[i+nEq]) ) break; } return i; } @@ -149876,7 +149876,7 @@ static int whereLoopAddBtreeIndex( ){ WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */ Parse *pParse = pWInfo->pParse; /* Parsing context */ - tdsqlite3 *db = pParse->db; /* Database connection malloc context */ + sqlite3 *db = pParse->db; /* Database connection malloc context */ WhereLoop *pNew; /* Template WhereLoop under construction */ WhereTerm *pTerm; /* A WhereTerm under consideration */ int opMask; /* Valid operators for constraints */ @@ -149978,7 +149978,7 @@ static int whereLoopAddBtreeIndex( if( ExprHasProperty(pExpr, EP_xIsSelect) ){ /* "x IN (SELECT ...)": TUNING: the SELECT returns 25 rows */ int i; - nIn = 46; assert( 46==tdsqlite3LogEst(25) ); + nIn = 46; assert( 46==sqlite3LogEst(25) ); /* The expression may actually be of the form (x, y) IN (SELECT...). ** In this case there is a separate term for each of (x) and (y). @@ -149990,7 +149990,7 @@ static int whereLoopAddBtreeIndex( } }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ /* "x IN (value, value, ...)" */ - nIn = tdsqlite3LogEst(pExpr->x.pList->nExpr); + nIn = sqlite3LogEst(pExpr->x.pList->nExpr); } if( pProbe->hasStat1 ){ LogEst M, logK, safetyMargin; @@ -150120,7 +150120,7 @@ static int whereLoopAddBtreeIndex( if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; if( rc!=SQLITE_OK ) break; /* Jump out of the pTerm loop */ if( nOut ){ - pNew->nOut = tdsqlite3LogEst(nOut); + pNew->nOut = sqlite3LogEst(nOut); if( pNew->nOut>saved_nOut ) pNew->nOut = saved_nOut; pNew->nOut -= nIn; } @@ -150145,9 +150145,9 @@ static int whereLoopAddBtreeIndex( ** visiting the rows in the main table. */ assert( pSrc->pTab->szTabRow>0 ); rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; - pNew->rRun = tdsqlite3LogEstAdd(rLogSize, rCostIdx); + pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ - pNew->rRun = tdsqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, pNew->nOut + 16); } ApplyCostMultiplier(pNew->rRun, pProbe->pTable->costMult); @@ -150192,7 +150192,7 @@ static int whereLoopAddBtreeIndex( ** the code). And, even if it is not, it should not be too much slower. ** On the other hand, the extra seeks could end up being significantly ** more expensive. */ - assert( 42==tdsqlite3LogEst(18) ); + assert( 42==sqlite3LogEst(18) ); if( saved_nEq==saved_nSkip && saved_nEq+1nKeyCol && saved_nEq==pNew->nLTerm @@ -150243,7 +150243,7 @@ static int indexMightHelpWithOrderBy( if( pIndex->bUnordered ) return 0; if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; for(ii=0; iinExpr; ii++){ - Expr *pExpr = tdsqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); + Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ if( pExpr->iColumn<0 ) return 1; for(jj=0; jjnKeyCol; jj++){ @@ -150252,7 +150252,7 @@ static int indexMightHelpWithOrderBy( }else if( (aColExpr = pIndex->aColExpr)!=0 ){ for(jj=0; jjnKeyCol; jj++){ if( pIndex->aiColumn[jj]!=XN_EXPR ) continue; - if( tdsqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ + if( sqlite3ExprCompareSkip(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){ return 1; } } @@ -150283,7 +150283,7 @@ static int whereUsablePartialIndex( pExpr = pTerm->pExpr; if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) && (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin)) - && tdsqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) + && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) ){ return 1; } @@ -150430,8 +150430,8 @@ static int whereLoopAddBtree( ** is more than the usual guess of 10 rows, since we have no way ** of knowing how selective the index will ultimately be. It would ** not be unreasonable to make this value much larger. */ - pNew->nOut = 43; assert( 43==tdsqlite3LogEst(20) ); - pNew->rRun = tdsqlite3LogEstAdd(rLogSize,pNew->nOut); + pNew->nOut = 43; assert( 43==sqlite3LogEst(20) ); + pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut); pNew->wsFlags = WHERE_AUTO_INDEX; pNew->prereq = mPrereq | pTerm->prereqRight; rc = whereLoopInsert(pBuilder, pNew); @@ -150499,7 +150499,7 @@ static int whereLoopAddBtree( && pProbe->bUnordered==0 && (pProbe->szIdxRowszTabRow) && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 - && tdsqlite3GlobalConfig.bUseCis + && sqlite3GlobalConfig.bUseCis && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan) ) ){ @@ -150521,7 +150521,7 @@ static int whereLoopAddBtree( WhereClause *pWC2 = &pWInfo->sWC; for(ii=0; iinTerm; ii++){ WhereTerm *pTerm = &pWC2->a[ii]; - if( !tdsqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){ + if( !sqlite3ExprCoveredByIndex(pTerm->pExpr, iCur, pProbe) ){ break; } /* pTerm can be evaluated using just the index. So reduce @@ -150534,7 +150534,7 @@ static int whereLoopAddBtree( } } - pNew->rRun = tdsqlite3LogEstAdd(pNew->rRun, nLookup); + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup); } ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); @@ -150554,7 +150554,7 @@ static int whereLoopAddBtree( pTab->tabFlags |= TF_StatsUsed; } #ifdef SQLITE_ENABLE_STAT4 - tdsqlite3Stat4ProbeFree(pBuilder->pRec); + sqlite3Stat4ProbeFree(pBuilder->pRec); pBuilder->nRecValid = 0; pBuilder->pRec = 0; #endif @@ -150589,13 +150589,13 @@ static int whereLoopAddVirtualOne( Bitmask mPrereq, /* Mask of tables that must be used. */ Bitmask mUsable, /* Mask of usable tables */ u16 mExclude, /* Exclude terms using these operators */ - tdsqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ + sqlite3_index_info *pIdxInfo, /* Populated object for xBestIndex */ u16 mNoOmit, /* Do not omit these constraints */ int *pbIn /* OUT: True if plan uses an IN(...) op */ ){ WhereClause *pWC = pBuilder->pWC; - struct tdsqlite3_index_constraint *pIdxCons; - struct tdsqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage; + struct sqlite3_index_constraint *pIdxCons; + struct sqlite3_index_constraint_usage *pUsage = pIdxInfo->aConstraintUsage; int i; int mxTerm; int rc = SQLITE_OK; @@ -150610,7 +150610,7 @@ static int whereLoopAddVirtualOne( /* Set the usable flag on the subset of constraints identified by ** arguments mUsable and mExclude. */ - pIdxCons = *(struct tdsqlite3_index_constraint**)&pIdxInfo->aConstraint; + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; ia[pIdxCons->iTermOffset]; pIdxCons->usable = 0; @@ -150621,7 +150621,7 @@ static int whereLoopAddVirtualOne( } } - /* Initialize the output fields of the tdsqlite3_index_info structure */ + /* Initialize the output fields of the sqlite3_index_info structure */ memset(pUsage, 0, sizeof(pUsage[0])*nConstraint); assert( pIdxInfo->needToFreeIdxStr==0 ); pIdxInfo->idxStr = 0; @@ -150630,7 +150630,7 @@ static int whereLoopAddVirtualOne( pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2; pIdxInfo->estimatedRows = 25; pIdxInfo->idxFlags = 0; - pIdxInfo->colUsed = (tdsqlite3_int64)pSrc->colUsed; + pIdxInfo->colUsed = (sqlite3_int64)pSrc->colUsed; /* Invoke the virtual table xBestIndex() method */ rc = vtabBestIndex(pParse, pSrc->pTab, pIdxInfo); @@ -150650,7 +150650,7 @@ static int whereLoopAddVirtualOne( assert( pNew->nLSlot>=nConstraint ); for(i=0; iaLTerm[i] = 0; pNew->u.vtab.omitMask = 0; - pIdxCons = *(struct tdsqlite3_index_constraint**)&pIdxInfo->aConstraint; + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; i=0 ){ @@ -150662,7 +150662,7 @@ static int whereLoopAddVirtualOne( || pNew->aLTerm[iTerm]!=0 || pIdxCons->usable==0 ){ - tdsqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); testcase( pIdxInfo->needToFreeIdxStr ); return SQLITE_ERROR; } @@ -150702,7 +150702,7 @@ static int whereLoopAddVirtualOne( if( pNew->aLTerm[i]==0 ){ /* The non-zero argvIdx values must be contiguous. Raise an ** error if they are not */ - tdsqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); + sqlite3ErrorMsg(pParse,"%s.xBestIndex malfunction",pSrc->pTab->zName); testcase( pIdxInfo->needToFreeIdxStr ); return SQLITE_ERROR; } @@ -150715,8 +150715,8 @@ static int whereLoopAddVirtualOne( pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ? pIdxInfo->nOrderBy : 0); pNew->rSetup = 0; - pNew->rRun = tdsqlite3LogEstFromDouble(pIdxInfo->estimatedCost); - pNew->nOut = tdsqlite3LogEst(pIdxInfo->estimatedRows); + pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost); + pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows); /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated ** that the scan will visit at most one row. Clear it otherwise. */ @@ -150727,12 +150727,12 @@ static int whereLoopAddVirtualOne( } rc = whereLoopInsert(pBuilder, pNew); if( pNew->u.vtab.needFree ){ - tdsqlite3_free(pNew->u.vtab.idxStr); + sqlite3_free(pNew->u.vtab.idxStr); pNew->u.vtab.needFree = 0; } WHERETRACE(0xffff, (" bIn=%d prereqIn=%04llx prereqOut=%04llx\n", - *pbIn, (tdsqlite3_uint64)mPrereq, - (tdsqlite3_uint64)(pNew->prereq & ~mPrereq))); + *pbIn, (sqlite3_uint64)mPrereq, + (sqlite3_uint64)(pNew->prereq & ~mPrereq))); return rc; } @@ -150740,11 +150740,11 @@ static int whereLoopAddVirtualOne( /* ** If this function is invoked from within an xBestIndex() callback, it ** returns a pointer to a buffer containing the name of the collation -** sequence associated with element iCons of the tdsqlite3_index_info.aConstraint +** sequence associated with element iCons of the sqlite3_index_info.aConstraint ** array. Or, if iCons is out of range or there is no active xBestIndex ** call, return NULL. */ -SQLITE_API const char *tdsqlite3_vtab_collation(tdsqlite3_index_info *pIdxInfo, int iCons){ +SQLITE_API const char *sqlite3_vtab_collation(sqlite3_index_info *pIdxInfo, int iCons){ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; const char *zRet = 0; if( iCons>=0 && iConsnConstraint ){ @@ -150752,9 +150752,9 @@ SQLITE_API const char *tdsqlite3_vtab_collation(tdsqlite3_index_info *pIdxInfo, int iTerm = pIdxInfo->aConstraint[iCons].iTermOffset; Expr *pX = pHidden->pWC->a[iTerm].pExpr; if( pX->pLeft ){ - pC = tdsqlite3ExprCompareCollSeq(pHidden->pParse, pX); + pC = sqlite3ExprCompareCollSeq(pHidden->pParse, pX); } - zRet = (pC ? pC->zName : tdsqlite3StrBINARY); + zRet = (pC ? pC->zName : sqlite3StrBINARY); } return zRet; } @@ -150794,7 +150794,7 @@ static int whereLoopAddVirtual( Parse *pParse; /* The parsing context */ WhereClause *pWC; /* The WHERE clause */ struct SrcList_item *pSrc; /* The FROM clause term to search */ - tdsqlite3_index_info *p; /* Object to pass to xBestIndex() */ + sqlite3_index_info *p; /* Object to pass to xBestIndex() */ int nConstraint; /* Number of constraints in p */ int bIn; /* True if plan uses IN(...) operator */ WhereLoop *pNew; @@ -150817,7 +150817,7 @@ static int whereLoopAddVirtual( pNew->u.vtab.needFree = 0; nConstraint = p->nConstraint; if( whereLoopResize(pParse->db, pNew, nConstraint) ){ - tdsqlite3DbFree(pParse->db, p); + sqlite3DbFree(pParse->db, p); return SQLITE_NOMEM_BKPT; } @@ -150867,7 +150867,7 @@ static int whereLoopAddVirtual( if( mNext==ALLBITS ) break; if( mNext==mBest || mNext==mBestNoIn ) continue; WHERETRACE(0x40, (" VirtualOne: mPrev=%04llx mNext=%04llx\n", - (tdsqlite3_uint64)mPrev, (tdsqlite3_uint64)mNext)); + (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext)); rc = whereLoopAddVirtualOne( pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn); if( pNew->prereq==mPrereq ){ @@ -150896,8 +150896,8 @@ static int whereLoopAddVirtual( } } - if( p->needToFreeIdxStr ) tdsqlite3_free(p->idxStr); - tdsqlite3DbFreeNN(pParse->db, p); + if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr); + sqlite3DbFreeNN(pParse->db, p); WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc)); return rc; } @@ -150962,8 +150962,8 @@ static int whereLoopAddOr( #ifdef WHERETRACE_ENABLED WHERETRACE(0x200, ("OR-term %d of %p has %d subterms:\n", (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); - if( tdsqlite3WhereTrace & 0x400 ){ - tdsqlite3WhereClausePrint(sSubBuild.pWC); + if( sqlite3WhereTrace & 0x400 ){ + sqlite3WhereClausePrint(sSubBuild.pWC); } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -150992,8 +150992,8 @@ static int whereLoopAddOr( for(i=0; ipTabList; struct SrcList_item *pItem; struct SrcList_item *pEnd = &pTabList->a[pWInfo->nLevel]; - tdsqlite3 *db = pWInfo->pParse->db; + sqlite3 *db = pWInfo->pParse->db; int rc = SQLITE_OK; WhereLoop *pNew; u8 priorJointype = 0; @@ -151052,7 +151052,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ Bitmask mUnusable = 0; pNew->iTab = iTab; pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; - pNew->maskSelf = tdsqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); + pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); if( ((pItem->fg.jointype|priorJointype) & (JT_LEFT|JT_CROSS))!=0 ){ /* This condition is true when pItem is the FROM clause term on the ** right-hand-side of a LEFT or CROSS JOIN. */ @@ -151064,7 +151064,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ struct SrcList_item *p; for(p=&pItem[1]; pfg.jointype & (JT_LEFT|JT_CROSS)) ){ - mUnusable |= tdsqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); + mUnusable |= sqlite3WhereGetMask(&pWInfo->sMaskSet, p->iCursor); } } rc = whereLoopAddVirtual(pBuilder, mPrereq, mUnusable); @@ -151080,7 +151080,7 @@ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ if( rc || db->mallocFailed ){ if( rc==SQLITE_DONE ){ /* We hit the query planner search limit set by iPlanLimit */ - tdsqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search"); + sqlite3_log(SQLITE_WARNING, "abbreviated query algorithm search"); rc = SQLITE_OK; }else{ break; @@ -151137,7 +151137,7 @@ static i8 wherePathSatisfiesOrderBy( Expr *pOBExpr; /* An expression from the ORDER BY clause */ CollSeq *pColl; /* COLLATE function from an ORDER BY clause term */ Index *pIndex; /* The index associated with pLoop */ - tdsqlite3 *db = pWInfo->pParse->db; /* Database connection */ + sqlite3 *db = pWInfo->pParse->db; /* Database connection */ Bitmask obSat = 0; /* Mask of ORDER BY terms satisfied so far */ Bitmask obDone; /* Mask of all ORDER BY terms */ Bitmask orderDistinctMask; /* Mask of all well-ordered loops */ @@ -151202,10 +151202,10 @@ static i8 wherePathSatisfiesOrderBy( */ for(i=0; ia[i].pExpr); + pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); if( pOBExpr->op!=TK_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; - pTerm = tdsqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, + pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, ~ready, eqOpMask, 0); if( pTerm==0 ) continue; if( pTerm->eOperator==WO_IN ){ @@ -151217,7 +151217,7 @@ static i8 wherePathSatisfiesOrderBy( if( j>=pLoop->nLTerm ) continue; } if( (pTerm->eOperator&(WO_EQ|WO_IS))!=0 && pOBExpr->iColumn>=0 ){ - if( tdsqlite3ExprCollSeqMatch(pWInfo->pParse, + if( sqlite3ExprCollSeqMatch(pWInfo->pParse, pOrderBy->a[i].pExpr, pTerm->pExpr)==0 ){ continue; } @@ -151322,7 +151322,7 @@ static i8 wherePathSatisfiesOrderBy( isMatch = 0; for(i=0; bOnce && ia[i].pExpr); + pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); testcase( wctrlFlags & WHERE_GROUPBY ); testcase( wctrlFlags & WHERE_DISTINCTBY ); if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; @@ -151332,13 +151332,13 @@ static i8 wherePathSatisfiesOrderBy( if( pOBExpr->iColumn!=iColumn ) continue; }else{ Expr *pIdxExpr = pIndex->aColExpr->a[j].pExpr; - if( tdsqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){ + if( sqlite3ExprCompareSkip(pOBExpr, pIdxExpr, iCur) ){ continue; } } if( iColumn!=XN_ROWID ){ - pColl = tdsqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); - if( tdsqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; + pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); + if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; } if( wctrlFlags & WHERE_DISTINCTBY ){ pLoop->u.btree.nDistinctCol = j+1; @@ -151395,8 +151395,8 @@ static i8 wherePathSatisfiesOrderBy( Bitmask mTerm; if( MASKBIT(i) & obSat ) continue; p = pOrderBy->a[i].pExpr; - mTerm = tdsqlite3WhereExprUsage(&pWInfo->sMaskSet,p); - if( mTerm==0 && !tdsqlite3ExprIsConstant(p) ) continue; + mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p); + if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue; if( (mTerm&~orderDistinctMask)==0 ){ obSat |= MASKBIT(i); } @@ -151416,7 +151416,7 @@ static i8 wherePathSatisfiesOrderBy( /* -** If the WHERE_GROUPBY flag is set in the mask passed to tdsqlite3WhereBegin(), +** If the WHERE_GROUPBY flag is set in the mask passed to sqlite3WhereBegin(), ** the planner assumes that the specified pOrderBy list is actually a GROUP ** BY clause - and so any order that groups rows as required satisfies the ** request. @@ -151424,7 +151424,7 @@ static i8 wherePathSatisfiesOrderBy( ** Normally, in this case it is not possible for the caller to determine ** whether or not the rows are really being delivered in sorted order, or ** just in some other order that provides the required grouping. However, -** if the WHERE_SORTBYGROUP flag is also passed to tdsqlite3WhereBegin(), then +** if the WHERE_SORTBYGROUP flag is also passed to sqlite3WhereBegin(), then ** this function may be called on the returned WhereInfo object. It returns ** true if the rows really will be sorted in the specified order, or false ** otherwise. @@ -151438,7 +151438,7 @@ static i8 wherePathSatisfiesOrderBy( ** SELECT * FROM t1 GROUP BY x,y ORDER BY x,y; -- IsSorted()==1 ** SELECT * FROM t1 GROUP BY y,x ORDER BY y,x; -- IsSorted()==0 */ -SQLITE_PRIVATE int tdsqlite3WhereIsSorted(WhereInfo *pWInfo){ +SQLITE_PRIVATE int sqlite3WhereIsSorted(WhereInfo *pWInfo){ assert( pWInfo->wctrlFlags & WHERE_GROUPBY ); assert( pWInfo->wctrlFlags & WHERE_SORTBYGROUP ); return pWInfo->sorted; @@ -151481,8 +151481,8 @@ static LogEst whereSortingCost( ** The (Y/X) term is implemented using stack variable rScale ** below. */ LogEst rScale, rSortCost; - assert( nOrderBy>0 && 66==tdsqlite3LogEst(100) ); - rScale = tdsqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; + assert( nOrderBy>0 && 66==sqlite3LogEst(100) ); + rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66; rSortCost = nRow + rScale + 16; /* Multiple by log(M) where M is the number of output rows. @@ -151510,7 +151510,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ int mxChoice; /* Maximum number of simultaneous paths tracked */ int nLoop; /* Number of terms in the join */ Parse *pParse; /* Parsing context */ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ int iLoop; /* Loop counter over the terms of the join */ int ii, jj; /* Loop counters */ int mxI = 0; /* Index of next entry to replace */ @@ -151552,7 +151552,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ /* Allocate and initialize space for aTo, aFrom and aSortCost[] */ nSpace = (sizeof(WherePath)+sizeof(WhereLoop*)*nLoop)*mxChoice*2; nSpace += sizeof(LogEst) * nOrderBy; - pSpace = tdsqlite3DbMallocRawNN(db, nSpace); + pSpace = sqlite3DbMallocRawNN(db, nSpace); if( pSpace==0 ) return SQLITE_NOMEM_BKPT; aTo = (WherePath*)pSpace; aFrom = aTo+mxChoice; @@ -151579,7 +151579,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** TUNING: Do not let the number of iterations go above 28. If the cost ** of computing an automatic index is not paid back within the first 28 ** rows, then do not use the automatic index. */ - aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==tdsqlite3LogEst(28) ); + aFrom[0].nRow = MIN(pParse->nQueryLoop, 48); assert( 48==sqlite3LogEst(28) ); nFrom = 1; assert( aFrom[0].isOrdered==0 ); if( nOrderBy ){ @@ -151613,14 +151613,14 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** to run less than 1.25 times. It is tempting to also exclude ** automatic index usage on an outer loop, but sometimes an automatic ** index is useful in the outer loop of a correlated subquery. */ - assert( 10==tdsqlite3LogEst(2) ); + assert( 10==sqlite3LogEst(2) ); continue; } /* At this point, pWLoop is a candidate to be the next loop. ** Compute its cost */ - rUnsorted = tdsqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); - rUnsorted = tdsqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); + rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); + rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); nOut = pFrom->nRow + pWLoop->nOut; maskNew = pFrom->maskLoop | pWLoop->maskSelf; if( isOrdered<0 ){ @@ -151640,7 +151640,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** extra encouragment to the query planner to select a plan ** where the rows emerge in the correct order without any sorting ** required. */ - rCost = tdsqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; + rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]) + 5; WHERETRACE(0x002, ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", @@ -151679,8 +151679,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** paths currently in the best-so-far buffer. So discard ** this candidate as not viable. */ #ifdef WHERETRACE_ENABLED /* 0x4 */ - if( tdsqlite3WhereTrace&0x4 ){ - tdsqlite3DebugPrintf("Skip %s cost=%-3d,%3d,%3d order=%c\n", + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf("Skip %s cost=%-3d,%3d,%3d order=%c\n", wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted, isOrdered>=0 ? isOrdered+'0' : '?'); } @@ -151698,8 +151698,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } pTo = &aTo[jj]; #ifdef WHERETRACE_ENABLED /* 0x4 */ - if( tdsqlite3WhereTrace&0x4 ){ - tdsqlite3DebugPrintf("New %s cost=%-3d,%3d,%3d order=%c\n", + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf("New %s cost=%-3d,%3d,%3d order=%c\n", wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted, isOrdered>=0 ? isOrdered+'0' : '?'); } @@ -151721,12 +151721,12 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ) ){ #ifdef WHERETRACE_ENABLED /* 0x4 */ - if( tdsqlite3WhereTrace&0x4 ){ - tdsqlite3DebugPrintf( + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf( "Skip %s cost=%-3d,%3d,%3d order=%c", wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted, isOrdered>=0 ? isOrdered+'0' : '?'); - tdsqlite3DebugPrintf(" vs %s cost=%-3d,%3d,%3d order=%c\n", + sqlite3DebugPrintf(" vs %s cost=%-3d,%3d,%3d order=%c\n", wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); } @@ -151739,12 +151739,12 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ /* Control reaches here if the candidate path is better than the ** pTo path. Replace pTo with the candidate. */ #ifdef WHERETRACE_ENABLED /* 0x4 */ - if( tdsqlite3WhereTrace&0x4 ){ - tdsqlite3DebugPrintf( + if( sqlite3WhereTrace&0x4 ){ + sqlite3DebugPrintf( "Update %s cost=%-3d,%3d,%3d order=%c", wherePathName(pFrom, iLoop, pWLoop), rCost, nOut, rUnsorted, isOrdered>=0 ? isOrdered+'0' : '?'); - tdsqlite3DebugPrintf(" was %s cost=%-3d,%3d,%3d order=%c\n", + sqlite3DebugPrintf(" was %s cost=%-3d,%3d,%3d order=%c\n", wherePathName(pTo, iLoop+1, 0), pTo->rCost, pTo->nRow, pTo->rUnsorted, pTo->isOrdered>=0 ? pTo->isOrdered+'0' : '?'); } @@ -151777,16 +151777,16 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } #ifdef WHERETRACE_ENABLED /* >=2 */ - if( tdsqlite3WhereTrace & 0x02 ){ - tdsqlite3DebugPrintf("---- after round %d ----\n", iLoop); + if( sqlite3WhereTrace & 0x02 ){ + sqlite3DebugPrintf("---- after round %d ----\n", iLoop); for(ii=0, pTo=aTo; iirCost, pTo->nRow, pTo->isOrdered>=0 ? (pTo->isOrdered+'0') : '?'); if( pTo->isOrdered>0 ){ - tdsqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); + sqlite3DebugPrintf(" rev=0x%llx\n", pTo->revLoop); }else{ - tdsqlite3DebugPrintf("\n"); + sqlite3DebugPrintf("\n"); } } } @@ -151800,8 +151800,8 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ } if( nFrom==0 ){ - tdsqlite3ErrorMsg(pParse, "no query solution"); - tdsqlite3DbFreeNN(db, pSpace); + sqlite3ErrorMsg(pParse, "no query solution"); + sqlite3DbFreeNN(db, pSpace); return SQLITE_ERROR; } @@ -151878,7 +151878,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ pWInfo->nRowOut = pFrom->nRow; /* Free temporary memory and return success */ - tdsqlite3DbFreeNN(db, pSpace); + sqlite3DbFreeNN(db, pSpace); return SQLITE_OK; } @@ -151886,7 +151886,7 @@ static int wherePathSolver(WhereInfo *pWInfo, LogEst nRowEst){ ** Most queries use only a single table (they are not joins) and have ** simple == constraints against indexed fields. This routine attempts ** to plan those simple cases using much less ceremony than the -** general-purpose query planner, and thereby yield faster tdsqlite3_prepare() +** general-purpose query planner, and thereby yield faster sqlite3_prepare() ** times for the common case. ** ** Return non-zero on success, if this query can be handled by this @@ -151916,7 +151916,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ pLoop = pBuilder->pNew; pLoop->wsFlags = 0; pLoop->nSkip = 0; - pTerm = tdsqlite3WhereFindTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0); + pTerm = sqlite3WhereFindTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0); if( pTerm ){ testcase( pTerm->eOperator & WO_IS ); pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW; @@ -151924,7 +151924,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ pLoop->nLTerm = 1; pLoop->u.btree.nEq = 1; /* TUNING: Cost of a rowid lookup is 10 */ - pLoop->rRun = 33; /* 33==tdsqlite3LogEst(10) */ + pLoop->rRun = 33; /* 33==sqlite3LogEst(10) */ }else{ for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int opMask; @@ -151935,7 +151935,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ ) continue; opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ; for(j=0; jnKeyCol; j++){ - pTerm = tdsqlite3WhereFindTerm(pWC, iCur, j, 0, opMask, pIdx); + pTerm = sqlite3WhereFindTerm(pWC, iCur, j, 0, opMask, pIdx); if( pTerm==0 ) break; testcase( pTerm->eOperator & WO_IS ); pLoop->aLTerm[j] = pTerm; @@ -151949,7 +151949,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ pLoop->u.btree.nEq = j; pLoop->u.btree.pIndex = pIdx; /* TUNING: Cost of a unique index lookup is 15 */ - pLoop->rRun = 39; /* 39==tdsqlite3LogEst(15) */ + pLoop->rRun = 39; /* 39==sqlite3LogEst(15) */ break; } } @@ -151957,7 +151957,7 @@ static int whereShortCut(WhereLoopBuilder *pBuilder){ pLoop->nOut = (LogEst)1; pWInfo->a[0].pWLoop = pLoop; assert( pWInfo->sMaskSet.n==1 && iCur==pWInfo->sMaskSet.ix[0] ); - pLoop->maskSelf = 1; /* tdsqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */ + pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */ pWInfo->a[0].iTabCur = iCur; pWInfo->nRowOut = 1; if( pWInfo->pOrderBy ) pWInfo->nOBSat = pWInfo->pOrderBy->nExpr; @@ -151993,8 +151993,8 @@ static int exprIsDeterministic(Expr *p){ memset(&w, 0, sizeof(w)); w.eCode = 1; w.xExprCallback = exprNodeIsDeterministic; - w.xSelectCallback = tdsqlite3SelectWalkFail; - tdsqlite3WalkExpr(&w, p); + w.xSelectCallback = sqlite3SelectWalkFail; + sqlite3WalkExpr(&w, p); return w.eCode; } @@ -152002,7 +152002,7 @@ static int exprIsDeterministic(Expr *p){ ** Generate the beginning of the loop used for WHERE clause processing. ** The return value is a pointer to an opaque structure that contains ** information needed to terminate the loop. Later, the calling routine -** should invoke tdsqlite3WhereEnd() with the return value of this function +** should invoke sqlite3WhereEnd() with the return value of this function ** in order to complete the WHERE clause processing. ** ** If an error occurs, this routine returns NULL. @@ -152017,11 +152017,11 @@ static int exprIsDeterministic(Expr *p){ ** Then the code generated is conceptually like the following: ** ** foreach row1 in t1 do \ Code generated -** foreach row2 in t2 do |-- by tdsqlite3WhereBegin() +** foreach row2 in t2 do |-- by sqlite3WhereBegin() ** foreach row3 in t3 do / ** ... ** end \ Code generated -** end |-- by tdsqlite3WhereEnd() +** end |-- by sqlite3WhereEnd() ** end / ** ** Note that the loops might not be nested in the order in which they @@ -152033,9 +152033,9 @@ static int exprIsDeterministic(Expr *p){ ** There are Btree cursors associated with each table. t1 uses cursor ** number pTabList->a[0].iCursor. t2 uses the cursor pTabList->a[1].iCursor. ** And so forth. This routine generates code to open those VDBE cursors -** and tdsqlite3WhereEnd() generates the code to close them. +** and sqlite3WhereEnd() generates the code to close them. ** -** The code that tdsqlite3WhereBegin() generates leaves the cursors named +** The code that sqlite3WhereBegin() generates leaves the cursors named ** in pTabList pointing at their appropriate entries. The [...] code ** can use OP_Column and OP_Rowid opcodes on these cursors to extract ** data from the various tables of the loop. @@ -152086,7 +152086,7 @@ static int exprIsDeterministic(Expr *p){ ** be used to compute the appropriate cursor depending on which index is ** used. */ -SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( +SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( Parse *pParse, /* The parser context */ SrcList *pTabList, /* FROM clause: A list of all tables to be scanned */ Expr *pWhere, /* The WHERE clause */ @@ -152106,7 +152106,7 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( WhereLevel *pLevel; /* A single level in pWInfo->a[] */ WhereLoop *pLoop; /* Pointer to a single WhereLoop object */ int ii; /* Loop counter */ - tdsqlite3 *db; /* Database connection */ + sqlite3 *db; /* Database connection */ int rc; /* Return code */ u8 bFordelete = 0; /* OPFLAG_FORDELETE or zero, as appropriate */ @@ -152129,7 +152129,7 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( sWLB.pOrderBy = pOrderBy; /* Disable the DISTINCT optimization if SQLITE_DistinctOpt is set via - ** tdsqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ + ** sqlite3_test_ctrl(SQLITE_TESTCTRL_OPTIMIZATIONS,...) */ if( OptimizationDisabled(db, SQLITE_DistinctOpt) ){ wctrlFlags &= ~WHERE_WANT_DISTINCT; } @@ -152139,7 +152139,7 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( */ testcase( pTabList->nSrc==BMS ); if( pTabList->nSrc>BMS ){ - tdsqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); + sqlite3ErrorMsg(pParse, "at most %d tables in a join", BMS); return 0; } @@ -152158,9 +152158,9 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( ** some architectures. Hence the ROUND8() below. */ nByteWInfo = ROUND8(sizeof(WhereInfo)+(nTabList-1)*sizeof(WhereLevel)); - pWInfo = tdsqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); + pWInfo = sqlite3DbMallocRawNN(db, nByteWInfo + sizeof(WhereLoop)); if( db->mallocFailed ){ - tdsqlite3DbFree(db, pWInfo); + sqlite3DbFree(db, pWInfo); pWInfo = 0; goto whereBeginError; } @@ -152171,7 +152171,7 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( pWInfo->pResultSet = pResultSet; pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; pWInfo->nLevel = nTabList; - pWInfo->iBreak = pWInfo->iContinue = tdsqlite3VdbeMakeLabel(pParse); + pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse); pWInfo->wctrlFlags = wctrlFlags; pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; @@ -152193,8 +152193,8 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( ** subexpression is separated by an AND operator. */ initMaskSet(pMaskSet); - tdsqlite3WhereClauseInit(&pWInfo->sWC, pWInfo); - tdsqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND); + sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo); + sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND); /* Special case: No FROM clause */ @@ -152222,13 +152222,13 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( ii = 0; do{ createMask(pMaskSet, pTabList->a[ii].iCursor); - tdsqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); + sqlite3WhereTabFuncArgs(pParse, &pTabList->a[ii], &pWInfo->sWC); }while( (++ii)nSrc ); #ifdef SQLITE_DEBUG { Bitmask mx = 0; for(ii=0; iinSrc; ii++){ - Bitmask m = tdsqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); + Bitmask m = sqlite3WhereGetMask(pMaskSet, pTabList->a[ii].iCursor); assert( m>=mx ); mx = m; } @@ -152237,7 +152237,7 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( } /* Analyze all of the subexpressions. */ - tdsqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); + sqlite3WhereExprAnalyze(pTabList, &pWInfo->sWC); if( db->mallocFailed ) goto whereBeginError; /* Special case: WHERE terms that do not refer to any tables in the join @@ -152255,7 +152255,7 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( WhereTerm *pT = &sWLB.pWC->a[ii]; if( pT->wtFlags & TERM_VIRTUAL ) continue; if( pT->prereqAll==0 && (nTabList==0 || exprIsDeterministic(pT->pExpr)) ){ - tdsqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL); + sqlite3ExprIfFalse(pParse, pT->pExpr, pWInfo->iBreak, SQLITE_JUMPIFNULL); pT->wtFlags |= TERM_CODED; } } @@ -152273,13 +152273,13 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( /* Construct the WhereLoop objects */ #if defined(WHERETRACE_ENABLED) - if( tdsqlite3WhereTrace & 0xffff ){ - tdsqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); + if( sqlite3WhereTrace & 0xffff ){ + sqlite3DebugPrintf("*** Optimizer Start *** (wctrlFlags: 0x%x",wctrlFlags); if( wctrlFlags & WHERE_USE_LIMIT ){ - tdsqlite3DebugPrintf(", limit: %d", iAuxArg); + sqlite3DebugPrintf(", limit: %d", iAuxArg); } - tdsqlite3DebugPrintf(")\n"); - if( tdsqlite3WhereTrace & 0x100 ){ + sqlite3DebugPrintf(")\n"); + if( sqlite3WhereTrace & 0x100 ){ Select sSelect; memset(&sSelect, 0, sizeof(sSelect)); sSelect.selFlags = SF_WhereBegin; @@ -152287,12 +152287,12 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( sSelect.pWhere = pWhere; sSelect.pOrderBy = pOrderBy; sSelect.pEList = pResultSet; - tdsqlite3TreeViewSelect(0, &sSelect, 0); + sqlite3TreeViewSelect(0, &sSelect, 0); } } - if( tdsqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ - tdsqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); - tdsqlite3WhereClausePrint(sWLB.pWC); + if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ + sqlite3DebugPrintf("---- WHERE clause at start of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); } #endif @@ -152301,14 +152301,14 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( if( rc ) goto whereBeginError; #ifdef WHERETRACE_ENABLED - if( tdsqlite3WhereTrace ){ /* Display all of the WhereLoop objects */ + if( sqlite3WhereTrace ){ /* Display all of the WhereLoop objects */ WhereLoop *p; int i; static const char zLabel[] = "0123456789abcdefghijklmnopqrstuvwyxz" "ABCDEFGHIJKLMNOPQRSTUVWYXZ"; for(p=pWInfo->pLoops, i=0; p; p=p->pNextLoop, i++){ p->cId = zLabel[i%(sizeof(zLabel)-1)]; - tdsqlite3WhereLoopPrint(p, sWLB.pWC); + sqlite3WhereLoopPrint(p, sWLB.pWC); } } #endif @@ -152327,28 +152327,28 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( goto whereBeginError; } #ifdef WHERETRACE_ENABLED - if( tdsqlite3WhereTrace ){ - tdsqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); + if( sqlite3WhereTrace ){ + sqlite3DebugPrintf("---- Solution nRow=%d", pWInfo->nRowOut); if( pWInfo->nOBSat>0 ){ - tdsqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); + sqlite3DebugPrintf(" ORDERBY=%d,0x%llx", pWInfo->nOBSat, pWInfo->revMask); } switch( pWInfo->eDistinct ){ case WHERE_DISTINCT_UNIQUE: { - tdsqlite3DebugPrintf(" DISTINCT=unique"); + sqlite3DebugPrintf(" DISTINCT=unique"); break; } case WHERE_DISTINCT_ORDERED: { - tdsqlite3DebugPrintf(" DISTINCT=ordered"); + sqlite3DebugPrintf(" DISTINCT=ordered"); break; } case WHERE_DISTINCT_UNORDERED: { - tdsqlite3DebugPrintf(" DISTINCT=unordered"); + sqlite3DebugPrintf(" DISTINCT=unordered"); break; } } - tdsqlite3DebugPrintf("\n"); + sqlite3DebugPrintf("\n"); for(ii=0; iinLevel; ii++){ - tdsqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC); + sqlite3WhereLoopPrint(pWInfo->a[ii].pWLoop, sWLB.pWC); } } #endif @@ -152388,9 +152388,9 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( && OptimizationEnabled(db, SQLITE_OmitNoopJoin) ){ int i; - Bitmask tabUsed = tdsqlite3WhereExprListUsage(pMaskSet, pResultSet); + Bitmask tabUsed = sqlite3WhereExprListUsage(pMaskSet, pResultSet); if( sWLB.pOrderBy ){ - tabUsed |= tdsqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); + tabUsed |= sqlite3WhereExprListUsage(pMaskSet, sWLB.pOrderBy); } for(i=pWInfo->nLevel-1; i>=1; i--){ WhereTerm *pTerm, *pEnd; @@ -152431,9 +152431,9 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( } } #if defined(WHERETRACE_ENABLED) - if( tdsqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ - tdsqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); - tdsqlite3WhereClausePrint(sWLB.pWC); + if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */ + sqlite3DebugPrintf("---- WHERE clause at end of analysis:\n"); + sqlite3WhereClausePrint(sWLB.pWC); } WHERETRACE(0xffff,("*** Optimizer Finished ***\n")); #endif @@ -152488,16 +152488,16 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; - iDb = tdsqlite3SchemaToIndex(db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); pLoop = pLevel->pWLoop; if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ){ /* Do nothing */ }else #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){ - const char *pVTab = (const char *)tdsqlite3GetVTable(db, pTab); + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); int iCur = pTabItem->iCursor; - tdsqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); + sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); }else if( IsVirtual(pTab) ){ /* noop */ }else @@ -152509,7 +152509,7 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( op = OP_OpenWrite; pWInfo->aiCurOnePass[0] = pTabItem->iCursor; }; - tdsqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); + sqlite3OpenTable(pParse, pTabItem->iCursor, iDb, pTab, op); assert( pTabItem->iCursor==pLevel->iTabCur ); testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 ); testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS ); @@ -152523,23 +152523,23 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( Bitmask b = pTabItem->colUsed; int n = 0; for(; b; b=b>>1, n++){} - tdsqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32); + sqlite3VdbeChangeP4(v, -1, SQLITE_INT_TO_PTR(n), P4_INT32); assert( n<=pTab->nCol ); } #ifdef SQLITE_ENABLE_CURSOR_HINTS if( pLoop->u.btree.pIndex!=0 ){ - tdsqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); + sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ|bFordelete); }else #endif { - tdsqlite3VdbeChangeP5(v, bFordelete); + sqlite3VdbeChangeP5(v, bFordelete); } #ifdef SQLITE_ENABLE_COLUMN_USED_MASK - tdsqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, pTabItem->iCursor, 0, 0, (const u8*)&pTabItem->colUsed, P4_INT64); #endif }else{ - tdsqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); + sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); } if( pLoop->wsFlags & WHERE_INDEXED ){ Index *pIx = pLoop->u.btree.pIndex; @@ -152574,15 +152574,15 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( assert( pIx->pSchema==pTab->pSchema ); assert( iIndexCur>=0 ); if( op ){ - tdsqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); - tdsqlite3VdbeSetP4KeyInfo(pParse, pIx); + sqlite3VdbeAddOp3(v, op, iIndexCur, pIx->tnum, iDb); + sqlite3VdbeSetP4KeyInfo(pParse, pIx); if( (pLoop->wsFlags & WHERE_CONSTRAINT)!=0 && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 && (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0 && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED ){ - tdsqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ + sqlite3VdbeChangeP5(v, OPFLAG_SEEKEQ); /* Hint to COMDB2 */ } VdbeComment((v, "%s", pIx->zName)); #ifdef SQLITE_ENABLE_COLUMN_USED_MASK @@ -152596,15 +152596,15 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( if( (pTabItem->colUsed & MASKBIT(jj))==0 ) continue; colUsed |= ((u64)1)<<(ii<63 ? ii : 63); } - tdsqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, + sqlite3VdbeAddOp4Dup8(v, OP_ColumnsUsed, iIndexCur, 0, 0, (u8*)&colUsed, P4_INT64); } #endif /* SQLITE_ENABLE_COLUMN_USED_MASK */ } } - if( iDb>=0 ) tdsqlite3CodeVerifySchema(pParse, iDb); + if( iDb>=0 ) sqlite3CodeVerifySchema(pParse, iDb); } - pWInfo->iTop = tdsqlite3VdbeCurrentAddr(v); + pWInfo->iTop = sqlite3VdbeCurrentAddr(v); if( db->mallocFailed ) goto whereBeginError; /* Generate the code to do the search. Each iteration of the for @@ -152623,14 +152623,14 @@ SQLITE_PRIVATE WhereInfo *tdsqlite3WhereBegin( if( db->mallocFailed ) goto whereBeginError; } #endif - addrExplain = tdsqlite3WhereExplainOneScan( + addrExplain = sqlite3WhereExplainOneScan( pParse, pTabList, pLevel, wctrlFlags ); - pLevel->addrBody = tdsqlite3VdbeCurrentAddr(v); - notReady = tdsqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady); + pLevel->addrBody = sqlite3VdbeCurrentAddr(v); + notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady); pWInfo->iContinue = pLevel->addrCont; if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){ - tdsqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain); + sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain); } } @@ -152648,7 +152648,7 @@ whereBeginError: } /* -** Part of tdsqlite3WhereEnd() will rewrite opcodes to reference the +** Part of sqlite3WhereEnd() will rewrite opcodes to reference the ** index rather than the main table. In SQLITE_DEBUG mode, we want ** to trace those changes if PRAGMA vdbe_addoptrace=on. This routine ** does that. @@ -152656,29 +152656,29 @@ whereBeginError: #ifndef SQLITE_DEBUG # define OpcodeRewriteTrace(D,K,P) /* no-op */ #else -# define OpcodeRewriteTrace(D,K,P) tdsqlite3WhereOpcodeRewriteTrace(D,K,P) - static void tdsqlite3WhereOpcodeRewriteTrace( - tdsqlite3 *db, +# define OpcodeRewriteTrace(D,K,P) sqlite3WhereOpcodeRewriteTrace(D,K,P) + static void sqlite3WhereOpcodeRewriteTrace( + sqlite3 *db, int pc, VdbeOp *pOp ){ if( (db->flags & SQLITE_VdbeAddopTrace)==0 ) return; - tdsqlite3VdbePrintOp(0, pc, pOp); + sqlite3VdbePrintOp(0, pc, pOp); } #endif /* ** Generate the end of the WHERE loop. See comments on -** tdsqlite3WhereBegin() for additional information. +** sqlite3WhereBegin() for additional information. */ -SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ +SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ Parse *pParse = pWInfo->pParse; Vdbe *v = pParse->pVdbe; int i; WhereLevel *pLevel; WhereLoop *pLoop; SrcList *pTabList = pWInfo->pTabList; - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; /* Generate loop termination code. */ @@ -152702,47 +152702,47 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ int r1 = pParse->nMem+1; int j, op; for(j=0; jiIdxCur, j, r1+j); + sqlite3VdbeAddOp3(v, OP_Column, pLevel->iIdxCur, j, r1+j); } pParse->nMem += n+1; op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT; - addrSeek = tdsqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n); + addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n); VdbeCoverageIf(v, op==OP_SeekLT); VdbeCoverageIf(v, op==OP_SeekGT); - tdsqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); + sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2); } #endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */ /* The common case: Advance to the next row */ - tdsqlite3VdbeResolveLabel(v, pLevel->addrCont); - tdsqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); - tdsqlite3VdbeChangeP5(v, pLevel->p5); + sqlite3VdbeResolveLabel(v, pLevel->addrCont); + sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3); + sqlite3VdbeChangeP5(v, pLevel->p5); VdbeCoverage(v); VdbeCoverageIf(v, pLevel->op==OP_Next); VdbeCoverageIf(v, pLevel->op==OP_Prev); VdbeCoverageIf(v, pLevel->op==OP_VNext); if( pLevel->regBignull ){ - tdsqlite3VdbeResolveLabel(v, pLevel->addrBignull); - tdsqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); + sqlite3VdbeResolveLabel(v, pLevel->addrBignull); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); VdbeCoverage(v); } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT - if( addrSeek ) tdsqlite3VdbeJumpHere(v, addrSeek); + if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); #endif }else{ - tdsqlite3VdbeResolveLabel(v, pLevel->addrCont); + sqlite3VdbeResolveLabel(v, pLevel->addrCont); } if( pLoop->wsFlags & WHERE_IN_ABLE && pLevel->u.in.nIn>0 ){ struct InLoop *pIn; int j; - tdsqlite3VdbeResolveLabel(v, pLevel->addrNxt); + sqlite3VdbeResolveLabel(v, pLevel->addrNxt); for(j=pLevel->u.in.nIn, pIn=&pLevel->u.in.aInLoop[j-1]; j>0; j--, pIn--){ - tdsqlite3VdbeJumpHere(v, pIn->addrInTop+1); + sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ assert( pLoop->wsFlags & WHERE_IN_EARLYOUT ); if( (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 ){ - tdsqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, - tdsqlite3VdbeCurrentAddr(v)+2+(pLevel->iLeftJoin!=0), + sqlite3VdbeAddOp4Int(v, OP_IfNoHope, pLevel->iIdxCur, + sqlite3VdbeCurrentAddr(v)+2+(pLevel->iLeftJoin!=0), pIn->iBase, pIn->nPrefix); VdbeCoverage(v); } @@ -152755,53 +152755,53 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ ** return the null-row. So, if the cursor is not open yet, ** jump over the OP_Next or OP_Prev instruction about to ** be coded. */ - tdsqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, - tdsqlite3VdbeCurrentAddr(v) + 2 + sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, + sqlite3VdbeCurrentAddr(v) + 2 ); VdbeCoverage(v); } } - tdsqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); + sqlite3VdbeAddOp2(v, pIn->eEndLoopOp, pIn->iCur, pIn->addrInTop); VdbeCoverage(v); VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Prev); VdbeCoverageIf(v, pIn->eEndLoopOp==OP_Next); } - tdsqlite3VdbeJumpHere(v, pIn->addrInTop-1); + sqlite3VdbeJumpHere(v, pIn->addrInTop-1); } } - tdsqlite3VdbeResolveLabel(v, pLevel->addrBrk); + sqlite3VdbeResolveLabel(v, pLevel->addrBrk); if( pLevel->addrSkip ){ - tdsqlite3VdbeGoto(v, pLevel->addrSkip); + sqlite3VdbeGoto(v, pLevel->addrSkip); VdbeComment((v, "next skip-scan on %s", pLoop->u.btree.pIndex->zName)); - tdsqlite3VdbeJumpHere(v, pLevel->addrSkip); - tdsqlite3VdbeJumpHere(v, pLevel->addrSkip-2); + sqlite3VdbeJumpHere(v, pLevel->addrSkip); + sqlite3VdbeJumpHere(v, pLevel->addrSkip-2); } #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS if( pLevel->addrLikeRep ){ - tdsqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1), + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, (int)(pLevel->iLikeRepCntr>>1), pLevel->addrLikeRep); VdbeCoverage(v); } #endif if( pLevel->iLeftJoin ){ int ws = pLoop->wsFlags; - addr = tdsqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); + addr = sqlite3VdbeAddOp1(v, OP_IfPos, pLevel->iLeftJoin); VdbeCoverage(v); assert( (ws & WHERE_IDX_ONLY)==0 || (ws & WHERE_INDEXED)!=0 ); if( (ws & WHERE_IDX_ONLY)==0 ){ assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor ); - tdsqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); } if( (ws & WHERE_INDEXED) || ((ws & WHERE_MULTI_OR) && pLevel->u.pCovidx) ){ - tdsqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); + sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iIdxCur); } if( pLevel->op==OP_Return ){ - tdsqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); + sqlite3VdbeAddOp2(v, OP_Gosub, pLevel->p1, pLevel->addrFirst); }else{ - tdsqlite3VdbeGoto(v, pLevel->addrFirst); + sqlite3VdbeGoto(v, pLevel->addrFirst); } - tdsqlite3VdbeJumpHere(v, addr); + sqlite3VdbeJumpHere(v, addr); } VdbeModuleComment((v, "End WHERE-loop%d: %s", i, pWInfo->pTabList->a[pLevel->iFrom].pTab->zName)); @@ -152810,7 +152810,7 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ /* The "break" point is here, just past the end of the outer loop. ** Set it. */ - tdsqlite3VdbeResolveLabel(v, pWInfo->iBreak); + sqlite3VdbeResolveLabel(v, pWInfo->iBreak); assert( pWInfo->nLevel<=pTabList->nSrc ); for(i=0, pLevel=pWInfo->a; inLevel; i++, pLevel++){ @@ -152834,7 +152834,7 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ } #ifdef SQLITE_ENABLE_EARLY_CURSOR_CLOSE - /* Close all of the cursors that were opened by tdsqlite3WhereBegin. + /* Close all of the cursors that were opened by sqlite3WhereBegin. ** Except, do not close cursors that will be reused by the OR optimization ** (WHERE_OR_SUBCLAUSE). And do not close the OP_OpenWrite cursors ** created for the ONEPASS optimization. @@ -152845,13 +152845,13 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ ){ int ws = pLoop->wsFlags; if( pWInfo->eOnePass==ONEPASS_OFF && (ws & WHERE_IDX_ONLY)==0 ){ - tdsqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); + sqlite3VdbeAddOp1(v, OP_Close, pTabItem->iCursor); } if( (ws & WHERE_INDEXED)!=0 && (ws & (WHERE_IPK|WHERE_AUTO_INDEX))==0 && pLevel->iIdxCur!=pWInfo->aiCurOnePass[1] ){ - tdsqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); + sqlite3VdbeAddOp1(v, OP_Close, pLevel->iIdxCur); } } #endif @@ -152861,8 +152861,8 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ ** this optimization prevents the table from ever being read, which can ** yield a significant performance boost. ** - ** Calls to the code generator in between tdsqlite3WhereBegin and - ** tdsqlite3WhereEnd will have created code that references the table + ** Calls to the code generator in between sqlite3WhereBegin and + ** sqlite3WhereEnd will have created code that references the table ** directly. This loop scans all that code looking for opcodes ** that reference the table and converts them into opcodes that ** reference the index. @@ -152876,14 +152876,14 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable)) && !db->mallocFailed ){ - last = tdsqlite3VdbeCurrentAddr(v); + last = sqlite3VdbeCurrentAddr(v); k = pLevel->addrBody; #ifdef SQLITE_DEBUG if( db->flags & SQLITE_VdbeAddopTrace ){ printf("TRANSLATE opcodes in range %d..%d\n", k, last-1); } #endif - pOp = tdsqlite3VdbeGetOp(v, k); + pOp = sqlite3VdbeGetOp(v, k); for(; kp1!=pLevel->iTabCur ) continue; if( pOp->opcode==OP_Column @@ -152894,14 +152894,14 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ int x = pOp->p2; assert( pIdx->pTable==pTab ); if( !HasRowid(pTab) ){ - Index *pPk = tdsqlite3PrimaryKeyIndex(pTab); + Index *pPk = sqlite3PrimaryKeyIndex(pTab); x = pPk->aiColumn[x]; assert( x>=0 ); }else{ - testcase( x!=tdsqlite3StorageColumnToTable(pTab,x) ); - x = tdsqlite3StorageColumnToTable(pTab,x); + testcase( x!=sqlite3StorageColumnToTable(pTab,x) ); + x = sqlite3StorageColumnToTable(pTab,x); } - x = tdsqlite3TableColumnToIndex(pIdx, x); + x = sqlite3TableColumnToIndex(pIdx, x); if( x>=0 ){ pOp->p2 = x; pOp->p1 = pLevel->iIdxCur; @@ -152929,7 +152929,7 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ WhereExprMod *p = pWInfo->pExprMods; pWInfo->pExprMods = p->pNext; memcpy(p->pExpr, &p->orig, sizeof(p->orig)); - tdsqlite3DbFree(db, p); + sqlite3DbFree(db, p); } /* Final cleanup @@ -152962,7 +152962,7 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ ** ** Any SELECT statement that contains one or more window functions in ** either the select list or ORDER BY clause (the only two places window -** functions may be used) is transformed by function tdsqlite3WindowRewrite() +** functions may be used) is transformed by function sqlite3WindowRewrite() ** in order to support window function processing. For example, with the ** schema: ** @@ -153021,12 +153021,12 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ ** INTERFACE WITH SELECT.C ** ** When processing the rewritten SELECT statement, code in select.c calls -** tdsqlite3WhereBegin() to begin iterating through the results of the +** sqlite3WhereBegin() to begin iterating through the results of the ** sub-query, which is always implemented as a co-routine. It then calls -** tdsqlite3WindowCodeStep() to process rows and finish the scan by calling -** tdsqlite3WhereEnd(). +** sqlite3WindowCodeStep() to process rows and finish the scan by calling +** sqlite3WhereEnd(). ** -** tdsqlite3WindowCodeStep() generates VM code so that, for each row returned +** sqlite3WindowCodeStep() generates VM code so that, for each row returned ** by the sub-query a sub-routine (OP_Gosub) coded by select.c is invoked. ** When the sub-routine is invoked: ** @@ -153037,7 +153037,7 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ ** temp table Window.iEphCsr. ** ** In some cases, depending on the window frame and the specific window -** functions invoked, tdsqlite3WindowCodeStep() caches each entire partition +** functions invoked, sqlite3WindowCodeStep() caches each entire partition ** in a temp table before returning any rows. In other cases it does not. ** This detail is encapsulated within this file, the code generated by ** select.c is the same in either case. @@ -153073,7 +153073,7 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ ** ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ** -** See tdsqlite3WindowUpdate() for details. +** See sqlite3WindowUpdate() for details. ** ** As well as some of the built-in window functions, aggregate window ** functions min() and max() are implemented using VDBE instructions if @@ -153088,18 +153088,18 @@ SQLITE_PRIVATE void tdsqlite3WhereEnd(WhereInfo *pWInfo){ ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW */ static void row_numberStepFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ - i64 *p = (i64*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ) (*p)++; UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(apArg); } -static void row_numberValueFunc(tdsqlite3_context *pCtx){ - i64 *p = (i64*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); - tdsqlite3_result_int64(pCtx, (p ? *p : 0)); +static void row_numberValueFunc(sqlite3_context *pCtx){ + i64 *p = (i64*)sqlite3_aggregate_context(pCtx, sizeof(*p)); + sqlite3_result_int64(pCtx, (p ? *p : 0)); } /* @@ -153119,25 +153119,25 @@ struct CallCount { ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW */ static void dense_rankStepFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct CallCount *p; - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ) p->nStep = 1; UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(apArg); } -static void dense_rankValueFunc(tdsqlite3_context *pCtx){ +static void dense_rankValueFunc(sqlite3_context *pCtx){ struct CallCount *p; - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ){ if( p->nStep ){ p->nValue++; p->nStep = 0; } - tdsqlite3_result_int64(pCtx, p->nValue); + sqlite3_result_int64(pCtx, p->nValue); } } @@ -153148,23 +153148,23 @@ static void dense_rankValueFunc(tdsqlite3_context *pCtx){ */ struct NthValueCtx { i64 nStep; - tdsqlite3_value *pValue; + sqlite3_value *pValue; }; static void nth_valueStepFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct NthValueCtx *p; - p = (struct NthValueCtx*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ){ i64 iVal; - switch( tdsqlite3_value_numeric_type(apArg[1]) ){ + switch( sqlite3_value_numeric_type(apArg[1]) ){ case SQLITE_INTEGER: - iVal = tdsqlite3_value_int64(apArg[1]); + iVal = sqlite3_value_int64(apArg[1]); break; case SQLITE_FLOAT: { - double fVal = tdsqlite3_value_double(apArg[1]); + double fVal = sqlite3_value_double(apArg[1]); if( ((i64)fVal)!=fVal ) goto error_out; iVal = (i64)fVal; break; @@ -153176,9 +153176,9 @@ static void nth_valueStepFunc( p->nStep++; if( iVal==p->nStep ){ - p->pValue = tdsqlite3_value_dup(apArg[0]); + p->pValue = sqlite3_value_dup(apArg[0]); if( !p->pValue ){ - tdsqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(pCtx); } } } @@ -153187,16 +153187,16 @@ static void nth_valueStepFunc( return; error_out: - tdsqlite3_result_error( + sqlite3_result_error( pCtx, "second argument to nth_value must be a positive integer", -1 ); } -static void nth_valueFinalizeFunc(tdsqlite3_context *pCtx){ +static void nth_valueFinalizeFunc(sqlite3_context *pCtx){ struct NthValueCtx *p; - p = (struct NthValueCtx*)tdsqlite3_aggregate_context(pCtx, 0); + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0); if( p && p->pValue ){ - tdsqlite3_result_value(pCtx, p->pValue); - tdsqlite3_value_free(p->pValue); + sqlite3_result_value(pCtx, p->pValue); + sqlite3_value_free(p->pValue); p->pValue = 0; } } @@ -153204,27 +153204,27 @@ static void nth_valueFinalizeFunc(tdsqlite3_context *pCtx){ #define nth_valueValueFunc noopValueFunc static void first_valueStepFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct NthValueCtx *p; - p = (struct NthValueCtx*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p && p->pValue==0 ){ - p->pValue = tdsqlite3_value_dup(apArg[0]); + p->pValue = sqlite3_value_dup(apArg[0]); if( !p->pValue ){ - tdsqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(pCtx); } } UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(apArg); } -static void first_valueFinalizeFunc(tdsqlite3_context *pCtx){ +static void first_valueFinalizeFunc(sqlite3_context *pCtx){ struct NthValueCtx *p; - p = (struct NthValueCtx*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p && p->pValue ){ - tdsqlite3_result_value(pCtx, p->pValue); - tdsqlite3_value_free(p->pValue); + sqlite3_result_value(pCtx, p->pValue); + sqlite3_value_free(p->pValue); p->pValue = 0; } } @@ -153238,12 +153238,12 @@ static void first_valueFinalizeFunc(tdsqlite3_context *pCtx){ ** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW */ static void rankStepFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct CallCount *p; - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ){ p->nStep++; if( p->nValue==0 ){ @@ -153253,11 +153253,11 @@ static void rankStepFunc( UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(apArg); } -static void rankValueFunc(tdsqlite3_context *pCtx){ +static void rankValueFunc(sqlite3_context *pCtx){ struct CallCount *p; - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ){ - tdsqlite3_result_int64(pCtx, p->nValue); + sqlite3_result_int64(pCtx, p->nValue); p->nValue = 0; } } @@ -153269,39 +153269,39 @@ static void rankValueFunc(tdsqlite3_context *pCtx){ ** GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING */ static void percent_rankStepFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct CallCount *p; UNUSED_PARAMETER(nArg); assert( nArg==0 ); UNUSED_PARAMETER(apArg); - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ){ p->nTotal++; } } static void percent_rankInvFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct CallCount *p; UNUSED_PARAMETER(nArg); assert( nArg==0 ); UNUSED_PARAMETER(apArg); - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); p->nStep++; } -static void percent_rankValueFunc(tdsqlite3_context *pCtx){ +static void percent_rankValueFunc(sqlite3_context *pCtx){ struct CallCount *p; - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ){ p->nValue = p->nStep; if( p->nTotal>1 ){ double r = (double)p->nValue / (double)(p->nTotal-1); - tdsqlite3_result_double(pCtx, r); + sqlite3_result_double(pCtx, r); }else{ - tdsqlite3_result_double(pCtx, 0.0); + sqlite3_result_double(pCtx, 0.0); } } } @@ -153314,35 +153314,35 @@ static void percent_rankValueFunc(tdsqlite3_context *pCtx){ ** GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING */ static void cume_distStepFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct CallCount *p; UNUSED_PARAMETER(nArg); assert( nArg==0 ); UNUSED_PARAMETER(apArg); - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ){ p->nTotal++; } } static void cume_distInvFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct CallCount *p; UNUSED_PARAMETER(nArg); assert( nArg==0 ); UNUSED_PARAMETER(apArg); - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p)); p->nStep++; } -static void cume_distValueFunc(tdsqlite3_context *pCtx){ +static void cume_distValueFunc(sqlite3_context *pCtx){ struct CallCount *p; - p = (struct CallCount*)tdsqlite3_aggregate_context(pCtx, 0); + p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0); if( p ){ double r = (double)(p->nStep) / (double)(p->nTotal); - tdsqlite3_result_double(pCtx, r); + sqlite3_result_double(pCtx, r); } } #define cume_distFinalizeFunc cume_distValueFunc @@ -153363,18 +153363,18 @@ struct NtileCtx { ** ROWS CURRENT ROW AND UNBOUNDED FOLLOWING */ static void ntileStepFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct NtileCtx *p; assert( nArg==1 ); UNUSED_PARAMETER(nArg); - p = (struct NtileCtx*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p ){ if( p->nTotal==0 ){ - p->nParam = tdsqlite3_value_int64(apArg[0]); + p->nParam = sqlite3_value_int64(apArg[0]); if( p->nParam<=0 ){ - tdsqlite3_result_error( + sqlite3_result_error( pCtx, "argument of ntile must be a positive integer", -1 ); } @@ -153383,23 +153383,23 @@ static void ntileStepFunc( } } static void ntileInvFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct NtileCtx *p; assert( nArg==1 ); UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(apArg); - p = (struct NtileCtx*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); p->iRow++; } -static void ntileValueFunc(tdsqlite3_context *pCtx){ +static void ntileValueFunc(sqlite3_context *pCtx){ struct NtileCtx *p; - p = (struct NtileCtx*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p && p->nParam>0 ){ int nSize = (p->nTotal / p->nParam); if( nSize==0 ){ - tdsqlite3_result_int64(pCtx, p->iRow+1); + sqlite3_result_int64(pCtx, p->iRow+1); }else{ i64 nLarge = p->nTotal - p->nParam*nSize; i64 iSmall = nLarge*(nSize+1); @@ -153408,9 +153408,9 @@ static void ntileValueFunc(tdsqlite3_context *pCtx){ assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal ); if( iRowpVal); - p->pVal = tdsqlite3_value_dup(apArg[0]); + sqlite3_value_free(p->pVal); + p->pVal = sqlite3_value_dup(apArg[0]); if( p->pVal==0 ){ - tdsqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(pCtx); }else{ p->nVal++; } } } static void last_valueInvFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ struct LastValueCtx *p; UNUSED_PARAMETER(nArg); UNUSED_PARAMETER(apArg); - p = (struct LastValueCtx*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( ALWAYS(p) ){ p->nVal--; if( p->nVal==0 ){ - tdsqlite3_value_free(p->pVal); + sqlite3_value_free(p->pVal); p->pVal = 0; } } } -static void last_valueValueFunc(tdsqlite3_context *pCtx){ +static void last_valueValueFunc(sqlite3_context *pCtx){ struct LastValueCtx *p; - p = (struct LastValueCtx*)tdsqlite3_aggregate_context(pCtx, 0); + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, 0); if( p && p->pVal ){ - tdsqlite3_result_value(pCtx, p->pVal); + sqlite3_result_value(pCtx, p->pVal); } } -static void last_valueFinalizeFunc(tdsqlite3_context *pCtx){ +static void last_valueFinalizeFunc(sqlite3_context *pCtx){ struct LastValueCtx *p; - p = (struct LastValueCtx*)tdsqlite3_aggregate_context(pCtx, sizeof(*p)); + p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p)); if( p && p->pVal ){ - tdsqlite3_result_value(pCtx, p->pVal); - tdsqlite3_value_free(p->pVal); + sqlite3_result_value(pCtx, p->pVal); + sqlite3_value_free(p->pVal); p->pVal = 0; } } @@ -153510,16 +153510,16 @@ static const char lagName[] = "lag"; ** invoked. */ static void noopStepFunc( /*NO_TEST*/ - tdsqlite3_context *p, /*NO_TEST*/ + sqlite3_context *p, /*NO_TEST*/ int n, /*NO_TEST*/ - tdsqlite3_value **a /*NO_TEST*/ + sqlite3_value **a /*NO_TEST*/ ){ /*NO_TEST*/ UNUSED_PARAMETER(p); /*NO_TEST*/ UNUSED_PARAMETER(n); /*NO_TEST*/ UNUSED_PARAMETER(a); /*NO_TEST*/ assert(0); /*NO_TEST*/ } /*NO_TEST*/ -static void noopValueFunc(tdsqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } +static void noopValueFunc(sqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ } /* Window functions that use all window interfaces: xStep, xFinal, ** xValue, and xInverse */ @@ -153550,7 +153550,7 @@ static void noopValueFunc(tdsqlite3_context *p){ UNUSED_PARAMETER(p); /*no-op*/ /* ** Register those built-in window functions that are not also aggregates. */ -SQLITE_PRIVATE void tdsqlite3WindowFunctions(void){ +SQLITE_PRIVATE void sqlite3WindowFunctions(void){ static FuncDef aWindowFuncs[] = { WINDOWFUNCX(row_number, 0, 0), WINDOWFUNCX(dense_rank, 0, 0), @@ -153568,16 +153568,16 @@ SQLITE_PRIVATE void tdsqlite3WindowFunctions(void){ WINDOWFUNCNOOP(lag, 2, 0), WINDOWFUNCNOOP(lag, 3, 0), }; - tdsqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs)); + sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs)); } static Window *windowFind(Parse *pParse, Window *pList, const char *zName){ Window *p; for(p=pList; p; p=p->pNextWin){ - if( tdsqlite3StrICmp(p->zName, zName)==0 ) break; + if( sqlite3StrICmp(p->zName, zName)==0 ) break; } if( p==0 ){ - tdsqlite3ErrorMsg(pParse, "no such window: %s", zName); + sqlite3ErrorMsg(pParse, "no such window: %s", zName); } return p; } @@ -153599,7 +153599,7 @@ static Window *windowFind(Parse *pParse, Window *pList, const char *zName){ ** window to be coerced (see "BUILT-IN WINDOW FUNCTIONS" at the top ** of this file), pWin is updated here. */ -SQLITE_PRIVATE void tdsqlite3WindowUpdate( +SQLITE_PRIVATE void sqlite3WindowUpdate( Parse *pParse, Window *pList, /* List of named windows for this SELECT */ Window *pWin, /* Window frame to update */ @@ -153608,29 +153608,29 @@ SQLITE_PRIVATE void tdsqlite3WindowUpdate( if( pWin->zName && pWin->eFrmType==0 ){ Window *p = windowFind(pParse, pList, pWin->zName); if( p==0 ) return; - pWin->pPartition = tdsqlite3ExprListDup(pParse->db, p->pPartition, 0); - pWin->pOrderBy = tdsqlite3ExprListDup(pParse->db, p->pOrderBy, 0); - pWin->pStart = tdsqlite3ExprDup(pParse->db, p->pStart, 0); - pWin->pEnd = tdsqlite3ExprDup(pParse->db, p->pEnd, 0); + pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0); + pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0); + pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0); + pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0); pWin->eStart = p->eStart; pWin->eEnd = p->eEnd; pWin->eFrmType = p->eFrmType; pWin->eExclude = p->eExclude; }else{ - tdsqlite3WindowChain(pParse, pWin, pList); + sqlite3WindowChain(pParse, pWin, pList); } if( (pWin->eFrmType==TK_RANGE) && (pWin->pStart || pWin->pEnd) && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1) ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression" ); }else if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( pWin->pFilter ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "FILTER clause may only be used with aggregate window functions" ); }else{ @@ -153652,15 +153652,15 @@ SQLITE_PRIVATE void tdsqlite3WindowUpdate( int i; for(i=0; izName==aUp[i].zFunc ){ - tdsqlite3ExprDelete(db, pWin->pStart); - tdsqlite3ExprDelete(db, pWin->pEnd); + sqlite3ExprDelete(db, pWin->pStart); + sqlite3ExprDelete(db, pWin->pEnd); pWin->pEnd = pWin->pStart = 0; pWin->eFrmType = aUp[i].eFrmType; pWin->eStart = aUp[i].eStart; pWin->eEnd = aUp[i].eEnd; pWin->eExclude = 0; if( pWin->eStart==TK_FOLLOWING ){ - pWin->pStart = tdsqlite3Expr(db, TK_INTEGER, "1"); + pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1"); } break; } @@ -153671,7 +153671,7 @@ SQLITE_PRIVATE void tdsqlite3WindowUpdate( } /* -** Context object passed through tdsqlite3WalkExprList() to +** Context object passed through sqlite3WalkExprList() to ** selectWindowRewriteExprCb() by selectWindowRewriteEList(). */ typedef struct WindowRewrite WindowRewrite; @@ -153734,21 +153734,21 @@ static int selectWindowRewriteExprCb(Walker *pWalker, Expr *pExpr){ if( p->pSub ){ int i; for(i=0; ipSub->nExpr; i++){ - if( 0==tdsqlite3ExprCompare(0, p->pSub->a[i].pExpr, pExpr, -1) ){ + if( 0==sqlite3ExprCompare(0, p->pSub->a[i].pExpr, pExpr, -1) ){ iCol = i; break; } } } if( iCol<0 ){ - Expr *pDup = tdsqlite3ExprDup(pParse->db, pExpr, 0); + Expr *pDup = sqlite3ExprDup(pParse->db, pExpr, 0); if( pDup && pDup->op==TK_AGG_FUNCTION ) pDup->op = TK_FUNCTION; - p->pSub = tdsqlite3ExprListAppend(pParse, p->pSub, pDup); + p->pSub = sqlite3ExprListAppend(pParse, p->pSub, pDup); } if( p->pSub ){ assert( ExprHasProperty(pExpr, EP_Static)==0 ); ExprSetProperty(pExpr, EP_Static); - tdsqlite3ExprDelete(pParse->db, pExpr); + sqlite3ExprDelete(pParse->db, pExpr); ExprClearProperty(pExpr, EP_Static); memset(pExpr, 0, sizeof(Expr)); @@ -153774,7 +153774,7 @@ static int selectWindowRewriteSelectCb(Walker *pWalker, Select *pSelect){ return WRC_Continue; }else{ p->pSubSelect = pSelect; - tdsqlite3WalkSelect(pWalker, pSelect); + sqlite3WalkSelect(pWalker, pSelect); p->pSubSelect = pSave; } return WRC_Prune; @@ -153819,7 +153819,7 @@ static void selectWindowRewriteEList( sWalker.xSelectCallback = selectWindowRewriteSelectCb; sWalker.u.pRewrite = &sRewrite; - (void)tdsqlite3WalkExprList(&sWalker, pEList); + (void)sqlite3WalkExprList(&sWalker, pEList); *ppSub = sRewrite.pSub; } @@ -153839,14 +153839,14 @@ static ExprList *exprListAppendList( int nInit = pList ? pList->nExpr : 0; for(i=0; inExpr; i++){ int iDummy; - Expr *pDup = tdsqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); + Expr *pDup = sqlite3ExprDup(pParse->db, pAppend->a[i].pExpr, 0); assert( pDup==0 || !ExprHasProperty(pDup, EP_MemToken) ); - if( bIntToNull && pDup && tdsqlite3ExprIsInteger(pDup, &iDummy) ){ + if( bIntToNull && pDup && sqlite3ExprIsInteger(pDup, &iDummy) ){ pDup->op = TK_NULL; pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); pDup->u.zToken = 0; } - pList = tdsqlite3ExprListAppend(pParse, pList, pDup); + pList = sqlite3ExprListAppend(pParse, pList, pDup); if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; } } @@ -153860,11 +153860,11 @@ static ExprList *exprListAppendList( ** are invoked in the correct order as described under "SELECT REWRITING" ** at the top of this file. */ -SQLITE_PRIVATE int tdsqlite3WindowRewrite(Parse *pParse, Select *p){ +SQLITE_PRIVATE int sqlite3WindowRewrite(Parse *pParse, Select *p){ int rc = SQLITE_OK; if( p->pWin && p->pPrior==0 && (p->selFlags & SF_WinRewrite)==0 ){ - Vdbe *v = tdsqlite3GetVdbe(pParse); - tdsqlite3 *db = pParse->db; + Vdbe *v = sqlite3GetVdbe(pParse); + sqlite3 *db = pParse->db; Select *pSub = 0; /* The subquery */ SrcList *pSrc = p->pSrc; Expr *pWhere = p->pWhere; @@ -153877,9 +153877,9 @@ SQLITE_PRIVATE int tdsqlite3WindowRewrite(Parse *pParse, Select *p){ Window *pWin; /* Window object iterator */ Table *pTab; - pTab = tdsqlite3DbMallocZero(db, sizeof(Table)); + pTab = sqlite3DbMallocZero(db, sizeof(Table)); if( pTab==0 ){ - return tdsqlite3ErrorToParser(db, SQLITE_NOMEM); + return sqlite3ErrorToParser(db, SQLITE_NOMEM); } p->pSrc = 0; @@ -153897,8 +153897,8 @@ SQLITE_PRIVATE int tdsqlite3WindowRewrite(Parse *pParse, Select *p){ if( pSort && p->pOrderBy && p->pOrderBy->nExpr<=pSort->nExpr ){ int nSave = pSort->nExpr; pSort->nExpr = p->pOrderBy->nExpr; - if( tdsqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ - tdsqlite3ExprListDelete(db, p->pOrderBy); + if( sqlite3ExprListCompare(pSort, p->pOrderBy, -1)==0 ){ + sqlite3ExprListDelete(db, p->pOrderBy); p->pOrderBy = 0; } pSort->nExpr = nSave; @@ -153935,12 +153935,12 @@ SQLITE_PRIVATE int tdsqlite3WindowRewrite(Parse *pParse, Select *p){ pSublist = exprListAppendList(pParse, pSublist, pArgs, 0); } if( pWin->pFilter ){ - Expr *pFilter = tdsqlite3ExprDup(db, pWin->pFilter, 0); - pSublist = tdsqlite3ExprListAppend(pParse, pSublist, pFilter); + Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); + pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); } pWin->regAccum = ++pParse->nMem; pWin->regResult = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); } /* If there is no ORDER BY or PARTITION BY clause, and the window @@ -153950,21 +153950,21 @@ SQLITE_PRIVATE int tdsqlite3WindowRewrite(Parse *pParse, Select *p){ ** keep everything legal in this case. */ if( pSublist==0 ){ - pSublist = tdsqlite3ExprListAppend(pParse, 0, - tdsqlite3Expr(db, TK_INTEGER, "0") + pSublist = sqlite3ExprListAppend(pParse, 0, + sqlite3Expr(db, TK_INTEGER, "0") ); } - pSub = tdsqlite3SelectNew( + pSub = sqlite3SelectNew( pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0 ); - p->pSrc = tdsqlite3SrcListAppend(pParse, 0, 0, 0); + p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0); if( p->pSrc ){ Table *pTab2; p->pSrc->a[0].pSelect = pSub; - tdsqlite3SrcListAssignCursors(pParse, p->pSrc); + sqlite3SrcListAssignCursors(pParse, p->pSrc); pSub->selFlags |= SF_Expanded; - pTab2 = tdsqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); + pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE); if( pTab2==0 ){ /* Might actually be some other kind of error, but in that case ** pParse->nErr will be set, so if SQLITE_NOMEM is set, we will get @@ -153977,18 +153977,18 @@ SQLITE_PRIVATE int tdsqlite3WindowRewrite(Parse *pParse, Select *p){ pTab = pTab2; } }else{ - tdsqlite3SelectDelete(db, pSub); + sqlite3SelectDelete(db, pSub); } if( db->mallocFailed ) rc = SQLITE_NOMEM; - tdsqlite3DbFree(db, pTab); + sqlite3DbFree(db, pTab); } if( rc ){ if( pParse->nErr==0 ){ assert( pParse->db->mallocFailed ); - tdsqlite3ErrorToParser(pParse->db, SQLITE_NOMEM); + sqlite3ErrorToParser(pParse->db, SQLITE_NOMEM); } - tdsqlite3SelectReset(pParse, p); + sqlite3SelectReset(pParse, p); } return rc; } @@ -153997,7 +153997,7 @@ SQLITE_PRIVATE int tdsqlite3WindowRewrite(Parse *pParse, Select *p){ ** Unlink the Window object from the Select to which it is attached, ** if it is attached. */ -SQLITE_PRIVATE void tdsqlite3WindowUnlinkFromSelect(Window *p){ +SQLITE_PRIVATE void sqlite3WindowUnlinkFromSelect(Window *p){ if( p->ppThis ){ *p->ppThis = p->pNextWin; if( p->pNextWin ) p->pNextWin->ppThis = p->ppThis; @@ -154008,27 +154008,27 @@ SQLITE_PRIVATE void tdsqlite3WindowUnlinkFromSelect(Window *p){ /* ** Free the Window object passed as the second argument. */ -SQLITE_PRIVATE void tdsqlite3WindowDelete(tdsqlite3 *db, Window *p){ +SQLITE_PRIVATE void sqlite3WindowDelete(sqlite3 *db, Window *p){ if( p ){ - tdsqlite3WindowUnlinkFromSelect(p); - tdsqlite3ExprDelete(db, p->pFilter); - tdsqlite3ExprListDelete(db, p->pPartition); - tdsqlite3ExprListDelete(db, p->pOrderBy); - tdsqlite3ExprDelete(db, p->pEnd); - tdsqlite3ExprDelete(db, p->pStart); - tdsqlite3DbFree(db, p->zName); - tdsqlite3DbFree(db, p->zBase); - tdsqlite3DbFree(db, p); + sqlite3WindowUnlinkFromSelect(p); + sqlite3ExprDelete(db, p->pFilter); + sqlite3ExprListDelete(db, p->pPartition); + sqlite3ExprListDelete(db, p->pOrderBy); + sqlite3ExprDelete(db, p->pEnd); + sqlite3ExprDelete(db, p->pStart); + sqlite3DbFree(db, p->zName); + sqlite3DbFree(db, p->zBase); + sqlite3DbFree(db, p); } } /* ** Free the linked list of Window objects starting at the second argument. */ -SQLITE_PRIVATE void tdsqlite3WindowListDelete(tdsqlite3 *db, Window *p){ +SQLITE_PRIVATE void sqlite3WindowListDelete(sqlite3 *db, Window *p){ while( p ){ Window *pNext = p->pNextWin; - tdsqlite3WindowDelete(db, p); + sqlite3WindowDelete(db, p); p = pNext; } } @@ -154040,11 +154040,11 @@ SQLITE_PRIVATE void tdsqlite3WindowListDelete(tdsqlite3 *db, Window *p){ ** integer will be caught later. But it is important not to leave ** variable values in the expression tree. */ -static Expr *tdsqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ - if( 0==tdsqlite3ExprIsConstant(pExpr) ){ - if( IN_RENAME_OBJECT ) tdsqlite3RenameExprUnmap(pParse, pExpr); - tdsqlite3ExprDelete(pParse->db, pExpr); - pExpr = tdsqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); +static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ + if( 0==sqlite3ExprIsConstant(pExpr) ){ + if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr); + sqlite3ExprDelete(pParse->db, pExpr); + pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0); } return pExpr; } @@ -154052,7 +154052,7 @@ static Expr *tdsqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){ /* ** Allocate and return a new Window object describing a Window Definition. */ -SQLITE_PRIVATE Window *tdsqlite3WindowAlloc( +SQLITE_PRIVATE Window *sqlite3WindowAlloc( Parse *pParse, /* Parsing context */ int eType, /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */ int eStart, /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */ @@ -154095,11 +154095,11 @@ SQLITE_PRIVATE Window *tdsqlite3WindowAlloc( if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING) || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT)) ){ - tdsqlite3ErrorMsg(pParse, "unsupported frame specification"); + sqlite3ErrorMsg(pParse, "unsupported frame specification"); goto windowAllocErr; } - pWin = (Window*)tdsqlite3DbMallocZero(pParse->db, sizeof(Window)); + pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( pWin==0 ) goto windowAllocErr; pWin->eFrmType = eType; pWin->eStart = eStart; @@ -154109,13 +154109,13 @@ SQLITE_PRIVATE Window *tdsqlite3WindowAlloc( } pWin->eExclude = eExclude; pWin->bImplicitFrame = bImplicitFrame; - pWin->pEnd = tdsqlite3WindowOffsetExpr(pParse, pEnd); - pWin->pStart = tdsqlite3WindowOffsetExpr(pParse, pStart); + pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd); + pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart); return pWin; windowAllocErr: - tdsqlite3ExprDelete(pParse->db, pEnd); - tdsqlite3ExprDelete(pParse->db, pStart); + sqlite3ExprDelete(pParse->db, pEnd); + sqlite3ExprDelete(pParse->db, pStart); return 0; } @@ -154124,7 +154124,7 @@ windowAllocErr: ** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the ** equivalent nul-terminated string. */ -SQLITE_PRIVATE Window *tdsqlite3WindowAssemble( +SQLITE_PRIVATE Window *sqlite3WindowAssemble( Parse *pParse, Window *pWin, ExprList *pPartition, @@ -154135,11 +154135,11 @@ SQLITE_PRIVATE Window *tdsqlite3WindowAssemble( pWin->pPartition = pPartition; pWin->pOrderBy = pOrderBy; if( pBase ){ - pWin->zBase = tdsqlite3DbStrNDup(pParse->db, pBase->z, pBase->n); + pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n); } }else{ - tdsqlite3ExprListDelete(pParse->db, pPartition); - tdsqlite3ExprListDelete(pParse->db, pOrderBy); + sqlite3ExprListDelete(pParse->db, pPartition); + sqlite3ExprListDelete(pParse->db, pOrderBy); } return pWin; } @@ -154151,9 +154151,9 @@ SQLITE_PRIVATE Window *tdsqlite3WindowAssemble( ** either updates *pWin according to the base specification, or else ** leaves an error in pParse. */ -SQLITE_PRIVATE void tdsqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){ +SQLITE_PRIVATE void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){ if( pWin->zBase ){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; Window *pExist = windowFind(pParse, pList, pWin->zBase); if( pExist ){ const char *zErr = 0; @@ -154166,16 +154166,16 @@ SQLITE_PRIVATE void tdsqlite3WindowChain(Parse *pParse, Window *pWin, Window *pL zErr = "frame specification"; } if( zErr ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "cannot override %s of window: %s", zErr, pWin->zBase ); }else{ - pWin->pPartition = tdsqlite3ExprListDup(db, pExist->pPartition, 0); + pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0); if( pExist->pOrderBy ){ assert( pWin->pOrderBy==0 ); - pWin->pOrderBy = tdsqlite3ExprListDup(db, pExist->pOrderBy, 0); + pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0); } - tdsqlite3DbFree(db, pWin->zBase); + sqlite3DbFree(db, pWin->zBase); pWin->zBase = 0; } } @@ -154185,7 +154185,7 @@ SQLITE_PRIVATE void tdsqlite3WindowChain(Parse *pParse, Window *pWin, Window *pL /* ** Attach window object pWin to expression p. */ -SQLITE_PRIVATE void tdsqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ +SQLITE_PRIVATE void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ if( p ){ assert( p->op==TK_FUNCTION ); assert( pWin ); @@ -154193,12 +154193,12 @@ SQLITE_PRIVATE void tdsqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ ExprSetProperty(p, EP_WinFunc); pWin->pOwner = p; if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){ - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "DISTINCT is not supported for window functions" ); } }else{ - tdsqlite3WindowDelete(pParse->db, pWin); + sqlite3WindowDelete(pParse->db, pWin); } } @@ -154208,9 +154208,9 @@ SQLITE_PRIVATE void tdsqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ ** in if either (a) there are no other windows already linked to this ** SELECT, or (b) the windows already linked use a compatible window frame. */ -SQLITE_PRIVATE void tdsqlite3WindowLink(Select *pSel, Window *pWin){ +SQLITE_PRIVATE void sqlite3WindowLink(Select *pSel, Window *pWin){ if( pSel!=0 - && (0==pSel->pWin || 0==tdsqlite3WindowCompare(0, pSel->pWin, pWin, 0)) + && (0==pSel->pWin || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0)) ){ pWin->pNextWin = pSel->pWin; if( pSel->pWin ){ @@ -154226,23 +154226,23 @@ SQLITE_PRIVATE void tdsqlite3WindowLink(Select *pSel, Window *pWin){ ** different, or 2 if it cannot be determined if the objects are identical ** or not. Identical window objects can be processed in a single scan. */ -SQLITE_PRIVATE int tdsqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){ +SQLITE_PRIVATE int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){ int res; if( NEVER(p1==0) || NEVER(p2==0) ) return 1; if( p1->eFrmType!=p2->eFrmType ) return 1; if( p1->eStart!=p2->eStart ) return 1; if( p1->eEnd!=p2->eEnd ) return 1; if( p1->eExclude!=p2->eExclude ) return 1; - if( tdsqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1; - if( tdsqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1; - if( (res = tdsqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1)) ){ + if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1; + if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1; + if( (res = sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1)) ){ return res; } - if( (res = tdsqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1)) ){ + if( (res = sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1)) ){ return res; } if( bFilter ){ - if( (res = tdsqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1)) ){ + if( (res = sqlite3ExprCompare(pParse, p1->pFilter, p2->pFilter, -1)) ){ return res; } } @@ -154251,20 +154251,20 @@ SQLITE_PRIVATE int tdsqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, /* -** This is called by code in select.c before it calls tdsqlite3WhereBegin() +** This is called by code in select.c before it calls sqlite3WhereBegin() ** to begin iterating through the sub-query results. It is used to allocate -** and initialize registers and cursors used by tdsqlite3WindowCodeStep(). +** and initialize registers and cursors used by sqlite3WindowCodeStep(). */ -SQLITE_PRIVATE void tdsqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ +SQLITE_PRIVATE void sqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ int nEphExpr = pSelect->pSrc->a[0].pSelect->pEList->nExpr; Window *pMWin = pSelect->pWin; Window *pWin; - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); - tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); - tdsqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); - tdsqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr); - tdsqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, nEphExpr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr); /* Allocate registers to use for PARTITION BY values, if any. Initialize ** said registers to NULL. */ @@ -154272,19 +154272,19 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ int nExpr = pMWin->pPartition->nExpr; pMWin->regPart = pParse->nMem+1; pParse->nMem += nExpr; - tdsqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1); + sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1); } pMWin->regOne = ++pParse->nMem; - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne); if( pMWin->eExclude ){ pMWin->regStartRowid = ++pParse->nMem; pMWin->regEndRowid = ++pParse->nMem; pMWin->csrApp = pParse->nTab++; - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid); - tdsqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid); + sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr); return; } @@ -154299,7 +154299,7 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ ** regApp+2: output of MakeRecord */ ExprList *pList = pWin->pOwner->x.pList; - KeyInfo *pKeyInfo = tdsqlite3KeyInfoFromExprList(pParse, pList, 0, 0); + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pList, 0, 0); pWin->csrApp = pParse->nTab++; pWin->regApp = pParse->nMem+1; pParse->nMem += 3; @@ -154307,9 +154307,9 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ assert( pKeyInfo->aSortFlags[0]==0 ); pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC; } - tdsqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); - tdsqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); + sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); } else if( p->zName==nth_valueName || p->zName==first_valueName ){ /* Allocate two registers at pWin->regApp. These will be used to @@ -154317,11 +154317,11 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeInit(Parse *pParse, Select *pSelect){ pWin->regApp = pParse->nMem+1; pWin->csrApp = pParse->nTab++; pParse->nMem += 2; - tdsqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); } else if( p->zName==leadName || p->zName==lagName ){ pWin->csrApp = pParse->nTab++; - tdsqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); + sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr); } } } @@ -154348,37 +154348,37 @@ static void windowCheckValue(Parse *pParse, int reg, int eCond){ "frame ending offset must be a non-negative number", }; static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge }; - Vdbe *v = tdsqlite3GetVdbe(pParse); - int regZero = tdsqlite3GetTempReg(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); + int regZero = sqlite3GetTempReg(pParse); assert( eCond>=0 && eCond=WINDOW_STARTING_NUM ){ - int regString = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); - tdsqlite3VdbeAddOp3(v, OP_Ge, regString, tdsqlite3VdbeCurrentAddr(v)+2, reg); - tdsqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL); + int regString = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); + sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg); + sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL); VdbeCoverage(v); assert( eCond==3 || eCond==4 ); VdbeCoverageIf(v, eCond==3); VdbeCoverageIf(v, eCond==4); }else{ - tdsqlite3VdbeAddOp2(v, OP_MustBeInt, reg, tdsqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); assert( eCond==0 || eCond==1 || eCond==2 ); VdbeCoverageIf(v, eCond==0); VdbeCoverageIf(v, eCond==1); VdbeCoverageIf(v, eCond==2); } - tdsqlite3VdbeAddOp3(v, aOp[eCond], regZero, tdsqlite3VdbeCurrentAddr(v)+2, reg); + sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg); VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */ VdbeCoverageNeverNullIf(v, eCond==1); /* the OP_MustBeInt */ VdbeCoverageNeverNullIf(v, eCond==2); VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */ VdbeCoverageNeverNullIf(v, eCond==4); /* the OP_Ge */ - tdsqlite3MayAbort(pParse); - tdsqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort); - tdsqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC); - tdsqlite3ReleaseTempReg(pParse, regZero); + sqlite3MayAbort(pParse); + sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort); + sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC); + sqlite3ReleaseTempReg(pParse, regZero); } /* @@ -154403,7 +154403,7 @@ struct WindowCsrAndReg { /* ** A single instance of this structure is allocated on the stack by -** tdsqlite3WindowCodeStep() and a pointer to it passed to the various helper +** sqlite3WindowCodeStep() and a pointer to it passed to the various helper ** routines. This is to reduce the number of arguments required by each ** helper function. ** @@ -154482,12 +154482,12 @@ static void windowReadPeerValues( Window *pMWin = p->pMWin; ExprList *pOrderBy = pMWin->pOrderBy; if( pOrderBy ){ - Vdbe *v = tdsqlite3GetVdbe(p->pParse); + Vdbe *v = sqlite3GetVdbe(p->pParse); ExprList *pPart = pMWin->pPartition; int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0); int i; for(i=0; inExpr; i++){ - tdsqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i); + sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i); } } } @@ -154519,7 +154519,7 @@ static void windowAggStep( int reg /* Array of registers */ ){ Parse *pParse = p->pParse; - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ FuncDef *pFunc = pWin->pFunc; @@ -154531,13 +154531,13 @@ static void windowAggStep( /* All OVER clauses in the same window function aggregate step must ** be the same. */ - assert( pWin==pMWin || tdsqlite3WindowCompare(pParse,pWin,pMWin,0)!=1 ); + assert( pWin==pMWin || sqlite3WindowCompare(pParse,pWin,pMWin,0)!=1 ); for(i=0; izName!=nth_valueName ){ - tdsqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i); }else{ - tdsqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i); + sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i); } } regArg = reg; @@ -154546,49 +154546,49 @@ static void windowAggStep( && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) ){ - int addrIsNull = tdsqlite3VdbeAddOp1(v, OP_IsNull, regArg); + int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg); VdbeCoverage(v); if( bInverse==0 ){ - tdsqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1); - tdsqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp); - tdsqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2); - tdsqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2); + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1); + sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp); + sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2); + sqlite3VdbeAddOp2(v, OP_IdxInsert, pWin->csrApp, pWin->regApp+2); }else{ - tdsqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1); + sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1); VdbeCoverageNeverTaken(v); - tdsqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp); - tdsqlite3VdbeJumpHere(v, tdsqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); } - tdsqlite3VdbeJumpHere(v, addrIsNull); + sqlite3VdbeJumpHere(v, addrIsNull); }else if( pWin->regApp ){ assert( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ); assert( bInverse==0 || bInverse==1 ); - tdsqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1); }else if( pFunc->xSFunc!=noopStepFunc ){ int addrIf = 0; if( pWin->pFilter ){ int regTmp; assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); - regTmp = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); - addrIf = tdsqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); + regTmp = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); + addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); VdbeCoverage(v); - tdsqlite3ReleaseTempReg(pParse, regTmp); + sqlite3ReleaseTempReg(pParse, regTmp); } if( pWin->bExprArgs ){ - int iStart = tdsqlite3VdbeCurrentAddr(v); + int iStart = sqlite3VdbeCurrentAddr(v); VdbeOp *pOp, *pEnd; nArg = pWin->pOwner->x.pList->nExpr; - regArg = tdsqlite3GetTempRange(pParse, nArg); - tdsqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); + regArg = sqlite3GetTempRange(pParse, nArg); + sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); - pEnd = tdsqlite3VdbeGetOp(v, -1); - for(pOp=tdsqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){ + pEnd = sqlite3VdbeGetOp(v, -1); + for(pOp=sqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){ if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){ pOp->p1 = csr; } @@ -154597,17 +154597,17 @@ static void windowAggStep( if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ CollSeq *pColl; assert( nArg>0 ); - pColl = tdsqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); - tdsqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); + pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); + sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); } - tdsqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, + sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); - tdsqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); - tdsqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); if( pWin->bExprArgs ){ - tdsqlite3ReleaseTempRange(pParse, regArg, nArg); + sqlite3ReleaseTempRange(pParse, regArg, nArg); } - if( addrIf ) tdsqlite3VdbeJumpHere(v, addrIf); + if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } } } @@ -154628,7 +154628,7 @@ static void windowAggStep( static void windowAggFinal(WindowCodeArg *p, int bFin){ Parse *pParse = p->pParse; Window *pMWin = p->pMWin; - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ @@ -154636,23 +154636,23 @@ static void windowAggFinal(WindowCodeArg *p, int bFin){ && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) ){ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); - tdsqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult); - tdsqlite3VdbeJumpHere(v, tdsqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); }else if( pWin->regApp ){ assert( pMWin->regStartRowid==0 ); }else{ int nArg = windowArgCount(pWin); if( bFin ){ - tdsqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg); - tdsqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); - tdsqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult); - tdsqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); + sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); }else{ - tdsqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult); - tdsqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); + sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult); + sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF); } } } @@ -154687,32 +154687,32 @@ static void windowFullScan(WindowCodeArg *p){ csr = pMWin->csrApp; nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); - lblNext = tdsqlite3VdbeMakeLabel(pParse); - lblBrk = tdsqlite3VdbeMakeLabel(pParse); + lblNext = sqlite3VdbeMakeLabel(pParse); + lblBrk = sqlite3VdbeMakeLabel(pParse); - regCRowid = tdsqlite3GetTempReg(pParse); - regRowid = tdsqlite3GetTempReg(pParse); + regCRowid = sqlite3GetTempReg(pParse); + regRowid = sqlite3GetTempReg(pParse); if( nPeer ){ - regCPeer = tdsqlite3GetTempRange(pParse, nPeer); - regPeer = tdsqlite3GetTempRange(pParse, nPeer); + regCPeer = sqlite3GetTempRange(pParse, nPeer); + regPeer = sqlite3GetTempRange(pParse, nPeer); } - tdsqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid); + sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid); windowReadPeerValues(p, pMWin->iEphCsr, regCPeer); for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); } - tdsqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid); + sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid); VdbeCoverage(v); - addrNext = tdsqlite3VdbeCurrentAddr(v); - tdsqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid); - tdsqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid); + addrNext = sqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid); + sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid); VdbeCoverageNeverNull(v); if( pMWin->eExclude==TK_CURRENT ){ - tdsqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid); + sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid); VdbeCoverageNeverNull(v); }else if( pMWin->eExclude!=TK_NO ){ int addr; @@ -154720,37 +154720,37 @@ static void windowFullScan(WindowCodeArg *p){ KeyInfo *pKeyInfo = 0; if( pMWin->pOrderBy ){ - pKeyInfo = tdsqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0); + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0); } if( pMWin->eExclude==TK_TIES ){ - addrEq = tdsqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid); + addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid); VdbeCoverageNeverNull(v); } if( pKeyInfo ){ windowReadPeerValues(p, csr, regPeer); - tdsqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer); - tdsqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); - addr = tdsqlite3VdbeCurrentAddr(v)+1; - tdsqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr); + sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + addr = sqlite3VdbeCurrentAddr(v)+1; + sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr); VdbeCoverageEqNe(v); }else{ - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext); } - if( addrEq ) tdsqlite3VdbeJumpHere(v, addrEq); + if( addrEq ) sqlite3VdbeJumpHere(v, addrEq); } windowAggStep(p, pMWin, csr, 0, p->regArg); - tdsqlite3VdbeResolveLabel(v, lblNext); - tdsqlite3VdbeAddOp2(v, OP_Next, csr, addrNext); + sqlite3VdbeResolveLabel(v, lblNext); + sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext); VdbeCoverage(v); - tdsqlite3VdbeJumpHere(v, addrNext-1); - tdsqlite3VdbeJumpHere(v, addrNext+1); - tdsqlite3ReleaseTempReg(pParse, regRowid); - tdsqlite3ReleaseTempReg(pParse, regCRowid); + sqlite3VdbeJumpHere(v, addrNext-1); + sqlite3VdbeJumpHere(v, addrNext+1); + sqlite3ReleaseTempReg(pParse, regRowid); + sqlite3ReleaseTempReg(pParse, regCRowid); if( nPeer ){ - tdsqlite3ReleaseTempRange(pParse, regPeer, nPeer); - tdsqlite3ReleaseTempRange(pParse, regCPeer, nPeer); + sqlite3ReleaseTempRange(pParse, regPeer, nPeer); + sqlite3ReleaseTempRange(pParse, regCPeer, nPeer); } windowAggFinal(p, 1); @@ -154786,58 +154786,58 @@ static void windowReturnOneRow(WindowCodeArg *p){ || pFunc->zName==first_valueName ){ int csr = pWin->csrApp; - int lbl = tdsqlite3VdbeMakeLabel(pParse); - int tmpReg = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + int lbl = sqlite3VdbeMakeLabel(pParse); + int tmpReg = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); if( pFunc->zName==nth_valueName ){ - tdsqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg); + sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg); windowCheckValue(pParse, tmpReg, 2); }else{ - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg); + sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg); } - tdsqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg); - tdsqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg); + sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg); + sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg); VdbeCoverageNeverNull(v); - tdsqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg); + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg); VdbeCoverageNeverTaken(v); - tdsqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); - tdsqlite3VdbeResolveLabel(v, lbl); - tdsqlite3ReleaseTempReg(pParse, tmpReg); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); } else if( pFunc->zName==leadName || pFunc->zName==lagName ){ int nArg = pWin->pOwner->x.pList->nExpr; int csr = pWin->csrApp; - int lbl = tdsqlite3VdbeMakeLabel(pParse); - int tmpReg = tdsqlite3GetTempReg(pParse); + int lbl = sqlite3VdbeMakeLabel(pParse); + int tmpReg = sqlite3GetTempReg(pParse); int iEph = pMWin->iEphCsr; if( nArg<3 ){ - tdsqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); }else{ - tdsqlite3VdbeAddOp3(v, OP_Column, iEph,pWin->iArgCol+2,pWin->regResult); + sqlite3VdbeAddOp3(v, OP_Column, iEph,pWin->iArgCol+2,pWin->regResult); } - tdsqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg); + sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg); if( nArg<2 ){ int val = (pFunc->zName==leadName ? 1 : -1); - tdsqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val); + sqlite3VdbeAddOp2(v, OP_AddImm, tmpReg, val); }else{ int op = (pFunc->zName==leadName ? OP_Add : OP_Subtract); - int tmpReg2 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2); - tdsqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg); - tdsqlite3ReleaseTempReg(pParse, tmpReg2); + int tmpReg2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+1, tmpReg2); + sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg); + sqlite3ReleaseTempReg(pParse, tmpReg2); } - tdsqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg); + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); - tdsqlite3VdbeResolveLabel(v, lbl); - tdsqlite3ReleaseTempReg(pParse, tmpReg); + sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); + sqlite3VdbeResolveLabel(v, lbl); + sqlite3ReleaseTempReg(pParse, tmpReg); } } } - tdsqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub); + sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub); } /* @@ -154847,24 +154847,24 @@ static void windowReturnOneRow(WindowCodeArg *p){ ** in the list. */ static int windowInitAccum(Parse *pParse, Window *pMWin){ - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); int regArg; int nArg = 0; Window *pWin; for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ FuncDef *pFunc = pWin->pFunc; - tdsqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); + sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum); nArg = MAX(nArg, windowArgCount(pWin)); if( pMWin->regStartRowid==0 ){ if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){ - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); } if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){ assert( pWin->eStart!=TK_UNBOUNDED ); - tdsqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); + sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1); } } } @@ -154910,19 +154910,19 @@ static void windowIfNewPeer( int regOld, /* First in array of old values */ int addr /* Jump here */ ){ - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); if( pOrderBy ){ int nVal = pOrderBy->nExpr; - KeyInfo *pKeyInfo = tdsqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); - tdsqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal); - tdsqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); - tdsqlite3VdbeAddOp3(v, OP_Jump, - tdsqlite3VdbeCurrentAddr(v)+1, addr, tdsqlite3VdbeCurrentAddr(v)+1 + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); + sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, + sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1 ); VdbeCoverageEqNe(v); - tdsqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1); + sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1); }else{ - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); } } @@ -154958,10 +154958,10 @@ static void windowCodeRangeTest( int lbl /* Jump destination if condition is true */ ){ Parse *pParse = p->pParse; - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */ - int reg1 = tdsqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */ - int reg2 = tdsqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */ + int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */ + int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */ int regString = ++pParse->nMem; /* Reg. for constant value '' */ int arith = OP_Add; /* OP_Add or OP_Subtract */ int addrGe; /* Jump destination */ @@ -154999,11 +154999,11 @@ static void windowCodeRangeTest( ** the add/subtract is skipped for these, as required. If reg1 is a NULL, ** then the arithmetic is performed, but since adding or subtracting from ** NULL is always NULL anyway, this case is handled as required too. */ - tdsqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); - addrGe = tdsqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); + sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); + addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); VdbeCoverage(v); - tdsqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); - tdsqlite3VdbeJumpHere(v, addrGe); + sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); + sqlite3VdbeJumpHere(v, addrGe); /* If the BIGNULL flag is set for the ORDER BY, then it is required to ** consider NULL values to be larger than all other values, instead of @@ -155026,52 +155026,52 @@ static void windowCodeRangeTest( ** block. */ if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){ /* This block runs if reg1 contains a NULL. */ - int addr = tdsqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); + int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); switch( op ){ case OP_Ge: - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break; case OP_Gt: - tdsqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); + sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); VdbeCoverage(v); break; case OP_Le: - tdsqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); break; default: assert( op==OP_Lt ); /* no-op */ break; } - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, tdsqlite3VdbeCurrentAddr(v)+3); + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); /* This block runs if reg1 is not NULL, but reg2 is. */ - tdsqlite3VdbeJumpHere(v, addr); - tdsqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); if( op==OP_Gt || op==OP_Ge ){ - tdsqlite3VdbeChangeP2(v, -1, tdsqlite3VdbeCurrentAddr(v)+1); + sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1); } } /* Compare registers reg2 and reg1, taking the jump if required. Note that ** control skips over this test if the BIGNULL flag is set and either ** reg1 or reg2 contain a NULL value. */ - tdsqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); - tdsqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); + sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge); testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt); testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le); testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt); - tdsqlite3ReleaseTempReg(pParse, reg1); - tdsqlite3ReleaseTempReg(pParse, reg2); + sqlite3ReleaseTempReg(pParse, reg1); + sqlite3ReleaseTempReg(pParse, reg2); VdbeModuleComment((v, "CodeRangeTest: end")); } /* -** Helper function for tdsqlite3WindowCodeStep(). Each call to this function +** Helper function for sqlite3WindowCodeStep(). Each call to this function ** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE -** operation. Refer to the header comment for tdsqlite3WindowCodeStep() for +** operation. Refer to the header comment for sqlite3WindowCodeStep() for ** details. */ static int windowCodeOp( @@ -155088,7 +155088,7 @@ static int windowCodeOp( int addrContinue = 0; int bPeer = (pMWin->eFrmType!=TK_ROWS); - int lblDone = tdsqlite3VdbeMakeLabel(pParse); + int lblDone = sqlite3VdbeMakeLabel(pParse); int addrNextRange = 0; /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame @@ -155100,7 +155100,7 @@ static int windowCodeOp( if( regCountdown>0 ){ if( pMWin->eFrmType==TK_RANGE ){ - addrNextRange = tdsqlite3VdbeCurrentAddr(v); + addrNextRange = sqlite3VdbeCurrentAddr(v); assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP ); if( op==WINDOW_AGGINVERSE ){ if( pMWin->eStart==TK_FOLLOWING ){ @@ -155118,7 +155118,7 @@ static int windowCodeOp( ); } }else{ - tdsqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, lblDone, 1); + sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, lblDone, 1); VdbeCoverage(v); } } @@ -155126,7 +155126,7 @@ static int windowCodeOp( if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){ windowAggFinal(p, 0); } - addrContinue = tdsqlite3VdbeCurrentAddr(v); + addrContinue = sqlite3VdbeCurrentAddr(v); /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the @@ -155135,14 +155135,14 @@ static int windowCodeOp( if( pMWin->eStart==pMWin->eEnd && regCountdown && pMWin->eFrmType==TK_RANGE && op==WINDOW_AGGINVERSE ){ - int regRowid1 = tdsqlite3GetTempReg(pParse); - int regRowid2 = tdsqlite3GetTempReg(pParse); - tdsqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1); - tdsqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2); - tdsqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1); + int regRowid1 = sqlite3GetTempReg(pParse); + int regRowid2 = sqlite3GetTempReg(pParse); + sqlite3VdbeAddOp2(v, OP_Rowid, p->start.csr, regRowid1); + sqlite3VdbeAddOp2(v, OP_Rowid, p->end.csr, regRowid2); + sqlite3VdbeAddOp3(v, OP_Ge, regRowid2, lblDone, regRowid1); VdbeCoverage(v); - tdsqlite3ReleaseTempReg(pParse, regRowid1); - tdsqlite3ReleaseTempReg(pParse, regRowid2); + sqlite3ReleaseTempReg(pParse, regRowid1); + sqlite3ReleaseTempReg(pParse, regRowid2); assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ); } @@ -155158,7 +155158,7 @@ static int windowCodeOp( reg = p->start.reg; if( pMWin->regStartRowid ){ assert( pMWin->regEndRowid ); - tdsqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1); }else{ windowAggStep(p, pMWin, csr, 1, p->regArg); } @@ -155170,7 +155170,7 @@ static int windowCodeOp( reg = p->end.reg; if( pMWin->regStartRowid ){ assert( pMWin->regEndRowid ); - tdsqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1); + sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1); }else{ windowAggStep(p, pMWin, csr, 0, p->regArg); } @@ -155178,34 +155178,34 @@ static int windowCodeOp( } if( op==p->eDelete ){ - tdsqlite3VdbeAddOp1(v, OP_Delete, csr); - tdsqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); + sqlite3VdbeAddOp1(v, OP_Delete, csr); + sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION); } if( jumpOnEof ){ - tdsqlite3VdbeAddOp2(v, OP_Next, csr, tdsqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2); VdbeCoverage(v); - ret = tdsqlite3VdbeAddOp0(v, OP_Goto); + ret = sqlite3VdbeAddOp0(v, OP_Goto); }else{ - tdsqlite3VdbeAddOp2(v, OP_Next, csr, tdsqlite3VdbeCurrentAddr(v)+1+bPeer); + sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer); VdbeCoverage(v); if( bPeer ){ - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, lblDone); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblDone); } } if( bPeer ){ int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0); - int regTmp = (nReg ? tdsqlite3GetTempRange(pParse, nReg) : 0); + int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0); windowReadPeerValues(p, csr, regTmp); windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue); - tdsqlite3ReleaseTempRange(pParse, regTmp, nReg); + sqlite3ReleaseTempRange(pParse, regTmp, nReg); } if( addrNextRange ){ - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange); } - tdsqlite3VdbeResolveLabel(v, lblDone); + sqlite3VdbeResolveLabel(v, lblDone); return ret; } @@ -155215,24 +155215,24 @@ static int windowCodeOp( ** third argument. Set the Window.pOwner field of the new object to ** pOwner. */ -SQLITE_PRIVATE Window *tdsqlite3WindowDup(tdsqlite3 *db, Expr *pOwner, Window *p){ +SQLITE_PRIVATE Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ Window *pNew = 0; if( ALWAYS(p) ){ - pNew = tdsqlite3DbMallocZero(db, sizeof(Window)); + pNew = sqlite3DbMallocZero(db, sizeof(Window)); if( pNew ){ - pNew->zName = tdsqlite3DbStrDup(db, p->zName); - pNew->zBase = tdsqlite3DbStrDup(db, p->zBase); - pNew->pFilter = tdsqlite3ExprDup(db, p->pFilter, 0); + pNew->zName = sqlite3DbStrDup(db, p->zName); + pNew->zBase = sqlite3DbStrDup(db, p->zBase); + pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); pNew->pFunc = p->pFunc; - pNew->pPartition = tdsqlite3ExprListDup(db, p->pPartition, 0); - pNew->pOrderBy = tdsqlite3ExprListDup(db, p->pOrderBy, 0); + pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); + pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0); pNew->eFrmType = p->eFrmType; pNew->eEnd = p->eEnd; pNew->eStart = p->eStart; pNew->eExclude = p->eExclude; pNew->regResult = p->regResult; - pNew->pStart = tdsqlite3ExprDup(db, p->pStart, 0); - pNew->pEnd = tdsqlite3ExprDup(db, p->pEnd, 0); + pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); + pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); pNew->pOwner = pOwner; pNew->bImplicitFrame = p->bImplicitFrame; } @@ -155244,13 +155244,13 @@ SQLITE_PRIVATE Window *tdsqlite3WindowDup(tdsqlite3 *db, Expr *pOwner, Window *p ** Return a copy of the linked list of Window objects passed as the ** second argument. */ -SQLITE_PRIVATE Window *tdsqlite3WindowListDup(tdsqlite3 *db, Window *p){ +SQLITE_PRIVATE Window *sqlite3WindowListDup(sqlite3 *db, Window *p){ Window *pWin; Window *pRet = 0; Window **pp = &pRet; for(pWin=p; pWin; pWin=pWin->pNextWin){ - *pp = tdsqlite3WindowDup(db, 0, pWin); + *pp = sqlite3WindowDup(db, 0, pWin); if( *pp==0 ) break; pp = &((*pp)->pNextWin); } @@ -155268,22 +155268,22 @@ SQLITE_PRIVATE Window *tdsqlite3WindowListDup(tdsqlite3 *db, Window *p){ */ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ int ret = 0; - tdsqlite3 *db = pParse->db; - tdsqlite3_value *pVal = 0; - tdsqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal); - if( pVal && tdsqlite3_value_int(pVal)>0 ){ + sqlite3 *db = pParse->db; + sqlite3_value *pVal = 0; + sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal); + if( pVal && sqlite3_value_int(pVal)>0 ){ ret = 1; } - tdsqlite3ValueFree(pVal); + sqlite3ValueFree(pVal); return ret; } /* -** tdsqlite3WhereBegin() has already been called for the SELECT statement +** sqlite3WhereBegin() has already been called for the SELECT statement ** passed as the second argument when this function is invoked. It generates ** code to populate the Window.regResult register for each window function ** and invoke the sub-routine at instruction addrGosub once for each row. -** tdsqlite3WhereEnd() is always called before returning. +** sqlite3WhereEnd() is always called before returning. ** ** This function handles several different types of window frames, which ** require slightly different processing. The following pseudo code is @@ -155293,7 +155293,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** Other window frame types use variants of the following: ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155335,7 +155335,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** AGGSTEP: invoke the aggregate xStep() function for each window function ** with arguments read from the current row of cursor csrEnd, then -** step cursor csrEnd forward one row (i.e. tdsqlite3BtreeNext()). +** step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()). ** ** RETURN_ROW: return a row to the caller based on the contents of the ** current row of csrCurrent and the current state of all @@ -155355,7 +155355,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** ROWS BETWEEN PRECEDING AND PRECEDING ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155383,7 +155383,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** ROWS BETWEEN FOLLOWING AND FOLLOWING ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155427,7 +155427,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** ROWS BETWEEN FOLLOWING AND UNBOUNDED FOLLOWING ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155461,7 +155461,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** To handle this case, the pseudo-code programs depicted above are modified ** slightly to be: ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155478,7 +155478,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ... ** ** The new "continue" statement in the above jumps to the next iteration -** of the outer loop - the one started by tdsqlite3WhereBegin(). +** of the outer loop - the one started by sqlite3WhereBegin(). ** ** The various GROUPS cases are implemented using the same patterns as ** ROWS. The VM code is modified slightly so that: @@ -155487,7 +155487,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** added to the ephemeral table is the start of a new group. In ** other words, it becomes: ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155512,7 +155512,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** RANGE BETWEEN PRECEDING AND FOLLOWING ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155548,7 +155548,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** RANGE BETWEEN PRECEDING AND PRECEDING ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155578,7 +155578,7 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** ** RANGE BETWEEN FOLLOWING AND FOLLOWING ** -** ... loop started by tdsqlite3WhereBegin() ... +** ... loop started by sqlite3WhereBegin() ... ** if( new partition ){ ** Gosub flush ** } @@ -155613,16 +155613,16 @@ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ ** The text above leaves out many details. Refer to the code and comments ** below for a more complete picture. */ -SQLITE_PRIVATE void tdsqlite3WindowCodeStep( +SQLITE_PRIVATE void sqlite3WindowCodeStep( Parse *pParse, /* Parse context */ Select *p, /* Rewritten SELECT statement */ - WhereInfo *pWInfo, /* Context returned by tdsqlite3WhereBegin() */ + WhereInfo *pWInfo, /* Context returned by sqlite3WhereBegin() */ int regGosub, /* Register for OP_Gosub */ int addrGosub /* OP_Gosub here to return each row */ ){ Window *pMWin = p->pWin; ExprList *pOrderBy = pMWin->pOrderBy; - Vdbe *v = tdsqlite3GetVdbe(pParse); + Vdbe *v = sqlite3GetVdbe(pParse); int csrWrite; /* Cursor used to write to eph. table */ int csrInput = p->pSrc->a[0].iCursor; /* Cursor of sub-select */ int nInput = p->pSrc->a[0].pTab->nCol; /* Number of cols returned by sub */ @@ -155638,7 +155638,7 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeStep( int regPeer = 0; /* Peer values for current row */ int regFlushPart = 0; /* Register for "Gosub flush_partition" */ WindowCodeArg s; /* Context object for sub-routines */ - int lblWhereEnd; /* Label just before tdsqlite3WhereEnd() code */ + int lblWhereEnd; /* Label just before sqlite3WhereEnd() code */ int regStart = 0; /* Value of PRECEDING */ int regEnd = 0; /* Value of FOLLOWING */ @@ -155653,7 +155653,7 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeStep( || pMWin->eExclude==TK_NO ); - lblWhereEnd = tdsqlite3VdbeMakeLabel(pParse); + lblWhereEnd = sqlite3VdbeMakeLabel(pParse); /* Fill in the context object */ memset(&s, 0, sizeof(WindowCodeArg)); @@ -155734,9 +155734,9 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeStep( ** into an array of registers starting at regNew. Assemble them into ** a record in register regRecord. */ for(iInput=0; iInputpPartition; int nPart = pPart->nExpr; int regNewPart = regNew + pMWin->nBufferCol; - KeyInfo *pKeyInfo = tdsqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); + KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0); regFlushPart = ++pParse->nMem; - addr = tdsqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart); - tdsqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); - tdsqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2); + addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart); + sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); + sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2); VdbeCoverageEqNe(v); - addrGosubFlush = tdsqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart); + addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart); VdbeComment((v, "call flush_partition")); - tdsqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1); + sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1); } /* Insert the new row into the ephemeral table */ - tdsqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid); - tdsqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid); - addrNe = tdsqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid); + sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid); + sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid); + addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid); VdbeCoverageNeverNull(v); /* This block is run for the first row of each partition */ s.regArg = windowInitAccum(pParse, pMWin); if( regStart ){ - tdsqlite3ExprCode(pParse, pMWin->pStart, regStart); + sqlite3ExprCode(pParse, pMWin->pStart, regStart); windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE?3:0)); } if( regEnd ){ - tdsqlite3ExprCode(pParse, pMWin->pEnd, regEnd); + sqlite3ExprCode(pParse, pMWin->pEnd, regEnd); windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE?3:0)); } if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){ int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); - int addrGe = tdsqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); + int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound */ VdbeCoverageNeverNullIf(v, op==OP_Le); /* values previously checked */ windowAggFinal(&s, 0); - tdsqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); + sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); VdbeCoverageNeverTaken(v); windowReturnOneRow(&s); - tdsqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); - tdsqlite3VdbeJumpHere(v, addrGe); + sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); + sqlite3VdbeJumpHere(v, addrGe); } if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){ assert( pMWin->eEnd==TK_FOLLOWING ); - tdsqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart); + sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart); } if( pMWin->eStart!=TK_UNBOUNDED ){ - tdsqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1); + sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1); VdbeCoverageNeverTaken(v); } - tdsqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); + sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1); VdbeCoverageNeverTaken(v); - tdsqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1); + sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1); VdbeCoverageNeverTaken(v); if( regPeer && pOrderBy ){ - tdsqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1); - tdsqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1); - tdsqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1); - tdsqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1); + sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1); } - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); + sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd); - tdsqlite3VdbeJumpHere(v, addrNe); + sqlite3VdbeJumpHere(v, addrNe); /* Beginning of the block executed for the second and subsequent rows. */ if( regPeer ){ @@ -155823,13 +155823,13 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeStep( windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); if( pMWin->eEnd!=TK_UNBOUNDED ){ if( pMWin->eFrmType==TK_RANGE ){ - int lbl = tdsqlite3VdbeMakeLabel(pParse); - int addrNext = tdsqlite3VdbeCurrentAddr(v); + int lbl = sqlite3VdbeMakeLabel(pParse); + int addrNext = sqlite3VdbeCurrentAddr(v); windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl); windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); - tdsqlite3VdbeResolveLabel(v, lbl); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); + sqlite3VdbeResolveLabel(v, lbl); }else{ windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0); windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); @@ -155848,40 +155848,40 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeStep( if( pMWin->eEnd!=TK_UNBOUNDED ){ if( pMWin->eFrmType==TK_RANGE ){ int lbl = 0; - addr = tdsqlite3VdbeCurrentAddr(v); + addr = sqlite3VdbeCurrentAddr(v); if( regEnd ){ - lbl = tdsqlite3VdbeMakeLabel(pParse); + lbl = sqlite3VdbeMakeLabel(pParse); windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl); } windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); if( regEnd ){ - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, addr); - tdsqlite3VdbeResolveLabel(v, lbl); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); + sqlite3VdbeResolveLabel(v, lbl); } }else{ if( regEnd ){ - addr = tdsqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1); + addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1); VdbeCoverage(v); } windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0); windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); - if( regEnd ) tdsqlite3VdbeJumpHere(v, addr); + if( regEnd ) sqlite3VdbeJumpHere(v, addr); } } } /* End of the main input loop */ - tdsqlite3VdbeResolveLabel(v, lblWhereEnd); - tdsqlite3WhereEnd(pWInfo); + sqlite3VdbeResolveLabel(v, lblWhereEnd); + sqlite3WhereEnd(pWInfo); /* Fall through */ if( pMWin->pPartition ){ - addrInteger = tdsqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart); - tdsqlite3VdbeJumpHere(v, addrGosubFlush); + addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart); + sqlite3VdbeJumpHere(v, addrGosubFlush); } - addrEmpty = tdsqlite3VdbeAddOp1(v, OP_Rewind, csrWrite); + addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite); VdbeCoverage(v); if( pMWin->eEnd==TK_PRECEDING ){ int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE); @@ -155895,47 +155895,47 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeStep( int addrBreak3; windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); if( pMWin->eFrmType==TK_RANGE ){ - addrStart = tdsqlite3VdbeCurrentAddr(v); + addrStart = sqlite3VdbeCurrentAddr(v); addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1); addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); }else if( pMWin->eEnd==TK_UNBOUNDED ){ - addrStart = tdsqlite3VdbeCurrentAddr(v); + addrStart = sqlite3VdbeCurrentAddr(v); addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1); addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1); }else{ assert( pMWin->eEnd==TK_FOLLOWING ); - addrStart = tdsqlite3VdbeCurrentAddr(v); + addrStart = sqlite3VdbeCurrentAddr(v); addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1); addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1); } - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); - tdsqlite3VdbeJumpHere(v, addrBreak2); - addrStart = tdsqlite3VdbeCurrentAddr(v); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak2); + addrStart = sqlite3VdbeCurrentAddr(v); addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); - tdsqlite3VdbeJumpHere(v, addrBreak1); - tdsqlite3VdbeJumpHere(v, addrBreak3); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak1); + sqlite3VdbeJumpHere(v, addrBreak3); }else{ int addrBreak; int addrStart; windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0); - addrStart = tdsqlite3VdbeCurrentAddr(v); + addrStart = sqlite3VdbeCurrentAddr(v); addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1); windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0); - tdsqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); - tdsqlite3VdbeJumpHere(v, addrBreak); + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart); + sqlite3VdbeJumpHere(v, addrBreak); } - tdsqlite3VdbeJumpHere(v, addrEmpty); + sqlite3VdbeJumpHere(v, addrEmpty); - tdsqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); + sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr); if( pMWin->pPartition ){ if( pMWin->regStartRowid ){ - tdsqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid); - tdsqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid); + sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid); } - tdsqlite3VdbeChangeP1(v, addrInteger, tdsqlite3VdbeCurrentAddr(v)); - tdsqlite3VdbeAddOp1(v, OP_Return, regFlushPart); + sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v)); + sqlite3VdbeAddOp1(v, OP_Return, regFlushPart); } } @@ -155985,27 +155985,27 @@ SQLITE_PRIVATE void tdsqlite3WindowCodeStep( #define yytestcase(X) testcase(X) /* -** Indicate that tdsqlite3ParserFree() will never be called with a null +** Indicate that sqlite3ParserFree() will never be called with a null ** pointer. */ #define YYPARSEFREENEVERNULL 1 /* ** In the amalgamation, the parse.c file generated by lemon and the -** tokenize.c file are concatenated. In that case, tdsqlite3RunParser() +** tokenize.c file are concatenated. In that case, sqlite3RunParser() ** has access to the the size of the yyParser object and so the parser ** engine can be allocated from stack. In that case, only the -** tdsqlite3ParserInit() and tdsqlite3ParserFinalize() routines are invoked -** and the tdsqlite3ParserAlloc() and tdsqlite3ParserFree() routines can be +** sqlite3ParserInit() and sqlite3ParserFinalize() routines are invoked +** and the sqlite3ParserAlloc() and sqlite3ParserFree() routines can be ** omitted. */ #ifdef SQLITE_AMALGAMATION -# define tdsqlite3Parser_ENGINEALWAYSONSTACK 1 +# define sqlite3Parser_ENGINEALWAYSONSTACK 1 #endif /* ** Alternative datatype for the argument to the malloc() routine passed -** into tdsqlite3ParserAlloc(). The default is size_t. +** into sqlite3ParserAlloc(). The default is size_t. */ #define YYMALLOCARGTYPE u64 @@ -156027,7 +156027,7 @@ struct FrameBound { int eType; Expr *pExpr; }; ** shared across database connections. */ static void disableLookaside(Parse *pParse){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; pParse->disableLookaside++; DisableLookaside; } @@ -156051,7 +156051,7 @@ static void disableLookaside(Parse *pParse){ (mxSelect = pParse->db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT])>0 && cnt>mxSelect ){ - tdsqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); + sqlite3ErrorMsg(pParse, "too many terms in compound SELECT"); } } } @@ -156062,7 +156062,7 @@ static void disableLookaside(Parse *pParse){ ** that created the expression. */ static Expr *tokenExpr(Parse *pParse, int op, Token t){ - Expr *p = tdsqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); + Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1); if( p ){ /* memset(p, 0, sizeof(Expr)); */ p->op = (u8)op; @@ -156079,14 +156079,14 @@ static void disableLookaside(Parse *pParse){ p->u.zToken = (char*)&p[1]; memcpy(p->u.zToken, t.z, t.n); p->u.zToken[t.n] = 0; - if( tdsqlite3Isquote(p->u.zToken[0]) ){ - tdsqlite3DequoteExpr(p); + if( sqlite3Isquote(p->u.zToken[0]) ){ + sqlite3DequoteExpr(p); } #if SQLITE_MAX_EXPR_DEPTH>0 p->nHeight = 1; #endif if( IN_RENAME_OBJECT ){ - return (Expr*)tdsqlite3RenameTokenMap(pParse, (void*)p, &t); + return (Expr*)sqlite3RenameTokenMap(pParse, (void*)p, &t); } } return p; @@ -156096,10 +156096,10 @@ static void disableLookaside(Parse *pParse){ /* A routine to convert a binary TK_IS or TK_ISNOT expression into a ** unary TK_ISNULL or TK_NOTNULL expression. */ static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){ - tdsqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; if( pA && pY && pY->op==TK_NULL && !IN_RENAME_OBJECT ){ pA->op = (u8)op; - tdsqlite3ExprDelete(db, pA->pRight); + sqlite3ExprDelete(db, pA->pRight); pA->pRight = 0; } } @@ -156116,14 +156116,14 @@ static void disableLookaside(Parse *pParse){ int hasCollate, int sortOrder ){ - ExprList *p = tdsqlite3ExprListAppend(pParse, pPrior, 0); + ExprList *p = sqlite3ExprListAppend(pParse, pPrior, 0); if( (hasCollate || sortOrder!=SQLITE_SO_UNDEFINED) && pParse->db->init.busy==0 ){ - tdsqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"", + sqlite3ErrorMsg(pParse, "syntax error after column name \"%.*s\"", pIdToken->n, pIdToken->z); } - tdsqlite3ExprListSetName(pParse, p, pIdToken, 1); + sqlite3ExprListSetName(pParse, p, pIdToken, 1); return p; } @@ -156153,7 +156153,7 @@ static void disableLookaside(Parse *pParse){ ** YYACTIONTYPE is the data type used for "action codes" - numbers ** that indicate what to do in response to the next ** token. -** tdsqlite3ParserTOKENTYPE is the data type used for minor type for terminal +** sqlite3ParserTOKENTYPE is the data type used for minor type for terminal ** symbols. Background: A "minor type" is a semantic ** value associated with a terminal or non-terminal ** symbols. For example, for an "ID" terminal symbol, @@ -156164,16 +156164,16 @@ static void disableLookaside(Parse *pParse){ ** symbols. ** YYMINORTYPE is the data type used for all minor types. ** This is typically a union of many types, one of -** which is tdsqlite3ParserTOKENTYPE. The entry in the union +** which is sqlite3ParserTOKENTYPE. The entry in the union ** for terminal symbols is called "yy0". ** YYSTACKDEPTH is the maximum depth of the parser's stack. If ** zero the stack is dynamically sized using realloc() -** tdsqlite3ParserARG_SDECL A static variable declaration for the %extra_argument -** tdsqlite3ParserARG_PDECL A parameter declaration for the %extra_argument -** tdsqlite3ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter -** tdsqlite3ParserARG_STORE Code to store %extra_argument into yypParser -** tdsqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser -** tdsqlite3ParserCTX_* As tdsqlite3ParserARG_ except for %extra_context +** sqlite3ParserARG_SDECL A static variable declaration for the %extra_argument +** sqlite3ParserARG_PDECL A parameter declaration for the %extra_argument +** sqlite3ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter +** sqlite3ParserARG_STORE Code to store %extra_argument into yypParser +** sqlite3ParserARG_FETCH Code to extract %extra_argument from yypParser +** sqlite3ParserCTX_* As sqlite3ParserARG_ except for %extra_context ** YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. ** YYNSTATE the combined number of states. @@ -156196,10 +156196,10 @@ static void disableLookaside(Parse *pParse){ #define YYNOCODE 310 #define YYACTIONTYPE unsigned short int #define YYWILDCARD 100 -#define tdsqlite3ParserTOKENTYPE Token +#define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; - tdsqlite3ParserTOKENTYPE yy0; + sqlite3ParserTOKENTYPE yy0; SrcList* yy47; u8 yy58; struct FrameBound yy77; @@ -156219,16 +156219,16 @@ typedef union { #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 #endif -#define tdsqlite3ParserARG_SDECL -#define tdsqlite3ParserARG_PDECL -#define tdsqlite3ParserARG_PARAM -#define tdsqlite3ParserARG_FETCH -#define tdsqlite3ParserARG_STORE -#define tdsqlite3ParserCTX_SDECL Parse *pParse; -#define tdsqlite3ParserCTX_PDECL ,Parse *pParse -#define tdsqlite3ParserCTX_PARAM ,pParse -#define tdsqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; -#define tdsqlite3ParserCTX_STORE yypParser->pParse=pParse; +#define sqlite3ParserARG_SDECL +#define sqlite3ParserARG_PDECL +#define sqlite3ParserARG_PARAM +#define sqlite3ParserARG_FETCH +#define sqlite3ParserARG_STORE +#define sqlite3ParserCTX_SDECL Parse *pParse; +#define sqlite3ParserCTX_PDECL ,Parse *pParse +#define sqlite3ParserCTX_PARAM ,pParse +#define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; +#define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #define YYFALLBACK 1 #define YYNSTATE 551 #define YYNRULE 385 @@ -157123,8 +157123,8 @@ struct yyParser { #ifndef YYNOERRORRECOVERY int yyerrcnt; /* Shifts left before out of the error */ #endif - tdsqlite3ParserARG_SDECL /* A place to hold %extra_argument */ - tdsqlite3ParserCTX_SDECL /* A place to hold %extra_context */ + sqlite3ParserARG_SDECL /* A place to hold %extra_argument */ + sqlite3ParserCTX_SDECL /* A place to hold %extra_context */ #if YYSTACKDEPTH<=0 int yystksz; /* Current side of the stack */ yyStackEntry *yystack; /* The parser's stack */ @@ -157160,7 +157160,7 @@ static char *yyTracePrompt = 0; ** Outputs: ** None. */ -SQLITE_PRIVATE void tdsqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ +SQLITE_PRIVATE void sqlite3ParserTrace(FILE *TraceFILE, char *zTracePrompt){ yyTraceFILE = TraceFILE; yyTracePrompt = zTracePrompt; if( yyTraceFILE==0 ) yyTracePrompt = 0; @@ -157912,7 +157912,7 @@ static int yyGrowStack(yyParser *p){ #endif /* Datatype of the argument to the memory allocated passed as the -** second argument to tdsqlite3ParserAlloc() below. This can be changed by +** second argument to sqlite3ParserAlloc() below. This can be changed by ** putting an appropriate #define in the %include section of the input ** grammar. */ @@ -157922,9 +157922,9 @@ static int yyGrowStack(yyParser *p){ /* Initialize a new parser that has already been allocated. */ -SQLITE_PRIVATE void tdsqlite3ParserInit(void *yypRawParser tdsqlite3ParserCTX_PDECL){ +SQLITE_PRIVATE void sqlite3ParserInit(void *yypRawParser sqlite3ParserCTX_PDECL){ yyParser *yypParser = (yyParser*)yypRawParser; - tdsqlite3ParserCTX_STORE + sqlite3ParserCTX_STORE #ifdef YYTRACKMAXSTACKDEPTH yypParser->yyhwm = 0; #endif @@ -157948,7 +157948,7 @@ SQLITE_PRIVATE void tdsqlite3ParserInit(void *yypRawParser tdsqlite3ParserCTX_PD #endif } -#ifndef tdsqlite3Parser_ENGINEALWAYSONSTACK +#ifndef sqlite3Parser_ENGINEALWAYSONSTACK /* ** This function allocates a new parser. ** The only argument is a pointer to a function which works like @@ -157959,18 +157959,18 @@ SQLITE_PRIVATE void tdsqlite3ParserInit(void *yypRawParser tdsqlite3ParserCTX_PD ** ** Outputs: ** A pointer to a parser. This pointer is used in subsequent calls -** to tdsqlite3Parser and tdsqlite3ParserFree. +** to sqlite3Parser and sqlite3ParserFree. */ -SQLITE_PRIVATE void *tdsqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) tdsqlite3ParserCTX_PDECL){ +SQLITE_PRIVATE void *sqlite3ParserAlloc(void *(*mallocProc)(YYMALLOCARGTYPE) sqlite3ParserCTX_PDECL){ yyParser *yypParser; yypParser = (yyParser*)(*mallocProc)( (YYMALLOCARGTYPE)sizeof(yyParser) ); if( yypParser ){ - tdsqlite3ParserCTX_STORE - tdsqlite3ParserInit(yypParser tdsqlite3ParserCTX_PARAM); + sqlite3ParserCTX_STORE + sqlite3ParserInit(yypParser sqlite3ParserCTX_PARAM); } return (void*)yypParser; } -#endif /* tdsqlite3Parser_ENGINEALWAYSONSTACK */ +#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */ /* The following function deletes the "minor type" or semantic value @@ -157985,8 +157985,8 @@ static void yy_destructor( YYCODETYPE yymajor, /* Type code for object to destroy */ YYMINORTYPE *yypminor /* The object to be destroyed */ ){ - tdsqlite3ParserARG_FETCH - tdsqlite3ParserCTX_FETCH + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH switch( yymajor ){ /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen @@ -158004,7 +158004,7 @@ static void yy_destructor( case 235: /* oneselect */ case 247: /* values */ { -tdsqlite3SelectDelete(pParse->db, (yypminor->yy539)); +sqlite3SelectDelete(pParse->db, (yypminor->yy539)); } break; case 211: /* term */ @@ -158019,7 +158019,7 @@ tdsqlite3SelectDelete(pParse->db, (yypminor->yy539)); case 288: /* key_opt */ case 302: /* filter_clause */ { -tdsqlite3ExprDelete(pParse->db, (yypminor->yy202)); +sqlite3ExprDelete(pParse->db, (yypminor->yy202)); } break; case 216: /* eidlist_opt */ @@ -158036,7 +158036,7 @@ tdsqlite3ExprDelete(pParse->db, (yypminor->yy202)); case 272: /* case_exprlist */ case 301: /* part_opt */ { -tdsqlite3ExprListDelete(pParse->db, (yypminor->yy242)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy242)); } break; case 233: /* fullname */ @@ -158045,25 +158045,25 @@ tdsqlite3ExprListDelete(pParse->db, (yypminor->yy242)); case 252: /* stl_prefix */ case 258: /* xfullname */ { -tdsqlite3SrcListDelete(pParse->db, (yypminor->yy47)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy47)); } break; case 236: /* wqlist */ { -tdsqlite3WithDelete(pParse->db, (yypminor->yy131)); +sqlite3WithDelete(pParse->db, (yypminor->yy131)); } break; case 246: /* window_clause */ case 297: /* windowdefn_list */ { -tdsqlite3WindowListDelete(pParse->db, (yypminor->yy303)); +sqlite3WindowListDelete(pParse->db, (yypminor->yy303)); } break; case 256: /* using_opt */ case 259: /* idlist */ case 264: /* idlist_opt */ { -tdsqlite3IdListDelete(pParse->db, (yypminor->yy600)); +sqlite3IdListDelete(pParse->db, (yypminor->yy600)); } break; case 266: /* filter_over */ @@ -158072,25 +158072,25 @@ tdsqlite3IdListDelete(pParse->db, (yypminor->yy600)); case 300: /* frame_opt */ case 303: /* over_clause */ { -tdsqlite3WindowDelete(pParse->db, (yypminor->yy303)); +sqlite3WindowDelete(pParse->db, (yypminor->yy303)); } break; case 279: /* trigger_cmd_list */ case 284: /* trigger_cmd */ { -tdsqlite3DeleteTriggerStep(pParse->db, (yypminor->yy447)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy447)); } break; case 281: /* trigger_event */ { -tdsqlite3IdListDelete(pParse->db, (yypminor->yy230).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy230).b); } break; case 305: /* frame_bound */ case 306: /* frame_bound_s */ case 307: /* frame_bound_e */ { -tdsqlite3ExprDelete(pParse->db, (yypminor->yy77).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy77).pExpr); } break; /********* End destructor definitions *****************************************/ @@ -158122,7 +158122,7 @@ static void yy_pop_parser_stack(yyParser *pParser){ /* ** Clear all secondary memory allocations from the parser */ -SQLITE_PRIVATE void tdsqlite3ParserFinalize(void *p){ +SQLITE_PRIVATE void sqlite3ParserFinalize(void *p){ yyParser *pParser = (yyParser*)p; while( pParser->yytos>pParser->yystack ) yy_pop_parser_stack(pParser); #if YYSTACKDEPTH<=0 @@ -158130,7 +158130,7 @@ SQLITE_PRIVATE void tdsqlite3ParserFinalize(void *p){ #endif } -#ifndef tdsqlite3Parser_ENGINEALWAYSONSTACK +#ifndef sqlite3Parser_ENGINEALWAYSONSTACK /* ** Deallocate and destroy a parser. Destructors are called for ** all stack elements before shutting the parser down. @@ -158139,23 +158139,23 @@ SQLITE_PRIVATE void tdsqlite3ParserFinalize(void *p){ ** is defined in a %include section of the input grammar) then it is ** assumed that the input pointer is never NULL. */ -SQLITE_PRIVATE void tdsqlite3ParserFree( +SQLITE_PRIVATE void sqlite3ParserFree( void *p, /* The parser to be deleted */ void (*freeProc)(void*) /* Function used to reclaim memory */ ){ #ifndef YYPARSEFREENEVERNULL if( p==0 ) return; #endif - tdsqlite3ParserFinalize(p); + sqlite3ParserFinalize(p); (*freeProc)(p); } -#endif /* tdsqlite3Parser_ENGINEALWAYSONSTACK */ +#endif /* sqlite3Parser_ENGINEALWAYSONSTACK */ /* ** Return the peak depth of the stack for a parser. */ #ifdef YYTRACKMAXSTACKDEPTH -SQLITE_PRIVATE int tdsqlite3ParserStackPeak(void *p){ +SQLITE_PRIVATE int sqlite3ParserStackPeak(void *p){ yyParser *pParser = (yyParser*)p; return pParser->yyhwm; } @@ -158179,7 +158179,7 @@ static unsigned char yycoverage[YYNSTATE][YYNTOKEN]; ** Return the number of missed state/lookahead combinations. */ #if defined(YYCOVERAGE) -SQLITE_PRIVATE int tdsqlite3ParserCoverage(FILE *out){ +SQLITE_PRIVATE int sqlite3ParserCoverage(FILE *out){ int stateno, iLookAhead, i; int nMissed = 0; for(stateno=0; statenoyytos++; @@ -159174,14 +159174,14 @@ static YYACTIONTYPE yy_reduce( yyParser *yypParser, /* The parser */ unsigned int yyruleno, /* Number of the rule by which to reduce */ int yyLookahead, /* Lookahead token, or YYNOCODE if none */ - tdsqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ - tdsqlite3ParserCTX_PDECL /* %extra_context */ + sqlite3ParserTOKENTYPE yyLookaheadToken /* Value of the lookahead token */ + sqlite3ParserCTX_PDECL /* %extra_context */ ){ int yygoto; /* The next state */ YYACTIONTYPE yyact; /* The next action */ yyStackEntry *yymsp; /* The top of the parser's stack */ int yysize; /* Amount to pop the stack */ - tdsqlite3ParserARG_FETCH + sqlite3ParserARG_FETCH (void)yyLookahead; (void)yyLookaheadToken; yymsp = yypParser->yytos; @@ -159252,10 +159252,10 @@ static YYACTIONTYPE yy_reduce( { pParse->explain = 2; } break; case 2: /* cmdx ::= cmd */ -{ tdsqlite3FinishCoding(pParse); } +{ sqlite3FinishCoding(pParse); } break; case 3: /* cmd ::= BEGIN transtype trans_opt */ -{tdsqlite3BeginTransaction(pParse, yymsp[-1].minor.yy192);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy192);} break; case 4: /* transtype ::= */ {yymsp[1].minor.yy192 = TK_DEFERRED;} @@ -159268,26 +159268,26 @@ static YYACTIONTYPE yy_reduce( break; case 8: /* cmd ::= COMMIT|END trans_opt */ case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9); -{tdsqlite3EndTransaction(pParse,yymsp[-1].major);} +{sqlite3EndTransaction(pParse,yymsp[-1].major);} break; case 10: /* cmd ::= SAVEPOINT nm */ { - tdsqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0); + sqlite3Savepoint(pParse, SAVEPOINT_BEGIN, &yymsp[0].minor.yy0); } break; case 11: /* cmd ::= RELEASE savepoint_opt nm */ { - tdsqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0); + sqlite3Savepoint(pParse, SAVEPOINT_RELEASE, &yymsp[0].minor.yy0); } break; case 12: /* cmd ::= ROLLBACK trans_opt TO savepoint_opt nm */ { - tdsqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); + sqlite3Savepoint(pParse, SAVEPOINT_ROLLBACK, &yymsp[0].minor.yy0); } break; case 13: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - tdsqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy192,0,0,yymsp[-2].minor.yy192); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy192,0,0,yymsp[-2].minor.yy192); } break; case 14: /* createkw ::= CREATE */ @@ -159313,27 +159313,27 @@ static YYACTIONTYPE yy_reduce( break; case 19: /* create_table_args ::= LP columnlist conslist_opt RP table_options */ { - tdsqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy192,0); + sqlite3EndTable(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,yymsp[0].minor.yy192,0); } break; case 20: /* create_table_args ::= AS select */ { - tdsqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy539); - tdsqlite3SelectDelete(pParse->db, yymsp[0].minor.yy539); + sqlite3EndTable(pParse,0,0,0,yymsp[0].minor.yy539); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy539); } break; case 22: /* table_options ::= WITHOUT nm */ { - if( yymsp[0].minor.yy0.n==5 && tdsqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ + if( yymsp[0].minor.yy0.n==5 && sqlite3_strnicmp(yymsp[0].minor.yy0.z,"rowid",5)==0 ){ yymsp[-1].minor.yy192 = TF_WithoutRowid | TF_NoVisibleRowid; }else{ yymsp[-1].minor.yy192 = 0; - tdsqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); + sqlite3ErrorMsg(pParse, "unknown table option: %.*s", yymsp[0].minor.yy0.n, yymsp[0].minor.yy0.z); } } break; case 23: /* columnname ::= nm typetoken */ -{tdsqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} +{sqlite3AddColumn(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} break; case 24: /* typetoken ::= */ case 63: /* conslist_opt ::= */ yytestcase(yyruleno==63); @@ -159370,57 +159370,57 @@ static YYACTIONTYPE yy_reduce( {pParse->constraintName = yymsp[0].minor.yy0;} break; case 31: /* ccons ::= DEFAULT scantok term */ -{tdsqlite3AddDefaultValue(pParse,yymsp[0].minor.yy202,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy202,yymsp[-1].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 32: /* ccons ::= DEFAULT LP expr RP */ -{tdsqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy202,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} +{sqlite3AddDefaultValue(pParse,yymsp[-1].minor.yy202,yymsp[-2].minor.yy0.z+1,yymsp[0].minor.yy0.z);} break; case 33: /* ccons ::= DEFAULT PLUS scantok term */ -{tdsqlite3AddDefaultValue(pParse,yymsp[0].minor.yy202,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} +{sqlite3AddDefaultValue(pParse,yymsp[0].minor.yy202,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]);} break; case 34: /* ccons ::= DEFAULT MINUS scantok term */ { - Expr *p = tdsqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy202, 0); - tdsqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); + Expr *p = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy202, 0); + sqlite3AddDefaultValue(pParse,p,yymsp[-2].minor.yy0.z,&yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]); } break; case 35: /* ccons ::= DEFAULT scantok ID|INDEXED */ { Expr *p = tokenExpr(pParse, TK_STRING, yymsp[0].minor.yy0); if( p ){ - tdsqlite3ExprIdToTrueFalse(p); - testcase( p->op==TK_TRUEFALSE && tdsqlite3ExprTruthValue(p) ); + sqlite3ExprIdToTrueFalse(p); + testcase( p->op==TK_TRUEFALSE && sqlite3ExprTruthValue(p) ); } - tdsqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); + sqlite3AddDefaultValue(pParse,p,yymsp[0].minor.yy0.z,yymsp[0].minor.yy0.z+yymsp[0].minor.yy0.n); } break; case 36: /* ccons ::= NOT NULL onconf */ -{tdsqlite3AddNotNull(pParse, yymsp[0].minor.yy192);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy192);} break; case 37: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{tdsqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy192,yymsp[0].minor.yy192,yymsp[-2].minor.yy192);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy192,yymsp[0].minor.yy192,yymsp[-2].minor.yy192);} break; case 38: /* ccons ::= UNIQUE onconf */ -{tdsqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy192,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy192,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 39: /* ccons ::= CHECK LP expr RP */ -{tdsqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy202);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy202);} break; case 40: /* ccons ::= REFERENCES nm eidlist_opt refargs */ -{tdsqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy242,yymsp[0].minor.yy192);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy242,yymsp[0].minor.yy192);} break; case 41: /* ccons ::= defer_subclause */ -{tdsqlite3DeferForeignKey(pParse,yymsp[0].minor.yy192);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy192);} break; case 42: /* ccons ::= COLLATE ID|STRING */ -{tdsqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} +{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 43: /* generated ::= LP expr RP */ -{tdsqlite3AddGenerated(pParse,yymsp[-1].minor.yy202,0);} +{sqlite3AddGenerated(pParse,yymsp[-1].minor.yy202,0);} break; case 44: /* generated ::= LP expr RP ID */ -{tdsqlite3AddGenerated(pParse,yymsp[-2].minor.yy202,&yymsp[0].minor.yy0);} +{sqlite3AddGenerated(pParse,yymsp[-2].minor.yy202,&yymsp[0].minor.yy0);} break; case 47: /* refargs ::= */ { yymsp[1].minor.yy192 = OE_None*0x0101; /* EV: R-19803-45884 */} @@ -159477,19 +159477,19 @@ static YYACTIONTYPE yy_reduce( {pParse->constraintName.n = 0;} break; case 66: /* tcons ::= PRIMARY KEY LP sortlist autoinc RP onconf */ -{tdsqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy242,yymsp[0].minor.yy192,yymsp[-2].minor.yy192,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy242,yymsp[0].minor.yy192,yymsp[-2].minor.yy192,0);} break; case 67: /* tcons ::= UNIQUE LP sortlist RP onconf */ -{tdsqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy242,yymsp[0].minor.yy192,0,0,0,0, +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy242,yymsp[0].minor.yy192,0,0,0,0, SQLITE_IDXTYPE_UNIQUE);} break; case 68: /* tcons ::= CHECK LP expr RP onconf */ -{tdsqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy202);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy202);} break; case 69: /* tcons ::= FOREIGN KEY LP eidlist RP REFERENCES nm eidlist_opt refargs defer_subclause_opt */ { - tdsqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy242, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy242, yymsp[-1].minor.yy192); - tdsqlite3DeferForeignKey(pParse, yymsp[0].minor.yy192); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy242, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy242, yymsp[-1].minor.yy192); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy192); } break; case 71: /* onconf ::= */ @@ -159508,24 +159508,24 @@ static YYACTIONTYPE yy_reduce( break; case 77: /* cmd ::= DROP TABLE ifexists fullname */ { - tdsqlite3DropTable(pParse, yymsp[0].minor.yy47, 0, yymsp[-1].minor.yy192); + sqlite3DropTable(pParse, yymsp[0].minor.yy47, 0, yymsp[-1].minor.yy192); } break; case 80: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm eidlist_opt AS select */ { - tdsqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy242, yymsp[0].minor.yy539, yymsp[-7].minor.yy192, yymsp[-5].minor.yy192); + sqlite3CreateView(pParse, &yymsp[-8].minor.yy0, &yymsp[-4].minor.yy0, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy242, yymsp[0].minor.yy539, yymsp[-7].minor.yy192, yymsp[-5].minor.yy192); } break; case 81: /* cmd ::= DROP VIEW ifexists fullname */ { - tdsqlite3DropTable(pParse, yymsp[0].minor.yy47, 1, yymsp[-1].minor.yy192); + sqlite3DropTable(pParse, yymsp[0].minor.yy47, 1, yymsp[-1].minor.yy192); } break; case 82: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0, 0}; - tdsqlite3Select(pParse, yymsp[0].minor.yy539, &dest); - tdsqlite3SelectDelete(pParse->db, yymsp[0].minor.yy539); + sqlite3Select(pParse, yymsp[0].minor.yy539, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy539); } break; case 83: /* select ::= WITH wqlist selectnowith */ @@ -159535,7 +159535,7 @@ static YYACTIONTYPE yy_reduce( p->pWith = yymsp[-1].minor.yy131; parserDoubleLinkSelect(pParse, p); }else{ - tdsqlite3WithDelete(pParse->db, yymsp[-1].minor.yy131); + sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy131); } yymsp[-2].minor.yy539 = p; } @@ -159547,7 +159547,7 @@ static YYACTIONTYPE yy_reduce( p->pWith = yymsp[-1].minor.yy131; parserDoubleLinkSelect(pParse, p); }else{ - tdsqlite3WithDelete(pParse->db, yymsp[-1].minor.yy131); + sqlite3WithDelete(pParse->db, yymsp[-1].minor.yy131); } yymsp[-3].minor.yy539 = p; } @@ -159570,8 +159570,8 @@ static YYACTIONTYPE yy_reduce( Token x; x.n = 0; parserDoubleLinkSelect(pParse, pRhs); - pFrom = tdsqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); - pRhs = tdsqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); + pFrom = sqlite3SrcListAppendFromTerm(pParse,0,0,0,&x,pRhs,0,0); + pRhs = sqlite3SelectNew(pParse,0,pFrom,0,0,0,0,0,0); } if( pRhs ){ pRhs->op = (u8)yymsp[-1].minor.yy192; @@ -159580,7 +159580,7 @@ static YYACTIONTYPE yy_reduce( pRhs->selFlags &= ~SF_MultiValue; if( yymsp[-1].minor.yy192!=TK_ALL ) pParse->hasCompound = 1; }else{ - tdsqlite3SelectDelete(pParse->db, pLhs); + sqlite3SelectDelete(pParse->db, pLhs); } yymsp[-2].minor.yy539 = pRhs; } @@ -159594,28 +159594,28 @@ static YYACTIONTYPE yy_reduce( break; case 90: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yymsp[-8].minor.yy539 = tdsqlite3SelectNew(pParse,yymsp[-6].minor.yy242,yymsp[-5].minor.yy47,yymsp[-4].minor.yy202,yymsp[-3].minor.yy242,yymsp[-2].minor.yy202,yymsp[-1].minor.yy242,yymsp[-7].minor.yy192,yymsp[0].minor.yy202); + yymsp[-8].minor.yy539 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy242,yymsp[-5].minor.yy47,yymsp[-4].minor.yy202,yymsp[-3].minor.yy242,yymsp[-2].minor.yy202,yymsp[-1].minor.yy242,yymsp[-7].minor.yy192,yymsp[0].minor.yy202); } break; case 91: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt window_clause orderby_opt limit_opt */ { - yymsp[-9].minor.yy539 = tdsqlite3SelectNew(pParse,yymsp[-7].minor.yy242,yymsp[-6].minor.yy47,yymsp[-5].minor.yy202,yymsp[-4].minor.yy242,yymsp[-3].minor.yy202,yymsp[-1].minor.yy242,yymsp[-8].minor.yy192,yymsp[0].minor.yy202); + yymsp[-9].minor.yy539 = sqlite3SelectNew(pParse,yymsp[-7].minor.yy242,yymsp[-6].minor.yy47,yymsp[-5].minor.yy202,yymsp[-4].minor.yy242,yymsp[-3].minor.yy202,yymsp[-1].minor.yy242,yymsp[-8].minor.yy192,yymsp[0].minor.yy202); if( yymsp[-9].minor.yy539 ){ yymsp[-9].minor.yy539->pWinDefn = yymsp[-2].minor.yy303; }else{ - tdsqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy303); + sqlite3WindowListDelete(pParse->db, yymsp[-2].minor.yy303); } } break; case 92: /* values ::= VALUES LP nexprlist RP */ { - yymsp[-3].minor.yy539 = tdsqlite3SelectNew(pParse,yymsp[-1].minor.yy242,0,0,0,0,0,SF_Values,0); + yymsp[-3].minor.yy539 = sqlite3SelectNew(pParse,yymsp[-1].minor.yy242,0,0,0,0,0,SF_Values,0); } break; case 93: /* values ::= values COMMA LP nexprlist RP */ { Select *pRight, *pLeft = yymsp[-4].minor.yy539; - pRight = tdsqlite3SelectNew(pParse,yymsp[-1].minor.yy242,0,0,0,0,0,SF_Values|SF_MultiValue,0); + pRight = sqlite3SelectNew(pParse,yymsp[-1].minor.yy242,0,0,0,0,0,SF_Values|SF_MultiValue,0); if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue; if( pRight ){ pRight->op = TK_ALL; @@ -159642,23 +159642,23 @@ static YYACTIONTYPE yy_reduce( break; case 98: /* selcollist ::= sclp scanpt expr scanpt as */ { - yymsp[-4].minor.yy242 = tdsqlite3ExprListAppend(pParse, yymsp[-4].minor.yy242, yymsp[-2].minor.yy202); - if( yymsp[0].minor.yy0.n>0 ) tdsqlite3ExprListSetName(pParse, yymsp[-4].minor.yy242, &yymsp[0].minor.yy0, 1); - tdsqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy242,yymsp[-3].minor.yy436,yymsp[-1].minor.yy436); + yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy242, yymsp[-2].minor.yy202); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy242, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yymsp[-4].minor.yy242,yymsp[-3].minor.yy436,yymsp[-1].minor.yy436); } break; case 99: /* selcollist ::= sclp scanpt STAR */ { - Expr *p = tdsqlite3Expr(pParse->db, TK_ASTERISK, 0); - yymsp[-2].minor.yy242 = tdsqlite3ExprListAppend(pParse, yymsp[-2].minor.yy242, p); + Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); + yymsp[-2].minor.yy242 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy242, p); } break; case 100: /* selcollist ::= sclp scanpt nm DOT STAR */ { - Expr *pRight = tdsqlite3PExpr(pParse, TK_ASTERISK, 0, 0); - Expr *pLeft = tdsqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *pDot = tdsqlite3PExpr(pParse, TK_DOT, pLeft, pRight); - yymsp[-4].minor.yy242 = tdsqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, pDot); + Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); + Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); + Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); + yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, pDot); } break; case 101: /* as ::= AS nm */ @@ -159668,12 +159668,12 @@ static YYACTIONTYPE yy_reduce( {yymsp[-1].minor.yy0 = yymsp[0].minor.yy0;} break; case 103: /* from ::= */ -{yymsp[1].minor.yy47 = tdsqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy47));} +{yymsp[1].minor.yy47 = sqlite3DbMallocZero(pParse->db, sizeof(*yymsp[1].minor.yy47));} break; case 104: /* from ::= FROM seltablist */ { yymsp[-1].minor.yy47 = yymsp[0].minor.yy47; - tdsqlite3SrcListShiftJoinType(yymsp[-1].minor.yy47); + sqlite3SrcListShiftJoinType(yymsp[-1].minor.yy47); } break; case 105: /* stl_prefix ::= seltablist joinop */ @@ -159686,19 +159686,19 @@ static YYACTIONTYPE yy_reduce( break; case 107: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yymsp[-6].minor.yy47 = tdsqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); - tdsqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy47, &yymsp[-2].minor.yy0); + yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + sqlite3SrcListIndexedBy(pParse, yymsp[-6].minor.yy47, &yymsp[-2].minor.yy0); } break; case 108: /* seltablist ::= stl_prefix nm dbnm LP exprlist RP as on_opt using_opt */ { - yymsp[-8].minor.yy47 = tdsqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy47,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); - tdsqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy47, yymsp[-4].minor.yy242); + yymsp[-8].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-8].minor.yy47,&yymsp[-7].minor.yy0,&yymsp[-6].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + sqlite3SrcListFuncArgs(pParse, yymsp[-8].minor.yy47, yymsp[-4].minor.yy242); } break; case 109: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yymsp[-6].minor.yy47 = tdsqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy539,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy539,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); } break; case 110: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ @@ -159706,7 +159706,7 @@ static YYACTIONTYPE yy_reduce( if( yymsp[-6].minor.yy47==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy202==0 && yymsp[0].minor.yy600==0 ){ yymsp[-6].minor.yy47 = yymsp[-4].minor.yy47; }else if( yymsp[-4].minor.yy47->nSrc==1 ){ - yymsp[-6].minor.yy47 = tdsqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); if( yymsp[-6].minor.yy47 ){ struct SrcList_item *pNew = &yymsp[-6].minor.yy47->a[yymsp[-6].minor.yy47->nSrc-1]; struct SrcList_item *pOld = yymsp[-4].minor.yy47->a; @@ -159722,12 +159722,12 @@ static YYACTIONTYPE yy_reduce( pOld->zName = pOld->zDatabase = 0; pOld->pSelect = 0; } - tdsqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy47); + sqlite3SrcListDelete(pParse->db, yymsp[-4].minor.yy47); }else{ Select *pSubquery; - tdsqlite3SrcListShiftJoinType(yymsp[-4].minor.yy47); - pSubquery = tdsqlite3SelectNew(pParse,0,yymsp[-4].minor.yy47,0,0,0,0,SF_NestedFrom,0); - yymsp[-6].minor.yy47 = tdsqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy47); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy47,0,0,0,0,SF_NestedFrom,0); + yymsp[-6].minor.yy47 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy47,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy202,yymsp[0].minor.yy600); } } break; @@ -159737,47 +159737,47 @@ static YYACTIONTYPE yy_reduce( break; case 113: /* fullname ::= nm */ { - yylhsminor.yy47 = tdsqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); - if( IN_RENAME_OBJECT && yylhsminor.yy47 ) tdsqlite3RenameTokenMap(pParse, yylhsminor.yy47->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); + if( IN_RENAME_OBJECT && yylhsminor.yy47 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy47->a[0].zName, &yymsp[0].minor.yy0); } yymsp[0].minor.yy47 = yylhsminor.yy47; break; case 114: /* fullname ::= nm DOT nm */ { - yylhsminor.yy47 = tdsqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); - if( IN_RENAME_OBJECT && yylhsminor.yy47 ) tdsqlite3RenameTokenMap(pParse, yylhsminor.yy47->a[0].zName, &yymsp[0].minor.yy0); + yylhsminor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + if( IN_RENAME_OBJECT && yylhsminor.yy47 ) sqlite3RenameTokenMap(pParse, yylhsminor.yy47->a[0].zName, &yymsp[0].minor.yy0); } yymsp[-2].minor.yy47 = yylhsminor.yy47; break; case 115: /* xfullname ::= nm */ -{yymsp[0].minor.yy47 = tdsqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} +{yymsp[0].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[0].minor.yy0,0); /*A-overwrites-X*/} break; case 116: /* xfullname ::= nm DOT nm */ -{yymsp[-2].minor.yy47 = tdsqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} +{yymsp[-2].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); /*A-overwrites-X*/} break; case 117: /* xfullname ::= nm DOT nm AS nm */ { - yymsp[-4].minor.yy47 = tdsqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ - if( yymsp[-4].minor.yy47 ) yymsp[-4].minor.yy47->a[0].zAlias = tdsqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-4].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,&yymsp[-2].minor.yy0); /*A-overwrites-X*/ + if( yymsp[-4].minor.yy47 ) yymsp[-4].minor.yy47->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 118: /* xfullname ::= nm AS nm */ { - yymsp[-2].minor.yy47 = tdsqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ - if( yymsp[-2].minor.yy47 ) yymsp[-2].minor.yy47->a[0].zAlias = tdsqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); + yymsp[-2].minor.yy47 = sqlite3SrcListAppend(pParse,0,&yymsp[-2].minor.yy0,0); /*A-overwrites-X*/ + if( yymsp[-2].minor.yy47 ) yymsp[-2].minor.yy47->a[0].zAlias = sqlite3NameFromToken(pParse->db, &yymsp[0].minor.yy0); } break; case 119: /* joinop ::= COMMA|JOIN */ { yymsp[0].minor.yy192 = JT_INNER; } break; case 120: /* joinop ::= JOIN_KW JOIN */ -{yymsp[-1].minor.yy192 = tdsqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} +{yymsp[-1].minor.yy192 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); /*X-overwrites-A*/} break; case 121: /* joinop ::= JOIN_KW nm JOIN */ -{yymsp[-2].minor.yy192 = tdsqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} +{yymsp[-2].minor.yy192 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); /*X-overwrites-A*/} break; case 122: /* joinop ::= JOIN_KW nm nm JOIN */ -{yymsp[-3].minor.yy192 = tdsqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} +{yymsp[-3].minor.yy192 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0);/*X-overwrites-A*/} break; case 123: /* on_opt ::= ON expr */ case 143: /* having_opt ::= HAVING expr */ yytestcase(yyruleno==143); @@ -159814,14 +159814,14 @@ static YYACTIONTYPE yy_reduce( break; case 132: /* sortlist ::= sortlist COMMA expr sortorder nulls */ { - yymsp[-4].minor.yy242 = tdsqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242,yymsp[-2].minor.yy202); - tdsqlite3ExprListSetSortOrder(yymsp[-4].minor.yy242,yymsp[-1].minor.yy192,yymsp[0].minor.yy192); + yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242,yymsp[-2].minor.yy202); + sqlite3ExprListSetSortOrder(yymsp[-4].minor.yy242,yymsp[-1].minor.yy192,yymsp[0].minor.yy192); } break; case 133: /* sortlist ::= expr sortorder nulls */ { - yymsp[-2].minor.yy242 = tdsqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy202); /*A-overwrites-Y*/ - tdsqlite3ExprListSetSortOrder(yymsp[-2].minor.yy242,yymsp[-1].minor.yy192,yymsp[0].minor.yy192); + yymsp[-2].minor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[-2].minor.yy202); /*A-overwrites-Y*/ + sqlite3ExprListSetSortOrder(yymsp[-2].minor.yy242,yymsp[-1].minor.yy192,yymsp[0].minor.yy192); } break; case 134: /* sortorder ::= ASC */ @@ -159841,80 +159841,80 @@ static YYACTIONTYPE yy_reduce( {yymsp[-1].minor.yy192 = SQLITE_SO_DESC;} break; case 145: /* limit_opt ::= LIMIT expr */ -{yymsp[-1].minor.yy202 = tdsqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,0);} +{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,0);} break; case 146: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yymsp[-3].minor.yy202 = tdsqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} +{yymsp[-3].minor.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} break; case 147: /* limit_opt ::= LIMIT expr COMMA expr */ -{yymsp[-3].minor.yy202 = tdsqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,yymsp[-2].minor.yy202);} +{yymsp[-3].minor.yy202 = sqlite3PExpr(pParse,TK_LIMIT,yymsp[0].minor.yy202,yymsp[-2].minor.yy202);} break; case 148: /* cmd ::= with DELETE FROM xfullname indexed_opt where_opt */ { - tdsqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy47, &yymsp[-1].minor.yy0); - tdsqlite3DeleteFrom(pParse,yymsp[-2].minor.yy47,yymsp[0].minor.yy202,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy47, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy47,yymsp[0].minor.yy202,0,0); } break; case 151: /* cmd ::= with UPDATE orconf xfullname indexed_opt SET setlist where_opt */ { - tdsqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy47, &yymsp[-3].minor.yy0); - tdsqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy242,"set list"); - tdsqlite3Update(pParse,yymsp[-4].minor.yy47,yymsp[-1].minor.yy242,yymsp[0].minor.yy202,yymsp[-5].minor.yy192,0,0,0); + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy47, &yymsp[-3].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy242,"set list"); + sqlite3Update(pParse,yymsp[-4].minor.yy47,yymsp[-1].minor.yy242,yymsp[0].minor.yy202,yymsp[-5].minor.yy192,0,0,0); } break; case 152: /* setlist ::= setlist COMMA nm EQ expr */ { - yymsp[-4].minor.yy242 = tdsqlite3ExprListAppend(pParse, yymsp[-4].minor.yy242, yymsp[0].minor.yy202); - tdsqlite3ExprListSetName(pParse, yymsp[-4].minor.yy242, &yymsp[-2].minor.yy0, 1); + yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy242, yymsp[0].minor.yy202); + sqlite3ExprListSetName(pParse, yymsp[-4].minor.yy242, &yymsp[-2].minor.yy0, 1); } break; case 153: /* setlist ::= setlist COMMA LP idlist RP EQ expr */ { - yymsp[-6].minor.yy242 = tdsqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy242, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); + yymsp[-6].minor.yy242 = sqlite3ExprListAppendVector(pParse, yymsp[-6].minor.yy242, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); } break; case 154: /* setlist ::= nm EQ expr */ { - yylhsminor.yy242 = tdsqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy202); - tdsqlite3ExprListSetName(pParse, yylhsminor.yy242, &yymsp[-2].minor.yy0, 1); + yylhsminor.yy242 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy202); + sqlite3ExprListSetName(pParse, yylhsminor.yy242, &yymsp[-2].minor.yy0, 1); } yymsp[-2].minor.yy242 = yylhsminor.yy242; break; case 155: /* setlist ::= LP idlist RP EQ expr */ { - yymsp[-4].minor.yy242 = tdsqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); + yymsp[-4].minor.yy242 = sqlite3ExprListAppendVector(pParse, 0, yymsp[-3].minor.yy600, yymsp[0].minor.yy202); } break; case 156: /* cmd ::= with insert_cmd INTO xfullname idlist_opt select upsert */ { - tdsqlite3Insert(pParse, yymsp[-3].minor.yy47, yymsp[-1].minor.yy539, yymsp[-2].minor.yy600, yymsp[-5].minor.yy192, yymsp[0].minor.yy318); + sqlite3Insert(pParse, yymsp[-3].minor.yy47, yymsp[-1].minor.yy539, yymsp[-2].minor.yy600, yymsp[-5].minor.yy192, yymsp[0].minor.yy318); } break; case 157: /* cmd ::= with insert_cmd INTO xfullname idlist_opt DEFAULT VALUES */ { - tdsqlite3Insert(pParse, yymsp[-3].minor.yy47, 0, yymsp[-2].minor.yy600, yymsp[-5].minor.yy192, 0); + sqlite3Insert(pParse, yymsp[-3].minor.yy47, 0, yymsp[-2].minor.yy600, yymsp[-5].minor.yy192, 0); } break; case 158: /* upsert ::= */ { yymsp[1].minor.yy318 = 0; } break; case 159: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO UPDATE SET setlist where_opt */ -{ yymsp[-10].minor.yy318 = tdsqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy242,yymsp[-5].minor.yy202,yymsp[-1].minor.yy242,yymsp[0].minor.yy202);} +{ yymsp[-10].minor.yy318 = sqlite3UpsertNew(pParse->db,yymsp[-7].minor.yy242,yymsp[-5].minor.yy202,yymsp[-1].minor.yy242,yymsp[0].minor.yy202);} break; case 160: /* upsert ::= ON CONFLICT LP sortlist RP where_opt DO NOTHING */ -{ yymsp[-7].minor.yy318 = tdsqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy242,yymsp[-2].minor.yy202,0,0); } +{ yymsp[-7].minor.yy318 = sqlite3UpsertNew(pParse->db,yymsp[-4].minor.yy242,yymsp[-2].minor.yy202,0,0); } break; case 161: /* upsert ::= ON CONFLICT DO NOTHING */ -{ yymsp[-3].minor.yy318 = tdsqlite3UpsertNew(pParse->db,0,0,0,0); } +{ yymsp[-3].minor.yy318 = sqlite3UpsertNew(pParse->db,0,0,0,0); } break; case 165: /* idlist_opt ::= LP idlist RP */ {yymsp[-2].minor.yy600 = yymsp[-1].minor.yy600;} break; case 166: /* idlist ::= idlist COMMA nm */ -{yymsp[-2].minor.yy600 = tdsqlite3IdListAppend(pParse,yymsp[-2].minor.yy600,&yymsp[0].minor.yy0);} +{yymsp[-2].minor.yy600 = sqlite3IdListAppend(pParse,yymsp[-2].minor.yy600,&yymsp[0].minor.yy0);} break; case 167: /* idlist ::= nm */ -{yymsp[0].minor.yy600 = tdsqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} +{yymsp[0].minor.yy600 = sqlite3IdListAppend(pParse,0,&yymsp[0].minor.yy0); /*A-overwrites-Y*/} break; case 168: /* expr ::= LP expr RP */ {yymsp[-2].minor.yy202 = yymsp[-1].minor.yy202;} @@ -159925,27 +159925,27 @@ static YYACTIONTYPE yy_reduce( break; case 171: /* expr ::= nm DOT nm */ { - Expr *temp1 = tdsqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp2 = tdsqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); + Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); + Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); - tdsqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); + sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[0].minor.yy0); + sqlite3RenameTokenMap(pParse, (void*)temp1, &yymsp[-2].minor.yy0); } - yylhsminor.yy202 = tdsqlite3PExpr(pParse, TK_DOT, temp1, temp2); + yylhsminor.yy202 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2); } yymsp[-2].minor.yy202 = yylhsminor.yy202; break; case 172: /* expr ::= nm DOT nm DOT nm */ { - Expr *temp1 = tdsqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1); - Expr *temp2 = tdsqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); - Expr *temp3 = tdsqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); - Expr *temp4 = tdsqlite3PExpr(pParse, TK_DOT, temp2, temp3); + Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-4].minor.yy0, 1); + Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[-2].minor.yy0, 1); + Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &yymsp[0].minor.yy0, 1); + Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3); if( IN_RENAME_OBJECT ){ - tdsqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); - tdsqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); + sqlite3RenameTokenMap(pParse, (void*)temp3, &yymsp[0].minor.yy0); + sqlite3RenameTokenMap(pParse, (void*)temp2, &yymsp[-2].minor.yy0); } - yylhsminor.yy202 = tdsqlite3PExpr(pParse, TK_DOT, temp1, temp4); + yylhsminor.yy202 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4); } yymsp[-4].minor.yy202 = yylhsminor.yy202; break; @@ -159955,16 +159955,16 @@ static YYACTIONTYPE yy_reduce( break; case 175: /* term ::= INTEGER */ { - yylhsminor.yy202 = tdsqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); + yylhsminor.yy202 = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &yymsp[0].minor.yy0, 1); } yymsp[0].minor.yy202 = yylhsminor.yy202; break; case 176: /* expr ::= VARIABLE */ { - if( !(yymsp[0].minor.yy0.z[0]=='#' && tdsqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ + if( !(yymsp[0].minor.yy0.z[0]=='#' && sqlite3Isdigit(yymsp[0].minor.yy0.z[1])) ){ u32 n = yymsp[0].minor.yy0.n; yymsp[0].minor.yy202 = tokenExpr(pParse, TK_VARIABLE, yymsp[0].minor.yy0); - tdsqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy202, n); + sqlite3ExprAssignVarNumber(pParse, yymsp[0].minor.yy202, n); }else{ /* When doing a nested parse, one can include terms in an expression ** that look like this: #1 #2 ... These terms refer to registers @@ -159972,74 +159972,74 @@ static YYACTIONTYPE yy_reduce( Token t = yymsp[0].minor.yy0; /*A-overwrites-X*/ assert( t.n>=2 ); if( pParse->nested==0 ){ - tdsqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t); yymsp[0].minor.yy202 = 0; }else{ - yymsp[0].minor.yy202 = tdsqlite3PExpr(pParse, TK_REGISTER, 0, 0); - if( yymsp[0].minor.yy202 ) tdsqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy202->iTable); + yymsp[0].minor.yy202 = sqlite3PExpr(pParse, TK_REGISTER, 0, 0); + if( yymsp[0].minor.yy202 ) sqlite3GetInt32(&t.z[1], &yymsp[0].minor.yy202->iTable); } } } break; case 177: /* expr ::= expr COLLATE ID|STRING */ { - yymsp[-2].minor.yy202 = tdsqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy202, &yymsp[0].minor.yy0, 1); + yymsp[-2].minor.yy202 = sqlite3ExprAddCollateToken(pParse, yymsp[-2].minor.yy202, &yymsp[0].minor.yy0, 1); } break; case 178: /* expr ::= CAST LP expr AS typetoken RP */ { - yymsp[-5].minor.yy202 = tdsqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); - tdsqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy202, yymsp[-3].minor.yy202, 0); + yymsp[-5].minor.yy202 = sqlite3ExprAlloc(pParse->db, TK_CAST, &yymsp[-1].minor.yy0, 1); + sqlite3ExprAttachSubtrees(pParse->db, yymsp[-5].minor.yy202, yymsp[-3].minor.yy202, 0); } break; case 179: /* expr ::= ID|INDEXED LP distinct exprlist RP */ { - yylhsminor.yy202 = tdsqlite3ExprFunction(pParse, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy192); + yylhsminor.yy202 = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0, yymsp[-2].minor.yy192); } yymsp[-4].minor.yy202 = yylhsminor.yy202; break; case 180: /* expr ::= ID|INDEXED LP STAR RP */ { - yylhsminor.yy202 = tdsqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); + yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0, 0); } yymsp[-3].minor.yy202 = yylhsminor.yy202; break; case 181: /* expr ::= ID|INDEXED LP distinct exprlist RP filter_over */ { - yylhsminor.yy202 = tdsqlite3ExprFunction(pParse, yymsp[-2].minor.yy242, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy192); - tdsqlite3WindowAttach(pParse, yylhsminor.yy202, yymsp[0].minor.yy303); + yylhsminor.yy202 = sqlite3ExprFunction(pParse, yymsp[-2].minor.yy242, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy192); + sqlite3WindowAttach(pParse, yylhsminor.yy202, yymsp[0].minor.yy303); } yymsp[-5].minor.yy202 = yylhsminor.yy202; break; case 182: /* expr ::= ID|INDEXED LP STAR RP filter_over */ { - yylhsminor.yy202 = tdsqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); - tdsqlite3WindowAttach(pParse, yylhsminor.yy202, yymsp[0].minor.yy303); + yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[-4].minor.yy0, 0); + sqlite3WindowAttach(pParse, yylhsminor.yy202, yymsp[0].minor.yy303); } yymsp[-4].minor.yy202 = yylhsminor.yy202; break; case 183: /* term ::= CTIME_KW */ { - yylhsminor.yy202 = tdsqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); + yylhsminor.yy202 = sqlite3ExprFunction(pParse, 0, &yymsp[0].minor.yy0, 0); } yymsp[0].minor.yy202 = yylhsminor.yy202; break; case 184: /* expr ::= LP nexprlist COMMA expr RP */ { - ExprList *pList = tdsqlite3ExprListAppend(pParse, yymsp[-3].minor.yy242, yymsp[-1].minor.yy202); - yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_VECTOR, 0, 0); + ExprList *pList = sqlite3ExprListAppend(pParse, yymsp[-3].minor.yy242, yymsp[-1].minor.yy202); + yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); if( yymsp[-4].minor.yy202 ){ yymsp[-4].minor.yy202->x.pList = pList; if( ALWAYS(pList->nExpr) ){ yymsp[-4].minor.yy202->flags |= pList->a[0].pExpr->flags & EP_Propagate; } }else{ - tdsqlite3ExprListDelete(pParse->db, pList); + sqlite3ExprListDelete(pParse->db, pList); } } break; case 185: /* expr ::= expr AND expr */ -{yymsp[-2].minor.yy202=tdsqlite3ExprAnd(pParse,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} +{yymsp[-2].minor.yy202=sqlite3ExprAnd(pParse,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} break; case 186: /* expr ::= expr OR expr */ case 187: /* expr ::= expr LT|GT|GE|LE expr */ yytestcase(yyruleno==187); @@ -160048,7 +160048,7 @@ static YYACTIONTYPE yy_reduce( case 190: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==190); case 191: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==191); case 192: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==192); -{yymsp[-2].minor.yy202=tdsqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} +{yymsp[-2].minor.yy202=sqlite3PExpr(pParse,yymsp[-1].major,yymsp[-2].minor.yy202,yymsp[0].minor.yy202);} break; case 193: /* likeop ::= NOT LIKE_KW|MATCH */ {yymsp[-1].minor.yy0=yymsp[0].minor.yy0; yymsp[-1].minor.yy0.n|=0x80000000; /*yymsp[-1].minor.yy0-overwrite-yymsp[0].minor.yy0*/} @@ -160058,10 +160058,10 @@ static YYACTIONTYPE yy_reduce( ExprList *pList; int bNot = yymsp[-1].minor.yy0.n & 0x80000000; yymsp[-1].minor.yy0.n &= 0x7fffffff; - pList = tdsqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy202); - pList = tdsqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy202); - yymsp[-2].minor.yy202 = tdsqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); - if( bNot ) yymsp[-2].minor.yy202 = tdsqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy202, 0); + pList = sqlite3ExprListAppend(pParse,0, yymsp[0].minor.yy202); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-2].minor.yy202); + yymsp[-2].minor.yy202 = sqlite3ExprFunction(pParse, pList, &yymsp[-1].minor.yy0, 0); + if( bNot ) yymsp[-2].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-2].minor.yy202, 0); if( yymsp[-2].minor.yy202 ) yymsp[-2].minor.yy202->flags |= EP_InfixFunc; } break; @@ -160070,39 +160070,39 @@ static YYACTIONTYPE yy_reduce( ExprList *pList; int bNot = yymsp[-3].minor.yy0.n & 0x80000000; yymsp[-3].minor.yy0.n &= 0x7fffffff; - pList = tdsqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); - pList = tdsqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy202); - pList = tdsqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy202); - yymsp[-4].minor.yy202 = tdsqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); - if( bNot ) yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-4].minor.yy202); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy202); + yymsp[-4].minor.yy202 = sqlite3ExprFunction(pParse, pList, &yymsp[-3].minor.yy0, 0); + if( bNot ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); if( yymsp[-4].minor.yy202 ) yymsp[-4].minor.yy202->flags |= EP_InfixFunc; } break; case 196: /* expr ::= expr ISNULL|NOTNULL */ -{yymsp[-1].minor.yy202 = tdsqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy202,0);} +{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse,yymsp[0].major,yymsp[-1].minor.yy202,0);} break; case 197: /* expr ::= expr NOT NULL */ -{yymsp[-2].minor.yy202 = tdsqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy202,0);} +{yymsp[-2].minor.yy202 = sqlite3PExpr(pParse,TK_NOTNULL,yymsp[-2].minor.yy202,0);} break; case 198: /* expr ::= expr IS expr */ { - yymsp[-2].minor.yy202 = tdsqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy202,yymsp[0].minor.yy202); + yymsp[-2].minor.yy202 = sqlite3PExpr(pParse,TK_IS,yymsp[-2].minor.yy202,yymsp[0].minor.yy202); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy202, yymsp[-2].minor.yy202, TK_ISNULL); } break; case 199: /* expr ::= expr IS NOT expr */ { - yymsp[-3].minor.yy202 = tdsqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy202,yymsp[0].minor.yy202); + yymsp[-3].minor.yy202 = sqlite3PExpr(pParse,TK_ISNOT,yymsp[-3].minor.yy202,yymsp[0].minor.yy202); binaryToUnaryIfNull(pParse, yymsp[0].minor.yy202, yymsp[-3].minor.yy202, TK_NOTNULL); } break; case 200: /* expr ::= NOT expr */ case 201: /* expr ::= BITNOT expr */ yytestcase(yyruleno==201); -{yymsp[-1].minor.yy202 = tdsqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy202, 0);/*A-overwrites-B*/} +{yymsp[-1].minor.yy202 = sqlite3PExpr(pParse, yymsp[-1].major, yymsp[0].minor.yy202, 0);/*A-overwrites-B*/} break; case 202: /* expr ::= PLUS|MINUS expr */ { - yymsp[-1].minor.yy202 = tdsqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy202, 0); + yymsp[-1].minor.yy202 = sqlite3PExpr(pParse, yymsp[-1].major==TK_PLUS ? TK_UPLUS : TK_UMINUS, yymsp[0].minor.yy202, 0); /*A-overwrites-B*/ } break; @@ -160112,15 +160112,15 @@ static YYACTIONTYPE yy_reduce( break; case 205: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = tdsqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); - pList = tdsqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy202); - yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy202, 0); + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy202); + yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy202, 0); if( yymsp[-4].minor.yy202 ){ yymsp[-4].minor.yy202->x.pList = pList; }else{ - tdsqlite3ExprListDelete(pParse->db, pList); + sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); } break; case 208: /* expr ::= expr in_op LP exprlist RP */ @@ -160134,82 +160134,82 @@ static YYACTIONTYPE yy_reduce( ** simplify to constants 0 (false) and 1 (true), respectively, ** regardless of the value of expr1. */ - tdsqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy202); - yymsp[-4].minor.yy202 = tdsqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy192 ? "1" : "0"); + sqlite3ExprUnmapAndDelete(pParse, yymsp[-4].minor.yy202); + yymsp[-4].minor.yy202 = sqlite3Expr(pParse->db, TK_INTEGER, yymsp[-3].minor.yy192 ? "1" : "0"); }else{ - yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); + yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); if( yymsp[-4].minor.yy202 ){ yymsp[-4].minor.yy202->x.pList = yymsp[-1].minor.yy242; - tdsqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202); + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202); }else{ - tdsqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy242); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy242); } - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); } } break; case 209: /* expr ::= LP select RP */ { - yymsp[-2].minor.yy202 = tdsqlite3PExpr(pParse, TK_SELECT, 0, 0); - tdsqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy202, yymsp[-1].minor.yy539); + yymsp[-2].minor.yy202 = sqlite3PExpr(pParse, TK_SELECT, 0, 0); + sqlite3PExprAddSelect(pParse, yymsp[-2].minor.yy202, yymsp[-1].minor.yy539); } break; case 210: /* expr ::= expr in_op LP select RP */ { - yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); - tdsqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy202, yymsp[-1].minor.yy539); - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy202, yymsp[-1].minor.yy539); + if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); } break; case 211: /* expr ::= expr in_op nm dbnm paren_exprlist */ { - SrcList *pSrc = tdsqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); - Select *pSelect = tdsqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); - if( yymsp[0].minor.yy242 ) tdsqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy242); - yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); - tdsqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy202, pSelect); - if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); + SrcList *pSrc = sqlite3SrcListAppend(pParse, 0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); + Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0); + if( yymsp[0].minor.yy242 ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, yymsp[0].minor.yy242); + yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy202, 0); + sqlite3PExprAddSelect(pParse, yymsp[-4].minor.yy202, pSelect); + if( yymsp[-3].minor.yy192 ) yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_NOT, yymsp[-4].minor.yy202, 0); } break; case 212: /* expr ::= EXISTS LP select RP */ { Expr *p; - p = yymsp[-3].minor.yy202 = tdsqlite3PExpr(pParse, TK_EXISTS, 0, 0); - tdsqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy539); + p = yymsp[-3].minor.yy202 = sqlite3PExpr(pParse, TK_EXISTS, 0, 0); + sqlite3PExprAddSelect(pParse, p, yymsp[-1].minor.yy539); } break; case 213: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yymsp[-4].minor.yy202 = tdsqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy202, 0); + yymsp[-4].minor.yy202 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy202, 0); if( yymsp[-4].minor.yy202 ){ - yymsp[-4].minor.yy202->x.pList = yymsp[-1].minor.yy202 ? tdsqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[-1].minor.yy202) : yymsp[-2].minor.yy242; - tdsqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202); + yymsp[-4].minor.yy202->x.pList = yymsp[-1].minor.yy202 ? sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[-1].minor.yy202) : yymsp[-2].minor.yy242; + sqlite3ExprSetHeightAndFlags(pParse, yymsp[-4].minor.yy202); }else{ - tdsqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy242); - tdsqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy202); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy242); + sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy202); } } break; case 214: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yymsp[-4].minor.yy242 = tdsqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[-2].minor.yy202); - yymsp[-4].minor.yy242 = tdsqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[0].minor.yy202); + yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[-2].minor.yy202); + yymsp[-4].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy242, yymsp[0].minor.yy202); } break; case 215: /* case_exprlist ::= WHEN expr THEN expr */ { - yymsp[-3].minor.yy242 = tdsqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); - yymsp[-3].minor.yy242 = tdsqlite3ExprListAppend(pParse,yymsp[-3].minor.yy242, yymsp[0].minor.yy202); + yymsp[-3].minor.yy242 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy202); + yymsp[-3].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy242, yymsp[0].minor.yy202); } break; case 218: /* case_operand ::= expr */ {yymsp[0].minor.yy202 = yymsp[0].minor.yy202; /*A-overwrites-X*/} break; case 221: /* nexprlist ::= nexprlist COMMA expr */ -{yymsp[-2].minor.yy242 = tdsqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[0].minor.yy202);} +{yymsp[-2].minor.yy242 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy242,yymsp[0].minor.yy202);} break; case 222: /* nexprlist ::= expr */ -{yymsp[0].minor.yy242 = tdsqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy202); /*A-overwrites-Y*/} +{yymsp[0].minor.yy242 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy202); /*A-overwrites-Y*/} break; case 224: /* paren_exprlist ::= LP exprlist RP */ case 229: /* eidlist_opt ::= LP eidlist RP */ yytestcase(yyruleno==229); @@ -160217,11 +160217,11 @@ static YYACTIONTYPE yy_reduce( break; case 225: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP sortlist RP where_opt */ { - tdsqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, - tdsqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy242, yymsp[-10].minor.yy192, + sqlite3CreateIndex(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, + sqlite3SrcListAppend(pParse,0,&yymsp[-4].minor.yy0,0), yymsp[-2].minor.yy242, yymsp[-10].minor.yy192, &yymsp[-11].minor.yy0, yymsp[0].minor.yy202, SQLITE_SO_ASC, yymsp[-8].minor.yy192, SQLITE_IDXTYPE_APPDEF); if( IN_RENAME_OBJECT && pParse->pNewIndex ){ - tdsqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); + sqlite3RenameTokenMap(pParse, pParse->pNewIndex->zName, &yymsp[-4].minor.yy0); } } break; @@ -160243,40 +160243,40 @@ static YYACTIONTYPE yy_reduce( } break; case 234: /* cmd ::= DROP INDEX ifexists fullname */ -{tdsqlite3DropIndex(pParse, yymsp[0].minor.yy47, yymsp[-1].minor.yy192);} +{sqlite3DropIndex(pParse, yymsp[0].minor.yy47, yymsp[-1].minor.yy192);} break; case 235: /* cmd ::= VACUUM vinto */ -{tdsqlite3Vacuum(pParse,0,yymsp[0].minor.yy202);} +{sqlite3Vacuum(pParse,0,yymsp[0].minor.yy202);} break; case 236: /* cmd ::= VACUUM nm vinto */ -{tdsqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy202);} +{sqlite3Vacuum(pParse,&yymsp[-1].minor.yy0,yymsp[0].minor.yy202);} break; case 239: /* cmd ::= PRAGMA nm dbnm */ -{tdsqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} +{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);} break; case 240: /* cmd ::= PRAGMA nm dbnm EQ nmnum */ -{tdsqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);} break; case 241: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */ -{tdsqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);} break; case 242: /* cmd ::= PRAGMA nm dbnm EQ minus_num */ -{tdsqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} +{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);} break; case 243: /* cmd ::= PRAGMA nm dbnm LP minus_num RP */ -{tdsqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} +{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,1);} break; case 246: /* cmd ::= createkw trigger_decl BEGIN trigger_cmd_list END */ { Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - tdsqlite3FinishTrigger(pParse, yymsp[-1].minor.yy447, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy447, &all); } break; case 247: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - tdsqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy192, yymsp[-4].minor.yy230.a, yymsp[-4].minor.yy230.b, yymsp[-2].minor.yy47, yymsp[0].minor.yy202, yymsp[-10].minor.yy192, yymsp[-8].minor.yy192); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy192, yymsp[-4].minor.yy230.a, yymsp[-4].minor.yy230.b, yymsp[-2].minor.yy47, yymsp[0].minor.yy202, yymsp[-10].minor.yy192, yymsp[-8].minor.yy192); yymsp[-10].minor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); /*A-overwrites-T*/ } break; @@ -160320,46 +160320,46 @@ static YYACTIONTYPE yy_reduce( case 258: /* trnm ::= nm DOT nm */ { yymsp[-2].minor.yy0 = yymsp[0].minor.yy0; - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "qualified table names are not allowed on INSERT, UPDATE, and DELETE " "statements within triggers"); } break; case 259: /* tridxby ::= INDEXED BY nm */ { - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; case 260: /* tridxby ::= NOT INDEXED */ { - tdsqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " "within triggers"); } break; case 261: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt scanpt */ -{yylhsminor.yy447 = tdsqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy242, yymsp[-1].minor.yy202, yymsp[-6].minor.yy192, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy436);} +{yylhsminor.yy447 = sqlite3TriggerUpdateStep(pParse, &yymsp[-5].minor.yy0, yymsp[-2].minor.yy242, yymsp[-1].minor.yy202, yymsp[-6].minor.yy192, yymsp[-7].minor.yy0.z, yymsp[0].minor.yy436);} yymsp[-7].minor.yy447 = yylhsminor.yy447; break; case 262: /* trigger_cmd ::= scanpt insert_cmd INTO trnm idlist_opt select upsert scanpt */ { - yylhsminor.yy447 = tdsqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy600,yymsp[-2].minor.yy539,yymsp[-6].minor.yy192,yymsp[-1].minor.yy318,yymsp[-7].minor.yy436,yymsp[0].minor.yy436);/*yylhsminor.yy447-overwrites-yymsp[-6].minor.yy192*/ + yylhsminor.yy447 = sqlite3TriggerInsertStep(pParse,&yymsp[-4].minor.yy0,yymsp[-3].minor.yy600,yymsp[-2].minor.yy539,yymsp[-6].minor.yy192,yymsp[-1].minor.yy318,yymsp[-7].minor.yy436,yymsp[0].minor.yy436);/*yylhsminor.yy447-overwrites-yymsp[-6].minor.yy192*/ } yymsp[-7].minor.yy447 = yylhsminor.yy447; break; case 263: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt scanpt */ -{yylhsminor.yy447 = tdsqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy202, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy436);} +{yylhsminor.yy447 = sqlite3TriggerDeleteStep(pParse, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy202, yymsp[-5].minor.yy0.z, yymsp[0].minor.yy436);} yymsp[-5].minor.yy447 = yylhsminor.yy447; break; case 264: /* trigger_cmd ::= scanpt select scanpt */ -{yylhsminor.yy447 = tdsqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy539, yymsp[-2].minor.yy436, yymsp[0].minor.yy436); /*yylhsminor.yy447-overwrites-yymsp[-1].minor.yy539*/} +{yylhsminor.yy447 = sqlite3TriggerSelectStep(pParse->db, yymsp[-1].minor.yy539, yymsp[-2].minor.yy436, yymsp[0].minor.yy436); /*yylhsminor.yy447-overwrites-yymsp[-1].minor.yy539*/} yymsp[-2].minor.yy447 = yylhsminor.yy447; break; case 265: /* expr ::= RAISE LP IGNORE RP */ { - yymsp[-3].minor.yy202 = tdsqlite3PExpr(pParse, TK_RAISE, 0, 0); + yymsp[-3].minor.yy202 = sqlite3PExpr(pParse, TK_RAISE, 0, 0); if( yymsp[-3].minor.yy202 ){ yymsp[-3].minor.yy202->affExpr = OE_Ignore; } @@ -160367,7 +160367,7 @@ static YYACTIONTYPE yy_reduce( break; case 266: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yymsp[-5].minor.yy202 = tdsqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); + yymsp[-5].minor.yy202 = sqlite3ExprAlloc(pParse->db, TK_RAISE, &yymsp[-1].minor.yy0, 1); if( yymsp[-5].minor.yy202 ) { yymsp[-5].minor.yy202->affExpr = (char)yymsp[-3].minor.yy192; } @@ -160381,84 +160381,84 @@ static YYACTIONTYPE yy_reduce( break; case 270: /* cmd ::= DROP TRIGGER ifexists fullname */ { - tdsqlite3DropTrigger(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy192); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy47,yymsp[-1].minor.yy192); } break; case 271: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - tdsqlite3Attach(pParse, yymsp[-3].minor.yy202, yymsp[-1].minor.yy202, yymsp[0].minor.yy202); + sqlite3Attach(pParse, yymsp[-3].minor.yy202, yymsp[-1].minor.yy202, yymsp[0].minor.yy202); } break; case 272: /* cmd ::= DETACH database_kw_opt expr */ { - tdsqlite3Detach(pParse, yymsp[0].minor.yy202); + sqlite3Detach(pParse, yymsp[0].minor.yy202); } break; case 275: /* cmd ::= REINDEX */ -{tdsqlite3Reindex(pParse, 0, 0);} +{sqlite3Reindex(pParse, 0, 0);} break; case 276: /* cmd ::= REINDEX nm dbnm */ -{tdsqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} +{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; case 277: /* cmd ::= ANALYZE */ -{tdsqlite3Analyze(pParse, 0, 0);} +{sqlite3Analyze(pParse, 0, 0);} break; case 278: /* cmd ::= ANALYZE nm dbnm */ -{tdsqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} +{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; case 279: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - tdsqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy47,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy47,&yymsp[0].minor.yy0); } break; case 280: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt columnname carglist */ { yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n; - tdsqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); + sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0); } break; case 281: /* add_column_fullname ::= fullname */ { disableLookaside(pParse); - tdsqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy47); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy47); } break; case 282: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */ { - tdsqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy47, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); + sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy47, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; case 283: /* cmd ::= create_vtab */ -{tdsqlite3VtabFinishParse(pParse,0);} +{sqlite3VtabFinishParse(pParse,0);} break; case 284: /* cmd ::= create_vtab LP vtabarglist RP */ -{tdsqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} +{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; case 285: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */ { - tdsqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy192); + sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy192); } break; case 286: /* vtabarg ::= */ -{tdsqlite3VtabArgInit(pParse);} +{sqlite3VtabArgInit(pParse);} break; case 287: /* vtabargtoken ::= ANY */ case 288: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==288); case 289: /* lp ::= LP */ yytestcase(yyruleno==289); -{tdsqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} +{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; case 290: /* with ::= WITH wqlist */ case 291: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==291); -{ tdsqlite3WithPush(pParse, yymsp[0].minor.yy131, 1); } +{ sqlite3WithPush(pParse, yymsp[0].minor.yy131, 1); } break; case 292: /* wqlist ::= nm eidlist_opt AS LP select RP */ { - yymsp[-5].minor.yy131 = tdsqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy242, yymsp[-1].minor.yy539); /*A-overwrites-X*/ + yymsp[-5].minor.yy131 = sqlite3WithAdd(pParse, 0, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy242, yymsp[-1].minor.yy539); /*A-overwrites-X*/ } break; case 293: /* wqlist ::= wqlist COMMA nm eidlist_opt AS LP select RP */ { - yymsp[-7].minor.yy131 = tdsqlite3WithAdd(pParse, yymsp[-7].minor.yy131, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy242, yymsp[-1].minor.yy539); + yymsp[-7].minor.yy131 = sqlite3WithAdd(pParse, yymsp[-7].minor.yy131, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy242, yymsp[-1].minor.yy539); } break; case 294: /* windowdefn_list ::= windowdefn */ @@ -160468,7 +160468,7 @@ static YYACTIONTYPE yy_reduce( case 295: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */ { assert( yymsp[0].minor.yy303!=0 ); - tdsqlite3WindowChain(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy303); + sqlite3WindowChain(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy303); yymsp[0].minor.yy303->pNextWin = yymsp[-2].minor.yy303; yylhsminor.yy303 = yymsp[0].minor.yy303; } @@ -160477,7 +160477,7 @@ static YYACTIONTYPE yy_reduce( case 296: /* windowdefn ::= nm AS LP window RP */ { if( ALWAYS(yymsp[-1].minor.yy303) ){ - yymsp[-1].minor.yy303->zName = tdsqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); + yymsp[-1].minor.yy303->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n); } yylhsminor.yy303 = yymsp[-1].minor.yy303; } @@ -160485,23 +160485,23 @@ static YYACTIONTYPE yy_reduce( break; case 297: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */ { - yymsp[-4].minor.yy303 = tdsqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy242, yymsp[-1].minor.yy242, 0); + yymsp[-4].minor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy242, yymsp[-1].minor.yy242, 0); } break; case 298: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */ { - yylhsminor.yy303 = tdsqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy242, yymsp[-1].minor.yy242, &yymsp[-5].minor.yy0); + yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, yymsp[-2].minor.yy242, yymsp[-1].minor.yy242, &yymsp[-5].minor.yy0); } yymsp[-5].minor.yy303 = yylhsminor.yy303; break; case 299: /* window ::= ORDER BY sortlist frame_opt */ { - yymsp[-3].minor.yy303 = tdsqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, yymsp[-1].minor.yy242, 0); + yymsp[-3].minor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, yymsp[-1].minor.yy242, 0); } break; case 300: /* window ::= nm ORDER BY sortlist frame_opt */ { - yylhsminor.yy303 = tdsqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0); + yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, yymsp[-1].minor.yy242, &yymsp[-4].minor.yy0); } yymsp[-4].minor.yy303 = yylhsminor.yy303; break; @@ -160514,24 +160514,24 @@ static YYACTIONTYPE yy_reduce( break; case 302: /* window ::= nm frame_opt */ { - yylhsminor.yy303 = tdsqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, 0, &yymsp[-1].minor.yy0); + yylhsminor.yy303 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy303, 0, 0, &yymsp[-1].minor.yy0); } yymsp[-1].minor.yy303 = yylhsminor.yy303; break; case 303: /* frame_opt ::= */ { - yymsp[1].minor.yy303 = tdsqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); + yymsp[1].minor.yy303 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0); } break; case 304: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */ { - yylhsminor.yy303 = tdsqlite3WindowAlloc(pParse, yymsp[-2].minor.yy192, yymsp[-1].minor.yy77.eType, yymsp[-1].minor.yy77.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy58); + yylhsminor.yy303 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy192, yymsp[-1].minor.yy77.eType, yymsp[-1].minor.yy77.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy58); } yymsp[-2].minor.yy303 = yylhsminor.yy303; break; case 305: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */ { - yylhsminor.yy303 = tdsqlite3WindowAlloc(pParse, yymsp[-5].minor.yy192, yymsp[-3].minor.yy77.eType, yymsp[-3].minor.yy77.pExpr, yymsp[-1].minor.yy77.eType, yymsp[-1].minor.yy77.pExpr, yymsp[0].minor.yy58); + yylhsminor.yy303 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy192, yymsp[-3].minor.yy77.eType, yymsp[-3].minor.yy77.pExpr, yymsp[-1].minor.yy77.eType, yymsp[-1].minor.yy77.pExpr, yymsp[0].minor.yy58); } yymsp[-5].minor.yy303 = yylhsminor.yy303; break; @@ -160575,12 +160575,12 @@ static YYACTIONTYPE yy_reduce( break; case 321: /* filter_over ::= filter_clause */ { - yylhsminor.yy303 = (Window*)tdsqlite3DbMallocZero(pParse->db, sizeof(Window)); + yylhsminor.yy303 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( yylhsminor.yy303 ){ yylhsminor.yy303->eFrmType = TK_FILTER; yylhsminor.yy303->pFilter = yymsp[0].minor.yy202; }else{ - tdsqlite3ExprDelete(pParse->db, yymsp[0].minor.yy202); + sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy202); } } yymsp[0].minor.yy303 = yylhsminor.yy303; @@ -160593,9 +160593,9 @@ static YYACTIONTYPE yy_reduce( break; case 323: /* over_clause ::= OVER nm */ { - yymsp[-1].minor.yy303 = (Window*)tdsqlite3DbMallocZero(pParse->db, sizeof(Window)); + yymsp[-1].minor.yy303 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window)); if( yymsp[-1].minor.yy303 ){ - yymsp[-1].minor.yy303->zName = tdsqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); + yymsp[-1].minor.yy303->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n); } } break; @@ -160693,8 +160693,8 @@ static YYACTIONTYPE yy_reduce( static void yy_parse_failed( yyParser *yypParser /* The parser */ ){ - tdsqlite3ParserARG_FETCH - tdsqlite3ParserCTX_FETCH + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); @@ -160705,8 +160705,8 @@ static void yy_parse_failed( ** parser fails */ /************ Begin %parse_failure code ***************************************/ /************ End %parse_failure code *****************************************/ - tdsqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ - tdsqlite3ParserCTX_STORE + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE } #endif /* YYNOERRORRECOVERY */ @@ -160716,22 +160716,22 @@ static void yy_parse_failed( static void yy_syntax_error( yyParser *yypParser, /* The parser */ int yymajor, /* The major type of the error token */ - tdsqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */ + sqlite3ParserTOKENTYPE yyminor /* The minor type of the error token */ ){ - tdsqlite3ParserARG_FETCH - tdsqlite3ParserCTX_FETCH + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH #define TOKEN yyminor /************ Begin %syntax_error code ****************************************/ UNUSED_PARAMETER(yymajor); /* Silence some compiler warnings */ if( TOKEN.z[0] ){ - tdsqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); + sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN); }else{ - tdsqlite3ErrorMsg(pParse, "incomplete input"); + sqlite3ErrorMsg(pParse, "incomplete input"); } /************ End %syntax_error code ******************************************/ - tdsqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ - tdsqlite3ParserCTX_STORE + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE } /* @@ -160740,8 +160740,8 @@ static void yy_syntax_error( static void yy_accept( yyParser *yypParser /* The parser */ ){ - tdsqlite3ParserARG_FETCH - tdsqlite3ParserCTX_FETCH + sqlite3ParserARG_FETCH + sqlite3ParserCTX_FETCH #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); @@ -160755,13 +160755,13 @@ static void yy_accept( ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ /*********** End %parse_accept code *******************************************/ - tdsqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ - tdsqlite3ParserCTX_STORE + sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3ParserCTX_STORE } /* The main parser program. ** The first argument is a pointer to a structure obtained from -** "tdsqlite3ParserAlloc" which describes the current state of the parser. +** "sqlite3ParserAlloc" which describes the current state of the parser. ** The second argument is the major token number. The third is ** the minor token. The fourth optional argument is whatever the ** user wants (and specified in the grammar) and is available for @@ -160778,11 +160778,11 @@ static void yy_accept( ** Outputs: ** None. */ -SQLITE_PRIVATE void tdsqlite3Parser( +SQLITE_PRIVATE void sqlite3Parser( void *yyp, /* The parser */ int yymajor, /* The major token code number */ - tdsqlite3ParserTOKENTYPE yyminor /* The value for the token */ - tdsqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ + sqlite3ParserTOKENTYPE yyminor /* The value for the token */ + sqlite3ParserARG_PDECL /* Optional %extra_argument parameter */ ){ YYMINORTYPE yyminorunion; YYACTIONTYPE yyact; /* The parser action. */ @@ -160793,8 +160793,8 @@ SQLITE_PRIVATE void tdsqlite3Parser( int yyerrorhit = 0; /* True if yymajor has invoked an error */ #endif yyParser *yypParser = (yyParser*)yyp; /* The parser */ - tdsqlite3ParserCTX_FETCH - tdsqlite3ParserARG_STORE + sqlite3ParserCTX_FETCH + sqlite3ParserARG_STORE assert( yypParser->yytos!=0 ); #if !defined(YYERRORSYMBOL) && !defined(YYNOERRORRECOVERY) @@ -160819,7 +160819,7 @@ SQLITE_PRIVATE void tdsqlite3Parser( yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact); if( yyact >= YY_MIN_REDUCE ){ yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor, - yyminor tdsqlite3ParserCTX_PARAM); + yyminor sqlite3ParserCTX_PARAM); }else if( yyact <= YY_MAX_SHIFTREDUCE ){ yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor); #ifndef YYNOERRORRECOVERY @@ -160952,7 +160952,7 @@ SQLITE_PRIVATE void tdsqlite3Parser( ** Return the fallback token corresponding to canonical token iToken, or ** 0 if iToken has no fallback. */ -SQLITE_PRIVATE int tdsqlite3ParserFallback(int iToken){ +SQLITE_PRIVATE int sqlite3ParserFallback(int iToken){ #ifdef YYFALLBACK assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); return yyFallback[iToken]; @@ -160986,7 +160986,7 @@ SQLITE_PRIVATE int tdsqlite3ParserFallback(int iToken){ /* Character classes for tokenizing ** -** In the tdsqlite3GetToken() function, a switch() on aiClass[c] is implemented +** In the sqlite3GetToken() function, a switch() on aiClass[c] is implemented ** using a lookup table, whereas a switch() directly on c uses a binary search. ** The lookup table is much faster. To maximize speed, and to ensure that ** a lookup table is used, all of the classes need to be small integers and @@ -161073,7 +161073,7 @@ static const unsigned char aiClass[] = { ** Used by keywordhash.h */ #ifdef SQLITE_ASCII -# define charMap(X) tdsqlite3UpperToLower[(unsigned char)X] +# define charMap(X) sqlite3UpperToLower[(unsigned char)X] #endif #ifdef SQLITE_EBCDIC # define charMap(X) ebcdicToAscii[(unsigned char)X] @@ -161099,7 +161099,7 @@ const unsigned char ebcdicToAscii[] = { #endif /* -** The tdsqlite3KeywordCode function looks up an identifier to determine if +** The sqlite3KeywordCode function looks up an identifier to determine if ** it is a keyword. If it is a keyword, the token code of that keyword is ** returned. If the input is not a keyword, TK_ID is returned. ** @@ -161567,21 +161567,21 @@ static int keywordCode(const char *z, int n, int *pType){ } return n; } -SQLITE_PRIVATE int tdsqlite3KeywordCode(const unsigned char *z, int n){ +SQLITE_PRIVATE int sqlite3KeywordCode(const unsigned char *z, int n){ int id = TK_ID; keywordCode((char*)z, n, &id); return id; } #define SQLITE_N_KEYWORD 145 -SQLITE_API int tdsqlite3_keyword_name(int i,const char **pzName,int *pnName){ +SQLITE_API int sqlite3_keyword_name(int i,const char **pzName,int *pnName){ if( i<0 || i>=SQLITE_N_KEYWORD ) return SQLITE_ERROR; *pzName = zKWText + aKWOffset[i]; *pnName = aKWLen[i]; return SQLITE_OK; } -SQLITE_API int tdsqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; } -SQLITE_API int tdsqlite3_keyword_check(const char *zName, int nName){ - return TK_ID!=tdsqlite3KeywordCode((const u8*)zName, nName); +SQLITE_API int sqlite3_keyword_count(void){ return SQLITE_N_KEYWORD; } +SQLITE_API int sqlite3_keyword_check(const char *zName, int nName){ + return TK_ID!=sqlite3KeywordCode((const u8*)zName, nName); } /************** End of keywordhash.h *****************************************/ @@ -161594,7 +161594,7 @@ SQLITE_API int tdsqlite3_keyword_check(const char *zName, int nName){ ** ** For ASCII, any character with the high-order bit set is ** allowed in an identifier. For 7-bit characters, -** tdsqlite3IsIdChar[X] must be 1. +** sqlite3IsIdChar[X] must be 1. ** ** For EBCDIC, the rules are more complex but have the same ** end result. @@ -161605,10 +161605,10 @@ SQLITE_API int tdsqlite3_keyword_check(const char *zName, int nName){ ** But the feature is undocumented. */ #ifdef SQLITE_ASCII -#define IdChar(C) ((tdsqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) #endif #ifdef SQLITE_EBCDIC -SQLITE_PRIVATE const char tdsqlite3IsEbcdicIdChar[] = { +SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[] = { /* x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF */ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, /* 4x */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, /* 5x */ @@ -161623,11 +161623,11 @@ SQLITE_PRIVATE const char tdsqlite3IsEbcdicIdChar[] = { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* Ex */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, /* Fx */ }; -#define IdChar(C) (((c=C)>=0x42 && tdsqlite3IsEbcdicIdChar[c-0x40])) +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) #endif /* Make the IdChar function accessible from ctime.c and alter.c */ -SQLITE_PRIVATE int tdsqlite3IsIdChar(u8 c){ return IdChar(c); } +SQLITE_PRIVATE int sqlite3IsIdChar(u8 c){ return IdChar(c); } #ifndef SQLITE_OMIT_WINDOWFUNC /* @@ -161638,14 +161638,14 @@ static int getToken(const unsigned char **pz){ const unsigned char *z = *pz; int t; /* Token type to return */ do { - z += tdsqlite3GetToken(z, &t); + z += sqlite3GetToken(z, &t); }while( t==TK_SPACE ); if( t==TK_ID || t==TK_STRING || t==TK_JOIN_KW || t==TK_WINDOW || t==TK_OVER - || tdsqlite3ParserFallback(t)==TK_ID + || sqlite3ParserFallback(t)==TK_ID ){ t = TK_ID; } @@ -161710,7 +161710,7 @@ static int analyzeFilterKeyword(const unsigned char *z, int lastToken){ ** Return the length (in bytes) of the token that begins at z[0]. ** Store the token type in *tokenType before returning. */ -SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *z, int *tokenType){ +SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *z, int *tokenType){ int i, c; switch( aiClass[*z] ){ /* Switch on the character-class of the first byte ** of the token. See the comment on the CC_ defines @@ -161721,7 +161721,7 @@ SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *z, int *tokenType){ testcase( z[0]=='\n' ); testcase( z[0]=='\f' ); testcase( z[0]=='\r' ); - for(i=1; tdsqlite3Isspace(z[i]); i++){} + for(i=1; sqlite3Isspace(z[i]); i++){} *tokenType = TK_SPACE; return i; } @@ -161856,7 +161856,7 @@ SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *z, int *tokenType){ } case CC_DOT: { #ifndef SQLITE_OMIT_FLOATING_POINT - if( !tdsqlite3Isdigit(z[1]) ) + if( !sqlite3Isdigit(z[1]) ) #endif { *tokenType = TK_DOT; @@ -161872,25 +161872,25 @@ SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *z, int *tokenType){ testcase( z[0]=='9' ); *tokenType = TK_INTEGER; #ifndef SQLITE_OMIT_HEX_INTEGER - if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && tdsqlite3Isxdigit(z[2]) ){ - for(i=3; tdsqlite3Isxdigit(z[i]); i++){} + if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ + for(i=3; sqlite3Isxdigit(z[i]); i++){} return i; } #endif - for(i=0; tdsqlite3Isdigit(z[i]); i++){} + for(i=0; sqlite3Isdigit(z[i]); i++){} #ifndef SQLITE_OMIT_FLOATING_POINT if( z[i]=='.' ){ i++; - while( tdsqlite3Isdigit(z[i]) ){ i++; } + while( sqlite3Isdigit(z[i]) ){ i++; } *tokenType = TK_FLOAT; } if( (z[i]=='e' || z[i]=='E') && - ( tdsqlite3Isdigit(z[i+1]) - || ((z[i+1]=='+' || z[i+1]=='-') && tdsqlite3Isdigit(z[i+2])) + ( sqlite3Isdigit(z[i+1]) + || ((z[i+1]=='+' || z[i+1]=='-') && sqlite3Isdigit(z[i+2])) ) ){ i += 2; - while( tdsqlite3Isdigit(z[i]) ){ i++; } + while( sqlite3Isdigit(z[i]) ){ i++; } *tokenType = TK_FLOAT; } #endif @@ -161907,7 +161907,7 @@ SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *z, int *tokenType){ } case CC_VARNUM: { *tokenType = TK_VARIABLE; - for(i=1; tdsqlite3Isdigit(z[i]); i++){} + for(i=1; sqlite3Isdigit(z[i]); i++){} return i; } case CC_DOLLAR: @@ -161923,7 +161923,7 @@ SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *z, int *tokenType){ }else if( c=='(' && n>0 ){ do{ i++; - }while( (c=z[i])!=0 && !tdsqlite3Isspace(c) && c!=')' ); + }while( (c=z[i])!=0 && !sqlite3Isspace(c) && c!=')' ); if( c==')' ){ i++; }else{ @@ -161957,7 +161957,7 @@ SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *z, int *tokenType){ testcase( z[0]=='x' ); testcase( z[0]=='X' ); if( z[1]=='\'' ){ *tokenType = TK_BLOB; - for(i=2; tdsqlite3Isxdigit(z[i]); i++){} + for(i=2; sqlite3Isxdigit(z[i]); i++){} if( z[i]!='\'' || i%2 ){ *tokenType = TK_ILLEGAL; while( z[i] && z[i]!='\'' ){ i++; } @@ -161991,18 +161991,18 @@ SQLITE_PRIVATE int tdsqlite3GetToken(const unsigned char *z, int *tokenType){ ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs ** then an and attempt is made to write an error message into -** memory obtained from tdsqlite3_malloc() and to make *pzErrMsg point to that +** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that ** error message. */ -SQLITE_PRIVATE int tdsqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ +SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){ int nErr = 0; /* Number of errors encountered */ void *pEngine; /* The LEMON-generated LALR(1) parser */ int n = 0; /* Length of the next token token */ int tokenType; /* type of the next token */ int lastTokenParsed = -1; /* type of the previous token */ - tdsqlite3 *db = pParse->db; /* The database connection */ + sqlite3 *db = pParse->db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ -#ifdef tdsqlite3Parser_ENGINEALWAYSONSTACK +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK yyParser sEngine; /* Space to hold the Lemon-generated Parser object */ #endif VVA_ONLY( u8 startedWithOom = db->mallocFailed ); @@ -162018,18 +162018,18 @@ SQLITE_PRIVATE int tdsqlite3RunParser(Parse *pParse, const char *zSql, char **pz #ifdef SQLITE_DEBUG if( db->flags & SQLITE_ParserTrace ){ printf("parser: [[[%s]]]\n", zSql); - tdsqlite3ParserTrace(stdout, "parser: "); + sqlite3ParserTrace(stdout, "parser: "); }else{ - tdsqlite3ParserTrace(0, 0); + sqlite3ParserTrace(0, 0); } #endif -#ifdef tdsqlite3Parser_ENGINEALWAYSONSTACK +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK pEngine = &sEngine; - tdsqlite3ParserInit(pEngine, pParse); + sqlite3ParserInit(pEngine, pParse); #else - pEngine = tdsqlite3ParserAlloc(tdsqlite3Malloc, pParse); + pEngine = sqlite3ParserAlloc(sqlite3Malloc, pParse); if( pEngine==0 ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); return SQLITE_NOMEM_BKPT; } #endif @@ -162040,7 +162040,7 @@ SQLITE_PRIVATE int tdsqlite3RunParser(Parse *pParse, const char *zSql, char **pz pParse->pParentParse = db->pParse; db->pParse = pParse; while( 1 ){ - n = tdsqlite3GetToken((u8*)zSql, &tokenType); + n = sqlite3GetToken((u8*)zSql, &tokenType); mxSqlLen -= n; if( mxSqlLen<0 ){ pParse->rc = SQLITE_TOOBIG; @@ -162086,13 +162086,13 @@ SQLITE_PRIVATE int tdsqlite3RunParser(Parse *pParse, const char *zSql, char **pz tokenType = analyzeFilterKeyword((const u8*)&zSql[6], lastTokenParsed); #endif /* SQLITE_OMIT_WINDOWFUNC */ }else{ - tdsqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql); + sqlite3ErrorMsg(pParse, "unrecognized token: \"%.*s\"", n, zSql); break; } } pParse->sLastToken.z = zSql; pParse->sLastToken.n = n; - tdsqlite3Parser(pEngine, tokenType, pParse->sLastToken); + sqlite3Parser(pEngine, tokenType, pParse->sLastToken); lastTokenParsed = tokenType; zSql += n; assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom ); @@ -162100,45 +162100,45 @@ SQLITE_PRIVATE int tdsqlite3RunParser(Parse *pParse, const char *zSql, char **pz } assert( nErr==0 ); #ifdef YYTRACKMAXSTACKDEPTH - tdsqlite3_mutex_enter(tdsqlite3MallocMutex()); - tdsqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, - tdsqlite3ParserStackPeak(pEngine) + sqlite3_mutex_enter(sqlite3MallocMutex()); + sqlite3StatusHighwater(SQLITE_STATUS_PARSER_STACK, + sqlite3ParserStackPeak(pEngine) ); - tdsqlite3_mutex_leave(tdsqlite3MallocMutex()); + sqlite3_mutex_leave(sqlite3MallocMutex()); #endif /* YYDEBUG */ -#ifdef tdsqlite3Parser_ENGINEALWAYSONSTACK - tdsqlite3ParserFinalize(pEngine); +#ifdef sqlite3Parser_ENGINEALWAYSONSTACK + sqlite3ParserFinalize(pEngine); #else - tdsqlite3ParserFree(pEngine, tdsqlite3_free); + sqlite3ParserFree(pEngine, sqlite3_free); #endif if( db->mallocFailed ){ pParse->rc = SQLITE_NOMEM_BKPT; } if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){ - pParse->zErrMsg = tdsqlite3MPrintf(db, "%s", tdsqlite3ErrStr(pParse->rc)); + pParse->zErrMsg = sqlite3MPrintf(db, "%s", sqlite3ErrStr(pParse->rc)); } assert( pzErrMsg!=0 ); if( pParse->zErrMsg ){ *pzErrMsg = pParse->zErrMsg; - tdsqlite3_log(pParse->rc, "%s in \"%s\"", + sqlite3_log(pParse->rc, "%s in \"%s\"", *pzErrMsg, pParse->zTail); pParse->zErrMsg = 0; nErr++; } pParse->zTail = zSql; if( pParse->pVdbe && pParse->nErr>0 && pParse->nested==0 ){ - tdsqlite3VdbeDelete(pParse->pVdbe); + sqlite3VdbeDelete(pParse->pVdbe); pParse->pVdbe = 0; } #ifndef SQLITE_OMIT_SHARED_CACHE if( pParse->nested==0 ){ - tdsqlite3DbFree(db, pParse->aTableLock); + sqlite3DbFree(db, pParse->aTableLock); pParse->aTableLock = 0; pParse->nTableLock = 0; } #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - tdsqlite3_free(pParse->apVtabLock); + sqlite3_free(pParse->apVtabLock); #endif if( !IN_SPECIAL_PARSE ){ @@ -162146,23 +162146,23 @@ SQLITE_PRIVATE int tdsqlite3RunParser(Parse *pParse, const char *zSql, char **pz ** structure built up in pParse->pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ - tdsqlite3DeleteTable(db, pParse->pNewTable); + sqlite3DeleteTable(db, pParse->pNewTable); } if( !IN_RENAME_OBJECT ){ - tdsqlite3DeleteTrigger(db, pParse->pNewTrigger); + sqlite3DeleteTrigger(db, pParse->pNewTrigger); } - if( pParse->pWithToFree ) tdsqlite3WithDelete(db, pParse->pWithToFree); - tdsqlite3DbFree(db, pParse->pVList); + if( pParse->pWithToFree ) sqlite3WithDelete(db, pParse->pWithToFree); + sqlite3DbFree(db, pParse->pVList); while( pParse->pAinc ){ AutoincInfo *p = pParse->pAinc; pParse->pAinc = p->pNext; - tdsqlite3DbFreeNN(db, p); + sqlite3DbFreeNN(db, p); } while( pParse->pZombieTab ){ Table *p = pParse->pZombieTab; pParse->pZombieTab = p->pNextZombie; - tdsqlite3DeleteTable(db, p); + sqlite3DeleteTable(db, p); } db->pParse = pParse->pParentParse; pParse->pParentParse = 0; @@ -162176,22 +162176,22 @@ SQLITE_PRIVATE int tdsqlite3RunParser(Parse *pParse, const char *zSql, char **pz ** Insert a single space character into pStr if the current string ** ends with an identifier */ -static void addSpaceSeparator(tdsqlite3_str *pStr){ - if( pStr->nChar && tdsqlite3IsIdChar(pStr->zText[pStr->nChar-1]) ){ - tdsqlite3_str_append(pStr, " ", 1); +static void addSpaceSeparator(sqlite3_str *pStr){ + if( pStr->nChar && sqlite3IsIdChar(pStr->zText[pStr->nChar-1]) ){ + sqlite3_str_append(pStr, " ", 1); } } /* ** Compute a normalization of the SQL given by zSql[0..nSql-1]. Return -** the normalization in space obtained from tdsqlite3DbMalloc(). Or return +** the normalization in space obtained from sqlite3DbMalloc(). Or return ** NULL if anything goes wrong or if zSql is NULL. */ -SQLITE_PRIVATE char *tdsqlite3Normalize( +SQLITE_PRIVATE char *sqlite3Normalize( Vdbe *pVdbe, /* VM being reprepared */ const char *zSql /* The original SQL string */ ){ - tdsqlite3 *db; /* The database connection */ + sqlite3 *db; /* The database connection */ int i; /* Next unread byte of zSql[] */ int n; /* length of current token */ int tokenType; /* type of current token */ @@ -162200,18 +162200,18 @@ SQLITE_PRIVATE char *tdsqlite3Normalize( int iStartIN; /* Start of RHS of IN operator in z[] */ int nParenAtIN; /* Value of nParent at start of RHS of IN operator */ u32 j; /* Bytes of normalized SQL generated so far */ - tdsqlite3_str *pStr; /* The normalized SQL string under construction */ + sqlite3_str *pStr; /* The normalized SQL string under construction */ - db = tdsqlite3VdbeDb(pVdbe); + db = sqlite3VdbeDb(pVdbe); tokenType = -1; nParen = iStartIN = nParenAtIN = 0; - pStr = tdsqlite3_str_new(db); - assert( pStr!=0 ); /* tdsqlite3_str_new() never returns NULL */ + pStr = sqlite3_str_new(db); + assert( pStr!=0 ); /* sqlite3_str_new() never returns NULL */ for(i=0; zSql[i] && pStr->accError==0; i+=n){ if( tokenType!=TK_SPACE ){ prevType = tokenType; } - n = tdsqlite3GetToken((unsigned char*)zSql+i, &tokenType); + n = sqlite3GetToken((unsigned char*)zSql+i, &tokenType); if( NEVER(n<=0) ) break; switch( tokenType ){ case TK_SPACE: { @@ -162219,7 +162219,7 @@ SQLITE_PRIVATE char *tdsqlite3Normalize( } case TK_NULL: { if( prevType==TK_IS || prevType==TK_NOT ){ - tdsqlite3_str_append(pStr, " NULL", 5); + sqlite3_str_append(pStr, " NULL", 5); break; } /* Fall through */ @@ -162229,7 +162229,7 @@ SQLITE_PRIVATE char *tdsqlite3Normalize( case TK_FLOAT: case TK_VARIABLE: case TK_BLOB: { - tdsqlite3_str_append(pStr, "?", 1); + sqlite3_str_append(pStr, "?", 1); break; } case TK_LP: { @@ -162238,48 +162238,48 @@ SQLITE_PRIVATE char *tdsqlite3Normalize( iStartIN = pStr->nChar; nParenAtIN = nParen; } - tdsqlite3_str_append(pStr, "(", 1); + sqlite3_str_append(pStr, "(", 1); break; } case TK_RP: { if( iStartIN>0 && nParen==nParenAtIN ){ assert( pStr->nChar>=(u32)iStartIN ); pStr->nChar = iStartIN+1; - tdsqlite3_str_append(pStr, "?,?,?", 5); + sqlite3_str_append(pStr, "?,?,?", 5); iStartIN = 0; } nParen--; - tdsqlite3_str_append(pStr, ")", 1); + sqlite3_str_append(pStr, ")", 1); break; } case TK_ID: { iStartIN = 0; j = pStr->nChar; - if( tdsqlite3Isquote(zSql[i]) ){ - char *zId = tdsqlite3DbStrNDup(db, zSql+i, n); + if( sqlite3Isquote(zSql[i]) ){ + char *zId = sqlite3DbStrNDup(db, zSql+i, n); int nId; int eType = 0; if( zId==0 ) break; - tdsqlite3Dequote(zId); - if( zSql[i]=='"' && tdsqlite3VdbeUsesDoubleQuotedString(pVdbe, zId) ){ - tdsqlite3_str_append(pStr, "?", 1); - tdsqlite3DbFree(db, zId); + sqlite3Dequote(zId); + if( zSql[i]=='"' && sqlite3VdbeUsesDoubleQuotedString(pVdbe, zId) ){ + sqlite3_str_append(pStr, "?", 1); + sqlite3DbFree(db, zId); break; } - nId = tdsqlite3Strlen30(zId); - if( tdsqlite3GetToken((u8*)zId, &eType)==nId && eType==TK_ID ){ + nId = sqlite3Strlen30(zId); + if( sqlite3GetToken((u8*)zId, &eType)==nId && eType==TK_ID ){ addSpaceSeparator(pStr); - tdsqlite3_str_append(pStr, zId, nId); + sqlite3_str_append(pStr, zId, nId); }else{ - tdsqlite3_str_appendf(pStr, "\"%w\"", zId); + sqlite3_str_appendf(pStr, "\"%w\"", zId); } - tdsqlite3DbFree(db, zId); + sqlite3DbFree(db, zId); }else{ addSpaceSeparator(pStr); - tdsqlite3_str_append(pStr, zSql+i, n); + sqlite3_str_append(pStr, zSql+i, n); } while( jnChar ){ - pStr->zText[j] = tdsqlite3Tolower(pStr->zText[j]); + pStr->zText[j] = sqlite3Tolower(pStr->zText[j]); j++; } break; @@ -162289,19 +162289,19 @@ SQLITE_PRIVATE char *tdsqlite3Normalize( /* fall through */ } default: { - if( tdsqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr); + if( sqlite3IsIdChar(zSql[i]) ) addSpaceSeparator(pStr); j = pStr->nChar; - tdsqlite3_str_append(pStr, zSql+i, n); + sqlite3_str_append(pStr, zSql+i, n); while( jnChar ){ - pStr->zText[j] = tdsqlite3Toupper(pStr->zText[j]); + pStr->zText[j] = sqlite3Toupper(pStr->zText[j]); j++; } break; } } } - if( tokenType!=TK_SEMI ) tdsqlite3_str_append(pStr, ";", 1); - return tdsqlite3_str_finish(pStr); + if( tokenType!=TK_SEMI ) sqlite3_str_append(pStr, ";", 1); + return sqlite3_str_finish(pStr); } #endif /* SQLITE_ENABLE_NORMALIZE */ @@ -162320,7 +162320,7 @@ SQLITE_PRIVATE char *tdsqlite3Normalize( ************************************************************************* ** An tokenizer for SQL ** -** This file contains C code that implements the tdsqlite3_complete() API. +** This file contains C code that implements the sqlite3_complete() API. ** This code used to be part of the tokenizer.c source file. But by ** separating it out, the code will be automatically omitted from ** static links that do not use it. @@ -162333,17 +162333,17 @@ SQLITE_PRIVATE char *tdsqlite3Normalize( */ #ifndef SQLITE_AMALGAMATION #ifdef SQLITE_ASCII -#define IdChar(C) ((tdsqlite3CtypeMap[(unsigned char)C]&0x46)!=0) +#define IdChar(C) ((sqlite3CtypeMap[(unsigned char)C]&0x46)!=0) #endif #ifdef SQLITE_EBCDIC -SQLITE_PRIVATE const char tdsqlite3IsEbcdicIdChar[]; -#define IdChar(C) (((c=C)>=0x42 && tdsqlite3IsEbcdicIdChar[c-0x40])) +SQLITE_PRIVATE const char sqlite3IsEbcdicIdChar[]; +#define IdChar(C) (((c=C)>=0x42 && sqlite3IsEbcdicIdChar[c-0x40])) #endif #endif /* SQLITE_AMALGAMATION */ /* -** Token types used by the tdsqlite3_complete() routine. See the header +** Token types used by the sqlite3_complete() routine. See the header ** comments on that procedure for additional information. */ #define tkSEMI 0 @@ -162410,7 +162410,7 @@ SQLITE_PRIVATE const char tdsqlite3IsEbcdicIdChar[]; ** to recognize the end of a trigger can be omitted. All we have to do ** is look for a semicolon that is not part of an string or comment. */ -SQLITE_API int tdsqlite3_complete(const char *zSql){ +SQLITE_API int sqlite3_complete(const char *zSql){ u8 state = 0; /* Current state, using numbers defined in header comment */ u8 token; /* Value of the next token */ @@ -162516,7 +162516,7 @@ SQLITE_API int tdsqlite3_complete(const char *zSql){ #else switch( *zSql ){ case 'c': case 'C': { - if( nId==6 && tdsqlite3StrNICmp(zSql, "create", 6)==0 ){ + if( nId==6 && sqlite3StrNICmp(zSql, "create", 6)==0 ){ token = tkCREATE; }else{ token = tkOTHER; @@ -162524,11 +162524,11 @@ SQLITE_API int tdsqlite3_complete(const char *zSql){ break; } case 't': case 'T': { - if( nId==7 && tdsqlite3StrNICmp(zSql, "trigger", 7)==0 ){ + if( nId==7 && sqlite3StrNICmp(zSql, "trigger", 7)==0 ){ token = tkTRIGGER; - }else if( nId==4 && tdsqlite3StrNICmp(zSql, "temp", 4)==0 ){ + }else if( nId==4 && sqlite3StrNICmp(zSql, "temp", 4)==0 ){ token = tkTEMP; - }else if( nId==9 && tdsqlite3StrNICmp(zSql, "temporary", 9)==0 ){ + }else if( nId==9 && sqlite3StrNICmp(zSql, "temporary", 9)==0 ){ token = tkTEMP; }else{ token = tkOTHER; @@ -162536,11 +162536,11 @@ SQLITE_API int tdsqlite3_complete(const char *zSql){ break; } case 'e': case 'E': { - if( nId==3 && tdsqlite3StrNICmp(zSql, "end", 3)==0 ){ + if( nId==3 && sqlite3StrNICmp(zSql, "end", 3)==0 ){ token = tkEND; }else #ifndef SQLITE_OMIT_EXPLAIN - if( nId==7 && tdsqlite3StrNICmp(zSql, "explain", 7)==0 ){ + if( nId==7 && sqlite3StrNICmp(zSql, "explain", 7)==0 ){ token = tkEXPLAIN; }else #endif @@ -162571,28 +162571,28 @@ SQLITE_API int tdsqlite3_complete(const char *zSql){ #ifndef SQLITE_OMIT_UTF16 /* -** This routine is the same as the tdsqlite3_complete() routine described +** This routine is the same as the sqlite3_complete() routine described ** above, except that the parameter is required to be UTF-16 encoded, not ** UTF-8. */ -SQLITE_API int tdsqlite3_complete16(const void *zSql){ - tdsqlite3_value *pVal; +SQLITE_API int sqlite3_complete16(const void *zSql){ + sqlite3_value *pVal; char const *zSql8; int rc; #ifndef SQLITE_OMIT_AUTOINIT - rc = tdsqlite3_initialize(); + rc = sqlite3_initialize(); if( rc ) return rc; #endif - pVal = tdsqlite3ValueNew(0); - tdsqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); - zSql8 = tdsqlite3ValueText(pVal, SQLITE_UTF8); + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8); if( zSql8 ){ - rc = tdsqlite3_complete(zSql8); + rc = sqlite3_complete(zSql8); }else{ rc = SQLITE_NOMEM_BKPT; } - tdsqlite3ValueFree(pVal); + sqlite3ValueFree(pVal); return rc & 0xff; } #endif /* SQLITE_OMIT_UTF16 */ @@ -162634,7 +162634,7 @@ SQLITE_API int tdsqlite3_complete16(const void *zSql){ ****************************************************************************** ** ** This header file is used by programs that want to link against the -** FTS3 library. All it does is declare the tdsqlite3Fts3Init() interface. +** FTS3 library. All it does is declare the sqlite3Fts3Init() interface. */ /* #include "sqlite3.h" */ @@ -162642,7 +162642,7 @@ SQLITE_API int tdsqlite3_complete16(const void *zSql){ extern "C" { #endif /* __cplusplus */ -SQLITE_PRIVATE int tdsqlite3Fts3Init(tdsqlite3 *db); +SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db); #if 0 } /* extern "C" */ @@ -162667,7 +162667,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3Init(tdsqlite3 *db); ****************************************************************************** ** ** This header file is used by programs that want to link against the -** RTREE library. All it does is declare the tdsqlite3RtreeInit() interface. +** RTREE library. All it does is declare the sqlite3RtreeInit() interface. */ /* #include "sqlite3.h" */ @@ -162679,7 +162679,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3Init(tdsqlite3 *db); extern "C" { #endif /* __cplusplus */ -SQLITE_PRIVATE int tdsqlite3RtreeInit(tdsqlite3 *db); +SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db); #if 0 } /* extern "C" */ @@ -162704,7 +162704,7 @@ SQLITE_PRIVATE int tdsqlite3RtreeInit(tdsqlite3 *db); ****************************************************************************** ** ** This header file is used by programs that want to link against the -** ICU extension. All it does is declare the tdsqlite3IcuInit() interface. +** ICU extension. All it does is declare the sqlite3IcuInit() interface. */ /* #include "sqlite3.h" */ @@ -162712,7 +162712,7 @@ SQLITE_PRIVATE int tdsqlite3RtreeInit(tdsqlite3 *db); extern "C" { #endif /* __cplusplus */ -SQLITE_PRIVATE int tdsqlite3IcuInit(tdsqlite3 *db); +SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); #if 0 } /* extern "C" */ @@ -162723,45 +162723,45 @@ SQLITE_PRIVATE int tdsqlite3IcuInit(tdsqlite3 *db); /************** Continuing where we left off in main.c ***********************/ #endif #ifdef SQLITE_ENABLE_JSON1 -SQLITE_PRIVATE int tdsqlite3Json1Init(tdsqlite3*); +SQLITE_PRIVATE int sqlite3Json1Init(sqlite3*); #endif #ifdef SQLITE_ENABLE_STMTVTAB -SQLITE_PRIVATE int tdsqlite3StmtVtabInit(tdsqlite3*); +SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3*); #endif #ifdef SQLITE_ENABLE_FTS5 -SQLITE_PRIVATE int tdsqlite3Fts5Init(tdsqlite3*); +SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3*); #endif #ifndef SQLITE_AMALGAMATION -/* IMPLEMENTATION-OF: R-46656-45156 The tdsqlite3_version[] string constant +/* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant ** contains the text of SQLITE_VERSION macro. */ -SQLITE_API const char tdsqlite3_version[] = SQLITE_VERSION; +SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; #endif -/* IMPLEMENTATION-OF: R-53536-42575 The tdsqlite3_libversion() function returns -** a pointer to the to the tdsqlite3_version[] string constant. +/* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns +** a pointer to the to the sqlite3_version[] string constant. */ -SQLITE_API const char *tdsqlite3_libversion(void){ return tdsqlite3_version; } +SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } -/* IMPLEMENTATION-OF: R-25063-23286 The tdsqlite3_sourceid() function returns a +/* IMPLEMENTATION-OF: R-25063-23286 The sqlite3_sourceid() function returns a ** pointer to a string constant whose value is the same as the ** SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using ** an edited copy of the amalgamation, then the last four characters of ** the hash might be different from SQLITE_SOURCE_ID. */ -/* SQLITE_API const char *tdsqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */ +/* SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } */ -/* IMPLEMENTATION-OF: R-35210-63508 The tdsqlite3_libversion_number() function +/* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function ** returns an integer equal to SQLITE_VERSION_NUMBER. */ -SQLITE_API int tdsqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } +SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } -/* IMPLEMENTATION-OF: R-20790-14025 The tdsqlite3_threadsafe() function returns +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns ** zero if and only if SQLite was compiled with mutexing code omitted due to ** the SQLITE_THREADSAFE compile-time option being set to 0. */ -SQLITE_API int tdsqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } +SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } /* ** When compiling the test fixture or with debugging enabled (on Win32), @@ -162772,7 +162772,7 @@ SQLITE_API int tdsqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } # ifndef SQLITE_DEBUG_OS_TRACE # define SQLITE_DEBUG_OS_TRACE 0 # endif - int tdsqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; + int sqlite3OSTrace = SQLITE_DEBUG_OS_TRACE; #endif #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE) @@ -162782,7 +162782,7 @@ SQLITE_API int tdsqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } ** I/O active are written using this function. These messages ** are intended for debugging activity only. */ -SQLITE_API void (SQLITE_CDECL *tdsqlite3IoTrace)(const char*, ...) = 0; +SQLITE_API void (SQLITE_CDECL *sqlite3IoTrace)(const char*, ...) = 0; #endif /* @@ -162792,7 +162792,7 @@ SQLITE_API void (SQLITE_CDECL *tdsqlite3IoTrace)(const char*, ...) = 0; ** ** See also the "PRAGMA temp_store_directory" SQL command. */ -SQLITE_API char *tdsqlite3_temp_directory = 0; +SQLITE_API char *sqlite3_temp_directory = 0; /* ** If the following global variable points to a string which is the @@ -162801,7 +162801,7 @@ SQLITE_API char *tdsqlite3_temp_directory = 0; ** ** See also the "PRAGMA data_store_directory" SQL command. */ -SQLITE_API char *tdsqlite3_data_directory = 0; +SQLITE_API char *sqlite3_data_directory = 0; /* ** Initialize SQLite. @@ -162810,10 +162810,10 @@ SQLITE_API char *tdsqlite3_data_directory = 0; ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as -** tdsqlite3_open(). +** sqlite3_open(). ** ** This routine is a no-op except on its very first call for the process, -** or for the first call after a call to tdsqlite3_shutdown. +** or for the first call after a call to sqlite3_shutdown. ** ** The first thread to call this routine runs the initialization to ** completion. If subsequent threads call this routine before the first @@ -162834,15 +162834,15 @@ SQLITE_API char *tdsqlite3_data_directory = 0; ** * Recursive calls to this routine from thread X return immediately ** without blocking. */ -SQLITE_API int tdsqlite3_initialize(void){ - MUTEX_LOGIC( tdsqlite3_mutex *pMaster; ) /* The main static mutex */ +SQLITE_API int sqlite3_initialize(void){ + MUTEX_LOGIC( sqlite3_mutex *pMaster; ) /* The main static mutex */ int rc; /* Result code */ #ifdef SQLITE_EXTRA_INIT int bRunExtraInit = 0; /* Extra initialization needed */ #endif #ifdef SQLITE_OMIT_WSD - rc = tdsqlite3_wsd_init(4096, 24); + rc = sqlite3_wsd_init(4096, 24); if( rc!=SQLITE_OK ){ return rc; } @@ -162854,11 +162854,11 @@ SQLITE_API int tdsqlite3_initialize(void){ assert( SQLITE_PTRSIZE==sizeof(char*) ); /* If SQLite is already completely initialized, then this call - ** to tdsqlite3_initialize() should be a no-op. But the initialization + ** to sqlite3_initialize() should be a no-op. But the initialization ** must be complete. So isInit must not be set until the very end ** of this routine. */ - if( tdsqlite3GlobalConfig.isInit ) return SQLITE_OK; + if( sqlite3GlobalConfig.isInit ) return SQLITE_OK; /* Make sure the mutex subsystem is initialized. If unable to ** initialize the mutex subsystem, return early with the error. @@ -162868,7 +162868,7 @@ SQLITE_API int tdsqlite3_initialize(void){ ** The mutex subsystem must take care of serializing its own ** initialization. */ - rc = tdsqlite3MutexInit(); + rc = sqlite3MutexInit(); if( rc ) return rc; /* Initialize the malloc() system and the recursive pInitMutex mutex. @@ -162877,26 +162877,26 @@ SQLITE_API int tdsqlite3_initialize(void){ ** malloc subsystem - this implies that the allocation of a static ** mutex must not require support from the malloc subsystem. */ - MUTEX_LOGIC( pMaster = tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) - tdsqlite3_mutex_enter(pMaster); - tdsqlite3GlobalConfig.isMutexInit = 1; - if( !tdsqlite3GlobalConfig.isMallocInit ){ - rc = tdsqlite3MallocInit(); + MUTEX_LOGIC( pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); ) + sqlite3_mutex_enter(pMaster); + sqlite3GlobalConfig.isMutexInit = 1; + if( !sqlite3GlobalConfig.isMallocInit ){ + rc = sqlite3MallocInit(); } if( rc==SQLITE_OK ){ - tdsqlite3GlobalConfig.isMallocInit = 1; - if( !tdsqlite3GlobalConfig.pInitMutex ){ - tdsqlite3GlobalConfig.pInitMutex = - tdsqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); - if( tdsqlite3GlobalConfig.bCoreMutex && !tdsqlite3GlobalConfig.pInitMutex ){ + sqlite3GlobalConfig.isMallocInit = 1; + if( !sqlite3GlobalConfig.pInitMutex ){ + sqlite3GlobalConfig.pInitMutex = + sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){ rc = SQLITE_NOMEM_BKPT; } } } if( rc==SQLITE_OK ){ - tdsqlite3GlobalConfig.nRefInitMutex++; + sqlite3GlobalConfig.nRefInitMutex++; } - tdsqlite3_mutex_leave(pMaster); + sqlite3_mutex_leave(pMaster); /* If rc is not SQLITE_OK at this point, then either the malloc ** subsystem could not be initialized or the system failed to allocate @@ -162907,63 +162907,63 @@ SQLITE_API int tdsqlite3_initialize(void){ /* Do the rest of the initialization under the recursive mutex so ** that we will be able to handle recursive calls into - ** tdsqlite3_initialize(). The recursive calls normally come through - ** tdsqlite3_os_init() when it invokes tdsqlite3_vfs_register(), but other + ** sqlite3_initialize(). The recursive calls normally come through + ** sqlite3_os_init() when it invokes sqlite3_vfs_register(), but other ** recursive calls might also be possible. ** ** IMPLEMENTATION-OF: R-00140-37445 SQLite automatically serializes calls ** to the xInit method, so the xInit method need not be threadsafe. ** ** The following mutex is what serializes access to the appdef pcache xInit - ** methods. The tdsqlite3_pcache_methods.xInit() all is embedded in the - ** call to tdsqlite3PcacheInitialize(). + ** methods. The sqlite3_pcache_methods.xInit() all is embedded in the + ** call to sqlite3PcacheInitialize(). */ - tdsqlite3_mutex_enter(tdsqlite3GlobalConfig.pInitMutex); - if( tdsqlite3GlobalConfig.isInit==0 && tdsqlite3GlobalConfig.inProgress==0 ){ - tdsqlite3GlobalConfig.inProgress = 1; + sqlite3_mutex_enter(sqlite3GlobalConfig.pInitMutex); + if( sqlite3GlobalConfig.isInit==0 && sqlite3GlobalConfig.inProgress==0 ){ + sqlite3GlobalConfig.inProgress = 1; #ifdef SQLITE_ENABLE_SQLLOG { - extern void tdsqlite3_init_sqllog(void); - tdsqlite3_init_sqllog(); + extern void sqlite3_init_sqllog(void); + sqlite3_init_sqllog(); } #endif - memset(&tdsqlite3BuiltinFunctions, 0, sizeof(tdsqlite3BuiltinFunctions)); - tdsqlite3RegisterBuiltinFunctions(); - if( tdsqlite3GlobalConfig.isPCacheInit==0 ){ - rc = tdsqlite3PcacheInitialize(); + memset(&sqlite3BuiltinFunctions, 0, sizeof(sqlite3BuiltinFunctions)); + sqlite3RegisterBuiltinFunctions(); + if( sqlite3GlobalConfig.isPCacheInit==0 ){ + rc = sqlite3PcacheInitialize(); } if( rc==SQLITE_OK ){ - tdsqlite3GlobalConfig.isPCacheInit = 1; - rc = tdsqlite3OsInit(); + sqlite3GlobalConfig.isPCacheInit = 1; + rc = sqlite3OsInit(); } #ifdef SQLITE_ENABLE_DESERIALIZE if( rc==SQLITE_OK ){ - rc = tdsqlite3MemdbInit(); + rc = sqlite3MemdbInit(); } #endif if( rc==SQLITE_OK ){ - tdsqlite3PCacheBufferSetup( tdsqlite3GlobalConfig.pPage, - tdsqlite3GlobalConfig.szPage, tdsqlite3GlobalConfig.nPage); - tdsqlite3GlobalConfig.isInit = 1; + sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, + sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); + sqlite3GlobalConfig.isInit = 1; #ifdef SQLITE_EXTRA_INIT bRunExtraInit = 1; #endif } - tdsqlite3GlobalConfig.inProgress = 0; + sqlite3GlobalConfig.inProgress = 0; } - tdsqlite3_mutex_leave(tdsqlite3GlobalConfig.pInitMutex); + sqlite3_mutex_leave(sqlite3GlobalConfig.pInitMutex); /* Go back under the static mutex and clean up the recursive ** mutex to prevent a resource leak. */ - tdsqlite3_mutex_enter(pMaster); - tdsqlite3GlobalConfig.nRefInitMutex--; - if( tdsqlite3GlobalConfig.nRefInitMutex<=0 ){ - assert( tdsqlite3GlobalConfig.nRefInitMutex==0 ); - tdsqlite3_mutex_free(tdsqlite3GlobalConfig.pInitMutex); - tdsqlite3GlobalConfig.pInitMutex = 0; + sqlite3_mutex_enter(pMaster); + sqlite3GlobalConfig.nRefInitMutex--; + if( sqlite3GlobalConfig.nRefInitMutex<=0 ){ + assert( sqlite3GlobalConfig.nRefInitMutex==0 ); + sqlite3_mutex_free(sqlite3GlobalConfig.pInitMutex); + sqlite3GlobalConfig.pInitMutex = 0; } - tdsqlite3_mutex_leave(pMaster); + sqlite3_mutex_leave(pMaster); /* The following is just a sanity check to make sure SQLite has ** been compiled correctly. It is important to run this code, but @@ -162979,7 +162979,7 @@ SQLITE_API int tdsqlite3_initialize(void){ assert(sizeof(x)==8); assert(sizeof(x)==sizeof(y)); memcpy(&y, &x, 8); - assert( tdsqlite3IsNaN(y) ); + assert( sqlite3IsNaN(y) ); } #endif #endif @@ -162998,53 +162998,53 @@ SQLITE_API int tdsqlite3_initialize(void){ } /* -** Undo the effects of tdsqlite3_initialize(). Must not be called while +** Undo the effects of sqlite3_initialize(). Must not be called while ** there are outstanding database connections or memory allocations or ** while any part of SQLite is otherwise in use in any thread. This ** routine is not threadsafe. But it is safe to invoke this routine ** on when SQLite is already shut down. If SQLite is already shut down ** when this routine is invoked, then this routine is a harmless no-op. */ -SQLITE_API int tdsqlite3_shutdown(void){ +SQLITE_API int sqlite3_shutdown(void){ #ifdef SQLITE_OMIT_WSD - int rc = tdsqlite3_wsd_init(4096, 24); + int rc = sqlite3_wsd_init(4096, 24); if( rc!=SQLITE_OK ){ return rc; } #endif - if( tdsqlite3GlobalConfig.isInit ){ + if( sqlite3GlobalConfig.isInit ){ #ifdef SQLITE_EXTRA_SHUTDOWN void SQLITE_EXTRA_SHUTDOWN(void); SQLITE_EXTRA_SHUTDOWN(); #endif - tdsqlite3_os_end(); - tdsqlite3_reset_auto_extension(); - tdsqlite3GlobalConfig.isInit = 0; + sqlite3_os_end(); + sqlite3_reset_auto_extension(); + sqlite3GlobalConfig.isInit = 0; } - if( tdsqlite3GlobalConfig.isPCacheInit ){ - tdsqlite3PcacheShutdown(); - tdsqlite3GlobalConfig.isPCacheInit = 0; + if( sqlite3GlobalConfig.isPCacheInit ){ + sqlite3PcacheShutdown(); + sqlite3GlobalConfig.isPCacheInit = 0; } - if( tdsqlite3GlobalConfig.isMallocInit ){ - tdsqlite3MallocEnd(); - tdsqlite3GlobalConfig.isMallocInit = 0; + if( sqlite3GlobalConfig.isMallocInit ){ + sqlite3MallocEnd(); + sqlite3GlobalConfig.isMallocInit = 0; #ifndef SQLITE_OMIT_SHUTDOWN_DIRECTORIES /* The heap subsystem has now been shutdown and these values are supposed - ** to be NULL or point to memory that was obtained from tdsqlite3_malloc(), + ** to be NULL or point to memory that was obtained from sqlite3_malloc(), ** which would rely on that heap subsystem; therefore, make sure these ** values cannot refer to heap memory that was just invalidated when the ** heap subsystem was shutdown. This is only done if the current call to ** this function resulted in the heap subsystem actually being shutdown. */ - tdsqlite3_data_directory = 0; - tdsqlite3_temp_directory = 0; + sqlite3_data_directory = 0; + sqlite3_temp_directory = 0; #endif } - if( tdsqlite3GlobalConfig.isMutexInit ){ - tdsqlite3MutexEnd(); - tdsqlite3GlobalConfig.isMutexInit = 0; + if( sqlite3GlobalConfig.isMutexInit ){ + sqlite3MutexEnd(); + sqlite3GlobalConfig.isMutexInit = 0; } return SQLITE_OK; @@ -163059,13 +163059,13 @@ SQLITE_API int tdsqlite3_shutdown(void){ ** threadsafe. Failure to heed these warnings can lead to unpredictable ** behavior. */ -SQLITE_API int tdsqlite3_config(int op, ...){ +SQLITE_API int sqlite3_config(int op, ...){ va_list ap; int rc = SQLITE_OK; - /* tdsqlite3_config() shall return SQLITE_MISUSE if it is invoked while + /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while ** the SQLite library is in use. */ - if( tdsqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; + if( sqlite3GlobalConfig.isInit ) return SQLITE_MISUSE_BKPT; va_start(ap, op); switch( op ){ @@ -163077,8 +163077,8 @@ SQLITE_API int tdsqlite3_config(int op, ...){ case SQLITE_CONFIG_SINGLETHREAD: { /* EVIDENCE-OF: R-02748-19096 This option sets the threading mode to ** Single-thread. */ - tdsqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */ - tdsqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ + sqlite3GlobalConfig.bCoreMutex = 0; /* Disable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ break; } #endif @@ -163086,8 +163086,8 @@ SQLITE_API int tdsqlite3_config(int op, ...){ case SQLITE_CONFIG_MULTITHREAD: { /* EVIDENCE-OF: R-14374-42468 This option sets the threading mode to ** Multi-thread. */ - tdsqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ - tdsqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 0; /* Disable mutex on connections */ break; } #endif @@ -163095,22 +163095,22 @@ SQLITE_API int tdsqlite3_config(int op, ...){ case SQLITE_CONFIG_SERIALIZED: { /* EVIDENCE-OF: R-41220-51800 This option sets the threading mode to ** Serialized. */ - tdsqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ - tdsqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */ + sqlite3GlobalConfig.bCoreMutex = 1; /* Enable mutex on core */ + sqlite3GlobalConfig.bFullMutex = 1; /* Enable mutex on connections */ break; } #endif #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-63666-48755 */ case SQLITE_CONFIG_MUTEX: { /* Specify an alternative mutex implementation */ - tdsqlite3GlobalConfig.mutex = *va_arg(ap, tdsqlite3_mutex_methods*); + sqlite3GlobalConfig.mutex = *va_arg(ap, sqlite3_mutex_methods*); break; } #endif #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE>0 /* IMP: R-14450-37597 */ case SQLITE_CONFIG_GETMUTEX: { /* Retrieve the current mutex implementation */ - *va_arg(ap, tdsqlite3_mutex_methods*) = tdsqlite3GlobalConfig.mutex; + *va_arg(ap, sqlite3_mutex_methods*) = sqlite3GlobalConfig.mutex; break; } #endif @@ -163118,30 +163118,30 @@ SQLITE_API int tdsqlite3_config(int op, ...){ case SQLITE_CONFIG_MALLOC: { /* EVIDENCE-OF: R-55594-21030 The SQLITE_CONFIG_MALLOC option takes a ** single argument which is a pointer to an instance of the - ** tdsqlite3_mem_methods structure. The argument specifies alternative + ** sqlite3_mem_methods structure. The argument specifies alternative ** low-level memory allocation routines to be used in place of the memory ** allocation routines built into SQLite. */ - tdsqlite3GlobalConfig.m = *va_arg(ap, tdsqlite3_mem_methods*); + sqlite3GlobalConfig.m = *va_arg(ap, sqlite3_mem_methods*); break; } case SQLITE_CONFIG_GETMALLOC: { /* EVIDENCE-OF: R-51213-46414 The SQLITE_CONFIG_GETMALLOC option takes a ** single argument which is a pointer to an instance of the - ** tdsqlite3_mem_methods structure. The tdsqlite3_mem_methods structure is + ** sqlite3_mem_methods structure. The sqlite3_mem_methods structure is ** filled with the currently defined memory allocation routines. */ - if( tdsqlite3GlobalConfig.m.xMalloc==0 ) tdsqlite3MemSetDefault(); - *va_arg(ap, tdsqlite3_mem_methods*) = tdsqlite3GlobalConfig.m; + if( sqlite3GlobalConfig.m.xMalloc==0 ) sqlite3MemSetDefault(); + *va_arg(ap, sqlite3_mem_methods*) = sqlite3GlobalConfig.m; break; } case SQLITE_CONFIG_MEMSTATUS: { /* EVIDENCE-OF: R-61275-35157 The SQLITE_CONFIG_MEMSTATUS option takes ** single argument of type int, interpreted as a boolean, which enables ** or disables the collection of memory allocation statistics. */ - tdsqlite3GlobalConfig.bMemstat = va_arg(ap, int); + sqlite3GlobalConfig.bMemstat = va_arg(ap, int); break; } case SQLITE_CONFIG_SMALL_MALLOC: { - tdsqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int); + sqlite3GlobalConfig.bSmallMalloc = va_arg(ap, int); break; } case SQLITE_CONFIG_PAGECACHE: { @@ -163149,9 +163149,9 @@ SQLITE_API int tdsqlite3_config(int op, ...){ ** SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem), ** the size of each page cache line (sz), and the number of cache lines ** (N). */ - tdsqlite3GlobalConfig.pPage = va_arg(ap, void*); - tdsqlite3GlobalConfig.szPage = va_arg(ap, int); - tdsqlite3GlobalConfig.nPage = va_arg(ap, int); + sqlite3GlobalConfig.pPage = va_arg(ap, void*); + sqlite3GlobalConfig.szPage = va_arg(ap, int); + sqlite3GlobalConfig.nPage = va_arg(ap, int); break; } case SQLITE_CONFIG_PCACHE_HDRSZ: { @@ -163160,9 +163160,9 @@ SQLITE_API int tdsqlite3_config(int op, ...){ ** that integer the number of extra bytes per page required for each page ** in SQLITE_CONFIG_PAGECACHE. */ *va_arg(ap, int*) = - tdsqlite3HeaderSizeBtree() + - tdsqlite3HeaderSizePcache() + - tdsqlite3HeaderSizePcache1(); + sqlite3HeaderSizeBtree() + + sqlite3HeaderSizePcache() + + sqlite3HeaderSizePcache1(); break; } @@ -163178,21 +163178,21 @@ SQLITE_API int tdsqlite3_config(int op, ...){ case SQLITE_CONFIG_PCACHE2: { /* EVIDENCE-OF: R-63325-48378 The SQLITE_CONFIG_PCACHE2 option takes a - ** single argument which is a pointer to an tdsqlite3_pcache_methods2 + ** single argument which is a pointer to an sqlite3_pcache_methods2 ** object. This object specifies the interface to a custom page cache ** implementation. */ - tdsqlite3GlobalConfig.pcache2 = *va_arg(ap, tdsqlite3_pcache_methods2*); + sqlite3GlobalConfig.pcache2 = *va_arg(ap, sqlite3_pcache_methods2*); break; } case SQLITE_CONFIG_GETPCACHE2: { /* EVIDENCE-OF: R-22035-46182 The SQLITE_CONFIG_GETPCACHE2 option takes a - ** single argument which is a pointer to an tdsqlite3_pcache_methods2 + ** single argument which is a pointer to an sqlite3_pcache_methods2 ** object. SQLite copies of the current page cache implementation into ** that object. */ - if( tdsqlite3GlobalConfig.pcache2.xInit==0 ){ - tdsqlite3PCacheSetDefault(); + if( sqlite3GlobalConfig.pcache2.xInit==0 ){ + sqlite3PCacheSetDefault(); } - *va_arg(ap, tdsqlite3_pcache_methods2*) = tdsqlite3GlobalConfig.pcache2; + *va_arg(ap, sqlite3_pcache_methods2*) = sqlite3GlobalConfig.pcache2; break; } @@ -163205,36 +163205,36 @@ SQLITE_API int tdsqlite3_config(int op, ...){ ** SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the ** number of bytes in the memory buffer, and the minimum allocation size. */ - tdsqlite3GlobalConfig.pHeap = va_arg(ap, void*); - tdsqlite3GlobalConfig.nHeap = va_arg(ap, int); - tdsqlite3GlobalConfig.mnReq = va_arg(ap, int); + sqlite3GlobalConfig.pHeap = va_arg(ap, void*); + sqlite3GlobalConfig.nHeap = va_arg(ap, int); + sqlite3GlobalConfig.mnReq = va_arg(ap, int); - if( tdsqlite3GlobalConfig.mnReq<1 ){ - tdsqlite3GlobalConfig.mnReq = 1; - }else if( tdsqlite3GlobalConfig.mnReq>(1<<12) ){ + if( sqlite3GlobalConfig.mnReq<1 ){ + sqlite3GlobalConfig.mnReq = 1; + }else if( sqlite3GlobalConfig.mnReq>(1<<12) ){ /* cap min request size at 2^12 */ - tdsqlite3GlobalConfig.mnReq = (1<<12); + sqlite3GlobalConfig.mnReq = (1<<12); } - if( tdsqlite3GlobalConfig.pHeap==0 ){ + if( sqlite3GlobalConfig.pHeap==0 ){ /* EVIDENCE-OF: R-49920-60189 If the first pointer (the memory pointer) ** is NULL, then SQLite reverts to using its default memory allocator ** (the system malloc() implementation), undoing any prior invocation of ** SQLITE_CONFIG_MALLOC. ** - ** Setting tdsqlite3GlobalConfig.m to all zeros will cause malloc to - ** revert to its default implementation when tdsqlite3_initialize() is run + ** Setting sqlite3GlobalConfig.m to all zeros will cause malloc to + ** revert to its default implementation when sqlite3_initialize() is run */ - memset(&tdsqlite3GlobalConfig.m, 0, sizeof(tdsqlite3GlobalConfig.m)); + memset(&sqlite3GlobalConfig.m, 0, sizeof(sqlite3GlobalConfig.m)); }else{ /* EVIDENCE-OF: R-61006-08918 If the memory pointer is not NULL then the ** alternative memory allocator is engaged to handle all of SQLites ** memory allocation needs. */ #ifdef SQLITE_ENABLE_MEMSYS3 - tdsqlite3GlobalConfig.m = *tdsqlite3MemGetMemsys3(); + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys3(); #endif #ifdef SQLITE_ENABLE_MEMSYS5 - tdsqlite3GlobalConfig.m = *tdsqlite3MemGetMemsys5(); + sqlite3GlobalConfig.m = *sqlite3MemGetMemsys5(); #endif } break; @@ -163242,8 +163242,8 @@ SQLITE_API int tdsqlite3_config(int op, ...){ #endif case SQLITE_CONFIG_LOOKASIDE: { - tdsqlite3GlobalConfig.szLookaside = va_arg(ap, int); - tdsqlite3GlobalConfig.nLookaside = va_arg(ap, int); + sqlite3GlobalConfig.szLookaside = va_arg(ap, int); + sqlite3GlobalConfig.nLookaside = va_arg(ap, int); break; } @@ -163254,25 +163254,25 @@ SQLITE_API int tdsqlite3_config(int op, ...){ case SQLITE_CONFIG_LOG: { /* MSVC is picky about pulling func ptrs from va lists. ** http://support.microsoft.com/kb/47961 - ** tdsqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); + ** sqlite3GlobalConfig.xLog = va_arg(ap, void(*)(void*,int,const char*)); */ typedef void(*LOGFUNC_t)(void*,int,const char*); - tdsqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); - tdsqlite3GlobalConfig.pLogArg = va_arg(ap, void*); + sqlite3GlobalConfig.xLog = va_arg(ap, LOGFUNC_t); + sqlite3GlobalConfig.pLogArg = va_arg(ap, void*); break; } /* EVIDENCE-OF: R-55548-33817 The compile-time setting for URI filenames ** can be changed at start-time using the - ** tdsqlite3_config(SQLITE_CONFIG_URI,1) or - ** tdsqlite3_config(SQLITE_CONFIG_URI,0) configuration calls. + ** sqlite3_config(SQLITE_CONFIG_URI,1) or + ** sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls. */ case SQLITE_CONFIG_URI: { /* EVIDENCE-OF: R-25451-61125 The SQLITE_CONFIG_URI option takes a single ** argument of type int. If non-zero, then URI handling is globally ** enabled. If the parameter is zero, then URI handling is globally ** disabled. */ - tdsqlite3GlobalConfig.bOpenUri = va_arg(ap, int); + sqlite3GlobalConfig.bOpenUri = va_arg(ap, int); break; } @@ -163281,26 +163281,26 @@ SQLITE_API int tdsqlite3_config(int op, ...){ ** option takes a single integer argument which is interpreted as a ** boolean in order to enable or disable the use of covering indices for ** full table scans in the query optimizer. */ - tdsqlite3GlobalConfig.bUseCis = va_arg(ap, int); + sqlite3GlobalConfig.bUseCis = va_arg(ap, int); break; } #ifdef SQLITE_ENABLE_SQLLOG case SQLITE_CONFIG_SQLLOG: { - typedef void(*SQLLOGFUNC_t)(void*, tdsqlite3*, const char*, int); - tdsqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t); - tdsqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *); + typedef void(*SQLLOGFUNC_t)(void*, sqlite3*, const char*, int); + sqlite3GlobalConfig.xSqllog = va_arg(ap, SQLLOGFUNC_t); + sqlite3GlobalConfig.pSqllogArg = va_arg(ap, void *); break; } #endif case SQLITE_CONFIG_MMAP_SIZE: { /* EVIDENCE-OF: R-58063-38258 SQLITE_CONFIG_MMAP_SIZE takes two 64-bit - ** integer (tdsqlite3_int64) values that are the default mmap size limit + ** integer (sqlite3_int64) values that are the default mmap size limit ** (the default setting for PRAGMA mmap_size) and the maximum allowed ** mmap size limit. */ - tdsqlite3_int64 szMmap = va_arg(ap, tdsqlite3_int64); - tdsqlite3_int64 mxMmap = va_arg(ap, tdsqlite3_int64); + sqlite3_int64 szMmap = va_arg(ap, sqlite3_int64); + sqlite3_int64 mxMmap = va_arg(ap, sqlite3_int64); /* EVIDENCE-OF: R-53367-43190 If either argument to this option is ** negative, then that argument is changed to its compile-time default. ** @@ -163314,8 +163314,8 @@ SQLITE_API int tdsqlite3_config(int op, ...){ } if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; if( szMmap>mxMmap) szMmap = mxMmap; - tdsqlite3GlobalConfig.mxMmap = mxMmap; - tdsqlite3GlobalConfig.szMmap = szMmap; + sqlite3GlobalConfig.mxMmap = mxMmap; + sqlite3GlobalConfig.szMmap = szMmap; break; } @@ -163324,18 +163324,18 @@ SQLITE_API int tdsqlite3_config(int op, ...){ /* EVIDENCE-OF: R-34926-03360 SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit ** unsigned integer value that specifies the maximum size of the created ** heap. */ - tdsqlite3GlobalConfig.nHeap = va_arg(ap, int); + sqlite3GlobalConfig.nHeap = va_arg(ap, int); break; } #endif case SQLITE_CONFIG_PMASZ: { - tdsqlite3GlobalConfig.szPma = va_arg(ap, unsigned int); + sqlite3GlobalConfig.szPma = va_arg(ap, unsigned int); break; } case SQLITE_CONFIG_STMTJRNL_SPILL: { - tdsqlite3GlobalConfig.nStmtSpill = va_arg(ap, int); + sqlite3GlobalConfig.nStmtSpill = va_arg(ap, int); break; } @@ -163345,14 +163345,14 @@ SQLITE_API int tdsqlite3_config(int op, ...){ if( iVal<0 ){ iVal = SQLITE_DEFAULT_SORTERREF_SIZE; } - tdsqlite3GlobalConfig.szSorterRef = (u32)iVal; + sqlite3GlobalConfig.szSorterRef = (u32)iVal; break; } #endif /* SQLITE_ENABLE_SORTER_REFERENCES */ #ifdef SQLITE_ENABLE_DESERIALIZE case SQLITE_CONFIG_MEMDB_MAXSIZE: { - tdsqlite3GlobalConfig.mxMemdbSize = va_arg(ap, tdsqlite3_int64); + sqlite3GlobalConfig.mxMemdbSize = va_arg(ap, sqlite3_int64); break; } #endif /* SQLITE_ENABLE_DESERIALIZE */ @@ -163373,18 +163373,18 @@ SQLITE_API int tdsqlite3_config(int op, ...){ ** ** The sz parameter is the number of bytes in each lookaside slot. ** The cnt parameter is the number of slots. If pStart is NULL the -** space for the lookaside memory is obtained from tdsqlite3_malloc(). +** space for the lookaside memory is obtained from sqlite3_malloc(). ** If pStart is not NULL then it is sz*cnt bytes of memory to use for ** the lookaside memory. */ -static int setupLookaside(tdsqlite3 *db, void *pBuf, int sz, int cnt){ +static int setupLookaside(sqlite3 *db, void *pBuf, int sz, int cnt){ #ifndef SQLITE_OMIT_LOOKASIDE void *pStart; - tdsqlite3_int64 szAlloc = sz*(tdsqlite3_int64)cnt; + sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt; int nBig; /* Number of full-size slots */ int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ - if( tdsqlite3LookasideUsed(db,0)>0 ){ + if( sqlite3LookasideUsed(db,0)>0 ){ return SQLITE_BUSY; } /* Free any existing lookaside buffer for this handle before @@ -163392,7 +163392,7 @@ static int setupLookaside(tdsqlite3 *db, void *pBuf, int sz, int cnt){ ** both at the same time. */ if( db->lookaside.bMalloced ){ - tdsqlite3_free(db->lookaside.pStart); + sqlite3_free(db->lookaside.pStart); } /* The size of a lookaside slot after ROUNDDOWN8 needs to be larger ** than a pointer to be useful. @@ -163404,10 +163404,10 @@ static int setupLookaside(tdsqlite3 *db, void *pBuf, int sz, int cnt){ sz = 0; pStart = 0; }else if( pBuf==0 ){ - tdsqlite3BeginBenignMalloc(); - pStart = tdsqlite3Malloc( szAlloc ); /* IMP: R-61949-35727 */ - tdsqlite3EndBenignMalloc(); - if( pStart ) szAlloc = tdsqlite3MallocSize(pStart); + sqlite3BeginBenignMalloc(); + pStart = sqlite3Malloc( szAlloc ); /* IMP: R-61949-35727 */ + sqlite3EndBenignMalloc(); + if( pStart ) szAlloc = sqlite3MallocSize(pStart); }else{ pStart = pBuf; } @@ -163469,7 +163469,7 @@ static int setupLookaside(tdsqlite3 *db, void *pBuf, int sz, int cnt){ db->lookaside.bMalloced = 0; db->lookaside.nSlot = 0; } - assert( tdsqlite3LookasideUsed(db,0)==0 ); + assert( sqlite3LookasideUsed(db,0)==0 ); #endif /* SQLITE_OMIT_LOOKASIDE */ return SQLITE_OK; } @@ -163477,9 +163477,9 @@ static int setupLookaside(tdsqlite3 *db, void *pBuf, int sz, int cnt){ /* ** Return the mutex associated with a database connection. */ -SQLITE_API tdsqlite3_mutex *tdsqlite3_db_mutex(tdsqlite3 *db){ +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } @@ -163491,23 +163491,23 @@ SQLITE_API tdsqlite3_mutex *tdsqlite3_db_mutex(tdsqlite3 *db){ ** Free up as much memory as we can from the given database ** connection. */ -SQLITE_API int tdsqlite3_db_release_memory(tdsqlite3 *db){ +SQLITE_API int sqlite3_db_release_memory(sqlite3 *db){ int i; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); - tdsqlite3BtreeEnterAll(db); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ - Pager *pPager = tdsqlite3BtreePager(pBt); - tdsqlite3PagerShrink(pPager); + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3PagerShrink(pPager); } } - tdsqlite3BtreeLeaveAll(db); - tdsqlite3_mutex_leave(db->mutex); + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -163515,36 +163515,36 @@ SQLITE_API int tdsqlite3_db_release_memory(tdsqlite3 *db){ ** Flush any dirty pages in the pager-cache for any attached database ** to disk. */ -SQLITE_API int tdsqlite3_db_cacheflush(tdsqlite3 *db){ +SQLITE_API int sqlite3_db_cacheflush(sqlite3 *db){ int i; int rc = SQLITE_OK; int bSeenBusy = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); - tdsqlite3BtreeEnterAll(db); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( pBt && tdsqlite3BtreeIsInTrans(pBt) ){ - Pager *pPager = tdsqlite3BtreePager(pBt); - rc = tdsqlite3PagerFlush(pPager); + if( pBt && sqlite3BtreeIsInTrans(pBt) ){ + Pager *pPager = sqlite3BtreePager(pBt); + rc = sqlite3PagerFlush(pPager); if( rc==SQLITE_BUSY ){ bSeenBusy = 1; rc = SQLITE_OK; } } } - tdsqlite3BtreeLeaveAll(db); - tdsqlite3_mutex_leave(db->mutex); + sqlite3BtreeLeaveAll(db); + sqlite3_mutex_leave(db->mutex); return ((rc==SQLITE_OK && bSeenBusy) ? SQLITE_BUSY : rc); } /* ** Configuration settings for an individual database connection */ -SQLITE_API int tdsqlite3_db_config(tdsqlite3 *db, int op, ...){ +SQLITE_API int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; va_start(ap, op); @@ -163599,7 +163599,7 @@ SQLITE_API int tdsqlite3_db_config(tdsqlite3 *db, int op, ...){ db->flags &= ~(u64)aFlagOp[i].mask; } if( oldFlags!=db->flags ){ - tdsqlite3ExpirePreparedStatements(db, 0); + sqlite3ExpirePreparedStatements(db, 0); } if( pRes ){ *pRes = (db->flags & aFlagOp[i].mask)!=0; @@ -163657,7 +163657,7 @@ static int rtrimCollFunc( /* ** Return true if CollSeq is the default built-in BINARY. */ -SQLITE_PRIVATE int tdsqlite3IsBinary(const CollSeq *p){ +SQLITE_PRIVATE int sqlite3IsBinary(const CollSeq *p){ assert( p==0 || p->xCmp!=binCollFunc || strcmp(p->zName,"BINARY")==0 ); return p==0 || p->xCmp==binCollFunc; } @@ -163676,7 +163676,7 @@ static int nocaseCollatingFunc( int nKey1, const void *pKey1, int nKey2, const void *pKey2 ){ - int r = tdsqlite3StrNICmp( + int r = sqlite3StrNICmp( (const char *)pKey1, (const char *)pKey2, (nKey1mutex); + sqlite3_mutex_enter(db->mutex); db->lastRowid = iRowid; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); } /* -** Return the number of changes in the most recent call to tdsqlite3_exec(). +** Return the number of changes in the most recent call to sqlite3_exec(). */ -SQLITE_API int tdsqlite3_changes(tdsqlite3 *db){ +SQLITE_API int sqlite3_changes(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } @@ -163729,9 +163729,9 @@ SQLITE_API int tdsqlite3_changes(tdsqlite3 *db){ /* ** Return the number of changes since the database handle was opened. */ -SQLITE_API int tdsqlite3_total_changes(tdsqlite3 *db){ +SQLITE_API int sqlite3_total_changes(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } @@ -163744,11 +163744,11 @@ SQLITE_API int tdsqlite3_total_changes(tdsqlite3 *db){ ** database handle object, it does not close any savepoints that may be open ** at the b-tree/pager level. */ -SQLITE_PRIVATE void tdsqlite3CloseSavepoints(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3CloseSavepoints(sqlite3 *db){ while( db->pSavepoint ){ Savepoint *pTmp = db->pSavepoint; db->pSavepoint = pTmp->pNext; - tdsqlite3DbFree(db, pTmp); + sqlite3DbFree(db, pTmp); } db->nSavepoint = 0; db->nStatement = 0; @@ -163761,43 +163761,43 @@ SQLITE_PRIVATE void tdsqlite3CloseSavepoints(tdsqlite3 *db){ ** copies of a single function are created when create_function() is called ** with SQLITE_ANY as the encoding. */ -static void functionDestroy(tdsqlite3 *db, FuncDef *p){ +static void functionDestroy(sqlite3 *db, FuncDef *p){ FuncDestructor *pDestructor = p->u.pDestructor; if( pDestructor ){ pDestructor->nRef--; if( pDestructor->nRef==0 ){ pDestructor->xDestroy(pDestructor->pUserData); - tdsqlite3DbFree(db, pDestructor); + sqlite3DbFree(db, pDestructor); } } } /* -** Disconnect all tdsqlite3_vtab objects that belong to database connection +** Disconnect all sqlite3_vtab objects that belong to database connection ** db. This is called when db is being closed. */ -static void disconnectAllVtab(tdsqlite3 *db){ +static void disconnectAllVtab(sqlite3 *db){ #ifndef SQLITE_OMIT_VIRTUALTABLE int i; HashElem *p; - tdsqlite3BtreeEnterAll(db); + sqlite3BtreeEnterAll(db); for(i=0; inDb; i++){ Schema *pSchema = db->aDb[i].pSchema; if( pSchema ){ for(p=sqliteHashFirst(&pSchema->tblHash); p; p=sqliteHashNext(p)){ Table *pTab = (Table *)sqliteHashData(p); - if( IsVirtual(pTab) ) tdsqlite3VtabDisconnect(db, pTab); + if( IsVirtual(pTab) ) sqlite3VtabDisconnect(db, pTab); } } } for(p=sqliteHashFirst(&db->aModule); p; p=sqliteHashNext(p)){ Module *pMod = (Module *)sqliteHashData(p); if( pMod->pEpoTab ){ - tdsqlite3VtabDisconnect(db, pMod->pEpoTab); + sqlite3VtabDisconnect(db, pMod->pEpoTab); } } - tdsqlite3VtabUnlockList(db); - tdsqlite3BtreeLeaveAll(db); + sqlite3VtabUnlockList(db); + sqlite3BtreeLeaveAll(db); #else UNUSED_PARAMETER(db); #endif @@ -163805,15 +163805,15 @@ static void disconnectAllVtab(tdsqlite3 *db){ /* ** Return TRUE if database connection db has unfinalized prepared -** statements or unfinished tdsqlite3_backup objects. +** statements or unfinished sqlite3_backup objects. */ -static int connectionIsBusy(tdsqlite3 *db){ +static int connectionIsBusy(sqlite3 *db){ int j; - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); if( db->pVdbe ) return 1; for(j=0; jnDb; j++){ Btree *pBt = db->aDb[j].pBt; - if( pBt && tdsqlite3BtreeIsInBackup(pBt) ) return 1; + if( pBt && sqlite3BtreeIsInBackup(pBt) ) return 1; } return 0; } @@ -163821,16 +163821,16 @@ static int connectionIsBusy(tdsqlite3 *db){ /* ** Close an existing SQLite database */ -static int tdsqlite3Close(tdsqlite3 *db, int forceZombie){ +static int sqlite3Close(sqlite3 *db, int forceZombie){ if( !db ){ - /* EVIDENCE-OF: R-63257-11740 Calling tdsqlite3_close() or - ** tdsqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */ + /* EVIDENCE-OF: R-63257-11740 Calling sqlite3_close() or + ** sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. */ return SQLITE_OK; } - if( !tdsqlite3SafetyCheckSickOrOk(db) ){ + if( !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE_BKPT; } - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( db->mTrace & SQLITE_TRACE_CLOSE ){ db->xTrace(SQLITE_TRACE_CLOSE, db->pTraceArg, db, 0); } @@ -163840,74 +163840,74 @@ static int tdsqlite3Close(tdsqlite3 *db, int forceZombie){ /* If a transaction is open, the disconnectAllVtab() call above ** will not have called the xDisconnect() method on any virtual - ** tables in the db->aVTrans[] array. The following tdsqlite3VtabRollback() + ** tables in the db->aVTrans[] array. The following sqlite3VtabRollback() ** call will do so. We need to do this before the check for active ** SQL statements below, as the v-table implementation may be storing ** some prepared statements internally. */ - tdsqlite3VtabRollback(db); + sqlite3VtabRollback(db); - /* Legacy behavior (tdsqlite3_close() behavior) is to return + /* Legacy behavior (sqlite3_close() behavior) is to return ** SQLITE_BUSY if the connection can not be closed immediately. */ if( !forceZombie && connectionIsBusy(db) ){ - tdsqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized " + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to close due to unfinalized " "statements or unfinished backups"); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return SQLITE_BUSY; } #ifdef SQLITE_ENABLE_SQLLOG - if( tdsqlite3GlobalConfig.xSqllog ){ + if( sqlite3GlobalConfig.xSqllog ){ /* Closing the handle. Fourth parameter is passed the value 2. */ - tdsqlite3GlobalConfig.xSqllog(tdsqlite3GlobalConfig.pSqllogArg, db, 0, 2); + sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); } #endif /* Convert the connection into a zombie and then close it. */ db->magic = SQLITE_MAGIC_ZOMBIE; - tdsqlite3LeaveMutexAndCloseZombie(db); + sqlite3LeaveMutexAndCloseZombie(db); return SQLITE_OK; } /* ** Two variations on the public interface for closing a database -** connection. The tdsqlite3_close() version returns SQLITE_BUSY and +** connection. The sqlite3_close() version returns SQLITE_BUSY and ** leaves the connection option if there are unfinalized prepared -** statements or unfinished tdsqlite3_backups. The tdsqlite3_close_v2() +** statements or unfinished sqlite3_backups. The sqlite3_close_v2() ** version forces the connection to become a zombie if there are ** unclosed resources, and arranges for deallocation when the last -** prepare statement or tdsqlite3_backup closes. +** prepare statement or sqlite3_backup closes. */ -SQLITE_API int tdsqlite3_close(tdsqlite3 *db){ return tdsqlite3Close(db,0); } -SQLITE_API int tdsqlite3_close_v2(tdsqlite3 *db){ return tdsqlite3Close(db,1); } +SQLITE_API int sqlite3_close(sqlite3 *db){ return sqlite3Close(db,0); } +SQLITE_API int sqlite3_close_v2(sqlite3 *db){ return sqlite3Close(db,1); } /* ** Close the mutex on database connection db. ** ** Furthermore, if database connection db is a zombie (meaning that there -** has been a prior call to tdsqlite3_close(db) or tdsqlite3_close_v2(db)) and -** every tdsqlite3_stmt has now been finalized and every tdsqlite3_backup has +** has been a prior call to sqlite3_close(db) or sqlite3_close_v2(db)) and +** every sqlite3_stmt has now been finalized and every sqlite3_backup has ** finished, then free all resources. */ -SQLITE_PRIVATE void tdsqlite3LeaveMutexAndCloseZombie(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ HashElem *i; /* Hash table iterator */ int j; - /* If there are outstanding tdsqlite3_stmt or tdsqlite3_backup objects - ** or if the connection has not yet been closed by tdsqlite3_close_v2(), + /* If there are outstanding sqlite3_stmt or sqlite3_backup objects + ** or if the connection has not yet been closed by sqlite3_close_v2(), ** then just leave the mutex and return. */ if( db->magic!=SQLITE_MAGIC_ZOMBIE || connectionIsBusy(db) ){ - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return; } /* If we reach this point, it means that the database connection has - ** closed all tdsqlite3_stmt and tdsqlite3_backup objects and has been - ** passed to tdsqlite3_close (meaning that it is a zombie). Therefore, + ** closed all sqlite3_stmt and sqlite3_backup objects and has been + ** passed to sqlite3_close (meaning that it is a zombie). Therefore, ** go ahead and free all resources. */ @@ -163915,16 +163915,16 @@ SQLITE_PRIVATE void tdsqlite3LeaveMutexAndCloseZombie(tdsqlite3 *db){ ** any database schemas have been modified by an uncommitted transaction ** they are reset. And that the required b-tree mutex is held to make ** the pager rollback and schema reset an atomic operation. */ - tdsqlite3RollbackAll(db, SQLITE_OK); + sqlite3RollbackAll(db, SQLITE_OK); /* Free any outstanding Savepoint structures. */ - tdsqlite3CloseSavepoints(db); + sqlite3CloseSavepoints(db); /* Close all database connections */ for(j=0; jnDb; j++){ struct Db *pDb = &db->aDb[j]; if( pDb->pBt ){ - tdsqlite3BtreeClose(pDb->pBt); + sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; if( j!=1 ){ pDb->pSchema = 0; @@ -163933,19 +163933,19 @@ SQLITE_PRIVATE void tdsqlite3LeaveMutexAndCloseZombie(tdsqlite3 *db){ } /* Clear the TEMP schema separately and last */ if( db->aDb[1].pSchema ){ - tdsqlite3SchemaClear(db->aDb[1].pSchema); + sqlite3SchemaClear(db->aDb[1].pSchema); } - tdsqlite3VtabUnlockList(db); + sqlite3VtabUnlockList(db); /* Free up the array of auxiliary databases */ - tdsqlite3CollapseDatabaseArray(db); + sqlite3CollapseDatabaseArray(db); assert( db->nDb<=2 ); assert( db->aDb==db->aDbStatic ); /* Tell the code in notify.c that the connection no longer holds any ** locks and does not require any further unlock-notify callbacks. */ - tdsqlite3ConnectionClosed(db); + sqlite3ConnectionClosed(db); for(i=sqliteHashFirst(&db->aFunc); i; i=sqliteHashNext(i)){ FuncDef *pNext, *p; @@ -163953,11 +163953,11 @@ SQLITE_PRIVATE void tdsqlite3LeaveMutexAndCloseZombie(tdsqlite3 *db){ do{ functionDestroy(db, p); pNext = p->pNext; - tdsqlite3DbFree(db, p); + sqlite3DbFree(db, p); p = pNext; }while( p ); } - tdsqlite3HashClear(&db->aFunc); + sqlite3HashClear(&db->aFunc); for(i=sqliteHashFirst(&db->aCollSeq); i; i=sqliteHashNext(i)){ CollSeq *pColl = (CollSeq *)sqliteHashData(i); /* Invoke any destructors registered for collation sequence user data. */ @@ -163966,43 +163966,43 @@ SQLITE_PRIVATE void tdsqlite3LeaveMutexAndCloseZombie(tdsqlite3 *db){ pColl[j].xDel(pColl[j].pUser); } } - tdsqlite3DbFree(db, pColl); + sqlite3DbFree(db, pColl); } - tdsqlite3HashClear(&db->aCollSeq); + sqlite3HashClear(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ Module *pMod = (Module *)sqliteHashData(i); - tdsqlite3VtabEponymousTableClear(db, pMod); - tdsqlite3VtabModuleUnref(db, pMod); + sqlite3VtabEponymousTableClear(db, pMod); + sqlite3VtabModuleUnref(db, pMod); } - tdsqlite3HashClear(&db->aModule); + sqlite3HashClear(&db->aModule); #endif - tdsqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ - tdsqlite3ValueFree(db->pErr); - tdsqlite3CloseExtensions(db); + sqlite3Error(db, SQLITE_OK); /* Deallocates any cached error strings. */ + sqlite3ValueFree(db->pErr); + sqlite3CloseExtensions(db); #if SQLITE_USER_AUTHENTICATION - tdsqlite3_free(db->auth.zAuthUser); - tdsqlite3_free(db->auth.zAuthPW); + sqlite3_free(db->auth.zAuthUser); + sqlite3_free(db->auth.zAuthPW); #endif db->magic = SQLITE_MAGIC_ERROR; /* The temp-database schema is allocated differently from the other schema - ** objects (using sqliteMalloc() directly, instead of tdsqlite3BtreeSchema()). + ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). ** So it needs to be freed here. Todo: Why not roll the temp schema into ** the same sqliteMalloc() as the one that allocates the database ** structure? */ - tdsqlite3DbFree(db, db->aDb[1].pSchema); - tdsqlite3_mutex_leave(db->mutex); + sqlite3DbFree(db, db->aDb[1].pSchema); + sqlite3_mutex_leave(db->mutex); db->magic = SQLITE_MAGIC_CLOSED; - tdsqlite3_mutex_free(db->mutex); - assert( tdsqlite3LookasideUsed(db,0)==0 ); + sqlite3_mutex_free(db->mutex); + assert( sqlite3LookasideUsed(db,0)==0 ); if( db->lookaside.bMalloced ){ - tdsqlite3_free(db->lookaside.pStart); + sqlite3_free(db->lookaside.pStart); } - tdsqlite3_free(db); + sqlite3_free(db); } /* @@ -164012,12 +164012,12 @@ SQLITE_PRIVATE void tdsqlite3LeaveMutexAndCloseZombie(tdsqlite3 *db){ ** attempts to use that cursor. Read cursors remain open and valid ** but are "saved" in case the table pages are moved around. */ -SQLITE_PRIVATE void tdsqlite3RollbackAll(tdsqlite3 *db, int tripCode){ +SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ int i; int inTrans = 0; int schemaChange; - assert( tdsqlite3_mutex_held(db->mutex) ); - tdsqlite3BeginBenignMalloc(); + assert( sqlite3_mutex_held(db->mutex) ); + sqlite3BeginBenignMalloc(); /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). ** This is important in case the transaction being rolled back has @@ -164025,26 +164025,26 @@ SQLITE_PRIVATE void tdsqlite3RollbackAll(tdsqlite3 *db, int tripCode){ ** here, then another shared-cache connection might sneak in between ** the database rollback and schema reset, which can cause false ** corruption reports in some cases. */ - tdsqlite3BtreeEnterAll(db); + sqlite3BtreeEnterAll(db); schemaChange = (db->mDbFlags & DBFLAG_SchemaChange)!=0 && db->init.busy==0; for(i=0; inDb; i++){ Btree *p = db->aDb[i].pBt; if( p ){ - if( tdsqlite3BtreeIsInTrans(p) ){ + if( sqlite3BtreeIsInTrans(p) ){ inTrans = 1; } - tdsqlite3BtreeRollback(p, tripCode, !schemaChange); + sqlite3BtreeRollback(p, tripCode, !schemaChange); } } - tdsqlite3VtabRollback(db); - tdsqlite3EndBenignMalloc(); + sqlite3VtabRollback(db); + sqlite3EndBenignMalloc(); if( schemaChange ){ - tdsqlite3ExpirePreparedStatements(db, 0); - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ExpirePreparedStatements(db, 0); + sqlite3ResetAllSchemasOfConnection(db); } - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); /* Any deferred constraint violations have now been resolved. */ db->nDeferredCons = 0; @@ -164062,7 +164062,7 @@ SQLITE_PRIVATE void tdsqlite3RollbackAll(tdsqlite3 *db, int tripCode){ ** specified in the argument. */ #if defined(SQLITE_NEED_ERR_NAME) -SQLITE_PRIVATE const char *tdsqlite3ErrName(int rc){ +SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ const char *zName = 0; int i, origRc = rc; for(i=0; i<2 && zName==0; i++, rc &= 0xff){ @@ -164162,7 +164162,7 @@ SQLITE_PRIVATE const char *tdsqlite3ErrName(int rc){ } if( zName==0 ){ static char zBuf[50]; - tdsqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); + sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); zName = zBuf; } return zName; @@ -164173,7 +164173,7 @@ SQLITE_PRIVATE const char *tdsqlite3ErrName(int rc){ ** Return a static string that describes the kind of error specified in the ** argument. */ -SQLITE_PRIVATE const char *tdsqlite3ErrStr(int rc){ +SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ static const char* const aMsg[] = { /* SQLITE_OK */ "not an error", /* SQLITE_ERROR */ "SQL logic error", @@ -164246,7 +164246,7 @@ SQLITE_PRIVATE const char *tdsqlite3ErrStr(int rc){ static int sqliteDefaultBusyCallback( void *ptr, /* Database connection */ int count, /* Number of times table has been busy */ - tdsqlite3_file *pFile /* The file on which the lock occurred */ + sqlite3_file *pFile /* The file on which the lock occurred */ ){ #if SQLITE_OS_WIN || HAVE_USLEEP /* This case is for systems that have support for sleeping for fractions of @@ -164256,15 +164256,15 @@ static int sqliteDefaultBusyCallback( static const u8 totals[] = { 0, 1, 3, 8, 18, 33, 53, 78, 103, 128, 178, 228 }; # define NDELAY ArraySize(delays) - tdsqlite3 *db = (tdsqlite3 *)ptr; + sqlite3 *db = (sqlite3 *)ptr; int tmout = db->busyTimeout; int delay, prior; #ifdef SQLITE_ENABLE_SETLK_TIMEOUT - if( tdsqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){ + if( sqlite3OsFileControl(pFile,SQLITE_FCNTL_LOCK_TIMEOUT,&tmout)==SQLITE_OK ){ if( count ){ tmout = 0; - tdsqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout); + sqlite3OsFileControl(pFile, SQLITE_FCNTL_LOCK_TIMEOUT, &tmout); return 0; }else{ return 1; @@ -164285,18 +164285,18 @@ static int sqliteDefaultBusyCallback( delay = tmout - prior; if( delay<=0 ) return 0; } - tdsqlite3OsSleep(db->pVfs, delay*1000); + sqlite3OsSleep(db->pVfs, delay*1000); return 1; #else /* This case for unix systems that lack usleep() support. Sleeping ** must be done in increments of whole seconds */ - tdsqlite3 *db = (tdsqlite3 *)ptr; - int tmout = ((tdsqlite3 *)ptr)->busyTimeout; + sqlite3 *db = (sqlite3 *)ptr; + int tmout = ((sqlite3 *)ptr)->busyTimeout; UNUSED_PARAMETER(pFile); if( (count+1)*1000 > tmout ){ return 0; } - tdsqlite3OsSleep(db->pVfs, 1000000); + sqlite3OsSleep(db->pVfs, 1000000); return 1; #endif } @@ -164310,14 +164310,14 @@ static int sqliteDefaultBusyCallback( ** If this routine returns non-zero, the lock is retried. If it ** returns 0, the operation aborts with an SQLITE_BUSY error. */ -SQLITE_PRIVATE int tdsqlite3InvokeBusyHandler(BusyHandler *p, tdsqlite3_file *pFile){ +SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p, sqlite3_file *pFile){ int rc; if( p->xBusyHandler==0 || p->nBusy<0 ) return 0; if( p->bExtraFileArg ){ /* Add an extra parameter with the pFile pointer to the end of the ** callback argument list */ - int (*xTra)(void*,int,tdsqlite3_file*); - xTra = (int(*)(void*,int,tdsqlite3_file*))p->xBusyHandler; + int (*xTra)(void*,int,sqlite3_file*); + xTra = (int(*)(void*,int,sqlite3_file*))p->xBusyHandler; rc = xTra(p->pBusyArg, p->nBusy, pFile); }else{ /* Legacy style busy handler callback */ @@ -164335,21 +164335,21 @@ SQLITE_PRIVATE int tdsqlite3InvokeBusyHandler(BusyHandler *p, tdsqlite3_file *pF ** This routine sets the busy callback for an Sqlite database to the ** given callback function with the given argument. */ -SQLITE_API int tdsqlite3_busy_handler( - tdsqlite3 *db, +SQLITE_API int sqlite3_busy_handler( + sqlite3 *db, int (*xBusy)(void*,int), void *pArg ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); db->busyHandler.xBusyHandler = xBusy; db->busyHandler.pBusyArg = pArg; db->busyHandler.nBusy = 0; db->busyHandler.bExtraFileArg = 0; db->busyTimeout = 0; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -164359,19 +164359,19 @@ SQLITE_API int tdsqlite3_busy_handler( ** given callback function with the given argument. The progress callback will ** be invoked every nOps opcodes. */ -SQLITE_API void tdsqlite3_progress_handler( - tdsqlite3 *db, +SQLITE_API void sqlite3_progress_handler( + sqlite3 *db, int nOps, int (*xProgress)(void*), void *pArg ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( nOps>0 ){ db->xProgress = xProgress; db->nProgressOps = (unsigned)nOps; @@ -164381,7 +164381,7 @@ SQLITE_API void tdsqlite3_progress_handler( db->nProgressOps = 0; db->pProgressArg = 0; } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); } #endif @@ -164390,17 +164390,17 @@ SQLITE_API void tdsqlite3_progress_handler( ** This routine installs a default busy handler that waits for the ** specified number of milliseconds before returning 0. */ -SQLITE_API int tdsqlite3_busy_timeout(tdsqlite3 *db, int ms){ +SQLITE_API int sqlite3_busy_timeout(sqlite3 *db, int ms){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif if( ms>0 ){ - tdsqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, + sqlite3_busy_handler(db, (int(*)(void*,int))sqliteDefaultBusyCallback, (void*)db); db->busyTimeout = ms; db->busyHandler.bExtraFileArg = 1; }else{ - tdsqlite3_busy_handler(db, 0, 0); + sqlite3_busy_handler(db, 0, 0); } return SQLITE_OK; } @@ -164408,9 +164408,9 @@ SQLITE_API int tdsqlite3_busy_timeout(tdsqlite3 *db, int ms){ /* ** Cause any pending operation to stop at its earliest opportunity. */ -SQLITE_API void tdsqlite3_interrupt(tdsqlite3 *db){ +SQLITE_API void sqlite3_interrupt(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){ + if( !sqlite3SafetyCheckOk(db) && (db==0 || db->magic!=SQLITE_MAGIC_ZOMBIE) ){ (void)SQLITE_MISUSE_BKPT; return; } @@ -164420,36 +164420,36 @@ SQLITE_API void tdsqlite3_interrupt(tdsqlite3 *db){ /* -** This function is exactly the same as tdsqlite3_create_function(), except +** This function is exactly the same as sqlite3_create_function(), except ** that it is designed to be called by internal code. The difference is -** that if a malloc() fails in tdsqlite3_create_function(), an error code +** that if a malloc() fails in sqlite3_create_function(), an error code ** is returned and the mallocFailed flag cleared. */ -SQLITE_PRIVATE int tdsqlite3CreateFunc( - tdsqlite3 *db, +SQLITE_PRIVATE int sqlite3CreateFunc( + sqlite3 *db, const char *zFunctionName, int nArg, int enc, void *pUserData, - void (*xSFunc)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*xFinal)(tdsqlite3_context*), - void (*xValue)(tdsqlite3_context*), - void (*xInverse)(tdsqlite3_context*,int,tdsqlite3_value **), + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), FuncDestructor *pDestructor ){ FuncDef *p; int nName; int extraFlags; - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); assert( xValue==0 || xSFunc==0 ); if( zFunctionName==0 /* Must have a valid name */ || (xSFunc!=0 && xFinal!=0) /* Not both xSFunc and xFinal */ || ((xFinal==0)!=(xStep==0)) /* Both or neither of xFinal and xStep */ || ((xValue==0)!=(xInverse==0)) /* Both or neither of xValue, xInverse */ || (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) - || (255<(nName = tdsqlite3Strlen30( zFunctionName))) + || (255<(nName = sqlite3Strlen30( zFunctionName))) ){ return SQLITE_MISUSE_BKPT; } @@ -164478,11 +164478,11 @@ SQLITE_PRIVATE int tdsqlite3CreateFunc( enc = SQLITE_UTF16NATIVE; }else if( enc==SQLITE_ANY ){ int rc; - rc = tdsqlite3CreateFunc(db, zFunctionName, nArg, + rc = sqlite3CreateFunc(db, zFunctionName, nArg, (SQLITE_UTF8|extraFlags)^SQLITE_FUNC_UNSAFE, pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); if( rc==SQLITE_OK ){ - rc = tdsqlite3CreateFunc(db, zFunctionName, nArg, + rc = sqlite3CreateFunc(db, zFunctionName, nArg, (SQLITE_UTF16LE|extraFlags)^SQLITE_FUNC_UNSAFE, pUserData, xSFunc, xStep, xFinal, xValue, xInverse, pDestructor); } @@ -164500,19 +164500,19 @@ SQLITE_PRIVATE int tdsqlite3CreateFunc( ** is being overridden/deleted but there are no active VMs, allow the ** operation to continue but invalidate all precompiled statements. */ - p = tdsqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0); + p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0); if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){ if( db->nVdbeActive ){ - tdsqlite3ErrorWithMsg(db, SQLITE_BUSY, + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify user-function due to active statements"); assert( !db->mallocFailed ); return SQLITE_BUSY; }else{ - tdsqlite3ExpirePreparedStatements(db, 0); + sqlite3ExpirePreparedStatements(db, 0); } } - p = tdsqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1); + p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 1); assert(p || db->mallocFailed); if( !p ){ return SQLITE_NOMEM_BKPT; @@ -164541,36 +164541,36 @@ SQLITE_PRIVATE int tdsqlite3CreateFunc( /* ** Worker function used by utf-8 APIs that create new functions: ** -** tdsqlite3_create_function() -** tdsqlite3_create_function_v2() -** tdsqlite3_create_window_function() +** sqlite3_create_function() +** sqlite3_create_function_v2() +** sqlite3_create_window_function() */ static int createFunctionApi( - tdsqlite3 *db, + sqlite3 *db, const char *zFunc, int nArg, int enc, void *p, - void (*xSFunc)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*), - void (*xValue)(tdsqlite3_context*), - void (*xInverse)(tdsqlite3_context*,int,tdsqlite3_value**), + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value**), void(*xDestroy)(void*) ){ int rc = SQLITE_ERROR; FuncDestructor *pArg = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( xDestroy ){ - pArg = (FuncDestructor *)tdsqlite3Malloc(sizeof(FuncDestructor)); + pArg = (FuncDestructor *)sqlite3Malloc(sizeof(FuncDestructor)); if( !pArg ){ - tdsqlite3OomFault(db); + sqlite3OomFault(db); xDestroy(p); goto out; } @@ -164578,61 +164578,61 @@ static int createFunctionApi( pArg->xDestroy = xDestroy; pArg->pUserData = p; } - rc = tdsqlite3CreateFunc(db, zFunc, nArg, enc, p, + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, xValue, xInverse, pArg ); if( pArg && pArg->nRef==0 ){ assert( rc!=SQLITE_OK ); xDestroy(p); - tdsqlite3_free(pArg); + sqlite3_free(pArg); } out: - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } /* ** Create new user functions. */ -SQLITE_API int tdsqlite3_create_function( - tdsqlite3 *db, +SQLITE_API int sqlite3_create_function( + sqlite3 *db, const char *zFunc, int nArg, int enc, void *p, - void (*xSFunc)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*xFinal)(tdsqlite3_context*) + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*) ){ return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, 0, 0, 0); } -SQLITE_API int tdsqlite3_create_function_v2( - tdsqlite3 *db, +SQLITE_API int sqlite3_create_function_v2( + sqlite3 *db, const char *zFunc, int nArg, int enc, void *p, - void (*xSFunc)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*xFinal)(tdsqlite3_context*), + void (*xSFunc)(sqlite3_context*,int,sqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), void (*xDestroy)(void *) ){ return createFunctionApi(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, 0, 0, xDestroy); } -SQLITE_API int tdsqlite3_create_window_function( - tdsqlite3 *db, +SQLITE_API int sqlite3_create_window_function( + sqlite3 *db, const char *zFunc, int nArg, int enc, void *p, - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value **), - void (*xFinal)(tdsqlite3_context*), - void (*xValue)(tdsqlite3_context*), - void (*xInverse)(tdsqlite3_context*,int,tdsqlite3_value **), + void (*xStep)(sqlite3_context*,int,sqlite3_value **), + void (*xFinal)(sqlite3_context*), + void (*xValue)(sqlite3_context*), + void (*xInverse)(sqlite3_context*,int,sqlite3_value **), void (*xDestroy)(void *) ){ return createFunctionApi(db, zFunc, nArg, enc, p, 0, xStep, @@ -164640,29 +164640,29 @@ SQLITE_API int tdsqlite3_create_window_function( } #ifndef SQLITE_OMIT_UTF16 -SQLITE_API int tdsqlite3_create_function16( - tdsqlite3 *db, +SQLITE_API int sqlite3_create_function16( + sqlite3 *db, const void *zFunctionName, int nArg, int eTextRep, void *p, - void (*xSFunc)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**), - void (*xFinal)(tdsqlite3_context*) + void (*xSFunc)(sqlite3_context*,int,sqlite3_value**), + void (*xStep)(sqlite3_context*,int,sqlite3_value**), + void (*xFinal)(sqlite3_context*) ){ int rc; char *zFunc8; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) || zFunctionName==0 ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - zFunc8 = tdsqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); - rc = tdsqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0); - tdsqlite3DbFree(db, zFunc8); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + zFunc8 = sqlite3Utf16to8(db, zFunctionName, -1, SQLITE_UTF16NATIVE); + rc = sqlite3CreateFunc(db, zFunc8, nArg, eTextRep, p, xSFunc,xStep,xFinal,0,0,0); + sqlite3DbFree(db, zFunc8); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } #endif @@ -164671,23 +164671,23 @@ SQLITE_API int tdsqlite3_create_function16( /* ** The following is the implementation of an SQL function that always ** fails with an error message stating that the function is used in the -** wrong context. The tdsqlite3_overload_function() API might construct +** wrong context. The sqlite3_overload_function() API might construct ** SQL function that use this routine so that the functions will exist ** for name resolution but are actually overloaded by the xFindFunction ** method of virtual tables. */ -static void tdsqlite3InvalidFunction( - tdsqlite3_context *context, /* The function calling context */ +static void sqlite3InvalidFunction( + sqlite3_context *context, /* The function calling context */ int NotUsed, /* Number of arguments to the function */ - tdsqlite3_value **NotUsed2 /* Value of each argument */ + sqlite3_value **NotUsed2 /* Value of each argument */ ){ - const char *zName = (const char*)tdsqlite3_user_data(context); + const char *zName = (const char*)sqlite3_user_data(context); char *zErr; UNUSED_PARAMETER2(NotUsed, NotUsed2); - zErr = tdsqlite3_mprintf( + zErr = sqlite3_mprintf( "unable to use function %s in the requested context", zName); - tdsqlite3_result_error(context, zErr, -1); - tdsqlite3_free(zErr); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); } /* @@ -164702,8 +164702,8 @@ static void tdsqlite3InvalidFunction( ** A global function must exist in order for name resolution to work ** properly. */ -SQLITE_API int tdsqlite3_overload_function( - tdsqlite3 *db, +SQLITE_API int sqlite3_overload_function( + sqlite3 *db, const char *zName, int nArg ){ @@ -164711,18 +164711,18 @@ SQLITE_API int tdsqlite3_overload_function( char *zCopy; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){ + if( !sqlite3SafetyCheckOk(db) || zName==0 || nArg<-2 ){ return SQLITE_MISUSE_BKPT; } #endif - tdsqlite3_mutex_enter(db->mutex); - rc = tdsqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_enter(db->mutex); + rc = sqlite3FindFunction(db, zName, nArg, SQLITE_UTF8, 0)!=0; + sqlite3_mutex_leave(db->mutex); if( rc ) return SQLITE_OK; - zCopy = tdsqlite3_mprintf(zName); + zCopy = sqlite3_mprintf(zName); if( zCopy==0 ) return SQLITE_NOMEM; - return tdsqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, - zCopy, tdsqlite3InvalidFunction, 0, 0, tdsqlite3_free); + return sqlite3_create_function_v2(db, zName, nArg, SQLITE_UTF8, + zCopy, sqlite3InvalidFunction, 0, 0, sqlite3_free); } #ifndef SQLITE_OMIT_TRACE @@ -164735,45 +164735,45 @@ SQLITE_API int tdsqlite3_overload_function( ** SQL statement. */ #ifndef SQLITE_OMIT_DEPRECATED -SQLITE_API void *tdsqlite3_trace(tdsqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){ +SQLITE_API void *sqlite3_trace(sqlite3 *db, void(*xTrace)(void*,const char*), void *pArg){ void *pOld; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); pOld = db->pTraceArg; db->mTrace = xTrace ? SQLITE_TRACE_LEGACY : 0; db->xTrace = (int(*)(u32,void*,void*,void*))xTrace; db->pTraceArg = pArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return pOld; } #endif /* SQLITE_OMIT_DEPRECATED */ /* Register a trace callback using the version-2 interface. */ -SQLITE_API int tdsqlite3_trace_v2( - tdsqlite3 *db, /* Trace this connection */ +SQLITE_API int sqlite3_trace_v2( + sqlite3 *db, /* Trace this connection */ unsigned mTrace, /* Mask of events to be traced */ int(*xTrace)(unsigned,void*,void*,void*), /* Callback to invoke */ void *pArg /* Context */ ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( mTrace==0 ) xTrace = 0; if( xTrace==0 ) mTrace = 0; db->mTrace = mTrace; db->xTrace = xTrace; db->pTraceArg = pArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -164786,26 +164786,26 @@ SQLITE_API int tdsqlite3_trace_v2( ** profile is a pointer to a function that is invoked at the conclusion of ** each SQL statement that is run. */ -SQLITE_API void *tdsqlite3_profile( - tdsqlite3 *db, +SQLITE_API void *sqlite3_profile( + sqlite3 *db, void (*xProfile)(void*,const char*,sqlite_uint64), void *pArg ){ void *pOld; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); pOld = db->pProfileArg; db->xProfile = xProfile; db->pProfileArg = pArg; db->mTrace &= SQLITE_TRACE_NONLEGACY_MASK; if( db->xProfile ) db->mTrace |= SQLITE_TRACE_XPROFILE; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return pOld; } #endif /* SQLITE_OMIT_DEPRECATED */ @@ -164816,24 +164816,24 @@ SQLITE_API void *tdsqlite3_profile( ** If the invoked function returns non-zero, then the commit becomes a ** rollback. */ -SQLITE_API void *tdsqlite3_commit_hook( - tdsqlite3 *db, /* Attach the hook to this database */ +SQLITE_API void *sqlite3_commit_hook( + sqlite3 *db, /* Attach the hook to this database */ int (*xCallback)(void*), /* Function to invoke on each commit */ void *pArg /* Argument to the function */ ){ void *pOld; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); pOld = db->pCommitArg; db->xCommitCallback = xCallback; db->pCommitArg = pArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return pOld; } @@ -164841,24 +164841,24 @@ SQLITE_API void *tdsqlite3_commit_hook( ** Register a callback to be invoked each time a row is updated, ** inserted or deleted using this database connection. */ -SQLITE_API void *tdsqlite3_update_hook( - tdsqlite3 *db, /* Attach the hook to this database */ +SQLITE_API void *sqlite3_update_hook( + sqlite3 *db, /* Attach the hook to this database */ void (*xCallback)(void*,int,char const *,char const *,sqlite_int64), void *pArg /* Argument to the function */ ){ void *pRet; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); pRet = db->pUpdateArg; db->xUpdateCallback = xCallback; db->pUpdateArg = pArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return pRet; } @@ -164866,24 +164866,24 @@ SQLITE_API void *tdsqlite3_update_hook( ** Register a callback to be invoked each time a transaction is rolled ** back by this database connection. */ -SQLITE_API void *tdsqlite3_rollback_hook( - tdsqlite3 *db, /* Attach the hook to this database */ +SQLITE_API void *sqlite3_rollback_hook( + sqlite3 *db, /* Attach the hook to this database */ void (*xCallback)(void*), /* Callback function */ void *pArg /* Argument to the function */ ){ void *pRet; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); pRet = db->pRollbackArg; db->xRollbackCallback = xCallback; db->pRollbackArg = pArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return pRet; } @@ -164892,67 +164892,67 @@ SQLITE_API void *tdsqlite3_rollback_hook( ** Register a callback to be invoked each time a row is updated, ** inserted or deleted using this database connection. */ -SQLITE_API void *tdsqlite3_preupdate_hook( - tdsqlite3 *db, /* Attach the hook to this database */ +SQLITE_API void *sqlite3_preupdate_hook( + sqlite3 *db, /* Attach the hook to this database */ void(*xCallback)( /* Callback function */ - void*,tdsqlite3*,int,char const*,char const*,tdsqlite3_int64,tdsqlite3_int64), + void*,sqlite3*,int,char const*,char const*,sqlite3_int64,sqlite3_int64), void *pArg /* First callback argument */ ){ void *pRet; - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); pRet = db->pPreUpdateArg; db->xPreUpdateCallback = xCallback; db->pPreUpdateArg = pArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return pRet; } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ #ifndef SQLITE_OMIT_WAL /* -** The tdsqlite3_wal_hook() callback registered by tdsqlite3_wal_autocheckpoint(). -** Invoke tdsqlite3_wal_checkpoint if the number of frames in the log file +** The sqlite3_wal_hook() callback registered by sqlite3_wal_autocheckpoint(). +** Invoke sqlite3_wal_checkpoint if the number of frames in the log file ** is greater than sqlite3.pWalArg cast to an integer (the value configured by ** wal_autocheckpoint()). */ -SQLITE_PRIVATE int tdsqlite3WalDefaultHook( +SQLITE_PRIVATE int sqlite3WalDefaultHook( void *pClientData, /* Argument */ - tdsqlite3 *db, /* Connection */ + sqlite3 *db, /* Connection */ const char *zDb, /* Database */ int nFrame /* Size of WAL */ ){ if( nFrame>=SQLITE_PTR_TO_INT(pClientData) ){ - tdsqlite3BeginBenignMalloc(); - tdsqlite3_wal_checkpoint(db, zDb); - tdsqlite3EndBenignMalloc(); + sqlite3BeginBenignMalloc(); + sqlite3_wal_checkpoint(db, zDb); + sqlite3EndBenignMalloc(); } return SQLITE_OK; } #endif /* SQLITE_OMIT_WAL */ /* -** Configure an tdsqlite3_wal_hook() callback to automatically checkpoint +** Configure an sqlite3_wal_hook() callback to automatically checkpoint ** a database after committing a transaction if there are nFrame or ** more frames in the log file. Passing zero or a negative value as the ** nFrame parameter disables automatic checkpoints entirely. ** ** The callback registered by this function replaces any existing callback -** registered using tdsqlite3_wal_hook(). Likewise, registering a callback -** using tdsqlite3_wal_hook() disables the automatic checkpoint mechanism +** registered using sqlite3_wal_hook(). Likewise, registering a callback +** using sqlite3_wal_hook() disables the automatic checkpoint mechanism ** configured by this function. */ -SQLITE_API int tdsqlite3_wal_autocheckpoint(tdsqlite3 *db, int nFrame){ +SQLITE_API int sqlite3_wal_autocheckpoint(sqlite3 *db, int nFrame){ #ifdef SQLITE_OMIT_WAL UNUSED_PARAMETER(db); UNUSED_PARAMETER(nFrame); #else #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif if( nFrame>0 ){ - tdsqlite3_wal_hook(db, tdsqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame)); + sqlite3_wal_hook(db, sqlite3WalDefaultHook, SQLITE_INT_TO_PTR(nFrame)); }else{ - tdsqlite3_wal_hook(db, 0, 0); + sqlite3_wal_hook(db, 0, 0); } #endif return SQLITE_OK; @@ -164962,24 +164962,24 @@ SQLITE_API int tdsqlite3_wal_autocheckpoint(tdsqlite3 *db, int nFrame){ ** Register a callback to be invoked each time a transaction is written ** into the write-ahead-log by this database connection. */ -SQLITE_API void *tdsqlite3_wal_hook( - tdsqlite3 *db, /* Attach the hook to this db handle */ - int(*xCallback)(void *, tdsqlite3*, const char*, int), +SQLITE_API void *sqlite3_wal_hook( + sqlite3 *db, /* Attach the hook to this db handle */ + int(*xCallback)(void *, sqlite3*, const char*, int), void *pArg /* First argument passed to xCallback() */ ){ #ifndef SQLITE_OMIT_WAL void *pRet; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); pRet = db->pWalArg; db->xWalCallback = xCallback; db->pWalArg = pArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return pRet; #else return 0; @@ -164989,8 +164989,8 @@ SQLITE_API void *tdsqlite3_wal_hook( /* ** Checkpoint database zDb. */ -SQLITE_API int tdsqlite3_wal_checkpoint_v2( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3_wal_checkpoint_v2( + sqlite3 *db, /* Database handle */ const char *zDb, /* Name of attached database (or NULL) */ int eMode, /* SQLITE_CHECKPOINT_* value */ int *pnLog, /* OUT: Size of WAL log in frames */ @@ -165003,7 +165003,7 @@ SQLITE_API int tdsqlite3_wal_checkpoint_v2( int iDb = SQLITE_MAX_ATTACHED; /* sqlite3.aDb[] index of db to checkpoint */ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif /* Initialize the output variables to -1 in case an error occurs. */ @@ -165020,19 +165020,19 @@ SQLITE_API int tdsqlite3_wal_checkpoint_v2( return SQLITE_MISUSE; } - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( zDb && zDb[0] ){ - iDb = tdsqlite3FindDbName(db, zDb); + iDb = sqlite3FindDbName(db, zDb); } if( iDb<0 ){ rc = SQLITE_ERROR; - tdsqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); + sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); }else{ db->busyHandler.nBusy = 0; - rc = tdsqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); - tdsqlite3Error(db, rc); + rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); + sqlite3Error(db, rc); } - rc = tdsqlite3ApiExit(db, rc); + rc = sqlite3ApiExit(db, rc); /* If there are no active statements, clear the interrupt flag at this ** point. */ @@ -165040,7 +165040,7 @@ SQLITE_API int tdsqlite3_wal_checkpoint_v2( db->u1.isInterrupted = 0; } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return rc; #endif } @@ -165051,10 +165051,10 @@ SQLITE_API int tdsqlite3_wal_checkpoint_v2( ** to contains a zero-length string, all attached databases are ** checkpointed. */ -SQLITE_API int tdsqlite3_wal_checkpoint(tdsqlite3 *db, const char *zDb){ - /* EVIDENCE-OF: R-41613-20553 The tdsqlite3_wal_checkpoint(D,X) is equivalent to - ** tdsqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ - return tdsqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); +SQLITE_API int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ + /* EVIDENCE-OF: R-41613-20553 The sqlite3_wal_checkpoint(D,X) is equivalent to + ** sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). */ + return sqlite3_wal_checkpoint_v2(db,zDb,SQLITE_CHECKPOINT_PASSIVE,0,0); } #ifndef SQLITE_OMIT_WAL @@ -165078,18 +165078,18 @@ SQLITE_API int tdsqlite3_wal_checkpoint(tdsqlite3 *db, const char *zDb){ ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL, RESTART ** or TRUNCATE. */ -SQLITE_PRIVATE int tdsqlite3Checkpoint(tdsqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ +SQLITE_PRIVATE int sqlite3Checkpoint(sqlite3 *db, int iDb, int eMode, int *pnLog, int *pnCkpt){ int rc = SQLITE_OK; /* Return code */ int i; /* Used to iterate through attached dbs */ int bBusy = 0; /* True if SQLITE_BUSY has been encountered */ - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); assert( !pnLog || *pnLog==-1 ); assert( !pnCkpt || *pnCkpt==-1 ); for(i=0; inDb && rc==SQLITE_OK; i++){ if( i==iDb || iDb==SQLITE_MAX_ATTACHED ){ - rc = tdsqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); + rc = sqlite3BtreeCheckpoint(db->aDb[i].pBt, eMode, pnLog, pnCkpt); pnLog = 0; pnCkpt = 0; if( rc==SQLITE_BUSY ){ @@ -165122,7 +165122,7 @@ SQLITE_PRIVATE int tdsqlite3Checkpoint(tdsqlite3 *db, int iDb, int eMode, int *p ** 2 0 memory (return 1) ** 3 any memory (return 1) */ -SQLITE_PRIVATE int tdsqlite3TempInMemory(const tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3 *db){ #if SQLITE_TEMP_STORE==1 return ( db->temp_store==2 ); #endif @@ -165143,26 +165143,26 @@ SQLITE_PRIVATE int tdsqlite3TempInMemory(const tdsqlite3 *db){ ** Return UTF-8 encoded English language explanation of the most recent ** error. */ -SQLITE_API const char *tdsqlite3_errmsg(tdsqlite3 *db){ +SQLITE_API const char *sqlite3_errmsg(sqlite3 *db){ const char *z; if( !db ){ - return tdsqlite3ErrStr(SQLITE_NOMEM_BKPT); + return sqlite3ErrStr(SQLITE_NOMEM_BKPT); } - if( !tdsqlite3SafetyCheckSickOrOk(db) ){ - return tdsqlite3ErrStr(SQLITE_MISUSE_BKPT); + if( !sqlite3SafetyCheckSickOrOk(db) ){ + return sqlite3ErrStr(SQLITE_MISUSE_BKPT); } - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( db->mallocFailed ){ - z = tdsqlite3ErrStr(SQLITE_NOMEM_BKPT); + z = sqlite3ErrStr(SQLITE_NOMEM_BKPT); }else{ testcase( db->pErr==0 ); - z = db->errCode ? (char*)tdsqlite3_value_text(db->pErr) : 0; + z = db->errCode ? (char*)sqlite3_value_text(db->pErr) : 0; assert( !db->mallocFailed ); if( z==0 ){ - z = tdsqlite3ErrStr(db->errCode); + z = sqlite3ErrStr(db->errCode); } } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return z; } @@ -165171,7 +165171,7 @@ SQLITE_API const char *tdsqlite3_errmsg(tdsqlite3 *db){ ** Return UTF-16 encoded English language explanation of the most recent ** error. */ -SQLITE_API const void *tdsqlite3_errmsg16(tdsqlite3 *db){ +SQLITE_API const void *sqlite3_errmsg16(sqlite3 *db){ static const u16 outOfMem[] = { 'o', 'u', 't', ' ', 'o', 'f', ' ', 'm', 'e', 'm', 'o', 'r', 'y', 0 }; @@ -165185,36 +165185,36 @@ SQLITE_API const void *tdsqlite3_errmsg16(tdsqlite3 *db){ if( !db ){ return (void *)outOfMem; } - if( !tdsqlite3SafetyCheckSickOrOk(db) ){ + if( !sqlite3SafetyCheckSickOrOk(db) ){ return (void *)misuse; } - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( db->mallocFailed ){ z = (void *)outOfMem; }else{ - z = tdsqlite3_value_text16(db->pErr); + z = sqlite3_value_text16(db->pErr); if( z==0 ){ - tdsqlite3ErrorWithMsg(db, db->errCode, tdsqlite3ErrStr(db->errCode)); - z = tdsqlite3_value_text16(db->pErr); + sqlite3ErrorWithMsg(db, db->errCode, sqlite3ErrStr(db->errCode)); + z = sqlite3_value_text16(db->pErr); } - /* A malloc() may have failed within the call to tdsqlite3_value_text16() + /* A malloc() may have failed within the call to sqlite3_value_text16() ** above. If this is the case, then the db->mallocFailed flag needs to ** be cleared before returning. Do this directly, instead of via - ** tdsqlite3ApiExit(), to avoid setting the database handle error message. + ** sqlite3ApiExit(), to avoid setting the database handle error message. */ - tdsqlite3OomClear(db); + sqlite3OomClear(db); } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return z; } #endif /* SQLITE_OMIT_UTF16 */ /* ** Return the most recent error code generated by an SQLite routine. If NULL is -** passed to this function, we assume a malloc() failed during tdsqlite3_open(). +** passed to this function, we assume a malloc() failed during sqlite3_open(). */ -SQLITE_API int tdsqlite3_errcode(tdsqlite3 *db){ - if( db && !tdsqlite3SafetyCheckSickOrOk(db) ){ +SQLITE_API int sqlite3_errcode(sqlite3 *db){ + if( db && !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE_BKPT; } if( !db || db->mallocFailed ){ @@ -165222,8 +165222,8 @@ SQLITE_API int tdsqlite3_errcode(tdsqlite3 *db){ } return db->errCode & db->errMask; } -SQLITE_API int tdsqlite3_extended_errcode(tdsqlite3 *db){ - if( db && !tdsqlite3SafetyCheckSickOrOk(db) ){ +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ + if( db && !sqlite3SafetyCheckSickOrOk(db) ){ return SQLITE_MISUSE_BKPT; } if( !db || db->mallocFailed ){ @@ -165231,17 +165231,17 @@ SQLITE_API int tdsqlite3_extended_errcode(tdsqlite3 *db){ } return db->errCode; } -SQLITE_API int tdsqlite3_system_errno(tdsqlite3 *db){ +SQLITE_API int sqlite3_system_errno(sqlite3 *db){ return db ? db->iSysErrno : 0; } /* ** Return a string that describes the kind of error specified in the -** argument. For now, this simply calls the internal tdsqlite3ErrStr() +** argument. For now, this simply calls the internal sqlite3ErrStr() ** function. */ -SQLITE_API const char *tdsqlite3_errstr(int rc){ - return tdsqlite3ErrStr(rc); +SQLITE_API const char *sqlite3_errstr(int rc){ + return sqlite3ErrStr(rc); } /* @@ -165249,7 +165249,7 @@ SQLITE_API const char *tdsqlite3_errstr(int rc){ ** and the encoding is enc. */ static int createCollation( - tdsqlite3* db, + sqlite3* db, const char *zName, u8 enc, void* pCtx, @@ -165259,7 +165259,7 @@ static int createCollation( CollSeq *pColl; int enc2; - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the @@ -165279,23 +165279,23 @@ static int createCollation( ** sequence. If so, and there are active VMs, return busy. If there ** are no active VMs, invalidate any pre-compiled statements. */ - pColl = tdsqlite3FindCollSeq(db, (u8)enc2, zName, 0); + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); if( pColl && pColl->xCmp ){ if( db->nVdbeActive ){ - tdsqlite3ErrorWithMsg(db, SQLITE_BUSY, + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } - tdsqlite3ExpirePreparedStatements(db, 0); + sqlite3ExpirePreparedStatements(db, 0); /* If collation sequence pColl was created directly by a call to - ** tdsqlite3_create_collation, and not generated by synthCollSeq(), + ** sqlite3_create_collation, and not generated by synthCollSeq(), ** then any copies made by synthCollSeq() need to be invalidated. ** Also, collation destructor - CollSeq.xDel() - function may need ** to be called. */ if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ - CollSeq *aColl = tdsqlite3HashFind(&db->aCollSeq, zName); + CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName); int j; for(j=0; j<3; j++){ CollSeq *p = &aColl[j]; @@ -165309,13 +165309,13 @@ static int createCollation( } } - pColl = tdsqlite3FindCollSeq(db, (u8)enc2, zName, 1); + pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 1); if( pColl==0 ) return SQLITE_NOMEM_BKPT; pColl->xCmp = xCompare; pColl->pUser = pCtx; pColl->xDel = xDel; pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); - tdsqlite3Error(db, SQLITE_OK); + sqlite3Error(db, SQLITE_OK); return SQLITE_OK; } @@ -165388,11 +165388,11 @@ static const int aHardLimit[] = { ** It merely prevents new constructs that exceed the limit ** from forming. */ -SQLITE_API int tdsqlite3_limit(tdsqlite3 *db, int limitId, int newLimit){ +SQLITE_API int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){ int oldLimit; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return -1; } @@ -165434,7 +165434,7 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3 *db, int limitId, int newLimit){ /* ** This function is used to parse both URIs and non-URI filenames passed by the -** user to API functions tdsqlite3_open() or tdsqlite3_open_v2(), and for database +** user to API functions sqlite3_open() or sqlite3_open_v2(), and for database ** URIs specified as part of ATTACH statements. ** ** The first argument to this function is the name of the VFS to use (or @@ -165448,19 +165448,19 @@ SQLITE_API int tdsqlite3_limit(tdsqlite3 *db, int limitId, int newLimit){ ** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to ** the VFS that should be used to open the database file. *pzFile is set to ** point to a buffer containing the name of the file to open. It is the -** responsibility of the caller to eventually call tdsqlite3_free() to release +** responsibility of the caller to eventually call sqlite3_free() to release ** this buffer. ** ** If an error occurs, then an SQLite error code is returned and *pzErrMsg ** may be set to point to a buffer containing an English language error ** message. It is the responsibility of the caller to eventually release -** this buffer by calling tdsqlite3_free(). +** this buffer by calling sqlite3_free(). */ -SQLITE_PRIVATE int tdsqlite3ParseUri( +SQLITE_PRIVATE int sqlite3ParseUri( const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ const char *zUri, /* Nul-terminated URI to parse */ unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ - tdsqlite3_vfs **ppVfs, /* OUT: VFS to use */ + sqlite3_vfs **ppVfs, /* OUT: VFS to use */ char **pzFile, /* OUT: Filename component of URI */ char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ ){ @@ -165469,12 +165469,12 @@ SQLITE_PRIVATE int tdsqlite3ParseUri( const char *zVfs = zDefaultVfs; char *zFile; char c; - int nUri = tdsqlite3Strlen30(zUri); + int nUri = sqlite3Strlen30(zUri); assert( *pzErrMsg==0 ); if( ((flags & SQLITE_OPEN_URI) /* IMP: R-48725-32206 */ - || tdsqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */ + || sqlite3GlobalConfig.bOpenUri) /* IMP: R-51689-46548 */ && nUri>=5 && memcmp(zUri, "file:", 5)==0 /* IMP: R-57884-37496 */ ){ char *zOpt; @@ -165488,7 +165488,7 @@ SQLITE_PRIVATE int tdsqlite3ParseUri( flags |= SQLITE_OPEN_URI; for(iIn=0; iIn=0 && octet<256 ); if( octet==0 ){ @@ -165555,7 +165555,7 @@ SQLITE_PRIVATE int tdsqlite3ParseUri( continue; #else /* If ENABLE_URI_00_ERROR is defined, "%00" in a URI is an error. */ - *pzErrMsg = tdsqlite3_mprintf("unexpected %%00 in uri"); + *pzErrMsg = sqlite3_mprintf("unexpected %%00 in uri"); rc = SQLITE_ERROR; goto parse_uri_out; #endif @@ -165585,13 +165585,13 @@ SQLITE_PRIVATE int tdsqlite3ParseUri( /* Check if there were any options specified that should be interpreted ** here. Options that are interpreted here include "vfs" and those that - ** correspond to flags that may be passed to the tdsqlite3_open_v2() + ** correspond to flags that may be passed to the sqlite3_open_v2() ** method. */ - zOpt = &zFile[tdsqlite3Strlen30(zFile)+1]; + zOpt = &zFile[sqlite3Strlen30(zFile)+1]; while( zOpt[0] ){ - int nOpt = tdsqlite3Strlen30(zOpt); + int nOpt = sqlite3Strlen30(zOpt); char *zVal = &zOpt[nOpt+1]; - int nVal = tdsqlite3Strlen30(zVal); + int nVal = sqlite3Strlen30(zVal); if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){ zVfs = zVal; @@ -165637,18 +165637,18 @@ SQLITE_PRIVATE int tdsqlite3ParseUri( int mode = 0; for(i=0; aMode[i].z; i++){ const char *z = aMode[i].z; - if( nVal==tdsqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ + if( nVal==sqlite3Strlen30(z) && 0==memcmp(zVal, z, nVal) ){ mode = aMode[i].mode; break; } } if( mode==0 ){ - *pzErrMsg = tdsqlite3_mprintf("no such %s mode: %s", zModeType, zVal); + *pzErrMsg = sqlite3_mprintf("no such %s mode: %s", zModeType, zVal); rc = SQLITE_ERROR; goto parse_uri_out; } if( (mode & ~SQLITE_OPEN_MEMORY)>limit ){ - *pzErrMsg = tdsqlite3_mprintf("%s mode not allowed: %s", + *pzErrMsg = sqlite3_mprintf("%s mode not allowed: %s", zModeType, zVal); rc = SQLITE_PERM; goto parse_uri_out; @@ -165661,7 +165661,7 @@ SQLITE_PRIVATE int tdsqlite3ParseUri( } }else{ - zFile = tdsqlite3_malloc64(nUri+2); + zFile = sqlite3_malloc64(nUri+2); if( !zFile ) return SQLITE_NOMEM_BKPT; if( nUri ){ memcpy(zFile, zUri, nUri); @@ -165671,14 +165671,14 @@ SQLITE_PRIVATE int tdsqlite3ParseUri( flags &= ~SQLITE_OPEN_URI; } - *ppVfs = tdsqlite3_vfs_find(zVfs); + *ppVfs = sqlite3_vfs_find(zVfs); if( *ppVfs==0 ){ - *pzErrMsg = tdsqlite3_mprintf("no such vfs: %s", zVfs); + *pzErrMsg = sqlite3_mprintf("no such vfs: %s", zVfs); rc = SQLITE_ERROR; } parse_uri_out: if( rc!=SQLITE_OK ){ - tdsqlite3_free(zFile); + sqlite3_free(zFile); zFile = 0; } *pFlags = flags; @@ -165692,27 +165692,27 @@ SQLITE_PRIVATE int tdsqlite3ParseUri( ** Extension. Return true if any of the relevant query parameters are ** seen and return false if not. */ -SQLITE_PRIVATE int tdsqlite3CodecQueryParameters( - tdsqlite3 *db, /* Database connection */ +SQLITE_PRIVATE int sqlite3CodecQueryParameters( + sqlite3 *db, /* Database connection */ const char *zDb, /* Which schema is being created/attached */ const char *zUri /* URI filename */ ){ const char *zKey; - if( (zKey = tdsqlite3_uri_parameter(zUri, "hexkey"))!=0 && zKey[0] ){ + if( (zKey = sqlite3_uri_parameter(zUri, "hexkey"))!=0 && zKey[0] ){ u8 iByte; int i; char zDecoded[40]; - for(i=0, iByte=0; imutex = tdsqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); if( db->mutex==0 ){ - tdsqlite3_free(db); + sqlite3_free(db); db = 0; goto opendb_out; } if( isThreadsafe==0 ){ - tdsqlite3MutexWarnOnContention(db->mutex); + sqlite3MutexWarnOnContention(db->mutex); } } - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); db->errMask = 0xff; db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; @@ -165817,7 +165817,7 @@ static int openDatabase( db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS; db->autoCommit = 1; db->nextAutovac = -1; - db->szMmap = tdsqlite3GlobalConfig.szMmap; + db->szMmap = sqlite3GlobalConfig.szMmap; db->nextPagesize = 0; db->nMaxSorterMmap = 0x7FFFFFFF; db->flags |= SQLITE_ShortColNames @@ -165886,9 +165886,9 @@ static int openDatabase( | SQLITE_Defensive #endif ; - tdsqlite3HashInit(&db->aCollSeq); + sqlite3HashInit(&db->aCollSeq); #ifndef SQLITE_OMIT_VIRTUALTABLE - tdsqlite3HashInit(&db->aModule); + sqlite3HashInit(&db->aModule); #endif /* Add the default collation sequence BINARY. BINARY works for both UTF-8 @@ -165898,9 +165898,9 @@ static int openDatabase( ** EVIDENCE-OF: R-52786-44878 SQLite defines three built-in collating ** functions: */ - createCollation(db, tdsqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0); - createCollation(db, tdsqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0); - createCollation(db, tdsqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF8, 0, binCollFunc, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16BE, 0, binCollFunc, 0); + createCollation(db, sqlite3StrBINARY, SQLITE_UTF16LE, 0, binCollFunc, 0); createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); createCollation(db, "RTRIM", SQLITE_UTF8, 0, rtrimCollFunc, 0); if( db->mallocFailed ){ @@ -165909,7 +165909,7 @@ static int openDatabase( /* EVIDENCE-OF: R-08308-17224 The default collating function for all ** strings is BINARY. */ - db->pDfltColl = tdsqlite3FindCollSeq(db, SQLITE_UTF8, tdsqlite3StrBINARY, 0); + db->pDfltColl = sqlite3FindCollSeq(db, SQLITE_UTF8, sqlite3StrBINARY, 0); assert( db->pDfltColl!=0 ); /* Parse the filename/URI argument @@ -165934,30 +165934,30 @@ static int openDatabase( if( ((1<<(flags&7)) & 0x46)==0 ){ rc = SQLITE_MISUSE_BKPT; /* IMP: R-65497-44594 */ }else{ - rc = tdsqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); + rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg); } if( rc!=SQLITE_OK ){ - if( rc==SQLITE_NOMEM ) tdsqlite3OomFault(db); - tdsqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); - tdsqlite3_free(zErrMsg); + if( rc==SQLITE_NOMEM ) sqlite3OomFault(db); + sqlite3ErrorWithMsg(db, rc, zErrMsg ? "%s" : 0, zErrMsg); + sqlite3_free(zErrMsg); goto opendb_out; } /* Open the backend database driver */ - rc = tdsqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, + rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0, flags | SQLITE_OPEN_MAIN_DB); if( rc!=SQLITE_OK ){ if( rc==SQLITE_IOERR_NOMEM ){ rc = SQLITE_NOMEM_BKPT; } - tdsqlite3Error(db, rc); + sqlite3Error(db, rc); goto opendb_out; } - tdsqlite3BtreeEnter(db->aDb[0].pBt); - db->aDb[0].pSchema = tdsqlite3SchemaGet(db, db->aDb[0].pBt); + sqlite3BtreeEnter(db->aDb[0].pBt); + db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt); if( !db->mallocFailed ) ENC(db) = SCHEMA_ENC(db); - tdsqlite3BtreeLeave(db->aDb[0].pBt); - db->aDb[1].pSchema = tdsqlite3SchemaGet(db, 0); + sqlite3BtreeLeave(db->aDb[0].pBt); + db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); /* The default safety_level for the main database is FULL; for the temp ** database it is OFF. This matches the pager layer defaults. @@ -165976,25 +165976,25 @@ static int openDatabase( ** database schema yet. This is delayed until the first time the database ** is accessed. */ - tdsqlite3Error(db, SQLITE_OK); - tdsqlite3RegisterPerConnectionBuiltinFunctions(db); - rc = tdsqlite3_errcode(db); + sqlite3Error(db, SQLITE_OK); + sqlite3RegisterPerConnectionBuiltinFunctions(db); + rc = sqlite3_errcode(db); #ifdef SQLITE_ENABLE_FTS5 /* Register any built-in FTS5 module before loading the automatic ** extensions. This allows automatic extensions to register FTS5 ** tokenizers and auxiliary functions. */ if( !db->mallocFailed && rc==SQLITE_OK ){ - rc = tdsqlite3Fts5Init(db); + rc = sqlite3Fts5Init(db); } #endif /* Load automatic extensions - extensions that have been registered - ** using the tdsqlite3_automatic_extension() API. + ** using the sqlite3_automatic_extension() API. */ if( rc==SQLITE_OK ){ - tdsqlite3AutoLoadExtensions(db); - rc = tdsqlite3_errcode(db); + sqlite3AutoLoadExtensions(db); + rc = sqlite3_errcode(db); if( rc!=SQLITE_OK ){ goto opendb_out; } @@ -166002,63 +166002,63 @@ static int openDatabase( #ifdef SQLITE_ENABLE_FTS1 if( !db->mallocFailed ){ - extern int tdsqlite3Fts1Init(tdsqlite3*); - rc = tdsqlite3Fts1Init(db); + extern int sqlite3Fts1Init(sqlite3*); + rc = sqlite3Fts1Init(db); } #endif #ifdef SQLITE_ENABLE_FTS2 if( !db->mallocFailed && rc==SQLITE_OK ){ - extern int tdsqlite3Fts2Init(tdsqlite3*); - rc = tdsqlite3Fts2Init(db); + extern int sqlite3Fts2Init(sqlite3*); + rc = sqlite3Fts2Init(db); } #endif #ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */ if( !db->mallocFailed && rc==SQLITE_OK ){ - rc = tdsqlite3Fts3Init(db); + rc = sqlite3Fts3Init(db); } #endif #if defined(SQLITE_ENABLE_ICU) || defined(SQLITE_ENABLE_ICU_COLLATIONS) if( !db->mallocFailed && rc==SQLITE_OK ){ - rc = tdsqlite3IcuInit(db); + rc = sqlite3IcuInit(db); } #endif #ifdef SQLITE_ENABLE_RTREE if( !db->mallocFailed && rc==SQLITE_OK){ - rc = tdsqlite3RtreeInit(db); + rc = sqlite3RtreeInit(db); } #endif #ifdef SQLITE_ENABLE_DBPAGE_VTAB if( !db->mallocFailed && rc==SQLITE_OK){ - rc = tdsqlite3DbpageRegister(db); + rc = sqlite3DbpageRegister(db); } #endif #ifdef SQLITE_ENABLE_DBSTAT_VTAB if( !db->mallocFailed && rc==SQLITE_OK){ - rc = tdsqlite3DbstatRegister(db); + rc = sqlite3DbstatRegister(db); } #endif #ifdef SQLITE_ENABLE_JSON1 if( !db->mallocFailed && rc==SQLITE_OK){ - rc = tdsqlite3Json1Init(db); + rc = sqlite3Json1Init(db); } #endif #ifdef SQLITE_ENABLE_STMTVTAB if( !db->mallocFailed && rc==SQLITE_OK){ - rc = tdsqlite3StmtVtabInit(db); + rc = sqlite3StmtVtabInit(db); } #endif #ifdef SQLCIPHER_EXT if( !db->mallocFailed && rc==SQLITE_OK ){ - extern int sqlcipherVtabInit(tdsqlite3 *); + extern int sqlcipherVtabInit(sqlite3 *); rc = sqlcipherVtabInit(db); } #endif @@ -166076,44 +166076,44 @@ static int openDatabase( */ #ifdef SQLITE_DEFAULT_LOCKING_MODE db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE; - tdsqlite3PagerLockingMode(tdsqlite3BtreePager(db->aDb[0].pBt), + sqlite3PagerLockingMode(sqlite3BtreePager(db->aDb[0].pBt), SQLITE_DEFAULT_LOCKING_MODE); #endif - if( rc ) tdsqlite3Error(db, rc); + if( rc ) sqlite3Error(db, rc); /* Enable the lookaside-malloc subsystem */ - setupLookaside(db, 0, tdsqlite3GlobalConfig.szLookaside, - tdsqlite3GlobalConfig.nLookaside); + setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside, + sqlite3GlobalConfig.nLookaside); - tdsqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); + sqlite3_wal_autocheckpoint(db, SQLITE_DEFAULT_WAL_AUTOCHECKPOINT); opendb_out: if( db ){ assert( db->mutex!=0 || isThreadsafe==0 - || tdsqlite3GlobalConfig.bFullMutex==0 ); - tdsqlite3_mutex_leave(db->mutex); + || sqlite3GlobalConfig.bFullMutex==0 ); + sqlite3_mutex_leave(db->mutex); } - rc = tdsqlite3_errcode(db); + rc = sqlite3_errcode(db); assert( db!=0 || rc==SQLITE_NOMEM ); if( rc==SQLITE_NOMEM ){ - tdsqlite3_close(db); + sqlite3_close(db); db = 0; }else if( rc!=SQLITE_OK ){ db->magic = SQLITE_MAGIC_SICK; } *ppDb = db; #ifdef SQLITE_ENABLE_SQLLOG - if( tdsqlite3GlobalConfig.xSqllog ){ + if( sqlite3GlobalConfig.xSqllog ){ /* Opening a db handle. Fourth parameter is passed 0. */ - void *pArg = tdsqlite3GlobalConfig.pSqllogArg; - tdsqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); + void *pArg = sqlite3GlobalConfig.pSqllogArg; + sqlite3GlobalConfig.xSqllog(pArg, db, zFilename, 0); } #endif #if defined(SQLITE_HAS_CODEC) - if( rc==SQLITE_OK ) tdsqlite3CodecQueryParameters(db, 0, zOpen); + if( rc==SQLITE_OK ) sqlite3CodecQueryParameters(db, 0, zOpen); #endif - tdsqlite3_free(zOpen); + sqlite3_free(zOpen); return rc & 0xff; } @@ -166121,16 +166121,16 @@ opendb_out: /* ** Open a new database handle. */ -SQLITE_API int tdsqlite3_open( +SQLITE_API int sqlite3_open( const char *zFilename, - tdsqlite3 **ppDb + sqlite3 **ppDb ){ return openDatabase(zFilename, ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); } -SQLITE_API int tdsqlite3_open_v2( +SQLITE_API int sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ - tdsqlite3 **ppDb, /* OUT: SQLite db handle */ + sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ const char *zVfs /* Name of VFS module to use */ ){ @@ -166141,12 +166141,12 @@ SQLITE_API int tdsqlite3_open_v2( /* ** Open a new database handle. */ -SQLITE_API int tdsqlite3_open16( +SQLITE_API int sqlite3_open16( const void *zFilename, - tdsqlite3 **ppDb + sqlite3 **ppDb ){ char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */ - tdsqlite3_value *pVal; + sqlite3_value *pVal; int rc; #ifdef SQLITE_ENABLE_API_ARMOR @@ -166154,13 +166154,13 @@ SQLITE_API int tdsqlite3_open16( #endif *ppDb = 0; #ifndef SQLITE_OMIT_AUTOINIT - rc = tdsqlite3_initialize(); + rc = sqlite3_initialize(); if( rc ) return rc; #endif if( zFilename==0 ) zFilename = "\000\000"; - pVal = tdsqlite3ValueNew(0); - tdsqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); - zFilename8 = tdsqlite3ValueText(pVal, SQLITE_UTF8); + pVal = sqlite3ValueNew(0); + sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC); + zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8); if( zFilename8 ){ rc = openDatabase(zFilename8, ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); @@ -166171,7 +166171,7 @@ SQLITE_API int tdsqlite3_open16( }else{ rc = SQLITE_NOMEM_BKPT; } - tdsqlite3ValueFree(pVal); + sqlite3ValueFree(pVal); return rc & 0xff; } @@ -166180,21 +166180,21 @@ SQLITE_API int tdsqlite3_open16( /* ** Register a new collation sequence with the database handle db. */ -SQLITE_API int tdsqlite3_create_collation( - tdsqlite3* db, +SQLITE_API int sqlite3_create_collation( + sqlite3* db, const char *zName, int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ - return tdsqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0); + return sqlite3_create_collation_v2(db, zName, enc, pCtx, xCompare, 0); } /* ** Register a new collation sequence with the database handle db. */ -SQLITE_API int tdsqlite3_create_collation_v2( - tdsqlite3* db, +SQLITE_API int sqlite3_create_collation_v2( + sqlite3* db, const char *zName, int enc, void* pCtx, @@ -166204,13 +166204,13 @@ SQLITE_API int tdsqlite3_create_collation_v2( int rc; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); rc = createCollation(db, zName, (u8)enc, pCtx, xCompare, xDel); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -166218,8 +166218,8 @@ SQLITE_API int tdsqlite3_create_collation_v2( /* ** Register a new collation sequence with the database handle db. */ -SQLITE_API int tdsqlite3_create_collation16( - tdsqlite3* db, +SQLITE_API int sqlite3_create_collation16( + sqlite3* db, const void *zName, int enc, void* pCtx, @@ -166229,17 +166229,17 @@ SQLITE_API int tdsqlite3_create_collation16( char *zName8; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - zName8 = tdsqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); + zName8 = sqlite3Utf16to8(db, zName, -1, SQLITE_UTF16NATIVE); if( zName8 ){ rc = createCollation(db, zName8, (u8)enc, pCtx, xCompare, 0); - tdsqlite3DbFree(db, zName8); + sqlite3DbFree(db, zName8); } - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } #endif /* SQLITE_OMIT_UTF16 */ @@ -166248,19 +166248,19 @@ SQLITE_API int tdsqlite3_create_collation16( ** Register a collation sequence factory callback with the database handle ** db. Replace any previously installed collation sequence factory. */ -SQLITE_API int tdsqlite3_collation_needed( - tdsqlite3 *db, +SQLITE_API int sqlite3_collation_needed( + sqlite3 *db, void *pCollNeededArg, - void(*xCollNeeded)(void*,tdsqlite3*,int eTextRep,const char*) + void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); db->xCollNeeded = xCollNeeded; db->xCollNeeded16 = 0; db->pCollNeededArg = pCollNeededArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } @@ -166269,19 +166269,19 @@ SQLITE_API int tdsqlite3_collation_needed( ** Register a collation sequence factory callback with the database handle ** db. Replace any previously installed collation sequence factory. */ -SQLITE_API int tdsqlite3_collation_needed16( - tdsqlite3 *db, +SQLITE_API int sqlite3_collation_needed16( + sqlite3 *db, void *pCollNeededArg, - void(*xCollNeeded16)(void*,tdsqlite3*,int eTextRep,const void*) + void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) ){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); db->xCollNeeded = 0; db->xCollNeeded16 = xCollNeeded16; db->pCollNeededArg = pCollNeededArg; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } #endif /* SQLITE_OMIT_UTF16 */ @@ -166291,7 +166291,7 @@ SQLITE_API int tdsqlite3_collation_needed16( ** This function is now an anachronism. It used to be used to recover from a ** malloc() failure, but SQLite now does this automatically. */ -SQLITE_API int tdsqlite3_global_recover(void){ +SQLITE_API int sqlite3_global_recover(void){ return SQLITE_OK; } #endif @@ -166302,9 +166302,9 @@ SQLITE_API int tdsqlite3_global_recover(void){ ** by default. Autocommit is disabled by a BEGIN statement and reenabled ** by the next COMMIT or ROLLBACK. */ -SQLITE_API int tdsqlite3_get_autocommit(tdsqlite3 *db){ +SQLITE_API int sqlite3_get_autocommit(sqlite3 *db){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } @@ -166320,40 +166320,40 @@ SQLITE_API int tdsqlite3_get_autocommit(tdsqlite3 *db){ ** 1. Serve as a convenient place to set a breakpoint in a debugger ** to detect when version error conditions occurs. ** -** 2. Invoke tdsqlite3_log() to provide the source code location where +** 2. Invoke sqlite3_log() to provide the source code location where ** a low-level error is first detected. */ -SQLITE_PRIVATE int tdsqlite3ReportError(int iErr, int lineno, const char *zType){ - tdsqlite3_log(iErr, "%s at line %d of [%.10s]", - zType, lineno, 20+tdsqlite3_sourceid()); +SQLITE_PRIVATE int sqlite3ReportError(int iErr, int lineno, const char *zType){ + sqlite3_log(iErr, "%s at line %d of [%.10s]", + zType, lineno, 20+sqlite3_sourceid()); return iErr; } -SQLITE_PRIVATE int tdsqlite3CorruptError(int lineno){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - return tdsqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption"); +SQLITE_PRIVATE int sqlite3CorruptError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CORRUPT, lineno, "database corruption"); } -SQLITE_PRIVATE int tdsqlite3MisuseError(int lineno){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - return tdsqlite3ReportError(SQLITE_MISUSE, lineno, "misuse"); +SQLITE_PRIVATE int sqlite3MisuseError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_MISUSE, lineno, "misuse"); } -SQLITE_PRIVATE int tdsqlite3CantopenError(int lineno){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - return tdsqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file"); +SQLITE_PRIVATE int sqlite3CantopenError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CANTOPEN, lineno, "cannot open file"); } #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3CorruptPgnoError(int lineno, Pgno pgno){ +SQLITE_PRIVATE int sqlite3CorruptPgnoError(int lineno, Pgno pgno){ char zMsg[100]; - tdsqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno); - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - return tdsqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); + sqlite3_snprintf(sizeof(zMsg), zMsg, "database corruption page %d", pgno); + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg); } -SQLITE_PRIVATE int tdsqlite3NomemError(int lineno){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - return tdsqlite3ReportError(SQLITE_NOMEM, lineno, "OOM"); +SQLITE_PRIVATE int sqlite3NomemError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_NOMEM, lineno, "OOM"); } -SQLITE_PRIVATE int tdsqlite3IoerrnomemError(int lineno){ - testcase( tdsqlite3GlobalConfig.xLog!=0 ); - return tdsqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); +SQLITE_PRIVATE int sqlite3IoerrnomemError(int lineno){ + testcase( sqlite3GlobalConfig.xLog!=0 ); + return sqlite3ReportError(SQLITE_IOERR_NOMEM, lineno, "I/O OOM error"); } #endif @@ -166365,7 +166365,7 @@ SQLITE_PRIVATE int tdsqlite3IoerrnomemError(int lineno){ ** SQLite no longer uses thread-specific data so this routine is now a ** no-op. It is retained for historical compatibility. */ -SQLITE_API void tdsqlite3_thread_cleanup(void){ +SQLITE_API void sqlite3_thread_cleanup(void){ } #endif @@ -166373,8 +166373,8 @@ SQLITE_API void tdsqlite3_thread_cleanup(void){ ** Return meta information about a specific column of a database table. ** See comment in sqlite3.h (sqlite.h.in) for details. */ -SQLITE_API int tdsqlite3_table_column_metadata( - tdsqlite3 *db, /* Connection handle */ +SQLITE_API int sqlite3_table_column_metadata( + sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ const char *zColumnName, /* Column name */ @@ -166397,21 +166397,21 @@ SQLITE_API int tdsqlite3_table_column_metadata( #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) || zTableName==0 ){ + if( !sqlite3SafetyCheckOk(db) || zTableName==0 ){ return SQLITE_MISUSE_BKPT; } #endif /* Ensure the database schema has been loaded */ - tdsqlite3_mutex_enter(db->mutex); - tdsqlite3BtreeEnterAll(db); - rc = tdsqlite3Init(db, &zErrMsg); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeEnterAll(db); + rc = sqlite3Init(db, &zErrMsg); if( SQLITE_OK!=rc ){ goto error_out; } /* Locate the table in question */ - pTab = tdsqlite3FindTable(db, zTableName, zDbName); + pTab = sqlite3FindTable(db, zTableName, zDbName); if( !pTab || pTab->pSelect ){ pTab = 0; goto error_out; @@ -166423,12 +166423,12 @@ SQLITE_API int tdsqlite3_table_column_metadata( }else{ for(iCol=0; iColnCol; iCol++){ pCol = &pTab->aCol[iCol]; - if( 0==tdsqlite3StrICmp(pCol->zName, zColumnName) ){ + if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){ break; } } if( iCol==pTab->nCol ){ - if( HasRowid(pTab) && tdsqlite3IsRowid(zColumnName) ){ + if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){ iCol = pTab->iPKey; pCol = iCol>=0 ? &pTab->aCol[iCol] : 0; }else{ @@ -166449,7 +166449,7 @@ SQLITE_API int tdsqlite3_table_column_metadata( ** explicitly declared column. Copy meta information from *pCol. */ if( pCol ){ - zDataType = tdsqlite3ColumnType(pCol,0); + zDataType = sqlite3ColumnType(pCol,0); zCollSeq = pCol->zColl; notnull = pCol->notNull!=0; primarykey = (pCol->colFlags & COLFLAG_PRIMKEY)!=0; @@ -166459,11 +166459,11 @@ SQLITE_API int tdsqlite3_table_column_metadata( primarykey = 1; } if( !zCollSeq ){ - zCollSeq = tdsqlite3StrBINARY; + zCollSeq = sqlite3StrBINARY; } error_out: - tdsqlite3BtreeLeaveAll(db); + sqlite3BtreeLeaveAll(db); /* Whether the function call succeeded or failed, set the output parameters ** to whatever their local counterparts contain. If an error did occur, @@ -166476,92 +166476,92 @@ error_out: if( pAutoinc ) *pAutoinc = autoinc; if( SQLITE_OK==rc && !pTab ){ - tdsqlite3DbFree(db, zErrMsg); - zErrMsg = tdsqlite3MPrintf(db, "no such table column: %s.%s", zTableName, + sqlite3DbFree(db, zErrMsg); + zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName, zColumnName); rc = SQLITE_ERROR; } - tdsqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg); - tdsqlite3DbFree(db, zErrMsg); - rc = tdsqlite3ApiExit(db, rc); - tdsqlite3_mutex_leave(db->mutex); + sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg); + sqlite3DbFree(db, zErrMsg); + rc = sqlite3ApiExit(db, rc); + sqlite3_mutex_leave(db->mutex); return rc; } /* ** Sleep for a little while. Return the amount of time slept. */ -SQLITE_API int tdsqlite3_sleep(int ms){ - tdsqlite3_vfs *pVfs; +SQLITE_API int sqlite3_sleep(int ms){ + sqlite3_vfs *pVfs; int rc; - pVfs = tdsqlite3_vfs_find(0); + pVfs = sqlite3_vfs_find(0); if( pVfs==0 ) return 0; /* This function works in milliseconds, but the underlying OsSleep() ** API uses microseconds. Hence the 1000's. */ - rc = (tdsqlite3OsSleep(pVfs, 1000*ms)/1000); + rc = (sqlite3OsSleep(pVfs, 1000*ms)/1000); return rc; } /* ** Enable or disable the extended result codes. */ -SQLITE_API int tdsqlite3_extended_result_codes(tdsqlite3 *db, int onoff){ +SQLITE_API int sqlite3_extended_result_codes(sqlite3 *db, int onoff){ #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); db->errMask = onoff ? 0xffffffff : 0xff; - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return SQLITE_OK; } /* ** Invoke the xFileControl method on a particular database. */ -SQLITE_API int tdsqlite3_file_control(tdsqlite3 *db, const char *zDbName, int op, void *pArg){ +SQLITE_API int sqlite3_file_control(sqlite3 *db, const char *zDbName, int op, void *pArg){ int rc = SQLITE_ERROR; Btree *pBtree; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif - tdsqlite3_mutex_enter(db->mutex); - pBtree = tdsqlite3DbNameToBtree(db, zDbName); + sqlite3_mutex_enter(db->mutex); + pBtree = sqlite3DbNameToBtree(db, zDbName); if( pBtree ){ Pager *pPager; - tdsqlite3_file *fd; - tdsqlite3BtreeEnter(pBtree); - pPager = tdsqlite3BtreePager(pBtree); + sqlite3_file *fd; + sqlite3BtreeEnter(pBtree); + pPager = sqlite3BtreePager(pBtree); assert( pPager!=0 ); - fd = tdsqlite3PagerFile(pPager); + fd = sqlite3PagerFile(pPager); assert( fd!=0 ); if( op==SQLITE_FCNTL_FILE_POINTER ){ - *(tdsqlite3_file**)pArg = fd; + *(sqlite3_file**)pArg = fd; rc = SQLITE_OK; }else if( op==SQLITE_FCNTL_VFS_POINTER ){ - *(tdsqlite3_vfs**)pArg = tdsqlite3PagerVfs(pPager); + *(sqlite3_vfs**)pArg = sqlite3PagerVfs(pPager); rc = SQLITE_OK; }else if( op==SQLITE_FCNTL_JOURNAL_POINTER ){ - *(tdsqlite3_file**)pArg = tdsqlite3PagerJrnlFile(pPager); + *(sqlite3_file**)pArg = sqlite3PagerJrnlFile(pPager); rc = SQLITE_OK; }else if( op==SQLITE_FCNTL_DATA_VERSION ){ - *(unsigned int*)pArg = tdsqlite3PagerDataVersion(pPager); + *(unsigned int*)pArg = sqlite3PagerDataVersion(pPager); rc = SQLITE_OK; }else{ - rc = tdsqlite3OsFileControl(fd, op, pArg); + rc = sqlite3OsFileControl(fd, op, pArg); } - tdsqlite3BtreeLeave(pBtree); + sqlite3BtreeLeave(pBtree); } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); return rc; } /* ** Interface to the testing logic. */ -SQLITE_API int tdsqlite3_test_control(int op, ...){ +SQLITE_API int sqlite3_test_control(int op, ...){ int rc = 0; #ifdef SQLITE_UNTESTABLE UNUSED_PARAMETER(op); @@ -166574,7 +166574,7 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** Save the current state of the PRNG. */ case SQLITE_TESTCTRL_PRNG_SAVE: { - tdsqlite3PrngSaveState(); + sqlite3PrngSaveState(); break; } @@ -166584,11 +166584,11 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** this verb acts like PRNG_RESET. */ case SQLITE_TESTCTRL_PRNG_RESTORE: { - tdsqlite3PrngRestoreState(); + sqlite3PrngRestoreState(); break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, tdsqlite3 *db); + /* sqlite3_test_control(SQLITE_TESTCTRL_PRNG_SEED, int x, sqlite3 *db); ** ** Control the seed for the pseudo-random number generator (PRNG) that ** is built into SQLite. Cases: @@ -166606,60 +166606,60 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** xRandomness method on the primary VFS. ** ** This test-control also resets the PRNG so that the new seed will - ** be used for the next call to tdsqlite3_randomness(). + ** be used for the next call to sqlite3_randomness(). */ #ifndef SQLITE_OMIT_WSD case SQLITE_TESTCTRL_PRNG_SEED: { int x = va_arg(ap, int); int y; - tdsqlite3 *db = va_arg(ap, tdsqlite3*); + sqlite3 *db = va_arg(ap, sqlite3*); assert( db==0 || db->aDb[0].pSchema!=0 ); if( db && (y = db->aDb[0].pSchema->schema_cookie)!=0 ){ x = y; } - tdsqlite3Config.iPrngSeed = x; - tdsqlite3_randomness(0,0); + sqlite3Config.iPrngSeed = x; + sqlite3_randomness(0,0); break; } #endif /* - ** tdsqlite3_test_control(BITVEC_TEST, size, program) + ** sqlite3_test_control(BITVEC_TEST, size, program) ** ** Run a test against a Bitvec object of size. The program argument ** is an array of integers that defines the test. Return -1 on a ** memory allocation error, 0 on success, or non-zero for an error. - ** See the tdsqlite3BitvecBuiltinTest() for additional information. + ** See the sqlite3BitvecBuiltinTest() for additional information. */ case SQLITE_TESTCTRL_BITVEC_TEST: { int sz = va_arg(ap, int); int *aProg = va_arg(ap, int*); - rc = tdsqlite3BitvecBuiltinTest(sz, aProg); + rc = sqlite3BitvecBuiltinTest(sz, aProg); break; } /* - ** tdsqlite3_test_control(FAULT_INSTALL, xCallback) + ** sqlite3_test_control(FAULT_INSTALL, xCallback) ** - ** Arrange to invoke xCallback() whenever tdsqlite3FaultSim() is called, + ** Arrange to invoke xCallback() whenever sqlite3FaultSim() is called, ** if xCallback is not NULL. ** - ** As a test of the fault simulator mechanism itself, tdsqlite3FaultSim(0) + ** As a test of the fault simulator mechanism itself, sqlite3FaultSim(0) ** is called immediately after installing the new callback and the return - ** value from tdsqlite3FaultSim(0) becomes the return from - ** tdsqlite3_test_control(). + ** value from sqlite3FaultSim(0) becomes the return from + ** sqlite3_test_control(). */ case SQLITE_TESTCTRL_FAULT_INSTALL: { /* MSVC is picky about pulling func ptrs from va lists. ** http://support.microsoft.com/kb/47961 - ** tdsqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); + ** sqlite3GlobalConfig.xTestCallback = va_arg(ap, int(*)(int)); */ typedef int(*TESTCALLBACKFUNC_t)(int); - tdsqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); - rc = tdsqlite3FaultSim(0); + sqlite3GlobalConfig.xTestCallback = va_arg(ap, TESTCALLBACKFUNC_t); + rc = sqlite3FaultSim(0); break; } /* - ** tdsqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) + ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) ** ** Register hooks to call to indicate which malloc() failures ** are benign. @@ -166670,12 +166670,12 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ void_function xBenignEnd; xBenignBegin = va_arg(ap, void_function); xBenignEnd = va_arg(ap, void_function); - tdsqlite3BenignMallocHooks(xBenignBegin, xBenignEnd); + sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd); break; } /* - ** tdsqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X) + ** sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, unsigned int X) ** ** Set the PENDING byte to the value in the argument, if X>0. ** Make no changes if X==0. Return the value of the pending byte @@ -166691,14 +166691,14 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ #ifndef SQLITE_OMIT_WSD { unsigned int newVal = va_arg(ap, unsigned int); - if( newVal ) tdsqlite3PendingByte = newVal; + if( newVal ) sqlite3PendingByte = newVal; } #endif break; } /* - ** tdsqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X) + ** sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, int X) ** ** This action provides a run-time test to see whether or not ** assert() was enabled at compile-time. If X is true and assert() @@ -166717,7 +166717,7 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ /* - ** tdsqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X) + ** sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, int X) ** ** This action provides a run-time test to see how the ALWAYS and ** NEVER macros were defined at compile-time. @@ -166735,9 +166735,9 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** ** The run-time test procedure might look something like this: ** - ** if( tdsqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){ + ** if( sqlite3_test_control(SQLITE_TESTCTRL_ALWAYS, 2)==2 ){ ** // ALWAYS() and NEVER() are no-op pass-through macros - ** }else if( tdsqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){ + ** }else if( sqlite3_test_control(SQLITE_TESTCTRL_ASSERT, 1) ){ ** // ALWAYS(x) asserts that x is true. NEVER(x) asserts x is false. ** }else{ ** // ALWAYS(x) is a constant 1. NEVER(x) is a constant 0. @@ -166750,7 +166750,7 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ } /* - ** tdsqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); + ** sqlite3_test_control(SQLITE_TESTCTRL_BYTEORDER); ** ** The integer returned reveals the byte-order of the computer on which ** SQLite is running: @@ -166765,21 +166765,21 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_RESERVE, tdsqlite3 *db, int N) + /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) ** ** Set the nReserve size to N for the main database on the database ** connection db. */ case SQLITE_TESTCTRL_RESERVE: { - tdsqlite3 *db = va_arg(ap, tdsqlite3*); + sqlite3 *db = va_arg(ap, sqlite3*); int x = va_arg(ap,int); - tdsqlite3_mutex_enter(db->mutex); - tdsqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0); - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0); + sqlite3_mutex_leave(db->mutex); break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, tdsqlite3 *db, int N) + /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N) ** ** Enable or disable various optimizations for testing purposes. The ** argument N is a bitmask of optimizations to be disabled. For normal @@ -166789,33 +166789,33 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** is obtained in every case. */ case SQLITE_TESTCTRL_OPTIMIZATIONS: { - tdsqlite3 *db = va_arg(ap, tdsqlite3*); + sqlite3 *db = va_arg(ap, sqlite3*); db->dbOptFlags = (u16)(va_arg(ap, int) & 0xffff); break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); + /* sqlite3_test_control(SQLITE_TESTCTRL_LOCALTIME_FAULT, int onoff); ** ** If parameter onoff is non-zero, subsequent calls to localtime() ** and its variants fail. If onoff is zero, undo this setting. */ case SQLITE_TESTCTRL_LOCALTIME_FAULT: { - tdsqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); + sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int); break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, tdsqlite3*); + /* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*); ** ** Toggle the ability to use internal functions on or off for ** the database connection given in the argument. */ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: { - tdsqlite3 *db = va_arg(ap, tdsqlite3*); + sqlite3 *db = va_arg(ap, sqlite3*); db->mDbFlags ^= DBFLAG_InternalFunc; break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); + /* sqlite3_test_control(SQLITE_TESTCTRL_NEVER_CORRUPT, int); ** ** Set or clear a flag that indicates that the database file is always well- ** formed and never corrupt. This flag is clear by default, indicating that @@ -166824,18 +166824,18 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** that demonstrat invariants on well-formed database files. */ case SQLITE_TESTCTRL_NEVER_CORRUPT: { - tdsqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); + sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int); + /* sqlite3_test_control(SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS, int); ** ** Set or clear a flag that causes SQLite to verify that type, name, ** and tbl_name fields of the sqlite_master table. This is normally ** on, but it is sometimes useful to turn it off for testing. */ case SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS: { - tdsqlite3GlobalConfig.bExtraSchemaChecks = va_arg(ap, int); + sqlite3GlobalConfig.bExtraSchemaChecks = va_arg(ap, int); break; } @@ -166845,11 +166845,11 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** provided to set a small and easily reachable reset value. */ case SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD: { - tdsqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int); + sqlite3GlobalConfig.iOnceResetThreshold = va_arg(ap, int); break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); + /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); ** ** Set the VDBE coverage callback function to xCallback with context ** pointer ptr. @@ -166858,30 +166858,30 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ #ifdef SQLITE_VDBE_COVERAGE typedef void (*branch_callback)(void*,unsigned int, unsigned char,unsigned char); - tdsqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); - tdsqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); + sqlite3GlobalConfig.xVdbeBranch = va_arg(ap,branch_callback); + sqlite3GlobalConfig.pVdbeBranchArg = va_arg(ap,void*); #endif break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */ + /* sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, nMax); */ case SQLITE_TESTCTRL_SORTER_MMAP: { - tdsqlite3 *db = va_arg(ap, tdsqlite3*); + sqlite3 *db = va_arg(ap, sqlite3*); db->nMaxSorterMmap = va_arg(ap, int); break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_ISINIT); + /* sqlite3_test_control(SQLITE_TESTCTRL_ISINIT); ** ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if ** not. */ case SQLITE_TESTCTRL_ISINIT: { - if( tdsqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; + if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; break; } - /* tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum); + /* sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, dbName, onOff, tnum); ** ** This test control is used to create imposter tables. "db" is a pointer ** to the database connection. dbName is the database name (ex: "main" or @@ -166898,20 +166898,20 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** effect of erasing all imposter tables. */ case SQLITE_TESTCTRL_IMPOSTER: { - tdsqlite3 *db = va_arg(ap, tdsqlite3*); - tdsqlite3_mutex_enter(db->mutex); - db->init.iDb = tdsqlite3FindDbName(db, va_arg(ap,const char*)); + sqlite3 *db = va_arg(ap, sqlite3*); + sqlite3_mutex_enter(db->mutex); + db->init.iDb = sqlite3FindDbName(db, va_arg(ap,const char*)); db->init.busy = db->init.imposterTable = va_arg(ap,int); db->init.newTnum = va_arg(ap,int); if( db->init.busy==0 && db->init.newTnum>0 ){ - tdsqlite3ResetAllSchemasOfConnection(db); + sqlite3ResetAllSchemasOfConnection(db); } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); break; } #if defined(YYCOVERAGE) - /* tdsqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out) + /* sqlite3_test_control(SQLITE_TESTCTRL_PARSER_COVERAGE, FILE *out) ** ** This test control (only available when SQLite is compiled with ** -DYYCOVERAGE) writes a report onto "out" that shows all @@ -166921,14 +166921,14 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ */ case SQLITE_TESTCTRL_PARSER_COVERAGE: { FILE *out = va_arg(ap, FILE*); - if( tdsqlite3ParserCoverage(out) ) rc = SQLITE_ERROR; + if( sqlite3ParserCoverage(out) ) rc = SQLITE_ERROR; break; } #endif /* defined(YYCOVERAGE) */ - /* tdsqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, tdsqlite3_context*); + /* sqlite3_test_control(SQLITE_TESTCTRL_RESULT_INTREAL, sqlite3_context*); ** - ** This test-control causes the most recent tdsqlite3_result_int64() value + ** This test-control causes the most recent sqlite3_result_int64() value ** to be interpreted as a MEM_IntReal instead of as an MEM_Int. Normally, ** MEM_IntReal values only arise during an INSERT operation of integer ** values into a REAL column, so they can be challenging to test. This @@ -166937,8 +166937,8 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** for testing purposes. */ case SQLITE_TESTCTRL_RESULT_INTREAL: { - tdsqlite3_context *pCtx = va_arg(ap, tdsqlite3_context*); - tdsqlite3ResultIntReal(pCtx); + sqlite3_context *pCtx = va_arg(ap, sqlite3_context*); + sqlite3ResultIntReal(pCtx); break; } } @@ -166958,14 +166958,14 @@ SQLITE_API int tdsqlite3_test_control(int op, ...){ ** parameter if it exists. If the parameter does not exist, this routine ** returns a NULL pointer. */ -SQLITE_API const char *tdsqlite3_uri_parameter(const char *zFilename, const char *zParam){ +SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){ if( zFilename==0 || zParam==0 ) return 0; - zFilename += tdsqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] ){ int x = strcmp(zFilename, zParam); - zFilename += tdsqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; if( x==0 ) return zFilename; - zFilename += tdsqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; } return 0; } @@ -166973,12 +166973,12 @@ SQLITE_API const char *tdsqlite3_uri_parameter(const char *zFilename, const char /* ** Return a pointer to the name of Nth query parameter of the filename. */ -SQLITE_API const char *tdsqlite3_uri_key(const char *zFilename, int N){ +SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N){ if( zFilename==0 || N<0 ) return 0; - zFilename += tdsqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; while( zFilename[0] && (N--)>0 ){ - zFilename += tdsqlite3Strlen30(zFilename) + 1; - zFilename += tdsqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; + zFilename += sqlite3Strlen30(zFilename) + 1; } return zFilename[0] ? zFilename : 0; } @@ -166986,23 +166986,23 @@ SQLITE_API const char *tdsqlite3_uri_key(const char *zFilename, int N){ /* ** Return a boolean value for a query parameter. */ -SQLITE_API int tdsqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ - const char *z = tdsqlite3_uri_parameter(zFilename, zParam); +SQLITE_API int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); bDflt = bDflt!=0; - return z ? tdsqlite3GetBoolean(z, bDflt) : bDflt; + return z ? sqlite3GetBoolean(z, bDflt) : bDflt; } /* ** Return a 64-bit integer value for a query parameter. */ -SQLITE_API tdsqlite3_int64 tdsqlite3_uri_int64( +SQLITE_API sqlite3_int64 sqlite3_uri_int64( const char *zFilename, /* Filename as passed to xOpen */ const char *zParam, /* URI parameter sought */ - tdsqlite3_int64 bDflt /* return if parameter is missing */ + sqlite3_int64 bDflt /* return if parameter is missing */ ){ - const char *z = tdsqlite3_uri_parameter(zFilename, zParam); - tdsqlite3_int64 v; - if( z && tdsqlite3DecOrHexToI64(z, &v)==0 ){ + const char *z = sqlite3_uri_parameter(zFilename, zParam); + sqlite3_int64 v; + if( z && sqlite3DecOrHexToI64(z, &v)==0 ){ bDflt = v; } return bDflt; @@ -167037,22 +167037,22 @@ static const char *startOfNameList(const char *zName){ ** an error that we cannot easily detect but that will likely cause memory ** corruption. */ -SQLITE_API const char *tdsqlite3_filename_database(const char *zFilename){ - return tdsqlite3_uri_parameter(zFilename - 3, "\003"); +SQLITE_API const char *sqlite3_filename_database(const char *zFilename){ + return sqlite3_uri_parameter(zFilename - 3, "\003"); } -SQLITE_API const char *tdsqlite3_filename_journal(const char *zFilename){ - const char *z = tdsqlite3_uri_parameter(startOfNameList(zFilename), "\001"); +SQLITE_API const char *sqlite3_filename_journal(const char *zFilename){ + const char *z = sqlite3_uri_parameter(startOfNameList(zFilename), "\001"); return ALWAYS(z) && z[0] ? z : 0; } -SQLITE_API const char *tdsqlite3_filename_wal(const char *zFilename){ - return tdsqlite3_uri_parameter(startOfNameList(zFilename), "\002"); +SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){ + return sqlite3_uri_parameter(startOfNameList(zFilename), "\002"); } /* ** Return the Btree pointer identified by zDbName. Return NULL if not found. */ -SQLITE_PRIVATE Btree *tdsqlite3DbNameToBtree(tdsqlite3 *db, const char *zDbName){ - int iDb = zDbName ? tdsqlite3FindDbName(db, zDbName) : 0; +SQLITE_PRIVATE Btree *sqlite3DbNameToBtree(sqlite3 *db, const char *zDbName){ + int iDb = zDbName ? sqlite3FindDbName(db, zDbName) : 0; return iDb<0 ? 0 : db->aDb[iDb].pBt; } @@ -167060,32 +167060,32 @@ SQLITE_PRIVATE Btree *tdsqlite3DbNameToBtree(tdsqlite3 *db, const char *zDbName) ** Return the filename of the database associated with a database ** connection. */ -SQLITE_API const char *tdsqlite3_db_filename(tdsqlite3 *db, const char *zDbName){ +SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){ Btree *pBt; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return 0; } #endif - pBt = tdsqlite3DbNameToBtree(db, zDbName); - return pBt ? tdsqlite3BtreeGetFilename(pBt) : 0; + pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeGetFilename(pBt) : 0; } /* ** Return 1 if database is read-only or 0 if read/write. Return -1 if ** no such database exists. */ -SQLITE_API int tdsqlite3_db_readonly(tdsqlite3 *db, const char *zDbName){ +SQLITE_API int sqlite3_db_readonly(sqlite3 *db, const char *zDbName){ Btree *pBt; #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ (void)SQLITE_MISUSE_BKPT; return -1; } #endif - pBt = tdsqlite3DbNameToBtree(db, zDbName); - return pBt ? tdsqlite3BtreeIsReadonly(pBt) : -1; + pBt = sqlite3DbNameToBtree(db, zDbName); + return pBt ? sqlite3BtreeIsReadonly(pBt) : -1; } #ifdef SQLITE_ENABLE_SNAPSHOT @@ -167093,35 +167093,35 @@ SQLITE_API int tdsqlite3_db_readonly(tdsqlite3 *db, const char *zDbName){ ** Obtain a snapshot handle for the snapshot of database zDb currently ** being read by handle db. */ -SQLITE_API int tdsqlite3_snapshot_get( - tdsqlite3 *db, +SQLITE_API int sqlite3_snapshot_get( + sqlite3 *db, const char *zDb, - tdsqlite3_snapshot **ppSnapshot + sqlite3_snapshot **ppSnapshot ){ int rc = SQLITE_ERROR; #ifndef SQLITE_OMIT_WAL #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( db->autoCommit==0 ){ - int iDb = tdsqlite3FindDbName(db, zDb); + int iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( 0==tdsqlite3BtreeIsInTrans(pBt) ){ - rc = tdsqlite3BtreeBeginTrans(pBt, 0, 0); + if( 0==sqlite3BtreeIsInTrans(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerSnapshotGet(tdsqlite3BtreePager(pBt), ppSnapshot); + rc = sqlite3PagerSnapshotGet(sqlite3BtreePager(pBt), ppSnapshot); } } } } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); #endif /* SQLITE_OMIT_WAL */ return rc; } @@ -167129,54 +167129,54 @@ SQLITE_API int tdsqlite3_snapshot_get( /* ** Open a read-transaction on the snapshot idendified by pSnapshot. */ -SQLITE_API int tdsqlite3_snapshot_open( - tdsqlite3 *db, +SQLITE_API int sqlite3_snapshot_open( + sqlite3 *db, const char *zDb, - tdsqlite3_snapshot *pSnapshot + sqlite3_snapshot *pSnapshot ){ int rc = SQLITE_ERROR; #ifndef SQLITE_OMIT_WAL #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } #endif - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); if( db->autoCommit==0 ){ int iDb; - iDb = tdsqlite3FindDbName(db, zDb); + iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( tdsqlite3BtreeIsInTrans(pBt)==0 ){ - Pager *pPager = tdsqlite3BtreePager(pBt); + if( sqlite3BtreeIsInTrans(pBt)==0 ){ + Pager *pPager = sqlite3BtreePager(pBt); int bUnlock = 0; - if( tdsqlite3BtreeIsInReadTrans(pBt) ){ + if( sqlite3BtreeIsInReadTrans(pBt) ){ if( db->nVdbeActive==0 ){ - rc = tdsqlite3PagerSnapshotCheck(pPager, pSnapshot); + rc = sqlite3PagerSnapshotCheck(pPager, pSnapshot); if( rc==SQLITE_OK ){ bUnlock = 1; - rc = tdsqlite3BtreeCommit(pBt); + rc = sqlite3BtreeCommit(pBt); } } }else{ rc = SQLITE_OK; } if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerSnapshotOpen(pPager, pSnapshot); + rc = sqlite3PagerSnapshotOpen(pPager, pSnapshot); } if( rc==SQLITE_OK ){ - rc = tdsqlite3BtreeBeginTrans(pBt, 0, 0); - tdsqlite3PagerSnapshotOpen(pPager, 0); + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); + sqlite3PagerSnapshotOpen(pPager, 0); } if( bUnlock ){ - tdsqlite3PagerSnapshotUnlock(pPager); + sqlite3PagerSnapshotUnlock(pPager); } } } } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); #endif /* SQLITE_OMIT_WAL */ return rc; } @@ -167185,39 +167185,39 @@ SQLITE_API int tdsqlite3_snapshot_open( ** Recover as many snapshots as possible from the wal file associated with ** schema zDb of database db. */ -SQLITE_API int tdsqlite3_snapshot_recover(tdsqlite3 *db, const char *zDb){ +SQLITE_API int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb){ int rc = SQLITE_ERROR; int iDb; #ifndef SQLITE_OMIT_WAL #ifdef SQLITE_ENABLE_API_ARMOR - if( !tdsqlite3SafetyCheckOk(db) ){ + if( !sqlite3SafetyCheckOk(db) ){ return SQLITE_MISUSE_BKPT; } #endif - tdsqlite3_mutex_enter(db->mutex); - iDb = tdsqlite3FindDbName(db, zDb); + sqlite3_mutex_enter(db->mutex); + iDb = sqlite3FindDbName(db, zDb); if( iDb==0 || iDb>1 ){ Btree *pBt = db->aDb[iDb].pBt; - if( 0==tdsqlite3BtreeIsInReadTrans(pBt) ){ - rc = tdsqlite3BtreeBeginTrans(pBt, 0, 0); + if( 0==sqlite3BtreeIsInReadTrans(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0, 0); if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerSnapshotRecover(tdsqlite3BtreePager(pBt)); - tdsqlite3BtreeCommit(pBt); + rc = sqlite3PagerSnapshotRecover(sqlite3BtreePager(pBt)); + sqlite3BtreeCommit(pBt); } } } - tdsqlite3_mutex_leave(db->mutex); + sqlite3_mutex_leave(db->mutex); #endif /* SQLITE_OMIT_WAL */ return rc; } /* -** Free a snapshot handle obtained from tdsqlite3_snapshot_get(). +** Free a snapshot handle obtained from sqlite3_snapshot_get(). */ -SQLITE_API void tdsqlite3_snapshot_free(tdsqlite3_snapshot *pSnapshot){ - tdsqlite3_free(pSnapshot); +SQLITE_API void sqlite3_snapshot_free(sqlite3_snapshot *pSnapshot){ + sqlite3_free(pSnapshot); } #endif /* SQLITE_ENABLE_SNAPSHOT */ @@ -167229,7 +167229,7 @@ SQLITE_API void tdsqlite3_snapshot_free(tdsqlite3_snapshot *pSnapshot){ ** The name can optionally begin with "SQLITE_" but the "SQLITE_" prefix ** is not required for a match. */ -SQLITE_API int tdsqlite3_compileoption_used(const char *zOptName){ +SQLITE_API int sqlite3_compileoption_used(const char *zOptName){ int i, n; int nOpt; const char **azCompileOpt; @@ -167241,16 +167241,16 @@ SQLITE_API int tdsqlite3_compileoption_used(const char *zOptName){ } #endif - azCompileOpt = tdsqlite3CompileOptions(&nOpt); + azCompileOpt = sqlite3CompileOptions(&nOpt); - if( tdsqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7; - n = tdsqlite3Strlen30(zOptName); + if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7; + n = sqlite3Strlen30(zOptName); /* Since nOpt is normally in single digits, a linear search is ** adequate. No need for a binary search. */ for(i=0; i=0 && NpNextBlocked){ +static void checkListProperties(sqlite3 *db){ + sqlite3 *p; + for(p=sqlite3BlockedList; p; p=p->pNextBlocked){ int seen = 0; - tdsqlite3 *p2; + sqlite3 *p2; /* Verify property (1) */ assert( p->pUnlockConnection || p->pBlockingConnection ); /* Verify property (2) */ - for(p2=tdsqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){ + for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){ if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1; assert( p2->xUnlockNotify==p->xUnlockNotify || !seen ); assert( db==0 || p->pUnlockConnection!=db ); @@ -167357,10 +167357,10 @@ static void checkListProperties(tdsqlite3 *db){ ** Remove connection db from the blocked connections list. If connection ** db is not currently a part of the list, this function is a no-op. */ -static void removeFromBlockedList(tdsqlite3 *db){ - tdsqlite3 **pp; +static void removeFromBlockedList(sqlite3 *db){ + sqlite3 **pp; assertMutexHeld(); - for(pp=&tdsqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){ + for(pp=&sqlite3BlockedList; *pp; pp = &(*pp)->pNextBlocked){ if( *pp==db ){ *pp = (*pp)->pNextBlocked; break; @@ -167372,11 +167372,11 @@ static void removeFromBlockedList(tdsqlite3 *db){ ** Add connection db to the blocked connections list. It is assumed ** that it is not already a part of the list. */ -static void addToBlockedList(tdsqlite3 *db){ - tdsqlite3 **pp; +static void addToBlockedList(sqlite3 *db){ + sqlite3 **pp; assertMutexHeld(); for( - pp=&tdsqlite3BlockedList; + pp=&sqlite3BlockedList; *pp && (*pp)->xUnlockNotify!=db->xUnlockNotify; pp=&(*pp)->pNextBlocked ); @@ -167388,7 +167388,7 @@ static void addToBlockedList(tdsqlite3 *db){ ** Obtain the STATIC_MASTER mutex. */ static void enterMutex(void){ - tdsqlite3_mutex_enter(tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); checkListProperties(0); } @@ -167398,7 +167398,7 @@ static void enterMutex(void){ static void leaveMutex(void){ assertMutexHeld(); checkListProperties(0); - tdsqlite3_mutex_leave(tdsqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); + sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } /* @@ -167422,14 +167422,14 @@ static void leaveMutex(void){ ** on the same "db". If xNotify==0 then any prior callbacks are immediately ** cancelled. */ -SQLITE_API int tdsqlite3_unlock_notify( - tdsqlite3 *db, +SQLITE_API int sqlite3_unlock_notify( + sqlite3 *db, void (*xNotify)(void **, int), void *pArg ){ int rc = SQLITE_OK; - tdsqlite3_mutex_enter(db->mutex); + sqlite3_mutex_enter(db->mutex); enterMutex(); if( xNotify==0 ){ @@ -167445,7 +167445,7 @@ SQLITE_API int tdsqlite3_unlock_notify( */ xNotify(&pArg, 1); }else{ - tdsqlite3 *p; + sqlite3 *p; for(p=db->pBlockingConnection; p && p!=db; p=p->pUnlockConnection){} if( p ){ @@ -167461,8 +167461,8 @@ SQLITE_API int tdsqlite3_unlock_notify( leaveMutex(); assert( !db->mallocFailed ); - tdsqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0)); - tdsqlite3_mutex_leave(db->mutex); + sqlite3ErrorWithMsg(db, rc, (rc?"database is deadlocked":0)); + sqlite3_mutex_leave(db->mutex); return rc; } @@ -167472,7 +167472,7 @@ SQLITE_API int tdsqlite3_unlock_notify( ** to the user because it requires a lock that will not be available ** until connection pBlocker concludes its current transaction. */ -SQLITE_PRIVATE void tdsqlite3ConnectionBlocked(tdsqlite3 *db, tdsqlite3 *pBlocker){ +SQLITE_PRIVATE void sqlite3ConnectionBlocked(sqlite3 *db, sqlite3 *pBlocker){ enterMutex(); if( db->pBlockingConnection==0 && db->pUnlockConnection==0 ){ addToBlockedList(db); @@ -167500,10 +167500,10 @@ SQLITE_PRIVATE void tdsqlite3ConnectionBlocked(tdsqlite3 *db, tdsqlite3 *pBlocke ** pUnlockConnection==0, remove the entry from the blocked connections ** list. */ -SQLITE_PRIVATE void tdsqlite3ConnectionUnlocked(tdsqlite3 *db){ +SQLITE_PRIVATE void sqlite3ConnectionUnlocked(sqlite3 *db){ void (*xUnlockNotify)(void **, int) = 0; /* Unlock-notify cb to invoke */ int nArg = 0; /* Number of entries in aArg[] */ - tdsqlite3 **pp; /* Iterator variable */ + sqlite3 **pp; /* Iterator variable */ void **aArg; /* Arguments to the unlock callback */ void **aDyn = 0; /* Dynamically allocated space for aArg[] */ void *aStatic[16]; /* Starter space for aArg[]. No malloc required */ @@ -167512,8 +167512,8 @@ SQLITE_PRIVATE void tdsqlite3ConnectionUnlocked(tdsqlite3 *db){ enterMutex(); /* Enter STATIC_MASTER mutex */ /* This loop runs once for each entry in the blocked-connections list. */ - for(pp=&tdsqlite3BlockedList; *pp; /* no-op */ ){ - tdsqlite3 *p = *pp; + for(pp=&sqlite3BlockedList; *pp; /* no-op */ ){ + sqlite3 *p = *pp; /* Step 1. */ if( p->pBlockingConnection==db ){ @@ -167528,17 +167528,17 @@ SQLITE_PRIVATE void tdsqlite3ConnectionUnlocked(tdsqlite3 *db){ nArg = 0; } - tdsqlite3BeginBenignMalloc(); + sqlite3BeginBenignMalloc(); assert( aArg==aDyn || (aDyn==0 && aArg==aStatic) ); assert( nArg<=(int)ArraySize(aStatic) || aArg==aDyn ); if( (!aDyn && nArg==(int)ArraySize(aStatic)) - || (aDyn && nArg==(int)(tdsqlite3MallocSize(aDyn)/sizeof(void*))) + || (aDyn && nArg==(int)(sqlite3MallocSize(aDyn)/sizeof(void*))) ){ /* The aArg[] array needs to grow. */ - void **pNew = (void **)tdsqlite3Malloc(nArg*sizeof(void *)*2); + void **pNew = (void **)sqlite3Malloc(nArg*sizeof(void *)*2); if( pNew ){ memcpy(pNew, aArg, nArg*sizeof(void *)); - tdsqlite3_free(aDyn); + sqlite3_free(aDyn); aDyn = aArg = pNew; }else{ /* This occurs when the array of context pointers that need to @@ -167569,7 +167569,7 @@ SQLITE_PRIVATE void tdsqlite3ConnectionUnlocked(tdsqlite3 *db){ nArg = 0; } } - tdsqlite3EndBenignMalloc(); + sqlite3EndBenignMalloc(); aArg[nArg++] = p->pUnlockArg; xUnlockNotify = p->xUnlockNotify; @@ -167591,7 +167591,7 @@ SQLITE_PRIVATE void tdsqlite3ConnectionUnlocked(tdsqlite3 *db){ if( nArg!=0 ){ xUnlockNotify(aArg, nArg); } - tdsqlite3_free(aDyn); + sqlite3_free(aDyn); leaveMutex(); /* Leave STATIC_MASTER mutex */ } @@ -167599,8 +167599,8 @@ SQLITE_PRIVATE void tdsqlite3ConnectionUnlocked(tdsqlite3 *db){ ** This is called when the database connection passed as an argument is ** being closed. The connection is removed from the blocked list. */ -SQLITE_PRIVATE void tdsqlite3ConnectionClosed(tdsqlite3 *db){ - tdsqlite3ConnectionUnlocked(db); +SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db){ + sqlite3ConnectionUnlocked(db); enterMutex(); removeFromBlockedList(db); checkListProperties(db); @@ -167939,9 +167939,9 @@ SQLITE_PRIVATE void tdsqlite3ConnectionClosed(tdsqlite3 *db){ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) -/* If not building as part of the core, include tdsqlite3ext.h. */ +/* If not building as part of the core, include sqlite3ext.h. */ #ifndef SQLITE_CORE -/* # include "tdsqlite3ext.h" */ +/* # include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT3 #endif @@ -167957,21 +167957,21 @@ SQLITE_EXTENSION_INIT3 ** Defines the interface to tokenizers used by fulltext-search. There ** are three basic components: ** -** tdsqlite3_tokenizer_module is a singleton defining the tokenizer +** sqlite3_tokenizer_module is a singleton defining the tokenizer ** interface functions. This is essentially the class structure for ** tokenizers. ** -** tdsqlite3_tokenizer is used to define a particular tokenizer, perhaps +** sqlite3_tokenizer is used to define a particular tokenizer, perhaps ** including customization information defined at creation time. ** -** tdsqlite3_tokenizer_cursor is generated by a tokenizer to generate +** sqlite3_tokenizer_cursor is generated by a tokenizer to generate ** tokens from a particular input. */ #ifndef _FTS3_TOKENIZER_H_ #define _FTS3_TOKENIZER_H_ /* TODO(shess) Only used for SQLITE_OK and SQLITE_DONE at this time. -** If tokenizers are to be allowed to call tdsqlite3_*() functions, then +** If tokenizers are to be allowed to call sqlite3_*() functions, then ** we will need a way to register the API consistently. */ /* #include "sqlite3.h" */ @@ -167979,27 +167979,27 @@ SQLITE_EXTENSION_INIT3 /* ** Structures used by the tokenizer interface. When a new tokenizer ** implementation is registered, the caller provides a pointer to -** an tdsqlite3_tokenizer_module containing pointers to the callback +** an sqlite3_tokenizer_module containing pointers to the callback ** functions that make up an implementation. ** ** When an fts3 table is created, it passes any arguments passed to ** the tokenizer clause of the CREATE VIRTUAL TABLE statement to the -** tdsqlite3_tokenizer_module.xCreate() function of the requested tokenizer +** sqlite3_tokenizer_module.xCreate() function of the requested tokenizer ** implementation. The xCreate() function in turn returns an -** tdsqlite3_tokenizer structure representing the specific tokenizer to +** sqlite3_tokenizer structure representing the specific tokenizer to ** be used for the fts3 table (customized by the tokenizer clause arguments). ** -** To tokenize an input buffer, the tdsqlite3_tokenizer_module.xOpen() -** method is called. It returns an tdsqlite3_tokenizer_cursor object +** To tokenize an input buffer, the sqlite3_tokenizer_module.xOpen() +** method is called. It returns an sqlite3_tokenizer_cursor object ** that may be used to tokenize a specific input buffer based on -** the tokenization rules supplied by a specific tdsqlite3_tokenizer +** the tokenization rules supplied by a specific sqlite3_tokenizer ** object. */ -typedef struct tdsqlite3_tokenizer_module tdsqlite3_tokenizer_module; -typedef struct tdsqlite3_tokenizer tdsqlite3_tokenizer; -typedef struct tdsqlite3_tokenizer_cursor tdsqlite3_tokenizer_cursor; +typedef struct sqlite3_tokenizer_module sqlite3_tokenizer_module; +typedef struct sqlite3_tokenizer sqlite3_tokenizer; +typedef struct sqlite3_tokenizer_cursor sqlite3_tokenizer_cursor; -struct tdsqlite3_tokenizer_module { +struct sqlite3_tokenizer_module { /* ** Structure version. Should always be set to 0 or 1. @@ -168020,20 +168020,20 @@ struct tdsqlite3_tokenizer_module { ** This method should return either SQLITE_OK (0), or an SQLite error ** code. If SQLITE_OK is returned, then *ppTokenizer should be set ** to point at the newly created tokenizer structure. The generic - ** tdsqlite3_tokenizer.pModule variable should not be initialized by + ** sqlite3_tokenizer.pModule variable should not be initialized by ** this callback. The caller will do so. */ int (*xCreate)( int argc, /* Size of argv array */ const char *const*argv, /* Tokenizer argument strings */ - tdsqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ ); /* ** Destroy an existing tokenizer. The fts3 module calls this method ** exactly once for each successful call to xCreate(). */ - int (*xDestroy)(tdsqlite3_tokenizer *pTokenizer); + int (*xDestroy)(sqlite3_tokenizer *pTokenizer); /* ** Create a tokenizer cursor to tokenize an input buffer. The caller @@ -168041,16 +168041,16 @@ struct tdsqlite3_tokenizer_module { ** until the cursor is closed (using the xClose() method). */ int (*xOpen)( - tdsqlite3_tokenizer *pTokenizer, /* Tokenizer object */ + sqlite3_tokenizer *pTokenizer, /* Tokenizer object */ const char *pInput, int nBytes, /* Input buffer */ - tdsqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Created tokenizer cursor */ ); /* ** Destroy an existing tokenizer cursor. The fts3 module calls this ** method exactly once for each successful call to xOpen(). */ - int (*xClose)(tdsqlite3_tokenizer_cursor *pCursor); + int (*xClose)(sqlite3_tokenizer_cursor *pCursor); /* ** Retrieve the next token from the tokenizer cursor pCursor. This @@ -168077,7 +168077,7 @@ struct tdsqlite3_tokenizer_module { ** should be converted to zInput. */ int (*xNext)( - tdsqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ + sqlite3_tokenizer_cursor *pCursor, /* Tokenizer cursor */ const char **ppToken, int *pnBytes, /* OUT: Normalized text for token */ int *piStartOffset, /* OUT: Byte offset of token in input buffer */ int *piEndOffset, /* OUT: Byte offset of end of token in input buffer */ @@ -168091,16 +168091,16 @@ struct tdsqlite3_tokenizer_module { /* ** Configure the language id of a tokenizer cursor. */ - int (*xLanguageid)(tdsqlite3_tokenizer_cursor *pCsr, int iLangid); + int (*xLanguageid)(sqlite3_tokenizer_cursor *pCsr, int iLangid); }; -struct tdsqlite3_tokenizer { - const tdsqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ +struct sqlite3_tokenizer { + const sqlite3_tokenizer_module *pModule; /* The module for this tokenizer */ /* Tokenizer implementations will typically add additional fields */ }; -struct tdsqlite3_tokenizer_cursor { - tdsqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ +struct sqlite3_tokenizer_cursor { + sqlite3_tokenizer *pTokenizer; /* Tokenizer for this cursor. */ /* Tokenizer implementations will typically add additional fields */ }; @@ -168187,20 +168187,20 @@ struct Fts3HashElem { /* ** Access routines. To delete, insert a NULL pointer. */ -SQLITE_PRIVATE void tdsqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey); -SQLITE_PRIVATE void *tdsqlite3Fts3HashInsert(Fts3Hash*, const void *pKey, int nKey, void *pData); -SQLITE_PRIVATE void *tdsqlite3Fts3HashFind(const Fts3Hash*, const void *pKey, int nKey); -SQLITE_PRIVATE void tdsqlite3Fts3HashClear(Fts3Hash*); -SQLITE_PRIVATE Fts3HashElem *tdsqlite3Fts3HashFindElem(const Fts3Hash *, const void *, int); +SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey); +SQLITE_PRIVATE void *sqlite3Fts3HashInsert(Fts3Hash*, const void *pKey, int nKey, void *pData); +SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash*, const void *pKey, int nKey); +SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash*); +SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem(const Fts3Hash *, const void *, int); /* ** Shorthand for the functions above */ -#define fts3HashInit tdsqlite3Fts3HashInit -#define fts3HashInsert tdsqlite3Fts3HashInsert -#define fts3HashFind tdsqlite3Fts3HashFind -#define fts3HashClear tdsqlite3Fts3HashClear -#define fts3HashFindElem tdsqlite3Fts3HashFindElem +#define fts3HashInit sqlite3Fts3HashInit +#define fts3HashInsert sqlite3Fts3HashInsert +#define fts3HashFind sqlite3Fts3HashFind +#define fts3HashClear sqlite3Fts3HashClear +#define fts3HashFindElem sqlite3Fts3HashFindElem /* ** Macros for looping over all elements of a hash table. The idiom is @@ -168320,8 +168320,8 @@ SQLITE_PRIVATE Fts3HashElem *tdsqlite3Fts3HashFindElem(const Fts3Hash *, const v ** guranteed that the database is not corrupt. */ #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) -SQLITE_API extern int tdsqlite3_fts3_may_be_corrupt; -# define assert_fts3_nc(x) assert(tdsqlite3_fts3_may_be_corrupt || (x)) +SQLITE_API extern int sqlite3_fts3_may_be_corrupt; +# define assert_fts3_nc(x) assert(sqlite3_fts3_may_be_corrupt || (x)) #else # define assert_fts3_nc(x) assert(x) #endif @@ -168340,10 +168340,10 @@ SQLITE_API extern int tdsqlite3_fts3_may_be_corrupt; # define ALWAYS(x) (1) # define NEVER(X) (0) #elif defined(SQLITE_DEBUG) -# define ALWAYS(x) tdsqlite3Fts3Always((x)!=0) -# define NEVER(x) tdsqlite3Fts3Never((x)!=0) -SQLITE_PRIVATE int tdsqlite3Fts3Always(int b); -SQLITE_PRIVATE int tdsqlite3Fts3Never(int b); +# define ALWAYS(x) sqlite3Fts3Always((x)!=0) +# define NEVER(x) sqlite3Fts3Never((x)!=0) +SQLITE_PRIVATE int sqlite3Fts3Always(int b); +SQLITE_PRIVATE int sqlite3Fts3Never(int b); #else # define ALWAYS(x) (x) # define NEVER(x) (x) @@ -168355,8 +168355,8 @@ SQLITE_PRIVATE int tdsqlite3Fts3Never(int b); typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ typedef short int i16; /* 2-byte (or larger) signed integer */ typedef unsigned int u32; /* 4-byte unsigned integer */ -typedef tdsqlite3_uint64 u64; /* 8-byte unsigned integer */ -typedef tdsqlite3_int64 i64; /* 8-byte signed integer */ +typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ +typedef sqlite3_int64 i64; /* 8-byte signed integer */ /* ** Macro used to suppress compiler warnings for unused parameters. @@ -168387,8 +168387,8 @@ typedef tdsqlite3_int64 i64; /* 8-byte signed integer */ #endif /* SQLITE_AMALGAMATION */ #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3Fts3Corrupt(void); -# define FTS_CORRUPT_VTAB tdsqlite3Fts3Corrupt() +SQLITE_PRIVATE int sqlite3Fts3Corrupt(void); +# define FTS_CORRUPT_VTAB sqlite3Fts3Corrupt() #else # define FTS_CORRUPT_VTAB SQLITE_CORRUPT_VTAB #endif @@ -168415,14 +168415,14 @@ typedef struct MatchinfoBuffer MatchinfoBuffer; ** arguments. */ struct Fts3Table { - tdsqlite3_vtab base; /* Base class used by SQLite core */ - tdsqlite3 *db; /* The database connection */ + sqlite3_vtab base; /* Base class used by SQLite core */ + sqlite3 *db; /* The database connection */ const char *zDb; /* logical database name */ const char *zName; /* virtual table name */ int nColumn; /* number of named columns in virtual table */ char **azColumn; /* column names. malloced */ u8 *abNotindexed; /* True for 'notindexed' columns */ - tdsqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ + sqlite3_tokenizer *pTokenizer; /* tokenizer for inserts and queries */ char *zContentTbl; /* content=xxx option, or NULL */ char *zLanguageid; /* languageid=xxx option, or NULL */ int nAutoincrmerge; /* Value configured by 'automerge' */ @@ -168432,8 +168432,8 @@ struct Fts3Table { /* Precompiled statements used by the implementation. Each of these ** statements is run and reset within a single virtual table API call. */ - tdsqlite3_stmt *aStmt[40]; - tdsqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */ + sqlite3_stmt *aStmt[40]; + sqlite3_stmt *pSeekStmt; /* Cache for fts3CursorSeekStmt() */ char *zReadExprlist; char *zWriteExprlist; @@ -168446,7 +168446,7 @@ struct Fts3Table { u8 bIgnoreSavepoint; /* True to ignore xSavepoint invocations */ int nPgsz; /* Page size for host database */ char *zSegmentsTbl; /* Name of %_segments table */ - tdsqlite3_blob *pSegments; /* Blob handle open on %_segments table */ + sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ /* ** The following array of hash tables is used to buffer pending index @@ -168509,24 +168509,24 @@ struct Fts3Table { ** the xOpen method. Cursors are destroyed using the xClose method. */ struct Fts3Cursor { - tdsqlite3_vtab_cursor base; /* Base class used by SQLite core */ + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ i16 eSearch; /* Search strategy (see below) */ u8 isEof; /* True if at End Of Results */ u8 isRequireSeek; /* True if must seek pStmt to %_content row */ u8 bSeekStmt; /* True if pStmt is a seek */ - tdsqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ + sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ Fts3Expr *pExpr; /* Parsed MATCH query string */ int iLangid; /* Language being queried for */ int nPhrase; /* Number of matchable phrases in query */ Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ - tdsqlite3_int64 iPrevId; /* Previous id read from aDoclist */ + sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ char *pNextId; /* Pointer into the body of aDoclist */ char *aDoclist; /* List of docids for full-text queries */ int nDoclist; /* Size of buffer at aDoclist */ u8 bDesc; /* True to sort in descending order */ int eEvalmode; /* An FTS3_EVAL_XX constant */ int nRowAvg; /* Average size of database rows, in pages */ - tdsqlite3_int64 nDoc; /* Documents in table */ + sqlite3_int64 nDoc; /* Documents in table */ i64 iMinDocid; /* Minimum docid to return */ i64 iMaxDocid; /* Maximum docid to return */ int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ @@ -168557,7 +168557,7 @@ struct Fts3Cursor { #define FTS3_FULLTEXT_SEARCH 2 /* Full-text index search */ /* -** The lower 16-bits of the tdsqlite3_index_info.idxNum value set by +** The lower 16-bits of the sqlite3_index_info.idxNum value set by ** the xBestIndex() method contains the Fts3Cursor.eSearch value described ** above. The upper 16-bits contain a combination of the following ** bits, used to describe extra constraints on full-text searches. @@ -168571,8 +168571,8 @@ struct Fts3Doclist { int nAll; /* Size of a[] in bytes */ char *pNextDocid; /* Pointer to next docid */ - tdsqlite3_int64 iDocid; /* Current docid (if pList!=0) */ - int bFreeList; /* True if pList should be tdsqlite3_free()d */ + sqlite3_int64 iDocid; /* Current docid (if pList!=0) */ + int bFreeList; /* True if pList should be sqlite3_free()d */ char *pList; /* Pointer to position list following iDocid */ int nList; /* Length of position list */ }; @@ -168602,7 +168602,7 @@ struct Fts3Phrase { int bIncr; /* True if doclist is loaded incrementally */ int iDoclistToken; - /* Used by tdsqlite3Fts3EvalPhrasePoslist() if this is a descendent of an + /* Used by sqlite3Fts3EvalPhrasePoslist() if this is a descendent of an ** OR condition. */ char *pOrPoslist; i64 iOrDocid; @@ -168633,7 +168633,7 @@ struct Fts3Phrase { ** aMI[iCol*3 + 1] = Number of occurrences ** aMI[iCol*3 + 2] = Number of rows containing at least one instance ** -** The aMI array is allocated using tdsqlite3_malloc(). It should be freed +** The aMI array is allocated using sqlite3_malloc(). It should be freed ** when the expression node is. */ struct Fts3Expr { @@ -168645,7 +168645,7 @@ struct Fts3Expr { Fts3Phrase *pPhrase; /* Valid if eType==FTSQUERY_PHRASE */ /* The following are used by the fts3_eval.c module. */ - tdsqlite3_int64 iDocid; /* Current docid */ + sqlite3_int64 iDocid; /* Current docid */ u8 bEof; /* True this expression is at EOF already */ u8 bStart; /* True if iDocid is valid */ u8 bDeferred; /* True if this expression is entirely deferred */ @@ -168674,47 +168674,47 @@ struct Fts3Expr { /* fts3_write.c */ -SQLITE_PRIVATE int tdsqlite3Fts3UpdateMethod(tdsqlite3_vtab*,int,tdsqlite3_value**,tdsqlite3_int64*); -SQLITE_PRIVATE int tdsqlite3Fts3PendingTermsFlush(Fts3Table *); -SQLITE_PRIVATE void tdsqlite3Fts3PendingTermsClear(Fts3Table *); -SQLITE_PRIVATE int tdsqlite3Fts3Optimize(Fts3Table *); -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderNew(int, int, tdsqlite3_int64, - tdsqlite3_int64, tdsqlite3_int64, const char *, int, Fts3SegReader**); -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderPending( +SQLITE_PRIVATE int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*); +SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *); +SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew(int, int, sqlite3_int64, + sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**); +SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( Fts3Table*,int,const char*,int,int,Fts3SegReader**); -SQLITE_PRIVATE void tdsqlite3Fts3SegReaderFree(Fts3SegReader *); -SQLITE_PRIVATE int tdsqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, tdsqlite3_stmt **); -SQLITE_PRIVATE int tdsqlite3Fts3ReadBlock(Fts3Table*, tdsqlite3_int64, char **, int*, int*); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *); +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs(Fts3Table*, int, int, int, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*, int*); -SQLITE_PRIVATE int tdsqlite3Fts3SelectDoctotal(Fts3Table *, tdsqlite3_stmt **); -SQLITE_PRIVATE int tdsqlite3Fts3SelectDocsize(Fts3Table *, tdsqlite3_int64, tdsqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); +SQLITE_PRIVATE int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); #ifndef SQLITE_DISABLE_FTS4_DEFERRED -SQLITE_PRIVATE void tdsqlite3Fts3FreeDeferredTokens(Fts3Cursor *); -SQLITE_PRIVATE int tdsqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); -SQLITE_PRIVATE int tdsqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); -SQLITE_PRIVATE void tdsqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); -SQLITE_PRIVATE int tdsqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *); +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList(Fts3DeferredToken *, char **, int *); #else -# define tdsqlite3Fts3FreeDeferredTokens(x) -# define tdsqlite3Fts3DeferToken(x,y,z) SQLITE_OK -# define tdsqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK -# define tdsqlite3Fts3FreeDeferredDoclists(x) -# define tdsqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK +# define sqlite3Fts3FreeDeferredTokens(x) +# define sqlite3Fts3DeferToken(x,y,z) SQLITE_OK +# define sqlite3Fts3CacheDeferredDoclists(x) SQLITE_OK +# define sqlite3Fts3FreeDeferredDoclists(x) +# define sqlite3Fts3DeferredTokenList(x,y,z) SQLITE_OK #endif -SQLITE_PRIVATE void tdsqlite3Fts3SegmentsClose(Fts3Table *); -SQLITE_PRIVATE int tdsqlite3Fts3MaxLevel(Fts3Table *, int *); +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *); +SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *, int *); -/* Special values interpreted by tdsqlite3SegReaderCursor() */ +/* Special values interpreted by sqlite3SegReaderCursor() */ #define FTS3_SEGCURSOR_PENDING -1 #define FTS3_SEGCURSOR_ALL -2 -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); -SQLITE_PRIVATE void tdsqlite3Fts3SegReaderFinish(Fts3MultiSegReader *); +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3MultiSegReader*, Fts3SegFilter*); +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3MultiSegReader *); +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish(Fts3MultiSegReader *); -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderCursor(Fts3Table *, +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor(Fts3Table *, int, int, int, const char *, int, int, int, Fts3MultiSegReader *); /* Flags allowed as part of the 4th argument to SegmentReaderIterate() */ @@ -168734,7 +168734,7 @@ struct Fts3SegFilter { }; struct Fts3MultiSegReader { - /* Used internally by tdsqlite3Fts3SegReaderXXX() calls */ + /* Used internally by sqlite3Fts3SegReaderXXX() calls */ Fts3SegReader **apSegment; /* Array of Fts3SegReader objects */ int nSegment; /* Size of apSegment array */ int nAdvance; /* How many seg-readers to advance */ @@ -168756,78 +168756,78 @@ struct Fts3MultiSegReader { int nDoclist; /* Size of aDoclist[] in bytes */ }; -SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table*,int,int); +SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table*,int,int); #define fts3GetVarint32(p, piVal) ( \ - (*(u8*)(p)&0x80) ? tdsqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ + (*(u8*)(p)&0x80) ? sqlite3Fts3GetVarint32(p, piVal) : (*piVal=*(u8*)(p), 1) \ ) /* fts3.c */ -SQLITE_PRIVATE void tdsqlite3Fts3ErrMsg(char**,const char*,...); -SQLITE_PRIVATE int tdsqlite3Fts3PutVarint(char *, tdsqlite3_int64); -SQLITE_PRIVATE int tdsqlite3Fts3GetVarint(const char *, sqlite_int64 *); -SQLITE_PRIVATE int tdsqlite3Fts3GetVarintU(const char *, sqlite_uint64 *); -SQLITE_PRIVATE int tdsqlite3Fts3GetVarintBounded(const char*,const char*,tdsqlite3_int64*); -SQLITE_PRIVATE int tdsqlite3Fts3GetVarint32(const char *, int *); -SQLITE_PRIVATE int tdsqlite3Fts3VarintLen(tdsqlite3_uint64); -SQLITE_PRIVATE void tdsqlite3Fts3Dequote(char *); -SQLITE_PRIVATE void tdsqlite3Fts3DoclistPrev(int,char*,int,char**,tdsqlite3_int64*,int*,u8*); -SQLITE_PRIVATE int tdsqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); -SQLITE_PRIVATE int tdsqlite3Fts3FirstFilter(tdsqlite3_int64, char *, int, char *); -SQLITE_PRIVATE void tdsqlite3Fts3CreateStatTable(int*, Fts3Table*); -SQLITE_PRIVATE int tdsqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc); +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char**,const char*,...); +SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *, sqlite3_int64); +SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *, sqlite_int64 *); +SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *, sqlite_uint64 *); +SQLITE_PRIVATE int sqlite3Fts3GetVarintBounded(const char*,const char*,sqlite3_int64*); +SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *, int *); +SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64); +SQLITE_PRIVATE void sqlite3Fts3Dequote(char *); +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev(int,char*,int,char**,sqlite3_int64*,int*,u8*); +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats(Fts3Cursor *, Fts3Expr *, u32 *); +SQLITE_PRIVATE int sqlite3Fts3FirstFilter(sqlite3_int64, char *, int, char *); +SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int*, Fts3Table*); +SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc); /* fts3_tokenizer.c */ -SQLITE_PRIVATE const char *tdsqlite3Fts3NextToken(const char *, int *); -SQLITE_PRIVATE int tdsqlite3Fts3InitHashTable(tdsqlite3 *, Fts3Hash *, const char *); -SQLITE_PRIVATE int tdsqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, - tdsqlite3_tokenizer **, char ** +SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *, int *); +SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *); +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *, + sqlite3_tokenizer **, char ** ); -SQLITE_PRIVATE int tdsqlite3Fts3IsIdChar(char); +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char); /* fts3_snippet.c */ -SQLITE_PRIVATE void tdsqlite3Fts3Offsets(tdsqlite3_context*, Fts3Cursor*); -SQLITE_PRIVATE void tdsqlite3Fts3Snippet(tdsqlite3_context *, Fts3Cursor *, const char *, +SQLITE_PRIVATE void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*); +SQLITE_PRIVATE void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *, const char *, const char *, int, int ); -SQLITE_PRIVATE void tdsqlite3Fts3Matchinfo(tdsqlite3_context *, Fts3Cursor *, const char *); -SQLITE_PRIVATE void tdsqlite3Fts3MIBufferFree(MatchinfoBuffer *p); +SQLITE_PRIVATE void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *); +SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p); /* fts3_expr.c */ -SQLITE_PRIVATE int tdsqlite3Fts3ExprParse(tdsqlite3_tokenizer *, int, +SQLITE_PRIVATE int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int, char **, int, int, int, const char *, int, Fts3Expr **, char ** ); -SQLITE_PRIVATE void tdsqlite3Fts3ExprFree(Fts3Expr *); +SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *); #ifdef SQLITE_TEST -SQLITE_PRIVATE int tdsqlite3Fts3ExprInitTestInterface(tdsqlite3 *db, Fts3Hash*); -SQLITE_PRIVATE int tdsqlite3Fts3InitTerm(tdsqlite3 *db); +SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*); +SQLITE_PRIVATE int sqlite3Fts3InitTerm(sqlite3 *db); #endif -SQLITE_PRIVATE int tdsqlite3Fts3OpenTokenizer(tdsqlite3_tokenizer *, int, const char *, int, - tdsqlite3_tokenizer_cursor ** +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int, + sqlite3_tokenizer_cursor ** ); /* fts3_aux.c */ -SQLITE_PRIVATE int tdsqlite3Fts3InitAux(tdsqlite3 *db); +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db); -SQLITE_PRIVATE void tdsqlite3Fts3EvalPhraseCleanup(Fts3Phrase *); +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *); -SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrStart( +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( Fts3Table*, Fts3MultiSegReader*, int, const char*, int); -SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrNext( - Fts3Table *, Fts3MultiSegReader *, tdsqlite3_int64 *, char **, int *); -SQLITE_PRIVATE int tdsqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); -SQLITE_PRIVATE int tdsqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); -SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( + Fts3Table *, Fts3MultiSegReader *, sqlite3_int64 *, char **, int *); +SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist(Fts3Cursor *, Fts3Expr *, int iCol, char **); +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl(Fts3Cursor *, Fts3MultiSegReader *, int *); +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr); /* fts3_tokenize_vtab.c */ -SQLITE_PRIVATE int tdsqlite3Fts3InitTok(tdsqlite3*, Fts3Hash *); +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3*, Fts3Hash *); /* fts3_unicode2.c (functions generated by parsing unicode text files) */ #ifndef SQLITE_DISABLE_FTS3_UNICODE -SQLITE_PRIVATE int tdsqlite3FtsUnicodeFold(int, int); -SQLITE_PRIVATE int tdsqlite3FtsUnicodeIsalnum(int); -SQLITE_PRIVATE int tdsqlite3FtsUnicodeIsdiacritic(int); +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int, int); +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int); +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int); #endif #endif /* !SQLITE_CORE || SQLITE_ENABLE_FTS3 */ @@ -168850,7 +168850,7 @@ SQLITE_PRIVATE int tdsqlite3FtsUnicodeIsdiacritic(int); /* #include "fts3.h" */ #ifndef SQLITE_CORE -/* # include "tdsqlite3ext.h" */ +/* # include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #endif @@ -168861,8 +168861,8 @@ static int fts3TermSegReaderCursor( #ifndef SQLITE_AMALGAMATION # if defined(SQLITE_DEBUG) -SQLITE_PRIVATE int tdsqlite3Fts3Always(int b) { assert( b ); return b; } -SQLITE_PRIVATE int tdsqlite3Fts3Never(int b) { assert( !b ); return b; } +SQLITE_PRIVATE int sqlite3Fts3Always(int b) { assert( b ); return b; } +SQLITE_PRIVATE int sqlite3Fts3Never(int b) { assert( !b ); return b; } # endif #endif @@ -168872,14 +168872,14 @@ SQLITE_PRIVATE int tdsqlite3Fts3Never(int b) { assert( !b ); return b; } ** assert() conditions in the fts3 code are activated - conditions that are ** only true if it is guaranteed that the fts3 database is not corrupt. */ -SQLITE_API int tdsqlite3_fts3_may_be_corrupt = 1; +SQLITE_API int sqlite3_fts3_may_be_corrupt = 1; /* ** Write a 64-bit variable-length integer to memory starting at p[0]. ** The length of data written will be between 1 and FTS3_VARINT_MAX bytes. ** The number of bytes written is returned. */ -SQLITE_PRIVATE int tdsqlite3Fts3PutVarint(char *p, sqlite_int64 v){ +SQLITE_PRIVATE int sqlite3Fts3PutVarint(char *p, sqlite_int64 v){ unsigned char *q = (unsigned char *) p; sqlite_uint64 vu = v; do{ @@ -168898,7 +168898,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3PutVarint(char *p, sqlite_int64 v){ v = (*ptr++); \ if( (v & mask2)==0 ){ var = v; return ret; } -SQLITE_PRIVATE int tdsqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){ +SQLITE_PRIVATE int sqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){ const unsigned char *p = (const unsigned char*)pBuf; const unsigned char *pStart = p; u32 a; @@ -168925,8 +168925,8 @@ SQLITE_PRIVATE int tdsqlite3Fts3GetVarintU(const char *pBuf, sqlite_uint64 *v){ ** Return the number of bytes read, or 0 on error. ** The value is stored in *v. */ -SQLITE_PRIVATE int tdsqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ - return tdsqlite3Fts3GetVarintU(pBuf, (tdsqlite3_uint64*)v); +SQLITE_PRIVATE int sqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ + return sqlite3Fts3GetVarintU(pBuf, (sqlite3_uint64*)v); } /* @@ -168935,7 +168935,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3GetVarint(const char *pBuf, sqlite_int64 *v){ ** Return the number of bytes read, or 0 on error. ** The value is stored in *v. */ -SQLITE_PRIVATE int tdsqlite3Fts3GetVarintBounded( +SQLITE_PRIVATE int sqlite3Fts3GetVarintBounded( const char *pBuf, const char *pEnd, sqlite_int64 *v @@ -168956,10 +168956,10 @@ SQLITE_PRIVATE int tdsqlite3Fts3GetVarintBounded( } /* -** Similar to tdsqlite3Fts3GetVarint(), except that the output is truncated to +** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to ** a non-negative 32-bit integer before it is returned. */ -SQLITE_PRIVATE int tdsqlite3Fts3GetVarint32(const char *p, int *pi){ +SQLITE_PRIVATE int sqlite3Fts3GetVarint32(const char *p, int *pi){ const unsigned char *ptr = (const unsigned char*)p; u32 a; @@ -168983,7 +168983,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3GetVarint32(const char *p, int *pi){ /* ** Return the number of bytes required to encode v as a varint */ -SQLITE_PRIVATE int tdsqlite3Fts3VarintLen(tdsqlite3_uint64 v){ +SQLITE_PRIVATE int sqlite3Fts3VarintLen(sqlite3_uint64 v){ int i = 0; do{ i++; @@ -169006,7 +169006,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3VarintLen(tdsqlite3_uint64 v){ ** `mno` becomes mno ** */ -SQLITE_PRIVATE void tdsqlite3Fts3Dequote(char *z){ +SQLITE_PRIVATE void sqlite3Fts3Dequote(char *z){ char quote; /* Quote character (if any ) */ quote = z[0]; @@ -169035,9 +169035,9 @@ SQLITE_PRIVATE void tdsqlite3Fts3Dequote(char *z){ ** to the first byte past the end of the varint. Add the value of the varint ** to *pVal. */ -static void fts3GetDeltaVarint(char **pp, tdsqlite3_int64 *pVal){ - tdsqlite3_int64 iVal; - *pp += tdsqlite3Fts3GetVarint(*pp, &iVal); +static void fts3GetDeltaVarint(char **pp, sqlite3_int64 *pVal){ + sqlite3_int64 iVal; + *pp += sqlite3Fts3GetVarint(*pp, &iVal); *pVal += iVal; } @@ -169053,9 +169053,9 @@ static void fts3GetDeltaVarint(char **pp, tdsqlite3_int64 *pVal){ static void fts3GetReverseVarint( char **pp, char *pStart, - tdsqlite3_int64 *pVal + sqlite3_int64 *pVal ){ - tdsqlite3_int64 iVal; + sqlite3_int64 iVal; char *p; /* Pointer p now points at the first byte past the varint we are @@ -169065,14 +169065,14 @@ static void fts3GetReverseVarint( p++; *pp = p; - tdsqlite3Fts3GetVarint(p, &iVal); + sqlite3Fts3GetVarint(p, &iVal); *pVal = iVal; } /* ** The xDisconnect() virtual table method. */ -static int fts3DisconnectMethod(tdsqlite3_vtab *pVtab){ +static int fts3DisconnectMethod(sqlite3_vtab *pVtab){ Fts3Table *p = (Fts3Table *)pVtab; int i; @@ -169080,31 +169080,31 @@ static int fts3DisconnectMethod(tdsqlite3_vtab *pVtab){ assert( p->pSegments==0 ); /* Free any prepared statements held */ - tdsqlite3_finalize(p->pSeekStmt); + sqlite3_finalize(p->pSeekStmt); for(i=0; iaStmt); i++){ - tdsqlite3_finalize(p->aStmt[i]); + sqlite3_finalize(p->aStmt[i]); } - tdsqlite3_free(p->zSegmentsTbl); - tdsqlite3_free(p->zReadExprlist); - tdsqlite3_free(p->zWriteExprlist); - tdsqlite3_free(p->zContentTbl); - tdsqlite3_free(p->zLanguageid); + sqlite3_free(p->zSegmentsTbl); + sqlite3_free(p->zReadExprlist); + sqlite3_free(p->zWriteExprlist); + sqlite3_free(p->zContentTbl); + sqlite3_free(p->zLanguageid); /* Invoke the tokenizer destructor to free the tokenizer. */ p->pTokenizer->pModule->xDestroy(p->pTokenizer); - tdsqlite3_free(p); + sqlite3_free(p); return SQLITE_OK; } /* ** Write an error message into *pzErr */ -SQLITE_PRIVATE void tdsqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){ +SQLITE_PRIVATE void sqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){ va_list ap; - tdsqlite3_free(*pzErr); + sqlite3_free(*pzErr); va_start(ap, zFormat); - *pzErr = tdsqlite3_vmprintf(zFormat, ap); + *pzErr = sqlite3_vmprintf(zFormat, ap); va_end(ap); } @@ -169117,7 +169117,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3ErrMsg(char **pzErr, const char *zFormat, ...){ */ static void fts3DbExec( int *pRc, /* Success code */ - tdsqlite3 *db, /* Database in which to run SQL */ + sqlite3 *db, /* Database in which to run SQL */ const char *zFormat, /* Format string for SQL */ ... /* Arguments to the format string */ ){ @@ -169125,24 +169125,24 @@ static void fts3DbExec( char *zSql; if( *pRc ) return; va_start(ap, zFormat); - zSql = tdsqlite3_vmprintf(zFormat, ap); + zSql = sqlite3_vmprintf(zFormat, ap); va_end(ap); if( zSql==0 ){ *pRc = SQLITE_NOMEM; }else{ - *pRc = tdsqlite3_exec(db, zSql, 0, 0, 0); - tdsqlite3_free(zSql); + *pRc = sqlite3_exec(db, zSql, 0, 0, 0); + sqlite3_free(zSql); } } /* ** The xDestroy() virtual table method. */ -static int fts3DestroyMethod(tdsqlite3_vtab *pVtab){ +static int fts3DestroyMethod(sqlite3_vtab *pVtab){ Fts3Table *p = (Fts3Table *)pVtab; int rc = SQLITE_OK; /* Return code */ const char *zDb = p->zDb; /* Name of database (e.g. "main", "temp") */ - tdsqlite3 *db = p->db; /* Database handle */ + sqlite3 *db = p->db; /* Database handle */ /* Drop the shadow tables */ fts3DbExec(&rc, db, @@ -169167,7 +169167,7 @@ static int fts3DestroyMethod(tdsqlite3_vtab *pVtab){ /* -** Invoke tdsqlite3_declare_vtab() to declare the schema for the FTS3 table +** Invoke sqlite3_declare_vtab() to declare the schema for the FTS3 table ** passed as the first argument. This is done as part of the xConnect() ** and xCreate() methods. ** @@ -169184,27 +169184,27 @@ static void fts3DeclareVtab(int *pRc, Fts3Table *p){ const char *zLanguageid; zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); - tdsqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); /* Create a list of user columns for the virtual table */ - zCols = tdsqlite3_mprintf("%Q, ", p->azColumn[0]); + zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); for(i=1; zCols && inColumn; i++){ - zCols = tdsqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); + zCols = sqlite3_mprintf("%z%Q, ", zCols, p->azColumn[i]); } /* Create the whole "CREATE TABLE" statement to pass to SQLite */ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "CREATE TABLE x(%s %Q HIDDEN, docid HIDDEN, %Q HIDDEN)", zCols, p->zName, zLanguageid ); if( !zCols || !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_declare_vtab(p->db, zSql); + rc = sqlite3_declare_vtab(p->db, zSql); } - tdsqlite3_free(zSql); - tdsqlite3_free(zCols); + sqlite3_free(zSql); + sqlite3_free(zCols); *pRc = rc; } } @@ -169212,7 +169212,7 @@ static void fts3DeclareVtab(int *pRc, Fts3Table *p){ /* ** Create the %_stat table if it does not already exist. */ -SQLITE_PRIVATE void tdsqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){ +SQLITE_PRIVATE void sqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){ fts3DbExec(pRc, p->db, "CREATE TABLE IF NOT EXISTS %Q.'%q_stat'" "(id INTEGER PRIMARY KEY, value BLOB);", @@ -169233,20 +169233,20 @@ SQLITE_PRIVATE void tdsqlite3Fts3CreateStatTable(int *pRc, Fts3Table *p){ static int fts3CreateTables(Fts3Table *p){ int rc = SQLITE_OK; /* Return code */ int i; /* Iterator variable */ - tdsqlite3 *db = p->db; /* The database connection */ + sqlite3 *db = p->db; /* The database connection */ if( p->zContentTbl==0 ){ const char *zLanguageid = p->zLanguageid; char *zContentCols; /* Columns of %_content table */ /* Create a list of user columns for the content table */ - zContentCols = tdsqlite3_mprintf("docid INTEGER PRIMARY KEY"); + zContentCols = sqlite3_mprintf("docid INTEGER PRIMARY KEY"); for(i=0; zContentCols && inColumn; i++){ char *z = p->azColumn[i]; - zContentCols = tdsqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); + zContentCols = sqlite3_mprintf("%z, 'c%d%q'", zContentCols, i, z); } if( zLanguageid && zContentCols ){ - zContentCols = tdsqlite3_mprintf("%z, langid", zContentCols, zLanguageid); + zContentCols = sqlite3_mprintf("%z, langid", zContentCols, zLanguageid); } if( zContentCols==0 ) rc = SQLITE_NOMEM; @@ -169255,7 +169255,7 @@ static int fts3CreateTables(Fts3Table *p){ "CREATE TABLE %Q.'%q_content'(%s)", p->zDb, p->zName, zContentCols ); - tdsqlite3_free(zContentCols); + sqlite3_free(zContentCols); } /* Create other tables */ @@ -169283,7 +169283,7 @@ static int fts3CreateTables(Fts3Table *p){ } assert( p->bHasStat==p->bFts4 ); if( p->bHasStat ){ - tdsqlite3Fts3CreateStatTable(&rc, p); + sqlite3Fts3CreateStatTable(&rc, p); } return rc; } @@ -169299,24 +169299,24 @@ static void fts3DatabasePageSize(int *pRc, Fts3Table *p){ if( *pRc==SQLITE_OK ){ int rc; /* Return code */ char *zSql; /* SQL text "PRAGMA %Q.page_size" */ - tdsqlite3_stmt *pStmt; /* Compiled "PRAGMA %Q.page_size" statement */ + sqlite3_stmt *pStmt; /* Compiled "PRAGMA %Q.page_size" statement */ - zSql = tdsqlite3_mprintf("PRAGMA %Q.page_size", p->zDb); + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", p->zDb); if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_prepare(p->db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare(p->db, zSql, -1, &pStmt, 0); if( rc==SQLITE_OK ){ - tdsqlite3_step(pStmt); - p->nPgsz = tdsqlite3_column_int(pStmt, 0); - rc = tdsqlite3_finalize(pStmt); + sqlite3_step(pStmt); + p->nPgsz = sqlite3_column_int(pStmt, 0); + rc = sqlite3_finalize(pStmt); }else if( rc==SQLITE_AUTH ){ p->nPgsz = 1024; rc = SQLITE_OK; } } assert( p->nPgsz>0 || rc!=SQLITE_OK ); - tdsqlite3_free(zSql); + sqlite3_free(zSql); *pRc = rc; } } @@ -169343,9 +169343,9 @@ static int fts3IsSpecialColumn( } *pnKey = (int)(zCsr-z); - zValue = tdsqlite3_mprintf("%s", &zCsr[1]); + zValue = sqlite3_mprintf("%s", &zCsr[1]); if( zValue ){ - tdsqlite3Fts3Dequote(zValue); + sqlite3Fts3Dequote(zValue); } *pzValue = zValue; return 1; @@ -169364,15 +169364,15 @@ static void fts3Appendf( va_list ap; char *z; va_start(ap, zFormat); - z = tdsqlite3_vmprintf(zFormat, ap); + z = sqlite3_vmprintf(zFormat, ap); va_end(ap); if( z && *pz ){ - char *z2 = tdsqlite3_mprintf("%s%s", *pz, z); - tdsqlite3_free(z); + char *z2 = sqlite3_mprintf("%s%s", *pz, z); + sqlite3_free(z); z = z2; } if( z==0 ) *pRc = SQLITE_NOMEM; - tdsqlite3_free(*pz); + sqlite3_free(*pz); *pz = z; } } @@ -169383,15 +169383,15 @@ static void fts3Appendf( ** ** fts3QuoteId("un \"zip\"") -> "un \"\"zip\"\"" ** -** The pointer returned points to memory obtained from tdsqlite3_malloc(). It -** is the callers responsibility to call tdsqlite3_free() to release this +** The pointer returned points to memory obtained from sqlite3_malloc(). It +** is the callers responsibility to call sqlite3_free() to release this ** memory. */ static char *fts3QuoteId(char const *zInput){ - tdsqlite3_int64 nRet; + sqlite3_int64 nRet; char *zRet; nRet = 2 + (int)strlen(zInput)*2 + 1; - zRet = tdsqlite3_malloc64(nRet); + zRet = sqlite3_malloc64(nRet); if( zRet ){ int i; char *z = zRet; @@ -169421,7 +169421,7 @@ static char *fts3QuoteId(char const *zInput){ ** ** "docid, unzip(x.'a'), unzip(x.'b'), unzip(x.'c') FROM %_content AS x" ** -** The pointer returned points to a buffer allocated by tdsqlite3_malloc(). It +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It ** is the responsibility of the caller to eventually free it. ** ** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and @@ -169448,7 +169448,7 @@ static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){ if( p->zLanguageid ){ fts3Appendf(pRc, &zRet, ", x.%Q", "langid"); } - tdsqlite3_free(zFree); + sqlite3_free(zFree); }else{ fts3Appendf(pRc, &zRet, "rowid"); for(i=0; inColumn; i++){ @@ -169478,7 +169478,7 @@ static char *fts3ReadExprList(Fts3Table *p, const char *zFunc, int *pRc){ ** ** "?, zip(?), zip(?), zip(?)" ** -** The pointer returned points to a buffer allocated by tdsqlite3_malloc(). It +** The pointer returned points to a buffer allocated by sqlite3_malloc(). It ** is the responsibility of the caller to eventually free it. ** ** If *pRc is not SQLITE_OK when this function is called, it is a no-op (and @@ -169504,7 +169504,7 @@ static char *fts3WriteExprList(Fts3Table *p, const char *zFunc, int *pRc){ if( p->zLanguageid ){ fts3Appendf(pRc, &zRet, ", ?"); } - tdsqlite3_free(zFree); + sqlite3_free(zFree); return zRet; } @@ -169554,7 +169554,7 @@ static int fts3GobbleInt(const char **pp, int *pnOut){ ** array. If an error does occur, an SQLite error code is returned. ** ** Regardless of whether or not an error is returned, it is the responsibility -** of the caller to call tdsqlite3_free() on the output array to free it. +** of the caller to call sqlite3_free() on the output array to free it. */ static int fts3PrefixParameter( const char *zParam, /* ABC in prefix=ABC parameter to parse */ @@ -169572,7 +169572,7 @@ static int fts3PrefixParameter( } } - aIndex = tdsqlite3_malloc64(sizeof(struct Fts3Index) * nIndex); + aIndex = sqlite3_malloc64(sizeof(struct Fts3Index) * nIndex); *apIndex = aIndex; if( !aIndex ){ return SQLITE_NOMEM; @@ -169619,14 +169619,14 @@ static int fts3PrefixParameter( ** the name of the corresponding column in table xxx. The array ** and its contents are allocated using a single allocation. It ** is the responsibility of the caller to free this allocation -** by eventually passing the *pazCol value to tdsqlite3_free(). +** by eventually passing the *pazCol value to sqlite3_free(). ** ** If the table cannot be found, an error code is returned and the output ** variables are undefined. Or, if an OOM is encountered, SQLITE_NOMEM is ** returned (and the output variables are undefined). */ static int fts3ContentColumns( - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ const char *zDb, /* Name of db (i.e. "main", "temp" etc.) */ const char *zTbl, /* Name of content table */ const char ***pazCol, /* OUT: Malloc'd array of column names */ @@ -169636,49 +169636,49 @@ static int fts3ContentColumns( ){ int rc = SQLITE_OK; /* Return code */ char *zSql; /* "SELECT *" statement on zTbl */ - tdsqlite3_stmt *pStmt = 0; /* Compiled version of zSql */ + sqlite3_stmt *pStmt = 0; /* Compiled version of zSql */ - zSql = tdsqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl); + zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", zDb, zTbl); if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_prepare(db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); if( rc!=SQLITE_OK ){ - tdsqlite3Fts3ErrMsg(pzErr, "%s", tdsqlite3_errmsg(db)); + sqlite3Fts3ErrMsg(pzErr, "%s", sqlite3_errmsg(db)); } } - tdsqlite3_free(zSql); + sqlite3_free(zSql); if( rc==SQLITE_OK ){ const char **azCol; /* Output array */ - tdsqlite3_int64 nStr = 0; /* Size of all column names (incl. 0x00) */ + sqlite3_int64 nStr = 0; /* Size of all column names (incl. 0x00) */ int nCol; /* Number of table columns */ int i; /* Used to iterate through columns */ /* Loop through the returned columns. Set nStr to the number of bytes of ** space required to store a copy of each column name, including the ** nul-terminator byte. */ - nCol = tdsqlite3_column_count(pStmt); + nCol = sqlite3_column_count(pStmt); for(i=0; i8 - && 0==tdsqlite3_strnicmp(z, "tokenize", 8) - && 0==tdsqlite3Fts3IsIdChar(z[8]) + && 0==sqlite3_strnicmp(z, "tokenize", 8) + && 0==sqlite3Fts3IsIdChar(z[8]) ){ - rc = tdsqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr); + rc = sqlite3Fts3InitTokenizer(pHash, &z[9], &pTokenizer, pzErr); } /* Check if it is an FTS4 special argument. */ @@ -169807,56 +169807,56 @@ static int fts3InitVtab( }else{ for(iOpt=0; iOptnOpt && !tdsqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){ + if( nKey==pOp->nOpt && !sqlite3_strnicmp(z, pOp->zOpt, pOp->nOpt) ){ break; } } switch( iOpt ){ case 0: /* MATCHINFO */ - if( strlen(zVal)!=4 || tdsqlite3_strnicmp(zVal, "fts3", 4) ){ - tdsqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); + if( strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "fts3", 4) ){ + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo: %s", zVal); rc = SQLITE_ERROR; } bNoDocsize = 1; break; case 1: /* PREFIX */ - tdsqlite3_free(zPrefix); + sqlite3_free(zPrefix); zPrefix = zVal; zVal = 0; break; case 2: /* COMPRESS */ - tdsqlite3_free(zCompress); + sqlite3_free(zCompress); zCompress = zVal; zVal = 0; break; case 3: /* UNCOMPRESS */ - tdsqlite3_free(zUncompress); + sqlite3_free(zUncompress); zUncompress = zVal; zVal = 0; break; case 4: /* ORDER */ - if( (strlen(zVal)!=3 || tdsqlite3_strnicmp(zVal, "asc", 3)) - && (strlen(zVal)!=4 || tdsqlite3_strnicmp(zVal, "desc", 4)) + if( (strlen(zVal)!=3 || sqlite3_strnicmp(zVal, "asc", 3)) + && (strlen(zVal)!=4 || sqlite3_strnicmp(zVal, "desc", 4)) ){ - tdsqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); + sqlite3Fts3ErrMsg(pzErr, "unrecognized order: %s", zVal); rc = SQLITE_ERROR; } bDescIdx = (zVal[0]=='d' || zVal[0]=='D'); break; case 5: /* CONTENT */ - tdsqlite3_free(zContent); + sqlite3_free(zContent); zContent = zVal; zVal = 0; break; case 6: /* LANGUAGEID */ assert( iOpt==6 ); - tdsqlite3_free(zLanguageid); + sqlite3_free(zLanguageid); zLanguageid = zVal; zVal = 0; break; @@ -169868,11 +169868,11 @@ static int fts3InitVtab( default: assert( iOpt==SizeofArray(aFts4Opt) ); - tdsqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); + sqlite3Fts3ErrMsg(pzErr, "unrecognized parameter: %s", z); rc = SQLITE_ERROR; break; } - tdsqlite3_free(zVal); + sqlite3_free(zVal); } } @@ -169891,12 +169891,12 @@ static int fts3InitVtab( ** TABLE statement, use all columns from the content table. */ if( rc==SQLITE_OK && zContent ){ - tdsqlite3_free(zCompress); - tdsqlite3_free(zUncompress); + sqlite3_free(zCompress); + sqlite3_free(zUncompress); zCompress = 0; zUncompress = 0; if( nCol==0 ){ - tdsqlite3_free((void*)aCol); + sqlite3_free((void*)aCol); aCol = 0; rc = fts3ContentColumns(db, argv[1], zContent,&aCol,&nCol,&nString,pzErr); @@ -169905,7 +169905,7 @@ static int fts3InitVtab( if( rc==SQLITE_OK && zLanguageid ){ int j; for(j=0; j0 ){ memcpy(zCsr, z, n); } zCsr[n] = '\0'; - tdsqlite3Fts3Dequote(zCsr); + sqlite3Fts3Dequote(zCsr); p->azColumn[iCol] = zCsr; zCsr += n+1; assert( zCsr <= &((char *)p)[nByte] ); @@ -170007,17 +170007,17 @@ static int fts3InitVtab( for(i=0; iazColumn[iCol], zNot, n) + && 0==sqlite3_strnicmp(p->azColumn[iCol], zNot, n) ){ p->abNotindexed[iCol] = 1; - tdsqlite3_free(zNot); + sqlite3_free(zNot); azNotindexed[i] = 0; } } } for(i=0; izReadExprlist = fts3ReadExprList(p, zUncompress, &rc); p->zWriteExprlist = fts3WriteExprList(p, zCompress, &rc); @@ -170058,18 +170058,18 @@ static int fts3InitVtab( fts3DeclareVtab(&rc, p); fts3_init_out: - tdsqlite3_free(zPrefix); - tdsqlite3_free(aIndex); - tdsqlite3_free(zCompress); - tdsqlite3_free(zUncompress); - tdsqlite3_free(zContent); - tdsqlite3_free(zLanguageid); - for(i=0; ipModule->xDestroy(pTokenizer); } @@ -170085,22 +170085,22 @@ fts3_init_out: ** work is done in function fts3InitVtab(). */ static int fts3ConnectMethod( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pAux, /* Pointer to tokenizer hash table */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVtab, /* OUT: New tdsqlite3_vtab object */ - char **pzErr /* OUT: tdsqlite3_malloc'd error message */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ ){ return fts3InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr); } static int fts3CreateMethod( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pAux, /* Pointer to tokenizer hash table */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVtab, /* OUT: New tdsqlite3_vtab object */ - char **pzErr /* OUT: tdsqlite3_malloc'd error message */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ ){ return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr); } @@ -170110,9 +170110,9 @@ static int fts3CreateMethod( ** extension is currently being used by a version of SQLite too old to ** support estimatedRows. In that case this function is a no-op. */ -static void fts3SetEstimatedRows(tdsqlite3_index_info *pIdxInfo, i64 nRow){ +static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){ #if SQLITE_VERSION_NUMBER>=3008002 - if( tdsqlite3_libversion_number()>=3008002 ){ + if( sqlite3_libversion_number()>=3008002 ){ pIdxInfo->estimatedRows = nRow; } #endif @@ -170123,9 +170123,9 @@ static void fts3SetEstimatedRows(tdsqlite3_index_info *pIdxInfo, i64 nRow){ ** extension is currently being used by a version of SQLite too old to ** support index-info flags. In that case this function is a no-op. */ -static void fts3SetUniqueFlag(tdsqlite3_index_info *pIdxInfo){ +static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){ #if SQLITE_VERSION_NUMBER>=3008012 - if( tdsqlite3_libversion_number()>=3008012 ){ + if( sqlite3_libversion_number()>=3008012 ){ pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE; } #endif @@ -170139,7 +170139,7 @@ static void fts3SetUniqueFlag(tdsqlite3_index_info *pIdxInfo){ ** 2. Full-text search using a MATCH operator on a non-docid column. ** 3. Linear scan of %_content table. */ -static int fts3BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInfo){ +static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts3Table *p = (Fts3Table *)pVTab; int i; /* Iterator variable */ int iCons = -1; /* Index of constraint to use */ @@ -170161,7 +170161,7 @@ static int fts3BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInf pInfo->estimatedCost = 5000000; for(i=0; inConstraint; i++){ int bDocid; /* True if this constraint is on docid */ - struct tdsqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; + struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i]; if( pCons->usable==0 ){ if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){ /* There exists an unusable MATCH constraint. This means that if @@ -170171,7 +170171,7 @@ static int fts3BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInf ** this, return a very high cost here. */ pInfo->idxNum = FTS3_FULLSCAN_SEARCH; pInfo->estimatedCost = 1e50; - fts3SetEstimatedRows(pInfo, ((tdsqlite3_int64)1) << 50); + fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50); return SQLITE_OK; } continue; @@ -170250,7 +170250,7 @@ static int fts3BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInf ** docid) order. Both ascending and descending are possible. */ if( pInfo->nOrderBy==1 ){ - struct tdsqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0]; + struct sqlite3_index_orderby *pOrder = &pInfo->aOrderBy[0]; if( pOrder->iColumn<0 || pOrder->iColumn==p->nColumn+1 ){ if( pOrder->desc ){ pInfo->idxStr = "DESC"; @@ -170268,8 +170268,8 @@ static int fts3BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInf /* ** Implementation of xOpen method. */ -static int fts3OpenMethod(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCsr){ - tdsqlite3_vtab_cursor *pCsr; /* Allocated cursor */ +static int fts3OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ + sqlite3_vtab_cursor *pCsr; /* Allocated cursor */ UNUSED_PARAMETER(pVTab); @@ -170277,7 +170277,7 @@ static int fts3OpenMethod(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCsr){ ** allocation succeeds, zero it and return SQLITE_OK. Otherwise, ** if the allocation fails, return SQLITE_NOMEM. */ - *ppCsr = pCsr = (tdsqlite3_vtab_cursor *)tdsqlite3_malloc(sizeof(Fts3Cursor)); + *ppCsr = pCsr = (sqlite3_vtab_cursor *)sqlite3_malloc(sizeof(Fts3Cursor)); if( !pCsr ){ return SQLITE_NOMEM; } @@ -170297,12 +170297,12 @@ static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){ Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; if( p->pSeekStmt==0 ){ p->pSeekStmt = pCsr->pStmt; - tdsqlite3_reset(pCsr->pStmt); + sqlite3_reset(pCsr->pStmt); pCsr->pStmt = 0; } pCsr->bSeekStmt = 0; } - tdsqlite3_finalize(pCsr->pStmt); + sqlite3_finalize(pCsr->pStmt); } /* @@ -170311,23 +170311,23 @@ static void fts3CursorFinalizeStmt(Fts3Cursor *pCsr){ */ static void fts3ClearCursor(Fts3Cursor *pCsr){ fts3CursorFinalizeStmt(pCsr); - tdsqlite3Fts3FreeDeferredTokens(pCsr); - tdsqlite3_free(pCsr->aDoclist); - tdsqlite3Fts3MIBufferFree(pCsr->pMIBuffer); - tdsqlite3Fts3ExprFree(pCsr->pExpr); - memset(&(&pCsr->base)[1], 0, sizeof(Fts3Cursor)-sizeof(tdsqlite3_vtab_cursor)); + sqlite3Fts3FreeDeferredTokens(pCsr); + sqlite3_free(pCsr->aDoclist); + sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); + sqlite3Fts3ExprFree(pCsr->pExpr); + memset(&(&pCsr->base)[1], 0, sizeof(Fts3Cursor)-sizeof(sqlite3_vtab_cursor)); } /* ** Close the cursor. For additional information see the documentation ** on the xClose method of the virtual table interface. */ -static int fts3CloseMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts3CloseMethod(sqlite3_vtab_cursor *pCursor){ Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); fts3ClearCursor(pCsr); assert( ((Fts3Table *)pCsr->base.pVtab)->pSegments==0 ); - tdsqlite3_free(pCsr); + sqlite3_free(pCsr); return SQLITE_OK; } @@ -170349,14 +170349,14 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){ pCsr->pStmt = p->pSeekStmt; p->pSeekStmt = 0; }else{ - zSql = tdsqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); + zSql = sqlite3_mprintf("SELECT %s WHERE rowid = ?", p->zReadExprlist); if( !zSql ) return SQLITE_NOMEM; p->bLock++; - rc = tdsqlite3_prepare_v3( + rc = sqlite3_prepare_v3( p->db, zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 ); p->bLock--; - tdsqlite3_free(zSql); + sqlite3_free(zSql); } if( rc==SQLITE_OK ) pCsr->bSeekStmt = 1; } @@ -170368,21 +170368,21 @@ static int fts3CursorSeekStmt(Fts3Cursor *pCsr){ ** of the %_content table that contains the last match. Return ** SQLITE_OK on success. */ -static int fts3CursorSeek(tdsqlite3_context *pContext, Fts3Cursor *pCsr){ +static int fts3CursorSeek(sqlite3_context *pContext, Fts3Cursor *pCsr){ int rc = SQLITE_OK; if( pCsr->isRequireSeek ){ rc = fts3CursorSeekStmt(pCsr); if( rc==SQLITE_OK ){ Fts3Table *pTab = (Fts3Table*)pCsr->base.pVtab; pTab->bLock++; - tdsqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); + sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iPrevId); pCsr->isRequireSeek = 0; - if( SQLITE_ROW==tdsqlite3_step(pCsr->pStmt) ){ + if( SQLITE_ROW==sqlite3_step(pCsr->pStmt) ){ pTab->bLock--; return SQLITE_OK; }else{ pTab->bLock--; - rc = tdsqlite3_reset(pCsr->pStmt); + rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK && ((Fts3Table *)pCsr->base.pVtab)->zContentTbl==0 ){ /* If no row was found and no error has occurred, then the %_content ** table is missing a row that is present in the full-text index. @@ -170395,7 +170395,7 @@ static int fts3CursorSeek(tdsqlite3_context *pContext, Fts3Cursor *pCsr){ } if( rc!=SQLITE_OK && pContext ){ - tdsqlite3_result_error_code(pContext, rc); + sqlite3_result_error_code(pContext, rc); } return rc; } @@ -170420,8 +170420,8 @@ static int fts3ScanInteriorNode( int nTerm, /* Size of term zTerm in bytes */ const char *zNode, /* Buffer containing segment interior node */ int nNode, /* Size of buffer at zNode */ - tdsqlite3_int64 *piFirst, /* OUT: Selected child node */ - tdsqlite3_int64 *piLast /* OUT: Selected child node */ + sqlite3_int64 *piFirst, /* OUT: Selected child node */ + sqlite3_int64 *piLast /* OUT: Selected child node */ ){ int rc = SQLITE_OK; /* Return code */ const char *zCsr = zNode; /* Cursor to iterate through node */ @@ -170429,7 +170429,7 @@ static int fts3ScanInteriorNode( char *zBuffer = 0; /* Buffer to load terms into */ i64 nAlloc = 0; /* Size of allocated buffer */ int isFirstTerm = 1; /* True when processing first term on page */ - tdsqlite3_int64 iChild; /* Block id of child node to descend to */ + sqlite3_int64 iChild; /* Block id of child node to descend to */ /* Skip over the 'height' varint that occurs at the start of every ** interior node. Then load the blockid of the left-child of the b-tree @@ -170442,10 +170442,10 @@ static int fts3ScanInteriorNode( ** either more than 20 bytes of allocated space following the nNode bytes of ** contents, or two zero bytes. Or, if the node is read from the %_segments ** table, then there are always 20 bytes of zeroed padding following the - ** nNode bytes of content (see tdsqlite3Fts3ReadBlock() for details). + ** nNode bytes of content (see sqlite3Fts3ReadBlock() for details). */ - zCsr += tdsqlite3Fts3GetVarint(zCsr, &iChild); - zCsr += tdsqlite3Fts3GetVarint(zCsr, &iChild); + zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); + zCsr += sqlite3Fts3GetVarint(zCsr, &iChild); if( zCsr>zEnd ){ return FTS_CORRUPT_VTAB; } @@ -170472,7 +170472,7 @@ static int fts3ScanInteriorNode( if( (i64)nPrefix+nSuffix>nAlloc ){ char *zNew; nAlloc = ((i64)nPrefix+nSuffix) * 2; - zNew = (char *)tdsqlite3_realloc64(zBuffer, nAlloc); + zNew = (char *)sqlite3_realloc64(zBuffer, nAlloc); if( !zNew ){ rc = SQLITE_NOMEM; goto finish_scan; @@ -170511,7 +170511,7 @@ static int fts3ScanInteriorNode( if( piLast ) *piLast = iChild; finish_scan: - tdsqlite3_free(zBuffer); + sqlite3_free(zBuffer); return rc; } @@ -170543,8 +170543,8 @@ static int fts3SelectLeaf( int nTerm, /* Size of term zTerm in bytes */ const char *zNode, /* Buffer containing segment interior node */ int nNode, /* Size of buffer at zNode */ - tdsqlite3_int64 *piLeaf, /* Selected leaf node */ - tdsqlite3_int64 *piLeaf2 /* Selected leaf node */ + sqlite3_int64 *piLeaf, /* Selected leaf node */ + sqlite3_int64 *piLeaf2 /* Selected leaf node */ ){ int rc = SQLITE_OK; /* Return code */ int iHeight; /* Height of this node in tree */ @@ -170560,17 +170560,17 @@ static int fts3SelectLeaf( int nBlob = 0; /* Size of zBlob in bytes */ if( piLeaf && piLeaf2 && (*piLeaf!=*piLeaf2) ){ - rc = tdsqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); + rc = sqlite3Fts3ReadBlock(p, *piLeaf, &zBlob, &nBlob, 0); if( rc==SQLITE_OK ){ rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, 0); } - tdsqlite3_free(zBlob); + sqlite3_free(zBlob); piLeaf = 0; zBlob = 0; } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0); + rc = sqlite3Fts3ReadBlock(p, piLeaf?*piLeaf:*piLeaf2, &zBlob, &nBlob, 0); } if( rc==SQLITE_OK ){ int iNewHeight = 0; @@ -170581,7 +170581,7 @@ static int fts3SelectLeaf( rc = fts3SelectLeaf(p, zTerm, nTerm, zBlob, nBlob, piLeaf, piLeaf2); } } - tdsqlite3_free(zBlob); + sqlite3_free(zBlob); } return rc; @@ -170593,11 +170593,11 @@ static int fts3SelectLeaf( */ static void fts3PutDeltaVarint( char **pp, /* IN/OUT: Output pointer */ - tdsqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ - tdsqlite3_int64 iVal /* Write this value to the list */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + sqlite3_int64 iVal /* Write this value to the list */ ){ assert( iVal-*piPrev > 0 || (*piPrev==0 && iVal==0) ); - *pp += tdsqlite3Fts3PutVarint(*pp, iVal-*piPrev); + *pp += sqlite3Fts3PutVarint(*pp, iVal-*piPrev); *piPrev = iVal; } @@ -170710,7 +170710,7 @@ static void fts3ColumnlistCopy(char **pp, char **ppPoslist){ */ static void fts3ReadNextPos( char **pp, /* IN/OUT: Pointer into position-list buffer */ - tdsqlite3_int64 *pi /* IN/OUT: Value read from position-list */ + sqlite3_int64 *pi /* IN/OUT: Value read from position-list */ ){ if( (**pp)&0xFE ){ fts3GetDeltaVarint(pp, pi); @@ -170733,7 +170733,7 @@ static int fts3PutColNumber(char **pp, int iCol){ int n = 0; /* Number of bytes written */ if( iCol ){ char *p = *pp; /* Output pointer */ - n = 1 + tdsqlite3Fts3PutVarint(&p[1], iCol); + n = 1 + sqlite3Fts3PutVarint(&p[1], iCol); *p = 0x01; *pp = &p[n]; } @@ -170775,9 +170775,9 @@ static int fts3PoslistMerge( else iCol2 = 0; if( iCol1==iCol2 ){ - tdsqlite3_int64 i1 = 0; /* Last position from pp1 */ - tdsqlite3_int64 i2 = 0; /* Last position from pp2 */ - tdsqlite3_int64 iPrev = 0; + sqlite3_int64 i1 = 0; /* Last position from pp1 */ + sqlite3_int64 i2 = 0; /* Last position from pp2 */ + sqlite3_int64 iPrev = 0; int n = fts3PutColNumber(&p, iCol1); p1 += n; p2 += n; @@ -170874,13 +170874,13 @@ static int fts3PoslistPhraseMerge( while( 1 ){ if( iCol1==iCol2 ){ char *pSave = p; - tdsqlite3_int64 iPrev = 0; - tdsqlite3_int64 iPos1 = 0; - tdsqlite3_int64 iPos2 = 0; + sqlite3_int64 iPrev = 0; + sqlite3_int64 iPos1 = 0; + sqlite3_int64 iPos2 = 0; if( iCol1 ){ *p++ = POS_COLUMN; - p += tdsqlite3Fts3PutVarint(p, iCol1); + p += sqlite3Fts3PutVarint(p, iCol1); } fts3GetDeltaVarint(&p1, &iPos1); iPos1 -= 2; @@ -170891,7 +170891,7 @@ static int fts3PoslistPhraseMerge( if( iPos2==iPos1+nToken || (isExact==0 && iPos2>iPos1 && iPos2<=iPos1+nToken) ){ - tdsqlite3_int64 iSave; + sqlite3_int64 iSave; iSave = isSaveLeft ? iPos1 : iPos2; fts3PutDeltaVarint(&p, &iPrev, iSave+2); iPrev -= 2; pSave = 0; @@ -171029,13 +171029,13 @@ static void fts3GetDeltaVarint3( char **pp, /* IN/OUT: Point to read varint from */ char *pEnd, /* End of buffer */ int bDescIdx, /* True if docids are descending */ - tdsqlite3_int64 *pVal /* IN/OUT: Integer value */ + sqlite3_int64 *pVal /* IN/OUT: Integer value */ ){ if( *pp>=pEnd ){ *pp = 0; }else{ u64 iVal; - *pp += tdsqlite3Fts3GetVarintU(*pp, &iVal); + *pp += sqlite3Fts3GetVarintU(*pp, &iVal); if( bDescIdx ){ *pVal = (i64)((u64)*pVal - iVal); }else{ @@ -171062,11 +171062,11 @@ static void fts3GetDeltaVarint3( static void fts3PutDeltaVarint3( char **pp, /* IN/OUT: Output pointer */ int bDescIdx, /* True for descending docids */ - tdsqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ + sqlite3_int64 *piPrev, /* IN/OUT: Previous value written to list */ int *pbFirst, /* IN/OUT: True after first int written */ - tdsqlite3_int64 iVal /* Write this value to the list */ + sqlite3_int64 iVal /* Write this value to the list */ ){ - tdsqlite3_uint64 iWrite; + sqlite3_uint64 iWrite; if( bDescIdx==0 || *pbFirst==0 ){ assert_fts3_nc( *pbFirst==0 || iVal>=*piPrev ); iWrite = (u64)iVal - (u64)*piPrev; @@ -171076,7 +171076,7 @@ static void fts3PutDeltaVarint3( } assert( *pbFirst || *piPrev==0 ); assert_fts3_nc( *pbFirst==0 || iWrite>0 ); - *pp += tdsqlite3Fts3PutVarint(*pp, iWrite); + *pp += sqlite3Fts3PutVarint(*pp, iWrite); *piPrev = iVal; *pbFirst = 1; } @@ -171101,7 +171101,7 @@ static void fts3PutDeltaVarint3( ** should be false. If they are sorted in ascending order, it should be ** passed a non-zero value. ** -** If no error occurs, *paOut is set to point at an tdsqlite3_malloc'd buffer +** If no error occurs, *paOut is set to point at an sqlite3_malloc'd buffer ** containing the output doclist and SQLITE_OK is returned. In this case ** *pnOut is set to the number of bytes in the output doclist. ** @@ -171115,9 +171115,9 @@ static int fts3DoclistOrMerge( char **paOut, int *pnOut /* OUT: Malloc'd doclist */ ){ int rc = SQLITE_OK; - tdsqlite3_int64 i1 = 0; - tdsqlite3_int64 i2 = 0; - tdsqlite3_int64 iPrev = 0; + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; char *pEnd1 = &a1[n1]; char *pEnd2 = &a2[n2]; char *p1 = a1; @@ -171158,14 +171158,14 @@ static int fts3DoclistOrMerge( ** A symetric argument may be made if the doclists are in descending ** order. */ - aOut = tdsqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); + aOut = sqlite3_malloc64((i64)n1+n2+FTS3_VARINT_MAX-1+FTS3_BUFFER_PADDING); if( !aOut ) return SQLITE_NOMEM; p = aOut; fts3GetDeltaVarint3(&p1, pEnd1, 0, &i1); fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); while( p1 || p2 ){ - tdsqlite3_int64 iDiff = DOCID_CMP(i1, i2); + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); if( p2 && p1 && iDiff==0 ){ fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); @@ -171187,7 +171187,7 @@ static int fts3DoclistOrMerge( } if( rc!=SQLITE_OK ){ - tdsqlite3_free(aOut); + sqlite3_free(aOut); p = aOut = 0; }else{ assert( (p-aOut)<=n1+n2+FTS3_VARINT_MAX-1 ); @@ -171216,9 +171216,9 @@ static int fts3DoclistPhraseMerge( char *aLeft, int nLeft, /* Left doclist */ char **paRight, int *pnRight /* IN/OUT: Right/output doclist */ ){ - tdsqlite3_int64 i1 = 0; - tdsqlite3_int64 i2 = 0; - tdsqlite3_int64 iPrev = 0; + sqlite3_int64 i1 = 0; + sqlite3_int64 i2 = 0; + sqlite3_int64 iPrev = 0; char *aRight = *paRight; char *pEnd1 = &aLeft[nLeft]; char *pEnd2 = &aRight[*pnRight]; @@ -171230,7 +171230,7 @@ static int fts3DoclistPhraseMerge( assert( nDist>0 ); if( bDescDoclist ){ - aOut = tdsqlite3_malloc64((tdsqlite3_int64)*pnRight + FTS3_VARINT_MAX); + aOut = sqlite3_malloc64((sqlite3_int64)*pnRight + FTS3_VARINT_MAX); if( aOut==0 ) return SQLITE_NOMEM; }else{ aOut = aRight; @@ -171241,10 +171241,10 @@ static int fts3DoclistPhraseMerge( fts3GetDeltaVarint3(&p2, pEnd2, 0, &i2); while( p1 && p2 ){ - tdsqlite3_int64 iDiff = DOCID_CMP(i1, i2); + sqlite3_int64 iDiff = DOCID_CMP(i1, i2); if( iDiff==0 ){ char *pSave = p; - tdsqlite3_int64 iPrevSave = iPrev; + sqlite3_int64 iPrevSave = iPrev; int bFirstOutSave = bFirstOut; fts3PutDeltaVarint3(&p, bDescDoclist, &iPrev, &bFirstOut, i1); @@ -171266,7 +171266,7 @@ static int fts3DoclistPhraseMerge( *pnRight = (int)(p - aOut); if( bDescDoclist ){ - tdsqlite3_free(aRight); + sqlite3_free(aRight); *paRight = aOut; } @@ -171281,8 +171281,8 @@ static int fts3DoclistPhraseMerge( ** of the entries from pList at position 0, and terminated by an 0x00 byte. ** The value returned is the number of bytes written to pOut (if any). */ -SQLITE_PRIVATE int tdsqlite3Fts3FirstFilter( - tdsqlite3_int64 iDelta, /* Varint that may be written to pOut */ +SQLITE_PRIVATE int sqlite3Fts3FirstFilter( + sqlite3_int64 iDelta, /* Varint that may be written to pOut */ char *pList, /* Position list (no 0x00 term) */ int nList, /* Size of pList in bytes */ char *pOut /* Write output here */ @@ -171294,7 +171294,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3FirstFilter( if( *p!=0x01 ){ if( *p==0x02 ){ - nOut += tdsqlite3Fts3PutVarint(&pOut[nOut], iDelta); + nOut += sqlite3Fts3PutVarint(&pOut[nOut], iDelta); pOut[nOut++] = 0x02; bWritten = 1; } @@ -171302,16 +171302,16 @@ SQLITE_PRIVATE int tdsqlite3Fts3FirstFilter( } while( paaOutput[i], pTS->anOutput[i], aOut, nOut, &aNew, &nNew ); if( rc!=SQLITE_OK ){ - tdsqlite3_free(aOut); + sqlite3_free(aOut); return rc; } - tdsqlite3_free(pTS->aaOutput[i]); - tdsqlite3_free(aOut); + sqlite3_free(pTS->aaOutput[i]); + sqlite3_free(aOut); pTS->aaOutput[i] = 0; aOut = aNew; nOut = nNew; @@ -171410,7 +171410,7 @@ static int fts3TermSelectMerge( ** ** Similar padding is added in the fts3DoclistOrMerge() function. */ - pTS->aaOutput[0] = tdsqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1); + pTS->aaOutput[0] = sqlite3_malloc(nDoclist + FTS3_VARINT_MAX + 1); pTS->anOutput[0] = nDoclist; if( pTS->aaOutput[0] ){ memcpy(pTS->aaOutput[0], aDoclist, nDoclist); @@ -171437,12 +171437,12 @@ static int fts3TermSelectMerge( pTS->aaOutput[iOut], pTS->anOutput[iOut], &aNew, &nNew ); if( rc!=SQLITE_OK ){ - if( aMerge!=aDoclist ) tdsqlite3_free(aMerge); + if( aMerge!=aDoclist ) sqlite3_free(aMerge); return rc; } - if( aMerge!=aDoclist ) tdsqlite3_free(aMerge); - tdsqlite3_free(pTS->aaOutput[iOut]); + if( aMerge!=aDoclist ) sqlite3_free(aMerge); + sqlite3_free(pTS->aaOutput[iOut]); pTS->aaOutput[iOut] = 0; aMerge = aNew; @@ -171466,10 +171466,10 @@ static int fts3SegReaderCursorAppend( ){ if( (pCsr->nSegment%16)==0 ){ Fts3SegReader **apNew; - tdsqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); - apNew = (Fts3SegReader **)tdsqlite3_realloc64(pCsr->apSegment, nByte); + sqlite3_int64 nByte = (pCsr->nSegment + 16)*sizeof(Fts3SegReader*); + apNew = (Fts3SegReader **)sqlite3_realloc64(pCsr->apSegment, nByte); if( !apNew ){ - tdsqlite3Fts3SegReaderFree(pNew); + sqlite3Fts3SegReaderFree(pNew); return SQLITE_NOMEM; } pCsr->apSegment = apNew; @@ -171497,8 +171497,8 @@ static int fts3SegReaderCursor( Fts3MultiSegReader *pCsr /* Cursor object to populate */ ){ int rc = SQLITE_OK; /* Error code */ - tdsqlite3_stmt *pStmt = 0; /* Statement to iterate through segments */ - int rc2; /* Result of tdsqlite3_reset() */ + sqlite3_stmt *pStmt = 0; /* Statement to iterate through segments */ + int rc2; /* Result of sqlite3_reset() */ /* If iLevel is less than 0 and this is not a scan, include a seg-reader ** for the pending-terms. If this is a scan, then this call must be being @@ -171508,7 +171508,7 @@ static int fts3SegReaderCursor( ** calls out here. */ if( iLevel<0 && p->aIndex && p->iPrevLangid==iLangid ){ Fts3SegReader *pSeg = 0; - rc = tdsqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); + rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); if( rc==SQLITE_OK && pSeg ){ rc = fts3SegReaderCursorAppend(pCsr, pSeg); } @@ -171516,29 +171516,29 @@ static int fts3SegReaderCursor( if( iLevel!=FTS3_SEGCURSOR_PENDING ){ if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts3AllSegdirs(p, iLangid, iIndex, iLevel, &pStmt); + rc = sqlite3Fts3AllSegdirs(p, iLangid, iIndex, iLevel, &pStmt); } - while( rc==SQLITE_OK && SQLITE_ROW==(rc = tdsqlite3_step(pStmt)) ){ + while( rc==SQLITE_OK && SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ Fts3SegReader *pSeg = 0; /* Read the values returned by the SELECT into local variables. */ - tdsqlite3_int64 iStartBlock = tdsqlite3_column_int64(pStmt, 1); - tdsqlite3_int64 iLeavesEndBlock = tdsqlite3_column_int64(pStmt, 2); - tdsqlite3_int64 iEndBlock = tdsqlite3_column_int64(pStmt, 3); - int nRoot = tdsqlite3_column_bytes(pStmt, 4); - char const *zRoot = tdsqlite3_column_blob(pStmt, 4); + sqlite3_int64 iStartBlock = sqlite3_column_int64(pStmt, 1); + sqlite3_int64 iLeavesEndBlock = sqlite3_column_int64(pStmt, 2); + sqlite3_int64 iEndBlock = sqlite3_column_int64(pStmt, 3); + int nRoot = sqlite3_column_bytes(pStmt, 4); + char const *zRoot = sqlite3_column_blob(pStmt, 4); /* If zTerm is not NULL, and this segment is not stored entirely on its ** root node, the range of leaves scanned can be reduced. Do this. */ if( iStartBlock && zTerm && zRoot ){ - tdsqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0); + sqlite3_int64 *pi = (isPrefix ? &iLeavesEndBlock : 0); rc = fts3SelectLeaf(p, zTerm, nTerm, zRoot, nRoot, &iStartBlock, pi); if( rc!=SQLITE_OK ) goto finished; if( isPrefix==0 && isScan==0 ) iLeavesEndBlock = iStartBlock; } - rc = tdsqlite3Fts3SegReaderNew(pCsr->nSegment+1, + rc = sqlite3Fts3SegReaderNew(pCsr->nSegment+1, (isPrefix==0 && isScan==0), iStartBlock, iLeavesEndBlock, iEndBlock, zRoot, nRoot, &pSeg @@ -171549,7 +171549,7 @@ static int fts3SegReaderCursor( } finished: - rc2 = tdsqlite3_reset(pStmt); + rc2 = sqlite3_reset(pStmt); if( rc==SQLITE_DONE ) rc = rc2; return rc; @@ -171559,7 +171559,7 @@ static int fts3SegReaderCursor( ** Set up a cursor object for iterating through a full-text index or a ** single level therein. */ -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderCursor( +SQLITE_PRIVATE int sqlite3Fts3SegReaderCursor( Fts3Table *p, /* FTS3 table handle */ int iLangid, /* Language-id to search */ int iIndex, /* Index to search (from 0 to p->nIndex-1) */ @@ -171626,7 +171626,7 @@ static int fts3TermSegReaderCursor( Fts3MultiSegReader *pSegcsr; /* Object to allocate and return */ int rc = SQLITE_NOMEM; /* Return code */ - pSegcsr = tdsqlite3_malloc(sizeof(Fts3MultiSegReader)); + pSegcsr = sqlite3_malloc(sizeof(Fts3MultiSegReader)); if( pSegcsr ){ int i; int bFound = 0; /* True once an index has been found */ @@ -171636,7 +171636,7 @@ static int fts3TermSegReaderCursor( for(i=1; bFound==0 && inIndex; i++){ if( p->aIndex[i].nPrefix==nTerm ){ bFound = 1; - rc = tdsqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 0, 0, pSegcsr ); pSegcsr->bLookup = 1; @@ -171646,7 +171646,7 @@ static int fts3TermSegReaderCursor( for(i=1; bFound==0 && inIndex; i++){ if( p->aIndex[i].nPrefix==nTerm+1 ){ bFound = 1; - rc = tdsqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, i, FTS3_SEGCURSOR_ALL, zTerm, nTerm, 1, 0, pSegcsr ); if( rc==SQLITE_OK ){ @@ -171659,7 +171659,7 @@ static int fts3TermSegReaderCursor( } if( bFound==0 ){ - rc = tdsqlite3Fts3SegReaderCursor(p, pCsr->iLangid, + rc = sqlite3Fts3SegReaderCursor(p, pCsr->iLangid, 0, FTS3_SEGCURSOR_ALL, zTerm, nTerm, isPrefix, 0, pSegcsr ); pSegcsr->bLookup = !isPrefix; @@ -171674,8 +171674,8 @@ static int fts3TermSegReaderCursor( ** Free an Fts3MultiSegReader allocated by fts3TermSegReaderCursor(). */ static void fts3SegReaderCursorFree(Fts3MultiSegReader *pSegcsr){ - tdsqlite3Fts3SegReaderFinish(pSegcsr); - tdsqlite3_free(pSegcsr); + sqlite3Fts3SegReaderFinish(pSegcsr); + sqlite3_free(pSegcsr); } /* @@ -171705,9 +171705,9 @@ static int fts3TermSelect( filter.zTerm = pTok->z; filter.nTerm = pTok->n; - rc = tdsqlite3Fts3SegReaderStart(p, pSegcsr, &filter); + rc = sqlite3Fts3SegReaderStart(p, pSegcsr, &filter); while( SQLITE_OK==rc - && SQLITE_ROW==(rc = tdsqlite3Fts3SegReaderStep(p, pSegcsr)) + && SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, pSegcsr)) ){ rc = fts3TermSelectMerge(p, &tsc, pSegcsr->aDoclist, pSegcsr->nDoclist); } @@ -171721,7 +171721,7 @@ static int fts3TermSelect( }else{ int i; for(i=0; ieSearch==FTS3_DOCID_SEARCH || pCsr->eSearch==FTS3_FULLSCAN_SEARCH ){ Fts3Table *pTab = (Fts3Table*)pCursor->pVtab; pTab->bLock++; - if( SQLITE_ROW!=tdsqlite3_step(pCsr->pStmt) ){ + if( SQLITE_ROW!=sqlite3_step(pCsr->pStmt) ){ pCsr->isEof = 1; - rc = tdsqlite3_reset(pCsr->pStmt); + rc = sqlite3_reset(pCsr->pStmt); }else{ - pCsr->iPrevId = tdsqlite3_column_int64(pCsr->pStmt, 0); + pCsr->iPrevId = sqlite3_column_int64(pCsr->pStmt, 0); rc = SQLITE_OK; } pTab->bLock--; @@ -171791,11 +171791,11 @@ static int fts3NextMethod(tdsqlite3_vtab_cursor *pCursor){ ** converted to a 64-bit signed integer. Otherwise, return a copy of ** the second parameter, iDefault. */ -static tdsqlite3_int64 fts3DocidRange(tdsqlite3_value *pVal, i64 iDefault){ +static sqlite3_int64 fts3DocidRange(sqlite3_value *pVal, i64 iDefault){ if( pVal ){ - int eType = tdsqlite3_value_numeric_type(pVal); + int eType = sqlite3_value_numeric_type(pVal); if( eType==SQLITE_INTEGER ){ - return tdsqlite3_value_int64(pVal); + return sqlite3_value_int64(pVal); } } return iDefault; @@ -171818,11 +171818,11 @@ static tdsqlite3_int64 fts3DocidRange(tdsqlite3_value *pVal, i64 iDefault){ ** side of the MATCH operator. */ static int fts3FilterMethod( - tdsqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ int idxNum, /* Strategy index */ const char *idxStr, /* Unused */ int nVal, /* Number of elements in apVal */ - tdsqlite3_value **apVal /* Arguments for the indexing scheme */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ int rc = SQLITE_OK; char *zSql; /* SQL statement used to access %_content */ @@ -171830,10 +171830,10 @@ static int fts3FilterMethod( Fts3Table *p = (Fts3Table *)pCursor->pVtab; Fts3Cursor *pCsr = (Fts3Cursor *)pCursor; - tdsqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */ - tdsqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */ - tdsqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */ - tdsqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */ + sqlite3_value *pCons = 0; /* The MATCH or rowid constraint, if any */ + sqlite3_value *pLangid = 0; /* The "langid = ?" constraint, if any */ + sqlite3_value *pDocidGe = 0; /* The "docid >= ?" constraint, if any */ + sqlite3_value *pDocidLe = 0; /* The "docid <= ?" constraint, if any */ int iIdx; UNUSED_PARAMETER(idxStr); @@ -171871,17 +171871,17 @@ static int fts3FilterMethod( if( eSearch!=FTS3_DOCID_SEARCH && eSearch!=FTS3_FULLSCAN_SEARCH ){ int iCol = eSearch-FTS3_FULLTEXT_SEARCH; - const char *zQuery = (const char *)tdsqlite3_value_text(pCons); + const char *zQuery = (const char *)sqlite3_value_text(pCons); - if( zQuery==0 && tdsqlite3_value_type(pCons)!=SQLITE_NULL ){ + if( zQuery==0 && sqlite3_value_type(pCons)!=SQLITE_NULL ){ return SQLITE_NOMEM; } pCsr->iLangid = 0; - if( pLangid ) pCsr->iLangid = tdsqlite3_value_int(pLangid); + if( pLangid ) pCsr->iLangid = sqlite3_value_int(pLangid); assert( p->base.zErrMsg==0 ); - rc = tdsqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, + rc = sqlite3Fts3ExprParse(p->pTokenizer, pCsr->iLangid, p->azColumn, p->bFts4, p->nColumn, iCol, zQuery, -1, &pCsr->pExpr, &p->base.zErrMsg ); @@ -171890,7 +171890,7 @@ static int fts3FilterMethod( } rc = fts3EvalStart(pCsr); - tdsqlite3Fts3SegmentsClose(p); + sqlite3Fts3SegmentsClose(p); if( rc!=SQLITE_OK ) return rc; pCsr->pNextId = pCsr->aDoclist; pCsr->iPrevId = 0; @@ -171903,30 +171903,30 @@ static int fts3FilterMethod( */ if( eSearch==FTS3_FULLSCAN_SEARCH ){ if( pDocidGe || pDocidLe ){ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s", p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid, (pCsr->bDesc ? "DESC" : "ASC") ); }else{ - zSql = tdsqlite3_mprintf("SELECT %s ORDER BY rowid %s", + zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") ); } if( zSql ){ p->bLock++; - rc = tdsqlite3_prepare_v3( + rc = sqlite3_prepare_v3( p->db,zSql,-1,SQLITE_PREPARE_PERSISTENT,&pCsr->pStmt,0 ); p->bLock--; - tdsqlite3_free(zSql); + sqlite3_free(zSql); }else{ rc = SQLITE_NOMEM; } }else if( eSearch==FTS3_DOCID_SEARCH ){ rc = fts3CursorSeekStmt(pCsr); if( rc==SQLITE_OK ){ - rc = tdsqlite3_bind_value(pCsr->pStmt, 1, pCons); + rc = sqlite3_bind_value(pCsr->pStmt, 1, pCons); } } if( rc!=SQLITE_OK ) return rc; @@ -171938,7 +171938,7 @@ static int fts3FilterMethod( ** This is the xEof method of the virtual table. SQLite calls this ** routine to find out if it has reached the end of a result set. */ -static int fts3EofMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts3EofMethod(sqlite3_vtab_cursor *pCursor){ Fts3Cursor *pCsr = (Fts3Cursor*)pCursor; if( pCsr->isEof ){ fts3ClearCursor(pCsr); @@ -171953,7 +171953,7 @@ static int fts3EofMethod(tdsqlite3_vtab_cursor *pCursor){ ** exposes %_content.docid as the rowid for the virtual table. The ** rowid should be written to *pRowid. */ -static int fts3RowidMethod(tdsqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ +static int fts3RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ Fts3Cursor *pCsr = (Fts3Cursor *) pCursor; *pRowid = pCsr->iPrevId; return SQLITE_OK; @@ -171971,8 +171971,8 @@ static int fts3RowidMethod(tdsqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid) ** (iCol == p->nColumn+2) -> Langid column */ static int fts3ColumnMethod( - tdsqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - tdsqlite3_context *pCtx, /* Context for tdsqlite3_result_xxx() calls */ + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ int iCol /* Index of column to read value from */ ){ int rc = SQLITE_OK; /* Return Code */ @@ -171985,20 +171985,20 @@ static int fts3ColumnMethod( switch( iCol-p->nColumn ){ case 0: /* The special 'table-name' column */ - tdsqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0); + sqlite3_result_pointer(pCtx, pCsr, "fts3cursor", 0); break; case 1: /* The docid column */ - tdsqlite3_result_int64(pCtx, pCsr->iPrevId); + sqlite3_result_int64(pCtx, pCsr->iPrevId); break; case 2: if( pCsr->pExpr ){ - tdsqlite3_result_int64(pCtx, pCsr->iLangid); + sqlite3_result_int64(pCtx, pCsr->iLangid); break; }else if( p->zLanguageid==0 ){ - tdsqlite3_result_int(pCtx, 0); + sqlite3_result_int(pCtx, 0); break; }else{ iCol = p->nColumn; @@ -172009,8 +172009,8 @@ static int fts3ColumnMethod( /* A user column. Or, if this is a full-table scan, possibly the ** language-id column. Seek the cursor. */ rc = fts3CursorSeek(0, pCsr); - if( rc==SQLITE_OK && tdsqlite3_data_count(pCsr->pStmt)-1>iCol ){ - tdsqlite3_result_value(pCtx, tdsqlite3_column_value(pCsr->pStmt, iCol+1)); + if( rc==SQLITE_OK && sqlite3_data_count(pCsr->pStmt)-1>iCol ){ + sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); } break; } @@ -172025,19 +172025,19 @@ static int fts3ColumnMethod( ** inserted, updated or deleted. */ static int fts3UpdateMethod( - tdsqlite3_vtab *pVtab, /* Virtual table handle */ + sqlite3_vtab *pVtab, /* Virtual table handle */ int nArg, /* Size of argument array */ - tdsqlite3_value **apVal, /* Array of arguments */ + sqlite3_value **apVal, /* Array of arguments */ sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ ){ - return tdsqlite3Fts3UpdateMethod(pVtab, nArg, apVal, pRowid); + return sqlite3Fts3UpdateMethod(pVtab, nArg, apVal, pRowid); } /* ** Implementation of xSync() method. Flush the contents of the pending-terms ** hash-table to the database. */ -static int fts3SyncMethod(tdsqlite3_vtab *pVtab){ +static int fts3SyncMethod(sqlite3_vtab *pVtab){ /* Following an incremental-merge operation, assuming that the input ** segments are not completely consumed (the usual case), they are updated @@ -172062,9 +172062,9 @@ static int fts3SyncMethod(tdsqlite3_vtab *pVtab){ Fts3Table *p = (Fts3Table*)pVtab; int rc; - i64 iLastRowid = tdsqlite3_last_insert_rowid(p->db); + i64 iLastRowid = sqlite3_last_insert_rowid(p->db); - rc = tdsqlite3Fts3PendingTermsFlush(p); + rc = sqlite3Fts3PendingTermsFlush(p); if( rc==SQLITE_OK && p->nLeafAdd>(nMinMerge/16) && p->nAutoincrmerge && p->nAutoincrmerge!=0xff @@ -172072,14 +172072,14 @@ static int fts3SyncMethod(tdsqlite3_vtab *pVtab){ int mxLevel = 0; /* Maximum relative level value in db */ int A; /* Incr-merge parameter A */ - rc = tdsqlite3Fts3MaxLevel(p, &mxLevel); + rc = sqlite3Fts3MaxLevel(p, &mxLevel); assert( rc==SQLITE_OK || mxLevel==0 ); A = p->nLeafAdd * mxLevel; A += (A/2); - if( A>(int)nMinMerge ) rc = tdsqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); + if( A>(int)nMinMerge ) rc = sqlite3Fts3Incrmerge(p, A, p->nAutoincrmerge); } - tdsqlite3Fts3SegmentsClose(p); - tdsqlite3_set_last_insert_rowid(p->db, iLastRowid); + sqlite3Fts3SegmentsClose(p); + sqlite3_set_last_insert_rowid(p->db, iLastRowid); return rc; } @@ -172092,10 +172092,10 @@ static int fts3SyncMethod(tdsqlite3_vtab *pVtab){ static int fts3SetHasStat(Fts3Table *p){ int rc = SQLITE_OK; if( p->bHasStat==2 ){ - char *zTbl = tdsqlite3_mprintf("%s_stat", p->zName); + char *zTbl = sqlite3_mprintf("%s_stat", p->zName); if( zTbl ){ - int res = tdsqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0); - tdsqlite3_free(zTbl); + int res = sqlite3_table_column_metadata(p->db, p->zDb, zTbl, 0,0,0,0,0,0); + sqlite3_free(zTbl); p->bHasStat = (res==SQLITE_OK); }else{ rc = SQLITE_NOMEM; @@ -172107,7 +172107,7 @@ static int fts3SetHasStat(Fts3Table *p){ /* ** Implementation of xBegin() method. */ -static int fts3BeginMethod(tdsqlite3_vtab *pVtab){ +static int fts3BeginMethod(sqlite3_vtab *pVtab){ Fts3Table *p = (Fts3Table*)pVtab; UNUSED_PARAMETER(pVtab); assert( p->pSegments==0 ); @@ -172124,7 +172124,7 @@ static int fts3BeginMethod(tdsqlite3_vtab *pVtab){ ** the pending-terms hash-table have already been flushed into the database ** by fts3SyncMethod(). */ -static int fts3CommitMethod(tdsqlite3_vtab *pVtab){ +static int fts3CommitMethod(sqlite3_vtab *pVtab){ TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); UNUSED_PARAMETER(pVtab); assert( p->nPendingData==0 ); @@ -172139,9 +172139,9 @@ static int fts3CommitMethod(tdsqlite3_vtab *pVtab){ ** Implementation of xRollback(). Discard the contents of the pending-terms ** hash-table. Any changes made to the database are reverted by SQLite. */ -static int fts3RollbackMethod(tdsqlite3_vtab *pVtab){ +static int fts3RollbackMethod(sqlite3_vtab *pVtab){ Fts3Table *p = (Fts3Table*)pVtab; - tdsqlite3Fts3PendingTermsClear(p); + sqlite3Fts3PendingTermsClear(p); assert( p->inTransaction!=0 ); TESTONLY( p->inTransaction = 0 ); TESTONLY( p->mxSavepoint = -1; ); @@ -172198,19 +172198,19 @@ static void fts3ReversePoslist(char *pStart, char **ppPoslist){ ** string passed via zFunc is used as part of the error message. */ static int fts3FunctionArg( - tdsqlite3_context *pContext, /* SQL function call context */ + sqlite3_context *pContext, /* SQL function call context */ const char *zFunc, /* Function name */ - tdsqlite3_value *pVal, /* argv[0] passed to function */ + sqlite3_value *pVal, /* argv[0] passed to function */ Fts3Cursor **ppCsr /* OUT: Store cursor handle here */ ){ int rc; - *ppCsr = (Fts3Cursor*)tdsqlite3_value_pointer(pVal, "fts3cursor"); + *ppCsr = (Fts3Cursor*)sqlite3_value_pointer(pVal, "fts3cursor"); if( (*ppCsr)!=0 ){ rc = SQLITE_OK; }else{ - char *zErr = tdsqlite3_mprintf("illegal first argument to %s", zFunc); - tdsqlite3_result_error(pContext, zErr, -1); - tdsqlite3_free(zErr); + char *zErr = sqlite3_mprintf("illegal first argument to %s", zFunc); + sqlite3_result_error(pContext, zErr, -1); + sqlite3_free(zErr); rc = SQLITE_ERROR; } return rc; @@ -172220,9 +172220,9 @@ static int fts3FunctionArg( ** Implementation of the snippet() function for FTS3 */ static void fts3SnippetFunc( - tdsqlite3_context *pContext, /* SQLite function call context */ + sqlite3_context *pContext, /* SQLite function call context */ int nVal, /* Size of apVal[] array */ - tdsqlite3_value **apVal /* Array of arguments */ + sqlite3_value **apVal /* Array of arguments */ ){ Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ const char *zStart = ""; @@ -172237,25 +172237,25 @@ static void fts3SnippetFunc( assert( nVal>=1 ); if( nVal>6 ){ - tdsqlite3_result_error(pContext, + sqlite3_result_error(pContext, "wrong number of arguments to function snippet()", -1); return; } if( fts3FunctionArg(pContext, "snippet", apVal[0], &pCsr) ) return; switch( nVal ){ - case 6: nToken = tdsqlite3_value_int(apVal[5]); - case 5: iCol = tdsqlite3_value_int(apVal[4]); - case 4: zEllipsis = (const char*)tdsqlite3_value_text(apVal[3]); - case 3: zEnd = (const char*)tdsqlite3_value_text(apVal[2]); - case 2: zStart = (const char*)tdsqlite3_value_text(apVal[1]); + case 6: nToken = sqlite3_value_int(apVal[5]); + case 5: iCol = sqlite3_value_int(apVal[4]); + case 4: zEllipsis = (const char*)sqlite3_value_text(apVal[3]); + case 3: zEnd = (const char*)sqlite3_value_text(apVal[2]); + case 2: zStart = (const char*)sqlite3_value_text(apVal[1]); } if( !zEllipsis || !zEnd || !zStart ){ - tdsqlite3_result_error_nomem(pContext); + sqlite3_result_error_nomem(pContext); }else if( nToken==0 ){ - tdsqlite3_result_text(pContext, "", -1, SQLITE_STATIC); + sqlite3_result_text(pContext, "", -1, SQLITE_STATIC); }else if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ - tdsqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); + sqlite3Fts3Snippet(pContext, pCsr, zStart, zEnd, zEllipsis, iCol, nToken); } } @@ -172263,9 +172263,9 @@ static void fts3SnippetFunc( ** Implementation of the offsets() function for FTS3 */ static void fts3OffsetsFunc( - tdsqlite3_context *pContext, /* SQLite function call context */ + sqlite3_context *pContext, /* SQLite function call context */ int nVal, /* Size of argument array */ - tdsqlite3_value **apVal /* Array of arguments */ + sqlite3_value **apVal /* Array of arguments */ ){ Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ @@ -172275,7 +172275,7 @@ static void fts3OffsetsFunc( if( fts3FunctionArg(pContext, "offsets", apVal[0], &pCsr) ) return; assert( pCsr ); if( SQLITE_OK==fts3CursorSeek(pContext, pCsr) ){ - tdsqlite3Fts3Offsets(pContext, pCsr); + sqlite3Fts3Offsets(pContext, pCsr); } } @@ -172289,9 +172289,9 @@ static void fts3OffsetsFunc( ** where 't' is the name of an FTS3 table. */ static void fts3OptimizeFunc( - tdsqlite3_context *pContext, /* SQLite function call context */ + sqlite3_context *pContext, /* SQLite function call context */ int nVal, /* Size of argument array */ - tdsqlite3_value **apVal /* Array of arguments */ + sqlite3_value **apVal /* Array of arguments */ ){ int rc; /* Return code */ Fts3Table *p; /* Virtual table handle */ @@ -172304,17 +172304,17 @@ static void fts3OptimizeFunc( p = (Fts3Table *)pCursor->base.pVtab; assert( p ); - rc = tdsqlite3Fts3Optimize(p); + rc = sqlite3Fts3Optimize(p); switch( rc ){ case SQLITE_OK: - tdsqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC); + sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC); break; case SQLITE_DONE: - tdsqlite3_result_text(pContext, "Index already optimal", -1, SQLITE_STATIC); + sqlite3_result_text(pContext, "Index already optimal", -1, SQLITE_STATIC); break; default: - tdsqlite3_result_error_code(pContext, rc); + sqlite3_result_error_code(pContext, rc); break; } } @@ -172323,18 +172323,18 @@ static void fts3OptimizeFunc( ** Implementation of the matchinfo() function for FTS3 */ static void fts3MatchinfoFunc( - tdsqlite3_context *pContext, /* SQLite function call context */ + sqlite3_context *pContext, /* SQLite function call context */ int nVal, /* Size of argument array */ - tdsqlite3_value **apVal /* Array of arguments */ + sqlite3_value **apVal /* Array of arguments */ ){ Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ assert( nVal==1 || nVal==2 ); if( SQLITE_OK==fts3FunctionArg(pContext, "matchinfo", apVal[0], &pCsr) ){ const char *zArg = 0; if( nVal>1 ){ - zArg = (const char *)tdsqlite3_value_text(apVal[1]); + zArg = (const char *)sqlite3_value_text(apVal[1]); } - tdsqlite3Fts3Matchinfo(pContext, pCsr, zArg); + sqlite3Fts3Matchinfo(pContext, pCsr, zArg); } } @@ -172343,15 +172343,15 @@ static void fts3MatchinfoFunc( ** virtual table. */ static int fts3FindFunctionMethod( - tdsqlite3_vtab *pVtab, /* Virtual table handle */ + sqlite3_vtab *pVtab, /* Virtual table handle */ int nArg, /* Number of SQL function arguments */ const char *zName, /* Name of SQL function */ - void (**pxFunc)(tdsqlite3_context*,int,tdsqlite3_value**), /* OUT: Result */ + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ void **ppArg /* Unused */ ){ struct Overloaded { const char *zName; - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**); + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } aOverload[] = { { "snippet", fts3SnippetFunc }, { "offsets", fts3OffsetsFunc }, @@ -172379,11 +172379,11 @@ static int fts3FindFunctionMethod( ** Implementation of FTS3 xRename method. Rename an fts3 table. */ static int fts3RenameMethod( - tdsqlite3_vtab *pVtab, /* Virtual table handle */ + sqlite3_vtab *pVtab, /* Virtual table handle */ const char *zName /* New name of table */ ){ Fts3Table *p = (Fts3Table *)pVtab; - tdsqlite3 *db = p->db; /* Database connection */ + sqlite3 *db = p->db; /* Database connection */ int rc; /* Return Code */ /* At this point it must be known if the %_stat table exists or not. @@ -172398,7 +172398,7 @@ static int fts3RenameMethod( */ assert( p->nPendingData==0 ); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts3PendingTermsFlush(p); + rc = sqlite3Fts3PendingTermsFlush(p); } if( p->zContentTbl==0 ){ @@ -172436,7 +172436,7 @@ static int fts3RenameMethod( ** ** Flush the contents of the pending-terms table to disk. */ -static int fts3SavepointMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ +static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; UNUSED_PARAMETER(iSavepoint); assert( ((Fts3Table *)pVtab)->inTransaction ); @@ -172453,7 +172453,7 @@ static int fts3SavepointMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ ** ** This is a no-op. */ -static int fts3ReleaseMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ +static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); UNUSED_PARAMETER(iSavepoint); UNUSED_PARAMETER(pVtab); @@ -172468,12 +172468,12 @@ static int fts3ReleaseMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ ** ** Discard the contents of the pending terms table. */ -static int fts3RollbackToMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ +static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts3Table *p = (Fts3Table*)pVtab; UNUSED_PARAMETER(iSavepoint); assert( p->inTransaction ); TESTONLY( p->mxSavepoint = iSavepoint ); - tdsqlite3Fts3PendingTermsClear(p); + sqlite3Fts3PendingTermsClear(p); return SQLITE_OK; } @@ -172487,12 +172487,12 @@ static int fts3ShadowName(const char *zName){ }; unsigned int i; for(i=0; idoclist.aAll/nAll. ** ** This function assumes that pList points to a buffer allocated using -** tdsqlite3_malloc(). This function takes responsibility for eventually +** sqlite3_malloc(). This function takes responsibility for eventually ** freeing the buffer. ** ** SQLITE_OK is returned if successful, or SQLITE_NOMEM if an error occurs. @@ -172718,7 +172718,7 @@ static int fts3EvalPhraseMergeToken( assert( iToken!=p->iDoclistToken ); if( pList==0 ){ - tdsqlite3_free(p->doclist.aAll); + sqlite3_free(p->doclist.aAll); p->doclist.aAll = 0; p->doclist.nAll = 0; } @@ -172729,7 +172729,7 @@ static int fts3EvalPhraseMergeToken( } else if( p->doclist.aAll==0 ){ - tdsqlite3_free(pList); + sqlite3_free(pList); } else { @@ -172756,7 +172756,7 @@ static int fts3EvalPhraseMergeToken( rc = fts3DoclistPhraseMerge( pTab->bDescIdx, nDiff, pLeft, nLeft, &pRight, &nRight ); - tdsqlite3_free(pLeft); + sqlite3_free(pLeft); p->doclist.aAll = pRight; p->doclist.nAll = nRight; } @@ -172823,11 +172823,11 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ if( pDeferred ){ char *pList; int nList; - int rc = tdsqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); + int rc = sqlite3Fts3DeferredTokenList(pDeferred, &pList, &nList); if( rc!=SQLITE_OK ) return rc; if( pList==0 ){ - tdsqlite3_free(aPoslist); + sqlite3_free(aPoslist); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; @@ -172843,11 +172843,11 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ assert( iPrev>=0 ); fts3PoslistPhraseMerge(&aOut, iToken-iPrev, 0, 1, &p1, &p2); - tdsqlite3_free(aPoslist); + sqlite3_free(aPoslist); aPoslist = pList; nPoslist = (int)(aOut - aPoslist); if( nPoslist==0 ){ - tdsqlite3_free(aPoslist); + sqlite3_free(aPoslist); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; return SQLITE_OK; @@ -172880,9 +172880,9 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ nDistance = iPrev - nMaxUndeferred; } - aOut = (char *)tdsqlite3_malloc(nPoslist+8); + aOut = (char *)sqlite3_malloc(nPoslist+8); if( !aOut ){ - tdsqlite3_free(aPoslist); + sqlite3_free(aPoslist); return SQLITE_NOMEM; } @@ -172891,11 +172891,11 @@ static int fts3EvalDeferredPhrase(Fts3Cursor *pCsr, Fts3Phrase *pPhrase){ pPhrase->doclist.bFreeList = 1; pPhrase->doclist.nList = (int)(aOut - pPhrase->doclist.pList); }else{ - tdsqlite3_free(aOut); + sqlite3_free(aOut); pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; } - tdsqlite3_free(aPoslist); + sqlite3_free(aPoslist); } } @@ -172954,7 +172954,7 @@ static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ Fts3PhraseToken *pToken = &p->aToken[i]; Fts3MultiSegReader *pSegcsr = pToken->pSegcsr; if( pSegcsr ){ - rc = tdsqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n); + rc = sqlite3Fts3MsrIncrStart(pTab, pSegcsr, iCol, pToken->z, pToken->n); } } p->bIncr = 1; @@ -172978,12 +172978,12 @@ static int fts3EvalPhraseStart(Fts3Cursor *pCsr, int bOptOk, Fts3Phrase *p){ ** descending (parameter bDescIdx==1) order of docid. Regardless, this ** function iterates from the end of the doclist to the beginning. */ -SQLITE_PRIVATE void tdsqlite3Fts3DoclistPrev( +SQLITE_PRIVATE void sqlite3Fts3DoclistPrev( int bDescIdx, /* True if the doclist is desc */ char *aDoclist, /* Pointer to entire doclist */ int nDoclist, /* Length of aDoclist in bytes */ char **ppIter, /* IN/OUT: Iterator pointer */ - tdsqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ + sqlite3_int64 *piDocid, /* IN/OUT: Docid pointer */ int *pnList, /* OUT: List length pointer */ u8 *pbEof /* OUT: End-of-file flag */ ){ @@ -172995,15 +172995,15 @@ SQLITE_PRIVATE void tdsqlite3Fts3DoclistPrev( assert( !p || (p>aDoclist && p<&aDoclist[nDoclist]) ); if( p==0 ){ - tdsqlite3_int64 iDocid = 0; + sqlite3_int64 iDocid = 0; char *pNext = 0; char *pDocid = aDoclist; char *pEnd = &aDoclist[nDoclist]; int iMul = 1; while( pDocid=&aDoclist[nDoclist] ){ *pbEof = 1; }else{ - tdsqlite3_int64 iVar; - p += tdsqlite3Fts3GetVarint(p, &iVar); + sqlite3_int64 iVar; + p += sqlite3Fts3GetVarint(p, &iVar); *piDocid += ((bDescIdx ? -1 : 1) * iVar); } } @@ -173090,8 +173090,8 @@ static void fts3EvalDlPhraseNext( /* We have already reached the end of this doclist. EOF. */ *pbEof = 1; }else{ - tdsqlite3_int64 iDelta; - pIter += tdsqlite3Fts3GetVarint(pIter, &iDelta); + sqlite3_int64 iDelta; + pIter += sqlite3Fts3GetVarint(pIter, &iDelta); if( pTab->bDescIdx==0 || pDL->pNextDocid==0 ){ pDL->iDocid += iDelta; }else{ @@ -173121,7 +173121,7 @@ static void fts3EvalDlPhraseNext( typedef struct TokenDoclist TokenDoclist; struct TokenDoclist { int bIgnore; - tdsqlite3_int64 iDocid; + sqlite3_int64 iDocid; char *pList; int nList; }; @@ -173157,7 +173157,7 @@ static int incrPhraseTokenNext( assert( pToken->pSegcsr || pPhrase->iDoclistToken>=0 ); if( pToken->pSegcsr ){ assert( p->bIgnore==0 ); - rc = tdsqlite3Fts3MsrIncrNext( + rc = sqlite3Fts3MsrIncrNext( pTab, pToken->pSegcsr, &p->iDocid, &p->pList, &p->nList ); if( p->pList==0 ) *pbEof = 1; @@ -173202,7 +173202,7 @@ static int fts3EvalIncrPhraseNext( assert( p->bIncr==1 ); if( p->nToken==1 ){ - rc = tdsqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, + rc = sqlite3Fts3MsrIncrNext(pTab, p->aToken[0].pSegcsr, &pDL->iDocid, &pDL->pList, &pDL->nList ); if( pDL->pList==0 ) bEof = 1; @@ -173216,7 +173216,7 @@ static int fts3EvalIncrPhraseNext( while( bEof==0 ){ int bMaxSet = 0; - tdsqlite3_int64 iMax = 0; /* Largest docid for all iterators */ + sqlite3_int64 iMax = 0; /* Largest docid for all iterators */ int i; /* Used to iterate through tokens */ /* Advance the iterator for each token in the phrase once. */ @@ -173247,7 +173247,7 @@ static int fts3EvalIncrPhraseNext( if( bEof==0 ){ int nList = 0; int nByte = a[p->nToken-1].nList; - char *aDoclist = tdsqlite3_malloc(nByte+FTS3_BUFFER_PADDING); + char *aDoclist = sqlite3_malloc(nByte+FTS3_BUFFER_PADDING); if( !aDoclist ) return SQLITE_NOMEM; memcpy(aDoclist, a[p->nToken-1].pList, nByte+1); memset(&aDoclist[nByte], 0, FTS3_BUFFER_PADDING); @@ -173270,7 +173270,7 @@ static int fts3EvalIncrPhraseNext( pDL->bFreeList = 1; break; } - tdsqlite3_free(aDoclist); + sqlite3_free(aDoclist); } } } @@ -173300,7 +173300,7 @@ static int fts3EvalPhraseNext( if( p->bIncr ){ rc = fts3EvalIncrPhraseNext(pCsr, p, pbEof); }else if( pCsr->bDesc!=pTab->bDescIdx && pDL->nAll ){ - tdsqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, + sqlite3Fts3DoclistPrev(pTab->bDescIdx, pDL->aAll, pDL->nAll, &pDL->pNextDocid, &pDL->iDocid, &pDL->nList, pbEof ); pDL->pList = pDL->pNextDocid; @@ -173399,7 +173399,7 @@ static void fts3EvalTokenCosts( pTC->pRoot = pRoot; pTC->pToken = &pPhrase->aToken[i]; pTC->iCol = pPhrase->iColumn; - *pRc = tdsqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); + *pRc = sqlite3Fts3MsrOvfl(pCsr, pTC->pToken->pSegcsr, &pTC->nOvfl); } }else if( pExpr->eType!=FTSQUERY_NOT ){ assert( pExpr->eType==FTSQUERY_OR @@ -173449,32 +173449,32 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ ** to right. */ Fts3Table *p = (Fts3Table*)pCsr->base.pVtab; - tdsqlite3_stmt *pStmt; - tdsqlite3_int64 nDoc = 0; - tdsqlite3_int64 nByte = 0; + sqlite3_stmt *pStmt; + sqlite3_int64 nDoc = 0; + sqlite3_int64 nByte = 0; const char *pEnd; const char *a; - rc = tdsqlite3Fts3SelectDoctotal(p, &pStmt); + rc = sqlite3Fts3SelectDoctotal(p, &pStmt); if( rc!=SQLITE_OK ) return rc; - a = tdsqlite3_column_blob(pStmt, 0); + a = sqlite3_column_blob(pStmt, 0); testcase( a==0 ); /* If %_stat.value set to X'' */ if( a ){ - pEnd = &a[tdsqlite3_column_bytes(pStmt, 0)]; - a += tdsqlite3Fts3GetVarintBounded(a, pEnd, &nDoc); + pEnd = &a[sqlite3_column_bytes(pStmt, 0)]; + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc); while( anDoc = nDoc; pCsr->nRowAvg = (int)(((nByte / nDoc) + p->nPgsz) / p->nPgsz); assert( pCsr->nRowAvg>0 ); - rc = tdsqlite3_reset(pStmt); + rc = sqlite3_reset(pStmt); } *pnPage = pCsr->nRowAvg; @@ -173491,7 +173491,7 @@ static int fts3EvalAverageDocsize(Fts3Cursor *pCsr, int *pnPage){ ** the cluster with root node pRoot. See comments above the definition ** of struct Fts3TokenAndCost for more details. ** -** If no error occurs, SQLITE_OK is returned and tdsqlite3Fts3DeferToken() +** If no error occurs, SQLITE_OK is returned and sqlite3Fts3DeferToken() ** called on each token to defer. Otherwise, an SQLite error code is ** returned. */ @@ -173578,7 +173578,7 @@ static int fts3EvalSelectDeferred( ** that will be loaded if all subsequent tokens are deferred. */ Fts3PhraseToken *pToken = pTC->pToken; - rc = tdsqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol); + rc = sqlite3Fts3DeferToken(pCsr, pToken, pTC->iCol); fts3SegReaderCursorFree(pToken->pSegcsr); pToken->pSegcsr = 0; }else{ @@ -173642,7 +173642,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){ if( rc==SQLITE_OK && nToken>1 && pTab->bFts4 ){ Fts3TokenAndCost *aTC; Fts3Expr **apOr; - aTC = (Fts3TokenAndCost *)tdsqlite3_malloc64( + aTC = (Fts3TokenAndCost *)sqlite3_malloc64( sizeof(Fts3TokenAndCost) * nToken + sizeof(Fts3Expr *) * nOr * 2 ); @@ -173666,7 +173666,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){ } } - tdsqlite3_free(aTC); + sqlite3_free(aTC); } } #endif @@ -173680,7 +173680,7 @@ static int fts3EvalStart(Fts3Cursor *pCsr){ */ static void fts3EvalInvalidatePoslist(Fts3Phrase *pPhrase){ if( pPhrase->doclist.bFreeList ){ - tdsqlite3_free(pPhrase->doclist.pList); + sqlite3_free(pPhrase->doclist.pList); } pPhrase->doclist.pList = 0; pPhrase->doclist.nList = 0; @@ -173780,7 +173780,7 @@ static int fts3EvalNearTrim( ** 2. NEAR is treated as AND. If the expression is "x NEAR y", it is ** advanced to point to the next row that matches "x AND y". ** -** See tdsqlite3Fts3EvalTestDeferred() for details on testing if a row is +** See sqlite3Fts3EvalTestDeferred() for details on testing if a row is ** really a match, taking into account deferred tokens and NEAR operators. */ static void fts3EvalNextRow( @@ -173817,7 +173817,7 @@ static void fts3EvalNextRow( fts3EvalNextRow(pCsr, pLeft, pRc); fts3EvalNextRow(pCsr, pRight, pRc); while( !pLeft->bEof && !pRight->bEof && *pRc==SQLITE_OK ){ - tdsqlite3_int64 iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + sqlite3_int64 iDiff = DOCID_CMP(pLeft->iDocid, pRight->iDocid); if( iDiff==0 ) break; if( iDiff<0 ){ fts3EvalNextRow(pCsr, pLeft, pRc); @@ -173851,7 +173851,7 @@ static void fts3EvalNextRow( case FTSQUERY_OR: { Fts3Expr *pLeft = pExpr->pLeft; Fts3Expr *pRight = pExpr->pRight; - tdsqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); + sqlite3_int64 iCmp = DOCID_CMP(pLeft->iDocid, pRight->iDocid); assert( pLeft->bStart || pLeft->iDocid==pRight->iDocid ); assert( pRight->bStart || pLeft->iDocid==pRight->iDocid ); @@ -173953,7 +173953,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ && (pExpr->pParent==0 || pExpr->pParent->eType!=FTSQUERY_NEAR) ){ Fts3Expr *p; - tdsqlite3_int64 nTmp = 0; /* Bytes of temp space */ + sqlite3_int64 nTmp = 0; /* Bytes of temp space */ char *aTmp; /* Temp space for PoslistNearMerge() */ /* Allocate temporary working space. */ @@ -173962,7 +173962,7 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ nTmp += p->pRight->pPhrase->doclist.nList; } nTmp += p->pPhrase->doclist.nList; - aTmp = tdsqlite3_malloc64(nTmp*2); + aTmp = sqlite3_malloc64(nTmp*2); if( !aTmp ){ *pRc = SQLITE_NOMEM; res = 0; @@ -173990,14 +173990,14 @@ static int fts3EvalNearTest(Fts3Expr *pExpr, int *pRc){ } } - tdsqlite3_free(aTmp); + sqlite3_free(aTmp); } return res; } /* -** This function is a helper function for tdsqlite3Fts3EvalTestDeferred(). +** This function is a helper function for sqlite3Fts3EvalTestDeferred(). ** Assuming no error occurs or has occurred, It returns non-zero if the ** expression passed as the second argument matches the row that pCsr ** currently points to, or zero if it does not. @@ -174118,7 +174118,7 @@ static int fts3EvalTestExpr( ** Or, if no error occurs and it seems the current row does match the FTS ** query, return 0. */ -SQLITE_PRIVATE int tdsqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){ +SQLITE_PRIVATE int sqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){ int rc = *pRc; int bMiss = 0; if( rc==SQLITE_OK ){ @@ -174132,13 +174132,13 @@ SQLITE_PRIVATE int tdsqlite3Fts3EvalTestDeferred(Fts3Cursor *pCsr, int *pRc){ if( pCsr->pDeferred ){ rc = fts3CursorSeek(0, pCsr); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts3CacheDeferredDoclists(pCsr); + rc = sqlite3Fts3CacheDeferredDoclists(pCsr); } } bMiss = (0==fts3EvalTestExpr(pCsr, pCsr->pExpr, &rc)); /* Free the position-lists accumulated for each deferred token above. */ - tdsqlite3Fts3FreeDeferredDoclists(pCsr); + sqlite3Fts3FreeDeferredDoclists(pCsr); *pRc = rc; } return (rc==SQLITE_OK && bMiss); @@ -174157,15 +174157,15 @@ static int fts3EvalNext(Fts3Cursor *pCsr){ }else{ do { if( pCsr->isRequireSeek==0 ){ - tdsqlite3_reset(pCsr->pStmt); + sqlite3_reset(pCsr->pStmt); } - assert( tdsqlite3_data_count(pCsr->pStmt)==0 ); + assert( sqlite3_data_count(pCsr->pStmt)==0 ); fts3EvalNextRow(pCsr, pExpr, &rc); pCsr->isEof = pExpr->bEof; pCsr->isRequireSeek = 1; pCsr->isMatchinfoNeeded = 1; pCsr->iPrevId = pExpr->iDocid; - }while( pCsr->isEof==0 && tdsqlite3Fts3EvalTestDeferred(pCsr, &rc) ); + }while( pCsr->isEof==0 && sqlite3Fts3EvalTestDeferred(pCsr, &rc) ); } /* Check if the cursor is past the end of the docid range specified @@ -174205,7 +174205,7 @@ static void fts3EvalRestart( Fts3PhraseToken *pToken = &pPhrase->aToken[i]; assert( pToken->pDeferred==0 ); if( pToken->pSegcsr ){ - tdsqlite3Fts3MsrIncrRestart(pToken->pSegcsr); + sqlite3Fts3MsrIncrRestart(pToken->pSegcsr); } } *pRc = fts3EvalPhraseStart(pCsr, 0, pPhrase); @@ -174286,8 +174286,8 @@ static int fts3EvalGatherStats( Fts3Expr *pRoot; /* Root of NEAR expression */ Fts3Expr *p; /* Iterator used for several purposes */ - tdsqlite3_int64 iPrevId = pCsr->iPrevId; - tdsqlite3_int64 iDocid; + sqlite3_int64 iPrevId = pCsr->iPrevId; + sqlite3_int64 iDocid; u8 bEof; /* Find the root of the NEAR expression */ @@ -174303,7 +174303,7 @@ static int fts3EvalGatherStats( for(p=pRoot; p; p=p->pLeft){ Fts3Expr *pE = (p->eType==FTSQUERY_PHRASE?p:p->pRight); assert( pE->aMI==0 ); - pE->aMI = (u32 *)tdsqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); + pE->aMI = (u32 *)sqlite3_malloc64(pTab->nColumn * 3 * sizeof(u32)); if( !pE->aMI ) return SQLITE_NOMEM; memset(pE->aMI, 0, pTab->nColumn * 3 * sizeof(u32)); } @@ -174314,8 +174314,8 @@ static int fts3EvalGatherStats( do { /* Ensure the %_content statement is reset. */ - if( pCsr->isRequireSeek==0 ) tdsqlite3_reset(pCsr->pStmt); - assert( tdsqlite3_data_count(pCsr->pStmt)==0 ); + if( pCsr->isRequireSeek==0 ) sqlite3_reset(pCsr->pStmt); + assert( sqlite3_data_count(pCsr->pStmt)==0 ); /* Advance to the next document */ fts3EvalNextRow(pCsr, pRoot, &rc); @@ -174325,7 +174325,7 @@ static int fts3EvalGatherStats( pCsr->iPrevId = pRoot->iDocid; }while( pCsr->isEof==0 && pRoot->eType==FTSQUERY_NEAR - && tdsqlite3Fts3EvalTestDeferred(pCsr, &rc) + && sqlite3Fts3EvalTestDeferred(pCsr, &rc) ); if( rc==SQLITE_OK && pCsr->isEof==0 ){ @@ -174385,7 +174385,7 @@ static int fts3EvalGatherStats( ** * If the phrase is part of a NEAR expression, then only phrase instances ** that meet the NEAR constraint are included in the counts. */ -SQLITE_PRIVATE int tdsqlite3Fts3EvalPhraseStats( +SQLITE_PRIVATE int sqlite3Fts3EvalPhraseStats( Fts3Cursor *pCsr, /* FTS cursor handle */ Fts3Expr *pExpr, /* Phrase expression */ u32 *aiOut /* Array to write results into (see above) */ @@ -174433,7 +174433,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3EvalPhraseStats( ** This function works regardless of whether or not the phrase is deferred, ** incremental, or neither. */ -SQLITE_PRIVATE int tdsqlite3Fts3EvalPhrasePoslist( +SQLITE_PRIVATE int sqlite3Fts3EvalPhrasePoslist( Fts3Cursor *pCsr, /* FTS3 cursor object */ Fts3Expr *pExpr, /* Phrase to return doclist for */ int iCol, /* Column to return position list for */ @@ -174443,7 +174443,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3EvalPhrasePoslist( Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; char *pIter; int iThis; - tdsqlite3_int64 iDocid; + sqlite3_int64 iDocid; /* If this phrase is applies specifically to some column other than ** column iCol, return a NULL pointer. */ @@ -174512,7 +174512,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3EvalPhrasePoslist( bEof = !pPh->doclist.nAll || (pIter >= (pPh->doclist.aAll + pPh->doclist.nAll)); while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)<0 ) && bEof==0 ){ - tdsqlite3Fts3DoclistNext( + sqlite3Fts3DoclistNext( bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, &pIter, &iDocid, &bEof ); @@ -174521,7 +174521,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3EvalPhrasePoslist( bEof = !pPh->doclist.nAll || (pIter && pIter<=pPh->doclist.aAll); while( (pIter==0 || DOCID_CMP(iDocid, pCsr->iPrevId)>0 ) && bEof==0 ){ int dummy; - tdsqlite3Fts3DoclistPrev( + sqlite3Fts3DoclistPrev( bDescDoclist, pPh->doclist.aAll, pPh->doclist.nAll, &pIter, &iDocid, &dummy, &bEof ); @@ -174567,10 +174567,10 @@ SQLITE_PRIVATE int tdsqlite3Fts3EvalPhrasePoslist( ** * the contents of pPhrase->doclist, and ** * any Fts3MultiSegReader objects held by phrase tokens. */ -SQLITE_PRIVATE void tdsqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){ +SQLITE_PRIVATE void sqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){ if( pPhrase ){ int i; - tdsqlite3_free(pPhrase->doclist.aAll); + sqlite3_free(pPhrase->doclist.aAll); fts3EvalInvalidatePoslist(pPhrase); memset(&pPhrase->doclist, 0, sizeof(Fts3Doclist)); for(i=0; inToken; i++){ @@ -174585,7 +174585,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3EvalPhraseCleanup(Fts3Phrase *pPhrase){ ** Return SQLITE_CORRUPT_VTAB. */ #ifdef SQLITE_DEBUG -SQLITE_PRIVATE int tdsqlite3Fts3Corrupt(){ +SQLITE_PRIVATE int sqlite3Fts3Corrupt(){ return SQLITE_CORRUPT_VTAB; } #endif @@ -174597,13 +174597,13 @@ SQLITE_PRIVATE int tdsqlite3Fts3Corrupt(){ #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int tdsqlite3_fts3_init( - tdsqlite3 *db, +SQLITE_API int sqlite3_fts3_init( + sqlite3 *db, char **pzErrMsg, - const tdsqlite3_api_routines *pApi + const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi) - return tdsqlite3Fts3Init(db); + return sqlite3Fts3Init(db); } #endif @@ -174634,25 +174634,25 @@ typedef struct Fts3auxTable Fts3auxTable; typedef struct Fts3auxCursor Fts3auxCursor; struct Fts3auxTable { - tdsqlite3_vtab base; /* Base class used by SQLite core */ + sqlite3_vtab base; /* Base class used by SQLite core */ Fts3Table *pFts3Tab; }; struct Fts3auxCursor { - tdsqlite3_vtab_cursor base; /* Base class used by SQLite core */ + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ Fts3MultiSegReader csr; /* Must be right after "base" */ Fts3SegFilter filter; char *zStop; int nStop; /* Byte-length of string zStop */ int iLangid; /* Language id to query */ int isEof; /* True if cursor is at EOF */ - tdsqlite3_int64 iRowid; /* Current rowid */ + sqlite3_int64 iRowid; /* Current rowid */ int iCol; /* Current value of 'col' column */ int nStat; /* Size of aStat[] array */ struct Fts3auxColstats { - tdsqlite3_int64 nDoc; /* 'documents' values for current csr row */ - tdsqlite3_int64 nOcc; /* 'occurrences' values for current csr row */ + sqlite3_int64 nDoc; /* 'documents' values for current csr row */ + sqlite3_int64 nOcc; /* 'occurrences' values for current csr row */ } *aStat; }; @@ -174668,18 +174668,18 @@ struct Fts3auxCursor { ** and xCreate are identical operations. */ static int fts3auxConnectMethod( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pUnused, /* Unused */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVtab, /* OUT: New tdsqlite3_vtab object */ - char **pzErr /* OUT: tdsqlite3_malloc'd error message */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ ){ char const *zDb; /* Name of database (e.g. "main") */ char const *zFts3; /* Name of fts3 table */ int nDb; /* Result of strlen(zDb) */ int nFts3; /* Result of strlen(zFts3) */ - tdsqlite3_int64 nByte; /* Bytes of space to allocate here */ + sqlite3_int64 nByte; /* Bytes of space to allocate here */ int rc; /* value returned by declare_vtab() */ Fts3auxTable *p; /* Virtual table object to return */ @@ -174695,7 +174695,7 @@ static int fts3auxConnectMethod( zDb = argv[1]; nDb = (int)strlen(zDb); if( argc==5 ){ - if( nDb==4 && 0==tdsqlite3_strnicmp("temp", zDb, 4) ){ + if( nDb==4 && 0==sqlite3_strnicmp("temp", zDb, 4) ){ zDb = argv[3]; nDb = (int)strlen(zDb); zFts3 = argv[4]; @@ -174707,11 +174707,11 @@ static int fts3auxConnectMethod( } nFts3 = (int)strlen(zFts3); - rc = tdsqlite3_declare_vtab(db, FTS3_AUX_SCHEMA); + rc = sqlite3_declare_vtab(db, FTS3_AUX_SCHEMA); if( rc!=SQLITE_OK ) return rc; nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2; - p = (Fts3auxTable *)tdsqlite3_malloc64(nByte); + p = (Fts3auxTable *)sqlite3_malloc64(nByte); if( !p ) return SQLITE_NOMEM; memset(p, 0, nByte); @@ -174723,13 +174723,13 @@ static int fts3auxConnectMethod( memcpy((char *)p->pFts3Tab->zDb, zDb, nDb); memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3); - tdsqlite3Fts3Dequote((char *)p->pFts3Tab->zName); + sqlite3Fts3Dequote((char *)p->pFts3Tab->zName); - *ppVtab = (tdsqlite3_vtab *)p; + *ppVtab = (sqlite3_vtab *)p; return SQLITE_OK; bad_args: - tdsqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor"); + sqlite3Fts3ErrMsg(pzErr, "invalid arguments to fts4aux constructor"); return SQLITE_ERROR; } @@ -174738,17 +174738,17 @@ static int fts3auxConnectMethod( ** These tables have no persistent representation of their own, so xDisconnect ** and xDestroy are identical operations. */ -static int fts3auxDisconnectMethod(tdsqlite3_vtab *pVtab){ +static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){ Fts3auxTable *p = (Fts3auxTable *)pVtab; Fts3Table *pFts3 = p->pFts3Tab; int i; /* Free any prepared statements held */ for(i=0; iaStmt); i++){ - tdsqlite3_finalize(pFts3->aStmt[i]); + sqlite3_finalize(pFts3->aStmt[i]); } - tdsqlite3_free(pFts3->zSegmentsTbl); - tdsqlite3_free(p); + sqlite3_free(pFts3->zSegmentsTbl); + sqlite3_free(p); return SQLITE_OK; } @@ -174760,8 +174760,8 @@ static int fts3auxDisconnectMethod(tdsqlite3_vtab *pVtab){ ** xBestIndex - Analyze a WHERE and ORDER BY clause. */ static int fts3auxBestIndexMethod( - tdsqlite3_vtab *pVTab, - tdsqlite3_index_info *pInfo + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo ){ int i; int iEq = -1; @@ -174829,39 +174829,39 @@ static int fts3auxBestIndexMethod( /* ** xOpen - Open a cursor. */ -static int fts3auxOpenMethod(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCsr){ +static int fts3auxOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ Fts3auxCursor *pCsr; /* Pointer to cursor object to return */ UNUSED_PARAMETER(pVTab); - pCsr = (Fts3auxCursor *)tdsqlite3_malloc(sizeof(Fts3auxCursor)); + pCsr = (Fts3auxCursor *)sqlite3_malloc(sizeof(Fts3auxCursor)); if( !pCsr ) return SQLITE_NOMEM; memset(pCsr, 0, sizeof(Fts3auxCursor)); - *ppCsr = (tdsqlite3_vtab_cursor *)pCsr; + *ppCsr = (sqlite3_vtab_cursor *)pCsr; return SQLITE_OK; } /* ** xClose - Close a cursor. */ -static int fts3auxCloseMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){ Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; - tdsqlite3Fts3SegmentsClose(pFts3); - tdsqlite3Fts3SegReaderFinish(&pCsr->csr); - tdsqlite3_free((void *)pCsr->filter.zTerm); - tdsqlite3_free(pCsr->zStop); - tdsqlite3_free(pCsr->aStat); - tdsqlite3_free(pCsr); + sqlite3Fts3SegmentsClose(pFts3); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->zStop); + sqlite3_free(pCsr->aStat); + sqlite3_free(pCsr); return SQLITE_OK; } static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){ if( nSize>pCsr->nStat ){ struct Fts3auxColstats *aNew; - aNew = (struct Fts3auxColstats *)tdsqlite3_realloc64(pCsr->aStat, + aNew = (struct Fts3auxColstats *)sqlite3_realloc64(pCsr->aStat, sizeof(struct Fts3auxColstats) * nSize ); if( aNew==0 ) return SQLITE_NOMEM; @@ -174877,7 +174877,7 @@ static int fts3auxGrowStatArray(Fts3auxCursor *pCsr, int nSize){ /* ** xNext - Advance the cursor to the next row, if any. */ -static int fts3auxNextMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){ Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; int rc; @@ -174889,7 +174889,7 @@ static int fts3auxNextMethod(tdsqlite3_vtab_cursor *pCursor){ if( pCsr->aStat[pCsr->iCol].nDoc>0 ) return SQLITE_OK; } - rc = tdsqlite3Fts3SegReaderStep(pFts3, &pCsr->csr); + rc = sqlite3Fts3SegReaderStep(pFts3, &pCsr->csr); if( rc==SQLITE_ROW ){ int i = 0; int nDoclist = pCsr->csr.nDoclist; @@ -174912,9 +174912,9 @@ static int fts3auxNextMethod(tdsqlite3_vtab_cursor *pCursor){ iCol = 0; while( ipVtab)->pFts3Tab; @@ -175016,32 +175016,32 @@ static int fts3auxFilterMethod( /* In case this cursor is being reused, close and zero it. */ testcase(pCsr->filter.zTerm); - tdsqlite3Fts3SegReaderFinish(&pCsr->csr); - tdsqlite3_free((void *)pCsr->filter.zTerm); - tdsqlite3_free(pCsr->aStat); + sqlite3Fts3SegReaderFinish(&pCsr->csr); + sqlite3_free((void *)pCsr->filter.zTerm); + sqlite3_free(pCsr->aStat); memset(&pCsr->csr, 0, ((u8*)&pCsr[1]) - (u8*)&pCsr->csr); pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; if( isScan ) pCsr->filter.flags |= FTS3_SEGMENT_SCAN; if( iEq>=0 || iGe>=0 ){ - const unsigned char *zStr = tdsqlite3_value_text(apVal[0]); + const unsigned char *zStr = sqlite3_value_text(apVal[0]); assert( (iEq==0 && iGe==-1) || (iEq==-1 && iGe==0) ); if( zStr ){ - pCsr->filter.zTerm = tdsqlite3_mprintf("%s", zStr); + pCsr->filter.zTerm = sqlite3_mprintf("%s", zStr); if( pCsr->filter.zTerm==0 ) return SQLITE_NOMEM; pCsr->filter.nTerm = (int)strlen(pCsr->filter.zTerm); } } if( iLe>=0 ){ - pCsr->zStop = tdsqlite3_mprintf("%s", tdsqlite3_value_text(apVal[iLe])); + pCsr->zStop = sqlite3_mprintf("%s", sqlite3_value_text(apVal[iLe])); if( pCsr->zStop==0 ) return SQLITE_NOMEM; pCsr->nStop = (int)strlen(pCsr->zStop); } if( iLangid>=0 ){ - iLangVal = tdsqlite3_value_int(apVal[iLangid]); + iLangVal = sqlite3_value_int(apVal[iLangid]); /* If the user specified a negative value for the languageid, use zero ** instead. This works, as the "languageid=?" constraint will also @@ -175052,11 +175052,11 @@ static int fts3auxFilterMethod( } pCsr->iLangid = iLangVal; - rc = tdsqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL, + rc = sqlite3Fts3SegReaderCursor(pFts3, iLangVal, 0, FTS3_SEGCURSOR_ALL, pCsr->filter.zTerm, pCsr->filter.nTerm, 0, isScan, &pCsr->csr ); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); + rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter); } if( rc==SQLITE_OK ) rc = fts3auxNextMethod(pCursor); @@ -175066,7 +175066,7 @@ static int fts3auxFilterMethod( /* ** xEof - Return true if the cursor is at EOF, or false otherwise. */ -static int fts3auxEofMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){ Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; return pCsr->isEof; } @@ -175075,8 +175075,8 @@ static int fts3auxEofMethod(tdsqlite3_vtab_cursor *pCursor){ ** xColumn - Return a column value. */ static int fts3auxColumnMethod( - tdsqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - tdsqlite3_context *pCtx, /* Context for tdsqlite3_result_xxx() calls */ + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ int iCol /* Index of column to read value from */ ){ Fts3auxCursor *p = (Fts3auxCursor *)pCursor; @@ -175084,28 +175084,28 @@ static int fts3auxColumnMethod( assert( p->isEof==0 ); switch( iCol ){ case 0: /* term */ - tdsqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT); break; case 1: /* col */ if( p->iCol ){ - tdsqlite3_result_int(pCtx, p->iCol-1); + sqlite3_result_int(pCtx, p->iCol-1); }else{ - tdsqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC); + sqlite3_result_text(pCtx, "*", -1, SQLITE_STATIC); } break; case 2: /* documents */ - tdsqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc); + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nDoc); break; case 3: /* occurrences */ - tdsqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc); + sqlite3_result_int64(pCtx, p->aStat[p->iCol].nOcc); break; default: /* languageid */ assert( iCol==4 ); - tdsqlite3_result_int(pCtx, p->iLangid); + sqlite3_result_int(pCtx, p->iLangid); break; } @@ -175116,7 +175116,7 @@ static int fts3auxColumnMethod( ** xRowid - Return the current rowid for the cursor. */ static int fts3auxRowidMethod( - tdsqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ sqlite_int64 *pRowid /* OUT: Rowid value */ ){ Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor; @@ -175126,10 +175126,10 @@ static int fts3auxRowidMethod( /* ** Register the fts3aux module with database connection db. Return SQLITE_OK -** if successful or an error code if tdsqlite3_create_module() fails. +** if successful or an error code if sqlite3_create_module() fails. */ -SQLITE_PRIVATE int tdsqlite3Fts3InitAux(tdsqlite3 *db){ - static const tdsqlite3_module fts3aux_module = { +SQLITE_PRIVATE int sqlite3Fts3InitAux(sqlite3 *db){ + static const sqlite3_module fts3aux_module = { 0, /* iVersion */ fts3auxConnectMethod, /* xCreate */ fts3auxConnectMethod, /* xConnect */ @@ -175157,7 +175157,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitAux(tdsqlite3 *db){ }; int rc; /* Return code */ - rc = tdsqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); + rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); return rc; } @@ -175203,7 +175203,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitAux(tdsqlite3 *db){ ** AND operators have a higher precedence than OR. ** ** If compiled with SQLITE_TEST defined, then this module exports the -** symbol "int tdsqlite3_fts3_enable_parentheses". Setting this variable +** symbol "int sqlite3_fts3_enable_parentheses". Setting this variable ** to zero causes the module to use the old syntax. If it is set to ** non-zero the new syntax is activated. This is so both syntaxes can ** be tested using a single build of testfixture. @@ -175231,12 +175231,12 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitAux(tdsqlite3 *db){ */ #ifdef SQLITE_TEST -SQLITE_API int tdsqlite3_fts3_enable_parentheses = 0; +SQLITE_API int sqlite3_fts3_enable_parentheses = 0; #else # ifdef SQLITE_ENABLE_FTS3_PARENTHESIS -# define tdsqlite3_fts3_enable_parentheses 1 +# define sqlite3_fts3_enable_parentheses 1 # else -# define tdsqlite3_fts3_enable_parentheses 0 +# define sqlite3_fts3_enable_parentheses 0 # endif #endif @@ -175258,14 +175258,14 @@ SQLITE_API int tdsqlite3_fts3_enable_parentheses = 0; */ typedef struct ParseContext ParseContext; struct ParseContext { - tdsqlite3_tokenizer *pTokenizer; /* Tokenizer module */ + sqlite3_tokenizer *pTokenizer; /* Tokenizer module */ int iLangid; /* Language id used with tokenizer */ const char **azCol; /* Array of column names for fts3 table */ int bFts4; /* True to allow FTS4-only syntax */ int nCol; /* Number of entries in azCol[] */ int iDefaultCol; /* Default column to query */ int isNot; /* True if getNextNode() sees a unary - */ - tdsqlite3_context *pCtx; /* Write error message here */ + sqlite3_context *pCtx; /* Write error message here */ int nNest; /* Number of nested brackets */ }; @@ -175285,25 +175285,25 @@ static int fts3isspace(char c){ } /* -** Allocate nByte bytes of memory using tdsqlite3_malloc(). If successful, +** Allocate nByte bytes of memory using sqlite3_malloc(). If successful, ** zero the memory before returning a pointer to it. If unsuccessful, ** return NULL. */ -static void *fts3MallocZero(tdsqlite3_int64 nByte){ - void *pRet = tdsqlite3_malloc64(nByte); +static void *fts3MallocZero(sqlite3_int64 nByte){ + void *pRet = sqlite3_malloc64(nByte); if( pRet ) memset(pRet, 0, nByte); return pRet; } -SQLITE_PRIVATE int tdsqlite3Fts3OpenTokenizer( - tdsqlite3_tokenizer *pTokenizer, +SQLITE_PRIVATE int sqlite3Fts3OpenTokenizer( + sqlite3_tokenizer *pTokenizer, int iLangid, const char *z, int n, - tdsqlite3_tokenizer_cursor **ppCsr + sqlite3_tokenizer_cursor **ppCsr ){ - tdsqlite3_tokenizer_module const *pModule = pTokenizer->pModule; - tdsqlite3_tokenizer_cursor *pCsr = 0; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr = 0; int rc; rc = pModule->xOpen(pTokenizer, z, n, &pCsr); @@ -175335,7 +175335,7 @@ static int fts3ExprParse(ParseContext *, const char *, int, Fts3Expr **, int *); ** single token and set *ppExpr to point to it. If the end of the buffer is ** reached before a token is found, set *ppExpr to zero. It is the ** responsibility of the caller to eventually deallocate the allocated -** Fts3Expr structure (if any) by passing it to tdsqlite3_free(). +** Fts3Expr structure (if any) by passing it to sqlite3_free(). ** ** Return SQLITE_OK if successful, or SQLITE_NOMEM if a memory allocation ** fails. @@ -175347,25 +175347,25 @@ static int getNextToken( Fts3Expr **ppExpr, /* OUT: expression */ int *pnConsumed /* OUT: Number of bytes consumed */ ){ - tdsqlite3_tokenizer *pTokenizer = pParse->pTokenizer; - tdsqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; int rc; - tdsqlite3_tokenizer_cursor *pCursor; + sqlite3_tokenizer_cursor *pCursor; Fts3Expr *pRet = 0; int i = 0; /* Set variable i to the maximum number of bytes of input to tokenize. */ for(i=0; iiLangid, z, i, &pCursor); + rc = sqlite3Fts3OpenTokenizer(pTokenizer, pParse->iLangid, z, i, &pCursor); if( rc==SQLITE_OK ){ const char *zToken; int nToken = 0, iStart = 0, iEnd = 0, iPosition = 0; - tdsqlite3_int64 nByte; /* total space to allocate */ + sqlite3_int64 nByte; /* total space to allocate */ rc = pModule->xNext(pCursor, &zToken, &nToken, &iStart, &iEnd, &iPosition); if( rc==SQLITE_OK ){ @@ -175388,7 +175388,7 @@ static int getNextToken( } while( 1 ){ - if( !tdsqlite3_fts3_enable_parentheses + if( !sqlite3_fts3_enable_parentheses && iStart>0 && z[iStart-1]=='-' ){ pParse->isNot = 1; @@ -175419,10 +175419,10 @@ static int getNextToken( ** Enlarge a memory allocation. If an out-of-memory allocation occurs, ** then free the old allocation. */ -static void *fts3ReallocOrFree(void *pOrig, tdsqlite3_int64 nNew){ - void *pRet = tdsqlite3_realloc64(pOrig, nNew); +static void *fts3ReallocOrFree(void *pOrig, sqlite3_int64 nNew){ + void *pRet = sqlite3_realloc64(pOrig, nNew); if( !pRet ){ - tdsqlite3_free(pOrig); + sqlite3_free(pOrig); } return pRet; } @@ -175444,11 +175444,11 @@ static int getNextString( const char *zInput, int nInput, /* Input string */ Fts3Expr **ppExpr /* OUT: expression */ ){ - tdsqlite3_tokenizer *pTokenizer = pParse->pTokenizer; - tdsqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer *pTokenizer = pParse->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; int rc; Fts3Expr *p = 0; - tdsqlite3_tokenizer_cursor *pCursor = 0; + sqlite3_tokenizer_cursor *pCursor = 0; char *zTemp = 0; int nTemp = 0; @@ -175458,7 +175458,7 @@ static int getNextString( /* The final Fts3Expr data structure, including the Fts3Phrase, ** Fts3PhraseToken structures token buffers are all stored as a single ** allocation so that the expression can be freed with a single call to - ** tdsqlite3_free(). Setting this up requires a two pass approach. + ** sqlite3_free(). Setting this up requires a two pass approach. ** ** The first pass, in the block below, uses a tokenizer cursor to iterate ** through the tokens in the expression. This pass uses fts3ReallocOrFree() @@ -175474,7 +175474,7 @@ static int getNextString( ** appends buffer zTemp to buffer p, and fills in the Fts3Expr and Fts3Phrase ** structures. */ - rc = tdsqlite3Fts3OpenTokenizer( + rc = sqlite3Fts3OpenTokenizer( pTokenizer, pParse->iLangid, zInput, nInput, &pCursor); if( rc==SQLITE_OK ){ int ii; @@ -175524,7 +175524,7 @@ static int getNextString( zBuf = (char *)&p->pPhrase->aToken[nToken]; if( zTemp ){ memcpy(zBuf, zTemp, nTemp); - tdsqlite3_free(zTemp); + sqlite3_free(zTemp); }else{ assert( nTemp==0 ); } @@ -175543,8 +175543,8 @@ no_mem: if( pCursor ){ pModule->xClose(pCursor); } - tdsqlite3_free(zTemp); - tdsqlite3_free(p); + sqlite3_free(zTemp); + sqlite3_free(p); *ppExpr = 0; return SQLITE_NOMEM; } @@ -175600,7 +175600,7 @@ static int getNextNode( for(ii=0; ii<(int)(sizeof(aKeyword)/sizeof(struct Fts3Keyword)); ii++){ const struct Fts3Keyword *pKey = &aKeyword[ii]; - if( (pKey->parenOnly & ~tdsqlite3_fts3_enable_parentheses)!=0 ){ + if( (pKey->parenOnly & ~sqlite3_fts3_enable_parentheses)!=0 ){ continue; } @@ -175659,7 +175659,7 @@ static int getNextNode( return getNextString(pParse, &zInput[1], ii-1, ppExpr); } - if( tdsqlite3_fts3_enable_parentheses ){ + if( sqlite3_fts3_enable_parentheses ){ if( *zInput=='(' ){ int nConsumed = 0; pParse->nNest++; @@ -175675,7 +175675,7 @@ static int getNextNode( } /* If control flows to this point, this must be a regular token, or - ** the end of the input. Read a regular token using the tdsqlite3_tokenizer + ** the end of the input. Read a regular token using the sqlite3_tokenizer ** interface. Before doing so, figure out if there is an explicit ** column specifier for the token. ** @@ -175691,7 +175691,7 @@ static int getNextNode( const char *zStr = pParse->azCol[ii]; int nStr = (int)strlen(zStr); if( nInput>nStr && zInput[nStr]==':' - && tdsqlite3_strnicmp(zStr, zInput, nStr)==0 + && sqlite3_strnicmp(zStr, zInput, nStr)==0 ){ iCol = ii; iColLen = (int)((zInput - z) + nStr + 1); @@ -175724,7 +175724,7 @@ static int getNextNode( */ static int opPrecedence(Fts3Expr *p){ assert( p->eType!=FTSQUERY_PHRASE ); - if( tdsqlite3_fts3_enable_parentheses ){ + if( sqlite3_fts3_enable_parentheses ){ return p->eType; }else if( p->eType==FTSQUERY_NEAR ){ return 1; @@ -175798,13 +175798,13 @@ static int fts3ExprParse( if( p ){ int isPhrase; - if( !tdsqlite3_fts3_enable_parentheses + if( !sqlite3_fts3_enable_parentheses && p->eType==FTSQUERY_PHRASE && pParse->isNot ){ /* Create an implicit NOT operator. */ Fts3Expr *pNot = fts3MallocZero(sizeof(Fts3Expr)); if( !pNot ){ - tdsqlite3Fts3ExprFree(p); + sqlite3Fts3ExprFree(p); rc = SQLITE_NOMEM; goto exprparse_out; } @@ -175827,7 +175827,7 @@ static int fts3ExprParse( ** isRequirePhrase is set, this is a syntax error. */ if( !isPhrase && isRequirePhrase ){ - tdsqlite3Fts3ExprFree(p); + sqlite3Fts3ExprFree(p); rc = SQLITE_ERROR; goto exprparse_out; } @@ -175838,7 +175838,7 @@ static int fts3ExprParse( assert( pRet && pPrev ); pAnd = fts3MallocZero(sizeof(Fts3Expr)); if( !pAnd ){ - tdsqlite3Fts3ExprFree(p); + sqlite3Fts3ExprFree(p); rc = SQLITE_NOMEM; goto exprparse_out; } @@ -175860,7 +175860,7 @@ static int fts3ExprParse( (eType==FTSQUERY_NEAR && !isPhrase && pPrev->eType!=FTSQUERY_PHRASE) || (eType!=FTSQUERY_PHRASE && isPhrase && pPrev->eType==FTSQUERY_NEAR) )){ - tdsqlite3Fts3ExprFree(p); + sqlite3Fts3ExprFree(p); rc = SQLITE_ERROR; goto exprparse_out; } @@ -175893,7 +175893,7 @@ static int fts3ExprParse( if( rc==SQLITE_DONE ){ rc = SQLITE_OK; - if( !tdsqlite3_fts3_enable_parentheses && pNotBranch ){ + if( !sqlite3_fts3_enable_parentheses && pNotBranch ){ if( !pRet ){ rc = SQLITE_ERROR; }else{ @@ -175911,8 +175911,8 @@ static int fts3ExprParse( exprparse_out: if( rc!=SQLITE_OK ){ - tdsqlite3Fts3ExprFree(pRet); - tdsqlite3Fts3ExprFree(pNotBranch); + sqlite3Fts3ExprFree(pRet); + sqlite3Fts3ExprFree(pNotBranch); pRet = 0; } *ppExpr = pRet; @@ -175962,7 +175962,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ if( rc==SQLITE_OK ){ if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){ Fts3Expr **apLeaf; - apLeaf = (Fts3Expr **)tdsqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth); + apLeaf = (Fts3Expr **)sqlite3_malloc64(sizeof(Fts3Expr *) * nMaxDepth); if( 0==apLeaf ){ rc = SQLITE_NOMEM; }else{ @@ -176012,7 +176012,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ } } if( p ){ - tdsqlite3Fts3ExprFree(p); + sqlite3Fts3ExprFree(p); rc = SQLITE_TOOBIG; break; } @@ -176063,19 +176063,19 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ }else{ /* An error occurred. Delete the contents of the apLeaf[] array ** and pFree list. Everything else is cleaned up by the call to - ** tdsqlite3Fts3ExprFree(pRoot) below. */ + ** sqlite3Fts3ExprFree(pRoot) below. */ Fts3Expr *pDel; for(i=0; ipParent; - tdsqlite3_free(pDel); + sqlite3_free(pDel); } } assert( pFree==0 ); - tdsqlite3_free( apLeaf ); + sqlite3_free( apLeaf ); } }else if( eType==FTSQUERY_NOT ){ Fts3Expr *pLeft = pRoot->pLeft; @@ -176092,8 +176092,8 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ } if( rc!=SQLITE_OK ){ - tdsqlite3Fts3ExprFree(pRight); - tdsqlite3Fts3ExprFree(pLeft); + sqlite3Fts3ExprFree(pRight); + sqlite3Fts3ExprFree(pLeft); }else{ assert( pLeft && pRight ); pRoot->pLeft = pLeft; @@ -176105,7 +176105,7 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ } if( rc!=SQLITE_OK ){ - tdsqlite3Fts3ExprFree(pRoot); + sqlite3Fts3ExprFree(pRoot); pRoot = 0; } *pp = pRoot; @@ -176113,18 +176113,18 @@ static int fts3ExprBalance(Fts3Expr **pp, int nMaxDepth){ } /* -** This function is similar to tdsqlite3Fts3ExprParse(), with the following +** This function is similar to sqlite3Fts3ExprParse(), with the following ** differences: ** ** 1. It does not do expression rebalancing. ** 2. It does not check that the expression does not exceed the ** maximum allowable depth. ** 3. Even if it fails, *ppExpr may still be set to point to an -** expression tree. It should be deleted using tdsqlite3Fts3ExprFree() +** expression tree. It should be deleted using sqlite3Fts3ExprFree() ** in this case. */ static int fts3ExprParseUnbalanced( - tdsqlite3_tokenizer *pTokenizer, /* Tokenizer module */ + sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ int iLangid, /* Language id for tokenizer */ char **azCol, /* Array of column names for fts3 table */ int bFts4, /* True to allow FTS4-only syntax */ @@ -176186,8 +176186,8 @@ static int fts3ExprParseUnbalanced( ** specified as part of the query string), or -1 if tokens may by default ** match any table column. */ -SQLITE_PRIVATE int tdsqlite3Fts3ExprParse( - tdsqlite3_tokenizer *pTokenizer, /* Tokenizer module */ +SQLITE_PRIVATE int sqlite3Fts3ExprParse( + sqlite3_tokenizer *pTokenizer, /* Tokenizer module */ int iLangid, /* Language id for tokenizer */ char **azCol, /* Array of column names for fts3 table */ int bFts4, /* True to allow FTS4-only syntax */ @@ -176195,7 +176195,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3ExprParse( int iDefaultCol, /* Default column to query */ const char *z, int n, /* Text of MATCH query */ Fts3Expr **ppExpr, /* OUT: Parsed query structure */ - char **pzErr /* OUT: Error message (tdsqlite3_malloc) */ + char **pzErr /* OUT: Error message (sqlite3_malloc) */ ){ int rc = fts3ExprParseUnbalanced( pTokenizer, iLangid, azCol, bFts4, nCol, iDefaultCol, z, n, ppExpr @@ -176211,16 +176211,16 @@ SQLITE_PRIVATE int tdsqlite3Fts3ExprParse( } if( rc!=SQLITE_OK ){ - tdsqlite3Fts3ExprFree(*ppExpr); + sqlite3Fts3ExprFree(*ppExpr); *ppExpr = 0; if( rc==SQLITE_TOOBIG ){ - tdsqlite3Fts3ErrMsg(pzErr, + sqlite3Fts3ErrMsg(pzErr, "FTS expression tree is too large (maximum depth %d)", SQLITE_FTS3_MAX_EXPR_DEPTH ); rc = SQLITE_ERROR; }else if( rc==SQLITE_ERROR ){ - tdsqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z); + sqlite3Fts3ErrMsg(pzErr, "malformed MATCH expression: [%s]", z); } } @@ -176232,19 +176232,19 @@ SQLITE_PRIVATE int tdsqlite3Fts3ExprParse( */ static void fts3FreeExprNode(Fts3Expr *p){ assert( p->eType==FTSQUERY_PHRASE || p->pPhrase==0 ); - tdsqlite3Fts3EvalPhraseCleanup(p->pPhrase); - tdsqlite3_free(p->aMI); - tdsqlite3_free(p); + sqlite3Fts3EvalPhraseCleanup(p->pPhrase); + sqlite3_free(p->aMI); + sqlite3_free(p); } /* -** Free a parsed fts3 query expression allocated by tdsqlite3Fts3ExprParse(). +** Free a parsed fts3 query expression allocated by sqlite3Fts3ExprParse(). ** ** This function would be simpler if it recursively called itself. But ** that would mean passing a sufficiently large expression to ExprParse() ** could cause a stack overflow. */ -SQLITE_PRIVATE void tdsqlite3Fts3ExprFree(Fts3Expr *pDel){ +SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *pDel){ Fts3Expr *p; assert( pDel==0 || pDel->pParent==0 ); for(p=pDel; p && (p->pLeft||p->pRight); p=(p->pLeft ? p->pLeft : p->pRight)){ @@ -176277,25 +176277,25 @@ SQLITE_PRIVATE void tdsqlite3Fts3ExprFree(Fts3Expr *pDel){ /* ** Return a pointer to a buffer containing a text representation of the ** expression passed as the first argument. The buffer is obtained from -** tdsqlite3_malloc(). It is the responsibility of the caller to use -** tdsqlite3_free() to release the memory. If an OOM condition is encountered, +** sqlite3_malloc(). It is the responsibility of the caller to use +** sqlite3_free() to release the memory. If an OOM condition is encountered, ** NULL is returned. ** ** If the second argument is not NULL, then its contents are prepended to -** the returned expression text and then freed using tdsqlite3_free(). +** the returned expression text and then freed using sqlite3_free(). */ static char *exprToString(Fts3Expr *pExpr, char *zBuf){ if( pExpr==0 ){ - return tdsqlite3_mprintf(""); + return sqlite3_mprintf(""); } switch( pExpr->eType ){ case FTSQUERY_PHRASE: { Fts3Phrase *pPhrase = pExpr->pPhrase; int i; - zBuf = tdsqlite3_mprintf( + zBuf = sqlite3_mprintf( "%zPHRASE %d 0", zBuf, pPhrase->iColumn); for(i=0; zBuf && inToken; i++){ - zBuf = tdsqlite3_mprintf("%z %.*s%s", zBuf, + zBuf = sqlite3_mprintf("%z %.*s%s", zBuf, pPhrase->aToken[i].n, pPhrase->aToken[i].z, (pPhrase->aToken[i].isPrefix?"+":"") ); @@ -176304,25 +176304,25 @@ static char *exprToString(Fts3Expr *pExpr, char *zBuf){ } case FTSQUERY_NEAR: - zBuf = tdsqlite3_mprintf("%zNEAR/%d ", zBuf, pExpr->nNear); + zBuf = sqlite3_mprintf("%zNEAR/%d ", zBuf, pExpr->nNear); break; case FTSQUERY_NOT: - zBuf = tdsqlite3_mprintf("%zNOT ", zBuf); + zBuf = sqlite3_mprintf("%zNOT ", zBuf); break; case FTSQUERY_AND: - zBuf = tdsqlite3_mprintf("%zAND ", zBuf); + zBuf = sqlite3_mprintf("%zAND ", zBuf); break; case FTSQUERY_OR: - zBuf = tdsqlite3_mprintf("%zOR ", zBuf); + zBuf = sqlite3_mprintf("%zOR ", zBuf); break; } - if( zBuf ) zBuf = tdsqlite3_mprintf("%z{", zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z{", zBuf); if( zBuf ) zBuf = exprToString(pExpr->pLeft, zBuf); - if( zBuf ) zBuf = tdsqlite3_mprintf("%z} {", zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z} {", zBuf); if( zBuf ) zBuf = exprToString(pExpr->pRight, zBuf); - if( zBuf ) zBuf = tdsqlite3_mprintf("%z}", zBuf); + if( zBuf ) zBuf = sqlite3_mprintf("%z}", zBuf); return zBuf; } @@ -176343,11 +176343,11 @@ static char *exprToString(Fts3Expr *pExpr, char *zBuf){ */ static void fts3ExprTestCommon( int bRebalance, - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ - tdsqlite3_tokenizer *pTokenizer = 0; + sqlite3_tokenizer *pTokenizer = 0; int rc; char **azCol = 0; const char *zExpr; @@ -176356,48 +176356,48 @@ static void fts3ExprTestCommon( int ii; Fts3Expr *pExpr; char *zBuf = 0; - Fts3Hash *pHash = (Fts3Hash*)tdsqlite3_user_data(context); + Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context); const char *zTokenizer = 0; char *zErr = 0; if( argc<3 ){ - tdsqlite3_result_error(context, + sqlite3_result_error(context, "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1 ); return; } - zTokenizer = (const char*)tdsqlite3_value_text(argv[0]); - rc = tdsqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr); + zTokenizer = (const char*)sqlite3_value_text(argv[0]); + rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr); if( rc!=SQLITE_OK ){ if( rc==SQLITE_NOMEM ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); }else{ - tdsqlite3_result_error(context, zErr, -1); + sqlite3_result_error(context, zErr, -1); } - tdsqlite3_free(zErr); + sqlite3_free(zErr); return; } - zExpr = (const char *)tdsqlite3_value_text(argv[1]); - nExpr = tdsqlite3_value_bytes(argv[1]); + zExpr = (const char *)sqlite3_value_text(argv[1]); + nExpr = sqlite3_value_bytes(argv[1]); nCol = argc-2; - azCol = (char **)tdsqlite3_malloc64(nCol*sizeof(char *)); + azCol = (char **)sqlite3_malloc64(nCol*sizeof(char *)); if( !azCol ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); goto exprtest_out; } for(ii=0; iipModule->xDestroy(pTokenizer); } - tdsqlite3_free(azCol); + sqlite3_free(azCol); } static void fts3ExprTest( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ fts3ExprTestCommon(0, context, argc, argv); } static void fts3ExprTestRebalance( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ fts3ExprTestCommon(1, context, argc, argv); } @@ -176442,12 +176442,12 @@ static void fts3ExprTestRebalance( ** Register the query expression parser test function fts3_exprtest() ** with database connection db. */ -SQLITE_PRIVATE int tdsqlite3Fts3ExprInitTestInterface(tdsqlite3 *db, Fts3Hash *pHash){ - int rc = tdsqlite3_create_function( +SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){ + int rc = sqlite3_create_function( db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0 ); if( rc==SQLITE_OK ){ - rc = tdsqlite3_create_function(db, "fts3_exprtest_rebalance", + rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0 ); } @@ -176496,15 +176496,15 @@ SQLITE_PRIVATE int tdsqlite3Fts3ExprInitTestInterface(tdsqlite3 *db, Fts3Hash *p /* ** Malloc and Free functions */ -static void *fts3HashMalloc(tdsqlite3_int64 n){ - void *p = tdsqlite3_malloc64(n); +static void *fts3HashMalloc(sqlite3_int64 n){ + void *p = sqlite3_malloc64(n); if( p ){ memset(p, 0, n); } return p; } static void fts3HashFree(void *p){ - tdsqlite3_free(p); + sqlite3_free(p); } /* Turn bulk memory into a hash table object by initializing the @@ -176517,7 +176517,7 @@ static void fts3HashFree(void *p){ ** true if the hash table should make its own private copy of keys and ** false if it should just use the supplied pointer. */ -SQLITE_PRIVATE void tdsqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey){ +SQLITE_PRIVATE void sqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char copyKey){ assert( pNew!=0 ); assert( keyClass>=FTS3_HASH_STRING && keyClass<=FTS3_HASH_BINARY ); pNew->keyClass = keyClass; @@ -176532,7 +176532,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3HashInit(Fts3Hash *pNew, char keyClass, char co ** Call this routine to delete a hash table or to reset a hash table ** to the empty state. */ -SQLITE_PRIVATE void tdsqlite3Fts3HashClear(Fts3Hash *pH){ +SQLITE_PRIVATE void sqlite3Fts3HashClear(Fts3Hash *pH){ Fts3HashElem *elem; /* For looping over all elements of the table */ assert( pH!=0 ); @@ -176740,7 +176740,7 @@ static void fts3RemoveElementByHash( } } -SQLITE_PRIVATE Fts3HashElem *tdsqlite3Fts3HashFindElem( +SQLITE_PRIVATE Fts3HashElem *sqlite3Fts3HashFindElem( const Fts3Hash *pH, const void *pKey, int nKey @@ -176761,10 +176761,10 @@ SQLITE_PRIVATE Fts3HashElem *tdsqlite3Fts3HashFindElem( ** that matches pKey,nKey. Return the data for this element if it is ** found, or NULL if there is no match. */ -SQLITE_PRIVATE void *tdsqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, int nKey){ +SQLITE_PRIVATE void *sqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, int nKey){ Fts3HashElem *pElem; /* The element that matches key (if any) */ - pElem = tdsqlite3Fts3HashFindElem(pH, pKey, nKey); + pElem = sqlite3Fts3HashFindElem(pH, pKey, nKey); return pElem ? pElem->data : 0; } @@ -176783,7 +176783,7 @@ SQLITE_PRIVATE void *tdsqlite3Fts3HashFind(const Fts3Hash *pH, const void *pKey, ** If the "data" parameter to this function is NULL, then the ** element corresponding to "key" is removed from the hash table. */ -SQLITE_PRIVATE void *tdsqlite3Fts3HashInsert( +SQLITE_PRIVATE void *sqlite3Fts3HashInsert( Fts3Hash *pH, /* The hash table to insert into */ const void *pKey, /* The key */ int nKey, /* Number of bytes in the key */ @@ -176880,17 +176880,17 @@ SQLITE_PRIVATE void *tdsqlite3Fts3HashInsert( /* #include "fts3_tokenizer.h" */ /* -** Class derived from tdsqlite3_tokenizer +** Class derived from sqlite3_tokenizer */ typedef struct porter_tokenizer { - tdsqlite3_tokenizer base; /* Base class */ + sqlite3_tokenizer base; /* Base class */ } porter_tokenizer; /* -** Class derived from tdsqlite3_tokenizer_cursor +** Class derived from sqlite3_tokenizer_cursor */ typedef struct porter_tokenizer_cursor { - tdsqlite3_tokenizer_cursor base; + sqlite3_tokenizer_cursor base; const char *zInput; /* input we are tokenizing */ int nInput; /* size of the input */ int iOffset; /* current position in zInput */ @@ -176905,14 +176905,14 @@ typedef struct porter_tokenizer_cursor { */ static int porterCreate( int argc, const char * const *argv, - tdsqlite3_tokenizer **ppTokenizer + sqlite3_tokenizer **ppTokenizer ){ porter_tokenizer *t; UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); - t = (porter_tokenizer *) tdsqlite3_malloc(sizeof(*t)); + t = (porter_tokenizer *) sqlite3_malloc(sizeof(*t)); if( t==NULL ) return SQLITE_NOMEM; memset(t, 0, sizeof(*t)); *ppTokenizer = &t->base; @@ -176922,8 +176922,8 @@ static int porterCreate( /* ** Destroy a tokenizer */ -static int porterDestroy(tdsqlite3_tokenizer *pTokenizer){ - tdsqlite3_free(pTokenizer); +static int porterDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); return SQLITE_OK; } @@ -176934,15 +176934,15 @@ static int porterDestroy(tdsqlite3_tokenizer *pTokenizer){ ** *ppCursor. */ static int porterOpen( - tdsqlite3_tokenizer *pTokenizer, /* The tokenizer */ + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ const char *zInput, int nInput, /* String to be tokenized */ - tdsqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ ){ porter_tokenizer_cursor *c; UNUSED_PARAMETER(pTokenizer); - c = (porter_tokenizer_cursor *) tdsqlite3_malloc(sizeof(*c)); + c = (porter_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); if( c==NULL ) return SQLITE_NOMEM; c->zInput = zInput; @@ -176966,10 +176966,10 @@ static int porterOpen( ** Close a tokenization cursor previously opened by a call to ** porterOpen() above. */ -static int porterClose(tdsqlite3_tokenizer_cursor *pCursor){ +static int porterClose(sqlite3_tokenizer_cursor *pCursor){ porter_tokenizer_cursor *c = (porter_tokenizer_cursor *) pCursor; - tdsqlite3_free(c->zToken); - tdsqlite3_free(c); + sqlite3_free(c->zToken); + sqlite3_free(c); return SQLITE_OK; } /* @@ -177439,7 +177439,7 @@ static const char porterIdChar[] = { ** have been opened by a prior call to porterOpen(). */ static int porterNext( - tdsqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */ + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by porterOpen */ const char **pzToken, /* OUT: *pzToken is the token text */ int *pnBytes, /* OUT: Number of bytes in token */ int *piStartOffset, /* OUT: Starting offset of token */ @@ -177468,7 +177468,7 @@ static int porterNext( if( n>c->nAllocated ){ char *pNew; c->nAllocated = n+20; - pNew = tdsqlite3_realloc(c->zToken, c->nAllocated); + pNew = sqlite3_realloc(c->zToken, c->nAllocated); if( !pNew ) return SQLITE_NOMEM; c->zToken = pNew; } @@ -177486,7 +177486,7 @@ static int porterNext( /* ** The set of routines that implement the porter-stemmer tokenizer */ -static const tdsqlite3_tokenizer_module porterTokenizerModule = { +static const sqlite3_tokenizer_module porterTokenizerModule = { 0, porterCreate, porterDestroy, @@ -177500,8 +177500,8 @@ static const tdsqlite3_tokenizer_module porterTokenizerModule = { ** Allocate a new porter tokenizer. Return a pointer to the new ** tokenizer in *ppModule */ -SQLITE_PRIVATE void tdsqlite3Fts3PorterTokenizerModule( - tdsqlite3_tokenizer_module const**ppModule +SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule( + sqlite3_tokenizer_module const**ppModule ){ *ppModule = &porterTokenizerModule; } @@ -177543,13 +177543,13 @@ SQLITE_PRIVATE void tdsqlite3Fts3PorterTokenizerModule( /* ** Return true if the two-argument version of fts3_tokenizer() -** has been activated via a prior call to tdsqlite3_db_config(db, +** has been activated via a prior call to sqlite3_db_config(db, ** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0); */ -static int fts3TokenizerEnabled(tdsqlite3_context *context){ - tdsqlite3 *db = tdsqlite3_context_db_handle(context); +static int fts3TokenizerEnabled(sqlite3_context *context){ + sqlite3 *db = sqlite3_context_db_handle(context); int isEnabled = 0; - tdsqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled); + sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled); return isEnabled; } @@ -177561,7 +177561,7 @@ static int fts3TokenizerEnabled(tdsqlite3_context *context){ ** SELECT (, ); ** ** where is the name passed as the second argument -** to the tdsqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer'). +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer'). ** ** If the argument is specified, it must be a blob value ** containing a pointer to be stored as the hash data corresponding @@ -177574,9 +177574,9 @@ static int fts3TokenizerEnabled(tdsqlite3_context *context){ ** to string (after the hash-table is updated, if applicable). */ static void fts3TokenizerFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ Fts3Hash *pHash; void *pPtr = 0; @@ -177585,45 +177585,45 @@ static void fts3TokenizerFunc( assert( argc==1 || argc==2 ); - pHash = (Fts3Hash *)tdsqlite3_user_data(context); + pHash = (Fts3Hash *)sqlite3_user_data(context); - zName = tdsqlite3_value_text(argv[0]); - nName = tdsqlite3_value_bytes(argv[0])+1; + zName = sqlite3_value_text(argv[0]); + nName = sqlite3_value_bytes(argv[0])+1; if( argc==2 ){ - if( fts3TokenizerEnabled(context) || tdsqlite3_value_frombind(argv[1]) ){ + if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){ void *pOld; - int n = tdsqlite3_value_bytes(argv[1]); + int n = sqlite3_value_bytes(argv[1]); if( zName==0 || n!=sizeof(pPtr) ){ - tdsqlite3_result_error(context, "argument type mismatch", -1); + sqlite3_result_error(context, "argument type mismatch", -1); return; } - pPtr = *(void **)tdsqlite3_value_blob(argv[1]); - pOld = tdsqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); + pPtr = *(void **)sqlite3_value_blob(argv[1]); + pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr); if( pOld==pPtr ){ - tdsqlite3_result_error(context, "out of memory", -1); + sqlite3_result_error(context, "out of memory", -1); } }else{ - tdsqlite3_result_error(context, "fts3tokenize disabled", -1); + sqlite3_result_error(context, "fts3tokenize disabled", -1); return; } }else{ if( zName ){ - pPtr = tdsqlite3Fts3HashFind(pHash, zName, nName); + pPtr = sqlite3Fts3HashFind(pHash, zName, nName); } if( !pPtr ){ - char *zErr = tdsqlite3_mprintf("unknown tokenizer: %s", zName); - tdsqlite3_result_error(context, zErr, -1); - tdsqlite3_free(zErr); + char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); return; } } - if( fts3TokenizerEnabled(context) || tdsqlite3_value_frombind(argv[0]) ){ - tdsqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); + if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[0]) ){ + sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT); } } -SQLITE_PRIVATE int tdsqlite3Fts3IsIdChar(char c){ +SQLITE_PRIVATE int sqlite3Fts3IsIdChar(char c){ static const char isFtsIdChar[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 1x */ @@ -177637,7 +177637,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3IsIdChar(char c){ return (c&0x80 || isFtsIdChar[(int)(c)]); } -SQLITE_PRIVATE const char *tdsqlite3Fts3NextToken(const char *zStr, int *pn){ +SQLITE_PRIVATE const char *sqlite3Fts3NextToken(const char *zStr, int *pn){ const char *z1; const char *z2 = 0; @@ -177661,9 +177661,9 @@ SQLITE_PRIVATE const char *tdsqlite3Fts3NextToken(const char *zStr, int *pn){ break; default: - if( tdsqlite3Fts3IsIdChar(*z1) ){ + if( sqlite3Fts3IsIdChar(*z1) ){ z2 = &z1[1]; - while( tdsqlite3Fts3IsIdChar(*z2) ) z2++; + while( sqlite3Fts3IsIdChar(*z2) ) z2++; }else{ z1++; } @@ -177674,10 +177674,10 @@ SQLITE_PRIVATE const char *tdsqlite3Fts3NextToken(const char *zStr, int *pn){ return z1; } -SQLITE_PRIVATE int tdsqlite3Fts3InitTokenizer( +SQLITE_PRIVATE int sqlite3Fts3InitTokenizer( Fts3Hash *pHash, /* Tokenizer hash table */ const char *zArg, /* Tokenizer name */ - tdsqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ + sqlite3_tokenizer **ppTok, /* OUT: Tokenizer (if applicable) */ char **pzErr /* OUT: Set to malloced error message */ ){ int rc; @@ -177685,53 +177685,53 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitTokenizer( int n = 0; char *zCopy; char *zEnd; /* Pointer to nul-term of zCopy */ - tdsqlite3_tokenizer_module *m; + sqlite3_tokenizer_module *m; - zCopy = tdsqlite3_mprintf("%s", zArg); + zCopy = sqlite3_mprintf("%s", zArg); if( !zCopy ) return SQLITE_NOMEM; zEnd = &zCopy[strlen(zCopy)]; - z = (char *)tdsqlite3Fts3NextToken(zCopy, &n); + z = (char *)sqlite3Fts3NextToken(zCopy, &n); if( z==0 ){ assert( n==0 ); z = zCopy; } z[n] = '\0'; - tdsqlite3Fts3Dequote(z); + sqlite3Fts3Dequote(z); - m = (tdsqlite3_tokenizer_module *)tdsqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); + m = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash,z,(int)strlen(z)+1); if( !m ){ - tdsqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z); + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z); rc = SQLITE_ERROR; }else{ char const **aArg = 0; int iArg = 0; z = &z[n+1]; - while( zxCreate(iArg, aArg, ppTok); assert( rc!=SQLITE_OK || *ppTok ); if( rc!=SQLITE_OK ){ - tdsqlite3Fts3ErrMsg(pzErr, "unknown tokenizer"); + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer"); }else{ (*ppTok)->pModule = m; } - tdsqlite3_free((void *)aArg); + sqlite3_free((void *)aArg); } - tdsqlite3_free(zCopy); + sqlite3_free(zCopy); return rc; } @@ -177753,7 +177753,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitTokenizer( ** SELECT (, ..., ); ** ** where is the name passed as the second argument -** to the tdsqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer') +** to the sqlite3Fts3InitHashTable() function (e.g. 'fts3_tokenizer') ** concatenated with the string '_test' (e.g. 'fts3_tokenizer_test'). ** ** The return value is a string that may be interpreted as a Tcl @@ -177771,14 +177771,14 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitTokenizer( ** */ static void testFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ Fts3Hash *pHash; - tdsqlite3_tokenizer_module *p; - tdsqlite3_tokenizer *pTokenizer = 0; - tdsqlite3_tokenizer_cursor *pCsr = 0; + sqlite3_tokenizer_module *p; + sqlite3_tokenizer *pTokenizer = 0; + sqlite3_tokenizer_cursor *pCsr = 0; const char *zErr = 0; @@ -177799,22 +177799,22 @@ static void testFunc( Tcl_Obj *pRet; if( argc<2 ){ - tdsqlite3_result_error(context, "insufficient arguments", -1); + sqlite3_result_error(context, "insufficient arguments", -1); return; } - nName = tdsqlite3_value_bytes(argv[0]); - zName = (const char *)tdsqlite3_value_text(argv[0]); - nInput = tdsqlite3_value_bytes(argv[argc-1]); - zInput = (const char *)tdsqlite3_value_text(argv[argc-1]); + nName = sqlite3_value_bytes(argv[0]); + zName = (const char *)sqlite3_value_text(argv[0]); + nInput = sqlite3_value_bytes(argv[argc-1]); + zInput = (const char *)sqlite3_value_text(argv[argc-1]); - pHash = (Fts3Hash *)tdsqlite3_user_data(context); - p = (tdsqlite3_tokenizer_module *)tdsqlite3Fts3HashFind(pHash, zName, nName+1); + pHash = (Fts3Hash *)sqlite3_user_data(context); + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); if( !p ){ - char *zErr2 = tdsqlite3_mprintf("unknown tokenizer: %s", zName); - tdsqlite3_result_error(context, zErr2, -1); - tdsqlite3_free(zErr2); + char *zErr2 = sqlite3_mprintf("unknown tokenizer: %s", zName); + sqlite3_result_error(context, zErr2, -1); + sqlite3_free(zErr2); return; } @@ -177822,7 +177822,7 @@ static void testFunc( Tcl_IncrRefCount(pRet); for(i=1; ixCreate(argc-2, azArg, &pTokenizer) ){ @@ -177830,7 +177830,7 @@ static void testFunc( goto finish; } pTokenizer->pModule = p; - if( tdsqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){ + if( sqlite3Fts3OpenTokenizer(pTokenizer, 0, zInput, nInput, &pCsr) ){ zErr = "error in xOpen()"; goto finish; } @@ -177854,65 +177854,65 @@ static void testFunc( finish: if( zErr ){ - tdsqlite3_result_error(context, zErr, -1); + sqlite3_result_error(context, zErr, -1); }else{ - tdsqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); + sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT); } Tcl_DecrRefCount(pRet); } static int registerTokenizer( - tdsqlite3 *db, + sqlite3 *db, char *zName, - const tdsqlite3_tokenizer_module *p + const sqlite3_tokenizer_module *p ){ int rc; - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; const char zSql[] = "SELECT fts3_tokenizer(?, ?)"; - rc = tdsqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); if( rc!=SQLITE_OK ){ return rc; } - tdsqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); - tdsqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); - tdsqlite3_step(pStmt); + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC); + sqlite3_step(pStmt); - return tdsqlite3_finalize(pStmt); + return sqlite3_finalize(pStmt); } static int queryTokenizer( - tdsqlite3 *db, + sqlite3 *db, char *zName, - const tdsqlite3_tokenizer_module **pp + const sqlite3_tokenizer_module **pp ){ int rc; - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; const char zSql[] = "SELECT fts3_tokenizer(?)"; *pp = 0; - rc = tdsqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); if( rc!=SQLITE_OK ){ return rc; } - tdsqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - if( tdsqlite3_column_type(pStmt, 0)==SQLITE_BLOB - && tdsqlite3_column_bytes(pStmt, 0)==sizeof(*pp) + sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB + && sqlite3_column_bytes(pStmt, 0)==sizeof(*pp) ){ - memcpy((void *)pp, tdsqlite3_column_blob(pStmt, 0), sizeof(*pp)); + memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp)); } } - return tdsqlite3_finalize(pStmt); + return sqlite3_finalize(pStmt); } -SQLITE_PRIVATE void tdsqlite3Fts3SimpleTokenizerModule(tdsqlite3_tokenizer_module const**ppModule); +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule); /* ** Implementation of the scalar function fts3_tokenizer_internal_test(). @@ -177933,27 +177933,27 @@ SQLITE_PRIVATE void tdsqlite3Fts3SimpleTokenizerModule(tdsqlite3_tokenizer_modul ** */ static void intTestFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ int rc; - const tdsqlite3_tokenizer_module *p1; - const tdsqlite3_tokenizer_module *p2; - tdsqlite3 *db = (tdsqlite3 *)tdsqlite3_user_data(context); + const sqlite3_tokenizer_module *p1; + const sqlite3_tokenizer_module *p2; + sqlite3 *db = (sqlite3 *)sqlite3_user_data(context); UNUSED_PARAMETER(argc); UNUSED_PARAMETER(argv); /* Test the query function */ - tdsqlite3Fts3SimpleTokenizerModule(&p1); + sqlite3Fts3SimpleTokenizerModule(&p1); rc = queryTokenizer(db, "simple", &p2); assert( rc==SQLITE_OK ); assert( p1==p2 ); rc = queryTokenizer(db, "nosuchtokenizer", &p2); assert( rc==SQLITE_ERROR ); assert( p2==0 ); - assert( 0==strcmp(tdsqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); + assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") ); /* Test the storage function */ if( fts3TokenizerEnabled(context) ){ @@ -177964,7 +177964,7 @@ static void intTestFunc( assert( p2==p1 ); } - tdsqlite3_result_text(context, "ok", -1, SQLITE_STATIC); + sqlite3_result_text(context, "ok", -1, SQLITE_STATIC); } #endif @@ -177975,7 +177975,7 @@ static void intTestFunc( ** been initialized to use string keys, and to take a private copy ** of the key when a value is inserted. i.e. by a call similar to: ** -** tdsqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); +** sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1); ** ** This function adds a scalar function (see header comment above ** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is @@ -177986,8 +177986,8 @@ static void intTestFunc( ** The third argument to this function, zName, is used as the name ** of both the scalar and, if created, the virtual table. */ -SQLITE_PRIVATE int tdsqlite3Fts3InitHashTable( - tdsqlite3 *db, +SQLITE_PRIVATE int sqlite3Fts3InitHashTable( + sqlite3 *db, Fts3Hash *pHash, const char *zName ){ @@ -177999,31 +177999,31 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitHashTable( char *zTest = 0; char *zTest2 = 0; void *pdb = (void *)db; - zTest = tdsqlite3_mprintf("%s_test", zName); - zTest2 = tdsqlite3_mprintf("%s_internal_test", zName); + zTest = sqlite3_mprintf("%s_test", zName); + zTest2 = sqlite3_mprintf("%s_internal_test", zName); if( !zTest || !zTest2 ){ rc = SQLITE_NOMEM; } #endif if( SQLITE_OK==rc ){ - rc = tdsqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0); + rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0); } if( SQLITE_OK==rc ){ - rc = tdsqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0); + rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0); } #ifdef SQLITE_TEST if( SQLITE_OK==rc ){ - rc = tdsqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0); + rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0); } if( SQLITE_OK==rc ){ - rc = tdsqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0); + rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0); } #endif #ifdef SQLITE_TEST - tdsqlite3_free(zTest); - tdsqlite3_free(zTest2); + sqlite3_free(zTest); + sqlite3_free(zTest2); #endif return rc; @@ -178068,12 +178068,12 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitHashTable( /* #include "fts3_tokenizer.h" */ typedef struct simple_tokenizer { - tdsqlite3_tokenizer base; + sqlite3_tokenizer base; char delim[128]; /* flag ASCII delimiters */ } simple_tokenizer; typedef struct simple_tokenizer_cursor { - tdsqlite3_tokenizer_cursor base; + sqlite3_tokenizer_cursor base; const char *pInput; /* input we are tokenizing */ int nBytes; /* size of the input */ int iOffset; /* current position in pInput */ @@ -178095,11 +178095,11 @@ static int fts3_isalnum(int x){ */ static int simpleCreate( int argc, const char * const *argv, - tdsqlite3_tokenizer **ppTokenizer + sqlite3_tokenizer **ppTokenizer ){ simple_tokenizer *t; - t = (simple_tokenizer *) tdsqlite3_malloc(sizeof(*t)); + t = (simple_tokenizer *) sqlite3_malloc(sizeof(*t)); if( t==NULL ) return SQLITE_NOMEM; memset(t, 0, sizeof(*t)); @@ -178114,7 +178114,7 @@ static int simpleCreate( unsigned char ch = argv[1][i]; /* We explicitly don't support UTF-8 delimiters for now. */ if( ch>=0x80 ){ - tdsqlite3_free(t); + sqlite3_free(t); return SQLITE_ERROR; } t->delim[ch] = 1; @@ -178134,8 +178134,8 @@ static int simpleCreate( /* ** Destroy a tokenizer */ -static int simpleDestroy(tdsqlite3_tokenizer *pTokenizer){ - tdsqlite3_free(pTokenizer); +static int simpleDestroy(sqlite3_tokenizer *pTokenizer){ + sqlite3_free(pTokenizer); return SQLITE_OK; } @@ -178146,15 +178146,15 @@ static int simpleDestroy(tdsqlite3_tokenizer *pTokenizer){ ** *ppCursor. */ static int simpleOpen( - tdsqlite3_tokenizer *pTokenizer, /* The tokenizer */ + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ const char *pInput, int nBytes, /* String to be tokenized */ - tdsqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ ){ simple_tokenizer_cursor *c; UNUSED_PARAMETER(pTokenizer); - c = (simple_tokenizer_cursor *) tdsqlite3_malloc(sizeof(*c)); + c = (simple_tokenizer_cursor *) sqlite3_malloc(sizeof(*c)); if( c==NULL ) return SQLITE_NOMEM; c->pInput = pInput; @@ -178178,10 +178178,10 @@ static int simpleOpen( ** Close a tokenization cursor previously opened by a call to ** simpleOpen() above. */ -static int simpleClose(tdsqlite3_tokenizer_cursor *pCursor){ +static int simpleClose(sqlite3_tokenizer_cursor *pCursor){ simple_tokenizer_cursor *c = (simple_tokenizer_cursor *) pCursor; - tdsqlite3_free(c->pToken); - tdsqlite3_free(c); + sqlite3_free(c->pToken); + sqlite3_free(c); return SQLITE_OK; } @@ -178190,7 +178190,7 @@ static int simpleClose(tdsqlite3_tokenizer_cursor *pCursor){ ** have been opened by a prior call to simpleOpen(). */ static int simpleNext( - tdsqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ const char **ppToken, /* OUT: *ppToken is the token text */ int *pnBytes, /* OUT: Number of bytes in token */ int *piStartOffset, /* OUT: Starting offset of token */ @@ -178220,7 +178220,7 @@ static int simpleNext( if( n>c->nTokenAllocated ){ char *pNew; c->nTokenAllocated = n+20; - pNew = tdsqlite3_realloc(c->pToken, c->nTokenAllocated); + pNew = sqlite3_realloc(c->pToken, c->nTokenAllocated); if( !pNew ) return SQLITE_NOMEM; c->pToken = pNew; } @@ -178246,7 +178246,7 @@ static int simpleNext( /* ** The set of routines that implement the simple tokenizer */ -static const tdsqlite3_tokenizer_module simpleTokenizerModule = { +static const sqlite3_tokenizer_module simpleTokenizerModule = { 0, simpleCreate, simpleDestroy, @@ -178260,8 +178260,8 @@ static const tdsqlite3_tokenizer_module simpleTokenizerModule = { ** Allocate a new simple tokenizer. Return a pointer to the new ** tokenizer in *ppModule */ -SQLITE_PRIVATE void tdsqlite3Fts3SimpleTokenizerModule( - tdsqlite3_tokenizer_module const**ppModule +SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule( + sqlite3_tokenizer_module const**ppModule ){ *ppModule = &simpleTokenizerModule; } @@ -178323,18 +178323,18 @@ typedef struct Fts3tokCursor Fts3tokCursor; ** Virtual table structure. */ struct Fts3tokTable { - tdsqlite3_vtab base; /* Base class used by SQLite core */ - const tdsqlite3_tokenizer_module *pMod; - tdsqlite3_tokenizer *pTok; + sqlite3_vtab base; /* Base class used by SQLite core */ + const sqlite3_tokenizer_module *pMod; + sqlite3_tokenizer *pTok; }; /* ** Virtual table cursor structure. */ struct Fts3tokCursor { - tdsqlite3_vtab_cursor base; /* Base class used by SQLite core */ + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ char *zInput; /* Input string */ - tdsqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */ + sqlite3_tokenizer_cursor *pCsr; /* Cursor to iterate through zInput */ int iRowid; /* Current 'rowid' value */ const char *zToken; /* Current 'token' value */ int nToken; /* Size of zToken in bytes */ @@ -178349,15 +178349,15 @@ struct Fts3tokCursor { static int fts3tokQueryTokenizer( Fts3Hash *pHash, const char *zName, - const tdsqlite3_tokenizer_module **pp, + const sqlite3_tokenizer_module **pp, char **pzErr ){ - tdsqlite3_tokenizer_module *p; + sqlite3_tokenizer_module *p; int nName = (int)strlen(zName); - p = (tdsqlite3_tokenizer_module *)tdsqlite3Fts3HashFind(pHash, zName, nName+1); + p = (sqlite3_tokenizer_module *)sqlite3Fts3HashFind(pHash, zName, nName+1); if( !p ){ - tdsqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName); + sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", zName); return SQLITE_ERROR; } @@ -178373,7 +178373,7 @@ static int fts3tokQueryTokenizer( ** ** If successful, output parameter *pazDequote is set to point at the ** array of dequoted strings and SQLITE_OK is returned. The caller is -** responsible for eventually calling tdsqlite3_free() to free the array +** responsible for eventually calling sqlite3_free() to free the array ** in this case. Or, if an error occurs, an SQLite error code is returned. ** The final value of *pazDequote is undefined in this case. */ @@ -178394,7 +178394,7 @@ static int fts3tokDequoteArray( nByte += (int)(strlen(argv[i]) + 1); } - *pazDequote = azDequote = tdsqlite3_malloc64(sizeof(char *)*argc + nByte); + *pazDequote = azDequote = sqlite3_malloc64(sizeof(char *)*argc + nByte); if( azDequote==0 ){ rc = SQLITE_NOMEM; }else{ @@ -178403,7 +178403,7 @@ static int fts3tokDequoteArray( int n = (int)strlen(argv[i]); azDequote[i] = pSpace; memcpy(pSpace, argv[i], n+1); - tdsqlite3Fts3Dequote(pSpace); + sqlite3Fts3Dequote(pSpace); pSpace += (n+1); } } @@ -178428,21 +178428,21 @@ static int fts3tokDequoteArray( ** argv[3]: first argument (tokenizer name) */ static int fts3tokConnectMethod( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pHash, /* Hash table of tokenizers */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVtab, /* OUT: New tdsqlite3_vtab object */ - char **pzErr /* OUT: tdsqlite3_malloc'd error message */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ ){ Fts3tokTable *pTab = 0; - const tdsqlite3_tokenizer_module *pMod = 0; - tdsqlite3_tokenizer *pTok = 0; + const sqlite3_tokenizer_module *pMod = 0; + sqlite3_tokenizer *pTok = 0; int rc; char **azDequote = 0; int nDequote; - rc = tdsqlite3_declare_vtab(db, FTS3_TOK_SCHEMA); + rc = sqlite3_declare_vtab(db, FTS3_TOK_SCHEMA); if( rc!=SQLITE_OK ) return rc; nDequote = argc-3; @@ -178465,7 +178465,7 @@ static int fts3tokConnectMethod( } if( rc==SQLITE_OK ){ - pTab = (Fts3tokTable *)tdsqlite3_malloc(sizeof(Fts3tokTable)); + pTab = (Fts3tokTable *)sqlite3_malloc(sizeof(Fts3tokTable)); if( pTab==0 ){ rc = SQLITE_NOMEM; } @@ -178482,7 +178482,7 @@ static int fts3tokConnectMethod( } } - tdsqlite3_free(azDequote); + sqlite3_free(azDequote); return rc; } @@ -178491,11 +178491,11 @@ static int fts3tokConnectMethod( ** These tables have no persistent representation of their own, so xDisconnect ** and xDestroy are identical operations. */ -static int fts3tokDisconnectMethod(tdsqlite3_vtab *pVtab){ +static int fts3tokDisconnectMethod(sqlite3_vtab *pVtab){ Fts3tokTable *pTab = (Fts3tokTable *)pVtab; pTab->pMod->xDestroy(pTab->pTok); - tdsqlite3_free(pTab); + sqlite3_free(pTab); return SQLITE_OK; } @@ -178503,8 +178503,8 @@ static int fts3tokDisconnectMethod(tdsqlite3_vtab *pVtab){ ** xBestIndex - Analyze a WHERE and ORDER BY clause. */ static int fts3tokBestIndexMethod( - tdsqlite3_vtab *pVTab, - tdsqlite3_index_info *pInfo + sqlite3_vtab *pVTab, + sqlite3_index_info *pInfo ){ int i; UNUSED_PARAMETER(pVTab); @@ -178531,17 +178531,17 @@ static int fts3tokBestIndexMethod( /* ** xOpen - Open a cursor. */ -static int fts3tokOpenMethod(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCsr){ +static int fts3tokOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ Fts3tokCursor *pCsr; UNUSED_PARAMETER(pVTab); - pCsr = (Fts3tokCursor *)tdsqlite3_malloc(sizeof(Fts3tokCursor)); + pCsr = (Fts3tokCursor *)sqlite3_malloc(sizeof(Fts3tokCursor)); if( pCsr==0 ){ return SQLITE_NOMEM; } memset(pCsr, 0, sizeof(Fts3tokCursor)); - *ppCsr = (tdsqlite3_vtab_cursor *)pCsr; + *ppCsr = (sqlite3_vtab_cursor *)pCsr; return SQLITE_OK; } @@ -178555,7 +178555,7 @@ static void fts3tokResetCursor(Fts3tokCursor *pCsr){ pTab->pMod->xClose(pCsr->pCsr); pCsr->pCsr = 0; } - tdsqlite3_free(pCsr->zInput); + sqlite3_free(pCsr->zInput); pCsr->zInput = 0; pCsr->zToken = 0; pCsr->nToken = 0; @@ -178568,18 +178568,18 @@ static void fts3tokResetCursor(Fts3tokCursor *pCsr){ /* ** xClose - Close a cursor. */ -static int fts3tokCloseMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts3tokCloseMethod(sqlite3_vtab_cursor *pCursor){ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; fts3tokResetCursor(pCsr); - tdsqlite3_free(pCsr); + sqlite3_free(pCsr); return SQLITE_OK; } /* ** xNext - Advance the cursor to the next row, if any. */ -static int fts3tokNextMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts3tokNextMethod(sqlite3_vtab_cursor *pCursor){ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; Fts3tokTable *pTab = (Fts3tokTable *)(pCursor->pVtab); int rc; /* Return code */ @@ -178602,11 +178602,11 @@ static int fts3tokNextMethod(tdsqlite3_vtab_cursor *pCursor){ ** xFilter - Initialize a cursor to point at the start of its data. */ static int fts3tokFilterMethod( - tdsqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ int idxNum, /* Strategy index */ const char *idxStr, /* Unused */ int nVal, /* Number of elements in apVal */ - tdsqlite3_value **apVal /* Arguments for the indexing scheme */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ int rc = SQLITE_ERROR; Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; @@ -178616,9 +178616,9 @@ static int fts3tokFilterMethod( fts3tokResetCursor(pCsr); if( idxNum==1 ){ - const char *zByte = (const char *)tdsqlite3_value_text(apVal[0]); - int nByte = tdsqlite3_value_bytes(apVal[0]); - pCsr->zInput = tdsqlite3_malloc64(nByte+1); + const char *zByte = (const char *)sqlite3_value_text(apVal[0]); + int nByte = sqlite3_value_bytes(apVal[0]); + pCsr->zInput = sqlite3_malloc64(nByte+1); if( pCsr->zInput==0 ){ rc = SQLITE_NOMEM; }else{ @@ -178638,7 +178638,7 @@ static int fts3tokFilterMethod( /* ** xEof - Return true if the cursor is at EOF, or false otherwise. */ -static int fts3tokEofMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts3tokEofMethod(sqlite3_vtab_cursor *pCursor){ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; return (pCsr->zToken==0); } @@ -178647,8 +178647,8 @@ static int fts3tokEofMethod(tdsqlite3_vtab_cursor *pCursor){ ** xColumn - Return a column value. */ static int fts3tokColumnMethod( - tdsqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - tdsqlite3_context *pCtx, /* Context for tdsqlite3_result_xxx() calls */ + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ int iCol /* Index of column to read value from */ ){ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; @@ -178656,20 +178656,20 @@ static int fts3tokColumnMethod( /* CREATE TABLE x(input, token, start, end, position) */ switch( iCol ){ case 0: - tdsqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, pCsr->zInput, -1, SQLITE_TRANSIENT); break; case 1: - tdsqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, pCsr->zToken, pCsr->nToken, SQLITE_TRANSIENT); break; case 2: - tdsqlite3_result_int(pCtx, pCsr->iStart); + sqlite3_result_int(pCtx, pCsr->iStart); break; case 3: - tdsqlite3_result_int(pCtx, pCsr->iEnd); + sqlite3_result_int(pCtx, pCsr->iEnd); break; default: assert( iCol==4 ); - tdsqlite3_result_int(pCtx, pCsr->iPos); + sqlite3_result_int(pCtx, pCsr->iPos); break; } return SQLITE_OK; @@ -178679,20 +178679,20 @@ static int fts3tokColumnMethod( ** xRowid - Return the current rowid for the cursor. */ static int fts3tokRowidMethod( - tdsqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ sqlite_int64 *pRowid /* OUT: Rowid value */ ){ Fts3tokCursor *pCsr = (Fts3tokCursor *)pCursor; - *pRowid = (tdsqlite3_int64)pCsr->iRowid; + *pRowid = (sqlite3_int64)pCsr->iRowid; return SQLITE_OK; } /* ** Register the fts3tok module with database connection db. Return SQLITE_OK -** if successful or an error code if tdsqlite3_create_module() fails. +** if successful or an error code if sqlite3_create_module() fails. */ -SQLITE_PRIVATE int tdsqlite3Fts3InitTok(tdsqlite3 *db, Fts3Hash *pHash){ - static const tdsqlite3_module fts3tok_module = { +SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){ + static const sqlite3_module fts3tok_module = { 0, /* iVersion */ fts3tokConnectMethod, /* xCreate */ fts3tokConnectMethod, /* xConnect */ @@ -178720,7 +178720,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3InitTok(tdsqlite3 *db, Fts3Hash *pHash){ }; int rc; /* Return code */ - rc = tdsqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash); + rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash); return rc; } @@ -178805,14 +178805,14 @@ int test_fts3_node_chunk_threshold = (4*1024)*4; #define FTS_STAT_AUTOINCRMERGE 2 /* -** If FTS_LOG_MERGES is defined, call tdsqlite3_log() to report each automatic +** If FTS_LOG_MERGES is defined, call sqlite3_log() to report each automatic ** and incremental merge operation that takes place. This is used for ** debugging FTS only, it should not usually be turned on in production ** systems. */ #ifdef FTS3_LOG_MERGES -static void fts3LogMerge(int nMerge, tdsqlite3_int64 iAbsLevel){ - tdsqlite3_log(SQLITE_OK, "%d-way merge from level %d", nMerge, (int)iAbsLevel); +static void fts3LogMerge(int nMerge, sqlite3_int64 iAbsLevel){ + sqlite3_log(SQLITE_OK, "%d-way merge from level %d", nMerge, (int)iAbsLevel); } #else #define fts3LogMerge(x, y) @@ -178831,9 +178831,9 @@ struct PendingList { int nData; char *aData; int nSpace; - tdsqlite3_int64 iLastDocid; - tdsqlite3_int64 iLastCol; - tdsqlite3_int64 iLastPos; + sqlite3_int64 iLastDocid; + sqlite3_int64 iLastCol; + sqlite3_int64 iLastPos; }; @@ -178854,9 +178854,9 @@ struct Fts3DeferredToken { ** of type Fts3SegReader* are also used by code in fts3.c to iterate through ** terms when querying the full-text index. See functions: ** -** tdsqlite3Fts3SegReaderNew() -** tdsqlite3Fts3SegReaderFree() -** tdsqlite3Fts3SegReaderIterate() +** sqlite3Fts3SegReaderNew() +** sqlite3Fts3SegReaderFree() +** sqlite3Fts3SegReaderIterate() ** ** Methods used to manipulate Fts3SegReader structures: ** @@ -178869,15 +178869,15 @@ struct Fts3SegReader { u8 bLookup; /* True for a lookup only */ u8 rootOnly; /* True for a root-only reader */ - tdsqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */ - tdsqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */ - tdsqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */ - tdsqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */ + sqlite3_int64 iStartBlock; /* Rowid of first leaf block to traverse */ + sqlite3_int64 iLeafEndBlock; /* Rowid of final leaf block to traverse */ + sqlite3_int64 iEndBlock; /* Rowid of final block in segment (or 0) */ + sqlite3_int64 iCurrentBlock; /* Current leaf block (or 0) */ char *aNode; /* Pointer to node data (or NULL) */ int nNode; /* Size of buffer at aNode (or 0) */ int nPopulate; /* If >0, bytes of buffer aNode[] loaded */ - tdsqlite3_blob *pBlob; /* If not NULL, blob handle to read node */ + sqlite3_blob *pBlob; /* If not NULL, blob handle to read node */ Fts3HashElem **ppNextElem; @@ -178897,7 +178897,7 @@ struct Fts3SegReader { */ char *pOffsetList; int nOffsetList; /* For descending pending seg-readers only */ - tdsqlite3_int64 iDocid; + sqlite3_int64 iDocid; }; #define fts3SegReaderIsPending(p) ((p)->ppNextElem!=0) @@ -178914,8 +178914,8 @@ struct Fts3SegReader { */ struct SegmentWriter { SegmentNode *pTree; /* Pointer to interior tree structure */ - tdsqlite3_int64 iFirst; /* First slot in %_segments written */ - tdsqlite3_int64 iFree; /* Next free slot in %_segments */ + sqlite3_int64 iFirst; /* First slot in %_segments written */ + sqlite3_int64 iFree; /* Next free slot in %_segments */ char *zTerm; /* Pointer to previous term buffer */ int nTerm; /* Number of bytes in zTerm */ int nMalloc; /* Size of malloc'd buffer at zMalloc */ @@ -179017,8 +179017,8 @@ struct SegmentNode { static int fts3SqlStmt( Fts3Table *p, /* Virtual table handle */ int eStmt, /* One of the SQL_XXX constants above */ - tdsqlite3_stmt **pp, /* OUT: Statement handle */ - tdsqlite3_value **apVal /* Values to bind to statement */ + sqlite3_stmt **pp, /* OUT: Statement handle */ + sqlite3_value **apVal /* Values to bind to statement */ ){ const char *azSql[] = { /* 0 */ "DELETE FROM %Q.'%q_content' WHERE rowid = ?", @@ -179069,7 +179069,7 @@ static int fts3SqlStmt( /* Estimate the upper limit on the number of leaf nodes in a new segment ** created by merging the oldest :2 segments from absolute level :1. See -** function tdsqlite3Fts3Incrmerge() for details. */ +** function sqlite3Fts3Incrmerge() for details. */ /* 29 */ "SELECT 2 * total(1 + leaves_end_block - start_block) " " FROM %Q.'%q_segdir' WHERE level = ? AND idx < ?", @@ -179119,7 +179119,7 @@ static int fts3SqlStmt( }; int rc = SQLITE_OK; - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; assert( SizeofArray(azSql)==SizeofArray(p->aStmt) ); assert( eStmt=0 ); @@ -179129,27 +179129,27 @@ static int fts3SqlStmt( int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB; char *zSql; if( eStmt==SQL_CONTENT_INSERT ){ - zSql = tdsqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist); }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){ f &= ~SQLITE_PREPARE_NO_VTAB; - zSql = tdsqlite3_mprintf(azSql[eStmt], p->zReadExprlist); + zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist); }else{ - zSql = tdsqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); + zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName); } if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL); - tdsqlite3_free(zSql); + rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL); + sqlite3_free(zSql); assert( rc==SQLITE_OK || pStmt==0 ); p->aStmt[eStmt] = pStmt; } } if( apVal ){ int i; - int nParam = tdsqlite3_bind_parameter_count(pStmt); + int nParam = sqlite3_bind_parameter_count(pStmt); for(i=0; rc==SQLITE_OK && inPendingData==0 ){ - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pStmt, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_null(pStmt, 1); - tdsqlite3_step(pStmt); - rc = tdsqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 1); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); } } @@ -179290,18 +179290,18 @@ static int fts3Writelock(Fts3Table *p){ ** absolute levels that corresponds to language-id iLangid and index ** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024). */ -static tdsqlite3_int64 getAbsoluteLevel( +static sqlite3_int64 getAbsoluteLevel( Fts3Table *p, /* FTS3 table handle */ int iLangid, /* Language id */ int iIndex, /* Index in p->aIndex[] */ int iLevel /* Level of segments */ ){ - tdsqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ + sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */ assert_fts3_nc( iLangid>=0 ); assert( p->nIndex>0 ); assert( iIndex>=0 && iIndexnIndex ); - iBase = ((tdsqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL; + iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL; return iBase + iLevel; } @@ -179322,15 +179322,15 @@ static tdsqlite3_int64 getAbsoluteLevel( ** 3: end_block ** 4: root */ -SQLITE_PRIVATE int tdsqlite3Fts3AllSegdirs( +SQLITE_PRIVATE int sqlite3Fts3AllSegdirs( Fts3Table *p, /* FTS3 table */ int iLangid, /* Language being queried */ int iIndex, /* Index for p->aIndex[] */ int iLevel, /* Level to select (relative level) */ - tdsqlite3_stmt **ppStmt /* OUT: Compiled statement */ + sqlite3_stmt **ppStmt /* OUT: Compiled statement */ ){ int rc; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; assert( iLevel==FTS3_SEGCURSOR_ALL || iLevel>=0 ); assert( iLevelnData+FTS3_VARINT_MAX+1>p->nSpace ){ int nNew = p->nSpace * 2; - p = tdsqlite3_realloc(p, sizeof(*p) + nNew); + p = sqlite3_realloc(p, sizeof(*p) + nNew); if( !p ){ - tdsqlite3_free(*pp); + sqlite3_free(*pp); *pp = 0; return SQLITE_NOMEM; } @@ -179398,7 +179398,7 @@ static int fts3PendingListAppendVarint( } /* Append the new serialized varint to the end of the list. */ - p->nData += tdsqlite3Fts3PutVarint(&p->aData[p->nData], i); + p->nData += sqlite3Fts3PutVarint(&p->aData[p->nData], i); p->aData[p->nData] = '\0'; *pp = p; return SQLITE_OK; @@ -179406,7 +179406,7 @@ static int fts3PendingListAppendVarint( /* ** Add a docid/column/position entry to a PendingList structure. Non-zero -** is returned if the structure is tdsqlite3_realloced as part of adding +** is returned if the structure is sqlite3_realloced as part of adding ** the entry. Otherwise, zero. ** ** If an OOM error occurs, *pRc is set to SQLITE_NOMEM before returning. @@ -179415,9 +179415,9 @@ static int fts3PendingListAppendVarint( */ static int fts3PendingListAppend( PendingList **pp, /* IN/OUT: PendingList structure */ - tdsqlite3_int64 iDocid, /* Docid for entry to add */ - tdsqlite3_int64 iCol, /* Column for entry to add */ - tdsqlite3_int64 iPos, /* Position of term for entry to add */ + sqlite3_int64 iDocid, /* Docid for entry to add */ + sqlite3_int64 iCol, /* Column for entry to add */ + sqlite3_int64 iPos, /* Position of term for entry to add */ int *pRc /* OUT: Return code */ ){ PendingList *p = *pp; @@ -179469,7 +179469,7 @@ static int fts3PendingListAppend( ** Free a PendingList object allocated by fts3PendingListAppend(). */ static void fts3PendingListDelete(PendingList *pList){ - tdsqlite3_free(pList); + sqlite3_free(pList); } /* @@ -179496,7 +179496,7 @@ static int fts3PendingTermsAddOne( ** happen if there was no previous entry for this token. */ assert( 0==fts3HashFind(pHash, zToken, nToken) ); - tdsqlite3_free(pList); + sqlite3_free(pList); rc = SQLITE_NOMEM; } } @@ -179529,10 +179529,10 @@ static int fts3PendingTermsAdd( char const *zToken; int nToken = 0; - tdsqlite3_tokenizer *pTokenizer = p->pTokenizer; - tdsqlite3_tokenizer_module const *pModule = pTokenizer->pModule; - tdsqlite3_tokenizer_cursor *pCsr; - int (*xNext)(tdsqlite3_tokenizer_cursor *pCursor, + sqlite3_tokenizer *pTokenizer = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pTokenizer->pModule; + sqlite3_tokenizer_cursor *pCsr; + int (*xNext)(sqlite3_tokenizer_cursor *pCursor, const char**,int*,int*,int*,int*); assert( pTokenizer && pModule ); @@ -179545,7 +179545,7 @@ static int fts3PendingTermsAdd( return SQLITE_OK; } - rc = tdsqlite3Fts3OpenTokenizer(pTokenizer, iLangid, zText, -1, &pCsr); + rc = sqlite3Fts3OpenTokenizer(pTokenizer, iLangid, zText, -1, &pCsr); if( rc!=SQLITE_OK ){ return rc; } @@ -179611,7 +179611,7 @@ static int fts3PendingTermsDocid( || p->iPrevLangid!=iLangid || p->nPendingData>p->nMaxPendingData ){ - int rc = tdsqlite3Fts3PendingTermsFlush(p); + int rc = sqlite3Fts3PendingTermsFlush(p); if( rc!=SQLITE_OK ) return rc; } p->iPrevDocid = iDocid; @@ -179623,7 +179623,7 @@ static int fts3PendingTermsDocid( /* ** Discard the contents of the pending-terms hash tables. */ -SQLITE_PRIVATE void tdsqlite3Fts3PendingTermsClear(Fts3Table *p){ +SQLITE_PRIVATE void sqlite3Fts3PendingTermsClear(Fts3Table *p){ int i; for(i=0; inIndex; i++){ Fts3HashElem *pElem; @@ -179648,19 +179648,19 @@ SQLITE_PRIVATE void tdsqlite3Fts3PendingTermsClear(Fts3Table *p){ static int fts3InsertTerms( Fts3Table *p, int iLangid, - tdsqlite3_value **apVal, + sqlite3_value **apVal, u32 *aSz ){ int i; /* Iterator variable */ for(i=2; inColumn+2; i++){ int iCol = i-2; if( p->abNotindexed[iCol]==0 ){ - const char *zText = (const char *)tdsqlite3_value_text(apVal[i]); + const char *zText = (const char *)sqlite3_value_text(apVal[i]); int rc = fts3PendingTermsAdd(p, iLangid, zText, iCol, &aSz[iCol]); if( rc!=SQLITE_OK ){ return rc; } - aSz[p->nColumn] += tdsqlite3_value_bytes(apVal[i]); + aSz[p->nColumn] += sqlite3_value_bytes(apVal[i]); } } return SQLITE_OK; @@ -179682,21 +179682,21 @@ static int fts3InsertTerms( */ static int fts3InsertData( Fts3Table *p, /* Full-text table */ - tdsqlite3_value **apVal, /* Array of values to insert */ - tdsqlite3_int64 *piDocid /* OUT: Docid for row just inserted */ + sqlite3_value **apVal, /* Array of values to insert */ + sqlite3_int64 *piDocid /* OUT: Docid for row just inserted */ ){ int rc; /* Return code */ - tdsqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */ + sqlite3_stmt *pContentInsert; /* INSERT INTO %_content VALUES(...) */ if( p->zContentTbl ){ - tdsqlite3_value *pRowid = apVal[p->nColumn+3]; - if( tdsqlite3_value_type(pRowid)==SQLITE_NULL ){ + sqlite3_value *pRowid = apVal[p->nColumn+3]; + if( sqlite3_value_type(pRowid)==SQLITE_NULL ){ pRowid = apVal[1]; } - if( tdsqlite3_value_type(pRowid)!=SQLITE_INTEGER ){ + if( sqlite3_value_type(pRowid)!=SQLITE_INTEGER ){ return SQLITE_CONSTRAINT; } - *piDocid = tdsqlite3_value_int64(pRowid); + *piDocid = sqlite3_value_int64(pRowid); return SQLITE_OK; } @@ -179710,9 +179710,9 @@ static int fts3InsertData( */ rc = fts3SqlStmt(p, SQL_CONTENT_INSERT, &pContentInsert, &apVal[1]); if( rc==SQLITE_OK && p->zLanguageid ){ - rc = tdsqlite3_bind_int( + rc = sqlite3_bind_int( pContentInsert, p->nColumn+2, - tdsqlite3_value_int(apVal[p->nColumn+4]) + sqlite3_value_int(apVal[p->nColumn+4]) ); } if( rc!=SQLITE_OK ) return rc; @@ -179727,24 +179727,24 @@ static int fts3InsertData( ** In FTS3, this is an error. It is an error to specify non-NULL values ** for both docid and some other rowid alias. */ - if( SQLITE_NULL!=tdsqlite3_value_type(apVal[3+p->nColumn]) ){ - if( SQLITE_NULL==tdsqlite3_value_type(apVal[0]) - && SQLITE_NULL!=tdsqlite3_value_type(apVal[1]) + if( SQLITE_NULL!=sqlite3_value_type(apVal[3+p->nColumn]) ){ + if( SQLITE_NULL==sqlite3_value_type(apVal[0]) + && SQLITE_NULL!=sqlite3_value_type(apVal[1]) ){ /* A rowid/docid conflict. */ return SQLITE_ERROR; } - rc = tdsqlite3_bind_value(pContentInsert, 1, apVal[3+p->nColumn]); + rc = sqlite3_bind_value(pContentInsert, 1, apVal[3+p->nColumn]); if( rc!=SQLITE_OK ) return rc; } /* Execute the statement to insert the record. Set *piDocid to the ** new docid value. */ - tdsqlite3_step(pContentInsert); - rc = tdsqlite3_reset(pContentInsert); + sqlite3_step(pContentInsert); + rc = sqlite3_reset(pContentInsert); - *piDocid = tdsqlite3_last_insert_rowid(p->db); + *piDocid = sqlite3_last_insert_rowid(p->db); return rc; } @@ -179758,7 +179758,7 @@ static int fts3DeleteAll(Fts3Table *p, int bContent){ int rc = SQLITE_OK; /* Return code */ /* Discard the contents of the pending-terms hash table. */ - tdsqlite3Fts3PendingTermsClear(p); + sqlite3Fts3PendingTermsClear(p); /* Delete everything from the shadow tables. Except, leave %_content as ** is if bContent is false. */ @@ -179778,9 +179778,9 @@ static int fts3DeleteAll(Fts3Table *p, int bContent){ /* ** */ -static int langidFromSelect(Fts3Table *p, tdsqlite3_stmt *pSelect){ +static int langidFromSelect(Fts3Table *p, sqlite3_stmt *pSelect){ int iLangid = 0; - if( p->zLanguageid ) iLangid = tdsqlite3_column_int(pSelect, p->nColumn+1); + if( p->zLanguageid ) iLangid = sqlite3_column_int(pSelect, p->nColumn+1); return iLangid; } @@ -179792,40 +179792,40 @@ static int langidFromSelect(Fts3Table *p, tdsqlite3_stmt *pSelect){ static void fts3DeleteTerms( int *pRC, /* Result code */ Fts3Table *p, /* The FTS table to delete from */ - tdsqlite3_value *pRowid, /* The docid to be deleted */ + sqlite3_value *pRowid, /* The docid to be deleted */ u32 *aSz, /* Sizes of deleted document written here */ int *pbFound /* OUT: Set to true if row really does exist */ ){ int rc; - tdsqlite3_stmt *pSelect; + sqlite3_stmt *pSelect; assert( *pbFound==0 ); if( *pRC ) return; rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid); if( rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pSelect) ){ + if( SQLITE_ROW==sqlite3_step(pSelect) ){ int i; int iLangid = langidFromSelect(p, pSelect); - i64 iDocid = tdsqlite3_column_int64(pSelect, 0); + i64 iDocid = sqlite3_column_int64(pSelect, 0); rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid); for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){ int iCol = i-1; if( p->abNotindexed[iCol]==0 ){ - const char *zText = (const char *)tdsqlite3_column_text(pSelect, i); + const char *zText = (const char *)sqlite3_column_text(pSelect, i); rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]); - aSz[p->nColumn] += tdsqlite3_column_bytes(pSelect, i); + aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i); } } if( rc!=SQLITE_OK ){ - tdsqlite3_reset(pSelect); + sqlite3_reset(pSelect); *pRC = rc; return; } *pbFound = 1; } - rc = tdsqlite3_reset(pSelect); + rc = sqlite3_reset(pSelect); }else{ - tdsqlite3_reset(pSelect); + sqlite3_reset(pSelect); } *pRC = rc; } @@ -179859,7 +179859,7 @@ static int fts3AllocateSegdirIdx( int *piIdx ){ int rc; /* Return Code */ - tdsqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */ + sqlite3_stmt *pNextIdx; /* Query for next idx at level iLevel */ int iNext = 0; /* Result of query pNextIdx */ assert( iLangid>=0 ); @@ -179868,13 +179868,13 @@ static int fts3AllocateSegdirIdx( /* Set variable iNext to the next available segdir index at level iLevel. */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pNextIdx, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64( + sqlite3_bind_int64( pNextIdx, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel) ); - if( SQLITE_ROW==tdsqlite3_step(pNextIdx) ){ - iNext = tdsqlite3_column_int(pNextIdx, 0); + if( SQLITE_ROW==sqlite3_step(pNextIdx) ){ + iNext = sqlite3_column_int(pNextIdx, 0); } - rc = tdsqlite3_reset(pNextIdx); + rc = sqlite3_reset(pNextIdx); } if( rc==SQLITE_OK ){ @@ -179902,7 +179902,7 @@ static int fts3AllocateSegdirIdx( ** ** This function reads data from a single row of the %_segments table. The ** specific row is identified by the iBlockid parameter. If paBlob is not -** NULL, then a buffer is allocated using tdsqlite3_malloc() and populated +** NULL, then a buffer is allocated using sqlite3_malloc() and populated ** with the contents of the blob stored in the "block" column of the ** identified table row is. Whether or not paBlob is NULL, *pnBlob is set ** to the size of the blob in bytes before returning. @@ -179912,19 +179912,19 @@ static int fts3AllocateSegdirIdx( ** paBlob is non-NULL, then it is the responsibility of the caller to ** eventually free the returned buffer. ** -** This function may leave an open tdsqlite3_blob* handle in the +** This function may leave an open sqlite3_blob* handle in the ** Fts3Table.pSegments variable. This handle is reused by subsequent calls ** to this function. The handle may be closed by calling the -** tdsqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy +** sqlite3Fts3SegmentsClose() function. Reusing a blob handle is a handy ** performance improvement, but the blob handle should always be closed ** before control is returned to the user (to prevent a lock being held ** on the database file for longer than necessary). Thus, any virtual table ** method (xFilter etc.) that may directly or indirectly call this function -** must call tdsqlite3Fts3SegmentsClose() before returning. +** must call sqlite3Fts3SegmentsClose() before returning. */ -SQLITE_PRIVATE int tdsqlite3Fts3ReadBlock( +SQLITE_PRIVATE int sqlite3Fts3ReadBlock( Fts3Table *p, /* FTS3 table handle */ - tdsqlite3_int64 iBlockid, /* Access the row with blockid=$iBlockid */ + sqlite3_int64 iBlockid, /* Access the row with blockid=$iBlockid */ char **paBlob, /* OUT: Blob data in malloc'd buffer */ int *pnBlob, /* OUT: Size of blob data */ int *pnLoad /* OUT: Bytes actually loaded */ @@ -179935,22 +179935,22 @@ SQLITE_PRIVATE int tdsqlite3Fts3ReadBlock( assert( pnBlob ); if( p->pSegments ){ - rc = tdsqlite3_blob_reopen(p->pSegments, iBlockid); + rc = sqlite3_blob_reopen(p->pSegments, iBlockid); }else{ if( 0==p->zSegmentsTbl ){ - p->zSegmentsTbl = tdsqlite3_mprintf("%s_segments", p->zName); + p->zSegmentsTbl = sqlite3_mprintf("%s_segments", p->zName); if( 0==p->zSegmentsTbl ) return SQLITE_NOMEM; } - rc = tdsqlite3_blob_open( + rc = sqlite3_blob_open( p->db, p->zDb, p->zSegmentsTbl, "block", iBlockid, 0, &p->pSegments ); } if( rc==SQLITE_OK ){ - int nByte = tdsqlite3_blob_bytes(p->pSegments); + int nByte = sqlite3_blob_bytes(p->pSegments); *pnBlob = nByte; if( paBlob ){ - char *aByte = tdsqlite3_malloc(nByte + FTS3_NODE_PADDING); + char *aByte = sqlite3_malloc(nByte + FTS3_NODE_PADDING); if( !aByte ){ rc = SQLITE_NOMEM; }else{ @@ -179958,10 +179958,10 @@ SQLITE_PRIVATE int tdsqlite3Fts3ReadBlock( nByte = FTS3_NODE_CHUNKSIZE; *pnLoad = nByte; } - rc = tdsqlite3_blob_read(p->pSegments, aByte, nByte, 0); + rc = sqlite3_blob_read(p->pSegments, aByte, nByte, 0); memset(&aByte[nByte], 0, FTS3_NODE_PADDING); if( rc!=SQLITE_OK ){ - tdsqlite3_free(aByte); + sqlite3_free(aByte); aByte = 0; } } @@ -179976,10 +179976,10 @@ SQLITE_PRIVATE int tdsqlite3Fts3ReadBlock( /* ** Close the blob handle at p->pSegments, if it is open. See comments above -** the tdsqlite3Fts3ReadBlock() function for details. +** the sqlite3Fts3ReadBlock() function for details. */ -SQLITE_PRIVATE void tdsqlite3Fts3SegmentsClose(Fts3Table *p){ - tdsqlite3_blob_close(p->pSegments); +SQLITE_PRIVATE void sqlite3Fts3SegmentsClose(Fts3Table *p){ + sqlite3_blob_close(p->pSegments); p->pSegments = 0; } @@ -179988,7 +179988,7 @@ static int fts3SegReaderIncrRead(Fts3SegReader *pReader){ int rc; /* Return code */ nRead = MIN(pReader->nNode - pReader->nPopulate, FTS3_NODE_CHUNKSIZE); - rc = tdsqlite3_blob_read( + rc = sqlite3_blob_read( pReader->pBlob, &pReader->aNode[pReader->nPopulate], nRead, @@ -179999,7 +179999,7 @@ static int fts3SegReaderIncrRead(Fts3SegReader *pReader){ pReader->nPopulate += nRead; memset(&pReader->aNode[pReader->nPopulate], 0, FTS3_NODE_PADDING); if( pReader->nPopulate==pReader->nNode ){ - tdsqlite3_blob_close(pReader->pBlob); + sqlite3_blob_close(pReader->pBlob); pReader->pBlob = 0; pReader->nPopulate = 0; } @@ -180025,8 +180025,8 @@ static int fts3SegReaderRequire(Fts3SegReader *pReader, char *pFrom, int nByte){ */ static void fts3SegReaderSetEof(Fts3SegReader *pSeg){ if( !fts3SegReaderIsRootOnly(pSeg) ){ - tdsqlite3_free(pSeg->aNode); - tdsqlite3_blob_close(pSeg->pBlob); + sqlite3_free(pSeg->aNode); + sqlite3_blob_close(pSeg->pBlob); pSeg->pBlob = 0; } pSeg->aNode = 0; @@ -180057,7 +180057,7 @@ static int fts3SegReaderNext( if( fts3SegReaderIsPending(pReader) ){ Fts3HashElem *pElem = *(pReader->ppNextElem); - tdsqlite3_free(pReader->aNode); + sqlite3_free(pReader->aNode); pReader->aNode = 0; if( pElem ){ char *aCopy; @@ -180065,7 +180065,7 @@ static int fts3SegReaderNext( int nCopy = pList->nData+1; pReader->zTerm = (char *)fts3HashKey(pElem); pReader->nTerm = fts3HashKeysize(pElem); - aCopy = (char*)tdsqlite3_malloc(nCopy); + aCopy = (char*)sqlite3_malloc(nCopy); if( !aCopy ) return SQLITE_NOMEM; memcpy(aCopy, pList->aData, nCopy); pReader->nNode = pReader->nDoclist = nCopy; @@ -180087,7 +180087,7 @@ static int fts3SegReaderNext( return SQLITE_OK; } - rc = tdsqlite3Fts3ReadBlock( + rc = sqlite3Fts3ReadBlock( p, ++pReader->iCurrentBlock, &pReader->aNode, &pReader->nNode, (bIncr ? &pReader->nPopulate : 0) ); @@ -180121,7 +180121,7 @@ static int fts3SegReaderNext( ** overflow - hence the (i64) casts. */ if( (i64)nPrefix+nSuffix>(i64)pReader->nTermAlloc ){ i64 nNew = ((i64)nPrefix+nSuffix)*2; - char *zNew = tdsqlite3_realloc64(pReader->zTerm, nNew); + char *zNew = sqlite3_realloc64(pReader->zTerm, nNew); if( !zNew ){ return SQLITE_NOMEM; } @@ -180163,14 +180163,14 @@ static int fts3SegReaderFirstDocid(Fts3Table *pTab, Fts3SegReader *pReader){ u8 bEof = 0; pReader->iDocid = 0; pReader->nOffsetList = 0; - tdsqlite3Fts3DoclistPrev(0, + sqlite3Fts3DoclistPrev(0, pReader->aDoclist, pReader->nDoclist, &pReader->pOffsetList, &pReader->iDocid, &pReader->nOffsetList, &bEof ); }else{ rc = fts3SegReaderRequire(pReader, pReader->aDoclist, FTS3_VARINT_MAX); if( rc==SQLITE_OK ){ - int n = tdsqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid); + int n = sqlite3Fts3GetVarint(pReader->aDoclist, &pReader->iDocid); pReader->pOffsetList = &pReader->aDoclist[n]; } } @@ -180208,7 +180208,7 @@ static int fts3SegReaderNextDocid( *ppOffsetList = pReader->pOffsetList; *pnOffsetList = pReader->nOffsetList - 1; } - tdsqlite3Fts3DoclistPrev(0, + sqlite3Fts3DoclistPrev(0, pReader->aDoclist, pReader->nDoclist, &p, &pReader->iDocid, &pReader->nOffsetList, &bEof ); @@ -180262,7 +180262,7 @@ static int fts3SegReaderNextDocid( rc = fts3SegReaderRequire(pReader, p, FTS3_VARINT_MAX); if( rc==SQLITE_OK ){ u64 iDelta; - pReader->pOffsetList = p + tdsqlite3Fts3GetVarintU(p, &iDelta); + pReader->pOffsetList = p + sqlite3Fts3GetVarintU(p, &iDelta); if( pTab->bDescIdx ){ pReader->iDocid = (i64)((u64)pReader->iDocid - iDelta); }else{ @@ -180276,7 +180276,7 @@ static int fts3SegReaderNextDocid( } -SQLITE_PRIVATE int tdsqlite3Fts3MsrOvfl( +SQLITE_PRIVATE int sqlite3Fts3MsrOvfl( Fts3Cursor *pCsr, Fts3MultiSegReader *pMsr, int *pnOvfl @@ -180295,10 +180295,10 @@ SQLITE_PRIVATE int tdsqlite3Fts3MsrOvfl( if( !fts3SegReaderIsPending(pReader) && !fts3SegReaderIsRootOnly(pReader) ){ - tdsqlite3_int64 jj; + sqlite3_int64 jj; for(jj=pReader->iStartBlock; jj<=pReader->iLeafEndBlock; jj++){ int nBlob; - rc = tdsqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); + rc = sqlite3Fts3ReadBlock(p, jj, 0, &nBlob, 0); if( rc!=SQLITE_OK ) break; if( (nBlob+35)>pgsz ){ nOvfl += (nBlob + 34)/pgsz; @@ -180314,28 +180314,28 @@ SQLITE_PRIVATE int tdsqlite3Fts3MsrOvfl( ** Free all allocations associated with the iterator passed as the ** second argument. */ -SQLITE_PRIVATE void tdsqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ +SQLITE_PRIVATE void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){ if( pReader ){ if( !fts3SegReaderIsPending(pReader) ){ - tdsqlite3_free(pReader->zTerm); + sqlite3_free(pReader->zTerm); } if( !fts3SegReaderIsRootOnly(pReader) ){ - tdsqlite3_free(pReader->aNode); + sqlite3_free(pReader->aNode); } - tdsqlite3_blob_close(pReader->pBlob); + sqlite3_blob_close(pReader->pBlob); } - tdsqlite3_free(pReader); + sqlite3_free(pReader); } /* ** Allocate a new SegReader object. */ -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderNew( +SQLITE_PRIVATE int sqlite3Fts3SegReaderNew( int iAge, /* Segment "age". */ int bLookup, /* True for a lookup only */ - tdsqlite3_int64 iStartLeaf, /* First leaf to traverse */ - tdsqlite3_int64 iEndLeaf, /* Final leaf to traverse */ - tdsqlite3_int64 iEndBlock, /* Final block of segment */ + sqlite3_int64 iStartLeaf, /* First leaf to traverse */ + sqlite3_int64 iEndLeaf, /* Final leaf to traverse */ + sqlite3_int64 iEndBlock, /* Final block of segment */ const char *zRoot, /* Buffer containing root node */ int nRoot, /* Size of buffer containing root node */ Fts3SegReader **ppReader /* OUT: Allocated Fts3SegReader */ @@ -180353,7 +180353,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderNew( nExtra = nRoot + FTS3_NODE_PADDING; } - pReader = (Fts3SegReader *)tdsqlite3_malloc(sizeof(Fts3SegReader) + nExtra); + pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra); if( !pReader ){ return SQLITE_NOMEM; } @@ -180419,7 +180419,7 @@ static int SQLITE_CDECL fts3CompareElemByTerm( ** ** firebird mysql sqlite */ -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderPending( +SQLITE_PRIVATE int sqlite3Fts3SegReaderPending( Fts3Table *p, /* Virtual table handle */ int iIndex, /* Index for p->aIndex */ const char *zTerm, /* Term to search for */ @@ -180445,7 +180445,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderPending( if( nElem==nAlloc ){ Fts3HashElem **aElem2; nAlloc += 16; - aElem2 = (Fts3HashElem **)tdsqlite3_realloc( + aElem2 = (Fts3HashElem **)sqlite3_realloc( aElem, nAlloc*sizeof(Fts3HashElem *) ); if( !aElem2 ){ @@ -180484,9 +180484,9 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderPending( } if( nElem>0 ){ - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *); - pReader = (Fts3SegReader *)tdsqlite3_malloc64(nByte); + pReader = (Fts3SegReader *)sqlite3_malloc64(nByte); if( !pReader ){ rc = SQLITE_NOMEM; }else{ @@ -180498,7 +180498,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderPending( } if( bPrefix ){ - tdsqlite3_free(aElem); + sqlite3_free(aElem); } *ppReader = pReader; return rc; @@ -180642,18 +180642,18 @@ static void fts3SegReaderSort( */ static int fts3WriteSegment( Fts3Table *p, /* Virtual table handle */ - tdsqlite3_int64 iBlock, /* Block id for new block */ + sqlite3_int64 iBlock, /* Block id for new block */ char *z, /* Pointer to buffer containing block data */ int n /* Size of buffer z in bytes */ ){ - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pStmt, 1, iBlock); - tdsqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); - tdsqlite3_step(pStmt); - rc = tdsqlite3_reset(pStmt); - tdsqlite3_bind_null(pStmt, 2); + sqlite3_bind_int64(pStmt, 1, iBlock); + sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); } return rc; } @@ -180663,17 +180663,17 @@ static int fts3WriteSegment( ** *pnMax to this value and return SQLITE_OK. Otherwise, if an error occurs, ** set *pnMax to zero and return an SQLite error code. */ -SQLITE_PRIVATE int tdsqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){ +SQLITE_PRIVATE int sqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){ int rc; int mxLevel = 0; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; rc = fts3SqlStmt(p, SQL_SELECT_MXLEVEL, &pStmt, 0); if( rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - mxLevel = tdsqlite3_column_int(pStmt, 0); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + mxLevel = sqlite3_column_int(pStmt, 0); } - rc = tdsqlite3_reset(pStmt); + rc = sqlite3_reset(pStmt); } *pnMax = mxLevel; return rc; @@ -180684,33 +180684,33 @@ SQLITE_PRIVATE int tdsqlite3Fts3MaxLevel(Fts3Table *p, int *pnMax){ */ static int fts3WriteSegdir( Fts3Table *p, /* Virtual table handle */ - tdsqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ + sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */ int iIdx, /* Value for "idx" field */ - tdsqlite3_int64 iStartBlock, /* Value for "start_block" field */ - tdsqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ - tdsqlite3_int64 iEndBlock, /* Value for "end_block" field */ - tdsqlite3_int64 nLeafData, /* Bytes of leaf data in segment */ + sqlite3_int64 iStartBlock, /* Value for "start_block" field */ + sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */ + sqlite3_int64 iEndBlock, /* Value for "end_block" field */ + sqlite3_int64 nLeafData, /* Bytes of leaf data in segment */ char *zRoot, /* Blob value for "root" field */ int nRoot /* Number of bytes in buffer zRoot */ ){ - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pStmt, 1, iLevel); - tdsqlite3_bind_int(pStmt, 2, iIdx); - tdsqlite3_bind_int64(pStmt, 3, iStartBlock); - tdsqlite3_bind_int64(pStmt, 4, iLeafEndBlock); + sqlite3_bind_int64(pStmt, 1, iLevel); + sqlite3_bind_int(pStmt, 2, iIdx); + sqlite3_bind_int64(pStmt, 3, iStartBlock); + sqlite3_bind_int64(pStmt, 4, iLeafEndBlock); if( nLeafData==0 ){ - tdsqlite3_bind_int64(pStmt, 5, iEndBlock); + sqlite3_bind_int64(pStmt, 5, iEndBlock); }else{ - char *zEnd = tdsqlite3_mprintf("%lld %lld", iEndBlock, nLeafData); + char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData); if( !zEnd ) return SQLITE_NOMEM; - tdsqlite3_bind_text(pStmt, 5, zEnd, -1, tdsqlite3_free); + sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free); } - tdsqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); - tdsqlite3_step(pStmt); - rc = tdsqlite3_reset(pStmt); - tdsqlite3_bind_null(pStmt, 6); + sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 6); } return rc; } @@ -180767,7 +180767,7 @@ static int fts3NodeAddTerm( ** compared with BINARY collation. This indicates corruption. */ if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; - nReq += tdsqlite3Fts3VarintLen(nPrefix)+tdsqlite3Fts3VarintLen(nSuffix)+nSuffix; + nReq += sqlite3Fts3VarintLen(nPrefix)+sqlite3Fts3VarintLen(nSuffix)+nSuffix; if( nReq<=p->nNodeSize || !pTree->zTerm ){ if( nReq>p->nNodeSize ){ @@ -180779,7 +180779,7 @@ static int fts3NodeAddTerm( ** this is not expected to be a serious problem. */ assert( pTree->aData==(char *)&pTree[1] ); - pTree->aData = (char *)tdsqlite3_malloc(nReq); + pTree->aData = (char *)sqlite3_malloc(nReq); if( !pTree->aData ){ return SQLITE_NOMEM; } @@ -180787,17 +180787,17 @@ static int fts3NodeAddTerm( if( pTree->zTerm ){ /* There is no prefix-length field for first term in a node */ - nData += tdsqlite3Fts3PutVarint(&pTree->aData[nData], nPrefix); + nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nPrefix); } - nData += tdsqlite3Fts3PutVarint(&pTree->aData[nData], nSuffix); + nData += sqlite3Fts3PutVarint(&pTree->aData[nData], nSuffix); memcpy(&pTree->aData[nData], &zTerm[nPrefix], nSuffix); pTree->nData = nData + nSuffix; pTree->nEntry++; if( isCopyTerm ){ if( pTree->nMalloczMalloc, nTerm*2); + char *zNew = sqlite3_realloc(pTree->zMalloc, nTerm*2); if( !zNew ){ return SQLITE_NOMEM; } @@ -180823,7 +180823,7 @@ static int fts3NodeAddTerm( ** now. Instead, the term is inserted into the parent of pTree. If pTree ** has no parent, one is created here. */ - pNew = (SegmentNode *)tdsqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize); + pNew = (SegmentNode *)sqlite3_malloc(sizeof(SegmentNode) + p->nNodeSize); if( !pNew ){ return SQLITE_NOMEM; } @@ -180858,13 +180858,13 @@ static int fts3NodeAddTerm( static int fts3TreeFinishNode( SegmentNode *pTree, int iHeight, - tdsqlite3_int64 iLeftChild + sqlite3_int64 iLeftChild ){ int nStart; assert( iHeight>=1 && iHeight<128 ); - nStart = FTS3_VARINT_MAX - tdsqlite3Fts3VarintLen(iLeftChild); + nStart = FTS3_VARINT_MAX - sqlite3Fts3VarintLen(iLeftChild); pTree->aData[nStart] = (char)iHeight; - tdsqlite3Fts3PutVarint(&pTree->aData[nStart+1], iLeftChild); + sqlite3Fts3PutVarint(&pTree->aData[nStart+1], iLeftChild); return nStart; } @@ -180885,9 +180885,9 @@ static int fts3NodeWrite( Fts3Table *p, /* Virtual table handle */ SegmentNode *pTree, /* SegmentNode handle */ int iHeight, /* Height of this node in tree */ - tdsqlite3_int64 iLeaf, /* Block id of first leaf node */ - tdsqlite3_int64 iFree, /* Block id of next free slot in %_segments */ - tdsqlite3_int64 *piLast, /* OUT: Block id of last entry written */ + sqlite3_int64 iLeaf, /* Block id of first leaf node */ + sqlite3_int64 iFree, /* Block id of next free slot in %_segments */ + sqlite3_int64 *piLast, /* OUT: Block id of last entry written */ char **paRoot, /* OUT: Data for root node */ int *pnRoot /* OUT: Size of root node in bytes */ ){ @@ -180901,8 +180901,8 @@ static int fts3NodeWrite( *paRoot = &pTree->aData[nStart]; }else{ SegmentNode *pIter; - tdsqlite3_int64 iNextFree = iFree; - tdsqlite3_int64 iNextLeaf = iLeaf; + sqlite3_int64 iNextFree = iFree; + sqlite3_int64 iNextLeaf = iLeaf; for(pIter=pTree->pLeftmost; pIter && rc==SQLITE_OK; pIter=pIter->pRight){ int nStart = fts3TreeFinishNode(pIter, iHeight, iNextLeaf); int nWrite = pIter->nData - nStart; @@ -180932,11 +180932,11 @@ static void fts3NodeFree(SegmentNode *pTree){ while( p ){ SegmentNode *pRight = p->pRight; if( p->aData!=(char *)&p[1] ){ - tdsqlite3_free(p->aData); + sqlite3_free(p->aData); } assert( pRight==0 || p->zMalloc==0 ); - tdsqlite3_free(p->zMalloc); - tdsqlite3_free(p); + sqlite3_free(p->zMalloc); + sqlite3_free(p); p = pRight; } } @@ -180967,27 +180967,27 @@ static int fts3SegWriterAdd( if( !pWriter ){ int rc; - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; /* Allocate the SegmentWriter structure */ - pWriter = (SegmentWriter *)tdsqlite3_malloc(sizeof(SegmentWriter)); + pWriter = (SegmentWriter *)sqlite3_malloc(sizeof(SegmentWriter)); if( !pWriter ) return SQLITE_NOMEM; memset(pWriter, 0, sizeof(SegmentWriter)); *ppWriter = pWriter; /* Allocate a buffer in which to accumulate data */ - pWriter->aData = (char *)tdsqlite3_malloc(p->nNodeSize); + pWriter->aData = (char *)sqlite3_malloc(p->nNodeSize); if( !pWriter->aData ) return SQLITE_NOMEM; pWriter->nSize = p->nNodeSize; /* Find the next free blockid in the %_segments table */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - pWriter->iFree = tdsqlite3_column_int64(pStmt, 0); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + pWriter->iFree = sqlite3_column_int64(pStmt, 0); pWriter->iFirst = pWriter->iFree; } - rc = tdsqlite3_reset(pStmt); + rc = sqlite3_reset(pStmt); if( rc!=SQLITE_OK ) return rc; } nData = pWriter->nData; @@ -181001,10 +181001,10 @@ static int fts3SegWriterAdd( if( nSuffix<=0 ) return FTS_CORRUPT_VTAB; /* Figure out how many bytes are required by this new entry */ - nReq = tdsqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */ - tdsqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */ + nReq = sqlite3Fts3VarintLen(nPrefix) + /* varint containing prefix size */ + sqlite3Fts3VarintLen(nSuffix) + /* varint containing suffix size */ nSuffix + /* Term suffix */ - tdsqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ + sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ nDoclist; /* Doclist data */ if( nData>0 && nData+nReq>p->nNodeSize ){ @@ -181038,9 +181038,9 @@ static int fts3SegWriterAdd( nPrefix = 0; nSuffix = nTerm; nReq = 1 + /* varint containing prefix size */ - tdsqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ + sqlite3Fts3VarintLen(nTerm) + /* varint containing suffix size */ nTerm + /* Term suffix */ - tdsqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ + sqlite3Fts3VarintLen(nDoclist) + /* Size of doclist */ nDoclist; /* Doclist data */ } @@ -181051,7 +181051,7 @@ static int fts3SegWriterAdd( ** the buffer to make it large enough. */ if( nReq>pWriter->nSize ){ - char *aNew = tdsqlite3_realloc(pWriter->aData, nReq); + char *aNew = sqlite3_realloc(pWriter->aData, nReq); if( !aNew ) return SQLITE_NOMEM; pWriter->aData = aNew; pWriter->nSize = nReq; @@ -181059,12 +181059,12 @@ static int fts3SegWriterAdd( assert( nData+nReq<=pWriter->nSize ); /* Append the prefix-compressed term and doclist to the buffer. */ - nData += tdsqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix); - nData += tdsqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix); + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nPrefix); + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nSuffix); assert( nSuffix>0 ); memcpy(&pWriter->aData[nData], &zTerm[nPrefix], nSuffix); nData += nSuffix; - nData += tdsqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist); + nData += sqlite3Fts3PutVarint(&pWriter->aData[nData], nDoclist); assert( nDoclist>0 ); memcpy(&pWriter->aData[nData], aDoclist, nDoclist); pWriter->nData = nData + nDoclist; @@ -181076,7 +181076,7 @@ static int fts3SegWriterAdd( */ if( isCopyTerm ){ if( nTerm>pWriter->nMalloc ){ - char *zNew = tdsqlite3_realloc(pWriter->zMalloc, nTerm*2); + char *zNew = sqlite3_realloc(pWriter->zMalloc, nTerm*2); if( !zNew ){ return SQLITE_NOMEM; } @@ -181104,13 +181104,13 @@ static int fts3SegWriterAdd( static int fts3SegWriterFlush( Fts3Table *p, /* Virtual table handle */ SegmentWriter *pWriter, /* SegmentWriter to flush to the db */ - tdsqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */ + sqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */ int iIdx /* Value for 'idx' column of %_segdir */ ){ int rc; /* Return code */ if( pWriter->pTree ){ - tdsqlite3_int64 iLast = 0; /* Largest block id written to database */ - tdsqlite3_int64 iLastLeaf; /* Largest leaf block id written to db */ + sqlite3_int64 iLast = 0; /* Largest block id written to database */ + sqlite3_int64 iLastLeaf; /* Largest leaf block id written to db */ char *zRoot = NULL; /* Pointer to buffer containing root node */ int nRoot = 0; /* Size of buffer zRoot */ @@ -181139,10 +181139,10 @@ static int fts3SegWriterFlush( */ static void fts3SegWriterFree(SegmentWriter *pWriter){ if( pWriter ){ - tdsqlite3_free(pWriter->aData); - tdsqlite3_free(pWriter->zMalloc); + sqlite3_free(pWriter->aData); + sqlite3_free(pWriter->zMalloc); fts3NodeFree(pWriter->pTree); - tdsqlite3_free(pWriter); + sqlite3_free(pWriter); } } @@ -181156,8 +181156,8 @@ static void fts3SegWriterFree(SegmentWriter *pWriter){ ** document pRowid, or false otherwise, and SQLITE_OK is returned. If an ** error occurs, an SQLite error code is returned. */ -static int fts3IsEmpty(Fts3Table *p, tdsqlite3_value *pRowid, int *pisEmpty){ - tdsqlite3_stmt *pStmt; +static int fts3IsEmpty(Fts3Table *p, sqlite3_value *pRowid, int *pisEmpty){ + sqlite3_stmt *pStmt; int rc; if( p->zContentTbl ){ /* If using the content=xxx option, assume the table is never empty */ @@ -181166,10 +181166,10 @@ static int fts3IsEmpty(Fts3Table *p, tdsqlite3_value *pRowid, int *pisEmpty){ }else{ rc = fts3SqlStmt(p, SQL_IS_EMPTY, &pStmt, &pRowid); if( rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - *pisEmpty = tdsqlite3_column_int(pStmt, 0); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pisEmpty = sqlite3_column_int(pStmt, 0); } - rc = tdsqlite3_reset(pStmt); + rc = sqlite3_reset(pStmt); } } return rc; @@ -181187,9 +181187,9 @@ static int fts3SegmentMaxLevel( Fts3Table *p, int iLangid, int iIndex, - tdsqlite3_int64 *pnMax + sqlite3_int64 *pnMax ){ - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; int rc; assert( iIndex>=0 && iIndexnIndex ); @@ -181201,14 +181201,14 @@ static int fts3SegmentMaxLevel( */ rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; - tdsqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); - tdsqlite3_bind_int64(pStmt, 2, + sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0)); + sqlite3_bind_int64(pStmt, 2, getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1) ); - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - *pnMax = tdsqlite3_column_int64(pStmt, 0); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pnMax = sqlite3_column_int64(pStmt, 0); } - return tdsqlite3_reset(pStmt); + return sqlite3_reset(pStmt); } /* @@ -181227,19 +181227,19 @@ static int fts3SegmentIsMaxLevel(Fts3Table *p, i64 iAbsLevel, int *pbMax){ ** ** (1024 is actually the value of macro FTS3_SEGDIR_PREFIXLEVEL_STR). */ - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; int rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0); if( rc!=SQLITE_OK ) return rc; - tdsqlite3_bind_int64(pStmt, 1, iAbsLevel+1); - tdsqlite3_bind_int64(pStmt, 2, + sqlite3_bind_int64(pStmt, 1, iAbsLevel+1); + sqlite3_bind_int64(pStmt, 2, ((iAbsLevel/FTS3_SEGDIR_MAXLEVEL)+1) * FTS3_SEGDIR_MAXLEVEL ); *pbMax = 0; - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - *pbMax = tdsqlite3_column_type(pStmt, 0)==SQLITE_NULL; + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *pbMax = sqlite3_column_type(pStmt, 0)==SQLITE_NULL; } - return tdsqlite3_reset(pStmt); + return sqlite3_reset(pStmt); } /* @@ -181253,13 +181253,13 @@ static int fts3DeleteSegment( ){ int rc = SQLITE_OK; /* Return code */ if( pSeg->iStartBlock ){ - tdsqlite3_stmt *pDelete; /* SQL statement to delete rows */ + sqlite3_stmt *pDelete; /* SQL statement to delete rows */ rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDelete, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pDelete, 1, pSeg->iStartBlock); - tdsqlite3_bind_int64(pDelete, 2, pSeg->iEndBlock); - tdsqlite3_step(pDelete); - rc = tdsqlite3_reset(pDelete); + sqlite3_bind_int64(pDelete, 1, pSeg->iStartBlock); + sqlite3_bind_int64(pDelete, 2, pSeg->iEndBlock); + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); } } return rc; @@ -181289,7 +181289,7 @@ static int fts3DeleteSegdir( ){ int rc = SQLITE_OK; /* Return Code */ int i; /* Iterator variable */ - tdsqlite3_stmt *pDelete = 0; /* SQL statement to delete rows */ + sqlite3_stmt *pDelete = 0; /* SQL statement to delete rows */ for(i=0; rc==SQLITE_OK && ipMsr->nBuffer ){ char *pNew; pMsr->nBuffer = nList*2; - pNew = (char *)tdsqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); + pNew = (char *)sqlite3_realloc(pMsr->aBuffer, pMsr->nBuffer); if( !pNew ) return SQLITE_NOMEM; pMsr->aBuffer = pNew; } @@ -181399,10 +181399,10 @@ static int fts3MsrBufferData( return SQLITE_OK; } -SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrNext( +SQLITE_PRIVATE int sqlite3Fts3MsrIncrNext( Fts3Table *p, /* Virtual table handle */ Fts3MultiSegReader *pMsr, /* Multi-segment-reader handle */ - tdsqlite3_int64 *piDocid, /* OUT: Docid value */ + sqlite3_int64 *piDocid, /* OUT: Docid value */ char **paPoslist, /* OUT: Pointer to position list */ int *pnPoslist /* OUT: Size of position list in bytes */ ){ @@ -181429,7 +181429,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrNext( char *pList; int nList; int j; - tdsqlite3_int64 iDocid = apSegment[0]->iDocid; + sqlite3_int64 iDocid = apSegment[0]->iDocid; rc = fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); j = 1; @@ -181499,7 +181499,7 @@ static int fts3SegReaderStart( return SQLITE_OK; } -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStart( +SQLITE_PRIVATE int sqlite3Fts3SegReaderStart( Fts3Table *p, /* Virtual table handle */ Fts3MultiSegReader *pCsr, /* Cursor object */ Fts3SegFilter *pFilter /* Restrictions on range of iteration */ @@ -181508,7 +181508,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStart( return fts3SegReaderStart(p, pCsr, pFilter->zTerm, pFilter->nTerm); } -SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrStart( +SQLITE_PRIVATE int sqlite3Fts3MsrIncrStart( Fts3Table *p, /* Virtual table handle */ Fts3MultiSegReader *pCsr, /* Cursor object */ int iCol, /* Column to match on. */ @@ -181553,17 +181553,17 @@ SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrStart( /* ** This function is called on a MultiSegReader that has been started using -** tdsqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also +** sqlite3Fts3MsrIncrStart(). One or more calls to MsrIncrNext() may also ** have been made. Calling this function puts the MultiSegReader in such ** a state that if the next two calls are: ** -** tdsqlite3Fts3SegReaderStart() -** tdsqlite3Fts3SegReaderStep() +** sqlite3Fts3SegReaderStart() +** sqlite3Fts3SegReaderStep() ** ** then the entire doclist for the term is available in ** MultiSegReader.aDoclist/nDoclist. */ -SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ +SQLITE_PRIVATE int sqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ int i; /* Used to iterate through segment-readers */ assert( pCsr->zTerm==0 ); @@ -181583,7 +181583,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3MsrIncrRestart(Fts3MultiSegReader *pCsr){ } -SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStep( +SQLITE_PRIVATE int sqlite3Fts3SegReaderStep( Fts3Table *p, /* Virtual table handle */ Fts3MultiSegReader *pCsr /* Cursor object */ ){ @@ -181672,7 +181672,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStep( if( rc==SQLITE_OK ) rc = SQLITE_ROW; }else{ int nDoclist = 0; /* Size of doclist */ - tdsqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ + sqlite3_int64 iPrev = 0; /* Previous docid stored in doclist */ /* The current term of the first nMerge entries in the array ** of Fts3SegReader objects is the same. The doclists must be merged @@ -181687,7 +181687,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStep( char *pList = 0; int nList = 0; int nByte; - tdsqlite3_int64 iDocid = apSegment[0]->iDocid; + sqlite3_int64 iDocid = apSegment[0]->iDocid; fts3SegReaderNextDocid(p, apSegment[0], &pList, &nList); j = 1; while( jbDescIdx && nDoclist>0 ){ if( iPrev<=iDocid ) return FTS_CORRUPT_VTAB; iDelta = (i64)((u64)iPrev - (u64)iDocid); @@ -181715,11 +181715,11 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStep( iDelta = (i64)((u64)iDocid - (u64)iPrev); } - nByte = tdsqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); + nByte = sqlite3Fts3VarintLen(iDelta) + (isRequirePos?nList+1:0); if( nDoclist+nByte>pCsr->nBuffer ){ char *aNew; pCsr->nBuffer = (nDoclist+nByte)*2; - aNew = tdsqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer); + aNew = sqlite3_realloc(pCsr->aBuffer, pCsr->nBuffer); if( !aNew ){ return SQLITE_NOMEM; } @@ -181730,13 +181730,13 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStep( char *a = &pCsr->aBuffer[nDoclist]; int nWrite; - nWrite = tdsqlite3Fts3FirstFilter(iDelta, pList, nList, a); + nWrite = sqlite3Fts3FirstFilter(iDelta, pList, nList, a); if( nWrite ){ iPrev = iDocid; nDoclist += nWrite; } }else{ - nDoclist += tdsqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta); + nDoclist += sqlite3Fts3PutVarint(&pCsr->aBuffer[nDoclist], iDelta); iPrev = iDocid; if( isRequirePos ){ memcpy(&pCsr->aBuffer[nDoclist], pList, nList); @@ -181761,16 +181761,16 @@ SQLITE_PRIVATE int tdsqlite3Fts3SegReaderStep( } -SQLITE_PRIVATE void tdsqlite3Fts3SegReaderFinish( +SQLITE_PRIVATE void sqlite3Fts3SegReaderFinish( Fts3MultiSegReader *pCsr /* Cursor object */ ){ if( pCsr ){ int i; for(i=0; inSegment; i++){ - tdsqlite3Fts3SegReaderFree(pCsr->apSegment[i]); + sqlite3Fts3SegReaderFree(pCsr->apSegment[i]); } - tdsqlite3_free(pCsr->apSegment); - tdsqlite3_free(pCsr->aBuffer); + sqlite3_free(pCsr->apSegment); + sqlite3_free(pCsr->aBuffer); pCsr->nSegment = 0; pCsr->apSegment = 0; @@ -181789,12 +181789,12 @@ SQLITE_PRIVATE void tdsqlite3Fts3SegReaderFinish( ** set *piEndBlock to the first value and *pnByte to the second. */ static void fts3ReadEndBlockField( - tdsqlite3_stmt *pStmt, + sqlite3_stmt *pStmt, int iCol, i64 *piEndBlock, i64 *pnByte ){ - const unsigned char *zText = tdsqlite3_column_text(pStmt, iCol); + const unsigned char *zText = sqlite3_column_text(pStmt, iCol); if( zText ){ int i; int iMul = 1; @@ -181823,11 +181823,11 @@ static void fts3ReadEndBlockField( */ static int fts3PromoteSegments( Fts3Table *p, /* FTS table handle */ - tdsqlite3_int64 iAbsLevel, /* Absolute level just updated */ - tdsqlite3_int64 nByte /* Size of new segment at iAbsLevel */ + sqlite3_int64 iAbsLevel, /* Absolute level just updated */ + sqlite3_int64 nByte /* Size of new segment at iAbsLevel */ ){ int rc = SQLITE_OK; - tdsqlite3_stmt *pRange; + sqlite3_stmt *pRange; rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE2, &pRange, 0); @@ -181841,9 +181841,9 @@ static int fts3PromoteSegments( ** at least one such segment, and it is possible to determine that all ** such segments are smaller than nLimit bytes in size, they will be ** promoted to level iAbsLevel. */ - tdsqlite3_bind_int64(pRange, 1, iAbsLevel+1); - tdsqlite3_bind_int64(pRange, 2, iLast); - while( SQLITE_ROW==tdsqlite3_step(pRange) ){ + sqlite3_bind_int64(pRange, 1, iAbsLevel+1); + sqlite3_bind_int64(pRange, 2, iLast); + while( SQLITE_ROW==sqlite3_step(pRange) ){ i64 nSize = 0, dummy; fts3ReadEndBlockField(pRange, 2, &dummy, &nSize); if( nSize<=0 || nSize>nLimit ){ @@ -181857,12 +181857,12 @@ static int fts3PromoteSegments( } bOk = 1; } - rc = tdsqlite3_reset(pRange); + rc = sqlite3_reset(pRange); if( bOk ){ int iIdx = 0; - tdsqlite3_stmt *pUpdate1 = 0; - tdsqlite3_stmt *pUpdate2 = 0; + sqlite3_stmt *pUpdate1 = 0; + sqlite3_stmt *pUpdate2 = 0; if( rc==SQLITE_OK ){ rc = fts3SqlStmt(p, SQL_UPDATE_LEVEL_IDX, &pUpdate1, 0); @@ -181882,28 +181882,28 @@ static int fts3PromoteSegments( ** setting the "idx" fields as appropriate to keep them in the same ** order. The contents of level -1 (which is never used, except ** transiently here), will be moved back to level iAbsLevel below. */ - tdsqlite3_bind_int64(pRange, 1, iAbsLevel); - while( SQLITE_ROW==tdsqlite3_step(pRange) ){ - tdsqlite3_bind_int(pUpdate1, 1, iIdx++); - tdsqlite3_bind_int(pUpdate1, 2, tdsqlite3_column_int(pRange, 0)); - tdsqlite3_bind_int(pUpdate1, 3, tdsqlite3_column_int(pRange, 1)); - tdsqlite3_step(pUpdate1); - rc = tdsqlite3_reset(pUpdate1); + sqlite3_bind_int64(pRange, 1, iAbsLevel); + while( SQLITE_ROW==sqlite3_step(pRange) ){ + sqlite3_bind_int(pUpdate1, 1, iIdx++); + sqlite3_bind_int(pUpdate1, 2, sqlite3_column_int(pRange, 0)); + sqlite3_bind_int(pUpdate1, 3, sqlite3_column_int(pRange, 1)); + sqlite3_step(pUpdate1); + rc = sqlite3_reset(pUpdate1); if( rc!=SQLITE_OK ){ - tdsqlite3_reset(pRange); + sqlite3_reset(pRange); break; } } } if( rc==SQLITE_OK ){ - rc = tdsqlite3_reset(pRange); + rc = sqlite3_reset(pRange); } /* Move level -1 to level iAbsLevel */ if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pUpdate2, 1, iAbsLevel); - tdsqlite3_step(pUpdate2); - rc = tdsqlite3_reset(pUpdate2); + sqlite3_bind_int64(pUpdate2, 1, iAbsLevel); + sqlite3_step(pUpdate2); + rc = sqlite3_reset(pUpdate2); } } } @@ -181931,7 +181931,7 @@ static int fts3SegmentMerge( ){ int rc; /* Return code */ int iIdx = 0; /* Index of new segment */ - tdsqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ + sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */ SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */ Fts3SegFilter filter; /* Segment term filter condition */ Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */ @@ -181945,7 +181945,7 @@ static int fts3SegmentMerge( assert( iLevel=0 && iIndexnIndex ); - rc = tdsqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); + rc = sqlite3Fts3SegReaderCursor(p, iLangid, iIndex, iLevel, 0, 0, 1, 0, &csr); if( rc!=SQLITE_OK || csr.nSegment==0 ) goto finished; if( iLevel!=FTS3_SEGCURSOR_PENDING ){ @@ -181987,9 +181987,9 @@ static int fts3SegmentMerge( filter.flags = FTS3_SEGMENT_REQUIRE_POS; filter.flags |= (bIgnoreEmpty ? FTS3_SEGMENT_IGNORE_EMPTY : 0); - rc = tdsqlite3Fts3SegReaderStart(p, &csr, &filter); + rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); while( SQLITE_OK==rc ){ - rc = tdsqlite3Fts3SegReaderStep(p, &csr); + rc = sqlite3Fts3SegReaderStep(p, &csr); if( rc!=SQLITE_ROW ) break; rc = fts3SegWriterAdd(p, &pWriter, 1, csr.zTerm, csr.nTerm, csr.aDoclist, csr.nDoclist); @@ -182014,7 +182014,7 @@ static int fts3SegmentMerge( finished: fts3SegWriterFree(pWriter); - tdsqlite3Fts3SegReaderFinish(&csr); + sqlite3Fts3SegReaderFinish(&csr); return rc; } @@ -182022,7 +182022,7 @@ static int fts3SegmentMerge( /* ** Flush the contents of pendingTerms to level 0 segments. */ -SQLITE_PRIVATE int tdsqlite3Fts3PendingTermsFlush(Fts3Table *p){ +SQLITE_PRIVATE int sqlite3Fts3PendingTermsFlush(Fts3Table *p){ int rc = SQLITE_OK; int i; @@ -182030,7 +182030,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3PendingTermsFlush(Fts3Table *p){ rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } - tdsqlite3Fts3PendingTermsClear(p); + sqlite3Fts3PendingTermsClear(p); /* Determine the auto-incr-merge setting if unknown. If enabled, ** estimate the number of leaf blocks of content to be written @@ -182038,18 +182038,18 @@ SQLITE_PRIVATE int tdsqlite3Fts3PendingTermsFlush(Fts3Table *p){ if( rc==SQLITE_OK && p->bHasStat && p->nAutoincrmerge==0xff && p->nLeafAdd>0 ){ - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); - rc = tdsqlite3_step(pStmt); + sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); + rc = sqlite3_step(pStmt); if( rc==SQLITE_ROW ){ - p->nAutoincrmerge = tdsqlite3_column_int(pStmt, 0); + p->nAutoincrmerge = sqlite3_column_int(pStmt, 0); if( p->nAutoincrmerge==1 ) p->nAutoincrmerge = 8; }else if( rc==SQLITE_DONE ){ p->nAutoincrmerge = 0; } - rc = tdsqlite3_reset(pStmt); + rc = sqlite3_reset(pStmt); } } return rc; @@ -182066,7 +182066,7 @@ static void fts3EncodeIntArray( ){ int i, j; for(i=j=0; inColumn ); + pBlob = sqlite3_malloc64( 10*(sqlite3_int64)p->nColumn ); if( pBlob==0 ){ *pRC = SQLITE_NOMEM; return; @@ -182116,14 +182116,14 @@ static void fts3InsertDocsize( fts3EncodeIntArray(p->nColumn, aSz, pBlob, &nBlob); rc = fts3SqlStmt(p, SQL_REPLACE_DOCSIZE, &pStmt, 0); if( rc ){ - tdsqlite3_free(pBlob); + sqlite3_free(pBlob); *pRC = rc; return; } - tdsqlite3_bind_int64(pStmt, 1, p->iPrevDocid); - tdsqlite3_bind_blob(pStmt, 2, pBlob, nBlob, tdsqlite3_free); - tdsqlite3_step(pStmt); - *pRC = tdsqlite3_reset(pStmt); + sqlite3_bind_int64(pStmt, 1, p->iPrevDocid); + sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, sqlite3_free); + sqlite3_step(pStmt); + *pRC = sqlite3_reset(pStmt); } /* @@ -182151,14 +182151,14 @@ static void fts3UpdateDocTotals( char *pBlob; /* Storage for BLOB written into %_stat */ int nBlob; /* Size of BLOB written into %_stat */ u32 *a; /* Array of integers that becomes the BLOB */ - tdsqlite3_stmt *pStmt; /* Statement for reading and writing */ + sqlite3_stmt *pStmt; /* Statement for reading and writing */ int i; /* Loop counter */ int rc; /* Result code from subfunctions */ const int nStat = p->nColumn+2; if( *pRC ) return; - a = tdsqlite3_malloc64( (sizeof(u32)+10)*(tdsqlite3_int64)nStat ); + a = sqlite3_malloc64( (sizeof(u32)+10)*(sqlite3_int64)nStat ); if( a==0 ){ *pRC = SQLITE_NOMEM; return; @@ -182166,21 +182166,21 @@ static void fts3UpdateDocTotals( pBlob = (char*)&a[nStat]; rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0); if( rc ){ - tdsqlite3_free(a); + sqlite3_free(a); *pRC = rc; return; } - tdsqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); - if( tdsqlite3_step(pStmt)==SQLITE_ROW ){ + sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); + if( sqlite3_step(pStmt)==SQLITE_ROW ){ fts3DecodeIntArray(nStat, a, - tdsqlite3_column_blob(pStmt, 0), - tdsqlite3_column_bytes(pStmt, 0)); + sqlite3_column_blob(pStmt, 0), + sqlite3_column_bytes(pStmt, 0)); }else{ memset(a, 0, sizeof(u32)*(nStat) ); } - rc = tdsqlite3_reset(pStmt); + rc = sqlite3_reset(pStmt); if( rc!=SQLITE_OK ){ - tdsqlite3_free(a); + sqlite3_free(a); *pRC = rc; return; } @@ -182201,16 +182201,16 @@ static void fts3UpdateDocTotals( fts3EncodeIntArray(nStat, a, pBlob, &nBlob); rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); if( rc ){ - tdsqlite3_free(a); + sqlite3_free(a); *pRC = rc; return; } - tdsqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); - tdsqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); - tdsqlite3_step(pStmt); - *pRC = tdsqlite3_reset(pStmt); - tdsqlite3_bind_null(pStmt, 2); - tdsqlite3_free(a); + sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL); + sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC); + sqlite3_step(pStmt); + *pRC = sqlite3_reset(pStmt); + sqlite3_bind_null(pStmt, 2); + sqlite3_free(a); } /* @@ -182220,19 +182220,19 @@ static void fts3UpdateDocTotals( static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ int bSeenDone = 0; int rc; - tdsqlite3_stmt *pAllLangid = 0; + sqlite3_stmt *pAllLangid = 0; - rc = tdsqlite3Fts3PendingTermsFlush(p); + rc = sqlite3Fts3PendingTermsFlush(p); if( rc==SQLITE_OK ){ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); } if( rc==SQLITE_OK ){ int rc2; - tdsqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); - tdsqlite3_bind_int(pAllLangid, 2, p->nIndex); - while( tdsqlite3_step(pAllLangid)==SQLITE_ROW ){ + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); + while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ int i; - int iLangid = tdsqlite3_column_int(pAllLangid, 0); + int iLangid = sqlite3_column_int(pAllLangid, 0); for(i=0; rc==SQLITE_OK && inIndex; i++){ rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL); if( rc==SQLITE_DONE ){ @@ -182241,11 +182241,11 @@ static int fts3DoOptimize(Fts3Table *p, int bReturnDone){ } } } - rc2 = tdsqlite3_reset(pAllLangid); + rc2 = sqlite3_reset(pAllLangid); if( rc==SQLITE_OK ) rc = rc2; } - tdsqlite3Fts3SegmentsClose(p); + sqlite3Fts3SegmentsClose(p); return (rc==SQLITE_OK && bReturnDone && bSeenDone) ? SQLITE_DONE : rc; } @@ -182268,21 +182268,21 @@ static int fts3DoRebuild(Fts3Table *p){ u32 *aSz = 0; u32 *aSzIns = 0; u32 *aSzDel = 0; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; int nEntry = 0; /* Compose and prepare an SQL statement to loop through the content table */ - char *zSql = tdsqlite3_mprintf("SELECT %s" , p->zReadExprlist); + char *zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - tdsqlite3_free(zSql); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); } if( rc==SQLITE_OK ){ - tdsqlite3_int64 nByte = sizeof(u32) * ((tdsqlite3_int64)p->nColumn+1)*3; - aSz = (u32 *)tdsqlite3_malloc64(nByte); + sqlite3_int64 nByte = sizeof(u32) * ((sqlite3_int64)p->nColumn+1)*3; + aSz = (u32 *)sqlite3_malloc64(nByte); if( aSz==0 ){ rc = SQLITE_NOMEM; }else{ @@ -182292,23 +182292,23 @@ static int fts3DoRebuild(Fts3Table *p){ } } - while( rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pStmt) ){ + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ int iCol; int iLangid = langidFromSelect(p, pStmt); - rc = fts3PendingTermsDocid(p, 0, iLangid, tdsqlite3_column_int64(pStmt, 0)); + rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0)); memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1)); for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ if( p->abNotindexed[iCol]==0 ){ - const char *z = (const char *) tdsqlite3_column_text(pStmt, iCol+1); + const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1); rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]); - aSz[p->nColumn] += tdsqlite3_column_bytes(pStmt, iCol+1); + aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1); } } if( p->bHasDocsize ){ fts3InsertDocsize(&rc, p, aSz); } if( rc!=SQLITE_OK ){ - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); pStmt = 0; }else{ nEntry++; @@ -182320,10 +182320,10 @@ static int fts3DoRebuild(Fts3Table *p){ if( p->bFts4 ){ fts3UpdateDocTotals(&rc, p, aSzIns, aSzDel, nEntry); } - tdsqlite3_free(aSz); + sqlite3_free(aSz); if( pStmt ){ - int rc2 = tdsqlite3_finalize(pStmt); + int rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ rc = rc2; } @@ -182342,18 +182342,18 @@ static int fts3DoRebuild(Fts3Table *p){ */ static int fts3IncrmergeCsr( Fts3Table *p, /* FTS3 table handle */ - tdsqlite3_int64 iAbsLevel, /* Absolute level to open */ + sqlite3_int64 iAbsLevel, /* Absolute level to open */ int nSeg, /* Number of segments to merge */ Fts3MultiSegReader *pCsr /* Cursor object to populate */ ){ int rc; /* Return Code */ - tdsqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */ - tdsqlite3_int64 nByte; /* Bytes allocated at pCsr->apSegment[] */ + sqlite3_stmt *pStmt = 0; /* Statement used to read %_segdir entry */ + sqlite3_int64 nByte; /* Bytes allocated at pCsr->apSegment[] */ /* Allocate space for the Fts3MultiSegReader.aCsr[] array */ memset(pCsr, 0, sizeof(*pCsr)); nByte = sizeof(Fts3SegReader *) * nSeg; - pCsr->apSegment = (Fts3SegReader **)tdsqlite3_malloc64(nByte); + pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc64(nByte); if( pCsr->apSegment==0 ){ rc = SQLITE_NOMEM; @@ -182364,20 +182364,20 @@ static int fts3IncrmergeCsr( if( rc==SQLITE_OK ){ int i; int rc2; - tdsqlite3_bind_int64(pStmt, 1, iAbsLevel); + sqlite3_bind_int64(pStmt, 1, iAbsLevel); assert( pCsr->nSegment==0 ); - for(i=0; rc==SQLITE_OK && tdsqlite3_step(pStmt)==SQLITE_ROW && iapSegment[i] ); pCsr->nSegment++; } - rc2 = tdsqlite3_reset(pStmt); + rc2 = sqlite3_reset(pStmt); if( rc==SQLITE_OK ) rc = rc2; } @@ -182406,7 +182406,7 @@ struct Blob { ** nodes (blocks). */ struct NodeWriter { - tdsqlite3_int64 iBlock; /* Current block id */ + sqlite3_int64 iBlock; /* Current block id */ Blob key; /* Last key written to the current block */ Blob block; /* Current block image */ }; @@ -182418,11 +182418,11 @@ struct NodeWriter { struct IncrmergeWriter { int nLeafEst; /* Space allocated for leaf blocks */ int nWork; /* Number of leaf pages flushed */ - tdsqlite3_int64 iAbsLevel; /* Absolute level of input segments */ + sqlite3_int64 iAbsLevel; /* Absolute level of input segments */ int iIdx; /* Index of *output* segment in iAbsLevel+1 */ - tdsqlite3_int64 iStart; /* Block number of first allocated block */ - tdsqlite3_int64 iEnd; /* Block number of last allocated block */ - tdsqlite3_int64 nLeafData; /* Bytes of leaf page data so far */ + sqlite3_int64 iStart; /* Block number of first allocated block */ + sqlite3_int64 iEnd; /* Block number of last allocated block */ + sqlite3_int64 nLeafData; /* Bytes of leaf page data so far */ u8 bNoLeafData; /* If true, store 0 for segment size */ NodeWriter aNodeWriter[FTS_MAX_APPENDABLE_HEIGHT]; }; @@ -182441,7 +182441,7 @@ struct NodeReader { int iOff; /* Current offset within aNode[] */ /* Output variables. Containing the current node entry. */ - tdsqlite3_int64 iChild; /* Pointer to child node */ + sqlite3_int64 iChild; /* Pointer to child node */ Blob term; /* Current term */ const char *aDoclist; /* Pointer to doclist */ int nDoclist; /* Size of doclist in bytes */ @@ -182459,7 +182459,7 @@ struct NodeReader { static void blobGrowBuffer(Blob *pBlob, int nMin, int *pRc){ if( *pRc==SQLITE_OK && nMin>pBlob->nAlloc ){ int nAlloc = nMin; - char *a = (char *)tdsqlite3_realloc(pBlob->a, nAlloc); + char *a = (char *)sqlite3_realloc(pBlob->a, nAlloc); if( a ){ pBlob->nAlloc = nAlloc; pBlob->a = a; @@ -182523,7 +182523,7 @@ static int nodeReaderNext(NodeReader *p){ ** Release all dynamic resources held by node-reader object *p. */ static void nodeReaderRelease(NodeReader *p){ - tdsqlite3_free(p->term.a); + sqlite3_free(p->term.a); } /* @@ -182541,7 +182541,7 @@ static int nodeReaderInit(NodeReader *p, const char *aNode, int nNode){ /* Figure out if this is a leaf or an internal node. */ if( aNode && aNode[0] ){ /* An internal node. */ - p->iOff = 1 + tdsqlite3Fts3GetVarint(&p->aNode[1], &p->iChild); + p->iOff = 1 + sqlite3Fts3GetVarint(&p->aNode[1], &p->iChild); }else{ p->iOff = 1; } @@ -182565,12 +182565,12 @@ static int fts3IncrmergePush( const char *zTerm, /* Term to write to internal node */ int nTerm /* Bytes at zTerm */ ){ - tdsqlite3_int64 iPtr = pWriter->aNodeWriter[0].iBlock; + sqlite3_int64 iPtr = pWriter->aNodeWriter[0].iBlock; int iLayer; assert( nTerm>0 ); for(iLayer=1; ALWAYS(iLayeraNodeWriter[iLayer]; int rc = SQLITE_OK; int nPrefix; @@ -182584,8 +182584,8 @@ static int fts3IncrmergePush( nPrefix = fts3PrefixCompress(pNode->key.a, pNode->key.n, zTerm, nTerm); nSuffix = nTerm - nPrefix; if(nSuffix<=0 ) return FTS_CORRUPT_VTAB; - nSpace = tdsqlite3Fts3VarintLen(nPrefix); - nSpace += tdsqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; if( pNode->key.n==0 || (pNode->block.n + nSpace)<=p->nNodeSize ){ /* If the current node of layer iLayer contains zero keys, or if adding @@ -182597,7 +182597,7 @@ static int fts3IncrmergePush( blobGrowBuffer(pBlk, p->nNodeSize, &rc); if( rc==SQLITE_OK ){ pBlk->a[0] = (char)iLayer; - pBlk->n = 1 + tdsqlite3Fts3PutVarint(&pBlk->a[1], iPtr); + pBlk->n = 1 + sqlite3Fts3PutVarint(&pBlk->a[1], iPtr); } } blobGrowBuffer(pBlk, pBlk->n + nSpace, &rc); @@ -182605,9 +182605,9 @@ static int fts3IncrmergePush( if( rc==SQLITE_OK ){ if( pNode->key.n ){ - pBlk->n += tdsqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix); + pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nPrefix); } - pBlk->n += tdsqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix); + pBlk->n += sqlite3Fts3PutVarint(&pBlk->a[pBlk->n], nSuffix); memcpy(&pBlk->a[pBlk->n], &zTerm[nPrefix], nSuffix); pBlk->n += nSuffix; @@ -182622,7 +182622,7 @@ static int fts3IncrmergePush( assert( pNode->block.nAlloc>=p->nNodeSize ); pNode->block.a[0] = (char)iLayer; - pNode->block.n = 1 + tdsqlite3Fts3PutVarint(&pNode->block.a[1], iPtr+1); + pNode->block.n = 1 + sqlite3Fts3PutVarint(&pNode->block.a[1], iPtr+1); iNextPtr = pNode->iBlock; pNode->iBlock++; @@ -182689,14 +182689,14 @@ static int fts3AppendToNode( pPrev->n = nTerm; if( bFirst==0 ){ - pNode->n += tdsqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nPrefix); } - pNode->n += tdsqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nSuffix); memcpy(&pNode->a[pNode->n], &zTerm[nPrefix], nSuffix); pNode->n += nSuffix; if( aDoclist ){ - pNode->n += tdsqlite3Fts3PutVarint(&pNode->a[pNode->n], nDoclist); + pNode->n += sqlite3Fts3PutVarint(&pNode->a[pNode->n], nDoclist); memcpy(&pNode->a[pNode->n], aDoclist, nDoclist); pNode->n += nDoclist; } @@ -182731,9 +182731,9 @@ static int fts3IncrmergeAppend( nPrefix = fts3PrefixCompress(pLeaf->key.a, pLeaf->key.n, zTerm, nTerm); nSuffix = nTerm - nPrefix; - nSpace = tdsqlite3Fts3VarintLen(nPrefix); - nSpace += tdsqlite3Fts3VarintLen(nSuffix) + nSuffix; - nSpace += tdsqlite3Fts3VarintLen(nDoclist) + nDoclist; + nSpace = sqlite3Fts3VarintLen(nPrefix); + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; /* If the current block is not empty, and if adding this term/doclist ** to the current block would make it larger than Fts3Table.nNodeSize @@ -182765,8 +182765,8 @@ static int fts3IncrmergeAppend( nSuffix = nTerm; nSpace = 1; - nSpace += tdsqlite3Fts3VarintLen(nSuffix) + nSuffix; - nSpace += tdsqlite3Fts3VarintLen(nDoclist) + nDoclist; + nSpace += sqlite3Fts3VarintLen(nSuffix) + nSuffix; + nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; } pWriter->nLeafData += nSpace; @@ -182816,8 +182816,8 @@ static void fts3IncrmergeRelease( if( pNode->block.n>0 ) break; assert( *pRc || pNode->block.nAlloc==0 ); assert( *pRc || pNode->key.nAlloc==0 ); - tdsqlite3_free(pNode->block.a); - tdsqlite3_free(pNode->key.a); + sqlite3_free(pNode->block.a); + sqlite3_free(pNode->key.a); } /* Empty output segment. This is a no-op. */ @@ -182843,7 +182843,7 @@ static void fts3IncrmergeRelease( blobGrowBuffer(pBlock, 1 + FTS3_VARINT_MAX, &rc); if( rc==SQLITE_OK ){ pBlock->a[0] = 0x01; - pBlock->n = 1 + tdsqlite3Fts3PutVarint( + pBlock->n = 1 + sqlite3Fts3PutVarint( &pBlock->a[1], pWriter->aNodeWriter[0].iBlock ); } @@ -182857,8 +182857,8 @@ static void fts3IncrmergeRelease( if( pNode->block.n>0 && rc==SQLITE_OK ){ rc = fts3WriteSegment(p, pNode->iBlock, pNode->block.a, pNode->block.n); } - tdsqlite3_free(pNode->block.a); - tdsqlite3_free(pNode->key.a); + sqlite3_free(pNode->block.a); + sqlite3_free(pNode->key.a); } /* Write the %_segdir record. */ @@ -182873,8 +182873,8 @@ static void fts3IncrmergeRelease( pRoot->block.a, pRoot->block.n /* root */ ); } - tdsqlite3_free(pRoot->block.a); - tdsqlite3_free(pRoot->key.a); + sqlite3_free(pRoot->block.a); + sqlite3_free(pRoot->key.a); *pRc = rc; } @@ -182913,16 +182913,16 @@ static int fts3TermCmp( ** is, then a NULL entry has been inserted into the %_segments table ** with blockid %_segdir.end_block. */ -static int fts3IsAppendable(Fts3Table *p, tdsqlite3_int64 iEnd, int *pbRes){ +static int fts3IsAppendable(Fts3Table *p, sqlite3_int64 iEnd, int *pbRes){ int bRes = 0; /* Result to set *pbRes to */ - tdsqlite3_stmt *pCheck = 0; /* Statement to query database with */ + sqlite3_stmt *pCheck = 0; /* Statement to query database with */ int rc; /* Return code */ rc = fts3SqlStmt(p, SQL_SEGMENT_IS_APPENDABLE, &pCheck, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pCheck, 1, iEnd); - if( SQLITE_ROW==tdsqlite3_step(pCheck) ) bRes = 1; - rc = tdsqlite3_reset(pCheck); + sqlite3_bind_int64(pCheck, 1, iEnd); + if( SQLITE_ROW==sqlite3_step(pCheck) ) bRes = 1; + rc = sqlite3_reset(pCheck); } *pbRes = bRes; @@ -182946,44 +182946,44 @@ static int fts3IsAppendable(Fts3Table *p, tdsqlite3_int64 iEnd, int *pbRes){ */ static int fts3IncrmergeLoad( Fts3Table *p, /* Fts3 table handle */ - tdsqlite3_int64 iAbsLevel, /* Absolute level of input segments */ + sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ int iIdx, /* Index of candidate output segment */ const char *zKey, /* First key to write */ int nKey, /* Number of bytes in nKey */ IncrmergeWriter *pWriter /* Populate this object */ ){ int rc; /* Return code */ - tdsqlite3_stmt *pSelect = 0; /* SELECT to read %_segdir entry */ + sqlite3_stmt *pSelect = 0; /* SELECT to read %_segdir entry */ rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pSelect, 0); if( rc==SQLITE_OK ){ - tdsqlite3_int64 iStart = 0; /* Value of %_segdir.start_block */ - tdsqlite3_int64 iLeafEnd = 0; /* Value of %_segdir.leaves_end_block */ - tdsqlite3_int64 iEnd = 0; /* Value of %_segdir.end_block */ + sqlite3_int64 iStart = 0; /* Value of %_segdir.start_block */ + sqlite3_int64 iLeafEnd = 0; /* Value of %_segdir.leaves_end_block */ + sqlite3_int64 iEnd = 0; /* Value of %_segdir.end_block */ const char *aRoot = 0; /* Pointer to %_segdir.root buffer */ int nRoot = 0; /* Size of aRoot[] in bytes */ - int rc2; /* Return code from tdsqlite3_reset() */ + int rc2; /* Return code from sqlite3_reset() */ int bAppendable = 0; /* Set to true if segment is appendable */ /* Read the %_segdir entry for index iIdx absolute level (iAbsLevel+1) */ - tdsqlite3_bind_int64(pSelect, 1, iAbsLevel+1); - tdsqlite3_bind_int(pSelect, 2, iIdx); - if( tdsqlite3_step(pSelect)==SQLITE_ROW ){ - iStart = tdsqlite3_column_int64(pSelect, 1); - iLeafEnd = tdsqlite3_column_int64(pSelect, 2); + sqlite3_bind_int64(pSelect, 1, iAbsLevel+1); + sqlite3_bind_int(pSelect, 2, iIdx); + if( sqlite3_step(pSelect)==SQLITE_ROW ){ + iStart = sqlite3_column_int64(pSelect, 1); + iLeafEnd = sqlite3_column_int64(pSelect, 2); fts3ReadEndBlockField(pSelect, 3, &iEnd, &pWriter->nLeafData); if( pWriter->nLeafData<0 ){ pWriter->nLeafData = pWriter->nLeafData * -1; } pWriter->bNoLeafData = (pWriter->nLeafData==0); - nRoot = tdsqlite3_column_bytes(pSelect, 4); - aRoot = tdsqlite3_column_blob(pSelect, 4); + nRoot = sqlite3_column_bytes(pSelect, 4); + aRoot = sqlite3_column_blob(pSelect, 4); if( aRoot==0 ){ - tdsqlite3_reset(pSelect); + sqlite3_reset(pSelect); return nRoot ? SQLITE_NOMEM : FTS_CORRUPT_VTAB; } }else{ - return tdsqlite3_reset(pSelect); + return sqlite3_reset(pSelect); } /* Check for the zero-length marker in the %_segments table */ @@ -182994,7 +182994,7 @@ static int fts3IncrmergeLoad( char *aLeaf = 0; int nLeaf = 0; - rc = tdsqlite3Fts3ReadBlock(p, iLeafEnd, &aLeaf, &nLeaf, 0); + rc = sqlite3Fts3ReadBlock(p, iLeafEnd, &aLeaf, &nLeaf, 0); if( rc==SQLITE_OK ){ NodeReader reader; for(rc = nodeReaderInit(&reader, aLeaf, nLeaf); @@ -183008,7 +183008,7 @@ static int fts3IncrmergeLoad( } nodeReaderRelease(&reader); } - tdsqlite3_free(aLeaf); + sqlite3_free(aLeaf); } if( rc==SQLITE_OK && bAppendable ){ @@ -183018,7 +183018,7 @@ static int fts3IncrmergeLoad( int nHeight = (int)aRoot[0]; NodeWriter *pNode; if( nHeight<1 || nHeight>FTS_MAX_APPENDABLE_HEIGHT ){ - tdsqlite3_reset(pSelect); + sqlite3_reset(pSelect); return FTS_CORRUPT_VTAB; } @@ -183059,7 +183059,7 @@ static int fts3IncrmergeLoad( int nBlock = 0; pNode = &pWriter->aNodeWriter[i-1]; pNode->iBlock = reader.iChild; - rc = tdsqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0); + rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock, 0); blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc ); @@ -183068,7 +183068,7 @@ static int fts3IncrmergeLoad( pNode->block.n = nBlock; memset(&pNode->block.a[nBlock], 0, FTS3_NODE_PADDING); } - tdsqlite3_free(aBlock); + sqlite3_free(aBlock); } } } @@ -183076,7 +183076,7 @@ static int fts3IncrmergeLoad( } } - rc2 = tdsqlite3_reset(pSelect); + rc2 = sqlite3_reset(pSelect); if( rc==SQLITE_OK ) rc = rc2; } @@ -183094,18 +183094,18 @@ static int fts3IncrmergeLoad( */ static int fts3IncrmergeOutputIdx( Fts3Table *p, /* FTS Table handle */ - tdsqlite3_int64 iAbsLevel, /* Absolute index of input segments */ + sqlite3_int64 iAbsLevel, /* Absolute index of input segments */ int *piIdx /* OUT: Next free index at iAbsLevel+1 */ ){ int rc; - tdsqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */ + sqlite3_stmt *pOutputIdx = 0; /* SQL used to find output index */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENT_INDEX, &pOutputIdx, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pOutputIdx, 1, iAbsLevel+1); - tdsqlite3_step(pOutputIdx); - *piIdx = tdsqlite3_column_int(pOutputIdx, 0); - rc = tdsqlite3_reset(pOutputIdx); + sqlite3_bind_int64(pOutputIdx, 1, iAbsLevel+1); + sqlite3_step(pOutputIdx); + *piIdx = sqlite3_column_int(pOutputIdx, 0); + rc = sqlite3_reset(pOutputIdx); } return rc; @@ -183139,7 +183139,7 @@ static int fts3IncrmergeOutputIdx( */ static int fts3IncrmergeWriter( Fts3Table *p, /* Fts3 table handle */ - tdsqlite3_int64 iAbsLevel, /* Absolute level of input segments */ + sqlite3_int64 iAbsLevel, /* Absolute level of input segments */ int iIdx, /* Index of new output segment */ Fts3MultiSegReader *pCsr, /* Cursor that data will be read from */ IncrmergeWriter *pWriter /* Populate this object */ @@ -183147,30 +183147,30 @@ static int fts3IncrmergeWriter( int rc; /* Return Code */ int i; /* Iterator variable */ int nLeafEst = 0; /* Blocks allocated for leaf nodes */ - tdsqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */ - tdsqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */ + sqlite3_stmt *pLeafEst = 0; /* SQL used to determine nLeafEst */ + sqlite3_stmt *pFirstBlock = 0; /* SQL used to determine first block */ /* Calculate nLeafEst. */ rc = fts3SqlStmt(p, SQL_MAX_LEAF_NODE_ESTIMATE, &pLeafEst, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pLeafEst, 1, iAbsLevel); - tdsqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment); - if( SQLITE_ROW==tdsqlite3_step(pLeafEst) ){ - nLeafEst = tdsqlite3_column_int(pLeafEst, 0); + sqlite3_bind_int64(pLeafEst, 1, iAbsLevel); + sqlite3_bind_int64(pLeafEst, 2, pCsr->nSegment); + if( SQLITE_ROW==sqlite3_step(pLeafEst) ){ + nLeafEst = sqlite3_column_int(pLeafEst, 0); } - rc = tdsqlite3_reset(pLeafEst); + rc = sqlite3_reset(pLeafEst); } if( rc!=SQLITE_OK ) return rc; /* Calculate the first block to use in the output segment */ rc = fts3SqlStmt(p, SQL_NEXT_SEGMENTS_ID, &pFirstBlock, 0); if( rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pFirstBlock) ){ - pWriter->iStart = tdsqlite3_column_int64(pFirstBlock, 0); + if( SQLITE_ROW==sqlite3_step(pFirstBlock) ){ + pWriter->iStart = sqlite3_column_int64(pFirstBlock, 0); pWriter->iEnd = pWriter->iStart - 1; pWriter->iEnd += nLeafEst * FTS_MAX_APPENDABLE_HEIGHT; } - rc = tdsqlite3_reset(pFirstBlock); + rc = sqlite3_reset(pFirstBlock); } if( rc!=SQLITE_OK ) return rc; @@ -183204,18 +183204,18 @@ static int fts3IncrmergeWriter( */ static int fts3RemoveSegdirEntry( Fts3Table *p, /* FTS3 table handle */ - tdsqlite3_int64 iAbsLevel, /* Absolute level to delete from */ + sqlite3_int64 iAbsLevel, /* Absolute level to delete from */ int iIdx /* Index of %_segdir entry to delete */ ){ int rc; /* Return code */ - tdsqlite3_stmt *pDelete = 0; /* DELETE statement */ + sqlite3_stmt *pDelete = 0; /* DELETE statement */ rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_ENTRY, &pDelete, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pDelete, 1, iAbsLevel); - tdsqlite3_bind_int(pDelete, 2, iIdx); - tdsqlite3_step(pDelete); - rc = tdsqlite3_reset(pDelete); + sqlite3_bind_int64(pDelete, 1, iAbsLevel); + sqlite3_bind_int(pDelete, 2, iIdx); + sqlite3_step(pDelete); + rc = sqlite3_reset(pDelete); } return rc; @@ -183228,34 +183228,34 @@ static int fts3RemoveSegdirEntry( */ static int fts3RepackSegdirLevel( Fts3Table *p, /* FTS3 table handle */ - tdsqlite3_int64 iAbsLevel /* Absolute level to repack */ + sqlite3_int64 iAbsLevel /* Absolute level to repack */ ){ int rc; /* Return code */ int *aIdx = 0; /* Array of remaining idx values */ int nIdx = 0; /* Valid entries in aIdx[] */ int nAlloc = 0; /* Allocated size of aIdx[] */ int i; /* Iterator variable */ - tdsqlite3_stmt *pSelect = 0; /* Select statement to read idx values */ - tdsqlite3_stmt *pUpdate = 0; /* Update statement to modify idx values */ + sqlite3_stmt *pSelect = 0; /* Select statement to read idx values */ + sqlite3_stmt *pUpdate = 0; /* Update statement to modify idx values */ rc = fts3SqlStmt(p, SQL_SELECT_INDEXES, &pSelect, 0); if( rc==SQLITE_OK ){ int rc2; - tdsqlite3_bind_int64(pSelect, 1, iAbsLevel); - while( SQLITE_ROW==tdsqlite3_step(pSelect) ){ + sqlite3_bind_int64(pSelect, 1, iAbsLevel); + while( SQLITE_ROW==sqlite3_step(pSelect) ){ if( nIdx>=nAlloc ){ int *aNew; nAlloc += 16; - aNew = tdsqlite3_realloc(aIdx, nAlloc*sizeof(int)); + aNew = sqlite3_realloc(aIdx, nAlloc*sizeof(int)); if( !aNew ){ rc = SQLITE_NOMEM; break; } aIdx = aNew; } - aIdx[nIdx++] = tdsqlite3_column_int(pSelect, 0); + aIdx[nIdx++] = sqlite3_column_int(pSelect, 0); } - rc2 = tdsqlite3_reset(pSelect); + rc2 = sqlite3_reset(pSelect); if( rc==SQLITE_OK ) rc = rc2; } @@ -183263,30 +183263,30 @@ static int fts3RepackSegdirLevel( rc = fts3SqlStmt(p, SQL_SHIFT_SEGDIR_ENTRY, &pUpdate, 0); } if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pUpdate, 2, iAbsLevel); + sqlite3_bind_int64(pUpdate, 2, iAbsLevel); } assert( p->bIgnoreSavepoint==0 ); p->bIgnoreSavepoint = 1; for(i=0; rc==SQLITE_OK && ibIgnoreSavepoint = 0; - tdsqlite3_free(aIdx); + sqlite3_free(aIdx); return rc; } -static void fts3StartNode(Blob *pNode, int iHeight, tdsqlite3_int64 iChild){ +static void fts3StartNode(Blob *pNode, int iHeight, sqlite3_int64 iChild){ pNode->a[0] = (char)iHeight; if( iChild ){ - assert( pNode->nAlloc>=1+tdsqlite3Fts3VarintLen(iChild) ); - pNode->n = 1 + tdsqlite3Fts3PutVarint(&pNode->a[1], iChild); + assert( pNode->nAlloc>=1+sqlite3Fts3VarintLen(iChild) ); + pNode->n = 1 + sqlite3Fts3PutVarint(&pNode->a[1], iChild); }else{ assert( pNode->nAlloc>=1 ); pNode->n = 1; @@ -183307,7 +183307,7 @@ static int fts3TruncateNode( Blob *pNew, /* OUT: Write new node image here */ const char *zTerm, /* Omit all terms smaller than this */ int nTerm, /* Size of zTerm in bytes */ - tdsqlite3_int64 *piBlock /* OUT: Block number in next layer down */ + sqlite3_int64 *piBlock /* OUT: Block number in next layer down */ ){ NodeReader reader; /* Reader object */ Blob prev = {0, 0, 0}; /* Previous term written to new node */ @@ -183346,7 +183346,7 @@ static int fts3TruncateNode( assert( pNew->n<=pNew->nAlloc ); nodeReaderRelease(&reader); - tdsqlite3_free(prev.a); + sqlite3_free(prev.a); return rc; } @@ -183361,7 +183361,7 @@ static int fts3TruncateNode( */ static int fts3TruncateSegment( Fts3Table *p, /* FTS3 table handle */ - tdsqlite3_int64 iAbsLevel, /* Absolute level of segment to modify */ + sqlite3_int64 iAbsLevel, /* Absolute level of segment to modify */ int iIdx, /* Index within level of segment to modify */ const char *zTerm, /* Remove terms smaller than this */ int nTerm /* Number of bytes in buffer zTerm */ @@ -183369,23 +183369,23 @@ static int fts3TruncateSegment( int rc = SQLITE_OK; /* Return code */ Blob root = {0,0,0}; /* New root page image */ Blob block = {0,0,0}; /* Buffer used for any other block */ - tdsqlite3_int64 iBlock = 0; /* Block id */ - tdsqlite3_int64 iNewStart = 0; /* New value for iStartBlock */ - tdsqlite3_int64 iOldStart = 0; /* Old value for iStartBlock */ - tdsqlite3_stmt *pFetch = 0; /* Statement used to fetch segdir */ + sqlite3_int64 iBlock = 0; /* Block id */ + sqlite3_int64 iNewStart = 0; /* New value for iStartBlock */ + sqlite3_int64 iOldStart = 0; /* Old value for iStartBlock */ + sqlite3_stmt *pFetch = 0; /* Statement used to fetch segdir */ rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR, &pFetch, 0); if( rc==SQLITE_OK ){ - int rc2; /* tdsqlite3_reset() return code */ - tdsqlite3_bind_int64(pFetch, 1, iAbsLevel); - tdsqlite3_bind_int(pFetch, 2, iIdx); - if( SQLITE_ROW==tdsqlite3_step(pFetch) ){ - const char *aRoot = tdsqlite3_column_blob(pFetch, 4); - int nRoot = tdsqlite3_column_bytes(pFetch, 4); - iOldStart = tdsqlite3_column_int64(pFetch, 1); + int rc2; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pFetch, 1, iAbsLevel); + sqlite3_bind_int(pFetch, 2, iIdx); + if( SQLITE_ROW==sqlite3_step(pFetch) ){ + const char *aRoot = sqlite3_column_blob(pFetch, 4); + int nRoot = sqlite3_column_bytes(pFetch, 4); + iOldStart = sqlite3_column_int64(pFetch, 1); rc = fts3TruncateNode(aRoot, nRoot, &root, zTerm, nTerm, &iBlock); } - rc2 = tdsqlite3_reset(pFetch); + rc2 = sqlite3_reset(pFetch); if( rc==SQLITE_OK ) rc = rc2; } @@ -183394,44 +183394,44 @@ static int fts3TruncateSegment( int nBlock = 0; iNewStart = iBlock; - rc = tdsqlite3Fts3ReadBlock(p, iBlock, &aBlock, &nBlock, 0); + rc = sqlite3Fts3ReadBlock(p, iBlock, &aBlock, &nBlock, 0); if( rc==SQLITE_OK ){ rc = fts3TruncateNode(aBlock, nBlock, &block, zTerm, nTerm, &iBlock); } if( rc==SQLITE_OK ){ rc = fts3WriteSegment(p, iNewStart, block.a, block.n); } - tdsqlite3_free(aBlock); + sqlite3_free(aBlock); } /* Variable iNewStart now contains the first valid leaf node. */ if( rc==SQLITE_OK && iNewStart ){ - tdsqlite3_stmt *pDel = 0; + sqlite3_stmt *pDel = 0; rc = fts3SqlStmt(p, SQL_DELETE_SEGMENTS_RANGE, &pDel, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pDel, 1, iOldStart); - tdsqlite3_bind_int64(pDel, 2, iNewStart-1); - tdsqlite3_step(pDel); - rc = tdsqlite3_reset(pDel); + sqlite3_bind_int64(pDel, 1, iOldStart); + sqlite3_bind_int64(pDel, 2, iNewStart-1); + sqlite3_step(pDel); + rc = sqlite3_reset(pDel); } } if( rc==SQLITE_OK ){ - tdsqlite3_stmt *pChomp = 0; + sqlite3_stmt *pChomp = 0; rc = fts3SqlStmt(p, SQL_CHOMP_SEGDIR, &pChomp, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pChomp, 1, iNewStart); - tdsqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC); - tdsqlite3_bind_int64(pChomp, 3, iAbsLevel); - tdsqlite3_bind_int(pChomp, 4, iIdx); - tdsqlite3_step(pChomp); - rc = tdsqlite3_reset(pChomp); - tdsqlite3_bind_null(pChomp, 2); + sqlite3_bind_int64(pChomp, 1, iNewStart); + sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC); + sqlite3_bind_int64(pChomp, 3, iAbsLevel); + sqlite3_bind_int(pChomp, 4, iIdx); + sqlite3_step(pChomp); + rc = sqlite3_reset(pChomp); + sqlite3_bind_null(pChomp, 2); } } - tdsqlite3_free(root.a); - tdsqlite3_free(block.a); + sqlite3_free(root.a); + sqlite3_free(block.a); return rc; } @@ -183447,7 +183447,7 @@ static int fts3TruncateSegment( */ static int fts3IncrmergeChomp( Fts3Table *p, /* FTS table handle */ - tdsqlite3_int64 iAbsLevel, /* Absolute level containing segments */ + sqlite3_int64 iAbsLevel, /* Absolute level containing segments */ Fts3MultiSegReader *pCsr, /* Chomp all segments opened by this cursor */ int *pnRem /* Number of segments not deleted */ ){ @@ -183497,16 +183497,16 @@ static int fts3IncrmergeChomp( ** Store an incr-merge hint in the database. */ static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){ - tdsqlite3_stmt *pReplace = 0; + sqlite3_stmt *pReplace = 0; int rc; /* Return code */ rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pReplace, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT); - tdsqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); - tdsqlite3_step(pReplace); - rc = tdsqlite3_reset(pReplace); - tdsqlite3_bind_null(pReplace, 2); + sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT); + sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } return rc; @@ -183521,17 +183521,17 @@ static int fts3IncrmergeHintStore(Fts3Table *p, Blob *pHint){ ** SQLite error code. */ static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){ - tdsqlite3_stmt *pSelect = 0; + sqlite3_stmt *pSelect = 0; int rc; pHint->n = 0; rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pSelect, 0); if( rc==SQLITE_OK ){ int rc2; - tdsqlite3_bind_int(pSelect, 1, FTS_STAT_INCRMERGEHINT); - if( SQLITE_ROW==tdsqlite3_step(pSelect) ){ - const char *aHint = tdsqlite3_column_blob(pSelect, 0); - int nHint = tdsqlite3_column_bytes(pSelect, 0); + sqlite3_bind_int(pSelect, 1, FTS_STAT_INCRMERGEHINT); + if( SQLITE_ROW==sqlite3_step(pSelect) ){ + const char *aHint = sqlite3_column_blob(pSelect, 0); + int nHint = sqlite3_column_bytes(pSelect, 0); if( aHint ){ blobGrowBuffer(pHint, nHint, &rc); if( rc==SQLITE_OK ){ @@ -183540,7 +183540,7 @@ static int fts3IncrmergeHintLoad(Fts3Table *p, Blob *pHint){ } } } - rc2 = tdsqlite3_reset(pSelect); + rc2 = sqlite3_reset(pSelect); if( rc==SQLITE_OK ) rc = rc2; } @@ -183564,8 +183564,8 @@ static void fts3IncrmergeHintPush( ){ blobGrowBuffer(pHint, pHint->n + 2*FTS3_VARINT_MAX, pRc); if( *pRc==SQLITE_OK ){ - pHint->n += tdsqlite3Fts3PutVarint(&pHint->a[pHint->n], iAbsLevel); - pHint->n += tdsqlite3Fts3PutVarint(&pHint->a[pHint->n], (i64)nInput); + pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], iAbsLevel); + pHint->n += sqlite3Fts3PutVarint(&pHint->a[pHint->n], (i64)nInput); } } @@ -183589,7 +183589,7 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; - i += tdsqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); + i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); assert( i<=nHint ); if( i!=nHint ) return FTS_CORRUPT_VTAB; @@ -183607,20 +183607,20 @@ static int fts3IncrmergeHintPop(Blob *pHint, i64 *piAbsLevel, int *pnInput){ ** at least nMin segments. Multiple merges might occur in an attempt to ** write the quota of nMerge leaf blocks. */ -SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ +SQLITE_PRIVATE int sqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ int rc; /* Return code */ int nRem = nMerge; /* Number of leaf pages yet to be written */ Fts3MultiSegReader *pCsr; /* Cursor used to read input data */ Fts3SegFilter *pFilter; /* Filter used with cursor pCsr */ IncrmergeWriter *pWriter; /* Writer object */ int nSeg = 0; /* Number of input segments */ - tdsqlite3_int64 iAbsLevel = 0; /* Absolute level number to work on */ + sqlite3_int64 iAbsLevel = 0; /* Absolute level number to work on */ Blob hint = {0, 0, 0}; /* Hint read from %_stat table */ int bDirtyHint = 0; /* True if blob 'hint' has been modified */ /* Allocate space for the cursor, filter and writer objects */ const int nAlloc = sizeof(*pCsr) + sizeof(*pFilter) + sizeof(*pWriter); - pWriter = (IncrmergeWriter *)tdsqlite3_malloc(nAlloc); + pWriter = (IncrmergeWriter *)sqlite3_malloc(nAlloc); if( !pWriter ) return SQLITE_NOMEM; pFilter = (Fts3SegFilter *)&pWriter[1]; pCsr = (Fts3MultiSegReader *)&pFilter[1]; @@ -183628,7 +183628,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ rc = fts3IncrmergeHintLoad(p, &hint); while( rc==SQLITE_OK && nRem>0 ){ const i64 nMod = FTS3_SEGDIR_MAXLEVEL * p->nIndex; - tdsqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ + sqlite3_stmt *pFindLevel = 0; /* SQL used to determine iAbsLevel */ int bUseHint = 0; /* True if attempting to append */ int iIdx = 0; /* Largest idx in level (iAbsLevel+1) */ @@ -183639,15 +183639,15 @@ SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ ** set nSeg to -1. */ rc = fts3SqlStmt(p, SQL_FIND_MERGE_LEVEL, &pFindLevel, 0); - tdsqlite3_bind_int(pFindLevel, 1, MAX(2, nMin)); - if( tdsqlite3_step(pFindLevel)==SQLITE_ROW ){ - iAbsLevel = tdsqlite3_column_int64(pFindLevel, 0); - nSeg = tdsqlite3_column_int(pFindLevel, 1); + sqlite3_bind_int(pFindLevel, 1, MAX(2, nMin)); + if( sqlite3_step(pFindLevel)==SQLITE_ROW ){ + iAbsLevel = sqlite3_column_int64(pFindLevel, 0); + nSeg = sqlite3_column_int(pFindLevel, 1); assert( nSeg>=2 ); }else{ nSeg = -1; } - rc = tdsqlite3_reset(pFindLevel); + rc = sqlite3_reset(pFindLevel); /* If the hint read from the %_stat table is not empty, check if the ** last entry in it specifies a relative level smaller than or equal @@ -183656,7 +183656,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ */ if( rc==SQLITE_OK && hint.n ){ int nHint = hint.n; - tdsqlite3_int64 iHintAbsLevel = 0; /* Hint level */ + sqlite3_int64 iHintAbsLevel = 0; /* Hint level */ int nHintSeg = 0; /* Hint number of segments */ rc = fts3IncrmergeHintPop(&hint, &iHintAbsLevel, &nHintSeg); @@ -183708,14 +183708,14 @@ SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ rc = fts3IncrmergeCsr(p, iAbsLevel, nSeg, pCsr); } if( SQLITE_OK==rc && pCsr->nSegment==nSeg - && SQLITE_OK==(rc = tdsqlite3Fts3SegReaderStart(p, pCsr, pFilter)) + && SQLITE_OK==(rc = sqlite3Fts3SegReaderStart(p, pCsr, pFilter)) ){ int bEmpty = 0; - rc = tdsqlite3Fts3SegReaderStep(p, pCsr); + rc = sqlite3Fts3SegReaderStep(p, pCsr); if( rc==SQLITE_OK ){ bEmpty = 1; }else if( rc!=SQLITE_ROW ){ - tdsqlite3Fts3SegReaderFinish(pCsr); + sqlite3Fts3SegReaderFinish(pCsr); break; } if( bUseHint && iIdx>0 ){ @@ -183731,7 +183731,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ if( bEmpty==0 ){ do { rc = fts3IncrmergeAppend(p, pWriter, pCsr); - if( rc==SQLITE_OK ) rc = tdsqlite3Fts3SegReaderStep(p, pCsr); + if( rc==SQLITE_OK ) rc = sqlite3Fts3SegReaderStep(p, pCsr); if( pWriter->nWork>=nRem && rc==SQLITE_ROW ) rc = SQLITE_OK; }while( rc==SQLITE_ROW ); } @@ -183756,7 +183756,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ } } - tdsqlite3Fts3SegReaderFinish(pCsr); + sqlite3Fts3SegReaderFinish(pCsr); } /* Write the hint values into the %_stat table for the next incr-merger */ @@ -183764,8 +183764,8 @@ SQLITE_PRIVATE int tdsqlite3Fts3Incrmerge(Fts3Table *p, int nMerge, int nMin){ rc = fts3IncrmergeHintStore(p, &hint); } - tdsqlite3_free(pWriter); - tdsqlite3_free(hint.a); + sqlite3_free(pWriter); + sqlite3_free(hint.a); return rc; } @@ -183819,12 +183819,12 @@ static int fts3DoIncrmerge( rc = SQLITE_OK; if( !p->bHasStat ){ assert( p->bFts4==0 ); - tdsqlite3Fts3CreateStatTable(&rc, p); + sqlite3Fts3CreateStatTable(&rc, p); } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts3Incrmerge(p, nMerge, nMin); + rc = sqlite3Fts3Incrmerge(p, nMerge, nMin); } - tdsqlite3Fts3SegmentsClose(p); + sqlite3Fts3SegmentsClose(p); } return rc; } @@ -183842,22 +183842,22 @@ static int fts3DoAutoincrmerge( const char *zParam /* Nul-terminated string containing boolean */ ){ int rc = SQLITE_OK; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; p->nAutoincrmerge = fts3Getint(&zParam); if( p->nAutoincrmerge==1 || p->nAutoincrmerge>MergeCount(p) ){ p->nAutoincrmerge = 8; } if( !p->bHasStat ){ assert( p->bFts4==0 ); - tdsqlite3Fts3CreateStatTable(&rc, p); + sqlite3Fts3CreateStatTable(&rc, p); if( rc ) return rc; } rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pStmt, 0); if( rc ) return rc; - tdsqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); - tdsqlite3_bind_int(pStmt, 2, p->nAutoincrmerge); - tdsqlite3_step(pStmt); - rc = tdsqlite3_reset(pStmt); + sqlite3_bind_int(pStmt, 1, FTS_STAT_AUTOINCRMERGE); + sqlite3_bind_int(pStmt, 2, p->nAutoincrmerge); + sqlite3_step(pStmt); + rc = sqlite3_reset(pStmt); return rc; } @@ -183913,15 +183913,15 @@ static u64 fts3ChecksumIndex( filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY; filter.flags |= FTS3_SEGMENT_SCAN; - rc = tdsqlite3Fts3SegReaderCursor( + rc = sqlite3Fts3SegReaderCursor( p, iLangid, iIndex, FTS3_SEGCURSOR_ALL, 0, 0, 0, 1,&csr ); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts3SegReaderStart(p, &csr, &filter); + rc = sqlite3Fts3SegReaderStart(p, &csr, &filter); } if( rc==SQLITE_OK ){ - while( SQLITE_ROW==(rc = tdsqlite3Fts3SegReaderStep(p, &csr)) ){ + while( SQLITE_ROW==(rc = sqlite3Fts3SegReaderStep(p, &csr)) ){ char *pCsr = csr.aDoclist; char *pEnd = &pCsr[csr.nDoclist]; @@ -183929,18 +183929,18 @@ static u64 fts3ChecksumIndex( i64 iCol = 0; u64 iPos = 0; - pCsr += tdsqlite3Fts3GetVarint(pCsr, &iDocid); + pCsr += sqlite3Fts3GetVarint(pCsr, &iDocid); while( pCsrbDescIdx ){ iDocid = (i64)((u64)iDocid - iVal); }else{ @@ -183958,7 +183958,7 @@ static u64 fts3ChecksumIndex( } } } - tdsqlite3Fts3SegReaderFinish(&csr); + sqlite3Fts3SegReaderFinish(&csr); *pRc = rc; return cksum; @@ -183977,50 +183977,50 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ int rc = SQLITE_OK; /* Return code */ u64 cksum1 = 0; /* Checksum based on FTS index contents */ u64 cksum2 = 0; /* Checksum based on %_content contents */ - tdsqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ + sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ /* This block calculates the checksum according to the FTS index. */ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ int rc2; - tdsqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); - tdsqlite3_bind_int(pAllLangid, 2, p->nIndex); - while( rc==SQLITE_OK && tdsqlite3_step(pAllLangid)==SQLITE_ROW ){ - int iLangid = tdsqlite3_column_int(pAllLangid, 0); + sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); + sqlite3_bind_int(pAllLangid, 2, p->nIndex); + while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ + int iLangid = sqlite3_column_int(pAllLangid, 0); int i; for(i=0; inIndex; i++){ cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc); } } - rc2 = tdsqlite3_reset(pAllLangid); + rc2 = sqlite3_reset(pAllLangid); if( rc==SQLITE_OK ) rc = rc2; } /* This block calculates the checksum according to the %_content table */ if( rc==SQLITE_OK ){ - tdsqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; - tdsqlite3_stmt *pStmt = 0; + sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; + sqlite3_stmt *pStmt = 0; char *zSql; - zSql = tdsqlite3_mprintf("SELECT %s" , p->zReadExprlist); + zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); if( !zSql ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); - tdsqlite3_free(zSql); + rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0); + sqlite3_free(zSql); } - while( rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pStmt) ){ - i64 iDocid = tdsqlite3_column_int64(pStmt, 0); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + i64 iDocid = sqlite3_column_int64(pStmt, 0); int iLang = langidFromSelect(p, pStmt); int iCol; for(iCol=0; rc==SQLITE_OK && iColnColumn; iCol++){ if( p->abNotindexed[iCol]==0 ){ - const char *zText = (const char *)tdsqlite3_column_text(pStmt, iCol+1); - tdsqlite3_tokenizer_cursor *pT = 0; + const char *zText = (const char *)sqlite3_column_text(pStmt, iCol+1); + sqlite3_tokenizer_cursor *pT = 0; - rc = tdsqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, -1, &pT); + rc = sqlite3Fts3OpenTokenizer(p->pTokenizer, iLang, zText, -1, &pT); while( rc==SQLITE_OK ){ char const *zToken; /* Buffer containing token */ int nToken = 0; /* Number of bytes in token */ @@ -184048,7 +184048,7 @@ static int fts3IntegrityCheck(Fts3Table *p, int *pbOk){ } } - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); } *pbOk = (cksum1==cksum2); @@ -184104,38 +184104,38 @@ static int fts3DoIntegrityCheck( ** Argument pVal contains the result of . Currently the only ** meaningful value to insert is the text 'optimize'. */ -static int fts3SpecialInsert(Fts3Table *p, tdsqlite3_value *pVal){ +static int fts3SpecialInsert(Fts3Table *p, sqlite3_value *pVal){ int rc = SQLITE_ERROR; /* Return Code */ - const char *zVal = (const char *)tdsqlite3_value_text(pVal); - int nVal = tdsqlite3_value_bytes(pVal); + const char *zVal = (const char *)sqlite3_value_text(pVal); + int nVal = sqlite3_value_bytes(pVal); if( !zVal ){ return SQLITE_NOMEM; - }else if( nVal==8 && 0==tdsqlite3_strnicmp(zVal, "optimize", 8) ){ + }else if( nVal==8 && 0==sqlite3_strnicmp(zVal, "optimize", 8) ){ rc = fts3DoOptimize(p, 0); - }else if( nVal==7 && 0==tdsqlite3_strnicmp(zVal, "rebuild", 7) ){ + }else if( nVal==7 && 0==sqlite3_strnicmp(zVal, "rebuild", 7) ){ rc = fts3DoRebuild(p); - }else if( nVal==15 && 0==tdsqlite3_strnicmp(zVal, "integrity-check", 15) ){ + }else if( nVal==15 && 0==sqlite3_strnicmp(zVal, "integrity-check", 15) ){ rc = fts3DoIntegrityCheck(p); - }else if( nVal>6 && 0==tdsqlite3_strnicmp(zVal, "merge=", 6) ){ + }else if( nVal>6 && 0==sqlite3_strnicmp(zVal, "merge=", 6) ){ rc = fts3DoIncrmerge(p, &zVal[6]); - }else if( nVal>10 && 0==tdsqlite3_strnicmp(zVal, "automerge=", 10) ){ + }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ rc = fts3DoAutoincrmerge(p, &zVal[10]); #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) }else{ int v; - if( nVal>9 && 0==tdsqlite3_strnicmp(zVal, "nodesize=", 9) ){ + if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ v = atoi(&zVal[9]); if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v; rc = SQLITE_OK; - }else if( nVal>11 && 0==tdsqlite3_strnicmp(zVal, "maxpending=", 9) ){ + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 9) ){ v = atoi(&zVal[11]); if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v; rc = SQLITE_OK; - }else if( nVal>21 && 0==tdsqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){ + }else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){ p->bNoIncrDoclist = atoi(&zVal[21]); rc = SQLITE_OK; - }else if( nVal>11 && 0==tdsqlite3_strnicmp(zVal,"mergecount=",11) ){ + }else if( nVal>11 && 0==sqlite3_strnicmp(zVal,"mergecount=",11) ){ v = atoi(&zVal[11]); if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; rc = SQLITE_OK; @@ -184148,9 +184148,9 @@ static int fts3SpecialInsert(Fts3Table *p, tdsqlite3_value *pVal){ #ifndef SQLITE_DISABLE_FTS4_DEFERRED /* ** Delete all cached deferred doclists. Deferred doclists are cached -** (allocated) by the tdsqlite3Fts3CacheDeferredDoclists() function. +** (allocated) by the sqlite3Fts3CacheDeferredDoclists() function. */ -SQLITE_PRIVATE void tdsqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){ Fts3DeferredToken *pDef; for(pDef=pCsr->pDeferred; pDef; pDef=pDef->pNext){ fts3PendingListDelete(pDef->pList); @@ -184160,15 +184160,15 @@ SQLITE_PRIVATE void tdsqlite3Fts3FreeDeferredDoclists(Fts3Cursor *pCsr){ /* ** Free all entries in the pCsr->pDeffered list. Entries are added to -** this list using tdsqlite3Fts3DeferToken(). +** this list using sqlite3Fts3DeferToken(). */ -SQLITE_PRIVATE void tdsqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ +SQLITE_PRIVATE void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ Fts3DeferredToken *pDef; Fts3DeferredToken *pNext; for(pDef=pCsr->pDeferred; pDef; pDef=pNext){ pNext = pDef->pNext; fts3PendingListDelete(pDef->pList); - tdsqlite3_free(pDef); + sqlite3_free(pDef); } pCsr->pDeferred = 0; } @@ -184181,26 +184181,26 @@ SQLITE_PRIVATE void tdsqlite3Fts3FreeDeferredTokens(Fts3Cursor *pCsr){ ** included, except that it only contains entries for a single row of the ** table, not for all rows. */ -SQLITE_PRIVATE int tdsqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ +SQLITE_PRIVATE int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ int rc = SQLITE_OK; /* Return code */ if( pCsr->pDeferred ){ int i; /* Used to iterate through table columns */ - tdsqlite3_int64 iDocid; /* Docid of the row pCsr points to */ + sqlite3_int64 iDocid; /* Docid of the row pCsr points to */ Fts3DeferredToken *pDef; /* Used to iterate through deferred tokens */ Fts3Table *p = (Fts3Table *)pCsr->base.pVtab; - tdsqlite3_tokenizer *pT = p->pTokenizer; - tdsqlite3_tokenizer_module const *pModule = pT->pModule; + sqlite3_tokenizer *pT = p->pTokenizer; + sqlite3_tokenizer_module const *pModule = pT->pModule; assert( pCsr->isRequireSeek==0 ); - iDocid = tdsqlite3_column_int64(pCsr->pStmt, 0); + iDocid = sqlite3_column_int64(pCsr->pStmt, 0); for(i=0; inColumn && rc==SQLITE_OK; i++){ if( p->abNotindexed[i]==0 ){ - const char *zText = (const char *)tdsqlite3_column_text(pCsr->pStmt, i+1); - tdsqlite3_tokenizer_cursor *pTC = 0; + const char *zText = (const char *)sqlite3_column_text(pCsr->pStmt, i+1); + sqlite3_tokenizer_cursor *pTC = 0; - rc = tdsqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); + rc = sqlite3Fts3OpenTokenizer(pT, pCsr->iLangid, zText, -1, &pTC); while( rc==SQLITE_OK ){ char const *zToken; /* Buffer containing token */ int nToken = 0; /* Number of bytes in token */ @@ -184234,14 +184234,14 @@ SQLITE_PRIVATE int tdsqlite3Fts3CacheDeferredDoclists(Fts3Cursor *pCsr){ return rc; } -SQLITE_PRIVATE int tdsqlite3Fts3DeferredTokenList( +SQLITE_PRIVATE int sqlite3Fts3DeferredTokenList( Fts3DeferredToken *p, char **ppData, int *pnData ){ char *pRet; int nSkip; - tdsqlite3_int64 dummy; + sqlite3_int64 dummy; *ppData = 0; *pnData = 0; @@ -184250,10 +184250,10 @@ SQLITE_PRIVATE int tdsqlite3Fts3DeferredTokenList( return SQLITE_OK; } - pRet = (char *)tdsqlite3_malloc(p->pList->nData); + pRet = (char *)sqlite3_malloc(p->pList->nData); if( !pRet ) return SQLITE_NOMEM; - nSkip = tdsqlite3Fts3GetVarint(p->pList->aData, &dummy); + nSkip = sqlite3Fts3GetVarint(p->pList->aData, &dummy); *pnData = p->pList->nData - nSkip; *ppData = pRet; @@ -184264,13 +184264,13 @@ SQLITE_PRIVATE int tdsqlite3Fts3DeferredTokenList( /* ** Add an entry for token pToken to the pCsr->pDeferred list. */ -SQLITE_PRIVATE int tdsqlite3Fts3DeferToken( +SQLITE_PRIVATE int sqlite3Fts3DeferToken( Fts3Cursor *pCsr, /* Fts3 table cursor */ Fts3PhraseToken *pToken, /* Token to defer */ int iCol /* Column that token must appear in (or -1) */ ){ Fts3DeferredToken *pDeferred; - pDeferred = tdsqlite3_malloc(sizeof(*pDeferred)); + pDeferred = sqlite3_malloc(sizeof(*pDeferred)); if( !pDeferred ){ return SQLITE_NOMEM; } @@ -184294,7 +184294,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3DeferToken( */ static int fts3DeleteByRowid( Fts3Table *p, - tdsqlite3_value *pRowid, + sqlite3_value *pRowid, int *pnChng, /* IN/OUT: Decrement if row is deleted */ u32 *aSzDel ){ @@ -184341,10 +184341,10 @@ static int fts3DeleteByRowid( ** ** */ -SQLITE_PRIVATE int tdsqlite3Fts3UpdateMethod( - tdsqlite3_vtab *pVtab, /* FTS3 vtab object */ +SQLITE_PRIVATE int sqlite3Fts3UpdateMethod( + sqlite3_vtab *pVtab, /* FTS3 vtab object */ int nArg, /* Size of argument array */ - tdsqlite3_value **apVal, /* Array of arguments */ + sqlite3_value **apVal, /* Array of arguments */ sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ ){ Fts3Table *p = (Fts3Table *)pVtab; @@ -184369,20 +184369,20 @@ SQLITE_PRIVATE int tdsqlite3Fts3UpdateMethod( ** INSERT INTO xyz(xyz) VALUES('command'); */ if( nArg>1 - && tdsqlite3_value_type(apVal[0])==SQLITE_NULL - && tdsqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL + && sqlite3_value_type(apVal[0])==SQLITE_NULL + && sqlite3_value_type(apVal[p->nColumn+2])!=SQLITE_NULL ){ rc = fts3SpecialInsert(p, apVal[p->nColumn+2]); goto update_out; } - if( nArg>1 && tdsqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){ + if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){ rc = SQLITE_CONSTRAINT; goto update_out; } /* Allocate space to hold the change in document sizes */ - aSzDel = tdsqlite3_malloc64(sizeof(aSzDel[0])*((tdsqlite3_int64)p->nColumn+1)*2); + aSzDel = sqlite3_malloc64(sizeof(aSzDel[0])*((sqlite3_int64)p->nColumn+1)*2); if( aSzDel==0 ){ rc = SQLITE_NOMEM; goto update_out; @@ -184404,14 +184404,14 @@ SQLITE_PRIVATE int tdsqlite3Fts3UpdateMethod( */ if( nArg>1 && p->zContentTbl==0 ){ /* Find the value object that holds the new rowid value. */ - tdsqlite3_value *pNewRowid = apVal[3+p->nColumn]; - if( tdsqlite3_value_type(pNewRowid)==SQLITE_NULL ){ + sqlite3_value *pNewRowid = apVal[3+p->nColumn]; + if( sqlite3_value_type(pNewRowid)==SQLITE_NULL ){ pNewRowid = apVal[1]; } - if( tdsqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( - tdsqlite3_value_type(apVal[0])==SQLITE_NULL - || tdsqlite3_value_int64(apVal[0])!=tdsqlite3_value_int64(pNewRowid) + if( sqlite3_value_type(pNewRowid)!=SQLITE_NULL && ( + sqlite3_value_type(apVal[0])==SQLITE_NULL + || sqlite3_value_int64(apVal[0])!=sqlite3_value_int64(pNewRowid) )){ /* The new rowid is not NULL (in this case the rowid will be ** automatically assigned and there is no chance of a conflict), and @@ -184430,7 +184430,7 @@ SQLITE_PRIVATE int tdsqlite3Fts3UpdateMethod( ** invoked, it will delete zero rows (since no row will have ** docid=$pNewRowid if $pNewRowid is not an integer value). */ - if( tdsqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){ + if( sqlite3_vtab_on_conflict(p->db)==SQLITE_REPLACE ){ rc = fts3DeleteByRowid(p, pNewRowid, &nChng, aSzDel); }else{ rc = fts3InsertData(p, apVal, pRowid); @@ -184443,14 +184443,14 @@ SQLITE_PRIVATE int tdsqlite3Fts3UpdateMethod( } /* If this is a DELETE or UPDATE operation, remove the old record. */ - if( tdsqlite3_value_type(apVal[0])!=SQLITE_NULL ){ - assert( tdsqlite3_value_type(apVal[0])==SQLITE_INTEGER ); + if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){ + assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ); rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel); } /* If this is an INSERT or UPDATE operation, insert the new record. */ if( nArg>1 && rc==SQLITE_OK ){ - int iLangid = tdsqlite3_value_int(apVal[2 + p->nColumn + 2]); + int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]); if( bInsertDone==0 ){ rc = fts3InsertData(p, apVal, pRowid); if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){ @@ -184475,8 +184475,8 @@ SQLITE_PRIVATE int tdsqlite3Fts3UpdateMethod( } update_out: - tdsqlite3_free(aSzDel); - tdsqlite3Fts3SegmentsClose(p); + sqlite3_free(aSzDel); + sqlite3Fts3SegmentsClose(p); return rc; } @@ -184485,20 +184485,20 @@ SQLITE_PRIVATE int tdsqlite3Fts3UpdateMethod( ** merge all segments in the database (including the new segment, if ** there was any data to flush) into a single segment. */ -SQLITE_PRIVATE int tdsqlite3Fts3Optimize(Fts3Table *p){ +SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){ int rc; - rc = tdsqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0); + rc = sqlite3_exec(p->db, "SAVEPOINT fts3", 0, 0, 0); if( rc==SQLITE_OK ){ rc = fts3DoOptimize(p, 1); if( rc==SQLITE_OK || rc==SQLITE_DONE ){ - int rc2 = tdsqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + int rc2 = sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); if( rc2!=SQLITE_OK ) rc = rc2; }else{ - tdsqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); - tdsqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); + sqlite3_exec(p->db, "ROLLBACK TO fts3", 0, 0, 0); + sqlite3_exec(p->db, "RELEASE fts3", 0, 0, 0); } } - tdsqlite3Fts3SegmentsClose(p); + sqlite3Fts3SegmentsClose(p); return rc; } @@ -184597,7 +184597,7 @@ struct MatchInfo { Fts3Cursor *pCursor; /* FTS3 Cursor */ int nCol; /* Number of columns in table */ int nPhrase; /* Number of matchable phrases in query */ - tdsqlite3_int64 nDoc; /* Number of docs in database */ + sqlite3_int64 nDoc; /* Number of docs in database */ char flag; u32 *aMatchinfo; /* Pre-allocated buffer */ }; @@ -184638,11 +184638,11 @@ struct StrBuffer { */ static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){ MatchinfoBuffer *pRet; - tdsqlite3_int64 nByte = sizeof(u32) * (2*(tdsqlite3_int64)nElem + 1) + sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1) + sizeof(MatchinfoBuffer); - tdsqlite3_int64 nStr = strlen(zMatchinfo); + sqlite3_int64 nStr = strlen(zMatchinfo); - pRet = tdsqlite3_malloc64(nByte + nStr+1); + pRet = sqlite3_malloc64(nByte + nStr+1); if( pRet ){ memset(pRet, 0, nByte); pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet; @@ -184670,7 +184670,7 @@ static void fts3MIBufferFree(void *p){ } if( pBuf->aRef[0]==0 && pBuf->aRef[1]==0 && pBuf->aRef[2]==0 ){ - tdsqlite3_free(pBuf); + sqlite3_free(pBuf); } } @@ -184688,9 +184688,9 @@ static void (*fts3MIBufferAlloc(MatchinfoBuffer *p, u32 **paOut))(void*){ aOut = &p->aMatchinfo[p->nElem+2]; xRet = fts3MIBufferFree; }else{ - aOut = (u32*)tdsqlite3_malloc64(p->nElem * sizeof(u32)); + aOut = (u32*)sqlite3_malloc64(p->nElem * sizeof(u32)); if( aOut ){ - xRet = tdsqlite3_free; + xRet = sqlite3_free; if( p->bGlobal ) memcpy(aOut, &p->aMatchinfo[1], p->nElem*sizeof(u32)); } } @@ -184707,12 +184707,12 @@ static void fts3MIBufferSetGlobal(MatchinfoBuffer *p){ /* ** Free a MatchinfoBuffer object allocated using fts3MIBufferNew() */ -SQLITE_PRIVATE void tdsqlite3Fts3MIBufferFree(MatchinfoBuffer *p){ +SQLITE_PRIVATE void sqlite3Fts3MIBufferFree(MatchinfoBuffer *p){ if( p ){ assert( p->aRef[0]==1 ); p->aRef[0] = 0; if( p->aRef[0]==0 && p->aRef[1]==0 && p->aRef[2]==0 ){ - tdsqlite3_free(p); + sqlite3_free(p); } } } @@ -184980,7 +184980,7 @@ static int fts3SnippetFindPositions(Fts3Expr *pExpr, int iPhrase, void *ctx){ int rc; pPhrase->nToken = pExpr->pPhrase->nToken; - rc = tdsqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr); + rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pCsr); assert( rc==SQLITE_OK || pCsr==0 ); if( pCsr ){ int iFirst = 0; @@ -185030,7 +185030,7 @@ static int fts3BestSnippet( int rc; /* Return Code */ int nList; /* Number of phrases in expression */ SnippetIter sIter; /* Iterates through snippet candidates */ - tdsqlite3_int64 nByte; /* Number of bytes of space to allocate */ + sqlite3_int64 nByte; /* Number of bytes of space to allocate */ int iBestScore = -1; /* Best snippet score found so far */ int i; /* Loop counter */ @@ -185048,7 +185048,7 @@ static int fts3BestSnippet( ** the required space using malloc(). */ nByte = sizeof(SnippetPhrase) * nList; - sIter.aPhrase = (SnippetPhrase *)tdsqlite3_malloc64(nByte); + sIter.aPhrase = (SnippetPhrase *)sqlite3_malloc64(nByte); if( !sIter.aPhrase ){ return SQLITE_NOMEM; } @@ -185093,7 +185093,7 @@ static int fts3BestSnippet( *piScore = iBestScore; } - tdsqlite3_free(sIter.aPhrase); + sqlite3_free(sIter.aPhrase); return rc; } @@ -185118,8 +185118,8 @@ static int fts3StringAppend( ** appended data. */ if( pStr->n+nAppend+1>=pStr->nAlloc ){ - tdsqlite3_int64 nAlloc = pStr->nAlloc+(tdsqlite3_int64)nAppend+100; - char *zNew = tdsqlite3_realloc64(pStr->z, nAlloc); + sqlite3_int64 nAlloc = pStr->nAlloc+(sqlite3_int64)nAppend+100; + char *zNew = sqlite3_realloc64(pStr->z, nAlloc); if( !zNew ){ return SQLITE_NOMEM; } @@ -185188,14 +185188,14 @@ static int fts3SnippetShift( int nShift; /* Number of tokens to shift snippet by */ int iCurrent = 0; /* Token counter */ int rc; /* Return Code */ - tdsqlite3_tokenizer_module *pMod; - tdsqlite3_tokenizer_cursor *pC; - pMod = (tdsqlite3_tokenizer_module *)pTab->pTokenizer->pModule; + sqlite3_tokenizer_module *pMod; + sqlite3_tokenizer_cursor *pC; + pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; /* Open a cursor on zDoc/nDoc. Check if there are (nSnippet+nDesired) ** or more tokens in zDoc/nDoc. */ - rc = tdsqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC); + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, iLangid, zDoc, nDoc, &pC); if( rc!=SQLITE_OK ){ return rc; } @@ -185242,21 +185242,21 @@ static int fts3SnippetText( int iPos = pFragment->iPos; /* First token of snippet */ u64 hlmask = pFragment->hlmask; /* Highlight-mask for snippet */ int iCol = pFragment->iCol+1; /* Query column to extract text from */ - tdsqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */ - tdsqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ + sqlite3_tokenizer_module *pMod; /* Tokenizer module methods object */ + sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor open on zDoc/nDoc */ - zDoc = (const char *)tdsqlite3_column_text(pCsr->pStmt, iCol); + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol); if( zDoc==0 ){ - if( tdsqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){ + if( sqlite3_column_type(pCsr->pStmt, iCol)!=SQLITE_NULL ){ return SQLITE_NOMEM; } return SQLITE_OK; } - nDoc = tdsqlite3_column_bytes(pCsr->pStmt, iCol); + nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol); /* Open a token cursor on the document. */ - pMod = (tdsqlite3_tokenizer_module *)pTab->pTokenizer->pModule; - rc = tdsqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC); + pMod = (sqlite3_tokenizer_module *)pTab->pTokenizer->pModule; + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc,nDoc,&pC); if( rc!=SQLITE_OK ){ return rc; } @@ -185455,7 +185455,7 @@ static int fts3ExprGlobalHitsCb( void *pCtx /* Pointer to MatchInfo structure */ ){ MatchInfo *p = (MatchInfo *)pCtx; - return tdsqlite3Fts3EvalPhraseStats( + return sqlite3Fts3EvalPhraseStats( p->pCursor, pExpr, &p->aMatchinfo[3*iPhrase*p->nCol] ); } @@ -185477,7 +185477,7 @@ static int fts3ExprLocalHitsCb( for(i=0; inCol && rc==SQLITE_OK; i++){ char *pCsr; - rc = tdsqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr); + rc = sqlite3Fts3EvalPhrasePoslist(p->pCursor, pExpr, i, &pCsr); if( pCsr ){ p->aMatchinfo[iStart+i*3] = fts3ColumnlistCount(&pCsr); }else{ @@ -185505,7 +185505,7 @@ static int fts3MatchinfoCheck( ){ return SQLITE_OK; } - tdsqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg); + sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg); return SQLITE_ERROR; } @@ -185544,32 +185544,32 @@ static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ static int fts3MatchinfoSelectDoctotal( Fts3Table *pTab, - tdsqlite3_stmt **ppStmt, - tdsqlite3_int64 *pnDoc, + sqlite3_stmt **ppStmt, + sqlite3_int64 *pnDoc, const char **paLen, const char **ppEnd ){ - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; const char *a; const char *pEnd; - tdsqlite3_int64 nDoc; + sqlite3_int64 nDoc; int n; if( !*ppStmt ){ - int rc = tdsqlite3Fts3SelectDoctotal(pTab, ppStmt); + int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt); if( rc!=SQLITE_OK ) return rc; } pStmt = *ppStmt; - assert( tdsqlite3_data_count(pStmt)==1 ); + assert( sqlite3_data_count(pStmt)==1 ); - n = tdsqlite3_column_bytes(pStmt, 0); - a = tdsqlite3_column_blob(pStmt, 0); + n = sqlite3_column_bytes(pStmt, 0); + a = sqlite3_column_blob(pStmt, 0); if( a==0 ){ return FTS_CORRUPT_VTAB; } pEnd = a + n; - a += tdsqlite3Fts3GetVarintBounded(a, pEnd, &nDoc); + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nDoc); if( nDoc<=0 || a>pEnd ){ return FTS_CORRUPT_VTAB; } @@ -185617,10 +185617,10 @@ static int fts3MatchinfoLcsCb( */ static int fts3LcsIteratorAdvance(LcsIterator *pIter){ char *pRead = pIter->pRead; - tdsqlite3_int64 iRead; + sqlite3_int64 iRead; int rc = 0; - pRead += tdsqlite3Fts3GetVarint(pRead, &iRead); + pRead += sqlite3Fts3GetVarint(pRead, &iRead); if( iRead==0 || iRead==1 ){ pRead = 0; rc = 1; @@ -185653,7 +185653,7 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ /* Allocate and populate the array of LcsIterator objects. The array ** contains one element for each matchable phrase in the query. **/ - aIter = tdsqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase); + aIter = sqlite3_malloc64(sizeof(LcsIterator) * pCsr->nPhrase); if( !aIter ) return SQLITE_NOMEM; memset(aIter, 0, sizeof(LcsIterator) * pCsr->nPhrase); (void)fts3ExprIterate(pCsr->pExpr, fts3MatchinfoLcsCb, (void*)aIter); @@ -185670,7 +185670,7 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ for(i=0; inPhrase; i++){ LcsIterator *pIt = &aIter[i]; - rc = tdsqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead); + rc = sqlite3Fts3EvalPhrasePoslist(pCsr, pIt->pExpr, iCol, &pIt->pRead); if( rc!=SQLITE_OK ) goto matchinfo_lcs_out; if( pIt->pRead ){ pIt->iPos = pIt->iPosOffset; @@ -185711,7 +185711,7 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){ } matchinfo_lcs_out: - tdsqlite3_free(aIter); + sqlite3_free(aIter); return rc; } @@ -185741,7 +185741,7 @@ static int fts3MatchinfoValues( int rc = SQLITE_OK; int i; Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - tdsqlite3_stmt *pSelect = 0; + sqlite3_stmt *pSelect = 0; for(i=0; rc==SQLITE_OK && zArg[i]; i++){ pInfo->flag = zArg[i]; @@ -185756,7 +185756,7 @@ static int fts3MatchinfoValues( case FTS3_MATCHINFO_NDOC: if( bGlobal ){ - tdsqlite3_int64 nDoc = 0; + sqlite3_int64 nDoc = 0; rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0, 0); pInfo->aMatchinfo[0] = (u32)nDoc; } @@ -185764,7 +185764,7 @@ static int fts3MatchinfoValues( case FTS3_MATCHINFO_AVGLENGTH: if( bGlobal ){ - tdsqlite3_int64 nDoc; /* Number of rows in table */ + sqlite3_int64 nDoc; /* Number of rows in table */ const char *a; /* Aggregate column length array */ const char *pEnd; /* First byte past end of length array */ @@ -185773,8 +185773,8 @@ static int fts3MatchinfoValues( int iCol; for(iCol=0; iColnCol; iCol++){ u32 iVal; - tdsqlite3_int64 nToken; - a += tdsqlite3Fts3GetVarint(a, &nToken); + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); if( a>pEnd ){ rc = SQLITE_CORRUPT_VTAB; break; @@ -185787,15 +185787,15 @@ static int fts3MatchinfoValues( break; case FTS3_MATCHINFO_LENGTH: { - tdsqlite3_stmt *pSelectDocsize = 0; - rc = tdsqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize); + sqlite3_stmt *pSelectDocsize = 0; + rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize); if( rc==SQLITE_OK ){ int iCol; - const char *a = tdsqlite3_column_blob(pSelectDocsize, 0); - const char *pEnd = a + tdsqlite3_column_bytes(pSelectDocsize, 0); + const char *a = sqlite3_column_blob(pSelectDocsize, 0); + const char *pEnd = a + sqlite3_column_bytes(pSelectDocsize, 0); for(iCol=0; iColnCol; iCol++){ - tdsqlite3_int64 nToken; - a += tdsqlite3Fts3GetVarintBounded(a, pEnd, &nToken); + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarintBounded(a, pEnd, &nToken); if( a>pEnd ){ rc = SQLITE_CORRUPT_VTAB; break; @@ -185803,7 +185803,7 @@ static int fts3MatchinfoValues( pInfo->aMatchinfo[iCol] = (u32)nToken; } } - tdsqlite3_reset(pSelectDocsize); + sqlite3_reset(pSelectDocsize); break; } @@ -185834,7 +185834,7 @@ static int fts3MatchinfoValues( if( rc!=SQLITE_OK ) break; } rc = fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); - tdsqlite3Fts3EvalTestDeferred(pCsr, &rc); + sqlite3Fts3EvalTestDeferred(pCsr, &rc); if( rc!=SQLITE_OK ) break; } (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); @@ -185845,7 +185845,7 @@ static int fts3MatchinfoValues( pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); } - tdsqlite3_reset(pSelect); + sqlite3_reset(pSelect); return rc; } @@ -185855,7 +185855,7 @@ static int fts3MatchinfoValues( ** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32). */ static void fts3GetMatchinfo( - tdsqlite3_context *pCtx, /* Return results here */ + sqlite3_context *pCtx, /* Return results here */ Fts3Cursor *pCsr, /* FTS3 Cursor object */ const char *zArg /* Second argument to matchinfo() function */ ){ @@ -185875,7 +185875,7 @@ static void fts3GetMatchinfo( ** cache does not match the format string for this request, discard ** the cached data. */ if( pCsr->pMIBuffer && strcmp(pCsr->pMIBuffer->zMatchinfo, zArg) ){ - tdsqlite3Fts3MIBufferFree(pCsr->pMIBuffer); + sqlite3Fts3MIBufferFree(pCsr->pMIBuffer); pCsr->pMIBuffer = 0; } @@ -185896,8 +185896,8 @@ static void fts3GetMatchinfo( for(i=0; zArg[i]; i++){ char *zErr = 0; if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){ - tdsqlite3_result_error(pCtx, zErr, -1); - tdsqlite3_free(zErr); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); return; } nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]); @@ -185928,19 +185928,19 @@ static void fts3GetMatchinfo( } if( rc!=SQLITE_OK ){ - tdsqlite3_result_error_code(pCtx, rc); + sqlite3_result_error_code(pCtx, rc); if( xDestroyOut ) xDestroyOut(aOut); }else{ int n = pCsr->pMIBuffer->nElem * sizeof(u32); - tdsqlite3_result_blob(pCtx, aOut, n, xDestroyOut); + sqlite3_result_blob(pCtx, aOut, n, xDestroyOut); } } /* ** Implementation of snippet() function. */ -SQLITE_PRIVATE void tdsqlite3Fts3Snippet( - tdsqlite3_context *pCtx, /* SQLite function call context */ +SQLITE_PRIVATE void sqlite3Fts3Snippet( + sqlite3_context *pCtx, /* SQLite function call context */ Fts3Cursor *pCsr, /* Cursor object */ const char *zStart, /* Snippet start text - "" */ const char *zEnd, /* Snippet end text - "" */ @@ -185966,7 +185966,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3Snippet( int nFToken = -1; /* Number of tokens in each fragment */ if( !pCsr->pExpr ){ - tdsqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); return; } @@ -186032,12 +186032,12 @@ SQLITE_PRIVATE void tdsqlite3Fts3Snippet( } snippet_out: - tdsqlite3Fts3SegmentsClose(pTab); + sqlite3Fts3SegmentsClose(pTab); if( rc!=SQLITE_OK ){ - tdsqlite3_result_error_code(pCtx, rc); - tdsqlite3_free(res.z); + sqlite3_result_error_code(pCtx, rc); + sqlite3_free(res.z); }else{ - tdsqlite3_result_text(pCtx, res.z, -1, tdsqlite3_free); + sqlite3_result_text(pCtx, res.z, -1, sqlite3_free); } } @@ -186055,12 +186055,12 @@ struct TermOffsetCtx { Fts3Cursor *pCsr; int iCol; /* Column of table to populate aTerm for */ int iTerm; - tdsqlite3_int64 iDocid; + sqlite3_int64 iDocid; TermOffset *aTerm; }; /* -** This function is an fts3ExprIterate() callback used by tdsqlite3Fts3Offsets(). +** This function is an fts3ExprIterate() callback used by sqlite3Fts3Offsets(). */ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ TermOffsetCtx *p = (TermOffsetCtx *)ctx; @@ -186071,7 +186071,7 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ int rc; UNUSED_PARAMETER(iPhrase); - rc = tdsqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pList); + rc = sqlite3Fts3EvalPhrasePoslist(p->pCsr, pExpr, p->iCol, &pList); nTerm = pExpr->pPhrase->nToken; if( pList ){ fts3GetDeltaPosition(&pList, &iPos); @@ -186091,12 +186091,12 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ /* ** Implementation of offsets() function. */ -SQLITE_PRIVATE void tdsqlite3Fts3Offsets( - tdsqlite3_context *pCtx, /* SQLite function call context */ +SQLITE_PRIVATE void sqlite3Fts3Offsets( + sqlite3_context *pCtx, /* SQLite function call context */ Fts3Cursor *pCsr /* Cursor object */ ){ Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; - tdsqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule; + sqlite3_tokenizer_module const *pMod = pTab->pTokenizer->pModule; int rc; /* Return Code */ int nToken; /* Number of tokens in query */ int iCol; /* Column currently being processed */ @@ -186104,7 +186104,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3Offsets( TermOffsetCtx sCtx; /* Context for fts3ExprTermOffsetInit() */ if( !pCsr->pExpr ){ - tdsqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); + sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC); return; } @@ -186116,7 +186116,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3Offsets( if( rc!=SQLITE_OK ) goto offsets_out; /* Allocate the array of TermOffset iterators. */ - sCtx.aTerm = (TermOffset *)tdsqlite3_malloc64(sizeof(TermOffset)*nToken); + sCtx.aTerm = (TermOffset *)sqlite3_malloc64(sizeof(TermOffset)*nToken); if( 0==sCtx.aTerm ){ rc = SQLITE_NOMEM; goto offsets_out; @@ -186128,7 +186128,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3Offsets( ** string-buffer res for each column. */ for(iCol=0; iColnColumn; iCol++){ - tdsqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */ + sqlite3_tokenizer_cursor *pC; /* Tokenizer cursor */ const char *ZDUMMY; /* Dummy argument used with xNext() */ int NDUMMY = 0; /* Dummy argument used with xNext() */ int iStart = 0; @@ -186151,10 +186151,10 @@ SQLITE_PRIVATE void tdsqlite3Fts3Offsets( ** needs to transform the data from utf-16 to utf-8), return SQLITE_NOMEM ** to the caller. */ - zDoc = (const char *)tdsqlite3_column_text(pCsr->pStmt, iCol+1); - nDoc = tdsqlite3_column_bytes(pCsr->pStmt, iCol+1); + zDoc = (const char *)sqlite3_column_text(pCsr->pStmt, iCol+1); + nDoc = sqlite3_column_bytes(pCsr->pStmt, iCol+1); if( zDoc==0 ){ - if( tdsqlite3_column_type(pCsr->pStmt, iCol+1)==SQLITE_NULL ){ + if( sqlite3_column_type(pCsr->pStmt, iCol+1)==SQLITE_NULL ){ continue; } rc = SQLITE_NOMEM; @@ -186162,7 +186162,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3Offsets( } /* Initialize a tokenizer iterator to iterate through column iCol. */ - rc = tdsqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, + rc = sqlite3Fts3OpenTokenizer(pTab->pTokenizer, pCsr->iLangid, zDoc, nDoc, &pC ); if( rc!=SQLITE_OK ) goto offsets_out; @@ -186196,7 +186196,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3Offsets( } if( rc==SQLITE_OK ){ char aBuffer[64]; - tdsqlite3_snprintf(sizeof(aBuffer), aBuffer, + sqlite3_snprintf(sizeof(aBuffer), aBuffer, "%d %d %d %d ", iCol, pTerm-sCtx.aTerm, iStart, iEnd-iStart ); rc = fts3StringAppend(&res, aBuffer, -1); @@ -186214,14 +186214,14 @@ SQLITE_PRIVATE void tdsqlite3Fts3Offsets( } offsets_out: - tdsqlite3_free(sCtx.aTerm); + sqlite3_free(sCtx.aTerm); assert( rc!=SQLITE_DONE ); - tdsqlite3Fts3SegmentsClose(pTab); + sqlite3Fts3SegmentsClose(pTab); if( rc!=SQLITE_OK ){ - tdsqlite3_result_error_code(pCtx, rc); - tdsqlite3_free(res.z); + sqlite3_result_error_code(pCtx, rc); + sqlite3_free(res.z); }else{ - tdsqlite3_result_text(pCtx, res.z, res.n-1, tdsqlite3_free); + sqlite3_result_text(pCtx, res.z, res.n-1, sqlite3_free); } return; } @@ -186229,8 +186229,8 @@ SQLITE_PRIVATE void tdsqlite3Fts3Offsets( /* ** Implementation of matchinfo() function. */ -SQLITE_PRIVATE void tdsqlite3Fts3Matchinfo( - tdsqlite3_context *pContext, /* Function call context */ +SQLITE_PRIVATE void sqlite3Fts3Matchinfo( + sqlite3_context *pContext, /* Function call context */ Fts3Cursor *pCsr, /* FTS3 table cursor */ const char *zArg /* Second arg to matchinfo() function */ ){ @@ -186244,12 +186244,12 @@ SQLITE_PRIVATE void tdsqlite3Fts3Matchinfo( } if( !pCsr->pExpr ){ - tdsqlite3_result_blob(pContext, "", 0, SQLITE_STATIC); + sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC); return; }else{ /* Retrieve matchinfo() data. */ fts3GetMatchinfo(pContext, pCsr, zFormat); - tdsqlite3Fts3SegmentsClose(pTab); + sqlite3Fts3SegmentsClose(pTab); } } @@ -186286,12 +186286,12 @@ SQLITE_PRIVATE void tdsqlite3Fts3Matchinfo( /* ** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied -** from the tdsqlite3 source file utf.c. If this file is compiled as part +** from the sqlite3 source file utf.c. If this file is compiled as part ** of the amalgamation, they are not required. */ #ifndef SQLITE_AMALGAMATION -static const unsigned char tdsqlite3Utf8Trans1[] = { +static const unsigned char sqlite3Utf8Trans1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, @@ -186305,7 +186305,7 @@ static const unsigned char tdsqlite3Utf8Trans1[] = { #define READ_UTF8(zIn, zTerm, c) \ c = *(zIn++); \ if( c>=0xc0 ){ \ - c = tdsqlite3Utf8Trans1[c-0xc0]; \ + c = sqlite3Utf8Trans1[c-0xc0]; \ while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ c = (c<<6) + (0x3f & *(zIn++)); \ } \ @@ -186340,14 +186340,14 @@ typedef struct unicode_tokenizer unicode_tokenizer; typedef struct unicode_cursor unicode_cursor; struct unicode_tokenizer { - tdsqlite3_tokenizer base; + sqlite3_tokenizer base; int eRemoveDiacritic; int nException; int *aiException; }; struct unicode_cursor { - tdsqlite3_tokenizer_cursor base; + sqlite3_tokenizer_cursor base; const unsigned char *aInput; /* Input text being tokenized */ int nInput; /* Size of aInput[] in bytes */ int iOff; /* Current offset within aInput[] */ @@ -186360,11 +186360,11 @@ struct unicode_cursor { /* ** Destroy a tokenizer allocated by unicodeCreate(). */ -static int unicodeDestroy(tdsqlite3_tokenizer *pTokenizer){ +static int unicodeDestroy(sqlite3_tokenizer *pTokenizer){ if( pTokenizer ){ unicode_tokenizer *p = (unicode_tokenizer *)pTokenizer; - tdsqlite3_free(p->aiException); - tdsqlite3_free(p); + sqlite3_free(p->aiException); + sqlite3_free(p); } return SQLITE_OK; } @@ -186376,13 +186376,13 @@ static int unicodeDestroy(tdsqlite3_tokenizer *pTokenizer){ ** token characters (if bAlnum==1). ** ** For each codepoint in the zIn/nIn string, this function checks if the -** tdsqlite3FtsUnicodeIsalnum() function already returns the desired result. +** sqlite3FtsUnicodeIsalnum() function already returns the desired result. ** If so, no action is taken. Otherwise, the codepoint is added to the ** unicode_tokenizer.aiException[] array. For the purposes of tokenization, -** the return value of tdsqlite3FtsUnicodeIsalnum() is inverted for all +** the return value of sqlite3FtsUnicodeIsalnum() is inverted for all ** codepoints in the aiException[] array. ** -** If a standalone diacritic mark (one that tdsqlite3FtsUnicodeIsdiacritic() +** If a standalone diacritic mark (one that sqlite3FtsUnicodeIsdiacritic() ** identifies as a diacritic) occurs in the zIn/nIn string it is ignored. ** It is not possible to change the behavior of the tokenizer with respect ** to these codepoints. @@ -186402,9 +186402,9 @@ static int unicodeAddExceptions( while( zaiException,(p->nException+nEntry)*sizeof(int)); + aNew = sqlite3_realloc64(p->aiException,(p->nException+nEntry)*sizeof(int)); if( aNew==0 ) return SQLITE_NOMEM; nNew = p->nException; z = (const unsigned char *)zIn; while( zeRemoveDiacritic = 1; @@ -186514,10 +186514,10 @@ static int unicodeCreate( } if( rc!=SQLITE_OK ){ - unicodeDestroy((tdsqlite3_tokenizer *)pNew); + unicodeDestroy((sqlite3_tokenizer *)pNew); pNew = 0; } - *pp = (tdsqlite3_tokenizer *)pNew; + *pp = (sqlite3_tokenizer *)pNew; return rc; } @@ -186528,14 +186528,14 @@ static int unicodeCreate( ** *ppCursor. */ static int unicodeOpen( - tdsqlite3_tokenizer *p, /* The tokenizer */ + sqlite3_tokenizer *p, /* The tokenizer */ const char *aInput, /* Input string */ int nInput, /* Size of string aInput in bytes */ - tdsqlite3_tokenizer_cursor **pp /* OUT: New cursor object */ + sqlite3_tokenizer_cursor **pp /* OUT: New cursor object */ ){ unicode_cursor *pCsr; - pCsr = (unicode_cursor *)tdsqlite3_malloc(sizeof(unicode_cursor)); + pCsr = (unicode_cursor *)sqlite3_malloc(sizeof(unicode_cursor)); if( pCsr==0 ){ return SQLITE_NOMEM; } @@ -186559,10 +186559,10 @@ static int unicodeOpen( ** Close a tokenization cursor previously opened by a call to ** simpleOpen() above. */ -static int unicodeClose(tdsqlite3_tokenizer_cursor *pCursor){ +static int unicodeClose(sqlite3_tokenizer_cursor *pCursor){ unicode_cursor *pCsr = (unicode_cursor *) pCursor; - tdsqlite3_free(pCsr->zToken); - tdsqlite3_free(pCsr); + sqlite3_free(pCsr->zToken); + sqlite3_free(pCsr); return SQLITE_OK; } @@ -186571,7 +186571,7 @@ static int unicodeClose(tdsqlite3_tokenizer_cursor *pCursor){ ** have been opened by a prior call to simpleOpen(). */ static int unicodeNext( - tdsqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */ + sqlite3_tokenizer_cursor *pC, /* Cursor returned by simpleOpen */ const char **paToken, /* OUT: Token text */ int *pnToken, /* OUT: Number of bytes at *paToken */ int *piStart, /* OUT: Starting offset of token */ @@ -186603,7 +186603,7 @@ static int unicodeNext( /* Grow the output buffer if required. */ if( (zOut-pCsr->zToken)>=(pCsr->nAlloc-4) ){ - char *zNew = tdsqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64); + char *zNew = sqlite3_realloc64(pCsr->zToken, pCsr->nAlloc+64); if( !zNew ) return SQLITE_NOMEM; zOut = &zNew[zOut - pCsr->zToken]; pCsr->zToken = zNew; @@ -186612,7 +186612,7 @@ static int unicodeNext( /* Write the folded case of the last character read to the output */ zEnd = z; - iOut = tdsqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic); + iOut = sqlite3FtsUnicodeFold((int)iCode, p->eRemoveDiacritic); if( iOut ){ WRITE_UTF8(zOut, iOut); } @@ -186621,7 +186621,7 @@ static int unicodeNext( if( z>=zTerm ) break; READ_UTF8(z, zTerm, iCode); }while( unicodeIsAlnum(p, (int)iCode) - || tdsqlite3FtsUnicodeIsdiacritic((int)iCode) + || sqlite3FtsUnicodeIsdiacritic((int)iCode) ); /* Set the output variables and return. */ @@ -186635,11 +186635,11 @@ static int unicodeNext( } /* -** Set *ppModule to a pointer to the tdsqlite3_tokenizer_module +** Set *ppModule to a pointer to the sqlite3_tokenizer_module ** structure for the unicode tokenizer. */ -SQLITE_PRIVATE void tdsqlite3Fts3UnicodeTokenizer(tdsqlite3_tokenizer_module const **ppModule){ - static const tdsqlite3_tokenizer_module module = { +SQLITE_PRIVATE void sqlite3Fts3UnicodeTokenizer(sqlite3_tokenizer_module const **ppModule){ + static const sqlite3_tokenizer_module module = { 0, unicodeCreate, unicodeDestroy, @@ -186685,7 +186685,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3UnicodeTokenizer(tdsqlite3_tokenizer_module con ** The results are undefined if the value passed to this function ** is less than zero. */ -SQLITE_PRIVATE int tdsqlite3FtsUnicodeIsalnum(int c){ +SQLITE_PRIVATE int sqlite3FtsUnicodeIsalnum(int c){ /* Each unsigned integer in the following array corresponds to a contiguous ** range of unicode codepoints that are not either letters or numbers (i.e. ** codepoints for which this function should return 0). @@ -186884,7 +186884,7 @@ static int remove_diacritic(int c, int bComplex){ ** Return true if the argument interpreted as a unicode codepoint ** is a diacritical modifier character. */ -SQLITE_PRIVATE int tdsqlite3FtsUnicodeIsdiacritic(int c){ +SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int c){ unsigned int mask0 = 0x08029FDF; unsigned int mask1 = 0x000361F8; if( c<768 || c>817 ) return 0; @@ -186903,7 +186903,7 @@ SQLITE_PRIVATE int tdsqlite3FtsUnicodeIsdiacritic(int c){ ** The results are undefined if the value passed to this function ** is less than zero. */ -SQLITE_PRIVATE int tdsqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ +SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ /* Each entry in the following array defines a rule for folding a range ** of codepoints to lower case. The rule applies to a range of nRange ** codepoints starting at codepoint iCode. @@ -187067,7 +187067,7 @@ SQLITE_PRIVATE int tdsqlite3FtsUnicodeFold(int c, int eRemoveDiacritic){ */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) #if !defined(SQLITEINT_H) -/* #include "tdsqlite3ext.h" */ +/* #include "sqlite3ext.h" */ #endif SQLITE_EXTENSION_INIT1 /* #include */ @@ -187082,20 +187082,20 @@ SQLITE_EXTENSION_INIT1 #endif #ifndef LARGEST_INT64 -# define LARGEST_INT64 (0xffffffff|(((tdsqlite3_int64)0x7fffffff)<<32)) -# define SMALLEST_INT64 (((tdsqlite3_int64)-1) - LARGEST_INT64) +# define LARGEST_INT64 (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32)) +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64) #endif /* ** Versions of isspace(), isalnum() and isdigit() to which it is safe ** to pass signed char values. */ -#ifdef tdsqlite3Isdigit +#ifdef sqlite3Isdigit /* Use the SQLite core versions if this routine is part of the ** SQLite amalgamation */ -# define safe_isdigit(x) tdsqlite3Isdigit(x) -# define safe_isalnum(x) tdsqlite3Isalnum(x) -# define safe_isxdigit(x) tdsqlite3Isxdigit(x) +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) #else /* Use the standard library for separate compilation */ #include /* amalgamator: keep */ @@ -187132,7 +187132,7 @@ static const char jsonIsSpace[] = { #ifndef SQLITE_AMALGAMATION /* Unsigned integer types. These are already defined in the sqliteInt.h, ** but the definitions need to be repeated for separate compilation. */ - typedef tdsqlite3_uint64 u64; + typedef sqlite3_uint64 u64; typedef unsigned int u32; typedef unsigned short int u16; typedef unsigned char u8; @@ -187148,7 +187148,7 @@ typedef struct JsonParse JsonParse; ** that can be and is used to create strings other than JSON. */ struct JsonString { - tdsqlite3_context *pCtx; /* Function context - put error messages here */ + sqlite3_context *pCtx; /* Function context - put error messages here */ char *zBuf; /* Append JSON content here */ u64 nAlloc; /* Bytes of storage available in zBuf[] */ u64 nUsed; /* Bytes of zBuf[] currently used */ @@ -187243,7 +187243,7 @@ static void jsonZero(JsonString *p){ /* Initialize the JsonString object */ -static void jsonInit(JsonString *p, tdsqlite3_context *pCtx){ +static void jsonInit(JsonString *p, sqlite3_context *pCtx){ p->pCtx = pCtx; p->bErr = 0; jsonZero(p); @@ -187254,7 +187254,7 @@ static void jsonInit(JsonString *p, tdsqlite3_context *pCtx){ ** initial state. */ static void jsonReset(JsonString *p){ - if( !p->bStatic ) tdsqlite3_free(p->zBuf); + if( !p->bStatic ) sqlite3_free(p->zBuf); jsonZero(p); } @@ -187263,7 +187263,7 @@ static void jsonReset(JsonString *p){ */ static void jsonOom(JsonString *p){ p->bErr = 1; - tdsqlite3_result_error_nomem(p->pCtx); + sqlite3_result_error_nomem(p->pCtx); jsonReset(p); } @@ -187275,7 +187275,7 @@ static int jsonGrow(JsonString *p, u32 N){ char *zNew; if( p->bStatic ){ if( p->bErr ) return 1; - zNew = tdsqlite3_malloc64(nTotal); + zNew = sqlite3_malloc64(nTotal); if( zNew==0 ){ jsonOom(p); return SQLITE_NOMEM; @@ -187284,7 +187284,7 @@ static int jsonGrow(JsonString *p, u32 N){ p->zBuf = zNew; p->bStatic = 0; }else{ - zNew = tdsqlite3_realloc64(p->zBuf, nTotal); + zNew = sqlite3_realloc64(p->zBuf, nTotal); if( zNew==0 ){ jsonOom(p); return SQLITE_NOMEM; @@ -187309,7 +187309,7 @@ static void jsonPrintf(int N, JsonString *p, const char *zFormat, ...){ va_list ap; if( (p->nUsed + N >= p->nAlloc) && jsonGrow(p, N) ) return; va_start(ap, zFormat); - tdsqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); + sqlite3_vsnprintf(N, p->zBuf+p->nUsed, zFormat, ap); va_end(ap); p->nUsed += (int)strlen(p->zBuf+p->nUsed); } @@ -187381,24 +187381,24 @@ static void jsonAppendString(JsonString *p, const char *zIn, u32 N){ */ static void jsonAppendValue( JsonString *p, /* Append to this JSON string */ - tdsqlite3_value *pValue /* Value to append */ + sqlite3_value *pValue /* Value to append */ ){ - switch( tdsqlite3_value_type(pValue) ){ + switch( sqlite3_value_type(pValue) ){ case SQLITE_NULL: { jsonAppendRaw(p, "null", 4); break; } case SQLITE_INTEGER: case SQLITE_FLOAT: { - const char *z = (const char*)tdsqlite3_value_text(pValue); - u32 n = (u32)tdsqlite3_value_bytes(pValue); + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); jsonAppendRaw(p, z, n); break; } case SQLITE_TEXT: { - const char *z = (const char*)tdsqlite3_value_text(pValue); - u32 n = (u32)tdsqlite3_value_bytes(pValue); - if( tdsqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + if( sqlite3_value_subtype(pValue)==JSON_SUBTYPE ){ jsonAppendRaw(p, z, n); }else{ jsonAppendString(p, z, n); @@ -187407,7 +187407,7 @@ static void jsonAppendValue( } default: { if( p->bErr==0 ){ - tdsqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); + sqlite3_result_error(p->pCtx, "JSON cannot hold BLOB values", -1); p->bErr = 2; jsonReset(p); } @@ -187421,8 +187421,8 @@ static void jsonAppendValue( */ static void jsonResult(JsonString *p){ if( p->bErr==0 ){ - tdsqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, - p->bStatic ? SQLITE_TRANSIENT : tdsqlite3_free, + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, SQLITE_UTF8); jsonZero(p); } @@ -187451,20 +187451,20 @@ static u32 jsonNodeSize(JsonNode *pNode){ ** delete the JsonParse object itself. */ static void jsonParseReset(JsonParse *pParse){ - tdsqlite3_free(pParse->aNode); + sqlite3_free(pParse->aNode); pParse->aNode = 0; pParse->nNode = 0; pParse->nAlloc = 0; - tdsqlite3_free(pParse->aUp); + sqlite3_free(pParse->aUp); pParse->aUp = 0; } /* -** Free a JsonParse object that was obtained from tdsqlite3_malloc(). +** Free a JsonParse object that was obtained from sqlite3_malloc(). */ static void jsonParseFree(JsonParse *pParse){ jsonParseReset(pParse); - tdsqlite3_free(pParse); + sqlite3_free(pParse); } /* @@ -187475,7 +187475,7 @@ static void jsonParseFree(JsonParse *pParse){ static void jsonRenderNode( JsonNode *pNode, /* The node to render */ JsonString *pOut, /* Write JSON here */ - tdsqlite3_value **aReplace /* Replacement values */ + sqlite3_value **aReplace /* Replacement values */ ){ if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ if( pNode->jnFlags & JNODE_REPLACE ){ @@ -187556,14 +187556,14 @@ static void jsonRenderNode( */ static void jsonReturnJson( JsonNode *pNode, /* Node to return */ - tdsqlite3_context *pCtx, /* Return value for this function */ - tdsqlite3_value **aReplace /* Array of replacement values */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ ){ JsonString s; jsonInit(&s, pCtx); jsonRenderNode(pNode, &s, aReplace); jsonResult(&s); - tdsqlite3_result_subtype(pCtx, JSON_SUBTYPE); + sqlite3_result_subtype(pCtx, JSON_SUBTYPE); } /* @@ -187602,25 +187602,25 @@ static u32 jsonHexToInt4(const char *z){ */ static void jsonReturn( JsonNode *pNode, /* Node to return */ - tdsqlite3_context *pCtx, /* Return value for this function */ - tdsqlite3_value **aReplace /* Array of replacement values */ + sqlite3_context *pCtx, /* Return value for this function */ + sqlite3_value **aReplace /* Array of replacement values */ ){ switch( pNode->eType ){ default: { assert( pNode->eType==JSON_NULL ); - tdsqlite3_result_null(pCtx); + sqlite3_result_null(pCtx); break; } case JSON_TRUE: { - tdsqlite3_result_int(pCtx, 1); + sqlite3_result_int(pCtx, 1); break; } case JSON_FALSE: { - tdsqlite3_result_int(pCtx, 0); + sqlite3_result_int(pCtx, 0); break; } case JSON_INT: { - tdsqlite3_int64 i = 0; + sqlite3_int64 i = 0; const char *z = pNode->u.zJContent; if( z[0]=='-' ){ z++; } while( z[0]>='0' && z[0]<='9' ){ @@ -187631,7 +187631,7 @@ static void jsonReturn( if( v==9 ) goto int_as_real; if( v==8 ){ if( pNode->u.zJContent[0]=='-' ){ - tdsqlite3_result_int64(pCtx, SMALLEST_INT64); + sqlite3_result_int64(pCtx, SMALLEST_INT64); goto int_done; }else{ goto int_as_real; @@ -187641,7 +187641,7 @@ static void jsonReturn( i = i*10 + v; } if( pNode->u.zJContent[0]=='-' ){ i = -i; } - tdsqlite3_result_int64(pCtx, i); + sqlite3_result_int64(pCtx, i); int_done: break; int_as_real: /* fall through to real */; @@ -187650,11 +187650,11 @@ static void jsonReturn( double r; #ifdef SQLITE_AMALGAMATION const char *z = pNode->u.zJContent; - tdsqlite3AtoF(z, &r, tdsqlite3Strlen30(z), SQLITE_UTF8); + sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8); #else r = strtod(pNode->u.zJContent, 0); #endif - tdsqlite3_result_double(pCtx, r); + sqlite3_result_double(pCtx, r); break; } case JSON_STRING: { @@ -187662,14 +187662,14 @@ static void jsonReturn( ** json_insert() and json_replace() and those routines do not ** call jsonReturn() */ if( pNode->jnFlags & JNODE_RAW ){ - tdsqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, + sqlite3_result_text(pCtx, pNode->u.zJContent, pNode->n, SQLITE_TRANSIENT); }else #endif assert( (pNode->jnFlags & JNODE_RAW)==0 ); if( (pNode->jnFlags & JNODE_ESCAPE)==0 ){ /* JSON formatted without any backslash-escapes */ - tdsqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, + sqlite3_result_text(pCtx, pNode->u.zJContent+1, pNode->n-2, SQLITE_TRANSIENT); }else{ /* Translate JSON formatted string into raw text */ @@ -187678,9 +187678,9 @@ static void jsonReturn( const char *z = pNode->u.zJContent; char *zOut; u32 j; - zOut = tdsqlite3_malloc( n+1 ); + zOut = sqlite3_malloc( n+1 ); if( zOut==0 ){ - tdsqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(pCtx); break; } for(i=1, j=0; inNode>=pParse->nAlloc ); if( pParse->oom ) return -1; nNew = pParse->nAlloc*2 + 10; - pNew = tdsqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew); + pNew = sqlite3_realloc64(pParse->aNode, sizeof(JsonNode)*nNew); if( pNew==0 ){ pParse->oom = 1; return -1; @@ -187988,7 +187988,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ */ static int jsonParse( JsonParse *pParse, /* Initialize and fill this JsonParse object */ - tdsqlite3_context *pCtx, /* Report errors here */ + sqlite3_context *pCtx, /* Report errors here */ const char *zJson /* Input JSON text to be parsed */ ){ int i; @@ -188005,9 +188005,9 @@ static int jsonParse( if( i<=0 ){ if( pCtx!=0 ){ if( pParse->oom ){ - tdsqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(pCtx); }else{ - tdsqlite3_result_error(pCtx, "malformed JSON", -1); + sqlite3_result_error(pCtx, "malformed JSON", -1); } } jsonParseReset(pParse); @@ -188049,7 +188049,7 @@ static void jsonParseFillInParentage(JsonParse *pParse, u32 i, u32 iParent){ static int jsonParseFindParents(JsonParse *pParse){ u32 *aUp; assert( pParse->aUp==0 ); - aUp = pParse->aUp = tdsqlite3_malloc64( sizeof(u32)*pParse->nNode ); + aUp = pParse->aUp = sqlite3_malloc64( sizeof(u32)*pParse->nNode ); if( aUp==0 ){ pParse->oom = 1; return SQLITE_NOMEM; @@ -188059,26 +188059,26 @@ static int jsonParseFindParents(JsonParse *pParse){ } /* -** Magic number used for the JSON parse cache in tdsqlite3_get_auxdata() +** Magic number used for the JSON parse cache in sqlite3_get_auxdata() */ #define JSON_CACHE_ID (-429938) /* First cache entry */ #define JSON_CACHE_SZ 4 /* Max number of cache entries */ /* ** Obtain a complete parse of the JSON found in the first argument -** of the argv array. Use the tdsqlite3_get_auxdata() cache for this +** of the argv array. Use the sqlite3_get_auxdata() cache for this ** parse if it is available. If the cache is not available or if it ** is no longer valid, parse the JSON again and return the new parse, ** and also register the new parse so that it will be available for -** future tdsqlite3_get_auxdata() calls. +** future sqlite3_get_auxdata() calls. */ static JsonParse *jsonParseCached( - tdsqlite3_context *pCtx, - tdsqlite3_value **argv, - tdsqlite3_context *pErrCtx + sqlite3_context *pCtx, + sqlite3_value **argv, + sqlite3_context *pErrCtx ){ - const char *zJson = (const char*)tdsqlite3_value_text(argv[0]); - int nJson = tdsqlite3_value_bytes(argv[0]); + const char *zJson = (const char*)sqlite3_value_text(argv[0]); + int nJson = sqlite3_value_bytes(argv[0]); JsonParse *p; JsonParse *pMatch = 0; int iKey; @@ -188087,7 +188087,7 @@ static JsonParse *jsonParseCached( u32 iMaxHold = 0; if( zJson==0 ) return 0; for(iKey=0; iKeyiHold = iMaxHold+1; return pMatch; } - p = tdsqlite3_malloc64( sizeof(*p) + nJson + 1 ); + p = sqlite3_malloc64( sizeof(*p) + nJson + 1 ); if( p==0 ){ - tdsqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(pCtx); return 0; } memset(p, 0, sizeof(*p)); p->zJson = (char*)&p[1]; memcpy((char*)p->zJson, zJson, nJson+1); if( jsonParse(p, pErrCtx, p->zJson) ){ - tdsqlite3_free(p); + sqlite3_free(p); return 0; } p->nJson = nJson; p->iHold = iMaxHold+1; - tdsqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, + sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, (void(*)(void*))jsonParseFree); - return (JsonParse*)tdsqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); + return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); } /* @@ -188325,10 +188325,10 @@ static JsonNode *jsonLookupAppend( /* ** Return the text of a syntax error message on a JSON path. Space is -** obtained from tdsqlite3_malloc(). +** obtained from sqlite3_malloc(). */ static char *jsonPathSyntaxError(const char *zErr){ - return tdsqlite3_mprintf("JSON path error near '%q'", zErr); + return sqlite3_mprintf("JSON path error near '%q'", zErr); } /* @@ -188345,7 +188345,7 @@ static JsonNode *jsonLookup( JsonParse *pParse, /* The JSON to search */ const char *zPath, /* The path to search */ int *pApnd, /* Append nodes to complete path if not NULL */ - tdsqlite3_context *pCtx /* Report errors here, if not NULL */ + sqlite3_context *pCtx /* Report errors here, if not NULL */ ){ const char *zErr = 0; JsonNode *pNode = 0; @@ -188365,10 +188365,10 @@ lookup_err: assert( zErr!=0 && pCtx!=0 ); zMsg = jsonPathSyntaxError(zErr); if( zMsg ){ - tdsqlite3_result_error(pCtx, zMsg, -1); - tdsqlite3_free(zMsg); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); }else{ - tdsqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(pCtx); } return 0; } @@ -188379,13 +188379,13 @@ lookup_err: ** or json_set(). */ static void jsonWrongNumArgs( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, const char *zFuncName ){ - char *zMsg = tdsqlite3_mprintf("json_%s() needs an odd number of arguments", + char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", zFuncName); - tdsqlite3_result_error(pCtx, zMsg, -1); - tdsqlite3_free(zMsg); + sqlite3_result_error(pCtx, zMsg, -1); + sqlite3_free(zMsg); } /* @@ -188419,16 +188419,16 @@ static void jsonRemoveAllNulls(JsonNode *pNode){ ** well-formed. */ static void jsonParseFunc( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ JsonString s; /* Output string - not real JSON */ JsonParse x; /* The parse */ u32 i; assert( argc==1 ); - if( jsonParse(&x, ctx, (const char*)tdsqlite3_value_text(argv[0])) ) return; + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; jsonParseFindParents(&x); jsonInit(&s, ctx); for(i=0; inNode ); if( argc==2 ){ - const char *zPath = (const char*)tdsqlite3_value_text(argv[1]); + const char *zPath = (const char*)sqlite3_value_text(argv[1]); pNode = jsonLookup(p, zPath, 0, ctx); }else{ pNode = p->aNode; @@ -188550,7 +188550,7 @@ static void jsonArrayLengthFunc( i += jsonNodeSize(&pNode[i]); } } - tdsqlite3_result_int64(ctx, n); + sqlite3_result_int64(ctx, n); } /* @@ -188562,9 +188562,9 @@ static void jsonArrayLengthFunc( ** is malformed. */ static void jsonExtractFunc( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ JsonParse *p; /* The parse */ JsonNode *pNode; @@ -188578,7 +188578,7 @@ static void jsonExtractFunc( jsonInit(&jx, ctx); jsonAppendChar(&jx, '['); for(i=1; inErr ) break; if( argc>2 ){ @@ -188595,7 +188595,7 @@ static void jsonExtractFunc( if( argc>2 && i==argc ){ jsonAppendChar(&jx, ']'); jsonResult(&jx); - tdsqlite3_result_subtype(ctx, JSON_SUBTYPE); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); } jsonReset(&jx); } @@ -188673,17 +188673,17 @@ static JsonNode *jsonMergePatch( ** on the two arguments. */ static void jsonPatchFunc( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ JsonParse x; /* The JSON that is being patched */ JsonParse y; /* The patch */ JsonNode *pResult; /* The result of the merge */ UNUSED_PARAM(argc); - if( jsonParse(&x, ctx, (const char*)tdsqlite3_value_text(argv[0])) ) return; - if( jsonParse(&y, ctx, (const char*)tdsqlite3_value_text(argv[1])) ){ + if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; + if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ jsonParseReset(&x); return; } @@ -188692,7 +188692,7 @@ static void jsonPatchFunc( if( pResult ){ jsonReturnJson(pResult, ctx, 0); }else{ - tdsqlite3_result_error_nomem(ctx); + sqlite3_result_error_nomem(ctx); } jsonParseReset(&x); jsonParseReset(&y); @@ -188705,9 +188705,9 @@ static void jsonPatchFunc( ** is not a string or if any value is a BLOB, throw an error. */ static void jsonObjectFunc( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ int i; JsonString jx; @@ -188715,28 +188715,28 @@ static void jsonObjectFunc( u32 n; if( argc&1 ){ - tdsqlite3_result_error(ctx, "json_object() requires an even number " + sqlite3_result_error(ctx, "json_object() requires an even number " "of arguments", -1); return; } jsonInit(&jx, ctx); jsonAppendChar(&jx, '{'); for(i=0; iaNode; } if( pNode ){ - tdsqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); + sqlite3_result_text(ctx, jsonType[pNode->eType], -1, SQLITE_STATIC); } } @@ -188904,14 +188904,14 @@ static void jsonTypeFunc( ** Return 0 otherwise. */ static void jsonValidFunc( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ JsonParse *p; /* The parse */ UNUSED_PARAM(argc); p = jsonParseCached(ctx, argv, 0); - tdsqlite3_result_int(ctx, p!=0); + sqlite3_result_int(ctx, p!=0); } @@ -188924,13 +188924,13 @@ static void jsonValidFunc( ** Return a JSON array composed of all values in the aggregate. */ static void jsonArrayStep( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ JsonString *pStr; UNUSED_PARAM(argc); - pStr = (JsonString*)tdsqlite3_aggregate_context(ctx, sizeof(*pStr)); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ jsonInit(pStr, ctx); @@ -188942,32 +188942,32 @@ static void jsonArrayStep( jsonAppendValue(pStr, argv[0]); } } -static void jsonArrayCompute(tdsqlite3_context *ctx, int isFinal){ +static void jsonArrayCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; - pStr = (JsonString*)tdsqlite3_aggregate_context(ctx, 0); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ pStr->pCtx = ctx; jsonAppendChar(pStr, ']'); if( pStr->bErr ){ - if( pStr->bErr==1 ) tdsqlite3_result_error_nomem(ctx); + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else if( isFinal ){ - tdsqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, - pStr->bStatic ? SQLITE_TRANSIENT : tdsqlite3_free); + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; }else{ - tdsqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); pStr->nUsed--; } }else{ - tdsqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); + sqlite3_result_text(ctx, "[]", 2, SQLITE_STATIC); } - tdsqlite3_result_subtype(ctx, JSON_SUBTYPE); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); } -static void jsonArrayValue(tdsqlite3_context *ctx){ +static void jsonArrayValue(sqlite3_context *ctx){ jsonArrayCompute(ctx, 0); } -static void jsonArrayFinal(tdsqlite3_context *ctx){ +static void jsonArrayFinal(sqlite3_context *ctx){ jsonArrayCompute(ctx, 1); } @@ -188979,9 +188979,9 @@ static void jsonArrayFinal(tdsqlite3_context *ctx){ ** text through that comma. */ static void jsonGroupInverse( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ unsigned int i; int inStr = 0; @@ -188991,7 +188991,7 @@ static void jsonGroupInverse( JsonString *pStr; UNUSED_PARAM(argc); UNUSED_PARAM(argv); - pStr = (JsonString*)tdsqlite3_aggregate_context(ctx, 0); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); #ifdef NEVER /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will ** always have been called to initalize it */ @@ -189026,15 +189026,15 @@ static void jsonGroupInverse( ** Return a JSON object composed of all names and values in the aggregate. */ static void jsonObjectStep( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ JsonString *pStr; const char *z; u32 n; UNUSED_PARAM(argc); - pStr = (JsonString*)tdsqlite3_aggregate_context(ctx, sizeof(*pStr)); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr)); if( pStr ){ if( pStr->zBuf==0 ){ jsonInit(pStr, ctx); @@ -189043,38 +189043,38 @@ static void jsonObjectStep( jsonAppendChar(pStr, ','); pStr->pCtx = ctx; } - z = (const char*)tdsqlite3_value_text(argv[0]); - n = (u32)tdsqlite3_value_bytes(argv[0]); + z = (const char*)sqlite3_value_text(argv[0]); + n = (u32)sqlite3_value_bytes(argv[0]); jsonAppendString(pStr, z, n); jsonAppendChar(pStr, ':'); jsonAppendValue(pStr, argv[1]); } } -static void jsonObjectCompute(tdsqlite3_context *ctx, int isFinal){ +static void jsonObjectCompute(sqlite3_context *ctx, int isFinal){ JsonString *pStr; - pStr = (JsonString*)tdsqlite3_aggregate_context(ctx, 0); + pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); if( pStr ){ jsonAppendChar(pStr, '}'); if( pStr->bErr ){ - if( pStr->bErr==1 ) tdsqlite3_result_error_nomem(ctx); + if( pStr->bErr==1 ) sqlite3_result_error_nomem(ctx); assert( pStr->bStatic ); }else if( isFinal ){ - tdsqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, - pStr->bStatic ? SQLITE_TRANSIENT : tdsqlite3_free); + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, + pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); pStr->bStatic = 1; }else{ - tdsqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); + sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); pStr->nUsed--; } }else{ - tdsqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); + sqlite3_result_text(ctx, "{}", 2, SQLITE_STATIC); } - tdsqlite3_result_subtype(ctx, JSON_SUBTYPE); + sqlite3_result_subtype(ctx, JSON_SUBTYPE); } -static void jsonObjectValue(tdsqlite3_context *ctx){ +static void jsonObjectValue(sqlite3_context *ctx){ jsonObjectCompute(ctx, 0); } -static void jsonObjectFinal(tdsqlite3_context *ctx){ +static void jsonObjectFinal(sqlite3_context *ctx){ jsonObjectCompute(ctx, 1); } @@ -189086,7 +189086,7 @@ static void jsonObjectFinal(tdsqlite3_context *ctx){ ****************************************************************************/ typedef struct JsonEachCursor JsonEachCursor; struct JsonEachCursor { - tdsqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3_vtab_cursor base; /* Base class - must be first */ u32 iRowid; /* The rowid */ u32 iBegin; /* The first node of the scan */ u32 i; /* Index in sParse.aNode[] of current row */ @@ -189100,13 +189100,13 @@ struct JsonEachCursor { /* Constructor for the json_each virtual table */ static int jsonEachConnect( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ - tdsqlite3_vtab *pNew; + sqlite3_vtab *pNew; int rc; /* Column numbers */ @@ -189128,30 +189128,30 @@ static int jsonEachConnect( UNUSED_PARAM(argv); UNUSED_PARAM(argc); UNUSED_PARAM(pAux); - rc = tdsqlite3_declare_vtab(db, + rc = sqlite3_declare_vtab(db, "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," "json HIDDEN,root HIDDEN)"); if( rc==SQLITE_OK ){ - pNew = *ppVtab = tdsqlite3_malloc( sizeof(*pNew) ); + pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) ); if( pNew==0 ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(*pNew)); - tdsqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); } return rc; } /* destructor for json_each virtual table */ -static int jsonEachDisconnect(tdsqlite3_vtab *pVtab){ - tdsqlite3_free(pVtab); +static int jsonEachDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); return SQLITE_OK; } /* constructor for a JsonEachCursor object for json_each(). */ -static int jsonEachOpenEach(tdsqlite3_vtab *p, tdsqlite3_vtab_cursor **ppCursor){ +static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ JsonEachCursor *pCur; UNUSED_PARAM(p); - pCur = tdsqlite3_malloc( sizeof(*pCur) ); + pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); *ppCursor = &pCur->base; @@ -189159,7 +189159,7 @@ static int jsonEachOpenEach(tdsqlite3_vtab *p, tdsqlite3_vtab_cursor **ppCursor) } /* constructor for a JsonEachCursor object for json_tree(). */ -static int jsonEachOpenTree(tdsqlite3_vtab *p, tdsqlite3_vtab_cursor **ppCursor){ +static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ int rc = jsonEachOpenEach(p, ppCursor); if( rc==SQLITE_OK ){ JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor; @@ -189171,8 +189171,8 @@ static int jsonEachOpenTree(tdsqlite3_vtab *p, tdsqlite3_vtab_cursor **ppCursor) /* Reset a JsonEachCursor back to its original state. Free any memory ** held. */ static void jsonEachCursorReset(JsonEachCursor *p){ - tdsqlite3_free(p->zJson); - tdsqlite3_free(p->zRoot); + sqlite3_free(p->zJson); + sqlite3_free(p->zRoot); jsonParseReset(&p->sParse); p->iRowid = 0; p->i = 0; @@ -189183,22 +189183,22 @@ static void jsonEachCursorReset(JsonEachCursor *p){ } /* Destructor for a jsonEachCursor object */ -static int jsonEachClose(tdsqlite3_vtab_cursor *cur){ +static int jsonEachClose(sqlite3_vtab_cursor *cur){ JsonEachCursor *p = (JsonEachCursor*)cur; jsonEachCursorReset(p); - tdsqlite3_free(cur); + sqlite3_free(cur); return SQLITE_OK; } /* Return TRUE if the jsonEachCursor object has been advanced off the end ** of the JSON object */ -static int jsonEachEof(tdsqlite3_vtab_cursor *cur){ +static int jsonEachEof(sqlite3_vtab_cursor *cur){ JsonEachCursor *p = (JsonEachCursor*)cur; return p->i >= p->iEnd; } /* Advance the cursor to the next element for json_tree() */ -static int jsonEachNext(tdsqlite3_vtab_cursor *cur){ +static int jsonEachNext(sqlite3_vtab_cursor *cur){ JsonEachCursor *p = (JsonEachCursor*)cur; if( p->bRecursive ){ if( p->sParse.aNode[p->i].jnFlags & JNODE_LABEL ) p->i++; @@ -189267,8 +189267,8 @@ static void jsonEachComputePath( /* Return the value of a column */ static int jsonEachColumn( - tdsqlite3_vtab_cursor *cur, /* The cursor */ - tdsqlite3_context *ctx, /* First argument to tdsqlite3_result_...() */ + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ int i /* Which column to return */ ){ JsonEachCursor *p = (JsonEachCursor*)cur; @@ -189286,7 +189286,7 @@ static int jsonEachColumn( }else{ iKey = p->iRowid; } - tdsqlite3_result_int64(ctx, (tdsqlite3_int64)iKey); + sqlite3_result_int64(ctx, (sqlite3_int64)iKey); } break; } @@ -189297,7 +189297,7 @@ static int jsonEachColumn( } case JEACH_TYPE: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; - tdsqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); + sqlite3_result_text(ctx, jsonType[pThis->eType], -1, SQLITE_STATIC); break; } case JEACH_ATOM: { @@ -189307,13 +189307,13 @@ static int jsonEachColumn( break; } case JEACH_ID: { - tdsqlite3_result_int64(ctx, - (tdsqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); + sqlite3_result_int64(ctx, + (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); break; } case JEACH_PARENT: { if( p->i>p->iBegin && p->bRecursive ){ - tdsqlite3_result_int64(ctx, (tdsqlite3_int64)p->sParse.aUp[p->i]); + sqlite3_result_int64(ctx, (sqlite3_int64)p->sParse.aUp[p->i]); } break; } @@ -189351,12 +189351,12 @@ static int jsonEachColumn( default: { const char *zRoot = p->zRoot; if( zRoot==0 ) zRoot = "$"; - tdsqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, zRoot, -1, SQLITE_STATIC); break; } case JEACH_JSON: { assert( i==JEACH_JSON ); - tdsqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, p->sParse.zJson, -1, SQLITE_STATIC); break; } } @@ -189364,7 +189364,7 @@ static int jsonEachColumn( } /* Return the current rowid value */ -static int jsonEachRowid(tdsqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ +static int jsonEachRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ JsonEachCursor *p = (JsonEachCursor*)cur; *pRowid = p->iRowid; return SQLITE_OK; @@ -189376,14 +189376,14 @@ static int jsonEachRowid(tdsqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ ** and 0 otherwise. */ static int jsonEachBestIndex( - tdsqlite3_vtab *tab, - tdsqlite3_index_info *pIdxInfo + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo ){ int i; /* Loop counter or computed array index */ int aIdx[2]; /* Index of constraints for JSON and ROOT */ int unusableMask = 0; /* Mask of unusable JSON and ROOT constraints */ int idxMask = 0; /* Mask of usable == constraints JSON and ROOT */ - const struct tdsqlite3_index_constraint *pConstraint; + const struct sqlite3_index_constraint *pConstraint; /* This implementation assumes that JSON and ROOT are the last two ** columns in the table */ @@ -189434,30 +189434,30 @@ static int jsonEachBestIndex( /* Start a search on a new JSON string */ static int jsonEachFilter( - tdsqlite3_vtab_cursor *cur, + sqlite3_vtab_cursor *cur, int idxNum, const char *idxStr, - int argc, tdsqlite3_value **argv + int argc, sqlite3_value **argv ){ JsonEachCursor *p = (JsonEachCursor*)cur; const char *z; const char *zRoot = 0; - tdsqlite3_int64 n; + sqlite3_int64 n; UNUSED_PARAM(idxStr); UNUSED_PARAM(argc); jsonEachCursorReset(p); if( idxNum==0 ) return SQLITE_OK; - z = (const char*)tdsqlite3_value_text(argv[0]); + z = (const char*)sqlite3_value_text(argv[0]); if( z==0 ) return SQLITE_OK; - n = tdsqlite3_value_bytes(argv[0]); - p->zJson = tdsqlite3_malloc64( n+1 ); + n = sqlite3_value_bytes(argv[0]); + p->zJson = sqlite3_malloc64( n+1 ); if( p->zJson==0 ) return SQLITE_NOMEM; memcpy(p->zJson, z, (size_t)n+1); if( jsonParse(&p->sParse, 0, p->zJson) ){ int rc = SQLITE_NOMEM; if( p->sParse.oom==0 ){ - tdsqlite3_free(cur->pVtab->zErrMsg); - cur->pVtab->zErrMsg = tdsqlite3_mprintf("malformed JSON"); + sqlite3_free(cur->pVtab->zErrMsg); + cur->pVtab->zErrMsg = sqlite3_mprintf("malformed JSON"); if( cur->pVtab->zErrMsg ) rc = SQLITE_ERROR; } jsonEachCursorReset(p); @@ -189469,10 +189469,10 @@ static int jsonEachFilter( JsonNode *pNode = 0; if( idxNum==3 ){ const char *zErr = 0; - zRoot = (const char*)tdsqlite3_value_text(argv[1]); + zRoot = (const char*)sqlite3_value_text(argv[1]); if( zRoot==0 ) return SQLITE_OK; - n = tdsqlite3_value_bytes(argv[1]); - p->zRoot = tdsqlite3_malloc64( n+1 ); + n = sqlite3_value_bytes(argv[1]); + p->zRoot = sqlite3_malloc64( n+1 ); if( p->zRoot==0 ) return SQLITE_NOMEM; memcpy(p->zRoot, zRoot, (size_t)n+1); if( zRoot[0]!='$' ){ @@ -189481,7 +189481,7 @@ static int jsonEachFilter( pNode = jsonLookupStep(&p->sParse, 0, p->zRoot+1, 0, &zErr); } if( zErr ){ - tdsqlite3_free(cur->pVtab->zErrMsg); + sqlite3_free(cur->pVtab->zErrMsg); cur->pVtab->zErrMsg = jsonPathSyntaxError(zErr); jsonEachCursorReset(p); return cur->pVtab->zErrMsg ? SQLITE_ERROR : SQLITE_NOMEM; @@ -189512,7 +189512,7 @@ static int jsonEachFilter( } /* The methods of the json_each virtual table */ -static tdsqlite3_module jsonEachModule = { +static sqlite3_module jsonEachModule = { 0, /* iVersion */ 0, /* xCreate */ jsonEachConnect, /* xConnect */ @@ -189540,7 +189540,7 @@ static tdsqlite3_module jsonEachModule = { }; /* The methods of the json_tree virtual table. */ -static tdsqlite3_module jsonTreeModule = { +static sqlite3_module jsonTreeModule = { 0, /* iVersion */ 0, /* xCreate */ jsonEachConnect, /* xConnect */ @@ -189574,14 +189574,14 @@ static tdsqlite3_module jsonTreeModule = { ** functions and the virtual table implemented by this file. ****************************************************************************/ -SQLITE_PRIVATE int tdsqlite3Json1Init(tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3Json1Init(sqlite3 *db){ int rc = SQLITE_OK; unsigned int i; static const struct { const char *zName; int nArg; int flag; - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**); + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } aFunc[] = { { "json", 1, 0, jsonRemoveFunc }, { "json_array", -1, 0, jsonArrayFunc }, @@ -189608,9 +189608,9 @@ SQLITE_PRIVATE int tdsqlite3Json1Init(tdsqlite3 *db){ static const struct { const char *zName; int nArg; - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**); - void (*xFinal)(tdsqlite3_context*); - void (*xValue)(tdsqlite3_context*); + void (*xStep)(sqlite3_context*,int,sqlite3_value**); + void (*xFinal)(sqlite3_context*); + void (*xValue)(sqlite3_context*); } aAgg[] = { { "json_group_array", 1, jsonArrayStep, jsonArrayFinal, jsonArrayValue }, @@ -189620,7 +189620,7 @@ SQLITE_PRIVATE int tdsqlite3Json1Init(tdsqlite3 *db){ #ifndef SQLITE_OMIT_VIRTUALTABLE static const struct { const char *zName; - tdsqlite3_module *pModule; + sqlite3_module *pModule; } aMod[] = { { "json_each", &jsonEachModule }, { "json_tree", &jsonTreeModule }, @@ -189631,13 +189631,13 @@ SQLITE_PRIVATE int tdsqlite3Json1Init(tdsqlite3 *db){ SQLITE_DETERMINISTIC | SQLITE_INNOCUOUS; for(i=0; iiNodeSize); + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode) + pRtree->iNodeSize); if( pNode ){ memset(pNode, 0, sizeof(RtreeNode) + pRtree->iNodeSize); pNode->zData = (u8 *)&pNode[1]; @@ -190314,9 +190314,9 @@ static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent){ */ static void nodeBlobReset(Rtree *pRtree){ if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){ - tdsqlite3_blob *pBlob = pRtree->pNodeBlob; + sqlite3_blob *pBlob = pRtree->pNodeBlob; pRtree->pNodeBlob = 0; - tdsqlite3_blob_close(pBlob); + sqlite3_blob_close(pBlob); } } @@ -190365,9 +190365,9 @@ static int nodeAcquire( } if( pRtree->pNodeBlob ){ - tdsqlite3_blob *pBlob = pRtree->pNodeBlob; + sqlite3_blob *pBlob = pRtree->pNodeBlob; pRtree->pNodeBlob = 0; - rc = tdsqlite3_blob_reopen(pBlob, iNode); + rc = sqlite3_blob_reopen(pBlob, iNode); pRtree->pNodeBlob = pBlob; if( rc ){ nodeBlobReset(pRtree); @@ -190375,23 +190375,23 @@ static int nodeAcquire( } } if( pRtree->pNodeBlob==0 ){ - char *zTab = tdsqlite3_mprintf("%s_node", pRtree->zName); + char *zTab = sqlite3_mprintf("%s_node", pRtree->zName); if( zTab==0 ) return SQLITE_NOMEM; - rc = tdsqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0, + rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0, &pRtree->pNodeBlob); - tdsqlite3_free(zTab); + sqlite3_free(zTab); } if( rc ){ nodeBlobReset(pRtree); *ppNode = 0; - /* If unable to open an tdsqlite3_blob on the desired row, that can only + /* If unable to open an sqlite3_blob on the desired row, that can only ** be because the shadow tables hold erroneous data. */ if( rc==SQLITE_ERROR ){ rc = SQLITE_CORRUPT_VTAB; RTREE_IS_CORRUPT(pRtree); } - }else if( pRtree->iNodeSize==tdsqlite3_blob_bytes(pRtree->pNodeBlob) ){ - pNode = (RtreeNode *)tdsqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize); + }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){ + pNode = (RtreeNode *)sqlite3_malloc64(sizeof(RtreeNode)+pRtree->iNodeSize); if( !pNode ){ rc = SQLITE_NOMEM; }else{ @@ -190402,7 +190402,7 @@ static int nodeAcquire( pNode->iNode = iNode; pNode->isDirty = 0; pNode->pNext = 0; - rc = tdsqlite3_blob_read(pRtree->pNodeBlob, pNode->zData, + rc = sqlite3_blob_read(pRtree->pNodeBlob, pNode->zData, pRtree->iNodeSize, 0); } } @@ -190444,7 +190444,7 @@ static int nodeAcquire( }else{ if( pNode ){ pRtree->nNodeRef--; - tdsqlite3_free(pNode); + sqlite3_free(pNode); } *ppNode = 0; } @@ -190515,19 +190515,19 @@ static int nodeInsertCell( static int nodeWrite(Rtree *pRtree, RtreeNode *pNode){ int rc = SQLITE_OK; if( pNode->isDirty ){ - tdsqlite3_stmt *p = pRtree->pWriteNode; + sqlite3_stmt *p = pRtree->pWriteNode; if( pNode->iNode ){ - tdsqlite3_bind_int64(p, 1, pNode->iNode); + sqlite3_bind_int64(p, 1, pNode->iNode); }else{ - tdsqlite3_bind_null(p, 1); + sqlite3_bind_null(p, 1); } - tdsqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC); - tdsqlite3_step(p); + sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC); + sqlite3_step(p); pNode->isDirty = 0; - rc = tdsqlite3_reset(p); - tdsqlite3_bind_null(p, 2); + rc = sqlite3_reset(p); + sqlite3_bind_null(p, 2); if( pNode->iNode==0 && rc==SQLITE_OK ){ - pNode->iNode = tdsqlite3_last_insert_rowid(pRtree->db); + pNode->iNode = sqlite3_last_insert_rowid(pRtree->db); nodeHashInsert(pRtree, pNode); } } @@ -190556,7 +190556,7 @@ static int nodeRelease(Rtree *pRtree, RtreeNode *pNode){ rc = nodeWrite(pRtree, pNode); } nodeHashDelete(pRtree, pNode); - tdsqlite3_free(pNode); + sqlite3_free(pNode); } } return rc; @@ -190618,17 +190618,17 @@ static void nodeGetCell( ** the virtual table module xCreate() and xConnect() methods. */ static int rtreeInit( - tdsqlite3 *, void *, int, const char *const*, tdsqlite3_vtab **, char **, int + sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int ); /* ** Rtree virtual table module xCreate method. */ static int rtreeCreate( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1); @@ -190638,10 +190638,10 @@ static int rtreeCreate( ** Rtree virtual table module xConnect method. */ static int rtreeConnect( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0); @@ -190665,24 +190665,24 @@ static void rtreeRelease(Rtree *pRtree){ assert( pRtree->nCursor==0 ); nodeBlobReset(pRtree); assert( pRtree->nNodeRef==0 || pRtree->bCorrupt ); - tdsqlite3_finalize(pRtree->pWriteNode); - tdsqlite3_finalize(pRtree->pDeleteNode); - tdsqlite3_finalize(pRtree->pReadRowid); - tdsqlite3_finalize(pRtree->pWriteRowid); - tdsqlite3_finalize(pRtree->pDeleteRowid); - tdsqlite3_finalize(pRtree->pReadParent); - tdsqlite3_finalize(pRtree->pWriteParent); - tdsqlite3_finalize(pRtree->pDeleteParent); - tdsqlite3_finalize(pRtree->pWriteAux); - tdsqlite3_free(pRtree->zReadAuxSql); - tdsqlite3_free(pRtree); + sqlite3_finalize(pRtree->pWriteNode); + sqlite3_finalize(pRtree->pDeleteNode); + sqlite3_finalize(pRtree->pReadRowid); + sqlite3_finalize(pRtree->pWriteRowid); + sqlite3_finalize(pRtree->pDeleteRowid); + sqlite3_finalize(pRtree->pReadParent); + sqlite3_finalize(pRtree->pWriteParent); + sqlite3_finalize(pRtree->pDeleteParent); + sqlite3_finalize(pRtree->pWriteAux); + sqlite3_free(pRtree->zReadAuxSql); + sqlite3_free(pRtree); } } /* ** Rtree virtual table module xDisconnect method. */ -static int rtreeDisconnect(tdsqlite3_vtab *pVtab){ +static int rtreeDisconnect(sqlite3_vtab *pVtab){ rtreeRelease((Rtree *)pVtab); return SQLITE_OK; } @@ -190690,10 +190690,10 @@ static int rtreeDisconnect(tdsqlite3_vtab *pVtab){ /* ** Rtree virtual table module xDestroy method. */ -static int rtreeDestroy(tdsqlite3_vtab *pVtab){ +static int rtreeDestroy(sqlite3_vtab *pVtab){ Rtree *pRtree = (Rtree *)pVtab; int rc; - char *zCreate = tdsqlite3_mprintf( + char *zCreate = sqlite3_mprintf( "DROP TABLE '%q'.'%q_node';" "DROP TABLE '%q'.'%q_rowid';" "DROP TABLE '%q'.'%q_parent';", @@ -190705,8 +190705,8 @@ static int rtreeDestroy(tdsqlite3_vtab *pVtab){ rc = SQLITE_NOMEM; }else{ nodeBlobReset(pRtree); - rc = tdsqlite3_exec(pRtree->db, zCreate, 0, 0, 0); - tdsqlite3_free(zCreate); + rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); } if( rc==SQLITE_OK ){ rtreeRelease(pRtree); @@ -190718,19 +190718,19 @@ static int rtreeDestroy(tdsqlite3_vtab *pVtab){ /* ** Rtree virtual table module xOpen method. */ -static int rtreeOpen(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCursor){ +static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ int rc = SQLITE_NOMEM; Rtree *pRtree = (Rtree *)pVTab; RtreeCursor *pCsr; - pCsr = (RtreeCursor *)tdsqlite3_malloc64(sizeof(RtreeCursor)); + pCsr = (RtreeCursor *)sqlite3_malloc64(sizeof(RtreeCursor)); if( pCsr ){ memset(pCsr, 0, sizeof(RtreeCursor)); pCsr->base.pVtab = pVTab; rc = SQLITE_OK; pRtree->nCursor++; } - *ppCursor = (tdsqlite3_vtab_cursor *)pCsr; + *ppCursor = (sqlite3_vtab_cursor *)pCsr; return rc; } @@ -190742,24 +190742,24 @@ static int rtreeOpen(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCursor){ static void resetCursor(RtreeCursor *pCsr){ Rtree *pRtree = (Rtree *)(pCsr->base.pVtab); int ii; - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; if( pCsr->aConstraint ){ int i; /* Used to iterate through constraint array */ for(i=0; inConstraint; i++){ - tdsqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; + sqlite3_rtree_query_info *pInfo = pCsr->aConstraint[i].pInfo; if( pInfo ){ if( pInfo->xDelUser ) pInfo->xDelUser(pInfo->pUser); - tdsqlite3_free(pInfo); + sqlite3_free(pInfo); } } - tdsqlite3_free(pCsr->aConstraint); + sqlite3_free(pCsr->aConstraint); pCsr->aConstraint = 0; } for(ii=0; iiaNode[ii]); - tdsqlite3_free(pCsr->aPoint); + sqlite3_free(pCsr->aPoint); pStmt = pCsr->pReadAux; memset(pCsr, 0, sizeof(RtreeCursor)); - pCsr->base.pVtab = (tdsqlite3_vtab*)pRtree; + pCsr->base.pVtab = (sqlite3_vtab*)pRtree; pCsr->pReadAux = pStmt; } @@ -190767,13 +190767,13 @@ static void resetCursor(RtreeCursor *pCsr){ /* ** Rtree virtual table module xClose method. */ -static int rtreeClose(tdsqlite3_vtab_cursor *cur){ +static int rtreeClose(sqlite3_vtab_cursor *cur){ Rtree *pRtree = (Rtree *)(cur->pVtab); RtreeCursor *pCsr = (RtreeCursor *)cur; assert( pRtree->nCursor>0 ); resetCursor(pCsr); - tdsqlite3_finalize(pCsr->pReadAux); - tdsqlite3_free(pCsr); + sqlite3_finalize(pCsr->pReadAux); + sqlite3_free(pCsr); pRtree->nCursor--; nodeBlobReset(pRtree); return SQLITE_OK; @@ -190785,7 +190785,7 @@ static int rtreeClose(tdsqlite3_vtab_cursor *cur){ ** Return non-zero if the cursor does not currently point to a valid ** record (i.e if the scan has finished), or zero otherwise. */ -static int rtreeEof(tdsqlite3_vtab_cursor *cur){ +static int rtreeEof(sqlite3_vtab_cursor *cur){ RtreeCursor *pCsr = (RtreeCursor *)cur; return pCsr->atEOF; } @@ -190805,13 +190805,13 @@ static int rtreeEof(tdsqlite3_vtab_cursor *cur){ #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ c.u = _byteswap_ulong(*(u32*)a); \ - r = eInt ? (tdsqlite3_rtree_dbl)c.i : (tdsqlite3_rtree_dbl)c.f; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ c.u = __builtin_bswap32(*(u32*)a); \ - r = eInt ? (tdsqlite3_rtree_dbl)c.i : (tdsqlite3_rtree_dbl)c.f; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } #elif SQLITE_BYTEORDER==1234 #define RTREE_DECODE_COORD(eInt, a, r) { \ @@ -190819,20 +190819,20 @@ static int rtreeEof(tdsqlite3_vtab_cursor *cur){ memcpy(&c.u,a,4); \ c.u = ((c.u>>24)&0xff)|((c.u>>8)&0xff00)| \ ((c.u&0xff)<<24)|((c.u&0xff00)<<8); \ - r = eInt ? (tdsqlite3_rtree_dbl)c.i : (tdsqlite3_rtree_dbl)c.f; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } #elif SQLITE_BYTEORDER==4321 #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ memcpy(&c.u,a,4); \ - r = eInt ? (tdsqlite3_rtree_dbl)c.i : (tdsqlite3_rtree_dbl)c.f; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } #else #define RTREE_DECODE_COORD(eInt, a, r) { \ RtreeCoord c; /* Coordinate decoded */ \ c.u = ((u32)a[0]<<24) + ((u32)a[1]<<16) \ +((u32)a[2]<<8) + a[3]; \ - r = eInt ? (tdsqlite3_rtree_dbl)c.i : (tdsqlite3_rtree_dbl)c.f; \ + r = eInt ? (sqlite3_rtree_dbl)c.i : (sqlite3_rtree_dbl)c.f; \ } #endif @@ -190845,14 +190845,14 @@ static int rtreeCallbackConstraint( int eInt, /* True if RTree holding integer coordinates */ u8 *pCellData, /* Raw cell content */ RtreeSearchPoint *pSearch, /* Container of this cell */ - tdsqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ + sqlite3_rtree_dbl *prScore, /* OUT: score for the cell */ int *peWithin /* OUT: visibility of the cell */ ){ - tdsqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ + sqlite3_rtree_query_info *pInfo = pConstraint->pInfo; /* Callback info */ int nCoord = pInfo->nCoord; /* No. of coordinates */ int rc; /* Callback return code */ RtreeCoord c; /* Translator union */ - tdsqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ + sqlite3_rtree_dbl aCoord[RTREE_MAX_DIMENSIONS*2]; /* Decoded coordinates */ assert( pConstraint->op==RTREE_MATCH || pConstraint->op==RTREE_QUERY ); assert( nCoord==2 || nCoord==4 || nCoord==6 || nCoord==8 || nCoord==10 ); @@ -190893,7 +190893,7 @@ static int rtreeCallbackConstraint( } if( pConstraint->op==RTREE_MATCH ){ int eWithin = 0; - rc = pConstraint->u.xGeom((tdsqlite3_rtree_geometry*)pInfo, + rc = pConstraint->u.xGeom((sqlite3_rtree_geometry*)pInfo, nCoord, aCoord, &eWithin); if( eWithin==0 ) *peWithin = NOT_WITHIN; *prScore = RTREE_ZERO; @@ -190922,7 +190922,7 @@ static void rtreeNonleafConstraint( u8 *pCellData, /* Raw cell content as appears on disk */ int *peWithin /* Adjust downward, as appropriate */ ){ - tdsqlite3_rtree_dbl val; /* Coordinate value convert to a double */ + sqlite3_rtree_dbl val; /* Coordinate value convert to a double */ /* p->iCoord might point to either a lower or upper bound coordinate ** in a coordinate pair. But make pCellData point to the lower bound. @@ -191079,7 +191079,7 @@ static RtreeSearchPoint *rtreeSearchPointFirst(RtreeCursor *pCur){ ** Get the RtreeNode for the search point with the lowest score. */ static RtreeNode *rtreeNodeOfFirstSearchPoint(RtreeCursor *pCur, int *pRC){ - tdsqlite3_int64 id; + sqlite3_int64 id; int ii = 1 - pCur->bPoint; assert( ii==0 || ii==1 ); assert( pCur->bPoint || pCur->nPoint ); @@ -191103,7 +191103,7 @@ static RtreeSearchPoint *rtreeEnqueue( RtreeSearchPoint *pNew; if( pCur->nPoint>=pCur->nPointAlloc ){ int nNew = pCur->nPointAlloc*2 + 8; - pNew = tdsqlite3_realloc64(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); + pNew = sqlite3_realloc64(pCur->aPoint, nNew*sizeof(pCur->aPoint[0])); if( pNew==0 ) return 0; pCur->aPoint = pNew; pCur->nPointAlloc = nNew; @@ -191265,7 +191265,7 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){ assert( nCell<200 ); pCellData = pNode->zData + (4+pRtree->nBytesPerCell*p->iCell); while( p->iCellaConstraint + ii; @@ -191325,7 +191325,7 @@ static int rtreeStepToLeaf(RtreeCursor *pCur){ /* ** Rtree virtual table module xNext method. */ -static int rtreeNext(tdsqlite3_vtab_cursor *pVtabCursor){ +static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){ RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; int rc = SQLITE_OK; @@ -191333,7 +191333,7 @@ static int rtreeNext(tdsqlite3_vtab_cursor *pVtabCursor){ RTREE_QUEUE_TRACE(pCsr, "POP-Nx:"); if( pCsr->bAuxValid ){ pCsr->bAuxValid = 0; - tdsqlite3_reset(pCsr->pReadAux); + sqlite3_reset(pCsr->pReadAux); } rtreeSearchPointPop(pCsr); rc = rtreeStepToLeaf(pCsr); @@ -191343,7 +191343,7 @@ static int rtreeNext(tdsqlite3_vtab_cursor *pVtabCursor){ /* ** Rtree virtual table module xRowid method. */ -static int rtreeRowid(tdsqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ +static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); int rc = SQLITE_OK; @@ -191357,7 +191357,7 @@ static int rtreeRowid(tdsqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){ /* ** Rtree virtual table module xColumn method. */ -static int rtreeColumn(tdsqlite3_vtab_cursor *cur, tdsqlite3_context *ctx, int i){ +static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ Rtree *pRtree = (Rtree *)cur->pVtab; RtreeCursor *pCsr = (RtreeCursor *)cur; RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); @@ -191368,38 +191368,38 @@ static int rtreeColumn(tdsqlite3_vtab_cursor *cur, tdsqlite3_context *ctx, int i if( rc ) return rc; if( p==0 ) return SQLITE_OK; if( i==0 ){ - tdsqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); + sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell)); }else if( i<=pRtree->nDim2 ){ nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c); #ifndef SQLITE_RTREE_INT_ONLY if( pRtree->eCoordType==RTREE_COORD_REAL32 ){ - tdsqlite3_result_double(ctx, c.f); + sqlite3_result_double(ctx, c.f); }else #endif { assert( pRtree->eCoordType==RTREE_COORD_INT32 ); - tdsqlite3_result_int(ctx, c.i); + sqlite3_result_int(ctx, c.i); } }else{ if( !pCsr->bAuxValid ){ if( pCsr->pReadAux==0 ){ - rc = tdsqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, &pCsr->pReadAux, 0); if( rc ) return rc; } - tdsqlite3_bind_int64(pCsr->pReadAux, 1, + sqlite3_bind_int64(pCsr->pReadAux, 1, nodeGetRowid(pRtree, pNode, p->iCell)); - rc = tdsqlite3_step(pCsr->pReadAux); + rc = sqlite3_step(pCsr->pReadAux); if( rc==SQLITE_ROW ){ pCsr->bAuxValid = 1; }else{ - tdsqlite3_reset(pCsr->pReadAux); + sqlite3_reset(pCsr->pReadAux); if( rc==SQLITE_DONE ) rc = SQLITE_OK; return rc; } } - tdsqlite3_result_value(ctx, - tdsqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1)); + sqlite3_result_value(ctx, + sqlite3_column_value(pCsr->pReadAux, i - pRtree->nDim2 + 1)); } return SQLITE_OK; } @@ -191415,18 +191415,18 @@ static int findLeafNode( Rtree *pRtree, /* RTree to search */ i64 iRowid, /* The rowid searching for */ RtreeNode **ppLeaf, /* Write the node here */ - tdsqlite3_int64 *piNode /* Write the node-id here */ + sqlite3_int64 *piNode /* Write the node-id here */ ){ int rc; *ppLeaf = 0; - tdsqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); - if( tdsqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ - i64 iNode = tdsqlite3_column_int64(pRtree->pReadRowid, 0); + sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid); + if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){ + i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0); if( piNode ) *piNode = iNode; rc = nodeAcquire(pRtree, iNode, 0, ppLeaf); - tdsqlite3_reset(pRtree->pReadRowid); + sqlite3_reset(pRtree->pReadRowid); }else{ - rc = tdsqlite3_reset(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); } return rc; } @@ -191437,14 +191437,14 @@ static int findLeafNode( ** first argument to this function is the right-hand operand to the MATCH ** operator. */ -static int deserializeGeometry(tdsqlite3_value *pValue, RtreeConstraint *pCons){ +static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){ RtreeMatchArg *pBlob, *pSrc; /* BLOB returned by geometry function */ - tdsqlite3_rtree_query_info *pInfo; /* Callback information */ + sqlite3_rtree_query_info *pInfo; /* Callback information */ - pSrc = tdsqlite3_value_pointer(pValue, "RtreeMatchArg"); + pSrc = sqlite3_value_pointer(pValue, "RtreeMatchArg"); if( pSrc==0 ) return SQLITE_ERROR; - pInfo = (tdsqlite3_rtree_query_info*) - tdsqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize ); + pInfo = (sqlite3_rtree_query_info*) + sqlite3_malloc64( sizeof(*pInfo)+pSrc->iSize ); if( !pInfo ) return SQLITE_NOMEM; memset(pInfo, 0, sizeof(*pInfo)); pBlob = (RtreeMatchArg*)&pInfo[1]; @@ -191468,9 +191468,9 @@ static int deserializeGeometry(tdsqlite3_value *pValue, RtreeConstraint *pCons){ ** Rtree virtual table module xFilter method. */ static int rtreeFilter( - tdsqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, - int argc, tdsqlite3_value **argv + int argc, sqlite3_value **argv ){ Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; @@ -191489,11 +191489,11 @@ static int rtreeFilter( /* Special case - lookup by rowid. */ RtreeNode *pLeaf; /* Leaf on which the required cell resides */ RtreeSearchPoint *p; /* Search point for the leaf */ - i64 iRowid = tdsqlite3_value_int64(argv[0]); + i64 iRowid = sqlite3_value_int64(argv[0]); i64 iNode = 0; - int eType = tdsqlite3_value_numeric_type(argv[0]); + int eType = sqlite3_value_numeric_type(argv[0]); if( eType==SQLITE_INTEGER - || (eType==SQLITE_FLOAT && tdsqlite3_value_double(argv[0])==iRowid) + || (eType==SQLITE_FLOAT && sqlite3_value_double(argv[0])==iRowid) ){ rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); }else{ @@ -191518,7 +191518,7 @@ static int rtreeFilter( */ rc = nodeAcquire(pRtree, 1, 0, &pRoot); if( rc==SQLITE_OK && argc>0 ){ - pCsr->aConstraint = tdsqlite3_malloc64(sizeof(RtreeConstraint)*argc); + pCsr->aConstraint = sqlite3_malloc64(sizeof(RtreeConstraint)*argc); pCsr->nConstraint = argc; if( !pCsr->aConstraint ){ rc = SQLITE_NOMEM; @@ -191529,13 +191529,13 @@ static int rtreeFilter( || (idxStr && (int)strlen(idxStr)==argc*2) ); for(ii=0; iiaConstraint[ii]; - int eType = tdsqlite3_value_numeric_type(argv[ii]); + int eType = sqlite3_value_numeric_type(argv[ii]); p->op = idxStr[ii*2]; p->iCoord = idxStr[ii*2+1]-'0'; if( p->op>=RTREE_MATCH ){ /* A MATCH operator. The right-hand-side must be a blob that ** can be cast into an RtreeMatchArg object. One created using - ** an tdsqlite3_rtree_geometry_callback() SQL user function. + ** an sqlite3_rtree_geometry_callback() SQL user function. */ rc = deserializeGeometry(argv[ii], p); if( rc!=SQLITE_OK ){ @@ -191546,9 +191546,9 @@ static int rtreeFilter( p->pInfo->mxLevel = pRtree->iDepth + 1; }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ #ifdef SQLITE_RTREE_INT_ONLY - p->u.rValue = tdsqlite3_value_int64(argv[ii]); + p->u.rValue = sqlite3_value_int64(argv[ii]); #else - p->u.rValue = tdsqlite3_value_double(argv[ii]); + p->u.rValue = sqlite3_value_double(argv[ii]); #endif }else{ p->u.rValue = RTREE_ZERO; @@ -191597,7 +191597,7 @@ static int rtreeFilter( ** If strategy 1 is used, then idxStr is not meaningful. If strategy ** 2 is used, idxStr is formatted to contain 2 bytes for each ** constraint used. The first two bytes of idxStr correspond to -** the constraint in tdsqlite3_index_info.aConstraintUsage[] with +** the constraint in sqlite3_index_info.aConstraintUsage[] with ** (argvIndex==1) etc. ** ** The first of each pair of bytes in idxStr identifies the constraint @@ -191617,7 +191617,7 @@ static int rtreeFilter( ** to which the constraint applies. The leftmost coordinate column ** is 'a', the second from the left 'b' etc. */ -static int rtreeBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ +static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ Rtree *pRtree = (Rtree*)tab; int rc = SQLITE_OK; int ii; @@ -191640,7 +191640,7 @@ static int rtreeBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ assert( pIdxInfo->idxStr==0 ); for(ii=0; iinConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){ - struct tdsqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; if( bMatch==0 && p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ @@ -191692,7 +191692,7 @@ static int rtreeBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ pIdxInfo->idxNum = 2; pIdxInfo->needToFreeIdxStr = 1; - if( iIdx>0 && 0==(pIdxInfo->idxStr = tdsqlite3_mprintf("%s", zIdxStr)) ){ + if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ return SQLITE_NOMEM; } @@ -191842,7 +191842,7 @@ static int ChooseLeaf( for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ int iCell; - tdsqlite3_int64 iBest = 0; + sqlite3_int64 iBest = 0; RtreeDValue fMinGrowth = RTREE_ZERO; RtreeDValue fMinArea = RTREE_ZERO; @@ -191874,7 +191874,7 @@ static int ChooseLeaf( } } - tdsqlite3_free(aCell); + sqlite3_free(aCell); rc = nodeAcquire(pRtree, iBest, pNode, &pChild); nodeRelease(pRtree, pNode); pNode = pChild; @@ -191920,21 +191920,21 @@ static int AdjustTree( /* ** Write mapping (iRowid->iNode) to the _rowid table. */ -static int rowidWrite(Rtree *pRtree, tdsqlite3_int64 iRowid, tdsqlite3_int64 iNode){ - tdsqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); - tdsqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); - tdsqlite3_step(pRtree->pWriteRowid); - return tdsqlite3_reset(pRtree->pWriteRowid); +static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){ + sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid); + sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode); + sqlite3_step(pRtree->pWriteRowid); + return sqlite3_reset(pRtree->pWriteRowid); } /* ** Write mapping (iNode->iPar) to the _parent table. */ -static int parentWrite(Rtree *pRtree, tdsqlite3_int64 iNode, tdsqlite3_int64 iPar){ - tdsqlite3_bind_int64(pRtree->pWriteParent, 1, iNode); - tdsqlite3_bind_int64(pRtree->pWriteParent, 2, iPar); - tdsqlite3_step(pRtree->pWriteParent); - return tdsqlite3_reset(pRtree->pWriteParent); +static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){ + sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode); + sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar); + sqlite3_step(pRtree->pWriteParent); + return sqlite3_reset(pRtree->pWriteParent); } static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int); @@ -192099,9 +192099,9 @@ static int splitNodeStartree( int iBestSplit = 0; RtreeDValue fBestMargin = RTREE_ZERO; - tdsqlite3_int64 nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); + sqlite3_int64 nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int)); - aaSorted = (int **)tdsqlite3_malloc64(nByte); + aaSorted = (int **)sqlite3_malloc64(nByte); if( !aaSorted ){ return SQLITE_NOMEM; } @@ -192175,7 +192175,7 @@ static int splitNodeStartree( cellUnion(pRtree, pBbox, pCell); } - tdsqlite3_free(aaSorted); + sqlite3_free(aaSorted); return SQLITE_OK; } @@ -192186,7 +192186,7 @@ static int updateMapping( RtreeNode *pNode, int iHeight ){ - int (*xSetMapping)(Rtree *, tdsqlite3_int64, tdsqlite3_int64); + int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64); xSetMapping = ((iHeight==0)?rowidWrite:parentWrite); if( iHeight>0 ){ RtreeNode *pChild = nodeHashLookup(pRtree, iRowid); @@ -192222,7 +192222,7 @@ static int SplitNode( /* Allocate an array and populate it with a copy of pCell and ** all cells from node pLeft. Then zero the original node. */ - aCell = tdsqlite3_malloc64((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); + aCell = sqlite3_malloc64((sizeof(RtreeCell)+sizeof(int))*(nCell+1)); if( !aCell ){ rc = SQLITE_NOMEM; goto splitnode_out; @@ -192331,7 +192331,7 @@ static int SplitNode( splitnode_out: nodeRelease(pRtree, pRight); nodeRelease(pRtree, pLeft); - tdsqlite3_free(aCell); + sqlite3_free(aCell); return rc; } @@ -192350,9 +192350,9 @@ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ int rc = SQLITE_OK; RtreeNode *pChild = pLeaf; while( rc==SQLITE_OK && pChild->iNode!=1 && pChild->pParent==0 ){ - int rc2 = SQLITE_OK; /* tdsqlite3_reset() return code */ - tdsqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode); - rc = tdsqlite3_step(pRtree->pReadParent); + int rc2 = SQLITE_OK; /* sqlite3_reset() return code */ + sqlite3_bind_int64(pRtree->pReadParent, 1, pChild->iNode); + rc = sqlite3_step(pRtree->pReadParent); if( rc==SQLITE_ROW ){ RtreeNode *pTest; /* Used to test for reference loops */ i64 iNode; /* Node number of parent node */ @@ -192362,13 +192362,13 @@ static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){ ** want to do this as it leads to a memory leak when trying to delete ** the referenced counted node structures. */ - iNode = tdsqlite3_column_int64(pRtree->pReadParent, 0); + iNode = sqlite3_column_int64(pRtree->pReadParent, 0); for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent); if( !pTest ){ rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent); } } - rc = tdsqlite3_reset(pRtree->pReadParent); + rc = sqlite3_reset(pRtree->pReadParent); if( rc==SQLITE_OK ) rc = rc2; if( rc==SQLITE_OK && !pChild->pParent ){ RTREE_IS_CORRUPT(pRtree); @@ -192405,16 +192405,16 @@ static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){ } /* Remove the xxx_node entry. */ - tdsqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); - tdsqlite3_step(pRtree->pDeleteNode); - if( SQLITE_OK!=(rc = tdsqlite3_reset(pRtree->pDeleteNode)) ){ + sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode); + sqlite3_step(pRtree->pDeleteNode); + if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){ return rc; } /* Remove the xxx_parent entry. */ - tdsqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); - tdsqlite3_step(pRtree->pDeleteParent); - if( SQLITE_OK!=(rc = tdsqlite3_reset(pRtree->pDeleteParent)) ){ + sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode); + sqlite3_step(pRtree->pDeleteParent); + if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){ return rc; } @@ -192513,7 +192513,7 @@ static int Reinsert( /* Allocate the buffers used by this operation. The allocation is ** relinquished before this function returns. */ - aCell = (RtreeCell *)tdsqlite3_malloc64(n * ( + aCell = (RtreeCell *)sqlite3_malloc64(n * ( sizeof(RtreeCell) + /* aCell array */ sizeof(int) + /* aOrder array */ sizeof(int) + /* aSpare array */ @@ -192585,7 +192585,7 @@ static int Reinsert( } } - tdsqlite3_free(aCell); + sqlite3_free(aCell); return rc; } @@ -192659,18 +192659,18 @@ static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){ */ static int rtreeNewRowid(Rtree *pRtree, i64 *piRowid){ int rc; - tdsqlite3_bind_null(pRtree->pWriteRowid, 1); - tdsqlite3_bind_null(pRtree->pWriteRowid, 2); - tdsqlite3_step(pRtree->pWriteRowid); - rc = tdsqlite3_reset(pRtree->pWriteRowid); - *piRowid = tdsqlite3_last_insert_rowid(pRtree->db); + sqlite3_bind_null(pRtree->pWriteRowid, 1); + sqlite3_bind_null(pRtree->pWriteRowid, 2); + sqlite3_step(pRtree->pWriteRowid); + rc = sqlite3_reset(pRtree->pWriteRowid); + *piRowid = sqlite3_last_insert_rowid(pRtree->db); return rc; } /* ** Remove the entry with rowid=iDelete from the r-tree structure. */ -static int rtreeDeleteRowid(Rtree *pRtree, tdsqlite3_int64 iDelete){ +static int rtreeDeleteRowid(Rtree *pRtree, sqlite3_int64 iDelete){ int rc; /* Return code */ RtreeNode *pLeaf = 0; /* Leaf node containing record iDelete */ int iCell; /* Index of iDelete cell in pLeaf */ @@ -192706,9 +192706,9 @@ static int rtreeDeleteRowid(Rtree *pRtree, tdsqlite3_int64 iDelete){ /* Delete the corresponding entry in the _rowid table. */ if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); - tdsqlite3_step(pRtree->pDeleteRowid); - rc = tdsqlite3_reset(pRtree->pDeleteRowid); + sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete); + sqlite3_step(pRtree->pDeleteRowid); + rc = sqlite3_reset(pRtree->pDeleteRowid); } /* Check if the root node now has exactly one child. If so, remove @@ -192743,7 +192743,7 @@ static int rtreeDeleteRowid(Rtree *pRtree, tdsqlite3_int64 iDelete){ } pRtree->pDeleted = pLeaf->pNext; pRtree->nNodeRef--; - tdsqlite3_free(pLeaf); + sqlite3_free(pLeaf); } /* Release the reference to the root node. */ @@ -192764,19 +192764,19 @@ static int rtreeDeleteRowid(Rtree *pRtree, tdsqlite3_int64 iDelete){ #if !defined(SQLITE_RTREE_INT_ONLY) /* -** Convert an tdsqlite3_value into an RtreeValue (presumably a float) +** Convert an sqlite3_value into an RtreeValue (presumably a float) ** while taking care to round toward negative or positive, respectively. */ -static RtreeValue rtreeValueDown(tdsqlite3_value *v){ - double d = tdsqlite3_value_double(v); +static RtreeValue rtreeValueDown(sqlite3_value *v){ + double d = sqlite3_value_double(v); float f = (float)d; if( f>d ){ f = (float)(d*(d<0 ? RNDAWAY : RNDTOWARDS)); } return f; } -static RtreeValue rtreeValueUp(tdsqlite3_value *v){ - double d = tdsqlite3_value_double(v); +static RtreeValue rtreeValueUp(sqlite3_value *v){ + double d = sqlite3_value_double(v); float f = (float)d; if( fzDb, pRtree->zName); + zSql = sqlite3_mprintf("SELECT * FROM %Q.%Q", pRtree->zDb, pRtree->zName); if( zSql ){ - rc = tdsqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(pRtree->db, zSql, -1, &pStmt, 0); }else{ rc = SQLITE_NOMEM; } - tdsqlite3_free(zSql); + sqlite3_free(zSql); if( rc==SQLITE_OK ){ if( iCol==0 ){ - const char *zCol = tdsqlite3_column_name(pStmt, 0); - pRtree->base.zErrMsg = tdsqlite3_mprintf( + const char *zCol = sqlite3_column_name(pStmt, 0); + pRtree->base.zErrMsg = sqlite3_mprintf( "UNIQUE constraint failed: %s.%s", pRtree->zName, zCol ); }else{ - const char *zCol1 = tdsqlite3_column_name(pStmt, iCol); - const char *zCol2 = tdsqlite3_column_name(pStmt, iCol+1); - pRtree->base.zErrMsg = tdsqlite3_mprintf( + const char *zCol1 = sqlite3_column_name(pStmt, iCol); + const char *zCol2 = sqlite3_column_name(pStmt, iCol+1); + pRtree->base.zErrMsg = sqlite3_mprintf( "rtree constraint failed: %s.(%s<=%s)", pRtree->zName, zCol1, zCol2 ); } } - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); return (rc==SQLITE_OK ? SQLITE_CONSTRAINT : rc); } @@ -192837,9 +192837,9 @@ static int rtreeConstraintError(Rtree *pRtree, int iCol){ ** The xUpdate method for rtree module virtual tables. */ static int rtreeUpdate( - tdsqlite3_vtab *pVtab, + sqlite3_vtab *pVtab, int nData, - tdsqlite3_value **aData, + sqlite3_value **aData, sqlite_int64 *pRowid ){ Rtree *pRtree = (Rtree *)pVtab; @@ -192897,8 +192897,8 @@ static int rtreeUpdate( #endif { for(ii=0; iicell.aCoord[ii+1].i ){ rc = rtreeConstraintError(pRtree, ii+1); goto constraint; @@ -192908,17 +192908,17 @@ static int rtreeUpdate( /* If a rowid value was supplied, check if it is already present in ** the table. If so, the constraint has failed. */ - if( tdsqlite3_value_type(aData[2])!=SQLITE_NULL ){ - cell.iRowid = tdsqlite3_value_int64(aData[2]); - if( tdsqlite3_value_type(aData[0])==SQLITE_NULL - || tdsqlite3_value_int64(aData[0])!=cell.iRowid + if( sqlite3_value_type(aData[2])!=SQLITE_NULL ){ + cell.iRowid = sqlite3_value_int64(aData[2]); + if( sqlite3_value_type(aData[0])==SQLITE_NULL + || sqlite3_value_int64(aData[0])!=cell.iRowid ){ int steprc; - tdsqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); - steprc = tdsqlite3_step(pRtree->pReadRowid); - rc = tdsqlite3_reset(pRtree->pReadRowid); + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); if( SQLITE_ROW==steprc ){ - if( tdsqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ rc = rtreeDeleteRowid(pRtree, cell.iRowid); }else{ rc = rtreeConstraintError(pRtree, 0); @@ -192934,8 +192934,8 @@ static int rtreeUpdate( ** record to delete from the r-tree table. The following block does ** just that. */ - if( tdsqlite3_value_type(aData[0])!=SQLITE_NULL ){ - rc = rtreeDeleteRowid(pRtree, tdsqlite3_value_int64(aData[0])); + if( sqlite3_value_type(aData[0])!=SQLITE_NULL ){ + rc = rtreeDeleteRowid(pRtree, sqlite3_value_int64(aData[0])); } /* If the aData[] array contains more than one element, elements @@ -192965,14 +192965,14 @@ static int rtreeUpdate( } } if( rc==SQLITE_OK && pRtree->nAux ){ - tdsqlite3_stmt *pUp = pRtree->pWriteAux; + sqlite3_stmt *pUp = pRtree->pWriteAux; int jj; - tdsqlite3_bind_int64(pUp, 1, *pRowid); + sqlite3_bind_int64(pUp, 1, *pRowid); for(jj=0; jjnAux; jj++){ - tdsqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]); + sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]); } - tdsqlite3_step(pUp); - rc = tdsqlite3_reset(pUp); + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); } } @@ -192984,7 +192984,7 @@ constraint: /* ** Called when a transaction starts. */ -static int rtreeBeginTransaction(tdsqlite3_vtab *pVtab){ +static int rtreeBeginTransaction(sqlite3_vtab *pVtab){ Rtree *pRtree = (Rtree *)pVtab; assert( pRtree->inWrTrans==0 ); pRtree->inWrTrans++; @@ -192993,9 +192993,9 @@ static int rtreeBeginTransaction(tdsqlite3_vtab *pVtab){ /* ** Called when a transaction completes (either by COMMIT or ROLLBACK). -** The tdsqlite3_blob object should be released at this point. +** The sqlite3_blob object should be released at this point. */ -static int rtreeEndTransaction(tdsqlite3_vtab *pVtab){ +static int rtreeEndTransaction(sqlite3_vtab *pVtab){ Rtree *pRtree = (Rtree *)pVtab; pRtree->inWrTrans = 0; nodeBlobReset(pRtree); @@ -193005,10 +193005,10 @@ static int rtreeEndTransaction(tdsqlite3_vtab *pVtab){ /* ** The xRename method for rtree module virtual tables. */ -static int rtreeRename(tdsqlite3_vtab *pVtab, const char *zNewName){ +static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){ Rtree *pRtree = (Rtree *)pVtab; int rc = SQLITE_NOMEM; - char *zSql = tdsqlite3_mprintf( + char *zSql = sqlite3_mprintf( "ALTER TABLE %Q.'%q_node' RENAME TO \"%w_node\";" "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";" "ALTER TABLE %Q.'%q_rowid' RENAME TO \"%w_rowid\";" @@ -193018,8 +193018,8 @@ static int rtreeRename(tdsqlite3_vtab *pVtab, const char *zNewName){ ); if( zSql ){ nodeBlobReset(pRtree); - rc = tdsqlite3_exec(pRtree->db, zSql, 0, 0, 0); - tdsqlite3_free(zSql); + rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0); + sqlite3_free(zSql); } return rc; } @@ -193038,7 +193038,7 @@ static int rtreeRename(tdsqlite3_vtab *pVtab, const char *zNewName){ ** DROP TABLE ; -- Would fail with SQLITE_LOCKED ** COMMIT; */ -static int rtreeSavepoint(tdsqlite3_vtab *pVtab, int iSavepoint){ +static int rtreeSavepoint(sqlite3_vtab *pVtab, int iSavepoint){ Rtree *pRtree = (Rtree *)pVtab; u8 iwt = pRtree->inWrTrans; UNUSED_PARAMETER(iSavepoint); @@ -193053,28 +193053,28 @@ static int rtreeSavepoint(tdsqlite3_vtab *pVtab, int iSavepoint){ ** of the number of rows in the virtual table. If possible, this is based ** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST. */ -static int rtreeQueryStat1(tdsqlite3 *db, Rtree *pRtree){ +static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){ const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'"; char *zSql; - tdsqlite3_stmt *p; + sqlite3_stmt *p; int rc; i64 nRow = 0; - rc = tdsqlite3_table_column_metadata( + rc = sqlite3_table_column_metadata( db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0 ); if( rc!=SQLITE_OK ){ pRtree->nRowEst = RTREE_DEFAULT_ROWEST; return rc==SQLITE_ERROR ? SQLITE_OK : rc; } - zSql = tdsqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); + zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_prepare_v2(db, zSql, -1, &p, 0); + rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0); if( rc==SQLITE_OK ){ - if( tdsqlite3_step(p)==SQLITE_ROW ) nRow = tdsqlite3_column_int64(p, 0); - rc = tdsqlite3_finalize(p); + if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0); + rc = sqlite3_finalize(p); }else if( rc!=SQLITE_NOMEM ){ rc = SQLITE_OK; } @@ -193086,7 +193086,7 @@ static int rtreeQueryStat1(tdsqlite3 *db, Rtree *pRtree){ pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST); } } - tdsqlite3_free(zSql); + sqlite3_free(zSql); } return rc; @@ -193103,12 +193103,12 @@ static int rtreeShadowName(const char *zName){ }; unsigned int i; for(i=0; inAux; ii++){ - tdsqlite3_str_appendf(p,",a%d",ii); + sqlite3_str_appendf(p,",a%d",ii); } - tdsqlite3_str_appendf(p, + sqlite3_str_appendf(p, ");CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY,data);", zDb, zPrefix); - tdsqlite3_str_appendf(p, + sqlite3_str_appendf(p, "CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY,parentnode);", zDb, zPrefix); - tdsqlite3_str_appendf(p, + sqlite3_str_appendf(p, "INSERT INTO \"%w\".\"%w_node\"VALUES(1,zeroblob(%d))", zDb, zPrefix, pRtree->iNodeSize); - zCreate = tdsqlite3_str_finish(p); + zCreate = sqlite3_str_finish(p); if( !zCreate ){ return SQLITE_NOMEM; } - rc = tdsqlite3_exec(db, zCreate, 0, 0, 0); - tdsqlite3_free(zCreate); + rc = sqlite3_exec(db, zCreate, 0, 0, 0); + sqlite3_free(zCreate); if( rc!=SQLITE_OK ){ return rc; } @@ -193217,40 +193217,40 @@ static int rtreeSqlInit( zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)" "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno"; } - zSql = tdsqlite3_mprintf(zFormat, zDb, zPrefix); + zSql = sqlite3_mprintf(zFormat, zDb, zPrefix); if( zSql ){ - rc = tdsqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); + rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); }else{ rc = SQLITE_NOMEM; } - tdsqlite3_free(zSql); + sqlite3_free(zSql); } if( pRtree->nAux ){ - pRtree->zReadAuxSql = tdsqlite3_mprintf( + pRtree->zReadAuxSql = sqlite3_mprintf( "SELECT * FROM \"%w\".\"%w_rowid\" WHERE rowid=?1", zDb, zPrefix); if( pRtree->zReadAuxSql==0 ){ rc = SQLITE_NOMEM; }else{ - tdsqlite3_str *p = tdsqlite3_str_new(db); + sqlite3_str *p = sqlite3_str_new(db); int ii; char *zSql; - tdsqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); + sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix); for(ii=0; iinAux; ii++){ - if( ii ) tdsqlite3_str_append(p, ",", 1); + if( ii ) sqlite3_str_append(p, ",", 1); if( iinAuxNotNull ){ - tdsqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); + sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii); }else{ - tdsqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); + sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2); } } - tdsqlite3_str_appendf(p, " WHERE rowid=?1"); - zSql = tdsqlite3_str_finish(p); + sqlite3_str_appendf(p, " WHERE rowid=?1"); + zSql = sqlite3_str_finish(p); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0); - tdsqlite3_free(zSql); + rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0); + sqlite3_free(zSql); } } } @@ -193265,16 +193265,16 @@ static int rtreeSqlInit( ** is written to *piVal and SQLITE_OK returned. Otherwise, an SQLite error ** code is returned and the value of *piVal after returning is not defined. */ -static int getIntFromStmt(tdsqlite3 *db, const char *zSql, int *piVal){ +static int getIntFromStmt(sqlite3 *db, const char *zSql, int *piVal){ int rc = SQLITE_NOMEM; if( zSql ){ - tdsqlite3_stmt *pStmt = 0; - rc = tdsqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + sqlite3_stmt *pStmt = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); if( rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - *piVal = tdsqlite3_column_int(pStmt, 0); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + *piVal = sqlite3_column_int(pStmt, 0); } - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); } } return rc; @@ -193296,7 +193296,7 @@ static int getIntFromStmt(tdsqlite3 *db, const char *zSql, int *piVal){ ** would fit in a single node, use a smaller node-size. */ static int getNodeSize( - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ Rtree *pRtree, /* Rtree handle */ int isCreate, /* True for xCreate, false for xConnect */ char **pzErr /* OUT: Error message, if any */ @@ -193305,7 +193305,7 @@ static int getNodeSize( char *zSql; if( isCreate ){ int iPageSize = 0; - zSql = tdsqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); + zSql = sqlite3_mprintf("PRAGMA %Q.page_size", pRtree->zDb); rc = getIntFromStmt(db, zSql, &iPageSize); if( rc==SQLITE_OK ){ pRtree->iNodeSize = iPageSize-64; @@ -193313,25 +193313,25 @@ static int getNodeSize( pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS; } }else{ - *pzErr = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); } }else{ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT length(data) FROM '%q'.'%q_node' WHERE nodeno = 1", pRtree->zDb, pRtree->zName ); rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize); if( rc!=SQLITE_OK ){ - *pzErr = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); }else if( pRtree->iNodeSize<(512-64) ){ rc = SQLITE_CORRUPT_VTAB; RTREE_IS_CORRUPT(pRtree); - *pzErr = tdsqlite3_mprintf("undersize RTree blobs in \"%q_node\"", + *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"", pRtree->zName); } } - tdsqlite3_free(zSql); + sqlite3_free(zSql); return rc; } @@ -193340,7 +193340,7 @@ static int getNodeSize( */ static int rtreeTokenLength(const char *z){ int dummy = 0; - return tdsqlite3GetToken((const unsigned char*)z,&dummy); + return sqlite3GetToken((const unsigned char*)z,&dummy); } /* @@ -193353,10 +193353,10 @@ static int rtreeTokenLength(const char *z){ ** argv[...] -> column names... */ static int rtreeInit( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pAux, /* One of the RTREE_COORD_* constants */ int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ - tdsqlite3_vtab **ppVtab, /* OUT: New virtual table */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ char **pzErr, /* OUT: Error message, if any */ int isCreate /* True for xCreate, false for xConnect */ ){ @@ -193365,7 +193365,7 @@ static int rtreeInit( int nDb; /* Length of string argv[1] */ int nName; /* Length of string argv[2] */ int eCoordType = (pAux ? RTREE_COORD_INT32 : RTREE_COORD_REAL32); - tdsqlite3_str *pSql; + sqlite3_str *pSql; char *zSql; int ii = 4; int iErr; @@ -193380,16 +193380,16 @@ static int rtreeInit( assert( RTREE_MAX_AUX_COLUMN<256 ); /* Aux columns counted by a u8 */ if( argc<6 || argc>RTREE_MAX_AUX_COLUMN+3 ){ - *pzErr = tdsqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]); + *pzErr = sqlite3_mprintf("%s", aErrMsg[2 + (argc>=6)]); return SQLITE_ERROR; } - tdsqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); - /* Allocate the tdsqlite3_vtab structure */ + /* Allocate the sqlite3_vtab structure */ nDb = (int)strlen(argv[1]); nName = (int)strlen(argv[2]); - pRtree = (Rtree *)tdsqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); if( !pRtree ){ return SQLITE_NOMEM; } @@ -193404,35 +193404,35 @@ static int rtreeInit( /* Create/Connect to the underlying relational database schema. If - ** that is successful, call tdsqlite3_declare_vtab() to configure + ** that is successful, call sqlite3_declare_vtab() to configure ** the r-tree table schema. */ - pSql = tdsqlite3_str_new(db); - tdsqlite3_str_appendf(pSql, "CREATE TABLE x(%.*s INT", + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(%.*s INT", rtreeTokenLength(argv[3]), argv[3]); for(ii=4; iinAux++; - tdsqlite3_str_appendf(pSql, ",%.*s", rtreeTokenLength(zArg+1), zArg+1); + sqlite3_str_appendf(pSql, ",%.*s", rtreeTokenLength(zArg+1), zArg+1); }else if( pRtree->nAux>0 ){ break; }else{ pRtree->nDim2++; - tdsqlite3_str_appendf(pSql, ",%.*s NUM", rtreeTokenLength(zArg), zArg); + sqlite3_str_appendf(pSql, ",%.*s NUM", rtreeTokenLength(zArg), zArg); } } - tdsqlite3_str_appendf(pSql, ");"); - zSql = tdsqlite3_str_finish(pSql); + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); if( !zSql ){ rc = SQLITE_NOMEM; }else if( iinDim = pRtree->nDim2/2; if( pRtree->nDim<1 ){ @@ -193445,7 +193445,7 @@ static int rtreeInit( iErr = 0; } if( iErr ){ - *pzErr = tdsqlite3_mprintf("%s", aErrMsg[iErr]); + *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]); goto rtreeInit_fail; } pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; @@ -193455,11 +193455,11 @@ static int rtreeInit( if( rc ) goto rtreeInit_fail; rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); if( rc ){ - *pzErr = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); goto rtreeInit_fail; } - *ppVtab = (tdsqlite3_vtab *)pRtree; + *ppVtab = (sqlite3_vtab *)pRtree; return SQLITE_OK; rtreeInit_fail: @@ -193487,46 +193487,46 @@ rtreeInit_fail: ** list, containing the 8-byte rowid/pageno followed by the ** *2 coordinates. */ -static void rtreenode(tdsqlite3_context *ctx, int nArg, tdsqlite3_value **apArg){ +static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){ RtreeNode node; Rtree tree; int ii; int nData; int errCode; - tdsqlite3_str *pOut; + sqlite3_str *pOut; UNUSED_PARAMETER(nArg); memset(&node, 0, sizeof(RtreeNode)); memset(&tree, 0, sizeof(Rtree)); - tree.nDim = (u8)tdsqlite3_value_int(apArg[0]); + tree.nDim = (u8)sqlite3_value_int(apArg[0]); if( tree.nDim<1 || tree.nDim>5 ) return; tree.nDim2 = tree.nDim*2; tree.nBytesPerCell = 8 + 8 * tree.nDim; - node.zData = (u8 *)tdsqlite3_value_blob(apArg[1]); - nData = tdsqlite3_value_bytes(apArg[1]); + node.zData = (u8 *)sqlite3_value_blob(apArg[1]); + nData = sqlite3_value_bytes(apArg[1]); if( nData<4 ) return; if( nData0 ) tdsqlite3_str_append(pOut, " ", 1); - tdsqlite3_str_appendf(pOut, "{%lld", cell.iRowid); + if( ii>0 ) sqlite3_str_append(pOut, " ", 1); + sqlite3_str_appendf(pOut, "{%lld", cell.iRowid); for(jj=0; jjrc==SQLITE_OK ) pCheck->rc = rc; } @@ -193589,26 +193589,26 @@ static void rtreeCheckReset(RtreeCheck *pCheck, tdsqlite3_stmt *pStmt){ ** If successful, a pointer to the new SQL statement is returned. Otherwise, ** NULL is returned and an error code left in RtreeCheck.rc. */ -static tdsqlite3_stmt *rtreeCheckPrepare( +static sqlite3_stmt *rtreeCheckPrepare( RtreeCheck *pCheck, /* RtreeCheck object */ const char *zFmt, ... /* Format string and trailing args */ ){ va_list ap; char *z; - tdsqlite3_stmt *pRet = 0; + sqlite3_stmt *pRet = 0; va_start(ap, zFmt); - z = tdsqlite3_vmprintf(zFmt, ap); + z = sqlite3_vmprintf(zFmt, ap); if( pCheck->rc==SQLITE_OK ){ if( z==0 ){ pCheck->rc = SQLITE_NOMEM; }else{ - pCheck->rc = tdsqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0); + pCheck->rc = sqlite3_prepare_v2(pCheck->db, z, -1, &pRet, 0); } } - tdsqlite3_free(z); + sqlite3_free(z); va_end(ap); return pRet; } @@ -193622,11 +193622,11 @@ static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ va_list ap; va_start(ap, zFmt); if( pCheck->rc==SQLITE_OK && pCheck->nErrrc = SQLITE_NOMEM; }else{ - pCheck->zReport = tdsqlite3_mprintf("%z%s%z", + pCheck->zReport = sqlite3_mprintf("%z%s%z", pCheck->zReport, (pCheck->zReport ? "\n" : ""), z ); if( pCheck->zReport==0 ){ @@ -193644,7 +193644,7 @@ static void rtreeCheckAppendMsg(RtreeCheck *pCheck, const char *zFmt, ...){ ** returned in this case. ** ** Otherwise, the contents of rtree table node iNode are loaded from -** the database and copied into a buffer obtained from tdsqlite3_malloc(). +** the database and copied into a buffer obtained from sqlite3_malloc(). ** If no error occurs, a pointer to the buffer is returned and (*pnNode) ** is set to the size of the buffer in bytes. ** @@ -193663,11 +193663,11 @@ static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){ } if( pCheck->rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pCheck->pGetNode, 1, iNode); - if( tdsqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){ - int nNode = tdsqlite3_column_bytes(pCheck->pGetNode, 0); - const u8 *pNode = (const u8*)tdsqlite3_column_blob(pCheck->pGetNode, 0); - pRet = tdsqlite3_malloc64(nNode); + sqlite3_bind_int64(pCheck->pGetNode, 1, iNode); + if( sqlite3_step(pCheck->pGetNode)==SQLITE_ROW ){ + int nNode = sqlite3_column_bytes(pCheck->pGetNode, 0); + const u8 *pNode = (const u8*)sqlite3_column_blob(pCheck->pGetNode, 0); + pRet = sqlite3_malloc64(nNode); if( pRet==0 ){ pCheck->rc = SQLITE_NOMEM; }else{ @@ -193703,7 +193703,7 @@ static void rtreeCheckMapping( i64 iVal /* Expected value for mapping */ ){ int rc; - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; const char *azSql[2] = { "SELECT parentnode FROM %Q.'%q_parent' WHERE nodeno=?1", "SELECT nodeno FROM %Q.'%q_rowid' WHERE rowid=?1" @@ -193718,14 +193718,14 @@ static void rtreeCheckMapping( if( pCheck->rc!=SQLITE_OK ) return; pStmt = pCheck->aCheckMapping[bLeaf]; - tdsqlite3_bind_int64(pStmt, 1, iKey); - rc = tdsqlite3_step(pStmt); + sqlite3_bind_int64(pStmt, 1, iKey); + rc = sqlite3_step(pStmt); if( rc==SQLITE_DONE ){ rtreeCheckAppendMsg(pCheck, "Mapping (%lld -> %lld) missing from %s table", iKey, iVal, (bLeaf ? "%_rowid" : "%_parent") ); }else if( rc==SQLITE_ROW ){ - i64 ii = tdsqlite3_column_int64(pStmt, 0); + i64 ii = sqlite3_column_int64(pStmt, 0); if( ii!=iVal ){ rtreeCheckAppendMsg(pCheck, "Found (%lld -> %lld) in %s table, expected (%lld -> %lld)", @@ -193819,7 +193819,7 @@ static void rtreeCheckNode( iDepth = readInt16(aNode); if( iDepth>RTREE_MAX_DEPTH ){ rtreeCheckAppendMsg(pCheck, "Rtree depth out of range (%d)", iDepth); - tdsqlite3_free(aNode); + sqlite3_free(aNode); return; } } @@ -193846,7 +193846,7 @@ static void rtreeCheckNode( } } } - tdsqlite3_free(aNode); + sqlite3_free(aNode); } } @@ -193859,20 +193859,20 @@ static void rtreeCheckNode( */ static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){ if( pCheck->rc==SQLITE_OK ){ - tdsqlite3_stmt *pCount; + sqlite3_stmt *pCount; pCount = rtreeCheckPrepare(pCheck, "SELECT count(*) FROM %Q.'%q%s'", pCheck->zDb, pCheck->zTab, zTbl ); if( pCount ){ - if( tdsqlite3_step(pCount)==SQLITE_ROW ){ - i64 nActual = tdsqlite3_column_int64(pCount, 0); + if( sqlite3_step(pCount)==SQLITE_ROW ){ + i64 nActual = sqlite3_column_int64(pCount, 0); if( nActual!=nExpect ){ rtreeCheckAppendMsg(pCheck, "Wrong number of entries in %%%s table" " - expected %lld, actual %lld" , zTbl, nExpect, nActual ); } } - pCheck->rc = tdsqlite3_finalize(pCount); + pCheck->rc = sqlite3_finalize(pCount); } } } @@ -193882,13 +193882,13 @@ static void rtreeCheckCount(RtreeCheck *pCheck, const char *zTbl, i64 nExpect){ ** It is called by rtreecheck(), which is the SQL function implementation. */ static int rtreeCheckTable( - tdsqlite3 *db, /* Database handle to access db through */ + sqlite3 *db, /* Database handle to access db through */ const char *zDb, /* Name of db ("main", "temp" etc.) */ const char *zTab, /* Name of rtree table to check */ - char **pzReport /* OUT: tdsqlite3_malloc'd report text */ + char **pzReport /* OUT: sqlite3_malloc'd report text */ ){ RtreeCheck check; /* Common context for various routines */ - tdsqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ + sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ int bEnd = 0; /* True if transaction should be closed */ int nAux = 0; /* Number of extra columns. */ @@ -193901,8 +193901,8 @@ static int rtreeCheckTable( /* If there is not already an open transaction, open one now. This is ** to ensure that the queries run as part of this integrity-check operate ** on a consistent snapshot. */ - if( tdsqlite3_get_autocommit(db) ){ - check.rc = tdsqlite3_exec(db, "BEGIN", 0, 0, 0); + if( sqlite3_get_autocommit(db) ){ + check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); bEnd = 1; } @@ -193910,8 +193910,8 @@ static int rtreeCheckTable( if( check.rc==SQLITE_OK ){ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); if( pStmt ){ - nAux = tdsqlite3_column_count(pStmt) - 2; - tdsqlite3_finalize(pStmt); + nAux = sqlite3_column_count(pStmt) - 2; + sqlite3_finalize(pStmt); } check.rc = SQLITE_OK; } @@ -193920,13 +193920,13 @@ static int rtreeCheckTable( pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab); if( pStmt ){ int rc; - check.nDim = (tdsqlite3_column_count(pStmt) - 1 - nAux) / 2; + check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2; if( check.nDim<1 ){ rtreeCheckAppendMsg(&check, "Schema corrupt or not an rtree"); - }else if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - check.bInt = (tdsqlite3_column_type(pStmt, 1)==SQLITE_INTEGER); + }else if( SQLITE_ROW==sqlite3_step(pStmt) ){ + check.bInt = (sqlite3_column_type(pStmt, 1)==SQLITE_INTEGER); } - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); if( rc!=SQLITE_CORRUPT ) check.rc = rc; } @@ -193940,13 +193940,13 @@ static int rtreeCheckTable( } /* Finalize SQL statements used by the integrity-check */ - tdsqlite3_finalize(check.pGetNode); - tdsqlite3_finalize(check.aCheckMapping[0]); - tdsqlite3_finalize(check.aCheckMapping[1]); + sqlite3_finalize(check.pGetNode); + sqlite3_finalize(check.aCheckMapping[0]); + sqlite3_finalize(check.aCheckMapping[1]); /* If one was opened, close the transaction */ if( bEnd ){ - int rc = tdsqlite3_exec(db, "END", 0, 0, 0); + int rc = sqlite3_exec(db, "END", 0, 0, 0); if( check.rc==SQLITE_OK ) check.rc = rc; } *pzReport = check.zReport; @@ -193987,32 +193987,32 @@ static int rtreeCheckTable( ** %_parent table. */ static void rtreecheck( - tdsqlite3_context *ctx, + sqlite3_context *ctx, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ if( nArg!=1 && nArg!=2 ){ - tdsqlite3_result_error(ctx, + sqlite3_result_error(ctx, "wrong number of arguments to function rtreecheck()", -1 ); }else{ int rc; char *zReport = 0; - const char *zDb = (const char*)tdsqlite3_value_text(apArg[0]); + const char *zDb = (const char*)sqlite3_value_text(apArg[0]); const char *zTab; if( nArg==1 ){ zTab = zDb; zDb = "main"; }else{ - zTab = (const char*)tdsqlite3_value_text(apArg[1]); + zTab = (const char*)sqlite3_value_text(apArg[1]); } - rc = rtreeCheckTable(tdsqlite3_context_db_handle(ctx), zDb, zTab, &zReport); + rc = rtreeCheckTable(sqlite3_context_db_handle(ctx), zDb, zTab, &zReport); if( rc==SQLITE_OK ){ - tdsqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT); + sqlite3_result_text(ctx, zReport ? zReport : "ok", -1, SQLITE_TRANSIENT); }else{ - tdsqlite3_result_error_code(ctx, rc); + sqlite3_result_error_code(ctx, rc); } - tdsqlite3_free(zReport); + sqlite3_free(zReport); } } @@ -194053,12 +194053,12 @@ static void rtreecheck( ** Versions of isspace(), isalnum() and isdigit() to which it is safe ** to pass signed char values. */ -#ifdef tdsqlite3Isdigit +#ifdef sqlite3Isdigit /* Use the SQLite core versions if this routine is part of the ** SQLite amalgamation */ -# define safe_isdigit(x) tdsqlite3Isdigit(x) -# define safe_isalnum(x) tdsqlite3Isalnum(x) -# define safe_isxdigit(x) tdsqlite3Isxdigit(x) +# define safe_isdigit(x) sqlite3Isdigit(x) +# define safe_isalnum(x) sqlite3Isalnum(x) +# define safe_isxdigit(x) sqlite3Isxdigit(x) #else /* Use the standard library for separate compilation */ #include /* amalgamator: keep */ @@ -194163,7 +194163,7 @@ struct GeoParse { int nVertex; /* Number of vertexes in a[] */ int nAlloc; /* Space allocated to a[] */ int nErr; /* Number of errors encountered */ - GeoCoord *a; /* Array of vertexes. From tdsqlite3_malloc64() */ + GeoCoord *a; /* Array of vertexes. From sqlite3_malloc64() */ }; /* Do a 4-byte byte swap */ @@ -194222,10 +194222,10 @@ static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){ if( z[j-1]<'0' ) return 0; if( pVal ){ #ifdef SQLITE_AMALGAMATION - /* The tdsqlite3AtoF() routine is much much faster than atof(), if it + /* The sqlite3AtoF() routine is much much faster than atof(), if it ** is available */ double r; - (void)tdsqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8); + (void)sqlite3AtoF((const char*)p->z, &r, j, SQLITE_UTF8); *pVal = r; #else *pVal = (GeoCoord)atof((const char*)p->z); @@ -194257,7 +194257,7 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ if( s.nVertex>=s.nAlloc ){ GeoCoord *aNew; s.nAlloc = s.nAlloc*2 + 16; - aNew = tdsqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 ); + aNew = sqlite3_realloc64(s.a, s.nAlloc*sizeof(GeoCoord)*2 ); if( aNew==0 ){ rc = SQLITE_NOMEM; s.nErr++; @@ -194291,7 +194291,7 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ GeoPoly *pOut; int x = 1; s.nVertex--; /* Remove the redundant vertex at the end */ - pOut = tdsqlite3_malloc64( GEOPOLY_SZ((tdsqlite3_int64)s.nVertex) ); + pOut = sqlite3_malloc64( GEOPOLY_SZ((sqlite3_int64)s.nVertex) ); x = 1; if( pOut==0 ) goto parse_json_err; pOut->nVertex = s.nVertex; @@ -194300,7 +194300,7 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ pOut->hdr[1] = (s.nVertex>>16)&0xff; pOut->hdr[2] = (s.nVertex>>8)&0xff; pOut->hdr[3] = s.nVertex&0xff; - tdsqlite3_free(s.a); + sqlite3_free(s.a); if( pRc ) *pRc = SQLITE_OK; return pOut; }else{ @@ -194310,7 +194310,7 @@ static GeoPoly *geopolyParseJson(const unsigned char *z, int *pRc){ } parse_json_err: if( pRc ) *pRc = rc; - tdsqlite3_free(s.a); + sqlite3_free(s.a); return 0; } @@ -194318,28 +194318,28 @@ parse_json_err: ** Given a function parameter, try to interpret it as a polygon, either ** in the binary format or JSON text. Compute a GeoPoly object and ** return a pointer to that object. Or if the input is not a well-formed -** polygon, put an error message in tdsqlite3_context and return NULL. +** polygon, put an error message in sqlite3_context and return NULL. */ static GeoPoly *geopolyFuncParam( - tdsqlite3_context *pCtx, /* Context for error messages */ - tdsqlite3_value *pVal, /* The value to decode */ + sqlite3_context *pCtx, /* Context for error messages */ + sqlite3_value *pVal, /* The value to decode */ int *pRc /* Write error here */ ){ GeoPoly *p = 0; int nByte; - if( tdsqlite3_value_type(pVal)==SQLITE_BLOB - && (nByte = tdsqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) + if( sqlite3_value_type(pVal)==SQLITE_BLOB + && (nByte = sqlite3_value_bytes(pVal))>=(4+6*sizeof(GeoCoord)) ){ - const unsigned char *a = tdsqlite3_value_blob(pVal); + const unsigned char *a = sqlite3_value_blob(pVal); int nVertex; nVertex = (a[1]<<16) + (a[2]<<8) + a[3]; if( (a[0]==0 || a[0]==1) && (nVertex*2*sizeof(GeoCoord) + 4)==(unsigned int)nByte ){ - p = tdsqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) ); + p = sqlite3_malloc64( sizeof(*p) + (nVertex-1)*2*sizeof(GeoCoord) ); if( p==0 ){ if( pRc ) *pRc = SQLITE_NOMEM; - if( pCtx ) tdsqlite3_result_error_nomem(pCtx); + if( pCtx ) sqlite3_result_error_nomem(pCtx); }else{ int x = 1; p->nVertex = nVertex; @@ -194356,8 +194356,8 @@ static GeoPoly *geopolyFuncParam( } if( pRc ) *pRc = SQLITE_OK; return p; - }else if( tdsqlite3_value_type(pVal)==SQLITE_TEXT ){ - const unsigned char *zJson = tdsqlite3_value_text(pVal); + }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){ + const unsigned char *zJson = sqlite3_value_text(pVal); if( zJson==0 ){ if( pRc ) *pRc = SQLITE_NOMEM; return 0; @@ -194377,15 +194377,15 @@ static GeoPoly *geopolyFuncParam( ** return NULL. */ static void geopolyBlobFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); if( p ){ - tdsqlite3_result_blob(context, p->hdr, + sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); - tdsqlite3_free(p); + sqlite3_free(p); } } @@ -194396,22 +194396,22 @@ static void geopolyBlobFunc( ** of coordinates. Or, if X is not a valid polygon, return NULL. */ static void geopolyJsonFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); if( p ){ - tdsqlite3 *db = tdsqlite3_context_db_handle(context); - tdsqlite3_str *x = tdsqlite3_str_new(db); + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); int i; - tdsqlite3_str_append(x, "[", 1); + sqlite3_str_append(x, "[", 1); for(i=0; inVertex; i++){ - tdsqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i)); + sqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i)); } - tdsqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0)); - tdsqlite3_result_text(context, tdsqlite3_str_finish(x), -1, tdsqlite3_free); - tdsqlite3_free(p); + sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0)); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); } } @@ -194422,33 +194422,33 @@ static void geopolyJsonFunc( ** Additional arguments are added as attributes to the . */ static void geopolySvgFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p; if( argc<1 ) return; p = geopolyFuncParam(context, argv[0], 0); if( p ){ - tdsqlite3 *db = tdsqlite3_context_db_handle(context); - tdsqlite3_str *x = tdsqlite3_str_new(db); + sqlite3 *db = sqlite3_context_db_handle(context); + sqlite3_str *x = sqlite3_str_new(db); int i; char cSep = '\''; - tdsqlite3_str_appendf(x, ""); - tdsqlite3_result_text(context, tdsqlite3_str_finish(x), -1, tdsqlite3_free); - tdsqlite3_free(p); + sqlite3_str_appendf(x, ">"); + sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free); + sqlite3_free(p); } } @@ -194469,17 +194469,17 @@ static void geopolySvgFunc( ** geopoly_xform(poly, cos(R), sin(R), -sin(R), cos(R), 0, 0) */ static void geopolyXformFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); - double A = tdsqlite3_value_double(argv[1]); - double B = tdsqlite3_value_double(argv[2]); - double C = tdsqlite3_value_double(argv[3]); - double D = tdsqlite3_value_double(argv[4]); - double E = tdsqlite3_value_double(argv[5]); - double F = tdsqlite3_value_double(argv[6]); + double A = sqlite3_value_double(argv[1]); + double B = sqlite3_value_double(argv[2]); + double C = sqlite3_value_double(argv[3]); + double D = sqlite3_value_double(argv[4]); + double E = sqlite3_value_double(argv[5]); + double F = sqlite3_value_double(argv[6]); GeoCoord x1, y1, x0, y0; int ii; if( p ){ @@ -194491,9 +194491,9 @@ static void geopolyXformFunc( GeoX(p,ii) = x1; GeoY(p,ii) = y1; } - tdsqlite3_result_blob(context, p->hdr, + sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); - tdsqlite3_free(p); + sqlite3_free(p); } } @@ -194527,14 +194527,14 @@ static double geopolyArea(GeoPoly *p){ ** enclosed area. Otherwise return NULL. */ static void geopolyAreaFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); if( p ){ - tdsqlite3_result_double(context, geopolyArea(p)); - tdsqlite3_free(p); + sqlite3_result_double(context, geopolyArea(p)); + sqlite3_free(p); } } @@ -194552,9 +194552,9 @@ static void geopolyAreaFunc( ** contain polygons that wind in the wrong direction. */ static void geopolyCcwFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p = geopolyFuncParam(context, argv[0], 0); if( p ){ @@ -194569,9 +194569,9 @@ static void geopolyCcwFunc( GeoY(p,jj) = t; } } - tdsqlite3_result_blob(context, p->hdr, + sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); - tdsqlite3_free(p); + sqlite3_free(p); } } @@ -194601,22 +194601,22 @@ static double geopolySine(double r){ ** with circumradius R and with N sides. */ static void geopolyRegularFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ - double x = tdsqlite3_value_double(argv[0]); - double y = tdsqlite3_value_double(argv[1]); - double r = tdsqlite3_value_double(argv[2]); - int n = tdsqlite3_value_int(argv[3]); + double x = sqlite3_value_double(argv[0]); + double y = sqlite3_value_double(argv[1]); + double r = sqlite3_value_double(argv[2]); + int n = sqlite3_value_int(argv[3]); int i; GeoPoly *p; if( n<3 || r<=0.0 ) return; if( n>1000 ) n = 1000; - p = tdsqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); + p = sqlite3_malloc64( sizeof(*p) + (n-1)*2*sizeof(GeoCoord) ); if( p==0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); return; } i = 1; @@ -194629,8 +194629,8 @@ static void geopolyRegularFunc( GeoX(p,i) = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI); GeoY(p,i) = y + r*geopolySine(rAngle); } - tdsqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT); - tdsqlite3_free(p); + sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT); + sqlite3_free(p); } /* @@ -194644,8 +194644,8 @@ static void geopolyRegularFunc( ** the bounding box in aCoord and return a pointer to that GeoPoly. */ static GeoPoly *geopolyBBox( - tdsqlite3_context *context, /* For recording the error */ - tdsqlite3_value *pPoly, /* The polygon */ + sqlite3_context *context, /* For recording the error */ + sqlite3_value *pPoly, /* The polygon */ RtreeCoord *aCoord, /* Results here */ int *pRc /* Error code here */ ){ @@ -194677,10 +194677,10 @@ static GeoPoly *geopolyBBox( if( pRc ) *pRc = SQLITE_OK; if( aCoord==0 ){ geopolyBboxFill: - pOut = tdsqlite3_realloc64(p, GEOPOLY_SZ(4)); + pOut = sqlite3_realloc64(p, GEOPOLY_SZ(4)); if( pOut==0 ){ - tdsqlite3_free(p); - if( context ) tdsqlite3_result_error_nomem(context); + sqlite3_free(p); + if( context ) sqlite3_result_error_nomem(context); if( pRc ) *pRc = SQLITE_NOMEM; return 0; } @@ -194699,7 +194699,7 @@ static GeoPoly *geopolyBBox( GeoX(pOut,3) = mnX; GeoY(pOut,3) = mxY; }else{ - tdsqlite3_free(p); + sqlite3_free(p); aCoord[0].f = mnX; aCoord[1].f = mxX; aCoord[2].f = mnY; @@ -194713,15 +194713,15 @@ static GeoPoly *geopolyBBox( ** Implementation of the geopoly_bbox(X) SQL function. */ static void geopolyBBoxFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p = geopolyBBox(context, argv[0], 0, 0); if( p ){ - tdsqlite3_result_blob(context, p->hdr, + sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); - tdsqlite3_free(p); + sqlite3_free(p); } } @@ -194739,16 +194739,16 @@ struct GeoBBox { ** Implementation of the geopoly_group_bbox(X) aggregate SQL function. */ static void geopolyBBoxStep( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ RtreeCoord a[4]; int rc = SQLITE_OK; (void)geopolyBBox(context, argv[0], a, &rc); if( rc==SQLITE_OK ){ GeoBBox *pBBox; - pBBox = (GeoBBox*)tdsqlite3_aggregate_context(context, sizeof(*pBBox)); + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, sizeof(*pBBox)); if( pBBox==0 ) return; if( pBBox->isInit==0 ){ pBBox->isInit = 1; @@ -194762,17 +194762,17 @@ static void geopolyBBoxStep( } } static void geopolyBBoxFinal( - tdsqlite3_context *context + sqlite3_context *context ){ GeoPoly *p; GeoBBox *pBBox; - pBBox = (GeoBBox*)tdsqlite3_aggregate_context(context, 0); + pBBox = (GeoBBox*)sqlite3_aggregate_context(context, 0); if( pBBox==0 ) return; p = geopolyBBox(context, 0, pBBox->a, 0); if( p ){ - tdsqlite3_result_blob(context, p->hdr, + sqlite3_result_blob(context, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); - tdsqlite3_free(p); + sqlite3_free(p); } } @@ -194823,13 +194823,13 @@ static int pointBeneathLine( ** Return 0 if point X,Y is outside the polygon */ static void geopolyContainsPointFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); - double x0 = tdsqlite3_value_double(argv[1]); - double y0 = tdsqlite3_value_double(argv[2]); + double x0 = sqlite3_value_double(argv[1]); + double y0 = sqlite3_value_double(argv[2]); int v = 0; int cnt = 0; int ii; @@ -194845,13 +194845,13 @@ static void geopolyContainsPointFunc( GeoX(p1,0), GeoY(p1,0)); } if( v==2 ){ - tdsqlite3_result_int(context, 1); + sqlite3_result_int(context, 1); }else if( ((v+cnt)&1)==0 ){ - tdsqlite3_result_int(context, 0); + sqlite3_result_int(context, 0); }else{ - tdsqlite3_result_int(context, 2); + sqlite3_result_int(context, 2); } - tdsqlite3_free(p1); + sqlite3_free(p1); } /* Forward declaration */ @@ -194866,22 +194866,22 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2); ** */ static void geopolyWithinFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); if( p1 && p2 ){ int x = geopolyOverlap(p1, p2); if( x<0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); }else{ - tdsqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); + sqlite3_result_int(context, x==2 ? 1 : x==4 ? 2 : 0); } } - tdsqlite3_free(p1); - tdsqlite3_free(p2); + sqlite3_free(p1); + sqlite3_free(p2); } /* Objects used by the overlap algorihm. */ @@ -195073,9 +195073,9 @@ static GeoSegment *geopolySortSegmentsByYAndC(GeoSegment *pList){ ** Determine the overlap between two polygons */ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){ - tdsqlite3_int64 nVertex = p1->nVertex + p2->nVertex + 2; + sqlite3_int64 nVertex = p1->nVertex + p2->nVertex + 2; GeoOverlap *p; - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; GeoEvent *pThisEvent; double rX; int rc = 0; @@ -195087,7 +195087,7 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){ nByte = sizeof(GeoEvent)*nVertex*2 + sizeof(GeoSegment)*nVertex + sizeof(GeoOverlap); - p = tdsqlite3_malloc64( nByte ); + p = sqlite3_malloc64( nByte ); if( p==0 ) return -1; p->aEvent = (GeoEvent*)&p[1]; p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2]; @@ -195179,7 +195179,7 @@ static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){ } geopolyOverlapDone: - tdsqlite3_free(p); + sqlite3_free(p); return rc; } @@ -195196,34 +195196,34 @@ geopolyOverlapDone: ** NULL Either P1 or P2 or both are not valid polygons */ static void geopolyOverlapFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ GeoPoly *p1 = geopolyFuncParam(context, argv[0], 0); GeoPoly *p2 = geopolyFuncParam(context, argv[1], 0); if( p1 && p2 ){ int x = geopolyOverlap(p1, p2); if( x<0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); }else{ - tdsqlite3_result_int(context, x); + sqlite3_result_int(context, x); } } - tdsqlite3_free(p1); - tdsqlite3_free(p2); + sqlite3_free(p1); + sqlite3_free(p2); } /* ** Enable or disable debugging output */ static void geopolyDebugFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ #ifdef GEOPOLY_ENABLE_DEBUG - geo_debug = tdsqlite3_value_int(argv[0]); + geo_debug = sqlite3_value_int(argv[0]); #endif } @@ -195237,27 +195237,27 @@ static void geopolyDebugFunc( ** argv[...] -> column names... */ static int geopolyInit( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pAux, /* One of the RTREE_COORD_* constants */ int argc, const char *const*argv, /* Parameters to CREATE TABLE statement */ - tdsqlite3_vtab **ppVtab, /* OUT: New virtual table */ + sqlite3_vtab **ppVtab, /* OUT: New virtual table */ char **pzErr, /* OUT: Error message, if any */ int isCreate /* True for xCreate, false for xConnect */ ){ int rc = SQLITE_OK; Rtree *pRtree; - tdsqlite3_int64 nDb; /* Length of string argv[1] */ - tdsqlite3_int64 nName; /* Length of string argv[2] */ - tdsqlite3_str *pSql; + sqlite3_int64 nDb; /* Length of string argv[1] */ + sqlite3_int64 nName; /* Length of string argv[2] */ + sqlite3_str *pSql; char *zSql; int ii; - tdsqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); - /* Allocate the tdsqlite3_vtab structure */ + /* Allocate the sqlite3_vtab structure */ nDb = strlen(argv[1]); nName = strlen(argv[2]); - pRtree = (Rtree *)tdsqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); if( !pRtree ){ return SQLITE_NOMEM; } @@ -195274,25 +195274,25 @@ static int geopolyInit( /* Create/Connect to the underlying relational database schema. If - ** that is successful, call tdsqlite3_declare_vtab() to configure + ** that is successful, call sqlite3_declare_vtab() to configure ** the r-tree table schema. */ - pSql = tdsqlite3_str_new(db); - tdsqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); + pSql = sqlite3_str_new(db); + sqlite3_str_appendf(pSql, "CREATE TABLE x(_shape"); pRtree->nAux = 1; /* Add one for _shape */ pRtree->nAuxNotNull = 1; /* The _shape column is always not-null */ for(ii=3; iinAux++; - tdsqlite3_str_appendf(pSql, ",%s", argv[ii]); + sqlite3_str_appendf(pSql, ",%s", argv[ii]); } - tdsqlite3_str_appendf(pSql, ");"); - zSql = tdsqlite3_str_finish(pSql); + sqlite3_str_appendf(pSql, ");"); + zSql = sqlite3_str_finish(pSql); if( !zSql ){ rc = SQLITE_NOMEM; - }else if( SQLITE_OK!=(rc = tdsqlite3_declare_vtab(db, zSql)) ){ - *pzErr = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); + }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); } - tdsqlite3_free(zSql); + sqlite3_free(zSql); if( rc ) goto geopolyInit_fail; pRtree->nBytesPerCell = 8 + pRtree->nDim2*4; @@ -195301,11 +195301,11 @@ static int geopolyInit( if( rc ) goto geopolyInit_fail; rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate); if( rc ){ - *pzErr = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); goto geopolyInit_fail; } - *ppVtab = (tdsqlite3_vtab *)pRtree; + *ppVtab = (sqlite3_vtab *)pRtree; return SQLITE_OK; geopolyInit_fail: @@ -195321,10 +195321,10 @@ geopolyInit_fail: ** GEOPOLY virtual table module xCreate method. */ static int geopolyCreate( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 1); @@ -195334,10 +195334,10 @@ static int geopolyCreate( ** GEOPOLY virtual table module xConnect method. */ static int geopolyConnect( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ return geopolyInit(db, pAux, argc, argv, ppVtab, pzErr, 0); @@ -195357,10 +195357,10 @@ static int geopolyConnect( ** 4 full table scan */ static int geopolyFilter( - tdsqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */ + sqlite3_vtab_cursor *pVtabCursor, /* The cursor to initialize */ int idxNum, /* Query plan */ const char *idxStr, /* Not Used */ - int argc, tdsqlite3_value **argv /* Parameters to the query plan */ + int argc, sqlite3_value **argv /* Parameters to the query plan */ ){ Rtree *pRtree = (Rtree *)pVtabCursor->pVtab; RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor; @@ -195378,7 +195378,7 @@ static int geopolyFilter( /* Special case - lookup by rowid. */ RtreeNode *pLeaf; /* Leaf on which the required cell resides */ RtreeSearchPoint *p; /* Search point for the leaf */ - i64 iRowid = tdsqlite3_value_int64(argv[0]); + i64 iRowid = sqlite3_value_int64(argv[0]); i64 iNode = 0; rc = findLeafNode(pRtree, iRowid, &pLeaf, &iNode); if( rc==SQLITE_OK && pLeaf!=0 ){ @@ -195406,7 +195406,7 @@ static int geopolyFilter( if( rc ){ goto geopoly_filter_end; } - pCsr->aConstraint = p = tdsqlite3_malloc(sizeof(RtreeConstraint)*4); + pCsr->aConstraint = p = sqlite3_malloc(sizeof(RtreeConstraint)*4); pCsr->nConstraint = 4; if( p==0 ){ rc = SQLITE_NOMEM; @@ -195487,14 +195487,14 @@ geopoly_filter_end: ** 4 "fullscan" full-table scan. ** ------------------------------------------------ */ -static int geopolyBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ +static int geopolyBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int ii; int iRowidTerm = -1; int iFuncTerm = -1; int idxNum = 0; for(ii=0; iinConstraint; ii++){ - struct tdsqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii]; if( !p->usable ) continue; if( p->iColumn<0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ iRowidTerm = ii; @@ -195539,7 +195539,7 @@ static int geopolyBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo) /* ** GEOPOLY virtual table module xColumn method. */ -static int geopolyColumn(tdsqlite3_vtab_cursor *cur, tdsqlite3_context *ctx, int i){ +static int geopolyColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ Rtree *pRtree = (Rtree *)cur->pVtab; RtreeCursor *pCsr = (RtreeCursor *)cur; RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr); @@ -195548,26 +195548,26 @@ static int geopolyColumn(tdsqlite3_vtab_cursor *cur, tdsqlite3_context *ctx, int if( rc ) return rc; if( p==0 ) return SQLITE_OK; - if( i==0 && tdsqlite3_vtab_nochange(ctx) ) return SQLITE_OK; + if( i==0 && sqlite3_vtab_nochange(ctx) ) return SQLITE_OK; if( i<=pRtree->nAux ){ if( !pCsr->bAuxValid ){ if( pCsr->pReadAux==0 ){ - rc = tdsqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, + rc = sqlite3_prepare_v3(pRtree->db, pRtree->zReadAuxSql, -1, 0, &pCsr->pReadAux, 0); if( rc ) return rc; } - tdsqlite3_bind_int64(pCsr->pReadAux, 1, + sqlite3_bind_int64(pCsr->pReadAux, 1, nodeGetRowid(pRtree, pNode, p->iCell)); - rc = tdsqlite3_step(pCsr->pReadAux); + rc = sqlite3_step(pCsr->pReadAux); if( rc==SQLITE_ROW ){ pCsr->bAuxValid = 1; }else{ - tdsqlite3_reset(pCsr->pReadAux); + sqlite3_reset(pCsr->pReadAux); if( rc==SQLITE_DONE ) rc = SQLITE_OK; return rc; } } - tdsqlite3_result_value(ctx, tdsqlite3_column_value(pCsr->pReadAux, i+2)); + sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pReadAux, i+2)); } return SQLITE_OK; } @@ -195595,9 +195595,9 @@ static int geopolyColumn(tdsqlite3_vtab_cursor *cur, tdsqlite3_context *ctx, int ** argv[3] = new value for first application-defined column.... */ static int geopolyUpdate( - tdsqlite3_vtab *pVtab, + sqlite3_vtab *pVtab, int nData, - tdsqlite3_value **aData, + sqlite3_value **aData, sqlite_int64 *pRowid ){ Rtree *pRtree = (Rtree *)pVtab; @@ -195618,22 +195618,22 @@ static int geopolyUpdate( rtreeReference(pRtree); assert(nData>=1); - oldRowidValid = tdsqlite3_value_type(aData[0])!=SQLITE_NULL;; - oldRowid = oldRowidValid ? tdsqlite3_value_int64(aData[0]) : 0; - newRowidValid = nData>1 && tdsqlite3_value_type(aData[1])!=SQLITE_NULL; - newRowid = newRowidValid ? tdsqlite3_value_int64(aData[1]) : 0; + oldRowidValid = sqlite3_value_type(aData[0])!=SQLITE_NULL;; + oldRowid = oldRowidValid ? sqlite3_value_int64(aData[0]) : 0; + newRowidValid = nData>1 && sqlite3_value_type(aData[1])!=SQLITE_NULL; + newRowid = newRowidValid ? sqlite3_value_int64(aData[1]) : 0; cell.iRowid = newRowid; if( nData>1 /* not a DELETE */ && (!oldRowidValid /* INSERT */ - || !tdsqlite3_value_nochange(aData[2]) /* UPDATE _shape */ + || !sqlite3_value_nochange(aData[2]) /* UPDATE _shape */ || oldRowid!=newRowid) /* Rowid change */ ){ geopolyBBox(0, aData[2], cell.aCoord, &rc); if( rc ){ if( rc==SQLITE_ERROR ){ pVtab->zErrMsg = - tdsqlite3_mprintf("_shape does not contain a valid polygon"); + sqlite3_mprintf("_shape does not contain a valid polygon"); } goto geopoly_update_end; } @@ -195643,11 +195643,11 @@ static int geopolyUpdate( ** the table. If so, the constraint has failed. */ if( newRowidValid && (!oldRowidValid || oldRowid!=newRowid) ){ int steprc; - tdsqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); - steprc = tdsqlite3_step(pRtree->pReadRowid); - rc = tdsqlite3_reset(pRtree->pReadRowid); + sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid); + steprc = sqlite3_step(pRtree->pReadRowid); + rc = sqlite3_reset(pRtree->pReadRowid); if( SQLITE_ROW==steprc ){ - if( tdsqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ + if( sqlite3_vtab_on_conflict(pRtree->db)==SQLITE_REPLACE ){ rc = rtreeDeleteRowid(pRtree, cell.iRowid); }else{ rc = rtreeConstraintError(pRtree, 0); @@ -195691,33 +195691,33 @@ static int geopolyUpdate( /* Change the data */ if( rc==SQLITE_OK && nData>1 ){ - tdsqlite3_stmt *pUp = pRtree->pWriteAux; + sqlite3_stmt *pUp = pRtree->pWriteAux; int jj; int nChange = 0; - tdsqlite3_bind_int64(pUp, 1, cell.iRowid); + sqlite3_bind_int64(pUp, 1, cell.iRowid); assert( pRtree->nAux>=1 ); - if( tdsqlite3_value_nochange(aData[2]) ){ - tdsqlite3_bind_null(pUp, 2); + if( sqlite3_value_nochange(aData[2]) ){ + sqlite3_bind_null(pUp, 2); }else{ GeoPoly *p = 0; - if( tdsqlite3_value_type(aData[2])==SQLITE_TEXT + if( sqlite3_value_type(aData[2])==SQLITE_TEXT && (p = geopolyFuncParam(0, aData[2], &rc))!=0 && rc==SQLITE_OK ){ - tdsqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); + sqlite3_bind_blob(pUp, 2, p->hdr, 4+8*p->nVertex, SQLITE_TRANSIENT); }else{ - tdsqlite3_bind_value(pUp, 2, aData[2]); + sqlite3_bind_value(pUp, 2, aData[2]); } - tdsqlite3_free(p); + sqlite3_free(p); nChange = 1; } for(jj=1; jjnAux; jj++){ nChange++; - tdsqlite3_bind_value(pUp, jj+2, aData[jj+2]); + sqlite3_bind_value(pUp, jj+2, aData[jj+2]); } if( nChange ){ - tdsqlite3_step(pUp); - rc = tdsqlite3_reset(pUp); + sqlite3_step(pUp); + rc = sqlite3_reset(pUp); } } @@ -195731,18 +195731,18 @@ geopoly_update_end: ** for use in xBestIndex. */ static int geopolyFindFunction( - tdsqlite3_vtab *pVtab, + sqlite3_vtab *pVtab, int nArg, const char *zName, - void (**pxFunc)(tdsqlite3_context*,int,tdsqlite3_value**), + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg ){ - if( tdsqlite3_stricmp(zName, "geopoly_overlap")==0 ){ + if( sqlite3_stricmp(zName, "geopoly_overlap")==0 ){ *pxFunc = geopolyOverlapFunc; *ppArg = 0; return SQLITE_INDEX_CONSTRAINT_FUNCTION; } - if( tdsqlite3_stricmp(zName, "geopoly_within")==0 ){ + if( sqlite3_stricmp(zName, "geopoly_within")==0 ){ *pxFunc = geopolyWithinFunc; *ppArg = 0; return SQLITE_INDEX_CONSTRAINT_FUNCTION+1; @@ -195751,7 +195751,7 @@ static int geopolyFindFunction( } -static tdsqlite3_module geopolyModule = { +static sqlite3_module geopolyModule = { 3, /* iVersion */ geopolyCreate, /* xCreate - create a table */ geopolyConnect, /* xConnect - connect to an existing table */ @@ -195778,10 +195778,10 @@ static tdsqlite3_module geopolyModule = { rtreeShadowName /* xShadowName */ }; -static int tdsqlite3_geopoly_init(tdsqlite3 *db){ +static int sqlite3_geopoly_init(sqlite3 *db){ int rc = SQLITE_OK; static const struct { - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**); + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); signed char nArg; unsigned char bPure; const char *zName; @@ -195800,8 +195800,8 @@ static int tdsqlite3_geopoly_init(tdsqlite3 *db){ { geopolyCcwFunc, 1, 1, "geopoly_ccw" }, }; static const struct { - void (*xStep)(tdsqlite3_context*,int,tdsqlite3_value**); - void (*xFinal)(tdsqlite3_context*); + void (*xStep)(sqlite3_context*,int,sqlite3_value**); + void (*xFinal)(sqlite3_context*); const char *zName; } aAgg[] = { { geopolyBBoxStep, geopolyBBoxFinal, "geopoly_group_bbox" }, @@ -195814,17 +195814,17 @@ static int tdsqlite3_geopoly_init(tdsqlite3 *db){ }else{ enc = SQLITE_UTF8|SQLITE_DIRECTONLY; } - rc = tdsqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, + rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg, enc, 0, aFunc[i].xFunc, 0, 0); } for(i=0; ixDestructor ) pInfo->xDestructor(pInfo->pContext); - tdsqlite3_free(p); + sqlite3_free(p); } /* @@ -195890,14 +195890,14 @@ static void rtreeMatchArgFree(void *pArg){ int i; RtreeMatchArg *p = (RtreeMatchArg*)pArg; for(i=0; inParam; i++){ - tdsqlite3_value_free(p->apSqlParam[i]); + sqlite3_value_free(p->apSqlParam[i]); } - tdsqlite3_free(p); + sqlite3_free(p); } /* -** Each call to tdsqlite3_rtree_geometry_callback() or -** tdsqlite3_rtree_query_callback() creates an ordinary SQLite +** Each call to sqlite3_rtree_geometry_callback() or +** sqlite3_rtree_query_callback() creates an ordinary SQLite ** scalar function that is implemented by this routine. ** ** All this function does is construct an RtreeMatchArg object that @@ -195909,37 +195909,37 @@ static void rtreeMatchArgFree(void *pArg){ ** the RtreeMatchArg object, and use the RtreeMatchArg object to figure ** out which elements of the R-Tree should be returned by the query. */ -static void geomCallback(tdsqlite3_context *ctx, int nArg, tdsqlite3_value **aArg){ - RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)tdsqlite3_user_data(ctx); +static void geomCallback(sqlite3_context *ctx, int nArg, sqlite3_value **aArg){ + RtreeGeomCallback *pGeomCtx = (RtreeGeomCallback *)sqlite3_user_data(ctx); RtreeMatchArg *pBlob; - tdsqlite3_int64 nBlob; + sqlite3_int64 nBlob; int memErr = 0; nBlob = sizeof(RtreeMatchArg) + (nArg-1)*sizeof(RtreeDValue) - + nArg*sizeof(tdsqlite3_value*); - pBlob = (RtreeMatchArg *)tdsqlite3_malloc64(nBlob); + + nArg*sizeof(sqlite3_value*); + pBlob = (RtreeMatchArg *)sqlite3_malloc64(nBlob); if( !pBlob ){ - tdsqlite3_result_error_nomem(ctx); + sqlite3_result_error_nomem(ctx); }else{ int i; pBlob->iSize = nBlob; pBlob->cb = pGeomCtx[0]; - pBlob->apSqlParam = (tdsqlite3_value**)&pBlob->aParam[nArg]; + pBlob->apSqlParam = (sqlite3_value**)&pBlob->aParam[nArg]; pBlob->nParam = nArg; for(i=0; iapSqlParam[i] = tdsqlite3_value_dup(aArg[i]); + pBlob->apSqlParam[i] = sqlite3_value_dup(aArg[i]); if( pBlob->apSqlParam[i]==0 ) memErr = 1; #ifdef SQLITE_RTREE_INT_ONLY - pBlob->aParam[i] = tdsqlite3_value_int64(aArg[i]); + pBlob->aParam[i] = sqlite3_value_int64(aArg[i]); #else - pBlob->aParam[i] = tdsqlite3_value_double(aArg[i]); + pBlob->aParam[i] = sqlite3_value_double(aArg[i]); #endif } if( memErr ){ - tdsqlite3_result_error_nomem(ctx); + sqlite3_result_error_nomem(ctx); rtreeMatchArgFree(pBlob); }else{ - tdsqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree); + sqlite3_result_pointer(ctx, pBlob, "RtreeMatchArg", rtreeMatchArgFree); } } } @@ -195947,22 +195947,22 @@ static void geomCallback(tdsqlite3_context *ctx, int nArg, tdsqlite3_value **aAr /* ** Register a new geometry function for use with the r-tree MATCH operator. */ -SQLITE_API int tdsqlite3_rtree_geometry_callback( - tdsqlite3 *db, /* Register SQL function on this connection */ +SQLITE_API int sqlite3_rtree_geometry_callback( + sqlite3 *db, /* Register SQL function on this connection */ const char *zGeom, /* Name of the new SQL function */ - int (*xGeom)(tdsqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ + int (*xGeom)(sqlite3_rtree_geometry*,int,RtreeDValue*,int*), /* Callback */ void *pContext /* Extra data associated with the callback */ ){ RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ /* Allocate and populate the context object. */ - pGeomCtx = (RtreeGeomCallback *)tdsqlite3_malloc(sizeof(RtreeGeomCallback)); + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); if( !pGeomCtx ) return SQLITE_NOMEM; pGeomCtx->xGeom = xGeom; pGeomCtx->xQueryFunc = 0; pGeomCtx->xDestructor = 0; pGeomCtx->pContext = pContext; - return tdsqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, + return sqlite3_create_function_v2(db, zGeom, -1, SQLITE_ANY, (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback ); } @@ -195971,23 +195971,23 @@ SQLITE_API int tdsqlite3_rtree_geometry_callback( ** Register a new 2nd-generation geometry function for use with the ** r-tree MATCH operator. */ -SQLITE_API int tdsqlite3_rtree_query_callback( - tdsqlite3 *db, /* Register SQL function on this connection */ +SQLITE_API int sqlite3_rtree_query_callback( + sqlite3 *db, /* Register SQL function on this connection */ const char *zQueryFunc, /* Name of new SQL function */ - int (*xQueryFunc)(tdsqlite3_rtree_query_info*), /* Callback */ + int (*xQueryFunc)(sqlite3_rtree_query_info*), /* Callback */ void *pContext, /* Extra data passed into the callback */ void (*xDestructor)(void*) /* Destructor for the extra data */ ){ RtreeGeomCallback *pGeomCtx; /* Context object for new user-function */ /* Allocate and populate the context object. */ - pGeomCtx = (RtreeGeomCallback *)tdsqlite3_malloc(sizeof(RtreeGeomCallback)); + pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback)); if( !pGeomCtx ) return SQLITE_NOMEM; pGeomCtx->xGeom = 0; pGeomCtx->xQueryFunc = xQueryFunc; pGeomCtx->xDestructor = xDestructor; pGeomCtx->pContext = pContext; - return tdsqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, + return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback ); } @@ -195996,13 +195996,13 @@ SQLITE_API int tdsqlite3_rtree_query_callback( #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int tdsqlite3_rtree_init( - tdsqlite3 *db, +SQLITE_API int sqlite3_rtree_init( + sqlite3 *db, char **pzErrMsg, - const tdsqlite3_api_routines *pApi + const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi) - return tdsqlite3RtreeInit(db); + return sqlite3RtreeInit(db); } #endif @@ -196053,7 +196053,7 @@ SQLITE_API int tdsqlite3_rtree_init( /* #include */ #ifndef SQLITE_CORE -/* #include "tdsqlite3ext.h" */ +/* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #else /* #include "sqlite3.h" */ @@ -196067,14 +196067,14 @@ SQLITE_API int tdsqlite3_rtree_init( ** loaded with an error message based on the following two args. */ static void icuFunctionError( - tdsqlite3_context *pCtx, /* SQLite scalar function context */ + sqlite3_context *pCtx, /* SQLite scalar function context */ const char *zName, /* Name of ICU function that failed */ UErrorCode e /* Error code returned by ICU function */ ){ char zBuf[128]; - tdsqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); + sqlite3_snprintf(128, zBuf, "ICU error: %s(): %s", zName, u_errorName(e)); zBuf[127] = '\0'; - tdsqlite3_result_error(pCtx, zBuf, -1); + sqlite3_result_error(pCtx, zBuf, -1); } #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) @@ -196088,10 +196088,10 @@ static void icuFunctionError( #endif /* -** Version of tdsqlite3_free() that is always a function, never a macro. +** Version of sqlite3_free() that is always a function, never a macro. */ static void xFree(void *p){ - tdsqlite3_free(p); + sqlite3_free(p); } /* @@ -196220,19 +196220,19 @@ static int icuLikeCompare( ** is mapped to like(B, A, E). */ static void icuLikeFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ - const unsigned char *zA = tdsqlite3_value_text(argv[0]); - const unsigned char *zB = tdsqlite3_value_text(argv[1]); + const unsigned char *zA = sqlite3_value_text(argv[0]); + const unsigned char *zB = sqlite3_value_text(argv[1]); UChar32 uEsc = 0; /* Limit the length of the LIKE or GLOB pattern to avoid problems ** of deep recursion and N*N behavior in patternCompare(). */ - if( tdsqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ - tdsqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); + if( sqlite3_value_bytes(argv[0])>SQLITE_MAX_LIKE_PATTERN_LENGTH ){ + sqlite3_result_error(context, "LIKE or GLOB pattern too complex", -1); return; } @@ -196241,26 +196241,26 @@ static void icuLikeFunc( /* The escape character string must consist of a single UTF-8 character. ** Otherwise, return an error. */ - int nE= tdsqlite3_value_bytes(argv[2]); - const unsigned char *zE = tdsqlite3_value_text(argv[2]); + int nE= sqlite3_value_bytes(argv[2]); + const unsigned char *zE = sqlite3_value_text(argv[2]); int i = 0; if( zE==0 ) return; U8_NEXT(zE, i, nE, uEsc); if( i!=nE){ - tdsqlite3_result_error(context, + sqlite3_result_error(context, "ESCAPE expression must be a single character", -1); return; } } if( zA && zB ){ - tdsqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc)); + sqlite3_result_int(context, icuLikeCompare(zA, zB, uEsc)); } } /* ** Function to delete compiled regexp objects. Registered as -** a destructor function with tdsqlite3_set_auxdata(). +** a destructor function with sqlite3_set_auxdata(). */ static void icuRegexpDelete(void *p){ URegularExpression *pExpr = (URegularExpression *)p; @@ -196286,11 +196286,11 @@ static void icuRegexpDelete(void *p){ ** uregex_matches() ** uregex_close() */ -static void icuRegexpFunc(tdsqlite3_context *p, int nArg, tdsqlite3_value **apArg){ +static void icuRegexpFunc(sqlite3_context *p, int nArg, sqlite3_value **apArg){ UErrorCode status = U_ZERO_ERROR; URegularExpression *pExpr; UBool res; - const UChar *zString = tdsqlite3_value_text16(apArg[1]); + const UChar *zString = sqlite3_value_text16(apArg[1]); (void)nArg; /* Unused parameter */ @@ -196301,16 +196301,16 @@ static void icuRegexpFunc(tdsqlite3_context *p, int nArg, tdsqlite3_value **apAr return; } - pExpr = tdsqlite3_get_auxdata(p, 0); + pExpr = sqlite3_get_auxdata(p, 0); if( !pExpr ){ - const UChar *zPattern = tdsqlite3_value_text16(apArg[0]); + const UChar *zPattern = sqlite3_value_text16(apArg[0]); if( !zPattern ){ return; } pExpr = uregex_open(zPattern, -1, 0, 0, &status); if( U_SUCCESS(status) ){ - tdsqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); + sqlite3_set_auxdata(p, 0, pExpr, icuRegexpDelete); }else{ assert(!pExpr); icuFunctionError(p, "uregex_open", status); @@ -196340,7 +196340,7 @@ static void icuRegexpFunc(tdsqlite3_context *p, int nArg, tdsqlite3_value **apAr uregex_setText(pExpr, 0, 0, &status); /* Return 1 or 0. */ - tdsqlite3_result_int(p, res ? 1 : 0); + sqlite3_result_int(p, res ? 1 : 0); } /* @@ -196369,7 +196369,7 @@ static void icuRegexpFunc(tdsqlite3_context *p, int nArg, tdsqlite3_value **apAr ** ** http://www.icu-project.org/userguide/posix.html#case_mappings */ -static void icuCaseFunc16(tdsqlite3_context *p, int nArg, tdsqlite3_value **apArg){ +static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){ const UChar *zInput; /* Pointer to input string */ UChar *zOutput = 0; /* Pointer to output buffer */ int nInput; /* Size of utf-16 input string in bytes */ @@ -196380,26 +196380,26 @@ static void icuCaseFunc16(tdsqlite3_context *p, int nArg, tdsqlite3_value **apAr const char *zLocale = 0; assert(nArg==1 || nArg==2); - bToUpper = (tdsqlite3_user_data(p)!=0); + bToUpper = (sqlite3_user_data(p)!=0); if( nArg==2 ){ - zLocale = (const char *)tdsqlite3_value_text(apArg[1]); + zLocale = (const char *)sqlite3_value_text(apArg[1]); } - zInput = tdsqlite3_value_text16(apArg[0]); + zInput = sqlite3_value_text16(apArg[0]); if( !zInput ){ return; } - nOut = nInput = tdsqlite3_value_bytes16(apArg[0]); + nOut = nInput = sqlite3_value_bytes16(apArg[0]); if( nOut==0 ){ - tdsqlite3_result_text16(p, "", 0, SQLITE_STATIC); + sqlite3_result_text16(p, "", 0, SQLITE_STATIC); return; } for(cnt=0; cnt<2; cnt++){ - UChar *zNew = tdsqlite3_realloc(zOutput, nOut); + UChar *zNew = sqlite3_realloc(zOutput, nOut); if( zNew==0 ){ - tdsqlite3_free(zOutput); - tdsqlite3_result_error_nomem(p); + sqlite3_free(zOutput); + sqlite3_result_error_nomem(p); return; } zOutput = zNew; @@ -196411,7 +196411,7 @@ static void icuCaseFunc16(tdsqlite3_context *p, int nArg, tdsqlite3_value **apAr } if( U_SUCCESS(status) ){ - tdsqlite3_result_text16(p, zOutput, nOut, xFree); + sqlite3_result_text16(p, zOutput, nOut, xFree); }else if( status==U_BUFFER_OVERFLOW_ERROR ){ assert( cnt==0 ); continue; @@ -196471,21 +196471,21 @@ static int icuCollationColl( ** collation sequence to create. */ static void icuLoadCollation( - tdsqlite3_context *p, + sqlite3_context *p, int nArg, - tdsqlite3_value **apArg + sqlite3_value **apArg ){ - tdsqlite3 *db = (tdsqlite3 *)tdsqlite3_user_data(p); + sqlite3 *db = (sqlite3 *)sqlite3_user_data(p); UErrorCode status = U_ZERO_ERROR; const char *zLocale; /* Locale identifier - (eg. "jp_JP") */ const char *zName; /* SQL Collation sequence name (eg. "japanese") */ UCollator *pUCollator; /* ICU library collation object */ - int rc; /* Return code from tdsqlite3_create_collation_x() */ + int rc; /* Return code from sqlite3_create_collation_x() */ assert(nArg==2); (void)nArg; /* Unused parameter */ - zLocale = (const char *)tdsqlite3_value_text(apArg[0]); - zName = (const char *)tdsqlite3_value_text(apArg[1]); + zLocale = (const char *)sqlite3_value_text(apArg[0]); + zName = (const char *)sqlite3_value_text(apArg[1]); if( !zLocale || !zName ){ return; @@ -196498,26 +196498,26 @@ static void icuLoadCollation( } assert(p); - rc = tdsqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, + rc = sqlite3_create_collation_v2(db, zName, SQLITE_UTF16, (void *)pUCollator, icuCollationColl, icuCollationDel ); if( rc!=SQLITE_OK ){ ucol_close(pUCollator); - tdsqlite3_result_error(p, "Error registering collation function", -1); + sqlite3_result_error(p, "Error registering collation function", -1); } } /* ** Register the ICU extension functions with database db. */ -SQLITE_PRIVATE int tdsqlite3IcuInit(tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db){ # define SQLITEICU_EXTRAFLAGS (SQLITE_DETERMINISTIC|SQLITE_INNOCUOUS) static const struct IcuScalar { const char *zName; /* Function name */ unsigned char nArg; /* Number of arguments */ unsigned int enc; /* Optimal text encoding */ - unsigned char iContext; /* tdsqlite3_user_data() context */ - void (*xFunc)(tdsqlite3_context*,int,tdsqlite3_value**); + unsigned char iContext; /* sqlite3_user_data() context */ + void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } scalars[] = { {"icu_load_collation",2,SQLITE_UTF8|SQLITE_DIRECTONLY,1, icuLoadCollation}, #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_ICU) @@ -196539,7 +196539,7 @@ SQLITE_PRIVATE int tdsqlite3IcuInit(tdsqlite3 *db){ for(i=0; rc==SQLITE_OK && i<(int)(sizeof(scalars)/sizeof(scalars[0])); i++){ const struct IcuScalar *p = &scalars[i]; - rc = tdsqlite3_create_function( + rc = sqlite3_create_function( db, p->zName, p->nArg, p->enc, p->iContext ? (void*)db : (void*)0, p->xFunc, 0, 0 @@ -196553,13 +196553,13 @@ SQLITE_PRIVATE int tdsqlite3IcuInit(tdsqlite3 *db){ #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int tdsqlite3_icu_init( - tdsqlite3 *db, +SQLITE_API int sqlite3_icu_init( + sqlite3 *db, char **pzErrMsg, - const tdsqlite3_api_routines *pApi + const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi) - return tdsqlite3IcuInit(db); + return sqlite3IcuInit(db); } #endif @@ -196597,12 +196597,12 @@ typedef struct IcuTokenizer IcuTokenizer; typedef struct IcuCursor IcuCursor; struct IcuTokenizer { - tdsqlite3_tokenizer base; + sqlite3_tokenizer base; char *zLocale; }; struct IcuCursor { - tdsqlite3_tokenizer_cursor base; + sqlite3_tokenizer_cursor base; UBreakIterator *pIter; /* ICU break-iterator object */ int nChar; /* Number of UChar elements in pInput */ @@ -196621,7 +196621,7 @@ struct IcuCursor { static int icuCreate( int argc, /* Number of entries in argv[] */ const char * const *argv, /* Tokenizer creation arguments */ - tdsqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ + sqlite3_tokenizer **ppTokenizer /* OUT: Created tokenizer */ ){ IcuTokenizer *p; int n = 0; @@ -196629,7 +196629,7 @@ static int icuCreate( if( argc>0 ){ n = strlen(argv[0])+1; } - p = (IcuTokenizer *)tdsqlite3_malloc64(sizeof(IcuTokenizer)+n); + p = (IcuTokenizer *)sqlite3_malloc64(sizeof(IcuTokenizer)+n); if( !p ){ return SQLITE_NOMEM; } @@ -196640,7 +196640,7 @@ static int icuCreate( memcpy(p->zLocale, argv[0], n); } - *ppTokenizer = (tdsqlite3_tokenizer *)p; + *ppTokenizer = (sqlite3_tokenizer *)p; return SQLITE_OK; } @@ -196648,9 +196648,9 @@ static int icuCreate( /* ** Destroy a tokenizer */ -static int icuDestroy(tdsqlite3_tokenizer *pTokenizer){ +static int icuDestroy(sqlite3_tokenizer *pTokenizer){ IcuTokenizer *p = (IcuTokenizer *)pTokenizer; - tdsqlite3_free(p); + sqlite3_free(p); return SQLITE_OK; } @@ -196661,10 +196661,10 @@ static int icuDestroy(tdsqlite3_tokenizer *pTokenizer){ ** *ppCursor. */ static int icuOpen( - tdsqlite3_tokenizer *pTokenizer, /* The tokenizer */ + sqlite3_tokenizer *pTokenizer, /* The tokenizer */ const char *zInput, /* Input string */ int nInput, /* Length of zInput in bytes */ - tdsqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ + sqlite3_tokenizer_cursor **ppCursor /* OUT: Tokenization cursor */ ){ IcuTokenizer *p = (IcuTokenizer *)pTokenizer; IcuCursor *pCsr; @@ -196686,7 +196686,7 @@ static int icuOpen( nInput = strlen(zInput); } nChar = nInput+1; - pCsr = (IcuCursor *)tdsqlite3_malloc64( + pCsr = (IcuCursor *)sqlite3_malloc64( sizeof(IcuCursor) + /* IcuCursor */ ((nChar+3)&~3) * sizeof(UChar) + /* IcuCursor.aChar[] */ (nChar+1) * sizeof(int) /* IcuCursor.aOffset[] */ @@ -196705,7 +196705,7 @@ static int icuOpen( c = u_foldCase(c, opt); U16_APPEND(pCsr->aChar, iOut, nChar, c, isError); if( isError ){ - tdsqlite3_free(pCsr); + sqlite3_free(pCsr); return SQLITE_ERROR; } pCsr->aOffset[iOut] = iInput; @@ -196719,24 +196719,24 @@ static int icuOpen( pCsr->pIter = ubrk_open(UBRK_WORD, p->zLocale, pCsr->aChar, iOut, &status); if( !U_SUCCESS(status) ){ - tdsqlite3_free(pCsr); + sqlite3_free(pCsr); return SQLITE_ERROR; } pCsr->nChar = iOut; ubrk_first(pCsr->pIter); - *ppCursor = (tdsqlite3_tokenizer_cursor *)pCsr; + *ppCursor = (sqlite3_tokenizer_cursor *)pCsr; return SQLITE_OK; } /* ** Close a tokenization cursor previously opened by a call to icuOpen(). */ -static int icuClose(tdsqlite3_tokenizer_cursor *pCursor){ +static int icuClose(sqlite3_tokenizer_cursor *pCursor){ IcuCursor *pCsr = (IcuCursor *)pCursor; ubrk_close(pCsr->pIter); - tdsqlite3_free(pCsr->zBuffer); - tdsqlite3_free(pCsr); + sqlite3_free(pCsr->zBuffer); + sqlite3_free(pCsr); return SQLITE_OK; } @@ -196744,7 +196744,7 @@ static int icuClose(tdsqlite3_tokenizer_cursor *pCursor){ ** Extract the next token from a tokenization cursor. */ static int icuNext( - tdsqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ + sqlite3_tokenizer_cursor *pCursor, /* Cursor returned by simpleOpen */ const char **ppToken, /* OUT: *ppToken is the token text */ int *pnBytes, /* OUT: Number of bytes in token */ int *piStartOffset, /* OUT: Starting offset of token */ @@ -196781,7 +196781,7 @@ static int icuNext( do { UErrorCode status = U_ZERO_ERROR; if( nByte ){ - char *zNew = tdsqlite3_realloc(pCsr->zBuffer, nByte); + char *zNew = sqlite3_realloc(pCsr->zBuffer, nByte); if( !zNew ){ return SQLITE_NOMEM; } @@ -196808,7 +196808,7 @@ static int icuNext( /* ** The set of routines that implement the simple tokenizer */ -static const tdsqlite3_tokenizer_module icuTokenizerModule = { +static const sqlite3_tokenizer_module icuTokenizerModule = { 0, /* iVersion */ icuCreate, /* xCreate */ icuDestroy, /* xCreate */ @@ -196821,8 +196821,8 @@ static const tdsqlite3_tokenizer_module icuTokenizerModule = { /* ** Set *ppModule to point at the implementation of the ICU tokenizer. */ -SQLITE_PRIVATE void tdsqlite3Fts3IcuTokenizerModule( - tdsqlite3_tokenizer_module const**ppModule +SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule( + sqlite3_tokenizer_module const**ppModule ){ *ppModule = &icuTokenizerModule; } @@ -196831,7 +196831,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3IcuTokenizerModule( #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */ /************** End of fts3_icu.c ********************************************/ -/************** Begin file tdsqlite3rbu.c **************************************/ +/************** Begin file sqlite3rbu.c **************************************/ /* ** 2014 August 30 ** @@ -196849,7 +196849,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3IcuTokenizerModule( ** ** The RBU extension requires that the RBU update be packaged as an ** SQLite database. The tables it expects to find are described in -** tdsqlite3rbu.h. Essentially, for each table xyz in the target database +** sqlite3rbu.h. Essentially, for each table xyz in the target database ** that the user wishes to write to, a corresponding data_xyz table is ** created in the RBU database and populated with one row for each row to ** update, insert or delete from the target table. @@ -196882,7 +196882,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3IcuTokenizerModule( ** ** 3) The new *-wal file is checkpointed. This proceeds in the same way ** as a regular database checkpoint, except that a single frame is -** checkpointed each time tdsqlite3rbu_step() is called. If the RBU +** checkpointed each time sqlite3rbu_step() is called. If the RBU ** handle is closed before the entire *-wal file is checkpointed, ** the checkpoint progress is saved in the RBU database and the ** checkpoint can be resumed by another RBU client at some point in @@ -196921,8 +196921,8 @@ SQLITE_PRIVATE void tdsqlite3Fts3IcuTokenizerModule( /* #include "sqlite3.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) -/************** Include tdsqlite3rbu.h in the middle of tdsqlite3rbu.c ***********/ -/************** Begin file tdsqlite3rbu.h **************************************/ +/************** Include sqlite3rbu.h in the middle of sqlite3rbu.c ***********/ +/************** Begin file sqlite3rbu.h **************************************/ /* ** 2014 August 30 ** @@ -197146,19 +197146,19 @@ SQLITE_PRIVATE void tdsqlite3Fts3IcuTokenizerModule( ** stored on disk to an existing target database. Essentially, the ** application: ** -** 1) Opens an RBU handle using the tdsqlite3rbu_open() function. +** 1) Opens an RBU handle using the sqlite3rbu_open() function. ** ** 2) Registers any required virtual table modules with the database -** handle returned by tdsqlite3rbu_db(). Also, if required, register +** handle returned by sqlite3rbu_db(). Also, if required, register ** the rbu_delta() implementation. ** -** 3) Calls the tdsqlite3rbu_step() function one or more times on -** the new handle. Each call to tdsqlite3rbu_step() performs a single +** 3) Calls the sqlite3rbu_step() function one or more times on +** the new handle. Each call to sqlite3rbu_step() performs a single ** b-tree operation, so thousands of calls may be required to apply ** a complete update. ** -** 4) Calls tdsqlite3rbu_close() to close the RBU update handle. If -** tdsqlite3rbu_step() has been called enough times to completely +** 4) Calls sqlite3rbu_close() to close the RBU update handle. If +** sqlite3rbu_step() has been called enough times to completely ** apply the update to the target database, then the RBU database ** is marked as fully applied. Otherwise, the state of the RBU ** update application is saved in the RBU database for later @@ -197167,7 +197167,7 @@ SQLITE_PRIVATE void tdsqlite3Fts3IcuTokenizerModule( ** See comments below for more detail on APIs. ** ** If an update is only partially applied to the target database by the -** time tdsqlite3rbu_close() is called, various state information is saved +** time sqlite3rbu_close() is called, various state information is saved ** within the RBU database. This allows subsequent processes to automatically ** resume the RBU update from where it left off. ** @@ -197198,15 +197198,15 @@ SQLITE_PRIVATE void tdsqlite3Fts3IcuTokenizerModule( extern "C" { #endif -typedef struct tdsqlite3rbu tdsqlite3rbu; +typedef struct sqlite3rbu sqlite3rbu; /* ** Open an RBU handle. ** ** Argument zTarget is the path to the target database. Argument zRbu is ** the path to the RBU database. Each call to this function must be matched -** by a call to tdsqlite3rbu_close(). When opening the databases, RBU passes -** the SQLITE_CONFIG_URI flag to tdsqlite3_open_v2(). So if either zTarget +** by a call to sqlite3rbu_close(). When opening the databases, RBU passes +** the SQLITE_CONFIG_URI flag to sqlite3_open_v2(). So if either zTarget ** or zRbu begin with "file:", it will be interpreted as an SQLite ** database URI, not a regular file name. ** @@ -197233,7 +197233,7 @@ typedef struct tdsqlite3rbu tdsqlite3rbu; ** not work out of the box with zipvfs. Refer to the comment describing ** the zipvfs_create_vfs() API below for details on using RBU with zipvfs. */ -SQLITE_API tdsqlite3rbu *tdsqlite3rbu_open( +SQLITE_API sqlite3rbu *sqlite3rbu_open( const char *zTarget, const char *zRbu, const char *zState @@ -197246,10 +197246,10 @@ SQLITE_API tdsqlite3rbu *tdsqlite3rbu_open( ** ** The second argument to this function identifies a database in which ** to store the state of the RBU vacuum operation if it is suspended. The -** first time tdsqlite3rbu_vacuum() is called, to start an RBU vacuum +** first time sqlite3rbu_vacuum() is called, to start an RBU vacuum ** operation, the state database should either not exist or be empty ** (contain no tables). If an RBU vacuum is suspended by calling -** tdsqlite3rbu_close() on the RBU handle before tdsqlite3rbu_step() has +** sqlite3rbu_close() on the RBU handle before sqlite3rbu_step() has ** returned SQLITE_DONE, the vacuum state is stored in the state database. ** The vacuum can be resumed by calling this function to open a new RBU ** handle specifying the same target and state databases. @@ -197266,17 +197266,17 @@ SQLITE_API tdsqlite3rbu *tdsqlite3rbu_open( ** ** This function does not delete the state database after an RBU vacuum ** is completed, even if it created it. However, if the call to -** tdsqlite3rbu_close() returns any value other than SQLITE_OK, the contents +** sqlite3rbu_close() returns any value other than SQLITE_OK, the contents ** of the state tables within the state database are zeroed. This way, -** the next call to tdsqlite3rbu_vacuum() opens a handle that starts a +** the next call to sqlite3rbu_vacuum() opens a handle that starts a ** new RBU vacuum operation. ** -** As with tdsqlite3rbu_open(), Zipvfs users should rever to the comment -** describing the tdsqlite3rbu_create_vfs() API function below for +** As with sqlite3rbu_open(), Zipvfs users should rever to the comment +** describing the sqlite3rbu_create_vfs() API function below for ** a description of the complications associated with using RBU with ** zipvfs databases. */ -SQLITE_API tdsqlite3rbu *tdsqlite3rbu_vacuum( +SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( const char *zTarget, const char *zState ); @@ -197295,13 +197295,13 @@ SQLITE_API tdsqlite3rbu *tdsqlite3rbu_vacuum( ** If the temp space limit is exceeded during operation, an SQLITE_FULL ** error is returned. */ -SQLITE_API tdsqlite3_int64 tdsqlite3rbu_temp_size_limit(tdsqlite3rbu*, tdsqlite3_int64); +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu*, sqlite3_int64); /* ** Return the current amount of temp file space, in bytes, currently used by ** the RBU handle passed as the only argument. */ -SQLITE_API tdsqlite3_int64 tdsqlite3rbu_temp_size(tdsqlite3rbu*); +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu*); /* ** Internally, each RBU connection uses a separate SQLite database @@ -197315,26 +197315,26 @@ SQLITE_API tdsqlite3_int64 tdsqlite3rbu_temp_size(tdsqlite3rbu*); ** following scenarios: ** ** * If any target tables are virtual tables, it may be necessary to -** call tdsqlite3_create_module() on the target database handle to +** call sqlite3_create_module() on the target database handle to ** register the required virtual table implementations. ** ** * If the data_xxx tables in the RBU source database are virtual -** tables, the application may need to call tdsqlite3_create_module() on +** tables, the application may need to call sqlite3_create_module() on ** the rbu update db handle to any required virtual table ** implementations. ** ** * If the application uses the "rbu_delta()" feature described above, -** it must use tdsqlite3_create_function() or similar to register the +** it must use sqlite3_create_function() or similar to register the ** rbu_delta() implementation with the target database handle. ** ** If an error has occurred, either while opening or stepping the RBU object, ** this function may return NULL. The error code and message may be collected -** when tdsqlite3rbu_close() is called. +** when sqlite3rbu_close() is called. ** ** Database handles returned by this function remain valid until the next -** call to any tdsqlite3rbu_xxx() function other than tdsqlite3rbu_db(). +** call to any sqlite3rbu_xxx() function other than sqlite3rbu_db(). */ -SQLITE_API tdsqlite3 *tdsqlite3rbu_db(tdsqlite3rbu*, int bRbu); +SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu*, int bRbu); /* ** Do some work towards applying the RBU update to the target db. @@ -197344,11 +197344,11 @@ SQLITE_API tdsqlite3 *tdsqlite3rbu_db(tdsqlite3rbu*, int bRbu); ** the RBU update. If an error does occur, some other error code is ** returned. ** -** Once a call to tdsqlite3rbu_step() has returned a value other than +** Once a call to sqlite3rbu_step() has returned a value other than ** SQLITE_OK, all subsequent calls on the same RBU handle are no-ops ** that immediately return the same value. */ -SQLITE_API int tdsqlite3rbu_step(tdsqlite3rbu *pRbu); +SQLITE_API int sqlite3rbu_step(sqlite3rbu *pRbu); /* ** Force RBU to save its state to disk. @@ -197356,11 +197356,11 @@ SQLITE_API int tdsqlite3rbu_step(tdsqlite3rbu *pRbu); ** If a power failure or application crash occurs during an update, following ** system recovery RBU may resume the update from the point at which the state ** was last saved. In other words, from the most recent successful call to -** tdsqlite3rbu_close() or this function. +** sqlite3rbu_close() or this function. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. */ -SQLITE_API int tdsqlite3rbu_savestate(tdsqlite3rbu *pRbu); +SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *pRbu); /* ** Close an RBU handle. @@ -197369,25 +197369,25 @@ SQLITE_API int tdsqlite3rbu_savestate(tdsqlite3rbu *pRbu); ** as fully applied. Otherwise, assuming no error has occurred, save the ** current state of the RBU update appliation to the RBU database. ** -** If an error has already occurred as part of an tdsqlite3rbu_step() -** or tdsqlite3rbu_open() call, or if one occurs within this function, an +** If an error has already occurred as part of an sqlite3rbu_step() +** or sqlite3rbu_open() call, or if one occurs within this function, an ** SQLite error code is returned. Additionally, if pzErrmsg is not NULL, ** *pzErrmsg may be set to point to a buffer containing a utf-8 formatted ** English language error message. It is the responsibility of the caller to -** eventually free any such buffer using tdsqlite3_free(). +** eventually free any such buffer using sqlite3_free(). ** ** Otherwise, if no error occurs, this function returns SQLITE_OK if the ** update has been partially applied, or SQLITE_DONE if it has been ** completely applied. */ -SQLITE_API int tdsqlite3rbu_close(tdsqlite3rbu *pRbu, char **pzErrmsg); +SQLITE_API int sqlite3rbu_close(sqlite3rbu *pRbu, char **pzErrmsg); /* ** Return the total number of key-value operations (inserts, deletes or ** updates) that have been performed on the target database since the ** current RBU update was started. */ -SQLITE_API tdsqlite3_int64 tdsqlite3rbu_progress(tdsqlite3rbu *pRbu); +SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu); /* ** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) @@ -197429,7 +197429,7 @@ SQLITE_API tdsqlite3_int64 tdsqlite3rbu_progress(tdsqlite3rbu *pRbu); ** table exists but is not correctly populated, the value of the *pnOne ** output variable during stage 1 is undefined. */ -SQLITE_API void tdsqlite3rbu_bp_progress(tdsqlite3rbu *pRbu, int *pnOne, int*pnTwo); +SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int*pnTwo); /* ** Obtain an indication as to the current stage of an RBU update or vacuum. @@ -197437,28 +197437,28 @@ SQLITE_API void tdsqlite3rbu_bp_progress(tdsqlite3rbu *pRbu, int *pnOne, int*pnT ** defined in this file. Return values should be interpreted as follows: ** ** SQLITE_RBU_STATE_OAL: -** RBU is currently building a *-oal file. The next call to tdsqlite3rbu_step() +** RBU is currently building a *-oal file. The next call to sqlite3rbu_step() ** may either add further data to the *-oal file, or compute data that will ** be added by a subsequent call. ** ** SQLITE_RBU_STATE_MOVE: -** RBU has finished building the *-oal file. The next call to tdsqlite3rbu_step() +** RBU has finished building the *-oal file. The next call to sqlite3rbu_step() ** will move the *-oal file to the equivalent *-wal path. If the current ** operation is an RBU update, then the updated version of the database ** file will become visible to ordinary SQLite clients following the next -** call to tdsqlite3rbu_step(). +** call to sqlite3rbu_step(). ** ** SQLITE_RBU_STATE_CHECKPOINT: ** RBU is currently performing an incremental checkpoint. The next call to -** tdsqlite3rbu_step() will copy a page of data from the *-wal file into +** sqlite3rbu_step() will copy a page of data from the *-wal file into ** the target database file. ** ** SQLITE_RBU_STATE_DONE: -** The RBU operation has finished. Any subsequent calls to tdsqlite3rbu_step() +** The RBU operation has finished. Any subsequent calls to sqlite3rbu_step() ** will immediately return SQLITE_DONE. ** ** SQLITE_RBU_STATE_ERROR: -** An error has occurred. Any subsequent calls to tdsqlite3rbu_step() will +** An error has occurred. Any subsequent calls to sqlite3rbu_step() will ** immediately return the SQLite error code associated with the error. */ #define SQLITE_RBU_STATE_OAL 1 @@ -197467,7 +197467,7 @@ SQLITE_API void tdsqlite3rbu_bp_progress(tdsqlite3rbu *pRbu, int *pnOne, int*pnT #define SQLITE_RBU_STATE_DONE 4 #define SQLITE_RBU_STATE_ERROR 5 -SQLITE_API int tdsqlite3rbu_state(tdsqlite3rbu *pRbu); +SQLITE_API int sqlite3rbu_state(sqlite3rbu *pRbu); /* ** Create an RBU VFS named zName that accesses the underlying file-system @@ -197488,19 +197488,19 @@ SQLITE_API int tdsqlite3rbu_state(tdsqlite3rbu *pRbu); ** multiplexor (error checking omitted): ** ** // Create a VFS named "multiplex" (not the default). -** tdsqlite3_multiplex_initialize(0, 0); +** sqlite3_multiplex_initialize(0, 0); ** ** // Create an rbu VFS named "rbu" that uses multiplexor. If the ** // second argument were replaced with NULL, the "rbu" VFS would ** // access the file-system via the system default VFS, bypassing the ** // multiplexor. -** tdsqlite3rbu_create_vfs("rbu", "multiplex"); +** sqlite3rbu_create_vfs("rbu", "multiplex"); ** ** // Create a zipvfs VFS named "zipvfs" that uses rbu. ** zipvfs_create_vfs_v3("zipvfs", "rbu", 0, xCompressorAlgorithmDetector); ** ** // Make zipvfs the default VFS. -** tdsqlite3_vfs_register(tdsqlite3_vfs_find("zipvfs"), 1); +** sqlite3_vfs_register(sqlite3_vfs_find("zipvfs"), 1); ** ** Because the default VFS created above includes a RBU functionality, it ** may be used by RBU clients. Attempting to use RBU with a zipvfs VFS stack @@ -197511,17 +197511,17 @@ SQLITE_API int tdsqlite3rbu_state(tdsqlite3rbu *pRbu); ** file-system via "rbu" all the time, even if it only uses RBU functionality ** occasionally. */ -SQLITE_API int tdsqlite3rbu_create_vfs(const char *zName, const char *zParent); +SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent); /* ** Deregister and destroy an RBU vfs created by an earlier call to -** tdsqlite3rbu_create_vfs(). +** sqlite3rbu_create_vfs(). ** ** VFS objects are not reference counted. If a VFS object is destroyed ** before all database handles that use it have been closed, the results ** are undefined. */ -SQLITE_API void tdsqlite3rbu_destroy_vfs(const char *zName); +SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName); #if 0 } /* end of the 'extern "C"' block */ @@ -197529,8 +197529,8 @@ SQLITE_API void tdsqlite3rbu_destroy_vfs(const char *zName); #endif /* _SQLITE3RBU_H */ -/************** End of tdsqlite3rbu.h ******************************************/ -/************** Continuing where we left off in tdsqlite3rbu.c *****************/ +/************** End of sqlite3rbu.h ******************************************/ +/************** Continuing where we left off in sqlite3rbu.c *****************/ #if defined(_WIN32_WCE) /* #include "windows.h" */ @@ -197580,7 +197580,7 @@ SQLITE_API void tdsqlite3rbu_destroy_vfs(const char *zName); ** table/index. ** ** RBU_STATE_PROGRESS: -** Trbul number of tdsqlite3rbu_step() calls made so far as part of this +** Trbul number of sqlite3rbu_step() calls made so far as part of this ** rbu update. ** ** RBU_STATE_CKPT: @@ -197634,7 +197634,7 @@ typedef struct RbuUpdateStmt RbuUpdateStmt; typedef unsigned int u32; typedef unsigned short u16; typedef unsigned char u8; -typedef tdsqlite3_int64 i64; +typedef sqlite3_int64 i64; #endif /* @@ -197666,7 +197666,7 @@ struct RbuState { struct RbuUpdateStmt { char *zMask; /* Copy of update mask used with pUpdate */ - tdsqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ + sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ RbuUpdateStmt *pNext; }; @@ -197697,8 +197697,8 @@ struct RbuSpan { ** */ struct RbuObjIter { - tdsqlite3_stmt *pTblIter; /* Iterate through tables */ - tdsqlite3_stmt *pIdxIter; /* Index iterator */ + sqlite3_stmt *pTblIter; /* Iterate through tables */ + sqlite3_stmt *pIdxIter; /* Index iterator */ int nTblCol; /* Size of azTblCol[] array */ char **azTblCol; /* Array of unquoted target column names */ char **azTblType; /* Array of target column types */ @@ -197720,10 +197720,10 @@ struct RbuObjIter { /* Statements created by rbuObjIterPrepareAll() */ int nCol; /* Number of columns in current object */ - tdsqlite3_stmt *pSelect; /* Source data */ - tdsqlite3_stmt *pInsert; /* Statement for INSERT operations */ - tdsqlite3_stmt *pDelete; /* Statement for DELETE ops */ - tdsqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */ + sqlite3_stmt *pSelect; /* Source data */ + sqlite3_stmt *pInsert; /* Statement for INSERT operations */ + sqlite3_stmt *pDelete; /* Statement for DELETE ops */ + sqlite3_stmt *pTmpInsert; /* Insert into rbu_tmp_$zDataTbl */ int nIdxCol; RbuSpan *aIdxCol; char *zIdxSql; @@ -197751,7 +197751,7 @@ struct RbuObjIter { /* -** Within the RBU_STAGE_OAL stage, each call to tdsqlite3rbu_step() performs +** Within the RBU_STAGE_OAL stage, each call to sqlite3rbu_step() performs ** one of the following operations. */ #define RBU_INSERT 1 /* Insert on a main table b-tree */ @@ -197777,7 +197777,7 @@ struct RbuFrame { ** nPhaseOneStep: ** If the RBU database contains an rbu_count table, this value is set to ** a running estimate of the number of b-tree operations required to -** finish populating the *-oal file. This allows the tdsqlite3_bp_progress() +** finish populating the *-oal file. This allows the sqlite3_bp_progress() ** API to calculate the permyriadage progress of populating the *-oal file ** using the formula: ** @@ -197811,10 +197811,10 @@ struct RbuFrame { ** first pass of each source table. The updated nPhaseOneStep value is ** stored in the rbu_state table if the RBU update is suspended. */ -struct tdsqlite3rbu { +struct sqlite3rbu { int eStage; /* Value of RBU_STATE_STAGE field */ - tdsqlite3 *dbMain; /* target database handle */ - tdsqlite3 *dbRbu; /* rbu database handle */ + sqlite3 *dbMain; /* target database handle */ + sqlite3 *dbRbu; /* rbu database handle */ char *zTarget; /* Path to target db */ char *zRbu; /* Path to rbu db */ char *zState; /* Path to state db (or NULL if zRbu) */ @@ -197854,14 +197854,14 @@ struct tdsqlite3rbu { ** ** Variable pRbu is only non-NULL for automatically created RBU VFS objects. ** It is NULL for RBU VFS objects created explicitly using -** tdsqlite3rbu_create_vfs(). It is used to track the total amount of temp +** sqlite3rbu_create_vfs(). It is used to track the total amount of temp ** space used by the RBU handle. */ struct rbu_vfs { - tdsqlite3_vfs base; /* rbu VFS shim methods */ - tdsqlite3_vfs *pRealVfs; /* Underlying VFS */ - tdsqlite3_mutex *mutex; /* Mutex to protect pMain */ - tdsqlite3rbu *pRbu; /* Owner RBU object */ + sqlite3_vfs base; /* rbu VFS shim methods */ + sqlite3_vfs *pRealVfs; /* Underlying VFS */ + sqlite3_mutex *mutex; /* Mutex to protect pMain */ + sqlite3rbu *pRbu; /* Owner RBU object */ rbu_file *pMain; /* List of main db files */ rbu_file *pMainRbu; /* List of main db files with pRbu!=0 */ }; @@ -197874,10 +197874,10 @@ struct rbu_vfs { ** "sz" is set to the current size of the database file. */ struct rbu_file { - tdsqlite3_file base; /* tdsqlite3_file methods */ - tdsqlite3_file *pReal; /* Underlying file handle */ + sqlite3_file base; /* sqlite3_file methods */ + sqlite3_file *pReal; /* Underlying file handle */ rbu_vfs *pRbuVfs; /* Pointer to the rbu_vfs object */ - tdsqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ + sqlite3rbu *pRbu; /* Pointer to rbu object (rbu target only) */ i64 sz; /* Size of file in bytes (temp only) */ int openFlags; /* Flags this file was opened with */ @@ -198108,9 +198108,9 @@ static int rbuDeltaOutputSize(const char *zDelta, int lenDelta){ ** function returns the patched blob. */ static void rbuFossilDeltaFunc( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ const char *aDelta; int nDelta; @@ -198123,28 +198123,28 @@ static void rbuFossilDeltaFunc( assert( argc==2 ); - nOrig = tdsqlite3_value_bytes(argv[0]); - aOrig = (const char*)tdsqlite3_value_blob(argv[0]); - nDelta = tdsqlite3_value_bytes(argv[1]); - aDelta = (const char*)tdsqlite3_value_blob(argv[1]); + nOrig = sqlite3_value_bytes(argv[0]); + aOrig = (const char*)sqlite3_value_blob(argv[0]); + nDelta = sqlite3_value_bytes(argv[1]); + aDelta = (const char*)sqlite3_value_blob(argv[1]); /* Figure out the size of the output */ nOut = rbuDeltaOutputSize(aDelta, nDelta); if( nOut<0 ){ - tdsqlite3_result_error(context, "corrupt fossil delta", -1); + sqlite3_result_error(context, "corrupt fossil delta", -1); return; } - aOut = tdsqlite3_malloc(nOut+1); + aOut = sqlite3_malloc(nOut+1); if( aOut==0 ){ - tdsqlite3_result_error_nomem(context); + sqlite3_result_error_nomem(context); }else{ nOut2 = rbuDeltaApply(aOrig, nOrig, aDelta, nDelta, aOut); if( nOut2!=nOut ){ - tdsqlite3_free(aOut); - tdsqlite3_result_error(context, "corrupt fossil delta", -1); + sqlite3_free(aOut); + sqlite3_result_error(context, "corrupt fossil delta", -1); }else{ - tdsqlite3_result_blob(context, aOut, nOut, tdsqlite3_free); + sqlite3_result_blob(context, aOut, nOut, sqlite3_free); } } } @@ -198158,17 +198158,17 @@ static void rbuFossilDeltaFunc( ** Otherwise, if an error does occur, set *ppStmt to NULL and return ** an SQLite error code. Additionally, set output variable *pzErrmsg to ** point to a buffer containing an error message. It is the responsibility -** of the caller to (eventually) free this buffer using tdsqlite3_free(). +** of the caller to (eventually) free this buffer using sqlite3_free(). */ static int prepareAndCollectError( - tdsqlite3 *db, - tdsqlite3_stmt **ppStmt, + sqlite3 *db, + sqlite3_stmt **ppStmt, char **pzErrmsg, const char *zSql ){ - int rc = tdsqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); + int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0); if( rc!=SQLITE_OK ){ - *pzErrmsg = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); + *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); *ppStmt = 0; } return rc; @@ -198176,23 +198176,23 @@ static int prepareAndCollectError( /* ** Reset the SQL statement passed as the first argument. Return a copy -** of the value returned by tdsqlite3_reset(). +** of the value returned by sqlite3_reset(). ** ** If an error has occurred, then set *pzErrmsg to point to a buffer ** containing an error message. It is the responsibility of the caller -** to eventually free this buffer using tdsqlite3_free(). +** to eventually free this buffer using sqlite3_free(). */ -static int resetAndCollectError(tdsqlite3_stmt *pStmt, char **pzErrmsg){ - int rc = tdsqlite3_reset(pStmt); +static int resetAndCollectError(sqlite3_stmt *pStmt, char **pzErrmsg){ + int rc = sqlite3_reset(pStmt); if( rc!=SQLITE_OK ){ - *pzErrmsg = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(tdsqlite3_db_handle(pStmt))); + *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(sqlite3_db_handle(pStmt))); } return rc; } /* ** Unless it is NULL, argument zSql points to a buffer allocated using -** tdsqlite3_malloc containing an SQL statement. This function prepares the SQL +** sqlite3_malloc containing an SQL statement. This function prepares the SQL ** statement against database db and frees the buffer. If statement ** compilation is successful, *ppStmt is set to point to the new statement ** handle and SQLITE_OK is returned. @@ -198200,14 +198200,14 @@ static int resetAndCollectError(tdsqlite3_stmt *pStmt, char **pzErrmsg){ ** Otherwise, if an error occurs, *ppStmt is set to NULL and an error code ** returned. In this case, *pzErrmsg may also be set to point to an error ** message. It is the responsibility of the caller to free this error message -** buffer using tdsqlite3_free(). +** buffer using sqlite3_free(). ** ** If argument zSql is NULL, this function assumes that an OOM has occurred. ** In this case SQLITE_NOMEM is returned and *ppStmt set to NULL. */ static int prepareFreeAndCollectError( - tdsqlite3 *db, - tdsqlite3_stmt **ppStmt, + sqlite3 *db, + sqlite3_stmt **ppStmt, char **pzErrmsg, char *zSql ){ @@ -198218,7 +198218,7 @@ static int prepareFreeAndCollectError( *ppStmt = 0; }else{ rc = prepareAndCollectError(db, ppStmt, pzErrmsg, zSql); - tdsqlite3_free(zSql); + sqlite3_free(zSql); } return rc; } @@ -198230,10 +198230,10 @@ static int prepareFreeAndCollectError( static void rbuObjIterFreeCols(RbuObjIter *pIter){ int i; for(i=0; inTblCol; i++){ - tdsqlite3_free(pIter->azTblCol[i]); - tdsqlite3_free(pIter->azTblType[i]); + sqlite3_free(pIter->azTblCol[i]); + sqlite3_free(pIter->azTblType[i]); } - tdsqlite3_free(pIter->azTblCol); + sqlite3_free(pIter->azTblCol); pIter->azTblCol = 0; pIter->azTblType = 0; pIter->aiSrcOrder = 0; @@ -198250,19 +198250,19 @@ static void rbuObjIterFreeCols(RbuObjIter *pIter){ static void rbuObjIterClearStatements(RbuObjIter *pIter){ RbuUpdateStmt *pUp; - tdsqlite3_finalize(pIter->pSelect); - tdsqlite3_finalize(pIter->pInsert); - tdsqlite3_finalize(pIter->pDelete); - tdsqlite3_finalize(pIter->pTmpInsert); + sqlite3_finalize(pIter->pSelect); + sqlite3_finalize(pIter->pInsert); + sqlite3_finalize(pIter->pDelete); + sqlite3_finalize(pIter->pTmpInsert); pUp = pIter->pRbuUpdate; while( pUp ){ RbuUpdateStmt *pTmp = pUp->pNext; - tdsqlite3_finalize(pUp->pUpdate); - tdsqlite3_free(pUp); + sqlite3_finalize(pUp->pUpdate); + sqlite3_free(pUp); pUp = pTmp; } - tdsqlite3_free(pIter->aIdxCol); - tdsqlite3_free(pIter->zIdxSql); + sqlite3_free(pIter->aIdxCol); + sqlite3_free(pIter->zIdxSql); pIter->pSelect = 0; pIter->pInsert = 0; @@ -198281,8 +198281,8 @@ static void rbuObjIterClearStatements(RbuObjIter *pIter){ */ static void rbuObjIterFinalize(RbuObjIter *pIter){ rbuObjIterClearStatements(pIter); - tdsqlite3_finalize(pIter->pTblIter); - tdsqlite3_finalize(pIter->pIdxIter); + sqlite3_finalize(pIter->pTblIter); + sqlite3_finalize(pIter->pIdxIter); rbuObjIterFreeCols(pIter); memset(pIter, 0, sizeof(RbuObjIter)); } @@ -198295,14 +198295,14 @@ static void rbuObjIterFinalize(RbuObjIter *pIter){ ** left in the RBU handle passed as the first argument. A copy of the ** error code is returned. */ -static int rbuObjIterNext(tdsqlite3rbu *p, RbuObjIter *pIter){ +static int rbuObjIterNext(sqlite3rbu *p, RbuObjIter *pIter){ int rc = p->rc; if( rc==SQLITE_OK ){ /* Free any SQLite statements used while processing the previous object */ rbuObjIterClearStatements(pIter); if( pIter->zIdx==0 ){ - rc = tdsqlite3_exec(p->dbMain, + rc = sqlite3_exec(p->dbMain, "DROP TRIGGER IF EXISTS temp.rbu_insert_tr;" "DROP TRIGGER IF EXISTS temp.rbu_update1_tr;" "DROP TRIGGER IF EXISTS temp.rbu_update2_tr;" @@ -198315,30 +198315,30 @@ static int rbuObjIterNext(tdsqlite3rbu *p, RbuObjIter *pIter){ if( pIter->bCleanup ){ rbuObjIterFreeCols(pIter); pIter->bCleanup = 0; - rc = tdsqlite3_step(pIter->pTblIter); + rc = sqlite3_step(pIter->pTblIter); if( rc!=SQLITE_ROW ){ rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg); pIter->zTbl = 0; }else{ - pIter->zTbl = (const char*)tdsqlite3_column_text(pIter->pTblIter, 0); - pIter->zDataTbl = (const char*)tdsqlite3_column_text(pIter->pTblIter,1); + pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0); + pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1); rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM; } }else{ if( pIter->zIdx==0 ){ - tdsqlite3_stmt *pIdx = pIter->pIdxIter; - rc = tdsqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC); + sqlite3_stmt *pIdx = pIter->pIdxIter; + rc = sqlite3_bind_text(pIdx, 1, pIter->zTbl, -1, SQLITE_STATIC); } if( rc==SQLITE_OK ){ - rc = tdsqlite3_step(pIter->pIdxIter); + rc = sqlite3_step(pIter->pIdxIter); if( rc!=SQLITE_ROW ){ rc = resetAndCollectError(pIter->pIdxIter, &p->zErrmsg); pIter->bCleanup = 1; pIter->zIdx = 0; }else{ - pIter->zIdx = (const char*)tdsqlite3_column_text(pIter->pIdxIter, 0); - pIter->iTnum = tdsqlite3_column_int(pIter->pIdxIter, 1); - pIter->bUnique = tdsqlite3_column_int(pIter->pIdxIter, 2); + pIter->zIdx = (const char*)sqlite3_column_text(pIter->pIdxIter, 0); + pIter->iTnum = sqlite3_column_int(pIter->pIdxIter, 1); + pIter->bUnique = sqlite3_column_int(pIter->pIdxIter, 2); rc = pIter->zIdx ? SQLITE_OK : SQLITE_NOMEM; } } @@ -198376,27 +198376,27 @@ static int rbuObjIterNext(tdsqlite3rbu *p, RbuObjIter *pIter){ ** the second argument is either missing or 0 (not a view). */ static void rbuTargetNameFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ - tdsqlite3rbu *p = tdsqlite3_user_data(pCtx); + sqlite3rbu *p = sqlite3_user_data(pCtx); const char *zIn; assert( argc==1 || argc==2 ); - zIn = (const char*)tdsqlite3_value_text(argv[0]); + zIn = (const char*)sqlite3_value_text(argv[0]); if( zIn ){ if( rbuIsVacuum(p) ){ assert( argc==2 || argc==1 ); - if( argc==1 || 0==tdsqlite3_value_int(argv[1]) ){ - tdsqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); + if( argc==1 || 0==sqlite3_value_int(argv[1]) ){ + sqlite3_result_text(pCtx, zIn, -1, SQLITE_STATIC); } }else{ if( strlen(zIn)>4 && memcmp("data", zIn, 4)==0 ){ int i; for(i=4; zIn[i]>='0' && zIn[i]<='9'; i++); if( zIn[i]=='_' && zIn[i+1] ){ - tdsqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC); + sqlite3_result_text(pCtx, &zIn[i+1], -1, SQLITE_STATIC); } } } @@ -198411,12 +198411,12 @@ static void rbuTargetNameFunc( ** left in the RBU handle passed as the first argument. A copy of the ** error code is returned. */ -static int rbuObjIterFirst(tdsqlite3rbu *p, RbuObjIter *pIter){ +static int rbuObjIterFirst(sqlite3rbu *p, RbuObjIter *pIter){ int rc; memset(pIter, 0, sizeof(RbuObjIter)); rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pTblIter, &p->zErrmsg, - tdsqlite3_mprintf( + sqlite3_mprintf( "SELECT rbu_target_name(name, type='view') AS target, name " "FROM sqlite_master " "WHERE type IN ('table', 'view') AND target IS NOT NULL " @@ -198438,23 +198438,23 @@ static int rbuObjIterFirst(tdsqlite3rbu *p, RbuObjIter *pIter){ } /* -** This is a wrapper around "tdsqlite3_mprintf(zFmt, ...)". If an OOM occurs, +** This is a wrapper around "sqlite3_mprintf(zFmt, ...)". If an OOM occurs, ** an error code is stored in the RBU handle passed as the first argument. ** ** If an error has already occurred (p->rc is already set to something other ** than SQLITE_OK), then this function returns NULL without modifying the -** stored error code. In this case it still calls tdsqlite3_free() on any +** stored error code. In this case it still calls sqlite3_free() on any ** printf() parameters associated with %z conversions. */ -static char *rbuMPrintf(tdsqlite3rbu *p, const char *zFmt, ...){ +static char *rbuMPrintf(sqlite3rbu *p, const char *zFmt, ...){ char *zSql = 0; va_list ap; va_start(ap, zFmt); - zSql = tdsqlite3_vmprintf(zFmt, ap); + zSql = sqlite3_vmprintf(zFmt, ap); if( p->rc==SQLITE_OK ){ if( zSql==0 ) p->rc = SQLITE_NOMEM; }else{ - tdsqlite3_free(zSql); + sqlite3_free(zSql); zSql = 0; } va_end(ap); @@ -198462,7 +198462,7 @@ static char *rbuMPrintf(tdsqlite3rbu *p, const char *zFmt, ...){ } /* -** Argument zFmt is a tdsqlite3_mprintf() style format string. The trailing +** Argument zFmt is a sqlite3_mprintf() style format string. The trailing ** arguments are the usual subsitution values. This function performs ** the printf() style substitutions and executes the result as an SQL ** statement on the RBU handles database. @@ -198471,19 +198471,19 @@ static char *rbuMPrintf(tdsqlite3rbu *p, const char *zFmt, ...){ ** RBU handle. If an error has already occurred when this function is ** called, it is a no-op. */ -static int rbuMPrintfExec(tdsqlite3rbu *p, tdsqlite3 *db, const char *zFmt, ...){ +static int rbuMPrintfExec(sqlite3rbu *p, sqlite3 *db, const char *zFmt, ...){ va_list ap; char *zSql; va_start(ap, zFmt); - zSql = tdsqlite3_vmprintf(zFmt, ap); + zSql = sqlite3_vmprintf(zFmt, ap); if( p->rc==SQLITE_OK ){ if( zSql==0 ){ p->rc = SQLITE_NOMEM; }else{ - p->rc = tdsqlite3_exec(db, zSql, 0, 0, &p->zErrmsg); + p->rc = sqlite3_exec(db, zSql, 0, 0, &p->zErrmsg); } } - tdsqlite3_free(zSql); + sqlite3_free(zSql); va_end(ap); return p->rc; } @@ -198498,11 +198498,11 @@ static int rbuMPrintfExec(tdsqlite3rbu *p, tdsqlite3 *db, const char *zFmt, ...) ** immediately without attempting the allocation or modifying the stored ** error code. */ -static void *rbuMalloc(tdsqlite3rbu *p, tdsqlite3_int64 nByte){ +static void *rbuMalloc(sqlite3rbu *p, sqlite3_int64 nByte){ void *pRet = 0; if( p->rc==SQLITE_OK ){ assert( nByte>0 ); - pRet = tdsqlite3_malloc64(nByte); + pRet = sqlite3_malloc64(nByte); if( pRet==0 ){ p->rc = SQLITE_NOMEM; }else{ @@ -198518,8 +198518,8 @@ static void *rbuMalloc(tdsqlite3rbu *p, tdsqlite3_int64 nByte){ ** there is room for at least nCol elements. If an OOM occurs, store an ** error code in the RBU handle passed as the first argument. */ -static void rbuAllocateIterArrays(tdsqlite3rbu *p, RbuObjIter *pIter, int nCol){ - tdsqlite3_int64 nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol; +static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){ + sqlite3_int64 nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol; char **azNew; azNew = (char**)rbuMalloc(p, nByte); @@ -198535,9 +198535,9 @@ static void rbuAllocateIterArrays(tdsqlite3rbu *p, RbuObjIter *pIter, int nCol){ /* ** The first argument must be a nul-terminated string. This function -** returns a copy of the string in memory obtained from tdsqlite3_malloc(). +** returns a copy of the string in memory obtained from sqlite3_malloc(). ** It is the responsibility of the caller to eventually free this memory -** using tdsqlite3_free(). +** using sqlite3_free(). ** ** If an OOM condition is encountered when attempting to allocate memory, ** output variable (*pRc) is set to SQLITE_NOMEM before returning. Otherwise, @@ -198549,7 +198549,7 @@ static char *rbuStrndup(const char *zStr, int *pRc){ if( *pRc==SQLITE_OK ){ if( zStr ){ size_t nCopy = strlen(zStr) + 1; - zRet = (char*)tdsqlite3_malloc64(nCopy); + zRet = (char*)sqlite3_malloc64(nCopy); if( zRet ){ memcpy(zRet, zStr, nCopy); }else{ @@ -198564,16 +198564,16 @@ static char *rbuStrndup(const char *zStr, int *pRc){ /* ** Finalize the statement passed as the second argument. ** -** If the tdsqlite3_finalize() call indicates that an error occurs, and the +** If the sqlite3_finalize() call indicates that an error occurs, and the ** rbu handle error code is not already set, set the error code and error ** message accordingly. */ -static void rbuFinalize(tdsqlite3rbu *p, tdsqlite3_stmt *pStmt){ - tdsqlite3 *db = tdsqlite3_db_handle(pStmt); - int rc = tdsqlite3_finalize(pStmt); +static void rbuFinalize(sqlite3rbu *p, sqlite3_stmt *pStmt){ + sqlite3 *db = sqlite3_db_handle(pStmt); + int rc = sqlite3_finalize(pStmt); if( p->rc==SQLITE_OK && rc!=SQLITE_OK ){ p->rc = rc; - p->zErrmsg = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); + p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); } } @@ -198617,7 +198617,7 @@ static void rbuFinalize(tdsqlite3rbu *p, tdsqlite3_stmt *pStmt){ ** } */ static void rbuTableType( - tdsqlite3rbu *p, + sqlite3rbu *p, const char *zTab, int *peType, int *piTnum, @@ -198629,43 +198629,43 @@ static void rbuTableType( ** 2) SELECT count(*) FROM sqlite_master where name=%Q ** 3) PRAGMA table_info = ? */ - tdsqlite3_stmt *aStmt[4] = {0, 0, 0, 0}; + sqlite3_stmt *aStmt[4] = {0, 0, 0, 0}; *peType = RBU_PK_NOTABLE; *piPk = 0; assert( p->rc==SQLITE_OK ); p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[0], &p->zErrmsg, - tdsqlite3_mprintf( + sqlite3_mprintf( "SELECT (sql LIKE 'create virtual%%'), rootpage" " FROM sqlite_master" " WHERE name=%Q", zTab )); - if( p->rc!=SQLITE_OK || tdsqlite3_step(aStmt[0])!=SQLITE_ROW ){ + if( p->rc!=SQLITE_OK || sqlite3_step(aStmt[0])!=SQLITE_ROW ){ /* Either an error, or no such table. */ goto rbuTableType_end; } - if( tdsqlite3_column_int(aStmt[0], 0) ){ + if( sqlite3_column_int(aStmt[0], 0) ){ *peType = RBU_PK_VTAB; /* virtual table */ goto rbuTableType_end; } - *piTnum = tdsqlite3_column_int(aStmt[0], 1); + *piTnum = sqlite3_column_int(aStmt[0], 1); p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[1], &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA index_list=%Q",zTab) + sqlite3_mprintf("PRAGMA index_list=%Q",zTab) ); if( p->rc ) goto rbuTableType_end; - while( tdsqlite3_step(aStmt[1])==SQLITE_ROW ){ - const u8 *zOrig = tdsqlite3_column_text(aStmt[1], 3); - const u8 *zIdx = tdsqlite3_column_text(aStmt[1], 1); + while( sqlite3_step(aStmt[1])==SQLITE_ROW ){ + const u8 *zOrig = sqlite3_column_text(aStmt[1], 3); + const u8 *zIdx = sqlite3_column_text(aStmt[1], 1); if( zOrig && zIdx && zOrig[0]=='p' ){ p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[2], &p->zErrmsg, - tdsqlite3_mprintf( + sqlite3_mprintf( "SELECT rootpage FROM sqlite_master WHERE name = %Q", zIdx )); if( p->rc==SQLITE_OK ){ - if( tdsqlite3_step(aStmt[2])==SQLITE_ROW ){ - *piPk = tdsqlite3_column_int(aStmt[2], 0); + if( sqlite3_step(aStmt[2])==SQLITE_ROW ){ + *piPk = sqlite3_column_int(aStmt[2], 0); *peType = RBU_PK_EXTERNAL; }else{ *peType = RBU_PK_WITHOUT_ROWID; @@ -198676,11 +198676,11 @@ static void rbuTableType( } p->rc = prepareFreeAndCollectError(p->dbMain, &aStmt[3], &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA table_info=%Q",zTab) + sqlite3_mprintf("PRAGMA table_info=%Q",zTab) ); if( p->rc==SQLITE_OK ){ - while( tdsqlite3_step(aStmt[3])==SQLITE_ROW ){ - if( tdsqlite3_column_int(aStmt[3],5)>0 ){ + while( sqlite3_step(aStmt[3])==SQLITE_ROW ){ + if( sqlite3_column_int(aStmt[3],5)>0 ){ *peType = RBU_PK_IPK; /* explicit IPK column */ goto rbuTableType_end; } @@ -198700,31 +198700,31 @@ rbuTableType_end: { ** This is a helper function for rbuObjIterCacheTableInfo(). It populates ** the pIter->abIndexed[] array. */ -static void rbuObjIterCacheIndexedCols(tdsqlite3rbu *p, RbuObjIter *pIter){ - tdsqlite3_stmt *pList = 0; +static void rbuObjIterCacheIndexedCols(sqlite3rbu *p, RbuObjIter *pIter){ + sqlite3_stmt *pList = 0; int bIndex = 0; if( p->rc==SQLITE_OK ){ memcpy(pIter->abIndexed, pIter->abTblPk, sizeof(u8)*pIter->nTblCol); p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) + sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) ); } pIter->nIndex = 0; - while( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pList) ){ - const char *zIdx = (const char*)tdsqlite3_column_text(pList, 1); - int bPartial = tdsqlite3_column_int(pList, 4); - tdsqlite3_stmt *pXInfo = 0; + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ + const char *zIdx = (const char*)sqlite3_column_text(pList, 1); + int bPartial = sqlite3_column_int(pList, 4); + sqlite3_stmt *pXInfo = 0; if( zIdx==0 ) break; if( bPartial ){ memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol); } p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); - while( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pXInfo) ){ - int iCid = tdsqlite3_column_int(pXInfo, 1); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); if( iCid>=0 ) pIter->abIndexed[iCid] = 1; if( iCid==-2 ){ memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol); @@ -198754,9 +198754,9 @@ static void rbuObjIterCacheIndexedCols(tdsqlite3rbu *p, RbuObjIter *pIter){ ** an error does occur, an error code and error message are also left in ** the RBU handle. */ -static int rbuObjIterCacheTableInfo(tdsqlite3rbu *p, RbuObjIter *pIter){ +static int rbuObjIterCacheTableInfo(sqlite3rbu *p, RbuObjIter *pIter){ if( pIter->azTblCol==0 ){ - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; int nCol = 0; int i; /* for() loop iterator variable */ int bRbuRowid = 0; /* If input table has column "rbu_rowid" */ @@ -198768,7 +198768,7 @@ static int rbuObjIterCacheTableInfo(tdsqlite3rbu *p, RbuObjIter *pIter){ rbuTableType(p, pIter->zTbl, &pIter->eType, &iTnum, &pIter->iPkTnum); if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_NOTABLE ){ p->rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf("no such table: %s", pIter->zTbl); + p->zErrmsg = sqlite3_mprintf("no such table: %s", pIter->zTbl); } if( p->rc ) return p->rc; if( pIter->zIdx==0 ) pIter->iTnum = iTnum; @@ -198782,24 +198782,24 @@ static int rbuObjIterCacheTableInfo(tdsqlite3rbu *p, RbuObjIter *pIter){ ** of the input table. Ignore any input table columns that begin with ** "rbu_". */ p->rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, - tdsqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl) + sqlite3_mprintf("SELECT * FROM '%q'", pIter->zDataTbl) ); if( p->rc==SQLITE_OK ){ - nCol = tdsqlite3_column_count(pStmt); + nCol = sqlite3_column_count(pStmt); rbuAllocateIterArrays(p, pIter, nCol); } for(i=0; p->rc==SQLITE_OK && irc); pIter->aiSrcOrder[pIter->nTblCol] = pIter->nTblCol; pIter->azTblCol[pIter->nTblCol++] = zCopy; } - else if( 0==tdsqlite3_stricmp("rbu_rowid", zName) ){ + else if( 0==sqlite3_stricmp("rbu_rowid", zName) ){ bRbuRowid = 1; } } - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); pStmt = 0; if( p->rc==SQLITE_OK @@ -198807,7 +198807,7 @@ static int rbuObjIterCacheTableInfo(tdsqlite3rbu *p, RbuObjIter *pIter){ && bRbuRowid!=(pIter->eType==RBU_PK_VTAB || pIter->eType==RBU_PK_NONE) ){ p->rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf( + p->zErrmsg = sqlite3_mprintf( "table %q %s rbu_rowid column", pIter->zDataTbl, (bRbuRowid ? "may not have" : "requires") ); @@ -198818,24 +198818,24 @@ static int rbuObjIterCacheTableInfo(tdsqlite3rbu *p, RbuObjIter *pIter){ ** aiTblOrder[] arrays at the same time. */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl) + sqlite3_mprintf("PRAGMA table_info(%Q)", pIter->zTbl) ); } - while( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pStmt) ){ - const char *zName = (const char*)tdsqlite3_column_text(pStmt, 1); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + const char *zName = (const char*)sqlite3_column_text(pStmt, 1); if( zName==0 ) break; /* An OOM - finalize() below returns S_NOMEM */ for(i=iOrder; inTblCol; i++){ if( 0==strcmp(zName, pIter->azTblCol[i]) ) break; } if( i==pIter->nTblCol ){ p->rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf("column missing from %q: %s", + p->zErrmsg = sqlite3_mprintf("column missing from %q: %s", pIter->zDataTbl, zName ); }else{ - int iPk = tdsqlite3_column_int(pStmt, 5); - int bNotNull = tdsqlite3_column_int(pStmt, 3); - const char *zType = (const char*)tdsqlite3_column_text(pStmt, 2); + int iPk = sqlite3_column_int(pStmt, 5); + int bNotNull = sqlite3_column_int(pStmt, 3); + const char *zType = (const char*)sqlite3_column_text(pStmt, 2); if( i!=iOrder ){ SWAP(int, pIter->aiSrcOrder[i], pIter->aiSrcOrder[iOrder]); @@ -198865,7 +198865,7 @@ static int rbuObjIterCacheTableInfo(tdsqlite3rbu *p, RbuObjIter *pIter){ ** column names currently stored in the pIter->azTblCol[] array. */ static char *rbuObjIterGetCollist( - tdsqlite3rbu *p, /* RBU object */ + sqlite3rbu *p, /* RBU object */ RbuObjIter *pIter /* Object iterator for column names */ ){ char *zList = 0; @@ -198886,7 +198886,7 @@ static char *rbuObjIterGetCollist( ** the separator text (usually ", "). */ static char *rbuObjIterGetPkList( - tdsqlite3rbu *p, /* RBU object */ + sqlite3rbu *p, /* RBU object */ RbuObjIter *pIter, /* Object iterator for column names */ const char *zPre, /* Before each quoted column name */ const char *zSeparator, /* Separator to use between columns */ @@ -198931,21 +198931,21 @@ static char *rbuObjIterGetPkList( ** this function contain literal SQL values. */ static char *rbuVacuumTableStart( - tdsqlite3rbu *p, /* RBU handle */ + sqlite3rbu *p, /* RBU handle */ RbuObjIter *pIter, /* RBU iterator object */ int bRowid, /* True for a rowid table */ const char *zWrite /* Target table name prefix */ ){ - tdsqlite3_stmt *pMax = 0; + sqlite3_stmt *pMax = 0; char *zRet = 0; if( bRowid ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, - tdsqlite3_mprintf( + sqlite3_mprintf( "SELECT max(_rowid_) FROM \"%s%w\"", zWrite, pIter->zTbl ) ); - if( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pMax) ){ - tdsqlite3_int64 iMax = tdsqlite3_column_int64(pMax, 0); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + sqlite3_int64 iMax = sqlite3_column_int64(pMax, 0); zRet = rbuMPrintf(p, " WHERE _rowid_ > %lld ", iMax); } rbuFinalize(p, pMax); @@ -198956,21 +198956,21 @@ static char *rbuVacuumTableStart( if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pMax, &p->zErrmsg, - tdsqlite3_mprintf( + sqlite3_mprintf( "SELECT %s FROM \"%s%w\" ORDER BY %s LIMIT 1", zSelect, zWrite, pIter->zTbl, zOrder ) ); - if( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pMax) ){ - const char *zVal = (const char*)tdsqlite3_column_text(pMax, 0); + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){ + const char *zVal = (const char*)sqlite3_column_text(pMax, 0); zRet = rbuMPrintf(p, " WHERE (%s) > (%s) ", zList, zVal); } rbuFinalize(p, pMax); } - tdsqlite3_free(zOrder); - tdsqlite3_free(zSelect); - tdsqlite3_free(zList); + sqlite3_free(zOrder); + sqlite3_free(zSelect); + sqlite3_free(zList); } return zRet; } @@ -198998,7 +198998,7 @@ static char *rbuVacuumTableStart( ** rows from the sourct table, just as it does for an RBU update operation. */ char *rbuVacuumIndexStart( - tdsqlite3rbu *p, /* RBU handle */ + sqlite3rbu *p, /* RBU handle */ RbuObjIter *pIter /* RBU iterator object */ ){ char *zOrder = 0; @@ -199009,16 +199009,16 @@ char *rbuVacuumIndexStart( int bFailed = 0; const char *zSep = ""; int iCol = 0; - tdsqlite3_stmt *pXInfo = 0; + sqlite3_stmt *pXInfo = 0; p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) ); - while( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pXInfo) ){ - int iCid = tdsqlite3_column_int(pXInfo, 1); - const char *zCollate = (const char*)tdsqlite3_column_text(pXInfo, 4); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); const char *zCol; - if( tdsqlite3_column_int(pXInfo, 3) ){ + if( sqlite3_column_int(pXInfo, 3) ){ bFailed = 1; break; } @@ -199052,17 +199052,17 @@ char *rbuVacuumIndexStart( if( bFailed ) goto index_start_out; if( p->rc==SQLITE_OK ){ - tdsqlite3_stmt *pSel = 0; + sqlite3_stmt *pSel = 0; p->rc = prepareFreeAndCollectError(p->dbMain, &pSel, &p->zErrmsg, - tdsqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1", + sqlite3_mprintf("SELECT %s FROM \"rbu_imp_%w\" ORDER BY %s LIMIT 1", zSelect, pIter->zTbl, zOrder ) ); - if( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pSel) ){ + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSel) ){ zSep = ""; for(iCol=0; iColnCol; iCol++){ - const char *zQuoted = (const char*)tdsqlite3_column_text(pSel, iCol); + const char *zQuoted = (const char*)sqlite3_column_text(pSel, iCol); if( zQuoted[0]=='N' ){ bFailed = 1; break; @@ -199079,10 +199079,10 @@ char *rbuVacuumIndexStart( } index_start_out: - tdsqlite3_free(zOrder); - tdsqlite3_free(zSelect); - tdsqlite3_free(zVector); - tdsqlite3_free(zLhs); + sqlite3_free(zOrder); + sqlite3_free(zSelect); + sqlite3_free(zVector); + sqlite3_free(zLhs); return zRet; } @@ -199111,7 +199111,7 @@ char *rbuVacuumIndexStart( ** pzWhere: ... */ static char *rbuObjIterGetIndexCols( - tdsqlite3rbu *p, /* RBU object */ + sqlite3rbu *p, /* RBU object */ RbuObjIter *pIter, /* Object iterator for column names */ char **pzImposterCols, /* OUT: Columns for imposter table */ char **pzImposterPk, /* OUT: Imposter PK clause */ @@ -199119,7 +199119,7 @@ static char *rbuObjIterGetIndexCols( int *pnBind /* OUT: Trbul number of columns */ ){ int rc = p->rc; /* Error code */ - int rc2; /* tdsqlite3_finalize() return code */ + int rc2; /* sqlite3_finalize() return code */ char *zRet = 0; /* String to return */ char *zImpCols = 0; /* String to return via *pzImposterCols */ char *zImpPK = 0; /* String to return via *pzImposterPK */ @@ -199127,25 +199127,25 @@ static char *rbuObjIterGetIndexCols( int nBind = 0; /* Value to return via *pnBind */ const char *zCom = ""; /* Set to ", " later on */ const char *zAnd = ""; /* Set to " AND " later on */ - tdsqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = ? */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = ? */ if( rc==SQLITE_OK ){ assert( p->zErrmsg==0 ); rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zIdx) ); } - while( rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pXInfo) ){ - int iCid = tdsqlite3_column_int(pXInfo, 1); - int bDesc = tdsqlite3_column_int(pXInfo, 3); - const char *zCollate = (const char*)tdsqlite3_column_text(pXInfo, 4); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int iCid = sqlite3_column_int(pXInfo, 1); + int bDesc = sqlite3_column_int(pXInfo, 3); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); const char *zCol = 0; const char *zType; if( iCid==-2 ){ - int iSeq = tdsqlite3_column_int(pXInfo, 0); - zRet = tdsqlite3_mprintf("%z%s(%.*s) COLLATE %Q", zRet, zCom, + int iSeq = sqlite3_column_int(pXInfo, 0); + zRet = sqlite3_mprintf("%z%s(%.*s) COLLATE %Q", zRet, zCom, pIter->aIdxCol[iSeq].nSpan, pIter->aIdxCol[iSeq].zSpan, zCollate ); zType = ""; @@ -199168,19 +199168,19 @@ static char *rbuObjIterGetIndexCols( zCol = pIter->azTblCol[iCid]; zType = pIter->azTblType[iCid]; } - zRet = tdsqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom,zCol,zCollate); + zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom,zCol,zCollate); } - if( pIter->bUnique==0 || tdsqlite3_column_int(pXInfo, 5) ){ + if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){ const char *zOrder = (bDesc ? " DESC" : ""); - zImpPK = tdsqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", + zImpPK = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\"%s", zImpPK, zCom, nBind, zCol, zOrder ); } - zImpCols = tdsqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", + zImpCols = sqlite3_mprintf("%z%s\"rbu_imp_%d%w\" %s COLLATE %Q", zImpCols, zCom, nBind, zCol, zType, zCollate ); - zWhere = tdsqlite3_mprintf( + zWhere = sqlite3_mprintf( "%z%s\"rbu_imp_%d%w\" IS ?", zWhere, zAnd, nBind, zCol ); if( zRet==0 || zImpPK==0 || zImpCols==0 || zWhere==0 ) rc = SQLITE_NOMEM; @@ -199189,14 +199189,14 @@ static char *rbuObjIterGetIndexCols( nBind++; } - rc2 = tdsqlite3_finalize(pXInfo); + rc2 = sqlite3_finalize(pXInfo); if( rc==SQLITE_OK ) rc = rc2; if( rc!=SQLITE_OK ){ - tdsqlite3_free(zRet); - tdsqlite3_free(zImpCols); - tdsqlite3_free(zImpPK); - tdsqlite3_free(zWhere); + sqlite3_free(zRet); + sqlite3_free(zImpCols); + sqlite3_free(zImpPK); + sqlite3_free(zWhere); zRet = 0; zImpCols = 0; zImpPK = 0; @@ -199223,7 +199223,7 @@ static char *rbuObjIterGetIndexCols( ** the text ", old._rowid_" to the returned value. */ static char *rbuObjIterGetOldlist( - tdsqlite3rbu *p, + sqlite3rbu *p, RbuObjIter *pIter, const char *zObj ){ @@ -199234,9 +199234,9 @@ static char *rbuObjIterGetOldlist( for(i=0; inTblCol; i++){ if( pIter->abIndexed[i] ){ const char *zCol = pIter->azTblCol[i]; - zList = tdsqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol); + zList = sqlite3_mprintf("%z%s%s.\"%w\"", zList, zS, zObj, zCol); }else{ - zList = tdsqlite3_mprintf("%z%sNULL", zList, zS); + zList = sqlite3_mprintf("%z%sNULL", zList, zS); } zS = ", "; if( zList==0 ){ @@ -199264,7 +199264,7 @@ static char *rbuObjIterGetOldlist( ** "b = ?1 AND c = ?2" */ static char *rbuObjIterGetWhere( - tdsqlite3rbu *p, + sqlite3rbu *p, RbuObjIter *pIter ){ char *zList = 0; @@ -199304,9 +199304,9 @@ static char *rbuObjIterGetWhere( ** stored in the (p->nCol+1)'th column. Set the error code and error message ** of the RBU handle to something reflecting this. */ -static void rbuBadControlError(tdsqlite3rbu *p){ +static void rbuBadControlError(sqlite3rbu *p){ p->rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf("invalid rbu_control value"); + p->zErrmsg = sqlite3_mprintf("invalid rbu_control value"); } @@ -199317,9 +199317,9 @@ static void rbuBadControlError(tdsqlite3rbu *p){ ** passed as the second argument currently points to if the rbu_control ** column of the data_xxx table entry is set to zMask. ** -** The memory for the returned string is obtained from tdsqlite3_malloc(). +** The memory for the returned string is obtained from sqlite3_malloc(). ** It is the responsibility of the caller to eventually free it using -** tdsqlite3_free(). +** sqlite3_free(). ** ** If an OOM error is encountered when allocating space for the new ** string, an error code is left in the rbu handle passed as the first @@ -199328,7 +199328,7 @@ static void rbuBadControlError(tdsqlite3rbu *p){ ** attempting the allocation or modifying the stored error code. */ static char *rbuObjIterGetSetlist( - tdsqlite3rbu *p, + sqlite3rbu *p, RbuObjIter *pIter, const char *zMask ){ @@ -199371,9 +199371,9 @@ static char *rbuObjIterGetSetlist( ** "?" expressions. For example, if nByte is 3, return a pointer to ** a buffer containing the string "?,?,?". ** -** The memory for the returned string is obtained from tdsqlite3_malloc(). +** The memory for the returned string is obtained from sqlite3_malloc(). ** It is the responsibility of the caller to eventually free it using -** tdsqlite3_free(). +** sqlite3_free(). ** ** If an OOM error is encountered when allocating space for the new ** string, an error code is left in the rbu handle passed as the first @@ -199381,9 +199381,9 @@ static char *rbuObjIterGetSetlist( ** when this function is called, NULL is returned immediately, without ** attempting the allocation or modifying the stored error code. */ -static char *rbuObjIterGetBindlist(tdsqlite3rbu *p, int nBind){ +static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){ char *zRet = 0; - tdsqlite3_int64 nByte = 2*(tdsqlite3_int64)nBind + 1; + sqlite3_int64 nByte = 2*(sqlite3_int64)nBind + 1; zRet = (char*)rbuMalloc(p, nByte); if( zRet ){ @@ -199408,24 +199408,24 @@ static char *rbuObjIterGetBindlist(tdsqlite3rbu *p, int nBind){ ** ** PRIMARY KEY("b", "a" DESC) */ -static char *rbuWithoutRowidPK(tdsqlite3rbu *p, RbuObjIter *pIter){ +static char *rbuWithoutRowidPK(sqlite3rbu *p, RbuObjIter *pIter){ char *z = 0; assert( pIter->zIdx==0 ); if( p->rc==SQLITE_OK ){ const char *zSep = "PRIMARY KEY("; - tdsqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */ - tdsqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = */ + sqlite3_stmt *pXList = 0; /* PRAGMA index_list = (pIter->zTbl) */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA index_xinfo = */ p->rc = prepareFreeAndCollectError(p->dbMain, &pXList, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) + sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) ); - while( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pXList) ){ - const char *zOrig = (const char*)tdsqlite3_column_text(pXList,3); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXList) ){ + const char *zOrig = (const char*)sqlite3_column_text(pXList,3); if( zOrig && strcmp(zOrig, "pk")==0 ){ - const char *zIdx = (const char*)tdsqlite3_column_text(pXList,1); + const char *zIdx = (const char*)sqlite3_column_text(pXList,1); if( zIdx ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); } break; @@ -199433,11 +199433,11 @@ static char *rbuWithoutRowidPK(tdsqlite3rbu *p, RbuObjIter *pIter){ } rbuFinalize(p, pXList); - while( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pXInfo) ){ - if( tdsqlite3_column_int(pXInfo, 5) ){ - /* int iCid = tdsqlite3_column_int(pXInfo, 0); */ - const char *zCol = (const char*)tdsqlite3_column_text(pXInfo, 2); - const char *zDesc = tdsqlite3_column_int(pXInfo, 3) ? " DESC" : ""; + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + if( sqlite3_column_int(pXInfo, 5) ){ + /* int iCid = sqlite3_column_int(pXInfo, 0); */ + const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2); + const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : ""; z = rbuMPrintf(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc); zSep = ", "; } @@ -199467,12 +199467,12 @@ static char *rbuWithoutRowidPK(tdsqlite3rbu *p, RbuObjIter *pIter){ ** CREATE TABLE rbu_imposter2(c1 TEXT, c2 REAL, id INTEGER) WITHOUT ROWID; ** */ -static void rbuCreateImposterTable2(tdsqlite3rbu *p, RbuObjIter *pIter){ +static void rbuCreateImposterTable2(sqlite3rbu *p, RbuObjIter *pIter){ if( p->rc==SQLITE_OK && pIter->eType==RBU_PK_EXTERNAL ){ int tnum = pIter->iPkTnum; /* Root page of PK index */ - tdsqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */ + sqlite3_stmt *pQuery = 0; /* SELECT name ... WHERE rootpage = $tnum */ const char *zIdx = 0; /* Name of PK index */ - tdsqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */ + sqlite3_stmt *pXInfo = 0; /* PRAGMA main.index_xinfo = $zIdx */ const char *zComma = ""; char *zCols = 0; /* Used to build up list of table cols */ char *zPk = 0; /* Used to build up table PK declaration */ @@ -199484,24 +199484,24 @@ static void rbuCreateImposterTable2(tdsqlite3rbu *p, RbuObjIter *pIter){ "SELECT name FROM sqlite_master WHERE rootpage = ?" ); if( p->rc==SQLITE_OK ){ - tdsqlite3_bind_int(pQuery, 1, tnum); - if( SQLITE_ROW==tdsqlite3_step(pQuery) ){ - zIdx = (const char*)tdsqlite3_column_text(pQuery, 0); + sqlite3_bind_int(pQuery, 1, tnum); + if( SQLITE_ROW==sqlite3_step(pQuery) ){ + zIdx = (const char*)sqlite3_column_text(pQuery, 0); } } if( zIdx ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) + sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx) ); } rbuFinalize(p, pQuery); - while( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pXInfo) ){ - int bKey = tdsqlite3_column_int(pXInfo, 5); + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){ + int bKey = sqlite3_column_int(pXInfo, 5); if( bKey ){ - int iCid = tdsqlite3_column_int(pXInfo, 1); - int bDesc = tdsqlite3_column_int(pXInfo, 3); - const char *zCollate = (const char*)tdsqlite3_column_text(pXInfo, 4); + int iCid = sqlite3_column_int(pXInfo, 1); + int bDesc = sqlite3_column_int(pXInfo, 3); + const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4); zCols = rbuMPrintf(p, "%z%sc%d %s COLLATE %Q", zCols, zComma, iCid, pIter->azTblType[iCid], zCollate ); @@ -199512,12 +199512,12 @@ static void rbuCreateImposterTable2(tdsqlite3rbu *p, RbuObjIter *pIter){ zCols = rbuMPrintf(p, "%z, id INTEGER", zCols); rbuFinalize(p, pXInfo); - tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); rbuMPrintfExec(p, p->dbMain, "CREATE TABLE rbu_imposter2(%z, PRIMARY KEY(%z)) WITHOUT ROWID", zCols, zPk ); - tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); } } @@ -199525,7 +199525,7 @@ static void rbuCreateImposterTable2(tdsqlite3rbu *p, RbuObjIter *pIter){ ** If an error has already occurred when this function is called, it ** immediately returns zero (without doing any work). Or, if an error ** occurs during the execution of this function, it sets the error code -** in the tdsqlite3rbu object indicated by the first argument and returns +** in the sqlite3rbu object indicated by the first argument and returns ** zero. ** ** The iterator passed as the second argument is guaranteed to point to @@ -199541,20 +199541,20 @@ static void rbuCreateImposterTable2(tdsqlite3rbu *p, RbuObjIter *pIter){ ** collation sequences. For tables that do not have an external PRIMARY ** KEY, it also means the same PRIMARY KEY declaration. */ -static void rbuCreateImposterTable(tdsqlite3rbu *p, RbuObjIter *pIter){ +static void rbuCreateImposterTable(sqlite3rbu *p, RbuObjIter *pIter){ if( p->rc==SQLITE_OK && pIter->eType!=RBU_PK_VTAB ){ int tnum = pIter->iTnum; const char *zComma = ""; char *zSql = 0; int iCol; - tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); for(iCol=0; p->rc==SQLITE_OK && iColnTblCol; iCol++){ const char *zPk = ""; const char *zCol = pIter->azTblCol[iCol]; const char *zColl = 0; - p->rc = tdsqlite3_table_column_metadata( + p->rc = sqlite3_table_column_metadata( p->dbMain, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0 ); @@ -199577,12 +199577,12 @@ static void rbuCreateImposterTable(tdsqlite3rbu *p, RbuObjIter *pIter){ } } - tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1, tnum); rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"(%z)%s", pIter->zTbl, zSql, (pIter->eType==RBU_PK_WITHOUT_ROWID ? " WITHOUT ROWID" : "") ); - tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); } } @@ -199598,7 +199598,7 @@ static void rbuCreateImposterTable(tdsqlite3rbu *p, RbuObjIter *pIter){ ** virtual table. */ static void rbuObjIterPrepareTmpInsert( - tdsqlite3rbu *p, + sqlite3rbu *p, RbuObjIter *pIter, const char *zCollist, const char *zRbuRowid @@ -199608,7 +199608,7 @@ static void rbuObjIterPrepareTmpInsert( if( zBind ){ assert( pIter->pTmpInsert==0 ); p->rc = prepareFreeAndCollectError( - p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, tdsqlite3_mprintf( + p->dbRbu, &pIter->pTmpInsert, &p->zErrmsg, sqlite3_mprintf( "INSERT INTO %s.'rbu_tmp_%q'(rbu_control,%s%s) VALUES(%z)", p->zStateDb, pIter->zDataTbl, zCollist, zRbuRowid, zBind )); @@ -199616,37 +199616,37 @@ static void rbuObjIterPrepareTmpInsert( } static void rbuTmpInsertFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nVal, - tdsqlite3_value **apVal + sqlite3_value **apVal ){ - tdsqlite3rbu *p = tdsqlite3_user_data(pCtx); + sqlite3rbu *p = sqlite3_user_data(pCtx); int rc = SQLITE_OK; int i; - assert( tdsqlite3_value_int(apVal[0])!=0 + assert( sqlite3_value_int(apVal[0])!=0 || p->objiter.eType==RBU_PK_EXTERNAL || p->objiter.eType==RBU_PK_NONE ); - if( tdsqlite3_value_int(apVal[0])!=0 ){ + if( sqlite3_value_int(apVal[0])!=0 ){ p->nPhaseOneStep += p->objiter.nIndex; } for(i=0; rc==SQLITE_OK && iobjiter.pTmpInsert, i+1, apVal[i]); + rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]); } if( rc==SQLITE_OK ){ - tdsqlite3_step(p->objiter.pTmpInsert); - rc = tdsqlite3_reset(p->objiter.pTmpInsert); + sqlite3_step(p->objiter.pTmpInsert); + rc = sqlite3_reset(p->objiter.pTmpInsert); } if( rc!=SQLITE_OK ){ - tdsqlite3_result_error_code(pCtx, rc); + sqlite3_result_error_code(pCtx, rc); } } -static char *rbuObjIterGetIndexWhere(tdsqlite3rbu *p, RbuObjIter *pIter){ - tdsqlite3_stmt *pStmt = 0; +static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){ + sqlite3_stmt *pStmt = 0; int rc = p->rc; char *zRet = 0; @@ -199659,9 +199659,9 @@ static char *rbuObjIterGetIndexWhere(tdsqlite3rbu *p, RbuObjIter *pIter){ } if( rc==SQLITE_OK ){ int rc2; - rc = tdsqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC); - if( rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pStmt) ){ - char *zSql = (char*)tdsqlite3_column_text(pStmt, 0); + rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + char *zSql = (char*)sqlite3_column_text(pStmt, 0); if( zSql ){ pIter->zIdxSql = zSql = rbuStrndup(zSql, &rc); } @@ -199675,7 +199675,7 @@ static char *rbuObjIterGetIndexWhere(tdsqlite3rbu *p, RbuObjIter *pIter){ /* If necessary, grow the pIter->aIdxCol[] array */ if( iIdxCol==nIdxAlloc ){ - RbuSpan *aIdxCol = (RbuSpan*)tdsqlite3_realloc( + RbuSpan *aIdxCol = (RbuSpan*)sqlite3_realloc( pIter->aIdxCol, (nIdxAlloc+16)*sizeof(RbuSpan) ); if( aIdxCol==0 ){ @@ -199732,7 +199732,7 @@ static char *rbuObjIterGetIndexWhere(tdsqlite3rbu *p, RbuObjIter *pIter){ } } - rc2 = tdsqlite3_finalize(pStmt); + rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ) rc = rc2; } @@ -199746,7 +199746,7 @@ static char *rbuObjIterGetIndexWhere(tdsqlite3rbu *p, RbuObjIter *pIter){ ** as the second argument are available. */ static int rbuObjIterPrepareAll( - tdsqlite3rbu *p, + sqlite3rbu *p, RbuObjIter *pIter, int nOffset /* Add "LIMIT -1 OFFSET $nOffset" to SELECT */ ){ @@ -199759,7 +199759,7 @@ static int rbuObjIterPrepareAll( char *zLimit = 0; if( nOffset ){ - zLimit = tdsqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset); + zLimit = sqlite3_mprintf(" LIMIT -1 OFFSET %d", nOffset); if( !zLimit ) p->rc = SQLITE_NOMEM; } @@ -199780,20 +199780,20 @@ static int rbuObjIterPrepareAll( zBind = rbuObjIterGetBindlist(p, nBind); /* Create the imposter table used to write to this index. */ - tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); - tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum); rbuMPrintfExec(p, p->dbMain, "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID", zTbl, zImposterCols, zImposterPK ); - tdsqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); + sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 0); /* Create the statement to insert index entries */ pIter->nCol = nBind; if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError( p->dbMain, &pIter->pInsert, &p->zErrmsg, - tdsqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind) + sqlite3_mprintf("INSERT INTO \"rbu_imp_%w\" VALUES(%s)", zTbl, zBind) ); } @@ -199801,7 +199801,7 @@ static int rbuObjIterPrepareAll( if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError( p->dbMain, &pIter->pDelete, &p->zErrmsg, - tdsqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere) + sqlite3_mprintf("DELETE FROM \"rbu_imp_%w\" WHERE %s", zTbl, zWhere) ); } @@ -199813,12 +199813,12 @@ static int rbuObjIterPrepareAll( if( nOffset ){ zStart = rbuVacuumIndexStart(p, pIter); if( zStart ){ - tdsqlite3_free(zLimit); + sqlite3_free(zLimit); zLimit = 0; } } - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT %s, 0 AS rbu_control FROM '%q' %s %s %s ORDER BY %s%s", zCollist, pIter->zDataTbl, @@ -199826,17 +199826,17 @@ static int rbuObjIterPrepareAll( (zStart ? (zPart ? "AND" : "WHERE") : ""), zStart, zCollist, zLimit ); - tdsqlite3_free(zStart); + sqlite3_free(zStart); }else if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s", zCollist, p->zStateDb, pIter->zDataTbl, zPart, zCollist, zLimit ); }else{ - zSql = tdsqlite3_mprintf( + zSql = sqlite3_mprintf( "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s " "UNION ALL " "SELECT %s, rbu_control FROM '%q' " @@ -199852,15 +199852,15 @@ static int rbuObjIterPrepareAll( if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbRbu,&pIter->pSelect,pz,zSql); }else{ - tdsqlite3_free(zSql); + sqlite3_free(zSql); } } - tdsqlite3_free(zImposterCols); - tdsqlite3_free(zImposterPK); - tdsqlite3_free(zWhere); - tdsqlite3_free(zBind); - tdsqlite3_free(zPart); + sqlite3_free(zImposterCols); + sqlite3_free(zImposterPK); + sqlite3_free(zWhere); + sqlite3_free(zBind); + sqlite3_free(zPart); }else{ int bRbuRowid = (pIter->eType==RBU_PK_VTAB) ||(pIter->eType==RBU_PK_NONE) @@ -199884,7 +199884,7 @@ static int rbuObjIterPrepareAll( /* Create the INSERT statement to write to the target PK b-tree */ if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pInsert, pz, - tdsqlite3_mprintf( + sqlite3_mprintf( "INSERT INTO \"%s%w\"(%s%s) VALUES(%s)", zWrite, zTbl, zCollist, (bRbuRowid ? ", _rowid_" : ""), zBindings ) @@ -199896,7 +199896,7 @@ static int rbuObjIterPrepareAll( ** an rbu vacuum handle. */ if( rbuIsVacuum(p)==0 && p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbMain, &pIter->pDelete, pz, - tdsqlite3_mprintf( + sqlite3_mprintf( "DELETE FROM \"%s%w\" WHERE %s", zWrite, zTbl, zWhere ) ); @@ -199963,7 +199963,7 @@ static int rbuObjIterPrepareAll( if( nOffset ){ zStart = rbuVacuumTableStart(p, pIter, bRbuRowid, zWrite); if( zStart ){ - tdsqlite3_free(zLimit); + sqlite3_free(zLimit); zLimit = 0; } } @@ -199976,7 +199976,7 @@ static int rbuObjIterPrepareAll( if( p->rc==SQLITE_OK ){ p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, - tdsqlite3_mprintf( + sqlite3_mprintf( "SELECT %s,%s rbu_control%s FROM '%q'%s %s %s %s", zCollist, (rbuIsVacuum(p) ? "0 AS " : ""), @@ -199987,17 +199987,17 @@ static int rbuObjIterPrepareAll( ) ); } - tdsqlite3_free(zStart); - tdsqlite3_free(zOrder); + sqlite3_free(zStart); + sqlite3_free(zOrder); } - tdsqlite3_free(zWhere); - tdsqlite3_free(zOldlist); - tdsqlite3_free(zNewlist); - tdsqlite3_free(zBindings); + sqlite3_free(zWhere); + sqlite3_free(zOldlist); + sqlite3_free(zNewlist); + sqlite3_free(zBindings); } - tdsqlite3_free(zCollist); - tdsqlite3_free(zLimit); + sqlite3_free(zCollist); + sqlite3_free(zLimit); } return p->rc; @@ -200013,10 +200013,10 @@ static int rbuObjIterPrepareAll( ** is not an error. Output variable *ppStmt is set to NULL in this case. */ static int rbuGetUpdateStmt( - tdsqlite3rbu *p, /* RBU handle */ + sqlite3rbu *p, /* RBU handle */ RbuObjIter *pIter, /* Object iterator */ const char *zMask, /* rbu_control value ('x.x.') */ - tdsqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */ + sqlite3_stmt **ppStmt /* OUT: UPDATE statement handle */ ){ RbuUpdateStmt **pp; RbuUpdateStmt *pUp = 0; @@ -200045,7 +200045,7 @@ static int rbuGetUpdateStmt( if( nUp>=SQLITE_RBU_UPDATE_CACHESIZE ){ for(pp=&pIter->pRbuUpdate; *pp!=pUp; pp=&((*pp)->pNext)); *pp = 0; - tdsqlite3_finalize(pUp->pUpdate); + sqlite3_finalize(pUp->pUpdate); pUp->pUpdate = 0; }else{ pUp = (RbuUpdateStmt*)rbuMalloc(p, sizeof(RbuUpdateStmt)+pIter->nTblCol+1); @@ -200065,7 +200065,7 @@ static int rbuGetUpdateStmt( const char *zPrefix = ""; if( pIter->eType!=RBU_PK_VTAB ) zPrefix = "rbu_imp_"; - zUpdate = tdsqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", + zUpdate = sqlite3_mprintf("UPDATE \"%s%w\" SET %s WHERE %s", zPrefix, pIter->zTbl, zSet, zWhere ); p->rc = prepareFreeAndCollectError( @@ -200073,25 +200073,25 @@ static int rbuGetUpdateStmt( ); *ppStmt = pUp->pUpdate; } - tdsqlite3_free(zWhere); - tdsqlite3_free(zSet); + sqlite3_free(zWhere); + sqlite3_free(zSet); } return p->rc; } -static tdsqlite3 *rbuOpenDbhandle( - tdsqlite3rbu *p, +static sqlite3 *rbuOpenDbhandle( + sqlite3rbu *p, const char *zName, int bUseVfs ){ - tdsqlite3 *db = 0; + sqlite3 *db = 0; if( p->rc==SQLITE_OK ){ const int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_URI; - p->rc = tdsqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0); + p->rc = sqlite3_open_v2(zName, &db, flags, bUseVfs ? p->zVfsName : 0); if( p->rc ){ - p->zErrmsg = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(db)); - tdsqlite3_close(db); + p->zErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db)); + sqlite3_close(db); db = 0; } } @@ -200103,10 +200103,10 @@ static tdsqlite3 *rbuOpenDbhandle( */ static void rbuFreeState(RbuState *p){ if( p ){ - tdsqlite3_free(p->zTbl); - tdsqlite3_free(p->zDataTbl); - tdsqlite3_free(p->zIdx); - tdsqlite3_free(p); + sqlite3_free(p->zTbl); + sqlite3_free(p->zDataTbl); + sqlite3_free(p->zIdx); + sqlite3_free(p); } } @@ -200114,14 +200114,14 @@ static void rbuFreeState(RbuState *p){ ** Allocate an RbuState object and load the contents of the rbu_state ** table into it. Return a pointer to the new object. It is the ** responsibility of the caller to eventually free the object using -** tdsqlite3_free(). +** sqlite3_free(). ** ** If an error occurs, leave an error code and message in the rbu handle ** and return NULL. */ -static RbuState *rbuLoadState(tdsqlite3rbu *p){ +static RbuState *rbuLoadState(sqlite3rbu *p){ RbuState *pRet = 0; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; int rc; int rc2; @@ -200129,12 +200129,12 @@ static RbuState *rbuLoadState(tdsqlite3rbu *p){ if( pRet==0 ) return 0; rc = prepareFreeAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, - tdsqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb) + sqlite3_mprintf("SELECT k, v FROM %s.rbu_state", p->zStateDb) ); - while( rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pStmt) ){ - switch( tdsqlite3_column_int(pStmt, 0) ){ + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + switch( sqlite3_column_int(pStmt, 0) ){ case RBU_STATE_STAGE: - pRet->eStage = tdsqlite3_column_int(pStmt, 1); + pRet->eStage = sqlite3_column_int(pStmt, 1); if( pRet->eStage!=RBU_STAGE_OAL && pRet->eStage!=RBU_STAGE_MOVE && pRet->eStage!=RBU_STAGE_CKPT @@ -200144,39 +200144,39 @@ static RbuState *rbuLoadState(tdsqlite3rbu *p){ break; case RBU_STATE_TBL: - pRet->zTbl = rbuStrndup((char*)tdsqlite3_column_text(pStmt, 1), &rc); + pRet->zTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); break; case RBU_STATE_IDX: - pRet->zIdx = rbuStrndup((char*)tdsqlite3_column_text(pStmt, 1), &rc); + pRet->zIdx = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); break; case RBU_STATE_ROW: - pRet->nRow = tdsqlite3_column_int(pStmt, 1); + pRet->nRow = sqlite3_column_int(pStmt, 1); break; case RBU_STATE_PROGRESS: - pRet->nProgress = tdsqlite3_column_int64(pStmt, 1); + pRet->nProgress = sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_CKPT: - pRet->iWalCksum = tdsqlite3_column_int64(pStmt, 1); + pRet->iWalCksum = sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_COOKIE: - pRet->iCookie = (u32)tdsqlite3_column_int64(pStmt, 1); + pRet->iCookie = (u32)sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_OALSZ: - pRet->iOalSz = (u32)tdsqlite3_column_int64(pStmt, 1); + pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_PHASEONESTEP: - pRet->nPhaseOneStep = tdsqlite3_column_int64(pStmt, 1); + pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); break; case RBU_STATE_DATATBL: - pRet->zDataTbl = rbuStrndup((char*)tdsqlite3_column_text(pStmt, 1), &rc); + pRet->zDataTbl = rbuStrndup((char*)sqlite3_column_text(pStmt, 1), &rc); break; default: @@ -200184,7 +200184,7 @@ static RbuState *rbuLoadState(tdsqlite3rbu *p){ break; } } - rc2 = tdsqlite3_finalize(pStmt); + rc2 = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ) rc = rc2; p->rc = rc; @@ -200196,7 +200196,7 @@ static RbuState *rbuLoadState(tdsqlite3rbu *p){ ** Open the database handle and attach the RBU database as "rbu". If an ** error occurs, leave an error code and message in the RBU handle. */ -static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ +static void rbuOpenDatabase(sqlite3rbu *p, int *pbRetry){ assert( p->rc || (p->dbMain==0 && p->dbRbu==0) ); assert( p->rc || rbuIsVacuum(p) || p->zTarget!=0 ); @@ -200204,9 +200204,9 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ p->dbRbu = rbuOpenDbhandle(p, p->zRbu, 1); if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ - tdsqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); if( p->zState==0 ){ - const char *zFile = tdsqlite3_db_filename(p->dbRbu, "main"); + const char *zFile = sqlite3_db_filename(p->dbRbu, "main"); p->zState = rbuMPrintf(p, "file://%s-vacuum?modeof=%s", zFile, zFile); } } @@ -200222,7 +200222,7 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ #if 0 if( p->rc==SQLITE_OK && rbuIsVacuum(p) ){ - p->rc = tdsqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0); + p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, 0); } #endif @@ -200234,26 +200234,26 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ if( p->rc==SQLITE_OK ){ int rc2; int bOk = 0; - tdsqlite3_stmt *pCnt = 0; + sqlite3_stmt *pCnt = 0; p->rc = prepareAndCollectError(p->dbRbu, &pCnt, &p->zErrmsg, "SELECT count(*) FROM stat.sqlite_master" ); if( p->rc==SQLITE_OK - && tdsqlite3_step(pCnt)==SQLITE_ROW - && 1==tdsqlite3_column_int(pCnt, 0) + && sqlite3_step(pCnt)==SQLITE_ROW + && 1==sqlite3_column_int(pCnt, 0) ){ bOk = 1; } - rc2 = tdsqlite3_finalize(pCnt); + rc2 = sqlite3_finalize(pCnt); if( p->rc==SQLITE_OK ) p->rc = rc2; if( p->rc==SQLITE_OK && bOk==0 ){ p->rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf("invalid state database"); + p->zErrmsg = sqlite3_mprintf("invalid state database"); } if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); + p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); } } } @@ -200264,7 +200264,7 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ int rc; p->nRbu = 0; p->pRbuFd = 0; - rc = tdsqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); + rc = sqlite3_file_control(p->dbRbu, "main", SQLITE_FCNTL_RBUCNT, (void*)p); if( rc!=SQLITE_NOTFOUND ) p->rc = rc; if( p->eStage>=RBU_STAGE_MOVE ){ bOpen = 1; @@ -200285,15 +200285,15 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ }else if( p->pRbuFd->pWalFd ){ if( pbRetry ){ p->pRbuFd->bNolock = 0; - tdsqlite3_close(p->dbRbu); - tdsqlite3_close(p->dbMain); + sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); p->dbMain = 0; p->dbRbu = 0; *pbRetry = 1; return; } p->rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf("cannot vacuum wal mode database"); + p->zErrmsg = sqlite3_mprintf("cannot vacuum wal mode database"); }else{ char *zTarget; char *zExtra = 0; @@ -200305,8 +200305,8 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ if( *zExtra=='\0' ) zExtra = 0; } - zTarget = tdsqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s", - tdsqlite3_db_filename(p->dbRbu, "main"), + zTarget = sqlite3_mprintf("file:%s-vactmp?rbu_memory=1%s%s", + sqlite3_db_filename(p->dbRbu, "main"), (zExtra==0 ? "" : "&"), (zExtra==0 ? "" : zExtra) ); @@ -200315,30 +200315,30 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ return; } p->dbMain = rbuOpenDbhandle(p, zTarget, p->nRbu<=1); - tdsqlite3_free(zTarget); + sqlite3_free(zTarget); } } if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_create_function(p->dbMain, + p->rc = sqlite3_create_function(p->dbMain, "rbu_tmp_insert", -1, SQLITE_UTF8, (void*)p, rbuTmpInsertFunc, 0, 0 ); } if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_create_function(p->dbMain, + p->rc = sqlite3_create_function(p->dbMain, "rbu_fossil_delta", 2, SQLITE_UTF8, 0, rbuFossilDeltaFunc, 0, 0 ); } if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_create_function(p->dbRbu, + p->rc = sqlite3_create_function(p->dbRbu, "rbu_target_name", -1, SQLITE_UTF8, (void*)p, rbuTargetNameFunc, 0, 0 ); } if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); + p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); } rbuMPrintfExec(p, p->dbMain, "SELECT * FROM sqlite_master"); @@ -200346,17 +200346,17 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ ** this call returns SQLITE_NOTFOUND, then the RBU vfs is not in use. ** This is an error. */ if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); + p->rc = sqlite3_file_control(p->dbMain, "main", SQLITE_FCNTL_RBU, (void*)p); } if( p->rc==SQLITE_NOTFOUND ){ p->rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf("rbu vfs not found"); + p->zErrmsg = sqlite3_mprintf("rbu vfs not found"); } } /* -** This routine is a copy of the tdsqlite3FileSuffix3() routine from the core. +** This routine is a copy of the sqlite3FileSuffix3() routine from the core. ** It is a no-op unless SQLITE_ENABLE_8_3_NAMES is defined. ** ** If SQLITE_ENABLE_8_3_NAMES is set at compile-time and if the database @@ -200378,7 +200378,7 @@ static void rbuOpenDatabase(tdsqlite3rbu *p, int *pbRetry){ static void rbuFileSuffix3(const char *zBase, char *z){ #ifdef SQLITE_ENABLE_8_3_NAMES #if SQLITE_ENABLE_8_3_NAMES<2 - if( tdsqlite3_uri_boolean(zBase, "8_3_names", 0) ) + if( sqlite3_uri_boolean(zBase, "8_3_names", 0) ) #endif { int i, sz; @@ -200396,10 +200396,10 @@ static void rbuFileSuffix3(const char *zBase, char *z){ ** The checksum is store in the first page of xShmMap memory as an 8-byte ** blob starting at byte offset 40. */ -static i64 rbuShmChecksum(tdsqlite3rbu *p){ +static i64 rbuShmChecksum(sqlite3rbu *p){ i64 iRet = 0; if( p->rc==SQLITE_OK ){ - tdsqlite3_file *pDb = p->pTargetFd->pReal; + sqlite3_file *pDb = p->pTargetFd->pReal; u32 volatile *ptr; p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr); if( p->rc==SQLITE_OK ){ @@ -200413,7 +200413,7 @@ static i64 rbuShmChecksum(tdsqlite3rbu *p){ ** This function is called as part of initializing or reinitializing an ** incremental checkpoint. ** -** It populates the tdsqlite3rbu.aFrame[] array with the set of +** It populates the sqlite3rbu.aFrame[] array with the set of ** (wal frame -> db page) copy operations required to checkpoint the ** current wal file, and obtains the set of shm locks required to safely ** perform the copy operations directly on the file-system. @@ -200425,7 +200425,7 @@ static i64 rbuShmChecksum(tdsqlite3rbu *p){ ** other client appends a transaction to the wal file in the middle of ** an incremental checkpoint. */ -static void rbuSetupCheckpoint(tdsqlite3rbu *p, RbuState *pState){ +static void rbuSetupCheckpoint(sqlite3rbu *p, RbuState *pState){ /* If pState is NULL, then the wal file may not have been opened and ** recovered. Running a read-statement here to ensure that doing so @@ -200433,12 +200433,12 @@ static void rbuSetupCheckpoint(tdsqlite3rbu *p, RbuState *pState){ if( pState==0 ){ p->eStage = 0; if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0); + p->rc = sqlite3_exec(p->dbMain, "SELECT * FROM sqlite_master", 0, 0, 0); } } /* Assuming no error has occurred, run a "restart" checkpoint with the - ** tdsqlite3rbu.eStage variable set to CAPTURE. This turns on the following + ** sqlite3rbu.eStage variable set to CAPTURE. This turns on the following ** special behaviour in the rbu VFS: ** ** * If the exclusive shm WRITER or READ0 lock cannot be obtained, @@ -200447,7 +200447,7 @@ static void rbuSetupCheckpoint(tdsqlite3rbu *p, RbuState *pState){ ** ** * Attempts to read from the *-wal file or write to the database file ** do not perform any IO. Instead, the frame/page combinations that - ** would be read/written are recorded in the tdsqlite3rbu.aFrame[] + ** would be read/written are recorded in the sqlite3rbu.aFrame[] ** array. ** ** * Calls to xShmLock(UNLOCK) to release the exclusive shm WRITER, @@ -200468,7 +200468,7 @@ static void rbuSetupCheckpoint(tdsqlite3rbu *p, RbuState *pState){ if( p->rc==SQLITE_OK ){ int rc2; p->eStage = RBU_STAGE_CAPTURE; - rc2 = tdsqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); + rc2 = sqlite3_exec(p->dbMain, "PRAGMA main.wal_checkpoint=restart", 0, 0,0); if( rc2!=SQLITE_INTERNAL ) p->rc = rc2; } @@ -200485,8 +200485,8 @@ static void rbuSetupCheckpoint(tdsqlite3rbu *p, RbuState *pState){ p->eStage = RBU_STAGE_DONE; }else{ int nSectorSize; - tdsqlite3_file *pDb = p->pTargetFd->pReal; - tdsqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; + sqlite3_file *pDb = p->pTargetFd->pReal; + sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; assert( p->nPagePerSector==0 ); nSectorSize = pDb->pMethods->xSectorSize(pDb); if( nSectorSize>p->pgsz ){ @@ -200509,7 +200509,7 @@ static void rbuSetupCheckpoint(tdsqlite3rbu *p, RbuState *pState){ ** the rbu object is in capture mode. Record the frame number of the frame ** being read in the aFrame[] array. */ -static int rbuCaptureWalRead(tdsqlite3rbu *pRbu, i64 iOff, int iAmt){ +static int rbuCaptureWalRead(sqlite3rbu *pRbu, i64 iOff, int iAmt){ const u32 mReq = (1<nFrame==pRbu->nFrameAlloc ){ int nNew = (pRbu->nFrameAlloc ? pRbu->nFrameAlloc : 64) * 2; RbuFrame *aNew; - aNew = (RbuFrame*)tdsqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame)); + aNew = (RbuFrame*)sqlite3_realloc64(pRbu->aFrame, nNew * sizeof(RbuFrame)); if( aNew==0 ) return SQLITE_NOMEM; pRbu->aFrame = aNew; pRbu->nFrameAlloc = nNew; @@ -200541,7 +200541,7 @@ static int rbuCaptureWalRead(tdsqlite3rbu *pRbu, i64 iOff, int iAmt){ ** file while the rbu handle is in capture mode. Record the page number ** of the page being written in the aFrame[] array. */ -static int rbuCaptureDbWrite(tdsqlite3rbu *pRbu, i64 iOff){ +static int rbuCaptureDbWrite(sqlite3rbu *pRbu, i64 iOff){ pRbu->aFrame[pRbu->nFrame-1].iDbPage = (u32)(iOff / pRbu->pgsz) + 1; return SQLITE_OK; } @@ -200551,9 +200551,9 @@ static int rbuCaptureDbWrite(tdsqlite3rbu *pRbu, i64 iOff){ ** a single frame of data from the wal file into the database file, as ** indicated by the RbuFrame object. */ -static void rbuCheckpointFrame(tdsqlite3rbu *p, RbuFrame *pFrame){ - tdsqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; - tdsqlite3_file *pDb = p->pTargetFd->pReal; +static void rbuCheckpointFrame(sqlite3rbu *p, RbuFrame *pFrame){ + sqlite3_file *pWal = p->pTargetFd->pWalFd->pReal; + sqlite3_file *pDb = p->pTargetFd->pReal; i64 iOff; assert( p->rc==SQLITE_OK ); @@ -200569,8 +200569,8 @@ static void rbuCheckpointFrame(tdsqlite3rbu *p, RbuFrame *pFrame){ /* ** Take an EXCLUSIVE lock on the database file. */ -static void rbuLockDatabase(tdsqlite3rbu *p){ - tdsqlite3_file *pReal = p->pTargetFd->pReal; +static void rbuLockDatabase(sqlite3rbu *p){ + sqlite3_file *pReal = p->pTargetFd->pReal; assert( p->rc==SQLITE_OK ); p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED); if( p->rc==SQLITE_OK ){ @@ -200587,7 +200587,7 @@ static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){ if( nChar==0 ){ return 0; } - zWideFilename = tdsqlite3_malloc64( nChar*sizeof(zWideFilename[0]) ); + zWideFilename = sqlite3_malloc64( nChar*sizeof(zWideFilename[0]) ); if( zWideFilename==0 ){ return 0; } @@ -200595,7 +200595,7 @@ static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){ nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename, nChar); if( nChar==0 ){ - tdsqlite3_free(zWideFilename); + sqlite3_free(zWideFilename); zWideFilename = 0; } return zWideFilename; @@ -200609,17 +200609,17 @@ static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){ ** If an error occurs, leave an error code and error message in the rbu ** handle. */ -static void rbuMoveOalFile(tdsqlite3rbu *p){ - const char *zBase = tdsqlite3_db_filename(p->dbMain, "main"); +static void rbuMoveOalFile(sqlite3rbu *p){ + const char *zBase = sqlite3_db_filename(p->dbMain, "main"); const char *zMove = zBase; char *zOal; char *zWal; if( rbuIsVacuum(p) ){ - zMove = tdsqlite3_db_filename(p->dbRbu, "main"); + zMove = sqlite3_db_filename(p->dbRbu, "main"); } - zOal = tdsqlite3_mprintf("%s-oal", zMove); - zWal = tdsqlite3_mprintf("%s-wal", zMove); + zOal = sqlite3_mprintf("%s-oal", zMove); + zWal = sqlite3_mprintf("%s-wal", zMove); assert( p->eStage==RBU_STAGE_MOVE ); assert( p->rc==SQLITE_OK && p->zErrmsg==0 ); @@ -200640,8 +200640,8 @@ static void rbuMoveOalFile(tdsqlite3rbu *p){ /* Re-open the databases. */ rbuObjIterFinalize(&p->objiter); - tdsqlite3_close(p->dbRbu); - tdsqlite3_close(p->dbMain); + sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); p->dbMain = 0; p->dbRbu = 0; @@ -200659,11 +200659,11 @@ static void rbuMoveOalFile(tdsqlite3rbu *p){ }else{ p->rc = SQLITE_IOERR; } - tdsqlite3_free(zWideWal); + sqlite3_free(zWideWal); }else{ p->rc = SQLITE_IOERR_NOMEM; } - tdsqlite3_free(zWideOal); + sqlite3_free(zWideOal); }else{ p->rc = SQLITE_IOERR_NOMEM; } @@ -200679,8 +200679,8 @@ static void rbuMoveOalFile(tdsqlite3rbu *p){ } } - tdsqlite3_free(zWal); - tdsqlite3_free(zOal); + sqlite3_free(zWal); + sqlite3_free(zOal); } /* @@ -200700,13 +200700,13 @@ static void rbuMoveOalFile(tdsqlite3rbu *p){ ** If the rbu_control field contains an invalid value, an error code and ** message are left in the RBU handle and zero returned. */ -static int rbuStepType(tdsqlite3rbu *p, const char **pzMask){ +static int rbuStepType(sqlite3rbu *p, const char **pzMask){ int iCol = p->objiter.nCol; /* Index of rbu_control column */ int res = 0; /* Return value */ - switch( tdsqlite3_column_type(p->objiter.pSelect, iCol) ){ + switch( sqlite3_column_type(p->objiter.pSelect, iCol) ){ case SQLITE_INTEGER: { - int iVal = tdsqlite3_column_int(p->objiter.pSelect, iCol); + int iVal = sqlite3_column_int(p->objiter.pSelect, iCol); switch( iVal ){ case 0: res = RBU_INSERT; break; case 1: res = RBU_DELETE; break; @@ -200718,7 +200718,7 @@ static int rbuStepType(tdsqlite3rbu *p, const char **pzMask){ } case SQLITE_TEXT: { - const unsigned char *z = tdsqlite3_column_text(p->objiter.pSelect, iCol); + const unsigned char *z = sqlite3_column_text(p->objiter.pSelect, iCol); if( z==0 ){ p->rc = SQLITE_NOMEM; }else{ @@ -200743,9 +200743,9 @@ static int rbuStepType(tdsqlite3rbu *p, const char **pzMask){ /* ** Assert that column iCol of statement pStmt is named zName. */ -static void assertColumnName(tdsqlite3_stmt *pStmt, int iCol, const char *zName){ - const char *zCol = tdsqlite3_column_name(pStmt, iCol); - assert( 0==tdsqlite3_stricmp(zName, zCol) ); +static void assertColumnName(sqlite3_stmt *pStmt, int iCol, const char *zName){ + const char *zCol = sqlite3_column_name(pStmt, iCol); + assert( 0==sqlite3_stricmp(zName, zCol) ); } #else # define assertColumnName(x,y,z) @@ -200754,12 +200754,12 @@ static void assertColumnName(tdsqlite3_stmt *pStmt, int iCol, const char *zName) /* ** Argument eType must be one of RBU_INSERT, RBU_DELETE, RBU_IDX_INSERT or ** RBU_IDX_DELETE. This function performs the work of a single -** tdsqlite3rbu_step() call for the type of operation specified by eType. +** sqlite3rbu_step() call for the type of operation specified by eType. */ -static void rbuStepOneOp(tdsqlite3rbu *p, int eType){ +static void rbuStepOneOp(sqlite3rbu *p, int eType){ RbuObjIter *pIter = &p->objiter; - tdsqlite3_value *pVal; - tdsqlite3_stmt *pWriter; + sqlite3_value *pVal; + sqlite3_stmt *pWriter; int i; assert( p->rc==SQLITE_OK ); @@ -200788,10 +200788,10 @@ static void rbuStepOneOp(tdsqlite3rbu *p, int eType){ ** to write a NULL into the IPK column. That is not permitted. */ if( eType==RBU_INSERT && pIter->zIdx==0 && pIter->eType==RBU_PK_IPK && pIter->abTblPk[i] - && tdsqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL + && sqlite3_column_type(pIter->pSelect, i)==SQLITE_NULL ){ p->rc = SQLITE_MISMATCH; - p->zErrmsg = tdsqlite3_mprintf("datatype mismatch"); + p->zErrmsg = sqlite3_mprintf("datatype mismatch"); return; } @@ -200799,8 +200799,8 @@ static void rbuStepOneOp(tdsqlite3rbu *p, int eType){ continue; } - pVal = tdsqlite3_column_value(pIter->pSelect, i); - p->rc = tdsqlite3_bind_value(pWriter, i+1, pVal); + pVal = sqlite3_column_value(pIter->pSelect, i); + p->rc = sqlite3_bind_value(pWriter, i+1, pVal); if( p->rc ) return; } if( pIter->zIdx==0 ){ @@ -200818,18 +200818,18 @@ static void rbuStepOneOp(tdsqlite3rbu *p, int eType){ assertColumnName(pIter->pSelect, pIter->nCol+1, rbuIsVacuum(p) ? "rowid" : "rbu_rowid" ); - pVal = tdsqlite3_column_value(pIter->pSelect, pIter->nCol+1); - p->rc = tdsqlite3_bind_value(pWriter, pIter->nCol+1, pVal); + pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); + p->rc = sqlite3_bind_value(pWriter, pIter->nCol+1, pVal); } } if( p->rc==SQLITE_OK ){ - tdsqlite3_step(pWriter); + sqlite3_step(pWriter); p->rc = resetAndCollectError(pWriter, &p->zErrmsg); } } /* -** This function does the work for an tdsqlite3rbu_step() call. +** This function does the work for an sqlite3rbu_step() call. ** ** The object-iterator (p->objiter) currently points to a valid object, ** and the input cursor (p->objiter.pSelect) currently points to a valid @@ -200839,7 +200839,7 @@ static void rbuStepOneOp(tdsqlite3rbu *p, int eType){ ** and message is left in the RBU handle and a copy of the error code ** returned. */ -static int rbuStep(tdsqlite3rbu *p){ +static int rbuStep(sqlite3rbu *p){ RbuObjIter *pIter = &p->objiter; const char *zMask = 0; int eType = rbuStepType(p, &zMask); @@ -200865,8 +200865,8 @@ static int rbuStep(tdsqlite3rbu *p){ rbuStepOneOp(p, eType); } else{ - tdsqlite3_value *pVal; - tdsqlite3_stmt *pUpdate = 0; + sqlite3_value *pVal; + sqlite3_stmt *pUpdate = 0; assert( eType==RBU_UPDATE ); p->nPhaseOneStep -= p->objiter.nIndex; rbuGetUpdateStmt(p, pIter, zMask, &pUpdate); @@ -200874,9 +200874,9 @@ static int rbuStep(tdsqlite3rbu *p){ int i; for(i=0; p->rc==SQLITE_OK && inCol; i++){ char c = zMask[pIter->aiSrcOrder[i]]; - pVal = tdsqlite3_column_value(pIter->pSelect, i); + pVal = sqlite3_column_value(pIter->pSelect, i); if( pIter->abTblPk[i] || c!='.' ){ - p->rc = tdsqlite3_bind_value(pUpdate, i+1, pVal); + p->rc = sqlite3_bind_value(pUpdate, i+1, pVal); } } if( p->rc==SQLITE_OK @@ -200884,11 +200884,11 @@ static int rbuStep(tdsqlite3rbu *p){ ){ /* Bind the rbu_rowid value to column _rowid_ */ assertColumnName(pIter->pSelect, pIter->nCol+1, "rbu_rowid"); - pVal = tdsqlite3_column_value(pIter->pSelect, pIter->nCol+1); - p->rc = tdsqlite3_bind_value(pUpdate, pIter->nCol+1, pVal); + pVal = sqlite3_column_value(pIter->pSelect, pIter->nCol+1); + p->rc = sqlite3_bind_value(pUpdate, pIter->nCol+1, pVal); } if( p->rc==SQLITE_OK ){ - tdsqlite3_step(pUpdate); + sqlite3_step(pUpdate); p->rc = resetAndCollectError(pUpdate, &p->zErrmsg); } } @@ -200904,23 +200904,23 @@ static int rbuStep(tdsqlite3rbu *p){ ** opened by p->dbMain to one more than the schema cookie of the main ** db opened by p->dbRbu. */ -static void rbuIncrSchemaCookie(tdsqlite3rbu *p){ +static void rbuIncrSchemaCookie(sqlite3rbu *p){ if( p->rc==SQLITE_OK ){ - tdsqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); + sqlite3 *dbread = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); int iCookie = 1000000; - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; p->rc = prepareAndCollectError(dbread, &pStmt, &p->zErrmsg, "PRAGMA schema_version" ); if( p->rc==SQLITE_OK ){ - /* Coverage: it may be that this tdsqlite3_step() cannot fail. There + /* Coverage: it may be that this sqlite3_step() cannot fail. There ** is already a transaction open, so the prepared statement cannot ** throw an SQLITE_SCHEMA exception. The only database page the ** statement reads is page 1, which is guaranteed to be in the cache. ** And no memory allocations are required. */ - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - iCookie = tdsqlite3_column_int(pStmt, 0); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + iCookie = sqlite3_column_int(pStmt, 0); } rbuFinalize(p, pStmt); } @@ -200935,15 +200935,15 @@ static void rbuIncrSchemaCookie(tdsqlite3rbu *p){ ** value stored in the RBU_STATE_STAGE column is eStage. All other values ** are determined by inspecting the rbu handle passed as the first argument. */ -static void rbuSaveState(tdsqlite3rbu *p, int eStage){ +static void rbuSaveState(sqlite3rbu *p, int eStage){ if( p->rc==SQLITE_OK || p->rc==SQLITE_DONE ){ - tdsqlite3_stmt *pInsert = 0; + sqlite3_stmt *pInsert = 0; rbu_file *pFd = (rbuIsVacuum(p) ? p->pRbuFd : p->pTargetFd); int rc; assert( p->zErrmsg==0 ); rc = prepareFreeAndCollectError(p->dbRbu, &pInsert, &p->zErrmsg, - tdsqlite3_mprintf( + sqlite3_mprintf( "INSERT OR REPLACE INTO %s.rbu_state(k, v) VALUES " "(%d, %d), " "(%d, %Q), " @@ -200971,8 +200971,8 @@ static void rbuSaveState(tdsqlite3rbu *p, int eStage){ assert( pInsert==0 || rc==SQLITE_OK ); if( rc==SQLITE_OK ){ - tdsqlite3_step(pInsert); - rc = tdsqlite3_finalize(pInsert); + sqlite3_step(pInsert); + rc = sqlite3_finalize(pInsert); } if( rc!=SQLITE_OK ) p->rc = rc; } @@ -200982,12 +200982,12 @@ static void rbuSaveState(tdsqlite3rbu *p, int eStage){ /* ** The second argument passed to this function is the name of a PRAGMA ** setting - "page_size", "auto_vacuum", "user_version" or "application_id". -** This function executes the following on tdsqlite3rbu.dbRbu: +** This function executes the following on sqlite3rbu.dbRbu: ** ** "PRAGMA main.$zPragma" ** ** where $zPragma is the string passed as the second argument, then -** on tdsqlite3rbu.dbMain: +** on sqlite3rbu.dbMain: ** ** "PRAGMA main.$zPragma = $val" ** @@ -200996,15 +200996,15 @@ static void rbuSaveState(tdsqlite3rbu *p, int eStage){ ** In short, it copies the value of the specified PRAGMA setting from ** dbRbu to dbMain. */ -static void rbuCopyPragma(tdsqlite3rbu *p, const char *zPragma){ +static void rbuCopyPragma(sqlite3rbu *p, const char *zPragma){ if( p->rc==SQLITE_OK ){ - tdsqlite3_stmt *pPragma = 0; + sqlite3_stmt *pPragma = 0; p->rc = prepareFreeAndCollectError(p->dbRbu, &pPragma, &p->zErrmsg, - tdsqlite3_mprintf("PRAGMA main.%s", zPragma) + sqlite3_mprintf("PRAGMA main.%s", zPragma) ); - if( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pPragma) ){ + if( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPragma) ){ p->rc = rbuMPrintfExec(p, p->dbMain, "PRAGMA main.%s = %d", - zPragma, tdsqlite3_column_int(pPragma, 0) + zPragma, sqlite3_column_int(pPragma, 0) ); } rbuFinalize(p, pPragma); @@ -201016,12 +201016,12 @@ static void rbuCopyPragma(tdsqlite3rbu *p, const char *zPragma){ ** the state database is empty. If this RBU handle was opened for an ** RBU vacuum operation, create the schema in the target db. */ -static void rbuCreateTargetSchema(tdsqlite3rbu *p){ - tdsqlite3_stmt *pSql = 0; - tdsqlite3_stmt *pInsert = 0; +static void rbuCreateTargetSchema(sqlite3rbu *p){ + sqlite3_stmt *pSql = 0; + sqlite3_stmt *pInsert = 0; assert( rbuIsVacuum(p) ); - p->rc = tdsqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg); + p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=1", 0,0, &p->zErrmsg); if( p->rc==SQLITE_OK ){ p->rc = prepareAndCollectError(p->dbRbu, &pSql, &p->zErrmsg, "SELECT sql FROM sqlite_master WHERE sql!='' AND rootpage!=0" @@ -201030,9 +201030,9 @@ static void rbuCreateTargetSchema(tdsqlite3rbu *p){ ); } - while( p->rc==SQLITE_OK && tdsqlite3_step(pSql)==SQLITE_ROW ){ - const char *zSql = (const char*)tdsqlite3_column_text(pSql, 0); - p->rc = tdsqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg); + while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ + const char *zSql = (const char*)sqlite3_column_text(pSql, 0); + p->rc = sqlite3_exec(p->dbMain, zSql, 0, 0, &p->zErrmsg); } rbuFinalize(p, pSql); if( p->rc!=SQLITE_OK ) return; @@ -201049,16 +201049,16 @@ static void rbuCreateTargetSchema(tdsqlite3rbu *p){ ); } - while( p->rc==SQLITE_OK && tdsqlite3_step(pSql)==SQLITE_ROW ){ + while( p->rc==SQLITE_OK && sqlite3_step(pSql)==SQLITE_ROW ){ int i; for(i=0; i<5; i++){ - tdsqlite3_bind_value(pInsert, i+1, tdsqlite3_column_value(pSql, i)); + sqlite3_bind_value(pInsert, i+1, sqlite3_column_value(pSql, i)); } - tdsqlite3_step(pInsert); - p->rc = tdsqlite3_reset(pInsert); + sqlite3_step(pInsert); + p->rc = sqlite3_reset(pInsert); } if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg); + p->rc = sqlite3_exec(p->dbMain, "PRAGMA writable_schema=0",0,0,&p->zErrmsg); } rbuFinalize(p, pSql); @@ -201068,7 +201068,7 @@ static void rbuCreateTargetSchema(tdsqlite3rbu *p){ /* ** Step the RBU object. */ -SQLITE_API int tdsqlite3rbu_step(tdsqlite3rbu *p){ +SQLITE_API int sqlite3rbu_step(sqlite3rbu *p){ if( p ){ switch( p->eStage ){ case RBU_STAGE_OAL: { @@ -201098,13 +201098,13 @@ SQLITE_API int tdsqlite3rbu_step(tdsqlite3rbu *p){ /* Advance to the next row to process. */ if( p->rc==SQLITE_OK ){ - int rc = tdsqlite3_step(pIter->pSelect); + int rc = sqlite3_step(pIter->pSelect); if( rc==SQLITE_ROW ){ p->nProgress++; p->nStep++; return rbuStep(p); } - p->rc = tdsqlite3_reset(pIter->pSelect); + p->rc = sqlite3_reset(pIter->pSelect); p->nStep = 0; } } @@ -201117,10 +201117,10 @@ SQLITE_API int tdsqlite3rbu_step(tdsqlite3rbu *p){ rbuSaveState(p, RBU_STAGE_MOVE); rbuIncrSchemaCookie(p); if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg); + p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg); } if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg); + p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg); } p->eStage = RBU_STAGE_MOVE; } @@ -201138,7 +201138,7 @@ SQLITE_API int tdsqlite3rbu_step(tdsqlite3rbu *p){ case RBU_STAGE_CKPT: { if( p->rc==SQLITE_OK ){ if( p->nStep>=p->nFrame ){ - tdsqlite3_file *pDb = p->pTargetFd->pReal; + sqlite3_file *pDb = p->pTargetFd->pReal; /* Sync the db file */ p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL); @@ -201158,11 +201158,11 @@ SQLITE_API int tdsqlite3rbu_step(tdsqlite3rbu *p){ } }else{ /* At one point the following block copied a single frame from the - ** wal file to the database file. So that one call to tdsqlite3rbu_step() + ** wal file to the database file. So that one call to sqlite3rbu_step() ** checkpointed a single frame. ** ** However, if the sector-size is larger than the page-size, and the - ** application calls tdsqlite3rbu_savestate() or close() immediately + ** application calls sqlite3rbu_savestate() or close() immediately ** after this step, then rbu_step() again, then a power failure occurs, ** then the database page written here may be damaged. Work around ** this by checkpointing frames until the next page in the aFrame[] @@ -201200,20 +201200,20 @@ SQLITE_API int tdsqlite3rbu_step(tdsqlite3rbu *p){ static int rbuStrCompare(const char *z1, const char *z2){ if( z1==0 && z2==0 ) return 0; if( z1==0 || z2==0 ) return 1; - return (tdsqlite3_stricmp(z1, z2)!=0); + return (sqlite3_stricmp(z1, z2)!=0); } /* -** This function is called as part of tdsqlite3rbu_open() when initializing +** This function is called as part of sqlite3rbu_open() when initializing ** an rbu handle in OAL stage. If the rbu update has not started (i.e. ** the rbu_state table was empty) it is a no-op. Otherwise, it arranges -** things so that the next call to tdsqlite3rbu_step() continues on from +** things so that the next call to sqlite3rbu_step() continues on from ** where the previous rbu handle left off. ** ** If an error occurs, an error code and error message are left in the ** rbu handle passed as the first argument. */ -static void rbuSetupOal(tdsqlite3rbu *p, RbuState *pState){ +static void rbuSetupOal(sqlite3rbu *p, RbuState *pState){ assert( p->rc==SQLITE_OK ); if( pState->zTbl ){ RbuObjIter *pIter = &p->objiter; @@ -201229,7 +201229,7 @@ static void rbuSetupOal(tdsqlite3rbu *p, RbuState *pState){ if( rc==SQLITE_OK && !pIter->zTbl ){ rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf("rbu_state mismatch error"); + p->zErrmsg = sqlite3_mprintf("rbu_state mismatch error"); } if( rc==SQLITE_OK ){ @@ -201246,32 +201246,32 @@ static void rbuSetupOal(tdsqlite3rbu *p, RbuState *pState){ ** target database in the file-system, delete it. If an error occurs, ** leave an error code and error message in the rbu handle. */ -static void rbuDeleteOalFile(tdsqlite3rbu *p){ +static void rbuDeleteOalFile(sqlite3rbu *p){ char *zOal = rbuMPrintf(p, "%s-oal", p->zTarget); if( zOal ){ - tdsqlite3_vfs *pVfs = tdsqlite3_vfs_find(0); + sqlite3_vfs *pVfs = sqlite3_vfs_find(0); assert( pVfs && p->rc==SQLITE_OK && p->zErrmsg==0 ); pVfs->xDelete(pVfs, zOal, 0); - tdsqlite3_free(zOal); + sqlite3_free(zOal); } } /* ** Allocate a private rbu VFS for the rbu handle passed as the only -** argument. This VFS will be used unless the call to tdsqlite3rbu_open() +** argument. This VFS will be used unless the call to sqlite3rbu_open() ** specified a URI with a vfs=? option in place of a target database ** file name. */ -static void rbuCreateVfs(tdsqlite3rbu *p){ +static void rbuCreateVfs(sqlite3rbu *p){ int rnd; char zRnd[64]; assert( p->rc==SQLITE_OK ); - tdsqlite3_randomness(sizeof(int), (void*)&rnd); - tdsqlite3_snprintf(sizeof(zRnd), zRnd, "rbu_vfs_%d", rnd); - p->rc = tdsqlite3rbu_create_vfs(zRnd, 0); + sqlite3_randomness(sizeof(int), (void*)&rnd); + sqlite3_snprintf(sizeof(zRnd), zRnd, "rbu_vfs_%d", rnd); + p->rc = sqlite3rbu_create_vfs(zRnd, 0); if( p->rc==SQLITE_OK ){ - tdsqlite3_vfs *pVfs = tdsqlite3_vfs_find(zRnd); + sqlite3_vfs *pVfs = sqlite3_vfs_find(zRnd); assert( pVfs ); p->zVfsName = pVfs->zName; ((rbu_vfs*)pVfs)->pRbu = p; @@ -201282,9 +201282,9 @@ static void rbuCreateVfs(tdsqlite3rbu *p){ ** Destroy the private VFS created for the rbu handle passed as the only ** argument by an earlier call to rbuCreateVfs(). */ -static void rbuDeleteVfs(tdsqlite3rbu *p){ +static void rbuDeleteVfs(sqlite3rbu *p){ if( p->zVfsName ){ - tdsqlite3rbu_destroy_vfs(p->zVfsName); + sqlite3rbu_destroy_vfs(p->zVfsName); p->zVfsName = 0; } } @@ -201295,43 +201295,43 @@ static void rbuDeleteVfs(tdsqlite3rbu *p){ ** the number of auxilliary indexes on the table. */ static void rbuIndexCntFunc( - tdsqlite3_context *pCtx, + sqlite3_context *pCtx, int nVal, - tdsqlite3_value **apVal + sqlite3_value **apVal ){ - tdsqlite3rbu *p = (tdsqlite3rbu*)tdsqlite3_user_data(pCtx); - tdsqlite3_stmt *pStmt = 0; + sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); + sqlite3_stmt *pStmt = 0; char *zErrmsg = 0; int rc; - tdsqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); + sqlite3 *db = (rbuIsVacuum(p) ? p->dbRbu : p->dbMain); assert( nVal==1 ); rc = prepareFreeAndCollectError(db, &pStmt, &zErrmsg, - tdsqlite3_mprintf("SELECT count(*) FROM sqlite_master " - "WHERE type='index' AND tbl_name = %Q", tdsqlite3_value_text(apVal[0])) + sqlite3_mprintf("SELECT count(*) FROM sqlite_master " + "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0])) ); if( rc!=SQLITE_OK ){ - tdsqlite3_result_error(pCtx, zErrmsg, -1); + sqlite3_result_error(pCtx, zErrmsg, -1); }else{ int nIndex = 0; - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - nIndex = tdsqlite3_column_int(pStmt, 0); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + nIndex = sqlite3_column_int(pStmt, 0); } - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); if( rc==SQLITE_OK ){ - tdsqlite3_result_int(pCtx, nIndex); + sqlite3_result_int(pCtx, nIndex); }else{ - tdsqlite3_result_error(pCtx, tdsqlite3_errmsg(db), -1); + sqlite3_result_error(pCtx, sqlite3_errmsg(db), -1); } } - tdsqlite3_free(zErrmsg); + sqlite3_free(zErrmsg); } /* ** If the RBU database contains the rbu_count table, use it to initialize -** the tdsqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table +** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table ** is assumed to contain the same columns as: ** ** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; @@ -201340,18 +201340,18 @@ static void rbuIndexCntFunc( ** database. The 'tbl' column should contain the name of a data_xxx table, ** and the cnt column the number of rows it contains. ** -** tdsqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt +** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt ** for all rows in the rbu_count table, where nIndex is the number of ** indexes on the corresponding target database table. */ -static void rbuInitPhaseOneSteps(tdsqlite3rbu *p){ +static void rbuInitPhaseOneSteps(sqlite3rbu *p){ if( p->rc==SQLITE_OK ){ - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; int bExists = 0; /* True if rbu_count exists */ p->nPhaseOneStep = -1; - p->rc = tdsqlite3_create_function(p->dbRbu, + p->rc = sqlite3_create_function(p->dbRbu, "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0 ); @@ -201363,10 +201363,10 @@ static void rbuInitPhaseOneSteps(tdsqlite3rbu *p){ ); } if( p->rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ + if( SQLITE_ROW==sqlite3_step(pStmt) ){ bExists = 1; } - p->rc = tdsqlite3_finalize(pStmt); + p->rc = sqlite3_finalize(pStmt); } if( p->rc==SQLITE_OK && bExists ){ @@ -201375,32 +201375,32 @@ static void rbuInitPhaseOneSteps(tdsqlite3rbu *p){ "FROM rbu_count" ); if( p->rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - p->nPhaseOneStep = tdsqlite3_column_int64(pStmt, 0); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0); } - p->rc = tdsqlite3_finalize(pStmt); + p->rc = sqlite3_finalize(pStmt); } } } } -static tdsqlite3rbu *openRbuHandle( +static sqlite3rbu *openRbuHandle( const char *zTarget, const char *zRbu, const char *zState ){ - tdsqlite3rbu *p; + sqlite3rbu *p; size_t nTarget = zTarget ? strlen(zTarget) : 0; size_t nRbu = strlen(zRbu); - size_t nByte = sizeof(tdsqlite3rbu) + nTarget+1 + nRbu+1; + size_t nByte = sizeof(sqlite3rbu) + nTarget+1 + nRbu+1; - p = (tdsqlite3rbu*)tdsqlite3_malloc64(nByte); + p = (sqlite3rbu*)sqlite3_malloc64(nByte); if( p ){ RbuState *pState = 0; /* Create the custom VFS. */ - memset(p, 0, sizeof(tdsqlite3rbu)); + memset(p, 0, sizeof(sqlite3rbu)); rbuCreateVfs(p); /* Open the target, RBU and state databases */ @@ -201454,7 +201454,7 @@ static tdsqlite3rbu *openRbuHandle( if( p->rc==SQLITE_OK && p->pTargetFd->pWalFd ){ if( p->eStage==RBU_STAGE_OAL ){ p->rc = SQLITE_ERROR; - p->zErrmsg = tdsqlite3_mprintf("cannot update wal mode database"); + p->zErrmsg = sqlite3_mprintf("cannot update wal mode database"); }else if( p->eStage==RBU_STAGE_MOVE ){ p->eStage = RBU_STAGE_CKPT; p->nStep = 0; @@ -201472,7 +201472,7 @@ static tdsqlite3rbu *openRbuHandle( ** transaction is committed in rollback mode) currently stored on ** page 1 of the database file. */ p->rc = SQLITE_BUSY; - p->zErrmsg = tdsqlite3_mprintf("database modified during rbu %s", + p->zErrmsg = sqlite3_mprintf("database modified during rbu %s", (rbuIsVacuum(p) ? "vacuum" : "update") ); } @@ -201480,8 +201480,8 @@ static tdsqlite3rbu *openRbuHandle( if( p->rc==SQLITE_OK ){ if( p->eStage==RBU_STAGE_OAL ){ - tdsqlite3 *db = p->dbMain; - p->rc = tdsqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg); + sqlite3 *db = p->dbMain; + p->rc = sqlite3_exec(p->dbRbu, "BEGIN", 0, 0, &p->zErrmsg); /* Point the object iterator at the first object */ if( p->rc==SQLITE_OK ){ @@ -201502,16 +201502,16 @@ static tdsqlite3rbu *openRbuHandle( /* Open transactions both databases. The *-oal file is opened or ** created at this point. */ if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); + p->rc = sqlite3_exec(db, "BEGIN IMMEDIATE", 0, 0, &p->zErrmsg); } /* Check if the main database is a zipvfs db. If it is, set the upper ** level pager to use "journal_mode=off". This prevents it from ** generating a large journal using a temp file. */ if( p->rc==SQLITE_OK ){ - int frc = tdsqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0); + int frc = sqlite3_file_control(db, "main", SQLITE_FCNTL_ZIPVFS, 0); if( frc==SQLITE_OK ){ - p->rc = tdsqlite3_exec( + p->rc = sqlite3_exec( db, "PRAGMA journal_mode=off",0,0,&p->zErrmsg); } } @@ -201541,11 +201541,11 @@ static tdsqlite3rbu *openRbuHandle( ** Allocate and return an RBU handle with all fields zeroed except for the ** error code, which is set to SQLITE_MISUSE. */ -static tdsqlite3rbu *rbuMisuseError(void){ - tdsqlite3rbu *pRet; - pRet = tdsqlite3_malloc64(sizeof(tdsqlite3rbu)); +static sqlite3rbu *rbuMisuseError(void){ + sqlite3rbu *pRet; + pRet = sqlite3_malloc64(sizeof(sqlite3rbu)); if( pRet ){ - memset(pRet, 0, sizeof(tdsqlite3rbu)); + memset(pRet, 0, sizeof(sqlite3rbu)); pRet->rc = SQLITE_MISUSE; } return pRet; @@ -201554,7 +201554,7 @@ static tdsqlite3rbu *rbuMisuseError(void){ /* ** Open and return a new RBU handle. */ -SQLITE_API tdsqlite3rbu *tdsqlite3rbu_open( +SQLITE_API sqlite3rbu *sqlite3rbu_open( const char *zTarget, const char *zRbu, const char *zState @@ -201567,7 +201567,7 @@ SQLITE_API tdsqlite3rbu *tdsqlite3rbu_open( /* ** Open a handle to begin or resume an RBU VACUUM operation. */ -SQLITE_API tdsqlite3rbu *tdsqlite3rbu_vacuum( +SQLITE_API sqlite3rbu *sqlite3rbu_vacuum( const char *zTarget, const char *zState ){ @@ -201585,8 +201585,8 @@ SQLITE_API tdsqlite3rbu *tdsqlite3rbu_vacuum( /* ** Return the database handle used by pRbu. */ -SQLITE_API tdsqlite3 *tdsqlite3rbu_db(tdsqlite3rbu *pRbu, int bRbu){ - tdsqlite3 *db = 0; +SQLITE_API sqlite3 *sqlite3rbu_db(sqlite3rbu *pRbu, int bRbu){ + sqlite3 *db = 0; if( pRbu ){ db = (bRbu ? pRbu->dbRbu : pRbu->dbMain); } @@ -201599,7 +201599,7 @@ SQLITE_API tdsqlite3 *tdsqlite3rbu_db(tdsqlite3rbu *pRbu, int bRbu){ ** then edit any error message string so as to remove all occurrences of ** the pattern "rbu_imp_[0-9]*". */ -static void rbuEditErrmsg(tdsqlite3rbu *p){ +static void rbuEditErrmsg(sqlite3rbu *p){ if( p->rc==SQLITE_CONSTRAINT && p->zErrmsg ){ unsigned int i; size_t nErrmsg = strlen(p->zErrmsg); @@ -201617,25 +201617,25 @@ static void rbuEditErrmsg(tdsqlite3rbu *p){ /* ** Close the RBU handle. */ -SQLITE_API int tdsqlite3rbu_close(tdsqlite3rbu *p, char **pzErrmsg){ +SQLITE_API int sqlite3rbu_close(sqlite3rbu *p, char **pzErrmsg){ int rc; if( p ){ /* Commit the transaction to the *-oal file. */ if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){ - p->rc = tdsqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg); + p->rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, &p->zErrmsg); } /* Sync the db file if currently doing an incremental checkpoint */ if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){ - tdsqlite3_file *pDb = p->pTargetFd->pReal; + sqlite3_file *pDb = p->pTargetFd->pReal; p->rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL); } rbuSaveState(p, p->eStage); if( p->rc==SQLITE_OK && p->eStage==RBU_STAGE_OAL ){ - p->rc = tdsqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg); + p->rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, &p->zErrmsg); } /* Close any open statement handles. */ @@ -201643,31 +201643,31 @@ SQLITE_API int tdsqlite3rbu_close(tdsqlite3rbu *p, char **pzErrmsg){ /* If this is an RBU vacuum handle and the vacuum has either finished ** successfully or encountered an error, delete the contents of the - ** state table. This causes the next call to tdsqlite3rbu_vacuum() + ** state table. This causes the next call to sqlite3rbu_vacuum() ** specifying the current target and state databases to start a new ** vacuum from scratch. */ if( rbuIsVacuum(p) && p->rc!=SQLITE_OK && p->dbRbu ){ - int rc2 = tdsqlite3_exec(p->dbRbu, "DELETE FROM stat.rbu_state", 0, 0, 0); + int rc2 = sqlite3_exec(p->dbRbu, "DELETE FROM stat.rbu_state", 0, 0, 0); if( p->rc==SQLITE_DONE && rc2!=SQLITE_OK ) p->rc = rc2; } /* Close the open database handle and VFS object. */ - tdsqlite3_close(p->dbRbu); - tdsqlite3_close(p->dbMain); + sqlite3_close(p->dbRbu); + sqlite3_close(p->dbMain); assert( p->szTemp==0 ); rbuDeleteVfs(p); - tdsqlite3_free(p->aBuf); - tdsqlite3_free(p->aFrame); + sqlite3_free(p->aBuf); + sqlite3_free(p->aFrame); rbuEditErrmsg(p); rc = p->rc; if( pzErrmsg ){ *pzErrmsg = p->zErrmsg; }else{ - tdsqlite3_free(p->zErrmsg); + sqlite3_free(p->zErrmsg); } - tdsqlite3_free(p->zState); - tdsqlite3_free(p); + sqlite3_free(p->zState); + sqlite3_free(p); }else{ rc = SQLITE_NOMEM; *pzErrmsg = 0; @@ -201680,7 +201680,7 @@ SQLITE_API int tdsqlite3rbu_close(tdsqlite3rbu *p, char **pzErrmsg){ ** updates) that have been performed on the target database since the ** current RBU update was started. */ -SQLITE_API tdsqlite3_int64 tdsqlite3rbu_progress(tdsqlite3rbu *pRbu){ +SQLITE_API sqlite3_int64 sqlite3rbu_progress(sqlite3rbu *pRbu){ return pRbu->nProgress; } @@ -201688,7 +201688,7 @@ SQLITE_API tdsqlite3_int64 tdsqlite3rbu_progress(tdsqlite3rbu *pRbu){ ** Return permyriadage progress indications for the two main stages of ** an RBU update. */ -SQLITE_API void tdsqlite3rbu_bp_progress(tdsqlite3rbu *p, int *pnOne, int *pnTwo){ +SQLITE_API void sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){ const int MAX_PROGRESS = 10000; switch( p->eStage ){ case RBU_STAGE_OAL: @@ -201723,7 +201723,7 @@ SQLITE_API void tdsqlite3rbu_bp_progress(tdsqlite3rbu *p, int *pnOne, int *pnTwo /* ** Return the current state of the RBU vacuum or update operation. */ -SQLITE_API int tdsqlite3rbu_state(tdsqlite3rbu *p){ +SQLITE_API int sqlite3rbu_state(sqlite3rbu *p){ int aRes[] = { 0, SQLITE_RBU_STATE_OAL, SQLITE_RBU_STATE_MOVE, 0, SQLITE_RBU_STATE_CHECKPOINT, SQLITE_RBU_STATE_DONE @@ -201751,19 +201751,19 @@ SQLITE_API int tdsqlite3rbu_state(tdsqlite3rbu *p){ } } -SQLITE_API int tdsqlite3rbu_savestate(tdsqlite3rbu *p){ +SQLITE_API int sqlite3rbu_savestate(sqlite3rbu *p){ int rc = p->rc; if( rc==SQLITE_DONE ) return SQLITE_OK; assert( p->eStage>=RBU_STAGE_OAL && p->eStage<=RBU_STAGE_DONE ); if( p->eStage==RBU_STAGE_OAL ){ assert( rc!=SQLITE_DONE ); - if( rc==SQLITE_OK ) rc = tdsqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0); + if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "COMMIT", 0, 0, 0); } /* Sync the db file */ if( rc==SQLITE_OK && p->eStage==RBU_STAGE_CKPT ){ - tdsqlite3_file *pDb = p->pTargetFd->pReal; + sqlite3_file *pDb = p->pTargetFd->pReal; rc = pDb->pMethods->xSync(pDb, SQLITE_SYNC_NORMAL); } @@ -201773,12 +201773,12 @@ SQLITE_API int tdsqlite3rbu_savestate(tdsqlite3rbu *p){ if( p->eStage==RBU_STAGE_OAL ){ assert( rc!=SQLITE_DONE ); - if( rc==SQLITE_OK ) rc = tdsqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); + if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbRbu, "COMMIT", 0, 0, 0); if( rc==SQLITE_OK ){ const char *zBegin = rbuIsVacuum(p) ? "BEGIN" : "BEGIN IMMEDIATE"; - rc = tdsqlite3_exec(p->dbRbu, zBegin, 0, 0, 0); + rc = sqlite3_exec(p->dbRbu, zBegin, 0, 0, 0); } - if( rc==SQLITE_OK ) rc = tdsqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0); + if( rc==SQLITE_OK ) rc = sqlite3_exec(p->dbMain, "BEGIN IMMEDIATE", 0, 0,0); } p->rc = rc; @@ -201831,7 +201831,7 @@ SQLITE_API int tdsqlite3rbu_savestate(tdsqlite3rbu *p){ ** mode except RBU_STAGE_DONE (all work completed and checkpointed), it ** fails with an SQLITE_BUSY error. This is to stop RBU connections ** from automatically checkpointing a *-wal (or *-oal) file from within -** tdsqlite3_close(). +** sqlite3_close(). ** ** 3d. In RBU_STAGE_CAPTURE mode, all xRead() calls on the wal file, and ** all xWrite() calls on the target database file perform no IO. @@ -201847,7 +201847,7 @@ SQLITE_API int tdsqlite3rbu_savestate(tdsqlite3rbu *p){ static void rbuUnlockShm(rbu_file *p){ assert( p->openFlags & SQLITE_OPEN_MAIN_DB ); if( p->pRbu ){ - int (*xShmLock)(tdsqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock; + int (*xShmLock)(sqlite3_file*,int,int,int) = p->pReal->pMethods->xShmLock; int i; for(i=0; ipRbu->mLock ){ @@ -201860,8 +201860,8 @@ static void rbuUnlockShm(rbu_file *p){ /* */ -static int rbuUpdateTempSize(rbu_file *pFd, tdsqlite3_int64 nNew){ - tdsqlite3rbu *pRbu = pFd->pRbu; +static int rbuUpdateTempSize(rbu_file *pFd, sqlite3_int64 nNew){ + sqlite3rbu *pRbu = pFd->pRbu; i64 nDiff = nNew - pFd->sz; pRbu->szTemp += nDiff; pFd->sz = nNew; @@ -201882,7 +201882,7 @@ static void rbuMainlistAdd(rbu_file *p){ rbu_vfs *pRbuVfs = p->pRbuVfs; rbu_file *pIter; assert( (p->openFlags & SQLITE_OPEN_MAIN_DB) ); - tdsqlite3_mutex_enter(pRbuVfs->mutex); + sqlite3_mutex_enter(pRbuVfs->mutex); if( p->pRbu==0 ){ for(pIter=pRbuVfs->pMain; pIter; pIter=pIter->pMainNext); p->pMainNext = pRbuVfs->pMain; @@ -201894,7 +201894,7 @@ static void rbuMainlistAdd(rbu_file *p){ pRbuVfs->pMainRbu = p; } } - tdsqlite3_mutex_leave(pRbuVfs->mutex); + sqlite3_mutex_leave(pRbuVfs->mutex); } /* @@ -201902,14 +201902,14 @@ static void rbuMainlistAdd(rbu_file *p){ */ static void rbuMainlistRemove(rbu_file *p){ rbu_file **pp; - tdsqlite3_mutex_enter(p->pRbuVfs->mutex); + sqlite3_mutex_enter(p->pRbuVfs->mutex); for(pp=&p->pRbuVfs->pMain; *pp && *pp!=p; pp=&((*pp)->pMainNext)){} if( *pp ) *pp = p->pMainNext; p->pMainNext = 0; for(pp=&p->pRbuVfs->pMainRbu; *pp && *pp!=p; pp=&((*pp)->pMainRbuNext)){} if( *pp ) *pp = p->pMainRbuNext; p->pMainRbuNext = 0; - tdsqlite3_mutex_leave(p->pRbuVfs->mutex); + sqlite3_mutex_leave(p->pRbuVfs->mutex); } /* @@ -201923,31 +201923,31 @@ static void rbuMainlistRemove(rbu_file *p){ */ static rbu_file *rbuFindMaindb(rbu_vfs *pRbuVfs, const char *zWal, int bRbu){ rbu_file *pDb; - tdsqlite3_mutex_enter(pRbuVfs->mutex); + sqlite3_mutex_enter(pRbuVfs->mutex); if( bRbu ){ for(pDb=pRbuVfs->pMainRbu; pDb && pDb->zWal!=zWal; pDb=pDb->pMainRbuNext){} }else{ for(pDb=pRbuVfs->pMain; pDb && pDb->zWal!=zWal; pDb=pDb->pMainNext){} } - tdsqlite3_mutex_leave(pRbuVfs->mutex); + sqlite3_mutex_leave(pRbuVfs->mutex); return pDb; } /* ** Close an rbu file. */ -static int rbuVfsClose(tdsqlite3_file *pFile){ +static int rbuVfsClose(sqlite3_file *pFile){ rbu_file *p = (rbu_file*)pFile; int rc; int i; /* Free the contents of the apShm[] array. And the array itself. */ for(i=0; inShm; i++){ - tdsqlite3_free(p->apShm[i]); + sqlite3_free(p->apShm[i]); } - tdsqlite3_free(p->apShm); + sqlite3_free(p->apShm); p->apShm = 0; - tdsqlite3_free(p->zDel); + sqlite3_free(p->zDel); if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ rbuMainlistRemove(p); @@ -201996,13 +201996,13 @@ static void rbuPutU16(u8 *aBuf, u16 iVal){ ** Read data from an rbuVfs-file. */ static int rbuVfsRead( - tdsqlite3_file *pFile, + sqlite3_file *pFile, void *zBuf, int iAmt, sqlite_int64 iOfst ){ rbu_file *p = (rbu_file*)pFile; - tdsqlite3rbu *pRbu = p->pRbu; + sqlite3rbu *pRbu = p->pRbu; int rc; if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ @@ -202027,7 +202027,7 @@ static int rbuVfsRead( && (p->openFlags & SQLITE_OPEN_MAIN_DB) && pRbu->rc==SQLITE_OK ){ - tdsqlite3_file *pFd = (tdsqlite3_file*)pRbu->pRbuFd; + sqlite3_file *pFd = (sqlite3_file*)pRbu->pRbuFd; rc = pFd->pMethods->xRead(pFd, zBuf, iAmt, iOfst); if( rc==SQLITE_OK ){ u8 *aBuf = (u8*)zBuf; @@ -202062,13 +202062,13 @@ static int rbuVfsRead( ** Write data to an rbuVfs-file. */ static int rbuVfsWrite( - tdsqlite3_file *pFile, + sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst ){ rbu_file *p = (rbu_file*)pFile; - tdsqlite3rbu *pRbu = p->pRbu; + sqlite3rbu *pRbu = p->pRbu; int rc; if( pRbu && pRbu->eStage==RBU_STAGE_CAPTURE ){ @@ -202104,7 +202104,7 @@ static int rbuVfsWrite( /* ** Truncate an rbuVfs-file. */ -static int rbuVfsTruncate(tdsqlite3_file *pFile, sqlite_int64 size){ +static int rbuVfsTruncate(sqlite3_file *pFile, sqlite_int64 size){ rbu_file *p = (rbu_file*)pFile; if( (p->openFlags & SQLITE_OPEN_DELETEONCLOSE) && p->pRbu ){ int rc = rbuUpdateTempSize(p, size); @@ -202116,7 +202116,7 @@ static int rbuVfsTruncate(tdsqlite3_file *pFile, sqlite_int64 size){ /* ** Sync an rbuVfs-file. */ -static int rbuVfsSync(tdsqlite3_file *pFile, int flags){ +static int rbuVfsSync(sqlite3_file *pFile, int flags){ rbu_file *p = (rbu_file *)pFile; if( p->pRbu && p->pRbu->eStage==RBU_STAGE_CAPTURE ){ if( p->openFlags & SQLITE_OPEN_MAIN_DB ){ @@ -202130,7 +202130,7 @@ static int rbuVfsSync(tdsqlite3_file *pFile, int flags){ /* ** Return the current file-size of an rbuVfs-file. */ -static int rbuVfsFileSize(tdsqlite3_file *pFile, sqlite_int64 *pSize){ +static int rbuVfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){ rbu_file *p = (rbu_file *)pFile; int rc; rc = p->pReal->pMethods->xFileSize(p->pReal, pSize); @@ -202151,9 +202151,9 @@ static int rbuVfsFileSize(tdsqlite3_file *pFile, sqlite_int64 *pSize){ /* ** Lock an rbuVfs-file. */ -static int rbuVfsLock(tdsqlite3_file *pFile, int eLock){ +static int rbuVfsLock(sqlite3_file *pFile, int eLock){ rbu_file *p = (rbu_file*)pFile; - tdsqlite3rbu *pRbu = p->pRbu; + sqlite3rbu *pRbu = p->pRbu; int rc = SQLITE_OK; assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); @@ -202161,7 +202161,7 @@ static int rbuVfsLock(tdsqlite3_file *pFile, int eLock){ && (p->bNolock || (pRbu && pRbu->eStage!=RBU_STAGE_DONE)) ){ /* Do not allow EXCLUSIVE locks. Preventing SQLite from taking this - ** prevents it from checkpointing the database from tdsqlite3_close(). */ + ** prevents it from checkpointing the database from sqlite3_close(). */ rc = SQLITE_BUSY; }else{ rc = p->pReal->pMethods->xLock(p->pReal, eLock); @@ -202173,7 +202173,7 @@ static int rbuVfsLock(tdsqlite3_file *pFile, int eLock){ /* ** Unlock an rbuVfs-file. */ -static int rbuVfsUnlock(tdsqlite3_file *pFile, int eLock){ +static int rbuVfsUnlock(sqlite3_file *pFile, int eLock){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xUnlock(p->pReal, eLock); } @@ -202181,7 +202181,7 @@ static int rbuVfsUnlock(tdsqlite3_file *pFile, int eLock){ /* ** Check if another file-handle holds a RESERVED lock on an rbuVfs-file. */ -static int rbuVfsCheckReservedLock(tdsqlite3_file *pFile, int *pResOut){ +static int rbuVfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut); } @@ -202189,16 +202189,16 @@ static int rbuVfsCheckReservedLock(tdsqlite3_file *pFile, int *pResOut){ /* ** File control method. For custom operations on an rbuVfs-file. */ -static int rbuVfsFileControl(tdsqlite3_file *pFile, int op, void *pArg){ +static int rbuVfsFileControl(sqlite3_file *pFile, int op, void *pArg){ rbu_file *p = (rbu_file *)pFile; - int (*xControl)(tdsqlite3_file*,int,void*) = p->pReal->pMethods->xFileControl; + int (*xControl)(sqlite3_file*,int,void*) = p->pReal->pMethods->xFileControl; int rc; assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) || p->openFlags & (SQLITE_OPEN_TRANSIENT_DB|SQLITE_OPEN_TEMP_JOURNAL) ); if( op==SQLITE_FCNTL_RBU ){ - tdsqlite3rbu *pRbu = (tdsqlite3rbu*)pArg; + sqlite3rbu *pRbu = (sqlite3rbu*)pArg; /* First try to find another RBU vfs lower down in the vfs stack. If ** one is found, this vfs will operate in pass-through mode. The lower @@ -202212,7 +202212,7 @@ static int rbuVfsFileControl(tdsqlite3_file *pFile, int op, void *pArg){ rc = xControl(p->pReal, SQLITE_FCNTL_ZIPVFS, &dummy); if( rc==SQLITE_OK ){ rc = SQLITE_ERROR; - pRbu->zErrmsg = tdsqlite3_mprintf("rbu/zipvfs setup error"); + pRbu->zErrmsg = sqlite3_mprintf("rbu/zipvfs setup error"); }else if( rc==SQLITE_NOTFOUND ){ pRbu->pTargetFd = p; p->pRbu = pRbu; @@ -202224,7 +202224,7 @@ static int rbuVfsFileControl(tdsqlite3_file *pFile, int op, void *pArg){ return rc; } else if( op==SQLITE_FCNTL_RBUCNT ){ - tdsqlite3rbu *pRbu = (tdsqlite3rbu*)pArg; + sqlite3rbu *pRbu = (sqlite3rbu*)pArg; pRbu->nRbu++; pRbu->pRbuFd = p; p->bNolock = 1; @@ -202234,7 +202234,7 @@ static int rbuVfsFileControl(tdsqlite3_file *pFile, int op, void *pArg){ if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){ rbu_vfs *pRbuVfs = p->pRbuVfs; char *zIn = *(char**)pArg; - char *zOut = tdsqlite3_mprintf("rbu(%s)/%z", pRbuVfs->base.zName, zIn); + char *zOut = sqlite3_mprintf("rbu(%s)/%z", pRbuVfs->base.zName, zIn); *(char**)pArg = zOut; if( zOut==0 ) rc = SQLITE_NOMEM; } @@ -202245,7 +202245,7 @@ static int rbuVfsFileControl(tdsqlite3_file *pFile, int op, void *pArg){ /* ** Return the sector-size in bytes for an rbuVfs-file. */ -static int rbuVfsSectorSize(tdsqlite3_file *pFile){ +static int rbuVfsSectorSize(sqlite3_file *pFile){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xSectorSize(p->pReal); } @@ -202253,7 +202253,7 @@ static int rbuVfsSectorSize(tdsqlite3_file *pFile){ /* ** Return the device characteristic flags supported by an rbuVfs-file. */ -static int rbuVfsDeviceCharacteristics(tdsqlite3_file *pFile){ +static int rbuVfsDeviceCharacteristics(sqlite3_file *pFile){ rbu_file *p = (rbu_file *)pFile; return p->pReal->pMethods->xDeviceCharacteristics(p->pReal); } @@ -202261,9 +202261,9 @@ static int rbuVfsDeviceCharacteristics(tdsqlite3_file *pFile){ /* ** Take or release a shared-memory lock. */ -static int rbuVfsShmLock(tdsqlite3_file *pFile, int ofst, int n, int flags){ +static int rbuVfsShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ rbu_file *p = (rbu_file*)pFile; - tdsqlite3rbu *pRbu = p->pRbu; + sqlite3rbu *pRbu = p->pRbu; int rc = SQLITE_OK; #ifdef SQLITE_AMALGAMATION @@ -202298,7 +202298,7 @@ static int rbuVfsShmLock(tdsqlite3_file *pFile, int ofst, int n, int flags){ ** Obtain a pointer to a mapping of a single 32KiB page of the *-shm file. */ static int rbuVfsShmMap( - tdsqlite3_file *pFile, + sqlite3_file *pFile, int iRegion, int szRegion, int isWrite, @@ -202313,8 +202313,8 @@ static int rbuVfsShmMap( ** instead of a file on disk. */ assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) ); if( eStage==RBU_STAGE_OAL ){ - tdsqlite3_int64 nByte = (iRegion+1) * sizeof(char*); - char **apNew = (char**)tdsqlite3_realloc64(p->apShm, nByte); + sqlite3_int64 nByte = (iRegion+1) * sizeof(char*); + char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte); /* This is an RBU connection that uses its own heap memory for the ** pages of the *-shm file. Since no other process can have run @@ -202330,7 +202330,7 @@ static int rbuVfsShmMap( } if( rc==SQLITE_OK ){ - char *pNew = (char*)tdsqlite3_malloc64(szRegion); + char *pNew = (char*)sqlite3_malloc64(szRegion); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ @@ -202355,7 +202355,7 @@ static int rbuVfsShmMap( /* ** Memory barrier. */ -static void rbuVfsShmBarrier(tdsqlite3_file *pFile){ +static void rbuVfsShmBarrier(sqlite3_file *pFile){ rbu_file *p = (rbu_file *)pFile; p->pReal->pMethods->xShmBarrier(p->pReal); } @@ -202363,7 +202363,7 @@ static void rbuVfsShmBarrier(tdsqlite3_file *pFile){ /* ** The xShmUnmap method. */ -static int rbuVfsShmUnmap(tdsqlite3_file *pFile, int delFlag){ +static int rbuVfsShmUnmap(sqlite3_file *pFile, int delFlag){ rbu_file *p = (rbu_file*)pFile; int rc = SQLITE_OK; int eStage = (p->pRbu ? p->pRbu->eStage : 0); @@ -202383,13 +202383,13 @@ static int rbuVfsShmUnmap(tdsqlite3_file *pFile, int delFlag){ ** Open an rbu file handle. */ static int rbuVfsOpen( - tdsqlite3_vfs *pVfs, + sqlite3_vfs *pVfs, const char *zName, - tdsqlite3_file *pFile, + sqlite3_file *pFile, int flags, int *pOutFlags ){ - static tdsqlite3_io_methods rbuvfs_io_methods = { + static sqlite3_io_methods rbuvfs_io_methods = { 2, /* iVersion */ rbuVfsClose, /* xClose */ rbuVfsRead, /* xRead */ @@ -202410,14 +202410,14 @@ static int rbuVfsOpen( 0, 0 /* xFetch, xUnfetch */ }; rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; - tdsqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; + sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; rbu_file *pFd = (rbu_file *)pFile; int rc = SQLITE_OK; const char *zOpen = zName; int oflags = flags; memset(pFd, 0, sizeof(rbu_file)); - pFd->pReal = (tdsqlite3_file*)&pFd[1]; + pFd->pReal = (sqlite3_file*)&pFd[1]; pFd->pRbuVfs = pRbuVfs; pFd->openFlags = flags; if( zName ){ @@ -202427,7 +202427,7 @@ static int rbuVfsOpen( ** the name of the *-wal file this db connection will use. SQLite ** happens to pass a pointer to this buffer when using xAccess() ** or xOpen() to operate on the *-wal file. */ - pFd->zWal = tdsqlite3_filename_wal(zName); + pFd->zWal = sqlite3_filename_wal(zName); } else if( flags & SQLITE_OPEN_WAL ){ rbu_file *pDb = rbuFindMaindb(pRbuVfs, zName, 0); @@ -202441,11 +202441,11 @@ static int rbuVfsOpen( size_t nCopy; char *zCopy; if( rbuIsVacuum(pDb->pRbu) ){ - zBase = tdsqlite3_db_filename(pDb->pRbu->dbRbu, "main"); - zBase = tdsqlite3_filename_wal(zBase); + zBase = sqlite3_db_filename(pDb->pRbu->dbRbu, "main"); + zBase = sqlite3_filename_wal(zBase); } nCopy = strlen(zBase); - zCopy = tdsqlite3_malloc64(nCopy+2); + zCopy = sqlite3_malloc64(nCopy+2); if( zCopy ){ memcpy(zCopy, zBase, nCopy); zCopy[nCopy-3] = 'o'; @@ -202465,7 +202465,7 @@ static int rbuVfsOpen( } if( oflags & SQLITE_OPEN_MAIN_DB - && tdsqlite3_uri_boolean(zName, "rbu_memory", 0) + && sqlite3_uri_boolean(zName, "rbu_memory", 0) ){ assert( oflags & SQLITE_OPEN_MAIN_DB ); oflags = SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | @@ -202477,7 +202477,7 @@ static int rbuVfsOpen( rc = pRealVfs->xOpen(pRealVfs, zOpen, pFd->pReal, oflags, pOutFlags); } if( pFd->pReal->pMethods ){ - /* The xOpen() operation has succeeded. Set the tdsqlite3_file.pMethods + /* The xOpen() operation has succeeded. Set the sqlite3_file.pMethods ** pointer and, if the file is a main database file, link it into the ** mutex protected linked list of all such files. */ pFile->pMethods = &rbuvfs_io_methods; @@ -202485,7 +202485,7 @@ static int rbuVfsOpen( rbuMainlistAdd(pFd); } }else{ - tdsqlite3_free(pFd->zDel); + sqlite3_free(pFd->zDel); } return rc; @@ -202494,8 +202494,8 @@ static int rbuVfsOpen( /* ** Delete the file located at zPath. */ -static int rbuVfsDelete(tdsqlite3_vfs *pVfs, const char *zPath, int dirSync){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; +static int rbuVfsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){ + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xDelete(pRealVfs, zPath, dirSync); } @@ -202504,13 +202504,13 @@ static int rbuVfsDelete(tdsqlite3_vfs *pVfs, const char *zPath, int dirSync){ ** is available, or false otherwise. */ static int rbuVfsAccess( - tdsqlite3_vfs *pVfs, + sqlite3_vfs *pVfs, const char *zPath, int flags, int *pResOut ){ rbu_vfs *pRbuVfs = (rbu_vfs*)pVfs; - tdsqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; + sqlite3_vfs *pRealVfs = pRbuVfs->pRealVfs; int rc; rc = pRealVfs->xAccess(pRealVfs, zPath, flags, pResOut); @@ -202536,7 +202536,7 @@ static int rbuVfsAccess( if( *pResOut ){ rc = SQLITE_CANTOPEN; }else{ - tdsqlite3_int64 sz = 0; + sqlite3_int64 sz = 0; rc = rbuVfsFileSize(&pDb->base, &sz); *pResOut = (sz>0); } @@ -202552,12 +202552,12 @@ static int rbuVfsAccess( ** of at least (DEVSYM_MAX_PATHNAME+1) bytes. */ static int rbuVfsFullPathname( - tdsqlite3_vfs *pVfs, + sqlite3_vfs *pVfs, const char *zPath, int nOut, char *zOut ){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xFullPathname(pRealVfs, zPath, nOut, zOut); } @@ -202565,8 +202565,8 @@ static int rbuVfsFullPathname( /* ** Open the dynamic library located at zPath and return a handle. */ -static void *rbuVfsDlOpen(tdsqlite3_vfs *pVfs, const char *zPath){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; +static void *rbuVfsDlOpen(sqlite3_vfs *pVfs, const char *zPath){ + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xDlOpen(pRealVfs, zPath); } @@ -202575,8 +202575,8 @@ static void *rbuVfsDlOpen(tdsqlite3_vfs *pVfs, const char *zPath){ ** utf-8 string describing the most recent error encountered associated ** with dynamic libraries. */ -static void rbuVfsDlError(tdsqlite3_vfs *pVfs, int nByte, char *zErrMsg){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; +static void rbuVfsDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){ + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; pRealVfs->xDlError(pRealVfs, nByte, zErrMsg); } @@ -202584,19 +202584,19 @@ static void rbuVfsDlError(tdsqlite3_vfs *pVfs, int nByte, char *zErrMsg){ ** Return a pointer to the symbol zSymbol in the dynamic library pHandle. */ static void (*rbuVfsDlSym( - tdsqlite3_vfs *pVfs, + sqlite3_vfs *pVfs, void *pArg, const char *zSym ))(void){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xDlSym(pRealVfs, pArg, zSym); } /* ** Close the dynamic library handle pHandle. */ -static void rbuVfsDlClose(tdsqlite3_vfs *pVfs, void *pHandle){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; +static void rbuVfsDlClose(sqlite3_vfs *pVfs, void *pHandle){ + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; pRealVfs->xDlClose(pRealVfs, pHandle); } #endif /* SQLITE_OMIT_LOAD_EXTENSION */ @@ -202605,8 +202605,8 @@ static void rbuVfsDlClose(tdsqlite3_vfs *pVfs, void *pHandle){ ** Populate the buffer pointed to by zBufOut with nByte bytes of ** random data. */ -static int rbuVfsRandomness(tdsqlite3_vfs *pVfs, int nByte, char *zBufOut){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; +static int rbuVfsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){ + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xRandomness(pRealVfs, nByte, zBufOut); } @@ -202614,36 +202614,36 @@ static int rbuVfsRandomness(tdsqlite3_vfs *pVfs, int nByte, char *zBufOut){ ** Sleep for nMicro microseconds. Return the number of microseconds ** actually slept. */ -static int rbuVfsSleep(tdsqlite3_vfs *pVfs, int nMicro){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; +static int rbuVfsSleep(sqlite3_vfs *pVfs, int nMicro){ + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xSleep(pRealVfs, nMicro); } /* ** Return the current time as a Julian Day number in *pTimeOut. */ -static int rbuVfsCurrentTime(tdsqlite3_vfs *pVfs, double *pTimeOut){ - tdsqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; +static int rbuVfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){ + sqlite3_vfs *pRealVfs = ((rbu_vfs*)pVfs)->pRealVfs; return pRealVfs->xCurrentTime(pRealVfs, pTimeOut); } /* ** No-op. */ -static int rbuVfsGetLastError(tdsqlite3_vfs *pVfs, int a, char *b){ +static int rbuVfsGetLastError(sqlite3_vfs *pVfs, int a, char *b){ return 0; } /* ** Deregister and destroy an RBU vfs created by an earlier call to -** tdsqlite3rbu_create_vfs(). +** sqlite3rbu_create_vfs(). */ -SQLITE_API void tdsqlite3rbu_destroy_vfs(const char *zName){ - tdsqlite3_vfs *pVfs = tdsqlite3_vfs_find(zName); +SQLITE_API void sqlite3rbu_destroy_vfs(const char *zName){ + sqlite3_vfs *pVfs = sqlite3_vfs_find(zName); if( pVfs && pVfs->xOpen==rbuVfsOpen ){ - tdsqlite3_mutex_free(((rbu_vfs*)pVfs)->mutex); - tdsqlite3_vfs_unregister(pVfs); - tdsqlite3_free(pVfs); + sqlite3_mutex_free(((rbu_vfs*)pVfs)->mutex); + sqlite3_vfs_unregister(pVfs); + sqlite3_free(pVfs); } } @@ -202652,10 +202652,10 @@ SQLITE_API void tdsqlite3rbu_destroy_vfs(const char *zName){ ** via existing VFS zParent. The new object is registered as a non-default ** VFS with SQLite before returning. */ -SQLITE_API int tdsqlite3rbu_create_vfs(const char *zName, const char *zParent){ +SQLITE_API int sqlite3rbu_create_vfs(const char *zName, const char *zParent){ /* Template for VFS */ - static tdsqlite3_vfs vfs_template = { + static sqlite3_vfs vfs_template = { 1, /* iVersion */ 0, /* szOsFile */ 0, /* mxPathname */ @@ -202691,18 +202691,18 @@ SQLITE_API int tdsqlite3rbu_create_vfs(const char *zName, const char *zParent){ nName = strlen(zName); nByte = sizeof(rbu_vfs) + nName + 1; - pNew = (rbu_vfs*)tdsqlite3_malloc64(nByte); + pNew = (rbu_vfs*)sqlite3_malloc64(nByte); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ - tdsqlite3_vfs *pParent; /* Parent VFS */ + sqlite3_vfs *pParent; /* Parent VFS */ memset(pNew, 0, nByte); - pParent = tdsqlite3_vfs_find(zParent); + pParent = sqlite3_vfs_find(zParent); if( pParent==0 ){ rc = SQLITE_NOTFOUND; }else{ char *zSpace; - memcpy(&pNew->base, &vfs_template, sizeof(tdsqlite3_vfs)); + memcpy(&pNew->base, &vfs_template, sizeof(sqlite3_vfs)); pNew->base.mxPathname = pParent->mxPathname; pNew->base.szOsFile = sizeof(rbu_file) + pParent->szOsFile; pNew->pRealVfs = pParent; @@ -202710,17 +202710,17 @@ SQLITE_API int tdsqlite3rbu_create_vfs(const char *zName, const char *zParent){ memcpy(zSpace, zName, nName); /* Allocate the mutex and register the new VFS (not as the default) */ - pNew->mutex = tdsqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); + pNew->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE); if( pNew->mutex==0 ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_vfs_register(&pNew->base, 0); + rc = sqlite3_vfs_register(&pNew->base, 0); } } if( rc!=SQLITE_OK ){ - tdsqlite3_mutex_free(pNew->mutex); - tdsqlite3_free(pNew); + sqlite3_mutex_free(pNew->mutex); + sqlite3_free(pNew); } } @@ -202730,14 +202730,14 @@ SQLITE_API int tdsqlite3rbu_create_vfs(const char *zName, const char *zParent){ /* ** Configure the aggregate temp file size limit for this RBU handle. */ -SQLITE_API tdsqlite3_int64 tdsqlite3rbu_temp_size_limit(tdsqlite3rbu *pRbu, tdsqlite3_int64 n){ +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size_limit(sqlite3rbu *pRbu, sqlite3_int64 n){ if( n>=0 ){ pRbu->szTempLimit = n; } return pRbu->szTempLimit; } -SQLITE_API tdsqlite3_int64 tdsqlite3rbu_temp_size(tdsqlite3rbu *pRbu){ +SQLITE_API sqlite3_int64 sqlite3rbu_temp_size(sqlite3rbu *pRbu){ return pRbu->szTemp; } @@ -202746,7 +202746,7 @@ SQLITE_API tdsqlite3_int64 tdsqlite3rbu_temp_size(tdsqlite3rbu *pRbu){ #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU) */ -/************** End of tdsqlite3rbu.c ******************************************/ +/************** End of sqlite3rbu.c ******************************************/ /************** Begin file dbstat.c ******************************************/ /* ** 2010 July 12 @@ -202764,7 +202764,7 @@ SQLITE_API tdsqlite3_int64 tdsqlite3rbu_temp_size(tdsqlite3rbu *pRbu){ ** ** The dbstat virtual table is used to extract low-level storage ** information from an SQLite database in order to implement the -** "tdsqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script +** "sqlite3_analyzer" utility. See the ../tool/spaceanal.tcl script ** for an example implementation. ** ** Additional information is available on the "dbstat.html" page of the @@ -202858,8 +202858,8 @@ struct StatPage { /* The cursor for scanning the dbstat virtual table */ struct StatCursor { - tdsqlite3_vtab_cursor base; /* base class. MUST BE FIRST! */ - tdsqlite3_stmt *pStmt; /* Iterates through set of root pages */ + sqlite3_vtab_cursor base; /* base class. MUST BE FIRST! */ + sqlite3_stmt *pStmt; /* Iterates through set of root pages */ u8 isEof; /* After pStmt has returned SQLITE_DONE */ u8 isAgg; /* Aggregate results for each table */ int iDb; /* Schema used for this query */ @@ -202883,8 +202883,8 @@ struct StatCursor { /* An instance of the DBSTAT virtual table */ struct StatTable { - tdsqlite3_vtab base; /* base class. MUST BE FIRST! */ - tdsqlite3 *db; /* Database connection that owns this vtab */ + sqlite3_vtab base; /* base class. MUST BE FIRST! */ + sqlite3 *db; /* Database connection that owns this vtab */ int iDb; /* Index of database to analyze */ }; @@ -202896,10 +202896,10 @@ struct StatTable { ** Connect to or create a new DBSTAT virtual table. */ static int statConnect( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ StatTable *pTab = 0; @@ -202908,19 +202908,19 @@ static int statConnect( if( argc>=4 ){ Token nm; - tdsqlite3TokenInit(&nm, (char*)argv[3]); - iDb = tdsqlite3FindDb(db, &nm); + sqlite3TokenInit(&nm, (char*)argv[3]); + iDb = sqlite3FindDb(db, &nm); if( iDb<0 ){ - *pzErr = tdsqlite3_mprintf("no such database: %s", argv[3]); + *pzErr = sqlite3_mprintf("no such database: %s", argv[3]); return SQLITE_ERROR; } }else{ iDb = 0; } - tdsqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); - rc = tdsqlite3_declare_vtab(db, zDbstatSchema); + sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); + rc = sqlite3_declare_vtab(db, zDbstatSchema); if( rc==SQLITE_OK ){ - pTab = (StatTable *)tdsqlite3_malloc64(sizeof(StatTable)); + pTab = (StatTable *)sqlite3_malloc64(sizeof(StatTable)); if( pTab==0 ) rc = SQLITE_NOMEM_BKPT; } @@ -202931,15 +202931,15 @@ static int statConnect( pTab->iDb = iDb; } - *ppVtab = (tdsqlite3_vtab*)pTab; + *ppVtab = (sqlite3_vtab*)pTab; return rc; } /* ** Disconnect from or destroy the DBSTAT virtual table. */ -static int statDisconnect(tdsqlite3_vtab *pVtab){ - tdsqlite3_free(pVtab); +static int statDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); return SQLITE_OK; } @@ -202953,7 +202953,7 @@ static int statDisconnect(tdsqlite3_vtab *pVtab){ ** 0x04 There is an aggregate=? term in the WHERE clause ** 0x08 Output should be ordered by name and path */ -static int statBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ +static int statBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; int iSchema = -1; int iName = -1; @@ -203025,11 +203025,11 @@ static int statBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ /* ** Open a new DBSTAT cursor. */ -static int statOpen(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCursor){ +static int statOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ StatTable *pTab = (StatTable *)pVTab; StatCursor *pCsr; - pCsr = (StatCursor *)tdsqlite3_malloc64(sizeof(StatCursor)); + pCsr = (StatCursor *)sqlite3_malloc64(sizeof(StatCursor)); if( pCsr==0 ){ return SQLITE_NOMEM_BKPT; }else{ @@ -203038,7 +203038,7 @@ static int statOpen(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCursor){ pCsr->iDb = pTab->iDb; } - *ppCursor = (tdsqlite3_vtab_cursor *)pCsr; + *ppCursor = (sqlite3_vtab_cursor *)pCsr; return SQLITE_OK; } @@ -203046,9 +203046,9 @@ static void statClearCells(StatPage *p){ int i; if( p->aCell ){ for(i=0; inCell; i++){ - tdsqlite3_free(p->aCell[i].aOvfl); + sqlite3_free(p->aCell[i].aOvfl); } - tdsqlite3_free(p->aCell); + sqlite3_free(p->aCell); } p->nCell = 0; p->aCell = 0; @@ -203056,19 +203056,19 @@ static void statClearCells(StatPage *p){ static void statClearPage(StatPage *p){ statClearCells(p); - tdsqlite3PagerUnref(p->pPg); - tdsqlite3_free(p->zPath); + sqlite3PagerUnref(p->pPg); + sqlite3_free(p->zPath); memset(p, 0, sizeof(StatPage)); } static void statResetCsr(StatCursor *pCsr){ int i; - tdsqlite3_reset(pCsr->pStmt); + sqlite3_reset(pCsr->pStmt); for(i=0; iaPage); i++){ statClearPage(&pCsr->aPage[i]); } pCsr->iPage = 0; - tdsqlite3_free(pCsr->zPath); + sqlite3_free(pCsr->zPath); pCsr->zPath = 0; pCsr->isEof = 0; } @@ -203086,11 +203086,11 @@ static void statResetCounts(StatCursor *pCsr){ /* ** Close a DBSTAT cursor. */ -static int statClose(tdsqlite3_vtab_cursor *pCursor){ +static int statClose(sqlite3_vtab_cursor *pCursor){ StatCursor *pCsr = (StatCursor *)pCursor; statResetCsr(pCsr); - tdsqlite3_finalize(pCsr->pStmt); - tdsqlite3_free(pCsr); + sqlite3_finalize(pCsr->pStmt); + sqlite3_free(pCsr); return SQLITE_OK; } @@ -203131,7 +203131,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ int isLeaf; int szPage; - u8 *aData = tdsqlite3PagerGetData(p->pPg); + u8 *aData = sqlite3PagerGetData(p->pPg); u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0]; p->flags = aHdr[0]; @@ -203147,7 +203147,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ if( p->iPgno==1 ) nHdr += 100; p->nCell = get2byte(&aHdr[3]); p->nMxPayload = 0; - szPage = tdsqlite3BtreeGetPageSize(pBt); + szPage = sqlite3BtreeGetPageSize(pBt); nUnused = get2byte(&aHdr[5]) - nHdr - 2*p->nCell; nUnused += (int)aHdr[7]; @@ -203161,16 +203161,16 @@ static int statDecodePage(Btree *pBt, StatPage *p){ iOff = iNext; } p->nUnused = nUnused; - p->iRightChildPg = isLeaf ? 0 : tdsqlite3Get4byte(&aHdr[8]); + p->iRightChildPg = isLeaf ? 0 : sqlite3Get4byte(&aHdr[8]); if( p->nCell ){ int i; /* Used to iterate through cells */ int nUsable; /* Usable bytes per page */ - tdsqlite3BtreeEnter(pBt); - nUsable = szPage - tdsqlite3BtreeGetReserveNoMutex(pBt); - tdsqlite3BtreeLeave(pBt); - p->aCell = tdsqlite3_malloc64((p->nCell+1) * sizeof(StatCell)); + sqlite3BtreeEnter(pBt); + nUsable = szPage - sqlite3BtreeGetReserveNoMutex(pBt); + sqlite3BtreeLeave(pBt); + p->aCell = sqlite3_malloc64((p->nCell+1) * sizeof(StatCell)); if( p->aCell==0 ) return SQLITE_NOMEM_BKPT; memset(p->aCell, 0, (p->nCell+1) * sizeof(StatCell)); @@ -203180,7 +203180,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ iOff = get2byte(&aData[nHdr+i*2]); if( iOff=szPage ) goto statPageIsCorrupt; if( !isLeaf ){ - pCell->iChildPg = tdsqlite3Get4byte(&aData[iOff]); + pCell->iChildPg = sqlite3Get4byte(&aData[iOff]); iOff += 4; } if( p->flags==0x05 ){ @@ -203191,7 +203191,7 @@ static int statDecodePage(Btree *pBt, StatPage *p){ iOff += getVarint32(&aData[iOff], nPayload); if( p->flags==0x0D ){ u64 dummy; - iOff += tdsqlite3GetVarint(&aData[iOff], &dummy); + iOff += sqlite3GetVarint(&aData[iOff], &dummy); } if( nPayload>(u32)p->nMxPayload ) p->nMxPayload = nPayload; nLocal = getLocalPayload(nUsable, p->flags, nPayload); @@ -203205,20 +203205,20 @@ static int statDecodePage(Btree *pBt, StatPage *p){ if( iOff+nLocal>nUsable ) goto statPageIsCorrupt; pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4); pCell->nOvfl = nOvfl; - pCell->aOvfl = tdsqlite3_malloc64(sizeof(u32)*nOvfl); + pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl); if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT; - pCell->aOvfl[0] = tdsqlite3Get4byte(&aData[iOff+nLocal]); + pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]); for(j=1; jaOvfl[j-1]; DbPage *pPg = 0; - rc = tdsqlite3PagerGet(tdsqlite3BtreePager(pBt), iPrev, &pPg, 0); + rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPrev, &pPg, 0); if( rc!=SQLITE_OK ){ assert( pPg==0 ); return rc; } - pCell->aOvfl[j] = tdsqlite3Get4byte(tdsqlite3PagerGetData(pPg)); - tdsqlite3PagerUnref(pPg); + pCell->aOvfl[j] = sqlite3Get4byte(sqlite3PagerGetData(pPg)); + sqlite3PagerUnref(pPg); } } } @@ -203238,23 +203238,23 @@ statPageIsCorrupt: ** the current value of pCsr->iPageno. */ static void statSizeAndOffset(StatCursor *pCsr){ - StatTable *pTab = (StatTable *)((tdsqlite3_vtab_cursor *)pCsr)->pVtab; + StatTable *pTab = (StatTable *)((sqlite3_vtab_cursor *)pCsr)->pVtab; Btree *pBt = pTab->db->aDb[pTab->iDb].pBt; - Pager *pPager = tdsqlite3BtreePager(pBt); - tdsqlite3_file *fd; - tdsqlite3_int64 x[2]; + Pager *pPager = sqlite3BtreePager(pBt); + sqlite3_file *fd; + sqlite3_int64 x[2]; /* If connected to a ZIPVFS backend, find the page size and ** offset from ZIPVFS. */ - fd = tdsqlite3PagerFile(pPager); + fd = sqlite3PagerFile(pPager); x[0] = pCsr->iPageno; - if( tdsqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ + if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){ pCsr->iOffset = x[0]; pCsr->szPage += x[1]; }else{ /* Not ZIPVFS: The default page size and offset */ - pCsr->szPage += tdsqlite3BtreeGetPageSize(pBt); + pCsr->szPage += sqlite3BtreeGetPageSize(pBt); pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1); } } @@ -203264,43 +203264,43 @@ static void statSizeAndOffset(StatCursor *pCsr){ ** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0), ** the next entry is the next btree. */ -static int statNext(tdsqlite3_vtab_cursor *pCursor){ +static int statNext(sqlite3_vtab_cursor *pCursor){ int rc; int nPayload; char *z; StatCursor *pCsr = (StatCursor *)pCursor; StatTable *pTab = (StatTable *)pCursor->pVtab; Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt; - Pager *pPager = tdsqlite3BtreePager(pBt); + Pager *pPager = sqlite3BtreePager(pBt); - tdsqlite3_free(pCsr->zPath); + sqlite3_free(pCsr->zPath); pCsr->zPath = 0; statNextRestart: if( pCsr->aPage[0].pPg==0 ){ /* Start measuring space on the next btree */ statResetCounts(pCsr); - rc = tdsqlite3_step(pCsr->pStmt); + rc = sqlite3_step(pCsr->pStmt); if( rc==SQLITE_ROW ){ int nPage; - u32 iRoot = (u32)tdsqlite3_column_int64(pCsr->pStmt, 1); - tdsqlite3PagerPagecount(pPager, &nPage); + u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1); + sqlite3PagerPagecount(pPager, &nPage); if( nPage==0 ){ pCsr->isEof = 1; - return tdsqlite3_reset(pCsr->pStmt); + return sqlite3_reset(pCsr->pStmt); } - rc = tdsqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0); + rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0); pCsr->aPage[0].iPgno = iRoot; pCsr->aPage[0].iCell = 0; if( !pCsr->isAgg ){ - pCsr->aPage[0].zPath = z = tdsqlite3_mprintf("/"); + pCsr->aPage[0].zPath = z = sqlite3_mprintf("/"); if( z==0 ) rc = SQLITE_NOMEM_BKPT; } pCsr->iPage = 0; pCsr->nPage = 1; }else{ pCsr->isEof = 1; - return tdsqlite3_reset(pCsr->pStmt); + return sqlite3_reset(pCsr->pStmt); } }else{ /* Continue analyzing the btree previously started */ @@ -203310,10 +203310,10 @@ statNextRestart: StatCell *pCell = &p->aCell[p->iCell]; while( pCell->iOvflnOvfl ){ int nUsable, iOvfl; - tdsqlite3BtreeEnter(pBt); - nUsable = tdsqlite3BtreeGetPageSize(pBt) - - tdsqlite3BtreeGetReserveNoMutex(pBt); - tdsqlite3BtreeLeave(pBt); + sqlite3BtreeEnter(pBt); + nUsable = sqlite3BtreeGetPageSize(pBt) - + sqlite3BtreeGetReserveNoMutex(pBt); + sqlite3BtreeLeave(pBt); pCsr->nPage++; statSizeAndOffset(pCsr); if( pCell->iOvflnOvfl-1 ){ @@ -203325,10 +203325,10 @@ statNextRestart: iOvfl = pCell->iOvfl; pCell->iOvfl++; if( !pCsr->isAgg ){ - pCsr->zName = (char *)tdsqlite3_column_text(pCsr->pStmt, 0); + pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); pCsr->iPageno = pCell->aOvfl[iOvfl]; pCsr->zPagetype = "overflow"; - pCsr->zPath = z = tdsqlite3_mprintf( + pCsr->zPath = z = sqlite3_mprintf( "%s%.3x+%.6x", p->zPath, p->iCell, iOvfl ); return z==0 ? SQLITE_NOMEM_BKPT : SQLITE_OK; @@ -203361,11 +203361,11 @@ statNextRestart: }else{ p[1].iPgno = p->aCell[p->iCell].iChildPg; } - rc = tdsqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0); + rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0); pCsr->nPage++; p[1].iCell = 0; if( !pCsr->isAgg ){ - p[1].zPath = z = tdsqlite3_mprintf("%s%.3x/", p->zPath, p->iCell); + p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell); if( z==0 ) rc = SQLITE_NOMEM_BKPT; } p->iCell++; @@ -203378,7 +203378,7 @@ statNextRestart: if( rc==SQLITE_OK ){ int i; StatPage *p = &pCsr->aPage[pCsr->iPage]; - pCsr->zName = (char *)tdsqlite3_column_text(pCsr->pStmt, 0); + pCsr->zName = (char *)sqlite3_column_text(pCsr->pStmt, 0); pCsr->iPageno = p->iPgno; rc = statDecodePage(pBt, p); @@ -203402,7 +203402,7 @@ statNextRestart: pCsr->nUnused += p->nUnused; if( p->nMxPayload>pCsr->nMxPayload ) pCsr->nMxPayload = p->nMxPayload; if( !pCsr->isAgg ){ - pCsr->zPath = z = tdsqlite3_mprintf("%s", p->zPath); + pCsr->zPath = z = sqlite3_mprintf("%s", p->zPath); if( z==0 ) rc = SQLITE_NOMEM_BKPT; } nPayload = 0; @@ -203421,7 +203421,7 @@ statNextRestart: return rc; } -static int statEof(tdsqlite3_vtab_cursor *pCursor){ +static int statEof(sqlite3_vtab_cursor *pCursor){ StatCursor *pCsr = (StatCursor *)pCursor; return pCsr->isEof; } @@ -203431,25 +203431,25 @@ static int statEof(tdsqlite3_vtab_cursor *pCursor){ ** meaning of the bits in idxNum. */ static int statFilter( - tdsqlite3_vtab_cursor *pCursor, + sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, - int argc, tdsqlite3_value **argv + int argc, sqlite3_value **argv ){ StatCursor *pCsr = (StatCursor *)pCursor; StatTable *pTab = (StatTable*)(pCursor->pVtab); - tdsqlite3_str *pSql; /* Query of btrees to analyze */ + sqlite3_str *pSql; /* Query of btrees to analyze */ char *zSql; /* String value of pSql */ int iArg = 0; /* Count of argv[] parameters used so far */ int rc = SQLITE_OK; /* Result of this operation */ const char *zName = 0; /* Only provide analysis of this table */ statResetCsr(pCsr); - tdsqlite3_finalize(pCsr->pStmt); + sqlite3_finalize(pCsr->pStmt); pCsr->pStmt = 0; if( idxNum & 0x01 ){ /* schema=? constraint is present. Get its value */ - const char *zDbase = (const char*)tdsqlite3_value_text(argv[iArg++]); - pCsr->iDb = tdsqlite3FindDbName(pTab->db, zDbase); + const char *zDbase = (const char*)sqlite3_value_text(argv[iArg++]); + pCsr->iDb = sqlite3FindDbName(pTab->db, zDbase); if( pCsr->iDb<0 ){ pCsr->iDb = 0; pCsr->isEof = 1; @@ -203460,16 +203460,16 @@ static int statFilter( } if( idxNum & 0x02 ){ /* name=? constraint is present */ - zName = (const char*)tdsqlite3_value_text(argv[iArg++]); + zName = (const char*)sqlite3_value_text(argv[iArg++]); } if( idxNum & 0x04 ){ /* aggregate=? constraint is present */ - pCsr->isAgg = tdsqlite3_value_double(argv[iArg++])!=0.0; + pCsr->isAgg = sqlite3_value_double(argv[iArg++])!=0.0; }else{ pCsr->isAgg = 0; } - pSql = tdsqlite3_str_new(pTab->db); - tdsqlite3_str_appendf(pSql, + pSql = sqlite3_str_new(pTab->db); + sqlite3_str_appendf(pSql, "SELECT * FROM (" "SELECT 'sqlite_master' AS name,1 AS rootpage,'table' AS type" " UNION ALL " @@ -203477,17 +203477,17 @@ static int statFilter( " FROM \"%w\".sqlite_master WHERE rootpage!=0)", pTab->db->aDb[pCsr->iDb].zDbSName); if( zName ){ - tdsqlite3_str_appendf(pSql, "WHERE name=%Q", zName); + sqlite3_str_appendf(pSql, "WHERE name=%Q", zName); } if( idxNum & 0x08 ){ - tdsqlite3_str_appendf(pSql, " ORDER BY name"); + sqlite3_str_appendf(pSql, " ORDER BY name"); } - zSql = tdsqlite3_str_finish(pSql); + zSql = sqlite3_str_finish(pSql); if( zSql==0 ){ return SQLITE_NOMEM_BKPT; }else{ - rc = tdsqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); - tdsqlite3_free(zSql); + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0); + sqlite3_free(zSql); } if( rc==SQLITE_OK ){ @@ -203497,67 +203497,67 @@ static int statFilter( } static int statColumn( - tdsqlite3_vtab_cursor *pCursor, - tdsqlite3_context *ctx, + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, int i ){ StatCursor *pCsr = (StatCursor *)pCursor; switch( i ){ case 0: /* name */ - tdsqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT); + sqlite3_result_text(ctx, pCsr->zName, -1, SQLITE_TRANSIENT); break; case 1: /* path */ if( !pCsr->isAgg ){ - tdsqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT); + sqlite3_result_text(ctx, pCsr->zPath, -1, SQLITE_TRANSIENT); } break; case 2: /* pageno */ if( pCsr->isAgg ){ - tdsqlite3_result_int64(ctx, pCsr->nPage); + sqlite3_result_int64(ctx, pCsr->nPage); }else{ - tdsqlite3_result_int64(ctx, pCsr->iPageno); + sqlite3_result_int64(ctx, pCsr->iPageno); } break; case 3: /* pagetype */ if( !pCsr->isAgg ){ - tdsqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, pCsr->zPagetype, -1, SQLITE_STATIC); } break; case 4: /* ncell */ - tdsqlite3_result_int(ctx, pCsr->nCell); + sqlite3_result_int(ctx, pCsr->nCell); break; case 5: /* payload */ - tdsqlite3_result_int(ctx, pCsr->nPayload); + sqlite3_result_int(ctx, pCsr->nPayload); break; case 6: /* unused */ - tdsqlite3_result_int(ctx, pCsr->nUnused); + sqlite3_result_int(ctx, pCsr->nUnused); break; case 7: /* mx_payload */ - tdsqlite3_result_int(ctx, pCsr->nMxPayload); + sqlite3_result_int(ctx, pCsr->nMxPayload); break; case 8: /* pgoffset */ if( !pCsr->isAgg ){ - tdsqlite3_result_int64(ctx, pCsr->iOffset); + sqlite3_result_int64(ctx, pCsr->iOffset); } break; case 9: /* pgsize */ - tdsqlite3_result_int(ctx, pCsr->szPage); + sqlite3_result_int(ctx, pCsr->szPage); break; case 10: { /* schema */ - tdsqlite3 *db = tdsqlite3_context_db_handle(ctx); + sqlite3 *db = sqlite3_context_db_handle(ctx); int iDb = pCsr->iDb; - tdsqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC); + sqlite3_result_text(ctx, db->aDb[iDb].zDbSName, -1, SQLITE_STATIC); break; } default: { /* aggregate */ - tdsqlite3_result_int(ctx, pCsr->isAgg); + sqlite3_result_int(ctx, pCsr->isAgg); break; } } return SQLITE_OK; } -static int statRowid(tdsqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ +static int statRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ StatCursor *pCsr = (StatCursor *)pCursor; *pRowid = pCsr->iPageno; return SQLITE_OK; @@ -203566,8 +203566,8 @@ static int statRowid(tdsqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ /* ** Invoke this routine to register the "dbstat" virtual table module */ -SQLITE_PRIVATE int tdsqlite3DbstatRegister(tdsqlite3 *db){ - static tdsqlite3_module dbstat_module = { +SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ + static sqlite3_module dbstat_module = { 0, /* iVersion */ statConnect, /* xCreate */ statConnect, /* xConnect */ @@ -203593,10 +203593,10 @@ SQLITE_PRIVATE int tdsqlite3DbstatRegister(tdsqlite3 *db){ 0, /* xRollbackTo */ 0 /* xShadowName */ }; - return tdsqlite3_create_module(db, "dbstat", &dbstat_module, 0); + return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); } #elif defined(SQLITE_ENABLE_DBSTAT_VTAB) -SQLITE_PRIVATE int tdsqlite3DbstatRegister(tdsqlite3 *db){ return SQLITE_OK; } +SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; } #endif /* SQLITE_ENABLE_DBSTAT_VTAB */ /************** End of dbstat.c **********************************************/ @@ -203642,7 +203642,7 @@ typedef struct DbpageTable DbpageTable; typedef struct DbpageCursor DbpageCursor; struct DbpageCursor { - tdsqlite3_vtab_cursor base; /* Base class. Must be first */ + sqlite3_vtab_cursor base; /* Base class. Must be first */ int pgno; /* Current page number */ int mxPgno; /* Last page to visit on this scan */ Pager *pPager; /* Pager being read/written */ @@ -203652,8 +203652,8 @@ struct DbpageCursor { }; struct DbpageTable { - tdsqlite3_vtab base; /* Base class. Must be first */ - tdsqlite3 *db; /* The database */ + sqlite3_vtab base; /* Base class. Must be first */ + sqlite3 *db; /* The database */ }; /* Columns */ @@ -203667,20 +203667,20 @@ struct DbpageTable { ** Connect to or create a dbpagevfs virtual table. */ static int dbpageConnect( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ DbpageTable *pTab = 0; int rc = SQLITE_OK; - tdsqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); - rc = tdsqlite3_declare_vtab(db, + sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY); + rc = sqlite3_declare_vtab(db, "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)"); if( rc==SQLITE_OK ){ - pTab = (DbpageTable *)tdsqlite3_malloc64(sizeof(DbpageTable)); + pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable)); if( pTab==0 ) rc = SQLITE_NOMEM_BKPT; } @@ -203690,15 +203690,15 @@ static int dbpageConnect( pTab->db = db; } - *ppVtab = (tdsqlite3_vtab*)pTab; + *ppVtab = (sqlite3_vtab*)pTab; return rc; } /* ** Disconnect from or destroy a dbpagevfs virtual table. */ -static int dbpageDisconnect(tdsqlite3_vtab *pVtab){ - tdsqlite3_free(pVtab); +static int dbpageDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); return SQLITE_OK; } @@ -203710,7 +203710,7 @@ static int dbpageDisconnect(tdsqlite3_vtab *pVtab){ ** 2 schema=?1, full table scan ** 3 schema=?1, pgno=?2 */ -static int dbpageBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ +static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ int i; int iPlan = 0; @@ -203719,7 +203719,7 @@ static int dbpageBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ ** unavailable */ for(i=0; inConstraint; i++){ - struct tdsqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; if( p->iColumn!=DBPAGE_COLUMN_SCHEMA ) continue; if( p->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue; if( !p->usable ){ @@ -203740,7 +203740,7 @@ static int dbpageBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ /* Check for constraints against pgno */ for(i=0; inConstraint; i++){ - struct tdsqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; + struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i]; if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){ pIdxInfo->estimatedRows = 1; pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE; @@ -203765,10 +203765,10 @@ static int dbpageBestIndex(tdsqlite3_vtab *tab, tdsqlite3_index_info *pIdxInfo){ /* ** Open a new dbpagevfs cursor. */ -static int dbpageOpen(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCursor){ +static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ DbpageCursor *pCsr; - pCsr = (DbpageCursor *)tdsqlite3_malloc64(sizeof(DbpageCursor)); + pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor)); if( pCsr==0 ){ return SQLITE_NOMEM_BKPT; }else{ @@ -203777,31 +203777,31 @@ static int dbpageOpen(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCursor){ pCsr->pgno = -1; } - *ppCursor = (tdsqlite3_vtab_cursor *)pCsr; + *ppCursor = (sqlite3_vtab_cursor *)pCsr; return SQLITE_OK; } /* ** Close a dbpagevfs cursor. */ -static int dbpageClose(tdsqlite3_vtab_cursor *pCursor){ +static int dbpageClose(sqlite3_vtab_cursor *pCursor){ DbpageCursor *pCsr = (DbpageCursor *)pCursor; - if( pCsr->pPage1 ) tdsqlite3PagerUnrefPageOne(pCsr->pPage1); - tdsqlite3_free(pCsr); + if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1); + sqlite3_free(pCsr); return SQLITE_OK; } /* ** Move a dbpagevfs cursor to the next entry in the file. */ -static int dbpageNext(tdsqlite3_vtab_cursor *pCursor){ +static int dbpageNext(sqlite3_vtab_cursor *pCursor){ int rc = SQLITE_OK; DbpageCursor *pCsr = (DbpageCursor *)pCursor; pCsr->pgno++; return rc; } -static int dbpageEof(tdsqlite3_vtab_cursor *pCursor){ +static int dbpageEof(sqlite3_vtab_cursor *pCursor){ DbpageCursor *pCsr = (DbpageCursor *)pCursor; return pCsr->pgno > pCsr->mxPgno; } @@ -203817,14 +203817,14 @@ static int dbpageEof(tdsqlite3_vtab_cursor *pCursor){ ** idxStr is not used */ static int dbpageFilter( - tdsqlite3_vtab_cursor *pCursor, + sqlite3_vtab_cursor *pCursor, int idxNum, const char *idxStr, - int argc, tdsqlite3_value **argv + int argc, sqlite3_value **argv ){ DbpageCursor *pCsr = (DbpageCursor *)pCursor; DbpageTable *pTab = (DbpageTable *)pCursor->pVtab; int rc; - tdsqlite3 *db = pTab->db; + sqlite3 *db = pTab->db; Btree *pBt; /* Default setting is no rows of result */ @@ -203834,20 +203834,20 @@ static int dbpageFilter( if( idxNum & 2 ){ const char *zSchema; assert( argc>=1 ); - zSchema = (const char*)tdsqlite3_value_text(argv[0]); - pCsr->iDb = tdsqlite3FindDbName(db, zSchema); + zSchema = (const char*)sqlite3_value_text(argv[0]); + pCsr->iDb = sqlite3FindDbName(db, zSchema); if( pCsr->iDb<0 ) return SQLITE_OK; }else{ pCsr->iDb = 0; } pBt = db->aDb[pCsr->iDb].pBt; if( pBt==0 ) return SQLITE_OK; - pCsr->pPager = tdsqlite3BtreePager(pBt); - pCsr->szPage = tdsqlite3BtreeGetPageSize(pBt); - pCsr->mxPgno = tdsqlite3BtreeLastPage(pBt); + pCsr->pPager = sqlite3BtreePager(pBt); + pCsr->szPage = sqlite3BtreeGetPageSize(pBt); + pCsr->mxPgno = sqlite3BtreeLastPage(pBt); if( idxNum & 1 ){ assert( argc>(idxNum>>1) ); - pCsr->pgno = tdsqlite3_value_int(argv[idxNum>>1]); + pCsr->pgno = sqlite3_value_int(argv[idxNum>>1]); if( pCsr->pgno<1 || pCsr->pgno>pCsr->mxPgno ){ pCsr->pgno = 1; pCsr->mxPgno = 0; @@ -203857,52 +203857,52 @@ static int dbpageFilter( }else{ assert( pCsr->pgno==1 ); } - if( pCsr->pPage1 ) tdsqlite3PagerUnrefPageOne(pCsr->pPage1); - rc = tdsqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0); + if( pCsr->pPage1 ) sqlite3PagerUnrefPageOne(pCsr->pPage1); + rc = sqlite3PagerGet(pCsr->pPager, 1, &pCsr->pPage1, 0); return rc; } static int dbpageColumn( - tdsqlite3_vtab_cursor *pCursor, - tdsqlite3_context *ctx, + sqlite3_vtab_cursor *pCursor, + sqlite3_context *ctx, int i ){ DbpageCursor *pCsr = (DbpageCursor *)pCursor; int rc = SQLITE_OK; switch( i ){ case 0: { /* pgno */ - tdsqlite3_result_int(ctx, pCsr->pgno); + sqlite3_result_int(ctx, pCsr->pgno); break; } case 1: { /* data */ DbPage *pDbPage = 0; - rc = tdsqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); + rc = sqlite3PagerGet(pCsr->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ - tdsqlite3_result_blob(ctx, tdsqlite3PagerGetData(pDbPage), pCsr->szPage, + sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pCsr->szPage, SQLITE_TRANSIENT); } - tdsqlite3PagerUnref(pDbPage); + sqlite3PagerUnref(pDbPage); break; } default: { /* schema */ - tdsqlite3 *db = tdsqlite3_context_db_handle(ctx); - tdsqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC); + sqlite3 *db = sqlite3_context_db_handle(ctx); + sqlite3_result_text(ctx, db->aDb[pCsr->iDb].zDbSName, -1, SQLITE_STATIC); break; } } return SQLITE_OK; } -static int dbpageRowid(tdsqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ +static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ DbpageCursor *pCsr = (DbpageCursor *)pCursor; *pRowid = pCsr->pgno; return SQLITE_OK; } static int dbpageUpdate( - tdsqlite3_vtab *pVtab, + sqlite3_vtab *pVtab, int argc, - tdsqlite3_value **argv, + sqlite3_value **argv, sqlite_int64 *pRowid ){ DbpageTable *pTab = (DbpageTable *)pVtab; @@ -203924,45 +203924,45 @@ static int dbpageUpdate( zErr = "cannot delete"; goto update_fail; } - pgno = tdsqlite3_value_int(argv[0]); - if( (Pgno)tdsqlite3_value_int(argv[1])!=pgno ){ + pgno = sqlite3_value_int(argv[0]); + if( (Pgno)sqlite3_value_int(argv[1])!=pgno ){ zErr = "cannot insert"; goto update_fail; } - zSchema = (const char*)tdsqlite3_value_text(argv[4]); - iDb = zSchema ? tdsqlite3FindDbName(pTab->db, zSchema) : -1; + zSchema = (const char*)sqlite3_value_text(argv[4]); + iDb = zSchema ? sqlite3FindDbName(pTab->db, zSchema) : -1; if( iDb<0 ){ zErr = "no such schema"; goto update_fail; } pBt = pTab->db->aDb[iDb].pBt; - if( pgno<1 || pBt==0 || pgno>(int)tdsqlite3BtreeLastPage(pBt) ){ + if( pgno<1 || pBt==0 || pgno>(int)sqlite3BtreeLastPage(pBt) ){ zErr = "bad page number"; goto update_fail; } - szPage = tdsqlite3BtreeGetPageSize(pBt); - if( tdsqlite3_value_type(argv[3])!=SQLITE_BLOB - || tdsqlite3_value_bytes(argv[3])!=szPage + szPage = sqlite3BtreeGetPageSize(pBt); + if( sqlite3_value_type(argv[3])!=SQLITE_BLOB + || sqlite3_value_bytes(argv[3])!=szPage ){ zErr = "bad page value"; goto update_fail; } - pPager = tdsqlite3BtreePager(pBt); - rc = tdsqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); + pPager = sqlite3BtreePager(pBt); + rc = sqlite3PagerGet(pPager, pgno, (DbPage**)&pDbPage, 0); if( rc==SQLITE_OK ){ - rc = tdsqlite3PagerWrite(pDbPage); + rc = sqlite3PagerWrite(pDbPage); if( rc==SQLITE_OK ){ - memcpy(tdsqlite3PagerGetData(pDbPage), - tdsqlite3_value_blob(argv[3]), + memcpy(sqlite3PagerGetData(pDbPage), + sqlite3_value_blob(argv[3]), szPage); } } - tdsqlite3PagerUnref(pDbPage); + sqlite3PagerUnref(pDbPage); return rc; update_fail: - tdsqlite3_free(pVtab->zErrMsg); - pVtab->zErrMsg = tdsqlite3_mprintf("%s", zErr); + sqlite3_free(pVtab->zErrMsg); + pVtab->zErrMsg = sqlite3_mprintf("%s", zErr); return SQLITE_ERROR; } @@ -203970,13 +203970,13 @@ update_fail: ** written by the sqlite_dbpage virtual table, start a write transaction ** on them all. */ -static int dbpageBegin(tdsqlite3_vtab *pVtab){ +static int dbpageBegin(sqlite3_vtab *pVtab){ DbpageTable *pTab = (DbpageTable *)pVtab; - tdsqlite3 *db = pTab->db; + sqlite3 *db = pTab->db; int i; for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; - if( pBt ) tdsqlite3BtreeBeginTrans(pBt, 1, 0); + if( pBt ) sqlite3BtreeBeginTrans(pBt, 1, 0); } return SQLITE_OK; } @@ -203985,8 +203985,8 @@ static int dbpageBegin(tdsqlite3_vtab *pVtab){ /* ** Invoke this routine to register the "dbpage" virtual table module */ -SQLITE_PRIVATE int tdsqlite3DbpageRegister(tdsqlite3 *db){ - static tdsqlite3_module dbpage_module = { +SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ + static sqlite3_module dbpage_module = { 0, /* iVersion */ dbpageConnect, /* xCreate */ dbpageConnect, /* xConnect */ @@ -204012,17 +204012,17 @@ SQLITE_PRIVATE int tdsqlite3DbpageRegister(tdsqlite3 *db){ 0, /* xRollbackTo */ 0 /* xShadowName */ }; - return tdsqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); + return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); } #elif defined(SQLITE_ENABLE_DBPAGE_VTAB) -SQLITE_PRIVATE int tdsqlite3DbpageRegister(tdsqlite3 *db){ return SQLITE_OK; } +SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; } #endif /* SQLITE_ENABLE_DBSTAT_VTAB */ /************** End of dbpage.c **********************************************/ -/************** Begin file tdsqlite3session.c **********************************/ +/************** Begin file sqlite3session.c **********************************/ #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK) -/* #include "tdsqlite3session.h" */ +/* #include "sqlite3session.h" */ /* #include */ /* #include */ @@ -204052,8 +204052,8 @@ static int sessions_strm_chunk_size = SESSIONS_STRM_CHUNK_SIZE; typedef struct SessionHook SessionHook; struct SessionHook { void *pCtx; - int (*xOld)(void*,int,tdsqlite3_value**); - int (*xNew)(void*,int,tdsqlite3_value**); + int (*xOld)(void*,int,sqlite3_value**); + int (*xNew)(void*,int,sqlite3_value**); int (*xCount)(void*); int (*xDepth)(void*); }; @@ -204061,8 +204061,8 @@ struct SessionHook { /* ** Session handle structure. */ -struct tdsqlite3_session { - tdsqlite3 *db; /* Database handle session is attached to */ +struct sqlite3_session { + sqlite3 *db; /* Database handle session is attached to */ char *zDb; /* Name of database session is attached to */ int bEnable; /* True if currently recording */ int bIndirect; /* True if all changes are indirect */ @@ -204070,8 +204070,8 @@ struct tdsqlite3_session { int rc; /* Non-zero if an error has occurred */ void *pFilterCtx; /* First argument to pass to xTableFilter */ int (*xTableFilter)(void *pCtx, const char *zTab); - tdsqlite3_value *pZeroBlob; /* Value containing X'' */ - tdsqlite3_session *pNext; /* Next session object on same db. */ + sqlite3_value *pZeroBlob; /* Value containing X'' */ + sqlite3_session *pNext; /* Next session object on same db. */ SessionTable *pTable; /* List of attached tables */ SessionHook hook; /* APIs to grab new and old data with */ }; @@ -204088,8 +204088,8 @@ struct SessionBuffer { /* ** An object of this type is used internally as an abstraction for ** input data. Input data may be supplied either as a single large buffer -** (e.g. tdsqlite3changeset_start()) or using a stream function (e.g. -** tdsqlite3changeset_start_strm()). +** (e.g. sqlite3changeset_start()) or using a stream function (e.g. +** sqlite3changeset_start_strm()). */ struct SessionInput { int bNoDiscard; /* If true, do not discard in InputBuffer() */ @@ -204107,25 +204107,25 @@ struct SessionInput { /* ** Structure for changeset iterators. */ -struct tdsqlite3_changeset_iter { +struct sqlite3_changeset_iter { SessionInput in; /* Input buffer or stream */ SessionBuffer tblhdr; /* Buffer to hold apValue/zTab/abPK/ */ int bPatchset; /* True if this is a patchset */ int bInvert; /* True to invert changeset */ int rc; /* Iterator error code */ - tdsqlite3_stmt *pConflict; /* Points to conflicting row, if any */ + sqlite3_stmt *pConflict; /* Points to conflicting row, if any */ char *zTab; /* Current table */ int nCol; /* Number of columns in zTab */ int op; /* Current operation */ int bIndirect; /* True if current change was indirect */ u8 *abPK; /* Primary key array */ - tdsqlite3_value **apValue; /* old.* and new.* values */ + sqlite3_value **apValue; /* old.* and new.* values */ }; /* ** Each session object maintains a set of the following structures, one ** for each table the session object is monitoring. The structures are -** stored in a linked list starting at tdsqlite3_session.pTable. +** stored in a linked list starting at sqlite3_session.pTable. ** ** The keys of the SessionTable.aChange[] hash table are all rows that have ** been modified in any way since the session object was attached to the @@ -204271,8 +204271,8 @@ struct SessionTable { ** ** REBASE BLOB FORMAT: ** -** A rebase blob may be output by tdsqlite3changeset_apply_v2() and its -** streaming equivalent for use with the tdsqlite3_rebaser APIs to rebase +** A rebase blob may be output by sqlite3changeset_apply_v2() and its +** streaming equivalent for use with the sqlite3_rebaser APIs to rebase ** existing changesets. A rebase blob contains one entry for each conflict ** resolved using either the OMIT or REPLACE strategies within the apply_v2() ** call. @@ -204330,7 +204330,7 @@ static int sessionVarintPut(u8 *aBuf, int iVal){ ** Return the number of bytes required to store value iVal as a varint. */ static int sessionVarintLen(int iVal){ - return tdsqlite3VarintLen(iVal); + return sqlite3VarintLen(iVal); } /* @@ -204348,17 +204348,17 @@ static int sessionVarintGet(u8 *aBuf, int *piVal){ ** Read a 64-bit big-endian integer value from buffer aRec[]. Return ** the value read. */ -static tdsqlite3_int64 sessionGetI64(u8 *aRec){ +static sqlite3_int64 sessionGetI64(u8 *aRec){ u64 x = SESSION_UINT32(aRec); u32 y = SESSION_UINT32(aRec+4); x = (x<<32) + y; - return (tdsqlite3_int64)x; + return (sqlite3_int64)x; } /* ** Write a 64-bit big-endian integer value to the buffer aBuf[]. */ -static void sessionPutI64(u8 *aBuf, tdsqlite3_int64 i){ +static void sessionPutI64(u8 *aBuf, sqlite3_int64 i){ aBuf[0] = (i>>56) & 0xFF; aBuf[1] = (i>>48) & 0xFF; aBuf[2] = (i>>40) & 0xFF; @@ -204379,20 +204379,20 @@ static void sessionPutI64(u8 *aBuf, tdsqlite3_int64 i){ ** set *pnWrite. ** ** If no error occurs, SQLITE_OK is returned. Or, if an OOM error occurs -** within a call to tdsqlite3_value_text() (may fail if the db is utf-16)) +** within a call to sqlite3_value_text() (may fail if the db is utf-16)) ** SQLITE_NOMEM is returned. */ static int sessionSerializeValue( u8 *aBuf, /* If non-NULL, write serialized value here */ - tdsqlite3_value *pValue, /* Value to serialize */ - tdsqlite3_int64 *pnWrite /* IN/OUT: Increment by bytes written */ + sqlite3_value *pValue, /* Value to serialize */ + sqlite3_int64 *pnWrite /* IN/OUT: Increment by bytes written */ ){ int nByte; /* Size of serialized value in bytes */ if( pValue ){ int eType; /* Value type (SQLITE_NULL, TEXT etc.) */ - eType = tdsqlite3_value_type(pValue); + eType = sqlite3_value_type(pValue); if( aBuf ) aBuf[0] = eType; switch( eType ){ @@ -204408,11 +204408,11 @@ static int sessionSerializeValue( ** too. */ u64 i; if( eType==SQLITE_INTEGER ){ - i = (u64)tdsqlite3_value_int64(pValue); + i = (u64)sqlite3_value_int64(pValue); }else{ double r; assert( sizeof(double)==8 && sizeof(u64)==8 ); - r = tdsqlite3_value_double(pValue); + r = sqlite3_value_double(pValue); memcpy(&i, &r, 8); } sessionPutI64(&aBuf[1], i); @@ -204427,11 +204427,11 @@ static int sessionSerializeValue( assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); if( eType==SQLITE_TEXT ){ - z = (u8 *)tdsqlite3_value_text(pValue); + z = (u8 *)sqlite3_value_text(pValue); }else{ - z = (u8 *)tdsqlite3_value_blob(pValue); + z = (u8 *)sqlite3_value_blob(pValue); } - n = tdsqlite3_value_bytes(pValue); + n = sqlite3_value_bytes(pValue); if( z==0 && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; nVarint = sessionVarintLen(n); @@ -204510,7 +204510,7 @@ static unsigned int sessionHashAppendType(unsigned int h, int eType){ ** and the output variables are set as described above. */ static int sessionPreupdateHash( - tdsqlite3_session *pSession, /* Session object that owns pTab */ + sqlite3_session *pSession, /* Session object that owns pTab */ SessionTable *pTab, /* Session table handle */ int bNew, /* True to hash the new.* PK */ int *piHash, /* OUT: Hash value */ @@ -204525,7 +204525,7 @@ static int sessionPreupdateHash( if( pTab->abPK[i] ){ int rc; int eType; - tdsqlite3_value *pVal; + sqlite3_value *pVal; if( bNew ){ rc = pSession->hook.xNew(pSession->hook.pCtx, i, &pVal); @@ -204534,14 +204534,14 @@ static int sessionPreupdateHash( } if( rc!=SQLITE_OK ) return rc; - eType = tdsqlite3_value_type(pVal); + eType = sqlite3_value_type(pVal); h = sessionHashAppendType(h, eType); if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ i64 iVal; if( eType==SQLITE_INTEGER ){ - iVal = tdsqlite3_value_int64(pVal); + iVal = sqlite3_value_int64(pVal); }else{ - double rVal = tdsqlite3_value_double(pVal); + double rVal = sqlite3_value_double(pVal); assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); memcpy(&iVal, &rVal, 8); } @@ -204550,11 +204550,11 @@ static int sessionPreupdateHash( const u8 *z; int n; if( eType==SQLITE_TEXT ){ - z = (const u8 *)tdsqlite3_value_text(pVal); + z = (const u8 *)sqlite3_value_text(pVal); }else{ - z = (const u8 *)tdsqlite3_value_blob(pVal); + z = (const u8 *)sqlite3_value_blob(pVal); } - n = tdsqlite3_value_bytes(pVal); + n = sqlite3_value_bytes(pVal); if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM; h = sessionHashAppendBlob(h, n, z); }else{ @@ -204842,7 +204842,7 @@ static int sessionMergeUpdate( ** false. */ static int sessionPreupdateEqual( - tdsqlite3_session *pSession, /* Session object that owns SessionTable */ + sqlite3_session *pSession, /* Session object that owns SessionTable */ SessionTable *pTab, /* Table associated with change */ SessionChange *pChange, /* Change to compare to */ int op /* Current pre-update operation */ @@ -204855,7 +204855,7 @@ static int sessionPreupdateEqual( if( !pTab->abPK[iCol] ){ a += sessionSerialLen(a); }else{ - tdsqlite3_value *pVal; /* Value returned by preupdate_new/old */ + sqlite3_value *pVal; /* Value returned by preupdate_new/old */ int rc; /* Error code from preupdate_new/old */ int eType = *a++; /* Type of value from change record */ @@ -204872,7 +204872,7 @@ static int sessionPreupdateEqual( rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal); } assert( rc==SQLITE_OK ); - if( tdsqlite3_value_type(pVal)!=eType ) return 0; + if( sqlite3_value_type(pVal)!=eType ) return 0; /* A SessionChange object never has a NULL value in a PK column */ assert( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT @@ -204883,22 +204883,22 @@ static int sessionPreupdateEqual( i64 iVal = sessionGetI64(a); a += 8; if( eType==SQLITE_INTEGER ){ - if( tdsqlite3_value_int64(pVal)!=iVal ) return 0; + if( sqlite3_value_int64(pVal)!=iVal ) return 0; }else{ double rVal; assert( sizeof(iVal)==8 && sizeof(rVal)==8 ); memcpy(&rVal, &iVal, 8); - if( tdsqlite3_value_double(pVal)!=rVal ) return 0; + if( sqlite3_value_double(pVal)!=rVal ) return 0; } }else{ int n; const u8 *z; a += sessionVarintGet(a, &n); - if( tdsqlite3_value_bytes(pVal)!=n ) return 0; + if( sqlite3_value_bytes(pVal)!=n ) return 0; if( eType==SQLITE_TEXT ){ - z = tdsqlite3_value_text(pVal); + z = sqlite3_value_text(pVal); }else{ - z = tdsqlite3_value_blob(pVal); + z = sqlite3_value_blob(pVal); } if( n>0 && memcmp(a, z, n) ) return 0; a += n; @@ -204924,9 +204924,9 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){ int i; SessionChange **apNew; - tdsqlite3_int64 nNew = 2*(tdsqlite3_int64)(pTab->nChange ? pTab->nChange : 128); + sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128); - apNew = (SessionChange **)tdsqlite3_malloc64(sizeof(SessionChange *) * nNew); + apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew); if( apNew==0 ){ if( pTab->nChange==0 ){ return SQLITE_ERROR; @@ -204947,7 +204947,7 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ } } - tdsqlite3_free(pTab->apChange); + sqlite3_free(pTab->apChange); pTab->nChange = nNew; pTab->apChange = apNew; } @@ -204978,10 +204978,10 @@ static int sessionGrowHash(int bPatchset, SessionTable *pTab){ ** *pabPK = {1, 0, 0, 1} ** ** All returned buffers are part of the same single allocation, which must -** be freed using tdsqlite3_free() by the caller +** be freed using sqlite3_free() by the caller */ static int sessionTableInfo( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ const char *zDb, /* Name of attached database (e.g. "main") */ const char *zThis, /* Table name */ int *pnCol, /* OUT: number of columns */ @@ -204990,9 +204990,9 @@ static int sessionTableInfo( u8 **pabPK /* OUT: Array of booleans - true for PK col */ ){ char *zPragma; - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; int rc; - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; int nDbCol = 0; int nThis; int i; @@ -205002,40 +205002,40 @@ static int sessionTableInfo( assert( pazCol && pabPK ); - nThis = tdsqlite3Strlen30(zThis); - if( nThis==12 && 0==tdsqlite3_stricmp("sqlite_stat1", zThis) ){ - rc = tdsqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0); + nThis = sqlite3Strlen30(zThis); + if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){ + rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0); if( rc==SQLITE_OK ){ /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */ - zPragma = tdsqlite3_mprintf( + zPragma = sqlite3_mprintf( "SELECT 0, 'tbl', '', 0, '', 1 UNION ALL " "SELECT 1, 'idx', '', 0, '', 2 UNION ALL " "SELECT 2, 'stat', '', 0, '', 0" ); }else if( rc==SQLITE_ERROR ){ - zPragma = tdsqlite3_mprintf(""); + zPragma = sqlite3_mprintf(""); }else{ return rc; } }else{ - zPragma = tdsqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); + zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); } if( !zPragma ) return SQLITE_NOMEM; - rc = tdsqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); - tdsqlite3_free(zPragma); + rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); + sqlite3_free(zPragma); if( rc!=SQLITE_OK ) return rc; nByte = nThis + 1; - while( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - nByte += tdsqlite3_column_bytes(pStmt, 1); + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + nByte += sqlite3_column_bytes(pStmt, 1); nDbCol++; } - rc = tdsqlite3_reset(pStmt); + rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ){ nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); - pAlloc = tdsqlite3_malloc64(nByte); + pAlloc = sqlite3_malloc64(nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; } @@ -205052,17 +205052,17 @@ static int sessionTableInfo( } i = 0; - while( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - int nName = tdsqlite3_column_bytes(pStmt, 1); - const unsigned char *zName = tdsqlite3_column_text(pStmt, 1); + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + int nName = sqlite3_column_bytes(pStmt, 1); + const unsigned char *zName = sqlite3_column_text(pStmt, 1); if( zName==0 ) break; memcpy(pAlloc, zName, nName+1); azCol[i] = (char *)pAlloc; pAlloc += nName+1; - abPK[i] = tdsqlite3_column_int(pStmt, 5); + abPK[i] = sqlite3_column_int(pStmt, 5); i++; } - rc = tdsqlite3_reset(pStmt); + rc = sqlite3_reset(pStmt); } @@ -205078,9 +205078,9 @@ static int sessionTableInfo( *pabPK = 0; *pnCol = 0; if( pzTab ) *pzTab = 0; - tdsqlite3_free(azCol); + sqlite3_free(azCol); } - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); return rc; } @@ -205090,13 +205090,13 @@ static int sessionTableInfo( ** write to this table, initalize the SessionTable.nCol, azCol[] and ** abPK[] arrays accordingly. ** -** If an error occurs, an error code is stored in tdsqlite3_session.rc and +** If an error occurs, an error code is stored in sqlite3_session.rc and ** non-zero returned. Or, if no error occurs but the table has no primary -** key, tdsqlite3_session.rc is left set to SQLITE_OK and non-zero returned to +** key, sqlite3_session.rc is left set to SQLITE_OK and non-zero returned to ** indicate that updates on this table should be ignored. SessionTable.abPK ** is set to NULL in this case. */ -static int sessionInitTable(tdsqlite3_session *pSession, SessionTable *pTab){ +static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); @@ -205111,7 +205111,7 @@ static int sessionInitTable(tdsqlite3_session *pSession, SessionTable *pTab){ break; } } - if( 0==tdsqlite3_stricmp("sqlite_stat1", pTab->zName) ){ + if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){ pTab->bStat1 = 1; } } @@ -205128,23 +205128,23 @@ static int sessionInitTable(tdsqlite3_session *pSession, SessionTable *pTab){ typedef struct SessionStat1Ctx SessionStat1Ctx; struct SessionStat1Ctx { SessionHook hook; - tdsqlite3_session *pSession; + sqlite3_session *pSession; }; -static int sessionStat1Old(void *pCtx, int iCol, tdsqlite3_value **ppVal){ +static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; - tdsqlite3_value *pVal = 0; + sqlite3_value *pVal = 0; int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal); - if( rc==SQLITE_OK && iCol==1 && tdsqlite3_value_type(pVal)==SQLITE_NULL ){ + if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){ pVal = p->pSession->pZeroBlob; } *ppVal = pVal; return rc; } -static int sessionStat1New(void *pCtx, int iCol, tdsqlite3_value **ppVal){ +static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){ SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx; - tdsqlite3_value *pVal = 0; + sqlite3_value *pVal = 0; int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal); - if( rc==SQLITE_OK && iCol==1 && tdsqlite3_value_type(pVal)==SQLITE_NULL ){ + if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){ pVal = p->pSession->pZeroBlob; } *ppVal = pVal; @@ -205170,7 +205170,7 @@ static int sessionStat1Depth(void *pCtx){ */ static void sessionPreupdateOneChange( int op, /* One of SQLITE_UPDATE, INSERT, DELETE */ - tdsqlite3_session *pSession, /* Session object pTab is attached to */ + sqlite3_session *pSession, /* Session object pTab is attached to */ SessionTable *pTab /* Table that change applies to */ ){ int iHash; @@ -205205,12 +205205,12 @@ static void sessionPreupdateOneChange( pSession->hook.xCount = sessionStat1Count; pSession->hook.xDepth = sessionStat1Depth; if( pSession->pZeroBlob==0 ){ - tdsqlite3_value *p = tdsqlite3ValueNew(0); + sqlite3_value *p = sqlite3ValueNew(0); if( p==0 ){ rc = SQLITE_NOMEM; goto error_out; } - tdsqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC); + sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC); pSession->pZeroBlob = p; } } @@ -205233,7 +205233,7 @@ static void sessionPreupdateOneChange( ** this is an SQLITE_UPDATE or SQLITE_DELETE), or just the PK ** values (if this is an INSERT). */ SessionChange *pChange; /* New change object */ - tdsqlite3_int64 nByte; /* Number of bytes to allocate */ + sqlite3_int64 nByte; /* Number of bytes to allocate */ int i; /* Used to iterate through columns */ assert( rc==SQLITE_OK ); @@ -205242,7 +205242,7 @@ static void sessionPreupdateOneChange( /* Figure out how large an allocation is required */ nByte = sizeof(SessionChange); for(i=0; inCol; i++){ - tdsqlite3_value *p = 0; + sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ TESTONLY(int trc = ) pSession->hook.xOld(pSession->hook.pCtx, i, &p); assert( trc==SQLITE_OK ); @@ -205258,7 +205258,7 @@ static void sessionPreupdateOneChange( } /* Allocate the change object */ - pChange = (SessionChange *)tdsqlite3_malloc64(nByte); + pChange = (SessionChange *)sqlite3_malloc64(nByte); if( !pChange ){ rc = SQLITE_NOMEM; goto error_out; @@ -205273,7 +205273,7 @@ static void sessionPreupdateOneChange( ** It is not possible for an OOM to occur in this block. */ nByte = 0; for(i=0; inCol; i++){ - tdsqlite3_value *p = 0; + sqlite3_value *p = 0; if( op!=SQLITE_INSERT ){ pSession->hook.xOld(pSession->hook.pCtx, i, &p); }else if( pTab->abPK[i] ){ @@ -205313,17 +205313,17 @@ static void sessionPreupdateOneChange( } static int sessionFindTable( - tdsqlite3_session *pSession, + sqlite3_session *pSession, const char *zName, SessionTable **ppTab ){ int rc = SQLITE_OK; - int nName = tdsqlite3Strlen30(zName); + int nName = sqlite3Strlen30(zName); SessionTable *pRet; /* Search for an existing table */ for(pRet=pSession->pTable; pRet; pRet=pRet->pNext){ - if( 0==tdsqlite3_strnicmp(pRet->zName, zName, nName+1) ) break; + if( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ) break; } if( pRet==0 && pSession->bAutoAttach ){ @@ -205332,10 +205332,10 @@ static int sessionFindTable( if( pSession->xTableFilter==0 || pSession->xTableFilter(pSession->pFilterCtx, zName) ){ - rc = tdsqlite3session_attach(pSession, zName); + rc = sqlite3session_attach(pSession, zName); if( rc==SQLITE_OK ){ for(pRet=pSession->pTable; pRet->pNext; pRet=pRet->pNext); - assert( 0==tdsqlite3_strnicmp(pRet->zName, zName, nName+1) ); + assert( 0==sqlite3_strnicmp(pRet->zName, zName, nName+1) ); } } } @@ -205350,19 +205350,19 @@ static int sessionFindTable( */ static void xPreUpdate( void *pCtx, /* Copy of third arg to preupdate_hook() */ - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ int op, /* SQLITE_UPDATE, DELETE or INSERT */ char const *zDb, /* Database name */ char const *zName, /* Table name */ - tdsqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ - tdsqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ + sqlite3_int64 iKey1, /* Rowid of row about to be deleted/updated */ + sqlite3_int64 iKey2 /* New rowid value (for a rowid UPDATE) */ ){ - tdsqlite3_session *pSession; - int nDb = tdsqlite3Strlen30(zDb); + sqlite3_session *pSession; + int nDb = sqlite3Strlen30(zDb); - assert( tdsqlite3_mutex_held(db->mutex) ); + assert( sqlite3_mutex_held(db->mutex) ); - for(pSession=(tdsqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ + for(pSession=(sqlite3_session *)pCtx; pSession; pSession=pSession->pNext){ SessionTable *pTab; /* If this session is attached to a different database ("main", "temp" @@ -205370,7 +205370,7 @@ static void xPreUpdate( ** to the next session object attached to this database. */ if( pSession->bEnable==0 ) continue; if( pSession->rc ) continue; - if( tdsqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue; + if( sqlite3_strnicmp(zDb, pSession->zDb, nDb+1) ) continue; pSession->rc = sessionFindTable(pSession, zName, &pTab); if( pTab ){ @@ -205386,17 +205386,17 @@ static void xPreUpdate( /* ** The pre-update hook implementations. */ -static int sessionPreupdateOld(void *pCtx, int iVal, tdsqlite3_value **ppVal){ - return tdsqlite3_preupdate_old((tdsqlite3*)pCtx, iVal, ppVal); +static int sessionPreupdateOld(void *pCtx, int iVal, sqlite3_value **ppVal){ + return sqlite3_preupdate_old((sqlite3*)pCtx, iVal, ppVal); } -static int sessionPreupdateNew(void *pCtx, int iVal, tdsqlite3_value **ppVal){ - return tdsqlite3_preupdate_new((tdsqlite3*)pCtx, iVal, ppVal); +static int sessionPreupdateNew(void *pCtx, int iVal, sqlite3_value **ppVal){ + return sqlite3_preupdate_new((sqlite3*)pCtx, iVal, ppVal); } static int sessionPreupdateCount(void *pCtx){ - return tdsqlite3_preupdate_count((tdsqlite3*)pCtx); + return sqlite3_preupdate_count((sqlite3*)pCtx); } static int sessionPreupdateDepth(void *pCtx){ - return tdsqlite3_preupdate_depth((tdsqlite3*)pCtx); + return sqlite3_preupdate_depth((sqlite3*)pCtx); } /* @@ -205404,7 +205404,7 @@ static int sessionPreupdateDepth(void *pCtx){ ** argument. */ static void sessionPreupdateHooks( - tdsqlite3_session *pSession + sqlite3_session *pSession ){ pSession->hook.pCtx = (void*)pSession->db; pSession->hook.xOld = sessionPreupdateOld; @@ -205415,26 +205415,26 @@ static void sessionPreupdateHooks( typedef struct SessionDiffCtx SessionDiffCtx; struct SessionDiffCtx { - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; int nOldOff; }; /* ** The diff hook implementations. */ -static int sessionDiffOld(void *pCtx, int iVal, tdsqlite3_value **ppVal){ +static int sessionDiffOld(void *pCtx, int iVal, sqlite3_value **ppVal){ SessionDiffCtx *p = (SessionDiffCtx*)pCtx; - *ppVal = tdsqlite3_column_value(p->pStmt, iVal+p->nOldOff); + *ppVal = sqlite3_column_value(p->pStmt, iVal+p->nOldOff); return SQLITE_OK; } -static int sessionDiffNew(void *pCtx, int iVal, tdsqlite3_value **ppVal){ +static int sessionDiffNew(void *pCtx, int iVal, sqlite3_value **ppVal){ SessionDiffCtx *p = (SessionDiffCtx*)pCtx; - *ppVal = tdsqlite3_column_value(p->pStmt, iVal); + *ppVal = sqlite3_column_value(p->pStmt, iVal); return SQLITE_OK; } static int sessionDiffCount(void *pCtx){ SessionDiffCtx *p = (SessionDiffCtx*)pCtx; - return p->nOldOff ? p->nOldOff : tdsqlite3_column_count(p->pStmt); + return p->nOldOff ? p->nOldOff : sqlite3_column_count(p->pStmt); } static int sessionDiffDepth(void *pCtx){ return 0; @@ -205445,7 +205445,7 @@ static int sessionDiffDepth(void *pCtx){ ** argument. */ static void sessionDiffHooks( - tdsqlite3_session *pSession, + sqlite3_session *pSession, SessionDiffCtx *pDiffCtx ){ pSession->hook.pCtx = (void*)pDiffCtx; @@ -205467,7 +205467,7 @@ static char *sessionExprComparePK( for(i=0; idb, zStmt, -1, &pStmt, 0); + sqlite3_stmt *pStmt; + rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); if( rc==SQLITE_OK ){ SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; pDiffCtx->pStmt = pStmt; pDiffCtx->nOldOff = 0; - while( SQLITE_ROW==tdsqlite3_step(pStmt) ){ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ sessionPreupdateOneChange(op, pSession, pTab); } - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); } - tdsqlite3_free(zStmt); + sqlite3_free(zStmt); } return rc; } static int sessionDiffFindModified( - tdsqlite3_session *pSession, + sqlite3_session *pSession, SessionTable *pTab, const char *zFrom, const char *zExpr @@ -205570,34 +205570,34 @@ static int sessionDiffFindModified( if( zExpr2==0 ){ rc = SQLITE_NOMEM; }else{ - char *zStmt = tdsqlite3_mprintf( + char *zStmt = sqlite3_mprintf( "SELECT * FROM \"%w\".\"%w\", \"%w\".\"%w\" WHERE %s AND (%z)", pSession->zDb, pTab->zName, zFrom, pTab->zName, zExpr, zExpr2 ); if( zStmt==0 ){ rc = SQLITE_NOMEM; }else{ - tdsqlite3_stmt *pStmt; - rc = tdsqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); + sqlite3_stmt *pStmt; + rc = sqlite3_prepare(pSession->db, zStmt, -1, &pStmt, 0); if( rc==SQLITE_OK ){ SessionDiffCtx *pDiffCtx = (SessionDiffCtx*)pSession->hook.pCtx; pDiffCtx->pStmt = pStmt; pDiffCtx->nOldOff = pTab->nCol; - while( SQLITE_ROW==tdsqlite3_step(pStmt) ){ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ sessionPreupdateOneChange(SQLITE_UPDATE, pSession, pTab); } - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); } - tdsqlite3_free(zStmt); + sqlite3_free(zStmt); } } return rc; } -SQLITE_API int tdsqlite3session_diff( - tdsqlite3_session *pSession, +SQLITE_API int sqlite3session_diff( + sqlite3_session *pSession, const char *zFrom, const char *zTbl, char **pzErrMsg @@ -205609,11 +205609,11 @@ SQLITE_API int tdsqlite3session_diff( memset(&d, 0, sizeof(d)); sessionDiffHooks(pSession, &d); - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); if( pzErrMsg ) *pzErrMsg = 0; if( rc==SQLITE_OK ){ char *zExpr = 0; - tdsqlite3 *db = pSession->db; + sqlite3 *db = pSession->db; SessionTable *pTo; /* Table zTbl */ /* Locate and if necessary initialize the target table object */ @@ -205639,15 +205639,15 @@ SQLITE_API int tdsqlite3session_diff( int i; for(i=0; iabPK[i]!=abPK[i] ) bMismatch = 1; - if( tdsqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1; + if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1; if( abPK[i] ) bHasPk = 1; } } } - tdsqlite3_free((char*)azCol); + sqlite3_free((char*)azCol); if( bMismatch ){ if( pzErrMsg ){ - *pzErrMsg = tdsqlite3_mprintf("table schemas do not match"); + *pzErrMsg = sqlite3_mprintf("table schemas do not match"); } rc = SQLITE_SCHEMA; } @@ -205678,12 +205678,12 @@ SQLITE_API int tdsqlite3session_diff( rc = sessionDiffFindModified(pSession, pTo, zFrom, zExpr); } - tdsqlite3_free(zExpr); + sqlite3_free(zExpr); } diff_out: sessionPreupdateHooks(pSession); - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); return rc; } @@ -205691,22 +205691,22 @@ SQLITE_API int tdsqlite3session_diff( ** Create a session object. This session object will record changes to ** database zDb attached to connection db. */ -SQLITE_API int tdsqlite3session_create( - tdsqlite3 *db, /* Database handle */ +SQLITE_API int sqlite3session_create( + sqlite3 *db, /* Database handle */ const char *zDb, /* Name of db (e.g. "main") */ - tdsqlite3_session **ppSession /* OUT: New session object */ + sqlite3_session **ppSession /* OUT: New session object */ ){ - tdsqlite3_session *pNew; /* Newly allocated session object */ - tdsqlite3_session *pOld; /* Session object already attached to db */ - int nDb = tdsqlite3Strlen30(zDb); /* Length of zDb in bytes */ + sqlite3_session *pNew; /* Newly allocated session object */ + sqlite3_session *pOld; /* Session object already attached to db */ + int nDb = sqlite3Strlen30(zDb); /* Length of zDb in bytes */ /* Zero the output value in case an error occurs. */ *ppSession = 0; /* Allocate and populate the new session object. */ - pNew = (tdsqlite3_session *)tdsqlite3_malloc64(sizeof(tdsqlite3_session) + nDb + 1); + pNew = (sqlite3_session *)sqlite3_malloc64(sizeof(sqlite3_session) + nDb + 1); if( !pNew ) return SQLITE_NOMEM; - memset(pNew, 0, sizeof(tdsqlite3_session)); + memset(pNew, 0, sizeof(sqlite3_session)); pNew->db = db; pNew->zDb = (char *)&pNew[1]; pNew->bEnable = 1; @@ -205716,10 +205716,10 @@ SQLITE_API int tdsqlite3session_create( /* Add the new session object to the linked list of session objects ** attached to database handle $db. Do this under the cover of the db ** handle mutex. */ - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(db)); - pOld = (tdsqlite3_session*)tdsqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + pOld = (sqlite3_session*)sqlite3_preupdate_hook(db, xPreUpdate, (void*)pNew); pNew->pNext = pOld; - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(db)); + sqlite3_mutex_leave(sqlite3_db_mutex(db)); *ppSession = pNew; return SQLITE_OK; @@ -205741,50 +205741,50 @@ static void sessionDeleteTable(SessionTable *pList){ SessionChange *pNextChange; for(p=pTab->apChange[i]; p; p=pNextChange){ pNextChange = p->pNext; - tdsqlite3_free(p); + sqlite3_free(p); } } - tdsqlite3_free((char*)pTab->azCol); /* cast works around VC++ bug */ - tdsqlite3_free(pTab->apChange); - tdsqlite3_free(pTab); + sqlite3_free((char*)pTab->azCol); /* cast works around VC++ bug */ + sqlite3_free(pTab->apChange); + sqlite3_free(pTab); } } /* -** Delete a session object previously allocated using tdsqlite3session_create(). +** Delete a session object previously allocated using sqlite3session_create(). */ -SQLITE_API void tdsqlite3session_delete(tdsqlite3_session *pSession){ - tdsqlite3 *db = pSession->db; - tdsqlite3_session *pHead; - tdsqlite3_session **pp; +SQLITE_API void sqlite3session_delete(sqlite3_session *pSession){ + sqlite3 *db = pSession->db; + sqlite3_session *pHead; + sqlite3_session **pp; /* Unlink the session from the linked list of sessions attached to the ** database handle. Hold the db mutex while doing so. */ - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(db)); - pHead = (tdsqlite3_session*)tdsqlite3_preupdate_hook(db, 0, 0); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + pHead = (sqlite3_session*)sqlite3_preupdate_hook(db, 0, 0); for(pp=&pHead; ALWAYS((*pp)!=0); pp=&((*pp)->pNext)){ if( (*pp)==pSession ){ *pp = (*pp)->pNext; - if( pHead ) tdsqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead); + if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead); break; } } - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(db)); - tdsqlite3ValueFree(pSession->pZeroBlob); + sqlite3_mutex_leave(sqlite3_db_mutex(db)); + sqlite3ValueFree(pSession->pZeroBlob); /* Delete all attached table objects. And the contents of their ** associated hash-tables. */ sessionDeleteTable(pSession->pTable); /* Free the session object itself. */ - tdsqlite3_free(pSession); + sqlite3_free(pSession); } /* ** Set a table filter on a Session Object. */ -SQLITE_API void tdsqlite3session_table_filter( - tdsqlite3_session *pSession, +SQLITE_API void sqlite3session_table_filter( + sqlite3_session *pSession, int(*xFilter)(void*, const char*), void *pCtx /* First argument passed to xFilter */ ){ @@ -205801,12 +205801,12 @@ SQLITE_API void tdsqlite3session_table_filter( ** not matter if the PRIMARY KEY is an "INTEGER PRIMARY KEY" (rowid alias) ** or not. */ -SQLITE_API int tdsqlite3session_attach( - tdsqlite3_session *pSession, /* Session object */ +SQLITE_API int sqlite3session_attach( + sqlite3_session *pSession, /* Session object */ const char *zName /* Table name */ ){ int rc = SQLITE_OK; - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); if( !zName ){ pSession->bAutoAttach = 1; @@ -205816,14 +205816,14 @@ SQLITE_API int tdsqlite3session_attach( /* First search for an existing entry. If one is found, this call is ** a no-op. Return early. */ - nName = tdsqlite3Strlen30(zName); + nName = sqlite3Strlen30(zName); for(pTab=pSession->pTable; pTab; pTab=pTab->pNext){ - if( 0==tdsqlite3_strnicmp(pTab->zName, zName, nName+1) ) break; + if( 0==sqlite3_strnicmp(pTab->zName, zName, nName+1) ) break; } if( !pTab ){ /* Allocate new SessionTable object. */ - pTab = (SessionTable *)tdsqlite3_malloc64(sizeof(SessionTable) + nName + 1); + pTab = (SessionTable *)sqlite3_malloc64(sizeof(SessionTable) + nName + 1); if( !pTab ){ rc = SQLITE_NOMEM; }else{ @@ -205842,13 +205842,13 @@ SQLITE_API int tdsqlite3session_attach( } } - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); return rc; } /* ** Ensure that there is room in the buffer to append nByte bytes of data. -** If not, use tdsqlite3_realloc() to grow the buffer so that there is. +** If not, use sqlite3_realloc() to grow the buffer so that there is. ** ** If successful, return zero. Otherwise, if an OOM condition is encountered, ** set *pRc to SQLITE_NOMEM and return non-zero. @@ -205861,7 +205861,7 @@ static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){ nNew = nNew*2; }while( (size_t)(nNew-p->nBuf)aBuf, nNew); + aNew = (u8 *)sqlite3_realloc64(p->aBuf, nNew); if( 0==aNew ){ *pRc = SQLITE_NOMEM; }else{ @@ -205880,10 +205880,10 @@ static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){ ** Otherwise, if an error occurs, *pRc is set to an SQLite error code ** before returning. */ -static void sessionAppendValue(SessionBuffer *p, tdsqlite3_value *pVal, int *pRc){ +static void sessionAppendValue(SessionBuffer *p, sqlite3_value *pVal, int *pRc){ int rc = *pRc; if( rc==SQLITE_OK ){ - tdsqlite3_int64 nByte = 0; + sqlite3_int64 nByte = 0; rc = sessionSerializeValue(0, pVal, &nByte); sessionBufferGrow(p, nByte, &rc); if( rc==SQLITE_OK ){ @@ -205953,7 +205953,7 @@ static void sessionAppendStr( const char *zStr, int *pRc ){ - int nStr = tdsqlite3Strlen30(zStr); + int nStr = sqlite3Strlen30(zStr); if( 0==sessionBufferGrow(p, nStr, pRc) ){ memcpy(&p->aBuf[p->nBuf], zStr, nStr); p->nBuf += nStr; @@ -205974,7 +205974,7 @@ static void sessionAppendInteger( int *pRc /* IN/OUT: Error code */ ){ char aBuf[24]; - tdsqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal); + sqlite3_snprintf(sizeof(aBuf)-1, aBuf, "%d", iVal); sessionAppendStr(p, aBuf, pRc); } @@ -205992,7 +205992,7 @@ static void sessionAppendIdent( const char *zStr, /* String to quote, escape and append */ int *pRc /* IN/OUT: Error code */ ){ - int nStr = tdsqlite3Strlen30(zStr)*2 + 2 + 1; + int nStr = sqlite3Strlen30(zStr)*2 + 2 + 1; if( 0==sessionBufferGrow(p, nStr, pRc) ){ char *zOut = (char *)&p->aBuf[p->nBuf]; const char *zIn = zStr; @@ -206014,20 +206014,20 @@ static void sessionAppendIdent( */ static void sessionAppendCol( SessionBuffer *p, /* Buffer to append to */ - tdsqlite3_stmt *pStmt, /* Handle pointing to row containing value */ + sqlite3_stmt *pStmt, /* Handle pointing to row containing value */ int iCol, /* Column to read value from */ int *pRc /* IN/OUT: Error code */ ){ if( *pRc==SQLITE_OK ){ - int eType = tdsqlite3_column_type(pStmt, iCol); + int eType = sqlite3_column_type(pStmt, iCol); sessionAppendByte(p, (u8)eType, pRc); if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - tdsqlite3_int64 i; + sqlite3_int64 i; u8 aBuf[8]; if( eType==SQLITE_INTEGER ){ - i = tdsqlite3_column_int64(pStmt, iCol); + i = sqlite3_column_int64(pStmt, iCol); }else{ - double r = tdsqlite3_column_double(pStmt, iCol); + double r = sqlite3_column_double(pStmt, iCol); memcpy(&i, &r, 8); } sessionPutI64(aBuf, i); @@ -206037,11 +206037,11 @@ static void sessionAppendCol( u8 *z; int nByte; if( eType==SQLITE_BLOB ){ - z = (u8 *)tdsqlite3_column_blob(pStmt, iCol); + z = (u8 *)sqlite3_column_blob(pStmt, iCol); }else{ - z = (u8 *)tdsqlite3_column_text(pStmt, iCol); + z = (u8 *)sqlite3_column_text(pStmt, iCol); } - nByte = tdsqlite3_column_bytes(pStmt, iCol); + nByte = sqlite3_column_bytes(pStmt, iCol); if( z || (eType==SQLITE_BLOB && nByte==0) ){ sessionAppendVarint(p, nByte, pRc); sessionAppendBlob(p, z, nByte, pRc); @@ -206077,7 +206077,7 @@ static void sessionAppendCol( static int sessionAppendUpdate( SessionBuffer *pBuf, /* Buffer to append to */ int bPatchset, /* True for "patchset", 0 for "changeset" */ - tdsqlite3_stmt *pStmt, /* Statement handle pointing at new row */ + sqlite3_stmt *pStmt, /* Statement handle pointing at new row */ SessionChange *p, /* Object containing old values */ u8 *abPK /* Boolean array - true for PK columns */ ){ @@ -206090,14 +206090,14 @@ static int sessionAppendUpdate( sessionAppendByte(pBuf, SQLITE_UPDATE, &rc); sessionAppendByte(pBuf, p->bIndirect, &rc); - for(i=0; idb; /* Source database handle */ + sqlite3 *db = pSession->db; /* Source database handle */ SessionTable *pTab; /* Used to iterate through attached tables */ SessionBuffer buf = {0,0,0}; /* Buffer in which to accumlate changeset */ int rc; /* Return code */ @@ -206395,7 +206395,7 @@ static int sessionGenerateChangeset( assert( xOutput==0 || (pnChangeset==0 && ppChangeset==0 ) ); /* Zero the output variables in case an error occurs. If this session - ** object is already in the error state (tdsqlite3_session.rc != SQLITE_OK), + ** object is already in the error state (sqlite3_session.rc != SQLITE_OK), ** this call will be a no-op. */ if( xOutput==0 ){ *pnChangeset = 0; @@ -206403,10 +206403,10 @@ static int sessionGenerateChangeset( } if( pSession->rc ) return pSession->rc; - rc = tdsqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); + rc = sqlite3_exec(pSession->db, "SAVEPOINT changeset", 0, 0, 0); if( rc!=SQLITE_OK ) return rc; - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(db)); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ @@ -206415,7 +206415,7 @@ static int sessionGenerateChangeset( u8 *abPK; /* Primary key array */ const char **azCol = 0; /* Table columns */ int i; /* Used to iterate through hash buckets */ - tdsqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ + sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ int nRewind = buf.nBuf; /* Initial size of write buffer */ int nNoop; /* Size of buffer after writing tbl header */ @@ -206441,7 +206441,7 @@ static int sessionGenerateChangeset( for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ rc = sessionSelectBind(pSel, nCol, abPK, p); if( rc!=SQLITE_OK ) continue; - if( tdsqlite3_step(pSel)==SQLITE_ROW ){ + if( sqlite3_step(pSel)==SQLITE_ROW ){ if( p->op==SQLITE_INSERT ){ int iCol; sessionAppendByte(&buf, SQLITE_INSERT, &rc); @@ -206456,7 +206456,7 @@ static int sessionGenerateChangeset( rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK); } if( rc==SQLITE_OK ){ - rc = tdsqlite3_reset(pSel); + rc = sqlite3_reset(pSel); } /* If the buffer is now larger than sessions_strm_chunk_size, pass @@ -206474,11 +206474,11 @@ static int sessionGenerateChangeset( } } - tdsqlite3_finalize(pSel); + sqlite3_finalize(pSel); if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } - tdsqlite3_free((char*)azCol); /* cast works around VC++ bug */ + sqlite3_free((char*)azCol); /* cast works around VC++ bug */ } } @@ -206492,9 +206492,9 @@ static int sessionGenerateChangeset( } } - tdsqlite3_free(buf.aBuf); - tdsqlite3_exec(db, "RELEASE changeset", 0, 0, 0); - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(db)); + sqlite3_free(buf.aBuf); + sqlite3_exec(db, "RELEASE changeset", 0, 0, 0); + sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } @@ -206503,10 +206503,10 @@ static int sessionGenerateChangeset( ** session object passed as the first argument. ** ** It is the responsibility of the caller to eventually free the buffer -** using tdsqlite3_free(). +** using sqlite3_free(). */ -SQLITE_API int tdsqlite3session_changeset( - tdsqlite3_session *pSession, /* Session object */ +SQLITE_API int sqlite3session_changeset( + sqlite3_session *pSession, /* Session object */ int *pnChangeset, /* OUT: Size of buffer at *ppChangeset */ void **ppChangeset /* OUT: Buffer containing changeset */ ){ @@ -206514,10 +206514,10 @@ SQLITE_API int tdsqlite3session_changeset( } /* -** Streaming version of tdsqlite3session_changeset(). +** Streaming version of sqlite3session_changeset(). */ -SQLITE_API int tdsqlite3session_changeset_strm( - tdsqlite3_session *pSession, +SQLITE_API int sqlite3session_changeset_strm( + sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ){ @@ -206525,10 +206525,10 @@ SQLITE_API int tdsqlite3session_changeset_strm( } /* -** Streaming version of tdsqlite3session_patchset(). +** Streaming version of sqlite3session_patchset(). */ -SQLITE_API int tdsqlite3session_patchset_strm( - tdsqlite3_session *pSession, +SQLITE_API int sqlite3session_patchset_strm( + sqlite3_session *pSession, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ){ @@ -206540,10 +206540,10 @@ SQLITE_API int tdsqlite3session_patchset_strm( ** session object passed as the first argument. ** ** It is the responsibility of the caller to eventually free the buffer -** using tdsqlite3_free(). +** using sqlite3_free(). */ -SQLITE_API int tdsqlite3session_patchset( - tdsqlite3_session *pSession, /* Session object */ +SQLITE_API int sqlite3session_patchset( + sqlite3_session *pSession, /* Session object */ int *pnPatchset, /* OUT: Size of buffer at *ppChangeset */ void **ppPatchset /* OUT: Buffer containing changeset */ ){ @@ -206553,28 +206553,28 @@ SQLITE_API int tdsqlite3session_patchset( /* ** Enable or disable the session object passed as the first argument. */ -SQLITE_API int tdsqlite3session_enable(tdsqlite3_session *pSession, int bEnable){ +SQLITE_API int sqlite3session_enable(sqlite3_session *pSession, int bEnable){ int ret; - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); if( bEnable>=0 ){ pSession->bEnable = bEnable; } ret = pSession->bEnable; - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); return ret; } /* ** Enable or disable the session object passed as the first argument. */ -SQLITE_API int tdsqlite3session_indirect(tdsqlite3_session *pSession, int bIndirect){ +SQLITE_API int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect){ int ret; - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); if( bIndirect>=0 ){ pSession->bIndirect = bIndirect; } ret = pSession->bIndirect; - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); return ret; } @@ -206582,31 +206582,31 @@ SQLITE_API int tdsqlite3session_indirect(tdsqlite3_session *pSession, int bIndir ** Return true if there have been no changes to monitored tables recorded ** by the session object passed as the only argument. */ -SQLITE_API int tdsqlite3session_isempty(tdsqlite3_session *pSession){ +SQLITE_API int sqlite3session_isempty(sqlite3_session *pSession){ int ret = 0; SessionTable *pTab; - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_enter(sqlite3_db_mutex(pSession->db)); for(pTab=pSession->pTable; pTab && ret==0; pTab=pTab->pNext){ ret = (pTab->nEntry>0); } - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(pSession->db)); + sqlite3_mutex_leave(sqlite3_db_mutex(pSession->db)); return (ret==0); } /* -** Do the work for either tdsqlite3changeset_start() or start_strm(). +** Do the work for either sqlite3changeset_start() or start_strm(). */ static int sessionChangesetStart( - tdsqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset, /* Pointer to buffer containing changeset */ int bInvert /* True to invert changeset */ ){ - tdsqlite3_changeset_iter *pRet; /* Iterator to return */ + sqlite3_changeset_iter *pRet; /* Iterator to return */ int nByte; /* Number of bytes to allocate for iterator */ assert( xInput==0 || (pChangeset==0 && nChangeset==0) ); @@ -206615,10 +206615,10 @@ static int sessionChangesetStart( *pp = 0; /* Allocate and initialize the iterator structure. */ - nByte = sizeof(tdsqlite3_changeset_iter); - pRet = (tdsqlite3_changeset_iter *)tdsqlite3_malloc(nByte); + nByte = sizeof(sqlite3_changeset_iter); + pRet = (sqlite3_changeset_iter *)sqlite3_malloc(nByte); if( !pRet ) return SQLITE_NOMEM; - memset(pRet, 0, sizeof(tdsqlite3_changeset_iter)); + memset(pRet, 0, sizeof(sqlite3_changeset_iter)); pRet->in.aData = (u8 *)pChangeset; pRet->in.nData = nChangeset; pRet->in.xInput = xInput; @@ -206634,15 +206634,15 @@ static int sessionChangesetStart( /* ** Create an iterator used to iterate through the contents of a changeset. */ -SQLITE_API int tdsqlite3changeset_start( - tdsqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ +SQLITE_API int sqlite3changeset_start( + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset /* Pointer to buffer containing changeset */ ){ return sessionChangesetStart(pp, 0, 0, nChangeset, pChangeset, 0); } -SQLITE_API int tdsqlite3changeset_start_v2( - tdsqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ +SQLITE_API int sqlite3changeset_start_v2( + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ int nChangeset, /* Size of buffer pChangeset in bytes */ void *pChangeset, /* Pointer to buffer containing changeset */ int flags @@ -206652,17 +206652,17 @@ SQLITE_API int tdsqlite3changeset_start_v2( } /* -** Streaming version of tdsqlite3changeset_start(). +** Streaming version of sqlite3changeset_start(). */ -SQLITE_API int tdsqlite3changeset_start_strm( - tdsqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ +SQLITE_API int sqlite3changeset_start_strm( + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ){ return sessionChangesetStart(pp, xInput, pIn, 0, 0, 0); } -SQLITE_API int tdsqlite3changeset_start_v2_strm( - tdsqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ +SQLITE_API int sqlite3changeset_start_v2_strm( + sqlite3_changeset_iter **pp, /* OUT: Changeset iterator handle */ int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int flags @@ -206744,25 +206744,25 @@ static void sessionSkipRecord( } /* -** This function sets the value of the tdsqlite3_value object passed as the +** This function sets the value of the sqlite3_value object passed as the ** first argument to a copy of the string or blob held in the aData[] ** buffer. SQLITE_OK is returned if successful, or SQLITE_NOMEM if an OOM ** error occurs. */ static int sessionValueSetStr( - tdsqlite3_value *pVal, /* Set the value of this object */ + sqlite3_value *pVal, /* Set the value of this object */ u8 *aData, /* Buffer containing string or blob data */ int nData, /* Size of buffer aData[] in bytes */ u8 enc /* String encoding (0 for blobs) */ ){ /* In theory this code could just pass SQLITE_TRANSIENT as the final - ** argument to tdsqlite3ValueSetStr() and have the copy created + ** argument to sqlite3ValueSetStr() and have the copy created ** automatically. But doing so makes it difficult to detect any OOM ** error. Hence the code to create the copy externally. */ - u8 *aCopy = tdsqlite3_malloc64((tdsqlite3_int64)nData+1); + u8 *aCopy = sqlite3_malloc64((sqlite3_int64)nData+1); if( aCopy==0 ) return SQLITE_NOMEM; memcpy(aCopy, aData, nData); - tdsqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, tdsqlite3_free); + sqlite3ValueSetStr(pVal, nData, (char*)aCopy, enc, sqlite3_free); return SQLITE_OK; } @@ -206778,14 +206778,14 @@ static int sessionValueSetStr( ** (in other words, it is a patchset DELETE record). ** ** If successful, each element of the apOut[] array (allocated by the caller) -** is set to point to an tdsqlite3_value object containing the value read +** is set to point to an sqlite3_value object containing the value read ** from the corresponding position in the record. If that value is not ** included in the record (i.e. because the record is part of an UPDATE change ** and the field was not modified), the corresponding element of apOut[] is ** set to NULL. ** ** It is the responsibility of the caller to free all sqlite_value structures -** using tdsqlite3_free(). +** using sqlite3_free(). ** ** If an error occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned. ** The apOut[] array may have been partially populated in this case. @@ -206794,7 +206794,7 @@ static int sessionReadRecord( SessionInput *pIn, /* Input data */ int nCol, /* Number of values in record */ u8 *abPK, /* Array of primary key flags, or NULL */ - tdsqlite3_value **apOut /* Write values to this array */ + sqlite3_value **apOut /* Write values to this array */ ){ int i; /* Used to iterate through columns */ int rc = SQLITE_OK; @@ -206810,7 +206810,7 @@ static int sessionReadRecord( eType = pIn->aData[pIn->iNext++]; assert( apOut[i]==0 ); if( eType ){ - apOut[i] = tdsqlite3ValueNew(0); + apOut[i] = sqlite3ValueNew(0); if( !apOut[i] ) rc = SQLITE_NOMEM; } } @@ -206833,13 +206833,13 @@ static int sessionReadRecord( } } if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - tdsqlite3_int64 v = sessionGetI64(aVal); + sqlite3_int64 v = sessionGetI64(aVal); if( eType==SQLITE_INTEGER ){ - tdsqlite3VdbeMemSetInt64(apOut[i], v); + sqlite3VdbeMemSetInt64(apOut[i], v); }else{ double d; memcpy(&d, &v, 8); - tdsqlite3VdbeMemSetDouble(apOut[i], d); + sqlite3VdbeMemSetDouble(apOut[i], d); } pIn->iNext += 8; } @@ -206949,7 +206949,7 @@ static int sessionChangesetBufferRecord( ** is returned and the final values of the various fields enumerated above ** are undefined. */ -static int sessionChangesetReadTblhdr(tdsqlite3_changeset_iter *p){ +static int sessionChangesetReadTblhdr(sqlite3_changeset_iter *p){ int rc; int nCopy; assert( p->rc==SQLITE_OK ); @@ -206962,7 +206962,7 @@ static int sessionChangesetReadTblhdr(tdsqlite3_changeset_iter *p){ if( p->nCol>0 ){ nCopy -= nVarint; p->in.iNext += nVarint; - nByte = p->nCol * sizeof(tdsqlite3_value*) * 2 + nCopy; + nByte = p->nCol * sizeof(sqlite3_value*) * 2 + nCopy; p->tblhdr.nBuf = 0; sessionBufferGrow(&p->tblhdr, nByte, &rc); }else{ @@ -206971,13 +206971,13 @@ static int sessionChangesetReadTblhdr(tdsqlite3_changeset_iter *p){ } if( rc==SQLITE_OK ){ - size_t iPK = sizeof(tdsqlite3_value*)*p->nCol*2; + size_t iPK = sizeof(sqlite3_value*)*p->nCol*2; memset(p->tblhdr.aBuf, 0, iPK); memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy); p->in.iNext += nCopy; } - p->apValue = (tdsqlite3_value**)p->tblhdr.aBuf; + p->apValue = (sqlite3_value**)p->tblhdr.aBuf; p->abPK = (u8*)&p->apValue[p->nCol*2]; p->zTab = (char*)&p->abPK[p->nCol]; return (p->rc = rc); @@ -206987,8 +206987,8 @@ static int sessionChangesetReadTblhdr(tdsqlite3_changeset_iter *p){ ** Advance the changeset iterator to the next change. ** ** If both paRec and pnRec are NULL, then this function works like the public -** API tdsqlite3changeset_next(). If SQLITE_ROW is returned, then the -** tdsqlite3changeset_new() and old() APIs may be used to query for values. +** API sqlite3changeset_next(). If SQLITE_ROW is returned, then the +** sqlite3changeset_new() and old() APIs may be used to query for values. ** ** Otherwise, if paRec and pnRec are not NULL, then a pointer to the change ** record is written to *paRec before returning and the number of bytes in @@ -207000,7 +207000,7 @@ static int sessionChangesetReadTblhdr(tdsqlite3_changeset_iter *p){ ** changes in the changeset. */ static int sessionChangesetNext( - tdsqlite3_changeset_iter *p, /* Changeset iterator */ + sqlite3_changeset_iter *p, /* Changeset iterator */ u8 **paRec, /* If non-NULL, store record pointer here */ int *pnRec, /* If non-NULL, store size of record here */ int *pbNew /* If non-NULL, true if new table */ @@ -207016,9 +207016,9 @@ static int sessionChangesetNext( /* Free the current contents of p->apValue[], if any. */ if( p->apValue ){ for(i=0; inCol*2; i++){ - tdsqlite3ValueFree(p->apValue[i]); + sqlite3ValueFree(p->apValue[i]); } - memset(p->apValue, 0, sizeof(tdsqlite3_value*)*p->nCol*2); + memset(p->apValue, 0, sizeof(sqlite3_value*)*p->nCol*2); } /* Make sure the buffer contains at least 10 bytes of input data, or all @@ -207075,8 +207075,8 @@ static int sessionChangesetNext( *paRec = &p->in.aData[p->in.iNext]; p->in.iNext += *pnRec; }else{ - tdsqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue); - tdsqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]); + sqlite3_value **apOld = (p->bInvert ? &p->apValue[p->nCol] : p->apValue); + sqlite3_value **apNew = (p->bInvert ? p->apValue : &p->apValue[p->nCol]); /* If this is an UPDATE or DELETE, read the old.* record. */ if( p->op!=SQLITE_INSERT && (p->bPatchset==0 || p->op==SQLITE_DELETE) ){ @@ -207115,14 +207115,14 @@ static int sessionChangesetNext( } /* -** Advance an iterator created by tdsqlite3changeset_start() to the next +** Advance an iterator created by sqlite3changeset_start() to the next ** change in the changeset. This function may return SQLITE_ROW, SQLITE_DONE ** or SQLITE_CORRUPT. ** ** This function may not be called on iterators passed to a conflict handler ** callback by changeset_apply(). */ -SQLITE_API int tdsqlite3changeset_next(tdsqlite3_changeset_iter *p){ +SQLITE_API int sqlite3changeset_next(sqlite3_changeset_iter *p){ return sessionChangesetNext(p, 0, 0, 0); } @@ -207131,8 +207131,8 @@ SQLITE_API int tdsqlite3changeset_next(tdsqlite3_changeset_iter *p){ ** from a changeset iterator. It may only be called after changeset_next() ** has returned SQLITE_ROW. */ -SQLITE_API int tdsqlite3changeset_op( - tdsqlite3_changeset_iter *pIter, /* Iterator handle */ +SQLITE_API int sqlite3changeset_op( + sqlite3_changeset_iter *pIter, /* Iterator handle */ const char **pzTab, /* OUT: Pointer to table name */ int *pnCol, /* OUT: Number of columns in table */ int *pOp, /* OUT: SQLITE_INSERT, DELETE or UPDATE */ @@ -207151,8 +207151,8 @@ SQLITE_API int tdsqlite3changeset_op( ** to. This function may only be called after changeset_next() returns ** SQLITE_ROW. */ -SQLITE_API int tdsqlite3changeset_pk( - tdsqlite3_changeset_iter *pIter, /* Iterator object */ +SQLITE_API int sqlite3changeset_pk( + sqlite3_changeset_iter *pIter, /* Iterator object */ unsigned char **pabPK, /* OUT: Array of boolean - true for PK cols */ int *pnCol /* OUT: Number of entries in output array */ ){ @@ -207163,10 +207163,10 @@ SQLITE_API int tdsqlite3changeset_pk( /* ** This function may only be called while the iterator is pointing to an -** SQLITE_UPDATE or SQLITE_DELETE change (see tdsqlite3changeset_op()). +** SQLITE_UPDATE or SQLITE_DELETE change (see sqlite3changeset_op()). ** Otherwise, SQLITE_MISUSE is returned. ** -** It sets *ppValue to point to an tdsqlite3_value structure containing the +** It sets *ppValue to point to an sqlite3_value structure containing the ** iVal'th value in the old.* record. Or, if that particular value is not ** included in the record (because the change is an UPDATE and the field ** was not modified and is not a PK column), set *ppValue to NULL. @@ -207174,10 +207174,10 @@ SQLITE_API int tdsqlite3changeset_pk( ** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is ** not modified. Otherwise, SQLITE_OK. */ -SQLITE_API int tdsqlite3changeset_old( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ +SQLITE_API int sqlite3changeset_old( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Index of old.* value to retrieve */ - tdsqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ + sqlite3_value **ppValue /* OUT: Old value (or NULL pointer) */ ){ if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_DELETE ){ return SQLITE_MISUSE; @@ -207191,10 +207191,10 @@ SQLITE_API int tdsqlite3changeset_old( /* ** This function may only be called while the iterator is pointing to an -** SQLITE_UPDATE or SQLITE_INSERT change (see tdsqlite3changeset_op()). +** SQLITE_UPDATE or SQLITE_INSERT change (see sqlite3changeset_op()). ** Otherwise, SQLITE_MISUSE is returned. ** -** It sets *ppValue to point to an tdsqlite3_value structure containing the +** It sets *ppValue to point to an sqlite3_value structure containing the ** iVal'th value in the new.* record. Or, if that particular value is not ** included in the record (because the change is an UPDATE and the field ** was not modified), set *ppValue to NULL. @@ -207202,10 +207202,10 @@ SQLITE_API int tdsqlite3changeset_old( ** If value iVal is out-of-range, SQLITE_RANGE is returned and *ppValue is ** not modified. Otherwise, SQLITE_OK. */ -SQLITE_API int tdsqlite3changeset_new( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ +SQLITE_API int sqlite3changeset_new( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Index of new.* value to retrieve */ - tdsqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ + sqlite3_value **ppValue /* OUT: New value (or NULL pointer) */ ){ if( pIter->op!=SQLITE_UPDATE && pIter->op!=SQLITE_INSERT ){ return SQLITE_MISUSE; @@ -207219,7 +207219,7 @@ SQLITE_API int tdsqlite3changeset_new( /* ** The following two macros are used internally. They are similar to the -** tdsqlite3changeset_new() and tdsqlite3changeset_old() functions, except that +** sqlite3changeset_new() and sqlite3changeset_old() functions, except that ** they omit all error checking and return a pointer to the requested value. */ #define sessionChangesetNew(pIter, iVal) (pIter)->apValue[(pIter)->nCol+(iVal)] @@ -207230,16 +207230,16 @@ SQLITE_API int tdsqlite3changeset_new( ** passed to an SQLITE_CHANGESET_DATA or SQLITE_CHANGESET_CONFLICT ** conflict-handler function. Otherwise, SQLITE_MISUSE is returned. ** -** If successful, *ppValue is set to point to an tdsqlite3_value structure +** If successful, *ppValue is set to point to an sqlite3_value structure ** containing the iVal'th value of the conflicting record. ** ** If value iVal is out-of-range or some other error occurs, an SQLite error ** code is returned. Otherwise, SQLITE_OK. */ -SQLITE_API int tdsqlite3changeset_conflict( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ +SQLITE_API int sqlite3changeset_conflict( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ int iVal, /* Index of conflict record value to fetch */ - tdsqlite3_value **ppValue /* OUT: Value from conflicting row */ + sqlite3_value **ppValue /* OUT: Value from conflicting row */ ){ if( !pIter->pConflict ){ return SQLITE_MISUSE; @@ -207247,7 +207247,7 @@ SQLITE_API int tdsqlite3changeset_conflict( if( iVal<0 || iVal>=pIter->nCol ){ return SQLITE_RANGE; } - *ppValue = tdsqlite3_column_value(pIter->pConflict, iVal); + *ppValue = sqlite3_column_value(pIter->pConflict, iVal); return SQLITE_OK; } @@ -207259,8 +207259,8 @@ SQLITE_API int tdsqlite3changeset_conflict( ** ** In all other cases this function returns SQLITE_MISUSE. */ -SQLITE_API int tdsqlite3changeset_fk_conflicts( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ +SQLITE_API int sqlite3changeset_fk_conflicts( + sqlite3_changeset_iter *pIter, /* Changeset iterator */ int *pnOut /* OUT: Number of FK violations */ ){ if( pIter->pConflict || pIter->apValue ){ @@ -207272,22 +207272,22 @@ SQLITE_API int tdsqlite3changeset_fk_conflicts( /* -** Finalize an iterator allocated with tdsqlite3changeset_start(). +** Finalize an iterator allocated with sqlite3changeset_start(). ** ** This function may not be called on iterators passed to a conflict handler ** callback by changeset_apply(). */ -SQLITE_API int tdsqlite3changeset_finalize(tdsqlite3_changeset_iter *p){ +SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *p){ int rc = SQLITE_OK; if( p ){ int i; /* Used to iterate through p->apValue[] */ rc = p->rc; if( p->apValue ){ - for(i=0; inCol*2; i++) tdsqlite3ValueFree(p->apValue[i]); + for(i=0; inCol*2; i++) sqlite3ValueFree(p->apValue[i]); } - tdsqlite3_free(p->tblhdr.aBuf); - tdsqlite3_free(p->in.buf.aBuf); - tdsqlite3_free(p); + sqlite3_free(p->tblhdr.aBuf); + sqlite3_free(p->in.buf.aBuf); + sqlite3_free(p); } return rc; } @@ -207303,7 +207303,7 @@ static int sessionChangesetInvert( SessionBuffer sOut; /* Output buffer */ int nCol = 0; /* Number of cols in current table */ u8 *abPK = 0; /* PK array for current table */ - tdsqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */ + sqlite3_value **apVal = 0; /* Space for values for UPDATE inversion */ SessionBuffer sPK = {0, 0, 0}; /* PK array for current table */ /* Initialize the output buffer */ @@ -207346,7 +207346,7 @@ static int sessionChangesetInvert( if( rc ) goto finished_invert; pInput->iNext += nByte; - tdsqlite3_free(apVal); + sqlite3_free(apVal); apVal = 0; abPK = sPK.aBuf; break; @@ -207372,7 +207372,7 @@ static int sessionChangesetInvert( int iCol; if( 0==apVal ){ - apVal = (tdsqlite3_value **)tdsqlite3_malloc64(sizeof(apVal[0])*nCol*2); + apVal = (sqlite3_value **)sqlite3_malloc64(sizeof(apVal[0])*nCol*2); if( 0==apVal ){ rc = SQLITE_NOMEM; goto finished_invert; @@ -207395,7 +207395,7 @@ static int sessionChangesetInvert( ** original old.* record, and the other values from the original ** new.* record. */ for(iCol=0; iColpDelete, 0); + rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pDelete, 0); } - tdsqlite3_free(buf.aBuf); + sqlite3_free(buf.aBuf); return rc; } @@ -207608,7 +207608,7 @@ static int sessionDeleteRow( ** pointing to the prepared version of the SQL statement. */ static int sessionUpdateRow( - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ @@ -207665,9 +207665,9 @@ static int sessionUpdateRow( sessionAppendStr(&buf, ")", &rc); if( rc==SQLITE_OK ){ - rc = tdsqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0); + rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0); } - tdsqlite3_free(buf.aBuf); + sqlite3_free(buf.aBuf); return rc; } @@ -207687,7 +207687,7 @@ static int sessionUpdateRow( ** pointing to the prepared version of the SQL statement. */ static int sessionSelectRow( - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ @@ -207705,7 +207705,7 @@ static int sessionSelectRow( ** pointing to the prepared version of the SQL statement. */ static int sessionInsertRow( - tdsqlite3 *db, /* Database handle */ + sqlite3 *db, /* Database handle */ const char *zTab, /* Table name */ SessionApplyCtx *p /* Session changeset-apply context */ ){ @@ -207728,14 +207728,14 @@ static int sessionInsertRow( sessionAppendStr(&buf, ")", &rc); if( rc==SQLITE_OK ){ - rc = tdsqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0); + rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0); } - tdsqlite3_free(buf.aBuf); + sqlite3_free(buf.aBuf); return rc; } -static int sessionPrepare(tdsqlite3 *db, tdsqlite3_stmt **pp, const char *zSql){ - return tdsqlite3_prepare_v2(db, zSql, -1, pp, 0); +static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){ + return sqlite3_prepare_v2(db, zSql, -1, pp, 0); } /* @@ -207744,7 +207744,7 @@ static int sessionPrepare(tdsqlite3 *db, tdsqlite3_stmt **pp, const char *zSql){ ** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for ** other tables. */ -static int sessionStat1Sql(tdsqlite3 *db, SessionApplyCtx *p){ +static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){ int rc = sessionSelectRow(db, "sqlite_stat1", p); if( rc==SQLITE_OK ){ rc = sessionPrepare(db, &p->pInsert, @@ -207775,26 +207775,26 @@ static int sessionStat1Sql(tdsqlite3 *db, SessionApplyCtx *p){ } /* -** A wrapper around tdsqlite3_bind_value() that detects an extra problem. +** A wrapper around sqlite3_bind_value() that detects an extra problem. ** See comments in the body of this function for details. */ static int sessionBindValue( - tdsqlite3_stmt *pStmt, /* Statement to bind value to */ + sqlite3_stmt *pStmt, /* Statement to bind value to */ int i, /* Parameter number to bind to */ - tdsqlite3_value *pVal /* Value to bind */ + sqlite3_value *pVal /* Value to bind */ ){ - int eType = tdsqlite3_value_type(pVal); + int eType = sqlite3_value_type(pVal); /* COVERAGE: The (pVal->z==0) branch is never true using current versions - ** of SQLite. If a malloc fails in an tdsqlite3_value_xxx() function, either + ** of SQLite. If a malloc fails in an sqlite3_value_xxx() function, either ** the (pVal->z) variable remains as it was or the type of the value is ** set to SQLITE_NULL. */ if( (eType==SQLITE_TEXT || eType==SQLITE_BLOB) && pVal->z==0 ){ /* This condition occurs when an earlier OOM in a call to - ** tdsqlite3_value_text() or tdsqlite3_value_blob() (perhaps from within + ** sqlite3_value_text() or sqlite3_value_blob() (perhaps from within ** a conflict-handler) has zeroed the pVal->z pointer. Return NOMEM. */ return SQLITE_NOMEM; } - return tdsqlite3_bind_value(pStmt, i, pVal); + return sqlite3_bind_value(pStmt, i, pVal); } /* @@ -207812,24 +207812,24 @@ static int sessionBindValue( ** An SQLite error code is returned if an error occurs. Otherwise, SQLITE_OK. */ static int sessionBindRow( - tdsqlite3_changeset_iter *pIter, /* Iterator to read values from */ - int(*xValue)(tdsqlite3_changeset_iter *, int, tdsqlite3_value **), + sqlite3_changeset_iter *pIter, /* Iterator to read values from */ + int(*xValue)(sqlite3_changeset_iter *, int, sqlite3_value **), int nCol, /* Number of columns */ u8 *abPK, /* If not NULL, bind only if true */ - tdsqlite3_stmt *pStmt /* Bind values to this statement */ + sqlite3_stmt *pStmt /* Bind values to this statement */ ){ int i; int rc = SQLITE_OK; - /* Neither tdsqlite3changeset_old or tdsqlite3changeset_new can fail if the + /* Neither sqlite3changeset_old or sqlite3changeset_new can fail if the ** argument iterator points to a suitable entry. Make sure that xValue ** is one of these to guarantee that it is safe to ignore the return ** in the code below. */ - assert( xValue==tdsqlite3changeset_old || xValue==tdsqlite3changeset_new ); + assert( xValue==sqlite3changeset_old || xValue==sqlite3changeset_new ); for(i=0; rc==SQLITE_OK && ibRebase ){ @@ -207922,11 +207922,11 @@ static int sessionRebaseAdd( ); sessionAppendByte(&p->rebase, (eType==SQLITE_CHANGESET_REPLACE), &rc); for(i=0; inCol; i++){ - tdsqlite3_value *pVal = 0; + sqlite3_value *pVal = 0; if( eOp==SQLITE_DELETE || (eOp==SQLITE_UPDATE && p->abPK[i]) ){ - tdsqlite3changeset_old(pIter, i, &pVal); + sqlite3changeset_old(pIter, i, &pVal); }else{ - tdsqlite3changeset_new(pIter, i, &pVal); + sqlite3changeset_new(pIter, i, &pVal); } sessionAppendValue(&p->rebase, pVal, &rc); } @@ -207972,8 +207972,8 @@ static int sessionRebaseAdd( static int sessionConflictHandler( int eType, /* Either CHANGESET_DATA or CONFLICT */ SessionApplyCtx *p, /* changeset_apply() context */ - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ - int(*xConflict)(void *, int, tdsqlite3_changeset_iter*), + sqlite3_changeset_iter *pIter, /* Changeset iterator */ + int(*xConflict)(void *, int, sqlite3_changeset_iter*), void *pCtx, /* First argument for conflict handler */ int *pbReplace /* OUT: Set to true if PK row is found */ ){ @@ -207983,7 +207983,7 @@ static int sessionConflictHandler( int op; const char *zDummy; - tdsqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); + sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); assert( eType==SQLITE_CHANGESET_CONFLICT || eType==SQLITE_CHANGESET_DATA ); assert( SQLITE_CHANGESET_CONFLICT+1==SQLITE_CHANGESET_CONSTRAINT ); @@ -208001,7 +208001,7 @@ static int sessionConflictHandler( pIter->pConflict = p->pSelect; res = xConflict(pCtx, eType, pIter); pIter->pConflict = 0; - rc = tdsqlite3_reset(p->pSelect); + rc = sqlite3_reset(p->pSelect); }else if( rc==SQLITE_OK ){ if( p->bDeferConstraints && eType==SQLITE_CHANGESET_CONFLICT ){ /* Instead of invoking the conflict handler, append the change blob @@ -208068,9 +208068,9 @@ static int sessionConflictHandler( ** returned. */ static int sessionApplyOneOp( - tdsqlite3_changeset_iter *pIter, /* Changeset iterator */ + sqlite3_changeset_iter *pIter, /* Changeset iterator */ SessionApplyCtx *p, /* changeset_apply() context */ - int(*xConflict)(void *, int, tdsqlite3_changeset_iter *), + int(*xConflict)(void *, int, sqlite3_changeset_iter *), void *pCtx, /* First argument for the conflict handler */ int *pbReplace, /* OUT: True to remove PK row and retry */ int *pbRetry /* OUT: True to retry. */ @@ -208084,7 +208084,7 @@ static int sessionApplyOneOp( assert( p->azCol && p->abPK ); assert( !pbReplace || *pbReplace==0 ); - tdsqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); + sqlite3changeset_op(pIter, &zDummy, &nCol, &op, 0); if( op==SQLITE_DELETE ){ @@ -208100,15 +208100,15 @@ static int sessionApplyOneOp( ** no (nCol+1) variable to bind to). */ u8 *abPK = (pIter->bPatchset ? p->abPK : 0); - rc = sessionBindRow(pIter, tdsqlite3changeset_old, nCol, abPK, p->pDelete); - if( rc==SQLITE_OK && tdsqlite3_bind_parameter_count(p->pDelete)>nCol ){ - rc = tdsqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK)); + rc = sessionBindRow(pIter, sqlite3changeset_old, nCol, abPK, p->pDelete); + if( rc==SQLITE_OK && sqlite3_bind_parameter_count(p->pDelete)>nCol ){ + rc = sqlite3_bind_int(p->pDelete, nCol+1, (pbRetry==0 || abPK)); } if( rc!=SQLITE_OK ) return rc; - tdsqlite3_step(p->pDelete); - rc = tdsqlite3_reset(p->pDelete); - if( rc==SQLITE_OK && tdsqlite3_changes(p->db)==0 ){ + sqlite3_step(p->pDelete); + rc = sqlite3_reset(p->pDelete); + if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ rc = sessionConflictHandler( SQLITE_CHANGESET_DATA, p, pIter, xConflict, pCtx, pbRetry ); @@ -208123,10 +208123,10 @@ static int sessionApplyOneOp( /* Bind values to the UPDATE statement. */ for(i=0; rc==SQLITE_OK && ipUpdate, i*3+2, !!pNew); + sqlite3_bind_int(p->pUpdate, i*3+2, !!pNew); if( pOld ){ rc = sessionBindValue(p->pUpdate, i*3+1, pOld); } @@ -208135,16 +208135,16 @@ static int sessionApplyOneOp( } } if( rc==SQLITE_OK ){ - tdsqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset); + sqlite3_bind_int(p->pUpdate, nCol*3+1, pbRetry==0 || pIter->bPatchset); } if( rc!=SQLITE_OK ) return rc; /* Attempt the UPDATE. In the case of a NOTFOUND or DATA conflict, ** the result will be SQLITE_OK with 0 rows modified. */ - tdsqlite3_step(p->pUpdate); - rc = tdsqlite3_reset(p->pUpdate); + sqlite3_step(p->pUpdate); + rc = sqlite3_reset(p->pUpdate); - if( rc==SQLITE_OK && tdsqlite3_changes(p->db)==0 ){ + if( rc==SQLITE_OK && sqlite3_changes(p->db)==0 ){ /* A NOTFOUND or DATA error. Search the table to see if it contains ** a row with a matching primary key. If so, this is a DATA conflict. ** Otherwise, if there is no primary key match, it is a NOTFOUND. */ @@ -208169,16 +208169,16 @@ static int sessionApplyOneOp( rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect); if( rc==SQLITE_ROW ){ rc = SQLITE_CONSTRAINT; - tdsqlite3_reset(p->pSelect); + sqlite3_reset(p->pSelect); } } if( rc==SQLITE_OK ){ - rc = sessionBindRow(pIter, tdsqlite3changeset_new, nCol, 0, p->pInsert); + rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert); if( rc!=SQLITE_OK ) return rc; - tdsqlite3_step(p->pInsert); - rc = tdsqlite3_reset(p->pInsert); + sqlite3_step(p->pInsert); + rc = sqlite3_reset(p->pInsert); } if( (rc&0xff)==SQLITE_CONSTRAINT ){ @@ -208202,10 +208202,10 @@ static int sessionApplyOneOp( ** retried in some manner. */ static int sessionApplyOneWithRetry( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ - tdsqlite3_changeset_iter *pIter, /* Changeset iterator to read change from */ + sqlite3 *db, /* Apply change to "main" db of this handle */ + sqlite3_changeset_iter *pIter, /* Changeset iterator to read change from */ SessionApplyCtx *pApply, /* Apply context */ - int(*xConflict)(void*, int, tdsqlite3_changeset_iter*), + int(*xConflict)(void*, int, sqlite3_changeset_iter*), void *pCtx /* First argument passed to xConflict */ ){ int bReplace = 0; @@ -208233,21 +208233,21 @@ static int sessionApplyOneWithRetry( ** before reattempting the INSERT. */ else if( bReplace ){ assert( pIter->op==SQLITE_INSERT ); - rc = tdsqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); + rc = sqlite3_exec(db, "SAVEPOINT replace_op", 0, 0, 0); if( rc==SQLITE_OK ){ rc = sessionBindRow(pIter, - tdsqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); - tdsqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); + sqlite3changeset_new, pApply->nCol, pApply->abPK, pApply->pDelete); + sqlite3_bind_int(pApply->pDelete, pApply->nCol+1, 1); } if( rc==SQLITE_OK ){ - tdsqlite3_step(pApply->pDelete); - rc = tdsqlite3_reset(pApply->pDelete); + sqlite3_step(pApply->pDelete); + rc = sqlite3_reset(pApply->pDelete); } if( rc==SQLITE_OK ){ rc = sessionApplyOneOp(pIter, pApply, xConflict, pCtx, 0, 0); } if( rc==SQLITE_OK ){ - rc = tdsqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); + rc = sqlite3_exec(db, "RELEASE replace_op", 0, 0, 0); } } } @@ -208259,42 +208259,42 @@ static int sessionApplyOneWithRetry( ** Retry the changes accumulated in the pApply->constraints buffer. */ static int sessionRetryConstraints( - tdsqlite3 *db, + sqlite3 *db, int bPatchset, const char *zTab, SessionApplyCtx *pApply, - int(*xConflict)(void*, int, tdsqlite3_changeset_iter*), + int(*xConflict)(void*, int, sqlite3_changeset_iter*), void *pCtx /* First argument passed to xConflict */ ){ int rc = SQLITE_OK; while( pApply->constraints.nBuf ){ - tdsqlite3_changeset_iter *pIter2 = 0; + sqlite3_changeset_iter *pIter2 = 0; SessionBuffer cons = pApply->constraints; memset(&pApply->constraints, 0, sizeof(SessionBuffer)); rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0); if( rc==SQLITE_OK ){ - size_t nByte = 2*pApply->nCol*sizeof(tdsqlite3_value*); + size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*); int rc2; pIter2->bPatchset = bPatchset; pIter2->zTab = (char*)zTab; pIter2->nCol = pApply->nCol; pIter2->abPK = pApply->abPK; sessionBufferGrow(&pIter2->tblhdr, nByte, &rc); - pIter2->apValue = (tdsqlite3_value**)pIter2->tblhdr.aBuf; + pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf; if( rc==SQLITE_OK ) memset(pIter2->apValue, 0, nByte); - while( rc==SQLITE_OK && SQLITE_ROW==tdsqlite3changeset_next(pIter2) ){ + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter2) ){ rc = sessionApplyOneWithRetry(db, pIter2, pApply, xConflict, pCtx); } - rc2 = tdsqlite3changeset_finalize(pIter2); + rc2 = sqlite3changeset_finalize(pIter2); if( rc==SQLITE_OK ) rc = rc2; } assert( pApply->bDeferConstraints || pApply->constraints.nBuf==0 ); - tdsqlite3_free(cons.aBuf); + sqlite3_free(cons.aBuf); if( rc!=SQLITE_OK ) break; if( pApply->constraints.nBuf>=cons.nBuf ){ /* No progress was made on the last round. */ @@ -208307,14 +208307,14 @@ static int sessionRetryConstraints( /* ** Argument pIter is a changeset iterator that has been initialized, but -** not yet passed to tdsqlite3changeset_next(). This function applies the +** not yet passed to sqlite3changeset_next(). This function applies the ** changeset to the main database attached to handle "db". The supplied ** conflict handler callback is invoked to resolve any conflicts encountered ** while applying the change. */ static int sessionChangesetApply( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ - tdsqlite3_changeset_iter *pIter, /* Changeset to apply */ + sqlite3 *db, /* Apply change to "main" db of this handle */ + sqlite3_changeset_iter *pIter, /* Changeset to apply */ int(*xFilter)( void *pCtx, /* Copy of sixth arg to _apply() */ const char *zTab /* Table name */ @@ -208322,7 +208322,7 @@ static int sessionChangesetApply( int(*xConflict)( void *pCtx, /* Copy of fifth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, /* OUT: Rebase information */ @@ -208331,7 +208331,7 @@ static int sessionChangesetApply( int schemaMismatch = 0; int rc = SQLITE_OK; /* Return code */ const char *zTab = 0; /* Name of current table */ - int nTab = 0; /* Result of tdsqlite3Strlen30(zTab) */ + int nTab = 0; /* Result of sqlite3Strlen30(zTab) */ SessionApplyCtx sApply; /* changeset_apply() context object */ int bPatchset; @@ -208340,21 +208340,21 @@ static int sessionChangesetApply( pIter->in.bNoDiscard = 1; memset(&sApply, 0, sizeof(sApply)); sApply.bRebase = (ppRebase && pnRebase); - tdsqlite3_mutex_enter(tdsqlite3_db_mutex(db)); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ - rc = tdsqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); + rc = sqlite3_exec(db, "SAVEPOINT changeset_apply", 0, 0, 0); } if( rc==SQLITE_OK ){ - rc = tdsqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); + rc = sqlite3_exec(db, "PRAGMA defer_foreign_keys = 1", 0, 0, 0); } - while( rc==SQLITE_OK && SQLITE_ROW==tdsqlite3changeset_next(pIter) ){ + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3changeset_next(pIter) ){ int nCol; int op; const char *zNew; - tdsqlite3changeset_op(pIter, &zNew, &nCol, &op, 0); + sqlite3changeset_op(pIter, &zNew, &nCol, &op, 0); - if( zTab==0 || tdsqlite3_strnicmp(zNew, zTab, nTab+1) ){ + if( zTab==0 || sqlite3_strnicmp(zNew, zTab, nTab+1) ){ u8 *abPK; rc = sessionRetryConstraints( @@ -208362,11 +208362,11 @@ static int sessionChangesetApply( ); if( rc!=SQLITE_OK ) break; - tdsqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ - tdsqlite3_finalize(sApply.pDelete); - tdsqlite3_finalize(sApply.pUpdate); - tdsqlite3_finalize(sApply.pInsert); - tdsqlite3_finalize(sApply.pSelect); + sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ + sqlite3_finalize(sApply.pDelete); + sqlite3_finalize(sApply.pUpdate); + sqlite3_finalize(sApply.pInsert); + sqlite3_finalize(sApply.pSelect); sApply.db = db; sApply.pDelete = 0; sApply.pUpdate = 0; @@ -208385,7 +208385,7 @@ static int sessionChangesetApply( ** non-zero, proceed. */ schemaMismatch = (xFilter && (0==xFilter(pCtx, zNew))); if( schemaMismatch ){ - zTab = tdsqlite3_mprintf("%s", zNew); + zTab = sqlite3_mprintf("%s", zNew); if( zTab==0 ){ rc = SQLITE_NOMEM; break; @@ -208396,7 +208396,7 @@ static int sessionChangesetApply( int nMinCol = 0; int i; - tdsqlite3changeset_pk(pIter, &abPK, 0); + sqlite3changeset_pk(pIter, &abPK, 0); rc = sessionTableInfo( db, "main", zNew, &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK ); @@ -208407,27 +208407,27 @@ static int sessionChangesetApply( if( sApply.nCol==0 ){ schemaMismatch = 1; - tdsqlite3_log(SQLITE_SCHEMA, - "tdsqlite3changeset_apply(): no such table: %s", zTab + sqlite3_log(SQLITE_SCHEMA, + "sqlite3changeset_apply(): no such table: %s", zTab ); } else if( sApply.nColbPatchset; if( rc==SQLITE_OK ){ - rc = tdsqlite3changeset_finalize(pIter); + rc = sqlite3changeset_finalize(pIter); }else{ - tdsqlite3changeset_finalize(pIter); + sqlite3changeset_finalize(pIter); } if( rc==SQLITE_OK ){ @@ -208467,10 +208467,10 @@ static int sessionChangesetApply( if( rc==SQLITE_OK ){ int nFk, notUsed; - tdsqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, ¬Used, 0); + sqlite3_db_status(db, SQLITE_DBSTATUS_DEFERRED_FKS, &nFk, ¬Used, 0); if( nFk!=0 ){ int res = SQLITE_CHANGESET_ABORT; - tdsqlite3_changeset_iter sIter; + sqlite3_changeset_iter sIter; memset(&sIter, 0, sizeof(sIter)); sIter.nCol = nFk; res = xConflict(pCtx, SQLITE_CHANGESET_FOREIGN_KEY, &sIter); @@ -208479,14 +208479,14 @@ static int sessionChangesetApply( } } } - tdsqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); + sqlite3_exec(db, "PRAGMA defer_foreign_keys = 0", 0, 0, 0); if( (flags & SQLITE_CHANGESETAPPLY_NOSAVEPOINT)==0 ){ if( rc==SQLITE_OK ){ - rc = tdsqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); + rc = sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); }else{ - tdsqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); - tdsqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); + sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0); + sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0); } } @@ -208496,14 +208496,14 @@ static int sessionChangesetApply( *pnRebase = sApply.rebase.nBuf; sApply.rebase.aBuf = 0; } - tdsqlite3_finalize(sApply.pInsert); - tdsqlite3_finalize(sApply.pDelete); - tdsqlite3_finalize(sApply.pUpdate); - tdsqlite3_finalize(sApply.pSelect); - tdsqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ - tdsqlite3_free((char*)sApply.constraints.aBuf); - tdsqlite3_free((char*)sApply.rebase.aBuf); - tdsqlite3_mutex_leave(tdsqlite3_db_mutex(db)); + sqlite3_finalize(sApply.pInsert); + sqlite3_finalize(sApply.pDelete); + sqlite3_finalize(sApply.pUpdate); + sqlite3_finalize(sApply.pSelect); + sqlite3_free((char*)sApply.azCol); /* cast works around VC++ bug */ + sqlite3_free((char*)sApply.constraints.aBuf); + sqlite3_free((char*)sApply.rebase.aBuf); + sqlite3_mutex_leave(sqlite3_db_mutex(db)); return rc; } @@ -208511,8 +208511,8 @@ static int sessionChangesetApply( ** Apply the changeset passed via pChangeset/nChangeset to the main ** database attached to handle "db". */ -SQLITE_API int tdsqlite3changeset_apply_v2( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ +SQLITE_API int sqlite3changeset_apply_v2( + sqlite3 *db, /* Apply change to "main" db of this handle */ int nChangeset, /* Size of changeset in bytes */ void *pChangeset, /* Changeset blob */ int(*xFilter)( @@ -208522,13 +208522,13 @@ SQLITE_API int tdsqlite3changeset_apply_v2( int(*xConflict)( void *pCtx, /* Copy of sixth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, int flags ){ - tdsqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ + sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); int rc = sessionChangesetStart(&pIter, 0, 0, nChangeset, pChangeset,bInverse); if( rc==SQLITE_OK ){ @@ -208544,8 +208544,8 @@ SQLITE_API int tdsqlite3changeset_apply_v2( ** attached to handle "db". Invoke the supplied conflict handler callback ** to resolve any conflicts encountered while applying the change. */ -SQLITE_API int tdsqlite3changeset_apply( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ +SQLITE_API int sqlite3changeset_apply( + sqlite3 *db, /* Apply change to "main" db of this handle */ int nChangeset, /* Size of changeset in bytes */ void *pChangeset, /* Changeset blob */ int(*xFilter)( @@ -208555,11 +208555,11 @@ SQLITE_API int tdsqlite3changeset_apply( int(*xConflict)( void *pCtx, /* Copy of fifth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx /* First argument passed to xConflict */ ){ - return tdsqlite3changeset_apply_v2( + return sqlite3changeset_apply_v2( db, nChangeset, pChangeset, xFilter, xConflict, pCtx, 0, 0, 0 ); } @@ -208569,8 +208569,8 @@ SQLITE_API int tdsqlite3changeset_apply( ** attached to handle "db". Invoke the supplied conflict handler callback ** to resolve any conflicts encountered while applying the change. */ -SQLITE_API int tdsqlite3changeset_apply_v2_strm( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ +SQLITE_API int sqlite3changeset_apply_v2_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ void *pIn, /* First arg for xInput */ int(*xFilter)( @@ -208580,13 +208580,13 @@ SQLITE_API int tdsqlite3changeset_apply_v2_strm( int(*xConflict)( void *pCtx, /* Copy of sixth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx, /* First argument passed to xConflict */ void **ppRebase, int *pnRebase, int flags ){ - tdsqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ + sqlite3_changeset_iter *pIter; /* Iterator to skip through changeset */ int bInverse = !!(flags & SQLITE_CHANGESETAPPLY_INVERT); int rc = sessionChangesetStart(&pIter, xInput, pIn, 0, 0, bInverse); if( rc==SQLITE_OK ){ @@ -208596,8 +208596,8 @@ SQLITE_API int tdsqlite3changeset_apply_v2_strm( } return rc; } -SQLITE_API int tdsqlite3changeset_apply_strm( - tdsqlite3 *db, /* Apply change to "main" db of this handle */ +SQLITE_API int sqlite3changeset_apply_strm( + sqlite3 *db, /* Apply change to "main" db of this handle */ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */ void *pIn, /* First arg for xInput */ int(*xFilter)( @@ -208607,19 +208607,19 @@ SQLITE_API int tdsqlite3changeset_apply_strm( int(*xConflict)( void *pCtx, /* Copy of sixth arg to _apply() */ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */ - tdsqlite3_changeset_iter *p /* Handle describing change and conflict */ + sqlite3_changeset_iter *p /* Handle describing change and conflict */ ), void *pCtx /* First argument passed to xConflict */ ){ - return tdsqlite3changeset_apply_v2_strm( + return sqlite3changeset_apply_v2_strm( db, xInput, pIn, xFilter, xConflict, pCtx, 0, 0, 0 ); } /* -** tdsqlite3_changegroup handle. +** sqlite3_changegroup handle. */ -struct tdsqlite3_changegroup { +struct sqlite3_changegroup { int rc; /* Error code */ int bPatch; /* True to accumulate patchsets */ SessionTable *pList; /* List of tables in current patch */ @@ -208627,7 +208627,7 @@ struct tdsqlite3_changegroup { /* ** This function is called to merge two changes to the same row together as -** part of an tdsqlite3changeset_concat() operation. A new change object is +** part of an sqlite3changeset_concat() operation. A new change object is ** allocated and a pointer to it stored in *ppNew. */ static int sessionChangeMerge( @@ -208645,7 +208645,7 @@ static int sessionChangeMerge( int rc = SQLITE_OK; if( !pExist ){ - pNew = (SessionChange *)tdsqlite3_malloc64(sizeof(SessionChange) + nRec); + pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec); if( !pNew ){ return SQLITE_NOMEM; } @@ -208678,8 +208678,8 @@ static int sessionChangeMerge( if( pExist->op==SQLITE_DELETE && pExist->bIndirect ){ *ppNew = pExist; }else{ - tdsqlite3_int64 nByte = nRec + pExist->nRecord + sizeof(SessionChange); - pNew = (SessionChange*)tdsqlite3_malloc64(nByte); + sqlite3_int64 nByte = nRec + pExist->nRecord + sizeof(SessionChange); + pNew = (SessionChange*)sqlite3_malloc64(nByte); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ @@ -208710,7 +208710,7 @@ static int sessionChangeMerge( } pNew->nRecord = pOut - pNew->aRecord; } - tdsqlite3_free(pExist); + sqlite3_free(pExist); } }else{ int op1 = pExist->op; @@ -208735,20 +208735,20 @@ static int sessionChangeMerge( ){ pNew = pExist; }else if( op1==SQLITE_INSERT && op2==SQLITE_DELETE ){ - tdsqlite3_free(pExist); + sqlite3_free(pExist); assert( pNew==0 ); }else{ u8 *aExist = pExist->aRecord; - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; u8 *aCsr; /* Allocate a new SessionChange object. Ensure that the aRecord[] ** buffer of the new object is large enough to hold any record that ** may be generated by combining the input records. */ nByte = sizeof(SessionChange) + pExist->nRecord + nRec; - pNew = (SessionChange *)tdsqlite3_malloc64(nByte); + pNew = (SessionChange *)sqlite3_malloc64(nByte); if( !pNew ){ - tdsqlite3_free(pExist); + sqlite3_free(pExist); return SQLITE_NOMEM; } memset(pNew, 0, sizeof(SessionChange)); @@ -208769,7 +208769,7 @@ static int sessionChangeMerge( aCsr += nRec; }else{ if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aExist, 0,aRec,0) ){ - tdsqlite3_free(pNew); + sqlite3_free(pNew); pNew = 0; } } @@ -208783,7 +208783,7 @@ static int sessionChangeMerge( } pNew->op = SQLITE_UPDATE; if( 0==sessionMergeUpdate(&aCsr, pTab, bPatchset, aRec, aExist,a1,a2) ){ - tdsqlite3_free(pNew); + sqlite3_free(pNew); pNew = 0; } }else{ /* UPDATE + DELETE */ @@ -208800,7 +208800,7 @@ static int sessionChangeMerge( if( pNew ){ pNew->nRecord = (int)(aCsr - pNew->aRecord); } - tdsqlite3_free(pExist); + sqlite3_free(pExist); } } @@ -208813,8 +208813,8 @@ static int sessionChangeMerge( ** the first argument to the changegroup hash tables. */ static int sessionChangesetToHash( - tdsqlite3_changeset_iter *pIter, /* Iterator to read from */ - tdsqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ + sqlite3_changeset_iter *pIter, /* Iterator to read from */ + sqlite3_changegroup *pGrp, /* Changegroup object to add changeset to */ int bRebase /* True if hash table is for rebasing */ ){ u8 *aRec; @@ -208839,20 +208839,20 @@ static int sessionChangesetToHash( break; } - tdsqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); - if( !pTab || tdsqlite3_stricmp(zNew, pTab->zName) ){ + sqlite3changeset_op(pIter, &zNew, &nCol, &op, &bIndirect); + if( !pTab || sqlite3_stricmp(zNew, pTab->zName) ){ /* Search the list for a matching table */ int nNew = (int)strlen(zNew); u8 *abPK; - tdsqlite3changeset_pk(pIter, &abPK, 0); + sqlite3changeset_pk(pIter, &abPK, 0); for(pTab = pGrp->pList; pTab; pTab=pTab->pNext){ - if( 0==tdsqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; + if( 0==sqlite3_strnicmp(pTab->zName, zNew, nNew+1) ) break; } if( !pTab ){ SessionTable **ppTab; - pTab = tdsqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1); + pTab = sqlite3_malloc64(sizeof(SessionTable) + nCol + nNew+1); if( !pTab ){ rc = SQLITE_NOMEM; break; @@ -208866,7 +208866,7 @@ static int sessionChangesetToHash( /* The new object must be linked on to the end of the list, not ** simply added to the start of it. This is to ensure that the - ** tables within the output of tdsqlite3changegroup_output() are in + ** tables within the output of sqlite3changegroup_output() are in ** the right order. */ for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); *ppTab = pTab; @@ -208929,14 +208929,14 @@ static int sessionChangesetToHash( ** buffer containing the output changeset before this function returns. In ** this case (*pnOut) is set to the size of the output buffer in bytes. It ** is the responsibility of the caller to free the output buffer using -** tdsqlite3_free() when it is no longer required. +** sqlite3_free() when it is no longer required. ** ** If successful, SQLITE_OK is returned. Or, if an error occurs, an SQLite ** error code. If an error occurs and xOutput is NULL, (*ppOut) and (*pnOut) ** are both set to 0 before returning. */ static int sessionChangegroupOutput( - tdsqlite3_changegroup *pGrp, + sqlite3_changegroup *pGrp, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut, int *pnOut, @@ -208978,22 +208978,22 @@ static int sessionChangegroupOutput( buf.aBuf = 0; } } - tdsqlite3_free(buf.aBuf); + sqlite3_free(buf.aBuf); return rc; } /* -** Allocate a new, empty, tdsqlite3_changegroup. +** Allocate a new, empty, sqlite3_changegroup. */ -SQLITE_API int tdsqlite3changegroup_new(tdsqlite3_changegroup **pp){ +SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp){ int rc = SQLITE_OK; /* Return code */ - tdsqlite3_changegroup *p; /* New object */ - p = (tdsqlite3_changegroup*)tdsqlite3_malloc(sizeof(tdsqlite3_changegroup)); + sqlite3_changegroup *p; /* New object */ + p = (sqlite3_changegroup*)sqlite3_malloc(sizeof(sqlite3_changegroup)); if( p==0 ){ rc = SQLITE_NOMEM; }else{ - memset(p, 0, sizeof(tdsqlite3_changegroup)); + memset(p, 0, sizeof(sqlite3_changegroup)); } *pp = p; return rc; @@ -209003,15 +209003,15 @@ SQLITE_API int tdsqlite3changegroup_new(tdsqlite3_changegroup **pp){ ** Add the changeset currently stored in buffer pData, size nData bytes, ** to changeset-group p. */ -SQLITE_API int tdsqlite3changegroup_add(tdsqlite3_changegroup *pGrp, int nData, void *pData){ - tdsqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */ +SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup *pGrp, int nData, void *pData){ + sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */ int rc; /* Return code */ - rc = tdsqlite3changeset_start(&pIter, nData, pData); + rc = sqlite3changeset_start(&pIter, nData, pData); if( rc==SQLITE_OK ){ rc = sessionChangesetToHash(pIter, pGrp, 0); } - tdsqlite3changeset_finalize(pIter); + sqlite3changeset_finalize(pIter); return rc; } @@ -209019,8 +209019,8 @@ SQLITE_API int tdsqlite3changegroup_add(tdsqlite3_changegroup *pGrp, int nData, ** Obtain a buffer containing a changeset representing the concatenation ** of all changesets added to the group so far. */ -SQLITE_API int tdsqlite3changegroup_output( - tdsqlite3_changegroup *pGrp, +SQLITE_API int sqlite3changegroup_output( + sqlite3_changegroup *pGrp, int *pnData, void **ppData ){ @@ -209030,27 +209030,27 @@ SQLITE_API int tdsqlite3changegroup_output( /* ** Streaming versions of changegroup_add(). */ -SQLITE_API int tdsqlite3changegroup_add_strm( - tdsqlite3_changegroup *pGrp, +SQLITE_API int sqlite3changegroup_add_strm( + sqlite3_changegroup *pGrp, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn ){ - tdsqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */ + sqlite3_changeset_iter *pIter; /* Iterator opened on pData/nData */ int rc; /* Return code */ - rc = tdsqlite3changeset_start_strm(&pIter, xInput, pIn); + rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); if( rc==SQLITE_OK ){ rc = sessionChangesetToHash(pIter, pGrp, 0); } - tdsqlite3changeset_finalize(pIter); + sqlite3changeset_finalize(pIter); return rc; } /* ** Streaming versions of changegroup_output(). */ -SQLITE_API int tdsqlite3changegroup_output_strm( - tdsqlite3_changegroup *pGrp, +SQLITE_API int sqlite3changegroup_output_strm( + sqlite3_changegroup *pGrp, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ){ @@ -209060,17 +209060,17 @@ SQLITE_API int tdsqlite3changegroup_output_strm( /* ** Delete a changegroup object. */ -SQLITE_API void tdsqlite3changegroup_delete(tdsqlite3_changegroup *pGrp){ +SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ sessionDeleteTable(pGrp->pList); - tdsqlite3_free(pGrp); + sqlite3_free(pGrp); } } /* ** Combine two changesets together. */ -SQLITE_API int tdsqlite3changeset_concat( +SQLITE_API int sqlite3changeset_concat( int nLeft, /* Number of bytes in lhs input */ void *pLeft, /* Lhs input changeset */ int nRight /* Number of bytes in rhs input */, @@ -209078,28 +209078,28 @@ SQLITE_API int tdsqlite3changeset_concat( int *pnOut, /* OUT: Number of bytes in output changeset */ void **ppOut /* OUT: changeset (left right) */ ){ - tdsqlite3_changegroup *pGrp; + sqlite3_changegroup *pGrp; int rc; - rc = tdsqlite3changegroup_new(&pGrp); + rc = sqlite3changegroup_new(&pGrp); if( rc==SQLITE_OK ){ - rc = tdsqlite3changegroup_add(pGrp, nLeft, pLeft); + rc = sqlite3changegroup_add(pGrp, nLeft, pLeft); } if( rc==SQLITE_OK ){ - rc = tdsqlite3changegroup_add(pGrp, nRight, pRight); + rc = sqlite3changegroup_add(pGrp, nRight, pRight); } if( rc==SQLITE_OK ){ - rc = tdsqlite3changegroup_output(pGrp, pnOut, ppOut); + rc = sqlite3changegroup_output(pGrp, pnOut, ppOut); } - tdsqlite3changegroup_delete(pGrp); + sqlite3changegroup_delete(pGrp); return rc; } /* -** Streaming version of tdsqlite3changeset_concat(). +** Streaming version of sqlite3changeset_concat(). */ -SQLITE_API int tdsqlite3changeset_concat_strm( +SQLITE_API int sqlite3changeset_concat_strm( int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA, int (*xInputB)(void *pIn, void *pData, int *pnData), @@ -209107,20 +209107,20 @@ SQLITE_API int tdsqlite3changeset_concat_strm( int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ){ - tdsqlite3_changegroup *pGrp; + sqlite3_changegroup *pGrp; int rc; - rc = tdsqlite3changegroup_new(&pGrp); + rc = sqlite3changegroup_new(&pGrp); if( rc==SQLITE_OK ){ - rc = tdsqlite3changegroup_add_strm(pGrp, xInputA, pInA); + rc = sqlite3changegroup_add_strm(pGrp, xInputA, pInA); } if( rc==SQLITE_OK ){ - rc = tdsqlite3changegroup_add_strm(pGrp, xInputB, pInB); + rc = sqlite3changegroup_add_strm(pGrp, xInputB, pInB); } if( rc==SQLITE_OK ){ - rc = tdsqlite3changegroup_output_strm(pGrp, xOutput, pOut); + rc = sqlite3changegroup_output_strm(pGrp, xOutput, pOut); } - tdsqlite3changegroup_delete(pGrp); + sqlite3changegroup_delete(pGrp); return rc; } @@ -209128,8 +209128,8 @@ SQLITE_API int tdsqlite3changeset_concat_strm( /* ** Changeset rebaser handle. */ -struct tdsqlite3_rebaser { - tdsqlite3_changegroup grp; /* Hash table */ +struct sqlite3_rebaser { + sqlite3_changegroup grp; /* Hash table */ }; /* @@ -209189,7 +209189,7 @@ static void sessionAppendRecordMerge( */ static void sessionAppendPartialUpdate( SessionBuffer *pBuf, /* Append record here */ - tdsqlite3_changeset_iter *pIter, /* Iterator pointed at local change */ + sqlite3_changeset_iter *pIter, /* Iterator pointed at local change */ u8 *aRec, int nRec, /* Local change */ u8 *aChange, int nChange, /* Record to rebase against */ int *pRc /* IN/OUT: Return Code */ @@ -209249,15 +209249,15 @@ static void sessionAppendPartialUpdate( ** then (*ppOut) is set to point to a buffer containing the rebased changeset ** before this function returns. In this case (*pnOut) is set to the size of ** the buffer in bytes. It is the responsibility of the caller to eventually -** free the (*ppOut) buffer using tdsqlite3_free(). +** free the (*ppOut) buffer using sqlite3_free(). ** ** If an error occurs, an SQLite error code is returned. If ppOut and ** pnOut are not NULL, then the two output parameters are set to 0 before ** returning. */ static int sessionRebase( - tdsqlite3_rebaser *p, /* Rebaser hash table */ - tdsqlite3_changeset_iter *pIter, /* Input data */ + sqlite3_rebaser *p, /* Rebaser hash table */ + sqlite3_changeset_iter *pIter, /* Input data */ int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut, /* Context for xOutput callback */ int *pnOut, /* OUT: Number of bytes in output changeset */ @@ -209277,7 +209277,7 @@ static int sessionRebase( if( bNew ){ const char *zTab = pIter->zTab; for(pTab=p->grp.pList; pTab; pTab=pTab->pNext){ - if( 0==tdsqlite3_stricmp(pTab->zName, zTab) ) break; + if( 0==sqlite3_stricmp(pTab->zName, zTab) ) break; } bNew = 0; @@ -209365,7 +209365,7 @@ static int sessionRebase( } if( rc!=SQLITE_OK ){ - tdsqlite3_free(sOut.aBuf); + sqlite3_free(sOut.aBuf); memset(&sOut, 0, sizeof(sOut)); } @@ -209380,22 +209380,22 @@ static int sessionRebase( sOut.aBuf = 0; } } - tdsqlite3_free(sOut.aBuf); + sqlite3_free(sOut.aBuf); return rc; } /* ** Create a new rebaser object. */ -SQLITE_API int tdsqlite3rebaser_create(tdsqlite3_rebaser **ppNew){ +SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew){ int rc = SQLITE_OK; - tdsqlite3_rebaser *pNew; + sqlite3_rebaser *pNew; - pNew = tdsqlite3_malloc(sizeof(tdsqlite3_rebaser)); + pNew = sqlite3_malloc(sizeof(sqlite3_rebaser)); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ - memset(pNew, 0, sizeof(tdsqlite3_rebaser)); + memset(pNew, 0, sizeof(sqlite3_rebaser)); } *ppNew = pNew; return rc; @@ -209404,34 +209404,34 @@ SQLITE_API int tdsqlite3rebaser_create(tdsqlite3_rebaser **ppNew){ /* ** Call this one or more times to configure a rebaser. */ -SQLITE_API int tdsqlite3rebaser_configure( - tdsqlite3_rebaser *p, +SQLITE_API int sqlite3rebaser_configure( + sqlite3_rebaser *p, int nRebase, const void *pRebase ){ - tdsqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ + sqlite3_changeset_iter *pIter = 0; /* Iterator opened on pData/nData */ int rc; /* Return code */ - rc = tdsqlite3changeset_start(&pIter, nRebase, (void*)pRebase); + rc = sqlite3changeset_start(&pIter, nRebase, (void*)pRebase); if( rc==SQLITE_OK ){ rc = sessionChangesetToHash(pIter, &p->grp, 1); } - tdsqlite3changeset_finalize(pIter); + sqlite3changeset_finalize(pIter); return rc; } /* ** Rebase a changeset according to current rebaser configuration */ -SQLITE_API int tdsqlite3rebaser_rebase( - tdsqlite3_rebaser *p, +SQLITE_API int sqlite3rebaser_rebase( + sqlite3_rebaser *p, int nIn, const void *pIn, int *pnOut, void **ppOut ){ - tdsqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ - int rc = tdsqlite3changeset_start(&pIter, nIn, (void*)pIn); + sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ + int rc = sqlite3changeset_start(&pIter, nIn, (void*)pIn); if( rc==SQLITE_OK ){ rc = sessionRebase(p, pIter, 0, 0, pnOut, ppOut); - tdsqlite3changeset_finalize(pIter); + sqlite3changeset_finalize(pIter); } return rc; @@ -209440,19 +209440,19 @@ SQLITE_API int tdsqlite3rebaser_rebase( /* ** Rebase a changeset according to current rebaser configuration */ -SQLITE_API int tdsqlite3rebaser_rebase_strm( - tdsqlite3_rebaser *p, +SQLITE_API int sqlite3rebaser_rebase_strm( + sqlite3_rebaser *p, int (*xInput)(void *pIn, void *pData, int *pnData), void *pIn, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut ){ - tdsqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ - int rc = tdsqlite3changeset_start_strm(&pIter, xInput, pIn); + sqlite3_changeset_iter *pIter = 0; /* Iterator to skip through input */ + int rc = sqlite3changeset_start_strm(&pIter, xInput, pIn); if( rc==SQLITE_OK ){ rc = sessionRebase(p, pIter, xOutput, pOut, 0, 0); - tdsqlite3changeset_finalize(pIter); + sqlite3changeset_finalize(pIter); } return rc; @@ -209461,17 +209461,17 @@ SQLITE_API int tdsqlite3rebaser_rebase_strm( /* ** Destroy a rebaser object */ -SQLITE_API void tdsqlite3rebaser_delete(tdsqlite3_rebaser *p){ +SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p){ if( p ){ sessionDeleteTable(p->grp.pList); - tdsqlite3_free(p); + sqlite3_free(p); } } /* ** Global configuration */ -SQLITE_API int tdsqlite3session_config(int op, void *pArg){ +SQLITE_API int sqlite3session_config(int op, void *pArg){ int rc = SQLITE_OK; switch( op ){ case SQLITE_SESSION_CONFIG_STRMSIZE: { @@ -209491,7 +209491,7 @@ SQLITE_API int tdsqlite3session_config(int op, void *pArg){ #endif /* SQLITE_ENABLE_SESSION && SQLITE_ENABLE_PREUPDATE_HOOK */ -/************** End of tdsqlite3session.c **************************************/ +/************** End of sqlite3session.c **************************************/ /************** Begin file fts5.c ********************************************/ @@ -209537,7 +209537,7 @@ extern "C" { ** CUSTOM AUXILIARY FUNCTIONS ** ** Virtual table implementations may overload SQL functions by implementing -** the tdsqlite3_module.xFindFunction() method. +** the sqlite3_module.xFindFunction() method. */ typedef struct Fts5ExtensionApi Fts5ExtensionApi; @@ -209547,9 +209547,9 @@ typedef struct Fts5PhraseIter Fts5PhraseIter; typedef void (*fts5_extension_function)( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ - tdsqlite3_context *pCtx, /* Context for returning result/error */ + sqlite3_context *pCtx, /* Context for returning result/error */ int nVal, /* Number of values in apVal[] array */ - tdsqlite3_value **apVal /* Array of trailing arguments */ + sqlite3_value **apVal /* Array of trailing arguments */ ); struct Fts5PhraseIter { @@ -209774,8 +209774,8 @@ struct Fts5ExtensionApi { void *(*xUserData)(Fts5Context*); int (*xColumnCount)(Fts5Context*); - int (*xRowCount)(Fts5Context*, tdsqlite3_int64 *pnRow); - int (*xColumnTotalSize)(Fts5Context*, int iCol, tdsqlite3_int64 *pnToken); + int (*xRowCount)(Fts5Context*, sqlite3_int64 *pnRow); + int (*xColumnTotalSize)(Fts5Context*, int iCol, sqlite3_int64 *pnToken); int (*xTokenize)(Fts5Context*, const char *pText, int nText, /* Text to tokenize */ @@ -209789,7 +209789,7 @@ struct Fts5ExtensionApi { int (*xInstCount)(Fts5Context*, int *pnInst); int (*xInst)(Fts5Context*, int iIdx, int *piPhrase, int *piCol, int *piOff); - tdsqlite3_int64 (*xRowid)(Fts5Context*); + sqlite3_int64 (*xRowid)(Fts5Context*); int (*xColumnText)(Fts5Context*, int iCol, const char **pz, int *pn); int (*xColumnSize)(Fts5Context*, int iCol, int *pnToken); @@ -210097,7 +210097,7 @@ struct fts5_api { #define _FTS5INT_H /* #include "fts5.h" */ -/* #include "tdsqlite3ext.h" */ +/* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 /* #include */ @@ -210109,8 +210109,8 @@ typedef unsigned char u8; typedef unsigned int u32; typedef unsigned short u16; typedef short i16; -typedef tdsqlite3_int64 i64; -typedef tdsqlite3_uint64 u64; +typedef sqlite3_int64 i64; +typedef sqlite3_uint64 u64; #ifndef ArraySize # define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0]))) @@ -210156,8 +210156,8 @@ typedef tdsqlite3_uint64 u64; #define FTS5_ROWID_NAME "rowid" #ifdef SQLITE_DEBUG -# define FTS5_CORRUPT tdsqlite3Fts5Corrupt() -static int tdsqlite3Fts5Corrupt(void); +# define FTS5_CORRUPT sqlite3Fts5Corrupt() +static int sqlite3Fts5Corrupt(void); #else # define FTS5_CORRUPT SQLITE_CORRUPT_VTAB #endif @@ -210168,8 +210168,8 @@ static int tdsqlite3Fts5Corrupt(void); ** guranteed that the database is not corrupt. */ #ifdef SQLITE_DEBUG -SQLITE_API extern int tdsqlite3_fts5_may_be_corrupt; -# define assert_nc(x) assert(tdsqlite3_fts5_may_be_corrupt || (x)) +SQLITE_API extern int sqlite3_fts5_may_be_corrupt; +# define assert_nc(x) assert(sqlite3_fts5_may_be_corrupt || (x)) #else # define assert_nc(x) assert(x) #endif @@ -210249,7 +210249,7 @@ typedef struct Fts5Config Fts5Config; ** */ struct Fts5Config { - tdsqlite3 *db; /* Database handle */ + sqlite3 *db; /* Database handle */ char *zDb; /* Database holding FTS index (e.g. "main") */ char *zName; /* Name of FTS index */ int nCol; /* Number of columns */ @@ -210277,7 +210277,7 @@ struct Fts5Config { char *zRank; /* Name of rank function */ char *zRankArgs; /* Arguments to rank function */ - /* If non-NULL, points to tdsqlite3_vtab.base.zErrmsg. Often NULL. */ + /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ char **pzErrmsg; #ifdef SQLITE_DEBUG @@ -210298,14 +210298,14 @@ struct Fts5Config { -static int tdsqlite3Fts5ConfigParse( - Fts5Global*, tdsqlite3*, int, const char **, Fts5Config**, char** +static int sqlite3Fts5ConfigParse( + Fts5Global*, sqlite3*, int, const char **, Fts5Config**, char** ); -static void tdsqlite3Fts5ConfigFree(Fts5Config*); +static void sqlite3Fts5ConfigFree(Fts5Config*); -static int tdsqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig); +static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig); -static int tdsqlite3Fts5Tokenize( +static int sqlite3Fts5Tokenize( Fts5Config *pConfig, /* FTS5 Configuration object */ int flags, /* FTS5_TOKENIZE_* flags */ const char *pText, int nText, /* Text to tokenize */ @@ -210313,15 +210313,15 @@ static int tdsqlite3Fts5Tokenize( int (*xToken)(void*, int, const char*, int, int, int) /* Callback */ ); -static void tdsqlite3Fts5Dequote(char *z); +static void sqlite3Fts5Dequote(char *z); /* Load the contents of the %_config table */ -static int tdsqlite3Fts5ConfigLoad(Fts5Config*, int); +static int sqlite3Fts5ConfigLoad(Fts5Config*, int); /* Set the value of a single config attribute */ -static int tdsqlite3Fts5ConfigSetValue(Fts5Config*, const char*, tdsqlite3_value*, int*); +static int sqlite3Fts5ConfigSetValue(Fts5Config*, const char*, sqlite3_value*, int*); -static int tdsqlite3Fts5ConfigParseRank(const char*, char**, char**); +static int sqlite3Fts5ConfigParseRank(const char*, char**, char**); /* ** End of interface to code in fts5_config.c. @@ -210341,38 +210341,38 @@ struct Fts5Buffer { int nSpace; }; -static int tdsqlite3Fts5BufferSize(int*, Fts5Buffer*, u32); -static void tdsqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64); -static void tdsqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*); -static void tdsqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*); -static void tdsqlite3Fts5BufferFree(Fts5Buffer*); -static void tdsqlite3Fts5BufferZero(Fts5Buffer*); -static void tdsqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*); -static void tdsqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...); +static int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32); +static void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64); +static void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*); +static void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*); +static void sqlite3Fts5BufferFree(Fts5Buffer*); +static void sqlite3Fts5BufferZero(Fts5Buffer*); +static void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*); +static void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...); -static char *tdsqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); +static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); -#define fts5BufferZero(x) tdsqlite3Fts5BufferZero(x) -#define fts5BufferAppendVarint(a,b,c) tdsqlite3Fts5BufferAppendVarint(a,b,c) -#define fts5BufferFree(a) tdsqlite3Fts5BufferFree(a) -#define fts5BufferAppendBlob(a,b,c,d) tdsqlite3Fts5BufferAppendBlob(a,b,c,d) -#define fts5BufferSet(a,b,c,d) tdsqlite3Fts5BufferSet(a,b,c,d) +#define fts5BufferZero(x) sqlite3Fts5BufferZero(x) +#define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c) +#define fts5BufferFree(a) sqlite3Fts5BufferFree(a) +#define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d) +#define fts5BufferSet(a,b,c,d) sqlite3Fts5BufferSet(a,b,c,d) #define fts5BufferGrow(pRc,pBuf,nn) ( \ (u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \ - tdsqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \ + sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \ ) /* Write and decode big-endian 32-bit integer values */ -static void tdsqlite3Fts5Put32(u8*, int); -static int tdsqlite3Fts5Get32(const u8*); +static void sqlite3Fts5Put32(u8*, int); +static int sqlite3Fts5Get32(const u8*); #define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32) #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0x7FFFFFFF) typedef struct Fts5PoslistReader Fts5PoslistReader; struct Fts5PoslistReader { - /* Variables used only by tdsqlite3Fts5PoslistIterXXX() functions. */ + /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */ const u8 *a; /* Position list to iterate through */ int n; /* Size of buffer at a[] in bytes */ int i; /* Current offset in a[] */ @@ -210383,38 +210383,38 @@ struct Fts5PoslistReader { u8 bEof; /* Set to true at EOF */ i64 iPos; /* (iCol<<32) + iPos */ }; -static int tdsqlite3Fts5PoslistReaderInit( +static int sqlite3Fts5PoslistReaderInit( const u8 *a, int n, /* Poslist buffer to iterate through */ Fts5PoslistReader *pIter /* Iterator object to initialize */ ); -static int tdsqlite3Fts5PoslistReaderNext(Fts5PoslistReader*); +static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*); typedef struct Fts5PoslistWriter Fts5PoslistWriter; struct Fts5PoslistWriter { i64 iPrev; }; -static int tdsqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64); -static void tdsqlite3Fts5PoslistSafeAppend(Fts5Buffer*, i64*, i64); +static int sqlite3Fts5PoslistWriterAppend(Fts5Buffer*, Fts5PoslistWriter*, i64); +static void sqlite3Fts5PoslistSafeAppend(Fts5Buffer*, i64*, i64); -static int tdsqlite3Fts5PoslistNext64( +static int sqlite3Fts5PoslistNext64( const u8 *a, int n, /* Buffer containing poslist */ int *pi, /* IN/OUT: Offset within a[] */ i64 *piOff /* IN/OUT: Current offset */ ); /* Malloc utility */ -static void *tdsqlite3Fts5MallocZero(int *pRc, tdsqlite3_int64 nByte); -static char *tdsqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn); +static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte); +static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn); /* Character set tests (like isspace(), isalpha() etc.) */ -static int tdsqlite3Fts5IsBareword(char t); +static int sqlite3Fts5IsBareword(char t); /* Bucket of terms object used by the integrity-check in offsets=0 mode. */ typedef struct Fts5Termset Fts5Termset; -static int tdsqlite3Fts5TermsetNew(Fts5Termset**); -static int tdsqlite3Fts5TermsetAdd(Fts5Termset*, int, const char*, int, int *pbPresent); -static void tdsqlite3Fts5TermsetFree(Fts5Termset*); +static int sqlite3Fts5TermsetNew(Fts5Termset**); +static int sqlite3Fts5TermsetAdd(Fts5Termset*, int, const char*, int, int *pbPresent); +static void sqlite3Fts5TermsetFree(Fts5Termset*); /* ** End of interface to code in fts5_buffer.c. @@ -210435,7 +210435,7 @@ struct Fts5IndexIter { u8 bEof; }; -#define tdsqlite3Fts5IterEof(x) ((x)->bEof) +#define sqlite3Fts5IterEof(x) ((x)->bEof) /* ** Values used as part of the flags argument passed to IndexQuery(). @@ -210454,13 +210454,13 @@ struct Fts5IndexIter { /* ** Create/destroy an Fts5Index object. */ -static int tdsqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**); -static int tdsqlite3Fts5IndexClose(Fts5Index *p); +static int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**); +static int sqlite3Fts5IndexClose(Fts5Index *p); /* ** Return a simple checksum value based on the arguments. */ -static u64 tdsqlite3Fts5IndexEntryCksum( +static u64 sqlite3Fts5IndexEntryCksum( i64 iRowid, int iCol, int iPos, @@ -210474,7 +210474,7 @@ static u64 tdsqlite3Fts5IndexEntryCksum( ** size. Return the number of bytes in the nChar character prefix of the ** buffer, or 0 if there are less than nChar characters in total. */ -static int tdsqlite3Fts5IndexCharlenToBytelen( +static int sqlite3Fts5IndexCharlenToBytelen( const char *p, int nByte, int nChar @@ -210484,7 +210484,7 @@ static int tdsqlite3Fts5IndexCharlenToBytelen( ** Open a new iterator to iterate though all rowids that match the ** specified token or token prefix. */ -static int tdsqlite3Fts5IndexQuery( +static int sqlite3Fts5IndexQuery( Fts5Index *p, /* FTS index to query */ const char *pToken, int nToken, /* Token (or prefix) to query for */ int flags, /* Mask of FTS5INDEX_QUERY_X flags */ @@ -210494,26 +210494,26 @@ static int tdsqlite3Fts5IndexQuery( /* ** The various operations on open token or token prefix iterators opened -** using tdsqlite3Fts5IndexQuery(). +** using sqlite3Fts5IndexQuery(). */ -static int tdsqlite3Fts5IterNext(Fts5IndexIter*); -static int tdsqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch); +static int sqlite3Fts5IterNext(Fts5IndexIter*); +static int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch); /* -** Close an iterator opened by tdsqlite3Fts5IndexQuery(). +** Close an iterator opened by sqlite3Fts5IndexQuery(). */ -static void tdsqlite3Fts5IterClose(Fts5IndexIter*); +static void sqlite3Fts5IterClose(Fts5IndexIter*); /* ** Close the reader blob handle, if it is open. */ -static void tdsqlite3Fts5IndexCloseReader(Fts5Index*); +static void sqlite3Fts5IndexCloseReader(Fts5Index*); /* ** This interface is used by the fts5vocab module. */ -static const char *tdsqlite3Fts5IterTerm(Fts5IndexIter*, int*); -static int tdsqlite3Fts5IterNextScan(Fts5IndexIter*); +static const char *sqlite3Fts5IterTerm(Fts5IndexIter*, int*); +static int sqlite3Fts5IterNextScan(Fts5IndexIter*); /* @@ -210526,7 +210526,7 @@ static int tdsqlite3Fts5IterNextScan(Fts5IndexIter*); ** unique token in the document with an iCol value less than zero. The iPos ** argument is ignored for a delete. */ -static int tdsqlite3Fts5IndexWrite( +static int sqlite3Fts5IndexWrite( Fts5Index *p, /* Index to write to */ int iCol, /* Column token appears in (-ve -> delete) */ int iPos, /* Position of token within column */ @@ -210534,10 +210534,10 @@ static int tdsqlite3Fts5IndexWrite( ); /* -** Indicate that subsequent calls to tdsqlite3Fts5IndexWrite() pertain to +** Indicate that subsequent calls to sqlite3Fts5IndexWrite() pertain to ** document iDocid. */ -static int tdsqlite3Fts5IndexBeginWrite( +static int sqlite3Fts5IndexBeginWrite( Fts5Index *p, /* Index to write to */ int bDelete, /* True if current operation is a delete */ i64 iDocid /* Docid to add or remove data from */ @@ -210547,7 +210547,7 @@ static int tdsqlite3Fts5IndexBeginWrite( ** Flush any data stored in the in-memory hash tables to the database. ** Also close any open blob handles. */ -static int tdsqlite3Fts5IndexSync(Fts5Index *p); +static int sqlite3Fts5IndexSync(Fts5Index *p); /* ** Discard any data stored in the in-memory hash tables. Do not write it @@ -210555,39 +210555,39 @@ static int tdsqlite3Fts5IndexSync(Fts5Index *p); ** table may have changed on disk. So any in-memory caches of %_data ** records must be invalidated. */ -static int tdsqlite3Fts5IndexRollback(Fts5Index *p); +static int sqlite3Fts5IndexRollback(Fts5Index *p); /* ** Get or set the "averages" values. */ -static int tdsqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize); -static int tdsqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int); +static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize); +static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int); /* ** Functions called by the storage module as part of integrity-check. */ -static int tdsqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum); +static int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum); /* ** Called during virtual module initialization to register UDF ** fts5_decode() with SQLite */ -static int tdsqlite3Fts5IndexInit(tdsqlite3*); +static int sqlite3Fts5IndexInit(sqlite3*); -static int tdsqlite3Fts5IndexSetCookie(Fts5Index*, int); +static int sqlite3Fts5IndexSetCookie(Fts5Index*, int); /* ** Return the total number of entries read from the %_data table by ** this connection since it was created. */ -static int tdsqlite3Fts5IndexReads(Fts5Index *p); +static int sqlite3Fts5IndexReads(Fts5Index *p); -static int tdsqlite3Fts5IndexReinit(Fts5Index *p); -static int tdsqlite3Fts5IndexOptimize(Fts5Index *p); -static int tdsqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); -static int tdsqlite3Fts5IndexReset(Fts5Index *p); +static int sqlite3Fts5IndexReinit(Fts5Index *p); +static int sqlite3Fts5IndexOptimize(Fts5Index *p); +static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); +static int sqlite3Fts5IndexReset(Fts5Index *p); -static int tdsqlite3Fts5IndexLoadConfig(Fts5Index *p); +static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); /* ** End of interface to code in fts5_index.c. @@ -210596,13 +210596,13 @@ static int tdsqlite3Fts5IndexLoadConfig(Fts5Index *p); /************************************************************************** ** Interface to code in fts5_varint.c. */ -static int tdsqlite3Fts5GetVarint32(const unsigned char *p, u32 *v); -static int tdsqlite3Fts5GetVarintLen(u32 iVal); -static u8 tdsqlite3Fts5GetVarint(const unsigned char*, u64*); -static int tdsqlite3Fts5PutVarint(unsigned char *p, u64 v); +static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v); +static int sqlite3Fts5GetVarintLen(u32 iVal); +static u8 sqlite3Fts5GetVarint(const unsigned char*, u64*); +static int sqlite3Fts5PutVarint(unsigned char *p, u64 v); -#define fts5GetVarint32(a,b) tdsqlite3Fts5GetVarint32(a,(u32*)&b) -#define fts5GetVarint tdsqlite3Fts5GetVarint +#define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b) +#define fts5GetVarint sqlite3Fts5GetVarint #define fts5FastGetVarint32(a, iOff, nVal) { \ nVal = (a)[iOff++]; \ @@ -210627,12 +210627,12 @@ static int tdsqlite3Fts5PutVarint(unsigned char *p, u64 v); */ typedef struct Fts5Table Fts5Table; struct Fts5Table { - tdsqlite3_vtab base; /* Base class used by SQLite core */ + sqlite3_vtab base; /* Base class used by SQLite core */ Fts5Config *pConfig; /* Virtual table configuration */ Fts5Index *pIndex; /* Full-text index */ }; -static int tdsqlite3Fts5GetTokenizer( +static int sqlite3Fts5GetTokenizer( Fts5Global*, const char **azArg, int nArg, @@ -210641,9 +210641,9 @@ static int tdsqlite3Fts5GetTokenizer( char **pzErr ); -static Fts5Table *tdsqlite3Fts5TableFromCsrid(Fts5Global*, i64); +static Fts5Table *sqlite3Fts5TableFromCsrid(Fts5Global*, i64); -static int tdsqlite3Fts5FlushToDisk(Fts5Table*); +static int sqlite3Fts5FlushToDisk(Fts5Table*); /* ** End of interface to code in fts5.c. @@ -210657,10 +210657,10 @@ typedef struct Fts5Hash Fts5Hash; /* ** Create a hash table, free a hash table. */ -static int tdsqlite3Fts5HashNew(Fts5Config*, Fts5Hash**, int *pnSize); -static void tdsqlite3Fts5HashFree(Fts5Hash*); +static int sqlite3Fts5HashNew(Fts5Config*, Fts5Hash**, int *pnSize); +static void sqlite3Fts5HashFree(Fts5Hash*); -static int tdsqlite3Fts5HashWrite( +static int sqlite3Fts5HashWrite( Fts5Hash*, i64 iRowid, /* Rowid for this entry */ int iCol, /* Column token appears in (-ve -> delete) */ @@ -210672,9 +210672,9 @@ static int tdsqlite3Fts5HashWrite( /* ** Empty (but do not delete) a hash table. */ -static void tdsqlite3Fts5HashClear(Fts5Hash*); +static void sqlite3Fts5HashClear(Fts5Hash*); -static int tdsqlite3Fts5HashQuery( +static int sqlite3Fts5HashQuery( Fts5Hash*, /* Hash table to query */ int nPre, const char *pTerm, int nTerm, /* Query term */ @@ -210682,13 +210682,13 @@ static int tdsqlite3Fts5HashQuery( int *pnDoclist /* OUT: Size of doclist in bytes */ ); -static int tdsqlite3Fts5HashScanInit( +static int sqlite3Fts5HashScanInit( Fts5Hash*, /* Hash table to query */ const char *pTerm, int nTerm /* Query prefix */ ); -static void tdsqlite3Fts5HashScanNext(Fts5Hash*); -static int tdsqlite3Fts5HashScanEof(Fts5Hash*); -static void tdsqlite3Fts5HashScanEntry(Fts5Hash *, +static void sqlite3Fts5HashScanNext(Fts5Hash*); +static int sqlite3Fts5HashScanEof(Fts5Hash*); +static void sqlite3Fts5HashScanEntry(Fts5Hash *, const char **pzTerm, /* OUT: term (nul-terminated) */ const u8 **ppDoclist, /* OUT: pointer to doclist */ int *pnDoclist /* OUT: size of doclist in bytes */ @@ -210710,38 +210710,38 @@ static void tdsqlite3Fts5HashScanEntry(Fts5Hash *, typedef struct Fts5Storage Fts5Storage; -static int tdsqlite3Fts5StorageOpen(Fts5Config*, Fts5Index*, int, Fts5Storage**, char**); -static int tdsqlite3Fts5StorageClose(Fts5Storage *p); -static int tdsqlite3Fts5StorageRename(Fts5Storage*, const char *zName); +static int sqlite3Fts5StorageOpen(Fts5Config*, Fts5Index*, int, Fts5Storage**, char**); +static int sqlite3Fts5StorageClose(Fts5Storage *p); +static int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName); -static int tdsqlite3Fts5DropAll(Fts5Config*); -static int tdsqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); +static int sqlite3Fts5DropAll(Fts5Config*); +static int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **); -static int tdsqlite3Fts5StorageDelete(Fts5Storage *p, i64, tdsqlite3_value**); -static int tdsqlite3Fts5StorageContentInsert(Fts5Storage *p, tdsqlite3_value**, i64*); -static int tdsqlite3Fts5StorageIndexInsert(Fts5Storage *p, tdsqlite3_value**, i64); +static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64, sqlite3_value**); +static int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*); +static int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64); -static int tdsqlite3Fts5StorageIntegrity(Fts5Storage *p); +static int sqlite3Fts5StorageIntegrity(Fts5Storage *p); -static int tdsqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, tdsqlite3_stmt**, char**); -static void tdsqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, tdsqlite3_stmt*); +static int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**); +static void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*); -static int tdsqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol); -static int tdsqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg); -static int tdsqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow); +static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol); +static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnAvg); +static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow); -static int tdsqlite3Fts5StorageSync(Fts5Storage *p); -static int tdsqlite3Fts5StorageRollback(Fts5Storage *p); +static int sqlite3Fts5StorageSync(Fts5Storage *p); +static int sqlite3Fts5StorageRollback(Fts5Storage *p); -static int tdsqlite3Fts5StorageConfigValue( - Fts5Storage *p, const char*, tdsqlite3_value*, int +static int sqlite3Fts5StorageConfigValue( + Fts5Storage *p, const char*, sqlite3_value*, int ); -static int tdsqlite3Fts5StorageDeleteAll(Fts5Storage *p); -static int tdsqlite3Fts5StorageRebuild(Fts5Storage *p); -static int tdsqlite3Fts5StorageOptimize(Fts5Storage *p); -static int tdsqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); -static int tdsqlite3Fts5StorageReset(Fts5Storage *p); +static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p); +static int sqlite3Fts5StorageRebuild(Fts5Storage *p); +static int sqlite3Fts5StorageOptimize(Fts5Storage *p); +static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); +static int sqlite3Fts5StorageReset(Fts5Storage *p); /* ** End of interface to code in fts5_storage.c. @@ -210764,7 +210764,7 @@ struct Fts5Token { }; /* Parse a MATCH expression. */ -static int tdsqlite3Fts5ExprNew( +static int sqlite3Fts5ExprNew( Fts5Config *pConfig, int iCol, /* Column on LHS of MATCH operator */ const char *zExpr, @@ -210773,48 +210773,48 @@ static int tdsqlite3Fts5ExprNew( ); /* -** for(rc = tdsqlite3Fts5ExprFirst(pExpr, pIdx, bDesc); -** rc==SQLITE_OK && 0==tdsqlite3Fts5ExprEof(pExpr); -** rc = tdsqlite3Fts5ExprNext(pExpr) +** for(rc = sqlite3Fts5ExprFirst(pExpr, pIdx, bDesc); +** rc==SQLITE_OK && 0==sqlite3Fts5ExprEof(pExpr); +** rc = sqlite3Fts5ExprNext(pExpr) ** ){ ** // The document with rowid iRowid matches the expression! -** i64 iRowid = tdsqlite3Fts5ExprRowid(pExpr); +** i64 iRowid = sqlite3Fts5ExprRowid(pExpr); ** } */ -static int tdsqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc); -static int tdsqlite3Fts5ExprNext(Fts5Expr*, i64 iMax); -static int tdsqlite3Fts5ExprEof(Fts5Expr*); -static i64 tdsqlite3Fts5ExprRowid(Fts5Expr*); +static int sqlite3Fts5ExprFirst(Fts5Expr*, Fts5Index *pIdx, i64 iMin, int bDesc); +static int sqlite3Fts5ExprNext(Fts5Expr*, i64 iMax); +static int sqlite3Fts5ExprEof(Fts5Expr*); +static i64 sqlite3Fts5ExprRowid(Fts5Expr*); -static void tdsqlite3Fts5ExprFree(Fts5Expr*); -static int tdsqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2); +static void sqlite3Fts5ExprFree(Fts5Expr*); +static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2); /* Called during startup to register a UDF with SQLite */ -static int tdsqlite3Fts5ExprInit(Fts5Global*, tdsqlite3*); +static int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*); -static int tdsqlite3Fts5ExprPhraseCount(Fts5Expr*); -static int tdsqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase); -static int tdsqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **); +static int sqlite3Fts5ExprPhraseCount(Fts5Expr*); +static int sqlite3Fts5ExprPhraseSize(Fts5Expr*, int iPhrase); +static int sqlite3Fts5ExprPoslist(Fts5Expr*, int, const u8 **); typedef struct Fts5PoslistPopulator Fts5PoslistPopulator; -static Fts5PoslistPopulator *tdsqlite3Fts5ExprClearPoslists(Fts5Expr*, int); -static int tdsqlite3Fts5ExprPopulatePoslists( +static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr*, int); +static int sqlite3Fts5ExprPopulatePoslists( Fts5Config*, Fts5Expr*, Fts5PoslistPopulator*, int, const char*, int ); -static void tdsqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64); +static void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64); -static int tdsqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**); +static int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**); -static int tdsqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *); +static int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *); /******************************************* ** The fts5_expr.c API above this point is used by the other hand-written ** C code in this module. The interfaces below this point are called by ** the parser code in fts5parse.y. */ -static void tdsqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...); +static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...); -static Fts5ExprNode *tdsqlite3Fts5ParseNode( +static Fts5ExprNode *sqlite3Fts5ParseNode( Fts5Parse *pParse, int eType, Fts5ExprNode *pLeft, @@ -210822,42 +210822,42 @@ static Fts5ExprNode *tdsqlite3Fts5ParseNode( Fts5ExprNearset *pNear ); -static Fts5ExprNode *tdsqlite3Fts5ParseImplicitAnd( +static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( Fts5Parse *pParse, Fts5ExprNode *pLeft, Fts5ExprNode *pRight ); -static Fts5ExprPhrase *tdsqlite3Fts5ParseTerm( +static Fts5ExprPhrase *sqlite3Fts5ParseTerm( Fts5Parse *pParse, Fts5ExprPhrase *pPhrase, Fts5Token *pToken, int bPrefix ); -static void tdsqlite3Fts5ParseSetCaret(Fts5ExprPhrase*); +static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*); -static Fts5ExprNearset *tdsqlite3Fts5ParseNearset( +static Fts5ExprNearset *sqlite3Fts5ParseNearset( Fts5Parse*, Fts5ExprNearset*, Fts5ExprPhrase* ); -static Fts5Colset *tdsqlite3Fts5ParseColset( +static Fts5Colset *sqlite3Fts5ParseColset( Fts5Parse*, Fts5Colset*, Fts5Token * ); -static void tdsqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*); -static void tdsqlite3Fts5ParseNearsetFree(Fts5ExprNearset*); -static void tdsqlite3Fts5ParseNodeFree(Fts5ExprNode*); +static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*); +static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*); +static void sqlite3Fts5ParseNodeFree(Fts5ExprNode*); -static void tdsqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); -static void tdsqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*); -static Fts5Colset *tdsqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*); -static void tdsqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); -static void tdsqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); +static void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*); +static void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNode*, Fts5Colset*); +static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse*, Fts5Colset*); +static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p); +static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); /* ** End of interface to code in fts5_expr.c. @@ -210869,7 +210869,7 @@ static void tdsqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*); ** Interface to code in fts5_aux.c. */ -static int tdsqlite3Fts5AuxInit(fts5_api*); +static int sqlite3Fts5AuxInit(fts5_api*); /* ** End of interface to code in fts5_aux.c. **************************************************************************/ @@ -210878,7 +210878,7 @@ static int tdsqlite3Fts5AuxInit(fts5_api*); ** Interface to code in fts5_tokenizer.c. */ -static int tdsqlite3Fts5TokenizerInit(fts5_api*); +static int sqlite3Fts5TokenizerInit(fts5_api*); /* ** End of interface to code in fts5_tokenizer.c. **************************************************************************/ @@ -210887,7 +210887,7 @@ static int tdsqlite3Fts5TokenizerInit(fts5_api*); ** Interface to code in fts5_vocab.c. */ -static int tdsqlite3Fts5VocabInit(Fts5Global*, tdsqlite3*); +static int sqlite3Fts5VocabInit(Fts5Global*, sqlite3*); /* ** End of interface to code in fts5_vocab.c. @@ -210897,12 +210897,12 @@ static int tdsqlite3Fts5VocabInit(Fts5Global*, tdsqlite3*); /************************************************************************** ** Interface to automatically generated code in fts5_unicode2.c. */ -static int tdsqlite3Fts5UnicodeIsdiacritic(int c); -static int tdsqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic); +static int sqlite3Fts5UnicodeIsdiacritic(int c); +static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic); -static int tdsqlite3Fts5UnicodeCatParse(const char*, u8*); -static int tdsqlite3Fts5UnicodeCategory(u32 iCode); -static void tdsqlite3Fts5UnicodeAscii(u8*, u8*); +static int sqlite3Fts5UnicodeCatParse(const char*, u8*); +static int sqlite3Fts5UnicodeCategory(u32 iCode); +static void sqlite3Fts5UnicodeAscii(u8*, u8*); /* ** End of interface to code in fts5_unicode2.c. **************************************************************************/ @@ -210968,14 +210968,14 @@ static void tdsqlite3Fts5UnicodeAscii(u8*, u8*); #define fts5yytestcase(X) testcase(X) /* -** Indicate that tdsqlite3ParserFree() will never be called with a null +** Indicate that sqlite3ParserFree() will never be called with a null ** pointer. */ #define fts5YYPARSEFREENOTNULL 1 /* ** Alternative datatype for the argument to the malloc() routine passed -** into tdsqlite3ParserAlloc(). The default is size_t. +** into sqlite3ParserAlloc(). The default is size_t. */ #define fts5YYMALLOCARGTYPE u64 @@ -211002,7 +211002,7 @@ static void tdsqlite3Fts5UnicodeAscii(u8*, u8*); ** fts5YYACTIONTYPE is the data type used for "action codes" - numbers ** that indicate what to do in response to the next ** token. -** tdsqlite3Fts5ParserFTS5TOKENTYPE is the data type used for minor type for terminal +** sqlite3Fts5ParserFTS5TOKENTYPE is the data type used for minor type for terminal ** symbols. Background: A "minor type" is a semantic ** value associated with a terminal or non-terminal ** symbols. For example, for an "ID" terminal symbol, @@ -211013,16 +211013,16 @@ static void tdsqlite3Fts5UnicodeAscii(u8*, u8*); ** symbols. ** fts5YYMINORTYPE is the data type used for all minor types. ** This is typically a union of many types, one of -** which is tdsqlite3Fts5ParserFTS5TOKENTYPE. The entry in the union +** which is sqlite3Fts5ParserFTS5TOKENTYPE. The entry in the union ** for terminal symbols is called "fts5yy0". ** fts5YYSTACKDEPTH is the maximum depth of the parser's stack. If ** zero the stack is dynamically sized using realloc() -** tdsqlite3Fts5ParserARG_SDECL A static variable declaration for the %extra_argument -** tdsqlite3Fts5ParserARG_PDECL A parameter declaration for the %extra_argument -** tdsqlite3Fts5ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter -** tdsqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser -** tdsqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser -** tdsqlite3Fts5ParserCTX_* As tdsqlite3Fts5ParserARG_ except for %extra_context +** sqlite3Fts5ParserARG_SDECL A static variable declaration for the %extra_argument +** sqlite3Fts5ParserARG_PDECL A parameter declaration for the %extra_argument +** sqlite3Fts5ParserARG_PARAM Code to pass %extra_argument as a subroutine parameter +** sqlite3Fts5ParserARG_STORE Code to store %extra_argument into fts5yypParser +** sqlite3Fts5ParserARG_FETCH Code to extract %extra_argument from fts5yypParser +** sqlite3Fts5ParserCTX_* As sqlite3Fts5ParserARG_ except for %extra_context ** fts5YYERRORSYMBOL is the code number of the error symbol. If not ** defined, then do no error processing. ** fts5YYNSTATE the combined number of states. @@ -211044,10 +211044,10 @@ static void tdsqlite3Fts5UnicodeAscii(u8*, u8*); #define fts5YYCODETYPE unsigned char #define fts5YYNOCODE 27 #define fts5YYACTIONTYPE unsigned char -#define tdsqlite3Fts5ParserFTS5TOKENTYPE Fts5Token +#define sqlite3Fts5ParserFTS5TOKENTYPE Fts5Token typedef union { int fts5yyinit; - tdsqlite3Fts5ParserFTS5TOKENTYPE fts5yy0; + sqlite3Fts5ParserFTS5TOKENTYPE fts5yy0; int fts5yy4; Fts5Colset* fts5yy11; Fts5ExprNode* fts5yy24; @@ -211057,16 +211057,16 @@ typedef union { #ifndef fts5YYSTACKDEPTH #define fts5YYSTACKDEPTH 100 #endif -#define tdsqlite3Fts5ParserARG_SDECL Fts5Parse *pParse; -#define tdsqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse -#define tdsqlite3Fts5ParserARG_PARAM ,pParse -#define tdsqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; -#define tdsqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; -#define tdsqlite3Fts5ParserCTX_SDECL -#define tdsqlite3Fts5ParserCTX_PDECL -#define tdsqlite3Fts5ParserCTX_PARAM -#define tdsqlite3Fts5ParserCTX_FETCH -#define tdsqlite3Fts5ParserCTX_STORE +#define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse; +#define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse +#define sqlite3Fts5ParserARG_PARAM ,pParse +#define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; +#define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; +#define sqlite3Fts5ParserCTX_SDECL +#define sqlite3Fts5ParserCTX_PDECL +#define sqlite3Fts5ParserCTX_PARAM +#define sqlite3Fts5ParserCTX_FETCH +#define sqlite3Fts5ParserCTX_STORE #define fts5YYNSTATE 35 #define fts5YYNRULE 28 #define fts5YYNRULE_WITH_ACTION 28 @@ -211252,8 +211252,8 @@ struct fts5yyParser { #ifndef fts5YYNOERRORRECOVERY int fts5yyerrcnt; /* Shifts left before out of the error */ #endif - tdsqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */ - tdsqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */ + sqlite3Fts5ParserARG_SDECL /* A place to hold %extra_argument */ + sqlite3Fts5ParserCTX_SDECL /* A place to hold %extra_context */ #if fts5YYSTACKDEPTH<=0 int fts5yystksz; /* Current side of the stack */ fts5yyStackEntry *fts5yystack; /* The parser's stack */ @@ -211289,7 +211289,7 @@ static char *fts5yyTracePrompt = 0; ** Outputs: ** None. */ -static void tdsqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){ +static void sqlite3Fts5ParserTrace(FILE *TraceFILE, char *zTracePrompt){ fts5yyTraceFILE = TraceFILE; fts5yyTracePrompt = zTracePrompt; if( fts5yyTraceFILE==0 ) fts5yyTracePrompt = 0; @@ -211401,7 +211401,7 @@ static int fts5yyGrowStack(fts5yyParser *p){ #endif /* Datatype of the argument to the memory allocated passed as the -** second argument to tdsqlite3Fts5ParserAlloc() below. This can be changed by +** second argument to sqlite3Fts5ParserAlloc() below. This can be changed by ** putting an appropriate #define in the %include section of the input ** grammar. */ @@ -211411,9 +211411,9 @@ static int fts5yyGrowStack(fts5yyParser *p){ /* Initialize a new parser that has already been allocated. */ -static void tdsqlite3Fts5ParserInit(void *fts5yypRawParser tdsqlite3Fts5ParserCTX_PDECL){ +static void sqlite3Fts5ParserInit(void *fts5yypRawParser sqlite3Fts5ParserCTX_PDECL){ fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yypRawParser; - tdsqlite3Fts5ParserCTX_STORE + sqlite3Fts5ParserCTX_STORE #ifdef fts5YYTRACKMAXSTACKDEPTH fts5yypParser->fts5yyhwm = 0; #endif @@ -211437,7 +211437,7 @@ static void tdsqlite3Fts5ParserInit(void *fts5yypRawParser tdsqlite3Fts5ParserCT #endif } -#ifndef tdsqlite3Fts5Parser_ENGINEALWAYSONSTACK +#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK /* ** This function allocates a new parser. ** The only argument is a pointer to a function which works like @@ -211448,18 +211448,18 @@ static void tdsqlite3Fts5ParserInit(void *fts5yypRawParser tdsqlite3Fts5ParserCT ** ** Outputs: ** A pointer to a parser. This pointer is used in subsequent calls -** to tdsqlite3Fts5Parser and tdsqlite3Fts5ParserFree. +** to sqlite3Fts5Parser and sqlite3Fts5ParserFree. */ -static void *tdsqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE) tdsqlite3Fts5ParserCTX_PDECL){ +static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(fts5YYMALLOCARGTYPE) sqlite3Fts5ParserCTX_PDECL){ fts5yyParser *fts5yypParser; fts5yypParser = (fts5yyParser*)(*mallocProc)( (fts5YYMALLOCARGTYPE)sizeof(fts5yyParser) ); if( fts5yypParser ){ - tdsqlite3Fts5ParserCTX_STORE - tdsqlite3Fts5ParserInit(fts5yypParser tdsqlite3Fts5ParserCTX_PARAM); + sqlite3Fts5ParserCTX_STORE + sqlite3Fts5ParserInit(fts5yypParser sqlite3Fts5ParserCTX_PARAM); } return (void*)fts5yypParser; } -#endif /* tdsqlite3Fts5Parser_ENGINEALWAYSONSTACK */ +#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */ /* The following function deletes the "minor type" or semantic value @@ -211474,8 +211474,8 @@ static void fts5yy_destructor( fts5YYCODETYPE fts5yymajor, /* Type code for object to destroy */ fts5YYMINORTYPE *fts5yypminor /* The object to be destroyed */ ){ - tdsqlite3Fts5ParserARG_FETCH - tdsqlite3Fts5ParserCTX_FETCH + sqlite3Fts5ParserARG_FETCH + sqlite3Fts5ParserCTX_FETCH switch( fts5yymajor ){ /* Here is inserted the actions which take place when a ** terminal or non-terminal is destroyed. This can happen @@ -211497,24 +211497,24 @@ static void fts5yy_destructor( case 18: /* cnearset */ case 19: /* exprlist */ { - tdsqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24)); + sqlite3Fts5ParseNodeFree((fts5yypminor->fts5yy24)); } break; case 20: /* colset */ case 21: /* colsetlist */ { - tdsqlite3_free((fts5yypminor->fts5yy11)); + sqlite3_free((fts5yypminor->fts5yy11)); } break; case 22: /* nearset */ case 23: /* nearphrases */ { - tdsqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46)); + sqlite3Fts5ParseNearsetFree((fts5yypminor->fts5yy46)); } break; case 24: /* phrase */ { - tdsqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53)); + sqlite3Fts5ParsePhraseFree((fts5yypminor->fts5yy53)); } break; /********* End destructor definitions *****************************************/ @@ -211546,7 +211546,7 @@ static void fts5yy_pop_parser_stack(fts5yyParser *pParser){ /* ** Clear all secondary memory allocations from the parser */ -static void tdsqlite3Fts5ParserFinalize(void *p){ +static void sqlite3Fts5ParserFinalize(void *p){ fts5yyParser *pParser = (fts5yyParser*)p; while( pParser->fts5yytos>pParser->fts5yystack ) fts5yy_pop_parser_stack(pParser); #if fts5YYSTACKDEPTH<=0 @@ -211554,7 +211554,7 @@ static void tdsqlite3Fts5ParserFinalize(void *p){ #endif } -#ifndef tdsqlite3Fts5Parser_ENGINEALWAYSONSTACK +#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK /* ** Deallocate and destroy a parser. Destructors are called for ** all stack elements before shutting the parser down. @@ -211563,23 +211563,23 @@ static void tdsqlite3Fts5ParserFinalize(void *p){ ** is defined in a %include section of the input grammar) then it is ** assumed that the input pointer is never NULL. */ -static void tdsqlite3Fts5ParserFree( +static void sqlite3Fts5ParserFree( void *p, /* The parser to be deleted */ void (*freeProc)(void*) /* Function used to reclaim memory */ ){ #ifndef fts5YYPARSEFREENEVERNULL if( p==0 ) return; #endif - tdsqlite3Fts5ParserFinalize(p); + sqlite3Fts5ParserFinalize(p); (*freeProc)(p); } -#endif /* tdsqlite3Fts5Parser_ENGINEALWAYSONSTACK */ +#endif /* sqlite3Fts5Parser_ENGINEALWAYSONSTACK */ /* ** Return the peak depth of the stack for a parser. */ #ifdef fts5YYTRACKMAXSTACKDEPTH -static int tdsqlite3Fts5ParserStackPeak(void *p){ +static int sqlite3Fts5ParserStackPeak(void *p){ fts5yyParser *pParser = (fts5yyParser*)p; return pParser->fts5yyhwm; } @@ -211603,7 +211603,7 @@ static unsigned char fts5yycoverage[fts5YYNSTATE][fts5YYNFTS5TOKEN]; ** Return the number of missed state/lookahead combinations. */ #if defined(fts5YYCOVERAGE) -static int tdsqlite3Fts5ParserCoverage(FILE *out){ +static int sqlite3Fts5ParserCoverage(FILE *out){ int stateno, iLookAhead, i; int nMissed = 0; for(stateno=0; statenofts5yytos++; @@ -211884,14 +211884,14 @@ static fts5YYACTIONTYPE fts5yy_reduce( fts5yyParser *fts5yypParser, /* The parser */ unsigned int fts5yyruleno, /* Number of the rule by which to reduce */ int fts5yyLookahead, /* Lookahead token, or fts5YYNOCODE if none */ - tdsqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken /* Value of the lookahead token */ - tdsqlite3Fts5ParserCTX_PDECL /* %extra_context */ + sqlite3Fts5ParserFTS5TOKENTYPE fts5yyLookaheadToken /* Value of the lookahead token */ + sqlite3Fts5ParserCTX_PDECL /* %extra_context */ ){ int fts5yygoto; /* The next state */ fts5YYACTIONTYPE fts5yyact; /* The next action */ fts5yyStackEntry *fts5yymsp; /* The top of the parser's stack */ int fts5yysize; /* Amount to pop the stack */ - tdsqlite3Fts5ParserARG_FETCH + sqlite3Fts5ParserARG_FETCH (void)fts5yyLookahead; (void)fts5yyLookaheadToken; fts5yymsp = fts5yypParser->fts5yytos; @@ -211956,11 +211956,11 @@ static fts5YYACTIONTYPE fts5yy_reduce( /********** Begin reduce actions **********************************************/ fts5YYMINORTYPE fts5yylhsminor; case 0: /* input ::= expr */ -{ tdsqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); } +{ sqlite3Fts5ParseFinished(pParse, fts5yymsp[0].minor.fts5yy24); } break; case 1: /* colset ::= MINUS LCP colsetlist RCP */ { - fts5yymsp[-3].minor.fts5yy11 = tdsqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); + fts5yymsp[-3].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); } break; case 2: /* colset ::= LCP colsetlist RCP */ @@ -211968,48 +211968,48 @@ static fts5YYACTIONTYPE fts5yy_reduce( break; case 3: /* colset ::= STRING */ { - fts5yylhsminor.fts5yy11 = tdsqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); + fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); } fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11; break; case 4: /* colset ::= MINUS STRING */ { - fts5yymsp[-1].minor.fts5yy11 = tdsqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); - fts5yymsp[-1].minor.fts5yy11 = tdsqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); + fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); + fts5yymsp[-1].minor.fts5yy11 = sqlite3Fts5ParseColsetInvert(pParse, fts5yymsp[-1].minor.fts5yy11); } break; case 5: /* colsetlist ::= colsetlist STRING */ { - fts5yylhsminor.fts5yy11 = tdsqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); } + fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, fts5yymsp[-1].minor.fts5yy11, &fts5yymsp[0].minor.fts5yy0); } fts5yymsp[-1].minor.fts5yy11 = fts5yylhsminor.fts5yy11; break; case 6: /* colsetlist ::= STRING */ { - fts5yylhsminor.fts5yy11 = tdsqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); + fts5yylhsminor.fts5yy11 = sqlite3Fts5ParseColset(pParse, 0, &fts5yymsp[0].minor.fts5yy0); } fts5yymsp[0].minor.fts5yy11 = fts5yylhsminor.fts5yy11; break; case 7: /* expr ::= expr AND expr */ { - fts5yylhsminor.fts5yy24 = tdsqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_AND, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); } fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; break; case 8: /* expr ::= expr OR expr */ { - fts5yylhsminor.fts5yy24 = tdsqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_OR, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); } fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; break; case 9: /* expr ::= expr NOT expr */ { - fts5yylhsminor.fts5yy24 = tdsqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_NOT, fts5yymsp[-2].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24, 0); } fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; break; case 10: /* expr ::= colset COLON LP expr RP */ { - tdsqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11); + sqlite3Fts5ParseSetColset(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[-4].minor.fts5yy11); fts5yylhsminor.fts5yy24 = fts5yymsp[-1].minor.fts5yy24; } fts5yymsp[-4].minor.fts5yy24 = fts5yylhsminor.fts5yy24; @@ -212024,50 +212024,50 @@ static fts5YYACTIONTYPE fts5yy_reduce( break; case 14: /* exprlist ::= exprlist cnearset */ { - fts5yylhsminor.fts5yy24 = tdsqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24); + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseImplicitAnd(pParse, fts5yymsp[-1].minor.fts5yy24, fts5yymsp[0].minor.fts5yy24); } fts5yymsp[-1].minor.fts5yy24 = fts5yylhsminor.fts5yy24; break; case 15: /* cnearset ::= nearset */ { - fts5yylhsminor.fts5yy24 = tdsqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); } fts5yymsp[0].minor.fts5yy24 = fts5yylhsminor.fts5yy24; break; case 16: /* cnearset ::= colset COLON nearset */ { - fts5yylhsminor.fts5yy24 = tdsqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); - tdsqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11); + fts5yylhsminor.fts5yy24 = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, fts5yymsp[0].minor.fts5yy46); + sqlite3Fts5ParseSetColset(pParse, fts5yylhsminor.fts5yy24, fts5yymsp[-2].minor.fts5yy11); } fts5yymsp[-2].minor.fts5yy24 = fts5yylhsminor.fts5yy24; break; case 17: /* nearset ::= phrase */ -{ fts5yylhsminor.fts5yy46 = tdsqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } +{ fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; case 18: /* nearset ::= CARET phrase */ { - tdsqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53); - fts5yymsp[-1].minor.fts5yy46 = tdsqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); + sqlite3Fts5ParseSetCaret(fts5yymsp[0].minor.fts5yy53); + fts5yymsp[-1].minor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } break; case 19: /* nearset ::= STRING LP nearphrases neardist_opt RP */ { - tdsqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0); - tdsqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0); + sqlite3Fts5ParseNear(pParse, &fts5yymsp[-4].minor.fts5yy0); + sqlite3Fts5ParseSetDistance(pParse, fts5yymsp[-2].minor.fts5yy46, &fts5yymsp[-1].minor.fts5yy0); fts5yylhsminor.fts5yy46 = fts5yymsp[-2].minor.fts5yy46; } fts5yymsp[-4].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; case 20: /* nearphrases ::= phrase */ { - fts5yylhsminor.fts5yy46 = tdsqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); + fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, 0, fts5yymsp[0].minor.fts5yy53); } fts5yymsp[0].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; case 21: /* nearphrases ::= nearphrases phrase */ { - fts5yylhsminor.fts5yy46 = tdsqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53); + fts5yylhsminor.fts5yy46 = sqlite3Fts5ParseNearset(pParse, fts5yymsp[-1].minor.fts5yy46, fts5yymsp[0].minor.fts5yy53); } fts5yymsp[-1].minor.fts5yy46 = fts5yylhsminor.fts5yy46; break; @@ -212079,13 +212079,13 @@ static fts5YYACTIONTYPE fts5yy_reduce( break; case 24: /* phrase ::= phrase PLUS STRING star_opt */ { - fts5yylhsminor.fts5yy53 = tdsqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); + fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, fts5yymsp[-3].minor.fts5yy53, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); } fts5yymsp[-3].minor.fts5yy53 = fts5yylhsminor.fts5yy53; break; case 25: /* phrase ::= STRING star_opt */ { - fts5yylhsminor.fts5yy53 = tdsqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); + fts5yylhsminor.fts5yy53 = sqlite3Fts5ParseTerm(pParse, 0, &fts5yymsp[-1].minor.fts5yy0, fts5yymsp[0].minor.fts5yy4); } fts5yymsp[-1].minor.fts5yy53 = fts5yylhsminor.fts5yy53; break; @@ -212126,8 +212126,8 @@ static fts5YYACTIONTYPE fts5yy_reduce( static void fts5yy_parse_failed( fts5yyParser *fts5yypParser /* The parser */ ){ - tdsqlite3Fts5ParserARG_FETCH - tdsqlite3Fts5ParserCTX_FETCH + sqlite3Fts5ParserARG_FETCH + sqlite3Fts5ParserCTX_FETCH #ifndef NDEBUG if( fts5yyTraceFILE ){ fprintf(fts5yyTraceFILE,"%sFail!\n",fts5yyTracePrompt); @@ -212138,8 +212138,8 @@ static void fts5yy_parse_failed( ** parser fails */ /************ Begin %parse_failure code ***************************************/ /************ End %parse_failure code *****************************************/ - tdsqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ - tdsqlite3Fts5ParserCTX_STORE + sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3Fts5ParserCTX_STORE } #endif /* fts5YYNOERRORRECOVERY */ @@ -212149,20 +212149,20 @@ static void fts5yy_parse_failed( static void fts5yy_syntax_error( fts5yyParser *fts5yypParser, /* The parser */ int fts5yymajor, /* The major type of the error token */ - tdsqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The minor type of the error token */ + sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The minor type of the error token */ ){ - tdsqlite3Fts5ParserARG_FETCH - tdsqlite3Fts5ParserCTX_FETCH + sqlite3Fts5ParserARG_FETCH + sqlite3Fts5ParserCTX_FETCH #define FTS5TOKEN fts5yyminor /************ Begin %syntax_error code ****************************************/ UNUSED_PARAM(fts5yymajor); /* Silence a compiler warning */ - tdsqlite3Fts5ParseError( + sqlite3Fts5ParseError( pParse, "fts5: syntax error near \"%.*s\"",FTS5TOKEN.n,FTS5TOKEN.p ); /************ End %syntax_error code ******************************************/ - tdsqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ - tdsqlite3Fts5ParserCTX_STORE + sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3Fts5ParserCTX_STORE } /* @@ -212171,8 +212171,8 @@ static void fts5yy_syntax_error( static void fts5yy_accept( fts5yyParser *fts5yypParser /* The parser */ ){ - tdsqlite3Fts5ParserARG_FETCH - tdsqlite3Fts5ParserCTX_FETCH + sqlite3Fts5ParserARG_FETCH + sqlite3Fts5ParserCTX_FETCH #ifndef NDEBUG if( fts5yyTraceFILE ){ fprintf(fts5yyTraceFILE,"%sAccept!\n",fts5yyTracePrompt); @@ -212186,13 +212186,13 @@ static void fts5yy_accept( ** parser accepts */ /*********** Begin %parse_accept code *****************************************/ /*********** End %parse_accept code *******************************************/ - tdsqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ - tdsqlite3Fts5ParserCTX_STORE + sqlite3Fts5ParserARG_STORE /* Suppress warning about unused %extra_argument variable */ + sqlite3Fts5ParserCTX_STORE } /* The main parser program. ** The first argument is a pointer to a structure obtained from -** "tdsqlite3Fts5ParserAlloc" which describes the current state of the parser. +** "sqlite3Fts5ParserAlloc" which describes the current state of the parser. ** The second argument is the major token number. The third is ** the minor token. The fourth optional argument is whatever the ** user wants (and specified in the grammar) and is available for @@ -212209,11 +212209,11 @@ static void fts5yy_accept( ** Outputs: ** None. */ -static void tdsqlite3Fts5Parser( +static void sqlite3Fts5Parser( void *fts5yyp, /* The parser */ int fts5yymajor, /* The major token code number */ - tdsqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The value for the token */ - tdsqlite3Fts5ParserARG_PDECL /* Optional %extra_argument parameter */ + sqlite3Fts5ParserFTS5TOKENTYPE fts5yyminor /* The value for the token */ + sqlite3Fts5ParserARG_PDECL /* Optional %extra_argument parameter */ ){ fts5YYMINORTYPE fts5yyminorunion; fts5YYACTIONTYPE fts5yyact; /* The parser action. */ @@ -212224,8 +212224,8 @@ static void tdsqlite3Fts5Parser( int fts5yyerrorhit = 0; /* True if fts5yymajor has invoked an error */ #endif fts5yyParser *fts5yypParser = (fts5yyParser*)fts5yyp; /* The parser */ - tdsqlite3Fts5ParserCTX_FETCH - tdsqlite3Fts5ParserARG_STORE + sqlite3Fts5ParserCTX_FETCH + sqlite3Fts5ParserARG_STORE assert( fts5yypParser->fts5yytos!=0 ); #if !defined(fts5YYERRORSYMBOL) && !defined(fts5YYNOERRORRECOVERY) @@ -212250,7 +212250,7 @@ static void tdsqlite3Fts5Parser( fts5yyact = fts5yy_find_shift_action((fts5YYCODETYPE)fts5yymajor,fts5yyact); if( fts5yyact >= fts5YY_MIN_REDUCE ){ fts5yyact = fts5yy_reduce(fts5yypParser,fts5yyact-fts5YY_MIN_REDUCE,fts5yymajor, - fts5yyminor tdsqlite3Fts5ParserCTX_PARAM); + fts5yyminor sqlite3Fts5ParserCTX_PARAM); }else if( fts5yyact <= fts5YY_MAX_SHIFTREDUCE ){ fts5yy_shift(fts5yypParser,fts5yyact,(fts5YYCODETYPE)fts5yymajor,fts5yyminor); #ifndef fts5YYNOERRORRECOVERY @@ -212383,7 +212383,7 @@ static void tdsqlite3Fts5Parser( ** Return the fallback token corresponding to canonical token iToken, or ** 0 if iToken has no fallback. */ -static int tdsqlite3Fts5ParserFallback(int iToken){ +static int sqlite3Fts5ParserFallback(int iToken){ #ifdef fts5YYFALLBACK assert( iToken<(int)(sizeof(fts5yyFallback)/sizeof(fts5yyFallback[0])) ); return fts5yyFallback[iToken]; @@ -212533,7 +212533,7 @@ static void fts5HighlightAppend( ){ if( *pRc==SQLITE_OK && z ){ if( n<0 ) n = (int)strlen(z); - p->zOut = tdsqlite3_mprintf("%z%.*s", p->zOut, n, z); + p->zOut = sqlite3_mprintf("%z%.*s", p->zOut, n, z); if( p->zOut==0 ) *pRc = SQLITE_NOMEM; } } @@ -212598,9 +212598,9 @@ static int fts5HighlightCb( static void fts5HighlightFunction( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ - tdsqlite3_context *pCtx, /* Context for returning result/error */ + sqlite3_context *pCtx, /* Context for returning result/error */ int nVal, /* Number of values in apVal[] array */ - tdsqlite3_value **apVal /* Array of trailing arguments */ + sqlite3_value **apVal /* Array of trailing arguments */ ){ HighlightContext ctx; int rc; @@ -212608,14 +212608,14 @@ static void fts5HighlightFunction( if( nVal!=3 ){ const char *zErr = "wrong number of arguments to function highlight()"; - tdsqlite3_result_error(pCtx, zErr, -1); + sqlite3_result_error(pCtx, zErr, -1); return; } - iCol = tdsqlite3_value_int(apVal[0]); + iCol = sqlite3_value_int(apVal[0]); memset(&ctx, 0, sizeof(HighlightContext)); - ctx.zOpen = (const char*)tdsqlite3_value_text(apVal[1]); - ctx.zClose = (const char*)tdsqlite3_value_text(apVal[2]); + ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]); + ctx.zClose = (const char*)sqlite3_value_text(apVal[2]); rc = pApi->xColumnText(pFts, iCol, &ctx.zIn, &ctx.nIn); if( ctx.zIn ){ @@ -212629,12 +212629,12 @@ static void fts5HighlightFunction( fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); if( rc==SQLITE_OK ){ - tdsqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT); } - tdsqlite3_free(ctx.zOut); + sqlite3_free(ctx.zOut); } if( rc!=SQLITE_OK ){ - tdsqlite3_result_error_code(pCtx, rc); + sqlite3_result_error_code(pCtx, rc); } } /* @@ -212663,7 +212663,7 @@ static int fts5SentenceFinderAdd(Fts5SFinder *p, int iAdd){ int nNew = p->nFirstAlloc ? p->nFirstAlloc*2 : 64; int *aNew; - aNew = (int*)tdsqlite3_realloc64(p->aFirst, nNew*sizeof(int)); + aNew = (int*)sqlite3_realloc64(p->aFirst, nNew*sizeof(int)); if( aNew==0 ) return SQLITE_NOMEM; p->aFirst = aNew; p->nFirstAlloc = nNew; @@ -212730,7 +212730,7 @@ static int fts5SnippetScore( int nInst; int nScore = 0; int iLast = 0; - tdsqlite3_int64 iEnd = (tdsqlite3_int64)iPos + nToken; + sqlite3_int64 iEnd = (sqlite3_int64)iPos + nToken; rc = pApi->xInstCount(pFts, &nInst); for(i=0; inDocsize ) iAdj = nDocsize - nToken; if( iAdj<0 ) iAdj = 0; *piPos = (int)iAdj; @@ -212759,8 +212759,8 @@ static int fts5SnippetScore( ** contains a NULL value, return a pointer to a static string zero ** bytes in length instead of a NULL pointer. */ -static const char *fts5ValueToText(tdsqlite3_value *pVal){ - const char *zRet = (const char*)tdsqlite3_value_text(pVal); +static const char *fts5ValueToText(sqlite3_value *pVal){ + const char *zRet = (const char*)sqlite3_value_text(pVal); return zRet ? zRet : ""; } @@ -212770,9 +212770,9 @@ static const char *fts5ValueToText(tdsqlite3_value *pVal){ static void fts5SnippetFunction( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ - tdsqlite3_context *pCtx, /* Context for returning result/error */ + sqlite3_context *pCtx, /* Context for returning result/error */ int nVal, /* Number of values in apVal[] array */ - tdsqlite3_value **apVal /* Array of trailing arguments */ + sqlite3_value **apVal /* Array of trailing arguments */ ){ HighlightContext ctx; int rc = SQLITE_OK; /* Return code */ @@ -212792,21 +212792,21 @@ static void fts5SnippetFunction( if( nVal!=5 ){ const char *zErr = "wrong number of arguments to function snippet()"; - tdsqlite3_result_error(pCtx, zErr, -1); + sqlite3_result_error(pCtx, zErr, -1); return; } nCol = pApi->xColumnCount(pFts); memset(&ctx, 0, sizeof(HighlightContext)); - iCol = tdsqlite3_value_int(apVal[0]); + iCol = sqlite3_value_int(apVal[0]); ctx.zOpen = fts5ValueToText(apVal[1]); ctx.zClose = fts5ValueToText(apVal[2]); zEllips = fts5ValueToText(apVal[3]); - nToken = tdsqlite3_value_int(apVal[4]); + nToken = sqlite3_value_int(apVal[4]); iBestCol = (iCol>=0 ? iCol : 0); nPhrase = pApi->xPhraseCount(pFts); - aSeen = tdsqlite3_malloc(nPhrase); + aSeen = sqlite3_malloc(nPhrase); if( aSeen==0 ){ rc = SQLITE_NOMEM; } @@ -212910,13 +212910,13 @@ static void fts5SnippetFunction( } } if( rc==SQLITE_OK ){ - tdsqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, (const char*)ctx.zOut, -1, SQLITE_TRANSIENT); }else{ - tdsqlite3_result_error_code(pCtx, rc); + sqlite3_result_error_code(pCtx, rc); } - tdsqlite3_free(ctx.zOut); - tdsqlite3_free(aSeen); - tdsqlite3_free(sFinder.aFirst); + sqlite3_free(ctx.zOut); + sqlite3_free(aSeen); + sqlite3_free(sFinder.aFirst); } /************************************************************************/ @@ -212940,9 +212940,9 @@ struct Fts5Bm25Data { static int fts5CountCb( const Fts5ExtensionApi *pApi, Fts5Context *pFts, - void *pUserData /* Pointer to tdsqlite3_int64 variable */ + void *pUserData /* Pointer to sqlite3_int64 variable */ ){ - tdsqlite3_int64 *pn = (tdsqlite3_int64*)pUserData; + sqlite3_int64 *pn = (sqlite3_int64*)pUserData; UNUSED_PARAM2(pApi, pFts); (*pn)++; return SQLITE_OK; @@ -212964,15 +212964,15 @@ static int fts5Bm25GetData( p = pApi->xGetAuxdata(pFts, 0); if( p==0 ){ int nPhrase; /* Number of phrases in query */ - tdsqlite3_int64 nRow = 0; /* Number of rows in table */ - tdsqlite3_int64 nToken = 0; /* Number of tokens in table */ - tdsqlite3_int64 nByte; /* Bytes of space to allocate */ + sqlite3_int64 nRow = 0; /* Number of rows in table */ + sqlite3_int64 nToken = 0; /* Number of tokens in table */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ int i; /* Allocate the Fts5Bm25Data object */ nPhrase = pApi->xPhraseCount(pFts); nByte = sizeof(Fts5Bm25Data) + nPhrase*2*sizeof(double); - p = (Fts5Bm25Data*)tdsqlite3_malloc64(nByte); + p = (Fts5Bm25Data*)sqlite3_malloc64(nByte); if( p==0 ){ rc = SQLITE_NOMEM; }else{ @@ -212990,7 +212990,7 @@ static int fts5Bm25GetData( /* Calculate an IDF for each phrase in the query */ for(i=0; rc==SQLITE_OK && ixQueryPhrase(pFts, i, (void*)&nHit, fts5CountCb); if( rc==SQLITE_OK ){ /* Calculate the IDF (Inverse Document Frequency) for phrase i. @@ -213013,9 +213013,9 @@ static int fts5Bm25GetData( } if( rc!=SQLITE_OK ){ - tdsqlite3_free(p); + sqlite3_free(p); }else{ - rc = pApi->xSetAuxdata(pFts, p, tdsqlite3_free); + rc = pApi->xSetAuxdata(pFts, p, sqlite3_free); } if( rc!=SQLITE_OK ) p = 0; } @@ -213029,9 +213029,9 @@ static int fts5Bm25GetData( static void fts5Bm25Function( const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ Fts5Context *pFts, /* First arg to pass to pApi functions */ - tdsqlite3_context *pCtx, /* Context for returning result/error */ + sqlite3_context *pCtx, /* Context for returning result/error */ int nVal, /* Number of values in apVal[] array */ - tdsqlite3_value **apVal /* Array of trailing arguments */ + sqlite3_value **apVal /* Array of trailing arguments */ ){ const double k1 = 1.2; /* Constant "k1" from BM25 formula */ const double b = 0.75; /* Constant "b" from BM25 formula */ @@ -213055,7 +213055,7 @@ static void fts5Bm25Function( int ip; int ic; int io; rc = pApi->xInst(pFts, i, &ip, &ic, &io); if( rc==SQLITE_OK ){ - double w = (nVal > ic) ? tdsqlite3_value_double(apVal[ic]) : 1.0; + double w = (nVal > ic) ? sqlite3_value_double(apVal[ic]) : 1.0; aFreq[ip] += w; } } @@ -213078,13 +213078,13 @@ static void fts5Bm25Function( /* If no error has occurred, return the calculated score. Otherwise, ** throw an SQL exception. */ if( rc==SQLITE_OK ){ - tdsqlite3_result_double(pCtx, -1.0 * score); + sqlite3_result_double(pCtx, -1.0 * score); }else{ - tdsqlite3_result_error_code(pCtx, rc); + sqlite3_result_error_code(pCtx, rc); } } -static int tdsqlite3Fts5AuxInit(fts5_api *pApi){ +static int sqlite3Fts5AuxInit(fts5_api *pApi){ struct Builtin { const char *zFunc; /* Function name (nul-terminated) */ void *pUserData; /* User-data pointer */ @@ -213127,14 +213127,14 @@ static int tdsqlite3Fts5AuxInit(fts5_api *pApi){ /* #include "fts5Int.h" */ -static int tdsqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ +static int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ if( (u32)pBuf->nSpacenSpace ? pBuf->nSpace : 64; u8 *pNew; while( nNewp, nNew); + pNew = sqlite3_realloc64(pBuf->p, nNew); if( pNew==0 ){ *pRc = SQLITE_NOMEM; return 1; @@ -213151,19 +213151,19 @@ static int tdsqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ ** Encode value iVal as an SQLite varint and append it to the buffer object ** pBuf. If an OOM error occurs, set the error code in p. */ -static void tdsqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){ +static void sqlite3Fts5BufferAppendVarint(int *pRc, Fts5Buffer *pBuf, i64 iVal){ if( fts5BufferGrow(pRc, pBuf, 9) ) return; - pBuf->n += tdsqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal); + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iVal); } -static void tdsqlite3Fts5Put32(u8 *aBuf, int iVal){ +static void sqlite3Fts5Put32(u8 *aBuf, int iVal){ aBuf[0] = (iVal>>24) & 0x00FF; aBuf[1] = (iVal>>16) & 0x00FF; aBuf[2] = (iVal>> 8) & 0x00FF; aBuf[3] = (iVal>> 0) & 0x00FF; } -static int tdsqlite3Fts5Get32(const u8 *aBuf){ +static int sqlite3Fts5Get32(const u8 *aBuf){ return (int)((((u32)aBuf[0])<<24) + (aBuf[1]<<16) + (aBuf[2]<<8) + aBuf[3]); } @@ -213172,7 +213172,7 @@ static int tdsqlite3Fts5Get32(const u8 *aBuf){ ** the error code in p. If an error has already occurred when this function ** is called, it is a no-op. */ -static void tdsqlite3Fts5BufferAppendBlob( +static void sqlite3Fts5BufferAppendBlob( int *pRc, Fts5Buffer *pBuf, u32 nData, @@ -213191,13 +213191,13 @@ static void tdsqlite3Fts5BufferAppendBlob( ** ensures that the byte following the buffer data is set to 0x00, even ** though this byte is not included in the pBuf->n count. */ -static void tdsqlite3Fts5BufferAppendString( +static void sqlite3Fts5BufferAppendString( int *pRc, Fts5Buffer *pBuf, const char *zStr ){ int nStr = (int)strlen(zStr); - tdsqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr); + sqlite3Fts5BufferAppendBlob(pRc, pBuf, nStr+1, (const u8*)zStr); pBuf->n--; } @@ -213205,11 +213205,11 @@ static void tdsqlite3Fts5BufferAppendString( ** Argument zFmt is a printf() style format string. This function performs ** the printf() style processing, then appends the results to buffer pBuf. ** -** Like tdsqlite3Fts5BufferAppendString(), this function ensures that the byte +** Like sqlite3Fts5BufferAppendString(), this function ensures that the byte ** following the buffer data is set to 0x00, even though this byte is not ** included in the pBuf->n count. */ -static void tdsqlite3Fts5BufferAppendPrintf( +static void sqlite3Fts5BufferAppendPrintf( int *pRc, Fts5Buffer *pBuf, char *zFmt, ... @@ -213218,24 +213218,24 @@ static void tdsqlite3Fts5BufferAppendPrintf( char *zTmp; va_list ap; va_start(ap, zFmt); - zTmp = tdsqlite3_vmprintf(zFmt, ap); + zTmp = sqlite3_vmprintf(zFmt, ap); va_end(ap); if( zTmp==0 ){ *pRc = SQLITE_NOMEM; }else{ - tdsqlite3Fts5BufferAppendString(pRc, pBuf, zTmp); - tdsqlite3_free(zTmp); + sqlite3Fts5BufferAppendString(pRc, pBuf, zTmp); + sqlite3_free(zTmp); } } } -static char *tdsqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...){ +static char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...){ char *zRet = 0; if( *pRc==SQLITE_OK ){ va_list ap; va_start(ap, zFmt); - zRet = tdsqlite3_vmprintf(zFmt, ap); + zRet = sqlite3_vmprintf(zFmt, ap); va_end(ap); if( zRet==0 ){ *pRc = SQLITE_NOMEM; @@ -213248,8 +213248,8 @@ static char *tdsqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...){ /* ** Free any buffer allocated by pBuf. Zero the structure before returning. */ -static void tdsqlite3Fts5BufferFree(Fts5Buffer *pBuf){ - tdsqlite3_free(pBuf->p); +static void sqlite3Fts5BufferFree(Fts5Buffer *pBuf){ + sqlite3_free(pBuf->p); memset(pBuf, 0, sizeof(Fts5Buffer)); } @@ -213257,7 +213257,7 @@ static void tdsqlite3Fts5BufferFree(Fts5Buffer *pBuf){ ** Zero the contents of the buffer object. But do not free the associated ** memory allocation. */ -static void tdsqlite3Fts5BufferZero(Fts5Buffer *pBuf){ +static void sqlite3Fts5BufferZero(Fts5Buffer *pBuf){ pBuf->n = 0; } @@ -213266,17 +213266,17 @@ static void tdsqlite3Fts5BufferZero(Fts5Buffer *pBuf){ ** the error code in p. If an error has already occurred when this function ** is called, it is a no-op. */ -static void tdsqlite3Fts5BufferSet( +static void sqlite3Fts5BufferSet( int *pRc, Fts5Buffer *pBuf, int nData, const u8 *pData ){ pBuf->n = 0; - tdsqlite3Fts5BufferAppendBlob(pRc, pBuf, nData, pData); + sqlite3Fts5BufferAppendBlob(pRc, pBuf, nData, pData); } -static int tdsqlite3Fts5PoslistNext64( +static int sqlite3Fts5PoslistNext64( const u8 *a, int n, /* Buffer containing poslist */ int *pi, /* IN/OUT: Offset within a[] */ i64 *piOff /* IN/OUT: Current offset */ @@ -213315,21 +213315,21 @@ static int tdsqlite3Fts5PoslistNext64( ** Advance the iterator object passed as the only argument. Return true ** if the iterator reaches EOF, or false otherwise. */ -static int tdsqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){ - if( tdsqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){ +static int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){ + if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){ pIter->bEof = 1; } return pIter->bEof; } -static int tdsqlite3Fts5PoslistReaderInit( +static int sqlite3Fts5PoslistReaderInit( const u8 *a, int n, /* Poslist buffer to iterate through */ Fts5PoslistReader *pIter /* Iterator object to initialize */ ){ memset(pIter, 0, sizeof(*pIter)); pIter->a = a; pIter->n = n; - tdsqlite3Fts5PoslistReaderNext(pIter); + sqlite3Fts5PoslistReaderNext(pIter); return pIter->bEof; } @@ -213339,7 +213339,7 @@ static int tdsqlite3Fts5PoslistReaderInit( ** The previous position written to this list is *piPrev. *piPrev is set ** to iPos before returning. */ -static void tdsqlite3Fts5PoslistSafeAppend( +static void sqlite3Fts5PoslistSafeAppend( Fts5Buffer *pBuf, i64 *piPrev, i64 iPos @@ -213347,28 +213347,28 @@ static void tdsqlite3Fts5PoslistSafeAppend( static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32; if( (iPos & colmask) != (*piPrev & colmask) ){ pBuf->p[pBuf->n++] = 1; - pBuf->n += tdsqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32)); + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32)); *piPrev = (iPos & colmask); } - pBuf->n += tdsqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2); + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-*piPrev)+2); *piPrev = iPos; } -static int tdsqlite3Fts5PoslistWriterAppend( +static int sqlite3Fts5PoslistWriterAppend( Fts5Buffer *pBuf, Fts5PoslistWriter *pWriter, i64 iPos ){ int rc = 0; /* Initialized only to suppress erroneous warning from Clang */ if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc; - tdsqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos); + sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos); return SQLITE_OK; } -static void *tdsqlite3Fts5MallocZero(int *pRc, tdsqlite3_int64 nByte){ +static void *sqlite3Fts5MallocZero(int *pRc, sqlite3_int64 nByte){ void *pRet = 0; if( *pRc==SQLITE_OK ){ - pRet = tdsqlite3_malloc64(nByte); + pRet = sqlite3_malloc64(nByte); if( pRet==0 ){ if( nByte>0 ) *pRc = SQLITE_NOMEM; }else{ @@ -213384,15 +213384,15 @@ static void *tdsqlite3Fts5MallocZero(int *pRc, tdsqlite3_int64 nByte){ ** the length of the string is determined using strlen(). ** ** It is the responsibility of the caller to eventually free the returned -** buffer using tdsqlite3_free(). If an OOM error occurs, NULL is returned. +** buffer using sqlite3_free(). If an OOM error occurs, NULL is returned. */ -static char *tdsqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ +static char *sqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ char *zRet = 0; if( *pRc==SQLITE_OK ){ if( nIn<0 ){ nIn = (int)strlen(pIn); } - zRet = (char*)tdsqlite3_malloc(nIn+1); + zRet = (char*)sqlite3_malloc(nIn+1); if( zRet ){ memcpy(zRet, pIn, nIn); zRet[nIn] = '\0'; @@ -213414,7 +213414,7 @@ static char *tdsqlite3Fts5Strndup(int *pRc, const char *pIn, int nIn){ ** * The underscore character "_" (0x5F). ** * The unicode "subsitute" character (0x1A). */ -static int tdsqlite3Fts5IsBareword(char t){ +static int sqlite3Fts5IsBareword(char t){ u8 aBareword[128] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 .. 0x0F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, /* 0x10 .. 0x1F */ @@ -213444,13 +213444,13 @@ struct Fts5Termset { Fts5TermsetEntry *apHash[512]; }; -static int tdsqlite3Fts5TermsetNew(Fts5Termset **pp){ +static int sqlite3Fts5TermsetNew(Fts5Termset **pp){ int rc = SQLITE_OK; - *pp = tdsqlite3Fts5MallocZero(&rc, sizeof(Fts5Termset)); + *pp = sqlite3Fts5MallocZero(&rc, sizeof(Fts5Termset)); return rc; } -static int tdsqlite3Fts5TermsetAdd( +static int sqlite3Fts5TermsetAdd( Fts5Termset *p, int iIdx, const char *pTerm, int nTerm, @@ -213484,7 +213484,7 @@ static int tdsqlite3Fts5TermsetAdd( } if( pEntry==0 ){ - pEntry = tdsqlite3Fts5MallocZero(&rc, sizeof(Fts5TermsetEntry) + nTerm); + pEntry = sqlite3Fts5MallocZero(&rc, sizeof(Fts5TermsetEntry) + nTerm); if( pEntry ){ pEntry->pTerm = (char*)&pEntry[1]; pEntry->nTerm = nTerm; @@ -213499,7 +213499,7 @@ static int tdsqlite3Fts5TermsetAdd( return rc; } -static void tdsqlite3Fts5TermsetFree(Fts5Termset *p){ +static void sqlite3Fts5TermsetFree(Fts5Termset *p){ if( p ){ u32 i; for(i=0; iapHash); i++){ @@ -213507,10 +213507,10 @@ static void tdsqlite3Fts5TermsetFree(Fts5Termset *p){ while( pEntry ){ Fts5TermsetEntry *pDel = pEntry; pEntry = pEntry->pNext; - tdsqlite3_free(pDel); + sqlite3_free(pDel); } } - tdsqlite3_free(p); + sqlite3_free(p); } } @@ -213569,7 +213569,7 @@ static const char *fts5ConfigSkipWhitespace(const char *pIn){ */ static const char *fts5ConfigSkipBareword(const char *pIn){ const char *p = pIn; - while ( tdsqlite3Fts5IsBareword(*p) ) p++; + while ( sqlite3Fts5IsBareword(*p) ) p++; if( p==pIn ) p = 0; return p; } @@ -213584,7 +213584,7 @@ static const char *fts5ConfigSkipLiteral(const char *pIn){ const char *p = pIn; switch( *p ){ case 'n': case 'N': - if( tdsqlite3_strnicmp("null", p, 4)==0 ){ + if( sqlite3_strnicmp("null", p, 4)==0 ){ p = &p[4]; }else{ p = 0; @@ -213701,7 +213701,7 @@ static int fts5Dequote(char *z){ ** [pqr] becomes pqr ** `mno` becomes mno */ -static void tdsqlite3Fts5Dequote(char *z){ +static void sqlite3Fts5Dequote(char *z){ char quote; /* Quote character (if any ) */ assert( 0==fts5_iswhitespace(z[0]) ); @@ -213728,7 +213728,7 @@ static int fts5ConfigSetEnum( int iVal = -1; for(i=0; aEnum[i].zName; i++){ - if( tdsqlite3_strnicmp(aEnum[i].zName, zEnum, nEnum)==0 ){ + if( sqlite3_strnicmp(aEnum[i].zName, zEnum, nEnum)==0 ){ if( iVal>=0 ) return SQLITE_ERROR; iVal = aEnum[i].eVal; } @@ -213745,7 +213745,7 @@ static int fts5ConfigSetEnum( ** If successful, object pConfig is updated and SQLITE_OK returned. If ** an error occurs, an SQLite error code is returned and an error message ** may be left in *pzErr. It is the responsibility of the caller to -** eventually free any such error message using tdsqlite3_free(). +** eventually free any such error message using sqlite3_free(). */ static int fts5ConfigParseSpecial( Fts5Global *pGlobal, @@ -213756,12 +213756,12 @@ static int fts5ConfigParseSpecial( ){ int rc = SQLITE_OK; int nCmd = (int)strlen(zCmd); - if( tdsqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ + if( sqlite3_strnicmp("prefix", zCmd, nCmd)==0 ){ const int nByte = sizeof(int) * FTS5_MAX_PREFIX_INDEXES; const char *p; int bFirst = 1; if( pConfig->aPrefix==0 ){ - pConfig->aPrefix = tdsqlite3Fts5MallocZero(&rc, nByte); + pConfig->aPrefix = sqlite3Fts5MallocZero(&rc, nByte); if( rc ) return rc; } @@ -213777,13 +213777,13 @@ static int fts5ConfigParseSpecial( break; } if( p[0]<'0' || p[0]>'9' ){ - *pzErr = tdsqlite3_mprintf("malformed prefix=... directive"); + *pzErr = sqlite3_mprintf("malformed prefix=... directive"); rc = SQLITE_ERROR; break; } if( pConfig->nPrefix==FTS5_MAX_PREFIX_INDEXES ){ - *pzErr = tdsqlite3_mprintf( + *pzErr = sqlite3_mprintf( "too many prefix indexes (max %d)", FTS5_MAX_PREFIX_INDEXES ); rc = SQLITE_ERROR; @@ -213796,7 +213796,7 @@ static int fts5ConfigParseSpecial( } if( nPre<=0 || nPre>=1000 ){ - *pzErr = tdsqlite3_mprintf("prefix length out of range (max 999)"); + *pzErr = sqlite3_mprintf("prefix length out of range (max 999)"); rc = SQLITE_ERROR; break; } @@ -213809,16 +213809,16 @@ static int fts5ConfigParseSpecial( return rc; } - if( tdsqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ + if( sqlite3_strnicmp("tokenize", zCmd, nCmd)==0 ){ const char *p = (const char*)zArg; - tdsqlite3_int64 nArg = strlen(zArg) + 1; - char **azArg = tdsqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); - char *pDel = tdsqlite3Fts5MallocZero(&rc, nArg * 2); + sqlite3_int64 nArg = strlen(zArg) + 1; + char **azArg = sqlite3Fts5MallocZero(&rc, sizeof(char*) * nArg); + char *pDel = sqlite3Fts5MallocZero(&rc, nArg * 2); char *pSpace = pDel; if( azArg && pSpace ){ if( pConfig->pTok ){ - *pzErr = tdsqlite3_mprintf("multiple tokenize=... directives"); + *pzErr = sqlite3_mprintf("multiple tokenize=... directives"); rc = SQLITE_ERROR; }else{ for(nArg=0; p && *p; nArg++){ @@ -213831,16 +213831,16 @@ static int fts5ConfigParseSpecial( if( p ){ memcpy(pSpace, p2, p-p2); azArg[nArg] = pSpace; - tdsqlite3Fts5Dequote(pSpace); + sqlite3Fts5Dequote(pSpace); pSpace += (p - p2) + 1; p = fts5ConfigSkipWhitespace(p); } } if( p==0 ){ - *pzErr = tdsqlite3_mprintf("parse error in tokenize directive"); + *pzErr = sqlite3_mprintf("parse error in tokenize directive"); rc = SQLITE_ERROR; }else{ - rc = tdsqlite3Fts5GetTokenizer(pGlobal, + rc = sqlite3Fts5GetTokenizer(pGlobal, (const char**)azArg, (int)nArg, &pConfig->pTok, &pConfig->pTokApi, pzErr ); @@ -213848,19 +213848,19 @@ static int fts5ConfigParseSpecial( } } - tdsqlite3_free(azArg); - tdsqlite3_free(pDel); + sqlite3_free(azArg); + sqlite3_free(pDel); return rc; } - if( tdsqlite3_strnicmp("content", zCmd, nCmd)==0 ){ + if( sqlite3_strnicmp("content", zCmd, nCmd)==0 ){ if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){ - *pzErr = tdsqlite3_mprintf("multiple content=... directives"); + *pzErr = sqlite3_mprintf("multiple content=... directives"); rc = SQLITE_ERROR; }else{ if( zArg[0] ){ pConfig->eContent = FTS5_CONTENT_EXTERNAL; - pConfig->zContent = tdsqlite3Fts5Mprintf(&rc, "%Q.%Q", pConfig->zDb,zArg); + pConfig->zContent = sqlite3Fts5Mprintf(&rc, "%Q.%Q", pConfig->zDb,zArg); }else{ pConfig->eContent = FTS5_CONTENT_NONE; } @@ -213868,19 +213868,19 @@ static int fts5ConfigParseSpecial( return rc; } - if( tdsqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ + if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ if( pConfig->zContentRowid ){ - *pzErr = tdsqlite3_mprintf("multiple content_rowid=... directives"); + *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); rc = SQLITE_ERROR; }else{ - pConfig->zContentRowid = tdsqlite3Fts5Strndup(&rc, zArg, -1); + pConfig->zContentRowid = sqlite3Fts5Strndup(&rc, zArg, -1); } return rc; } - if( tdsqlite3_strnicmp("columnsize", zCmd, nCmd)==0 ){ + if( sqlite3_strnicmp("columnsize", zCmd, nCmd)==0 ){ if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ - *pzErr = tdsqlite3_mprintf("malformed columnsize=... directive"); + *pzErr = sqlite3_mprintf("malformed columnsize=... directive"); rc = SQLITE_ERROR; }else{ pConfig->bColumnsize = (zArg[0]=='1'); @@ -213888,7 +213888,7 @@ static int fts5ConfigParseSpecial( return rc; } - if( tdsqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ + if( sqlite3_strnicmp("detail", zCmd, nCmd)==0 ){ const Fts5Enum aDetail[] = { { "none", FTS5_DETAIL_NONE }, { "full", FTS5_DETAIL_FULL }, @@ -213897,12 +213897,12 @@ static int fts5ConfigParseSpecial( }; if( (rc = fts5ConfigSetEnum(aDetail, zArg, &pConfig->eDetail)) ){ - *pzErr = tdsqlite3_mprintf("malformed detail=... directive"); + *pzErr = sqlite3_mprintf("malformed detail=... directive"); } return rc; } - *pzErr = tdsqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); + *pzErr = sqlite3_mprintf("unrecognized option: \"%.*s\"", nCmd, zCmd); return SQLITE_ERROR; } @@ -213913,7 +213913,7 @@ static int fts5ConfigParseSpecial( */ static int fts5ConfigDefaultTokenizer(Fts5Global *pGlobal, Fts5Config *pConfig){ assert( pConfig->pTok==0 && pConfig->pTokApi==0 ); - return tdsqlite3Fts5GetTokenizer( + return sqlite3Fts5GetTokenizer( pGlobal, 0, 0, &pConfig->pTok, &pConfig->pTokApi, 0 ); } @@ -213941,8 +213941,8 @@ static const char *fts5ConfigGobbleWord( ){ const char *zRet = 0; - tdsqlite3_int64 nIn = strlen(zIn); - char *zOut = tdsqlite3_malloc64(nIn+1); + sqlite3_int64 nIn = strlen(zIn); + char *zOut = sqlite3_malloc64(nIn+1); assert( *pRc==SQLITE_OK ); *pbQuoted = 0; @@ -213965,7 +213965,7 @@ static const char *fts5ConfigGobbleWord( } if( zRet==0 ){ - tdsqlite3_free(zOut); + sqlite3_free(zOut); }else{ *pzOut = zOut; } @@ -213980,16 +213980,16 @@ static int fts5ConfigParseColumn( char **pzErr ){ int rc = SQLITE_OK; - if( 0==tdsqlite3_stricmp(zCol, FTS5_RANK_NAME) - || 0==tdsqlite3_stricmp(zCol, FTS5_ROWID_NAME) + if( 0==sqlite3_stricmp(zCol, FTS5_RANK_NAME) + || 0==sqlite3_stricmp(zCol, FTS5_ROWID_NAME) ){ - *pzErr = tdsqlite3_mprintf("reserved fts5 column name: %s", zCol); + *pzErr = sqlite3_mprintf("reserved fts5 column name: %s", zCol); rc = SQLITE_ERROR; }else if( zArg ){ - if( 0==tdsqlite3_stricmp(zArg, "unindexed") ){ + if( 0==sqlite3_stricmp(zArg, "unindexed") ){ p->abUnindexed[p->nCol] = 1; }else{ - *pzErr = tdsqlite3_mprintf("unrecognized column option: %s", zArg); + *pzErr = sqlite3_mprintf("unrecognized column option: %s", zArg); rc = SQLITE_ERROR; } } @@ -214006,13 +214006,13 @@ static int fts5ConfigMakeExprlist(Fts5Config *p){ int rc = SQLITE_OK; Fts5Buffer buf = {0, 0, 0}; - tdsqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid); + sqlite3Fts5BufferAppendPrintf(&rc, &buf, "T.%Q", p->zContentRowid); if( p->eContent!=FTS5_CONTENT_NONE ){ for(i=0; inCol; i++){ if( p->eContent==FTS5_CONTENT_EXTERNAL ){ - tdsqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.%Q", p->azCol[i]); }else{ - tdsqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); + sqlite3Fts5BufferAppendPrintf(&rc, &buf, ", T.c%d", i); } } } @@ -214032,11 +214032,11 @@ static int fts5ConfigMakeExprlist(Fts5Config *p){ ** new Fts5Config object. If an error occurs, an SQLite error code is ** returned, *ppOut is set to NULL and an error message may be left in ** *pzErr. It is the responsibility of the caller to eventually free any -** such error message using tdsqlite3_free(). +** such error message using sqlite3_free(). */ -static int tdsqlite3Fts5ConfigParse( +static int sqlite3Fts5ConfigParse( Fts5Global *pGlobal, - tdsqlite3 *db, + sqlite3 *db, int nArg, /* Number of arguments */ const char **azArg, /* Array of nArg CREATE VIRTUAL TABLE args */ Fts5Config **ppOut, /* OUT: Results of parse */ @@ -214045,26 +214045,26 @@ static int tdsqlite3Fts5ConfigParse( int rc = SQLITE_OK; /* Return code */ Fts5Config *pRet; /* New object to return */ int i; - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; - *ppOut = pRet = (Fts5Config*)tdsqlite3_malloc(sizeof(Fts5Config)); + *ppOut = pRet = (Fts5Config*)sqlite3_malloc(sizeof(Fts5Config)); if( pRet==0 ) return SQLITE_NOMEM; memset(pRet, 0, sizeof(Fts5Config)); pRet->db = db; pRet->iCookie = -1; nByte = nArg * (sizeof(char*) + sizeof(u8)); - pRet->azCol = (char**)tdsqlite3Fts5MallocZero(&rc, nByte); + pRet->azCol = (char**)sqlite3Fts5MallocZero(&rc, nByte); pRet->abUnindexed = (u8*)&pRet->azCol[nArg]; - pRet->zDb = tdsqlite3Fts5Strndup(&rc, azArg[1], -1); - pRet->zName = tdsqlite3Fts5Strndup(&rc, azArg[2], -1); + pRet->zDb = sqlite3Fts5Strndup(&rc, azArg[1], -1); + pRet->zName = sqlite3Fts5Strndup(&rc, azArg[2], -1); pRet->bColumnsize = 1; pRet->eDetail = FTS5_DETAIL_FULL; #ifdef SQLITE_DEBUG pRet->bPrefixIndex = 1; #endif - if( rc==SQLITE_OK && tdsqlite3_stricmp(pRet->zName, FTS5_RANK_NAME)==0 ){ - *pzErr = tdsqlite3_mprintf("reserved fts5 table name: %s", pRet->zName); + if( rc==SQLITE_OK && sqlite3_stricmp(pRet->zName, FTS5_RANK_NAME)==0 ){ + *pzErr = sqlite3_mprintf("reserved fts5 table name: %s", pRet->zName); rc = SQLITE_ERROR; } @@ -214092,7 +214092,7 @@ static int tdsqlite3Fts5ConfigParse( if( rc==SQLITE_OK ){ if( z==0 ){ - *pzErr = tdsqlite3_mprintf("parse error in \"%s\"", zOrig); + *pzErr = sqlite3_mprintf("parse error in \"%s\"", zOrig); rc = SQLITE_ERROR; }else{ if( bOption ){ @@ -214104,8 +214104,8 @@ static int tdsqlite3Fts5ConfigParse( } } - tdsqlite3_free(zOne); - tdsqlite3_free(zTwo); + sqlite3_free(zOne); + sqlite3_free(zTwo); } /* If a tokenizer= option was successfully parsed, the tokenizer has @@ -214128,14 +214128,14 @@ static int tdsqlite3Fts5ConfigParse( } if( zTail ){ - pRet->zContent = tdsqlite3Fts5Mprintf( + pRet->zContent = sqlite3Fts5Mprintf( &rc, "%Q.'%q_%s'", pRet->zDb, pRet->zName, zTail ); } } if( rc==SQLITE_OK && pRet->zContentRowid==0 ){ - pRet->zContentRowid = tdsqlite3Fts5Strndup(&rc, "rowid", -1); + pRet->zContentRowid = sqlite3Fts5Strndup(&rc, "rowid", -1); } /* Formulate the zContentExprlist text */ @@ -214144,7 +214144,7 @@ static int tdsqlite3Fts5ConfigParse( } if( rc!=SQLITE_OK ){ - tdsqlite3Fts5ConfigFree(pRet); + sqlite3Fts5ConfigFree(pRet); *ppOut = 0; } return rc; @@ -214153,51 +214153,51 @@ static int tdsqlite3Fts5ConfigParse( /* ** Free the configuration object passed as the only argument. */ -static void tdsqlite3Fts5ConfigFree(Fts5Config *pConfig){ +static void sqlite3Fts5ConfigFree(Fts5Config *pConfig){ if( pConfig ){ int i; if( pConfig->pTok ){ pConfig->pTokApi->xDelete(pConfig->pTok); } - tdsqlite3_free(pConfig->zDb); - tdsqlite3_free(pConfig->zName); + sqlite3_free(pConfig->zDb); + sqlite3_free(pConfig->zName); for(i=0; inCol; i++){ - tdsqlite3_free(pConfig->azCol[i]); + sqlite3_free(pConfig->azCol[i]); } - tdsqlite3_free(pConfig->azCol); - tdsqlite3_free(pConfig->aPrefix); - tdsqlite3_free(pConfig->zRank); - tdsqlite3_free(pConfig->zRankArgs); - tdsqlite3_free(pConfig->zContent); - tdsqlite3_free(pConfig->zContentRowid); - tdsqlite3_free(pConfig->zContentExprlist); - tdsqlite3_free(pConfig); + sqlite3_free(pConfig->azCol); + sqlite3_free(pConfig->aPrefix); + sqlite3_free(pConfig->zRank); + sqlite3_free(pConfig->zRankArgs); + sqlite3_free(pConfig->zContent); + sqlite3_free(pConfig->zContentRowid); + sqlite3_free(pConfig->zContentExprlist); + sqlite3_free(pConfig); } } /* -** Call tdsqlite3_declare_vtab() based on the contents of the configuration +** Call sqlite3_declare_vtab() based on the contents of the configuration ** object passed as the only argument. Return SQLITE_OK if successful, or ** an SQLite error code if an error occurs. */ -static int tdsqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){ +static int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){ int i; int rc = SQLITE_OK; char *zSql; - zSql = tdsqlite3Fts5Mprintf(&rc, "CREATE TABLE x("); + zSql = sqlite3Fts5Mprintf(&rc, "CREATE TABLE x("); for(i=0; zSql && inCol; i++){ const char *zSep = (i==0?"":", "); - zSql = tdsqlite3Fts5Mprintf(&rc, "%z%s%Q", zSql, zSep, pConfig->azCol[i]); + zSql = sqlite3Fts5Mprintf(&rc, "%z%s%Q", zSql, zSep, pConfig->azCol[i]); } - zSql = tdsqlite3Fts5Mprintf(&rc, "%z, %Q HIDDEN, %s HIDDEN)", + zSql = sqlite3Fts5Mprintf(&rc, "%z, %Q HIDDEN, %s HIDDEN)", zSql, pConfig->zName, FTS5_RANK_NAME ); assert( zSql || rc==SQLITE_NOMEM ); if( zSql ){ - rc = tdsqlite3_declare_vtab(pConfig->db, zSql); - tdsqlite3_free(zSql); + rc = sqlite3_declare_vtab(pConfig->db, zSql); + sqlite3_free(zSql); } return rc; @@ -214209,7 +214209,7 @@ static int tdsqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){ ** The callback is invoked once for each token in the input text. The ** arguments passed to it are, in order: ** -** void *pCtx // Copy of 4th argument to tdsqlite3Fts5Tokenize() +** void *pCtx // Copy of 4th argument to sqlite3Fts5Tokenize() ** const char *pToken // Pointer to buffer containing token ** int nToken // Size of token in bytes ** int iStart // Byte offset of start of token within input text @@ -214226,7 +214226,7 @@ static int tdsqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){ ** because the callback returned another non-zero value, it is assumed ** to be an SQLite error code and returned to the caller. */ -static int tdsqlite3Fts5Tokenize( +static int sqlite3Fts5Tokenize( Fts5Config *pConfig, /* FTS5 Configuration object */ int flags, /* FTS5_TOKENIZE_* flags */ const char *pText, int nText, /* Text to tokenize */ @@ -214272,7 +214272,7 @@ static const char *fts5ConfigSkipArgs(const char *pIn){ ** + Zero or more SQL literals in a comma separated list ** + Close parenthesis - ")" */ -static int tdsqlite3Fts5ConfigParseRank( +static int sqlite3Fts5ConfigParseRank( const char *zIn, /* Input string */ char **pzRank, /* OUT: Rank function name */ char **pzRankArgs /* OUT: Rank function arguments */ @@ -214294,7 +214294,7 @@ static int tdsqlite3Fts5ConfigParseRank( p = fts5ConfigSkipBareword(p); if( p ){ - zRank = tdsqlite3Fts5MallocZero(&rc, 1 + p - pRank); + zRank = sqlite3Fts5MallocZero(&rc, 1 + p - pRank); if( zRank ) memcpy(zRank, pRank, p-pRank); }else{ rc = SQLITE_ERROR; @@ -214314,7 +214314,7 @@ static int tdsqlite3Fts5ConfigParseRank( if( p==0 ){ rc = SQLITE_ERROR; }else{ - zRankArgs = tdsqlite3Fts5MallocZero(&rc, 1 + p - pArgs); + zRankArgs = sqlite3Fts5MallocZero(&rc, 1 + p - pArgs); if( zRankArgs ) memcpy(zRankArgs, pArgs, p-pArgs); } } @@ -214322,7 +214322,7 @@ static int tdsqlite3Fts5ConfigParseRank( } if( rc!=SQLITE_OK ){ - tdsqlite3_free(zRank); + sqlite3_free(zRank); assert( zRankArgs==0 ); }else{ *pzRank = zRank; @@ -214331,18 +214331,18 @@ static int tdsqlite3Fts5ConfigParseRank( return rc; } -static int tdsqlite3Fts5ConfigSetValue( +static int sqlite3Fts5ConfigSetValue( Fts5Config *pConfig, const char *zKey, - tdsqlite3_value *pVal, + sqlite3_value *pVal, int *pbBadkey ){ int rc = SQLITE_OK; - if( 0==tdsqlite3_stricmp(zKey, "pgsz") ){ + if( 0==sqlite3_stricmp(zKey, "pgsz") ){ int pgsz = 0; - if( SQLITE_INTEGER==tdsqlite3_value_numeric_type(pVal) ){ - pgsz = tdsqlite3_value_int(pVal); + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + pgsz = sqlite3_value_int(pVal); } if( pgsz<32 || pgsz>FTS5_MAX_PAGE_SIZE ){ *pbBadkey = 1; @@ -214351,10 +214351,10 @@ static int tdsqlite3Fts5ConfigSetValue( } } - else if( 0==tdsqlite3_stricmp(zKey, "hashsize") ){ + else if( 0==sqlite3_stricmp(zKey, "hashsize") ){ int nHashSize = -1; - if( SQLITE_INTEGER==tdsqlite3_value_numeric_type(pVal) ){ - nHashSize = tdsqlite3_value_int(pVal); + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + nHashSize = sqlite3_value_int(pVal); } if( nHashSize<=0 ){ *pbBadkey = 1; @@ -214363,10 +214363,10 @@ static int tdsqlite3Fts5ConfigSetValue( } } - else if( 0==tdsqlite3_stricmp(zKey, "automerge") ){ + else if( 0==sqlite3_stricmp(zKey, "automerge") ){ int nAutomerge = -1; - if( SQLITE_INTEGER==tdsqlite3_value_numeric_type(pVal) ){ - nAutomerge = tdsqlite3_value_int(pVal); + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + nAutomerge = sqlite3_value_int(pVal); } if( nAutomerge<0 || nAutomerge>64 ){ *pbBadkey = 1; @@ -214376,10 +214376,10 @@ static int tdsqlite3Fts5ConfigSetValue( } } - else if( 0==tdsqlite3_stricmp(zKey, "usermerge") ){ + else if( 0==sqlite3_stricmp(zKey, "usermerge") ){ int nUsermerge = -1; - if( SQLITE_INTEGER==tdsqlite3_value_numeric_type(pVal) ){ - nUsermerge = tdsqlite3_value_int(pVal); + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + nUsermerge = sqlite3_value_int(pVal); } if( nUsermerge<2 || nUsermerge>16 ){ *pbBadkey = 1; @@ -214388,10 +214388,10 @@ static int tdsqlite3Fts5ConfigSetValue( } } - else if( 0==tdsqlite3_stricmp(zKey, "crisismerge") ){ + else if( 0==sqlite3_stricmp(zKey, "crisismerge") ){ int nCrisisMerge = -1; - if( SQLITE_INTEGER==tdsqlite3_value_numeric_type(pVal) ){ - nCrisisMerge = tdsqlite3_value_int(pVal); + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + nCrisisMerge = sqlite3_value_int(pVal); } if( nCrisisMerge<0 ){ *pbBadkey = 1; @@ -214402,14 +214402,14 @@ static int tdsqlite3Fts5ConfigSetValue( } } - else if( 0==tdsqlite3_stricmp(zKey, "rank") ){ - const char *zIn = (const char*)tdsqlite3_value_text(pVal); + else if( 0==sqlite3_stricmp(zKey, "rank") ){ + const char *zIn = (const char*)sqlite3_value_text(pVal); char *zRank; char *zRankArgs; - rc = tdsqlite3Fts5ConfigParseRank(zIn, &zRank, &zRankArgs); + rc = sqlite3Fts5ConfigParseRank(zIn, &zRank, &zRankArgs); if( rc==SQLITE_OK ){ - tdsqlite3_free(pConfig->zRank); - tdsqlite3_free(pConfig->zRankArgs); + sqlite3_free(pConfig->zRank); + sqlite3_free(pConfig->zRankArgs); pConfig->zRank = zRank; pConfig->zRankArgs = zRankArgs; }else if( rc==SQLITE_ERROR ){ @@ -214425,10 +214425,10 @@ static int tdsqlite3Fts5ConfigSetValue( /* ** Load the contents of the %_config table into memory. */ -static int tdsqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ +static int sqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ const char *zSelect = "SELECT k, v FROM %Q.'%q_config'"; char *zSql; - tdsqlite3_stmt *p = 0; + sqlite3_stmt *p = 0; int rc = SQLITE_OK; int iVersion = 0; @@ -214439,32 +214439,32 @@ static int tdsqlite3Fts5ConfigLoad(Fts5Config *pConfig, int iCookie){ pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE; pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE; - zSql = tdsqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName); + zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName); if( zSql ){ - rc = tdsqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0); - tdsqlite3_free(zSql); + rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &p, 0); + sqlite3_free(zSql); } assert( rc==SQLITE_OK || p==0 ); if( rc==SQLITE_OK ){ - while( SQLITE_ROW==tdsqlite3_step(p) ){ - const char *zK = (const char*)tdsqlite3_column_text(p, 0); - tdsqlite3_value *pVal = tdsqlite3_column_value(p, 1); - if( 0==tdsqlite3_stricmp(zK, "version") ){ - iVersion = tdsqlite3_value_int(pVal); + while( SQLITE_ROW==sqlite3_step(p) ){ + const char *zK = (const char*)sqlite3_column_text(p, 0); + sqlite3_value *pVal = sqlite3_column_value(p, 1); + if( 0==sqlite3_stricmp(zK, "version") ){ + iVersion = sqlite3_value_int(pVal); }else{ int bDummy = 0; - tdsqlite3Fts5ConfigSetValue(pConfig, zK, pVal, &bDummy); + sqlite3Fts5ConfigSetValue(pConfig, zK, pVal, &bDummy); } } - rc = tdsqlite3_finalize(p); + rc = sqlite3_finalize(p); } if( rc==SQLITE_OK && iVersion!=FTS5_CURRENT_VERSION ){ rc = SQLITE_ERROR; if( pConfig->pzErrmsg ){ assert( 0==*pConfig->pzErrmsg ); - *pConfig->pzErrmsg = tdsqlite3_mprintf( + *pConfig->pzErrmsg = sqlite3_mprintf( "invalid fts5 file format (found %d, expected %d) - run 'rebuild'", iVersion, FTS5_CURRENT_VERSION ); @@ -214508,14 +214508,14 @@ typedef struct Fts5ExprTerm Fts5ExprTerm; /* ** Functions generated by lemon from fts5parse.y. */ -static void *tdsqlite3Fts5ParserAlloc(void *(*mallocProc)(u64)); -static void tdsqlite3Fts5ParserFree(void*, void (*freeProc)(void*)); -static void tdsqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*); +static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64)); +static void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*)); +static void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*); #ifndef NDEBUG /* #include */ -static void tdsqlite3Fts5ParserTrace(FILE*, char*); +static void sqlite3Fts5ParserTrace(FILE*, char*); #endif -static int tdsqlite3Fts5ParserFallback(int); +static int sqlite3Fts5ParserFallback(int); struct Fts5Expr { @@ -214609,11 +214609,11 @@ struct Fts5Parse { Fts5ExprNode *pExpr; /* Result of a successful parse */ }; -static void tdsqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){ +static void sqlite3Fts5ParseError(Fts5Parse *pParse, const char *zFmt, ...){ va_list ap; va_start(ap, zFmt); if( pParse->rc==SQLITE_OK ){ - pParse->zErr = tdsqlite3_vmprintf(zFmt, ap); + pParse->zErr = sqlite3_vmprintf(zFmt, ap); pParse->rc = SQLITE_ERROR; } va_end(ap); @@ -214662,7 +214662,7 @@ static int fts5ExprGetToken( if( z2[0]!='"' ) break; } if( z2[0]=='\0' ){ - tdsqlite3Fts5ParseError(pParse, "unterminated string"); + sqlite3Fts5ParseError(pParse, "unterminated string"); return FTS5_EOF; } } @@ -214672,12 +214672,12 @@ static int fts5ExprGetToken( default: { const char *z2; - if( tdsqlite3Fts5IsBareword(z[0])==0 ){ - tdsqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z); + if( sqlite3Fts5IsBareword(z[0])==0 ){ + sqlite3Fts5ParseError(pParse, "fts5: syntax error near \"%.1s\"", z); return FTS5_EOF; } tok = FTS5_STRING; - for(z2=&z[1]; tdsqlite3Fts5IsBareword(*z2); z2++); + for(z2=&z[1]; sqlite3Fts5IsBareword(*z2); z2++); pToken->n = (z2 - z); if( pToken->n==2 && memcmp(pToken->p, "OR", 2)==0 ) tok = FTS5_OR; if( pToken->n==3 && memcmp(pToken->p, "NOT", 3)==0 ) tok = FTS5_NOT; @@ -214690,10 +214690,10 @@ static int fts5ExprGetToken( return tok; } -static void *fts5ParseAlloc(u64 t){ return tdsqlite3_malloc64((tdsqlite3_int64)t);} -static void fts5ParseFree(void *p){ tdsqlite3_free(p); } +static void *fts5ParseAlloc(u64 t){ return sqlite3_malloc64((sqlite3_int64)t);} +static void fts5ParseFree(void *p){ sqlite3_free(p); } -static int tdsqlite3Fts5ExprNew( +static int sqlite3Fts5ExprNew( Fts5Config *pConfig, /* FTS5 Configuration */ int iCol, const char *zExpr, /* Expression text */ @@ -214710,38 +214710,38 @@ static int tdsqlite3Fts5ExprNew( *ppNew = 0; *pzErr = 0; memset(&sParse, 0, sizeof(sParse)); - pEngine = tdsqlite3Fts5ParserAlloc(fts5ParseAlloc); + pEngine = sqlite3Fts5ParserAlloc(fts5ParseAlloc); if( pEngine==0 ){ return SQLITE_NOMEM; } sParse.pConfig = pConfig; do { t = fts5ExprGetToken(&sParse, &z, &token); - tdsqlite3Fts5Parser(pEngine, t, token, &sParse); + sqlite3Fts5Parser(pEngine, t, token, &sParse); }while( sParse.rc==SQLITE_OK && t!=FTS5_EOF ); - tdsqlite3Fts5ParserFree(pEngine, fts5ParseFree); + sqlite3Fts5ParserFree(pEngine, fts5ParseFree); /* If the LHS of the MATCH expression was a user column, apply the ** implicit column-filter. */ if( iColnCol && sParse.pExpr && sParse.rc==SQLITE_OK ){ int n = sizeof(Fts5Colset); - Fts5Colset *pColset = (Fts5Colset*)tdsqlite3Fts5MallocZero(&sParse.rc, n); + Fts5Colset *pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&sParse.rc, n); if( pColset ){ pColset->nCol = 1; pColset->aiCol[0] = iCol; - tdsqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset); + sqlite3Fts5ParseSetColset(&sParse, sParse.pExpr, pColset); } } assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 ); if( sParse.rc==SQLITE_OK ){ - *ppNew = pNew = tdsqlite3_malloc(sizeof(Fts5Expr)); + *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr)); if( pNew==0 ){ sParse.rc = SQLITE_NOMEM; - tdsqlite3Fts5ParseNodeFree(sParse.pExpr); + sqlite3Fts5ParseNodeFree(sParse.pExpr); }else{ if( !sParse.pExpr ){ const int nByte = sizeof(Fts5ExprNode); - pNew->pRoot = (Fts5ExprNode*)tdsqlite3Fts5MallocZero(&sParse.rc, nByte); + pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte); if( pNew->pRoot ){ pNew->pRoot->bEof = 1; } @@ -214755,10 +214755,10 @@ static int tdsqlite3Fts5ExprNew( sParse.apPhrase = 0; } }else{ - tdsqlite3Fts5ParseNodeFree(sParse.pExpr); + sqlite3Fts5ParseNodeFree(sParse.pExpr); } - tdsqlite3_free(sParse.apPhrase); + sqlite3_free(sParse.apPhrase); *pzErr = sParse.zErr; return sParse.rc; } @@ -214766,29 +214766,29 @@ static int tdsqlite3Fts5ExprNew( /* ** Free the expression node object passed as the only argument. */ -static void tdsqlite3Fts5ParseNodeFree(Fts5ExprNode *p){ +static void sqlite3Fts5ParseNodeFree(Fts5ExprNode *p){ if( p ){ int i; for(i=0; inChild; i++){ - tdsqlite3Fts5ParseNodeFree(p->apChild[i]); + sqlite3Fts5ParseNodeFree(p->apChild[i]); } - tdsqlite3Fts5ParseNearsetFree(p->pNear); - tdsqlite3_free(p); + sqlite3Fts5ParseNearsetFree(p->pNear); + sqlite3_free(p); } } /* ** Free the expression object passed as the only argument. */ -static void tdsqlite3Fts5ExprFree(Fts5Expr *p){ +static void sqlite3Fts5ExprFree(Fts5Expr *p){ if( p ){ - tdsqlite3Fts5ParseNodeFree(p->pRoot); - tdsqlite3_free(p->apExprPhrase); - tdsqlite3_free(p); + sqlite3Fts5ParseNodeFree(p->pRoot); + sqlite3_free(p->apExprPhrase); + sqlite3_free(p); } } -static int tdsqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ +static int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ Fts5Parse sParse; memset(&sParse, 0, sizeof(sParse)); @@ -214796,11 +214796,11 @@ static int tdsqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ Fts5Expr *p1 = *pp1; int nPhrase = p1->nPhrase + p2->nPhrase; - p1->pRoot = tdsqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0); + p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0); p2->pRoot = 0; if( sParse.rc==SQLITE_OK ){ - Fts5ExprPhrase **ap = (Fts5ExprPhrase**)tdsqlite3_realloc( + Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc( p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*) ); if( ap==0 ){ @@ -214815,8 +214815,8 @@ static int tdsqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ p1->apExprPhrase = ap; } } - tdsqlite3_free(p2->apExprPhrase); - tdsqlite3_free(p2); + sqlite3_free(p2->apExprPhrase); + sqlite3_free(p2); }else{ *pp1 = p2; } @@ -214836,7 +214836,7 @@ static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){ assert( pTerm->pSynonym ); assert( bDesc==0 || bDesc==1 ); for(p=pTerm; p; p=p->pSynonym){ - if( 0==tdsqlite3Fts5IterEof(p->pIter) ){ + if( 0==sqlite3Fts5IterEof(p->pIter) ){ i64 iRowid = p->pIter->iRowid; if( bRetValid==0 || (bDesc!=(iRowidpSynonym ); for(p=pTerm; p; p=p->pSynonym){ Fts5IndexIter *pIter = p->pIter; - if( tdsqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){ + if( sqlite3Fts5IterEof(pIter)==0 && pIter->iRowid==iRowid ){ if( pIter->nData==0 ) continue; if( nIter==nAlloc ){ - tdsqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2; - Fts5PoslistReader *aNew = (Fts5PoslistReader*)tdsqlite3_malloc64(nByte); + sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nAlloc * 2; + Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc64(nByte); if( aNew==0 ){ rc = SQLITE_NOMEM; goto synonym_poslist_out; } memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter); nAlloc = nAlloc*2; - if( aIter!=aStatic ) tdsqlite3_free(aIter); + if( aIter!=aStatic ) sqlite3_free(aIter); aIter = aNew; } - tdsqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]); + sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]); assert( aIter[nIter].bEof==0 ); nIter++; } @@ -214901,7 +214901,7 @@ static int fts5ExprSynonymList( for(i=0; iposlist); /* If the aStatic[] array is not large enough, allocate a large array - ** using tdsqlite3_malloc(). This approach could be improved upon. */ + ** using sqlite3_malloc(). This approach could be improved upon. */ if( pPhrase->nTerm>ArraySize(aStatic) ){ - tdsqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm; - aIter = (Fts5PoslistReader*)tdsqlite3_malloc64(nByte); + sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm; + aIter = (Fts5PoslistReader*)sqlite3_malloc64(nByte); if( !aIter ) return SQLITE_NOMEM; } memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm); @@ -214968,7 +214968,7 @@ static int fts5ExprPhraseIsMatch( Fts5Buffer buf = {0, 0, 0}; rc = fts5ExprSynonymList(pTerm, pNode->iRowid, &buf, &a, &n); if( rc ){ - tdsqlite3_free(a); + sqlite3_free(a); goto ismatch_out; } if( a==buf.p ) bFlag = 1; @@ -214976,7 +214976,7 @@ static int fts5ExprPhraseIsMatch( a = (u8*)pTerm->pIter->pData; n = pTerm->pIter->nData; } - tdsqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); + sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); aIter[i].bFlag = (u8)bFlag; if( aIter[i].bEof ) goto ismatch_out; } @@ -214992,7 +214992,7 @@ static int fts5ExprPhraseIsMatch( if( pPos->iPos!=iAdj ){ bMatch = 0; while( pPos->iPosiPos>iAdj ) iPos = pPos->iPos-i; } @@ -215001,21 +215001,21 @@ static int fts5ExprPhraseIsMatch( /* Append position iPos to the output */ if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){ - rc = tdsqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos); + rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos); if( rc!=SQLITE_OK ) goto ismatch_out; } for(i=0; inTerm; i++){ - if( tdsqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out; + if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out; } } ismatch_out: *pbMatch = (pPhrase->poslist.n>0); for(i=0; inTerm; i++){ - if( aIter[i].bFlag ) tdsqlite3_free((u8*)aIter[i].a); + if( aIter[i].bFlag ) sqlite3_free((u8*)aIter[i].a); } - if( aIter!=aStatic ) tdsqlite3_free(aIter); + if( aIter!=aStatic ) sqlite3_free(aIter); return rc; } @@ -215032,7 +215032,7 @@ struct Fts5LookaheadReader { static int fts5LookaheadReaderNext(Fts5LookaheadReader *p){ p->iPos = p->iLookahead; - if( tdsqlite3Fts5PoslistNext64(p->a, p->n, &p->i, &p->iLookahead) ){ + if( sqlite3Fts5PoslistNext64(p->a, p->n, &p->i, &p->iLookahead) ){ p->iLookahead = FTS5_LOOKAHEAD_EOF; } return (p->iPos==FTS5_LOOKAHEAD_EOF); @@ -215085,10 +215085,10 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ assert( pNear->nPhrase>1 ); /* If the aStatic[] array is not large enough, allocate a large array - ** using tdsqlite3_malloc(). This approach could be improved upon. */ + ** using sqlite3_malloc(). This approach could be improved upon. */ if( pNear->nPhrase>ArraySize(aStatic) ){ - tdsqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase; - a = (Fts5NearTrimmer*)tdsqlite3Fts5MallocZero(&rc, nByte); + sqlite3_int64 nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase; + a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte); }else{ memset(aStatic, 0, sizeof(aStatic)); } @@ -215140,7 +215140,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ i64 iPos = a[i].reader.iPos; Fts5PoslistWriter *pWriter = &a[i].writer; if( a[i].pOut->n==0 || iPos!=pWriter->iPrev ){ - tdsqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos); + sqlite3Fts5PoslistWriterAppend(a[i].pOut, pWriter, iPos); } } @@ -215158,7 +215158,7 @@ static int fts5ExprNearIsMatch(int *pRc, Fts5ExprNearset *pNear){ ismatch_out: { int bRet = a[0].pOut->n>0; *pRc = rc; - if( a!=aStatic ) tdsqlite3_free(a); + if( a!=aStatic ) sqlite3_free(a); return bRet; } } @@ -215184,8 +215184,8 @@ static int fts5ExprAdvanceto( iRowid = pIter->iRowid; if( (bDesc==0 && iLast>iRowid) || (bDesc && iLastpSynonym){ - if( tdsqlite3Fts5IterEof(p->pIter)==0 ){ + if( sqlite3Fts5IterEof(p->pIter)==0 ){ i64 iRowid = p->pIter->iRowid; if( (bDesc==0 && iLast>iRowid) || (bDesc && iLastpIter, iLast); + rc = sqlite3Fts5IterNextFrom(p->pIter, iLast); } } } @@ -215242,7 +215242,7 @@ static int fts5ExprNearTest( pPhrase->poslist.n = 0; for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){ Fts5IndexIter *pIter = pTerm->pIter; - if( tdsqlite3Fts5IterEof(pIter)==0 ){ + if( sqlite3Fts5IterEof(pIter)==0 ){ if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){ pPhrase->poslist.n = 1; } @@ -215310,10 +215310,10 @@ static int fts5ExprNearInitAll( for(p=pTerm; p; p=p->pSynonym){ int rc; if( p->pIter ){ - tdsqlite3Fts5IterClose(p->pIter); + sqlite3Fts5IterClose(p->pIter); p->pIter = 0; } - rc = tdsqlite3Fts5IndexQuery( + rc = sqlite3Fts5IndexQuery( pExpr->pIndex, p->zTerm, (int)strlen(p->zTerm), (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) | (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0), @@ -215322,7 +215322,7 @@ static int fts5ExprNearInitAll( ); assert( (rc==SQLITE_OK)==(p->pIter!=0) ); if( rc!=SQLITE_OK ) return rc; - if( 0==tdsqlite3Fts5IterEof(p->pIter) ){ + if( 0==sqlite3Fts5IterEof(p->pIter) ){ bHit = 1; } } @@ -215514,18 +215514,18 @@ static int fts5ExprNodeNext_STRING( /* Advance each iterator that currently points to iRowid. Or, if iFrom ** is valid - each iterator that points to a rowid before iFrom. */ for(p=pTerm; p; p=p->pSynonym){ - if( tdsqlite3Fts5IterEof(p->pIter)==0 ){ + if( sqlite3Fts5IterEof(p->pIter)==0 ){ i64 ii = p->pIter->iRowid; if( ii==iRowid || (bFromValid && ii!=iFrom && (ii>iFrom)==pExpr->bDesc) ){ if( bFromValid ){ - rc = tdsqlite3Fts5IterNextFrom(p->pIter, iFrom); + rc = sqlite3Fts5IterNextFrom(p->pIter, iFrom); }else{ - rc = tdsqlite3Fts5IterNext(p->pIter); + rc = sqlite3Fts5IterNext(p->pIter); } if( rc!=SQLITE_OK ) break; - if( tdsqlite3Fts5IterEof(p->pIter)==0 ){ + if( sqlite3Fts5IterEof(p->pIter)==0 ){ bEof = 0; } }else{ @@ -215542,12 +215542,12 @@ static int fts5ExprNodeNext_STRING( assert( Fts5NodeIsString(pNode) ); if( bFromValid ){ - rc = tdsqlite3Fts5IterNextFrom(pIter, iFrom); + rc = sqlite3Fts5IterNextFrom(pIter, iFrom); }else{ - rc = tdsqlite3Fts5IterNext(pIter); + rc = sqlite3Fts5IterNext(pIter); } - pNode->bEof = (rc || tdsqlite3Fts5IterEof(pIter)); + pNode->bEof = (rc || sqlite3Fts5IterEof(pIter)); } if( pNode->bEof==0 ){ @@ -215598,11 +215598,11 @@ static int fts5ExprNodeNext_TERM( assert( pNode->bEof==0 ); if( bFromValid ){ - rc = tdsqlite3Fts5IterNextFrom(pIter, iFrom); + rc = sqlite3Fts5IterNextFrom(pIter, iFrom); }else{ - rc = tdsqlite3Fts5IterNext(pIter); + rc = sqlite3Fts5IterNext(pIter); } - if( rc==SQLITE_OK && tdsqlite3Fts5IterEof(pIter)==0 ){ + if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){ rc = fts5ExprNodeTest_TERM(pExpr, pNode); }else{ pNode->bEof = 1; @@ -215882,7 +215882,7 @@ static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){ ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It ** is not considered an error if the query does not match any documents. */ -static int tdsqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ +static int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){ Fts5ExprNode *pRoot = p->pRoot; int rc; /* Return code */ @@ -215913,7 +215913,7 @@ static int tdsqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It ** is not considered an error if the query does not match any documents. */ -static int tdsqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){ +static int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){ int rc; Fts5ExprNode *pRoot = p->pRoot; assert( pRoot->bEof==0 && pRoot->bNomatch==0 ); @@ -215927,17 +215927,17 @@ static int tdsqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){ return rc; } -static int tdsqlite3Fts5ExprEof(Fts5Expr *p){ +static int sqlite3Fts5ExprEof(Fts5Expr *p){ return p->pRoot->bEof; } -static i64 tdsqlite3Fts5ExprRowid(Fts5Expr *p){ +static i64 sqlite3Fts5ExprRowid(Fts5Expr *p){ return p->pRoot->iRowid; } static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){ int rc = SQLITE_OK; - *pz = tdsqlite3Fts5Strndup(&rc, pToken->p, pToken->n); + *pz = sqlite3Fts5Strndup(&rc, pToken->p, pToken->n); return rc; } @@ -215951,17 +215951,17 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){ Fts5ExprTerm *pSyn; Fts5ExprTerm *pNext; Fts5ExprTerm *pTerm = &pPhrase->aTerm[i]; - tdsqlite3_free(pTerm->zTerm); - tdsqlite3Fts5IterClose(pTerm->pIter); + sqlite3_free(pTerm->zTerm); + sqlite3Fts5IterClose(pTerm->pIter); for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){ pNext = pSyn->pSynonym; - tdsqlite3Fts5IterClose(pSyn->pIter); + sqlite3Fts5IterClose(pSyn->pIter); fts5BufferFree((Fts5Buffer*)&pSyn[1]); - tdsqlite3_free(pSyn); + sqlite3_free(pSyn); } } if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist); - tdsqlite3_free(pPhrase); + sqlite3_free(pPhrase); } } @@ -215969,7 +215969,7 @@ static void fts5ExprPhraseFree(Fts5ExprPhrase *pPhrase){ ** Set the "bFirst" flag on the first token of the phrase passed as the ** only argument. */ -static void tdsqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){ +static void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){ if( pPhrase && pPhrase->nTerm ){ pPhrase->aTerm[0].bFirst = 1; } @@ -215983,7 +215983,7 @@ static void tdsqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){ ** If an OOM error occurs, both the pNear and pPhrase objects are freed and ** NULL returned. */ -static Fts5ExprNearset *tdsqlite3Fts5ParseNearset( +static Fts5ExprNearset *sqlite3Fts5ParseNearset( Fts5Parse *pParse, /* Parse context */ Fts5ExprNearset *pNear, /* Existing nearset, or NULL */ Fts5ExprPhrase *pPhrase /* Recently parsed phrase */ @@ -215996,9 +215996,9 @@ static Fts5ExprNearset *tdsqlite3Fts5ParseNearset( return pNear; } if( pNear==0 ){ - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; nByte = sizeof(Fts5ExprNearset) + SZALLOC * sizeof(Fts5ExprPhrase*); - pRet = tdsqlite3_malloc64(nByte); + pRet = sqlite3_malloc64(nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; }else{ @@ -216006,10 +216006,10 @@ static Fts5ExprNearset *tdsqlite3Fts5ParseNearset( } }else if( (pNear->nPhrase % SZALLOC)==0 ){ int nNew = pNear->nPhrase + SZALLOC; - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; nByte = sizeof(Fts5ExprNearset) + nNew * sizeof(Fts5ExprPhrase*); - pRet = (Fts5ExprNearset*)tdsqlite3_realloc64(pNear, nByte); + pRet = (Fts5ExprNearset*)sqlite3_realloc64(pNear, nByte); if( pRet==0 ){ pParse->rc = SQLITE_NOMEM; } @@ -216020,8 +216020,8 @@ static Fts5ExprNearset *tdsqlite3Fts5ParseNearset( if( pRet==0 ){ assert( pParse->rc!=SQLITE_OK ); - tdsqlite3Fts5ParseNearsetFree(pNear); - tdsqlite3Fts5ParsePhraseFree(pPhrase); + sqlite3Fts5ParseNearsetFree(pNear); + sqlite3Fts5ParsePhraseFree(pPhrase); }else{ if( pRet->nPhrase>0 ){ Fts5ExprPhrase *pLast = pRet->apPhrase[pRet->nPhrase-1]; @@ -216073,8 +216073,8 @@ static int fts5ParseTokenize( if( pPhrase && pPhrase->nTerm>0 && (tflags & FTS5_TOKEN_COLOCATED) ){ Fts5ExprTerm *pSyn; - tdsqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1; - pSyn = (Fts5ExprTerm*)tdsqlite3_malloc64(nByte); + sqlite3_int64 nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1; + pSyn = (Fts5ExprTerm*)sqlite3_malloc64(nByte); if( pSyn==0 ){ rc = SQLITE_NOMEM; }else{ @@ -216090,7 +216090,7 @@ static int fts5ParseTokenize( Fts5ExprPhrase *pNew; int nNew = SZALLOC + (pPhrase ? pPhrase->nTerm : 0); - pNew = (Fts5ExprPhrase*)tdsqlite3_realloc64(pPhrase, + pNew = (Fts5ExprPhrase*)sqlite3_realloc64(pPhrase, sizeof(Fts5ExprPhrase) + sizeof(Fts5ExprTerm) * nNew ); if( pNew==0 ){ @@ -216105,7 +216105,7 @@ static int fts5ParseTokenize( if( rc==SQLITE_OK ){ pTerm = &pPhrase->aTerm[pPhrase->nTerm++]; memset(pTerm, 0, sizeof(Fts5ExprTerm)); - pTerm->zTerm = tdsqlite3Fts5Strndup(&rc, pToken, nToken); + pTerm->zTerm = sqlite3Fts5Strndup(&rc, pToken, nToken); } } @@ -216117,25 +216117,25 @@ static int fts5ParseTokenize( /* ** Free the phrase object passed as the only argument. */ -static void tdsqlite3Fts5ParsePhraseFree(Fts5ExprPhrase *pPhrase){ +static void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase *pPhrase){ fts5ExprPhraseFree(pPhrase); } /* ** Free the phrase object passed as the second argument. */ -static void tdsqlite3Fts5ParseNearsetFree(Fts5ExprNearset *pNear){ +static void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset *pNear){ if( pNear ){ int i; for(i=0; inPhrase; i++){ fts5ExprPhraseFree(pNear->apPhrase[i]); } - tdsqlite3_free(pNear->pColset); - tdsqlite3_free(pNear); + sqlite3_free(pNear->pColset); + sqlite3_free(pNear); } } -static void tdsqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){ +static void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){ assert( pParse->pExpr==0 ); pParse->pExpr = p; } @@ -216145,7 +216145,7 @@ static void tdsqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p){ ** string may or may not be quoted. In any case it is tokenized and a ** phrase object consisting of all tokens returned. */ -static Fts5ExprPhrase *tdsqlite3Fts5ParseTerm( +static Fts5ExprPhrase *sqlite3Fts5ParseTerm( Fts5Parse *pParse, /* Parse context */ Fts5ExprPhrase *pAppend, /* Phrase to append to */ Fts5Token *pToken, /* String to tokenize */ @@ -216163,11 +216163,11 @@ static Fts5ExprPhrase *tdsqlite3Fts5ParseTerm( if( rc==SQLITE_OK ){ int flags = FTS5_TOKENIZE_QUERY | (bPrefix ? FTS5_TOKENIZE_PREFIX : 0); int n; - tdsqlite3Fts5Dequote(z); + sqlite3Fts5Dequote(z); n = (int)strlen(z); - rc = tdsqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize); + rc = sqlite3Fts5Tokenize(pConfig, flags, z, n, &sCtx, fts5ParseTokenize); } - tdsqlite3_free(z); + sqlite3_free(z); if( rc || (rc = sCtx.rc) ){ pParse->rc = rc; fts5ExprPhraseFree(sCtx.pPhrase); @@ -216176,9 +216176,9 @@ static Fts5ExprPhrase *tdsqlite3Fts5ParseTerm( if( pAppend==0 ){ if( (pParse->nPhrase % 8)==0 ){ - tdsqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8); + sqlite3_int64 nByte = sizeof(Fts5ExprPhrase*) * (pParse->nPhrase + 8); Fts5ExprPhrase **apNew; - apNew = (Fts5ExprPhrase**)tdsqlite3_realloc64(pParse->apPhrase, nByte); + apNew = (Fts5ExprPhrase**)sqlite3_realloc64(pParse->apPhrase, nByte); if( apNew==0 ){ pParse->rc = SQLITE_NOMEM; fts5ExprPhraseFree(sCtx.pPhrase); @@ -216192,7 +216192,7 @@ static Fts5ExprPhrase *tdsqlite3Fts5ParseTerm( if( sCtx.pPhrase==0 ){ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ - sCtx.pPhrase = tdsqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); + sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase)); }else if( sCtx.pPhrase->nTerm ){ sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix; } @@ -216206,7 +216206,7 @@ static Fts5ExprPhrase *tdsqlite3Fts5ParseTerm( ** Create a new FTS5 expression by cloning phrase iPhrase of the ** expression passed as the second argument. */ -static int tdsqlite3Fts5ExprClonePhrase( +static int sqlite3Fts5ExprClonePhrase( Fts5Expr *pExpr, int iPhrase, Fts5Expr **ppNew @@ -216217,26 +216217,26 @@ static int tdsqlite3Fts5ExprClonePhrase( TokenCtx sCtx = {0,0}; /* Context object for fts5ParseTokenize */ pOrig = pExpr->apExprPhrase[iPhrase]; - pNew = (Fts5Expr*)tdsqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); + pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr)); if( rc==SQLITE_OK ){ - pNew->apExprPhrase = (Fts5ExprPhrase**)tdsqlite3Fts5MallocZero(&rc, + pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase*)); } if( rc==SQLITE_OK ){ - pNew->pRoot = (Fts5ExprNode*)tdsqlite3Fts5MallocZero(&rc, + pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprNode)); } if( rc==SQLITE_OK ){ - pNew->pRoot->pNear = (Fts5ExprNearset*)tdsqlite3Fts5MallocZero(&rc, + pNew->pRoot->pNear = (Fts5ExprNearset*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprNearset) + sizeof(Fts5ExprPhrase*)); } if( rc==SQLITE_OK ){ Fts5Colset *pColsetOrig = pOrig->pNode->pNear->pColset; if( pColsetOrig ){ - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; Fts5Colset *pColset; nByte = sizeof(Fts5Colset) + (pColsetOrig->nCol-1) * sizeof(int); - pColset = (Fts5Colset*)tdsqlite3Fts5MallocZero(&rc, nByte); + pColset = (Fts5Colset*)sqlite3Fts5MallocZero(&rc, nByte); if( pColset ){ memcpy(pColset, pColsetOrig, (size_t)nByte); } @@ -216263,7 +216263,7 @@ static int tdsqlite3Fts5ExprClonePhrase( }else{ /* This happens when parsing a token or quoted phrase that contains ** no token characters at all. (e.g ... MATCH '""'). */ - sCtx.pPhrase = tdsqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); + sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase)); } if( rc==SQLITE_OK ){ @@ -216287,7 +216287,7 @@ static int tdsqlite3Fts5ExprClonePhrase( pNew->pRoot->xNext = fts5ExprNodeNext_STRING; } }else{ - tdsqlite3Fts5ExprFree(pNew); + sqlite3Fts5ExprFree(pNew); fts5ExprPhraseFree(sCtx.pPhrase); pNew = 0; } @@ -216302,15 +216302,15 @@ static int tdsqlite3Fts5ExprClonePhrase( ** is expected. If token pTok does not contain "NEAR", store an error ** in the pParse object. */ -static void tdsqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token *pTok){ +static void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token *pTok){ if( pTok->n!=4 || memcmp("NEAR", pTok->p, 4) ){ - tdsqlite3Fts5ParseError( + sqlite3Fts5ParseError( pParse, "fts5: syntax error near \"%.*s\"", pTok->n, pTok->p ); } } -static void tdsqlite3Fts5ParseSetDistance( +static void sqlite3Fts5ParseSetDistance( Fts5Parse *pParse, Fts5ExprNearset *pNear, Fts5Token *p @@ -216322,7 +216322,7 @@ static void tdsqlite3Fts5ParseSetDistance( for(i=0; in; i++){ char c = (char)p->p[i]; if( c<'0' || c>'9' ){ - tdsqlite3Fts5ParseError( + sqlite3Fts5ParseError( pParse, "expected integer, got \"%.*s\"", p->n, p->p ); return; @@ -216356,7 +216356,7 @@ static Fts5Colset *fts5ParseColset( assert( pParse->rc==SQLITE_OK ); assert( iCol>=0 && iColpConfig->nCol ); - pNew = tdsqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol); + pNew = sqlite3_realloc64(p, sizeof(Fts5Colset) + sizeof(int)*nCol); if( pNew==0 ){ pParse->rc = SQLITE_NOMEM; }else{ @@ -216386,11 +216386,11 @@ static Fts5Colset *fts5ParseColset( ** the colset passed as the second argument. Free the colset passed ** as the second argument before returning. */ -static Fts5Colset *tdsqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){ +static Fts5Colset *sqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset *p){ Fts5Colset *pRet; int nCol = pParse->pConfig->nCol; - pRet = (Fts5Colset*)tdsqlite3Fts5MallocZero(&pParse->rc, + pRet = (Fts5Colset*)sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5Colset) + sizeof(int)*nCol ); if( pRet ){ @@ -216405,11 +216405,11 @@ static Fts5Colset *tdsqlite3Fts5ParseColsetInvert(Fts5Parse *pParse, Fts5Colset } } - tdsqlite3_free(p); + sqlite3_free(p); return pRet; } -static Fts5Colset *tdsqlite3Fts5ParseColset( +static Fts5Colset *sqlite3Fts5ParseColset( Fts5Parse *pParse, /* Store SQLITE_NOMEM here if required */ Fts5Colset *pColset, /* Existing colset object */ Fts5Token *p @@ -216418,24 +216418,24 @@ static Fts5Colset *tdsqlite3Fts5ParseColset( int iCol; char *z; /* Dequoted copy of token p */ - z = tdsqlite3Fts5Strndup(&pParse->rc, p->p, p->n); + z = sqlite3Fts5Strndup(&pParse->rc, p->p, p->n); if( pParse->rc==SQLITE_OK ){ Fts5Config *pConfig = pParse->pConfig; - tdsqlite3Fts5Dequote(z); + sqlite3Fts5Dequote(z); for(iCol=0; iColnCol; iCol++){ - if( 0==tdsqlite3_stricmp(pConfig->azCol[iCol], z) ) break; + if( 0==sqlite3_stricmp(pConfig->azCol[iCol], z) ) break; } if( iCol==pConfig->nCol ){ - tdsqlite3Fts5ParseError(pParse, "no such column: %s", z); + sqlite3Fts5ParseError(pParse, "no such column: %s", z); }else{ pRet = fts5ParseColset(pParse, pColset, iCol); } - tdsqlite3_free(z); + sqlite3_free(z); } if( pRet==0 ){ assert( pParse->rc!=SQLITE_OK ); - tdsqlite3_free(pColset); + sqlite3_free(pColset); } return pRet; @@ -216446,14 +216446,14 @@ static Fts5Colset *tdsqlite3Fts5ParseColset( ** SQLITE_OK when this function is called, NULL is returned. ** ** Otherwise, a copy of (*pOrig) is made into memory obtained from -** tdsqlite3Fts5MallocZero() and a pointer to it returned. If the allocation +** sqlite3Fts5MallocZero() and a pointer to it returned. If the allocation ** fails, (*pRc) is set to SQLITE_NOMEM and NULL is returned. */ static Fts5Colset *fts5CloneColset(int *pRc, Fts5Colset *pOrig){ Fts5Colset *pRet; if( pOrig ){ - tdsqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); - pRet = (Fts5Colset*)tdsqlite3Fts5MallocZero(pRc, nByte); + sqlite3_int64 nByte = sizeof(Fts5Colset) + (pOrig->nCol-1) * sizeof(int); + pRet = (Fts5Colset*)sqlite3Fts5MallocZero(pRc, nByte); if( pRet ){ memcpy(pRet, pOrig, (size_t)nByte); } @@ -216530,7 +216530,7 @@ static void fts5ParseSetColset( /* ** Apply colset pColset to expression node pExpr and all of its descendents. */ -static void tdsqlite3Fts5ParseSetColset( +static void sqlite3Fts5ParseSetColset( Fts5Parse *pParse, Fts5ExprNode *pExpr, Fts5Colset *pColset @@ -216538,13 +216538,13 @@ static void tdsqlite3Fts5ParseSetColset( Fts5Colset *pFree = pColset; if( pParse->pConfig->eDetail==FTS5_DETAIL_NONE ){ pParse->rc = SQLITE_ERROR; - pParse->zErr = tdsqlite3_mprintf( + pParse->zErr = sqlite3_mprintf( "fts5: column queries are not supported (detail=none)" ); }else{ fts5ParseSetColset(pParse, pExpr, pColset, &pFree); } - tdsqlite3_free(pFree); + sqlite3_free(pFree); } static void fts5ExprAssignXNext(Fts5ExprNode *pNode){ @@ -216585,7 +216585,7 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ int nByte = sizeof(Fts5ExprNode*) * pSub->nChild; memcpy(&p->apChild[p->nChild], pSub->apChild, nByte); p->nChild += pSub->nChild; - tdsqlite3_free(pSub); + sqlite3_free(pSub); }else{ p->apChild[p->nChild++] = pSub; } @@ -216595,7 +216595,7 @@ static void fts5ExprAddChildren(Fts5ExprNode *p, Fts5ExprNode *pSub){ ** Allocate and return a new expression object. If anything goes wrong (i.e. ** OOM error), leave an error code in pParse and return NULL. */ -static Fts5ExprNode *tdsqlite3Fts5ParseNode( +static Fts5ExprNode *sqlite3Fts5ParseNode( Fts5Parse *pParse, /* Parse context */ int eType, /* FTS5_STRING, AND, OR or NOT */ Fts5ExprNode *pLeft, /* Left hand child expression */ @@ -216606,7 +216606,7 @@ static Fts5ExprNode *tdsqlite3Fts5ParseNode( if( pParse->rc==SQLITE_OK ){ int nChild = 0; /* Number of children of returned node */ - tdsqlite3_int64 nByte; /* Bytes of space to allocate for this node */ + sqlite3_int64 nByte; /* Bytes of space to allocate for this node */ assert( (eType!=FTS5_STRING && !pNear) || (eType==FTS5_STRING && !pLeft && !pRight) @@ -216624,7 +216624,7 @@ static Fts5ExprNode *tdsqlite3Fts5ParseNode( } nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1); - pRet = (Fts5ExprNode*)tdsqlite3Fts5MallocZero(&pParse->rc, nByte); + pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte); if( pRet ){ pRet->eType = eType; @@ -216649,11 +216649,11 @@ static Fts5ExprNode *tdsqlite3Fts5ParseNode( assert( pParse->rc==SQLITE_OK ); pParse->rc = SQLITE_ERROR; assert( pParse->zErr==0 ); - pParse->zErr = tdsqlite3_mprintf( + pParse->zErr = sqlite3_mprintf( "fts5: %s queries are not supported (detail!=full)", pNear->nPhrase==1 ? "phrase": "NEAR" ); - tdsqlite3_free(pRet); + sqlite3_free(pRet); pRet = 0; } } @@ -216666,14 +216666,14 @@ static Fts5ExprNode *tdsqlite3Fts5ParseNode( if( pRet==0 ){ assert( pParse->rc!=SQLITE_OK ); - tdsqlite3Fts5ParseNodeFree(pLeft); - tdsqlite3Fts5ParseNodeFree(pRight); - tdsqlite3Fts5ParseNearsetFree(pNear); + sqlite3Fts5ParseNodeFree(pLeft); + sqlite3Fts5ParseNodeFree(pRight); + sqlite3Fts5ParseNearsetFree(pNear); } return pRet; } -static Fts5ExprNode *tdsqlite3Fts5ParseImplicitAnd( +static Fts5ExprNode *sqlite3Fts5ParseImplicitAnd( Fts5Parse *pParse, /* Parse context */ Fts5ExprNode *pLeft, /* Left hand child expression */ Fts5ExprNode *pRight /* Right hand child expression */ @@ -216682,8 +216682,8 @@ static Fts5ExprNode *tdsqlite3Fts5ParseImplicitAnd( Fts5ExprNode *pPrev; if( pParse->rc ){ - tdsqlite3Fts5ParseNodeFree(pLeft); - tdsqlite3Fts5ParseNodeFree(pRight); + sqlite3Fts5ParseNodeFree(pLeft); + sqlite3Fts5ParseNodeFree(pRight); }else{ assert( pLeft->eType==FTS5_STRING @@ -216708,7 +216708,7 @@ static Fts5ExprNode *tdsqlite3Fts5ParseImplicitAnd( if( pRight->eType==FTS5_EOF ){ assert( pParse->apPhrase[pParse->nPhrase-1]==pRight->pNear->apPhrase[0] ); - tdsqlite3Fts5ParseNodeFree(pRight); + sqlite3Fts5ParseNodeFree(pRight); pRet = pLeft; pParse->nPhrase--; } @@ -216727,10 +216727,10 @@ static Fts5ExprNode *tdsqlite3Fts5ParseImplicitAnd( memmove(ap, &ap[1], sizeof(Fts5ExprPhrase*)*pRight->pNear->nPhrase); pParse->nPhrase--; - tdsqlite3Fts5ParseNodeFree(pPrev); + sqlite3Fts5ParseNodeFree(pPrev); } else{ - pRet = tdsqlite3Fts5ParseNode(pParse, FTS5_AND, pLeft, pRight, 0); + pRet = sqlite3Fts5ParseNode(pParse, FTS5_AND, pLeft, pRight, 0); } } @@ -216738,7 +216738,7 @@ static Fts5ExprNode *tdsqlite3Fts5ParseImplicitAnd( } static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ - tdsqlite3_int64 nByte = 0; + sqlite3_int64 nByte = 0; Fts5ExprTerm *p; char *zQuoted; @@ -216746,7 +216746,7 @@ static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ for(p=pTerm; p; p=p->pSynonym){ nByte += (int)strlen(pTerm->zTerm) * 2 + 3 + 2; } - zQuoted = tdsqlite3_malloc64(nByte); + zQuoted = sqlite3_malloc64(nByte); if( zQuoted ){ int i = 0; @@ -216773,14 +216773,14 @@ static char *fts5PrintfAppend(char *zApp, const char *zFmt, ...){ char *zNew; va_list ap; va_start(ap, zFmt); - zNew = tdsqlite3_vmprintf(zFmt, ap); + zNew = sqlite3_vmprintf(zFmt, ap); va_end(ap); if( zApp && zNew ){ - char *zNew2 = tdsqlite3_mprintf("%s%s", zApp, zNew); - tdsqlite3_free(zNew); + char *zNew2 = sqlite3_mprintf("%s%s", zApp, zNew); + sqlite3_free(zNew); zNew = zNew2; } - tdsqlite3_free(zApp); + sqlite3_free(zApp); return zNew; } @@ -216788,7 +216788,7 @@ static char *fts5PrintfAppend(char *zApp, const char *zFmt, ...){ ** Compose a tcl-readable representation of expression pExpr. Return a ** pointer to a buffer containing that representation. It is the ** responsibility of the caller to at some point free the buffer using -** tdsqlite3_free(). +** sqlite3_free(). */ static char *fts5ExprPrintTcl( Fts5Config *pConfig, @@ -216854,11 +216854,11 @@ static char *fts5ExprPrintTcl( break; } - zRet = tdsqlite3_mprintf("%s", zOp); + zRet = sqlite3_mprintf("%s", zOp); for(i=0; zRet && inChild; i++){ char *z = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->apChild[i]); if( !z ){ - tdsqlite3_free(zRet); + sqlite3_free(zRet); zRet = 0; }else{ zRet = fts5PrintfAppend(zRet, " [%z]", z); @@ -216872,7 +216872,7 @@ static char *fts5ExprPrintTcl( static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){ char *zRet = 0; if( pExpr->eType==0 ){ - return tdsqlite3_mprintf("\"\""); + return sqlite3_mprintf("\"\""); }else if( pExpr->eType==FTS5_STRING || pExpr->eType==FTS5_TERM ){ Fts5ExprNearset *pNear = pExpr->pNear; @@ -216900,10 +216900,10 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){ char *zTerm = fts5ExprTermPrint(&pPhrase->aTerm[iTerm]); if( zTerm ){ zRet = fts5PrintfAppend(zRet, "%s%s", iTerm==0?"":" + ", zTerm); - tdsqlite3_free(zTerm); + sqlite3_free(zTerm); } if( zTerm==0 || zRet==0 ){ - tdsqlite3_free(zRet); + sqlite3_free(zRet); return 0; } } @@ -216930,7 +216930,7 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){ for(i=0; inChild; i++){ char *z = fts5ExprPrint(pConfig, pExpr->apChild[i]); if( z==0 ){ - tdsqlite3_free(zRet); + sqlite3_free(zRet); zRet = 0; }else{ int e = pExpr->apChild[i]->eType; @@ -216952,13 +216952,13 @@ static char *fts5ExprPrint(Fts5Config *pConfig, Fts5ExprNode *pExpr){ ** and fts5_expr_tcl() (bTcl!=0). */ static void fts5ExprFunction( - tdsqlite3_context *pCtx, /* Function call context */ + sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ - tdsqlite3_value **apVal, /* Function arguments */ + sqlite3_value **apVal, /* Function arguments */ int bTcl ){ - Fts5Global *pGlobal = (Fts5Global*)tdsqlite3_user_data(pCtx); - tdsqlite3 *db = tdsqlite3_context_db_handle(pCtx); + Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx); + sqlite3 *db = sqlite3_context_db_handle(pCtx); const char *zExpr = 0; char *zErr = 0; Fts5Expr *pExpr = 0; @@ -216972,44 +216972,44 @@ static void fts5ExprFunction( int iArg = 1; if( nArg<1 ){ - zErr = tdsqlite3_mprintf("wrong number of arguments to function %s", + zErr = sqlite3_mprintf("wrong number of arguments to function %s", bTcl ? "fts5_expr_tcl" : "fts5_expr" ); - tdsqlite3_result_error(pCtx, zErr, -1); - tdsqlite3_free(zErr); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); return; } if( bTcl && nArg>1 ){ - zNearsetCmd = (const char*)tdsqlite3_value_text(apVal[1]); + zNearsetCmd = (const char*)sqlite3_value_text(apVal[1]); iArg = 2; } nConfig = 3 + (nArg-iArg); - azConfig = (const char**)tdsqlite3_malloc64(sizeof(char*) * nConfig); + azConfig = (const char**)sqlite3_malloc64(sizeof(char*) * nConfig); if( azConfig==0 ){ - tdsqlite3_result_error_nomem(pCtx); + sqlite3_result_error_nomem(pCtx); return; } azConfig[0] = 0; azConfig[1] = "main"; azConfig[2] = "tbl"; for(i=3; iArgnCol, zExpr, &pExpr, &zErr); + rc = sqlite3Fts5ExprNew(pConfig, pConfig->nCol, zExpr, &pExpr, &zErr); } if( rc==SQLITE_OK ){ char *zText; if( pExpr->pRoot->xNext==0 ){ - zText = tdsqlite3_mprintf(""); + zText = sqlite3_mprintf(""); }else if( bTcl ){ zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot); }else{ @@ -217018,35 +217018,35 @@ static void fts5ExprFunction( if( zText==0 ){ rc = SQLITE_NOMEM; }else{ - tdsqlite3_result_text(pCtx, zText, -1, SQLITE_TRANSIENT); - tdsqlite3_free(zText); + sqlite3_result_text(pCtx, zText, -1, SQLITE_TRANSIENT); + sqlite3_free(zText); } } if( rc!=SQLITE_OK ){ if( zErr ){ - tdsqlite3_result_error(pCtx, zErr, -1); - tdsqlite3_free(zErr); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); }else{ - tdsqlite3_result_error_code(pCtx, rc); + sqlite3_result_error_code(pCtx, rc); } } - tdsqlite3_free((void *)azConfig); - tdsqlite3Fts5ConfigFree(pConfig); - tdsqlite3Fts5ExprFree(pExpr); + sqlite3_free((void *)azConfig); + sqlite3Fts5ConfigFree(pConfig); + sqlite3Fts5ExprFree(pExpr); } static void fts5ExprFunctionHr( - tdsqlite3_context *pCtx, /* Function call context */ + sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ - tdsqlite3_value **apVal /* Function arguments */ + sqlite3_value **apVal /* Function arguments */ ){ fts5ExprFunction(pCtx, nArg, apVal, 0); } static void fts5ExprFunctionTcl( - tdsqlite3_context *pCtx, /* Function call context */ + sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ - tdsqlite3_value **apVal /* Function arguments */ + sqlite3_value **apVal /* Function arguments */ ){ fts5ExprFunction(pCtx, nArg, apVal, 1); } @@ -217057,41 +217057,41 @@ static void fts5ExprFunctionTcl( ** unicode code point, 1 is returned. Otherwise 0. */ static void fts5ExprIsAlnum( - tdsqlite3_context *pCtx, /* Function call context */ + sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ - tdsqlite3_value **apVal /* Function arguments */ + sqlite3_value **apVal /* Function arguments */ ){ int iCode; u8 aArr[32]; if( nArg!=1 ){ - tdsqlite3_result_error(pCtx, + sqlite3_result_error(pCtx, "wrong number of arguments to function fts5_isalnum", -1 ); return; } memset(aArr, 0, sizeof(aArr)); - tdsqlite3Fts5UnicodeCatParse("L*", aArr); - tdsqlite3Fts5UnicodeCatParse("N*", aArr); - tdsqlite3Fts5UnicodeCatParse("Co", aArr); - iCode = tdsqlite3_value_int(apVal[0]); - tdsqlite3_result_int(pCtx, aArr[tdsqlite3Fts5UnicodeCategory((u32)iCode)]); + sqlite3Fts5UnicodeCatParse("L*", aArr); + sqlite3Fts5UnicodeCatParse("N*", aArr); + sqlite3Fts5UnicodeCatParse("Co", aArr); + iCode = sqlite3_value_int(apVal[0]); + sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]); } static void fts5ExprFold( - tdsqlite3_context *pCtx, /* Function call context */ + sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ - tdsqlite3_value **apVal /* Function arguments */ + sqlite3_value **apVal /* Function arguments */ ){ if( nArg!=1 && nArg!=2 ){ - tdsqlite3_result_error(pCtx, + sqlite3_result_error(pCtx, "wrong number of arguments to function fts5_fold", -1 ); }else{ int iCode; int bRemoveDiacritics = 0; - iCode = tdsqlite3_value_int(apVal[0]); - if( nArg==2 ) bRemoveDiacritics = tdsqlite3_value_int(apVal[1]); - tdsqlite3_result_int(pCtx, tdsqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics)); + iCode = sqlite3_value_int(apVal[0]); + if( nArg==2 ) bRemoveDiacritics = sqlite3_value_int(apVal[1]); + sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics)); } } @@ -217099,10 +217099,10 @@ static void fts5ExprFold( ** This is called during initialization to register the fts5_expr() scalar ** UDF with the SQLite handle passed as the only argument. */ -static int tdsqlite3Fts5ExprInit(Fts5Global *pGlobal, tdsqlite3 *db){ +static int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ struct Fts5ExprFunc { const char *z; - void (*x)(tdsqlite3_context*,int,tdsqlite3_value**); + void (*x)(sqlite3_context*,int,sqlite3_value**); } aFunc[] = { { "fts5_expr", fts5ExprFunctionHr }, { "fts5_expr_tcl", fts5ExprFunctionTcl }, @@ -217115,15 +217115,15 @@ static int tdsqlite3Fts5ExprInit(Fts5Global *pGlobal, tdsqlite3 *db){ for(i=0; rc==SQLITE_OK && iz, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); + rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0); } - /* Avoid warnings indicating that tdsqlite3Fts5ParserTrace() and - ** tdsqlite3Fts5ParserFallback() are unused */ + /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and + ** sqlite3Fts5ParserFallback() are unused */ #ifndef NDEBUG - (void)tdsqlite3Fts5ParserTrace; + (void)sqlite3Fts5ParserTrace; #endif - (void)tdsqlite3Fts5ParserFallback; + (void)sqlite3Fts5ParserFallback; return rc; } @@ -217131,14 +217131,14 @@ static int tdsqlite3Fts5ExprInit(Fts5Global *pGlobal, tdsqlite3 *db){ /* ** Return the number of phrases in expression pExpr. */ -static int tdsqlite3Fts5ExprPhraseCount(Fts5Expr *pExpr){ +static int sqlite3Fts5ExprPhraseCount(Fts5Expr *pExpr){ return (pExpr ? pExpr->nPhrase : 0); } /* ** Return the number of terms in the iPhrase'th phrase in pExpr. */ -static int tdsqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){ +static int sqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){ if( iPhrase<0 || iPhrase>=pExpr->nPhrase ) return 0; return pExpr->apExprPhrase[iPhrase]->nTerm; } @@ -217147,7 +217147,7 @@ static int tdsqlite3Fts5ExprPhraseSize(Fts5Expr *pExpr, int iPhrase){ ** This function is used to access the current position list for phrase ** iPhrase. */ -static int tdsqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){ +static int sqlite3Fts5ExprPoslist(Fts5Expr *pExpr, int iPhrase, const u8 **pa){ int nRet; Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase]; Fts5ExprNode *pNode = pPhrase->pNode; @@ -217167,9 +217167,9 @@ struct Fts5PoslistPopulator { int bMiss; }; -static Fts5PoslistPopulator *tdsqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){ +static Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr *pExpr, int bLive){ Fts5PoslistPopulator *pRet; - pRet = tdsqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase); + pRet = sqlite3_malloc64(sizeof(Fts5PoslistPopulator)*pExpr->nPhrase); if( pRet ){ int i; memset(pRet, 0, sizeof(Fts5PoslistPopulator)*pExpr->nPhrase); @@ -217231,7 +217231,7 @@ static int fts5ExprPopulatePoslistsCb( if( (nTerm==nToken || (nTermbPrefix)) && memcmp(pTerm->zTerm, pToken, nTerm)==0 ){ - int rc = tdsqlite3Fts5PoslistWriterAppend( + int rc = sqlite3Fts5PoslistWriterAppend( &pExpr->apExprPhrase[i]->poslist, &p->aPopulator[i].writer, p->iOff ); if( rc ) return rc; @@ -217242,7 +217242,7 @@ static int fts5ExprPopulatePoslistsCb( return SQLITE_OK; } -static int tdsqlite3Fts5ExprPopulatePoslists( +static int sqlite3Fts5ExprPopulatePoslists( Fts5Config *pConfig, Fts5Expr *pExpr, Fts5PoslistPopulator *aPopulator, @@ -217267,7 +217267,7 @@ static int tdsqlite3Fts5ExprPopulatePoslists( } } - return tdsqlite3Fts5Tokenize(pConfig, + return sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, z, n, (void*)&sCtx, fts5ExprPopulatePoslistsCb ); } @@ -217327,14 +217327,14 @@ static int fts5ExprCheckPoslists(Fts5ExprNode *pNode, i64 iRowid){ return 1; } -static void tdsqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){ +static void sqlite3Fts5ExprCheckPoslists(Fts5Expr *pExpr, i64 iRowid){ fts5ExprCheckPoslists(pExpr->pRoot, iRowid); } /* ** This function is only called for detail=columns tables. */ -static int tdsqlite3Fts5ExprPhraseCollist( +static int sqlite3Fts5ExprPhraseCollist( Fts5Expr *pExpr, int iPhrase, const u8 **ppCollist, @@ -217453,24 +217453,24 @@ struct Fts5HashEntry { /* ** Allocate a new hash table. */ -static int tdsqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){ +static int sqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnByte){ int rc = SQLITE_OK; Fts5Hash *pNew; - *ppNew = pNew = (Fts5Hash*)tdsqlite3_malloc(sizeof(Fts5Hash)); + *ppNew = pNew = (Fts5Hash*)sqlite3_malloc(sizeof(Fts5Hash)); if( pNew==0 ){ rc = SQLITE_NOMEM; }else{ - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; memset(pNew, 0, sizeof(Fts5Hash)); pNew->pnByte = pnByte; pNew->eDetail = pConfig->eDetail; pNew->nSlot = 1024; nByte = sizeof(Fts5HashEntry*) * pNew->nSlot; - pNew->aSlot = (Fts5HashEntry**)tdsqlite3_malloc64(nByte); + pNew->aSlot = (Fts5HashEntry**)sqlite3_malloc64(nByte); if( pNew->aSlot==0 ){ - tdsqlite3_free(pNew); + sqlite3_free(pNew); *ppNew = 0; rc = SQLITE_NOMEM; }else{ @@ -217483,25 +217483,25 @@ static int tdsqlite3Fts5HashNew(Fts5Config *pConfig, Fts5Hash **ppNew, int *pnBy /* ** Free a hash table object. */ -static void tdsqlite3Fts5HashFree(Fts5Hash *pHash){ +static void sqlite3Fts5HashFree(Fts5Hash *pHash){ if( pHash ){ - tdsqlite3Fts5HashClear(pHash); - tdsqlite3_free(pHash->aSlot); - tdsqlite3_free(pHash); + sqlite3Fts5HashClear(pHash); + sqlite3_free(pHash->aSlot); + sqlite3_free(pHash); } } /* ** Empty (but do not delete) a hash table. */ -static void tdsqlite3Fts5HashClear(Fts5Hash *pHash){ +static void sqlite3Fts5HashClear(Fts5Hash *pHash){ int i; for(i=0; inSlot; i++){ Fts5HashEntry *pNext; Fts5HashEntry *pSlot; for(pSlot=pHash->aSlot[i]; pSlot; pSlot=pNext){ pNext = pSlot->pHashNext; - tdsqlite3_free(pSlot); + sqlite3_free(pSlot); } } memset(pHash->aSlot, 0, pHash->nSlot * sizeof(Fts5HashEntry*)); @@ -217536,7 +217536,7 @@ static int fts5HashResize(Fts5Hash *pHash){ Fts5HashEntry **apNew; Fts5HashEntry **apOld = pHash->aSlot; - apNew = (Fts5HashEntry**)tdsqlite3_malloc64(nNew*sizeof(Fts5HashEntry*)); + apNew = (Fts5HashEntry**)sqlite3_malloc64(nNew*sizeof(Fts5HashEntry*)); if( !apNew ) return SQLITE_NOMEM; memset(apNew, 0, nNew*sizeof(Fts5HashEntry*)); @@ -217552,7 +217552,7 @@ static int fts5HashResize(Fts5Hash *pHash){ } } - tdsqlite3_free(apOld); + sqlite3_free(apOld); pHash->nSlot = nNew; pHash->aSlot = apNew; return SQLITE_OK; @@ -217583,9 +217583,9 @@ static int fts5HashAddPoslistSize( if( nPos<=127 ){ pPtr[p->iSzPoslist] = (u8)nPos; }else{ - int nByte = tdsqlite3Fts5GetVarintLen((u32)nPos); + int nByte = sqlite3Fts5GetVarintLen((u32)nPos); memmove(&pPtr[p->iSzPoslist + nByte], &pPtr[p->iSzPoslist + 1], nSz); - tdsqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos); + sqlite3Fts5PutVarint(&pPtr[p->iSzPoslist], nPos); nData += (nByte-1); } } @@ -217609,7 +217609,7 @@ static int fts5HashAddPoslistSize( ** ** Or, if iCol is negative, then the value is a delete marker. */ -static int tdsqlite3Fts5HashWrite( +static int sqlite3Fts5HashWrite( Fts5Hash *pHash, i64 iRowid, /* Rowid for this entry */ int iCol, /* Column token appears in (-ve -> delete) */ @@ -217641,7 +217641,7 @@ static int tdsqlite3Fts5HashWrite( if( p==0 ){ /* Figure out how much space to allocate */ char *zKey; - tdsqlite3_int64 nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64; + sqlite3_int64 nByte = sizeof(Fts5HashEntry) + (nToken+1) + 1 + 64; if( nByte<128 ) nByte = 128; /* Grow the Fts5Hash.aSlot[] array if necessary. */ @@ -217652,7 +217652,7 @@ static int tdsqlite3Fts5HashWrite( } /* Allocate new Fts5HashEntry and add it to the hash table. */ - p = (Fts5HashEntry*)tdsqlite3_malloc64(nByte); + p = (Fts5HashEntry*)sqlite3_malloc64(nByte); if( !p ) return SQLITE_NOMEM; memset(p, 0, sizeof(Fts5HashEntry)); p->nAlloc = (int)nByte; @@ -217668,7 +217668,7 @@ static int tdsqlite3Fts5HashWrite( pHash->nEntry++; /* Add the first rowid field to the hash-entry */ - p->nData += tdsqlite3Fts5PutVarint(&((u8*)p)[p->nData], iRowid); + p->nData += sqlite3Fts5PutVarint(&((u8*)p)[p->nData], iRowid); p->iRowid = iRowid; p->iSzPoslist = p->nData; @@ -217691,10 +217691,10 @@ static int tdsqlite3Fts5HashWrite( ** + 5 bytes for the new position offset (32-bit max). */ if( (p->nAlloc - p->nData) < (9 + 4 + 1 + 3 + 5) ){ - tdsqlite3_int64 nNew = p->nAlloc * 2; + sqlite3_int64 nNew = p->nAlloc * 2; Fts5HashEntry *pNew; Fts5HashEntry **pp; - pNew = (Fts5HashEntry*)tdsqlite3_realloc64(p, nNew); + pNew = (Fts5HashEntry*)sqlite3_realloc64(p, nNew); if( pNew==0 ) return SQLITE_NOMEM; pNew->nAlloc = (int)nNew; for(pp=&pHash->aSlot[iHash]; *pp!=p; pp=&(*pp)->pHashNext); @@ -217711,7 +217711,7 @@ static int tdsqlite3Fts5HashWrite( ** entry, and the new rowid for this entry. */ if( iRowid!=p->iRowid ){ fts5HashAddPoslistSize(pHash, p, 0); - p->nData += tdsqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid); + p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iRowid - p->iRowid); p->iRowid = iRowid; bNew = 1; p->iSzPoslist = p->nData; @@ -217731,7 +217731,7 @@ static int tdsqlite3Fts5HashWrite( if( iCol!=p->iCol ){ if( pHash->eDetail==FTS5_DETAIL_FULL ){ pPtr[p->nData++] = 0x01; - p->nData += tdsqlite3Fts5PutVarint(&pPtr[p->nData], iCol); + p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iCol); p->iCol = (i16)iCol; p->iPos = 0; }else{ @@ -217742,7 +217742,7 @@ static int tdsqlite3Fts5HashWrite( /* Append the new position offset, if necessary */ if( bNew ){ - p->nData += tdsqlite3Fts5PutVarint(&pPtr[p->nData], iPos - p->iPos + 2); + p->nData += sqlite3Fts5PutVarint(&pPtr[p->nData], iPos - p->iPos + 2); p->iPos = iPos; } } @@ -217820,7 +217820,7 @@ static int fts5HashEntrySort( int i; *ppSorted = 0; - ap = tdsqlite3_malloc64(sizeof(Fts5HashEntry*) * nMergeSlot); + ap = sqlite3_malloc64(sizeof(Fts5HashEntry*) * nMergeSlot); if( !ap ) return SQLITE_NOMEM; memset(ap, 0, sizeof(Fts5HashEntry*) * nMergeSlot); @@ -217847,7 +217847,7 @@ static int fts5HashEntrySort( } pHash->nEntry = 0; - tdsqlite3_free(ap); + sqlite3_free(ap); *ppSorted = pList; return SQLITE_OK; } @@ -217855,7 +217855,7 @@ static int fts5HashEntrySort( /* ** Query the hash table for a doclist associated with term pTerm/nTerm. */ -static int tdsqlite3Fts5HashQuery( +static int sqlite3Fts5HashQuery( Fts5Hash *pHash, /* Hash table to query */ int nPre, const char *pTerm, int nTerm, /* Query term */ @@ -217875,7 +217875,7 @@ static int tdsqlite3Fts5HashQuery( if( p ){ int nHashPre = sizeof(Fts5HashEntry) + nTerm + 1; int nList = p->nData - nHashPre; - u8 *pRet = (u8*)(*ppOut = tdsqlite3_malloc64(nPre + nList + 10)); + u8 *pRet = (u8*)(*ppOut = sqlite3_malloc64(nPre + nList + 10)); if( pRet ){ Fts5HashEntry *pFaux = (Fts5HashEntry*)&pRet[nPre-nHashPre]; memcpy(&pRet[nPre], &((u8*)p)[nHashPre], nList); @@ -217893,23 +217893,23 @@ static int tdsqlite3Fts5HashQuery( return SQLITE_OK; } -static int tdsqlite3Fts5HashScanInit( +static int sqlite3Fts5HashScanInit( Fts5Hash *p, /* Hash table to query */ const char *pTerm, int nTerm /* Query prefix */ ){ return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan); } -static void tdsqlite3Fts5HashScanNext(Fts5Hash *p){ - assert( !tdsqlite3Fts5HashScanEof(p) ); +static void sqlite3Fts5HashScanNext(Fts5Hash *p){ + assert( !sqlite3Fts5HashScanEof(p) ); p->pScan = p->pScan->pScanNext; } -static int tdsqlite3Fts5HashScanEof(Fts5Hash *p){ +static int sqlite3Fts5HashScanEof(Fts5Hash *p){ return (p->pScan==0); } -static void tdsqlite3Fts5HashScanEntry( +static void sqlite3Fts5HashScanEntry( Fts5Hash *pHash, const char **pzTerm, /* OUT: term (nul-terminated) */ const u8 **ppDoclist, /* OUT: pointer to doclist */ @@ -218172,7 +218172,7 @@ static void tdsqlite3Fts5HashScanEntry( #define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno) #ifdef SQLITE_DEBUG -static int tdsqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; } +static int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; } #endif @@ -218224,15 +218224,15 @@ struct Fts5Index { int rc; /* Current error code */ /* State used by the fts5DataXXX() functions. */ - tdsqlite3_blob *pReader; /* RO incr-blob open on %_data table */ - tdsqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */ - tdsqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ - tdsqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ - tdsqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ - tdsqlite3_stmt *pIdxSelect; + sqlite3_blob *pReader; /* RO incr-blob open on %_data table */ + sqlite3_stmt *pWriter; /* "INSERT ... %_data VALUES(?,?)" */ + sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ + sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ + sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ + sqlite3_stmt *pIdxSelect; int nRead; /* Total number of blocks read */ - tdsqlite3_stmt *pDataVersion; + sqlite3_stmt *pDataVersion; i64 iStructVersion; /* data_version when pStruct read */ Fts5Structure *pStruct; /* Current db structure (or NULL) */ }; @@ -218432,7 +218432,7 @@ struct Fts5SegIter { ** the smallest key overall. aFirst[0] is unused. ** ** poslist: -** Used by tdsqlite3Fts5IterPoslist() when the poslist needs to be buffered. +** Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered. ** There is no way to tell if this is populated or not. */ struct Fts5Iter { @@ -218499,8 +218499,8 @@ static u16 fts5GetU16(const u8 *aIn){ ** If an OOM error is encountered, return NULL and set the error code in ** the Fts5Index handle passed as the first argument. */ -static void *fts5IdxMalloc(Fts5Index *p, tdsqlite3_int64 nByte){ - return tdsqlite3Fts5MallocZero(&p->rc, nByte); +static void *fts5IdxMalloc(Fts5Index *p, sqlite3_int64 nByte){ + return sqlite3Fts5MallocZero(&p->rc, nByte); } /* @@ -218546,11 +218546,11 @@ static int fts5LeafFirstTermOff(Fts5Data *pLeaf){ /* ** Close the read-only blob handle, if it is open. */ -static void tdsqlite3Fts5IndexCloseReader(Fts5Index *p){ +static void sqlite3Fts5IndexCloseReader(Fts5Index *p){ if( p->pReader ){ - tdsqlite3_blob *pReader = p->pReader; + sqlite3_blob *pReader = p->pReader; p->pReader = 0; - tdsqlite3_blob_close(pReader); + sqlite3_blob_close(pReader); } } @@ -218569,13 +218569,13 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ /* This call may return SQLITE_ABORT if there has been a savepoint ** rollback since it was last used. In this case a new blob handle ** is required. */ - tdsqlite3_blob *pBlob = p->pReader; + sqlite3_blob *pBlob = p->pReader; p->pReader = 0; - rc = tdsqlite3_blob_reopen(pBlob, iRowid); + rc = sqlite3_blob_reopen(pBlob, iRowid); assert( p->pReader==0 ); p->pReader = pBlob; if( rc!=SQLITE_OK ){ - tdsqlite3Fts5IndexCloseReader(p); + sqlite3Fts5IndexCloseReader(p); } if( rc==SQLITE_ABORT ) rc = SQLITE_OK; } @@ -218584,12 +218584,12 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ ** to the requested entry. */ if( p->pReader==0 && rc==SQLITE_OK ){ Fts5Config *pConfig = p->pConfig; - rc = tdsqlite3_blob_open(pConfig->db, + rc = sqlite3_blob_open(pConfig->db, pConfig->zDb, p->zDataTbl, "block", iRowid, 0, &p->pReader ); } - /* If either of the tdsqlite3_blob_open() or tdsqlite3_blob_reopen() calls + /* If either of the sqlite3_blob_open() or sqlite3_blob_reopen() calls ** above returned SQLITE_ERROR, return SQLITE_CORRUPT_VTAB instead. ** All the reasons those functions might return SQLITE_ERROR - missing ** table, missing row, non-blob/text in block column - indicate @@ -218598,9 +218598,9 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ if( rc==SQLITE_OK ){ u8 *aOut = 0; /* Read blob data into this buffer */ - int nByte = tdsqlite3_blob_bytes(p->pReader); - tdsqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; - pRet = (Fts5Data*)tdsqlite3_malloc64(nAlloc); + int nByte = sqlite3_blob_bytes(p->pReader); + sqlite3_int64 nAlloc = sizeof(Fts5Data) + nByte + FTS5_DATA_PADDING; + pRet = (Fts5Data*)sqlite3_malloc64(nAlloc); if( pRet ){ pRet->nn = nByte; aOut = pRet->p = (u8*)&pRet[1]; @@ -218609,10 +218609,10 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ } if( rc==SQLITE_OK ){ - rc = tdsqlite3_blob_read(p->pReader, aOut, nByte, 0); + rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0); } if( rc!=SQLITE_OK ){ - tdsqlite3_free(pRet); + sqlite3_free(pRet); pRet = 0; }else{ /* TODO1: Fix this */ @@ -218634,7 +218634,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){ ** fts5DataRead(). */ static void fts5DataRelease(Fts5Data *pData){ - tdsqlite3_free(pData); + sqlite3_free(pData); } static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){ @@ -218651,19 +218651,19 @@ static Fts5Data *fts5LeafRead(Fts5Index *p, i64 iRowid){ static int fts5IndexPrepareStmt( Fts5Index *p, - tdsqlite3_stmt **ppStmt, + sqlite3_stmt **ppStmt, char *zSql ){ if( p->rc==SQLITE_OK ){ if( zSql ){ - p->rc = tdsqlite3_prepare_v3(p->pConfig->db, zSql, -1, + p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB, ppStmt, 0); }else{ p->rc = SQLITE_NOMEM; } } - tdsqlite3_free(zSql); + sqlite3_free(zSql); return p->rc; } @@ -218676,18 +218676,18 @@ static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){ if( p->pWriter==0 ){ Fts5Config *pConfig = p->pConfig; - fts5IndexPrepareStmt(p, &p->pWriter, tdsqlite3_mprintf( + fts5IndexPrepareStmt(p, &p->pWriter, sqlite3_mprintf( "REPLACE INTO '%q'.'%q_data'(id, block) VALUES(?,?)", pConfig->zDb, pConfig->zName )); if( p->rc ) return; } - tdsqlite3_bind_int64(p->pWriter, 1, iRowid); - tdsqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC); - tdsqlite3_step(p->pWriter); - p->rc = tdsqlite3_reset(p->pWriter); - tdsqlite3_bind_null(p->pWriter, 2); + sqlite3_bind_int64(p->pWriter, 1, iRowid); + sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC); + sqlite3_step(p->pWriter); + p->rc = sqlite3_reset(p->pWriter); + sqlite3_bind_null(p->pWriter, 2); } /* @@ -218700,17 +218700,17 @@ static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){ if( p->pDeleter==0 ){ Fts5Config *pConfig = p->pConfig; - char *zSql = tdsqlite3_mprintf( + char *zSql = sqlite3_mprintf( "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?", pConfig->zDb, pConfig->zName ); if( fts5IndexPrepareStmt(p, &p->pDeleter, zSql) ) return; } - tdsqlite3_bind_int64(p->pDeleter, 1, iFirst); - tdsqlite3_bind_int64(p->pDeleter, 2, iLast); - tdsqlite3_step(p->pDeleter); - p->rc = tdsqlite3_reset(p->pDeleter); + sqlite3_bind_int64(p->pDeleter, 1, iFirst); + sqlite3_bind_int64(p->pDeleter, 2, iLast); + sqlite3_step(p->pDeleter); + p->rc = sqlite3_reset(p->pDeleter); } /* @@ -218722,15 +218722,15 @@ static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){ fts5DataDelete(p, iFirst, iLast); if( p->pIdxDeleter==0 ){ Fts5Config *pConfig = p->pConfig; - fts5IndexPrepareStmt(p, &p->pIdxDeleter, tdsqlite3_mprintf( + fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf( "DELETE FROM '%q'.'%q_idx' WHERE segid=?", pConfig->zDb, pConfig->zName )); } if( p->rc==SQLITE_OK ){ - tdsqlite3_bind_int(p->pIdxDeleter, 1, iSegid); - tdsqlite3_step(p->pIdxDeleter); - p->rc = tdsqlite3_reset(p->pIdxDeleter); + sqlite3_bind_int(p->pIdxDeleter, 1, iSegid); + sqlite3_step(p->pIdxDeleter); + p->rc = sqlite3_reset(p->pIdxDeleter); } } @@ -218743,9 +218743,9 @@ static void fts5StructureRelease(Fts5Structure *pStruct){ int i; assert( pStruct->nRef==0 ); for(i=0; inLevel; i++){ - tdsqlite3_free(pStruct->aLevel[i].aSeg); + sqlite3_free(pStruct->aLevel[i].aSeg); } - tdsqlite3_free(pStruct); + sqlite3_free(pStruct); } } @@ -218776,11 +218776,11 @@ static int fts5StructureDecode( int iLvl; int nLevel = 0; int nSegment = 0; - tdsqlite3_int64 nByte; /* Bytes of space to allocate at pRet */ + sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */ Fts5Structure *pRet = 0; /* Structure object to return */ /* Grab the cookie value */ - if( piCookie ) *piCookie = tdsqlite3Fts5Get32(pData); + if( piCookie ) *piCookie = sqlite3Fts5Get32(pData); i = 4; /* Read the total number of levels and segments from the start of the @@ -218796,13 +218796,13 @@ static int fts5StructureDecode( sizeof(Fts5Structure) + /* Main structure */ sizeof(Fts5StructureLevel) * (nLevel-1) /* aLevel[] array */ ); - pRet = (Fts5Structure*)tdsqlite3Fts5MallocZero(&rc, nByte); + pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte); if( pRet ){ pRet->nRef = 1; pRet->nLevel = nLevel; pRet->nSegment = nSegment; - i += tdsqlite3Fts5GetVarint(&pData[i], &pRet->nWriteCounter); + i += sqlite3Fts5GetVarint(&pData[i], &pRet->nWriteCounter); for(iLvl=0; rc==SQLITE_OK && iLvlaLevel[iLvl]; @@ -218815,7 +218815,7 @@ static int fts5StructureDecode( i += fts5GetVarint32(&pData[i], pLvl->nMerge); i += fts5GetVarint32(&pData[i], nTotal); if( nTotalnMerge ) rc = FTS5_CORRUPT; - pLvl->aSeg = (Fts5StructureSegment*)tdsqlite3Fts5MallocZero(&rc, + pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, nTotal * sizeof(Fts5StructureSegment) ); nSegment -= nTotal; @@ -218860,12 +218860,12 @@ static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){ if( *pRc==SQLITE_OK ){ Fts5Structure *pStruct = *ppStruct; int nLevel = pStruct->nLevel; - tdsqlite3_int64 nByte = ( + sqlite3_int64 nByte = ( sizeof(Fts5Structure) + /* Main structure */ sizeof(Fts5StructureLevel) * (nLevel+1) /* aLevel[] array */ ); - pStruct = tdsqlite3_realloc64(pStruct, nByte); + pStruct = sqlite3_realloc64(pStruct, nByte); if( pStruct ){ memset(&pStruct->aLevel[nLevel], 0, sizeof(Fts5StructureLevel)); pStruct->nLevel++; @@ -218890,10 +218890,10 @@ static void fts5StructureExtendLevel( if( *pRc==SQLITE_OK ){ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; Fts5StructureSegment *aNew; - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; nByte = (pLvl->nSeg + nExtra) * sizeof(Fts5StructureSegment); - aNew = tdsqlite3_realloc64(pLvl->aSeg, nByte); + aNew = sqlite3_realloc64(pLvl->aSeg, nByte); if( aNew ){ if( bInsert==0 ){ memset(&aNew[pLvl->nSeg], 0, sizeof(Fts5StructureSegment) * nExtra); @@ -218921,7 +218921,7 @@ static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){ memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING); p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet); if( p->rc==SQLITE_OK && (pConfig->pgsz==0 || pConfig->iCookie!=iCookie) ){ - p->rc = tdsqlite3Fts5ConfigLoad(pConfig, iCookie); + p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie); } fts5DataRelease(pData); if( p->rc!=SQLITE_OK ){ @@ -218939,15 +218939,15 @@ static i64 fts5IndexDataVersion(Fts5Index *p){ if( p->rc==SQLITE_OK ){ if( p->pDataVersion==0 ){ p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, - tdsqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb) + sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb) ); if( p->rc ) return 0; } - if( SQLITE_ROW==tdsqlite3_step(p->pDataVersion) ){ - iVersion = tdsqlite3_column_int64(p->pDataVersion, 0); + if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){ + iVersion = sqlite3_column_int64(p->pDataVersion, 0); } - p->rc = tdsqlite3_reset(p->pDataVersion); + p->rc = sqlite3_reset(p->pDataVersion); } return iVersion; @@ -219035,7 +219035,7 @@ static int fts5StructureCountSegments(Fts5Structure *pStruct){ } #define fts5BufferSafeAppendVarint(pBuf, iVal) { \ - (pBuf)->n += tdsqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \ + (pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal)); \ assert( (pBuf)->nSpace>=(pBuf)->n ); \ } @@ -219059,8 +219059,8 @@ static void fts5StructureWrite(Fts5Index *p, Fts5Structure *pStruct){ iCookie = p->pConfig->iCookie; if( iCookie<0 ) iCookie = 0; - if( 0==tdsqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){ - tdsqlite3Fts5Put32(buf.p, iCookie); + if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){ + sqlite3Fts5Put32(buf.p, iCookie); buf.n = 4; fts5BufferSafeAppendVarint(&buf, pStruct->nLevel); fts5BufferSafeAppendVarint(&buf, pStruct->nSegment); @@ -219392,7 +219392,7 @@ static void fts5DlidxIterFree(Fts5DlidxIter *pIter){ for(i=0; inLvl; i++){ fts5DataRelease(pIter->aLvl[i].pData); } - tdsqlite3_free(pIter); + sqlite3_free(pIter); } } @@ -219407,10 +219407,10 @@ static Fts5DlidxIter *fts5DlidxIterInit( int bDone = 0; for(i=0; p->rc==SQLITE_OK && bDone==0; i++){ - tdsqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl); + sqlite3_int64 nByte = sizeof(Fts5DlidxIter) + i * sizeof(Fts5DlidxLvl); Fts5DlidxIter *pNew; - pNew = (Fts5DlidxIter*)tdsqlite3_realloc64(pIter, nByte); + pNew = (Fts5DlidxIter*)sqlite3_realloc64(pIter, nByte); if( pNew==0 ){ p->rc = SQLITE_NOMEM; }else{ @@ -219555,7 +219555,7 @@ static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){ iOff = 4; a = pIter->pLeaf->p; } - iOff += tdsqlite3Fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); + iOff += sqlite3Fts5GetVarint(&a[iOff], (u64*)&pIter->iRowid); pIter->iLeafOffset = iOff; } @@ -219707,7 +219707,7 @@ static void fts5SegIterReverseInitPage(Fts5Index *p, Fts5SegIter *pIter){ /* If necessary, grow the pIter->aRowidOffset[] array. */ if( iRowidOffset>=pIter->nRowidOffset ){ int nNew = pIter->nRowidOffset + 8; - int *aNew = (int*)tdsqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int)); + int *aNew = (int*)sqlite3_realloc64(pIter->aRowidOffset,nNew*sizeof(int)); if( aNew==0 ){ p->rc = SQLITE_NOMEM; break; @@ -219847,7 +219847,7 @@ static void fts5SegIterNext_None( if( iOffiEndofDoclist ){ /* Next entry is on the current page */ i64 iDelta; - iOff += tdsqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta); + iOff += sqlite3Fts5GetVarint(&pIter->pLeaf->p[iOff], (u64*)&iDelta); pIter->iLeafOffset = iOff; pIter->iRowid += iDelta; }else if( (pIter->flags & FTS5_SEGITER_ONETERM)==0 ){ @@ -219862,14 +219862,14 @@ static void fts5SegIterNext_None( const u8 *pList = 0; const char *zTerm = 0; int nList; - tdsqlite3Fts5HashScanNext(p->pHash); - tdsqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); + sqlite3Fts5HashScanNext(p->pHash); + sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); if( pList==0 ) goto next_none_eof; pIter->pLeaf->p = (u8*)pList; pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList; - tdsqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm); + sqlite3Fts5BufferSet(&p->rc,&pIter->term, (int)strlen(zTerm), (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); } @@ -219926,7 +219926,7 @@ static void fts5SegIterNext( } }else{ u64 iDelta; - iOff += tdsqlite3Fts5GetVarint(&a[iOff], &iDelta); + iOff += sqlite3Fts5GetVarint(&a[iOff], &iDelta); pIter->iRowid += iDelta; assert_nc( iDelta>0 ); } @@ -219938,8 +219938,8 @@ static void fts5SegIterNext( int nList = 0; assert( (pIter->flags & FTS5_SEGITER_ONETERM) || pbNewTerm ); if( 0==(pIter->flags & FTS5_SEGITER_ONETERM) ){ - tdsqlite3Fts5HashScanNext(p->pHash); - tdsqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); + sqlite3Fts5HashScanNext(p->pHash); + sqlite3Fts5HashScanEntry(p->pHash, &zTerm, &pList, &nList); } if( pList==0 ){ fts5DataRelease(pIter->pLeaf); @@ -219949,7 +219949,7 @@ static void fts5SegIterNext( pIter->pLeaf->nn = nList; pIter->pLeaf->szLeaf = nList; pIter->iEndofDoclist = nList+1; - tdsqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), + sqlite3Fts5BufferSet(&p->rc, &pIter->term, (int)strlen(zTerm), (u8*)zTerm); pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid); *pbNewTerm = 1; @@ -219963,7 +219963,7 @@ static void fts5SegIterNext( if( pLeaf==0 ) break; ASSERT_SZLEAF_OK(pLeaf); if( (iOff = fts5LeafFirstRowidOff(pLeaf)) && iOffszLeaf ){ - iOff += tdsqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid); + iOff += sqlite3Fts5GetVarint(&pLeaf->p[iOff], (u64*)&pIter->iRowid); pIter->iLeafOffset = iOff; if( pLeaf->nn>pLeaf->szLeaf ){ @@ -220277,10 +220277,10 @@ static void fts5LeafSeek( fts5SegIterLoadNPos(p, pIter); } -static tdsqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){ +static sqlite3_stmt *fts5IdxSelectStmt(Fts5Index *p){ if( p->pIdxSelect==0 ){ Fts5Config *pConfig = p->pConfig; - fts5IndexPrepareStmt(p, &p->pIdxSelect, tdsqlite3_mprintf( + fts5IndexPrepareStmt(p, &p->pIdxSelect, sqlite3_mprintf( "SELECT pgno FROM '%q'.'%q_idx' WHERE " "segid=? AND term<=? ORDER BY term DESC LIMIT 1", pConfig->zDb, pConfig->zName @@ -220306,7 +220306,7 @@ static void fts5SegIterSeekInit( int iPg = 1; int bGe = (flags & FTS5INDEX_QUERY_SCAN); int bDlidx = 0; /* True if there is a doclist-index */ - tdsqlite3_stmt *pIdxSelect = 0; + sqlite3_stmt *pIdxSelect = 0; assert( bGe==0 || (flags & FTS5INDEX_QUERY_DESC)==0 ); assert( pTerm && nTerm ); @@ -220317,15 +220317,15 @@ static void fts5SegIterSeekInit( ** contain term (pTerm/nTerm), if it is present in the segment. */ pIdxSelect = fts5IdxSelectStmt(p); if( p->rc ) return; - tdsqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid); - tdsqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC); - if( SQLITE_ROW==tdsqlite3_step(pIdxSelect) ){ - i64 val = tdsqlite3_column_int(pIdxSelect, 0); + sqlite3_bind_int(pIdxSelect, 1, pSeg->iSegid); + sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC); + if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){ + i64 val = sqlite3_column_int(pIdxSelect, 0); iPg = (int)(val>>1); bDlidx = (val & 0x0001); } - p->rc = tdsqlite3_reset(pIdxSelect); - tdsqlite3_bind_null(pIdxSelect, 2); + p->rc = sqlite3_reset(pIdxSelect); + sqlite3_bind_null(pIdxSelect, 2); if( iPgpgnoFirst ){ iPg = pSeg->pgnoFirst; @@ -220396,8 +220396,8 @@ static void fts5SegIterHashInit( if( pTerm==0 || (flags & FTS5INDEX_QUERY_SCAN) ){ const u8 *pList = 0; - p->rc = tdsqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); - tdsqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList); + p->rc = sqlite3Fts5HashScanInit(p->pHash, (const char*)pTerm, nTerm); + sqlite3Fts5HashScanEntry(p->pHash, (const char**)&z, &pList, &nList); n = (z ? (int)strlen((const char*)z) : 0); if( pList ){ pLeaf = fts5IdxMalloc(p, sizeof(Fts5Data)); @@ -220406,7 +220406,7 @@ static void fts5SegIterHashInit( } } }else{ - p->rc = tdsqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data), + p->rc = sqlite3Fts5HashQuery(p->pHash, sizeof(Fts5Data), (const char*)pTerm, nTerm, (void**)&pLeaf, &nList ); if( pLeaf ){ @@ -220418,7 +220418,7 @@ static void fts5SegIterHashInit( } if( pLeaf ){ - tdsqlite3Fts5BufferSet(&p->rc, &pIter->term, n, z); + sqlite3Fts5BufferSet(&p->rc, &pIter->term, n, z); pLeaf->nn = pLeaf->szLeaf = nList; pIter->pLeaf = pLeaf; pIter->iLeafOffset = fts5GetVarint(pLeaf->p, (u64*)&pIter->iRowid); @@ -220443,7 +220443,7 @@ static void fts5SegIterClear(Fts5SegIter *pIter){ fts5DataRelease(pIter->pLeaf); fts5DataRelease(pIter->pNextLeaf); fts5DlidxIterFree(pIter->pDlidx); - tdsqlite3_free(pIter->aRowidOffset); + sqlite3_free(pIter->aRowidOffset); memset(pIter, 0, sizeof(Fts5SegIter)); } @@ -220695,7 +220695,7 @@ static void fts5MultiIterFree(Fts5Iter *pIter){ fts5SegIterClear(&pIter->aSeg[i]); } fts5BufferFree(&pIter->poslist); - tdsqlite3_free(pIter); + sqlite3_free(pIter); } } @@ -221288,7 +221288,7 @@ static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){ assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS ); if( pConfig->nCol<=100 ){ pIter->xSetOutputs = fts5IterSetOutputs_Col100; - tdsqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol); + sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol); }else{ pIter->xSetOutputs = fts5IterSetOutputs_Col; } @@ -221538,14 +221538,14 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){ assert_nc( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); { - tdsqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p); + sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p); if( p->rc==SQLITE_OK ){ u8 aBlob[2] = {0xff, 0xff}; - tdsqlite3_bind_int(pIdxSelect, 1, iSegid); - tdsqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); - assert_nc( tdsqlite3_step(pIdxSelect)!=SQLITE_ROW ); - p->rc = tdsqlite3_reset(pIdxSelect); - tdsqlite3_bind_null(pIdxSelect, 2); + sqlite3_bind_int(pIdxSelect, 1, iSegid); + sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC); + assert_nc( sqlite3_step(pIdxSelect)!=SQLITE_ROW ); + p->rc = sqlite3_reset(pIdxSelect); + sqlite3_bind_null(pIdxSelect, 2); } } #endif @@ -221561,7 +221561,7 @@ static int fts5AllocateSegid(Fts5Index *p, Fts5Structure *pStruct){ static void fts5IndexDiscardData(Fts5Index *p){ assert( p->pHash || p->nPendingData==0 ); if( p->pHash ){ - tdsqlite3Fts5HashClear(p->pHash); + sqlite3Fts5HashClear(p->pHash); p->nPendingData = 0; } } @@ -221598,7 +221598,7 @@ static void fts5WriteDlidxClear( pDlidx->buf.p, pDlidx->buf.n ); } - tdsqlite3Fts5BufferZero(&pDlidx->buf); + sqlite3Fts5BufferZero(&pDlidx->buf); pDlidx->bPrevValid = 0; } } @@ -221613,7 +221613,7 @@ static int fts5WriteDlidxGrow( int nLvl ){ if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){ - Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)tdsqlite3_realloc64( + Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc64( pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl ); if( aDlidx==0 ){ @@ -221667,12 +221667,12 @@ static void fts5WriteFlushBtree(Fts5Index *p, Fts5SegWriter *pWriter){ if( p->rc==SQLITE_OK ){ const char *z = (pWriter->btterm.n>0?(const char*)pWriter->btterm.p:""); /* The following was already done in fts5WriteInit(): */ - /* tdsqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); */ - tdsqlite3_bind_blob(p->pIdxWriter, 2, z, pWriter->btterm.n, SQLITE_STATIC); - tdsqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1)); - tdsqlite3_step(p->pIdxWriter); - p->rc = tdsqlite3_reset(p->pIdxWriter); - tdsqlite3_bind_null(p->pIdxWriter, 2); + /* sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); */ + sqlite3_bind_blob(p->pIdxWriter, 2, z, pWriter->btterm.n, SQLITE_STATIC); + sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1)); + sqlite3_step(p->pIdxWriter); + p->rc = sqlite3_reset(p->pIdxWriter); + sqlite3_bind_null(p->pIdxWriter, 2); } pWriter->iBtPage = 0; } @@ -221711,7 +221711,7 @@ static void fts5WriteBtreeNoTerm( if( pWriter->bFirstRowidInPage && pWriter->aDlidx[0].buf.n>0 ){ Fts5DlidxWriter *pDlidx = &pWriter->aDlidx[0]; assert( pDlidx->bPrevValid ); - tdsqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, 0); + sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, 0); } /* Increment the "number of sequential leaves without a term" counter. */ @@ -221762,14 +221762,14 @@ static void fts5WriteDlidxAppend( /* This was the root node. Push its first rowid up to the new root. */ pDlidx[1].pgno = pDlidx->pgno; - tdsqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, 0); - tdsqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, pDlidx->pgno); - tdsqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, iFirst); + sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, 0); + sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, pDlidx->pgno); + sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx[1].buf, iFirst); pDlidx[1].bPrevValid = 1; pDlidx[1].iPrev = iFirst; } - tdsqlite3Fts5BufferZero(&pDlidx->buf); + sqlite3Fts5BufferZero(&pDlidx->buf); pDlidx->bPrevValid = 0; pDlidx->pgno++; }else{ @@ -221781,12 +221781,12 @@ static void fts5WriteDlidxAppend( }else{ i64 iPgno = (i==0 ? pWriter->writer.pgno : pDlidx[-1].pgno); assert( pDlidx->buf.n==0 ); - tdsqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone); - tdsqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno); + sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, !bDone); + sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iPgno); iVal = iRowid; } - tdsqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iVal); + sqlite3Fts5BufferAppendVarint(&p->rc, &pDlidx->buf, iVal); pDlidx->bPrevValid = 1; pDlidx->iPrev = iRowid; } @@ -221862,7 +221862,7 @@ static void fts5WriteAppendTerm( } /* TODO1: Updating pgidx here. */ - pPgidx->n += tdsqlite3Fts5PutVarint( + pPgidx->n += sqlite3Fts5PutVarint( &pPgidx->p[pPgidx->n], pPage->buf.n - pPage->iPrevPgidx ); pPage->iPrevPgidx = pPage->buf.n; @@ -222009,9 +222009,9 @@ static void fts5WriteFinish( fts5BufferFree(&pWriter->btterm); for(i=0; inDlidx; i++){ - tdsqlite3Fts5BufferFree(&pWriter->aDlidx[i].buf); + sqlite3Fts5BufferFree(&pWriter->aDlidx[i].buf); } - tdsqlite3_free(pWriter->aDlidx); + sqlite3_free(pWriter->aDlidx); } static void fts5WriteInit( @@ -222033,12 +222033,12 @@ static void fts5WriteInit( assert( pWriter->writer.pgidx.n==0 ); /* Grow the two buffers to pgsz + padding bytes in size. */ - tdsqlite3Fts5BufferSize(&p->rc, &pWriter->writer.pgidx, nBuffer); - tdsqlite3Fts5BufferSize(&p->rc, &pWriter->writer.buf, nBuffer); + sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.pgidx, nBuffer); + sqlite3Fts5BufferSize(&p->rc, &pWriter->writer.buf, nBuffer); if( p->pIdxWriter==0 ){ Fts5Config *pConfig = p->pConfig; - fts5IndexPrepareStmt(p, &p->pIdxWriter, tdsqlite3_mprintf( + fts5IndexPrepareStmt(p, &p->pIdxWriter, sqlite3_mprintf( "INSERT INTO '%q'.'%q_idx'(segid,term,pgno) VALUES(?,?,?)", pConfig->zDb, pConfig->zName )); @@ -222052,7 +222052,7 @@ static void fts5WriteInit( /* Bind the current output segment id to the index-writer. This is an ** optimization over binding the same value over and over as rows are ** inserted into %_idx by the current writer. */ - tdsqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); + sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); } } @@ -222457,15 +222457,15 @@ static void fts5FlushOneHash(Fts5Index *p){ /* Begin scanning through hash table entries. This loop runs once for each ** term/doclist currently stored within the hash table. */ if( p->rc==SQLITE_OK ){ - p->rc = tdsqlite3Fts5HashScanInit(pHash, 0, 0); + p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); } - while( p->rc==SQLITE_OK && 0==tdsqlite3Fts5HashScanEof(pHash) ){ + while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ const char *zTerm; /* Buffer containing term */ const u8 *pDoclist; /* Pointer to doclist for this term */ int nDoclist; /* Size of doclist in bytes */ /* Write the term for this entry to disk. */ - tdsqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); + sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); fts5WriteAppendTerm(p, &writer, (int)strlen(zTerm), (const u8*)zTerm); if( p->rc!=SQLITE_OK ) break; @@ -222487,12 +222487,12 @@ static void fts5FlushOneHash(Fts5Index *p){ if( writer.bFirstRowidInPage ){ fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */ - pBuf->n += tdsqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); writer.bFirstRowidInPage = 0; fts5WriteDlidxAppend(p, &writer, iRowid); if( p->rc!=SQLITE_OK ) break; }else{ - pBuf->n += tdsqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta); + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iDelta); } assert( pBuf->n<=pBuf->nSpace ); @@ -222548,9 +222548,9 @@ static void fts5FlushOneHash(Fts5Index *p){ /* TODO2: Doclist terminator written here. */ /* pBuf->p[pBuf->n++] = '\0'; */ assert( pBuf->n<=pBuf->nSpace ); - if( p->rc==SQLITE_OK ) tdsqlite3Fts5HashScanNext(pHash); + if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); } - tdsqlite3Fts5HashClear(pHash); + sqlite3Fts5HashClear(pHash); fts5WriteFinish(p, &writer, &pgnoLast); /* Update the Fts5Structure. It is written back to the database by the @@ -222592,7 +222592,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( Fts5Structure *pStruct ){ Fts5Structure *pNew = 0; - tdsqlite3_int64 nByte = sizeof(Fts5Structure); + sqlite3_int64 nByte = sizeof(Fts5Structure); int nSeg = pStruct->nSegment; int i; @@ -222617,7 +222617,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( } nByte += (pStruct->nLevel+1) * sizeof(Fts5StructureLevel); - pNew = (Fts5Structure*)tdsqlite3Fts5MallocZero(&p->rc, nByte); + pNew = (Fts5Structure*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pNew ){ Fts5StructureLevel *pLvl; @@ -222626,7 +222626,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( pNew->nRef = 1; pNew->nWriteCounter = pStruct->nWriteCounter; pLvl = &pNew->aLevel[pStruct->nLevel]; - pLvl->aSeg = (Fts5StructureSegment*)tdsqlite3Fts5MallocZero(&p->rc, nByte); + pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pLvl->aSeg ){ int iLvl, iSeg; int iSegOut = 0; @@ -222641,7 +222641,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( } pNew->nSegment = pLvl->nSeg = nSeg; }else{ - tdsqlite3_free(pNew); + sqlite3_free(pNew); pNew = 0; } } @@ -222649,7 +222649,7 @@ static Fts5Structure *fts5IndexOptimizeStruct( return pNew; } -static int tdsqlite3Fts5IndexOptimize(Fts5Index *p){ +static int sqlite3Fts5IndexOptimize(Fts5Index *p){ Fts5Structure *pStruct; Fts5Structure *pNew = 0; @@ -222683,7 +222683,7 @@ static int tdsqlite3Fts5IndexOptimize(Fts5Index *p){ ** This is called to implement the special "VALUES('merge', $nMerge)" ** INSERT command. */ -static int tdsqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ +static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ Fts5Structure *pStruct = fts5StructureRead(p); if( pStruct ){ int nMin = p->pConfig->nUsermerge; @@ -222808,7 +222808,7 @@ static void fts5NextRowid(Fts5Buffer *pBuf, int *piOff, i64 *piRowid){ *piOff = -1; }else{ u64 iVal; - *piOff = i + tdsqlite3Fts5GetVarint(&pBuf->p[i], &iVal); + *piOff = i + sqlite3Fts5GetVarint(&pBuf->p[i], &iVal); *piRowid += iVal; } } @@ -222830,7 +222830,7 @@ static void fts5MergeRowidLists( Fts5Buffer out; memset(&out, 0, sizeof(out)); - tdsqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n); + sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n); if( p->rc ) return; fts5NextRowid(p1, &i1, &iRowid1); @@ -222888,7 +222888,7 @@ static void fts5MergePrefixLists( ** (the value PoslistNext64() uses for EOF) as a position and appending ** it to the output. This can happen at most once for each input ** position-list, hence two 10 byte paddings. */ - if( tdsqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return; + if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9+10+10) ) return; fts5DoclistIterInit(p1, &i1); fts5DoclistIterInit(p2, &i2); @@ -222929,32 +222929,32 @@ static void fts5MergePrefixLists( ** at most 20 bytes of unexpected space. */ fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferZero(&tmp); - tdsqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10); + sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10); if( p->rc ) break; - tdsqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); - tdsqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); + sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); + sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2); assert_nc( iPos1>=0 && iPos2>=0 ); if( iPos1=0 && iPos2>=0 ){ while( 1 ){ if( iPos1=0 ){ if( iPos1!=iPrev ){ - tdsqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos1); } aCopy = &a1[iOff1]; nCopy = i1.nPoslist - iOff1; }else{ assert_nc( iPos2>=0 && iPos2!=iPrev ); - tdsqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); + sqlite3Fts5PoslistSafeAppend(&tmp, &iPrev, iPos2); aCopy = &a2[iOff2]; nCopy = i2.nPoslist - iOff2; } @@ -223101,20 +223101,20 @@ static void fts5SetupPrefixIter( } fts5StructureRelease(pStruct); - tdsqlite3_free(aBuf); + sqlite3_free(aBuf); } /* -** Indicate that all subsequent calls to tdsqlite3Fts5IndexWrite() pertain +** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain ** to the document with rowid iRowid. */ -static int tdsqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ +static int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ assert( p->rc==SQLITE_OK ); /* Allocate the hash table if it has not already been allocated */ if( p->pHash==0 ){ - p->rc = tdsqlite3Fts5HashNew(p->pConfig, &p->pHash, &p->nPendingData); + p->rc = sqlite3Fts5HashNew(p->pConfig, &p->pHash, &p->nPendingData); } /* Flush the hash table to disk if required */ @@ -223133,10 +223133,10 @@ static int tdsqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){ /* ** Commit data to disk. */ -static int tdsqlite3Fts5IndexSync(Fts5Index *p){ +static int sqlite3Fts5IndexSync(Fts5Index *p){ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); - tdsqlite3Fts5IndexCloseReader(p); + sqlite3Fts5IndexCloseReader(p); return fts5IndexReturn(p); } @@ -223146,8 +223146,8 @@ static int tdsqlite3Fts5IndexSync(Fts5Index *p){ ** table may have changed on disk. So any in-memory caches of %_data ** records must be invalidated. */ -static int tdsqlite3Fts5IndexRollback(Fts5Index *p){ - tdsqlite3Fts5IndexCloseReader(p); +static int sqlite3Fts5IndexRollback(Fts5Index *p){ + sqlite3Fts5IndexCloseReader(p); fts5IndexDiscardData(p); fts5StructureInvalidate(p); /* assert( p->rc==SQLITE_OK ); */ @@ -223159,7 +223159,7 @@ static int tdsqlite3Fts5IndexRollback(Fts5Index *p){ ** function populates it with the initial structure objects for each index, ** and the initial version of the "averages" record (a zero-byte blob). */ -static int tdsqlite3Fts5IndexReinit(Fts5Index *p){ +static int sqlite3Fts5IndexReinit(Fts5Index *p){ Fts5Structure s; fts5StructureInvalidate(p); fts5IndexDiscardData(p); @@ -223176,7 +223176,7 @@ static int tdsqlite3Fts5IndexReinit(Fts5Index *p){ ** If successful, set *pp to point to the new object and return SQLITE_OK. ** Otherwise, set *pp to NULL and return an SQLite error code. */ -static int tdsqlite3Fts5IndexOpen( +static int sqlite3Fts5IndexOpen( Fts5Config *pConfig, int bCreate, Fts5Index **pp, @@ -223185,52 +223185,52 @@ static int tdsqlite3Fts5IndexOpen( int rc = SQLITE_OK; Fts5Index *p; /* New object */ - *pp = p = (Fts5Index*)tdsqlite3Fts5MallocZero(&rc, sizeof(Fts5Index)); + *pp = p = (Fts5Index*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Index)); if( rc==SQLITE_OK ){ p->pConfig = pConfig; p->nWorkUnit = FTS5_WORK_UNIT; - p->zDataTbl = tdsqlite3Fts5Mprintf(&rc, "%s_data", pConfig->zName); + p->zDataTbl = sqlite3Fts5Mprintf(&rc, "%s_data", pConfig->zName); if( p->zDataTbl && bCreate ){ - rc = tdsqlite3Fts5CreateTable( + rc = sqlite3Fts5CreateTable( pConfig, "data", "id INTEGER PRIMARY KEY, block BLOB", 0, pzErr ); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5CreateTable(pConfig, "idx", + rc = sqlite3Fts5CreateTable(pConfig, "idx", "segid, term, pgno, PRIMARY KEY(segid, term)", 1, pzErr ); } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IndexReinit(p); + rc = sqlite3Fts5IndexReinit(p); } } } assert( rc!=SQLITE_OK || p->rc==SQLITE_OK ); if( rc ){ - tdsqlite3Fts5IndexClose(p); + sqlite3Fts5IndexClose(p); *pp = 0; } return rc; } /* -** Close a handle opened by an earlier call to tdsqlite3Fts5IndexOpen(). +** Close a handle opened by an earlier call to sqlite3Fts5IndexOpen(). */ -static int tdsqlite3Fts5IndexClose(Fts5Index *p){ +static int sqlite3Fts5IndexClose(Fts5Index *p){ int rc = SQLITE_OK; if( p ){ assert( p->pReader==0 ); fts5StructureInvalidate(p); - tdsqlite3_finalize(p->pWriter); - tdsqlite3_finalize(p->pDeleter); - tdsqlite3_finalize(p->pIdxWriter); - tdsqlite3_finalize(p->pIdxDeleter); - tdsqlite3_finalize(p->pIdxSelect); - tdsqlite3_finalize(p->pDataVersion); - tdsqlite3Fts5HashFree(p->pHash); - tdsqlite3_free(p->zDataTbl); - tdsqlite3_free(p); + sqlite3_finalize(p->pWriter); + sqlite3_finalize(p->pDeleter); + sqlite3_finalize(p->pIdxWriter); + sqlite3_finalize(p->pIdxDeleter); + sqlite3_finalize(p->pIdxSelect); + sqlite3_finalize(p->pDataVersion); + sqlite3Fts5HashFree(p->pHash); + sqlite3_free(p->zDataTbl); + sqlite3_free(p); } return rc; } @@ -223240,7 +223240,7 @@ static int tdsqlite3Fts5IndexClose(Fts5Index *p){ ** size. Return the number of bytes in the nChar character prefix of the ** buffer, or 0 if there are less than nChar characters in total. */ -static int tdsqlite3Fts5IndexCharlenToBytelen( +static int sqlite3Fts5IndexCharlenToBytelen( const char *p, int nByte, int nChar @@ -223289,7 +223289,7 @@ static int fts5IndexCharlen(const char *pIn, int nIn){ ** unique token in the document with an iCol value less than zero. The iPos ** argument is ignored for a delete. */ -static int tdsqlite3Fts5IndexWrite( +static int sqlite3Fts5IndexWrite( Fts5Index *p, /* Index to write to */ int iCol, /* Column token appears in (-ve -> delete) */ int iPos, /* Position of token within column */ @@ -223303,15 +223303,15 @@ static int tdsqlite3Fts5IndexWrite( assert( (iCol<0)==p->bDelete ); /* Add the entry to the main terms index. */ - rc = tdsqlite3Fts5HashWrite( + rc = sqlite3Fts5HashWrite( p->pHash, p->iWriteRowid, iCol, iPos, FTS5_MAIN_PREFIX, pToken, nToken ); for(i=0; inPrefix && rc==SQLITE_OK; i++){ const int nChar = pConfig->aPrefix[i]; - int nByte = tdsqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar); + int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar); if( nByte ){ - rc = tdsqlite3Fts5HashWrite(p->pHash, + rc = sqlite3Fts5HashWrite(p->pHash, p->iWriteRowid, iCol, iPos, (char)(FTS5_MAIN_PREFIX+i+1), pToken, nByte ); @@ -223325,7 +223325,7 @@ static int tdsqlite3Fts5IndexWrite( ** Open a new iterator to iterate though all rowid that match the ** specified token or token prefix. */ -static int tdsqlite3Fts5IndexQuery( +static int sqlite3Fts5IndexQuery( Fts5Index *p, /* FTS index to query */ const char *pToken, int nToken, /* Token (or prefix) to query for */ int flags, /* Mask of FTS5INDEX_QUERY_X flags */ @@ -223339,7 +223339,7 @@ static int tdsqlite3Fts5IndexQuery( /* If the QUERY_SCAN flag is set, all other flags must be clear. */ assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN ); - if( tdsqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ + if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ int iIdx = 0; /* Index to search */ if( nToken ) memcpy(&buf.p[1], pToken, nToken); @@ -223390,13 +223390,13 @@ static int tdsqlite3Fts5IndexQuery( } if( p->rc ){ - tdsqlite3Fts5IterClose((Fts5IndexIter*)pRet); + sqlite3Fts5IterClose((Fts5IndexIter*)pRet); pRet = 0; - tdsqlite3Fts5IndexCloseReader(p); + sqlite3Fts5IndexCloseReader(p); } *ppIter = (Fts5IndexIter*)pRet; - tdsqlite3Fts5BufferFree(&buf); + sqlite3Fts5BufferFree(&buf); } return fts5IndexReturn(p); } @@ -223407,7 +223407,7 @@ static int tdsqlite3Fts5IndexQuery( /* ** Move to the next matching rowid. */ -static int tdsqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ +static int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; assert( pIter->pIndex->rc==SQLITE_OK ); fts5MultiIterNext(pIter->pIndex, pIter, 0, 0); @@ -223417,7 +223417,7 @@ static int tdsqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){ /* ** Move to the next matching term/rowid. Used by the fts5vocab module. */ -static int tdsqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ +static int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *p = pIter->pIndex; @@ -223441,7 +223441,7 @@ static int tdsqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){ ** definition of "at or after" depends on whether this iterator iterates ** in ascending or descending rowid order. */ -static int tdsqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ +static int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch); return fts5IndexReturn(pIter->pIndex); @@ -223450,7 +223450,7 @@ static int tdsqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){ /* ** Return the current term. */ -static const char *tdsqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ +static const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ int n; const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n); *pn = n-1; @@ -223458,14 +223458,14 @@ static const char *tdsqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){ } /* -** Close an iterator opened by an earlier call to tdsqlite3Fts5IndexQuery(). +** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery(). */ -static void tdsqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ +static void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ if( pIndexIter ){ Fts5Iter *pIter = (Fts5Iter*)pIndexIter; Fts5Index *pIndex = pIter->pIndex; fts5MultiIterFree(pIter); - tdsqlite3Fts5IndexCloseReader(pIndex); + sqlite3Fts5IndexCloseReader(pIndex); } } @@ -223475,7 +223475,7 @@ static void tdsqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){ ** Parameter anSize must point to an array of size nCol, where nCol is ** the number of user defined columns in the FTS table. */ -static int tdsqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize){ +static int sqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize){ int nCol = p->pConfig->nCol; Fts5Data *pData; @@ -223499,7 +223499,7 @@ static int tdsqlite3Fts5IndexGetAverages(Fts5Index *p, i64 *pnRow, i64 *anSize){ ** Replace the current "averages" record with the contents of the buffer ** supplied as the second argument. */ -static int tdsqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nData){ +static int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nData){ assert( p->rc==SQLITE_OK ); fts5DataWrite(p, FTS5_AVERAGES_ROWID, pData, nData); return fts5IndexReturn(p); @@ -223509,7 +223509,7 @@ static int tdsqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nDat ** Return the total number of blocks this module has read from the %_data ** table since it was created. */ -static int tdsqlite3Fts5IndexReads(Fts5Index *p){ +static int sqlite3Fts5IndexReads(Fts5Index *p){ return p->nRead; } @@ -223520,27 +223520,27 @@ static int tdsqlite3Fts5IndexReads(Fts5Index *p){ ** Return SQLITE_OK if successful, or an SQLite error code if an error ** occurs. */ -static int tdsqlite3Fts5IndexSetCookie(Fts5Index *p, int iNew){ +static int sqlite3Fts5IndexSetCookie(Fts5Index *p, int iNew){ int rc; /* Return code */ Fts5Config *pConfig = p->pConfig; /* Configuration object */ u8 aCookie[4]; /* Binary representation of iNew */ - tdsqlite3_blob *pBlob = 0; + sqlite3_blob *pBlob = 0; assert( p->rc==SQLITE_OK ); - tdsqlite3Fts5Put32(aCookie, iNew); + sqlite3Fts5Put32(aCookie, iNew); - rc = tdsqlite3_blob_open(pConfig->db, pConfig->zDb, p->zDataTbl, + rc = sqlite3_blob_open(pConfig->db, pConfig->zDb, p->zDataTbl, "block", FTS5_STRUCTURE_ROWID, 1, &pBlob ); if( rc==SQLITE_OK ){ - tdsqlite3_blob_write(pBlob, aCookie, 4, 0); - rc = tdsqlite3_blob_close(pBlob); + sqlite3_blob_write(pBlob, aCookie, 4, 0); + rc = sqlite3_blob_close(pBlob); } return rc; } -static int tdsqlite3Fts5IndexLoadConfig(Fts5Index *p){ +static int sqlite3Fts5IndexLoadConfig(Fts5Index *p){ Fts5Structure *pStruct; pStruct = fts5StructureRead(p); fts5StructureRelease(pStruct); @@ -223557,7 +223557,7 @@ static int tdsqlite3Fts5IndexLoadConfig(Fts5Index *p){ /* ** Return a simple checksum value based on the arguments. */ -static u64 tdsqlite3Fts5IndexEntryCksum( +static u64 sqlite3Fts5IndexEntryCksum( i64 iRowid, int iCol, int iPos, @@ -223630,29 +223630,29 @@ static int fts5QueryCksum( int eDetail = p->pConfig->eDetail; u64 cksum = *pCksum; Fts5IndexIter *pIter = 0; - int rc = tdsqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); + int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter); - while( rc==SQLITE_OK && 0==tdsqlite3Fts5IterEof(pIter) ){ + while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){ i64 rowid = pIter->iRowid; if( eDetail==FTS5_DETAIL_NONE ){ - cksum ^= tdsqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n); + cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n); }else{ Fts5PoslistReader sReader; - for(tdsqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader); + for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader); sReader.bEof==0; - tdsqlite3Fts5PoslistReaderNext(&sReader) + sqlite3Fts5PoslistReaderNext(&sReader) ){ int iCol = FTS5_POS2COLUMN(sReader.iPos); int iOff = FTS5_POS2OFFSET(sReader.iPos); - cksum ^= tdsqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n); + cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n); } } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IterNext(pIter); + rc = sqlite3Fts5IterNext(pIter); } } - tdsqlite3Fts5IterClose(pIter); + sqlite3Fts5IterClose(pIter); *pCksum = cksum; return rc; @@ -223851,28 +223851,28 @@ static void fts5IndexIntegrityCheckSegment( Fts5StructureSegment *pSeg /* Segment to check internal consistency */ ){ Fts5Config *pConfig = p->pConfig; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; int rc2; int iIdxPrevLeaf = pSeg->pgnoFirst-1; int iDlidxPrevLeaf = pSeg->pgnoLast; if( pSeg->pgnoFirst==0 ) return; - fts5IndexPrepareStmt(p, &pStmt, tdsqlite3_mprintf( + fts5IndexPrepareStmt(p, &pStmt, sqlite3_mprintf( "SELECT segid, term, (pgno>>1), (pgno&1) FROM %Q.'%q_idx' WHERE segid=%d " "ORDER BY 1, 2", pConfig->zDb, pConfig->zName, pSeg->iSegid )); /* Iterate through the b-tree hierarchy. */ - while( p->rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pStmt) ){ + while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ i64 iRow; /* Rowid for this leaf */ Fts5Data *pLeaf; /* Data for this leaf */ - const char *zIdxTerm = (const char*)tdsqlite3_column_blob(pStmt, 1); - int nIdxTerm = tdsqlite3_column_bytes(pStmt, 1); - int iIdxLeaf = tdsqlite3_column_int(pStmt, 2); - int bIdxDlidx = tdsqlite3_column_int(pStmt, 3); + const char *zIdxTerm = (const char*)sqlite3_column_blob(pStmt, 1); + int nIdxTerm = sqlite3_column_bytes(pStmt, 1); + int iIdxLeaf = sqlite3_column_int(pStmt, 2); + int bIdxDlidx = sqlite3_column_int(pStmt, 3); /* If the leaf in question has already been trimmed from the segment, ** ignore this b-tree entry. Otherwise, load it into memory. */ @@ -223969,7 +223969,7 @@ static void fts5IndexIntegrityCheckSegment( iIdxPrevLeaf = iIdxLeaf; } - rc2 = tdsqlite3_finalize(pStmt); + rc2 = sqlite3_finalize(pStmt); if( p->rc==SQLITE_OK ) p->rc = rc2; /* Page iter.iLeaf must now be the rightmost leaf-page in the segment */ @@ -223984,14 +223984,14 @@ static void fts5IndexIntegrityCheckSegment( /* ** Run internal checks to ensure that the FTS index (a) is internally ** consistent and (b) contains entries for which the XOR of the checksums -** as calculated by tdsqlite3Fts5IndexEntryCksum() is cksum. +** as calculated by sqlite3Fts5IndexEntryCksum() is cksum. ** ** Return SQLITE_CORRUPT if any of the internal checks fail, or if the ** checksum does not match. Return SQLITE_OK if all checks pass without ** error, or some other SQLite error code if another error (e.g. OOM) ** occurs. */ -static int tdsqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ +static int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ int eDetail = p->pConfig->eDetail; u64 cksum2 = 0; /* Checksum based on contents of indexes */ Fts5Buffer poslist = {0,0,0}; /* Buffer used to hold a poslist */ @@ -224047,15 +224047,15 @@ static int tdsqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){ if( eDetail==FTS5_DETAIL_NONE ){ if( 0==fts5MultiIterIsEmpty(p, pIter) ){ - cksum2 ^= tdsqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n); + cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, 0, 0, -1, z, n); } }else{ poslist.n = 0; fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst], 0, &poslist); - while( 0==tdsqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){ + while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){ int iCol = FTS5_POS2COLUMN(iPos); int iTokOff = FTS5_POS2OFFSET(iPos); - cksum2 ^= tdsqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n); + cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n); } } } @@ -224107,13 +224107,13 @@ static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ if( iSegid==0 ){ if( iKey==FTS5_AVERAGES_ROWID ){ - tdsqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} "); + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{averages} "); }else{ - tdsqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}"); + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{structure}"); } } else{ - tdsqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}", + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}", bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno ); } @@ -224128,16 +224128,16 @@ static void fts5DebugStructure( for(iLvl=0; iLvlnLevel; iLvl++){ Fts5StructureLevel *pLvl = &p->aLevel[iLvl]; - tdsqlite3Fts5BufferAppendPrintf(pRc, pBuf, + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {lvl=%d nMerge=%d nSeg=%d", iLvl, pLvl->nMerge, pLvl->nSeg ); for(iSeg=0; iSegnSeg; iSeg++){ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; - tdsqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}", + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}", pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast ); } - tdsqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); } } @@ -224183,8 +224183,8 @@ static void fts5DecodeAverages( while( i0 ){ - iOff = tdsqlite3Fts5GetVarint(a, (u64*)&iDocid); - tdsqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid); + iOff = sqlite3Fts5GetVarint(a, (u64*)&iDocid); + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid); } while( iOff0 ) memcpy(a, aBlob, n); @@ -224327,7 +224327,7 @@ static void fts5DecodeFunction( lvl.iLeafPgno = iPgno; for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){ - tdsqlite3Fts5BufferAppendPrintf(&rc, &s, + sqlite3Fts5BufferAppendPrintf(&rc, &s, " %d(%lld)", lvl.iLeafPgno, lvl.iRowid ); } @@ -224363,7 +224363,7 @@ static void fts5DecodeFunction( iOff += fts5GetVarint32(&a[iOff], nAppend); term.n = nKeep; fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]); - tdsqlite3Fts5BufferAppendPrintf( + sqlite3Fts5BufferAppendPrintf( &rc, &s, " term=%.*s", term.n, (const char*)term.p ); iOff += nAppend; @@ -224398,7 +224398,7 @@ static void fts5DecodeFunction( memset(&term, 0, sizeof(Fts5Buffer)); if( n<4 ){ - tdsqlite3Fts5BufferSet(&rc, &s, 7, (const u8*)"corrupt"); + sqlite3Fts5BufferSet(&rc, &s, 7, (const u8*)"corrupt"); goto decode_out; }else{ iRowidOff = fts5GetU16(&a[0]); @@ -224470,7 +224470,7 @@ static void fts5DecodeFunction( fts5BufferAppendBlob(&rc, &term, nByte, &a[iOff]); iOff += nByte; - tdsqlite3Fts5BufferAppendPrintf( + sqlite3Fts5BufferAppendPrintf( &rc, &s, " term=%.*s", term.n, (const char*)term.p ); iOff += fts5DecodeDoclist(&rc, &s, &a[iOff], iEnd-iOff); @@ -224480,11 +224480,11 @@ static void fts5DecodeFunction( } decode_out: - tdsqlite3_free(a); + sqlite3_free(a); if( rc==SQLITE_OK ){ - tdsqlite3_result_text(pCtx, (const char*)s.p, s.n, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, (const char*)s.p, s.n, SQLITE_TRANSIENT); }else{ - tdsqlite3_result_error_code(pCtx, rc); + sqlite3_result_error_code(pCtx, rc); } fts5BufferFree(&s); } @@ -224493,30 +224493,30 @@ static void fts5DecodeFunction( ** The implementation of user-defined scalar function fts5_rowid(). */ static void fts5RowidFunction( - tdsqlite3_context *pCtx, /* Function call context */ + sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args (always 2) */ - tdsqlite3_value **apVal /* Function arguments */ + sqlite3_value **apVal /* Function arguments */ ){ const char *zArg; if( nArg==0 ){ - tdsqlite3_result_error(pCtx, "should be: fts5_rowid(subject, ....)", -1); + sqlite3_result_error(pCtx, "should be: fts5_rowid(subject, ....)", -1); }else{ - zArg = (const char*)tdsqlite3_value_text(apVal[0]); - if( 0==tdsqlite3_stricmp(zArg, "segment") ){ + zArg = (const char*)sqlite3_value_text(apVal[0]); + if( 0==sqlite3_stricmp(zArg, "segment") ){ i64 iRowid; int segid, pgno; if( nArg!=3 ){ - tdsqlite3_result_error(pCtx, + sqlite3_result_error(pCtx, "should be: fts5_rowid('segment', segid, pgno))", -1 ); }else{ - segid = tdsqlite3_value_int(apVal[1]); - pgno = tdsqlite3_value_int(apVal[2]); + segid = sqlite3_value_int(apVal[1]); + pgno = sqlite3_value_int(apVal[2]); iRowid = FTS5_SEGMENT_ROWID(segid, pgno); - tdsqlite3_result_int64(pCtx, iRowid); + sqlite3_result_int64(pCtx, iRowid); } }else{ - tdsqlite3_result_error(pCtx, + sqlite3_result_error(pCtx, "first arg to fts5_rowid() must be 'segment'" , -1 ); } @@ -224531,20 +224531,20 @@ static void fts5RowidFunction( ** If successful, SQLITE_OK is returned. If an error occurs, some other ** SQLite error code is returned instead. */ -static int tdsqlite3Fts5IndexInit(tdsqlite3 *db){ - int rc = tdsqlite3_create_function( +static int sqlite3Fts5IndexInit(sqlite3 *db){ + int rc = sqlite3_create_function( db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0 ); if( rc==SQLITE_OK ){ - rc = tdsqlite3_create_function( + rc = sqlite3_create_function( db, "fts5_decode_none", 2, SQLITE_UTF8, (void*)db, fts5DecodeFunction, 0, 0 ); } if( rc==SQLITE_OK ){ - rc = tdsqlite3_create_function( + rc = sqlite3_create_function( db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0 ); } @@ -224552,7 +224552,7 @@ static int tdsqlite3Fts5IndexInit(tdsqlite3 *db){ } -static int tdsqlite3Fts5IndexReset(Fts5Index *p){ +static int sqlite3Fts5IndexReset(Fts5Index *p){ assert( p->pStruct==0 || p->iStructVersion!=0 ); if( fts5IndexDataVersion(p)!=p->iStructVersion ){ fts5StructureInvalidate(p); @@ -224584,7 +224584,7 @@ static int tdsqlite3Fts5IndexReset(Fts5Index *p){ ** assert() conditions in the fts5 code are activated - conditions that are ** only true if it is guaranteed that the fts5 database is not corrupt. */ -SQLITE_API int tdsqlite3_fts5_may_be_corrupt = 1; +SQLITE_API int sqlite3_fts5_may_be_corrupt = 1; typedef struct Fts5Auxdata Fts5Auxdata; @@ -224637,7 +224637,7 @@ struct Fts5TransactionState { */ struct Fts5Global { fts5_api api; /* User visible part of object (see fts5.h) */ - tdsqlite3 *db; /* Associated database connection */ + sqlite3 *db; /* Associated database connection */ i64 iNextId; /* Used to allocate unique cursor ids */ Fts5Auxiliary *pAux; /* First in list of all aux. functions */ Fts5TokenizerModule *pTok; /* First in list of all tokenizer modules */ @@ -224697,7 +224697,7 @@ struct Fts5MatchPhrase { ** byte of the position list for the corresponding phrase. */ struct Fts5Sorter { - tdsqlite3_stmt *pStmt; + sqlite3_stmt *pStmt; i64 iRowid; /* Current rowid */ const u8 *aPoslist; /* Position lists for current row */ int nIdx; /* Number of entries in aIdx[] */ @@ -224725,7 +224725,7 @@ struct Fts5Sorter { ** the lower. */ struct Fts5Cursor { - tdsqlite3_vtab_cursor base; /* Base class used by SQLite core */ + sqlite3_vtab_cursor base; /* Base class used by SQLite core */ Fts5Cursor *pNext; /* Next cursor in Fts5Cursor.pCsr list */ int *aColumnSize; /* Values for xColumnSize() */ i64 iCsrId; /* Cursor id */ @@ -224735,7 +224735,7 @@ struct Fts5Cursor { int bDesc; /* True for "ORDER BY rowid DESC" queries */ i64 iFirstRowid; /* Return no rowids earlier than this */ i64 iLastRowid; /* Return no rowids later than this */ - tdsqlite3_stmt *pStmt; /* Statement used to read %_content */ + sqlite3_stmt *pStmt; /* Statement used to read %_content */ Fts5Expr *pExpr; /* Expression for MATCH queries */ Fts5Sorter *pSorter; /* Sorter for "ORDER BY rank" queries */ int csrflags; /* Mask of cursor flags (see below) */ @@ -224746,8 +224746,8 @@ struct Fts5Cursor { char *zRankArgs; /* Custom rank function args */ Fts5Auxiliary *pRank; /* Rank callback (or NULL) */ int nRankArg; /* Number of trailing arguments for rank() */ - tdsqlite3_value **apRankArg; /* Array of trailing arguments */ - tdsqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */ + sqlite3_value **apRankArg; /* Array of trailing arguments */ + sqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */ /* Auxiliary data storage */ Fts5Auxiliary *pAux; /* Currently executing extension function */ @@ -224875,17 +224875,17 @@ static int fts5IsContentless(Fts5FullTable *pTab){ */ static void fts5FreeVtab(Fts5FullTable *pTab){ if( pTab ){ - tdsqlite3Fts5IndexClose(pTab->p.pIndex); - tdsqlite3Fts5StorageClose(pTab->pStorage); - tdsqlite3Fts5ConfigFree(pTab->p.pConfig); - tdsqlite3_free(pTab); + sqlite3Fts5IndexClose(pTab->p.pIndex); + sqlite3Fts5StorageClose(pTab->pStorage); + sqlite3Fts5ConfigFree(pTab->p.pConfig); + sqlite3_free(pTab); } } /* ** The xDisconnect() virtual table method. */ -static int fts5DisconnectMethod(tdsqlite3_vtab *pVtab){ +static int fts5DisconnectMethod(sqlite3_vtab *pVtab){ fts5FreeVtab((Fts5FullTable*)pVtab); return SQLITE_OK; } @@ -224893,9 +224893,9 @@ static int fts5DisconnectMethod(tdsqlite3_vtab *pVtab){ /* ** The xDestroy() virtual table method. */ -static int fts5DestroyMethod(tdsqlite3_vtab *pVtab){ +static int fts5DestroyMethod(sqlite3_vtab *pVtab){ Fts5Table *pTab = (Fts5Table*)pVtab; - int rc = tdsqlite3Fts5DropAll(pTab->pConfig); + int rc = sqlite3Fts5DropAll(pTab->pConfig); if( rc==SQLITE_OK ){ fts5FreeVtab((Fts5FullTable*)pVtab); } @@ -224915,11 +224915,11 @@ static int fts5DestroyMethod(tdsqlite3_vtab *pVtab){ */ static int fts5InitVtab( int bCreate, /* True for xCreate, false for xConnect */ - tdsqlite3 *db, /* The SQLite database connection */ + sqlite3 *db, /* The SQLite database connection */ void *pAux, /* Hash table containing tokenizers */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ + sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ char **pzErr /* Write any error message here */ ){ Fts5Global *pGlobal = (Fts5Global*)pAux; @@ -224929,9 +224929,9 @@ static int fts5InitVtab( Fts5FullTable *pTab = 0; /* New virtual table object */ /* Allocate the new vtab object and parse the configuration */ - pTab = (Fts5FullTable*)tdsqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable)); + pTab = (Fts5FullTable*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5FullTable)); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr); + rc = sqlite3Fts5ConfigParse(pGlobal, db, argc, azConfig, &pConfig, pzErr); assert( (rc==SQLITE_OK && *pzErr==0) || pConfig==0 ); } if( rc==SQLITE_OK ){ @@ -224941,27 +224941,27 @@ static int fts5InitVtab( /* Open the index sub-system */ if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr); + rc = sqlite3Fts5IndexOpen(pConfig, bCreate, &pTab->p.pIndex, pzErr); } /* Open the storage sub-system */ if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5StorageOpen( + rc = sqlite3Fts5StorageOpen( pConfig, pTab->p.pIndex, bCreate, &pTab->pStorage, pzErr ); } - /* Call tdsqlite3_declare_vtab() */ + /* Call sqlite3_declare_vtab() */ if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5ConfigDeclareVtab(pConfig); + rc = sqlite3Fts5ConfigDeclareVtab(pConfig); } /* Load the initial configuration */ if( rc==SQLITE_OK ){ assert( pConfig->pzErrmsg==0 ); pConfig->pzErrmsg = pzErr; - rc = tdsqlite3Fts5IndexLoadConfig(pTab->p.pIndex); - tdsqlite3Fts5IndexRollback(pTab->p.pIndex); + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + sqlite3Fts5IndexRollback(pTab->p.pIndex); pConfig->pzErrmsg = 0; } @@ -224971,7 +224971,7 @@ static int fts5InitVtab( }else if( bCreate ){ fts5CheckTransactionState(pTab, FTS5_BEGIN, 0); } - *ppVTab = (tdsqlite3_vtab*)pTab; + *ppVTab = (sqlite3_vtab*)pTab; return rc; } @@ -224980,22 +224980,22 @@ static int fts5InitVtab( ** work is done in function fts5InitVtab(). */ static int fts5ConnectMethod( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pAux, /* Pointer to tokenizer hash table */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVtab, /* OUT: New tdsqlite3_vtab object */ - char **pzErr /* OUT: tdsqlite3_malloc'd error message */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ ){ return fts5InitVtab(0, db, pAux, argc, argv, ppVtab, pzErr); } static int fts5CreateMethod( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pAux, /* Pointer to tokenizer hash table */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVtab, /* OUT: New tdsqlite3_vtab object */ - char **pzErr /* OUT: tdsqlite3_malloc'd error message */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ ){ return fts5InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr); } @@ -225015,10 +225015,10 @@ static int fts5CreateMethod( ** extension is currently being used by a version of SQLite too old to ** support index-info flags. In that case this function is a no-op. */ -static void fts5SetUniqueFlag(tdsqlite3_index_info *pIdxInfo){ +static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ #if SQLITE_VERSION_NUMBER>=3008012 #ifndef SQLITE_CORE - if( tdsqlite3_libversion_number()>=3008012 ) + if( sqlite3_libversion_number()>=3008012 ) #endif { pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE; @@ -225085,7 +225085,7 @@ static void fts5SetUniqueFlag(tdsqlite3_index_info *pIdxInfo){ ** ** Costs are not modified by the ORDER BY clause. */ -static int fts5BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInfo){ +static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts5Table *pTab = (Fts5Table*)pVTab; Fts5Config *pConfig = pTab->pConfig; const int nCol = pConfig->nCol; @@ -225110,19 +225110,19 @@ static int fts5BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInf assert( SQLITE_INDEX_CONSTRAINT_LEbLock ){ - pTab->base.zErrMsg = tdsqlite3_mprintf( + pTab->base.zErrMsg = sqlite3_mprintf( "recursively defined fts5 content table" ); return SQLITE_ERROR; } - idxStr = (char*)tdsqlite3_malloc(pInfo->nConstraint * 6 + 1); + idxStr = (char*)sqlite3_malloc(pInfo->nConstraint * 6 + 1); if( idxStr==0 ) return SQLITE_NOMEM; pInfo->idxStr = idxStr; pInfo->needToFreeIdxStr = 1; for(i=0; inConstraint; i++){ - struct tdsqlite3_index_constraint *p = &pInfo->aConstraint[i]; + struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; int iCol = p->iColumn; if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol) @@ -225144,7 +225144,7 @@ static int fts5BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInf bSeenMatch = 1; idxStr[iIdxStr++] = 'm'; if( iColnConstraint; i++){ - struct tdsqlite3_index_constraint *p = &pInfo->aConstraint[i]; + struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->iColumn<0 && p->usable ){ int op = p->op; if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){ @@ -225219,25 +225219,25 @@ static int fts5BestIndexMethod(tdsqlite3_vtab *pVTab, tdsqlite3_index_info *pInf static int fts5NewTransaction(Fts5FullTable *pTab){ Fts5Cursor *pCsr; for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ - if( pCsr->base.pVtab==(tdsqlite3_vtab*)pTab ) return SQLITE_OK; + if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK; } - return tdsqlite3Fts5StorageReset(pTab->pStorage); + return sqlite3Fts5StorageReset(pTab->pStorage); } /* ** Implementation of xOpen method. */ -static int fts5OpenMethod(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCsr){ +static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ Fts5FullTable *pTab = (Fts5FullTable*)pVTab; Fts5Config *pConfig = pTab->p.pConfig; Fts5Cursor *pCsr = 0; /* New cursor object */ - tdsqlite3_int64 nByte; /* Bytes of space to allocate */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ int rc; /* Return code */ rc = fts5NewTransaction(pTab); if( rc==SQLITE_OK ){ nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int); - pCsr = (Fts5Cursor*)tdsqlite3_malloc64(nByte); + pCsr = (Fts5Cursor*)sqlite3_malloc64(nByte); if( pCsr ){ Fts5Global *pGlobal = pTab->pGlobal; memset(pCsr, 0, (size_t)nByte); @@ -225249,7 +225249,7 @@ static int fts5OpenMethod(tdsqlite3_vtab *pVTab, tdsqlite3_vtab_cursor **ppCsr){ rc = SQLITE_NOMEM; } } - *ppCsr = (tdsqlite3_vtab_cursor*)pCsr; + *ppCsr = (sqlite3_vtab_cursor*)pCsr; return rc; } @@ -225279,37 +225279,37 @@ static void fts5FreeCursorComponents(Fts5Cursor *pCsr){ Fts5Auxdata *pData; Fts5Auxdata *pNext; - tdsqlite3_free(pCsr->aInstIter); - tdsqlite3_free(pCsr->aInst); + sqlite3_free(pCsr->aInstIter); + sqlite3_free(pCsr->aInst); if( pCsr->pStmt ){ int eStmt = fts5StmtType(pCsr); - tdsqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt); + sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt); } if( pCsr->pSorter ){ Fts5Sorter *pSorter = pCsr->pSorter; - tdsqlite3_finalize(pSorter->pStmt); - tdsqlite3_free(pSorter); + sqlite3_finalize(pSorter->pStmt); + sqlite3_free(pSorter); } if( pCsr->ePlan!=FTS5_PLAN_SOURCE ){ - tdsqlite3Fts5ExprFree(pCsr->pExpr); + sqlite3Fts5ExprFree(pCsr->pExpr); } for(pData=pCsr->pAuxdata; pData; pData=pNext){ pNext = pData->pNext; if( pData->xDelete ) pData->xDelete(pData->pPtr); - tdsqlite3_free(pData); + sqlite3_free(pData); } - tdsqlite3_finalize(pCsr->pRankArgStmt); - tdsqlite3_free(pCsr->apRankArg); + sqlite3_finalize(pCsr->pRankArgStmt); + sqlite3_free(pCsr->apRankArg); if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){ - tdsqlite3_free(pCsr->zRank); - tdsqlite3_free(pCsr->zRankArgs); + sqlite3_free(pCsr->zRank); + sqlite3_free(pCsr->zRankArgs); } - tdsqlite3Fts5IndexCloseReader(pTab->p.pIndex); + sqlite3Fts5IndexCloseReader(pTab->p.pIndex); memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr)); } @@ -225318,7 +225318,7 @@ static void fts5FreeCursorComponents(Fts5Cursor *pCsr){ ** Close the cursor. For additional information see the documentation ** on the xClose method of the virtual table interface. */ -static int fts5CloseMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){ if( pCursor ){ Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab); Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; @@ -225329,7 +225329,7 @@ static int fts5CloseMethod(tdsqlite3_vtab_cursor *pCursor){ for(pp=&pTab->pGlobal->pCsr; (*pp)!=pCsr; pp=&(*pp)->pNext); *pp = pCsr->pNext; - tdsqlite3_free(pCsr); + sqlite3_free(pCsr); } return SQLITE_OK; } @@ -225338,7 +225338,7 @@ static int fts5SorterNext(Fts5Cursor *pCsr){ Fts5Sorter *pSorter = pCsr->pSorter; int rc; - rc = tdsqlite3_step(pSorter->pStmt); + rc = sqlite3_step(pSorter->pStmt); if( rc==SQLITE_DONE ){ rc = SQLITE_OK; CsrFlagSet(pCsr, FTS5CSR_EOF); @@ -225350,9 +225350,9 @@ static int fts5SorterNext(Fts5Cursor *pCsr){ int iOff = 0; rc = SQLITE_OK; - pSorter->iRowid = tdsqlite3_column_int64(pSorter->pStmt, 0); - nBlob = tdsqlite3_column_bytes(pSorter->pStmt, 1); - aBlob = a = tdsqlite3_column_blob(pSorter->pStmt, 1); + pSorter->iRowid = sqlite3_column_int64(pSorter->pStmt, 0); + nBlob = sqlite3_column_bytes(pSorter->pStmt, 1); + aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1); /* nBlob==0 in detail=none mode. */ if( nBlob>0 ){ @@ -225381,7 +225381,7 @@ static void fts5TripCursors(Fts5FullTable *pTab){ Fts5Cursor *pCsr; for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ if( pCsr->ePlan==FTS5_PLAN_MATCH - && pCsr->base.pVtab==(tdsqlite3_vtab*)pTab + && pCsr->base.pVtab==(sqlite3_vtab*)pTab ){ CsrFlagSet(pCsr, FTS5CSR_REQUIRE_RESEEK); } @@ -225406,16 +225406,16 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); int bDesc = pCsr->bDesc; - i64 iRowid = tdsqlite3Fts5ExprRowid(pCsr->pExpr); + i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr); - rc = tdsqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc); - if( rc==SQLITE_OK && iRowid!=tdsqlite3Fts5ExprRowid(pCsr->pExpr) ){ + rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->p.pIndex, iRowid, bDesc); + if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){ *pbSkip = 1; } CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK); fts5CsrNewrow(pCsr); - if( tdsqlite3Fts5ExprEof(pCsr->pExpr) ){ + if( sqlite3Fts5ExprEof(pCsr->pExpr) ){ CsrFlagSet(pCsr, FTS5CSR_EOF); *pbSkip = 1; } @@ -225432,7 +225432,7 @@ static int fts5CursorReseek(Fts5Cursor *pCsr, int *pbSkip){ ** even if we reach end-of-file. The fts5EofMethod() will be called ** subsequently to determine whether or not an EOF was hit. */ -static int fts5NextMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int rc; @@ -225444,8 +225444,8 @@ static int fts5NextMethod(tdsqlite3_vtab_cursor *pCursor){ if( pCsr->ePlan<3 ){ int bSkip = 0; if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc; - rc = tdsqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid); - CsrFlagSet(pCsr, tdsqlite3Fts5ExprEof(pCsr->pExpr)); + rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid); + CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr)); fts5CsrNewrow(pCsr); }else{ switch( pCsr->ePlan ){ @@ -225463,14 +225463,14 @@ static int fts5NextMethod(tdsqlite3_vtab_cursor *pCursor){ default: { Fts5Config *pConfig = ((Fts5Table*)pCursor->pVtab)->pConfig; pConfig->bLock++; - rc = tdsqlite3_step(pCsr->pStmt); + rc = sqlite3_step(pCsr->pStmt); pConfig->bLock--; if( rc!=SQLITE_ROW ){ CsrFlagSet(pCsr, FTS5CSR_EOF); - rc = tdsqlite3_reset(pCsr->pStmt); + rc = sqlite3_reset(pCsr->pStmt); if( rc!=SQLITE_OK ){ - pCursor->pVtab->zErrMsg = tdsqlite3_mprintf( - "%s", tdsqlite3_errmsg(pConfig->db) + pCursor->pVtab->zErrMsg = sqlite3_mprintf( + "%s", sqlite3_errmsg(pConfig->db) ); } }else{ @@ -225486,27 +225486,27 @@ static int fts5NextMethod(tdsqlite3_vtab_cursor *pCursor){ static int fts5PrepareStatement( - tdsqlite3_stmt **ppStmt, + sqlite3_stmt **ppStmt, Fts5Config *pConfig, const char *zFmt, ... ){ - tdsqlite3_stmt *pRet = 0; + sqlite3_stmt *pRet = 0; int rc; char *zSql; va_list ap; va_start(ap, zFmt); - zSql = tdsqlite3_vmprintf(zFmt, ap); + zSql = sqlite3_vmprintf(zFmt, ap); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_prepare_v3(pConfig->db, zSql, -1, + rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT, &pRet, 0); if( rc!=SQLITE_OK ){ - *pConfig->pzErrmsg = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(pConfig->db)); + *pConfig->pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(pConfig->db)); } - tdsqlite3_free(zSql); + sqlite3_free(zSql); } va_end(ap); @@ -225522,14 +225522,14 @@ static int fts5CursorFirstSorted( Fts5Config *pConfig = pTab->p.pConfig; Fts5Sorter *pSorter; int nPhrase; - tdsqlite3_int64 nByte; + sqlite3_int64 nByte; int rc; const char *zRank = pCsr->zRank; const char *zRankArgs = pCsr->zRankArgs; - nPhrase = tdsqlite3Fts5ExprPhraseCount(pCsr->pExpr); + nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); nByte = sizeof(Fts5Sorter) + sizeof(int) * (nPhrase-1); - pSorter = (Fts5Sorter*)tdsqlite3_malloc64(nByte); + pSorter = (Fts5Sorter*)sqlite3_malloc64(nByte); if( pSorter==0 ) return SQLITE_NOMEM; memset(pSorter, 0, (size_t)nByte); pSorter->nIdx = nPhrase; @@ -225558,8 +225558,8 @@ static int fts5CursorFirstSorted( } if( rc!=SQLITE_OK ){ - tdsqlite3_finalize(pSorter->pStmt); - tdsqlite3_free(pSorter); + sqlite3_finalize(pSorter->pStmt); + sqlite3_free(pSorter); pCsr->pSorter = 0; } @@ -225569,8 +225569,8 @@ static int fts5CursorFirstSorted( static int fts5CursorFirst(Fts5FullTable *pTab, Fts5Cursor *pCsr, int bDesc){ int rc; Fts5Expr *pExpr = pCsr->pExpr; - rc = tdsqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc); - if( tdsqlite3Fts5ExprEof(pExpr) ){ + rc = sqlite3Fts5ExprFirst(pExpr, pTab->p.pIndex, pCsr->iFirstRowid, bDesc); + if( sqlite3Fts5ExprEof(pExpr) ){ CsrFlagSet(pCsr, FTS5CSR_EOF); } fts5CsrNewrow(pCsr); @@ -225598,15 +225598,15 @@ static int fts5SpecialMatch( assert( pTab->p.base.zErrMsg==0 ); pCsr->ePlan = FTS5_PLAN_SPECIAL; - if( n==5 && 0==tdsqlite3_strnicmp("reads", z, n) ){ - pCsr->iSpecial = tdsqlite3Fts5IndexReads(pTab->p.pIndex); + if( n==5 && 0==sqlite3_strnicmp("reads", z, n) ){ + pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex); } - else if( n==2 && 0==tdsqlite3_strnicmp("id", z, n) ){ + else if( n==2 && 0==sqlite3_strnicmp("id", z, n) ){ pCsr->iSpecial = pCsr->iCsrId; } else{ /* An unrecognized directive. Return an error message. */ - pTab->p.base.zErrMsg = tdsqlite3_mprintf("unknown special query: %.*s", n, z); + pTab->p.base.zErrMsg = sqlite3_mprintf("unknown special query: %.*s", n, z); rc = SQLITE_ERROR; } @@ -225622,7 +225622,7 @@ static Fts5Auxiliary *fts5FindAuxiliary(Fts5FullTable *pTab, const char *zName){ Fts5Auxiliary *pAux; for(pAux=pTab->pGlobal->pAux; pAux; pAux=pAux->pNext){ - if( tdsqlite3_stricmp(zName, pAux->zFunc)==0 ) return pAux; + if( sqlite3_stricmp(zName, pAux->zFunc)==0 ) return pAux; } /* No function of the specified name was found. Return 0. */ @@ -225639,28 +225639,28 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){ const char *zRankArgs = pCsr->zRankArgs; if( zRankArgs ){ - char *zSql = tdsqlite3Fts5Mprintf(&rc, "SELECT %s", zRankArgs); + char *zSql = sqlite3Fts5Mprintf(&rc, "SELECT %s", zRankArgs); if( zSql ){ - tdsqlite3_stmt *pStmt = 0; - rc = tdsqlite3_prepare_v3(pConfig->db, zSql, -1, + sqlite3_stmt *pStmt = 0; + rc = sqlite3_prepare_v3(pConfig->db, zSql, -1, SQLITE_PREPARE_PERSISTENT, &pStmt, 0); - tdsqlite3_free(zSql); + sqlite3_free(zSql); assert( rc==SQLITE_OK || pCsr->pRankArgStmt==0 ); if( rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pStmt) ){ - tdsqlite3_int64 nByte; - pCsr->nRankArg = tdsqlite3_column_count(pStmt); - nByte = sizeof(tdsqlite3_value*)*pCsr->nRankArg; - pCsr->apRankArg = (tdsqlite3_value**)tdsqlite3Fts5MallocZero(&rc, nByte); + if( SQLITE_ROW==sqlite3_step(pStmt) ){ + sqlite3_int64 nByte; + pCsr->nRankArg = sqlite3_column_count(pStmt); + nByte = sizeof(sqlite3_value*)*pCsr->nRankArg; + pCsr->apRankArg = (sqlite3_value**)sqlite3Fts5MallocZero(&rc, nByte); if( rc==SQLITE_OK ){ int i; for(i=0; inRankArg; i++){ - pCsr->apRankArg[i] = tdsqlite3_column_value(pStmt, i); + pCsr->apRankArg[i] = sqlite3_column_value(pStmt, i); } } pCsr->pRankArgStmt = pStmt; }else{ - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); assert( rc!=SQLITE_OK ); } } @@ -225671,7 +225671,7 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){ pAux = fts5FindAuxiliary(pTab, zRank); if( pAux==0 ){ assert( pTab->p.base.zErrMsg==0 ); - pTab->p.base.zErrMsg = tdsqlite3_mprintf("no such function: %s", zRank); + pTab->p.base.zErrMsg = sqlite3_mprintf("no such function: %s", zRank); rc = SQLITE_ERROR; } } @@ -225684,25 +225684,25 @@ static int fts5FindRankFunction(Fts5Cursor *pCsr){ static int fts5CursorParseRank( Fts5Config *pConfig, Fts5Cursor *pCsr, - tdsqlite3_value *pRank + sqlite3_value *pRank ){ int rc = SQLITE_OK; if( pRank ){ - const char *z = (const char*)tdsqlite3_value_text(pRank); + const char *z = (const char*)sqlite3_value_text(pRank); char *zRank = 0; char *zRankArgs = 0; if( z==0 ){ - if( tdsqlite3_value_type(pRank)==SQLITE_NULL ) rc = SQLITE_ERROR; + if( sqlite3_value_type(pRank)==SQLITE_NULL ) rc = SQLITE_ERROR; }else{ - rc = tdsqlite3Fts5ConfigParseRank(z, &zRank, &zRankArgs); + rc = sqlite3Fts5ConfigParseRank(z, &zRank, &zRankArgs); } if( rc==SQLITE_OK ){ pCsr->zRank = zRank; pCsr->zRankArgs = zRankArgs; CsrFlagSet(pCsr, FTS5CSR_FREE_ZRANK); }else if( rc==SQLITE_ERROR ){ - pCsr->base.pVtab->zErrMsg = tdsqlite3_mprintf( + pCsr->base.pVtab->zErrMsg = sqlite3_mprintf( "parse error in rank function: %s", z ); } @@ -225718,11 +225718,11 @@ static int fts5CursorParseRank( return rc; } -static i64 fts5GetRowidLimit(tdsqlite3_value *pVal, i64 iDefault){ +static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){ if( pVal ){ - int eType = tdsqlite3_value_numeric_type(pVal); + int eType = sqlite3_value_numeric_type(pVal); if( eType==SQLITE_INTEGER ){ - return tdsqlite3_value_int64(pVal); + return sqlite3_value_int64(pVal); } } return iDefault; @@ -225740,11 +225740,11 @@ static i64 fts5GetRowidLimit(tdsqlite3_value *pVal, i64 iDefault){ ** 3. A full-table scan. */ static int fts5FilterMethod( - tdsqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ int idxNum, /* Strategy index */ const char *idxStr, /* Unused */ int nVal, /* Number of elements in apVal */ - tdsqlite3_value **apVal /* Arguments for the indexing scheme */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab); Fts5Config *pConfig = pTab->p.pConfig; @@ -225752,10 +225752,10 @@ static int fts5FilterMethod( int rc = SQLITE_OK; /* Error code */ int bDesc; /* True if ORDER BY [rank|rowid] DESC */ int bOrderByRank; /* True if ORDER BY rank */ - tdsqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */ - tdsqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */ - tdsqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */ - tdsqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ + sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */ + sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */ + sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */ + sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; int i; @@ -225763,7 +225763,7 @@ static int fts5FilterMethod( Fts5Expr *pExpr = 0; if( pConfig->bLock ){ - pTab->p.base.zErrMsg = tdsqlite3_mprintf( + pTab->p.base.zErrMsg = sqlite3_mprintf( "recursively defined fts5 content table" ); return SQLITE_ERROR; @@ -225792,7 +225792,7 @@ static int fts5FilterMethod( pRank = apVal[i]; break; case 'm': { - const char *zText = (const char*)tdsqlite3_value_text(apVal[i]); + const char *zText = (const char*)sqlite3_value_text(apVal[i]); if( zText==0 ) zText = ""; if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){ @@ -225813,9 +225813,9 @@ static int fts5FilterMethod( goto filter_out; }else{ char **pzErr = &pTab->p.base.zErrMsg; - rc = tdsqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr); + rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); + rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); pExpr = 0; } if( rc!=SQLITE_OK ) goto filter_out; @@ -225839,7 +225839,7 @@ static int fts5FilterMethod( /* Set the cursor upper and lower rowid limits. Only some strategies ** actually use them. This is ok, as the xBestIndex() method leaves the - ** tdsqlite3_index_constraint.omit flag clear for range constraints + ** sqlite3_index_constraint.omit flag clear for range constraints ** on the rowid field. */ if( pRowidEq ){ pRowidLe = pRowidGe = pRowidEq; @@ -225885,7 +225885,7 @@ static int fts5FilterMethod( } } }else if( pConfig->zContent==0 ){ - *pConfig->pzErrmsg = tdsqlite3_mprintf( + *pConfig->pzErrmsg = sqlite3_mprintf( "%s: table does not support scanning", pConfig->zName ); rc = SQLITE_ERROR; @@ -225893,22 +225893,22 @@ static int fts5FilterMethod( /* This is either a full-table scan (ePlan==FTS5_PLAN_SCAN) or a lookup ** by rowid (ePlan==FTS5_PLAN_ROWID). */ pCsr->ePlan = (pRowidEq ? FTS5_PLAN_ROWID : FTS5_PLAN_SCAN); - rc = tdsqlite3Fts5StorageStmt( + rc = sqlite3Fts5StorageStmt( pTab->pStorage, fts5StmtType(pCsr), &pCsr->pStmt, &pTab->p.base.zErrMsg ); if( rc==SQLITE_OK ){ if( pCsr->ePlan==FTS5_PLAN_ROWID ){ - tdsqlite3_bind_value(pCsr->pStmt, 1, pRowidEq); + sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq); }else{ - tdsqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid); - tdsqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid); + sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid); + sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid); } rc = fts5NextMethod(pCursor); } } filter_out: - tdsqlite3Fts5ExprFree(pExpr); + sqlite3Fts5ExprFree(pExpr); pConfig->pzErrmsg = pzErrmsg; return rc; } @@ -225917,7 +225917,7 @@ static int fts5FilterMethod( ** This is the xEof method of the virtual table. SQLite calls this ** routine to find out if it has reached the end of a result set. */ -static int fts5EofMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts5EofMethod(sqlite3_vtab_cursor *pCursor){ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; return (CsrFlagTest(pCsr, FTS5CSR_EOF) ? 1 : 0); } @@ -225933,7 +225933,7 @@ static i64 fts5CursorRowid(Fts5Cursor *pCsr){ if( pCsr->pSorter ){ return pCsr->pSorter->iRowid; }else{ - return tdsqlite3Fts5ExprRowid(pCsr->pExpr); + return sqlite3Fts5ExprRowid(pCsr->pExpr); } } @@ -225943,7 +225943,7 @@ static i64 fts5CursorRowid(Fts5Cursor *pCsr){ ** exposes %_content.rowid as the rowid for the virtual table. The ** rowid should be written to *pRowid. */ -static int fts5RowidMethod(tdsqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ +static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){ Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int ePlan = pCsr->ePlan; @@ -225960,7 +225960,7 @@ static int fts5RowidMethod(tdsqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid) break; default: - *pRowid = tdsqlite3_column_int64(pCsr->pStmt, 0); + *pRowid = sqlite3_column_int64(pCsr->pStmt, 0); break; } @@ -225972,7 +225972,7 @@ static int fts5RowidMethod(tdsqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid) ** Return SQLITE_OK if no error occurs, or an SQLite error code otherwise. ** ** If argument bErrormsg is true and an error occurs, an error message may -** be left in tdsqlite3_vtab.zErrMsg. +** be left in sqlite3_vtab.zErrMsg. */ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ int rc = SQLITE_OK; @@ -225981,7 +225981,7 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ if( pCsr->pStmt==0 ){ Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); int eStmt = fts5StmtType(pCsr); - rc = tdsqlite3Fts5StorageStmt( + rc = sqlite3Fts5StorageStmt( pTab->pStorage, eStmt, &pCsr->pStmt, (bErrormsg?&pTab->p.base.zErrMsg:0) ); assert( rc!=SQLITE_OK || pTab->p.base.zErrMsg==0 ); @@ -225991,21 +225991,21 @@ static int fts5SeekCursor(Fts5Cursor *pCsr, int bErrormsg){ if( rc==SQLITE_OK && CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){ Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); assert( pCsr->pExpr ); - tdsqlite3_reset(pCsr->pStmt); - tdsqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr)); + sqlite3_reset(pCsr->pStmt); + sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr)); pTab->pConfig->bLock++; - rc = tdsqlite3_step(pCsr->pStmt); + rc = sqlite3_step(pCsr->pStmt); pTab->pConfig->bLock--; if( rc==SQLITE_ROW ){ rc = SQLITE_OK; CsrFlagClear(pCsr, FTS5CSR_REQUIRE_CONTENT); }else{ - rc = tdsqlite3_reset(pCsr->pStmt); + rc = sqlite3_reset(pCsr->pStmt); if( rc==SQLITE_OK ){ rc = FTS5_CORRUPT; }else if( pTab->pConfig->pzErrmsg ){ - *pTab->pConfig->pzErrmsg = tdsqlite3_mprintf( - "%s", tdsqlite3_errmsg(pTab->pConfig->db) + *pTab->pConfig->pzErrmsg = sqlite3_mprintf( + "%s", sqlite3_errmsg(pTab->pConfig->db) ); } } @@ -226017,7 +226017,7 @@ static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ va_list ap; /* ... printf arguments */ va_start(ap, zFormat); assert( p->p.base.zErrMsg==0 ); - p->p.base.zErrMsg = tdsqlite3_vmprintf(zFormat, ap); + p->p.base.zErrMsg = sqlite3_vmprintf(zFormat, ap); va_end(ap); } @@ -226039,13 +226039,13 @@ static void fts5SetVtabError(Fts5FullTable *p, const char *zFormat, ...){ static int fts5SpecialInsert( Fts5FullTable *pTab, /* Fts5 table object */ const char *zCmd, /* Text inserted into table-name column */ - tdsqlite3_value *pVal /* Value inserted into rank column */ + sqlite3_value *pVal /* Value inserted into rank column */ ){ Fts5Config *pConfig = pTab->p.pConfig; int rc = SQLITE_OK; int bError = 0; - if( 0==tdsqlite3_stricmp("delete-all", zCmd) ){ + if( 0==sqlite3_stricmp("delete-all", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ fts5SetVtabError(pTab, "'delete-all' may only be used with a " @@ -226053,38 +226053,38 @@ static int fts5SpecialInsert( ); rc = SQLITE_ERROR; }else{ - rc = tdsqlite3Fts5StorageDeleteAll(pTab->pStorage); + rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage); } - }else if( 0==tdsqlite3_stricmp("rebuild", zCmd) ){ + }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NONE ){ fts5SetVtabError(pTab, "'rebuild' may not be used with a contentless fts5 table" ); rc = SQLITE_ERROR; }else{ - rc = tdsqlite3Fts5StorageRebuild(pTab->pStorage); + rc = sqlite3Fts5StorageRebuild(pTab->pStorage); } - }else if( 0==tdsqlite3_stricmp("optimize", zCmd) ){ - rc = tdsqlite3Fts5StorageOptimize(pTab->pStorage); - }else if( 0==tdsqlite3_stricmp("merge", zCmd) ){ - int nMerge = tdsqlite3_value_int(pVal); - rc = tdsqlite3Fts5StorageMerge(pTab->pStorage, nMerge); - }else if( 0==tdsqlite3_stricmp("integrity-check", zCmd) ){ - rc = tdsqlite3Fts5StorageIntegrity(pTab->pStorage); + }else if( 0==sqlite3_stricmp("optimize", zCmd) ){ + rc = sqlite3Fts5StorageOptimize(pTab->pStorage); + }else if( 0==sqlite3_stricmp("merge", zCmd) ){ + int nMerge = sqlite3_value_int(pVal); + rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge); + }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){ + rc = sqlite3Fts5StorageIntegrity(pTab->pStorage); #ifdef SQLITE_DEBUG - }else if( 0==tdsqlite3_stricmp("prefix-index", zCmd) ){ - pConfig->bPrefixIndex = tdsqlite3_value_int(pVal); + }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){ + pConfig->bPrefixIndex = sqlite3_value_int(pVal); #endif }else{ - rc = tdsqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError); + rc = sqlite3Fts5ConfigSetValue(pTab->p.pConfig, zCmd, pVal, &bError); } if( rc==SQLITE_OK ){ if( bError ){ rc = SQLITE_ERROR; }else{ - rc = tdsqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0); + rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0); } } } @@ -226093,13 +226093,13 @@ static int fts5SpecialInsert( static int fts5SpecialDelete( Fts5FullTable *pTab, - tdsqlite3_value **apVal + sqlite3_value **apVal ){ int rc = SQLITE_OK; - int eType1 = tdsqlite3_value_type(apVal[1]); + int eType1 = sqlite3_value_type(apVal[1]); if( eType1==SQLITE_INTEGER ){ - tdsqlite3_int64 iDel = tdsqlite3_value_int64(apVal[1]); - rc = tdsqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]); + sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]); } return rc; } @@ -226107,15 +226107,15 @@ static int fts5SpecialDelete( static void fts5StorageInsert( int *pRc, Fts5FullTable *pTab, - tdsqlite3_value **apVal, + sqlite3_value **apVal, i64 *piRowid ){ int rc = *pRc; if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid); + rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid); } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid); + rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid); } *pRc = rc; } @@ -226135,9 +226135,9 @@ static void fts5StorageInsert( ** 4. Values for the two hidden columns ( and "rank"). */ static int fts5UpdateMethod( - tdsqlite3_vtab *pVtab, /* Virtual table handle */ + sqlite3_vtab *pVtab, /* Virtual table handle */ int nArg, /* Size of argument array */ - tdsqlite3_value **apVal, /* Array of arguments */ + sqlite3_value **apVal, /* Array of arguments */ sqlite_int64 *pRowid /* OUT: The affected (or effected) rowid */ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; @@ -226150,8 +226150,8 @@ static int fts5UpdateMethod( assert( pVtab->zErrMsg==0 ); assert( nArg==1 || nArg==(2+pConfig->nCol+2) ); - assert( tdsqlite3_value_type(apVal[0])==SQLITE_INTEGER - || tdsqlite3_value_type(apVal[0])==SQLITE_NULL + assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER + || sqlite3_value_type(apVal[0])==SQLITE_NULL ); assert( pTab->p.pConfig->pzErrmsg==0 ); pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; @@ -226159,14 +226159,14 @@ static int fts5UpdateMethod( /* Put any active cursors into REQUIRE_SEEK state. */ fts5TripCursors(pTab); - eType0 = tdsqlite3_value_type(apVal[0]); + eType0 = sqlite3_value_type(apVal[0]); if( eType0==SQLITE_NULL - && tdsqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL + && sqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL ){ /* A "special" INSERT op. These are handled separately. */ - const char *z = (const char*)tdsqlite3_value_text(apVal[2+pConfig->nCol]); + const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]); if( pConfig->eContent!=FTS5_CONTENT_NORMAL - && 0==tdsqlite3_stricmp("delete", z) + && 0==sqlite3_stricmp("delete", z) ){ rc = fts5SpecialDelete(pTab, apVal); }else{ @@ -226186,7 +226186,7 @@ static int fts5UpdateMethod( */ int eConflict = SQLITE_ABORT; if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ - eConflict = tdsqlite3_vtab_on_conflict(pConfig->db); + eConflict = sqlite3_vtab_on_conflict(pConfig->db); } assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL ); @@ -226195,7 +226195,7 @@ static int fts5UpdateMethod( /* Filter out attempts to run UPDATE or DELETE on contentless tables. ** This is not suported. */ if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){ - pTab->p.base.zErrMsg = tdsqlite3_mprintf( + pTab->p.base.zErrMsg = sqlite3_mprintf( "cannot %s contentless fts5 table: %s", (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName ); @@ -226204,13 +226204,13 @@ static int fts5UpdateMethod( /* DELETE */ else if( nArg==1 ){ - i64 iDel = tdsqlite3_value_int64(apVal[0]); /* Rowid to delete */ - rc = tdsqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); + i64 iDel = sqlite3_value_int64(apVal[0]); /* Rowid to delete */ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, 0); } /* INSERT or UPDATE */ else{ - int eType1 = tdsqlite3_value_numeric_type(apVal[1]); + int eType1 = sqlite3_value_numeric_type(apVal[1]); if( eType1!=SQLITE_INTEGER && eType1!=SQLITE_NULL ){ rc = SQLITE_MISMATCH; @@ -226219,34 +226219,34 @@ static int fts5UpdateMethod( else if( eType0!=SQLITE_INTEGER ){ /* If this is a REPLACE, first remove the current entry (if any) */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ - i64 iNew = tdsqlite3_value_int64(apVal[1]); /* Rowid to delete */ - rc = tdsqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); + i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); } /* UPDATE */ else{ - i64 iOld = tdsqlite3_value_int64(apVal[0]); /* Old rowid */ - i64 iNew = tdsqlite3_value_int64(apVal[1]); /* New rowid */ + i64 iOld = sqlite3_value_int64(apVal[0]); /* Old rowid */ + i64 iNew = sqlite3_value_int64(apVal[1]); /* New rowid */ if( eType1==SQLITE_INTEGER && iOld!=iNew ){ if( eConflict==SQLITE_REPLACE ){ - rc = tdsqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); } fts5StorageInsert(&rc, pTab, apVal, pRowid); }else{ - rc = tdsqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); + rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid); + rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal,*pRowid); } } }else{ - rc = tdsqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); + rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld, 0); fts5StorageInsert(&rc, pTab, apVal, pRowid); } } @@ -226260,13 +226260,13 @@ static int fts5UpdateMethod( /* ** Implementation of xSync() method. */ -static int fts5SyncMethod(tdsqlite3_vtab *pVtab){ +static int fts5SyncMethod(sqlite3_vtab *pVtab){ int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_SYNC, 0); pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; fts5TripCursors(pTab); - rc = tdsqlite3Fts5StorageSync(pTab->pStorage); + rc = sqlite3Fts5StorageSync(pTab->pStorage); pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -226274,7 +226274,7 @@ static int fts5SyncMethod(tdsqlite3_vtab *pVtab){ /* ** Implementation of xBegin() method. */ -static int fts5BeginMethod(tdsqlite3_vtab *pVtab){ +static int fts5BeginMethod(sqlite3_vtab *pVtab){ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_BEGIN, 0); fts5NewTransaction((Fts5FullTable*)pVtab); return SQLITE_OK; @@ -226285,7 +226285,7 @@ static int fts5BeginMethod(tdsqlite3_vtab *pVtab){ ** the pending-terms hash-table have already been flushed into the database ** by fts5SyncMethod(). */ -static int fts5CommitMethod(tdsqlite3_vtab *pVtab){ +static int fts5CommitMethod(sqlite3_vtab *pVtab){ UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_COMMIT, 0); return SQLITE_OK; @@ -226295,11 +226295,11 @@ static int fts5CommitMethod(tdsqlite3_vtab *pVtab){ ** Implementation of xRollback(). Discard the contents of the pending-terms ** hash-table. Any changes made to the database are reverted by SQLite. */ -static int fts5RollbackMethod(tdsqlite3_vtab *pVtab){ +static int fts5RollbackMethod(sqlite3_vtab *pVtab){ int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_ROLLBACK, 0); - rc = tdsqlite3Fts5StorageRollback(pTab->pStorage); + rc = sqlite3Fts5StorageRollback(pTab->pStorage); return rc; } @@ -226318,17 +226318,17 @@ static int fts5ApiColumnCount(Fts5Context *pCtx){ static int fts5ApiColumnTotalSize( Fts5Context *pCtx, int iCol, - tdsqlite3_int64 *pnToken + sqlite3_int64 *pnToken ){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); - return tdsqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken); + return sqlite3Fts5StorageSize(pTab->pStorage, iCol, pnToken); } static int fts5ApiRowCount(Fts5Context *pCtx, i64 *pnRow){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5FullTable *pTab = (Fts5FullTable*)(pCsr->base.pVtab); - return tdsqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); + return sqlite3Fts5StorageRowCount(pTab->pStorage, pnRow); } static int fts5ApiTokenize( @@ -226339,19 +226339,19 @@ static int fts5ApiTokenize( ){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab); - return tdsqlite3Fts5Tokenize( + return sqlite3Fts5Tokenize( pTab->pConfig, FTS5_TOKENIZE_AUX, pText, nText, pUserData, xToken ); } static int fts5ApiPhraseCount(Fts5Context *pCtx){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - return tdsqlite3Fts5ExprPhraseCount(pCsr->pExpr); + return sqlite3Fts5ExprPhraseCount(pCsr->pExpr); } static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){ Fts5Cursor *pCsr = (Fts5Cursor*)pCtx; - return tdsqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase); + return sqlite3Fts5ExprPhraseSize(pCsr->pExpr, iPhrase); } static int fts5ApiColumnText( @@ -226370,8 +226370,8 @@ static int fts5ApiColumnText( }else{ rc = fts5SeekCursor(pCsr, 0); if( rc==SQLITE_OK ){ - *pz = (const char*)tdsqlite3_column_text(pCsr->pStmt, iCol+1); - *pn = tdsqlite3_column_bytes(pCsr->pStmt, iCol+1); + *pz = (const char*)sqlite3_column_text(pCsr->pStmt, iCol+1); + *pn = sqlite3_column_bytes(pCsr->pStmt, iCol+1); } } return rc; @@ -226392,21 +226392,21 @@ static int fts5CsrPoslist( if( pConfig->eDetail!=FTS5_DETAIL_FULL ){ Fts5PoslistPopulator *aPopulator; int i; - aPopulator = tdsqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive); + aPopulator = sqlite3Fts5ExprClearPoslists(pCsr->pExpr, bLive); if( aPopulator==0 ) rc = SQLITE_NOMEM; for(i=0; inCol && rc==SQLITE_OK; i++){ int n; const char *z; rc = fts5ApiColumnText((Fts5Context*)pCsr, i, &z, &n); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5ExprPopulatePoslists( + rc = sqlite3Fts5ExprPopulatePoslists( pConfig, pCsr->pExpr, aPopulator, i, z, n ); } } - tdsqlite3_free(aPopulator); + sqlite3_free(aPopulator); if( pCsr->pSorter ){ - tdsqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid); + sqlite3Fts5ExprCheckPoslists(pCsr->pExpr, pCsr->pSorter->iRowid); } } CsrFlagClear(pCsr, FTS5CSR_REQUIRE_POSLIST); @@ -226418,7 +226418,7 @@ static int fts5CsrPoslist( *pn = pSorter->aIdx[iPhrase] - i1; *pa = &pSorter->aPoslist[i1]; }else{ - *pn = tdsqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); + *pn = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, pa); } return rc; @@ -226435,10 +226435,10 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ int nIter; /* Number of iterators/phrases */ int nCol = ((Fts5Table*)pCsr->base.pVtab)->pConfig->nCol; - nIter = tdsqlite3Fts5ExprPhraseCount(pCsr->pExpr); + nIter = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); if( pCsr->aInstIter==0 ){ - tdsqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nIter; - pCsr->aInstIter = (Fts5PoslistReader*)tdsqlite3Fts5MallocZero(&rc, nByte); + sqlite3_int64 nByte = sizeof(Fts5PoslistReader) * nIter; + pCsr->aInstIter = (Fts5PoslistReader*)sqlite3Fts5MallocZero(&rc, nByte); } aIter = pCsr->aInstIter; @@ -226452,7 +226452,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ int n; rc = fts5CsrPoslist(pCsr, i, &a, &n); if( rc==SQLITE_OK ){ - tdsqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); + sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]); } } @@ -226472,7 +226472,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ nInst++; if( nInst>=pCsr->nInstAlloc ){ pCsr->nInstAlloc = pCsr->nInstAlloc ? pCsr->nInstAlloc*2 : 32; - aInst = (int*)tdsqlite3_realloc64( + aInst = (int*)sqlite3_realloc64( pCsr->aInst, pCsr->nInstAlloc*sizeof(int)*3 ); if( aInst ){ @@ -226491,7 +226491,7 @@ static int fts5CacheInstArray(Fts5Cursor *pCsr){ rc = FTS5_CORRUPT; break; } - tdsqlite3Fts5PoslistReaderNext(&aIter[iBest]); + sqlite3Fts5PoslistReaderNext(&aIter[iBest]); } } @@ -226540,7 +226540,7 @@ static int fts5ApiInst( return rc; } -static tdsqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){ +static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){ return fts5CursorRowid((Fts5Cursor*)pCtx); } @@ -226570,7 +226570,7 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){ if( pConfig->bColumnsize ){ i64 iRowid = fts5CursorRowid(pCsr); - rc = tdsqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize); + rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize); }else if( pConfig->zContent==0 ){ int i; for(i=0; inCol; i++){ @@ -226587,7 +226587,7 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){ pCsr->aColumnSize[i] = 0; rc = fts5ApiColumnText(pCtx, i, &z, &n); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5Tokenize( + rc = sqlite3Fts5Tokenize( pConfig, FTS5_TOKENIZE_AUX, z, n, p, fts5ColumnSizeCb ); } @@ -226634,7 +226634,7 @@ static int fts5ApiSetAuxdata( } }else{ int rc = SQLITE_OK; - pData = (Fts5Auxdata*)tdsqlite3Fts5MallocZero(&rc, sizeof(Fts5Auxdata)); + pData = (Fts5Auxdata*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Auxdata)); if( pData==0 ){ if( xDelete ) xDelete(pPtr); return rc; @@ -226757,7 +226757,7 @@ static int fts5ApiPhraseFirstColumn( n = pSorter->aIdx[iPhrase] - i1; pIter->a = &pSorter->aPoslist[i1]; }else{ - rc = tdsqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); + rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, iPhrase, &pIter->a, &n); } if( rc==SQLITE_OK ){ pIter->b = &pIter->a[n]; @@ -226824,19 +226824,19 @@ static int fts5ApiQueryPhrase( int rc; Fts5Cursor *pNew = 0; - rc = fts5OpenMethod(pCsr->base.pVtab, (tdsqlite3_vtab_cursor**)&pNew); + rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew); if( rc==SQLITE_OK ){ pNew->ePlan = FTS5_PLAN_MATCH; pNew->iFirstRowid = SMALLEST_INT64; pNew->iLastRowid = LARGEST_INT64; - pNew->base.pVtab = (tdsqlite3_vtab*)pTab; - rc = tdsqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr); + pNew->base.pVtab = (sqlite3_vtab*)pTab; + rc = sqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr); } if( rc==SQLITE_OK ){ for(rc = fts5CursorFirst(pTab, pNew, 0); rc==SQLITE_OK && CsrFlagTest(pNew, FTS5CSR_EOF)==0; - rc = fts5NextMethod((tdsqlite3_vtab_cursor*)pNew) + rc = fts5NextMethod((sqlite3_vtab_cursor*)pNew) ){ rc = xCallback(&sFts5Api, (Fts5Context*)pNew, pUserData); if( rc!=SQLITE_OK ){ @@ -226846,16 +226846,16 @@ static int fts5ApiQueryPhrase( } } - fts5CloseMethod((tdsqlite3_vtab_cursor*)pNew); + fts5CloseMethod((sqlite3_vtab_cursor*)pNew); return rc; } static void fts5ApiInvoke( Fts5Auxiliary *pAux, Fts5Cursor *pCsr, - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ assert( pCsr->pAux==0 ); pCsr->pAux = pAux; @@ -226872,9 +226872,9 @@ static Fts5Cursor *fts5CursorFromCsrid(Fts5Global *pGlobal, i64 iCsrId){ } static void fts5ApiCallback( - tdsqlite3_context *context, + sqlite3_context *context, int argc, - tdsqlite3_value **argv + sqlite3_value **argv ){ Fts5Auxiliary *pAux; @@ -226882,14 +226882,14 @@ static void fts5ApiCallback( i64 iCsrId; assert( argc>=1 ); - pAux = (Fts5Auxiliary*)tdsqlite3_user_data(context); - iCsrId = tdsqlite3_value_int64(argv[0]); + pAux = (Fts5Auxiliary*)sqlite3_user_data(context); + iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); if( pCsr==0 || pCsr->ePlan==0 ){ - char *zErr = tdsqlite3_mprintf("no such cursor: %lld", iCsrId); - tdsqlite3_result_error(context, zErr, -1); - tdsqlite3_free(zErr); + char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId); + sqlite3_result_error(context, zErr, -1); + sqlite3_free(zErr); }else{ fts5ApiInvoke(pAux, pCsr, context, argc-1, &argv[1]); } @@ -226900,7 +226900,7 @@ static void fts5ApiCallback( ** Given cursor id iId, return a pointer to the corresponding Fts5Table ** object. Or NULL If the cursor id does not exist. */ -static Fts5Table *tdsqlite3Fts5TableFromCsrid( +static Fts5Table *sqlite3Fts5TableFromCsrid( Fts5Global *pGlobal, /* FTS5 global context for db handle */ i64 iCsrId /* Id of cursor to find */ ){ @@ -226914,7 +226914,7 @@ static Fts5Table *tdsqlite3Fts5TableFromCsrid( /* ** Return a "position-list blob" corresponding to the current position of -** cursor pCsr via tdsqlite3_result_blob(). A position-list blob contains +** cursor pCsr via sqlite3_result_blob(). A position-list blob contains ** the current position-list for each phrase in the query associated with ** cursor pCsr. ** @@ -226927,10 +226927,10 @@ static Fts5Table *tdsqlite3Fts5TableFromCsrid( ** list 1. And so on. There is no size field for the final position list, ** as it can be derived from the total size of the blob. */ -static int fts5PoslistBlob(tdsqlite3_context *pCtx, Fts5Cursor *pCsr){ +static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){ int i; int rc = SQLITE_OK; - int nPhrase = tdsqlite3Fts5ExprPhraseCount(pCsr->pExpr); + int nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr); Fts5Buffer val; memset(&val, 0, sizeof(Fts5Buffer)); @@ -226940,16 +226940,16 @@ static int fts5PoslistBlob(tdsqlite3_context *pCtx, Fts5Cursor *pCsr){ /* Append the varints */ for(i=0; i<(nPhrase-1); i++){ const u8 *dummy; - int nByte = tdsqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy); - tdsqlite3Fts5BufferAppendVarint(&rc, &val, nByte); + int nByte = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy); + sqlite3Fts5BufferAppendVarint(&rc, &val, nByte); } /* Append the position lists */ for(i=0; ipExpr, i, &pPoslist); - tdsqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist); + nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist); + sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist); } break; @@ -226959,16 +226959,16 @@ static int fts5PoslistBlob(tdsqlite3_context *pCtx, Fts5Cursor *pCsr){ for(i=0; rc==SQLITE_OK && i<(nPhrase-1); i++){ const u8 *dummy; int nByte; - rc = tdsqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &dummy, &nByte); - tdsqlite3Fts5BufferAppendVarint(&rc, &val, nByte); + rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &dummy, &nByte); + sqlite3Fts5BufferAppendVarint(&rc, &val, nByte); } /* Append the position lists */ for(i=0; rc==SQLITE_OK && ipExpr, i, &pPoslist, &nPoslist); - tdsqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist); + rc = sqlite3Fts5ExprPhraseCollist(pCsr->pExpr, i, &pPoslist, &nPoslist); + sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist); } break; @@ -226976,7 +226976,7 @@ static int fts5PoslistBlob(tdsqlite3_context *pCtx, Fts5Cursor *pCsr){ break; } - tdsqlite3_result_blob(pCtx, val.p, val.n, tdsqlite3_free); + sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free); return rc; } @@ -226985,8 +226985,8 @@ static int fts5PoslistBlob(tdsqlite3_context *pCtx, Fts5Cursor *pCsr){ ** the row that the supplied cursor currently points to. */ static int fts5ColumnMethod( - tdsqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - tdsqlite3_context *pCtx, /* Context for tdsqlite3_result_xxx() calls */ + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ int iCol /* Index of column to read value from */ ){ Fts5FullTable *pTab = (Fts5FullTable*)(pCursor->pVtab); @@ -226998,7 +226998,7 @@ static int fts5ColumnMethod( if( pCsr->ePlan==FTS5_PLAN_SPECIAL ){ if( iCol==pConfig->nCol ){ - tdsqlite3_result_int64(pCtx, pCsr->iSpecial); + sqlite3_result_int64(pCtx, pCsr->iSpecial); } }else @@ -227007,7 +227007,7 @@ static int fts5ColumnMethod( ** as the table. Return the cursor integer id number. This value is only ** useful in that it may be passed as the first argument to an FTS5 ** auxiliary function. */ - tdsqlite3_result_int64(pCtx, pCsr->iCsrId); + sqlite3_result_int64(pCtx, pCsr->iCsrId); }else if( iCol==pConfig->nCol+1 ){ /* The value of the "rank" column. */ @@ -227025,7 +227025,7 @@ static int fts5ColumnMethod( pConfig->pzErrmsg = &pTab->p.base.zErrMsg; rc = fts5SeekCursor(pCsr, 1); if( rc==SQLITE_OK ){ - tdsqlite3_result_value(pCtx, tdsqlite3_column_value(pCsr->pStmt, iCol+1)); + sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); } pConfig->pzErrmsg = 0; } @@ -227038,10 +227038,10 @@ static int fts5ColumnMethod( ** virtual table. */ static int fts5FindFunctionMethod( - tdsqlite3_vtab *pVtab, /* Virtual table handle */ + sqlite3_vtab *pVtab, /* Virtual table handle */ int nUnused, /* Number of SQL function arguments */ const char *zName, /* Name of SQL function */ - void (**pxFunc)(tdsqlite3_context*,int,tdsqlite3_value**), /* OUT: Result */ + void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */ void **ppArg /* OUT: User data for *pxFunc */ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; @@ -227063,16 +227063,16 @@ static int fts5FindFunctionMethod( ** Implementation of FTS5 xRename method. Rename an fts5 table. */ static int fts5RenameMethod( - tdsqlite3_vtab *pVtab, /* Virtual table handle */ + sqlite3_vtab *pVtab, /* Virtual table handle */ const char *zName /* New name of table */ ){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - return tdsqlite3Fts5StorageRename(pTab->pStorage, zName); + return sqlite3Fts5StorageRename(pTab->pStorage, zName); } -static int tdsqlite3Fts5FlushToDisk(Fts5Table *pTab){ +static int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ fts5TripCursors((Fts5FullTable*)pTab); - return tdsqlite3Fts5StorageSync(((Fts5FullTable*)pTab)->pStorage); + return sqlite3Fts5StorageSync(((Fts5FullTable*)pTab)->pStorage); } /* @@ -227080,10 +227080,10 @@ static int tdsqlite3Fts5FlushToDisk(Fts5Table *pTab){ ** ** Flush the contents of the pending-terms table to disk. */ -static int fts5SavepointMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ +static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint); - return tdsqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); } /* @@ -227091,10 +227091,10 @@ static int fts5SavepointMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ ** ** This is a no-op. */ -static int fts5ReleaseMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ +static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint); - return tdsqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); } /* @@ -227102,12 +227102,12 @@ static int fts5ReleaseMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ ** ** Discard the contents of the pending terms table. */ -static int fts5RollbackToMethod(tdsqlite3_vtab *pVtab, int iSavepoint){ +static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); - return tdsqlite3Fts5StorageRollback(pTab->pStorage); + return sqlite3Fts5StorageRollback(pTab->pStorage); } /* @@ -227121,15 +227121,15 @@ static int fts5CreateAux( void(*xDestroy)(void*) /* Destructor for pUserData */ ){ Fts5Global *pGlobal = (Fts5Global*)pApi; - int rc = tdsqlite3_overload_function(pGlobal->db, zName, -1); + int rc = sqlite3_overload_function(pGlobal->db, zName, -1); if( rc==SQLITE_OK ){ Fts5Auxiliary *pAux; - tdsqlite3_int64 nName; /* Size of zName in bytes, including \0 */ - tdsqlite3_int64 nByte; /* Bytes of space to allocate */ + sqlite3_int64 nName; /* Size of zName in bytes, including \0 */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ nName = strlen(zName) + 1; nByte = sizeof(Fts5Auxiliary) + nName; - pAux = (Fts5Auxiliary*)tdsqlite3_malloc64(nByte); + pAux = (Fts5Auxiliary*)sqlite3_malloc64(nByte); if( pAux ){ memset(pAux, 0, (size_t)nByte); pAux->zFunc = (char*)&pAux[1]; @@ -227161,13 +227161,13 @@ static int fts5CreateTokenizer( ){ Fts5Global *pGlobal = (Fts5Global*)pApi; Fts5TokenizerModule *pNew; - tdsqlite3_int64 nName; /* Size of zName and its \0 terminator */ - tdsqlite3_int64 nByte; /* Bytes of space to allocate */ + sqlite3_int64 nName; /* Size of zName and its \0 terminator */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ int rc = SQLITE_OK; nName = strlen(zName) + 1; nByte = sizeof(Fts5TokenizerModule) + nName; - pNew = (Fts5TokenizerModule*)tdsqlite3_malloc64(nByte); + pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte); if( pNew ){ memset(pNew, 0, (size_t)nByte); pNew->zName = (char*)&pNew[1]; @@ -227197,7 +227197,7 @@ static Fts5TokenizerModule *fts5LocateTokenizer( pMod = pGlobal->pDfltTok; }else{ for(pMod=pGlobal->pTok; pMod; pMod=pMod->pNext){ - if( tdsqlite3_stricmp(zName, pMod->zName)==0 ) break; + if( sqlite3_stricmp(zName, pMod->zName)==0 ) break; } } @@ -227229,7 +227229,7 @@ static int fts5FindTokenizer( return rc; } -static int tdsqlite3Fts5GetTokenizer( +static int sqlite3Fts5GetTokenizer( Fts5Global *pGlobal, const char **azArg, int nArg, @@ -227244,12 +227244,12 @@ static int tdsqlite3Fts5GetTokenizer( if( pMod==0 ){ assert( nArg>0 ); rc = SQLITE_ERROR; - *pzErr = tdsqlite3_mprintf("no such tokenizer: %s", azArg[0]); + *pzErr = sqlite3_mprintf("no such tokenizer: %s", azArg[0]); }else{ rc = pMod->x.xCreate(pMod->pUserData, &azArg[1], (nArg?nArg-1:0), ppTok); *ppTokApi = &pMod->x; if( rc!=SQLITE_OK && pzErr ){ - *pzErr = tdsqlite3_mprintf("error in tokenizer constructor"); + *pzErr = sqlite3_mprintf("error in tokenizer constructor"); } } @@ -227269,28 +227269,28 @@ static void fts5ModuleDestroy(void *pCtx){ for(pAux=pGlobal->pAux; pAux; pAux=pNextAux){ pNextAux = pAux->pNext; if( pAux->xDestroy ) pAux->xDestroy(pAux->pUserData); - tdsqlite3_free(pAux); + sqlite3_free(pAux); } for(pTok=pGlobal->pTok; pTok; pTok=pNextTok){ pNextTok = pTok->pNext; if( pTok->xDestroy ) pTok->xDestroy(pTok->pUserData); - tdsqlite3_free(pTok); + sqlite3_free(pTok); } - tdsqlite3_free(pGlobal); + sqlite3_free(pGlobal); } static void fts5Fts5Func( - tdsqlite3_context *pCtx, /* Function call context */ + sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ - tdsqlite3_value **apArg /* Function arguments */ + sqlite3_value **apArg /* Function arguments */ ){ - Fts5Global *pGlobal = (Fts5Global*)tdsqlite3_user_data(pCtx); + Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx); fts5_api **ppApi; UNUSED_PARAM(nArg); assert( nArg==1 ); - ppApi = (fts5_api**)tdsqlite3_value_pointer(apArg[0], "fts5_api_ptr"); + ppApi = (fts5_api**)sqlite3_value_pointer(apArg[0], "fts5_api_ptr"); if( ppApi ) *ppApi = &pGlobal->api; } @@ -227298,13 +227298,13 @@ static void fts5Fts5Func( ** Implementation of fts5_source_id() function. */ static void fts5SourceIdFunc( - tdsqlite3_context *pCtx, /* Function call context */ + sqlite3_context *pCtx, /* Function call context */ int nArg, /* Number of args */ - tdsqlite3_value **apUnused /* Function arguments */ + sqlite3_value **apUnused /* Function arguments */ ){ assert( nArg==0 ); UNUSED_PARAM2(nArg, apUnused); - tdsqlite3_result_text(pCtx, "fts5: 2020-01-22 18:38:59 f6affdd41608946fcfcea914ece149038a8b25a62bbe719ed2561c649b86d824", -1, SQLITE_TRANSIENT); + sqlite3_result_text(pCtx, "fts5: 2020-01-22 18:38:59 f6affdd41608946fcfcea914ece149038a8b25a62bbe719ed2561c649b86d824", -1, SQLITE_TRANSIENT); } /* @@ -227317,13 +227317,13 @@ static int fts5ShadowName(const char *zName){ }; unsigned int i; for(i=0; iapi.xCreateFunction = fts5CreateAux; pGlobal->api.xCreateTokenizer = fts5CreateTokenizer; pGlobal->api.xFindTokenizer = fts5FindTokenizer; - rc = tdsqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy); - if( rc==SQLITE_OK ) rc = tdsqlite3Fts5IndexInit(db); - if( rc==SQLITE_OK ) rc = tdsqlite3Fts5ExprInit(pGlobal, db); - if( rc==SQLITE_OK ) rc = tdsqlite3Fts5AuxInit(&pGlobal->api); - if( rc==SQLITE_OK ) rc = tdsqlite3Fts5TokenizerInit(&pGlobal->api); - if( rc==SQLITE_OK ) rc = tdsqlite3Fts5VocabInit(pGlobal, db); + rc = sqlite3_create_module_v2(db, "fts5", &fts5Mod, p, fts5ModuleDestroy); + if( rc==SQLITE_OK ) rc = sqlite3Fts5IndexInit(db); + if( rc==SQLITE_OK ) rc = sqlite3Fts5ExprInit(pGlobal, db); + if( rc==SQLITE_OK ) rc = sqlite3Fts5AuxInit(&pGlobal->api); + if( rc==SQLITE_OK ) rc = sqlite3Fts5TokenizerInit(&pGlobal->api); + if( rc==SQLITE_OK ) rc = sqlite3Fts5VocabInit(pGlobal, db); if( rc==SQLITE_OK ){ - rc = tdsqlite3_create_function( + rc = sqlite3_create_function( db, "fts5", 1, SQLITE_UTF8, p, fts5Fts5Func, 0, 0 ); } if( rc==SQLITE_OK ){ - rc = tdsqlite3_create_function( + rc = sqlite3_create_function( db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0 ); } @@ -227387,8 +227387,8 @@ static int fts5Init(tdsqlite3 *db){ ** its entry point to enable the matchinfo() demo. */ #ifdef SQLITE_FTS5_ENABLE_TEST_MI if( rc==SQLITE_OK ){ - extern int tdsqlite3Fts5TestRegisterMatchinfo(tdsqlite3*); - rc = tdsqlite3Fts5TestRegisterMatchinfo(db); + extern int sqlite3Fts5TestRegisterMatchinfo(sqlite3*); + rc = sqlite3Fts5TestRegisterMatchinfo(db); } #endif @@ -227398,20 +227398,20 @@ static int fts5Init(tdsqlite3 *db){ /* ** The following functions are used to register the module with SQLite. If ** this module is being built as part of the SQLite core (SQLITE_CORE is -** defined), then tdsqlite3_open() will call tdsqlite3Fts5Init() directly. +** defined), then sqlite3_open() will call sqlite3Fts5Init() directly. ** ** Or, if this module is being built as a loadable extension, -** tdsqlite3Fts5Init() is omitted and the two standard entry points -** tdsqlite3_fts_init() and tdsqlite3_fts5_init() defined instead. +** sqlite3Fts5Init() is omitted and the two standard entry points +** sqlite3_fts_init() and sqlite3_fts5_init() defined instead. */ #ifndef SQLITE_CORE #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int tdsqlite3_fts_init( - tdsqlite3 *db, +SQLITE_API int sqlite3_fts_init( + sqlite3 *db, char **pzErrMsg, - const tdsqlite3_api_routines *pApi + const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ @@ -227421,17 +227421,17 @@ SQLITE_API int tdsqlite3_fts_init( #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int tdsqlite3_fts5_init( - tdsqlite3 *db, +SQLITE_API int sqlite3_fts5_init( + sqlite3 *db, char **pzErrMsg, - const tdsqlite3_api_routines *pApi + const sqlite3_api_routines *pApi ){ SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; /* Unused parameter */ return fts5Init(db); } #else -SQLITE_PRIVATE int tdsqlite3Fts5Init(tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3Fts5Init(sqlite3 *db){ return fts5Init(db); } #endif @@ -227460,7 +227460,7 @@ struct Fts5Storage { int bTotalsValid; /* True if nTotalRow/aTotalSize[] are valid */ i64 nTotalRow; /* Total number of rows in FTS table */ i64 *aTotalSize; /* Total sizes of each column */ - tdsqlite3_stmt *aStmt[11]; + sqlite3_stmt *aStmt[11]; }; @@ -227492,7 +227492,7 @@ struct Fts5Storage { static int fts5StorageGetStmt( Fts5Storage *p, /* Storage handle */ int eStmt, /* FTS5_STMT_XXX constant */ - tdsqlite3_stmt **ppStmt, /* OUT: Prepared statement handle */ + sqlite3_stmt **ppStmt, /* OUT: Prepared statement handle */ char **pzErrMsg /* OUT: Error message (if any) */ ){ int rc = SQLITE_OK; @@ -227528,21 +227528,21 @@ static int fts5StorageGetStmt( switch( eStmt ){ case FTS5_STMT_SCAN: - zSql = tdsqlite3_mprintf(azStmt[eStmt], + zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent ); break; case FTS5_STMT_SCAN_ASC: case FTS5_STMT_SCAN_DESC: - zSql = tdsqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, + zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid, pC->zContentRowid, pC->zContentRowid ); break; case FTS5_STMT_LOOKUP: - zSql = tdsqlite3_mprintf(azStmt[eStmt], + zSql = sqlite3_mprintf(azStmt[eStmt], pC->zContentExprlist, pC->zContent, pC->zContentRowid ); break; @@ -227553,21 +227553,21 @@ static int fts5StorageGetStmt( char *zBind; int i; - zBind = tdsqlite3_malloc64(1 + nCol*2); + zBind = sqlite3_malloc64(1 + nCol*2); if( zBind ){ for(i=0; izDb, pC->zName, zBind); - tdsqlite3_free(zBind); + zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, zBind); + sqlite3_free(zBind); } break; } default: - zSql = tdsqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName); + zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName); break; } @@ -227577,23 +227577,23 @@ static int fts5StorageGetStmt( int f = SQLITE_PREPARE_PERSISTENT; if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB; p->pConfig->bLock++; - rc = tdsqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); + rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0); p->pConfig->bLock--; - tdsqlite3_free(zSql); + sqlite3_free(zSql); if( rc!=SQLITE_OK && pzErrMsg ){ - *pzErrMsg = tdsqlite3_mprintf("%s", tdsqlite3_errmsg(pC->db)); + *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db)); } } } *ppStmt = p->aStmt[eStmt]; - tdsqlite3_reset(*ppStmt); + sqlite3_reset(*ppStmt); return rc; } static int fts5ExecPrintf( - tdsqlite3 *db, + sqlite3 *db, char **pzErr, const char *zFormat, ... @@ -227603,13 +227603,13 @@ static int fts5ExecPrintf( char *zSql; va_start(ap, zFormat); - zSql = tdsqlite3_vmprintf(zFormat, ap); + zSql = sqlite3_vmprintf(zFormat, ap); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ - rc = tdsqlite3_exec(db, zSql, 0, 0, pzErr); - tdsqlite3_free(zSql); + rc = sqlite3_exec(db, zSql, 0, 0, pzErr); + sqlite3_free(zSql); } va_end(ap); @@ -227620,7 +227620,7 @@ static int fts5ExecPrintf( ** Drop all shadow tables. Return SQLITE_OK if successful or an SQLite error ** code otherwise. */ -static int tdsqlite3Fts5DropAll(Fts5Config *pConfig){ +static int sqlite3Fts5DropAll(Fts5Config *pConfig){ int rc = fts5ExecPrintf(pConfig->db, 0, "DROP TABLE IF EXISTS %Q.'%q_data';" "DROP TABLE IF EXISTS %Q.'%q_idx';" @@ -227658,9 +227658,9 @@ static void fts5StorageRenameOne( } } -static int tdsqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){ +static int sqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){ Fts5Config *pConfig = pStorage->pConfig; - int rc = tdsqlite3Fts5StorageSync(pStorage); + int rc = sqlite3Fts5StorageSync(pStorage); fts5StorageRenameOne(pConfig, &rc, "data", zName); fts5StorageRenameOne(pConfig, &rc, "idx", zName); @@ -227678,7 +227678,7 @@ static int tdsqlite3Fts5StorageRename(Fts5Storage *pStorage, const char *zName){ ** Create the shadow table named zPost, with definition zDefn. Return ** SQLITE_OK if successful, or an SQLite error code otherwise. */ -static int tdsqlite3Fts5CreateTable( +static int sqlite3Fts5CreateTable( Fts5Config *pConfig, /* FTS5 configuration */ const char *zPost, /* Shadow table to create (e.g. "content") */ const char *zDefn, /* Columns etc. for shadow table */ @@ -227696,11 +227696,11 @@ static int tdsqlite3Fts5CreateTable( "" ); if( zErr ){ - *pzErr = tdsqlite3_mprintf( + *pzErr = sqlite3_mprintf( "fts5: error creating shadow table %q_%s: %s", pConfig->zName, zPost, zErr ); - tdsqlite3_free(zErr); + sqlite3_free(zErr); } return rc; @@ -227713,7 +227713,7 @@ static int tdsqlite3Fts5CreateTable( ** If successful, set *pp to point to the new object and return SQLITE_OK. ** Otherwise, set *pp to NULL and return an SQLite error code. */ -static int tdsqlite3Fts5StorageOpen( +static int sqlite3Fts5StorageOpen( Fts5Config *pConfig, Fts5Index *pIndex, int bCreate, @@ -227722,11 +227722,11 @@ static int tdsqlite3Fts5StorageOpen( ){ int rc = SQLITE_OK; Fts5Storage *p; /* New object */ - tdsqlite3_int64 nByte; /* Bytes of space to allocate */ + sqlite3_int64 nByte; /* Bytes of space to allocate */ nByte = sizeof(Fts5Storage) /* Fts5Storage object */ + pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */ - *pp = p = (Fts5Storage*)tdsqlite3_malloc64(nByte); + *pp = p = (Fts5Storage*)sqlite3_malloc64(nByte); if( !p ) return SQLITE_NOMEM; memset(p, 0, (size_t)nByte); @@ -227737,59 +227737,59 @@ static int tdsqlite3Fts5StorageOpen( if( bCreate ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ int nDefn = 32 + pConfig->nCol*10; - char *zDefn = tdsqlite3_malloc64(32 + (tdsqlite3_int64)pConfig->nCol * 10); + char *zDefn = sqlite3_malloc64(32 + (sqlite3_int64)pConfig->nCol * 10); if( zDefn==0 ){ rc = SQLITE_NOMEM; }else{ int i; int iOff; - tdsqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); + sqlite3_snprintf(nDefn, zDefn, "id INTEGER PRIMARY KEY"); iOff = (int)strlen(zDefn); for(i=0; inCol; i++){ - tdsqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); + sqlite3_snprintf(nDefn-iOff, &zDefn[iOff], ", c%d", i); iOff += (int)strlen(&zDefn[iOff]); } - rc = tdsqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); + rc = sqlite3Fts5CreateTable(pConfig, "content", zDefn, 0, pzErr); } - tdsqlite3_free(zDefn); + sqlite3_free(zDefn); } if( rc==SQLITE_OK && pConfig->bColumnsize ){ - rc = tdsqlite3Fts5CreateTable( + rc = sqlite3Fts5CreateTable( pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr ); } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5CreateTable( + rc = sqlite3Fts5CreateTable( pConfig, "config", "k PRIMARY KEY, v", 1, pzErr ); } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION); + rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION); } } if( rc ){ - tdsqlite3Fts5StorageClose(p); + sqlite3Fts5StorageClose(p); *pp = 0; } return rc; } /* -** Close a handle opened by an earlier call to tdsqlite3Fts5StorageOpen(). +** Close a handle opened by an earlier call to sqlite3Fts5StorageOpen(). */ -static int tdsqlite3Fts5StorageClose(Fts5Storage *p){ +static int sqlite3Fts5StorageClose(Fts5Storage *p){ int rc = SQLITE_OK; if( p ){ int i; /* Finalize all SQL statements */ for(i=0; iaStmt); i++){ - tdsqlite3_finalize(p->aStmt[i]); + sqlite3_finalize(p->aStmt[i]); } - tdsqlite3_free(p); + sqlite3_free(p); } return rc; } @@ -227819,7 +227819,7 @@ static int fts5StorageInsertCallback( if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){ pCtx->szCol++; } - return tdsqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); + return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken); } /* @@ -227830,40 +227830,40 @@ static int fts5StorageInsertCallback( static int fts5StorageDeleteFromIndex( Fts5Storage *p, i64 iDel, - tdsqlite3_value **apVal + sqlite3_value **apVal ){ Fts5Config *pConfig = p->pConfig; - tdsqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ + sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ int rc; /* Return code */ - int rc2; /* tdsqlite3_reset() return code */ + int rc2; /* sqlite3_reset() return code */ int iCol; Fts5InsertCtx ctx; if( apVal==0 ){ rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP, &pSeek, 0); if( rc!=SQLITE_OK ) return rc; - tdsqlite3_bind_int64(pSeek, 1, iDel); - if( tdsqlite3_step(pSeek)!=SQLITE_ROW ){ - return tdsqlite3_reset(pSeek); + sqlite3_bind_int64(pSeek, 1, iDel); + if( sqlite3_step(pSeek)!=SQLITE_ROW ){ + return sqlite3_reset(pSeek); } } ctx.pStorage = p; ctx.iCol = -1; - rc = tdsqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); + rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ const char *zText; int nText; if( pSeek ){ - zText = (const char*)tdsqlite3_column_text(pSeek, iCol); - nText = tdsqlite3_column_bytes(pSeek, iCol); + zText = (const char*)sqlite3_column_text(pSeek, iCol); + nText = sqlite3_column_bytes(pSeek, iCol); }else{ - zText = (const char*)tdsqlite3_value_text(apVal[iCol-1]); - nText = tdsqlite3_value_bytes(apVal[iCol-1]); + zText = (const char*)sqlite3_value_text(apVal[iCol-1]); + nText = sqlite3_value_bytes(apVal[iCol-1]); } ctx.szCol = 0; - rc = tdsqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, zText, nText, (void*)&ctx, fts5StorageInsertCallback ); p->aTotalSize[iCol-1] -= (i64)ctx.szCol; @@ -227871,7 +227871,7 @@ static int fts5StorageDeleteFromIndex( } p->nTotalRow--; - rc2 = tdsqlite3_reset(pSeek); + rc2 = sqlite3_reset(pSeek); if( rc==SQLITE_OK ) rc = rc2; return rc; } @@ -227892,14 +227892,14 @@ static int fts5StorageInsertDocsize( ){ int rc = SQLITE_OK; if( p->pConfig->bColumnsize ){ - tdsqlite3_stmt *pReplace = 0; + sqlite3_stmt *pReplace = 0; rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pReplace, 1, iRowid); - tdsqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); - tdsqlite3_step(pReplace); - rc = tdsqlite3_reset(pReplace); - tdsqlite3_bind_null(pReplace, 2); + sqlite3_bind_int64(pReplace, 1, iRowid); + sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); } } return rc; @@ -227918,7 +227918,7 @@ static int fts5StorageInsertDocsize( static int fts5StorageLoadTotals(Fts5Storage *p, int bCache){ int rc = SQLITE_OK; if( p->bTotalsValid==0 ){ - rc = tdsqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize); + rc = sqlite3Fts5IndexGetAverages(p->pIndex, &p->nTotalRow, p->aTotalSize); p->bTotalsValid = bCache; } return rc; @@ -227938,14 +227938,14 @@ static int fts5StorageSaveTotals(Fts5Storage *p){ int rc = SQLITE_OK; memset(&buf, 0, sizeof(buf)); - tdsqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow); + sqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow); for(i=0; iaTotalSize[i]); + sqlite3Fts5BufferAppendVarint(&rc, &buf, p->aTotalSize[i]); } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n); + rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n); } - tdsqlite3_free(buf.p); + sqlite3_free(buf.p); return rc; } @@ -227953,10 +227953,10 @@ static int fts5StorageSaveTotals(Fts5Storage *p){ /* ** Remove a row from the FTS table. */ -static int tdsqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, tdsqlite3_value **apVal){ +static int sqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, sqlite3_value **apVal){ Fts5Config *pConfig = p->pConfig; int rc; - tdsqlite3_stmt *pDel = 0; + sqlite3_stmt *pDel = 0; assert( pConfig->eContent!=FTS5_CONTENT_NORMAL || apVal==0 ); rc = fts5StorageLoadTotals(p, 1); @@ -227970,9 +227970,9 @@ static int tdsqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, tdsqlite3_value if( rc==SQLITE_OK && pConfig->bColumnsize ){ rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_DOCSIZE, &pDel, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pDel, 1, iDel); - tdsqlite3_step(pDel); - rc = tdsqlite3_reset(pDel); + sqlite3_bind_int64(pDel, 1, iDel); + sqlite3_step(pDel); + rc = sqlite3_reset(pDel); } } @@ -227982,9 +227982,9 @@ static int tdsqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, tdsqlite3_value rc = fts5StorageGetStmt(p, FTS5_STMT_DELETE_CONTENT, &pDel, 0); } if( rc==SQLITE_OK ){ - tdsqlite3_bind_int64(pDel, 1, iDel); - tdsqlite3_step(pDel); - rc = tdsqlite3_reset(pDel); + sqlite3_bind_int64(pDel, 1, iDel); + sqlite3_step(pDel); + rc = sqlite3_reset(pDel); } } @@ -227994,7 +227994,7 @@ static int tdsqlite3Fts5StorageDelete(Fts5Storage *p, i64 iDel, tdsqlite3_value /* ** Delete all entries in the FTS5 index. */ -static int tdsqlite3Fts5StorageDeleteAll(Fts5Storage *p){ +static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p){ Fts5Config *pConfig = p->pConfig; int rc; @@ -228017,24 +228017,24 @@ static int tdsqlite3Fts5StorageDeleteAll(Fts5Storage *p){ /* Reinitialize the %_data table. This call creates the initial structure ** and averages records. */ if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IndexReinit(p->pIndex); + rc = sqlite3Fts5IndexReinit(p->pIndex); } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION); + rc = sqlite3Fts5StorageConfigValue(p, "version", 0, FTS5_CURRENT_VERSION); } return rc; } -static int tdsqlite3Fts5StorageRebuild(Fts5Storage *p){ +static int sqlite3Fts5StorageRebuild(Fts5Storage *p){ Fts5Buffer buf = {0,0,0}; Fts5Config *pConfig = p->pConfig; - tdsqlite3_stmt *pScan = 0; + sqlite3_stmt *pScan = 0; Fts5InsertCtx ctx; int rc, rc2; memset(&ctx, 0, sizeof(Fts5InsertCtx)); ctx.pStorage = p; - rc = tdsqlite3Fts5StorageDeleteAll(p); + rc = sqlite3Fts5StorageDeleteAll(p); if( rc==SQLITE_OK ){ rc = fts5StorageLoadTotals(p, 1); } @@ -228043,24 +228043,24 @@ static int tdsqlite3Fts5StorageRebuild(Fts5Storage *p){ rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); } - while( rc==SQLITE_OK && SQLITE_ROW==tdsqlite3_step(pScan) ){ - i64 iRowid = tdsqlite3_column_int64(pScan, 0); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){ + i64 iRowid = sqlite3_column_int64(pScan, 0); - tdsqlite3Fts5BufferZero(&buf); - rc = tdsqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid); + sqlite3Fts5BufferZero(&buf); + rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid); for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ - const char *zText = (const char*)tdsqlite3_column_text(pScan, ctx.iCol+1); - int nText = tdsqlite3_column_bytes(pScan, ctx.iCol+1); - rc = tdsqlite3Fts5Tokenize(pConfig, + const char *zText = (const char*)sqlite3_column_text(pScan, ctx.iCol+1); + int nText = sqlite3_column_bytes(pScan, ctx.iCol+1); + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, zText, nText, (void*)&ctx, fts5StorageInsertCallback ); } - tdsqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); + sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; } p->nTotalRow++; @@ -228069,8 +228069,8 @@ static int tdsqlite3Fts5StorageRebuild(Fts5Storage *p){ rc = fts5StorageInsertDocsize(p, iRowid, &buf); } } - tdsqlite3_free(buf.p); - rc2 = tdsqlite3_reset(pScan); + sqlite3_free(buf.p); + rc2 = sqlite3_reset(pScan); if( rc==SQLITE_OK ) rc = rc2; /* Write the averages record */ @@ -228080,16 +228080,16 @@ static int tdsqlite3Fts5StorageRebuild(Fts5Storage *p){ return rc; } -static int tdsqlite3Fts5StorageOptimize(Fts5Storage *p){ - return tdsqlite3Fts5IndexOptimize(p->pIndex); +static int sqlite3Fts5StorageOptimize(Fts5Storage *p){ + return sqlite3Fts5IndexOptimize(p->pIndex); } -static int tdsqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){ - return tdsqlite3Fts5IndexMerge(p->pIndex, nMerge); +static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){ + return sqlite3Fts5IndexMerge(p->pIndex, nMerge); } -static int tdsqlite3Fts5StorageReset(Fts5Storage *p){ - return tdsqlite3Fts5IndexReset(p->pIndex); +static int sqlite3Fts5StorageReset(Fts5Storage *p){ + return sqlite3Fts5IndexReset(p->pIndex); } /* @@ -228104,16 +228104,16 @@ static int tdsqlite3Fts5StorageReset(Fts5Storage *p){ static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){ int rc = SQLITE_MISMATCH; if( p->pConfig->bColumnsize ){ - tdsqlite3_stmt *pReplace = 0; + sqlite3_stmt *pReplace = 0; rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_null(pReplace, 1); - tdsqlite3_bind_null(pReplace, 2); - tdsqlite3_step(pReplace); - rc = tdsqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 1); + sqlite3_bind_null(pReplace, 2); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); } if( rc==SQLITE_OK ){ - *piRowid = tdsqlite3_last_insert_rowid(p->pConfig->db); + *piRowid = sqlite3_last_insert_rowid(p->pConfig->db); } } return rc; @@ -228122,9 +228122,9 @@ static int fts5StorageNewRowid(Fts5Storage *p, i64 *piRowid){ /* ** Insert a new row into the FTS content table. */ -static int tdsqlite3Fts5StorageContentInsert( +static int sqlite3Fts5StorageContentInsert( Fts5Storage *p, - tdsqlite3_value **apVal, + sqlite3_value **apVal, i64 *piRowid ){ Fts5Config *pConfig = p->pConfig; @@ -228132,23 +228132,23 @@ static int tdsqlite3Fts5StorageContentInsert( /* Insert the new row into the %_content table. */ if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){ - if( tdsqlite3_value_type(apVal[1])==SQLITE_INTEGER ){ - *piRowid = tdsqlite3_value_int64(apVal[1]); + if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){ + *piRowid = sqlite3_value_int64(apVal[1]); }else{ rc = fts5StorageNewRowid(p, piRowid); } }else{ - tdsqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ + sqlite3_stmt *pInsert = 0; /* Statement to write %_content table */ int i; /* Counter variable */ rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0); for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){ - rc = tdsqlite3_bind_value(pInsert, i, apVal[i]); + rc = sqlite3_bind_value(pInsert, i, apVal[i]); } if( rc==SQLITE_OK ){ - tdsqlite3_step(pInsert); - rc = tdsqlite3_reset(pInsert); + sqlite3_step(pInsert); + rc = sqlite3_reset(pInsert); } - *piRowid = tdsqlite3_last_insert_rowid(pConfig->db); + *piRowid = sqlite3_last_insert_rowid(pConfig->db); } return rc; @@ -228157,9 +228157,9 @@ static int tdsqlite3Fts5StorageContentInsert( /* ** Insert new entries into the FTS index and %_docsize table. */ -static int tdsqlite3Fts5StorageIndexInsert( +static int sqlite3Fts5StorageIndexInsert( Fts5Storage *p, - tdsqlite3_value **apVal, + sqlite3_value **apVal, i64 iRowid ){ Fts5Config *pConfig = p->pConfig; @@ -228172,21 +228172,21 @@ static int tdsqlite3Fts5StorageIndexInsert( rc = fts5StorageLoadTotals(p, 1); if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid); + rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid); } for(ctx.iCol=0; rc==SQLITE_OK && ctx.iColnCol; ctx.iCol++){ ctx.szCol = 0; if( pConfig->abUnindexed[ctx.iCol]==0 ){ - const char *zText = (const char*)tdsqlite3_value_text(apVal[ctx.iCol+2]); - int nText = tdsqlite3_value_bytes(apVal[ctx.iCol+2]); - rc = tdsqlite3Fts5Tokenize(pConfig, + const char *zText = (const char*)sqlite3_value_text(apVal[ctx.iCol+2]); + int nText = sqlite3_value_bytes(apVal[ctx.iCol+2]); + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, zText, nText, (void*)&ctx, fts5StorageInsertCallback ); } - tdsqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); + sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol); p->aTotalSize[ctx.iCol] += (i64)ctx.szCol; } p->nTotalRow++; @@ -228195,7 +228195,7 @@ static int tdsqlite3Fts5StorageIndexInsert( if( rc==SQLITE_OK ){ rc = fts5StorageInsertDocsize(p, iRowid, &buf); } - tdsqlite3_free(buf.p); + sqlite3_free(buf.p); return rc; } @@ -228205,28 +228205,28 @@ static int fts5StorageCount(Fts5Storage *p, const char *zSuffix, i64 *pnRow){ char *zSql; int rc; - zSql = tdsqlite3_mprintf("SELECT count(*) FROM %Q.'%q_%s'", + zSql = sqlite3_mprintf("SELECT count(*) FROM %Q.'%q_%s'", pConfig->zDb, pConfig->zName, zSuffix ); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ - tdsqlite3_stmt *pCnt = 0; - rc = tdsqlite3_prepare_v2(pConfig->db, zSql, -1, &pCnt, 0); + sqlite3_stmt *pCnt = 0; + rc = sqlite3_prepare_v2(pConfig->db, zSql, -1, &pCnt, 0); if( rc==SQLITE_OK ){ - if( SQLITE_ROW==tdsqlite3_step(pCnt) ){ - *pnRow = tdsqlite3_column_int64(pCnt, 0); + if( SQLITE_ROW==sqlite3_step(pCnt) ){ + *pnRow = sqlite3_column_int64(pCnt, 0); } - rc = tdsqlite3_finalize(pCnt); + rc = sqlite3_finalize(pCnt); } } - tdsqlite3_free(zSql); + sqlite3_free(zSql); return rc; } /* -** Context object used by tdsqlite3Fts5StorageIntegrity(). +** Context object used by sqlite3Fts5StorageIntegrity(). */ typedef struct Fts5IntegrityCtx Fts5IntegrityCtx; struct Fts5IntegrityCtx { @@ -228283,20 +228283,20 @@ static int fts5StorageIntegrityCallback( break; } - rc = tdsqlite3Fts5TermsetAdd(pTermset, 0, pToken, nToken, &bPresent); + rc = sqlite3Fts5TermsetAdd(pTermset, 0, pToken, nToken, &bPresent); if( rc==SQLITE_OK && bPresent==0 ){ - pCtx->cksum ^= tdsqlite3Fts5IndexEntryCksum( + pCtx->cksum ^= sqlite3Fts5IndexEntryCksum( pCtx->iRowid, iCol, iPos, 0, pToken, nToken ); } for(ii=0; rc==SQLITE_OK && iipConfig->nPrefix; ii++){ const int nChar = pCtx->pConfig->aPrefix[ii]; - int nByte = tdsqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar); + int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar); if( nByte ){ - rc = tdsqlite3Fts5TermsetAdd(pTermset, ii+1, pToken, nByte, &bPresent); + rc = sqlite3Fts5TermsetAdd(pTermset, ii+1, pToken, nByte, &bPresent); if( bPresent==0 ){ - pCtx->cksum ^= tdsqlite3Fts5IndexEntryCksum( + pCtx->cksum ^= sqlite3Fts5IndexEntryCksum( pCtx->iRowid, iCol, iPos, ii+1, pToken, nByte ); } @@ -228312,17 +228312,17 @@ static int fts5StorageIntegrityCallback( ** some other SQLite error code if an error occurs while attempting to ** determine this. */ -static int tdsqlite3Fts5StorageIntegrity(Fts5Storage *p){ +static int sqlite3Fts5StorageIntegrity(Fts5Storage *p){ Fts5Config *pConfig = p->pConfig; int rc; /* Return code */ int *aColSize; /* Array of size pConfig->nCol */ i64 *aTotalSize; /* Array of size pConfig->nCol */ Fts5IntegrityCtx ctx; - tdsqlite3_stmt *pScan; + sqlite3_stmt *pScan; memset(&ctx, 0, sizeof(Fts5IntegrityCtx)); ctx.pConfig = p->pConfig; - aTotalSize = (i64*)tdsqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64))); + aTotalSize = (i64*)sqlite3_malloc64(pConfig->nCol*(sizeof(int)+sizeof(i64))); if( !aTotalSize ) return SQLITE_NOMEM; aColSize = (int*)&aTotalSize[pConfig->nCol]; memset(aTotalSize, 0, sizeof(i64) * pConfig->nCol); @@ -228332,27 +228332,27 @@ static int tdsqlite3Fts5StorageIntegrity(Fts5Storage *p){ rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0); if( rc==SQLITE_OK ){ int rc2; - while( SQLITE_ROW==tdsqlite3_step(pScan) ){ + while( SQLITE_ROW==sqlite3_step(pScan) ){ int i; - ctx.iRowid = tdsqlite3_column_int64(pScan, 0); + ctx.iRowid = sqlite3_column_int64(pScan, 0); ctx.szCol = 0; if( pConfig->bColumnsize ){ - rc = tdsqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); + rc = sqlite3Fts5StorageDocsize(p, ctx.iRowid, aColSize); } if( rc==SQLITE_OK && pConfig->eDetail==FTS5_DETAIL_NONE ){ - rc = tdsqlite3Fts5TermsetNew(&ctx.pTermset); + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } for(i=0; rc==SQLITE_OK && inCol; i++){ if( pConfig->abUnindexed[i] ) continue; ctx.iCol = i; ctx.szCol = 0; if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - rc = tdsqlite3Fts5TermsetNew(&ctx.pTermset); + rc = sqlite3Fts5TermsetNew(&ctx.pTermset); } if( rc==SQLITE_OK ){ - const char *zText = (const char*)tdsqlite3_column_text(pScan, i+1); - int nText = tdsqlite3_column_bytes(pScan, i+1); - rc = tdsqlite3Fts5Tokenize(pConfig, + const char *zText = (const char*)sqlite3_column_text(pScan, i+1); + int nText = sqlite3_column_bytes(pScan, i+1); + rc = sqlite3Fts5Tokenize(pConfig, FTS5_TOKENIZE_DOCUMENT, zText, nText, (void*)&ctx, @@ -228364,16 +228364,16 @@ static int tdsqlite3Fts5StorageIntegrity(Fts5Storage *p){ } aTotalSize[i] += ctx.szCol; if( pConfig->eDetail==FTS5_DETAIL_COLUMNS ){ - tdsqlite3Fts5TermsetFree(ctx.pTermset); + sqlite3Fts5TermsetFree(ctx.pTermset); ctx.pTermset = 0; } } - tdsqlite3Fts5TermsetFree(ctx.pTermset); + sqlite3Fts5TermsetFree(ctx.pTermset); ctx.pTermset = 0; if( rc!=SQLITE_OK ) break; } - rc2 = tdsqlite3_reset(pScan); + rc2 = sqlite3_reset(pScan); if( rc==SQLITE_OK ) rc = rc2; } @@ -228403,10 +228403,10 @@ static int tdsqlite3Fts5StorageIntegrity(Fts5Storage *p){ ** verify, amongst other things, that it matches the checksum generated by ** inspecting the index itself. */ if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum); + rc = sqlite3Fts5IndexIntegrityCheck(p->pIndex, ctx.cksum); } - tdsqlite3_free(aTotalSize); + sqlite3_free(aTotalSize); return rc; } @@ -228414,10 +228414,10 @@ static int tdsqlite3Fts5StorageIntegrity(Fts5Storage *p){ ** Obtain an SQLite statement handle that may be used to read data from the ** %_content table. */ -static int tdsqlite3Fts5StorageStmt( +static int sqlite3Fts5StorageStmt( Fts5Storage *p, int eStmt, - tdsqlite3_stmt **pp, + sqlite3_stmt **pp, char **pzErrMsg ){ int rc; @@ -228435,23 +228435,23 @@ static int tdsqlite3Fts5StorageStmt( /* ** Release an SQLite statement handle obtained via an earlier call to -** tdsqlite3Fts5StorageStmt(). The eStmt parameter passed to this function -** must match that passed to the tdsqlite3Fts5StorageStmt() call. +** sqlite3Fts5StorageStmt(). The eStmt parameter passed to this function +** must match that passed to the sqlite3Fts5StorageStmt() call. */ -static void tdsqlite3Fts5StorageStmtRelease( +static void sqlite3Fts5StorageStmtRelease( Fts5Storage *p, int eStmt, - tdsqlite3_stmt *pStmt + sqlite3_stmt *pStmt ){ assert( eStmt==FTS5_STMT_SCAN_ASC || eStmt==FTS5_STMT_SCAN_DESC || eStmt==FTS5_STMT_LOOKUP ); if( p->aStmt[eStmt]==0 ){ - tdsqlite3_reset(pStmt); + sqlite3_reset(pStmt); p->aStmt[eStmt] = pStmt; }else{ - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); } } @@ -228476,24 +228476,24 @@ static int fts5StorageDecodeSizeArray( ** An SQLite error code is returned if an error occurs, or SQLITE_OK ** otherwise. */ -static int tdsqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){ +static int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){ int nCol = p->pConfig->nCol; /* Number of user columns in table */ - tdsqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */ + sqlite3_stmt *pLookup = 0; /* Statement to query %_docsize */ int rc; /* Return Code */ assert( p->pConfig->bColumnsize ); rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0); if( rc==SQLITE_OK ){ int bCorrupt = 1; - tdsqlite3_bind_int64(pLookup, 1, iRowid); - if( SQLITE_ROW==tdsqlite3_step(pLookup) ){ - const u8 *aBlob = tdsqlite3_column_blob(pLookup, 0); - int nBlob = tdsqlite3_column_bytes(pLookup, 0); + sqlite3_bind_int64(pLookup, 1, iRowid); + if( SQLITE_ROW==sqlite3_step(pLookup) ){ + const u8 *aBlob = sqlite3_column_blob(pLookup, 0); + int nBlob = sqlite3_column_bytes(pLookup, 0); if( 0==fts5StorageDecodeSizeArray(aCol, nCol, aBlob, nBlob) ){ bCorrupt = 0; } } - rc = tdsqlite3_reset(pLookup); + rc = sqlite3_reset(pLookup); if( bCorrupt && rc==SQLITE_OK ){ rc = FTS5_CORRUPT; } @@ -228502,7 +228502,7 @@ static int tdsqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){ return rc; } -static int tdsqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){ +static int sqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){ int rc = fts5StorageLoadTotals(p, 0); if( rc==SQLITE_OK ){ *pnToken = 0; @@ -228520,7 +228520,7 @@ static int tdsqlite3Fts5StorageSize(Fts5Storage *p, int iCol, i64 *pnToken){ return rc; } -static int tdsqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){ +static int sqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){ int rc = fts5StorageLoadTotals(p, 0); if( rc==SQLITE_OK ){ /* nTotalRow being zero does not necessarily indicate a corrupt @@ -228537,47 +228537,47 @@ static int tdsqlite3Fts5StorageRowCount(Fts5Storage *p, i64 *pnRow){ /* ** Flush any data currently held in-memory to disk. */ -static int tdsqlite3Fts5StorageSync(Fts5Storage *p){ +static int sqlite3Fts5StorageSync(Fts5Storage *p){ int rc = SQLITE_OK; - i64 iLastRowid = tdsqlite3_last_insert_rowid(p->pConfig->db); + i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); p->bTotalsValid = 0; } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IndexSync(p->pIndex); + rc = sqlite3Fts5IndexSync(p->pIndex); } - tdsqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid); + sqlite3_set_last_insert_rowid(p->pConfig->db, iLastRowid); return rc; } -static int tdsqlite3Fts5StorageRollback(Fts5Storage *p){ +static int sqlite3Fts5StorageRollback(Fts5Storage *p){ p->bTotalsValid = 0; - return tdsqlite3Fts5IndexRollback(p->pIndex); + return sqlite3Fts5IndexRollback(p->pIndex); } -static int tdsqlite3Fts5StorageConfigValue( +static int sqlite3Fts5StorageConfigValue( Fts5Storage *p, const char *z, - tdsqlite3_value *pVal, + sqlite3_value *pVal, int iVal ){ - tdsqlite3_stmt *pReplace = 0; + sqlite3_stmt *pReplace = 0; int rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_CONFIG, &pReplace, 0); if( rc==SQLITE_OK ){ - tdsqlite3_bind_text(pReplace, 1, z, -1, SQLITE_STATIC); + sqlite3_bind_text(pReplace, 1, z, -1, SQLITE_STATIC); if( pVal ){ - tdsqlite3_bind_value(pReplace, 2, pVal); + sqlite3_bind_value(pReplace, 2, pVal); }else{ - tdsqlite3_bind_int(pReplace, 2, iVal); + sqlite3_bind_int(pReplace, 2, iVal); } - tdsqlite3_step(pReplace); - rc = tdsqlite3_reset(pReplace); - tdsqlite3_bind_null(pReplace, 1); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 1); } if( rc==SQLITE_OK && pVal ){ int iNew = p->pConfig->iCookie + 1; - rc = tdsqlite3Fts5IndexSetCookie(p->pIndex, iNew); + rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew); if( rc==SQLITE_OK ){ p->pConfig->iCookie = iNew; } @@ -228642,7 +228642,7 @@ static void fts5AsciiAddExceptions( ** Delete a "ascii" tokenizer. */ static void fts5AsciiDelete(Fts5Tokenizer *p){ - tdsqlite3_free(p); + sqlite3_free(p); } /* @@ -228659,7 +228659,7 @@ static int fts5AsciiCreate( if( nArg%2 ){ rc = SQLITE_ERROR; }else{ - p = tdsqlite3_malloc(sizeof(AsciiTokenizer)); + p = sqlite3_malloc(sizeof(AsciiTokenizer)); if( p==0 ){ rc = SQLITE_NOMEM; }else{ @@ -228668,10 +228668,10 @@ static int fts5AsciiCreate( memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar)); for(i=0; rc==SQLITE_OK && inFold ){ - if( pFold!=aFold ) tdsqlite3_free(pFold); - pFold = tdsqlite3_malloc64((tdsqlite3_int64)nByte*2); + if( pFold!=aFold ) sqlite3_free(pFold); + pFold = sqlite3_malloc64((sqlite3_int64)nByte*2); if( pFold==0 ){ rc = SQLITE_NOMEM; break; @@ -228753,7 +228753,7 @@ static int fts5AsciiTokenize( is = ie+1; } - if( pFold!=aFold ) tdsqlite3_free(pFold); + if( pFold!=aFold ) sqlite3_free(pFold); if( rc==SQLITE_DONE ) rc = SQLITE_OK; return rc; } @@ -228765,12 +228765,12 @@ static int fts5AsciiTokenize( /* ** The following two macros - READ_UTF8 and WRITE_UTF8 - have been copied -** from the tdsqlite3 source file utf.c. If this file is compiled as part +** from the sqlite3 source file utf.c. If this file is compiled as part ** of the amalgamation, they are not required. */ #ifndef SQLITE_AMALGAMATION -static const unsigned char tdsqlite3Utf8Trans1[] = { +static const unsigned char sqlite3Utf8Trans1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, @@ -228784,7 +228784,7 @@ static const unsigned char tdsqlite3Utf8Trans1[] = { #define READ_UTF8(zIn, zTerm, c) \ c = *(zIn++); \ if( c>=0xc0 ){ \ - c = tdsqlite3Utf8Trans1[c-0xc0]; \ + c = sqlite3Utf8Trans1[c-0xc0]; \ while( zIn!=zTerm && (*zIn & 0xc0)==0x80 ){ \ c = (c<<6) + (0x3f & *(zIn++)); \ } \ @@ -228843,7 +228843,7 @@ static int fts5UnicodeAddExceptions( int *aNew; if( n>0 ){ - aNew = (int*)tdsqlite3_realloc64(p->aiException, + aNew = (int*)sqlite3_realloc64(p->aiException, (n+p->nException)*sizeof(int)); if( aNew ){ int nNew = p->nException; @@ -228856,10 +228856,10 @@ static int fts5UnicodeAddExceptions( if( iCode<128 ){ p->aTokenChar[iCode] = (unsigned char)bTokenChars; }else{ - bToken = p->aCategory[tdsqlite3Fts5UnicodeCategory(iCode)]; + bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]; assert( (bToken==0 || bToken==1) ); assert( (bTokenChars==0 || bTokenChars==1) ); - if( bToken!=bTokenChars && tdsqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){ + if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){ int i; for(i=0; iiCode ) break; @@ -228910,9 +228910,9 @@ static int fts5UnicodeIsException(Unicode61Tokenizer *p, int iCode){ static void fts5UnicodeDelete(Fts5Tokenizer *pTok){ if( pTok ){ Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTok; - tdsqlite3_free(p->aiException); - tdsqlite3_free(p->aFold); - tdsqlite3_free(p); + sqlite3_free(p->aiException); + sqlite3_free(p->aFold); + sqlite3_free(p); } return; } @@ -228922,13 +228922,13 @@ static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){ while( *z ){ while( *z==' ' || *z=='\t' ) z++; - if( *z && tdsqlite3Fts5UnicodeCatParse(z, p->aCategory) ){ + if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){ return SQLITE_ERROR; } while( *z!=' ' && *z!='\t' && *z!='\0' ) z++; } - tdsqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar); + sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar); return SQLITE_OK; } @@ -228948,7 +228948,7 @@ static int fts5UnicodeCreate( if( nArg%2 ){ rc = SQLITE_ERROR; }else{ - p = (Unicode61Tokenizer*)tdsqlite3_malloc(sizeof(Unicode61Tokenizer)); + p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer)); if( p ){ const char *zCat = "L* N* Co"; int i; @@ -228956,14 +228956,14 @@ static int fts5UnicodeCreate( p->eRemoveDiacritic = FTS5_REMOVE_DIACRITICS_SIMPLE; p->nFold = 64; - p->aFold = tdsqlite3_malloc64(p->nFold * sizeof(char)); + p->aFold = sqlite3_malloc64(p->nFold * sizeof(char)); if( p->aFold==0 ){ rc = SQLITE_NOMEM; } /* Search for a "categories" argument */ for(i=0; rc==SQLITE_OK && iaCategory[tdsqlite3Fts5UnicodeCategory((u32)iCode)] + p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)] ^ fts5UnicodeIsException(p, iCode) ); } @@ -229078,14 +229078,14 @@ static int fts5UnicodeTokenize( /* Grow the output buffer so that there is sufficient space to fit the ** largest possible utf-8 character. */ if( zOut>pEnd ){ - aFold = tdsqlite3_malloc64((tdsqlite3_int64)nFold*2); + aFold = sqlite3_malloc64((sqlite3_int64)nFold*2); if( aFold==0 ){ rc = SQLITE_NOMEM; goto tokenize_done; } zOut = &aFold[zOut - p->aFold]; memcpy(aFold, p->aFold, nFold); - tdsqlite3_free(p->aFold); + sqlite3_free(p->aFold); p->aFold = aFold; p->nFold = nFold = nFold*2; pEnd = &aFold[nFold-6]; @@ -229095,9 +229095,9 @@ static int fts5UnicodeTokenize( /* An non-ascii-range character. Fold it into the output buffer if ** it is a token character, or break out of the loop if it is not. */ READ_UTF8(zCsr, zTerm, iCode); - if( fts5UnicodeIsAlnum(p,iCode)||tdsqlite3Fts5UnicodeIsdiacritic(iCode) ){ + if( fts5UnicodeIsAlnum(p,iCode)||sqlite3Fts5UnicodeIsdiacritic(iCode) ){ non_ascii_tokenchar: - iCode = tdsqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic); + iCode = sqlite3Fts5UnicodeFold(iCode, p->eRemoveDiacritic); if( iCode ) WRITE_UTF8(zOut, iCode); }else{ break; @@ -229150,7 +229150,7 @@ static void fts5PorterDelete(Fts5Tokenizer *pTok){ if( p->pTokenizer ){ p->tokenizer.xDelete(p->pTokenizer); } - tdsqlite3_free(p); + sqlite3_free(p); } } @@ -229172,7 +229172,7 @@ static int fts5PorterCreate( zBase = azArg[0]; } - pRet = (PorterTokenizer*)tdsqlite3_malloc(sizeof(PorterTokenizer)); + pRet = (PorterTokenizer*)sqlite3_malloc(sizeof(PorterTokenizer)); if( pRet ){ memset(pRet, 0, sizeof(PorterTokenizer)); rc = pApi->xFindTokenizer(pApi, zBase, &pUserdata, &pRet->tokenizer); @@ -229848,7 +229848,7 @@ static int fts5PorterTokenize( /* ** Register all built-in tokenizers with FTS5. */ -static int tdsqlite3Fts5TokenizerInit(fts5_api *pApi){ +static int sqlite3Fts5TokenizerInit(fts5_api *pApi){ struct BuiltinTokenizer { const char *zName; fts5_tokenizer x; @@ -229970,7 +229970,7 @@ static int fts5_remove_diacritic(int c, int bComplex){ ** Return true if the argument interpreted as a unicode codepoint ** is a diacritical modifier character. */ -static int tdsqlite3Fts5UnicodeIsdiacritic(int c){ +static int sqlite3Fts5UnicodeIsdiacritic(int c){ unsigned int mask0 = 0x08029FDF; unsigned int mask1 = 0x000361F8; if( c<768 || c>817 ) return 0; @@ -229989,7 +229989,7 @@ static int tdsqlite3Fts5UnicodeIsdiacritic(int c){ ** The results are undefined if the value passed to this function ** is less than zero. */ -static int tdsqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){ +static int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){ /* Each entry in the following array defines a rule for folding a range ** of codepoints to lower case. The rule applies to a range of nRange ** codepoints starting at codepoint iCode. @@ -230125,7 +230125,7 @@ static int tdsqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic){ } -static int tdsqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ +static int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ aArray[0] = 1; switch( zCat[0] ){ case 'C': @@ -230606,7 +230606,7 @@ static u16 aFts5UnicodeData[] = { 34, 3074, 7692, 63, 63, }; -static int tdsqlite3Fts5UnicodeCategory(u32 iCode) { +static int sqlite3Fts5UnicodeCategory(u32 iCode) { int iRes = -1; int iHi; int iLo; @@ -230637,7 +230637,7 @@ static int tdsqlite3Fts5UnicodeCategory(u32 iCode) { return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9; } -static void tdsqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ +static void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ int i = 0; int iTbl = 0; while( i<128 ){ @@ -230669,11 +230669,11 @@ static void tdsqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){ /* #include "fts5Int.h" */ /* -** This is a copy of the tdsqlite3GetVarint32() routine from the SQLite core. +** This is a copy of the sqlite3GetVarint32() routine from the SQLite core. ** Except, this version does handle the single byte case that the core ** version depends on being handled before its function is called. */ -static int tdsqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){ +static int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){ u32 a,b; /* The 1-byte case. Overwhelmingly the most common. */ @@ -230727,7 +230727,7 @@ static int tdsqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){ u64 v64; u8 n; p -= 2; - n = tdsqlite3Fts5GetVarint(p, &v64); + n = sqlite3Fts5GetVarint(p, &v64); *v = ((u32)v64) & 0x7FFFFFFF; assert( n>3 && n<=9 ); return n; @@ -230736,7 +230736,7 @@ static int tdsqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){ /* -** Bitmasks used by tdsqlite3GetVarint(). These precomputed constants +** Bitmasks used by sqlite3GetVarint(). These precomputed constants ** are defined here rather than simply putting the constant expressions ** inline in order to work around bugs in the RVT compiler. ** @@ -230751,7 +230751,7 @@ static int tdsqlite3Fts5GetVarint32(const unsigned char *p, u32 *v){ ** Read a 64-bit variable-length integer from memory starting at p[0]. ** Return the number of bytes read. The value is stored in *v. */ -static u8 tdsqlite3Fts5GetVarint(const unsigned char *p, u64 *v){ +static u8 sqlite3Fts5GetVarint(const unsigned char *p, u64 *v){ u32 a,b,s; a = *p; @@ -230970,7 +230970,7 @@ static int FTS5_NOINLINE fts5PutVarint64(unsigned char *p, u64 v){ return n; } -static int tdsqlite3Fts5PutVarint(unsigned char *p, u64 v){ +static int sqlite3Fts5PutVarint(unsigned char *p, u64 v){ if( v<=0x7f ){ p[0] = v&0x7f; return 1; @@ -230984,7 +230984,7 @@ static int tdsqlite3Fts5PutVarint(unsigned char *p, u64 v){ } -static int tdsqlite3Fts5GetVarintLen(u32 iVal){ +static int sqlite3Fts5GetVarintLen(u32 iVal){ #if 0 if( iVal<(1 << 7 ) ) return 1; #endif @@ -231041,17 +231041,17 @@ typedef struct Fts5VocabTable Fts5VocabTable; typedef struct Fts5VocabCursor Fts5VocabCursor; struct Fts5VocabTable { - tdsqlite3_vtab base; + sqlite3_vtab base; char *zFts5Tbl; /* Name of fts5 table */ char *zFts5Db; /* Db containing fts5 table */ - tdsqlite3 *db; /* Database handle */ + sqlite3 *db; /* Database handle */ Fts5Global *pGlobal; /* FTS5 global object for this database */ int eType; /* FTS5_VOCAB_COL, ROW or INSTANCE */ }; struct Fts5VocabCursor { - tdsqlite3_vtab_cursor base; - tdsqlite3_stmt *pStmt; /* Statement holding lock on pIndex */ + sqlite3_vtab_cursor base; + sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */ Fts5Table *pFts5; /* Associated FTS5 table */ int bEof; /* True if this cursor is at EOF */ @@ -231098,24 +231098,24 @@ struct Fts5VocabCursor { */ static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){ int rc = SQLITE_OK; - char *zCopy = tdsqlite3Fts5Strndup(&rc, zType, -1); + char *zCopy = sqlite3Fts5Strndup(&rc, zType, -1); if( rc==SQLITE_OK ){ - tdsqlite3Fts5Dequote(zCopy); - if( tdsqlite3_stricmp(zCopy, "col")==0 ){ + sqlite3Fts5Dequote(zCopy); + if( sqlite3_stricmp(zCopy, "col")==0 ){ *peType = FTS5_VOCAB_COL; }else - if( tdsqlite3_stricmp(zCopy, "row")==0 ){ + if( sqlite3_stricmp(zCopy, "row")==0 ){ *peType = FTS5_VOCAB_ROW; }else - if( tdsqlite3_stricmp(zCopy, "instance")==0 ){ + if( sqlite3_stricmp(zCopy, "instance")==0 ){ *peType = FTS5_VOCAB_INSTANCE; }else { - *pzErr = tdsqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy); + *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy); rc = SQLITE_ERROR; } - tdsqlite3_free(zCopy); + sqlite3_free(zCopy); } return rc; @@ -231125,18 +231125,18 @@ static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){ /* ** The xDisconnect() virtual table method. */ -static int fts5VocabDisconnectMethod(tdsqlite3_vtab *pVtab){ +static int fts5VocabDisconnectMethod(sqlite3_vtab *pVtab){ Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab; - tdsqlite3_free(pTab); + sqlite3_free(pTab); return SQLITE_OK; } /* ** The xDestroy() virtual table method. */ -static int fts5VocabDestroyMethod(tdsqlite3_vtab *pVtab){ +static int fts5VocabDestroyMethod(sqlite3_vtab *pVtab){ Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab; - tdsqlite3_free(pTab); + sqlite3_free(pTab); return SQLITE_OK; } @@ -231162,11 +231162,11 @@ static int fts5VocabDestroyMethod(tdsqlite3_vtab *pVtab){ ** argv[5] -> type of fts5vocab table */ static int fts5VocabInitVtab( - tdsqlite3 *db, /* The SQLite database connection */ + sqlite3 *db, /* The SQLite database connection */ void *pAux, /* Pointer to Fts5Global object */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ + sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ char **pzErr /* Write any error message here */ ){ const char *azSchema[] = { @@ -231182,7 +231182,7 @@ static int fts5VocabInitVtab( bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0); if( argc!=5 && bDb==0 ){ - *pzErr = tdsqlite3_mprintf("wrong number of vtable arguments"); + *pzErr = sqlite3_mprintf("wrong number of vtable arguments"); rc = SQLITE_ERROR; }else{ int nByte; /* Bytes of space to allocate */ @@ -231196,11 +231196,11 @@ static int fts5VocabInitVtab( rc = fts5VocabTableType(zType, pzErr, &eType); if( rc==SQLITE_OK ){ assert( eType>=0 && eTypepGlobal = (Fts5Global*)pAux; pRet->eType = eType; @@ -231209,12 +231209,12 @@ static int fts5VocabInitVtab( pRet->zFts5Db = &pRet->zFts5Tbl[nTab]; memcpy(pRet->zFts5Tbl, zTab, nTab); memcpy(pRet->zFts5Db, zDb, nDb); - tdsqlite3Fts5Dequote(pRet->zFts5Tbl); - tdsqlite3Fts5Dequote(pRet->zFts5Db); + sqlite3Fts5Dequote(pRet->zFts5Tbl); + sqlite3Fts5Dequote(pRet->zFts5Db); } } - *ppVTab = (tdsqlite3_vtab*)pRet; + *ppVTab = (sqlite3_vtab*)pRet; return rc; } @@ -231224,22 +231224,22 @@ static int fts5VocabInitVtab( ** work is done in function fts5VocabInitVtab(). */ static int fts5VocabConnectMethod( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pAux, /* Pointer to tokenizer hash table */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVtab, /* OUT: New tdsqlite3_vtab object */ - char **pzErr /* OUT: tdsqlite3_malloc'd error message */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ ){ return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr); } static int fts5VocabCreateMethod( - tdsqlite3 *db, /* Database connection */ + sqlite3 *db, /* Database connection */ void *pAux, /* Pointer to tokenizer hash table */ int argc, /* Number of elements in argv array */ const char * const *argv, /* xCreate/xConnect argument array */ - tdsqlite3_vtab **ppVtab, /* OUT: New tdsqlite3_vtab object */ - char **pzErr /* OUT: tdsqlite3_malloc'd error message */ + sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ + char **pzErr /* OUT: sqlite3_malloc'd error message */ ){ return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr); } @@ -231257,8 +231257,8 @@ static int fts5VocabCreateMethod( ** identically, as are greater-than and greater-than-or-equal. */ static int fts5VocabBestIndexMethod( - tdsqlite3_vtab *pUnused, - tdsqlite3_index_info *pInfo + sqlite3_vtab *pUnused, + sqlite3_index_info *pInfo ){ int i; int iTermEq = -1; @@ -231270,7 +231270,7 @@ static int fts5VocabBestIndexMethod( UNUSED_PARAM(pUnused); for(i=0; inConstraint; i++){ - struct tdsqlite3_index_constraint *p = &pInfo->aConstraint[i]; + struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; if( p->usable==0 ) continue; if( p->iColumn==0 ){ /* term column */ if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i; @@ -231302,7 +231302,7 @@ static int fts5VocabBestIndexMethod( /* This virtual table always delivers results in ascending order of ** the "term" column (column 0). So if the user has requested this ** specifically - "ORDER BY term" or "ORDER BY term ASC" - set the - ** tdsqlite3_index_info.orderByConsumed flag to tell the core the results + ** sqlite3_index_info.orderByConsumed flag to tell the core the results ** are already in sorted order. */ if( pInfo->nOrderBy==1 && pInfo->aOrderBy[0].iColumn==0 @@ -231319,50 +231319,50 @@ static int fts5VocabBestIndexMethod( ** Implementation of xOpen method. */ static int fts5VocabOpenMethod( - tdsqlite3_vtab *pVTab, - tdsqlite3_vtab_cursor **ppCsr + sqlite3_vtab *pVTab, + sqlite3_vtab_cursor **ppCsr ){ Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab; Fts5Table *pFts5 = 0; Fts5VocabCursor *pCsr = 0; int rc = SQLITE_OK; - tdsqlite3_stmt *pStmt = 0; + sqlite3_stmt *pStmt = 0; char *zSql = 0; - zSql = tdsqlite3Fts5Mprintf(&rc, + zSql = sqlite3Fts5Mprintf(&rc, "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'", pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl ); if( zSql ){ - rc = tdsqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0); + rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0); } - tdsqlite3_free(zSql); + sqlite3_free(zSql); assert( rc==SQLITE_OK || pStmt==0 ); if( rc==SQLITE_ERROR ) rc = SQLITE_OK; - if( pStmt && tdsqlite3_step(pStmt)==SQLITE_ROW ){ - i64 iId = tdsqlite3_column_int64(pStmt, 0); - pFts5 = tdsqlite3Fts5TableFromCsrid(pTab->pGlobal, iId); + if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ + i64 iId = sqlite3_column_int64(pStmt, 0); + pFts5 = sqlite3Fts5TableFromCsrid(pTab->pGlobal, iId); } if( rc==SQLITE_OK ){ if( pFts5==0 ){ - rc = tdsqlite3_finalize(pStmt); + rc = sqlite3_finalize(pStmt); pStmt = 0; if( rc==SQLITE_OK ){ - pVTab->zErrMsg = tdsqlite3_mprintf( + pVTab->zErrMsg = sqlite3_mprintf( "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl ); rc = SQLITE_ERROR; } }else{ - rc = tdsqlite3Fts5FlushToDisk(pFts5); + rc = sqlite3Fts5FlushToDisk(pFts5); } } if( rc==SQLITE_OK ){ int nByte = pFts5->pConfig->nCol * sizeof(i64)*2 + sizeof(Fts5VocabCursor); - pCsr = (Fts5VocabCursor*)tdsqlite3Fts5MallocZero(&rc, nByte); + pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte); } if( pCsr ){ @@ -231371,18 +231371,18 @@ static int fts5VocabOpenMethod( pCsr->aCnt = (i64*)&pCsr[1]; pCsr->aDoc = &pCsr->aCnt[pFts5->pConfig->nCol]; }else{ - tdsqlite3_finalize(pStmt); + sqlite3_finalize(pStmt); } - *ppCsr = (tdsqlite3_vtab_cursor*)pCsr; + *ppCsr = (sqlite3_vtab_cursor*)pCsr; return rc; } static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){ pCsr->rowid = 0; - tdsqlite3Fts5IterClose(pCsr->pIter); + sqlite3Fts5IterClose(pCsr->pIter); pCsr->pIter = 0; - tdsqlite3_free(pCsr->zLeTerm); + sqlite3_free(pCsr->zLeTerm); pCsr->nLeTerm = -1; pCsr->zLeTerm = 0; pCsr->bEof = 0; @@ -231392,24 +231392,24 @@ static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){ ** Close the cursor. For additional information see the documentation ** on the xClose method of the virtual table interface. */ -static int fts5VocabCloseMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts5VocabCloseMethod(sqlite3_vtab_cursor *pCursor){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; fts5VocabResetCursor(pCsr); - tdsqlite3Fts5BufferFree(&pCsr->term); - tdsqlite3_finalize(pCsr->pStmt); - tdsqlite3_free(pCsr); + sqlite3Fts5BufferFree(&pCsr->term); + sqlite3_finalize(pCsr->pStmt); + sqlite3_free(pCsr); return SQLITE_OK; } static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){ int rc = SQLITE_OK; - if( tdsqlite3Fts5IterEof(pCsr->pIter) ){ + if( sqlite3Fts5IterEof(pCsr->pIter) ){ pCsr->bEof = 1; }else{ const char *zTerm; int nTerm; - zTerm = tdsqlite3Fts5IterTerm(pCsr->pIter, &nTerm); + zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); if( pCsr->nLeTerm>=0 ){ int nCmp = MIN(nTerm, pCsr->nLeTerm); int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp); @@ -231418,7 +231418,7 @@ static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){ } } - tdsqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); + sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); } return rc; } @@ -231430,15 +231430,15 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){ i64 *pp = &pCsr->iInstPos; int *po = &pCsr->iInstOff; - assert( tdsqlite3Fts5IterEof(pIter)==0 ); + assert( sqlite3Fts5IterEof(pIter)==0 ); assert( pCsr->bEof==0 ); while( eDetail==FTS5_DETAIL_NONE - || tdsqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp) + || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp) ){ pCsr->iInstPos = 0; pCsr->iInstOff = 0; - rc = tdsqlite3Fts5IterNextScan(pCsr->pIter); + rc = sqlite3Fts5IterNextScan(pCsr->pIter); if( rc==SQLITE_OK ){ rc = fts5VocabInstanceNewTerm(pCsr); if( pCsr->bEof || eDetail==FTS5_DETAIL_NONE ) break; @@ -231455,7 +231455,7 @@ static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){ /* ** Advance the cursor to the next row in the table. */ -static int fts5VocabNextMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab; int rc = SQLITE_OK; @@ -231474,13 +231474,13 @@ static int fts5VocabNextMethod(tdsqlite3_vtab_cursor *pCursor){ } if( pTab->eType!=FTS5_VOCAB_COL || pCsr->iCol>=nCol ){ - if( tdsqlite3Fts5IterEof(pCsr->pIter) ){ + if( sqlite3Fts5IterEof(pCsr->pIter) ){ pCsr->bEof = 1; }else{ const char *zTerm; int nTerm; - zTerm = tdsqlite3Fts5IterTerm(pCsr->pIter, &nTerm); + zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); assert( nTerm>=0 ); if( pCsr->nLeTerm>=0 ){ int nCmp = MIN(nTerm, pCsr->nLeTerm); @@ -231491,7 +231491,7 @@ static int fts5VocabNextMethod(tdsqlite3_vtab_cursor *pCursor){ } } - tdsqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); + sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); memset(pCsr->aCnt, 0, nCol * sizeof(i64)); memset(pCsr->aDoc, 0, nCol * sizeof(i64)); pCsr->iCol = 0; @@ -231509,7 +231509,7 @@ static int fts5VocabNextMethod(tdsqlite3_vtab_cursor *pCursor){ switch( pTab->eType ){ case FTS5_VOCAB_ROW: if( eDetail==FTS5_DETAIL_FULL ){ - while( 0==tdsqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ + while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ pCsr->aCnt[0]++; } } @@ -231519,7 +231519,7 @@ static int fts5VocabNextMethod(tdsqlite3_vtab_cursor *pCursor){ case FTS5_VOCAB_COL: if( eDetail==FTS5_DETAIL_FULL ){ int iCol = -1; - while( 0==tdsqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ + while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ int ii = FTS5_POS2COLUMN(iPos); if( iCol!=ii ){ if( ii>=nCol ){ @@ -231532,7 +231532,7 @@ static int fts5VocabNextMethod(tdsqlite3_vtab_cursor *pCursor){ pCsr->aCnt[ii]++; } }else if( eDetail==FTS5_DETAIL_COLUMNS ){ - while( 0==tdsqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){ + while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){ assert_nc( iPos>=0 && iPos=nCol ){ rc = FTS5_CORRUPT; @@ -231552,18 +231552,18 @@ static int fts5VocabNextMethod(tdsqlite3_vtab_cursor *pCursor){ } if( rc==SQLITE_OK ){ - rc = tdsqlite3Fts5IterNextScan(pCsr->pIter); + rc = sqlite3Fts5IterNextScan(pCsr->pIter); } if( pTab->eType==FTS5_VOCAB_INSTANCE ) break; if( rc==SQLITE_OK ){ - zTerm = tdsqlite3Fts5IterTerm(pCsr->pIter, &nTerm); + zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); if( nTerm!=pCsr->term.n || (nTerm>0 && memcmp(zTerm, pCsr->term.p, nTerm)) ){ break; } - if( tdsqlite3Fts5IterEof(pCsr->pIter) ) break; + if( sqlite3Fts5IterEof(pCsr->pIter) ) break; } } } @@ -231582,11 +231582,11 @@ static int fts5VocabNextMethod(tdsqlite3_vtab_cursor *pCursor){ ** This is the xFilter implementation for the virtual table. */ static int fts5VocabFilterMethod( - tdsqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ + sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ int idxNum, /* Strategy index */ const char *zUnused, /* Unused */ int nUnused, /* Number of elements in apVal */ - tdsqlite3_value **apVal /* Arguments for the indexing scheme */ + sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab; Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; @@ -231598,9 +231598,9 @@ static int fts5VocabFilterMethod( const char *zTerm = 0; int nTerm = 0; - tdsqlite3_value *pEq = 0; - tdsqlite3_value *pGe = 0; - tdsqlite3_value *pLe = 0; + sqlite3_value *pEq = 0; + sqlite3_value *pGe = 0; + sqlite3_value *pLe = 0; UNUSED_PARAM2(zUnused, nUnused); @@ -231610,19 +231610,19 @@ static int fts5VocabFilterMethod( if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; if( pEq ){ - zTerm = (const char *)tdsqlite3_value_text(pEq); - nTerm = tdsqlite3_value_bytes(pEq); + zTerm = (const char *)sqlite3_value_text(pEq); + nTerm = sqlite3_value_bytes(pEq); f = 0; }else{ if( pGe ){ - zTerm = (const char *)tdsqlite3_value_text(pGe); - nTerm = tdsqlite3_value_bytes(pGe); + zTerm = (const char *)sqlite3_value_text(pGe); + nTerm = sqlite3_value_bytes(pGe); } if( pLe ){ - const char *zCopy = (const char *)tdsqlite3_value_text(pLe); + const char *zCopy = (const char *)sqlite3_value_text(pLe); if( zCopy==0 ) zCopy = ""; - pCsr->nLeTerm = tdsqlite3_value_bytes(pLe); - pCsr->zLeTerm = tdsqlite3_malloc(pCsr->nLeTerm+1); + pCsr->nLeTerm = sqlite3_value_bytes(pLe); + pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1); if( pCsr->zLeTerm==0 ){ rc = SQLITE_NOMEM; }else{ @@ -231633,7 +231633,7 @@ static int fts5VocabFilterMethod( if( rc==SQLITE_OK ){ Fts5Index *pIndex = pCsr->pFts5->pIndex; - rc = tdsqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); + rc = sqlite3Fts5IndexQuery(pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); } if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){ rc = fts5VocabInstanceNewTerm(pCsr); @@ -231652,14 +231652,14 @@ static int fts5VocabFilterMethod( ** This is the xEof method of the virtual table. SQLite calls this ** routine to find out if it has reached the end of a result set. */ -static int fts5VocabEofMethod(tdsqlite3_vtab_cursor *pCursor){ +static int fts5VocabEofMethod(sqlite3_vtab_cursor *pCursor){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; return pCsr->bEof; } static int fts5VocabColumnMethod( - tdsqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ - tdsqlite3_context *pCtx, /* Context for tdsqlite3_result_xxx() calls */ + sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ + sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ int iCol /* Index of column to read value from */ ){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; @@ -231668,7 +231668,7 @@ static int fts5VocabColumnMethod( i64 iVal = 0; if( iCol==0 ){ - tdsqlite3_result_text( + sqlite3_result_text( pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT ); }else if( eType==FTS5_VOCAB_COL ){ @@ -231676,7 +231676,7 @@ static int fts5VocabColumnMethod( if( iCol==1 ){ if( eDetail!=FTS5_DETAIL_NONE ){ const char *z = pCsr->pFts5->pConfig->azCol[pCsr->iCol]; - tdsqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); + sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); } }else if( iCol==2 ){ iVal = pCsr->aDoc[pCsr->iCol]; @@ -231694,7 +231694,7 @@ static int fts5VocabColumnMethod( assert( eType==FTS5_VOCAB_INSTANCE ); switch( iCol ){ case 1: - tdsqlite3_result_int64(pCtx, pCsr->pIter->iRowid); + sqlite3_result_int64(pCtx, pCsr->pIter->iRowid); break; case 2: { int ii = -1; @@ -231705,7 +231705,7 @@ static int fts5VocabColumnMethod( } if( ii>=0 && iipFts5->pConfig->nCol ){ const char *z = pCsr->pFts5->pConfig->azCol[ii]; - tdsqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); + sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); } break; } @@ -231713,14 +231713,14 @@ static int fts5VocabColumnMethod( assert( iCol==3 ); if( eDetail==FTS5_DETAIL_FULL ){ int ii = FTS5_POS2OFFSET(pCsr->iInstPos); - tdsqlite3_result_int(pCtx, ii); + sqlite3_result_int(pCtx, ii); } break; } } } - if( iVal>0 ) tdsqlite3_result_int64(pCtx, iVal); + if( iVal>0 ) sqlite3_result_int64(pCtx, iVal); return SQLITE_OK; } @@ -231730,7 +231730,7 @@ static int fts5VocabColumnMethod( ** rowid should be written to *pRowid. */ static int fts5VocabRowidMethod( - tdsqlite3_vtab_cursor *pCursor, + sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid ){ Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; @@ -231738,8 +231738,8 @@ static int fts5VocabRowidMethod( return SQLITE_OK; } -static int tdsqlite3Fts5VocabInit(Fts5Global *pGlobal, tdsqlite3 *db){ - static const tdsqlite3_module fts5Vocab = { +static int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ + static const sqlite3_module fts5Vocab = { /* iVersion */ 2, /* xCreate */ fts5VocabCreateMethod, /* xConnect */ fts5VocabConnectMethod, @@ -231767,7 +231767,7 @@ static int tdsqlite3Fts5VocabInit(Fts5Global *pGlobal, tdsqlite3 *db){ }; void *p = (void*)pGlobal; - return tdsqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0); + return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0); } @@ -231800,7 +231800,7 @@ static int tdsqlite3Fts5VocabInit(Fts5Global *pGlobal, tdsqlite3 *db){ */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_STMTVTAB) #if !defined(SQLITEINT_H) -/* #include "tdsqlite3ext.h" */ +/* #include "sqlite3ext.h" */ #endif SQLITE_EXTENSION_INIT1 /* #include */ @@ -231808,25 +231808,25 @@ SQLITE_EXTENSION_INIT1 #ifndef SQLITE_OMIT_VIRTUALTABLE -/* stmt_vtab is a subclass of tdsqlite3_vtab which will +/* stmt_vtab is a subclass of sqlite3_vtab which will ** serve as the underlying representation of a stmt virtual table */ typedef struct stmt_vtab stmt_vtab; struct stmt_vtab { - tdsqlite3_vtab base; /* Base class - must be first */ - tdsqlite3 *db; /* Database connection for this stmt vtab */ + sqlite3_vtab base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this stmt vtab */ }; -/* stmt_cursor is a subclass of tdsqlite3_vtab_cursor which will +/* stmt_cursor is a subclass of sqlite3_vtab_cursor which will ** serve as the underlying representation of a cursor that scans ** over rows of the result */ typedef struct stmt_cursor stmt_cursor; struct stmt_cursor { - tdsqlite3_vtab_cursor base; /* Base class - must be first */ - tdsqlite3 *db; /* Database connection for this cursor */ - tdsqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */ - tdsqlite3_int64 iRowid; /* The rowid */ + sqlite3_vtab_cursor base; /* Base class - must be first */ + sqlite3 *db; /* Database connection for this cursor */ + sqlite3_stmt *pStmt; /* Statement cursor is currently pointing at */ + sqlite3_int64 iRowid; /* The rowid */ }; /* @@ -231839,14 +231839,14 @@ struct stmt_cursor { ** ** (1) Allocate the stmt_vtab object and initialize all fields. ** -** (2) Tell SQLite (via the tdsqlite3_declare_vtab() interface) what the +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the ** result set of queries against stmt will look like. */ static int stmtConnect( - tdsqlite3 *db, + sqlite3 *db, void *pAux, int argc, const char *const*argv, - tdsqlite3_vtab **ppVtab, + sqlite3_vtab **ppVtab, char **pzErr ){ stmt_vtab *pNew; @@ -231866,12 +231866,12 @@ static int stmtConnect( #define STMT_COLUMN_MEM 10 /* SQLITE_STMTSTATUS_MEMUSED */ - rc = tdsqlite3_declare_vtab(db, + rc = sqlite3_declare_vtab(db, "CREATE TABLE x(sql,ncol,ro,busy,nscan,nsort,naidx,nstep," "reprep,run,mem)"); if( rc==SQLITE_OK ){ - pNew = tdsqlite3_malloc( sizeof(*pNew) ); - *ppVtab = (tdsqlite3_vtab*)pNew; + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; if( pNew==0 ) return SQLITE_NOMEM; memset(pNew, 0, sizeof(*pNew)); pNew->db = db; @@ -231882,17 +231882,17 @@ static int stmtConnect( /* ** This method is the destructor for stmt_cursor objects. */ -static int stmtDisconnect(tdsqlite3_vtab *pVtab){ - tdsqlite3_free(pVtab); +static int stmtDisconnect(sqlite3_vtab *pVtab){ + sqlite3_free(pVtab); return SQLITE_OK; } /* ** Constructor for a new stmt_cursor object. */ -static int stmtOpen(tdsqlite3_vtab *p, tdsqlite3_vtab_cursor **ppCursor){ +static int stmtOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ stmt_cursor *pCur; - pCur = tdsqlite3_malloc( sizeof(*pCur) ); + pCur = sqlite3_malloc( sizeof(*pCur) ); if( pCur==0 ) return SQLITE_NOMEM; memset(pCur, 0, sizeof(*pCur)); pCur->db = ((stmt_vtab*)p)->db; @@ -231903,8 +231903,8 @@ static int stmtOpen(tdsqlite3_vtab *p, tdsqlite3_vtab_cursor **ppCursor){ /* ** Destructor for a stmt_cursor. */ -static int stmtClose(tdsqlite3_vtab_cursor *cur){ - tdsqlite3_free(cur); +static int stmtClose(sqlite3_vtab_cursor *cur){ + sqlite3_free(cur); return SQLITE_OK; } @@ -231912,10 +231912,10 @@ static int stmtClose(tdsqlite3_vtab_cursor *cur){ /* ** Advance a stmt_cursor to its next row of output. */ -static int stmtNext(tdsqlite3_vtab_cursor *cur){ +static int stmtNext(sqlite3_vtab_cursor *cur){ stmt_cursor *pCur = (stmt_cursor*)cur; pCur->iRowid++; - pCur->pStmt = tdsqlite3_next_stmt(pCur->db, pCur->pStmt); + pCur->pStmt = sqlite3_next_stmt(pCur->db, pCur->pStmt); return SQLITE_OK; } @@ -231924,26 +231924,26 @@ static int stmtNext(tdsqlite3_vtab_cursor *cur){ ** is currently pointing. */ static int stmtColumn( - tdsqlite3_vtab_cursor *cur, /* The cursor */ - tdsqlite3_context *ctx, /* First argument to tdsqlite3_result_...() */ + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ int i /* Which column to return */ ){ stmt_cursor *pCur = (stmt_cursor*)cur; switch( i ){ case STMT_COLUMN_SQL: { - tdsqlite3_result_text(ctx, tdsqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT); + sqlite3_result_text(ctx, sqlite3_sql(pCur->pStmt), -1, SQLITE_TRANSIENT); break; } case STMT_COLUMN_NCOL: { - tdsqlite3_result_int(ctx, tdsqlite3_column_count(pCur->pStmt)); + sqlite3_result_int(ctx, sqlite3_column_count(pCur->pStmt)); break; } case STMT_COLUMN_RO: { - tdsqlite3_result_int(ctx, tdsqlite3_stmt_readonly(pCur->pStmt)); + sqlite3_result_int(ctx, sqlite3_stmt_readonly(pCur->pStmt)); break; } case STMT_COLUMN_BUSY: { - tdsqlite3_result_int(ctx, tdsqlite3_stmt_busy(pCur->pStmt)); + sqlite3_result_int(ctx, sqlite3_stmt_busy(pCur->pStmt)); break; } case STMT_COLUMN_MEM: { @@ -231957,7 +231957,7 @@ static int stmtColumn( case STMT_COLUMN_NSTEP: case STMT_COLUMN_REPREP: case STMT_COLUMN_RUN: { - tdsqlite3_result_int(ctx, tdsqlite3_stmt_status(pCur->pStmt, + sqlite3_result_int(ctx, sqlite3_stmt_status(pCur->pStmt, i-STMT_COLUMN_NSCAN+SQLITE_STMTSTATUS_FULLSCAN_STEP, 0)); break; } @@ -231969,7 +231969,7 @@ static int stmtColumn( ** Return the rowid for the current row. In this implementation, the ** rowid is the same as the output value. */ -static int stmtRowid(tdsqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ +static int stmtRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ stmt_cursor *pCur = (stmt_cursor*)cur; *pRowid = pCur->iRowid; return SQLITE_OK; @@ -231979,7 +231979,7 @@ static int stmtRowid(tdsqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ ** Return TRUE if the cursor has been moved off of the last ** row of output. */ -static int stmtEof(tdsqlite3_vtab_cursor *cur){ +static int stmtEof(sqlite3_vtab_cursor *cur){ stmt_cursor *pCur = (stmt_cursor*)cur; return pCur->pStmt==0; } @@ -231991,9 +231991,9 @@ static int stmtEof(tdsqlite3_vtab_cursor *cur){ ** stmtEof(). */ static int stmtFilter( - tdsqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, - int argc, tdsqlite3_value **argv + int argc, sqlite3_value **argv ){ stmt_cursor *pCur = (stmt_cursor *)pVtabCursor; pCur->pStmt = 0; @@ -232008,8 +232008,8 @@ static int stmtFilter( ** plan. */ static int stmtBestIndex( - tdsqlite3_vtab *tab, - tdsqlite3_index_info *pIdxInfo + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo ){ pIdxInfo->estimatedCost = (double)500; pIdxInfo->estimatedRows = 500; @@ -232020,7 +232020,7 @@ static int stmtBestIndex( ** This following structure defines all the methods for the ** stmt virtual table. */ -static tdsqlite3_module stmtModule = { +static sqlite3_module stmtModule = { 0, /* iVersion */ 0, /* xCreate */ stmtConnect, /* xConnect */ @@ -232049,10 +232049,10 @@ static tdsqlite3_module stmtModule = { #endif /* SQLITE_OMIT_VIRTUALTABLE */ -SQLITE_PRIVATE int tdsqlite3StmtVtabInit(tdsqlite3 *db){ +SQLITE_PRIVATE int sqlite3StmtVtabInit(sqlite3 *db){ int rc = SQLITE_OK; #ifndef SQLITE_OMIT_VIRTUALTABLE - rc = tdsqlite3_create_module(db, "sqlite_stmt", &stmtModule, 0); + rc = sqlite3_create_module(db, "sqlite_stmt", &stmtModule, 0); #endif return rc; } @@ -232061,15 +232061,15 @@ SQLITE_PRIVATE int tdsqlite3StmtVtabInit(tdsqlite3 *db){ #ifdef _WIN32 __declspec(dllexport) #endif -SQLITE_API int tdsqlite3_stmt_init( - tdsqlite3 *db, +SQLITE_API int sqlite3_stmt_init( + sqlite3 *db, char **pzErrMsg, - const tdsqlite3_api_routines *pApi + const sqlite3_api_routines *pApi ){ int rc = SQLITE_OK; SQLITE_EXTENSION_INIT2(pApi); #ifndef SQLITE_OMIT_VIRTUALTABLE - rc = tdsqlite3StmtVtabInit(db); + rc = sqlite3StmtVtabInit(db); #endif return rc; } @@ -232082,5 +232082,5 @@ SQLITE_API int tdsqlite3_stmt_init( #define SQLITE_SOURCE_ID "2020-01-22 18:38:59 f6affdd41608946fcfcea914ece149038a8b25a62bbe719ed2561c649b86alt2" #endif /* Return the source-id for this library */ -SQLITE_API const char *tdsqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } +SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } /************************** End of sqlite3.c ******************************/ diff --git a/protocols/Telegram/tdlib/td/td/generate/auto/td/mtproto/mtproto_api.cpp b/protocols/Telegram/tdlib/td/td/generate/auto/td/mtproto/mtproto_api.cpp index 7e85a47bdd..18c4a565ad 100644 --- a/protocols/Telegram/tdlib/td/td/generate/auto/td/mtproto/mtproto_api.cpp +++ b/protocols/Telegram/tdlib/td/td/generate/auto/td/mtproto/mtproto_api.cpp @@ -149,11 +149,9 @@ object_ptr bad_msg_notification::fetch(TlParser &p) { } bad_msg_notification::bad_msg_notification(TlParser &p) -#define FAIL(error) p.set_error(error) : bad_msg_id_(TlFetchLong::parse(p)) , bad_msg_seqno_(TlFetchInt::parse(p)) , error_code_(TlFetchInt::parse(p)) -#undef FAIL {} void bad_msg_notification::store(TlStorerCalcLength &s) const { @@ -194,12 +192,10 @@ object_ptr bad_server_salt::fetch(TlParser &p) { } bad_server_salt::bad_server_salt(TlParser &p) -#define FAIL(error) p.set_error(error) : bad_msg_id_(TlFetchLong::parse(p)) , bad_msg_seqno_(TlFetchInt::parse(p)) , error_code_(TlFetchInt::parse(p)) , new_server_salt_(TlFetchLong::parse(p)) -#undef FAIL {} void bad_server_salt::store(TlStorerCalcLength &s) const { @@ -244,13 +240,11 @@ object_ptr bind_auth_key_inner::fetch(TlParser &p) { } bind_auth_key_inner::bind_auth_key_inner(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchLong::parse(p)) , temp_auth_key_id_(TlFetchLong::parse(p)) , perm_auth_key_id_(TlFetchLong::parse(p)) , temp_session_id_(TlFetchLong::parse(p)) , expires_at_(TlFetchInt::parse(p)) -#undef FAIL {} void bind_auth_key_inner::store(TlStorerCalcLength &s) const { @@ -297,12 +291,10 @@ object_ptr client_DH_inner_data::fetch(TlParser &p) { } client_DH_inner_data::client_DH_inner_data(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , retry_id_(TlFetchLong::parse(p)) , g_b_(TlFetchString::parse(p)) -#undef FAIL {} void client_DH_inner_data::store(TlStorerCalcLength &s) const { @@ -424,11 +416,9 @@ object_ptr future_salt::fetch(TlParser &p) { } future_salt::future_salt(TlParser &p) -#define FAIL(error) p.set_error(error) : valid_since_(TlFetchInt::parse(p)) , valid_until_(TlFetchInt::parse(p)) , salt_(TlFetchLong::parse(p)) -#undef FAIL {} void future_salt::store(TlStorerCalcLength &s) const { @@ -468,11 +458,9 @@ object_ptr future_salts::fetch(TlParser &p) { } future_salts::future_salts(TlParser &p) -#define FAIL(error) p.set_error(error) : req_msg_id_(TlFetchLong::parse(p)) , now_(TlFetchInt::parse(p)) , salts_(TlFetchVector>::parse(p)) -#undef FAIL {} void future_salts::store(TlStorerCalcLength &s) const { @@ -510,9 +498,7 @@ object_ptr gzip_packed::fetch(TlParser &p) { } gzip_packed::gzip_packed(TlParser &p) -#define FAIL(error) p.set_error(error) : packed_data_(TlFetchString::parse(p)) -#undef FAIL {} void gzip_packed::store(TlStorerCalcLength &s) const { @@ -582,12 +568,10 @@ object_ptr msg_detailed_info::fetch(TlParser &p) { } msg_detailed_info::msg_detailed_info(TlParser &p) -#define FAIL(error) p.set_error(error) : msg_id_(TlFetchLong::parse(p)) , answer_msg_id_(TlFetchLong::parse(p)) , bytes_(TlFetchInt::parse(p)) , status_(TlFetchInt::parse(p)) -#undef FAIL {} void msg_detailed_info::store(TlStorerCalcLength &s) const { @@ -630,11 +614,9 @@ object_ptr msg_new_detailed_info::fetch(TlParser &p) { } msg_new_detailed_info::msg_new_detailed_info(TlParser &p) -#define FAIL(error) p.set_error(error) : answer_msg_id_(TlFetchLong::parse(p)) , bytes_(TlFetchInt::parse(p)) , status_(TlFetchInt::parse(p)) -#undef FAIL {} void msg_new_detailed_info::store(TlStorerCalcLength &s) const { @@ -672,9 +654,7 @@ object_ptr msg_resend_req::fetch(TlParser &p) { } msg_resend_req::msg_resend_req(TlParser &p) -#define FAIL(error) p.set_error(error) : msg_ids_(TlFetchBoxed, 481674261>::parse(p)) -#undef FAIL {} void msg_resend_req::store(TlStorerCalcLength &s) const { @@ -706,9 +686,7 @@ object_ptr msgs_ack::fetch(TlParser &p) { } msgs_ack::msgs_ack(TlParser &p) -#define FAIL(error) p.set_error(error) : msg_ids_(TlFetchBoxed, 481674261>::parse(p)) -#undef FAIL {} void msgs_ack::store(TlStorerCalcLength &s) const { @@ -741,10 +719,8 @@ object_ptr msgs_all_info::fetch(TlParser &p) { } msgs_all_info::msgs_all_info(TlParser &p) -#define FAIL(error) p.set_error(error) : msg_ids_(TlFetchBoxed, 481674261>::parse(p)) , info_(TlFetchString::parse(p)) -#undef FAIL {} void msgs_all_info::store(TlStorerCalcLength &s) const { @@ -780,10 +756,8 @@ object_ptr msgs_state_info::fetch(TlParser &p) { } msgs_state_info::msgs_state_info(TlParser &p) -#define FAIL(error) p.set_error(error) : req_msg_id_(TlFetchLong::parse(p)) , info_(TlFetchString::parse(p)) -#undef FAIL {} void msgs_state_info::store(TlStorerCalcLength &s) const { @@ -818,9 +792,7 @@ object_ptr msgs_state_req::fetch(TlParser &p) { } msgs_state_req::msgs_state_req(TlParser &p) -#define FAIL(error) p.set_error(error) : msg_ids_(TlFetchBoxed, 481674261>::parse(p)) -#undef FAIL {} void msgs_state_req::store(TlStorerCalcLength &s) const { @@ -854,11 +826,9 @@ object_ptr new_session_created::fetch(TlParser &p) { } new_session_created::new_session_created(TlParser &p) -#define FAIL(error) p.set_error(error) : first_msg_id_(TlFetchLong::parse(p)) , unique_id_(TlFetchLong::parse(p)) , server_salt_(TlFetchLong::parse(p)) -#undef FAIL {} void new_session_created::store(TlStorerCalcLength &s) const { @@ -916,7 +886,6 @@ object_ptr p_q_inner_data_dc::fetch(TlParser &p) { } p_q_inner_data_dc::p_q_inner_data_dc(TlParser &p) -#define FAIL(error) p.set_error(error) : pq_(TlFetchString::parse(p)) , p_(TlFetchString::parse(p)) , q_(TlFetchString::parse(p)) @@ -924,7 +893,6 @@ p_q_inner_data_dc::p_q_inner_data_dc(TlParser &p) , server_nonce_(TlFetchInt128::parse(p)) , new_nonce_(TlFetchInt256::parse(p)) , dc_(TlFetchInt::parse(p)) -#undef FAIL {} void p_q_inner_data_dc::store(TlStorerCalcLength &s) const { @@ -981,7 +949,6 @@ object_ptr p_q_inner_data_temp_dc::fetch(TlParser &p) { } p_q_inner_data_temp_dc::p_q_inner_data_temp_dc(TlParser &p) -#define FAIL(error) p.set_error(error) : pq_(TlFetchString::parse(p)) , p_(TlFetchString::parse(p)) , q_(TlFetchString::parse(p)) @@ -990,7 +957,6 @@ p_q_inner_data_temp_dc::p_q_inner_data_temp_dc(TlParser &p) , new_nonce_(TlFetchInt256::parse(p)) , dc_(TlFetchInt::parse(p)) , expires_in_(TlFetchInt::parse(p)) -#undef FAIL {} void p_q_inner_data_temp_dc::store(TlStorerCalcLength &s) const { @@ -1044,10 +1010,8 @@ object_ptr pong::fetch(TlParser &p) { } pong::pong(TlParser &p) -#define FAIL(error) p.set_error(error) : msg_id_(TlFetchLong::parse(p)) , ping_id_(TlFetchLong::parse(p)) -#undef FAIL {} void pong::store(TlStorerCalcLength &s) const { @@ -1083,10 +1047,8 @@ object_ptr rsa_public_key::fetch(TlParser &p) { } rsa_public_key::rsa_public_key(TlParser &p) -#define FAIL(error) p.set_error(error) : n_(TlFetchString::parse(p)) , e_(TlFetchString::parse(p)) -#undef FAIL {} void rsa_public_key::store(TlStorerCalcLength &s) const { @@ -1124,12 +1086,10 @@ object_ptr resPQ::fetch(TlParser &p) { } resPQ::resPQ(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , pq_(TlFetchString::parse(p)) , server_public_key_fingerprints_(TlFetchBoxed, 481674261>::parse(p)) -#undef FAIL {} void resPQ::store(TlStorerCalcLength &s) const { @@ -1230,11 +1190,9 @@ object_ptr rpc_answer_dropped::fetch(TlParser &p) { } rpc_answer_dropped::rpc_answer_dropped(TlParser &p) -#define FAIL(error) p.set_error(error) : msg_id_(TlFetchLong::parse(p)) , seq_no_(TlFetchInt::parse(p)) , bytes_(TlFetchInt::parse(p)) -#undef FAIL {} void rpc_answer_dropped::store(TlStorerCalcLength &s) const { @@ -1273,10 +1231,8 @@ object_ptr rpc_error::fetch(TlParser &p) { } rpc_error::rpc_error(TlParser &p) -#define FAIL(error) p.set_error(error) : error_code_(TlFetchInt::parse(p)) , error_message_(TlFetchString::parse(p)) -#undef FAIL {} void rpc_error::store(TlStorerCalcLength &s) const { @@ -1313,11 +1269,9 @@ object_ptr server_DH_params_ok::fetch(TlParser &p) { } server_DH_params_ok::server_DH_params_ok(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , encrypted_answer_(TlFetchString::parse(p)) -#undef FAIL {} void server_DH_params_ok::store(TlStorerCalcLength &s) const { @@ -1360,14 +1314,12 @@ object_ptr server_DH_inner_data::fetch(TlParser &p) { } server_DH_inner_data::server_DH_inner_data(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , g_(TlFetchInt::parse(p)) , dh_prime_(TlFetchString::parse(p)) , g_a_(TlFetchString::parse(p)) , server_time_(TlFetchInt::parse(p)) -#undef FAIL {} void server_DH_inner_data::store(TlStorerCalcLength &s) const { @@ -1432,11 +1384,9 @@ object_ptr dh_gen_ok::fetch(TlParser &p) { } dh_gen_ok::dh_gen_ok(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , new_nonce_hash1_(TlFetchInt128::parse(p)) -#undef FAIL {} void dh_gen_ok::store(TlStorerCalcLength &s) const { @@ -1476,11 +1426,9 @@ object_ptr dh_gen_retry::fetch(TlParser &p) { } dh_gen_retry::dh_gen_retry(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , new_nonce_hash2_(TlFetchInt128::parse(p)) -#undef FAIL {} void dh_gen_retry::store(TlStorerCalcLength &s) const { @@ -1520,11 +1468,9 @@ object_ptr dh_gen_fail::fetch(TlParser &p) { } dh_gen_fail::dh_gen_fail(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , new_nonce_hash3_(TlFetchInt128::parse(p)) -#undef FAIL {} void dh_gen_fail::store(TlStorerCalcLength &s) const { @@ -1591,9 +1537,7 @@ object_ptr get_future_salts::fetch(TlParser &p) { } get_future_salts::get_future_salts(TlParser &p) -#define FAIL(error) p.set_error(error) : num_(TlFetchInt::parse(p)) -#undef FAIL {} void get_future_salts::store(TlStorerCalcLength &s) const { @@ -1635,11 +1579,9 @@ object_ptr http_wait::fetch(TlParser &p) { } http_wait::http_wait(TlParser &p) -#define FAIL(error) p.set_error(error) : max_delay_(TlFetchInt::parse(p)) , wait_after_(TlFetchInt::parse(p)) , max_wait_(TlFetchInt::parse(p)) -#undef FAIL {} void http_wait::store(TlStorerCalcLength &s) const { @@ -1686,10 +1628,8 @@ object_ptr ping_delay_disconnect::fetch(TlParser &p) { } ping_delay_disconnect::ping_delay_disconnect(TlParser &p) -#define FAIL(error) p.set_error(error) : ping_id_(TlFetchLong::parse(p)) , disconnect_delay_(TlFetchInt::parse(p)) -#undef FAIL {} void ping_delay_disconnect::store(TlStorerCalcLength &s) const { @@ -1737,14 +1677,12 @@ object_ptr req_DH_params::fetch(TlParser &p) { } req_DH_params::req_DH_params(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , p_(TlFetchString::parse(p)) , q_(TlFetchString::parse(p)) , public_key_fingerprint_(TlFetchLong::parse(p)) , encrypted_data_(TlFetchString::parse(p)) -#undef FAIL {} void req_DH_params::store(TlStorerCalcLength &s) const { @@ -1799,9 +1737,7 @@ object_ptr req_pq_multi::fetch(TlParser &p) { } req_pq_multi::req_pq_multi(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) -#undef FAIL {} void req_pq_multi::store(TlStorerCalcLength &s) const { @@ -1841,9 +1777,7 @@ object_ptr rpc_drop_answer::fetch(TlParser &p) { } rpc_drop_answer::rpc_drop_answer(TlParser &p) -#define FAIL(error) p.set_error(error) : req_msg_id_(TlFetchLong::parse(p)) -#undef FAIL {} void rpc_drop_answer::store(TlStorerCalcLength &s) const { @@ -1885,11 +1819,9 @@ object_ptr set_client_DH_params::fetch(TlParser &p) { } set_client_DH_params::set_client_DH_params(TlParser &p) -#define FAIL(error) p.set_error(error) : nonce_(TlFetchInt128::parse(p)) , server_nonce_(TlFetchInt128::parse(p)) , encrypted_data_(TlFetchString::parse(p)) -#undef FAIL {} void set_client_DH_params::store(TlStorerCalcLength &s) const { diff --git a/protocols/Telegram/tdlib/td/td/generate/auto/td/mtproto/mtproto_api.h b/protocols/Telegram/tdlib/td/td/generate/auto/td/mtproto/mtproto_api.h index 457a9a9642..71fa8532b0 100644 --- a/protocols/Telegram/tdlib/td/td/generate/auto/td/mtproto/mtproto_api.h +++ b/protocols/Telegram/tdlib/td/td/generate/auto/td/mtproto/mtproto_api.h @@ -68,56 +68,6 @@ std::string to_string(const std::vector> &values) { return result; } -class BadMsgNotification; - -class bind_auth_key_inner; - -class client_DH_inner_data; - -class DestroyAuthKeyRes; - -class future_salt; - -class future_salts; - -class gzip_packed; - -class dummyHttpWait; - -class MsgDetailedInfo; - -class msg_resend_req; - -class msgs_ack; - -class msgs_all_info; - -class msgs_state_info; - -class msgs_state_req; - -class new_session_created; - -class P_Q_inner_data; - -class pong; - -class rsa_public_key; - -class resPQ; - -class RpcDropAnswer; - -class rpc_error; - -class server_DH_params_ok; - -class server_DH_inner_data; - -class Set_client_DH_params_answer; - -class Object; - class Object: public TlObject { public: @@ -137,6 +87,10 @@ class BadMsgNotification: public Object { }; class bad_msg_notification final : public BadMsgNotification { + std::int32_t get_id() const final { + return ID; + } + public: int64 bad_msg_id_; int32 bad_msg_seqno_; @@ -145,9 +99,6 @@ class bad_msg_notification final : public BadMsgNotification { bad_msg_notification(int64 bad_msg_id_, int32 bad_msg_seqno_, int32 error_code_); static const std::int32_t ID = -1477445615; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -161,6 +112,10 @@ class bad_msg_notification final : public BadMsgNotification { }; class bad_server_salt final : public BadMsgNotification { + std::int32_t get_id() const final { + return ID; + } + public: int64 bad_msg_id_; int32 bad_msg_seqno_; @@ -170,9 +125,6 @@ class bad_server_salt final : public BadMsgNotification { bad_server_salt(int64 bad_msg_id_, int32 bad_msg_seqno_, int32 error_code_, int64 new_server_salt_); static const std::int32_t ID = -307542917; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -186,6 +138,10 @@ class bad_server_salt final : public BadMsgNotification { }; class bind_auth_key_inner final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: int64 nonce_; int64 temp_auth_key_id_; @@ -196,9 +152,6 @@ class bind_auth_key_inner final : public Object { bind_auth_key_inner(int64 nonce_, int64 temp_auth_key_id_, int64 perm_auth_key_id_, int64 temp_session_id_, int32 expires_at_); static const std::int32_t ID = 1973679973; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -212,6 +165,10 @@ class bind_auth_key_inner final : public Object { }; class client_DH_inner_data final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -221,9 +178,6 @@ class client_DH_inner_data final : public Object { client_DH_inner_data(UInt128 const &nonce_, UInt128 const &server_nonce_, int64 retry_id_, string const &g_b_); static const std::int32_t ID = 1715713620; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -243,13 +197,14 @@ class DestroyAuthKeyRes: public Object { }; class destroy_auth_key_ok final : public DestroyAuthKeyRes { - public: - - static const std::int32_t ID = -161422892; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -161422892; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -260,13 +215,14 @@ class destroy_auth_key_ok final : public DestroyAuthKeyRes { }; class destroy_auth_key_none final : public DestroyAuthKeyRes { - public: - - static const std::int32_t ID = 178201177; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = 178201177; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -277,13 +233,14 @@ class destroy_auth_key_none final : public DestroyAuthKeyRes { }; class destroy_auth_key_fail final : public DestroyAuthKeyRes { - public: - - static const std::int32_t ID = -368010477; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -368010477; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -294,6 +251,10 @@ class destroy_auth_key_fail final : public DestroyAuthKeyRes { }; class future_salt final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: int32 valid_since_; int32 valid_until_; @@ -302,9 +263,6 @@ class future_salt final : public Object { future_salt(int32 valid_since_, int32 valid_until_, int64 salt_); static const std::int32_t ID = 155834844; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -317,7 +275,13 @@ class future_salt final : public Object { void store(TlStorerToString &s, const char *field_name) const final; }; +class future_salt; + class future_salts final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: int64 req_msg_id_; int32 now_; @@ -326,9 +290,6 @@ class future_salts final : public Object { future_salts(int64 req_msg_id_, int32 now_, array> &&salts_); static const std::int32_t ID = -1370486635; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -342,15 +303,16 @@ class future_salts final : public Object { }; class gzip_packed final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: string packed_data_; explicit gzip_packed(string const &packed_data_); static const std::int32_t ID = 812830625; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -364,13 +326,14 @@ class gzip_packed final : public Object { }; class dummyHttpWait final : public Object { - public: - - static const std::int32_t ID = -919090642; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -919090642; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -387,6 +350,10 @@ class MsgDetailedInfo: public Object { }; class msg_detailed_info final : public MsgDetailedInfo { + std::int32_t get_id() const final { + return ID; + } + public: int64 msg_id_; int64 answer_msg_id_; @@ -396,9 +363,6 @@ class msg_detailed_info final : public MsgDetailedInfo { msg_detailed_info(int64 msg_id_, int64 answer_msg_id_, int32 bytes_, int32 status_); static const std::int32_t ID = 661470918; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -412,6 +376,10 @@ class msg_detailed_info final : public MsgDetailedInfo { }; class msg_new_detailed_info final : public MsgDetailedInfo { + std::int32_t get_id() const final { + return ID; + } + public: int64 answer_msg_id_; int32 bytes_; @@ -420,9 +388,6 @@ class msg_new_detailed_info final : public MsgDetailedInfo { msg_new_detailed_info(int64 answer_msg_id_, int32 bytes_, int32 status_); static const std::int32_t ID = -2137147681; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -436,15 +401,16 @@ class msg_new_detailed_info final : public MsgDetailedInfo { }; class msg_resend_req final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: array msg_ids_; explicit msg_resend_req(array &&msg_ids_); static const std::int32_t ID = 2105940488; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -458,15 +424,16 @@ class msg_resend_req final : public Object { }; class msgs_ack final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: array msg_ids_; explicit msgs_ack(array &&msg_ids_); static const std::int32_t ID = 1658238041; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -480,6 +447,10 @@ class msgs_ack final : public Object { }; class msgs_all_info final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: array msg_ids_; string info_; @@ -487,9 +458,6 @@ class msgs_all_info final : public Object { msgs_all_info(array &&msg_ids_, string const &info_); static const std::int32_t ID = -1933520591; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -503,6 +471,10 @@ class msgs_all_info final : public Object { }; class msgs_state_info final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: int64 req_msg_id_; string info_; @@ -510,9 +482,6 @@ class msgs_state_info final : public Object { msgs_state_info(int64 req_msg_id_, string const &info_); static const std::int32_t ID = 81704317; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -526,15 +495,16 @@ class msgs_state_info final : public Object { }; class msgs_state_req final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: array msg_ids_; explicit msgs_state_req(array &&msg_ids_); static const std::int32_t ID = -630588590; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -548,6 +518,10 @@ class msgs_state_req final : public Object { }; class new_session_created final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: int64 first_msg_id_; int64 unique_id_; @@ -556,9 +530,6 @@ class new_session_created final : public Object { new_session_created(int64 first_msg_id_, int64 unique_id_, int64 server_salt_); static const std::int32_t ID = -1631450872; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -578,6 +549,10 @@ class P_Q_inner_data: public Object { }; class p_q_inner_data_dc final : public P_Q_inner_data { + std::int32_t get_id() const final { + return ID; + } + public: string pq_; string p_; @@ -590,9 +565,6 @@ class p_q_inner_data_dc final : public P_Q_inner_data { p_q_inner_data_dc(string const &pq_, string const &p_, string const &q_, UInt128 const &nonce_, UInt128 const &server_nonce_, UInt256 const &new_nonce_, int32 dc_); static const std::int32_t ID = -1443537003; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -606,6 +578,10 @@ class p_q_inner_data_dc final : public P_Q_inner_data { }; class p_q_inner_data_temp_dc final : public P_Q_inner_data { + std::int32_t get_id() const final { + return ID; + } + public: string pq_; string p_; @@ -619,9 +595,6 @@ class p_q_inner_data_temp_dc final : public P_Q_inner_data { p_q_inner_data_temp_dc(string const &pq_, string const &p_, string const &q_, UInt128 const &nonce_, UInt128 const &server_nonce_, UInt256 const &new_nonce_, int32 dc_, int32 expires_in_); static const std::int32_t ID = 1459478408; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -635,6 +608,10 @@ class p_q_inner_data_temp_dc final : public P_Q_inner_data { }; class pong final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: int64 msg_id_; int64 ping_id_; @@ -642,9 +619,6 @@ class pong final : public Object { pong(int64 msg_id_, int64 ping_id_); static const std::int32_t ID = 880243653; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -658,6 +632,10 @@ class pong final : public Object { }; class rsa_public_key final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: string n_; string e_; @@ -665,9 +643,6 @@ class rsa_public_key final : public Object { rsa_public_key(string const &n_, string const &e_); static const std::int32_t ID = 2048510838; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -681,6 +656,10 @@ class rsa_public_key final : public Object { }; class resPQ final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -690,9 +669,6 @@ class resPQ final : public Object { resPQ(UInt128 const &nonce_, UInt128 const &server_nonce_, string const &pq_, array &&server_public_key_fingerprints_); static const std::int32_t ID = 85337187; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -712,13 +688,14 @@ class RpcDropAnswer: public Object { }; class rpc_answer_unknown final : public RpcDropAnswer { - public: - - static const std::int32_t ID = 1579864942; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = 1579864942; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -729,13 +706,14 @@ class rpc_answer_unknown final : public RpcDropAnswer { }; class rpc_answer_dropped_running final : public RpcDropAnswer { - public: - - static const std::int32_t ID = -847714938; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -847714938; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -746,6 +724,10 @@ class rpc_answer_dropped_running final : public RpcDropAnswer { }; class rpc_answer_dropped final : public RpcDropAnswer { + std::int32_t get_id() const final { + return ID; + } + public: int64 msg_id_; int32 seq_no_; @@ -754,9 +736,6 @@ class rpc_answer_dropped final : public RpcDropAnswer { rpc_answer_dropped(int64 msg_id_, int32 seq_no_, int32 bytes_); static const std::int32_t ID = -1539647305; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -770,6 +749,10 @@ class rpc_answer_dropped final : public RpcDropAnswer { }; class rpc_error final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: int32 error_code_; string error_message_; @@ -777,9 +760,6 @@ class rpc_error final : public Object { rpc_error(int32 error_code_, string const &error_message_); static const std::int32_t ID = 558156313; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -793,6 +773,10 @@ class rpc_error final : public Object { }; class server_DH_params_ok final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -801,9 +785,6 @@ class server_DH_params_ok final : public Object { server_DH_params_ok(UInt128 const &nonce_, UInt128 const &server_nonce_, string const &encrypted_answer_); static const std::int32_t ID = -790100132; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -817,6 +798,10 @@ class server_DH_params_ok final : public Object { }; class server_DH_inner_data final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -828,9 +813,6 @@ class server_DH_inner_data final : public Object { server_DH_inner_data(UInt128 const &nonce_, UInt128 const &server_nonce_, int32 g_, string const &dh_prime_, string const &g_a_, int32 server_time_); static const std::int32_t ID = -1249309254; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -850,6 +832,10 @@ class Set_client_DH_params_answer: public Object { }; class dh_gen_ok final : public Set_client_DH_params_answer { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -858,9 +844,6 @@ class dh_gen_ok final : public Set_client_DH_params_answer { dh_gen_ok(UInt128 const &nonce_, UInt128 const &server_nonce_, UInt128 const &new_nonce_hash1_); static const std::int32_t ID = 1003222836; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -874,6 +857,10 @@ class dh_gen_ok final : public Set_client_DH_params_answer { }; class dh_gen_retry final : public Set_client_DH_params_answer { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -882,9 +869,6 @@ class dh_gen_retry final : public Set_client_DH_params_answer { dh_gen_retry(UInt128 const &nonce_, UInt128 const &server_nonce_, UInt128 const &new_nonce_hash2_); static const std::int32_t ID = 1188831161; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -898,6 +882,10 @@ class dh_gen_retry final : public Set_client_DH_params_answer { }; class dh_gen_fail final : public Set_client_DH_params_answer { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -906,9 +894,6 @@ class dh_gen_fail final : public Set_client_DH_params_answer { dh_gen_fail(UInt128 const &nonce_, UInt128 const &server_nonce_, UInt128 const &new_nonce_hash3_); static const std::int32_t ID = -1499615742; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -921,14 +906,17 @@ class dh_gen_fail final : public Set_client_DH_params_answer { void store(TlStorerToString &s, const char *field_name) const final; }; -class destroy_auth_key final : public Function { - public: +class DestroyAuthKeyRes; - static const std::int32_t ID = -784117408; +class destroy_auth_key final : public Function { std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -784117408; + using ReturnType = object_ptr; static object_ptr fetch(TlParser &p); @@ -942,16 +930,19 @@ class destroy_auth_key final : public Function { static ReturnType fetch_result(TlParser &p); }; +class future_salts; + class get_future_salts final : public Function { + std::int32_t get_id() const final { + return ID; + } + public: int32 num_; explicit get_future_salts(int32 num_); static const std::int32_t ID = -1188971260; - std::int32_t get_id() const final { - return ID; - } using ReturnType = object_ptr; @@ -968,7 +959,13 @@ class get_future_salts final : public Function { static ReturnType fetch_result(TlParser &p); }; +class dummyHttpWait; + class http_wait final : public Function { + std::int32_t get_id() const final { + return ID; + } + public: int32 max_delay_; int32 wait_after_; @@ -977,9 +974,6 @@ class http_wait final : public Function { http_wait(int32 max_delay_, int32 wait_after_, int32 max_wait_); static const std::int32_t ID = -1835453025; - std::int32_t get_id() const final { - return ID; - } using ReturnType = object_ptr; @@ -996,7 +990,13 @@ class http_wait final : public Function { static ReturnType fetch_result(TlParser &p); }; +class pong; + class ping_delay_disconnect final : public Function { + std::int32_t get_id() const final { + return ID; + } + public: int64 ping_id_; int32 disconnect_delay_; @@ -1004,9 +1004,6 @@ class ping_delay_disconnect final : public Function { ping_delay_disconnect(int64 ping_id_, int32 disconnect_delay_); static const std::int32_t ID = -213746804; - std::int32_t get_id() const final { - return ID; - } using ReturnType = object_ptr; @@ -1023,7 +1020,13 @@ class ping_delay_disconnect final : public Function { static ReturnType fetch_result(TlParser &p); }; +class server_DH_params_ok; + class req_DH_params final : public Function { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -1035,9 +1038,6 @@ class req_DH_params final : public Function { req_DH_params(UInt128 const &nonce_, UInt128 const &server_nonce_, string const &p_, string const &q_, int64 public_key_fingerprint_, string const &encrypted_data_); static const std::int32_t ID = -686627650; - std::int32_t get_id() const final { - return ID; - } using ReturnType = object_ptr; @@ -1054,16 +1054,19 @@ class req_DH_params final : public Function { static ReturnType fetch_result(TlParser &p); }; +class resPQ; + class req_pq_multi final : public Function { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; explicit req_pq_multi(UInt128 const &nonce_); static const std::int32_t ID = -1099002127; - std::int32_t get_id() const final { - return ID; - } using ReturnType = object_ptr; @@ -1080,16 +1083,19 @@ class req_pq_multi final : public Function { static ReturnType fetch_result(TlParser &p); }; +class RpcDropAnswer; + class rpc_drop_answer final : public Function { + std::int32_t get_id() const final { + return ID; + } + public: int64 req_msg_id_; explicit rpc_drop_answer(int64 req_msg_id_); static const std::int32_t ID = 1491380032; - std::int32_t get_id() const final { - return ID; - } using ReturnType = object_ptr; @@ -1106,7 +1112,13 @@ class rpc_drop_answer final : public Function { static ReturnType fetch_result(TlParser &p); }; +class Set_client_DH_params_answer; + class set_client_DH_params final : public Function { + std::int32_t get_id() const final { + return ID; + } + public: UInt128 nonce_; UInt128 server_nonce_; @@ -1115,9 +1127,6 @@ class set_client_DH_params final : public Function { set_client_DH_params(UInt128 const &nonce_, UInt128 const &server_nonce_, string const &encrypted_data_); static const std::int32_t ID = -184262881; - std::int32_t get_id() const final { - return ID; - } using ReturnType = object_ptr; diff --git a/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/secret_api.cpp b/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/secret_api.cpp index 6dbfc94299..3820b5f488 100644 --- a/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/secret_api.cpp +++ b/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/secret_api.cpp @@ -248,12 +248,10 @@ object_ptr decryptedMessage8::fetch(TlParser &p) { } decryptedMessage8::decryptedMessage8(TlParser &p) -#define FAIL(error) p.set_error(error) : random_id_(TlFetchLong::parse(p)) , random_bytes_(TlFetchBytes::parse(p)) , message_(TlFetchString::parse(p)) , media_(TlFetchObject::parse(p)) -#undef FAIL {} void decryptedMessage8::store(TlStorerCalcLength &s) const { @@ -296,11 +294,9 @@ object_ptr decryptedMessageService8::fetch(TlParser &p) { } decryptedMessageService8::decryptedMessageService8(TlParser &p) -#define FAIL(error) p.set_error(error) : random_id_(TlFetchLong::parse(p)) , random_bytes_(TlFetchBytes::parse(p)) , action_(TlFetchObject::parse(p)) -#undef FAIL {} void decryptedMessageService8::store(TlStorerCalcLength &s) const { @@ -341,12 +337,10 @@ object_ptr decryptedMessage23::fetch(TlParser &p) { } decryptedMessage23::decryptedMessage23(TlParser &p) -#define FAIL(error) p.set_error(error) : random_id_(TlFetchLong::parse(p)) , ttl_(TlFetchInt::parse(p)) , message_(TlFetchString::parse(p)) , media_(TlFetchObject::parse(p)) -#undef FAIL {} void decryptedMessage23::store(TlStorerCalcLength &s) const { @@ -388,10 +382,8 @@ object_ptr decryptedMessageService::fetch(TlParser &p) { } decryptedMessageService::decryptedMessageService(TlParser &p) -#define FAIL(error) p.set_error(error) : random_id_(TlFetchLong::parse(p)) , action_(TlFetchObject::parse(p)) -#undef FAIL {} void decryptedMessageService::store(TlStorerCalcLength &s) const { @@ -531,7 +523,7 @@ object_ptr decryptedMessage::fetch(TlParser &p) { object_ptr res = make_tl_object(); int32 var0; if ((var0 = res->flags_ = TlFetchInt::parse(p)) < 0) { FAIL("Variable of type # can't be negative"); } - if (var0 & 32) { res->silent_ = TlFetchTrue::parse(p); } + res->silent_ = (var0 & 32) != 0; res->random_id_ = TlFetchLong::parse(p); res->ttl_ = TlFetchInt::parse(p); res->message_ = TlFetchString::parse(p); @@ -578,6 +570,7 @@ void decryptedMessage::store(TlStorerToString &s, const char *field_name) const s.store_class_begin(field_name, "decryptedMessage"); int32 var0; s.store_field("flags", (var0 = flags_)); + if (var0 & 32) { s.store_field("silent", true); } s.store_field("random_id", random_id_); s.store_field("ttl", ttl_); s.store_field("message", message_); @@ -637,9 +630,7 @@ object_ptr decryptedMessageActionSetMessageTTL::fetch(Tl } decryptedMessageActionSetMessageTTL::decryptedMessageActionSetMessageTTL(TlParser &p) -#define FAIL(error) p.set_error(error) : ttl_seconds_(TlFetchInt::parse(p)) -#undef FAIL {} void decryptedMessageActionSetMessageTTL::store(TlStorerCalcLength &s) const { @@ -671,9 +662,7 @@ object_ptr decryptedMessageActionReadMessages::fetch(TlP } decryptedMessageActionReadMessages::decryptedMessageActionReadMessages(TlParser &p) -#define FAIL(error) p.set_error(error) : random_ids_(TlFetchBoxed, 481674261>::parse(p)) -#undef FAIL {} void decryptedMessageActionReadMessages::store(TlStorerCalcLength &s) const { @@ -705,9 +694,7 @@ object_ptr decryptedMessageActionDeleteMessages::fetch(T } decryptedMessageActionDeleteMessages::decryptedMessageActionDeleteMessages(TlParser &p) -#define FAIL(error) p.set_error(error) : random_ids_(TlFetchBoxed, 481674261>::parse(p)) -#undef FAIL {} void decryptedMessageActionDeleteMessages::store(TlStorerCalcLength &s) const { @@ -739,9 +726,7 @@ object_ptr decryptedMessageActionScreenshotMessages::fet } decryptedMessageActionScreenshotMessages::decryptedMessageActionScreenshotMessages(TlParser &p) -#define FAIL(error) p.set_error(error) : random_ids_(TlFetchBoxed, 481674261>::parse(p)) -#undef FAIL {} void decryptedMessageActionScreenshotMessages::store(TlStorerCalcLength &s) const { @@ -795,10 +780,8 @@ object_ptr decryptedMessageActionResend::fetch(TlParser } decryptedMessageActionResend::decryptedMessageActionResend(TlParser &p) -#define FAIL(error) p.set_error(error) : start_seq_no_(TlFetchInt::parse(p)) , end_seq_no_(TlFetchInt::parse(p)) -#undef FAIL {} void decryptedMessageActionResend::store(TlStorerCalcLength &s) const { @@ -833,9 +816,7 @@ object_ptr decryptedMessageActionNotifyLayer::fetch(TlPa } decryptedMessageActionNotifyLayer::decryptedMessageActionNotifyLayer(TlParser &p) -#define FAIL(error) p.set_error(error) : layer_(TlFetchInt::parse(p)) -#undef FAIL {} void decryptedMessageActionNotifyLayer::store(TlStorerCalcLength &s) const { @@ -867,9 +848,7 @@ object_ptr decryptedMessageActionTyping::fetch(TlParser } decryptedMessageActionTyping::decryptedMessageActionTyping(TlParser &p) -#define FAIL(error) p.set_error(error) : action_(TlFetchObject::parse(p)) -#undef FAIL {} void decryptedMessageActionTyping::store(TlStorerCalcLength &s) const { @@ -902,10 +881,8 @@ object_ptr decryptedMessageActionRequestKey::fetch(TlPar } decryptedMessageActionRequestKey::decryptedMessageActionRequestKey(TlParser &p) -#define FAIL(error) p.set_error(error) : exchange_id_(TlFetchLong::parse(p)) , g_a_(TlFetchBytes::parse(p)) -#undef FAIL {} void decryptedMessageActionRequestKey::store(TlStorerCalcLength &s) const { @@ -942,11 +919,9 @@ object_ptr decryptedMessageActionAcceptKey::fetch(TlPars } decryptedMessageActionAcceptKey::decryptedMessageActionAcceptKey(TlParser &p) -#define FAIL(error) p.set_error(error) : exchange_id_(TlFetchLong::parse(p)) , g_b_(TlFetchBytes::parse(p)) , key_fingerprint_(TlFetchLong::parse(p)) -#undef FAIL {} void decryptedMessageActionAcceptKey::store(TlStorerCalcLength &s) const { @@ -984,9 +959,7 @@ object_ptr decryptedMessageActionAbortKey::fetch(TlParse } decryptedMessageActionAbortKey::decryptedMessageActionAbortKey(TlParser &p) -#define FAIL(error) p.set_error(error) : exchange_id_(TlFetchLong::parse(p)) -#undef FAIL {} void decryptedMessageActionAbortKey::store(TlStorerCalcLength &s) const { @@ -1019,10 +992,8 @@ object_ptr decryptedMessageActionCommitKey::fetch(TlPars } decryptedMessageActionCommitKey::decryptedMessageActionCommitKey(TlParser &p) -#define FAIL(error) p.set_error(error) : exchange_id_(TlFetchLong::parse(p)) , key_fingerprint_(TlFetchLong::parse(p)) -#undef FAIL {} void decryptedMessageActionCommitKey::store(TlStorerCalcLength &s) const { @@ -1082,13 +1053,11 @@ object_ptr decryptedMessageLayer::fetch(TlParser &p) { } decryptedMessageLayer::decryptedMessageLayer(TlParser &p) -#define FAIL(error) p.set_error(error) : random_bytes_(TlFetchBytes::parse(p)) , layer_(TlFetchInt::parse(p)) , in_seq_no_(TlFetchInt::parse(p)) , out_seq_no_(TlFetchInt::parse(p)) , message_(TlFetchObject::parse(p)) -#undef FAIL {} void decryptedMessageLayer::store(TlStorerCalcLength &s) const { @@ -1202,7 +1171,6 @@ object_ptr decryptedMessageMediaPhoto8::fetch(TlParser &p } decryptedMessageMediaPhoto8::decryptedMessageMediaPhoto8(TlParser &p) -#define FAIL(error) p.set_error(error) : thumb_(TlFetchBytes::parse(p)) , thumb_w_(TlFetchInt::parse(p)) , thumb_h_(TlFetchInt::parse(p)) @@ -1211,7 +1179,6 @@ decryptedMessageMediaPhoto8::decryptedMessageMediaPhoto8(TlParser &p) , size_(TlFetchInt::parse(p)) , key_(TlFetchBytes::parse(p)) , iv_(TlFetchBytes::parse(p)) -#undef FAIL {} void decryptedMessageMediaPhoto8::store(TlStorerCalcLength &s) const { @@ -1272,7 +1239,6 @@ object_ptr decryptedMessageMediaVideo8::fetch(TlParser &p } decryptedMessageMediaVideo8::decryptedMessageMediaVideo8(TlParser &p) -#define FAIL(error) p.set_error(error) : thumb_(TlFetchBytes::parse(p)) , thumb_w_(TlFetchInt::parse(p)) , thumb_h_(TlFetchInt::parse(p)) @@ -1282,7 +1248,6 @@ decryptedMessageMediaVideo8::decryptedMessageMediaVideo8(TlParser &p) , size_(TlFetchInt::parse(p)) , key_(TlFetchBytes::parse(p)) , iv_(TlFetchBytes::parse(p)) -#undef FAIL {} void decryptedMessageMediaVideo8::store(TlStorerCalcLength &s) const { @@ -1339,10 +1304,8 @@ object_ptr decryptedMessageMediaGeoPoint::fetch(TlParser } decryptedMessageMediaGeoPoint::decryptedMessageMediaGeoPoint(TlParser &p) -#define FAIL(error) p.set_error(error) : lat_(TlFetchDouble::parse(p)) , long_(TlFetchDouble::parse(p)) -#undef FAIL {} void decryptedMessageMediaGeoPoint::store(TlStorerCalcLength &s) const { @@ -1380,12 +1343,10 @@ object_ptr decryptedMessageMediaContact::fetch(TlParser & } decryptedMessageMediaContact::decryptedMessageMediaContact(TlParser &p) -#define FAIL(error) p.set_error(error) : phone_number_(TlFetchString::parse(p)) , first_name_(TlFetchString::parse(p)) , last_name_(TlFetchString::parse(p)) , user_id_(TlFetchInt::parse(p)) -#undef FAIL {} void decryptedMessageMediaContact::store(TlStorerCalcLength &s) const { @@ -1433,7 +1394,6 @@ object_ptr decryptedMessageMediaDocument8::fetch(TlParser } decryptedMessageMediaDocument8::decryptedMessageMediaDocument8(TlParser &p) -#define FAIL(error) p.set_error(error) : thumb_(TlFetchBytes::parse(p)) , thumb_w_(TlFetchInt::parse(p)) , thumb_h_(TlFetchInt::parse(p)) @@ -1442,7 +1402,6 @@ decryptedMessageMediaDocument8::decryptedMessageMediaDocument8(TlParser &p) , size_(TlFetchInt::parse(p)) , key_(TlFetchBytes::parse(p)) , iv_(TlFetchBytes::parse(p)) -#undef FAIL {} void decryptedMessageMediaDocument8::store(TlStorerCalcLength &s) const { @@ -1498,12 +1457,10 @@ object_ptr decryptedMessageMediaAudio8::fetch(TlParser &p } decryptedMessageMediaAudio8::decryptedMessageMediaAudio8(TlParser &p) -#define FAIL(error) p.set_error(error) : duration_(TlFetchInt::parse(p)) , size_(TlFetchInt::parse(p)) , key_(TlFetchBytes::parse(p)) , iv_(TlFetchBytes::parse(p)) -#undef FAIL {} void decryptedMessageMediaAudio8::store(TlStorerCalcLength &s) const { @@ -1553,7 +1510,6 @@ object_ptr decryptedMessageMediaVideo23::fetch(TlParser & } decryptedMessageMediaVideo23::decryptedMessageMediaVideo23(TlParser &p) -#define FAIL(error) p.set_error(error) : thumb_(TlFetchBytes::parse(p)) , thumb_w_(TlFetchInt::parse(p)) , thumb_h_(TlFetchInt::parse(p)) @@ -1564,7 +1520,6 @@ decryptedMessageMediaVideo23::decryptedMessageMediaVideo23(TlParser &p) , size_(TlFetchInt::parse(p)) , key_(TlFetchBytes::parse(p)) , iv_(TlFetchBytes::parse(p)) -#undef FAIL {} void decryptedMessageMediaVideo23::store(TlStorerCalcLength &s) const { @@ -1627,13 +1582,11 @@ object_ptr decryptedMessageMediaAudio::fetch(TlParser &p) } decryptedMessageMediaAudio::decryptedMessageMediaAudio(TlParser &p) -#define FAIL(error) p.set_error(error) : duration_(TlFetchInt::parse(p)) , mime_type_(TlFetchString::parse(p)) , size_(TlFetchInt::parse(p)) , key_(TlFetchBytes::parse(p)) , iv_(TlFetchBytes::parse(p)) -#undef FAIL {} void decryptedMessageMediaAudio::store(TlStorerCalcLength &s) const { @@ -1684,7 +1637,6 @@ object_ptr decryptedMessageMediaExternalDocument::fetch(T } decryptedMessageMediaExternalDocument::decryptedMessageMediaExternalDocument(TlParser &p) -#define FAIL(error) p.set_error(error) : id_(TlFetchLong::parse(p)) , access_hash_(TlFetchLong::parse(p)) , date_(TlFetchInt::parse(p)) @@ -1693,7 +1645,6 @@ decryptedMessageMediaExternalDocument::decryptedMessageMediaExternalDocument(TlP , thumb_(TlFetchObject::parse(p)) , dc_id_(TlFetchInt::parse(p)) , attributes_(TlFetchBoxed>, 481674261>::parse(p)) -#undef FAIL {} void decryptedMessageMediaExternalDocument::store(TlStorerCalcLength &s) const { @@ -1754,7 +1705,6 @@ object_ptr decryptedMessageMediaPhoto::fetch(TlParser &p) } decryptedMessageMediaPhoto::decryptedMessageMediaPhoto(TlParser &p) -#define FAIL(error) p.set_error(error) : thumb_(TlFetchBytes::parse(p)) , thumb_w_(TlFetchInt::parse(p)) , thumb_h_(TlFetchInt::parse(p)) @@ -1764,7 +1714,6 @@ decryptedMessageMediaPhoto::decryptedMessageMediaPhoto(TlParser &p) , key_(TlFetchBytes::parse(p)) , iv_(TlFetchBytes::parse(p)) , caption_(TlFetchString::parse(p)) -#undef FAIL {} void decryptedMessageMediaPhoto::store(TlStorerCalcLength &s) const { @@ -1830,7 +1779,6 @@ object_ptr decryptedMessageMediaVideo::fetch(TlParser &p) } decryptedMessageMediaVideo::decryptedMessageMediaVideo(TlParser &p) -#define FAIL(error) p.set_error(error) : thumb_(TlFetchBytes::parse(p)) , thumb_w_(TlFetchInt::parse(p)) , thumb_h_(TlFetchInt::parse(p)) @@ -1842,7 +1790,6 @@ decryptedMessageMediaVideo::decryptedMessageMediaVideo(TlParser &p) , key_(TlFetchBytes::parse(p)) , iv_(TlFetchBytes::parse(p)) , caption_(TlFetchString::parse(p)) -#undef FAIL {} void decryptedMessageMediaVideo::store(TlStorerCalcLength &s) const { @@ -1912,7 +1859,6 @@ object_ptr decryptedMessageMediaDocument46::fetch(TlParse } decryptedMessageMediaDocument46::decryptedMessageMediaDocument46(TlParser &p) -#define FAIL(error) p.set_error(error) : thumb_(TlFetchBytes::parse(p)) , thumb_w_(TlFetchInt::parse(p)) , thumb_h_(TlFetchInt::parse(p)) @@ -1922,7 +1868,6 @@ decryptedMessageMediaDocument46::decryptedMessageMediaDocument46(TlParser &p) , iv_(TlFetchBytes::parse(p)) , attributes_(TlFetchBoxed>, 481674261>::parse(p)) , caption_(TlFetchString::parse(p)) -#undef FAIL {} void decryptedMessageMediaDocument46::store(TlStorerCalcLength &s) const { @@ -1983,14 +1928,12 @@ object_ptr decryptedMessageMediaVenue::fetch(TlParser &p) } decryptedMessageMediaVenue::decryptedMessageMediaVenue(TlParser &p) -#define FAIL(error) p.set_error(error) : lat_(TlFetchDouble::parse(p)) , long_(TlFetchDouble::parse(p)) , title_(TlFetchString::parse(p)) , address_(TlFetchString::parse(p)) , provider_(TlFetchString::parse(p)) , venue_id_(TlFetchString::parse(p)) -#undef FAIL {} void decryptedMessageMediaVenue::store(TlStorerCalcLength &s) const { @@ -2037,9 +1980,7 @@ object_ptr decryptedMessageMediaWebPage::fetch(TlParser & } decryptedMessageMediaWebPage::decryptedMessageMediaWebPage(TlParser &p) -#define FAIL(error) p.set_error(error) : url_(TlFetchString::parse(p)) -#undef FAIL {} void decryptedMessageMediaWebPage::store(TlStorerCalcLength &s) const { @@ -2079,7 +2020,6 @@ object_ptr decryptedMessageMediaDocument::fetch(TlParser } decryptedMessageMediaDocument::decryptedMessageMediaDocument(TlParser &p) -#define FAIL(error) p.set_error(error) : thumb_(TlFetchBytes::parse(p)) , thumb_w_(TlFetchInt::parse(p)) , thumb_h_(TlFetchInt::parse(p)) @@ -2089,7 +2029,6 @@ decryptedMessageMediaDocument::decryptedMessageMediaDocument(TlParser &p) , iv_(TlFetchBytes::parse(p)) , attributes_(TlFetchBoxed>, 481674261>::parse(p)) , caption_(TlFetchString::parse(p)) -#undef FAIL {} void decryptedMessageMediaDocument::store(TlStorerCalcLength &s) const { @@ -2176,10 +2115,8 @@ object_ptr documentAttributeImageSize::fetch(TlParser &p) { } documentAttributeImageSize::documentAttributeImageSize(TlParser &p) -#define FAIL(error) p.set_error(error) : w_(TlFetchInt::parse(p)) , h_(TlFetchInt::parse(p)) -#undef FAIL {} void documentAttributeImageSize::store(TlStorerCalcLength &s) const { @@ -2258,11 +2195,9 @@ object_ptr documentAttributeVideo23::fetch(TlParser &p) { } documentAttributeVideo23::documentAttributeVideo23(TlParser &p) -#define FAIL(error) p.set_error(error) : duration_(TlFetchInt::parse(p)) , w_(TlFetchInt::parse(p)) , h_(TlFetchInt::parse(p)) -#undef FAIL {} void documentAttributeVideo23::store(TlStorerCalcLength &s) const { @@ -2300,9 +2235,7 @@ object_ptr documentAttributeAudio23::fetch(TlParser &p) { } documentAttributeAudio23::documentAttributeAudio23(TlParser &p) -#define FAIL(error) p.set_error(error) : duration_(TlFetchInt::parse(p)) -#undef FAIL {} void documentAttributeAudio23::store(TlStorerCalcLength &s) const { @@ -2334,9 +2267,7 @@ object_ptr documentAttributeFilename::fetch(TlParser &p) { } documentAttributeFilename::documentAttributeFilename(TlParser &p) -#define FAIL(error) p.set_error(error) : file_name_(TlFetchString::parse(p)) -#undef FAIL {} void documentAttributeFilename::store(TlStorerCalcLength &s) const { @@ -2370,11 +2301,9 @@ object_ptr documentAttributeAudio45::fetch(TlParser &p) { } documentAttributeAudio45::documentAttributeAudio45(TlParser &p) -#define FAIL(error) p.set_error(error) : duration_(TlFetchInt::parse(p)) , title_(TlFetchString::parse(p)) , performer_(TlFetchString::parse(p)) -#undef FAIL {} void documentAttributeAudio45::store(TlStorerCalcLength &s) const { @@ -2413,10 +2342,8 @@ object_ptr documentAttributeSticker::fetch(TlParser &p) { } documentAttributeSticker::documentAttributeSticker(TlParser &p) -#define FAIL(error) p.set_error(error) : alt_(TlFetchString::parse(p)) , stickerset_(TlFetchObject::parse(p)) -#undef FAIL {} void documentAttributeSticker::store(TlStorerCalcLength &s) const { @@ -2465,7 +2392,7 @@ object_ptr documentAttributeAudio::fetch(TlParser &p) { object_ptr res = make_tl_object(); int32 var0; if ((var0 = res->flags_ = TlFetchInt::parse(p)) < 0) { FAIL("Variable of type # can't be negative"); } - if (var0 & 1024) { res->voice_ = TlFetchTrue::parse(p); } + res->voice_ = (var0 & 1024) != 0; res->duration_ = TlFetchInt::parse(p); if (var0 & 1) { res->title_ = TlFetchString::parse(p); } if (var0 & 2) { res->performer_ = TlFetchString::parse(p); } @@ -2500,6 +2427,7 @@ void documentAttributeAudio::store(TlStorerToString &s, const char *field_name) s.store_class_begin(field_name, "documentAttributeAudio"); int32 var0; s.store_field("flags", (var0 = flags_)); + if (var0 & 1024) { s.store_field("voice", true); } s.store_field("duration", duration_); if (var0 & 1) { s.store_field("title", title_); } if (var0 & 2) { s.store_field("performer", performer_); } @@ -2531,7 +2459,7 @@ object_ptr documentAttributeVideo::fetch(TlParser &p) { object_ptr res = make_tl_object(); int32 var0; if ((var0 = res->flags_ = TlFetchInt::parse(p)) < 0) { FAIL("Variable of type # can't be negative"); } - if (var0 & 1) { res->round_message_ = TlFetchTrue::parse(p); } + res->round_message_ = (var0 & 1) != 0; res->duration_ = TlFetchInt::parse(p); res->w_ = TlFetchInt::parse(p); res->h_ = TlFetchInt::parse(p); @@ -2563,6 +2491,7 @@ void documentAttributeVideo::store(TlStorerToString &s, const char *field_name) s.store_class_begin(field_name, "documentAttributeVideo"); int32 var0; s.store_field("flags", (var0 = flags_)); + if (var0 & 1) { s.store_field("round_message", true); } s.store_field("duration", duration_); s.store_field("w", w_); s.store_field("h", h_); @@ -2597,11 +2526,9 @@ object_ptr fileLocationUnavailable::fetch(TlParser &p) { } fileLocationUnavailable::fileLocationUnavailable(TlParser &p) -#define FAIL(error) p.set_error(error) : volume_id_(TlFetchLong::parse(p)) , local_id_(TlFetchInt::parse(p)) , secret_(TlFetchLong::parse(p)) -#undef FAIL {} void fileLocationUnavailable::store(TlStorerCalcLength &s) const { @@ -2642,12 +2569,10 @@ object_ptr fileLocation::fetch(TlParser &p) { } fileLocation::fileLocation(TlParser &p) -#define FAIL(error) p.set_error(error) : dc_id_(TlFetchInt::parse(p)) , volume_id_(TlFetchLong::parse(p)) , local_id_(TlFetchInt::parse(p)) , secret_(TlFetchLong::parse(p)) -#undef FAIL {} void fileLocation::store(TlStorerCalcLength &s) const { @@ -2702,9 +2627,7 @@ object_ptr inputStickerSetShortName::fetch(TlParser &p) { } inputStickerSetShortName::inputStickerSetShortName(TlParser &p) -#define FAIL(error) p.set_error(error) : short_name_(TlFetchString::parse(p)) -#undef FAIL {} void inputStickerSetShortName::store(TlStorerCalcLength &s) const { @@ -2808,10 +2731,8 @@ object_ptr messageEntityUnknown::fetch(TlParser &p) { } messageEntityUnknown::messageEntityUnknown(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityUnknown::store(TlStorerCalcLength &s) const { @@ -2847,10 +2768,8 @@ object_ptr messageEntityMention::fetch(TlParser &p) { } messageEntityMention::messageEntityMention(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityMention::store(TlStorerCalcLength &s) const { @@ -2886,10 +2805,8 @@ object_ptr messageEntityHashtag::fetch(TlParser &p) { } messageEntityHashtag::messageEntityHashtag(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityHashtag::store(TlStorerCalcLength &s) const { @@ -2925,10 +2842,8 @@ object_ptr messageEntityBotCommand::fetch(TlParser &p) { } messageEntityBotCommand::messageEntityBotCommand(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityBotCommand::store(TlStorerCalcLength &s) const { @@ -2964,10 +2879,8 @@ object_ptr messageEntityUrl::fetch(TlParser &p) { } messageEntityUrl::messageEntityUrl(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityUrl::store(TlStorerCalcLength &s) const { @@ -3003,10 +2916,8 @@ object_ptr messageEntityEmail::fetch(TlParser &p) { } messageEntityEmail::messageEntityEmail(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityEmail::store(TlStorerCalcLength &s) const { @@ -3042,10 +2953,8 @@ object_ptr messageEntityBold::fetch(TlParser &p) { } messageEntityBold::messageEntityBold(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityBold::store(TlStorerCalcLength &s) const { @@ -3081,10 +2990,8 @@ object_ptr messageEntityItalic::fetch(TlParser &p) { } messageEntityItalic::messageEntityItalic(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityItalic::store(TlStorerCalcLength &s) const { @@ -3120,10 +3027,8 @@ object_ptr messageEntityCode::fetch(TlParser &p) { } messageEntityCode::messageEntityCode(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityCode::store(TlStorerCalcLength &s) const { @@ -3160,11 +3065,9 @@ object_ptr messageEntityPre::fetch(TlParser &p) { } messageEntityPre::messageEntityPre(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) , language_(TlFetchString::parse(p)) -#undef FAIL {} void messageEntityPre::store(TlStorerCalcLength &s) const { @@ -3204,11 +3107,9 @@ object_ptr messageEntityTextUrl::fetch(TlParser &p) { } messageEntityTextUrl::messageEntityTextUrl(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) , url_(TlFetchString::parse(p)) -#undef FAIL {} void messageEntityTextUrl::store(TlStorerCalcLength &s) const { @@ -3248,11 +3149,9 @@ object_ptr messageEntityMentionName::fetch(TlParser &p) { } messageEntityMentionName::messageEntityMentionName(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) , user_id_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityMentionName::store(TlStorerCalcLength &s) const { @@ -3291,10 +3190,8 @@ object_ptr messageEntityPhone::fetch(TlParser &p) { } messageEntityPhone::messageEntityPhone(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityPhone::store(TlStorerCalcLength &s) const { @@ -3330,10 +3227,8 @@ object_ptr messageEntityCashtag::fetch(TlParser &p) { } messageEntityCashtag::messageEntityCashtag(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityCashtag::store(TlStorerCalcLength &s) const { @@ -3369,10 +3264,8 @@ object_ptr messageEntityBankCard::fetch(TlParser &p) { } messageEntityBankCard::messageEntityBankCard(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityBankCard::store(TlStorerCalcLength &s) const { @@ -3408,10 +3301,8 @@ object_ptr messageEntityUnderline::fetch(TlParser &p) { } messageEntityUnderline::messageEntityUnderline(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityUnderline::store(TlStorerCalcLength &s) const { @@ -3447,10 +3338,8 @@ object_ptr messageEntityStrike::fetch(TlParser &p) { } messageEntityStrike::messageEntityStrike(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityStrike::store(TlStorerCalcLength &s) const { @@ -3486,10 +3375,8 @@ object_ptr messageEntityBlockquote::fetch(TlParser &p) { } messageEntityBlockquote::messageEntityBlockquote(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntityBlockquote::store(TlStorerCalcLength &s) const { @@ -3525,10 +3412,8 @@ object_ptr messageEntitySpoiler::fetch(TlParser &p) { } messageEntitySpoiler::messageEntitySpoiler(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) -#undef FAIL {} void messageEntitySpoiler::store(TlStorerCalcLength &s) const { @@ -3565,11 +3450,9 @@ object_ptr messageEntityCustomEmoji::fetch(TlParser &p) { } messageEntityCustomEmoji::messageEntityCustomEmoji(TlParser &p) -#define FAIL(error) p.set_error(error) : offset_(TlFetchInt::parse(p)) , length_(TlFetchInt::parse(p)) , document_id_(TlFetchLong::parse(p)) -#undef FAIL {} void messageEntityCustomEmoji::store(TlStorerCalcLength &s) const { @@ -3623,9 +3506,7 @@ object_ptr photoSizeEmpty::fetch(TlParser &p) { } photoSizeEmpty::photoSizeEmpty(TlParser &p) -#define FAIL(error) p.set_error(error) : type_(TlFetchString::parse(p)) -#undef FAIL {} void photoSizeEmpty::store(TlStorerCalcLength &s) const { @@ -3661,13 +3542,11 @@ object_ptr photoSize::fetch(TlParser &p) { } photoSize::photoSize(TlParser &p) -#define FAIL(error) p.set_error(error) : type_(TlFetchString::parse(p)) , location_(TlFetchObject::parse(p)) , w_(TlFetchInt::parse(p)) , h_(TlFetchInt::parse(p)) , size_(TlFetchInt::parse(p)) -#undef FAIL {} void photoSize::store(TlStorerCalcLength &s) const { @@ -3715,13 +3594,11 @@ object_ptr photoCachedSize::fetch(TlParser &p) { } photoCachedSize::photoCachedSize(TlParser &p) -#define FAIL(error) p.set_error(error) : type_(TlFetchString::parse(p)) , location_(TlFetchObject::parse(p)) , w_(TlFetchInt::parse(p)) , h_(TlFetchInt::parse(p)) , bytes_(TlFetchBytes::parse(p)) -#undef FAIL {} void photoCachedSize::store(TlStorerCalcLength &s) const { diff --git a/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/secret_api.h b/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/secret_api.h index e6da9e2ef2..e1188ba733 100644 --- a/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/secret_api.h +++ b/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/secret_api.h @@ -67,28 +67,6 @@ std::string to_string(const std::vector> &values) { return result; } -class DecryptedMessage; - -class DecryptedMessageAction; - -class decryptedMessageLayer; - -class DecryptedMessageMedia; - -class DocumentAttribute; - -class FileLocation; - -class InputStickerSet; - -class MessageEntity; - -class PhotoSize; - -class SendMessageAction; - -class Object; - class Object: public TlObject { public: @@ -101,6 +79,12 @@ class Function: public TlObject { static object_ptr fetch(TlParser &p); }; +class DecryptedMessageAction; + +class DecryptedMessageMedia; + +class MessageEntity; + class DecryptedMessage: public Object { public: @@ -108,6 +92,10 @@ class DecryptedMessage: public Object { }; class decryptedMessage8 final : public DecryptedMessage { + std::int32_t get_id() const final { + return ID; + } + public: int64 random_id_; bytes random_bytes_; @@ -117,9 +105,6 @@ class decryptedMessage8 final : public DecryptedMessage { decryptedMessage8(int64 random_id_, bytes &&random_bytes_, string const &message_, object_ptr &&media_); static const std::int32_t ID = 528568095; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -133,6 +118,10 @@ class decryptedMessage8 final : public DecryptedMessage { }; class decryptedMessageService8 final : public DecryptedMessage { + std::int32_t get_id() const final { + return ID; + } + public: int64 random_id_; bytes random_bytes_; @@ -141,9 +130,6 @@ class decryptedMessageService8 final : public DecryptedMessage { decryptedMessageService8(int64 random_id_, bytes &&random_bytes_, object_ptr &&action_); static const std::int32_t ID = -1438109059; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -157,6 +143,10 @@ class decryptedMessageService8 final : public DecryptedMessage { }; class decryptedMessage23 final : public DecryptedMessage { + std::int32_t get_id() const final { + return ID; + } + public: int64 random_id_; int32 ttl_; @@ -166,9 +156,6 @@ class decryptedMessage23 final : public DecryptedMessage { decryptedMessage23(int64 random_id_, int32 ttl_, string const &message_, object_ptr &&media_); static const std::int32_t ID = 541931640; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -182,6 +169,10 @@ class decryptedMessage23 final : public DecryptedMessage { }; class decryptedMessageService final : public DecryptedMessage { + std::int32_t get_id() const final { + return ID; + } + public: int64 random_id_; object_ptr action_; @@ -189,9 +180,6 @@ class decryptedMessageService final : public DecryptedMessage { decryptedMessageService(int64 random_id_, object_ptr &&action_); static const std::int32_t ID = 1930838368; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -205,6 +193,10 @@ class decryptedMessageService final : public DecryptedMessage { }; class decryptedMessage46 final : public DecryptedMessage { + std::int32_t get_id() const final { + return ID; + } + public: int32 flags_; int64 random_id_; @@ -221,9 +213,6 @@ class decryptedMessage46 final : public DecryptedMessage { decryptedMessage46(int32 flags_, int64 random_id_, int32 ttl_, string const &message_, object_ptr &&media_, array> &&entities_, string const &via_bot_name_, int64 reply_to_random_id_); static const std::int32_t ID = 917541342; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -235,6 +224,10 @@ class decryptedMessage46 final : public DecryptedMessage { }; class decryptedMessage final : public DecryptedMessage { + std::int32_t get_id() const final { + return ID; + } + public: int32 flags_; bool silent_; @@ -253,9 +246,6 @@ class decryptedMessage final : public DecryptedMessage { decryptedMessage(int32 flags_, bool silent_, int64 random_id_, int32 ttl_, string const &message_, object_ptr &&media_, array> &&entities_, string const &via_bot_name_, int64 reply_to_random_id_, int64 grouped_id_); static const std::int32_t ID = -1848883596; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -266,6 +256,8 @@ class decryptedMessage final : public DecryptedMessage { void store(TlStorerToString &s, const char *field_name) const final; }; +class SendMessageAction; + class DecryptedMessageAction: public Object { public: @@ -273,15 +265,16 @@ class DecryptedMessageAction: public Object { }; class decryptedMessageActionSetMessageTTL final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: int32 ttl_seconds_; explicit decryptedMessageActionSetMessageTTL(int32 ttl_seconds_); static const std::int32_t ID = -1586283796; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -295,15 +288,16 @@ class decryptedMessageActionSetMessageTTL final : public DecryptedMessageAction }; class decryptedMessageActionReadMessages final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: array random_ids_; explicit decryptedMessageActionReadMessages(array &&random_ids_); static const std::int32_t ID = 206520510; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -317,15 +311,16 @@ class decryptedMessageActionReadMessages final : public DecryptedMessageAction { }; class decryptedMessageActionDeleteMessages final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: array random_ids_; explicit decryptedMessageActionDeleteMessages(array &&random_ids_); static const std::int32_t ID = 1700872964; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -339,15 +334,16 @@ class decryptedMessageActionDeleteMessages final : public DecryptedMessageAction }; class decryptedMessageActionScreenshotMessages final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: array random_ids_; explicit decryptedMessageActionScreenshotMessages(array &&random_ids_); static const std::int32_t ID = -1967000459; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -361,13 +357,14 @@ class decryptedMessageActionScreenshotMessages final : public DecryptedMessageAc }; class decryptedMessageActionFlushHistory final : public DecryptedMessageAction { - public: - - static const std::int32_t ID = 1729750108; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = 1729750108; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -378,6 +375,10 @@ class decryptedMessageActionFlushHistory final : public DecryptedMessageAction { }; class decryptedMessageActionResend final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: int32 start_seq_no_; int32 end_seq_no_; @@ -385,9 +386,6 @@ class decryptedMessageActionResend final : public DecryptedMessageAction { decryptedMessageActionResend(int32 start_seq_no_, int32 end_seq_no_); static const std::int32_t ID = 1360072880; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -401,15 +399,16 @@ class decryptedMessageActionResend final : public DecryptedMessageAction { }; class decryptedMessageActionNotifyLayer final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: int32 layer_; explicit decryptedMessageActionNotifyLayer(int32 layer_); static const std::int32_t ID = -217806717; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -423,15 +422,16 @@ class decryptedMessageActionNotifyLayer final : public DecryptedMessageAction { }; class decryptedMessageActionTyping final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: object_ptr action_; explicit decryptedMessageActionTyping(object_ptr &&action_); static const std::int32_t ID = -860719551; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -445,6 +445,10 @@ class decryptedMessageActionTyping final : public DecryptedMessageAction { }; class decryptedMessageActionRequestKey final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: int64 exchange_id_; bytes g_a_; @@ -452,9 +456,6 @@ class decryptedMessageActionRequestKey final : public DecryptedMessageAction { decryptedMessageActionRequestKey(int64 exchange_id_, bytes &&g_a_); static const std::int32_t ID = -204906213; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -468,6 +469,10 @@ class decryptedMessageActionRequestKey final : public DecryptedMessageAction { }; class decryptedMessageActionAcceptKey final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: int64 exchange_id_; bytes g_b_; @@ -476,9 +481,6 @@ class decryptedMessageActionAcceptKey final : public DecryptedMessageAction { decryptedMessageActionAcceptKey(int64 exchange_id_, bytes &&g_b_, int64 key_fingerprint_); static const std::int32_t ID = 1877046107; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -492,15 +494,16 @@ class decryptedMessageActionAcceptKey final : public DecryptedMessageAction { }; class decryptedMessageActionAbortKey final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: int64 exchange_id_; explicit decryptedMessageActionAbortKey(int64 exchange_id_); static const std::int32_t ID = -586814357; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -514,6 +517,10 @@ class decryptedMessageActionAbortKey final : public DecryptedMessageAction { }; class decryptedMessageActionCommitKey final : public DecryptedMessageAction { + std::int32_t get_id() const final { + return ID; + } + public: int64 exchange_id_; int64 key_fingerprint_; @@ -521,9 +528,6 @@ class decryptedMessageActionCommitKey final : public DecryptedMessageAction { decryptedMessageActionCommitKey(int64 exchange_id_, int64 key_fingerprint_); static const std::int32_t ID = -332526693; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -537,13 +541,14 @@ class decryptedMessageActionCommitKey final : public DecryptedMessageAction { }; class decryptedMessageActionNoop final : public DecryptedMessageAction { - public: - - static const std::int32_t ID = -1473258141; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -1473258141; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -553,7 +558,13 @@ class decryptedMessageActionNoop final : public DecryptedMessageAction { void store(TlStorerToString &s, const char *field_name) const final; }; +class DecryptedMessage; + class decryptedMessageLayer final : public Object { + std::int32_t get_id() const final { + return ID; + } + public: bytes random_bytes_; int32 layer_; @@ -564,9 +575,6 @@ class decryptedMessageLayer final : public Object { decryptedMessageLayer(bytes &&random_bytes_, int32 layer_, int32 in_seq_no_, int32 out_seq_no_, object_ptr &&message_); static const std::int32_t ID = 467867529; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -579,6 +587,10 @@ class decryptedMessageLayer final : public Object { void store(TlStorerToString &s, const char *field_name) const final; }; +class DocumentAttribute; + +class PhotoSize; + class DecryptedMessageMedia: public Object { public: @@ -586,13 +598,14 @@ class DecryptedMessageMedia: public Object { }; class decryptedMessageMediaEmpty final : public DecryptedMessageMedia { - public: - - static const std::int32_t ID = 144661578; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = 144661578; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -603,6 +616,10 @@ class decryptedMessageMediaEmpty final : public DecryptedMessageMedia { }; class decryptedMessageMediaPhoto8 final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: bytes thumb_; int32 thumb_w_; @@ -616,9 +633,6 @@ class decryptedMessageMediaPhoto8 final : public DecryptedMessageMedia { decryptedMessageMediaPhoto8(bytes &&thumb_, int32 thumb_w_, int32 thumb_h_, int32 w_, int32 h_, int32 size_, bytes &&key_, bytes &&iv_); static const std::int32_t ID = 846826124; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -632,6 +646,10 @@ class decryptedMessageMediaPhoto8 final : public DecryptedMessageMedia { }; class decryptedMessageMediaVideo8 final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: bytes thumb_; int32 thumb_w_; @@ -646,9 +664,6 @@ class decryptedMessageMediaVideo8 final : public DecryptedMessageMedia { decryptedMessageMediaVideo8(bytes &&thumb_, int32 thumb_w_, int32 thumb_h_, int32 duration_, int32 w_, int32 h_, int32 size_, bytes &&key_, bytes &&iv_); static const std::int32_t ID = 1290694387; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -662,6 +677,10 @@ class decryptedMessageMediaVideo8 final : public DecryptedMessageMedia { }; class decryptedMessageMediaGeoPoint final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: double lat_; double long_; @@ -669,9 +688,6 @@ class decryptedMessageMediaGeoPoint final : public DecryptedMessageMedia { decryptedMessageMediaGeoPoint(double lat_, double long_); static const std::int32_t ID = 893913689; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -685,6 +701,10 @@ class decryptedMessageMediaGeoPoint final : public DecryptedMessageMedia { }; class decryptedMessageMediaContact final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: string phone_number_; string first_name_; @@ -694,9 +714,6 @@ class decryptedMessageMediaContact final : public DecryptedMessageMedia { decryptedMessageMediaContact(string const &phone_number_, string const &first_name_, string const &last_name_, int32 user_id_); static const std::int32_t ID = 1485441687; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -710,6 +727,10 @@ class decryptedMessageMediaContact final : public DecryptedMessageMedia { }; class decryptedMessageMediaDocument8 final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: bytes thumb_; int32 thumb_w_; @@ -723,9 +744,6 @@ class decryptedMessageMediaDocument8 final : public DecryptedMessageMedia { decryptedMessageMediaDocument8(bytes &&thumb_, int32 thumb_w_, int32 thumb_h_, string const &file_name_, string const &mime_type_, int32 size_, bytes &&key_, bytes &&iv_); static const std::int32_t ID = -1332395189; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -739,6 +757,10 @@ class decryptedMessageMediaDocument8 final : public DecryptedMessageMedia { }; class decryptedMessageMediaAudio8 final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: int32 duration_; int32 size_; @@ -748,9 +770,6 @@ class decryptedMessageMediaAudio8 final : public DecryptedMessageMedia { decryptedMessageMediaAudio8(int32 duration_, int32 size_, bytes &&key_, bytes &&iv_); static const std::int32_t ID = 1619031439; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -764,6 +783,10 @@ class decryptedMessageMediaAudio8 final : public DecryptedMessageMedia { }; class decryptedMessageMediaVideo23 final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: bytes thumb_; int32 thumb_w_; @@ -779,9 +802,6 @@ class decryptedMessageMediaVideo23 final : public DecryptedMessageMedia { decryptedMessageMediaVideo23(bytes &&thumb_, int32 thumb_w_, int32 thumb_h_, int32 duration_, string const &mime_type_, int32 w_, int32 h_, int32 size_, bytes &&key_, bytes &&iv_); static const std::int32_t ID = 1380598109; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -795,6 +815,10 @@ class decryptedMessageMediaVideo23 final : public DecryptedMessageMedia { }; class decryptedMessageMediaAudio final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: int32 duration_; string mime_type_; @@ -805,9 +829,6 @@ class decryptedMessageMediaAudio final : public DecryptedMessageMedia { decryptedMessageMediaAudio(int32 duration_, string const &mime_type_, int32 size_, bytes &&key_, bytes &&iv_); static const std::int32_t ID = 1474341323; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -821,6 +842,10 @@ class decryptedMessageMediaAudio final : public DecryptedMessageMedia { }; class decryptedMessageMediaExternalDocument final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: int64 id_; int64 access_hash_; @@ -834,9 +859,6 @@ class decryptedMessageMediaExternalDocument final : public DecryptedMessageMedia decryptedMessageMediaExternalDocument(int64 id_, int64 access_hash_, int32 date_, string const &mime_type_, int32 size_, object_ptr &&thumb_, int32 dc_id_, array> &&attributes_); static const std::int32_t ID = -90853155; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -850,6 +872,10 @@ class decryptedMessageMediaExternalDocument final : public DecryptedMessageMedia }; class decryptedMessageMediaPhoto final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: bytes thumb_; int32 thumb_w_; @@ -864,9 +890,6 @@ class decryptedMessageMediaPhoto final : public DecryptedMessageMedia { decryptedMessageMediaPhoto(bytes &&thumb_, int32 thumb_w_, int32 thumb_h_, int32 w_, int32 h_, int32 size_, bytes &&key_, bytes &&iv_, string const &caption_); static const std::int32_t ID = -235238024; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -880,6 +903,10 @@ class decryptedMessageMediaPhoto final : public DecryptedMessageMedia { }; class decryptedMessageMediaVideo final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: bytes thumb_; int32 thumb_w_; @@ -896,9 +923,6 @@ class decryptedMessageMediaVideo final : public DecryptedMessageMedia { decryptedMessageMediaVideo(bytes &&thumb_, int32 thumb_w_, int32 thumb_h_, int32 duration_, string const &mime_type_, int32 w_, int32 h_, int32 size_, bytes &&key_, bytes &&iv_, string const &caption_); static const std::int32_t ID = -1760785394; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -912,6 +936,10 @@ class decryptedMessageMediaVideo final : public DecryptedMessageMedia { }; class decryptedMessageMediaDocument46 final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: bytes thumb_; int32 thumb_w_; @@ -926,9 +954,6 @@ class decryptedMessageMediaDocument46 final : public DecryptedMessageMedia { decryptedMessageMediaDocument46(bytes &&thumb_, int32 thumb_w_, int32 thumb_h_, string const &mime_type_, int32 size_, bytes &&key_, bytes &&iv_, array> &&attributes_, string const &caption_); static const std::int32_t ID = 2063502050; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -942,6 +967,10 @@ class decryptedMessageMediaDocument46 final : public DecryptedMessageMedia { }; class decryptedMessageMediaVenue final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: double lat_; double long_; @@ -953,9 +982,6 @@ class decryptedMessageMediaVenue final : public DecryptedMessageMedia { decryptedMessageMediaVenue(double lat_, double long_, string const &title_, string const &address_, string const &provider_, string const &venue_id_); static const std::int32_t ID = -1978796689; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -969,15 +995,16 @@ class decryptedMessageMediaVenue final : public DecryptedMessageMedia { }; class decryptedMessageMediaWebPage final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: string url_; explicit decryptedMessageMediaWebPage(string const &url_); static const std::int32_t ID = -452652584; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -991,6 +1018,10 @@ class decryptedMessageMediaWebPage final : public DecryptedMessageMedia { }; class decryptedMessageMediaDocument final : public DecryptedMessageMedia { + std::int32_t get_id() const final { + return ID; + } + public: bytes thumb_; int32 thumb_w_; @@ -1005,9 +1036,6 @@ class decryptedMessageMediaDocument final : public DecryptedMessageMedia { decryptedMessageMediaDocument(bytes &&thumb_, int32 thumb_w_, int32 thumb_h_, string const &mime_type_, int64 size_, bytes &&key_, bytes &&iv_, array> &&attributes_, string const &caption_); static const std::int32_t ID = 1790809986; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1020,6 +1048,8 @@ class decryptedMessageMediaDocument final : public DecryptedMessageMedia { void store(TlStorerToString &s, const char *field_name) const final; }; +class InputStickerSet; + class DocumentAttribute: public Object { public: @@ -1027,6 +1057,10 @@ class DocumentAttribute: public Object { }; class documentAttributeImageSize final : public DocumentAttribute { + std::int32_t get_id() const final { + return ID; + } + public: int32 w_; int32 h_; @@ -1034,9 +1068,6 @@ class documentAttributeImageSize final : public DocumentAttribute { documentAttributeImageSize(int32 w_, int32 h_); static const std::int32_t ID = 1815593308; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1050,13 +1081,14 @@ class documentAttributeImageSize final : public DocumentAttribute { }; class documentAttributeAnimated final : public DocumentAttribute { - public: - - static const std::int32_t ID = 297109817; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = 297109817; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -1067,13 +1099,14 @@ class documentAttributeAnimated final : public DocumentAttribute { }; class documentAttributeSticker23 final : public DocumentAttribute { - public: - - static const std::int32_t ID = -83208409; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -83208409; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -1084,6 +1117,10 @@ class documentAttributeSticker23 final : public DocumentAttribute { }; class documentAttributeVideo23 final : public DocumentAttribute { + std::int32_t get_id() const final { + return ID; + } + public: int32 duration_; int32 w_; @@ -1092,9 +1129,6 @@ class documentAttributeVideo23 final : public DocumentAttribute { documentAttributeVideo23(int32 duration_, int32 w_, int32 h_); static const std::int32_t ID = 1494273227; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1108,15 +1142,16 @@ class documentAttributeVideo23 final : public DocumentAttribute { }; class documentAttributeAudio23 final : public DocumentAttribute { + std::int32_t get_id() const final { + return ID; + } + public: int32 duration_; explicit documentAttributeAudio23(int32 duration_); static const std::int32_t ID = 85215461; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1130,15 +1165,16 @@ class documentAttributeAudio23 final : public DocumentAttribute { }; class documentAttributeFilename final : public DocumentAttribute { + std::int32_t get_id() const final { + return ID; + } + public: string file_name_; explicit documentAttributeFilename(string const &file_name_); static const std::int32_t ID = 358154344; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1152,6 +1188,10 @@ class documentAttributeFilename final : public DocumentAttribute { }; class documentAttributeAudio45 final : public DocumentAttribute { + std::int32_t get_id() const final { + return ID; + } + public: int32 duration_; string title_; @@ -1160,9 +1200,6 @@ class documentAttributeAudio45 final : public DocumentAttribute { documentAttributeAudio45(int32 duration_, string const &title_, string const &performer_); static const std::int32_t ID = -556656416; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1176,6 +1213,10 @@ class documentAttributeAudio45 final : public DocumentAttribute { }; class documentAttributeSticker final : public DocumentAttribute { + std::int32_t get_id() const final { + return ID; + } + public: string alt_; object_ptr stickerset_; @@ -1183,9 +1224,6 @@ class documentAttributeSticker final : public DocumentAttribute { documentAttributeSticker(string const &alt_, object_ptr &&stickerset_); static const std::int32_t ID = 978674434; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1199,6 +1237,10 @@ class documentAttributeSticker final : public DocumentAttribute { }; class documentAttributeAudio final : public DocumentAttribute { + std::int32_t get_id() const final { + return ID; + } + public: int32 flags_; bool voice_; @@ -1213,9 +1255,6 @@ class documentAttributeAudio final : public DocumentAttribute { documentAttributeAudio(int32 flags_, bool voice_, int32 duration_, string const &title_, string const &performer_, bytes &&waveform_); static const std::int32_t ID = -1739392570; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1227,6 +1266,10 @@ class documentAttributeAudio final : public DocumentAttribute { }; class documentAttributeVideo final : public DocumentAttribute { + std::int32_t get_id() const final { + return ID; + } + public: int32 flags_; bool round_message_; @@ -1240,9 +1283,6 @@ class documentAttributeVideo final : public DocumentAttribute { documentAttributeVideo(int32 flags_, bool round_message_, int32 duration_, int32 w_, int32 h_); static const std::int32_t ID = 250621158; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1260,6 +1300,10 @@ class FileLocation: public Object { }; class fileLocationUnavailable final : public FileLocation { + std::int32_t get_id() const final { + return ID; + } + public: int64 volume_id_; int32 local_id_; @@ -1268,9 +1312,6 @@ class fileLocationUnavailable final : public FileLocation { fileLocationUnavailable(int64 volume_id_, int32 local_id_, int64 secret_); static const std::int32_t ID = 2086234950; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1284,6 +1325,10 @@ class fileLocationUnavailable final : public FileLocation { }; class fileLocation final : public FileLocation { + std::int32_t get_id() const final { + return ID; + } + public: int32 dc_id_; int64 volume_id_; @@ -1293,9 +1338,6 @@ class fileLocation final : public FileLocation { fileLocation(int32 dc_id_, int64 volume_id_, int32 local_id_, int64 secret_); static const std::int32_t ID = 1406570614; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1315,15 +1357,16 @@ class InputStickerSet: public Object { }; class inputStickerSetShortName final : public InputStickerSet { + std::int32_t get_id() const final { + return ID; + } + public: string short_name_; explicit inputStickerSetShortName(string const &short_name_); static const std::int32_t ID = -2044933984; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1337,13 +1380,14 @@ class inputStickerSetShortName final : public InputStickerSet { }; class inputStickerSetEmpty final : public InputStickerSet { - public: - - static const std::int32_t ID = -4838507; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -4838507; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -1360,6 +1404,10 @@ class MessageEntity: public Object { }; class messageEntityUnknown final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1367,9 +1415,6 @@ class messageEntityUnknown final : public MessageEntity { messageEntityUnknown(int32 offset_, int32 length_); static const std::int32_t ID = -1148011883; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1383,6 +1428,10 @@ class messageEntityUnknown final : public MessageEntity { }; class messageEntityMention final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1390,9 +1439,6 @@ class messageEntityMention final : public MessageEntity { messageEntityMention(int32 offset_, int32 length_); static const std::int32_t ID = -100378723; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1406,6 +1452,10 @@ class messageEntityMention final : public MessageEntity { }; class messageEntityHashtag final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1413,9 +1463,6 @@ class messageEntityHashtag final : public MessageEntity { messageEntityHashtag(int32 offset_, int32 length_); static const std::int32_t ID = 1868782349; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1429,6 +1476,10 @@ class messageEntityHashtag final : public MessageEntity { }; class messageEntityBotCommand final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1436,9 +1487,6 @@ class messageEntityBotCommand final : public MessageEntity { messageEntityBotCommand(int32 offset_, int32 length_); static const std::int32_t ID = 1827637959; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1452,6 +1500,10 @@ class messageEntityBotCommand final : public MessageEntity { }; class messageEntityUrl final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1459,9 +1511,6 @@ class messageEntityUrl final : public MessageEntity { messageEntityUrl(int32 offset_, int32 length_); static const std::int32_t ID = 1859134776; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1475,6 +1524,10 @@ class messageEntityUrl final : public MessageEntity { }; class messageEntityEmail final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1482,9 +1535,6 @@ class messageEntityEmail final : public MessageEntity { messageEntityEmail(int32 offset_, int32 length_); static const std::int32_t ID = 1692693954; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1498,6 +1548,10 @@ class messageEntityEmail final : public MessageEntity { }; class messageEntityBold final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1505,9 +1559,6 @@ class messageEntityBold final : public MessageEntity { messageEntityBold(int32 offset_, int32 length_); static const std::int32_t ID = -1117713463; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1521,6 +1572,10 @@ class messageEntityBold final : public MessageEntity { }; class messageEntityItalic final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1528,9 +1583,6 @@ class messageEntityItalic final : public MessageEntity { messageEntityItalic(int32 offset_, int32 length_); static const std::int32_t ID = -2106619040; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1544,6 +1596,10 @@ class messageEntityItalic final : public MessageEntity { }; class messageEntityCode final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1551,9 +1607,6 @@ class messageEntityCode final : public MessageEntity { messageEntityCode(int32 offset_, int32 length_); static const std::int32_t ID = 681706865; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1567,6 +1620,10 @@ class messageEntityCode final : public MessageEntity { }; class messageEntityPre final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1575,9 +1632,6 @@ class messageEntityPre final : public MessageEntity { messageEntityPre(int32 offset_, int32 length_, string const &language_); static const std::int32_t ID = 1938967520; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1591,6 +1645,10 @@ class messageEntityPre final : public MessageEntity { }; class messageEntityTextUrl final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1599,9 +1657,6 @@ class messageEntityTextUrl final : public MessageEntity { messageEntityTextUrl(int32 offset_, int32 length_, string const &url_); static const std::int32_t ID = 1990644519; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1615,6 +1670,10 @@ class messageEntityTextUrl final : public MessageEntity { }; class messageEntityMentionName final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1623,9 +1682,6 @@ class messageEntityMentionName final : public MessageEntity { messageEntityMentionName(int32 offset_, int32 length_, int32 user_id_); static const std::int32_t ID = 892193368; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1639,6 +1695,10 @@ class messageEntityMentionName final : public MessageEntity { }; class messageEntityPhone final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1646,9 +1706,6 @@ class messageEntityPhone final : public MessageEntity { messageEntityPhone(int32 offset_, int32 length_); static const std::int32_t ID = -1687559349; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1662,6 +1719,10 @@ class messageEntityPhone final : public MessageEntity { }; class messageEntityCashtag final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1669,9 +1730,6 @@ class messageEntityCashtag final : public MessageEntity { messageEntityCashtag(int32 offset_, int32 length_); static const std::int32_t ID = 1280209983; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1685,6 +1743,10 @@ class messageEntityCashtag final : public MessageEntity { }; class messageEntityBankCard final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1692,9 +1754,6 @@ class messageEntityBankCard final : public MessageEntity { messageEntityBankCard(int32 offset_, int32 length_); static const std::int32_t ID = 1981704948; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1708,6 +1767,10 @@ class messageEntityBankCard final : public MessageEntity { }; class messageEntityUnderline final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1715,9 +1778,6 @@ class messageEntityUnderline final : public MessageEntity { messageEntityUnderline(int32 offset_, int32 length_); static const std::int32_t ID = -1672577397; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1731,6 +1791,10 @@ class messageEntityUnderline final : public MessageEntity { }; class messageEntityStrike final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1738,9 +1802,6 @@ class messageEntityStrike final : public MessageEntity { messageEntityStrike(int32 offset_, int32 length_); static const std::int32_t ID = -1090087980; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1754,6 +1815,10 @@ class messageEntityStrike final : public MessageEntity { }; class messageEntityBlockquote final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1761,9 +1826,6 @@ class messageEntityBlockquote final : public MessageEntity { messageEntityBlockquote(int32 offset_, int32 length_); static const std::int32_t ID = 34469328; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1777,6 +1839,10 @@ class messageEntityBlockquote final : public MessageEntity { }; class messageEntitySpoiler final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1784,9 +1850,6 @@ class messageEntitySpoiler final : public MessageEntity { messageEntitySpoiler(int32 offset_, int32 length_); static const std::int32_t ID = 852137487; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1800,6 +1863,10 @@ class messageEntitySpoiler final : public MessageEntity { }; class messageEntityCustomEmoji final : public MessageEntity { + std::int32_t get_id() const final { + return ID; + } + public: int32 offset_; int32 length_; @@ -1808,9 +1875,6 @@ class messageEntityCustomEmoji final : public MessageEntity { messageEntityCustomEmoji(int32 offset_, int32 length_, int64 document_id_); static const std::int32_t ID = -925956616; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1823,6 +1887,8 @@ class messageEntityCustomEmoji final : public MessageEntity { void store(TlStorerToString &s, const char *field_name) const final; }; +class FileLocation; + class PhotoSize: public Object { public: @@ -1830,15 +1896,16 @@ class PhotoSize: public Object { }; class photoSizeEmpty final : public PhotoSize { + std::int32_t get_id() const final { + return ID; + } + public: string type_; explicit photoSizeEmpty(string const &type_); static const std::int32_t ID = 236446268; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1852,6 +1919,10 @@ class photoSizeEmpty final : public PhotoSize { }; class photoSize final : public PhotoSize { + std::int32_t get_id() const final { + return ID; + } + public: string type_; object_ptr location_; @@ -1862,9 +1933,6 @@ class photoSize final : public PhotoSize { photoSize(string const &type_, object_ptr &&location_, int32 w_, int32 h_, int32 size_); static const std::int32_t ID = 2009052699; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1878,6 +1946,10 @@ class photoSize final : public PhotoSize { }; class photoCachedSize final : public PhotoSize { + std::int32_t get_id() const final { + return ID; + } + public: string type_; object_ptr location_; @@ -1888,9 +1960,6 @@ class photoCachedSize final : public PhotoSize { photoCachedSize(string const &type_, object_ptr &&location_, int32 w_, int32 h_, bytes &&bytes_); static const std::int32_t ID = -374917894; - std::int32_t get_id() const final { - return ID; - } static object_ptr fetch(TlParser &p); @@ -1910,13 +1979,14 @@ class SendMessageAction: public Object { }; class sendMessageTypingAction final : public SendMessageAction { - public: - - static const std::int32_t ID = 381645902; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = 381645902; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -1927,13 +1997,14 @@ class sendMessageTypingAction final : public SendMessageAction { }; class sendMessageCancelAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -44119819; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -44119819; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -1944,13 +2015,14 @@ class sendMessageCancelAction final : public SendMessageAction { }; class sendMessageRecordVideoAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -1584933265; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -1584933265; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -1961,13 +2033,14 @@ class sendMessageRecordVideoAction final : public SendMessageAction { }; class sendMessageUploadVideoAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -1845219337; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -1845219337; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -1978,13 +2051,14 @@ class sendMessageUploadVideoAction final : public SendMessageAction { }; class sendMessageRecordAudioAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -718310409; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -718310409; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -1995,13 +2069,14 @@ class sendMessageRecordAudioAction final : public SendMessageAction { }; class sendMessageUploadAudioAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -424899985; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -424899985; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -2012,13 +2087,14 @@ class sendMessageUploadAudioAction final : public SendMessageAction { }; class sendMessageUploadPhotoAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -1727382502; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -1727382502; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -2029,13 +2105,14 @@ class sendMessageUploadPhotoAction final : public SendMessageAction { }; class sendMessageUploadDocumentAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -1884362354; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -1884362354; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -2046,13 +2123,14 @@ class sendMessageUploadDocumentAction final : public SendMessageAction { }; class sendMessageGeoLocationAction final : public SendMessageAction { - public: - - static const std::int32_t ID = 393186209; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = 393186209; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -2063,13 +2141,14 @@ class sendMessageGeoLocationAction final : public SendMessageAction { }; class sendMessageChooseContactAction final : public SendMessageAction { - public: - - static const std::int32_t ID = 1653390447; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = 1653390447; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -2080,13 +2159,14 @@ class sendMessageChooseContactAction final : public SendMessageAction { }; class sendMessageRecordRoundAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -1997373508; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -1997373508; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -2097,13 +2177,14 @@ class sendMessageRecordRoundAction final : public SendMessageAction { }; class sendMessageUploadRoundAction final : public SendMessageAction { - public: - - static const std::int32_t ID = -1150187996; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -1150187996; + static object_ptr fetch(TlParser &p); void store(TlStorerCalcLength &s) const final; @@ -2114,13 +2195,14 @@ class sendMessageUploadRoundAction final : public SendMessageAction { }; class test_dummyFunction final : public Function { - public: - - static const std::int32_t ID = -936020215; std::int32_t get_id() const final { return ID; } + public: + + static const std::int32_t ID = -936020215; + using ReturnType = bool; static object_ptr fetch(TlParser &p); diff --git a/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/td_api.cpp b/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/td_api.cpp index f025d63cbf..b5354edf92 100644 --- a/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/td_api.cpp +++ b/protocols/Telegram/tdlib/td/td/generate/auto/td/telegram/td_api.cpp @@ -17,6 +17,36 @@ std::string to_string(const BaseObject &value) { return storer.move_as_string(); } +accentColor::accentColor() + : id_() + , built_in_accent_color_id_() + , light_theme_colors_() + , dark_theme_colors_() + , min_channel_chat_boost_level_() +{} + +accentColor::accentColor(int32 id_, int32 built_in_accent_color_id_, array &&light_theme_colors_, array &&dark_theme_colors_, int32 min_channel_chat_boost_level_) + : id_(id_) + , built_in_accent_color_id_(built_in_accent_color_id_) + , light_theme_colors_(std::move(light_theme_colors_)) + , dark_theme_colors_(std::move(dark_theme_colors_)) + , min_channel_chat_boost_level_(min_channel_chat_boost_level_) +{} + +const std::int32_t accentColor::ID; + +void accentColor::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "accentColor"); + s.store_field("id", id_); + s.store_field("built_in_accent_color_id", built_in_accent_color_id_); + { s.store_vector_begin("light_theme_colors", light_theme_colors_.size()); for (const auto &_value : light_theme_colors_) { s.store_field("", _value); } s.store_class_end(); } + { s.store_vector_begin("dark_theme_colors", dark_theme_colors_.size()); for (const auto &_value : dark_theme_colors_) { s.store_field("", _value); } s.store_class_end(); } + s.store_field("min_channel_chat_boost_level", min_channel_chat_boost_level_); + s.store_class_end(); + } +} + accountTtl::accountTtl() : days_() {} @@ -38,12 +68,14 @@ void accountTtl::store(TlStorerToString &s, const char *field_name) const { addedReaction::addedReaction() : type_() , sender_id_() + , is_outgoing_() , date_() {} -addedReaction::addedReaction(object_ptr &&type_, object_ptr &&sender_id_, int32 date_) +addedReaction::addedReaction(object_ptr &&type_, object_ptr &&sender_id_, bool is_outgoing_, int32 date_) : type_(std::move(type_)) , sender_id_(std::move(sender_id_)) + , is_outgoing_(is_outgoing_) , date_(date_) {} @@ -54,6 +86,7 @@ void addedReaction::store(TlStorerToString &s, const char *field_name) const { s.store_class_begin(field_name, "addedReaction"); s.store_object_field("type", static_cast(type_.get())); s.store_object_field("sender_id", static_cast(sender_id_.get())); + s.store_field("is_outgoing", is_outgoing_); s.store_field("date", date_); s.store_class_end(); } @@ -230,6 +263,30 @@ void animations::store(TlStorerToString &s, const char *field_name) const { } } +archiveChatListSettings::archiveChatListSettings() + : archive_and_mute_new_chats_from_unknown_users_() + , keep_unmuted_chats_archived_() + , keep_chats_from_folders_archived_() +{} + +archiveChatListSettings::archiveChatListSettings(bool archive_and_mute_new_chats_from_unknown_users_, bool keep_unmuted_chats_archived_, bool keep_chats_from_folders_archived_) + : archive_and_mute_new_chats_from_unknown_users_(archive_and_mute_new_chats_from_unknown_users_) + , keep_unmuted_chats_archived_(keep_unmuted_chats_archived_) + , keep_chats_from_folders_archived_(keep_chats_from_folders_archived_) +{} + +const std::int32_t archiveChatListSettings::ID; + +void archiveChatListSettings::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "archiveChatListSettings"); + s.store_field("archive_and_mute_new_chats_from_unknown_users", archive_and_mute_new_chats_from_unknown_users_); + s.store_field("keep_unmuted_chats_archived", keep_unmuted_chats_archived_); + s.store_field("keep_chats_from_folders_archived", keep_chats_from_folders_archived_); + s.store_class_end(); + } +} + attachmentMenuBot::attachmentMenuBot() : bot_user_id_() , supports_self_chat_() @@ -237,35 +294,47 @@ attachmentMenuBot::attachmentMenuBot() , supports_bot_chats_() , supports_group_chats_() , supports_channel_chats_() - , supports_settings_() , request_write_access_() + , is_added_() + , show_in_attachment_menu_() + , show_in_side_menu_() + , show_disclaimer_in_side_menu_() , name_() , name_color_() , default_icon_() , ios_static_icon_() , ios_animated_icon_() + , ios_side_menu_icon_() , android_icon_() + , android_side_menu_icon_() , macos_icon_() + , macos_side_menu_icon_() , icon_color_() , web_app_placeholder_() {} -attachmentMenuBot::attachmentMenuBot(int53 bot_user_id_, bool supports_self_chat_, bool supports_user_chats_, bool supports_bot_chats_, bool supports_group_chats_, bool supports_channel_chats_, bool supports_settings_, bool request_write_access_, string const &name_, object_ptr &&name_color_, object_ptr &&default_icon_, object_ptr &&ios_static_icon_, object_ptr &&ios_animated_icon_, object_ptr &&android_icon_, object_ptr &&macos_icon_, object_ptr &&icon_color_, object_ptr &&web_app_placeholder_) +attachmentMenuBot::attachmentMenuBot(int53 bot_user_id_, bool supports_self_chat_, bool supports_user_chats_, bool supports_bot_chats_, bool supports_group_chats_, bool supports_channel_chats_, bool request_write_access_, bool is_added_, bool show_in_attachment_menu_, bool show_in_side_menu_, bool show_disclaimer_in_side_menu_, string const &name_, object_ptr &&name_color_, object_ptr &&default_icon_, object_ptr &&ios_static_icon_, object_ptr &&ios_animated_icon_, object_ptr &&ios_side_menu_icon_, object_ptr &&android_icon_, object_ptr &&android_side_menu_icon_, object_ptr &&macos_icon_, object_ptr &&macos_side_menu_icon_, object_ptr &&icon_color_, object_ptr &&web_app_placeholder_) : bot_user_id_(bot_user_id_) , supports_self_chat_(supports_self_chat_) , supports_user_chats_(supports_user_chats_) , supports_bot_chats_(supports_bot_chats_) , supports_group_chats_(supports_group_chats_) , supports_channel_chats_(supports_channel_chats_) - , supports_settings_(supports_settings_) , request_write_access_(request_write_access_) + , is_added_(is_added_) + , show_in_attachment_menu_(show_in_attachment_menu_) + , show_in_side_menu_(show_in_side_menu_) + , show_disclaimer_in_side_menu_(show_disclaimer_in_side_menu_) , name_(name_) , name_color_(std::move(name_color_)) , default_icon_(std::move(default_icon_)) , ios_static_icon_(std::move(ios_static_icon_)) , ios_animated_icon_(std::move(ios_animated_icon_)) + , ios_side_menu_icon_(std::move(ios_side_menu_icon_)) , android_icon_(std::move(android_icon_)) + , android_side_menu_icon_(std::move(android_side_menu_icon_)) , macos_icon_(std::move(macos_icon_)) + , macos_side_menu_icon_(std::move(macos_side_menu_icon_)) , icon_color_(std::move(icon_color_)) , web_app_placeholder_(std::move(web_app_placeholder_)) {} @@ -281,15 +350,21 @@ void attachmentMenuBot::store(TlStorerToString &s, const char *field_name) const s.store_field("supports_bot_chats", supports_bot_chats_); s.store_field("supports_group_chats", supports_group_chats_); s.store_field("supports_channel_chats", supports_channel_chats_); - s.store_field("supports_settings", supports_settings_); s.store_field("request_write_access", request_write_access_); + s.store_field("is_added", is_added_); + s.store_field("show_in_attachment_menu", show_in_attachment_menu_); + s.store_field("show_in_side_menu", show_in_side_menu_); + s.store_field("show_disclaimer_in_side_menu", show_disclaimer_in_side_menu_); s.store_field("name", name_); s.store_object_field("name_color", static_cast(name_color_.get())); s.store_object_field("default_icon", static_cast(default_icon_.get())); s.store_object_field("ios_static_icon", static_cast(ios_static_icon_.get())); s.store_object_field("ios_animated_icon", static_cast(ios_animated_icon_.get())); + s.store_object_field("ios_side_menu_icon", static_cast(ios_side_menu_icon_.get())); s.store_object_field("android_icon", static_cast(android_icon_.get())); + s.store_object_field("android_side_menu_icon", static_cast(android_side_menu_icon_.get())); s.store_object_field("macos_icon", static_cast(macos_icon_.get())); + s.store_object_field("macos_side_menu_icon", static_cast(macos_side_menu_icon_.get())); s.store_object_field("icon_color", static_cast(icon_color_.get())); s.store_object_field("web_app_placeholder", static_cast(web_app_placeholder_.get())); s.store_class_end(); @@ -422,6 +497,42 @@ void authenticationCodeTypeSms::store(TlStorerToString &s, const char *field_nam } } +authenticationCodeTypeSmsWord::authenticationCodeTypeSmsWord() + : first_letter_() +{} + +authenticationCodeTypeSmsWord::authenticationCodeTypeSmsWord(string const &first_letter_) + : first_letter_(first_letter_) +{} + +const std::int32_t authenticationCodeTypeSmsWord::ID; + +void authenticationCodeTypeSmsWord::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "authenticationCodeTypeSmsWord"); + s.store_field("first_letter", first_letter_); + s.store_class_end(); + } +} + +authenticationCodeTypeSmsPhrase::authenticationCodeTypeSmsPhrase() + : first_word_() +{} + +authenticationCodeTypeSmsPhrase::authenticationCodeTypeSmsPhrase(string const &first_word_) + : first_word_(first_word_) +{} + +const std::int32_t authenticationCodeTypeSmsPhrase::ID; + +void authenticationCodeTypeSmsPhrase::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "authenticationCodeTypeSmsPhrase"); + s.store_field("first_word", first_word_); + s.store_class_end(); + } +} + authenticationCodeTypeCall::authenticationCodeTypeCall() : length_() {} @@ -501,12 +612,12 @@ void authenticationCodeTypeFragment::store(TlStorerToString &s, const char *fiel } authenticationCodeTypeFirebaseAndroid::authenticationCodeTypeFirebaseAndroid() - : nonce_() + : device_verification_parameters_() , length_() {} -authenticationCodeTypeFirebaseAndroid::authenticationCodeTypeFirebaseAndroid(bytes const &nonce_, int32 length_) - : nonce_(std::move(nonce_)) +authenticationCodeTypeFirebaseAndroid::authenticationCodeTypeFirebaseAndroid(object_ptr &&device_verification_parameters_, int32 length_) + : device_verification_parameters_(std::move(device_verification_parameters_)) , length_(length_) {} @@ -515,7 +626,7 @@ const std::int32_t authenticationCodeTypeFirebaseAndroid::ID; void authenticationCodeTypeFirebaseAndroid::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { s.store_class_begin(field_name, "authenticationCodeTypeFirebaseAndroid"); - s.store_bytes_field("nonce", nonce_); + s.store_object_field("device_verification_parameters", static_cast(device_verification_parameters_.get())); s.store_field("length", length_); s.store_class_end(); } @@ -754,10 +865,11 @@ autoDownloadSettings::autoDownloadSettings() , video_upload_bitrate_() , preload_large_videos_() , preload_next_audio_() + , preload_stories_() , use_less_data_for_calls_() {} -autoDownloadSettings::autoDownloadSettings(bool is_auto_download_enabled_, int32 max_photo_file_size_, int53 max_video_file_size_, int53 max_other_file_size_, int32 video_upload_bitrate_, bool preload_large_videos_, bool preload_next_audio_, bool use_less_data_for_calls_) +autoDownloadSettings::autoDownloadSettings(bool is_auto_download_enabled_, int32 max_photo_file_size_, int53 max_video_file_size_, int53 max_other_file_size_, int32 video_upload_bitrate_, bool preload_large_videos_, bool preload_next_audio_, bool preload_stories_, bool use_less_data_for_calls_) : is_auto_download_enabled_(is_auto_download_enabled_) , max_photo_file_size_(max_photo_file_size_) , max_video_file_size_(max_video_file_size_) @@ -765,6 +877,7 @@ autoDownloadSettings::autoDownloadSettings(bool is_auto_download_enabled_, int32 , video_upload_bitrate_(video_upload_bitrate_) , preload_large_videos_(preload_large_videos_) , preload_next_audio_(preload_next_audio_) + , preload_stories_(preload_stories_) , use_less_data_for_calls_(use_less_data_for_calls_) {} @@ -780,6 +893,7 @@ void autoDownloadSettings::store(TlStorerToString &s, const char *field_name) co s.store_field("video_upload_bitrate", video_upload_bitrate_); s.store_field("preload_large_videos", preload_large_videos_); s.store_field("preload_next_audio", preload_next_audio_); + s.store_field("preload_stories", preload_stories_); s.store_field("use_less_data_for_calls", use_less_data_for_calls_); s.store_class_end(); } @@ -937,13 +1051,17 @@ availableReactions::availableReactions() , recent_reactions_() , popular_reactions_() , allow_custom_emoji_() + , are_tags_() + , unavailability_reason_() {} -availableReactions::availableReactions(array> &&top_reactions_, array> &&recent_reactions_, array> &&popular_reactions_, bool allow_custom_emoji_) +availableReactions::availableReactions(array> &&top_reactions_, array> &&recent_reactions_, array> &&popular_reactions_, bool allow_custom_emoji_, bool are_tags_, object_ptr &&unavailability_reason_) : top_reactions_(std::move(top_reactions_)) , recent_reactions_(std::move(recent_reactions_)) , popular_reactions_(std::move(popular_reactions_)) , allow_custom_emoji_(allow_custom_emoji_) + , are_tags_(are_tags_) + , unavailability_reason_(std::move(unavailability_reason_)) {} const std::int32_t availableReactions::ID; @@ -955,6 +1073,8 @@ void availableReactions::store(TlStorerToString &s, const char *field_name) cons { s.store_vector_begin("recent_reactions", recent_reactions_.size()); for (const auto &_value : recent_reactions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } { s.store_vector_begin("popular_reactions", popular_reactions_.size()); for (const auto &_value : popular_reactions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_field("allow_custom_emoji", allow_custom_emoji_); + s.store_field("are_tags", are_tags_); + s.store_object_field("unavailability_reason", static_cast(unavailability_reason_.get())); s.store_class_end(); } } @@ -1118,6 +1238,24 @@ void backgroundTypeFill::store(TlStorerToString &s, const char *field_name) cons } } +backgroundTypeChatTheme::backgroundTypeChatTheme() + : theme_name_() +{} + +backgroundTypeChatTheme::backgroundTypeChatTheme(string const &theme_name_) + : theme_name_(theme_name_) +{} + +const std::int32_t backgroundTypeChatTheme::ID; + +void backgroundTypeChatTheme::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "backgroundTypeChatTheme"); + s.store_field("theme_name", theme_name_); + s.store_class_end(); + } +} + backgrounds::backgrounds() : backgrounds_() {} @@ -1247,6 +1385,54 @@ void basicGroupFullInfo::store(TlStorerToString &s, const char *field_name) cons } } +birthdate::birthdate() + : day_() + , month_() + , year_() +{} + +birthdate::birthdate(int32 day_, int32 month_, int32 year_) + : day_(day_) + , month_(month_) + , year_(year_) +{} + +const std::int32_t birthdate::ID; + +void birthdate::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "birthdate"); + s.store_field("day", day_); + s.store_field("month", month_); + s.store_field("year", year_); + s.store_class_end(); + } +} + +blockListMain::blockListMain() { +} + +const std::int32_t blockListMain::ID; + +void blockListMain::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "blockListMain"); + s.store_class_end(); + } +} + +blockListStories::blockListStories() { +} + +const std::int32_t blockListStories::ID; + +void blockListStories::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "blockListStories"); + s.store_class_end(); + } +} + botCommand::botCommand() : command_() , description_() @@ -1401,23 +1587,27 @@ botInfo::botInfo() , animation_() , menu_button_() , commands_() + , privacy_policy_url_() , default_group_administrator_rights_() , default_channel_administrator_rights_() + , has_media_previews_() , edit_commands_link_() , edit_description_link_() , edit_description_media_link_() , edit_settings_link_() {} -botInfo::botInfo(string const &short_description_, string const &description_, object_ptr &&photo_, object_ptr &&animation_, object_ptr &&menu_button_, array> &&commands_, object_ptr &&default_group_administrator_rights_, object_ptr &&default_channel_administrator_rights_, object_ptr &&edit_commands_link_, object_ptr &&edit_description_link_, object_ptr &&edit_description_media_link_, object_ptr &&edit_settings_link_) +botInfo::botInfo(string const &short_description_, string const &description_, object_ptr &&photo_, object_ptr &&animation_, object_ptr &&menu_button_, array> &&commands_, string const &privacy_policy_url_, object_ptr &&default_group_administrator_rights_, object_ptr &&default_channel_administrator_rights_, bool has_media_previews_, object_ptr &&edit_commands_link_, object_ptr &&edit_description_link_, object_ptr &&edit_description_media_link_, object_ptr &&edit_settings_link_) : short_description_(short_description_) , description_(description_) , photo_(std::move(photo_)) , animation_(std::move(animation_)) , menu_button_(std::move(menu_button_)) , commands_(std::move(commands_)) + , privacy_policy_url_(privacy_policy_url_) , default_group_administrator_rights_(std::move(default_group_administrator_rights_)) , default_channel_administrator_rights_(std::move(default_channel_administrator_rights_)) + , has_media_previews_(has_media_previews_) , edit_commands_link_(std::move(edit_commands_link_)) , edit_description_link_(std::move(edit_description_link_)) , edit_description_media_link_(std::move(edit_description_media_link_)) @@ -1435,8 +1625,10 @@ void botInfo::store(TlStorerToString &s, const char *field_name) const { s.store_object_field("animation", static_cast(animation_.get())); s.store_object_field("menu_button", static_cast(menu_button_.get())); { s.store_vector_begin("commands", commands_.size()); for (const auto &_value : commands_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("privacy_policy_url", privacy_policy_url_); s.store_object_field("default_group_administrator_rights", static_cast(default_group_administrator_rights_.get())); s.store_object_field("default_channel_administrator_rights", static_cast(default_channel_administrator_rights_.get())); + s.store_field("has_media_previews", has_media_previews_); s.store_object_field("edit_commands_link", static_cast(edit_commands_link_.get())); s.store_object_field("edit_description_link", static_cast(edit_description_link_.get())); s.store_object_field("edit_description_media_link", static_cast(edit_description_media_link_.get())); @@ -1445,18143 +1637,25706 @@ void botInfo::store(TlStorerToString &s, const char *field_name) const { } } -botMenuButton::botMenuButton() - : text_() - , url_() +botMediaPreview::botMediaPreview() + : date_() + , content_() {} -botMenuButton::botMenuButton(string const &text_, string const &url_) - : text_(text_) - , url_(url_) +botMediaPreview::botMediaPreview(int32 date_, object_ptr &&content_) + : date_(date_) + , content_(std::move(content_)) {} -const std::int32_t botMenuButton::ID; +const std::int32_t botMediaPreview::ID; -void botMenuButton::store(TlStorerToString &s, const char *field_name) const { +void botMediaPreview::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "botMenuButton"); - s.store_field("text", text_); - s.store_field("url", url_); + s.store_class_begin(field_name, "botMediaPreview"); + s.store_field("date", date_); + s.store_object_field("content", static_cast(content_.get())); s.store_class_end(); } } -call::call() - : id_() - , user_id_() - , is_outgoing_() - , is_video_() - , state_() +botMediaPreviewInfo::botMediaPreviewInfo() + : previews_() + , language_codes_() {} -call::call(int32 id_, int53 user_id_, bool is_outgoing_, bool is_video_, object_ptr &&state_) - : id_(id_) - , user_id_(user_id_) - , is_outgoing_(is_outgoing_) - , is_video_(is_video_) - , state_(std::move(state_)) +botMediaPreviewInfo::botMediaPreviewInfo(array> &&previews_, array &&language_codes_) + : previews_(std::move(previews_)) + , language_codes_(std::move(language_codes_)) {} -const std::int32_t call::ID; +const std::int32_t botMediaPreviewInfo::ID; -void call::store(TlStorerToString &s, const char *field_name) const { +void botMediaPreviewInfo::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "call"); - s.store_field("id", id_); - s.store_field("user_id", user_id_); - s.store_field("is_outgoing", is_outgoing_); - s.store_field("is_video", is_video_); - s.store_object_field("state", static_cast(state_.get())); + s.store_class_begin(field_name, "botMediaPreviewInfo"); + { s.store_vector_begin("previews", previews_.size()); for (const auto &_value : previews_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + { s.store_vector_begin("language_codes", language_codes_.size()); for (const auto &_value : language_codes_) { s.store_field("", _value); } s.store_class_end(); } s.store_class_end(); } } -callDiscardReasonEmpty::callDiscardReasonEmpty() { -} - -const std::int32_t callDiscardReasonEmpty::ID; - -void callDiscardReasonEmpty::store(TlStorerToString &s, const char *field_name) const { - if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callDiscardReasonEmpty"); - s.store_class_end(); - } -} +botMediaPreviews::botMediaPreviews() + : previews_() +{} -callDiscardReasonMissed::callDiscardReasonMissed() { -} +botMediaPreviews::botMediaPreviews(array> &&previews_) + : previews_(std::move(previews_)) +{} -const std::int32_t callDiscardReasonMissed::ID; +const std::int32_t botMediaPreviews::ID; -void callDiscardReasonMissed::store(TlStorerToString &s, const char *field_name) const { +void botMediaPreviews::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callDiscardReasonMissed"); + s.store_class_begin(field_name, "botMediaPreviews"); + { s.store_vector_begin("previews", previews_.size()); for (const auto &_value : previews_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -callDiscardReasonDeclined::callDiscardReasonDeclined() { -} +botMenuButton::botMenuButton() + : text_() + , url_() +{} -const std::int32_t callDiscardReasonDeclined::ID; +botMenuButton::botMenuButton(string const &text_, string const &url_) + : text_(text_) + , url_(url_) +{} -void callDiscardReasonDeclined::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t botMenuButton::ID; + +void botMenuButton::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callDiscardReasonDeclined"); + s.store_class_begin(field_name, "botMenuButton"); + s.store_field("text", text_); + s.store_field("url", url_); s.store_class_end(); } } -callDiscardReasonDisconnected::callDiscardReasonDisconnected() { -} +botTransactionPurposePaidMedia::botTransactionPurposePaidMedia() + : media_() + , payload_() +{} -const std::int32_t callDiscardReasonDisconnected::ID; +botTransactionPurposePaidMedia::botTransactionPurposePaidMedia(array> &&media_, string const &payload_) + : media_(std::move(media_)) + , payload_(payload_) +{} -void callDiscardReasonDisconnected::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t botTransactionPurposePaidMedia::ID; + +void botTransactionPurposePaidMedia::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callDiscardReasonDisconnected"); + s.store_class_begin(field_name, "botTransactionPurposePaidMedia"); + { s.store_vector_begin("media", media_.size()); for (const auto &_value : media_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("payload", payload_); s.store_class_end(); } } -callDiscardReasonHungUp::callDiscardReasonHungUp() { -} +botTransactionPurposeInvoicePayment::botTransactionPurposeInvoicePayment() + : product_info_() + , invoice_payload_() +{} -const std::int32_t callDiscardReasonHungUp::ID; +botTransactionPurposeInvoicePayment::botTransactionPurposeInvoicePayment(object_ptr &&product_info_, bytes const &invoice_payload_) + : product_info_(std::move(product_info_)) + , invoice_payload_(std::move(invoice_payload_)) +{} -void callDiscardReasonHungUp::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t botTransactionPurposeInvoicePayment::ID; + +void botTransactionPurposeInvoicePayment::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callDiscardReasonHungUp"); + s.store_class_begin(field_name, "botTransactionPurposeInvoicePayment"); + s.store_object_field("product_info", static_cast(product_info_.get())); + s.store_bytes_field("invoice_payload", invoice_payload_); s.store_class_end(); } } -callId::callId() - : id_() +botWriteAccessAllowReasonConnectedWebsite::botWriteAccessAllowReasonConnectedWebsite() + : domain_name_() {} -callId::callId(int32 id_) - : id_(id_) +botWriteAccessAllowReasonConnectedWebsite::botWriteAccessAllowReasonConnectedWebsite(string const &domain_name_) + : domain_name_(domain_name_) {} -const std::int32_t callId::ID; +const std::int32_t botWriteAccessAllowReasonConnectedWebsite::ID; -void callId::store(TlStorerToString &s, const char *field_name) const { +void botWriteAccessAllowReasonConnectedWebsite::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callId"); - s.store_field("id", id_); + s.store_class_begin(field_name, "botWriteAccessAllowReasonConnectedWebsite"); + s.store_field("domain_name", domain_name_); s.store_class_end(); } } -callProblemEcho::callProblemEcho() { +botWriteAccessAllowReasonAddedToAttachmentMenu::botWriteAccessAllowReasonAddedToAttachmentMenu() { } -const std::int32_t callProblemEcho::ID; +const std::int32_t botWriteAccessAllowReasonAddedToAttachmentMenu::ID; -void callProblemEcho::store(TlStorerToString &s, const char *field_name) const { +void botWriteAccessAllowReasonAddedToAttachmentMenu::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemEcho"); + s.store_class_begin(field_name, "botWriteAccessAllowReasonAddedToAttachmentMenu"); s.store_class_end(); } } -callProblemNoise::callProblemNoise() { -} +botWriteAccessAllowReasonLaunchedWebApp::botWriteAccessAllowReasonLaunchedWebApp() + : web_app_() +{} -const std::int32_t callProblemNoise::ID; +botWriteAccessAllowReasonLaunchedWebApp::botWriteAccessAllowReasonLaunchedWebApp(object_ptr &&web_app_) + : web_app_(std::move(web_app_)) +{} -void callProblemNoise::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t botWriteAccessAllowReasonLaunchedWebApp::ID; + +void botWriteAccessAllowReasonLaunchedWebApp::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemNoise"); + s.store_class_begin(field_name, "botWriteAccessAllowReasonLaunchedWebApp"); + s.store_object_field("web_app", static_cast(web_app_.get())); s.store_class_end(); } } -callProblemInterruptions::callProblemInterruptions() { +botWriteAccessAllowReasonAcceptedRequest::botWriteAccessAllowReasonAcceptedRequest() { } -const std::int32_t callProblemInterruptions::ID; +const std::int32_t botWriteAccessAllowReasonAcceptedRequest::ID; -void callProblemInterruptions::store(TlStorerToString &s, const char *field_name) const { +void botWriteAccessAllowReasonAcceptedRequest::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemInterruptions"); + s.store_class_begin(field_name, "botWriteAccessAllowReasonAcceptedRequest"); s.store_class_end(); } } -callProblemDistortedSpeech::callProblemDistortedSpeech() { +businessAwayMessageScheduleAlways::businessAwayMessageScheduleAlways() { } -const std::int32_t callProblemDistortedSpeech::ID; +const std::int32_t businessAwayMessageScheduleAlways::ID; -void callProblemDistortedSpeech::store(TlStorerToString &s, const char *field_name) const { +void businessAwayMessageScheduleAlways::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemDistortedSpeech"); + s.store_class_begin(field_name, "businessAwayMessageScheduleAlways"); s.store_class_end(); } } -callProblemSilentLocal::callProblemSilentLocal() { +businessAwayMessageScheduleOutsideOfOpeningHours::businessAwayMessageScheduleOutsideOfOpeningHours() { } -const std::int32_t callProblemSilentLocal::ID; +const std::int32_t businessAwayMessageScheduleOutsideOfOpeningHours::ID; -void callProblemSilentLocal::store(TlStorerToString &s, const char *field_name) const { +void businessAwayMessageScheduleOutsideOfOpeningHours::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemSilentLocal"); + s.store_class_begin(field_name, "businessAwayMessageScheduleOutsideOfOpeningHours"); s.store_class_end(); } } -callProblemSilentRemote::callProblemSilentRemote() { -} +businessAwayMessageScheduleCustom::businessAwayMessageScheduleCustom() + : start_date_() + , end_date_() +{} -const std::int32_t callProblemSilentRemote::ID; +businessAwayMessageScheduleCustom::businessAwayMessageScheduleCustom(int32 start_date_, int32 end_date_) + : start_date_(start_date_) + , end_date_(end_date_) +{} -void callProblemSilentRemote::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t businessAwayMessageScheduleCustom::ID; + +void businessAwayMessageScheduleCustom::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemSilentRemote"); + s.store_class_begin(field_name, "businessAwayMessageScheduleCustom"); + s.store_field("start_date", start_date_); + s.store_field("end_date", end_date_); s.store_class_end(); } } -callProblemDropped::callProblemDropped() { -} +businessAwayMessageSettings::businessAwayMessageSettings() + : shortcut_id_() + , recipients_() + , schedule_() + , offline_only_() +{} -const std::int32_t callProblemDropped::ID; +businessAwayMessageSettings::businessAwayMessageSettings(int32 shortcut_id_, object_ptr &&recipients_, object_ptr &&schedule_, bool offline_only_) + : shortcut_id_(shortcut_id_) + , recipients_(std::move(recipients_)) + , schedule_(std::move(schedule_)) + , offline_only_(offline_only_) +{} -void callProblemDropped::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t businessAwayMessageSettings::ID; + +void businessAwayMessageSettings::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemDropped"); + s.store_class_begin(field_name, "businessAwayMessageSettings"); + s.store_field("shortcut_id", shortcut_id_); + s.store_object_field("recipients", static_cast(recipients_.get())); + s.store_object_field("schedule", static_cast(schedule_.get())); + s.store_field("offline_only", offline_only_); s.store_class_end(); } } -callProblemDistortedVideo::callProblemDistortedVideo() { -} +businessBotManageBar::businessBotManageBar() + : bot_user_id_() + , manage_url_() + , is_bot_paused_() + , can_bot_reply_() +{} -const std::int32_t callProblemDistortedVideo::ID; +businessBotManageBar::businessBotManageBar(int53 bot_user_id_, string const &manage_url_, bool is_bot_paused_, bool can_bot_reply_) + : bot_user_id_(bot_user_id_) + , manage_url_(manage_url_) + , is_bot_paused_(is_bot_paused_) + , can_bot_reply_(can_bot_reply_) +{} -void callProblemDistortedVideo::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t businessBotManageBar::ID; + +void businessBotManageBar::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemDistortedVideo"); + s.store_class_begin(field_name, "businessBotManageBar"); + s.store_field("bot_user_id", bot_user_id_); + s.store_field("manage_url", manage_url_); + s.store_field("is_bot_paused", is_bot_paused_); + s.store_field("can_bot_reply", can_bot_reply_); s.store_class_end(); } } -callProblemPixelatedVideo::callProblemPixelatedVideo() { -} +businessChatLink::businessChatLink() + : link_() + , text_() + , title_() + , view_count_() +{} -const std::int32_t callProblemPixelatedVideo::ID; +businessChatLink::businessChatLink(string const &link_, object_ptr &&text_, string const &title_, int32 view_count_) + : link_(link_) + , text_(std::move(text_)) + , title_(title_) + , view_count_(view_count_) +{} -void callProblemPixelatedVideo::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t businessChatLink::ID; + +void businessChatLink::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProblemPixelatedVideo"); + s.store_class_begin(field_name, "businessChatLink"); + s.store_field("link", link_); + s.store_object_field("text", static_cast(text_.get())); + s.store_field("title", title_); + s.store_field("view_count", view_count_); s.store_class_end(); } } -callProtocol::callProtocol() - : udp_p2p_() - , udp_reflector_() - , min_layer_() - , max_layer_() - , library_versions_() +businessChatLinkInfo::businessChatLinkInfo() + : chat_id_() + , text_() {} -callProtocol::callProtocol(bool udp_p2p_, bool udp_reflector_, int32 min_layer_, int32 max_layer_, array &&library_versions_) - : udp_p2p_(udp_p2p_) - , udp_reflector_(udp_reflector_) - , min_layer_(min_layer_) - , max_layer_(max_layer_) - , library_versions_(std::move(library_versions_)) +businessChatLinkInfo::businessChatLinkInfo(int53 chat_id_, object_ptr &&text_) + : chat_id_(chat_id_) + , text_(std::move(text_)) {} -const std::int32_t callProtocol::ID; +const std::int32_t businessChatLinkInfo::ID; -void callProtocol::store(TlStorerToString &s, const char *field_name) const { +void businessChatLinkInfo::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callProtocol"); - s.store_field("udp_p2p", udp_p2p_); - s.store_field("udp_reflector", udp_reflector_); - s.store_field("min_layer", min_layer_); - s.store_field("max_layer", max_layer_); - { s.store_vector_begin("library_versions", library_versions_.size()); for (const auto &_value : library_versions_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_begin(field_name, "businessChatLinkInfo"); + s.store_field("chat_id", chat_id_); + s.store_object_field("text", static_cast(text_.get())); s.store_class_end(); } } -callServer::callServer() - : id_() - , ip_address_() - , ipv6_address_() - , port_() - , type_() +businessChatLinks::businessChatLinks() + : links_() {} -callServer::callServer(int64 id_, string const &ip_address_, string const &ipv6_address_, int32 port_, object_ptr &&type_) - : id_(id_) - , ip_address_(ip_address_) - , ipv6_address_(ipv6_address_) - , port_(port_) - , type_(std::move(type_)) +businessChatLinks::businessChatLinks(array> &&links_) + : links_(std::move(links_)) {} -const std::int32_t callServer::ID; +const std::int32_t businessChatLinks::ID; -void callServer::store(TlStorerToString &s, const char *field_name) const { +void businessChatLinks::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callServer"); - s.store_field("id", id_); - s.store_field("ip_address", ip_address_); - s.store_field("ipv6_address", ipv6_address_); - s.store_field("port", port_); - s.store_object_field("type", static_cast(type_.get())); + s.store_class_begin(field_name, "businessChatLinks"); + { s.store_vector_begin("links", links_.size()); for (const auto &_value : links_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -callServerTypeTelegramReflector::callServerTypeTelegramReflector() - : peer_tag_() - , is_tcp_() +businessConnectedBot::businessConnectedBot() + : bot_user_id_() + , recipients_() + , can_reply_() {} -callServerTypeTelegramReflector::callServerTypeTelegramReflector(bytes const &peer_tag_, bool is_tcp_) - : peer_tag_(std::move(peer_tag_)) - , is_tcp_(is_tcp_) +businessConnectedBot::businessConnectedBot(int53 bot_user_id_, object_ptr &&recipients_, bool can_reply_) + : bot_user_id_(bot_user_id_) + , recipients_(std::move(recipients_)) + , can_reply_(can_reply_) {} -const std::int32_t callServerTypeTelegramReflector::ID; +const std::int32_t businessConnectedBot::ID; -void callServerTypeTelegramReflector::store(TlStorerToString &s, const char *field_name) const { +void businessConnectedBot::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callServerTypeTelegramReflector"); - s.store_bytes_field("peer_tag", peer_tag_); - s.store_field("is_tcp", is_tcp_); + s.store_class_begin(field_name, "businessConnectedBot"); + s.store_field("bot_user_id", bot_user_id_); + s.store_object_field("recipients", static_cast(recipients_.get())); + s.store_field("can_reply", can_reply_); s.store_class_end(); } } -callServerTypeWebrtc::callServerTypeWebrtc() - : username_() - , password_() - , supports_turn_() - , supports_stun_() +businessConnection::businessConnection() + : id_() + , user_id_() + , user_chat_id_() + , date_() + , can_reply_() + , is_enabled_() {} -callServerTypeWebrtc::callServerTypeWebrtc(string const &username_, string const &password_, bool supports_turn_, bool supports_stun_) - : username_(username_) - , password_(password_) - , supports_turn_(supports_turn_) - , supports_stun_(supports_stun_) +businessConnection::businessConnection(string const &id_, int53 user_id_, int53 user_chat_id_, int32 date_, bool can_reply_, bool is_enabled_) + : id_(id_) + , user_id_(user_id_) + , user_chat_id_(user_chat_id_) + , date_(date_) + , can_reply_(can_reply_) + , is_enabled_(is_enabled_) {} -const std::int32_t callServerTypeWebrtc::ID; +const std::int32_t businessConnection::ID; -void callServerTypeWebrtc::store(TlStorerToString &s, const char *field_name) const { +void businessConnection::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callServerTypeWebrtc"); - s.store_field("username", username_); - s.store_field("password", password_); - s.store_field("supports_turn", supports_turn_); - s.store_field("supports_stun", supports_stun_); + s.store_class_begin(field_name, "businessConnection"); + s.store_field("id", id_); + s.store_field("user_id", user_id_); + s.store_field("user_chat_id", user_chat_id_); + s.store_field("date", date_); + s.store_field("can_reply", can_reply_); + s.store_field("is_enabled", is_enabled_); s.store_class_end(); } } -callStatePending::callStatePending() - : is_created_() - , is_received_() -{} - -callStatePending::callStatePending(bool is_created_, bool is_received_) - : is_created_(is_created_) - , is_received_(is_received_) -{} +businessFeatureLocation::businessFeatureLocation() { +} -const std::int32_t callStatePending::ID; +const std::int32_t businessFeatureLocation::ID; -void callStatePending::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureLocation::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callStatePending"); - s.store_field("is_created", is_created_); - s.store_field("is_received", is_received_); + s.store_class_begin(field_name, "businessFeatureLocation"); s.store_class_end(); } } -callStateExchangingKeys::callStateExchangingKeys() { +businessFeatureOpeningHours::businessFeatureOpeningHours() { } -const std::int32_t callStateExchangingKeys::ID; +const std::int32_t businessFeatureOpeningHours::ID; -void callStateExchangingKeys::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureOpeningHours::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callStateExchangingKeys"); + s.store_class_begin(field_name, "businessFeatureOpeningHours"); s.store_class_end(); } } -callStateReady::callStateReady() - : protocol_() - , servers_() - , config_() - , encryption_key_() - , emojis_() - , allow_p2p_() -{} - -callStateReady::callStateReady(object_ptr &&protocol_, array> &&servers_, string const &config_, bytes const &encryption_key_, array &&emojis_, bool allow_p2p_) - : protocol_(std::move(protocol_)) - , servers_(std::move(servers_)) - , config_(config_) - , encryption_key_(std::move(encryption_key_)) - , emojis_(std::move(emojis_)) - , allow_p2p_(allow_p2p_) -{} +businessFeatureQuickReplies::businessFeatureQuickReplies() { +} -const std::int32_t callStateReady::ID; +const std::int32_t businessFeatureQuickReplies::ID; -void callStateReady::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureQuickReplies::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callStateReady"); - s.store_object_field("protocol", static_cast(protocol_.get())); - { s.store_vector_begin("servers", servers_.size()); for (const auto &_value : servers_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } - s.store_field("config", config_); - s.store_bytes_field("encryption_key", encryption_key_); - { s.store_vector_begin("emojis", emojis_.size()); for (const auto &_value : emojis_) { s.store_field("", _value); } s.store_class_end(); } - s.store_field("allow_p2p", allow_p2p_); + s.store_class_begin(field_name, "businessFeatureQuickReplies"); s.store_class_end(); } } -callStateHangingUp::callStateHangingUp() { +businessFeatureGreetingMessage::businessFeatureGreetingMessage() { } -const std::int32_t callStateHangingUp::ID; +const std::int32_t businessFeatureGreetingMessage::ID; -void callStateHangingUp::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureGreetingMessage::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callStateHangingUp"); + s.store_class_begin(field_name, "businessFeatureGreetingMessage"); s.store_class_end(); } } -callStateDiscarded::callStateDiscarded() - : reason_() - , need_rating_() - , need_debug_information_() - , need_log_() -{} - -callStateDiscarded::callStateDiscarded(object_ptr &&reason_, bool need_rating_, bool need_debug_information_, bool need_log_) - : reason_(std::move(reason_)) - , need_rating_(need_rating_) - , need_debug_information_(need_debug_information_) - , need_log_(need_log_) -{} +businessFeatureAwayMessage::businessFeatureAwayMessage() { +} -const std::int32_t callStateDiscarded::ID; +const std::int32_t businessFeatureAwayMessage::ID; -void callStateDiscarded::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureAwayMessage::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callStateDiscarded"); - s.store_object_field("reason", static_cast(reason_.get())); - s.store_field("need_rating", need_rating_); - s.store_field("need_debug_information", need_debug_information_); - s.store_field("need_log", need_log_); + s.store_class_begin(field_name, "businessFeatureAwayMessage"); s.store_class_end(); } } -callStateError::callStateError() - : error_() -{} - -callStateError::callStateError(object_ptr &&error_) - : error_(std::move(error_)) -{} +businessFeatureAccountLinks::businessFeatureAccountLinks() { +} -const std::int32_t callStateError::ID; +const std::int32_t businessFeatureAccountLinks::ID; -void callStateError::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureAccountLinks::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callStateError"); - s.store_object_field("error", static_cast(error_.get())); + s.store_class_begin(field_name, "businessFeatureAccountLinks"); s.store_class_end(); } } -callbackQueryAnswer::callbackQueryAnswer() - : text_() - , show_alert_() - , url_() -{} - -callbackQueryAnswer::callbackQueryAnswer(string const &text_, bool show_alert_, string const &url_) - : text_(text_) - , show_alert_(show_alert_) - , url_(url_) -{} +businessFeatureStartPage::businessFeatureStartPage() { +} -const std::int32_t callbackQueryAnswer::ID; +const std::int32_t businessFeatureStartPage::ID; -void callbackQueryAnswer::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureStartPage::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callbackQueryAnswer"); - s.store_field("text", text_); - s.store_field("show_alert", show_alert_); - s.store_field("url", url_); + s.store_class_begin(field_name, "businessFeatureStartPage"); s.store_class_end(); } } -callbackQueryPayloadData::callbackQueryPayloadData() - : data_() -{} - -callbackQueryPayloadData::callbackQueryPayloadData(bytes const &data_) - : data_(std::move(data_)) -{} +businessFeatureBots::businessFeatureBots() { +} -const std::int32_t callbackQueryPayloadData::ID; +const std::int32_t businessFeatureBots::ID; -void callbackQueryPayloadData::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureBots::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callbackQueryPayloadData"); - s.store_bytes_field("data", data_); + s.store_class_begin(field_name, "businessFeatureBots"); s.store_class_end(); } } -callbackQueryPayloadDataWithPassword::callbackQueryPayloadDataWithPassword() - : password_() - , data_() -{} - -callbackQueryPayloadDataWithPassword::callbackQueryPayloadDataWithPassword(string const &password_, bytes const &data_) - : password_(password_) - , data_(std::move(data_)) -{} +businessFeatureEmojiStatus::businessFeatureEmojiStatus() { +} -const std::int32_t callbackQueryPayloadDataWithPassword::ID; +const std::int32_t businessFeatureEmojiStatus::ID; -void callbackQueryPayloadDataWithPassword::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureEmojiStatus::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callbackQueryPayloadDataWithPassword"); - s.store_field("password", password_); - s.store_bytes_field("data", data_); + s.store_class_begin(field_name, "businessFeatureEmojiStatus"); s.store_class_end(); } } -callbackQueryPayloadGame::callbackQueryPayloadGame() - : game_short_name_() -{} +businessFeatureChatFolderTags::businessFeatureChatFolderTags() { +} -callbackQueryPayloadGame::callbackQueryPayloadGame(string const &game_short_name_) - : game_short_name_(game_short_name_) -{} - -const std::int32_t callbackQueryPayloadGame::ID; +const std::int32_t businessFeatureChatFolderTags::ID; -void callbackQueryPayloadGame::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureChatFolderTags::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "callbackQueryPayloadGame"); - s.store_field("game_short_name", game_short_name_); + s.store_class_begin(field_name, "businessFeatureChatFolderTags"); s.store_class_end(); } } -canTransferOwnershipResultOk::canTransferOwnershipResultOk() { +businessFeatureUpgradedStories::businessFeatureUpgradedStories() { } -const std::int32_t canTransferOwnershipResultOk::ID; +const std::int32_t businessFeatureUpgradedStories::ID; -void canTransferOwnershipResultOk::store(TlStorerToString &s, const char *field_name) const { +void businessFeatureUpgradedStories::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "canTransferOwnershipResultOk"); + s.store_class_begin(field_name, "businessFeatureUpgradedStories"); s.store_class_end(); } } -canTransferOwnershipResultPasswordNeeded::canTransferOwnershipResultPasswordNeeded() { -} +businessFeaturePromotionAnimation::businessFeaturePromotionAnimation() + : feature_() + , animation_() +{} -const std::int32_t canTransferOwnershipResultPasswordNeeded::ID; +businessFeaturePromotionAnimation::businessFeaturePromotionAnimation(object_ptr &&feature_, object_ptr &&animation_) + : feature_(std::move(feature_)) + , animation_(std::move(animation_)) +{} -void canTransferOwnershipResultPasswordNeeded::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t businessFeaturePromotionAnimation::ID; + +void businessFeaturePromotionAnimation::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "canTransferOwnershipResultPasswordNeeded"); + s.store_class_begin(field_name, "businessFeaturePromotionAnimation"); + s.store_object_field("feature", static_cast(feature_.get())); + s.store_object_field("animation", static_cast(animation_.get())); s.store_class_end(); } } -canTransferOwnershipResultPasswordTooFresh::canTransferOwnershipResultPasswordTooFresh() - : retry_after_() +businessFeatures::businessFeatures() + : features_() {} -canTransferOwnershipResultPasswordTooFresh::canTransferOwnershipResultPasswordTooFresh(int32 retry_after_) - : retry_after_(retry_after_) +businessFeatures::businessFeatures(array> &&features_) + : features_(std::move(features_)) {} -const std::int32_t canTransferOwnershipResultPasswordTooFresh::ID; +const std::int32_t businessFeatures::ID; -void canTransferOwnershipResultPasswordTooFresh::store(TlStorerToString &s, const char *field_name) const { +void businessFeatures::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "canTransferOwnershipResultPasswordTooFresh"); - s.store_field("retry_after", retry_after_); + s.store_class_begin(field_name, "businessFeatures"); + { s.store_vector_begin("features", features_.size()); for (const auto &_value : features_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -canTransferOwnershipResultSessionTooFresh::canTransferOwnershipResultSessionTooFresh() - : retry_after_() +businessGreetingMessageSettings::businessGreetingMessageSettings() + : shortcut_id_() + , recipients_() + , inactivity_days_() {} -canTransferOwnershipResultSessionTooFresh::canTransferOwnershipResultSessionTooFresh(int32 retry_after_) - : retry_after_(retry_after_) +businessGreetingMessageSettings::businessGreetingMessageSettings(int32 shortcut_id_, object_ptr &&recipients_, int32 inactivity_days_) + : shortcut_id_(shortcut_id_) + , recipients_(std::move(recipients_)) + , inactivity_days_(inactivity_days_) {} -const std::int32_t canTransferOwnershipResultSessionTooFresh::ID; +const std::int32_t businessGreetingMessageSettings::ID; -void canTransferOwnershipResultSessionTooFresh::store(TlStorerToString &s, const char *field_name) const { +void businessGreetingMessageSettings::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "canTransferOwnershipResultSessionTooFresh"); - s.store_field("retry_after", retry_after_); + s.store_class_begin(field_name, "businessGreetingMessageSettings"); + s.store_field("shortcut_id", shortcut_id_); + s.store_object_field("recipients", static_cast(recipients_.get())); + s.store_field("inactivity_days", inactivity_days_); s.store_class_end(); } } -chat::chat() - : id_() - , type_() - , title_() - , photo_() - , permissions_() - , last_message_() - , positions_() - , message_sender_id_() - , has_protected_content_() - , is_translatable_() - , is_marked_as_unread_() - , is_blocked_() - , has_scheduled_messages_() - , can_be_deleted_only_for_self_() - , can_be_deleted_for_all_users_() - , can_be_reported_() - , default_disable_notification_() - , unread_count_() - , last_read_inbox_message_id_() - , last_read_outbox_message_id_() - , unread_mention_count_() - , unread_reaction_count_() - , notification_settings_() - , available_reactions_() - , message_auto_delete_time_() - , background_() - , theme_name_() - , action_bar_() - , video_chat_() - , pending_join_requests_() - , reply_markup_message_id_() - , draft_message_() - , client_data_() +businessInfo::businessInfo() + : location_() + , opening_hours_() + , local_opening_hours_() + , next_open_in_() + , next_close_in_() + , greeting_message_settings_() + , away_message_settings_() + , start_page_() {} -chat::chat(int53 id_, object_ptr &&type_, string const &title_, object_ptr &&photo_, object_ptr &&permissions_, object_ptr &&last_message_, array> &&positions_, object_ptr &&message_sender_id_, bool has_protected_content_, bool is_translatable_, bool is_marked_as_unread_, bool is_blocked_, bool has_scheduled_messages_, bool can_be_deleted_only_for_self_, bool can_be_deleted_for_all_users_, bool can_be_reported_, bool default_disable_notification_, int32 unread_count_, int53 last_read_inbox_message_id_, int53 last_read_outbox_message_id_, int32 unread_mention_count_, int32 unread_reaction_count_, object_ptr &¬ification_settings_, object_ptr &&available_reactions_, int32 message_auto_delete_time_, object_ptr &&background_, string const &theme_name_, object_ptr &&action_bar_, object_ptr &&video_chat_, object_ptr &&pending_join_requests_, int53 reply_markup_message_id_, object_ptr &&draft_message_, string const &client_data_) - : id_(id_) - , type_(std::move(type_)) - , title_(title_) - , photo_(std::move(photo_)) - , permissions_(std::move(permissions_)) - , last_message_(std::move(last_message_)) - , positions_(std::move(positions_)) - , message_sender_id_(std::move(message_sender_id_)) - , has_protected_content_(has_protected_content_) - , is_translatable_(is_translatable_) - , is_marked_as_unread_(is_marked_as_unread_) - , is_blocked_(is_blocked_) - , has_scheduled_messages_(has_scheduled_messages_) - , can_be_deleted_only_for_self_(can_be_deleted_only_for_self_) - , can_be_deleted_for_all_users_(can_be_deleted_for_all_users_) - , can_be_reported_(can_be_reported_) - , default_disable_notification_(default_disable_notification_) - , unread_count_(unread_count_) - , last_read_inbox_message_id_(last_read_inbox_message_id_) - , last_read_outbox_message_id_(last_read_outbox_message_id_) - , unread_mention_count_(unread_mention_count_) - , unread_reaction_count_(unread_reaction_count_) - , notification_settings_(std::move(notification_settings_)) - , available_reactions_(std::move(available_reactions_)) - , message_auto_delete_time_(message_auto_delete_time_) - , background_(std::move(background_)) - , theme_name_(theme_name_) - , action_bar_(std::move(action_bar_)) - , video_chat_(std::move(video_chat_)) - , pending_join_requests_(std::move(pending_join_requests_)) - , reply_markup_message_id_(reply_markup_message_id_) - , draft_message_(std::move(draft_message_)) - , client_data_(client_data_) +businessInfo::businessInfo(object_ptr &&location_, object_ptr &&opening_hours_, object_ptr &&local_opening_hours_, int32 next_open_in_, int32 next_close_in_, object_ptr &&greeting_message_settings_, object_ptr &&away_message_settings_, object_ptr &&start_page_) + : location_(std::move(location_)) + , opening_hours_(std::move(opening_hours_)) + , local_opening_hours_(std::move(local_opening_hours_)) + , next_open_in_(next_open_in_) + , next_close_in_(next_close_in_) + , greeting_message_settings_(std::move(greeting_message_settings_)) + , away_message_settings_(std::move(away_message_settings_)) + , start_page_(std::move(start_page_)) {} -const std::int32_t chat::ID; +const std::int32_t businessInfo::ID; -void chat::store(TlStorerToString &s, const char *field_name) const { +void businessInfo::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chat"); - s.store_field("id", id_); - s.store_object_field("type", static_cast(type_.get())); - s.store_field("title", title_); - s.store_object_field("photo", static_cast(photo_.get())); - s.store_object_field("permissions", static_cast(permissions_.get())); - s.store_object_field("last_message", static_cast(last_message_.get())); - { s.store_vector_begin("positions", positions_.size()); for (const auto &_value : positions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } - s.store_object_field("message_sender_id", static_cast(message_sender_id_.get())); - s.store_field("has_protected_content", has_protected_content_); - s.store_field("is_translatable", is_translatable_); - s.store_field("is_marked_as_unread", is_marked_as_unread_); - s.store_field("is_blocked", is_blocked_); - s.store_field("has_scheduled_messages", has_scheduled_messages_); - s.store_field("can_be_deleted_only_for_self", can_be_deleted_only_for_self_); - s.store_field("can_be_deleted_for_all_users", can_be_deleted_for_all_users_); - s.store_field("can_be_reported", can_be_reported_); - s.store_field("default_disable_notification", default_disable_notification_); - s.store_field("unread_count", unread_count_); - s.store_field("last_read_inbox_message_id", last_read_inbox_message_id_); - s.store_field("last_read_outbox_message_id", last_read_outbox_message_id_); - s.store_field("unread_mention_count", unread_mention_count_); - s.store_field("unread_reaction_count", unread_reaction_count_); - s.store_object_field("notification_settings", static_cast(notification_settings_.get())); - s.store_object_field("available_reactions", static_cast(available_reactions_.get())); - s.store_field("message_auto_delete_time", message_auto_delete_time_); - s.store_object_field("background", static_cast(background_.get())); - s.store_field("theme_name", theme_name_); - s.store_object_field("action_bar", static_cast(action_bar_.get())); - s.store_object_field("video_chat", static_cast(video_chat_.get())); - s.store_object_field("pending_join_requests", static_cast(pending_join_requests_.get())); - s.store_field("reply_markup_message_id", reply_markup_message_id_); - s.store_object_field("draft_message", static_cast(draft_message_.get())); - s.store_field("client_data", client_data_); + s.store_class_begin(field_name, "businessInfo"); + s.store_object_field("location", static_cast(location_.get())); + s.store_object_field("opening_hours", static_cast(opening_hours_.get())); + s.store_object_field("local_opening_hours", static_cast(local_opening_hours_.get())); + s.store_field("next_open_in", next_open_in_); + s.store_field("next_close_in", next_close_in_); + s.store_object_field("greeting_message_settings", static_cast(greeting_message_settings_.get())); + s.store_object_field("away_message_settings", static_cast(away_message_settings_.get())); + s.store_object_field("start_page", static_cast(start_page_.get())); s.store_class_end(); } } -chatActionTyping::chatActionTyping() { -} +businessLocation::businessLocation() + : location_() + , address_() +{} -const std::int32_t chatActionTyping::ID; +businessLocation::businessLocation(object_ptr &&location_, string const &address_) + : location_(std::move(location_)) + , address_(address_) +{} -void chatActionTyping::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t businessLocation::ID; + +void businessLocation::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionTyping"); + s.store_class_begin(field_name, "businessLocation"); + s.store_object_field("location", static_cast(location_.get())); + s.store_field("address", address_); s.store_class_end(); } } -chatActionRecordingVideo::chatActionRecordingVideo() { -} +businessMessage::businessMessage() + : message_() + , reply_to_message_() +{} -const std::int32_t chatActionRecordingVideo::ID; +businessMessage::businessMessage(object_ptr &&message_, object_ptr &&reply_to_message_) + : message_(std::move(message_)) + , reply_to_message_(std::move(reply_to_message_)) +{} -void chatActionRecordingVideo::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t businessMessage::ID; + +void businessMessage::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionRecordingVideo"); + s.store_class_begin(field_name, "businessMessage"); + s.store_object_field("message", static_cast(message_.get())); + s.store_object_field("reply_to_message", static_cast(reply_to_message_.get())); s.store_class_end(); } } -chatActionUploadingVideo::chatActionUploadingVideo() - : progress_() +businessMessages::businessMessages() + : messages_() {} -chatActionUploadingVideo::chatActionUploadingVideo(int32 progress_) - : progress_(progress_) +businessMessages::businessMessages(array> &&messages_) + : messages_(std::move(messages_)) {} -const std::int32_t chatActionUploadingVideo::ID; +const std::int32_t businessMessages::ID; -void chatActionUploadingVideo::store(TlStorerToString &s, const char *field_name) const { +void businessMessages::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionUploadingVideo"); - s.store_field("progress", progress_); + s.store_class_begin(field_name, "businessMessages"); + { s.store_vector_begin("messages", messages_.size()); for (const auto &_value : messages_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -chatActionRecordingVoiceNote::chatActionRecordingVoiceNote() { -} +businessOpeningHours::businessOpeningHours() + : time_zone_id_() + , opening_hours_() +{} -const std::int32_t chatActionRecordingVoiceNote::ID; +businessOpeningHours::businessOpeningHours(string const &time_zone_id_, array> &&opening_hours_) + : time_zone_id_(time_zone_id_) + , opening_hours_(std::move(opening_hours_)) +{} -void chatActionRecordingVoiceNote::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t businessOpeningHours::ID; + +void businessOpeningHours::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionRecordingVoiceNote"); + s.store_class_begin(field_name, "businessOpeningHours"); + s.store_field("time_zone_id", time_zone_id_); + { s.store_vector_begin("opening_hours", opening_hours_.size()); for (const auto &_value : opening_hours_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -chatActionUploadingVoiceNote::chatActionUploadingVoiceNote() - : progress_() +businessOpeningHoursInterval::businessOpeningHoursInterval() + : start_minute_() + , end_minute_() {} -chatActionUploadingVoiceNote::chatActionUploadingVoiceNote(int32 progress_) - : progress_(progress_) +businessOpeningHoursInterval::businessOpeningHoursInterval(int32 start_minute_, int32 end_minute_) + : start_minute_(start_minute_) + , end_minute_(end_minute_) {} -const std::int32_t chatActionUploadingVoiceNote::ID; +const std::int32_t businessOpeningHoursInterval::ID; -void chatActionUploadingVoiceNote::store(TlStorerToString &s, const char *field_name) const { +void businessOpeningHoursInterval::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionUploadingVoiceNote"); - s.store_field("progress", progress_); + s.store_class_begin(field_name, "businessOpeningHoursInterval"); + s.store_field("start_minute", start_minute_); + s.store_field("end_minute", end_minute_); s.store_class_end(); } } -chatActionUploadingPhoto::chatActionUploadingPhoto() - : progress_() +businessRecipients::businessRecipients() + : chat_ids_() + , excluded_chat_ids_() + , select_existing_chats_() + , select_new_chats_() + , select_contacts_() + , select_non_contacts_() + , exclude_selected_() {} -chatActionUploadingPhoto::chatActionUploadingPhoto(int32 progress_) - : progress_(progress_) +businessRecipients::businessRecipients(array &&chat_ids_, array &&excluded_chat_ids_, bool select_existing_chats_, bool select_new_chats_, bool select_contacts_, bool select_non_contacts_, bool exclude_selected_) + : chat_ids_(std::move(chat_ids_)) + , excluded_chat_ids_(std::move(excluded_chat_ids_)) + , select_existing_chats_(select_existing_chats_) + , select_new_chats_(select_new_chats_) + , select_contacts_(select_contacts_) + , select_non_contacts_(select_non_contacts_) + , exclude_selected_(exclude_selected_) {} -const std::int32_t chatActionUploadingPhoto::ID; +const std::int32_t businessRecipients::ID; -void chatActionUploadingPhoto::store(TlStorerToString &s, const char *field_name) const { +void businessRecipients::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionUploadingPhoto"); - s.store_field("progress", progress_); + s.store_class_begin(field_name, "businessRecipients"); + { s.store_vector_begin("chat_ids", chat_ids_.size()); for (const auto &_value : chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + { s.store_vector_begin("excluded_chat_ids", excluded_chat_ids_.size()); for (const auto &_value : excluded_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_field("select_existing_chats", select_existing_chats_); + s.store_field("select_new_chats", select_new_chats_); + s.store_field("select_contacts", select_contacts_); + s.store_field("select_non_contacts", select_non_contacts_); + s.store_field("exclude_selected", exclude_selected_); s.store_class_end(); } } -chatActionUploadingDocument::chatActionUploadingDocument() - : progress_() +businessStartPage::businessStartPage() + : title_() + , message_() + , sticker_() {} -chatActionUploadingDocument::chatActionUploadingDocument(int32 progress_) - : progress_(progress_) +businessStartPage::businessStartPage(string const &title_, string const &message_, object_ptr &&sticker_) + : title_(title_) + , message_(message_) + , sticker_(std::move(sticker_)) {} -const std::int32_t chatActionUploadingDocument::ID; +const std::int32_t businessStartPage::ID; -void chatActionUploadingDocument::store(TlStorerToString &s, const char *field_name) const { +void businessStartPage::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionUploadingDocument"); - s.store_field("progress", progress_); + s.store_class_begin(field_name, "businessStartPage"); + s.store_field("title", title_); + s.store_field("message", message_); + s.store_object_field("sticker", static_cast(sticker_.get())); s.store_class_end(); } } -chatActionChoosingSticker::chatActionChoosingSticker() { -} +call::call() + : id_() + , user_id_() + , is_outgoing_() + , is_video_() + , state_() +{} -const std::int32_t chatActionChoosingSticker::ID; +call::call(int32 id_, int53 user_id_, bool is_outgoing_, bool is_video_, object_ptr &&state_) + : id_(id_) + , user_id_(user_id_) + , is_outgoing_(is_outgoing_) + , is_video_(is_video_) + , state_(std::move(state_)) +{} -void chatActionChoosingSticker::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t call::ID; + +void call::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionChoosingSticker"); + s.store_class_begin(field_name, "call"); + s.store_field("id", id_); + s.store_field("user_id", user_id_); + s.store_field("is_outgoing", is_outgoing_); + s.store_field("is_video", is_video_); + s.store_object_field("state", static_cast(state_.get())); s.store_class_end(); } } -chatActionChoosingLocation::chatActionChoosingLocation() { +callDiscardReasonEmpty::callDiscardReasonEmpty() { } -const std::int32_t chatActionChoosingLocation::ID; +const std::int32_t callDiscardReasonEmpty::ID; -void chatActionChoosingLocation::store(TlStorerToString &s, const char *field_name) const { +void callDiscardReasonEmpty::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionChoosingLocation"); + s.store_class_begin(field_name, "callDiscardReasonEmpty"); s.store_class_end(); } } -chatActionChoosingContact::chatActionChoosingContact() { +callDiscardReasonMissed::callDiscardReasonMissed() { } -const std::int32_t chatActionChoosingContact::ID; +const std::int32_t callDiscardReasonMissed::ID; -void chatActionChoosingContact::store(TlStorerToString &s, const char *field_name) const { +void callDiscardReasonMissed::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionChoosingContact"); + s.store_class_begin(field_name, "callDiscardReasonMissed"); s.store_class_end(); } } -chatActionStartPlayingGame::chatActionStartPlayingGame() { +callDiscardReasonDeclined::callDiscardReasonDeclined() { } -const std::int32_t chatActionStartPlayingGame::ID; +const std::int32_t callDiscardReasonDeclined::ID; -void chatActionStartPlayingGame::store(TlStorerToString &s, const char *field_name) const { +void callDiscardReasonDeclined::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionStartPlayingGame"); + s.store_class_begin(field_name, "callDiscardReasonDeclined"); s.store_class_end(); } } -chatActionRecordingVideoNote::chatActionRecordingVideoNote() { +callDiscardReasonDisconnected::callDiscardReasonDisconnected() { } -const std::int32_t chatActionRecordingVideoNote::ID; +const std::int32_t callDiscardReasonDisconnected::ID; -void chatActionRecordingVideoNote::store(TlStorerToString &s, const char *field_name) const { +void callDiscardReasonDisconnected::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionRecordingVideoNote"); + s.store_class_begin(field_name, "callDiscardReasonDisconnected"); s.store_class_end(); } } -chatActionUploadingVideoNote::chatActionUploadingVideoNote() - : progress_() -{} - -chatActionUploadingVideoNote::chatActionUploadingVideoNote(int32 progress_) - : progress_(progress_) -{} +callDiscardReasonHungUp::callDiscardReasonHungUp() { +} -const std::int32_t chatActionUploadingVideoNote::ID; +const std::int32_t callDiscardReasonHungUp::ID; -void chatActionUploadingVideoNote::store(TlStorerToString &s, const char *field_name) const { +void callDiscardReasonHungUp::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionUploadingVideoNote"); - s.store_field("progress", progress_); + s.store_class_begin(field_name, "callDiscardReasonHungUp"); s.store_class_end(); } } -chatActionWatchingAnimations::chatActionWatchingAnimations() - : emoji_() +callId::callId() + : id_() {} -chatActionWatchingAnimations::chatActionWatchingAnimations(string const &emoji_) - : emoji_(emoji_) +callId::callId(int32 id_) + : id_(id_) {} -const std::int32_t chatActionWatchingAnimations::ID; +const std::int32_t callId::ID; -void chatActionWatchingAnimations::store(TlStorerToString &s, const char *field_name) const { +void callId::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionWatchingAnimations"); - s.store_field("emoji", emoji_); + s.store_class_begin(field_name, "callId"); + s.store_field("id", id_); s.store_class_end(); } } -chatActionCancel::chatActionCancel() { +callProblemEcho::callProblemEcho() { } -const std::int32_t chatActionCancel::ID; +const std::int32_t callProblemEcho::ID; -void chatActionCancel::store(TlStorerToString &s, const char *field_name) const { +void callProblemEcho::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionCancel"); + s.store_class_begin(field_name, "callProblemEcho"); s.store_class_end(); } } -chatActionBarReportSpam::chatActionBarReportSpam() - : can_unarchive_() -{} - -chatActionBarReportSpam::chatActionBarReportSpam(bool can_unarchive_) - : can_unarchive_(can_unarchive_) -{} +callProblemNoise::callProblemNoise() { +} -const std::int32_t chatActionBarReportSpam::ID; +const std::int32_t callProblemNoise::ID; -void chatActionBarReportSpam::store(TlStorerToString &s, const char *field_name) const { +void callProblemNoise::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionBarReportSpam"); - s.store_field("can_unarchive", can_unarchive_); + s.store_class_begin(field_name, "callProblemNoise"); s.store_class_end(); } } -chatActionBarReportUnrelatedLocation::chatActionBarReportUnrelatedLocation() { +callProblemInterruptions::callProblemInterruptions() { } -const std::int32_t chatActionBarReportUnrelatedLocation::ID; +const std::int32_t callProblemInterruptions::ID; -void chatActionBarReportUnrelatedLocation::store(TlStorerToString &s, const char *field_name) const { +void callProblemInterruptions::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionBarReportUnrelatedLocation"); + s.store_class_begin(field_name, "callProblemInterruptions"); s.store_class_end(); } } -chatActionBarInviteMembers::chatActionBarInviteMembers() { +callProblemDistortedSpeech::callProblemDistortedSpeech() { } -const std::int32_t chatActionBarInviteMembers::ID; +const std::int32_t callProblemDistortedSpeech::ID; -void chatActionBarInviteMembers::store(TlStorerToString &s, const char *field_name) const { +void callProblemDistortedSpeech::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionBarInviteMembers"); + s.store_class_begin(field_name, "callProblemDistortedSpeech"); s.store_class_end(); } } -chatActionBarReportAddBlock::chatActionBarReportAddBlock() - : can_unarchive_() - , distance_() -{} - -chatActionBarReportAddBlock::chatActionBarReportAddBlock(bool can_unarchive_, int32 distance_) - : can_unarchive_(can_unarchive_) - , distance_(distance_) -{} +callProblemSilentLocal::callProblemSilentLocal() { +} -const std::int32_t chatActionBarReportAddBlock::ID; +const std::int32_t callProblemSilentLocal::ID; -void chatActionBarReportAddBlock::store(TlStorerToString &s, const char *field_name) const { +void callProblemSilentLocal::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionBarReportAddBlock"); - s.store_field("can_unarchive", can_unarchive_); - s.store_field("distance", distance_); + s.store_class_begin(field_name, "callProblemSilentLocal"); s.store_class_end(); } } -chatActionBarAddContact::chatActionBarAddContact() { +callProblemSilentRemote::callProblemSilentRemote() { } -const std::int32_t chatActionBarAddContact::ID; +const std::int32_t callProblemSilentRemote::ID; -void chatActionBarAddContact::store(TlStorerToString &s, const char *field_name) const { +void callProblemSilentRemote::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionBarAddContact"); + s.store_class_begin(field_name, "callProblemSilentRemote"); s.store_class_end(); } } -chatActionBarSharePhoneNumber::chatActionBarSharePhoneNumber() { +callProblemDropped::callProblemDropped() { } -const std::int32_t chatActionBarSharePhoneNumber::ID; +const std::int32_t callProblemDropped::ID; -void chatActionBarSharePhoneNumber::store(TlStorerToString &s, const char *field_name) const { +void callProblemDropped::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionBarSharePhoneNumber"); + s.store_class_begin(field_name, "callProblemDropped"); s.store_class_end(); } } -chatActionBarJoinRequest::chatActionBarJoinRequest() - : title_() - , is_channel_() - , request_date_() -{} - -chatActionBarJoinRequest::chatActionBarJoinRequest(string const &title_, bool is_channel_, int32 request_date_) - : title_(title_) - , is_channel_(is_channel_) - , request_date_(request_date_) -{} +callProblemDistortedVideo::callProblemDistortedVideo() { +} -const std::int32_t chatActionBarJoinRequest::ID; +const std::int32_t callProblemDistortedVideo::ID; -void chatActionBarJoinRequest::store(TlStorerToString &s, const char *field_name) const { +void callProblemDistortedVideo::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatActionBarJoinRequest"); - s.store_field("title", title_); - s.store_field("is_channel", is_channel_); - s.store_field("request_date", request_date_); + s.store_class_begin(field_name, "callProblemDistortedVideo"); s.store_class_end(); } } -chatAdministrator::chatAdministrator() - : user_id_() - , custom_title_() - , is_owner_() -{} - -chatAdministrator::chatAdministrator(int53 user_id_, string const &custom_title_, bool is_owner_) - : user_id_(user_id_) - , custom_title_(custom_title_) - , is_owner_(is_owner_) -{} +callProblemPixelatedVideo::callProblemPixelatedVideo() { +} -const std::int32_t chatAdministrator::ID; +const std::int32_t callProblemPixelatedVideo::ID; -void chatAdministrator::store(TlStorerToString &s, const char *field_name) const { +void callProblemPixelatedVideo::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatAdministrator"); - s.store_field("user_id", user_id_); - s.store_field("custom_title", custom_title_); - s.store_field("is_owner", is_owner_); + s.store_class_begin(field_name, "callProblemPixelatedVideo"); s.store_class_end(); } } -chatAdministratorRights::chatAdministratorRights() - : can_manage_chat_() - , can_change_info_() - , can_post_messages_() - , can_edit_messages_() - , can_delete_messages_() - , can_invite_users_() - , can_restrict_members_() - , can_pin_messages_() - , can_manage_topics_() - , can_promote_members_() - , can_manage_video_chats_() - , is_anonymous_() +callProtocol::callProtocol() + : udp_p2p_() + , udp_reflector_() + , min_layer_() + , max_layer_() + , library_versions_() {} -chatAdministratorRights::chatAdministratorRights(bool can_manage_chat_, bool can_change_info_, bool can_post_messages_, bool can_edit_messages_, bool can_delete_messages_, bool can_invite_users_, bool can_restrict_members_, bool can_pin_messages_, bool can_manage_topics_, bool can_promote_members_, bool can_manage_video_chats_, bool is_anonymous_) - : can_manage_chat_(can_manage_chat_) - , can_change_info_(can_change_info_) - , can_post_messages_(can_post_messages_) - , can_edit_messages_(can_edit_messages_) - , can_delete_messages_(can_delete_messages_) - , can_invite_users_(can_invite_users_) - , can_restrict_members_(can_restrict_members_) - , can_pin_messages_(can_pin_messages_) - , can_manage_topics_(can_manage_topics_) - , can_promote_members_(can_promote_members_) - , can_manage_video_chats_(can_manage_video_chats_) - , is_anonymous_(is_anonymous_) +callProtocol::callProtocol(bool udp_p2p_, bool udp_reflector_, int32 min_layer_, int32 max_layer_, array &&library_versions_) + : udp_p2p_(udp_p2p_) + , udp_reflector_(udp_reflector_) + , min_layer_(min_layer_) + , max_layer_(max_layer_) + , library_versions_(std::move(library_versions_)) {} -const std::int32_t chatAdministratorRights::ID; +const std::int32_t callProtocol::ID; -void chatAdministratorRights::store(TlStorerToString &s, const char *field_name) const { +void callProtocol::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatAdministratorRights"); - s.store_field("can_manage_chat", can_manage_chat_); - s.store_field("can_change_info", can_change_info_); - s.store_field("can_post_messages", can_post_messages_); - s.store_field("can_edit_messages", can_edit_messages_); - s.store_field("can_delete_messages", can_delete_messages_); - s.store_field("can_invite_users", can_invite_users_); - s.store_field("can_restrict_members", can_restrict_members_); - s.store_field("can_pin_messages", can_pin_messages_); - s.store_field("can_manage_topics", can_manage_topics_); - s.store_field("can_promote_members", can_promote_members_); - s.store_field("can_manage_video_chats", can_manage_video_chats_); - s.store_field("is_anonymous", is_anonymous_); + s.store_class_begin(field_name, "callProtocol"); + s.store_field("udp_p2p", udp_p2p_); + s.store_field("udp_reflector", udp_reflector_); + s.store_field("min_layer", min_layer_); + s.store_field("max_layer", max_layer_); + { s.store_vector_begin("library_versions", library_versions_.size()); for (const auto &_value : library_versions_) { s.store_field("", _value); } s.store_class_end(); } s.store_class_end(); } } -chatAdministrators::chatAdministrators() - : administrators_() +callServer::callServer() + : id_() + , ip_address_() + , ipv6_address_() + , port_() + , type_() {} -chatAdministrators::chatAdministrators(array> &&administrators_) - : administrators_(std::move(administrators_)) -{} - -const std::int32_t chatAdministrators::ID; - -void chatAdministrators::store(TlStorerToString &s, const char *field_name) const { - if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatAdministrators"); - { s.store_vector_begin("administrators", administrators_.size()); for (const auto &_value : administrators_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } - s.store_class_end(); - } -} - -chatAvailableReactionsAll::chatAvailableReactionsAll() { -} +callServer::callServer(int64 id_, string const &ip_address_, string const &ipv6_address_, int32 port_, object_ptr &&type_) + : id_(id_) + , ip_address_(ip_address_) + , ipv6_address_(ipv6_address_) + , port_(port_) + , type_(std::move(type_)) +{} -const std::int32_t chatAvailableReactionsAll::ID; +const std::int32_t callServer::ID; -void chatAvailableReactionsAll::store(TlStorerToString &s, const char *field_name) const { +void callServer::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatAvailableReactionsAll"); + s.store_class_begin(field_name, "callServer"); + s.store_field("id", id_); + s.store_field("ip_address", ip_address_); + s.store_field("ipv6_address", ipv6_address_); + s.store_field("port", port_); + s.store_object_field("type", static_cast(type_.get())); s.store_class_end(); } } -chatAvailableReactionsSome::chatAvailableReactionsSome() - : reactions_() +callServerTypeTelegramReflector::callServerTypeTelegramReflector() + : peer_tag_() + , is_tcp_() {} -chatAvailableReactionsSome::chatAvailableReactionsSome(array> &&reactions_) - : reactions_(std::move(reactions_)) +callServerTypeTelegramReflector::callServerTypeTelegramReflector(bytes const &peer_tag_, bool is_tcp_) + : peer_tag_(std::move(peer_tag_)) + , is_tcp_(is_tcp_) {} -const std::int32_t chatAvailableReactionsSome::ID; +const std::int32_t callServerTypeTelegramReflector::ID; -void chatAvailableReactionsSome::store(TlStorerToString &s, const char *field_name) const { +void callServerTypeTelegramReflector::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatAvailableReactionsSome"); - { s.store_vector_begin("reactions", reactions_.size()); for (const auto &_value : reactions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "callServerTypeTelegramReflector"); + s.store_bytes_field("peer_tag", peer_tag_); + s.store_field("is_tcp", is_tcp_); s.store_class_end(); } } -chatBackground::chatBackground() - : background_() - , dark_theme_dimming_() +callServerTypeWebrtc::callServerTypeWebrtc() + : username_() + , password_() + , supports_turn_() + , supports_stun_() {} -chatBackground::chatBackground(object_ptr &&background_, int32 dark_theme_dimming_) - : background_(std::move(background_)) - , dark_theme_dimming_(dark_theme_dimming_) +callServerTypeWebrtc::callServerTypeWebrtc(string const &username_, string const &password_, bool supports_turn_, bool supports_stun_) + : username_(username_) + , password_(password_) + , supports_turn_(supports_turn_) + , supports_stun_(supports_stun_) {} -const std::int32_t chatBackground::ID; +const std::int32_t callServerTypeWebrtc::ID; -void chatBackground::store(TlStorerToString &s, const char *field_name) const { +void callServerTypeWebrtc::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatBackground"); - s.store_object_field("background", static_cast(background_.get())); - s.store_field("dark_theme_dimming", dark_theme_dimming_); + s.store_class_begin(field_name, "callServerTypeWebrtc"); + s.store_field("username", username_); + s.store_field("password", password_); + s.store_field("supports_turn", supports_turn_); + s.store_field("supports_stun", supports_stun_); s.store_class_end(); } } -chatEvent::chatEvent() - : id_() - , date_() - , member_id_() - , action_() +callStatePending::callStatePending() + : is_created_() + , is_received_() {} -chatEvent::chatEvent(int64 id_, int32 date_, object_ptr &&member_id_, object_ptr &&action_) - : id_(id_) - , date_(date_) - , member_id_(std::move(member_id_)) - , action_(std::move(action_)) +callStatePending::callStatePending(bool is_created_, bool is_received_) + : is_created_(is_created_) + , is_received_(is_received_) {} -const std::int32_t chatEvent::ID; +const std::int32_t callStatePending::ID; -void chatEvent::store(TlStorerToString &s, const char *field_name) const { +void callStatePending::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEvent"); - s.store_field("id", id_); - s.store_field("date", date_); - s.store_object_field("member_id", static_cast(member_id_.get())); - s.store_object_field("action", static_cast(action_.get())); + s.store_class_begin(field_name, "callStatePending"); + s.store_field("is_created", is_created_); + s.store_field("is_received", is_received_); s.store_class_end(); } } -chatEventMessageEdited::chatEventMessageEdited() - : old_message_() - , new_message_() -{} - -chatEventMessageEdited::chatEventMessageEdited(object_ptr &&old_message_, object_ptr &&new_message_) - : old_message_(std::move(old_message_)) - , new_message_(std::move(new_message_)) -{} +callStateExchangingKeys::callStateExchangingKeys() { +} -const std::int32_t chatEventMessageEdited::ID; +const std::int32_t callStateExchangingKeys::ID; -void chatEventMessageEdited::store(TlStorerToString &s, const char *field_name) const { +void callStateExchangingKeys::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMessageEdited"); - s.store_object_field("old_message", static_cast(old_message_.get())); - s.store_object_field("new_message", static_cast(new_message_.get())); + s.store_class_begin(field_name, "callStateExchangingKeys"); s.store_class_end(); } } -chatEventMessageDeleted::chatEventMessageDeleted() - : message_() - , can_report_anti_spam_false_positive_() +callStateReady::callStateReady() + : protocol_() + , servers_() + , config_() + , encryption_key_() + , emojis_() + , allow_p2p_() + , custom_parameters_() {} -chatEventMessageDeleted::chatEventMessageDeleted(object_ptr &&message_, bool can_report_anti_spam_false_positive_) - : message_(std::move(message_)) - , can_report_anti_spam_false_positive_(can_report_anti_spam_false_positive_) +callStateReady::callStateReady(object_ptr &&protocol_, array> &&servers_, string const &config_, bytes const &encryption_key_, array &&emojis_, bool allow_p2p_, string const &custom_parameters_) + : protocol_(std::move(protocol_)) + , servers_(std::move(servers_)) + , config_(config_) + , encryption_key_(std::move(encryption_key_)) + , emojis_(std::move(emojis_)) + , allow_p2p_(allow_p2p_) + , custom_parameters_(custom_parameters_) {} -const std::int32_t chatEventMessageDeleted::ID; +const std::int32_t callStateReady::ID; -void chatEventMessageDeleted::store(TlStorerToString &s, const char *field_name) const { +void callStateReady::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMessageDeleted"); - s.store_object_field("message", static_cast(message_.get())); - s.store_field("can_report_anti_spam_false_positive", can_report_anti_spam_false_positive_); + s.store_class_begin(field_name, "callStateReady"); + s.store_object_field("protocol", static_cast(protocol_.get())); + { s.store_vector_begin("servers", servers_.size()); for (const auto &_value : servers_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("config", config_); + s.store_bytes_field("encryption_key", encryption_key_); + { s.store_vector_begin("emojis", emojis_.size()); for (const auto &_value : emojis_) { s.store_field("", _value); } s.store_class_end(); } + s.store_field("allow_p2p", allow_p2p_); + s.store_field("custom_parameters", custom_parameters_); s.store_class_end(); } } -chatEventMessagePinned::chatEventMessagePinned() - : message_() -{} - -chatEventMessagePinned::chatEventMessagePinned(object_ptr &&message_) - : message_(std::move(message_)) -{} +callStateHangingUp::callStateHangingUp() { +} -const std::int32_t chatEventMessagePinned::ID; +const std::int32_t callStateHangingUp::ID; -void chatEventMessagePinned::store(TlStorerToString &s, const char *field_name) const { +void callStateHangingUp::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMessagePinned"); - s.store_object_field("message", static_cast(message_.get())); + s.store_class_begin(field_name, "callStateHangingUp"); s.store_class_end(); } } -chatEventMessageUnpinned::chatEventMessageUnpinned() - : message_() +callStateDiscarded::callStateDiscarded() + : reason_() + , need_rating_() + , need_debug_information_() + , need_log_() {} -chatEventMessageUnpinned::chatEventMessageUnpinned(object_ptr &&message_) - : message_(std::move(message_)) +callStateDiscarded::callStateDiscarded(object_ptr &&reason_, bool need_rating_, bool need_debug_information_, bool need_log_) + : reason_(std::move(reason_)) + , need_rating_(need_rating_) + , need_debug_information_(need_debug_information_) + , need_log_(need_log_) {} -const std::int32_t chatEventMessageUnpinned::ID; +const std::int32_t callStateDiscarded::ID; -void chatEventMessageUnpinned::store(TlStorerToString &s, const char *field_name) const { +void callStateDiscarded::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMessageUnpinned"); - s.store_object_field("message", static_cast(message_.get())); + s.store_class_begin(field_name, "callStateDiscarded"); + s.store_object_field("reason", static_cast(reason_.get())); + s.store_field("need_rating", need_rating_); + s.store_field("need_debug_information", need_debug_information_); + s.store_field("need_log", need_log_); s.store_class_end(); } } -chatEventPollStopped::chatEventPollStopped() - : message_() +callStateError::callStateError() + : error_() {} -chatEventPollStopped::chatEventPollStopped(object_ptr &&message_) - : message_(std::move(message_)) +callStateError::callStateError(object_ptr &&error_) + : error_(std::move(error_)) {} -const std::int32_t chatEventPollStopped::ID; +const std::int32_t callStateError::ID; -void chatEventPollStopped::store(TlStorerToString &s, const char *field_name) const { +void callStateError::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventPollStopped"); - s.store_object_field("message", static_cast(message_.get())); + s.store_class_begin(field_name, "callStateError"); + s.store_object_field("error", static_cast(error_.get())); s.store_class_end(); } } -chatEventMemberJoined::chatEventMemberJoined() { -} +callbackQueryAnswer::callbackQueryAnswer() + : text_() + , show_alert_() + , url_() +{} -const std::int32_t chatEventMemberJoined::ID; +callbackQueryAnswer::callbackQueryAnswer(string const &text_, bool show_alert_, string const &url_) + : text_(text_) + , show_alert_(show_alert_) + , url_(url_) +{} -void chatEventMemberJoined::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t callbackQueryAnswer::ID; + +void callbackQueryAnswer::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMemberJoined"); + s.store_class_begin(field_name, "callbackQueryAnswer"); + s.store_field("text", text_); + s.store_field("show_alert", show_alert_); + s.store_field("url", url_); s.store_class_end(); } } -chatEventMemberJoinedByInviteLink::chatEventMemberJoinedByInviteLink() - : invite_link_() - , via_chat_folder_invite_link_() +callbackQueryPayloadData::callbackQueryPayloadData() + : data_() {} -chatEventMemberJoinedByInviteLink::chatEventMemberJoinedByInviteLink(object_ptr &&invite_link_, bool via_chat_folder_invite_link_) - : invite_link_(std::move(invite_link_)) - , via_chat_folder_invite_link_(via_chat_folder_invite_link_) +callbackQueryPayloadData::callbackQueryPayloadData(bytes const &data_) + : data_(std::move(data_)) {} -const std::int32_t chatEventMemberJoinedByInviteLink::ID; +const std::int32_t callbackQueryPayloadData::ID; -void chatEventMemberJoinedByInviteLink::store(TlStorerToString &s, const char *field_name) const { +void callbackQueryPayloadData::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMemberJoinedByInviteLink"); - s.store_object_field("invite_link", static_cast(invite_link_.get())); - s.store_field("via_chat_folder_invite_link", via_chat_folder_invite_link_); + s.store_class_begin(field_name, "callbackQueryPayloadData"); + s.store_bytes_field("data", data_); s.store_class_end(); } } -chatEventMemberJoinedByRequest::chatEventMemberJoinedByRequest() - : approver_user_id_() - , invite_link_() +callbackQueryPayloadDataWithPassword::callbackQueryPayloadDataWithPassword() + : password_() + , data_() {} -chatEventMemberJoinedByRequest::chatEventMemberJoinedByRequest(int53 approver_user_id_, object_ptr &&invite_link_) - : approver_user_id_(approver_user_id_) - , invite_link_(std::move(invite_link_)) +callbackQueryPayloadDataWithPassword::callbackQueryPayloadDataWithPassword(string const &password_, bytes const &data_) + : password_(password_) + , data_(std::move(data_)) {} -const std::int32_t chatEventMemberJoinedByRequest::ID; +const std::int32_t callbackQueryPayloadDataWithPassword::ID; -void chatEventMemberJoinedByRequest::store(TlStorerToString &s, const char *field_name) const { +void callbackQueryPayloadDataWithPassword::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMemberJoinedByRequest"); - s.store_field("approver_user_id", approver_user_id_); - s.store_object_field("invite_link", static_cast(invite_link_.get())); + s.store_class_begin(field_name, "callbackQueryPayloadDataWithPassword"); + s.store_field("password", password_); + s.store_bytes_field("data", data_); s.store_class_end(); } } -chatEventMemberInvited::chatEventMemberInvited() - : user_id_() - , status_() +callbackQueryPayloadGame::callbackQueryPayloadGame() + : game_short_name_() {} -chatEventMemberInvited::chatEventMemberInvited(int53 user_id_, object_ptr &&status_) - : user_id_(user_id_) - , status_(std::move(status_)) +callbackQueryPayloadGame::callbackQueryPayloadGame(string const &game_short_name_) + : game_short_name_(game_short_name_) {} -const std::int32_t chatEventMemberInvited::ID; +const std::int32_t callbackQueryPayloadGame::ID; -void chatEventMemberInvited::store(TlStorerToString &s, const char *field_name) const { +void callbackQueryPayloadGame::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMemberInvited"); - s.store_field("user_id", user_id_); - s.store_object_field("status", static_cast(status_.get())); + s.store_class_begin(field_name, "callbackQueryPayloadGame"); + s.store_field("game_short_name", game_short_name_); s.store_class_end(); } } -chatEventMemberLeft::chatEventMemberLeft() { +canSendMessageToUserResultOk::canSendMessageToUserResultOk() { } -const std::int32_t chatEventMemberLeft::ID; +const std::int32_t canSendMessageToUserResultOk::ID; -void chatEventMemberLeft::store(TlStorerToString &s, const char *field_name) const { +void canSendMessageToUserResultOk::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMemberLeft"); + s.store_class_begin(field_name, "canSendMessageToUserResultOk"); s.store_class_end(); } } -chatEventMemberPromoted::chatEventMemberPromoted() - : user_id_() - , old_status_() - , new_status_() -{} - -chatEventMemberPromoted::chatEventMemberPromoted(int53 user_id_, object_ptr &&old_status_, object_ptr &&new_status_) - : user_id_(user_id_) - , old_status_(std::move(old_status_)) - , new_status_(std::move(new_status_)) -{} +canSendMessageToUserResultUserIsDeleted::canSendMessageToUserResultUserIsDeleted() { +} -const std::int32_t chatEventMemberPromoted::ID; +const std::int32_t canSendMessageToUserResultUserIsDeleted::ID; -void chatEventMemberPromoted::store(TlStorerToString &s, const char *field_name) const { +void canSendMessageToUserResultUserIsDeleted::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMemberPromoted"); - s.store_field("user_id", user_id_); - s.store_object_field("old_status", static_cast(old_status_.get())); - s.store_object_field("new_status", static_cast(new_status_.get())); + s.store_class_begin(field_name, "canSendMessageToUserResultUserIsDeleted"); s.store_class_end(); } } -chatEventMemberRestricted::chatEventMemberRestricted() - : member_id_() - , old_status_() - , new_status_() -{} - -chatEventMemberRestricted::chatEventMemberRestricted(object_ptr &&member_id_, object_ptr &&old_status_, object_ptr &&new_status_) - : member_id_(std::move(member_id_)) - , old_status_(std::move(old_status_)) - , new_status_(std::move(new_status_)) -{} +canSendMessageToUserResultUserRestrictsNewChats::canSendMessageToUserResultUserRestrictsNewChats() { +} -const std::int32_t chatEventMemberRestricted::ID; +const std::int32_t canSendMessageToUserResultUserRestrictsNewChats::ID; -void chatEventMemberRestricted::store(TlStorerToString &s, const char *field_name) const { +void canSendMessageToUserResultUserRestrictsNewChats::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMemberRestricted"); - s.store_object_field("member_id", static_cast(member_id_.get())); - s.store_object_field("old_status", static_cast(old_status_.get())); - s.store_object_field("new_status", static_cast(new_status_.get())); + s.store_class_begin(field_name, "canSendMessageToUserResultUserRestrictsNewChats"); s.store_class_end(); } } -chatEventAvailableReactionsChanged::chatEventAvailableReactionsChanged() - : old_available_reactions_() - , new_available_reactions_() -{} - -chatEventAvailableReactionsChanged::chatEventAvailableReactionsChanged(object_ptr &&old_available_reactions_, object_ptr &&new_available_reactions_) - : old_available_reactions_(std::move(old_available_reactions_)) - , new_available_reactions_(std::move(new_available_reactions_)) -{} +canSendStoryResultOk::canSendStoryResultOk() { +} -const std::int32_t chatEventAvailableReactionsChanged::ID; +const std::int32_t canSendStoryResultOk::ID; -void chatEventAvailableReactionsChanged::store(TlStorerToString &s, const char *field_name) const { +void canSendStoryResultOk::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventAvailableReactionsChanged"); - s.store_object_field("old_available_reactions", static_cast(old_available_reactions_.get())); - s.store_object_field("new_available_reactions", static_cast(new_available_reactions_.get())); + s.store_class_begin(field_name, "canSendStoryResultOk"); s.store_class_end(); } } -chatEventDescriptionChanged::chatEventDescriptionChanged() - : old_description_() - , new_description_() -{} - -chatEventDescriptionChanged::chatEventDescriptionChanged(string const &old_description_, string const &new_description_) - : old_description_(old_description_) - , new_description_(new_description_) -{} +canSendStoryResultPremiumNeeded::canSendStoryResultPremiumNeeded() { +} -const std::int32_t chatEventDescriptionChanged::ID; +const std::int32_t canSendStoryResultPremiumNeeded::ID; -void chatEventDescriptionChanged::store(TlStorerToString &s, const char *field_name) const { +void canSendStoryResultPremiumNeeded::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventDescriptionChanged"); - s.store_field("old_description", old_description_); - s.store_field("new_description", new_description_); + s.store_class_begin(field_name, "canSendStoryResultPremiumNeeded"); s.store_class_end(); } } -chatEventLinkedChatChanged::chatEventLinkedChatChanged() - : old_linked_chat_id_() - , new_linked_chat_id_() -{} - -chatEventLinkedChatChanged::chatEventLinkedChatChanged(int53 old_linked_chat_id_, int53 new_linked_chat_id_) - : old_linked_chat_id_(old_linked_chat_id_) - , new_linked_chat_id_(new_linked_chat_id_) -{} +canSendStoryResultBoostNeeded::canSendStoryResultBoostNeeded() { +} -const std::int32_t chatEventLinkedChatChanged::ID; +const std::int32_t canSendStoryResultBoostNeeded::ID; -void chatEventLinkedChatChanged::store(TlStorerToString &s, const char *field_name) const { +void canSendStoryResultBoostNeeded::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventLinkedChatChanged"); - s.store_field("old_linked_chat_id", old_linked_chat_id_); - s.store_field("new_linked_chat_id", new_linked_chat_id_); + s.store_class_begin(field_name, "canSendStoryResultBoostNeeded"); s.store_class_end(); } } -chatEventLocationChanged::chatEventLocationChanged() - : old_location_() - , new_location_() -{} - -chatEventLocationChanged::chatEventLocationChanged(object_ptr &&old_location_, object_ptr &&new_location_) - : old_location_(std::move(old_location_)) - , new_location_(std::move(new_location_)) -{} +canSendStoryResultActiveStoryLimitExceeded::canSendStoryResultActiveStoryLimitExceeded() { +} -const std::int32_t chatEventLocationChanged::ID; +const std::int32_t canSendStoryResultActiveStoryLimitExceeded::ID; -void chatEventLocationChanged::store(TlStorerToString &s, const char *field_name) const { +void canSendStoryResultActiveStoryLimitExceeded::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventLocationChanged"); - s.store_object_field("old_location", static_cast(old_location_.get())); - s.store_object_field("new_location", static_cast(new_location_.get())); + s.store_class_begin(field_name, "canSendStoryResultActiveStoryLimitExceeded"); s.store_class_end(); } } -chatEventMessageAutoDeleteTimeChanged::chatEventMessageAutoDeleteTimeChanged() - : old_message_auto_delete_time_() - , new_message_auto_delete_time_() +canSendStoryResultWeeklyLimitExceeded::canSendStoryResultWeeklyLimitExceeded() + : retry_after_() {} -chatEventMessageAutoDeleteTimeChanged::chatEventMessageAutoDeleteTimeChanged(int32 old_message_auto_delete_time_, int32 new_message_auto_delete_time_) - : old_message_auto_delete_time_(old_message_auto_delete_time_) - , new_message_auto_delete_time_(new_message_auto_delete_time_) +canSendStoryResultWeeklyLimitExceeded::canSendStoryResultWeeklyLimitExceeded(int32 retry_after_) + : retry_after_(retry_after_) {} -const std::int32_t chatEventMessageAutoDeleteTimeChanged::ID; +const std::int32_t canSendStoryResultWeeklyLimitExceeded::ID; -void chatEventMessageAutoDeleteTimeChanged::store(TlStorerToString &s, const char *field_name) const { +void canSendStoryResultWeeklyLimitExceeded::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventMessageAutoDeleteTimeChanged"); - s.store_field("old_message_auto_delete_time", old_message_auto_delete_time_); - s.store_field("new_message_auto_delete_time", new_message_auto_delete_time_); + s.store_class_begin(field_name, "canSendStoryResultWeeklyLimitExceeded"); + s.store_field("retry_after", retry_after_); s.store_class_end(); } } -chatEventPermissionsChanged::chatEventPermissionsChanged() - : old_permissions_() - , new_permissions_() +canSendStoryResultMonthlyLimitExceeded::canSendStoryResultMonthlyLimitExceeded() + : retry_after_() {} -chatEventPermissionsChanged::chatEventPermissionsChanged(object_ptr &&old_permissions_, object_ptr &&new_permissions_) - : old_permissions_(std::move(old_permissions_)) - , new_permissions_(std::move(new_permissions_)) +canSendStoryResultMonthlyLimitExceeded::canSendStoryResultMonthlyLimitExceeded(int32 retry_after_) + : retry_after_(retry_after_) {} -const std::int32_t chatEventPermissionsChanged::ID; +const std::int32_t canSendStoryResultMonthlyLimitExceeded::ID; -void chatEventPermissionsChanged::store(TlStorerToString &s, const char *field_name) const { +void canSendStoryResultMonthlyLimitExceeded::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventPermissionsChanged"); - s.store_object_field("old_permissions", static_cast(old_permissions_.get())); - s.store_object_field("new_permissions", static_cast(new_permissions_.get())); + s.store_class_begin(field_name, "canSendStoryResultMonthlyLimitExceeded"); + s.store_field("retry_after", retry_after_); s.store_class_end(); } } -chatEventPhotoChanged::chatEventPhotoChanged() - : old_photo_() - , new_photo_() -{} - -chatEventPhotoChanged::chatEventPhotoChanged(object_ptr &&old_photo_, object_ptr &&new_photo_) - : old_photo_(std::move(old_photo_)) - , new_photo_(std::move(new_photo_)) -{} +canTransferOwnershipResultOk::canTransferOwnershipResultOk() { +} -const std::int32_t chatEventPhotoChanged::ID; +const std::int32_t canTransferOwnershipResultOk::ID; -void chatEventPhotoChanged::store(TlStorerToString &s, const char *field_name) const { +void canTransferOwnershipResultOk::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventPhotoChanged"); - s.store_object_field("old_photo", static_cast(old_photo_.get())); - s.store_object_field("new_photo", static_cast(new_photo_.get())); + s.store_class_begin(field_name, "canTransferOwnershipResultOk"); s.store_class_end(); } } -chatEventSlowModeDelayChanged::chatEventSlowModeDelayChanged() - : old_slow_mode_delay_() - , new_slow_mode_delay_() -{} - -chatEventSlowModeDelayChanged::chatEventSlowModeDelayChanged(int32 old_slow_mode_delay_, int32 new_slow_mode_delay_) - : old_slow_mode_delay_(old_slow_mode_delay_) - , new_slow_mode_delay_(new_slow_mode_delay_) -{} +canTransferOwnershipResultPasswordNeeded::canTransferOwnershipResultPasswordNeeded() { +} -const std::int32_t chatEventSlowModeDelayChanged::ID; +const std::int32_t canTransferOwnershipResultPasswordNeeded::ID; -void chatEventSlowModeDelayChanged::store(TlStorerToString &s, const char *field_name) const { +void canTransferOwnershipResultPasswordNeeded::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventSlowModeDelayChanged"); - s.store_field("old_slow_mode_delay", old_slow_mode_delay_); - s.store_field("new_slow_mode_delay", new_slow_mode_delay_); + s.store_class_begin(field_name, "canTransferOwnershipResultPasswordNeeded"); s.store_class_end(); } } -chatEventStickerSetChanged::chatEventStickerSetChanged() - : old_sticker_set_id_() - , new_sticker_set_id_() +canTransferOwnershipResultPasswordTooFresh::canTransferOwnershipResultPasswordTooFresh() + : retry_after_() {} -chatEventStickerSetChanged::chatEventStickerSetChanged(int64 old_sticker_set_id_, int64 new_sticker_set_id_) - : old_sticker_set_id_(old_sticker_set_id_) - , new_sticker_set_id_(new_sticker_set_id_) +canTransferOwnershipResultPasswordTooFresh::canTransferOwnershipResultPasswordTooFresh(int32 retry_after_) + : retry_after_(retry_after_) {} -const std::int32_t chatEventStickerSetChanged::ID; +const std::int32_t canTransferOwnershipResultPasswordTooFresh::ID; -void chatEventStickerSetChanged::store(TlStorerToString &s, const char *field_name) const { +void canTransferOwnershipResultPasswordTooFresh::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventStickerSetChanged"); - s.store_field("old_sticker_set_id", old_sticker_set_id_); - s.store_field("new_sticker_set_id", new_sticker_set_id_); + s.store_class_begin(field_name, "canTransferOwnershipResultPasswordTooFresh"); + s.store_field("retry_after", retry_after_); s.store_class_end(); } } -chatEventTitleChanged::chatEventTitleChanged() - : old_title_() - , new_title_() +canTransferOwnershipResultSessionTooFresh::canTransferOwnershipResultSessionTooFresh() + : retry_after_() {} -chatEventTitleChanged::chatEventTitleChanged(string const &old_title_, string const &new_title_) - : old_title_(old_title_) - , new_title_(new_title_) +canTransferOwnershipResultSessionTooFresh::canTransferOwnershipResultSessionTooFresh(int32 retry_after_) + : retry_after_(retry_after_) {} -const std::int32_t chatEventTitleChanged::ID; +const std::int32_t canTransferOwnershipResultSessionTooFresh::ID; -void chatEventTitleChanged::store(TlStorerToString &s, const char *field_name) const { +void canTransferOwnershipResultSessionTooFresh::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventTitleChanged"); - s.store_field("old_title", old_title_); - s.store_field("new_title", new_title_); + s.store_class_begin(field_name, "canTransferOwnershipResultSessionTooFresh"); + s.store_field("retry_after", retry_after_); s.store_class_end(); } } -chatEventUsernameChanged::chatEventUsernameChanged() - : old_username_() - , new_username_() -{} - -chatEventUsernameChanged::chatEventUsernameChanged(string const &old_username_, string const &new_username_) - : old_username_(old_username_) - , new_username_(new_username_) -{} - -const std::int32_t chatEventUsernameChanged::ID; - -void chatEventUsernameChanged::store(TlStorerToString &s, const char *field_name) const { +chat::chat() + : id_() + , type_() + , title_() + , photo_() + , accent_color_id_() + , background_custom_emoji_id_() + , profile_accent_color_id_() + , profile_background_custom_emoji_id_() + , permissions_() + , last_message_() + , positions_() + , chat_lists_() + , message_sender_id_() + , block_list_() + , has_protected_content_() + , is_translatable_() + , is_marked_as_unread_() + , view_as_topics_() + , has_scheduled_messages_() + , can_be_deleted_only_for_self_() + , can_be_deleted_for_all_users_() + , can_be_reported_() + , default_disable_notification_() + , unread_count_() + , last_read_inbox_message_id_() + , last_read_outbox_message_id_() + , unread_mention_count_() + , unread_reaction_count_() + , notification_settings_() + , available_reactions_() + , message_auto_delete_time_() + , emoji_status_() + , background_() + , theme_name_() + , action_bar_() + , business_bot_manage_bar_() + , video_chat_() + , pending_join_requests_() + , reply_markup_message_id_() + , draft_message_() + , client_data_() +{} + +chat::chat(int53 id_, object_ptr &&type_, string const &title_, object_ptr &&photo_, int32 accent_color_id_, int64 background_custom_emoji_id_, int32 profile_accent_color_id_, int64 profile_background_custom_emoji_id_, object_ptr &&permissions_, object_ptr &&last_message_, array> &&positions_, array> &&chat_lists_, object_ptr &&message_sender_id_, object_ptr &&block_list_, bool has_protected_content_, bool is_translatable_, bool is_marked_as_unread_, bool view_as_topics_, bool has_scheduled_messages_, bool can_be_deleted_only_for_self_, bool can_be_deleted_for_all_users_, bool can_be_reported_, bool default_disable_notification_, int32 unread_count_, int53 last_read_inbox_message_id_, int53 last_read_outbox_message_id_, int32 unread_mention_count_, int32 unread_reaction_count_, object_ptr &¬ification_settings_, object_ptr &&available_reactions_, int32 message_auto_delete_time_, object_ptr &&emoji_status_, object_ptr &&background_, string const &theme_name_, object_ptr &&action_bar_, object_ptr &&business_bot_manage_bar_, object_ptr &&video_chat_, object_ptr &&pending_join_requests_, int53 reply_markup_message_id_, object_ptr &&draft_message_, string const &client_data_) + : id_(id_) + , type_(std::move(type_)) + , title_(title_) + , photo_(std::move(photo_)) + , accent_color_id_(accent_color_id_) + , background_custom_emoji_id_(background_custom_emoji_id_) + , profile_accent_color_id_(profile_accent_color_id_) + , profile_background_custom_emoji_id_(profile_background_custom_emoji_id_) + , permissions_(std::move(permissions_)) + , last_message_(std::move(last_message_)) + , positions_(std::move(positions_)) + , chat_lists_(std::move(chat_lists_)) + , message_sender_id_(std::move(message_sender_id_)) + , block_list_(std::move(block_list_)) + , has_protected_content_(has_protected_content_) + , is_translatable_(is_translatable_) + , is_marked_as_unread_(is_marked_as_unread_) + , view_as_topics_(view_as_topics_) + , has_scheduled_messages_(has_scheduled_messages_) + , can_be_deleted_only_for_self_(can_be_deleted_only_for_self_) + , can_be_deleted_for_all_users_(can_be_deleted_for_all_users_) + , can_be_reported_(can_be_reported_) + , default_disable_notification_(default_disable_notification_) + , unread_count_(unread_count_) + , last_read_inbox_message_id_(last_read_inbox_message_id_) + , last_read_outbox_message_id_(last_read_outbox_message_id_) + , unread_mention_count_(unread_mention_count_) + , unread_reaction_count_(unread_reaction_count_) + , notification_settings_(std::move(notification_settings_)) + , available_reactions_(std::move(available_reactions_)) + , message_auto_delete_time_(message_auto_delete_time_) + , emoji_status_(std::move(emoji_status_)) + , background_(std::move(background_)) + , theme_name_(theme_name_) + , action_bar_(std::move(action_bar_)) + , business_bot_manage_bar_(std::move(business_bot_manage_bar_)) + , video_chat_(std::move(video_chat_)) + , pending_join_requests_(std::move(pending_join_requests_)) + , reply_markup_message_id_(reply_markup_message_id_) + , draft_message_(std::move(draft_message_)) + , client_data_(client_data_) +{} + +const std::int32_t chat::ID; + +void chat::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventUsernameChanged"); - s.store_field("old_username", old_username_); - s.store_field("new_username", new_username_); + s.store_class_begin(field_name, "chat"); + s.store_field("id", id_); + s.store_object_field("type", static_cast(type_.get())); + s.store_field("title", title_); + s.store_object_field("photo", static_cast(photo_.get())); + s.store_field("accent_color_id", accent_color_id_); + s.store_field("background_custom_emoji_id", background_custom_emoji_id_); + s.store_field("profile_accent_color_id", profile_accent_color_id_); + s.store_field("profile_background_custom_emoji_id", profile_background_custom_emoji_id_); + s.store_object_field("permissions", static_cast(permissions_.get())); + s.store_object_field("last_message", static_cast(last_message_.get())); + { s.store_vector_begin("positions", positions_.size()); for (const auto &_value : positions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + { s.store_vector_begin("chat_lists", chat_lists_.size()); for (const auto &_value : chat_lists_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_object_field("message_sender_id", static_cast(message_sender_id_.get())); + s.store_object_field("block_list", static_cast(block_list_.get())); + s.store_field("has_protected_content", has_protected_content_); + s.store_field("is_translatable", is_translatable_); + s.store_field("is_marked_as_unread", is_marked_as_unread_); + s.store_field("view_as_topics", view_as_topics_); + s.store_field("has_scheduled_messages", has_scheduled_messages_); + s.store_field("can_be_deleted_only_for_self", can_be_deleted_only_for_self_); + s.store_field("can_be_deleted_for_all_users", can_be_deleted_for_all_users_); + s.store_field("can_be_reported", can_be_reported_); + s.store_field("default_disable_notification", default_disable_notification_); + s.store_field("unread_count", unread_count_); + s.store_field("last_read_inbox_message_id", last_read_inbox_message_id_); + s.store_field("last_read_outbox_message_id", last_read_outbox_message_id_); + s.store_field("unread_mention_count", unread_mention_count_); + s.store_field("unread_reaction_count", unread_reaction_count_); + s.store_object_field("notification_settings", static_cast(notification_settings_.get())); + s.store_object_field("available_reactions", static_cast(available_reactions_.get())); + s.store_field("message_auto_delete_time", message_auto_delete_time_); + s.store_object_field("emoji_status", static_cast(emoji_status_.get())); + s.store_object_field("background", static_cast(background_.get())); + s.store_field("theme_name", theme_name_); + s.store_object_field("action_bar", static_cast(action_bar_.get())); + s.store_object_field("business_bot_manage_bar", static_cast(business_bot_manage_bar_.get())); + s.store_object_field("video_chat", static_cast(video_chat_.get())); + s.store_object_field("pending_join_requests", static_cast(pending_join_requests_.get())); + s.store_field("reply_markup_message_id", reply_markup_message_id_); + s.store_object_field("draft_message", static_cast(draft_message_.get())); + s.store_field("client_data", client_data_); s.store_class_end(); } } -chatEventActiveUsernamesChanged::chatEventActiveUsernamesChanged() - : old_usernames_() - , new_usernames_() -{} - -chatEventActiveUsernamesChanged::chatEventActiveUsernamesChanged(array &&old_usernames_, array &&new_usernames_) - : old_usernames_(std::move(old_usernames_)) - , new_usernames_(std::move(new_usernames_)) -{} +chatActionTyping::chatActionTyping() { +} -const std::int32_t chatEventActiveUsernamesChanged::ID; +const std::int32_t chatActionTyping::ID; -void chatEventActiveUsernamesChanged::store(TlStorerToString &s, const char *field_name) const { +void chatActionTyping::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventActiveUsernamesChanged"); - { s.store_vector_begin("old_usernames", old_usernames_.size()); for (const auto &_value : old_usernames_) { s.store_field("", _value); } s.store_class_end(); } - { s.store_vector_begin("new_usernames", new_usernames_.size()); for (const auto &_value : new_usernames_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_begin(field_name, "chatActionTyping"); s.store_class_end(); } } -chatEventHasProtectedContentToggled::chatEventHasProtectedContentToggled() - : has_protected_content_() -{} - -chatEventHasProtectedContentToggled::chatEventHasProtectedContentToggled(bool has_protected_content_) - : has_protected_content_(has_protected_content_) -{} +chatActionRecordingVideo::chatActionRecordingVideo() { +} -const std::int32_t chatEventHasProtectedContentToggled::ID; +const std::int32_t chatActionRecordingVideo::ID; -void chatEventHasProtectedContentToggled::store(TlStorerToString &s, const char *field_name) const { +void chatActionRecordingVideo::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventHasProtectedContentToggled"); - s.store_field("has_protected_content", has_protected_content_); + s.store_class_begin(field_name, "chatActionRecordingVideo"); s.store_class_end(); } } -chatEventInvitesToggled::chatEventInvitesToggled() - : can_invite_users_() +chatActionUploadingVideo::chatActionUploadingVideo() + : progress_() {} -chatEventInvitesToggled::chatEventInvitesToggled(bool can_invite_users_) - : can_invite_users_(can_invite_users_) +chatActionUploadingVideo::chatActionUploadingVideo(int32 progress_) + : progress_(progress_) {} -const std::int32_t chatEventInvitesToggled::ID; +const std::int32_t chatActionUploadingVideo::ID; -void chatEventInvitesToggled::store(TlStorerToString &s, const char *field_name) const { +void chatActionUploadingVideo::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventInvitesToggled"); - s.store_field("can_invite_users", can_invite_users_); + s.store_class_begin(field_name, "chatActionUploadingVideo"); + s.store_field("progress", progress_); s.store_class_end(); } } -chatEventIsAllHistoryAvailableToggled::chatEventIsAllHistoryAvailableToggled() - : is_all_history_available_() -{} - -chatEventIsAllHistoryAvailableToggled::chatEventIsAllHistoryAvailableToggled(bool is_all_history_available_) - : is_all_history_available_(is_all_history_available_) -{} +chatActionRecordingVoiceNote::chatActionRecordingVoiceNote() { +} -const std::int32_t chatEventIsAllHistoryAvailableToggled::ID; +const std::int32_t chatActionRecordingVoiceNote::ID; -void chatEventIsAllHistoryAvailableToggled::store(TlStorerToString &s, const char *field_name) const { +void chatActionRecordingVoiceNote::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventIsAllHistoryAvailableToggled"); - s.store_field("is_all_history_available", is_all_history_available_); + s.store_class_begin(field_name, "chatActionRecordingVoiceNote"); s.store_class_end(); } } -chatEventHasAggressiveAntiSpamEnabledToggled::chatEventHasAggressiveAntiSpamEnabledToggled() - : has_aggressive_anti_spam_enabled_() +chatActionUploadingVoiceNote::chatActionUploadingVoiceNote() + : progress_() {} -chatEventHasAggressiveAntiSpamEnabledToggled::chatEventHasAggressiveAntiSpamEnabledToggled(bool has_aggressive_anti_spam_enabled_) - : has_aggressive_anti_spam_enabled_(has_aggressive_anti_spam_enabled_) +chatActionUploadingVoiceNote::chatActionUploadingVoiceNote(int32 progress_) + : progress_(progress_) {} -const std::int32_t chatEventHasAggressiveAntiSpamEnabledToggled::ID; +const std::int32_t chatActionUploadingVoiceNote::ID; -void chatEventHasAggressiveAntiSpamEnabledToggled::store(TlStorerToString &s, const char *field_name) const { +void chatActionUploadingVoiceNote::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventHasAggressiveAntiSpamEnabledToggled"); - s.store_field("has_aggressive_anti_spam_enabled", has_aggressive_anti_spam_enabled_); + s.store_class_begin(field_name, "chatActionUploadingVoiceNote"); + s.store_field("progress", progress_); s.store_class_end(); } } -chatEventSignMessagesToggled::chatEventSignMessagesToggled() - : sign_messages_() +chatActionUploadingPhoto::chatActionUploadingPhoto() + : progress_() {} -chatEventSignMessagesToggled::chatEventSignMessagesToggled(bool sign_messages_) - : sign_messages_(sign_messages_) +chatActionUploadingPhoto::chatActionUploadingPhoto(int32 progress_) + : progress_(progress_) {} -const std::int32_t chatEventSignMessagesToggled::ID; +const std::int32_t chatActionUploadingPhoto::ID; -void chatEventSignMessagesToggled::store(TlStorerToString &s, const char *field_name) const { +void chatActionUploadingPhoto::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventSignMessagesToggled"); - s.store_field("sign_messages", sign_messages_); + s.store_class_begin(field_name, "chatActionUploadingPhoto"); + s.store_field("progress", progress_); s.store_class_end(); } } -chatEventInviteLinkEdited::chatEventInviteLinkEdited() - : old_invite_link_() - , new_invite_link_() +chatActionUploadingDocument::chatActionUploadingDocument() + : progress_() {} -chatEventInviteLinkEdited::chatEventInviteLinkEdited(object_ptr &&old_invite_link_, object_ptr &&new_invite_link_) - : old_invite_link_(std::move(old_invite_link_)) - , new_invite_link_(std::move(new_invite_link_)) +chatActionUploadingDocument::chatActionUploadingDocument(int32 progress_) + : progress_(progress_) {} -const std::int32_t chatEventInviteLinkEdited::ID; +const std::int32_t chatActionUploadingDocument::ID; -void chatEventInviteLinkEdited::store(TlStorerToString &s, const char *field_name) const { +void chatActionUploadingDocument::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventInviteLinkEdited"); - s.store_object_field("old_invite_link", static_cast(old_invite_link_.get())); - s.store_object_field("new_invite_link", static_cast(new_invite_link_.get())); + s.store_class_begin(field_name, "chatActionUploadingDocument"); + s.store_field("progress", progress_); s.store_class_end(); } } -chatEventInviteLinkRevoked::chatEventInviteLinkRevoked() - : invite_link_() -{} - -chatEventInviteLinkRevoked::chatEventInviteLinkRevoked(object_ptr &&invite_link_) - : invite_link_(std::move(invite_link_)) -{} +chatActionChoosingSticker::chatActionChoosingSticker() { +} -const std::int32_t chatEventInviteLinkRevoked::ID; +const std::int32_t chatActionChoosingSticker::ID; -void chatEventInviteLinkRevoked::store(TlStorerToString &s, const char *field_name) const { +void chatActionChoosingSticker::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventInviteLinkRevoked"); - s.store_object_field("invite_link", static_cast(invite_link_.get())); + s.store_class_begin(field_name, "chatActionChoosingSticker"); s.store_class_end(); } } -chatEventInviteLinkDeleted::chatEventInviteLinkDeleted() - : invite_link_() -{} - -chatEventInviteLinkDeleted::chatEventInviteLinkDeleted(object_ptr &&invite_link_) - : invite_link_(std::move(invite_link_)) -{} +chatActionChoosingLocation::chatActionChoosingLocation() { +} -const std::int32_t chatEventInviteLinkDeleted::ID; +const std::int32_t chatActionChoosingLocation::ID; -void chatEventInviteLinkDeleted::store(TlStorerToString &s, const char *field_name) const { +void chatActionChoosingLocation::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventInviteLinkDeleted"); - s.store_object_field("invite_link", static_cast(invite_link_.get())); + s.store_class_begin(field_name, "chatActionChoosingLocation"); s.store_class_end(); } } -chatEventVideoChatCreated::chatEventVideoChatCreated() - : group_call_id_() -{} - -chatEventVideoChatCreated::chatEventVideoChatCreated(int32 group_call_id_) - : group_call_id_(group_call_id_) -{} +chatActionChoosingContact::chatActionChoosingContact() { +} -const std::int32_t chatEventVideoChatCreated::ID; +const std::int32_t chatActionChoosingContact::ID; -void chatEventVideoChatCreated::store(TlStorerToString &s, const char *field_name) const { +void chatActionChoosingContact::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventVideoChatCreated"); - s.store_field("group_call_id", group_call_id_); + s.store_class_begin(field_name, "chatActionChoosingContact"); s.store_class_end(); } } -chatEventVideoChatEnded::chatEventVideoChatEnded() - : group_call_id_() -{} +chatActionStartPlayingGame::chatActionStartPlayingGame() { +} -chatEventVideoChatEnded::chatEventVideoChatEnded(int32 group_call_id_) - : group_call_id_(group_call_id_) -{} +const std::int32_t chatActionStartPlayingGame::ID; -const std::int32_t chatEventVideoChatEnded::ID; +void chatActionStartPlayingGame::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatActionStartPlayingGame"); + s.store_class_end(); + } +} -void chatEventVideoChatEnded::store(TlStorerToString &s, const char *field_name) const { +chatActionRecordingVideoNote::chatActionRecordingVideoNote() { +} + +const std::int32_t chatActionRecordingVideoNote::ID; + +void chatActionRecordingVideoNote::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventVideoChatEnded"); - s.store_field("group_call_id", group_call_id_); + s.store_class_begin(field_name, "chatActionRecordingVideoNote"); s.store_class_end(); } } -chatEventVideoChatMuteNewParticipantsToggled::chatEventVideoChatMuteNewParticipantsToggled() - : mute_new_participants_() +chatActionUploadingVideoNote::chatActionUploadingVideoNote() + : progress_() {} -chatEventVideoChatMuteNewParticipantsToggled::chatEventVideoChatMuteNewParticipantsToggled(bool mute_new_participants_) - : mute_new_participants_(mute_new_participants_) +chatActionUploadingVideoNote::chatActionUploadingVideoNote(int32 progress_) + : progress_(progress_) {} -const std::int32_t chatEventVideoChatMuteNewParticipantsToggled::ID; +const std::int32_t chatActionUploadingVideoNote::ID; -void chatEventVideoChatMuteNewParticipantsToggled::store(TlStorerToString &s, const char *field_name) const { +void chatActionUploadingVideoNote::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventVideoChatMuteNewParticipantsToggled"); - s.store_field("mute_new_participants", mute_new_participants_); + s.store_class_begin(field_name, "chatActionUploadingVideoNote"); + s.store_field("progress", progress_); s.store_class_end(); } } -chatEventVideoChatParticipantIsMutedToggled::chatEventVideoChatParticipantIsMutedToggled() - : participant_id_() - , is_muted_() +chatActionWatchingAnimations::chatActionWatchingAnimations() + : emoji_() {} -chatEventVideoChatParticipantIsMutedToggled::chatEventVideoChatParticipantIsMutedToggled(object_ptr &&participant_id_, bool is_muted_) - : participant_id_(std::move(participant_id_)) - , is_muted_(is_muted_) +chatActionWatchingAnimations::chatActionWatchingAnimations(string const &emoji_) + : emoji_(emoji_) {} -const std::int32_t chatEventVideoChatParticipantIsMutedToggled::ID; +const std::int32_t chatActionWatchingAnimations::ID; -void chatEventVideoChatParticipantIsMutedToggled::store(TlStorerToString &s, const char *field_name) const { +void chatActionWatchingAnimations::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventVideoChatParticipantIsMutedToggled"); - s.store_object_field("participant_id", static_cast(participant_id_.get())); - s.store_field("is_muted", is_muted_); + s.store_class_begin(field_name, "chatActionWatchingAnimations"); + s.store_field("emoji", emoji_); s.store_class_end(); } } -chatEventVideoChatParticipantVolumeLevelChanged::chatEventVideoChatParticipantVolumeLevelChanged() - : participant_id_() - , volume_level_() -{} - -chatEventVideoChatParticipantVolumeLevelChanged::chatEventVideoChatParticipantVolumeLevelChanged(object_ptr &&participant_id_, int32 volume_level_) - : participant_id_(std::move(participant_id_)) - , volume_level_(volume_level_) -{} +chatActionCancel::chatActionCancel() { +} -const std::int32_t chatEventVideoChatParticipantVolumeLevelChanged::ID; +const std::int32_t chatActionCancel::ID; -void chatEventVideoChatParticipantVolumeLevelChanged::store(TlStorerToString &s, const char *field_name) const { +void chatActionCancel::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventVideoChatParticipantVolumeLevelChanged"); - s.store_object_field("participant_id", static_cast(participant_id_.get())); - s.store_field("volume_level", volume_level_); + s.store_class_begin(field_name, "chatActionCancel"); s.store_class_end(); } } -chatEventIsForumToggled::chatEventIsForumToggled() - : is_forum_() +chatActionBarReportSpam::chatActionBarReportSpam() + : can_unarchive_() {} -chatEventIsForumToggled::chatEventIsForumToggled(bool is_forum_) - : is_forum_(is_forum_) +chatActionBarReportSpam::chatActionBarReportSpam(bool can_unarchive_) + : can_unarchive_(can_unarchive_) {} -const std::int32_t chatEventIsForumToggled::ID; +const std::int32_t chatActionBarReportSpam::ID; -void chatEventIsForumToggled::store(TlStorerToString &s, const char *field_name) const { +void chatActionBarReportSpam::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventIsForumToggled"); - s.store_field("is_forum", is_forum_); + s.store_class_begin(field_name, "chatActionBarReportSpam"); + s.store_field("can_unarchive", can_unarchive_); s.store_class_end(); } } -chatEventForumTopicCreated::chatEventForumTopicCreated() - : topic_info_() -{} +chatActionBarReportUnrelatedLocation::chatActionBarReportUnrelatedLocation() { +} -chatEventForumTopicCreated::chatEventForumTopicCreated(object_ptr &&topic_info_) - : topic_info_(std::move(topic_info_)) -{} +const std::int32_t chatActionBarReportUnrelatedLocation::ID; -const std::int32_t chatEventForumTopicCreated::ID; +void chatActionBarReportUnrelatedLocation::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatActionBarReportUnrelatedLocation"); + s.store_class_end(); + } +} -void chatEventForumTopicCreated::store(TlStorerToString &s, const char *field_name) const { +chatActionBarInviteMembers::chatActionBarInviteMembers() { +} + +const std::int32_t chatActionBarInviteMembers::ID; + +void chatActionBarInviteMembers::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventForumTopicCreated"); - s.store_object_field("topic_info", static_cast(topic_info_.get())); + s.store_class_begin(field_name, "chatActionBarInviteMembers"); s.store_class_end(); } } -chatEventForumTopicEdited::chatEventForumTopicEdited() - : old_topic_info_() - , new_topic_info_() +chatActionBarReportAddBlock::chatActionBarReportAddBlock() + : can_unarchive_() + , distance_() {} -chatEventForumTopicEdited::chatEventForumTopicEdited(object_ptr &&old_topic_info_, object_ptr &&new_topic_info_) - : old_topic_info_(std::move(old_topic_info_)) - , new_topic_info_(std::move(new_topic_info_)) +chatActionBarReportAddBlock::chatActionBarReportAddBlock(bool can_unarchive_, int32 distance_) + : can_unarchive_(can_unarchive_) + , distance_(distance_) {} -const std::int32_t chatEventForumTopicEdited::ID; +const std::int32_t chatActionBarReportAddBlock::ID; -void chatEventForumTopicEdited::store(TlStorerToString &s, const char *field_name) const { +void chatActionBarReportAddBlock::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventForumTopicEdited"); - s.store_object_field("old_topic_info", static_cast(old_topic_info_.get())); - s.store_object_field("new_topic_info", static_cast(new_topic_info_.get())); + s.store_class_begin(field_name, "chatActionBarReportAddBlock"); + s.store_field("can_unarchive", can_unarchive_); + s.store_field("distance", distance_); s.store_class_end(); } } -chatEventForumTopicToggleIsClosed::chatEventForumTopicToggleIsClosed() - : topic_info_() -{} +chatActionBarAddContact::chatActionBarAddContact() { +} -chatEventForumTopicToggleIsClosed::chatEventForumTopicToggleIsClosed(object_ptr &&topic_info_) - : topic_info_(std::move(topic_info_)) -{} +const std::int32_t chatActionBarAddContact::ID; -const std::int32_t chatEventForumTopicToggleIsClosed::ID; +void chatActionBarAddContact::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatActionBarAddContact"); + s.store_class_end(); + } +} -void chatEventForumTopicToggleIsClosed::store(TlStorerToString &s, const char *field_name) const { +chatActionBarSharePhoneNumber::chatActionBarSharePhoneNumber() { +} + +const std::int32_t chatActionBarSharePhoneNumber::ID; + +void chatActionBarSharePhoneNumber::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventForumTopicToggleIsClosed"); - s.store_object_field("topic_info", static_cast(topic_info_.get())); + s.store_class_begin(field_name, "chatActionBarSharePhoneNumber"); s.store_class_end(); } } -chatEventForumTopicToggleIsHidden::chatEventForumTopicToggleIsHidden() - : topic_info_() +chatActionBarJoinRequest::chatActionBarJoinRequest() + : title_() + , is_channel_() + , request_date_() {} -chatEventForumTopicToggleIsHidden::chatEventForumTopicToggleIsHidden(object_ptr &&topic_info_) - : topic_info_(std::move(topic_info_)) +chatActionBarJoinRequest::chatActionBarJoinRequest(string const &title_, bool is_channel_, int32 request_date_) + : title_(title_) + , is_channel_(is_channel_) + , request_date_(request_date_) {} -const std::int32_t chatEventForumTopicToggleIsHidden::ID; +const std::int32_t chatActionBarJoinRequest::ID; -void chatEventForumTopicToggleIsHidden::store(TlStorerToString &s, const char *field_name) const { +void chatActionBarJoinRequest::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventForumTopicToggleIsHidden"); - s.store_object_field("topic_info", static_cast(topic_info_.get())); + s.store_class_begin(field_name, "chatActionBarJoinRequest"); + s.store_field("title", title_); + s.store_field("is_channel", is_channel_); + s.store_field("request_date", request_date_); s.store_class_end(); } } -chatEventForumTopicDeleted::chatEventForumTopicDeleted() - : topic_info_() +chatActiveStories::chatActiveStories() + : chat_id_() + , list_() + , order_() + , max_read_story_id_() + , stories_() {} -chatEventForumTopicDeleted::chatEventForumTopicDeleted(object_ptr &&topic_info_) - : topic_info_(std::move(topic_info_)) +chatActiveStories::chatActiveStories(int53 chat_id_, object_ptr &&list_, int53 order_, int32 max_read_story_id_, array> &&stories_) + : chat_id_(chat_id_) + , list_(std::move(list_)) + , order_(order_) + , max_read_story_id_(max_read_story_id_) + , stories_(std::move(stories_)) {} -const std::int32_t chatEventForumTopicDeleted::ID; +const std::int32_t chatActiveStories::ID; -void chatEventForumTopicDeleted::store(TlStorerToString &s, const char *field_name) const { +void chatActiveStories::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventForumTopicDeleted"); - s.store_object_field("topic_info", static_cast(topic_info_.get())); + s.store_class_begin(field_name, "chatActiveStories"); + s.store_field("chat_id", chat_id_); + s.store_object_field("list", static_cast(list_.get())); + s.store_field("order", order_); + s.store_field("max_read_story_id", max_read_story_id_); + { s.store_vector_begin("stories", stories_.size()); for (const auto &_value : stories_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -chatEventForumTopicPinned::chatEventForumTopicPinned() - : old_topic_info_() - , new_topic_info_() +chatAdministrator::chatAdministrator() + : user_id_() + , custom_title_() + , is_owner_() {} -chatEventForumTopicPinned::chatEventForumTopicPinned(object_ptr &&old_topic_info_, object_ptr &&new_topic_info_) - : old_topic_info_(std::move(old_topic_info_)) - , new_topic_info_(std::move(new_topic_info_)) +chatAdministrator::chatAdministrator(int53 user_id_, string const &custom_title_, bool is_owner_) + : user_id_(user_id_) + , custom_title_(custom_title_) + , is_owner_(is_owner_) {} -const std::int32_t chatEventForumTopicPinned::ID; +const std::int32_t chatAdministrator::ID; -void chatEventForumTopicPinned::store(TlStorerToString &s, const char *field_name) const { +void chatAdministrator::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventForumTopicPinned"); - s.store_object_field("old_topic_info", static_cast(old_topic_info_.get())); - s.store_object_field("new_topic_info", static_cast(new_topic_info_.get())); + s.store_class_begin(field_name, "chatAdministrator"); + s.store_field("user_id", user_id_); + s.store_field("custom_title", custom_title_); + s.store_field("is_owner", is_owner_); s.store_class_end(); } } -chatEventLogFilters::chatEventLogFilters() - : message_edits_() - , message_deletions_() - , message_pins_() - , member_joins_() - , member_leaves_() - , member_invites_() - , member_promotions_() - , member_restrictions_() - , info_changes_() - , setting_changes_() - , invite_link_changes_() - , video_chat_changes_() - , forum_changes_() +chatAdministratorRights::chatAdministratorRights() + : can_manage_chat_() + , can_change_info_() + , can_post_messages_() + , can_edit_messages_() + , can_delete_messages_() + , can_invite_users_() + , can_restrict_members_() + , can_pin_messages_() + , can_manage_topics_() + , can_promote_members_() + , can_manage_video_chats_() + , can_post_stories_() + , can_edit_stories_() + , can_delete_stories_() + , is_anonymous_() {} -chatEventLogFilters::chatEventLogFilters(bool message_edits_, bool message_deletions_, bool message_pins_, bool member_joins_, bool member_leaves_, bool member_invites_, bool member_promotions_, bool member_restrictions_, bool info_changes_, bool setting_changes_, bool invite_link_changes_, bool video_chat_changes_, bool forum_changes_) - : message_edits_(message_edits_) - , message_deletions_(message_deletions_) - , message_pins_(message_pins_) - , member_joins_(member_joins_) - , member_leaves_(member_leaves_) - , member_invites_(member_invites_) - , member_promotions_(member_promotions_) - , member_restrictions_(member_restrictions_) - , info_changes_(info_changes_) - , setting_changes_(setting_changes_) - , invite_link_changes_(invite_link_changes_) - , video_chat_changes_(video_chat_changes_) - , forum_changes_(forum_changes_) +chatAdministratorRights::chatAdministratorRights(bool can_manage_chat_, bool can_change_info_, bool can_post_messages_, bool can_edit_messages_, bool can_delete_messages_, bool can_invite_users_, bool can_restrict_members_, bool can_pin_messages_, bool can_manage_topics_, bool can_promote_members_, bool can_manage_video_chats_, bool can_post_stories_, bool can_edit_stories_, bool can_delete_stories_, bool is_anonymous_) + : can_manage_chat_(can_manage_chat_) + , can_change_info_(can_change_info_) + , can_post_messages_(can_post_messages_) + , can_edit_messages_(can_edit_messages_) + , can_delete_messages_(can_delete_messages_) + , can_invite_users_(can_invite_users_) + , can_restrict_members_(can_restrict_members_) + , can_pin_messages_(can_pin_messages_) + , can_manage_topics_(can_manage_topics_) + , can_promote_members_(can_promote_members_) + , can_manage_video_chats_(can_manage_video_chats_) + , can_post_stories_(can_post_stories_) + , can_edit_stories_(can_edit_stories_) + , can_delete_stories_(can_delete_stories_) + , is_anonymous_(is_anonymous_) {} -const std::int32_t chatEventLogFilters::ID; +const std::int32_t chatAdministratorRights::ID; -void chatEventLogFilters::store(TlStorerToString &s, const char *field_name) const { +void chatAdministratorRights::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEventLogFilters"); - s.store_field("message_edits", message_edits_); - s.store_field("message_deletions", message_deletions_); - s.store_field("message_pins", message_pins_); - s.store_field("member_joins", member_joins_); - s.store_field("member_leaves", member_leaves_); - s.store_field("member_invites", member_invites_); - s.store_field("member_promotions", member_promotions_); - s.store_field("member_restrictions", member_restrictions_); - s.store_field("info_changes", info_changes_); - s.store_field("setting_changes", setting_changes_); - s.store_field("invite_link_changes", invite_link_changes_); - s.store_field("video_chat_changes", video_chat_changes_); - s.store_field("forum_changes", forum_changes_); + s.store_class_begin(field_name, "chatAdministratorRights"); + s.store_field("can_manage_chat", can_manage_chat_); + s.store_field("can_change_info", can_change_info_); + s.store_field("can_post_messages", can_post_messages_); + s.store_field("can_edit_messages", can_edit_messages_); + s.store_field("can_delete_messages", can_delete_messages_); + s.store_field("can_invite_users", can_invite_users_); + s.store_field("can_restrict_members", can_restrict_members_); + s.store_field("can_pin_messages", can_pin_messages_); + s.store_field("can_manage_topics", can_manage_topics_); + s.store_field("can_promote_members", can_promote_members_); + s.store_field("can_manage_video_chats", can_manage_video_chats_); + s.store_field("can_post_stories", can_post_stories_); + s.store_field("can_edit_stories", can_edit_stories_); + s.store_field("can_delete_stories", can_delete_stories_); + s.store_field("is_anonymous", is_anonymous_); s.store_class_end(); } } -chatEvents::chatEvents() - : events_() +chatAdministrators::chatAdministrators() + : administrators_() {} -chatEvents::chatEvents(array> &&events_) - : events_(std::move(events_)) +chatAdministrators::chatAdministrators(array> &&administrators_) + : administrators_(std::move(administrators_)) {} -const std::int32_t chatEvents::ID; +const std::int32_t chatAdministrators::ID; -void chatEvents::store(TlStorerToString &s, const char *field_name) const { +void chatAdministrators::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatEvents"); - { s.store_vector_begin("events", events_.size()); for (const auto &_value : events_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatAdministrators"); + { s.store_vector_begin("administrators", administrators_.size()); for (const auto &_value : administrators_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -chatFolder::chatFolder() - : title_() - , icon_() - , is_shareable_() - , pinned_chat_ids_() - , included_chat_ids_() - , excluded_chat_ids_() - , exclude_muted_() - , exclude_read_() - , exclude_archived_() - , include_contacts_() - , include_non_contacts_() - , include_bots_() - , include_groups_() - , include_channels_() +chatAvailableReactionsAll::chatAvailableReactionsAll() + : max_reaction_count_() {} -chatFolder::chatFolder(string const &title_, object_ptr &&icon_, bool is_shareable_, array &&pinned_chat_ids_, array &&included_chat_ids_, array &&excluded_chat_ids_, bool exclude_muted_, bool exclude_read_, bool exclude_archived_, bool include_contacts_, bool include_non_contacts_, bool include_bots_, bool include_groups_, bool include_channels_) - : title_(title_) - , icon_(std::move(icon_)) - , is_shareable_(is_shareable_) - , pinned_chat_ids_(std::move(pinned_chat_ids_)) - , included_chat_ids_(std::move(included_chat_ids_)) - , excluded_chat_ids_(std::move(excluded_chat_ids_)) - , exclude_muted_(exclude_muted_) - , exclude_read_(exclude_read_) - , exclude_archived_(exclude_archived_) - , include_contacts_(include_contacts_) - , include_non_contacts_(include_non_contacts_) - , include_bots_(include_bots_) - , include_groups_(include_groups_) - , include_channels_(include_channels_) +chatAvailableReactionsAll::chatAvailableReactionsAll(int32 max_reaction_count_) + : max_reaction_count_(max_reaction_count_) {} -const std::int32_t chatFolder::ID; +const std::int32_t chatAvailableReactionsAll::ID; -void chatFolder::store(TlStorerToString &s, const char *field_name) const { +void chatAvailableReactionsAll::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatFolder"); - s.store_field("title", title_); - s.store_object_field("icon", static_cast(icon_.get())); - s.store_field("is_shareable", is_shareable_); - { s.store_vector_begin("pinned_chat_ids", pinned_chat_ids_.size()); for (const auto &_value : pinned_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } - { s.store_vector_begin("included_chat_ids", included_chat_ids_.size()); for (const auto &_value : included_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } - { s.store_vector_begin("excluded_chat_ids", excluded_chat_ids_.size()); for (const auto &_value : excluded_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } - s.store_field("exclude_muted", exclude_muted_); - s.store_field("exclude_read", exclude_read_); - s.store_field("exclude_archived", exclude_archived_); - s.store_field("include_contacts", include_contacts_); - s.store_field("include_non_contacts", include_non_contacts_); - s.store_field("include_bots", include_bots_); - s.store_field("include_groups", include_groups_); - s.store_field("include_channels", include_channels_); + s.store_class_begin(field_name, "chatAvailableReactionsAll"); + s.store_field("max_reaction_count", max_reaction_count_); s.store_class_end(); } } -chatFolderIcon::chatFolderIcon() - : name_() +chatAvailableReactionsSome::chatAvailableReactionsSome() + : reactions_() + , max_reaction_count_() {} -chatFolderIcon::chatFolderIcon(string const &name_) - : name_(name_) +chatAvailableReactionsSome::chatAvailableReactionsSome(array> &&reactions_, int32 max_reaction_count_) + : reactions_(std::move(reactions_)) + , max_reaction_count_(max_reaction_count_) {} -const std::int32_t chatFolderIcon::ID; +const std::int32_t chatAvailableReactionsSome::ID; -void chatFolderIcon::store(TlStorerToString &s, const char *field_name) const { +void chatAvailableReactionsSome::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatFolderIcon"); - s.store_field("name", name_); + s.store_class_begin(field_name, "chatAvailableReactionsSome"); + { s.store_vector_begin("reactions", reactions_.size()); for (const auto &_value : reactions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("max_reaction_count", max_reaction_count_); s.store_class_end(); } } -chatFolderInfo::chatFolderInfo() - : id_() - , title_() - , icon_() - , has_my_invite_links_() +chatBackground::chatBackground() + : background_() + , dark_theme_dimming_() {} -chatFolderInfo::chatFolderInfo(int32 id_, string const &title_, object_ptr &&icon_, bool has_my_invite_links_) - : id_(id_) - , title_(title_) - , icon_(std::move(icon_)) - , has_my_invite_links_(has_my_invite_links_) +chatBackground::chatBackground(object_ptr &&background_, int32 dark_theme_dimming_) + : background_(std::move(background_)) + , dark_theme_dimming_(dark_theme_dimming_) {} -const std::int32_t chatFolderInfo::ID; +const std::int32_t chatBackground::ID; -void chatFolderInfo::store(TlStorerToString &s, const char *field_name) const { +void chatBackground::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatFolderInfo"); - s.store_field("id", id_); - s.store_field("title", title_); - s.store_object_field("icon", static_cast(icon_.get())); - s.store_field("has_my_invite_links", has_my_invite_links_); + s.store_class_begin(field_name, "chatBackground"); + s.store_object_field("background", static_cast(background_.get())); + s.store_field("dark_theme_dimming", dark_theme_dimming_); s.store_class_end(); } } -chatFolderInviteLink::chatFolderInviteLink() - : invite_link_() - , name_() - , chat_ids_() +chatBoost::chatBoost() + : id_() + , count_() + , source_() + , start_date_() + , expiration_date_() {} -chatFolderInviteLink::chatFolderInviteLink(string const &invite_link_, string const &name_, array &&chat_ids_) - : invite_link_(invite_link_) - , name_(name_) - , chat_ids_(std::move(chat_ids_)) +chatBoost::chatBoost(string const &id_, int32 count_, object_ptr &&source_, int32 start_date_, int32 expiration_date_) + : id_(id_) + , count_(count_) + , source_(std::move(source_)) + , start_date_(start_date_) + , expiration_date_(expiration_date_) {} -const std::int32_t chatFolderInviteLink::ID; +const std::int32_t chatBoost::ID; -void chatFolderInviteLink::store(TlStorerToString &s, const char *field_name) const { +void chatBoost::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatFolderInviteLink"); - s.store_field("invite_link", invite_link_); - s.store_field("name", name_); - { s.store_vector_begin("chat_ids", chat_ids_.size()); for (const auto &_value : chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_begin(field_name, "chatBoost"); + s.store_field("id", id_); + s.store_field("count", count_); + s.store_object_field("source", static_cast(source_.get())); + s.store_field("start_date", start_date_); + s.store_field("expiration_date", expiration_date_); s.store_class_end(); } } -chatFolderInviteLinkInfo::chatFolderInviteLinkInfo() - : chat_folder_info_() - , missing_chat_ids_() - , added_chat_ids_() +chatBoostFeatures::chatBoostFeatures() + : features_() + , min_profile_background_custom_emoji_boost_level_() + , min_background_custom_emoji_boost_level_() + , min_emoji_status_boost_level_() + , min_chat_theme_background_boost_level_() + , min_custom_background_boost_level_() + , min_custom_emoji_sticker_set_boost_level_() + , min_speech_recognition_boost_level_() + , min_sponsored_message_disable_boost_level_() {} -chatFolderInviteLinkInfo::chatFolderInviteLinkInfo(object_ptr &&chat_folder_info_, array &&missing_chat_ids_, array &&added_chat_ids_) - : chat_folder_info_(std::move(chat_folder_info_)) - , missing_chat_ids_(std::move(missing_chat_ids_)) - , added_chat_ids_(std::move(added_chat_ids_)) +chatBoostFeatures::chatBoostFeatures(array> &&features_, int32 min_profile_background_custom_emoji_boost_level_, int32 min_background_custom_emoji_boost_level_, int32 min_emoji_status_boost_level_, int32 min_chat_theme_background_boost_level_, int32 min_custom_background_boost_level_, int32 min_custom_emoji_sticker_set_boost_level_, int32 min_speech_recognition_boost_level_, int32 min_sponsored_message_disable_boost_level_) + : features_(std::move(features_)) + , min_profile_background_custom_emoji_boost_level_(min_profile_background_custom_emoji_boost_level_) + , min_background_custom_emoji_boost_level_(min_background_custom_emoji_boost_level_) + , min_emoji_status_boost_level_(min_emoji_status_boost_level_) + , min_chat_theme_background_boost_level_(min_chat_theme_background_boost_level_) + , min_custom_background_boost_level_(min_custom_background_boost_level_) + , min_custom_emoji_sticker_set_boost_level_(min_custom_emoji_sticker_set_boost_level_) + , min_speech_recognition_boost_level_(min_speech_recognition_boost_level_) + , min_sponsored_message_disable_boost_level_(min_sponsored_message_disable_boost_level_) {} -const std::int32_t chatFolderInviteLinkInfo::ID; +const std::int32_t chatBoostFeatures::ID; -void chatFolderInviteLinkInfo::store(TlStorerToString &s, const char *field_name) const { +void chatBoostFeatures::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatFolderInviteLinkInfo"); - s.store_object_field("chat_folder_info", static_cast(chat_folder_info_.get())); - { s.store_vector_begin("missing_chat_ids", missing_chat_ids_.size()); for (const auto &_value : missing_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } - { s.store_vector_begin("added_chat_ids", added_chat_ids_.size()); for (const auto &_value : added_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } - s.store_class_end(); - } -} - -chatFolderInviteLinks::chatFolderInviteLinks() - : invite_links_() + s.store_class_begin(field_name, "chatBoostFeatures"); + { s.store_vector_begin("features", features_.size()); for (const auto &_value : features_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("min_profile_background_custom_emoji_boost_level", min_profile_background_custom_emoji_boost_level_); + s.store_field("min_background_custom_emoji_boost_level", min_background_custom_emoji_boost_level_); + s.store_field("min_emoji_status_boost_level", min_emoji_status_boost_level_); + s.store_field("min_chat_theme_background_boost_level", min_chat_theme_background_boost_level_); + s.store_field("min_custom_background_boost_level", min_custom_background_boost_level_); + s.store_field("min_custom_emoji_sticker_set_boost_level", min_custom_emoji_sticker_set_boost_level_); + s.store_field("min_speech_recognition_boost_level", min_speech_recognition_boost_level_); + s.store_field("min_sponsored_message_disable_boost_level", min_sponsored_message_disable_boost_level_); + s.store_class_end(); + } +} + +chatBoostLevelFeatures::chatBoostLevelFeatures() + : level_() + , story_per_day_count_() + , custom_emoji_reaction_count_() + , title_color_count_() + , profile_accent_color_count_() + , can_set_profile_background_custom_emoji_() + , accent_color_count_() + , can_set_background_custom_emoji_() + , can_set_emoji_status_() + , chat_theme_background_count_() + , can_set_custom_background_() + , can_set_custom_emoji_sticker_set_() + , can_recognize_speech_() + , can_disable_sponsored_messages_() +{} + +chatBoostLevelFeatures::chatBoostLevelFeatures(int32 level_, int32 story_per_day_count_, int32 custom_emoji_reaction_count_, int32 title_color_count_, int32 profile_accent_color_count_, bool can_set_profile_background_custom_emoji_, int32 accent_color_count_, bool can_set_background_custom_emoji_, bool can_set_emoji_status_, int32 chat_theme_background_count_, bool can_set_custom_background_, bool can_set_custom_emoji_sticker_set_, bool can_recognize_speech_, bool can_disable_sponsored_messages_) + : level_(level_) + , story_per_day_count_(story_per_day_count_) + , custom_emoji_reaction_count_(custom_emoji_reaction_count_) + , title_color_count_(title_color_count_) + , profile_accent_color_count_(profile_accent_color_count_) + , can_set_profile_background_custom_emoji_(can_set_profile_background_custom_emoji_) + , accent_color_count_(accent_color_count_) + , can_set_background_custom_emoji_(can_set_background_custom_emoji_) + , can_set_emoji_status_(can_set_emoji_status_) + , chat_theme_background_count_(chat_theme_background_count_) + , can_set_custom_background_(can_set_custom_background_) + , can_set_custom_emoji_sticker_set_(can_set_custom_emoji_sticker_set_) + , can_recognize_speech_(can_recognize_speech_) + , can_disable_sponsored_messages_(can_disable_sponsored_messages_) +{} + +const std::int32_t chatBoostLevelFeatures::ID; + +void chatBoostLevelFeatures::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatBoostLevelFeatures"); + s.store_field("level", level_); + s.store_field("story_per_day_count", story_per_day_count_); + s.store_field("custom_emoji_reaction_count", custom_emoji_reaction_count_); + s.store_field("title_color_count", title_color_count_); + s.store_field("profile_accent_color_count", profile_accent_color_count_); + s.store_field("can_set_profile_background_custom_emoji", can_set_profile_background_custom_emoji_); + s.store_field("accent_color_count", accent_color_count_); + s.store_field("can_set_background_custom_emoji", can_set_background_custom_emoji_); + s.store_field("can_set_emoji_status", can_set_emoji_status_); + s.store_field("chat_theme_background_count", chat_theme_background_count_); + s.store_field("can_set_custom_background", can_set_custom_background_); + s.store_field("can_set_custom_emoji_sticker_set", can_set_custom_emoji_sticker_set_); + s.store_field("can_recognize_speech", can_recognize_speech_); + s.store_field("can_disable_sponsored_messages", can_disable_sponsored_messages_); + s.store_class_end(); + } +} + +chatBoostLink::chatBoostLink() + : link_() + , is_public_() {} -chatFolderInviteLinks::chatFolderInviteLinks(array> &&invite_links_) - : invite_links_(std::move(invite_links_)) +chatBoostLink::chatBoostLink(string const &link_, bool is_public_) + : link_(link_) + , is_public_(is_public_) {} -const std::int32_t chatFolderInviteLinks::ID; +const std::int32_t chatBoostLink::ID; -void chatFolderInviteLinks::store(TlStorerToString &s, const char *field_name) const { +void chatBoostLink::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatFolderInviteLinks"); - { s.store_vector_begin("invite_links", invite_links_.size()); for (const auto &_value : invite_links_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatBoostLink"); + s.store_field("link", link_); + s.store_field("is_public", is_public_); s.store_class_end(); } } -chatInviteLink::chatInviteLink() - : invite_link_() - , name_() - , creator_user_id_() - , date_() - , edit_date_() - , expiration_date_() - , member_limit_() - , member_count_() - , pending_join_request_count_() - , creates_join_request_() - , is_primary_() - , is_revoked_() +chatBoostLinkInfo::chatBoostLinkInfo() + : is_public_() + , chat_id_() {} -chatInviteLink::chatInviteLink(string const &invite_link_, string const &name_, int53 creator_user_id_, int32 date_, int32 edit_date_, int32 expiration_date_, int32 member_limit_, int32 member_count_, int32 pending_join_request_count_, bool creates_join_request_, bool is_primary_, bool is_revoked_) - : invite_link_(invite_link_) - , name_(name_) - , creator_user_id_(creator_user_id_) - , date_(date_) - , edit_date_(edit_date_) - , expiration_date_(expiration_date_) - , member_limit_(member_limit_) - , member_count_(member_count_) - , pending_join_request_count_(pending_join_request_count_) - , creates_join_request_(creates_join_request_) - , is_primary_(is_primary_) - , is_revoked_(is_revoked_) +chatBoostLinkInfo::chatBoostLinkInfo(bool is_public_, int53 chat_id_) + : is_public_(is_public_) + , chat_id_(chat_id_) {} -const std::int32_t chatInviteLink::ID; +const std::int32_t chatBoostLinkInfo::ID; -void chatInviteLink::store(TlStorerToString &s, const char *field_name) const { +void chatBoostLinkInfo::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatInviteLink"); - s.store_field("invite_link", invite_link_); - s.store_field("name", name_); - s.store_field("creator_user_id", creator_user_id_); - s.store_field("date", date_); - s.store_field("edit_date", edit_date_); - s.store_field("expiration_date", expiration_date_); - s.store_field("member_limit", member_limit_); - s.store_field("member_count", member_count_); - s.store_field("pending_join_request_count", pending_join_request_count_); - s.store_field("creates_join_request", creates_join_request_); - s.store_field("is_primary", is_primary_); - s.store_field("is_revoked", is_revoked_); + s.store_class_begin(field_name, "chatBoostLinkInfo"); + s.store_field("is_public", is_public_); + s.store_field("chat_id", chat_id_); s.store_class_end(); } } -chatInviteLinkCount::chatInviteLinkCount() - : user_id_() - , invite_link_count_() - , revoked_invite_link_count_() +chatBoostSlot::chatBoostSlot() + : slot_id_() + , currently_boosted_chat_id_() + , start_date_() + , expiration_date_() + , cooldown_until_date_() {} -chatInviteLinkCount::chatInviteLinkCount(int53 user_id_, int32 invite_link_count_, int32 revoked_invite_link_count_) - : user_id_(user_id_) - , invite_link_count_(invite_link_count_) - , revoked_invite_link_count_(revoked_invite_link_count_) +chatBoostSlot::chatBoostSlot(int32 slot_id_, int53 currently_boosted_chat_id_, int32 start_date_, int32 expiration_date_, int32 cooldown_until_date_) + : slot_id_(slot_id_) + , currently_boosted_chat_id_(currently_boosted_chat_id_) + , start_date_(start_date_) + , expiration_date_(expiration_date_) + , cooldown_until_date_(cooldown_until_date_) {} -const std::int32_t chatInviteLinkCount::ID; +const std::int32_t chatBoostSlot::ID; -void chatInviteLinkCount::store(TlStorerToString &s, const char *field_name) const { +void chatBoostSlot::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatInviteLinkCount"); - s.store_field("user_id", user_id_); - s.store_field("invite_link_count", invite_link_count_); - s.store_field("revoked_invite_link_count", revoked_invite_link_count_); + s.store_class_begin(field_name, "chatBoostSlot"); + s.store_field("slot_id", slot_id_); + s.store_field("currently_boosted_chat_id", currently_boosted_chat_id_); + s.store_field("start_date", start_date_); + s.store_field("expiration_date", expiration_date_); + s.store_field("cooldown_until_date", cooldown_until_date_); s.store_class_end(); } } -chatInviteLinkCounts::chatInviteLinkCounts() - : invite_link_counts_() +chatBoostSlots::chatBoostSlots() + : slots_() {} -chatInviteLinkCounts::chatInviteLinkCounts(array> &&invite_link_counts_) - : invite_link_counts_(std::move(invite_link_counts_)) +chatBoostSlots::chatBoostSlots(array> &&slots_) + : slots_(std::move(slots_)) {} -const std::int32_t chatInviteLinkCounts::ID; +const std::int32_t chatBoostSlots::ID; -void chatInviteLinkCounts::store(TlStorerToString &s, const char *field_name) const { +void chatBoostSlots::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatInviteLinkCounts"); - { s.store_vector_begin("invite_link_counts", invite_link_counts_.size()); for (const auto &_value : invite_link_counts_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatBoostSlots"); + { s.store_vector_begin("slots", slots_.size()); for (const auto &_value : slots_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -chatInviteLinkInfo::chatInviteLinkInfo() - : chat_id_() - , accessible_for_() - , type_() - , title_() - , photo_() - , description_() - , member_count_() - , member_user_ids_() - , creates_join_request_() - , is_public_() +chatBoostSourceGiftCode::chatBoostSourceGiftCode() + : user_id_() + , gift_code_() {} -chatInviteLinkInfo::chatInviteLinkInfo(int53 chat_id_, int32 accessible_for_, object_ptr &&type_, string const &title_, object_ptr &&photo_, string const &description_, int32 member_count_, array &&member_user_ids_, bool creates_join_request_, bool is_public_) - : chat_id_(chat_id_) - , accessible_for_(accessible_for_) - , type_(std::move(type_)) - , title_(title_) - , photo_(std::move(photo_)) - , description_(description_) - , member_count_(member_count_) - , member_user_ids_(std::move(member_user_ids_)) - , creates_join_request_(creates_join_request_) - , is_public_(is_public_) +chatBoostSourceGiftCode::chatBoostSourceGiftCode(int53 user_id_, string const &gift_code_) + : user_id_(user_id_) + , gift_code_(gift_code_) {} -const std::int32_t chatInviteLinkInfo::ID; +const std::int32_t chatBoostSourceGiftCode::ID; -void chatInviteLinkInfo::store(TlStorerToString &s, const char *field_name) const { +void chatBoostSourceGiftCode::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatInviteLinkInfo"); - s.store_field("chat_id", chat_id_); - s.store_field("accessible_for", accessible_for_); - s.store_object_field("type", static_cast(type_.get())); - s.store_field("title", title_); - s.store_object_field("photo", static_cast(photo_.get())); - s.store_field("description", description_); - s.store_field("member_count", member_count_); - { s.store_vector_begin("member_user_ids", member_user_ids_.size()); for (const auto &_value : member_user_ids_) { s.store_field("", _value); } s.store_class_end(); } - s.store_field("creates_join_request", creates_join_request_); - s.store_field("is_public", is_public_); + s.store_class_begin(field_name, "chatBoostSourceGiftCode"); + s.store_field("user_id", user_id_); + s.store_field("gift_code", gift_code_); s.store_class_end(); } } -chatInviteLinkMember::chatInviteLinkMember() +chatBoostSourceGiveaway::chatBoostSourceGiveaway() : user_id_() - , joined_chat_date_() - , via_chat_folder_invite_link_() - , approver_user_id_() + , gift_code_() + , star_count_() + , giveaway_message_id_() + , is_unclaimed_() {} -chatInviteLinkMember::chatInviteLinkMember(int53 user_id_, int32 joined_chat_date_, bool via_chat_folder_invite_link_, int53 approver_user_id_) +chatBoostSourceGiveaway::chatBoostSourceGiveaway(int53 user_id_, string const &gift_code_, int53 star_count_, int53 giveaway_message_id_, bool is_unclaimed_) : user_id_(user_id_) - , joined_chat_date_(joined_chat_date_) - , via_chat_folder_invite_link_(via_chat_folder_invite_link_) - , approver_user_id_(approver_user_id_) + , gift_code_(gift_code_) + , star_count_(star_count_) + , giveaway_message_id_(giveaway_message_id_) + , is_unclaimed_(is_unclaimed_) {} -const std::int32_t chatInviteLinkMember::ID; +const std::int32_t chatBoostSourceGiveaway::ID; -void chatInviteLinkMember::store(TlStorerToString &s, const char *field_name) const { +void chatBoostSourceGiveaway::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatInviteLinkMember"); + s.store_class_begin(field_name, "chatBoostSourceGiveaway"); s.store_field("user_id", user_id_); - s.store_field("joined_chat_date", joined_chat_date_); - s.store_field("via_chat_folder_invite_link", via_chat_folder_invite_link_); - s.store_field("approver_user_id", approver_user_id_); + s.store_field("gift_code", gift_code_); + s.store_field("star_count", star_count_); + s.store_field("giveaway_message_id", giveaway_message_id_); + s.store_field("is_unclaimed", is_unclaimed_); s.store_class_end(); } } -chatInviteLinkMembers::chatInviteLinkMembers() - : total_count_() - , members_() +chatBoostSourcePremium::chatBoostSourcePremium() + : user_id_() {} -chatInviteLinkMembers::chatInviteLinkMembers(int32 total_count_, array> &&members_) - : total_count_(total_count_) - , members_(std::move(members_)) +chatBoostSourcePremium::chatBoostSourcePremium(int53 user_id_) + : user_id_(user_id_) {} -const std::int32_t chatInviteLinkMembers::ID; +const std::int32_t chatBoostSourcePremium::ID; -void chatInviteLinkMembers::store(TlStorerToString &s, const char *field_name) const { +void chatBoostSourcePremium::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatInviteLinkMembers"); - s.store_field("total_count", total_count_); - { s.store_vector_begin("members", members_.size()); for (const auto &_value : members_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatBoostSourcePremium"); + s.store_field("user_id", user_id_); s.store_class_end(); } } -chatInviteLinks::chatInviteLinks() - : total_count_() - , invite_links_() +chatBoostStatus::chatBoostStatus() + : boost_url_() + , applied_slot_ids_() + , level_() + , gift_code_boost_count_() + , boost_count_() + , current_level_boost_count_() + , next_level_boost_count_() + , premium_member_count_() + , premium_member_percentage_() + , prepaid_giveaways_() {} -chatInviteLinks::chatInviteLinks(int32 total_count_, array> &&invite_links_) - : total_count_(total_count_) - , invite_links_(std::move(invite_links_)) +chatBoostStatus::chatBoostStatus(string const &boost_url_, array &&applied_slot_ids_, int32 level_, int32 gift_code_boost_count_, int32 boost_count_, int32 current_level_boost_count_, int32 next_level_boost_count_, int32 premium_member_count_, double premium_member_percentage_, array> &&prepaid_giveaways_) + : boost_url_(boost_url_) + , applied_slot_ids_(std::move(applied_slot_ids_)) + , level_(level_) + , gift_code_boost_count_(gift_code_boost_count_) + , boost_count_(boost_count_) + , current_level_boost_count_(current_level_boost_count_) + , next_level_boost_count_(next_level_boost_count_) + , premium_member_count_(premium_member_count_) + , premium_member_percentage_(premium_member_percentage_) + , prepaid_giveaways_(std::move(prepaid_giveaways_)) {} -const std::int32_t chatInviteLinks::ID; +const std::int32_t chatBoostStatus::ID; -void chatInviteLinks::store(TlStorerToString &s, const char *field_name) const { +void chatBoostStatus::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatInviteLinks"); - s.store_field("total_count", total_count_); - { s.store_vector_begin("invite_links", invite_links_.size()); for (const auto &_value : invite_links_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatBoostStatus"); + s.store_field("boost_url", boost_url_); + { s.store_vector_begin("applied_slot_ids", applied_slot_ids_.size()); for (const auto &_value : applied_slot_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_field("level", level_); + s.store_field("gift_code_boost_count", gift_code_boost_count_); + s.store_field("boost_count", boost_count_); + s.store_field("current_level_boost_count", current_level_boost_count_); + s.store_field("next_level_boost_count", next_level_boost_count_); + s.store_field("premium_member_count", premium_member_count_); + s.store_field("premium_member_percentage", premium_member_percentage_); + { s.store_vector_begin("prepaid_giveaways", prepaid_giveaways_.size()); for (const auto &_value : prepaid_giveaways_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } s.store_class_end(); } } -chatJoinRequest::chatJoinRequest() - : user_id_() +chatEvent::chatEvent() + : id_() , date_() - , bio_() + , member_id_() + , action_() {} -chatJoinRequest::chatJoinRequest(int53 user_id_, int32 date_, string const &bio_) - : user_id_(user_id_) +chatEvent::chatEvent(int64 id_, int32 date_, object_ptr &&member_id_, object_ptr &&action_) + : id_(id_) , date_(date_) - , bio_(bio_) + , member_id_(std::move(member_id_)) + , action_(std::move(action_)) {} -const std::int32_t chatJoinRequest::ID; +const std::int32_t chatEvent::ID; -void chatJoinRequest::store(TlStorerToString &s, const char *field_name) const { +void chatEvent::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatJoinRequest"); - s.store_field("user_id", user_id_); + s.store_class_begin(field_name, "chatEvent"); + s.store_field("id", id_); s.store_field("date", date_); - s.store_field("bio", bio_); + s.store_object_field("member_id", static_cast(member_id_.get())); + s.store_object_field("action", static_cast(action_.get())); s.store_class_end(); } } -chatJoinRequests::chatJoinRequests() - : total_count_() - , requests_() +chatEventMessageEdited::chatEventMessageEdited() + : old_message_() + , new_message_() {} -chatJoinRequests::chatJoinRequests(int32 total_count_, array> &&requests_) - : total_count_(total_count_) - , requests_(std::move(requests_)) +chatEventMessageEdited::chatEventMessageEdited(object_ptr &&old_message_, object_ptr &&new_message_) + : old_message_(std::move(old_message_)) + , new_message_(std::move(new_message_)) {} -const std::int32_t chatJoinRequests::ID; +const std::int32_t chatEventMessageEdited::ID; -void chatJoinRequests::store(TlStorerToString &s, const char *field_name) const { +void chatEventMessageEdited::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatJoinRequests"); - s.store_field("total_count", total_count_); - { s.store_vector_begin("requests", requests_.size()); for (const auto &_value : requests_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatEventMessageEdited"); + s.store_object_field("old_message", static_cast(old_message_.get())); + s.store_object_field("new_message", static_cast(new_message_.get())); s.store_class_end(); } } -chatJoinRequestsInfo::chatJoinRequestsInfo() - : total_count_() - , user_ids_() +chatEventMessageDeleted::chatEventMessageDeleted() + : message_() + , can_report_anti_spam_false_positive_() {} -chatJoinRequestsInfo::chatJoinRequestsInfo(int32 total_count_, array &&user_ids_) - : total_count_(total_count_) - , user_ids_(std::move(user_ids_)) +chatEventMessageDeleted::chatEventMessageDeleted(object_ptr &&message_, bool can_report_anti_spam_false_positive_) + : message_(std::move(message_)) + , can_report_anti_spam_false_positive_(can_report_anti_spam_false_positive_) {} -const std::int32_t chatJoinRequestsInfo::ID; +const std::int32_t chatEventMessageDeleted::ID; -void chatJoinRequestsInfo::store(TlStorerToString &s, const char *field_name) const { +void chatEventMessageDeleted::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatJoinRequestsInfo"); - s.store_field("total_count", total_count_); - { s.store_vector_begin("user_ids", user_ids_.size()); for (const auto &_value : user_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_begin(field_name, "chatEventMessageDeleted"); + s.store_object_field("message", static_cast(message_.get())); + s.store_field("can_report_anti_spam_false_positive", can_report_anti_spam_false_positive_); s.store_class_end(); } } -chatListMain::chatListMain() { -} +chatEventMessagePinned::chatEventMessagePinned() + : message_() +{} -const std::int32_t chatListMain::ID; +chatEventMessagePinned::chatEventMessagePinned(object_ptr &&message_) + : message_(std::move(message_)) +{} -void chatListMain::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventMessagePinned::ID; + +void chatEventMessagePinned::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatListMain"); + s.store_class_begin(field_name, "chatEventMessagePinned"); + s.store_object_field("message", static_cast(message_.get())); s.store_class_end(); } } -chatListArchive::chatListArchive() { -} +chatEventMessageUnpinned::chatEventMessageUnpinned() + : message_() +{} -const std::int32_t chatListArchive::ID; +chatEventMessageUnpinned::chatEventMessageUnpinned(object_ptr &&message_) + : message_(std::move(message_)) +{} -void chatListArchive::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventMessageUnpinned::ID; + +void chatEventMessageUnpinned::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatListArchive"); + s.store_class_begin(field_name, "chatEventMessageUnpinned"); + s.store_object_field("message", static_cast(message_.get())); s.store_class_end(); } } -chatListFolder::chatListFolder() - : chat_folder_id_() +chatEventPollStopped::chatEventPollStopped() + : message_() {} -chatListFolder::chatListFolder(int32 chat_folder_id_) - : chat_folder_id_(chat_folder_id_) +chatEventPollStopped::chatEventPollStopped(object_ptr &&message_) + : message_(std::move(message_)) {} -const std::int32_t chatListFolder::ID; +const std::int32_t chatEventPollStopped::ID; -void chatListFolder::store(TlStorerToString &s, const char *field_name) const { +void chatEventPollStopped::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatListFolder"); - s.store_field("chat_folder_id", chat_folder_id_); + s.store_class_begin(field_name, "chatEventPollStopped"); + s.store_object_field("message", static_cast(message_.get())); s.store_class_end(); } } -chatLists::chatLists() - : chat_lists_() +chatEventMemberJoined::chatEventMemberJoined() { +} + +const std::int32_t chatEventMemberJoined::ID; + +void chatEventMemberJoined::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatEventMemberJoined"); + s.store_class_end(); + } +} + +chatEventMemberJoinedByInviteLink::chatEventMemberJoinedByInviteLink() + : invite_link_() + , via_chat_folder_invite_link_() {} -chatLists::chatLists(array> &&chat_lists_) - : chat_lists_(std::move(chat_lists_)) +chatEventMemberJoinedByInviteLink::chatEventMemberJoinedByInviteLink(object_ptr &&invite_link_, bool via_chat_folder_invite_link_) + : invite_link_(std::move(invite_link_)) + , via_chat_folder_invite_link_(via_chat_folder_invite_link_) {} -const std::int32_t chatLists::ID; +const std::int32_t chatEventMemberJoinedByInviteLink::ID; -void chatLists::store(TlStorerToString &s, const char *field_name) const { +void chatEventMemberJoinedByInviteLink::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatLists"); - { s.store_vector_begin("chat_lists", chat_lists_.size()); for (const auto &_value : chat_lists_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatEventMemberJoinedByInviteLink"); + s.store_object_field("invite_link", static_cast(invite_link_.get())); + s.store_field("via_chat_folder_invite_link", via_chat_folder_invite_link_); s.store_class_end(); } } -chatLocation::chatLocation() - : location_() - , address_() +chatEventMemberJoinedByRequest::chatEventMemberJoinedByRequest() + : approver_user_id_() + , invite_link_() {} -chatLocation::chatLocation(object_ptr &&location_, string const &address_) - : location_(std::move(location_)) - , address_(address_) +chatEventMemberJoinedByRequest::chatEventMemberJoinedByRequest(int53 approver_user_id_, object_ptr &&invite_link_) + : approver_user_id_(approver_user_id_) + , invite_link_(std::move(invite_link_)) {} -const std::int32_t chatLocation::ID; +const std::int32_t chatEventMemberJoinedByRequest::ID; -void chatLocation::store(TlStorerToString &s, const char *field_name) const { +void chatEventMemberJoinedByRequest::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatLocation"); - s.store_object_field("location", static_cast(location_.get())); - s.store_field("address", address_); + s.store_class_begin(field_name, "chatEventMemberJoinedByRequest"); + s.store_field("approver_user_id", approver_user_id_); + s.store_object_field("invite_link", static_cast(invite_link_.get())); s.store_class_end(); } } -chatMember::chatMember() - : member_id_() - , inviter_user_id_() - , joined_chat_date_() +chatEventMemberInvited::chatEventMemberInvited() + : user_id_() , status_() {} -chatMember::chatMember(object_ptr &&member_id_, int53 inviter_user_id_, int32 joined_chat_date_, object_ptr &&status_) - : member_id_(std::move(member_id_)) - , inviter_user_id_(inviter_user_id_) - , joined_chat_date_(joined_chat_date_) +chatEventMemberInvited::chatEventMemberInvited(int53 user_id_, object_ptr &&status_) + : user_id_(user_id_) , status_(std::move(status_)) {} -const std::int32_t chatMember::ID; +const std::int32_t chatEventMemberInvited::ID; -void chatMember::store(TlStorerToString &s, const char *field_name) const { +void chatEventMemberInvited::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMember"); - s.store_object_field("member_id", static_cast(member_id_.get())); - s.store_field("inviter_user_id", inviter_user_id_); - s.store_field("joined_chat_date", joined_chat_date_); + s.store_class_begin(field_name, "chatEventMemberInvited"); + s.store_field("user_id", user_id_); s.store_object_field("status", static_cast(status_.get())); s.store_class_end(); } } -chatMemberStatusCreator::chatMemberStatusCreator() - : custom_title_() - , is_anonymous_() - , is_member_() +chatEventMemberLeft::chatEventMemberLeft() { +} + +const std::int32_t chatEventMemberLeft::ID; + +void chatEventMemberLeft::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatEventMemberLeft"); + s.store_class_end(); + } +} + +chatEventMemberPromoted::chatEventMemberPromoted() + : user_id_() + , old_status_() + , new_status_() {} -chatMemberStatusCreator::chatMemberStatusCreator(string const &custom_title_, bool is_anonymous_, bool is_member_) - : custom_title_(custom_title_) - , is_anonymous_(is_anonymous_) - , is_member_(is_member_) +chatEventMemberPromoted::chatEventMemberPromoted(int53 user_id_, object_ptr &&old_status_, object_ptr &&new_status_) + : user_id_(user_id_) + , old_status_(std::move(old_status_)) + , new_status_(std::move(new_status_)) {} -const std::int32_t chatMemberStatusCreator::ID; +const std::int32_t chatEventMemberPromoted::ID; -void chatMemberStatusCreator::store(TlStorerToString &s, const char *field_name) const { +void chatEventMemberPromoted::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMemberStatusCreator"); - s.store_field("custom_title", custom_title_); - s.store_field("is_anonymous", is_anonymous_); - s.store_field("is_member", is_member_); + s.store_class_begin(field_name, "chatEventMemberPromoted"); + s.store_field("user_id", user_id_); + s.store_object_field("old_status", static_cast(old_status_.get())); + s.store_object_field("new_status", static_cast(new_status_.get())); s.store_class_end(); } } -chatMemberStatusAdministrator::chatMemberStatusAdministrator() - : custom_title_() - , can_be_edited_() - , rights_() +chatEventMemberRestricted::chatEventMemberRestricted() + : member_id_() + , old_status_() + , new_status_() {} -chatMemberStatusAdministrator::chatMemberStatusAdministrator(string const &custom_title_, bool can_be_edited_, object_ptr &&rights_) - : custom_title_(custom_title_) - , can_be_edited_(can_be_edited_) - , rights_(std::move(rights_)) +chatEventMemberRestricted::chatEventMemberRestricted(object_ptr &&member_id_, object_ptr &&old_status_, object_ptr &&new_status_) + : member_id_(std::move(member_id_)) + , old_status_(std::move(old_status_)) + , new_status_(std::move(new_status_)) {} -const std::int32_t chatMemberStatusAdministrator::ID; +const std::int32_t chatEventMemberRestricted::ID; -void chatMemberStatusAdministrator::store(TlStorerToString &s, const char *field_name) const { +void chatEventMemberRestricted::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMemberStatusAdministrator"); - s.store_field("custom_title", custom_title_); - s.store_field("can_be_edited", can_be_edited_); - s.store_object_field("rights", static_cast(rights_.get())); + s.store_class_begin(field_name, "chatEventMemberRestricted"); + s.store_object_field("member_id", static_cast(member_id_.get())); + s.store_object_field("old_status", static_cast(old_status_.get())); + s.store_object_field("new_status", static_cast(new_status_.get())); s.store_class_end(); } } -chatMemberStatusMember::chatMemberStatusMember() { -} +chatEventMemberSubscriptionExtended::chatEventMemberSubscriptionExtended() + : user_id_() + , old_status_() + , new_status_() +{} -const std::int32_t chatMemberStatusMember::ID; +chatEventMemberSubscriptionExtended::chatEventMemberSubscriptionExtended(int53 user_id_, object_ptr &&old_status_, object_ptr &&new_status_) + : user_id_(user_id_) + , old_status_(std::move(old_status_)) + , new_status_(std::move(new_status_)) +{} -void chatMemberStatusMember::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventMemberSubscriptionExtended::ID; + +void chatEventMemberSubscriptionExtended::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMemberStatusMember"); + s.store_class_begin(field_name, "chatEventMemberSubscriptionExtended"); + s.store_field("user_id", user_id_); + s.store_object_field("old_status", static_cast(old_status_.get())); + s.store_object_field("new_status", static_cast(new_status_.get())); s.store_class_end(); } } -chatMemberStatusRestricted::chatMemberStatusRestricted() - : is_member_() - , restricted_until_date_() - , permissions_() +chatEventAvailableReactionsChanged::chatEventAvailableReactionsChanged() + : old_available_reactions_() + , new_available_reactions_() {} -chatMemberStatusRestricted::chatMemberStatusRestricted(bool is_member_, int32 restricted_until_date_, object_ptr &&permissions_) - : is_member_(is_member_) - , restricted_until_date_(restricted_until_date_) - , permissions_(std::move(permissions_)) +chatEventAvailableReactionsChanged::chatEventAvailableReactionsChanged(object_ptr &&old_available_reactions_, object_ptr &&new_available_reactions_) + : old_available_reactions_(std::move(old_available_reactions_)) + , new_available_reactions_(std::move(new_available_reactions_)) {} -const std::int32_t chatMemberStatusRestricted::ID; +const std::int32_t chatEventAvailableReactionsChanged::ID; -void chatMemberStatusRestricted::store(TlStorerToString &s, const char *field_name) const { +void chatEventAvailableReactionsChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMemberStatusRestricted"); - s.store_field("is_member", is_member_); - s.store_field("restricted_until_date", restricted_until_date_); - s.store_object_field("permissions", static_cast(permissions_.get())); + s.store_class_begin(field_name, "chatEventAvailableReactionsChanged"); + s.store_object_field("old_available_reactions", static_cast(old_available_reactions_.get())); + s.store_object_field("new_available_reactions", static_cast(new_available_reactions_.get())); s.store_class_end(); } } -chatMemberStatusLeft::chatMemberStatusLeft() { -} +chatEventBackgroundChanged::chatEventBackgroundChanged() + : old_background_() + , new_background_() +{} -const std::int32_t chatMemberStatusLeft::ID; +chatEventBackgroundChanged::chatEventBackgroundChanged(object_ptr &&old_background_, object_ptr &&new_background_) + : old_background_(std::move(old_background_)) + , new_background_(std::move(new_background_)) +{} -void chatMemberStatusLeft::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventBackgroundChanged::ID; + +void chatEventBackgroundChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMemberStatusLeft"); + s.store_class_begin(field_name, "chatEventBackgroundChanged"); + s.store_object_field("old_background", static_cast(old_background_.get())); + s.store_object_field("new_background", static_cast(new_background_.get())); s.store_class_end(); } } -chatMemberStatusBanned::chatMemberStatusBanned() - : banned_until_date_() +chatEventDescriptionChanged::chatEventDescriptionChanged() + : old_description_() + , new_description_() {} -chatMemberStatusBanned::chatMemberStatusBanned(int32 banned_until_date_) - : banned_until_date_(banned_until_date_) +chatEventDescriptionChanged::chatEventDescriptionChanged(string const &old_description_, string const &new_description_) + : old_description_(old_description_) + , new_description_(new_description_) {} -const std::int32_t chatMemberStatusBanned::ID; +const std::int32_t chatEventDescriptionChanged::ID; -void chatMemberStatusBanned::store(TlStorerToString &s, const char *field_name) const { +void chatEventDescriptionChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMemberStatusBanned"); - s.store_field("banned_until_date", banned_until_date_); + s.store_class_begin(field_name, "chatEventDescriptionChanged"); + s.store_field("old_description", old_description_); + s.store_field("new_description", new_description_); s.store_class_end(); } } -chatMembers::chatMembers() - : total_count_() - , members_() +chatEventEmojiStatusChanged::chatEventEmojiStatusChanged() + : old_emoji_status_() + , new_emoji_status_() {} -chatMembers::chatMembers(int32 total_count_, array> &&members_) - : total_count_(total_count_) - , members_(std::move(members_)) +chatEventEmojiStatusChanged::chatEventEmojiStatusChanged(object_ptr &&old_emoji_status_, object_ptr &&new_emoji_status_) + : old_emoji_status_(std::move(old_emoji_status_)) + , new_emoji_status_(std::move(new_emoji_status_)) {} -const std::int32_t chatMembers::ID; +const std::int32_t chatEventEmojiStatusChanged::ID; -void chatMembers::store(TlStorerToString &s, const char *field_name) const { +void chatEventEmojiStatusChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMembers"); - s.store_field("total_count", total_count_); - { s.store_vector_begin("members", members_.size()); for (const auto &_value : members_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatEventEmojiStatusChanged"); + s.store_object_field("old_emoji_status", static_cast(old_emoji_status_.get())); + s.store_object_field("new_emoji_status", static_cast(new_emoji_status_.get())); s.store_class_end(); } } -chatMembersFilterContacts::chatMembersFilterContacts() { -} +chatEventLinkedChatChanged::chatEventLinkedChatChanged() + : old_linked_chat_id_() + , new_linked_chat_id_() +{} -const std::int32_t chatMembersFilterContacts::ID; +chatEventLinkedChatChanged::chatEventLinkedChatChanged(int53 old_linked_chat_id_, int53 new_linked_chat_id_) + : old_linked_chat_id_(old_linked_chat_id_) + , new_linked_chat_id_(new_linked_chat_id_) +{} -void chatMembersFilterContacts::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventLinkedChatChanged::ID; + +void chatEventLinkedChatChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMembersFilterContacts"); + s.store_class_begin(field_name, "chatEventLinkedChatChanged"); + s.store_field("old_linked_chat_id", old_linked_chat_id_); + s.store_field("new_linked_chat_id", new_linked_chat_id_); s.store_class_end(); } } -chatMembersFilterAdministrators::chatMembersFilterAdministrators() { -} +chatEventLocationChanged::chatEventLocationChanged() + : old_location_() + , new_location_() +{} -const std::int32_t chatMembersFilterAdministrators::ID; +chatEventLocationChanged::chatEventLocationChanged(object_ptr &&old_location_, object_ptr &&new_location_) + : old_location_(std::move(old_location_)) + , new_location_(std::move(new_location_)) +{} -void chatMembersFilterAdministrators::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventLocationChanged::ID; + +void chatEventLocationChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMembersFilterAdministrators"); + s.store_class_begin(field_name, "chatEventLocationChanged"); + s.store_object_field("old_location", static_cast(old_location_.get())); + s.store_object_field("new_location", static_cast(new_location_.get())); s.store_class_end(); } } -chatMembersFilterMembers::chatMembersFilterMembers() { -} +chatEventMessageAutoDeleteTimeChanged::chatEventMessageAutoDeleteTimeChanged() + : old_message_auto_delete_time_() + , new_message_auto_delete_time_() +{} -const std::int32_t chatMembersFilterMembers::ID; +chatEventMessageAutoDeleteTimeChanged::chatEventMessageAutoDeleteTimeChanged(int32 old_message_auto_delete_time_, int32 new_message_auto_delete_time_) + : old_message_auto_delete_time_(old_message_auto_delete_time_) + , new_message_auto_delete_time_(new_message_auto_delete_time_) +{} -void chatMembersFilterMembers::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventMessageAutoDeleteTimeChanged::ID; + +void chatEventMessageAutoDeleteTimeChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMembersFilterMembers"); + s.store_class_begin(field_name, "chatEventMessageAutoDeleteTimeChanged"); + s.store_field("old_message_auto_delete_time", old_message_auto_delete_time_); + s.store_field("new_message_auto_delete_time", new_message_auto_delete_time_); s.store_class_end(); } } -chatMembersFilterMention::chatMembersFilterMention() - : message_thread_id_() +chatEventPermissionsChanged::chatEventPermissionsChanged() + : old_permissions_() + , new_permissions_() {} -chatMembersFilterMention::chatMembersFilterMention(int53 message_thread_id_) - : message_thread_id_(message_thread_id_) +chatEventPermissionsChanged::chatEventPermissionsChanged(object_ptr &&old_permissions_, object_ptr &&new_permissions_) + : old_permissions_(std::move(old_permissions_)) + , new_permissions_(std::move(new_permissions_)) {} -const std::int32_t chatMembersFilterMention::ID; +const std::int32_t chatEventPermissionsChanged::ID; -void chatMembersFilterMention::store(TlStorerToString &s, const char *field_name) const { +void chatEventPermissionsChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMembersFilterMention"); - s.store_field("message_thread_id", message_thread_id_); + s.store_class_begin(field_name, "chatEventPermissionsChanged"); + s.store_object_field("old_permissions", static_cast(old_permissions_.get())); + s.store_object_field("new_permissions", static_cast(new_permissions_.get())); s.store_class_end(); } } -chatMembersFilterRestricted::chatMembersFilterRestricted() { -} +chatEventPhotoChanged::chatEventPhotoChanged() + : old_photo_() + , new_photo_() +{} -const std::int32_t chatMembersFilterRestricted::ID; +chatEventPhotoChanged::chatEventPhotoChanged(object_ptr &&old_photo_, object_ptr &&new_photo_) + : old_photo_(std::move(old_photo_)) + , new_photo_(std::move(new_photo_)) +{} -void chatMembersFilterRestricted::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventPhotoChanged::ID; + +void chatEventPhotoChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMembersFilterRestricted"); + s.store_class_begin(field_name, "chatEventPhotoChanged"); + s.store_object_field("old_photo", static_cast(old_photo_.get())); + s.store_object_field("new_photo", static_cast(new_photo_.get())); s.store_class_end(); } } -chatMembersFilterBanned::chatMembersFilterBanned() { -} +chatEventSlowModeDelayChanged::chatEventSlowModeDelayChanged() + : old_slow_mode_delay_() + , new_slow_mode_delay_() +{} -const std::int32_t chatMembersFilterBanned::ID; +chatEventSlowModeDelayChanged::chatEventSlowModeDelayChanged(int32 old_slow_mode_delay_, int32 new_slow_mode_delay_) + : old_slow_mode_delay_(old_slow_mode_delay_) + , new_slow_mode_delay_(new_slow_mode_delay_) +{} -void chatMembersFilterBanned::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventSlowModeDelayChanged::ID; + +void chatEventSlowModeDelayChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMembersFilterBanned"); + s.store_class_begin(field_name, "chatEventSlowModeDelayChanged"); + s.store_field("old_slow_mode_delay", old_slow_mode_delay_); + s.store_field("new_slow_mode_delay", new_slow_mode_delay_); s.store_class_end(); } } -chatMembersFilterBots::chatMembersFilterBots() { -} +chatEventStickerSetChanged::chatEventStickerSetChanged() + : old_sticker_set_id_() + , new_sticker_set_id_() +{} -const std::int32_t chatMembersFilterBots::ID; +chatEventStickerSetChanged::chatEventStickerSetChanged(int64 old_sticker_set_id_, int64 new_sticker_set_id_) + : old_sticker_set_id_(old_sticker_set_id_) + , new_sticker_set_id_(new_sticker_set_id_) +{} -void chatMembersFilterBots::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventStickerSetChanged::ID; + +void chatEventStickerSetChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMembersFilterBots"); + s.store_class_begin(field_name, "chatEventStickerSetChanged"); + s.store_field("old_sticker_set_id", old_sticker_set_id_); + s.store_field("new_sticker_set_id", new_sticker_set_id_); s.store_class_end(); } } -chatMessageSender::chatMessageSender() - : sender_() - , needs_premium_() +chatEventCustomEmojiStickerSetChanged::chatEventCustomEmojiStickerSetChanged() + : old_sticker_set_id_() + , new_sticker_set_id_() {} -chatMessageSender::chatMessageSender(object_ptr &&sender_, bool needs_premium_) - : sender_(std::move(sender_)) - , needs_premium_(needs_premium_) +chatEventCustomEmojiStickerSetChanged::chatEventCustomEmojiStickerSetChanged(int64 old_sticker_set_id_, int64 new_sticker_set_id_) + : old_sticker_set_id_(old_sticker_set_id_) + , new_sticker_set_id_(new_sticker_set_id_) {} -const std::int32_t chatMessageSender::ID; +const std::int32_t chatEventCustomEmojiStickerSetChanged::ID; -void chatMessageSender::store(TlStorerToString &s, const char *field_name) const { +void chatEventCustomEmojiStickerSetChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMessageSender"); - s.store_object_field("sender", static_cast(sender_.get())); - s.store_field("needs_premium", needs_premium_); + s.store_class_begin(field_name, "chatEventCustomEmojiStickerSetChanged"); + s.store_field("old_sticker_set_id", old_sticker_set_id_); + s.store_field("new_sticker_set_id", new_sticker_set_id_); s.store_class_end(); } } -chatMessageSenders::chatMessageSenders() - : senders_() +chatEventTitleChanged::chatEventTitleChanged() + : old_title_() + , new_title_() {} -chatMessageSenders::chatMessageSenders(array> &&senders_) - : senders_(std::move(senders_)) +chatEventTitleChanged::chatEventTitleChanged(string const &old_title_, string const &new_title_) + : old_title_(old_title_) + , new_title_(new_title_) {} -const std::int32_t chatMessageSenders::ID; +const std::int32_t chatEventTitleChanged::ID; -void chatMessageSenders::store(TlStorerToString &s, const char *field_name) const { +void chatEventTitleChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatMessageSenders"); - { s.store_vector_begin("senders", senders_.size()); for (const auto &_value : senders_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatEventTitleChanged"); + s.store_field("old_title", old_title_); + s.store_field("new_title", new_title_); s.store_class_end(); } } -chatNearby::chatNearby() - : chat_id_() - , distance_() +chatEventUsernameChanged::chatEventUsernameChanged() + : old_username_() + , new_username_() {} -chatNearby::chatNearby(int53 chat_id_, int32 distance_) - : chat_id_(chat_id_) - , distance_(distance_) +chatEventUsernameChanged::chatEventUsernameChanged(string const &old_username_, string const &new_username_) + : old_username_(old_username_) + , new_username_(new_username_) {} -const std::int32_t chatNearby::ID; +const std::int32_t chatEventUsernameChanged::ID; -void chatNearby::store(TlStorerToString &s, const char *field_name) const { +void chatEventUsernameChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatNearby"); - s.store_field("chat_id", chat_id_); - s.store_field("distance", distance_); + s.store_class_begin(field_name, "chatEventUsernameChanged"); + s.store_field("old_username", old_username_); + s.store_field("new_username", new_username_); s.store_class_end(); } } -chatNotificationSettings::chatNotificationSettings() - : use_default_mute_for_() - , mute_for_() - , use_default_sound_() - , sound_id_() - , use_default_show_preview_() - , show_preview_() - , use_default_disable_pinned_message_notifications_() - , disable_pinned_message_notifications_() - , use_default_disable_mention_notifications_() - , disable_mention_notifications_() +chatEventActiveUsernamesChanged::chatEventActiveUsernamesChanged() + : old_usernames_() + , new_usernames_() {} -chatNotificationSettings::chatNotificationSettings(bool use_default_mute_for_, int32 mute_for_, bool use_default_sound_, int64 sound_id_, bool use_default_show_preview_, bool show_preview_, bool use_default_disable_pinned_message_notifications_, bool disable_pinned_message_notifications_, bool use_default_disable_mention_notifications_, bool disable_mention_notifications_) - : use_default_mute_for_(use_default_mute_for_) - , mute_for_(mute_for_) - , use_default_sound_(use_default_sound_) - , sound_id_(sound_id_) - , use_default_show_preview_(use_default_show_preview_) - , show_preview_(show_preview_) - , use_default_disable_pinned_message_notifications_(use_default_disable_pinned_message_notifications_) - , disable_pinned_message_notifications_(disable_pinned_message_notifications_) - , use_default_disable_mention_notifications_(use_default_disable_mention_notifications_) - , disable_mention_notifications_(disable_mention_notifications_) +chatEventActiveUsernamesChanged::chatEventActiveUsernamesChanged(array &&old_usernames_, array &&new_usernames_) + : old_usernames_(std::move(old_usernames_)) + , new_usernames_(std::move(new_usernames_)) {} -const std::int32_t chatNotificationSettings::ID; +const std::int32_t chatEventActiveUsernamesChanged::ID; -void chatNotificationSettings::store(TlStorerToString &s, const char *field_name) const { +void chatEventActiveUsernamesChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatNotificationSettings"); - s.store_field("use_default_mute_for", use_default_mute_for_); - s.store_field("mute_for", mute_for_); - s.store_field("use_default_sound", use_default_sound_); - s.store_field("sound_id", sound_id_); - s.store_field("use_default_show_preview", use_default_show_preview_); - s.store_field("show_preview", show_preview_); - s.store_field("use_default_disable_pinned_message_notifications", use_default_disable_pinned_message_notifications_); - s.store_field("disable_pinned_message_notifications", disable_pinned_message_notifications_); - s.store_field("use_default_disable_mention_notifications", use_default_disable_mention_notifications_); - s.store_field("disable_mention_notifications", disable_mention_notifications_); + s.store_class_begin(field_name, "chatEventActiveUsernamesChanged"); + { s.store_vector_begin("old_usernames", old_usernames_.size()); for (const auto &_value : old_usernames_) { s.store_field("", _value); } s.store_class_end(); } + { s.store_vector_begin("new_usernames", new_usernames_.size()); for (const auto &_value : new_usernames_) { s.store_field("", _value); } s.store_class_end(); } s.store_class_end(); } } -chatPermissions::chatPermissions() - : can_send_basic_messages_() - , can_send_audios_() - , can_send_documents_() - , can_send_photos_() - , can_send_videos_() - , can_send_video_notes_() - , can_send_voice_notes_() - , can_send_polls_() - , can_send_other_messages_() - , can_add_web_page_previews_() - , can_change_info_() - , can_invite_users_() - , can_pin_messages_() - , can_manage_topics_() +chatEventAccentColorChanged::chatEventAccentColorChanged() + : old_accent_color_id_() + , old_background_custom_emoji_id_() + , new_accent_color_id_() + , new_background_custom_emoji_id_() {} -chatPermissions::chatPermissions(bool can_send_basic_messages_, bool can_send_audios_, bool can_send_documents_, bool can_send_photos_, bool can_send_videos_, bool can_send_video_notes_, bool can_send_voice_notes_, bool can_send_polls_, bool can_send_other_messages_, bool can_add_web_page_previews_, bool can_change_info_, bool can_invite_users_, bool can_pin_messages_, bool can_manage_topics_) - : can_send_basic_messages_(can_send_basic_messages_) - , can_send_audios_(can_send_audios_) - , can_send_documents_(can_send_documents_) - , can_send_photos_(can_send_photos_) - , can_send_videos_(can_send_videos_) - , can_send_video_notes_(can_send_video_notes_) - , can_send_voice_notes_(can_send_voice_notes_) - , can_send_polls_(can_send_polls_) - , can_send_other_messages_(can_send_other_messages_) - , can_add_web_page_previews_(can_add_web_page_previews_) - , can_change_info_(can_change_info_) - , can_invite_users_(can_invite_users_) - , can_pin_messages_(can_pin_messages_) - , can_manage_topics_(can_manage_topics_) +chatEventAccentColorChanged::chatEventAccentColorChanged(int32 old_accent_color_id_, int64 old_background_custom_emoji_id_, int32 new_accent_color_id_, int64 new_background_custom_emoji_id_) + : old_accent_color_id_(old_accent_color_id_) + , old_background_custom_emoji_id_(old_background_custom_emoji_id_) + , new_accent_color_id_(new_accent_color_id_) + , new_background_custom_emoji_id_(new_background_custom_emoji_id_) {} -const std::int32_t chatPermissions::ID; +const std::int32_t chatEventAccentColorChanged::ID; -void chatPermissions::store(TlStorerToString &s, const char *field_name) const { +void chatEventAccentColorChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatPermissions"); - s.store_field("can_send_basic_messages", can_send_basic_messages_); - s.store_field("can_send_audios", can_send_audios_); - s.store_field("can_send_documents", can_send_documents_); - s.store_field("can_send_photos", can_send_photos_); - s.store_field("can_send_videos", can_send_videos_); - s.store_field("can_send_video_notes", can_send_video_notes_); - s.store_field("can_send_voice_notes", can_send_voice_notes_); - s.store_field("can_send_polls", can_send_polls_); - s.store_field("can_send_other_messages", can_send_other_messages_); - s.store_field("can_add_web_page_previews", can_add_web_page_previews_); - s.store_field("can_change_info", can_change_info_); - s.store_field("can_invite_users", can_invite_users_); - s.store_field("can_pin_messages", can_pin_messages_); - s.store_field("can_manage_topics", can_manage_topics_); + s.store_class_begin(field_name, "chatEventAccentColorChanged"); + s.store_field("old_accent_color_id", old_accent_color_id_); + s.store_field("old_background_custom_emoji_id", old_background_custom_emoji_id_); + s.store_field("new_accent_color_id", new_accent_color_id_); + s.store_field("new_background_custom_emoji_id", new_background_custom_emoji_id_); s.store_class_end(); } } -chatPhoto::chatPhoto() - : id_() - , added_date_() - , minithumbnail_() - , sizes_() - , animation_() - , small_animation_() - , sticker_() +chatEventProfileAccentColorChanged::chatEventProfileAccentColorChanged() + : old_profile_accent_color_id_() + , old_profile_background_custom_emoji_id_() + , new_profile_accent_color_id_() + , new_profile_background_custom_emoji_id_() {} -chatPhoto::chatPhoto(int64 id_, int32 added_date_, object_ptr &&minithumbnail_, array> &&sizes_, object_ptr &&animation_, object_ptr &&small_animation_, object_ptr &&sticker_) - : id_(id_) - , added_date_(added_date_) - , minithumbnail_(std::move(minithumbnail_)) - , sizes_(std::move(sizes_)) - , animation_(std::move(animation_)) - , small_animation_(std::move(small_animation_)) - , sticker_(std::move(sticker_)) +chatEventProfileAccentColorChanged::chatEventProfileAccentColorChanged(int32 old_profile_accent_color_id_, int64 old_profile_background_custom_emoji_id_, int32 new_profile_accent_color_id_, int64 new_profile_background_custom_emoji_id_) + : old_profile_accent_color_id_(old_profile_accent_color_id_) + , old_profile_background_custom_emoji_id_(old_profile_background_custom_emoji_id_) + , new_profile_accent_color_id_(new_profile_accent_color_id_) + , new_profile_background_custom_emoji_id_(new_profile_background_custom_emoji_id_) {} -const std::int32_t chatPhoto::ID; +const std::int32_t chatEventProfileAccentColorChanged::ID; -void chatPhoto::store(TlStorerToString &s, const char *field_name) const { +void chatEventProfileAccentColorChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatPhoto"); - s.store_field("id", id_); - s.store_field("added_date", added_date_); - s.store_object_field("minithumbnail", static_cast(minithumbnail_.get())); - { s.store_vector_begin("sizes", sizes_.size()); for (const auto &_value : sizes_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } - s.store_object_field("animation", static_cast(animation_.get())); - s.store_object_field("small_animation", static_cast(small_animation_.get())); - s.store_object_field("sticker", static_cast(sticker_.get())); + s.store_class_begin(field_name, "chatEventProfileAccentColorChanged"); + s.store_field("old_profile_accent_color_id", old_profile_accent_color_id_); + s.store_field("old_profile_background_custom_emoji_id", old_profile_background_custom_emoji_id_); + s.store_field("new_profile_accent_color_id", new_profile_accent_color_id_); + s.store_field("new_profile_background_custom_emoji_id", new_profile_background_custom_emoji_id_); s.store_class_end(); } } -chatPhotoInfo::chatPhotoInfo() - : small_() - , big_() - , minithumbnail_() - , has_animation_() - , is_personal_() +chatEventHasProtectedContentToggled::chatEventHasProtectedContentToggled() + : has_protected_content_() {} -chatPhotoInfo::chatPhotoInfo(object_ptr &&small_, object_ptr &&big_, object_ptr &&minithumbnail_, bool has_animation_, bool is_personal_) - : small_(std::move(small_)) - , big_(std::move(big_)) - , minithumbnail_(std::move(minithumbnail_)) - , has_animation_(has_animation_) - , is_personal_(is_personal_) +chatEventHasProtectedContentToggled::chatEventHasProtectedContentToggled(bool has_protected_content_) + : has_protected_content_(has_protected_content_) {} -const std::int32_t chatPhotoInfo::ID; +const std::int32_t chatEventHasProtectedContentToggled::ID; -void chatPhotoInfo::store(TlStorerToString &s, const char *field_name) const { +void chatEventHasProtectedContentToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatPhotoInfo"); - s.store_object_field("small", static_cast(small_.get())); - s.store_object_field("big", static_cast(big_.get())); - s.store_object_field("minithumbnail", static_cast(minithumbnail_.get())); - s.store_field("has_animation", has_animation_); - s.store_field("is_personal", is_personal_); + s.store_class_begin(field_name, "chatEventHasProtectedContentToggled"); + s.store_field("has_protected_content", has_protected_content_); s.store_class_end(); } } -chatPhotoSticker::chatPhotoSticker() - : type_() - , background_fill_() +chatEventInvitesToggled::chatEventInvitesToggled() + : can_invite_users_() {} -chatPhotoSticker::chatPhotoSticker(object_ptr &&type_, object_ptr &&background_fill_) - : type_(std::move(type_)) - , background_fill_(std::move(background_fill_)) +chatEventInvitesToggled::chatEventInvitesToggled(bool can_invite_users_) + : can_invite_users_(can_invite_users_) {} -const std::int32_t chatPhotoSticker::ID; +const std::int32_t chatEventInvitesToggled::ID; -void chatPhotoSticker::store(TlStorerToString &s, const char *field_name) const { +void chatEventInvitesToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatPhotoSticker"); - s.store_object_field("type", static_cast(type_.get())); - s.store_object_field("background_fill", static_cast(background_fill_.get())); + s.store_class_begin(field_name, "chatEventInvitesToggled"); + s.store_field("can_invite_users", can_invite_users_); s.store_class_end(); } } -chatPhotoStickerTypeRegularOrMask::chatPhotoStickerTypeRegularOrMask() - : sticker_set_id_() - , sticker_id_() +chatEventIsAllHistoryAvailableToggled::chatEventIsAllHistoryAvailableToggled() + : is_all_history_available_() {} -chatPhotoStickerTypeRegularOrMask::chatPhotoStickerTypeRegularOrMask(int64 sticker_set_id_, int64 sticker_id_) - : sticker_set_id_(sticker_set_id_) - , sticker_id_(sticker_id_) +chatEventIsAllHistoryAvailableToggled::chatEventIsAllHistoryAvailableToggled(bool is_all_history_available_) + : is_all_history_available_(is_all_history_available_) {} -const std::int32_t chatPhotoStickerTypeRegularOrMask::ID; +const std::int32_t chatEventIsAllHistoryAvailableToggled::ID; -void chatPhotoStickerTypeRegularOrMask::store(TlStorerToString &s, const char *field_name) const { +void chatEventIsAllHistoryAvailableToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatPhotoStickerTypeRegularOrMask"); - s.store_field("sticker_set_id", sticker_set_id_); - s.store_field("sticker_id", sticker_id_); + s.store_class_begin(field_name, "chatEventIsAllHistoryAvailableToggled"); + s.store_field("is_all_history_available", is_all_history_available_); s.store_class_end(); } } -chatPhotoStickerTypeCustomEmoji::chatPhotoStickerTypeCustomEmoji() - : custom_emoji_id_() +chatEventHasAggressiveAntiSpamEnabledToggled::chatEventHasAggressiveAntiSpamEnabledToggled() + : has_aggressive_anti_spam_enabled_() {} -chatPhotoStickerTypeCustomEmoji::chatPhotoStickerTypeCustomEmoji(int64 custom_emoji_id_) - : custom_emoji_id_(custom_emoji_id_) +chatEventHasAggressiveAntiSpamEnabledToggled::chatEventHasAggressiveAntiSpamEnabledToggled(bool has_aggressive_anti_spam_enabled_) + : has_aggressive_anti_spam_enabled_(has_aggressive_anti_spam_enabled_) {} -const std::int32_t chatPhotoStickerTypeCustomEmoji::ID; +const std::int32_t chatEventHasAggressiveAntiSpamEnabledToggled::ID; -void chatPhotoStickerTypeCustomEmoji::store(TlStorerToString &s, const char *field_name) const { +void chatEventHasAggressiveAntiSpamEnabledToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatPhotoStickerTypeCustomEmoji"); - s.store_field("custom_emoji_id", custom_emoji_id_); + s.store_class_begin(field_name, "chatEventHasAggressiveAntiSpamEnabledToggled"); + s.store_field("has_aggressive_anti_spam_enabled", has_aggressive_anti_spam_enabled_); s.store_class_end(); } } -chatPhotos::chatPhotos() - : total_count_() - , photos_() +chatEventSignMessagesToggled::chatEventSignMessagesToggled() + : sign_messages_() {} -chatPhotos::chatPhotos(int32 total_count_, array> &&photos_) - : total_count_(total_count_) - , photos_(std::move(photos_)) +chatEventSignMessagesToggled::chatEventSignMessagesToggled(bool sign_messages_) + : sign_messages_(sign_messages_) {} -const std::int32_t chatPhotos::ID; +const std::int32_t chatEventSignMessagesToggled::ID; -void chatPhotos::store(TlStorerToString &s, const char *field_name) const { +void chatEventSignMessagesToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatPhotos"); - s.store_field("total_count", total_count_); - { s.store_vector_begin("photos", photos_.size()); for (const auto &_value : photos_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatEventSignMessagesToggled"); + s.store_field("sign_messages", sign_messages_); s.store_class_end(); } } -chatPosition::chatPosition() - : list_() - , order_() - , is_pinned_() - , source_() +chatEventShowMessageSenderToggled::chatEventShowMessageSenderToggled() + : show_message_sender_() {} -chatPosition::chatPosition(object_ptr &&list_, int64 order_, bool is_pinned_, object_ptr &&source_) - : list_(std::move(list_)) - , order_(order_) - , is_pinned_(is_pinned_) - , source_(std::move(source_)) +chatEventShowMessageSenderToggled::chatEventShowMessageSenderToggled(bool show_message_sender_) + : show_message_sender_(show_message_sender_) {} -const std::int32_t chatPosition::ID; +const std::int32_t chatEventShowMessageSenderToggled::ID; -void chatPosition::store(TlStorerToString &s, const char *field_name) const { +void chatEventShowMessageSenderToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatPosition"); - s.store_object_field("list", static_cast(list_.get())); - s.store_field("order", order_); - s.store_field("is_pinned", is_pinned_); - s.store_object_field("source", static_cast(source_.get())); + s.store_class_begin(field_name, "chatEventShowMessageSenderToggled"); + s.store_field("show_message_sender", show_message_sender_); s.store_class_end(); } } -chatReportReasonSpam::chatReportReasonSpam() { -} - -const std::int32_t chatReportReasonSpam::ID; - -void chatReportReasonSpam::store(TlStorerToString &s, const char *field_name) const { - if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonSpam"); - s.store_class_end(); - } -} +chatEventInviteLinkEdited::chatEventInviteLinkEdited() + : old_invite_link_() + , new_invite_link_() +{} -chatReportReasonViolence::chatReportReasonViolence() { -} +chatEventInviteLinkEdited::chatEventInviteLinkEdited(object_ptr &&old_invite_link_, object_ptr &&new_invite_link_) + : old_invite_link_(std::move(old_invite_link_)) + , new_invite_link_(std::move(new_invite_link_)) +{} -const std::int32_t chatReportReasonViolence::ID; +const std::int32_t chatEventInviteLinkEdited::ID; -void chatReportReasonViolence::store(TlStorerToString &s, const char *field_name) const { +void chatEventInviteLinkEdited::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonViolence"); + s.store_class_begin(field_name, "chatEventInviteLinkEdited"); + s.store_object_field("old_invite_link", static_cast(old_invite_link_.get())); + s.store_object_field("new_invite_link", static_cast(new_invite_link_.get())); s.store_class_end(); } } -chatReportReasonPornography::chatReportReasonPornography() { -} - -const std::int32_t chatReportReasonPornography::ID; - -void chatReportReasonPornography::store(TlStorerToString &s, const char *field_name) const { - if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonPornography"); - s.store_class_end(); - } -} +chatEventInviteLinkRevoked::chatEventInviteLinkRevoked() + : invite_link_() +{} -chatReportReasonChildAbuse::chatReportReasonChildAbuse() { -} +chatEventInviteLinkRevoked::chatEventInviteLinkRevoked(object_ptr &&invite_link_) + : invite_link_(std::move(invite_link_)) +{} -const std::int32_t chatReportReasonChildAbuse::ID; +const std::int32_t chatEventInviteLinkRevoked::ID; -void chatReportReasonChildAbuse::store(TlStorerToString &s, const char *field_name) const { +void chatEventInviteLinkRevoked::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonChildAbuse"); + s.store_class_begin(field_name, "chatEventInviteLinkRevoked"); + s.store_object_field("invite_link", static_cast(invite_link_.get())); s.store_class_end(); } } -chatReportReasonCopyright::chatReportReasonCopyright() { -} - -const std::int32_t chatReportReasonCopyright::ID; - -void chatReportReasonCopyright::store(TlStorerToString &s, const char *field_name) const { - if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonCopyright"); - s.store_class_end(); - } -} +chatEventInviteLinkDeleted::chatEventInviteLinkDeleted() + : invite_link_() +{} -chatReportReasonUnrelatedLocation::chatReportReasonUnrelatedLocation() { -} +chatEventInviteLinkDeleted::chatEventInviteLinkDeleted(object_ptr &&invite_link_) + : invite_link_(std::move(invite_link_)) +{} -const std::int32_t chatReportReasonUnrelatedLocation::ID; +const std::int32_t chatEventInviteLinkDeleted::ID; -void chatReportReasonUnrelatedLocation::store(TlStorerToString &s, const char *field_name) const { +void chatEventInviteLinkDeleted::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonUnrelatedLocation"); + s.store_class_begin(field_name, "chatEventInviteLinkDeleted"); + s.store_object_field("invite_link", static_cast(invite_link_.get())); s.store_class_end(); } } -chatReportReasonFake::chatReportReasonFake() { -} - -const std::int32_t chatReportReasonFake::ID; - -void chatReportReasonFake::store(TlStorerToString &s, const char *field_name) const { - if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonFake"); - s.store_class_end(); - } -} +chatEventVideoChatCreated::chatEventVideoChatCreated() + : group_call_id_() +{} -chatReportReasonIllegalDrugs::chatReportReasonIllegalDrugs() { -} +chatEventVideoChatCreated::chatEventVideoChatCreated(int32 group_call_id_) + : group_call_id_(group_call_id_) +{} -const std::int32_t chatReportReasonIllegalDrugs::ID; +const std::int32_t chatEventVideoChatCreated::ID; -void chatReportReasonIllegalDrugs::store(TlStorerToString &s, const char *field_name) const { +void chatEventVideoChatCreated::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonIllegalDrugs"); + s.store_class_begin(field_name, "chatEventVideoChatCreated"); + s.store_field("group_call_id", group_call_id_); s.store_class_end(); } } -chatReportReasonPersonalDetails::chatReportReasonPersonalDetails() { -} - -const std::int32_t chatReportReasonPersonalDetails::ID; - -void chatReportReasonPersonalDetails::store(TlStorerToString &s, const char *field_name) const { - if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonPersonalDetails"); - s.store_class_end(); - } -} +chatEventVideoChatEnded::chatEventVideoChatEnded() + : group_call_id_() +{} -chatReportReasonCustom::chatReportReasonCustom() { -} +chatEventVideoChatEnded::chatEventVideoChatEnded(int32 group_call_id_) + : group_call_id_(group_call_id_) +{} -const std::int32_t chatReportReasonCustom::ID; +const std::int32_t chatEventVideoChatEnded::ID; -void chatReportReasonCustom::store(TlStorerToString &s, const char *field_name) const { +void chatEventVideoChatEnded::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatReportReasonCustom"); + s.store_class_begin(field_name, "chatEventVideoChatEnded"); + s.store_field("group_call_id", group_call_id_); s.store_class_end(); } } -chatSourceMtprotoProxy::chatSourceMtprotoProxy() { -} +chatEventVideoChatMuteNewParticipantsToggled::chatEventVideoChatMuteNewParticipantsToggled() + : mute_new_participants_() +{} -const std::int32_t chatSourceMtprotoProxy::ID; +chatEventVideoChatMuteNewParticipantsToggled::chatEventVideoChatMuteNewParticipantsToggled(bool mute_new_participants_) + : mute_new_participants_(mute_new_participants_) +{} -void chatSourceMtprotoProxy::store(TlStorerToString &s, const char *field_name) const { +const std::int32_t chatEventVideoChatMuteNewParticipantsToggled::ID; + +void chatEventVideoChatMuteNewParticipantsToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatSourceMtprotoProxy"); + s.store_class_begin(field_name, "chatEventVideoChatMuteNewParticipantsToggled"); + s.store_field("mute_new_participants", mute_new_participants_); s.store_class_end(); } } -chatSourcePublicServiceAnnouncement::chatSourcePublicServiceAnnouncement() - : type_() - , text_() +chatEventVideoChatParticipantIsMutedToggled::chatEventVideoChatParticipantIsMutedToggled() + : participant_id_() + , is_muted_() {} -chatSourcePublicServiceAnnouncement::chatSourcePublicServiceAnnouncement(string const &type_, string const &text_) - : type_(type_) - , text_(text_) +chatEventVideoChatParticipantIsMutedToggled::chatEventVideoChatParticipantIsMutedToggled(object_ptr &&participant_id_, bool is_muted_) + : participant_id_(std::move(participant_id_)) + , is_muted_(is_muted_) {} -const std::int32_t chatSourcePublicServiceAnnouncement::ID; +const std::int32_t chatEventVideoChatParticipantIsMutedToggled::ID; -void chatSourcePublicServiceAnnouncement::store(TlStorerToString &s, const char *field_name) const { +void chatEventVideoChatParticipantIsMutedToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatSourcePublicServiceAnnouncement"); - s.store_field("type", type_); - s.store_field("text", text_); + s.store_class_begin(field_name, "chatEventVideoChatParticipantIsMutedToggled"); + s.store_object_field("participant_id", static_cast(participant_id_.get())); + s.store_field("is_muted", is_muted_); s.store_class_end(); } } -chatStatisticsSupergroup::chatStatisticsSupergroup() - : period_() - , member_count_() - , message_count_() - , viewer_count_() - , sender_count_() - , member_count_graph_() - , join_graph_() - , join_by_source_graph_() - , language_graph_() - , message_content_graph_() - , action_graph_() - , day_graph_() - , week_graph_() - , top_senders_() - , top_administrators_() - , top_inviters_() +chatEventVideoChatParticipantVolumeLevelChanged::chatEventVideoChatParticipantVolumeLevelChanged() + : participant_id_() + , volume_level_() {} -chatStatisticsSupergroup::chatStatisticsSupergroup(object_ptr &&period_, object_ptr &&member_count_, object_ptr &&message_count_, object_ptr &&viewer_count_, object_ptr &&sender_count_, object_ptr &&member_count_graph_, object_ptr &&join_graph_, object_ptr &&join_by_source_graph_, object_ptr &&language_graph_, object_ptr &&message_content_graph_, object_ptr &&action_graph_, object_ptr &&day_graph_, object_ptr &&week_graph_, array> &&top_senders_, array> &&top_administrators_, array> &&top_inviters_) - : period_(std::move(period_)) - , member_count_(std::move(member_count_)) - , message_count_(std::move(message_count_)) - , viewer_count_(std::move(viewer_count_)) - , sender_count_(std::move(sender_count_)) - , member_count_graph_(std::move(member_count_graph_)) - , join_graph_(std::move(join_graph_)) - , join_by_source_graph_(std::move(join_by_source_graph_)) - , language_graph_(std::move(language_graph_)) - , message_content_graph_(std::move(message_content_graph_)) - , action_graph_(std::move(action_graph_)) - , day_graph_(std::move(day_graph_)) - , week_graph_(std::move(week_graph_)) - , top_senders_(std::move(top_senders_)) - , top_administrators_(std::move(top_administrators_)) - , top_inviters_(std::move(top_inviters_)) +chatEventVideoChatParticipantVolumeLevelChanged::chatEventVideoChatParticipantVolumeLevelChanged(object_ptr &&participant_id_, int32 volume_level_) + : participant_id_(std::move(participant_id_)) + , volume_level_(volume_level_) {} -const std::int32_t chatStatisticsSupergroup::ID; +const std::int32_t chatEventVideoChatParticipantVolumeLevelChanged::ID; -void chatStatisticsSupergroup::store(TlStorerToString &s, const char *field_name) const { +void chatEventVideoChatParticipantVolumeLevelChanged::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatStatisticsSupergroup"); - s.store_object_field("period", static_cast(period_.get())); - s.store_object_field("member_count", static_cast(member_count_.get())); - s.store_object_field("message_count", static_cast(message_count_.get())); - s.store_object_field("viewer_count", static_cast(viewer_count_.get())); - s.store_object_field("sender_count", static_cast(sender_count_.get())); - s.store_object_field("member_count_graph", static_cast(member_count_graph_.get())); - s.store_object_field("join_graph", static_cast(join_graph_.get())); - s.store_object_field("join_by_source_graph", static_cast(join_by_source_graph_.get())); - s.store_object_field("language_graph", static_cast(language_graph_.get())); - s.store_object_field("message_content_graph", static_cast(message_content_graph_.get())); - s.store_object_field("action_graph", static_cast(action_graph_.get())); - s.store_object_field("day_graph", static_cast(day_graph_.get())); - s.store_object_field("week_graph", static_cast(week_graph_.get())); - { s.store_vector_begin("top_senders", top_senders_.size()); for (const auto &_value : top_senders_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } - { s.store_vector_begin("top_administrators", top_administrators_.size()); for (const auto &_value : top_administrators_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } - { s.store_vector_begin("top_inviters", top_inviters_.size()); for (const auto &_value : top_inviters_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatEventVideoChatParticipantVolumeLevelChanged"); + s.store_object_field("participant_id", static_cast(participant_id_.get())); + s.store_field("volume_level", volume_level_); s.store_class_end(); } } -chatStatisticsChannel::chatStatisticsChannel() - : period_() - , member_count_() - , mean_view_count_() - , mean_share_count_() - , enabled_notifications_percentage_() - , member_count_graph_() - , join_graph_() - , mute_graph_() - , view_count_by_hour_graph_() - , view_count_by_source_graph_() - , join_by_source_graph_() - , language_graph_() - , message_interaction_graph_() - , instant_view_interaction_graph_() - , recent_message_interactions_() +chatEventIsForumToggled::chatEventIsForumToggled() + : is_forum_() {} -chatStatisticsChannel::chatStatisticsChannel(object_ptr &&period_, object_ptr &&member_count_, object_ptr &&mean_view_count_, object_ptr &&mean_share_count_, double enabled_notifications_percentage_, object_ptr &&member_count_graph_, object_ptr &&join_graph_, object_ptr &&mute_graph_, object_ptr &&view_count_by_hour_graph_, object_ptr &&view_count_by_source_graph_, object_ptr &&join_by_source_graph_, object_ptr &&language_graph_, object_ptr &&message_interaction_graph_, object_ptr &&instant_view_interaction_graph_, array> &&recent_message_interactions_) - : period_(std::move(period_)) - , member_count_(std::move(member_count_)) - , mean_view_count_(std::move(mean_view_count_)) - , mean_share_count_(std::move(mean_share_count_)) - , enabled_notifications_percentage_(enabled_notifications_percentage_) - , member_count_graph_(std::move(member_count_graph_)) - , join_graph_(std::move(join_graph_)) - , mute_graph_(std::move(mute_graph_)) - , view_count_by_hour_graph_(std::move(view_count_by_hour_graph_)) - , view_count_by_source_graph_(std::move(view_count_by_source_graph_)) - , join_by_source_graph_(std::move(join_by_source_graph_)) - , language_graph_(std::move(language_graph_)) - , message_interaction_graph_(std::move(message_interaction_graph_)) - , instant_view_interaction_graph_(std::move(instant_view_interaction_graph_)) - , recent_message_interactions_(std::move(recent_message_interactions_)) +chatEventIsForumToggled::chatEventIsForumToggled(bool is_forum_) + : is_forum_(is_forum_) {} -const std::int32_t chatStatisticsChannel::ID; +const std::int32_t chatEventIsForumToggled::ID; -void chatStatisticsChannel::store(TlStorerToString &s, const char *field_name) const { +void chatEventIsForumToggled::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatStatisticsChannel"); - s.store_object_field("period", static_cast(period_.get())); - s.store_object_field("member_count", static_cast(member_count_.get())); - s.store_object_field("mean_view_count", static_cast(mean_view_count_.get())); - s.store_object_field("mean_share_count", static_cast(mean_share_count_.get())); - s.store_field("enabled_notifications_percentage", enabled_notifications_percentage_); - s.store_object_field("member_count_graph", static_cast(member_count_graph_.get())); - s.store_object_field("join_graph", static_cast(join_graph_.get())); - s.store_object_field("mute_graph", static_cast(mute_graph_.get())); - s.store_object_field("view_count_by_hour_graph", static_cast(view_count_by_hour_graph_.get())); - s.store_object_field("view_count_by_source_graph", static_cast(view_count_by_source_graph_.get())); - s.store_object_field("join_by_source_graph", static_cast(join_by_source_graph_.get())); - s.store_object_field("language_graph", static_cast(language_graph_.get())); - s.store_object_field("message_interaction_graph", static_cast(message_interaction_graph_.get())); - s.store_object_field("instant_view_interaction_graph", static_cast(instant_view_interaction_graph_.get())); - { s.store_vector_begin("recent_message_interactions", recent_message_interactions_.size()); for (const auto &_value : recent_message_interactions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_begin(field_name, "chatEventIsForumToggled"); + s.store_field("is_forum", is_forum_); s.store_class_end(); } } -chatStatisticsAdministratorActionsInfo::chatStatisticsAdministratorActionsInfo() - : user_id_() - , deleted_message_count_() - , banned_user_count_() - , restricted_user_count_() +chatEventForumTopicCreated::chatEventForumTopicCreated() + : topic_info_() {} -chatStatisticsAdministratorActionsInfo::chatStatisticsAdministratorActionsInfo(int53 user_id_, int32 deleted_message_count_, int32 banned_user_count_, int32 restricted_user_count_) - : user_id_(user_id_) - , deleted_message_count_(deleted_message_count_) - , banned_user_count_(banned_user_count_) - , restricted_user_count_(restricted_user_count_) +chatEventForumTopicCreated::chatEventForumTopicCreated(object_ptr &&topic_info_) + : topic_info_(std::move(topic_info_)) {} -const std::int32_t chatStatisticsAdministratorActionsInfo::ID; +const std::int32_t chatEventForumTopicCreated::ID; -void chatStatisticsAdministratorActionsInfo::store(TlStorerToString &s, const char *field_name) const { +void chatEventForumTopicCreated::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatStatisticsAdministratorActionsInfo"); - s.store_field("user_id", user_id_); - s.store_field("deleted_message_count", deleted_message_count_); - s.store_field("banned_user_count", banned_user_count_); - s.store_field("restricted_user_count", restricted_user_count_); + s.store_class_begin(field_name, "chatEventForumTopicCreated"); + s.store_object_field("topic_info", static_cast(topic_info_.get())); s.store_class_end(); } } -chatStatisticsInviterInfo::chatStatisticsInviterInfo() - : user_id_() - , added_member_count_() +chatEventForumTopicEdited::chatEventForumTopicEdited() + : old_topic_info_() + , new_topic_info_() {} -chatStatisticsInviterInfo::chatStatisticsInviterInfo(int53 user_id_, int32 added_member_count_) - : user_id_(user_id_) - , added_member_count_(added_member_count_) +chatEventForumTopicEdited::chatEventForumTopicEdited(object_ptr &&old_topic_info_, object_ptr &&new_topic_info_) + : old_topic_info_(std::move(old_topic_info_)) + , new_topic_info_(std::move(new_topic_info_)) {} -const std::int32_t chatStatisticsInviterInfo::ID; +const std::int32_t chatEventForumTopicEdited::ID; -void chatStatisticsInviterInfo::store(TlStorerToString &s, const char *field_name) const { +void chatEventForumTopicEdited::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatStatisticsInviterInfo"); - s.store_field("user_id", user_id_); - s.store_field("added_member_count", added_member_count_); + s.store_class_begin(field_name, "chatEventForumTopicEdited"); + s.store_object_field("old_topic_info", static_cast(old_topic_info_.get())); + s.store_object_field("new_topic_info", static_cast(new_topic_info_.get())); s.store_class_end(); } } -chatStatisticsMessageInteractionInfo::chatStatisticsMessageInteractionInfo() - : message_id_() - , view_count_() - , forward_count_() +chatEventForumTopicToggleIsClosed::chatEventForumTopicToggleIsClosed() + : topic_info_() {} -chatStatisticsMessageInteractionInfo::chatStatisticsMessageInteractionInfo(int53 message_id_, int32 view_count_, int32 forward_count_) - : message_id_(message_id_) - , view_count_(view_count_) - , forward_count_(forward_count_) +chatEventForumTopicToggleIsClosed::chatEventForumTopicToggleIsClosed(object_ptr &&topic_info_) + : topic_info_(std::move(topic_info_)) {} -const std::int32_t chatStatisticsMessageInteractionInfo::ID; +const std::int32_t chatEventForumTopicToggleIsClosed::ID; -void chatStatisticsMessageInteractionInfo::store(TlStorerToString &s, const char *field_name) const { +void chatEventForumTopicToggleIsClosed::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatStatisticsMessageInteractionInfo"); - s.store_field("message_id", message_id_); - s.store_field("view_count", view_count_); - s.store_field("forward_count", forward_count_); + s.store_class_begin(field_name, "chatEventForumTopicToggleIsClosed"); + s.store_object_field("topic_info", static_cast(topic_info_.get())); s.store_class_end(); } } -chatStatisticsMessageSenderInfo::chatStatisticsMessageSenderInfo() - : user_id_() - , sent_message_count_() - , average_character_count_() +chatEventForumTopicToggleIsHidden::chatEventForumTopicToggleIsHidden() + : topic_info_() {} -chatStatisticsMessageSenderInfo::chatStatisticsMessageSenderInfo(int53 user_id_, int32 sent_message_count_, int32 average_character_count_) - : user_id_(user_id_) - , sent_message_count_(sent_message_count_) - , average_character_count_(average_character_count_) +chatEventForumTopicToggleIsHidden::chatEventForumTopicToggleIsHidden(object_ptr &&topic_info_) + : topic_info_(std::move(topic_info_)) {} -const std::int32_t chatStatisticsMessageSenderInfo::ID; +const std::int32_t chatEventForumTopicToggleIsHidden::ID; -void chatStatisticsMessageSenderInfo::store(TlStorerToString &s, const char *field_name) const { +void chatEventForumTopicToggleIsHidden::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatStatisticsMessageSenderInfo"); - s.store_field("user_id", user_id_); - s.store_field("sent_message_count", sent_message_count_); - s.store_field("average_character_count", average_character_count_); + s.store_class_begin(field_name, "chatEventForumTopicToggleIsHidden"); + s.store_object_field("topic_info", static_cast(topic_info_.get())); s.store_class_end(); } } -chatTheme::chatTheme() - : name_() - , light_settings_() - , dark_settings_() +chatEventForumTopicDeleted::chatEventForumTopicDeleted() + : topic_info_() {} -chatTheme::chatTheme(string const &name_, object_ptr &&light_settings_, object_ptr &&dark_settings_) - : name_(name_) - , light_settings_(std::move(light_settings_)) - , dark_settings_(std::move(dark_settings_)) +chatEventForumTopicDeleted::chatEventForumTopicDeleted(object_ptr &&topic_info_) + : topic_info_(std::move(topic_info_)) {} -const std::int32_t chatTheme::ID; +const std::int32_t chatEventForumTopicDeleted::ID; -void chatTheme::store(TlStorerToString &s, const char *field_name) const { +void chatEventForumTopicDeleted::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatTheme"); - s.store_field("name", name_); - s.store_object_field("light_settings", static_cast(light_settings_.get())); - s.store_object_field("dark_settings", static_cast(dark_settings_.get())); + s.store_class_begin(field_name, "chatEventForumTopicDeleted"); + s.store_object_field("topic_info", static_cast(topic_info_.get())); s.store_class_end(); } } -chatTypePrivate::chatTypePrivate() - : user_id_() +chatEventForumTopicPinned::chatEventForumTopicPinned() + : old_topic_info_() + , new_topic_info_() {} -chatTypePrivate::chatTypePrivate(int53 user_id_) - : user_id_(user_id_) +chatEventForumTopicPinned::chatEventForumTopicPinned(object_ptr &&old_topic_info_, object_ptr &&new_topic_info_) + : old_topic_info_(std::move(old_topic_info_)) + , new_topic_info_(std::move(new_topic_info_)) {} -const std::int32_t chatTypePrivate::ID; +const std::int32_t chatEventForumTopicPinned::ID; -void chatTypePrivate::store(TlStorerToString &s, const char *field_name) const { +void chatEventForumTopicPinned::store(TlStorerToString &s, const char *field_name) const { if (!LOG_IS_STRIPPED(ERROR)) { - s.store_class_begin(field_name, "chatTypePrivate"); - s.store_field("user_id", user_id_); + s.store_class_begin(field_name, "chatEventForumTopicPinned"); + s.store_object_field("old_topic_info", static_cast(old_topic_info_.get())); + s.store_object_field("new_topic_info", static_cast(new_topic_info_.get())); s.store_class_end(); } } -chatTypeBasicGroup::chatTypeBasicGroup() - : basic_group_id_() +chatEventLogFilters::chatEventLogFilters() + : message_edits_() + , message_deletions_() + , message_pins_() + , member_joins_() + , member_leaves_() + , member_invites_() + , member_promotions_() + , member_restrictions_() + , info_changes_() + , setting_changes_() + , invite_link_changes_() + , video_chat_changes_() + , forum_changes_() + , subscription_extensions_() +{} + +chatEventLogFilters::chatEventLogFilters(bool message_edits_, bool message_deletions_, bool message_pins_, bool member_joins_, bool member_leaves_, bool member_invites_, bool member_promotions_, bool member_restrictions_, bool info_changes_, bool setting_changes_, bool invite_link_changes_, bool video_chat_changes_, bool forum_changes_, bool subscription_extensions_) + : message_edits_(message_edits_) + , message_deletions_(message_deletions_) + , message_pins_(message_pins_) + , member_joins_(member_joins_) + , member_leaves_(member_leaves_) + , member_invites_(member_invites_) + , member_promotions_(member_promotions_) + , member_restrictions_(member_restrictions_) + , info_changes_(info_changes_) + , setting_changes_(setting_changes_) + , invite_link_changes_(invite_link_changes_) + , video_chat_changes_(video_chat_changes_) + , forum_changes_(forum_changes_) + , subscription_extensions_(subscription_extensions_) +{} + +const std::int32_t chatEventLogFilters::ID; + +void chatEventLogFilters::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatEventLogFilters"); + s.store_field("message_edits", message_edits_); + s.store_field("message_deletions", message_deletions_); + s.store_field("message_pins", message_pins_); + s.store_field("member_joins", member_joins_); + s.store_field("member_leaves", member_leaves_); + s.store_field("member_invites", member_invites_); + s.store_field("member_promotions", member_promotions_); + s.store_field("member_restrictions", member_restrictions_); + s.store_field("info_changes", info_changes_); + s.store_field("setting_changes", setting_changes_); + s.store_field("invite_link_changes", invite_link_changes_); + s.store_field("video_chat_changes", video_chat_changes_); + s.store_field("forum_changes", forum_changes_); + s.store_field("subscription_extensions", subscription_extensions_); + s.store_class_end(); + } +} + +chatEvents::chatEvents() + : events_() +{} + +chatEvents::chatEvents(array> &&events_) + : events_(std::move(events_)) +{} + +const std::int32_t chatEvents::ID; + +void chatEvents::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatEvents"); + { s.store_vector_begin("events", events_.size()); for (const auto &_value : events_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatFolder::chatFolder() + : title_() + , icon_() + , color_id_() + , is_shareable_() + , pinned_chat_ids_() + , included_chat_ids_() + , excluded_chat_ids_() + , exclude_muted_() + , exclude_read_() + , exclude_archived_() + , include_contacts_() + , include_non_contacts_() + , include_bots_() + , include_groups_() + , include_channels_() +{} + +chatFolder::chatFolder(string const &title_, object_ptr &&icon_, int32 color_id_, bool is_shareable_, array &&pinned_chat_ids_, array &&included_chat_ids_, array &&excluded_chat_ids_, bool exclude_muted_, bool exclude_read_, bool exclude_archived_, bool include_contacts_, bool include_non_contacts_, bool include_bots_, bool include_groups_, bool include_channels_) + : title_(title_) + , icon_(std::move(icon_)) + , color_id_(color_id_) + , is_shareable_(is_shareable_) + , pinned_chat_ids_(std::move(pinned_chat_ids_)) + , included_chat_ids_(std::move(included_chat_ids_)) + , excluded_chat_ids_(std::move(excluded_chat_ids_)) + , exclude_muted_(exclude_muted_) + , exclude_read_(exclude_read_) + , exclude_archived_(exclude_archived_) + , include_contacts_(include_contacts_) + , include_non_contacts_(include_non_contacts_) + , include_bots_(include_bots_) + , include_groups_(include_groups_) + , include_channels_(include_channels_) +{} + +const std::int32_t chatFolder::ID; + +void chatFolder::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatFolder"); + s.store_field("title", title_); + s.store_object_field("icon", static_cast(icon_.get())); + s.store_field("color_id", color_id_); + s.store_field("is_shareable", is_shareable_); + { s.store_vector_begin("pinned_chat_ids", pinned_chat_ids_.size()); for (const auto &_value : pinned_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + { s.store_vector_begin("included_chat_ids", included_chat_ids_.size()); for (const auto &_value : included_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + { s.store_vector_begin("excluded_chat_ids", excluded_chat_ids_.size()); for (const auto &_value : excluded_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_field("exclude_muted", exclude_muted_); + s.store_field("exclude_read", exclude_read_); + s.store_field("exclude_archived", exclude_archived_); + s.store_field("include_contacts", include_contacts_); + s.store_field("include_non_contacts", include_non_contacts_); + s.store_field("include_bots", include_bots_); + s.store_field("include_groups", include_groups_); + s.store_field("include_channels", include_channels_); + s.store_class_end(); + } +} + +chatFolderIcon::chatFolderIcon() + : name_() +{} + +chatFolderIcon::chatFolderIcon(string const &name_) + : name_(name_) +{} + +const std::int32_t chatFolderIcon::ID; + +void chatFolderIcon::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatFolderIcon"); + s.store_field("name", name_); + s.store_class_end(); + } +} + +chatFolderInfo::chatFolderInfo() + : id_() + , title_() + , icon_() + , color_id_() + , is_shareable_() + , has_my_invite_links_() +{} + +chatFolderInfo::chatFolderInfo(int32 id_, string const &title_, object_ptr &&icon_, int32 color_id_, bool is_shareable_, bool has_my_invite_links_) + : id_(id_) + , title_(title_) + , icon_(std::move(icon_)) + , color_id_(color_id_) + , is_shareable_(is_shareable_) + , has_my_invite_links_(has_my_invite_links_) +{} + +const std::int32_t chatFolderInfo::ID; + +void chatFolderInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatFolderInfo"); + s.store_field("id", id_); + s.store_field("title", title_); + s.store_object_field("icon", static_cast(icon_.get())); + s.store_field("color_id", color_id_); + s.store_field("is_shareable", is_shareable_); + s.store_field("has_my_invite_links", has_my_invite_links_); + s.store_class_end(); + } +} + +chatFolderInviteLink::chatFolderInviteLink() + : invite_link_() + , name_() + , chat_ids_() +{} + +chatFolderInviteLink::chatFolderInviteLink(string const &invite_link_, string const &name_, array &&chat_ids_) + : invite_link_(invite_link_) + , name_(name_) + , chat_ids_(std::move(chat_ids_)) +{} + +const std::int32_t chatFolderInviteLink::ID; + +void chatFolderInviteLink::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatFolderInviteLink"); + s.store_field("invite_link", invite_link_); + s.store_field("name", name_); + { s.store_vector_begin("chat_ids", chat_ids_.size()); for (const auto &_value : chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatFolderInviteLinkInfo::chatFolderInviteLinkInfo() + : chat_folder_info_() + , missing_chat_ids_() + , added_chat_ids_() +{} + +chatFolderInviteLinkInfo::chatFolderInviteLinkInfo(object_ptr &&chat_folder_info_, array &&missing_chat_ids_, array &&added_chat_ids_) + : chat_folder_info_(std::move(chat_folder_info_)) + , missing_chat_ids_(std::move(missing_chat_ids_)) + , added_chat_ids_(std::move(added_chat_ids_)) +{} + +const std::int32_t chatFolderInviteLinkInfo::ID; + +void chatFolderInviteLinkInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatFolderInviteLinkInfo"); + s.store_object_field("chat_folder_info", static_cast(chat_folder_info_.get())); + { s.store_vector_begin("missing_chat_ids", missing_chat_ids_.size()); for (const auto &_value : missing_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + { s.store_vector_begin("added_chat_ids", added_chat_ids_.size()); for (const auto &_value : added_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatFolderInviteLinks::chatFolderInviteLinks() + : invite_links_() +{} + +chatFolderInviteLinks::chatFolderInviteLinks(array> &&invite_links_) + : invite_links_(std::move(invite_links_)) +{} + +const std::int32_t chatFolderInviteLinks::ID; + +void chatFolderInviteLinks::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatFolderInviteLinks"); + { s.store_vector_begin("invite_links", invite_links_.size()); for (const auto &_value : invite_links_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatInviteLink::chatInviteLink() + : invite_link_() + , name_() + , creator_user_id_() + , date_() + , edit_date_() + , expiration_date_() + , subscription_pricing_() + , member_limit_() + , member_count_() + , expired_member_count_() + , pending_join_request_count_() + , creates_join_request_() + , is_primary_() + , is_revoked_() +{} + +chatInviteLink::chatInviteLink(string const &invite_link_, string const &name_, int53 creator_user_id_, int32 date_, int32 edit_date_, int32 expiration_date_, object_ptr &&subscription_pricing_, int32 member_limit_, int32 member_count_, int32 expired_member_count_, int32 pending_join_request_count_, bool creates_join_request_, bool is_primary_, bool is_revoked_) + : invite_link_(invite_link_) + , name_(name_) + , creator_user_id_(creator_user_id_) + , date_(date_) + , edit_date_(edit_date_) + , expiration_date_(expiration_date_) + , subscription_pricing_(std::move(subscription_pricing_)) + , member_limit_(member_limit_) + , member_count_(member_count_) + , expired_member_count_(expired_member_count_) + , pending_join_request_count_(pending_join_request_count_) + , creates_join_request_(creates_join_request_) + , is_primary_(is_primary_) + , is_revoked_(is_revoked_) +{} + +const std::int32_t chatInviteLink::ID; + +void chatInviteLink::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatInviteLink"); + s.store_field("invite_link", invite_link_); + s.store_field("name", name_); + s.store_field("creator_user_id", creator_user_id_); + s.store_field("date", date_); + s.store_field("edit_date", edit_date_); + s.store_field("expiration_date", expiration_date_); + s.store_object_field("subscription_pricing", static_cast(subscription_pricing_.get())); + s.store_field("member_limit", member_limit_); + s.store_field("member_count", member_count_); + s.store_field("expired_member_count", expired_member_count_); + s.store_field("pending_join_request_count", pending_join_request_count_); + s.store_field("creates_join_request", creates_join_request_); + s.store_field("is_primary", is_primary_); + s.store_field("is_revoked", is_revoked_); + s.store_class_end(); + } +} + +chatInviteLinkCount::chatInviteLinkCount() + : user_id_() + , invite_link_count_() + , revoked_invite_link_count_() +{} + +chatInviteLinkCount::chatInviteLinkCount(int53 user_id_, int32 invite_link_count_, int32 revoked_invite_link_count_) + : user_id_(user_id_) + , invite_link_count_(invite_link_count_) + , revoked_invite_link_count_(revoked_invite_link_count_) +{} + +const std::int32_t chatInviteLinkCount::ID; + +void chatInviteLinkCount::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatInviteLinkCount"); + s.store_field("user_id", user_id_); + s.store_field("invite_link_count", invite_link_count_); + s.store_field("revoked_invite_link_count", revoked_invite_link_count_); + s.store_class_end(); + } +} + +chatInviteLinkCounts::chatInviteLinkCounts() + : invite_link_counts_() +{} + +chatInviteLinkCounts::chatInviteLinkCounts(array> &&invite_link_counts_) + : invite_link_counts_(std::move(invite_link_counts_)) +{} + +const std::int32_t chatInviteLinkCounts::ID; + +void chatInviteLinkCounts::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatInviteLinkCounts"); + { s.store_vector_begin("invite_link_counts", invite_link_counts_.size()); for (const auto &_value : invite_link_counts_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatInviteLinkInfo::chatInviteLinkInfo() + : chat_id_() + , accessible_for_() + , type_() + , title_() + , photo_() + , accent_color_id_() + , description_() + , member_count_() + , member_user_ids_() + , subscription_info_() + , creates_join_request_() + , is_public_() + , is_verified_() + , is_scam_() + , is_fake_() +{} + +chatInviteLinkInfo::chatInviteLinkInfo(int53 chat_id_, int32 accessible_for_, object_ptr &&type_, string const &title_, object_ptr &&photo_, int32 accent_color_id_, string const &description_, int32 member_count_, array &&member_user_ids_, object_ptr &&subscription_info_, bool creates_join_request_, bool is_public_, bool is_verified_, bool is_scam_, bool is_fake_) + : chat_id_(chat_id_) + , accessible_for_(accessible_for_) + , type_(std::move(type_)) + , title_(title_) + , photo_(std::move(photo_)) + , accent_color_id_(accent_color_id_) + , description_(description_) + , member_count_(member_count_) + , member_user_ids_(std::move(member_user_ids_)) + , subscription_info_(std::move(subscription_info_)) + , creates_join_request_(creates_join_request_) + , is_public_(is_public_) + , is_verified_(is_verified_) + , is_scam_(is_scam_) + , is_fake_(is_fake_) +{} + +const std::int32_t chatInviteLinkInfo::ID; + +void chatInviteLinkInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatInviteLinkInfo"); + s.store_field("chat_id", chat_id_); + s.store_field("accessible_for", accessible_for_); + s.store_object_field("type", static_cast(type_.get())); + s.store_field("title", title_); + s.store_object_field("photo", static_cast(photo_.get())); + s.store_field("accent_color_id", accent_color_id_); + s.store_field("description", description_); + s.store_field("member_count", member_count_); + { s.store_vector_begin("member_user_ids", member_user_ids_.size()); for (const auto &_value : member_user_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_object_field("subscription_info", static_cast(subscription_info_.get())); + s.store_field("creates_join_request", creates_join_request_); + s.store_field("is_public", is_public_); + s.store_field("is_verified", is_verified_); + s.store_field("is_scam", is_scam_); + s.store_field("is_fake", is_fake_); + s.store_class_end(); + } +} + +chatInviteLinkMember::chatInviteLinkMember() + : user_id_() + , joined_chat_date_() + , via_chat_folder_invite_link_() + , approver_user_id_() +{} + +chatInviteLinkMember::chatInviteLinkMember(int53 user_id_, int32 joined_chat_date_, bool via_chat_folder_invite_link_, int53 approver_user_id_) + : user_id_(user_id_) + , joined_chat_date_(joined_chat_date_) + , via_chat_folder_invite_link_(via_chat_folder_invite_link_) + , approver_user_id_(approver_user_id_) +{} + +const std::int32_t chatInviteLinkMember::ID; + +void chatInviteLinkMember::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatInviteLinkMember"); + s.store_field("user_id", user_id_); + s.store_field("joined_chat_date", joined_chat_date_); + s.store_field("via_chat_folder_invite_link", via_chat_folder_invite_link_); + s.store_field("approver_user_id", approver_user_id_); + s.store_class_end(); + } +} + +chatInviteLinkMembers::chatInviteLinkMembers() + : total_count_() + , members_() +{} + +chatInviteLinkMembers::chatInviteLinkMembers(int32 total_count_, array> &&members_) + : total_count_(total_count_) + , members_(std::move(members_)) +{} + +const std::int32_t chatInviteLinkMembers::ID; + +void chatInviteLinkMembers::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatInviteLinkMembers"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("members", members_.size()); for (const auto &_value : members_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatInviteLinkSubscriptionInfo::chatInviteLinkSubscriptionInfo() + : pricing_() + , can_reuse_() + , form_id_() +{} + +chatInviteLinkSubscriptionInfo::chatInviteLinkSubscriptionInfo(object_ptr &&pricing_, bool can_reuse_, int64 form_id_) + : pricing_(std::move(pricing_)) + , can_reuse_(can_reuse_) + , form_id_(form_id_) +{} + +const std::int32_t chatInviteLinkSubscriptionInfo::ID; + +void chatInviteLinkSubscriptionInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatInviteLinkSubscriptionInfo"); + s.store_object_field("pricing", static_cast(pricing_.get())); + s.store_field("can_reuse", can_reuse_); + s.store_field("form_id", form_id_); + s.store_class_end(); + } +} + +chatInviteLinks::chatInviteLinks() + : total_count_() + , invite_links_() +{} + +chatInviteLinks::chatInviteLinks(int32 total_count_, array> &&invite_links_) + : total_count_(total_count_) + , invite_links_(std::move(invite_links_)) +{} + +const std::int32_t chatInviteLinks::ID; + +void chatInviteLinks::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatInviteLinks"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("invite_links", invite_links_.size()); for (const auto &_value : invite_links_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatJoinRequest::chatJoinRequest() + : user_id_() + , date_() + , bio_() +{} + +chatJoinRequest::chatJoinRequest(int53 user_id_, int32 date_, string const &bio_) + : user_id_(user_id_) + , date_(date_) + , bio_(bio_) +{} + +const std::int32_t chatJoinRequest::ID; + +void chatJoinRequest::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatJoinRequest"); + s.store_field("user_id", user_id_); + s.store_field("date", date_); + s.store_field("bio", bio_); + s.store_class_end(); + } +} + +chatJoinRequests::chatJoinRequests() + : total_count_() + , requests_() +{} + +chatJoinRequests::chatJoinRequests(int32 total_count_, array> &&requests_) + : total_count_(total_count_) + , requests_(std::move(requests_)) +{} + +const std::int32_t chatJoinRequests::ID; + +void chatJoinRequests::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatJoinRequests"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("requests", requests_.size()); for (const auto &_value : requests_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatJoinRequestsInfo::chatJoinRequestsInfo() + : total_count_() + , user_ids_() +{} + +chatJoinRequestsInfo::chatJoinRequestsInfo(int32 total_count_, array &&user_ids_) + : total_count_(total_count_) + , user_ids_(std::move(user_ids_)) +{} + +const std::int32_t chatJoinRequestsInfo::ID; + +void chatJoinRequestsInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatJoinRequestsInfo"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("user_ids", user_ids_.size()); for (const auto &_value : user_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatListMain::chatListMain() { +} + +const std::int32_t chatListMain::ID; + +void chatListMain::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatListMain"); + s.store_class_end(); + } +} + +chatListArchive::chatListArchive() { +} + +const std::int32_t chatListArchive::ID; + +void chatListArchive::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatListArchive"); + s.store_class_end(); + } +} + +chatListFolder::chatListFolder() + : chat_folder_id_() +{} + +chatListFolder::chatListFolder(int32 chat_folder_id_) + : chat_folder_id_(chat_folder_id_) +{} + +const std::int32_t chatListFolder::ID; + +void chatListFolder::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatListFolder"); + s.store_field("chat_folder_id", chat_folder_id_); + s.store_class_end(); + } +} + +chatLists::chatLists() + : chat_lists_() +{} + +chatLists::chatLists(array> &&chat_lists_) + : chat_lists_(std::move(chat_lists_)) +{} + +const std::int32_t chatLists::ID; + +void chatLists::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatLists"); + { s.store_vector_begin("chat_lists", chat_lists_.size()); for (const auto &_value : chat_lists_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatLocation::chatLocation() + : location_() + , address_() +{} + +chatLocation::chatLocation(object_ptr &&location_, string const &address_) + : location_(std::move(location_)) + , address_(address_) +{} + +const std::int32_t chatLocation::ID; + +void chatLocation::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatLocation"); + s.store_object_field("location", static_cast(location_.get())); + s.store_field("address", address_); + s.store_class_end(); + } +} + +chatMember::chatMember() + : member_id_() + , inviter_user_id_() + , joined_chat_date_() + , status_() +{} + +chatMember::chatMember(object_ptr &&member_id_, int53 inviter_user_id_, int32 joined_chat_date_, object_ptr &&status_) + : member_id_(std::move(member_id_)) + , inviter_user_id_(inviter_user_id_) + , joined_chat_date_(joined_chat_date_) + , status_(std::move(status_)) +{} + +const std::int32_t chatMember::ID; + +void chatMember::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMember"); + s.store_object_field("member_id", static_cast(member_id_.get())); + s.store_field("inviter_user_id", inviter_user_id_); + s.store_field("joined_chat_date", joined_chat_date_); + s.store_object_field("status", static_cast(status_.get())); + s.store_class_end(); + } +} + +chatMemberStatusCreator::chatMemberStatusCreator() + : custom_title_() + , is_anonymous_() + , is_member_() +{} + +chatMemberStatusCreator::chatMemberStatusCreator(string const &custom_title_, bool is_anonymous_, bool is_member_) + : custom_title_(custom_title_) + , is_anonymous_(is_anonymous_) + , is_member_(is_member_) +{} + +const std::int32_t chatMemberStatusCreator::ID; + +void chatMemberStatusCreator::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMemberStatusCreator"); + s.store_field("custom_title", custom_title_); + s.store_field("is_anonymous", is_anonymous_); + s.store_field("is_member", is_member_); + s.store_class_end(); + } +} + +chatMemberStatusAdministrator::chatMemberStatusAdministrator() + : custom_title_() + , can_be_edited_() + , rights_() +{} + +chatMemberStatusAdministrator::chatMemberStatusAdministrator(string const &custom_title_, bool can_be_edited_, object_ptr &&rights_) + : custom_title_(custom_title_) + , can_be_edited_(can_be_edited_) + , rights_(std::move(rights_)) +{} + +const std::int32_t chatMemberStatusAdministrator::ID; + +void chatMemberStatusAdministrator::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMemberStatusAdministrator"); + s.store_field("custom_title", custom_title_); + s.store_field("can_be_edited", can_be_edited_); + s.store_object_field("rights", static_cast(rights_.get())); + s.store_class_end(); + } +} + +chatMemberStatusMember::chatMemberStatusMember() + : member_until_date_() +{} + +chatMemberStatusMember::chatMemberStatusMember(int32 member_until_date_) + : member_until_date_(member_until_date_) +{} + +const std::int32_t chatMemberStatusMember::ID; + +void chatMemberStatusMember::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMemberStatusMember"); + s.store_field("member_until_date", member_until_date_); + s.store_class_end(); + } +} + +chatMemberStatusRestricted::chatMemberStatusRestricted() + : is_member_() + , restricted_until_date_() + , permissions_() +{} + +chatMemberStatusRestricted::chatMemberStatusRestricted(bool is_member_, int32 restricted_until_date_, object_ptr &&permissions_) + : is_member_(is_member_) + , restricted_until_date_(restricted_until_date_) + , permissions_(std::move(permissions_)) +{} + +const std::int32_t chatMemberStatusRestricted::ID; + +void chatMemberStatusRestricted::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMemberStatusRestricted"); + s.store_field("is_member", is_member_); + s.store_field("restricted_until_date", restricted_until_date_); + s.store_object_field("permissions", static_cast(permissions_.get())); + s.store_class_end(); + } +} + +chatMemberStatusLeft::chatMemberStatusLeft() { +} + +const std::int32_t chatMemberStatusLeft::ID; + +void chatMemberStatusLeft::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMemberStatusLeft"); + s.store_class_end(); + } +} + +chatMemberStatusBanned::chatMemberStatusBanned() + : banned_until_date_() +{} + +chatMemberStatusBanned::chatMemberStatusBanned(int32 banned_until_date_) + : banned_until_date_(banned_until_date_) +{} + +const std::int32_t chatMemberStatusBanned::ID; + +void chatMemberStatusBanned::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMemberStatusBanned"); + s.store_field("banned_until_date", banned_until_date_); + s.store_class_end(); + } +} + +chatMembers::chatMembers() + : total_count_() + , members_() +{} + +chatMembers::chatMembers(int32 total_count_, array> &&members_) + : total_count_(total_count_) + , members_(std::move(members_)) +{} + +const std::int32_t chatMembers::ID; + +void chatMembers::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMembers"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("members", members_.size()); for (const auto &_value : members_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatMembersFilterContacts::chatMembersFilterContacts() { +} + +const std::int32_t chatMembersFilterContacts::ID; + +void chatMembersFilterContacts::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMembersFilterContacts"); + s.store_class_end(); + } +} + +chatMembersFilterAdministrators::chatMembersFilterAdministrators() { +} + +const std::int32_t chatMembersFilterAdministrators::ID; + +void chatMembersFilterAdministrators::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMembersFilterAdministrators"); + s.store_class_end(); + } +} + +chatMembersFilterMembers::chatMembersFilterMembers() { +} + +const std::int32_t chatMembersFilterMembers::ID; + +void chatMembersFilterMembers::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMembersFilterMembers"); + s.store_class_end(); + } +} + +chatMembersFilterMention::chatMembersFilterMention() + : message_thread_id_() +{} + +chatMembersFilterMention::chatMembersFilterMention(int53 message_thread_id_) + : message_thread_id_(message_thread_id_) +{} + +const std::int32_t chatMembersFilterMention::ID; + +void chatMembersFilterMention::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMembersFilterMention"); + s.store_field("message_thread_id", message_thread_id_); + s.store_class_end(); + } +} + +chatMembersFilterRestricted::chatMembersFilterRestricted() { +} + +const std::int32_t chatMembersFilterRestricted::ID; + +void chatMembersFilterRestricted::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMembersFilterRestricted"); + s.store_class_end(); + } +} + +chatMembersFilterBanned::chatMembersFilterBanned() { +} + +const std::int32_t chatMembersFilterBanned::ID; + +void chatMembersFilterBanned::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMembersFilterBanned"); + s.store_class_end(); + } +} + +chatMembersFilterBots::chatMembersFilterBots() { +} + +const std::int32_t chatMembersFilterBots::ID; + +void chatMembersFilterBots::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMembersFilterBots"); + s.store_class_end(); + } +} + +chatMessageSender::chatMessageSender() + : sender_() + , needs_premium_() +{} + +chatMessageSender::chatMessageSender(object_ptr &&sender_, bool needs_premium_) + : sender_(std::move(sender_)) + , needs_premium_(needs_premium_) +{} + +const std::int32_t chatMessageSender::ID; + +void chatMessageSender::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMessageSender"); + s.store_object_field("sender", static_cast(sender_.get())); + s.store_field("needs_premium", needs_premium_); + s.store_class_end(); + } +} + +chatMessageSenders::chatMessageSenders() + : senders_() +{} + +chatMessageSenders::chatMessageSenders(array> &&senders_) + : senders_(std::move(senders_)) +{} + +const std::int32_t chatMessageSenders::ID; + +void chatMessageSenders::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatMessageSenders"); + { s.store_vector_begin("senders", senders_.size()); for (const auto &_value : senders_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatNearby::chatNearby() + : chat_id_() + , distance_() +{} + +chatNearby::chatNearby(int53 chat_id_, int32 distance_) + : chat_id_(chat_id_) + , distance_(distance_) +{} + +const std::int32_t chatNearby::ID; + +void chatNearby::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatNearby"); + s.store_field("chat_id", chat_id_); + s.store_field("distance", distance_); + s.store_class_end(); + } +} + +chatNotificationSettings::chatNotificationSettings() + : use_default_mute_for_() + , mute_for_() + , use_default_sound_() + , sound_id_() + , use_default_show_preview_() + , show_preview_() + , use_default_mute_stories_() + , mute_stories_() + , use_default_story_sound_() + , story_sound_id_() + , use_default_show_story_sender_() + , show_story_sender_() + , use_default_disable_pinned_message_notifications_() + , disable_pinned_message_notifications_() + , use_default_disable_mention_notifications_() + , disable_mention_notifications_() +{} + +chatNotificationSettings::chatNotificationSettings(bool use_default_mute_for_, int32 mute_for_, bool use_default_sound_, int64 sound_id_, bool use_default_show_preview_, bool show_preview_, bool use_default_mute_stories_, bool mute_stories_, bool use_default_story_sound_, int64 story_sound_id_, bool use_default_show_story_sender_, bool show_story_sender_, bool use_default_disable_pinned_message_notifications_, bool disable_pinned_message_notifications_, bool use_default_disable_mention_notifications_, bool disable_mention_notifications_) + : use_default_mute_for_(use_default_mute_for_) + , mute_for_(mute_for_) + , use_default_sound_(use_default_sound_) + , sound_id_(sound_id_) + , use_default_show_preview_(use_default_show_preview_) + , show_preview_(show_preview_) + , use_default_mute_stories_(use_default_mute_stories_) + , mute_stories_(mute_stories_) + , use_default_story_sound_(use_default_story_sound_) + , story_sound_id_(story_sound_id_) + , use_default_show_story_sender_(use_default_show_story_sender_) + , show_story_sender_(show_story_sender_) + , use_default_disable_pinned_message_notifications_(use_default_disable_pinned_message_notifications_) + , disable_pinned_message_notifications_(disable_pinned_message_notifications_) + , use_default_disable_mention_notifications_(use_default_disable_mention_notifications_) + , disable_mention_notifications_(disable_mention_notifications_) +{} + +const std::int32_t chatNotificationSettings::ID; + +void chatNotificationSettings::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatNotificationSettings"); + s.store_field("use_default_mute_for", use_default_mute_for_); + s.store_field("mute_for", mute_for_); + s.store_field("use_default_sound", use_default_sound_); + s.store_field("sound_id", sound_id_); + s.store_field("use_default_show_preview", use_default_show_preview_); + s.store_field("show_preview", show_preview_); + s.store_field("use_default_mute_stories", use_default_mute_stories_); + s.store_field("mute_stories", mute_stories_); + s.store_field("use_default_story_sound", use_default_story_sound_); + s.store_field("story_sound_id", story_sound_id_); + s.store_field("use_default_show_story_sender", use_default_show_story_sender_); + s.store_field("show_story_sender", show_story_sender_); + s.store_field("use_default_disable_pinned_message_notifications", use_default_disable_pinned_message_notifications_); + s.store_field("disable_pinned_message_notifications", disable_pinned_message_notifications_); + s.store_field("use_default_disable_mention_notifications", use_default_disable_mention_notifications_); + s.store_field("disable_mention_notifications", disable_mention_notifications_); + s.store_class_end(); + } +} + +chatPermissions::chatPermissions() + : can_send_basic_messages_() + , can_send_audios_() + , can_send_documents_() + , can_send_photos_() + , can_send_videos_() + , can_send_video_notes_() + , can_send_voice_notes_() + , can_send_polls_() + , can_send_other_messages_() + , can_add_link_previews_() + , can_change_info_() + , can_invite_users_() + , can_pin_messages_() + , can_create_topics_() +{} + +chatPermissions::chatPermissions(bool can_send_basic_messages_, bool can_send_audios_, bool can_send_documents_, bool can_send_photos_, bool can_send_videos_, bool can_send_video_notes_, bool can_send_voice_notes_, bool can_send_polls_, bool can_send_other_messages_, bool can_add_link_previews_, bool can_change_info_, bool can_invite_users_, bool can_pin_messages_, bool can_create_topics_) + : can_send_basic_messages_(can_send_basic_messages_) + , can_send_audios_(can_send_audios_) + , can_send_documents_(can_send_documents_) + , can_send_photos_(can_send_photos_) + , can_send_videos_(can_send_videos_) + , can_send_video_notes_(can_send_video_notes_) + , can_send_voice_notes_(can_send_voice_notes_) + , can_send_polls_(can_send_polls_) + , can_send_other_messages_(can_send_other_messages_) + , can_add_link_previews_(can_add_link_previews_) + , can_change_info_(can_change_info_) + , can_invite_users_(can_invite_users_) + , can_pin_messages_(can_pin_messages_) + , can_create_topics_(can_create_topics_) +{} + +const std::int32_t chatPermissions::ID; + +void chatPermissions::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatPermissions"); + s.store_field("can_send_basic_messages", can_send_basic_messages_); + s.store_field("can_send_audios", can_send_audios_); + s.store_field("can_send_documents", can_send_documents_); + s.store_field("can_send_photos", can_send_photos_); + s.store_field("can_send_videos", can_send_videos_); + s.store_field("can_send_video_notes", can_send_video_notes_); + s.store_field("can_send_voice_notes", can_send_voice_notes_); + s.store_field("can_send_polls", can_send_polls_); + s.store_field("can_send_other_messages", can_send_other_messages_); + s.store_field("can_add_link_previews", can_add_link_previews_); + s.store_field("can_change_info", can_change_info_); + s.store_field("can_invite_users", can_invite_users_); + s.store_field("can_pin_messages", can_pin_messages_); + s.store_field("can_create_topics", can_create_topics_); + s.store_class_end(); + } +} + +chatPhoto::chatPhoto() + : id_() + , added_date_() + , minithumbnail_() + , sizes_() + , animation_() + , small_animation_() + , sticker_() +{} + +chatPhoto::chatPhoto(int64 id_, int32 added_date_, object_ptr &&minithumbnail_, array> &&sizes_, object_ptr &&animation_, object_ptr &&small_animation_, object_ptr &&sticker_) + : id_(id_) + , added_date_(added_date_) + , minithumbnail_(std::move(minithumbnail_)) + , sizes_(std::move(sizes_)) + , animation_(std::move(animation_)) + , small_animation_(std::move(small_animation_)) + , sticker_(std::move(sticker_)) +{} + +const std::int32_t chatPhoto::ID; + +void chatPhoto::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatPhoto"); + s.store_field("id", id_); + s.store_field("added_date", added_date_); + s.store_object_field("minithumbnail", static_cast(minithumbnail_.get())); + { s.store_vector_begin("sizes", sizes_.size()); for (const auto &_value : sizes_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_object_field("animation", static_cast(animation_.get())); + s.store_object_field("small_animation", static_cast(small_animation_.get())); + s.store_object_field("sticker", static_cast(sticker_.get())); + s.store_class_end(); + } +} + +chatPhotoInfo::chatPhotoInfo() + : small_() + , big_() + , minithumbnail_() + , has_animation_() + , is_personal_() +{} + +chatPhotoInfo::chatPhotoInfo(object_ptr &&small_, object_ptr &&big_, object_ptr &&minithumbnail_, bool has_animation_, bool is_personal_) + : small_(std::move(small_)) + , big_(std::move(big_)) + , minithumbnail_(std::move(minithumbnail_)) + , has_animation_(has_animation_) + , is_personal_(is_personal_) +{} + +const std::int32_t chatPhotoInfo::ID; + +void chatPhotoInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatPhotoInfo"); + s.store_object_field("small", static_cast(small_.get())); + s.store_object_field("big", static_cast(big_.get())); + s.store_object_field("minithumbnail", static_cast(minithumbnail_.get())); + s.store_field("has_animation", has_animation_); + s.store_field("is_personal", is_personal_); + s.store_class_end(); + } +} + +chatPhotoSticker::chatPhotoSticker() + : type_() + , background_fill_() +{} + +chatPhotoSticker::chatPhotoSticker(object_ptr &&type_, object_ptr &&background_fill_) + : type_(std::move(type_)) + , background_fill_(std::move(background_fill_)) +{} + +const std::int32_t chatPhotoSticker::ID; + +void chatPhotoSticker::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatPhotoSticker"); + s.store_object_field("type", static_cast(type_.get())); + s.store_object_field("background_fill", static_cast(background_fill_.get())); + s.store_class_end(); + } +} + +chatPhotoStickerTypeRegularOrMask::chatPhotoStickerTypeRegularOrMask() + : sticker_set_id_() + , sticker_id_() +{} + +chatPhotoStickerTypeRegularOrMask::chatPhotoStickerTypeRegularOrMask(int64 sticker_set_id_, int64 sticker_id_) + : sticker_set_id_(sticker_set_id_) + , sticker_id_(sticker_id_) +{} + +const std::int32_t chatPhotoStickerTypeRegularOrMask::ID; + +void chatPhotoStickerTypeRegularOrMask::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatPhotoStickerTypeRegularOrMask"); + s.store_field("sticker_set_id", sticker_set_id_); + s.store_field("sticker_id", sticker_id_); + s.store_class_end(); + } +} + +chatPhotoStickerTypeCustomEmoji::chatPhotoStickerTypeCustomEmoji() + : custom_emoji_id_() +{} + +chatPhotoStickerTypeCustomEmoji::chatPhotoStickerTypeCustomEmoji(int64 custom_emoji_id_) + : custom_emoji_id_(custom_emoji_id_) +{} + +const std::int32_t chatPhotoStickerTypeCustomEmoji::ID; + +void chatPhotoStickerTypeCustomEmoji::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatPhotoStickerTypeCustomEmoji"); + s.store_field("custom_emoji_id", custom_emoji_id_); + s.store_class_end(); + } +} + +chatPhotos::chatPhotos() + : total_count_() + , photos_() +{} + +chatPhotos::chatPhotos(int32 total_count_, array> &&photos_) + : total_count_(total_count_) + , photos_(std::move(photos_)) +{} + +const std::int32_t chatPhotos::ID; + +void chatPhotos::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatPhotos"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("photos", photos_.size()); for (const auto &_value : photos_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatPosition::chatPosition() + : list_() + , order_() + , is_pinned_() + , source_() +{} + +chatPosition::chatPosition(object_ptr &&list_, int64 order_, bool is_pinned_, object_ptr &&source_) + : list_(std::move(list_)) + , order_(order_) + , is_pinned_(is_pinned_) + , source_(std::move(source_)) +{} + +const std::int32_t chatPosition::ID; + +void chatPosition::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatPosition"); + s.store_object_field("list", static_cast(list_.get())); + s.store_field("order", order_); + s.store_field("is_pinned", is_pinned_); + s.store_object_field("source", static_cast(source_.get())); + s.store_class_end(); + } +} + +chatRevenueAmount::chatRevenueAmount() + : cryptocurrency_() + , total_amount_() + , balance_amount_() + , available_amount_() + , withdrawal_enabled_() +{} + +chatRevenueAmount::chatRevenueAmount(string const &cryptocurrency_, int64 total_amount_, int64 balance_amount_, int64 available_amount_, bool withdrawal_enabled_) + : cryptocurrency_(cryptocurrency_) + , total_amount_(total_amount_) + , balance_amount_(balance_amount_) + , available_amount_(available_amount_) + , withdrawal_enabled_(withdrawal_enabled_) +{} + +const std::int32_t chatRevenueAmount::ID; + +void chatRevenueAmount::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatRevenueAmount"); + s.store_field("cryptocurrency", cryptocurrency_); + s.store_field("total_amount", total_amount_); + s.store_field("balance_amount", balance_amount_); + s.store_field("available_amount", available_amount_); + s.store_field("withdrawal_enabled", withdrawal_enabled_); + s.store_class_end(); + } +} + +chatRevenueStatistics::chatRevenueStatistics() + : revenue_by_hour_graph_() + , revenue_graph_() + , revenue_amount_() + , usd_rate_() +{} + +chatRevenueStatistics::chatRevenueStatistics(object_ptr &&revenue_by_hour_graph_, object_ptr &&revenue_graph_, object_ptr &&revenue_amount_, double usd_rate_) + : revenue_by_hour_graph_(std::move(revenue_by_hour_graph_)) + , revenue_graph_(std::move(revenue_graph_)) + , revenue_amount_(std::move(revenue_amount_)) + , usd_rate_(usd_rate_) +{} + +const std::int32_t chatRevenueStatistics::ID; + +void chatRevenueStatistics::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatRevenueStatistics"); + s.store_object_field("revenue_by_hour_graph", static_cast(revenue_by_hour_graph_.get())); + s.store_object_field("revenue_graph", static_cast(revenue_graph_.get())); + s.store_object_field("revenue_amount", static_cast(revenue_amount_.get())); + s.store_field("usd_rate", usd_rate_); + s.store_class_end(); + } +} + +chatRevenueTransaction::chatRevenueTransaction() + : cryptocurrency_() + , cryptocurrency_amount_() + , type_() +{} + +chatRevenueTransaction::chatRevenueTransaction(string const &cryptocurrency_, int64 cryptocurrency_amount_, object_ptr &&type_) + : cryptocurrency_(cryptocurrency_) + , cryptocurrency_amount_(cryptocurrency_amount_) + , type_(std::move(type_)) +{} + +const std::int32_t chatRevenueTransaction::ID; + +void chatRevenueTransaction::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatRevenueTransaction"); + s.store_field("cryptocurrency", cryptocurrency_); + s.store_field("cryptocurrency_amount", cryptocurrency_amount_); + s.store_object_field("type", static_cast(type_.get())); + s.store_class_end(); + } +} + +chatRevenueTransactionTypeEarnings::chatRevenueTransactionTypeEarnings() + : start_date_() + , end_date_() +{} + +chatRevenueTransactionTypeEarnings::chatRevenueTransactionTypeEarnings(int32 start_date_, int32 end_date_) + : start_date_(start_date_) + , end_date_(end_date_) +{} + +const std::int32_t chatRevenueTransactionTypeEarnings::ID; + +void chatRevenueTransactionTypeEarnings::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatRevenueTransactionTypeEarnings"); + s.store_field("start_date", start_date_); + s.store_field("end_date", end_date_); + s.store_class_end(); + } +} + +chatRevenueTransactionTypeWithdrawal::chatRevenueTransactionTypeWithdrawal() + : withdrawal_date_() + , provider_() + , state_() +{} + +chatRevenueTransactionTypeWithdrawal::chatRevenueTransactionTypeWithdrawal(int32 withdrawal_date_, string const &provider_, object_ptr &&state_) + : withdrawal_date_(withdrawal_date_) + , provider_(provider_) + , state_(std::move(state_)) +{} + +const std::int32_t chatRevenueTransactionTypeWithdrawal::ID; + +void chatRevenueTransactionTypeWithdrawal::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatRevenueTransactionTypeWithdrawal"); + s.store_field("withdrawal_date", withdrawal_date_); + s.store_field("provider", provider_); + s.store_object_field("state", static_cast(state_.get())); + s.store_class_end(); + } +} + +chatRevenueTransactionTypeRefund::chatRevenueTransactionTypeRefund() + : refund_date_() + , provider_() +{} + +chatRevenueTransactionTypeRefund::chatRevenueTransactionTypeRefund(int32 refund_date_, string const &provider_) + : refund_date_(refund_date_) + , provider_(provider_) +{} + +const std::int32_t chatRevenueTransactionTypeRefund::ID; + +void chatRevenueTransactionTypeRefund::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatRevenueTransactionTypeRefund"); + s.store_field("refund_date", refund_date_); + s.store_field("provider", provider_); + s.store_class_end(); + } +} + +chatRevenueTransactions::chatRevenueTransactions() + : total_count_() + , transactions_() +{} + +chatRevenueTransactions::chatRevenueTransactions(int32 total_count_, array> &&transactions_) + : total_count_(total_count_) + , transactions_(std::move(transactions_)) +{} + +const std::int32_t chatRevenueTransactions::ID; + +void chatRevenueTransactions::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatRevenueTransactions"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("transactions", transactions_.size()); for (const auto &_value : transactions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatSourceMtprotoProxy::chatSourceMtprotoProxy() { +} + +const std::int32_t chatSourceMtprotoProxy::ID; + +void chatSourceMtprotoProxy::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatSourceMtprotoProxy"); + s.store_class_end(); + } +} + +chatSourcePublicServiceAnnouncement::chatSourcePublicServiceAnnouncement() + : type_() + , text_() +{} + +chatSourcePublicServiceAnnouncement::chatSourcePublicServiceAnnouncement(string const &type_, string const &text_) + : type_(type_) + , text_(text_) +{} + +const std::int32_t chatSourcePublicServiceAnnouncement::ID; + +void chatSourcePublicServiceAnnouncement::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatSourcePublicServiceAnnouncement"); + s.store_field("type", type_); + s.store_field("text", text_); + s.store_class_end(); + } +} + +chatStatisticsSupergroup::chatStatisticsSupergroup() + : period_() + , member_count_() + , message_count_() + , viewer_count_() + , sender_count_() + , member_count_graph_() + , join_graph_() + , join_by_source_graph_() + , language_graph_() + , message_content_graph_() + , action_graph_() + , day_graph_() + , week_graph_() + , top_senders_() + , top_administrators_() + , top_inviters_() +{} + +chatStatisticsSupergroup::chatStatisticsSupergroup(object_ptr &&period_, object_ptr &&member_count_, object_ptr &&message_count_, object_ptr &&viewer_count_, object_ptr &&sender_count_, object_ptr &&member_count_graph_, object_ptr &&join_graph_, object_ptr &&join_by_source_graph_, object_ptr &&language_graph_, object_ptr &&message_content_graph_, object_ptr &&action_graph_, object_ptr &&day_graph_, object_ptr &&week_graph_, array> &&top_senders_, array> &&top_administrators_, array> &&top_inviters_) + : period_(std::move(period_)) + , member_count_(std::move(member_count_)) + , message_count_(std::move(message_count_)) + , viewer_count_(std::move(viewer_count_)) + , sender_count_(std::move(sender_count_)) + , member_count_graph_(std::move(member_count_graph_)) + , join_graph_(std::move(join_graph_)) + , join_by_source_graph_(std::move(join_by_source_graph_)) + , language_graph_(std::move(language_graph_)) + , message_content_graph_(std::move(message_content_graph_)) + , action_graph_(std::move(action_graph_)) + , day_graph_(std::move(day_graph_)) + , week_graph_(std::move(week_graph_)) + , top_senders_(std::move(top_senders_)) + , top_administrators_(std::move(top_administrators_)) + , top_inviters_(std::move(top_inviters_)) +{} + +const std::int32_t chatStatisticsSupergroup::ID; + +void chatStatisticsSupergroup::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatStatisticsSupergroup"); + s.store_object_field("period", static_cast(period_.get())); + s.store_object_field("member_count", static_cast(member_count_.get())); + s.store_object_field("message_count", static_cast(message_count_.get())); + s.store_object_field("viewer_count", static_cast(viewer_count_.get())); + s.store_object_field("sender_count", static_cast(sender_count_.get())); + s.store_object_field("member_count_graph", static_cast(member_count_graph_.get())); + s.store_object_field("join_graph", static_cast(join_graph_.get())); + s.store_object_field("join_by_source_graph", static_cast(join_by_source_graph_.get())); + s.store_object_field("language_graph", static_cast(language_graph_.get())); + s.store_object_field("message_content_graph", static_cast(message_content_graph_.get())); + s.store_object_field("action_graph", static_cast(action_graph_.get())); + s.store_object_field("day_graph", static_cast(day_graph_.get())); + s.store_object_field("week_graph", static_cast(week_graph_.get())); + { s.store_vector_begin("top_senders", top_senders_.size()); for (const auto &_value : top_senders_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + { s.store_vector_begin("top_administrators", top_administrators_.size()); for (const auto &_value : top_administrators_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + { s.store_vector_begin("top_inviters", top_inviters_.size()); for (const auto &_value : top_inviters_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatStatisticsChannel::chatStatisticsChannel() + : period_() + , member_count_() + , mean_message_view_count_() + , mean_message_share_count_() + , mean_message_reaction_count_() + , mean_story_view_count_() + , mean_story_share_count_() + , mean_story_reaction_count_() + , enabled_notifications_percentage_() + , member_count_graph_() + , join_graph_() + , mute_graph_() + , view_count_by_hour_graph_() + , view_count_by_source_graph_() + , join_by_source_graph_() + , language_graph_() + , message_interaction_graph_() + , message_reaction_graph_() + , story_interaction_graph_() + , story_reaction_graph_() + , instant_view_interaction_graph_() + , recent_interactions_() +{} + +chatStatisticsChannel::chatStatisticsChannel(object_ptr &&period_, object_ptr &&member_count_, object_ptr &&mean_message_view_count_, object_ptr &&mean_message_share_count_, object_ptr &&mean_message_reaction_count_, object_ptr &&mean_story_view_count_, object_ptr &&mean_story_share_count_, object_ptr &&mean_story_reaction_count_, double enabled_notifications_percentage_, object_ptr &&member_count_graph_, object_ptr &&join_graph_, object_ptr &&mute_graph_, object_ptr &&view_count_by_hour_graph_, object_ptr &&view_count_by_source_graph_, object_ptr &&join_by_source_graph_, object_ptr &&language_graph_, object_ptr &&message_interaction_graph_, object_ptr &&message_reaction_graph_, object_ptr &&story_interaction_graph_, object_ptr &&story_reaction_graph_, object_ptr &&instant_view_interaction_graph_, array> &&recent_interactions_) + : period_(std::move(period_)) + , member_count_(std::move(member_count_)) + , mean_message_view_count_(std::move(mean_message_view_count_)) + , mean_message_share_count_(std::move(mean_message_share_count_)) + , mean_message_reaction_count_(std::move(mean_message_reaction_count_)) + , mean_story_view_count_(std::move(mean_story_view_count_)) + , mean_story_share_count_(std::move(mean_story_share_count_)) + , mean_story_reaction_count_(std::move(mean_story_reaction_count_)) + , enabled_notifications_percentage_(enabled_notifications_percentage_) + , member_count_graph_(std::move(member_count_graph_)) + , join_graph_(std::move(join_graph_)) + , mute_graph_(std::move(mute_graph_)) + , view_count_by_hour_graph_(std::move(view_count_by_hour_graph_)) + , view_count_by_source_graph_(std::move(view_count_by_source_graph_)) + , join_by_source_graph_(std::move(join_by_source_graph_)) + , language_graph_(std::move(language_graph_)) + , message_interaction_graph_(std::move(message_interaction_graph_)) + , message_reaction_graph_(std::move(message_reaction_graph_)) + , story_interaction_graph_(std::move(story_interaction_graph_)) + , story_reaction_graph_(std::move(story_reaction_graph_)) + , instant_view_interaction_graph_(std::move(instant_view_interaction_graph_)) + , recent_interactions_(std::move(recent_interactions_)) +{} + +const std::int32_t chatStatisticsChannel::ID; + +void chatStatisticsChannel::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatStatisticsChannel"); + s.store_object_field("period", static_cast(period_.get())); + s.store_object_field("member_count", static_cast(member_count_.get())); + s.store_object_field("mean_message_view_count", static_cast(mean_message_view_count_.get())); + s.store_object_field("mean_message_share_count", static_cast(mean_message_share_count_.get())); + s.store_object_field("mean_message_reaction_count", static_cast(mean_message_reaction_count_.get())); + s.store_object_field("mean_story_view_count", static_cast(mean_story_view_count_.get())); + s.store_object_field("mean_story_share_count", static_cast(mean_story_share_count_.get())); + s.store_object_field("mean_story_reaction_count", static_cast(mean_story_reaction_count_.get())); + s.store_field("enabled_notifications_percentage", enabled_notifications_percentage_); + s.store_object_field("member_count_graph", static_cast(member_count_graph_.get())); + s.store_object_field("join_graph", static_cast(join_graph_.get())); + s.store_object_field("mute_graph", static_cast(mute_graph_.get())); + s.store_object_field("view_count_by_hour_graph", static_cast(view_count_by_hour_graph_.get())); + s.store_object_field("view_count_by_source_graph", static_cast(view_count_by_source_graph_.get())); + s.store_object_field("join_by_source_graph", static_cast(join_by_source_graph_.get())); + s.store_object_field("language_graph", static_cast(language_graph_.get())); + s.store_object_field("message_interaction_graph", static_cast(message_interaction_graph_.get())); + s.store_object_field("message_reaction_graph", static_cast(message_reaction_graph_.get())); + s.store_object_field("story_interaction_graph", static_cast(story_interaction_graph_.get())); + s.store_object_field("story_reaction_graph", static_cast(story_reaction_graph_.get())); + s.store_object_field("instant_view_interaction_graph", static_cast(instant_view_interaction_graph_.get())); + { s.store_vector_begin("recent_interactions", recent_interactions_.size()); for (const auto &_value : recent_interactions_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatStatisticsAdministratorActionsInfo::chatStatisticsAdministratorActionsInfo() + : user_id_() + , deleted_message_count_() + , banned_user_count_() + , restricted_user_count_() +{} + +chatStatisticsAdministratorActionsInfo::chatStatisticsAdministratorActionsInfo(int53 user_id_, int32 deleted_message_count_, int32 banned_user_count_, int32 restricted_user_count_) + : user_id_(user_id_) + , deleted_message_count_(deleted_message_count_) + , banned_user_count_(banned_user_count_) + , restricted_user_count_(restricted_user_count_) +{} + +const std::int32_t chatStatisticsAdministratorActionsInfo::ID; + +void chatStatisticsAdministratorActionsInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatStatisticsAdministratorActionsInfo"); + s.store_field("user_id", user_id_); + s.store_field("deleted_message_count", deleted_message_count_); + s.store_field("banned_user_count", banned_user_count_); + s.store_field("restricted_user_count", restricted_user_count_); + s.store_class_end(); + } +} + +chatStatisticsInteractionInfo::chatStatisticsInteractionInfo() + : object_type_() + , view_count_() + , forward_count_() + , reaction_count_() +{} + +chatStatisticsInteractionInfo::chatStatisticsInteractionInfo(object_ptr &&object_type_, int32 view_count_, int32 forward_count_, int32 reaction_count_) + : object_type_(std::move(object_type_)) + , view_count_(view_count_) + , forward_count_(forward_count_) + , reaction_count_(reaction_count_) +{} + +const std::int32_t chatStatisticsInteractionInfo::ID; + +void chatStatisticsInteractionInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatStatisticsInteractionInfo"); + s.store_object_field("object_type", static_cast(object_type_.get())); + s.store_field("view_count", view_count_); + s.store_field("forward_count", forward_count_); + s.store_field("reaction_count", reaction_count_); + s.store_class_end(); + } +} + +chatStatisticsInviterInfo::chatStatisticsInviterInfo() + : user_id_() + , added_member_count_() +{} + +chatStatisticsInviterInfo::chatStatisticsInviterInfo(int53 user_id_, int32 added_member_count_) + : user_id_(user_id_) + , added_member_count_(added_member_count_) +{} + +const std::int32_t chatStatisticsInviterInfo::ID; + +void chatStatisticsInviterInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatStatisticsInviterInfo"); + s.store_field("user_id", user_id_); + s.store_field("added_member_count", added_member_count_); + s.store_class_end(); + } +} + +chatStatisticsMessageSenderInfo::chatStatisticsMessageSenderInfo() + : user_id_() + , sent_message_count_() + , average_character_count_() +{} + +chatStatisticsMessageSenderInfo::chatStatisticsMessageSenderInfo(int53 user_id_, int32 sent_message_count_, int32 average_character_count_) + : user_id_(user_id_) + , sent_message_count_(sent_message_count_) + , average_character_count_(average_character_count_) +{} + +const std::int32_t chatStatisticsMessageSenderInfo::ID; + +void chatStatisticsMessageSenderInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatStatisticsMessageSenderInfo"); + s.store_field("user_id", user_id_); + s.store_field("sent_message_count", sent_message_count_); + s.store_field("average_character_count", average_character_count_); + s.store_class_end(); + } +} + +chatStatisticsObjectTypeMessage::chatStatisticsObjectTypeMessage() + : message_id_() +{} + +chatStatisticsObjectTypeMessage::chatStatisticsObjectTypeMessage(int53 message_id_) + : message_id_(message_id_) +{} + +const std::int32_t chatStatisticsObjectTypeMessage::ID; + +void chatStatisticsObjectTypeMessage::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatStatisticsObjectTypeMessage"); + s.store_field("message_id", message_id_); + s.store_class_end(); + } +} + +chatStatisticsObjectTypeStory::chatStatisticsObjectTypeStory() + : story_id_() +{} + +chatStatisticsObjectTypeStory::chatStatisticsObjectTypeStory(int32 story_id_) + : story_id_(story_id_) +{} + +const std::int32_t chatStatisticsObjectTypeStory::ID; + +void chatStatisticsObjectTypeStory::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatStatisticsObjectTypeStory"); + s.store_field("story_id", story_id_); + s.store_class_end(); + } +} + +chatTheme::chatTheme() + : name_() + , light_settings_() + , dark_settings_() +{} + +chatTheme::chatTheme(string const &name_, object_ptr &&light_settings_, object_ptr &&dark_settings_) + : name_(name_) + , light_settings_(std::move(light_settings_)) + , dark_settings_(std::move(dark_settings_)) +{} + +const std::int32_t chatTheme::ID; + +void chatTheme::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTheme"); + s.store_field("name", name_); + s.store_object_field("light_settings", static_cast(light_settings_.get())); + s.store_object_field("dark_settings", static_cast(dark_settings_.get())); + s.store_class_end(); + } +} + +chatTransactionPurposePaidMedia::chatTransactionPurposePaidMedia() + : message_id_() + , media_() +{} + +chatTransactionPurposePaidMedia::chatTransactionPurposePaidMedia(int53 message_id_, array> &&media_) + : message_id_(message_id_) + , media_(std::move(media_)) +{} + +const std::int32_t chatTransactionPurposePaidMedia::ID; + +void chatTransactionPurposePaidMedia::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTransactionPurposePaidMedia"); + s.store_field("message_id", message_id_); + { s.store_vector_begin("media", media_.size()); for (const auto &_value : media_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatTransactionPurposeJoin::chatTransactionPurposeJoin() + : period_() +{} + +chatTransactionPurposeJoin::chatTransactionPurposeJoin(int32 period_) + : period_(period_) +{} + +const std::int32_t chatTransactionPurposeJoin::ID; + +void chatTransactionPurposeJoin::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTransactionPurposeJoin"); + s.store_field("period", period_); + s.store_class_end(); + } +} + +chatTransactionPurposeReaction::chatTransactionPurposeReaction() + : message_id_() +{} + +chatTransactionPurposeReaction::chatTransactionPurposeReaction(int53 message_id_) + : message_id_(message_id_) +{} + +const std::int32_t chatTransactionPurposeReaction::ID; + +void chatTransactionPurposeReaction::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTransactionPurposeReaction"); + s.store_field("message_id", message_id_); + s.store_class_end(); + } +} + +chatTransactionPurposeGiveaway::chatTransactionPurposeGiveaway() + : giveaway_message_id_() +{} + +chatTransactionPurposeGiveaway::chatTransactionPurposeGiveaway(int53 giveaway_message_id_) + : giveaway_message_id_(giveaway_message_id_) +{} + +const std::int32_t chatTransactionPurposeGiveaway::ID; + +void chatTransactionPurposeGiveaway::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTransactionPurposeGiveaway"); + s.store_field("giveaway_message_id", giveaway_message_id_); + s.store_class_end(); + } +} + +chatTypePrivate::chatTypePrivate() + : user_id_() +{} + +chatTypePrivate::chatTypePrivate(int53 user_id_) + : user_id_(user_id_) +{} + +const std::int32_t chatTypePrivate::ID; + +void chatTypePrivate::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTypePrivate"); + s.store_field("user_id", user_id_); + s.store_class_end(); + } +} + +chatTypeBasicGroup::chatTypeBasicGroup() + : basic_group_id_() +{} + +chatTypeBasicGroup::chatTypeBasicGroup(int53 basic_group_id_) + : basic_group_id_(basic_group_id_) +{} + +const std::int32_t chatTypeBasicGroup::ID; + +void chatTypeBasicGroup::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTypeBasicGroup"); + s.store_field("basic_group_id", basic_group_id_); + s.store_class_end(); + } +} + +chatTypeSupergroup::chatTypeSupergroup() + : supergroup_id_() + , is_channel_() +{} + +chatTypeSupergroup::chatTypeSupergroup(int53 supergroup_id_, bool is_channel_) + : supergroup_id_(supergroup_id_) + , is_channel_(is_channel_) +{} + +const std::int32_t chatTypeSupergroup::ID; + +void chatTypeSupergroup::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTypeSupergroup"); + s.store_field("supergroup_id", supergroup_id_); + s.store_field("is_channel", is_channel_); + s.store_class_end(); + } +} + +chatTypeSecret::chatTypeSecret() + : secret_chat_id_() + , user_id_() +{} + +chatTypeSecret::chatTypeSecret(int32 secret_chat_id_, int53 user_id_) + : secret_chat_id_(secret_chat_id_) + , user_id_(user_id_) +{} + +const std::int32_t chatTypeSecret::ID; + +void chatTypeSecret::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatTypeSecret"); + s.store_field("secret_chat_id", secret_chat_id_); + s.store_field("user_id", user_id_); + s.store_class_end(); + } +} + +chats::chats() + : total_count_() + , chat_ids_() +{} + +chats::chats(int32 total_count_, array &&chat_ids_) + : total_count_(total_count_) + , chat_ids_(std::move(chat_ids_)) +{} + +const std::int32_t chats::ID; + +void chats::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chats"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("chat_ids", chat_ids_.size()); for (const auto &_value : chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +chatsNearby::chatsNearby() + : users_nearby_() + , supergroups_nearby_() +{} + +chatsNearby::chatsNearby(array> &&users_nearby_, array> &&supergroups_nearby_) + : users_nearby_(std::move(users_nearby_)) + , supergroups_nearby_(std::move(supergroups_nearby_)) +{} + +const std::int32_t chatsNearby::ID; + +void chatsNearby::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "chatsNearby"); + { s.store_vector_begin("users_nearby", users_nearby_.size()); for (const auto &_value : users_nearby_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + { s.store_vector_begin("supergroups_nearby", supergroups_nearby_.size()); for (const auto &_value : supergroups_nearby_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +checkChatUsernameResultOk::checkChatUsernameResultOk() { +} + +const std::int32_t checkChatUsernameResultOk::ID; + +void checkChatUsernameResultOk::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkChatUsernameResultOk"); + s.store_class_end(); + } +} + +checkChatUsernameResultUsernameInvalid::checkChatUsernameResultUsernameInvalid() { +} + +const std::int32_t checkChatUsernameResultUsernameInvalid::ID; + +void checkChatUsernameResultUsernameInvalid::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkChatUsernameResultUsernameInvalid"); + s.store_class_end(); + } +} + +checkChatUsernameResultUsernameOccupied::checkChatUsernameResultUsernameOccupied() { +} + +const std::int32_t checkChatUsernameResultUsernameOccupied::ID; + +void checkChatUsernameResultUsernameOccupied::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkChatUsernameResultUsernameOccupied"); + s.store_class_end(); + } +} + +checkChatUsernameResultUsernamePurchasable::checkChatUsernameResultUsernamePurchasable() { +} + +const std::int32_t checkChatUsernameResultUsernamePurchasable::ID; + +void checkChatUsernameResultUsernamePurchasable::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkChatUsernameResultUsernamePurchasable"); + s.store_class_end(); + } +} + +checkChatUsernameResultPublicChatsTooMany::checkChatUsernameResultPublicChatsTooMany() { +} + +const std::int32_t checkChatUsernameResultPublicChatsTooMany::ID; + +void checkChatUsernameResultPublicChatsTooMany::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkChatUsernameResultPublicChatsTooMany"); + s.store_class_end(); + } +} + +checkChatUsernameResultPublicGroupsUnavailable::checkChatUsernameResultPublicGroupsUnavailable() { +} + +const std::int32_t checkChatUsernameResultPublicGroupsUnavailable::ID; + +void checkChatUsernameResultPublicGroupsUnavailable::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkChatUsernameResultPublicGroupsUnavailable"); + s.store_class_end(); + } +} + +checkStickerSetNameResultOk::checkStickerSetNameResultOk() { +} + +const std::int32_t checkStickerSetNameResultOk::ID; + +void checkStickerSetNameResultOk::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkStickerSetNameResultOk"); + s.store_class_end(); + } +} + +checkStickerSetNameResultNameInvalid::checkStickerSetNameResultNameInvalid() { +} + +const std::int32_t checkStickerSetNameResultNameInvalid::ID; + +void checkStickerSetNameResultNameInvalid::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkStickerSetNameResultNameInvalid"); + s.store_class_end(); + } +} + +checkStickerSetNameResultNameOccupied::checkStickerSetNameResultNameOccupied() { +} + +const std::int32_t checkStickerSetNameResultNameOccupied::ID; + +void checkStickerSetNameResultNameOccupied::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "checkStickerSetNameResultNameOccupied"); + s.store_class_end(); + } +} + +closeBirthdayUser::closeBirthdayUser() + : user_id_() + , birthdate_() +{} + +closeBirthdayUser::closeBirthdayUser(int53 user_id_, object_ptr &&birthdate_) + : user_id_(user_id_) + , birthdate_(std::move(birthdate_)) +{} + +const std::int32_t closeBirthdayUser::ID; + +void closeBirthdayUser::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "closeBirthdayUser"); + s.store_field("user_id", user_id_); + s.store_object_field("birthdate", static_cast(birthdate_.get())); + s.store_class_end(); + } +} + +closedVectorPath::closedVectorPath() + : commands_() +{} + +closedVectorPath::closedVectorPath(array> &&commands_) + : commands_(std::move(commands_)) +{} + +const std::int32_t closedVectorPath::ID; + +void closedVectorPath::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "closedVectorPath"); + { s.store_vector_begin("commands", commands_.size()); for (const auto &_value : commands_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +collectibleItemInfo::collectibleItemInfo() + : purchase_date_() + , currency_() + , amount_() + , cryptocurrency_() + , cryptocurrency_amount_() + , url_() +{} + +collectibleItemInfo::collectibleItemInfo(int32 purchase_date_, string const ¤cy_, int53 amount_, string const &cryptocurrency_, int64 cryptocurrency_amount_, string const &url_) + : purchase_date_(purchase_date_) + , currency_(currency_) + , amount_(amount_) + , cryptocurrency_(cryptocurrency_) + , cryptocurrency_amount_(cryptocurrency_amount_) + , url_(url_) +{} + +const std::int32_t collectibleItemInfo::ID; + +void collectibleItemInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "collectibleItemInfo"); + s.store_field("purchase_date", purchase_date_); + s.store_field("currency", currency_); + s.store_field("amount", amount_); + s.store_field("cryptocurrency", cryptocurrency_); + s.store_field("cryptocurrency_amount", cryptocurrency_amount_); + s.store_field("url", url_); + s.store_class_end(); + } +} + +collectibleItemTypeUsername::collectibleItemTypeUsername() + : username_() +{} + +collectibleItemTypeUsername::collectibleItemTypeUsername(string const &username_) + : username_(username_) +{} + +const std::int32_t collectibleItemTypeUsername::ID; + +void collectibleItemTypeUsername::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "collectibleItemTypeUsername"); + s.store_field("username", username_); + s.store_class_end(); + } +} + +collectibleItemTypePhoneNumber::collectibleItemTypePhoneNumber() + : phone_number_() +{} + +collectibleItemTypePhoneNumber::collectibleItemTypePhoneNumber(string const &phone_number_) + : phone_number_(phone_number_) +{} + +const std::int32_t collectibleItemTypePhoneNumber::ID; + +void collectibleItemTypePhoneNumber::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "collectibleItemTypePhoneNumber"); + s.store_field("phone_number", phone_number_); + s.store_class_end(); + } +} + +connectedWebsite::connectedWebsite() + : id_() + , domain_name_() + , bot_user_id_() + , browser_() + , platform_() + , log_in_date_() + , last_active_date_() + , ip_address_() + , location_() +{} + +connectedWebsite::connectedWebsite(int64 id_, string const &domain_name_, int53 bot_user_id_, string const &browser_, string const &platform_, int32 log_in_date_, int32 last_active_date_, string const &ip_address_, string const &location_) + : id_(id_) + , domain_name_(domain_name_) + , bot_user_id_(bot_user_id_) + , browser_(browser_) + , platform_(platform_) + , log_in_date_(log_in_date_) + , last_active_date_(last_active_date_) + , ip_address_(ip_address_) + , location_(location_) +{} + +const std::int32_t connectedWebsite::ID; + +void connectedWebsite::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "connectedWebsite"); + s.store_field("id", id_); + s.store_field("domain_name", domain_name_); + s.store_field("bot_user_id", bot_user_id_); + s.store_field("browser", browser_); + s.store_field("platform", platform_); + s.store_field("log_in_date", log_in_date_); + s.store_field("last_active_date", last_active_date_); + s.store_field("ip_address", ip_address_); + s.store_field("location", location_); + s.store_class_end(); + } +} + +connectedWebsites::connectedWebsites() + : websites_() +{} + +connectedWebsites::connectedWebsites(array> &&websites_) + : websites_(std::move(websites_)) +{} + +const std::int32_t connectedWebsites::ID; + +void connectedWebsites::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "connectedWebsites"); + { s.store_vector_begin("websites", websites_.size()); for (const auto &_value : websites_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +connectionStateWaitingForNetwork::connectionStateWaitingForNetwork() { +} + +const std::int32_t connectionStateWaitingForNetwork::ID; + +void connectionStateWaitingForNetwork::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "connectionStateWaitingForNetwork"); + s.store_class_end(); + } +} + +connectionStateConnectingToProxy::connectionStateConnectingToProxy() { +} + +const std::int32_t connectionStateConnectingToProxy::ID; + +void connectionStateConnectingToProxy::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "connectionStateConnectingToProxy"); + s.store_class_end(); + } +} + +connectionStateConnecting::connectionStateConnecting() { +} + +const std::int32_t connectionStateConnecting::ID; + +void connectionStateConnecting::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "connectionStateConnecting"); + s.store_class_end(); + } +} + +connectionStateUpdating::connectionStateUpdating() { +} + +const std::int32_t connectionStateUpdating::ID; + +void connectionStateUpdating::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "connectionStateUpdating"); + s.store_class_end(); + } +} + +connectionStateReady::connectionStateReady() { +} + +const std::int32_t connectionStateReady::ID; + +void connectionStateReady::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "connectionStateReady"); + s.store_class_end(); + } +} + +contact::contact() + : phone_number_() + , first_name_() + , last_name_() + , vcard_() + , user_id_() +{} + +contact::contact(string const &phone_number_, string const &first_name_, string const &last_name_, string const &vcard_, int53 user_id_) + : phone_number_(phone_number_) + , first_name_(first_name_) + , last_name_(last_name_) + , vcard_(vcard_) + , user_id_(user_id_) +{} + +const std::int32_t contact::ID; + +void contact::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "contact"); + s.store_field("phone_number", phone_number_); + s.store_field("first_name", first_name_); + s.store_field("last_name", last_name_); + s.store_field("vcard", vcard_); + s.store_field("user_id", user_id_); + s.store_class_end(); + } +} + +count::count() + : count_() +{} + +count::count(int32 count_) + : count_(count_) +{} + +const std::int32_t count::ID; + +void count::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "count"); + s.store_field("count", count_); + s.store_class_end(); + } +} + +countries::countries() + : countries_() +{} + +countries::countries(array> &&countries_) + : countries_(std::move(countries_)) +{} + +const std::int32_t countries::ID; + +void countries::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "countries"); + { s.store_vector_begin("countries", countries_.size()); for (const auto &_value : countries_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +countryInfo::countryInfo() + : country_code_() + , name_() + , english_name_() + , is_hidden_() + , calling_codes_() +{} + +countryInfo::countryInfo(string const &country_code_, string const &name_, string const &english_name_, bool is_hidden_, array &&calling_codes_) + : country_code_(country_code_) + , name_(name_) + , english_name_(english_name_) + , is_hidden_(is_hidden_) + , calling_codes_(std::move(calling_codes_)) +{} + +const std::int32_t countryInfo::ID; + +void countryInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "countryInfo"); + s.store_field("country_code", country_code_); + s.store_field("name", name_); + s.store_field("english_name", english_name_); + s.store_field("is_hidden", is_hidden_); + { s.store_vector_begin("calling_codes", calling_codes_.size()); for (const auto &_value : calling_codes_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +createdBasicGroupChat::createdBasicGroupChat() + : chat_id_() + , failed_to_add_members_() +{} + +createdBasicGroupChat::createdBasicGroupChat(int53 chat_id_, object_ptr &&failed_to_add_members_) + : chat_id_(chat_id_) + , failed_to_add_members_(std::move(failed_to_add_members_)) +{} + +const std::int32_t createdBasicGroupChat::ID; + +void createdBasicGroupChat::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "createdBasicGroupChat"); + s.store_field("chat_id", chat_id_); + s.store_object_field("failed_to_add_members", static_cast(failed_to_add_members_.get())); + s.store_class_end(); + } +} + +currentWeather::currentWeather() + : temperature_() + , emoji_() +{} + +currentWeather::currentWeather(double temperature_, string const &emoji_) + : temperature_(temperature_) + , emoji_(emoji_) +{} + +const std::int32_t currentWeather::ID; + +void currentWeather::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "currentWeather"); + s.store_field("temperature", temperature_); + s.store_field("emoji", emoji_); + s.store_class_end(); + } +} + +customRequestResult::customRequestResult() + : result_() +{} + +customRequestResult::customRequestResult(string const &result_) + : result_(result_) +{} + +const std::int32_t customRequestResult::ID; + +void customRequestResult::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "customRequestResult"); + s.store_field("result", result_); + s.store_class_end(); + } +} + +databaseStatistics::databaseStatistics() + : statistics_() +{} + +databaseStatistics::databaseStatistics(string const &statistics_) + : statistics_(statistics_) +{} + +const std::int32_t databaseStatistics::ID; + +void databaseStatistics::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "databaseStatistics"); + s.store_field("statistics", statistics_); + s.store_class_end(); + } +} + +date::date() + : day_() + , month_() + , year_() +{} + +date::date(int32 day_, int32 month_, int32 year_) + : day_(day_) + , month_(month_) + , year_(year_) +{} + +const std::int32_t date::ID; + +void date::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "date"); + s.store_field("day", day_); + s.store_field("month", month_); + s.store_field("year", year_); + s.store_class_end(); + } +} + +dateRange::dateRange() + : start_date_() + , end_date_() +{} + +dateRange::dateRange(int32 start_date_, int32 end_date_) + : start_date_(start_date_) + , end_date_(end_date_) +{} + +const std::int32_t dateRange::ID; + +void dateRange::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "dateRange"); + s.store_field("start_date", start_date_); + s.store_field("end_date", end_date_); + s.store_class_end(); + } +} + +datedFile::datedFile() + : file_() + , date_() +{} + +datedFile::datedFile(object_ptr &&file_, int32 date_) + : file_(std::move(file_)) + , date_(date_) +{} + +const std::int32_t datedFile::ID; + +void datedFile::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "datedFile"); + s.store_object_field("file", static_cast(file_.get())); + s.store_field("date", date_); + s.store_class_end(); + } +} + +deepLinkInfo::deepLinkInfo() + : text_() + , need_update_application_() +{} + +deepLinkInfo::deepLinkInfo(object_ptr &&text_, bool need_update_application_) + : text_(std::move(text_)) + , need_update_application_(need_update_application_) +{} + +const std::int32_t deepLinkInfo::ID; + +void deepLinkInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deepLinkInfo"); + s.store_object_field("text", static_cast(text_.get())); + s.store_field("need_update_application", need_update_application_); + s.store_class_end(); + } +} + +deviceTokenFirebaseCloudMessaging::deviceTokenFirebaseCloudMessaging() + : token_() + , encrypt_() +{} + +deviceTokenFirebaseCloudMessaging::deviceTokenFirebaseCloudMessaging(string const &token_, bool encrypt_) + : token_(token_) + , encrypt_(encrypt_) +{} + +const std::int32_t deviceTokenFirebaseCloudMessaging::ID; + +void deviceTokenFirebaseCloudMessaging::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenFirebaseCloudMessaging"); + s.store_field("token", token_); + s.store_field("encrypt", encrypt_); + s.store_class_end(); + } +} + +deviceTokenApplePush::deviceTokenApplePush() + : device_token_() + , is_app_sandbox_() +{} + +deviceTokenApplePush::deviceTokenApplePush(string const &device_token_, bool is_app_sandbox_) + : device_token_(device_token_) + , is_app_sandbox_(is_app_sandbox_) +{} + +const std::int32_t deviceTokenApplePush::ID; + +void deviceTokenApplePush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenApplePush"); + s.store_field("device_token", device_token_); + s.store_field("is_app_sandbox", is_app_sandbox_); + s.store_class_end(); + } +} + +deviceTokenApplePushVoIP::deviceTokenApplePushVoIP() + : device_token_() + , is_app_sandbox_() + , encrypt_() +{} + +deviceTokenApplePushVoIP::deviceTokenApplePushVoIP(string const &device_token_, bool is_app_sandbox_, bool encrypt_) + : device_token_(device_token_) + , is_app_sandbox_(is_app_sandbox_) + , encrypt_(encrypt_) +{} + +const std::int32_t deviceTokenApplePushVoIP::ID; + +void deviceTokenApplePushVoIP::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenApplePushVoIP"); + s.store_field("device_token", device_token_); + s.store_field("is_app_sandbox", is_app_sandbox_); + s.store_field("encrypt", encrypt_); + s.store_class_end(); + } +} + +deviceTokenWindowsPush::deviceTokenWindowsPush() + : access_token_() +{} + +deviceTokenWindowsPush::deviceTokenWindowsPush(string const &access_token_) + : access_token_(access_token_) +{} + +const std::int32_t deviceTokenWindowsPush::ID; + +void deviceTokenWindowsPush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenWindowsPush"); + s.store_field("access_token", access_token_); + s.store_class_end(); + } +} + +deviceTokenMicrosoftPush::deviceTokenMicrosoftPush() + : channel_uri_() +{} + +deviceTokenMicrosoftPush::deviceTokenMicrosoftPush(string const &channel_uri_) + : channel_uri_(channel_uri_) +{} + +const std::int32_t deviceTokenMicrosoftPush::ID; + +void deviceTokenMicrosoftPush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenMicrosoftPush"); + s.store_field("channel_uri", channel_uri_); + s.store_class_end(); + } +} + +deviceTokenMicrosoftPushVoIP::deviceTokenMicrosoftPushVoIP() + : channel_uri_() +{} + +deviceTokenMicrosoftPushVoIP::deviceTokenMicrosoftPushVoIP(string const &channel_uri_) + : channel_uri_(channel_uri_) +{} + +const std::int32_t deviceTokenMicrosoftPushVoIP::ID; + +void deviceTokenMicrosoftPushVoIP::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenMicrosoftPushVoIP"); + s.store_field("channel_uri", channel_uri_); + s.store_class_end(); + } +} + +deviceTokenWebPush::deviceTokenWebPush() + : endpoint_() + , p256dh_base64url_() + , auth_base64url_() +{} + +deviceTokenWebPush::deviceTokenWebPush(string const &endpoint_, string const &p256dh_base64url_, string const &auth_base64url_) + : endpoint_(endpoint_) + , p256dh_base64url_(p256dh_base64url_) + , auth_base64url_(auth_base64url_) +{} + +const std::int32_t deviceTokenWebPush::ID; + +void deviceTokenWebPush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenWebPush"); + s.store_field("endpoint", endpoint_); + s.store_field("p256dh_base64url", p256dh_base64url_); + s.store_field("auth_base64url", auth_base64url_); + s.store_class_end(); + } +} + +deviceTokenSimplePush::deviceTokenSimplePush() + : endpoint_() +{} + +deviceTokenSimplePush::deviceTokenSimplePush(string const &endpoint_) + : endpoint_(endpoint_) +{} + +const std::int32_t deviceTokenSimplePush::ID; + +void deviceTokenSimplePush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenSimplePush"); + s.store_field("endpoint", endpoint_); + s.store_class_end(); + } +} + +deviceTokenUbuntuPush::deviceTokenUbuntuPush() + : token_() +{} + +deviceTokenUbuntuPush::deviceTokenUbuntuPush(string const &token_) + : token_(token_) +{} + +const std::int32_t deviceTokenUbuntuPush::ID; + +void deviceTokenUbuntuPush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenUbuntuPush"); + s.store_field("token", token_); + s.store_class_end(); + } +} + +deviceTokenBlackBerryPush::deviceTokenBlackBerryPush() + : token_() +{} + +deviceTokenBlackBerryPush::deviceTokenBlackBerryPush(string const &token_) + : token_(token_) +{} + +const std::int32_t deviceTokenBlackBerryPush::ID; + +void deviceTokenBlackBerryPush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenBlackBerryPush"); + s.store_field("token", token_); + s.store_class_end(); + } +} + +deviceTokenTizenPush::deviceTokenTizenPush() + : reg_id_() +{} + +deviceTokenTizenPush::deviceTokenTizenPush(string const ®_id_) + : reg_id_(reg_id_) +{} + +const std::int32_t deviceTokenTizenPush::ID; + +void deviceTokenTizenPush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenTizenPush"); + s.store_field("reg_id", reg_id_); + s.store_class_end(); + } +} + +deviceTokenHuaweiPush::deviceTokenHuaweiPush() + : token_() + , encrypt_() +{} + +deviceTokenHuaweiPush::deviceTokenHuaweiPush(string const &token_, bool encrypt_) + : token_(token_) + , encrypt_(encrypt_) +{} + +const std::int32_t deviceTokenHuaweiPush::ID; + +void deviceTokenHuaweiPush::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "deviceTokenHuaweiPush"); + s.store_field("token", token_); + s.store_field("encrypt", encrypt_); + s.store_class_end(); + } +} + +diceStickersRegular::diceStickersRegular() + : sticker_() +{} + +diceStickersRegular::diceStickersRegular(object_ptr &&sticker_) + : sticker_(std::move(sticker_)) +{} + +const std::int32_t diceStickersRegular::ID; + +void diceStickersRegular::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "diceStickersRegular"); + s.store_object_field("sticker", static_cast(sticker_.get())); + s.store_class_end(); + } +} + +diceStickersSlotMachine::diceStickersSlotMachine() + : background_() + , lever_() + , left_reel_() + , center_reel_() + , right_reel_() +{} + +diceStickersSlotMachine::diceStickersSlotMachine(object_ptr &&background_, object_ptr &&lever_, object_ptr &&left_reel_, object_ptr &¢er_reel_, object_ptr &&right_reel_) + : background_(std::move(background_)) + , lever_(std::move(lever_)) + , left_reel_(std::move(left_reel_)) + , center_reel_(std::move(center_reel_)) + , right_reel_(std::move(right_reel_)) +{} + +const std::int32_t diceStickersSlotMachine::ID; + +void diceStickersSlotMachine::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "diceStickersSlotMachine"); + s.store_object_field("background", static_cast(background_.get())); + s.store_object_field("lever", static_cast(lever_.get())); + s.store_object_field("left_reel", static_cast(left_reel_.get())); + s.store_object_field("center_reel", static_cast(center_reel_.get())); + s.store_object_field("right_reel", static_cast(right_reel_.get())); + s.store_class_end(); + } +} + +document::document() + : file_name_() + , mime_type_() + , minithumbnail_() + , thumbnail_() + , document_() +{} + +document::document(string const &file_name_, string const &mime_type_, object_ptr &&minithumbnail_, object_ptr &&thumbnail_, object_ptr &&document_) + : file_name_(file_name_) + , mime_type_(mime_type_) + , minithumbnail_(std::move(minithumbnail_)) + , thumbnail_(std::move(thumbnail_)) + , document_(std::move(document_)) +{} + +const std::int32_t document::ID; + +void document::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "document"); + s.store_field("file_name", file_name_); + s.store_field("mime_type", mime_type_); + s.store_object_field("minithumbnail", static_cast(minithumbnail_.get())); + s.store_object_field("thumbnail", static_cast(thumbnail_.get())); + s.store_object_field("document", static_cast(document_.get())); + s.store_class_end(); + } +} + +downloadedFileCounts::downloadedFileCounts() + : active_count_() + , paused_count_() + , completed_count_() +{} + +downloadedFileCounts::downloadedFileCounts(int32 active_count_, int32 paused_count_, int32 completed_count_) + : active_count_(active_count_) + , paused_count_(paused_count_) + , completed_count_(completed_count_) +{} + +const std::int32_t downloadedFileCounts::ID; + +void downloadedFileCounts::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "downloadedFileCounts"); + s.store_field("active_count", active_count_); + s.store_field("paused_count", paused_count_); + s.store_field("completed_count", completed_count_); + s.store_class_end(); + } +} + +draftMessage::draftMessage() + : reply_to_() + , date_() + , input_message_text_() + , effect_id_() +{} + +draftMessage::draftMessage(object_ptr &&reply_to_, int32 date_, object_ptr &&input_message_text_, int64 effect_id_) + : reply_to_(std::move(reply_to_)) + , date_(date_) + , input_message_text_(std::move(input_message_text_)) + , effect_id_(effect_id_) +{} + +const std::int32_t draftMessage::ID; + +void draftMessage::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "draftMessage"); + s.store_object_field("reply_to", static_cast(reply_to_.get())); + s.store_field("date", date_); + s.store_object_field("input_message_text", static_cast(input_message_text_.get())); + s.store_field("effect_id", effect_id_); + s.store_class_end(); + } +} + +emailAddressAuthenticationCode::emailAddressAuthenticationCode() + : code_() +{} + +emailAddressAuthenticationCode::emailAddressAuthenticationCode(string const &code_) + : code_(code_) +{} + +const std::int32_t emailAddressAuthenticationCode::ID; + +void emailAddressAuthenticationCode::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emailAddressAuthenticationCode"); + s.store_field("code", code_); + s.store_class_end(); + } +} + +emailAddressAuthenticationAppleId::emailAddressAuthenticationAppleId() + : token_() +{} + +emailAddressAuthenticationAppleId::emailAddressAuthenticationAppleId(string const &token_) + : token_(token_) +{} + +const std::int32_t emailAddressAuthenticationAppleId::ID; + +void emailAddressAuthenticationAppleId::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emailAddressAuthenticationAppleId"); + s.store_field("token", token_); + s.store_class_end(); + } +} + +emailAddressAuthenticationGoogleId::emailAddressAuthenticationGoogleId() + : token_() +{} + +emailAddressAuthenticationGoogleId::emailAddressAuthenticationGoogleId(string const &token_) + : token_(token_) +{} + +const std::int32_t emailAddressAuthenticationGoogleId::ID; + +void emailAddressAuthenticationGoogleId::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emailAddressAuthenticationGoogleId"); + s.store_field("token", token_); + s.store_class_end(); + } +} + +emailAddressAuthenticationCodeInfo::emailAddressAuthenticationCodeInfo() + : email_address_pattern_() + , length_() +{} + +emailAddressAuthenticationCodeInfo::emailAddressAuthenticationCodeInfo(string const &email_address_pattern_, int32 length_) + : email_address_pattern_(email_address_pattern_) + , length_(length_) +{} + +const std::int32_t emailAddressAuthenticationCodeInfo::ID; + +void emailAddressAuthenticationCodeInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emailAddressAuthenticationCodeInfo"); + s.store_field("email_address_pattern", email_address_pattern_); + s.store_field("length", length_); + s.store_class_end(); + } +} + +emailAddressResetStateAvailable::emailAddressResetStateAvailable() + : wait_period_() +{} + +emailAddressResetStateAvailable::emailAddressResetStateAvailable(int32 wait_period_) + : wait_period_(wait_period_) +{} + +const std::int32_t emailAddressResetStateAvailable::ID; + +void emailAddressResetStateAvailable::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emailAddressResetStateAvailable"); + s.store_field("wait_period", wait_period_); + s.store_class_end(); + } +} + +emailAddressResetStatePending::emailAddressResetStatePending() + : reset_in_() +{} + +emailAddressResetStatePending::emailAddressResetStatePending(int32 reset_in_) + : reset_in_(reset_in_) +{} + +const std::int32_t emailAddressResetStatePending::ID; + +void emailAddressResetStatePending::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emailAddressResetStatePending"); + s.store_field("reset_in", reset_in_); + s.store_class_end(); + } +} + +emojiCategories::emojiCategories() + : categories_() +{} + +emojiCategories::emojiCategories(array> &&categories_) + : categories_(std::move(categories_)) +{} + +const std::int32_t emojiCategories::ID; + +void emojiCategories::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiCategories"); + { s.store_vector_begin("categories", categories_.size()); for (const auto &_value : categories_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +emojiCategory::emojiCategory() + : name_() + , icon_() + , source_() + , is_greeting_() +{} + +emojiCategory::emojiCategory(string const &name_, object_ptr &&icon_, object_ptr &&source_, bool is_greeting_) + : name_(name_) + , icon_(std::move(icon_)) + , source_(std::move(source_)) + , is_greeting_(is_greeting_) +{} + +const std::int32_t emojiCategory::ID; + +void emojiCategory::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiCategory"); + s.store_field("name", name_); + s.store_object_field("icon", static_cast(icon_.get())); + s.store_object_field("source", static_cast(source_.get())); + s.store_field("is_greeting", is_greeting_); + s.store_class_end(); + } +} + +emojiCategorySourceSearch::emojiCategorySourceSearch() + : emojis_() +{} + +emojiCategorySourceSearch::emojiCategorySourceSearch(array &&emojis_) + : emojis_(std::move(emojis_)) +{} + +const std::int32_t emojiCategorySourceSearch::ID; + +void emojiCategorySourceSearch::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiCategorySourceSearch"); + { s.store_vector_begin("emojis", emojis_.size()); for (const auto &_value : emojis_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +emojiCategorySourcePremium::emojiCategorySourcePremium() { +} + +const std::int32_t emojiCategorySourcePremium::ID; + +void emojiCategorySourcePremium::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiCategorySourcePremium"); + s.store_class_end(); + } +} + +emojiCategoryTypeDefault::emojiCategoryTypeDefault() { +} + +const std::int32_t emojiCategoryTypeDefault::ID; + +void emojiCategoryTypeDefault::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiCategoryTypeDefault"); + s.store_class_end(); + } +} + +emojiCategoryTypeRegularStickers::emojiCategoryTypeRegularStickers() { +} + +const std::int32_t emojiCategoryTypeRegularStickers::ID; + +void emojiCategoryTypeRegularStickers::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiCategoryTypeRegularStickers"); + s.store_class_end(); + } +} + +emojiCategoryTypeEmojiStatus::emojiCategoryTypeEmojiStatus() { +} + +const std::int32_t emojiCategoryTypeEmojiStatus::ID; + +void emojiCategoryTypeEmojiStatus::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiCategoryTypeEmojiStatus"); + s.store_class_end(); + } +} + +emojiCategoryTypeChatPhoto::emojiCategoryTypeChatPhoto() { +} + +const std::int32_t emojiCategoryTypeChatPhoto::ID; + +void emojiCategoryTypeChatPhoto::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiCategoryTypeChatPhoto"); + s.store_class_end(); + } +} + +emojiKeyword::emojiKeyword() + : emoji_() + , keyword_() +{} + +emojiKeyword::emojiKeyword(string const &emoji_, string const &keyword_) + : emoji_(emoji_) + , keyword_(keyword_) +{} + +const std::int32_t emojiKeyword::ID; + +void emojiKeyword::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiKeyword"); + s.store_field("emoji", emoji_); + s.store_field("keyword", keyword_); + s.store_class_end(); + } +} + +emojiKeywords::emojiKeywords() + : emoji_keywords_() +{} + +emojiKeywords::emojiKeywords(array> &&emoji_keywords_) + : emoji_keywords_(std::move(emoji_keywords_)) +{} + +const std::int32_t emojiKeywords::ID; + +void emojiKeywords::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiKeywords"); + { s.store_vector_begin("emoji_keywords", emoji_keywords_.size()); for (const auto &_value : emoji_keywords_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +emojiReaction::emojiReaction() + : emoji_() + , title_() + , is_active_() + , static_icon_() + , appear_animation_() + , select_animation_() + , activate_animation_() + , effect_animation_() + , around_animation_() + , center_animation_() +{} + +emojiReaction::emojiReaction(string const &emoji_, string const &title_, bool is_active_, object_ptr &&static_icon_, object_ptr &&appear_animation_, object_ptr &&select_animation_, object_ptr &&activate_animation_, object_ptr &&effect_animation_, object_ptr &&around_animation_, object_ptr &¢er_animation_) + : emoji_(emoji_) + , title_(title_) + , is_active_(is_active_) + , static_icon_(std::move(static_icon_)) + , appear_animation_(std::move(appear_animation_)) + , select_animation_(std::move(select_animation_)) + , activate_animation_(std::move(activate_animation_)) + , effect_animation_(std::move(effect_animation_)) + , around_animation_(std::move(around_animation_)) + , center_animation_(std::move(center_animation_)) +{} + +const std::int32_t emojiReaction::ID; + +void emojiReaction::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiReaction"); + s.store_field("emoji", emoji_); + s.store_field("title", title_); + s.store_field("is_active", is_active_); + s.store_object_field("static_icon", static_cast(static_icon_.get())); + s.store_object_field("appear_animation", static_cast(appear_animation_.get())); + s.store_object_field("select_animation", static_cast(select_animation_.get())); + s.store_object_field("activate_animation", static_cast(activate_animation_.get())); + s.store_object_field("effect_animation", static_cast(effect_animation_.get())); + s.store_object_field("around_animation", static_cast(around_animation_.get())); + s.store_object_field("center_animation", static_cast(center_animation_.get())); + s.store_class_end(); + } +} + +emojiStatus::emojiStatus() + : custom_emoji_id_() + , expiration_date_() +{} + +emojiStatus::emojiStatus(int64 custom_emoji_id_, int32 expiration_date_) + : custom_emoji_id_(custom_emoji_id_) + , expiration_date_(expiration_date_) +{} + +const std::int32_t emojiStatus::ID; + +void emojiStatus::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiStatus"); + s.store_field("custom_emoji_id", custom_emoji_id_); + s.store_field("expiration_date", expiration_date_); + s.store_class_end(); + } +} + +emojiStatuses::emojiStatuses() + : custom_emoji_ids_() +{} + +emojiStatuses::emojiStatuses(array &&custom_emoji_ids_) + : custom_emoji_ids_(std::move(custom_emoji_ids_)) +{} + +const std::int32_t emojiStatuses::ID; + +void emojiStatuses::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojiStatuses"); + { s.store_vector_begin("custom_emoji_ids", custom_emoji_ids_.size()); for (const auto &_value : custom_emoji_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +emojis::emojis() + : emojis_() +{} + +emojis::emojis(array &&emojis_) + : emojis_(std::move(emojis_)) +{} + +const std::int32_t emojis::ID; + +void emojis::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "emojis"); + { s.store_vector_begin("emojis", emojis_.size()); for (const auto &_value : emojis_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +encryptedCredentials::encryptedCredentials() + : data_() + , hash_() + , secret_() +{} + +encryptedCredentials::encryptedCredentials(bytes const &data_, bytes const &hash_, bytes const &secret_) + : data_(std::move(data_)) + , hash_(std::move(hash_)) + , secret_(std::move(secret_)) +{} + +const std::int32_t encryptedCredentials::ID; + +void encryptedCredentials::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "encryptedCredentials"); + s.store_bytes_field("data", data_); + s.store_bytes_field("hash", hash_); + s.store_bytes_field("secret", secret_); + s.store_class_end(); + } +} + +encryptedPassportElement::encryptedPassportElement() + : type_() + , data_() + , front_side_() + , reverse_side_() + , selfie_() + , translation_() + , files_() + , value_() + , hash_() +{} + +encryptedPassportElement::encryptedPassportElement(object_ptr &&type_, bytes const &data_, object_ptr &&front_side_, object_ptr &&reverse_side_, object_ptr &&selfie_, array> &&translation_, array> &&files_, string const &value_, string const &hash_) + : type_(std::move(type_)) + , data_(std::move(data_)) + , front_side_(std::move(front_side_)) + , reverse_side_(std::move(reverse_side_)) + , selfie_(std::move(selfie_)) + , translation_(std::move(translation_)) + , files_(std::move(files_)) + , value_(value_) + , hash_(hash_) +{} + +const std::int32_t encryptedPassportElement::ID; + +void encryptedPassportElement::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "encryptedPassportElement"); + s.store_object_field("type", static_cast(type_.get())); + s.store_bytes_field("data", data_); + s.store_object_field("front_side", static_cast(front_side_.get())); + s.store_object_field("reverse_side", static_cast(reverse_side_.get())); + s.store_object_field("selfie", static_cast(selfie_.get())); + { s.store_vector_begin("translation", translation_.size()); for (const auto &_value : translation_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + { s.store_vector_begin("files", files_.size()); for (const auto &_value : files_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("value", value_); + s.store_field("hash", hash_); + s.store_class_end(); + } +} + +error::error() + : code_() + , message_() +{} + +error::error(int32 code_, string const &message_) + : code_(code_) + , message_(message_) +{} + +const std::int32_t error::ID; + +void error::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "error"); + s.store_field("code", code_); + s.store_field("message", message_); + s.store_class_end(); + } +} + +factCheck::factCheck() + : text_() + , country_code_() +{} + +factCheck::factCheck(object_ptr &&text_, string const &country_code_) + : text_(std::move(text_)) + , country_code_(country_code_) +{} + +const std::int32_t factCheck::ID; + +void factCheck::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "factCheck"); + s.store_object_field("text", static_cast(text_.get())); + s.store_field("country_code", country_code_); + s.store_class_end(); + } +} + +failedToAddMember::failedToAddMember() + : user_id_() + , premium_would_allow_invite_() + , premium_required_to_send_messages_() +{} + +failedToAddMember::failedToAddMember(int53 user_id_, bool premium_would_allow_invite_, bool premium_required_to_send_messages_) + : user_id_(user_id_) + , premium_would_allow_invite_(premium_would_allow_invite_) + , premium_required_to_send_messages_(premium_required_to_send_messages_) +{} + +const std::int32_t failedToAddMember::ID; + +void failedToAddMember::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "failedToAddMember"); + s.store_field("user_id", user_id_); + s.store_field("premium_would_allow_invite", premium_would_allow_invite_); + s.store_field("premium_required_to_send_messages", premium_required_to_send_messages_); + s.store_class_end(); + } +} + +failedToAddMembers::failedToAddMembers() + : failed_to_add_members_() +{} + +failedToAddMembers::failedToAddMembers(array> &&failed_to_add_members_) + : failed_to_add_members_(std::move(failed_to_add_members_)) +{} + +const std::int32_t failedToAddMembers::ID; + +void failedToAddMembers::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "failedToAddMembers"); + { s.store_vector_begin("failed_to_add_members", failed_to_add_members_.size()); for (const auto &_value : failed_to_add_members_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +file::file() + : id_() + , size_() + , expected_size_() + , local_() + , remote_() +{} + +file::file(int32 id_, int53 size_, int53 expected_size_, object_ptr &&local_, object_ptr &&remote_) + : id_(id_) + , size_(size_) + , expected_size_(expected_size_) + , local_(std::move(local_)) + , remote_(std::move(remote_)) +{} + +const std::int32_t file::ID; + +void file::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "file"); + s.store_field("id", id_); + s.store_field("size", size_); + s.store_field("expected_size", expected_size_); + s.store_object_field("local", static_cast(local_.get())); + s.store_object_field("remote", static_cast(remote_.get())); + s.store_class_end(); + } +} + +fileDownload::fileDownload() + : file_id_() + , message_() + , add_date_() + , complete_date_() + , is_paused_() +{} + +fileDownload::fileDownload(int32 file_id_, object_ptr &&message_, int32 add_date_, int32 complete_date_, bool is_paused_) + : file_id_(file_id_) + , message_(std::move(message_)) + , add_date_(add_date_) + , complete_date_(complete_date_) + , is_paused_(is_paused_) +{} + +const std::int32_t fileDownload::ID; + +void fileDownload::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileDownload"); + s.store_field("file_id", file_id_); + s.store_object_field("message", static_cast(message_.get())); + s.store_field("add_date", add_date_); + s.store_field("complete_date", complete_date_); + s.store_field("is_paused", is_paused_); + s.store_class_end(); + } +} + +fileDownloadedPrefixSize::fileDownloadedPrefixSize() + : size_() +{} + +fileDownloadedPrefixSize::fileDownloadedPrefixSize(int53 size_) + : size_(size_) +{} + +const std::int32_t fileDownloadedPrefixSize::ID; + +void fileDownloadedPrefixSize::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileDownloadedPrefixSize"); + s.store_field("size", size_); + s.store_class_end(); + } +} + +filePart::filePart() + : data_() +{} + +filePart::filePart(bytes const &data_) + : data_(std::move(data_)) +{} + +const std::int32_t filePart::ID; + +void filePart::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "filePart"); + s.store_bytes_field("data", data_); + s.store_class_end(); + } +} + +fileTypeNone::fileTypeNone() { +} + +const std::int32_t fileTypeNone::ID; + +void fileTypeNone::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeNone"); + s.store_class_end(); + } +} + +fileTypeAnimation::fileTypeAnimation() { +} + +const std::int32_t fileTypeAnimation::ID; + +void fileTypeAnimation::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeAnimation"); + s.store_class_end(); + } +} + +fileTypeAudio::fileTypeAudio() { +} + +const std::int32_t fileTypeAudio::ID; + +void fileTypeAudio::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeAudio"); + s.store_class_end(); + } +} + +fileTypeDocument::fileTypeDocument() { +} + +const std::int32_t fileTypeDocument::ID; + +void fileTypeDocument::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeDocument"); + s.store_class_end(); + } +} + +fileTypeNotificationSound::fileTypeNotificationSound() { +} + +const std::int32_t fileTypeNotificationSound::ID; + +void fileTypeNotificationSound::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeNotificationSound"); + s.store_class_end(); + } +} + +fileTypePhoto::fileTypePhoto() { +} + +const std::int32_t fileTypePhoto::ID; + +void fileTypePhoto::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypePhoto"); + s.store_class_end(); + } +} + +fileTypePhotoStory::fileTypePhotoStory() { +} + +const std::int32_t fileTypePhotoStory::ID; + +void fileTypePhotoStory::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypePhotoStory"); + s.store_class_end(); + } +} + +fileTypeProfilePhoto::fileTypeProfilePhoto() { +} + +const std::int32_t fileTypeProfilePhoto::ID; + +void fileTypeProfilePhoto::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeProfilePhoto"); + s.store_class_end(); + } +} + +fileTypeSecret::fileTypeSecret() { +} + +const std::int32_t fileTypeSecret::ID; + +void fileTypeSecret::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeSecret"); + s.store_class_end(); + } +} + +fileTypeSecretThumbnail::fileTypeSecretThumbnail() { +} + +const std::int32_t fileTypeSecretThumbnail::ID; + +void fileTypeSecretThumbnail::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeSecretThumbnail"); + s.store_class_end(); + } +} + +fileTypeSecure::fileTypeSecure() { +} + +const std::int32_t fileTypeSecure::ID; + +void fileTypeSecure::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeSecure"); + s.store_class_end(); + } +} + +fileTypeSticker::fileTypeSticker() { +} + +const std::int32_t fileTypeSticker::ID; + +void fileTypeSticker::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeSticker"); + s.store_class_end(); + } +} + +fileTypeThumbnail::fileTypeThumbnail() { +} + +const std::int32_t fileTypeThumbnail::ID; + +void fileTypeThumbnail::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeThumbnail"); + s.store_class_end(); + } +} + +fileTypeUnknown::fileTypeUnknown() { +} + +const std::int32_t fileTypeUnknown::ID; + +void fileTypeUnknown::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeUnknown"); + s.store_class_end(); + } +} + +fileTypeVideo::fileTypeVideo() { +} + +const std::int32_t fileTypeVideo::ID; + +void fileTypeVideo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeVideo"); + s.store_class_end(); + } +} + +fileTypeVideoNote::fileTypeVideoNote() { +} + +const std::int32_t fileTypeVideoNote::ID; + +void fileTypeVideoNote::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeVideoNote"); + s.store_class_end(); + } +} + +fileTypeVideoStory::fileTypeVideoStory() { +} + +const std::int32_t fileTypeVideoStory::ID; + +void fileTypeVideoStory::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeVideoStory"); + s.store_class_end(); + } +} + +fileTypeVoiceNote::fileTypeVoiceNote() { +} + +const std::int32_t fileTypeVoiceNote::ID; + +void fileTypeVoiceNote::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeVoiceNote"); + s.store_class_end(); + } +} + +fileTypeWallpaper::fileTypeWallpaper() { +} + +const std::int32_t fileTypeWallpaper::ID; + +void fileTypeWallpaper::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "fileTypeWallpaper"); + s.store_class_end(); + } +} + +firebaseAuthenticationSettingsAndroid::firebaseAuthenticationSettingsAndroid() { +} + +const std::int32_t firebaseAuthenticationSettingsAndroid::ID; + +void firebaseAuthenticationSettingsAndroid::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "firebaseAuthenticationSettingsAndroid"); + s.store_class_end(); + } +} + +firebaseAuthenticationSettingsIos::firebaseAuthenticationSettingsIos() + : device_token_() + , is_app_sandbox_() +{} + +firebaseAuthenticationSettingsIos::firebaseAuthenticationSettingsIos(string const &device_token_, bool is_app_sandbox_) + : device_token_(device_token_) + , is_app_sandbox_(is_app_sandbox_) +{} + +const std::int32_t firebaseAuthenticationSettingsIos::ID; + +void firebaseAuthenticationSettingsIos::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "firebaseAuthenticationSettingsIos"); + s.store_field("device_token", device_token_); + s.store_field("is_app_sandbox", is_app_sandbox_); + s.store_class_end(); + } +} + +firebaseDeviceVerificationParametersSafetyNet::firebaseDeviceVerificationParametersSafetyNet() + : nonce_() +{} + +firebaseDeviceVerificationParametersSafetyNet::firebaseDeviceVerificationParametersSafetyNet(bytes const &nonce_) + : nonce_(std::move(nonce_)) +{} + +const std::int32_t firebaseDeviceVerificationParametersSafetyNet::ID; + +void firebaseDeviceVerificationParametersSafetyNet::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "firebaseDeviceVerificationParametersSafetyNet"); + s.store_bytes_field("nonce", nonce_); + s.store_class_end(); + } +} + +firebaseDeviceVerificationParametersPlayIntegrity::firebaseDeviceVerificationParametersPlayIntegrity() + : nonce_() + , cloud_project_number_() +{} + +firebaseDeviceVerificationParametersPlayIntegrity::firebaseDeviceVerificationParametersPlayIntegrity(string const &nonce_, int64 cloud_project_number_) + : nonce_(nonce_) + , cloud_project_number_(cloud_project_number_) +{} + +const std::int32_t firebaseDeviceVerificationParametersPlayIntegrity::ID; + +void firebaseDeviceVerificationParametersPlayIntegrity::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "firebaseDeviceVerificationParametersPlayIntegrity"); + s.store_field("nonce", nonce_); + s.store_field("cloud_project_number", cloud_project_number_); + s.store_class_end(); + } +} + +formattedText::formattedText() + : text_() + , entities_() +{} + +formattedText::formattedText(string const &text_, array> &&entities_) + : text_(text_) + , entities_(std::move(entities_)) +{} + +const std::int32_t formattedText::ID; + +void formattedText::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "formattedText"); + s.store_field("text", text_); + { s.store_vector_begin("entities", entities_.size()); for (const auto &_value : entities_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +forumTopic::forumTopic() + : info_() + , last_message_() + , is_pinned_() + , unread_count_() + , last_read_inbox_message_id_() + , last_read_outbox_message_id_() + , unread_mention_count_() + , unread_reaction_count_() + , notification_settings_() + , draft_message_() +{} + +forumTopic::forumTopic(object_ptr &&info_, object_ptr &&last_message_, bool is_pinned_, int32 unread_count_, int53 last_read_inbox_message_id_, int53 last_read_outbox_message_id_, int32 unread_mention_count_, int32 unread_reaction_count_, object_ptr &¬ification_settings_, object_ptr &&draft_message_) + : info_(std::move(info_)) + , last_message_(std::move(last_message_)) + , is_pinned_(is_pinned_) + , unread_count_(unread_count_) + , last_read_inbox_message_id_(last_read_inbox_message_id_) + , last_read_outbox_message_id_(last_read_outbox_message_id_) + , unread_mention_count_(unread_mention_count_) + , unread_reaction_count_(unread_reaction_count_) + , notification_settings_(std::move(notification_settings_)) + , draft_message_(std::move(draft_message_)) +{} + +const std::int32_t forumTopic::ID; + +void forumTopic::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "forumTopic"); + s.store_object_field("info", static_cast(info_.get())); + s.store_object_field("last_message", static_cast(last_message_.get())); + s.store_field("is_pinned", is_pinned_); + s.store_field("unread_count", unread_count_); + s.store_field("last_read_inbox_message_id", last_read_inbox_message_id_); + s.store_field("last_read_outbox_message_id", last_read_outbox_message_id_); + s.store_field("unread_mention_count", unread_mention_count_); + s.store_field("unread_reaction_count", unread_reaction_count_); + s.store_object_field("notification_settings", static_cast(notification_settings_.get())); + s.store_object_field("draft_message", static_cast(draft_message_.get())); + s.store_class_end(); + } +} + +forumTopicIcon::forumTopicIcon() + : color_() + , custom_emoji_id_() +{} + +forumTopicIcon::forumTopicIcon(int32 color_, int64 custom_emoji_id_) + : color_(color_) + , custom_emoji_id_(custom_emoji_id_) +{} + +const std::int32_t forumTopicIcon::ID; + +void forumTopicIcon::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "forumTopicIcon"); + s.store_field("color", color_); + s.store_field("custom_emoji_id", custom_emoji_id_); + s.store_class_end(); + } +} + +forumTopicInfo::forumTopicInfo() + : message_thread_id_() + , name_() + , icon_() + , creation_date_() + , creator_id_() + , is_general_() + , is_outgoing_() + , is_closed_() + , is_hidden_() +{} + +forumTopicInfo::forumTopicInfo(int53 message_thread_id_, string const &name_, object_ptr &&icon_, int32 creation_date_, object_ptr &&creator_id_, bool is_general_, bool is_outgoing_, bool is_closed_, bool is_hidden_) + : message_thread_id_(message_thread_id_) + , name_(name_) + , icon_(std::move(icon_)) + , creation_date_(creation_date_) + , creator_id_(std::move(creator_id_)) + , is_general_(is_general_) + , is_outgoing_(is_outgoing_) + , is_closed_(is_closed_) + , is_hidden_(is_hidden_) +{} + +const std::int32_t forumTopicInfo::ID; + +void forumTopicInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "forumTopicInfo"); + s.store_field("message_thread_id", message_thread_id_); + s.store_field("name", name_); + s.store_object_field("icon", static_cast(icon_.get())); + s.store_field("creation_date", creation_date_); + s.store_object_field("creator_id", static_cast(creator_id_.get())); + s.store_field("is_general", is_general_); + s.store_field("is_outgoing", is_outgoing_); + s.store_field("is_closed", is_closed_); + s.store_field("is_hidden", is_hidden_); + s.store_class_end(); + } +} + +forumTopics::forumTopics() + : total_count_() + , topics_() + , next_offset_date_() + , next_offset_message_id_() + , next_offset_message_thread_id_() +{} + +forumTopics::forumTopics(int32 total_count_, array> &&topics_, int32 next_offset_date_, int53 next_offset_message_id_, int53 next_offset_message_thread_id_) + : total_count_(total_count_) + , topics_(std::move(topics_)) + , next_offset_date_(next_offset_date_) + , next_offset_message_id_(next_offset_message_id_) + , next_offset_message_thread_id_(next_offset_message_thread_id_) +{} + +const std::int32_t forumTopics::ID; + +void forumTopics::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "forumTopics"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("topics", topics_.size()); for (const auto &_value : topics_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("next_offset_date", next_offset_date_); + s.store_field("next_offset_message_id", next_offset_message_id_); + s.store_field("next_offset_message_thread_id", next_offset_message_thread_id_); + s.store_class_end(); + } +} + +forwardSource::forwardSource() + : chat_id_() + , message_id_() + , sender_id_() + , sender_name_() + , date_() + , is_outgoing_() +{} + +forwardSource::forwardSource(int53 chat_id_, int53 message_id_, object_ptr &&sender_id_, string const &sender_name_, int32 date_, bool is_outgoing_) + : chat_id_(chat_id_) + , message_id_(message_id_) + , sender_id_(std::move(sender_id_)) + , sender_name_(sender_name_) + , date_(date_) + , is_outgoing_(is_outgoing_) +{} + +const std::int32_t forwardSource::ID; + +void forwardSource::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "forwardSource"); + s.store_field("chat_id", chat_id_); + s.store_field("message_id", message_id_); + s.store_object_field("sender_id", static_cast(sender_id_.get())); + s.store_field("sender_name", sender_name_); + s.store_field("date", date_); + s.store_field("is_outgoing", is_outgoing_); + s.store_class_end(); + } +} + +foundChatBoosts::foundChatBoosts() + : total_count_() + , boosts_() + , next_offset_() +{} + +foundChatBoosts::foundChatBoosts(int32 total_count_, array> &&boosts_, string const &next_offset_) + : total_count_(total_count_) + , boosts_(std::move(boosts_)) + , next_offset_(next_offset_) +{} + +const std::int32_t foundChatBoosts::ID; + +void foundChatBoosts::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundChatBoosts"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("boosts", boosts_.size()); for (const auto &_value : boosts_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("next_offset", next_offset_); + s.store_class_end(); + } +} + +foundChatMessages::foundChatMessages() + : total_count_() + , messages_() + , next_from_message_id_() +{} + +foundChatMessages::foundChatMessages(int32 total_count_, array> &&messages_, int53 next_from_message_id_) + : total_count_(total_count_) + , messages_(std::move(messages_)) + , next_from_message_id_(next_from_message_id_) +{} + +const std::int32_t foundChatMessages::ID; + +void foundChatMessages::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundChatMessages"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("messages", messages_.size()); for (const auto &_value : messages_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("next_from_message_id", next_from_message_id_); + s.store_class_end(); + } +} + +foundFileDownloads::foundFileDownloads() + : total_counts_() + , files_() + , next_offset_() +{} + +foundFileDownloads::foundFileDownloads(object_ptr &&total_counts_, array> &&files_, string const &next_offset_) + : total_counts_(std::move(total_counts_)) + , files_(std::move(files_)) + , next_offset_(next_offset_) +{} + +const std::int32_t foundFileDownloads::ID; + +void foundFileDownloads::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundFileDownloads"); + s.store_object_field("total_counts", static_cast(total_counts_.get())); + { s.store_vector_begin("files", files_.size()); for (const auto &_value : files_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("next_offset", next_offset_); + s.store_class_end(); + } +} + +foundMessages::foundMessages() + : total_count_() + , messages_() + , next_offset_() +{} + +foundMessages::foundMessages(int32 total_count_, array> &&messages_, string const &next_offset_) + : total_count_(total_count_) + , messages_(std::move(messages_)) + , next_offset_(next_offset_) +{} + +const std::int32_t foundMessages::ID; + +void foundMessages::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundMessages"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("messages", messages_.size()); for (const auto &_value : messages_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("next_offset", next_offset_); + s.store_class_end(); + } +} + +foundPosition::foundPosition() + : position_() +{} + +foundPosition::foundPosition(int32 position_) + : position_(position_) +{} + +const std::int32_t foundPosition::ID; + +void foundPosition::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundPosition"); + s.store_field("position", position_); + s.store_class_end(); + } +} + +foundPositions::foundPositions() + : total_count_() + , positions_() +{} + +foundPositions::foundPositions(int32 total_count_, array &&positions_) + : total_count_(total_count_) + , positions_(std::move(positions_)) +{} + +const std::int32_t foundPositions::ID; + +void foundPositions::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundPositions"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("positions", positions_.size()); for (const auto &_value : positions_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +foundStories::foundStories() + : total_count_() + , stories_() + , next_offset_() +{} + +foundStories::foundStories(int32 total_count_, array> &&stories_, string const &next_offset_) + : total_count_(total_count_) + , stories_(std::move(stories_)) + , next_offset_(next_offset_) +{} + +const std::int32_t foundStories::ID; + +void foundStories::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundStories"); + s.store_field("total_count", total_count_); + { s.store_vector_begin("stories", stories_.size()); for (const auto &_value : stories_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("next_offset", next_offset_); + s.store_class_end(); + } +} + +foundUsers::foundUsers() + : user_ids_() + , next_offset_() +{} + +foundUsers::foundUsers(array &&user_ids_, string const &next_offset_) + : user_ids_(std::move(user_ids_)) + , next_offset_(next_offset_) +{} + +const std::int32_t foundUsers::ID; + +void foundUsers::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundUsers"); + { s.store_vector_begin("user_ids", user_ids_.size()); for (const auto &_value : user_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_field("next_offset", next_offset_); + s.store_class_end(); + } +} + +foundWebApp::foundWebApp() + : web_app_() + , request_write_access_() + , skip_confirmation_() +{} + +foundWebApp::foundWebApp(object_ptr &&web_app_, bool request_write_access_, bool skip_confirmation_) + : web_app_(std::move(web_app_)) + , request_write_access_(request_write_access_) + , skip_confirmation_(skip_confirmation_) +{} + +const std::int32_t foundWebApp::ID; + +void foundWebApp::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "foundWebApp"); + s.store_object_field("web_app", static_cast(web_app_.get())); + s.store_field("request_write_access", request_write_access_); + s.store_field("skip_confirmation", skip_confirmation_); + s.store_class_end(); + } +} + +game::game() + : id_() + , short_name_() + , title_() + , text_() + , description_() + , photo_() + , animation_() +{} + +game::game(int64 id_, string const &short_name_, string const &title_, object_ptr &&text_, string const &description_, object_ptr &&photo_, object_ptr &&animation_) + : id_(id_) + , short_name_(short_name_) + , title_(title_) + , text_(std::move(text_)) + , description_(description_) + , photo_(std::move(photo_)) + , animation_(std::move(animation_)) +{} + +const std::int32_t game::ID; + +void game::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "game"); + s.store_field("id", id_); + s.store_field("short_name", short_name_); + s.store_field("title", title_); + s.store_object_field("text", static_cast(text_.get())); + s.store_field("description", description_); + s.store_object_field("photo", static_cast(photo_.get())); + s.store_object_field("animation", static_cast(animation_.get())); + s.store_class_end(); + } +} + +gameHighScore::gameHighScore() + : position_() + , user_id_() + , score_() +{} + +gameHighScore::gameHighScore(int32 position_, int53 user_id_, int32 score_) + : position_(position_) + , user_id_(user_id_) + , score_(score_) +{} + +const std::int32_t gameHighScore::ID; + +void gameHighScore::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "gameHighScore"); + s.store_field("position", position_); + s.store_field("user_id", user_id_); + s.store_field("score", score_); + s.store_class_end(); + } +} + +gameHighScores::gameHighScores() + : scores_() +{} + +gameHighScores::gameHighScores(array> &&scores_) + : scores_(std::move(scores_)) +{} + +const std::int32_t gameHighScores::ID; + +void gameHighScores::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "gameHighScores"); + { s.store_vector_begin("scores", scores_.size()); for (const auto &_value : scores_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +giveawayInfoOngoing::giveawayInfoOngoing() + : creation_date_() + , status_() + , is_ended_() +{} + +giveawayInfoOngoing::giveawayInfoOngoing(int32 creation_date_, object_ptr &&status_, bool is_ended_) + : creation_date_(creation_date_) + , status_(std::move(status_)) + , is_ended_(is_ended_) +{} + +const std::int32_t giveawayInfoOngoing::ID; + +void giveawayInfoOngoing::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayInfoOngoing"); + s.store_field("creation_date", creation_date_); + s.store_object_field("status", static_cast(status_.get())); + s.store_field("is_ended", is_ended_); + s.store_class_end(); + } +} + +giveawayInfoCompleted::giveawayInfoCompleted() + : creation_date_() + , actual_winners_selection_date_() + , was_refunded_() + , is_winner_() + , winner_count_() + , activation_count_() + , gift_code_() + , won_star_count_() +{} + +giveawayInfoCompleted::giveawayInfoCompleted(int32 creation_date_, int32 actual_winners_selection_date_, bool was_refunded_, bool is_winner_, int32 winner_count_, int32 activation_count_, string const &gift_code_, int53 won_star_count_) + : creation_date_(creation_date_) + , actual_winners_selection_date_(actual_winners_selection_date_) + , was_refunded_(was_refunded_) + , is_winner_(is_winner_) + , winner_count_(winner_count_) + , activation_count_(activation_count_) + , gift_code_(gift_code_) + , won_star_count_(won_star_count_) +{} + +const std::int32_t giveawayInfoCompleted::ID; + +void giveawayInfoCompleted::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayInfoCompleted"); + s.store_field("creation_date", creation_date_); + s.store_field("actual_winners_selection_date", actual_winners_selection_date_); + s.store_field("was_refunded", was_refunded_); + s.store_field("is_winner", is_winner_); + s.store_field("winner_count", winner_count_); + s.store_field("activation_count", activation_count_); + s.store_field("gift_code", gift_code_); + s.store_field("won_star_count", won_star_count_); + s.store_class_end(); + } +} + +giveawayParameters::giveawayParameters() + : boosted_chat_id_() + , additional_chat_ids_() + , winners_selection_date_() + , only_new_members_() + , has_public_winners_() + , country_codes_() + , prize_description_() +{} + +giveawayParameters::giveawayParameters(int53 boosted_chat_id_, array &&additional_chat_ids_, int32 winners_selection_date_, bool only_new_members_, bool has_public_winners_, array &&country_codes_, string const &prize_description_) + : boosted_chat_id_(boosted_chat_id_) + , additional_chat_ids_(std::move(additional_chat_ids_)) + , winners_selection_date_(winners_selection_date_) + , only_new_members_(only_new_members_) + , has_public_winners_(has_public_winners_) + , country_codes_(std::move(country_codes_)) + , prize_description_(prize_description_) +{} + +const std::int32_t giveawayParameters::ID; + +void giveawayParameters::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayParameters"); + s.store_field("boosted_chat_id", boosted_chat_id_); + { s.store_vector_begin("additional_chat_ids", additional_chat_ids_.size()); for (const auto &_value : additional_chat_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_field("winners_selection_date", winners_selection_date_); + s.store_field("only_new_members", only_new_members_); + s.store_field("has_public_winners", has_public_winners_); + { s.store_vector_begin("country_codes", country_codes_.size()); for (const auto &_value : country_codes_) { s.store_field("", _value); } s.store_class_end(); } + s.store_field("prize_description", prize_description_); + s.store_class_end(); + } +} + +giveawayParticipantStatusEligible::giveawayParticipantStatusEligible() { +} + +const std::int32_t giveawayParticipantStatusEligible::ID; + +void giveawayParticipantStatusEligible::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayParticipantStatusEligible"); + s.store_class_end(); + } +} + +giveawayParticipantStatusParticipating::giveawayParticipantStatusParticipating() { +} + +const std::int32_t giveawayParticipantStatusParticipating::ID; + +void giveawayParticipantStatusParticipating::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayParticipantStatusParticipating"); + s.store_class_end(); + } +} + +giveawayParticipantStatusAlreadyWasMember::giveawayParticipantStatusAlreadyWasMember() + : joined_chat_date_() +{} + +giveawayParticipantStatusAlreadyWasMember::giveawayParticipantStatusAlreadyWasMember(int32 joined_chat_date_) + : joined_chat_date_(joined_chat_date_) +{} + +const std::int32_t giveawayParticipantStatusAlreadyWasMember::ID; + +void giveawayParticipantStatusAlreadyWasMember::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayParticipantStatusAlreadyWasMember"); + s.store_field("joined_chat_date", joined_chat_date_); + s.store_class_end(); + } +} + +giveawayParticipantStatusAdministrator::giveawayParticipantStatusAdministrator() + : chat_id_() +{} + +giveawayParticipantStatusAdministrator::giveawayParticipantStatusAdministrator(int53 chat_id_) + : chat_id_(chat_id_) +{} + +const std::int32_t giveawayParticipantStatusAdministrator::ID; + +void giveawayParticipantStatusAdministrator::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayParticipantStatusAdministrator"); + s.store_field("chat_id", chat_id_); + s.store_class_end(); + } +} + +giveawayParticipantStatusDisallowedCountry::giveawayParticipantStatusDisallowedCountry() + : user_country_code_() +{} + +giveawayParticipantStatusDisallowedCountry::giveawayParticipantStatusDisallowedCountry(string const &user_country_code_) + : user_country_code_(user_country_code_) +{} + +const std::int32_t giveawayParticipantStatusDisallowedCountry::ID; + +void giveawayParticipantStatusDisallowedCountry::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayParticipantStatusDisallowedCountry"); + s.store_field("user_country_code", user_country_code_); + s.store_class_end(); + } +} + +giveawayPrizePremium::giveawayPrizePremium() + : month_count_() +{} + +giveawayPrizePremium::giveawayPrizePremium(int32 month_count_) + : month_count_(month_count_) +{} + +const std::int32_t giveawayPrizePremium::ID; + +void giveawayPrizePremium::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayPrizePremium"); + s.store_field("month_count", month_count_); + s.store_class_end(); + } +} + +giveawayPrizeStars::giveawayPrizeStars() + : star_count_() +{} + +giveawayPrizeStars::giveawayPrizeStars(int53 star_count_) + : star_count_(star_count_) +{} + +const std::int32_t giveawayPrizeStars::ID; + +void giveawayPrizeStars::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "giveawayPrizeStars"); + s.store_field("star_count", star_count_); + s.store_class_end(); + } +} + +groupCall::groupCall() + : id_() + , title_() + , scheduled_start_date_() + , enabled_start_notification_() + , is_active_() + , is_rtmp_stream_() + , is_joined_() + , need_rejoin_() + , can_be_managed_() + , participant_count_() + , has_hidden_listeners_() + , loaded_all_participants_() + , recent_speakers_() + , is_my_video_enabled_() + , is_my_video_paused_() + , can_enable_video_() + , mute_new_participants_() + , can_toggle_mute_new_participants_() + , record_duration_() + , is_video_recorded_() + , duration_() +{} + +groupCall::groupCall(int32 id_, string const &title_, int32 scheduled_start_date_, bool enabled_start_notification_, bool is_active_, bool is_rtmp_stream_, bool is_joined_, bool need_rejoin_, bool can_be_managed_, int32 participant_count_, bool has_hidden_listeners_, bool loaded_all_participants_, array> &&recent_speakers_, bool is_my_video_enabled_, bool is_my_video_paused_, bool can_enable_video_, bool mute_new_participants_, bool can_toggle_mute_new_participants_, int32 record_duration_, bool is_video_recorded_, int32 duration_) + : id_(id_) + , title_(title_) + , scheduled_start_date_(scheduled_start_date_) + , enabled_start_notification_(enabled_start_notification_) + , is_active_(is_active_) + , is_rtmp_stream_(is_rtmp_stream_) + , is_joined_(is_joined_) + , need_rejoin_(need_rejoin_) + , can_be_managed_(can_be_managed_) + , participant_count_(participant_count_) + , has_hidden_listeners_(has_hidden_listeners_) + , loaded_all_participants_(loaded_all_participants_) + , recent_speakers_(std::move(recent_speakers_)) + , is_my_video_enabled_(is_my_video_enabled_) + , is_my_video_paused_(is_my_video_paused_) + , can_enable_video_(can_enable_video_) + , mute_new_participants_(mute_new_participants_) + , can_toggle_mute_new_participants_(can_toggle_mute_new_participants_) + , record_duration_(record_duration_) + , is_video_recorded_(is_video_recorded_) + , duration_(duration_) +{} + +const std::int32_t groupCall::ID; + +void groupCall::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCall"); + s.store_field("id", id_); + s.store_field("title", title_); + s.store_field("scheduled_start_date", scheduled_start_date_); + s.store_field("enabled_start_notification", enabled_start_notification_); + s.store_field("is_active", is_active_); + s.store_field("is_rtmp_stream", is_rtmp_stream_); + s.store_field("is_joined", is_joined_); + s.store_field("need_rejoin", need_rejoin_); + s.store_field("can_be_managed", can_be_managed_); + s.store_field("participant_count", participant_count_); + s.store_field("has_hidden_listeners", has_hidden_listeners_); + s.store_field("loaded_all_participants", loaded_all_participants_); + { s.store_vector_begin("recent_speakers", recent_speakers_.size()); for (const auto &_value : recent_speakers_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("is_my_video_enabled", is_my_video_enabled_); + s.store_field("is_my_video_paused", is_my_video_paused_); + s.store_field("can_enable_video", can_enable_video_); + s.store_field("mute_new_participants", mute_new_participants_); + s.store_field("can_toggle_mute_new_participants", can_toggle_mute_new_participants_); + s.store_field("record_duration", record_duration_); + s.store_field("is_video_recorded", is_video_recorded_); + s.store_field("duration", duration_); + s.store_class_end(); + } +} + +groupCallId::groupCallId() + : id_() +{} + +groupCallId::groupCallId(int32 id_) + : id_(id_) +{} + +const std::int32_t groupCallId::ID; + +void groupCallId::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallId"); + s.store_field("id", id_); + s.store_class_end(); + } +} + +groupCallParticipant::groupCallParticipant() + : participant_id_() + , audio_source_id_() + , screen_sharing_audio_source_id_() + , video_info_() + , screen_sharing_video_info_() + , bio_() + , is_current_user_() + , is_speaking_() + , is_hand_raised_() + , can_be_muted_for_all_users_() + , can_be_unmuted_for_all_users_() + , can_be_muted_for_current_user_() + , can_be_unmuted_for_current_user_() + , is_muted_for_all_users_() + , is_muted_for_current_user_() + , can_unmute_self_() + , volume_level_() + , order_() +{} + +groupCallParticipant::groupCallParticipant(object_ptr &&participant_id_, int32 audio_source_id_, int32 screen_sharing_audio_source_id_, object_ptr &&video_info_, object_ptr &&screen_sharing_video_info_, string const &bio_, bool is_current_user_, bool is_speaking_, bool is_hand_raised_, bool can_be_muted_for_all_users_, bool can_be_unmuted_for_all_users_, bool can_be_muted_for_current_user_, bool can_be_unmuted_for_current_user_, bool is_muted_for_all_users_, bool is_muted_for_current_user_, bool can_unmute_self_, int32 volume_level_, string const &order_) + : participant_id_(std::move(participant_id_)) + , audio_source_id_(audio_source_id_) + , screen_sharing_audio_source_id_(screen_sharing_audio_source_id_) + , video_info_(std::move(video_info_)) + , screen_sharing_video_info_(std::move(screen_sharing_video_info_)) + , bio_(bio_) + , is_current_user_(is_current_user_) + , is_speaking_(is_speaking_) + , is_hand_raised_(is_hand_raised_) + , can_be_muted_for_all_users_(can_be_muted_for_all_users_) + , can_be_unmuted_for_all_users_(can_be_unmuted_for_all_users_) + , can_be_muted_for_current_user_(can_be_muted_for_current_user_) + , can_be_unmuted_for_current_user_(can_be_unmuted_for_current_user_) + , is_muted_for_all_users_(is_muted_for_all_users_) + , is_muted_for_current_user_(is_muted_for_current_user_) + , can_unmute_self_(can_unmute_self_) + , volume_level_(volume_level_) + , order_(order_) +{} + +const std::int32_t groupCallParticipant::ID; + +void groupCallParticipant::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallParticipant"); + s.store_object_field("participant_id", static_cast(participant_id_.get())); + s.store_field("audio_source_id", audio_source_id_); + s.store_field("screen_sharing_audio_source_id", screen_sharing_audio_source_id_); + s.store_object_field("video_info", static_cast(video_info_.get())); + s.store_object_field("screen_sharing_video_info", static_cast(screen_sharing_video_info_.get())); + s.store_field("bio", bio_); + s.store_field("is_current_user", is_current_user_); + s.store_field("is_speaking", is_speaking_); + s.store_field("is_hand_raised", is_hand_raised_); + s.store_field("can_be_muted_for_all_users", can_be_muted_for_all_users_); + s.store_field("can_be_unmuted_for_all_users", can_be_unmuted_for_all_users_); + s.store_field("can_be_muted_for_current_user", can_be_muted_for_current_user_); + s.store_field("can_be_unmuted_for_current_user", can_be_unmuted_for_current_user_); + s.store_field("is_muted_for_all_users", is_muted_for_all_users_); + s.store_field("is_muted_for_current_user", is_muted_for_current_user_); + s.store_field("can_unmute_self", can_unmute_self_); + s.store_field("volume_level", volume_level_); + s.store_field("order", order_); + s.store_class_end(); + } +} + +groupCallParticipantVideoInfo::groupCallParticipantVideoInfo() + : source_groups_() + , endpoint_id_() + , is_paused_() +{} + +groupCallParticipantVideoInfo::groupCallParticipantVideoInfo(array> &&source_groups_, string const &endpoint_id_, bool is_paused_) + : source_groups_(std::move(source_groups_)) + , endpoint_id_(endpoint_id_) + , is_paused_(is_paused_) +{} + +const std::int32_t groupCallParticipantVideoInfo::ID; + +void groupCallParticipantVideoInfo::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallParticipantVideoInfo"); + { s.store_vector_begin("source_groups", source_groups_.size()); for (const auto &_value : source_groups_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_field("endpoint_id", endpoint_id_); + s.store_field("is_paused", is_paused_); + s.store_class_end(); + } +} + +groupCallRecentSpeaker::groupCallRecentSpeaker() + : participant_id_() + , is_speaking_() +{} + +groupCallRecentSpeaker::groupCallRecentSpeaker(object_ptr &&participant_id_, bool is_speaking_) + : participant_id_(std::move(participant_id_)) + , is_speaking_(is_speaking_) +{} + +const std::int32_t groupCallRecentSpeaker::ID; + +void groupCallRecentSpeaker::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallRecentSpeaker"); + s.store_object_field("participant_id", static_cast(participant_id_.get())); + s.store_field("is_speaking", is_speaking_); + s.store_class_end(); + } +} + +groupCallStream::groupCallStream() + : channel_id_() + , scale_() + , time_offset_() +{} + +groupCallStream::groupCallStream(int32 channel_id_, int32 scale_, int53 time_offset_) + : channel_id_(channel_id_) + , scale_(scale_) + , time_offset_(time_offset_) +{} + +const std::int32_t groupCallStream::ID; + +void groupCallStream::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallStream"); + s.store_field("channel_id", channel_id_); + s.store_field("scale", scale_); + s.store_field("time_offset", time_offset_); + s.store_class_end(); + } +} + +groupCallStreams::groupCallStreams() + : streams_() +{} + +groupCallStreams::groupCallStreams(array> &&streams_) + : streams_(std::move(streams_)) +{} + +const std::int32_t groupCallStreams::ID; + +void groupCallStreams::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallStreams"); + { s.store_vector_begin("streams", streams_.size()); for (const auto &_value : streams_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +groupCallVideoQualityThumbnail::groupCallVideoQualityThumbnail() { +} + +const std::int32_t groupCallVideoQualityThumbnail::ID; + +void groupCallVideoQualityThumbnail::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallVideoQualityThumbnail"); + s.store_class_end(); + } +} + +groupCallVideoQualityMedium::groupCallVideoQualityMedium() { +} + +const std::int32_t groupCallVideoQualityMedium::ID; + +void groupCallVideoQualityMedium::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallVideoQualityMedium"); + s.store_class_end(); + } +} + +groupCallVideoQualityFull::groupCallVideoQualityFull() { +} + +const std::int32_t groupCallVideoQualityFull::ID; + +void groupCallVideoQualityFull::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallVideoQualityFull"); + s.store_class_end(); + } +} + +groupCallVideoSourceGroup::groupCallVideoSourceGroup() + : semantics_() + , source_ids_() +{} + +groupCallVideoSourceGroup::groupCallVideoSourceGroup(string const &semantics_, array &&source_ids_) + : semantics_(semantics_) + , source_ids_(std::move(source_ids_)) +{} + +const std::int32_t groupCallVideoSourceGroup::ID; + +void groupCallVideoSourceGroup::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "groupCallVideoSourceGroup"); + s.store_field("semantics", semantics_); + { s.store_vector_begin("source_ids", source_ids_.size()); for (const auto &_value : source_ids_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +hashtags::hashtags() + : hashtags_() +{} + +hashtags::hashtags(array &&hashtags_) + : hashtags_(std::move(hashtags_)) +{} + +const std::int32_t hashtags::ID; + +void hashtags::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "hashtags"); + { s.store_vector_begin("hashtags", hashtags_.size()); for (const auto &_value : hashtags_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +httpUrl::httpUrl() + : url_() +{} + +httpUrl::httpUrl(string const &url_) + : url_(url_) +{} + +const std::int32_t httpUrl::ID; + +void httpUrl::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "httpUrl"); + s.store_field("url", url_); + s.store_class_end(); + } +} + +identityDocument::identityDocument() + : number_() + , expiration_date_() + , front_side_() + , reverse_side_() + , selfie_() + , translation_() +{} + +identityDocument::identityDocument(string const &number_, object_ptr &&expiration_date_, object_ptr &&front_side_, object_ptr &&reverse_side_, object_ptr &&selfie_, array> &&translation_) + : number_(number_) + , expiration_date_(std::move(expiration_date_)) + , front_side_(std::move(front_side_)) + , reverse_side_(std::move(reverse_side_)) + , selfie_(std::move(selfie_)) + , translation_(std::move(translation_)) +{} + +const std::int32_t identityDocument::ID; + +void identityDocument::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "identityDocument"); + s.store_field("number", number_); + s.store_object_field("expiration_date", static_cast(expiration_date_.get())); + s.store_object_field("front_side", static_cast(front_side_.get())); + s.store_object_field("reverse_side", static_cast(reverse_side_.get())); + s.store_object_field("selfie", static_cast(selfie_.get())); + { s.store_vector_begin("translation", translation_.size()); for (const auto &_value : translation_) { s.store_object_field("", static_cast(_value.get())); } s.store_class_end(); } + s.store_class_end(); + } +} + +importedContacts::importedContacts() + : user_ids_() + , importer_count_() +{} + +importedContacts::importedContacts(array &&user_ids_, array &&importer_count_) + : user_ids_(std::move(user_ids_)) + , importer_count_(std::move(importer_count_)) +{} + +const std::int32_t importedContacts::ID; + +void importedContacts::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "importedContacts"); + { s.store_vector_begin("user_ids", user_ids_.size()); for (const auto &_value : user_ids_) { s.store_field("", _value); } s.store_class_end(); } + { s.store_vector_begin("importer_count", importer_count_.size()); for (const auto &_value : importer_count_) { s.store_field("", _value); } s.store_class_end(); } + s.store_class_end(); + } +} + +inlineKeyboardButton::inlineKeyboardButton() + : text_() + , type_() +{} + +inlineKeyboardButton::inlineKeyboardButton(string const &text_, object_ptr &&type_) + : text_(text_) + , type_(std::move(type_)) +{} + +const std::int32_t inlineKeyboardButton::ID; + +void inlineKeyboardButton::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButton"); + s.store_field("text", text_); + s.store_object_field("type", static_cast(type_.get())); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeUrl::inlineKeyboardButtonTypeUrl() + : url_() +{} + +inlineKeyboardButtonTypeUrl::inlineKeyboardButtonTypeUrl(string const &url_) + : url_(url_) +{} + +const std::int32_t inlineKeyboardButtonTypeUrl::ID; + +void inlineKeyboardButtonTypeUrl::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeUrl"); + s.store_field("url", url_); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeLoginUrl::inlineKeyboardButtonTypeLoginUrl() + : url_() + , id_() + , forward_text_() +{} + +inlineKeyboardButtonTypeLoginUrl::inlineKeyboardButtonTypeLoginUrl(string const &url_, int53 id_, string const &forward_text_) + : url_(url_) + , id_(id_) + , forward_text_(forward_text_) +{} + +const std::int32_t inlineKeyboardButtonTypeLoginUrl::ID; + +void inlineKeyboardButtonTypeLoginUrl::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeLoginUrl"); + s.store_field("url", url_); + s.store_field("id", id_); + s.store_field("forward_text", forward_text_); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeWebApp::inlineKeyboardButtonTypeWebApp() + : url_() +{} + +inlineKeyboardButtonTypeWebApp::inlineKeyboardButtonTypeWebApp(string const &url_) + : url_(url_) +{} + +const std::int32_t inlineKeyboardButtonTypeWebApp::ID; + +void inlineKeyboardButtonTypeWebApp::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeWebApp"); + s.store_field("url", url_); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeCallback::inlineKeyboardButtonTypeCallback() + : data_() +{} + +inlineKeyboardButtonTypeCallback::inlineKeyboardButtonTypeCallback(bytes const &data_) + : data_(std::move(data_)) +{} + +const std::int32_t inlineKeyboardButtonTypeCallback::ID; + +void inlineKeyboardButtonTypeCallback::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeCallback"); + s.store_bytes_field("data", data_); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeCallbackWithPassword::inlineKeyboardButtonTypeCallbackWithPassword() + : data_() +{} + +inlineKeyboardButtonTypeCallbackWithPassword::inlineKeyboardButtonTypeCallbackWithPassword(bytes const &data_) + : data_(std::move(data_)) +{} + +const std::int32_t inlineKeyboardButtonTypeCallbackWithPassword::ID; + +void inlineKeyboardButtonTypeCallbackWithPassword::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeCallbackWithPassword"); + s.store_bytes_field("data", data_); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeCallbackGame::inlineKeyboardButtonTypeCallbackGame() { +} + +const std::int32_t inlineKeyboardButtonTypeCallbackGame::ID; + +void inlineKeyboardButtonTypeCallbackGame::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeCallbackGame"); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeSwitchInline::inlineKeyboardButtonTypeSwitchInline() + : query_() + , target_chat_() +{} + +inlineKeyboardButtonTypeSwitchInline::inlineKeyboardButtonTypeSwitchInline(string const &query_, object_ptr &&target_chat_) + : query_(query_) + , target_chat_(std::move(target_chat_)) +{} + +const std::int32_t inlineKeyboardButtonTypeSwitchInline::ID; + +void inlineKeyboardButtonTypeSwitchInline::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeSwitchInline"); + s.store_field("query", query_); + s.store_object_field("target_chat", static_cast(target_chat_.get())); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeBuy::inlineKeyboardButtonTypeBuy() { +} + +const std::int32_t inlineKeyboardButtonTypeBuy::ID; + +void inlineKeyboardButtonTypeBuy::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeBuy"); + s.store_class_end(); + } +} + +inlineKeyboardButtonTypeUser::inlineKeyboardButtonTypeUser() + : user_id_() +{} + +inlineKeyboardButtonTypeUser::inlineKeyboardButtonTypeUser(int53 user_id_) + : user_id_(user_id_) +{} + +const std::int32_t inlineKeyboardButtonTypeUser::ID; + +void inlineKeyboardButtonTypeUser::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineKeyboardButtonTypeUser"); + s.store_field("user_id", user_id_); + s.store_class_end(); + } +} + +inlineQueryResultArticle::inlineQueryResultArticle() + : id_() + , url_() + , hide_url_() + , title_() + , description_() + , thumbnail_() +{} + +inlineQueryResultArticle::inlineQueryResultArticle(string const &id_, string const &url_, bool hide_url_, string const &title_, string const &description_, object_ptr &&thumbnail_) + : id_(id_) + , url_(url_) + , hide_url_(hide_url_) + , title_(title_) + , description_(description_) + , thumbnail_(std::move(thumbnail_)) +{} + +const std::int32_t inlineQueryResultArticle::ID; + +void inlineQueryResultArticle::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineQueryResultArticle"); + s.store_field("id", id_); + s.store_field("url", url_); + s.store_field("hide_url", hide_url_); + s.store_field("title", title_); + s.store_field("description", description_); + s.store_object_field("thumbnail", static_cast(thumbnail_.get())); + s.store_class_end(); + } +} + +inlineQueryResultContact::inlineQueryResultContact() + : id_() + , contact_() + , thumbnail_() +{} + +inlineQueryResultContact::inlineQueryResultContact(string const &id_, object_ptr &&contact_, object_ptr &&thumbnail_) + : id_(id_) + , contact_(std::move(contact_)) + , thumbnail_(std::move(thumbnail_)) +{} + +const std::int32_t inlineQueryResultContact::ID; + +void inlineQueryResultContact::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineQueryResultContact"); + s.store_field("id", id_); + s.store_object_field("contact", static_cast(contact_.get())); + s.store_object_field("thumbnail", static_cast(thumbnail_.get())); + s.store_class_end(); + } +} + +inlineQueryResultLocation::inlineQueryResultLocation() + : id_() + , location_() + , title_() + , thumbnail_() +{} + +inlineQueryResultLocation::inlineQueryResultLocation(string const &id_, object_ptr &&location_, string const &title_, object_ptr &&thumbnail_) + : id_(id_) + , location_(std::move(location_)) + , title_(title_) + , thumbnail_(std::move(thumbnail_)) +{} + +const std::int32_t inlineQueryResultLocation::ID; + +void inlineQueryResultLocation::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineQueryResultLocation"); + s.store_field("id", id_); + s.store_object_field("location", static_cast(location_.get())); + s.store_field("title", title_); + s.store_object_field("thumbnail", static_cast(thumbnail_.get())); + s.store_class_end(); + } +} + +inlineQueryResultVenue::inlineQueryResultVenue() + : id_() + , venue_() + , thumbnail_() +{} + +inlineQueryResultVenue::inlineQueryResultVenue(string const &id_, object_ptr &&venue_, object_ptr &&thumbnail_) + : id_(id_) + , venue_(std::move(venue_)) + , thumbnail_(std::move(thumbnail_)) +{} + +const std::int32_t inlineQueryResultVenue::ID; + +void inlineQueryResultVenue::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineQueryResultVenue"); + s.store_field("id", id_); + s.store_object_field("venue", static_cast(venue_.get())); + s.store_object_field("thumbnail", static_cast(thumbnail_.get())); + s.store_class_end(); + } +} + +inlineQueryResultGame::inlineQueryResultGame() + : id_() + , game_() +{} + +inlineQueryResultGame::inlineQueryResultGame(string const &id_, object_ptr &&game_) + : id_(id_) + , game_(std::move(game_)) +{} + +const std::int32_t inlineQueryResultGame::ID; + +void inlineQueryResultGame::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineQueryResultGame"); + s.store_field("id", id_); + s.store_object_field("game", static_cast(game_.get())); + s.store_class_end(); + } +} + +inlineQueryResultAnimation::inlineQueryResultAnimation() + : id_() + , animation_() + , title_() +{} + +inlineQueryResultAnimation::inlineQueryResultAnimation(string const &id_, object_ptr &&animation_, string const &title_) + : id_(id_) + , animation_(std::move(animation_)) + , title_(title_) +{} + +const std::int32_t inlineQueryResultAnimation::ID; + +void inlineQueryResultAnimation::store(TlStorerToString &s, const char *field_name) const { + if (!LOG_IS_STRIPPED(ERROR)) { + s.store_class_begin(field_name, "inlineQueryResultAnimation"); + s.store_field("id", id_); + s.store_object_field("animation", static_cast(animation_.get())); + s.store_field("title", title_); + s.store_class_end(); + } +} + +inlineQueryResultAudio::inlineQueryResultAudio() + : id_() + , audio_() +{} + +inlineQueryResultAudio::inlineQueryResultAudio(string const &id_, object_ptr
td, unique_ptr td_db_ptr) { - gc_scheduler_id_ = min(Scheduler::instance()->sched_id() + 2, Scheduler::instance()->sched_count() - 1); - slow_net_scheduler_id_ = min(Scheduler::instance()->sched_id() + 3, Scheduler::instance()->sched_count() - 1); - td_ = td; td_db_ = std::move(td_db_ptr); @@ -344,6 +345,10 @@ void Global::add_location_access_hash(double latitude, double longitude, int64 a location_access_hashes_[get_location_key(latitude, longitude)] = access_hash; } +void Global::notify_speed_limited(bool is_upload) { + send_closure(updates_manager_, &UpdatesManager::notify_speed_limited, is_upload); +} + double get_global_server_time() { return G()->server_time(); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/Global.h b/protocols/Telegram/tdlib/td/td/telegram/Global.h index 20319d7d5c..4a2ea40c76 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Global.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Global.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -30,41 +30,64 @@ namespace td { +class AccountManager; class AnimationsManager; class AttachMenuManager; class AuthManager; class AutosaveManager; class BackgroundManager; +class BoostManager; +class BotInfoManager; +class BusinessConnectionManager; +class BusinessManager; class CallManager; +class ChatManager; class ConfigManager; class ConnectionCreator; -class ContactsManager; +class DialogActionManager; class DialogFilterManager; +class DialogInviteLinkManager; +class DialogManager; +class DialogParticipantManager; class DownloadManager; class FileManager; class FileReferenceManager; class ForumTopicManager; class GameManager; class GroupCallManager; +class InlineMessageManager; class LanguagePackManager; class LinkManager; +class MessageImportManager; class MessagesManager; class NetQueryDispatcher; +class NetQueryStats; class NotificationManager; class NotificationSettingsManager; +class OnlineManager; class OptionManager; class PasswordManager; +class PeopleNearbyManager; +class PromoDataManager; +class QuickReplyManager; +class ReactionManager; +class SavedMessagesManager; class SecretChatsManager; class SponsoredMessageManager; +class StarManager; class StateManager; class StickersManager; class StorageManager; +class StoryManager; class Td; class TdDb; class TempAuthKeyWatchdog; class ThemeManager; +class TimeZoneManager; class TopDialogManager; +class TranscriptionManager; class UpdatesManager; +class UserManager; class WebPagesManager; class Global final : public ActorContext { @@ -89,8 +112,7 @@ class Global final : public ActorContext { void log_out(Slice reason); - void close_all(Promise<> on_finished); - void close_and_destroy_all(Promise<> on_finished); + void close_all(bool destroy_flag, Promise<> on_finished); Status init(ActorId td, unique_ptr td_db_ptr) TD_WARN_UNUSED_RESULT; @@ -141,23 +163,14 @@ class Global final : public ActorContext { string get_option_string(Slice name, string default_value = "") const; bool is_server_time_reliable() const { - return server_time_difference_was_updated_; - } - double to_server_time(double now) const { - return now + get_server_time_difference(); + return server_time_difference_was_updated_.load(std::memory_order_relaxed); } double server_time() const { - return to_server_time(Time::now()); - } - double server_time_cached() const { - return to_server_time(Time::now_cached()); + return Time::now() + get_server_time_difference(); } int32 unix_time() const { return to_unix_time(server_time()); } - int32 unix_time_cached() const { - return to_unix_time(server_time_cached()); - } void update_server_time_difference(double diff, bool force); @@ -182,6 +195,13 @@ class Global final : public ActorContext { return td_; } + ActorId account_manager() const { + return account_manager_; + } + void set_account_manager(ActorId account_manager) { + account_manager_ = account_manager; + } + ActorId animations_manager() const { return animations_manager_; } @@ -214,6 +234,34 @@ class Global final : public ActorContext { background_manager_ = background_manager; } + ActorId boost_manager() const { + return boost_manager_; + } + void set_boost_manager(ActorId boost_manager) { + boost_manager_ = boost_manager; + } + + ActorId bot_info_manager() const { + return bot_info_manager_; + } + void set_bot_info_manager(ActorId bot_info_manager) { + bot_info_manager_ = bot_info_manager; + } + + ActorId business_connection_manager() const { + return business_connection_manager_; + } + void set_business_connection_manager(ActorId business_connection_manager) { + business_connection_manager_ = business_connection_manager; + } + + ActorId business_manager() const { + return business_manager_; + } + void set_business_manager(ActorId business_manager) { + business_manager_ = business_manager; + } + ActorId call_manager() const { return call_manager_; } @@ -221,6 +269,13 @@ class Global final : public ActorContext { call_manager_ = call_manager; } + ActorId chat_manager() const { + return chat_manager_; + } + void set_chat_manager(ActorId chat_manager) { + chat_manager_ = chat_manager; + } + ActorId config_manager() const { return config_manager_; } @@ -228,11 +283,11 @@ class Global final : public ActorContext { config_manager_ = config_manager; } - ActorId contacts_manager() const { - return contacts_manager_; + ActorId dialog_action_manager() const { + return dialog_action_manager_; } - void set_contacts_manager(ActorId contacts_manager) { - contacts_manager_ = contacts_manager; + void set_dialog_action_manager(ActorId dialog_action_manager) { + dialog_action_manager_ = std::move(dialog_action_manager); } ActorId dialog_filter_manager() const { @@ -242,6 +297,27 @@ class Global final : public ActorContext { dialog_filter_manager_ = std::move(dialog_filter_manager); } + ActorId dialog_invite_link_manager() const { + return dialog_invite_link_manager_; + } + void set_dialog_invite_link_manager(ActorId dialog_invite_link_manager) { + dialog_invite_link_manager_ = std::move(dialog_invite_link_manager); + } + + ActorId dialog_manager() const { + return dialog_manager_; + } + void set_dialog_manager(ActorId dialog_manager) { + dialog_manager_ = std::move(dialog_manager); + } + + ActorId dialog_participant_manager() const { + return dialog_participant_manager_; + } + void set_dialog_participant_manager(ActorId dialog_participant_manager) { + dialog_participant_manager_ = std::move(dialog_participant_manager); + } + ActorId download_manager() const { return download_manager_; } @@ -284,6 +360,13 @@ class Global final : public ActorContext { group_call_manager_ = group_call_manager; } + ActorId inline_message_manager() const { + return inline_message_manager_; + } + void set_inline_message_manager(ActorId inline_message_manager) { + inline_message_manager_ = inline_message_manager; + } + ActorId language_pack_manager() const { return language_pack_manager_; } @@ -298,6 +381,13 @@ class Global final : public ActorContext { link_manager_ = link_manager; } + ActorId message_import_manager() const { + return message_import_manager_; + } + void set_message_import_manager(ActorId message_import_manager) { + message_import_manager_ = message_import_manager; + } + ActorId messages_manager() const { return messages_manager_; } @@ -319,9 +409,17 @@ class Global final : public ActorContext { notification_settings_manager_ = notification_settings_manager; } + ActorId online_manager() const { + return online_manager_; + } + void set_online_manager(ActorId online_manager) { + online_manager_ = online_manager; + } + void set_option_manager(OptionManager *option_manager) { option_manager_ = option_manager; } + OptionManager *get_option_manager(); ActorId password_manager() const { return password_manager_; @@ -330,6 +428,41 @@ class Global final : public ActorContext { password_manager_ = password_manager; } + ActorId people_nearby_manager() const { + return people_nearby_manager_; + } + void set_people_nearby_manager(ActorId people_nearby_manager) { + people_nearby_manager_ = people_nearby_manager; + } + + ActorId promo_data_manager() const { + return promo_data_manager_; + } + void set_promo_data_manager(ActorId promo_data_manager) { + promo_data_manager_ = promo_data_manager; + } + + ActorId quick_reply_manager() const { + return quick_reply_manager_; + } + void set_quick_reply_manager(ActorId quick_reply_manager) { + quick_reply_manager_ = quick_reply_manager; + } + + ActorId reaction_manager() const { + return reaction_manager_; + } + void set_reaction_manager(ActorId reaction_manager) { + reaction_manager_ = reaction_manager; + } + + ActorId saved_messages_manager() const { + return saved_messages_manager_; + } + void set_saved_messages_manager(ActorId saved_messages_manager) { + saved_messages_manager_ = saved_messages_manager; + } + ActorId secret_chats_manager() const { return secret_chats_manager_; } @@ -344,6 +477,13 @@ class Global final : public ActorContext { sponsored_message_manager_ = sponsored_message_manager; } + ActorId star_manager() const { + return star_manager_; + } + void set_star_manager(ActorId star_manager) { + star_manager_ = star_manager; + } + ActorId stickers_manager() const { return stickers_manager_; } @@ -358,6 +498,13 @@ class Global final : public ActorContext { storage_manager_ = storage_manager; } + ActorId story_manager() const { + return story_manager_; + } + void set_story_manager(ActorId story_manager) { + story_manager_ = story_manager; + } + ActorId theme_manager() const { return theme_manager_; } @@ -365,6 +512,13 @@ class Global final : public ActorContext { theme_manager_ = theme_manager; } + ActorId time_zone_manager() const { + return time_zone_manager_; + } + void set_time_zone_manager(ActorId time_zone_manager) { + time_zone_manager_ = time_zone_manager; + } + ActorId top_dialog_manager() const { return top_dialog_manager_; } @@ -372,6 +526,13 @@ class Global final : public ActorContext { top_dialog_manager_ = top_dialog_manager; } + ActorId transcription_manager() const { + return transcription_manager_; + } + void set_transcription_manager(ActorId transcription_manager) { + transcription_manager_ = transcription_manager; + } + ActorId updates_manager() const { return updates_manager_; } @@ -379,6 +540,13 @@ class Global final : public ActorContext { updates_manager_ = updates_manager; } + ActorId user_manager() const { + return user_manager_; + } + void set_user_manager(ActorId user_manager) { + user_manager_ = user_manager; + } + ActorId web_pages_manager() const { return web_pages_manager_; } @@ -410,6 +578,10 @@ class Global final : public ActorContext { return use_file_database(); } + int32 get_database_scheduler_id() { + return database_scheduler_id_; + } + int32 get_gc_scheduler_id() const { return gc_scheduler_id_; } @@ -476,6 +648,10 @@ class Global final : public ActorContext { static int32 get_retry_after(int32 error_code, Slice error_message); + static int32 get_retry_after(const Status &error) { + return get_retry_after(error.code(), error.message()); + } + const std::vector> &get_net_stats_file_callbacks() { return net_stats_file_callbacks_; } @@ -491,40 +667,64 @@ class Global final : public ActorContext { store_all_files_in_files_directory_ = flag; } + void notify_speed_limited(bool is_upload); + private: std::shared_ptr dh_config_; unique_ptr td_db_; ActorId td_; + ActorId account_manager_; ActorId animations_manager_; ActorId attach_menu_manager_; ActorId auth_manager_; ActorId autosave_manager_; ActorId background_manager_; + ActorId boost_manager_; + ActorId bot_info_manager_; + ActorId business_connection_manager_; + ActorId business_manager_; ActorId call_manager_; + ActorId chat_manager_; ActorId config_manager_; - ActorId contacts_manager_; + ActorId dialog_action_manager_; ActorId dialog_filter_manager_; + ActorId dialog_invite_link_manager_; + ActorId dialog_manager_; + ActorId dialog_participant_manager_; ActorId download_manager_; ActorId file_manager_; ActorId file_reference_manager_; ActorId forum_topic_manager_; ActorId game_manager_; ActorId group_call_manager_; + ActorId inline_message_manager_; ActorId language_pack_manager_; ActorId link_manager_; + ActorId message_import_manager_; ActorId messages_manager_; ActorId notification_manager_; ActorId notification_settings_manager_; + ActorId online_manager_; ActorId password_manager_; + ActorId people_nearby_manager_; + ActorId promo_data_manager_; + ActorId quick_reply_manager_; + ActorId reaction_manager_; + ActorId saved_messages_manager_; ActorId secret_chats_manager_; ActorId sponsored_message_manager_; + ActorId star_manager_; ActorId stickers_manager_; ActorId storage_manager_; + ActorId story_manager_; ActorId theme_manager_; + ActorId time_zone_manager_; ActorId top_dialog_manager_; + ActorId transcription_manager_; ActorId updates_manager_; + ActorId user_manager_; ActorId web_pages_manager_; ActorOwn connection_creator_; ActorOwn temp_auth_key_watchdog_; @@ -533,6 +733,7 @@ class Global final : public ActorContext { OptionManager *option_manager_ = nullptr; + int32 database_scheduler_id_ = 0; int32 gc_scheduler_id_ = 0; int32 slow_net_scheduler_id_ = 0; @@ -566,8 +767,6 @@ class Global final : public ActorContext { const OptionManager *get_option_manager() const; - OptionManager *get_option_manager(); - void do_save_server_time_difference(); void do_close(Promise<> on_finish, bool destroy_flag); diff --git a/protocols/Telegram/tdlib/td/td/telegram/GlobalPrivacySettings.cpp b/protocols/Telegram/tdlib/td/td/telegram/GlobalPrivacySettings.cpp new file mode 100644 index 0000000000..70ae812aaa --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/GlobalPrivacySettings.cpp @@ -0,0 +1,189 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/GlobalPrivacySettings.h" + +#include "td/telegram/ConfigManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/net/NetQueryCreator.h" +#include "td/telegram/SuggestedAction.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" + +#include "td/actor/actor.h" + +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/Status.h" + +namespace td { + +class GetGlobalPrivacySettingsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetGlobalPrivacySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::account_getGlobalPrivacySettings(), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG(INFO) << "Receive result for GetGlobalPrivacySettingsQuery: " << to_string(result_ptr.ok()); + promise_.set_value(GlobalPrivacySettings(result_ptr.move_as_ok())); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class SetGlobalPrivacySettingsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit SetGlobalPrivacySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(GlobalPrivacySettings settings) { + send_query(G()->net_query_creator().create( + telegram_api::account_setGlobalPrivacySettings(settings.get_input_global_privacy_settings()), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +GlobalPrivacySettings::GlobalPrivacySettings(telegram_api::object_ptr &&settings) + : archive_and_mute_new_noncontact_peers_(settings->archive_and_mute_new_noncontact_peers_) + , keep_archived_unmuted_(settings->keep_archived_unmuted_) + , keep_archived_folders_(settings->keep_archived_folders_) + , hide_read_marks_(settings->hide_read_marks_) + , new_noncontact_peers_require_premium_(settings->new_noncontact_peers_require_premium_) { +} + +GlobalPrivacySettings::GlobalPrivacySettings(td_api::object_ptr &&settings) + : set_type_(SetType::Archive) { + if (settings != nullptr) { + archive_and_mute_new_noncontact_peers_ = settings->archive_and_mute_new_chats_from_unknown_users_; + keep_archived_unmuted_ = settings->keep_unmuted_chats_archived_; + keep_archived_folders_ = settings->keep_chats_from_folders_archived_; + } +} + +GlobalPrivacySettings::GlobalPrivacySettings(td_api::object_ptr &&settings) + : set_type_(SetType::ReadDate) { + hide_read_marks_ = settings == nullptr || !settings->show_read_date_; +} + +GlobalPrivacySettings::GlobalPrivacySettings(td_api::object_ptr &&settings) + : set_type_(SetType::NewChat) { + new_noncontact_peers_require_premium_ = settings == nullptr || !settings->allow_new_chats_from_unknown_users_; +} + +void GlobalPrivacySettings::apply_changes(const GlobalPrivacySettings &set_settings) { + CHECK(set_type_ == SetType::None); + switch (set_settings.set_type_) { + case SetType::Archive: + archive_and_mute_new_noncontact_peers_ = set_settings.archive_and_mute_new_noncontact_peers_; + keep_archived_unmuted_ = set_settings.keep_archived_unmuted_; + keep_archived_folders_ = set_settings.keep_archived_folders_; + break; + case SetType::ReadDate: + hide_read_marks_ = set_settings.hide_read_marks_; + break; + case SetType::NewChat: + new_noncontact_peers_require_premium_ = set_settings.new_noncontact_peers_require_premium_; + break; + default: + UNREACHABLE(); + break; + } +} + +telegram_api::object_ptr GlobalPrivacySettings::get_input_global_privacy_settings() + const { + CHECK(set_type_ == SetType::None); + int32 flags = 0; + if (archive_and_mute_new_noncontact_peers_) { + flags |= telegram_api::globalPrivacySettings::ARCHIVE_AND_MUTE_NEW_NONCONTACT_PEERS_MASK; + } + if (keep_archived_unmuted_) { + flags |= telegram_api::globalPrivacySettings::KEEP_ARCHIVED_UNMUTED_MASK; + } + if (keep_archived_folders_) { + flags |= telegram_api::globalPrivacySettings::KEEP_ARCHIVED_FOLDERS_MASK; + } + if (hide_read_marks_) { + flags |= telegram_api::globalPrivacySettings::HIDE_READ_MARKS_MASK; + } + if (new_noncontact_peers_require_premium_) { + flags |= telegram_api::globalPrivacySettings::NEW_NONCONTACT_PEERS_REQUIRE_PREMIUM_MASK; + } + return telegram_api::make_object( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/); +} + +td_api::object_ptr GlobalPrivacySettings::get_archive_chat_list_settings_object() + const { + CHECK(set_type_ == SetType::None); + return td_api::make_object(archive_and_mute_new_noncontact_peers_, + keep_archived_unmuted_, keep_archived_folders_); +} + +td_api::object_ptr GlobalPrivacySettings::get_read_date_privacy_settings_object() + const { + CHECK(set_type_ == SetType::None); + return td_api::make_object(!hide_read_marks_); +} + +td_api::object_ptr GlobalPrivacySettings::get_new_chat_privacy_settings_object() const { + CHECK(set_type_ == SetType::None); + return td_api::make_object(!new_noncontact_peers_require_premium_); +} + +void GlobalPrivacySettings::get_global_privacy_settings(Td *td, Promise &&promise) { + td->create_handler(std::move(promise))->send(); +} + +void GlobalPrivacySettings::set_global_privacy_settings(Td *td, GlobalPrivacySettings settings, + Promise &&promise) { + CHECK(settings.set_type_ != SetType::None); + if (settings.archive_and_mute_new_noncontact_peers_) { + send_closure(td->config_manager_, &ConfigManager::hide_suggested_action, + SuggestedAction{SuggestedAction::Type::EnableArchiveAndMuteNewChats}); + } + + get_global_privacy_settings( + td, PromiseCreator::lambda([td, set_settings = std::move(settings), + promise = std::move(promise)](Result result) mutable { + G()->ignore_result_if_closing(result); + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + auto settings = result.move_as_ok(); + settings.apply_changes(set_settings); + td->create_handler(std::move(promise))->send(std::move(settings)); + })); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/GlobalPrivacySettings.h b/protocols/Telegram/tdlib/td/td/telegram/GlobalPrivacySettings.h new file mode 100644 index 0000000000..3c941b7de1 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/GlobalPrivacySettings.h @@ -0,0 +1,52 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/Promise.h" + +namespace td { + +class Td; + +class GlobalPrivacySettings { + enum class SetType : int32 { None, Archive, ReadDate, NewChat }; + SetType set_type_ = SetType::None; + bool archive_and_mute_new_noncontact_peers_ = false; + bool keep_archived_unmuted_ = false; + bool keep_archived_folders_ = false; + bool hide_read_marks_ = false; + bool new_noncontact_peers_require_premium_ = false; + + void apply_changes(const GlobalPrivacySettings &set_settings); + + public: + explicit GlobalPrivacySettings(telegram_api::object_ptr &&settings); + + explicit GlobalPrivacySettings(td_api::object_ptr &&settings); + + explicit GlobalPrivacySettings(td_api::object_ptr &&settings); + + explicit GlobalPrivacySettings(td_api::object_ptr &&settings); + + telegram_api::object_ptr get_input_global_privacy_settings() const; + + td_api::object_ptr get_archive_chat_list_settings_object() const; + + td_api::object_ptr get_read_date_privacy_settings_object() const; + + td_api::object_ptr get_new_chat_privacy_settings_object() const; + + static void get_global_privacy_settings(Td *td, Promise &&promise); + + static void set_global_privacy_settings(Td *td, GlobalPrivacySettings settings, Promise &&promise); +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/GroupCallManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/GroupCallManager.cpp index 0e7895894c..a18193d9e3 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/GroupCallManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/GroupCallManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,9 +8,12 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/AuthManager.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/DialogAction.h" +#include "td/telegram/DialogActionManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/DialogParticipantFilter.h" +#include "td/telegram/DialogParticipantManager.h" #include "td/telegram/Global.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessageSender.h" @@ -19,7 +22,9 @@ #include "td/telegram/net/DcId.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" @@ -122,7 +127,7 @@ class GetGroupCallJoinAsQuery final : public Td::ResultHandler { void send(DialogId dialog_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create(telegram_api::phone_getGroupCallJoinAs(std::move(input_peer)))); @@ -137,14 +142,14 @@ class GetGroupCallJoinAsQuery final : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for GetGroupCallJoinAsQuery: " << to_string(ptr); - td_->contacts_manager_->on_get_users(std::move(ptr->users_), "GetGroupCallJoinAsQuery"); - td_->contacts_manager_->on_get_chats(std::move(ptr->chats_), "GetGroupCallJoinAsQuery"); + td_->user_manager_->on_get_users(std::move(ptr->users_), "GetGroupCallJoinAsQuery"); + td_->chat_manager_->on_get_chats(std::move(ptr->chats_), "GetGroupCallJoinAsQuery"); promise_.set_value(convert_message_senders_object(td_, ptr->peers_)); } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetGroupCallJoinAsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetGroupCallJoinAsQuery"); promise_.set_error(std::move(status)); } }; @@ -157,10 +162,10 @@ class SaveDefaultGroupCallJoinAsQuery final : public Td::ResultHandler { } void send(DialogId dialog_id, DialogId as_dialog_id) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); - auto as_input_peer = td_->messages_manager_->get_input_peer(as_dialog_id, AccessRights::Read); + auto as_input_peer = td_->dialog_manager_->get_input_peer(as_dialog_id, AccessRights::Read); CHECK(as_input_peer != nullptr); send_query(G()->net_query_creator().create( @@ -180,7 +185,7 @@ class SaveDefaultGroupCallJoinAsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - // td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetGroupCallJoinAsQuery"); + // td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetGroupCallJoinAsQuery"); promise_.set_error(std::move(status)); } }; @@ -196,7 +201,7 @@ class CreateGroupCallQuery final : public Td::ResultHandler { void send(DialogId dialog_id, const string &title, int32 start_date, bool is_rtmp_stream) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); int32 flags = 0; @@ -242,7 +247,7 @@ class CreateGroupCallQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "CreateGroupCallQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "CreateGroupCallQuery"); promise_.set_error(std::move(status)); } }; @@ -259,7 +264,7 @@ class GetGroupCallRtmpStreamUrlGroupCallQuery final : public Td::ResultHandler { void send(DialogId dialog_id, bool revoke) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query( @@ -277,7 +282,7 @@ class GetGroupCallRtmpStreamUrlGroupCallQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetGroupCallRtmpStreamUrlGroupCallQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetGroupCallRtmpStreamUrlGroupCallQuery"); promise_.set_error(std::move(status)); } }; @@ -429,7 +434,7 @@ class JoinGroupCallQuery final : public Td::ResultHandler { tl_object_ptr join_as_input_peer; if (as_dialog_id.is_valid()) { - join_as_input_peer = td_->messages_manager_->get_input_peer(as_dialog_id, AccessRights::Read); + join_as_input_peer = td_->dialog_manager_->get_input_peer(as_dialog_id, AccessRights::Read); } else { join_as_input_peer = make_tl_object(); } @@ -747,7 +752,7 @@ class EditGroupCallParticipantQuery final : public Td::ResultHandler { int32 volume_level, bool set_raise_hand, bool raise_hand, bool set_video_is_stopped, bool video_is_stopped, bool set_video_is_paused, bool video_is_paused, bool set_presentation_is_paused, bool presentation_is_paused) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Know); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Know); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -1097,8 +1102,8 @@ void GroupCallManager::on_send_speaking_action_timeout(GroupCallId group_call_id pending_send_speaking_action_timeout_.add_timeout_in(group_call_id.get(), 4.0); - td_->messages_manager_->send_dialog_action(group_call->dialog_id, MessageId(), DialogAction::get_speaking_action(), - Promise()); + td_->dialog_action_manager_->send_dialog_action(group_call->dialog_id, MessageId(), {}, + DialogAction::get_speaking_action(), Promise()); } void GroupCallManager::on_recent_speaker_update_timeout_callback(void *group_call_manager_ptr, @@ -1218,22 +1223,14 @@ GroupCallManager::GroupCall *GroupCallManager::get_group_call(InputGroupCallId i } Status GroupCallManager::can_join_group_calls(DialogId dialog_id) const { - if (!dialog_id.is_valid()) { - return Status::Error(400, "Invalid chat identifier specified"); - } - if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_group_call_join_as")) { - return Status::Error(400, "Chat not found"); - } - if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access chat"); - } + TRY_STATUS(td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Read, "can_join_group_calls")); switch (dialog_id.get_type()) { case DialogType::Chat: case DialogType::Channel: break; case DialogType::User: - case DialogType::SecretChat: return Status::Error(400, "Chat can't have a voice chat"); + case DialogType::SecretChat: case DialogType::None: default: UNREACHABLE(); @@ -1246,14 +1243,14 @@ Status GroupCallManager::can_manage_group_calls(DialogId dialog_id) const { switch (dialog_id.get_type()) { case DialogType::Chat: { auto chat_id = dialog_id.get_chat_id(); - if (!td_->contacts_manager_->get_chat_permissions(chat_id).can_manage_calls()) { + if (!td_->chat_manager_->get_chat_permissions(chat_id).can_manage_calls()) { return Status::Error(400, "Not enough rights in the chat"); } break; } case DialogType::Channel: { auto channel_id = dialog_id.get_channel_id(); - if (!td_->contacts_manager_->get_channel_permissions(channel_id).can_manage_calls()) { + if (!td_->chat_manager_->get_channel_permissions(channel_id).can_manage_calls()) { return Status::Error(400, "Not enough rights in the chat"); } break; @@ -1303,13 +1300,13 @@ void GroupCallManager::set_group_call_default_join_as(DialogId dialog_id, Dialog switch (as_dialog_id.get_type()) { case DialogType::User: - if (as_dialog_id != DialogId(td_->contacts_manager_->get_my_id())) { + if (as_dialog_id != td_->dialog_manager_->get_my_dialog_id()) { return promise.set_error(Status::Error(400, "Can't join voice chat as another user")); } break; case DialogType::Chat: case DialogType::Channel: - if (!td_->messages_manager_->have_dialog_force(as_dialog_id, "set_group_call_default_join_as 2")) { + if (!td_->dialog_manager_->have_dialog_force(as_dialog_id, "set_group_call_default_join_as 2")) { return promise.set_error(Status::Error(400, "Participant chat not found")); } break; @@ -1318,7 +1315,7 @@ void GroupCallManager::set_group_call_default_join_as(DialogId dialog_id, Dialog default: return promise.set_error(Status::Error(400, "Invalid default participant identifier specified")); } - if (!td_->messages_manager_->have_input_peer(as_dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(as_dialog_id, false, AccessRights::Read)) { return promise.set_error(Status::Error(400, "Can't access specified default participant chat")); } @@ -1328,16 +1325,8 @@ void GroupCallManager::set_group_call_default_join_as(DialogId dialog_id, Dialog void GroupCallManager::create_voice_chat(DialogId dialog_id, string title, int32 start_date, bool is_rtmp_stream, Promise &&promise) { - if (!dialog_id.is_valid()) { - return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); - } - if (!td_->messages_manager_->have_dialog_force(dialog_id, "create_voice_chat")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access chat")); - } - + TRY_STATUS_PROMISE( + promise, td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Read, "create_voice_chat")); TRY_STATUS_PROMISE(promise, can_manage_group_calls(dialog_id)); title = clean_name(title, MAX_TITLE_LENGTH); @@ -1357,16 +1346,8 @@ void GroupCallManager::create_voice_chat(DialogId dialog_id, string title, int32 void GroupCallManager::get_voice_chat_rtmp_stream_url(DialogId dialog_id, bool revoke, Promise> &&promise) { - if (!dialog_id.is_valid()) { - return promise.set_error(Status::Error(400, "Invalid chat identifier specified")); - } - if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_voice_chat_rtmp_stream_url")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access chat")); - } - + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Read, + "get_voice_chat_rtmp_stream_url")); TRY_STATUS_PROMISE(promise, can_manage_group_calls(dialog_id)); td_->create_handler(std::move(promise))->send(dialog_id, revoke); @@ -1456,8 +1437,8 @@ void GroupCallManager::finish_get_group_call(InputGroupCallId input_group_call_i load_group_call_queries_.erase(it); if (result.is_ok()) { - td_->contacts_manager_->on_get_users(std::move(result.ok_ref()->users_), "finish_get_group_call"); - td_->contacts_manager_->on_get_chats(std::move(result.ok_ref()->chats_), "finish_get_group_call"); + td_->user_manager_->on_get_users(std::move(result.ok_ref()->users_), "finish_get_group_call"); + td_->chat_manager_->on_get_chats(std::move(result.ok_ref()->chats_), "finish_get_group_call"); if (update_group_call(result.ok()->call_, DialogId()) != input_group_call_id) { LOG(ERROR) << "Expected " << input_group_call_id << ", but received " << to_string(result.ok()); @@ -1601,8 +1582,8 @@ void GroupCallManager::on_get_group_call_participants( LOG(INFO) << "Receive group call participants: " << to_string(participants); CHECK(participants != nullptr); - td_->contacts_manager_->on_get_users(std::move(participants->users_), "on_get_group_call_participants"); - td_->contacts_manager_->on_get_chats(std::move(participants->chats_), "on_get_group_call_participants"); + td_->user_manager_->on_get_users(std::move(participants->users_), "on_get_group_call_participants"); + td_->chat_manager_->on_get_chats(std::move(participants->chats_), "on_get_group_call_participants"); if (!need_group_call_participants(input_group_call_id)) { return; @@ -1721,7 +1702,7 @@ GroupCallParticipant *GroupCallManager::get_group_call_participant(GroupCallPart if (!dialog_id.is_valid()) { return nullptr; } - if (dialog_id == DialogId(td_->contacts_manager_->get_my_id())) { + if (dialog_id == td_->dialog_manager_->get_my_dialog_id()) { for (auto &group_call_participant : group_call_participants->participants) { if (group_call_participant.is_self) { return &group_call_participant; @@ -1807,7 +1788,7 @@ void GroupCallManager::on_update_group_call_participants( } if (!missing_participants.empty()) { LOG(INFO) << "Can't apply min updates about " << missing_participants << " in " << input_group_call_id; - auto input_peers = transform(missing_participants, &MessagesManager::get_input_peer_force); + auto input_peers = transform(missing_participants, &DialogManager::get_input_peer_force); auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), input_group_call_id, participants = std::move(participants), version](Result &&result) mutable { @@ -1843,7 +1824,7 @@ void GroupCallManager::on_update_group_call_participants( } auto dialog_id = participant.dialog_id; if (dialog_id.get_type() != DialogType::User && participant.joined_date != 0) { - td_->messages_manager_->force_create_dialog(dialog_id, "on_update_group_call_participants 2", true); + td_->dialog_manager_->force_create_dialog(dialog_id, "on_update_group_call_participants 2", true); } bool is_versioned = GroupCallParticipant::is_versioned_update(group_call_participant); @@ -2087,7 +2068,7 @@ void GroupCallManager::process_group_call_participants( continue; } if (participant.dialog_id.get_type() != DialogType::User) { - td_->messages_manager_->force_create_dialog(participant.dialog_id, "process_group_call_participants", true); + td_->dialog_manager_->force_create_dialog(participant.dialog_id, "process_group_call_participants", true); } on_participant_speaking_in_group_call(input_group_call_id, participant); @@ -2119,7 +2100,7 @@ void GroupCallManager::process_group_call_participants( continue; } if (participant.dialog_id.get_type() != DialogType::User) { - td_->messages_manager_->force_create_dialog(participant.dialog_id, "process_group_call_participants", true); + td_->dialog_manager_->force_create_dialog(participant.dialog_id, "process_group_call_participants", true); } if (is_load) { @@ -2240,7 +2221,7 @@ void GroupCallManager::process_my_group_call_participant(InputGroupCallId input_ return; } auto my_participant = get_group_call_participant(add_group_call_participants(input_group_call_id), - DialogId(td_->contacts_manager_->get_my_id())); + td_->dialog_manager_->get_my_dialog_id()); if (my_participant == nullptr || my_participant->is_fake || my_participant->joined_date < participant.joined_date || (my_participant->joined_date <= participant.joined_date && my_participant->audio_source != participant.audio_source)) { @@ -2629,7 +2610,7 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di bool have_as_dialog_id = true; { - auto my_dialog_id = DialogId(td_->contacts_manager_->get_my_id()); + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); if (!as_dialog_id.is_valid()) { as_dialog_id = my_dialog_id; } @@ -2638,20 +2619,17 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di if (as_dialog_id != my_dialog_id) { return promise.set_error(Status::Error(400, "Can't join voice chat as another user")); } - if (!td_->contacts_manager_->have_user_force(as_dialog_id.get_user_id())) { + if (!td_->user_manager_->have_user_force(as_dialog_id.get_user_id(), "join_group_call")) { have_as_dialog_id = false; } } else { - if (!td_->messages_manager_->have_dialog_force(as_dialog_id, "join_group_call")) { + if (!td_->dialog_manager_->have_dialog_force(as_dialog_id, "join_group_call")) { return promise.set_error(Status::Error(400, "Join as chat not found")); } } - if (!td_->messages_manager_->have_input_peer(as_dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(as_dialog_id, false, AccessRights::Read)) { return promise.set_error(Status::Error(400, "Can't access the join as participant")); } - if (dialog_type == DialogType::SecretChat) { - return promise.set_error(Status::Error(400, "Can't join voice chat as a secret chat")); - } } if (group_call->is_being_left) { @@ -2682,14 +2660,14 @@ void GroupCallManager::join_group_call(GroupCallId group_call_id, DialogId as_di true); } else { if (as_dialog_id.get_type() != DialogType::User) { - td_->messages_manager_->force_create_dialog(as_dialog_id, "join_group_call"); + td_->dialog_manager_->force_create_dialog(as_dialog_id, "join_group_call"); } } if (group_call->is_inited && have_as_dialog_id) { GroupCallParticipant participant; participant.is_self = true; participant.dialog_id = as_dialog_id; - participant.about = td_->contacts_manager_->get_dialog_about(participant.dialog_id); + participant.about = td_->dialog_manager_->get_dialog_about(participant.dialog_id); participant.audio_source = audio_source; participant.joined_date = G()->unix_time(); // if can_self_unmute has never been inited from self-participant, @@ -2814,7 +2792,7 @@ void GroupCallManager::try_load_group_call_administrators(InputGroupCallId input send_closure(actor_id, &GroupCallManager::finish_load_group_call_administrators, input_group_call_id, std::move(result)); }); - td_->contacts_manager_->search_dialog_participants( + td_->dialog_participant_manager_->search_dialog_participants( dialog_id, string(), 100, DialogParticipantFilter(td_api::make_object()), std::move(promise)); } @@ -2842,7 +2820,7 @@ void GroupCallManager::finish_load_group_call_administrators(InputGroupCallId in auto participants = result.move_as_ok(); for (auto &administrator : participants.participants_) { if (administrator.status_.can_manage_calls() && - administrator.dialog_id_ != DialogId(td_->contacts_manager_->get_my_id())) { + administrator.dialog_id_ != td_->dialog_manager_->get_my_dialog_id()) { administrator_dialog_ids.push_back(administrator.dialog_id_); } } @@ -2953,7 +2931,7 @@ void GroupCallManager::finish_join_group_call(InputGroupCallId input_group_call_ if (group_call != nullptr && group_call->dialog_id.is_valid()) { update_group_call_dialog(group_call, "finish_join_group_call", false); - td_->messages_manager_->reload_dialog_info_full(group_call->dialog_id, "finish_join_group_call"); + td_->dialog_manager_->reload_dialog_info_full(group_call->dialog_id, "finish_join_group_call"); } } @@ -3516,9 +3494,9 @@ void GroupCallManager::invite_group_call_participants(GroupCallId group_call_id, TRY_RESULT_PROMISE(promise, input_group_call_id, get_input_group_call_id(group_call_id)); vector> input_users; - auto my_user_id = td_->contacts_manager_->get_my_id(); + auto my_user_id = td_->user_manager_->get_my_id(); for (auto user_id : user_ids) { - TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(user_id)); + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(user_id)); if (user_id == my_user_id) { // can't invite self @@ -4121,9 +4099,9 @@ void GroupCallManager::on_group_call_left_impl(GroupCall *group_call, bool need_ group_call->need_rejoin = need_rejoin && !group_call->is_being_left; if (group_call->need_rejoin && group_call->dialog_id.is_valid()) { auto dialog_id = group_call->dialog_id; - if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read) || + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read) || (dialog_id.get_type() == DialogType::Chat && - !td_->contacts_manager_->get_chat_status(dialog_id.get_chat_id()).is_member())) { + !td_->chat_manager_->get_chat_status(dialog_id.get_chat_id()).is_member())) { group_call->need_rejoin = false; } } @@ -4442,7 +4420,7 @@ InputGroupCallId GroupCallManager::update_group_call(const tl_object_ptrscheduled_start_date && call.scheduled_start_date_version >= group_call->scheduled_start_date_version) { - LOG_IF(ERROR, group_call->scheduled_start_date == 0) << call.group_call_id << " became scheduled"; + LOG_IF(ERROR, group_call->scheduled_start_date == 0) << input_group_call_id << " became scheduled"; group_call->scheduled_start_date = call.scheduled_start_date; group_call->scheduled_start_date_version = call.scheduled_start_date_version; need_update = true; @@ -4545,7 +4523,7 @@ void GroupCallManager::on_user_speaking_in_group_call(GroupCallId group_call_id, return; } - if (!td_->messages_manager_->have_dialog_info_force(dialog_id) || + if (!td_->dialog_manager_->have_dialog_info_force(dialog_id, "on_user_speaking_in_group_call") || (!is_recursive && need_group_call_participants(input_group_call_id, group_call) && get_group_call_participant(input_group_call_id, dialog_id) == nullptr)) { if (is_recursive) { @@ -4559,7 +4537,7 @@ void GroupCallManager::on_user_speaking_in_group_call(GroupCallId group_call_id, } }); vector> input_peers; - input_peers.push_back(MessagesManager::get_input_peer_force(dialog_id)); + input_peers.push_back(DialogManager::get_input_peer_force(dialog_id)); td_->create_handler(std::move(query_promise)) ->send(input_group_call_id, std::move(input_peers), {}); } @@ -4591,7 +4569,7 @@ void GroupCallManager::on_user_speaking_in_group_call(GroupCallId group_call_id, for (size_t i = 0; i <= recent_speakers->users.size(); i++) { if (i == recent_speakers->users.size() || recent_speakers->users[i].second <= date) { if (dialog_id.get_type() != DialogType::User) { - td_->messages_manager_->force_create_dialog(dialog_id, "on_user_speaking_in_group_call", true); + td_->dialog_manager_->force_create_dialog(dialog_id, "on_user_speaking_in_group_call", true); } recent_speakers->users.insert(recent_speakers->users.begin() + i, {dialog_id, date}); break; diff --git a/protocols/Telegram/tdlib/td/td/telegram/GroupCallParticipant.cpp b/protocols/Telegram/tdlib/td/td/telegram/GroupCallParticipant.cpp index 9950212323..2ecfcece32 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/GroupCallParticipant.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/GroupCallParticipant.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,6 +8,7 @@ #include "td/telegram/Global.h" #include "td/telegram/MessageSender.h" +#include "td/telegram/telegram_api.h" #include "td/utils/logging.h" diff --git a/protocols/Telegram/tdlib/td/td/telegram/GroupCallVideoPayload.cpp b/protocols/Telegram/tdlib/td/td/telegram/GroupCallVideoPayload.cpp index 901ab59fee..7d7057a7c8 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/GroupCallVideoPayload.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/GroupCallVideoPayload.cpp @@ -1,11 +1,13 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/GroupCallVideoPayload.h" +#include "td/telegram/telegram_api.h" + #include "td/utils/algorithm.h" namespace td { diff --git a/protocols/Telegram/tdlib/td/td/telegram/HashtagHints.cpp b/protocols/Telegram/tdlib/td/td/telegram/HashtagHints.cpp index 0c094a1adf..2c953b2501 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/HashtagHints.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/HashtagHints.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,12 +13,14 @@ #include "td/utils/HashTableUtils.h" #include "td/utils/logging.h" +#include "td/utils/Slice.h" #include "td/utils/tl_helpers.h" #include "td/utils/utf8.h" namespace td { -HashtagHints::HashtagHints(string mode, ActorShared<> parent) : mode_(std::move(mode)), parent_(std::move(parent)) { +HashtagHints::HashtagHints(string mode, char first_character, ActorShared<> parent) + : mode_(std::move(mode)), first_character_(first_character), parent_(std::move(parent)) { } void HashtagHints::start_up() { @@ -36,35 +38,44 @@ void HashtagHints::hashtag_used(const string &hashtag) { } hashtag_used_impl(hashtag); G()->td_db()->get_sqlite_pmc()->set(get_key(), serialize(keys_to_strings(hints_.search_empty(101).second)), - Promise<>()); + Promise()); } -void HashtagHints::remove_hashtag(string hashtag, Promise<> promise) { +void HashtagHints::remove_hashtag(string hashtag, Promise promise) { if (!sync_with_db_) { - promise.set_value(Unit()); - return; + return promise.set_value(Unit()); } - if (hashtag[0] == '#') { + if (hashtag[0] == first_character_) { hashtag = hashtag.substr(1); } auto key = Hash()(hashtag); if (hints_.has_key(key)) { hints_.remove(key); G()->td_db()->get_sqlite_pmc()->set(get_key(), serialize(keys_to_strings(hints_.search_empty(101).second)), - Promise<>()); + Promise()); promise.set_value(Unit()); // set promise explicitly, because sqlite_pmc waits for too long before setting promise } else { promise.set_value(Unit()); } } -void HashtagHints::query(const string &prefix, int32 limit, Promise> promise) { +void HashtagHints::clear(Promise promise) { if (!sync_with_db_) { - promise.set_value(std::vector()); + return promise.set_value(Unit()); + } + hints_ = {}; + G()->td_db()->get_sqlite_pmc()->set(get_key(), serialize(vector()), Promise()); + promise.set_value(Unit()); +} + +void HashtagHints::query(const string &prefix, int32 limit, Promise> promise) { + if (!sync_with_db_) { + promise.set_value(vector()); return; } - auto result = prefix.empty() ? hints_.search_empty(limit) : hints_.search(prefix, limit); + auto query = Slice(prefix).substr(prefix[0] == first_character_ ? 1 : 0); + auto result = query.empty() ? hints_.search_empty(limit) : hints_.search(query, limit); promise.set_value(keys_to_strings(result.second)); } @@ -92,7 +103,7 @@ void HashtagHints::from_db(Result data, bool dummy) { if (data.is_error() || data.ok().empty()) { return; } - std::vector hashtags; + vector hashtags; auto status = unserialize(hashtags, data.ok()); if (status.is_error()) { LOG(ERROR) << "Failed to unserialize hashtag hints: " << status; @@ -104,12 +115,13 @@ void HashtagHints::from_db(Result data, bool dummy) { } } -std::vector HashtagHints::keys_to_strings(const std::vector &keys) { - std::vector result; +vector HashtagHints::keys_to_strings(const vector &keys) { + vector result; result.reserve(keys.size()); for (auto &it : keys) { result.push_back(hints_.key_to_string(it)); } return result; } + } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/HashtagHints.h b/protocols/Telegram/tdlib/td/td/telegram/HashtagHints.h index bdf806d3f8..1dcd6878fa 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/HashtagHints.h +++ b/protocols/Telegram/tdlib/td/td/telegram/HashtagHints.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -17,17 +17,20 @@ namespace td { class HashtagHints final : public Actor { public: - HashtagHints(string mode, ActorShared<> parent); + HashtagHints(string mode, char first_character, ActorShared<> parent); void hashtag_used(const string &hashtag); - void remove_hashtag(string hashtag, Promise<> promise); + void remove_hashtag(string hashtag, Promise promise); - void query(const string &prefix, int32 limit, Promise> promise); + void clear(Promise promise); + + void query(const string &prefix, int32 limit, Promise> promise); private: string mode_; Hints hints_; + char first_character_ = '#'; bool sync_with_db_ = false; int64 counter_ = 0; @@ -39,7 +42,7 @@ class HashtagHints final : public Actor { void hashtag_used_impl(const string &hashtag); void from_db(Result data, bool dummy); - std::vector keys_to_strings(const std::vector &keys); + vector keys_to_strings(const vector &keys); }; } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InlineMessageManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/InlineMessageManager.cpp new file mode 100644 index 0000000000..cd87d2fc24 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/InlineMessageManager.cpp @@ -0,0 +1,387 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/InlineMessageManager.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/GameManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/InputMessageText.h" +#include "td/telegram/Location.h" +#include "td/telegram/MessageContent.h" +#include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageSelfDestructType.h" +#include "td/telegram/net/DcId.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/ReplyMarkup.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/base64.h" +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/Status.h" +#include "td/utils/tl_parsers.h" + +namespace td { + +static int32 get_inline_message_dc_id( + const telegram_api::object_ptr &inline_message_id) { + CHECK(inline_message_id != nullptr); + switch (inline_message_id->get_id()) { + case telegram_api::inputBotInlineMessageID::ID: + return static_cast(inline_message_id.get())->dc_id_; + case telegram_api::inputBotInlineMessageID64::ID: + return static_cast(inline_message_id.get())->dc_id_; + default: + UNREACHABLE(); + return 0; + } +} + +static telegram_api::object_ptr parse_input_bot_inline_message_id( + const string &inline_message_id) { + auto r_binary = base64url_decode(inline_message_id); + if (r_binary.is_error()) { + return nullptr; + } + BufferSlice buffer_slice(r_binary.ok()); + TlBufferParser parser(&buffer_slice); + auto result = buffer_slice.size() == 20 ? telegram_api::inputBotInlineMessageID::fetch(parser) + : telegram_api::inputBotInlineMessageID64::fetch(parser); + parser.fetch_end(); + if (parser.get_error()) { + return nullptr; + } + if (!DcId::is_valid(get_inline_message_dc_id(result))) { + return nullptr; + } + LOG(INFO) << "Have inline message identifier: " << to_string(result); + return result; +} + +static Result> get_input_bot_inline_message_id( + const string &inline_message_id) { + auto result = parse_input_bot_inline_message_id(inline_message_id); + if (result == nullptr) { + return Status::Error(400, "Invalid inline message identifier specified"); + } + return std::move(result); +} + +class EditInlineMessageQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit EditInlineMessageQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(telegram_api::object_ptr input_bot_inline_message_id, + bool force_edit_text, const string &text, + vector> &&entities, bool disable_web_page_preview, + telegram_api::object_ptr &&input_media, bool invert_media, + telegram_api::object_ptr &&reply_markup) { + CHECK(input_bot_inline_message_id != nullptr); + + // file in an inline message can't be uploaded to another datacenter, + // so only previously uploaded files or URLs can be used in the InputMedia + CHECK(!FileManager::extract_was_uploaded(input_media)); + + int32 flags = 0; + if (disable_web_page_preview) { + flags |= telegram_api::messages_editInlineBotMessage::NO_WEBPAGE_MASK; + } + if (reply_markup != nullptr) { + flags |= telegram_api::messages_editInlineBotMessage::REPLY_MARKUP_MASK; + } + if (!entities.empty()) { + flags |= telegram_api::messages_editInlineBotMessage::ENTITIES_MASK; + } + if (force_edit_text || !text.empty()) { + flags |= telegram_api::messages_editInlineBotMessage::MESSAGE_MASK; + } + if (input_media != nullptr) { + flags |= telegram_api::messages_editInlineBotMessage::MEDIA_MASK; + } + if (invert_media) { + flags |= telegram_api::messages_editInlineBotMessage::INVERT_MEDIA_MASK; + } + + auto dc_id = DcId::internal(get_inline_message_dc_id(input_bot_inline_message_id)); + send_query(G()->net_query_creator().create( + telegram_api::messages_editInlineBotMessage( + flags, false /*ignored*/, false /*ignored*/, std::move(input_bot_inline_message_id), text, + std::move(input_media), std::move(reply_markup), std::move(entities)), + {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG_IF(ERROR, !result_ptr.ok()) << "Receive false in result of editInlineMessage"; + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for EditInlineMessageQuery: " << status; + promise_.set_error(std::move(status)); + } +}; + +class SetInlineGameScoreQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit SetInlineGameScoreQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(tl_object_ptr input_bot_inline_message_id, bool edit_message, + tl_object_ptr input_user, int32 score, bool force) { + CHECK(input_bot_inline_message_id != nullptr); + CHECK(input_user != nullptr); + + int32 flags = 0; + if (edit_message) { + flags |= telegram_api::messages_setInlineGameScore::EDIT_MESSAGE_MASK; + } + if (force) { + flags |= telegram_api::messages_setInlineGameScore::FORCE_MASK; + } + + auto dc_id = DcId::internal(get_inline_message_dc_id(input_bot_inline_message_id)); + send_query(G()->net_query_creator().create( + telegram_api::messages_setInlineGameScore(flags, false /*ignored*/, false /*ignored*/, + std::move(input_bot_inline_message_id), std::move(input_user), score), + {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG_IF(ERROR, !result_ptr.ok()) << "Receive false in result of setInlineGameScore"; + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for SetInlineGameScoreQuery: " << status; + promise_.set_error(std::move(status)); + } +}; + +class GetInlineGameHighScoresQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetInlineGameHighScoresQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(tl_object_ptr input_bot_inline_message_id, + tl_object_ptr input_user) { + CHECK(input_bot_inline_message_id != nullptr); + CHECK(input_user != nullptr); + + auto dc_id = DcId::internal(get_inline_message_dc_id(input_bot_inline_message_id)); + send_query(G()->net_query_creator().create( + telegram_api::messages_getInlineGameHighScores(std::move(input_bot_inline_message_id), std::move(input_user)), + {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(td_->game_manager_->get_game_high_scores_object(result_ptr.move_as_ok())); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +InlineMessageManager::InlineMessageManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void InlineMessageManager::tear_down() { + parent_.reset(); +} + +void InlineMessageManager::edit_inline_message_text( + const string &inline_message_id, td_api::object_ptr &&reply_markup, + td_api::object_ptr &&input_message_content, Promise &&promise) { + CHECK(td_->auth_manager_->is_bot()); + + if (input_message_content == nullptr) { + return promise.set_error(Status::Error(400, "Can't edit message without new content")); + } + int32 new_message_content_type = input_message_content->get_id(); + if (new_message_content_type != td_api::inputMessageText::ID) { + return promise.set_error(Status::Error(400, "Input message content type must be InputMessageText")); + } + + TRY_RESULT_PROMISE( + promise, input_message_text, + process_input_message_text(td_, DialogId(), std::move(input_message_content), td_->auth_manager_->is_bot())); + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true)); + TRY_RESULT_PROMISE(promise, input_bot_inline_message_id, get_input_bot_inline_message_id(inline_message_id)); + + td_->create_handler(std::move(promise)) + ->send(std::move(input_bot_inline_message_id), true, input_message_text.text.text, + get_input_message_entities(td_->user_manager_.get(), input_message_text.text.entities, + "edit_inline_message_text"), + input_message_text.disable_web_page_preview, input_message_text.get_input_media_web_page(), + input_message_text.show_above_text, get_input_reply_markup(td_->user_manager_.get(), new_reply_markup)); +} + +void InlineMessageManager::edit_inline_message_live_location(const string &inline_message_id, + td_api::object_ptr &&reply_markup, + td_api::object_ptr &&input_location, + int32 live_period, int32 heading, + int32 proximity_alert_radius, Promise &&promise) { + CHECK(td_->auth_manager_->is_bot()); + + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true)); + TRY_RESULT_PROMISE(promise, input_bot_inline_message_id, get_input_bot_inline_message_id(inline_message_id)); + + Location location(input_location); + if (location.empty() && input_location != nullptr) { + return promise.set_error(Status::Error(400, "Invalid location specified")); + } + + int32 flags = 0; + if (location.empty()) { + flags |= telegram_api::inputMediaGeoLive::STOPPED_MASK; + } + if (live_period != 0) { + flags |= telegram_api::inputMediaGeoLive::PERIOD_MASK; + } + if (heading != 0) { + flags |= telegram_api::inputMediaGeoLive::HEADING_MASK; + } + flags |= telegram_api::inputMediaGeoLive::PROXIMITY_NOTIFICATION_RADIUS_MASK; + auto input_media = telegram_api::make_object( + flags, false /*ignored*/, location.get_input_geo_point(), heading, live_period, proximity_alert_radius); + td_->create_handler(std::move(promise)) + ->send(std::move(input_bot_inline_message_id), false, string(), + vector>(), false, std::move(input_media), + false /*ignored*/, get_input_reply_markup(td_->user_manager_.get(), new_reply_markup)); +} + +void InlineMessageManager::edit_inline_message_media( + const string &inline_message_id, td_api::object_ptr &&reply_markup, + td_api::object_ptr &&input_message_content, Promise &&promise) { + CHECK(td_->auth_manager_->is_bot()); + + if (input_message_content == nullptr) { + return promise.set_error(Status::Error(400, "Can't edit message without new content")); + } + int32 new_message_content_type = input_message_content->get_id(); + if (new_message_content_type != td_api::inputMessageAnimation::ID && + new_message_content_type != td_api::inputMessageAudio::ID && + new_message_content_type != td_api::inputMessageDocument::ID && + new_message_content_type != td_api::inputMessagePhoto::ID && + new_message_content_type != td_api::inputMessageVideo::ID) { + return promise.set_error(Status::Error(400, "Unsupported input message content type")); + } + + bool is_premium = td_->option_manager_->get_option_boolean("is_premium"); + TRY_RESULT_PROMISE(promise, content, + get_input_message_content(DialogId(), std::move(input_message_content), td_, is_premium)); + if (!content.ttl.is_empty()) { + return promise.set_error(Status::Error(400, "Can't enable self-destruction for media")); + } + + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true)); + TRY_RESULT_PROMISE(promise, input_bot_inline_message_id, get_input_bot_inline_message_id(inline_message_id)); + + auto input_media = + get_message_content_input_media(content.content.get(), td_, MessageSelfDestructType(), string(), true); + if (input_media == nullptr) { + return promise.set_error(Status::Error(400, "Invalid message content specified")); + } + + const FormattedText *caption = get_message_content_caption(content.content.get()); + td_->create_handler(std::move(promise)) + ->send(std::move(input_bot_inline_message_id), true, caption == nullptr ? "" : caption->text, + get_input_message_entities(td_->user_manager_.get(), caption, "edit_inline_message_media"), false, + std::move(input_media), content.invert_media, + get_input_reply_markup(td_->user_manager_.get(), new_reply_markup)); +} + +void InlineMessageManager::edit_inline_message_caption(const string &inline_message_id, + td_api::object_ptr &&reply_markup, + td_api::object_ptr &&input_caption, + bool invert_media, Promise &&promise) { + CHECK(td_->auth_manager_->is_bot()); + + TRY_RESULT_PROMISE(promise, caption, + get_formatted_text(td_, td_->dialog_manager_->get_my_dialog_id(), std::move(input_caption), + td_->auth_manager_->is_bot(), true, false, false)); + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true)); + TRY_RESULT_PROMISE(promise, input_bot_inline_message_id, get_input_bot_inline_message_id(inline_message_id)); + + td_->create_handler(std::move(promise)) + ->send(std::move(input_bot_inline_message_id), true, caption.text, + get_input_message_entities(td_->user_manager_.get(), caption.entities, "edit_inline_message_caption"), + false, nullptr, invert_media, get_input_reply_markup(td_->user_manager_.get(), new_reply_markup)); +} + +void InlineMessageManager::edit_inline_message_reply_markup(const string &inline_message_id, + td_api::object_ptr &&reply_markup, + Promise &&promise) { + CHECK(td_->auth_manager_->is_bot()); + + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true)); + TRY_RESULT_PROMISE(promise, input_bot_inline_message_id, get_input_bot_inline_message_id(inline_message_id)); + + td_->create_handler(std::move(promise)) + ->send(std::move(input_bot_inline_message_id), false, string(), + vector>(), false, nullptr, false /*ignored*/, + get_input_reply_markup(td_->user_manager_.get(), new_reply_markup)); +} + +void InlineMessageManager::set_inline_game_score(const string &inline_message_id, bool edit_message, UserId user_id, + int32 score, bool force, Promise &&promise) { + CHECK(td_->auth_manager_->is_bot()); + + TRY_RESULT_PROMISE(promise, input_bot_inline_message_id, get_input_bot_inline_message_id(inline_message_id)); + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(user_id)); + + td_->create_handler(std::move(promise)) + ->send(std::move(input_bot_inline_message_id), edit_message, std::move(input_user), score, force); +} + +void InlineMessageManager::get_inline_game_high_scores(const string &inline_message_id, UserId user_id, + Promise> &&promise) { + CHECK(td_->auth_manager_->is_bot()); + + TRY_RESULT_PROMISE(promise, input_bot_inline_message_id, get_input_bot_inline_message_id(inline_message_id)); + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(user_id)); + + td_->create_handler(std::move(promise)) + ->send(std::move(input_bot_inline_message_id), std::move(input_user)); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InlineMessageManager.h b/protocols/Telegram/tdlib/td/td/telegram/InlineMessageManager.h new file mode 100644 index 0000000000..7a6b7e3e51 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/InlineMessageManager.h @@ -0,0 +1,61 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/UserId.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/Promise.h" + +namespace td { + +class Td; + +class InlineMessageManager final : public Actor { + public: + InlineMessageManager(Td *td, ActorShared<> parent); + + void edit_inline_message_text(const string &inline_message_id, td_api::object_ptr &&reply_markup, + td_api::object_ptr &&input_message_content, + Promise &&promise); + + void edit_inline_message_live_location(const string &inline_message_id, + td_api::object_ptr &&reply_markup, + td_api::object_ptr &&input_location, int32 live_period, + int32 heading, int32 proximity_alert_radius, Promise &&promise); + + void edit_inline_message_media(const string &inline_message_id, + td_api::object_ptr &&reply_markup, + td_api::object_ptr &&input_message_content, + Promise &&promise); + + void edit_inline_message_caption(const string &inline_message_id, + td_api::object_ptr &&reply_markup, + td_api::object_ptr &&input_caption, bool invert_media, + Promise &&promise); + + void edit_inline_message_reply_markup(const string &inline_message_id, + td_api::object_ptr &&reply_markup, + Promise &&promise); + + void set_inline_game_score(const string &inline_message_id, bool edit_message, UserId user_id, int32 score, + bool force, Promise &&promise); + + void get_inline_game_high_scores(const string &inline_message_id, UserId user_id, + Promise> &&promise); + + private: + void tear_down() final; + + Td *td_; + ActorShared<> parent_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InlineQueriesManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/InlineQueriesManager.cpp index 7c6ca44700..6e4d5787d5 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InlineQueriesManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/InlineQueriesManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,8 +10,10 @@ #include "td/telegram/AnimationsManager.h" #include "td/telegram/AudiosManager.h" #include "td/telegram/AuthManager.h" +#include "td/telegram/ChannelId.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/Contact.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Document.h" #include "td/telegram/DocumentsManager.h" #include "td/telegram/files/FileManager.h" @@ -25,9 +27,8 @@ #include "td/telegram/MessageContent.h" #include "td/telegram/MessageContentType.h" #include "td/telegram/MessageEntity.h" -#include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" -#include "td/telegram/net/DcId.h" +#include "td/telegram/OptionManager.h" #include "td/telegram/Photo.h" #include "td/telegram/PhotoFormat.h" #include "td/telegram/PhotoSize.h" @@ -36,9 +37,11 @@ #include "td/telegram/Td.h" #include "td/telegram/td_api.hpp" #include "td/telegram/TdDb.h" -#include "td/telegram/telegram_api.hpp" +#include "td/telegram/telegram_api.h" #include "td/telegram/ThemeManager.h" +#include "td/telegram/TopDialogCategory.h" #include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" #include "td/telegram/Venue.h" #include "td/telegram/VideosManager.h" #include "td/telegram/VoiceNotesManager.h" @@ -46,6 +49,7 @@ #include "td/utils/algorithm.h" #include "td/utils/base64.h" #include "td/utils/buffer.h" +#include "td/utils/emoji.h" #include "td/utils/HashTableUtils.h" #include "td/utils/HttpUrl.h" #include "td/utils/logging.h" @@ -55,14 +59,11 @@ #include "td/utils/SliceBuilder.h" #include "td/utils/Time.h" #include "td/utils/tl_helpers.h" -#include "td/utils/tl_parsers.h" - -#include namespace td { class GetInlineBotResultsQuery final : public Td::ResultHandler { - Promise promise_; + Promise> promise_; DialogId dialog_id_; UserId bot_user_id_; uint64 query_hash_; @@ -70,7 +71,8 @@ class GetInlineBotResultsQuery final : public Td::ResultHandler { static constexpr int32 GET_INLINE_BOT_RESULTS_FLAG_HAS_LOCATION = 1 << 0; public: - explicit GetInlineBotResultsQuery(Promise &&promise) : promise_(std::move(promise)) { + explicit GetInlineBotResultsQuery(Promise> &&promise) + : promise_(std::move(promise)) { } NetQueryRef send(UserId bot_user_id, DialogId dialog_id, tl_object_ptr bot_input_user, @@ -101,8 +103,7 @@ class GetInlineBotResultsQuery final : public Td::ResultHandler { } td_->inline_queries_manager_->on_get_inline_query_results(dialog_id_, bot_user_id_, query_hash_, - result_ptr.move_as_ok()); - promise_.set_value(Unit()); + result_ptr.move_as_ok(), std::move(promise_)); } void on_error(Status status) final { @@ -113,7 +114,7 @@ class GetInlineBotResultsQuery final : public Td::ResultHandler { } LOG(INFO) << "Receive error for GetInlineBotResultsQuery: " << status; - td_->inline_queries_manager_->on_get_inline_query_results(dialog_id_, bot_user_id_, query_hash_, nullptr); + td_->inline_queries_manager_->on_get_inline_query_results(dialog_id_, bot_user_id_, query_hash_, nullptr, Auto()); promise_.set_error(std::move(status)); } }; @@ -176,7 +177,7 @@ class RequestSimpleWebViewQuery final : public Td::ResultHandler { explicit RequestSimpleWebViewQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(tl_object_ptr &&input_user, const string &url, + void send(tl_object_ptr &&input_user, string url, const td_api::object_ptr &theme, string &&platform) { tl_object_ptr theme_parameters; int32 flags = 0; @@ -184,19 +185,32 @@ class RequestSimpleWebViewQuery final : public Td::ResultHandler { flags |= telegram_api::messages_requestSimpleWebView::THEME_PARAMS_MASK; theme_parameters = make_tl_object(string()); - theme_parameters->data_ = ThemeManager::get_theme_parameters_json_string(theme, false); + theme_parameters->data_ = ThemeManager::get_theme_parameters_json_string(theme); } + string start_parameter; if (ends_with(url, "#kb")) { // a URL from keyboard button + url.resize(url.size() - 3); + flags |= telegram_api::messages_requestSimpleWebView::URL_MASK; } else if (ends_with(url, "#iq")) { // a URL from inline query results button + url.resize(url.size() - 3); flags |= telegram_api::messages_requestSimpleWebView::FROM_SWITCH_WEBVIEW_MASK; + flags |= telegram_api::messages_requestSimpleWebView::URL_MASK; + } else if (url.empty()) { + flags |= telegram_api::messages_requestSimpleWebView::FROM_SIDE_MENU_MASK; + } else if (begins_with(url, "start://")) { + start_parameter = url.substr(8); + url = string(); + + flags |= telegram_api::messages_requestSimpleWebView::FROM_SIDE_MENU_MASK; + flags |= telegram_api::messages_requestSimpleWebView::START_PARAM_MASK; } else { return on_error(Status::Error(400, "Invalid URL specified")); } send_query(G()->net_query_creator().create(telegram_api::messages_requestSimpleWebView( - flags, false /*ignored*/, std::move(input_user), url.substr(0, url.size() - 3), std::move(theme_parameters), - platform))); + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_user), url, start_parameter, + std::move(theme_parameters), platform))); } void on_result(BufferSlice packet) final { @@ -207,6 +221,7 @@ class RequestSimpleWebViewQuery final : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for RequestSimpleWebViewQuery: " << to_string(ptr); + LOG_IF(ERROR, ptr->query_id_ != 0) << "Receive " << to_string(ptr); promise_.set_value(std::move(ptr->url_)); } @@ -309,41 +324,6 @@ void InlineQueriesManager::after_get_difference() { } } -int32 InlineQueriesManager::get_inline_message_dc_id( - const tl_object_ptr &inline_message_id) { - CHECK(inline_message_id != nullptr); - switch (inline_message_id->get_id()) { - case telegram_api::inputBotInlineMessageID::ID: - return static_cast(inline_message_id.get())->dc_id_; - case telegram_api::inputBotInlineMessageID64::ID: - return static_cast(inline_message_id.get())->dc_id_; - default: - UNREACHABLE(); - return 0; - } -} - -tl_object_ptr InlineQueriesManager::get_input_bot_inline_message_id( - const string &inline_message_id) { - auto r_binary = base64url_decode(inline_message_id); - if (r_binary.is_error()) { - return nullptr; - } - BufferSlice buffer_slice(r_binary.ok()); - TlBufferParser parser(&buffer_slice); - auto result = buffer_slice.size() == 20 ? telegram_api::inputBotInlineMessageID::fetch(parser) - : telegram_api::inputBotInlineMessageID64::fetch(parser); - parser.fetch_end(); - if (parser.get_error()) { - return nullptr; - } - if (!DcId::is_valid(get_inline_message_dc_id(result))) { - return nullptr; - } - LOG(INFO) << "Have inline message identifier: " << to_string(result); - return result; -} - string InlineQueriesManager::get_inline_message_id( tl_object_ptr &&input_bot_inline_message_id) { if (input_bot_inline_message_id == nullptr) { @@ -361,35 +341,62 @@ Result> InlineQueriesManager: return Status::Error(400, "Inline message must be non-empty"); } TRY_RESULT(reply_markup, get_reply_markup(std::move(reply_markup_ptr), true, true, false, true)); - auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), reply_markup); + auto input_reply_markup = get_input_reply_markup(td_->user_manager_.get(), reply_markup); auto constructor_id = input_message_content->get_id(); if (constructor_id == td_api::inputMessageText::ID) { - TRY_RESULT(input_message_text, process_input_message_text(td_, DialogId(td_->contacts_manager_->get_my_id()), + TRY_RESULT(input_message_text, process_input_message_text(td_, td_->dialog_manager_->get_my_dialog_id(), std::move(input_message_content), true)); + auto entities = + get_input_message_entities(td_->user_manager_.get(), input_message_text.text.entities, "get_inline_message"); + if (!input_message_text.web_page_url.empty()) { + int32 flags = 0; + if (input_reply_markup != nullptr) { + flags |= telegram_api::inputBotInlineMessageMediaWebPage::REPLY_MARKUP_MASK; + } + if (!entities.empty()) { + flags |= telegram_api::inputBotInlineMessageMediaWebPage::ENTITIES_MASK; + } + if (input_message_text.force_small_media) { + flags |= telegram_api::inputBotInlineMessageMediaWebPage::FORCE_SMALL_MEDIA_MASK; + } + if (input_message_text.force_large_media) { + flags |= telegram_api::inputBotInlineMessageMediaWebPage::FORCE_LARGE_MEDIA_MASK; + } + if (input_message_text.show_above_text) { + flags |= telegram_api::inputBotInlineMessageMediaWebPage::INVERT_MEDIA_MASK; + } + if (!input_message_text.text.text.empty()) { + flags |= telegram_api::inputBotInlineMessageMediaWebPage::OPTIONAL_MASK; + } + return make_tl_object( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + std::move(input_message_text.text.text), std::move(entities), input_message_text.web_page_url, + std::move(input_reply_markup)); + } int32 flags = 0; if (input_reply_markup != nullptr) { flags |= telegram_api::inputBotInlineMessageText::REPLY_MARKUP_MASK; } if (input_message_text.disable_web_page_preview) { flags |= telegram_api::inputBotInlineMessageText::NO_WEBPAGE_MASK; + } else if (input_message_text.show_above_text) { + flags |= telegram_api::inputBotInlineMessageText::INVERT_MEDIA_MASK; } - if (!input_message_text.text.entities.empty()) { + if (!entities.empty()) { flags |= telegram_api::inputBotInlineMessageText::ENTITIES_MASK; } - return make_tl_object( - flags, false /*ignored*/, std::move(input_message_text.text.text), - get_input_message_entities(td_->contacts_manager_.get(), input_message_text.text.entities, - "get_inline_message"), - std::move(input_reply_markup)); + return make_tl_object(flags, false /*ignored*/, false /*ignored*/, + std::move(input_message_text.text.text), + std::move(entities), std::move(input_reply_markup)); } if (constructor_id == td_api::inputMessageContact::ID) { - TRY_RESULT(contact, process_input_message_contact(std::move(input_message_content))); + TRY_RESULT(contact, process_input_message_contact(td_, std::move(input_message_content))); return contact.get_input_bot_inline_message_media_contact(std::move(input_reply_markup)); } if (constructor_id == td_api::inputMessageInvoice::ID) { TRY_RESULT(input_invoice, - InputInvoice::process_input_message_invoice(std::move(input_message_content), td_, DialogId(), false)); + InputInvoice::process_input_message_invoice(std::move(input_message_content), td_, DialogId())); return input_invoice.get_input_bot_inline_message_media_invoice(std::move(input_reply_markup), td_); } if (constructor_id == td_api::inputMessageLocation::ID) { @@ -414,25 +421,28 @@ Result> InlineQueriesManager: return venue.get_input_bot_inline_message_media_venue(std::move(input_reply_markup)); } if (constructor_id == allowed_media_content_id) { - TRY_RESULT(caption, get_formatted_text(td_, DialogId(td_->contacts_manager_->get_my_id()), + TRY_RESULT(caption, get_formatted_text(td_, td_->dialog_manager_->get_my_dialog_id(), extract_input_caption(input_message_content), true, true, true, false)); int32 flags = 0; if (input_reply_markup != nullptr) { flags |= telegram_api::inputBotInlineMessageMediaAuto::REPLY_MARKUP_MASK; } - auto entities = get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "get_inline_message"); + auto entities = get_input_message_entities(td_->user_manager_.get(), caption.entities, "get_inline_message"); if (!entities.empty()) { flags |= telegram_api::inputBotInlineMessageMediaAuto::ENTITIES_MASK; } - return make_tl_object(flags, caption.text, std::move(entities), - std::move(input_reply_markup)); + if (extract_input_invert_media(input_message_content)) { + flags |= telegram_api::inputBotInlineMessageMediaAuto::INVERT_MEDIA_MASK; + } + return make_tl_object( + flags, false /*ignored*/, caption.text, std::move(entities), std::move(input_reply_markup)); } return Status::Error(400, "Unallowed inline message content type"); } bool InlineQueriesManager::register_inline_message_content( int64 query_id, const string &result_id, FileId file_id, - tl_object_ptr &&inline_message, int32 allowed_media_content_id, bool allow_invoice, + tl_object_ptr &&inline_message, int32 allowed_media_content_id, bool is_secret_chat, Photo *photo, Game *game) { CHECK(query_id != 0); if (result_id.empty()) { @@ -442,7 +452,7 @@ bool InlineQueriesManager::register_inline_message_content( InlineMessageContent content = create_inline_message_content(td_, file_id, std::move(inline_message), allowed_media_content_id, photo, game); if (content.message_content != nullptr) { - if (!allow_invoice && content.message_content->get_type() == MessageContentType::Invoice) { + if (is_secret_chat && !can_send_message_content_to_secret_chat(content.message_content->get_type())) { return false; } @@ -496,13 +506,13 @@ void InlineQueriesManager::answer_inline_query( case td_api::inlineQueryResultsButtonTypeStartBot::ID: { auto type = td_api::move_object_as(button->type_); if (type->parameter_.empty()) { - return promise.set_error(Status::Error(400, "Can't use empty switch_pm_parameter")); + return promise.set_error(Status::Error(400, "Can't use empty start_parameter")); } if (type->parameter_.size() > 64) { - return promise.set_error(Status::Error(400, "Too long switch_pm_parameter specified")); + return promise.set_error(Status::Error(400, "Too long start_parameter specified")); } if (!is_base64url_characters(type->parameter_)) { - return promise.set_error(Status::Error(400, "Unallowed characters in switch_pm_parameter are used")); + return promise.set_error(Status::Error(400, "Unallowed characters in start_parameter are used")); } switch_pm = telegram_api::make_object(button->text_, type->parameter_); break; @@ -543,23 +553,24 @@ void InlineQueriesManager::answer_inline_query( void InlineQueriesManager::get_simple_web_view_url(UserId bot_user_id, string &&url, const td_api::object_ptr &theme, string &&platform, Promise &&promise) { - TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(bot_user_id)); - TRY_RESULT_PROMISE(promise, bot_data, td_->contacts_manager_->get_bot_data(bot_user_id)); + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(bot_user_id)); + TRY_RESULT_PROMISE(promise, bot_data, td_->user_manager_->get_bot_data(bot_user_id)); + on_dialog_used(TopDialogCategory::BotApp, DialogId(bot_user_id), G()->unix_time()); td_->create_handler(std::move(promise)) - ->send(std::move(input_user), url, theme, std::move(platform)); + ->send(std::move(input_user), std::move(url), theme, std::move(platform)); } void InlineQueriesManager::send_web_view_data(UserId bot_user_id, string &&button_text, string &&data, Promise &&promise) const { - TRY_RESULT_PROMISE(promise, bot_data, td_->contacts_manager_->get_bot_data(bot_user_id)); + TRY_RESULT_PROMISE(promise, bot_data, td_->user_manager_->get_bot_data(bot_user_id)); int64 random_id; do { random_id = Random::secure_int64(); } while (random_id == 0); - TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(bot_user_id)); + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(bot_user_id)); td_->create_handler(std::move(promise)) ->send(std::move(input_user), random_id, button_text, data); @@ -738,7 +749,7 @@ Result> InlineQueriesManager:: return r_reply_markup.move_as_error(); } - auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_reply_markup.ok()); + auto input_reply_markup = get_input_reply_markup(td_->user_manager_.get(), r_reply_markup.ok()); int32 flags = 0; if (input_reply_markup != nullptr) { flags |= telegram_api::inputBotInlineMessageGame::REPLY_MARKUP_MASK; @@ -906,22 +917,22 @@ Result> InlineQueriesManager:: TRY_RESULT(file_id, td_->file_manager_->get_input_file_id( file_type, make_tl_object(content_url), DialogId(), false, false)); FileView file_view = td_->file_manager_->get_file_view(file_id); - CHECK(file_view.has_remote_location()); if (file_view.is_encrypted()) { return Status::Error(400, "Can't send encrypted file"); } - if (file_view.main_remote_location().is_web()) { + const auto *main_remote_location = file_view.get_main_remote_location(); + CHECK(main_remote_location != nullptr); + if (main_remote_location->is_web()) { return Status::Error(400, "Can't send web file"); } if (file_type == FileType::Photo) { - return make_tl_object( - id, type, file_view.main_remote_location().as_input_photo(), std::move(inline_message)); + return make_tl_object(id, type, main_remote_location->as_input_photo(), + std::move(inline_message)); } return make_tl_object( - flags, id, type, title, description, file_view.main_remote_location().as_input_document(), - std::move(inline_message)); + flags, id, type, title, description, main_remote_location->as_input_document(), std::move(inline_message)); } if (!url.empty()) { @@ -956,7 +967,7 @@ Result> InlineQueriesManager:: if (width > 0 && height > 0) { if ((duration > 0 || type == "video" || content_type == "video/mp4") && !begins_with(content_type, "image/")) { attributes.push_back(make_tl_object( - 0, false /*ignored*/, false /*ignored*/, duration, width, height)); + 0, false /*ignored*/, false /*ignored*/, false /*ignored*/, duration, width, height, 0, 0.0)); } else { attributes.push_back(make_tl_object(width, height)); } @@ -977,24 +988,75 @@ Result> InlineQueriesManager:: flags, id, type, title, description, url, std::move(thumbnail), std::move(content), std::move(inline_message)); } -uint64 InlineQueriesManager::send_inline_query(UserId bot_user_id, DialogId dialog_id, Location user_location, - const string &query, const string &offset, Promise &&promise) { - if (td_->auth_manager_->is_bot()) { - promise.set_error(Status::Error(400, "Bot can't send inline queries to other bot")); - return 0; +void InlineQueriesManager::get_weather(Location location, + Promise> &&promise) { + if (location.empty()) { + return promise.set_error(Status::Error(400, "Location must be non-empty")); + } + auto bot_username = td_->option_manager_->get_option_string("weather_bot_username"); + if (bot_username.empty()) { + LOG(ERROR) << "Have no weather bot"; + return promise.set_error(Status::Error(500, "Not supported")); } + td_->dialog_manager_->resolve_dialog( + bot_username, ChannelId(), + PromiseCreator::lambda([actor_id = actor_id(this), location = std::move(location), + promise = std::move(promise)](Result r_bot_dialog_id) mutable { + if (r_bot_dialog_id.is_error()) { + return promise.set_error(r_bot_dialog_id.move_as_error()); + } + send_closure(actor_id, &InlineQueriesManager::do_get_weather, r_bot_dialog_id.ok(), std::move(location), + std::move(promise)); + })); +} + +void InlineQueriesManager::do_get_weather(DialogId dialog_id, Location location, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + if (dialog_id.get_type() != DialogType::User) { + LOG(ERROR) << "Weather bot isn't a user"; + return promise.set_error(Status::Error(500, "Not supported")); + } + send_inline_query( + dialog_id.get_user_id(), DialogId(), std::move(location), string(), string(), + PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( + Result> r_results) mutable { + if (r_results.is_error()) { + return promise.set_error(Status::Error(500, "Not supported")); + } + send_closure(actor_id, &InlineQueriesManager::on_get_weather, r_results.move_as_ok(), std::move(promise)); + })); +} - auto r_bot_data = td_->contacts_manager_->get_bot_data(bot_user_id); +void InlineQueriesManager::on_get_weather(td_api::object_ptr results, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + if (results->results_.size() != 1u || results->results_[0]->get_id() != td_api::inlineQueryResultArticle::ID) { + LOG(ERROR) << "Receive " << to_string(results); + return promise.set_error(Status::Error(500, "Not supported")); + } + auto result = td_api::move_object_as(results->results_[0]); + if (!is_emoji(result->title_)) { + LOG(ERROR) << "Receive " << to_string(results); + return promise.set_error(Status::Error(500, "Not supported")); + } + promise.set_value(td_api::make_object(to_double(result->description_), result->title_)); +} + +void InlineQueriesManager::send_inline_query(UserId bot_user_id, DialogId dialog_id, Location user_location, + const string &query, const string &offset, + Promise> &&promise) { + CHECK(!td_->auth_manager_->is_bot()); + + auto r_bot_data = td_->user_manager_->get_bot_data(bot_user_id); if (r_bot_data.is_error()) { - promise.set_error(r_bot_data.move_as_error()); - return 0; + return promise.set_error(r_bot_data.move_as_error()); } if (!r_bot_data.ok().is_inline) { - promise.set_error(Status::Error(400, "Bot doesn't support inline queries")); - return 0; + return promise.set_error(Status::Error(400, "Bot doesn't support inline queries")); } - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { input_peer = make_tl_object(); } @@ -1012,7 +1074,7 @@ uint64 InlineQueriesManager::send_inline_query(UserId bot_user_id, DialogId dial return dialog_id == DialogId(bot_user_id) ? 3 : 4; case telegram_api::inputPeerChannel::ID: case telegram_api::inputPeerChannelFromMessage::ID: - return 5 + static_cast(td_->contacts_manager_->get_channel_type(dialog_id.get_channel_id())); + return 5 + static_cast(td_->chat_manager_->get_channel_type(dialog_id.get_channel_id())); default: UNREACHABLE(); return -1; @@ -1036,8 +1098,7 @@ uint64 InlineQueriesManager::send_inline_query(UserId bot_user_id, DialogId dial if (it != inline_query_results_.end()) { it->second.pending_request_count++; if (Time::now() < it->second.cache_expire_time) { - promise.set_value(Unit()); - return query_hash; + return promise.set_value(get_inline_query_results_object(query_hash)); } } else { inline_query_results_[query_hash] = {nullptr, -1.0, 1}; @@ -1046,7 +1107,7 @@ uint64 InlineQueriesManager::send_inline_query(UserId bot_user_id, DialogId dial if (pending_inline_query_ != nullptr) { LOG(INFO) << "Drop inline query " << pending_inline_query_->query_hash; on_get_inline_query_results(pending_inline_query_->dialog_id, pending_inline_query_->bot_user_id, - pending_inline_query_->query_hash, nullptr); + pending_inline_query_->query_hash, nullptr, Auto()); pending_inline_query_->promise.set_error(Status::Error(406, "Request canceled")); } @@ -1054,12 +1115,9 @@ uint64 InlineQueriesManager::send_inline_query(UserId bot_user_id, DialogId dial query_hash, bot_user_id, dialog_id, std::move(input_peer), user_location, query, offset, std::move(promise)}); loop(); - - return query_hash; } void InlineQueriesManager::loop() { - LOG(INFO) << "Inline query loop"; if (pending_inline_query_ == nullptr) { return; } @@ -1067,7 +1125,7 @@ void InlineQueriesManager::loop() { auto now = Time::now(); if (now >= next_inline_query_time_) { LOG(INFO) << "Send inline query " << pending_inline_query_->query_hash; - auto r_bot_input_user = td_->contacts_manager_->get_input_user(pending_inline_query_->bot_user_id); + auto r_bot_input_user = td_->user_manager_->get_input_user(pending_inline_query_->bot_user_id); if (r_bot_input_user.is_ok()) { if (!sent_query_.empty()) { LOG(INFO) << "Cancel inline query request"; @@ -1084,8 +1142,8 @@ void InlineQueriesManager::loop() { pending_inline_query_ = nullptr; } else { if (!has_timeout()) { - LOG(INFO) << "Schedule send inline query " << pending_inline_query_->query_hash << " at " - << G()->to_server_time(next_inline_query_time_); + LOG(INFO) << "Schedule send inline query " << pending_inline_query_->query_hash << " in " + << next_inline_query_time_ - now; set_timeout_at(next_inline_query_time_); } } @@ -1450,12 +1508,13 @@ static tl_object_ptr copy_result(const tl_object_ptr< } template <> -tl_object_ptr copy(const td_api::inlineQueryResults &obj) { +td_api::object_ptr copy(const td_api::inlineQueryResults &obj) { return td_api::make_object(obj.inline_query_id_, copy(obj.button_), transform(obj.results_, copy_result), obj.next_offset_); } -tl_object_ptr InlineQueriesManager::decrease_pending_request_count(uint64 query_hash) { +td_api::object_ptr InlineQueriesManager::get_inline_query_results_object( + uint64 query_hash) { auto it = inline_query_results_.find(query_hash); CHECK(it != inline_query_results_.end()); CHECK(it->second.pending_request_count > 0); @@ -1536,19 +1595,21 @@ string InlineQueriesManager::get_web_document_content_type( return {}; } -void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserId bot_user_id, uint64 query_hash, - tl_object_ptr &&results) { +void InlineQueriesManager::on_get_inline_query_results( + DialogId dialog_id, UserId bot_user_id, uint64 query_hash, + tl_object_ptr &&results, + Promise> promise) { LOG(INFO) << "Receive results for inline query " << query_hash; if (results == nullptr || results->query_id_ == 0) { - decrease_pending_request_count(query_hash); - return; + get_inline_query_results_object(query_hash); + return promise.set_error(Status::Error(500, "Receive no response")); } LOG(INFO) << to_string(results); - td_->contacts_manager_->on_get_users(std::move(results->users_), "on_get_inline_query_results"); + td_->user_manager_->on_get_users(std::move(results->users_), "on_get_inline_query_results"); auto dialog_type = dialog_id.get_type(); - bool allow_invoice = dialog_type != DialogType::SecretChat; + bool is_secret_chat = dialog_type == DialogType::SecretChat; vector> output_results; for (auto &result_ptr : results->results_) { tl_object_ptr output_result; @@ -1562,10 +1623,10 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (result->type_ == "game") { if (!has_photo) { LOG(ERROR) << "Receive game without photo in the result of inline query: " << to_string(result); - break; + continue; } if (dialog_type == DialogType::Channel && - td_->contacts_manager_->is_broadcast_channel(dialog_id.get_channel_id())) { + td_->chat_manager_->is_broadcast_channel(dialog_id.get_channel_id())) { continue; } if (dialog_type == DialogType::SecretChat) { @@ -1577,11 +1638,11 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI std::move(result->document_), DialogId()); game->id_ = std::move(result->id_); - game->game_ = inline_game.get_game_object(td_, true); + game->game_ = inline_game.get_game_object(td_, true, true); if (!register_inline_message_content(results->query_id_, game->id_, FileId(), std::move(result->send_message_), td_api::inputMessageGame::ID, - allow_invoice, nullptr, &inline_game)) { + is_secret_chat, nullptr, &inline_game)) { continue; } output_result = std::move(game); @@ -1590,7 +1651,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI int32 document_id = document_ptr->get_id(); if (document_id == telegram_api::documentEmpty::ID) { LOG(ERROR) << "Receive empty cached document in the result of inline query"; - break; + continue; } CHECK(document_id == telegram_api::document::ID); @@ -1607,7 +1668,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (!register_inline_message_content(results->query_id_, animation->id_, parsed_document.file_id, std::move(result->send_message_), td_api::inputMessageAnimation::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(animation); @@ -1622,7 +1683,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (!register_inline_message_content(results->query_id_, audio->id_, parsed_document.file_id, std::move(result->send_message_), td_api::inputMessageAudio::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(audio); @@ -1640,7 +1701,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (!register_inline_message_content(results->query_id_, document->id_, parsed_document.file_id, std::move(result->send_message_), td_api::inputMessageDocument::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(document); @@ -1655,7 +1716,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (!register_inline_message_content(results->query_id_, sticker->id_, parsed_document.file_id, std::move(result->send_message_), td_api::inputMessageSticker::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(sticker); @@ -1672,7 +1733,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (!register_inline_message_content(results->query_id_, video->id_, parsed_document.file_id, std::move(result->send_message_), td_api::inputMessageVideo::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(video); @@ -1691,7 +1752,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (!register_inline_message_content(results->query_id_, voice_note->id_, parsed_document.file_id, std::move(result->send_message_), td_api::inputMessageVoiceNote::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(voice_note); @@ -1719,7 +1780,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (!register_inline_message_content(results->query_id_, photo->id_, FileId(), std::move(result->send_message_), td_api::inputMessagePhoto::ID, - allow_invoice, &p)) { + is_secret_chat, &p)) { continue; } output_result = std::move(photo); @@ -1747,7 +1808,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI article->thumbnail_ = register_thumbnail(std::move(result->thumb_)); if (!register_inline_message_content(results->query_id_, article->id_, FileId(), - std::move(result->send_message_), -1, allow_invoice)) { + std::move(result->send_message_), -1, is_secret_chat)) { continue; } output_result = std::move(article); @@ -1759,15 +1820,15 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI static_cast(result->send_message_.get()); Contact c(inline_message_contact->phone_number_, inline_message_contact->first_name_, inline_message_contact->last_name_, inline_message_contact->vcard_, UserId()); - contact->contact_ = c.get_contact_object(); + contact->contact_ = c.get_contact_object(td_); } else { Contact c(std::move(result->description_), std::move(result->title_), string(), string(), UserId()); - contact->contact_ = c.get_contact_object(); + contact->contact_ = c.get_contact_object(td_); } contact->thumbnail_ = register_thumbnail(std::move(result->thumb_)); if (!register_inline_message_content(results->query_id_, contact->id_, FileId(), - std::move(result->send_message_), -1, allow_invoice)) { + std::move(result->send_message_), -1, is_secret_chat)) { continue; } output_result = std::move(contact); @@ -1778,17 +1839,17 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (result->send_message_->get_id() == telegram_api::botInlineMessageMediaGeo::ID) { auto inline_message_geo = static_cast(result->send_message_.get()); - Location l(inline_message_geo->geo_); + Location l(td_, inline_message_geo->geo_); location->location_ = l.get_location_object(); } else { auto latitude_longitude = split(Slice(result->description_)); - Location l(to_double(latitude_longitude.first), to_double(latitude_longitude.second), 0.0, 0); + Location l(td_, to_double(latitude_longitude.first), to_double(latitude_longitude.second), 0.0, 0); location->location_ = l.get_location_object(); } location->thumbnail_ = register_thumbnail(std::move(result->thumb_)); if (!register_inline_message_content(results->query_id_, location->id_, FileId(), - std::move(result->send_message_), -1, allow_invoice)) { + std::move(result->send_message_), -1, is_secret_chat)) { continue; } output_result = std::move(location); @@ -1798,24 +1859,25 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (result->send_message_->get_id() == telegram_api::botInlineMessageMediaVenue::ID) { auto inline_message_venue = static_cast(result->send_message_.get()); - Venue v(inline_message_venue->geo_, inline_message_venue->title_, inline_message_venue->address_, + Venue v(td_, inline_message_venue->geo_, inline_message_venue->title_, inline_message_venue->address_, inline_message_venue->provider_, inline_message_venue->venue_id_, inline_message_venue->venue_type_); venue->venue_ = v.get_venue_object(); } else if (result->send_message_->get_id() == telegram_api::botInlineMessageMediaGeo::ID) { auto inline_message_geo = static_cast(result->send_message_.get()); - Venue v(inline_message_geo->geo_, std::move(result->title_), std::move(result->description_), string(), + Venue v(td_, inline_message_geo->geo_, std::move(result->title_), std::move(result->description_), string(), string(), string()); venue->venue_ = v.get_venue_object(); } else { - Venue v(nullptr, std::move(result->title_), std::move(result->description_), string(), string(), string()); + Venue v(td_, nullptr, std::move(result->title_), std::move(result->description_), string(), string(), + string()); venue->venue_ = v.get_venue_object(); } venue->thumbnail_ = register_thumbnail(std::move(result->thumb_)); if (!register_inline_message_content(results->query_id_, venue->id_, FileId(), - std::move(result->send_message_), -1, allow_invoice)) { + std::move(result->send_message_), -1, is_secret_chat)) { continue; } output_result = std::move(venue); @@ -1845,7 +1907,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI if (!register_inline_message_content(results->query_id_, photo->id_, FileId(), std::move(result->send_message_), td_api::inputMessagePhoto::ID, - allow_invoice, &new_photo)) { + is_secret_chat, &new_photo)) { continue; } output_result = std::move(photo); @@ -1855,9 +1917,17 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI continue; } - vector> attributes; - downcast_call(*result->content_, - [&attributes](auto &web_document) { attributes = std::move(web_document.attributes_); }); + auto attributes = [content = result->content_.get()] { + switch (content->get_id()) { + case telegram_api::webDocument::ID: + return std::move(static_cast(content)->attributes_); + case telegram_api::webDocumentNoProxy::ID: + return std::move(static_cast(content)->attributes_); + default: + UNREACHABLE(); + return vector>(); + } + }(); bool is_animation = result->type_ == "gif" && (content_type == "image/gif" || content_type == "video/mp4"); if (is_animation) { @@ -1898,7 +1968,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI audio->audio_ = td_->audios_manager_->get_audio_object(file_id); if (!register_inline_message_content(results->query_id_, audio->id_, file_id, std::move(result->send_message_), td_api::inputMessageAudio::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(audio); @@ -1910,7 +1980,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI document->description_ = std::move(result->description_); if (!register_inline_message_content(results->query_id_, document->id_, file_id, std::move(result->send_message_), td_api::inputMessageDocument::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(document); @@ -1921,7 +1991,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI animation->title_ = std::move(result->title_); if (!register_inline_message_content(results->query_id_, animation->id_, file_id, std::move(result->send_message_), td_api::inputMessageAnimation::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(animation); @@ -1931,7 +2001,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI sticker->sticker_ = td_->stickers_manager_->get_sticker_object(file_id); if (!register_inline_message_content(results->query_id_, sticker->id_, file_id, std::move(result->send_message_), td_api::inputMessageSticker::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(sticker); @@ -1943,7 +2013,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI video->description_ = std::move(result->description_); if (!register_inline_message_content(results->query_id_, video->id_, file_id, std::move(result->send_message_), td_api::inputMessageVideo::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(video); @@ -1954,7 +2024,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI voice_note->title_ = std::move(result->title_); if (!register_inline_message_content(results->query_id_, voice_note->id_, file_id, std::move(result->send_message_), td_api::inputMessageVoiceNote::ID, - allow_invoice)) { + is_secret_chat)) { continue; } output_result = std::move(voice_note); @@ -1991,6 +2061,7 @@ void InlineQueriesManager::on_get_inline_query_results(DialogId dialog_id, UserI it->second.results = make_tl_object(results->query_id_, std::move(button), std::move(output_results), results->next_offset_); it->second.cache_expire_time = Time::now() + results->cache_time_; + promise.set_value(get_inline_query_results_object(query_hash)); } vector InlineQueriesManager::get_recent_inline_bots(Promise &&promise) { @@ -2014,7 +2085,7 @@ void InlineQueriesManager::save_recently_used_bots() { value += ','; value_ids += ','; } - value += td_->contacts_manager_->get_user_first_username(bot_user_id); + value += td_->user_manager_->get_user_first_username(bot_user_id); value_ids += to_string(bot_user_id.get()); } G()->td_db()->get_binlog_pmc()->set("recently_used_inline_bot_usernames", value); @@ -2040,13 +2111,13 @@ bool InlineQueriesManager::load_recently_used_bots(Promise &promise) { LOG(INFO) << "Load recently used inline bots " << saved_bots << '/' << saved_bot_ids; if (recently_used_bots_loaded_ == 1 && resolve_recent_inline_bots_multipromise_.promise_count() == 0) { - // queries was sent and have already been finished + // queries were sent and have already been finished auto newly_used_bots = std::move(recently_used_bot_user_ids_); recently_used_bot_user_ids_.clear(); for (auto it = bot_ids.rbegin(); it != bot_ids.rend(); ++it) { UserId user_id(to_integer(*it)); - if (td_->contacts_manager_->have_user(user_id)) { + if (td_->user_manager_->have_user(user_id)) { update_bot_usage(user_id); } else { LOG(ERROR) << "Can't find " << user_id; @@ -2068,13 +2139,13 @@ bool InlineQueriesManager::load_recently_used_bots(Promise &promise) { auto lock = resolve_recent_inline_bots_multipromise_.get_promise(); if (!G()->use_chat_info_database()) { for (auto &bot_username : bot_usernames) { - td_->messages_manager_->search_public_dialog(bot_username, false, - resolve_recent_inline_bots_multipromise_.get_promise()); + td_->dialog_manager_->search_public_dialog(bot_username, false, + resolve_recent_inline_bots_multipromise_.get_promise()); } } else { for (auto &bot_id : bot_ids) { UserId user_id(to_integer(bot_id)); - td_->contacts_manager_->get_user(user_id, 3, resolve_recent_inline_bots_multipromise_.get_promise()); + td_->user_manager_->get_user(user_id, 3, resolve_recent_inline_bots_multipromise_.get_promise()); } } lock.set_value(Unit()); @@ -2083,10 +2154,6 @@ bool InlineQueriesManager::load_recently_used_bots(Promise &promise) { return false; } -tl_object_ptr InlineQueriesManager::get_inline_query_results_object(uint64 query_hash) { - return decrease_pending_request_count(query_hash); -} - void InlineQueriesManager::on_new_query(int64 query_id, UserId sender_user_id, Location user_location, tl_object_ptr peer_type, const string &query, const string &offset) { @@ -2094,7 +2161,6 @@ void InlineQueriesManager::on_new_query(int64 query_id, UserId sender_user_id, L LOG(ERROR) << "Receive new inline query from invalid " << sender_user_id; return; } - LOG_IF(ERROR, !td_->contacts_manager_->have_user(sender_user_id)) << "Receive unknown " << sender_user_id; if (!td_->auth_manager_->is_bot()) { LOG(ERROR) << "Receive new inline query"; return; @@ -2106,7 +2172,8 @@ void InlineQueriesManager::on_new_query(int64 query_id, UserId sender_user_id, L switch (peer_type->get_id()) { case telegram_api::inlineQueryPeerTypeSameBotPM::ID: - return td_api::make_object(sender_user_id.get()); + return td_api::make_object( + td_->user_manager_->get_user_id_object(sender_user_id, "inlineQueryPeerTypeSameBotPM")); case telegram_api::inlineQueryPeerTypeBotPM::ID: case telegram_api::inlineQueryPeerTypePM::ID: return td_api::make_object(0); @@ -2123,7 +2190,7 @@ void InlineQueriesManager::on_new_query(int64 query_id, UserId sender_user_id, L }(); send_closure(G()->td(), &Td::send_update, make_tl_object( - query_id, td_->contacts_manager_->get_user_id_object(sender_user_id, "updateNewInlineQuery"), + query_id, td_->user_manager_->get_user_id_object(sender_user_id, "updateNewInlineQuery"), user_location.get_location_object(), std::move(chat_type), query, offset)); } @@ -2134,14 +2201,14 @@ void InlineQueriesManager::on_chosen_result( LOG(ERROR) << "Receive chosen inline query result from invalid " << user_id; return; } - LOG_IF(ERROR, !td_->contacts_manager_->have_user(user_id)) << "Receive unknown " << user_id; + LOG_IF(ERROR, !td_->user_manager_->have_user(user_id)) << "Receive unknown " << user_id; if (!td_->auth_manager_->is_bot()) { LOG(ERROR) << "Receive chosen inline query result"; return; } send_closure(G()->td(), &Td::send_update, make_tl_object( - td_->contacts_manager_->get_user_id_object(user_id, "updateNewChosenInlineResult"), + td_->user_manager_->get_user_id_object(user_id, "updateNewChosenInlineResult"), user_location.get_location_object(), query, result_id, get_inline_message_id(std::move(input_bot_inline_message_id)))); } @@ -2153,7 +2220,7 @@ bool InlineQueriesManager::update_bot_usage(UserId bot_user_id) { if (!recently_used_bot_user_ids_.empty() && recently_used_bot_user_ids_[0] == bot_user_id) { return false; } - auto r_bot_data = td_->contacts_manager_->get_bot_data(bot_user_id); + auto r_bot_data = td_->user_manager_->get_bot_data(bot_user_id); if (r_bot_data.is_error()) { return false; } @@ -2161,17 +2228,8 @@ bool InlineQueriesManager::update_bot_usage(UserId bot_user_id) { return false; } - auto it = std::find(recently_used_bot_user_ids_.begin(), recently_used_bot_user_ids_.end(), bot_user_id); - if (it == recently_used_bot_user_ids_.end()) { - if (static_cast(recently_used_bot_user_ids_.size()) == MAX_RECENT_INLINE_BOTS) { - CHECK(!recently_used_bot_user_ids_.empty()); - recently_used_bot_user_ids_.back() = bot_user_id; - } else { - recently_used_bot_user_ids_.push_back(bot_user_id); - } - it = recently_used_bot_user_ids_.end() - 1; - } - std::rotate(recently_used_bot_user_ids_.begin(), it, it + 1); + add_to_top(recently_used_bot_user_ids_, MAX_RECENT_INLINE_BOTS, bot_user_id); + return true; } diff --git a/protocols/Telegram/tdlib/td/td/telegram/InlineQueriesManager.h b/protocols/Telegram/tdlib/td/td/telegram/InlineQueriesManager.h index cc8bfa3c3d..5327c82114 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InlineQueriesManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/InlineQueriesManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -55,8 +55,10 @@ class InlineQueriesManager final : public Actor { td_api::object_ptr &&input_result, Promise> &&promise) const; - uint64 send_inline_query(UserId bot_user_id, DialogId dialog_id, Location user_location, const string &query, - const string &offset, Promise &&promise); + void get_weather(Location location, Promise> &&promise); + + void send_inline_query(UserId bot_user_id, DialogId dialog_id, Location user_location, const string &query, + const string &offset, Promise> &&promise); vector get_recent_inline_bots(Promise &&promise); @@ -67,9 +69,8 @@ class InlineQueriesManager final : public Actor { UserId get_inline_bot_user_id(int64 query_id) const; void on_get_inline_query_results(DialogId dialog_id, UserId bot_user_id, uint64 query_hash, - tl_object_ptr &&results); - - tl_object_ptr get_inline_query_results_object(uint64 query_hash); + tl_object_ptr &&results, + Promise> promise); void on_new_query(int64 query_id, UserId sender_user_id, Location user_location, tl_object_ptr peer_type, const string &query, @@ -78,17 +79,12 @@ class InlineQueriesManager final : public Actor { void on_chosen_result(UserId user_id, Location user_location, const string &query, const string &result_id, tl_object_ptr &&input_bot_inline_message_id); - static int32 get_inline_message_dc_id(const tl_object_ptr &inline_message_id); - - static tl_object_ptr get_input_bot_inline_message_id( - const string &inline_message_id); - static string get_inline_message_id( tl_object_ptr &&input_bot_inline_message_id); private: - static constexpr int32 MAX_RECENT_INLINE_BOTS = 20; // some reasonable value - static constexpr int32 INLINE_QUERY_DELAY_MS = 400; // server side limit + static constexpr size_t MAX_RECENT_INLINE_BOTS = 20; // some reasonable value + static constexpr int32 INLINE_QUERY_DELAY_MS = 400; // server side limit static constexpr int32 BOT_INLINE_MEDIA_RESULT_FLAG_HAS_PHOTO = 1 << 0; static constexpr int32 BOT_INLINE_MEDIA_RESULT_FLAG_HAS_DOCUMENT = 1 << 1; @@ -105,21 +101,29 @@ class InlineQueriesManager final : public Actor { bool register_inline_message_content(int64 query_id, const string &result_id, FileId file_id, tl_object_ptr &&inline_message, - int32 allowed_media_content_id, bool allow_invoice, Photo *photo = nullptr, + int32 allowed_media_content_id, bool is_secret_chat, Photo *photo = nullptr, Game *game = nullptr); tl_object_ptr register_thumbnail( tl_object_ptr &&web_document_ptr) const; static string get_web_document_url(const tl_object_ptr &web_document_ptr); + static string get_web_document_content_type(const tl_object_ptr &web_document_ptr); bool update_bot_usage(UserId bot_user_id); void save_recently_used_bots(); + bool load_recently_used_bots(Promise &promise); - tl_object_ptr decrease_pending_request_count(uint64 query_hash); + void do_get_weather(DialogId dialog_id, Location location, + Promise> &&promise); + + void on_get_weather(td_api::object_ptr results, + Promise> &&promise); + + td_api::object_ptr get_inline_query_results_object(uint64 query_hash); static void on_drop_inline_query_result_timeout_callback(void *inline_queries_manager_ptr, int64 query_hash); @@ -140,7 +144,7 @@ class InlineQueriesManager final : public Actor { Location user_location; string query; string offset; - Promise promise; + Promise> promise; }; double next_inline_query_time_ = 0.0; @@ -148,7 +152,7 @@ class InlineQueriesManager final : public Actor { NetQueryRef sent_query_; struct InlineQueryResult { - tl_object_ptr results; + td_api::object_ptr results; double cache_expire_time; int32 pending_request_count; }; diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputBusinessChatLink.cpp b/protocols/Telegram/tdlib/td/td/telegram/InputBusinessChatLink.cpp new file mode 100644 index 0000000000..7645965a5a --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/InputBusinessChatLink.cpp @@ -0,0 +1,50 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/InputBusinessChatLink.h" + +#include "td/telegram/DialogManager.h" +#include "td/telegram/misc.h" +#include "td/telegram/Td.h" + +#include "td/utils/logging.h" + +namespace td { + +InputBusinessChatLink::InputBusinessChatLink(const Td *td, td_api::object_ptr &&link) { + if (link == nullptr) { + return; + } + auto r_text = + get_formatted_text(td, td->dialog_manager_->get_my_dialog_id(), std::move(link->text_), false, true, true, false); + if (r_text.is_error()) { + LOG(INFO) << "Ignore draft text: " << r_text.error(); + } else { + text_ = r_text.move_as_ok(); + } + if (clean_input_string(link->title_)) { + title_ = std::move(link->title_); + } +} + +telegram_api::object_ptr InputBusinessChatLink::get_input_business_chat_link( + const UserManager *user_manager) const { + int32 flags = 0; + auto entities = get_input_message_entities(user_manager, &text_, "get_input_business_chat_link"); + if (!entities.empty()) { + flags |= telegram_api::inputBusinessChatLink::ENTITIES_MASK; + } + if (!title_.empty()) { + flags |= telegram_api::inputBusinessChatLink::TITLE_MASK; + } + return telegram_api::make_object(flags, text_.text, std::move(entities), title_); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const InputBusinessChatLink &link) { + return string_builder << '[' << link.title_ << ']'; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputBusinessChatLink.h b/protocols/Telegram/tdlib/td/td/telegram/InputBusinessChatLink.h new file mode 100644 index 0000000000..1cd9d1eb6d --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/InputBusinessChatLink.h @@ -0,0 +1,36 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageEntity.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Td; +class UserManager; + +class InputBusinessChatLink { + FormattedText text_; + string title_; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const InputBusinessChatLink &link); + + public: + InputBusinessChatLink(const Td *td, td_api::object_ptr &&link); + + telegram_api::object_ptr get_input_business_chat_link( + const UserManager *user_manager) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const InputBusinessChatLink &link); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputDialogId.cpp b/protocols/Telegram/tdlib/td/td/telegram/InputDialogId.cpp index 4298125b14..a6696bb312 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InputDialogId.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/InputDialogId.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,6 +15,25 @@ namespace td { +InputDialogId::InputDialogId(const telegram_api::object_ptr &input_user) { + CHECK(input_user != nullptr); + switch (input_user->get_id()) { + case telegram_api::inputUser::ID: { + auto user = static_cast(input_user.get()); + UserId user_id(user->user_id_); + if (user_id.is_valid()) { + dialog_id = DialogId(user_id); + access_hash = user->access_hash_; + return; + } + break; + } + default: + break; + } + LOG(ERROR) << "Receive " << to_string(input_user); +} + InputDialogId::InputDialogId(const tl_object_ptr &input_peer) { CHECK(input_peer != nullptr); switch (input_peer->get_id()) { diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputDialogId.h b/protocols/Telegram/tdlib/td/td/telegram/InputDialogId.h index 11eca9d44f..6a293396c0 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InputDialogId.h +++ b/protocols/Telegram/tdlib/td/td/telegram/InputDialogId.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -25,6 +25,8 @@ class InputDialogId { explicit constexpr InputDialogId(DialogId dialog_id) : dialog_id(dialog_id) { } + explicit InputDialogId(const telegram_api::object_ptr &input_user); + explicit InputDialogId(const tl_object_ptr &input_peer); static vector get_input_dialog_ids(const vector> &input_peers, diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.cpp b/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.cpp index 7f48f78382..071402c309 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.cpp @@ -1,11 +1,12 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/InputInvoice.h" +#include "td/telegram/AuthManager.h" #include "td/telegram/Dimensions.h" #include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileType.h" @@ -13,6 +14,7 @@ #include "td/telegram/PhotoSize.h" #include "td/telegram/ServerMessageId.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" @@ -34,14 +36,16 @@ bool operator==(const InputInvoice &lhs, const InputInvoice &rhs) { lhs.is_flexible_ == rhs.is_flexible_ && lhs.currency_ == rhs.currency_ && lhs.price_parts_ == rhs.price_parts_ && lhs.max_tip_amount_ == rhs.max_tip_amount_ && lhs.suggested_tip_amounts_ == rhs.suggested_tip_amounts_ && - lhs.recurring_payment_terms_of_service_url_ == rhs.recurring_payment_terms_of_service_url_; + lhs.recurring_payment_terms_of_service_url_ == rhs.recurring_payment_terms_of_service_url_ && + lhs.terms_of_service_url_ == rhs.terms_of_service_url_; }; return lhs.title_ == rhs.title_ && lhs.description_ == rhs.description_ && lhs.photo_ == rhs.photo_ && lhs.start_parameter_ == rhs.start_parameter_ && are_invoice_equal(lhs.invoice_, rhs.invoice_) && lhs.payload_ == rhs.payload_ && lhs.provider_token_ == rhs.provider_token_ && lhs.provider_data_ == rhs.provider_data_ && lhs.extended_media_ == rhs.extended_media_ && - lhs.total_amount_ == rhs.total_amount_ && lhs.receipt_message_id_ == rhs.receipt_message_id_; + lhs.extended_media_caption_ == rhs.extended_media_caption_ && lhs.total_amount_ == rhs.total_amount_ && + lhs.receipt_message_id_ == rhs.receipt_message_id_; } bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs) { @@ -60,8 +64,10 @@ InputInvoice::InputInvoice(tl_object_ptr &&me // payload_ = string(); // provider_token_ = string(); // provider_data_ = string(); - extended_media_ = - MessageExtendedMedia(td, std::move(message_invoice->extended_media_), std::move(message), owner_dialog_id); + extended_media_ = MessageExtendedMedia(td, std::move(message_invoice->extended_media_), owner_dialog_id); + if (!extended_media_.is_empty()) { + extended_media_caption_ = std::move(message); + } if (message_invoice->total_amount_ <= 0 || !check_currency_amount(message_invoice->total_amount_)) { LOG(ERROR) << "Receive invalid total amount " << message_invoice->total_amount_; message_invoice->total_amount_ = 0; @@ -89,6 +95,7 @@ InputInvoice::InputInvoice(tl_object_ptrtotal_amount_ <= 0 || !check_currency_amount(message_invoice->total_amount_)) { LOG(ERROR) << "Receive invalid total amount " << message_invoice->total_amount_; message_invoice->total_amount_ = 0; @@ -98,8 +105,7 @@ InputInvoice::InputInvoice(tl_object_ptr InputInvoice::process_input_message_invoice( - td_api::object_ptr &&input_message_content, Td *td, DialogId owner_dialog_id, - bool is_premium) { + td_api::object_ptr &&input_message_content, Td *td, DialogId owner_dialog_id) { CHECK(input_message_content != nullptr); CHECK(input_message_content->get_id() == td_api::inputMessageInvoice::ID); auto input_invoice = move_tl_object_as(input_message_content); @@ -128,6 +134,12 @@ Result InputInvoice::process_input_message_invoice( if (!clean_input_string(input_invoice->invoice_->currency_)) { return Status::Error(400, "Invoice currency must be encoded in UTF-8"); } + if (!clean_input_string(input_invoice->invoice_->recurring_payment_terms_of_service_url_)) { + return Status::Error(400, "Invoice terms of service URL must be encoded in UTF-8"); + } + if (!clean_input_string(input_invoice->invoice_->terms_of_service_url_)) { + return Status::Error(400, "Invoice terms of service URL must be encoded in UTF-8"); + } InputInvoice result; result.title_ = std::move(input_invoice->title_); @@ -199,6 +211,7 @@ Result InputInvoice::process_input_message_invoice( result.invoice_.suggested_tip_amounts_ = std::move(input_invoice->invoice_->suggested_tip_amounts_); result.invoice_.recurring_payment_terms_of_service_url_ = std::move(input_invoice->invoice_->recurring_payment_terms_of_service_url_); + result.invoice_.terms_of_service_url_ = std::move(input_invoice->invoice_->terms_of_service_url_); result.invoice_.is_test_ = input_invoice->invoice_->is_test_; result.invoice_.need_name_ = input_invoice->invoice_->need_name_; result.invoice_.need_phone_number_ = input_invoice->invoice_->need_phone_number_; @@ -221,20 +234,33 @@ Result InputInvoice::process_input_message_invoice( result.provider_token_ = std::move(input_invoice->provider_token_); result.provider_data_ = std::move(input_invoice->provider_data_); - TRY_RESULT(extended_media, MessageExtendedMedia::get_message_extended_media( - td, std::move(input_invoice->extended_media_content_), owner_dialog_id, is_premium)); + TRY_RESULT(extended_media, MessageExtendedMedia::get_message_extended_media(td, std::move(input_invoice->paid_media_), + owner_dialog_id)); result.extended_media_ = std::move(extended_media); + if (!result.extended_media_.is_empty()) { + bool is_bot = td->auth_manager_->is_bot(); + TRY_RESULT(extended_media_caption, + get_formatted_text(td, owner_dialog_id, std::move(input_invoice->paid_media_caption_), is_bot, true, + false, false)); + result.extended_media_caption_ = std::move(extended_media_caption); + } return result; } -tl_object_ptr InputInvoice::get_message_invoice_object(Td *td, bool skip_bot_commands, - int32 max_media_timestamp) const { - return make_tl_object( - title_, get_product_description_object(description_), get_photo_object(td->file_manager_.get(), photo_), - invoice_.currency_, total_amount_, start_parameter_, invoice_.is_test_, invoice_.need_shipping_address_, - receipt_message_id_.get(), - extended_media_.get_message_extended_media_object(td, skip_bot_commands, max_media_timestamp)); +td_api::object_ptr InputInvoice::get_message_invoice_object(Td *td, bool is_server, + bool skip_bot_commands, + int32 max_media_timestamp) const { + auto extended_media_object = extended_media_.get_paid_media_object(td); + auto extended_media_caption_object = + extended_media_object == nullptr + ? nullptr + : get_formatted_text_object(is_server ? td->user_manager_.get() : nullptr, extended_media_caption_, + skip_bot_commands, max_media_timestamp); + return td_api::make_object( + get_product_info_object(td, title_, description_, photo_), invoice_.currency_, total_amount_, start_parameter_, + invoice_.is_test_, invoice_.need_shipping_address_, receipt_message_id_.get(), std::move(extended_media_object), + std::move(extended_media_caption_object)); } tl_object_ptr InputInvoice::Invoice::get_input_invoice() const { @@ -266,8 +292,14 @@ tl_object_ptr InputInvoice::Invoice::get_input_invoice() if (max_tip_amount_ != 0) { flags |= telegram_api::invoice::MAX_TIP_AMOUNT_MASK; } + string terms_of_service_url; if (!recurring_payment_terms_of_service_url_.empty()) { - flags |= telegram_api::invoice::RECURRING_TERMS_URL_MASK; + flags |= telegram_api::invoice::RECURRING_MASK; + flags |= telegram_api::invoice::TERMS_URL_MASK; + terms_of_service_url = recurring_payment_terms_of_service_url_; + } else if (!terms_of_service_url_.empty()) { + flags |= telegram_api::invoice::TERMS_URL_MASK; + terms_of_service_url = terms_of_service_url_; } auto prices = transform(price_parts_, [](const LabeledPricePart &price) { @@ -276,11 +308,11 @@ tl_object_ptr InputInvoice::Invoice::get_input_invoice() return make_tl_object( flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, currency_, std::move(prices), - max_tip_amount_, vector(suggested_tip_amounts_), recurring_payment_terms_of_service_url_); + max_tip_amount_, vector(suggested_tip_amounts_), terms_of_service_url); } -static tl_object_ptr get_input_web_document(const FileManager *file_manager, - const Photo &photo) { +static telegram_api::object_ptr get_input_web_document(const FileManager *file_manager, + const Photo &photo) { if (photo.is_empty()) { return nullptr; } @@ -296,12 +328,12 @@ static tl_object_ptr get_input_web_document(cons } auto file_view = file_manager->get_file_view(size.file_id); - CHECK(file_view.has_url()); + const auto *url = file_view.get_url(); + CHECK(url != nullptr); - auto file_name = get_url_file_name(file_view.url()); - return make_tl_object( - file_view.url(), size.size, MimeType::from_extension(PathView(file_name).extension(), "image/jpeg"), - std::move(attributes)); + auto file_name = get_url_file_name(*url); + return telegram_api::make_object( + *url, size.size, MimeType::from_extension(PathView(file_name).extension(), "image/jpeg"), std::move(attributes)); } tl_object_ptr InputInvoice::get_input_media_invoice( @@ -323,6 +355,9 @@ tl_object_ptr InputInvoice::get_input_media_inv return nullptr; } } + if (!provider_token_.empty()) { + flags |= telegram_api::inputMediaInvoice::PROVIDER_MASK; + } return make_tl_object( flags, title_, description_, std::move(input_web_document), invoice_.get_input_invoice(), BufferSlice(payload_), @@ -371,7 +406,7 @@ bool InputInvoice::is_equal_but_different(const InputInvoice &other) const { } const FormattedText *InputInvoice::get_caption() const { - return extended_media_.get_caption(); + return &extended_media_caption_; } int32 InputInvoice::get_duration(const Td *td) const { @@ -403,11 +438,14 @@ bool InputInvoice::need_poll_extended_media() const { return extended_media_.need_poll(); } -tl_object_ptr get_product_description_object(const string &description) { - FormattedText result; - result.text = description; - result.entities = find_entities(result.text, true, true); - return get_formatted_text_object(result, true, 0); +td_api::object_ptr get_product_info_object(Td *td, const string &title, const string &description, + const Photo &photo) { + FormattedText formatted_description; + formatted_description.text = description; + formatted_description.entities = find_entities(formatted_description.text, true, true); + return td_api::make_object( + title, get_formatted_text_object(td->user_manager_.get(), formatted_description, true, 0), + get_photo_object(td->file_manager_.get(), photo)); } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.h b/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.h index 1adaf82d47..9fcb34668e 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.h +++ b/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,6 +9,7 @@ #include "td/telegram/DialogId.h" #include "td/telegram/files/FileId.h" #include "td/telegram/LabeledPricePart.h" +#include "td/telegram/MessageEntity.h" #include "td/telegram/MessageExtendedMedia.h" #include "td/telegram/MessageId.h" #include "td/telegram/Photo.h" @@ -30,6 +31,7 @@ class InputInvoice { int64 max_tip_amount_ = 0; vector suggested_tip_amounts_; string recurring_payment_terms_of_service_url_; + string terms_of_service_url_; bool is_test_ = false; bool need_name_ = false; bool need_phone_number_ = false; @@ -62,6 +64,7 @@ class InputInvoice { string provider_token_; string provider_data_; MessageExtendedMedia extended_media_; + FormattedText extended_media_caption_; int64 total_amount_ = 0; MessageId receipt_message_id_; @@ -78,11 +81,10 @@ class InputInvoice { DialogId owner_dialog_id); static Result process_input_message_invoice( - td_api::object_ptr &&input_message_content, Td *td, DialogId owner_dialog_id, - bool is_premium); + td_api::object_ptr &&input_message_content, Td *td, DialogId owner_dialog_id); - tl_object_ptr get_message_invoice_object(Td *td, bool skip_bot_commands, - int32 max_media_timestamp) const; + td_api::object_ptr get_message_invoice_object(Td *td, bool is_server, bool skip_bot_commands, + int32 max_media_timestamp) const; tl_object_ptr get_input_media_invoice( Td *td, tl_object_ptr input_file, @@ -128,6 +130,7 @@ class InputInvoice { bool operator==(const InputInvoice &lhs, const InputInvoice &rhs); bool operator!=(const InputInvoice &lhs, const InputInvoice &rhs); -tl_object_ptr get_product_description_object(const string &description); +td_api::object_ptr get_product_info_object(Td *td, const string &title, const string &description, + const Photo &photo); } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.hpp b/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.hpp index 4cbc8f1029..4700d16e8a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/InputInvoice.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,6 +8,7 @@ #include "td/telegram/InputInvoice.h" +#include "td/telegram/MessageEntity.hpp" #include "td/telegram/MessageExtendedMedia.hpp" #include "td/telegram/Photo.hpp" #include "td/telegram/Version.h" @@ -84,6 +85,7 @@ void InputInvoice::store(StorerT &storer) const { bool has_total_amount = total_amount_ != 0; bool has_receipt_message_id = receipt_message_id_.is_valid(); bool has_extended_media = !extended_media_.is_empty(); + bool has_extended_media_caption = !extended_media_caption_.text.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(has_description); STORE_FLAG(has_photo); @@ -94,6 +96,7 @@ void InputInvoice::store(StorerT &storer) const { STORE_FLAG(has_total_amount); STORE_FLAG(has_receipt_message_id); STORE_FLAG(has_extended_media); + STORE_FLAG(has_extended_media_caption); END_STORE_FLAGS(); store(title_, storer); if (has_description) { @@ -124,6 +127,9 @@ void InputInvoice::store(StorerT &storer) const { if (has_extended_media) { store(extended_media_, storer); } + if (has_extended_media_caption) { + store(extended_media_caption_, storer); + } } template @@ -138,6 +144,7 @@ void InputInvoice::parse(ParserT &parser) { bool has_total_amount; bool has_receipt_message_id; bool has_extended_media; + bool has_extended_media_caption = false; if (parser.version() >= static_cast(Version::AddInputInvoiceFlags)) { BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_description); @@ -149,6 +156,7 @@ void InputInvoice::parse(ParserT &parser) { PARSE_FLAG(has_total_amount); PARSE_FLAG(has_receipt_message_id); PARSE_FLAG(has_extended_media); + PARSE_FLAG(has_extended_media_caption); END_PARSE_FLAGS(); } else { has_description = true; @@ -190,6 +198,9 @@ void InputInvoice::parse(ParserT &parser) { if (has_extended_media) { parse(extended_media_, parser); } + if (has_extended_media_caption) { + parse(extended_media_caption_, parser); + } } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.cpp b/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.cpp index 35e85de333..c59046dbef 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.cpp @@ -1,12 +1,16 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/InputMessageText.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/Dependencies.h" #include "td/telegram/MessageEntity.h" +#include "td/telegram/misc.h" +#include "td/telegram/Td.h" #include "td/utils/common.h" @@ -27,17 +31,75 @@ Result process_input_message_text(const Td *td, DialogId dialo CHECK(input_message_content != nullptr); CHECK(input_message_content->get_id() == td_api::inputMessageText::ID); auto input_message_text = static_cast(input_message_content.get()); - TRY_RESULT(text, get_formatted_text(td, dialog_id, std::move(input_message_text->text_), is_bot, for_draft, for_draft, - for_draft)); - return InputMessageText{std::move(text), input_message_text->disable_web_page_preview_, - input_message_text->clear_draft_}; + string web_page_url; + bool disable_web_page_preview = false; + bool force_small_media = false; + bool force_large_media = false; + bool show_above_text = false; + if (input_message_text->link_preview_options_ != nullptr) { + auto options = std::move(input_message_text->link_preview_options_); + web_page_url = std::move(options->url_); + disable_web_page_preview = options->is_disabled_; + force_small_media = options->force_small_media_; + force_large_media = options->force_large_media_; + show_above_text = options->show_above_text_; + + if (!clean_input_string(web_page_url)) { + return Status::Error(400, "Link preview URL must be encoded in UTF-8"); + } + + if (disable_web_page_preview || + (dialog_id.get_type() == DialogType::Channel && + !td->chat_manager_->get_channel_permissions(dialog_id.get_channel_id()).can_add_web_page_previews())) { + web_page_url.clear(); + } + if (web_page_url.empty()) { + force_small_media = false; + force_large_media = false; + } + } + TRY_RESULT(text, get_formatted_text(td, dialog_id, std::move(input_message_text->text_), is_bot, + for_draft || !web_page_url.empty(), for_draft, for_draft)); + if (!disable_web_page_preview && web_page_url.empty() && dialog_id.get_type() == DialogType::SecretChat) { + web_page_url = get_first_url(text).str(); + } + return InputMessageText{ + std::move(text), std::move(web_page_url), disable_web_page_preview, force_small_media, + force_large_media, show_above_text, input_message_text->clear_draft_}; +} + +void InputMessageText::add_dependencies(Dependencies &dependencies) const { + add_formatted_text_dependencies(dependencies, &text); +} + +telegram_api::object_ptr InputMessageText::get_input_media_web_page() const { + if (web_page_url.empty()) { + return nullptr; + } + int32 flags = 0; + if (force_small_media) { + flags |= telegram_api::inputMediaWebPage::FORCE_SMALL_MEDIA_MASK; + } + if (force_large_media) { + flags |= telegram_api::inputMediaWebPage::FORCE_LARGE_MEDIA_MASK; + } + if (!text.text.empty()) { + flags |= telegram_api::inputMediaWebPage::OPTIONAL_MASK; + } + return telegram_api::make_object(flags, false /*ignored*/, false /*ignored*/, + false /*ignored*/, web_page_url); } // used only for draft -td_api::object_ptr get_input_message_text_object(const InputMessageText &input_message_text) { - return td_api::make_object(get_formatted_text_object(input_message_text.text, false, -1), - input_message_text.disable_web_page_preview, - input_message_text.clear_draft); +td_api::object_ptr InputMessageText::get_input_message_text_object( + const UserManager *user_manager) const { + td_api::object_ptr options; + if (!web_page_url.empty() || disable_web_page_preview || force_small_media || force_large_media || show_above_text) { + options = td_api::make_object(disable_web_page_preview, web_page_url, force_small_media, + force_large_media, show_above_text); + } + return td_api::make_object(get_formatted_text_object(user_manager, text, false, -1), + std::move(options), clear_draft); } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.h b/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.h index 647bd4b2d8..2a9518ba20 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.h +++ b/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,22 +9,50 @@ #include "td/telegram/DialogId.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/utils/common.h" #include "td/utils/Status.h" namespace td { +class Dependencies; + class Td; +class UserManager; + class InputMessageText { public: FormattedText text; + string web_page_url; bool disable_web_page_preview = false; + bool force_small_media = false; + bool force_large_media = false; + bool show_above_text = false; bool clear_draft = false; + InputMessageText() = default; - InputMessageText(FormattedText text, bool disable_web_page_preview, bool clear_draft) - : text(std::move(text)), disable_web_page_preview(disable_web_page_preview), clear_draft(clear_draft) { + InputMessageText(FormattedText text, string &&web_page_url, bool disable_web_page_preview, bool force_small_media, + bool force_large_media, bool show_above_text, bool clear_draft) + : text(std::move(text)) + , web_page_url(std::move(web_page_url)) + , disable_web_page_preview(disable_web_page_preview) + , force_small_media(force_small_media) + , force_large_media(force_large_media) + , show_above_text(show_above_text) + , clear_draft(clear_draft) { + } + + bool is_empty() const { + return text.text.empty() && web_page_url.empty(); } + + void add_dependencies(Dependencies &dependencies) const; + + telegram_api::object_ptr get_input_media_web_page() const; + + td_api::object_ptr get_input_message_text_object(const UserManager *user_manager) const; }; bool operator==(const InputMessageText &lhs, const InputMessageText &rhs); @@ -34,6 +62,4 @@ Result process_input_message_text(const Td *td, DialogId dialo tl_object_ptr &&input_message_content, bool is_bot, bool for_draft = false) TD_WARN_UNUSED_RESULT; -td_api::object_ptr get_input_message_text_object(const InputMessageText &input_message_text); - } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.hpp b/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.hpp index 1bec66a24f..b982a08f1a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/InputMessageText.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,20 +16,42 @@ namespace td { template void store(const InputMessageText &input_message_text, StorerT &storer) { + bool has_web_page_url = !input_message_text.web_page_url.empty(); + bool has_empty_text = input_message_text.text.text.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(input_message_text.disable_web_page_preview); STORE_FLAG(input_message_text.clear_draft); + STORE_FLAG(input_message_text.force_small_media); + STORE_FLAG(input_message_text.force_large_media); + STORE_FLAG(has_web_page_url); + STORE_FLAG(has_empty_text); END_STORE_FLAGS(); - store(input_message_text.text, storer); + if (!has_empty_text) { + store(input_message_text.text, storer); + } + if (has_web_page_url) { + store(input_message_text.web_page_url, storer); + } } template void parse(InputMessageText &input_message_text, ParserT &parser) { + bool has_web_page_url; + bool has_empty_text; BEGIN_PARSE_FLAGS(); PARSE_FLAG(input_message_text.disable_web_page_preview); PARSE_FLAG(input_message_text.clear_draft); + PARSE_FLAG(input_message_text.force_small_media); + PARSE_FLAG(input_message_text.force_large_media); + PARSE_FLAG(has_web_page_url); + PARSE_FLAG(has_empty_text); END_PARSE_FLAGS(); - parse(input_message_text.text, parser); + if (!has_empty_text) { + parse(input_message_text.text, parser); + } + if (has_web_page_url) { + parse(input_message_text.web_page_url, parser); + } } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/JsonValue.cpp b/protocols/Telegram/tdlib/td/td/telegram/JsonValue.cpp index dc2302a84e..2603935c2a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/JsonValue.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/JsonValue.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,6 +7,7 @@ #include "td/telegram/JsonValue.h" #include "td/telegram/misc.h" +#include "td/telegram/telegram_api.h" #include "td/utils/algorithm.h" #include "td/utils/JsonBuilder.h" @@ -18,14 +19,6 @@ namespace td { -static td_api::object_ptr get_json_value_object(const JsonValue &json_value); - -static td_api::object_ptr get_json_value_member_object( - const std::pair &json_value_member) { - return td_api::make_object(json_value_member.first.str(), - get_json_value_object(json_value_member.second)); -} - static td_api::object_ptr get_json_value_object(const JsonValue &json_value) { switch (json_value.type()) { case JsonValue::Type::Null: @@ -38,9 +31,13 @@ static td_api::object_ptr get_json_value_object(const JsonVal return td_api::make_object(json_value.get_string().str()); case JsonValue::Type::Array: return td_api::make_object(transform(json_value.get_array(), get_json_value_object)); - case JsonValue::Type::Object: - return td_api::make_object( - transform(json_value.get_object(), get_json_value_member_object)); + case JsonValue::Type::Object: { + vector> members; + json_value.get_object().foreach([&members](Slice name, const JsonValue &value) { + members.push_back(td_api::make_object(name.str(), get_json_value_object(value))); + }); + return td_api::make_object(std::move(members)); + } default: UNREACHABLE(); return nullptr; @@ -222,6 +219,9 @@ int64 get_json_value_long(telegram_api::object_ptr &&js if (json_value->get_id() == telegram_api::jsonString::ID) { return to_integer(static_cast(json_value.get())->value_); } + if (json_value->get_id() == telegram_api::jsonNumber::ID) { + return static_cast(static_cast(json_value.get())->value_); + } LOG(ERROR) << "Expected Long as " << name << ", but found " << to_string(json_value); return 0; } diff --git a/protocols/Telegram/tdlib/td/td/telegram/LanguagePackManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/LanguagePackManager.cpp index 87f8b8becb..4c95f337fe 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/LanguagePackManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/LanguagePackManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ #include "td/telegram/misc.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/Td.h" -#include "td/telegram/td_api.hpp" +#include "td/telegram/telegram_api.h" #include "td/db/DbKey.h" #include "td/db/SqliteDb.h" @@ -870,13 +870,9 @@ void LanguagePackManager::get_languages(bool only_local, auto request_promise = PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_, promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - - send_closure(actor_id, &LanguagePackManager::on_get_languages, r_result.move_as_ok(), std::move(language_pack), - false, std::move(promise)); + TRY_RESULT_PROMISE(promise, result, fetch_result(std::move(r_query))); + send_closure(actor_id, &LanguagePackManager::on_get_languages, std::move(result), std::move(language_pack), false, + std::move(promise)); }); send_with_promise(G()->net_query_creator().create_unauth(telegram_api::langpack_getLanguages(language_pack_)), std::move(request_promise)); @@ -891,13 +887,9 @@ void LanguagePackManager::search_language_info(string language_code, auto request_promise = PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_, language_code, promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - - LOG(INFO) << "Receive " << to_string(r_result.ok()); - send_closure(actor_id, &LanguagePackManager::on_get_language, r_result.move_as_ok(), std::move(language_pack), + TRY_RESULT_PROMISE(promise, result, fetch_result(std::move(r_query))); + LOG(INFO) << "Receive " << to_string(result); + send_closure(actor_id, &LanguagePackManager::on_get_language, std::move(result), std::move(language_pack), std::move(language_code), std::move(promise)); }); send_with_promise( @@ -1061,12 +1053,8 @@ void LanguagePackManager::on_get_language(tl_object_ptr> promise) { CHECK(lang_pack_language != nullptr); - auto r_info = get_language_info(lang_pack_language.get()); - if (r_info.is_error()) { - return promise.set_error(r_info.move_as_error()); - } - - auto result = get_language_pack_info_object(lang_pack_language->lang_code_, r_info.ok()); + TRY_RESULT_PROMISE(promise, language_info, get_language_info(lang_pack_language.get())); + auto result = get_language_pack_info_object(lang_pack_language->lang_code_, language_info); on_get_language_info(language_pack, result.get()); @@ -1083,15 +1071,15 @@ void LanguagePackManager::on_get_language(tl_object_ptrserver_language_pack_infos_) { if (info.first == lang_pack_language->lang_code_ || info.first == language_code) { - if (!(info.second == r_info.ok())) { + if (!(info.second == language_info)) { LOG(INFO) << "Language pack " << info.first << " was changed"; is_changed = true; - info.second = r_info.ok(); + info.second = language_info; } } } pack->all_server_language_pack_infos_[lang_pack_language->lang_code_] = - td::make_unique(r_info.move_as_ok()); + td::make_unique(std::move(language_info)); if (is_changed) { save_server_language_pack_infos(pack); @@ -1146,12 +1134,7 @@ void LanguagePackManager::get_language_pack_strings(string language_code, vector auto request_promise = PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_, language_code, promise = std::move(result_promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - - auto result = r_result.move_as_ok(); + TRY_RESULT_PROMISE(promise, result, fetch_result(std::move(r_query))); to_lower_inplace(result->lang_code_); LOG(INFO) << "Receive language pack " << result->lang_code_ << " from version " << result->from_version_ << " with version " << result->version_ << " of size " << result->strings_.size(); @@ -1169,13 +1152,9 @@ void LanguagePackManager::get_language_pack_strings(string language_code, vector auto request_promise = PromiseCreator::lambda([actor_id = actor_id(this), language_pack = language_pack_, language_code, keys, promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - + TRY_RESULT_PROMISE(promise, result, fetch_result(std::move(r_query))); send_closure(actor_id, &LanguagePackManager::on_get_language_pack_strings, std::move(language_pack), - std::move(language_code), -1, false, std::move(keys), r_result.move_as_ok(), std::move(promise)); + std::move(language_code), -1, false, std::move(keys), std::move(result), std::move(promise)); }); send_with_promise(G()->net_query_creator().create_unauth( telegram_api::langpack_getStrings(language_pack_, language_code, std::move(keys))), @@ -1733,10 +1712,7 @@ void LanguagePackManager::set_custom_language(td_api::object_ptrid_); if (!is_custom_language_code(language_code)) { return promise.set_error(Status::Error(400, "Custom language pack ID must begin with 'X'")); @@ -1744,11 +1720,8 @@ void LanguagePackManager::set_custom_language(td_api::object_ptr> server_strings; for (auto &str : strings) { - auto r_result = convert_to_telegram_api(std::move(str)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - server_strings.push_back(r_result.move_as_ok()); + TRY_RESULT_PROMISE(promise, result, convert_to_telegram_api(std::move(str))); + server_strings.push_back(std::move(result)); } // TODO atomic replace @@ -1761,7 +1734,7 @@ void LanguagePackManager::set_custom_language(td_api::object_ptrsecond.get(); std::lock_guard pack_lock(pack->mutex_); auto &info = pack->custom_language_pack_infos_[language_code]; - info = r_info.move_as_ok(); + info = std::move(language_info); if (!pack->pack_kv_.empty()) { pack->pack_kv_.set(language_code, get_language_info_string(info)); } @@ -1775,10 +1748,7 @@ void LanguagePackManager::edit_custom_language_info(td_api::object_ptrid_); if (!is_custom_language_code(language_code)) { return promise.set_error(Status::Error(400, "Custom language pack ID must begin with 'X'")); @@ -1794,7 +1764,7 @@ void LanguagePackManager::edit_custom_language_info(td_api::object_ptrsecond; - info = r_info.move_as_ok(); + info = std::move(language_info); if (!pack->pack_kv_.empty()) { pack->pack_kv_.set(language_code, get_language_info_string(info)); } @@ -1824,13 +1794,10 @@ void LanguagePackManager::set_custom_language_string(string language_code, vector keys{str->key_}; - auto r_str = convert_to_telegram_api(std::move(str)); - if (r_str.is_error()) { - return promise.set_error(r_str.move_as_error()); - } + TRY_RESULT_PROMISE(promise, lang_pack_string, convert_to_telegram_api(std::move(str))); vector> server_strings; - server_strings.push_back(r_str.move_as_ok()); + server_strings.push_back(std::move(lang_pack_string)); on_get_language_pack_strings(language_pack_, language_code, 1, true, std::move(keys), std::move(server_strings), Auto()); diff --git a/protocols/Telegram/tdlib/td/td/telegram/LinkManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/LinkManager.cpp index 7c0faeac50..75ee116530 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/LinkManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/LinkManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,9 +10,11 @@ #include "td/telegram/BackgroundType.h" #include "td/telegram/ChannelId.h" #include "td/telegram/ChannelType.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/ConfigManager.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/DialogId.h" +#include "td/telegram/DialogInviteLinkManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/DialogParticipant.h" #include "td/telegram/Global.h" #include "td/telegram/MessageEntity.h" @@ -20,17 +22,22 @@ #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" #include "td/telegram/net/Proxy.h" +#include "td/telegram/OptionManager.h" #include "td/telegram/ServerMessageId.h" +#include "td/telegram/StickersManager.h" +#include "td/telegram/StoryId.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" #include "td/mtproto/ProxySecret.h" #include "td/utils/algorithm.h" #include "td/utils/base64.h" #include "td/utils/buffer.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/HttpUrl.h" #include "td/utils/logging.h" #include "td/utils/misc.h" @@ -44,7 +51,7 @@ namespace td { static bool is_valid_start_parameter(Slice start_parameter) { - return start_parameter.size() <= 64 && is_base64url_characters(start_parameter); + return is_base64url_characters(start_parameter); } static bool is_valid_phone_number(Slice phone_number) { @@ -67,6 +74,11 @@ static bool is_valid_web_app_name(Slice name) { return name.size() >= 3 && is_valid_username(name); } +static bool is_valid_story_id(Slice story_id) { + auto r_story_id = to_integer_safe(story_id); + return r_story_id.is_ok() && StoryId(r_story_id.ok()).is_server(); +} + static string get_url_query_hash(bool is_tg, const HttpUrlQuery &url_query) { const auto &path = url_query.path_; if (is_tg) { @@ -103,6 +115,22 @@ static string get_url_query_slug(bool is_tg, const HttpUrlQuery &url_query) { return string(); } +static string get_url_query_draft_text(const HttpUrlQuery &url_query) { + auto text_slice = url_query.get_arg("text"); + if (text_slice.empty()) { + return string(); + } + auto text = text_slice.str(); + if (!check_utf8(text)) { + return string(); + } + text = utf8_truncate(std::move(text), 4096u); + if (text[0] == '@') { + return ' ' + text; + } + return text; +} + static AdministratorRights get_administrator_rights(Slice rights, bool for_channel) { bool can_manage_dialog = false; bool can_change_info = false; @@ -115,6 +143,9 @@ static AdministratorRights get_administrator_rights(Slice rights, bool for_chann bool can_manage_topics = false; bool can_promote_members = false; bool can_manage_calls = false; + bool can_post_stories = false; + bool can_edit_stories = false; + bool can_delete_stories = false; bool is_anonymous = false; for (auto right : full_split(rights, ' ')) { if (right == "change_info") { @@ -137,6 +168,12 @@ static AdministratorRights get_administrator_rights(Slice rights, bool for_chann can_promote_members = true; } else if (right == "manage_video_chats") { can_manage_calls = true; + } else if (right == "post_stories") { + can_post_stories = true; + } else if (right == "edit_stories") { + can_edit_stories = true; + } else if (right == "delete_stories") { + can_delete_stories = true; } else if (right == "anonymous") { is_anonymous = true; } else if (right == "manage_chat") { @@ -145,7 +182,8 @@ static AdministratorRights get_administrator_rights(Slice rights, bool for_chann } return AdministratorRights(is_anonymous, can_manage_dialog, can_change_info, can_post_messages, can_edit_messages, can_delete_messages, can_invite_users, can_restrict_members, can_pin_messages, - can_manage_topics, can_promote_members, can_manage_calls, + can_manage_topics, can_promote_members, can_manage_calls, can_post_stories, + can_edit_stories, can_delete_stories, for_channel ? ChannelType::Broadcast : ChannelType::Megagroup); } @@ -181,6 +219,15 @@ static string get_admin_string(AdministratorRights rights) { if (rights.can_manage_calls()) { admin_rights.emplace_back("manage_video_chats"); } + if (rights.can_post_stories()) { + admin_rights.emplace_back("post_stories"); + } + if (rights.can_edit_stories()) { + admin_rights.emplace_back("edit_stories"); + } + if (rights.can_delete_stories()) { + admin_rights.emplace_back("delete_stories"); + } if (rights.is_anonymous()) { admin_rights.emplace_back("anonymous"); } @@ -304,7 +351,7 @@ class LinkManager::InternalLinkBotStart final : public InternalLink { autostart = true; } else { const Td *td = G()->td().get_actor_unsafe(); - auto dialog_id = td->messages_manager_->resolve_dialog_username(bot_username_); + auto dialog_id = td->dialog_manager_->get_resolved_dialog_by_username(bot_username_); if (dialog_id.is_valid() && dialog_id.get_type() == DialogType::User && td->messages_manager_->get_dialog_has_last_message(dialog_id) && !td->messages_manager_->is_dialog_blocked(dialog_id)) { @@ -341,6 +388,32 @@ class LinkManager::InternalLinkBotStartInGroup final : public InternalLink { } }; +class LinkManager::InternalLinkBusinessChat final : public InternalLink { + string link_name_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(link_name_); + } + + public: + explicit InternalLinkBusinessChat(string link_name) : link_name_(std::move(link_name)) { + } +}; + +class LinkManager::InternalLinkBuyStars final : public InternalLink { + int64 star_count_; + string purpose_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(star_count_, purpose_); + } + + public: + InternalLinkBuyStars(int64 star_count, const string &purpose) + : star_count_(clamp(star_count, static_cast(1), static_cast(1000000000000))), purpose_(purpose) { + } +}; + class LinkManager::InternalLinkChangePhoneNumber final : public InternalLink { td_api::object_ptr get_internal_link_type_object() const final { return td_api::make_object(); @@ -367,6 +440,18 @@ class LinkManager::InternalLinkDefaultMessageAutoDeleteTimerSettings final : pub } }; +class LinkManager::InternalLinkDialogBoost final : public InternalLink { + string url_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(url_); + } + + public: + explicit InternalLinkDialogBoost(string url) : url_(std::move(url)) { + } +}; + class LinkManager::InternalLinkDialogFolderInvite final : public InternalLink { string url_; @@ -461,6 +546,21 @@ class LinkManager::InternalLinkLanguageSettings final : public InternalLink { } }; +class LinkManager::InternalLinkMainWebApp final : public InternalLink { + string bot_username_; + string start_parameter_; + string mode_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(bot_username_, start_parameter_, mode_ == "compact"); + } + + public: + InternalLinkMainWebApp(string bot_username, string start_parameter, string mode) + : bot_username_(std::move(bot_username)), start_parameter_(std::move(start_parameter)), mode_(std::move(mode)) { + } +}; + class LinkManager::InternalLinkMessage final : public InternalLink { string url_; @@ -478,8 +578,8 @@ class LinkManager::InternalLinkMessageDraft final : public InternalLink { bool contains_link_ = false; td_api::object_ptr get_internal_link_type_object() const final { - return td_api::make_object(get_formatted_text_object(text_, true, -1), - contains_link_); + return td_api::make_object( + get_formatted_text_object(nullptr, text_, true, -1), contains_link_); } public: @@ -523,6 +623,30 @@ class LinkManager::InternalLinkPremiumFeatures final : public InternalLink { } }; +class LinkManager::InternalLinkPremiumGift final : public InternalLink { + string referrer_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(referrer_); + } + + public: + explicit InternalLinkPremiumGift(string referrer) : referrer_(std::move(referrer)) { + } +}; + +class LinkManager::InternalLinkPremiumGiftCode final : public InternalLink { + string code_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(code_); + } + + public: + explicit InternalLinkPremiumGiftCode(string code) : code_(std::move(code)) { + } +}; + class LinkManager::InternalLinkPrivacyAndSecuritySettings final : public InternalLink { td_api::object_ptr get_internal_link_type_object() const final { return td_api::make_object(); @@ -563,13 +687,16 @@ class LinkManager::InternalLinkProxy final : public InternalLink { class LinkManager::InternalLinkPublicDialog final : public InternalLink { string dialog_username_; + string draft_text_; + bool open_profile_; td_api::object_ptr get_internal_link_type_object() const final { - return td_api::make_object(dialog_username_); + return td_api::make_object(dialog_username_, draft_text_, open_profile_); } public: - explicit InternalLinkPublicDialog(string dialog_username) : dialog_username_(std::move(dialog_username)) { + InternalLinkPublicDialog(string dialog_username, string draft_text, bool open_profile) + : dialog_username_(std::move(dialog_username)), draft_text_(std::move(draft_text)), open_profile_(open_profile) { } }; @@ -605,6 +732,20 @@ class LinkManager::InternalLinkStickerSet final : public InternalLink { } }; +class LinkManager::InternalLinkStory final : public InternalLink { + string story_sender_username_; + StoryId story_id_; + + td_api::object_ptr get_internal_link_type_object() const final { + return td_api::make_object(story_sender_username_, story_id_.get()); + } + + public: + InternalLinkStory(string story_sender_username, StoryId story_id) + : story_sender_username_(std::move(story_sender_username)), story_id_(story_id) { + } +}; + class LinkManager::InternalLinkTheme final : public InternalLink { string theme_name_; @@ -643,13 +784,18 @@ class LinkManager::InternalLinkUnsupportedProxy final : public InternalLink { class LinkManager::InternalLinkUserPhoneNumber final : public InternalLink { string phone_number_; + string draft_text_; + bool open_profile_; td_api::object_ptr get_internal_link_type_object() const final { - return td_api::make_object(phone_number_); + return td_api::make_object(phone_number_, draft_text_, open_profile_); } public: - explicit InternalLinkUserPhoneNumber(string phone_number) : phone_number_(std::move(phone_number)) { + InternalLinkUserPhoneNumber(Slice phone_number, string draft_text, bool open_profile) + : phone_number_(PSTRING() << '+' << phone_number) + , draft_text_(std::move(draft_text)) + , open_profile_(open_profile) { } }; @@ -686,16 +832,118 @@ class LinkManager::InternalLinkWebApp final : public InternalLink { string bot_username_; string web_app_short_name_; string start_parameter_; + string mode_; td_api::object_ptr get_internal_link_type_object() const final { - return td_api::make_object(bot_username_, web_app_short_name_, start_parameter_); + return td_api::make_object(bot_username_, web_app_short_name_, start_parameter_, + mode_ == "compact"); } public: - InternalLinkWebApp(string bot_username, string web_app_short_name, string start_parameter) + InternalLinkWebApp(string bot_username, string web_app_short_name, string start_parameter, string mode) : bot_username_(std::move(bot_username)) , web_app_short_name_(std::move(web_app_short_name)) - , start_parameter_(std::move(start_parameter)) { + , start_parameter_(std::move(start_parameter)) + , mode_(std::move(mode)) { + } +}; + +class GetRecentMeUrlsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetRecentMeUrlsQuery(Promise> &&promise) : promise_(std::move(promise)) { + } + + void send(const string &referrer) { + send_query(G()->net_query_creator().create(telegram_api::help_getRecentMeUrls(referrer))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto urls_full = result_ptr.move_as_ok(); + td_->user_manager_->on_get_users(std::move(urls_full->users_), "GetRecentMeUrlsQuery"); + td_->chat_manager_->on_get_chats(std::move(urls_full->chats_), "GetRecentMeUrlsQuery"); + + auto urls = std::move(urls_full->urls_); + auto results = td_api::make_object(); + results->urls_.reserve(urls.size()); + for (auto &url_ptr : urls) { + CHECK(url_ptr != nullptr); + td_api::object_ptr result = td_api::make_object(); + switch (url_ptr->get_id()) { + case telegram_api::recentMeUrlUser::ID: { + auto url = telegram_api::move_object_as(url_ptr); + result->url_ = std::move(url->url_); + UserId user_id(url->user_id_); + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + result = nullptr; + break; + } + result->type_ = td_api::make_object( + td_->user_manager_->get_user_id_object(user_id, "tMeUrlTypeUser")); + break; + } + case telegram_api::recentMeUrlChat::ID: { + auto url = telegram_api::move_object_as(url_ptr); + result->url_ = std::move(url->url_); + ChannelId channel_id(url->chat_id_); + if (!channel_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << channel_id; + result = nullptr; + break; + } + result->type_ = td_api::make_object( + td_->chat_manager_->get_supergroup_id_object(channel_id, "tMeUrlTypeSupergroup")); + break; + } + case telegram_api::recentMeUrlChatInvite::ID: { + auto url = telegram_api::move_object_as(url_ptr); + result->url_ = std::move(url->url_); + td_->dialog_invite_link_manager_->on_get_dialog_invite_link_info(result->url_, std::move(url->chat_invite_), + Promise()); + auto info_object = td_->dialog_invite_link_manager_->get_chat_invite_link_info_object(result->url_); + if (info_object == nullptr) { + result = nullptr; + break; + } + result->type_ = td_api::make_object(std::move(info_object)); + break; + } + case telegram_api::recentMeUrlStickerSet::ID: { + auto url = telegram_api::move_object_as(url_ptr); + result->url_ = std::move(url->url_); + auto sticker_set_id = + td_->stickers_manager_->on_get_sticker_set_covered(std::move(url->set_), false, "recentMeUrlStickerSet"); + if (!sticker_set_id.is_valid()) { + LOG(ERROR) << "Receive invalid sticker set"; + result = nullptr; + break; + } + result->type_ = td_api::make_object(sticker_set_id.get()); + break; + } + case telegram_api::recentMeUrlUnknown::ID: + // skip + result = nullptr; + break; + default: + UNREACHABLE(); + } + if (result != nullptr) { + results->urls_.push_back(std::move(result)); + } + } + promise_.set_value(std::move(results)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); } }; @@ -723,18 +971,10 @@ class GetDeepLinkInfoQuery final : public Td::ResultHandler { return promise_.set_value(nullptr); case telegram_api::help_deepLinkInfo::ID: { auto info = telegram_api::move_object_as(result); - auto entities = get_message_entities(nullptr, std::move(info->entities_), "GetDeepLinkInfoQuery"); - auto status = fix_formatted_text(info->message_, entities, true, true, true, true, true); - if (status.is_error()) { - LOG(ERROR) << "Receive error " << status << " while parsing deep link info " << info->message_; - if (!clean_input_string(info->message_)) { - info->message_.clear(); - } - entities = find_entities(info->message_, true, true); - } - FormattedText text{std::move(info->message_), std::move(entities)}; - return promise_.set_value( - td_api::make_object(get_formatted_text_object(text, true, -1), info->update_app_)); + auto text = get_formatted_text(nullptr, std::move(info->message_), std::move(info->entities_), true, true, + "GetDeepLinkInfoQuery"); + return promise_.set_value(td_api::make_object( + get_formatted_text_object(td_->user_manager_.get(), text, true, -1), info->update_app_)); } default: UNREACHABLE(); @@ -756,20 +996,20 @@ class RequestUrlAuthQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(string url, FullMessageId full_message_id, int32 button_id) { + void send(string url, MessageFullId message_full_id, int32 button_id) { url_ = std::move(url); int32 flags = 0; tl_object_ptr input_peer; - if (full_message_id.get_dialog_id().is_valid()) { - dialog_id_ = full_message_id.get_dialog_id(); - input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (message_full_id.get_dialog_id().is_valid()) { + dialog_id_ = message_full_id.get_dialog_id(); + input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); CHECK(input_peer != nullptr); flags |= telegram_api::messages_requestUrlAuth::PEER_MASK; } else { flags |= telegram_api::messages_requestUrlAuth::URL_MASK; } send_query(G()->net_query_creator().create(telegram_api::messages_requestUrlAuth( - flags, std::move(input_peer), full_message_id.get_message_id().get_server_message_id().get(), button_id, + flags, std::move(input_peer), message_full_id.get_message_id().get_server_message_id().get(), button_id, url_))); } @@ -784,13 +1024,13 @@ class RequestUrlAuthQuery final : public Td::ResultHandler { switch (result->get_id()) { case telegram_api::urlAuthResultRequest::ID: { auto request = telegram_api::move_object_as(result); - UserId bot_user_id = ContactsManager::get_user_id(request->bot_); + UserId bot_user_id = UserManager::get_user_id(request->bot_); if (!bot_user_id.is_valid()) { return on_error(Status::Error(500, "Receive invalid bot_user_id")); } - td_->contacts_manager_->on_get_user(std::move(request->bot_), "RequestUrlAuthQuery"); + td_->user_manager_->on_get_user(std::move(request->bot_), "RequestUrlAuthQuery"); promise_.set_value(td_api::make_object( - url_, request->domain_, td_->contacts_manager_->get_user_id_object(bot_user_id, "RequestUrlAuthQuery"), + url_, request->domain_, td_->user_manager_->get_user_id_object(bot_user_id, "RequestUrlAuthQuery"), request->request_write_access_)); break; } @@ -807,7 +1047,7 @@ class RequestUrlAuthQuery final : public Td::ResultHandler { void on_error(Status status) final { if (!dialog_id_.is_valid() || - !td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "RequestUrlAuthQuery")) { + !td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "RequestUrlAuthQuery")) { LOG(INFO) << "Receive error for RequestUrlAuthQuery: " << status; } promise_.set_value(td_api::make_object(url_, false)); @@ -823,13 +1063,13 @@ class AcceptUrlAuthQuery final : public Td::ResultHandler { explicit AcceptUrlAuthQuery(Promise> &&promise) : promise_(std::move(promise)) { } - void send(string url, FullMessageId full_message_id, int32 button_id, bool allow_write_access) { + void send(string url, MessageFullId message_full_id, int32 button_id, bool allow_write_access) { url_ = std::move(url); int32 flags = 0; tl_object_ptr input_peer; - if (full_message_id.get_dialog_id().is_valid()) { - dialog_id_ = full_message_id.get_dialog_id(); - input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (message_full_id.get_dialog_id().is_valid()) { + dialog_id_ = message_full_id.get_dialog_id(); + input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); CHECK(input_peer != nullptr); flags |= telegram_api::messages_acceptUrlAuth::PEER_MASK; } else { @@ -839,7 +1079,7 @@ class AcceptUrlAuthQuery final : public Td::ResultHandler { flags |= telegram_api::messages_acceptUrlAuth::WRITE_ALLOWED_MASK; } send_query(G()->net_query_creator().create(telegram_api::messages_acceptUrlAuth( - flags, false /*ignored*/, std::move(input_peer), full_message_id.get_message_id().get_server_message_id().get(), + flags, false /*ignored*/, std::move(input_peer), message_full_id.get_message_id().get_server_message_id().get(), button_id, url_))); } @@ -868,7 +1108,7 @@ class AcceptUrlAuthQuery final : public Td::ResultHandler { void on_error(Status status) final { if (!dialog_id_.is_valid() || - !td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "AcceptUrlAuthQuery")) { + !td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "AcceptUrlAuthQuery")) { LOG(INFO) << "Receive error for AcceptUrlAuthQuery: " << status; } promise_.set_error(std::move(status)); @@ -930,21 +1170,25 @@ string LinkManager::get_checked_link(Slice link, bool http_only, bool https_only Result LinkManager::check_link_impl(Slice link, bool http_only, bool https_only) { bool is_tg = false; bool is_ton = false; + bool is_tonsite = false; if (tolower_begins_with(link, "tg:")) { link.remove_prefix(3); is_tg = true; } else if (tolower_begins_with(link, "ton:")) { link.remove_prefix(4); is_ton = true; + } else if (tolower_begins_with(link, "tonsite:")) { + link.remove_prefix(8); + is_tonsite = true; } - if ((is_tg || is_ton) && begins_with(link, "//")) { + if ((is_tg || is_ton || is_tonsite) && begins_with(link, "//")) { link.remove_prefix(2); } TRY_RESULT(http_url, parse_url(link)); - if (https_only && (http_url.protocol_ != HttpUrl::Protocol::Https || is_tg || is_ton)) { + if (https_only && (http_url.protocol_ != HttpUrl::Protocol::Https || is_tg || is_ton || is_tonsite)) { return Status::Error("Only HTTPS links are allowed"); } - if (is_tg || is_ton) { + if (is_tg || is_ton || is_tonsite) { if (http_only) { return Status::Error("Only HTTP links are allowed"); } @@ -959,11 +1203,11 @@ Result LinkManager::check_link_impl(Slice link, bool http_only, bool htt query.remove_prefix(1); } for (auto c : http_url.host_) { - if (!is_alnum(c) && c != '-' && c != '_') { + if (!is_alnum(c) && c != '-' && c != '_' && !(is_tonsite && c == '.')) { return Status::Error("Unallowed characters in URL host"); } } - return PSTRING() << (is_tg ? "tg" : "ton") << "://" << http_url.host_ << query; + return PSTRING() << (is_tg ? "tg" : (is_tonsite ? "tonsite" : "ton")) << "://" << http_url.host_ << query; } if (http_url.host_.find('.') == string::npos && !http_url.is_ipv6_) { @@ -1016,11 +1260,11 @@ LinkManager::LinkInfo LinkManager::get_link_info(Slice link) { to_lower_inplace(host); if (ends_with(host, ".t.me") && host.size() >= 9 && host.find('.') == host.size() - 5) { Slice subdomain(&host[0], host.size() - 5); - if (is_valid_username(subdomain) && subdomain != "addemoji" && subdomain != "addlist" && - subdomain != "addstickers" && subdomain != "addtheme" && subdomain != "auth" && subdomain != "confirmphone" && - subdomain != "invoice" && subdomain != "joinchat" && subdomain != "login" && subdomain != "proxy" && - subdomain != "setlanguage" && subdomain != "share" && subdomain != "socks" && subdomain != "web" && - subdomain != "k" && subdomain != "z") { + static const FlatHashSet disallowed_subdomains( + {"addemoji", "addlist", "addstickers", "addtheme", "auth", "boost", "confirmphone", + "contact", "giftcode", "invoice", "joinchat", "login", "m", "proxy", + "setlanguage", "share", "socks", "web", "a", "k", "z"}); + if (is_valid_username(subdomain) && disallowed_subdomains.count(subdomain) == 0) { result.type_ = LinkType::TMe; result.query_ = PSTRING() << '/' << subdomain << http_url.query_; return result; @@ -1166,7 +1410,7 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que // resolve?domain=&videochat // resolve?domain=&videochat= if (Scheduler::context() != nullptr) { - send_closure(G()->messages_manager(), &MessagesManager::reload_voice_chat_on_search, username); + send_closure(G()->dialog_manager(), &DialogManager::reload_voice_chat_on_search, username); } return td::make_unique(std::move(username), arg.second, arg.first == "livestream"); } @@ -1195,17 +1439,27 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que } if (arg.first == "appname" && is_valid_web_app_name(arg.second)) { // resolve?domain=&appname= - // resolve?domain=&appname=&startapp= - return td::make_unique(std::move(username), arg.second, - url_query.get_arg("startapp").str()); + // resolve?domain=&appname=&startapp=&mode=compact + return td::make_unique( + std::move(username), arg.second, url_query.get_arg("startapp").str(), url_query.get_arg("mode").str()); } + if (arg.first == "story" && is_valid_story_id(arg.second)) { + // resolve?domain=&story= + return td::make_unique(std::move(username), StoryId(to_integer(arg.second))); + } + } + if (url_query.has_arg("startapp") && !url_query.has_arg("appname")) { + // resolve?domain=&startapp= + // resolve?domain=&startapp=&mode=compact + return td::make_unique(std::move(username), url_query.get_arg("startapp").str(), + url_query.get_arg("mode").str()); } if (!url_query.get_arg("attach").empty()) { // resolve?domain=&attach= // resolve?domain=&attach=&startattach= return td::make_unique( - nullptr, td::make_unique(std::move(username)), url_query.get_arg("attach").str(), - url_query.get_arg("startattach")); + nullptr, td::make_unique(std::move(username), string(), false), + url_query.get_arg("attach").str(), url_query.get_arg("startattach")); } else if (url_query.has_arg("startattach")) { // resolve?domain=&startattach&choose=users+bots+groups+channels // resolve?domain=&startattach=&choose=users+bots+groups+channels @@ -1220,17 +1474,23 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que } } // resolve?domain= - return td::make_unique(std::move(username)); - } else if (is_valid_phone_number(get_arg("phone"))) { - auto user_link = td::make_unique(get_arg("phone")); - if (!url_query.get_arg("attach").empty()) { - // resolve?phone=&attach= - // resolve?phone=&attach=&startattach= - return td::make_unique( - nullptr, std::move(user_link), url_query.get_arg("attach").str(), url_query.get_arg("startattach")); + return td::make_unique(std::move(username), get_url_query_draft_text(url_query), + url_query.has_arg("profile")); + } else { + string phone_number_str = get_arg("phone"); + auto phone_number = phone_number_str[0] == ' ' ? Slice(phone_number_str).substr(1) : Slice(phone_number_str); + if (is_valid_phone_number(phone_number)) { + if (!url_query.get_arg("attach").empty()) { + // resolve?phone=&attach= + // resolve?phone=&attach=&startattach= + return td::make_unique( + nullptr, td::make_unique(phone_number, string(), false), + url_query.get_arg("attach").str(), url_query.get_arg("startattach")); + } + // resolve?phone=12345 + return td::make_unique(phone_number, get_url_query_draft_text(url_query), + url_query.has_arg("profile")); } - // resolve?phone=12345 - return std::move(user_link); } } else if (path.size() == 1 && path[0] == "contact") { // contact?token= @@ -1255,6 +1515,9 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que } else if (path.size() == 1 && path[0] == "premium_offer") { // premium_offer?ref= return td::make_unique(get_arg("ref")); + } else if (path.size() == 1 && path[0] == "premium_multigift") { + // premium_multigift?ref= + return td::make_unique(get_arg("ref")); } else if (!path.empty() && path[0] == "settings") { if (path.size() == 2 && path[1] == "auto_delete") { // settings/auto_delete @@ -1353,6 +1616,15 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que PSTRING() << "tg://privatepost" << copy_arg("channel") << copy_arg("post") << copy_arg("single") << copy_arg("thread") << copy_arg("comment") << copy_arg("t")); } + } else if (path.size() == 1 && path[0] == "boost") { + // boost?domain=channel_username + // boost?channel=123456 + if (has_arg("domain")) { + return td::make_unique(PSTRING() << "tg://boost" << copy_arg("domain")); + } + if (has_arg("channel")) { + return td::make_unique(PSTRING() << "tg://boost" << copy_arg("channel")); + } } else if (path.size() == 1 && path[0] == "bg") { // bg?color= // bg?gradient=-&rotation=... @@ -1375,10 +1647,26 @@ unique_ptr LinkManager::parse_tg_link_query(Slice que if (has_arg("slug")) { return td::make_unique(url_query.get_arg("slug").str()); } + } else if (path.size() == 1 && path[0] == "giftcode") { + // giftcode?slug= + if (has_arg("slug")) { + return td::make_unique(url_query.get_arg("slug").str()); + } + } else if (path.size() == 1 && path[0] == "message") { + // message?slug= + if (has_arg("slug")) { + return td::make_unique(url_query.get_arg("slug").str()); + } } else if (path.size() == 1 && (path[0] == "share" || path[0] == "msg" || path[0] == "msg_url")) { // msg_url?url= // msg_url?url=&text= return get_internal_link_message_draft(get_arg("url"), get_arg("text")); + } else if (path.size() == 1 && path[0] == "stars_topup") { + // stars_topup?balance=&purpose= + if (has_arg("balance")) { + return td::make_unique(to_integer(url_query.get_arg("balance")), + url_query.get_arg("purpose").str()); + } } if (!path.empty() && !path[0].empty()) { return td::make_unique(PSTRING() << "tg://" << query); @@ -1420,6 +1708,9 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q return td::make_unique(PSTRING() << "tg://privatepost?channel=" << to_integer(path[1]) << "&post=" << post << copy_arg("single") << thread << copy_arg("comment") << copy_arg("t")); + } else if (path.size() >= 2 && to_integer(path[1]) > 0 && url_query.has_arg("boost")) { + // /c/123456789?boost + return td::make_unique(PSTRING() << "tg://boost?channel=" << to_integer(path[1])); } } else if (path[0] == "login") { if (path.size() >= 2 && !path[1].empty()) { @@ -1441,15 +1732,16 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q } else if (path[0][0] == ' ' || path[0][0] == '+') { auto invite_hash = get_url_query_hash(false, url_query); if (is_valid_phone_number(invite_hash)) { - auto user_link = td::make_unique(invite_hash); if (!url_query.get_arg("attach").empty()) { // /+?attach= // /+?attach=&startattach= return td::make_unique( - nullptr, std::move(user_link), url_query.get_arg("attach").str(), url_query.get_arg("startattach")); + nullptr, td::make_unique(invite_hash, string(), false), + url_query.get_arg("attach").str(), url_query.get_arg("startattach")); } // /+ - return std::move(user_link); + return td::make_unique(invite_hash, get_url_query_draft_text(url_query), + url_query.has_arg("profile")); } else if (!invite_hash.empty() && is_base64url_characters(invite_hash)) { // /+ return td::make_unique(get_dialog_invite_link(invite_hash, true)); @@ -1522,6 +1814,16 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q // /invoice/ return td::make_unique(path[1]); } + } else if (path[0] == "giftcode") { + if (path.size() >= 2 && !path[1].empty()) { + // /giftcode/ + return td::make_unique(path[1]); + } + } else if (path[0] == "m") { + if (path.size() >= 2 && !path[1].empty()) { + // /m/ + return td::make_unique(path[1]); + } } else if (path[0][0] == '$') { if (path[0].size() >= 2) { // /$ @@ -1554,21 +1856,42 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q << "&post=" << post << copy_arg("single") << thread << copy_arg("comment") << copy_arg("t")); } + auto username = path[0]; + if (to_lower(username) == "boost") { + if (path.size() == 2 && is_valid_username(path[1])) { + // /boost/ + return td::make_unique(PSTRING() << "tg://boost?domain=" << url_encode(path[1])); + } + auto channel_id = url_query.get_arg("c"); + if (path.size() == 1 && to_integer(channel_id) > 0) { + // /boost?c= + return td::make_unique(PSTRING() + << "tg://boost?channel=" << to_integer(channel_id)); + } + } + if (path.size() == 3 && path[1] == "s" && is_valid_story_id(path[2])) { + // //s/ + return td::make_unique(std::move(username), StoryId(to_integer(path[2]))); + } if (path.size() == 2 && is_valid_web_app_name(path[1])) { // // - // //?startapp= - return td::make_unique(path[0], path[1], url_query.get_arg("startapp").str()); + // //?startapp=&mode=compact + return td::make_unique(std::move(username), path[1], url_query.get_arg("startapp").str(), + url_query.get_arg("mode").str()); } - auto username = path[0]; for (auto &arg : url_query.args_) { if (arg.first == "voicechat" || arg.first == "videochat" || arg.first == "livestream") { // /?videochat // /?videochat= if (Scheduler::context() != nullptr) { - send_closure(G()->messages_manager(), &MessagesManager::reload_voice_chat_on_search, username); + send_closure(G()->dialog_manager(), &DialogManager::reload_voice_chat_on_search, username); } return td::make_unique(std::move(username), arg.second, arg.first == "livestream"); } + if (arg.first == "boost") { + // /?boost + return td::make_unique(PSTRING() << "tg://boost?domain=" << url_encode(username)); + } if (arg.first == "start" && is_valid_start_parameter(arg.second)) { // /?start= return td::make_unique(std::move(username), arg.second, is_trusted); @@ -1588,6 +1911,12 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q return td::make_unique(std::move(username), std::move(administrator_rights)); } } + if (arg.first == "startapp" && is_valid_start_parameter(arg.second)) { + // /?startapp + // /?startapp=&mode=compact + return td::make_unique(std::move(username), arg.second, + url_query.get_arg("mode").str()); + } if (arg.first == "game" && is_valid_game_name(arg.second)) { // /?game= return td::make_unique(std::move(username), arg.second); @@ -1597,8 +1926,8 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q // /?attach= // /?attach=&startattach= return td::make_unique( - nullptr, td::make_unique(std::move(username)), url_query.get_arg("attach").str(), - url_query.get_arg("startattach")); + nullptr, td::make_unique(std::move(username), string(), false), + url_query.get_arg("attach").str(), url_query.get_arg("startattach")); } else if (url_query.has_arg("startattach")) { // /?startattach&choose=users+bots+groups+channels // /?startattach=&choose=users+bots+groups+channels @@ -1607,7 +1936,8 @@ unique_ptr LinkManager::parse_t_me_link_query(Slice q } // / - return td::make_unique(std::move(username)); + return td::make_unique(std::move(username), get_url_query_draft_text(url_query), + url_query.has_arg("profile")); } return nullptr; } @@ -1699,7 +2029,11 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp if (!begins_with(link->url_, "start://")) { return Status::Error(400, "Unsupported link URL specified"); } - start_parameter = PSTRING() << '=' << Slice(link->url_).substr(8); + auto start_parameter_slice = Slice(link->url_).substr(8); + if (start_parameter_slice.empty() || !is_valid_start_parameter(start_parameter_slice)) { + return Status::Error(400, "Invalid start parameter specified"); + } + start_parameter = PSTRING() << '=' << start_parameter_slice; } if (link->target_chat_ == nullptr) { return Status::Error(400, "Target chat must be non-empty"); @@ -1748,20 +2082,32 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp if (target->link_->get_id() == td_api::internalLinkTypeUserPhoneNumber::ID) { auto user_phone_number_link = static_cast(target->link_.get()); - if (!is_valid_phone_number(user_phone_number_link->phone_number_)) { + if (user_phone_number_link->open_profile_) { + return Status::Error(400, "Link must not open chat profile information screen"); + } + string phone_number; + if (user_phone_number_link->phone_number_[0] == '+') { + phone_number = user_phone_number_link->phone_number_.substr(1); + } else { + phone_number = user_phone_number_link->phone_number_; + } + if (!is_valid_phone_number(phone_number)) { return Status::Error(400, "Invalid target phone number specified"); } if (is_internal) { - return PSTRING() << "tg://resolve?phone=" << user_phone_number_link->phone_number_ - << "&attach=" << link->bot_username_ << start_parameter; + return PSTRING() << "tg://resolve?phone=+" << phone_number << "&attach=" << link->bot_username_ + << start_parameter; } else { - return PSTRING() << get_t_me_url() << '+' << user_phone_number_link->phone_number_ - << "?attach=" << link->bot_username_ << start_parameter; + return PSTRING() << get_t_me_url() << '+' << phone_number << "?attach=" << link->bot_username_ + << start_parameter; } } return Status::Error(400, "Unsupported target link specified"); } auto public_chat_link = static_cast(target->link_.get()); + if (public_chat_link->open_profile_) { + return Status::Error(400, "Link must not open chat profile information screen"); + } if (!is_valid_username(public_chat_link->chat_username_)) { return Status::Error(400, "Invalid target public chat username specified"); } @@ -1863,11 +2209,44 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp return PSTRING() << get_t_me_url() << link->bot_username_ << "?startgroup" << start_parameter << admin; } } + case td_api::internalLinkTypeBusinessChat::ID: { + auto link = static_cast(type_ptr); + if (is_internal) { + return PSTRING() << "tg://message?slug=" << url_encode(link->link_name_); + } else { + return PSTRING() << get_t_me_url() << "m/" << url_encode(link->link_name_); + } + } + case td_api::internalLinkTypeBuyStars::ID: { + auto link = static_cast(type_ptr); + if (!is_internal) { + return Status::Error("HTTP link is unavailable for the link type"); + } + if (link->star_count_ <= 0) { + return Status::Error(400, "Invalid Telegram Star number provided"); + } + return PSTRING() << "tg://stars_topup?balance=" << link->star_count_ << "&purpose=" << url_encode(link->purpose_); + } case td_api::internalLinkTypeChangePhoneNumber::ID: if (!is_internal) { return Status::Error("HTTP link is unavailable for the link type"); } return "tg://settings/change_number"; + case td_api::internalLinkTypeChatBoost::ID: { + auto link = static_cast(type_ptr); + auto parsed_link = parse_internal_link(link->url_); + if (parsed_link == nullptr) { + return Status::Error(400, "Invalid chat boost URL specified"); + } + auto parsed_object = parsed_link->get_internal_link_type_object(); + if (parsed_object->get_id() != td_api::internalLinkTypeChatBoost::ID) { + return Status::Error(400, "Invalid chat boost URL specified"); + } + if (!is_internal) { + return Status::Error(400, "Use getChatBoostLink to get an HTTPS link to boost a chat"); + } + return std::move(static_cast(*parsed_object).url_); + } case td_api::internalLinkTypeChatFolderInvite::ID: { auto link = static_cast(type_ptr); auto slug = get_dialog_filter_invite_link_slug(link->invite_link_); @@ -1876,6 +2255,11 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp } return get_dialog_filter_invite_link(slug, is_internal); } + case td_api::internalLinkTypeChatFolderSettings::ID: + if (!is_internal) { + return Status::Error("HTTP link is unavailable for the link type"); + } + return "tg://settings/folders"; case td_api::internalLinkTypeChatInvite::ID: { auto link = static_cast(type_ptr); auto invite_hash = get_dialog_invite_link_hash(link->invite_link_); @@ -1894,11 +2278,6 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp return Status::Error("HTTP link is unavailable for the link type"); } return "tg://settings/edit_profile"; - case td_api::internalLinkTypeChatFolderSettings::ID: - if (!is_internal) { - return Status::Error("HTTP link is unavailable for the link type"); - } - return "tg://settings/folders"; case td_api::internalLinkTypeGame::ID: { auto link = static_cast(type_ptr); if (!is_valid_username(link->bot_username_)) { @@ -1959,6 +2338,25 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp return Status::Error("HTTP link is unavailable for the link type"); } return "tg://settings/language"; + case td_api::internalLinkTypeMainWebApp::ID: { + auto link = static_cast(type_ptr); + if (!is_valid_username(link->bot_username_)) { + return Status::Error(400, "Invalid bot username specified"); + } + string start_parameter; + if (!link->start_parameter_.empty()) { + if (!is_valid_start_parameter(link->start_parameter_)) { + return Status::Error(400, "Invalid start parameter specified"); + } + start_parameter = PSTRING() << '=' << link->start_parameter_; + } + string mode = link->is_compact_ ? "&mode=compact" : ""; + if (is_internal) { + return PSTRING() << "tg://resolve?domain=" << link->bot_username_ << "&startapp" << start_parameter << mode; + } else { + return PSTRING() << get_t_me_url() << link->bot_username_ << "?startapp" << start_parameter << mode; + } + } case td_api::internalLinkTypeMessage::ID: { auto link = static_cast(type_ptr); auto parsed_link = parse_internal_link(link->url_); @@ -1970,7 +2368,7 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp return Status::Error(400, "Invalid message URL specified"); } if (!is_internal) { - return Status::Error(400, "Use getMessageLink to get HTTPS link to a message"); + return Status::Error(400, "Use getMessageLink to get an HTTPS link to a message"); } return std::move(static_cast(*parsed_object).url_); } @@ -2025,6 +2423,21 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp } return PSTRING() << "tg://premium_offer?ref=" << url_encode(link->referrer_); } + case td_api::internalLinkTypePremiumGift::ID: { + auto link = static_cast(type_ptr); + if (!is_internal) { + return Status::Error("HTTP link is unavailable for the link type"); + } + return PSTRING() << "tg://premium_multigift?ref=" << url_encode(link->referrer_); + } + case td_api::internalLinkTypePremiumGiftCode::ID: { + auto link = static_cast(type_ptr); + if (is_internal) { + return PSTRING() << "tg://giftcode?slug=" << url_encode(link->code_); + } else { + return PSTRING() << get_t_me_url() << "giftcode/" << url_encode(link->code_); + } + } case td_api::internalLinkTypePrivacyAndSecuritySettings::ID: if (!is_internal) { return Status::Error("HTTP link is unavailable for the link type"); @@ -2040,7 +2453,10 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp if (!is_valid_username(link->chat_username_)) { return Status::Error(400, "Invalid chat username specified"); } - return get_public_dialog_link(link->chat_username_, is_internal); + if (!check_utf8(link->draft_text_)) { + return Status::Error(400, "Draft text must be encoded in UTF-8"); + } + return get_public_dialog_link(link->chat_username_, link->draft_text_, link->open_profile_, is_internal); } case td_api::internalLinkTypeQrCodeAuthentication::ID: return Status::Error("The link must never be generated client-side"); @@ -2067,6 +2483,20 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp << url_encode(link->sticker_set_name_); } } + case td_api::internalLinkTypeStory::ID: { + auto link = static_cast(type_ptr); + if (!is_valid_username(link->story_sender_username_)) { + return Status::Error(400, "Invalid story sender username specified"); + } + if (!StoryId(link->story_id_).is_server()) { + return Status::Error(400, "Invalid story identifier specified"); + } + if (is_internal) { + return PSTRING() << "tg://resolve?domain=" << link->story_sender_username_ << "&story=" << link->story_id_; + } else { + return PSTRING() << get_t_me_url() << link->story_sender_username_ << "/s/" << link->story_id_; + } + } case td_api::internalLinkTypeTheme::ID: { auto link = static_cast(type_ptr); if (link->theme_name_.empty()) { @@ -2106,13 +2536,26 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp } case td_api::internalLinkTypeUserPhoneNumber::ID: { auto link = static_cast(type_ptr); - if (!is_valid_phone_number(link->phone_number_)) { + string phone_number; + if (link->phone_number_[0] == '+') { + phone_number = link->phone_number_.substr(1); + } else { + phone_number = link->phone_number_; + } + if (!is_valid_phone_number(phone_number)) { return Status::Error(400, "Invalid phone number specified"); } + if (!check_utf8(link->draft_text_)) { + return Status::Error(400, "Draft text must be encoded in UTF-8"); + } if (is_internal) { - return PSTRING() << "tg://resolve?phone=" << link->phone_number_; + return PSTRING() << "tg://resolve?phone=+" << phone_number << (link->draft_text_.empty() ? "" : "&text=") + << url_encode(link->draft_text_) << (link->open_profile_ ? "&profile" : ""); } else { - return PSTRING() << get_t_me_url() << '+' << link->phone_number_; + bool has_draft = !link->draft_text_.empty(); + return PSTRING() << get_t_me_url() << '+' << phone_number << (has_draft ? "?text=" : "") + << url_encode(link->draft_text_) + << (link->open_profile_ ? (has_draft ? "&profile" : "?profile") : ""); } } case td_api::internalLinkTypeUserToken::ID: { @@ -2153,16 +2596,18 @@ Result LinkManager::get_internal_link_impl(const td_api::InternalLinkTyp if (!is_valid_start_parameter(link->start_parameter_)) { return Status::Error(400, "Invalid start parameter specified"); } - string start_parameter; + string parameters; if (!link->start_parameter_.empty()) { - start_parameter = PSTRING() << (is_internal ? '&' : '?') << "startapp=" << url_encode(link->start_parameter_); + parameters = PSTRING() << (is_internal ? '&' : '?') << "startapp=" << link->start_parameter_ + << (link->is_compact_ ? "&mode=compact" : ""); + } else if (link->is_compact_) { + parameters = PSTRING() << (is_internal ? '&' : '?') << "mode=compact"; } if (is_internal) { return PSTRING() << "tg://resolve?domain=" << link->bot_username_ << "&appname=" << link->web_app_short_name_ - << start_parameter; + << parameters; } else { - return PSTRING() << get_t_me_url() << link->bot_username_ << '/' << link->web_app_short_name_ - << start_parameter; + return PSTRING() << get_t_me_url() << link->bot_username_ << '/' << link->web_app_short_name_ << parameters; } } default: @@ -2193,6 +2638,10 @@ void LinkManager::update_autologin_domains(vector autologin_domains, vec } } +void LinkManager::get_recent_me_urls(const string &referrer, Promise> &&promise) { + td_->create_handler(std::move(promise))->send(referrer); +} + void LinkManager::get_deep_link_info(Slice link, Promise> &&promise) { Slice link_scheme("tg:"); if (begins_with(link, link_scheme)) { @@ -2210,6 +2659,11 @@ void LinkManager::get_deep_link_info(Slice link, Promise> &&promise) { + bool is_ton = false; + if (tolower_begins_with(link, "tonsite://")) { + link = link.substr(10); + is_ton = true; + } auto default_result = td_api::make_object(link, false); if (G()->close_flag()) { return promise.set_value(std::move(default_result)); @@ -2224,13 +2678,32 @@ void LinkManager::get_external_link_info(string &&link, Promise= 4u && to_lower(url.host_.substr(url.host_.size() - 4)) == ".ton")) { + auto ton_proxy_address = td_->option_manager_->get_option_string("ton_proxy_address"); + if (ton_proxy_address.empty()) { + return promise.set_value(std::move(default_result)); + } + url.protocol_ = HttpUrl::Protocol::Https; + string new_host; + for (auto c : url.host_) { + if (c == '.') { + new_host += "-d"; + } else if (c == '-') { + new_host += "-h"; + } else { + new_host += c; + } + } + url.host_ = PSTRING() << new_host << '.' << ton_proxy_address; + default_result->url_ = url.get_url(); + } bool skip_confirmation = td::contains(whitelisted_domains_, url.host_); default_result->skip_confirmation_ = skip_confirmation; if (!td::contains(autologin_domains_, url.host_)) { if (td::contains(url_auth_domains_, url.host_)) { - td_->create_handler(std::move(promise))->send(link, FullMessageId(), 0); + td_->create_handler(std::move(promise))->send(link, MessageFullId(), 0); return; } return promise.set_value(std::move(default_result)); @@ -2275,23 +2748,23 @@ void LinkManager::get_external_link_info(string &&link, Promise(url.get_url(), skip_confirmation)); } -void LinkManager::get_login_url_info(FullMessageId full_message_id, int64 button_id, +void LinkManager::get_login_url_info(MessageFullId message_full_id, int64 button_id, Promise> &&promise) { - TRY_RESULT_PROMISE(promise, url, td_->messages_manager_->get_login_button_url(full_message_id, button_id)); + TRY_RESULT_PROMISE(promise, url, td_->messages_manager_->get_login_button_url(message_full_id, button_id)); td_->create_handler(std::move(promise)) - ->send(std::move(url), full_message_id, narrow_cast(button_id)); + ->send(std::move(url), message_full_id, narrow_cast(button_id)); } -void LinkManager::get_login_url(FullMessageId full_message_id, int64 button_id, bool allow_write_access, +void LinkManager::get_login_url(MessageFullId message_full_id, int64 button_id, bool allow_write_access, Promise> &&promise) { - TRY_RESULT_PROMISE(promise, url, td_->messages_manager_->get_login_button_url(full_message_id, button_id)); + TRY_RESULT_PROMISE(promise, url, td_->messages_manager_->get_login_button_url(message_full_id, button_id)); td_->create_handler(std::move(promise)) - ->send(std::move(url), full_message_id, narrow_cast(button_id), allow_write_access); + ->send(std::move(url), message_full_id, narrow_cast(button_id), allow_write_access); } void LinkManager::get_link_login_url(const string &url, bool allow_write_access, Promise> &&promise) { - td_->create_handler(std::move(promise))->send(url, FullMessageId(), 0, allow_write_access); + td_->create_handler(std::move(promise))->send(url, MessageFullId(), 0, allow_write_access); } Result LinkManager::get_background_url(const string &name, @@ -2299,6 +2772,9 @@ Result LinkManager::get_background_url(const string &name, if (background_type == nullptr) { return Status::Error(400, "Type must be non-empty"); } + if (background_type->get_id() == td_api::backgroundTypeChatTheme::ID) { + return Status::Error(400, "Background has no link"); + } TRY_RESULT(type, BackgroundType::get_background_type(background_type.get(), 0)); auto url = PSTRING() << get_t_me_url() << "bg/"; auto link = type.get_link(); @@ -2314,6 +2790,30 @@ Result LinkManager::get_background_url(const string &name, return url; } +td_api::object_ptr LinkManager::get_background_type_object(const string &link, + bool is_pattern) { + auto parsed_link = parse_internal_link(link); + if (parsed_link == nullptr) { + return nullptr; + } + auto parsed_object = parsed_link->get_internal_link_type_object(); + if (parsed_object->get_id() != td_api::internalLinkTypeBackground::ID) { + return nullptr; + } + auto background_name = + std::move(static_cast(parsed_object.get())->background_name_); + if (!BackgroundType::is_background_name_local(background_name)) { + BackgroundType type(false, is_pattern, nullptr); + type.apply_parameters_from_link(background_name); + return type.get_background_type_object(); + } + auto r_background_type = BackgroundType::get_local_background_type(background_name); + if (r_background_type.is_error()) { + return nullptr; + } + return r_background_type.ok().get_background_type_object(); +} + string LinkManager::get_dialog_filter_invite_link_slug(Slice invite_link) { auto link_info = get_link_info(invite_link); if (link_info.type_ != LinkType::Tg && link_info.type_ != LinkType::TMe) { @@ -2395,11 +2895,13 @@ string LinkManager::get_instant_view_link(Slice url, Slice rhash) { return PSTRING() << get_t_me_url() << "iv?url=" << url_encode(url) << "&rhash=" << url_encode(rhash); } -string LinkManager::get_public_dialog_link(Slice username, bool is_internal) { +string LinkManager::get_public_dialog_link(Slice username, Slice draft_text, bool open_profile, bool is_internal) { if (is_internal) { - return PSTRING() << "tg://resolve?domain=" << url_encode(username); + return PSTRING() << "tg://resolve?domain=" << url_encode(username) << (draft_text.empty() ? "" : "&text=") + << url_encode(draft_text) << (open_profile ? "&profile" : ""); } else { - return PSTRING() << get_t_me_url() << url_encode(username); + return PSTRING() << get_t_me_url() << url_encode(username) << (draft_text.empty() ? "" : "?text=") + << url_encode(draft_text) << (open_profile ? (draft_text.empty() ? "?profile" : "&profile") : ""); } } @@ -2530,6 +3032,105 @@ Result LinkManager::get_link_custom_emoji_id(Slice url) { return Status::Error(400, "Custom emoji URL must have an emoji identifier"); } +Result LinkManager::get_dialog_boost_link_info(Slice url) { + if (url.empty()) { + return Status::Error("URL must be non-empty"); + } + auto link_info = get_link_info(url); + if (link_info.type_ != LinkType::Tg && link_info.type_ != LinkType::TMe) { + return Status::Error("Invalid chat boost link URL"); + } + url = link_info.query_; + + Slice username; + Slice channel_id_slice; + if (link_info.type_ == LinkType::Tg) { + // boost?domain=username + // boost?channel=123456789 + + if (!begins_with(url, "boost")) { + return Status::Error("Wrong chat boost link URL"); + } + url = url.substr(5); + + if (begins_with(url, "/")) { + url = url.substr(1); + } + if (!begins_with(url, "?")) { + return Status::Error("Wrong chat boost link URL"); + } + url = url.substr(1); + + auto args = full_split(url, '&'); + for (auto arg : args) { + auto key_value = split(arg, '='); + if (key_value.first == "domain") { + username = key_value.second; + } else if (key_value.first == "channel") { + channel_id_slice = key_value.second; + } + } + } else { + // /username?boost + // /c/123456789?boost + + CHECK(!url.empty() && url[0] == '/'); + url.remove_prefix(1); + + size_t username_end_pos = 0; + while (username_end_pos < url.size() && url[username_end_pos] != '/' && url[username_end_pos] != '?' && + url[username_end_pos] != '#') { + username_end_pos++; + } + username = url.substr(0, username_end_pos); + url = url.substr(username_end_pos); + if (!url.empty() && url[0] == '/') { + url = url.substr(1); + } + if (username == "c") { + username = Slice(); + size_t channel_id_end_pos = 0; + while (channel_id_end_pos < url.size() && url[channel_id_end_pos] != '/' && url[channel_id_end_pos] != '?' && + url[channel_id_end_pos] != '#') { + channel_id_end_pos++; + } + channel_id_slice = url.substr(0, channel_id_end_pos); + url = url.substr(channel_id_end_pos); + } + + bool is_boost = false; + auto query_pos = url.find('?'); + if (query_pos != Slice::npos) { + auto args = full_split(url.substr(query_pos + 1), '&'); + for (auto arg : args) { + auto key_value = split(arg, '='); + if (key_value.first == "boost") { + is_boost = true; + } + } + } + + if (!is_boost) { + return Status::Error("Wrong chat boost link URL"); + } + } + + ChannelId channel_id; + if (username.empty()) { + auto r_channel_id = to_integer_safe(channel_id_slice); + if (r_channel_id.is_error() || !ChannelId(r_channel_id.ok()).is_valid()) { + return Status::Error("Wrong channel ID"); + } + channel_id = ChannelId(r_channel_id.ok()); + } + + DialogBoostLinkInfo info; + info.username = username.str(); + info.channel_id = channel_id; + LOG(INFO) << "Have link to boost chat @" << info.username << '/' << channel_id.get(); + return std::move(info); +} + Result LinkManager::get_message_link_info(Slice url) { if (url.empty()) { return Status::Error("URL must be non-empty"); @@ -2729,7 +3330,7 @@ Result LinkManager::get_message_link_info(Slice url) { info.media_timestamp = is_media_timestamp_invalid ? 0 : media_timestamp; info.is_single = is_single; info.for_comment = for_comment; - LOG(INFO) << "Have link to " << info.message_id << " in chat @" << info.username << "/" << channel_id.get(); + LOG(INFO) << "Have link to " << info.message_id << " in chat @" << info.username << '/' << channel_id.get(); return std::move(info); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/LinkManager.h b/protocols/Telegram/tdlib/td/td/telegram/LinkManager.h index 0620815d94..ee477dd2cc 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/LinkManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/LinkManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,7 +7,8 @@ #pragma once #include "td/telegram/CustomEmojiId.h" -#include "td/telegram/FullMessageId.h" +#include "td/telegram/DialogBoostLinkInfo.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/MessageLinkInfo.h" #include "td/telegram/td_api.h" #include "td/telegram/UserId.h" @@ -67,14 +68,16 @@ class LinkManager final : public Actor { void update_autologin_domains(vector autologin_domains, vector url_auth_domains, vector whitelisted_domains); + void get_recent_me_urls(const string &referrer, Promise> &&promise); + void get_deep_link_info(Slice link, Promise> &&promise); void get_external_link_info(string &&link, Promise> &&promise); - void get_login_url_info(FullMessageId full_message_id, int64 button_id, + void get_login_url_info(MessageFullId message_full_id, int64 button_id, Promise> &&promise); - void get_login_url(FullMessageId full_message_id, int64 button_id, bool allow_write_access, + void get_login_url(MessageFullId message_full_id, int64 button_id, bool allow_write_access, Promise> &&promise); void get_link_login_url(const string &url, bool allow_write_access, @@ -83,6 +86,8 @@ class LinkManager final : public Actor { static Result get_background_url(const string &name, td_api::object_ptr background_type); + static td_api::object_ptr get_background_type_object(const string &link, bool is_pattern); + static string get_dialog_filter_invite_link_slug(Slice invite_link); static string get_dialog_filter_invite_link(Slice slug, bool is_internal); @@ -97,7 +102,7 @@ class LinkManager final : public Actor { static string get_instant_view_link(Slice url, Slice rhash); - static string get_public_dialog_link(Slice username, bool is_internal); + static string get_public_dialog_link(Slice username, Slice draft_text, bool open_profile, bool is_internal); static Result get_proxy_link(const Proxy &proxy, bool is_internal); @@ -107,6 +112,8 @@ class LinkManager final : public Actor { static Result get_link_custom_emoji_id(Slice url); + static Result get_dialog_boost_link_info(Slice url); + static Result get_message_link_info(Slice url); private: @@ -121,9 +128,12 @@ class LinkManager final : public Actor { class InternalLinkBotAddToChannel; class InternalLinkBotStart; class InternalLinkBotStartInGroup; + class InternalLinkBusinessChat; + class InternalLinkBuyStars; class InternalLinkChangePhoneNumber; class InternalLinkConfirmPhone; class InternalLinkDefaultMessageAutoDeleteTimerSettings; + class InternalLinkDialogBoost; class InternalLinkDialogFolderInvite; class InternalLinkDialogFolderSettings; class InternalLinkDialogInvite; @@ -133,10 +143,13 @@ class LinkManager final : public Actor { class InternalLinkInvoice; class InternalLinkLanguage; class InternalLinkLanguageSettings; + class InternalLinkMainWebApp; class InternalLinkMessage; class InternalLinkMessageDraft; class InternalLinkPassportDataRequest; class InternalLinkPremiumFeatures; + class InternalLinkPremiumGift; + class InternalLinkPremiumGiftCode; class InternalLinkPrivacyAndSecuritySettings; class InternalLinkProxy; class InternalLinkPublicDialog; @@ -144,6 +157,7 @@ class LinkManager final : public Actor { class InternalLinkRestorePurchases; class InternalLinkSettings; class InternalLinkStickerSet; + class InternalLinkStory; class InternalLinkTheme; class InternalLinkThemeSettings; class InternalLinkUnknownDeepLink; diff --git a/protocols/Telegram/tdlib/td/td/telegram/Location.cpp b/protocols/Telegram/tdlib/td/td/telegram/Location.cpp index 6d87ca1b1a..46061086dd 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Location.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/Location.cpp @@ -1,12 +1,16 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/Location.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/Td.h" + #include +#include namespace td { @@ -20,26 +24,28 @@ double Location::fix_accuracy(double accuracy) { return accuracy; } -void Location::init(double latitude, double longitude, double horizontal_accuracy, int64 access_hash) { +void Location::init(Td *td, double latitude, double longitude, double horizontal_accuracy, int64 access_hash) { if (std::isfinite(latitude) && std::isfinite(longitude) && std::abs(latitude) <= 90 && std::abs(longitude) <= 180) { is_empty_ = false; latitude_ = latitude; longitude_ = longitude; horizontal_accuracy_ = fix_accuracy(horizontal_accuracy); access_hash_ = access_hash; - G()->add_location_access_hash(latitude_, longitude_, access_hash_); + if (td != nullptr && !td->auth_manager_->is_bot()) { + G()->add_location_access_hash(latitude_, longitude_, access_hash_); + } } } -Location::Location(double latitude, double longitude, double horizontal_accuracy, int64 access_hash) { - init(latitude, longitude, horizontal_accuracy, access_hash); +Location::Location(Td *td, double latitude, double longitude, double horizontal_accuracy, int64 access_hash) { + init(td, latitude, longitude, horizontal_accuracy, access_hash); } Location::Location(const tl_object_ptr &geo_point) - : Location(geo_point->lat_, geo_point->long_, 0.0, 0) { + : Location(nullptr, geo_point->lat_, geo_point->long_, 0.0, 0) { } -Location::Location(const tl_object_ptr &geo_point_ptr) { +Location::Location(Td *td, const tl_object_ptr &geo_point_ptr) { if (geo_point_ptr == nullptr) { return; } @@ -48,7 +54,7 @@ Location::Location(const tl_object_ptr &geo_point_ptr) { break; case telegram_api::geoPoint::ID: { auto geo_point = static_cast(geo_point_ptr.get()); - init(geo_point->lat_, geo_point->long_, geo_point->accuracy_radius_, geo_point->access_hash_); + init(td, geo_point->lat_, geo_point->long_, geo_point->accuracy_radius_, geo_point->access_hash_); break; } default: @@ -62,7 +68,7 @@ Location::Location(const tl_object_ptr &location) { return; } - init(location->latitude_, location->longitude_, location->horizontal_accuracy_, 0); + init(nullptr, location->latitude_, location->longitude_, location->horizontal_accuracy_, 0); } bool Location::empty() const { @@ -95,6 +101,19 @@ tl_object_ptr Location::get_input_geo_point() const static_cast(std::ceil(horizontal_accuracy_))); } +telegram_api::object_ptr Location::get_fake_geo_point() const { + if (empty()) { + return make_tl_object(); + } + + int32 flags = 0; + if (horizontal_accuracy_ > 0) { + flags |= telegram_api::geoPoint::ACCURACY_RADIUS_MASK; + } + return telegram_api::make_object(flags, longitude_, latitude_, 0, + static_cast(std::ceil(horizontal_accuracy_))); +} + tl_object_ptr Location::get_input_media_geo_point() const { return make_tl_object(get_input_geo_point()); } @@ -139,7 +158,8 @@ Result process_input_message_location( constexpr int32 MAX_LIVE_LOCATION_PERIOD = 86400; // seconds, server side limit auto period = input_location->live_period_; - if (period != 0 && (period < MIN_LIVE_LOCATION_PERIOD || period > MAX_LIVE_LOCATION_PERIOD)) { + if (period != 0 && period != std::numeric_limits::max() && + (period < MIN_LIVE_LOCATION_PERIOD || period > MAX_LIVE_LOCATION_PERIOD)) { return Status::Error(400, "Wrong live location period specified"); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/Location.h b/protocols/Telegram/tdlib/td/td/telegram/Location.h index 1e1fcad12a..7eb157696b 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Location.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Location.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -19,6 +19,8 @@ namespace td { +class Td; + class Location { bool is_empty_ = true; double latitude_ = 0.0; @@ -31,18 +33,18 @@ class Location { friend StringBuilder &operator<<(StringBuilder &string_builder, const Location &location); - void init(double latitude, double longitude, double horizontal_accuracy, int64 access_hash); + void init(Td *td, double latitude, double longitude, double horizontal_accuracy, int64 access_hash); static double fix_accuracy(double accuracy); public: Location() = default; - Location(double latitude, double longitude, double horizontal_accuracy, int64 access_hash); + Location(Td *td, double latitude, double longitude, double horizontal_accuracy, int64 access_hash); explicit Location(const tl_object_ptr &geo_point); - explicit Location(const tl_object_ptr &geo_point_ptr); + Location(Td *td, const tl_object_ptr &geo_point_ptr); explicit Location(const tl_object_ptr &location); @@ -54,6 +56,8 @@ class Location { tl_object_ptr get_input_geo_point() const; + telegram_api::object_ptr get_fake_geo_point() const; + tl_object_ptr get_input_media_geo_point() const; double get_latitude() const { diff --git a/protocols/Telegram/tdlib/td/td/telegram/LogDotNet.cpp b/protocols/Telegram/tdlib/td/td/telegram/LogDotNet.cpp deleted file mode 100644 index adf88dabbc..0000000000 --- a/protocols/Telegram/tdlib/td/td/telegram/LogDotNet.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// -#pragma managed(push, off) -#include "td/telegram/Log.h" -#pragma managed(pop) - -#include "td/utils/port/CxCli.h" - -#pragma managed(push, off) -#include -#pragma managed(pop) - -namespace Telegram { -namespace Td { - -using namespace CxCli; - -/// -/// Class for managing internal TDLib logging. -/// -[DEPRECATED_ATTRIBUTE("Telegram.Td.Log class is deprecated, please use Telegram.Td.Api.*Log* requests instead.")] -public ref class Log sealed { -public: - /// - /// Changes TDLib log verbosity. - /// - /// New value of log verbosity level. Must be non-negative. - /// Value 0 means FATAL, value 1 means ERROR, value 2 means WARNING, value 3 means INFO, value 4 means DEBUG, - /// value greater than 4 can be used to enable even more logging. - /// Default value of the log verbosity level is 5. - [DEPRECATED_ATTRIBUTE("SetVerbosityLevel is deprecated, please use Telegram.Td.Api.SetLogVerbosityLevel request instead.")] - static void SetVerbosityLevel(int verbosityLevel) { - ::td::Log::set_verbosity_level(verbosityLevel); - } - - /// - /// Sets file path for writing TDLib internal log. By default TDLib writes logs to the System.err. - /// Use this method to write the log to a file instead. - /// - /// Path to a file for writing TDLib internal log. Use an empty path to switch back to logging - /// to the System.err. - /// Returns whether opening the log file succeeded. - [DEPRECATED_ATTRIBUTE("SetFilePath is deprecated, please use Telegram.Td.Api.SetLogStream request instead.")] - static bool SetFilePath(String^ filePath) { - return ::td::Log::set_file_path(string_to_unmanaged(filePath)); - } - - /// - /// Changes the maximum size of TDLib log file. - /// - /// The maximum size of the file to where the internal TDLib log is written - /// before the file will be auto-rotated. Must be positive. Defaults to 10 MB. - [DEPRECATED_ATTRIBUTE("SetMaxFileSize is deprecated, please use Telegram.Td.Api.SetLogStream request instead.")] - static void SetMaxFileSize(std::int64_t maxFileSize) { - ::td::Log::set_max_file_size(maxFileSize); - } -}; - -} // namespace Td -} // namespace Telegram diff --git a/protocols/Telegram/tdlib/td/td/telegram/MediaArea.cpp b/protocols/Telegram/tdlib/td/td/telegram/MediaArea.cpp new file mode 100644 index 0000000000..c20fab1485 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MediaArea.cpp @@ -0,0 +1,388 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MediaArea.h" + +#include "td/telegram/ChannelId.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/InlineQueriesManager.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/misc.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/Td.h" + +#include "td/utils/emoji.h" +#include "td/utils/logging.h" + +#include + +namespace td { + +MediaArea::MediaArea(Td *td, telegram_api::object_ptr &&media_area_ptr) { + CHECK(media_area_ptr != nullptr); + switch (media_area_ptr->get_id()) { + case telegram_api::mediaAreaGeoPoint::ID: { + auto area = telegram_api::move_object_as(media_area_ptr); + coordinates_ = MediaAreaCoordinates(area->coordinates_); + location_ = Location(td, area->geo_); + if (area->address_ != nullptr) { + address_.country_iso2_ = area->address_->country_iso2_; + address_.state_ = area->address_->state_; + address_.city_ = area->address_->city_; + address_.street_ = area->address_->street_; + } + if (coordinates_.is_valid() && !location_.empty()) { + type_ = Type::Location; + } else { + LOG(ERROR) << "Receive " << to_string(area); + } + break; + } + case telegram_api::mediaAreaVenue::ID: { + auto area = telegram_api::move_object_as(media_area_ptr); + coordinates_ = MediaAreaCoordinates(area->coordinates_); + venue_ = Venue(td, area->geo_, std::move(area->title_), std::move(area->address_), std::move(area->provider_), + std::move(area->venue_id_), std::move(area->venue_type_)); + if (coordinates_.is_valid() && !venue_.empty()) { + type_ = Type::Venue; + } else { + LOG(ERROR) << "Receive " << to_string(area); + } + break; + } + case telegram_api::mediaAreaSuggestedReaction::ID: { + auto area = telegram_api::move_object_as(media_area_ptr); + coordinates_ = MediaAreaCoordinates(area->coordinates_); + reaction_type_ = ReactionType(area->reaction_); + is_dark_ = area->dark_; + is_flipped_ = area->flipped_; + if (coordinates_.is_valid() && !reaction_type_.is_empty() && !reaction_type_.is_paid_reaction()) { + type_ = Type::Reaction; + } else { + LOG(ERROR) << "Receive " << to_string(area); + } + break; + } + case telegram_api::mediaAreaChannelPost::ID: { + auto area = telegram_api::move_object_as(media_area_ptr); + coordinates_ = MediaAreaCoordinates(area->coordinates_); + auto channel_id = ChannelId(area->channel_id_); + auto server_message_id = ServerMessageId(area->msg_id_); + if (coordinates_.is_valid() && channel_id.is_valid() && server_message_id.is_valid()) { + type_ = Type::Message; + message_full_id_ = MessageFullId(DialogId(channel_id), MessageId(server_message_id)); + } else { + LOG(ERROR) << "Receive " << to_string(area); + } + break; + } + case telegram_api::mediaAreaUrl::ID: { + auto area = telegram_api::move_object_as(media_area_ptr); + coordinates_ = MediaAreaCoordinates(area->coordinates_); + if (coordinates_.is_valid()) { + type_ = Type::Url; + url_ = std::move(area->url_); + } else { + LOG(ERROR) << "Receive " << to_string(area); + } + break; + } + case telegram_api::mediaAreaWeather::ID: { + auto area = telegram_api::move_object_as(media_area_ptr); + coordinates_ = MediaAreaCoordinates(area->coordinates_); + if (coordinates_.is_valid() && is_emoji(area->emoji_) && std::isfinite(area->temperature_c_)) { + type_ = Type::Weather; + url_ = std::move(area->emoji_); + temperature_ = area->temperature_c_; + color_ = area->color_; + } else { + LOG(ERROR) << "Receive " << to_string(area); + } + break; + } + case telegram_api::inputMediaAreaVenue::ID: + LOG(ERROR) << "Receive " << to_string(media_area_ptr); + break; + case telegram_api::inputMediaAreaChannelPost::ID: + LOG(ERROR) << "Receive " << to_string(media_area_ptr); + break; + default: + UNREACHABLE(); + } +} + +MediaArea::MediaArea(Td *td, td_api::object_ptr &&input_story_area, + const vector &old_media_areas) { + if (input_story_area == nullptr || input_story_area->position_ == nullptr || input_story_area->type_ == nullptr) { + return; + } + coordinates_ = MediaAreaCoordinates(input_story_area->position_); + if (!coordinates_.is_valid()) { + return; + } + switch (input_story_area->type_->get_id()) { + case td_api::inputStoryAreaTypeLocation::ID: { + auto type = td_api::move_object_as(input_story_area->type_); + location_ = Location(type->location_); + if (type->address_ != nullptr) { + address_.country_iso2_ = std::move(type->address_->country_code_); + address_.state_ = std::move(type->address_->state_); + address_.city_ = std::move(type->address_->city_); + address_.street_ = std::move(type->address_->street_); + if (!clean_input_string(address_.country_iso2_) || !clean_input_string(address_.state_) || + !clean_input_string(address_.city_) || !clean_input_string(address_.street_)) { + break; + } + } + if (!location_.empty()) { + type_ = Type::Location; + } + break; + } + case td_api::inputStoryAreaTypeFoundVenue::ID: { + auto type = td_api::move_object_as(input_story_area->type_); + const InlineMessageContent *inline_message_content = + td->inline_queries_manager_->get_inline_message_content(type->query_id_, type->result_id_); + if (inline_message_content == nullptr || inline_message_content->message_content == nullptr) { + break; + } + auto venue_ptr = get_message_content_venue(inline_message_content->message_content.get()); + if (venue_ptr == nullptr || venue_ptr->empty()) { + break; + } + venue_ = *venue_ptr; + input_query_id_ = type->query_id_; + input_result_id_ = std::move(type->result_id_); + type_ = Type::Venue; + break; + } + case td_api::inputStoryAreaTypePreviousVenue::ID: { + auto type = td_api::move_object_as(input_story_area->type_); + for (auto &old_media_area : old_media_areas) { + if (old_media_area.type_ == Type::Venue && !old_media_area.venue_.empty() && + old_media_area.venue_.is_same(type->venue_provider_, type->venue_id_)) { + venue_ = old_media_area.venue_; + input_query_id_ = old_media_area.input_query_id_; + input_result_id_ = old_media_area.input_result_id_; + type_ = Type::Venue; + break; + } + } + break; + } + case td_api::inputStoryAreaTypeSuggestedReaction::ID: { + auto type = td_api::move_object_as(input_story_area->type_); + reaction_type_ = ReactionType(type->reaction_type_); + is_dark_ = type->is_dark_; + is_flipped_ = type->is_flipped_; + if (!reaction_type_.is_empty() && !reaction_type_.is_paid_reaction()) { + type_ = Type::Reaction; + } + break; + } + case td_api::inputStoryAreaTypeMessage::ID: { + auto type = td_api::move_object_as(input_story_area->type_); + auto dialog_id = DialogId(type->chat_id_); + auto message_id = MessageId(type->message_id_); + auto message_full_id = MessageFullId(dialog_id, message_id); + for (auto &old_media_area : old_media_areas) { + if (old_media_area.type_ == Type::Message && old_media_area.message_full_id_ == message_full_id) { + message_full_id_ = message_full_id; + is_old_message_ = true; + type_ = Type::Message; + break; + } + } + if (!is_old_message_) { + if (!td->messages_manager_->can_share_message_in_story(message_full_id)) { + break; + } + message_full_id_ = message_full_id; + type_ = Type::Message; + } + break; + } + case td_api::inputStoryAreaTypeLink::ID: { + auto type = td_api::move_object_as(input_story_area->type_); + if (!clean_input_string(type->url_)) { + break; + } + url_ = std::move(type->url_); + type_ = Type::Url; + break; + } + case td_api::inputStoryAreaTypeWeather::ID: { + auto type = td_api::move_object_as(input_story_area->type_); + if (!clean_input_string(type->emoji_) || !is_emoji(type->emoji_) || !std::isfinite(type->temperature_)) { + break; + } + url_ = std::move(type->emoji_); + temperature_ = type->temperature_; + color_ = type->background_color_; + type_ = Type::Weather; + break; + } + default: + UNREACHABLE(); + } +} + +bool MediaArea::has_reaction_type(const ReactionType &reaction_type) const { + return reaction_type_ == reaction_type; +} + +td_api::object_ptr MediaArea::get_story_area_object( + Td *td, const vector> &reaction_counts) const { + CHECK(is_valid()); + td_api::object_ptr type; + switch (type_) { + case Type::Location: + type = td_api::make_object( + location_.get_location_object(), + address_.is_empty() ? nullptr + : td_api::make_object(address_.country_iso2_, address_.state_, + address_.city_, address_.street_)); + break; + case Type::Venue: + type = td_api::make_object(venue_.get_venue_object()); + break; + case Type::Reaction: { + int32 total_count = 0; + for (const auto &reaction_count : reaction_counts) { + if (reaction_count.first == reaction_type_) { + total_count = reaction_count.second; + } + } + type = td_api::make_object(reaction_type_.get_reaction_type_object(), + total_count, is_dark_, is_flipped_); + break; + } + case Type::Message: + type = td_api::make_object( + td->dialog_manager_->get_chat_id_object(message_full_id_.get_dialog_id(), "storyAreaTypeMessage"), + message_full_id_.get_message_id().get()); + break; + case Type::Url: + type = td_api::make_object(url_); + break; + case Type::Weather: + type = td_api::make_object(temperature_, url_, color_); + break; + default: + UNREACHABLE(); + } + return td_api::make_object(coordinates_.get_story_area_position_object(), std::move(type)); +} + +telegram_api::object_ptr MediaArea::get_input_media_area(const Td *td) const { + CHECK(is_valid()); + switch (type_) { + case Type::Location: { + int32 flags = 0; + telegram_api::object_ptr address; + if (!address_.is_empty()) { + int32 address_flags = 0; + if (!address_.state_.empty()) { + address_flags |= telegram_api::geoPointAddress::STATE_MASK; + } + if (!address_.city_.empty()) { + address_flags |= telegram_api::geoPointAddress::CITY_MASK; + } + if (!address_.street_.empty()) { + address_flags |= telegram_api::geoPointAddress::STREET_MASK; + } + address = telegram_api::make_object( + address_flags, address_.country_iso2_, address_.state_, address_.city_, address_.street_); + flags |= telegram_api::mediaAreaGeoPoint::ADDRESS_MASK; + } + + return telegram_api::make_object( + flags, coordinates_.get_input_media_area_coordinates(), location_.get_fake_geo_point(), std::move(address)); + } + case Type::Venue: + if (input_query_id_ != 0) { + return telegram_api::make_object( + coordinates_.get_input_media_area_coordinates(), input_query_id_, input_result_id_); + } + return venue_.get_input_media_area_venue(coordinates_.get_input_media_area_coordinates()); + case Type::Reaction: { + int32 flags = 0; + if (is_dark_) { + flags |= telegram_api::mediaAreaSuggestedReaction::DARK_MASK; + } + if (is_flipped_) { + flags |= telegram_api::mediaAreaSuggestedReaction::FLIPPED_MASK; + } + return telegram_api::make_object( + flags, false /*ignored*/, false /*ignored*/, coordinates_.get_input_media_area_coordinates(), + reaction_type_.get_input_reaction()); + } + case Type::Message: { + auto channel_id = message_full_id_.get_dialog_id().get_channel_id(); + auto server_message_id = message_full_id_.get_message_id().get_server_message_id(); + if (!is_old_message_) { + auto input_channel = td->chat_manager_->get_input_channel(channel_id); + if (input_channel == nullptr) { + return nullptr; + } + return telegram_api::make_object( + coordinates_.get_input_media_area_coordinates(), std::move(input_channel), server_message_id.get()); + } + return telegram_api::make_object( + coordinates_.get_input_media_area_coordinates(), channel_id.get(), server_message_id.get()); + } + case Type::Url: + return telegram_api::make_object(coordinates_.get_input_media_area_coordinates(), + url_); + case Type::Weather: + return telegram_api::make_object(coordinates_.get_input_media_area_coordinates(), + url_, temperature_, color_); + default: + UNREACHABLE(); + return nullptr; + } +} + +vector> MediaArea::get_input_media_areas( + const Td *td, const vector &media_areas) { + vector> input_media_areas; + for (const auto &media_area : media_areas) { + auto input_media_area = media_area.get_input_media_area(td); + if (input_media_area != nullptr) { + input_media_areas.push_back(std::move(input_media_area)); + } + } + return input_media_areas; +} + +void MediaArea::add_dependencies(Dependencies &dependencies) const { + dependencies.add_dialog_and_dependencies(message_full_id_.get_dialog_id()); +} + +bool operator==(const MediaArea &lhs, const MediaArea &rhs) { + return lhs.type_ == rhs.type_ && lhs.coordinates_ == rhs.coordinates_ && lhs.location_ == rhs.location_ && + lhs.venue_ == rhs.venue_ && lhs.message_full_id_ == rhs.message_full_id_ && + lhs.input_query_id_ == rhs.input_query_id_ && lhs.input_result_id_ == rhs.input_result_id_ && + lhs.reaction_type_ == rhs.reaction_type_ && std::fabs(lhs.temperature_ - rhs.temperature_) < 1e-6 && + lhs.color_ == rhs.color_ && lhs.is_dark_ == rhs.is_dark_ && lhs.is_flipped_ == rhs.is_flipped_ && + lhs.is_old_message_ == rhs.is_old_message_; +} + +bool operator!=(const MediaArea &lhs, const MediaArea &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MediaArea &media_area) { + return string_builder << "StoryArea[" << media_area.coordinates_ << ": " << media_area.location_ << '/' + << media_area.venue_ << '/' << media_area.reaction_type_ << '/' << media_area.message_full_id_ + << '/' << media_area.temperature_ << ']'; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MediaArea.h b/protocols/Telegram/tdlib/td/td/telegram/MediaArea.h new file mode 100644 index 0000000000..ed56a900d2 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MediaArea.h @@ -0,0 +1,103 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/Location.h" +#include "td/telegram/MediaAreaCoordinates.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/ReactionType.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/Venue.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +#include + +namespace td { + +class Dependencies; +class Td; + +class MediaArea { + struct GeoPointAddress { + string country_iso2_; + string state_; + string city_; + string street_; + + bool is_empty() const { + return country_iso2_.empty(); + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + enum class Type : int32 { None, Location, Venue, Reaction, Message, Url, Weather }; + Type type_ = Type::None; + MediaAreaCoordinates coordinates_; + Location location_; + GeoPointAddress address_; + Venue venue_; + MessageFullId message_full_id_; + int64 input_query_id_ = 0; + string input_result_id_; + ReactionType reaction_type_; + string url_; + double temperature_ = 0.0; + int32 color_ = 0; + bool is_dark_ = false; + bool is_flipped_ = false; + bool is_old_message_ = false; + + friend bool operator==(const MediaArea &lhs, const MediaArea &rhs); + friend bool operator!=(const MediaArea &lhs, const MediaArea &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MediaArea &media_area); + + telegram_api::object_ptr get_input_media_area(const Td *td) const; + + public: + MediaArea() = default; + + MediaArea(Td *td, telegram_api::object_ptr &&media_area_ptr); + + MediaArea(Td *td, td_api::object_ptr &&input_story_area, + const vector &old_media_areas); + + bool has_reaction_type(const ReactionType &reaction_type) const; + + td_api::object_ptr get_story_area_object( + Td *td, const vector> &reaction_counts) const; + + static vector> get_input_media_areas( + const Td *td, const vector &media_areas); + + bool is_valid() const { + return type_ != Type::None; + } + + void add_dependencies(Dependencies &dependencies) const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const MediaArea &lhs, const MediaArea &rhs); +bool operator!=(const MediaArea &lhs, const MediaArea &rhs); + +StringBuilder &operator<<(StringBuilder &string_builder, const MediaArea &media_area); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MediaArea.hpp b/protocols/Telegram/tdlib/td/td/telegram/MediaArea.hpp new file mode 100644 index 0000000000..06ce1161bf --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MediaArea.hpp @@ -0,0 +1,162 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MediaArea.h" +#include "td/telegram/MediaAreaCoordinates.hpp" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void MediaArea::GeoPointAddress::store(StorerT &storer) const { + bool has_country_iso2 = !country_iso2_.empty(); + bool has_state = !state_.empty(); + bool has_city = !city_.empty(); + bool has_street = !street_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_country_iso2); + STORE_FLAG(has_state); + STORE_FLAG(has_city); + STORE_FLAG(has_street); + END_STORE_FLAGS(); + if (has_country_iso2) { + td::store(country_iso2_, storer); + } + if (has_state) { + td::store(state_, storer); + } + if (has_city) { + td::store(city_, storer); + } + if (has_street) { + td::store(street_, storer); + } +} + +template +void MediaArea::GeoPointAddress::parse(ParserT &parser) { + bool has_country_iso2; + bool has_state; + bool has_city; + bool has_street; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_country_iso2); + PARSE_FLAG(has_state); + PARSE_FLAG(has_city); + PARSE_FLAG(has_street); + END_PARSE_FLAGS(); + if (has_country_iso2) { + td::parse(country_iso2_, parser); + } + if (has_state) { + td::parse(state_, parser); + } + if (has_city) { + td::parse(city_, parser); + } + if (has_street) { + td::parse(street_, parser); + } +} + +template +void MediaArea::store(StorerT &storer) const { + using td::store; + bool has_input_query_id = input_query_id_ != 0; + bool has_address = !address_.is_empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_input_query_id); + STORE_FLAG(is_dark_); + STORE_FLAG(is_flipped_); + STORE_FLAG(is_old_message_); + STORE_FLAG(has_address); + END_STORE_FLAGS(); + store(type_, storer); + store(coordinates_, storer); + switch (type_) { + case Type::Location: + store(location_, storer); + break; + case Type::Venue: + store(venue_, storer); + if (has_input_query_id) { + store(input_query_id_, storer); + store(input_result_id_, storer); + } + break; + case Type::Reaction: + store(reaction_type_, storer); + break; + case Type::Message: + store(message_full_id_, storer); + break; + case Type::Url: + store(url_, storer); + break; + case Type::Weather: + store(temperature_, storer); + store(url_, storer); + store(color_, storer); + break; + default: + UNREACHABLE(); + } + if (has_address) { + store(address_, storer); + } +} + +template +void MediaArea::parse(ParserT &parser) { + using td::parse; + bool has_input_query_id; + bool has_address; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_input_query_id); + PARSE_FLAG(is_dark_); + PARSE_FLAG(is_flipped_); + PARSE_FLAG(is_old_message_); + PARSE_FLAG(has_address); + END_PARSE_FLAGS(); + parse(type_, parser); + parse(coordinates_, parser); + switch (type_) { + case Type::Location: + parse(location_, parser); + break; + case Type::Venue: + parse(venue_, parser); + if (has_input_query_id) { + parse(input_query_id_, parser); + parse(input_result_id_, parser); + } + break; + case Type::Reaction: + parse(reaction_type_, parser); + break; + case Type::Message: + parse(message_full_id_, parser); + break; + case Type::Url: + parse(url_, parser); + break; + case Type::Weather: + parse(temperature_, parser); + parse(url_, parser); + parse(color_, parser); + break; + default: + parser.set_error("Load invalid area type"); + } + if (has_address) { + parse(address_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.cpp b/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.cpp new file mode 100644 index 0000000000..0376d7ed66 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.cpp @@ -0,0 +1,84 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MediaAreaCoordinates.h" + +#include "td/utils/misc.h" + +#include + +namespace td { + +static double fix_double(double &value, double min_value = 0.0, double max_value = 100.0) { + if (!std::isfinite(value)) { + return 0.0; + } + return clamp(value, min_value, max_value); +} + +void MediaAreaCoordinates::init(double x, double y, double width, double height, double rotation_angle, double radius) { + x_ = fix_double(x); + y_ = fix_double(y); + width_ = fix_double(width); + height_ = fix_double(height); + rotation_angle_ = fix_double(rotation_angle, -360.0, 360.0); + if (rotation_angle_ < 0) { + rotation_angle_ += 360.0; + } + radius_ = fix_double(radius); +} + +MediaAreaCoordinates::MediaAreaCoordinates( + const telegram_api::object_ptr &coordinates) { + if (coordinates == nullptr) { + return; + } + init(coordinates->x_, coordinates->y_, coordinates->w_, coordinates->h_, coordinates->rotation_, + coordinates->radius_); +} + +MediaAreaCoordinates::MediaAreaCoordinates(const td_api::object_ptr &position) { + if (position == nullptr) { + return; + } + + init(position->x_percentage_, position->y_percentage_, position->width_percentage_, position->height_percentage_, + position->rotation_angle_, position->corner_radius_percentage_); +} + +td_api::object_ptr MediaAreaCoordinates::get_story_area_position_object() const { + CHECK(is_valid()); + return td_api::make_object(x_, y_, width_, height_, rotation_angle_, radius_); +} + +telegram_api::object_ptr MediaAreaCoordinates::get_input_media_area_coordinates() + const { + CHECK(is_valid()); + int32 flags = 0; + if (radius_ > 0) { + flags |= telegram_api::mediaAreaCoordinates::RADIUS_MASK; + } + return telegram_api::make_object(flags, x_, y_, width_, height_, rotation_angle_, + radius_); +} + +bool operator==(const MediaAreaCoordinates &lhs, const MediaAreaCoordinates &rhs) { + return std::abs(lhs.x_ - rhs.x_) < 1e-6 && std::abs(lhs.y_ - rhs.y_) < 1e-6 && + std::abs(lhs.width_ - rhs.width_) < 1e-6 && std::abs(lhs.height_ - rhs.height_) < 1e-6 && + std::abs(lhs.rotation_angle_ - rhs.rotation_angle_) < 1e-6 && std::abs(lhs.radius_ - rhs.radius_) < 1e-6; +} + +bool operator!=(const MediaAreaCoordinates &lhs, const MediaAreaCoordinates &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MediaAreaCoordinates &coordinates) { + return string_builder << "StoryAreaPosition[" << coordinates.x_ << ", " << coordinates.y_ << ", " + << coordinates.width_ << ", " << coordinates.height_ << ", " << coordinates.rotation_angle_ + << ", " << coordinates.radius_ << ']'; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.h b/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.h new file mode 100644 index 0000000000..90a86e794c --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.h @@ -0,0 +1,59 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class MediaAreaCoordinates { + double x_ = 0.0; + double y_ = 0.0; + double width_ = 0.0; + double height_ = 0.0; + double rotation_angle_ = 0.0; + double radius_ = 0.0; + + friend bool operator==(const MediaAreaCoordinates &lhs, const MediaAreaCoordinates &rhs); + friend bool operator!=(const MediaAreaCoordinates &lhs, const MediaAreaCoordinates &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MediaAreaCoordinates &coordinates); + + void init(double x, double y, double width, double height, double rotation_angle, double radius); + + public: + MediaAreaCoordinates() = default; + + explicit MediaAreaCoordinates(const telegram_api::object_ptr &coordinates); + + explicit MediaAreaCoordinates(const td_api::object_ptr &position); + + td_api::object_ptr get_story_area_position_object() const; + + telegram_api::object_ptr get_input_media_area_coordinates() const; + + bool is_valid() const { + return width_ > 0.0 && height_ > 0.0; + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const MediaAreaCoordinates &lhs, const MediaAreaCoordinates &rhs); +bool operator!=(const MediaAreaCoordinates &lhs, const MediaAreaCoordinates &rhs); + +StringBuilder &operator<<(StringBuilder &string_builder, const MediaAreaCoordinates &coordinates); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.hpp b/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.hpp new file mode 100644 index 0000000000..6565fc0167 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MediaAreaCoordinates.hpp @@ -0,0 +1,56 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MediaAreaCoordinates.h" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void MediaAreaCoordinates::store(StorerT &storer) const { + using td::store; + bool has_radius = radius_ > 0.0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_radius); + END_STORE_FLAGS(); + store(x_, storer); + store(y_, storer); + store(width_, storer); + store(height_, storer); + store(rotation_angle_, storer); + if (has_radius) { + store(radius_, storer); + } +} + +template +void MediaAreaCoordinates::parse(ParserT &parser) { + using td::parse; + bool has_radius; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_radius); + END_PARSE_FLAGS(); + double x; + double y; + double width; + double height; + double rotation_angle; + double radius = 0.0; + parse(x, parser); + parse(y, parser); + parse(width, parser); + parse(height, parser); + parse(rotation_angle, parser); + if (has_radius) { + parse(radius, parser); + } + init(x, y, width, height, rotation_angle, radius); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageContent.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageContent.cpp index c56f5a4116..0577de8e75 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageContent.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageContent.cpp @@ -1,11 +1,12 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/MessageContent.h" +#include "td/telegram/AccessRights.h" #include "td/telegram/AnimationsManager.h" #include "td/telegram/AnimationsManager.hpp" #include "td/telegram/AudiosManager.h" @@ -14,12 +15,13 @@ #include "td/telegram/BackgroundInfo.hpp" #include "td/telegram/CallDiscardReason.h" #include "td/telegram/ChannelId.h" +#include "td/telegram/ChannelType.h" #include "td/telegram/ChatId.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/Contact.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/CustomEmojiId.h" #include "td/telegram/Dependencies.h" -#include "td/telegram/DialogAction.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/DialogParticipant.h" #include "td/telegram/Dimensions.h" #include "td/telegram/Document.h" @@ -37,6 +39,8 @@ #include "td/telegram/ForumTopicManager.h" #include "td/telegram/Game.h" #include "td/telegram/Game.hpp" +#include "td/telegram/GiveawayParameters.h" +#include "td/telegram/GiveawayParameters.hpp" #include "td/telegram/Global.h" #include "td/telegram/GroupCallManager.h" #include "td/telegram/HashtagHints.h" @@ -47,12 +51,11 @@ #include "td/telegram/Location.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/MessageEntity.hpp" +#include "td/telegram/MessageExtendedMedia.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessageSearchFilter.h" #include "td/telegram/MessageSender.h" -#include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" -#include "td/telegram/net/DcId.h" #include "td/telegram/OptionManager.h" #include "td/telegram/OrderInfo.h" #include "td/telegram/OrderInfo.hpp" @@ -60,20 +63,30 @@ #include "td/telegram/Photo.hpp" #include "td/telegram/PhotoFormat.h" #include "td/telegram/PhotoSize.h" -#include "td/telegram/PhotoSizeSource.h" #include "td/telegram/PollId.h" #include "td/telegram/PollId.hpp" #include "td/telegram/PollManager.h" +#include "td/telegram/RepliedMessageInfo.h" #include "td/telegram/secret_api.hpp" #include "td/telegram/SecureValue.h" #include "td/telegram/SecureValue.hpp" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/SharedDialog.h" +#include "td/telegram/SharedDialog.hpp" +#include "td/telegram/StarManager.h" #include "td/telegram/StickerFormat.h" #include "td/telegram/StickersManager.h" #include "td/telegram/StickersManager.hpp" #include "td/telegram/StickerType.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/StoryManager.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/TopDialogManager.h" +#include "td/telegram/TranscriptionManager.h" #include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" #include "td/telegram/Venue.h" #include "td/telegram/Version.h" #include "td/telegram/VideoNotesManager.h" @@ -104,6 +117,7 @@ #include "td/utils/utf8.h" #include +#include #include namespace td { @@ -112,9 +126,26 @@ class MessageText final : public MessageContent { public: FormattedText text; WebPageId web_page_id; + bool force_small_media = false; + bool force_large_media = false; + bool skip_web_page_confirmation = false; + string web_page_url; MessageText() = default; - MessageText(FormattedText text, WebPageId web_page_id) : text(std::move(text)), web_page_id(web_page_id) { + MessageText(FormattedText text, WebPageId web_page_id, bool force_small_media, bool force_large_media, + bool skip_web_page_confirmation, string web_page_url) + : text(std::move(text)) + , web_page_id(web_page_id) + , force_small_media(force_small_media) + , force_large_media(force_large_media) + , skip_web_page_confirmation(skip_web_page_confirmation) + , web_page_url(std::move(web_page_url)) { + if (this->web_page_url.empty()) { + this->force_small_media = false; + this->force_large_media = false; + } else if (this->force_large_media) { + this->force_small_media = false; + } } MessageContentType get_type() const final { @@ -473,7 +504,7 @@ class MessageChatSetTtl final : public MessageContent { class MessageUnsupported final : public MessageContent { public: - static constexpr int32 CURRENT_VERSION = 18; + static constexpr int32 CURRENT_VERSION = 36; int32 version = CURRENT_VERSION; MessageUnsupported() = default; @@ -873,11 +904,12 @@ class MessageWriteAccessAllowed final : public MessageContent { class MessageRequestedDialog final : public MessageContent { public: - DialogId dialog_id; + vector shared_dialog_ids; int32 button_id = 0; MessageRequestedDialog() = default; - MessageRequestedDialog(DialogId dialog_id, int32 button_id) : dialog_id(dialog_id), button_id(button_id) { + MessageRequestedDialog(vector &&shared_dialog_ids, int32 button_id) + : shared_dialog_ids(std::move(shared_dialog_ids)), button_id(button_id) { } MessageContentType get_type() const final { @@ -902,10 +934,11 @@ class MessageSetBackground final : public MessageContent { public: MessageId old_message_id; BackgroundInfo background_info; + bool for_both = false; MessageSetBackground() = default; - MessageSetBackground(MessageId old_message_id, BackgroundInfo background_info) - : old_message_id(old_message_id), background_info(std::move(background_info)) { + MessageSetBackground(MessageId old_message_id, BackgroundInfo background_info, bool for_both) + : old_message_id(old_message_id), background_info(std::move(background_info)), for_both(for_both) { } MessageContentType get_type() const final { @@ -913,6 +946,287 @@ class MessageSetBackground final : public MessageContent { } }; +class MessageStory final : public MessageContent { + public: + StoryFullId story_full_id; + bool via_mention = false; + + MessageStory() = default; + MessageStory(StoryFullId story_full_id, bool via_mention) : story_full_id(story_full_id), via_mention(via_mention) { + } + + MessageContentType get_type() const final { + return MessageContentType::Story; + } +}; + +class MessageWriteAccessAllowedByRequest final : public MessageContent { + public: + MessageContentType get_type() const final { + return MessageContentType::WriteAccessAllowedByRequest; + } +}; + +class MessageGiftCode final : public MessageContent { + public: + DialogId creator_dialog_id; + int32 months = 0; + string currency; + int64 amount = 0; + string crypto_currency; + int64 crypto_amount = 0; + bool via_giveaway = false; + bool is_unclaimed = false; + string code; + + MessageGiftCode() = default; + MessageGiftCode(DialogId creator_dialog_id, int32 months, string &¤cy, int64 amount, string &&crypto_currency, + int64 crypto_amount, bool via_giveaway, bool is_unclaimed, string &&code) + : creator_dialog_id(creator_dialog_id) + , months(months) + , currency(std::move(currency)) + , amount(amount) + , crypto_currency(std::move(crypto_currency)) + , crypto_amount(crypto_amount) + , via_giveaway(via_giveaway || is_unclaimed) + , is_unclaimed(is_unclaimed) + , code(std::move(code)) { + } + + MessageContentType get_type() const final { + return MessageContentType::GiftCode; + } +}; + +class MessageGiveaway final : public MessageContent { + public: + GiveawayParameters giveaway_parameters; + int32 quantity = 0; + int32 months = 0; + int64 star_count = 0; + + MessageGiveaway() = default; + MessageGiveaway(GiveawayParameters giveaway_parameters, int32 quantity, int32 months, int64 star_count) + : giveaway_parameters(std::move(giveaway_parameters)) + , quantity(quantity) + , months(months) + , star_count(star_count) { + } + + MessageContentType get_type() const final { + return MessageContentType::Giveaway; + } +}; + +class MessageGiveawayLaunch final : public MessageContent { + public: + int64 star_count = 0; + + MessageGiveawayLaunch() = default; + explicit MessageGiveawayLaunch(int64 star_count) : star_count(star_count) { + } + + MessageContentType get_type() const final { + return MessageContentType::GiveawayLaunch; + } +}; + +class MessageGiveawayResults final : public MessageContent { + public: + MessageId giveaway_message_id; + int32 winner_count = 0; + int32 unclaimed_count = 0; + bool is_star_giveaway = false; + + MessageGiveawayResults() = default; + MessageGiveawayResults(MessageId giveaway_message_id, int32 winner_count, int32 unclaimed_count, + bool is_star_giveaway) + : giveaway_message_id(giveaway_message_id) + , winner_count(winner_count) + , unclaimed_count(unclaimed_count) + , is_star_giveaway(is_star_giveaway) { + } + + MessageContentType get_type() const final { + return MessageContentType::GiveawayResults; + } +}; + +class MessageGiveawayWinners final : public MessageContent { + public: + MessageId giveaway_message_id; + ChannelId boosted_channel_id; + int32 additional_dialog_count = 0; + int32 month_count = 0; + int64 star_count = 0; + string prize_description; + int32 winners_selection_date = 0; + bool only_new_subscribers = false; + bool was_refunded = false; + int32 winner_count = 0; + int32 unclaimed_count = 0; + vector winner_user_ids; + + MessageGiveawayWinners() = default; + MessageGiveawayWinners(MessageId giveaway_message_id, ChannelId boosted_channel_id, int32 additional_dialog_count, + int32 month_count, int64 star_count, string &&prize_description, int32 winners_selection_date, + bool only_new_subscribers, bool was_refunded, int32 winner_count, int32 unclaimed_count, + vector &&winner_user_ids) + : giveaway_message_id(giveaway_message_id) + , boosted_channel_id(boosted_channel_id) + , additional_dialog_count(additional_dialog_count) + , month_count(month_count) + , star_count(star_count) + , prize_description(std::move(prize_description)) + , winners_selection_date(winners_selection_date) + , only_new_subscribers(only_new_subscribers) + , was_refunded(was_refunded) + , winner_count(winner_count) + , unclaimed_count(unclaimed_count) + , winner_user_ids(std::move(winner_user_ids)) { + } + + MessageContentType get_type() const final { + return MessageContentType::GiveawayWinners; + } +}; + +class MessageExpiredVideoNote final : public MessageContent { + public: + MessageExpiredVideoNote() = default; + + MessageContentType get_type() const final { + return MessageContentType::ExpiredVideoNote; + } +}; + +class MessageExpiredVoiceNote final : public MessageContent { + public: + MessageExpiredVoiceNote() = default; + + MessageContentType get_type() const final { + return MessageContentType::ExpiredVoiceNote; + } +}; + +class MessageBoostApply final : public MessageContent { + public: + int32 boost_count = 0; + + MessageBoostApply() = default; + explicit MessageBoostApply(int32 boost_count) : boost_count(boost_count) { + } + + MessageContentType get_type() const final { + return MessageContentType::BoostApply; + } +}; + +class MessageDialogShared final : public MessageContent { + public: + vector shared_dialogs; + int32 button_id = 0; + + MessageDialogShared() = default; + MessageDialogShared(vector &&shared_dialogs, int32 button_id) + : shared_dialogs(std::move(shared_dialogs)), button_id(button_id) { + } + + MessageContentType get_type() const final { + return MessageContentType::DialogShared; + } +}; + +class MessagePaidMedia final : public MessageContent { + public: + vector media; + FormattedText caption; + int64 star_count = 0; + string payload; + + MessagePaidMedia() = default; + MessagePaidMedia(vector &&media, FormattedText &&caption, int64 star_count, string payload) + : media(std::move(media)), caption(std::move(caption)), star_count(star_count), payload(std::move(payload)) { + } + + MessageContentType get_type() const final { + return MessageContentType::PaidMedia; + } +}; + +class MessagePaymentRefunded final : public MessageContent { + public: + DialogId dialog_id; + string currency; + int64 total_amount = 0; + string invoice_payload; + string telegram_payment_charge_id; + string provider_payment_charge_id; + + MessagePaymentRefunded() = default; + MessagePaymentRefunded(DialogId dialog_id, string currency, int64 total_amount, string invoice_payload, + string telegram_payment_charge_id, string provider_payment_charge_id) + : dialog_id(dialog_id) + , currency(std::move(currency)) + , total_amount(total_amount) + , invoice_payload(std::move(invoice_payload)) + , telegram_payment_charge_id(std::move(telegram_payment_charge_id)) + , provider_payment_charge_id(std::move(provider_payment_charge_id)) { + } + + MessageContentType get_type() const final { + return MessageContentType::PaymentRefunded; + } +}; + +class MessageGiftStars final : public MessageContent { + public: + string currency; + int64 amount = 0; + string crypto_currency; + int64 crypto_amount = 0; + int64 star_count = 0; + string transaction_id; + + MessageGiftStars() = default; + MessageGiftStars(string &¤cy, int64 amount, string &&crypto_currency, int64 crypto_amount, int64 star_count, + string &&transaction_id) + : currency(std::move(currency)) + , amount(amount) + , crypto_currency(std::move(crypto_currency)) + , crypto_amount(crypto_amount) + , star_count(star_count) + , transaction_id(std::move(transaction_id)) { + } + + MessageContentType get_type() const final { + return MessageContentType::GiftStars; + } +}; + +class MessagePrizeStars final : public MessageContent { + public: + int64 star_count = 0; + string transaction_id; + DialogId boosted_dialog_id; + MessageId giveaway_message_id; + bool is_unclaimed = false; + + MessagePrizeStars() = default; + MessagePrizeStars(int64 star_count, string &&transaction_id, DialogId boosted_dialog_id, + MessageId giveaway_message_id, bool is_unclaimed) + : star_count(star_count) + , transaction_id(std::move(transaction_id)) + , boosted_dialog_id(boosted_dialog_id) + , giveaway_message_id(giveaway_message_id) + , is_unclaimed(is_unclaimed) { + } + + MessageContentType get_type() const final { + return MessageContentType::PrizeStars; + } +}; + template static void store(const MessageContent *content, StorerT &storer) { CHECK(content != nullptr); @@ -993,8 +1307,22 @@ static void store(const MessageContent *content, StorerT &storer) { } case MessageContentType::Text: { const auto *m = static_cast(content); + bool has_web_page_id = m->web_page_id.is_valid(); + bool has_web_page_url = !m->web_page_url.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_web_page_id); + STORE_FLAG(m->force_small_media); + STORE_FLAG(m->force_large_media); + STORE_FLAG(has_web_page_url); + STORE_FLAG(m->skip_web_page_confirmation); + END_STORE_FLAGS(); store(m->text, storer); - store(m->web_page_id, storer); + if (has_web_page_id) { + store(m->web_page_id, storer); + } + if (has_web_page_url) { + store(m->web_page_url, storer); + } break; } case MessageContentType::Unsupported: { @@ -1284,7 +1612,15 @@ static void store(const MessageContent *content, StorerT &storer) { break; case MessageContentType::RequestedDialog: { const auto *m = static_cast(content); - store(m->dialog_id, storer); + bool has_one_shared_dialog = m->shared_dialog_ids.size() == 1; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_one_shared_dialog); + END_STORE_FLAGS(); + if (has_one_shared_dialog) { + store(m->shared_dialog_ids[0], storer); + } else { + store(m->shared_dialog_ids, storer); + } store(m->button_id, storer); break; } @@ -1298,6 +1634,7 @@ static void store(const MessageContent *content, StorerT &storer) { bool has_message_id = m->old_message_id.is_valid(); BEGIN_STORE_FLAGS(); STORE_FLAG(has_message_id); + STORE_FLAG(m->for_both); END_STORE_FLAGS(); if (has_message_id) { store(m->old_message_id, storer); @@ -1305,6 +1642,240 @@ static void store(const MessageContent *content, StorerT &storer) { store(m->background_info, storer); break; } + case MessageContentType::Story: { + const auto *m = static_cast(content); + BEGIN_STORE_FLAGS(); + STORE_FLAG(m->via_mention); + END_STORE_FLAGS(); + store(m->story_full_id, storer); + break; + } + case MessageContentType::WriteAccessAllowedByRequest: + break; + case MessageContentType::GiftCode: { + const auto *m = static_cast(content); + bool has_creator_dialog_id = m->creator_dialog_id.is_valid(); + bool has_currency = !m->currency.empty(); + bool has_amount = m->amount > 0; + bool has_crypto_currency = !m->crypto_currency.empty(); + bool has_crypto_amount = m->crypto_amount > 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(m->via_giveaway); + STORE_FLAG(has_creator_dialog_id); + STORE_FLAG(m->is_unclaimed); + STORE_FLAG(has_currency); + STORE_FLAG(has_amount); + STORE_FLAG(has_crypto_currency); + STORE_FLAG(has_crypto_amount); + END_STORE_FLAGS(); + if (has_creator_dialog_id) { + store(m->creator_dialog_id, storer); + } + store(m->months, storer); + store(m->code, storer); + if (has_currency) { + store(m->currency, storer); + } + if (has_amount) { + store(m->amount, storer); + } + if (has_crypto_currency) { + store(m->crypto_currency, storer); + } + if (has_crypto_amount) { + store(m->crypto_amount, storer); + } + break; + } + case MessageContentType::Giveaway: { + const auto *m = static_cast(content); + bool has_star_count = m->star_count != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_star_count); + END_STORE_FLAGS(); + store(m->giveaway_parameters, storer); + store(m->quantity, storer); + store(m->months, storer); + if (has_star_count) { + store(m->star_count, storer); + } + break; + } + case MessageContentType::GiveawayLaunch: { + const auto *m = static_cast(content); + bool has_star_count = m->star_count != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_star_count); + END_STORE_FLAGS(); + if (has_star_count) { + store(m->star_count, storer); + } + break; + } + case MessageContentType::GiveawayResults: { + const auto *m = static_cast(content); + bool has_winner_count = m->winner_count != 0; + bool has_unclaimed_count = m->unclaimed_count != 0; + bool has_giveaway_message_id = m->giveaway_message_id.is_valid(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_winner_count); + STORE_FLAG(has_unclaimed_count); + STORE_FLAG(has_giveaway_message_id); + STORE_FLAG(m->is_star_giveaway); + END_STORE_FLAGS(); + if (has_winner_count) { + store(m->winner_count, storer); + } + if (has_unclaimed_count) { + store(m->unclaimed_count, storer); + } + if (has_giveaway_message_id) { + store(m->giveaway_message_id, storer); + } + break; + } + case MessageContentType::GiveawayWinners: { + const auto *m = static_cast(content); + bool has_giveaway_message_id = m->giveaway_message_id.is_valid(); + bool has_boosted_channel_id = m->boosted_channel_id.is_valid(); + bool has_additional_dialog_count = m->additional_dialog_count != 0; + bool has_month_count = m->month_count != 0; + bool has_prize_description = !m->prize_description.empty(); + bool has_winners_selection_date = m->winners_selection_date != 0; + bool has_winner_count = m->winner_count != 0; + bool has_unclaimed_count = m->unclaimed_count != 0; + bool has_winner_user_ids = !m->winner_user_ids.empty(); + bool has_star_count = m->star_count != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(m->only_new_subscribers); + STORE_FLAG(m->was_refunded); + STORE_FLAG(has_giveaway_message_id); + STORE_FLAG(has_boosted_channel_id); + STORE_FLAG(has_additional_dialog_count); + STORE_FLAG(has_month_count); + STORE_FLAG(has_prize_description); + STORE_FLAG(has_winners_selection_date); + STORE_FLAG(has_winner_count); + STORE_FLAG(has_unclaimed_count); + STORE_FLAG(has_winner_user_ids); + STORE_FLAG(has_star_count); + END_STORE_FLAGS(); + if (has_giveaway_message_id) { + store(m->giveaway_message_id, storer); + } + if (has_boosted_channel_id) { + store(m->boosted_channel_id, storer); + } + if (has_additional_dialog_count) { + store(m->additional_dialog_count, storer); + } + if (has_month_count) { + store(m->month_count, storer); + } + if (has_prize_description) { + store(m->prize_description, storer); + } + if (has_winners_selection_date) { + store(m->winners_selection_date, storer); + } + if (has_winner_count) { + store(m->winner_count, storer); + } + if (has_unclaimed_count) { + store(m->unclaimed_count, storer); + } + if (has_winner_user_ids) { + store(m->winner_user_ids, storer); + } + if (has_star_count) { + store(m->star_count, storer); + } + break; + } + case MessageContentType::ExpiredVideoNote: + break; + case MessageContentType::ExpiredVoiceNote: + break; + case MessageContentType::BoostApply: { + const auto *m = static_cast(content); + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + store(m->boost_count, storer); + break; + } + case MessageContentType::DialogShared: { + const auto *m = static_cast(content); + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + store(m->shared_dialogs, storer); + store(m->button_id, storer); + break; + } + case MessageContentType::PaidMedia: { + const auto *m = static_cast(content); + bool has_caption = !m->caption.text.empty(); + bool has_payload = !m->payload.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_caption); + STORE_FLAG(has_payload); + END_STORE_FLAGS(); + store(m->media, storer); + if (has_caption) { + store(m->caption, storer); + } + store(m->star_count, storer); + if (has_payload) { + store(m->payload, storer); + } + break; + } + case MessageContentType::PaymentRefunded: { + const auto *m = static_cast(content); + bool has_invoice_payload = !m->invoice_payload.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_invoice_payload); + END_STORE_FLAGS(); + store(m->dialog_id, storer); + store(m->currency, storer); + store(m->total_amount, storer); + if (has_invoice_payload) { + store(m->invoice_payload, storer); + } + store(m->telegram_payment_charge_id, storer); + store(m->provider_payment_charge_id, storer); + break; + } + case MessageContentType::GiftStars: { + const auto *m = static_cast(content); + bool has_crypto_amount = !m->crypto_currency.empty(); + bool has_transaction_id = !m->transaction_id.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_crypto_amount); + STORE_FLAG(has_transaction_id); + END_STORE_FLAGS(); + store(m->currency, storer); + store(m->amount, storer); + store(m->star_count, storer); + if (has_crypto_amount) { + store(m->crypto_currency, storer); + store(m->crypto_amount, storer); + } + if (has_transaction_id) { + store(m->transaction_id, storer); + } + break; + } + case MessageContentType::PrizeStars: { + const auto *m = static_cast(content); + BEGIN_STORE_FLAGS(); + STORE_FLAG(m->is_unclaimed); + END_STORE_FLAGS(); + store(m->star_count, storer); + store(m->transaction_id, storer); + store(m->boosted_dialog_id, storer); + store(m->giveaway_message_id, storer); + break; + } default: UNREACHABLE(); } @@ -1433,8 +2004,24 @@ static void parse(unique_ptr &content, ParserT &parser) { } case MessageContentType::Text: { auto m = make_unique(); + bool has_web_page_id = true; + bool has_web_page_url = false; + if (parser.version() >= static_cast(Version::AddMessageTextFlags)) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_web_page_id); + PARSE_FLAG(m->force_small_media); + PARSE_FLAG(m->force_large_media); + PARSE_FLAG(has_web_page_url); + PARSE_FLAG(m->skip_web_page_confirmation); + END_PARSE_FLAGS(); + } parse(m->text, parser); - parse(m->web_page_id, parser); + if (has_web_page_id) { + parse(m->web_page_id, parser); + } + if (has_web_page_url) { + parse(m->web_page_url, parser); + } content = std::move(m); break; } @@ -1812,12 +2399,34 @@ static void parse(unique_ptr &content, ParserT &parser) { break; case MessageContentType::RequestedDialog: { auto m = make_unique(); - parse(m->dialog_id, parser); - parse(m->button_id, parser); - content = std::move(m); - break; - } - case MessageContentType::WebViewWriteAccessAllowed: { + bool has_one_shared_dialog = true; + if (parser.version() >= static_cast(Version::SupportMultipleSharedUsers)) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_one_shared_dialog); + END_PARSE_FLAGS(); + } + if (has_one_shared_dialog) { + DialogId dialog_id; + parse(dialog_id, parser); + m->shared_dialog_ids = {dialog_id}; + } else { + parse(m->shared_dialog_ids, parser); + if (m->shared_dialog_ids.size() > 1) { + for (auto dialog_id : m->shared_dialog_ids) { + if (dialog_id.get_type() != DialogType::User) { + is_bad = true; + } + } + } + } + if (m->shared_dialog_ids.empty() || !m->shared_dialog_ids[0].is_valid()) { + is_bad = true; + } + parse(m->button_id, parser); + content = std::move(m); + break; + } + case MessageContentType::WebViewWriteAccessAllowed: { auto m = make_unique(); parse(m->web_app, parser); content = std::move(m); @@ -1828,6 +2437,7 @@ static void parse(unique_ptr &content, ParserT &parser) { bool has_message_id; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_message_id); + PARSE_FLAG(m->for_both); END_PARSE_FLAGS(); if (has_message_id) { parse(m->old_message_id, parser); @@ -1836,8 +2446,285 @@ static void parse(unique_ptr &content, ParserT &parser) { content = std::move(m); break; } + case MessageContentType::Story: { + auto m = make_unique(); + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(m->via_mention); + END_PARSE_FLAGS(); + parse(m->story_full_id, parser); + if (!m->story_full_id.is_server()) { + is_bad = true; + } + content = std::move(m); + break; + } + case MessageContentType::WriteAccessAllowedByRequest: + content = make_unique(); + break; + case MessageContentType::GiftCode: { + auto m = make_unique(); + bool has_creator_dialog_id; + bool has_currency; + bool has_amount; + bool has_crypto_currency; + bool has_crypto_amount; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(m->via_giveaway); + PARSE_FLAG(has_creator_dialog_id); + PARSE_FLAG(m->is_unclaimed); + PARSE_FLAG(has_currency); + PARSE_FLAG(has_amount); + PARSE_FLAG(has_crypto_currency); + PARSE_FLAG(has_crypto_amount); + END_PARSE_FLAGS(); + if (has_creator_dialog_id) { + parse(m->creator_dialog_id, parser); + } + parse(m->months, parser); + parse(m->code, parser); + if (has_currency) { + parse(m->currency, parser); + } + if (has_amount) { + parse(m->amount, parser); + } + if (has_crypto_currency) { + parse(m->crypto_currency, parser); + } + if (has_crypto_amount) { + parse(m->crypto_amount, parser); + } + content = std::move(m); + break; + } + case MessageContentType::Giveaway: { + auto m = make_unique(); + bool has_star_count; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_star_count); + END_PARSE_FLAGS(); + parse(m->giveaway_parameters, parser); + parse(m->quantity, parser); + parse(m->months, parser); + if (has_star_count) { + parse(m->star_count, parser); + } + if (!m->giveaway_parameters.is_valid()) { + is_bad = true; + } + content = std::move(m); + break; + } + case MessageContentType::GiveawayLaunch: { + auto m = make_unique(); + bool has_star_count = false; + if (parser.version() >= static_cast(Version::SupportStarGiveaways)) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_star_count); + END_PARSE_FLAGS(); + } + if (has_star_count) { + parse(m->star_count, parser); + } + content = std::move(m); + break; + } + case MessageContentType::GiveawayResults: { + auto m = make_unique(); + bool has_winner_count; + bool has_unclaimed_count; + bool has_giveaway_message_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_winner_count); + PARSE_FLAG(has_unclaimed_count); + PARSE_FLAG(has_giveaway_message_id); + PARSE_FLAG(m->is_star_giveaway); + END_PARSE_FLAGS(); + if (has_winner_count) { + parse(m->winner_count, parser); + } + if (has_unclaimed_count) { + parse(m->unclaimed_count, parser); + } + if (has_giveaway_message_id) { + parse(m->giveaway_message_id, parser); + } + if (m->winner_count < 0 || m->unclaimed_count < 0) { + is_bad = true; + } + content = std::move(m); + break; + } + case MessageContentType::GiveawayWinners: { + auto m = make_unique(); + bool has_giveaway_message_id; + bool has_boosted_channel_id; + bool has_additional_dialog_count; + bool has_month_count; + bool has_prize_description; + bool has_winners_selection_date; + bool has_winner_count; + bool has_unclaimed_count; + bool has_winner_user_ids; + bool has_star_count; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(m->only_new_subscribers); + PARSE_FLAG(m->was_refunded); + PARSE_FLAG(has_giveaway_message_id); + PARSE_FLAG(has_boosted_channel_id); + PARSE_FLAG(has_additional_dialog_count); + PARSE_FLAG(has_month_count); + PARSE_FLAG(has_prize_description); + PARSE_FLAG(has_winners_selection_date); + PARSE_FLAG(has_winner_count); + PARSE_FLAG(has_unclaimed_count); + PARSE_FLAG(has_winner_user_ids); + PARSE_FLAG(has_star_count); + END_PARSE_FLAGS(); + if (has_giveaway_message_id) { + parse(m->giveaway_message_id, parser); + } + if (has_boosted_channel_id) { + parse(m->boosted_channel_id, parser); + } + if (has_additional_dialog_count) { + parse(m->additional_dialog_count, parser); + } + if (has_month_count) { + parse(m->month_count, parser); + } + if (has_prize_description) { + parse(m->prize_description, parser); + } + if (has_winners_selection_date) { + parse(m->winners_selection_date, parser); + } + if (has_winner_count) { + parse(m->winner_count, parser); + } + if (has_unclaimed_count) { + parse(m->unclaimed_count, parser); + } + if (has_winner_user_ids) { + parse(m->winner_user_ids, parser); + } + if (has_star_count) { + parse(m->star_count, parser); + } + if (m->winner_count < 0 || m->unclaimed_count < 0) { + is_bad = true; + } + content = std::move(m); + break; + } + case MessageContentType::ExpiredVideoNote: + content = make_unique(); + break; + case MessageContentType::ExpiredVoiceNote: + content = make_unique(); + break; + case MessageContentType::BoostApply: { + auto m = make_unique(); + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + parse(m->boost_count, parser); + if (m->boost_count < 0) { + is_bad = true; + } + content = std::move(m); + break; + } + case MessageContentType::DialogShared: { + auto m = make_unique(); + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + parse(m->shared_dialogs, parser); + if (m->shared_dialogs.empty() || + any_of(m->shared_dialogs, [](const auto &shared_dialog) { return !shared_dialog.is_valid(); })) { + is_bad = true; + } + parse(m->button_id, parser); + content = std::move(m); + break; + } + case MessageContentType::PaidMedia: { + auto m = make_unique(); + bool has_caption; + bool has_payload; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_caption); + PARSE_FLAG(has_payload); + END_PARSE_FLAGS(); + parse(m->media, parser); + if (has_caption) { + parse(m->caption, parser); + } + parse(m->star_count, parser); + if (has_payload) { + parse(m->payload, parser); + } + + for (auto &media : m->media) { + if (media.is_empty()) { + is_bad = true; + } + } + content = std::move(m); + break; + } + case MessageContentType::PaymentRefunded: { + auto m = make_unique(); + bool has_invoice_payload; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_invoice_payload); + END_PARSE_FLAGS(); + parse(m->dialog_id, parser); + parse(m->currency, parser); + parse(m->total_amount, parser); + if (has_invoice_payload) { + parse(m->invoice_payload, parser); + } + parse(m->telegram_payment_charge_id, parser); + parse(m->provider_payment_charge_id, parser); + content = std::move(m); + break; + } + case MessageContentType::GiftStars: { + auto m = make_unique(); + bool has_crypto_amount; + bool has_transaction_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_crypto_amount); + PARSE_FLAG(has_transaction_id); + END_PARSE_FLAGS(); + parse(m->currency, parser); + parse(m->amount, parser); + parse(m->star_count, parser); + if (has_crypto_amount) { + parse(m->crypto_currency, parser); + parse(m->crypto_amount, parser); + } + if (has_transaction_id) { + parse(m->transaction_id, parser); + } + content = std::move(m); + break; + } + case MessageContentType::PrizeStars: { + auto m = make_unique(); + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(m->is_unclaimed); + END_PARSE_FLAGS(); + parse(m->star_count, parser); + parse(m->transaction_id, parser); + parse(m->boosted_dialog_id, parser); + parse(m->giveaway_message_id, parser); + content = std::move(m); + break; + } + default: - LOG(FATAL) << "Have unknown message content type " << static_cast(content_type); + is_bad = true; } if (is_bad) { LOG(ERROR) << "Load a message with an invalid content of type " << content_type; @@ -1870,27 +2757,41 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, InlineMessageContent result; tl_object_ptr reply_markup; result.disable_web_page_preview = false; + result.invert_media = false; switch (bot_inline_message->get_id()) { case telegram_api::botInlineMessageText::ID: { auto inline_message = move_tl_object_as(bot_inline_message); - auto entities = get_message_entities(td->contacts_manager_.get(), std::move(inline_message->entities_), - "botInlineMessageText"); - auto status = fix_formatted_text(inline_message->message_, entities, false, true, true, false, false); - if (status.is_error()) { - LOG(ERROR) << "Receive error " << status << " while parsing botInlineMessageText " << inline_message->message_; - break; - } - + auto text = get_formatted_text(td->user_manager_.get(), std::move(inline_message->message_), + std::move(inline_message->entities_), false, false, "botInlineMessageText"); result.disable_web_page_preview = inline_message->no_webpage_; - FormattedText text{std::move(inline_message->message_), std::move(entities)}; + result.invert_media = inline_message->invert_media_; WebPageId web_page_id; if (!result.disable_web_page_preview) { - web_page_id = td->web_pages_manager_->get_web_page_by_url(get_first_url(text)); + web_page_id = td->web_pages_manager_->get_web_page_by_url(get_first_url(text).str()); } - result.message_content = make_unique(std::move(text), web_page_id); + result.message_content = + td::make_unique(std::move(text), web_page_id, false, false, false, string()); reply_markup = std::move(inline_message->reply_markup_); break; } + case telegram_api::botInlineMessageMediaWebPage::ID: { + auto inline_message = move_tl_object_as(bot_inline_message); + string web_page_url; + if (inline_message->manual_) { + web_page_url = std::move(inline_message->url_); + } + auto text = + get_formatted_text(td->user_manager_.get(), std::move(inline_message->message_), + std::move(inline_message->entities_), false, false, "botInlineMessageMediaWebPage"); + auto web_page_id = + td->web_pages_manager_->get_web_page_by_url(web_page_url.empty() ? get_first_url(text).str() : web_page_url); + result.message_content = td::make_unique( + std::move(text), web_page_id, inline_message->force_small_media_, inline_message->force_large_media_, + inline_message->safe_, std::move(web_page_url)); + reply_markup = std::move(inline_message->reply_markup_); + result.invert_media = inline_message->invert_media_; + break; + } case telegram_api::botInlineMessageMediaInvoice::ID: { auto inline_message = move_tl_object_as(bot_inline_message); reply_markup = std::move(inline_message->reply_markup_); @@ -1901,10 +2802,10 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, auto inline_message = move_tl_object_as(bot_inline_message); if (inline_message->period_ > 0) { result.message_content = - make_unique(Location(inline_message->geo_), inline_message->period_, + make_unique(Location(td, inline_message->geo_), inline_message->period_, inline_message->heading_, inline_message->proximity_notification_radius_); } else { - result.message_content = make_unique(Location(inline_message->geo_)); + result.message_content = make_unique(Location(td, inline_message->geo_)); } reply_markup = std::move(inline_message->reply_markup_); break; @@ -1912,7 +2813,7 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, case telegram_api::botInlineMessageMediaVenue::ID: { auto inline_message = move_tl_object_as(bot_inline_message); result.message_content = make_unique( - Venue(inline_message->geo_, std::move(inline_message->title_), std::move(inline_message->address_), + Venue(td, inline_message->geo_, std::move(inline_message->title_), std::move(inline_message->address_), std::move(inline_message->provider_), std::move(inline_message->venue_id_), std::move(inline_message->venue_type_))); reply_markup = std::move(inline_message->reply_markup_); @@ -1929,7 +2830,7 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, case telegram_api::botInlineMessageMediaAuto::ID: { auto inline_message = move_tl_object_as(bot_inline_message); auto caption = - get_message_text(td->contacts_manager_.get(), inline_message->message_, std::move(inline_message->entities_), + get_message_text(td->user_manager_.get(), inline_message->message_, std::move(inline_message->entities_), true, false, 0, false, "create_inline_message_content"); if (allowed_media_content_id == td_api::inputMessageAnimation::ID) { result.message_content = make_unique(file_id, std::move(caption), false); @@ -1953,6 +2854,7 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, LOG(WARNING) << "Unallowed bot inline message " << to_string(inline_message); } + result.invert_media = inline_message->invert_media_; reply_markup = std::move(inline_message->reply_markup_); break; } @@ -1964,8 +2866,19 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, } unique_ptr create_text_message_content(string text, vector entities, - WebPageId web_page_id) { - return make_unique(FormattedText{std::move(text), std::move(entities)}, web_page_id); + WebPageId web_page_id, bool force_small_media, + bool force_large_media, bool skip_confirmation, + string &&web_page_url) { + return td::make_unique(FormattedText{std::move(text), std::move(entities)}, web_page_id, + force_small_media, force_large_media, skip_confirmation, std::move(web_page_url)); +} + +unique_ptr create_photo_message_content(Photo photo) { + return make_unique(std::move(photo), FormattedText(), false); +} + +unique_ptr create_video_message_content(FileId file_id) { + return make_unique(file_id, FormattedText(), false); } unique_ptr create_contact_registered_message_content() { @@ -1980,6 +2893,65 @@ unique_ptr create_chat_set_ttl_message_content(int32 ttl, UserId return make_unique(ttl, from_user_id); } +td_api::object_ptr extract_input_caption( + td_api::object_ptr &input_message_content) { + switch (input_message_content->get_id()) { + case td_api::inputMessageAnimation::ID: { + auto input_animation = static_cast(input_message_content.get()); + return std::move(input_animation->caption_); + } + case td_api::inputMessageAudio::ID: { + auto input_audio = static_cast(input_message_content.get()); + return std::move(input_audio->caption_); + } + case td_api::inputMessageDocument::ID: { + auto input_document = static_cast(input_message_content.get()); + return std::move(input_document->caption_); + } + case td_api::inputMessagePaidMedia::ID: { + auto input_paid_media = static_cast(input_message_content.get()); + return std::move(input_paid_media->caption_); + } + case td_api::inputMessagePhoto::ID: { + auto input_photo = static_cast(input_message_content.get()); + return std::move(input_photo->caption_); + } + case td_api::inputMessageVideo::ID: { + auto input_video = static_cast(input_message_content.get()); + return std::move(input_video->caption_); + } + case td_api::inputMessageVoiceNote::ID: { + auto input_voice_note = static_cast(input_message_content.get()); + return std::move(input_voice_note->caption_); + } + default: + return nullptr; + } +} + +bool extract_input_invert_media(const td_api::object_ptr &input_message_content) { + switch (input_message_content->get_id()) { + case td_api::inputMessageAnimation::ID: { + auto input_animation = static_cast(input_message_content.get()); + return input_animation->show_caption_above_media_; + } + case td_api::inputMessagePaidMedia::ID: { + auto input_paid_media = static_cast(input_message_content.get()); + return input_paid_media->show_caption_above_media_; + } + case td_api::inputMessagePhoto::ID: { + auto input_photo = static_cast(input_message_content.get()); + return input_photo->show_caption_above_media_; + } + case td_api::inputMessageVideo::ID: { + auto input_video = static_cast(input_message_content.get()); + return input_video->show_caption_above_media_; + } + default: + return false; + } +} + static Result create_input_message_content( DialogId dialog_id, tl_object_ptr &&input_message_content, Td *td, FormattedText caption, FileId file_id, PhotoSize thumbnail, vector sticker_file_ids, bool is_premium) { @@ -1998,10 +2970,11 @@ static Result create_input_message_content( } bool disable_web_page_preview = false; + bool invert_media = false; bool clear_draft = false; unique_ptr content; UserId via_bot_user_id; - int32 ttl = 0; + td_api::object_ptr self_destruct_type; string emoji; bool is_bot = td->auth_manager_->is_bot(); bool is_secret = dialog_id.get_type() == DialogType::SecretChat; @@ -2009,7 +2982,9 @@ static Result create_input_message_content( case td_api::inputMessageText::ID: { TRY_RESULT(input_message_text, process_input_message_text(td, dialog_id, std::move(input_message_content), is_bot)); + auto web_page_url = std::move(input_message_text.web_page_url); disable_web_page_preview = input_message_text.disable_web_page_preview; + invert_media = input_message_text.show_above_text; clear_draft = input_message_text.clear_draft; if (is_bot && static_cast(utf8_length(input_message_text.text.text)) > @@ -2020,19 +2995,24 @@ static Result create_input_message_content( WebPageId web_page_id; bool can_add_web_page_previews = dialog_id.get_type() != DialogType::Channel || - td->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()).can_add_web_page_previews(); + td->chat_manager_->get_channel_permissions(dialog_id.get_channel_id()).can_add_web_page_previews(); if (!is_bot && !disable_web_page_preview && can_add_web_page_previews) { - web_page_id = td->web_pages_manager_->get_web_page_by_url(get_first_url(input_message_text.text)); + web_page_id = td->web_pages_manager_->get_web_page_by_url( + web_page_url.empty() ? get_first_url(input_message_text.text).str() : web_page_url); } - content = make_unique(std::move(input_message_text.text), web_page_id); + content = td::make_unique(std::move(input_message_text.text), web_page_id, + input_message_text.force_small_media, input_message_text.force_large_media, + false, std::move(web_page_url)); break; } case td_api::inputMessageAnimation::ID: { auto input_animation = static_cast(input_message_content.get()); + invert_media = input_animation->show_caption_above_media_ && !is_secret; + bool has_stickers = !sticker_file_ids.empty(); td->animations_manager_->create_animation( - file_id, string(), thumbnail, AnimationSize(), has_stickers, std::move(sticker_file_ids), + file_id, string(), std::move(thumbnail), AnimationSize(), has_stickers, std::move(sticker_file_ids), std::move(file_name), std::move(mime_type), input_animation->duration_, get_dimensions(input_animation->width_, input_animation->height_, nullptr), false); @@ -2049,8 +3029,8 @@ static Result create_input_message_content( return Status::Error(400, "Audio performer must be encoded in UTF-8"); } - td->audios_manager_->create_audio(file_id, string(), thumbnail, std::move(file_name), std::move(mime_type), - input_audio->duration_, std::move(input_audio->title_), + td->audios_manager_->create_audio(file_id, string(), std::move(thumbnail), std::move(file_name), + std::move(mime_type), input_audio->duration_, std::move(input_audio->title_), std::move(input_audio->performer_), 0, false); content = make_unique(file_id, std::move(caption)); @@ -2066,15 +3046,43 @@ static Result create_input_message_content( break; } case td_api::inputMessageDocument::ID: - td->documents_manager_->create_document(file_id, string(), thumbnail, std::move(file_name), std::move(mime_type), - false); + td->documents_manager_->create_document(file_id, string(), std::move(thumbnail), std::move(file_name), + std::move(mime_type), false); content = make_unique(file_id, std::move(caption)); break; + case td_api::inputMessagePaidMedia::ID: { + auto input_paid_media = static_cast(input_message_content.get()); + + invert_media = input_paid_media->show_caption_above_media_ && !is_secret; + + if (input_paid_media->star_count_ <= 0 || + input_paid_media->star_count_ > + td->option_manager_->get_option_integer("paid_media_message_star_count_max")) { + return Status::Error(400, "Invalid media price specified"); + } + vector extended_media; + for (auto &paid_media : input_paid_media->paid_media_) { + TRY_RESULT(media, MessageExtendedMedia::get_message_extended_media(td, std::move(paid_media), dialog_id)); + if (media.is_empty()) { + return Status::Error(400, "Paid media must be non-empty"); + } + extended_media.push_back(std::move(media)); + } + static constexpr size_t MAX_PAID_MEDIA = 10; // server side limit + if (extended_media.empty() || extended_media.size() > MAX_PAID_MEDIA) { + return Status::Error(400, "Invalid number of paid media specified"); + } + + content = td::make_unique(std::move(extended_media), std::move(caption), + input_paid_media->star_count_, std::move(input_paid_media->payload_)); + break; + } case td_api::inputMessagePhoto::ID: { auto input_photo = static_cast(input_message_content.get()); - ttl = input_photo->self_destruct_time_; + invert_media = input_photo->show_caption_above_media_ && !is_secret; + self_destruct_type = std::move(input_photo->self_destruct_type_); TRY_RESULT(photo, create_photo(td->file_manager_.get(), file_id, std::move(thumbnail), input_photo->width_, input_photo->height_, std::move(sticker_file_ids))); @@ -2088,7 +3096,7 @@ static Result create_input_message_content( emoji = std::move(input_sticker->emoji_); - td->stickers_manager_->create_sticker(file_id, FileId(), string(), thumbnail, + td->stickers_manager_->create_sticker(file_id, FileId(), string(), std::move(thumbnail), get_dimensions(input_sticker->width_, input_sticker->height_, nullptr), nullptr, nullptr, StickerFormat::Unknown, nullptr); @@ -2098,26 +3106,29 @@ static Result create_input_message_content( case td_api::inputMessageVideo::ID: { auto input_video = static_cast(input_message_content.get()); - ttl = input_video->self_destruct_time_; + invert_media = input_video->show_caption_above_media_ && !is_secret; + self_destruct_type = std::move(input_video->self_destruct_type_); bool has_stickers = !sticker_file_ids.empty(); - td->videos_manager_->create_video( - file_id, string(), thumbnail, AnimationSize(), has_stickers, std::move(sticker_file_ids), - std::move(file_name), std::move(mime_type), input_video->duration_, - get_dimensions(input_video->width_, input_video->height_, nullptr), input_video->supports_streaming_, false); + td->videos_manager_->create_video(file_id, string(), std::move(thumbnail), AnimationSize(), has_stickers, + std::move(sticker_file_ids), std::move(file_name), std::move(mime_type), + input_video->duration_, input_video->duration_, + get_dimensions(input_video->width_, input_video->height_, nullptr), + input_video->supports_streaming_, false, 0, 0.0, false); content = make_unique(file_id, std::move(caption), input_video->has_spoiler_ && !is_secret); break; } case td_api::inputMessageVideoNote::ID: { auto input_video_note = static_cast(input_message_content.get()); + self_destruct_type = std::move(input_video_note->self_destruct_type_); auto length = input_video_note->length_; - if (length < 0 || length >= 640) { + if (length < 0 || length > 640) { return Status::Error(400, "Wrong video note length"); } - td->video_notes_manager_->create_video_note(file_id, string(), thumbnail, input_video_note->duration_, + td->video_notes_manager_->create_video_note(file_id, string(), std::move(thumbnail), input_video_note->duration_, get_dimensions(length, length, nullptr), string(), false); content = make_unique(file_id, false); @@ -2125,6 +3136,7 @@ static Result create_input_message_content( } case td_api::inputMessageVoiceNote::ID: { auto input_voice_note = static_cast(input_message_content.get()); + self_destruct_type = std::move(input_voice_note->self_destruct_type_); td->voice_notes_manager_->create_voice_note(file_id, std::move(mime_type), input_voice_note->duration_, std::move(input_voice_note->waveform_), false); @@ -2148,14 +3160,14 @@ static Result create_input_message_content( break; } case td_api::inputMessageContact::ID: { - TRY_RESULT(contact, process_input_message_contact(std::move(input_message_content))); + TRY_RESULT(contact, process_input_message_contact(td, std::move(input_message_content))); content = make_unique(std::move(contact)); break; } case td_api::inputMessageGame::ID: { - TRY_RESULT(game, process_input_message_game(td->contacts_manager_.get(), std::move(input_message_content))); + TRY_RESULT(game, process_input_message_game(td->user_manager_.get(), std::move(input_message_content))); via_bot_user_id = game.get_bot_user_id(); - if (via_bot_user_id == td->contacts_manager_->get_my_id()) { + if (via_bot_user_id == td->user_manager_->get_my_id()) { via_bot_user_id = UserId(); } @@ -2167,8 +3179,8 @@ static Result create_input_message_content( return Status::Error(400, "Invoices can be sent only by bots"); } - TRY_RESULT(input_invoice, InputInvoice::process_input_message_invoice(std::move(input_message_content), td, - dialog_id, is_premium)); + TRY_RESULT(input_invoice, + InputInvoice::process_input_message_invoice(std::move(input_message_content), td, dialog_id)); content = make_unique(std::move(input_invoice)); break; } @@ -2177,13 +3189,9 @@ static Result create_input_message_content( constexpr size_t MAX_POLL_OPTION_LENGTH = 100; // server-side limit constexpr size_t MAX_POLL_OPTIONS = 10; // server-side limit auto input_poll = static_cast(input_message_content.get()); - if (!clean_input_string(input_poll->question_)) { - return Status::Error(400, "Poll question must be encoded in UTF-8"); - } - if (input_poll->question_.empty()) { - return Status::Error(400, "Poll question must be non-empty"); - } - if (utf8_length(input_poll->question_) > MAX_POLL_QUESTION_LENGTH) { + TRY_RESULT(question, + get_formatted_text(td, dialog_id, std::move(input_poll->question_), is_bot, false, true, false)); + if (utf8_length(question.text) > MAX_POLL_QUESTION_LENGTH) { return Status::Error(400, PSLICE() << "Poll question length must not exceed " << MAX_POLL_QUESTION_LENGTH); } if (input_poll->options_.size() <= 1) { @@ -2192,16 +3200,13 @@ static Result create_input_message_content( if (input_poll->options_.size() > MAX_POLL_OPTIONS) { return Status::Error(400, PSLICE() << "Poll can't have more than " << MAX_POLL_OPTIONS << " options"); } - for (auto &option : input_poll->options_) { - if (!clean_input_string(option)) { - return Status::Error(400, "Poll options must be encoded in UTF-8"); - } - if (option.empty()) { - return Status::Error(400, "Poll options must be non-empty"); - } - if (utf8_length(option) > MAX_POLL_OPTION_LENGTH) { + vector options; + for (auto &input_option : input_poll->options_) { + TRY_RESULT(option, get_formatted_text(td, dialog_id, std::move(input_option), is_bot, false, true, false)); + if (utf8_length(option.text) > MAX_POLL_OPTION_LENGTH) { return Status::Error(400, PSLICE() << "Poll options length must not exceed " << MAX_POLL_OPTION_LENGTH); } + options.push_back(std::move(option)); } bool allow_multiple_answers = false; @@ -2224,12 +3229,8 @@ static Result create_input_message_content( if (correct_option_id < 0 || correct_option_id >= static_cast(input_poll->options_.size())) { return Status::Error(400, "Wrong correct option ID specified"); } - auto r_explanation = - get_formatted_text(td, dialog_id, std::move(type->explanation_), is_bot, true, true, false); - if (r_explanation.is_error()) { - return r_explanation.move_as_error(); - } - explanation = r_explanation.move_as_ok(); + TRY_RESULT_ASSIGN( + explanation, get_formatted_text(td, dialog_id, std::move(type->explanation_), is_bot, true, true, false)); break; } default: @@ -2242,22 +3243,47 @@ static Result create_input_message_content( close_date = 0; } bool is_closed = is_bot ? input_poll->is_closed_ : false; - content = make_unique( - td->poll_manager_->create_poll(std::move(input_poll->question_), std::move(input_poll->options_), - input_poll->is_anonymous_, allow_multiple_answers, is_quiz, correct_option_id, - std::move(explanation), open_period, close_date, is_closed)); + content = make_unique(td->poll_manager_->create_poll( + std::move(question), std::move(options), input_poll->is_anonymous_, allow_multiple_answers, is_quiz, + correct_option_id, std::move(explanation), open_period, close_date, is_closed)); + break; + } + case td_api::inputMessageStory::ID: { + auto input_story = static_cast(input_message_content.get()); + DialogId story_sender_dialog_id(input_story->story_sender_chat_id_); + StoryId story_id(input_story->story_id_); + StoryFullId story_full_id(story_sender_dialog_id, story_id); + if (!td->story_manager_->have_story_force(story_full_id)) { + return Status::Error(400, "Story not found"); + } + if (!story_id.is_server()) { + return Status::Error(400, "Story can't be forwarded"); + } + if (td->dialog_manager_->get_input_peer(story_sender_dialog_id, AccessRights::Read) == nullptr) { + return Status::Error(400, "Can't access the story"); + } + content = make_unique(story_full_id, false); break; } default: UNREACHABLE(); } - return InputMessageContent{std::move(content), disable_web_page_preview, clear_draft, ttl, + + TRY_RESULT(ttl, MessageSelfDestructType::get_message_self_destruct_type(std::move(self_destruct_type))); + if (!ttl.is_empty() && dialog_id.get_type() != DialogType::User) { + return Status::Error(400, "Messages can self-destruct only in private chats"); + } + + return InputMessageContent{std::move(content), disable_web_page_preview, invert_media, clear_draft, ttl, via_bot_user_id, std::move(emoji)}; } Result get_input_message_content( DialogId dialog_id, tl_object_ptr &&input_message_content, Td *td, bool is_premium) { LOG(INFO) << "Get input message content from " << to_string(input_message_content); + if (input_message_content == nullptr) { + return Status::Error(400, "Input message content must be non-empty"); + } td_api::object_ptr input_file; auto file_type = FileType::None; @@ -2357,12 +3383,60 @@ Result get_input_message_content( std::move(sticker_file_ids), is_premium); } -bool can_have_input_media(const Td *td, const MessageContent *content, bool is_server) { +Status check_message_group_message_contents(const vector &message_contents) { + static constexpr size_t MAX_GROUPED_MESSAGES = 10; // server side limit + if (message_contents.size() > MAX_GROUPED_MESSAGES) { + return Status::Error(400, "Too many messages to send as an album"); + } + if (message_contents.empty()) { + return Status::Error(400, "There are no messages to send"); + } + + std::unordered_set message_content_types; + for (const auto &message_content : message_contents) { + auto message_content_type = message_content.content->get_type(); + if (!is_allowed_media_group_content(message_content_type)) { + return Status::Error(400, "Invalid message content type"); + } + if (message_content.invert_media != message_contents[0].invert_media) { + return Status::Error(400, "Parameter show_caption_above_media must be the same for all messages"); + } + message_content_types.insert(message_content_type); + } + if (message_content_types.size() > 1) { + for (auto message_content_type : message_content_types) { + if (is_homogenous_media_group_content(message_content_type)) { + return Status::Error(400, PSLICE() << message_content_type << " can't be mixed with other media types"); + } + } + } + return Status::OK(); +} + +bool can_message_content_have_input_media(const Td *td, const MessageContent *content, bool is_server) { switch (content->get_type()) { case MessageContentType::Game: return is_server || static_cast(content)->game.has_input_media(); case MessageContentType::Poll: return td->poll_manager_->has_input_media(static_cast(content)->poll_id); + case MessageContentType::Story: { + auto story_full_id = static_cast(content)->story_full_id; + auto dialog_id = story_full_id.get_dialog_id(); + return td->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read) != nullptr; + } + case MessageContentType::Giveaway: + case MessageContentType::GiveawayWinners: + return is_server; + case MessageContentType::PaidMedia: + if (is_server) { + return true; + } + for (const auto &media : static_cast(content)->media) { + if (!media.has_input_media()) { + return false; + } + } + return true; case MessageContentType::Unsupported: case MessageContentType::ChatCreate: case MessageContentType::ChatChangeTitle: @@ -2402,6 +3476,17 @@ bool can_have_input_media(const Td *td, const MessageContent *content, bool is_s case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: return false; case MessageContentType::Animation: case MessageContentType::Audio: @@ -2424,9 +3509,9 @@ bool can_have_input_media(const Td *td, const MessageContent *content, bool is_s } } -SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td, - tl_object_ptr input_file, - BufferSlice thumbnail, int32 layer) { +SecretInputMedia get_message_content_secret_input_media( + const MessageContent *content, Td *td, telegram_api::object_ptr input_file, + BufferSlice thumbnail, int32 layer) { switch (content->get_type()) { case MessageContentType::Animation: { const auto *m = static_cast(content); @@ -2465,7 +3550,10 @@ SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td, CHECK(input_file == nullptr); CHECK(thumbnail.empty()); const auto *m = static_cast(content); - return td->web_pages_manager_->get_secret_input_media(m->web_page_id); + if (m->web_page_url.empty()) { + return SecretInputMedia{}; + } + return SecretInputMedia{nullptr, make_tl_object(m->web_page_url)}; } case MessageContentType::Venue: { const auto *m = static_cast(content); @@ -2492,6 +3580,7 @@ SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td, case MessageContentType::Invoice: case MessageContentType::LiveLocation: case MessageContentType::Poll: + case MessageContentType::Story: case MessageContentType::Unsupported: case MessageContentType::ChatCreate: case MessageContentType::ChatChangeTitle: @@ -2530,6 +3619,20 @@ SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td, case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaidMedia: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: break; default: UNREACHABLE(); @@ -2537,12 +3640,17 @@ SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td, return SecretInputMedia{}; } -static tl_object_ptr get_input_media_impl( - const MessageContent *content, Td *td, tl_object_ptr input_file, - tl_object_ptr input_thumbnail, int32 ttl, const string &emoji) { - if (!can_have_input_media(td, content, false)) { +static telegram_api::object_ptr get_message_content_input_media_impl( + const MessageContent *content, int32 media_pos, Td *td, + telegram_api::object_ptr input_file, + telegram_api::object_ptr input_thumbnail, MessageSelfDestructType ttl, + const string &emoji) { + if (!can_message_content_have_input_media(td, content, false)) { return nullptr; } + if (media_pos >= 0) { + CHECK(content->get_type() == MessageContentType::PaidMedia); + } switch (content->get_type()) { case MessageContentType::Animation: { const auto *m = static_cast(content); @@ -2588,9 +3696,32 @@ static tl_object_ptr get_input_media_impl( const auto *m = static_cast(content); return m->location.get_input_media_geo_point(); } + case MessageContentType::PaidMedia: { + const auto *m = static_cast(content); + if (media_pos >= 0) { + CHECK(static_cast(media_pos) < m->media.size()); + return m->media[media_pos].get_input_media(td, std::move(input_file), std::move(input_thumbnail)); + } + CHECK(m->media.size() == 1u || (input_file == nullptr && input_thumbnail == nullptr)); + vector> input_media; + for (auto &extended_media : m->media) { + auto media = extended_media.get_input_media(td, std::move(input_file), std::move(input_thumbnail)); + if (media == nullptr) { + return nullptr; + } + input_media.push_back(std::move(media)); + } + int32 flags = 0; + if (!m->payload.empty()) { + flags |= telegram_api::inputMediaPaidMedia::PAYLOAD_MASK; + } + return telegram_api::make_object(flags, m->star_count, std::move(input_media), + m->payload); + } case MessageContentType::Photo: { const auto *m = static_cast(content); - return photo_get_input_media(td->file_manager_.get(), m->photo, std::move(input_file), ttl, m->has_spoiler); + return photo_get_input_media(td->file_manager_.get(), m->photo, std::move(input_file), ttl.get_input_ttl(), + m->has_spoiler); } case MessageContentType::Poll: { const auto *m = static_cast(content); @@ -2601,22 +3732,27 @@ static tl_object_ptr get_input_media_impl( return td->stickers_manager_->get_input_media(m->file_id, std::move(input_file), std::move(input_thumbnail), emoji); } + case MessageContentType::Story: { + const auto *m = static_cast(content); + return td->story_manager_->get_input_media(m->story_full_id); + } case MessageContentType::Venue: { const auto *m = static_cast(content); return m->venue.get_input_media_venue(); } case MessageContentType::Video: { const auto *m = static_cast(content); - return td->videos_manager_->get_input_media(m->file_id, std::move(input_file), std::move(input_thumbnail), ttl, - m->has_spoiler); + return td->videos_manager_->get_input_media(m->file_id, std::move(input_file), std::move(input_thumbnail), + ttl.get_input_ttl(), m->has_spoiler); } case MessageContentType::VideoNote: { const auto *m = static_cast(content); - return td->video_notes_manager_->get_input_media(m->file_id, std::move(input_file), std::move(input_thumbnail)); + return td->video_notes_manager_->get_input_media(m->file_id, std::move(input_file), std::move(input_thumbnail), + ttl.get_input_ttl()); } case MessageContentType::VoiceNote: { const auto *m = static_cast(content); - return td->voice_notes_manager_->get_input_media(m->file_id, std::move(input_file)); + return td->voice_notes_manager_->get_input_media(m->file_id, std::move(input_file), ttl.get_input_ttl()); } case MessageContentType::Text: case MessageContentType::Unsupported: @@ -2658,6 +3794,19 @@ static tl_object_ptr get_input_media_impl( case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: break; default: UNREACHABLE(); @@ -2665,14 +3814,15 @@ static tl_object_ptr get_input_media_impl( return nullptr; } -tl_object_ptr get_input_media(const MessageContent *content, Td *td, - tl_object_ptr input_file, - tl_object_ptr input_thumbnail, - FileId file_id, FileId thumbnail_file_id, int32 ttl, - const string &emoji, bool force) { +telegram_api::object_ptr get_message_content_input_media( + const MessageContent *content, int32 media_pos, Td *td, + telegram_api::object_ptr input_file, + telegram_api::object_ptr input_thumbnail, FileId file_id, FileId thumbnail_file_id, + MessageSelfDestructType ttl, const string &emoji, bool force) { bool had_input_file = input_file != nullptr; bool had_input_thumbnail = input_thumbnail != nullptr; - auto input_media = get_input_media_impl(content, td, std::move(input_file), std::move(input_thumbnail), ttl, emoji); + auto input_media = get_message_content_input_media_impl(content, media_pos, td, std::move(input_file), + std::move(input_thumbnail), ttl, emoji); auto was_uploaded = FileManager::extract_was_uploaded(input_media); if (had_input_file) { if (!was_uploaded) { @@ -2689,82 +3839,150 @@ tl_object_ptr get_input_media(const MessageContent *co CHECK(!had_input_thumbnail); } if (!was_uploaded) { - auto file_reference = FileManager::extract_file_reference(input_media); - if (file_reference == FileReferenceView::invalid_file_reference()) { - if (!force) { - LOG(INFO) << "File " << file_id << " has invalid file reference"; - return nullptr; + auto file_references = FileManager::extract_file_references(input_media); + for (auto &file_reference : file_references) { + if (file_reference == FileReferenceView::invalid_file_reference()) { + if (!force) { + LOG(INFO) << "File " << file_id << " has invalid file reference"; + return nullptr; + } + LOG(ERROR) << "File " << file_id << " has invalid file reference, but we are forced to use it"; } - LOG(ERROR) << "File " << file_id << " has invalid file reference, but we forced to use it"; } } return input_media; } -tl_object_ptr get_input_media(const MessageContent *content, Td *td, int32 ttl, - const string &emoji, bool force) { - auto input_media = get_input_media_impl(content, td, nullptr, nullptr, ttl, emoji); - auto file_reference = FileManager::extract_file_reference(input_media); - if (file_reference == FileReferenceView::invalid_file_reference()) { - auto file_id = get_message_content_any_file_id(content); - if (!force) { - LOG(INFO) << "File " << file_id << " has invalid file reference"; - return nullptr; +telegram_api::object_ptr get_message_content_input_media(const MessageContent *content, + Td *td, MessageSelfDestructType ttl, + const string &emoji, bool force, + int32 media_pos) { + auto input_media = get_message_content_input_media_impl(content, media_pos, td, nullptr, nullptr, ttl, emoji); + auto file_references = FileManager::extract_file_references(input_media); + for (size_t i = 0; i < file_references.size(); i++) { + if (file_references[i] == FileReferenceView::invalid_file_reference()) { + auto file_ids = get_message_content_any_file_ids(content); + CHECK(file_ids.size() == file_references.size()); + auto file_id = file_ids[i]; + if (!force) { + LOG(INFO) << "File " << file_id << " has invalid file reference"; + return nullptr; + } + LOG(ERROR) << "File " << file_id << " has invalid file reference, but we are forced to use it"; } - LOG(ERROR) << "File " << file_id << " has invalid file reference, but we forced to use it"; } return input_media; } -tl_object_ptr get_fake_input_media(Td *td, tl_object_ptr input_file, - FileId file_id) { +telegram_api::object_ptr get_message_content_fake_input_media( + Td *td, telegram_api::object_ptr input_file, FileId file_id) { FileView file_view = td->file_manager_->get_file_view(file_id); auto file_type = file_view.get_type(); if (is_document_file_type(file_type)) { - vector> attributes; + vector> attributes; auto file_path = file_view.suggested_path(); const PathView path_view(file_path); Slice file_name = path_view.file_name(); if (!file_name.empty()) { - attributes.push_back(make_tl_object(file_name.str())); + attributes.push_back(telegram_api::make_object(file_name.str())); } string mime_type = MimeType::from_extension(path_view.extension()); int32 flags = 0; - if (file_type == FileType::Video) { + if (file_type == FileType::Video || file_type == FileType::VideoStory) { flags |= telegram_api::inputMediaUploadedDocument::NOSOUND_VIDEO_MASK; } if (file_type == FileType::DocumentAsFile) { flags |= telegram_api::inputMediaUploadedDocument::FORCE_FILE_MASK; } - return make_tl_object( + return telegram_api::make_object( flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_file), nullptr, mime_type, - std::move(attributes), vector>(), 0); + std::move(attributes), vector>(), 0); } else { - CHECK(file_type == FileType::Photo); + CHECK(file_type == FileType::Photo || file_type == FileType::PhotoStory); int32 flags = 0; - return make_tl_object( - flags, false /*ignored*/, std::move(input_file), vector>(), 0); + return telegram_api::make_object( + flags, false /*ignored*/, std::move(input_file), + vector>(), 0); } } -void delete_message_content_thumbnail(MessageContent *content, Td *td) { - switch (content->get_type()) { - case MessageContentType::Animation: { - auto *m = static_cast(content); - return td->animations_manager_->delete_animation_thumbnail(m->file_id); - } - case MessageContentType::Audio: { - auto *m = static_cast(content); - return td->audios_manager_->delete_audio_thumbnail(m->file_id); - } - case MessageContentType::Document: { - auto *m = static_cast(content); +telegram_api::object_ptr get_message_content_input_media_web_page( + const Td *td, const MessageContent *content) { + CHECK(content != nullptr); + if (content->get_type() != MessageContentType::Text) { + return nullptr; + } + auto *text = static_cast(content); + if (text->web_page_url.empty()) { + return nullptr; + } + int32 flags = 0; + if (text->force_small_media) { + flags |= telegram_api::inputMediaWebPage::FORCE_SMALL_MEDIA_MASK; + } + if (text->force_large_media) { + flags |= telegram_api::inputMediaWebPage::FORCE_LARGE_MEDIA_MASK; + } + if (!text->text.text.empty()) { + flags |= telegram_api::inputMediaWebPage::OPTIONAL_MASK; + } + return telegram_api::make_object(flags, false /*ignored*/, false /*ignored*/, + false /*ignored*/, text->web_page_url); +} + +bool is_uploaded_input_media(telegram_api::object_ptr &input_media) { + CHECK(input_media != nullptr); + LOG(DEBUG) << "Have " << to_string(input_media); + switch (input_media->get_id()) { + case telegram_api::inputMediaUploadedDocument::ID: + static_cast(input_media.get())->flags_ |= + telegram_api::inputMediaUploadedDocument::NOSOUND_VIDEO_MASK; + // fallthrough + case telegram_api::inputMediaUploadedPhoto::ID: + case telegram_api::inputMediaDocumentExternal::ID: + case telegram_api::inputMediaPhotoExternal::ID: + return false; + case telegram_api::inputMediaDocument::ID: + case telegram_api::inputMediaPhoto::ID: + return true; + default: + UNREACHABLE(); + return false; + } +} + +void delete_message_content_thumbnail(MessageContent *content, Td *td, int32 media_pos) { + if (media_pos != -1) { + CHECK(content->get_type() == MessageContentType::PaidMedia); + } + switch (content->get_type()) { + case MessageContentType::Animation: { + auto *m = static_cast(content); + return td->animations_manager_->delete_animation_thumbnail(m->file_id); + } + case MessageContentType::Audio: { + auto *m = static_cast(content); + return td->audios_manager_->delete_audio_thumbnail(m->file_id); + } + case MessageContentType::Document: { + auto *m = static_cast(content); return td->documents_manager_->delete_document_thumbnail(m->file_id); } case MessageContentType::Invoice: { auto *m = static_cast(content); return m->input_invoice.delete_thumbnail(td); } + case MessageContentType::PaidMedia: { + auto *m = static_cast(content); + if (media_pos == -1) { + CHECK(m->media.size() == 1u); + media_pos = 0; + } else { + CHECK(static_cast(media_pos) < m->media.size()); + } + m->media[media_pos].delete_thumbnail(td); + break; + } case MessageContentType::Photo: { auto *m = static_cast(content); return photo_delete_thumbnail(m->photo); @@ -2786,6 +4004,7 @@ void delete_message_content_thumbnail(MessageContent *content, Td *td) { case MessageContentType::Game: case MessageContentType::LiveLocation: case MessageContentType::Location: + case MessageContentType::Story: case MessageContentType::Venue: case MessageContentType::VoiceNote: case MessageContentType::Text: @@ -2829,33 +4048,53 @@ void delete_message_content_thumbnail(MessageContent *content, Td *td) { case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: break; default: UNREACHABLE(); } } -Status can_send_message_content(DialogId dialog_id, const MessageContent *content, bool is_forward, const Td *td) { +Status can_send_message_content(DialogId dialog_id, const MessageContent *content, bool is_forward, + bool check_permissions, const Td *td) { auto dialog_type = dialog_id.get_type(); RestrictedRights permissions = [&] { + if (!check_permissions) { + return RestrictedRights(true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, + true, true, ChannelType::Unknown); + } switch (dialog_type) { case DialogType::User: - return td->contacts_manager_->get_user_default_permissions(dialog_id.get_user_id()); + return td->user_manager_->get_user_default_permissions(dialog_id.get_user_id()); case DialogType::Chat: - return td->contacts_manager_->get_chat_permissions(dialog_id.get_chat_id()).get_effective_restricted_rights(); + return td->chat_manager_->get_chat_permissions(dialog_id.get_chat_id()).get_effective_restricted_rights(); case DialogType::Channel: - return td->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()) - .get_effective_restricted_rights(); + return td->chat_manager_->get_channel_permissions(dialog_id.get_channel_id()).get_effective_restricted_rights(); case DialogType::SecretChat: - return td->contacts_manager_->get_secret_chat_default_permissions(dialog_id.get_secret_chat_id()); + return td->user_manager_->get_secret_chat_default_permissions(dialog_id.get_secret_chat_id()); case DialogType::None: default: UNREACHABLE(); - return td->contacts_manager_->get_user_default_permissions(UserId()); + return td->user_manager_->get_user_default_permissions(UserId()); } }(); auto content_type = content->get_type(); + if (dialog_type == DialogType::SecretChat && !can_send_message_content_to_secret_chat(content_type)) { + return Status::Error(400, "Message can't be sent to a secret chat"); + } switch (content_type) { case MessageContentType::Animation: if (!permissions.can_send_animations()) { @@ -2876,9 +4115,6 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten if (!permissions.can_send_stickers()) { return Status::Error(400, "Not enough rights to send dice to the chat"); } - if (dialog_type == DialogType::SecretChat) { - return Status::Error(400, "Dice can't be sent to secret chats"); - } break; case MessageContentType::Document: if (!permissions.can_send_documents()) { @@ -2886,24 +4122,27 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten } break; case MessageContentType::Game: - if (dialog_type == DialogType::Channel && - td->contacts_manager_->is_broadcast_channel(dialog_id.get_channel_id())) { + if (dialog_type == DialogType::Channel && td->chat_manager_->is_broadcast_channel(dialog_id.get_channel_id())) { // return Status::Error(400, "Games can't be sent to channel chats"); } - if (dialog_type == DialogType::SecretChat) { - return Status::Error(400, "Games can't be sent to secret chats"); - } if (!permissions.can_send_games()) { return Status::Error(400, "Not enough rights to send games to the chat"); } break; + case MessageContentType::Giveaway: + if (!permissions.can_send_messages()) { + return Status::Error(400, "Not enough rights to send giveaways to the chat"); + } + break; + case MessageContentType::GiveawayWinners: + if (!permissions.can_send_messages()) { + return Status::Error(400, "Not enough rights to send giveaway winners to the chat"); + } + break; case MessageContentType::Invoice: if (!permissions.can_send_messages()) { return Status::Error(400, "Not enough rights to send invoice messages to the chat"); } - if (dialog_type == DialogType::SecretChat) { - return Status::Error(400, "Invoice messages can't be sent to secret chats"); - } break; case MessageContentType::LiveLocation: if (!permissions.can_send_messages()) { @@ -2915,6 +4154,18 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten return Status::Error(400, "Not enough rights to send locations to the chat"); } break; + case MessageContentType::PaidMedia: + if (is_forward) { + if (!permissions.can_send_photos() || !permissions.can_send_videos()) { + return Status::Error(400, "Not enough rights to send paid media to the chat"); + } + } else { + if (!td->auth_manager_->is_bot() && (dialog_type != DialogType::Channel || + !td->chat_manager_->is_broadcast_channel(dialog_id.get_channel_id()))) { + return Status::Error(400, "Paid media can be sent only in channel chats"); + } + } + break; case MessageContentType::Photo: if (!permissions.can_send_photos()) { return Status::Error(400, "Not enough rights to send photos to the chat"); @@ -2924,18 +4175,14 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten if (!permissions.can_send_polls()) { return Status::Error(400, "Not enough rights to send polls to the chat"); } - if (dialog_type == DialogType::Channel && - td->contacts_manager_->is_broadcast_channel(dialog_id.get_channel_id()) && + if (dialog_type == DialogType::Channel && td->chat_manager_->is_broadcast_channel(dialog_id.get_channel_id()) && !td->poll_manager_->get_poll_is_anonymous(static_cast(content)->poll_id)) { return Status::Error(400, "Non-anonymous polls can't be sent to channel chats"); } if (dialog_type == DialogType::User && !is_forward && !td->auth_manager_->is_bot() && - !td->contacts_manager_->is_user_bot(dialog_id.get_user_id())) { + !td->user_manager_->is_user_bot(dialog_id.get_user_id())) { return Status::Error(400, "Polls can't be sent to the private chat"); } - if (dialog_type == DialogType::SecretChat) { - return Status::Error(400, "Polls can't be sent to secret chats"); - } break; case MessageContentType::Sticker: if (!permissions.can_send_stickers()) { @@ -2945,6 +4192,11 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten return Status::Error(400, "Can't send emoji stickers in messages"); } break; + case MessageContentType::Story: + if (!permissions.can_send_photos() || !permissions.can_send_videos()) { + return Status::Error(400, "Not enough rights to send stories to the chat"); + } + break; case MessageContentType::Text: if (!permissions.can_send_messages()) { return Status::Error(400, "Not enough rights to send text messages to the chat"); @@ -2965,7 +4217,7 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten return Status::Error(400, "Not enough rights to send video notes to the chat"); } if (dialog_type == DialogType::User && - td->contacts_manager_->get_user_voice_messages_forbidden(dialog_id.get_user_id())) { + td->user_manager_->get_user_voice_messages_forbidden(dialog_id.get_user_id())) { return Status::Error(400, "User restricted receiving of voice messages"); } break; @@ -2974,7 +4226,7 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten return Status::Error(400, "Not enough rights to send voice notes to the chat"); } if (dialog_type == DialogType::User && - td->contacts_manager_->get_user_voice_messages_forbidden(dialog_id.get_user_id())) { + td->user_manager_->get_user_voice_messages_forbidden(dialog_id.get_user_id())) { return Status::Error(400, "User restricted receiving of video messages"); } break; @@ -3018,6 +4270,17 @@ Status can_send_message_content(DialogId dialog_id, const MessageContent *conten case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: UNREACHABLE(); } return Status::OK(); @@ -3027,7 +4290,8 @@ bool can_forward_message_content(const MessageContent *content) { auto content_type = content->get_type(); if (content_type == MessageContentType::Text) { auto *text = static_cast(content); - return !is_empty_string(text->text.text); // text must be non-empty in the new message + // text must be non-empty if there is no link preview + return !is_empty_string(text->text.text) || text->web_page_id.is_valid() || !text->web_page_url.empty(); } if (content_type == MessageContentType::Poll) { auto *poll = static_cast(content); @@ -3035,7 +4299,7 @@ bool can_forward_message_content(const MessageContent *content) { } return !is_service_message_content(content_type) && content_type != MessageContentType::Unsupported && - content_type != MessageContentType::ExpiredPhoto && content_type != MessageContentType::ExpiredVideo; + !is_expired_message_content(content_type); } bool update_opened_message_content(MessageContent *content) { @@ -3114,6 +4378,7 @@ static int32 get_message_content_media_index_mask(const MessageContent *content, case MessageContentType::LiveLocation: case MessageContentType::Location: case MessageContentType::Sticker: + case MessageContentType::Story: case MessageContentType::Unsupported: case MessageContentType::Venue: case MessageContentType::ChatCreate: @@ -3154,6 +4419,20 @@ static int32 get_message_content_media_index_mask(const MessageContent *content, case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaidMedia: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: return 0; default: UNREACHABLE(); @@ -3166,6 +4445,12 @@ int32 get_message_content_index_mask(const MessageContent *content, const Td *td return get_message_content_text_index_mask(content) | get_message_content_media_index_mask(content, td, is_outgoing); } +vector> get_individual_message_contents(const MessageContent *content) { + CHECK(content->get_type() == MessageContentType::PaidMedia); + const auto *m = static_cast(content); + return transform(m->media, [](const MessageExtendedMedia &media) { return media.get_message_content(); }); +} + StickerType get_message_content_sticker_type(const Td *td, const MessageContent *content) { CHECK(content->get_type() == MessageContentType::Sticker); return td->stickers_manager_->get_sticker_type(static_cast(content)->file_id); @@ -3180,13 +4465,19 @@ MessageId get_message_content_pinned_message_id(const MessageContent *content) { } } -BackgroundInfo get_message_content_background_info(const MessageContent *content) { +BackgroundInfo get_message_content_my_background_info(const MessageContent *content, bool is_outgoing) { switch (content->get_type()) { - case MessageContentType::SetBackground: - return static_cast(content)->background_info; + case MessageContentType::SetBackground: { + const auto *set_background = static_cast(content); + if (is_outgoing || set_background->for_both) { + return set_background->background_info; + } + break; + } default: - return BackgroundInfo(); + break; } + return BackgroundInfo(); } string get_message_content_theme_name(const MessageContent *content) { @@ -3198,7 +4489,7 @@ string get_message_content_theme_name(const MessageContent *content) { } } -FullMessageId get_message_content_replied_message_id(DialogId dialog_id, const MessageContent *content) { +MessageFullId get_message_content_replied_message_id(DialogId dialog_id, const MessageContent *content) { switch (content->get_type()) { case MessageContentType::PinMessage: return {dialog_id, static_cast(content)->message_id}; @@ -3207,7 +4498,7 @@ FullMessageId get_message_content_replied_message_id(DialogId dialog_id, const M case MessageContentType::PaymentSuccessful: { auto *m = static_cast(content); if (!m->invoice_message_id.is_valid()) { - return FullMessageId(); + return MessageFullId(); } auto reply_in_dialog_id = m->invoice_dialog_id.is_valid() ? m->invoice_dialog_id : dialog_id; @@ -3216,13 +4507,21 @@ FullMessageId get_message_content_replied_message_id(DialogId dialog_id, const M case MessageContentType::SetBackground: { auto *m = static_cast(content); if (!m->old_message_id.is_valid()) { - return FullMessageId(); + return MessageFullId(); } return {dialog_id, m->old_message_id}; } + case MessageContentType::GiveawayResults: { + auto *m = static_cast(content); + if (!m->giveaway_message_id.is_valid()) { + return MessageFullId(); + } + + return {dialog_id, m->giveaway_message_id}; + } default: - return FullMessageId(); + return MessageFullId(); } } @@ -3232,13 +4531,256 @@ std::pair get_message_content_group_call_info(const Mess return {m->input_group_call_id, m->duration >= 0}; } -UserId get_message_content_contact_user_id(const MessageContent *content) { - switch (content->get_type()) { - case MessageContentType::Contact: - return static_cast(content)->contact.get_user_id(); +static vector get_formatted_text_user_ids(const FormattedText *formatted_text) { + vector user_ids; + if (formatted_text != nullptr) { + for (auto &entity : formatted_text->entities) { + if (entity.user_id.is_valid()) { + user_ids.push_back(entity.user_id); + } + } + } + return user_ids; +} + +vector get_message_content_min_user_ids(const Td *td, const MessageContent *message_content) { + CHECK(message_content != nullptr); + switch (message_content->get_type()) { + case MessageContentType::Text: { + const auto *content = static_cast(message_content); + auto user_ids = get_formatted_text_user_ids(&content->text); + if (content->web_page_id.is_valid()) { + combine(user_ids, td->web_pages_manager_->get_web_page_user_ids(content->web_page_id)); + } + return user_ids; + } + case MessageContentType::Animation: + break; + case MessageContentType::Audio: + break; + case MessageContentType::Contact: { + const auto *content = static_cast(message_content); + auto user_id = content->contact.get_user_id(); + if (user_id.is_valid()) { + return {user_id}; + } + break; + } + case MessageContentType::Document: + break; + case MessageContentType::Game: { + const auto *content = static_cast(message_content); + auto user_id = content->game.get_bot_user_id(); + if (user_id.is_valid()) { + return {user_id}; + } + break; + } + case MessageContentType::Invoice: + break; + case MessageContentType::LiveLocation: + break; + case MessageContentType::Location: + break; + case MessageContentType::Photo: + break; + case MessageContentType::Sticker: + break; + case MessageContentType::Venue: + break; + case MessageContentType::Video: + break; + case MessageContentType::VideoNote: + break; + case MessageContentType::VoiceNote: + break; + case MessageContentType::ChatCreate: { + const auto *content = static_cast(message_content); + return content->participant_user_ids; + } + case MessageContentType::ChatChangeTitle: + break; + case MessageContentType::ChatChangePhoto: + break; + case MessageContentType::ChatDeletePhoto: + break; + case MessageContentType::ChatDeleteHistory: + break; + case MessageContentType::ChatAddUsers: { + const auto *content = static_cast(message_content); + return content->user_ids; + } + case MessageContentType::ChatJoinedByLink: + break; + case MessageContentType::ChatDeleteUser: { + const auto *content = static_cast(message_content); + return {content->user_id}; + } + case MessageContentType::ChatMigrateTo: + break; + case MessageContentType::ChannelCreate: + break; + case MessageContentType::ChannelMigrateFrom: + break; + case MessageContentType::PinMessage: + break; + case MessageContentType::GameScore: + break; + case MessageContentType::ScreenshotTaken: + break; + case MessageContentType::ChatSetTtl: + // the content->from_user_id user can't be min + break; + case MessageContentType::Unsupported: + break; + case MessageContentType::Call: + break; + case MessageContentType::PaymentSuccessful: + break; + case MessageContentType::ContactRegistered: + break; + case MessageContentType::ExpiredPhoto: + break; + case MessageContentType::ExpiredVideo: + break; + case MessageContentType::CustomServiceAction: + break; + case MessageContentType::WebsiteConnected: + break; + case MessageContentType::PassportDataSent: + break; + case MessageContentType::PassportDataReceived: + break; + case MessageContentType::Poll: + break; + case MessageContentType::Dice: + break; + case MessageContentType::ProximityAlertTriggered: { + const auto *content = static_cast(message_content); + vector user_ids; + if (content->traveler_dialog_id.get_type() == DialogType::User) { + user_ids.push_back(content->traveler_dialog_id.get_user_id()); + } + if (content->watcher_dialog_id.get_type() == DialogType::User) { + user_ids.push_back(content->watcher_dialog_id.get_user_id()); + } + return user_ids; + } + case MessageContentType::GroupCall: + break; + case MessageContentType::InviteToGroupCall: { + const auto *content = static_cast(message_content); + return content->user_ids; + } + case MessageContentType::ChatSetTheme: + break; + case MessageContentType::WebViewDataSent: + break; + case MessageContentType::WebViewDataReceived: + break; + case MessageContentType::GiftPremium: + break; + case MessageContentType::TopicCreate: + break; + case MessageContentType::TopicEdit: + break; + case MessageContentType::SuggestProfilePhoto: + break; + case MessageContentType::WriteAccessAllowed: + break; + case MessageContentType::RequestedDialog: + break; + case MessageContentType::WebViewWriteAccessAllowed: + break; + case MessageContentType::SetBackground: + break; + case MessageContentType::Story: { + const auto *content = static_cast(message_content); + auto dialog_id = content->story_full_id.get_dialog_id(); + if (dialog_id.get_type() == DialogType::User) { + return {dialog_id.get_user_id()}; + } + break; + } + case MessageContentType::WriteAccessAllowedByRequest: + break; + case MessageContentType::GiftCode: + break; + case MessageContentType::Giveaway: + break; + case MessageContentType::GiveawayLaunch: + break; + case MessageContentType::GiveawayResults: + break; + case MessageContentType::GiveawayWinners: { + const auto *content = static_cast(message_content); + return content->winner_user_ids; + } + case MessageContentType::ExpiredVideoNote: + break; + case MessageContentType::ExpiredVoiceNote: + break; + case MessageContentType::BoostApply: + break; + case MessageContentType::DialogShared: + break; + case MessageContentType::PaidMedia: + break; + case MessageContentType::PaymentRefunded: + // private chats only + break; + case MessageContentType::GiftStars: + break; + case MessageContentType::PrizeStars: + break; default: - return UserId(); + UNREACHABLE(); + break; } + return get_formatted_text_user_ids(get_message_content_text(message_content)); +} + +vector get_message_content_min_channel_ids(const Td *td, const MessageContent *message_content) { + CHECK(message_content != nullptr); + switch (message_content->get_type()) { + case MessageContentType::Text: { + const auto *content = static_cast(message_content); + if (content->web_page_id.is_valid()) { + return td->web_pages_manager_->get_web_page_channel_ids(content->web_page_id); + } + break; + } + case MessageContentType::ProximityAlertTriggered: { + const auto *content = static_cast(message_content); + vector channel_ids; + if (content->traveler_dialog_id.get_type() == DialogType::Channel) { + channel_ids.push_back(content->traveler_dialog_id.get_channel_id()); + } + if (content->watcher_dialog_id.get_type() == DialogType::Channel) { + channel_ids.push_back(content->watcher_dialog_id.get_channel_id()); + } + return channel_ids; + } + case MessageContentType::Story: { + const auto *content = static_cast(message_content); + auto dialog_id = content->story_full_id.get_dialog_id(); + if (dialog_id.get_type() == DialogType::Channel) { + return {dialog_id.get_channel_id()}; + } + break; + } + case MessageContentType::Giveaway: { + const auto *content = static_cast(message_content); + return content->giveaway_parameters.get_channel_ids(); + } + case MessageContentType::GiveawayWinners: { + const auto *content = static_cast(message_content); + return {content->boosted_channel_id}; + } + default: + break; + } + return {}; } vector get_message_content_added_user_ids(const MessageContent *content) { @@ -3282,6 +4824,15 @@ bool get_message_content_poll_is_closed(const Td *td, const MessageContent *cont } } +const Venue *get_message_content_venue(const MessageContent *content) { + switch (content->get_type()) { + case MessageContentType::Venue: + return &static_cast(content)->venue; + default: + return nullptr; + } +} + bool has_message_content_web_page(const MessageContent *content) { if (content->get_type() == MessageContentType::Text) { return static_cast(content)->web_page_id.is_valid(); @@ -3291,13 +4842,19 @@ bool has_message_content_web_page(const MessageContent *content) { void remove_message_content_web_page(MessageContent *content) { CHECK(content->get_type() == MessageContentType::Text); - static_cast(content)->web_page_id = WebPageId(); + auto message_text = static_cast(content); + message_text->web_page_id = WebPageId(); + message_text->force_small_media = false; + message_text->force_large_media = false; + message_text->skip_web_page_confirmation = false; + message_text->web_page_url = string(); } bool can_message_content_have_media_timestamp(const MessageContent *content) { CHECK(content != nullptr); switch (content->get_type()) { case MessageContentType::Audio: + case MessageContentType::Story: case MessageContentType::Video: case MessageContentType::VideoNote: case MessageContentType::VoiceNote: @@ -3311,25 +4868,25 @@ bool can_message_content_have_media_timestamp(const MessageContent *content) { } } -void set_message_content_poll_answer(Td *td, const MessageContent *content, FullMessageId full_message_id, +void set_message_content_poll_answer(Td *td, const MessageContent *content, MessageFullId message_full_id, vector &&option_ids, Promise &&promise) { CHECK(content->get_type() == MessageContentType::Poll); - td->poll_manager_->set_poll_answer(static_cast(content)->poll_id, full_message_id, + td->poll_manager_->set_poll_answer(static_cast(content)->poll_id, message_full_id, std::move(option_ids), std::move(promise)); } -void get_message_content_poll_voters(Td *td, const MessageContent *content, FullMessageId full_message_id, +void get_message_content_poll_voters(Td *td, const MessageContent *content, MessageFullId message_full_id, int32 option_id, int32 offset, int32 limit, - Promise>> &&promise) { + Promise> &&promise) { CHECK(content->get_type() == MessageContentType::Poll); - td->poll_manager_->get_poll_voters(static_cast(content)->poll_id, full_message_id, option_id, + td->poll_manager_->get_poll_voters(static_cast(content)->poll_id, message_full_id, option_id, offset, limit, std::move(promise)); } -void stop_message_content_poll(Td *td, const MessageContent *content, FullMessageId full_message_id, +void stop_message_content_poll(Td *td, const MessageContent *content, MessageFullId message_full_id, unique_ptr &&reply_markup, Promise &&promise) { CHECK(content->get_type() == MessageContentType::Poll); - td->poll_manager_->stop_poll(static_cast(content)->poll_id, full_message_id, + td->poll_manager_->stop_poll(static_cast(content)->poll_id, message_full_id, std::move(reply_markup), std::move(promise)); } @@ -3342,6 +4899,10 @@ static void merge_location_access_hash(const Location &first, const Location &se } static bool need_message_text_changed_warning(const MessageText *old_content, const MessageText *new_content) { + const int32 MAX_CUSTOM_ENTITIES_COUNT = 100; // server-side limit + if (old_content->text.entities.size() > MAX_CUSTOM_ENTITIES_COUNT) { + return false; + } if (new_content->text.text == "Unsupported characters" || new_content->text.text == "This channel is blocked because it was used to spread pornographic content." || begins_with(new_content->text.text, @@ -3377,8 +4938,19 @@ static bool need_message_entities_changed_warning(const vector &o new_pos++; continue; } - - if (old_pos < old_entities.size() && (old_entities[old_pos].type == MessageEntity::Type::MentionName || + if (old_pos < old_entities.size() && new_pos < new_entities.size() && + (old_entities[old_pos].type == MessageEntity::Type::Pre || + old_entities[old_pos].type == MessageEntity::Type::PreCode) && + new_entities[new_pos].type == MessageEntity::Type::PreCode && old_entities[old_pos].argument.empty() && + old_entities[old_pos].offset == new_entities[new_pos].offset && + old_entities[old_pos].length == new_entities[new_pos].length) { + // server can add recognized language code + old_pos++; + new_pos++; + continue; + } + + if (old_pos < old_entities.size() && (old_entities[old_pos].type == MessageEntity::Type::MentionName || old_entities[old_pos].type == MessageEntity::Type::CustomEmoji)) { // server can delete some MentionName and CustomEmoji entities old_pos++; @@ -3404,90 +4976,46 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); auto get_content_object = [td, dialog_id](const MessageContent *content) { - return to_string( - get_message_content_object(content, td, dialog_id, -1, false, false, std::numeric_limits::max())); + return to_string(get_message_content_object(content, td, dialog_id, false, false, -1, false, false, + std::numeric_limits::max(), false, false)); }; if (old_->text.text != new_->text.text) { if (need_message_changed_warning && need_message_text_changed_warning(old_, new_)) { - LOG(ERROR) << "Message text has changed in " << get_content_object(old_content) << ". New content is " - << get_content_object(new_content); + LOG(ERROR) << "Message text has changed for a message in " << dialog_id << " from " + << get_content_object(old_content) << " to " << get_content_object(new_content); } - need_update = true; } if (old_->text.entities != new_->text.entities) { - const int32 MAX_CUSTOM_ENTITIES_COUNT = 100; // server-side limit if (need_message_changed_warning && need_message_text_changed_warning(old_, new_) && - old_->text.entities.size() <= MAX_CUSTOM_ENTITIES_COUNT && need_message_entities_changed_warning(old_->text.entities, new_->text.entities) && td->option_manager_->get_option_integer("session_count") <= 1) { - LOG(WARNING) << "Entities have changed in " << get_content_object(old_content) << ". New content is " - << get_content_object(new_content); + LOG(WARNING) << "Entities have changed for a message in " << dialog_id << " from " + << get_content_object(old_content) << " to " << get_content_object(new_content); } - need_update = true; - } - if (old_->web_page_id != new_->web_page_id) { - LOG(INFO) << "Old: " << old_->web_page_id << ", new: " << new_->web_page_id; - is_content_changed = true; - need_update |= td->web_pages_manager_->have_web_page(old_->web_page_id) || - td->web_pages_manager_->have_web_page(new_->web_page_id); } break; } case MessageContentType::Animation: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); - if (old_->file_id != new_->file_id) { - if (need_merge_files) { - td->animations_manager_->merge_animations(new_->file_id, old_->file_id); - } - need_update = true; - } - if (old_->caption != new_->caption || old_->has_spoiler != new_->has_spoiler) { - need_update = true; + if (old_->file_id != new_->file_id && need_merge_files) { + td->animations_manager_->merge_animations(new_->file_id, old_->file_id); } break; } case MessageContentType::Audio: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); - if (old_->file_id != new_->file_id) { - if (need_merge_files) { - td->audios_manager_->merge_audios(new_->file_id, old_->file_id); - } - need_update = true; - } - if (old_->caption != new_->caption) { - need_update = true; - } - break; - } - case MessageContentType::Contact: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->contact != new_->contact) { - need_update = true; + if (old_->file_id != new_->file_id && need_merge_files) { + td->audios_manager_->merge_audios(new_->file_id, old_->file_id); } break; } case MessageContentType::Document: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); - if (old_->file_id != new_->file_id) { - if (need_merge_files) { - td->documents_manager_->merge_documents(new_->file_id, old_->file_id); - } - need_update = true; - } - if (old_->caption != new_->caption) { - need_update = true; - } - break; - } - case MessageContentType::Game: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->game != new_->game) { - need_update = true; + if (old_->file_id != new_->file_id && need_merge_files) { + td->documents_manager_->merge_documents(new_->file_id, old_->file_id); } break; } @@ -3495,25 +5023,12 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo const auto *old_ = static_cast(old_content); auto *new_ = static_cast(new_content); new_->input_invoice.update_from(old_->input_invoice); - if (old_->input_invoice != new_->input_invoice) { - need_update = true; - } else if (old_->input_invoice.is_equal_but_different(new_->input_invoice)) { - is_content_changed = true; - } break; } case MessageContentType::LiveLocation: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); - if (old_->location != new_->location) { - need_update = true; - } - if (old_->period != new_->period || old_->heading != new_->heading || - old_->proximity_alert_radius != new_->proximity_alert_radius) { - need_update = true; - } if (old_->location.get_access_hash() != new_->location.get_access_hash()) { - is_content_changed = true; merge_location_access_hash(old_->location, new_->location); } break; @@ -3521,46 +5036,41 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo case MessageContentType::Location: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); - if (old_->location != new_->location) { - need_update = true; - } if (old_->location.get_access_hash() != new_->location.get_access_hash()) { - is_content_changed = true; merge_location_access_hash(old_->location, new_->location); } break; } + case MessageContentType::PaidMedia: { + const auto *old_ = static_cast(old_content); + auto *new_ = static_cast(new_content); + if (old_->media.size() != new_->media.size()) { + LOG(ERROR) << "Had " << old_->media.size() << " paid media, but now have " << new_->media.size(); + } else { + for (size_t i = 0; i < old_->media.size(); i++) { + old_->media[i].merge_files(td, new_->media[i], dialog_id, need_merge_files, is_content_changed, need_update); + } + } + break; + } case MessageContentType::Photo: { const auto *old_ = static_cast(old_content); auto *new_ = static_cast(new_content); merge_photos(td, &old_->photo, &new_->photo, dialog_id, need_merge_files, is_content_changed, need_update); - if (old_->caption != new_->caption || old_->has_spoiler != new_->has_spoiler) { - need_update = true; - } break; } case MessageContentType::Sticker: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); - if (old_->file_id != new_->file_id) { - if (need_merge_files) { - td->stickers_manager_->merge_stickers(new_->file_id, old_->file_id); - } - need_update = true; - } - if (old_->is_premium != new_->is_premium) { - need_update = true; + if (old_->file_id != new_->file_id && need_merge_files) { + td->stickers_manager_->merge_stickers(new_->file_id, old_->file_id); } break; } case MessageContentType::Venue: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); - if (old_->venue != new_->venue) { - need_update = true; - } if (old_->venue.location().get_access_hash() != new_->venue.location().get_access_hash()) { - is_content_changed = true; merge_location_access_hash(old_->venue.location(), new_->venue.location()); } break; @@ -3568,65 +5078,427 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo case MessageContentType::Video: { const auto *old_ = static_cast(old_content); const auto *new_ = static_cast(new_content); - if (old_->file_id != new_->file_id) { - if (need_merge_files) { - td->videos_manager_->merge_videos(new_->file_id, old_->file_id); + if (old_->file_id != new_->file_id && need_merge_files) { + td->videos_manager_->merge_videos(new_->file_id, old_->file_id); + } + break; + } + case MessageContentType::VideoNote: { + const auto *old_ = static_cast(old_content); + auto *new_ = static_cast(new_content); + if (old_->file_id != new_->file_id && need_merge_files) { + td->video_notes_manager_->merge_video_notes(new_->file_id, old_->file_id); + } + if (old_->is_viewed) { + new_->is_viewed = true; + } + break; + } + case MessageContentType::VoiceNote: { + const auto *old_ = static_cast(old_content); + auto *new_ = static_cast(new_content); + if (old_->file_id != new_->file_id && need_merge_files) { + td->voice_notes_manager_->merge_voice_notes(new_->file_id, old_->file_id); + } + if (old_->is_listened) { + new_->is_listened = true; + } + break; + } + case MessageContentType::Contact: + case MessageContentType::Game: + case MessageContentType::ChatCreate: + case MessageContentType::ChatChangeTitle: + case MessageContentType::ChatChangePhoto: + case MessageContentType::ChatDeletePhoto: + case MessageContentType::ChatDeleteHistory: + case MessageContentType::ChatAddUsers: + case MessageContentType::ChatJoinedByLink: + case MessageContentType::ChatDeleteUser: + case MessageContentType::ChatMigrateTo: + case MessageContentType::ChannelCreate: + case MessageContentType::ChannelMigrateFrom: + case MessageContentType::PinMessage: + case MessageContentType::GameScore: + case MessageContentType::ScreenshotTaken: + case MessageContentType::ChatSetTtl: + case MessageContentType::Call: + case MessageContentType::PaymentSuccessful: + case MessageContentType::ContactRegistered: + case MessageContentType::ExpiredPhoto: + case MessageContentType::ExpiredVideo: + case MessageContentType::CustomServiceAction: + case MessageContentType::WebsiteConnected: + case MessageContentType::PassportDataSent: + case MessageContentType::PassportDataReceived: + case MessageContentType::Poll: + case MessageContentType::Dice: + case MessageContentType::ProximityAlertTriggered: + case MessageContentType::GroupCall: + case MessageContentType::InviteToGroupCall: + case MessageContentType::ChatSetTheme: + case MessageContentType::WebViewDataSent: + case MessageContentType::WebViewDataReceived: + case MessageContentType::GiftPremium: + case MessageContentType::TopicCreate: + case MessageContentType::TopicEdit: + case MessageContentType::Unsupported: + case MessageContentType::SuggestProfilePhoto: + case MessageContentType::WriteAccessAllowed: + case MessageContentType::RequestedDialog: + case MessageContentType::WebViewWriteAccessAllowed: + case MessageContentType::SetBackground: + case MessageContentType::Story: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: + break; + default: + UNREACHABLE(); + break; + } +} + +bool merge_message_content_file_id(Td *td, MessageContent *message_content, FileId new_file_id) { + if (!new_file_id.is_valid()) { + return false; + } + + // secret chats only + LOG(INFO) << "Merge message content of a message with file " << new_file_id; + MessageContentType content_type = message_content->get_type(); + switch (content_type) { + case MessageContentType::Animation: { + auto content = static_cast(message_content); + if (new_file_id != content->file_id) { + td->animations_manager_->merge_animations(new_file_id, content->file_id); + content->file_id = new_file_id; + return true; + } + break; + } + case MessageContentType::Audio: { + auto content = static_cast(message_content); + if (new_file_id != content->file_id) { + td->audios_manager_->merge_audios(new_file_id, content->file_id); + content->file_id = new_file_id; + return true; + } + break; + } + case MessageContentType::Document: { + auto content = static_cast(message_content); + if (new_file_id != content->file_id) { + td->documents_manager_->merge_documents(new_file_id, content->file_id); + content->file_id = new_file_id; + return true; + } + break; + } + case MessageContentType::Photo: { + auto content = static_cast(message_content); + Photo *photo = &content->photo; + if (!photo->photos.empty() && photo->photos.back().type == 'i') { + FileId &old_file_id = photo->photos.back().file_id; + if (old_file_id != new_file_id) { + LOG_STATUS(td->file_manager_->merge(new_file_id, old_file_id)); + old_file_id = new_file_id; + return true; } - need_update = true; } - if (old_->caption != new_->caption || old_->has_spoiler != new_->has_spoiler) { - need_update = true; + break; + } + case MessageContentType::Sticker: { + auto content = static_cast(message_content); + if (new_file_id != content->file_id) { + td->stickers_manager_->merge_stickers(new_file_id, content->file_id); + content->file_id = new_file_id; + return true; + } + break; + } + case MessageContentType::Video: { + auto content = static_cast(message_content); + if (new_file_id != content->file_id) { + td->videos_manager_->merge_videos(new_file_id, content->file_id); + content->file_id = new_file_id; + return true; } break; } case MessageContentType::VideoNote: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->file_id != new_->file_id) { - if (need_merge_files) { - td->video_notes_manager_->merge_video_notes(new_->file_id, old_->file_id); + auto content = static_cast(message_content); + if (new_file_id != content->file_id) { + td->video_notes_manager_->merge_video_notes(new_file_id, content->file_id); + content->file_id = new_file_id; + return true; + } + break; + } + case MessageContentType::VoiceNote: { + auto content = static_cast(message_content); + if (new_file_id != content->file_id) { + td->voice_notes_manager_->merge_voice_notes(new_file_id, content->file_id); + content->file_id = new_file_id; + return true; + } + break; + } + case MessageContentType::Contact: + case MessageContentType::Game: + case MessageContentType::Invoice: + case MessageContentType::LiveLocation: + case MessageContentType::Location: + case MessageContentType::PaidMedia: + case MessageContentType::Story: + case MessageContentType::Text: + case MessageContentType::Venue: + case MessageContentType::ChatCreate: + case MessageContentType::ChatChangeTitle: + case MessageContentType::ChatChangePhoto: + case MessageContentType::ChatDeletePhoto: + case MessageContentType::ChatDeleteHistory: + case MessageContentType::ChatAddUsers: + case MessageContentType::ChatJoinedByLink: + case MessageContentType::ChatDeleteUser: + case MessageContentType::ChatMigrateTo: + case MessageContentType::ChannelCreate: + case MessageContentType::ChannelMigrateFrom: + case MessageContentType::PinMessage: + case MessageContentType::GameScore: + case MessageContentType::ScreenshotTaken: + case MessageContentType::ChatSetTtl: + case MessageContentType::Unsupported: + case MessageContentType::Call: + case MessageContentType::PaymentSuccessful: + case MessageContentType::ContactRegistered: + case MessageContentType::ExpiredPhoto: + case MessageContentType::ExpiredVideo: + case MessageContentType::CustomServiceAction: + case MessageContentType::WebsiteConnected: + case MessageContentType::PassportDataSent: + case MessageContentType::PassportDataReceived: + case MessageContentType::Poll: + case MessageContentType::Dice: + case MessageContentType::ProximityAlertTriggered: + case MessageContentType::GroupCall: + case MessageContentType::InviteToGroupCall: + case MessageContentType::ChatSetTheme: + case MessageContentType::WebViewDataSent: + case MessageContentType::WebViewDataReceived: + case MessageContentType::GiftPremium: + case MessageContentType::TopicCreate: + case MessageContentType::TopicEdit: + case MessageContentType::SuggestProfilePhoto: + case MessageContentType::WriteAccessAllowed: + case MessageContentType::RequestedDialog: + case MessageContentType::WebViewWriteAccessAllowed: + case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: + LOG(ERROR) << "Receive new file " << new_file_id << " in a sent message of the type " << content_type; + break; + default: + UNREACHABLE(); + break; + } + return false; +} + +void compare_message_contents(Td *td, const MessageContent *old_content, const MessageContent *new_content, + bool &is_content_changed, bool &need_update) { + if (old_content == nullptr) { + if (new_content != nullptr) { + need_update = true; + } + return; + } + MessageContentType content_type = old_content->get_type(); + if (new_content == nullptr || new_content->get_type() != content_type) { + need_update = true; + return; + } + + switch (content_type) { + case MessageContentType::Text: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->text.text != rhs->text.text || lhs->text.entities != rhs->text.entities || + lhs->web_page_url != rhs->web_page_url || lhs->force_small_media != rhs->force_small_media || + lhs->force_large_media != rhs->force_large_media) { + need_update = true; + } else if (lhs->web_page_id != rhs->web_page_id || + lhs->skip_web_page_confirmation != rhs->skip_web_page_confirmation) { + is_content_changed = true; + if (td == nullptr || td->web_pages_manager_->have_web_page(lhs->web_page_id) || + td->web_pages_manager_->have_web_page(rhs->web_page_id)) { + need_update = true; } + } + break; + } + case MessageContentType::Animation: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->file_id != rhs->file_id || lhs->caption != rhs->caption || lhs->has_spoiler != rhs->has_spoiler) { need_update = true; } - if (old_->is_viewed != new_->is_viewed) { + break; + } + case MessageContentType::Audio: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->file_id != rhs->file_id || lhs->caption != rhs->caption) { need_update = true; } break; } - case MessageContentType::VoiceNote: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->file_id != new_->file_id) { - if (need_merge_files) { - td->voice_notes_manager_->merge_voice_notes(new_->file_id, old_->file_id); - } + case MessageContentType::Contact: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->contact != rhs->contact) { need_update = true; } - if (old_->caption != new_->caption || old_->is_listened != new_->is_listened) { + break; + } + case MessageContentType::Document: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->file_id != rhs->file_id || lhs->caption != rhs->caption) { + need_update = true; + } + break; + } + case MessageContentType::Game: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->game != rhs->game) { + need_update = true; + } + break; + } + case MessageContentType::Invoice: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->input_invoice != rhs->input_invoice) { + need_update = true; + } else if (lhs->input_invoice.is_equal_but_different(rhs->input_invoice)) { + is_content_changed = true; + } + break; + } + case MessageContentType::LiveLocation: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->location != rhs->location || lhs->period != rhs->period || lhs->heading != rhs->heading || + lhs->proximity_alert_radius != rhs->proximity_alert_radius) { + need_update = true; + } else if (lhs->location.get_access_hash() != rhs->location.get_access_hash()) { + is_content_changed = true; + } + break; + } + case MessageContentType::Location: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->location != rhs->location) { + need_update = true; + } else if (lhs->location.get_access_hash() != rhs->location.get_access_hash()) { + is_content_changed = true; + } + break; + } + case MessageContentType::Photo: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->caption != rhs->caption || lhs->has_spoiler != rhs->has_spoiler) { + need_update = true; + } + break; + } + case MessageContentType::Sticker: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->file_id != rhs->file_id || lhs->is_premium != rhs->is_premium) { + need_update = true; + } + break; + } + case MessageContentType::Venue: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->venue != rhs->venue) { + need_update = true; + } else if (lhs->venue.location().get_access_hash() != rhs->venue.location().get_access_hash()) { + is_content_changed = true; + } + break; + } + case MessageContentType::Video: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->file_id != rhs->file_id || lhs->caption != rhs->caption || lhs->has_spoiler != rhs->has_spoiler) { + need_update = true; + } + break; + } + case MessageContentType::VideoNote: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->file_id != rhs->file_id || lhs->is_viewed != rhs->is_viewed) { + need_update = true; + } + break; + } + case MessageContentType::VoiceNote: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->file_id != rhs->file_id || lhs->caption != rhs->caption || lhs->is_listened != rhs->is_listened) { need_update = true; } break; } case MessageContentType::ChatCreate: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->title != new_->title || old_->participant_user_ids != new_->participant_user_ids) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->title != rhs->title || lhs->participant_user_ids != rhs->participant_user_ids) { need_update = true; } break; } case MessageContentType::ChatChangeTitle: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->title != new_->title) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->title != rhs->title) { need_update = true; } break; } case MessageContentType::ChatChangePhoto: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->photo != new_->photo) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->photo != rhs->photo) { need_update = true; } break; @@ -3636,66 +5508,65 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo case MessageContentType::ChatDeleteHistory: break; case MessageContentType::ChatAddUsers: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->user_ids != new_->user_ids) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->user_ids != rhs->user_ids) { need_update = true; } break; } case MessageContentType::ChatJoinedByLink: { - auto old_ = static_cast(old_content); - auto new_ = static_cast(new_content); - if (old_->is_approved != new_->is_approved) { + auto lhs = static_cast(old_content); + auto rhs = static_cast(new_content); + if (lhs->is_approved != rhs->is_approved) { need_update = true; } break; } case MessageContentType::ChatDeleteUser: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->user_id != new_->user_id) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->user_id != rhs->user_id) { need_update = true; } break; } case MessageContentType::ChatMigrateTo: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->migrated_to_channel_id != new_->migrated_to_channel_id) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->migrated_to_channel_id != rhs->migrated_to_channel_id) { need_update = true; } break; } case MessageContentType::ChannelCreate: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->title != new_->title) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->title != rhs->title) { need_update = true; } break; } case MessageContentType::ChannelMigrateFrom: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->title != new_->title || old_->migrated_from_chat_id != new_->migrated_from_chat_id) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->title != rhs->title || lhs->migrated_from_chat_id != rhs->migrated_from_chat_id) { need_update = true; } break; } case MessageContentType::PinMessage: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->message_id != new_->message_id) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->message_id != rhs->message_id) { need_update = true; } break; } case MessageContentType::GameScore: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->game_message_id != new_->game_message_id || old_->game_id != new_->game_id || - old_->score != new_->score) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->game_message_id != rhs->game_message_id || lhs->game_id != rhs->game_id || lhs->score != rhs->score) { need_update = true; } break; @@ -3703,40 +5574,35 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo case MessageContentType::ScreenshotTaken: break; case MessageContentType::ChatSetTtl: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->ttl != new_->ttl) { - LOG(ERROR) << "Message auto-delete time has changed from " << old_->ttl << " to " << new_->ttl; - need_update = true; - } - if (old_->from_user_id != new_->from_user_id) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->ttl != rhs->ttl || lhs->from_user_id != rhs->from_user_id) { need_update = true; } break; } case MessageContentType::Call: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->call_id != new_->call_id) { - is_content_changed = true; - } - if (old_->duration != new_->duration || old_->discard_reason != new_->discard_reason || - old_->is_video != new_->is_video) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->duration != rhs->duration || lhs->discard_reason != rhs->discard_reason || + lhs->is_video != rhs->is_video) { need_update = true; + } else if (lhs->call_id != rhs->call_id) { + is_content_changed = true; } break; } case MessageContentType::PaymentSuccessful: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->invoice_dialog_id != new_->invoice_dialog_id || old_->invoice_message_id != new_->invoice_message_id || - old_->currency != new_->currency || old_->total_amount != new_->total_amount || - old_->invoice_payload != new_->invoice_payload || old_->shipping_option_id != new_->shipping_option_id || - old_->telegram_payment_charge_id != new_->telegram_payment_charge_id || - old_->provider_payment_charge_id != new_->provider_payment_charge_id || - ((old_->order_info != nullptr || new_->order_info != nullptr) && - (old_->order_info == nullptr || new_->order_info == nullptr || *old_->order_info != *new_->order_info)) || - old_->is_recurring != new_->is_recurring || old_->is_first_recurring != new_->is_first_recurring) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->invoice_dialog_id != rhs->invoice_dialog_id || lhs->invoice_message_id != rhs->invoice_message_id || + lhs->currency != rhs->currency || lhs->total_amount != rhs->total_amount || + lhs->invoice_payload != rhs->invoice_payload || lhs->shipping_option_id != rhs->shipping_option_id || + lhs->telegram_payment_charge_id != rhs->telegram_payment_charge_id || + lhs->provider_payment_charge_id != rhs->provider_payment_charge_id || + ((lhs->order_info != nullptr || rhs->order_info != nullptr) && + (lhs->order_info == nullptr || rhs->order_info == nullptr || *lhs->order_info != *rhs->order_info)) || + lhs->is_recurring != rhs->is_recurring || lhs->is_first_recurring != rhs->is_first_recurring) { need_update = true; } break; @@ -3748,147 +5614,145 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo case MessageContentType::ExpiredVideo: break; case MessageContentType::CustomServiceAction: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->message != new_->message) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->message != rhs->message) { need_update = true; } break; } case MessageContentType::WebsiteConnected: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->domain_name != new_->domain_name) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->domain_name != rhs->domain_name) { need_update = true; } break; } case MessageContentType::PassportDataSent: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->types != new_->types) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->types != rhs->types) { need_update = true; } break; } case MessageContentType::PassportDataReceived: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->values != new_->values || old_->credentials != new_->credentials) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->values != rhs->values || lhs->credentials != rhs->credentials) { need_update = true; } break; } case MessageContentType::Poll: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->poll_id != new_->poll_id) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->poll_id != rhs->poll_id) { need_update = true; } break; } case MessageContentType::Dice: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->emoji != new_->emoji || old_->dice_value != new_->dice_value) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->emoji != rhs->emoji || lhs->dice_value != rhs->dice_value) { need_update = true; } break; } case MessageContentType::ProximityAlertTriggered: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->traveler_dialog_id != new_->traveler_dialog_id || old_->watcher_dialog_id != new_->watcher_dialog_id || - old_->distance != new_->distance) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->traveler_dialog_id != rhs->traveler_dialog_id || lhs->watcher_dialog_id != rhs->watcher_dialog_id || + lhs->distance != rhs->distance) { need_update = true; } break; } case MessageContentType::GroupCall: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->input_group_call_id != new_->input_group_call_id || old_->duration != new_->duration || - old_->schedule_date != new_->schedule_date) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->input_group_call_id != rhs->input_group_call_id || lhs->duration != rhs->duration || + lhs->schedule_date != rhs->schedule_date) { need_update = true; - } - if (!old_->input_group_call_id.is_identical(new_->input_group_call_id)) { + } else if (!lhs->input_group_call_id.is_identical(rhs->input_group_call_id)) { is_content_changed = true; } break; } case MessageContentType::InviteToGroupCall: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->input_group_call_id != new_->input_group_call_id || old_->user_ids != new_->user_ids) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->input_group_call_id != rhs->input_group_call_id || lhs->user_ids != rhs->user_ids) { need_update = true; - } - if (!old_->input_group_call_id.is_identical(new_->input_group_call_id)) { + } else if (!lhs->input_group_call_id.is_identical(rhs->input_group_call_id)) { is_content_changed = true; } break; } case MessageContentType::ChatSetTheme: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->emoji != new_->emoji) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->emoji != rhs->emoji) { need_update = true; } break; } case MessageContentType::WebViewDataSent: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->button_text != new_->button_text) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->button_text != rhs->button_text) { need_update = true; } break; } case MessageContentType::WebViewDataReceived: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->button_text != new_->button_text || old_->data != new_->data) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->button_text != rhs->button_text || lhs->data != rhs->data) { need_update = true; } break; } case MessageContentType::GiftPremium: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->currency != new_->currency || old_->amount != new_->amount || - old_->crypto_currency != new_->crypto_currency || old_->crypto_amount != new_->crypto_amount || - old_->months != new_->months) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->currency != rhs->currency || lhs->amount != rhs->amount || + lhs->crypto_currency != rhs->crypto_currency || lhs->crypto_amount != rhs->crypto_amount || + lhs->months != rhs->months) { need_update = true; } break; } case MessageContentType::TopicCreate: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->title != new_->title || old_->icon != new_->icon) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->title != rhs->title || lhs->icon != rhs->icon) { need_update = true; } break; } case MessageContentType::TopicEdit: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->edited_data != new_->edited_data) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->edited_data != rhs->edited_data) { need_update = true; } break; } case MessageContentType::Unsupported: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->version != new_->version) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->version != rhs->version) { is_content_changed = true; } break; } case MessageContentType::SuggestProfilePhoto: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->photo != new_->photo) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->photo != rhs->photo) { need_update = true; } break; @@ -3896,175 +5760,166 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo case MessageContentType::WriteAccessAllowed: break; case MessageContentType::RequestedDialog: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->dialog_id != new_->dialog_id || old_->button_id != new_->button_id) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->shared_dialog_ids != rhs->shared_dialog_ids || lhs->button_id != rhs->button_id) { need_update = true; } break; } case MessageContentType::WebViewWriteAccessAllowed: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->web_app != new_->web_app) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->web_app != rhs->web_app) { need_update = true; } break; } case MessageContentType::SetBackground: { - const auto *old_ = static_cast(old_content); - const auto *new_ = static_cast(new_content); - if (old_->old_message_id != new_->old_message_id || old_->background_info != new_->background_info) { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->old_message_id != rhs->old_message_id || lhs->background_info != rhs->background_info || + lhs->for_both != rhs->for_both) { need_update = true; } break; } - default: - UNREACHABLE(); + case MessageContentType::Story: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->story_full_id != rhs->story_full_id || lhs->via_mention != rhs->via_mention) { + need_update = true; + } break; - } -} - -bool merge_message_content_file_id(Td *td, MessageContent *message_content, FileId new_file_id) { - if (!new_file_id.is_valid()) { - return false; - } - - // secret chats only - LOG(INFO) << "Merge message content of a message with file " << new_file_id; - MessageContentType content_type = message_content->get_type(); - switch (content_type) { - case MessageContentType::Animation: { - auto content = static_cast(message_content); - if (new_file_id != content->file_id) { - td->animations_manager_->merge_animations(new_file_id, content->file_id); - content->file_id = new_file_id; - return true; + } + case MessageContentType::WriteAccessAllowedByRequest: + break; + case MessageContentType::GiftCode: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->creator_dialog_id != rhs->creator_dialog_id || lhs->months != rhs->months || + lhs->currency != rhs->currency || lhs->amount != rhs->amount || + lhs->crypto_currency != rhs->crypto_currency || lhs->crypto_amount != rhs->crypto_amount || + lhs->via_giveaway != rhs->via_giveaway || lhs->is_unclaimed != rhs->is_unclaimed || lhs->code != rhs->code) { + need_update = true; } break; } - case MessageContentType::Audio: { - auto content = static_cast(message_content); - if (new_file_id != content->file_id) { - td->audios_manager_->merge_audios(new_file_id, content->file_id); - content->file_id = new_file_id; - return true; + case MessageContentType::Giveaway: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->giveaway_parameters != rhs->giveaway_parameters || lhs->quantity != rhs->quantity || + lhs->months != rhs->months || lhs->star_count != rhs->star_count) { + need_update = true; } break; } - case MessageContentType::Document: { - auto content = static_cast(message_content); - if (new_file_id != content->file_id) { - td->documents_manager_->merge_documents(new_file_id, content->file_id); - content->file_id = new_file_id; - return true; + case MessageContentType::GiveawayLaunch: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->star_count != rhs->star_count) { + need_update = true; } break; } - case MessageContentType::Photo: { - auto content = static_cast(message_content); - Photo *photo = &content->photo; - if (!photo->photos.empty() && photo->photos.back().type == 'i') { - FileId &old_file_id = photo->photos.back().file_id; - if (old_file_id != new_file_id) { - LOG_STATUS(td->file_manager_->merge(new_file_id, old_file_id)); - old_file_id = new_file_id; - return true; - } + case MessageContentType::GiveawayResults: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->giveaway_message_id != rhs->giveaway_message_id || lhs->winner_count != rhs->winner_count || + lhs->unclaimed_count != rhs->unclaimed_count || lhs->is_star_giveaway != rhs->is_star_giveaway) { + need_update = true; } break; } - case MessageContentType::Sticker: { - auto content = static_cast(message_content); - if (new_file_id != content->file_id) { - td->stickers_manager_->merge_stickers(new_file_id, content->file_id); - content->file_id = new_file_id; - return true; + case MessageContentType::GiveawayWinners: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->giveaway_message_id != rhs->giveaway_message_id || lhs->boosted_channel_id != rhs->boosted_channel_id || + lhs->additional_dialog_count != rhs->additional_dialog_count || lhs->month_count != rhs->month_count || + lhs->star_count != rhs->star_count || lhs->prize_description != rhs->prize_description || + lhs->winners_selection_date != rhs->winners_selection_date || + lhs->only_new_subscribers != rhs->only_new_subscribers || lhs->was_refunded != rhs->was_refunded || + lhs->winner_count != rhs->winner_count || lhs->unclaimed_count != rhs->unclaimed_count || + lhs->winner_user_ids != rhs->winner_user_ids) { + need_update = true; } break; } - case MessageContentType::Video: { - auto content = static_cast(message_content); - if (new_file_id != content->file_id) { - td->videos_manager_->merge_videos(new_file_id, content->file_id); - content->file_id = new_file_id; - return true; + case MessageContentType::ExpiredVideoNote: + break; + case MessageContentType::ExpiredVoiceNote: + break; + case MessageContentType::BoostApply: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->boost_count != rhs->boost_count) { + need_update = true; } break; } - case MessageContentType::VideoNote: { - auto content = static_cast(message_content); - if (new_file_id != content->file_id) { - td->video_notes_manager_->merge_video_notes(new_file_id, content->file_id); - content->file_id = new_file_id; - return true; + case MessageContentType::DialogShared: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->shared_dialogs != rhs->shared_dialogs || lhs->button_id != rhs->button_id) { + need_update = true; } break; } - case MessageContentType::VoiceNote: { - auto content = static_cast(message_content); - if (new_file_id != content->file_id) { - td->voice_notes_manager_->merge_voice_notes(new_file_id, content->file_id); - content->file_id = new_file_id; - return true; + case MessageContentType::PaidMedia: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->caption != rhs->caption || lhs->star_count != rhs->star_count || + lhs->media.size() != rhs->media.size()) { + need_update = true; + } else { + for (size_t i = 0; i < lhs->media.size(); i++) { + if (lhs->media[i] != rhs->media[i]) { + need_update = true; + } else if (lhs->media[i].is_equal_but_different(rhs->media[i])) { + is_content_changed = true; + } + } + if (lhs->payload != rhs->payload) { + is_content_changed = true; + } } break; } - case MessageContentType::Contact: - case MessageContentType::Game: - case MessageContentType::Invoice: - case MessageContentType::LiveLocation: - case MessageContentType::Location: - case MessageContentType::Text: - case MessageContentType::Venue: - case MessageContentType::ChatCreate: - case MessageContentType::ChatChangeTitle: - case MessageContentType::ChatChangePhoto: - case MessageContentType::ChatDeletePhoto: - case MessageContentType::ChatDeleteHistory: - case MessageContentType::ChatAddUsers: - case MessageContentType::ChatJoinedByLink: - case MessageContentType::ChatDeleteUser: - case MessageContentType::ChatMigrateTo: - case MessageContentType::ChannelCreate: - case MessageContentType::ChannelMigrateFrom: - case MessageContentType::PinMessage: - case MessageContentType::GameScore: - case MessageContentType::ScreenshotTaken: - case MessageContentType::ChatSetTtl: - case MessageContentType::Unsupported: - case MessageContentType::Call: - case MessageContentType::PaymentSuccessful: - case MessageContentType::ContactRegistered: - case MessageContentType::ExpiredPhoto: - case MessageContentType::ExpiredVideo: - case MessageContentType::CustomServiceAction: - case MessageContentType::WebsiteConnected: - case MessageContentType::PassportDataSent: - case MessageContentType::PassportDataReceived: - case MessageContentType::Poll: - case MessageContentType::Dice: - case MessageContentType::ProximityAlertTriggered: - case MessageContentType::GroupCall: - case MessageContentType::InviteToGroupCall: - case MessageContentType::ChatSetTheme: - case MessageContentType::WebViewDataSent: - case MessageContentType::WebViewDataReceived: - case MessageContentType::GiftPremium: - case MessageContentType::TopicCreate: - case MessageContentType::TopicEdit: - case MessageContentType::SuggestProfilePhoto: - case MessageContentType::WriteAccessAllowed: - case MessageContentType::RequestedDialog: - case MessageContentType::WebViewWriteAccessAllowed: - case MessageContentType::SetBackground: - LOG(ERROR) << "Receive new file " << new_file_id << " in a sent message of the type " << content_type; + case MessageContentType::PaymentRefunded: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->dialog_id != rhs->dialog_id || lhs->currency != rhs->currency || + lhs->total_amount != rhs->total_amount || lhs->invoice_payload != rhs->invoice_payload || + lhs->telegram_payment_charge_id != rhs->telegram_payment_charge_id || + lhs->provider_payment_charge_id != rhs->provider_payment_charge_id) { + need_update = true; + } + break; + } + case MessageContentType::GiftStars: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->currency != rhs->currency || lhs->amount != rhs->amount || + lhs->crypto_currency != rhs->crypto_currency || lhs->crypto_amount != rhs->crypto_amount || + lhs->star_count != rhs->star_count || lhs->transaction_id != rhs->transaction_id) { + need_update = true; + } break; + } + case MessageContentType::PrizeStars: { + const auto *lhs = static_cast(old_content); + const auto *rhs = static_cast(new_content); + if (lhs->star_count != rhs->star_count || lhs->transaction_id != rhs->transaction_id || + lhs->boosted_dialog_id != rhs->boosted_dialog_id || lhs->giveaway_message_id != rhs->giveaway_message_id || + lhs->is_unclaimed != rhs->is_unclaimed) { + need_update = true; + } + break; + } default: UNREACHABLE(); break; } - return false; } static bool can_be_animated_emoji(const FormattedText &text) { @@ -4086,48 +5941,78 @@ static CustomEmojiId get_custom_emoji_id(const FormattedText &text) { return text.entities.empty() ? CustomEmojiId() : text.entities[0].custom_emoji_id; } -void register_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id, +static bool need_register_message_content_for_bots(MessageContentType content_type) { + return content_type == MessageContentType::Poll; +} + +void register_message_content(Td *td, const MessageContent *content, MessageFullId message_full_id, const char *source) { - switch (content->get_type()) { + auto content_type = content->get_type(); + if (td->auth_manager_->is_bot() && !need_register_message_content_for_bots(content_type)) { + return; + } + switch (content_type) { case MessageContentType::Text: { auto text = static_cast(content); if (text->web_page_id.is_valid()) { - td->web_pages_manager_->register_web_page(text->web_page_id, full_message_id, source); + td->web_pages_manager_->register_web_page(text->web_page_id, message_full_id, source); } else if (can_be_animated_emoji(text->text)) { - td->stickers_manager_->register_emoji(text->text.text, get_custom_emoji_id(text->text), full_message_id, + td->stickers_manager_->register_emoji(text->text.text, get_custom_emoji_id(text->text), message_full_id, {}, source); } return; } case MessageContentType::VideoNote: - return td->video_notes_manager_->register_video_note(static_cast(content)->file_id, - full_message_id, source); + return td->transcription_manager_->register_voice(static_cast(content)->file_id, + content_type, message_full_id, source); case MessageContentType::VoiceNote: - return td->voice_notes_manager_->register_voice_note(static_cast(content)->file_id, - full_message_id, source); + return td->transcription_manager_->register_voice(static_cast(content)->file_id, + content_type, message_full_id, source); case MessageContentType::Poll: - return td->poll_manager_->register_poll(static_cast(content)->poll_id, full_message_id, + return td->poll_manager_->register_poll(static_cast(content)->poll_id, message_full_id, source); case MessageContentType::Dice: { auto dice = static_cast(content); - return td->stickers_manager_->register_dice(dice->emoji, dice->dice_value, full_message_id, source); + return td->stickers_manager_->register_dice(dice->emoji, dice->dice_value, message_full_id, {}, source); } case MessageContentType::GiftPremium: - return td->stickers_manager_->register_premium_gift(static_cast(content)->months, - full_message_id, source); + return td->stickers_manager_->register_premium_gift(static_cast(content)->months, 0, + message_full_id, source); + case MessageContentType::GiftCode: + return td->stickers_manager_->register_premium_gift(static_cast(content)->months, 0, + message_full_id, source); + case MessageContentType::Giveaway: { + auto giveaway = static_cast(content); + return td->stickers_manager_->register_premium_gift(giveaway->months, giveaway->star_count, message_full_id, + source); + } case MessageContentType::SuggestProfilePhoto: - return td->contacts_manager_->register_suggested_profile_photo( + return td->user_manager_->register_suggested_profile_photo( static_cast(content)->photo); + case MessageContentType::Story: + return td->story_manager_->register_story(static_cast(content)->story_full_id, + message_full_id, {}, source); + case MessageContentType::GiftStars: { + auto star_count = static_cast(content)->star_count; + return td->stickers_manager_->register_premium_gift(0, star_count, message_full_id, source); + } + case MessageContentType::PrizeStars: { + auto star_count = static_cast(content)->star_count; + return td->stickers_manager_->register_premium_gift(0, star_count, message_full_id, source); + } default: return; } } void reregister_message_content(Td *td, const MessageContent *old_content, const MessageContent *new_content, - FullMessageId full_message_id, const char *source) { + MessageFullId message_full_id, const char *source) { auto old_content_type = old_content->get_type(); auto new_content_type = new_content->get_type(); if (old_content_type == new_content_type) { + if (td->auth_manager_->is_bot() && !need_register_message_content_for_bots(new_content_type)) { + return; + } switch (old_content_type) { case MessageContentType::Text: { auto old_text = static_cast(old_content); @@ -4171,43 +6056,166 @@ void reregister_message_content(Td *td, const MessageContent *old_content, const return; } break; + case MessageContentType::GiftCode: + if (static_cast(old_content)->months == + static_cast(new_content)->months) { + return; + } + break; + case MessageContentType::Giveaway: + if (static_cast(old_content)->months == + static_cast(new_content)->months && + static_cast(old_content)->star_count == + static_cast(new_content)->star_count) { + return; + } + break; + case MessageContentType::Story: + if (static_cast(old_content)->story_full_id == + static_cast(new_content)->story_full_id) { + return; + } + break; + case MessageContentType::GiftStars: + if (static_cast(old_content)->star_count == + static_cast(new_content)->star_count) { + return; + } + break; + case MessageContentType::PrizeStars: + if (static_cast(old_content)->star_count == + static_cast(new_content)->star_count) { + return; + } + break; default: return; } } - unregister_message_content(td, old_content, full_message_id, source); - register_message_content(td, new_content, full_message_id, source); + unregister_message_content(td, old_content, message_full_id, source); + register_message_content(td, new_content, message_full_id, source); } -void unregister_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id, +void unregister_message_content(Td *td, const MessageContent *content, MessageFullId message_full_id, const char *source) { - switch (content->get_type()) { + auto content_type = content->get_type(); + if (td->auth_manager_->is_bot() && !need_register_message_content_for_bots(content_type)) { + return; + } + switch (content_type) { case MessageContentType::Text: { auto text = static_cast(content); if (text->web_page_id.is_valid()) { - td->web_pages_manager_->unregister_web_page(text->web_page_id, full_message_id, source); + td->web_pages_manager_->unregister_web_page(text->web_page_id, message_full_id, source); } else if (can_be_animated_emoji(text->text)) { - td->stickers_manager_->unregister_emoji(text->text.text, get_custom_emoji_id(text->text), full_message_id, + td->stickers_manager_->unregister_emoji(text->text.text, get_custom_emoji_id(text->text), message_full_id, {}, source); } return; } case MessageContentType::VideoNote: - return td->video_notes_manager_->unregister_video_note(static_cast(content)->file_id, - full_message_id, source); + return td->transcription_manager_->unregister_voice(static_cast(content)->file_id, + content_type, message_full_id, source); case MessageContentType::VoiceNote: - return td->voice_notes_manager_->unregister_voice_note(static_cast(content)->file_id, - full_message_id, source); + return td->transcription_manager_->unregister_voice(static_cast(content)->file_id, + content_type, message_full_id, source); case MessageContentType::Poll: - return td->poll_manager_->unregister_poll(static_cast(content)->poll_id, full_message_id, + return td->poll_manager_->unregister_poll(static_cast(content)->poll_id, message_full_id, source); case MessageContentType::Dice: { auto dice = static_cast(content); - return td->stickers_manager_->unregister_dice(dice->emoji, dice->dice_value, full_message_id, source); + return td->stickers_manager_->unregister_dice(dice->emoji, dice->dice_value, message_full_id, {}, source); } case MessageContentType::GiftPremium: - return td->stickers_manager_->unregister_premium_gift(static_cast(content)->months, - full_message_id, source); + return td->stickers_manager_->unregister_premium_gift(static_cast(content)->months, 0, + message_full_id, source); + case MessageContentType::GiftCode: + return td->stickers_manager_->unregister_premium_gift(static_cast(content)->months, 0, + message_full_id, source); + case MessageContentType::Giveaway: { + auto giveaway = static_cast(content); + return td->stickers_manager_->unregister_premium_gift(giveaway->months, giveaway->star_count, message_full_id, + source); + } + case MessageContentType::Story: + return td->story_manager_->unregister_story(static_cast(content)->story_full_id, + message_full_id, {}, source); + case MessageContentType::GiftStars: { + auto star_count = static_cast(content)->star_count; + return td->stickers_manager_->unregister_premium_gift(0, star_count, message_full_id, source); + } + case MessageContentType::PrizeStars: { + auto star_count = static_cast(content)->star_count; + return td->stickers_manager_->unregister_premium_gift(0, star_count, message_full_id, source); + } + default: + return; + } +} + +void register_reply_message_content(Td *td, const MessageContent *content) { + switch (content->get_type()) { + case MessageContentType::Poll: + return td->poll_manager_->register_reply_poll(static_cast(content)->poll_id); + default: + return; + } +} + +void unregister_reply_message_content(Td *td, const MessageContent *content) { + switch (content->get_type()) { + case MessageContentType::Poll: + return td->poll_manager_->unregister_reply_poll(static_cast(content)->poll_id); + default: + return; + } +} + +void register_quick_reply_message_content(Td *td, const MessageContent *content, + QuickReplyMessageFullId message_full_id, const char *source) { + switch (content->get_type()) { + case MessageContentType::Text: { + auto text = static_cast(content); + if (text->web_page_id.is_valid()) { + td->web_pages_manager_->register_quick_reply_web_page(text->web_page_id, message_full_id, source); + } else if (can_be_animated_emoji(text->text)) { + td->stickers_manager_->register_emoji(text->text.text, get_custom_emoji_id(text->text), {}, message_full_id, + source); + } + return; + } + case MessageContentType::Dice: { + auto dice = static_cast(content); + return td->stickers_manager_->register_dice(dice->emoji, dice->dice_value, {}, message_full_id, source); + } + case MessageContentType::Story: + return td->story_manager_->register_story(static_cast(content)->story_full_id, {}, + message_full_id, source); + default: + return; + } +} + +void unregister_quick_reply_message_content(Td *td, const MessageContent *content, + QuickReplyMessageFullId message_full_id, const char *source) { + switch (content->get_type()) { + case MessageContentType::Text: { + auto text = static_cast(content); + if (text->web_page_id.is_valid()) { + td->web_pages_manager_->unregister_quick_reply_web_page(text->web_page_id, message_full_id, source); + } else if (can_be_animated_emoji(text->text)) { + td->stickers_manager_->unregister_emoji(text->text.text, get_custom_emoji_id(text->text), {}, message_full_id, + source); + } + return; + } + case MessageContentType::Dice: { + auto dice = static_cast(content); + return td->stickers_manager_->unregister_dice(dice->emoji, dice->dice_value, {}, message_full_id, source); + } + case MessageContentType::Story: + return td->story_manager_->unregister_story(static_cast(content)->story_full_id, {}, + message_full_id, source); default: return; } @@ -4254,7 +6262,7 @@ static auto secret_to_telegram(secret_api::documentAttributeAnimated &animated) // documentAttributeSticker23 = DocumentAttribute; static auto secret_to_telegram(secret_api::documentAttributeSticker23 &sticker) { return make_tl_object( - 0, false /*ignored*/, "", make_tl_object(), nullptr); + 0, false, "", make_tl_object(), nullptr); } static auto secret_to_telegram(secret_api::inputStickerSetEmpty &sticker_set) { @@ -4274,14 +6282,13 @@ static auto secret_to_telegram(secret_api::documentAttributeSticker &sticker) { sticker.alt_.clear(); } return make_tl_object( - 0, false /*ignored*/, sticker.alt_, secret_to_telegram(*sticker.stickerset_), - nullptr); + 0, false, sticker.alt_, secret_to_telegram(*sticker.stickerset_), nullptr); } // documentAttributeVideo23 duration:int w:int h:int = DocumentAttribute; static auto secret_to_telegram(secret_api::documentAttributeVideo23 &video) { - return make_tl_object(0, false /*ignored*/, false /*ignored*/, video.duration_, - video.w_, video.h_); + return make_tl_object(0, false, false, false, video.duration_, video.w_, + video.h_, 0, 0.0); } // documentAttributeFilename file_name:string = DocumentAttribute; @@ -4296,7 +6303,7 @@ static auto secret_to_telegram(secret_api::documentAttributeFilename &filename) static auto secret_to_telegram(secret_api::documentAttributeVideo &video) { return make_tl_object( video.round_message_ ? telegram_api::documentAttributeVideo::ROUND_MESSAGE_MASK : 0, video.round_message_, false, - video.duration_, video.w_, video.h_); + false, video.duration_, video.w_, video.h_, 0, 0.0); } static auto telegram_documentAttributeAudio(bool is_voice_note, int duration, string title, string performer, @@ -4521,9 +6528,9 @@ unique_ptr get_secret_message_content( media->venue_id_.clear(); } - auto m = make_unique(Venue(Location(media->lat_, media->long_, 0.0, 0), std::move(media->title_), - std::move(media->address_), std::move(media->provider_), - std::move(media->venue_id_), string())); + auto m = make_unique(Venue(Location(td, media->lat_, media->long_, 0.0, 0), + std::move(media->title_), std::move(media->address_), + std::move(media->provider_), std::move(media->venue_id_), string())); if (m->venue.empty()) { is_media_empty = true; break; @@ -4557,7 +6564,8 @@ unique_ptr get_secret_message_content( } auto url = r_http_url.ok().get_url(); - auto result = make_unique(FormattedText{std::move(message_text), std::move(entities)}, WebPageId()); + auto result = td::make_unique(FormattedText{std::move(message_text), std::move(entities)}, + WebPageId(), false, false, false, url); td->web_pages_manager_->get_web_page_by_url( url, PromiseCreator::lambda([&web_page_id = result->web_page_id, promise = load_data_multipromise.get_promise()]( @@ -4583,7 +6591,8 @@ unique_ptr get_secret_message_content( is_media_empty = true; } if (is_media_empty) { - return create_text_message_content(std::move(message_text), std::move(entities), WebPageId()); + return create_text_message_content(std::move(message_text), std::move(entities), WebPageId(), false, false, false, + string()); } switch (constructor_id) { case secret_api::decryptedMessageMediaPhoto::ID: { @@ -4623,9 +6632,10 @@ unique_ptr get_secret_message_content( unique_ptr get_message_content(Td *td, FormattedText message, tl_object_ptr &&media_ptr, - DialogId owner_dialog_id, bool is_content_read, UserId via_bot_user_id, - int32 *ttl, bool *disable_web_page_preview, const char *source) { - if (!td->auth_manager_->was_authorized() && !G()->close_flag() && media_ptr != nullptr && + DialogId owner_dialog_id, int32 message_date, bool is_content_read, + UserId via_bot_user_id, MessageSelfDestructType *ttl, + bool *disable_web_page_preview, const char *source) { + if (!G()->close_flag() && !td->auth_manager_->was_authorized() && media_ptr != nullptr && media_ptr->get_id() != telegram_api::messageMediaEmpty::ID) { LOG(ERROR) << "Receive without authorization from " << source << ": " << to_string(media_ptr); media_ptr = nullptr; @@ -4634,16 +6644,15 @@ unique_ptr get_message_content(Td *td, FormattedText message, *disable_web_page_preview = false; } - int32 constructor_id = media_ptr == nullptr ? telegram_api::messageMediaEmpty::ID : media_ptr->get_id(); - switch (constructor_id) { + switch (media_ptr == nullptr ? telegram_api::messageMediaEmpty::ID : media_ptr->get_id()) { case telegram_api::messageMediaEmpty::ID: if (message.text.empty()) { LOG(ERROR) << "Receive empty message text and media from " << source; } - if (disable_web_page_preview != nullptr) { + if (disable_web_page_preview != nullptr && !get_first_url(message).empty()) { *disable_web_page_preview = true; } - return make_unique(std::move(message), WebPageId()); + return td::make_unique(std::move(message), WebPageId(), false, false, false, string()); case telegram_api::messageMediaPhoto::ID: { auto media = move_tl_object_as(media_ptr); if (media->photo_ == nullptr) { @@ -4662,7 +6671,7 @@ unique_ptr get_message_content(Td *td, FormattedText message, } if (ttl != nullptr && (media->flags_ & telegram_api::messageMediaPhoto::TTL_SECONDS_MASK) != 0) { - *ttl = media->ttl_seconds_; + *ttl = MessageSelfDestructType(media->ttl_seconds_, true); } return make_unique(std::move(photo), std::move(message), media->spoiler_); } @@ -4679,7 +6688,7 @@ unique_ptr get_message_content(Td *td, FormattedText message, case telegram_api::messageMediaGeo::ID: { auto media = move_tl_object_as(media_ptr); - auto m = make_unique(Location(media->geo_)); + auto m = make_unique(Location(td, media->geo_)); if (m->location.empty()) { break; } @@ -4688,7 +6697,7 @@ unique_ptr get_message_content(Td *td, FormattedText message, } case telegram_api::messageMediaGeoLive::ID: { auto media = move_tl_object_as(media_ptr); - auto location = Location(media->geo_); + auto location = Location(td, media->geo_); if (location.empty()) { break; } @@ -4703,7 +6712,7 @@ unique_ptr get_message_content(Td *td, FormattedText message, } case telegram_api::messageMediaVenue::ID: { auto media = move_tl_object_as(media_ptr); - auto m = make_unique(Venue(media->geo_, std::move(media->title_), std::move(media->address_), + auto m = make_unique(Venue(td, media->geo_, std::move(media->title_), std::move(media->address_), std::move(media->provider_), std::move(media->venue_id_), std::move(media->venue_type_))); if (m->venue.empty()) { @@ -4715,8 +6724,8 @@ unique_ptr get_message_content(Td *td, FormattedText message, case telegram_api::messageMediaContact::ID: { auto media = move_tl_object_as(media_ptr); if (media->user_id_ != 0) { - td->contacts_manager_->get_user_id_object(UserId(media->user_id_), - "MessageMediaContact"); // to ensure updateUser + td->user_manager_->get_user_id_object(UserId(media->user_id_), + "MessageMediaContact"); // to ensure updateUser } return make_unique(Contact(std::move(media->phone_number_), std::move(media->first_name_), std::move(media->last_name_), std::move(media->vcard_), @@ -4730,6 +6739,17 @@ unique_ptr get_message_content(Td *td, FormattedText message, << oneline(to_string(media)); break; } + if (media->voice_) { + return make_unique(); + } + if (media->round_) { + return make_unique(); + } + if (media->video_) { + return make_unique(); + } + LOG(ERROR) << "Receive messageMediaDocument without document and media type from " << source << ": " + << oneline(to_string(media)); return make_unique(); } @@ -4742,7 +6762,7 @@ unique_ptr get_message_content(Td *td, FormattedText message, CHECK(document_id == telegram_api::document::ID); if (ttl != nullptr && (media->flags_ & telegram_api::messageMediaDocument::TTL_SECONDS_MASK) != 0) { - *ttl = media->ttl_seconds_; + *ttl = MessageSelfDestructType(media->ttl_seconds_, true); } return get_document_message_content(td, move_tl_object_as(document_ptr), owner_dialog_id, std::move(message), is_content_read, !media->nopremium_, media->spoiler_, @@ -4763,11 +6783,18 @@ unique_ptr get_message_content(Td *td, FormattedText message, move_tl_object_as(media_ptr), td, owner_dialog_id, std::move(message))); case telegram_api::messageMediaWebPage::ID: { auto media = move_tl_object_as(media_ptr); - if (disable_web_page_preview != nullptr) { - *disable_web_page_preview = (media->webpage_ == nullptr); + string web_page_url; + if (media->manual_ || media->force_small_media_ || media->force_large_media_) { + web_page_url = WebPagesManager::get_web_page_url(media->webpage_); + if (web_page_url.empty()) { + LOG(ERROR) << "Have no URL in " << to_string(media); + } + } else if (td->auth_manager_->is_bot()) { + web_page_url = WebPagesManager::get_web_page_url(media->webpage_); } auto web_page_id = td->web_pages_manager_->on_get_web_page(std::move(media->webpage_), owner_dialog_id); - return make_unique(std::move(message), web_page_id); + return td::make_unique(std::move(message), web_page_id, media->force_small_media_, + media->force_large_media_, media->safe_, std::move(web_page_url)); } case telegram_api::messageMediaPoll::ID: { auto media = move_tl_object_as(media_ptr); @@ -4778,6 +6805,84 @@ unique_ptr get_message_content(Td *td, FormattedText message, } return make_unique(poll_id); } + case telegram_api::messageMediaStory::ID: { + auto media = move_tl_object_as(media_ptr); + auto dialog_id = DialogId(media->peer_); + auto story_id = StoryId(media->id_); + auto story_full_id = StoryFullId(dialog_id, story_id); + if (!story_full_id.is_server()) { + LOG(ERROR) << "Receive " << to_string(media); + break; + } + if (media->story_ != nullptr && !td->auth_manager_->is_bot()) { + auto actual_story_id = td->story_manager_->on_get_story(dialog_id, std::move(media->story_)); + if (story_id != actual_story_id) { + LOG(ERROR) << "Receive " << actual_story_id << " instead of " << story_id; + } + } + td->dialog_manager_->force_create_dialog(dialog_id, "messageMediaStory", true); + return make_unique(story_full_id, media->via_mention_); + } + case telegram_api::messageMediaGiveaway::ID: { + auto media = move_tl_object_as(media_ptr); + vector channel_ids; + for (auto channel : media->channels_) { + ChannelId channel_id(channel); + if (channel_id.is_valid()) { + channel_ids.push_back(channel_id); + td->dialog_manager_->force_create_dialog(DialogId(channel_id), "messageMediaGiveaway", true); + } + } + if (channel_ids.empty() || media->quantity_ <= 0 || (media->months_ <= 0 && media->stars_ <= 0) || + media->until_date_ < 0) { + if (message_date >= 1700000000) { // approximate release date + LOG(ERROR) << "Receive " << to_string(media); + } + break; + } + auto boosted_channel_id = channel_ids[0]; + channel_ids.erase(channel_ids.begin()); + return td::make_unique( + GiveawayParameters{boosted_channel_id, std::move(channel_ids), media->only_new_subscribers_, + media->winners_are_visible_, media->until_date_, std::move(media->countries_iso2_), + std::move(media->prize_description_)}, + media->quantity_, media->months_, StarManager::get_star_count(media->stars_)); + } + case telegram_api::messageMediaGiveawayResults::ID: { + auto media = move_tl_object_as(media_ptr); + auto giveaway_message_id = MessageId(ServerMessageId(media->launch_msg_id_)); + auto boosted_channel_id = ChannelId(media->channel_id_); + if (!giveaway_message_id.is_valid() || !boosted_channel_id.is_valid() || media->additional_peers_count_ < 0 || + (media->months_ <= 0 && media->stars_ <= 0) || media->until_date_ <= 0 || media->winners_count_ < 0 || + media->unclaimed_count_ < 0) { + LOG(ERROR) << "Receive " << to_string(media); + break; + } + td->dialog_manager_->force_create_dialog(DialogId(boosted_channel_id), "messageMediaGiveawayResults", true); + vector winner_user_ids; + for (auto winner : media->winners_) { + UserId winner_user_id(winner); + if (winner_user_id.is_valid()) { + winner_user_ids.push_back(winner_user_id); + } else { + LOG(ERROR) << "Receive " << to_string(media); + break; + } + } + return td::make_unique( + giveaway_message_id, boosted_channel_id, media->additional_peers_count_, media->months_, + StarManager::get_star_count(media->stars_), std::move(media->prize_description_), media->until_date_, + media->only_new_subscribers_, media->refunded_, media->winners_count_, media->unclaimed_count_, + std::move(winner_user_ids)); + } + case telegram_api::messageMediaPaidMedia::ID: { + auto media = telegram_api::move_object_as(media_ptr); + auto extended_media = transform(std::move(media->extended_media_), [&](auto &&extended_media) { + return MessageExtendedMedia(td, std::move(extended_media), owner_dialog_id); + }); + return td::make_unique(std::move(extended_media), std::move(message), + StarManager::get_star_count(media->stars_amount_), string()); + } case telegram_api::messageMediaUnsupported::ID: return make_unique(); default: @@ -4785,10 +6890,10 @@ unique_ptr get_message_content(Td *td, FormattedText message, } // explicit empty media message - if (disable_web_page_preview != nullptr) { + if (disable_web_page_preview != nullptr && !get_first_url(message).empty()) { *disable_web_page_preview = true; } - return make_unique(std::move(message), WebPageId()); + return td::make_unique(std::move(message), WebPageId(), false, false, false, string()); } unique_ptr dup_message_content(Td *td, DialogId dialog_id, const MessageContent *content, @@ -4798,12 +6903,15 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const CHECK(type == MessageContentDupType::Copy || type == MessageContentDupType::ServerCopy); } if (type != MessageContentDupType::Forward && type != MessageContentDupType::SendViaBot && - !can_have_input_media(td, content, type == MessageContentDupType::ServerCopy)) { + !can_message_content_have_input_media(td, content, type == MessageContentDupType::ServerCopy)) { return nullptr; } bool to_secret = dialog_id.get_type() == DialogType::SecretChat; - auto fix_file_id = [dialog_id, to_secret, file_manager = td->file_manager_.get()](FileId file_id) { + bool need_dup = type != MessageContentDupType::ServerCopy && type != MessageContentDupType::Forward; + CHECK(!to_secret || need_dup); + auto fix_file_id = [dialog_id, to_secret, need_dup, file_manager = td->file_manager_.get()](FileId file_id) { + CHECK(need_dup); auto file_view = file_manager->get_file_view(file_id); if (to_secret && !file_view.is_encrypted_secret()) { file_id = file_manager->copy_file_id(file_id, FileType::Encrypted, dialog_id, "copy message content to secret"); @@ -4823,7 +6931,7 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const if (replace_caption) { result->caption = std::move(copy_options.new_caption); } - if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { + if (!need_dup || td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { return std::move(result); } result->file_id = td->animations_manager_->dup_animation(fix_file_id(result->file_id), result->file_id); @@ -4835,7 +6943,7 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const if (replace_caption) { result->caption = std::move(copy_options.new_caption); } - if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { + if (!need_dup || td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { return std::move(result); } result->file_id = td->audios_manager_->dup_audio(fix_file_id(result->file_id), result->file_id); @@ -4856,7 +6964,7 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const if (replace_caption) { result->caption = std::move(copy_options.new_caption); } - if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { + if (!need_dup || td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { return std::move(result); } result->file_id = td->documents_manager_->dup_document(fix_file_id(result->file_id), result->file_id); @@ -4865,6 +6973,16 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const } case MessageContentType::Game: return make_unique(*static_cast(content)); + case MessageContentType::Giveaway: + if (type != MessageContentDupType::Forward) { + return nullptr; + } + return make_unique(*static_cast(content)); + case MessageContentType::GiveawayWinners: + if (type != MessageContentDupType::Forward) { + return nullptr; + } + return make_unique(*static_cast(content)); case MessageContentType::Invoice: if (type == MessageContentDupType::Copy) { return nullptr; @@ -4878,6 +6996,23 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const } case MessageContentType::Location: return make_unique(*static_cast(content)); + case MessageContentType::PaidMedia: { + if (type == MessageContentDupType::Copy || type == MessageContentDupType::ServerCopy) { + return nullptr; + } + CHECK(!to_secret); + auto result = make_unique(*static_cast(content)); + if (replace_caption) { + result->caption = std::move(copy_options.new_caption); + } + if (type != MessageContentDupType::Forward) { + for (auto &media : result->media) { + media = media.dup_to_send(td, true); + CHECK(!media.is_empty()); + } + } + return result; + } case MessageContentType::Photo: { auto result = make_unique(*static_cast(content)); if (replace_caption) { @@ -4885,62 +7020,25 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const } CHECK(!result->photo.photos.empty()); - if ((result->photo.photos.size() > 2 || result->photo.photos.back().type != 'i') && !to_secret) { + if ((!need_dup || result->photo.photos.size() > 2 || result->photo.photos.back().type != 'i') && !to_secret) { // already sent photo // having remote location is not enough to have InputMedia, because the file may not have valid file_reference // also file_id needs to be duped, because upload can be called to repair the file_reference and every upload // request must have unique file_id - if (!td->auth_manager_->is_bot()) { + if (!td->auth_manager_->is_bot() && need_dup) { result->photo.photos.back().file_id = fix_file_id(result->photo.photos.back().file_id); } return std::move(result); } - // Find 'i' or largest - PhotoSize photo; - for (const auto &size : result->photo.photos) { - if (size.type == 'i') { - photo = size; - } - } - if (photo.type == 0) { - for (const auto &size : result->photo.photos) { - if (photo.type == 0 || photo < size) { - photo = size; - } - } - } - - // Find 't' or smallest - PhotoSize thumbnail; - for (const auto &size : result->photo.photos) { - if (size.type == 't') { - thumbnail = size; - } - } - if (thumbnail.type == 0) { - for (const auto &size : result->photo.photos) { - if (size.type != photo.type && (thumbnail.type == 0 || size < thumbnail)) { - thumbnail = size; - } - } - } - - result->photo.photos.clear(); - bool has_thumbnail = thumbnail.type != 0; - if (has_thumbnail) { - thumbnail.type = 't'; - result->photo.photos.push_back(std::move(thumbnail)); - } - photo.type = 'i'; - result->photo.photos.push_back(std::move(photo)); + result->photo = dup_photo(result->photo); if (photo_has_input_media(td->file_manager_.get(), result->photo, to_secret, td->auth_manager_->is_bot())) { return std::move(result); } result->photo.photos.back().file_id = fix_file_id(result->photo.photos.back().file_id); - if (has_thumbnail) { + if (result->photo.photos.size() > 1) { result->photo.photos[0].file_id = td->file_manager_->dup_file_id(result->photo.photos[0].file_id, "dup_message_content photo"); } @@ -4949,22 +7047,24 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const case MessageContentType::Poll: if (type == MessageContentDupType::Copy || type == MessageContentDupType::ServerCopy) { return make_unique( - td->poll_manager_->dup_poll(static_cast(content)->poll_id)); + td->poll_manager_->dup_poll(dialog_id, static_cast(content)->poll_id)); } else { return make_unique(*static_cast(content)); } case MessageContentType::Sticker: { auto result = make_unique(*static_cast(content)); result->is_premium = td->option_manager_->get_option_boolean("is_premium"); - if (td->stickers_manager_->has_input_media(result->file_id, to_secret)) { + if (!need_dup || td->stickers_manager_->has_input_media(result->file_id, to_secret)) { return std::move(result); } result->file_id = td->stickers_manager_->dup_sticker(fix_file_id(result->file_id), result->file_id); CHECK(result->file_id.is_valid()); return std::move(result); } + case MessageContentType::Story: + return make_unique(static_cast(content)->story_full_id, false); case MessageContentType::Text: { - auto result = make_unique(*static_cast(content)); + auto result = td::make_unique(*static_cast(content)); if (type == MessageContentDupType::Copy || type == MessageContentDupType::ServerCopy) { remove_unallowed_entities(td, result->text, dialog_id); } @@ -4977,7 +7077,7 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const if (replace_caption) { result->caption = std::move(copy_options.new_caption); } - if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { + if (!need_dup || td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { return std::move(result); } result->file_id = td->videos_manager_->dup_video(fix_file_id(result->file_id), result->file_id); @@ -4987,7 +7087,7 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const case MessageContentType::VideoNote: { auto result = make_unique(*static_cast(content)); result->is_viewed = false; - if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { + if (!need_dup || td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { return std::move(result); } result->file_id = td->video_notes_manager_->dup_video_note(fix_file_id(result->file_id), result->file_id); @@ -5000,7 +7100,7 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const result->caption = std::move(copy_options.new_caption); } result->is_listened = false; - if (td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { + if (!need_dup || td->documents_manager_->has_input_media(result->file_id, thumbnail_file_id, to_secret)) { return std::move(result); } result->file_id = td->voice_notes_manager_->dup_voice_note(fix_file_id(result->file_id), result->file_id); @@ -5046,6 +7146,17 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: return nullptr; default: UNREACHABLE(); @@ -5055,10 +7166,66 @@ unique_ptr dup_message_content(Td *td, DialogId dialog_id, const } unique_ptr get_action_message_content(Td *td, tl_object_ptr &&action_ptr, - DialogId owner_dialog_id, DialogId reply_in_dialog_id, - MessageId reply_to_message_id) { + DialogId owner_dialog_id, int32 message_date, + const RepliedMessageInfo &replied_message_info, + bool is_business_message) { CHECK(action_ptr != nullptr); - + if (is_business_message) { + switch (action_ptr->get_id()) { + case telegram_api::messageActionEmpty::ID: + case telegram_api::messageActionChatCreate::ID: + case telegram_api::messageActionChatEditTitle::ID: + case telegram_api::messageActionChatEditPhoto::ID: + case telegram_api::messageActionChatDeletePhoto::ID: + case telegram_api::messageActionChatAddUser::ID: + case telegram_api::messageActionChatJoinedByLink::ID: + case telegram_api::messageActionChatDeleteUser::ID: + case telegram_api::messageActionChatMigrateTo::ID: + case telegram_api::messageActionChannelCreate::ID: + case telegram_api::messageActionChannelMigrateFrom::ID: + case telegram_api::messageActionPaymentSent::ID: + case telegram_api::messageActionPaymentSentMe::ID: + case telegram_api::messageActionBotAllowed::ID: + case telegram_api::messageActionSecureValuesSent::ID: + case telegram_api::messageActionSecureValuesSentMe::ID: + case telegram_api::messageActionGroupCall::ID: + case telegram_api::messageActionInviteToGroupCall::ID: + case telegram_api::messageActionGroupCallScheduled::ID: + case telegram_api::messageActionChatJoinedByRequest::ID: + case telegram_api::messageActionWebViewDataSent::ID: + case telegram_api::messageActionWebViewDataSentMe::ID: + case telegram_api::messageActionTopicCreate::ID: + case telegram_api::messageActionTopicEdit::ID: + case telegram_api::messageActionRequestedPeer::ID: + case telegram_api::messageActionGiveawayLaunch::ID: + case telegram_api::messageActionGiveawayResults::ID: + case telegram_api::messageActionBoostApply::ID: + case telegram_api::messageActionPaymentRefunded::ID: + LOG(ERROR) << "Receive business " << to_string(action_ptr); + break; + case telegram_api::messageActionHistoryClear::ID: + case telegram_api::messageActionPinMessage::ID: + case telegram_api::messageActionGameScore::ID: + case telegram_api::messageActionPhoneCall::ID: + case telegram_api::messageActionScreenshotTaken::ID: + case telegram_api::messageActionCustomAction::ID: + case telegram_api::messageActionContactSignUp::ID: + case telegram_api::messageActionGeoProximityReached::ID: + case telegram_api::messageActionSetMessagesTTL::ID: + case telegram_api::messageActionSetChatTheme::ID: + case telegram_api::messageActionGiftPremium::ID: + case telegram_api::messageActionSuggestProfilePhoto::ID: + case telegram_api::messageActionSetChatWallPaper::ID: + case telegram_api::messageActionGiftCode::ID: + case telegram_api::messageActionRequestedPeerSentMe::ID: + case telegram_api::messageActionGiftStars::ID: + case telegram_api::messageActionPrizeStars::ID: + // ok + break; + default: + UNREACHABLE(); + } + } switch (action_ptr->get_id()) { case telegram_api::messageActionEmpty::ID: LOG(ERROR) << "Receive empty message action in " << owner_dialog_id; @@ -5091,12 +7258,10 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(std::move(photo)); } - case telegram_api::messageActionChatDeletePhoto::ID: { + case telegram_api::messageActionChatDeletePhoto::ID: return make_unique(); - } - case telegram_api::messageActionHistoryClear::ID: { + case telegram_api::messageActionHistoryClear::ID: return make_unique(); - } case telegram_api::messageActionChatAddUser::ID: { auto action = move_tl_object_as(action_ptr); @@ -5151,12 +7316,7 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(std::move(action->title_), chat_id); } case telegram_api::messageActionPinMessage::ID: { - if (reply_in_dialog_id.is_valid() && reply_in_dialog_id != owner_dialog_id) { - LOG(ERROR) << "Receive pinned message with " << reply_to_message_id << " in " << owner_dialog_id - << " in another " << reply_in_dialog_id; - reply_to_message_id = MessageId(); - reply_in_dialog_id = DialogId(); - } + auto reply_to_message_id = replied_message_info.get_same_chat_reply_to_message_id(true); if (!reply_to_message_id.is_valid()) { // possible in basic groups LOG(INFO) << "Receive pinned message with " << reply_to_message_id << " in " << owner_dialog_id; @@ -5165,12 +7325,7 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(reply_to_message_id); } case telegram_api::messageActionGameScore::ID: { - if (reply_in_dialog_id.is_valid() && reply_in_dialog_id != owner_dialog_id) { - LOG(ERROR) << "Receive game score with " << reply_to_message_id << " in " << owner_dialog_id << " in another " - << reply_in_dialog_id; - reply_to_message_id = MessageId(); - reply_in_dialog_id = DialogId(); - } + auto reply_to_message_id = replied_message_info.get_same_chat_reply_to_message_id(true); if (!reply_to_message_id.is_valid()) { // possible in basic groups LOG(INFO) << "Receive game score with " << reply_to_message_id << " in " << owner_dialog_id; @@ -5195,20 +7350,20 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(action_ptr); - if (!reply_to_message_id.is_valid()) { - if (reply_to_message_id != MessageId()) { - LOG(ERROR) << "Receive succesful payment message with " << reply_to_message_id << " in " << owner_dialog_id; + auto message_full_id = replied_message_info.get_reply_message_full_id(DialogId(), true); + if (!message_full_id.get_message_id().is_valid()) { + if (message_full_id.get_message_id() != MessageId()) { + LOG(ERROR) << "Receive successful payment message with " << message_full_id << " in " << owner_dialog_id; } - reply_in_dialog_id = DialogId(); - reply_to_message_id = MessageId(); + message_full_id = {}; } if (action->total_amount_ <= 0 || !check_currency_amount(action->total_amount_)) { LOG(ERROR) << "Receive invalid total amount " << action->total_amount_; action->total_amount_ = 0; } return td::make_unique( - reply_in_dialog_id, reply_to_message_id, std::move(action->currency_), action->total_amount_, - std::move(action->invoice_slug_), action->recurring_used_, action->recurring_init_); + message_full_id.get_dialog_id(), message_full_id.get_message_id(), std::move(action->currency_), + action->total_amount_, std::move(action->invoice_slug_), action->recurring_used_, action->recurring_init_); } case telegram_api::messageActionPaymentSentMe::ID: { if (!td->auth_manager_->is_bot()) { @@ -5229,9 +7384,8 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptrprovider_payment_charge_id = std::move(action->charge_->provider_charge_id_); return std::move(result); } - case telegram_api::messageActionScreenshotTaken::ID: { + case telegram_api::messageActionScreenshotTaken::ID: return make_unique(); - } case telegram_api::messageActionCustomAction::ID: { auto action = move_tl_object_as(action_ptr); return td::make_unique(std::move(action->message_)); @@ -5248,6 +7402,9 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr( WebApp(td, telegram_api::move_object_as(action->app_), owner_dialog_id)); } + if (action->from_request_) { + return td::make_unique(); + } return td::make_unique(); } case telegram_api::messageActionSecureValuesSent::ID: { @@ -5262,10 +7419,11 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptrfile_manager_.get(), std::move(action->values_)), get_encrypted_secure_credentials(std::move(action->credentials_))); } - case telegram_api::messageActionContactSignUp::ID: { - LOG_IF(ERROR, td->auth_manager_->is_bot()) << "Receive ContactRegistered in " << owner_dialog_id; + case telegram_api::messageActionContactSignUp::ID: + if (!is_business_message && td->auth_manager_->is_bot()) { + LOG(ERROR) << "Receive ContactRegistered in " << owner_dialog_id; + } return td::make_unique(); - } case telegram_api::messageActionGeoProximityReached::ID: { auto action = move_tl_object_as(action_ptr); DialogId traveler_id(action->from_id_); @@ -5357,7 +7515,7 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptrcrypto_amount_ = 0; } } else if (action->crypto_amount_ <= 0) { - LOG(ERROR) << "Receive invalid premium gift crypto price " << action->crypto_amount_; + LOG(ERROR) << "Receive invalid premium gift crypto amount " << action->crypto_amount_; action->crypto_amount_ = 0; } return td::make_unique(std::move(action->currency_), action->amount_, @@ -5388,84 +7546,192 @@ unique_ptr get_action_message_content(Td *td, tl_object_ptr(action_ptr); - DialogId dialog_id(action->peer_); - if (!dialog_id.is_valid()) { + vector shared_dialog_ids; + for (const auto &peer : action->peers_) { + DialogId dialog_id(peer); + if (dialog_id.is_valid()) { + shared_dialog_ids.push_back(dialog_id); + } + } + if (shared_dialog_ids.size() > 1) { + for (auto dialog_id : shared_dialog_ids) { + if (dialog_id.get_type() != DialogType::User) { + shared_dialog_ids.clear(); + break; + } + } + } + if (shared_dialog_ids.empty() || shared_dialog_ids.size() != action->peers_.size()) { LOG(ERROR) << "Receive invalid " << oneline(to_string(action)); break; } - return make_unique(dialog_id, action->button_id_); + return td::make_unique(std::move(shared_dialog_ids), action->button_id_); } case telegram_api::messageActionSetChatWallPaper::ID: { auto action = move_tl_object_as(action_ptr); - BackgroundInfo background_info(td, std::move(action->wallpaper_)); + BackgroundInfo background_info(td, std::move(action->wallpaper_), true); if (!background_info.is_valid()) { break; } - return make_unique(MessageId(), std::move(background_info)); + auto reply_to_message_id = replied_message_info.get_same_chat_reply_to_message_id(true); + if (!reply_to_message_id.is_valid() || !action->same_) { + reply_to_message_id = MessageId(); + } + return make_unique(reply_to_message_id, std::move(background_info), action->for_both_); + } + case telegram_api::messageActionGiveawayLaunch::ID: { + auto action = move_tl_object_as(action_ptr); + return td::make_unique(StarManager::get_star_count(action->stars_)); + } + case telegram_api::messageActionGiftCode::ID: { + auto action = move_tl_object_as(action_ptr); + DialogId dialog_id; + if (action->boost_peer_ != nullptr) { + dialog_id = DialogId(action->boost_peer_); + if (!dialog_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << oneline(to_string(action)); + break; + } + if (dialog_id.get_type() != DialogType::User) { + td->dialog_manager_->force_create_dialog(dialog_id, "messageActionGiftCode", true); + } + } + return td::make_unique(dialog_id, action->months_, std::move(action->currency_), action->amount_, + std::move(action->crypto_currency_), action->crypto_amount_, + action->via_giveaway_, action->unclaimed_, std::move(action->slug_)); } - case telegram_api::messageActionSetSameChatWallPaper::ID: { - if (reply_in_dialog_id.is_valid() && reply_in_dialog_id != owner_dialog_id) { - LOG(ERROR) << "Receive old background message with " << reply_to_message_id << " in " << owner_dialog_id - << " in another " << reply_in_dialog_id; + case telegram_api::messageActionGiveawayResults::ID: { + auto action = move_tl_object_as(action_ptr); + auto reply_to_message_id = replied_message_info.get_same_chat_reply_to_message_id(true); + if (!reply_to_message_id.is_valid() && reply_to_message_id != MessageId()) { + LOG(ERROR) << "Receive giveaway results message with " << reply_to_message_id << " in " << owner_dialog_id; reply_to_message_id = MessageId(); - reply_in_dialog_id = DialogId(); } - auto action = move_tl_object_as(action_ptr); - BackgroundInfo background_info(td, std::move(action->wallpaper_)); - if (!background_info.is_valid()) { + return td::make_unique(reply_to_message_id, action->winners_count_, + action->unclaimed_count_, action->stars_); + } + case telegram_api::messageActionBoostApply::ID: { + auto action = move_tl_object_as(action_ptr); + return make_unique(max(action->boosts_, 0)); + } + case telegram_api::messageActionRequestedPeerSentMe::ID: { + auto action = move_tl_object_as(action_ptr); + vector shared_dialogs; + for (auto &peer : action->peers_) { + SharedDialog shared_dialog(td, std::move(peer)); + if (shared_dialog.is_valid()) { + shared_dialogs.push_back(std::move(shared_dialog)); + } + } + if (shared_dialogs.size() > 1) { + for (auto shared_dialog : shared_dialogs) { + if (!shared_dialog.is_user()) { + shared_dialogs.clear(); + break; + } + } + } + if (shared_dialogs.empty() || shared_dialogs.size() != action->peers_.size()) { + LOG(ERROR) << "Receive invalid " << oneline(to_string(action)); + break; + } + + return td::make_unique(std::move(shared_dialogs), action->button_id_); + } + case telegram_api::messageActionPaymentRefunded::ID: { + auto action = move_tl_object_as(action_ptr); + if (action->total_amount_ <= 0 || !check_currency_amount(action->total_amount_)) { + LOG(ERROR) << "Receive invalid refunded payment amount " << action->total_amount_; + action->total_amount_ = 0; + } + return td::make_unique(DialogId(action->peer_), std::move(action->currency_), + action->total_amount_, action->payload_.as_slice().str(), + std::move(action->charge_->id_), + std::move(action->charge_->provider_charge_id_)); + } + case telegram_api::messageActionGiftStars::ID: { + auto action = move_tl_object_as(action_ptr); + if (action->amount_ <= 0 || !check_currency_amount(action->amount_)) { + LOG(ERROR) << "Receive invalid gifted star price " << action->amount_; + action->amount_ = 0; + } + if (action->crypto_currency_.empty()) { + if (action->crypto_amount_ != 0) { + LOG(ERROR) << "Receive gifted star crypto price " << action->crypto_amount_ << " without currency"; + action->crypto_amount_ = 0; + } + } else if (action->crypto_amount_ <= 0) { + LOG(ERROR) << "Receive invalid gifted star crypto amount " << action->crypto_amount_; + action->crypto_amount_ = 0; + } + return td::make_unique( + std::move(action->currency_), action->amount_, std::move(action->crypto_currency_), action->crypto_amount_, + StarManager::get_star_count(action->stars_), std::move(action->transaction_id_)); + } + case telegram_api::messageActionPrizeStars::ID: { + auto action = move_tl_object_as(action_ptr); + DialogId boosted_dialog_id = DialogId(action->boost_peer_); + if (!boosted_dialog_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << oneline(to_string(action)); break; } - return make_unique(reply_to_message_id, std::move(background_info)); + td->dialog_manager_->force_create_dialog(boosted_dialog_id, "messageActionPrizeStars", true); + return td::make_unique( + StarManager::get_star_count(action->stars_), std::move(action->transaction_id_), boosted_dialog_id, + MessageId(ServerMessageId(action->giveaway_msg_id_)), action->unclaimed_); } default: UNREACHABLE(); } // explicit empty or wrong action - return make_unique(FormattedText(), WebPageId()); + return td::make_unique(FormattedText(), WebPageId(), false, false, false, string()); } -tl_object_ptr get_message_content_object(const MessageContent *content, Td *td, - DialogId dialog_id, int32 message_date, - bool is_content_secret, bool skip_bot_commands, - int32 max_media_timestamp) { +td_api::object_ptr get_message_content_object(const MessageContent *content, Td *td, + DialogId dialog_id, bool is_server, + bool is_outgoing, int32 message_date, + bool is_content_secret, bool skip_bot_commands, + int32 max_media_timestamp, bool invert_media, + bool disable_web_page_preview) { CHECK(content != nullptr); + auto get_text_object = [&](const FormattedText &text) { + return get_formatted_text_object(is_server ? td->user_manager_.get() : nullptr, text, skip_bot_commands, + max_media_timestamp); + }; switch (content->get_type()) { case MessageContentType::Animation: { const auto *m = static_cast(content); - return make_tl_object( - td->animations_manager_->get_animation_object(m->file_id), - get_formatted_text_object(m->caption, skip_bot_commands, max_media_timestamp), m->has_spoiler, - is_content_secret); + return make_tl_object(td->animations_manager_->get_animation_object(m->file_id), + get_text_object(m->caption), invert_media, m->has_spoiler, + is_content_secret); } case MessageContentType::Audio: { const auto *m = static_cast(content); - return make_tl_object( - td->audios_manager_->get_audio_object(m->file_id), - get_formatted_text_object(m->caption, skip_bot_commands, max_media_timestamp)); + return make_tl_object(td->audios_manager_->get_audio_object(m->file_id), + get_text_object(m->caption)); } case MessageContentType::Contact: { const auto *m = static_cast(content); - return make_tl_object(m->contact.get_contact_object()); + return make_tl_object(m->contact.get_contact_object(td)); } case MessageContentType::Document: { const auto *m = static_cast(content); return make_tl_object( - td->documents_manager_->get_document_object(m->file_id, PhotoFormat::Jpeg), - get_formatted_text_object(m->caption, skip_bot_commands, max_media_timestamp)); + td->documents_manager_->get_document_object(m->file_id, PhotoFormat::Jpeg), get_text_object(m->caption)); } case MessageContentType::Game: { const auto *m = static_cast(content); - return make_tl_object(m->game.get_game_object(td, skip_bot_commands)); + return make_tl_object(m->game.get_game_object(td, is_server, skip_bot_commands)); } case MessageContentType::Invoice: { const auto *m = static_cast(content); - return m->input_invoice.get_message_invoice_object(td, skip_bot_commands, max_media_timestamp); + return m->input_invoice.get_message_invoice_object(td, is_server, skip_bot_commands, max_media_timestamp); } case MessageContentType::LiveLocation: { const auto *m = static_cast(content); - auto passed = max(G()->unix_time_cached() - message_date, 0); - auto expires_in = max(0, m->period - passed); + auto passed = max(G()->unix_time() - message_date, 0); + auto expires_in = m->period == std::numeric_limits::max() ? m->period : max(0, m->period - passed); auto heading = expires_in == 0 ? 0 : m->heading; auto proximity_alert_radius = expires_in == 0 ? 0 : m->proximity_alert_radius; return make_tl_object(m->location.get_location_object(), m->period, expires_in, heading, @@ -5482,9 +7748,8 @@ tl_object_ptr get_message_content_object(const MessageCo LOG(ERROR) << "Have empty " << m->photo; return make_tl_object(); } - auto caption = get_formatted_text_object(m->caption, skip_bot_commands, max_media_timestamp); - return make_tl_object(std::move(photo), std::move(caption), m->has_spoiler, - is_content_secret); + return make_tl_object(std::move(photo), get_text_object(m->caption), invert_media, + m->has_spoiler, is_content_secret); } case MessageContentType::Sticker: { const auto *m = static_cast(content); @@ -5504,9 +7769,25 @@ tl_object_ptr get_message_content_object(const MessageCo return td_api::make_object(std::move(animated_emoji), m->text.text); } } - return make_tl_object( - get_formatted_text_object(m->text, skip_bot_commands, max_media_timestamp), - td->web_pages_manager_->get_web_page_object(m->web_page_id)); + auto web_page = td->web_pages_manager_->get_link_preview_object( + m->web_page_id, m->force_small_media, m->force_large_media, m->skip_web_page_confirmation, invert_media); + if (web_page != nullptr && !web_page->skip_confirmation_ && is_visible_url(m->text, web_page->url_)) { + web_page->skip_confirmation_ = true; + } + if (web_page == nullptr && get_first_url(m->text).empty()) { + disable_web_page_preview = false; + } else if (disable_web_page_preview && web_page != nullptr) { + LOG(ERROR) << "Have " << m->web_page_id << " in a message with link preview disabled"; + web_page = nullptr; + } + td_api::object_ptr link_preview_options; + if (disable_web_page_preview || !m->web_page_url.empty() || m->force_small_media || m->force_large_media || + invert_media) { + link_preview_options = td_api::make_object( + disable_web_page_preview, m->web_page_url, m->force_small_media, m->force_large_media, invert_media); + } + return make_tl_object(get_text_object(m->text), std::move(web_page), + std::move(link_preview_options)); } case MessageContentType::Unsupported: return make_tl_object(); @@ -5516,10 +7797,9 @@ tl_object_ptr get_message_content_object(const MessageCo } case MessageContentType::Video: { const auto *m = static_cast(content); - return make_tl_object( - td->videos_manager_->get_video_object(m->file_id), - get_formatted_text_object(m->caption, skip_bot_commands, max_media_timestamp), m->has_spoiler, - is_content_secret); + return make_tl_object(td->videos_manager_->get_video_object(m->file_id), + get_text_object(m->caption), invert_media, m->has_spoiler, + is_content_secret); } case MessageContentType::VideoNote: { const auto *m = static_cast(content); @@ -5528,14 +7808,13 @@ tl_object_ptr get_message_content_object(const MessageCo } case MessageContentType::VoiceNote: { const auto *m = static_cast(content); - return make_tl_object( - td->voice_notes_manager_->get_voice_note_object(m->file_id), - get_formatted_text_object(m->caption, skip_bot_commands, max_media_timestamp), m->is_listened); + return make_tl_object(td->voice_notes_manager_->get_voice_note_object(m->file_id), + get_text_object(m->caption), m->is_listened); } case MessageContentType::ChatCreate: { const auto *m = static_cast(content); return make_tl_object( - m->title, td->contacts_manager_->get_user_ids_object(m->participant_user_ids, "MessageChatCreate")); + m->title, td->user_manager_->get_user_ids_object(m->participant_user_ids, "MessageChatCreate")); } case MessageContentType::ChatChangeTitle: { const auto *m = static_cast(content); @@ -5557,7 +7836,7 @@ tl_object_ptr get_message_content_object(const MessageCo case MessageContentType::ChatAddUsers: { const auto *m = static_cast(content); return make_tl_object( - td->contacts_manager_->get_user_ids_object(m->user_ids, "MessageChatAddUsers")); + td->user_manager_->get_user_ids_object(m->user_ids, "MessageChatAddUsers")); } case MessageContentType::ChatJoinedByLink: { const MessageChatJoinedByLink *m = static_cast(content); @@ -5569,12 +7848,12 @@ tl_object_ptr get_message_content_object(const MessageCo case MessageContentType::ChatDeleteUser: { const auto *m = static_cast(content); return make_tl_object( - td->contacts_manager_->get_user_id_object(m->user_id, "MessageChatDeleteMember")); + td->user_manager_->get_user_id_object(m->user_id, "MessageChatDeleteMember")); } case MessageContentType::ChatMigrateTo: { const auto *m = static_cast(content); return make_tl_object( - td->contacts_manager_->get_supergroup_id_object(m->migrated_to_channel_id, "MessageChatUpgradeTo")); + td->chat_manager_->get_supergroup_id_object(m->migrated_to_channel_id, "MessageChatUpgradeTo")); } case MessageContentType::ChannelCreate: { const auto *m = static_cast(content); @@ -5583,8 +7862,7 @@ tl_object_ptr get_message_content_object(const MessageCo case MessageContentType::ChannelMigrateFrom: { const auto *m = static_cast(content); return make_tl_object( - m->title, - td->contacts_manager_->get_basic_group_id_object(m->migrated_from_chat_id, "MessageChatUpgradeFrom")); + m->title, td->chat_manager_->get_basic_group_id_object(m->migrated_from_chat_id, "MessageChatUpgradeFrom")); } case MessageContentType::PinMessage: { const auto *m = static_cast(content); @@ -5599,7 +7877,7 @@ tl_object_ptr get_message_content_object(const MessageCo case MessageContentType::ChatSetTtl: { const auto *m = static_cast(content); return make_tl_object( - m->ttl, td->contacts_manager_->get_user_id_object(m->from_user_id, "MessageChatSetTtl")); + m->ttl, td->user_manager_->get_user_id_object(m->from_user_id, "MessageChatSetTtl")); } case MessageContentType::Call: { const auto *m = static_cast(content); @@ -5616,7 +7894,7 @@ tl_object_ptr get_message_content_object(const MessageCo } else { auto invoice_dialog_id = m->invoice_dialog_id.is_valid() ? m->invoice_dialog_id : dialog_id; return make_tl_object( - td->messages_manager_->get_chat_id_object(invoice_dialog_id, "messagePaymentSuccessful"), + td->dialog_manager_->get_chat_id_object(invoice_dialog_id, "messagePaymentSuccessful"), m->invoice_message_id.get(), m->currency, m->total_amount, m->is_recurring, m->is_first_recurring, m->invoice_payload); } @@ -5633,7 +7911,8 @@ tl_object_ptr get_message_content_object(const MessageCo } case MessageContentType::WebsiteConnected: { const auto *m = static_cast(content); - return make_tl_object(m->domain_name); + return td_api::make_object( + td_api::make_object(m->domain_name)); } case MessageContentType::PassportDataSent: { const auto *m = static_cast(content); @@ -5682,7 +7961,7 @@ tl_object_ptr get_message_content_object(const MessageCo const auto *m = static_cast(content); return make_tl_object( td->group_call_manager_->get_group_call_id(m->input_group_call_id, DialogId()).get(), - td->contacts_manager_->get_user_ids_object(m->user_ids, "MessageInviteToGroupCall")); + td->user_manager_->get_user_ids_object(m->user_ids, "MessageInviteToGroupCall")); } case MessageContentType::ChatSetTheme: { const auto *m = static_cast(content); @@ -5699,16 +7978,23 @@ tl_object_ptr get_message_content_object(const MessageCo case MessageContentType::GiftPremium: { const auto *m = static_cast(content); int64 gifter_user_id = 0; + int64 receiver_user_id = 0; if (dialog_id.get_type() == DialogType::User) { auto user_id = dialog_id.get_user_id(); - if (user_id != ContactsManager::get_service_notifications_user_id() && - !td->contacts_manager_->is_user_bot(user_id) && !td->contacts_manager_->is_user_support(user_id)) { - gifter_user_id = td->contacts_manager_->get_user_id_object(user_id, "MessageGiftPremium"); + if (is_outgoing) { + receiver_user_id = td->user_manager_->get_user_id_object(user_id, "MessageGiftPremium 2"); + } else { + if (user_id != UserManager::get_service_notifications_user_id() && !td->user_manager_->is_user_bot(user_id) && + !td->user_manager_->is_user_support(user_id)) { + gifter_user_id = td->user_manager_->get_user_id_object(user_id, "MessageGiftPremium 3"); + } } + } else { + LOG(ERROR) << "Receive gifted premium in " << dialog_id; } - return make_tl_object( - gifter_user_id, m->currency, m->amount, m->crypto_currency, m->crypto_amount, m->months, - td->stickers_manager_->get_premium_gift_sticker_object(m->months)); + return td_api::make_object( + gifter_user_id, receiver_user_id, m->currency, m->amount, m->crypto_currency, m->crypto_amount, m->months, + td->stickers_manager_->get_premium_gift_sticker_object(m->months, 0)); } case MessageContentType::TopicCreate: { const auto *m = static_cast(content); @@ -5728,34 +8014,147 @@ tl_object_ptr get_message_content_object(const MessageCo return make_tl_object(std::move(photo)); } case MessageContentType::WriteAccessAllowed: - return make_tl_object(nullptr); + return td_api::make_object( + td_api::make_object()); case MessageContentType::RequestedDialog: { const auto *m = static_cast(content); - if (m->dialog_id.get_type() == DialogType::User) { - int64 user_id; - if (td->auth_manager_->is_bot()) { - user_id = m->dialog_id.get_user_id().get(); - } else { - user_id = td->contacts_manager_->get_user_id_object(m->dialog_id.get_user_id(), "MessageRequestedDialog"); + CHECK(!m->shared_dialog_ids.empty()); + if (m->shared_dialog_ids[0].get_type() == DialogType::User) { + vector> users; + for (auto shared_dialog_id : m->shared_dialog_ids) { + users.push_back(SharedDialog(shared_dialog_id).get_shared_user_object(td)); } - return make_tl_object(user_id, m->button_id); + return make_tl_object(std::move(users), m->button_id); } - int64 chat_id; - if (td->auth_manager_->is_bot()) { - chat_id = m->dialog_id.get(); - } else { - chat_id = td->messages_manager_->get_chat_id_object(m->dialog_id, "messageChatShared"); - } - return make_tl_object(chat_id, m->button_id); + CHECK(m->shared_dialog_ids.size() == 1); + return make_tl_object(SharedDialog(m->shared_dialog_ids[0]).get_shared_chat_object(td), + m->button_id); } case MessageContentType::WebViewWriteAccessAllowed: { const auto *m = static_cast(content); - return td_api::make_object(m->web_app.get_web_app_object(td)); + return td_api::make_object( + td_api::make_object(m->web_app.get_web_app_object(td))); } case MessageContentType::SetBackground: { const auto *m = static_cast(content); - return td_api::make_object(m->old_message_id.get(), - m->background_info.get_chat_background_object(td)); + return td_api::make_object( + m->old_message_id.get(), m->background_info.get_chat_background_object(td), !m->for_both); + } + case MessageContentType::Story: { + const auto *m = static_cast(content); + return td_api::make_object( + td->dialog_manager_->get_chat_id_object(m->story_full_id.get_dialog_id(), "messageStory"), + m->story_full_id.get_story_id().get(), m->via_mention); + } + case MessageContentType::WriteAccessAllowedByRequest: + return td_api::make_object( + td_api::make_object()); + case MessageContentType::GiftCode: { + const auto *m = static_cast(content); + return td_api::make_object( + m->creator_dialog_id.is_valid() + ? get_message_sender_object(td, m->creator_dialog_id, "messagePremiumGiftCode") + : nullptr, + m->via_giveaway, m->is_unclaimed, m->currency, m->amount, m->crypto_currency, m->crypto_amount, m->months, + td->stickers_manager_->get_premium_gift_sticker_object(m->months, 0), m->code); + } + case MessageContentType::Giveaway: { + const auto *m = static_cast(content); + td_api::object_ptr prize; + if (m->months != 0) { + prize = td_api::make_object(m->months); + } else { + prize = td_api::make_object(m->star_count); + } + return td_api::make_object( + m->giveaway_parameters.get_giveaway_parameters_object(td), m->quantity, std::move(prize), + td->stickers_manager_->get_premium_gift_sticker_object(m->months, m->star_count)); + } + case MessageContentType::GiveawayLaunch: { + const auto *m = static_cast(content); + return td_api::make_object(m->star_count); + } + case MessageContentType::GiveawayResults: { + const auto *m = static_cast(content); + return td_api::make_object(m->giveaway_message_id.get(), m->winner_count, + m->is_star_giveaway, m->unclaimed_count); + } + case MessageContentType::GiveawayWinners: { + const auto *m = static_cast(content); + td_api::object_ptr prize; + if (m->month_count != 0) { + prize = td_api::make_object(m->month_count); + } else { + prize = td_api::make_object(m->star_count); + } + return td_api::make_object( + td->dialog_manager_->get_chat_id_object(DialogId(m->boosted_channel_id), "messageGiveawayWinners"), + m->giveaway_message_id.get(), m->additional_dialog_count, m->winners_selection_date, m->only_new_subscribers, + m->was_refunded, std::move(prize), m->prize_description, m->winner_count, + td->user_manager_->get_user_ids_object(m->winner_user_ids, "messageGiveawayWinners"), m->unclaimed_count); + } + case MessageContentType::ExpiredVideoNote: + return make_tl_object(); + case MessageContentType::ExpiredVoiceNote: + return make_tl_object(); + case MessageContentType::BoostApply: { + const auto *m = static_cast(content); + return td_api::make_object(m->boost_count); + } + case MessageContentType::DialogShared: { + const auto *m = static_cast(content); + CHECK(!m->shared_dialogs.empty()); + if (m->shared_dialogs[0].is_user()) { + vector> users; + for (const auto &shared_dialog : m->shared_dialogs) { + users.push_back(shared_dialog.get_shared_user_object(td)); + } + return td_api::make_object(std::move(users), m->button_id); + } + CHECK(m->shared_dialogs.size() == 1); + return td_api::make_object(m->shared_dialogs[0].get_shared_chat_object(td), + m->button_id); + } + case MessageContentType::PaidMedia: { + const auto *m = static_cast(content); + return td_api::make_object( + m->star_count, transform(m->media, [&](const auto &media) { return media.get_paid_media_object(td); }), + get_text_object(m->caption), invert_media); + } + case MessageContentType::PaymentRefunded: { + const auto *m = static_cast(content); + return td_api::make_object( + get_message_sender_object(td, m->dialog_id, "messagePaymentRefunded"), m->currency, m->total_amount, + m->invoice_payload, m->telegram_payment_charge_id, m->provider_payment_charge_id); + } + case MessageContentType::GiftStars: { + const auto *m = static_cast(content); + int64 gifter_user_id = 0; + int64 receiver_user_id = 0; + if (dialog_id.get_type() == DialogType::User) { + auto user_id = dialog_id.get_user_id(); + if (is_outgoing) { + receiver_user_id = td->user_manager_->get_user_id_object(user_id, "MessageGiftStars 2"); + } else { + if (user_id != UserManager::get_service_notifications_user_id() && !td->user_manager_->is_user_bot(user_id) && + !td->user_manager_->is_user_support(user_id)) { + gifter_user_id = td->user_manager_->get_user_id_object(user_id, "MessageGiftStars 3"); + } + } + } else { + LOG(ERROR) << "Receive gifted stars in " << dialog_id; + } + return td_api::make_object( + gifter_user_id, receiver_user_id, m->currency, m->amount, m->crypto_currency, m->crypto_amount, m->star_count, + m->transaction_id, td->stickers_manager_->get_premium_gift_sticker_object(0, m->star_count)); + } + case MessageContentType::PrizeStars: { + const auto *m = static_cast(content); + return td_api::make_object( + m->star_count, m->transaction_id, + td->dialog_manager_->get_chat_id_object(m->boosted_dialog_id, "messageGiveawayPrizeStars"), + m->giveaway_message_id.get(), m->is_unclaimed, + td->stickers_manager_->get_premium_gift_sticker_object(0, m->star_count)); } default: UNREACHABLE(); @@ -5790,6 +8189,8 @@ const FormattedText *get_message_content_caption(const MessageContent *content) return &static_cast(content)->caption; case MessageContentType::Invoice: return static_cast(content)->input_invoice.get_caption(); + case MessageContentType::PaidMedia: + return &static_cast(content)->caption; case MessageContentType::Photo: return &static_cast(content)->caption; case MessageContentType::Video: @@ -5801,7 +8202,7 @@ const FormattedText *get_message_content_caption(const MessageContent *content) } } -bool get_message_content_has_spoiler(const MessageContent *content) { +static bool get_message_content_has_spoiler(const MessageContent *content) { switch (content->get_type()) { case MessageContentType::Animation: return static_cast(content)->has_spoiler; @@ -5814,7 +8215,7 @@ bool get_message_content_has_spoiler(const MessageContent *content) { } } -void set_message_content_has_spoiler(MessageContent *content, bool has_spoiler) { +static void set_message_content_has_spoiler(MessageContent *content, bool has_spoiler) { switch (content->get_type()) { case MessageContentType::Animation: static_cast(content)->has_spoiler = has_spoiler; @@ -5830,6 +8231,43 @@ void set_message_content_has_spoiler(MessageContent *content, bool has_spoiler) } } +unique_ptr get_uploaded_message_content( + Td *td, const MessageContent *old_content, int32 media_pos, + telegram_api::object_ptr &&media_ptr, DialogId owner_dialog_id, int32 message_date, + const char *source) { + if (media_pos >= 0) { + CHECK(old_content->get_type() == MessageContentType::PaidMedia); + auto paid_media = static_cast(old_content); + CHECK(static_cast(media_pos) < paid_media->media.size()); + auto content = make_unique(*paid_media); + auto media = MessageExtendedMedia(td, std::move(media_ptr), owner_dialog_id); + if (!media.has_input_media()) { + LOG(ERROR) << "Receive invalid uploaded paid media"; + } else { + bool is_content_changed = false; + bool need_update = false; + content->media[media_pos].merge_files(td, media, owner_dialog_id, true, is_content_changed, need_update); + } + return content; + } + auto caption = get_message_content_caption(old_content); + auto has_spoiler = get_message_content_has_spoiler(old_content); + auto content = get_message_content(td, caption == nullptr ? FormattedText() : *caption, std::move(media_ptr), + owner_dialog_id, message_date, false, UserId(), nullptr, nullptr, source); + set_message_content_has_spoiler(content.get(), has_spoiler); + return content; +} + +int64 get_message_content_star_count(const MessageContent *content) { + CHECK(content->get_type() == MessageContentType::PaidMedia); + return static_cast(content)->star_count; +} + +string get_message_content_payload(const MessageContent *content) { + CHECK(content->get_type() == MessageContentType::PaidMedia); + return static_cast(content)->payload; +} + int32 get_message_content_duration(const MessageContent *content, const Td *td) { CHECK(content != nullptr); switch (content->get_type()) { @@ -5843,6 +8281,13 @@ int32 get_message_content_duration(const MessageContent *content, const Td *td) } case MessageContentType::Invoice: return static_cast(content)->input_invoice.get_duration(td); + case MessageContentType::PaidMedia: { + int32 result = -1; + for (auto &media : static_cast(content)->media) { + result = max(result, media.get_duration(td)); + } + return result; + } case MessageContentType::Video: { auto video_file_id = static_cast(content)->file_id; return td->videos_manager_->get_video_duration(video_file_id); @@ -5856,7 +8301,7 @@ int32 get_message_content_duration(const MessageContent *content, const Td *td) return td->voice_notes_manager_->get_voice_note_duration(voice_file_id); } default: - return 0; + return -1; } } @@ -5869,6 +8314,17 @@ int32 get_message_content_media_duration(const MessageContent *content, const Td } case MessageContentType::Invoice: return static_cast(content)->input_invoice.get_duration(td); + case MessageContentType::PaidMedia: { + int32 result = -1; + for (const auto &media : static_cast(content)->media) { + result = max(result, media.get_duration(td)); + } + return result; + } + case MessageContentType::Story: { + auto story_full_id = static_cast(content)->story_full_id; + return td->story_manager_->get_story_duration(story_full_id); + } case MessageContentType::Text: { auto web_page_id = static_cast(content)->web_page_id; return td->web_pages_manager_->get_web_page_media_duration(web_page_id); @@ -5920,12 +8376,27 @@ FileId get_message_content_upload_file_id(const MessageContent *content) { return static_cast(content)->file_id; case MessageContentType::VoiceNote: return static_cast(content)->file_id; + case MessageContentType::PaidMedia: + UNREACHABLE(); + break; default: break; } return FileId(); } +vector get_message_content_upload_file_ids(const MessageContent *content) { + if (content->get_type() == MessageContentType::PaidMedia) { + return transform(static_cast(content)->media, + [](const MessageExtendedMedia &media) { return media.get_upload_file_id(); }); + } + auto file_id = get_message_content_upload_file_id(content); + if (file_id.is_valid()) { + return {file_id}; + } + return {}; +} + FileId get_message_content_any_file_id(const MessageContent *content) { FileId result = get_message_content_upload_file_id(content); if (!result.is_valid()) { @@ -5938,6 +8409,18 @@ FileId get_message_content_any_file_id(const MessageContent *content) { return result; } +vector get_message_content_any_file_ids(const MessageContent *content) { + if (content->get_type() == MessageContentType::PaidMedia) { + return transform(static_cast(content)->media, + [](const MessageExtendedMedia &media) { return media.get_any_file_id(); }); + } + auto file_id = get_message_content_any_file_id(content); + if (file_id.is_valid()) { + return {file_id}; + } + return {}; +} + void update_message_content_file_id_remote(MessageContent *content, FileId file_id) { if (file_id.get_remote() == 0) { return; @@ -5958,6 +8441,9 @@ void update_message_content_file_id_remote(MessageContent *content, FileId file_ return &static_cast(content)->file_id; case MessageContentType::VoiceNote: return &static_cast(content)->file_id; + case MessageContentType::PaidMedia: + UNREACHABLE(); + return static_cast(nullptr); default: return static_cast(nullptr); } @@ -5967,6 +8453,23 @@ void update_message_content_file_id_remote(MessageContent *content, FileId file_ } } +void update_message_content_file_id_remotes(MessageContent *content, const vector &file_ids) { + if (content->get_type() == MessageContentType::PaidMedia) { + auto &media = static_cast(content)->media; + if (file_ids.size() != media.size()) { + return; + } + for (size_t i = 0; i < file_ids.size(); i++) { + media[i].update_file_id_remote(file_ids[i]); + } + return; + } + if (file_ids.size() != 1) { + return; + } + update_message_content_file_id_remote(content, file_ids[0]); +} + FileId get_message_content_thumbnail_file_id(const MessageContent *content, const Td *td) { switch (content->get_type()) { case MessageContentType::Animation: @@ -5991,13 +8494,29 @@ FileId get_message_content_thumbnail_file_id(const MessageContent *content, cons static_cast(content)->file_id); case MessageContentType::VoiceNote: return FileId(); + case MessageContentType::PaidMedia: + UNREACHABLE(); + return FileId(); default: break; } return FileId(); } +vector get_message_content_thumbnail_file_ids(const MessageContent *content, const Td *td) { + if (content->get_type() == MessageContentType::PaidMedia) { + return transform(static_cast(content)->media, + [&](const MessageExtendedMedia &media) { return media.get_thumbnail_file_id(td); }); + } + auto file_id = get_message_content_thumbnail_file_id(content, td); + if (file_id.is_valid()) { + return {file_id}; + } + return {}; +} + vector get_message_content_file_ids(const MessageContent *content, const Td *td) { + CHECK(content != nullptr); switch (content->get_type()) { case MessageContentType::Photo: return photo_get_file_ids(static_cast(content)->photo); @@ -6064,11 +8583,33 @@ vector get_message_content_file_ids(const MessageContent *content, const case MessageContentType::SetBackground: // background file references are repaired independently return {}; + case MessageContentType::Story: + // story file references are repaired independently + return {}; + case MessageContentType::PaidMedia: { + vector result; + for (const auto &media : static_cast(content)->media) { + media.append_file_ids(td, result); + } + return result; + } default: return {}; } } +StoryFullId get_message_content_story_full_id(const Td *td, const MessageContent *content) { + CHECK(content != nullptr); + switch (content->get_type()) { + case MessageContentType::Text: + return td->web_pages_manager_->get_web_page_story_full_id(static_cast(content)->web_page_id); + case MessageContentType::Story: + return static_cast(content)->story_full_id; + default: + return StoryFullId(); + } +} + string get_message_content_search_text(const Td *td, const MessageContent *content) { switch (content->get_type()) { case MessageContentType::Text: { @@ -6096,6 +8637,10 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte const auto *invoice = static_cast(content); return invoice->input_invoice.get_caption()->text; } + case MessageContentType::PaidMedia: { + const auto *paid_media = static_cast(content); + return paid_media->caption.text; + } case MessageContentType::Photo: { const auto *photo = static_cast(content); return photo->caption.text; @@ -6121,6 +8666,7 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte case MessageContentType::LiveLocation: case MessageContentType::Location: case MessageContentType::Sticker: + case MessageContentType::Story: case MessageContentType::Unsupported: case MessageContentType::Venue: case MessageContentType::VideoNote: @@ -6162,6 +8708,19 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: return string(); default: UNREACHABLE(); @@ -6169,24 +8728,62 @@ string get_message_content_search_text(const Td *td, const MessageContent *conte } } -bool update_message_content_extended_media(MessageContent *content, - telegram_api::object_ptr extended_media, - DialogId owner_dialog_id, Td *td) { +bool update_message_content_extended_media( + MessageContent *content, vector> extended_media, + DialogId owner_dialog_id, Td *td) { CHECK(content != nullptr); - CHECK(content->get_type() == MessageContentType::Invoice); - return static_cast(content)->input_invoice.update_extended_media(std::move(extended_media), - owner_dialog_id, td); + switch (content->get_type()) { + case MessageContentType::Invoice: + if (extended_media.size() != 1) { + LOG(ERROR) << "Receive " << extended_media.size() << " extended media in " << owner_dialog_id; + return false; + } + return static_cast(content)->input_invoice.update_extended_media(std::move(extended_media[0]), + owner_dialog_id, td); + case MessageContentType::PaidMedia: { + auto &media = static_cast(content)->media; + if (extended_media.size() != media.size()) { + LOG(ERROR) << "Receive " << extended_media.size() << " paid media instead of " << media.size() << " in " + << owner_dialog_id; + return false; + } + bool result = false; + for (size_t i = 0; i < media.size(); i++) { + if (media[i].update_to(td, std::move(extended_media[i]), owner_dialog_id)) { + result = true; + } + } + return result; + } + case MessageContentType::Unsupported: + return false; + default: + LOG(ERROR) << "Receive updateMessageExtendedMedia for a message of type " << content->get_type() << " in " + << owner_dialog_id; + return false; + } } bool need_poll_message_content_extended_media(const MessageContent *content) { CHECK(content != nullptr); - if (content->get_type() != MessageContentType::Invoice) { - return false; + switch (content->get_type()) { + case MessageContentType::Invoice: + return static_cast(content)->input_invoice.need_poll_extended_media(); + case MessageContentType::PaidMedia: { + const auto &media = static_cast(content)->media; + for (auto &extended_media : media) { + if (extended_media.need_poll()) { + return true; + } + } + return false; + } + default: + return false; } - return static_cast(content)->input_invoice.need_poll_extended_media(); } -void get_message_content_animated_emoji_click_sticker(const MessageContent *content, FullMessageId full_message_id, +void get_message_content_animated_emoji_click_sticker(const MessageContent *content, MessageFullId message_full_id, Td *td, Promise> &&promise) { if (content->get_type() != MessageContentType::Text) { return promise.set_error(Status::Error(400, "Message is not an animated emoji message")); @@ -6196,10 +8793,10 @@ void get_message_content_animated_emoji_click_sticker(const MessageContent *cont if (!can_be_animated_emoji(text)) { return promise.set_error(Status::Error(400, "Message is not an animated emoji message")); } - td->stickers_manager_->get_animated_emoji_click_sticker(text.text, full_message_id, std::move(promise)); + td->stickers_manager_->get_animated_emoji_click_sticker(text.text, message_full_id, std::move(promise)); } -void on_message_content_animated_emoji_clicked(const MessageContent *content, FullMessageId full_message_id, Td *td, +void on_message_content_animated_emoji_clicked(const MessageContent *content, MessageFullId message_full_id, Td *td, string &&emoji, string &&data) { if (content->get_type() != MessageContentType::Text) { return; @@ -6210,7 +8807,7 @@ void on_message_content_animated_emoji_clicked(const MessageContent *content, Fu if (!text.entities.empty() || remove_emoji_modifiers(text.text) != emoji) { return; } - auto error = td->stickers_manager_->on_animated_emoji_message_clicked(std::move(emoji), full_message_id, data); + auto error = td->stickers_manager_->on_animated_emoji_message_clicked(std::move(emoji), message_full_id, data); if (error.is_error()) { LOG(WARNING) << "Failed to process animated emoji click with data \"" << data << "\": " << error; } @@ -6227,6 +8824,15 @@ bool need_reget_message_content(const MessageContent *content) { const auto *m = static_cast(content); return m->input_invoice.need_reget(); } + case MessageContentType::PaidMedia: { + const auto *m = static_cast(content); + for (const auto &media : m->media) { + if (media.need_reget()) { + return true; + } + } + return false; + } default: return false; } @@ -6261,16 +8867,22 @@ void update_expired_message_content(unique_ptr &content) { case MessageContentType::Unsupported: // can happen if message content file identifier is broken break; + case MessageContentType::VideoNote: + content = make_unique(); + break; + case MessageContentType::VoiceNote: + content = make_unique(); + break; case MessageContentType::ExpiredPhoto: case MessageContentType::ExpiredVideo: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: // can happen if message content has been reget from somewhere break; case MessageContentType::Animation: case MessageContentType::Audio: case MessageContentType::Document: case MessageContentType::Sticker: - case MessageContentType::VideoNote: - case MessageContentType::VoiceNote: // can happen if server will send a document with a wrong content content = make_unique(); break; @@ -6296,6 +8908,7 @@ void update_failed_to_send_message_content(Td *td, unique_ptr &c } void add_message_content_dependencies(Dependencies &dependencies, const MessageContent *message_content, bool is_bot) { + CHECK(message_content != nullptr); switch (message_content->get_type()) { case MessageContentType::Text: { const auto *content = static_cast(message_content); @@ -6450,10 +9063,12 @@ void add_message_content_dependencies(Dependencies &dependencies, const MessageC case MessageContentType::RequestedDialog: { const auto *content = static_cast(message_content); if (!is_bot) { - if (content->dialog_id.get_type() == DialogType::User) { - dependencies.add(content->dialog_id.get_user_id()); - } else { - dependencies.add_dialog_and_dependencies(content->dialog_id); + for (auto dialog_id : content->shared_dialog_ids) { + if (dialog_id.get_type() == DialogType::User) { + dependencies.add(dialog_id.get_user_id()); + } else { + dependencies.add_dialog_and_dependencies(dialog_id); + } } } break; @@ -6462,6 +9077,57 @@ void add_message_content_dependencies(Dependencies &dependencies, const MessageC break; case MessageContentType::SetBackground: break; + case MessageContentType::Story: { + const auto *content = static_cast(message_content); + dependencies.add(content->story_full_id); + break; + } + case MessageContentType::WriteAccessAllowedByRequest: + break; + case MessageContentType::GiftCode: { + const auto *content = static_cast(message_content); + dependencies.add_message_sender_dependencies(content->creator_dialog_id); + break; + } + case MessageContentType::Giveaway: { + const auto *content = static_cast(message_content); + content->giveaway_parameters.add_dependencies(dependencies); + break; + } + case MessageContentType::GiveawayLaunch: + break; + case MessageContentType::GiveawayResults: + break; + case MessageContentType::GiveawayWinners: { + const auto *content = static_cast(message_content); + dependencies.add_dialog_and_dependencies(DialogId(content->boosted_channel_id)); + for (auto &user_id : content->winner_user_ids) { + dependencies.add(user_id); + } + break; + } + case MessageContentType::ExpiredVideoNote: + break; + case MessageContentType::ExpiredVoiceNote: + break; + case MessageContentType::BoostApply: + break; + case MessageContentType::DialogShared: + break; + case MessageContentType::PaidMedia: + break; + case MessageContentType::PaymentRefunded: { + const auto *content = static_cast(message_content); + dependencies.add_message_sender_dependencies(content->dialog_id); + break; + } + case MessageContentType::GiftStars: + break; + case MessageContentType::PrizeStars: { + const auto *content = static_cast(message_content); + dependencies.add_dialog_and_dependencies(DialogId(content->boosted_dialog_id)); + break; + } default: UNREACHABLE(); break; @@ -6518,19 +9184,6 @@ void move_message_content_sticker_set_to_top(Td *td, const MessageContent *conte } } -bool is_unsent_animated_emoji_click(Td *td, DialogId dialog_id, const DialogAction &action) { - auto emoji = action.get_watching_animations_emoji(); - if (emoji.empty()) { - // not a WatchingAnimations action - return false; - } - return !td->stickers_manager_->is_sent_animated_emoji_click(dialog_id, remove_emoji_modifiers(emoji)); -} - -void init_stickers_manager(Td *td) { - td->stickers_manager_->init(); -} - void on_dialog_used(TopDialogCategory category, DialogId dialog_id, int32 date) { send_closure(G()->top_dialog_manager(), &TopDialogManager::on_dialog_used, category, dialog_id, date); } @@ -6567,28 +9220,4 @@ void update_used_hashtags(Td *td, const MessageContent *content) { } } -void recognize_message_content_speech(Td *td, const MessageContent *content, FullMessageId full_message_id, - Promise &&promise) { - switch (content->get_type()) { - case MessageContentType::VideoNote: - return td->video_notes_manager_->recognize_speech(full_message_id, std::move(promise)); - case MessageContentType::VoiceNote: - return td->voice_notes_manager_->recognize_speech(full_message_id, std::move(promise)); - default: - return promise.set_error(Status::Error(400, "Invalid message specified")); - } -} - -void rate_message_content_speech_recognition(Td *td, const MessageContent *content, FullMessageId full_message_id, - bool is_good, Promise &&promise) { - switch (content->get_type()) { - case MessageContentType::VideoNote: - return td->video_notes_manager_->rate_speech_recognition(full_message_id, is_good, std::move(promise)); - case MessageContentType::VoiceNote: - return td->voice_notes_manager_->rate_speech_recognition(full_message_id, is_good, std::move(promise)); - default: - return promise.set_error(Status::Error(400, "Invalid message specified")); - } -} - } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageContent.h b/protocols/Telegram/tdlib/td/td/telegram/MessageContent.h index cb743ff9e0..4d9a861e46 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageContent.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageContent.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,21 +7,25 @@ #pragma once #include "td/telegram/BackgroundInfo.h" +#include "td/telegram/ChannelId.h" #include "td/telegram/DialogId.h" #include "td/telegram/EncryptedFile.h" #include "td/telegram/files/FileId.h" -#include "td/telegram/FullMessageId.h" #include "td/telegram/InputGroupCallId.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/MessageContentType.h" #include "td/telegram/MessageCopyOptions.h" #include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/MessageId.h" +#include "td/telegram/MessageSelfDestructType.h" #include "td/telegram/Photo.h" +#include "td/telegram/QuickReplyMessageFullId.h" #include "td/telegram/ReplyMarkup.h" #include "td/telegram/secret_api.h" #include "td/telegram/SecretInputMedia.h" #include "td/telegram/StickerType.h" +#include "td/telegram/StoryFullId.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/TopDialogCategory.h" @@ -38,13 +42,14 @@ namespace td { class Dependencies; -class DialogAction; class Game; class MultiPromiseActor; struct Photo; +class RepliedMessageInfo; class Td; +class Venue; -// Do not forget to update merge_message_contents when one of the inheritors of this class changes +// Do not forget to update merge_message_contents and compare_message_contents when one of the inheritors of this class changes class MessageContent { public: MessageContent() = default; @@ -60,15 +65,17 @@ class MessageContent { struct InputMessageContent { unique_ptr content; bool disable_web_page_preview = false; + bool invert_media = false; bool clear_draft = false; - int32 ttl = 0; + MessageSelfDestructType ttl; UserId via_bot_user_id; string emoji; - InputMessageContent(unique_ptr &&content, bool disable_web_page_preview, bool clear_draft, int32 ttl, - UserId via_bot_user_id, string emoji) + InputMessageContent(unique_ptr &&content, bool disable_web_page_preview, bool invert_media, + bool clear_draft, MessageSelfDestructType ttl, UserId via_bot_user_id, string emoji) : content(std::move(content)) , disable_web_page_preview(disable_web_page_preview) + , invert_media(invert_media) , clear_draft(clear_draft) , ttl(ttl) , via_bot_user_id(via_bot_user_id) @@ -80,6 +87,7 @@ struct InlineMessageContent { unique_ptr message_content; unique_ptr message_reply_markup; bool disable_web_page_preview; + bool invert_media; }; void store_message_content(const MessageContent *content, LogEventStorerCalcLength &storer); @@ -93,7 +101,13 @@ InlineMessageContent create_inline_message_content(Td *td, FileId file_id, int32 allowed_media_content_id, Photo *photo, Game *game); unique_ptr create_text_message_content(string text, vector entities, - WebPageId web_page_id); + WebPageId web_page_id, bool force_small_media, + bool force_large_media, bool skip_confitmation, + string &&web_page_url); + +unique_ptr create_photo_message_content(Photo photo); + +unique_ptr create_video_message_content(FileId file_id); unique_ptr create_contact_registered_message_content(); @@ -101,30 +115,45 @@ unique_ptr create_screenshot_taken_message_content(); unique_ptr create_chat_set_ttl_message_content(int32 ttl, UserId from_user_id); +td_api::object_ptr extract_input_caption( + td_api::object_ptr &input_message_content); + +bool extract_input_invert_media(const td_api::object_ptr &input_message_content); + Result get_input_message_content( DialogId dialog_id, tl_object_ptr &&input_message_content, Td *td, bool is_premium); -bool can_have_input_media(const Td *td, const MessageContent *content, bool is_server); +Status check_message_group_message_contents(const vector &message_contents); + +bool can_message_content_have_input_media(const Td *td, const MessageContent *content, bool is_server); + +SecretInputMedia get_message_content_secret_input_media( + const MessageContent *content, Td *td, telegram_api::object_ptr input_file, + BufferSlice thumbnail, int32 layer); + +telegram_api::object_ptr get_message_content_input_media( + const MessageContent *content, int32 media_pos, Td *td, + telegram_api::object_ptr input_file, + telegram_api::object_ptr input_thumbnail, FileId file_id, FileId thumbnail_file_id, + MessageSelfDestructType ttl, const string &emoji, bool force); -SecretInputMedia get_secret_input_media(const MessageContent *content, Td *td, - tl_object_ptr input_file, - BufferSlice thumbnail, int32 layer); +telegram_api::object_ptr get_message_content_input_media(const MessageContent *content, + Td *td, MessageSelfDestructType ttl, + const string &emoji, bool force, + int32 media_pos = -1); -tl_object_ptr get_input_media(const MessageContent *content, Td *td, - tl_object_ptr input_file, - tl_object_ptr input_thumbnail, - FileId file_id, FileId thumbnail_file_id, int32 ttl, - const string &emoji, bool force); +telegram_api::object_ptr get_message_content_fake_input_media( + Td *td, telegram_api::object_ptr input_file, FileId file_id); -tl_object_ptr get_input_media(const MessageContent *content, Td *td, int32 ttl, - const string &emoji, bool force); +telegram_api::object_ptr get_message_content_input_media_web_page( + const Td *td, const MessageContent *content); -tl_object_ptr get_fake_input_media(Td *td, tl_object_ptr input_file, - FileId file_id); +bool is_uploaded_input_media(telegram_api::object_ptr &input_media); -void delete_message_content_thumbnail(MessageContent *content, Td *td); +void delete_message_content_thumbnail(MessageContent *content, Td *td, int32 media_pos = -1); -Status can_send_message_content(DialogId dialog_id, const MessageContent *content, bool is_forward, const Td *td); +Status can_send_message_content(DialogId dialog_id, const MessageContent *content, bool is_forward, + bool check_permissions, const Td *td); bool can_forward_message_content(const MessageContent *content); @@ -132,19 +161,23 @@ bool update_opened_message_content(MessageContent *content); int32 get_message_content_index_mask(const MessageContent *content, const Td *td, bool is_outgoing); +vector> get_individual_message_contents(const MessageContent *content); + StickerType get_message_content_sticker_type(const Td *td, const MessageContent *content); MessageId get_message_content_pinned_message_id(const MessageContent *content); -BackgroundInfo get_message_content_background_info(const MessageContent *content); +BackgroundInfo get_message_content_my_background_info(const MessageContent *content, bool is_outgoing); string get_message_content_theme_name(const MessageContent *content); -FullMessageId get_message_content_replied_message_id(DialogId dialog_id, const MessageContent *content); +MessageFullId get_message_content_replied_message_id(DialogId dialog_id, const MessageContent *content); std::pair get_message_content_group_call_info(const MessageContent *content); -UserId get_message_content_contact_user_id(const MessageContent *content); +vector get_message_content_min_user_ids(const Td *td, const MessageContent *message_content); + +vector get_message_content_min_channel_ids(const Td *td, const MessageContent *message_content); vector get_message_content_added_user_ids(const MessageContent *content); @@ -156,20 +189,22 @@ bool get_message_content_poll_is_anonymous(const Td *td, const MessageContent *c bool get_message_content_poll_is_closed(const Td *td, const MessageContent *content); +const Venue *get_message_content_venue(const MessageContent *content); + bool has_message_content_web_page(const MessageContent *content); void remove_message_content_web_page(MessageContent *content); bool can_message_content_have_media_timestamp(const MessageContent *content); -void set_message_content_poll_answer(Td *td, const MessageContent *content, FullMessageId full_message_id, +void set_message_content_poll_answer(Td *td, const MessageContent *content, MessageFullId message_full_id, vector &&option_ids, Promise &&promise); -void get_message_content_poll_voters(Td *td, const MessageContent *content, FullMessageId full_message_id, +void get_message_content_poll_voters(Td *td, const MessageContent *content, MessageFullId message_full_id, int32 option_id, int32 offset, int32 limit, - Promise>> &&promise); + Promise> &&promise); -void stop_message_content_poll(Td *td, const MessageContent *content, FullMessageId full_message_id, +void stop_message_content_poll(Td *td, const MessageContent *content, MessageFullId message_full_id, unique_ptr &&reply_markup, Promise &&promise); void merge_message_contents(Td *td, const MessageContent *old_content, MessageContent *new_content, @@ -178,14 +213,27 @@ void merge_message_contents(Td *td, const MessageContent *old_content, MessageCo bool merge_message_content_file_id(Td *td, MessageContent *message_content, FileId new_file_id); -void register_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id, const char *source); +void compare_message_contents(Td *td, const MessageContent *lhs_content, const MessageContent *rhs_content, + bool &is_content_changed, bool &need_update); + +void register_message_content(Td *td, const MessageContent *content, MessageFullId message_full_id, const char *source); void reregister_message_content(Td *td, const MessageContent *old_content, const MessageContent *new_content, - FullMessageId full_message_id, const char *source); + MessageFullId message_full_id, const char *source); -void unregister_message_content(Td *td, const MessageContent *content, FullMessageId full_message_id, +void unregister_message_content(Td *td, const MessageContent *content, MessageFullId message_full_id, const char *source); +void register_reply_message_content(Td *td, const MessageContent *content); + +void unregister_reply_message_content(Td *td, const MessageContent *content); + +void register_quick_reply_message_content(Td *td, const MessageContent *content, + QuickReplyMessageFullId message_full_id, const char *source); + +void unregister_quick_reply_message_content(Td *td, const MessageContent *content, + QuickReplyMessageFullId message_full_id, const char *source); + unique_ptr get_secret_message_content( Td *td, string message_text, unique_ptr file, tl_object_ptr &&media_ptr, @@ -194,22 +242,37 @@ unique_ptr get_secret_message_content( unique_ptr get_message_content(Td *td, FormattedText message_text, tl_object_ptr &&media_ptr, - DialogId owner_dialog_id, bool is_content_read, UserId via_bot_user_id, - int32 *ttl, bool *disable_web_page_preview, const char *source); - -enum class MessageContentDupType : int32 { Send, SendViaBot, Forward, Copy, ServerCopy }; + DialogId owner_dialog_id, int32 message_date, bool is_content_read, + UserId via_bot_user_id, MessageSelfDestructType *ttl, + bool *disable_web_page_preview, const char *source); + +unique_ptr get_uploaded_message_content( + Td *td, const MessageContent *old_content, int32 media_pos, + telegram_api::object_ptr &&media_ptr, DialogId owner_dialog_id, int32 message_date, + const char *source); + +enum class MessageContentDupType : int32 { + Send, // normal message sending + SendViaBot, // message sending via bot + Forward, // server-side message forward + Copy, // local message copy + ServerCopy // server-side message copy +}; unique_ptr dup_message_content(Td *td, DialogId dialog_id, const MessageContent *content, MessageContentDupType type, MessageCopyOptions &©_options); unique_ptr get_action_message_content(Td *td, tl_object_ptr &&action_ptr, - DialogId owner_dialog_id, DialogId reply_in_dialog_id, - MessageId reply_to_message_id); + DialogId owner_dialog_id, int32 message_date, + const RepliedMessageInfo &replied_message_info, + bool is_business_message); -tl_object_ptr get_message_content_object(const MessageContent *content, Td *td, - DialogId dialog_id, int32 message_date, - bool is_content_secret, bool skip_bot_commands, - int32 max_media_timestamp); +td_api::object_ptr get_message_content_object(const MessageContent *content, Td *td, + DialogId dialog_id, bool is_server, + bool is_outgoing, int32 message_date, + bool is_content_secret, bool skip_bot_commands, + int32 max_media_timestamp, bool invert_media, + bool disable_web_page_preview); FormattedText *get_message_content_text_mutable(MessageContent *content); @@ -217,9 +280,9 @@ const FormattedText *get_message_content_text(const MessageContent *content); const FormattedText *get_message_content_caption(const MessageContent *content); -bool get_message_content_has_spoiler(const MessageContent *content); +int64 get_message_content_star_count(const MessageContent *content); -void set_message_content_has_spoiler(MessageContent *content, bool has_spoiler); +string get_message_content_payload(const MessageContent *content); int32 get_message_content_duration(const MessageContent *content, const Td *td); @@ -229,26 +292,36 @@ const Photo *get_message_content_photo(const MessageContent *content); FileId get_message_content_upload_file_id(const MessageContent *content); +vector get_message_content_upload_file_ids(const MessageContent *content); + FileId get_message_content_any_file_id(const MessageContent *content); +vector get_message_content_any_file_ids(const MessageContent *content); + void update_message_content_file_id_remote(MessageContent *content, FileId file_id); +void update_message_content_file_id_remotes(MessageContent *content, const vector &file_ids); + FileId get_message_content_thumbnail_file_id(const MessageContent *content, const Td *td); +vector get_message_content_thumbnail_file_ids(const MessageContent *content, const Td *td); + vector get_message_content_file_ids(const MessageContent *content, const Td *td); +StoryFullId get_message_content_story_full_id(const Td *td, const MessageContent *content); + string get_message_content_search_text(const Td *td, const MessageContent *content); -bool update_message_content_extended_media(MessageContent *content, - telegram_api::object_ptr extended_media, - DialogId owner_dialog_id, Td *td); +bool update_message_content_extended_media( + MessageContent *content, vector> extended_media, + DialogId owner_dialog_id, Td *td); bool need_poll_message_content_extended_media(const MessageContent *content); -void get_message_content_animated_emoji_click_sticker(const MessageContent *content, FullMessageId full_message_id, +void get_message_content_animated_emoji_click_sticker(const MessageContent *content, MessageFullId message_full_id, Td *td, Promise> &&promise); -void on_message_content_animated_emoji_clicked(const MessageContent *content, FullMessageId full_message_id, Td *td, +void on_message_content_animated_emoji_clicked(const MessageContent *content, MessageFullId message_full_id, Td *td, string &&emoji, string &&data); bool need_reget_message_content(const MessageContent *content); @@ -268,18 +341,8 @@ void on_sent_message_content(Td *td, const MessageContent *content); void move_message_content_sticker_set_to_top(Td *td, const MessageContent *content); -bool is_unsent_animated_emoji_click(Td *td, DialogId dialog_id, const DialogAction &action); - -void init_stickers_manager(Td *td); - void on_dialog_used(TopDialogCategory category, DialogId dialog_id, int32 date); void update_used_hashtags(Td *td, const MessageContent *content); -void recognize_message_content_speech(Td *td, const MessageContent *content, FullMessageId full_message_id, - Promise &&promise); - -void rate_message_content_speech_recognition(Td *td, const MessageContent *content, FullMessageId full_message_id, - bool is_good, Promise &&promise); - } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageContentType.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageContentType.cpp index 639512f885..e8c4c2878e 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageContentType.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageContentType.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -124,9 +124,50 @@ StringBuilder &operator<<(StringBuilder &string_builder, MessageContentType cont return string_builder << "WebAppWriteAccessAllowed"; case MessageContentType::SetBackground: return string_builder << "SetBackground"; + case MessageContentType::Story: + return string_builder << "Story"; + case MessageContentType::WriteAccessAllowedByRequest: + return string_builder << "WriteAccessAllowedByRequest"; + case MessageContentType::GiftCode: + return string_builder << "GiftCode"; + case MessageContentType::Giveaway: + return string_builder << "Giveaway"; + case MessageContentType::GiveawayLaunch: + return string_builder << "GiveawayLaunch"; + case MessageContentType::GiveawayResults: + return string_builder << "GiveawayResults"; + case MessageContentType::GiveawayWinners: + return string_builder << "GiveawayWinners"; + case MessageContentType::ExpiredVideoNote: + return string_builder << "ExpiredVideoNote"; + case MessageContentType::ExpiredVoiceNote: + return string_builder << "ExpiredVoiceNote"; + case MessageContentType::BoostApply: + return string_builder << "BoostApply"; + case MessageContentType::DialogShared: + return string_builder << "ChatShared"; + case MessageContentType::PaidMedia: + return string_builder << "PaidMedia"; + case MessageContentType::PaymentRefunded: + return string_builder << "PaymentRefunded"; + case MessageContentType::GiftStars: + return string_builder << "GiftStars"; + case MessageContentType::PrizeStars: + return string_builder << "PrizeStars"; default: - UNREACHABLE(); - return string_builder; + return string_builder << "Invalid type " << static_cast(content_type); + } +} + +bool is_allowed_invert_caption_message_content(MessageContentType content_type) { + switch (content_type) { + case MessageContentType::Animation: + case MessageContentType::PaidMedia: + case MessageContentType::Photo: + case MessageContentType::Video: + return true; + default: + return false; } } @@ -189,6 +230,21 @@ bool is_allowed_media_group_content(MessageContentType content_type) { case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::Story: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaidMedia: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: return false; default: UNREACHABLE(); @@ -200,10 +256,7 @@ bool is_homogenous_media_group_content(MessageContentType content_type) { return content_type == MessageContentType::Audio || content_type == MessageContentType::Document; } -bool is_secret_message_content(int32 ttl, MessageContentType content_type) { - if (ttl <= 0 || ttl > 60) { - return false; - } +bool can_be_secret_message_content(MessageContentType content_type) { switch (content_type) { case MessageContentType::Animation: case MessageContentType::Audio: @@ -262,6 +315,102 @@ bool is_secret_message_content(int32 ttl, MessageContentType content_type) { case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::Story: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaidMedia: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: + return false; + default: + UNREACHABLE(); + return false; + } +} + +bool can_be_local_message_content(MessageContentType content_type) { + switch (content_type) { + case MessageContentType::Animation: + case MessageContentType::Audio: + case MessageContentType::Contact: + case MessageContentType::Document: + case MessageContentType::Location: + case MessageContentType::Photo: + case MessageContentType::Sticker: + case MessageContentType::Text: + case MessageContentType::Venue: + case MessageContentType::Video: + case MessageContentType::VideoNote: + case MessageContentType::VoiceNote: + case MessageContentType::Story: + return true; + case MessageContentType::Game: + case MessageContentType::Invoice: + case MessageContentType::LiveLocation: + case MessageContentType::Unsupported: + case MessageContentType::ExpiredPhoto: + case MessageContentType::ExpiredVideo: + case MessageContentType::ChatCreate: + case MessageContentType::ChatChangeTitle: + case MessageContentType::ChatChangePhoto: + case MessageContentType::ChatDeletePhoto: + case MessageContentType::ChatDeleteHistory: + case MessageContentType::ChatAddUsers: + case MessageContentType::ChatJoinedByLink: + case MessageContentType::ChatDeleteUser: + case MessageContentType::ChatMigrateTo: + case MessageContentType::ChannelCreate: + case MessageContentType::ChannelMigrateFrom: + case MessageContentType::PinMessage: + case MessageContentType::GameScore: + case MessageContentType::ScreenshotTaken: + case MessageContentType::ChatSetTtl: + case MessageContentType::Call: + case MessageContentType::PaymentSuccessful: + case MessageContentType::ContactRegistered: + case MessageContentType::CustomServiceAction: + case MessageContentType::WebsiteConnected: + case MessageContentType::PassportDataSent: + case MessageContentType::PassportDataReceived: + case MessageContentType::Poll: + case MessageContentType::Dice: + case MessageContentType::ProximityAlertTriggered: + case MessageContentType::GroupCall: + case MessageContentType::InviteToGroupCall: + case MessageContentType::ChatSetTheme: + case MessageContentType::WebViewDataSent: + case MessageContentType::WebViewDataReceived: + case MessageContentType::GiftPremium: + case MessageContentType::TopicCreate: + case MessageContentType::TopicEdit: + case MessageContentType::SuggestProfilePhoto: + case MessageContentType::WriteAccessAllowed: + case MessageContentType::RequestedDialog: + case MessageContentType::WebViewWriteAccessAllowed: + case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaidMedia: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: return false; default: UNREACHABLE(); @@ -274,24 +423,107 @@ bool is_service_message_content(MessageContentType content_type) { case MessageContentType::Animation: case MessageContentType::Audio: case MessageContentType::Contact: + case MessageContentType::Dice: case MessageContentType::Document: + case MessageContentType::ExpiredPhoto: + case MessageContentType::ExpiredVideo: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: case MessageContentType::Game: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayWinners: case MessageContentType::Invoice: case MessageContentType::LiveLocation: case MessageContentType::Location: + case MessageContentType::PaidMedia: case MessageContentType::Photo: + case MessageContentType::Poll: case MessageContentType::Sticker: + case MessageContentType::Story: case MessageContentType::Text: case MessageContentType::Unsupported: case MessageContentType::Venue: case MessageContentType::Video: case MessageContentType::VideoNote: case MessageContentType::VoiceNote: - case MessageContentType::ExpiredPhoto: - case MessageContentType::ExpiredVideo: + return false; + case MessageContentType::ChatCreate: + case MessageContentType::ChatChangeTitle: + case MessageContentType::ChatChangePhoto: + case MessageContentType::ChatDeletePhoto: + case MessageContentType::ChatDeleteHistory: + case MessageContentType::ChatAddUsers: + case MessageContentType::ChatJoinedByLink: + case MessageContentType::ChatDeleteUser: + case MessageContentType::ChatMigrateTo: + case MessageContentType::ChannelCreate: + case MessageContentType::ChannelMigrateFrom: + case MessageContentType::PinMessage: + case MessageContentType::GameScore: + case MessageContentType::ScreenshotTaken: + case MessageContentType::ChatSetTtl: + case MessageContentType::Call: + case MessageContentType::PaymentSuccessful: + case MessageContentType::ContactRegistered: + case MessageContentType::CustomServiceAction: + case MessageContentType::WebsiteConnected: + case MessageContentType::PassportDataSent: + case MessageContentType::PassportDataReceived: + case MessageContentType::ProximityAlertTriggered: + case MessageContentType::GroupCall: + case MessageContentType::InviteToGroupCall: + case MessageContentType::ChatSetTheme: + case MessageContentType::WebViewDataSent: + case MessageContentType::WebViewDataReceived: + case MessageContentType::GiftPremium: + case MessageContentType::TopicCreate: + case MessageContentType::TopicEdit: + case MessageContentType::SuggestProfilePhoto: + case MessageContentType::WriteAccessAllowed: + case MessageContentType::RequestedDialog: + case MessageContentType::WebViewWriteAccessAllowed: + case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: + return true; + default: + UNREACHABLE(); + return false; + } +} + +bool is_editable_message_content(MessageContentType content_type) { + switch (content_type) { + case MessageContentType::Animation: + case MessageContentType::Audio: + case MessageContentType::Document: + case MessageContentType::Game: + case MessageContentType::PaidMedia: + case MessageContentType::Photo: + case MessageContentType::Text: + case MessageContentType::Video: + case MessageContentType::VoiceNote: + return true; + case MessageContentType::LiveLocation: case MessageContentType::Poll: + case MessageContentType::Story: + case MessageContentType::Contact: case MessageContentType::Dice: - return false; + case MessageContentType::Giveaway: + case MessageContentType::GiveawayWinners: + case MessageContentType::Location: + case MessageContentType::Sticker: + case MessageContentType::Venue: + case MessageContentType::VideoNote: + case MessageContentType::Invoice: + case MessageContentType::Unsupported: case MessageContentType::ChatCreate: case MessageContentType::ChatChangeTitle: case MessageContentType::ChatChangePhoto: @@ -310,6 +542,8 @@ bool is_service_message_content(MessageContentType content_type) { case MessageContentType::Call: case MessageContentType::PaymentSuccessful: case MessageContentType::ContactRegistered: + case MessageContentType::ExpiredPhoto: + case MessageContentType::ExpiredVideo: case MessageContentType::CustomServiceAction: case MessageContentType::WebsiteConnected: case MessageContentType::PassportDataSent: @@ -328,18 +562,94 @@ bool is_service_message_content(MessageContentType content_type) { case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: + return false; + default: + UNREACHABLE(); + return false; + } +} + +bool is_supported_reply_message_content(MessageContentType content_type) { + switch (content_type) { + case MessageContentType::Animation: + case MessageContentType::Audio: + case MessageContentType::Contact: + case MessageContentType::Dice: + case MessageContentType::Document: + case MessageContentType::Game: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayWinners: + case MessageContentType::Invoice: + case MessageContentType::Location: + case MessageContentType::PaidMedia: + case MessageContentType::Photo: + case MessageContentType::Poll: + case MessageContentType::Sticker: + case MessageContentType::Story: + case MessageContentType::Text: + case MessageContentType::Unsupported: + case MessageContentType::Venue: + case MessageContentType::Video: + case MessageContentType::VideoNote: + case MessageContentType::VoiceNote: + // update documentation when the list changes return true; + case MessageContentType::ExpiredPhoto: + case MessageContentType::ExpiredVideo: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::LiveLocation: + return false; default: UNREACHABLE(); return false; } } +bool is_expired_message_content(MessageContentType content_type) { + switch (content_type) { + case MessageContentType::ExpiredPhoto: + case MessageContentType::ExpiredVideo: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + return true; + default: + return false; + } +} + +MessageContentType get_expired_message_content_type(MessageContentType content_type) { + switch (content_type) { + case MessageContentType::Photo: + return MessageContentType::ExpiredPhoto; + case MessageContentType::Video: + return MessageContentType::ExpiredVideo; + case MessageContentType::VideoNote: + return MessageContentType::ExpiredVideoNote; + case MessageContentType::VoiceNote: + return MessageContentType::ExpiredVoiceNote; + default: + return MessageContentType::None; + } +} + bool can_have_message_content_caption(MessageContentType content_type) { switch (content_type) { case MessageContentType::Animation: case MessageContentType::Audio: case MessageContentType::Document: + case MessageContentType::PaidMedia: case MessageContentType::Photo: case MessageContentType::Video: case MessageContentType::VoiceNote: @@ -394,6 +704,20 @@ bool can_have_message_content_caption(MessageContentType content_type) { case MessageContentType::RequestedDialog: case MessageContentType::WebViewWriteAccessAllowed: case MessageContentType::SetBackground: + case MessageContentType::Story: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::GiveawayWinners: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: return false; default: UNREACHABLE(); @@ -401,12 +725,95 @@ bool can_have_message_content_caption(MessageContentType content_type) { } } +bool can_send_message_content_to_secret_chat(MessageContentType content_type) { + switch (content_type) { + case MessageContentType::Animation: + case MessageContentType::Audio: + case MessageContentType::Contact: + case MessageContentType::Document: + case MessageContentType::LiveLocation: + case MessageContentType::Location: + case MessageContentType::Photo: + case MessageContentType::Sticker: + case MessageContentType::Text: + case MessageContentType::Venue: + case MessageContentType::Video: + case MessageContentType::VideoNote: + case MessageContentType::VoiceNote: + return true; + case MessageContentType::Dice: + case MessageContentType::Game: + case MessageContentType::Giveaway: + case MessageContentType::GiveawayWinners: + case MessageContentType::Invoice: + case MessageContentType::PaidMedia: + case MessageContentType::Poll: + case MessageContentType::Story: + return false; + case MessageContentType::None: + case MessageContentType::ChatCreate: + case MessageContentType::ChatChangeTitle: + case MessageContentType::ChatChangePhoto: + case MessageContentType::ChatDeletePhoto: + case MessageContentType::ChatDeleteHistory: + case MessageContentType::ChatAddUsers: + case MessageContentType::ChatJoinedByLink: + case MessageContentType::ChatDeleteUser: + case MessageContentType::ChatMigrateTo: + case MessageContentType::ChannelCreate: + case MessageContentType::ChannelMigrateFrom: + case MessageContentType::PinMessage: + case MessageContentType::GameScore: + case MessageContentType::ScreenshotTaken: + case MessageContentType::ChatSetTtl: + case MessageContentType::Unsupported: + case MessageContentType::Call: + case MessageContentType::PaymentSuccessful: + case MessageContentType::ContactRegistered: + case MessageContentType::ExpiredPhoto: + case MessageContentType::ExpiredVideo: + case MessageContentType::CustomServiceAction: + case MessageContentType::WebsiteConnected: + case MessageContentType::PassportDataSent: + case MessageContentType::PassportDataReceived: + case MessageContentType::ProximityAlertTriggered: + case MessageContentType::GroupCall: + case MessageContentType::InviteToGroupCall: + case MessageContentType::ChatSetTheme: + case MessageContentType::WebViewDataSent: + case MessageContentType::WebViewDataReceived: + case MessageContentType::GiftPremium: + case MessageContentType::TopicCreate: + case MessageContentType::TopicEdit: + case MessageContentType::SuggestProfilePhoto: + case MessageContentType::WriteAccessAllowed: + case MessageContentType::RequestedDialog: + case MessageContentType::WebViewWriteAccessAllowed: + case MessageContentType::SetBackground: + case MessageContentType::WriteAccessAllowedByRequest: + case MessageContentType::GiftCode: + case MessageContentType::GiveawayLaunch: + case MessageContentType::GiveawayResults: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: + case MessageContentType::BoostApply: + case MessageContentType::DialogShared: + case MessageContentType::PaymentRefunded: + case MessageContentType::GiftStars: + case MessageContentType::PrizeStars: + default: + UNREACHABLE(); + return false; + } +} + uint64 get_message_content_chain_id(MessageContentType content_type) { switch (content_type) { case MessageContentType::Animation: case MessageContentType::Audio: case MessageContentType::Document: case MessageContentType::Invoice: + case MessageContentType::PaidMedia: case MessageContentType::Photo: case MessageContentType::Sticker: case MessageContentType::Video: diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageContentType.h b/protocols/Telegram/tdlib/td/td/telegram/MessageContentType.h index 8e71557fb3..ef5d3603eb 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageContentType.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageContentType.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -69,22 +69,51 @@ enum class MessageContentType : int32 { WriteAccessAllowed, RequestedDialog, WebViewWriteAccessAllowed, - SetBackground + SetBackground, + Story, + WriteAccessAllowedByRequest, + GiftCode, + Giveaway, + GiveawayLaunch, + GiveawayResults, + GiveawayWinners, + ExpiredVideoNote, + ExpiredVoiceNote, + BoostApply, + DialogShared, + PaidMedia, + PaymentRefunded, + GiftStars, + PrizeStars }; // increase MessageUnsupported::CURRENT_VERSION each time a new message content type is added StringBuilder &operator<<(StringBuilder &string_builder, MessageContentType content_type); +bool is_allowed_invert_caption_message_content(MessageContentType content_type); + bool is_allowed_media_group_content(MessageContentType content_type); bool is_homogenous_media_group_content(MessageContentType content_type); -bool is_secret_message_content(int32 ttl, MessageContentType content_type); +bool can_be_secret_message_content(MessageContentType content_type); + +bool can_be_local_message_content(MessageContentType content_type); bool is_service_message_content(MessageContentType content_type); +bool is_editable_message_content(MessageContentType content_type); + +bool is_supported_reply_message_content(MessageContentType content_type); + +bool is_expired_message_content(MessageContentType content_type); + +MessageContentType get_expired_message_content_type(MessageContentType content_type); + bool can_have_message_content_caption(MessageContentType content_type); +bool can_send_message_content_to_secret_chat(MessageContentType content_type); + uint64 get_message_content_chain_id(MessageContentType content_type); struct MessageContentTypeHash { diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageCopyOptions.h b/protocols/Telegram/tdlib/td/td/telegram/MessageCopyOptions.h index 2335b30e7a..33051b01f6 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageCopyOptions.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageCopyOptions.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,7 +7,7 @@ #pragma once #include "td/telegram/MessageEntity.h" -#include "td/telegram/MessageId.h" +#include "td/telegram/MessageInputReplyTo.h" #include "td/telegram/ReplyMarkup.h" #include "td/utils/common.h" @@ -18,8 +18,9 @@ namespace td { struct MessageCopyOptions { bool send_copy = false; bool replace_caption = false; + bool new_invert_media = false; FormattedText new_caption; - MessageId reply_to_message_id; + MessageInputReplyTo input_reply_to; unique_ptr reply_markup; MessageCopyOptions() = default; @@ -30,7 +31,7 @@ struct MessageCopyOptions { if (!send_copy) { return true; } - if ((replace_caption && !new_caption.text.empty()) || reply_to_message_id.is_valid() || reply_markup != nullptr) { + if ((replace_caption && !new_caption.text.empty()) || input_reply_to.is_valid() || reply_markup != nullptr) { return false; } return true; @@ -41,10 +42,11 @@ inline StringBuilder &operator<<(StringBuilder &string_builder, MessageCopyOptio if (copy_options.send_copy) { string_builder << "CopyOptions[replace_caption = " << copy_options.replace_caption; if (copy_options.replace_caption) { - string_builder << ", new_caption = " << copy_options.new_caption; + string_builder << ", new_caption = " << copy_options.new_caption + << ", new_show_caption_above_media = " << copy_options.new_invert_media; } - if (copy_options.reply_to_message_id.is_valid()) { - string_builder << ", in reply to " << copy_options.reply_to_message_id; + if (copy_options.input_reply_to.is_valid()) { + string_builder << ", in reply to " << copy_options.input_reply_to; } if (copy_options.reply_markup != nullptr) { string_builder << ", with reply markup"; diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageDb.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageDb.cpp index e0d15cd7e7..6277b2e9dc 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageDb.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageDb.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -49,7 +49,7 @@ Status init_message_db(SqliteDb &db, int32 version) { TRY_RESULT(has_table, db.has_table("messages")); if (!has_table) { version = 0; - } else if (version < static_cast(DbVersion::DialogDbCreated) || version > current_db_version()) { + } else if (version > current_db_version()) { TRY_STATUS(drop_message_db(db, version)); version = 0; } @@ -142,19 +142,19 @@ Status init_message_db(SqliteDb &db, int32 version) { version = current_db_version(); } - if (version < static_cast(DbVersion::MessageDbMediaIndex)) { + if (version < static_cast(DbVersion::AddMessageDbMediaIndex)) { TRY_STATUS(db.exec("ALTER TABLE messages ADD COLUMN index_mask INT4")); TRY_STATUS(add_media_indices(0, MESSAGE_DB_INDEX_COUNT_OLD)); } - if (version < static_cast(DbVersion::MessageDb30MediaIndex)) { + if (version < static_cast(DbVersion::AddMessageDb30MediaIndex)) { TRY_STATUS(add_media_indices(MESSAGE_DB_INDEX_COUNT_OLD, MESSAGE_DB_INDEX_COUNT)); } - if (version < static_cast(DbVersion::MessageDbFts)) { + if (version < static_cast(DbVersion::AddMessageDbFts)) { TRY_STATUS(db.exec("ALTER TABLE messages ADD COLUMN search_id INT8")); TRY_STATUS(db.exec("ALTER TABLE messages ADD COLUMN text STRING")); TRY_STATUS(add_fts()); } - if (version < static_cast(DbVersion::MessagesCallIndex)) { + if (version < static_cast(DbVersion::AddMessagesCallIndex)) { TRY_STATUS(add_call_index()); } if (version < static_cast(DbVersion::AddNotificationsSupport)) { @@ -287,13 +287,13 @@ class MessageDbImpl final : public MessageDbSyncInterface { return Status::OK(); } - void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, + void add_message(MessageFullId message_full_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text, NotificationId notification_id, MessageId top_thread_message_id, BufferSlice data) final { - LOG(INFO) << "Add " << full_message_id << " to database"; - auto dialog_id = full_message_id.get_dialog_id(); - auto message_id = full_message_id.get_message_id(); - LOG_CHECK(dialog_id.is_valid()) << dialog_id << ' ' << message_id << ' ' << full_message_id; + LOG(INFO) << "Add " << message_full_id << " to database"; + auto dialog_id = message_full_id.get_dialog_id(); + auto message_id = message_full_id.get_message_id(); + LOG_CHECK(dialog_id.is_valid()) << dialog_id << ' ' << message_id << ' ' << message_full_id; CHECK(message_id.is_valid()); SCOPE_EXIT { add_message_stmt_.reset(); @@ -366,10 +366,10 @@ class MessageDbImpl final : public MessageDbSyncInterface { add_message_stmt_.step().ensure(); } - void add_scheduled_message(FullMessageId full_message_id, BufferSlice data) final { - LOG(INFO) << "Add " << full_message_id << " to database"; - auto dialog_id = full_message_id.get_dialog_id(); - auto message_id = full_message_id.get_message_id(); + void add_scheduled_message(MessageFullId message_full_id, BufferSlice data) final { + LOG(INFO) << "Add " << message_full_id << " to database"; + auto dialog_id = message_full_id.get_dialog_id(); + auto message_id = message_full_id.get_message_id(); CHECK(dialog_id.is_valid()); CHECK(message_id.is_valid_scheduled()); SCOPE_EXIT { @@ -389,10 +389,10 @@ class MessageDbImpl final : public MessageDbSyncInterface { add_scheduled_message_stmt_.step().ensure(); } - void delete_message(FullMessageId full_message_id) final { - LOG(INFO) << "Delete " << full_message_id << " from database"; - auto dialog_id = full_message_id.get_dialog_id(); - auto message_id = full_message_id.get_message_id(); + void delete_message(MessageFullId message_full_id) final { + LOG(INFO) << "Delete " << message_full_id << " from database"; + auto dialog_id = message_full_id.get_dialog_id(); + auto message_id = message_full_id.get_message_id(); CHECK(dialog_id.is_valid()); CHECK(message_id.is_valid() || message_id.is_valid_scheduled()); bool is_scheduled = message_id.is_scheduled(); @@ -439,9 +439,9 @@ class MessageDbImpl final : public MessageDbSyncInterface { delete_dialog_messages_by_sender_stmt_.step().ensure(); } - Result get_message(FullMessageId full_message_id) final { - auto dialog_id = full_message_id.get_dialog_id(); - auto message_id = full_message_id.get_message_id(); + Result get_message(MessageFullId message_full_id) final { + auto dialog_id = message_full_id.get_dialog_id(); + auto message_id = message_full_id.get_message_id(); CHECK(dialog_id.is_valid()); CHECK(message_id.is_valid() || message_id.is_valid_scheduled()); bool is_scheduled = message_id.is_scheduled(); @@ -988,20 +988,20 @@ class MessageDbAsync final : public MessageDbAsyncInterface { impl_ = create_actor_on_scheduler("MessageDbActor", scheduler_id, std::move(sync_db)); } - void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, + void add_message(MessageFullId message_full_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text, NotificationId notification_id, MessageId top_thread_message_id, BufferSlice data, Promise<> promise) final { - send_closure_later(impl_, &Impl::add_message, full_message_id, unique_message_id, sender_dialog_id, random_id, + send_closure_later(impl_, &Impl::add_message, message_full_id, unique_message_id, sender_dialog_id, random_id, ttl_expires_at, index_mask, search_id, std::move(text), notification_id, top_thread_message_id, std::move(data), std::move(promise)); } - void add_scheduled_message(FullMessageId full_message_id, BufferSlice data, Promise<> promise) final { - send_closure_later(impl_, &Impl::add_scheduled_message, full_message_id, std::move(data), std::move(promise)); + void add_scheduled_message(MessageFullId message_full_id, BufferSlice data, Promise<> promise) final { + send_closure_later(impl_, &Impl::add_scheduled_message, message_full_id, std::move(data), std::move(promise)); } - void delete_message(FullMessageId full_message_id, Promise<> promise) final { - send_closure_later(impl_, &Impl::delete_message, full_message_id, std::move(promise)); + void delete_message(MessageFullId message_full_id, Promise<> promise) final { + send_closure_later(impl_, &Impl::delete_message, message_full_id, std::move(promise)); } void delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id, Promise<> promise) final { send_closure_later(impl_, &Impl::delete_all_dialog_messages, dialog_id, from_message_id, std::move(promise)); @@ -1010,8 +1010,8 @@ class MessageDbAsync final : public MessageDbAsyncInterface { send_closure_later(impl_, &Impl::delete_dialog_messages_by_sender, dialog_id, sender_dialog_id, std::move(promise)); } - void get_message(FullMessageId full_message_id, Promise promise) final { - send_closure_later(impl_, &Impl::get_message, full_message_id, std::move(promise)); + void get_message(MessageFullId message_full_id, Promise promise) final { + send_closure_later(impl_, &Impl::get_message, message_full_id, std::move(promise)); } void get_message_by_unique_message_id(ServerMessageId unique_message_id, Promise promise) final { send_closure_later(impl_, &Impl::get_message_by_unique_message_id, unique_message_id, std::move(promise)); @@ -1068,29 +1068,29 @@ class MessageDbAsync final : public MessageDbAsyncInterface { public: explicit Impl(std::shared_ptr sync_db_safe) : sync_db_safe_(std::move(sync_db_safe)) { } - void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, + void add_message(MessageFullId message_full_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text, NotificationId notification_id, MessageId top_thread_message_id, BufferSlice data, Promise<> promise) { - add_write_query([this, full_message_id, unique_message_id, sender_dialog_id, random_id, ttl_expires_at, + add_write_query([this, message_full_id, unique_message_id, sender_dialog_id, random_id, ttl_expires_at, index_mask, search_id, text = std::move(text), notification_id, top_thread_message_id, data = std::move(data), promise = std::move(promise)](Unit) mutable { - sync_db_->add_message(full_message_id, unique_message_id, sender_dialog_id, random_id, ttl_expires_at, + sync_db_->add_message(message_full_id, unique_message_id, sender_dialog_id, random_id, ttl_expires_at, index_mask, search_id, std::move(text), notification_id, top_thread_message_id, std::move(data)); on_write_result(std::move(promise)); }); } - void add_scheduled_message(FullMessageId full_message_id, BufferSlice data, Promise<> promise) { - add_write_query([this, full_message_id, promise = std::move(promise), data = std::move(data)](Unit) mutable { - sync_db_->add_scheduled_message(full_message_id, std::move(data)); + void add_scheduled_message(MessageFullId message_full_id, BufferSlice data, Promise<> promise) { + add_write_query([this, message_full_id, promise = std::move(promise), data = std::move(data)](Unit) mutable { + sync_db_->add_scheduled_message(message_full_id, std::move(data)); on_write_result(std::move(promise)); }); } - void delete_message(FullMessageId full_message_id, Promise<> promise) { - add_write_query([this, full_message_id, promise = std::move(promise)](Unit) mutable { - sync_db_->delete_message(full_message_id); + void delete_message(MessageFullId message_full_id, Promise<> promise) { + add_write_query([this, message_full_id, promise = std::move(promise)](Unit) mutable { + sync_db_->delete_message(message_full_id); on_write_result(std::move(promise)); }); } @@ -1112,9 +1112,9 @@ class MessageDbAsync final : public MessageDbAsyncInterface { promise.set_value(Unit()); } - void get_message(FullMessageId full_message_id, Promise promise) { + void get_message(MessageFullId message_full_id, Promise promise) { add_read_query(); - promise.set_result(sync_db_->get_message(full_message_id)); + promise.set_result(sync_db_->get_message(message_full_id)); } void get_message_by_unique_message_id(ServerMessageId unique_message_id, Promise promise) { add_read_query(); diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageDb.h b/protocols/Telegram/tdlib/td/td/telegram/MessageDb.h index 8360f39d6d..412fc2452d 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageDb.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageDb.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,7 +7,7 @@ #pragma once #include "td/telegram/DialogId.h" -#include "td/telegram/FullMessageId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessageSearchFilter.h" #include "td/telegram/NotificationId.h" @@ -104,16 +104,16 @@ class MessageDbSyncInterface { MessageDbSyncInterface &operator=(const MessageDbSyncInterface &) = delete; virtual ~MessageDbSyncInterface() = default; - virtual void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, + virtual void add_message(MessageFullId message_full_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text, NotificationId notification_id, MessageId top_thread_message_id, BufferSlice data) = 0; - virtual void add_scheduled_message(FullMessageId full_message_id, BufferSlice data) = 0; + virtual void add_scheduled_message(MessageFullId message_full_id, BufferSlice data) = 0; - virtual void delete_message(FullMessageId full_message_id) = 0; + virtual void delete_message(MessageFullId message_full_id) = 0; virtual void delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id) = 0; virtual void delete_dialog_messages_by_sender(DialogId dialog_id, DialogId sender_dialog_id) = 0; - virtual Result get_message(FullMessageId full_message_id) = 0; + virtual Result get_message(MessageFullId message_full_id) = 0; virtual Result get_message_by_unique_message_id(ServerMessageId unique_message_id) = 0; virtual Result get_message_by_random_id(DialogId dialog_id, int64 random_id) = 0; virtual Result get_dialog_message_by_date(DialogId dialog_id, MessageId first_message_id, @@ -155,17 +155,17 @@ class MessageDbAsyncInterface { MessageDbAsyncInterface &operator=(const MessageDbAsyncInterface &) = delete; virtual ~MessageDbAsyncInterface() = default; - virtual void add_message(FullMessageId full_message_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, + virtual void add_message(MessageFullId message_full_id, ServerMessageId unique_message_id, DialogId sender_dialog_id, int64 random_id, int32 ttl_expires_at, int32 index_mask, int64 search_id, string text, NotificationId notification_id, MessageId top_thread_message_id, BufferSlice data, Promise<> promise) = 0; - virtual void add_scheduled_message(FullMessageId full_message_id, BufferSlice data, Promise<> promise) = 0; + virtual void add_scheduled_message(MessageFullId message_full_id, BufferSlice data, Promise<> promise) = 0; - virtual void delete_message(FullMessageId full_message_id, Promise<> promise) = 0; + virtual void delete_message(MessageFullId message_full_id, Promise<> promise) = 0; virtual void delete_all_dialog_messages(DialogId dialog_id, MessageId from_message_id, Promise<> promise) = 0; virtual void delete_dialog_messages_by_sender(DialogId dialog_id, DialogId sender_dialog_id, Promise<> promise) = 0; - virtual void get_message(FullMessageId full_message_id, Promise promise) = 0; + virtual void get_message(MessageFullId message_full_id, Promise promise) = 0; virtual void get_message_by_unique_message_id(ServerMessageId unique_message_id, Promise promise) = 0; virtual void get_message_by_random_id(DialogId dialog_id, int64 random_id, diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageEffectId.h b/protocols/Telegram/tdlib/td/td/telegram/MessageEffectId.h new file mode 100644 index 0000000000..f41017e80f --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageEffectId.h @@ -0,0 +1,65 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +#include + +namespace td { + +class MessageEffectId { + int64 id = 0; + + public: + MessageEffectId() = default; + + explicit constexpr MessageEffectId(int64 message_effect_id) : id(message_effect_id) { + } + template ::value>> + MessageEffectId(T message_effect_id) = delete; + + bool is_valid() const { + return id != 0; + } + + int64 get() const { + return id; + } + + bool operator==(const MessageEffectId &other) const { + return id == other.id; + } + + bool operator!=(const MessageEffectId &other) const { + return id != other.id; + } + + template + void store(StorerT &storer) const { + storer.store_long(id); + } + + template + void parse(ParserT &parser) { + id = parser.fetch_long(); + } +}; + +struct MessageEffectIdHash { + uint32 operator()(MessageEffectId message_effect_id) const { + return Hash()(message_effect_id.get()); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, MessageEffectId message_effect_id) { + return string_builder << "message effect " << message_effect_id.get(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageEntity.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageEntity.cpp index 542d3f2e5d..1cb9e0d770 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageEntity.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageEntity.cpp @@ -1,19 +1,20 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/MessageEntity.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/LinkManager.h" #include "td/telegram/misc.h" #include "td/telegram/OptionManager.h" #include "td/telegram/SecretChatLayer.h" #include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" +#include "td/telegram/UserManager.h" #include "td/actor/MultiPromise.h" @@ -56,7 +57,8 @@ int MessageEntity::get_type_priority(Type type) { 50 /*BankCardNumber*/, 50 /*MediaTimestamp*/, 94 /*Spoiler*/, - 99 /*CustomEmoji*/}; + 99 /*CustomEmoji*/, + 0 /*ExpandableBlockQuote*/}; static_assert(sizeof(priorities) / sizeof(priorities[0]) == static_cast(MessageEntity::Type::Size), ""); return priorities[static_cast(type)]; } @@ -105,6 +107,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageEntity::Ty return string_builder << "Spoiler"; case MessageEntity::Type::CustomEmoji: return string_builder << "CustomEmoji"; + case MessageEntity::Type::ExpandableBlockQuote: + return string_builder << "ExpandableBlockQuote"; default: UNREACHABLE(); return string_builder << "Impossible"; @@ -130,7 +134,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageEntity &me return string_builder; } -tl_object_ptr MessageEntity::get_text_entity_type_object() const { +tl_object_ptr MessageEntity::get_text_entity_type_object( + const UserManager *user_manager) const { switch (type) { case MessageEntity::Type::Mention: return make_tl_object(); @@ -151,7 +156,7 @@ tl_object_ptr MessageEntity::get_text_entity_type_object case MessageEntity::Type::Strikethrough: return make_tl_object(); case MessageEntity::Type::BlockQuote: - return nullptr; + return make_tl_object(); case MessageEntity::Type::Code: return make_tl_object(); case MessageEntity::Type::Pre: @@ -161,8 +166,9 @@ tl_object_ptr MessageEntity::get_text_entity_type_object case MessageEntity::Type::TextUrl: return make_tl_object(argument); case MessageEntity::Type::MentionName: - // can't use contacts_manager, because can be called from a static request - return make_tl_object(user_id.get()); + return make_tl_object( + user_manager == nullptr ? user_id.get() + : user_manager->get_user_id_object(user_id, "textEntityTypeMentionName")); case MessageEntity::Type::Cashtag: return make_tl_object(); case MessageEntity::Type::PhoneNumber: @@ -175,17 +181,20 @@ tl_object_ptr MessageEntity::get_text_entity_type_object return make_tl_object(); case MessageEntity::Type::CustomEmoji: return make_tl_object(custom_emoji_id.get()); + case MessageEntity::Type::ExpandableBlockQuote: + return make_tl_object(); default: UNREACHABLE(); return nullptr; } } -tl_object_ptr MessageEntity::get_text_entity_object() const { - return make_tl_object(offset, length, get_text_entity_type_object()); +tl_object_ptr MessageEntity::get_text_entity_object(const UserManager *user_manager) const { + return make_tl_object(offset, length, get_text_entity_type_object(user_manager)); } -vector> get_text_entities_object(const vector &entities, +vector> get_text_entities_object(const UserManager *user_manager, + const vector &entities, bool skip_bot_commands, int32 max_media_timestamp) { vector> result; result.reserve(entities.size()); @@ -197,7 +206,7 @@ vector> get_text_entities_object(const vector< if (entity.type == MessageEntity::Type::MediaTimestamp && max_media_timestamp < entity.media_timestamp) { continue; } - auto entity_object = entity.get_text_entity_object(); + auto entity_object = entity.get_text_entity_object(user_manager); if (entity_object->type_ != nullptr) { result.push_back(std::move(entity_object)); } @@ -210,10 +219,11 @@ StringBuilder &operator<<(StringBuilder &string_builder, const FormattedText &te return string_builder << '"' << text.text << "\" with entities " << text.entities; } -td_api::object_ptr get_formatted_text_object(const FormattedText &text, bool skip_bot_commands, +td_api::object_ptr get_formatted_text_object(const UserManager *user_manager, + const FormattedText &text, bool skip_bot_commands, int32 max_media_timestamp) { return td_api::make_object( - text.text, get_text_entities_object(text.entities, skip_bot_commands, max_media_timestamp)); + text.text, get_text_entities_object(user_manager, text.entities, skip_bot_commands, max_media_timestamp)); } static bool is_word_character(uint32 code) { @@ -622,7 +632,7 @@ static vector match_tg_urls(Slice str) { const unsigned char *end = str.uend(); const unsigned char *ptr = begin; - // '(tg|ton)://[a-z0-9_-]{1,253}([/?#][^\s\x{2000}-\x{200b}\x{200e}-\x{200f}\x{2016}-\x{206f}<>«»"]*)?' + // '(tg|ton|tonsite)://[a-z0-9_-]{1,253}([/?#][^\s\x{2000}-\x{200b}\x{200e}-\x{200f}\x{2016}-\x{206f}<>«»"]*)?' Slice bad_path_end_chars(".:;,('?!`"); @@ -638,6 +648,10 @@ static vector match_tg_urls(Slice str) { url_begin = ptr - 2; } else if (ptr - begin >= 3 && to_lower(ptr[-3]) == 't' && to_lower(ptr[-2]) == 'o' && to_lower(ptr[-1]) == 'n') { url_begin = ptr - 3; + } else if (ptr - begin >= 7 && to_lower(ptr[-7]) == 't' && to_lower(ptr[-6]) == 'o' && to_lower(ptr[-5]) == 'n' && + to_lower(ptr[-4]) == 's' && to_lower(ptr[-3]) == 'i' && to_lower(ptr[-2]) == 't' && + to_lower(ptr[-1]) == 'e') { + url_begin = ptr - 3; } } if (url_begin == nullptr) { @@ -857,6 +871,8 @@ static vector match_urls(Slice str) { url_begin_ptr = url_begin_ptr - 8; } else if (ends_with(protocol, "ftp") && protocol != "tftp" && protocol != "sftp") { url_begin_ptr = url_begin_ptr - 6; + } else if (ends_with(protocol, "tonsite")) { + url_begin_ptr = url_begin_ptr - 10; } else { is_bad = true; } @@ -1015,133 +1031,123 @@ bool is_email_address(Slice str) { static bool is_common_tld(Slice str) { static const FlatHashSet tlds( - {"aaa", "aarp", "abarth", "abb", "abbott", "abbvie", "abc", "able", "abogado", "abudhabi", "ac", "academy", - "accenture", "accountant", "accountants", "aco", "active", "actor", "ad", "adac", "ads", "adult", "ae", "aeg", - "aero", "aetna", "af", "afamilycompany", "afl", "africa", "ag", "agakhan", "agency", "ai", "aig", "aigo", - "airbus", "airforce", "airtel", "akdn", "al", "alfaromeo", "alibaba", "alipay", "allfinanz", "allstate", "ally", - "alsace", "alstom", "am", "americanexpress", "americanfamily", "amex", "amfam", "amica", "amsterdam", - "analytics", "android", "anquan", "anz", "ao", "aol", "apartments", "app", "apple", "aq", "aquarelle", "ar", - "arab", "aramco", "archi", "army", "arpa", "art", "arte", "as", "asda", "asia", "associates", "at", "athleta", - "attorney", "au", "auction", "audi", "audible", "audio", "auspost", "author", "auto", "autos", "avianca", "aw", - "aws", "ax", "axa", "az", "azure", "ba", "baby", "baidu", "banamex", "bananarepublic", "band", "bank", "bar", - "barcelona", "barclaycard", "barclays", "barefoot", "bargains", "baseball", "basketball", "bauhaus", "bayern", - "bb", "bbc", "bbt", "bbva", "bcg", "bcn", "bd", "be", "beats", "beauty", "beer", "bentley", "berlin", "best", - "bestbuy", "bet", "bf", "bg", "bh", "bharti", "bi", "bible", "bid", "bike", "bing", "bingo", "bio", "biz", "bj", - "black", "blackfriday", "blanco", "blockbuster", "blog", "bloomberg", "blue", "bm", "bms", "bmw", "bn", "bnl", - "bnpparibas", "bo", "boats", "boehringer", "bofa", "bom", "bond", "boo", "book", "booking", "boots", "bosch", - "bostik", "boston", "bot", "boutique", "box", "br", "bradesco", "bridgestone", "broadway", "broker", "brother", - "brussels", "bs", "bt", "budapest", "bugatti", "build", "builders", "business", "buy", "buzz", "bv", "bw", "by", - "bz", "bzh", "ca", "cab", "cafe", "cal", "call", "calvinklein", "cam", "camera", "camp", "cancerresearch", - "canon", "capetown", "capital", "capitalone", "car", "caravan", "cards", "care", "career", "careers", "cars", - "cartier", "casa", "case", "caseih", "cash", "casino", "cat", "catering", "catholic", "cba", "cbn", "cbre", - "cbs", "cc", "cd", "ceb", "center", "ceo", "cern", "cf", "cfa", "cfd", "cg", "ch", "chanel", "channel", "chase", - "chat", "cheap", "chintai", "christmas", "chrome", "chrysler", "church", "ci", "cipriani", "circle", "cisco", - "citadel", "citi", "citic", "city", "cityeats", "ck", "cl", "claims", "cleaning", "click", "clinic", "clinique", - "clothing", "cloud", "club", "clubmed", "cm", "cn", "co", "coach", "codes", "coffee", "college", "cologne", - "com", "comcast", "commbank", "community", "company", "compare", "computer", "comsec", "condos", "construction", - "consulting", "contact", "contractors", "cooking", "cookingchannel", "cool", "coop", "corsica", "country", - "coupon", "coupons", "courses", "cr", "credit", "creditcard", "creditunion", "cricket", "crown", "crs", "cruise", - "cruises", "csc", "cu", "cuisinella", "cv", "cw", "cx", "cy", "cymru", "cyou", "cz", "dabur", "dad", "dance", - "data", "date", "dating", "datsun", "day", "dclk", "dds", "de", "deal", "dealer", "deals", "degree", "delivery", - "dell", "deloitte", "delta", "democrat", "dental", "dentist", "desi", "design", "dev", "dhl", "diamonds", "diet", + {"aaa", "aarp", "abb", "abbott", "abbvie", "abc", "able", "abogado", "abudhabi", "ac", "academy", "accenture", + "accountant", "accountants", "aco", "actor", "ad", "ads", "adult", "ae", "aeg", "aero", "aetna", "af", "afl", + "africa", "ag", "agakhan", "agency", "ai", "aig", "airbus", "airforce", "airtel", "akdn", "al", "alibaba", + "alipay", "allfinanz", "allstate", "ally", "alsace", "alstom", "am", "amazon", "americanexpress", + "americanfamily", "amex", "amfam", "amica", "amsterdam", "analytics", "android", "anquan", "anz", "ao", "aol", + "apartments", "app", "apple", "aq", "aquarelle", "ar", "arab", "aramco", "archi", "army", "arpa", "art", "arte", + "as", "asda", "asia", "associates", "at", "athleta", "attorney", "au", "auction", "audi", "audible", "audio", + "auspost", "author", "auto", "autos", "aw", "aws", "ax", "axa", "az", "azure", "ba", "baby", "baidu", "banamex", + "band", "bank", "bar", "barcelona", "barclaycard", "barclays", "barefoot", "bargains", "baseball", "basketball", + "bauhaus", "bayern", "bb", "bbc", "bbt", "bbva", "bcg", "bcn", "bd", "be", "beats", "beauty", "beer", "bentley", + "berlin", "best", "bestbuy", "bet", "bf", "bg", "bh", "bharti", "bi", "bible", "bid", "bike", "bing", "bingo", + "bio", "biz", "bj", "black", "blackfriday", "blockbuster", "blog", "bloomberg", "blue", "bm", "bms", "bmw", "bn", + "bnpparibas", "bo", "boats", "boehringer", "bofa", "bom", "bond", "boo", "book", "booking", "bosch", "bostik", + "boston", "bot", "boutique", "box", "br", "bradesco", "bridgestone", "broadway", "broker", "brother", "brussels", + "bs", "bt", "build", "builders", "business", "buy", "buzz", "bv", "bw", "by", "bz", "bzh", "ca", "cab", "cafe", + "cal", "call", "calvinklein", "cam", "camera", "camp", "canon", "capetown", "capital", "capitalone", "car", + "caravan", "cards", "care", "career", "careers", "cars", "casa", "case", "cash", "casino", "cat", "catering", + "catholic", "cba", "cbn", "cbre", "cc", "cd", "center", "ceo", "cern", "cf", "cfa", "cfd", "cg", "ch", "chanel", + "channel", "charity", "chase", "chat", "cheap", "chintai", "christmas", "chrome", "church", "ci", "cipriani", + "circle", "cisco", "citadel", "citi", "citic", "city", "ck", "cl", "claims", "cleaning", "click", "clinic", + "clinique", "clothing", "cloud", "club", "clubmed", "cm", "cn", "co", "coach", "codes", "coffee", "college", + "cologne", "com", "commbank", "community", "company", "compare", "computer", "comsec", "condos", "construction", + "consulting", "contact", "contractors", "cooking", "cool", "coop", "corsica", "country", "coupon", "coupons", + "courses", "cpa", "cr", "credit", "creditcard", "creditunion", "cricket", "crown", "crs", "cruise", "cruises", + "cu", "cuisinella", "cv", "cw", "cx", "cy", "cymru", "cyou", "cz", "dabur", "dad", "dance", "data", "date", + "dating", "datsun", "day", "dclk", "dds", "de", "deal", "dealer", "deals", "degree", "delivery", "dell", + "deloitte", "delta", "democrat", "dental", "dentist", "desi", "design", "dev", "dhl", "diamonds", "diet", "digital", "direct", "directory", "discount", "discover", "dish", "diy", "dj", "dk", "dm", "dnp", "do", "docs", - "doctor", "dodge", "dog", "doha", "domains", "dot", "download", "drive", "dtv", "dubai", "duck", "dunlop", - "duns", "dupont", "durban", "dvag", "dvr", "dz", "earth", "eat", "ec", "eco", "edeka", "edu", "education", "ee", - "eg", "email", "emerck", "energy", "engineer", "engineering", "enterprises", "epost", "epson", "equipment", "er", - "ericsson", "erni", "es", "esq", "estate", "esurance", "et", "etisalat", "eu", "eurovision", "eus", "events", - "everbank", "exchange", "expert", "exposed", "express", "extraspace", "fage", "fail", "fairwinds", "faith", - "family", "fan", "fans", "farm", "farmers", "fashion", "fast", "fedex", "feedback", "ferrari", "ferrero", "fi", - "fiat", "fidelity", "fido", "film", "final", "finance", "financial", "fire", "firestone", "firmdale", "fish", - "fishing", "fit", "fitness", "fj", "fk", "flickr", "flights", "flir", "florist", "flowers", "fly", "fm", "fo", - "foo", "food", "foodnetwork", "football", "ford", "forex", "forsale", "forum", "foundation", "fox", "fr", "free", - "fresenius", "frl", "frogans", "frontdoor", "frontier", "ftr", "fujitsu", "fujixerox", "fun", "fund", - "furniture", "futbol", "fyi", "ga", "gal", "gallery", "gallo", "gallup", "game", "games", "gap", "garden", "gb", - "gbiz", "gd", "gdn", "ge", "gea", "gent", "genting", "george", "gf", "gg", "ggee", "gh", "gi", "gift", "gifts", - "gives", "giving", "gl", "glade", "glass", "gle", "global", "globo", "gm", "gmail", "gmbh", "gmo", "gmx", "gn", - "godaddy", "gold", "goldpoint", "golf", "goo", "goodhands", "goodyear", "goog", "google", "gop", "got", "gov", - "gp", "gq", "gr", "grainger", "graphics", "gratis", "green", "gripe", "grocery", "group", "gs", "gt", "gu", - "guardian", "gucci", "guge", "guide", "guitars", "guru", "gw", "gy", "hair", "hamburg", "hangout", "haus", "hbo", - "hdfc", "hdfcbank", "health", "healthcare", "help", "helsinki", "here", "hermes", "hgtv", "hiphop", "hisamitsu", - "hitachi", "hiv", "hk", "hkt", "hm", "hn", "hockey", "holdings", "holiday", "homedepot", "homegoods", "homes", - "homesense", "honda", "honeywell", "horse", "hospital", "host", "hosting", "hot", "hoteles", "hotels", "hotmail", - "house", "how", "hr", "hsbc", "ht", "hu", "hughes", "hyatt", "hyundai", "ibm", "icbc", "ice", "icu", "id", "ie", - "ieee", "ifm", "ikano", "il", "im", "imamat", "imdb", "immo", "immobilien", "in", "industries", "infiniti", - "info", "ing", "ink", "institute", "insurance", "insure", "int", "intel", "international", "intuit", - "investments", "io", "ipiranga", "iq", "ir", "irish", "is", "iselect", "ismaili", "ist", "istanbul", "it", - "itau", "itv", "iveco", "iwc", "jaguar", "java", "jcb", "jcp", "je", "jeep", "jetzt", "jewelry", "jio", "jlc", - "jll", "jm", "jmp", "jnj", "jo", "jobs", "joburg", "jot", "joy", "jp", "jpmorgan", "jprs", "juegos", "juniper", - "kaufen", "kddi", "ke", "kerryhotels", "kerrylogistics", "kerryproperties", "kfh", "kg", "kh", "ki", "kia", - "kim", "kinder", "kindle", "kitchen", "kiwi", "km", "kn", "koeln", "komatsu", "kosher", "kp", "kpmg", "kpn", - "kr", "krd", "kred", "kuokgroup", "kw", "ky", "kyoto", "kz", "la", "lacaixa", "ladbrokes", "lamborghini", - "lamer", "lancaster", "lancia", "lancome", "land", "landrover", "lanxess", "lasalle", "lat", "latino", "latrobe", - "law", "lawyer", "lb", "lc", "lds", "lease", "leclerc", "lefrak", "legal", "lego", "lexus", "lgbt", "li", - "liaison", "lidl", "life", "lifeinsurance", "lifestyle", "lighting", "like", "lilly", "limited", "limo", - "lincoln", "linde", "link", "lipsy", "live", "living", "lixil", "lk", "loan", "loans", "locker", "locus", "loft", - "lol", "london", "lotte", "lotto", "love", "lpl", "lplfinancial", "lr", "ls", "lt", "ltd", "ltda", "lu", - "lundbeck", "lupin", "luxe", "luxury", "lv", "ly", "ma", "macys", "madrid", "maif", "maison", "makeup", "man", - "management", "mango", "map", "market", "marketing", "markets", "marriott", "marshalls", "maserati", "mattel", - "mba", "mc", "mckinsey", "md", "me", "med", "media", "meet", "melbourne", "meme", "memorial", "men", "menu", - "meo", "merckmsd", "metlife", "mg", "mh", "miami", "microsoft", "mil", "mini", "mint", "mit", "mitsubishi", "mk", - "ml", "mlb", "mls", "mm", "mma", "mn", "mo", "mobi", "mobile", "mobily", "moda", "moe", "moi", "mom", "monash", - "money", "monster", "mopar", "mormon", "mortgage", "moscow", "moto", "motorcycles", "mov", "movie", "movistar", - "mp", "mq", "mr", "ms", "msd", "mt", "mtn", "mtr", "mu", "museum", "mutual", "mv", "mw", "mx", "my", "mz", "na", - "nab", "nadex", "nagoya", "name", "nationwide", "natura", "navy", "nba", "nc", "ne", "nec", "net", "netbank", - "netflix", "network", "neustar", "new", "newholland", "news", "next", "nextdirect", "nexus", "nf", "nfl", "ng", - "ngo", "nhk", "ni", "nico", "nike", "nikon", "ninja", "nissan", "nissay", "nl", "no", "nokia", - "northwesternmutual", "norton", "now", "nowruz", "nowtv", "np", "nr", "nra", "nrw", "ntt", "nu", "nyc", "nz", - "obi", "observer", "off", "office", "okinawa", "olayan", "olayangroup", "oldnavy", "ollo", "om", "omega", "one", - "ong", "onion", "onl", "online", "onyourside", "ooo", "open", "oracle", "orange", "org", "organic", "origins", - "osaka", "otsuka", "ott", "ovh", "pa", "page", "panasonic", "panerai", "paris", "pars", "partners", "parts", - "party", "passagens", "pay", "pccw", "pe", "pet", "pf", "pfizer", "pg", "ph", "pharmacy", "phd", "philips", - "phone", "photo", "photography", "photos", "physio", "piaget", "pics", "pictet", "pictures", "pid", "pin", - "ping", "pink", "pioneer", "pizza", "pk", "pl", "place", "play", "playstation", "plumbing", "plus", "pm", "pn", - "pnc", "pohl", "poker", "politie", "porn", "post", "pr", "pramerica", "praxi", "press", "prime", "pro", "prod", - "productions", "prof", "progressive", "promo", "properties", "property", "protection", "pru", "prudential", "ps", - "pt", "pub", "pw", "pwc", "py", "qa", "qpon", "quebec", "quest", "qvc", "racing", "radio", "raid", "re", "read", - "realestate", "realtor", "realty", "recipes", "red", "redstone", "redumbrella", "rehab", "reise", "reisen", - "reit", "reliance", "ren", "rent", "rentals", "repair", "report", "republican", "rest", "restaurant", "review", - "reviews", "rexroth", "rich", "richardli", "ricoh", "rightathome", "ril", "rio", "rip", "rmit", "ro", "rocher", - "rocks", "rodeo", "rogers", "room", "rs", "rsvp", "ru", "rugby", "ruhr", "run", "rw", "rwe", "ryukyu", "sa", - "saarland", "safe", "safety", "sakura", "sale", "salon", "samsclub", "samsung", "sandvik", "sandvikcoromant", - "sanofi", "sap", "sapo", "sarl", "sas", "save", "saxo", "sb", "sbi", "sbs", "sc", "sca", "scb", "schaeffler", - "schmidt", "scholarships", "school", "schule", "schwarz", "science", "scjohnson", "scor", "scot", "sd", "se", - "search", "seat", "secure", "security", "seek", "select", "sener", "services", "ses", "seven", "sew", "sex", - "sexy", "sfr", "sg", "sh", "shangrila", "sharp", "shaw", "shell", "shia", "shiksha", "shoes", "shop", "shopping", - "shouji", "show", "showtime", "shriram", "si", "silk", "sina", "singles", "site", "sj", "sk", "ski", "skin", - "sky", "skype", "sl", "sling", "sm", "smart", "smile", "sn", "sncf", "so", "soccer", "social", "softbank", - "software", "sohu", "solar", "solutions", "song", "sony", "soy", "space", "spiegel", "sport", "spot", - "spreadbetting", "sr", "srl", "srt", "st", "stada", "staples", "star", "starhub", "statebank", "statefarm", - "statoil", "stc", "stcgroup", "stockholm", "storage", "store", "stream", "studio", "study", "style", "su", - "sucks", "supplies", "supply", "support", "surf", "surgery", "suzuki", "sv", "swatch", "swiftcover", "swiss", - "sx", "sy", "sydney", "symantec", "systems", "sz", "tab", "taipei", "talk", "taobao", "target", "tatamotors", - "tatar", "tattoo", "tax", "taxi", "tc", "tci", "td", "tdk", "team", "tech", "technology", "tel", "telecity", - "telefonica", "temasek", "tennis", "teva", "tf", "tg", "th", "thd", "theater", "theatre", "tiaa", "tickets", - "tienda", "tiffany", "tips", "tires", "tirol", "tj", "tjmaxx", "tjx", "tk", "tkmaxx", "tl", "tm", "tmall", "tn", - "to", "today", "tokyo", "tools", "top", "toray", "toshiba", "total", "tours", "town", "toyota", "toys", "tr", - "trade", "trading", "training", "travel", "travelchannel", "travelers", "travelersinsurance", "trust", "trv", - "tt", "tube", "tui", "tunes", "tushu", "tv", "tvs", "tw", "tz", "ua", "ubank", "ubs", "uconnect", "ug", "uk", - "unicom", "university", "uno", "uol", "ups", "us", "uy", "uz", "va", "vacations", "vana", "vanguard", "vc", "ve", - "vegas", "ventures", "verisign", "versicherung", "vet", "vg", "vi", "viajes", "video", "vig", "viking", "villas", - "vin", "vip", "virgin", "visa", "vision", "vista", "vistaprint", "viva", "vivo", "vlaanderen", "vn", "vodka", - "volkswagen", "volvo", "vote", "voting", "voto", "voyage", "vu", "vuelos", "wales", "walmart", "walter", "wang", - "wanggou", "warman", "watch", "watches", "weather", "weatherchannel", "webcam", "weber", "website", "wed", - "wedding", "weibo", "weir", "wf", "whoswho", "wien", "wiki", "williamhill", "win", "windows", "wine", "winners", - "wme", "wolterskluwer", "woodside", "work", "works", "world", "wow", "ws", "wtc", "wtf", "xbox", "xerox", - "xfinity", "xihuan", "xin", "कॉम", "セール", "佛山", "ಭಾರತ", "慈善", "集团", "在线", "한국", "ଭାରତ", "大众汽车", - "点看", "คอม", "ভাৰত", "ভারত", "八卦", "موقع", "বাংলা", "公益", "公司", "香格里拉", "网站", "移动", "我爱你", - "москва", "қаз", "католик", "онлайн", "сайт", "联通", "срб", "бг", "бел", "קום", "时尚", "微博", "淡马锡", - "ファッション", "орг", "नेट", "ストア", "삼성", "சிங்கப்பூர்", "商标", "商店", "商城", "дети", "мкд", "ею", - "ポイント", "新闻", "工行", "家電", "كوم", "中文网", "中信", "中国", "中國", "娱乐", "谷歌", "భారత్", "ලංකා", - "電訊盈科", "购物", "クラウド", "ભારત", "通販", "भारतम्", "भारत", "भारोत", "网店", "संगठन", "餐厅", "网络", "ком", - "укр", "香港", "诺基亚", "食品", "飞利浦", "台湾", "台灣", "手表", "手机", "мон", "الجزائر", "عمان", "ارامكو", - "ایران", "العليان", "اتصالات", "امارات", "بازار", "پاکستان", "الاردن", "موبايلي", "بارت", "بھارت", "المغرب", - "ابوظبي", "السعودية", "ڀارت", "كاثوليك", "سودان", "همراه", "عراق", "مليسيا", "澳門", "닷컴", "政府", "شبكة", - "بيتك", "عرب", "გე", "机构", "组织机构", "健康", "ไทย", "سورية", "招聘", "рус", "рф", "珠宝", "تونس", "大拿", - "みんな", "グーグル", "ελ", "世界", "書籍", "ഭാരതം", "ਭਾਰਤ", "网址", "닷넷", "コム", "天主教", "游戏", - "vermögensberater", "vermögensberatung", "企业", "信息", "嘉里大酒店", "嘉里", "مصر", "قطر", "广东", "இலங்கை", - "இந்தியா", "հայ", "新加坡", "فلسطين", "政务", "xperia", "xxx", "xyz", "yachts", "yahoo", "yamaxun", "yandex", - "ye", "yodobashi", "yoga", "yokohama", "you", "youtube", "yt", "yun", "za", "zappos", "zara", "zero", "zip", - "zippo", "zm", "zone", "zuerich", + "doctor", "dog", "domains", "dot", "download", "drive", "dtv", "dubai", "dunlop", "dupont", "durban", "dvag", + "dvr", "dz", "earth", "eat", "ec", "eco", "edeka", "edu", "education", "ee", "eg", "email", "emerck", "energy", + "engineer", "engineering", "enterprises", "epson", "equipment", "er", "ericsson", "erni", "es", "esq", "estate", + "et", "eu", "eurovision", "eus", "events", "exchange", "expert", "exposed", "express", "extraspace", "fage", + "fail", "fairwinds", "faith", "family", "fan", "fans", "farm", "farmers", "fashion", "fast", "fedex", "feedback", + "ferrari", "ferrero", "fi", "fidelity", "fido", "film", "final", "finance", "financial", "fire", "firestone", + "firmdale", "fish", "fishing", "fit", "fitness", "fj", "fk", "flickr", "flights", "flir", "florist", "flowers", + "fly", "fm", "fo", "foo", "food", "football", "ford", "forex", "forsale", "forum", "foundation", "fox", "fr", + "free", "fresenius", "frl", "frogans", "frontier", "ftr", "fujitsu", "fun", "fund", "furniture", "futbol", "fyi", + "ga", "gal", "gallery", "gallo", "gallup", "game", "games", "gap", "garden", "gay", "gb", "gbiz", "gd", "gdn", + "ge", "gea", "gent", "genting", "george", "gf", "gg", "ggee", "gh", "gi", "gift", "gifts", "gives", "giving", + "gl", "glass", "gle", "global", "globo", "gm", "gmail", "gmbh", "gmo", "gmx", "gn", "godaddy", "gold", + "goldpoint", "golf", "goo", "goodyear", "goog", "google", "gop", "got", "gov", "gp", "gq", "gr", "grainger", + "graphics", "gratis", "green", "gripe", "grocery", "group", "gs", "gt", "gu", "gucci", "guge", "guide", + "guitars", "guru", "gw", "gy", "hair", "hamburg", "hangout", "haus", "hbo", "hdfc", "hdfcbank", "health", + "healthcare", "help", "helsinki", "here", "hermes", "hiphop", "hisamitsu", "hitachi", "hiv", "hk", "hkt", "hm", + "hn", "hockey", "holdings", "holiday", "homedepot", "homegoods", "homes", "homesense", "honda", "horse", + "hospital", "host", "hosting", "hot", "hotels", "hotmail", "house", "how", "hr", "hsbc", "ht", "hu", "hughes", + "hyatt", "hyundai", "ibm", "icbc", "ice", "icu", "id", "ie", "ieee", "ifm", "ikano", "il", "im", "imamat", + "imdb", "immo", "immobilien", "in", "inc", "industries", "infiniti", "info", "ing", "ink", "institute", + "insurance", "insure", "int", "international", "intuit", "investments", "io", "ipiranga", "iq", "ir", "irish", + "is", "ismaili", "ist", "istanbul", "it", "itau", "itv", "jaguar", "java", "jcb", "je", "jeep", "jetzt", + "jewelry", "jio", "jll", "jm", "jmp", "jnj", "jo", "jobs", "joburg", "jot", "joy", "jp", "jpmorgan", "jprs", + "juegos", "juniper", "kaufen", "kddi", "ke", "kerryhotels", "kerrylogistics", "kerryproperties", "kfh", "kg", + "kh", "ki", "kia", "kids", "kim", "kindle", "kitchen", "kiwi", "km", "kn", "koeln", "komatsu", "kosher", "kp", + "kpmg", "kpn", "kr", "krd", "kred", "kuokgroup", "kw", "ky", "kyoto", "kz", "la", "lacaixa", "lamborghini", + "lamer", "lancaster", "land", "landrover", "lanxess", "lasalle", "lat", "latino", "latrobe", "law", "lawyer", + "lb", "lc", "lds", "lease", "leclerc", "lefrak", "legal", "lego", "lexus", "lgbt", "li", "lidl", "life", + "lifeinsurance", "lifestyle", "lighting", "like", "lilly", "limited", "limo", "lincoln", "link", "lipsy", "live", + "living", "lk", "llc", "llp", "loan", "loans", "locker", "locus", "lol", "london", "lotte", "lotto", "love", + "lpl", "lplfinancial", "lr", "ls", "lt", "ltd", "ltda", "lu", "lundbeck", "luxe", "luxury", "lv", "ly", "ma", + "madrid", "maif", "maison", "makeup", "man", "management", "mango", "map", "market", "marketing", "markets", + "marriott", "marshalls", "mattel", "mba", "mc", "mckinsey", "md", "me", "med", "media", "meet", "melbourne", + "meme", "memorial", "men", "menu", "merckmsd", "mg", "mh", "miami", "microsoft", "mil", "mini", "mint", "mit", + "mitsubishi", "mk", "ml", "mlb", "mls", "mm", "mma", "mn", "mo", "mobi", "mobile", "moda", "moe", "moi", "mom", + "monash", "money", "monster", "mormon", "mortgage", "moscow", "moto", "motorcycles", "mov", "movie", "mp", "mq", + "mr", "ms", "msd", "mt", "mtn", "mtr", "mu", "museum", "music", "mv", "mw", "mx", "my", "mz", "na", "nab", + "nagoya", "name", "navy", "nba", "nc", "ne", "nec", "net", "netbank", "netflix", "network", "neustar", "new", + "news", "next", "nextdirect", "nexus", "nf", "nfl", "ng", "ngo", "nhk", "ni", "nico", "nike", "nikon", "ninja", + "nissan", "nissay", "nl", "no", "nokia", "norton", "now", "nowruz", "nowtv", "np", "nr", "nra", "nrw", "ntt", + "nu", "nyc", "nz", "obi", "observer", "office", "okinawa", "olayan", "olayangroup", "ollo", "om", "omega", "one", + "ong", "onion", "onl", "online", "ooo", "open", "oracle", "orange", "org", "organic", "origins", "osaka", + "otsuka", "ott", "ovh", "pa", "page", "panasonic", "paris", "pars", "partners", "parts", "party", "pay", "pccw", + "pe", "pet", "pf", "pfizer", "pg", "ph", "pharmacy", "phd", "philips", "phone", "photo", "photography", "photos", + "physio", "pics", "pictet", "pictures", "pid", "pin", "ping", "pink", "pioneer", "pizza", "pk", "pl", "place", + "play", "playstation", "plumbing", "plus", "pm", "pn", "pnc", "pohl", "poker", "politie", "porn", "post", "pr", + "pramerica", "praxi", "press", "prime", "pro", "prod", "productions", "prof", "progressive", "promo", + "properties", "property", "protection", "pru", "prudential", "ps", "pt", "pub", "pw", "pwc", "py", "qa", "qpon", + "quebec", "quest", "racing", "radio", "re", "read", "realestate", "realtor", "realty", "recipes", "red", + "redstone", "redumbrella", "rehab", "reise", "reisen", "reit", "reliance", "ren", "rent", "rentals", "repair", + "report", "republican", "rest", "restaurant", "review", "reviews", "rexroth", "rich", "richardli", "ricoh", + "ril", "rio", "rip", "ro", "rocks", "rodeo", "rogers", "room", "rs", "rsvp", "ru", "rugby", "ruhr", "run", "rw", + "rwe", "ryukyu", "sa", "saarland", "safe", "safety", "sakura", "sale", "salon", "samsclub", "samsung", "sandvik", + "sandvikcoromant", "sanofi", "sap", "sarl", "sas", "save", "saxo", "sb", "sbi", "sbs", "sc", "scb", "schaeffler", + "schmidt", "scholarships", "school", "schule", "schwarz", "science", "scot", "sd", "se", "search", "seat", + "secure", "security", "seek", "select", "sener", "services", "seven", "sew", "sex", "sexy", "sfr", "sg", "sh", + "shangrila", "sharp", "shell", "shia", "shiksha", "shoes", "shop", "shopping", "shouji", "show", "si", "silk", + "sina", "singles", "site", "sj", "sk", "ski", "skin", "sky", "skype", "sl", "sling", "sm", "smart", "smile", + "sn", "sncf", "so", "soccer", "social", "softbank", "software", "sohu", "solar", "solutions", "song", "sony", + "soy", "spa", "space", "sport", "spot", "sr", "srl", "ss", "st", "stada", "staples", "star", "statebank", + "statefarm", "stc", "stcgroup", "stockholm", "storage", "store", "stream", "studio", "study", "style", "su", + "sucks", "supplies", "supply", "support", "surf", "surgery", "suzuki", "sv", "swatch", "swiss", "sx", "sy", + "sydney", "systems", "sz", "tab", "taipei", "talk", "taobao", "target", "tatamotors", "tatar", "tattoo", "tax", + "taxi", "tc", "tci", "td", "tdk", "team", "tech", "technology", "tel", "temasek", "tennis", "teva", "tf", "tg", + "th", "thd", "theater", "theatre", "tiaa", "tickets", "tienda", "tips", "tires", "tirol", "tj", "tjmaxx", "tjx", + "tk", "tkmaxx", "tl", "tm", "tmall", "tn", "to", "today", "tokyo", "ton", "tools", "top", "toray", "toshiba", + "total", "tours", "town", "toyota", "toys", "tr", "trade", "trading", "training", "travel", "travelers", + "travelersinsurance", "trust", "trv", "tt", "tube", "tui", "tunes", "tushu", "tv", "tvs", "tw", "tz", "ua", + "ubank", "ubs", "ug", "uk", "unicom", "university", "uno", "uol", "ups", "us", "uy", "uz", "va", "vacations", + "vana", "vanguard", "vc", "ve", "vegas", "ventures", "verisign", "vermögensberater", "vermögensberatung", + "versicherung", "vet", "vg", "vi", "viajes", "video", "vig", "viking", "villas", "vin", "vip", "virgin", "visa", + "vision", "viva", "vivo", "vlaanderen", "vn", "vodka", "volvo", "vote", "voting", "voto", "voyage", "vu", + "wales", "walmart", "walter", "wang", "wanggou", "watch", "watches", "weather", "weatherchannel", "webcam", + "weber", "website", "wed", "wedding", "weibo", "weir", "wf", "whoswho", "wien", "wiki", "williamhill", "win", + "windows", "wine", "winners", "wme", "wolterskluwer", "woodside", "work", "works", "world", "wow", "ws", "wtc", + "wtf", "xbox", "xerox", "xihuan", "xin", "ελ", "ευ", "бг", "бел", "дети", "ею", "католик", "ком", "мкд", "мон", + "москва", "онлайн", "орг", "рус", "рф", "сайт", "срб", "укр", "қаз", "հայ", "ישראל", "קום", "ابوظبي", "ارامكو", + "الاردن", "البحرين", "الجزائر", "السعودية", "العليان", "المغرب", "امارات", "ایران", "بارت", "بازار", "بيتك", + "بھارت", "تونس", "سودان", "سورية", "شبكة", "عراق", "عرب", "عمان", "فلسطين", "قطر", "كاثوليك", "كوم", "مصر", + "مليسيا", "موريتانيا", "موقع", "همراه", "پاکستان", "ڀارت", "कॉम", "नेट", "भारत", "भारतम्", "भारोत", "संगठन", + "বাংলা", "ভারত", "ভাৰত", "ਭਾਰਤ", "ભારત", "ଭାରତ", "இந்தியா", "இலங்கை", "சிங்கப்பூர்", "భారత్", "ಭಾರತ", "ഭാരതം", "ලංකා", + "คอม", "ไทย", "ລາວ", "გე", "みんな", "アマゾン", "クラウド", "グーグル", "コム", "ストア", "セール", + "ファッション", "ポイント", "世界", "中信", "中国", "中國", "中文网", "亚马逊", "企业", "佛山", "信息", "健康", + "八卦", "公司", "公益", "台湾", "台灣", "商城", "商店", "商标", "嘉里", "嘉里大酒店", "在线", "大拿", "天主教", + "娱乐", "家電", "广东", "微博", "慈善", "我爱你", "手机", "招聘", "政务", "政府", "新加坡", "新闻", "时尚", + "書籍", "机构", "淡马锡", "游戏", "澳門", "点看", "移动", "组织机构", "网址", "网店", "网站", "网络", "联通", + "谷歌", "购物", "通販", "集团", "電訊盈科", "飞利浦", "食品", "餐厅", "香格里拉", "香港", "닷넷", "닷컴", "삼성", + "한국", "xxx", "xyz", "yachts", "yahoo", "yamaxun", "yandex", "ye", "yodobashi", "yoga", "yokohama", "you", + "youtube", "yt", "yun", "za", "zappos", "zara", "zero", "zip", "zm", "zone", "zuerich", // comment for clang-format to prevent it from placing all strings on separate lines "zw"}); bool is_lower = true; @@ -1166,8 +1172,9 @@ static Slice fix_url(Slice str) { auto full_url = str; bool has_protocol = false; - auto str_begin = to_lower(str.substr(0, 8)); - if (begins_with(str_begin, "http://") || begins_with(str_begin, "https://") || begins_with(str_begin, "ftp://")) { + auto str_begin = to_lower(str.substr(0, 10)); + if (begins_with(str_begin, "http://") || begins_with(str_begin, "https://") || begins_with(str_begin, "ftp://") || + begins_with(str_begin, "tonsite://")) { auto pos = str.find(':'); str = str.substr(pos + 3); has_protocol = true; @@ -1458,7 +1465,8 @@ static constexpr int32 get_splittable_entities_mask() { } static constexpr int32 get_blockquote_entities_mask() { - return get_entity_type_mask(MessageEntity::Type::BlockQuote); + return get_entity_type_mask(MessageEntity::Type::BlockQuote) | + get_entity_type_mask(MessageEntity::Type::ExpandableBlockQuote); } static constexpr int32 get_continuous_entities_mask() { @@ -1488,7 +1496,7 @@ static int32 is_splittable_entity(MessageEntity::Type type) { } static int32 is_blockquote_entity(MessageEntity::Type type) { - return type == MessageEntity::Type::BlockQuote; + return (get_entity_type_mask(type) & get_blockquote_entities_mask()) != 0; } static int32 is_continuous_entity(MessageEntity::Type type) { @@ -1503,12 +1511,6 @@ static int32 is_user_entity(MessageEntity::Type type) { return (get_entity_type_mask(type) & get_user_entities_mask()) != 0; } -static int32 is_hidden_data_entity(MessageEntity::Type type) { - return (get_entity_type_mask(type) & - (get_entity_type_mask(MessageEntity::Type::TextUrl) | get_entity_type_mask(MessageEntity::Type::MentionName) | - get_pre_entities_mask())) != 0; -} - static constexpr size_t SPLITTABLE_ENTITY_TYPE_COUNT = 5; static size_t get_splittable_entity_type_index(MessageEntity::Type type) { @@ -1566,6 +1568,10 @@ static bool are_entities_valid(const vector &entities) { // continuous and blockquote can't be part of other continuous entity return false; } + if (is_blockquote_entity(entity.type) && (nested_entity_type_mask & get_blockquote_entities_mask()) != 0) { + // blockquote entities can't be nested + return false; + } if ((nested_entity_type_mask & get_splittable_entities_mask()) != 0) { // the previous nested entity may be needed to split for consistency // alternatively, better entity merging needs to be implemented @@ -1619,7 +1625,7 @@ static void remove_entities_intersecting_blockquote(vector &entit size_t left_entities = 0; for (size_t i = 0; i < entities.size(); i++) { while (blockquote_it != blockquote_entities.end() && - (blockquote_it->type != MessageEntity::Type::BlockQuote || + (!is_blockquote_entity(blockquote_it->type) || blockquote_it->offset + blockquote_it->length <= entities[i].offset)) { ++blockquote_it; } @@ -1775,7 +1781,7 @@ static bool is_plain_domain(Slice url) { return url.find('/') >= url.size() && url.find('?') >= url.size() && url.find('#') >= url.size(); } -string get_first_url(const FormattedText &text) { +Slice get_first_url(const FormattedText &text) { for (auto &entity : text.entities) { switch (entity.type) { case MessageEntity::Type::Mention: @@ -1789,11 +1795,12 @@ string get_first_url(const FormattedText &text) { continue; } auto url = utf8_utf16_substr(text.text, entity.offset, entity.length); - string scheme = to_lower(url.substr(0, 4)); - if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:" || is_plain_domain(url)) { + string scheme = to_lower(url.substr(0, 8)); + if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:" || scheme == "tonsite:" || + is_plain_domain(url)) { continue; } - return url.str(); + return url; } case MessageEntity::Type::EmailAddress: break; @@ -1815,10 +1822,11 @@ string get_first_url(const FormattedText &text) { break; case MessageEntity::Type::TextUrl: { Slice url = entity.argument; - if (begins_with(url, "ton:") || begins_with(url, "tg:") || begins_with(url, "ftp:")) { + string scheme = to_lower(url.substr(0, 8)); + if (scheme == "ton:" || begins_with(scheme, "tg:") || scheme == "ftp:" || scheme == "tonsite:") { continue; } - return url.str(); + return url; } case MessageEntity::Type::MentionName: break; @@ -1834,12 +1842,36 @@ string get_first_url(const FormattedText &text) { break; case MessageEntity::Type::CustomEmoji: break; + case MessageEntity::Type::ExpandableBlockQuote: + break; default: UNREACHABLE(); } } - return string(); + return Slice(); +} + +bool is_visible_url(const FormattedText &text, const string &url) { + if (url.empty()) { + return false; + } + + auto url_size = static_cast(utf8_utf16_length(url)); + auto cur_offset = 0; + Slice left_text = text.text; + for (auto &entity : text.entities) { + if (entity.type == MessageEntity::Type::Url && url_size == entity.length) { + CHECK(entity.offset >= cur_offset); + left_text = utf8_utf16_substr(left_text, entity.offset - cur_offset); + cur_offset = entity.offset; + if (begins_with(left_text, url)) { + return true; + } + } + } + + return false; } Result> parse_markdown(string &text) { @@ -1982,18 +2014,23 @@ Result> parse_markdown_v2(string &text) { , entity_begin_pos(entity_begin_pos) { } }; - std::vector nested_entities; + vector nested_entities; + bool have_blockquote = false; + bool can_start_blockquote = true; for (size_t i = 0; i < text.size(); i++) { auto c = static_cast(text[i]); if (c == '\\' && text[i + 1] > 0 && text[i + 1] <= 126) { i++; utf16_offset += 1; text[result_size++] = text[i]; + if (text[i] != '\r') { + can_start_blockquote = (text[i] == '\n'); + } continue; } - Slice reserved_characters("_*[]()~`>#+-=|{}.!"); + Slice reserved_characters("_*[]()~`>#+-=|{}.!\n"); if (!nested_entities.empty()) { switch (nested_entities.back().type) { case MessageEntity::Type::Code: @@ -2009,41 +2046,48 @@ Result> parse_markdown_v2(string &text) { if (reserved_characters.find(text[i]) == Slice::npos) { if (is_utf8_character_first_code_unit(c)) { utf16_offset += 1 + (c >= 0xf0); // >= 4 bytes in symbol => surrogate pair + if (c != '\r') { + can_start_blockquote = false; + } } text[result_size++] = text[i]; continue; } - bool is_end_of_an_entity = false; - if (!nested_entities.empty()) { - is_end_of_an_entity = [&] { - switch (nested_entities.back().type) { - case MessageEntity::Type::Bold: - return c == '*'; - case MessageEntity::Type::Italic: - return c == '_' && text[i + 1] != '_'; - case MessageEntity::Type::Code: - return c == '`'; - case MessageEntity::Type::Pre: - case MessageEntity::Type::PreCode: - return c == '`' && text[i + 1] == '`' && text[i + 2] == '`'; - case MessageEntity::Type::TextUrl: - return c == ']'; - case MessageEntity::Type::Underline: - return c == '_' && text[i + 1] == '_'; - case MessageEntity::Type::Strikethrough: - return c == '~'; - case MessageEntity::Type::Spoiler: - return c == '|' && text[i + 1] == '|'; - case MessageEntity::Type::CustomEmoji: - return c == ']'; - default: - UNREACHABLE(); - return false; - } - }(); - } - + bool is_end_of_an_entity = [&] { + if (nested_entities.empty()) { + return false; + } + if (have_blockquote && c == '\n' && (i + 1 == text.size() || text[i + 1] != '>')) { + return true; + } + switch (nested_entities.back().type) { + case MessageEntity::Type::Bold: + return c == '*'; + case MessageEntity::Type::Italic: + return c == '_' && text[i + 1] != '_'; + case MessageEntity::Type::Code: + return c == '`'; + case MessageEntity::Type::Pre: + case MessageEntity::Type::PreCode: + return c == '`' && text[i + 1] == '`' && text[i + 2] == '`'; + case MessageEntity::Type::TextUrl: + return c == ']'; + case MessageEntity::Type::Underline: + return c == '_' && text[i + 1] == '_'; + case MessageEntity::Type::Strikethrough: + return c == '~'; + case MessageEntity::Type::Spoiler: + return c == '|' && text[i + 1] == '|'; + case MessageEntity::Type::CustomEmoji: + return c == ']'; + case MessageEntity::Type::BlockQuote: + return false; + default: + UNREACHABLE(); + return false; + } + }(); if (!is_end_of_an_entity) { // begin of an entity MessageEntity::Type type; @@ -2112,14 +2156,53 @@ Result> parse_markdown_v2(string &text) { << "' is reserved and must be escaped with the preceding '\\'"); } break; + case '\n': + utf16_offset += 1; + text[result_size++] = '\n'; + can_start_blockquote = true; + type = MessageEntity::Type::Size; + break; + case '>': + if (can_start_blockquote) { + if (have_blockquote) { + type = MessageEntity::Type::Size; + } else { + type = MessageEntity::Type::BlockQuote; + have_blockquote = true; + } + } else { + return Status::Error(400, PSLICE() << "Character '" << text[i] + << "' is reserved and must be escaped with the preceding '\\'"); + } + break; default: return Status::Error( 400, PSLICE() << "Character '" << text[i] << "' is reserved and must be escaped with the preceding '\\'"); } + if (type == MessageEntity::Type::Size) { + continue; + } nested_entities.emplace_back(type, std::move(argument), utf16_offset, entity_byte_offset, result_size); } else { // end of an entity auto type = nested_entities.back().type; + if (c == '\n' && type != MessageEntity::Type::BlockQuote) { + if (type != MessageEntity::Type::Spoiler || !(nested_entities.back().entity_byte_offset == i - 2 || + (nested_entities.back().entity_byte_offset == i - 3 && + result_size != 0 && text[result_size - 1] == '\r'))) { + return Status::Error(400, PSLICE() << "Can't find end of " << nested_entities.back().type + << " entity at byte offset " << nested_entities.back().entity_byte_offset); + } + nested_entities.pop_back(); + CHECK(!nested_entities.empty()); + type = nested_entities.back().type; + if (type != MessageEntity::Type::BlockQuote) { + CHECK(type != MessageEntity::Type::Spoiler); + return Status::Error(400, PSLICE() << "Can't find end of " << nested_entities.back().type + << " entity at byte offset " << nested_entities.back().entity_byte_offset); + } + type = MessageEntity::Type::ExpandableBlockQuote; + } auto argument = std::move(nested_entities.back().argument); UserId user_id; CustomEmojiId custom_emoji_id; @@ -2192,6 +2275,15 @@ Result> parse_markdown_v2(string &text) { TRY_RESULT_ASSIGN(custom_emoji_id, LinkManager::get_link_custom_emoji_id(url)); break; } + case MessageEntity::Type::BlockQuote: + case MessageEntity::Type::ExpandableBlockQuote: + CHECK(have_blockquote); + have_blockquote = false; + text[result_size++] = text[i]; + can_start_blockquote = true; + utf16_offset += 1; + skip_entity = false; + break; default: UNREACHABLE(); return false; @@ -2211,6 +2303,25 @@ Result> parse_markdown_v2(string &text) { nested_entities.pop_back(); } } + if (have_blockquote) { + CHECK(!nested_entities.empty()); + auto type = MessageEntity::Type::BlockQuote; + if (nested_entities.back().type == MessageEntity::Type::Spoiler && + nested_entities.back().entity_byte_offset == text.size() - 2) { + nested_entities.pop_back(); + CHECK(!nested_entities.empty()); + type = MessageEntity::Type::ExpandableBlockQuote; + } + if (nested_entities.back().type == MessageEntity::Type::BlockQuote) { + have_blockquote = false; + auto entity_offset = nested_entities.back().entity_offset; + auto entity_length = utf16_offset - entity_offset; + if (entity_length != 0) { + entities.emplace_back(type, entity_offset, entity_length); + } + nested_entities.pop_back(); + } + } if (!nested_entities.empty()) { return Status::Error(400, PSLICE() << "Can't find end of " << nested_entities.back().type << " entity at byte offset " << nested_entities.back().entity_byte_offset); @@ -2626,9 +2737,29 @@ static FormattedText parse_pre_entities_v3(Slice text) { if (end_tag_end - end_tag_begin == j - i) { // end tag found CHECK(entity_length > 0); - entities.emplace_back(j - i == 3 ? MessageEntity::Type::Pre : MessageEntity::Type::Code, utf16_offset, - entity_length); - result.append(text.begin() + j, end_tag_begin - j); + auto entity_begin = j; + string language_code; + if (j - i == 3) { + size_t language_code_end = j; + while (language_code_end < end_tag_begin - 1 && 33 <= text[language_code_end] && + text[language_code_end] <= 126) { + language_code_end++; + } + if (language_code_end < end_tag_begin - 1 && text[language_code_end] == '\n') { + language_code = text.substr(entity_begin, language_code_end - entity_begin).str(); + entity_begin = language_code_end + 1; + entity_length -= static_cast(entity_begin - j); + CHECK(entity_length > 0); + } + } + if (!language_code.empty()) { + entities.emplace_back(MessageEntity::Type::PreCode, utf16_offset, entity_length, + std::move(language_code)); + } else { + entities.emplace_back(j - i == 3 ? MessageEntity::Type::Pre : MessageEntity::Type::Code, utf16_offset, + entity_length); + } + result.append(text.begin() + entity_begin, end_tag_begin - entity_begin); utf16_offset += entity_length; i = end_tag_end - 1; is_found = true; @@ -2689,10 +2820,7 @@ static FormattedText parse_pre_entities_v3(Slice text, vector ent result_text_utf16_length += part_end - max_end; } else { FormattedText parsed_text = parse_pre_entities_v3(parsed_part_text); - int32 new_skipped_length = 0; - for (auto &entity : parsed_text.entities) { - new_skipped_length += (entity.type == MessageEntity::Type::Pre ? 6 : 2); - } + auto new_skipped_length = static_cast(parsed_part_text.size() - parsed_text.text.size()); CHECK(new_skipped_length < part_end - max_end); result.text += parsed_text.text; for (auto &entity : parsed_text.entities) { @@ -2722,9 +2850,8 @@ static FormattedText parse_pre_entities_v3(Slice text, vector ent return result; } -// text entities must be valid -// returned entities must be resplit and fixed -FormattedText parse_markdown_v3(FormattedText text) { +// entities must be valid and can contain only splittable, continuous and pre entities +static FormattedText parse_markdown_v3_without_blockquote(FormattedText text) { if (text.text.find('`') != string::npos) { text = parse_pre_entities_v3(text.text, std::move(text.entities)); check_is_sorted(text.entities); @@ -2783,6 +2910,86 @@ FormattedText parse_markdown_v3(FormattedText text) { result_text_utf16_length += entity.length; part_begin = entity.offset + entity.length; } else { + CHECK(entity.offset >= part_begin); + part_entities.push_back(entity); + part_entities.back().offset -= part_begin; + } + + max_end = td::max(max_end, entity.offset + entity.length); + } + add_part(part_begin + text_length(left_text)); + + return result; +} + +// text entities must be valid +// returned entities must be resplit and fixed +FormattedText parse_markdown_v3(FormattedText text) { + bool have_blockquote = false; + for (auto &entity : text.entities) { + if (is_blockquote_entity(entity.type)) { + have_blockquote = true; + break; + } + } + if (!have_blockquote) { + // fast path + return parse_markdown_v3_without_blockquote(std::move(text)); + } + + FormattedText result; + int32 result_text_utf16_length = 0; + vector part_entities; + int32 part_begin = 0; + int32 max_end = 0; + Slice left_text = text.text; + + auto add_part = [&](int32 part_end) { + auto part_text = utf8_utf16_substr(left_text, 0, part_end - part_begin); + left_text = left_text.substr(part_text.size()); + + FormattedText part = parse_markdown_v3_without_blockquote({part_text.str(), std::move(part_entities)}); + part_entities.clear(); + + result.text += part.text; + for (auto &entity : part.entities) { + entity.offset += result_text_utf16_length; + } + append(result.entities, std::move(part.entities)); + result_text_utf16_length += text_length(part.text); + part_begin = part_end; + }; + + for (size_t i = 0; i < text.entities.size(); i++) { + auto &entity = text.entities[i]; + CHECK(is_splittable_entity(entity.type) || is_pre_entity(entity.type) || is_continuous_entity(entity.type) || + is_blockquote_entity(entity.type)); + if (is_blockquote_entity(entity.type)) { + CHECK(entity.offset >= max_end); + + add_part(entity.offset); + + auto offset = result_text_utf16_length; + result.entities.push_back(entity); + result.entities.back().offset = offset; + auto index = result.entities.size() - 1; + + while (i + 1 < text.entities.size() && + text.entities[i + 1].offset + text.entities[i + 1].length <= entity.offset + entity.length) { + i++; + auto &next_entity = text.entities[i]; + CHECK(is_splittable_entity(next_entity.type) || is_pre_entity(next_entity.type) || + is_continuous_entity(next_entity.type)); + CHECK(next_entity.offset >= part_begin); + part_entities.push_back(next_entity); + part_entities.back().offset -= part_begin; + } + CHECK(i + 1 == text.entities.size() || text.entities[i + 1].offset >= entity.offset + entity.length); + add_part(entity.offset + entity.length); + + result.entities[index].length = result_text_utf16_length - offset; + } else { + CHECK(entity.offset >= part_begin); part_entities.push_back(entity); part_entities.back().offset -= part_begin; } @@ -2822,6 +3029,14 @@ FormattedText get_markdown_v3(FormattedText text) { int32 utf16_offset = 0; int32 utf16_added = 0; + auto is_valid_language_code = [](Slice code) { + for (auto c : code) { + if (c < 33 || c > 126) { + return false; + } + } + return true; + }; for (size_t pos = 0; pos <= text.text.size(); pos++) { auto c = static_cast(text.text[pos]); if (is_utf8_character_first_code_unit(c)) { @@ -2834,6 +3049,7 @@ FormattedText get_markdown_v3(FormattedText text) { CHECK(utf16_offset == entity_end); + bool need_entity = false; switch (entity->type) { case MessageEntity::Type::Italic: result.text += "__"; @@ -2865,12 +3081,23 @@ FormattedText get_markdown_v3(FormattedText text) { result.text += "```"; utf16_added += 3; break; + case MessageEntity::Type::PreCode: + if (is_valid_language_code(entity->argument)) { + result.text += "```"; + utf16_added += 3; + } else { + need_entity = true; + } + break; default: - result.entities.push_back(*entity); - result.entities.back().offset += nested_entities_stack.back().utf16_added_before; - result.entities.back().length += utf16_added - nested_entities_stack.back().utf16_added_before; + need_entity = true; break; } + if (need_entity) { + result.entities.push_back(*entity); + result.entities.back().offset += nested_entities_stack.back().utf16_added_before; + result.entities.back().length += utf16_added - nested_entities_stack.back().utf16_added_before; + } nested_entities_stack.pop_back(); } @@ -2904,6 +3131,24 @@ FormattedText get_markdown_v3(FormattedText text) { case MessageEntity::Type::Pre: result.text += "```"; utf16_added += 3; + if (c != '\n') { + result.text += "\n"; + utf16_added++; + } + break; + case MessageEntity::Type::PreCode: + if (is_valid_language_code(text.entities[current_entity].argument)) { + result.text += "```"; + utf16_added += 3; + if (!text.entities[current_entity].argument.empty()) { + result.text += text.entities[current_entity].argument; + utf16_added += static_cast(text.entities[current_entity].argument.size()); + } + if (c != '\n') { + result.text += "\n"; + utf16_added++; + } + } break; default: // keep as is @@ -3039,7 +3284,7 @@ Result> parse_html(string &str) { if (tag_name != "a" && tag_name != "b" && tag_name != "strong" && tag_name != "i" && tag_name != "em" && tag_name != "s" && tag_name != "strike" && tag_name != "del" && tag_name != "u" && tag_name != "ins" && tag_name != "tg-spoiler" && tag_name != "tg-emoji" && tag_name != "span" && tag_name != "pre" && - tag_name != "code") { + tag_name != "code" && tag_name != "blockquote") { return Status::Error(400, PSLICE() << "Unsupported start tag \"" << tag_name << "\" at byte offset " << begin_pos); } @@ -3053,7 +3298,8 @@ Result> parse_html(string &str) { break; } auto attribute_begin_pos = i; - while (!is_space(text[i]) && text[i] != '=') { + while (!is_space(text[i]) && text[i] != '=' && text[i] != '>' && text[i] != '/' && text[i] != '"' && + text[i] != '\'') { i++; } Slice attribute_name(text + attribute_begin_pos, i - attribute_begin_pos); @@ -3065,8 +3311,14 @@ Result> parse_html(string &str) { i++; } if (text[i] != '=') { - return Status::Error(400, PSLICE() << "Expected equal sign in declaration of an attribute of the tag \"" - << tag_name << "\" at byte offset " << begin_pos); + if (text[i] == 0) { + return Status::Error(400, PSLICE() + << "Unclosed start tag \"" << tag_name << "\" at byte offset " << begin_pos); + } + if (tag_name == "blockquote" && attribute_name == Slice("expandable")) { + argument = "1"; + } + continue; } i++; while (text[i] != 0 && is_space(text[i])) { @@ -3123,6 +3375,8 @@ Result> parse_html(string &str) { argument = attribute_value.substr(3); } else if (tag_name == "tg-emoji" && attribute_name == Slice("emoji-id")) { argument = std::move(attribute_value); + } else if (tag_name == "blockquote" && attribute_name == Slice("expandable")) { + argument = "1"; } } @@ -3207,6 +3461,12 @@ Result> parse_html(string &str) { entities.emplace_back(MessageEntity::Type::Code, entity_offset, entity_length, nested_entities.back().argument); } + } else if (tag_name == "blockquote") { + if (!nested_entities.back().argument.empty()) { + entities.emplace_back(MessageEntity::Type::ExpandableBlockQuote, entity_offset, entity_length); + } else { + entities.emplace_back(MessageEntity::Type::BlockQuote, entity_offset, entity_length); + } } else { UNREACHABLE(); } @@ -3216,7 +3476,7 @@ Result> parse_html(string &str) { } if (!nested_entities.empty()) { return Status::Error( - 400, PSLICE() << "Can't find end tag corresponding to start tag " << nested_entities.back().tag_name); + 400, PSLICE() << "Can't find end tag corresponding to start tag \"" << nested_entities.back().tag_name << '"'); } for (auto &entity : entities) { @@ -3279,7 +3539,7 @@ vector> get_input_secret_message_entiti break; case MessageEntity::Type::BlockQuote: if (layer >= static_cast(SecretChatLayer::NewEntities)) { - result.push_back(make_tl_object(entity.offset, entity.length)); + // result.push_back(make_tl_object(0, false /*ignored*/, entity.offset, entity.length)); } break; case MessageEntity::Type::Code: @@ -3310,6 +3570,12 @@ vector> get_input_secret_message_entiti entity.custom_emoji_id.get())); } break; + case MessageEntity::Type::ExpandableBlockQuote: + if (layer >= static_cast(SecretChatLayer::NewEntities)) { + // result.push_back(make_tl_object( + // secret_api::messageEntityBlockquote::COLLAPSED_MASK, false /*ignored*/, entity.offset, entity.length)); + } + break; default: UNREACHABLE(); } @@ -3318,7 +3584,7 @@ vector> get_input_secret_message_entiti return result; } -Result> get_message_entities(const ContactsManager *contacts_manager, +Result> get_message_entities(const UserManager *user_manager, vector> &&input_entities, bool allow_all) { vector entities; @@ -3367,6 +3633,9 @@ Result> get_message_entities(const ContactsManager *contac case td_api::textEntityTypeStrikethrough::ID: entities.emplace_back(MessageEntity::Type::Strikethrough, offset, length); break; + case td_api::textEntityTypeBlockQuote::ID: + entities.emplace_back(MessageEntity::Type::BlockQuote, offset, length); + break; case td_api::textEntityTypeCode::ID: entities.emplace_back(MessageEntity::Type::Code, offset, length); break; @@ -3388,8 +3657,8 @@ Result> get_message_entities(const ContactsManager *contac } auto user_id = LinkManager::get_link_user_id(entity->url_); if (user_id.is_valid()) { - if (contacts_manager != nullptr) { - TRY_STATUS(contacts_manager->get_input_user(user_id)); + if (user_manager != nullptr) { + TRY_STATUS(user_manager->get_input_user(user_id)); } entities.emplace_back(offset, length, user_id); break; @@ -3404,8 +3673,8 @@ Result> get_message_entities(const ContactsManager *contac case td_api::textEntityTypeMentionName::ID: { auto entity = static_cast(input_entity->type_.get()); UserId user_id(entity->user_id_); - if (contacts_manager != nullptr) { - TRY_STATUS(contacts_manager->get_input_user(user_id)); + if (user_manager != nullptr) { + TRY_STATUS(user_manager->get_input_user(user_id)); } entities.emplace_back(offset, length, user_id); break; @@ -3430,6 +3699,9 @@ Result> get_message_entities(const ContactsManager *contac entities.emplace_back(MessageEntity::Type::CustomEmoji, offset, length, custom_emoji_id); break; } + case td_api::textEntityTypeExpandableBlockQuote::ID: + entities.emplace_back(MessageEntity::Type::ExpandableBlockQuote, offset, length); + break; default: UNREACHABLE(); } @@ -3441,7 +3713,7 @@ Result> get_message_entities(const ContactsManager *contac return std::move(entities); } -vector get_message_entities(const ContactsManager *contacts_manager, +vector get_message_entities(const UserManager *user_manager, vector> &&server_entities, const char *source) { vector entities; @@ -3517,7 +3789,8 @@ vector get_message_entities(const ContactsManager *contacts_manag } case telegram_api::messageEntityBlockquote::ID: { auto entity = static_cast(server_entity.get()); - entities.emplace_back(MessageEntity::Type::BlockQuote, entity->offset_, entity->length_); + auto type = entity->collapsed_ ? MessageEntity::Type::ExpandableBlockQuote : MessageEntity::Type::BlockQuote; + entities.emplace_back(type, entity->offset_, entity->length_); break; } case telegram_api::messageEntityCode::ID: { @@ -3552,11 +3825,11 @@ vector get_message_entities(const ContactsManager *contacts_manag LOG(ERROR) << "Receive invalid " << user_id << " in MentionName from " << source; continue; } - if (contacts_manager == nullptr) { + if (user_manager == nullptr) { LOG(ERROR) << "Receive unknown " << user_id << " in MentionName from " << source; continue; } - auto r_input_user = contacts_manager->get_input_user(user_id); + auto r_input_user = user_manager->get_input_user(user_id); if (r_input_user.is_error()) { LOG(ERROR) << "Receive wrong " << user_id << ": " << r_input_user.error() << " from " << source; continue; @@ -3717,27 +3990,35 @@ vector get_message_entities(Td *td, vector get_input_text_with_entities( - const ContactsManager *contacts_manager, const FormattedText &text, const char *source) { +telegram_api::object_ptr get_input_text_with_entities(const UserManager *user_manager, + const FormattedText &text, + const char *source) { return telegram_api::make_object( - text.text, get_input_message_entities(contacts_manager, text.entities, source)); + text.text, get_input_message_entities(user_manager, text.entities, source)); } -FormattedText get_formatted_text(const ContactsManager *contacts_manager, - telegram_api::object_ptr text_with_entities, - bool allow_empty, bool skip_new_entities, bool skip_bot_commands, +FormattedText get_formatted_text(const UserManager *user_manager, string &&text, + vector> &&server_entities, bool skip_media_timestamps, bool skip_trim, const char *source) { - CHECK(text_with_entities != nullptr); - auto entities = get_message_entities(contacts_manager, std::move(text_with_entities->entities_), source); - auto status = fix_formatted_text(text_with_entities->text_, entities, allow_empty, skip_new_entities, - skip_bot_commands, skip_media_timestamps, skip_trim); + auto entities = get_message_entities(user_manager, std::move(server_entities), source); + auto status = fix_formatted_text(text, entities, true, true, true, skip_media_timestamps, skip_trim); if (status.is_error()) { - if (!clean_input_string(text_with_entities->text_)) { - text_with_entities->text_.clear(); + LOG(ERROR) << "Receive error " << status << " from " << source << " while parsing \"" << text << "\"(" + << hex_encode(text) << ')'; + if (!clean_input_string(text)) { + text.clear(); } - entities = find_entities(text_with_entities->text_, skip_bot_commands, skip_media_timestamps); + entities = find_entities(text, true, skip_media_timestamps); } - return {std::move(text_with_entities->text_), std::move(entities)}; + return {std::move(text), std::move(entities)}; +} + +FormattedText get_formatted_text(const UserManager *user_manager, + telegram_api::object_ptr text_with_entities, + bool skip_media_timestamps, bool skip_trim, const char *source) { + CHECK(text_with_entities != nullptr); + return get_formatted_text(user_manager, std::move(text_with_entities->text_), + std::move(text_with_entities->entities_), skip_media_timestamps, skip_trim, source); } // like clean_input_string but also fixes entities @@ -3882,11 +4163,10 @@ static Result clean_input_string_with_entities(const string &text, vecto } replace_offending_characters(result); - return result; } -// removes entities containing whitespaces only +// removes empty entities // entities must be sorted by offset and length, but not necessary by type // returns {last_non_whitespace_pos, last_non_whitespace_utf16_offset} static std::pair remove_invalid_entities(const string &text, vector &entities) { @@ -3904,8 +4184,6 @@ static std::pair remove_invalid_entities(const string &text, vect } // check_is_sorted(entities); - vector nested_entities_stack; - size_t current_entity = 0; size_t last_non_whitespace_pos = text.size(); @@ -3914,49 +4192,7 @@ static std::pair remove_invalid_entities(const string &text, vect remove_empty_entities(entities); - for (size_t pos = 0; pos <= text.size(); pos++) { - while (!nested_entities_stack.empty()) { - auto *entity = nested_entities_stack.back(); - auto entity_end = entity->offset + entity->length; - if (utf16_offset < entity_end) { - break; - } - - if (last_non_whitespace_utf16_offset >= entity->offset || is_hidden_data_entity(entity->type)) { - // keep entity - // TODO check entity for validness, for example, that mentions, hashtags, cashtags and URLs are valid - } else { - entity->length = 0; - } - - nested_entities_stack.pop_back(); - } - while (current_entity < entities.size() && utf16_offset >= entities[current_entity].offset) { - nested_entities_stack.push_back(&entities[current_entity++]); - } - - if (pos == text.size()) { - break; - } - - if (!nested_entities_stack.empty() && nested_entities_stack.back()->offset == utf16_offset && - (text[pos] == '\n' || text[pos] == ' ')) { - // entities was fixed, so there can't be more than one splittable entity of each type, one blockquote and - // one continuous entity for the given offset - for (size_t i = nested_entities_stack.size(); i > 0; i--) { - auto *entity = nested_entities_stack[i - 1]; - if (entity->offset != utf16_offset || is_hidden_data_entity(entity->type)) { - break; - } - entity->offset++; - entity->length--; - if (entity->length == 0) { - CHECK(i == nested_entities_stack.size()); - nested_entities_stack.pop_back(); - } - } - } - + for (size_t pos = 0; pos < text.size(); pos++) { auto c = static_cast(text[pos]); switch (c) { case '\n': @@ -3974,11 +4210,6 @@ static std::pair remove_invalid_entities(const string &text, vect utf16_offset++; } - CHECK(nested_entities_stack.empty()); - CHECK(current_entity == entities.size()); - - remove_empty_entities(entities); - return {last_non_whitespace_pos, last_non_whitespace_utf16_offset}; } @@ -4071,7 +4302,7 @@ static vector resplit_entities(vector &&splittable return std::move(entities); } -static void fix_entities(vector &entities) { +void fix_entities(vector &entities) { sort_entities(entities); if (are_entities_valid(entities)) { @@ -4146,7 +4377,7 @@ static void merge_new_entities(vector &entities, vector &entities, bool allow_empty, bool skip_new_entities, - bool skip_bot_commands, bool skip_media_timestamps, bool skip_trim) { + bool skip_bot_commands, bool skip_media_timestamps, bool skip_trim, int32 *ltrim_count) { string result; if (entities.empty()) { // fast path @@ -4186,7 +4417,7 @@ Status fix_formatted_text(string &text, vector &entities, bool al entities.clear(); return Status::OK(); } - return Status::Error(400, "Message must be non-empty"); + return Status::Error(400, "Text must be non-empty"); } // re-fix entities if needed after removal of some characters @@ -4194,6 +4425,9 @@ Status fix_formatted_text(string &text, vector &entities, bool al // some splittable entities may be needed to be concatenated fix_entities(entities); + if (ltrim_count != nullptr) { + *ltrim_count = 0; + } if (skip_trim) { text = std::move(result); } else { @@ -4201,7 +4435,6 @@ Status fix_formatted_text(string &text, vector &entities, bool al CHECK(last_non_whitespace_pos < result.size()); result.resize(last_non_whitespace_pos + 1); while (!entities.empty() && entities.back().offset > last_non_whitespace_utf16_offset) { - CHECK(is_hidden_data_entity(entities.back().type)); entities.pop_back(); } bool need_sort = false; @@ -4225,6 +4458,9 @@ Status fix_formatted_text(string &text, vector &entities, bool al } if (first_non_whitespaces_pos > 0) { auto offset = narrow_cast(first_non_whitespaces_pos); + if (ltrim_count != nullptr) { + *ltrim_count = offset; + } text = result.substr(first_non_whitespaces_pos); for (auto &entity : entities) { entity.offset -= offset; @@ -4237,7 +4473,7 @@ Status fix_formatted_text(string &text, vector &entities, bool al LOG_CHECK(check_utf8(text)) << text; if (!allow_empty && is_empty_string(text)) { - return Status::Error(400, "Message must be non-empty"); + return Status::Error(400, "Text must be non-empty"); } constexpr size_t LENGTH_LIMIT = 35000; // server side limit @@ -4259,17 +4495,14 @@ Status fix_formatted_text(string &text, vector &entities, bool al merge_new_entities(entities, find_media_timestamp_entities(text)); } - // new whitespace-only entities could be added after splitting of entities - remove_invalid_entities(text, entities); - return Status::OK(); } -FormattedText get_message_text(const ContactsManager *contacts_manager, string message_text, +FormattedText get_message_text(const UserManager *user_manager, string message_text, vector> &&server_entities, bool skip_new_entities, bool skip_media_timestamps, int32 send_date, bool from_album, const char *source) { - auto entities = get_message_entities(contacts_manager, std::move(server_entities), source); + auto entities = get_message_entities(user_manager, std::move(server_entities), source); auto debug_message_text = message_text; auto debug_entities = entities; auto status = fix_formatted_text(message_text, entities, true, skip_new_entities, true, skip_media_timestamps, false); @@ -4288,41 +4521,29 @@ FormattedText get_message_text(const ContactsManager *contacts_manager, string m return FormattedText{std::move(message_text), std::move(entities)}; } -td_api::object_ptr extract_input_caption( - tl_object_ptr &input_message_content) { - switch (input_message_content->get_id()) { - case td_api::inputMessageAnimation::ID: { - auto input_animation = static_cast(input_message_content.get()); - return std::move(input_animation->caption_); - } - case td_api::inputMessageAudio::ID: { - auto input_audio = static_cast(input_message_content.get()); - return std::move(input_audio->caption_); - } - case td_api::inputMessageDocument::ID: { - auto input_document = static_cast(input_message_content.get()); - return std::move(input_document->caption_); - } - case td_api::inputMessagePhoto::ID: { - auto input_photo = static_cast(input_message_content.get()); - return std::move(input_photo->caption_); - } - case td_api::inputMessageVideo::ID: { - auto input_video = static_cast(input_message_content.get()); - return std::move(input_video->caption_); - } - case td_api::inputMessageVoiceNote::ID: { - auto input_voice_note = static_cast(input_message_content.get()); - return std::move(input_voice_note->caption_); +void truncate_formatted_text(FormattedText &text, size_t length) { + auto result_size = utf8_truncate(Slice(text.text), length).size(); + if (result_size == text.text.size()) { + return; + } + text.text.resize(result_size); + auto utf16_length = narrow_cast(utf8_utf16_length(text.text)); + for (auto &entity : text.entities) { + if (entity.offset + entity.length > utf16_length) { + if (entity.offset >= utf16_length || is_continuous_entity(entity.type)) { + entity.length = 0; + continue; + } + entity.length = utf16_length - entity.offset; // truncate the entity } - default: - return nullptr; } + remove_empty_entities(text.entities); } Result get_formatted_text(const Td *td, DialogId dialog_id, td_api::object_ptr &&text, bool is_bot, - bool allow_empty, bool skip_media_timestamps, bool skip_trim) { + bool allow_empty, bool skip_media_timestamps, bool skip_trim, + int32 *ltrim_count) { if (text == nullptr) { if (allow_empty) { return FormattedText(); @@ -4331,19 +4552,19 @@ Result get_formatted_text(const Td *td, DialogId dialog_id, return Status::Error(400, "Text must be non-empty"); } - TRY_RESULT(entities, get_message_entities(td->contacts_manager_.get(), std::move(text->entities_))); - auto need_skip_bot_commands = need_always_skip_bot_commands(td->contacts_manager_.get(), dialog_id, is_bot); + TRY_RESULT(entities, get_message_entities(td->user_manager_.get(), std::move(text->entities_))); + auto need_skip_bot_commands = need_always_skip_bot_commands(td->user_manager_.get(), dialog_id, is_bot); bool parse_markdown = td->option_manager_->get_option_boolean("always_parse_markdown"); bool skip_new_entities = is_bot && td->option_manager_->get_option_integer("session_count") > 1; TRY_STATUS(fix_formatted_text(text->text_, entities, allow_empty, skip_new_entities || parse_markdown, skip_new_entities || need_skip_bot_commands, - is_bot || skip_media_timestamps || parse_markdown, skip_trim)); + is_bot || skip_media_timestamps || parse_markdown, skip_trim, ltrim_count)); FormattedText result{std::move(text->text_), std::move(entities)}; if (parse_markdown) { result = parse_markdown_v3(std::move(result)); fix_formatted_text(result.text, result.entities, allow_empty, false, need_skip_bot_commands, - is_bot || skip_media_timestamps, skip_trim) + is_bot || skip_media_timestamps, skip_trim, nullptr) .ensure(); } remove_unallowed_entities(td, result, dialog_id); @@ -4355,9 +4576,7 @@ void add_formatted_text_dependencies(Dependencies &dependencies, const Formatted return; } for (auto &entity : text->entities) { - if (entity.user_id.is_valid()) { - dependencies.add(entity.user_id); - } + dependencies.add(entity.user_id); } } @@ -4386,7 +4605,7 @@ bool has_bot_commands(const FormattedText *text) { return false; } -bool need_always_skip_bot_commands(const ContactsManager *contacts_manager, DialogId dialog_id, bool is_bot) { +bool need_always_skip_bot_commands(const UserManager *user_manager, DialogId dialog_id, bool is_bot) { if (!dialog_id.is_valid()) { return true; } @@ -4397,11 +4616,11 @@ bool need_always_skip_bot_commands(const ContactsManager *contacts_manager, Dial switch (dialog_id.get_type()) { case DialogType::User: { auto user_id = dialog_id.get_user_id(); - return user_id == ContactsManager::get_replies_bot_user_id() || !contacts_manager->is_user_bot(user_id); + return user_id == UserManager::get_replies_bot_user_id() || !user_manager->is_user_bot(user_id); } case DialogType::SecretChat: { - auto user_id = contacts_manager->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); - return !user_id.is_valid() || !contacts_manager->is_user_bot(user_id); + auto user_id = user_manager->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + return !user_id.is_valid() || !user_manager->is_user_bot(user_id); } case DialogType::Chat: case DialogType::Channel: @@ -4413,7 +4632,7 @@ bool need_always_skip_bot_commands(const ContactsManager *contacts_manager, Dial } } -vector> get_input_message_entities(const ContactsManager *contacts_manager, +vector> get_input_message_entities(const UserManager *user_manager, const vector &entities, const char *source) { vector> result; @@ -4439,7 +4658,8 @@ vector> get_input_message_entities(co user_entity_count++; switch (entity.type) { case MessageEntity::Type::BlockQuote: - result.push_back(make_tl_object(entity.offset, entity.length)); + result.push_back( + make_tl_object(0, false /*ignored*/, entity.offset, entity.length)); break; case MessageEntity::Type::Code: result.push_back(make_tl_object(entity.offset, entity.length)); @@ -4455,11 +4675,16 @@ vector> get_input_message_entities(co make_tl_object(entity.offset, entity.length, entity.argument)); break; case MessageEntity::Type::MentionName: { - auto input_user = contacts_manager->get_input_user_force(entity.user_id); + CHECK(user_manager != nullptr); + auto input_user = user_manager->get_input_user_force(entity.user_id); result.push_back(make_tl_object(entity.offset, entity.length, std::move(input_user))); break; } + case MessageEntity::Type::ExpandableBlockQuote: + result.push_back(make_tl_object( + telegram_api::messageEntityBlockquote::COLLAPSED_MASK, false /*ignored*/, entity.offset, entity.length)); + break; default: UNREACHABLE(); } @@ -4495,11 +4720,11 @@ vector> get_input_message_entities(co return result; } -vector> get_input_message_entities(const ContactsManager *contacts_manager, +vector> get_input_message_entities(const UserManager *user_manager, const FormattedText *text, const char *source) { if (text != nullptr && !text->entities.empty()) { - return get_input_message_entities(contacts_manager, text->entities, source); + return get_input_message_entities(user_manager, text->entities, source); } return {}; } @@ -4517,11 +4742,12 @@ void remove_unallowed_entities(const Td *td, FormattedText &text, DialogId dialo } if (dialog_id.get_type() == DialogType::SecretChat) { - auto layer = td->contacts_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); + auto layer = td->user_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); td::remove_if(text.entities, [layer](const MessageEntity &entity) { if (layer < static_cast(SecretChatLayer::NewEntities) && (entity.type == MessageEntity::Type::Underline || entity.type == MessageEntity::Type::Strikethrough || - entity.type == MessageEntity::Type::BlockQuote)) { + entity.type == MessageEntity::Type::BlockQuote || + entity.type == MessageEntity::Type::ExpandableBlockQuote)) { return true; } if (layer < static_cast(SecretChatLayer::SpoilerAndCustomEmojiEntities) && @@ -4536,9 +4762,8 @@ void remove_unallowed_entities(const Td *td, FormattedText &text, DialogId dialo remove_intersecting_entities(text.entities); } } - if (!td->option_manager_->get_option_boolean("is_premium") && - dialog_id != DialogId(td->contacts_manager_->get_my_id())) { - remove_premium_custom_emoji_entities(td, text.entities, false); + if (!td->dialog_manager_->can_use_premium_custom_emoji_in_dialog(dialog_id)) { + remove_premium_custom_emoji_entities(td, text.entities, true); } } diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageEntity.h b/protocols/Telegram/tdlib/td/td/telegram/MessageEntity.h index a0d8a4b7b6..c310076a0e 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageEntity.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageEntity.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -24,10 +24,10 @@ namespace td { -class ContactsManager; class Dependencies; class MultiPromiseActor; class Td; +class UserManager; class MessageEntity { public: @@ -53,6 +53,7 @@ class MessageEntity { MediaTimestamp, Spoiler, CustomEmoji, + ExpandableBlockQuote, Size }; Type type = Type::Size; @@ -80,7 +81,7 @@ class MessageEntity { CHECK(type == Type::CustomEmoji); } - tl_object_ptr get_text_entity_object() const; + tl_object_ptr get_text_entity_object(const UserManager *user_manager) const; bool operator==(const MessageEntity &other) const { return offset == other.offset && length == other.length && type == other.type && @@ -111,7 +112,7 @@ class MessageEntity { void parse(ParserT &parser); private: - tl_object_ptr get_text_entity_type_object() const; + tl_object_ptr get_text_entity_type_object(const UserManager *user_manager) const; static int get_type_priority(Type type); }; @@ -135,9 +136,9 @@ struct FormattedTextHash { uint32 operator()(const FormattedText &formatted_text) const { auto hash = Hash()(formatted_text.text); for (auto &entity : formatted_text.entities) { - hash = hash * 2023654985u + Hash()(static_cast(entity.type)); - hash = hash * 2023654985u + Hash()(entity.length); - hash = hash * 2023654985u + Hash()(entity.offset); + hash = combine_hashes(hash, Hash()(static_cast(entity.type))); + hash = combine_hashes(hash, Hash()(entity.length)); + hash = combine_hashes(hash, Hash()(entity.offset)); } return hash; } @@ -155,14 +156,16 @@ inline bool operator!=(const FormattedText &lhs, const FormattedText &rhs) { const FlatHashSet &get_valid_short_usernames(); -Result> get_message_entities(const ContactsManager *contacts_manager, +Result> get_message_entities(const UserManager *user_manager, vector> &&input_entities, bool allow_all = false); -vector> get_text_entities_object(const vector &entities, +vector> get_text_entities_object(const UserManager *user_manager, + const vector &entities, bool skip_bot_commands, int32 max_media_timestamp); -td_api::object_ptr get_formatted_text_object(const FormattedText &text, bool skip_bot_commands, +td_api::object_ptr get_formatted_text_object(const UserManager *user_manager, + const FormattedText &text, bool skip_bot_commands, int32 max_media_timestamp); void remove_premium_custom_emoji_entities(const Td *td, vector &entities, bool remove_unknown); @@ -183,7 +186,9 @@ vector> find_media_timestamps(Slice str); // slice + me void remove_empty_entities(vector &entities); -string get_first_url(const FormattedText &text); +Slice get_first_url(const FormattedText &text); + +bool is_visible_url(const FormattedText &text, const string &url); Result> parse_markdown(string &text); @@ -195,47 +200,50 @@ FormattedText get_markdown_v3(FormattedText text); Result> parse_html(string &str); -vector> get_input_message_entities(const ContactsManager *contacts_manager, +vector> get_input_message_entities(const UserManager *user_manager, const vector &entities, const char *source); -vector> get_input_message_entities(const ContactsManager *contacts_manager, +vector> get_input_message_entities(const UserManager *user_manager, const FormattedText *text, const char *source); vector> get_input_secret_message_entities( const vector &entities, int32 layer); -vector get_message_entities(const ContactsManager *contacts_manager, - vector> &&server_entities, - const char *source); - vector get_message_entities(Td *td, vector> &&secret_entities, bool is_premium, MultiPromiseActor &load_data_multipromise); -telegram_api::object_ptr get_input_text_with_entities( - const ContactsManager *contacts_manager, const FormattedText &text, const char *source); +telegram_api::object_ptr get_input_text_with_entities(const UserManager *user_manager, + const FormattedText &text, + const char *source); -FormattedText get_formatted_text(const ContactsManager *contacts_manager, +FormattedText get_formatted_text(const UserManager *user_manager, string &&text, + vector> &&server_entities, + bool skip_media_timestamps, bool skip_trim, const char *source); + +FormattedText get_formatted_text(const UserManager *user_manager, telegram_api::object_ptr text_with_entities, - bool allow_empty, bool skip_new_entities, bool skip_bot_commands, bool skip_media_timestamps, bool skip_trim, const char *source); +void fix_entities(vector &entities); + // like clean_input_string but also validates entities Status fix_formatted_text(string &text, vector &entities, bool allow_empty, bool skip_new_entities, - bool skip_bot_commands, bool skip_media_timestamps, bool skip_trim) TD_WARN_UNUSED_RESULT; + bool skip_bot_commands, bool skip_media_timestamps, bool skip_trim, + int32 *ltrim_count = nullptr) TD_WARN_UNUSED_RESULT; -FormattedText get_message_text(const ContactsManager *contacts_manager, string message_text, +FormattedText get_message_text(const UserManager *user_manager, string message_text, vector> &&server_entities, bool skip_new_entities, bool skip_media_timestamps, int32 send_date, bool from_album, const char *source); -td_api::object_ptr extract_input_caption( - tl_object_ptr &input_message_content); +void truncate_formatted_text(FormattedText &text, size_t length); Result get_formatted_text(const Td *td, DialogId dialog_id, td_api::object_ptr &&text, bool is_bot, - bool allow_empty, bool skip_media_timestamps, bool skip_trim); + bool allow_empty, bool skip_media_timestamps, bool skip_trim, + int32 *ltrim_count = nullptr); void add_formatted_text_dependencies(Dependencies &dependencies, const FormattedText *text); @@ -243,6 +251,6 @@ bool has_media_timestamps(const FormattedText *text, int32 min_media_timestamp, bool has_bot_commands(const FormattedText *text); -bool need_always_skip_bot_commands(const ContactsManager *contacts_manager, DialogId dialog_id, bool is_bot); +bool need_always_skip_bot_commands(const UserManager *user_manager, DialogId dialog_id, bool is_bot); } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.cpp index 322ead66b2..649342bf1f 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.cpp @@ -1,31 +1,37 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/MessageExtendedMedia.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/Dimensions.h" #include "td/telegram/Document.h" #include "td/telegram/DocumentsManager.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/files/FileType.h" #include "td/telegram/MessageContent.h" -#include "td/telegram/MessageContentType.h" +#include "td/telegram/Photo.h" #include "td/telegram/PhotoSize.h" +#include "td/telegram/StickersManager.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/VideosManager.h" #include "td/utils/algorithm.h" #include "td/utils/logging.h" +#include "td/utils/MimeType.h" +#include "td/utils/PathView.h" namespace td { MessageExtendedMedia::MessageExtendedMedia( - Td *td, telegram_api::object_ptr &&extended_media, FormattedText &&caption, - DialogId owner_dialog_id) { + Td *td, telegram_api::object_ptr &&extended_media, DialogId owner_dialog_id) { if (extended_media == nullptr) { return; } - caption_ = std::move(caption); switch (extended_media->get_id()) { case telegram_api::messageExtendedMediaPreview::ID: { @@ -45,88 +51,130 @@ MessageExtendedMedia::MessageExtendedMedia( } case telegram_api::messageExtendedMedia::ID: { auto media = move_tl_object_as(extended_media); - type_ = Type::Unsupported; - switch (media->media_->get_id()) { - case telegram_api::messageMediaPhoto::ID: { - auto photo = move_tl_object_as(media->media_); - if (photo->photo_ == nullptr) { - break; - } + init_from_media(td, std::move(media->media_), owner_dialog_id); + break; + } + default: + UNREACHABLE(); + } +} - photo_ = get_photo(td, std::move(photo->photo_), owner_dialog_id); - if (photo_.is_empty()) { - break; - } - type_ = Type::Photo; - break; - } - case telegram_api::messageMediaDocument::ID: { - auto document = move_tl_object_as(media->media_); - if (document->document_ == nullptr) { - break; - } +MessageExtendedMedia::MessageExtendedMedia(Td *td, telegram_api::object_ptr &&media, + DialogId owner_dialog_id) { + init_from_media(td, std::move(media), owner_dialog_id); +} - auto document_ptr = std::move(document->document_); - int32 document_id = document_ptr->get_id(); - if (document_id == telegram_api::documentEmpty::ID) { - break; - } - CHECK(document_id == telegram_api::document::ID); +void MessageExtendedMedia::init_from_media(Td *td, telegram_api::object_ptr &&media, + DialogId owner_dialog_id) { + type_ = Type::Unsupported; + switch (media->get_id()) { + case telegram_api::messageMediaPhoto::ID: { + auto photo = move_tl_object_as(media); + if (photo->photo_ == nullptr) { + break; + } - auto parsed_document = td->documents_manager_->on_get_document( - move_tl_object_as(document_ptr), owner_dialog_id); - if (parsed_document.empty() || parsed_document.type != Document::Type::Video) { - break; - } - CHECK(parsed_document.file_id.is_valid()); - video_file_id_ = parsed_document.file_id; - type_ = Type::Video; - break; - } - default: - break; + photo_ = get_photo(td, std::move(photo->photo_), owner_dialog_id); + if (photo_.is_empty()) { + break; + } + type_ = Type::Photo; + break; + } + case telegram_api::messageMediaDocument::ID: { + auto document = move_tl_object_as(media); + if (document->document_ == nullptr) { + break; + } + + auto document_ptr = std::move(document->document_); + int32 document_id = document_ptr->get_id(); + if (document_id == telegram_api::documentEmpty::ID) { + break; } - if (type_ == Type::Unsupported) { - unsupported_version_ = CURRENT_VERSION; + CHECK(document_id == telegram_api::document::ID); + + auto parsed_document = td->documents_manager_->on_get_document( + move_tl_object_as(document_ptr), owner_dialog_id); + if (parsed_document.empty() || parsed_document.type != Document::Type::Video) { + break; } + CHECK(parsed_document.file_id.is_valid()); + video_file_id_ = parsed_document.file_id; + type_ = Type::Video; break; } default: - UNREACHABLE(); + break; + } + if (type_ == Type::Unsupported) { + unsupported_version_ = CURRENT_VERSION; } } Result MessageExtendedMedia::get_message_extended_media( - Td *td, td_api::object_ptr &&extended_media_content, DialogId owner_dialog_id, - bool is_premium) { - if (extended_media_content == nullptr) { + Td *td, td_api::object_ptr &&paid_media, DialogId owner_dialog_id) { + if (paid_media == nullptr) { return MessageExtendedMedia(); } if (!owner_dialog_id.is_valid()) { return Status::Error(400, "Extended media can't be added to the invoice"); } - - auto input_content_type = extended_media_content->get_id(); - if (input_content_type != td_api::inputMessagePhoto::ID && input_content_type != td_api::inputMessageVideo::ID) { - return Status::Error("Invalid extended media content specified"); - } - TRY_RESULT(input_message_content, - get_input_message_content(owner_dialog_id, std::move(extended_media_content), td, is_premium)); - if (input_message_content.ttl != 0) { - return Status::Error("Can't use self-destructing extended media"); + if (paid_media->type_ == nullptr) { + return Status::Error(400, "Paid media type must be non-empty"); } - auto content = input_message_content.content.get(); - auto content_type = content->get_type(); MessageExtendedMedia result; - CHECK(content_type == MessageContentType::Photo || content_type == MessageContentType::Video); - result.caption_ = *get_message_content_caption(content); - if (content_type == MessageContentType::Photo) { - result.type_ = Type::Photo; - result.photo_ = *get_message_content_photo(content); - } else { - result.type_ = Type::Video; - result.video_file_id_ = get_message_content_upload_file_id(content); + + auto file_type = FileType::None; + switch (paid_media->type_->get_id()) { + case td_api::inputPaidMediaTypePhoto::ID: + file_type = FileType::Photo; + result.type_ = Type::Photo; + break; + case td_api::inputPaidMediaTypeVideo::ID: + file_type = FileType::Video; + result.type_ = Type::Video; + break; + default: + UNREACHABLE(); + break; + } + + TRY_RESULT(file_id, td->file_manager_->get_input_file_id(file_type, std::move(paid_media->media_), owner_dialog_id, + false, false)); + CHECK(file_id.is_valid()); + + auto sticker_file_ids = td->stickers_manager_->get_attached_sticker_file_ids(paid_media->added_sticker_file_ids_); + auto thumbnail = + get_input_thumbnail_photo_size(td->file_manager_.get(), paid_media->thumbnail_.get(), owner_dialog_id, false); + + switch (result.type_) { + case Type::Photo: { + TRY_RESULT(photo, create_photo(td->file_manager_.get(), file_id, std::move(thumbnail), paid_media->width_, + paid_media->height_, std::move(sticker_file_ids))); + result.photo_ = std::move(photo); + break; + } + case Type::Video: { + auto type = static_cast(paid_media->type_.get()); + FileView file_view = td->file_manager_->get_file_view(file_id); + auto suggested_path = file_view.suggested_path(); + const PathView path_view(suggested_path); + string file_name = path_view.file_name().str(); + string mime_type = MimeType::from_extension(path_view.extension()); + + bool has_stickers = !sticker_file_ids.empty(); + td->videos_manager_->create_video(file_id, string(), std::move(thumbnail), AnimationSize(), has_stickers, + std::move(sticker_file_ids), std::move(file_name), std::move(mime_type), + type->duration_, type->duration_, + get_dimensions(paid_media->width_, paid_media->height_, nullptr), + type->supports_streaming_, false, 0, 0.0, false); + result.video_file_id_ = file_id; + break; + } + default: + UNREACHABLE(); } return result; } @@ -140,7 +188,7 @@ void MessageExtendedMedia::update_from(const MessageExtendedMedia &old_extended_ bool MessageExtendedMedia::update_to(Td *td, telegram_api::object_ptr extended_media_ptr, DialogId owner_dialog_id) { - MessageExtendedMedia new_extended_media(td, std::move(extended_media_ptr), FormattedText(caption_), owner_dialog_id); + MessageExtendedMedia new_extended_media(td, std::move(extended_media_ptr), owner_dialog_id); if (!new_extended_media.is_media() && is_media()) { return false; } @@ -151,28 +199,24 @@ bool MessageExtendedMedia::update_to(Td *td, return false; } -td_api::object_ptr MessageExtendedMedia::get_message_extended_media_object( - Td *td, bool skip_bot_commands, int32 max_media_timestamp) const { +td_api::object_ptr MessageExtendedMedia::get_paid_media_object(Td *td) const { if (type_ == Type::Empty) { return nullptr; } - auto caption = get_formatted_text_object(caption_, skip_bot_commands, max_media_timestamp); switch (type_) { case Type::Unsupported: - return td_api::make_object(std::move(caption)); + return td_api::make_object(); case Type::Preview: - return td_api::make_object(dimensions_.width, dimensions_.height, duration_, - get_minithumbnail_object(minithumbnail_), - std::move(caption)); + return td_api::make_object(dimensions_.width, dimensions_.height, duration_, + get_minithumbnail_object(minithumbnail_)); case Type::Photo: { auto photo = get_photo_object(td->file_manager_.get(), photo_); CHECK(photo != nullptr); - return td_api::make_object(std::move(photo), std::move(caption)); + return td_api::make_object(std::move(photo)); } case Type::Video: - return td_api::make_object( - td->videos_manager_->get_video_object(video_file_id_), std::move(caption)); + return td_api::make_object(td->videos_manager_->get_video_object(video_file_id_)); default: UNREACHABLE(); return nullptr; @@ -215,9 +259,24 @@ void MessageExtendedMedia::delete_thumbnail(Td *td) { } } +unique_ptr MessageExtendedMedia::get_message_content() const { + switch (type_) { + case Type::Photo: + return create_photo_message_content(photo_); + case Type::Video: + return create_video_message_content(video_file_id_); + case Type::Empty: + case Type::Unsupported: + case Type::Preview: + default: + UNREACHABLE(); + return nullptr; + } +} + int32 MessageExtendedMedia::get_duration(const Td *td) const { if (!has_media_timestamp()) { - return 0; + return -1; } return td->videos_manager_->get_video_duration(video_file_id_); } @@ -273,6 +332,64 @@ FileId MessageExtendedMedia::get_thumbnail_file_id(const Td *td) const { return FileId(); } +void MessageExtendedMedia::update_file_id_remote(FileId file_id) { + if (file_id.get_remote() == 0 || type_ != Type::Video) { + return; + } + if (video_file_id_ == file_id && video_file_id_.get_remote() == 0) { + video_file_id_ = file_id; + } +} + +MessageExtendedMedia MessageExtendedMedia::dup_to_send(Td *td, bool always_dup_files) const { + switch (type_) { + case Type::Empty: + case Type::Unsupported: + case Type::Preview: + return {}; + case Type::Photo: { + MessageExtendedMedia result; + result.type_ = Type::Photo; + CHECK(!photo_.photos.empty()); + if (photo_.photos.size() > 2 || photo_.photos.back().type != 'i') { + // already sent photo + result.photo_ = photo_; + if (always_dup_files || !td->auth_manager_->is_bot()) { + result.photo_.photos.back().file_id = td->file_manager_->dup_file_id(result.photo_.photos.back().file_id, + "MessageExtendedMedia::dup_to_send 1"); + } + } else { + result.photo_ = dup_photo(photo_); + if (always_dup_files || + !photo_has_input_media(td->file_manager_.get(), result.photo_, false, td->auth_manager_->is_bot())) { + result.photo_.photos.back().file_id = td->file_manager_->dup_file_id(result.photo_.photos.back().file_id, + "MessageExtendedMedia::dup_to_send 2"); + if (result.photo_.photos.size() > 1) { + result.photo_.photos[0].file_id = + td->file_manager_->dup_file_id(result.photo_.photos[0].file_id, "MessageExtendedMedia::dup_to_send 3"); + } + } + } + return result; + } + case Type::Video: { + MessageExtendedMedia result; + result.type_ = Type::Video; + if (always_dup_files || !td->documents_manager_->has_input_media(video_file_id_, FileId(), false)) { + result.video_file_id_ = td->videos_manager_->dup_video( + td->file_manager_->dup_file_id(video_file_id_, "MessageExtendedMedia::dup_to_send 4"), video_file_id_); + } else { + result.video_file_id_ = video_file_id_; + } + CHECK(result.video_file_id_.is_valid()); + return result; + } + default: + UNREACHABLE(); + return {}; + } +} + telegram_api::object_ptr MessageExtendedMedia::get_input_media( Td *td, tl_object_ptr input_file, tl_object_ptr input_thumbnail) const { @@ -293,13 +410,40 @@ telegram_api::object_ptr MessageExtendedMedia::get_inp return nullptr; } +void MessageExtendedMedia::merge_files(Td *td, MessageExtendedMedia &other, DialogId dialog_id, bool need_merge_files, + bool &is_content_changed, bool &need_update) const { + if (!has_input_media() || !other.has_input_media()) { + return; + } + if (type_ != other.type_) { + LOG(ERROR) << "Type of paid media has changed"; + return; + } + switch (type_) { + case Type::Photo: + merge_photos(td, &photo_, &other.photo_, dialog_id, need_merge_files, is_content_changed, need_update); + break; + case Type::Video: + if (video_file_id_ != other.video_file_id_ && need_merge_files) { + td->videos_manager_->merge_videos(other.video_file_id_, video_file_id_); + } + break; + case Type::Empty: + case Type::Preview: + case Type::Unsupported: + default: + UNREACHABLE(); + break; + } +} + bool MessageExtendedMedia::is_equal_but_different(const MessageExtendedMedia &other) const { return type_ == Type::Unsupported && other.type_ == Type::Unsupported && unsupported_version_ != other.unsupported_version_; } bool operator==(const MessageExtendedMedia &lhs, const MessageExtendedMedia &rhs) { - if (lhs.type_ != rhs.type_ || lhs.caption_ != rhs.caption_) { + if (lhs.type_ != rhs.type_) { return false; } switch (lhs.type_) { diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.h b/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.h index 48fa452a5b..eced72fde2 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,7 +9,6 @@ #include "td/telegram/DialogId.h" #include "td/telegram/Dimensions.h" #include "td/telegram/files/FileId.h" -#include "td/telegram/MessageEntity.h" #include "td/telegram/Photo.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" @@ -19,12 +18,13 @@ namespace td { +class MessageContent; + class Td; class MessageExtendedMedia { enum class Type : int32 { Empty, Unsupported, Preview, Photo, Video }; Type type_ = Type::Empty; - FormattedText caption_; static constexpr int32 CURRENT_VERSION = 1; @@ -44,6 +44,8 @@ class MessageExtendedMedia { friend bool operator==(const MessageExtendedMedia &lhs, const MessageExtendedMedia &rhs); + void init_from_media(Td *td, telegram_api::object_ptr &&media, DialogId owner_dialog_id); + bool is_media() const { return type_ != Type::Empty && type_ != Type::Preview; } @@ -52,23 +54,27 @@ class MessageExtendedMedia { MessageExtendedMedia() = default; MessageExtendedMedia(Td *td, telegram_api::object_ptr &&extended_media, - FormattedText &&caption, DialogId owner_dialog_id); + DialogId owner_dialog_id); + + MessageExtendedMedia(Td *td, telegram_api::object_ptr &&media, DialogId owner_dialog_id); static Result get_message_extended_media( - Td *td, td_api::object_ptr &&extended_media_content, DialogId owner_dialog_id, - bool is_premium); + Td *td, td_api::object_ptr &&paid_media, DialogId owner_dialog_id); bool is_empty() const { return type_ == Type::Empty; } + bool has_input_media() const { + return type_ == Type::Photo || type_ == Type::Video; + } + void update_from(const MessageExtendedMedia &old_extended_media); bool update_to(Td *td, telegram_api::object_ptr extended_media_ptr, DialogId owner_dialog_id); - td_api::object_ptr get_message_extended_media_object(Td *td, bool skip_bot_commands, - int32 max_media_timestamp) const; + td_api::object_ptr get_paid_media_object(Td *td) const; void append_file_ids(const Td *td, vector &file_ids) const; @@ -88,11 +94,9 @@ class MessageExtendedMedia { bool is_equal_but_different(const MessageExtendedMedia &other) const; - int32 get_duration(const Td *td) const; + unique_ptr get_message_content() const; - const FormattedText *get_caption() const { - return &caption_; - } + int32 get_duration(const Td *td) const; FileId get_upload_file_id() const; @@ -100,10 +104,17 @@ class MessageExtendedMedia { FileId get_thumbnail_file_id(const Td *td) const; + void update_file_id_remote(FileId file_id); + + MessageExtendedMedia dup_to_send(Td *td, bool always_dup_files) const; + telegram_api::object_ptr get_input_media( Td *td, tl_object_ptr input_file, tl_object_ptr input_thumbnail) const; + void merge_files(Td *td, MessageExtendedMedia &other, DialogId dialog_id, bool need_merge_files, + bool &is_content_changed, bool &need_update) const; + template void store(StorerT &storer) const; diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.hpp b/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.hpp index 99fcc5ee08..eaa4a9e756 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageExtendedMedia.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -18,7 +18,6 @@ namespace td { template void MessageExtendedMedia::store(StorerT &storer) const { - bool has_caption = !caption_.text.empty(); bool has_unsupported_version = unsupported_version_ != 0; bool has_duration = duration_ != 0; bool has_dimensions = dimensions_.width != 0 || dimensions_.height != 0; @@ -26,7 +25,7 @@ void MessageExtendedMedia::store(StorerT &storer) const { bool has_photo = !photo_.is_empty(); bool has_video = video_file_id_.is_valid(); BEGIN_STORE_FLAGS(); - STORE_FLAG(has_caption); + STORE_FLAG(false); // has_caption STORE_FLAG(has_unsupported_version); STORE_FLAG(has_duration); STORE_FLAG(has_dimensions); @@ -35,9 +34,6 @@ void MessageExtendedMedia::store(StorerT &storer) const { STORE_FLAG(has_video); END_STORE_FLAGS(); td::store(type_, storer); - if (has_caption) { - td::store(caption_, storer); - } if (has_unsupported_version) { td::store(unsupported_version_, storer); } @@ -79,7 +75,8 @@ void MessageExtendedMedia::parse(ParserT &parser) { END_PARSE_FLAGS(); td::parse(type_, parser); if (has_caption) { - td::parse(caption_, parser); + FormattedText caption; + td::parse(caption, parser); } if (has_unsupported_version) { td::parse(unsupported_version_, parser); @@ -103,8 +100,10 @@ void MessageExtendedMedia::parse(ParserT &parser) { video_file_id_ = td->videos_manager_->parse_video(parser); is_bad = !video_file_id_.is_valid(); } - if (is_bad) { - LOG(ERROR) << "Failed to parse MessageExtendedMedia"; + if (is_bad || has_caption) { + if (is_bad) { + LOG(ERROR) << "Failed to parse MessageExtendedMedia"; + } photo_ = Photo(); video_file_id_ = FileId(); type_ = Type::Unsupported; diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.cpp new file mode 100644 index 0000000000..4e81a45c70 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.cpp @@ -0,0 +1,278 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageForwardInfo.h" + +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/MessageSender.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/Td.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/logging.h" +#include "td/utils/misc.h" + +namespace td { + +bool LastForwardedMessageInfo::is_empty() const { + return *this == LastForwardedMessageInfo(); +} + +void LastForwardedMessageInfo::validate() { + if (dialog_id_.is_valid() != message_id_.is_valid() || + (sender_dialog_id_ != DialogId() && !sender_dialog_id_.is_valid()) || + ((sender_dialog_id_ != DialogId() || !sender_name_.empty()) && date_ <= 0)) { + *this = {}; + } +} + +void LastForwardedMessageInfo::hide_sender_if_needed(Td *td) { + if (sender_name_.empty() && sender_dialog_id_.get_type() == DialogType::User) { + auto private_forward_name = td->user_manager_->get_user_private_forward_name(sender_dialog_id_.get_user_id()); + if (!private_forward_name.empty()) { + dialog_id_ = DialogId(); + message_id_ = MessageId(); + sender_dialog_id_ = DialogId(); + sender_name_ = std::move(private_forward_name); + } + } +} + +void LastForwardedMessageInfo::add_dependencies(Dependencies &dependencies) const { + dependencies.add_dialog_and_dependencies(dialog_id_); + dependencies.add_message_sender_dependencies(sender_dialog_id_); +} + +void LastForwardedMessageInfo::add_min_user_ids(vector &user_ids) const { + if (dialog_id_.get_type() == DialogType::User) { + user_ids.push_back(dialog_id_.get_user_id()); + } + if (sender_dialog_id_.get_type() == DialogType::User) { + user_ids.push_back(sender_dialog_id_.get_user_id()); + } +} + +void LastForwardedMessageInfo::add_min_channel_ids(vector &channel_ids) const { + if (dialog_id_.get_type() == DialogType::Channel) { + channel_ids.push_back(dialog_id_.get_channel_id()); + } + if (sender_dialog_id_.get_type() == DialogType::Channel) { + channel_ids.push_back(sender_dialog_id_.get_channel_id()); + } +} + +td_api::object_ptr LastForwardedMessageInfo::get_forward_source_object( + Td *td, bool for_saved_messages, const MessageOrigin &origin, int32 origin_date) const { + if (is_empty() && (origin.is_empty() || !for_saved_messages)) { + return nullptr; + } + td_api::object_ptr sender_id; + if (date_ == 0 && for_saved_messages) { + auto sender_dialog_id = origin.get_sender(); + if (sender_dialog_id.is_valid()) { + sender_id = get_message_sender_object_const(td, sender_dialog_id, "origin.forwardSource.sender_id"); + } + return td_api::make_object( + td->messages_manager_->get_chat_id_object(dialog_id_, "forwardSource.chat_id"), message_id_.get(), + std::move(sender_id), origin.get_sender_name(), origin_date, + is_outgoing_ || sender_dialog_id == td->dialog_manager_->get_my_dialog_id()); + } + + if (sender_dialog_id_ != DialogId()) { + sender_id = get_message_sender_object_const(td, sender_dialog_id_, "forwardSource.sender_id"); + } + return td_api::make_object( + td->messages_manager_->get_chat_id_object(dialog_id_, "forwardSource.chat_id"), message_id_.get(), + std::move(sender_id), sender_name_, date_, + is_outgoing_ || sender_dialog_id_ == td->dialog_manager_->get_my_dialog_id()); +} + +bool operator==(const LastForwardedMessageInfo &lhs, const LastForwardedMessageInfo &rhs) { + return lhs.dialog_id_ == rhs.dialog_id_ && lhs.message_id_ == rhs.message_id_ && + lhs.sender_dialog_id_ == rhs.sender_dialog_id_ && lhs.sender_name_ == rhs.sender_name_ && + lhs.date_ == rhs.date_ && lhs.is_outgoing_ == rhs.is_outgoing_; +} + +bool operator!=(const LastForwardedMessageInfo &lhs, const LastForwardedMessageInfo &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const LastForwardedMessageInfo &last_message_info) { + if (!last_message_info.is_empty()) { + string_builder << "last"; + if (last_message_info.dialog_id_ != DialogId()) { + string_builder << " forwarded from " + << MessageFullId(last_message_info.dialog_id_, last_message_info.message_id_); + } + if (last_message_info.sender_dialog_id_ != DialogId() || !last_message_info.sender_name_.empty() || + last_message_info.is_outgoing_) { + string_builder << " sent by"; + if (last_message_info.sender_dialog_id_.is_valid()) { + string_builder << ' ' << last_message_info.sender_dialog_id_; + } + if (!last_message_info.sender_name_.empty()) { + if (last_message_info.sender_dialog_id_.is_valid()) { + string_builder << '/'; + } else { + string_builder << ' '; + } + string_builder << '"' << last_message_info.sender_name_ << '"'; + } + string_builder << (last_message_info.is_outgoing_ ? " (me)" : " (not me)"); + } + if (last_message_info.date_ != 0) { + string_builder << " at " << last_message_info.date_; + } + } + return string_builder; +} + +unique_ptr MessageForwardInfo::get_message_forward_info( + Td *td, telegram_api::object_ptr &&forward_header) { + if (forward_header == nullptr) { + return nullptr; + } + auto date = forward_header->date_; + if (date <= 0) { + LOG(ERROR) << "Wrong date in message forward header: " << oneline(to_string(forward_header)); + return nullptr; + } + + LastForwardedMessageInfo last_message_info; + if (forward_header->saved_from_peer_ != nullptr || forward_header->saved_from_id_ != nullptr || + !forward_header->saved_from_name_.empty()) { + DialogId from_dialog_id; + if (forward_header->saved_from_peer_ != nullptr) { + from_dialog_id = DialogId(forward_header->saved_from_peer_); + } + DialogId sender_dialog_id; + if (forward_header->saved_from_id_ != nullptr) { + sender_dialog_id = DialogId(forward_header->saved_from_id_); + } + last_message_info = LastForwardedMessageInfo( + from_dialog_id, MessageId(ServerMessageId(forward_header->saved_from_msg_id_)), sender_dialog_id, + forward_header->saved_from_name_, forward_header->saved_date_, + forward_header->saved_out_ || sender_dialog_id == td->dialog_manager_->get_my_dialog_id()); + last_message_info.validate(); + if (last_message_info.is_empty()) { + LOG(ERROR) << "Receive wrong last message in message forward header: " << oneline(to_string(forward_header)); + } else { + Dependencies dependencies; + last_message_info.add_dependencies(dependencies); + for (auto dialog_id : dependencies.get_dialog_ids()) { + td->dialog_manager_->force_create_dialog(dialog_id, "get_message_forward_info", true); + } + } + } + bool is_imported = forward_header->imported_; + auto psa_type = std::move(forward_header->psa_type_); + auto r_origin = MessageOrigin::get_message_origin(td, std::move(forward_header)); + if (r_origin.is_error()) { + return nullptr; + } + + return td::make_unique(r_origin.move_as_ok(), date, std::move(last_message_info), + std::move(psa_type), is_imported); +} + +unique_ptr MessageForwardInfo::copy_message_forward_info( + Td *td, const MessageForwardInfo &forward_info, LastForwardedMessageInfo &&last_message_info) { + last_message_info.validate(); + last_message_info.hide_sender_if_needed(td); + + auto result = make_unique(forward_info); + result->last_message_info_ = std::move(last_message_info); + result->origin_.hide_sender_if_needed(td); + return result; +} + +td_api::object_ptr MessageForwardInfo::get_message_forward_info_object( + Td *td, bool for_saved_messages) const { + if (is_imported_) { + return nullptr; + } + return td_api::make_object( + origin_.get_message_origin_object(td), date_, + last_message_info_.get_forward_source_object(td, for_saved_messages, origin_, date_), psa_type_); +} + +td_api::object_ptr MessageForwardInfo::get_message_import_info_object() const { + if (!is_imported_) { + return nullptr; + } + return td_api::make_object(origin_.get_sender_name(), date_); +} + +void MessageForwardInfo::add_dependencies(Dependencies &dependencies) const { + origin_.add_dependencies(dependencies); + last_message_info_.add_dependencies(dependencies); +} + +void MessageForwardInfo::add_min_user_ids(vector &user_ids) const { + origin_.add_user_ids(user_ids); + last_message_info_.add_min_user_ids(user_ids); +} + +void MessageForwardInfo::add_min_channel_ids(vector &channel_ids) const { + origin_.add_channel_ids(channel_ids); + last_message_info_.add_min_channel_ids(channel_ids); +} + +bool MessageForwardInfo::need_change_warning(const MessageForwardInfo *lhs, const MessageForwardInfo *rhs, + MessageId message_id) { + // it should be already checked that *lhs != *rhs + if (lhs == nullptr || rhs == nullptr || lhs->is_imported_ || rhs->is_imported_) { + return true; + } + if (!message_id.is_scheduled() && !message_id.is_yet_unsent()) { + return true; + } + // yet unsent or scheduled messages can change sender name or author signature when being sent + return !lhs->origin_.has_sender_signature() && !rhs->origin_.has_sender_signature() && + !lhs->last_message_info_.has_sender_name() && !rhs->last_message_info_.has_sender_name(); +} + +bool operator==(const MessageForwardInfo &lhs, const MessageForwardInfo &rhs) { + return lhs.origin_ == rhs.origin_ && lhs.date_ == rhs.date_ && lhs.last_message_info_ == rhs.last_message_info_ && + lhs.psa_type_ == rhs.psa_type_ && lhs.is_imported_ == rhs.is_imported_; +} + +bool operator!=(const MessageForwardInfo &lhs, const MessageForwardInfo &rhs) { + return !(lhs == rhs); +} + +bool operator==(const unique_ptr &lhs, const unique_ptr &rhs) { + if (lhs == nullptr) { + return rhs == nullptr; + } + return rhs != nullptr && *lhs == *rhs; +} + +bool operator!=(const unique_ptr &lhs, const unique_ptr &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageForwardInfo &forward_info) { + string_builder << "MessageForwardInfo[" << (forward_info.is_imported_ ? "imported " : "") << forward_info.origin_; + if (!forward_info.psa_type_.empty()) { + string_builder << ", psa_type " << forward_info.psa_type_; + } + if (!forward_info.last_message_info_.is_empty()) { + string_builder << ", " << forward_info.last_message_info_; + } + return string_builder << " at " << forward_info.date_ << ']'; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const unique_ptr &forward_info) { + if (forward_info == nullptr) { + return string_builder << "[null]"; + } + return string_builder << *forward_info; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.h b/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.h new file mode 100644 index 0000000000..fd29c86310 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.h @@ -0,0 +1,179 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ChannelId.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessageOrigin.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Dependencies; +class Td; + +class LastForwardedMessageInfo { + DialogId dialog_id_; + MessageId message_id_; + DialogId sender_dialog_id_; + string sender_name_; + int32 date_ = 0; + bool is_outgoing_ = false; + + friend bool operator==(const LastForwardedMessageInfo &lhs, const LastForwardedMessageInfo &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const LastForwardedMessageInfo &last_message_info); + + public: + LastForwardedMessageInfo() = default; + + LastForwardedMessageInfo(DialogId dialog_id, MessageId message_id, DialogId sender_dialog_id, string sender_name, + int32 date, bool is_outgoing) + : dialog_id_(dialog_id) + , message_id_(message_id) + , sender_dialog_id_(sender_dialog_id) + , sender_name_(std::move(sender_name)) + , date_(date) + , is_outgoing_(is_outgoing) { + } + + bool is_empty() const; + + void validate(); + + void hide_sender_if_needed(Td *td); + + void add_dependencies(Dependencies &dependencies) const; + + void add_min_user_ids(vector &user_ids) const; + + void add_min_channel_ids(vector &channel_ids) const; + + td_api::object_ptr get_forward_source_object(Td *td, bool for_saved_messages, + const MessageOrigin &origin, + int32 origin_date) const; + + DialogId get_dialog_id() const { + return dialog_id_; + } + + MessageFullId get_message_full_id() const { + return {dialog_id_, message_id_}; + } + + bool has_sender_name() const { + return !sender_name_.empty(); + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +class MessageForwardInfo { + MessageOrigin origin_; + int32 date_ = 0; + LastForwardedMessageInfo last_message_info_; + string psa_type_; + bool is_imported_ = false; + + friend bool operator==(const MessageForwardInfo &lhs, const MessageForwardInfo &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageForwardInfo &forward_info); + + public: + MessageForwardInfo() = default; + + MessageForwardInfo(MessageOrigin &&origin, int32 date, LastForwardedMessageInfo &&last_message_info, + string &&psa_type, bool is_imported) + : origin_(std::move(origin)) + , date_(date) + , last_message_info_(std::move(last_message_info)) + , psa_type_(std::move(psa_type)) + , is_imported_(is_imported) { + last_message_info_.validate(); + } + + static unique_ptr get_message_forward_info( + Td *td, telegram_api::object_ptr &&forward_header); + + static unique_ptr copy_message_forward_info(Td *td, const MessageForwardInfo &forward_info, + LastForwardedMessageInfo &&last_message_info); + + td_api::object_ptr get_message_forward_info_object(Td *td, bool for_saved_messages) const; + + td_api::object_ptr get_message_import_info_object() const; + + void add_dependencies(Dependencies &dependencies) const; + + void add_min_user_ids(vector &user_ids) const; + + void add_min_channel_ids(vector &channel_ids) const; + + static bool need_change_warning(const MessageForwardInfo *lhs, const MessageForwardInfo *rhs, MessageId message_id); + + int32 get_origin_date() const { + return date_; + } + + bool is_imported() const { + return is_imported_; + } + + const MessageOrigin &get_origin() const { + return origin_; + } + + MessageFullId get_origin_message_full_id() const { + return origin_.get_message_full_id(); + } + + DialogId get_last_dialog_id() const { + return last_message_info_.get_dialog_id(); + } + + MessageFullId get_last_message_full_id() const { + return last_message_info_.get_message_full_id(); + } + + bool has_last_sender_name() const { + return last_message_info_.has_sender_name(); + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const LastForwardedMessageInfo &lhs, const LastForwardedMessageInfo &rhs); + +bool operator!=(const LastForwardedMessageInfo &lhs, const LastForwardedMessageInfo &rhs); + +bool operator==(const MessageForwardInfo &lhs, const MessageForwardInfo &rhs); + +bool operator!=(const MessageForwardInfo &lhs, const MessageForwardInfo &rhs); + +bool operator==(const unique_ptr &lhs, const unique_ptr &rhs); + +bool operator!=(const unique_ptr &lhs, const unique_ptr &rhs); + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageForwardInfo &forward_info); + +StringBuilder &operator<<(StringBuilder &string_builder, const unique_ptr &forward_info); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.hpp b/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.hpp new file mode 100644 index 0000000000..9a2ad859b8 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageForwardInfo.hpp @@ -0,0 +1,105 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageForwardInfo.h" +#include "td/telegram/MessageOrigin.hpp" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void LastForwardedMessageInfo::store(StorerT &storer) const { + bool has_sender_dialog_id = sender_dialog_id_.is_valid(); + bool has_sender_name = !sender_name_.empty(); + bool has_date = date_ > 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_sender_dialog_id); + STORE_FLAG(has_sender_name); + STORE_FLAG(has_date); + STORE_FLAG(is_outgoing_); + END_STORE_FLAGS(); + td::store(dialog_id_, storer); + td::store(message_id_, storer); + if (has_sender_dialog_id) { + td::store(sender_dialog_id_, storer); + } + if (has_sender_name) { + td::store(sender_name_, storer); + } + if (has_date) { + td::store(date_, storer); + } +} + +template +void LastForwardedMessageInfo::parse(ParserT &parser) { + bool has_sender_dialog_id; + bool has_sender_name; + bool has_date; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_sender_dialog_id); + PARSE_FLAG(has_sender_name); + PARSE_FLAG(has_date); + PARSE_FLAG(is_outgoing_); + END_PARSE_FLAGS(); + td::parse(dialog_id_, parser); + td::parse(message_id_, parser); + if (has_sender_dialog_id) { + td::parse(sender_dialog_id_, parser); + } + if (has_sender_name) { + td::parse(sender_name_, parser); + } + if (has_date) { + td::parse(date_, parser); + } + + validate(); +} + +template +void MessageForwardInfo::store(StorerT &storer) const { + bool has_last_message_info = !last_message_info_.is_empty(); + bool has_psa_type = !psa_type_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_imported_); + STORE_FLAG(has_last_message_info); + STORE_FLAG(has_psa_type); + END_STORE_FLAGS(); + td::store(origin_, storer); + td::store(date_, storer); + if (has_last_message_info) { + td::store(last_message_info_, storer); + } + if (has_psa_type) { + td::store(psa_type_, storer); + } +} + +template +void MessageForwardInfo::parse(ParserT &parser) { + bool has_last_message_info; + bool has_psa_type; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_imported_); + PARSE_FLAG(has_last_message_info); + PARSE_FLAG(has_psa_type); + END_PARSE_FLAGS(); + td::parse(origin_, parser); + td::parse(date_, parser); + if (has_last_message_info) { + td::parse(last_message_info_, parser); + } + if (has_psa_type) { + td::parse(psa_type_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageFullId.h b/protocols/Telegram/tdlib/td/td/telegram/MessageFullId.h new file mode 100644 index 0000000000..5ed2fa0afd --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageFullId.h @@ -0,0 +1,75 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +struct MessageFullId { + private: + DialogId dialog_id; + MessageId message_id; + + public: + MessageFullId() : dialog_id(), message_id() { + } + + MessageFullId(DialogId dialog_id, MessageId message_id) : dialog_id(dialog_id), message_id(message_id) { + } + + bool operator==(const MessageFullId &other) const { + return dialog_id == other.dialog_id && message_id == other.message_id; + } + + bool operator!=(const MessageFullId &other) const { + return !(*this == other); + } + + DialogId get_dialog_id() const { + return dialog_id; + } + + MessageId get_message_id() const { + return message_id; + } + + static MessageFullId get_message_full_id(const tl_object_ptr &message_ptr, bool is_scheduled) { + return {DialogId::get_message_dialog_id(message_ptr), MessageId::get_message_id(message_ptr, is_scheduled)}; + } + + template + void store(StorerT &storer) const { + dialog_id.store(storer); + message_id.store(storer); + } + + template + void parse(ParserT &parser) { + dialog_id.parse(parser); + message_id.parse(parser); + } +}; + +struct MessageFullIdHash { + uint32 operator()(MessageFullId message_full_id) const { + return combine_hashes(DialogIdHash()(message_full_id.get_dialog_id()), + MessageIdHash()(message_full_id.get_message_id())); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, MessageFullId message_full_id) { + return string_builder << message_full_id.get_message_id() << " in " << message_full_id.get_dialog_id(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageImportManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageImportManager.cpp new file mode 100644 index 0000000000..c8f18f1245 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageImportManager.cpp @@ -0,0 +1,575 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageImportManager.h" + +#include "td/telegram/AccessRights.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/FileReferenceManager.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/files/FileType.h" +#include "td/telegram/Global.h" +#include "td/telegram/MessageContent.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/PathView.h" +#include "td/utils/Random.h" + +namespace td { + +class CheckHistoryImportQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit CheckHistoryImportQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(const string &message_file_head) { + send_query(G()->net_query_creator().create(telegram_api::messages_checkHistoryImport(message_file_head))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for CheckHistoryImportQuery: " << to_string(ptr); + auto file_type = [&]() -> td_api::object_ptr { + if (ptr->pm_) { + return td_api::make_object(ptr->title_); + } else if (ptr->group_) { + return td_api::make_object(ptr->title_); + } else { + return td_api::make_object(); + } + }(); + promise_.set_value(std::move(file_type)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class CheckHistoryImportPeerQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit CheckHistoryImportPeerQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + CHECK(input_peer != nullptr); + send_query(G()->net_query_creator().create(telegram_api::messages_checkHistoryImportPeer(std::move(input_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for CheckHistoryImportPeerQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr->confirm_text_)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "CheckHistoryImportPeerQuery"); + promise_.set_error(std::move(status)); + } +}; + +class InitHistoryImportQuery final : public Td::ResultHandler { + Promise promise_; + FileId file_id_; + DialogId dialog_id_; + vector attached_file_ids_; + + public: + explicit InitHistoryImportQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, FileId file_id, tl_object_ptr &&input_file, + vector attached_file_ids) { + CHECK(input_file != nullptr); + file_id_ = file_id; + dialog_id_ = dialog_id; + attached_file_ids_ = std::move(attached_file_ids); + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + CHECK(input_peer != nullptr); + send_query(G()->net_query_creator().create(telegram_api::messages_initHistoryImport( + std::move(input_peer), std::move(input_file), narrow_cast(attached_file_ids_.size())))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + td_->message_import_manager_->start_import_messages(dialog_id_, ptr->id_, std::move(attached_file_ids_), + std::move(promise_)); + + td_->file_manager_->delete_partial_remote_location(file_id_); + } + + void on_error(Status status) final { + if (FileReferenceManager::is_file_reference_error(status)) { + LOG(ERROR) << "Receive file reference error " << status; + } + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + // TODO reupload the file + } + + td_->file_manager_->delete_partial_remote_location(file_id_); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "InitHistoryImportQuery"); + promise_.set_error(std::move(status)); + } +}; + +class UploadImportedMediaQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + int64 import_id_; + FileId file_id_; + + public: + explicit UploadImportedMediaQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, int64 import_id, const string &file_name, FileId file_id, + tl_object_ptr &&input_media) { + CHECK(input_media != nullptr); + dialog_id_ = dialog_id; + import_id_ = import_id; + file_id_ = file_id; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + send_query(G()->net_query_creator().create(telegram_api::messages_uploadImportedMedia( + std::move(input_peer), import_id, file_name, std::move(input_media)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + // ignore response + + promise_.set_value(Unit()); + + td_->file_manager_->delete_partial_remote_location(file_id_); + } + + void on_error(Status status) final { + if (FileReferenceManager::is_file_reference_error(status)) { + LOG(ERROR) << "Receive file reference error " << status; + } + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + // TODO reupload the file + } + + td_->file_manager_->delete_partial_remote_location(file_id_); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "UploadImportedMediaQuery"); + promise_.set_error(std::move(status)); + } +}; + +class StartImportHistoryQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit StartImportHistoryQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, int64 import_id) { + dialog_id_ = dialog_id; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + CHECK(input_peer != nullptr); + + send_query( + G()->net_query_creator().create(telegram_api::messages_startHistoryImport(std::move(input_peer), import_id))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + if (!result_ptr.ok()) { + return on_error(Status::Error(500, "Import history returned false")); + } + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "StartImportHistoryQuery"); + promise_.set_error(std::move(status)); + } +}; + +class MessageImportManager::UploadImportedMessagesCallback final : public FileManager::UploadCallback { + public: + void on_upload_ok(FileId file_id, tl_object_ptr input_file) final { + send_closure_later(G()->message_import_manager(), &MessageImportManager::on_upload_imported_messages, file_id, + std::move(input_file)); + } + void on_upload_encrypted_ok(FileId file_id, tl_object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_secure_ok(FileId file_id, tl_object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_error(FileId file_id, Status error) final { + send_closure_later(G()->message_import_manager(), &MessageImportManager::on_upload_imported_messages_error, file_id, + std::move(error)); + } +}; + +class MessageImportManager::UploadImportedMessageAttachmentCallback final : public FileManager::UploadCallback { + public: + void on_upload_ok(FileId file_id, tl_object_ptr input_file) final { + send_closure_later(G()->message_import_manager(), &MessageImportManager::on_upload_imported_message_attachment, + file_id, std::move(input_file)); + } + void on_upload_encrypted_ok(FileId file_id, tl_object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_secure_ok(FileId file_id, tl_object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_error(FileId file_id, Status error) final { + send_closure_later(G()->message_import_manager(), + &MessageImportManager::on_upload_imported_message_attachment_error, file_id, std::move(error)); + } +}; + +MessageImportManager::MessageImportManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { + upload_imported_messages_callback_ = std::make_shared(); + upload_imported_message_attachment_callback_ = std::make_shared(); +} + +void MessageImportManager::tear_down() { + parent_.reset(); +} + +void MessageImportManager::get_message_file_type(const string &message_file_head, + Promise> &&promise) { + td_->create_handler(std::move(promise))->send(message_file_head); +} + +Status MessageImportManager::can_import_messages(DialogId dialog_id) { + TRY_STATUS(td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Write, "can_import_messages")); + + switch (dialog_id.get_type()) { + case DialogType::User: + if (!td_->user_manager_->is_user_contact(dialog_id.get_user_id(), true)) { + return Status::Error(400, "User must be a mutual contact"); + } + break; + case DialogType::Chat: + return Status::Error(400, "Basic groups must be upgraded to supergroups first"); + case DialogType::Channel: + if (td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + return Status::Error(400, "Can't import messages to channels"); + } + if (!td_->chat_manager_->get_channel_permissions(dialog_id.get_channel_id()).can_change_info_and_settings()) { + return Status::Error(400, "Not enough rights to import messages"); + } + break; + case DialogType::SecretChat: + case DialogType::None: + default: + UNREACHABLE(); + } + + return Status::OK(); +} + +void MessageImportManager::get_message_import_confirmation_text(DialogId dialog_id, Promise &&promise) { + TRY_STATUS_PROMISE(promise, can_import_messages(dialog_id)); + + td_->create_handler(std::move(promise))->send(dialog_id); +} + +void MessageImportManager::import_messages(DialogId dialog_id, + const td_api::object_ptr &message_file, + const vector> &attached_files, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, can_import_messages(dialog_id)); + + TRY_RESULT_PROMISE(promise, file_id, + td_->file_manager_->get_input_file_id(FileType::Document, message_file, dialog_id, false, false)); + + vector attached_file_ids; + attached_file_ids.reserve(attached_files.size()); + for (auto &attached_file : attached_files) { + auto file_type = td_->file_manager_->guess_file_type(attached_file); + if (file_type != FileType::Animation && file_type != FileType::Audio && file_type != FileType::Document && + file_type != FileType::Photo && file_type != FileType::Sticker && file_type != FileType::Video && + file_type != FileType::VoiceNote) { + LOG(INFO) << "Skip attached file of type " << file_type; + continue; + } + TRY_RESULT_PROMISE(promise, attached_file_id, + td_->file_manager_->get_input_file_id(file_type, attached_file, dialog_id, false, false)); + attached_file_ids.push_back(attached_file_id); + } + + upload_imported_messages(dialog_id, td_->file_manager_->dup_file_id(file_id, "import_messages"), + std::move(attached_file_ids), false, std::move(promise)); +} + +void MessageImportManager::upload_imported_messages(DialogId dialog_id, FileId file_id, + vector attached_file_ids, bool is_reupload, + Promise &&promise, vector bad_parts) { + CHECK(file_id.is_valid()); + LOG(INFO) << "Ask to upload imported messages file " << file_id; + auto info = td::make_unique(dialog_id, std::move(attached_file_ids), is_reupload, + std::move(promise)); + bool is_inserted = being_uploaded_imported_messages_.emplace(file_id, std::move(info)).second; + CHECK(is_inserted); + // TODO use force_reupload if is_reupload + td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_imported_messages_callback_, 1, 0, false, + true); +} + +void MessageImportManager::on_upload_imported_messages(FileId file_id, + tl_object_ptr input_file) { + LOG(INFO) << "File " << file_id << " has been uploaded"; + + auto it = being_uploaded_imported_messages_.find(file_id); + if (it == being_uploaded_imported_messages_.end()) { + // just in case, as in on_upload_media + return; + } + + CHECK(it->second != nullptr); + DialogId dialog_id = it->second->dialog_id; + vector attached_file_ids = std::move(it->second->attached_file_ids); + bool is_reupload = it->second->is_reupload; + Promise promise = std::move(it->second->promise); + + being_uploaded_imported_messages_.erase(it); + + TRY_STATUS_PROMISE(promise, + td_->dialog_manager_->check_dialog_access_in_memory(dialog_id, false, AccessRights::Write)); + + FileView file_view = td_->file_manager_->get_file_view(file_id); + CHECK(!file_view.is_encrypted()); + const auto *main_remote_location = file_view.get_main_remote_location(); + if (input_file == nullptr && main_remote_location != nullptr) { + if (main_remote_location->is_web()) { + return promise.set_error(Status::Error(400, "Can't use web file")); + } + if (is_reupload) { + return promise.set_error(Status::Error(400, "Failed to reupload the file")); + } + + CHECK(file_view.get_type() == FileType::Document); + // delete file reference and forcely reupload the file + auto file_reference = FileManager::extract_file_reference(main_remote_location->as_input_document()); + td_->file_manager_->delete_file_reference(file_id, file_reference); + upload_imported_messages(dialog_id, file_id, std::move(attached_file_ids), true, std::move(promise), {-1}); + return; + } + CHECK(input_file != nullptr); + + td_->create_handler(std::move(promise)) + ->send(dialog_id, file_id, std::move(input_file), std::move(attached_file_ids)); +} + +void MessageImportManager::on_upload_imported_messages_error(FileId file_id, Status status) { + if (G()->close_flag()) { + // do not fail upload if closing + return; + } + + LOG(INFO) << "File " << file_id << " has upload error " << status; + CHECK(status.is_error()); + + auto it = being_uploaded_imported_messages_.find(file_id); + if (it == being_uploaded_imported_messages_.end()) { + // just in case, as in on_upload_media_error + return; + } + + Promise promise = std::move(it->second->promise); + + being_uploaded_imported_messages_.erase(it); + + promise.set_error(std::move(status)); +} + +void MessageImportManager::start_import_messages(DialogId dialog_id, int64 import_id, + vector &&attached_file_ids, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + TRY_STATUS_PROMISE(promise, + td_->dialog_manager_->check_dialog_access_in_memory(dialog_id, false, AccessRights::Write)); + + auto pending_message_import = make_unique(); + pending_message_import->dialog_id = dialog_id; + pending_message_import->import_id = import_id; + pending_message_import->promise = std::move(promise); + + auto &multipromise = pending_message_import->upload_files_multipromise; + + int64 random_id; + do { + random_id = Random::secure_int64(); + } while (random_id == 0 || pending_message_imports_.count(random_id) > 0); + pending_message_imports_[random_id] = std::move(pending_message_import); + + multipromise.add_promise(PromiseCreator::lambda([actor_id = actor_id(this), random_id](Result result) { + send_closure_later(actor_id, &MessageImportManager::on_imported_message_attachments_uploaded, random_id, + std::move(result)); + })); + auto lock_promise = multipromise.get_promise(); + + for (auto attached_file_id : attached_file_ids) { + upload_imported_message_attachment(dialog_id, import_id, + td_->file_manager_->dup_file_id(attached_file_id, "start_import_messages"), + false, multipromise.get_promise()); + } + + lock_promise.set_value(Unit()); +} + +void MessageImportManager::upload_imported_message_attachment(DialogId dialog_id, int64 import_id, FileId file_id, + bool is_reupload, Promise &&promise, + vector bad_parts) { + CHECK(file_id.is_valid()); + LOG(INFO) << "Ask to upload imported message attached file " << file_id; + auto info = + td::make_unique(dialog_id, import_id, is_reupload, std::move(promise)); + bool is_inserted = being_uploaded_imported_message_attachments_.emplace(file_id, std::move(info)).second; + CHECK(is_inserted); + // TODO use force_reupload if is_reupload + td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_imported_message_attachment_callback_, 1, 0, + false, true); +} + +void MessageImportManager::on_upload_imported_message_attachment(FileId file_id, + tl_object_ptr input_file) { + LOG(INFO) << "File " << file_id << " has been uploaded"; + + auto it = being_uploaded_imported_message_attachments_.find(file_id); + if (it == being_uploaded_imported_message_attachments_.end()) { + // just in case, as in on_upload_media + return; + } + + CHECK(it->second != nullptr); + DialogId dialog_id = it->second->dialog_id; + int64 import_id = it->second->import_id; + bool is_reupload = it->second->is_reupload; + Promise promise = std::move(it->second->promise); + + being_uploaded_imported_message_attachments_.erase(it); + + FileView file_view = td_->file_manager_->get_file_view(file_id); + CHECK(!file_view.is_encrypted()); + const auto *main_remote_location = file_view.get_main_remote_location(); + if (input_file == nullptr && main_remote_location != nullptr) { + if (main_remote_location->is_web()) { + return promise.set_error(Status::Error(400, "Can't use web file")); + } + if (is_reupload) { + return promise.set_error(Status::Error(400, "Failed to reupload the file")); + } + + // delete file reference and forcely reupload the file + auto file_reference = file_view.get_type() == FileType::Photo + ? FileManager::extract_file_reference(main_remote_location->as_input_photo()) + : FileManager::extract_file_reference(main_remote_location->as_input_document()); + td_->file_manager_->delete_file_reference(file_id, file_reference); + upload_imported_message_attachment(dialog_id, import_id, file_id, true, std::move(promise), {-1}); + return; + } + CHECK(input_file != nullptr); + + auto suggested_path = file_view.suggested_path(); + const PathView path_view(suggested_path); + td_->create_handler(std::move(promise)) + ->send(dialog_id, import_id, path_view.file_name().str(), file_id, + get_message_content_fake_input_media(td_, std::move(input_file), file_id)); +} + +void MessageImportManager::on_upload_imported_message_attachment_error(FileId file_id, Status status) { + if (G()->close_flag()) { + // do not fail upload if closing + return; + } + + LOG(INFO) << "File " << file_id << " has upload error " << status; + CHECK(status.is_error()); + + auto it = being_uploaded_imported_message_attachments_.find(file_id); + if (it == being_uploaded_imported_message_attachments_.end()) { + // just in case, as in on_upload_media_error + return; + } + + Promise promise = std::move(it->second->promise); + + being_uploaded_imported_message_attachments_.erase(it); + + promise.set_error(std::move(status)); +} + +void MessageImportManager::on_imported_message_attachments_uploaded(int64 random_id, Result &&result) { + G()->ignore_result_if_closing(result); + + auto it = pending_message_imports_.find(random_id); + CHECK(it != pending_message_imports_.end()); + + auto pending_message_import = std::move(it->second); + CHECK(pending_message_import != nullptr); + + pending_message_imports_.erase(it); + + if (result.is_error()) { + pending_message_import->promise.set_error(result.move_as_error()); + return; + } + + CHECK(pending_message_import->upload_files_multipromise.promise_count() == 0); + + auto promise = std::move(pending_message_import->promise); + auto dialog_id = pending_message_import->dialog_id; + + TRY_STATUS_PROMISE(promise, + td_->dialog_manager_->check_dialog_access_in_memory(dialog_id, false, AccessRights::Write)); + + td_->create_handler(std::move(promise))->send(dialog_id, pending_message_import->import_id); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageImportManager.h b/protocols/Telegram/tdlib/td/td/telegram/MessageImportManager.h new file mode 100644 index 0000000000..415356af37 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageImportManager.h @@ -0,0 +1,112 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/actor/actor.h" +#include "td/actor/MultiPromise.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" + +#include + +namespace td { + +class Td; + +class MessageImportManager final : public Actor { + public: + MessageImportManager(Td *td, ActorShared<> parent); + + void get_message_file_type(const string &message_file_head, + Promise> &&promise); + + void get_message_import_confirmation_text(DialogId dialog_id, Promise &&promise); + + void import_messages(DialogId dialog_id, const td_api::object_ptr &message_file, + const vector> &attached_files, Promise &&promise); + + void start_import_messages(DialogId dialog_id, int64 import_id, vector &&attached_file_ids, + Promise &&promise); + + private: + void tear_down() final; + + Status can_import_messages(DialogId dialog_id); + + void upload_imported_messages(DialogId dialog_id, FileId file_id, vector attached_file_ids, bool is_reupload, + Promise &&promise, vector bad_parts = {}); + + void on_upload_imported_messages(FileId file_id, tl_object_ptr input_file); + + void on_upload_imported_messages_error(FileId file_id, Status status); + + void upload_imported_message_attachment(DialogId dialog_id, int64 import_id, FileId file_id, bool is_reupload, + Promise &&promise, vector bad_parts = {}); + + void on_upload_imported_message_attachment(FileId file_id, tl_object_ptr input_file); + + void on_upload_imported_message_attachment_error(FileId file_id, Status status); + + void on_imported_message_attachments_uploaded(int64 random_id, Result &&result); + + class UploadImportedMessagesCallback; + class UploadImportedMessageAttachmentCallback; + + std::shared_ptr upload_imported_messages_callback_; + std::shared_ptr upload_imported_message_attachment_callback_; + + struct UploadedImportedMessagesInfo { + DialogId dialog_id; + vector attached_file_ids; + bool is_reupload; + Promise promise; + + UploadedImportedMessagesInfo(DialogId dialog_id, vector &&attached_file_ids, bool is_reupload, + Promise &&promise) + : dialog_id(dialog_id) + , attached_file_ids(std::move(attached_file_ids)) + , is_reupload(is_reupload) + , promise(std::move(promise)) { + } + }; + FlatHashMap, FileIdHash> being_uploaded_imported_messages_; + + struct UploadedImportedMessageAttachmentInfo { + DialogId dialog_id; + int64 import_id; + bool is_reupload; + Promise promise; + + UploadedImportedMessageAttachmentInfo(DialogId dialog_id, int64 import_id, bool is_reupload, + Promise &&promise) + : dialog_id(dialog_id), import_id(import_id), is_reupload(is_reupload), promise(std::move(promise)) { + } + }; + FlatHashMap, FileIdHash> + being_uploaded_imported_message_attachments_; + + struct PendingMessageImport { + MultiPromiseActor upload_files_multipromise{"UploadAttachedFilesMultiPromiseActor"}; + DialogId dialog_id; + int64 import_id = 0; + Promise promise; + }; + FlatHashMap> pending_message_imports_; + + Td *td_; + ActorShared<> parent_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.cpp new file mode 100644 index 0000000000..8b7065d64b --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.cpp @@ -0,0 +1,174 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageInputReplyTo.h" + +#include "td/telegram/AccessRights.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/InputDialogId.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/logging.h" + +namespace td { + +MessageInputReplyTo::~MessageInputReplyTo() = default; + +MessageInputReplyTo::MessageInputReplyTo(Td *td, + telegram_api::object_ptr &&input_reply_to) { + if (input_reply_to == nullptr) { + return; + } + switch (input_reply_to->get_id()) { + case telegram_api::inputReplyToStory::ID: { + auto reply_to = telegram_api::move_object_as(input_reply_to); + auto dialog_id = InputDialogId(reply_to->peer_).get_dialog_id(); + auto story_id = StoryId(reply_to->story_id_); + if (dialog_id.is_valid() && story_id.is_valid()) { + td->dialog_manager_->force_create_dialog(dialog_id, "MessageInputReplyTo", true); + story_full_id_ = {dialog_id, story_id}; + } + break; + } + case telegram_api::inputReplyToMessage::ID: { + auto reply_to = telegram_api::move_object_as(input_reply_to); + MessageId message_id(ServerMessageId(reply_to->reply_to_msg_id_)); + if (!message_id.is_valid() && !message_id_.is_valid_scheduled()) { + return; + } + DialogId dialog_id; + if (reply_to->reply_to_peer_id_ != nullptr) { + dialog_id = InputDialogId(reply_to->reply_to_peer_id_).get_dialog_id(); + if (!dialog_id.is_valid() || !td->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { + return; + } + td->dialog_manager_->force_create_dialog(dialog_id, "inputReplyToMessage"); + } + message_id_ = message_id; + dialog_id_ = dialog_id; + + quote_ = MessageQuote(td, reply_to); + break; + } + default: + UNREACHABLE(); + } +} + +void MessageInputReplyTo::add_dependencies(Dependencies &dependencies) const { + dependencies.add_dialog_and_dependencies(dialog_id_); + quote_.add_dependencies(dependencies); + dependencies.add_dialog_and_dependencies(story_full_id_.get_dialog_id()); // just in case +} + +telegram_api::object_ptr MessageInputReplyTo::get_input_reply_to( + Td *td, MessageId top_thread_message_id) const { + if (story_full_id_.is_valid()) { + auto dialog_id = story_full_id_.get_dialog_id(); + auto input_peer = td->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + LOG(INFO) << "Failed to get input peer for " << story_full_id_; + return nullptr; + } + return telegram_api::make_object(std::move(input_peer), + story_full_id_.get_story_id().get()); + } + auto reply_to_message_id = message_id_; + if (reply_to_message_id == MessageId()) { + if (top_thread_message_id == MessageId()) { + return nullptr; + } + reply_to_message_id = top_thread_message_id; + } + CHECK(reply_to_message_id.is_server()); + int32 flags = 0; + if (top_thread_message_id != MessageId()) { + CHECK(top_thread_message_id.is_server()); + flags |= telegram_api::inputReplyToMessage::TOP_MSG_ID_MASK; + } + telegram_api::object_ptr input_peer; + if (dialog_id_ != DialogId()) { + input_peer = td->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + LOG(INFO) << "Failed to get input peer for " << dialog_id_; + return nullptr; + } + flags |= telegram_api::inputReplyToMessage::REPLY_TO_PEER_ID_MASK; + } + auto result = telegram_api::make_object( + flags, reply_to_message_id.get_server_message_id().get(), top_thread_message_id.get_server_message_id().get(), + std::move(input_peer), string(), Auto(), 0); + quote_.update_input_reply_to_message(td, result.get()); + return std::move(result); +} + +// only for draft messages +td_api::object_ptr MessageInputReplyTo::get_input_message_reply_to_object(Td *td) const { + if (story_full_id_.is_valid()) { + return td_api::make_object( + td->dialog_manager_->get_chat_id_object(story_full_id_.get_dialog_id(), "inputMessageReplyToStory"), + story_full_id_.get_story_id().get()); + } + if (!message_id_.is_valid() && !message_id_.is_valid_scheduled()) { + return nullptr; + } + if (dialog_id_ != DialogId()) { + return td_api::make_object( + td->dialog_manager_->get_chat_id_object(dialog_id_, "inputMessageReplyToExternalMessage"), message_id_.get(), + quote_.get_input_text_quote_object(td->user_manager_.get())); + } + return td_api::make_object( + message_id_.get(), quote_.get_input_text_quote_object(td->user_manager_.get())); +} + +MessageId MessageInputReplyTo::get_same_chat_reply_to_message_id() const { + return dialog_id_ == DialogId() && (message_id_.is_valid() || message_id_.is_valid_scheduled()) ? message_id_ + : MessageId(); +} + +MessageFullId MessageInputReplyTo::get_reply_message_full_id(DialogId owner_dialog_id) const { + if (!message_id_.is_valid() && !message_id_.is_valid_scheduled()) { + return {}; + } + return {dialog_id_ != DialogId() ? dialog_id_ : owner_dialog_id, message_id_}; +} + +bool operator==(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs) { + return lhs.message_id_ == rhs.message_id_ && lhs.dialog_id_ == rhs.dialog_id_ && + lhs.story_full_id_ == rhs.story_full_id_ && lhs.quote_ == rhs.quote_; +} + +bool operator!=(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageInputReplyTo &input_reply_to) { + if (input_reply_to.message_id_.is_valid() || input_reply_to.message_id_.is_valid_scheduled()) { + string_builder << input_reply_to.message_id_; + if (input_reply_to.dialog_id_ != DialogId()) { + string_builder << " in " << input_reply_to.dialog_id_; + } + return string_builder << input_reply_to.quote_; + } + if (input_reply_to.story_full_id_.is_valid()) { + return string_builder << input_reply_to.story_full_id_; + } + return string_builder << "nothing"; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageInputReplyTo *input_reply_to_ptr) { + if (input_reply_to_ptr == nullptr) { + return string_builder << "nothing"; + } + return string_builder << *input_reply_to_ptr; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.h b/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.h new file mode 100644 index 0000000000..c0dfaba3f2 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.h @@ -0,0 +1,114 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessageQuote.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Dependencies; + +class Td; + +class MessageInputReplyTo { + MessageId message_id_; + DialogId dialog_id_; + MessageQuote quote_; + // or + StoryFullId story_full_id_; + + friend bool operator==(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageInputReplyTo &input_reply_to); + + friend class RepliedMessageInfo; + + public: + MessageInputReplyTo() = default; + MessageInputReplyTo(const MessageInputReplyTo &) = delete; + MessageInputReplyTo &operator=(const MessageInputReplyTo &) = delete; + MessageInputReplyTo(MessageInputReplyTo &&) = default; + MessageInputReplyTo &operator=(MessageInputReplyTo &&) = default; + ~MessageInputReplyTo(); + + MessageInputReplyTo(MessageId message_id, DialogId dialog_id, MessageQuote quote) + : message_id_(message_id), dialog_id_(dialog_id), quote_(std::move(quote)) { + } + + explicit MessageInputReplyTo(StoryFullId story_full_id) : story_full_id_(story_full_id) { + } + + MessageInputReplyTo(Td *td, telegram_api::object_ptr &&input_reply_to); + + bool is_empty() const { + return !message_id_.is_valid() && !message_id_.is_valid_scheduled() && !story_full_id_.is_valid(); + } + + bool is_valid() const { + return !is_empty(); + } + + bool has_quote() const { + return !quote_.is_empty(); + } + + void set_quote(MessageQuote quote) { + quote_ = std::move(quote); + } + + StoryFullId get_story_full_id() const { + return story_full_id_; + } + + MessageInputReplyTo clone() const { + if (story_full_id_.is_valid()) { + return MessageInputReplyTo(story_full_id_); + } + return MessageInputReplyTo(message_id_, dialog_id_, quote_.clone()); + } + + void add_dependencies(Dependencies &dependencies) const; + + telegram_api::object_ptr get_input_reply_to(Td *td, + MessageId top_thread_message_id) const; + + td_api::object_ptr get_input_message_reply_to_object(Td *td) const; + + void set_message_id(MessageId new_message_id) { + CHECK(message_id_.is_valid() || message_id_.is_valid_scheduled()); + message_id_ = new_message_id; + } + + MessageId get_same_chat_reply_to_message_id() const; + + MessageFullId get_reply_message_full_id(DialogId owner_dialog_id) const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs); + +bool operator!=(const MessageInputReplyTo &lhs, const MessageInputReplyTo &rhs); + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageInputReplyTo &input_reply_to); + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageInputReplyTo *input_reply_to_ptr); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.hpp b/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.hpp new file mode 100644 index 0000000000..544204631e --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageInputReplyTo.hpp @@ -0,0 +1,87 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageInputReplyTo.h" + +#include "td/telegram/MessageOrigin.hpp" +#include "td/telegram/MessageQuote.h" +#include "td/telegram/MessageQuote.hpp" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void MessageInputReplyTo::store(StorerT &storer) const { + bool has_message_id = message_id_.is_valid(); + bool has_story_full_id = story_full_id_.is_valid(); + bool has_dialog_id = dialog_id_.is_valid(); + bool has_quote = !quote_.is_empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_message_id); + STORE_FLAG(has_story_full_id); + STORE_FLAG(false); + STORE_FLAG(has_dialog_id); + STORE_FLAG(false); + STORE_FLAG(has_quote); + END_STORE_FLAGS(); + if (has_message_id) { + td::store(message_id_, storer); + } + if (has_story_full_id) { + td::store(story_full_id_, storer); + } + if (has_dialog_id) { + td::store(dialog_id_, storer); + } + if (has_quote) { + td::store(quote_, storer); + } +} + +template +void MessageInputReplyTo::parse(ParserT &parser) { + bool has_message_id; + bool has_story_full_id; + bool has_quote_legacy; + bool has_dialog_id; + bool has_quote_position_legacy; + bool has_quote; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_message_id); + PARSE_FLAG(has_story_full_id); + PARSE_FLAG(has_quote_legacy); + PARSE_FLAG(has_dialog_id); + PARSE_FLAG(has_quote_position_legacy); + PARSE_FLAG(has_quote); + END_PARSE_FLAGS(); + if (has_message_id) { + td::parse(message_id_, parser); + } + if (has_story_full_id) { + td::parse(story_full_id_, parser); + } + FormattedText quote_legacy; + if (has_quote_legacy) { + td::parse(quote_legacy, parser); + } + if (has_dialog_id) { + td::parse(dialog_id_, parser); + } + int32 quote_position_legacy = 0; + if (has_quote_position_legacy) { + td::parse(quote_position_legacy, parser); + } + if (has_quote) { + td::parse(quote_, parser); + } else if (has_quote_legacy) { + quote_ = MessageQuote(std::move(quote_legacy), quote_position_legacy); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.cpp new file mode 100644 index 0000000000..418430236d --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.cpp @@ -0,0 +1,172 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageOrigin.h" + +#include "td/telegram/ChannelId.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/Td.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/logging.h" +#include "td/utils/misc.h" + +namespace td { + +Result MessageOrigin::get_message_origin( + Td *td, telegram_api::object_ptr &&forward_header) { + CHECK(forward_header != nullptr); + DialogId sender_dialog_id; + if (forward_header->from_id_ != nullptr) { + sender_dialog_id = DialogId(forward_header->from_id_); + if (!sender_dialog_id.is_valid()) { + LOG(ERROR) << "Receive invalid sender identifier in message forward header: " + << oneline(to_string(forward_header)); + sender_dialog_id = DialogId(); + } + } + + MessageId message_id; + if (forward_header->channel_post_ != 0) { + message_id = MessageId(ServerMessageId(forward_header->channel_post_)); + if (!message_id.is_valid()) { + LOG(ERROR) << "Receive " << message_id << " in message forward header: " << oneline(to_string(forward_header)); + message_id = MessageId(); + } + } + + string author_signature = std::move(forward_header->post_author_); + string sender_name = std::move(forward_header->from_name_); + + UserId sender_user_id; + if (sender_dialog_id.get_type() == DialogType::User) { + sender_user_id = sender_dialog_id.get_user_id(); + sender_dialog_id = DialogId(); + } + if (!sender_dialog_id.is_valid()) { + if (sender_user_id.is_valid()) { + if (message_id.is_valid()) { + LOG(ERROR) << "Receive non-empty message identifier in message forward header: " + << oneline(to_string(forward_header)); + message_id = MessageId(); + } + } else if (sender_name.empty()) { + LOG(ERROR) << "Receive wrong message forward header: " << oneline(to_string(forward_header)); + return Status::Error("Receive empty forward header"); + } + } else if (sender_dialog_id.get_type() != DialogType::Channel) { + LOG(ERROR) << "Receive wrong message forward header with non-channel sender: " + << oneline(to_string(forward_header)); + return Status::Error("Forward from a non-channel"); + } else { + auto channel_id = sender_dialog_id.get_channel_id(); + if (!td->chat_manager_->have_channel(channel_id)) { + LOG(ERROR) << "Receive forward from " << (td->chat_manager_->have_min_channel(channel_id) ? "min" : "unknown") + << ' ' << channel_id; + } + td->dialog_manager_->force_create_dialog(sender_dialog_id, "get_message_origin", true); + CHECK(!sender_user_id.is_valid()); + } + + return MessageOrigin{sender_user_id, sender_dialog_id, message_id, std::move(author_signature), + std::move(sender_name)}; +} + +td_api::object_ptr MessageOrigin::get_message_origin_object(const Td *td) const { + if (is_sender_hidden()) { + return td_api::make_object(sender_name_.empty() ? author_signature_ + : sender_name_); + } + if (message_id_.is_valid()) { + return td_api::make_object( + td->dialog_manager_->get_chat_id_object(sender_dialog_id_, "messageOriginChannel"), message_id_.get(), + author_signature_); + } + if (sender_dialog_id_.is_valid()) { + return td_api::make_object( + td->dialog_manager_->get_chat_id_object(sender_dialog_id_, "messageOriginChat"), + sender_name_.empty() ? author_signature_ : sender_name_); + } + return td_api::make_object( + td->user_manager_->get_user_id_object(sender_user_id_, "messageOriginUser")); +} + +bool MessageOrigin::is_sender_hidden() const { + if (!sender_name_.empty()) { + return true; + } + DialogId hidden_sender_dialog_id(ChannelId(static_cast(G()->is_test_dc() ? 10460537 : 1228946795))); + return sender_dialog_id_ == hidden_sender_dialog_id && !author_signature_.empty() && !message_id_.is_valid(); +} + +MessageFullId MessageOrigin::get_message_full_id() const { + if (!message_id_.is_valid() || !sender_dialog_id_.is_valid() || is_sender_hidden()) { + return MessageFullId(); + } + return {sender_dialog_id_, message_id_}; +} + +DialogId MessageOrigin::get_sender() const { + if (is_sender_hidden()) { + return DialogId(); + } + return message_id_.is_valid() || sender_dialog_id_.is_valid() ? sender_dialog_id_ : DialogId(sender_user_id_); +} + +void MessageOrigin::hide_sender_if_needed(Td *td) { + if (!is_sender_hidden() && !message_id_.is_valid() && !sender_dialog_id_.is_valid()) { + auto private_forward_name = td->user_manager_->get_user_private_forward_name(sender_user_id_); + if (!private_forward_name.empty()) { + sender_user_id_ = UserId(); + sender_name_ = std::move(private_forward_name); + } + } +} + +void MessageOrigin::add_dependencies(Dependencies &dependencies) const { + dependencies.add(sender_user_id_); + dependencies.add_dialog_and_dependencies(sender_dialog_id_); +} + +void MessageOrigin::add_user_ids(vector &user_ids) const { + if (sender_user_id_.is_valid()) { + user_ids.push_back(sender_user_id_); + } +} + +void MessageOrigin::add_channel_ids(vector &channel_ids) const { + if (sender_dialog_id_.get_type() == DialogType::Channel) { + channel_ids.push_back(sender_dialog_id_.get_channel_id()); + } +} + +bool operator==(const MessageOrigin &lhs, const MessageOrigin &rhs) { + return lhs.sender_user_id_ == rhs.sender_user_id_ && lhs.sender_dialog_id_ == rhs.sender_dialog_id_ && + lhs.message_id_ == rhs.message_id_ && lhs.author_signature_ == rhs.author_signature_ && + lhs.sender_name_ == rhs.sender_name_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageOrigin &origin) { + string_builder << "sender " << origin.sender_user_id_; + if (!origin.author_signature_.empty() || !origin.sender_name_.empty()) { + string_builder << '(' << origin.author_signature_ << '/' << origin.sender_name_ << ')'; + } + if (origin.sender_dialog_id_.is_valid()) { + string_builder << ", source "; + if (origin.message_id_.is_valid()) { + string_builder << MessageFullId(origin.sender_dialog_id_, origin.message_id_); + } else { + string_builder << origin.sender_dialog_id_; + } + } + return string_builder; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.h b/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.h new file mode 100644 index 0000000000..afb45cd750 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.h @@ -0,0 +1,101 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ChannelId.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Dependencies; + +class Td; + +class MessageOrigin { + UserId sender_user_id_; + DialogId sender_dialog_id_; + MessageId message_id_; + string author_signature_; + string sender_name_; + + public: + MessageOrigin() = default; + + MessageOrigin(UserId sender_user_id, DialogId sender_dialog_id, MessageId message_id, string &&author_signature, + string &&sender_name) + : sender_user_id_(sender_user_id) + , sender_dialog_id_(sender_dialog_id) + , message_id_(message_id) + , author_signature_(std::move(author_signature)) + , sender_name_(std::move(sender_name)) { + } + + static Result get_message_origin( + Td *td, telegram_api::object_ptr &&forward_header); + + bool is_empty() const { + return !sender_user_id_.is_valid() && !sender_dialog_id_.is_valid() && !message_id_.is_valid() && + author_signature_.empty() && sender_name_.empty(); + } + + td_api::object_ptr get_message_origin_object(const Td *td) const; + + bool is_sender_hidden() const; + + MessageFullId get_message_full_id() const; + + const string &get_sender_name() const { + return sender_name_; + } + + bool is_channel_post() const { + return message_id_.is_valid(); + } + + bool has_sender_signature() const { + return !author_signature_.empty() || !sender_name_.empty(); + } + + DialogId get_sender() const; + + void hide_sender_if_needed(Td *td); + + void add_dependencies(Dependencies &dependencies) const; + + void add_user_ids(vector &user_ids) const; + + void add_channel_ids(vector &channel_ids) const; + + friend bool operator==(const MessageOrigin &lhs, const MessageOrigin &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageOrigin &origin); + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const MessageOrigin &lhs, const MessageOrigin &rhs); + +inline bool operator!=(const MessageOrigin &lhs, const MessageOrigin &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageOrigin &origin); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.hpp b/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.hpp new file mode 100644 index 0000000000..f5c233b2eb --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageOrigin.hpp @@ -0,0 +1,79 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageOrigin.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void MessageOrigin::store(StorerT &storer) const { + bool has_sender_user_id = sender_user_id_.is_valid(); + bool has_sender_dialog_id = sender_dialog_id_.is_valid(); + bool has_message_id = message_id_.is_valid(); + bool has_author_signature = !author_signature_.empty(); + bool has_sender_name = !sender_name_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_sender_user_id); + STORE_FLAG(has_sender_dialog_id); + STORE_FLAG(has_message_id); + STORE_FLAG(has_author_signature); + STORE_FLAG(has_sender_name); + END_STORE_FLAGS(); + if (has_sender_user_id) { + td::store(sender_user_id_, storer); + } + if (has_sender_dialog_id) { + td::store(sender_dialog_id_, storer); + } + if (has_message_id) { + td::store(message_id_, storer); + } + if (has_author_signature) { + td::store(author_signature_, storer); + } + if (has_sender_name) { + td::store(sender_name_, storer); + } +} + +template +void MessageOrigin::parse(ParserT &parser) { + bool has_sender_user_id; + bool has_sender_dialog_id; + bool has_message_id; + bool has_author_signature; + bool has_sender_name; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_sender_user_id); + PARSE_FLAG(has_sender_dialog_id); + PARSE_FLAG(has_message_id); + PARSE_FLAG(has_author_signature); + PARSE_FLAG(has_sender_name); + END_PARSE_FLAGS(); + if (has_sender_user_id) { + td::parse(sender_user_id_, parser); + } + if (has_sender_dialog_id) { + td::parse(sender_dialog_id_, parser); + CHECK(sender_dialog_id_.get_type() == DialogType::Channel); + } + if (has_message_id) { + td::parse(message_id_, parser); + } + if (has_author_signature) { + td::parse(author_signature_, parser); + } + if (has_sender_name) { + td::parse(sender_name_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.cpp new file mode 100644 index 0000000000..34d83cae79 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.cpp @@ -0,0 +1,238 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageQuote.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/algorithm.h" +#include "td/utils/misc.h" +#include "td/utils/Slice.h" +#include "td/utils/utf8.h" + +namespace td { + +MessageQuote::~MessageQuote() = default; + +MessageQuote::MessageQuote(Td *td, + telegram_api::object_ptr &input_reply_to_message) { + CHECK(input_reply_to_message != nullptr); + if (input_reply_to_message->quote_text_.empty()) { + return; + } + text_ = get_formatted_text(td->user_manager_.get(), std::move(input_reply_to_message->quote_text_), + std::move(input_reply_to_message->quote_entities_), true, false, "inputReplyToMessage"); + remove_unallowed_quote_entities(text_); + position_ = max(0, input_reply_to_message->quote_offset_); +} + +MessageQuote::MessageQuote(Td *td, telegram_api::object_ptr &reply_header) { + CHECK(reply_header != nullptr); + if (reply_header->quote_text_.empty()) { + return; + } + text_ = get_formatted_text(td->user_manager_.get(), std::move(reply_header->quote_text_), + std::move(reply_header->quote_entities_), true, false, "messageReplyHeader"); + remove_unallowed_quote_entities(text_); + position_ = max(0, reply_header->quote_offset_); + is_manual_ = reply_header->quote_; +} + +MessageQuote::MessageQuote(Td *td, td_api::object_ptr quote) { + if (quote == nullptr) { + return; + } + int32 ltrim_count = 0; + auto r_text = get_formatted_text(td, td->dialog_manager_->get_my_dialog_id(), std::move(quote->text_), + td->auth_manager_->is_bot(), true, true, false, <rim_count); + if (!r_text.is_ok() || r_text.ok().text.empty()) { + return; + } + text_ = r_text.move_as_ok(); + position_ = quote->position_; + if (0 <= position_ && position_ <= 1000000) { // some unreasonably big bound + position_ += ltrim_count; + } else { + position_ = 0; + } +} + +MessageQuote MessageQuote::clone(bool ignore_is_manual) const { + return {FormattedText(text_), position_, ignore_is_manual ? true : is_manual_}; +} + +MessageQuote MessageQuote::create_automatic_quote(Td *td, FormattedText &&text) { + truncate_formatted_text( + text, static_cast(td->option_manager_->get_option_integer("message_reply_quote_length_max"))); + return MessageQuote(std::move(text), 0, false); +} + +int MessageQuote::need_quote_changed_warning(const MessageQuote &old_quote, const MessageQuote &new_quote) { + if (old_quote.position_ != new_quote.position_ && + max(old_quote.position_, new_quote.position_) < + static_cast(min(old_quote.text_.text.size(), new_quote.text_.text.size()))) { + // quote position can't change + return 1; + } + if (old_quote.is_manual_ != new_quote.is_manual_) { + // quote manual property can't change + return 1; + } + if (old_quote.text_ != new_quote.text_) { + if (old_quote.is_manual_) { + return 1; + } + // automatic quote can change if the original message was edited + return -1; + } + return 0; +} + +void MessageQuote::add_dependencies(Dependencies &dependencies) const { + add_formatted_text_dependencies(dependencies, &text_); // just in case +} + +void MessageQuote::update_input_reply_to_message(Td *td, + telegram_api::inputReplyToMessage *input_reply_to_message) const { + CHECK(input_reply_to_message != nullptr); + if (is_empty()) { + return; + } + CHECK(is_manual_); + input_reply_to_message->flags_ |= telegram_api::inputReplyToMessage::QUOTE_TEXT_MASK; + input_reply_to_message->quote_text_ = text_.text; + input_reply_to_message->quote_entities_ = + get_input_message_entities(td->user_manager_.get(), text_.entities, "update_input_reply_to_message"); + if (!input_reply_to_message->quote_entities_.empty()) { + input_reply_to_message->flags_ |= telegram_api::inputReplyToMessage::QUOTE_ENTITIES_MASK; + } + if (position_ != 0) { + input_reply_to_message->flags_ |= telegram_api::inputReplyToMessage::QUOTE_OFFSET_MASK; + input_reply_to_message->quote_offset_ = position_; + } +} + +// only for draft messages +td_api::object_ptr MessageQuote::get_input_text_quote_object( + const UserManager *user_manager) const { + if (is_empty()) { + return nullptr; + } + CHECK(is_manual_); + return td_api::make_object(get_formatted_text_object(user_manager, text_, true, -1), + position_); +} + +td_api::object_ptr MessageQuote::get_text_quote_object(const UserManager *user_manager) const { + if (is_empty()) { + return nullptr; + } + return td_api::make_object(get_formatted_text_object(user_manager, text_, true, -1), position_, + is_manual_); +} + +bool operator==(const MessageQuote &lhs, const MessageQuote &rhs) { + return lhs.text_ == rhs.text_ && lhs.position_ == rhs.position_ && lhs.is_manual_ == rhs.is_manual_; +} + +bool operator!=(const MessageQuote &lhs, const MessageQuote &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageQuote "e) { + if (!quote.is_empty()) { + string_builder << " with " << quote.text_.text.size() << (!quote.is_manual_ ? " automatically" : "") + << " quoted bytes"; + if (quote.position_ != 0) { + string_builder << " at position " << quote.position_; + } + } + return string_builder; +} + +void MessageQuote::remove_unallowed_quote_entities(FormattedText &text) { + auto is_allowed_quote_entity = [](const MessageEntity &entity) { + switch (entity.type) { + case MessageEntity::Type::Bold: + case MessageEntity::Type::Italic: + case MessageEntity::Type::Underline: + case MessageEntity::Type::Strikethrough: + case MessageEntity::Type::Spoiler: + case MessageEntity::Type::CustomEmoji: + return true; + default: + return false; + } + }; + + td::remove_if(text.entities, [&](const auto &entity) { return !is_allowed_quote_entity(entity); }); +} + +int32 MessageQuote::search_quote(FormattedText &&text, FormattedText &"e, int32 quote_position) { + auto process_quote_entities = [](FormattedText &text, int32 length) { + remove_unallowed_quote_entities(text); + td::remove_if(text.entities, [length](const MessageEntity &entity) { + if (entity.offset < 0 || entity.offset >= length) { + return true; + } + if (entity.length <= 0 || entity.length > length - entity.offset) { + return true; + } + return false; + }); + remove_empty_entities(text.entities); + fix_entities(text.entities); + remove_empty_entities(text.entities); + }; + auto length = narrow_cast(utf8_utf16_length(text.text)); + auto quote_length = narrow_cast(utf8_utf16_length(quote.text)); + if (quote_length == 0 || quote_length > length) { + return -1; + } + process_quote_entities(text, length); + process_quote_entities(quote, quote_length); + + quote_position = clamp(quote_position, 0, length - 1); + vector byte_positions; + byte_positions.reserve(length); + for (size_t i = 0; i < text.text.size(); i++) { + auto c = static_cast(text.text[i]); + if (is_utf8_character_first_code_unit(c)) { + byte_positions.push_back(i); + if (c >= 0xf0) { // >= 4 bytes in symbol => surrogate pair + byte_positions.push_back(string::npos); + } + } + } + CHECK(byte_positions.size() == static_cast(length)); + auto check_position = [&text, "e, &byte_positions, length, quote_length](int32 position) { + if (position < 0 || position > length - quote_length) { + return false; + } + auto byte_position = byte_positions[position]; + if (byte_position == string::npos || text.text[byte_position] != quote.text[0] || + Slice(text.text).substr(byte_position, quote.text.size()) != quote.text) { + return false; + } + return true; + }; + for (int32 i = 0; quote_position - i >= 0 || quote_position + i + 1 <= length - quote_length; i++) { + if (check_position(quote_position - i)) { + return quote_position - i; + } + if (check_position(quote_position + i + 1)) { + return quote_position + i + 1; + } + } + return -1; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.h b/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.h new file mode 100644 index 0000000000..d9779300f9 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.h @@ -0,0 +1,85 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageEntity.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Dependencies; + +class Td; + +class MessageQuote { + FormattedText text_; + int32 position_ = 0; + bool is_manual_ = true; + + friend bool operator==(const MessageQuote &lhs, const MessageQuote &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageQuote "e); + + static void remove_unallowed_quote_entities(FormattedText &text); + + public: + MessageQuote() = default; + MessageQuote(const MessageQuote &) = delete; + MessageQuote &operator=(const MessageQuote &) = delete; + MessageQuote(MessageQuote &&) = default; + MessageQuote &operator=(MessageQuote &&) = default; + ~MessageQuote(); + + MessageQuote(FormattedText &&text, int32 position, bool is_manual = true) + : text_(std::move(text)), position_(max(0, position)), is_manual_(is_manual) { + remove_unallowed_quote_entities(text_); + } + + MessageQuote(Td *td, telegram_api::object_ptr &input_reply_to_message); + + MessageQuote(Td *td, telegram_api::object_ptr &reply_header); + + MessageQuote(Td *td, td_api::object_ptr quote); + + static MessageQuote create_automatic_quote(Td *td, FormattedText &&text); + + static int need_quote_changed_warning(const MessageQuote &old_quote, const MessageQuote &new_quote); + + static int32 search_quote(FormattedText &&text, FormattedText &"e, int32 quote_position); + + bool is_empty() const { + return text_.text.empty(); + } + + MessageQuote clone(bool ignore_is_manual = false) const; + + void add_dependencies(Dependencies &dependencies) const; + + void update_input_reply_to_message(Td *td, telegram_api::inputReplyToMessage *input_reply_to_message) const; + + td_api::object_ptr get_input_text_quote_object(const UserManager *user_manager) const; + + td_api::object_ptr get_text_quote_object(const UserManager *user_manager) const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const MessageQuote &lhs, const MessageQuote &rhs); + +bool operator!=(const MessageQuote &lhs, const MessageQuote &rhs); + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageQuote "e); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.hpp b/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.hpp new file mode 100644 index 0000000000..ea29ad5b68 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageQuote.hpp @@ -0,0 +1,50 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageQuote.h" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void MessageQuote::store(StorerT &storer) const { + bool has_text = !text_.text.empty(); + bool has_position = position_ != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_text); + STORE_FLAG(has_position); + STORE_FLAG(is_manual_); + END_STORE_FLAGS(); + if (has_text) { + td::store(text_, storer); + } + if (has_position) { + td::store(position_, storer); + } +} + +template +void MessageQuote::parse(ParserT &parser) { + bool has_text; + bool has_position; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_text); + PARSE_FLAG(has_position); + PARSE_FLAG(is_manual_); + END_PARSE_FLAGS(); + if (has_text) { + td::parse(text_, parser); + remove_unallowed_quote_entities(text_); + } + if (has_position) { + td::parse(position_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.cpp index a8a2d6db8d..e00b7d4261 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,35 +7,33 @@ #include "td/telegram/MessageReaction.h" #include "td/telegram/AccessRights.h" -#include "td/telegram/ConfigManager.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Global.h" #include "td/telegram/MessageSender.h" #include "td/telegram/MessagesManager.h" -#include "td/telegram/misc.h" #include "td/telegram/OptionManager.h" #include "td/telegram/ServerMessageId.h" -#include "td/telegram/StickersManager.h" +#include "td/telegram/StarManager.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" #include "td/actor/actor.h" +#include "td/actor/SleepActor.h" #include "td/utils/algorithm.h" -#include "td/utils/as.h" -#include "td/utils/base64.h" #include "td/utils/buffer.h" -#include "td/utils/crypto.h" -#include "td/utils/emoji.h" #include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" +#include "td/utils/misc.h" #include "td/utils/Slice.h" -#include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" -#include "td/utils/utf8.h" #include +#include #include namespace td { @@ -47,81 +45,6 @@ static size_t get_max_reaction_count() { max(static_cast(1), static_cast(G()->get_option_integer(option_key, is_premium ? 3 : 1)))); } -static int64 get_custom_emoji_id(const string &reaction) { - auto r_decoded = base64_decode(Slice(&reaction[1], reaction.size() - 1)); - CHECK(r_decoded.is_ok()); - CHECK(r_decoded.ok().size() == 8); - return as(r_decoded.ok().c_str()); -} - -static string get_custom_emoji_string(int64 custom_emoji_id) { - char s[8]; - as(&s) = custom_emoji_id; - return PSTRING() << '#' << base64_encode(Slice(s, 8)); -} - -telegram_api::object_ptr get_input_reaction(const string &reaction) { - if (reaction.empty()) { - return telegram_api::make_object(); - } - if (is_custom_reaction(reaction)) { - return telegram_api::make_object(get_custom_emoji_id(reaction)); - } - return telegram_api::make_object(reaction); -} - -string get_message_reaction_string(const telegram_api::object_ptr &reaction) { - if (reaction == nullptr) { - return string(); - } - switch (reaction->get_id()) { - case telegram_api::reactionEmpty::ID: - return string(); - case telegram_api::reactionEmoji::ID: { - const string &emoji = static_cast(reaction.get())->emoticon_; - if (is_custom_reaction(emoji)) { - return string(); - } - return emoji; - } - case telegram_api::reactionCustomEmoji::ID: - return get_custom_emoji_string( - static_cast(reaction.get())->document_id_); - default: - UNREACHABLE(); - return string(); - } -} - -td_api::object_ptr get_reaction_type_object(const string &reaction) { - CHECK(!reaction.empty()); - if (is_custom_reaction(reaction)) { - return td_api::make_object(get_custom_emoji_id(reaction)); - } - return td_api::make_object(reaction); -} - -string get_message_reaction_string(const td_api::object_ptr &type) { - if (type == nullptr) { - return string(); - } - switch (type->get_id()) { - case td_api::reactionTypeEmoji::ID: { - const string &emoji = static_cast(type.get())->emoji_; - if (!check_utf8(emoji) || is_custom_reaction(emoji)) { - return string(); - } - return emoji; - } - case td_api::reactionTypeCustomEmoji::ID: - return get_custom_emoji_string( - static_cast(type.get())->custom_emoji_id_); - default: - UNREACHABLE(); - return string(); - } -} - class GetMessagesReactionsQuery final : public Td::ResultHandler { DialogId dialog_id_; vector message_ids_; @@ -131,7 +54,7 @@ class GetMessagesReactionsQuery final : public Td::ResultHandler { dialog_id_ = dialog_id; message_ids_ = std::move(message_ids); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); CHECK(input_peer != nullptr); send_query( @@ -171,7 +94,7 @@ class GetMessagesReactionsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetMessagesReactionsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetMessagesReactionsQuery"); td_->messages_manager_->try_reload_message_reactions(dialog_id_, true); } }; @@ -184,16 +107,16 @@ class SendReactionQuery final : public Td::ResultHandler { explicit SendReactionQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(FullMessageId full_message_id, vector reactions, bool is_big, bool add_to_recent) { - dialog_id_ = full_message_id.get_dialog_id(); + void send(MessageFullId message_full_id, vector reaction_types, bool is_big, bool add_to_recent) { + dialog_id_ = message_full_id.get_dialog_id(); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } int32 flags = 0; - if (!reactions.empty()) { + if (!reaction_types.empty()) { flags |= telegram_api::messages_sendReaction::REACTION_MASK; if (is_big) { @@ -207,9 +130,9 @@ class SendReactionQuery final : public Td::ResultHandler { send_query(G()->net_query_creator().create( telegram_api::messages_sendReaction(flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), - full_message_id.get_message_id().get_server_message_id().get(), - transform(reactions, get_input_reaction)), - {{dialog_id_}, {full_message_id}})); + message_full_id.get_message_id().get_server_message_id().get(), + ReactionType::get_input_reactions(reaction_types)), + {{dialog_id_}, {message_full_id}})); } void on_result(BufferSlice packet) final { @@ -227,16 +150,130 @@ class SendReactionQuery final : public Td::ResultHandler { if (status.message() == "MESSAGE_NOT_MODIFIED") { return promise_.set_value(Unit()); } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendReactionQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendReactionQuery"); + promise_.set_error(std::move(status)); + } +}; + +class SendPaidReactionQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + int64 star_count_; + + public: + explicit SendPaidReactionQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(MessageFullId message_full_id, int32 star_count, bool use_default_is_anonymous, bool is_anonymous, + int64 random_id) { + dialog_id_ = message_full_id.get_dialog_id(); + star_count_ = star_count; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + int32 flags = 0; + if (!use_default_is_anonymous) { + flags |= telegram_api::messages_sendPaidReaction::PRIVATE_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::messages_sendPaidReaction(flags, std::move(input_peer), + message_full_id.get_message_id().get_server_message_id().get(), + star_count, random_id, is_anonymous), + {{dialog_id_}, {message_full_id}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendPaidReactionQuery: " << to_string(ptr); + td_->star_manager_->add_pending_owned_star_count(star_count_, true); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + if (status.message() == "MESSAGE_NOT_MODIFIED") { + td_->star_manager_->add_pending_owned_star_count(star_count_, true); + return promise_.set_value(Unit()); + } + td_->star_manager_->add_pending_owned_star_count(star_count_, false); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendPaidReactionQuery"); + promise_.set_error(std::move(status)); + } +}; + +class TogglePaidReactionPrivacyQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit TogglePaidReactionPrivacyQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(MessageFullId message_full_id, bool is_anonymous) { + dialog_id_ = message_full_id.get_dialog_id(); + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + send_query(G()->net_query_creator().create( + telegram_api::messages_togglePaidReactionPrivacy( + std::move(input_peer), message_full_id.get_message_id().get_server_message_id().get(), is_anonymous), + {{dialog_id_}, {message_full_id}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "TogglePaidReactionPrivacyQuery"); promise_.set_error(std::move(status)); } }; +class GetPaidReactionPrivacyQuery final : public Td::ResultHandler { + public: + void send() { + send_query(G()->net_query_creator().create(telegram_api::messages_getPaidReactionPrivacy())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetPaidReactionPrivacyQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), Promise()); + } + + void on_error(Status status) final { + if (!G()->is_expected_error(status)) { + LOG(ERROR) << "Receive " << status; + } + } +}; + class GetMessageReactionsListQuery final : public Td::ResultHandler { Promise> promise_; DialogId dialog_id_; MessageId message_id_; - string reaction_; + ReactionType reaction_type_; string offset_; public: @@ -244,19 +281,19 @@ class GetMessageReactionsListQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(FullMessageId full_message_id, string reaction, string offset, int32 limit) { - dialog_id_ = full_message_id.get_dialog_id(); - message_id_ = full_message_id.get_message_id(); - reaction_ = std::move(reaction); + void send(MessageFullId message_full_id, ReactionType reaction_type, string offset, int32 limit) { + dialog_id_ = message_full_id.get_dialog_id(); + message_id_ = message_full_id.get_message_id(); + reaction_type_ = std::move(reaction_type); offset_ = std::move(offset); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } int32 flags = 0; - if (!reaction_.empty()) { + if (!reaction_type_.is_empty()) { flags |= telegram_api::messages_getMessageReactionsList::REACTION_MASK; } if (!offset_.empty()) { @@ -266,8 +303,8 @@ class GetMessageReactionsListQuery final : public Td::ResultHandler { send_query(G()->net_query_creator().create( telegram_api::messages_getMessageReactionsList(flags, std::move(input_peer), message_id_.get_server_message_id().get(), - get_input_reaction(reaction_), offset_, limit), - {{full_message_id}})); + reaction_type_.get_input_reaction(), offset_, limit), + {{message_full_id}})); } void on_result(BufferSlice packet) final { @@ -279,8 +316,8 @@ class GetMessageReactionsListQuery final : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for GetMessageReactionsListQuery: " << to_string(ptr); - td_->contacts_manager_->on_get_users(std::move(ptr->users_), "GetMessageReactionsListQuery"); - td_->contacts_manager_->on_get_chats(std::move(ptr->chats_), "GetMessageReactionsListQuery"); + td_->user_manager_->on_get_users(std::move(ptr->users_), "GetMessageReactionsListQuery"); + td_->chat_manager_->on_get_chats(std::move(ptr->chats_), "GetMessageReactionsListQuery"); int32 total_count = ptr->count_; auto received_reaction_count = static_cast(ptr->reactions_.size()); @@ -290,29 +327,30 @@ class GetMessageReactionsListQuery final : public Td::ResultHandler { } vector> reactions; - FlatHashMap> recent_reactions; + FlatHashMap, ReactionTypeHash> recent_reaction_types; for (const auto &reaction : ptr->reactions_) { DialogId dialog_id(reaction->peer_id_); - auto reaction_str = get_message_reaction_string(reaction->reaction_); - if (!dialog_id.is_valid() || (reaction_.empty() ? reaction_str.empty() : reaction_ != reaction_str)) { + auto reaction_type = ReactionType(reaction->reaction_); + if (!dialog_id.is_valid() || + (reaction_type_.is_empty() ? reaction_type.is_empty() : reaction_type_ != reaction_type)) { LOG(ERROR) << "Receive unexpected " << to_string(reaction); continue; } if (offset_.empty()) { - recent_reactions[reaction_str].push_back(dialog_id); + recent_reaction_types[reaction_type].push_back(dialog_id); } auto message_sender = get_min_message_sender_object(td_, dialog_id, "GetMessageReactionsListQuery"); if (message_sender != nullptr) { - reactions.push_back(td_api::make_object(get_reaction_type_object(reaction_str), - std::move(message_sender), reaction->date_)); + reactions.push_back(td_api::make_object( + reaction_type.get_reaction_type_object(), std::move(message_sender), reaction->my_, reaction->date_)); } } if (offset_.empty()) { - td_->messages_manager_->on_get_message_reaction_list({dialog_id_, message_id_}, reaction_, - std::move(recent_reactions), total_count); + td_->messages_manager_->on_get_message_reaction_list({dialog_id_, message_id_}, reaction_type_, + std::move(recent_reaction_types), total_count); } promise_.set_value( @@ -320,50 +358,11 @@ class GetMessageReactionsListQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetMessageReactionsListQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetMessageReactionsListQuery"); promise_.set_error(std::move(status)); } }; -class SetDefaultReactionQuery final : public Td::ResultHandler { - string reaction_; - - public: - void send(const string &reaction) { - reaction_ = reaction; - send_query( - G()->net_query_creator().create(telegram_api::messages_setDefaultReaction(get_input_reaction(reaction)))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - if (!result_ptr.ok()) { - return on_error(Status::Error(400, "Receive false")); - } - - auto default_reaction = td_->option_manager_->get_option_string("default_reaction", "-"); - if (default_reaction != reaction_) { - send_set_default_reaction_query(td_); - } else { - td_->option_manager_->set_option_empty("default_reaction_needs_sync"); - } - } - - void on_error(Status status) final { - if (G()->close_flag()) { - return; - } - - LOG(INFO) << "Receive error for SetDefaultReactionQuery: " << status; - td_->option_manager_->set_option_empty("default_reaction_needs_sync"); - send_closure(G()->config_manager(), &ConfigManager::request_config, false); - } -}; - class ReportReactionQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; @@ -375,10 +374,10 @@ class ReportReactionQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId message_id, DialogId chooser_dialog_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); CHECK(input_peer != nullptr); - auto chooser_input_peer = td_->messages_manager_->get_input_peer(chooser_dialog_id, AccessRights::Know); + auto chooser_input_peer = td_->dialog_manager_->get_input_peer(chooser_dialog_id, AccessRights::Know); if (chooser_input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Reaction sender is not accessible")); } @@ -397,21 +396,51 @@ class ReportReactionQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReportReactionQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ReportReactionQuery"); promise_.set_error(std::move(status)); } }; -void MessageReaction::add_recent_chooser_dialog_id(DialogId dialog_id) { - recent_chooser_dialog_ids_.insert(recent_chooser_dialog_ids_.begin(), dialog_id); - if (recent_chooser_dialog_ids_.size() > MAX_RECENT_CHOOSERS + 1) { - LOG(ERROR) << "Have " << recent_chooser_dialog_ids_.size() << " recent reaction choosers"; - recent_chooser_dialog_ids_.resize(MAX_RECENT_CHOOSERS + 1); +MessageReaction::MessageReaction(ReactionType reaction_type, int32 choose_count, bool is_chosen, + DialogId my_recent_chooser_dialog_id, vector &&recent_chooser_dialog_ids, + vector> &&recent_chooser_min_channels) + : reaction_type_(std::move(reaction_type)) + , choose_count_(choose_count) + , is_chosen_(is_chosen) + , my_recent_chooser_dialog_id_(my_recent_chooser_dialog_id) + , recent_chooser_dialog_ids_(std::move(recent_chooser_dialog_ids)) + , recent_chooser_min_channels_(std::move(recent_chooser_min_channels)) { + if (my_recent_chooser_dialog_id_.is_valid()) { + CHECK(td::contains(recent_chooser_dialog_ids_, my_recent_chooser_dialog_id_)); + } + fix_choose_count(); +} + +void MessageReaction::add_my_recent_chooser_dialog_id(DialogId dialog_id) { + CHECK(!my_recent_chooser_dialog_id_.is_valid()); + my_recent_chooser_dialog_id_ = dialog_id; + add_to_top(recent_chooser_dialog_ids_, MAX_RECENT_CHOOSERS + 1, dialog_id); + fix_choose_count(); +} + +bool MessageReaction::remove_my_recent_chooser_dialog_id() { + if (my_recent_chooser_dialog_id_.is_valid()) { + bool is_removed = td::remove(recent_chooser_dialog_ids_, my_recent_chooser_dialog_id_); + CHECK(is_removed); + my_recent_chooser_dialog_id_ = DialogId(); + return true; } + return false; } -bool MessageReaction::remove_recent_chooser_dialog_id(DialogId dialog_id) { - return td::remove(recent_chooser_dialog_ids_, dialog_id); +void MessageReaction::update_from(const MessageReaction &old_reaction) { + CHECK(old_reaction.is_chosen()); + is_chosen_ = true; + + auto my_dialog_id = old_reaction.get_my_recent_chooser_dialog_id(); + if (my_dialog_id.is_valid() && td::contains(recent_chooser_dialog_ids_, my_dialog_id)) { + my_recent_chooser_dialog_id_ = my_dialog_id; + } } void MessageReaction::update_recent_chooser_dialog_ids(const MessageReaction &old_reaction) { @@ -419,45 +448,75 @@ void MessageReaction::update_recent_chooser_dialog_ids(const MessageReaction &ol return; } CHECK(is_chosen_ && old_reaction.is_chosen_); - CHECK(reaction_ == old_reaction.reaction_); + CHECK(reaction_type_ == old_reaction.reaction_type_); CHECK(old_reaction.recent_chooser_dialog_ids_.size() == MAX_RECENT_CHOOSERS + 1); for (size_t i = 0; i < MAX_RECENT_CHOOSERS; i++) { if (recent_chooser_dialog_ids_[i] != old_reaction.recent_chooser_dialog_ids_[i]) { return; } } + my_recent_chooser_dialog_id_ = old_reaction.my_recent_chooser_dialog_id_; recent_chooser_dialog_ids_ = old_reaction.recent_chooser_dialog_ids_; recent_chooser_min_channels_ = old_reaction.recent_chooser_min_channels_; + fix_choose_count(); } -void MessageReaction::set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool have_recent_choosers) { - if (is_chosen_ == is_chosen) { - return; +void MessageReaction::set_as_chosen(DialogId my_dialog_id, bool have_recent_choosers) { + CHECK(!is_chosen_); + + is_chosen_ = true; + choose_count_++; + if (have_recent_choosers) { + remove_my_recent_chooser_dialog_id(); + add_my_recent_chooser_dialog_id(my_dialog_id); } +} - is_chosen_ = is_chosen; +void MessageReaction::unset_as_chosen() { + CHECK(is_chosen_); - if (chooser_dialog_id.is_valid()) { - choose_count_ += is_chosen_ ? 1 : -1; - if (have_recent_choosers) { - remove_recent_chooser_dialog_id(chooser_dialog_id); - if (is_chosen_) { - add_recent_chooser_dialog_id(chooser_dialog_id); - } + is_chosen_ = false; + choose_count_--; + remove_my_recent_chooser_dialog_id(); + fix_choose_count(); +} + +void MessageReaction::add_paid_reaction(int32 star_count) { + is_chosen_ = true; + CHECK(star_count <= std::numeric_limits::max() - choose_count_); + choose_count_ += star_count; +} + +void MessageReaction::fix_choose_count() { + choose_count_ = max(choose_count_, narrow_cast(recent_chooser_dialog_ids_.size())); +} + +void MessageReaction::set_my_recent_chooser_dialog_id(DialogId my_dialog_id) { + if (!my_recent_chooser_dialog_id_.is_valid() || my_recent_chooser_dialog_id_ == my_dialog_id) { + return; + } + td::remove(recent_chooser_dialog_ids_, my_dialog_id); + for (auto &dialog_id : recent_chooser_dialog_ids_) { + if (dialog_id == my_recent_chooser_dialog_id_) { + dialog_id = my_dialog_id; } } + CHECK(td::contains(recent_chooser_dialog_ids_, my_dialog_id)); + my_recent_chooser_dialog_id_ = my_dialog_id; } td_api::object_ptr MessageReaction::get_message_reaction_object(Td *td, UserId my_user_id, UserId peer_user_id) const { CHECK(!is_empty()); + td_api::object_ptr used_sender; vector> recent_choosers; if (my_user_id.is_valid()) { CHECK(peer_user_id.is_valid()); if (is_chosen()) { auto recent_chooser = get_min_message_sender_object(td, DialogId(my_user_id), "get_message_reaction_object"); if (recent_chooser != nullptr) { + used_sender = get_min_message_sender_object(td, DialogId(my_user_id), "get_message_reaction_object"); recent_choosers.push_back(std::move(recent_chooser)); } } @@ -471,6 +530,9 @@ td_api::object_ptr MessageReaction::get_message_reactio for (auto dialog_id : recent_chooser_dialog_ids_) { auto recent_chooser = get_min_message_sender_object(td, dialog_id, "get_message_reaction_object"); if (recent_chooser != nullptr) { + if (is_chosen() && dialog_id == my_recent_chooser_dialog_id_) { + used_sender = get_min_message_sender_object(td, dialog_id, "get_message_reaction_object"); + } recent_choosers.push_back(std::move(recent_chooser)); if (recent_choosers.size() == MAX_RECENT_CHOOSERS) { break; @@ -478,19 +540,23 @@ td_api::object_ptr MessageReaction::get_message_reactio } } } - return td_api::make_object(get_reaction_type_object(reaction_), choose_count_, is_chosen_, - std::move(recent_choosers)); + return td_api::make_object(reaction_type_.get_reaction_type_object(), choose_count_, + is_chosen_, std::move(used_sender), std::move(recent_choosers)); } bool operator==(const MessageReaction &lhs, const MessageReaction &rhs) { - return lhs.reaction_ == rhs.reaction_ && lhs.choose_count_ == rhs.choose_count_ && lhs.is_chosen_ == rhs.is_chosen_ && + return lhs.reaction_type_ == rhs.reaction_type_ && lhs.choose_count_ == rhs.choose_count_ && + lhs.is_chosen_ == rhs.is_chosen_ && lhs.my_recent_chooser_dialog_id_ == rhs.my_recent_chooser_dialog_id_ && lhs.recent_chooser_dialog_ids_ == rhs.recent_chooser_dialog_ids_; } StringBuilder &operator<<(StringBuilder &string_builder, const MessageReaction &reaction) { - string_builder << '[' << reaction.reaction_ << (reaction.is_chosen_ ? " X " : " x ") << reaction.choose_count_; + string_builder << '[' << reaction.reaction_type_ << (reaction.is_chosen_ ? " X " : " x ") << reaction.choose_count_; if (!reaction.recent_chooser_dialog_ids_.empty()) { string_builder << " by " << reaction.recent_chooser_dialog_ids_; + if (reaction.my_recent_chooser_dialog_id_.is_valid()) { + string_builder << " and my " << reaction.my_recent_chooser_dialog_id_; + } } return string_builder << ']'; } @@ -500,21 +566,26 @@ td_api::object_ptr UnreadMessageReaction::get_unread_rea if (sender_id == nullptr) { return nullptr; } - return td_api::make_object(get_reaction_type_object(reaction_), std::move(sender_id), + return td_api::make_object(reaction_type_.get_reaction_type_object(), std::move(sender_id), is_big_); } bool operator==(const UnreadMessageReaction &lhs, const UnreadMessageReaction &rhs) { - return lhs.reaction_ == rhs.reaction_ && lhs.sender_dialog_id_ == rhs.sender_dialog_id_ && lhs.is_big_ == rhs.is_big_; + return lhs.reaction_type_ == rhs.reaction_type_ && lhs.sender_dialog_id_ == rhs.sender_dialog_id_ && + lhs.is_big_ == rhs.is_big_; } StringBuilder &operator<<(StringBuilder &string_builder, const UnreadMessageReaction &unread_reaction) { - return string_builder << '[' << unread_reaction.reaction_ << (unread_reaction.is_big_ ? " BY " : " by ") + return string_builder << '[' << unread_reaction.reaction_type_ << (unread_reaction.is_big_ ? " BY " : " by ") << unread_reaction.sender_dialog_id_ << ']'; } +bool MessageReactions::are_empty() const { + return reactions_.empty() && pending_paid_reactions_ == 0; +} + unique_ptr MessageReactions::get_message_reactions( - Td *td, tl_object_ptr &&reactions, bool is_bot) { + Td *td, telegram_api::object_ptr &&reactions, bool is_bot) { if (reactions == nullptr || is_bot) { return nullptr; } @@ -522,48 +593,64 @@ unique_ptr MessageReactions::get_message_reactions( auto result = make_unique(); result->can_get_added_reactions_ = reactions->can_see_list_; result->is_min_ = reactions->min_; + result->are_tags_ = reactions->reactions_as_tags_; + + DialogId my_dialog_id; + for (auto &peer_reaction : reactions->recent_reactions_) { + if (peer_reaction->my_) { + DialogId dialog_id(peer_reaction->peer_id_); + if (!dialog_id.is_valid()) { + continue; + } + if (my_dialog_id.is_valid() && dialog_id != my_dialog_id) { + LOG(ERROR) << "Receive my reactions with " << dialog_id << " and " << my_dialog_id; + } + my_dialog_id = dialog_id; + } + } - FlatHashSet reaction_strings; - vector> chosen_reaction_order; + FlatHashSet reaction_types; + vector> chosen_reaction_order; for (auto &reaction_count : reactions->results_) { - auto reaction_str = get_message_reaction_string(reaction_count->reaction_); + auto reaction_type = ReactionType(reaction_count->reaction_); if (reaction_count->count_ <= 0 || reaction_count->count_ >= MessageReaction::MAX_CHOOSE_COUNT || - reaction_str.empty()) { - LOG(ERROR) << "Receive reaction " << reaction_str << " with invalid count " << reaction_count->count_; + reaction_type.is_empty()) { + LOG(ERROR) << "Receive " << reaction_type << " with invalid count " << reaction_count->count_; continue; } - if (!reaction_strings.insert(reaction_str).second) { - LOG(ERROR) << "Receive duplicate reaction " << reaction_str; + if (!reaction_types.insert(reaction_type).second) { + LOG(ERROR) << "Receive duplicate " << reaction_type; continue; } FlatHashSet recent_choosers; + DialogId my_recent_chooser_dialog_id; vector recent_chooser_dialog_ids; vector> recent_chooser_min_channels; for (auto &peer_reaction : reactions->recent_reactions_) { - auto peer_reaction_str = get_message_reaction_string(peer_reaction->reaction_); - if (peer_reaction_str == reaction_str) { + auto peer_reaction_type = ReactionType(peer_reaction->reaction_); + if (peer_reaction_type == reaction_type) { DialogId dialog_id(peer_reaction->peer_id_); if (!dialog_id.is_valid()) { - LOG(ERROR) << "Receive invalid " << dialog_id << " as a recent chooser for reaction " << reaction_str; + LOG(ERROR) << "Receive invalid " << dialog_id << " as a recent chooser for " << reaction_type; continue; } if (!recent_choosers.insert(dialog_id).second) { - LOG(ERROR) << "Receive duplicate " << dialog_id << " as a recent chooser for reaction " << reaction_str; + LOG(ERROR) << "Receive duplicate " << dialog_id << " as a recent chooser for " << reaction_type; continue; } - if (!td->messages_manager_->have_dialog_info(dialog_id)) { + if (!td->dialog_manager_->have_dialog_info(dialog_id)) { auto dialog_type = dialog_id.get_type(); if (dialog_type == DialogType::User) { auto user_id = dialog_id.get_user_id(); - if (!td->contacts_manager_->have_min_user(user_id)) { + if (!td->user_manager_->have_min_user(user_id)) { LOG(ERROR) << "Receive unknown " << user_id; continue; } } else if (dialog_type == DialogType::Channel) { auto channel_id = dialog_id.get_channel_id(); - auto min_channel = td->contacts_manager_->get_min_channel(channel_id); + auto min_channel = td->chat_manager_->get_min_channel(channel_id); if (min_channel == nullptr) { LOG(ERROR) << "Receive unknown reacted " << channel_id; continue; @@ -576,8 +663,11 @@ unique_ptr MessageReactions::get_message_reactions( } recent_chooser_dialog_ids.push_back(dialog_id); + if (dialog_id == my_dialog_id) { + my_recent_chooser_dialog_id = dialog_id; + } if (peer_reaction->unread_) { - result->unread_reactions_.emplace_back(std::move(peer_reaction_str), dialog_id, peer_reaction->big_); + result->unread_reactions_.emplace_back(std::move(peer_reaction_type), dialog_id, peer_reaction->big_); } if (recent_chooser_dialog_ids.size() == MessageReaction::MAX_RECENT_CHOOSERS) { break; @@ -587,87 +677,143 @@ unique_ptr MessageReactions::get_message_reactions( bool is_chosen = (reaction_count->flags_ & telegram_api::reactionCount::CHOSEN_ORDER_MASK) != 0; if (is_chosen) { - chosen_reaction_order.emplace_back(reaction_count->chosen_order_, reaction_str); + if (reaction_type == ReactionType::paid()) { + LOG_IF(ERROR, reaction_count->chosen_order_ != -1) + << "Receive paid reaction with order " << reaction_count->chosen_order_; + } else { + chosen_reaction_order.emplace_back(reaction_count->chosen_order_, reaction_type); + } } - result->reactions_.push_back({std::move(reaction_str), reaction_count->count_, is_chosen, - std::move(recent_chooser_dialog_ids), std::move(recent_chooser_min_channels)}); + result->reactions_.push_back({std::move(reaction_type), reaction_count->count_, is_chosen, + my_recent_chooser_dialog_id, std::move(recent_chooser_dialog_ids), + std::move(recent_chooser_min_channels)}); } if (chosen_reaction_order.size() > 1) { std::sort(chosen_reaction_order.begin(), chosen_reaction_order.end()); result->chosen_reaction_order_ = - transform(chosen_reaction_order, [](const std::pair &order) { return order.second; }); + transform(chosen_reaction_order, [](const std::pair &order) { return order.second; }); } + bool was_me = false; + for (auto &top_reactor : reactions->top_reactors_) { + MessageReactor reactor(std::move(top_reactor)); + if (!reactor.is_valid() || (reactions->min_ && reactor.is_me())) { + LOG(ERROR) << "Receive " << reactor; + continue; + } + if (reactor.is_me()) { + if (was_me) { + LOG(ERROR) << "Receive duplicate " << reactor; + continue; + } + was_me = true; + } + result->top_reactors_.push_back(std::move(reactor)); + } + MessageReactor::fix_message_reactors(result->top_reactors_, true); return result; } -MessageReaction *MessageReactions::get_reaction(const string &reaction) { +MessageReaction *MessageReactions::get_reaction(const ReactionType &reaction_type) { for (auto &added_reaction : reactions_) { - if (added_reaction.get_reaction() == reaction) { + if (added_reaction.get_reaction_type() == reaction_type) { return &added_reaction; } } return nullptr; } -const MessageReaction *MessageReactions::get_reaction(const string &reaction) const { - for (auto &added_reaction : reactions_) { - if (added_reaction.get_reaction() == reaction) { +const MessageReaction *MessageReactions::get_reaction(const ReactionType &reaction_type) const { + for (const auto &added_reaction : reactions_) { + if (added_reaction.get_reaction_type() == reaction_type) { return &added_reaction; } } return nullptr; } -void MessageReactions::update_from(const MessageReactions &old_reactions) { +void MessageReactions::update_from(const MessageReactions &old_reactions, DialogId my_dialog_id) { if (is_min_ && !old_reactions.is_min_) { - // chosen reaction was known, keep it + // chosen reactions were known, keep them is_min_ = false; + chosen_reaction_order_ = old_reactions.chosen_reaction_order_; for (const auto &old_reaction : old_reactions.reactions_) { if (old_reaction.is_chosen()) { - auto *reaction = get_reaction(old_reaction.get_reaction()); + auto *reaction = get_reaction(old_reaction.get_reaction_type()); if (reaction != nullptr) { - reaction->set_is_chosen(true, DialogId(), false); + reaction->update_from(old_reaction); } + } else { + td::remove(chosen_reaction_order_, old_reaction.get_reaction_type()); } } unread_reactions_ = old_reactions.unread_reactions_; - chosen_reaction_order_ = old_reactions.chosen_reaction_order_; + if (chosen_reaction_order_.size() == 1) { + reset_to_empty(chosen_reaction_order_); + } + + bool was_me = false; + for (auto &reactor : top_reactors_) { + if (reactor.fix_is_me(my_dialog_id)) { + was_me = true; + break; + } + } + if (!was_me) { + for (auto &reactor : old_reactions.top_reactors_) { + if (reactor.is_me()) { + // self paid reaction was known, keep it + top_reactors_.push_back(reactor); + MessageReactor::fix_message_reactors(top_reactors_, false); + } + } + } } for (const auto &old_reaction : old_reactions.reactions_) { if (old_reaction.is_chosen() && old_reaction.get_recent_chooser_dialog_ids().size() == MessageReaction::MAX_RECENT_CHOOSERS + 1) { - auto *reaction = get_reaction(old_reaction.get_reaction()); + auto *reaction = get_reaction(old_reaction.get_reaction_type()); if (reaction != nullptr && reaction->is_chosen()) { reaction->update_recent_chooser_dialog_ids(old_reaction); } } } + pending_paid_reactions_ = old_reactions.pending_paid_reactions_; + pending_use_default_is_anonymous_ = old_reactions.pending_use_default_is_anonymous_; + pending_is_anonymous_ = old_reactions.pending_is_anonymous_; } -bool MessageReactions::add_reaction(const string &reaction, bool is_big, DialogId chooser_dialog_id, - bool have_recent_choosers) { - vector new_chosen_reaction_order = get_chosen_reactions(); +bool MessageReactions::add_my_reaction(const ReactionType &reaction_type, bool is_big, DialogId my_dialog_id, + bool have_recent_choosers, bool is_tag) { + vector new_chosen_reaction_order = get_chosen_reaction_types(); - auto added_reaction = get_reaction(reaction); + auto added_reaction = get_reaction(reaction_type); if (added_reaction == nullptr) { vector recent_chooser_dialog_ids; + DialogId my_recent_chooser_dialog_id; if (have_recent_choosers) { - recent_chooser_dialog_ids.push_back(chooser_dialog_id); + recent_chooser_dialog_ids.push_back(my_dialog_id); + my_recent_chooser_dialog_id = my_dialog_id; } - reactions_.push_back({reaction, 1, true, std::move(recent_chooser_dialog_ids), Auto()}); - new_chosen_reaction_order.emplace_back(reaction); + reactions_.push_back( + {reaction_type, 1, true, my_recent_chooser_dialog_id, std::move(recent_chooser_dialog_ids), Auto()}); + new_chosen_reaction_order.emplace_back(reaction_type); } else if (!added_reaction->is_chosen()) { - added_reaction->set_is_chosen(true, chooser_dialog_id, have_recent_choosers); - new_chosen_reaction_order.emplace_back(reaction); + added_reaction->set_as_chosen(my_dialog_id, have_recent_choosers); + new_chosen_reaction_order.emplace_back(reaction_type); } else if (!is_big) { return false; } + if (!is_tag) { + CHECK(!are_tags_); + } else { + are_tags_ = true; + } auto max_reaction_count = get_max_reaction_count(); while (new_chosen_reaction_order.size() > max_reaction_count) { - auto index = new_chosen_reaction_order[0] == reaction ? 1 : 0; + auto index = new_chosen_reaction_order[0] == reaction_type ? 1 : 0; CHECK(static_cast(index) < new_chosen_reaction_order.size()); - bool is_removed = do_remove_reaction(new_chosen_reaction_order[index], chooser_dialog_id, have_recent_choosers); + bool is_removed = do_remove_my_reaction(new_chosen_reaction_order[index]); CHECK(is_removed); new_chosen_reaction_order.erase(new_chosen_reaction_order.begin() + index); } @@ -676,18 +822,24 @@ bool MessageReactions::add_reaction(const string &reaction, bool is_big, DialogI new_chosen_reaction_order.clear(); } chosen_reaction_order_ = std::move(new_chosen_reaction_order); + + for (auto &message_reaction : reactions_) { + message_reaction.set_my_recent_chooser_dialog_id(my_dialog_id); + } + return true; } -bool MessageReactions::remove_reaction(const string &reaction, DialogId chooser_dialog_id, bool have_recent_choosers) { - if (do_remove_reaction(reaction, chooser_dialog_id, have_recent_choosers)) { +bool MessageReactions::remove_my_reaction(const ReactionType &reaction_type, DialogId my_dialog_id) { + if (do_remove_my_reaction(reaction_type)) { if (!chosen_reaction_order_.empty()) { - bool is_removed = td::remove(chosen_reaction_order_, reaction); + bool is_removed = td::remove(chosen_reaction_order_, reaction_type); CHECK(is_removed); + // if the user isn't a Premium user, then max_reaction_count could be reduced from 3 to 1 auto max_reaction_count = get_max_reaction_count(); while (chosen_reaction_order_.size() > max_reaction_count) { - is_removed = do_remove_reaction(chosen_reaction_order_[0], chooser_dialog_id, have_recent_choosers); + is_removed = do_remove_my_reaction(chosen_reaction_order_[0]); CHECK(is_removed); chosen_reaction_order_.erase(chosen_reaction_order_.begin()); } @@ -697,18 +849,21 @@ bool MessageReactions::remove_reaction(const string &reaction, DialogId chooser_ } } + for (auto &message_reaction : reactions_) { + message_reaction.set_my_recent_chooser_dialog_id(my_dialog_id); + } + return true; } return false; } -bool MessageReactions::do_remove_reaction(const string &reaction, DialogId chooser_dialog_id, - bool have_recent_choosers) { +bool MessageReactions::do_remove_my_reaction(const ReactionType &reaction_type) { for (auto it = reactions_.begin(); it != reactions_.end(); ++it) { auto &message_reaction = *it; - if (message_reaction.get_reaction() == reaction) { + if (message_reaction.get_reaction_type() == reaction_type) { if (message_reaction.is_chosen()) { - message_reaction.set_is_chosen(false, chooser_dialog_id, have_recent_choosers); + message_reaction.unset_as_chosen(); if (message_reaction.is_empty()) { it = reactions_.erase(it); } @@ -720,58 +875,118 @@ bool MessageReactions::do_remove_reaction(const string &reaction, DialogId choos return false; } -void MessageReactions::sort_reactions(const FlatHashMap &active_reaction_pos) { +void MessageReactions::add_my_paid_reaction(Td *td, int32 star_count, bool use_default_is_anonymous, + bool is_anonymous) { + if (pending_paid_reactions_ > 1000000000 || star_count > 1000000000) { + LOG(ERROR) << "Pending paid reactions overflown"; + return; + } + td->star_manager_->add_pending_owned_star_count(-star_count, false); + if (use_default_is_anonymous) { + if (pending_paid_reactions_ == 0) { + pending_use_default_is_anonymous_ = true; + } + if (pending_use_default_is_anonymous_) { + bool was_me = false; + for (auto &reactor : top_reactors_) { + if (reactor.is_me()) { + was_me = true; + pending_is_anonymous_ = reactor.is_anonymous(); + } + } + if (!was_me) { + pending_is_anonymous_ = td->option_manager_->get_option_boolean("is_paid_reaction_anonymous"); + } + } + } else { + td->option_manager_->set_option_boolean("is_paid_reaction_anonymous", is_anonymous); + + pending_use_default_is_anonymous_ = false; + pending_is_anonymous_ = is_anonymous; + } + pending_paid_reactions_ += star_count; +} + +bool MessageReactions::has_pending_paid_reactions() const { + return pending_paid_reactions_ != 0; +} + +void MessageReactions::drop_pending_paid_reactions(Td *td) { + CHECK(has_pending_paid_reactions()); + td->star_manager_->add_pending_owned_star_count(pending_paid_reactions_, false); + pending_paid_reactions_ = 0; + pending_use_default_is_anonymous_ = false; + pending_is_anonymous_ = false; +} + +void MessageReactions::sort_reactions(const FlatHashMap &active_reaction_pos) { std::sort(reactions_.begin(), reactions_.end(), [&active_reaction_pos](const MessageReaction &lhs, const MessageReaction &rhs) { + if (lhs.get_reaction_type().is_paid_reaction() != rhs.get_reaction_type().is_paid_reaction()) { + return lhs.get_reaction_type().is_paid_reaction(); + } if (lhs.get_choose_count() != rhs.get_choose_count()) { return lhs.get_choose_count() > rhs.get_choose_count(); } - auto lhs_it = active_reaction_pos.find(lhs.get_reaction()); + auto lhs_it = active_reaction_pos.find(lhs.get_reaction_type()); auto lhs_pos = lhs_it != active_reaction_pos.end() ? lhs_it->second : active_reaction_pos.size(); - auto rhs_it = active_reaction_pos.find(rhs.get_reaction()); + auto rhs_it = active_reaction_pos.find(rhs.get_reaction_type()); auto rhs_pos = rhs_it != active_reaction_pos.end() ? rhs_it->second : active_reaction_pos.size(); if (lhs_pos != rhs_pos) { return lhs_pos < rhs_pos; } - return lhs.get_reaction() < rhs.get_reaction(); + return lhs.get_reaction_type() < rhs.get_reaction_type(); }); } -void MessageReactions::fix_chosen_reaction(DialogId my_dialog_id) { - bool need_fix = false; +void MessageReactions::fix_chosen_reaction() { + DialogId my_dialog_id; for (auto &reaction : reactions_) { - if (!reaction.is_chosen() && reaction.remove_recent_chooser_dialog_id(my_dialog_id)) { + if (!reaction.is_chosen() && reaction.get_my_recent_chooser_dialog_id().is_valid()) { + my_dialog_id = reaction.get_my_recent_chooser_dialog_id(); LOG(WARNING) << "Fix recent chosen reaction in " << *this; - need_fix = true; + reaction.remove_my_recent_chooser_dialog_id(); } } - if (!need_fix) { + if (!my_dialog_id.is_valid()) { return; } for (auto &reaction : reactions_) { - if (reaction.is_chosen() && !td::contains(reaction.get_recent_chooser_dialog_ids(), my_dialog_id)) { - reaction.add_recent_chooser_dialog_id(my_dialog_id); + if (!reaction.get_reaction_type().is_paid_reaction() && reaction.is_chosen() && + !reaction.get_my_recent_chooser_dialog_id().is_valid()) { + reaction.add_my_recent_chooser_dialog_id(my_dialog_id); + } + } +} + +void MessageReactions::fix_my_recent_chooser_dialog_id(DialogId my_dialog_id) { + for (auto &reaction : reactions_) { + if (!reaction.get_reaction_type().is_paid_reaction() && reaction.is_chosen() && + !reaction.get_my_recent_chooser_dialog_id().is_valid() && + td::contains(reaction.get_recent_chooser_dialog_ids(), my_dialog_id)) { + reaction.my_recent_chooser_dialog_id_ = my_dialog_id; } } } -vector MessageReactions::get_chosen_reactions() const { +vector MessageReactions::get_chosen_reaction_types() const { if (!chosen_reaction_order_.empty()) { return chosen_reaction_order_; } - vector reaction_order; - for (auto &reaction : reactions_) { - if (reaction.is_chosen()) { - reaction_order.push_back(reaction.get_reaction()); + vector reaction_order; + for (const auto &reaction : reactions_) { + if (!reaction.get_reaction_type().is_paid_reaction() && reaction.is_chosen()) { + reaction_order.push_back(reaction.get_reaction_type()); } } return reaction_order; } -bool MessageReactions::are_consistent_with_list(const string &reaction, FlatHashMap> reactions, - int32 total_count) const { +bool MessageReactions::are_consistent_with_list( + const ReactionType &reaction_type, FlatHashMap, ReactionTypeHash> reaction_types, + int32 total_count) const { auto are_consistent = [](const vector &lhs, const vector &rhs) { size_t i = 0; size_t max_i = td::min(lhs.size(), rhs.size()); @@ -781,43 +996,89 @@ bool MessageReactions::are_consistent_with_list(const string &reaction, FlatHash return i == max_i; }; - if (reaction.empty()) { + if (reaction_type.is_empty()) { // received list and total_count for all reactions int32 old_total_count = 0; for (const auto &message_reaction : reactions_) { - CHECK(!message_reaction.get_reaction().empty()); - if (!are_consistent(reactions[message_reaction.get_reaction()], + CHECK(!message_reaction.get_reaction_type().is_empty()); + if (!are_consistent(reaction_types[message_reaction.get_reaction_type()], message_reaction.get_recent_chooser_dialog_ids())) { return false; } old_total_count += message_reaction.get_choose_count(); - reactions.erase(message_reaction.get_reaction()); + reaction_types.erase(message_reaction.get_reaction_type()); } - return old_total_count == total_count && reactions.empty(); + return old_total_count == total_count && reaction_types.empty(); } // received list and total_count for a single reaction - const auto *message_reaction = get_reaction(reaction); + const auto *message_reaction = get_reaction(reaction_type); if (message_reaction == nullptr) { - return reactions.count(reaction) == 0 && total_count == 0; + return reaction_types.count(reaction_type) == 0 && total_count == 0; } else { - return are_consistent(reactions[reaction], message_reaction->get_recent_chooser_dialog_ids()) && + return are_consistent(reaction_types[reaction_type], message_reaction->get_recent_chooser_dialog_ids()) && message_reaction->get_choose_count() == total_count; } } -vector> MessageReactions::get_message_reactions_object( - Td *td, UserId my_user_id, UserId peer_user_id) const { - return transform(reactions_, [td, my_user_id, peer_user_id](const MessageReaction &reaction) { +vector MessageReactions::apply_reactor_pending_paid_reactions(DialogId my_dialog_id) const { + vector top_reactors; + bool was_me = false; + for (auto &reactor : top_reactors_) { + top_reactors.push_back(reactor); + if (reactor.is_me()) { + was_me = true; + top_reactors.back().add_count(pending_paid_reactions_, pending_is_anonymous_); + } + } + if (!was_me) { + top_reactors.emplace_back(my_dialog_id, pending_paid_reactions_, pending_is_anonymous_); + } + MessageReactor::fix_message_reactors(top_reactors, false); + return top_reactors; +} + +td_api::object_ptr MessageReactions::get_message_reactions_object(Td *td, UserId my_user_id, + UserId peer_user_id) const { + auto reactions = transform(reactions_, [td, my_user_id, peer_user_id](const MessageReaction &reaction) { return reaction.get_message_reaction_object(td, my_user_id, peer_user_id); }); + auto reactors = + transform(top_reactors_, [td](const MessageReactor &reactor) { return reactor.get_paid_reactor_object(td); }); + if (pending_paid_reactions_ > 0) { + if (reactions_.empty() || !reactions_[0].reaction_type_.is_paid_reaction()) { + reactions.insert(reactions.begin(), + MessageReaction(ReactionType::paid(), pending_paid_reactions_, true, DialogId(), Auto(), Auto()) + .get_message_reaction_object(td, my_user_id, peer_user_id)); + } else { + reactions[0]->total_count_ += pending_paid_reactions_; + reactions[0]->is_chosen_ = true; + } + + // my_user_id == UserId() + auto top_reactors = apply_reactor_pending_paid_reactions(td->dialog_manager_->get_my_dialog_id()); + reactors = + transform(top_reactors, [td](const MessageReactor &reactor) { return reactor.get_paid_reactor_object(td); }); + } + return td_api::make_object(std::move(reactions), are_tags_, std::move(reactors), + can_get_added_reactions_); +} + +int32 MessageReactions::get_non_paid_reaction_count() const { + int32 result = 0; + for (const auto &reaction : reactions_) { + if (!reaction.reaction_type_.is_paid_reaction()) { + result++; + } + } + return result; } void MessageReactions::add_min_channels(Td *td) const { for (const auto &reaction : reactions_) { for (const auto &recent_chooser_min_channel : reaction.get_recent_chooser_min_channels()) { LOG(INFO) << "Add min reacted " << recent_chooser_min_channel.first; - td->contacts_manager_->add_min_channel(recent_chooser_min_channel.first, recent_chooser_min_channel.second); + td->chat_manager_->add_min_channel(recent_chooser_min_channel.first, recent_chooser_min_channel.second); } } } @@ -829,6 +1090,9 @@ void MessageReactions::add_dependencies(Dependencies &dependencies) const { dependencies.add_message_sender_dependencies(dialog_id); } } + for (const auto &reactor : top_reactors_) { + reactor.add_dependencies(dependencies); + } } bool MessageReactions::need_update_message_reactions(const MessageReactions *old_reactions, @@ -845,7 +1109,9 @@ bool MessageReactions::need_update_message_reactions(const MessageReactions *old // unread_reactions_ and chosen_reaction_order_ are updated independently; compare all other fields return old_reactions->reactions_ != new_reactions->reactions_ || old_reactions->is_min_ != new_reactions->is_min_ || old_reactions->can_get_added_reactions_ != new_reactions->can_get_added_reactions_ || - old_reactions->need_polling_ != new_reactions->need_polling_; + old_reactions->need_polling_ != new_reactions->need_polling_ || + old_reactions->are_tags_ != new_reactions->are_tags_ || + old_reactions->top_reactors_ != new_reactions->top_reactors_; } bool MessageReactions::need_update_unread_reactions(const MessageReactions *old_reactions, @@ -856,11 +1122,59 @@ bool MessageReactions::need_update_unread_reactions(const MessageReactions *old_ return new_reactions == nullptr || old_reactions->unread_reactions_ != new_reactions->unread_reactions_; } +void MessageReactions::send_paid_message_reaction(Td *td, MessageFullId message_full_id, int64 random_id, + Promise &&promise) { + CHECK(has_pending_paid_reactions()); + auto star_count = pending_paid_reactions_; + auto use_default_is_anonymous = pending_use_default_is_anonymous_; + auto is_anonymous = pending_is_anonymous_; + top_reactors_ = apply_reactor_pending_paid_reactions(td->dialog_manager_->get_my_dialog_id()); + if (reactions_.empty() || !reactions_[0].reaction_type_.is_paid_reaction()) { + reactions_.insert(reactions_.begin(), + MessageReaction(ReactionType::paid(), star_count, true, DialogId(), Auto(), Auto())); + } else { + reactions_[0].add_paid_reaction(star_count); + } + pending_paid_reactions_ = 0; + pending_use_default_is_anonymous_ = false; + pending_is_anonymous_ = false; + + td->create_handler(std::move(promise)) + ->send(message_full_id, star_count, use_default_is_anonymous, is_anonymous, random_id); +} + +bool MessageReactions::toggle_paid_message_reaction_is_anonymous(Td *td, MessageFullId message_full_id, + bool is_anonymous, Promise &&promise) { + if (pending_paid_reactions_ != 0) { + pending_use_default_is_anonymous_ = false; + pending_is_anonymous_ = is_anonymous; + } + for (auto &top_reactor : top_reactors_) { + if (top_reactor.is_me()) { + top_reactor.add_count(0, is_anonymous); + td->create_handler(std::move(promise))->send(message_full_id, is_anonymous); + return true; + } + } + if (pending_paid_reactions_ != 0) { + promise.set_value(Unit()); + return true; + } + promise.set_error(Status::Error(400, "Message has no paid reaction")); + return false; +} + StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactions &reactions) { + if (reactions.are_tags_) { + return string_builder << "MessageTags{" << reactions.reactions_ << '}'; + } return string_builder << (reactions.is_min_ ? "Min" : "") << "MessageReactions{" << reactions.reactions_ << " with unread " << reactions.unread_reactions_ << ", reaction order " << reactions.chosen_reaction_order_ - << " and can_get_added_reactions = " << reactions.can_get_added_reactions_; + << " and can_get_added_reactions = " << reactions.can_get_added_reactions_ + << " with paid reactions by " << reactions.top_reactors_ << " and " + << reactions.pending_paid_reactions_ << (reactions.pending_is_anonymous_ ? "anonymous " : "") + << " pending paid reactions}"; } StringBuilder &operator<<(StringBuilder &string_builder, const unique_ptr &reactions) { @@ -870,17 +1184,14 @@ StringBuilder &operator<<(StringBuilder &string_builder, const unique_ptr &active_reaction_pos) { - return !reaction.empty() && (is_custom_reaction(reaction) || active_reaction_pos.count(reaction) > 0); -} - void reload_message_reactions(Td *td, DialogId dialog_id, vector &&message_ids) { - if (!td->messages_manager_->have_input_peer(dialog_id, AccessRights::Read) || - dialog_id.get_type() == DialogType::SecretChat || message_ids.empty()) { + if (!td->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read) || message_ids.empty()) { + create_actor( + "RetryReloadMessageReactionsActor", 0.2, + PromiseCreator::lambda([actor_id = G()->messages_manager(), dialog_id](Result result) mutable { + send_closure(actor_id, &MessagesManager::try_reload_message_reactions, dialog_id, true); + })) + .release(); return; } @@ -892,20 +1203,40 @@ void reload_message_reactions(Td *td, DialogId dialog_id, vector &&me td->create_handler()->send(dialog_id, std::move(message_ids)); } -void send_message_reaction(Td *td, FullMessageId full_message_id, vector reactions, bool is_big, +void send_message_reaction(Td *td, MessageFullId message_full_id, vector reaction_types, bool is_big, bool add_to_recent, Promise &&promise) { td->create_handler(std::move(promise)) - ->send(full_message_id, std::move(reactions), is_big, add_to_recent); + ->send(message_full_id, std::move(reaction_types), is_big, add_to_recent); } -void get_message_added_reactions(Td *td, FullMessageId full_message_id, string reaction, string offset, int32 limit, - Promise> &&promise) { - if (!td->messages_manager_->have_message_force(full_message_id, "get_message_added_reactions")) { +void set_message_reactions(Td *td, MessageFullId message_full_id, vector reaction_types, bool is_big, + Promise &&promise) { + if (!td->messages_manager_->have_message_force(message_full_id, "set_message_reactions")) { return promise.set_error(Status::Error(400, "Message not found")); } + for (const auto &reaction_type : reaction_types) { + if (reaction_type.is_empty() || reaction_type.is_paid_reaction()) { + return promise.set_error(Status::Error(400, "Invalid reaction type specified")); + } + } + send_message_reaction(td, message_full_id, std::move(reaction_types), is_big, false, std::move(promise)); +} - auto message_id = full_message_id.get_message_id(); - if (full_message_id.get_dialog_id().get_type() == DialogType::SecretChat || !message_id.is_valid() || +void reload_paid_reaction_privacy(Td *td) { + td->create_handler()->send(); +} + +void get_message_added_reactions(Td *td, MessageFullId message_full_id, ReactionType reaction_type, string offset, + int32 limit, Promise> &&promise) { + if (!td->messages_manager_->have_message_force(message_full_id, "get_message_added_reactions")) { + return promise.set_error(Status::Error(400, "Message not found")); + } + if (reaction_type.is_paid_reaction()) { + return promise.set_error(Status::Error(400, "Can't use the method for paid reaction")); + } + + auto message_id = message_full_id.get_message_id(); + if (message_full_id.get_dialog_id().get_type() == DialogType::SecretChat || !message_id.is_valid() || !message_id.is_server()) { return promise.set_value(td_api::make_object(0, Auto(), string())); } @@ -919,55 +1250,19 @@ void get_message_added_reactions(Td *td, FullMessageId full_message_id, string r } td->create_handler(std::move(promise)) - ->send(full_message_id, std::move(reaction), std::move(offset), limit); -} - -void set_default_reaction(Td *td, string reaction, Promise &&promise) { - if (reaction.empty()) { - return promise.set_error(Status::Error(400, "Default reaction must be non-empty")); - } - if (!is_custom_reaction(reaction) && !td->stickers_manager_->is_active_reaction(reaction)) { - return promise.set_error(Status::Error(400, "Can't set incative reaction as default")); - } - - if (td->option_manager_->get_option_string("default_reaction", "-") != reaction) { - td->option_manager_->set_option_string("default_reaction", reaction); - if (!td->option_manager_->get_option_boolean("default_reaction_needs_sync")) { - td->option_manager_->set_option_boolean("default_reaction_needs_sync", true); - send_set_default_reaction_query(td); - } - } - promise.set_value(Unit()); -} - -void send_set_default_reaction_query(Td *td) { - td->create_handler()->send(td->option_manager_->get_option_string("default_reaction")); + ->send(message_full_id, std::move(reaction_type), std::move(offset), limit); } -td_api::object_ptr get_update_default_reaction_type(const string &default_reaction) { - if (default_reaction.empty()) { - return nullptr; - } - return td_api::make_object(get_reaction_type_object(default_reaction)); -} - -void report_message_reactions(Td *td, FullMessageId full_message_id, DialogId chooser_dialog_id, +void report_message_reactions(Td *td, MessageFullId message_full_id, DialogId chooser_dialog_id, Promise &&promise) { - auto dialog_id = full_message_id.get_dialog_id(); - if (!td->messages_manager_->have_dialog_force(dialog_id, "send_callback_query")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!td->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - if (dialog_id.get_type() == DialogType::SecretChat) { - return promise.set_error(Status::Error(400, "Reactions can't be reported in the chat")); - } + auto dialog_id = message_full_id.get_dialog_id(); + TRY_STATUS_PROMISE(promise, td->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Read, + "report_message_reactions")); - if (!td->messages_manager_->have_message_force(full_message_id, "report_user_reactions")) { + if (!td->messages_manager_->have_message_force(message_full_id, "report_message_reactions")) { return promise.set_error(Status::Error(400, "Message not found")); } - auto message_id = full_message_id.get_message_id(); + auto message_id = message_full_id.get_message_id(); if (message_id.is_valid_scheduled()) { return promise.set_error(Status::Error(400, "Can't report reactions on scheduled messages")); } @@ -975,45 +1270,18 @@ void report_message_reactions(Td *td, FullMessageId full_message_id, DialogId ch return promise.set_error(Status::Error(400, "Message reactions can't be reported")); } - if (!td->messages_manager_->have_input_peer(chooser_dialog_id, AccessRights::Know)) { + if (!td->dialog_manager_->have_input_peer(chooser_dialog_id, false, AccessRights::Know)) { return promise.set_error(Status::Error(400, "Reaction sender not found")); } td->create_handler(std::move(promise))->send(dialog_id, message_id, chooser_dialog_id); } -vector get_recent_reactions(Td *td) { - return td->stickers_manager_->get_recent_reactions(); -} - -vector get_top_reactions(Td *td) { - return td->stickers_manager_->get_top_reactions(); -} - -void add_recent_reaction(Td *td, const string &reaction) { - td->stickers_manager_->add_recent_reaction(reaction); -} - -int64 get_reactions_hash(const vector &reactions) { - vector numbers; - for (auto &reaction : reactions) { - if (is_custom_reaction(reaction)) { - auto custom_emoji_id = static_cast(get_custom_emoji_id(reaction)); - numbers.push_back(custom_emoji_id >> 32); - numbers.push_back(custom_emoji_id & 0xFFFFFFFF); - } else { - auto emoji = remove_emoji_selectors(reaction); - unsigned char hash[16]; - md5(emoji, {hash, sizeof(hash)}); - auto get = [hash](int num) { - return static_cast(hash[num]); - }; - - numbers.push_back(0); - numbers.push_back(static_cast((get(0) << 24) + (get(1) << 16) + (get(2) << 8) + get(3))); - } +vector get_chosen_tags(const unique_ptr &message_reactions) { + if (message_reactions == nullptr || !message_reactions->are_tags_) { + return {}; } - return get_vector_hash(numbers); + return message_reactions->get_chosen_reaction_types(); } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.h b/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.h index caad4b65bf..854ecc18e3 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,9 +8,11 @@ #include "td/telegram/ChannelId.h" #include "td/telegram/DialogId.h" -#include "td/telegram/FullMessageId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/MessageId.h" +#include "td/telegram/MessageReactor.h" #include "td/telegram/MinChannel.h" +#include "td/telegram/ReactionType.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" @@ -33,9 +35,10 @@ class MessageReaction { static constexpr size_t MAX_RECENT_CHOOSERS = 3; - string reaction_; + ReactionType reaction_type_; int32 choose_count_ = 0; bool is_chosen_ = false; + DialogId my_recent_chooser_dialog_id_; vector recent_chooser_dialog_ids_; vector> recent_chooser_min_channels_; @@ -45,14 +48,9 @@ class MessageReaction { friend struct MessageReactions; - MessageReaction(string reaction, int32 choose_count, bool is_chosen, vector &&recent_chooser_dialog_ids, - vector> &&recent_chooser_min_channels) - : reaction_(std::move(reaction)) - , choose_count_(choose_count) - , is_chosen_(is_chosen) - , recent_chooser_dialog_ids_(std::move(recent_chooser_dialog_ids)) - , recent_chooser_min_channels_(std::move(recent_chooser_min_channels)) { - } + MessageReaction(ReactionType reaction_type, int32 choose_count, bool is_chosen, DialogId my_recent_chooser_dialog_id, + vector &&recent_chooser_dialog_ids, + vector> &&recent_chooser_min_channels); bool is_empty() const { return choose_count_ <= 0; @@ -62,11 +60,17 @@ class MessageReaction { return is_chosen_; } - void set_is_chosen(bool is_chosen, DialogId chooser_dialog_id, bool have_recent_choosers); + void set_as_chosen(DialogId my_dialog_id, bool have_recent_choosers); + + void unset_as_chosen(); + + void add_paid_reaction(int32 star_count); + + void add_my_recent_chooser_dialog_id(DialogId dialog_id); - void add_recent_chooser_dialog_id(DialogId dialog_id); + bool remove_my_recent_chooser_dialog_id(); - bool remove_recent_chooser_dialog_id(DialogId dialog_id); + void update_from(const MessageReaction &old_reaction); void update_recent_chooser_dialog_ids(const MessageReaction &old_reaction); @@ -74,6 +78,14 @@ class MessageReaction { return choose_count_; } + void fix_choose_count(); + + void set_my_recent_chooser_dialog_id(DialogId my_dialog_id); + + DialogId get_my_recent_chooser_dialog_id() const { + return my_recent_chooser_dialog_id_; + } + const vector &get_recent_chooser_dialog_ids() const { return recent_chooser_dialog_ids_; } @@ -88,8 +100,8 @@ class MessageReaction { public: MessageReaction() = default; - const string &get_reaction() const { - return reaction_; + const ReactionType &get_reaction_type() const { + return reaction_type_; } template @@ -108,7 +120,7 @@ inline bool operator!=(const MessageReaction &lhs, const MessageReaction &rhs) { StringBuilder &operator<<(StringBuilder &string_builder, const MessageReaction &reaction); class UnreadMessageReaction { - string reaction_; + ReactionType reaction_type_; DialogId sender_dialog_id_; bool is_big_ = false; @@ -119,8 +131,8 @@ class UnreadMessageReaction { public: UnreadMessageReaction() = default; - UnreadMessageReaction(string reaction, DialogId sender_dialog_id, bool is_big) - : reaction_(std::move(reaction)), sender_dialog_id_(sender_dialog_id), is_big_(is_big) { + UnreadMessageReaction(ReactionType reaction_type, DialogId sender_dialog_id, bool is_big) + : reaction_type_(std::move(reaction_type)), sender_dialog_id_(sender_dialog_id), is_big_(is_big) { } td_api::object_ptr get_unread_reaction_object(Td *td) const; @@ -143,38 +155,56 @@ StringBuilder &operator<<(StringBuilder &string_builder, const UnreadMessageReac struct MessageReactions { vector reactions_; vector unread_reactions_; - vector chosen_reaction_order_; + vector chosen_reaction_order_; + vector top_reactors_; + int32 pending_paid_reactions_ = 0; + bool pending_use_default_is_anonymous_ = false; + bool pending_is_anonymous_ = false; bool is_min_ = false; bool need_polling_ = true; bool can_get_added_reactions_ = false; + bool are_tags_ = false; MessageReactions() = default; - static unique_ptr get_message_reactions(Td *td, - tl_object_ptr &&reactions, - bool is_bot); + bool are_empty() const; + + static unique_ptr get_message_reactions( + Td *td, telegram_api::object_ptr &&reactions, bool is_bot); + + MessageReaction *get_reaction(const ReactionType &reaction_type); + + const MessageReaction *get_reaction(const ReactionType &reaction_type) const; - MessageReaction *get_reaction(const string &reaction); + void update_from(const MessageReactions &old_reactions, DialogId my_dialog_id); - const MessageReaction *get_reaction(const string &reaction) const; + bool add_my_reaction(const ReactionType &reaction_type, bool is_big, DialogId my_dialog_id, bool have_recent_choosers, + bool is_tag); - void update_from(const MessageReactions &old_reactions); + bool remove_my_reaction(const ReactionType &reaction_type, DialogId my_dialog_id); - bool add_reaction(const string &reaction, bool is_big, DialogId chooser_dialog_id, bool have_recent_choosers); + void add_my_paid_reaction(Td *td, int32 star_count, bool use_default_is_anonymous, bool is_anonymous); - bool remove_reaction(const string &reaction, DialogId chooser_dialog_id, bool have_recent_choosers); + bool has_pending_paid_reactions() const; - void sort_reactions(const FlatHashMap &active_reaction_pos); + void drop_pending_paid_reactions(Td *td); - void fix_chosen_reaction(DialogId my_dialog_id); + void sort_reactions(const FlatHashMap &active_reaction_pos); - vector get_chosen_reactions() const; + void fix_chosen_reaction(); - bool are_consistent_with_list(const string &reaction, FlatHashMap> reactions, + void fix_my_recent_chooser_dialog_id(DialogId my_dialog_id); + + vector get_chosen_reaction_types() const; + + bool are_consistent_with_list(const ReactionType &reaction_type, + FlatHashMap, ReactionTypeHash> reaction_types, int32 total_count) const; - vector> get_message_reactions_object(Td *td, UserId my_user_id, - UserId peer_user_id) const; + td_api::object_ptr get_message_reactions_object(Td *td, UserId my_user_id, + UserId peer_user_id) const; + + int32 get_non_paid_reaction_count() const; void add_min_channels(Td *td) const; @@ -186,6 +216,11 @@ struct MessageReactions { static bool need_update_unread_reactions(const MessageReactions *old_reactions, const MessageReactions *new_reactions); + void send_paid_message_reaction(Td *td, MessageFullId message_full_id, int64 random_id, Promise &&promise); + + bool toggle_paid_message_reaction_is_anonymous(Td *td, MessageFullId message_full_id, bool is_anonymous, + Promise &&promise); + template void store(StorerT &storer) const; @@ -193,48 +228,31 @@ struct MessageReactions { void parse(ParserT &parser); private: - bool do_remove_reaction(const string &reaction, DialogId chooser_dialog_id, bool have_recent_choosers); + bool do_remove_my_reaction(const ReactionType &reaction_type); + + vector apply_reactor_pending_paid_reactions(DialogId my_dialog_id) const; }; StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactions &reactions); StringBuilder &operator<<(StringBuilder &string_builder, const unique_ptr &reactions); -telegram_api::object_ptr get_input_reaction(const string &reaction); - -td_api::object_ptr get_reaction_type_object(const string &reaction); - -string get_message_reaction_string(const telegram_api::object_ptr &reaction); - -string get_message_reaction_string(const td_api::object_ptr &type); - -bool is_custom_reaction(const string &reaction); - -bool is_active_reaction(const string &reaction, const FlatHashMap &active_reaction_pos); - void reload_message_reactions(Td *td, DialogId dialog_id, vector &&message_ids); -void send_message_reaction(Td *td, FullMessageId full_message_id, vector reactions, bool is_big, +void send_message_reaction(Td *td, MessageFullId message_full_id, vector reaction_types, bool is_big, bool add_to_recent, Promise &&promise); -void get_message_added_reactions(Td *td, FullMessageId full_message_id, string reaction, string offset, int32 limit, - Promise> &&promise); - -void set_default_reaction(Td *td, string reaction, Promise &&promise); +void set_message_reactions(Td *td, MessageFullId message_full_id, vector reaction_types, bool is_big, + Promise &&promise); -void send_set_default_reaction_query(Td *td); +void reload_paid_reaction_privacy(Td *td); -td_api::object_ptr get_update_default_reaction_type(const string &default_reaction); +void get_message_added_reactions(Td *td, MessageFullId message_full_id, ReactionType reaction_type, string offset, + int32 limit, Promise> &&promise); -void report_message_reactions(Td *td, FullMessageId full_message_id, DialogId chooser_dialog_id, +void report_message_reactions(Td *td, MessageFullId message_full_id, DialogId chooser_dialog_id, Promise &&promise); -vector get_recent_reactions(Td *td); - -vector get_top_reactions(Td *td); - -void add_recent_reaction(Td *td, const string &reaction); - -int64 get_reactions_hash(const vector &reactions); +vector get_chosen_tags(const unique_ptr &message_reactions); } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.hpp b/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.hpp index 6fda93ccb6..588a254068 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReaction.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,6 +8,11 @@ #include "td/telegram/MessageReaction.h" +#include "td/telegram/MessageReactor.hpp" +#include "td/telegram/MinChannel.hpp" +#include "td/telegram/ReactionType.hpp" + +#include "td/utils/algorithm.h" #include "td/utils/common.h" #include "td/utils/tl_helpers.h" @@ -18,12 +23,14 @@ void MessageReaction::store(StorerT &storer) const { CHECK(!is_empty()); bool has_recent_chooser_dialog_ids = !recent_chooser_dialog_ids_.empty(); bool has_recent_chooser_min_channels = !recent_chooser_min_channels_.empty(); + bool has_my_recent_chooser_dialog_id = my_recent_chooser_dialog_id_.is_valid(); BEGIN_STORE_FLAGS(); STORE_FLAG(is_chosen_); STORE_FLAG(has_recent_chooser_dialog_ids); STORE_FLAG(has_recent_chooser_min_channels); + STORE_FLAG(has_my_recent_chooser_dialog_id); END_STORE_FLAGS(); - td::store(reaction_, storer); + td::store(reaction_type_, storer); td::store(choose_count_, storer); if (has_recent_chooser_dialog_ids) { td::store(recent_chooser_dialog_ids_, storer); @@ -31,18 +38,23 @@ void MessageReaction::store(StorerT &storer) const { if (has_recent_chooser_min_channels) { td::store(recent_chooser_min_channels_, storer); } + if (has_my_recent_chooser_dialog_id) { + td::store(my_recent_chooser_dialog_id_, storer); + } } template void MessageReaction::parse(ParserT &parser) { bool has_recent_chooser_dialog_ids; bool has_recent_chooser_min_channels; + bool has_my_recent_chooser_dialog_id; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_chosen_); PARSE_FLAG(has_recent_chooser_dialog_ids); PARSE_FLAG(has_recent_chooser_min_channels); + PARSE_FLAG(has_my_recent_chooser_dialog_id); END_PARSE_FLAGS(); - td::parse(reaction_, parser); + td::parse(reaction_type_, parser); td::parse(choose_count_, parser); if (has_recent_chooser_dialog_ids) { td::parse(recent_chooser_dialog_ids_, parser); @@ -50,8 +62,18 @@ void MessageReaction::parse(ParserT &parser) { if (has_recent_chooser_min_channels) { td::parse(recent_chooser_min_channels_, parser); } - CHECK(!is_empty()); - CHECK(!reaction_.empty()); + if (has_my_recent_chooser_dialog_id) { + td::parse(my_recent_chooser_dialog_id_, parser); + if (!my_recent_chooser_dialog_id_.is_valid() || + !td::contains(recent_chooser_dialog_ids_, my_recent_chooser_dialog_id_)) { + return parser.set_error("Invalid recent reaction chooser"); + } + } + fix_choose_count(); + + if (is_empty() || reaction_type_.is_empty()) { + parser.set_error("Invalid message reaction"); + } } template @@ -59,7 +81,7 @@ void UnreadMessageReaction::store(StorerT &storer) const { BEGIN_STORE_FLAGS(); STORE_FLAG(is_big_); END_STORE_FLAGS(); - td::store(reaction_, storer); + td::store(reaction_type_, storer); td::store(sender_dialog_id_, storer); } @@ -68,9 +90,11 @@ void UnreadMessageReaction::parse(ParserT &parser) { BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_big_); END_PARSE_FLAGS(); - td::parse(reaction_, parser); + td::parse(reaction_type_, parser); td::parse(sender_dialog_id_, parser); - CHECK(!reaction_.empty()); + if (reaction_type_.is_empty()) { + parser.set_error("Invalid unread message reaction"); + } } template @@ -78,6 +102,7 @@ void MessageReactions::store(StorerT &storer) const { bool has_reactions = !reactions_.empty(); bool has_unread_reactions = !unread_reactions_.empty(); bool has_chosen_reaction_order = !chosen_reaction_order_.empty(); + bool has_top_reactors = !top_reactors_.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(is_min_); STORE_FLAG(need_polling_); @@ -85,6 +110,8 @@ void MessageReactions::store(StorerT &storer) const { STORE_FLAG(has_unread_reactions); STORE_FLAG(has_reactions); STORE_FLAG(has_chosen_reaction_order); + STORE_FLAG(are_tags_); + STORE_FLAG(has_top_reactors); END_STORE_FLAGS(); if (has_reactions) { td::store(reactions_, storer); @@ -95,6 +122,9 @@ void MessageReactions::store(StorerT &storer) const { if (has_chosen_reaction_order) { td::store(chosen_reaction_order_, storer); } + if (has_top_reactors) { + td::store(top_reactors_, storer); + } } template @@ -102,6 +132,7 @@ void MessageReactions::parse(ParserT &parser) { bool has_reactions; bool has_unread_reactions; bool has_chosen_reaction_order; + bool has_top_reactors; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_min_); PARSE_FLAG(need_polling_); @@ -109,6 +140,8 @@ void MessageReactions::parse(ParserT &parser) { PARSE_FLAG(has_unread_reactions); PARSE_FLAG(has_reactions); PARSE_FLAG(has_chosen_reaction_order); + PARSE_FLAG(are_tags_); + PARSE_FLAG(has_top_reactors); END_PARSE_FLAGS(); if (has_reactions) { td::parse(reactions_, parser); @@ -119,6 +152,9 @@ void MessageReactions::parse(ParserT &parser) { if (has_chosen_reaction_order) { td::parse(chosen_reaction_order_, parser); } + if (has_top_reactors) { + td::parse(top_reactors_, parser); + } } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.cpp new file mode 100644 index 0000000000..b79c7727ae --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.cpp @@ -0,0 +1,102 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageReactor.h" + +#include "td/telegram/Dependencies.h" +#include "td/telegram/MessageSender.h" + +#include "td/utils/logging.h" + +#include + +namespace td { + +MessageReactor::MessageReactor(telegram_api::object_ptr &&reactor) + : dialog_id_(reactor->peer_id_ == nullptr ? DialogId() : DialogId(reactor->peer_id_)) + , count_(reactor->count_) + , is_top_(reactor->top_) + , is_me_(reactor->my_) + , is_anonymous_(reactor->anonymous_) { +} + +td_api::object_ptr MessageReactor::get_paid_reactor_object(Td *td) const { + return td_api::make_object( + dialog_id_ == DialogId() ? nullptr : get_message_sender_object(td, dialog_id_, "paidReactor"), count_, is_top_, + is_me_, is_anonymous_); +} + +void MessageReactor::add_dependencies(Dependencies &dependencies) const { + dependencies.add_message_sender_dependencies(dialog_id_); +} + +bool MessageReactor::fix_is_me(DialogId my_dialog_id) { + if (dialog_id_ == my_dialog_id) { + is_me_ = true; + return true; + } + return false; +} + +void MessageReactor::fix_message_reactors(vector &reactors, bool need_warning) { + size_t TOP_REACTOR_COUNT = 3u; + if (reactors.size() > TOP_REACTOR_COUNT + 1) { + LOG(ERROR) << "Have too many " << reactors; + reactors.resize(TOP_REACTOR_COUNT + 1); + } + if (reactors.size() > TOP_REACTOR_COUNT && !reactors[TOP_REACTOR_COUNT].is_me()) { + LOG(ERROR) << "Receive unexpected " << reactors; + reactors.resize(TOP_REACTOR_COUNT); + } + if (need_warning) { + for (size_t i = 0; i < reactors.size(); i++) { + if (reactors[i].is_top_ != (i < TOP_REACTOR_COUNT)) { + LOG(ERROR) << "Receive incorrect top " << reactors; + break; + } + } + for (size_t i = 0; i + 1 < reactors.size(); i++) { + if (reactors[i].count_ < reactors[i + 1].count_) { + LOG(ERROR) << "Receive unordered " << reactors; + break; + } + } + } + bool was_me = false; + for (const auto &reactor : reactors) { + CHECK(reactor.is_valid()); + if (reactor.is_me()) { + CHECK(!was_me); + was_me = true; + } + } + std::sort(reactors.begin(), reactors.end()); + if (reactors.size() > TOP_REACTOR_COUNT && !reactors[TOP_REACTOR_COUNT].is_me()) { + reactors.resize(TOP_REACTOR_COUNT); + } + for (size_t i = 0; i < reactors.size(); i++) { + reactors[i].is_top_ = (i < TOP_REACTOR_COUNT); + } +} + +bool operator<(const MessageReactor &lhs, const MessageReactor &rhs) { + if (lhs.count_ != rhs.count_) { + return lhs.count_ > rhs.count_; + } + return lhs.dialog_id_.get() < rhs.dialog_id_.get(); +} + +bool operator==(const MessageReactor &lhs, const MessageReactor &rhs) { + return lhs.dialog_id_ == rhs.dialog_id_ && lhs.count_ == rhs.count_ && lhs.is_top_ == rhs.is_top_ && + lhs.is_me_ == rhs.is_me_ && lhs.is_anonymous_ == rhs.is_anonymous_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactor &reactor) { + return string_builder << "PaidReactor[" << reactor.dialog_id_ << " - " << reactor.count_ + << (reactor.is_me_ ? " by me" : "") << ']'; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.h b/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.h new file mode 100644 index 0000000000..a92865f3d2 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.h @@ -0,0 +1,86 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Dependencies; + +class Td; + +class MessageReactor { + DialogId dialog_id_; + int32 count_ = 0; + bool is_top_ = false; + bool is_me_ = false; + bool is_anonymous_ = false; + + friend bool operator<(const MessageReactor &lhs, const MessageReactor &rhs); + + friend bool operator==(const MessageReactor &lhs, const MessageReactor &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactor &reactor); + + public: + MessageReactor() = default; + + explicit MessageReactor(telegram_api::object_ptr &&reactor); + + MessageReactor(DialogId dialog_id, int32 count, bool is_anonymous) + : dialog_id_(dialog_id), count_(count), is_me_(true), is_anonymous_(is_anonymous) { + } + + bool is_valid() const { + return count_ > 0 && (is_me_ ? dialog_id_.is_valid() : (dialog_id_.is_valid() || is_anonymous_) && is_top_); + } + + bool is_me() const { + return is_me_; + } + + bool is_anonymous() const { + return is_anonymous_; + } + + bool fix_is_me(DialogId my_dialog_id); + + void add_count(int32 count, bool is_anonymous) { + count_ += count; + is_anonymous_ = is_anonymous; + } + + td_api::object_ptr get_paid_reactor_object(Td *td) const; + + void add_dependencies(Dependencies &dependencies) const; + + static void fix_message_reactors(vector &reactors, bool need_warning); + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator<(const MessageReactor &lhs, const MessageReactor &rhs); + +bool operator==(const MessageReactor &lhs, const MessageReactor &rhs); + +inline bool operator!=(const MessageReactor &lhs, const MessageReactor &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageReactor &reactor); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.hpp b/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.hpp new file mode 100644 index 0000000000..d50f21ba9d --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReactor.hpp @@ -0,0 +1,46 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageReactor.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void MessageReactor::store(StorerT &storer) const { + bool has_dialog_id = dialog_id_.is_valid(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_top_); + STORE_FLAG(is_me_); + STORE_FLAG(is_anonymous_); + STORE_FLAG(has_dialog_id); + END_STORE_FLAGS(); + if (has_dialog_id) { + td::store(dialog_id_, storer); + } + td::store(count_, storer); +} + +template +void MessageReactor::parse(ParserT &parser) { + bool has_dialog_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_top_); + PARSE_FLAG(is_me_); + PARSE_FLAG(is_anonymous_); + PARSE_FLAG(has_dialog_id); + END_PARSE_FLAGS(); + if (has_dialog_id) { + td::parse(dialog_id_, parser); + } + td::parse(count_, parser); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReplyHeader.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageReplyHeader.cpp index 30cef73a5a..8ecf65309d 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageReplyHeader.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReplyHeader.cpp @@ -1,61 +1,63 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/MessageReplyHeader.h" -#include "td/telegram/FullMessageId.h" -#include "td/telegram/ScheduledServerMessageId.h" #include "td/telegram/ServerMessageId.h" +#include "td/telegram/StoryId.h" #include "td/utils/logging.h" namespace td { -MessageReplyHeader::MessageReplyHeader(tl_object_ptr &&reply_header, +MessageReplyHeader::MessageReplyHeader(Td *td, tl_object_ptr &&reply_header_ptr, DialogId dialog_id, MessageId message_id, int32 date, bool can_have_thread) { - if (reply_header == nullptr) { + if (reply_header_ptr == nullptr) { return; } - if (reply_header->reply_to_scheduled_) { - reply_to_message_id = MessageId(ScheduledServerMessageId(reply_header->reply_to_msg_id_), date); - if (message_id.is_scheduled()) { - auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_); - if (reply_to_peer_id != nullptr) { - reply_in_dialog_id = DialogId(reply_to_peer_id); - LOG(ERROR) << "Receive reply to " << FullMessageId{reply_in_dialog_id, reply_to_message_id} << " in " - << FullMessageId{dialog_id, message_id}; - reply_to_message_id = MessageId(); - reply_in_dialog_id = DialogId(); - } + if (reply_header_ptr->get_id() == telegram_api::messageReplyStoryHeader::ID) { + auto reply_header = telegram_api::move_object_as(reply_header_ptr); + DialogId story_dialog_id(reply_header->peer_); + StoryId story_id(reply_header->story_id_); + if (!story_dialog_id.is_valid() || !story_id.is_server()) { + LOG(ERROR) << "Receive " << to_string(reply_header); } else { - LOG(ERROR) << "Receive reply to " << reply_to_message_id << " in " << FullMessageId{dialog_id, message_id}; - reply_to_message_id = MessageId(); + story_full_id_ = {story_dialog_id, story_id}; } - } else { - reply_to_message_id = MessageId(ServerMessageId(reply_header->reply_to_msg_id_)); - auto reply_to_peer_id = std::move(reply_header->reply_to_peer_id_); - if (reply_to_peer_id != nullptr) { - reply_in_dialog_id = DialogId(reply_to_peer_id); - if (!reply_in_dialog_id.is_valid()) { - LOG(ERROR) << "Receive reply in invalid " << to_string(reply_to_peer_id); - reply_to_message_id = MessageId(); - reply_in_dialog_id = DialogId(); - } - if (reply_in_dialog_id == dialog_id) { - reply_in_dialog_id = DialogId(); // just in case + return; + } + CHECK(reply_header_ptr->get_id() == telegram_api::messageReplyHeader::ID); + auto reply_header = telegram_api::move_object_as(reply_header_ptr); + + if (!message_id.is_scheduled() && can_have_thread) { + if ((reply_header->flags_ & telegram_api::messageReplyHeader::REPLY_TO_TOP_ID_MASK) != 0) { + top_thread_message_id_ = MessageId(ServerMessageId(reply_header->reply_to_top_id_)); + if (!top_thread_message_id_.is_valid()) { + LOG(ERROR) << "Receive " << to_string(reply_header); + top_thread_message_id_ = MessageId(); } } - if (reply_to_message_id.is_valid() && !message_id.is_scheduled() && !reply_in_dialog_id.is_valid() && - can_have_thread) { - if ((reply_header->flags_ & telegram_api::messageReplyHeader::REPLY_TO_TOP_ID_MASK) != 0) { - top_thread_message_id = MessageId(ServerMessageId(reply_header->reply_to_top_id_)); + is_topic_message_ = reply_header->forum_topic_; + } + + replied_message_info_ = RepliedMessageInfo(td, std::move(reply_header), dialog_id, message_id, date); + + if (!message_id.is_scheduled() && can_have_thread) { + if (!top_thread_message_id_.is_valid()) { + auto same_chat_reply_to_message_id = replied_message_info_.get_same_chat_reply_to_message_id(false); + if (same_chat_reply_to_message_id.is_valid()) { + CHECK(same_chat_reply_to_message_id.is_server()); + top_thread_message_id_ = same_chat_reply_to_message_id; } else { - top_thread_message_id = reply_to_message_id; + is_topic_message_ = false; } - is_topic_message = reply_header->forum_topic_; + } + if (top_thread_message_id_ >= message_id) { + LOG(ERROR) << "Receive top thread " << top_thread_message_id_ << " in " << message_id << " in " << dialog_id; + top_thread_message_id_ = MessageId(); } } } diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReplyHeader.h b/protocols/Telegram/tdlib/td/td/telegram/MessageReplyHeader.h index 40ba95fc02..fcd0eb79ff 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageReplyHeader.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReplyHeader.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,21 +8,29 @@ #include "td/telegram/DialogId.h" #include "td/telegram/MessageId.h" +#include "td/telegram/RepliedMessageInfo.h" +#include "td/telegram/StoryFullId.h" #include "td/telegram/telegram_api.h" #include "td/utils/common.h" namespace td { +class Td; + struct MessageReplyHeader { - MessageId reply_to_message_id; - DialogId reply_in_dialog_id; - MessageId top_thread_message_id; - bool is_topic_message = false; + RepliedMessageInfo replied_message_info_; + + MessageId top_thread_message_id_; + bool is_topic_message_ = false; + + // or + + StoryFullId story_full_id_; MessageReplyHeader() = default; - MessageReplyHeader(tl_object_ptr &&reply_header, DialogId dialog_id, + MessageReplyHeader(Td *td, tl_object_ptr &&reply_header_ptr, DialogId dialog_id, MessageId message_id, int32 date, bool can_have_thread); }; diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageReplyInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageReplyInfo.cpp index 831482c27f..de0ff5515d 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageReplyInfo.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageReplyInfo.cpp @@ -1,16 +1,17 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/MessageReplyInfo.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/MessageSender.h" -#include "td/telegram/MessagesManager.h" #include "td/telegram/ServerMessageId.h" #include "td/telegram/Td.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" #include "td/utils/logging.h" @@ -55,17 +56,17 @@ MessageReplyInfo::MessageReplyInfo(Td *td, tl_object_ptrmessages_manager_->have_dialog_info(dialog_id)) { + if (!td->dialog_manager_->have_dialog_info(dialog_id)) { auto dialog_type = dialog_id.get_type(); if (dialog_type == DialogType::User) { auto replier_user_id = dialog_id.get_user_id(); - if (!td->contacts_manager_->have_min_user(replier_user_id)) { + if (!td->user_manager_->have_min_user(replier_user_id)) { LOG(ERROR) << "Receive unknown replied " << replier_user_id; continue; } } else if (dialog_type == DialogType::Channel) { auto replier_channel_id = dialog_id.get_channel_id(); - auto min_channel = td->contacts_manager_->get_min_channel(replier_channel_id); + auto min_channel = td->chat_manager_->get_min_channel(replier_channel_id); if (min_channel == nullptr) { LOG(ERROR) << "Receive unknown replied " << replier_channel_id; continue; @@ -101,6 +102,10 @@ bool MessageReplyInfo::need_update_to(const MessageReplyInfo &other) const { // ignore updates to empty reply info, because we will hide the info ourselves // return true; } + if (other.is_comment_ != is_comment_ && !other.was_dropped()) { + LOG(ERROR) << "Reply info has changed from " << *this << " to " << other; + return true; + } if (other.pts_ < pts_ && !other.was_dropped()) { return false; } @@ -162,13 +167,10 @@ bool MessageReplyInfo::add_reply(DialogId replier_dialog_id, MessageId reply_mes } } - td::remove(recent_replier_dialog_ids_, replier_dialog_id); if (diff > 0) { - recent_replier_dialog_ids_.insert(recent_replier_dialog_ids_.begin(), replier_dialog_id); - if (recent_replier_dialog_ids_.size() > MAX_RECENT_REPLIERS) { - recent_replier_dialog_ids_.pop_back(); - } + add_to_top(recent_replier_dialog_ids_, MAX_RECENT_REPLIERS, replier_dialog_id); } else { + td::remove(recent_replier_dialog_ids_, replier_dialog_id); auto max_repliers = static_cast(reply_count_); if (recent_replier_dialog_ids_.size() > max_repliers) { recent_replier_dialog_ids_.resize(max_repliers); @@ -184,9 +186,9 @@ bool MessageReplyInfo::add_reply(DialogId replier_dialog_id, MessageId reply_mes bool MessageReplyInfo::need_reget(const Td *td) const { for (auto &dialog_id : recent_replier_dialog_ids_) { - if (dialog_id.get_type() != DialogType::User && !td->messages_manager_->have_dialog_info(dialog_id)) { + if (dialog_id.get_type() != DialogType::User && !td->dialog_manager_->have_dialog_info(dialog_id)) { if (dialog_id.get_type() == DialogType::Channel && - td->contacts_manager_->have_min_channel(dialog_id.get_channel_id())) { + td->chat_manager_->have_min_channel(dialog_id.get_channel_id())) { return false; } LOG(INFO) << "Reget a message because of replied " << dialog_id; @@ -222,10 +224,11 @@ StringBuilder &operator<<(StringBuilder &string_builder, const MessageReplyInfo if (reply_info.is_comment_) { return string_builder << reply_info.reply_count_ << " comments in " << reply_info.channel_id_ << " by " << reply_info.recent_replier_dialog_ids_ << " read up to " - << reply_info.last_read_inbox_message_id_ << "/" << reply_info.last_read_outbox_message_id_; + << reply_info.last_read_inbox_message_id_ << '/' << reply_info.last_read_outbox_message_id_ + << " with PTS " << reply_info.pts_; } else { return string_builder << reply_info.reply_count_ << " replies read up to " << reply_info.last_read_inbox_message_id_ - << "/" << reply_info.last_read_outbox_message_id_; + << "/" << reply_info.last_read_outbox_message_id_ << " with PTS " << reply_info.pts_; } } diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageSearchOffset.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageSearchOffset.cpp new file mode 100644 index 0000000000..9d08b8ae68 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageSearchOffset.cpp @@ -0,0 +1,69 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageSearchOffset.h" + +#include "td/telegram/DialogManager.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/ServerMessageId.h" + +#include "td/utils/misc.h" +#include "td/utils/SliceBuilder.h" +#include "td/utils/StringBuilder.h" + +#include + +namespace td { + +void MessageSearchOffset::update_from_message(const telegram_api::object_ptr &message) { + auto message_date = MessagesManager::get_message_date(message); + auto message_id = MessageId::get_message_id(message, false); + auto dialog_id = DialogId::get_message_dialog_id(message); + if (message_date > 0 && message_id.is_valid() && dialog_id.is_valid()) { + date_ = message_date; + message_id_ = message_id; + dialog_id_ = dialog_id; + } +} + +string MessageSearchOffset::to_string() const { + return PSTRING() << date_ << ',' << dialog_id_.get() << ',' << message_id_.get_server_message_id().get(); +} + +Result MessageSearchOffset::from_string(const string &offset) { + MessageSearchOffset result; + result.date_ = std::numeric_limits::max(); + bool is_offset_valid = [&] { + if (offset.empty()) { + return true; + } + + auto parts = full_split(offset, ','); + if (parts.size() != 3) { + return false; + } + auto r_offset_date = to_integer_safe(parts[0]); + auto r_offset_dialog_id = to_integer_safe(parts[1]); + auto r_offset_message_id = to_integer_safe(parts[2]); + if (r_offset_date.is_error() || r_offset_message_id.is_error() || r_offset_dialog_id.is_error()) { + return false; + } + result.date_ = r_offset_date.ok(); + result.message_id_ = MessageId(ServerMessageId(r_offset_message_id.ok())); + result.dialog_id_ = DialogId(r_offset_dialog_id.ok()); + if (result.date_ <= 0 || !result.message_id_.is_valid() || !result.dialog_id_.is_valid() || + DialogManager::get_input_peer_force(result.dialog_id_)->get_id() == telegram_api::inputPeerEmpty::ID) { + return false; + } + return true; + }(); + if (!is_offset_valid) { + return Status::Error(400, "Invalid offset specified"); + } + return std::move(result); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageSearchOffset.h b/protocols/Telegram/tdlib/td/td/telegram/MessageSearchOffset.h new file mode 100644 index 0000000000..91a88e6420 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageSearchOffset.h @@ -0,0 +1,30 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" + +namespace td { + +struct MessageSearchOffset { + int32 date_ = 0; + MessageId message_id_; + DialogId dialog_id_; + + void update_from_message(const telegram_api::object_ptr &message); + + string to_string() const; + + static Result from_string(const string &offset); +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageSelfDestructType.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageSelfDestructType.cpp new file mode 100644 index 0000000000..4abee57646 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageSelfDestructType.cpp @@ -0,0 +1,90 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MessageSelfDestructType.h" + +namespace td { + +bool MessageSelfDestructType::is_valid() const { + return ttl_ > 0; +} + +bool MessageSelfDestructType::is_empty() const { + return ttl_ == 0; +} + +bool MessageSelfDestructType::is_immediate() const { + return ttl_ == 0x7FFFFFFF; +} + +bool MessageSelfDestructType::is_secret_message_content(MessageContentType content_type) { + if (ttl_ <= 0 || ttl_ > 60) { + return is_immediate(); + } + return can_be_secret_message_content(content_type); +} + +void MessageSelfDestructType::ensure_at_least(int32 ttl) { + if (is_immediate() || ttl_ >= ttl || ttl_ <= 0 || ttl <= 0) { + return; + } + ttl_ = ttl; +} + +Result MessageSelfDestructType::get_message_self_destruct_type( + td_api::object_ptr &&self_destruct_type) { + if (self_destruct_type == nullptr) { + return MessageSelfDestructType(); + } + switch (self_destruct_type->get_id()) { + case td_api::messageSelfDestructTypeTimer::ID: { + auto ttl = + static_cast(self_destruct_type.get())->self_destruct_time_; + + static constexpr int32 MAX_PRIVATE_MESSAGE_TTL = 60; // server side limit + if (ttl <= 0 || ttl > MAX_PRIVATE_MESSAGE_TTL) { + return Status::Error(400, "Invalid message content self-destruct time specified"); + } + return MessageSelfDestructType(ttl, true); + } + case td_api::messageSelfDestructTypeImmediately::ID: + return MessageSelfDestructType(0x7FFFFFFF, true); + default: + UNREACHABLE(); + return MessageSelfDestructType(); + } +} + +td_api::object_ptr MessageSelfDestructType::get_message_self_destruct_type_object() + const { + if (is_immediate()) { + return td_api::make_object(); + } + if (!is_empty()) { + return td_api::make_object(ttl_); + } + return nullptr; +} + +int32 MessageSelfDestructType::get_input_ttl() const { + return ttl_; +} + +bool operator==(const MessageSelfDestructType &lhs, const MessageSelfDestructType &rhs) { + return lhs.ttl_ == rhs.ttl_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageSelfDestructType &message_ttl) { + if (message_ttl.is_empty()) { + return string_builder << "non-self-destruct"; + } + if (message_ttl.is_immediate()) { + return string_builder << "self-destruct immediately"; + } + return string_builder << "self-destruct at " << message_ttl.get_input_ttl(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageSelfDestructType.h b/protocols/Telegram/tdlib/td/td/telegram/MessageSelfDestructType.h new file mode 100644 index 0000000000..3939039b63 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageSelfDestructType.h @@ -0,0 +1,74 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageContentType.h" +#include "td/telegram/td_api.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" +#include "td/utils/StringBuilder.h" +#include "td/utils/tl_helpers.h" + +#include + +namespace td { + +class MessageSelfDestructType { + int32 ttl_ = 0; + + friend bool operator==(const MessageSelfDestructType &lhs, const MessageSelfDestructType &rhs); + + public: + MessageSelfDestructType() = default; + + template ::value>> + MessageSelfDestructType(T ttl) = delete; + + MessageSelfDestructType(int32 ttl, bool allow_immediate) : ttl_(ttl) { + if (!allow_immediate && is_immediate()) { + ttl_ = 0x7FFFFFFE; + } + } + + bool is_valid() const; + + bool is_empty() const; + + bool is_immediate() const; + + bool is_secret_message_content(MessageContentType content_type); + + void ensure_at_least(int32 ttl); + + static Result get_message_self_destruct_type( + td_api::object_ptr &&self_destruct_type); + + td_api::object_ptr get_message_self_destruct_type_object() const; + + int32 get_input_ttl() const; + + template + void store(StorerT &storer) const { + td::store(ttl_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(ttl_, parser); + } +}; + +bool operator==(const MessageSelfDestructType &lhs, const MessageSelfDestructType &rhs); + +inline bool operator!=(const MessageSelfDestructType &lhs, const MessageSelfDestructType &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MessageSelfDestructType &message_self_destruct_type); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageSender.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageSender.cpp index 7f9a1a8558..7b37555472 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageSender.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageSender.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,9 +7,11 @@ #include "td/telegram/MessageSender.h" #include "td/telegram/AuthManager.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/Td.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" #include "td/utils/logging.h" @@ -21,14 +23,14 @@ td_api::object_ptr get_message_sender_object_const(Td *td const char *source) { if (dialog_id.is_valid() && td->messages_manager_->have_dialog(dialog_id)) { return td_api::make_object( - td->messages_manager_->get_chat_id_object(dialog_id, "get_message_sender_object_const")); + td->dialog_manager_->get_chat_id_object(dialog_id, "get_message_sender_object_const")); } if (!user_id.is_valid()) { // can happen only if the server sends a message with wrong sender LOG(ERROR) << "Receive message with wrong sender " << user_id << '/' << dialog_id << " from " << source; - user_id = td->contacts_manager_->add_service_notifications_user(); + user_id = td->user_manager_->add_service_notifications_user(); } - return td_api::make_object(td->contacts_manager_->get_user_id_object(user_id, source)); + return td_api::make_object(td->user_manager_->get_user_id_object(user_id, source)); } td_api::object_ptr get_message_sender_object_const(Td *td, DialogId dialog_id, @@ -42,13 +44,12 @@ td_api::object_ptr get_message_sender_object_const(Td *td td_api::object_ptr get_message_sender_object(Td *td, UserId user_id, DialogId dialog_id, const char *source) { if (dialog_id.is_valid() && !td->messages_manager_->have_dialog(dialog_id)) { - LOG(ERROR) << "Failed to find " << dialog_id; - td->messages_manager_->force_create_dialog(dialog_id, source); + td->dialog_manager_->force_create_dialog(dialog_id, source, true); } if (!user_id.is_valid() && td->auth_manager_->is_bot()) { - td->contacts_manager_->add_anonymous_bot_user(); - td->contacts_manager_->add_channel_bot_user(); - td->contacts_manager_->add_service_notifications_user(); + td->user_manager_->add_anonymous_bot_user(); + td->user_manager_->add_channel_bot_user(); + td->user_manager_->add_service_notifications_user(); } return get_message_sender_object_const(td, user_id, dialog_id, source); } @@ -65,19 +66,19 @@ td_api::object_ptr get_min_message_sender_object(Td *td, auto dialog_type = dialog_id.get_type(); if (dialog_type == DialogType::User) { auto user_id = dialog_id.get_user_id(); - if (td->contacts_manager_->have_min_user(user_id)) { - return td_api::make_object(td->contacts_manager_->get_user_id_object(user_id, source)); + if (td->user_manager_->have_min_user(user_id)) { + return td_api::make_object(td->user_manager_->get_user_id_object(user_id, source)); } } else { if (!td->messages_manager_->have_dialog(dialog_id) && - (td->messages_manager_->have_dialog_info(dialog_id) || - (dialog_type == DialogType::Channel && td->contacts_manager_->have_min_channel(dialog_id.get_channel_id())))) { + (td->dialog_manager_->have_dialog_info(dialog_id) || + (dialog_type == DialogType::Channel && td->chat_manager_->have_min_channel(dialog_id.get_channel_id())))) { LOG(INFO) << "Force creation of " << dialog_id; - td->messages_manager_->force_create_dialog(dialog_id, source, true); + td->dialog_manager_->force_create_dialog(dialog_id, source, true); } if (td->messages_manager_->have_dialog(dialog_id)) { return td_api::make_object( - td->messages_manager_->get_chat_id_object(dialog_id, "get_min_message_sender_object")); + td->dialog_manager_->get_chat_id_object(dialog_id, "get_min_message_sender_object")); } } LOG(ERROR) << "Can't return unknown " << dialog_id << " from " << source; @@ -95,15 +96,15 @@ vector get_message_sender_dialog_ids(Td *td, continue; } if (dialog_id.get_type() == DialogType::User) { - if (!td->contacts_manager_->have_user(dialog_id.get_user_id())) { + if (!td->user_manager_->have_user(dialog_id.get_user_id())) { LOG(ERROR) << "Receive unknown " << dialog_id.get_user_id(); continue; } } else { - if (!td->messages_manager_->have_dialog_info(dialog_id)) { + if (!td->dialog_manager_->have_dialog_info(dialog_id)) { continue; } - td->messages_manager_->force_create_dialog(dialog_id, "get_message_sender_dialog_ids"); + td->dialog_manager_->force_create_dialog(dialog_id, "get_message_sender_dialog_ids"); if (!td->messages_manager_->have_dialog(dialog_id)) { continue; } @@ -140,7 +141,7 @@ Result get_message_sender_dialog_id(Td *td, } return Status::Error(400, "Invalid user identifier specified"); } - bool know_user = td->contacts_manager_->have_user_force(user_id); + bool know_user = td->user_manager_->have_user_force(user_id, "get_message_sender_dialog_id"); if (check_access && !know_user) { return Status::Error(400, "Unknown user identifier specified"); } @@ -154,9 +155,10 @@ Result get_message_sender_dialog_id(Td *td, } return Status::Error(400, "Invalid chat identifier specified"); } - bool know_dialog = dialog_id.get_type() == DialogType::User - ? td->contacts_manager_->have_user_force(dialog_id.get_user_id()) - : td->messages_manager_->have_dialog_force(dialog_id, "get_message_sender_dialog_id"); + bool know_dialog = + dialog_id.get_type() == DialogType::User + ? td->user_manager_->have_user_force(dialog_id.get_user_id(), "get_message_sender_dialog_id 2") + : td->dialog_manager_->have_dialog_force(dialog_id, "get_message_sender_dialog_id"); if (check_access && !know_dialog) { return Status::Error(400, "Unknown chat identifier specified"); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageSource.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageSource.cpp index 1e75ab0d42..6522469950 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageSource.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageSource.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -28,6 +28,8 @@ StringBuilder &operator<<(StringBuilder &string_builder, MessageSource source) { return string_builder << "DialogEventLog"; case MessageSource::Notification: return string_builder << "Notification"; + case MessageSource::Screenshot: + return string_builder << "Screenshot"; case MessageSource::Other: return string_builder << "Other"; default: @@ -56,6 +58,8 @@ MessageSource get_message_source(const td_api::object_ptr return MessageSource::DialogEventLog; case td_api::messageSourceNotification::ID: return MessageSource::Notification; + case td_api::messageSourceScreenshot::ID: + return MessageSource::Screenshot; case td_api::messageSourceOther::ID: return MessageSource::Other; default: diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageSource.h b/protocols/Telegram/tdlib/td/td/telegram/MessageSource.h index 778fd58715..190f72f380 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageSource.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageSource.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -23,6 +23,7 @@ enum class MessageSource : int32 { Search, DialogEventLog, Notification, + Screenshot, Other }; diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageViewer.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessageViewer.cpp index c6520e9ab0..1cb011950e 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageViewer.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageViewer.cpp @@ -1,43 +1,50 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/MessageViewer.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" +#include "td/utils/logging.h" namespace td { MessageViewer::MessageViewer(telegram_api::object_ptr &&read_date) - : user_id_(read_date->user_id_), date_(read_date->date_) { + : MessageViewer(UserId(read_date->user_id_), read_date->date_) { } -td_api::object_ptr MessageViewer::get_message_viewer_object( - ContactsManager *contacts_manager) const { +td_api::object_ptr MessageViewer::get_message_viewer_object(UserManager *user_manager) const { return td_api::make_object( - contacts_manager->get_user_id_object(user_id_, "get_message_viewer_object"), date_); + user_manager->get_user_id_object(user_id_, "get_message_viewer_object"), date_); } StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewer &viewer) { return string_builder << '[' << viewer.user_id_ << " at " << viewer.date_ << ']'; } -MessageViewers::MessageViewers(vector> &&read_dates) - : message_viewers_( - transform(std::move(read_dates), [](telegram_api::object_ptr &&read_date) { - return MessageViewer(std::move(read_date)); - })) { +MessageViewers::MessageViewers(vector> &&read_dates) { + for (auto &read_date : read_dates) { + message_viewers_.emplace_back(std::move(read_date)); + auto user_id = message_viewers_.back().get_user_id(); + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id << " as a viewer of a message"; + message_viewers_.pop_back(); + } + } } -td_api::object_ptr MessageViewers::get_message_viewers_object( - ContactsManager *contacts_manager) const { +vector MessageViewers::get_user_ids() const { + return transform(message_viewers_, [](auto &viewer) { return viewer.get_user_id(); }); +} + +td_api::object_ptr MessageViewers::get_message_viewers_object(UserManager *user_manager) const { return td_api::make_object( - transform(message_viewers_, [contacts_manager](const MessageViewer &message_viewer) { - return message_viewer.get_message_viewer_object(contacts_manager); + transform(message_viewers_, [user_manager](const MessageViewer &message_viewer) { + return message_viewer.get_message_viewer_object(user_manager); })); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessageViewer.h b/protocols/Telegram/tdlib/td/td/telegram/MessageViewer.h index fb071af1b3..f3ddaffb1f 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessageViewer.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessageViewer.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,7 +15,7 @@ namespace td { -class ContactsManager; +class UserManager; class MessageViewer { UserId user_id_; @@ -26,21 +26,35 @@ class MessageViewer { public: explicit MessageViewer(telegram_api::object_ptr &&read_date); + MessageViewer(UserId user_id, int32 date) : user_id_(user_id), date_(td::max(date, static_cast(0))) { + } + UserId get_user_id() const { return user_id_; } - td_api::object_ptr get_message_viewer_object(ContactsManager *contacts_manager) const; + bool is_empty() const { + return user_id_ == UserId() && date_ == 0; + } + + td_api::object_ptr get_message_viewer_object(UserManager *user_manager) const; }; StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewer &viewer); -struct MessageViewers { +class MessageViewers { vector message_viewers_; + friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewers &viewers); + + public: + MessageViewers() = default; + explicit MessageViewers(vector> &&read_dates); - td_api::object_ptr get_message_viewers_object(ContactsManager *contacts_manager) const; + vector get_user_ids() const; + + td_api::object_ptr get_message_viewers_object(UserManager *user_manager) const; }; StringBuilder &operator<<(StringBuilder &string_builder, const MessageViewers &viewers); diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessagesInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessagesInfo.cpp index f7d2638084..e7a1c4b5e7 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessagesInfo.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessagesInfo.cpp @@ -1,14 +1,16 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/MessagesInfo.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/ForumTopicManager.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" #include "td/utils/logging.h" #include "td/utils/misc.h" @@ -66,8 +68,8 @@ MessagesInfo get_messages_info(Td *td, DialogId dialog_id, break; } - td->contacts_manager_->on_get_users(std::move(users), source); - td->contacts_manager_->on_get_chats(std::move(chats), source); + td->user_manager_->on_get_users(std::move(users), source); + td->chat_manager_->on_get_chats(std::move(chats), source); td->forum_topic_manager_->on_get_forum_topic_infos(dialog_id, std::move(topics), source); return result; diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.cpp index 0faa4706f3..698aed91e9 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.cpp @@ -1,27 +1,36 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/MessagesManager.h" +#include "td/telegram/AccountManager.h" #include "td/telegram/AuthManager.h" #include "td/telegram/BackgroundInfo.hpp" +#include "td/telegram/BlockListId.h" +#include "td/telegram/BusinessBotManageBar.h" +#include "td/telegram/BusinessConnectionManager.h" #include "td/telegram/ChainId.h" #include "td/telegram/ChannelType.h" -#include "td/telegram/ChatId.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/ChatReactions.hpp" #include "td/telegram/Dependencies.h" +#include "td/telegram/DialogAction.h" #include "td/telegram/DialogActionBar.h" +#include "td/telegram/DialogActionManager.h" #include "td/telegram/DialogDb.h" #include "td/telegram/DialogFilter.h" #include "td/telegram/DialogFilterManager.h" -#include "td/telegram/DialogLocation.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/DialogNotificationSettings.hpp" +#include "td/telegram/DialogParticipantManager.h" #include "td/telegram/DownloadManager.h" #include "td/telegram/DraftMessage.h" #include "td/telegram/DraftMessage.hpp" +#include "td/telegram/FactCheck.h" +#include "td/telegram/FactCheck.hpp" #include "td/telegram/FileReferenceManager.h" #include "td/telegram/files/FileId.hpp" #include "td/telegram/files/FileLocation.h" @@ -30,7 +39,9 @@ #include "td/telegram/ForumTopicManager.h" #include "td/telegram/Global.h" #include "td/telegram/GroupCallManager.h" +#include "td/telegram/HashtagHints.h" #include "td/telegram/InlineQueriesManager.h" +#include "td/telegram/InputDialogId.h" #include "td/telegram/InputMessageText.h" #include "td/telegram/LinkManager.h" #include "td/telegram/Location.h" @@ -39,32 +50,51 @@ #include "td/telegram/MessageDb.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/MessageEntity.hpp" +#include "td/telegram/MessageForwardInfo.h" +#include "td/telegram/MessageForwardInfo.hpp" +#include "td/telegram/MessageOrigin.hpp" +#include "td/telegram/MessageQuote.h" #include "td/telegram/MessageReaction.h" #include "td/telegram/MessageReaction.hpp" #include "td/telegram/MessageReplyInfo.hpp" +#include "td/telegram/MessageSearchOffset.h" #include "td/telegram/MessageSender.h" #include "td/telegram/misc.h" +#include "td/telegram/MissingInvitee.h" #include "td/telegram/net/DcId.h" -#include "td/telegram/net/NetQuery.h" +#include "td/telegram/NotificationGroupInfo.hpp" #include "td/telegram/NotificationGroupType.h" #include "td/telegram/NotificationManager.h" +#include "td/telegram/NotificationObjectId.h" #include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/NotificationSound.h" #include "td/telegram/NotificationType.h" +#include "td/telegram/OnlineManager.h" #include "td/telegram/OptionManager.h" +#include "td/telegram/Photo.h" #include "td/telegram/PollId.h" #include "td/telegram/PublicDialogType.h" +#include "td/telegram/QuickReplyManager.h" +#include "td/telegram/ReactionManager.h" +#include "td/telegram/RepliedMessageInfo.hpp" #include "td/telegram/ReplyMarkup.h" #include "td/telegram/ReplyMarkup.hpp" +#include "td/telegram/SavedMessagesManager.h" #include "td/telegram/SecretChatsManager.h" #include "td/telegram/SponsoredMessageManager.h" -#include "td/telegram/StickerPhotoSize.h" +#include "td/telegram/StarManager.h" #include "td/telegram/StickerType.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/StoryManager.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/TopDialogCategory.h" +#include "td/telegram/TopDialogManager.h" #include "td/telegram/TranslationManager.h" #include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" +#include "td/telegram/Usernames.h" #include "td/telegram/Version.h" #include "td/telegram/WebPageId.h" @@ -79,7 +109,6 @@ #include "td/utils/format.h" #include "td/utils/logging.h" #include "td/utils/misc.h" -#include "td/utils/PathView.h" #include "td/utils/Random.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" @@ -96,37 +125,6 @@ namespace td { -class GetOnlinesQuery final : public Td::ResultHandler { - DialogId dialog_id_; - - public: - void send(DialogId dialog_id) { - dialog_id_ = dialog_id; - CHECK(dialog_id.get_type() == DialogType::Channel); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); - if (input_peer == nullptr) { - return on_error(Status::Error(400, "Can't access the chat")); - } - - send_query(G()->net_query_creator().create(telegram_api::messages_getOnlines(std::move(input_peer)))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto result = result_ptr.move_as_ok(); - td_->messages_manager_->on_update_dialog_online_member_count(dialog_id_, result->onlines_, true); - } - - void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetOnlinesQuery"); - td_->messages_manager_->on_update_dialog_online_member_count(dialog_id_, 0, true); - } -}; - class GetDialogQuery final : public Td::ResultHandler { DialogId dialog_id_; @@ -135,7 +133,7 @@ class GetDialogQuery final : public Td::ResultHandler { dialog_id_ = dialog_id; send_query(G()->net_query_creator().create( telegram_api::messages_getPeerDialogs( - td_->messages_manager_->get_input_dialog_peers({dialog_id}, AccessRights::Read)), + td_->dialog_manager_->get_input_dialog_peers({dialog_id}, AccessRights::Read)), {{dialog_id}})); } @@ -148,8 +146,8 @@ class GetDialogQuery final : public Td::ResultHandler { auto result = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for GetDialogQuery: " << to_string(result); - td_->contacts_manager_->on_get_users(std::move(result->users_), "GetDialogQuery"); - td_->contacts_manager_->on_get_chats(std::move(result->chats_), "GetDialogQuery"); + td_->user_manager_->on_get_users(std::move(result->users_), "GetDialogQuery"); + td_->chat_manager_->on_get_chats(std::move(result->chats_), "GetDialogQuery"); td_->messages_manager_->on_get_dialogs(FolderId(), std::move(result->dialogs_), -1, std::move(result->messages_), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_](Result<> result) { @@ -160,7 +158,7 @@ class GetDialogQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDialogQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetDialogQuery"); td_->messages_manager_->on_get_dialog_query_finished(dialog_id_, std::move(status)); } }; @@ -191,8 +189,8 @@ class GetPinnedDialogsQuery final : public Td::ResultHandler { auto result = result_ptr.move_as_ok(); LOG(INFO) << "Receive pinned chats in " << folder_id_ << ": " << to_string(result); - td_->contacts_manager_->on_get_users(std::move(result->users_), "GetPinnedDialogsQuery"); - td_->contacts_manager_->on_get_chats(std::move(result->chats_), "GetPinnedDialogsQuery"); + td_->user_manager_->on_get_users(std::move(result->users_), "GetPinnedDialogsQuery"); + td_->chat_manager_->on_get_chats(std::move(result->chats_), "GetPinnedDialogsQuery"); td_->messages_manager_->on_get_dialogs(folder_id_, std::move(result->dialogs_), -2, std::move(result->messages_), std::move(promise_)); } @@ -247,7 +245,7 @@ class GetDiscussionMessageQuery final : public Td::ResultHandler { expected_dialog_id_ = expected_dialog_id; expected_message_id_ = expected_message_id; CHECK(expected_dialog_id_.is_valid()); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create( telegram_api::messages_getDiscussionMessage(std::move(input_peer), message_id.get_server_message_id().get()))); @@ -264,13 +262,7 @@ class GetDiscussionMessageQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (expected_dialog_id_ == dialog_id_) { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDiscussionMessageQuery"); - } - if (status.message() == "MSG_ID_INVALID") { - td_->messages_manager_->get_message_from_server({dialog_id_, message_id_}, Promise(), - "GetDiscussionMessageQuery"); - } + td_->messages_manager_->on_get_message_error(dialog_id_, message_id_, status, "GetDiscussionMessageQuery"); promise_.set_error(std::move(status)); } }; @@ -361,7 +353,8 @@ class GetChannelMessagesQuery final : public Td::ResultHandler { send_closure(actor_id, &MessagesManager::on_get_messages, std::move(info.messages), info.is_channel_messages, false, std::move(promise), source); } - })); + }), + source); } void on_error(Status status) final { @@ -369,7 +362,7 @@ class GetChannelMessagesQuery final : public Td::ResultHandler { promise_.set_value(Unit()); return; } - td_->contacts_manager_->on_get_channel_error(channel_id_, status, "GetChannelMessagesQuery"); + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetChannelMessagesQuery"); promise_.set_error(std::move(status)); } }; @@ -407,22 +400,27 @@ class GetScheduledMessagesQuery final : public Td::ResultHandler { promise_.set_value(Unit()); return; } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetScheduledMessagesQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetScheduledMessagesQuery"); promise_.set_error(std::move(status)); } }; class UpdateDialogPinnedMessageQuery final : public Td::ResultHandler { Promise promise_; + BusinessConnectionId business_connection_id_; DialogId dialog_id_; + MessageId message_id_; public: explicit UpdateDialogPinnedMessageQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(DialogId dialog_id, MessageId message_id, bool is_unpin, bool disable_notification, bool only_for_self) { + void send(BusinessConnectionId business_connection_id, DialogId dialog_id, MessageId message_id, bool is_unpin, + bool disable_notification, bool only_for_self) { + business_connection_id_ = business_connection_id; dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + message_id_ = message_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { LOG(INFO) << "Can't update pinned message in " << dialog_id; return on_error(Status::Error(400, "Can't update pinned message")); @@ -438,9 +436,11 @@ class UpdateDialogPinnedMessageQuery final : public Td::ResultHandler { if (only_for_self) { flags |= telegram_api::messages_updatePinnedMessage::PM_ONESIDE_MASK; } - send_query(G()->net_query_creator().create( + send_query(G()->net_query_creator().create_with_prefix( + business_connection_id.get_invoke_prefix(), telegram_api::messages_updatePinnedMessage(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, - std::move(input_peer), message_id.get_server_message_id().get()))); + std::move(input_peer), message_id.get_server_message_id().get()), + td_->business_connection_manager_->get_business_connection_dc_id(business_connection_id))); } void on_result(BufferSlice packet) final { @@ -451,11 +451,17 @@ class UpdateDialogPinnedMessageQuery final : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for UpdateDialogPinnedMessageQuery: " << to_string(ptr); - td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + if (!business_connection_id_.is_empty()) { + promise_.set_value(Unit()); + } else { + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "UpdateDialogPinnedMessageQuery"); + if (!business_connection_id_.is_empty()) { + td_->messages_manager_->on_get_message_error(dialog_id_, message_id_, status, "UpdateDialogPinnedMessageQuery"); + } promise_.set_error(std::move(status)); } }; @@ -463,6 +469,7 @@ class UpdateDialogPinnedMessageQuery final : public Td::ResultHandler { class UnpinAllMessagesQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; + MessageId top_thread_message_id_; public: explicit UnpinAllMessagesQuery(Promise &&promise) : promise_(std::move(promise)) { @@ -470,8 +477,9 @@ class UnpinAllMessagesQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId top_thread_message_id) { dialog_id_ = dialog_id; + top_thread_message_id_ = top_thread_message_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); if (input_peer == nullptr) { LOG(INFO) << "Can't unpin all messages in " << dialog_id_; return on_error(Status::Error(400, "Can't unpin all messages")); @@ -495,7 +503,52 @@ class UnpinAllMessagesQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "UnpinAllMessagesQuery"); + td_->messages_manager_->on_get_message_error(dialog_id_, top_thread_message_id_, status, "UnpinAllMessagesQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetOutboxReadDateQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + MessageId message_id_; + + public: + explicit GetOutboxReadDateQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, MessageId message_id) { + dialog_id_ = dialog_id; + message_id_ = message_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); + CHECK(input_peer != nullptr); + send_query(G()->net_query_creator().create( + telegram_api::messages_getOutboxReadDate(std::move(input_peer), message_id.get_server_message_id().get()))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + promise_.set_value(td_api::make_object(ptr->date_)); + } + + void on_error(Status status) final { + if (status.message() == "USER_PRIVACY_RESTRICTED") { + return promise_.set_value(td_api::make_object()); + } + if (status.message() == "YOUR_PRIVACY_RESTRICTED") { + return promise_.set_value(td_api::make_object()); + } + if (status.message() == "MESSAGE_TOO_OLD") { + return promise_.set_value(td_api::make_object()); + } + + td_->messages_manager_->on_get_message_error(dialog_id_, message_id_, status, "GetOutboxReadDateQuery"); promise_.set_error(std::move(status)); } }; @@ -503,6 +556,7 @@ class UnpinAllMessagesQuery final : public Td::ResultHandler { class GetMessageReadParticipantsQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; + MessageId message_id_; public: explicit GetMessageReadParticipantsQuery(Promise &&promise) : promise_(std::move(promise)) { @@ -510,7 +564,8 @@ class GetMessageReadParticipantsQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId message_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + message_id_ = message_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create(telegram_api::messages_getMessageReadParticipants( std::move(input_peer), message_id.get_server_message_id().get()))); @@ -526,7 +581,7 @@ class GetMessageReadParticipantsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetMessageReadParticipantsQuery"); + td_->messages_manager_->on_get_message_error(dialog_id_, message_id_, status, "GetMessageReadParticipantsQuery"); promise_.set_error(std::move(status)); } }; @@ -547,7 +602,7 @@ class ExportChannelMessageLinkQuery final : public Td::ResultHandler { message_id_ = message_id; for_group_ = for_group; ignore_result_ = ignore_result; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -578,7 +633,8 @@ class ExportChannelMessageLinkQuery final : public Td::ResultHandler { void on_error(Status status) final { if (!ignore_result_) { - td_->contacts_manager_->on_get_channel_error(channel_id_, status, "ExportChannelMessageLinkQuery"); + td_->messages_manager_->on_get_message_error(DialogId(channel_id_), message_id_, status, + "ExportChannelMessageLinkQuery"); } promise_.set_error(std::move(status)); } @@ -595,7 +651,7 @@ class GetDialogListQuery final : public Td::ResultHandler { void send(FolderId folder_id, int32 offset_date, ServerMessageId offset_message_id, DialogId offset_dialog_id, int32 limit) { folder_id_ = folder_id; - auto input_peer = MessagesManager::get_input_peer_force(offset_dialog_id); + auto input_peer = DialogManager::get_input_peer_force(offset_dialog_id); CHECK(input_peer != nullptr); int32 flags = @@ -617,8 +673,8 @@ class GetDialogListQuery final : public Td::ResultHandler { switch (ptr->get_id()) { case telegram_api::messages_dialogs::ID: { auto dialogs = move_tl_object_as(ptr); - td_->contacts_manager_->on_get_users(std::move(dialogs->users_), "GetDialogListQuery"); - td_->contacts_manager_->on_get_chats(std::move(dialogs->chats_), "GetDialogListQuery"); + td_->user_manager_->on_get_users(std::move(dialogs->users_), "GetDialogListQuery"); + td_->chat_manager_->on_get_chats(std::move(dialogs->chats_), "GetDialogListQuery"); td_->messages_manager_->on_get_dialogs(folder_id_, std::move(dialogs->dialogs_), narrow_cast(dialogs->dialogs_.size()), std::move(dialogs->messages_), std::move(promise_)); @@ -626,8 +682,8 @@ class GetDialogListQuery final : public Td::ResultHandler { } case telegram_api::messages_dialogsSlice::ID: { auto dialogs = move_tl_object_as(ptr); - td_->contacts_manager_->on_get_users(std::move(dialogs->users_), "GetDialogListQuery slice"); - td_->contacts_manager_->on_get_chats(std::move(dialogs->chats_), "GetDialogListQuery slice"); + td_->user_manager_->on_get_users(std::move(dialogs->users_), "GetDialogListQuery slice"); + td_->chat_manager_->on_get_chats(std::move(dialogs->chats_), "GetDialogListQuery slice"); td_->messages_manager_->on_get_dialogs(folder_id_, std::move(dialogs->dialogs_), max(dialogs->count_, 0), std::move(dialogs->messages_), std::move(promise_)); break; @@ -651,7 +707,8 @@ class SearchPublicDialogsQuery final : public Td::ResultHandler { public: void send(const string &query) { query_ = query; - send_query(G()->net_query_creator().create(telegram_api::contacts_search(query, 3 /* ignored server-side */))); + send_query( + G()->net_query_creator().create(telegram_api::contacts_search(query, 20 /* mostly ignored server-side */))); } void on_result(BufferSlice packet) final { @@ -662,8 +719,8 @@ class SearchPublicDialogsQuery final : public Td::ResultHandler { auto dialogs = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for SearchPublicDialogsQuery: " << to_string(dialogs); - td_->contacts_manager_->on_get_users(std::move(dialogs->users_), "SearchPublicDialogsQuery"); - td_->contacts_manager_->on_get_chats(std::move(dialogs->chats_), "SearchPublicDialogsQuery"); + td_->user_manager_->on_get_users(std::move(dialogs->users_), "SearchPublicDialogsQuery"); + td_->chat_manager_->on_get_chats(std::move(dialogs->chats_), "SearchPublicDialogsQuery"); td_->messages_manager_->on_get_public_dialogs_search_result(query_, std::move(dialogs->my_results_), std::move(dialogs->results_)); } @@ -679,56 +736,6 @@ class SearchPublicDialogsQuery final : public Td::ResultHandler { } }; -class GetCommonDialogsQuery final : public Td::ResultHandler { - Promise promise_; - UserId user_id_; - int64 offset_chat_id_ = 0; - - public: - explicit GetCommonDialogsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(UserId user_id, tl_object_ptr &&input_user, int64 offset_chat_id, int32 limit) { - user_id_ = user_id; - offset_chat_id_ = offset_chat_id; - - send_query(G()->net_query_creator().create( - telegram_api::messages_getCommonChats(std::move(input_user), offset_chat_id, limit))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto chats_ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for GetCommonDialogsQuery: " << to_string(chats_ptr); - switch (chats_ptr->get_id()) { - case telegram_api::messages_chats::ID: { - auto chats = move_tl_object_as(chats_ptr); - td_->messages_manager_->on_get_common_dialogs(user_id_, offset_chat_id_, std::move(chats->chats_), - narrow_cast(chats->chats_.size())); - break; - } - case telegram_api::messages_chatsSlice::ID: { - auto chats = move_tl_object_as(chats_ptr); - td_->messages_manager_->on_get_common_dialogs(user_id_, offset_chat_id_, std::move(chats->chats_), - chats->count_); - break; - } - default: - UNREACHABLE(); - } - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - promise_.set_error(std::move(status)); - } -}; - class GetBlockedDialogsQuery final : public Td::ResultHandler { Promise> promise_; int32 offset_; @@ -739,11 +746,17 @@ class GetBlockedDialogsQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(int32 offset, int32 limit) { + void send(BlockListId block_list_id, int32 offset, int32 limit) { offset_ = offset; limit_ = limit; - send_query(G()->net_query_creator().create(telegram_api::contacts_getBlocked(offset, limit))); + int32 flags = 0; + if (block_list_id == BlockListId::stories()) { + flags |= telegram_api::contacts_getBlocked::MY_STORIES_FROM_MASK; + } + + send_query( + G()->net_query_creator().create(telegram_api::contacts_getBlocked(flags, false /*ignored*/, offset, limit))); } void on_result(BufferSlice packet) final { @@ -759,8 +772,8 @@ class GetBlockedDialogsQuery final : public Td::ResultHandler { case telegram_api::contacts_blocked::ID: { auto blocked_peers = move_tl_object_as(ptr); - td_->contacts_manager_->on_get_users(std::move(blocked_peers->users_), "GetBlockedDialogsQuery"); - td_->contacts_manager_->on_get_chats(std::move(blocked_peers->chats_), "GetBlockedDialogsQuery"); + td_->user_manager_->on_get_users(std::move(blocked_peers->users_), "GetBlockedDialogsQuery"); + td_->chat_manager_->on_get_chats(std::move(blocked_peers->chats_), "GetBlockedDialogsQuery"); td_->messages_manager_->on_get_blocked_dialogs(offset_, limit_, narrow_cast(blocked_peers->blocked_.size()), std::move(blocked_peers->blocked_), std::move(promise_)); @@ -769,8 +782,8 @@ class GetBlockedDialogsQuery final : public Td::ResultHandler { case telegram_api::contacts_blockedSlice::ID: { auto blocked_peers = move_tl_object_as(ptr); - td_->contacts_manager_->on_get_users(std::move(blocked_peers->users_), "GetBlockedDialogsQuery slice"); - td_->contacts_manager_->on_get_chats(std::move(blocked_peers->chats_), "GetBlockedDialogsQuery slice"); + td_->user_manager_->on_get_users(std::move(blocked_peers->users_), "GetBlockedDialogsQuery slice"); + td_->chat_manager_->on_get_chats(std::move(blocked_peers->chats_), "GetBlockedDialogsQuery slice"); td_->messages_manager_->on_get_blocked_dialogs(offset_, limit_, blocked_peers->count_, std::move(blocked_peers->blocked_), std::move(promise_)); break; @@ -785,432 +798,6 @@ class GetBlockedDialogsQuery final : public Td::ResultHandler { } }; -class CreateChatQuery final : public Td::ResultHandler { - Promise promise_; - int64 random_id_; - - public: - explicit CreateChatQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(vector> &&input_users, const string &title, MessageTtl message_ttl, - int64 random_id) { - random_id_ = random_id; - int32 flags = telegram_api::messages_createChat::TTL_PERIOD_MASK; - send_query(G()->net_query_creator().create( - telegram_api::messages_createChat(flags, std::move(input_users), title, message_ttl.get_input_ttl_period()))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for CreateChatQuery: " << to_string(ptr); - td_->messages_manager_->on_create_new_dialog_success(random_id_, std::move(ptr), DialogType::Chat, - std::move(promise_)); - } - - void on_error(Status status) final { - td_->messages_manager_->on_create_new_dialog_fail(random_id_, std::move(status), std::move(promise_)); - } -}; - -class CreateChannelQuery final : public Td::ResultHandler { - Promise promise_; - int64 random_id_; - - public: - explicit CreateChannelQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(const string &title, bool is_forum, bool is_megagroup, const string &about, const DialogLocation &location, - bool for_import, MessageTtl message_ttl, int64 random_id) { - int32 flags = telegram_api::channels_createChannel::TTL_PERIOD_MASK; - if (is_forum) { - flags |= telegram_api::channels_createChannel::FORUM_MASK; - } else if (is_megagroup) { - flags |= telegram_api::channels_createChannel::MEGAGROUP_MASK; - } else { - flags |= telegram_api::channels_createChannel::BROADCAST_MASK; - } - if (!location.empty()) { - flags |= telegram_api::channels_createChannel::GEO_POINT_MASK; - } - if (for_import) { - flags |= telegram_api::channels_createChannel::FOR_IMPORT_MASK; - } - - random_id_ = random_id; - send_query(G()->net_query_creator().create(telegram_api::channels_createChannel( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, title, about, - location.get_input_geo_point(), location.get_address(), message_ttl.get_input_ttl_period()))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for CreateChannelQuery: " << to_string(ptr); - td_->messages_manager_->on_create_new_dialog_success(random_id_, std::move(ptr), DialogType::Channel, - std::move(promise_)); - } - - void on_error(Status status) final { - td_->messages_manager_->on_create_new_dialog_fail(random_id_, std::move(status), std::move(promise_)); - } -}; - -class CheckHistoryImportQuery final : public Td::ResultHandler { - Promise> promise_; - - public: - explicit CheckHistoryImportQuery(Promise> &&promise) - : promise_(std::move(promise)) { - } - - void send(const string &message_file_head) { - send_query(G()->net_query_creator().create(telegram_api::messages_checkHistoryImport(message_file_head))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for CheckHistoryImportQuery: " << to_string(ptr); - auto file_type = [&]() -> td_api::object_ptr { - if (ptr->pm_) { - return td_api::make_object(ptr->title_); - } else if (ptr->group_) { - return td_api::make_object(ptr->title_); - } else { - return td_api::make_object(); - } - }(); - promise_.set_value(std::move(file_type)); - } - - void on_error(Status status) final { - promise_.set_error(std::move(status)); - } -}; - -class CheckHistoryImportPeerQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - - public: - explicit CheckHistoryImportPeerQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id) { - dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - CHECK(input_peer != nullptr); - send_query(G()->net_query_creator().create(telegram_api::messages_checkHistoryImportPeer(std::move(input_peer)))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for CheckHistoryImportPeerQuery: " << to_string(ptr); - promise_.set_value(std::move(ptr->confirm_text_)); - } - - void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "CheckHistoryImportPeerQuery"); - promise_.set_error(std::move(status)); - } -}; - -class InitHistoryImportQuery final : public Td::ResultHandler { - Promise promise_; - FileId file_id_; - DialogId dialog_id_; - vector attached_file_ids_; - - public: - explicit InitHistoryImportQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, FileId file_id, tl_object_ptr &&input_file, - vector attached_file_ids) { - CHECK(input_file != nullptr); - file_id_ = file_id; - dialog_id_ = dialog_id; - attached_file_ids_ = std::move(attached_file_ids); - - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - CHECK(input_peer != nullptr); - send_query(G()->net_query_creator().create(telegram_api::messages_initHistoryImport( - std::move(input_peer), std::move(input_file), narrow_cast(attached_file_ids_.size())))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - td_->messages_manager_->start_import_messages(dialog_id_, ptr->id_, std::move(attached_file_ids_), - std::move(promise_)); - - td_->file_manager_->delete_partial_remote_location(file_id_); - } - - void on_error(Status status) final { - if (FileReferenceManager::is_file_reference_error(status)) { - LOG(ERROR) << "Receive file reference error " << status; - } - if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) { - // TODO support FILE_PART_*_MISSING - } - - td_->file_manager_->delete_partial_remote_location(file_id_); - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "InitHistoryImportQuery"); - promise_.set_error(std::move(status)); - } -}; - -class UploadImportedMediaQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - int64 import_id_; - FileId file_id_; - - public: - explicit UploadImportedMediaQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, int64 import_id, const string &file_name, FileId file_id, - tl_object_ptr &&input_media) { - CHECK(input_media != nullptr); - dialog_id_ = dialog_id; - import_id_ = import_id; - file_id_ = file_id; - - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - if (input_peer == nullptr) { - return on_error(Status::Error(400, "Can't access the chat")); - } - - send_query(G()->net_query_creator().create(telegram_api::messages_uploadImportedMedia( - std::move(input_peer), import_id, file_name, std::move(input_media)))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - // ignore response - - promise_.set_value(Unit()); - - td_->file_manager_->delete_partial_remote_location(file_id_); - } - - void on_error(Status status) final { - if (FileReferenceManager::is_file_reference_error(status)) { - LOG(ERROR) << "Receive file reference error " << status; - } - if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) { - // TODO support FILE_PART_*_MISSING - } - - td_->file_manager_->delete_partial_remote_location(file_id_); - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "UploadImportedMediaQuery"); - promise_.set_error(std::move(status)); - } -}; - -class StartImportHistoryQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - - public: - explicit StartImportHistoryQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, int64 import_id) { - dialog_id_ = dialog_id; - - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - CHECK(input_peer != nullptr); - - send_query( - G()->net_query_creator().create(telegram_api::messages_startHistoryImport(std::move(input_peer), import_id))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - if (!result_ptr.ok()) { - return on_error(Status::Error(500, "Import history returned false")); - } - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "StartImportHistoryQuery"); - promise_.set_error(std::move(status)); - } -}; - -class EditDialogPhotoQuery final : public Td::ResultHandler { - Promise promise_; - FileId file_id_; - bool was_uploaded_ = false; - string file_reference_; - DialogId dialog_id_; - - public: - explicit EditDialogPhotoQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, FileId file_id, tl_object_ptr &&input_chat_photo) { - CHECK(input_chat_photo != nullptr); - file_id_ = file_id; - was_uploaded_ = FileManager::extract_was_uploaded(input_chat_photo); - file_reference_ = FileManager::extract_file_reference(input_chat_photo); - dialog_id_ = dialog_id; - - switch (dialog_id.get_type()) { - case DialogType::Chat: - send_query(G()->net_query_creator().create( - telegram_api::messages_editChatPhoto(dialog_id.get_chat_id().get(), std::move(input_chat_photo)))); - break; - case DialogType::Channel: { - auto channel_id = dialog_id.get_channel_id(); - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); - CHECK(input_channel != nullptr); - send_query(G()->net_query_creator().create( - telegram_api::channels_editPhoto(std::move(input_channel), std::move(input_chat_photo)))); - break; - } - default: - UNREACHABLE(); - } - } - - void on_result(BufferSlice packet) final { - static_assert(std::is_same::value, - ""); - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for EditDialogPhotoQuery: " << to_string(ptr); - - td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); - - if (file_id_.is_valid() && was_uploaded_) { - td_->file_manager_->delete_partial_remote_location(file_id_); - } - } - - void on_error(Status status) final { - if (file_id_.is_valid() && was_uploaded_) { - td_->file_manager_->delete_partial_remote_location(file_id_); - } - if (!td_->auth_manager_->is_bot() && FileReferenceManager::is_file_reference_error(status)) { - if (file_id_.is_valid() && !was_uploaded_) { - VLOG(file_references) << "Receive " << status << " for " << file_id_; - td_->file_manager_->delete_file_reference(file_id_, file_reference_); - td_->messages_manager_->upload_dialog_photo(dialog_id_, file_id_, false, 0.0, false, std::move(promise_), {-1}); - return; - } else { - LOG(ERROR) << "Receive file reference error, but file_id = " << file_id_ - << ", was_uploaded = " << was_uploaded_; - } - } - - if (status.message() == "CHAT_NOT_MODIFIED") { - if (!td_->auth_manager_->is_bot()) { - promise_.set_value(Unit()); - return; - } - } else { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditDialogPhotoQuery"); - } - promise_.set_error(std::move(status)); - } -}; - -class EditDialogTitleQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - - public: - explicit EditDialogTitleQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, const string &title) { - dialog_id_ = dialog_id; - switch (dialog_id.get_type()) { - case DialogType::Chat: - send_query(G()->net_query_creator().create( - telegram_api::messages_editChatTitle(dialog_id.get_chat_id().get(), title))); - break; - case DialogType::Channel: { - auto channel_id = dialog_id.get_channel_id(); - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); - CHECK(input_channel != nullptr); - send_query(G()->net_query_creator().create(telegram_api::channels_editTitle(std::move(input_channel), title))); - break; - } - default: - UNREACHABLE(); - } - } - - void on_result(BufferSlice packet) final { - static_assert(std::is_same::value, - ""); - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for EditDialogTitleQuery: " << to_string(ptr); - td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); - } - - void on_error(Status status) final { - if (status.message() == "CHAT_NOT_MODIFIED") { - if (!td_->auth_manager_->is_bot()) { - promise_.set_value(Unit()); - return; - } - } else { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditDialogTitleQuery"); - } - promise_.set_error(std::move(status)); - } -}; - class SetChatAvailableReactionsQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; @@ -1221,12 +808,17 @@ class SetChatAvailableReactionsQuery final : public Td::ResultHandler { void send(DialogId dialog_id, const ChatReactions &available_reactions) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } + int32 flags = telegram_api::messages_setChatAvailableReactions::PAID_ENABLED_MASK; + if (available_reactions.reactions_limit_ != 0) { + flags |= telegram_api::messages_setChatAvailableReactions::REACTIONS_LIMIT_MASK; + } send_query(G()->net_query_creator().create(telegram_api::messages_setChatAvailableReactions( - std::move(input_peer), available_reactions.get_input_chat_reactions()))); + flags, std::move(input_peer), available_reactions.get_input_chat_reactions(), + available_reactions.reactions_limit_, available_reactions.paid_reactions_available_))); } void on_result(BufferSlice packet) final { @@ -1247,8 +839,8 @@ class SetChatAvailableReactionsQuery final : public Td::ResultHandler { return; } } else { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SetChatAvailableReactionsQuery"); - td_->messages_manager_->reload_dialog_info_full(dialog_id_, "SetChatAvailableReactionsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SetChatAvailableReactionsQuery"); + td_->dialog_manager_->reload_dialog_info_full(dialog_id_, "SetChatAvailableReactionsQuery"); } promise_.set_error(std::move(status)); } @@ -1264,7 +856,7 @@ class SetChatThemeQuery final : public Td::ResultHandler { void send(DialogId dialog_id, const string &theme_name) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create(telegram_api::messages_setChatTheme(std::move(input_peer), theme_name))); } @@ -1287,7 +879,7 @@ class SetChatThemeQuery final : public Td::ResultHandler { return; } } else { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SetChatThemeQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SetChatThemeQuery"); } promise_.set_error(std::move(status)); } @@ -1304,7 +896,7 @@ class SetHistoryTtlQuery final : public Td::ResultHandler { void send(DialogId dialog_id, int32 period) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create(telegram_api::messages_setHistoryTTL(std::move(input_peer), period))); @@ -1328,85 +920,7 @@ class SetHistoryTtlQuery final : public Td::ResultHandler { return; } } else { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SetHistoryTtlQuery"); - } - promise_.set_error(std::move(status)); - } -}; - -class EditChatDefaultBannedRightsQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - - public: - explicit EditChatDefaultBannedRightsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, RestrictedRights permissions) { - dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); - CHECK(input_peer != nullptr); - send_query(G()->net_query_creator().create(telegram_api::messages_editChatDefaultBannedRights( - std::move(input_peer), permissions.get_chat_banned_rights()))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for EditChatDefaultBannedRightsQuery: " << to_string(ptr); - td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); - } - - void on_error(Status status) final { - if (status.message() == "CHAT_NOT_MODIFIED") { - if (!td_->auth_manager_->is_bot()) { - promise_.set_value(Unit()); - return; - } - } else { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditChatDefaultBannedRightsQuery"); - } - promise_.set_error(std::move(status)); - } -}; - -class ToggleNoForwardsQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - - public: - explicit ToggleNoForwardsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, bool has_protected_content) { - dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); - CHECK(input_peer != nullptr); - send_query(G()->net_query_creator().create( - telegram_api::messages_toggleNoForwards(std::move(input_peer), has_protected_content))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for ToggleNoForwardsQuery: " << to_string(ptr); - td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); - } - - void on_error(Status status) final { - if (status.message() == "CHAT_NOT_MODIFIED") { - promise_.set_value(Unit()); - return; - } else { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ToggleNoForwardsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SetHistoryTtlQuery"); } promise_.set_error(std::move(status)); } @@ -1425,7 +939,7 @@ class ToggleDialogPinQuery final : public Td::ResultHandler { dialog_id_ = dialog_id; is_pinned_ = is_pinned; - auto input_peer = td_->messages_manager_->get_input_dialog_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_dialog_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -1453,7 +967,7 @@ class ToggleDialogPinQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ToggleDialogPinQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ToggleDialogPinQuery")) { LOG(ERROR) << "Receive error for ToggleDialogPinQuery: " << status; } td_->messages_manager_->on_update_pinned_dialogs(FolderId::main()); @@ -1475,7 +989,7 @@ class ReorderPinnedDialogsQuery final : public Td::ResultHandler { int32 flags = telegram_api::messages_reorderPinnedDialogs::FORCE_MASK; send_query(G()->net_query_creator().create(telegram_api::messages_reorderPinnedDialogs( flags, true /*ignored*/, folder_id.get(), - td_->messages_manager_->get_input_dialog_peers(dialog_ids, AccessRights::Read)))); + td_->dialog_manager_->get_input_dialog_peers(dialog_ids, AccessRights::Read)))); } void on_result(BufferSlice packet) final { @@ -1500,6 +1014,48 @@ class ReorderPinnedDialogsQuery final : public Td::ResultHandler { } }; +class ToggleViewForumAsMessagesQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + bool view_as_messages_; + + public: + explicit ToggleViewForumAsMessagesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, bool view_as_messages) { + dialog_id_ = dialog_id; + view_as_messages_ = view_as_messages; + + CHECK(dialog_id.get_type() == DialogType::Channel); + auto input_channel = td_->chat_manager_->get_input_channel(dialog_id.get_channel_id()); + CHECK(input_channel != nullptr); + send_query(G()->net_query_creator().create( + telegram_api::channels_toggleViewForumAsMessages(std::move(input_channel), view_as_messages), {{dialog_id}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for ToggleViewForumAsMessagesQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ToggleViewForumAsMessagesQuery")) { + LOG(ERROR) << "Receive error for ToggleViewForumAsMessagesQuery: " << status; + } + if (!G()->close_flag()) { + td_->messages_manager_->on_update_dialog_view_as_messages(dialog_id_, !view_as_messages_); + } + promise_.set_error(std::move(status)); + } +}; + class ToggleDialogUnreadMarkQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; @@ -1513,7 +1069,7 @@ class ToggleDialogUnreadMarkQuery final : public Td::ResultHandler { dialog_id_ = dialog_id; is_marked_as_unread_ = is_marked_as_unread; - auto input_peer = td_->messages_manager_->get_input_dialog_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_dialog_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -1541,7 +1097,7 @@ class ToggleDialogUnreadMarkQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ToggleDialogUnreadMarkQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ToggleDialogUnreadMarkQuery")) { LOG(ERROR) << "Receive error for ToggleDialogUnreadMarkQuery: " << status; } if (!G()->close_flag()) { @@ -1564,7 +1120,7 @@ class ToggleDialogTranslationsQuery final : public Td::ResultHandler { dialog_id_ = dialog_id; is_translatable_ = is_translatable; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -1592,7 +1148,7 @@ class ToggleDialogTranslationsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ToggleDialogTranslationsQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ToggleDialogTranslationsQuery")) { LOG(ERROR) << "Receive error for ToggleDialogTranslationsQuery: " << status; } if (!G()->close_flag()) { @@ -1605,23 +1161,29 @@ class ToggleDialogTranslationsQuery final : public Td::ResultHandler { class ToggleDialogIsBlockedQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; - bool is_blocked_; public: explicit ToggleDialogIsBlockedQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(DialogId dialog_id, bool is_blocked) { + void send(DialogId dialog_id, bool is_blocked, bool is_blocked_for_stories) { dialog_id_ = dialog_id; - is_blocked_ = is_blocked; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Know); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Know); CHECK(input_peer != nullptr && input_peer->get_id() != telegram_api::inputPeerEmpty::ID); + + int32 flags = 0; + if (is_blocked_for_stories) { + flags |= telegram_api::contacts_block::MY_STORIES_FROM_MASK; + } vector chain_ids{{dialog_id, MessageContentType::Photo}, {dialog_id, MessageContentType::Text}}; - auto query = is_blocked ? G()->net_query_creator().create(telegram_api::contacts_block(std::move(input_peer)), - std::move(chain_ids)) - : G()->net_query_creator().create(telegram_api::contacts_unblock(std::move(input_peer)), - std::move(chain_ids)); + auto query = + is_blocked || is_blocked_for_stories + ? G()->net_query_creator().create( + telegram_api::contacts_block(flags, false /*ignored*/, std::move(input_peer)), std::move(chain_ids)) + : G()->net_query_creator().create( + telegram_api::contacts_unblock(flags, false /*ignored*/, std::move(input_peer)), + std::move(chain_ids)); send_query(std::move(query)); } @@ -1640,12 +1202,11 @@ class ToggleDialogIsBlockedQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ToggleDialogIsBlockedQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ToggleDialogIsBlockedQuery")) { LOG(ERROR) << "Receive error for ToggleDialogIsBlockedQuery: " << status; } if (!G()->close_flag()) { - td_->messages_manager_->on_update_dialog_is_blocked(dialog_id_, !is_blocked_); - td_->messages_manager_->get_dialog_info_full(dialog_id_, Auto(), "ToggleDialogIsBlockedQuery"); + td_->dialog_manager_->get_dialog_info_full(dialog_id_, Auto(), "ToggleDialogIsBlockedQuery"); td_->messages_manager_->reget_dialog_action_bar(dialog_id_, "ToggleDialogIsBlockedQuery"); } promise_.set_error(std::move(status)); @@ -1661,7 +1222,7 @@ class GetMessagesViewsQuery final : public Td::ResultHandler { dialog_id_ = dialog_id; message_ids_ = std::move(message_ids); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -1681,23 +1242,23 @@ class GetMessagesViewsQuery final : public Td::ResultHandler { if (message_ids_.size() != interaction_infos.size()) { return on_error(Status::Error(500, "Wrong number of message views returned")); } - td_->contacts_manager_->on_get_users(std::move(result->users_), "GetMessagesViewsQuery"); - td_->contacts_manager_->on_get_chats(std::move(result->chats_), "GetMessagesViewsQuery"); + td_->user_manager_->on_get_users(std::move(result->users_), "GetMessagesViewsQuery"); + td_->chat_manager_->on_get_chats(std::move(result->chats_), "GetMessagesViewsQuery"); for (size_t i = 0; i < message_ids_.size(); i++) { - FullMessageId full_message_id{dialog_id_, message_ids_[i]}; + MessageFullId message_full_id{dialog_id_, message_ids_[i]}; auto *info = interaction_infos[i].get(); auto flags = info->flags_; auto view_count = (flags & telegram_api::messageViews::VIEWS_MASK) != 0 ? info->views_ : 0; auto forward_count = (flags & telegram_api::messageViews::FORWARDS_MASK) != 0 ? info->forwards_ : 0; - td_->messages_manager_->on_update_message_interaction_info(full_message_id, view_count, forward_count, true, + td_->messages_manager_->on_update_message_interaction_info(message_full_id, view_count, forward_count, true, std::move(info->replies_)); } td_->messages_manager_->finish_get_message_views(dialog_id_, message_ids_); } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetMessagesViewsQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetMessagesViewsQuery")) { LOG(ERROR) << "Receive error for GetMessagesViewsQuery: " << status; } td_->messages_manager_->finish_get_message_views(dialog_id_, message_ids_); @@ -1713,7 +1274,7 @@ class GetExtendedMediaQuery final : public Td::ResultHandler { dialog_id_ = dialog_id; message_ids_ = std::move(message_ids); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -1735,11 +1296,90 @@ class GetExtendedMediaQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetExtendedMediaQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetExtendedMediaQuery"); td_->messages_manager_->finish_get_message_extended_media(dialog_id_, message_ids_); } }; +class GetFactCheckQuery final : public Td::ResultHandler { + Promise>> promise_; + DialogId dialog_id_; + + public: + explicit GetFactCheckQuery(Promise>> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, vector &&message_ids) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + return promise_.set_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::messages_getFactCheck(std::move(input_peer), MessageId::get_server_message_ids(message_ids)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetFactCheckQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetFactCheckQuery"); + promise_.set_error(std::move(status)); + } +}; + +class EditMessageFactCheckQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit EditMessageFactCheckQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, MessageId message_id, const FormattedText &text) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); + CHECK(input_peer != nullptr); + auto server_message_id = message_id.get_server_message_id().get(); + if (text.text.empty()) { + send_query(G()->net_query_creator().create( + telegram_api::messages_deleteFactCheck(std::move(input_peer), server_message_id))); + } else { + send_query(G()->net_query_creator().create(telegram_api::messages_editFactCheck( + std::move(input_peer), server_message_id, + get_input_text_with_entities(td_->user_manager_.get(), text, "messages_editFactCheck")))); + } + } + + void on_result(BufferSlice packet) final { + static_assert(std::is_same::value, + ""); + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for EditMessageFactCheckQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "EditMessageFactCheckQuery"); + promise_.set_error(std::move(status)); + } +}; + class ReadMessagesContentsQuery final : public Td::ResultHandler { Promise promise_; @@ -1759,7 +1399,6 @@ class ReadMessagesContentsQuery final : public Td::ResultHandler { } auto affected_messages = result_ptr.move_as_ok(); - CHECK(affected_messages->get_id() == telegram_api::messages_affectedMessages::ID); LOG(INFO) << "Receive result for ReadMessagesContentsQuery: " << to_string(affected_messages); if (affected_messages->pts_count_ > 0) { @@ -1790,7 +1429,7 @@ class ReadChannelMessagesContentsQuery final : public Td::ResultHandler { void send(ChannelId channel_id, vector &&message_ids) { channel_id_ = channel_id; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { LOG(ERROR) << "Have no input channel for " << channel_id; return on_error(Status::Error(400, "Can't access the chat")); @@ -1815,7 +1454,7 @@ class ReadChannelMessagesContentsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->contacts_manager_->on_get_channel_error(channel_id_, status, "ReadChannelMessagesContentsQuery")) { + if (!td_->chat_manager_->on_get_channel_error(channel_id_, status, "ReadChannelMessagesContentsQuery")) { LOG(ERROR) << "Receive error for read messages contents in " << channel_id_ << ": " << status; } promise_.set_error(std::move(status)); @@ -1823,24 +1462,23 @@ class ReadChannelMessagesContentsQuery final : public Td::ResultHandler { }; class GetDialogMessageByDateQuery final : public Td::ResultHandler { - Promise promise_; + Promise> promise_; DialogId dialog_id_; int32 date_; - int64 random_id_; public: - explicit GetDialogMessageByDateQuery(Promise &&promise) : promise_(std::move(promise)) { + explicit GetDialogMessageByDateQuery(Promise> &&promise) + : promise_(std::move(promise)) { } - void send(DialogId dialog_id, int32 date, int64 random_id) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + void send(DialogId dialog_id, int32 date) { + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Can't access the chat")); } dialog_id_ = dialog_id; date_ = date; - random_id_ = random_id; send_query(G()->net_query_creator().create( telegram_api::messages_getHistory(std::move(input_peer), 0, date, -3, 5, 0, 0, 0))); @@ -1856,24 +1494,23 @@ class GetDialogMessageByDateQuery final : public Td::ResultHandler { td_->messages_manager_->get_channel_difference_if_needed( dialog_id_, std::move(info), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, date = date_, - random_id = random_id_, promise = std::move(promise_)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { auto info = result.move_as_ok(); - send_closure(actor_id, &MessagesManager::on_get_dialog_message_by_date_success, dialog_id, date, random_id, + send_closure(actor_id, &MessagesManager::on_get_dialog_message_by_date, dialog_id, date, std::move(info.messages), std::move(promise)); } - })); + }), + "GetDialogMessageByDateQuery"); } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDialogMessageByDateQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetDialogMessageByDateQuery")) { LOG(ERROR) << "Receive error for GetDialogMessageByDateQuery in " << dialog_id_ << ": " << status; } promise_.set_error(std::move(status)); - td_->messages_manager_->on_get_dialog_message_by_date_fail(random_id_); } }; @@ -1892,7 +1529,7 @@ class GetHistoryQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId from_message_id, MessageId old_last_new_message_id, int32 offset, int32 limit) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Can't access the chat")); } @@ -1909,7 +1546,7 @@ class GetHistoryQuery final : public Td::ResultHandler { } void send_get_from_the_end(DialogId dialog_id, MessageId old_last_new_message_id, int32 limit) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Can't access the chat")); } @@ -1945,11 +1582,12 @@ class GetHistoryQuery final : public Td::ResultHandler { old_last_new_message_id, offset, limit, from_the_end, std::move(info.messages), std::move(promise)); } - })); + }), + "GetHistoryQuery"); } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetHistoryQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetHistoryQuery")) { LOG(ERROR) << "Receive error for GetHistoryQuery in " << dialog_id_ << ": " << status; } promise_.set_error(std::move(status)); @@ -1966,7 +1604,7 @@ class ReadHistoryQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId max_message_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create( telegram_api::messages_readHistory(std::move(input_peer), max_message_id.get_server_message_id().get()), @@ -1980,7 +1618,6 @@ class ReadHistoryQuery final : public Td::ResultHandler { } auto affected_messages = result_ptr.move_as_ok(); - CHECK(affected_messages->get_id() == telegram_api::messages_affectedMessages::ID); LOG(INFO) << "Receive result for ReadHistoryQuery: " << to_string(affected_messages); if (affected_messages->pts_count_ > 0) { @@ -1993,7 +1630,7 @@ class ReadHistoryQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReadHistoryQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ReadHistoryQuery")) { LOG(ERROR) << "Receive error for ReadHistoryQuery: " << status; } promise_.set_error(std::move(status)); @@ -2010,7 +1647,7 @@ class ReadChannelHistoryQuery final : public Td::ResultHandler { void send(ChannelId channel_id, MessageId max_message_id) { channel_id_ = channel_id; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -2030,7 +1667,7 @@ class ReadChannelHistoryQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->contacts_manager_->on_get_channel_error(channel_id_, status, "ReadChannelHistoryQuery")) { + if (!td_->chat_manager_->on_get_channel_error(channel_id_, status, "ReadChannelHistoryQuery")) { LOG(ERROR) << "Receive error for ReadChannelHistoryQuery: " << status; } promise_.set_error(std::move(status)); @@ -2047,7 +1684,7 @@ class ReadDiscussionQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId top_thread_message_id, MessageId max_message_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create( telegram_api::messages_readDiscussion(std::move(input_peer), @@ -2066,33 +1703,43 @@ class ReadDiscussionQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReadDiscussionQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ReadDiscussionQuery"); promise_.set_error(std::move(status)); } }; class GetSearchResultCalendarQuery final : public Td::ResultHandler { - Promise promise_; + Promise> promise_; DialogId dialog_id_; + SavedMessagesTopicId saved_messages_topic_id_; MessageId from_message_id_; MessageSearchFilter filter_; - int64 random_id_; public: - explicit GetSearchResultCalendarQuery(Promise &&promise) : promise_(std::move(promise)) { + explicit GetSearchResultCalendarQuery(Promise> &&promise) + : promise_(std::move(promise)) { } - void send(DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, int64 random_id) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + void send(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, + MessageSearchFilter filter) { + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); dialog_id_ = dialog_id; + saved_messages_topic_id_ = saved_messages_topic_id; from_message_id_ = from_message_id; filter_ = filter; - random_id_ = random_id; + int32 flags = 0; + telegram_api::object_ptr saved_input_peer; + if (saved_messages_topic_id.is_valid()) { + flags |= telegram_api::messages_getSearchResultsCalendar::SAVED_PEER_ID_MASK; + saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + } send_query(G()->net_query_creator().create(telegram_api::messages_getSearchResultsCalendar( - std::move(input_peer), get_input_messages_filter(filter), from_message_id.get_server_message_id().get(), 0))); + flags, std::move(input_peer), std::move(saved_input_peer), get_input_messages_filter(filter), + from_message_id.get_server_message_id().get(), 0))); } void on_result(BufferSlice packet) final { @@ -2103,8 +1750,8 @@ class GetSearchResultCalendarQuery final : public Td::ResultHandler { auto result = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for GetSearchResultCalendarQuery: " << to_string(result); - td_->contacts_manager_->on_get_users(std::move(result->users_), "GetSearchResultCalendarQuery"); - td_->contacts_manager_->on_get_chats(std::move(result->chats_), "GetSearchResultCalendarQuery"); + td_->user_manager_->on_get_users(std::move(result->users_), "GetSearchResultCalendarQuery"); + td_->chat_manager_->on_get_chats(std::move(result->chats_), "GetSearchResultCalendarQuery"); // unused: inexact:flags.0?true min_date:int min_msg_id:int offset_id_offset:flags.1?int @@ -2116,23 +1763,23 @@ class GetSearchResultCalendarQuery final : public Td::ResultHandler { td_->messages_manager_->get_channel_difference_if_needed( dialog_id_, std::move(info), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, - from_message_id = from_message_id_, filter = filter_, random_id = random_id_, - periods = std::move(result->periods_), + saved_messages_topic_id = saved_messages_topic_id_, from_message_id = from_message_id_, + filter = filter_, periods = std::move(result->periods_), promise = std::move(promise_)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { auto info = result.move_as_ok(); - send_closure(actor_id, &MessagesManager::on_get_message_search_result_calendar, dialog_id, from_message_id, - filter, random_id, info.total_count, std::move(info.messages), std::move(periods), - std::move(promise)); + send_closure(actor_id, &MessagesManager::on_get_message_search_result_calendar, dialog_id, + saved_messages_topic_id, from_message_id, filter, info.total_count, std::move(info.messages), + std::move(periods), std::move(promise)); } - })); + }), + "GetSearchResultCalendarQuery"); } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetSearchResultCalendarQuery"); - td_->messages_manager_->on_failed_get_message_search_result_calendar(dialog_id_, random_id_); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetSearchResultCalendarQuery"); promise_.set_error(std::move(status)); } }; @@ -2142,33 +1789,48 @@ class GetMessagePositionQuery final : public Td::ResultHandler { DialogId dialog_id_; MessageId message_id_; MessageId top_thread_message_id_; + SavedMessagesTopicId saved_messages_topic_id_; MessageSearchFilter filter_; public: explicit GetMessagePositionQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(DialogId dialog_id, MessageId message_id, MessageSearchFilter filter, MessageId top_thread_message_id) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + void send(DialogId dialog_id, MessageId message_id, MessageSearchFilter filter, MessageId top_thread_message_id, + SavedMessagesTopicId saved_messages_topic_id) { + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); dialog_id_ = dialog_id; message_id_ = message_id; top_thread_message_id_ = top_thread_message_id; + saved_messages_topic_id_ = saved_messages_topic_id; filter_ = filter; if (filter == MessageSearchFilter::Empty && !top_thread_message_id.is_valid()) { - send_query(G()->net_query_creator().create(telegram_api::messages_getHistory( - std::move(input_peer), message_id.get_server_message_id().get(), 0, -1, 1, 0, 0, 0))); + if (saved_messages_topic_id.is_valid()) { + send_query(G()->net_query_creator().create(telegram_api::messages_getSavedHistory( + saved_messages_topic_id.get_input_peer(td_), message_id.get_server_message_id().get(), 0, -1, 1, 0, 0, 0))); + } else { + send_query(G()->net_query_creator().create(telegram_api::messages_getHistory( + std::move(input_peer), message_id.get_server_message_id().get(), 0, -1, 1, 0, 0, 0))); + } } else { int32 flags = 0; + tl_object_ptr saved_input_peer; + if (saved_messages_topic_id.is_valid()) { + flags |= telegram_api::messages_search::SAVED_PEER_ID_MASK; + saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + } if (top_thread_message_id.is_valid()) { flags |= telegram_api::messages_search::TOP_MSG_ID_MASK; } send_query(G()->net_query_creator().create(telegram_api::messages_search( - flags, std::move(input_peer), string(), nullptr, top_thread_message_id.get_server_message_id().get(), - get_input_messages_filter(filter), 0, std::numeric_limits::max(), - message_id.get_server_message_id().get(), -1, 1, std::numeric_limits::max(), 0, 0))); + flags, std::move(input_peer), string(), nullptr, std::move(saved_input_peer), Auto(), + top_thread_message_id.get_server_message_id().get(), get_input_messages_filter(filter), 0, + std::numeric_limits::max(), message_id.get_server_message_id().get(), -1, 1, + std::numeric_limits::max(), 0, 0))); } } @@ -2197,7 +1859,7 @@ class GetMessagePositionQuery final : public Td::ResultHandler { } if (messages->offset_id_offset_ <= 0) { LOG(ERROR) << "Failed to receive position for " << message_id_ << " in thread of " << top_thread_message_id_ - << " in " << dialog_id_ << " by " << filter_; + << " and in " << saved_messages_topic_id_ << " in " << dialog_id_ << " by " << filter_; return promise_.set_error(Status::Error(400, "Message position is unknown")); } return promise_.set_value(std::move(messages->offset_id_offset_)); @@ -2224,7 +1886,7 @@ class GetMessagePositionQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetMessagePositionQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetMessagePositionQuery"); promise_.set_error(std::move(status)); } }; @@ -2232,6 +1894,7 @@ class GetMessagePositionQuery final : public Td::ResultHandler { class SearchMessagesQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; + SavedMessagesTopicId saved_messages_topic_id_; string query_; DialogId sender_dialog_id_; MessageId from_message_id_; @@ -2239,6 +1902,7 @@ class SearchMessagesQuery final : public Td::ResultHandler { int32 limit_; MessageSearchFilter filter_; MessageId top_thread_message_id_; + ReactionType tag_; int64 random_id_; bool handle_errors_ = true; @@ -2246,13 +1910,14 @@ class SearchMessagesQuery final : public Td::ResultHandler { explicit SearchMessagesQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(DialogId dialog_id, const string &query, DialogId sender_dialog_id, MessageId from_message_id, int32 offset, - int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, int64 random_id) { - auto input_peer = dialog_id.is_valid() ? td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read) - : make_tl_object(); + void send(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, const string &query, + DialogId sender_dialog_id, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, + MessageId top_thread_message_id, const ReactionType &tag, int64 random_id) { + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); dialog_id_ = dialog_id; + saved_messages_topic_id_ = saved_messages_topic_id; query_ = query; sender_dialog_id_ = sender_dialog_id; from_message_id_ = from_message_id; @@ -2260,11 +1925,14 @@ class SearchMessagesQuery final : public Td::ResultHandler { limit_ = limit; filter_ = filter; top_thread_message_id_ = top_thread_message_id; + tag_ = tag; random_id_ = random_id; auto top_msg_id = top_thread_message_id.get_server_message_id().get(); auto offset_id = from_message_id.get_server_message_id().get(); if (filter == MessageSearchFilter::UnreadMention) { + CHECK(!saved_messages_topic_id.is_valid()); + CHECK(tag_.is_empty()); int32 flags = 0; if (top_thread_message_id.is_valid()) { flags |= telegram_api::messages_getUnreadMentions::TOP_MSG_ID_MASK; @@ -2272,6 +1940,8 @@ class SearchMessagesQuery final : public Td::ResultHandler { send_query(G()->net_query_creator().create(telegram_api::messages_getUnreadMentions( flags, std::move(input_peer), top_msg_id, offset_id, offset, limit, std::numeric_limits::max(), 0))); } else if (filter == MessageSearchFilter::UnreadReaction) { + CHECK(!saved_messages_topic_id.is_valid()); + CHECK(tag_.is_empty()); int32 flags = 0; if (top_thread_message_id.is_valid()) { flags |= telegram_api::messages_getUnreadReactions::TOP_MSG_ID_MASK; @@ -2280,8 +1950,10 @@ class SearchMessagesQuery final : public Td::ResultHandler { flags, std::move(input_peer), top_msg_id, offset_id, offset, limit, std::numeric_limits::max(), 0))); } else if (top_thread_message_id.is_valid() && query.empty() && !sender_dialog_id.is_valid() && filter == MessageSearchFilter::Empty) { + CHECK(!saved_messages_topic_id.is_valid()); + CHECK(tag_.is_empty()); handle_errors_ = dialog_id.get_type() != DialogType::Channel || - !td_->contacts_manager_->is_broadcast_channel(dialog_id.get_channel_id()); + !td_->chat_manager_->is_broadcast_channel(dialog_id.get_channel_id()); send_query(G()->net_query_creator().create(telegram_api::messages_getReplies( std::move(input_peer), top_msg_id, offset_id, 0, offset, limit, std::numeric_limits::max(), 0, 0))); } else { @@ -2289,17 +1961,28 @@ class SearchMessagesQuery final : public Td::ResultHandler { tl_object_ptr sender_input_peer; if (sender_dialog_id.is_valid()) { flags |= telegram_api::messages_search::FROM_ID_MASK; - sender_input_peer = td_->messages_manager_->get_input_peer(sender_dialog_id, AccessRights::Know); + sender_input_peer = td_->dialog_manager_->get_input_peer(sender_dialog_id, AccessRights::Know); CHECK(sender_input_peer != nullptr); } + tl_object_ptr saved_input_peer; + if (saved_messages_topic_id.is_valid()) { + flags |= telegram_api::messages_search::SAVED_PEER_ID_MASK; + saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + } + vector> saved_reactions; + if (!tag.is_empty()) { + flags |= telegram_api::messages_search::SAVED_REACTION_MASK; + saved_reactions.push_back(tag.get_input_reaction()); + } if (top_thread_message_id.is_valid()) { flags |= telegram_api::messages_search::TOP_MSG_ID_MASK; } - send_query(G()->net_query_creator().create( - telegram_api::messages_search(flags, std::move(input_peer), query, std::move(sender_input_peer), top_msg_id, - get_input_messages_filter(filter), 0, std::numeric_limits::max(), - offset_id, offset, limit, std::numeric_limits::max(), 0, 0))); + send_query(G()->net_query_creator().create(telegram_api::messages_search( + flags, std::move(input_peer), query, std::move(sender_input_peer), std::move(saved_input_peer), + std::move(saved_reactions), top_msg_id, get_input_messages_filter(filter), 0, + std::numeric_limits::max(), offset_id, offset, limit, std::numeric_limits::max(), 0, 0))); } } @@ -2321,27 +2004,81 @@ class SearchMessagesQuery final : public Td::ResultHandler { auto info = get_messages_info(td_, dialog_id_, result_ptr.move_as_ok(), "SearchMessagesQuery"); td_->messages_manager_->get_channel_difference_if_needed( dialog_id_, std::move(info), - PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, - query = std::move(query_), sender_dialog_id = sender_dialog_id_, - from_message_id = from_message_id_, offset = offset_, limit = limit_, filter = filter_, - top_thread_message_id = top_thread_message_id_, random_id = random_id_, + PromiseCreator::lambda( + [actor_id = td_->messages_manager_actor_.get(), dialog_id = dialog_id_, + saved_messages_topic_id = saved_messages_topic_id_, query = std::move(query_), + sender_dialog_id = sender_dialog_id_, from_message_id = from_message_id_, offset = offset_, limit = limit_, + filter = filter_, top_thread_message_id = top_thread_message_id_, tag = std::move(tag_), + random_id = random_id_, promise = std::move(promise_)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + auto info = result.move_as_ok(); + send_closure(actor_id, &MessagesManager::on_get_dialog_messages_search_result, dialog_id, + saved_messages_topic_id, query, sender_dialog_id, from_message_id, offset, limit, filter, + top_thread_message_id, tag, random_id, info.total_count, std::move(info.messages), + std::move(promise)); + } + }), + "SearchMessagesQuery"); + } + + void on_error(Status status) final { + if (handle_errors_) { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SearchMessagesQuery"); + } + td_->messages_manager_->on_failed_dialog_messages_search(dialog_id_, random_id_); + promise_.set_error(std::move(status)); + } +}; + +class SearchCallMessagesQuery final : public Td::ResultHandler { + Promise> promise_; + MessageId from_message_id_; + int32 limit_; + MessageSearchFilter filter_; + + public: + explicit SearchCallMessagesQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(MessageId from_message_id, int32 limit, MessageSearchFilter filter) { + from_message_id_ = from_message_id; + limit_ = limit; + filter_ = filter; + + auto offset_id = from_message_id.get_server_message_id().get(); + send_query(G()->net_query_creator().create(telegram_api::messages_search( + 0, telegram_api::make_object(), string(), nullptr, nullptr, + vector>(), 0, get_input_messages_filter(filter), 0, + std::numeric_limits::max(), offset_id, 0, limit, std::numeric_limits::max(), 0, 0))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto info = get_messages_info(td_, DialogId(), result_ptr.move_as_ok(), "SearchCallMessagesQuery"); + td_->messages_manager_->get_channel_differences_if_needed( + std::move(info), + PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), from_message_id = from_message_id_, + limit = limit_, filter = filter_, promise = std::move(promise_)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { auto info = result.move_as_ok(); - send_closure(actor_id, &MessagesManager::on_get_dialog_messages_search_result, dialog_id, query, - sender_dialog_id, from_message_id, offset, limit, filter, top_thread_message_id, random_id, + send_closure(actor_id, &MessagesManager::on_get_call_messages, from_message_id, limit, filter, info.total_count, std::move(info.messages), std::move(promise)); } - })); + }), + "SearchCallMessagesQuery"); } void on_error(Status status) final { - if (handle_errors_) { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SearchMessagesQuery"); - } - td_->messages_manager_->on_failed_dialog_messages_search(dialog_id_, random_id_); promise_.set_error(std::move(status)); } }; @@ -2349,6 +2086,7 @@ class SearchMessagesQuery final : public Td::ResultHandler { class GetSearchResultPositionsQuery final : public Td::ResultHandler { Promise> promise_; DialogId dialog_id_; + SavedMessagesTopicId saved_messages_topic_id_; MessageSearchFilter filter_; public: @@ -2356,17 +2094,26 @@ class GetSearchResultPositionsQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(DialogId dialog_id, MessageSearchFilter filter, MessageId from_message_id, int32 limit) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + void send(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageSearchFilter filter, + MessageId from_message_id, int32 limit) { + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Can't access the chat")); } dialog_id_ = dialog_id; + saved_messages_topic_id_ = saved_messages_topic_id; filter_ = filter; - send_query(G()->net_query_creator().create( - telegram_api::messages_getSearchResultsPositions(std::move(input_peer), get_input_messages_filter(filter), - from_message_id.get_server_message_id().get(), limit))); + int32 flags = 0; + telegram_api::object_ptr saved_input_peer; + if (saved_messages_topic_id.is_valid()) { + flags |= telegram_api::messages_getSearchResultsPositions::SAVED_PEER_ID_MASK; + saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + } + send_query(G()->net_query_creator().create(telegram_api::messages_getSearchResultsPositions( + flags, std::move(input_peer), std::move(saved_input_peer), get_input_messages_filter(filter), + from_message_id.get_server_message_id().get(), limit))); } void on_result(BufferSlice packet) final { @@ -2375,12 +2122,12 @@ class GetSearchResultPositionsQuery final : public Td::ResultHandler { return on_error(result_ptr.move_as_error()); } - td_->messages_manager_->on_get_dialog_sparse_message_positions(dialog_id_, filter_, result_ptr.move_as_ok(), - std::move(promise_)); + td_->messages_manager_->on_get_dialog_sparse_message_positions(dialog_id_, saved_messages_topic_id_, filter_, + result_ptr.move_as_ok(), std::move(promise_)); } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetSearchResultPositionsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetSearchResultPositionsQuery"); promise_.set_error(std::move(status)); } }; @@ -2388,19 +2135,21 @@ class GetSearchResultPositionsQuery final : public Td::ResultHandler { class GetSearchCountersQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; + SavedMessagesTopicId saved_messages_topic_id_; MessageSearchFilter filter_; public: explicit GetSearchCountersQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(DialogId dialog_id, MessageSearchFilter filter) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + void send(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageSearchFilter filter) { + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Can't access the chat")); } dialog_id_ = dialog_id; + saved_messages_topic_id_ = saved_messages_topic_id; filter_ = filter; CHECK(filter != MessageSearchFilter::Empty); @@ -2411,8 +2160,14 @@ class GetSearchCountersQuery final : public Td::ResultHandler { filters.push_back(get_input_messages_filter(filter)); int32 flags = 0; - send_query(G()->net_query_creator().create( - telegram_api::messages_getSearchCounters(flags, std::move(input_peer), 0, std::move(filters)))); + telegram_api::object_ptr saved_input_peer; + if (saved_messages_topic_id.is_valid()) { + flags |= telegram_api::messages_getSearchCounters::SAVED_PEER_ID_MASK; + saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + } + send_query(G()->net_query_creator().create(telegram_api::messages_getSearchCounters( + flags, std::move(input_peer), std::move(saved_input_peer), 0, std::move(filters)))); } void on_result(BufferSlice packet) final { @@ -2428,17 +2183,18 @@ class GetSearchCountersQuery final : public Td::ResultHandler { return on_error(Status::Error(500, "Receive wrong response")); } - td_->messages_manager_->on_get_dialog_message_count(dialog_id_, filter_, result[0]->count_, std::move(promise_)); + td_->messages_manager_->on_get_dialog_message_count(dialog_id_, saved_messages_topic_id_, filter_, + result[0]->count_, std::move(promise_)); } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetSearchCountersQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetSearchCountersQuery"); promise_.set_error(std::move(status)); } }; class SearchMessagesGlobalQuery final : public Td::ResultHandler { - Promise promise_; + Promise> promise_; string query_; int32 offset_date_; DialogId offset_dialog_id_; @@ -2447,35 +2203,37 @@ class SearchMessagesGlobalQuery final : public Td::ResultHandler { MessageSearchFilter filter_; int32 min_date_; int32 max_date_; - int64 random_id_; public: - explicit SearchMessagesGlobalQuery(Promise &&promise) : promise_(std::move(promise)) { + explicit SearchMessagesGlobalQuery(Promise> &&promise) + : promise_(std::move(promise)) { } - void send(FolderId folder_id, bool ignore_folder_id, const string &query, int32 offset_date, + void send(FolderId folder_id, bool ignore_folder_id, bool broadcasts_only, const string &query, int32 offset_date, DialogId offset_dialog_id, MessageId offset_message_id, int32 limit, MessageSearchFilter filter, - int32 min_date, int32 max_date, int64 random_id) { + int32 min_date, int32 max_date) { query_ = query; offset_date_ = offset_date; offset_dialog_id_ = offset_dialog_id; offset_message_id_ = offset_message_id; limit_ = limit; - random_id_ = random_id; filter_ = filter; min_date_ = min_date; max_date_ = max_date; - auto input_peer = MessagesManager::get_input_peer_force(offset_dialog_id); + auto input_peer = DialogManager::get_input_peer_force(offset_dialog_id); CHECK(input_peer != nullptr); int32 flags = 0; if (!ignore_folder_id) { flags |= telegram_api::messages_searchGlobal::FOLDER_ID_MASK; } + if (broadcasts_only) { + flags |= telegram_api::messages_searchGlobal::BROADCASTS_ONLY_MASK; + } send_query(G()->net_query_creator().create(telegram_api::messages_searchGlobal( - flags, folder_id.get(), query, get_input_messages_filter(filter), min_date_, max_date_, offset_date_, - std::move(input_peer), offset_message_id.get_server_message_id().get(), limit))); + flags, false /*ignored*/, folder_id.get(), query, get_input_messages_filter(filter), min_date_, max_date_, + offset_date_, std::move(input_peer), offset_message_id.get_server_message_id().get(), limit))); } void on_result(BufferSlice packet) final { @@ -2490,21 +2248,78 @@ class SearchMessagesGlobalQuery final : public Td::ResultHandler { PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), query = std::move(query_), offset_date = offset_date_, offset_dialog_id = offset_dialog_id_, offset_message_id = offset_message_id_, limit = limit_, filter = std::move(filter_), - min_date = min_date_, max_date = max_date_, random_id = random_id_, + min_date = min_date_, max_date = max_date_, promise = std::move(promise_)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { auto info = result.move_as_ok(); send_closure(actor_id, &MessagesManager::on_get_messages_search_result, query, offset_date, - offset_dialog_id, offset_message_id, limit, filter, min_date, max_date, random_id, + offset_dialog_id, offset_message_id, limit, filter, min_date, max_date, info.total_count, + std::move(info.messages), info.next_rate, std::move(promise)); + } + }), + "SearchMessagesGlobalQuery"); + } + + void on_error(Status status) final { + if (status.message() == "SEARCH_QUERY_EMPTY") { + return promise_.set_value(td_->messages_manager_->get_found_messages_object({}, "SearchMessagesGlobalQuery")); + } + promise_.set_error(std::move(status)); + } +}; + +class SearchPostsQuery final : public Td::ResultHandler { + Promise> promise_; + string hashtag_; + MessageSearchOffset offset_; + int32 limit_; + + public: + explicit SearchPostsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(const string &hashtag, MessageSearchOffset offset, int32 limit) { + hashtag_ = hashtag; + offset_ = offset; + limit_ = limit; + + auto input_peer = DialogManager::get_input_peer_force(offset.dialog_id_); + CHECK(input_peer != nullptr); + + send_query(G()->net_query_creator().create(telegram_api::channels_searchPosts( + hashtag, offset.date_, std::move(input_peer), offset.message_id_.get_server_message_id().get(), limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto info = get_messages_info(td_, DialogId(), result_ptr.move_as_ok(), "SearchPostsQuery"); + td_->messages_manager_->get_channel_differences_if_needed( + std::move(info), + PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), hashtag = std::move(hashtag_), + offset = offset_, limit = limit_, + promise = std::move(promise_)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + auto info = result.move_as_ok(); + send_closure(actor_id, &MessagesManager::on_get_hashtag_search_result, hashtag, offset, limit, info.total_count, std::move(info.messages), info.next_rate, std::move(promise)); } - })); + }), + "SearchPostsQuery"); } void on_error(Status status) final { - td_->messages_manager_->on_failed_messages_search(random_id_); + if (status.message() == "SEARCH_QUERY_EMPTY") { + return promise_.set_value(td_->messages_manager_->get_found_messages_object({}, "SearchPostsQuery")); + } promise_.set_error(std::move(status)); } }; @@ -2519,7 +2334,7 @@ class GetAllScheduledMessagesQuery final : public Td::ResultHandler { } void send(DialogId dialog_id, int64 hash, uint32 generation) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); dialog_id_ = dialog_id; @@ -2547,7 +2362,7 @@ class GetAllScheduledMessagesQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetAllScheduledMessagesQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetAllScheduledMessagesQuery"); promise_.set_error(std::move(status)); } }; @@ -2573,8 +2388,9 @@ class SearchSentMediaQuery final : public Td::ResultHandler { auto info = get_messages_info(td_, DialogId(), result_ptr.move_as_ok(), "SearchSentMediaQuery"); td_->messages_manager_->get_channel_differences_if_needed( - std::move(info), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), - promise = std::move(promise_)](Result &&result) mutable { + std::move(info), + PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), + promise = std::move(promise_)](Result &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { @@ -2582,7 +2398,8 @@ class SearchSentMediaQuery final : public Td::ResultHandler { send_closure(actor_id, &MessagesManager::on_get_outgoing_document_messages, std::move(info.messages), std::move(promise)); } - })); + }), + "SearchSentMediaQuery"); } void on_error(Status status) final { @@ -2601,7 +2418,7 @@ class GetRecentLocationsQuery final : public Td::ResultHandler { } void send(DialogId dialog_id, int32 limit) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Chat is not accessible")); } @@ -2631,65 +2448,12 @@ class GetRecentLocationsQuery final : public Td::ResultHandler { send_closure(actor_id, &MessagesManager::on_get_recent_locations, dialog_id, limit, info.total_count, std::move(info.messages), std::move(promise)); } - })); + }), + "GetRecentLocationsQuery"); } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetRecentLocationsQuery"); - promise_.set_error(std::move(status)); - } -}; - -class GetMessagePublicForwardsQuery final : public Td::ResultHandler { - Promise> promise_; - DialogId dialog_id_; - int32 limit_; - - public: - explicit GetMessagePublicForwardsQuery(Promise> &&promise) - : promise_(std::move(promise)) { - } - - void send(DcId dc_id, FullMessageId full_message_id, int32 offset_date, DialogId offset_dialog_id, - ServerMessageId offset_message_id, int32 limit) { - dialog_id_ = full_message_id.get_dialog_id(); - limit_ = limit; - - auto input_peer = MessagesManager::get_input_peer_force(offset_dialog_id); - CHECK(input_peer != nullptr); - - auto input_channel = td_->contacts_manager_->get_input_channel(dialog_id_.get_channel_id()); - CHECK(input_channel != nullptr); - - send_query(G()->net_query_creator().create( - telegram_api::stats_getMessagePublicForwards( - std::move(input_channel), full_message_id.get_message_id().get_server_message_id().get(), offset_date, - std::move(input_peer), offset_message_id.get(), limit), - {}, dc_id)); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto info = get_messages_info(td_, DialogId(), result_ptr.move_as_ok(), "GetMessagePublicForwardsQuery"); - td_->messages_manager_->get_channel_differences_if_needed( - std::move(info), PromiseCreator::lambda([actor_id = td_->messages_manager_actor_.get(), - promise = std::move(promise_)](Result &&result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - auto info = result.move_as_ok(); - send_closure(actor_id, &MessagesManager::on_get_message_public_forwards, info.total_count, - std::move(info.messages), info.next_rate, std::move(promise)); - } - })); - } - - void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetMessagePublicForwardsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetRecentLocationsQuery"); promise_.set_error(std::move(status)); } }; @@ -2700,7 +2464,7 @@ class HidePromoDataQuery final : public Td::ResultHandler { public: void send(DialogId dialog_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create(telegram_api::help_hidePromoData(std::move(input_peer)))); } @@ -2715,7 +2479,7 @@ class HidePromoDataQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "HidePromoDataQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "HidePromoDataQuery")) { LOG(ERROR) << "Receive error for sponsored chat hiding: " << status; } } @@ -2732,7 +2496,7 @@ class DeleteHistoryQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId max_message_id, bool remove_from_dialog_list, bool revoke) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Chat is not accessible")); } @@ -2760,7 +2524,7 @@ class DeleteHistoryQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "DeleteHistoryQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "DeleteHistoryQuery"); promise_.set_error(std::move(status)); } }; @@ -2768,6 +2532,7 @@ class DeleteHistoryQuery final : public Td::ResultHandler { class DeleteTopicHistoryQuery final : public Td::ResultHandler { Promise promise_; ChannelId channel_id_; + MessageId top_thread_message_id_; public: explicit DeleteTopicHistoryQuery(Promise &&promise) : promise_(std::move(promise)) { @@ -2776,8 +2541,9 @@ class DeleteTopicHistoryQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId top_thread_message_id) { CHECK(dialog_id.get_type() == DialogType::Channel); channel_id_ = dialog_id.get_channel_id(); + top_thread_message_id_ = top_thread_message_id; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id_); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id_); if (input_channel == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -2796,7 +2562,8 @@ class DeleteTopicHistoryQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->contacts_manager_->on_get_channel_error(channel_id_, status, "DeleteTopicHistoryQuery"); + td_->messages_manager_->on_get_message_error(DialogId(channel_id_), top_thread_message_id_, status, + "DeleteTopicHistoryQuery"); promise_.set_error(std::move(status)); } }; @@ -2815,7 +2582,7 @@ class DeleteChannelHistoryQuery final : public Td::ResultHandler { channel_id_ = channel_id; max_message_id_ = max_message_id; allow_error_ = allow_error; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -2841,7 +2608,7 @@ class DeleteChannelHistoryQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->contacts_manager_->on_get_channel_error(channel_id_, status, "DeleteChannelHistoryQuery")) { + if (!td_->chat_manager_->on_get_channel_error(channel_id_, status, "DeleteChannelHistoryQuery")) { LOG(ERROR) << "Receive error for DeleteChannelHistoryQuery: " << status; } promise_.set_error(std::move(status)); @@ -2859,7 +2626,7 @@ class DeleteMessagesByDateQuery final : public Td::ResultHandler { void send(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Chat is not accessible")); } @@ -2885,7 +2652,7 @@ class DeleteMessagesByDateQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "DeleteMessagesByDateQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "DeleteMessagesByDateQuery"); promise_.set_error(std::move(status)); } }; @@ -2976,11 +2743,11 @@ class DeleteParticipantHistoryQuery final : public Td::ResultHandler { channel_id_ = channel_id; sender_dialog_id_ = sender_dialog_id; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return promise_.set_error(Status::Error(400, "Chat is not accessible")); } - auto input_peer = td_->messages_manager_->get_input_peer(sender_dialog_id, AccessRights::Know); + auto input_peer = td_->dialog_manager_->get_input_peer(sender_dialog_id, AccessRights::Know); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Message sender is not accessible")); } @@ -3000,7 +2767,7 @@ class DeleteParticipantHistoryQuery final : public Td::ResultHandler { void on_error(Status status) final { if (sender_dialog_id_.get_type() != DialogType::Channel) { - td_->contacts_manager_->on_get_channel_error(channel_id_, status, "DeleteParticipantHistoryQuery"); + td_->chat_manager_->on_get_channel_error(channel_id_, status, "DeleteParticipantHistoryQuery"); } promise_.set_error(std::move(status)); } @@ -3017,7 +2784,7 @@ class ReadMentionsQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId top_thread_message_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Chat is not accessible")); } @@ -3042,7 +2809,7 @@ class ReadMentionsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReadMentionsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ReadMentionsQuery"); promise_.set_error(std::move(status)); } }; @@ -3058,7 +2825,7 @@ class ReadReactionsQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId top_thread_message_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_error(Status::Error(400, "Chat is not accessible")); } @@ -3083,7 +2850,7 @@ class ReadReactionsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReadReactionsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ReadReactionsQuery"); promise_.set_error(std::move(status)); } }; @@ -3096,10 +2863,10 @@ class SaveDefaultSendAsQuery final : public Td::ResultHandler { } void send(DialogId dialog_id, DialogId send_as_dialog_id) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); - auto send_as_input_peer = td_->messages_manager_->get_input_peer(send_as_dialog_id, AccessRights::Read); + auto send_as_input_peer = td_->dialog_manager_->get_input_peer(send_as_dialog_id, AccessRights::Read); CHECK(send_as_input_peer != nullptr); send_query(G()->net_query_creator().create( @@ -3120,7 +2887,7 @@ class SaveDefaultSendAsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - // td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SaveDefaultSendAsQuery"); + // td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SaveDefaultSendAsQuery"); promise_.set_error(std::move(status)); } }; @@ -3131,18 +2898,23 @@ class SendMessageQuery final : public Td::ResultHandler { public: void send(int32 flags, DialogId dialog_id, tl_object_ptr as_input_peer, - MessageId reply_to_message_id, MessageId top_thread_message_id, int32 schedule_date, - tl_object_ptr &&reply_markup, + const MessageInputReplyTo &input_reply_to, MessageId top_thread_message_id, int32 schedule_date, + MessageEffectId effect_id, tl_object_ptr &&reply_markup, vector> &&entities, const string &text, bool is_copy, int64 random_id, NetQueryRef *send_query_ref) { random_id_ = random_id; dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { return on_error(Status::Error(400, "Have no write access to the chat")); } + auto reply_to = input_reply_to.get_input_reply_to(td_, top_thread_message_id); + + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendMessage::REPLY_TO_MASK; + } if (!entities.empty()) { flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_ENTITIES; } @@ -3150,14 +2922,12 @@ class SendMessageQuery final : public Td::ResultHandler { flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_SEND_AS; } - CHECK(reply_to_message_id == MessageId() || reply_to_message_id.is_server()); - CHECK(top_thread_message_id == MessageId() || top_thread_message_id.is_server()); auto query = G()->net_query_creator().create( - telegram_api::messages_sendMessage( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, std::move(input_peer), reply_to_message_id.get_server_message_id().get(), - top_thread_message_id.get_server_message_id().get(), text, random_id, std::move(reply_markup), - std::move(entities), schedule_date, std::move(as_input_peer)), + telegram_api::messages_sendMessage(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + std::move(input_peer), std::move(reply_to), text, random_id, + std::move(reply_markup), std::move(entities), schedule_date, + std::move(as_input_peer), nullptr, effect_id.get()), {{dialog_id, MessageContentType::Text}, {dialog_id, is_copy ? MessageContentType::Photo : MessageContentType::Text}}); if (td_->option_manager_->get_option_boolean("use_quick_ack")) { @@ -3206,10 +2976,10 @@ class SendMessageQuery final : public Td::ResultHandler { void on_error(Status status) final { LOG(INFO) << "Receive error for SendMessage: " << status; if (G()->close_flag() && G()->use_message_database()) { - // do not send error, message will be re-sent + // do not send error, message will be re-sent after restart return; } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendMessageQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendMessageQuery"); td_->messages_manager_->on_send_message_fail(random_id_, std::move(status)); } }; @@ -3257,10 +3027,10 @@ class StartBotQuery final : public Td::ResultHandler { void on_error(Status status) final { LOG(INFO) << "Receive error for StartBotQuery: " << status; if (G()->close_flag() && G()->use_message_database()) { - // do not send error, message should be re-sent + // do not send error, message should be re-sent after restart return; } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "StartBotQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "StartBotQuery"); td_->messages_manager_->on_send_message_fail(random_id_, std::move(status)); } }; @@ -3271,25 +3041,27 @@ class SendInlineBotResultQuery final : public Td::ResultHandler { public: NetQueryRef send(int32 flags, DialogId dialog_id, tl_object_ptr as_input_peer, - MessageId reply_to_message_id, MessageId top_thread_message_id, int32 schedule_date, int64 random_id, - int64 query_id, const string &result_id) { + const MessageInputReplyTo &input_reply_to, MessageId top_thread_message_id, int32 schedule_date, + int64 random_id, int64 query_id, const string &result_id) { random_id_ = random_id; dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); CHECK(input_peer != nullptr); + auto reply_to = input_reply_to.get_input_reply_to(td_, top_thread_message_id); + + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendInlineBotResult::REPLY_TO_MASK; + } if (as_input_peer != nullptr) { flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_SEND_AS; } - CHECK(reply_to_message_id == MessageId() || reply_to_message_id.is_server()); - CHECK(top_thread_message_id == MessageId() || top_thread_message_id.is_server()); auto query = G()->net_query_creator().create( telegram_api::messages_sendInlineBotResult( flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_peer), - reply_to_message_id.get_server_message_id().get(), top_thread_message_id.get_server_message_id().get(), - random_id, query_id, result_id, schedule_date, std::move(as_input_peer)), + std::move(reply_to), random_id, query_id, result_id, schedule_date, std::move(as_input_peer), nullptr), {{dialog_id, MessageContentType::Text}, {dialog_id, MessageContentType::Photo}}); auto send_query_ref = query.get_weak(); send_query(std::move(query)); @@ -3311,10 +3083,10 @@ class SendInlineBotResultQuery final : public Td::ResultHandler { void on_error(Status status) final { LOG(INFO) << "Receive error for SendInlineBotResultQuery: " << status; if (G()->close_flag() && G()->use_message_database()) { - // do not send error, message will be re-sent + // do not send error, message will be re-sent after restart return; } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendInlineBotResultQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendInlineBotResultQuery"); td_->messages_manager_->on_send_message_fail(random_id_, std::move(status)); } }; @@ -3327,9 +3099,9 @@ class SendMultiMediaQuery final : public Td::ResultHandler { public: void send(int32 flags, DialogId dialog_id, tl_object_ptr as_input_peer, - MessageId reply_to_message_id, MessageId top_thread_message_id, int32 schedule_date, - vector &&file_ids, vector> &&input_single_media, - bool is_copy) { + const MessageInputReplyTo &input_reply_to, MessageId top_thread_message_id, int32 schedule_date, + MessageEffectId effect_id, vector &&file_ids, + vector> &&input_single_media, bool is_copy) { for (auto &single_media : input_single_media) { random_ids_.push_back(single_media->random_id_); CHECK(FileManager::extract_was_uploaded(single_media->media_) == false); @@ -3339,24 +3111,26 @@ class SendMultiMediaQuery final : public Td::ResultHandler { file_ids_ = std::move(file_ids); CHECK(file_ids_.size() == random_ids_.size()); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { return on_error(Status::Error(400, "Have no write access to the chat")); } + auto reply_to = input_reply_to.get_input_reply_to(td_, top_thread_message_id); + + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendMultiMedia::REPLY_TO_MASK; + } if (as_input_peer != nullptr) { flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_SEND_AS; } // no quick ack, because file reference errors are very likely to happen - CHECK(reply_to_message_id == MessageId() || reply_to_message_id.is_server()); - CHECK(top_thread_message_id == MessageId() || top_thread_message_id.is_server()); send_query(G()->net_query_creator().create( telegram_api::messages_sendMultiMedia(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, std::move(input_peer), - reply_to_message_id.get_server_message_id().get(), - top_thread_message_id.get_server_message_id().get(), - std::move(input_single_media), schedule_date, std::move(as_input_peer)), + false /*ignored*/, false /*ignored*/, false /*ignored*/, + std::move(input_peer), std::move(reply_to), std::move(input_single_media), + schedule_date, std::move(as_input_peer), nullptr, effect_id.get()), {{dialog_id, is_copy ? MessageContentType::Text : MessageContentType::Photo}, {dialog_id, MessageContentType::Photo}})); } @@ -3408,11 +3182,11 @@ class SendMultiMediaQuery final : public Td::ResultHandler { } void on_error(Status status) final { - LOG(INFO) << "Receive error for SendMultiMedia: " << status; if (G()->close_flag() && G()->use_message_database()) { - // do not send error, message will be re-sent + // do not send error, message will be re-sent after restart return; } + LOG(INFO) << "Receive error for SendMultiMedia: " << status; if (!td_->auth_manager_->is_bot() && FileReferenceManager::is_file_reference_error(status)) { auto pos = FileReferenceManager::get_file_reference_error_pos(status); if (1 <= pos && pos <= file_ids_.size() && file_ids_[pos - 1].is_valid()) { @@ -3425,7 +3199,7 @@ class SendMultiMediaQuery final : public Td::ResultHandler { << ", message_count = " << file_ids_.size(); } } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendMultiMediaQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendMultiMediaQuery"); for (auto &random_id : random_ids_) { td_->messages_manager_->on_send_message_fail(random_id, status.clone()); } @@ -3434,34 +3208,39 @@ class SendMultiMediaQuery final : public Td::ResultHandler { class SendMediaQuery final : public Td::ResultHandler { int64 random_id_ = 0; - FileId file_id_; - FileId thumbnail_file_id_; + vector file_ids_; + vector thumbnail_file_ids_; DialogId dialog_id_; - string file_reference_; + vector file_references_; bool was_uploaded_ = false; bool was_thumbnail_uploaded_ = false; public: - void send(FileId file_id, FileId thumbnail_file_id, int32 flags, DialogId dialog_id, - tl_object_ptr as_input_peer, MessageId reply_to_message_id, - MessageId top_thread_message_id, int32 schedule_date, + void send(vector file_ids, vector thumbnail_file_ids, int32 flags, DialogId dialog_id, + tl_object_ptr as_input_peer, const MessageInputReplyTo &input_reply_to, + MessageId top_thread_message_id, int32 schedule_date, MessageEffectId effect_id, tl_object_ptr &&reply_markup, vector> &&entities, const string &text, tl_object_ptr &&input_media, MessageContentType content_type, bool is_copy, int64 random_id, NetQueryRef *send_query_ref) { random_id_ = random_id; - file_id_ = file_id; - thumbnail_file_id_ = thumbnail_file_id; + file_ids_ = std::move(file_ids); + thumbnail_file_ids_ = std::move(thumbnail_file_ids); dialog_id_ = dialog_id; - file_reference_ = FileManager::extract_file_reference(input_media); + file_references_ = FileManager::extract_file_references(input_media); was_uploaded_ = FileManager::extract_was_uploaded(input_media); was_thumbnail_uploaded_ = FileManager::extract_was_thumbnail_uploaded(input_media); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { return on_error(Status::Error(400, "Have no write access to the chat")); } + auto reply_to = input_reply_to.get_input_reply_to(td_, top_thread_message_id); + + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendMedia::REPLY_TO_MASK; + } if (!entities.empty()) { flags |= telegram_api::messages_sendMedia::ENTITIES_MASK; } @@ -3469,14 +3248,12 @@ class SendMediaQuery final : public Td::ResultHandler { flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_SEND_AS; } - CHECK(reply_to_message_id == MessageId() || reply_to_message_id.is_server()); - CHECK(top_thread_message_id == MessageId() || top_thread_message_id.is_server()); auto query = G()->net_query_creator().create( - telegram_api::messages_sendMedia( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - std::move(input_peer), reply_to_message_id.get_server_message_id().get(), - top_thread_message_id.get_server_message_id().get(), std::move(input_media), text, random_id, - std::move(reply_markup), std::move(entities), schedule_date, std::move(as_input_peer)), + telegram_api::messages_sendMedia(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_peer), + std::move(reply_to), std::move(input_media), text, random_id, + std::move(reply_markup), std::move(entities), schedule_date, + std::move(as_input_peer), nullptr, effect_id.get()), {{dialog_id, content_type}, {dialog_id, is_copy ? MessageContentType::Text : content_type}}); if (td_->option_manager_->get_option_boolean("use_quick_ack") && was_uploaded_) { query->quick_ack_promise_ = PromiseCreator::lambda([random_id](Result result) { @@ -3501,48 +3278,53 @@ class SendMediaQuery final : public Td::ResultHandler { td_->updates_manager_->on_get_updates(std::move(ptr), Promise()); if (was_thumbnail_uploaded_) { - CHECK(thumbnail_file_id_.is_valid()); + CHECK(thumbnail_file_ids_.size() == 1u); + CHECK(thumbnail_file_ids_[0].is_valid()); // always delete partial remote location for the thumbnail, because it can't be reused anyway - td_->file_manager_->delete_partial_remote_location(thumbnail_file_id_); + td_->file_manager_->delete_partial_remote_location(thumbnail_file_ids_[0]); } } void on_error(Status status) final { LOG(INFO) << "Receive error for SendMedia: " << status; if (G()->close_flag() && G()->use_message_database()) { - // do not send error, message will be re-sent + // do not send error, message will be re-sent after restart return; } if (was_uploaded_) { if (was_thumbnail_uploaded_) { - CHECK(thumbnail_file_id_.is_valid()); + CHECK(thumbnail_file_ids_.size() == 1u); + CHECK(thumbnail_file_ids_[0].is_valid()); // always delete partial remote location for the thumbnail, because it can't be reused anyway - td_->file_manager_->delete_partial_remote_location(thumbnail_file_id_); + td_->file_manager_->delete_partial_remote_location(thumbnail_file_ids_[0]); } - CHECK(file_id_.is_valid()); - if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) { - td_->messages_manager_->on_send_message_file_part_missing(random_id_, - to_integer(status.message().substr(10))); + CHECK(file_ids_.size() == 1u); + CHECK(file_ids_[0].is_valid()); + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + td_->messages_manager_->on_send_message_file_parts_missing(random_id_, std::move(bad_parts)); return; } else { - if (status.code() != 429 && status.code() < 500 && !G()->close_flag()) { - td_->file_manager_->delete_partial_remote_location(file_id_); - } + td_->file_manager_->delete_partial_remote_location_if_needed(file_ids_[0], status); } } else if (!td_->auth_manager_->is_bot() && FileReferenceManager::is_file_reference_error(status)) { - if (file_id_.is_valid() && !was_uploaded_) { - VLOG(file_references) << "Receive " << status << " for " << file_id_; - td_->file_manager_->delete_file_reference(file_id_, file_reference_); - td_->messages_manager_->on_send_message_file_reference_error(random_id_); + auto pos = FileReferenceManager::get_file_reference_error_pos(status); + if (pos > 0) { + pos--; + } + if (pos < file_ids_.size() && pos < file_references_.size() && !was_uploaded_) { + VLOG(file_references) << "Receive " << status << " for " << file_ids_[pos]; + td_->file_manager_->delete_file_reference(file_ids_[pos], file_references_[pos]); + td_->messages_manager_->on_send_message_file_reference_error(random_id_, pos); return; } else { - LOG(ERROR) << "Receive file reference error, but file_id = " << file_id_ - << ", was_uploaded = " << was_uploaded_; + LOG(ERROR) << "Receive file reference error " << pos << ", but file_ids = " << file_ids_ + << ", was_uploaded = " << was_uploaded_ << ", file_references = " << file_references_; } } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendMediaQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendMediaQuery"); td_->messages_manager_->on_send_message_fail(random_id_, std::move(status)); } }; @@ -3550,6 +3332,7 @@ class SendMediaQuery final : public Td::ResultHandler { class UploadMediaQuery final : public Td::ResultHandler { DialogId dialog_id_; MessageId message_id_; + int32 media_pos_ = -1; FileId file_id_; FileId thumbnail_file_id_; string file_reference_; @@ -3557,24 +3340,26 @@ class UploadMediaQuery final : public Td::ResultHandler { bool was_thumbnail_uploaded_ = false; public: - void send(DialogId dialog_id, MessageId message_id, FileId file_id, FileId thumbnail_file_id, + void send(DialogId dialog_id, MessageId message_id, int32 media_pos, FileId file_id, FileId thumbnail_file_id, tl_object_ptr &&input_media) { CHECK(input_media != nullptr); dialog_id_ = dialog_id; message_id_ = message_id; + media_pos_ = media_pos; file_id_ = file_id; thumbnail_file_id_ = thumbnail_file_id; file_reference_ = FileManager::extract_file_reference(input_media); was_uploaded_ = FileManager::extract_was_uploaded(input_media); was_thumbnail_uploaded_ = FileManager::extract_was_thumbnail_uploaded(input_media); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { return on_error(Status::Error(400, "Have no write access to the chat")); } + int32 flags = 0; send_query(G()->net_query_creator().create( - telegram_api::messages_uploadMedia(std::move(input_peer), std::move(input_media)))); + telegram_api::messages_uploadMedia(flags, string(), std::move(input_peer), std::move(input_media)))); } void on_result(BufferSlice packet) final { @@ -3592,16 +3377,16 @@ class UploadMediaQuery final : public Td::ResultHandler { auto ptr = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for UploadMediaQuery for " << message_id_ << " in " << dialog_id_ << ": " << to_string(ptr); - td_->messages_manager_->on_upload_message_media_success(dialog_id_, message_id_, std::move(ptr)); + td_->messages_manager_->on_upload_message_media_success(dialog_id_, message_id_, media_pos_, std::move(ptr)); } void on_error(Status status) final { LOG(INFO) << "Receive error for UploadMediaQuery for " << message_id_ << " in " << dialog_id_ << ": " << status; if (G()->close_flag() && G()->use_message_database()) { - // do not send error, message will be re-sent + // do not send error, message will be re-sent after restart return; } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "UploadMediaQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "UploadMediaQuery"); if (was_uploaded_) { if (was_thumbnail_uploaded_) { CHECK(thumbnail_file_id_.is_valid()); @@ -3610,19 +3395,18 @@ class UploadMediaQuery final : public Td::ResultHandler { } CHECK(file_id_.is_valid()); - if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) { - td_->messages_manager_->on_upload_message_media_file_part_missing( - dialog_id_, message_id_, to_integer(status.message().substr(10))); + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + td_->messages_manager_->on_upload_message_media_file_parts_missing(dialog_id_, message_id_, media_pos_, + std::move(bad_parts)); return; } else { - if (status.code() != 429 && status.code() < 500 && !G()->close_flag()) { - td_->file_manager_->delete_partial_remote_location(file_id_); - } + td_->file_manager_->delete_partial_remote_location_if_needed(file_id_, status); } } else if (FileReferenceManager::is_file_reference_error(status)) { LOG(ERROR) << "Receive file reference error for UploadMediaQuery"; } - td_->messages_manager_->on_upload_message_media_fail(dialog_id_, message_id_, std::move(status)); + td_->messages_manager_->on_upload_message_media_fail(dialog_id_, message_id_, media_pos_, std::move(status)); } }; @@ -3637,7 +3421,7 @@ class SendScheduledMessageQuery final : public Td::ResultHandler { void send(DialogId dialog_id, MessageId message_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Edit); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Edit); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -3661,7 +3445,7 @@ class SendScheduledMessageQuery final : public Td::ResultHandler { void on_error(Status status) final { LOG(INFO) << "Receive error for SendScheduledMessageQuery: " << status; - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendScheduledMessageQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendScheduledMessageQuery"); promise_.set_error(std::move(status)); } }; @@ -3686,7 +3470,7 @@ class EditMessageQuery final : public Td::ResultHandler { void send(int32 flags, DialogId dialog_id, MessageId message_id, const string &text, vector> &&entities, - tl_object_ptr &&input_media, + tl_object_ptr &&input_media, bool invert_media, tl_object_ptr &&reply_markup, int32 schedule_date) { dialog_id_ = dialog_id; message_id_ = message_id; @@ -3695,7 +3479,7 @@ class EditMessageQuery final : public Td::ResultHandler { return on_error(Status::Error(400, "FILE_PART_1_MISSING")); } - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Edit); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Edit); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -3712,6 +3496,9 @@ class EditMessageQuery final : public Td::ResultHandler { if (input_media != nullptr) { flags |= telegram_api::messages_editMessage::MEDIA_MASK; } + if (invert_media) { + flags |= telegram_api::messages_editMessage::INVERT_MEDIA_MASK; + } if (schedule_date != 0) { flags |= telegram_api::messages_editMessage::SCHEDULE_DATE_MASK; } @@ -3719,9 +3506,9 @@ class EditMessageQuery final : public Td::ResultHandler { int32 server_message_id = schedule_date != 0 ? message_id.get_scheduled_server_message_id().get() : message_id.get_server_message_id().get(); send_query(G()->net_query_creator().create( - telegram_api::messages_editMessage(flags, false /*ignored*/, std::move(input_peer), server_message_id, text, - std::move(input_media), std::move(reply_markup), std::move(entities), - schedule_date), + telegram_api::messages_editMessage(flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), + server_message_id, text, std::move(input_media), std::move(reply_markup), + std::move(entities), schedule_date, 0), {{dialog_id}})); } @@ -3740,66 +3527,16 @@ class EditMessageQuery final : public Td::ResultHandler { } void on_error(Status status) final { - LOG(INFO) << "Receive error for EditMessage: " << status; + if (status.code() != 403 && !(status.code() == 500 && G()->close_flag())) { + LOG(WARNING) << "Failed to edit " << MessageFullId{dialog_id_, message_id_} << " with the error " + << status.message(); + } else { + LOG(INFO) << "Receive error for EditMessageQuery: " << status; + } if (!td_->auth_manager_->is_bot() && status.message() == "MESSAGE_NOT_MODIFIED") { return promise_.set_value(0); } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditMessageQuery"); - promise_.set_error(std::move(status)); - } -}; - -class EditInlineMessageQuery final : public Td::ResultHandler { - Promise promise_; - - public: - explicit EditInlineMessageQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(int32 flags, tl_object_ptr input_bot_inline_message_id, - const string &text, vector> &&entities, - tl_object_ptr &&input_media, - tl_object_ptr &&reply_markup) { - CHECK(input_bot_inline_message_id != nullptr); - - // file in an inline message can't be uploaded to another datacenter, - // so only previously uploaded files or URLs can be used in the InputMedia - CHECK(!FileManager::extract_was_uploaded(input_media)); - - if (reply_markup != nullptr) { - flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_REPLY_MARKUP; - } - if (!entities.empty()) { - flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_ENTITIES; - } - if (!text.empty()) { - flags |= MessagesManager::SEND_MESSAGE_FLAG_HAS_MESSAGE; - } - if (input_media != nullptr) { - flags |= telegram_api::messages_editInlineBotMessage::MEDIA_MASK; - } - - auto dc_id = DcId::internal(InlineQueriesManager::get_inline_message_dc_id(input_bot_inline_message_id)); - send_query(G()->net_query_creator().create( - telegram_api::messages_editInlineBotMessage(flags, false /*ignored*/, std::move(input_bot_inline_message_id), - text, std::move(input_media), std::move(reply_markup), - std::move(entities)), - {}, dc_id)); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - LOG_IF(ERROR, !result_ptr.ok()) << "Receive false in result of editInlineMessage"; - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - LOG(INFO) << "Receive error for EditInlineMessageQuery: " << status; + td_->messages_manager_->on_get_message_error(dialog_id_, message_id_, status, "EditMessageQuery"); promise_.set_error(std::move(status)); } }; @@ -3809,6 +3546,7 @@ class ForwardMessagesQuery final : public Td::ResultHandler { vector random_ids_; DialogId from_dialog_id_; DialogId to_dialog_id_; + MessageId message_id_; public: explicit ForwardMessagesQuery(Promise &&promise) : promise_(std::move(promise)) { @@ -3820,13 +3558,16 @@ class ForwardMessagesQuery final : public Td::ResultHandler { random_ids_ = random_ids; from_dialog_id_ = from_dialog_id; to_dialog_id_ = to_dialog_id; + if (message_ids.size() == 1) { + message_id_ = message_ids[0]; + } - auto to_input_peer = td_->messages_manager_->get_input_peer(to_dialog_id, AccessRights::Write); + auto to_input_peer = td_->dialog_manager_->get_input_peer(to_dialog_id, AccessRights::Write); if (to_input_peer == nullptr) { return on_error(Status::Error(400, "Have no write access to the chat")); } - auto from_input_peer = td_->messages_manager_->get_input_peer(from_dialog_id, AccessRights::Read); + auto from_input_peer = td_->dialog_manager_->get_input_peer(from_dialog_id, AccessRights::Read); if (from_input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat to forward messages from")); } @@ -3843,7 +3584,7 @@ class ForwardMessagesQuery final : public Td::ResultHandler { flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(from_input_peer), MessageId::get_server_message_ids(message_ids), std::move(random_ids), std::move(to_input_peer), top_thread_message_id.get_server_message_id().get(), - schedule_date, std::move(as_input_peer)), + schedule_date, std::move(as_input_peer), nullptr), {{to_dialog_id, MessageContentType::Text}, {to_dialog_id, MessageContentType::Photo}}); if (td_->option_manager_->get_option_boolean("use_quick_ack")) { query->quick_ack_promise_ = PromiseCreator::lambda([random_ids = random_ids_](Result result) { @@ -3906,15 +3647,111 @@ class ForwardMessagesQuery final : public Td::ResultHandler { void on_error(Status status) final { LOG(INFO) << "Receive error for forward messages: " << status; if (G()->close_flag() && G()->use_message_database()) { - // do not send error, messages should be re-sent + // do not send error, messages will be re-sent after restart return; } // no on_get_dialog_error call, because two dialogs are involved if (status.code() == 400 && status.message() == CSlice("CHAT_FORWARDS_RESTRICTED")) { - td_->contacts_manager_->reload_dialog_info(from_dialog_id_, Promise()); + td_->dialog_manager_->reload_dialog_info(from_dialog_id_, Promise()); } if (status.code() == 400 && status.message() == CSlice("SEND_AS_PEER_INVALID")) { - td_->messages_manager_->reload_dialog_info_full(to_dialog_id_, "SEND_AS_PEER_INVALID"); + td_->dialog_manager_->reload_dialog_info_full(to_dialog_id_, "SEND_AS_PEER_INVALID"); + } + if (message_id_.is_valid() && status.message() == CSlice("MESSAGE_ID_INVALID")) { + td_->messages_manager_->get_message_from_server({from_dialog_id_, message_id_}, Promise(), + "ForwardMessagesQuery"); + } + for (auto &random_id : random_ids_) { + td_->messages_manager_->on_send_message_fail(random_id, status.clone()); + } + promise_.set_error(std::move(status)); + } +}; + +class SendQuickReplyMessagesQuery final : public Td::ResultHandler { + Promise promise_; + vector random_ids_; + DialogId dialog_id_; + QuickReplyShortcutId shortcut_id_; + + public: + explicit SendQuickReplyMessagesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, QuickReplyShortcutId shortcut_id, const vector &message_ids, + vector &&random_ids) { + random_ids_ = random_ids; + dialog_id_ = dialog_id; + shortcut_id_ = shortcut_id; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Have no write access to the chat")); + } + + auto query = G()->net_query_creator().create( + telegram_api::messages_sendQuickReplyMessages(std::move(input_peer), shortcut_id.get(), + MessageId::get_server_message_ids(message_ids), + std::move(random_ids)), + {{dialog_id, MessageContentType::Text}, {dialog_id, MessageContentType::Photo}}); + if (td_->option_manager_->get_option_boolean("use_quick_ack")) { + query->quick_ack_promise_ = PromiseCreator::lambda([random_ids = random_ids_](Result result) { + if (result.is_ok()) { + for (auto random_id : random_ids) { + send_closure(G()->messages_manager(), &MessagesManager::on_send_message_get_quick_ack, random_id); + } + } + }); + } + send_query(std::move(query)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendQuickReplyMessagesQuery for " << format::as_array(random_ids_) << ": " + << to_string(ptr); + auto sent_messages = UpdatesManager::get_new_messages(ptr.get()); + auto sent_random_ids = UpdatesManager::get_sent_messages_random_ids(ptr.get()); + bool is_result_wrong = false; + if (random_ids_.size() != sent_messages.size() || random_ids_.size() != sent_random_ids.size()) { + is_result_wrong = true; + } + for (auto &random_id : random_ids_) { + auto it = sent_random_ids.find(random_id); + if (it == sent_random_ids.end()) { + is_result_wrong = true; + } + } + for (auto &sent_message : sent_messages) { + if (DialogId::get_message_dialog_id(sent_message.first) != dialog_id_) { + is_result_wrong = true; + } + } + if (is_result_wrong) { + LOG(ERROR) << "Receive wrong result for sending quick reply messages with random_ids " + << format::as_array(random_ids_) << " to " << dialog_id_ << ": " << oneline(to_string(ptr)); + td_->updates_manager_->schedule_get_difference("Wrong sendQuickReplyMessages result"); + for (auto &random_id : random_ids_) { + td_->messages_manager_->on_send_message_fail(random_id, Status::Error(500, "Receive invalid response")); + } + } + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for SendQuickReplyMessagesQuery: " << status; + if (G()->close_flag() && G()->use_message_database()) { + // do not send error, messages will be re-sent after restart + return; + } + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendQuickReplyMessagesQuery"); + if (status.code() == 400 && status.message() == CSlice("MESSAGE_IDS_MISMATCH")) { + td_->quick_reply_manager_->reload_quick_reply_messages(shortcut_id_, Auto()); } for (auto &random_id : random_ids_) { td_->messages_manager_->on_send_message_fail(random_id, status.clone()); @@ -3936,11 +3773,14 @@ class SendScreenshotNotificationQuery final : public Td::ResultHandler { random_id_ = random_id; dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create( - telegram_api::messages_sendScreenshotNotification(std::move(input_peer), 0, random_id), + telegram_api::messages_sendScreenshotNotification( + std::move(input_peer), + telegram_api::make_object(0, 0, 0, nullptr, string(), Auto(), 0), + random_id), {{dialog_id, MessageContentType::Text}})); } @@ -3960,10 +3800,10 @@ class SendScreenshotNotificationQuery final : public Td::ResultHandler { void on_error(Status status) final { LOG(INFO) << "Receive error for SendScreenshotNotificationQuery: " << status; if (G()->close_flag() && G()->use_message_database()) { - // do not send error, messages should be re-sent + // do not send error, messages will be re-sent after restart return; } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendScreenshotNotificationQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendScreenshotNotificationQuery"); td_->messages_manager_->on_send_message_fail(random_id_, status.clone()); promise_.set_error(std::move(status)); } @@ -3976,21 +3816,25 @@ class SendBotRequestedPeerQuery final : public Td::ResultHandler { explicit SendBotRequestedPeerQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(FullMessageId full_message_id, int32 button_id, DialogId requested_dialog_id) { - auto dialog_id = full_message_id.get_dialog_id(); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + void send(MessageFullId message_full_id, int32 button_id, vector &&requested_dialog_ids) { + auto dialog_id = message_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } - auto requested_peer = td_->messages_manager_->get_input_peer(requested_dialog_id, AccessRights::Read); - if (requested_peer == nullptr) { - return on_error(Status::Error(400, "Can't access the chosen chat")); + vector> requested_peers; + for (auto requested_dialog_id : requested_dialog_ids) { + auto requested_peer = td_->dialog_manager_->get_input_peer(requested_dialog_id, AccessRights::Read); + if (requested_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chosen chat")); + } + requested_peers.push_back(std::move(requested_peer)); } send_query(G()->net_query_creator().create( telegram_api::messages_sendBotRequestedPeer(std::move(input_peer), - full_message_id.get_message_id().get_server_message_id().get(), - button_id, std::move(requested_peer)), + message_full_id.get_message_id().get_server_message_id().get(), + button_id, std::move(requested_peers)), {{dialog_id, MessageContentType::Text}})); } @@ -4010,59 +3854,6 @@ class SendBotRequestedPeerQuery final : public Td::ResultHandler { } }; -class SetTypingQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - int32 generation_ = 0; - - public: - explicit SetTypingQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - NetQueryRef send(DialogId dialog_id, tl_object_ptr &&input_peer, MessageId message_id, - tl_object_ptr &&action) { - dialog_id_ = dialog_id; - CHECK(input_peer != nullptr); - - int32 flags = 0; - if (message_id.is_valid()) { - flags |= telegram_api::messages_setTyping::TOP_MSG_ID_MASK; - } - auto query = G()->net_query_creator().create(telegram_api::messages_setTyping( - flags, std::move(input_peer), message_id.get_server_message_id().get(), std::move(action))); - query->total_timeout_limit_ = 2; - auto result = query.get_weak(); - generation_ = result.generation(); - send_query(std::move(query)); - return result; - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - // ignore result - promise_.set_value(Unit()); - - send_closure_later(G()->messages_manager(), &MessagesManager::after_set_typing_query, dialog_id_, generation_); - } - - void on_error(Status status) final { - if (status.code() == NetQuery::Canceled) { - return promise_.set_value(Unit()); - } - - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SetTypingQuery")) { - LOG(INFO) << "Receive error for set typing: " << status; - } - promise_.set_error(std::move(status)); - - send_closure_later(G()->messages_manager(), &MessagesManager::after_set_typing_query, dialog_id_, generation_); - } -}; - class DeleteMessagesQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; @@ -4092,18 +3883,15 @@ class DeleteMessagesQuery final : public Td::ResultHandler { } auto affected_messages = result_ptr.move_as_ok(); - if (affected_messages->pts_count_ > 0) { - td_->updates_manager_->add_pending_pts_update(make_tl_object(), affected_messages->pts_, - affected_messages->pts_count_, Time::now(), std::move(promise_), - "delete messages query"); - } else { - promise_.set_value(Unit()); - } + LOG(INFO) << "Receive result for DeleteMessagesQuery: " << to_string(affected_messages); + td_->updates_manager_->add_pending_pts_update(make_tl_object(), affected_messages->pts_, + affected_messages->pts_count_, Time::now(), std::move(promise_), + "delete messages query"); } void on_error(Status status) final { if (!G()->is_expected_error(status)) { - // MESSAGE_DELETE_FORBIDDEN can be returned in group chats when administrator rights was removed + // MESSAGE_DELETE_FORBIDDEN can be returned in group chats when administrator rights were removed // MESSAGE_DELETE_FORBIDDEN can be returned in private chats for bots when revoke time limit exceeded if (status.message() != "MESSAGE_DELETE_FORBIDDEN" || (dialog_id_.get_type() == DialogType::User && !td_->auth_manager_->is_bot())) { @@ -4128,7 +3916,7 @@ class DeleteChannelMessagesQuery final : public Td::ResultHandler { channel_id_ = channel_id; server_message_ids_ = server_message_ids; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -4143,17 +3931,14 @@ class DeleteChannelMessagesQuery final : public Td::ResultHandler { } auto affected_messages = result_ptr.move_as_ok(); - if (affected_messages->pts_count_ > 0) { - td_->messages_manager_->add_pending_channel_update(DialogId(channel_id_), make_tl_object(), - affected_messages->pts_, affected_messages->pts_count_, - std::move(promise_), "DeleteChannelMessagesQuery"); - } else { - promise_.set_value(Unit()); - } + LOG(INFO) << "Receive result for DeleteChannelMessagesQuery: " << to_string(affected_messages); + td_->messages_manager_->add_pending_channel_update(DialogId(channel_id_), make_tl_object(), + affected_messages->pts_, affected_messages->pts_count_, + std::move(promise_), "DeleteChannelMessagesQuery"); } void on_error(Status status) final { - if (!td_->contacts_manager_->on_get_channel_error(channel_id_, status, "DeleteChannelMessagesQuery")) { + if (!td_->chat_manager_->on_get_channel_error(channel_id_, status, "DeleteChannelMessagesQuery")) { if (status.message() != "MESSAGE_DELETE_FORBIDDEN") { LOG(ERROR) << "Receive error for delete channel messages: " << status; } @@ -4176,7 +3961,7 @@ class DeleteScheduledMessagesQuery final : public Td::ResultHandler { dialog_id_ = dialog_id; message_ids_ = std::move(message_ids); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -4196,7 +3981,7 @@ class DeleteScheduledMessagesQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "DeleteScheduledMessagesQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "DeleteScheduledMessagesQuery")) { LOG(ERROR) << "Receive error for delete scheduled messages: " << status; } td_->messages_manager_->on_failed_scheduled_message_deletion(dialog_id_, message_ids_); @@ -4211,7 +3996,7 @@ class GetPeerSettingsQuery final : public Td::ResultHandler { void send(DialogId dialog_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create(telegram_api::messages_getPeerSettings(std::move(input_peer)))); @@ -4224,14 +4009,14 @@ class GetPeerSettingsQuery final : public Td::ResultHandler { } auto ptr = result_ptr.move_as_ok(); - td_->contacts_manager_->on_get_users(std::move(ptr->users_), "GetPeerSettingsQuery"); - td_->contacts_manager_->on_get_chats(std::move(ptr->chats_), "GetPeerSettingsQuery"); + td_->user_manager_->on_get_users(std::move(ptr->users_), "GetPeerSettingsQuery"); + td_->chat_manager_->on_get_chats(std::move(ptr->chats_), "GetPeerSettingsQuery"); td_->messages_manager_->on_get_peer_settings(dialog_id_, std::move(ptr->settings_)); } void on_error(Status status) final { LOG(INFO) << "Receive error for get peer settings: " << status; - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetPeerSettingsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetPeerSettingsQuery"); } }; @@ -4246,7 +4031,7 @@ class UpdatePeerSettingsQuery final : public Td::ResultHandler { void send(DialogId dialog_id, bool is_spam_dialog) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return promise_.set_value(Unit()); } @@ -4274,7 +4059,7 @@ class UpdatePeerSettingsQuery final : public Td::ResultHandler { void on_error(Status status) final { LOG(INFO) << "Receive error for update peer settings: " << status; - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "UpdatePeerSettingsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "UpdatePeerSettingsQuery"); td_->messages_manager_->reget_dialog_action_bar(dialog_id_, "UpdatePeerSettingsQuery"); promise_.set_error(std::move(status)); } @@ -4291,7 +4076,7 @@ class ReportEncryptedSpamQuery final : public Td::ResultHandler { void send(DialogId dialog_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_encrypted_chat(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_encrypted_chat(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create(telegram_api::messages_reportEncryptedSpam(std::move(input_peer)))); @@ -4310,127 +4095,14 @@ class ReportEncryptedSpamQuery final : public Td::ResultHandler { void on_error(Status status) final { LOG(INFO) << "Receive error for report encrypted spam: " << status; - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReportEncryptedSpamQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ReportEncryptedSpamQuery"); td_->messages_manager_->reget_dialog_action_bar( - DialogId(td_->contacts_manager_->get_secret_chat_user_id(dialog_id_.get_secret_chat_id())), + DialogId(td_->user_manager_->get_secret_chat_user_id(dialog_id_.get_secret_chat_id())), "ReportEncryptedSpamQuery"); promise_.set_error(std::move(status)); } }; -class ReportPeerQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - - public: - explicit ReportPeerQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, const vector &message_ids, ReportReason &&report_reason) { - dialog_id_ = dialog_id; - - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); - CHECK(input_peer != nullptr); - - if (message_ids.empty()) { - send_query(G()->net_query_creator().create(telegram_api::account_reportPeer( - std::move(input_peer), report_reason.get_input_report_reason(), report_reason.get_message()))); - } else { - send_query(G()->net_query_creator().create( - telegram_api::messages_report(std::move(input_peer), MessageId::get_server_message_ids(message_ids), - report_reason.get_input_report_reason(), report_reason.get_message()))); - } - } - - void on_result(BufferSlice packet) final { - static_assert( - std::is_same::value, - ""); - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - bool result = result_ptr.ok(); - if (!result) { - return on_error(Status::Error(400, "Receive false as result")); - } - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - LOG(INFO) << "Receive error for report peer: " << status; - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReportPeerQuery"); - td_->messages_manager_->reget_dialog_action_bar(dialog_id_, "ReportPeerQuery"); - promise_.set_error(std::move(status)); - } -}; - -class ReportProfilePhotoQuery final : public Td::ResultHandler { - Promise promise_; - DialogId dialog_id_; - FileId file_id_; - string file_reference_; - ReportReason report_reason_; - - public: - explicit ReportProfilePhotoQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(DialogId dialog_id, FileId file_id, tl_object_ptr &&input_photo, - ReportReason &&report_reason) { - dialog_id_ = dialog_id; - file_id_ = file_id; - file_reference_ = FileManager::extract_file_reference(input_photo); - report_reason_ = std::move(report_reason); - - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); - CHECK(input_peer != nullptr); - - send_query(G()->net_query_creator().create(telegram_api::account_reportProfilePhoto( - std::move(input_peer), std::move(input_photo), report_reason_.get_input_report_reason(), - report_reason_.get_message()))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - bool result = result_ptr.ok(); - if (!result) { - return on_error(Status::Error(400, "Receive false as result")); - } - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - LOG(INFO) << "Receive error for report chat photo: " << status; - if (!td_->auth_manager_->is_bot() && FileReferenceManager::is_file_reference_error(status)) { - VLOG(file_references) << "Receive " << status << " for " << file_id_; - td_->file_manager_->delete_file_reference(file_id_, file_reference_); - td_->file_reference_manager_->repair_file_reference( - file_id_, - PromiseCreator::lambda([dialog_id = dialog_id_, file_id = file_id_, report_reason = std::move(report_reason_), - promise = std::move(promise_)](Result result) mutable { - if (result.is_error()) { - LOG(INFO) << "Reported photo " << file_id << " is likely to be deleted"; - return promise.set_value(Unit()); - } - send_closure(G()->messages_manager(), &MessagesManager::report_dialog_photo, dialog_id, file_id, - std::move(report_reason), std::move(promise)); - })); - return; - } - - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ReportProfilePhotoQuery"); - promise_.set_error(std::move(status)); - } -}; - class EditPeerFoldersQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; @@ -4442,7 +4114,7 @@ class EditPeerFoldersQuery final : public Td::ResultHandler { void send(DialogId dialog_id, FolderId folder_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); CHECK(input_peer != nullptr); vector> input_folder_peers; @@ -4463,12 +4135,12 @@ class EditPeerFoldersQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "EditPeerFoldersQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "EditPeerFoldersQuery")) { LOG(INFO) << "Receive error for EditPeerFoldersQuery: " << status; } // trying to repair folder ID for this dialog - td_->messages_manager_->get_dialog_info_full(dialog_id_, Auto(), "EditPeerFoldersQuery"); + td_->dialog_manager_->get_dialog_info_full(dialog_id_, Auto(), "EditPeerFoldersQuery"); promise_.set_error(std::move(status)); } @@ -4503,53 +4175,16 @@ class GetChannelDifferenceQuery final : public Td::ResultHandler { return on_error(result_ptr.move_as_error()); } - td_->messages_manager_->on_get_channel_difference(dialog_id_, pts_, limit_, result_ptr.move_as_ok()); + td_->messages_manager_->on_get_channel_difference(dialog_id_, pts_, limit_, result_ptr.move_as_ok(), Status::OK()); } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetChannelDifferenceQuery") && + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetChannelDifferenceQuery") && status.message() != "PERSISTENT_TIMESTAMP_INVALID") { LOG(ERROR) << "Receive error for GetChannelDifferenceQuery for " << dialog_id_ << " with PTS " << pts_ << " and limit " << limit_ << ": " << status; } - td_->messages_manager_->on_get_channel_difference(dialog_id_, pts_, limit_, nullptr); - } -}; - -class ResolveUsernameQuery final : public Td::ResultHandler { - Promise promise_; - string username_; - - public: - explicit ResolveUsernameQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(const string &username) { - username_ = username; - send_query(G()->net_query_creator().create(telegram_api::contacts_resolveUsername(username))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(DEBUG) << "Receive result for ResolveUsernameQuery: " << to_string(ptr); - td_->contacts_manager_->on_get_users(std::move(ptr->users_), "ResolveUsernameQuery"); - td_->contacts_manager_->on_get_chats(std::move(ptr->chats_), "ResolveUsernameQuery"); - - td_->messages_manager_->on_resolved_username(username_, DialogId(ptr->peer_)); - - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - if (status.message() == Slice("USERNAME_NOT_OCCUPIED")) { - td_->messages_manager_->drop_username(username_); - } - promise_.set_error(std::move(status)); + td_->messages_manager_->on_get_channel_difference(dialog_id_, pts_, limit_, nullptr, std::move(status)); } }; @@ -4587,98 +4222,35 @@ class MessagesManager::UploadThumbnailCallback final : public FileManager::Uploa } }; -class MessagesManager::UploadDialogPhotoCallback final : public FileManager::UploadCallback { - public: - void on_upload_ok(FileId file_id, tl_object_ptr input_file) final { - send_closure_later(G()->messages_manager(), &MessagesManager::on_upload_dialog_photo, file_id, - std::move(input_file)); - } - void on_upload_encrypted_ok(FileId file_id, tl_object_ptr input_file) final { - UNREACHABLE(); - } - void on_upload_secure_ok(FileId file_id, tl_object_ptr input_file) final { - UNREACHABLE(); - } - void on_upload_error(FileId file_id, Status error) final { - send_closure_later(G()->messages_manager(), &MessagesManager::on_upload_dialog_photo_error, file_id, - std::move(error)); - } -}; - -class MessagesManager::UploadImportedMessagesCallback final : public FileManager::UploadCallback { - public: - void on_upload_ok(FileId file_id, tl_object_ptr input_file) final { - send_closure_later(G()->messages_manager(), &MessagesManager::on_upload_imported_messages, file_id, - std::move(input_file)); - } - void on_upload_encrypted_ok(FileId file_id, tl_object_ptr input_file) final { - UNREACHABLE(); - } - void on_upload_secure_ok(FileId file_id, tl_object_ptr input_file) final { - UNREACHABLE(); - } - void on_upload_error(FileId file_id, Status error) final { - send_closure_later(G()->messages_manager(), &MessagesManager::on_upload_imported_messages_error, file_id, - std::move(error)); - } -}; - -class MessagesManager::UploadImportedMessageAttachmentCallback final : public FileManager::UploadCallback { - public: - void on_upload_ok(FileId file_id, tl_object_ptr input_file) final { - send_closure_later(G()->messages_manager(), &MessagesManager::on_upload_imported_message_attachment, file_id, - std::move(input_file)); - } - void on_upload_encrypted_ok(FileId file_id, tl_object_ptr input_file) final { - UNREACHABLE(); - } - void on_upload_secure_ok(FileId file_id, tl_object_ptr input_file) final { - UNREACHABLE(); - } - void on_upload_error(FileId file_id, Status error) final { - send_closure_later(G()->messages_manager(), &MessagesManager::on_upload_imported_message_attachment_error, file_id, - std::move(error)); - } -}; - template void MessagesManager::Message::store(StorerT &storer) const { using td::store; bool has_sender = sender_user_id.is_valid(); bool has_edit_date = edit_date > 0; bool has_random_id = random_id != 0; - bool is_forwarded = forward_info != nullptr; - bool is_reply = reply_to_message_id.is_valid() || reply_to_message_id.is_valid_scheduled(); bool is_reply_to_random_id = reply_to_random_id != 0; bool is_via_bot = via_bot_user_id.is_valid(); bool has_view_count = view_count > 0; bool has_reply_markup = reply_markup != nullptr; - bool has_ttl = ttl != 0; + bool has_ttl = ttl.is_valid(); bool has_author_signature = !author_signature.empty(); - bool has_forward_author_signature = is_forwarded && !forward_info->author_signature.empty(); bool has_media_album_id = media_album_id != 0; - bool has_forward_from = - is_forwarded && (forward_info->from_dialog_id.is_valid() || forward_info->from_message_id.is_valid()); bool has_send_date = message_id.is_yet_unsent() && send_date != 0; bool has_flags2 = true; bool has_notification_id = notification_id.is_valid(); - bool has_forward_sender_name = is_forwarded && !forward_info->sender_name.empty(); bool has_send_error_code = send_error_code != 0; bool has_real_forward_from = real_forward_from_dialog_id.is_valid() && real_forward_from_message_id.is_valid(); bool has_legacy_layer = legacy_layer != 0; bool has_restriction_reasons = !restriction_reasons.empty(); - bool has_forward_psa_type = is_forwarded && !forward_info->psa_type.empty(); bool has_forward_count = forward_count > 0; bool has_reply_info = !reply_info.is_empty(); bool has_sender_dialog_id = sender_dialog_id.is_valid(); - bool has_reply_in_dialog_id = is_reply && reply_in_dialog_id.is_valid(); bool has_top_thread_message_id = top_thread_message_id.is_valid(); bool has_thread_draft_message = thread_draft_message != nullptr; bool has_local_thread_message_ids = !local_thread_message_ids.empty(); bool has_linked_top_thread_message_id = linked_top_thread_message_id.is_valid(); bool has_interaction_info_update_date = interaction_info_update_date != 0; bool has_send_emoji = !send_emoji.empty(); - bool is_imported = is_forwarded && forward_info->is_imported; bool has_ttl_period = ttl_period != 0; bool has_max_reply_media_timestamp = max_reply_media_timestamp >= 0; bool are_message_media_timestamp_entities_found = true; @@ -4686,6 +4258,17 @@ void MessagesManager::Message::store(StorerT &storer) const { bool has_reactions = reactions != nullptr; bool has_available_reactions_generation = available_reactions_generation != 0; bool has_history_generation = history_generation != 0; + bool is_reply_to_story = reply_to_story_full_id != StoryFullId(); + bool has_input_reply_to = !message_id.is_any_server() && input_reply_to.is_valid(); + bool has_replied_message_info = !replied_message_info.is_empty(); + bool has_forward_info = forward_info != nullptr; + bool has_saved_messages_topic_id = saved_messages_topic_id.is_valid(); + bool has_initial_top_thread_message_id = !message_id.is_any_server() && initial_top_thread_message_id.is_valid(); + bool has_sender_boost_count = sender_boost_count != 0; + bool has_via_business_bot_user_id = via_business_bot_user_id.is_valid(); + bool has_effect_id = effect_id.is_valid(); + bool has_fact_check = fact_check != nullptr; + bool has_initial_sender_dialog_id = !message_id.is_any_server() && initial_sender_dialog_id.is_valid(); BEGIN_STORE_FLAGS(); STORE_FLAG(is_channel_post); STORE_FLAG(is_outgoing); @@ -4700,19 +4283,19 @@ void MessagesManager::Message::store(StorerT &storer) const { STORE_FLAG(has_sender); STORE_FLAG(has_edit_date); STORE_FLAG(has_random_id); - STORE_FLAG(is_forwarded); - STORE_FLAG(is_reply); + STORE_FLAG(false); + STORE_FLAG(false); STORE_FLAG(is_reply_to_random_id); STORE_FLAG(is_via_bot); STORE_FLAG(has_view_count); STORE_FLAG(has_reply_markup); STORE_FLAG(has_ttl); STORE_FLAG(has_author_signature); - STORE_FLAG(has_forward_author_signature); + STORE_FLAG(false); STORE_FLAG(had_reply_markup); STORE_FLAG(contains_unread_mention); STORE_FLAG(has_media_album_id); - STORE_FLAG(has_forward_from); + STORE_FLAG(false); STORE_FLAG(in_game_share); STORE_FLAG(is_content_secret); STORE_FLAG(has_send_date); @@ -4723,7 +4306,7 @@ void MessagesManager::Message::store(StorerT &storer) const { STORE_FLAG(has_notification_id); STORE_FLAG(is_mention_notification_disabled); STORE_FLAG(had_forward_info); - STORE_FLAG(has_forward_sender_name); + STORE_FLAG(false); STORE_FLAG(has_send_error_code); STORE_FLAG(hide_via_bot); STORE_FLAG(is_bot_start_message); @@ -4733,11 +4316,11 @@ void MessagesManager::Message::store(StorerT &storer) const { STORE_FLAG(has_restriction_reasons); STORE_FLAG(is_from_scheduled); STORE_FLAG(is_copy); - STORE_FLAG(has_forward_psa_type); + STORE_FLAG(false); STORE_FLAG(has_forward_count); STORE_FLAG(has_reply_info); STORE_FLAG(has_sender_dialog_id); - STORE_FLAG(has_reply_in_dialog_id); + STORE_FLAG(false); STORE_FLAG(has_top_thread_message_id); STORE_FLAG(has_thread_draft_message); STORE_FLAG(has_local_thread_message_ids); @@ -4745,7 +4328,7 @@ void MessagesManager::Message::store(StorerT &storer) const { STORE_FLAG(is_pinned); STORE_FLAG(has_interaction_info_update_date); STORE_FLAG(has_send_emoji); - STORE_FLAG(is_imported); + STORE_FLAG(false); STORE_FLAG(has_ttl_period); STORE_FLAG(has_max_reply_media_timestamp); STORE_FLAG(are_message_media_timestamp_entities_found); @@ -4761,6 +4344,20 @@ void MessagesManager::Message::store(StorerT &storer) const { STORE_FLAG(update_stickersets_order); STORE_FLAG(is_topic_message); STORE_FLAG(has_history_generation); + STORE_FLAG(is_reply_to_story); + STORE_FLAG(false); + STORE_FLAG(invert_media); + STORE_FLAG(has_input_reply_to); + STORE_FLAG(has_replied_message_info); + STORE_FLAG(has_forward_info); + STORE_FLAG(has_saved_messages_topic_id); + STORE_FLAG(has_initial_top_thread_message_id); + STORE_FLAG(has_sender_boost_count); + STORE_FLAG(has_via_business_bot_user_id); + STORE_FLAG(is_from_offline); + STORE_FLAG(has_effect_id); + STORE_FLAG(has_fact_check); + STORE_FLAG(has_initial_sender_dialog_id); END_STORE_FLAGS(); } @@ -4778,32 +4375,13 @@ void MessagesManager::Message::store(StorerT &storer) const { if (has_random_id) { store(random_id, storer); } - if (is_forwarded) { - store(forward_info->sender_user_id, storer); - store(forward_info->date, storer); - store(forward_info->sender_dialog_id, storer); - store(forward_info->message_id, storer); - if (has_forward_author_signature) { - store(forward_info->author_signature, storer); - } - if (has_forward_sender_name) { - store(forward_info->sender_name, storer); - } - if (has_forward_from) { - store(forward_info->from_dialog_id, storer); - store(forward_info->from_message_id, storer); - } - if (has_forward_psa_type) { - store(forward_info->psa_type, storer); - } + if (has_forward_info) { + store(forward_info, storer); } if (has_real_forward_from) { store(real_forward_from_dialog_id, storer); store(real_forward_from_message_id, storer); } - if (is_reply) { - store(reply_to_message_id, storer); - } if (is_reply_to_random_id) { store(reply_to_random_id, storer); } @@ -4848,9 +4426,6 @@ void MessagesManager::Message::store(StorerT &storer) const { if (has_sender_dialog_id) { store(sender_dialog_id, storer); } - if (has_reply_in_dialog_id) { - store(reply_in_dialog_id, storer); - } if (has_top_thread_message_id) { store(top_thread_message_id, storer); } @@ -4888,6 +4463,36 @@ void MessagesManager::Message::store(StorerT &storer) const { if (has_history_generation) { store(history_generation, storer); } + if (is_reply_to_story) { + store(reply_to_story_full_id, storer); + } + if (has_input_reply_to) { + store(input_reply_to, storer); + } + if (has_replied_message_info) { + store(replied_message_info, storer); + } + if (has_saved_messages_topic_id) { + store(saved_messages_topic_id, storer); + } + if (has_initial_top_thread_message_id) { + store(initial_top_thread_message_id, storer); + } + if (has_sender_boost_count) { + store(sender_boost_count, storer); + } + if (has_via_business_bot_user_id) { + store(via_business_bot_user_id, storer); + } + if (has_effect_id) { + store(effect_id, storer); + } + if (has_fact_check) { + store(fact_check, storer); + } + if (has_initial_sender_dialog_id) { + store(initial_sender_dialog_id, storer); + } } // do not forget to resolve message dependencies @@ -4899,43 +4504,55 @@ void MessagesManager::Message::parse(ParserT &parser) { bool has_sender; bool has_edit_date; bool has_random_id; - bool is_forwarded; - bool is_reply; + bool legacy_is_forwarded; + bool legacy_is_reply; bool is_reply_to_random_id; bool is_via_bot; bool has_view_count; bool has_reply_markup; bool has_ttl; bool has_author_signature; - bool has_forward_author_signature; + bool legacy_has_forward_author_signature; bool has_media_album_id; - bool has_forward_from; + bool legacy_has_forward_from; bool has_send_date; bool has_flags2; bool has_notification_id = false; - bool has_forward_sender_name = false; + bool legacy_has_forward_sender_name = false; bool has_send_error_code = false; bool has_real_forward_from = false; bool has_legacy_layer = false; bool has_restriction_reasons = false; - bool has_forward_psa_type = false; + bool legacy_has_forward_psa_type = false; bool has_forward_count = false; bool has_reply_info = false; bool has_sender_dialog_id = false; - bool has_reply_in_dialog_id = false; + bool legacy_has_reply_in_dialog_id = false; bool has_top_thread_message_id = false; bool has_thread_draft_message = false; bool has_local_thread_message_ids = false; bool has_linked_top_thread_message_id = false; bool has_interaction_info_update_date = false; bool has_send_emoji = false; - bool is_imported = false; + bool legacy_is_imported = false; bool has_ttl_period = false; bool has_max_reply_media_timestamp = false; bool has_flags3 = false; bool has_reactions = false; bool has_available_reactions_generation = false; bool has_history_generation = false; + bool is_reply_to_story = false; + bool legacy_has_forward_origin = false; + bool has_input_reply_to = false; + bool has_replied_message_info = false; + bool has_forward_info = false; + bool has_saved_messages_topic_id = false; + bool has_initial_top_thread_message_id = false; + bool has_sender_boost_count = false; + bool has_via_business_bot_user_id = false; + bool has_effect_id = false; + bool has_fact_check = false; + bool has_initial_sender_dialog_id = false; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_channel_post); PARSE_FLAG(is_outgoing); @@ -4950,19 +4567,19 @@ void MessagesManager::Message::parse(ParserT &parser) { PARSE_FLAG(has_sender); PARSE_FLAG(has_edit_date); PARSE_FLAG(has_random_id); - PARSE_FLAG(is_forwarded); - PARSE_FLAG(is_reply); + PARSE_FLAG(legacy_is_forwarded); + PARSE_FLAG(legacy_is_reply); PARSE_FLAG(is_reply_to_random_id); PARSE_FLAG(is_via_bot); PARSE_FLAG(has_view_count); PARSE_FLAG(has_reply_markup); PARSE_FLAG(has_ttl); PARSE_FLAG(has_author_signature); - PARSE_FLAG(has_forward_author_signature); + PARSE_FLAG(legacy_has_forward_author_signature); PARSE_FLAG(had_reply_markup); PARSE_FLAG(contains_unread_mention); PARSE_FLAG(has_media_album_id); - PARSE_FLAG(has_forward_from); + PARSE_FLAG(legacy_has_forward_from); PARSE_FLAG(in_game_share); PARSE_FLAG(is_content_secret); PARSE_FLAG(has_send_date); @@ -4973,7 +4590,7 @@ void MessagesManager::Message::parse(ParserT &parser) { PARSE_FLAG(has_notification_id); PARSE_FLAG(is_mention_notification_disabled); PARSE_FLAG(had_forward_info); - PARSE_FLAG(has_forward_sender_name); + PARSE_FLAG(legacy_has_forward_sender_name); PARSE_FLAG(has_send_error_code); PARSE_FLAG(hide_via_bot); PARSE_FLAG(is_bot_start_message); @@ -4983,11 +4600,11 @@ void MessagesManager::Message::parse(ParserT &parser) { PARSE_FLAG(has_restriction_reasons); PARSE_FLAG(is_from_scheduled); PARSE_FLAG(is_copy); - PARSE_FLAG(has_forward_psa_type); + PARSE_FLAG(legacy_has_forward_psa_type); PARSE_FLAG(has_forward_count); PARSE_FLAG(has_reply_info); PARSE_FLAG(has_sender_dialog_id); - PARSE_FLAG(has_reply_in_dialog_id); + PARSE_FLAG(legacy_has_reply_in_dialog_id); PARSE_FLAG(has_top_thread_message_id); PARSE_FLAG(has_thread_draft_message); PARSE_FLAG(has_local_thread_message_ids); @@ -4995,7 +4612,7 @@ void MessagesManager::Message::parse(ParserT &parser) { PARSE_FLAG(is_pinned); PARSE_FLAG(has_interaction_info_update_date); PARSE_FLAG(has_send_emoji); - PARSE_FLAG(is_imported); + PARSE_FLAG(legacy_is_imported); PARSE_FLAG(has_ttl_period); PARSE_FLAG(has_max_reply_media_timestamp); PARSE_FLAG(are_media_timestamp_entities_found); @@ -5011,6 +4628,20 @@ void MessagesManager::Message::parse(ParserT &parser) { PARSE_FLAG(update_stickersets_order); PARSE_FLAG(is_topic_message); PARSE_FLAG(has_history_generation); + PARSE_FLAG(is_reply_to_story); + PARSE_FLAG(legacy_has_forward_origin); + PARSE_FLAG(invert_media); + PARSE_FLAG(has_input_reply_to); + PARSE_FLAG(has_replied_message_info); + PARSE_FLAG(has_forward_info); + PARSE_FLAG(has_saved_messages_topic_id); + PARSE_FLAG(has_initial_top_thread_message_id); + PARSE_FLAG(has_sender_boost_count); + PARSE_FLAG(has_via_business_bot_user_id); + PARSE_FLAG(is_from_offline); + PARSE_FLAG(has_effect_id); + PARSE_FLAG(has_fact_check); + PARSE_FLAG(has_initial_sender_dialog_id); END_PARSE_FLAGS(); } @@ -5036,33 +4667,56 @@ void MessagesManager::Message::parse(ParserT &parser) { if (has_random_id) { parse(random_id, parser); } - if (is_forwarded) { - forward_info = make_unique(); - parse(forward_info->sender_user_id, parser); - parse(forward_info->date, parser); - parse(forward_info->sender_dialog_id, parser); - parse(forward_info->message_id, parser); - if (has_forward_author_signature) { - parse(forward_info->author_signature, parser); - } - if (has_forward_sender_name) { - parse(forward_info->sender_name, parser); - } - if (has_forward_from) { - parse(forward_info->from_dialog_id, parser); - parse(forward_info->from_message_id, parser); - } - if (has_forward_psa_type) { - parse(forward_info->psa_type, parser); - } - forward_info->is_imported = is_imported; + if (has_forward_info) { + parse(forward_info, parser); + } else if (legacy_is_forwarded) { + MessageOrigin forward_origin; + int32 forward_date; + if (legacy_has_forward_origin) { + parse(forward_origin, parser); + parse(forward_date, parser); + } else { + UserId forward_sender_user_id; + DialogId forward_sender_dialog_id; + MessageId forward_message_id; + string forward_author_signature; + string forward_sender_name; + parse(forward_sender_user_id, parser); + parse(forward_date, parser); + parse(forward_sender_dialog_id, parser); + parse(forward_message_id, parser); + if (legacy_has_forward_author_signature) { + parse(forward_author_signature, parser); + } + if (legacy_has_forward_sender_name) { + parse(forward_sender_name, parser); + } + forward_origin = MessageOrigin(forward_sender_user_id, forward_sender_dialog_id, forward_message_id, + std::move(forward_author_signature), std::move(forward_sender_name)); + } + LastForwardedMessageInfo last_message_info; + if (legacy_has_forward_from) { + DialogId forward_from_dialog_id; + MessageId forward_from_message_id; + parse(forward_from_dialog_id, parser); + parse(forward_from_message_id, parser); + last_message_info = + LastForwardedMessageInfo(forward_from_dialog_id, forward_from_message_id, DialogId(), string(), 0, false); + } + string psa_type; + if (legacy_has_forward_psa_type) { + parse(psa_type, parser); + } + forward_info = td::make_unique( + std::move(forward_origin), forward_date, std::move(last_message_info), std::move(psa_type), legacy_is_imported); } if (has_real_forward_from) { parse(real_forward_from_dialog_id, parser); parse(real_forward_from_message_id, parser); } - if (is_reply) { - parse(reply_to_message_id, parser); + MessageId legacy_reply_to_message_id; + if (legacy_is_reply) { + parse(legacy_reply_to_message_id, parser); } if (is_reply_to_random_id) { parse(reply_to_random_id, parser); @@ -5108,8 +4762,9 @@ void MessagesManager::Message::parse(ParserT &parser) { if (has_sender_dialog_id) { parse(sender_dialog_id, parser); } - if (has_reply_in_dialog_id) { - parse(reply_in_dialog_id, parser); + DialogId legacy_reply_in_dialog_id; + if (legacy_has_reply_in_dialog_id) { + parse(legacy_reply_in_dialog_id, parser); } if (has_top_thread_message_id) { parse(top_thread_message_id, parser); @@ -5148,37 +4803,52 @@ void MessagesManager::Message::parse(ParserT &parser) { if (has_history_generation) { parse(history_generation, parser); } + if (is_reply_to_story) { + parse(reply_to_story_full_id, parser); + } + if (has_input_reply_to) { + parse(input_reply_to, parser); + } else if (!message_id.is_any_server()) { + if (reply_to_story_full_id.is_valid()) { + input_reply_to = MessageInputReplyTo(reply_to_story_full_id); + } else if (legacy_reply_to_message_id.is_valid()) { + input_reply_to = MessageInputReplyTo{legacy_reply_to_message_id, DialogId(), MessageQuote()}; + } + } + if (has_replied_message_info) { + parse(replied_message_info, parser); + } else { + replied_message_info = RepliedMessageInfo::legacy(legacy_reply_to_message_id, legacy_reply_in_dialog_id); + } + if (has_saved_messages_topic_id) { + parse(saved_messages_topic_id, parser); + } + if (has_initial_top_thread_message_id) { + parse(initial_top_thread_message_id, parser); + } + if (has_sender_boost_count) { + parse(sender_boost_count, parser); + } + if (has_via_business_bot_user_id) { + parse(via_business_bot_user_id, parser); + } + if (has_effect_id) { + parse(effect_id, parser); + } + if (has_fact_check) { + parse(fact_check, parser); + } + if (has_initial_sender_dialog_id) { + parse(initial_sender_dialog_id, parser); + } CHECK(content != nullptr); - is_content_secret |= - is_secret_message_content(ttl, content->get_type()); // repair is_content_secret for old messages + is_content_secret |= ttl.is_secret_message_content(content->get_type()); // repair is_content_secret for old messages if (hide_edit_date && content->get_type() == MessageContentType::LiveLocation) { hide_edit_date = false; } } -template -void MessagesManager::NotificationGroupInfo::store(StorerT &storer) const { - using td::store; - store(group_id, storer); - store(last_notification_date, storer); - store(last_notification_id, storer); - store(max_removed_notification_id, storer); - store(max_removed_message_id, storer); -} - -template -void MessagesManager::NotificationGroupInfo::parse(ParserT &parser) { - using td::parse; - parse(group_id, parser); - parse(last_notification_date, parser); - parse(last_notification_id, parser); - parse(max_removed_notification_id, parser); - if (parser.version() >= static_cast(Version::AddNotificationGroupInfoMaxRemovedMessageId)) { - parse(max_removed_message_id, parser); - } -} - template void MessagesManager::Dialog::store(StorerT &storer) const { using td::store; @@ -5200,21 +4870,19 @@ void MessagesManager::Dialog::store(StorerT &storer) const { bool has_deleted_last_message = delete_last_message_date > 0; bool has_last_clear_history_message_id = last_clear_history_message_id.is_valid(); bool has_last_database_message_id = !has_last_database_message && last_database_message_id.is_valid(); - bool has_message_notification_group = notification_info != nullptr && - notification_info->message_notification_group_.group_id.is_valid() && - !notification_info->message_notification_group_.try_reuse; - bool has_mention_notification_group = notification_info != nullptr && - notification_info->mention_notification_group_.group_id.is_valid() && - !notification_info->mention_notification_group_.try_reuse; + bool has_message_notification_group = + notification_info != nullptr && notification_info->message_notification_group_.is_active(); + bool has_mention_notification_group = + notification_info != nullptr && notification_info->mention_notification_group_.is_active(); bool has_new_secret_chat_notification_id = notification_info != nullptr && notification_info->new_secret_chat_notification_id_.is_valid(); bool has_pinned_message_notification = notification_info != nullptr && notification_info->pinned_message_notification_message_id_.is_valid(); bool has_last_pinned_message_id = last_pinned_message_id.is_valid(); bool has_flags2 = true; - bool has_max_notification_message_id = notification_info != nullptr && - notification_info->max_notification_message_id_.is_valid() && - notification_info->max_notification_message_id_ > last_new_message_id; + bool has_max_push_notification_message_id = + notification_info != nullptr && notification_info->max_push_notification_message_id_.is_valid() && + notification_info->max_push_notification_message_id_ > last_new_message_id; bool has_folder_id = folder_id != FolderId(); bool has_pending_read_channel_inbox = pending_read_channel_inbox_pts != 0; bool has_last_yet_unsent_message = last_message_id.is_valid() && last_message_id.is_yet_unsent(); @@ -5233,6 +4901,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const { bool has_available_reactions = !available_reactions.empty(); bool has_history_generation = history_generation != 0; bool has_background = background_info.is_valid(); + bool has_business_bot_manage_bar = business_bot_manage_bar != nullptr; BEGIN_STORE_FLAGS(); STORE_FLAG(has_draft_message); STORE_FLAG(has_last_database_message); @@ -5270,7 +4939,7 @@ void MessagesManager::Dialog::store(StorerT &storer) const { if (has_flags2) { BEGIN_STORE_FLAGS(); - STORE_FLAG(has_max_notification_message_id); + STORE_FLAG(has_max_push_notification_message_id); STORE_FLAG(has_folder_id); STORE_FLAG(is_folder_id_inited); STORE_FLAG(has_pending_read_channel_inbox); @@ -5320,6 +4989,13 @@ void MessagesManager::Dialog::store(StorerT &storer) const { STORE_FLAG(need_repair_unread_mention_count); STORE_FLAG(is_background_inited); STORE_FLAG(has_background); + STORE_FLAG(is_blocked_for_stories); + STORE_FLAG(is_is_blocked_for_stories_inited); + STORE_FLAG(view_as_messages); + STORE_FLAG(is_view_as_messages_inited); + STORE_FLAG(is_forum); + STORE_FLAG(is_saved_messages_view_as_messages_inited); + STORE_FLAG(has_business_bot_manage_bar); END_STORE_FLAGS(); } @@ -5390,8 +5066,8 @@ void MessagesManager::Dialog::store(StorerT &storer) const { if (has_last_pinned_message_id) { store(last_pinned_message_id, storer); } - if (has_max_notification_message_id) { - store(notification_info->max_notification_message_id_, storer); + if (has_max_push_notification_message_id) { + store(notification_info->max_push_notification_message_id_, storer); } if (has_folder_id) { store(folder_id, storer); @@ -5438,6 +5114,9 @@ void MessagesManager::Dialog::store(StorerT &storer) const { if (has_background) { store(background_info, storer); } + if (has_business_bot_manage_bar) { + store(business_bot_manage_bar, storer); + } } // do not forget to resolve dialog dependencies including dependencies of last_message @@ -5464,7 +5143,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { bool has_pinned_message_notification; bool has_last_pinned_message_id; bool has_flags2; - bool has_max_notification_message_id = false; + bool has_max_push_notification_message_id = false; bool has_folder_id = false; bool has_pending_read_channel_inbox = false; bool has_active_group_call_id = false; @@ -5489,6 +5168,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { bool has_available_reactions = false; bool has_history_generation = false; bool has_background = false; + bool has_business_bot_manage_bar = false; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_draft_message); PARSE_FLAG(has_last_database_message); @@ -5526,7 +5206,7 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_flags2) { BEGIN_PARSE_FLAGS(); - PARSE_FLAG(has_max_notification_message_id); + PARSE_FLAG(has_max_push_notification_message_id); PARSE_FLAG(has_folder_id); PARSE_FLAG(is_folder_id_inited); PARSE_FLAG(has_pending_read_channel_inbox); @@ -5591,11 +5271,24 @@ void MessagesManager::Dialog::parse(ParserT &parser) { PARSE_FLAG(need_repair_unread_mention_count); PARSE_FLAG(is_background_inited); PARSE_FLAG(has_background); + PARSE_FLAG(is_blocked_for_stories); + PARSE_FLAG(is_is_blocked_for_stories_inited); + PARSE_FLAG(view_as_messages); + PARSE_FLAG(is_view_as_messages_inited); + PARSE_FLAG(is_forum); + PARSE_FLAG(is_saved_messages_view_as_messages_inited); + PARSE_FLAG(has_business_bot_manage_bar); END_PARSE_FLAGS(); } else { need_repair_action_bar = false; is_available_reactions_inited = false; is_background_inited = false; + is_blocked_for_stories = false; + is_is_blocked_for_stories_inited = false; + view_as_messages = false; + is_view_as_messages_inited = false; + is_forum = false; + is_saved_messages_view_as_messages_inited = false; } parse(last_new_message_id, parser); @@ -5700,8 +5393,8 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_last_pinned_message_id) { parse(last_pinned_message_id, parser); } - if (has_max_notification_message_id) { - parse(add_dialog_notification_info(this)->max_notification_message_id_, parser); + if (has_max_push_notification_message_id) { + parse(add_dialog_notification_info(this)->max_push_notification_message_id_, parser); } if (has_folder_id) { parse(folder_id, parser); @@ -5740,9 +5433,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_available_reactions) { parse(available_reactions, parser); } else if (has_legacy_available_reactions) { - vector legacy_available_reactions; - parse(legacy_available_reactions, parser); - available_reactions = ChatReactions(std::move(legacy_available_reactions)); + vector legacy_available_reaction_types; + parse(legacy_available_reaction_types, parser); + available_reactions = ChatReactions::legacy(std::move(legacy_available_reaction_types)); } if (has_available_reactions_generation) { parse(available_reactions_generation, parser); @@ -5756,6 +5449,9 @@ void MessagesManager::Dialog::parse(ParserT &parser) { if (has_background) { parse(background_info, parser); } + if (has_business_bot_manage_bar) { + parse(business_bot_manage_bar, parser); + } (void)legacy_know_can_report_spam; if (know_action_bar && !has_action_bar) { @@ -5834,9 +5530,6 @@ MessagesManager::MessagesManager(Td *td, ActorShared<> parent) , parent_(std::move(parent)) { upload_media_callback_ = std::make_shared(); upload_thumbnail_callback_ = std::make_shared(); - upload_dialog_photo_callback_ = std::make_shared(); - upload_imported_messages_callback_ = std::make_shared(); - upload_imported_message_attachment_callback_ = std::make_shared(); channel_get_difference_timeout_.set_callback(on_channel_get_difference_timeout_callback); channel_get_difference_timeout_.set_callback_data(static_cast(this)); @@ -5868,12 +5561,6 @@ MessagesManager::MessagesManager(Td *td, ActorShared<> parent) pending_send_dialog_action_timeout_.set_callback(on_pending_send_dialog_action_timeout_callback); pending_send_dialog_action_timeout_.set_callback_data(static_cast(this)); - active_dialog_action_timeout_.set_callback(on_active_dialog_action_timeout_callback); - active_dialog_action_timeout_.set_callback_data(static_cast(this)); - - update_dialog_online_member_count_timeout_.set_callback(on_update_dialog_online_member_count_timeout_callback); - update_dialog_online_member_count_timeout_.set_callback_data(static_cast(this)); - preload_folder_dialog_list_timeout_.set_callback(on_preload_folder_dialog_list_timeout_callback); preload_folder_dialog_list_timeout_.set_callback_data(static_cast(this)); @@ -5888,14 +5575,20 @@ MessagesManager::~MessagesManager() { Scheduler::instance()->destroy_on_scheduler( G()->get_gc_scheduler_id(), ttl_nodes_, ttl_heap_, being_sent_messages_, update_message_ids_, update_scheduled_message_ids_, message_id_to_dialog_id_, last_clear_history_message_id_to_dialog_id_, dialogs_, - postponed_chat_read_inbox_updates_, found_public_dialogs_, found_on_server_dialogs_, found_common_dialogs_, - message_embedding_codes_[0], message_embedding_codes_[1], replied_by_media_timestamp_messages_, - notification_group_id_to_dialog_id_, pending_get_channel_differences_, active_get_channel_differences_, - get_channel_difference_to_log_event_id_, channel_get_difference_retry_timeouts_, is_channel_difference_finished_, - expected_channel_pts_, expected_channel_max_message_id_, resolved_usernames_, inaccessible_resolved_usernames_, - dialog_bot_command_message_ids_, full_message_id_to_file_source_id_, last_outgoing_forwarded_message_date_, - dialog_viewed_messages_, dialog_online_member_counts_, previous_repaired_read_inbox_max_message_id_, - failed_to_load_dialogs_); + postponed_chat_read_inbox_updates_, found_public_dialogs_, found_on_server_dialogs_, message_embedding_codes_[0], + message_embedding_codes_[1], message_to_replied_media_timestamp_messages_, + story_to_replied_media_timestamp_messages_, notification_group_id_to_dialog_id_, pending_get_channel_differences_, + active_get_channel_differences_, get_channel_difference_to_log_event_id_, channel_get_difference_retry_timeouts_, + is_channel_difference_finished_, expected_channel_pts_, expected_channel_max_message_id_, + dialog_bot_command_message_ids_, message_full_id_to_file_source_id_, last_outgoing_forwarded_message_date_, + dialog_viewed_messages_, previous_repaired_read_inbox_max_message_id_, failed_to_load_dialogs_); +} + +MessagesManager::AddDialogData::AddDialogData(int32 dependent_dialog_count, unique_ptr &&last_message, + unique_ptr &&draft_message) + : dependent_dialog_count_(dependent_dialog_count) + , last_message_(std::move(last_message)) + , draft_message_(std::move(draft_message)) { } void MessagesManager::on_channel_get_difference_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) { @@ -5966,7 +5659,7 @@ void MessagesManager::on_pending_unload_dialog_timeout_callback(void *messages_m auto messages_manager = static_cast(messages_manager_ptr); send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::unload_dialog, - DialogId(dialog_id_int)); + DialogId(dialog_id_int), -1); } void MessagesManager::on_dialog_unmute_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) { @@ -5989,55 +5682,69 @@ void MessagesManager::on_pending_send_dialog_action_timeout_callback(void *messa DialogId(dialog_id_int)); } -void MessagesManager::on_active_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) { +void MessagesManager::on_preload_folder_dialog_list_timeout_callback(void *messages_manager_ptr, int64 folder_id_int) { if (G()->close_flag()) { return; } auto messages_manager = static_cast(messages_manager_ptr); - send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::on_active_dialog_action_timeout, - DialogId(dialog_id_int)); + send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::preload_folder_dialog_list, + FolderId(narrow_cast(folder_id_int))); } -void MessagesManager::on_update_dialog_online_member_count_timeout_callback(void *messages_manager_ptr, - int64 dialog_id_int) { +void MessagesManager::on_update_viewed_messages_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) { if (G()->close_flag()) { return; } auto messages_manager = static_cast(messages_manager_ptr); - send_closure_later(messages_manager->actor_id(messages_manager), - &MessagesManager::on_update_dialog_online_member_count_timeout, DialogId(dialog_id_int)); + send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::on_update_viewed_messages_timeout, + DialogId(dialog_id_int)); } -void MessagesManager::on_preload_folder_dialog_list_timeout_callback(void *messages_manager_ptr, int64 folder_id_int) { +void MessagesManager::on_send_update_chat_read_inbox_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) { if (G()->close_flag()) { return; } auto messages_manager = static_cast(messages_manager_ptr); - send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::preload_folder_dialog_list, - FolderId(narrow_cast(folder_id_int))); + send_closure_later(messages_manager->actor_id(messages_manager), + &MessagesManager::on_send_update_chat_read_inbox_timeout, DialogId(dialog_id_int)); } -void MessagesManager::on_update_viewed_messages_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) { +void MessagesManager::on_live_location_expire_timeout_callback(void *messages_manager_ptr) { if (G()->close_flag()) { return; } auto messages_manager = static_cast(messages_manager_ptr); - send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::on_update_viewed_messages_timeout, - DialogId(dialog_id_int)); + send_closure_later(messages_manager->actor_id(messages_manager), &MessagesManager::on_live_location_expire_timeout); } -void MessagesManager::on_send_update_chat_read_inbox_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int) { - if (G()->close_flag()) { +void MessagesManager::on_live_location_expire_timeout() { + if (G()->close_flag() || !td_->auth_manager_->is_authorized()) { return; } - - auto messages_manager = static_cast(messages_manager_ptr); - send_closure_later(messages_manager->actor_id(messages_manager), - &MessagesManager::on_send_update_chat_read_inbox_timeout, DialogId(dialog_id_int)); + vector to_delete_message_full_ids; + for (const auto &message_full_id : active_live_location_message_full_ids_) { + auto m = get_message(message_full_id); + CHECK(m != nullptr); + auto live_period = get_message_content_live_location_period(m->content.get()); + if (live_period <= G()->unix_time() - m->date) { + to_delete_message_full_ids.push_back(message_full_id); + } + } + if (to_delete_message_full_ids.empty()) { + LOG(INFO) << "Have no messages to delete"; + schedule_active_live_location_expiration(); + } else { + for (auto message_full_id : to_delete_message_full_ids) { + bool is_deleted = delete_active_live_location(message_full_id); + CHECK(is_deleted); + } + send_update_active_live_location_messages(); + save_active_live_locations(); + } } BufferSlice MessagesManager::get_dialog_database_value(const Dialog *d) { @@ -6059,23 +5766,19 @@ void MessagesManager::save_dialog_to_database(DialogId dialog_id) { CHECK(d != nullptr); LOG(INFO) << "Save " << dialog_id << " to database"; vector changed_group_keys; - bool can_reuse_notification_group = false; if (d->notification_info != nullptr) { - auto add_group_key = [&](auto &group_info) { - if (group_info.is_changed) { - can_reuse_notification_group |= group_info.try_reuse; - changed_group_keys.emplace_back(group_info.group_id, group_info.try_reuse ? DialogId() : dialog_id, - group_info.last_notification_date); - group_info.is_changed = false; - } - }; - add_group_key(d->notification_info->message_notification_group_); - add_group_key(d->notification_info->mention_notification_group_); + d->notification_info->message_notification_group_.add_group_key_if_changed(changed_group_keys, dialog_id); + d->notification_info->mention_notification_group_.add_group_key_if_changed(changed_group_keys, dialog_id); + } + bool can_reuse_notification_group = false; + for (auto &group_key : changed_group_keys) { + if (group_key.dialog_id == DialogId()) { + can_reuse_notification_group = true; + } } - auto fixed_folder_id = d->folder_id == FolderId::archive() ? FolderId::archive() : FolderId::main(); G()->td_db()->get_dialog_db_async()->add_dialog( - dialog_id, fixed_folder_id, d->is_folder_id_inited ? d->order : 0, get_dialog_database_value(d), - std::move(changed_group_keys), PromiseCreator::lambda([dialog_id, can_reuse_notification_group](Result<> result) { + dialog_id, d->folder_id, d->order, get_dialog_database_value(d), std::move(changed_group_keys), + PromiseCreator::lambda([dialog_id, can_reuse_notification_group](Result<> result) { send_closure(G()->messages_manager(), &MessagesManager::on_save_dialog_to_database, dialog_id, can_reuse_notification_group, result.is_ok()); })); @@ -6097,26 +5800,11 @@ void MessagesManager::on_save_dialog_to_database(DialogId dialog_id, bool can_re } void MessagesManager::try_reuse_notification_group(NotificationGroupInfo &group_info) { - if (!group_info.try_reuse) { - return; - } - if (group_info.is_changed) { - LOG(ERROR) << "Failed to reuse changed " << group_info.group_id; - return; - } - group_info.try_reuse = false; - if (!group_info.group_id.is_valid()) { - LOG(ERROR) << "Failed to reuse invalid " << group_info.group_id; - return; + auto group_id = group_info.get_reused_group_id(); + if (group_id.is_valid()) { + send_closure_later(G()->notification_manager(), &NotificationManager::try_reuse_notification_group_id, group_id); + notification_group_id_to_dialog_id_.erase(group_id); } - CHECK(group_info.last_notification_id == NotificationId()); - CHECK(group_info.last_notification_date == 0); - send_closure_later(G()->notification_manager(), &NotificationManager::try_reuse_notification_group_id, - group_info.group_id); - notification_group_id_to_dialog_id_.erase(group_info.group_id); - group_info.group_id = NotificationGroupId(); - group_info.max_removed_notification_id = NotificationId(); - group_info.max_removed_message_id = MessageId(); } void MessagesManager::invalidate_message_indexes(Dialog *d) { @@ -6203,7 +5891,7 @@ int32 MessagesManager::get_message_index_mask(DialogId dialog_id, const Message index_mask |= message_search_filter_index_mask(MessageSearchFilter::Pinned); } // retain second condition just in case - if (m->is_content_secret || (m->ttl > 0 && !is_secret)) { + if (m->is_content_secret || (!m->ttl.is_empty() && !is_secret)) { return index_mask; } index_mask |= get_message_content_index_mask(m->content.get(), td_, m->is_outgoing); @@ -6252,187 +5940,10 @@ void MessagesManager::update_message_reply_count(Dialog *d, MessageId message_id } if (!is_recursive && is_discussion_message(d->dialog_id, m)) { - update_message_reply_count(get_dialog(m->forward_info->from_dialog_id), m->forward_info->from_message_id, - replier_dialog_id, reply_message_id, update_date, diff, true); - } -} - -tl_object_ptr MessagesManager::get_input_peer(DialogId dialog_id, - AccessRights access_rights) const { - switch (dialog_id.get_type()) { - case DialogType::User: - return td_->contacts_manager_->get_input_peer_user(dialog_id.get_user_id(), access_rights); - case DialogType::Chat: - return td_->contacts_manager_->get_input_peer_chat(dialog_id.get_chat_id(), access_rights); - case DialogType::Channel: - return td_->contacts_manager_->get_input_peer_channel(dialog_id.get_channel_id(), access_rights); - case DialogType::SecretChat: - return nullptr; - case DialogType::None: - return make_tl_object(); - default: - UNREACHABLE(); - return nullptr; - } -} - -tl_object_ptr MessagesManager::get_input_peer_force(DialogId dialog_id) { - switch (dialog_id.get_type()) { - case DialogType::User: { - UserId user_id = dialog_id.get_user_id(); - return make_tl_object(user_id.get(), 0); - } - case DialogType::Chat: { - ChatId chat_id = dialog_id.get_chat_id(); - return make_tl_object(chat_id.get()); - } - case DialogType::Channel: { - ChannelId channel_id = dialog_id.get_channel_id(); - return make_tl_object(channel_id.get(), 0); - } - case DialogType::SecretChat: - case DialogType::None: - return make_tl_object(); - default: - UNREACHABLE(); - return nullptr; - } -} - -vector> MessagesManager::get_input_peers(const vector &dialog_ids, - AccessRights access_rights) const { - vector> input_peers; - input_peers.reserve(dialog_ids.size()); - for (auto &dialog_id : dialog_ids) { - auto input_peer = get_input_peer(dialog_id, access_rights); - if (input_peer == nullptr) { - LOG(ERROR) << "Have no access to " << dialog_id; - continue; - } - input_peers.push_back(std::move(input_peer)); - } - return input_peers; -} - -tl_object_ptr MessagesManager::get_input_dialog_peer(DialogId dialog_id, - AccessRights access_rights) const { - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::Chat: - case DialogType::Channel: - case DialogType::None: - return make_tl_object(get_input_peer(dialog_id, access_rights)); - case DialogType::SecretChat: - return nullptr; - default: - UNREACHABLE(); - return nullptr; - } -} - -vector> MessagesManager::get_input_dialog_peers( - const vector &dialog_ids, AccessRights access_rights) const { - vector> input_dialog_peers; - input_dialog_peers.reserve(dialog_ids.size()); - for (auto &dialog_id : dialog_ids) { - auto input_dialog_peer = get_input_dialog_peer(dialog_id, access_rights); - if (input_dialog_peer == nullptr) { - LOG(ERROR) << "Have no access to " << dialog_id; - continue; - } - input_dialog_peers.push_back(std::move(input_dialog_peer)); - } - return input_dialog_peers; -} - -bool MessagesManager::have_input_peer(DialogId dialog_id, AccessRights access_rights) const { - switch (dialog_id.get_type()) { - case DialogType::User: { - UserId user_id = dialog_id.get_user_id(); - return td_->contacts_manager_->have_input_peer_user(user_id, access_rights); - } - case DialogType::Chat: { - ChatId chat_id = dialog_id.get_chat_id(); - return td_->contacts_manager_->have_input_peer_chat(chat_id, access_rights); - } - case DialogType::Channel: { - ChannelId channel_id = dialog_id.get_channel_id(); - return td_->contacts_manager_->have_input_peer_channel(channel_id, access_rights); - } - case DialogType::SecretChat: { - SecretChatId secret_chat_id = dialog_id.get_secret_chat_id(); - return td_->contacts_manager_->have_input_encrypted_peer(secret_chat_id, access_rights); - } - case DialogType::None: - return false; - default: - UNREACHABLE(); - return false; - } -} - -bool MessagesManager::have_dialog_info(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: { - UserId user_id = dialog_id.get_user_id(); - return td_->contacts_manager_->have_user(user_id); - } - case DialogType::Chat: { - ChatId chat_id = dialog_id.get_chat_id(); - return td_->contacts_manager_->have_chat(chat_id); - } - case DialogType::Channel: { - ChannelId channel_id = dialog_id.get_channel_id(); - return td_->contacts_manager_->have_channel(channel_id); - } - case DialogType::SecretChat: { - SecretChatId secret_chat_id = dialog_id.get_secret_chat_id(); - return td_->contacts_manager_->have_secret_chat(secret_chat_id); - } - case DialogType::None: - default: - return false; - } -} - -bool MessagesManager::have_dialog_info_force(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: { - UserId user_id = dialog_id.get_user_id(); - return td_->contacts_manager_->have_user_force(user_id); - } - case DialogType::Chat: { - ChatId chat_id = dialog_id.get_chat_id(); - return td_->contacts_manager_->have_chat_force(chat_id); - } - case DialogType::Channel: { - ChannelId channel_id = dialog_id.get_channel_id(); - return td_->contacts_manager_->have_channel_force(channel_id); - } - case DialogType::SecretChat: { - SecretChatId secret_chat_id = dialog_id.get_secret_chat_id(); - return td_->contacts_manager_->have_secret_chat_force(secret_chat_id); - } - case DialogType::None: - default: - return false; - } -} - -tl_object_ptr MessagesManager::get_input_encrypted_chat( - DialogId dialog_id, AccessRights access_rights) const { - switch (dialog_id.get_type()) { - case DialogType::SecretChat: { - SecretChatId secret_chat_id = dialog_id.get_secret_chat_id(); - return td_->contacts_manager_->get_input_encrypted_chat(secret_chat_id, access_rights); - } - case DialogType::User: - case DialogType::Chat: - case DialogType::Channel: - case DialogType::None: - default: - UNREACHABLE(); - return nullptr; + auto linked_message_full_id = m->forward_info->get_last_message_full_id(); + update_message_reply_count(get_dialog(linked_message_full_id.get_dialog_id()), + linked_message_full_id.get_message_id(), replier_dialog_id, reply_message_id, + update_date, diff, true); } } @@ -6457,37 +5968,34 @@ bool MessagesManager::is_allowed_useless_update(const tl_object_ptr &&update, int32 new_pts, int32 old_pts, int32 pts_count, const char *source) { + LOG(DEBUG) << "Skip old update with PTS = " << new_pts << ", current PTS = " << old_pts; if (update->get_id() == telegram_api::updateNewMessage::ID) { auto update_new_message = static_cast(update.get()); - auto full_message_id = FullMessageId::get_full_message_id(update_new_message->message_, false); - if (update_message_ids_.count(full_message_id) > 0) { - if (new_pts == old_pts || old_pts == std::numeric_limits::max()) { - // apply sent message anyway if it is definitely non-deleted or being skipped because of PTS overflow - auto added_full_message_id = on_get_message(std::move(update_new_message->message_), true, false, false, - "updateNewMessage with an awaited message"); - if (added_full_message_id != full_message_id) { - LOG(ERROR) << "Failed to add an awaited " << full_message_id << " from " << source; - } - return; - } else { - LOG(ERROR) << "Receive awaited sent " << full_message_id << " from " << source << " with PTS " << new_pts - << " and pts_count " << pts_count << ", but current PTS is " << old_pts; + auto message_full_id = MessageFullId::get_message_full_id(update_new_message->message_, false); + if (update_message_ids_.count(message_full_id) > 0) { + // apply the sent message anyway, even it could have been deleted or edited already + + CHECK(message_full_id.get_dialog_id().get_type() == DialogType::User || + message_full_id.get_dialog_id().get_type() == DialogType::Chat); // checked in check_pts_update + delete_messages_from_updates({message_full_id.get_message_id()}, false); + + auto added_message_full_id = on_get_message(std::move(update_new_message->message_), true, false, false, + "updateNewMessage with an awaited message"); + if (added_message_full_id != message_full_id) { + LOG(ERROR) << "Failed to add an awaited " << message_full_id << " from " << source; } + return; } } if (update->get_id() == updateSentMessage::ID) { auto update_sent_message = static_cast(update.get()); if (being_sent_messages_.count(update_sent_message->random_id_) > 0) { - if (new_pts == old_pts || old_pts == std::numeric_limits::max()) { - // apply sent message anyway if it is definitely non-deleted or being skipped because of PTS overflow - on_send_message_success(update_sent_message->random_id_, update_sent_message->message_id_, - update_sent_message->date_, update_sent_message->ttl_period_, FileId(), - "process old updateSentMessage"); - return; - } else if (update_sent_message->random_id_ != 0) { - LOG(ERROR) << "Receive awaited sent " << update_sent_message->message_id_ << " from " << source << " with PTS " - << new_pts << " and pts_count " << pts_count << ", but current PTS is " << old_pts; - } + // apply the sent message anyway, even it could have been deleted or edited already + delete_messages_from_updates({update_sent_message->message_id_}, false); + on_send_message_success(update_sent_message->random_id_, update_sent_message->message_id_, + update_sent_message->date_, update_sent_message->ttl_period_, FileId(), + "process old updateSentMessage"); + return; } return; } @@ -6498,12 +6006,43 @@ void MessagesManager::skip_old_pending_pts_update(tl_object_ptrcontacts_manager_->add_service_notifications_user(); + UserId service_notifications_user_id = td_->user_manager_->add_service_notifications_user(); DialogId service_notifications_dialog_id(service_notifications_user_id); force_create_dialog(service_notifications_dialog_id, "get_service_notifications_dialog"); return get_dialog(service_notifications_dialog_id); } +void MessagesManager::extract_authentication_codes(DialogId dialog_id, const Message *m, + vector &authentication_codes) { + CHECK(m != nullptr); + if (dialog_id != DialogId(UserManager::get_service_notifications_user_id()) || !m->message_id.is_valid() || + !m->message_id.is_server() || m->content->get_type() != MessageContentType::Text || m->is_outgoing) { + return; + } + auto *formatted_text = get_message_content_text(m->content.get()); + CHECK(formatted_text != nullptr); + const string &text = formatted_text->text; + for (size_t i = 0; i < text.size(); i++) { + if (is_digit(text[i])) { + string code; + do { + if (is_digit(text[i])) { + code += text[i++]; + continue; + } + if (text[i] == '-') { + i++; + continue; + } + break; + } while (true); + if (5 <= code.size() && code.size() <= 7) { + authentication_codes.push_back(code); + } + } + } +} + void MessagesManager::save_auth_notification_ids() { auto min_date = G()->unix_time() - AUTH_NOTIFICATION_ID_CACHE_TIME; vector stored_ids; @@ -6561,21 +6100,22 @@ void MessagesManager::on_update_service_notification(tl_object_ptrauth_manager_->is_authorized(); bool is_user = is_authorized && !td_->auth_manager_->is_bot(); - auto contacts_manager = is_authorized ? td_->contacts_manager_.get() : nullptr; - auto message_text = get_message_text(contacts_manager, std::move(update->message_), std::move(update->entities_), + auto user_manager = is_authorized ? td_->user_manager_.get() : nullptr; + auto message_text = get_message_text(user_manager, std::move(update->message_), std::move(update->entities_), skip_new_entities, !is_user, date, false, "on_update_service_notification"); DialogId owner_dialog_id = is_user ? get_service_notifications_dialog()->dialog_id : DialogId(); - int32 ttl = 0; + MessageSelfDestructType ttl; bool disable_web_page_preview = false; - auto content = get_message_content(td_, std::move(message_text), std::move(update->media_), owner_dialog_id, false, - UserId(), &ttl, &disable_web_page_preview, "updateServiceNotification"); - bool is_content_secret = is_secret_message_content(ttl, content->get_type()); + auto content = get_message_content(td_, std::move(message_text), std::move(update->media_), owner_dialog_id, date, + false, UserId(), &ttl, &disable_web_page_preview, "updateServiceNotification"); + bool is_content_secret = ttl.is_secret_message_content(content->get_type()); if (update->popup_) { send_closure(G()->td(), &Td::send_update, td_api::make_object( - update->type_, get_message_content_object(content.get(), td_, owner_dialog_id, date, - is_content_secret, true, -1))); + update->type_, get_message_content_object(content.get(), td_, owner_dialog_id, true, false, date, + is_content_secret, true, -1, update->invert_media_, + disable_web_page_preview))); } if (has_date && is_user) { Dialog *d = get_service_notifications_dialog(); @@ -6590,11 +6130,18 @@ void MessagesManager::on_update_service_notification(tl_object_ptrttl = ttl; new_message->disable_web_page_preview = disable_web_page_preview; new_message->is_content_secret = is_content_secret; + new_message->invert_media = update->invert_media_; new_message->content = std::move(content); bool need_update = true; bool need_update_dialog_pos = false; + Dependencies dependencies; + add_message_dependencies(dependencies, new_message.get()); + for (auto dependent_dialog_id : dependencies.get_dialog_ids()) { + force_create_dialog(dependent_dialog_id, "on_update_service_notification", true); + } + const Message *m = add_message_to_dialog(d, std::move(new_message), false, true, &need_update, &need_update_dialog_pos, "on_update_service_notification"); if (m != nullptr && need_update) { @@ -6619,12 +6166,7 @@ void MessagesManager::on_update_read_channel_inbox(tl_object_ptrflags_ & telegram_api::updateReadChannelInbox::FOLDER_ID_MASK) != 0) { - folder_id = FolderId(update->folder_id_); - } - on_update_dialog_folder_id(DialogId(channel_id), folder_id); + on_update_dialog_folder_id(DialogId(channel_id), FolderId(update->folder_id_)); on_read_channel_inbox(channel_id, MessageId(ServerMessageId(update->max_id_)), update->still_unread_count_, update->pts_, "updateReadChannelInbox"); } @@ -6701,6 +6243,10 @@ void MessagesManager::on_update_channel_too_long(tl_object_ptrchat_manager_->have_channel_force(channel_id, "on_update_channel_too_long")) { + LOG(INFO) << "Skip updateChannelTooLong about unknown " << channel_id; + return; + } DialogId dialog_id = DialogId(channel_id); auto d = get_dialog_force(dialog_id, "on_update_channel_too_long 4"); @@ -6727,32 +6273,32 @@ void MessagesManager::on_update_channel_too_long(tl_object_ptr &&reactions, Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); auto new_reactions = MessageReactions::get_message_reactions(td_, std::move(reactions), td_->auth_manager_->is_bot()); - if (!have_message_force(full_message_id, "on_update_message_reactions")) { - auto dialog_id = full_message_id.get_dialog_id(); - if (!have_input_peer(dialog_id, AccessRights::Read)) { - LOG(INFO) << "Ignore updateMessageReaction in inaccessible " << full_message_id; + if (!have_message_force(message_full_id, "on_update_message_reactions")) { + auto dialog_id = message_full_id.get_dialog_id(); + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { + LOG(INFO) << "Ignore updateMessageReaction in inaccessible " << message_full_id; promise.set_value(Unit()); return; } @@ -6774,46 +6320,47 @@ void MessagesManager::on_update_message_reactions(FullMessageId full_message_id, return; } - update_message_interaction_info(full_message_id, -1, -1, false, nullptr, true, std::move(new_reactions)); + update_message_interaction_info(message_full_id, -1, -1, false, nullptr, true, std::move(new_reactions)); promise.set_value(Unit()); } -void MessagesManager::update_message_reactions(FullMessageId full_message_id, +void MessagesManager::update_message_reactions(MessageFullId message_full_id, unique_ptr &&reactions) { - update_message_interaction_info(full_message_id, -1, -1, false, nullptr, true, std::move(reactions)); + update_message_interaction_info(message_full_id, -1, -1, false, nullptr, true, std::move(reactions)); } -void MessagesManager::on_get_message_reaction_list(FullMessageId full_message_id, const string &reaction, - FlatHashMap> reactions, int32 total_count) { - const Message *m = get_message_force(full_message_id, "on_get_message_reaction_list"); +void MessagesManager::on_get_message_reaction_list( + MessageFullId message_full_id, const ReactionType &reaction_type, + FlatHashMap, ReactionTypeHash> reaction_types, int32 total_count) { + const Message *m = get_message_force(message_full_id, "on_get_message_reaction_list"); if (m == nullptr || m->reactions == nullptr) { return; } // it's impossible to use received reactions to update message reactions, because there is no way to find, // which reactions are chosen by the current user, so just reload message reactions for consistency - if (m->reactions->are_consistent_with_list(reaction, std::move(reactions), total_count)) { + if (m->reactions->are_consistent_with_list(reaction_type, std::move(reaction_types), total_count)) { return; } - LOG(INFO) << "Need reload reactions in " << full_message_id << " for consistency"; + LOG(INFO) << "Need reload reactions in " << message_full_id << " for consistency"; - auto it = pending_reactions_.find(full_message_id); + auto it = pending_reactions_.find(message_full_id); if (it != pending_reactions_.end()) { it->second.was_updated = true; } else { - queue_message_reactions_reload(full_message_id); + queue_message_reactions_reload(message_full_id); } } -void MessagesManager::on_update_message_interaction_info(FullMessageId full_message_id, int32 view_count, +void MessagesManager::on_update_message_interaction_info(MessageFullId message_full_id, int32 view_count, int32 forward_count, bool has_reply_info, tl_object_ptr &&reply_info) { if (view_count < 0 || forward_count < 0) { - LOG(ERROR) << "Receive " << view_count << "/" << forward_count << " interaction counters for " << full_message_id; + LOG(ERROR) << "Receive " << view_count << "/" << forward_count << " interaction counters for " << message_full_id; return; } - update_message_interaction_info(full_message_id, view_count, forward_count, has_reply_info, std::move(reply_info), + update_message_interaction_info(message_full_id, view_count, forward_count, has_reply_info, std::move(reply_info), false, nullptr); } @@ -6861,7 +6408,7 @@ void MessagesManager::on_pending_message_views_timeout(DialogId dialog_id) { pending_message_views_.erase(it); } -void MessagesManager::update_message_interaction_info(FullMessageId full_message_id, int32 view_count, +void MessagesManager::update_message_interaction_info(MessageFullId message_full_id, int32 view_count, int32 forward_count, bool has_reply_info, tl_object_ptr &&reply_info, bool has_reactions, unique_ptr &&reactions) { @@ -6869,15 +6416,15 @@ void MessagesManager::update_message_interaction_info(FullMessageId full_message return; } - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog_force(dialog_id, "update_message_interaction_info"); if (d == nullptr) { return; } - auto message_id = full_message_id.get_message_id(); + auto message_id = message_full_id.get_message_id(); Message *m = get_message_force(d, message_id, "update_message_interaction_info"); if (m == nullptr) { - LOG(INFO) << "Ignore message interaction info about unknown " << full_message_id; + LOG(INFO) << "Ignore message interaction info about unknown " << message_full_id; if (!message_id.is_scheduled() && d->last_new_message_id.is_valid() && message_id > d->last_new_message_id && dialog_id.get_type() == DialogType::Channel) { get_channel_difference(dialog_id, d->pts, 0, message_id, true, "update_message_interaction_info"); @@ -6910,7 +6457,7 @@ bool MessagesManager::is_thread_message(DialogId dialog_id, const Message *m) co bool MessagesManager::is_thread_message(DialogId dialog_id, MessageId message_id, const MessageReplyInfo &reply_info, MessageContentType content_type) const { - if (dialog_id.get_type() != DialogType::Channel || is_broadcast_channel(dialog_id)) { + if (dialog_id.get_type() != DialogType::Channel || td_->dialog_manager_->is_broadcast_channel(dialog_id)) { return false; } if (!message_id.is_valid() || !message_id.is_server()) { @@ -6930,20 +6477,20 @@ bool MessagesManager::is_active_message_reply_info(DialogId dialog_id, const Mes if (!reply_info.is_comment_) { return true; } - if (!is_broadcast_channel(dialog_id)) { + if (!td_->dialog_manager_->is_broadcast_channel(dialog_id)) { return true; } auto channel_id = dialog_id.get_channel_id(); - if (!td_->contacts_manager_->get_channel_has_linked_channel(channel_id)) { + if (!td_->chat_manager_->get_channel_has_linked_channel(channel_id)) { return false; } auto linked_channel_id = - td_->contacts_manager_->get_channel_linked_channel_id(channel_id, "is_active_message_reply_info"); + td_->chat_manager_->get_channel_linked_channel_id(channel_id, "is_active_message_reply_info"); if (!linked_channel_id.is_valid()) { // keep the comment button while linked channel is unknown - send_closure_later(G()->contacts_manager(), &ContactsManager::load_channel_full, channel_id, false, Promise(), + send_closure_later(G()->chat_manager(), &ChatManager::load_channel_full, channel_id, false, Promise(), "is_active_message_reply_info"); return true; } @@ -6960,7 +6507,7 @@ bool MessagesManager::is_visible_message_reply_info(DialogId dialog_id, const Me if (!m->message_id.is_valid()) { return false; } - bool is_broadcast = is_broadcast_channel(dialog_id); + bool is_broadcast = td_->dialog_manager_->is_broadcast_channel(dialog_id); if (!m->message_id.is_server() && !(is_broadcast && m->message_id.is_yet_unsent())) { return false; } @@ -6971,8 +6518,8 @@ bool MessagesManager::is_visible_message_reply_info(DialogId dialog_id, const Me return false; } if (m->reply_info.is_comment_ && is_broadcast && - td_->contacts_manager_->have_channel_force(m->reply_info.channel_id_) && - !td_->contacts_manager_->have_input_peer_channel(m->reply_info.channel_id_, AccessRights::Read)) { + td_->chat_manager_->have_channel_force(m->reply_info.channel_id_, "is_visible_message_reply_info") && + !td_->chat_manager_->have_input_peer_channel(m->reply_info.channel_id_, AccessRights::Read)) { // keep the comment button while have no information about the linked channel return false; } @@ -6980,7 +6527,7 @@ bool MessagesManager::is_visible_message_reply_info(DialogId dialog_id, const Me } bool MessagesManager::is_visible_message_reactions(DialogId dialog_id, const Message *m) const { - if (m == nullptr || !m->message_id.is_valid()) { + if (m == nullptr) { return false; } @@ -6996,6 +6543,9 @@ bool MessagesManager::is_visible_message_reactions(DialogId dialog_id, const Mes } bool MessagesManager::has_unread_message_reactions(DialogId dialog_id, const Message *m) const { + if (td_->auth_manager_->is_bot()) { + return false; + } CHECK(m != nullptr); return m->reactions != nullptr && !m->reactions->unread_reactions_.empty() && is_visible_message_reactions(dialog_id, m); @@ -7015,11 +6565,12 @@ td_api::object_ptr MessagesManager::get_message_ DialogId dialog_id, const Message *m) const { bool is_visible_reply_info = is_visible_message_reply_info(dialog_id, m); bool has_reactions = - m->reactions != nullptr && !m->reactions->reactions_.empty() && is_visible_message_reactions(dialog_id, m); + m->reactions != nullptr && !m->reactions->are_empty() && is_visible_message_reactions(dialog_id, m); if (m->view_count == 0 && m->forward_count == 0 && !is_visible_reply_info && !has_reactions) { return nullptr; } - if (m->message_id.is_scheduled() && (m->forward_info == nullptr || is_broadcast_channel(dialog_id))) { + if (m->message_id.is_scheduled() && + (m->forward_info == nullptr || td_->dialog_manager_->is_broadcast_channel(dialog_id))) { return nullptr; } if (m->message_id.is_local() && m->forward_info == nullptr) { @@ -7035,12 +6586,12 @@ td_api::object_ptr MessagesManager::get_message_ CHECK(reply_info != nullptr); } - vector> reactions; + td_api::object_ptr reactions; if (has_reactions) { UserId my_user_id; UserId peer_user_id; if (dialog_id.get_type() == DialogType::User) { - my_user_id = td_->contacts_manager_->get_my_id(); + my_user_id = td_->user_manager_->get_my_id(); peer_user_id = dialog_id.get_user_id(); } reactions = m->reactions->get_message_reactions_object(td_, my_user_id, peer_user_id); @@ -7050,6 +6601,13 @@ td_api::object_ptr MessagesManager::get_message_ std::move(reactions)); } +td_api::object_ptr MessagesManager::get_message_fact_check_object(const Message *m) const { + if (m->fact_check == nullptr) { + return nullptr; + } + return m->fact_check->get_fact_check_object(td_->user_manager_.get()); +} + vector> MessagesManager::get_unread_reactions_object( DialogId dialog_id, const Message *m) const { if (!has_unread_message_reactions(dialog_id, m)) { @@ -7066,6 +6624,32 @@ vector> MessagesManager::get_unread_r return unread_reactions; } +bool MessagesManager::update_message_fact_check(const Dialog *d, Message *m, unique_ptr &&fact_check, + bool need_save) { + CHECK(m != nullptr); + if (td_->auth_manager_->is_bot() || !m->message_id.is_valid() || !m->message_id.is_server()) { + return false; + } + if (fact_check != nullptr && m->fact_check != nullptr) { + fact_check->update_from(*m->fact_check); + } + bool need_update = false; + if (fact_check != m->fact_check) { + if ((fact_check != nullptr && !fact_check->need_check()) || + (m->fact_check != nullptr && !m->fact_check->need_check())) { + need_update = true; + } + m->fact_check = std::move(fact_check); + if (need_save) { + on_message_changed(d, m, false, "update_message_fact_check"); + } + } + if (need_update) { + send_update_message_fact_check(d->dialog_id, m); + } + return need_update; +} + bool MessagesManager::update_message_interaction_info(Dialog *d, Message *m, int32 view_count, int32 forward_count, bool has_reply_info, MessageReplyInfo &&reply_info, bool has_reactions, unique_ptr &&reactions, @@ -7094,28 +6678,26 @@ bool MessagesManager::update_message_interaction_info(Dialog *d, Message *m, int } } } + MessageFullId message_full_id{dialog_id, m->message_id}; if (has_reactions) { - auto it = pending_reactions_.find({dialog_id, m->message_id}); + auto it = pending_reactions_.find(message_full_id); if (it != pending_reactions_.end()) { - LOG(INFO) << "Ignore reactions, because have a pending message reaction"; + LOG(INFO) << "Ignore reactions for " << message_full_id << ", because they are being changed"; has_reactions = false; it->second.was_updated = true; } - if (has_reactions && pending_read_reactions_.count({dialog_id, m->message_id}) > 0) { - LOG(INFO) << "Ignore reactions, because have a pending message reaction read"; + if (has_reactions && pending_read_reactions_.count(message_full_id) > 0) { + LOG(INFO) << "Ignore reactions for " << message_full_id << ", because they are being read"; has_reactions = false; } } if (has_reactions && reactions != nullptr) { if (m->reactions != nullptr) { - reactions->update_from(*m->reactions); + reactions->update_from(*m->reactions, td_->dialog_manager_->get_my_dialog_id()); } reactions->sort_reactions(active_reaction_pos_); - reactions->fix_chosen_reaction(get_my_dialog_id()); - if (d->default_send_message_as_dialog_id.is_valid()) { - // the reaction could be set by previous owner of the broadcast - // reactions->fix_chosen_reaction(d->default_send_message_as_dialog_id); - } + reactions->fix_chosen_reaction(); + reactions->fix_my_recent_chooser_dialog_id(td_->dialog_manager_->get_my_dialog_id()); } bool need_update_reactions = has_reactions && MessageReactions::need_update_message_reactions(m->reactions.get(), reactions.get()); @@ -7125,9 +6707,13 @@ bool MessagesManager::update_message_interaction_info(Dialog *d, Message *m, int m->reactions->chosen_reaction_order_ != reactions->chosen_reaction_order_; if (view_count > m->view_count || forward_count > m->forward_count || need_update_reply_info || need_update_reactions || need_update_unread_reactions || need_update_chosen_reaction_order) { - LOG(DEBUG) << "Update interaction info of " << FullMessageId{dialog_id, m->message_id} << " from " << m->view_count - << '/' << m->forward_count << '/' << m->reply_info << '/' << m->reactions << " to " << view_count << '/' - << forward_count << '/' << reply_info << '/' << reactions; + LOG(DEBUG) << "Update interaction info of " << message_full_id << " from " << m->view_count << '/' + << m->forward_count << '/' << m->reply_info << '/' << m->reactions << " to " << view_count << '/' + << forward_count << '/' << reply_info << '/' << reactions + << ", need_update_reply_info = " << need_update_reply_info + << ", need_update_reactions = " << need_update_reactions + << ", need_update_unread_reactions = " << need_update_unread_reactions + << ", need_update_chosen_reaction_order = " << need_update_chosen_reaction_order; bool need_update = false; if (view_count > m->view_count) { m->view_count = view_count; @@ -7140,8 +6726,8 @@ bool MessagesManager::update_message_interaction_info(Dialog *d, Message *m, int if (need_update_reply_info) { if (m->reply_info.channel_id_ != reply_info.channel_id_) { if (m->reply_info.channel_id_.is_valid() && reply_info.channel_id_.is_valid() && m->message_id.is_server()) { - LOG(ERROR) << "Reply info of " << FullMessageId{dialog_id, m->message_id} << " changed from " << m->reply_info - << " to " << reply_info << " from " << source; + LOG(ERROR) << "Reply info of " << message_full_id << " changed from " << m->reply_info << " to " << reply_info + << " from " << source; } } m->reply_info = std::move(reply_info); @@ -7154,11 +6740,15 @@ bool MessagesManager::update_message_interaction_info(Dialog *d, Message *m, int if (need_update_reactions || need_update_unread_reactions) { CHECK(m->message_id.is_valid()); + auto old_chosen_tags = get_chosen_tags(m->reactions); int32 unread_reaction_diff = 0; unread_reaction_diff -= (has_unread_message_reactions(dialog_id, m) ? 1 : 0); m->reactions = std::move(reactions); m->available_reactions_generation = d->available_reactions_generation; unread_reaction_diff += (has_unread_message_reactions(dialog_id, m) ? 1 : 0); + auto new_chosen_tags = get_chosen_tags(m->reactions); + + td_->reaction_manager_->update_saved_messages_tags(m->saved_messages_topic_id, old_chosen_tags, new_chosen_tags); if (is_visible_message_reactions(dialog_id, m)) { need_update |= need_update_reactions; @@ -7211,28 +6801,28 @@ bool MessagesManager::update_message_interaction_info(Dialog *d, Message *m, int return false; } -void MessagesManager::on_update_live_location_viewed(FullMessageId full_message_id) { - LOG(DEBUG) << "Live location was viewed in " << full_message_id; +void MessagesManager::on_update_live_location_viewed(MessageFullId message_full_id) { + LOG(DEBUG) << "Live location was viewed in " << message_full_id; if (!are_active_live_location_messages_loaded_) { - get_active_live_location_messages(PromiseCreator::lambda([actor_id = actor_id(this), full_message_id](Unit result) { - send_closure(actor_id, &MessagesManager::on_update_live_location_viewed, full_message_id); - })); + load_active_live_location_messages( + PromiseCreator::lambda([actor_id = actor_id(this), message_full_id](Unit result) { + send_closure(actor_id, &MessagesManager::on_update_live_location_viewed, message_full_id); + })); return; } - auto active_live_location_message_ids = get_active_live_location_messages(Auto()); - if (!td::contains(active_live_location_message_ids, full_message_id)) { - LOG(DEBUG) << "Can't find " << full_message_id << " in " << active_live_location_message_ids; + if (!td::contains(active_live_location_message_full_ids_, message_full_id)) { + LOG(DEBUG) << "Can't find " << message_full_id; return; } - send_update_message_live_location_viewed(full_message_id); + send_update_message_live_location_viewed(message_full_id); } void MessagesManager::on_update_some_live_location_viewed(Promise &&promise) { LOG(DEBUG) << "Some live location was viewed"; if (!are_active_live_location_messages_loaded_) { - get_active_live_location_messages( + load_active_live_location_messages( PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)](Unit result) mutable { send_closure(actor_id, &MessagesManager::on_update_some_live_location_viewed, std::move(promise)); })); @@ -7240,41 +6830,33 @@ void MessagesManager::on_update_some_live_location_viewed(Promise &&promis } // update all live locations, because it is unknown, which exactly was viewed - auto active_live_location_message_ids = get_active_live_location_messages(Auto()); - for (const auto &full_message_id : active_live_location_message_ids) { - send_update_message_live_location_viewed(full_message_id); + for (const auto &message_full_id : active_live_location_message_full_ids_) { + send_update_message_live_location_viewed(message_full_id); } promise.set_value(Unit()); } void MessagesManager::on_update_message_extended_media( - FullMessageId full_message_id, telegram_api::object_ptr extended_media) { - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "on_update_message_extended_media"); + MessageFullId message_full_id, + vector> extended_media) { + auto dialog_id = message_full_id.get_dialog_id(); + Dialog *d = get_dialog_force(dialog_id, "on_update_message_extended_media 1"); if (d == nullptr) { LOG(INFO) << "Ignore update of message extended media in unknown " << dialog_id; return; } - auto m = get_message_force(d, full_message_id.get_message_id(), "on_update_message_extended_media"); + auto m = get_message_force(d, message_full_id.get_message_id(), "on_update_message_extended_media 2"); if (m == nullptr) { - LOG(INFO) << "Ignore update of message extended media in unknown " << full_message_id; + LOG(INFO) << "Ignore update of message extended media in unknown " << message_full_id; return; } - auto content = m->content.get(); - auto content_type = content->get_type(); - if (content_type != MessageContentType::Invoice) { - if (content_type != MessageContentType::Unsupported) { - LOG(ERROR) << "Receive updateMessageExtendedMedia for " << full_message_id << " of type " << content_type; - } - return; - } - if (update_message_content_extended_media(content, std::move(extended_media), dialog_id, td_)) { - send_update_message_content(d, m, true, "on_update_message_extended_media"); - on_message_changed(d, m, true, "on_update_message_extended_media"); - on_message_notification_changed(d, m, "on_update_message_extended_media"); // usually a no-op + if (update_message_content_extended_media(m->content.get(), std::move(extended_media), dialog_id, td_)) { + send_update_message_content(d, m, true, "on_update_message_extended_media 3"); + on_message_changed(d, m, true, "on_update_message_extended_media 4"); + on_message_notification_changed(d, m, "on_update_message_extended_media 5"); // usually a no-op } } @@ -7288,31 +6870,33 @@ bool MessagesManager::need_skip_bot_commands(DialogId dialog_id, const Message * } auto d = get_dialog(dialog_id); - CHECK(d != nullptr); - return (d->is_has_bots_inited && !d->has_bots) || is_broadcast_channel(dialog_id); + return (d != nullptr && d->is_has_bots_inited && !d->has_bots) || + td_->dialog_manager_->is_broadcast_channel(dialog_id); } -void MessagesManager::on_external_update_message_content(FullMessageId full_message_id) { - Dialog *d = get_dialog(full_message_id.get_dialog_id()); +void MessagesManager::on_external_update_message_content(MessageFullId message_full_id, const char *source, + bool expect_no_message) { + Dialog *d = get_dialog(message_full_id.get_dialog_id()); CHECK(d != nullptr); - Message *m = get_message(d, full_message_id.get_message_id()); + Message *m = get_message(d, message_full_id.get_message_id()); + if (expect_no_message && m == nullptr) { + return; + } CHECK(m != nullptr); - send_update_message_content(d, m, true, "on_external_update_message_content"); + send_update_message_content(d, m, true, source); // must not call on_message_changed, because the message itself wasn't changed - if (m->message_id == d->last_message_id) { - send_update_chat_last_message_impl(d, "on_external_update_message_content"); - } - on_message_notification_changed(d, m, "on_external_update_message_content"); + send_update_last_message_if_needed(d, m, source); + on_message_notification_changed(d, m, source); } -void MessagesManager::on_update_message_content(FullMessageId full_message_id) { - Dialog *d = get_dialog(full_message_id.get_dialog_id()); +void MessagesManager::on_update_message_content(MessageFullId message_full_id) { + Dialog *d = get_dialog(message_full_id.get_dialog_id()); CHECK(d != nullptr); - Message *m = get_message(d, full_message_id.get_message_id()); + Message *m = get_message(d, message_full_id.get_message_id()); CHECK(m != nullptr); - send_update_message_content(d, m, true, "on_update_message_content"); - on_message_changed(d, m, true, "on_update_message_content"); - on_message_notification_changed(d, m, "on_update_message_content"); + send_update_message_content(d, m, true, "on_update_message_content 1"); + on_message_changed(d, m, true, "on_update_message_content 2"); + on_message_notification_changed(d, m, "on_update_message_content 3"); } bool MessagesManager::update_message_contains_unread_mention(Dialog *d, Message *m, bool contains_unread_mention, @@ -7402,7 +6986,7 @@ void MessagesManager::on_read_channel_inbox(ChannelId channel_id, MessageId max_ // update from the future, keep it until it can be applied if (pts >= d->pending_read_channel_inbox_pts) { if (d->pending_read_channel_inbox_pts == 0) { - schedule_get_channel_difference(dialog_id, pts, MessageId(), 0.001); + schedule_get_channel_difference(dialog_id, pts, MessageId(), 0.001, "on_read_channel_inbox"); } d->pending_read_channel_inbox_pts = pts; d->pending_read_channel_inbox_max_message_id = max_message_id; @@ -7421,46 +7005,20 @@ void MessagesManager::on_read_channel_outbox(ChannelId channel_id, MessageId max } void MessagesManager::on_update_channel_max_unavailable_message_id(ChannelId channel_id, - MessageId max_unavailable_message_id) { + MessageId max_unavailable_message_id, + const char *source) { if (!channel_id.is_valid()) { - LOG(ERROR) << "Receive max_unavailable_message_id in invalid " << channel_id; + LOG(ERROR) << "Receive max_unavailable_message_id in invalid " << channel_id << " from " << source; return; } DialogId dialog_id(channel_id); CHECK(!max_unavailable_message_id.is_scheduled()); if (!max_unavailable_message_id.is_valid() && max_unavailable_message_id != MessageId()) { - LOG(ERROR) << "Receive wrong max_unavailable_message_id: " << max_unavailable_message_id; + LOG(ERROR) << "Receive wrong max_unavailable_message_id: " << max_unavailable_message_id << " from " << source; max_unavailable_message_id = MessageId(); } - set_dialog_max_unavailable_message_id(dialog_id, max_unavailable_message_id, true, - "on_update_channel_max_unavailable_message_id"); -} - -void MessagesManager::on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, - bool is_from_server) { - if (td_->auth_manager_->is_bot()) { - return; - } - - if (!dialog_id.is_valid()) { - LOG(ERROR) << "Receive number of online members in invalid " << dialog_id; - return; - } - - if (is_broadcast_channel(dialog_id)) { - LOG_IF(ERROR, online_member_count != 0) - << "Receive " << online_member_count << " as a number of online members in a channel " << dialog_id; - return; - } - - if (online_member_count < 0) { - LOG(ERROR) << "Receive " << online_member_count << " as a number of online members in a " << dialog_id; - return; - } - - set_dialog_online_member_count(dialog_id, online_member_count, is_from_server, - "on_update_channel_online_member_count"); + set_dialog_max_unavailable_message_id(dialog_id, max_unavailable_message_id, true, source); } void MessagesManager::on_update_delete_scheduled_messages(DialogId dialog_id, @@ -7500,189 +7058,20 @@ void MessagesManager::on_update_delete_scheduled_messages(DialogId dialog_id, send_update_chat_has_scheduled_messages(d, true); } -void MessagesManager::on_update_created_public_broadcasts(vector channel_ids) { - if (td_->auth_manager_->is_bot()) { - // just in case - return; - } - - if (created_public_broadcasts_inited_ && created_public_broadcasts_ == channel_ids) { - return; - } - - LOG(INFO) << "Update create public channels to " << channel_ids; - for (auto channel_id : channel_ids) { - force_create_dialog(DialogId(channel_id), "on_update_created_public_broadcasts"); +void MessagesManager::on_dialog_speaking_action(DialogId dialog_id, DialogId speaking_dialog_id, int32 date) { + const Dialog *d = get_dialog_force(dialog_id, "on_dialog_speaking_action"); + if (d != nullptr && d->active_group_call_id.is_valid()) { + auto group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, dialog_id); + td_->group_call_manager_->on_user_speaking_in_group_call(group_call_id, speaking_dialog_id, false, date); } - - created_public_broadcasts_inited_ = true; - created_public_broadcasts_ = std::move(channel_ids); } -void MessagesManager::on_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id, - DialogAction action, int32 date, MessageContentType message_content_type) { - if (td_->auth_manager_->is_bot() || !typing_dialog_id.is_valid()) { - return; - } - if (top_thread_message_id != MessageId() && !top_thread_message_id.is_valid()) { - LOG(ERROR) << "Ignore " << action << " in the message thread of " << top_thread_message_id; - return; - } - - auto dialog_type = dialog_id.get_type(); - if (action == DialogAction::get_speaking_action()) { - if ((dialog_type != DialogType::Chat && dialog_type != DialogType::Channel) || top_thread_message_id.is_valid()) { - LOG(ERROR) << "Receive " << action << " in thread of " << top_thread_message_id << " in " << dialog_id; - return; - } - const Dialog *d = get_dialog_force(dialog_id, "on_dialog_action"); - if (d != nullptr && d->active_group_call_id.is_valid()) { - auto group_call_id = td_->group_call_manager_->get_group_call_id(d->active_group_call_id, dialog_id); - td_->group_call_manager_->on_user_speaking_in_group_call(group_call_id, typing_dialog_id, false, date); - } - return; - } - - if (is_broadcast_channel(dialog_id)) { - return; - } - - auto typing_dialog_type = typing_dialog_id.get_type(); - if (typing_dialog_type != DialogType::User && dialog_type != DialogType::Chat && dialog_type != DialogType::Channel) { - LOG(ERROR) << "Ignore " << action << " of " << typing_dialog_id << " in " << dialog_id; - return; - } - - { - auto message_import_progress = action.get_importing_messages_action_progress(); - if (message_import_progress >= 0) { - // TODO - return; - } - } - - { - auto clicking_info = action.get_clicking_animated_emoji_action_info(); - if (!clicking_info.data.empty()) { - if (date > G()->unix_time() - 10 && dialog_type == DialogType::User && dialog_id == typing_dialog_id) { - FullMessageId full_message_id{dialog_id, MessageId(ServerMessageId(clicking_info.message_id))}; - auto *m = get_message_force(full_message_id, "on_dialog_action"); - if (m != nullptr) { - on_message_content_animated_emoji_clicked(m->content.get(), full_message_id, td_, - std::move(clicking_info.emoji), std::move(clicking_info.data)); - } - } - return; - } - } - - if (is_unsent_animated_emoji_click(td_, dialog_id, action)) { - LOG(DEBUG) << "Ignore unsent " << action; - return; - } - - if (!have_dialog(dialog_id)) { - LOG(DEBUG) << "Ignore " << action << " in unknown " << dialog_id; - return; - } - - if (typing_dialog_type == DialogType::User) { - if (!td_->contacts_manager_->have_min_user(typing_dialog_id.get_user_id())) { - LOG(DEBUG) << "Ignore " << action << " of unknown " << typing_dialog_id.get_user_id(); - return; - } - } else { - if (!have_dialog_info_force(typing_dialog_id)) { - LOG(DEBUG) << "Ignore " << action << " of unknown " << typing_dialog_id; - return; - } - force_create_dialog(typing_dialog_id, "on_dialog_action", true); - if (!have_dialog(typing_dialog_id)) { - LOG(ERROR) << "Failed to create typing " << typing_dialog_id; - return; - } - } - - bool is_canceled = action == DialogAction(); - if ((!is_canceled || message_content_type != MessageContentType::None) && typing_dialog_type == DialogType::User) { - td_->contacts_manager_->on_update_user_local_was_online(typing_dialog_id.get_user_id(), date); - } - - if (dialog_type == DialogType::User || dialog_type == DialogType::SecretChat) { - CHECK(typing_dialog_type == DialogType::User); - auto user_id = typing_dialog_id.get_user_id(); - if (!td_->contacts_manager_->is_user_bot(user_id) && !td_->contacts_manager_->is_user_status_exact(user_id) && - !is_dialog_opened(dialog_id) && !is_canceled) { - return; - } - } - - if (is_canceled) { - // passed top_thread_message_id must be ignored - auto actions_it = active_dialog_actions_.find(dialog_id); - if (actions_it == active_dialog_actions_.end()) { - return; - } - - auto &active_actions = actions_it->second; - auto it = std::find_if( - active_actions.begin(), active_actions.end(), - [typing_dialog_id](const ActiveDialogAction &action) { return action.typing_dialog_id == typing_dialog_id; }); - if (it == active_actions.end()) { - return; - } - - if (!(typing_dialog_type == DialogType::User && - td_->contacts_manager_->is_user_bot(typing_dialog_id.get_user_id())) && - !it->action.is_canceled_by_message_of_type(message_content_type)) { - return; - } - - LOG(DEBUG) << "Cancel action of " << typing_dialog_id << " in " << dialog_id; - top_thread_message_id = it->top_thread_message_id; - active_actions.erase(it); - if (active_actions.empty()) { - active_dialog_actions_.erase(dialog_id); - LOG(DEBUG) << "Cancel action timeout in " << dialog_id; - active_dialog_action_timeout_.cancel_timeout(dialog_id.get()); - } - } else { - if (date < G()->unix_time_cached() - DIALOG_ACTION_TIMEOUT - 60) { - LOG(DEBUG) << "Ignore too old action of " << typing_dialog_id << " in " << dialog_id << " sent at " << date; - return; - } - auto &active_actions = active_dialog_actions_[dialog_id]; - auto it = std::find_if( - active_actions.begin(), active_actions.end(), - [typing_dialog_id](const ActiveDialogAction &action) { return action.typing_dialog_id == typing_dialog_id; }); - MessageId prev_top_thread_message_id; - DialogAction prev_action; - if (it != active_actions.end()) { - LOG(DEBUG) << "Re-add action of " << typing_dialog_id << " in " << dialog_id; - prev_top_thread_message_id = it->top_thread_message_id; - prev_action = it->action; - active_actions.erase(it); - } else { - LOG(DEBUG) << "Add action of " << typing_dialog_id << " in " << dialog_id; - } - - active_actions.emplace_back(top_thread_message_id, typing_dialog_id, action, Time::now()); - if (top_thread_message_id == prev_top_thread_message_id && action == prev_action) { - return; - } - if (top_thread_message_id != prev_top_thread_message_id && prev_top_thread_message_id.is_valid()) { - send_update_chat_action(dialog_id, prev_top_thread_message_id, typing_dialog_id, DialogAction()); - } - if (active_actions.size() == 1u) { - LOG(DEBUG) << "Set action timeout in " << dialog_id; - active_dialog_action_timeout_.set_timeout_in(dialog_id.get(), DIALOG_ACTION_TIMEOUT); - } - } - - if (top_thread_message_id.is_valid()) { - send_update_chat_action(dialog_id, MessageId(), typing_dialog_id, action); +void MessagesManager::on_message_animated_emoji_clicked(MessageFullId message_full_id, string &&emoji, string &&data) { + const auto *m = get_message_force(message_full_id, "on_message_animated_emoji_clicked"); + if (m != nullptr) { + on_message_content_animated_emoji_clicked(m->content.get(), message_full_id, td_, std::move(emoji), + std::move(data)); } - send_update_chat_action(dialog_id, top_thread_message_id, typing_dialog_id, action); } void MessagesManager::cancel_dialog_action(DialogId dialog_id, const Message *m) { @@ -7692,8 +7081,8 @@ void MessagesManager::cancel_dialog_action(DialogId dialog_id, const Message *m) return; } - on_dialog_action(dialog_id, MessageId() /*ignored*/, get_message_sender(m), DialogAction(), m->date, - m->content->get_type()); + td_->dialog_action_manager_->on_dialog_action(dialog_id, MessageId() /*ignored*/, get_message_sender(m), + DialogAction(), m->date, m->content->get_type()); } void MessagesManager::add_postponed_channel_update(DialogId dialog_id, tl_object_ptr &&update, @@ -7705,7 +7094,6 @@ void MessagesManager::add_postponed_channel_update(DialogId dialog_id, tl_object void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_ptr &&update, int32 new_pts, int32 pts_count, Promise &&promise, const char *source, bool is_postponed_update) { - LOG(INFO) << "Receive from " << source << " pending " << to_string(update); CHECK(update != nullptr); if (dialog_id.get_type() != DialogType::Channel) { LOG(ERROR) << "Receive channel update in invalid " << dialog_id << " from " << source << ": " @@ -7721,7 +7109,7 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p } auto channel_id = dialog_id.get_channel_id(); - if (!td_->contacts_manager_->have_channel(channel_id) && td_->contacts_manager_->have_min_channel(channel_id)) { + if (!td_->chat_manager_->have_channel(channel_id) && td_->chat_manager_->have_min_channel(channel_id)) { td_->updates_manager_->schedule_get_difference("add_pending_channel_update 1"); promise.set_value(Unit()); return; @@ -7734,28 +7122,13 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p if (d == nullptr) { auto pts = load_channel_pts(dialog_id); if (pts > 0) { - if (!td_->contacts_manager_->have_channel(channel_id)) { + if (!td_->chat_manager_->have_channel(channel_id)) { // do not create dialog if there is no info about the channel LOG(INFO) << "There is no info about " << channel_id << ", so ignore " << oneline(to_string(update)); promise.set_value(Unit()); return; } - if (new_pts <= pts && new_pts >= pts - 19999) { - LOG(INFO) << "There is no need to process an update with PTS " << new_pts << " in " << dialog_id << " with PTS " - << pts; - promise.set_value(Unit()); - return; - } - - if (new_pts > pts && pts != new_pts - pts_count) { - LOG(INFO) << "Found a gap in unknown " << dialog_id << " with PTS = " << pts << ". new_pts = " << new_pts - << ", pts_count = " << pts_count << " in update from " << source; - add_postponed_channel_update(dialog_id, std::move(update), new_pts, pts_count, std::move(promise)); - get_channel_difference(dialog_id, pts, new_pts, MessageId(), true, "add_pending_channel_update 3"); - return; - } - d = add_dialog(dialog_id, "add_pending_channel_update 4"); CHECK(d != nullptr); CHECK(d->pts == pts); @@ -7764,7 +7137,8 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p } if (d == nullptr) { // if there is no dialog, it can be created by the update - LOG(INFO) << "Receive pending update from " << source << " about unknown " << dialog_id; + LOG(INFO) << "Receive from " << source << " pending update about unknown " << dialog_id << ": " + << to_string(update); if (running_get_channel_difference(dialog_id)) { add_postponed_channel_update(dialog_id, std::move(update), new_pts, pts_count, std::move(promise)); return; @@ -7775,13 +7149,13 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p if (update->get_id() == telegram_api::updateNewChannelMessage::ID) { auto update_new_channel_message = static_cast(update.get()); auto message_id = MessageId::get_message_id(update_new_channel_message->message_, false); - FullMessageId full_message_id(dialog_id, message_id); - if (update_message_ids_.count(full_message_id) > 0) { + MessageFullId message_full_id(dialog_id, message_id); + if (update_message_ids_.count(message_full_id) > 0) { // apply sent channel message - auto added_full_message_id = on_get_message(std::move(update_new_channel_message->message_), true, true, + auto added_message_full_id = on_get_message(std::move(update_new_channel_message->message_), true, true, false, "updateNewChannelMessage with an awaited message"); - if (added_full_message_id != full_message_id) { - LOG(ERROR) << "Failed to add an awaited " << full_message_id << " from " << source; + if (added_message_full_id != message_full_id) { + LOG(ERROR) << "Failed to add an awaited " << message_full_id << " from " << source; } promise.set_value(Unit()); return; @@ -7801,22 +7175,26 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p LOG_IF(WARNING, new_pts == old_pts && pts_count == 0 && !is_allowed_useless_update(update)) << "Receive from " << source << " useless channel update " << oneline(to_string(update)); - LOG(INFO) << "Skip already applied channel update"; + LOG(INFO) << "Skip already applied channel update with PTS " << new_pts << " from " << source; + Scheduler::instance()->destroy_on_scheduler_unique_ptr(G()->get_gc_scheduler_id(), update); promise.set_value(Unit()); return; } + LOG(INFO) << "Receive from " << source << " pending " << to_string(update); if (running_get_channel_difference(dialog_id)) { LOG(INFO) << "Postpone channel update, because getChannelDifference is run"; add_postponed_channel_update(dialog_id, std::move(update), new_pts, pts_count, std::move(promise)); return; } - if (old_pts != new_pts - pts_count) { + if (old_pts == 0) { + old_pts = new_pts - pts_count; + LOG(INFO) << "Receive first update in " << dialog_id << " with PTS = " << new_pts << " from " << source; + } else if (old_pts != new_pts - pts_count) { LOG(INFO) << "Found a gap in the " << dialog_id << " with PTS = " << old_pts << ". new_pts = " << new_pts << ", pts_count = " << pts_count << " in update from " << source; - if (d->was_opened || td_->contacts_manager_->get_channel_status(channel_id).is_member() || - is_dialog_sponsored(d)) { + if (d->was_opened || td_->chat_manager_->get_channel_status(channel_id).is_member() || is_dialog_sponsored(d)) { add_postponed_channel_update(dialog_id, std::move(update), new_pts, pts_count, std::move(promise)); get_channel_difference(dialog_id, old_pts, new_pts, MessageId(), true, "add_pending_channel_update PTS mismatch"); @@ -7825,6 +7203,7 @@ void MessagesManager::add_pending_channel_update(DialogId dialog_id, tl_object_p } return; } + CHECK(old_pts + pts_count == new_pts); // the update can be applied } if (d == nullptr || pts_count > 0) { @@ -7879,13 +7258,10 @@ void MessagesManager::process_pts_update(tl_object_ptr &&u break; } case telegram_api::updateReadMessagesContents::ID: { - if (td_->auth_manager_->is_bot()) { - break; - } auto update = move_tl_object_as(update_ptr); LOG(INFO) << "Process updateReadMessageContents"; for (auto &message_id : update->messages_) { - read_message_content_from_updates(MessageId(ServerMessageId(message_id))); + read_message_content_from_updates(MessageId(ServerMessageId(message_id)), update->date_); } break; } @@ -7893,9 +7269,9 @@ void MessagesManager::process_pts_update(tl_object_ptr &&u auto update = move_tl_object_as(update_ptr); LOG(INFO) << "Process updateEditMessage"; bool had_message = - have_message_force(FullMessageId::get_full_message_id(update->message_, false), "updateEditMessage"); - auto full_message_id = on_get_message(std::move(update->message_), false, false, false, "updateEditMessage"); - on_message_edited(full_message_id, update->pts_, had_message); + have_message_force(MessageFullId::get_message_full_id(update->message_, false), "updateEditMessage"); + auto message_full_id = on_get_message(std::move(update->message_), false, false, false, "updateEditMessage"); + on_message_edited(message_full_id, update->pts_, had_message); break; } case telegram_api::updateDeleteMessages::ID: { @@ -7905,18 +7281,14 @@ void MessagesManager::process_pts_update(tl_object_ptr &&u for (auto message : update->messages_) { message_ids.push_back(MessageId(ServerMessageId(message))); } - delete_messages_from_updates(message_ids); + delete_messages_from_updates(message_ids, true); break; } case telegram_api::updateReadHistoryInbox::ID: { auto update = move_tl_object_as(update_ptr); LOG(INFO) << "Process updateReadHistoryInbox"; DialogId dialog_id(update->peer_); - FolderId folder_id; - if ((update->flags_ & telegram_api::updateReadHistoryInbox::FOLDER_ID_MASK) != 0) { - folder_id = FolderId(update->folder_id_); - } - on_update_dialog_folder_id(dialog_id, folder_id); + on_update_dialog_folder_id(dialog_id, FolderId(update->folder_id_)); read_history_inbox(dialog_id, MessageId(ServerMessageId(update->max_id_)), -1 /*update->still_unread_count*/, "updateReadHistoryInbox"); break; @@ -7988,13 +7360,13 @@ bool MessagesManager::process_channel_update(tl_object_ptr auto update = move_tl_object_as(update_ptr); LOG(INFO) << "Process updateEditChannelMessage"; bool had_message = - have_message_force(FullMessageId::get_full_message_id(update->message_, false), "updateEditChannelMessage"); - auto full_message_id = + have_message_force(MessageFullId::get_message_full_id(update->message_, false), "updateEditChannelMessage"); + auto message_full_id = on_get_message(std::move(update->message_), false, true, false, "updateEditChannelMessage"); - if (full_message_id == FullMessageId()) { + if (message_full_id == MessageFullId()) { return false; } - on_message_edited(full_message_id, update->pts_, had_message); + on_message_edited(message_full_id, update->pts_, had_message); break; } case telegram_api::updatePinnedChannelMessages::ID: { @@ -8020,14 +7392,14 @@ bool MessagesManager::process_channel_update(tl_object_ptr return true; } -void MessagesManager::on_message_edited(FullMessageId full_message_id, int32 pts, bool had_message) { - if (full_message_id == FullMessageId()) { +void MessagesManager::on_message_edited(MessageFullId message_full_id, int32 pts, bool had_message) { + if (message_full_id == MessageFullId()) { return; } - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog(dialog_id); - Message *m = get_message(d, full_message_id.get_message_id()); + Message *m = get_message(d, message_full_id.get_message_id()); CHECK(m != nullptr); m->last_edit_pts = pts; d->last_edited_message_id = m->message_id; @@ -8072,7 +7444,7 @@ bool MessagesManager::update_dialog_notification_settings(DialogId dialog_id, remove_all_dialog_notifications(d, false, "update_dialog_notification_settings 2"); } if (is_dialog_pinned_message_notifications_disabled(d) && d->notification_info != nullptr && - d->notification_info->mention_notification_group_.group_id.is_valid() && + d->notification_info->mention_notification_group_.is_valid() && d->notification_info->pinned_message_notification_message_id_.is_valid()) { remove_dialog_pinned_message_notification(d, "update_dialog_notification_settings 3"); } @@ -8094,10 +7466,9 @@ bool MessagesManager::update_dialog_notification_settings(DialogId dialog_id, return need_update.need_update_server; } -void MessagesManager::schedule_dialog_unmute(DialogId dialog_id, bool use_default, int32 mute_until) { - auto now = G()->unix_time_cached(); - if (!use_default && mute_until >= now && mute_until < now + 366 * 86400) { - dialog_unmute_timeout_.set_timeout_in(dialog_id.get(), mute_until - now + 1); +void MessagesManager::schedule_dialog_unmute(DialogId dialog_id, bool use_default, int32 mute_until, int32 unix_time) { + if (!use_default && mute_until >= unix_time && mute_until < unix_time + 366 * 86400) { + dialog_unmute_timeout_.set_timeout_in(dialog_id.get(), mute_until - unix_time + 1); } else { dialog_unmute_timeout_.cancel_timeout(dialog_id.get()); } @@ -8116,9 +7487,9 @@ void MessagesManager::update_dialog_unmute_timeout(Dialog *d, bool &old_use_defa CHECK(d != nullptr); CHECK(old_mute_until >= 0); - schedule_dialog_unmute(d->dialog_id, new_use_default, new_mute_until); + schedule_dialog_unmute(d->dialog_id, new_use_default, new_mute_until, G()->unix_time()); - auto scope = get_dialog_notification_setting_scope(d->dialog_id); + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(d->dialog_id); auto scope_mute_until = td_->notification_settings_manager_->get_scope_mute_until(scope); bool was_muted = (old_use_default ? scope_mute_until : old_mute_until) != 0; bool is_muted = (new_use_default ? scope_mute_until : new_mute_until) != 0; @@ -8164,7 +7535,7 @@ void MessagesManager::on_update_notification_scope_is_muted(NotificationSettings dialogs_.foreach([&](const DialogId &dialog_id, unique_ptr &dialog) { Dialog *d = dialog.get(); if (need_unread_counter(d->order) && d->notification_settings.use_default_mute_until && - get_dialog_notification_setting_scope(d->dialog_id) == scope) { + td_->dialog_manager_->get_dialog_notification_setting_scope(d->dialog_id) == scope) { int32 unread_count = d->server_unread_count + d->local_unread_count; if (unread_count != 0) { for (auto dialog_list_id : get_dialog_list_ids(d)) { @@ -8209,7 +7580,7 @@ void MessagesManager::on_update_notification_scope_is_muted(NotificationSettings dialogs_.foreach([&](const DialogId &dialog_id, unique_ptr &dialog) { Dialog *d = dialog.get(); if (need_unread_counter(d->order) && d->notification_settings.use_default_mute_until && - get_dialog_notification_setting_scope(d->dialog_id) == scope) { + td_->dialog_manager_->get_dialog_notification_setting_scope(d->dialog_id) == scope) { update_dialog_lists(d, get_dialog_positions(d), true, false, "on_update_notification_scope_is_muted"); } }); @@ -8219,7 +7590,7 @@ void MessagesManager::on_update_notification_scope_is_muted(NotificationSettings dialogs_.foreach([&](const DialogId &dialog_id, unique_ptr &dialog) { Dialog *d = dialog.get(); if (need_unread_counter(d->order) && d->notification_settings.use_default_mute_until && - get_dialog_notification_setting_scope(d->dialog_id) == scope) { + td_->dialog_manager_->get_dialog_notification_setting_scope(d->dialog_id) == scope) { remove_all_dialog_notifications(d, false, "on_update_notification_scope_is_muted"); } }); @@ -8242,11 +7613,11 @@ void MessagesManager::on_dialog_unmute(DialogId dialog_id) { return; } - auto now = G()->unix_time(); - if (d->notification_settings.mute_until > now) { - LOG(ERROR) << "Failed to unmute " << dialog_id << " in " << now << ", will be unmuted in " - << d->notification_settings.mute_until; - schedule_dialog_unmute(dialog_id, false, d->notification_settings.mute_until); + auto unix_time = G()->unix_time(); + if (d->notification_settings.mute_until > unix_time) { + LOG(INFO) << "Failed to unmute " << dialog_id << " in " << unix_time << ", will be unmuted in " + << d->notification_settings.mute_until; + schedule_dialog_unmute(dialog_id, false, d->notification_settings.mute_until, unix_time); return; } @@ -8284,21 +7655,18 @@ void MessagesManager::on_update_dialog_notify_settings( } void MessagesManager::on_update_dialog_available_reactions( - DialogId dialog_id, telegram_api::object_ptr &&available_reactions) { - if (td_->auth_manager_->is_bot()) { - return; - } - + DialogId dialog_id, telegram_api::object_ptr &&available_reactions, + int32 reactions_limit, bool paid_reactions_available) { Dialog *d = get_dialog_force(dialog_id, "on_update_dialog_available_reactions"); if (d == nullptr) { return; } - set_dialog_available_reactions(d, ChatReactions(std::move(available_reactions))); + set_dialog_available_reactions( + d, ChatReactions(std::move(available_reactions), reactions_limit, paid_reactions_available)); } void MessagesManager::set_dialog_available_reactions(Dialog *d, ChatReactions &&available_reactions) { - CHECK(!td_->auth_manager_->is_bot()); CHECK(d != nullptr); switch (d->dialog_id.get_type()) { case DialogType::Chat: @@ -8311,6 +7679,9 @@ void MessagesManager::set_dialog_available_reactions(Dialog *d, ChatReactions && UNREACHABLE(); break; } + if (td_->dialog_manager_->is_broadcast_channel(d->dialog_id)) { + available_reactions.fix_broadcast_reactions(active_reaction_types_); + } if (d->available_reactions == available_reactions) { if (!d->is_available_reactions_inited) { d->is_available_reactions_inited = true; @@ -8319,12 +7690,13 @@ void MessagesManager::set_dialog_available_reactions(Dialog *d, ChatReactions && return; } - VLOG(notifications) << "Update available reactions in " << d->dialog_id << " to " << available_reactions; + LOG(INFO) << "Update available reactions in " << d->dialog_id << " to " << available_reactions; auto old_active_reactions = get_active_reactions(d->available_reactions); auto new_active_reactions = get_active_reactions(available_reactions); bool need_update = old_active_reactions != new_active_reactions; - bool need_update_message_reactions_visibility = old_active_reactions.empty() != new_active_reactions.empty(); + bool need_update_message_reactions_visibility = + old_active_reactions.empty() != new_active_reactions.empty() && !td_->auth_manager_->is_bot(); d->available_reactions = std::move(available_reactions); d->is_available_reactions_inited = true; @@ -8371,8 +7743,10 @@ void MessagesManager::set_dialog_next_available_reactions_generation(Dialog *d, void MessagesManager::hide_dialog_message_reactions(Dialog *d) { CHECK(!td_->auth_manager_->is_bot()); - auto message_ids = find_dialog_messages( - d, [](const Message *m) { return m->reactions != nullptr && !m->reactions->reactions_.empty(); }); + auto dialog_type = d->dialog_id.get_type(); + CHECK(dialog_type == DialogType::Chat || dialog_type == DialogType::Channel); + auto message_ids = + find_dialog_messages(d, [](const Message *m) { return m->reactions != nullptr && !m->reactions->are_empty(); }); for (auto message_id : message_ids) { Message *m = get_message(d, message_id); CHECK(m != nullptr); @@ -8390,19 +7764,20 @@ void MessagesManager::hide_dialog_message_reactions(Dialog *d) { } } -void MessagesManager::set_active_reactions(vector active_reactions) { - if (active_reactions == active_reactions_) { +void MessagesManager::set_active_reactions(vector active_reaction_types) { + if (active_reaction_types == active_reaction_types_) { return; } - LOG(INFO) << "Set active reactions to " << active_reactions; - bool is_changed = active_reactions != active_reactions_; - active_reactions_ = std::move(active_reactions); + LOG(INFO) << "Set active reactions to " << active_reaction_types; + bool is_changed = active_reaction_types != active_reaction_types_; + active_reaction_types_ = std::move(active_reaction_types); auto old_active_reaction_pos_ = std::move(active_reaction_pos_); active_reaction_pos_.clear(); - for (size_t i = 0; i < active_reactions_.size(); i++) { - active_reaction_pos_[active_reactions_[i]] = i; + for (size_t i = 0; i < active_reaction_types_.size(); i++) { + CHECK(!active_reaction_types_[i].is_empty()); + active_reaction_pos_[active_reaction_types_[i]] = i; } if (td_->auth_manager_->is_bot()) { @@ -8443,6 +7818,9 @@ void MessagesManager::set_active_reactions(vector active_reactions) { } ChatReactions MessagesManager::get_active_reactions(const ChatReactions &available_reactions) const { + if (td_->auth_manager_->is_bot()) { + return available_reactions; + } return available_reactions.get_active_reactions(active_reaction_pos_); } @@ -8462,17 +7840,20 @@ ChatReactions MessagesManager::get_dialog_active_reactions(const Dialog *d) cons } } +// affects all users ChatReactions MessagesManager::get_message_active_reactions(const Dialog *d, const Message *m) const { CHECK(d != nullptr); CHECK(m != nullptr); - if (is_service_message_content(m->content->get_type()) || m->ttl > 0) { + if (is_service_message_content(m->content->get_type()) || !m->ttl.is_empty() || !m->message_id.is_valid() || + !m->message_id.is_server()) { return ChatReactions(); } - if (is_discussion_message(d->dialog_id, m)) { - d = get_dialog(m->forward_info->from_dialog_id); + auto dialog_id = d->dialog_id; + if (is_discussion_message(dialog_id, m)) { + auto linked_dialog_id = m->forward_info->get_last_dialog_id(); + d = get_dialog(linked_dialog_id); if (d == nullptr) { - LOG(ERROR) << "Failed to find linked " << m->forward_info->from_dialog_id - << " to determine correct active reactions"; + LOG(ERROR) << "Failed to find linked " << linked_dialog_id << " to determine correct active reactions"; return ChatReactions(); } } @@ -8514,10 +7895,10 @@ bool MessagesManager::need_poll_message_reactions(const Dialog *d, const Message return true; } -void MessagesManager::queue_message_reactions_reload(FullMessageId full_message_id) { - auto dialog_id = full_message_id.get_dialog_id(); +void MessagesManager::queue_message_reactions_reload(MessageFullId message_full_id) { + auto dialog_id = message_full_id.get_dialog_id(); CHECK(dialog_id.is_valid()); - auto message_id = full_message_id.get_message_id(); + auto message_id = message_full_id.get_message_id(); CHECK(message_id.is_valid()); being_reloaded_reactions_[dialog_id].message_ids.insert(message_id); try_reload_message_reactions(dialog_id, false); @@ -8563,7 +7944,10 @@ void MessagesManager::try_reload_message_reactions(DialogId dialog_id, bool is_f vector message_ids; for (auto message_id_it = it->second.message_ids.begin(); message_id_it != it->second.message_ids.end() && message_ids.size() < MAX_MESSAGE_IDS; ++message_id_it) { - message_ids.push_back(*message_id_it); + auto message_id = *message_id_it; + if (pending_read_reactions_.count({dialog_id, message_id}) == 0) { + message_ids.push_back(message_id); + } } for (auto message_id : message_ids) { it->second.message_ids.erase(message_id); @@ -8613,11 +7997,11 @@ void MessagesManager::reget_dialog_action_bar(DialogId dialog_id, const char *so LOG(INFO) << "Reget action bar in " << dialog_id << " from " << source; switch (dialog_id.get_type()) { case DialogType::User: - td_->contacts_manager_->reload_user_full(dialog_id.get_user_id(), Auto()); + td_->user_manager_->reload_user_full(dialog_id.get_user_id(), Auto(), source); return; case DialogType::Chat: case DialogType::Channel: - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { return; } @@ -8633,7 +8017,7 @@ void MessagesManager::repair_dialog_action_bar(Dialog *d, const char *source) { CHECK(d != nullptr); auto dialog_id = d->dialog_id; d->need_repair_action_bar = true; - if (have_input_peer(dialog_id, AccessRights::Read)) { + if (td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { create_actor( "RepairChatActionBarActor", 1.0, PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, source](Result result) { @@ -8671,24 +8055,12 @@ void MessagesManager::hide_dialog_action_bar(Dialog *d) { } void MessagesManager::remove_dialog_action_bar(DialogId dialog_id, Promise &&promise) { - Dialog *d = get_dialog_force(dialog_id, "remove_dialog_action_bar"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Read, "remove_dialog_action_bar")); if (dialog_id.get_type() == DialogType::SecretChat) { - dialog_id = DialogId(td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id())); - d = get_dialog_force(dialog_id, "remove_dialog_action_bar 2"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat with the user not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + dialog_id = DialogId(td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id())); + TRY_RESULT_PROMISE_ASSIGN(promise, d, + check_dialog_access(dialog_id, false, AccessRights::Read, "remove_dialog_action_bar 2")); } if (!d->know_action_bar) { @@ -8708,8 +8080,18 @@ void MessagesManager::remove_dialog_action_bar(DialogId dialog_id, Promise toggle_dialog_report_spam_state_on_server(dialog_id, false, 0, std::move(promise)); } +void MessagesManager::hide_all_business_bot_manager_bars() { + dialogs_.foreach([&](const DialogId &dialog_id, unique_ptr &dialog) { + Dialog *d = dialog.get(); + if (d->business_bot_manage_bar != nullptr) { + d->business_bot_manage_bar = nullptr; + send_update_chat_business_bot_manage_bar(d); + } + }); +} + void MessagesManager::repair_dialog_active_group_call_id(DialogId dialog_id) { - if (have_input_peer(dialog_id, AccessRights::Read)) { + if (td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { LOG(INFO) << "Repair active voice chat ID in " << dialog_id; create_actor("RepairChatActiveVoiceChatId", 1.0, PromiseCreator::lambda([actor_id = actor_id(this), dialog_id](Result result) { @@ -8734,11 +8116,11 @@ void MessagesManager::do_repair_dialog_active_group_call_id(DialogId dialog_id) if (!need_repair_active_group_call_id && !need_repair_expected_group_call_id) { return; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { return; } - reload_dialog_info_full(dialog_id, "do_repair_dialog_active_group_call_id"); + td_->dialog_manager_->reload_dialog_info_full(dialog_id, "do_repair_dialog_active_group_call_id"); } class MessagesManager::ToggleDialogReportSpamStateOnServerLogEvent { @@ -8784,7 +8166,7 @@ void MessagesManager::toggle_dialog_report_spam_state_on_server(DialogId dialog_ if (is_spam_dialog) { return td_->create_handler(std::move(promise))->send(dialog_id); } else { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); if (!user_id.is_valid()) { return promise.set_error(Status::Error(400, "Peer user not found")); } @@ -8797,109 +8179,6 @@ void MessagesManager::toggle_dialog_report_spam_state_on_server(DialogId dialog_ } } -bool MessagesManager::can_report_dialog(DialogId dialog_id) const { - // doesn't include possibility of report from action bar - switch (dialog_id.get_type()) { - case DialogType::User: - return td_->contacts_manager_->can_report_user(dialog_id.get_user_id()); - case DialogType::Chat: - return false; - case DialogType::Channel: - return !td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).is_creator(); - case DialogType::SecretChat: - return false; - case DialogType::None: - default: - UNREACHABLE(); - return false; - } -} - -void MessagesManager::report_dialog(DialogId dialog_id, const vector &message_ids, ReportReason &&reason, - Promise &&promise) { - Dialog *d = get_dialog_force(dialog_id, "report_dialog"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - - Dialog *user_d = d; - bool is_dialog_spam_report = false; - bool can_report_spam = false; - if (reason.is_spam() && message_ids.empty()) { - // report from action bar - if (dialog_id.get_type() == DialogType::SecretChat) { - auto user_dialog_id = DialogId(td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id())); - user_d = get_dialog_force(user_dialog_id, "report_dialog 2"); - if (user_d == nullptr) { - return promise.set_error(Status::Error(400, "Chat with the user not found")); - } - } - is_dialog_spam_report = user_d->know_action_bar; - can_report_spam = user_d->action_bar != nullptr && user_d->action_bar->can_report_spam(); - } - - if (is_dialog_spam_report && can_report_spam) { - hide_dialog_action_bar(user_d); - return toggle_dialog_report_spam_state_on_server(dialog_id, true, 0, std::move(promise)); - } - - if (!can_report_dialog(dialog_id)) { - if (is_dialog_spam_report) { - return promise.set_value(Unit()); - } - - return promise.set_error(Status::Error(400, "Chat can't be reported")); - } - - vector server_message_ids; - for (auto message_id : message_ids) { - if (message_id.is_scheduled()) { - return promise.set_error(Status::Error(400, "Can't report scheduled messages")); - } - if (message_id.is_valid() && message_id.is_server()) { - server_message_ids.push_back(message_id); - } - } - - if (dialog_id.get_type() == DialogType::Channel && reason.is_unrelated_location()) { - hide_dialog_action_bar(d); - } - - td_->create_handler(std::move(promise))->send(dialog_id, server_message_ids, std::move(reason)); -} - -void MessagesManager::report_dialog_photo(DialogId dialog_id, FileId file_id, ReportReason &&reason, - Promise &&promise) { - Dialog *d = get_dialog_force(dialog_id, "report_dialog_photo"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - - if (!can_report_dialog(dialog_id)) { - return promise.set_error(Status::Error(400, "Chat photo can't be reported")); - } - - auto file_view = td_->file_manager_->get_file_view(file_id); - if (file_view.empty()) { - return promise.set_error(Status::Error(400, "Unknown file ID")); - } - if (get_main_file_type(file_view.get_type()) != FileType::Photo || !file_view.has_remote_location() || - !file_view.remote_location().is_photo()) { - return promise.set_error(Status::Error(400, "Only full chat photos can be reported")); - } - - td_->create_handler(std::move(promise)) - ->send(dialog_id, file_id, file_view.remote_location().as_input_photo(), std::move(reason)); -} - void MessagesManager::on_get_peer_settings(DialogId dialog_id, tl_object_ptr &&peer_settings, bool ignore_privacy_exception) { @@ -8909,8 +8188,8 @@ void MessagesManager::on_get_peer_settings(DialogId dialog_id, } if (dialog_id.get_type() == DialogType::User && !ignore_privacy_exception) { - td_->contacts_manager_->on_update_user_need_phone_number_privacy_exception(dialog_id.get_user_id(), - peer_settings->need_contacts_exception_); + td_->user_manager_->on_update_user_need_phone_number_privacy_exception(dialog_id.get_user_id(), + peer_settings->need_contacts_exception_); } Dialog *d = get_dialog_force(dialog_id, "on_get_peer_settings"); @@ -8918,6 +8197,15 @@ void MessagesManager::on_get_peer_settings(DialogId dialog_id, return; } + auto business_bot_manage_bar = BusinessBotManageBar::create( + peer_settings->business_bot_paused_, peer_settings->business_bot_can_reply_, + UserId(peer_settings->business_bot_id_), std::move(peer_settings->business_bot_manage_url_)); + fix_dialog_business_bot_manage_bar(dialog_id, business_bot_manage_bar.get()); + if (d->business_bot_manage_bar != business_bot_manage_bar) { + d->business_bot_manage_bar = std::move(business_bot_manage_bar); + send_update_chat_business_bot_manage_bar(d); + } + auto distance = (peer_settings->flags_ & telegram_api::peerSettings::GEO_DISTANCE_MASK) != 0 ? peer_settings->geo_distance_ : -1; if (distance < -1 || d->has_outgoing_messages) { @@ -8956,16 +8244,20 @@ void MessagesManager::fix_dialog_action_bar(const Dialog *d, DialogActionBar *ac action_bar->fix(td_, d->dialog_id, d->is_blocked, d->folder_id); } -Result MessagesManager::get_login_button_url(FullMessageId full_message_id, int64 button_id) { - Dialog *d = get_dialog_force(full_message_id.get_dialog_id(), "get_login_button_url"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); - } - if (!have_input_peer(d->dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); +void MessagesManager::fix_dialog_business_bot_manage_bar(DialogId dialog_id, + BusinessBotManageBar *business_bot_manage_bar) { + if (business_bot_manage_bar == nullptr) { + return; } - auto m = get_message_force(d, full_message_id.get_message_id(), "get_login_button_url"); + business_bot_manage_bar->fix(dialog_id); +} + +Result MessagesManager::get_login_button_url(MessageFullId message_full_id, int64 button_id) { + TRY_RESULT(d, + check_dialog_access(message_full_id.get_dialog_id(), false, AccessRights::Read, "get_login_button_url")); + + auto m = get_message_force(d, message_full_id.get_message_id(), "get_login_button_url"); if (m == nullptr) { return Status::Error(400, "Message not found"); } @@ -8979,10 +8271,6 @@ Result MessagesManager::get_login_button_url(FullMessageId full_message_ // it shouldn't have UrlAuth buttons anyway return Status::Error(400, "Message is not server"); } - if (d->dialog_id.get_type() == DialogType::SecretChat) { - // secret chat messages can't have reply markup, so this shouldn't happen now - return Status::Error(400, "Message is in a secret chat"); - } if (button_id < std::numeric_limits::min() || button_id > std::numeric_limits::max()) { return Status::Error(400, "Invalid button identifier specified"); } @@ -9048,12 +8336,13 @@ void MessagesManager::on_upload_media(FileId file_id, tl_object_ptrsecond.first; - auto thumbnail_file_id = it->second.second; + auto message_full_id = it->second.message_full_id; + auto thumbnail_file_id = it->second.thumbnail_file_id; + auto media_pos = it->second.media_pos; being_uploaded_files_.erase(it); - Message *m = get_message(full_message_id); + const Message *m = get_message(message_full_id); if (m == nullptr) { // message has already been deleted by the user or sent to inaccessible channel, do not need to send or edit it // file upload should be already canceled in cancel_send_message_query, it shouldn't happen @@ -9062,13 +8351,13 @@ void MessagesManager::on_upload_media(FileId file_id, tl_object_ptrmessage_id.is_any_server(); - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); auto can_send_status = can_send_message(dialog_id); if (!is_edit && can_send_status.is_error()) { // user has left the chat during upload of the file or lost their privileges LOG(INFO) << "Can't send a message to " << dialog_id << ": " << can_send_status; - fail_send_message(full_message_id, std::move(can_send_status)); + fail_send_message(message_full_id, std::move(can_send_status)); return; } @@ -9079,21 +8368,22 @@ void MessagesManager::on_upload_media(FileId file_id, tl_object_ptrfile_manager_->upload(thumbnail_file_id, upload_thumbnail_callback_, 32, m->message_id.get()); } else { - do_send_media(dialog_id, m, file_id, thumbnail_file_id, std::move(input_file), nullptr); + do_send_media(dialog_id, m, media_pos, file_id, thumbnail_file_id, std::move(input_file), nullptr); } break; case DialogType::SecretChat: + CHECK(media_pos == -1); if (thumbnail_file_id.is_valid()) { LOG(INFO) << "Ask to load thumbnail " << thumbnail_file_id; bool is_inserted = being_loaded_secret_thumbnails_ - .emplace(thumbnail_file_id, UploadedSecretThumbnailInfo{full_message_id, file_id, + .emplace(thumbnail_file_id, UploadedSecretThumbnailInfo{message_full_id, file_id, std::move(input_encrypted_file)}) .second; CHECK(is_inserted); @@ -9110,8 +8400,8 @@ void MessagesManager::on_upload_media(FileId file_id, tl_object_ptr input_file, +void MessagesManager::do_send_media(DialogId dialog_id, const Message *m, int32 media_pos, FileId file_id, + FileId thumbnail_file_id, tl_object_ptr input_file, tl_object_ptr input_thumbnail) { CHECK(m != nullptr); @@ -9119,10 +8409,11 @@ void MessagesManager::do_send_media(DialogId dialog_id, Message *m, FileId file_ bool have_input_thumbnail = input_thumbnail != nullptr; LOG(INFO) << "Do send media file " << file_id << " with thumbnail " << thumbnail_file_id << ", have_input_file = " << have_input_file << ", have_input_thumbnail = " << have_input_thumbnail - << ", self-destruct time = " << m->ttl; + << ", self-destruct time = " << m->ttl << ", media_pos = " << media_pos; - MessageContent *content = nullptr; + const MessageContent *content = nullptr; if (m->message_id.is_any_server()) { + CHECK(media_pos == -1); content = m->edited_content.get(); if (content == nullptr) { LOG(ERROR) << "Message has no edited content"; @@ -9132,16 +8423,18 @@ void MessagesManager::do_send_media(DialogId dialog_id, Message *m, FileId file_ content = m->content.get(); } - auto input_media = get_input_media(content, td_, std::move(input_file), std::move(input_thumbnail), file_id, - thumbnail_file_id, m->ttl, m->send_emoji, true); - LOG_CHECK(input_media != nullptr) << to_string(get_message_object(dialog_id, m, "do_send_media")) << ' ' - << have_input_file << ' ' << have_input_thumbnail << ' ' << file_id << ' ' + auto input_media = + get_message_content_input_media(content, media_pos, td_, std::move(input_file), std::move(input_thumbnail), + file_id, thumbnail_file_id, m->ttl, m->send_emoji, true); + LOG_CHECK(input_media != nullptr) << to_string(get_message_object(dialog_id, m, "do_send_media")) << ' ' << media_pos + << ' ' << have_input_file << ' ' << have_input_thumbnail << ' ' << file_id << ' ' << thumbnail_file_id << ' ' << m->ttl; - on_message_media_uploaded(dialog_id, m, std::move(input_media), file_id, thumbnail_file_id); + on_message_media_uploaded(dialog_id, m, media_pos, std::move(input_media), {file_id}, {thumbnail_file_id}); } -void MessagesManager::do_send_secret_media(DialogId dialog_id, Message *m, FileId file_id, FileId thumbnail_file_id, +void MessagesManager::do_send_secret_media(DialogId dialog_id, const Message *m, FileId file_id, + FileId thumbnail_file_id, tl_object_ptr input_encrypted_file, BufferSlice thumbnail) { CHECK(dialog_id.get_type() == DialogType::SecretChat); @@ -9153,10 +8446,11 @@ void MessagesManager::do_send_secret_media(DialogId dialog_id, Message *m, FileI LOG(INFO) << "Do send secret media file " << file_id << " with thumbnail " << thumbnail_file_id << ", have_input_file = " << have_input_file; - auto layer = td_->contacts_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); + auto layer = td_->user_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); on_secret_message_media_uploaded( dialog_id, m, - get_secret_input_media(m->content.get(), td_, std::move(input_encrypted_file), std::move(thumbnail), layer), + get_message_content_secret_input_media(m->content.get(), td_, std::move(input_encrypted_file), + std::move(thumbnail), layer), file_id, thumbnail_file_id); } @@ -9175,15 +8469,15 @@ void MessagesManager::on_upload_media_error(FileId file_id, Status status) { return; } - auto full_message_id = it->second.first; + auto message_full_id = it->second.message_full_id; being_uploaded_files_.erase(it); - bool is_edit = full_message_id.get_message_id().is_any_server(); + bool is_edit = message_full_id.get_message_id().is_any_server(); if (is_edit) { - fail_edit_message_media(full_message_id, std::move(status)); + fail_edit_message_media(message_full_id, std::move(status)); } else { - fail_send_message(full_message_id, std::move(status)); + fail_send_message(message_full_id, std::move(status)); } } @@ -9201,13 +8495,13 @@ void MessagesManager::on_load_secret_thumbnail(FileId thumbnail_file_id, BufferS return; } - auto full_message_id = it->second.full_message_id; + auto message_full_id = it->second.message_full_id; auto file_id = it->second.file_id; auto input_file = std::move(it->second.input_file); being_loaded_secret_thumbnails_.erase(it); - Message *m = get_message(full_message_id); + Message *m = get_message(message_full_id); if (m == nullptr) { // message has already been deleted by the user, do not need to send it // cancel file upload of the main file to allow next upload with the same file to succeed @@ -9221,13 +8515,13 @@ void MessagesManager::on_load_secret_thumbnail(FileId thumbnail_file_id, BufferS delete_message_content_thumbnail(m->content.get(), td_); } - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); auto can_send_status = can_send_message(dialog_id); if (can_send_status.is_error()) { // secret chat was closed during load of the file LOG(INFO) << "Can't send a message to " << dialog_id << ": " << can_send_status; - fail_send_message(full_message_id, std::move(can_send_status)); + fail_send_message(message_full_id, std::move(can_send_status)); return; } @@ -9249,13 +8543,14 @@ void MessagesManager::on_upload_thumbnail(FileId thumbnail_file_id, return; } - auto full_message_id = it->second.full_message_id; + auto message_full_id = it->second.message_full_id; auto file_id = it->second.file_id; auto input_file = std::move(it->second.input_file); + auto media_pos = it->second.media_pos; being_uploaded_thumbnails_.erase(it); - Message *m = get_message(full_message_id); + Message *m = get_message(message_full_id); if (m == nullptr) { // message has already been deleted by the user or sent to inaccessible channel, do not need to send or edit it // thumbnail file upload should be already canceled in cancel_send_message_query @@ -9266,237 +8561,21 @@ void MessagesManager::on_upload_thumbnail(FileId thumbnail_file_id, bool is_edit = m->message_id.is_any_server(); if (thumbnail_input_file == nullptr) { - delete_message_content_thumbnail(is_edit ? m->edited_content.get() : m->content.get(), td_); + delete_message_content_thumbnail(is_edit ? m->edited_content.get() : m->content.get(), td_, media_pos); } - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); auto can_send_status = can_send_message(dialog_id); if (!is_edit && can_send_status.is_error()) { // user has left the chat during upload of the thumbnail or lost their privileges LOG(INFO) << "Can't send a message to " << dialog_id << ": " << can_send_status; - fail_send_message(full_message_id, std::move(can_send_status)); - return; - } - - do_send_media(dialog_id, m, file_id, thumbnail_file_id, std::move(input_file), std::move(thumbnail_input_file)); -} - -void MessagesManager::on_upload_dialog_photo(FileId file_id, tl_object_ptr input_file) { - LOG(INFO) << "File " << file_id << " has been uploaded"; - - auto it = being_uploaded_dialog_photos_.find(file_id); - if (it == being_uploaded_dialog_photos_.end()) { - // just in case, as in on_upload_media - return; - } - - DialogId dialog_id = it->second.dialog_id; - double main_frame_timestamp = it->second.main_frame_timestamp; - bool is_animation = it->second.is_animation; - bool is_reupload = it->second.is_reupload; - Promise promise = std::move(it->second.promise); - - being_uploaded_dialog_photos_.erase(it); - - FileView file_view = td_->file_manager_->get_file_view(file_id); - CHECK(!file_view.is_encrypted()); - if (input_file == nullptr && file_view.has_remote_location()) { - if (file_view.main_remote_location().is_web()) { - return promise.set_error(Status::Error(400, "Can't use web photo as profile photo")); - } - if (is_reupload) { - return promise.set_error(Status::Error(400, "Failed to reupload the file")); - } - - if (is_animation) { - CHECK(file_view.get_type() == FileType::Animation); - // delete file reference and forcely reupload the file - auto file_reference = FileManager::extract_file_reference(file_view.main_remote_location().as_input_document()); - td_->file_manager_->delete_file_reference(file_id, file_reference); - upload_dialog_photo(dialog_id, file_id, is_animation, main_frame_timestamp, true, std::move(promise), {-1}); - } else { - CHECK(file_view.get_type() == FileType::Photo); - auto input_photo = file_view.main_remote_location().as_input_photo(); - auto input_chat_photo = make_tl_object(std::move(input_photo)); - send_edit_dialog_photo_query(dialog_id, file_id, std::move(input_chat_photo), std::move(promise)); - } - return; - } - CHECK(input_file != nullptr); - - int32 flags = 0; - tl_object_ptr photo_input_file; - tl_object_ptr video_input_file; - if (is_animation) { - flags |= telegram_api::inputChatUploadedPhoto::VIDEO_MASK; - video_input_file = std::move(input_file); - - if (main_frame_timestamp != 0.0) { - flags |= telegram_api::inputChatUploadedPhoto::VIDEO_START_TS_MASK; - } - } else { - flags |= telegram_api::inputChatUploadedPhoto::FILE_MASK; - photo_input_file = std::move(input_file); - } - - auto input_chat_photo = make_tl_object( - flags, std::move(photo_input_file), std::move(video_input_file), main_frame_timestamp, nullptr); - send_edit_dialog_photo_query(dialog_id, file_id, std::move(input_chat_photo), std::move(promise)); -} - -void MessagesManager::on_upload_dialog_photo_error(FileId file_id, Status status) { - if (G()->close_flag()) { - // do not fail upload if closing - return; - } - - LOG(INFO) << "File " << file_id << " has upload error " << status; - CHECK(status.is_error()); - - auto it = being_uploaded_dialog_photos_.find(file_id); - if (it == being_uploaded_dialog_photos_.end()) { - // just in case, as in on_upload_media_error - return; - } - - Promise promise = std::move(it->second.promise); - - being_uploaded_dialog_photos_.erase(it); - - promise.set_error(std::move(status)); -} - -void MessagesManager::on_upload_imported_messages(FileId file_id, tl_object_ptr input_file) { - LOG(INFO) << "File " << file_id << " has been uploaded"; - - auto it = being_uploaded_imported_messages_.find(file_id); - if (it == being_uploaded_imported_messages_.end()) { - // just in case, as in on_upload_media - return; - } - - CHECK(it->second != nullptr); - DialogId dialog_id = it->second->dialog_id; - vector attached_file_ids = std::move(it->second->attached_file_ids); - bool is_reupload = it->second->is_reupload; - Promise promise = std::move(it->second->promise); - - being_uploaded_imported_messages_.erase(it); - - TRY_STATUS_PROMISE(promise, can_send_message(dialog_id)); - - FileView file_view = td_->file_manager_->get_file_view(file_id); - CHECK(!file_view.is_encrypted()); - if (input_file == nullptr && file_view.has_remote_location()) { - if (file_view.main_remote_location().is_web()) { - return promise.set_error(Status::Error(400, "Can't use web file")); - } - if (is_reupload) { - return promise.set_error(Status::Error(400, "Failed to reupload the file")); - } - - CHECK(file_view.get_type() == FileType::Document); - // delete file reference and forcely reupload the file - auto file_reference = FileManager::extract_file_reference(file_view.main_remote_location().as_input_document()); - td_->file_manager_->delete_file_reference(file_id, file_reference); - upload_imported_messages(dialog_id, file_id, std::move(attached_file_ids), true, std::move(promise), {-1}); - return; - } - CHECK(input_file != nullptr); - - td_->create_handler(std::move(promise)) - ->send(dialog_id, file_id, std::move(input_file), std::move(attached_file_ids)); -} - -void MessagesManager::on_upload_imported_messages_error(FileId file_id, Status status) { - if (G()->close_flag()) { - // do not fail upload if closing - return; - } - - LOG(INFO) << "File " << file_id << " has upload error " << status; - CHECK(status.is_error()); - - auto it = being_uploaded_imported_messages_.find(file_id); - if (it == being_uploaded_imported_messages_.end()) { - // just in case, as in on_upload_media_error - return; - } - - Promise promise = std::move(it->second->promise); - - being_uploaded_imported_messages_.erase(it); - - promise.set_error(std::move(status)); -} - -void MessagesManager::on_upload_imported_message_attachment(FileId file_id, - tl_object_ptr input_file) { - LOG(INFO) << "File " << file_id << " has been uploaded"; - - auto it = being_uploaded_imported_message_attachments_.find(file_id); - if (it == being_uploaded_imported_message_attachments_.end()) { - // just in case, as in on_upload_media - return; - } - - CHECK(it->second != nullptr); - DialogId dialog_id = it->second->dialog_id; - int64 import_id = it->second->import_id; - bool is_reupload = it->second->is_reupload; - Promise promise = std::move(it->second->promise); - - being_uploaded_imported_message_attachments_.erase(it); - - FileView file_view = td_->file_manager_->get_file_view(file_id); - CHECK(!file_view.is_encrypted()); - if (input_file == nullptr && file_view.has_remote_location()) { - if (file_view.main_remote_location().is_web()) { - return promise.set_error(Status::Error(400, "Can't use web file")); - } - if (is_reupload) { - return promise.set_error(Status::Error(400, "Failed to reupload the file")); - } - - // delete file reference and forcely reupload the file - auto file_reference = - file_view.get_type() == FileType::Photo - ? FileManager::extract_file_reference(file_view.main_remote_location().as_input_photo()) - : FileManager::extract_file_reference(file_view.main_remote_location().as_input_document()); - td_->file_manager_->delete_file_reference(file_id, file_reference); - upload_imported_message_attachment(dialog_id, import_id, file_id, true, std::move(promise), {-1}); + fail_send_message(message_full_id, std::move(can_send_status)); return; } - CHECK(input_file != nullptr); - auto suggested_path = file_view.suggested_path(); - const PathView path_view(suggested_path); - td_->create_handler(std::move(promise)) - ->send(dialog_id, import_id, path_view.file_name().str(), file_id, - get_fake_input_media(td_, std::move(input_file), file_id)); -} - -void MessagesManager::on_upload_imported_message_attachment_error(FileId file_id, Status status) { - if (G()->close_flag()) { - // do not fail upload if closing - return; - } - - LOG(INFO) << "File " << file_id << " has upload error " << status; - CHECK(status.is_error()); - - auto it = being_uploaded_imported_message_attachments_.find(file_id); - if (it == being_uploaded_imported_message_attachments_.end()) { - // just in case, as in on_upload_media_error - return; - } - - Promise promise = std::move(it->second->promise); - - being_uploaded_imported_message_attachments_.erase(it); - - promise.set_error(std::move(status)); + do_send_media(dialog_id, m, media_pos, file_id, thumbnail_file_id, std::move(input_file), + std::move(thumbnail_input_file)); } void MessagesManager::before_get_difference() { @@ -9538,14 +8617,14 @@ void MessagesManager::after_get_difference() { send_update_unread_chat_count(*list, DialogId(), true, "after_get_difference"); } - vector update_message_ids_to_delete; + vector update_message_ids_to_delete; for (auto &it : update_message_ids_) { // there can be unhandled updateMessageId updates after getDifference even for ordinary chats, // because despite updates coming during getDifference have already been applied, // some of them could be postponed because of PTS gap - auto full_message_id = it.first; - auto dialog_id = full_message_id.get_dialog_id(); - auto message_id = full_message_id.get_message_id(); + auto message_full_id = it.first; + auto dialog_id = message_full_id.get_dialog_id(); + auto message_id = message_full_id.get_message_id(); auto old_message_id = it.second; CHECK(message_id.is_valid()); CHECK(message_id.is_server()); @@ -9566,10 +8645,10 @@ void MessagesManager::after_get_difference() { // add the message or delete it from the server. In this case we forget updateMessageId for such messages in // order to not check them over and over. const Dialog *d = get_dialog(dialog_id); - if (!have_input_peer(dialog_id, AccessRights::Read) || + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read) || (d != nullptr && message_id <= td::max(d->last_clear_history_message_id, d->max_unavailable_message_id))) { - update_message_ids_to_delete.push_back(full_message_id); + update_message_ids_to_delete.push_back(message_full_id); } break; } @@ -9577,19 +8656,19 @@ void MessagesManager::after_get_difference() { const Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); if (dialog_id.get_type() == DialogType::Channel || message_id <= d->last_new_message_id) { - LOG(ERROR) << "Receive updateMessageId from " << old_message_id << " to " << full_message_id + LOG(ERROR) << "Receive updateMessageId from " << old_message_id << " to " << message_full_id << " but not receive corresponding message, last_new_message_id = " << d->last_new_message_id; } if (message_id <= d->last_new_message_id) { get_message_from_server( - full_message_id, - PromiseCreator::lambda([actor_id = actor_id(this), full_message_id, old_message_id](Result result) { + message_full_id, + PromiseCreator::lambda([actor_id = actor_id(this), message_full_id, old_message_id](Result result) { send_closure(actor_id, &MessagesManager::on_restore_missing_message_after_get_difference, - full_message_id, old_message_id, std::move(result)); + message_full_id, old_message_id, std::move(result)); }), "get missing"); } else if (dialog_id.get_type() == DialogType::Channel) { - schedule_get_channel_difference(dialog_id, 0, message_id, 0.001); + schedule_get_channel_difference(dialog_id, 0, message_id, 0.001, "after_get_difference"); } break; } @@ -9601,8 +8680,8 @@ void MessagesManager::after_get_difference() { break; } } - for (const auto &full_message_id : update_message_ids_to_delete) { - update_message_ids_.erase(full_message_id); + for (const auto &message_full_id : update_message_ids_to_delete) { + update_message_ids_.erase(message_full_id); } if (!td_->auth_manager_->is_bot()) { @@ -9622,21 +8701,21 @@ void MessagesManager::after_get_difference() { } } -void MessagesManager::on_restore_missing_message_after_get_difference(FullMessageId full_message_id, +void MessagesManager::on_restore_missing_message_after_get_difference(MessageFullId message_full_id, MessageId old_message_id, Result result) { if (result.is_error()) { - LOG(WARNING) << "Failed to get missing " << full_message_id << " for " << old_message_id << ": " << result.error(); + LOG(WARNING) << "Failed to get missing " << message_full_id << " for " << old_message_id << ": " << result.error(); } else { - LOG(WARNING) << "Successfully get missing " << full_message_id << " for " << old_message_id; + LOG(WARNING) << "Successfully get missing " << message_full_id << " for " << old_message_id; - bool have_message = have_message_force(full_message_id, "on_restore_missing_message_after_get_difference"); - if (!have_message && update_message_ids_.count(full_message_id)) { - LOG(ERROR) << "Receive messageEmpty instead of missing " << full_message_id << " for " << old_message_id; + bool have_message = have_message_force(message_full_id, "on_restore_missing_message_after_get_difference"); + if (!have_message && update_message_ids_.count(message_full_id)) { + LOG(ERROR) << "Receive messageEmpty instead of missing " << message_full_id << " for " << old_message_id; - delete_dialog_messages(full_message_id.get_dialog_id(), {old_message_id}, false, + delete_dialog_messages(message_full_id.get_dialog_id(), {old_message_id}, false, "on_restore_missing_message_after_get_difference"); - update_message_ids_.erase(full_message_id); + update_message_ids_.erase(message_full_id); } } } @@ -9647,10 +8726,21 @@ void MessagesManager::on_get_empty_messages(DialogId dialog_id, const vectorpts, 0, message_id, true, source); +} + void MessagesManager::get_channel_difference_if_needed(DialogId dialog_id, MessagesInfo &&messages_info, - Promise &&promise) { + Promise &&promise, const char *source) { + if (td_->auth_manager_->is_bot()) { + return promise.set_value(std::move(messages_info)); + } if (!dialog_id.is_valid()) { - return get_channel_differences_if_needed(std::move(messages_info), std::move(promise)); + return get_channel_differences_if_needed(std::move(messages_info), std::move(promise), source); } for (auto &message : messages_info.messages) { if (need_channel_difference_to_add_message(dialog_id, message)) { @@ -9658,13 +8748,18 @@ void MessagesManager::get_channel_difference_if_needed(DialogId dialog_id, Messa return run_after_channel_difference( dialog_id, max_message_id, PromiseCreator::lambda([messages_info = std::move(messages_info), promise = std::move(promise)]( - Unit ignored) mutable { promise.set_value(std::move(messages_info)); })); + Unit ignored) mutable { promise.set_value(std::move(messages_info)); }), + source); } } promise.set_value(std::move(messages_info)); } -void MessagesManager::get_channel_differences_if_needed(MessagesInfo &&messages_info, Promise &&promise) { +void MessagesManager::get_channel_differences_if_needed(MessagesInfo &&messages_info, Promise &&promise, + const char *source) { + if (td_->auth_manager_->is_bot()) { + return promise.set_value(std::move(messages_info)); + } MultiPromiseActorSafe mpas{"GetChannelDifferencesIfNeededMultiPromiseActor"}; mpas.add_promise(Promise()); mpas.set_ignore_errors(true); @@ -9676,8 +8771,7 @@ void MessagesManager::get_channel_differences_if_needed(MessagesInfo &&messages_ auto dialog_id = DialogId::get_message_dialog_id(message); if (need_channel_difference_to_add_message(dialog_id, message)) { - run_after_channel_difference(dialog_id, MessageId::get_max_message_id(messages_info.messages), - mpas.get_promise()); + run_after_channel_difference(dialog_id, MessageId::get_message_id(message, false), mpas.get_promise(), source); } } // must be added after messages_info is checked @@ -9686,6 +8780,28 @@ void MessagesManager::get_channel_differences_if_needed(MessagesInfo &&messages_ lock.set_value(Unit()); } +void MessagesManager::get_channel_differences_if_needed( + const vector *> &messages, Promise &&promise, + const char *source) { + if (td_->auth_manager_->is_bot()) { + return promise.set_value(Unit()); + } + MultiPromiseActorSafe mpas{"GetChannelDifferencesIfNeededGenericMultiPromiseActor"}; + mpas.add_promise(std::move(promise)); + mpas.set_ignore_errors(true); + auto lock = mpas.get_promise(); + for (const auto &message : messages) { + if (message == nullptr) { + continue; + } + auto dialog_id = DialogId::get_message_dialog_id(*message); + if (need_channel_difference_to_add_message(dialog_id, *message)) { + run_after_channel_difference(dialog_id, MessageId::get_message_id(*message, false), mpas.get_promise(), source); + } + } + lock.set_value(Unit()); +} + void MessagesManager::on_get_messages(vector> &&messages, bool is_channel_message, bool is_scheduled, Promise &&promise, const char *source) { TRY_STATUS_PROMISE(promise, G()->close_status()); @@ -9735,7 +8851,11 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ << dialog_id << " from " << from_message_id << " with offset " << offset << " and limit " << limit; CHECK(-limit < offset && offset <= 0); CHECK(offset < 0 || from_the_end); - CHECK(!from_message_id.is_scheduled()); + if (from_the_end) { + CHECK(from_message_id == MessageId()); + } else { + CHECK(!from_message_id.is_scheduled()); + } Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); @@ -9745,11 +8865,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ last_received_message_id < d->last_new_message_id) { // new server messages were added to the dialog since the request was sent, but weren't received // they should have been received, so we must repeat the request to get them - if (from_the_end) { - get_history_from_the_end_impl(d, false, false, std::move(promise), "on_get_history"); - } else { - get_history_impl(d, from_message_id, offset, limit, false, false, std::move(promise)); - } + get_history_impl(d, from_message_id, offset, limit, false, false, std::move(promise), "on_get_history"); return; } @@ -9800,7 +8916,7 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ } // be aware that returned messages are guaranteed to be consecutive messages, but if !from_the_end they - // may be older (if some messages was deleted) or newer (if some messages were added) than an expected answer + // may be older (if some messages were deleted) or newer (if some messages were added) than an expected answer // be aware that any subset of the returned messages may be already deleted and returned as MessageEmpty bool is_channel_message = dialog_id.get_type() == DialogType::Channel; MessageId first_added_message_id; @@ -9863,8 +8979,8 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ continue; } - auto full_message_id = on_get_message(std::move(message), false, is_channel_message, false, "get history"); - auto message_id = full_message_id.get_message_id(); + auto message_full_id = on_get_message(std::move(message), false, is_channel_message, false, "get history"); + auto message_id = message_full_id.get_message_id(); if (message_id.is_valid()) { CHECK(message_id == expected_message_id); if (have_next) { @@ -10013,20 +9129,6 @@ void MessagesManager::on_get_history(DialogId dialog_id, MessageId from_message_ promise.set_value(Unit()); } -vector MessagesManager::get_peers_dialog_ids(vector> &&peers, - bool expect_no_access) { - vector result; - result.reserve(peers.size()); - for (auto &peer : peers) { - DialogId dialog_id(peer); - if (dialog_id.is_valid()) { - force_create_dialog(dialog_id, "get_peers_dialog_ids", expect_no_access); - result.push_back(dialog_id); - } - } - return result; -} - void MessagesManager::on_get_public_dialogs_search_result(const string &query, vector> &&my_peers, vector> &&peers) { @@ -10036,8 +9138,9 @@ void MessagesManager::on_get_public_dialogs_search_result(const string &query, auto promises = std::move(it->second); search_public_dialogs_queries_.erase(it); - found_public_dialogs_[query] = get_peers_dialog_ids(std::move(peers)); - found_on_server_dialogs_[query] = get_peers_dialog_ids(std::move(my_peers)); + CHECK(!query.empty()); + found_public_dialogs_[query] = td_->dialog_manager_->get_peers_dialog_ids(std::move(peers)); + found_on_server_dialogs_[query] = td_->dialog_manager_->get_peers_dialog_ids(std::move(my_peers)); set_promises(promises); } @@ -10056,25 +9159,23 @@ void MessagesManager::on_failed_public_dialogs_search(const string &query, Statu } void MessagesManager::on_get_message_search_result_calendar( - DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, int64 random_id, int32 total_count, - vector> &&messages, - vector> &&periods, Promise &&promise) { + DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, + MessageSearchFilter filter, int32 total_count, vector> &&messages, + vector> &&periods, + Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); - auto it = found_dialog_message_calendars_.find(random_id); - CHECK(it != found_dialog_message_calendars_.end()); - int32 received_message_count = 0; for (auto &message : messages) { - auto new_full_message_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, + auto new_message_full_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, false, "on_get_message_search_result_calendar"); - if (new_full_message_id == FullMessageId()) { + if (new_message_full_id == MessageFullId()) { total_count--; continue; } - if (new_full_message_id.get_dialog_id() != dialog_id) { - LOG(ERROR) << "Receive " << new_full_message_id << " instead of a message in " << dialog_id; + if (new_message_full_id.get_dialog_id() != dialog_id) { + LOG(ERROR) << "Receive " << new_message_full_id << " instead of a message in " << dialog_id; total_count--; continue; } @@ -10089,10 +9190,12 @@ void MessagesManager::on_get_message_search_result_calendar( Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - auto &old_message_count = d->message_count_by_index[message_search_filter_index(filter)]; - if (old_message_count != total_count) { - old_message_count = total_count; - on_dialog_updated(dialog_id, "on_get_message_search_result_calendar"); + if (!saved_messages_topic_id.is_valid()) { + auto &old_message_count = d->message_count_by_index[message_search_filter_index(filter)]; + if (old_message_count != total_count) { + old_message_count = total_count; + on_dialog_updated(dialog_id, "on_get_message_search_result_calendar"); + } } vector> days; @@ -10110,97 +9213,91 @@ void MessagesManager::on_get_message_search_result_calendar( days.push_back(td_api::make_object( period->count_, get_message_object(dialog_id, m, "on_get_message_search_result_calendar"))); } - it->second = td_api::make_object(total_count, std::move(days)); - promise.set_value(Unit()); -} - -void MessagesManager::on_failed_get_message_search_result_calendar(DialogId dialog_id, int64 random_id) { - auto it = found_dialog_message_calendars_.find(random_id); - CHECK(it != found_dialog_message_calendars_.end()); - found_dialog_message_calendars_.erase(it); + promise.set_value(td_api::make_object(total_count, std::move(days))); } -void MessagesManager::on_get_dialog_messages_search_result( - DialogId dialog_id, const string &query, DialogId sender_dialog_id, MessageId from_message_id, int32 offset, - int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, int64 random_id, int32 total_count, - vector> &&messages, Promise &&promise) { +void MessagesManager::on_get_call_messages(MessageId from_message_id, int32 limit, MessageSearchFilter filter, + int32 total_count, + vector> &&messages, + Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); - LOG(INFO) << "Receive " << messages.size() << " found messages in " << dialog_id; - if (!dialog_id.is_valid()) { - CHECK(query.empty()); - CHECK(!sender_dialog_id.is_valid()); - CHECK(!top_thread_message_id.is_valid()); - auto it = found_call_messages_.find(random_id); - CHECK(it != found_call_messages_.end()); + LOG(INFO) << "Receive " << messages.size() << " found call messages"; + MessageId first_added_message_id; + if (messages.empty()) { + // messages may be empty because there are no more messages or they can't be found due to global limit + // anyway pretend that there are no more messages + first_added_message_id = MessageId::min(); + } - MessageId first_added_message_id; - if (messages.empty()) { - // messages may be empty because there are no more messages or they can't be found due to global limit - // anyway pretend that there are no more messages - first_added_message_id = MessageId::min(); + FoundMessages found_messages; + auto &result = found_messages.message_full_ids; + int32 added_message_count = 0; + MessageId next_offset_message_id; + for (auto &message : messages) { + auto message_id = MessageId::get_message_id(message, false); + if (message_id.is_valid() && (!next_offset_message_id.is_valid() || message_id < next_offset_message_id)) { + next_offset_message_id = message_id; + } + auto new_message_full_id = on_get_message(std::move(message), false, false, false, "on_get_call_messages"); + if (new_message_full_id == MessageFullId()) { + continue; } - auto &result = it->second.full_message_ids; - CHECK(result.empty()); - int32 added_message_count = 0; - MessageId next_offset_message_id; - for (auto &message : messages) { - auto message_id = MessageId::get_message_id(message, false); - if (message_id.is_valid() && (!next_offset_message_id.is_valid() || message_id < next_offset_message_id)) { - next_offset_message_id = message_id; - } - auto new_full_message_id = on_get_message(std::move(message), false, false, false, "search call messages"); - if (new_full_message_id == FullMessageId()) { - continue; - } - - result.push_back(new_full_message_id); - added_message_count++; + result.push_back(new_message_full_id); + added_message_count++; - CHECK(message_id == new_full_message_id.get_message_id()); - CHECK(message_id.is_valid()); - if (message_id < first_added_message_id || !first_added_message_id.is_valid()) { - first_added_message_id = message_id; - } - } - if (total_count < added_message_count) { - LOG(ERROR) << "Receive total_count = " << total_count << ", but added " << added_message_count - << " messages out of " << messages.size(); - total_count = added_message_count; + CHECK(message_id == new_message_full_id.get_message_id()); + CHECK(message_id.is_valid()); + if (message_id < first_added_message_id || !first_added_message_id.is_valid()) { + first_added_message_id = message_id; } - if (G()->use_message_database()) { - bool update_state = false; - - auto &old_message_count = calls_db_state_.message_count_by_index[call_message_search_filter_index(filter)]; - if (old_message_count != total_count) { - LOG(INFO) << "Update calls database message count to " << total_count; - old_message_count = total_count; - update_state = true; - } + } + if (total_count < added_message_count) { + LOG(ERROR) << "Receive total_count = " << total_count << ", but added " << added_message_count + << " messages out of " << messages.size(); + total_count = added_message_count; + } + if (G()->use_message_database()) { + bool update_state = false; - auto &old_first_db_message_id = - calls_db_state_.first_calls_database_message_id_by_index[call_message_search_filter_index(filter)]; - bool from_the_end = !from_message_id.is_valid() || from_message_id >= MessageId::max(); - LOG(INFO) << "Have from_the_end = " << from_the_end << ", old_first_db_message_id = " << old_first_db_message_id - << ", first_added_message_id = " << first_added_message_id << ", from_message_id = " << from_message_id; - if ((from_the_end || (old_first_db_message_id.is_valid() && old_first_db_message_id <= from_message_id)) && - (!old_first_db_message_id.is_valid() || first_added_message_id < old_first_db_message_id)) { - LOG(INFO) << "Update calls database first message to " << first_added_message_id; - old_first_db_message_id = first_added_message_id; - update_state = true; - } - if (update_state) { - save_calls_db_state(); - } + auto &old_message_count = calls_db_state_.message_count_by_index[call_message_search_filter_index(filter)]; + if (old_message_count != total_count) { + LOG(INFO) << "Update calls database message count to " << total_count; + old_message_count = total_count; + update_state = true; } - it->second.total_count = total_count; - if (next_offset_message_id.is_valid()) { - it->second.next_offset = PSTRING() << next_offset_message_id.get_server_message_id().get(); + + auto &old_first_db_message_id = + calls_db_state_.first_calls_database_message_id_by_index[call_message_search_filter_index(filter)]; + bool from_the_end = !from_message_id.is_valid() || from_message_id >= MessageId::max(); + LOG(INFO) << "Have from_the_end = " << from_the_end << ", old_first_db_message_id = " << old_first_db_message_id + << ", first_added_message_id = " << first_added_message_id << ", from_message_id = " << from_message_id; + if ((from_the_end || (old_first_db_message_id.is_valid() && old_first_db_message_id <= from_message_id)) && + (!old_first_db_message_id.is_valid() || first_added_message_id < old_first_db_message_id)) { + LOG(INFO) << "Update calls database first message to " << first_added_message_id; + old_first_db_message_id = first_added_message_id; + update_state = true; + } + if (update_state) { + save_calls_db_state(); } - promise.set_value(Unit()); - return; } + found_messages.total_count = total_count; + if (next_offset_message_id.is_valid()) { + found_messages.next_offset = PSTRING() << next_offset_message_id.get_server_message_id().get(); + } + promise.set_value(get_found_messages_object(found_messages, "on_get_call_messages")); +} + +void MessagesManager::on_get_dialog_messages_search_result( + DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, const string &query, DialogId sender_dialog_id, + MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, + const ReactionType &tag, int64 random_id, int32 total_count, + vector> &&messages, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + LOG(INFO) << "Receive " << messages.size() << " found messages in " << dialog_id; auto it = found_dialog_messages_.find(random_id); CHECK(it != found_dialog_messages_.end()); @@ -10213,7 +9310,8 @@ void MessagesManager::on_get_dialog_messages_search_result( // anyway pretend that there are no more messages first_added_message_id = MessageId::min(); } - bool can_be_in_different_dialog = top_thread_message_id.is_valid() && is_broadcast_channel(dialog_id); + bool can_be_in_different_dialog = + top_thread_message_id.is_valid() && td_->dialog_manager_->is_broadcast_channel(dialog_id); DialogId real_dialog_id; MessageId next_from_message_id; Dialog *d = get_dialog(dialog_id); @@ -10223,24 +9321,24 @@ void MessagesManager::on_get_dialog_messages_search_result( if (message_id.is_valid() && (!next_from_message_id.is_valid() || message_id < next_from_message_id)) { next_from_message_id = message_id; } - auto new_full_message_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, + auto new_message_full_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, false, "on_get_dialog_messages_search_result"); - if (new_full_message_id == FullMessageId()) { + if (new_message_full_id == MessageFullId()) { total_count--; continue; } - if (new_full_message_id.get_dialog_id() != dialog_id) { + if (new_message_full_id.get_dialog_id() != dialog_id) { if (!can_be_in_different_dialog) { - LOG(ERROR) << "Receive " << new_full_message_id << " instead of a message in " << dialog_id; + LOG(ERROR) << "Receive " << new_message_full_id << " instead of a message in " << dialog_id; total_count--; continue; } else { if (!real_dialog_id.is_valid()) { - real_dialog_id = new_full_message_id.get_dialog_id(); + real_dialog_id = new_message_full_id.get_dialog_id(); found_dialog_messages_dialog_id_[random_id] = real_dialog_id; - } else if (new_full_message_id.get_dialog_id() != real_dialog_id) { - LOG(ERROR) << "Receive " << new_full_message_id << " instead of a message in " << real_dialog_id << " or " + } else if (new_message_full_id.get_dialog_id() != real_dialog_id) { + LOG(ERROR) << "Receive " << new_message_full_id << " instead of a message in " << real_dialog_id << " or " << dialog_id; total_count--; continue; @@ -10248,7 +9346,7 @@ void MessagesManager::on_get_dialog_messages_search_result( } } - CHECK(message_id == new_full_message_id.get_message_id()); + CHECK(message_id == new_message_full_id.get_message_id()); if (filter == MessageSearchFilter::UnreadMention && message_id <= d->last_read_all_mentions_message_id && !real_dialog_id.is_valid()) { total_count--; @@ -10256,11 +9354,11 @@ void MessagesManager::on_get_dialog_messages_search_result( } if (filter != MessageSearchFilter::Empty) { - const Message *m = get_message(new_full_message_id); + const Message *m = get_message(new_message_full_id); CHECK(m != nullptr); - auto index_mask = get_message_index_mask(new_full_message_id.get_dialog_id(), m); + auto index_mask = get_message_index_mask(new_message_full_id.get_dialog_id(), m); if ((message_search_filter_index_mask(filter) & index_mask) == 0) { - LOG(INFO) << "Skip " << new_full_message_id << " of unexpected type"; + LOG(INFO) << "Skip " << new_message_full_id << " of unexpected type"; total_count--; continue; } @@ -10278,7 +9376,7 @@ void MessagesManager::on_get_dialog_messages_search_result( total_count = static_cast(result.size()); } if (query.empty() && !sender_dialog_id.is_valid() && filter != MessageSearchFilter::Empty && - !top_thread_message_id.is_valid()) { + !top_thread_message_id.is_valid() && !saved_messages_topic_id.is_valid() && tag.is_empty()) { bool from_the_end = !from_message_id.is_valid() || (d->last_message_id != MessageId() && from_message_id > d->last_message_id) || from_message_id >= MessageId::max(); @@ -10322,26 +9420,25 @@ void MessagesManager::on_get_dialog_messages_search_result( } void MessagesManager::on_failed_dialog_messages_search(DialogId dialog_id, int64 random_id) { - if (!dialog_id.is_valid()) { - auto it = found_call_messages_.find(random_id); - CHECK(it != found_call_messages_.end()); - found_call_messages_.erase(it); - return; - } - auto it = found_dialog_messages_.find(random_id); CHECK(it != found_dialog_messages_.end()); found_dialog_messages_.erase(it); } -void MessagesManager::on_get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, int32 total_count, +void MessagesManager::on_get_dialog_message_count(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, int32 total_count, Promise &&promise) { LOG(INFO) << "Receive " << total_count << " message count in " << dialog_id << " with filter " << filter; if (total_count < 0) { - LOG(ERROR) << "Receive total message count = " << total_count << " in " << dialog_id << " with filter " << filter; + LOG(ERROR) << "Receive total message count = " << total_count << " in " << dialog_id << " with " + << saved_messages_topic_id << " and filter " << filter; total_count = 0; } + if (saved_messages_topic_id.is_valid()) { + return promise.set_value(std::move(total_count)); + } + Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); CHECK(filter != MessageSearchFilter::Empty); @@ -10371,35 +9468,24 @@ void MessagesManager::on_get_dialog_message_count(DialogId dialog_id, MessageSea void MessagesManager::on_get_messages_search_result(const string &query, int32 offset_date, DialogId offset_dialog_id, MessageId offset_message_id, int32 limit, MessageSearchFilter filter, int32 min_date, int32 max_date, - int64 random_id, int32 total_count, + int32 total_count, vector> &&messages, - int32 next_rate, Promise &&promise) { + int32 next_rate, + Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); LOG(INFO) << "Receive " << messages.size() << " found messages"; - auto it = found_messages_.find(random_id); - CHECK(it != found_messages_.end()); - auto &result = it->second.full_message_ids; - CHECK(result.empty()); - int32 last_message_date = 0; - MessageId last_message_id; - DialogId last_dialog_id; + FoundMessages found_messages; + auto &result = found_messages.message_full_ids; + MessageSearchOffset next_offset; for (auto &message : messages) { - auto message_date = get_message_date(message); - auto message_id = MessageId::get_message_id(message, false); - auto dialog_id = DialogId::get_message_dialog_id(message); - if (message_date > 0 && message_id.is_valid() && dialog_id.is_valid()) { - last_message_date = message_date; - last_message_id = message_id; - last_dialog_id = dialog_id; - } + next_offset.update_from_message(message); - auto new_full_message_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, - false, "search messages"); - if (new_full_message_id != FullMessageId()) { - CHECK(dialog_id == new_full_message_id.get_dialog_id()); - result.push_back(new_full_message_id); + bool is_channel_message = DialogId::get_message_dialog_id(message).get_type() == DialogType::Channel; + auto new_message_full_id = on_get_message(std::move(message), false, is_channel_message, false, "search messages"); + if (new_message_full_id != MessageFullId()) { + result.push_back(new_message_full_id); } else { total_count--; } @@ -10409,21 +9495,49 @@ void MessagesManager::on_get_messages_search_result(const string &query, int32 o << " messages"; total_count = static_cast(result.size()); } - it->second.total_count = total_count; + found_messages.total_count = total_count; if (!result.empty()) { if (next_rate > 0) { - last_message_date = next_rate; + next_offset.date_ = next_rate; } - it->second.next_offset = PSTRING() << last_message_date << ',' << last_dialog_id.get() << ',' - << last_message_id.get_server_message_id().get(); + found_messages.next_offset = next_offset.to_string(); } - promise.set_value(Unit()); + promise.set_value(get_found_messages_object(found_messages, "on_get_messages_search_result")); } -void MessagesManager::on_failed_messages_search(int64 random_id) { - auto it = found_messages_.find(random_id); - CHECK(it != found_messages_.end()); - found_messages_.erase(it); +void MessagesManager::on_get_hashtag_search_result(const string &hashtag, const MessageSearchOffset &old_offset, + int32 limit, int32 total_count, + vector> &&messages, + int32 next_rate, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + FoundMessages found_messages; + auto &result = found_messages.message_full_ids; + MessageSearchOffset next_offset; + for (auto &message : messages) { + next_offset.update_from_message(message); + + auto new_message_full_id = on_get_message(std::move(message), false, true, false, "search hashtag"); + if (new_message_full_id != MessageFullId()) { + result.push_back(new_message_full_id); + } else { + total_count--; + } + } + if (total_count < static_cast(result.size())) { + LOG(ERROR) << "Receive " << result.size() << " valid messages out of " << total_count << " in " << messages.size() + << " messages"; + total_count = static_cast(result.size()); + } + found_messages.total_count = total_count; + if (!result.empty()) { + if (next_rate > 0) { + next_offset.date_ = next_rate; + } + found_messages.next_offset = next_offset.to_string(); + } + promise.set_value(get_found_messages_object(found_messages, "on_get_hashtag_search_result")); } void MessagesManager::on_get_outgoing_document_messages(vector> &&messages, @@ -10433,11 +9547,11 @@ void MessagesManager::on_get_outgoing_document_messages(vectorsent_scheduled_messages, is_channel_message, true, + auto message_full_id = on_get_message(std::move(message), d->sent_scheduled_messages, is_channel_message, true, "on_get_scheduled_server_messages"); - auto message_id = full_message_id.get_message_id(); + auto message_id = message_full_id.get_message_id(); if (message_id.is_valid_scheduled()) { CHECK(message_id.is_scheduled_server()); old_server_message_ids.erase(message_id.get_scheduled_server_message_id()); @@ -10516,15 +9634,15 @@ void MessagesManager::on_get_recent_locations(DialogId dialog_id, int32 limit, i LOG(INFO) << "Receive " << messages.size() << " recent locations in " << dialog_id; vector result; for (auto &message : messages) { - auto new_full_message_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, + auto new_message_full_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, false, "get recent locations"); - if (new_full_message_id != FullMessageId()) { - if (new_full_message_id.get_dialog_id() != dialog_id) { - LOG(ERROR) << "Receive " << new_full_message_id << " instead of a message in " << dialog_id; + if (new_message_full_id != MessageFullId()) { + if (new_message_full_id.get_dialog_id() != dialog_id) { + LOG(ERROR) << "Receive " << new_message_full_id << " instead of a message in " << dialog_id; total_count--; continue; } - auto m = get_message(new_full_message_id); + auto m = get_message(new_message_full_id); CHECK(m != nullptr); if (m->content->get_type() != MessageContentType::LiveLocation) { LOG(ERROR) << "Receive a message of wrong type " << m->content->get_type() << " in on_get_recent_locations in " @@ -10546,55 +9664,7 @@ void MessagesManager::on_get_recent_locations(DialogId dialog_id, int32 limit, i promise.set_value(get_messages_object(total_count, dialog_id, result, true, "on_get_recent_locations")); } -void MessagesManager::on_get_message_public_forwards(int32 total_count, - vector> &&messages, - int32 next_rate, - Promise> &&promise) { - TRY_STATUS_PROMISE(promise, G()->close_status()); - - LOG(INFO) << "Receive " << messages.size() << " forwarded messages"; - vector> result; - int32 last_message_date = 0; - MessageId last_message_id; - DialogId last_dialog_id; - for (auto &message : messages) { - auto message_date = get_message_date(message); - auto message_id = MessageId::get_message_id(message, false); - auto dialog_id = DialogId::get_message_dialog_id(message); - if (message_date > 0 && message_id.is_valid() && dialog_id.is_valid()) { - last_message_date = message_date; - last_message_id = message_id; - last_dialog_id = dialog_id; - } - - auto new_full_message_id = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, - false, "get message public forwards"); - if (new_full_message_id != FullMessageId()) { - CHECK(dialog_id == new_full_message_id.get_dialog_id()); - result.push_back(get_message_object(new_full_message_id, "on_get_message_public_forwards")); - CHECK(result.back() != nullptr); - } else { - total_count--; - } - } - if (total_count < static_cast(result.size())) { - LOG(ERROR) << "Receive " << result.size() << " valid messages out of " << total_count << " in " << messages.size() - << " messages"; - total_count = static_cast(result.size()); - } - string next_offset; - if (!result.empty()) { - if (next_rate > 0) { - last_message_date = next_rate; - } - next_offset = PSTRING() << last_message_date << ',' << last_dialog_id.get() << ',' - << last_message_id.get_server_message_id().get(); - } - - promise.set_value(td_api::make_object(total_count, std::move(result), next_offset)); -} - -void MessagesManager::delete_messages_from_updates(const vector &message_ids) { +void MessagesManager::delete_messages_from_updates(const vector &message_ids, bool is_permanent) { FlatHashMap, DialogIdHash> deleted_message_ids; FlatHashMap need_update_dialog_pos; vector> deleted_messages; @@ -10606,8 +9676,8 @@ void MessagesManager::delete_messages_from_updates(const vector &mess Dialog *d = get_dialog_by_message_id(message_id); if (d != nullptr) { - auto message = - delete_message(d, message_id, true, &need_update_dialog_pos[d->dialog_id], "delete_messages_from_updates"); + auto message = delete_message(d, message_id, is_permanent, &need_update_dialog_pos[d->dialog_id], + "delete_messages_from_updates"); CHECK(message != nullptr); LOG_CHECK(message->message_id == message_id) << message_id << " " << message->message_id << " " << d->dialog_id; deleted_message_ids[d->dialog_id].push_back(message->message_id.get()); @@ -10616,8 +9686,8 @@ void MessagesManager::delete_messages_from_updates(const vector &mess if (last_clear_history_message_id_to_dialog_id_.count(message_id)) { d = get_dialog(last_clear_history_message_id_to_dialog_id_[message_id]); CHECK(d != nullptr); - auto message = - delete_message(d, message_id, true, &need_update_dialog_pos[d->dialog_id], "delete_messages_from_updates"); + auto message = delete_message(d, message_id, is_permanent, &need_update_dialog_pos[d->dialog_id], + "delete_messages_from_updates"); CHECK(message == nullptr); } } @@ -10634,7 +9704,7 @@ void MessagesManager::delete_messages_from_updates(const vector &mess } for (auto &it : deleted_message_ids) { auto dialog_id = it.first; - send_update_delete_messages(dialog_id, std::move(it.second), true); + send_update_delete_messages(dialog_id, std::move(it.second), is_permanent); } } @@ -10751,7 +9821,7 @@ bool MessagesManager::can_forward_message(DialogId from_dialog_id, const Message if (m == nullptr) { return false; } - if (m->ttl > 0) { + if (!m->ttl.is_empty()) { return false; } if (m->message_id.is_scheduled()) { @@ -10778,23 +9848,33 @@ bool MessagesManager::can_save_message(DialogId dialog_id, const Message *m) con if (m == nullptr || m->noforwards || m->is_content_secret) { return false; } - return !get_dialog_has_protected_content(dialog_id); + return !td_->dialog_manager_->get_dialog_has_protected_content(dialog_id); +} + +bool MessagesManager::can_share_message_in_story(MessageFullId message_full_id) { + return can_share_message_in_story(message_full_id.get_dialog_id(), + get_message_force(message_full_id, "can_share_message_in_story")); +} + +bool MessagesManager::can_share_message_in_story(DialogId dialog_id, const Message *m) const { + return dialog_id.get_type() == DialogType::Channel && m != nullptr && m->message_id.is_valid() && + m->message_id.is_server(); } -bool MessagesManager::can_get_message_statistics(FullMessageId full_message_id) { - return can_get_message_statistics(full_message_id.get_dialog_id(), - get_message_force(full_message_id, "can_get_message_statistics")); +bool MessagesManager::can_get_message_statistics(MessageFullId message_full_id) { + return can_get_message_statistics(message_full_id.get_dialog_id(), + get_message_force(message_full_id, "can_get_message_statistics")); } bool MessagesManager::can_get_message_statistics(DialogId dialog_id, const Message *m) const { - if (td_->auth_manager_->is_bot()) { + if (td_->auth_manager_->is_bot() || dialog_id.get_type() != DialogType::Channel) { return false; } if (m == nullptr || m->message_id.is_scheduled() || !m->message_id.is_server() || m->view_count == 0 || - m->had_forward_info || (m->forward_info != nullptr && m->forward_info->message_id.is_valid())) { + m->had_forward_info || (m->forward_info != nullptr && m->forward_info->get_origin().is_channel_post())) { return false; } - return td_->contacts_manager_->can_get_channel_message_statistics(dialog_id); + return td_->chat_manager_->can_get_channel_message_statistics(dialog_id.get_channel_id()); } bool MessagesManager::can_delete_channel_message(const DialogParticipantStatus &status, const Message *m, bool is_bot) { @@ -10811,7 +9891,7 @@ bool MessagesManager::can_delete_channel_message(const DialogParticipantStatus & return true; } - if (is_bot && G()->unix_time_cached() >= m->date + 2 * 86400) { + if (is_bot && G()->unix_time() >= m->date + 2 * 86400) { // bots can't delete messages older than 2 days return false; } @@ -10854,7 +9934,7 @@ bool MessagesManager::can_delete_message(DialogId dialog_id, const Message *m) c case DialogType::Chat: return true; case DialogType::Channel: { - auto dialog_status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()); + auto dialog_status = td_->chat_manager_->get_channel_permissions(dialog_id.get_channel_id()); return can_delete_channel_message(dialog_status, m, td_->auth_manager_->is_bot()); } case DialogType::SecretChat: @@ -10873,7 +9953,7 @@ bool MessagesManager::can_revoke_message(DialogId dialog_id, const Message *m) c if (m->message_id.is_local()) { return false; } - if (dialog_id == get_my_dialog_id()) { + if (dialog_id == td_->dialog_manager_->get_my_dialog_id()) { return false; } if (m->message_id.is_scheduled()) { @@ -10892,27 +9972,26 @@ bool MessagesManager::can_revoke_message(DialogId dialog_id, const Message *m) c int64 revoke_time_limit = td_->option_manager_->get_option_integer("revoke_pm_time_limit", DEFAULT_REVOKE_TIME_LIMIT); - if (G()->unix_time_cached() - m->date < 86400 && content_type == MessageContentType::Dice) { + if (G()->unix_time() - m->date < 86400 && content_type == MessageContentType::Dice) { return false; } return ((m->is_outgoing && !is_service_message_content(content_type)) || (can_revoke_incoming && content_type != MessageContentType::ScreenshotTaken)) && - G()->unix_time_cached() - m->date <= revoke_time_limit; + G()->unix_time() - m->date <= revoke_time_limit; } case DialogType::Chat: { - bool is_appointed_administrator = - td_->contacts_manager_->is_appointed_chat_administrator(dialog_id.get_chat_id()); + bool is_appointed_administrator = td_->chat_manager_->is_appointed_chat_administrator(dialog_id.get_chat_id()); int64 revoke_time_limit = td_->option_manager_->get_option_integer("revoke_time_limit", DEFAULT_REVOKE_TIME_LIMIT); return ((m->is_outgoing && !is_service_message_content(content_type)) || is_appointed_administrator) && - G()->unix_time_cached() - m->date <= revoke_time_limit; + G()->unix_time() - m->date <= revoke_time_limit; } case DialogType::Channel: return true; // any server message that can be deleted will be deleted for all participants case DialogType::SecretChat: // all non-service messages will be deleted for everyone if secret chat is active - return td_->contacts_manager_->get_secret_chat_state(dialog_id.get_secret_chat_id()) == SecretChatState::Active && + return td_->user_manager_->get_secret_chat_state(dialog_id.get_secret_chat_id()) == SecretChatState::Active && !is_service_message_content(content_type); case DialogType::None: default: @@ -10998,7 +10077,7 @@ void MessagesManager::delete_sent_message_on_server(DialogId dialog_id, MessageI // being sent message was deleted by the user or is in an inaccessible channel // don't need to send an update to the user, because the message has already been deleted - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { LOG(INFO) << "Ignore sent " << message_id << " in inaccessible " << dialog_id; return; } @@ -11171,16 +10250,16 @@ void MessagesManager::on_failed_message_deletion(DialogId dialog_id, const vecto } Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - vector full_message_ids; + vector message_full_ids; for (auto &server_message_id : server_message_ids) { auto message_id = MessageId(ServerMessageId(server_message_id)); d->deleted_message_ids.erase(message_id); - full_message_ids.emplace_back(dialog_id, message_id); + message_full_ids.emplace_back(dialog_id, message_id); } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { return; } - get_messages_from_server(std::move(full_message_ids), Promise(), "on_failed_message_deletion"); + get_messages_from_server(std::move(message_full_ids), Promise(), "on_failed_message_deletion"); } void MessagesManager::on_failed_scheduled_message_deletion(DialogId dialog_id, const vector &message_ids) { @@ -11194,11 +10273,11 @@ void MessagesManager::on_failed_scheduled_message_deletion(DialogId dialog_id, c d->scheduled_messages->deleted_scheduled_server_message_ids_.erase(message_id.get_scheduled_server_message_id()); } } - if (!have_input_peer(dialog_id, AccessRights::Read) || dialog_id.get_type() == DialogType::SecretChat) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { return; } - if (is_broadcast_channel(dialog_id) && - !td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).can_post_messages()) { + if (td_->dialog_manager_->is_broadcast_channel(dialog_id) && + !td_->chat_manager_->get_channel_status(dialog_id.get_channel_id()).can_post_messages()) { return; } load_dialog_scheduled_messages(dialog_id, false, 0, Promise()); @@ -11217,27 +10296,32 @@ MessagesManager::CanDeleteDialog MessagesManager::can_delete_dialog(const Dialog } } } - if (td_->auth_manager_->is_bot() || !have_input_peer(d->dialog_id, AccessRights::Read)) { + if (td_->auth_manager_->is_bot() || !td_->dialog_manager_->have_input_peer(d->dialog_id, true, AccessRights::Read)) { return {false, false}; } switch (d->dialog_id.get_type()) { case DialogType::User: - if (d->dialog_id == get_my_dialog_id() || td_->contacts_manager_->is_user_deleted(d->dialog_id.get_user_id()) || - td_->contacts_manager_->is_user_bot(d->dialog_id.get_user_id())) { + if (d->dialog_id == td_->dialog_manager_->get_my_dialog_id() || + td_->user_manager_->is_user_deleted(d->dialog_id.get_user_id()) || + td_->user_manager_->is_user_bot(d->dialog_id.get_user_id())) { return {true, false}; } return {true, td_->option_manager_->get_option_boolean("revoke_pm_inbox", true)}; case DialogType::Chat: // chats can be deleted only for self and can be deleted for everyone by their creator - return {true, td_->contacts_manager_->get_chat_status(d->dialog_id.get_chat_id()).is_creator()}; - case DialogType::Channel: - // private supergroups can be deleted for self - return {!is_broadcast_channel(d->dialog_id) && - !td_->contacts_manager_->is_channel_public(d->dialog_id.get_channel_id()), - td_->contacts_manager_->get_channel_can_be_deleted(d->dialog_id.get_channel_id())}; + return {true, td_->chat_manager_->get_chat_status(d->dialog_id.get_chat_id()).is_creator()}; + case DialogType::Channel: { + // private non-forum joined supergroups can be deleted for self + auto channel_id = d->dialog_id.get_channel_id(); + return {!td_->chat_manager_->is_broadcast_channel(channel_id) && + !td_->chat_manager_->is_channel_public(channel_id) && + !td_->chat_manager_->is_forum_channel(channel_id) && + td_->chat_manager_->get_channel_status(channel_id).is_member(), + td_->chat_manager_->get_channel_can_be_deleted(channel_id)}; + } case DialogType::SecretChat: - if (td_->contacts_manager_->get_secret_chat_state(d->dialog_id.get_secret_chat_id()) == SecretChatState::Closed) { + if (td_->user_manager_->get_secret_chat_state(d->dialog_id.get_secret_chat_id()) == SecretChatState::Closed) { // in a closed secret chats there is no way to delete messages for both users return {true, false}; } @@ -11255,14 +10339,7 @@ void MessagesManager::delete_dialog_history(DialogId dialog_id, bool remove_from LOG(INFO) << "Receive deleteChatHistory request to delete all messages in " << dialog_id << ", remove_from_chat_list is " << remove_from_dialog_list << ", revoke is " << revoke; - Dialog *d = get_dialog_force(dialog_id, "delete_dialog_history"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Chat info not found")); - } + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Read, "delete_dialog_history")); if (is_dialog_sponsored(d)) { auto chat_source = sponsored_dialog_source_.get_chat_source_object(); @@ -11401,14 +10478,8 @@ void MessagesManager::delete_dialog_history_on_server(DialogId dialog_id, Messag void MessagesManager::delete_topic_history(DialogId dialog_id, MessageId top_thread_message_id, Promise &&promise) { - Dialog *d = get_dialog_force(dialog_id, "delete_dialog_history"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Chat info not found")); - } + TRY_STATUS_PROMISE( + promise, td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Read, "delete_topic_history")); // auto old_order = d->order; // delete_all_dialog_topic_messages(d, top_thread_message_id); @@ -11543,16 +10614,10 @@ void MessagesManager::delete_dialog_messages_by_sender(DialogId dialog_id, Dialo bool is_bot = td_->auth_manager_->is_bot(); CHECK(!is_bot); - Dialog *d = get_dialog_force(dialog_id, "delete_dialog_messages_by_sender"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Write)) { - return promise.set_error(Status::Error(400, "Not enough rights")); - } + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, true, AccessRights::Write, "delete_dialog_messages_by_sender")); - if (!have_input_peer(sender_dialog_id, AccessRights::Know)) { + if (!td_->dialog_manager_->have_input_peer(sender_dialog_id, false, AccessRights::Know)) { return promise.set_error(Status::Error(400, "Message sender not found")); } @@ -11566,10 +10631,10 @@ void MessagesManager::delete_dialog_messages_by_sender(DialogId dialog_id, Dialo Status::Error(400, "All messages from a sender can be deleted only in supergroup chats")); case DialogType::Channel: { channel_id = dialog_id.get_channel_id(); - if (!td_->contacts_manager_->is_megagroup_channel(channel_id)) { + if (!td_->chat_manager_->is_megagroup_channel(channel_id)) { return promise.set_error(Status::Error(400, "The method is available only in supergroup chats")); } - channel_status = td_->contacts_manager_->get_channel_permissions(channel_id); + channel_status = td_->chat_manager_->get_channel_permissions(channel_id); if (!channel_status.can_delete_messages()) { return promise.set_error(Status::Error(400, "Need delete messages administator right in the supergroup chat")); } @@ -11649,27 +10714,16 @@ void MessagesManager::delete_all_channel_messages_by_sender_on_server(ChannelId get_erase_log_event_promise(log_event_id, std::move(promise))); } -void MessagesManager::delete_dialog_messages_by_date(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke, - Promise &&promise) { - bool is_bot = td_->auth_manager_->is_bot(); - CHECK(!is_bot); - - Dialog *d = get_dialog_force(dialog_id, "delete_dialog_messages_by_date"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - +Status MessagesManager::fix_delete_message_min_max_dates(int32 &min_date, int32 &max_date) { if (min_date > max_date) { - return promise.set_error(Status::Error(400, "Wrong date interval specified")); + return Status::Error(400, "Wrong date interval specified"); } const int32 telegram_launch_date = 1376438400; if (max_date < telegram_launch_date) { - return promise.set_value(Unit()); + max_date = 0; + min_date = 0; + return Status::OK(); } if (min_date < telegram_launch_date) { min_date = telegram_launch_date; @@ -11677,12 +10731,27 @@ void MessagesManager::delete_dialog_messages_by_date(DialogId dialog_id, int32 m auto current_date = max(G()->unix_time(), 1635000000); if (min_date >= current_date - 30) { - return promise.set_value(Unit()); + max_date = 0; + min_date = 0; + return Status::OK(); } if (max_date >= current_date - 30) { max_date = current_date - 31; } CHECK(min_date <= max_date); + return Status::OK(); +} + +void MessagesManager::delete_dialog_messages_by_date(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke, + Promise &&promise) { + CHECK(!td_->auth_manager_->is_bot()); + + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, true, AccessRights::Read, "delete_dialog_messages_by_date")); + TRY_STATUS_PROMISE(promise, fix_delete_message_min_max_dates(min_date, max_date)); + if (max_date == 0) { + return promise.set_value(Unit()); + } switch (dialog_id.get_type()) { case DialogType::User: @@ -11779,10 +10848,13 @@ double MessagesManager::get_next_unload_dialog_delay(Dialog *d) const { return delay + delay * 1e-9 * d->unload_dialog_delay_seed; } -void MessagesManager::unload_dialog(DialogId dialog_id) { +void MessagesManager::unload_dialog(DialogId dialog_id, int32 delay) { if (G()->close_flag()) { return; } + if (delay < 0) { + delay = get_unload_dialog_delay() - 2; + } Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); @@ -11801,8 +10873,7 @@ void MessagesManager::unload_dialog(DialogId dialog_id) { } bool has_left_to_unload_messages = false; - auto to_unload_message_ids = - find_unloadable_messages(d, G()->unix_time_cached() - get_unload_dialog_delay() + 2, has_left_to_unload_messages); + auto to_unload_message_ids = find_unloadable_messages(d, G()->unix_time() - delay, has_left_to_unload_messages); vector unloaded_message_ids; vector> unloaded_messages; @@ -11909,6 +10980,7 @@ void MessagesManager::delete_all_dialog_messages(Dialog *d, bool remove_from_dia clear_dialog_message_list(d, remove_from_dialog_list, last_message_date); } + bool was_live_location_deleted = false; vector deleted_message_ids; d->messages.foreach([&](const MessageId &message_id, unique_ptr &message) { CHECK(message_id == message->message_id); @@ -11919,7 +10991,9 @@ void MessagesManager::delete_all_dialog_messages(Dialog *d, bool remove_from_dia LOG(INFO) << "Delete " << message_id; deleted_message_ids.push_back(message_id.get()); - delete_active_live_location(d->dialog_id, m); + if (delete_active_live_location({d->dialog_id, m->message_id})) { + was_live_location_deleted = true; + } remove_message_file_sources(d->dialog_id, m); on_message_deleted(d, m, is_permanently_deleted, "do_delete_all_dialog_messages"); @@ -11930,15 +11004,19 @@ void MessagesManager::delete_all_dialog_messages(Dialog *d, bool remove_from_dia }); Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), d->messages, d->ordered_messages); + if (was_live_location_deleted) { + send_update_active_live_location_messages(); + save_active_live_locations(); + } + delete_all_dialog_messages_from_database(d, MessageId::max(), "delete_all_dialog_messages 3"); if (d->notification_info != nullptr) { - d->notification_info->message_notification_group_.max_removed_notification_id = - NotificationId(); // it is not needed anymore - d->notification_info->message_notification_group_.max_removed_message_id = MessageId(); // it is not needed anymore - d->notification_info->mention_notification_group_.max_removed_notification_id = - NotificationId(); // it is not needed anymore - d->notification_info->mention_notification_group_.max_removed_message_id = MessageId(); // it is not needed anymore + // they aren't needed anymore + delete_all_dialog_notifications(d, MessageId::max(), "delete_all_dialog_messages 4"); + + d->notification_info->message_notification_group_.drop_max_removed_notification_id(); + d->notification_info->mention_notification_group_.drop_max_removed_notification_id(); d->notification_info->notification_id_to_message_id_.clear(); } @@ -11962,8 +11040,10 @@ void MessagesManager::on_dialog_deleted(DialogId dialog_id, Promise &&prom d->need_restore_reply_markup = true; on_dialog_updated(dialog_id, "on_dialog_deleted"); } - recently_found_dialogs_.remove_dialog(dialog_id); - recently_opened_dialogs_.remove_dialog(dialog_id); + if (!td_->auth_manager_->is_bot()) { + recently_found_dialogs_.remove_dialog(dialog_id); + recently_opened_dialogs_.remove_dialog(dialog_id); + } if (dialog_id.get_type() == DialogType::Channel) { G()->td_db()->get_binlog_pmc()->erase(get_channel_pts_key(dialog_id)); } @@ -11989,16 +11069,8 @@ void MessagesManager::on_update_dialog_group_call_rights(DialogId dialog_id) { void MessagesManager::read_all_dialog_mentions(DialogId dialog_id, MessageId top_thread_message_id, Promise &&promise) { - Dialog *d = get_dialog_force(dialog_id, "read_all_dialog_mentions"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - TRY_STATUS_PROMISE(promise, can_use_top_thread_message_id(d, top_thread_message_id, MessageId())); - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Chat is not accessible")); - } + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Read, "read_all_dialog_mentions")); + TRY_STATUS_PROMISE(promise, can_use_top_thread_message_id(d, top_thread_message_id, MessageInputReplyTo())); if (top_thread_message_id.is_valid()) { LOG(INFO) << "Receive readAllChatMentions request in thread of " << top_thread_message_id << " in " << dialog_id; @@ -12092,16 +11164,8 @@ void MessagesManager::read_all_dialog_mentions_on_server(DialogId dialog_id, uin void MessagesManager::read_all_dialog_reactions(DialogId dialog_id, MessageId top_thread_message_id, Promise &&promise) { - Dialog *d = get_dialog_force(dialog_id, "read_all_dialog_reactions"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - TRY_STATUS_PROMISE(promise, can_use_top_thread_message_id(d, top_thread_message_id, MessageId())); - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Chat is not accessible")); - } + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Read, "read_all_dialog_reactions")); + TRY_STATUS_PROMISE(promise, can_use_top_thread_message_id(d, top_thread_message_id, MessageInputReplyTo())); if (top_thread_message_id.is_valid()) { LOG(INFO) << "Receive readAllChatReactions request in thread of " << top_thread_message_id << " in " << dialog_id; @@ -12188,7 +11252,7 @@ void MessagesManager::read_all_dialog_reactions_on_server(DialogId dialog_id, ui get_erase_log_event_promise(log_event_id, std::move(promise))); } -void MessagesManager::read_message_content_from_updates(MessageId message_id) { +void MessagesManager::read_message_content_from_updates(MessageId message_id, int32 read_date) { if (!message_id.is_valid() || !message_id.is_server()) { LOG(ERROR) << "Incoming update tries to read content of " << message_id; return; @@ -12198,7 +11262,7 @@ void MessagesManager::read_message_content_from_updates(MessageId message_id) { if (d != nullptr) { Message *m = get_message(d, message_id); CHECK(m != nullptr); - read_message_content(d, m, false, "read_message_content_from_updates"); + read_message_content(d, m, false, read_date, "read_message_content_from_updates"); } } @@ -12214,9 +11278,9 @@ void MessagesManager::read_channel_message_content_from_updates(Dialog *d, Messa Message *m = get_message_force(d, message_id, "read_channel_message_content_from_updates"); if (m != nullptr) { - read_message_content(d, m, false, "read_channel_message_content_from_updates"); + read_message_content(d, m, false, 0, "read_channel_message_content_from_updates"); } else { - if (!have_input_peer(d->dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(d->dialog_id, false, AccessRights::Read)) { LOG(INFO) << "Ignore updateChannelReadMessagesContents in inaccessible " << d->dialog_id; if (d->unread_mention_count != 0) { set_dialog_unread_mention_count(d, 0); @@ -12235,12 +11299,13 @@ void MessagesManager::read_channel_message_content_from_updates(Dialog *d, Messa } } -bool MessagesManager::read_message_content(Dialog *d, Message *m, bool is_local_read, const char *source) { +bool MessagesManager::read_message_content(Dialog *d, Message *m, bool is_local_read, int32 read_date, + const char *source) { LOG_CHECK(m != nullptr) << source; CHECK(!m->message_id.is_scheduled()); bool is_mention_read = update_message_contains_unread_mention(d, m, false, "read_message_content"); bool is_content_read = update_opened_message_content(m->content.get()); - if (ttl_on_open(d, m, Time::now(), is_local_read)) { + if (ttl_on_open(d, m, Time::now(), is_local_read, read_date)) { is_content_read = true; } @@ -12263,7 +11328,7 @@ bool MessagesManager::has_incoming_notification(DialogId dialog_id, const Messag if (m->is_from_scheduled) { return true; } - return !m->message_id.is_scheduled() && !m->is_outgoing && dialog_id != get_my_dialog_id(); + return !m->message_id.is_scheduled() && !m->is_outgoing && dialog_id != td_->dialog_manager_->get_my_dialog_id(); } int32 MessagesManager::calc_new_unread_count_from_last_unread(Dialog *d, MessageId max_message_id, @@ -12356,7 +11421,7 @@ int32 MessagesManager::calc_new_unread_count(Dialog *d, MessageId max_message_id } void MessagesManager::repair_server_unread_count(DialogId dialog_id, int32 unread_count, const char *source) { - if (td_->auth_manager_->is_bot() || !have_input_peer(dialog_id, AccessRights::Read)) { + if (td_->auth_manager_->is_bot() || !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { return; } if (pending_read_history_timeout_.has_timeout(dialog_id.get())) { @@ -12393,7 +11458,7 @@ void MessagesManager::repair_channel_server_unread_count(Dialog *d) { } LOG(INFO) << "Reload ChannelFull for " << d->dialog_id << " to repair unread message counts"; - get_dialog_info_full(d->dialog_id, Auto(), "repair_channel_server_unread_count"); + td_->dialog_manager_->get_dialog_info_full(d->dialog_id, Auto(), "repair_channel_server_unread_count"); } void MessagesManager::repair_dialog_unread_reaction_count(Dialog *d, Promise &&promise, const char *source) { @@ -12478,15 +11543,19 @@ void MessagesManager::read_history_inbox(Dialog *d, MessageId max_message_id, in LOG(ERROR) << "Have unknown " << unread_count << " unread messages up to " << max_message_id << " in " << dialog_id << " with last_new_message_id = " << d->last_new_message_id << ", last_message_id = " << d->last_message_id - << ", last_database_message_id = " << d->last_database_message_id << " from " << source; + << ", last_database_message_id = " << d->last_database_message_id << ", and " << d->server_unread_count + << " unread messages up to " << d->last_read_inbox_message_id << " from " << source; + unread_count = d->server_unread_count; + } else { + unread_count = 0; } - unread_count = 0; } - LOG_IF(INFO, - d->last_new_message_id.is_valid() && max_message_id > d->last_new_message_id && - (d->notification_info != nullptr && max_message_id > d->notification_info->max_notification_message_id_) && - max_message_id.is_server() && dialog_id.get_type() != DialogType::Channel && !running_get_difference_) + LOG_IF(INFO, d->last_new_message_id.is_valid() && max_message_id > d->last_new_message_id && + (d->notification_info != nullptr && + max_message_id > d->notification_info->max_push_notification_message_id_) && + max_message_id.is_server() && dialog_id.get_type() != DialogType::Channel && + !running_get_difference_) << "Receive read inbox update up to unknown " << max_message_id << " in " << dialog_id << " from " << source << ". Last new is " << d->last_new_message_id << ", unread_count = " << unread_count << ". Possible only for deleted incoming message"; @@ -12496,7 +11565,7 @@ void MessagesManager::read_history_inbox(Dialog *d, MessageId max_message_id, in } if (max_message_id > d->last_new_message_id && dialog_id.get_type() == DialogType::Channel) { - schedule_get_channel_difference(dialog_id, 0, max_message_id, 0.001); + schedule_get_channel_difference(dialog_id, 0, max_message_id, 0.001, "read_history_inbox"); } int32 server_unread_count = calc_new_unread_count(d, max_message_id, MessageType::Server, unread_count); @@ -12505,8 +11574,7 @@ void MessagesManager::read_history_inbox(Dialog *d, MessageId max_message_id, in if (server_unread_count < 0) { server_unread_count = unread_count >= 0 ? unread_count : d->server_unread_count; - if (dialog_id.get_type() != DialogType::SecretChat && have_input_peer(dialog_id, AccessRights::Read) && - need_unread_counter(d->order)) { + if (td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read) && need_unread_counter(d->order)) { d->need_repair_server_unread_count = true; on_dialog_updated(dialog_id, "read_history_inbox"); repair_server_unread_count(dialog_id, server_unread_count, "read_history_inbox"); @@ -12858,7 +11926,7 @@ void MessagesManager::set_dialog_last_read_inbox_message_id(Dialog *d, MessageId << " after updating last read inbox message to " << message_id << " and unread message count to " << server_unread_count << " + " << local_unread_count << " from " << source; - if (d->notification_info != nullptr && d->notification_info->message_notification_group_.group_id.is_valid()) { + if (d->notification_info != nullptr && d->notification_info->message_notification_group_.is_valid()) { auto total_count = get_dialog_pending_notification_count(d, false); if (total_count == 0) { set_dialog_last_notification(d->dialog_id, d->notification_info->message_notification_group_, 0, @@ -12881,12 +11949,12 @@ void MessagesManager::set_dialog_last_read_inbox_message_id(Dialog *d, MessageId total_count = 0; } send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification_group, - d->notification_info->message_notification_group_.group_id, NotificationId(), - d->last_read_inbox_message_id, total_count, Slice(source) == Slice("view_messages"), + d->notification_info->message_notification_group_.get_group_id(), NotificationId(), + d->last_read_inbox_message_id, total_count, Slice(source) == Slice("read_dialog_inbox"), Promise()); } - if (d->notification_info != nullptr && d->notification_info->mention_notification_group_.group_id.is_valid() && + if (d->notification_info != nullptr && d->notification_info->mention_notification_group_.is_valid() && d->notification_info->pinned_message_notification_message_id_.is_valid() && d->notification_info->pinned_message_notification_message_id_ <= d->last_read_inbox_message_id) { // remove pinned message notification when it is read @@ -12980,94 +12048,6 @@ void MessagesManager::set_dialog_max_unavailable_message_id(DialogId dialog_id, } } -void MessagesManager::set_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server, - const char *source) { - if (td_->auth_manager_->is_bot()) { - return; - } - - Dialog *d = get_dialog(dialog_id); - if (d == nullptr) { - return; - } - - if (online_member_count < 0) { - LOG(ERROR) << "Receive online_member_count = " << online_member_count << " in " << dialog_id; - online_member_count = 0; - } - - switch (dialog_id.get_type()) { - case DialogType::Chat: { - auto participant_count = td_->contacts_manager_->get_chat_participant_count(dialog_id.get_chat_id()); - if (online_member_count > participant_count) { - online_member_count = participant_count; - } - break; - } - case DialogType::Channel: { - auto participant_count = td_->contacts_manager_->get_channel_participant_count(dialog_id.get_channel_id()); - if (participant_count != 0 && online_member_count > participant_count) { - online_member_count = participant_count; - } - break; - } - default: - break; - } - - auto &info = dialog_online_member_counts_[dialog_id]; - LOG(INFO) << "Change number of online members from " << info.online_member_count << " to " << online_member_count - << " in " << dialog_id << " from " << source; - bool need_update = d->open_count > 0 && (!info.is_update_sent || info.online_member_count != online_member_count); - info.online_member_count = online_member_count; - info.update_time = Time::now(); - - if (need_update) { - info.is_update_sent = true; - send_update_chat_online_member_count(dialog_id, online_member_count); - } - if (d->open_count > 0) { - if (is_from_server) { - update_dialog_online_member_count_timeout_.set_timeout_in(dialog_id.get(), ONLINE_MEMBER_COUNT_UPDATE_TIME); - } else { - update_dialog_online_member_count_timeout_.add_timeout_in(dialog_id.get(), ONLINE_MEMBER_COUNT_UPDATE_TIME); - } - } -} - -void MessagesManager::on_update_dialog_online_member_count_timeout(DialogId dialog_id) { - if (G()->close_flag()) { - return; - } - - LOG(INFO) << "Expired timeout for number of online members in " << dialog_id; - Dialog *d = get_dialog(dialog_id); - CHECK(d != nullptr); - if (d->open_count == 0) { - send_update_chat_online_member_count(dialog_id, 0); - return; - } - - if (dialog_id.get_type() == DialogType::Channel && !is_broadcast_channel(dialog_id)) { - auto participant_count = td_->contacts_manager_->get_channel_participant_count(dialog_id.get_channel_id()); - auto has_hidden_participants = td_->contacts_manager_->get_channel_effective_has_hidden_participants( - dialog_id.get_channel_id(), "on_update_dialog_online_member_count_timeout"); - if (participant_count == 0 || participant_count >= 195 || has_hidden_participants) { - td_->create_handler()->send(dialog_id); - } else { - td_->contacts_manager_->get_channel_participants(dialog_id.get_channel_id(), - td_api::make_object(), - string(), 0, 200, 200, Auto()); - } - return; - } - if (dialog_id.get_type() == DialogType::Chat) { - // we need actual online status state, so we need to reget chat participants - td_->contacts_manager_->repair_chat_participants(dialog_id.get_chat_id()); - return; - } -} - void MessagesManager::on_update_viewed_messages_timeout(DialogId dialog_id) { if (G()->close_flag()) { return; @@ -13081,24 +12061,32 @@ void MessagesManager::on_update_viewed_messages_timeout(DialogId dialog_id) { } auto it = dialog_viewed_messages_.find(dialog_id); - if (it == dialog_viewed_messages_.end() || !td_->is_online()) { + if (it == dialog_viewed_messages_.end() || !td_->online_manager_->is_online()) { return; } - auto &info = it->second; - CHECK(info != nullptr); + vector viewed_message_ids; + for (const auto &message_it : it->second->message_id_to_view_id) { + viewed_message_ids.push_back(message_it.first); + } + process_viewed_message(d, viewed_message_ids, false); +} + +void MessagesManager::process_viewed_message(Dialog *d, const vector &viewed_message_ids, bool is_first) { + auto dialog_id = d->dialog_id; vector reaction_message_ids; vector views_message_ids; vector extended_media_message_ids; - for (auto &message_it : info->message_id_to_view_id) { - Message *m = get_message_force(d, message_it.first, "on_update_viewed_messages_timeout"); + int32 newest_message_date = 0; + for (auto message_id : viewed_message_ids) { + Message *m = get_message_force(d, message_id, "on_update_viewed_messages_timeout"); CHECK(m != nullptr); CHECK(m->message_id.is_valid()); CHECK(m->message_id.is_server()); if (need_poll_message_reactions(d, m)) { reaction_message_ids.push_back(m->message_id); } - if (m->view_count > 0 && !m->has_get_message_views_query) { + if (!is_first && m->view_count > 0 && !m->has_get_message_views_query) { m->has_get_message_views_query = true; views_message_ids.push_back(m->message_id); } @@ -13106,6 +12094,9 @@ void MessagesManager::on_update_viewed_messages_timeout(DialogId dialog_id) { m->has_get_extended_media_query = true; extended_media_message_ids.push_back(m->message_id); } + if (m->date > newest_message_date) { + newest_message_date = m->date; + } } if (!reaction_message_ids.empty()) { @@ -13117,8 +12108,10 @@ void MessagesManager::on_update_viewed_messages_timeout(DialogId dialog_id) { if (!extended_media_message_ids.empty()) { td_->create_handler()->send(dialog_id, std::move(extended_media_message_ids)); } - - update_viewed_messages_timeout_.add_timeout_in(dialog_id.get(), UPDATE_VIEWED_MESSAGES_PERIOD); + if (td_->online_manager_->is_online()) { + int divisor = 5 - min(max(G()->unix_time() - newest_message_date, 0) / UPDATE_VIEWED_MESSAGES_PERIOD, 4); + update_viewed_messages_timeout_.add_timeout_in(dialog_id.get(), UPDATE_VIEWED_MESSAGES_PERIOD / divisor); + } } void MessagesManager::on_send_update_chat_read_inbox_timeout(DialogId dialog_id) { @@ -13149,7 +12142,7 @@ int32 MessagesManager::get_message_date(const tl_object_ptr MessagesManager::get_message_user_ids(const Message *m) { +vector MessagesManager::get_message_user_ids(const Message *m) const { vector user_ids; if (m->sender_user_id.is_valid()) { user_ids.push_back(m->sender_user_id); @@ -13157,35 +12150,30 @@ vector MessagesManager::get_message_user_ids(const Message *m) { if (m->via_bot_user_id.is_valid()) { user_ids.push_back(m->via_bot_user_id); } - if (m->forward_info != nullptr && m->forward_info->sender_user_id.is_valid()) { - user_ids.push_back(m->forward_info->sender_user_id); - } - if (m->content->get_type() == MessageContentType::ChatAddUsers) { - append(user_ids, get_message_content_added_user_ids(m->content.get())); + if (m->via_business_bot_user_id.is_valid()) { + user_ids.push_back(m->via_business_bot_user_id); } - auto deleted_user_id = get_message_content_deleted_user_id(m->content.get()); - if (deleted_user_id.is_valid()) { - user_ids.push_back(deleted_user_id); + if (m->forward_info != nullptr) { + m->forward_info->add_min_user_ids(user_ids); } - auto contact_user_id = get_message_content_contact_user_id(m->content.get()); - if (contact_user_id.is_valid()) { - user_ids.push_back(contact_user_id); + append(user_ids, get_message_content_min_user_ids(td_, m->content.get())); + if (!m->replied_message_info.is_empty()) { + append(user_ids, m->replied_message_info.get_min_user_ids(td_)); } return user_ids; } -vector MessagesManager::get_message_channel_ids(const Message *m) { +vector MessagesManager::get_message_channel_ids(const Message *m) const { vector channel_ids; if (m->sender_dialog_id.is_valid() && m->sender_dialog_id.get_type() == DialogType::Channel) { channel_ids.push_back(m->sender_dialog_id.get_channel_id()); } - if (m->forward_info != nullptr && m->forward_info->sender_dialog_id.is_valid() && - m->forward_info->sender_dialog_id.get_type() == DialogType::Channel) { - channel_ids.push_back(m->forward_info->sender_dialog_id.get_channel_id()); + if (m->forward_info != nullptr) { + m->forward_info->add_min_channel_ids(channel_ids); } - if (m->forward_info != nullptr && m->forward_info->from_dialog_id.is_valid() && - m->forward_info->from_dialog_id.get_type() == DialogType::Channel) { - channel_ids.push_back(m->forward_info->from_dialog_id.get_channel_id()); + append(channel_ids, get_message_content_min_channel_ids(td_, m->content.get())); + if (!m->replied_message_info.is_empty()) { + append(channel_ids, m->replied_message_info.get_min_channel_ids(td_)); } return channel_ids; } @@ -13206,6 +12194,7 @@ void MessagesManager::ttl_read_history(Dialog *d, bool is_outgoing, MessageId fr void MessagesManager::ttl_read_history_impl(DialogId dialog_id, bool is_outgoing, MessageId from_message_id, MessageId till_message_id, double view_date) { + CHECK(dialog_id.get_type() == DialogType::SecretChat); CHECK(!from_message_id.is_scheduled()); CHECK(!till_message_id.is_scheduled()); @@ -13223,21 +12212,38 @@ void MessagesManager::ttl_read_history_impl(DialogId dialog_id, bool is_outgoing } void MessagesManager::ttl_on_view(const Dialog *d, Message *m, double view_date, double now) { - if (m->ttl > 0 && m->ttl_expires_at == 0 && !m->message_id.is_scheduled() && !m->message_id.is_yet_unsent() && + if (!m->ttl.is_empty() && m->ttl_expires_at == 0 && !m->message_id.is_scheduled() && !m->message_id.is_yet_unsent() && !m->is_failed_to_send && !m->is_content_secret) { - m->ttl_expires_at = m->ttl + view_date; + m->ttl_expires_at = m->ttl.get_input_ttl() + view_date; ttl_register_message(d->dialog_id, m, now); on_message_changed(d, m, true, "ttl_on_view"); } } -bool MessagesManager::ttl_on_open(Dialog *d, Message *m, double now, bool is_local_read) { +bool MessagesManager::ttl_on_open(Dialog *d, Message *m, double now, bool is_local_read, int32 read_date) { CHECK(!m->message_id.is_scheduled()); - if (m->ttl > 0 && m->ttl_expires_at == 0) { - if (!is_local_read && d->dialog_id.get_type() != DialogType::SecretChat) { + if (!m->ttl.is_empty() && m->ttl_expires_at == 0) { + int32 passed_after_read_time = 0; + auto can_destroy_immediately = [&] { + if (m->ttl.is_immediate()) { + return true; + } + if (is_local_read) { + return false; + } + if (read_date <= 0) { + return d->dialog_id.get_type() != DialogType::SecretChat; + } + passed_after_read_time = max(G()->unix_time() - read_date, 0); + if (m->ttl.get_input_ttl() <= passed_after_read_time) { + return true; + } + return false; + }(); + if (can_destroy_immediately) { on_message_ttl_expired(d, m); } else { - m->ttl_expires_at = m->ttl + now; + m->ttl_expires_at = m->ttl.get_input_ttl() + now - passed_after_read_time; ttl_register_message(d->dialog_id, m, now); } return true; @@ -13280,7 +12286,7 @@ void MessagesManager::ttl_unregister_message(DialogId dialog_id, const Message * auto it = ttl_nodes_.find(TtlNode(dialog_id, m->message_id, false)); - // expect m->ttl == 0, but m->ttl_expires_at > 0 from binlog + // expect m->ttl.is_empty(), but m->ttl_expires_at > 0 from binlog CHECK(it != ttl_nodes_.end()); auto *heap_node = it->as_heap_node(); @@ -13313,14 +12319,15 @@ void MessagesManager::ttl_loop(double now) { FlatHashMap, DialogIdHash> to_delete; while (!ttl_heap_.empty() && ttl_heap_.top_key() < now) { TtlNode *ttl_node = TtlNode::from_heap_node(ttl_heap_.pop()); - auto full_message_id = ttl_node->full_message_id_; - auto dialog_id = full_message_id.get_dialog_id(); + auto message_full_id = ttl_node->message_full_id_; + auto dialog_id = message_full_id.get_dialog_id(); + CHECK(dialog_id.is_valid()); if (dialog_id.get_type() == DialogType::SecretChat || ttl_node->by_ttl_period_) { - to_delete[dialog_id].push_back(full_message_id.get_message_id()); + to_delete[dialog_id].push_back(message_full_id.get_message_id()); } else { auto d = get_dialog(dialog_id); CHECK(d != nullptr); - auto m = get_message(d, full_message_id.get_message_id()); + auto m = get_message(d, message_full_id.get_message_id()); CHECK(m != nullptr); on_message_ttl_expired(d, m); on_message_changed(d, m, true, "ttl_loop"); @@ -13346,27 +12353,27 @@ void MessagesManager::ttl_update_timeout(double now) { void MessagesManager::on_message_ttl_expired(Dialog *d, Message *m) { CHECK(d != nullptr); CHECK(m != nullptr); - CHECK(m->ttl > 0); + CHECK(m->ttl.is_valid()); CHECK(d->dialog_id.get_type() != DialogType::SecretChat); ttl_unregister_message(d->dialog_id, m, "on_message_ttl_expired"); unregister_message_content(td_, m->content.get(), {d->dialog_id, m->message_id}, "on_message_ttl_expired"); remove_message_file_sources(d->dialog_id, m); - on_message_ttl_expired_impl(d, m); + on_message_ttl_expired_impl(d, m, true); register_message_content(td_, m->content.get(), {d->dialog_id, m->message_id}, "on_message_ttl_expired"); send_update_message_content(d, m, true, "on_message_ttl_expired"); // the caller must call on_message_changed } -void MessagesManager::on_message_ttl_expired_impl(Dialog *d, Message *m) { +void MessagesManager::on_message_ttl_expired_impl(Dialog *d, Message *m, bool is_message_in_dialog) { CHECK(d != nullptr); CHECK(m != nullptr); CHECK(m->message_id.is_valid()); CHECK(!m->message_id.is_yet_unsent()); - CHECK(m->ttl > 0); + CHECK(m->ttl.is_valid()); CHECK(d->dialog_id.get_type() != DialogType::SecretChat); delete_message_files(d->dialog_id, m); update_expired_message_content(m->content); - m->ttl = 0; + m->ttl = {}; m->ttl_expires_at = 0; if (m->reply_markup != nullptr) { if (m->reply_markup->type != ReplyMarkup::Type::InlineKeyboard) { @@ -13380,15 +12387,12 @@ void MessagesManager::on_message_ttl_expired_impl(Dialog *d, Message *m) { remove_message_notification_id(d, m, true, true); update_message_contains_unread_mention(d, m, false, "on_message_ttl_expired_impl"); remove_message_unread_reactions(d, m, "on_message_ttl_expired_impl"); - unregister_message_reply(d->dialog_id, m); + set_message_reply(d, m, MessageInputReplyTo(), is_message_in_dialog); m->noforwards = false; m->contains_mention = false; - m->reply_to_message_id = MessageId(); - m->reply_to_random_id = 0; - m->max_reply_media_timestamp = -1; - m->reply_in_dialog_id = DialogId(); m->linked_top_thread_message_id = MessageId(); m->is_content_secret = false; + m->invert_media = false; } void MessagesManager::loop() { @@ -13412,26 +12416,26 @@ void MessagesManager::hangup() { if (!G()->use_message_database()) { while (!being_uploaded_files_.empty()) { auto it = being_uploaded_files_.begin(); - auto full_message_id = it->second.first; + auto message_full_id = it->second.message_full_id; being_uploaded_files_.erase(it); - if (full_message_id.get_message_id().is_yet_unsent()) { - fail_send_message(full_message_id, Global::request_aborted_error()); + if (message_full_id.get_message_id().is_yet_unsent()) { + fail_send_message(message_full_id, Global::request_aborted_error()); } } while (!being_uploaded_thumbnails_.empty()) { auto it = being_uploaded_thumbnails_.begin(); - auto full_message_id = it->second.full_message_id; + auto message_full_id = it->second.message_full_id; being_uploaded_thumbnails_.erase(it); - if (full_message_id.get_message_id().is_yet_unsent()) { - fail_send_message(full_message_id, Global::request_aborted_error()); + if (message_full_id.get_message_id().is_yet_unsent()) { + fail_send_message(message_full_id, Global::request_aborted_error()); } } while (!being_loaded_secret_thumbnails_.empty()) { auto it = being_loaded_secret_thumbnails_.begin(); - auto full_message_id = it->second.full_message_id; + auto message_full_id = it->second.message_full_id; being_loaded_secret_thumbnails_.erase(it); - if (full_message_id.get_message_id().is_yet_unsent()) { - fail_send_message(full_message_id, Global::request_aborted_error()); + if (message_full_id.get_message_id().is_yet_unsent()) { + fail_send_message(message_full_id, Global::request_aborted_error()); } } while (!yet_unsent_media_queues_.empty()) { @@ -13448,11 +12452,23 @@ void MessagesManager::hangup() { while (!being_sent_messages_.empty()) { on_send_message_fail(being_sent_messages_.begin()->first, Global::request_aborted_error()); } - if (!update_message_ids_.empty()) { - LOG(ERROR) << "Have " << update_message_ids_.size() << " awaited sent messages"; + while (!update_message_ids_.empty()) { + auto it = update_message_ids_.begin(); + auto message_full_id = MessageFullId(it->first.get_dialog_id(), it->second); + update_message_ids_.erase(it); + + // the message was sent successfully, but can't be added yet + fail_send_message(message_full_id, Global::request_aborted_error()); } - if (!update_scheduled_message_ids_.empty()) { - LOG(ERROR) << "Have " << update_scheduled_message_ids_.size() << " awaited sent scheduled messages"; + while (!update_scheduled_message_ids_.empty()) { + auto it = update_scheduled_message_ids_.begin(); + auto dialog_id = it->first; + auto message_ids = std::move(it->second); + update_scheduled_message_ids_.erase(it); + for (auto &message_id_it : message_ids) { + // the message was sent successfully, but can't be added yet + fail_send_message({dialog_id, message_id_it.second}, Global::request_aborted_error()); + } } } @@ -13469,6 +12485,7 @@ void MessagesManager::hangup() { fail_promise_map(load_scheduled_messages_from_database_queries_); fail_promise_map(run_after_get_channel_difference_); fail_promise_map(search_public_dialogs_queries_); + fail_promise_map(get_history_queries_); while (!pending_channel_on_get_dialogs_.empty()) { auto it = pending_channel_on_get_dialogs_.begin(); auto promise = std::move(it->second.promise); @@ -13489,13 +12506,15 @@ void MessagesManager::start_up() { init(); } -void MessagesManager::create_folders() { +void MessagesManager::create_folders(int source) { LOG(INFO) << "Create folders"; + create_folders_source_ = source; dialog_folders_[FolderId::main()].folder_id = FolderId::main(); dialog_folders_[FolderId::archive()].folder_id = FolderId::archive(); add_dialog_list(DialogListId(FolderId::main())); add_dialog_list(DialogListId(FolderId::archive())); + create_folders_source_ = source + 1; } void MessagesManager::init() { @@ -13505,14 +12524,14 @@ void MessagesManager::init() { is_inited_ = true; td_->notification_settings_manager_->init(); // load scope notification settings - init_stickers_manager(td_); // load available reactions + td_->reaction_manager_->init(); // load active reactions start_time_ = Time::now(); last_channel_pts_jump_warning_time_ = start_time_ - 3600; bool was_authorized_user = td_->auth_manager_->was_authorized() && !td_->auth_manager_->is_bot(); if (was_authorized_user) { - create_folders(); // ensure that Main and Archive dialog lists are created + create_folders(10); // ensure that Main and Archive dialog lists are created } authorization_date_ = td_->option_manager_->get_option_integer("authorization_date"); @@ -13594,8 +12613,7 @@ void MessagesManager::init() { } return dialog_id; }); - if (std::any_of(r_dialog_ids.begin(), r_dialog_ids.end(), - [](auto &r_dialog_id) { return r_dialog_id.is_error(); })) { + if (any_of(r_dialog_ids, [](const auto &r_dialog_id) { return r_dialog_id.is_error(); })) { LOG(ERROR) << "Can't parse " << it.second; reload_pinned_dialogs(DialogListId(folder_id), Auto()); } else { @@ -13658,8 +12676,7 @@ void MessagesManager::init() { } auto counts = transform(full_split(Slice(it.second)), [](Slice str) { return to_integer_safe(str); }); - if ((counts.size() != 4 && counts.size() != 6) || - std::any_of(counts.begin(), counts.end(), [](auto &c) { return c.is_error(); })) { + if ((counts.size() != 4 && counts.size() != 6) || any_of(counts, [](const auto &c) { return c.is_error(); })) { LOG(ERROR) << "Can't parse " << it.second; } else { DialogListId dialog_list_id(r_dialog_list_id.ok()); @@ -13686,7 +12703,9 @@ void MessagesManager::init() { } } } - } else { + + load_active_live_location_messages(Promise()); + } else if (!td_->auth_manager_->is_bot()) { G()->td_db()->get_binlog_pmc()->erase_by_prefix("pinned_dialog_ids"); G()->td_db()->get_binlog_pmc()->erase_by_prefix("last_server_dialog_date"); G()->td_db()->get_binlog_pmc()->erase_by_prefix("unread_message_count"); @@ -13735,7 +12754,7 @@ void MessagesManager::on_authorization_success() { return; } - create_folders(); + create_folders(20); } void MessagesManager::ttl_db_loop() { @@ -13794,23 +12813,22 @@ void MessagesManager::on_send_secret_message_error(int64 random_id, Status error auto it = being_sent_messages_.find(random_id); if (it != being_sent_messages_.end()) { - auto full_message_id = it->second; - auto *m = get_message(full_message_id); + auto message_full_id = it->second; + auto *m = get_message(message_full_id); if (m != nullptr) { auto file_id = get_message_content_upload_file_id(m->content.get()); if (file_id.is_valid()) { if (G()->close_flag() && G()->use_message_database()) { - // do not send error, message will be re-sent + // do not send error, message will be re-sent after restart return; } - if (begins_with(error.message(), "FILE_PART_") && ends_with(error.message(), "_MISSING")) { - on_send_message_file_part_missing(random_id, to_integer(error.message().substr(10))); + auto bad_parts = FileManager::get_missing_file_parts(error); + if (!bad_parts.empty()) { + on_send_message_file_parts_missing(random_id, std::move(bad_parts)); return; } - if (error.code() != 429 && error.code() < 500 && !G()->close_flag()) { - td_->file_manager_->delete_partial_remote_location(file_id); - } + td_->file_manager_->delete_partial_remote_location_if_needed(file_id, error); } } } @@ -13937,9 +12955,9 @@ void MessagesManager::read_secret_chat_outbox(SecretChatId secret_chat_id, int32 } if (read_date > 0) { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(secret_chat_id); + auto user_id = td_->user_manager_->get_secret_chat_user_id(secret_chat_id); if (user_id.is_valid()) { - td_->contacts_manager_->on_update_user_local_was_online(user_id, read_date); + td_->user_manager_->on_update_user_local_was_online(user_id, read_date); } } @@ -13989,7 +13007,7 @@ void MessagesManager::open_secret_message(SecretChatId secret_chat_id, int64 ran return; } - read_message_content(d, m, false, "open_secret_message"); + read_message_content(d, m, false, 0, "open_secret_message"); } void MessagesManager::on_update_secret_chat_state(SecretChatId secret_chat_id, SecretChatState state) { @@ -14000,15 +13018,13 @@ void MessagesManager::on_update_secret_chat_state(SecretChatId secret_chat_id, S if (d->notification_info->new_secret_chat_notification_id_.is_valid()) { remove_new_secret_chat_notification(d, true); } - if (d->notification_info->message_notification_group_.group_id.is_valid() && + if (d->notification_info->message_notification_group_.is_valid() && get_dialog_pending_notification_count(d, false) == 0 && - !d->notification_info->message_notification_group_.last_notification_id.is_valid()) { - CHECK(d->notification_info->message_notification_group_.last_notification_date == 0); - d->notification_info->message_notification_group_.try_reuse = true; - d->notification_info->message_notification_group_.is_changed = true; + !d->notification_info->message_notification_group_.get_last_notification_id().is_valid()) { + d->notification_info->message_notification_group_.try_reuse(); on_dialog_updated(d->dialog_id, "on_update_secret_chat_state"); } - CHECK(!d->notification_info->mention_notification_group_.group_id + CHECK(!d->notification_info->mention_notification_group_ .is_valid()); // there can't be unread mentions in secret chats } } @@ -14039,10 +13055,13 @@ void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId message_info.sender_user_id = user_id; message_info.date = date; message_info.random_id = message->random_id_; - message_info.ttl = message->ttl_; + message_info.ttl = MessageSelfDestructType(message->ttl_, false); + message_info.has_unread_content = true; + message_info.is_silent = message->silent_; + message_info.media_album_id = message->grouped_id_; Dialog *d = get_dialog_force(message_info.dialog_id, "on_get_secret_message"); - if (d == nullptr && have_dialog_info_force(message_info.dialog_id)) { + if (d == nullptr && td_->dialog_manager_->have_dialog_info_force(message_info.dialog_id, "on_get_secret_message")) { force_create_dialog(message_info.dialog_id, "on_get_secret_message", true, true); d = get_dialog(message_info.dialog_id); } @@ -14057,22 +13076,18 @@ void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId pending_secret_message->load_data_multipromise.add_promise(Auto()); auto lock_promise = pending_secret_message->load_data_multipromise.get_promise(); - int32 flags = MESSAGE_FLAG_HAS_UNREAD_CONTENT | MESSAGE_FLAG_HAS_FROM_ID; if ((message->flags_ & secret_api::decryptedMessage::REPLY_TO_RANDOM_ID_MASK) != 0) { - message_info.reply_header.reply_to_message_id = - get_message_id_by_random_id(d, message->reply_to_random_id_, "on_get_secret_message"); - if (!message_info.reply_header.reply_to_message_id.is_valid()) { + auto reply_to_message_id = get_message_id_by_random_id(d, message->reply_to_random_id_, "on_get_secret_message"); + if (!reply_to_message_id.is_valid()) { auto dialog_it = pending_secret_message_ids_.find(message_info.dialog_id); if (dialog_it != pending_secret_message_ids_.end()) { auto message_it = dialog_it->second.find(message->reply_to_random_id_); if (message_it != dialog_it->second.end()) { - message_info.reply_header.reply_to_message_id = message_it->second; + reply_to_message_id = message_it->second; } } } - } - if ((message->flags_ & secret_api::decryptedMessage::SILENT_MASK) != 0) { - flags |= MESSAGE_FLAG_IS_SILENT; + message_info.reply_header.replied_message_info_ = RepliedMessageInfo::legacy(reply_to_message_id); } if (!clean_input_string(message->via_bot_name_)) { @@ -14086,17 +13101,13 @@ void MessagesManager::on_get_secret_message(SecretChatId secret_chat_id, UserId send_closure(actor_id, &MessagesManager::on_resolve_secret_chat_message_via_bot_username, via_bot_username, message_info_ptr, std::move(promise)); }); - search_public_dialog(message->via_bot_name_, false, std::move(request_promise)); - } - if ((message->flags_ & secret_api::decryptedMessage::GROUPED_ID_MASK) != 0 && message->grouped_id_ != 0) { - message_info.media_album_id = message->grouped_id_; + td_->dialog_manager_->search_public_dialog(message->via_bot_name_, false, std::move(request_promise)); } - message_info.flags = flags; message_info.content = get_secret_message_content( td_, std::move(message->message_), std::move(file), std::move(message->media_), std::move(message->entities_), message_info.dialog_id, pending_secret_message->load_data_multipromise, - td_->contacts_manager_->is_user_premium(user_id)); + td_->user_manager_->is_user_premium(user_id)); add_secret_message(std::move(pending_secret_message), std::move(lock_promise)); } @@ -14105,12 +13116,11 @@ void MessagesManager::on_resolve_secret_chat_message_via_bot_username(const stri MessageInfo *message_info_ptr, Promise &&promise) { if (!G()->close_flag()) { - auto dialog_id = resolve_dialog_username(via_bot_username); + auto dialog_id = td_->dialog_manager_->get_resolved_dialog_by_username(via_bot_username); if (dialog_id.is_valid() && dialog_id.get_type() == DialogType::User) { auto user_id = dialog_id.get_user_id(); - auto r_bot_data = td_->contacts_manager_->get_bot_data(user_id); + auto r_bot_data = td_->user_manager_->get_bot_data(user_id); if (r_bot_data.is_ok() && r_bot_data.ok().is_inline) { - message_info_ptr->flags |= MESSAGE_FLAG_IS_SENT_VIA_BOT; message_info_ptr->via_bot_user_id = user_id; } } @@ -14134,11 +13144,11 @@ void MessagesManager::on_secret_chat_screenshot_taken(SecretChatId secret_chat_i message_info.sender_user_id = user_id; message_info.date = date; message_info.random_id = random_id; - message_info.flags = MESSAGE_FLAG_HAS_FROM_ID; message_info.content = create_screenshot_taken_message_content(); Dialog *d = get_dialog_force(message_info.dialog_id, "on_secret_chat_screenshot_taken"); - if (d == nullptr && have_dialog_info_force(message_info.dialog_id)) { + if (d == nullptr && + td_->dialog_manager_->have_dialog_info_force(message_info.dialog_id, "on_secret_chat_screenshot_taken")) { force_create_dialog(message_info.dialog_id, "on_get_secret_message", true, true); d = get_dialog(message_info.dialog_id); } @@ -14172,11 +13182,11 @@ void MessagesManager::on_secret_chat_ttl_changed(SecretChatId secret_chat_id, Us message_info.sender_user_id = user_id; message_info.date = date; message_info.random_id = random_id; - message_info.flags = MESSAGE_FLAG_HAS_FROM_ID; message_info.content = create_chat_set_ttl_message_content(ttl, UserId()); Dialog *d = get_dialog_force(message_info.dialog_id, "on_secret_chat_ttl_changed"); - if (d == nullptr && have_dialog_info_force(message_info.dialog_id)) { + if (d == nullptr && + td_->dialog_manager_->have_dialog_info_force(message_info.dialog_id, "on_secret_chat_ttl_changed")) { force_create_dialog(message_info.dialog_id, "on_get_secret_message", true, true); d = get_dialog(message_info.dialog_id); } @@ -14244,7 +13254,7 @@ void MessagesManager::finish_add_secret_message(unique_ptr << " received earlier with " << message_id << " and random_id " << random_id; } } else { - if (!td_->contacts_manager_->is_user_premium(pending_secret_message->message_info.sender_user_id)) { + if (!td_->user_manager_->is_user_premium(pending_secret_message->message_info.sender_user_id)) { auto message_text = get_message_content_text_mutable(pending_secret_message->message_info.content.get()); if (message_text != nullptr) { remove_premium_custom_emoji_entities(td_, message_text->entities, true); @@ -14268,10 +13278,12 @@ void MessagesManager::finish_add_secret_message(unique_ptr } MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( - tl_object_ptr message_ptr, bool is_scheduled, const char *source) const { + Td *td, tl_object_ptr message_ptr, bool is_scheduled, bool is_business_message, + const char *source) { LOG(DEBUG) << "Receive from " << source << " " << to_string(message_ptr); LOG_CHECK(message_ptr != nullptr) << source; + auto is_bot = td->auth_manager_->is_bot(); MessageInfo message_info; message_info.message_id = MessageId::get_message_id(message_ptr, is_scheduled); switch (message_ptr->get_id()) { @@ -14280,6 +13292,11 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( break; case telegram_api::message::ID: { auto message = move_tl_object_as(message_ptr); + if (message->quick_reply_shortcut_id_ != 0) { + LOG(ERROR) << "Receive shortcut " << message->quick_reply_shortcut_id_ << " from " << source; + message_info.message_id = MessageId(); + break; + } message_info.dialog_id = DialogId(message->peer_id_); if (message->from_id_ != nullptr) { @@ -14289,57 +13306,72 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( } message_info.date = message->date_; message_info.forward_header = std::move(message->fwd_from_); - bool can_have_thread = - message_info.dialog_id.get_type() == DialogType::Channel && !is_broadcast_channel(message_info.dialog_id); - message_info.reply_header = MessageReplyHeader(std::move(message->reply_to_), message_info.dialog_id, + bool can_have_thread = message_info.dialog_id.get_type() == DialogType::Channel && + !td->dialog_manager_->is_broadcast_channel(message_info.dialog_id); + message_info.reply_header = MessageReplyHeader(td, std::move(message->reply_to_), message_info.dialog_id, message_info.message_id, message_info.date, can_have_thread); - if (message->flags_ & MESSAGE_FLAG_IS_SENT_VIA_BOT) { + if (message->flags_ & telegram_api::message::VIA_BOT_ID_MASK) { message_info.via_bot_user_id = UserId(message->via_bot_id_); if (!message_info.via_bot_user_id.is_valid()) { LOG(ERROR) << "Receive invalid " << message_info.via_bot_user_id << " from " << source; message_info.via_bot_user_id = UserId(); } } - if (message->flags_ & MESSAGE_FLAG_HAS_INTERACTION_INFO) { - message_info.view_count = message->views_; - message_info.forward_count = message->forwards_; - } - if (message->flags_ & MESSAGE_FLAG_HAS_REPLY_INFO) { - message_info.reply_info = std::move(message->replies_); - } - if (message->flags_ & MESSAGE_FLAG_HAS_REACTIONS) { - message_info.reactions = std::move(message->reactions_); - } - if (message->flags_ & MESSAGE_FLAG_HAS_EDIT_DATE) { - message_info.edit_date = message->edit_date_; - } - if (message->flags_ & MESSAGE_FLAG_HAS_MEDIA_ALBUM_ID) { - message_info.media_album_id = message->grouped_id_; - } - if (message->flags_ & MESSAGE_FLAG_HAS_TTL_PERIOD) { - message_info.ttl_period = message->ttl_period_; - } - message_info.flags = message->flags_; - bool is_content_read = (message->flags_ & MESSAGE_FLAG_HAS_UNREAD_CONTENT) == 0; - if (is_message_auto_read(message_info.dialog_id, (message->flags_ & MESSAGE_FLAG_IS_OUT) != 0)) { - is_content_read = true; - } - if (is_scheduled) { - is_content_read = false; + if (message->flags2_ & telegram_api::message::VIA_BUSINESS_BOT_ID_MASK) { + message_info.via_business_bot_user_id = UserId(message->via_business_bot_id_); + if (!message_info.via_business_bot_user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << message_info.via_business_bot_user_id << " from " << source; + message_info.via_business_bot_user_id = UserId(); + } + } + message_info.view_count = message->views_; + message_info.forward_count = message->forwards_; + message_info.reply_info = std::move(message->replies_); + message_info.reactions = std::move(message->reactions_); + message_info.fact_check = std::move(message->factcheck_); + message_info.edit_date = message->edit_date_; + message_info.media_album_id = message->grouped_id_; + message_info.ttl_period = message->ttl_period_; + message_info.is_outgoing = message->out_; + message_info.is_silent = message->silent_; + message_info.is_channel_post = message->post_; + message_info.is_legacy = message->legacy_; + message_info.hide_edit_date = message->edit_hide_; + message_info.is_from_scheduled = message->from_scheduled_; + message_info.is_from_offline = message->offline_; + message_info.is_pinned = message->pinned_; + message_info.noforwards = message->noforwards_; + message_info.has_mention = message->mentioned_; + message_info.has_unread_content = message->media_unread_; + message_info.invert_media = message->invert_media_; + message_info.effect_id = MessageEffectId(message->effect_); + + bool is_content_read = true; + if (!is_bot) { + if (is_scheduled) { + is_content_read = false; + } else if (td->messages_manager_->is_message_auto_read(message_info.dialog_id, message_info.is_outgoing)) { + is_content_read = true; + } else { + is_content_read = !message_info.has_unread_content; + } } - auto new_source = PSTRING() << FullMessageId(message_info.dialog_id, message_info.message_id) << " sent by " + auto new_source = PSTRING() << MessageFullId(message_info.dialog_id, message_info.message_id) << " sent by " << message_info.sender_dialog_id << " from " << source; message_info.content = get_message_content( - td_, - get_message_text(td_->contacts_manager_.get(), std::move(message->message_), std::move(message->entities_), - true, td_->auth_manager_->is_bot(), - message_info.forward_header ? message_info.forward_header->date_ : message_info.date, + td, + get_message_text(td->user_manager_.get(), std::move(message->message_), std::move(message->entities_), true, + is_bot, message_info.forward_header ? message_info.forward_header->date_ : message_info.date, message_info.media_album_id != 0, new_source.c_str()), - std::move(message->media_), message_info.dialog_id, is_content_read, message_info.via_bot_user_id, - &message_info.ttl, &message_info.disable_web_page_preview, new_source.c_str()); + std::move(message->media_), message_info.dialog_id, message_info.date, is_content_read, + message_info.via_bot_user_id, &message_info.ttl, &message_info.disable_web_page_preview, new_source.c_str()); message_info.reply_markup = std::move(message->reply_markup_); message_info.restriction_reasons = get_restriction_reasons(std::move(message->restriction_reason_)); message_info.author_signature = std::move(message->post_author_); + message_info.sender_boost_count = message->from_boosts_applied_; + if (!is_bot && message->saved_peer_id_ != nullptr) { + message_info.saved_messages_topic_id = SavedMessagesTopicId(DialogId(message->saved_peer_id_)); + } break; } case telegram_api::messageService::ID: { @@ -14352,19 +13384,25 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( message_info.sender_dialog_id = message_info.dialog_id; } message_info.date = message->date_; - if (message->flags_ & MESSAGE_FLAG_HAS_TTL_PERIOD) { - message_info.ttl_period = message->ttl_period_; - } - message_info.flags = message->flags_; - bool can_have_thread = - message_info.dialog_id.get_type() == DialogType::Channel && !is_broadcast_channel(message_info.dialog_id); - message_info.reply_header = MessageReplyHeader(std::move(message->reply_to_), message_info.dialog_id, + message_info.ttl_period = message->ttl_period_; + message_info.is_outgoing = message->out_; + message_info.is_silent = message->silent_; + message_info.is_channel_post = message->post_; + message_info.is_legacy = message->legacy_; + message_info.has_mention = message->mentioned_; + message_info.has_unread_content = message->media_unread_; + bool can_have_thread = message_info.dialog_id.get_type() == DialogType::Channel && + !td->dialog_manager_->is_broadcast_channel(message_info.dialog_id); + message_info.reply_header = MessageReplyHeader(td, std::move(message->reply_to_), message_info.dialog_id, message_info.message_id, message_info.date, can_have_thread); - message_info.content = get_action_message_content(td_, std::move(message->action_), message_info.dialog_id, - message_info.reply_header.reply_in_dialog_id, - message_info.reply_header.reply_to_message_id); - message_info.reply_header.reply_in_dialog_id = DialogId(); - message_info.reply_header.reply_to_message_id = MessageId(); + message_info.content = + get_action_message_content(td, std::move(message->action_), message_info.dialog_id, message_info.date, + message_info.reply_header.replied_message_info_, is_business_message); + message_info.reply_header.replied_message_info_ = RepliedMessageInfo(); + message_info.reply_header.story_full_id_ = StoryFullId(); + if (!is_bot && message_info.dialog_id == td->dialog_manager_->get_my_dialog_id()) { + message_info.saved_messages_topic_id = SavedMessagesTopicId(message_info.dialog_id); + } break; } default: @@ -14378,8 +13416,8 @@ MessagesManager::MessageInfo MessagesManager::parse_telegram_api_message( return message_info; } -std::pair> MessagesManager::create_message(MessageInfo &&message_info, - bool is_channel_message) { +std::pair> MessagesManager::create_message( + Td *td, MessageInfo &&message_info, bool is_channel_message, bool is_business_message, const char *source) { DialogId dialog_id = message_info.dialog_id; MessageId message_id = message_info.message_id; if ((!message_id.is_valid() && !message_id.is_valid_scheduled()) || !dialog_id.is_valid()) { @@ -14395,6 +13433,7 @@ std::pair> MessagesManager::creat CHECK(message_info.content != nullptr); + auto is_bot = td->auth_manager_->is_bot(); auto dialog_type = dialog_id.get_type(); UserId sender_user_id = message_info.sender_user_id; DialogId sender_dialog_id = message_info.sender_dialog_id; @@ -14403,12 +13442,12 @@ std::pair> MessagesManager::creat LOG(ERROR) << "Receive invalid " << sender_user_id; sender_user_id = UserId(); } - if (!is_broadcast_channel(dialog_id) && td_->auth_manager_->is_bot()) { + if (!td->dialog_manager_->is_broadcast_channel(dialog_id) && is_bot) { if (dialog_id == sender_dialog_id) { - td_->contacts_manager_->add_anonymous_bot_user(); + td->user_manager_->add_anonymous_bot_user(); } else { - td_->contacts_manager_->add_service_notifications_user(); - td_->contacts_manager_->add_channel_bot_user(); + td->user_manager_->add_service_notifications_user(); + td->user_manager_->add_channel_bot_user(); } } } @@ -14425,24 +13464,16 @@ std::pair> MessagesManager::creat is_channel_message = (dialog_type == DialogType::Channel); } - int32 flags = message_info.flags; - bool is_outgoing = (flags & MESSAGE_FLAG_IS_OUT) != 0; - bool is_silent = (flags & MESSAGE_FLAG_IS_SILENT) != 0; - bool is_channel_post = (flags & MESSAGE_FLAG_IS_POST) != 0; - bool is_legacy = (flags & MESSAGE_FLAG_IS_LEGACY) != 0; - bool hide_edit_date = (flags & MESSAGE_FLAG_HIDE_EDIT_DATE) != 0; - bool is_from_scheduled = (flags & MESSAGE_FLAG_IS_FROM_SCHEDULED) != 0; - bool is_pinned = (flags & MESSAGE_FLAG_IS_PINNED) != 0; - bool noforwards = (flags & MESSAGE_FLAG_NOFORWARDS) != 0; - LOG_IF(ERROR, is_channel_message != (dialog_type == DialogType::Channel)) << "Receive wrong is_channel_message for " << message_id << " in " << dialog_id; - if (is_channel_post && !is_broadcast_channel(dialog_id)) { + + bool is_channel_post = message_info.is_channel_post; + if (is_channel_post && !td->dialog_manager_->is_broadcast_channel(dialog_id)) { LOG(ERROR) << "Receive is_channel_post for " << message_id << " in " << dialog_id; is_channel_post = false; } - UserId my_id = td_->contacts_manager_->get_my_id(); + UserId my_id = td->user_manager_->get_my_id(); DialogId my_dialog_id = DialogId(my_id); if (dialog_id == my_dialog_id && (sender_user_id != my_id || sender_dialog_id.is_valid())) { LOG(ERROR) << "Receive " << sender_user_id << "/" << sender_dialog_id << " as a sender of " << message_id @@ -14451,10 +13482,11 @@ std::pair> MessagesManager::creat sender_dialog_id = DialogId(); } + bool is_outgoing = message_info.is_outgoing; bool supposed_to_be_outgoing = sender_user_id == my_id && !(dialog_id == my_dialog_id && !message_id.is_scheduled()); - if (sender_user_id.is_valid() && supposed_to_be_outgoing != is_outgoing) { - LOG(ERROR) << "Receive wrong message out flag: me is " << my_id << ", message is from " << sender_user_id - << ", flags = " << flags << " for " << message_id << " in " << dialog_id; + if (sender_user_id.is_valid() && supposed_to_be_outgoing != is_outgoing && !is_business_message) { + LOG(ERROR) << "Receive wrong out flag for " << message_id << " in " << dialog_id << ": me is " << my_id + << ", but message is from " << sender_user_id; is_outgoing = supposed_to_be_outgoing; /* @@ -14464,7 +13496,7 @@ std::pair> MessagesManager::creat // it is safer to completely ignore the message and re-get it through getChannelDifference Dialog *d = get_dialog(dialog_id); if (d != nullptr) { - schedule_get_channel_difference(dialog_id, 0, message_id, 0.001); + schedule_get_channel_difference(dialog_id, 0, message_id, 0.001, source); return {DialogId(), nullptr}; } } @@ -14477,12 +13509,17 @@ std::pair> MessagesManager::creat date = 1; } - MessageId reply_to_message_id = message_info.reply_header.reply_to_message_id; - DialogId reply_in_dialog_id = message_info.reply_header.reply_in_dialog_id; - MessageId top_thread_message_id = message_info.reply_header.top_thread_message_id; - bool is_topic_message = message_info.reply_header.is_topic_message; - fix_server_reply_to_message_id(dialog_id, message_id, reply_in_dialog_id, reply_to_message_id); - fix_server_reply_to_message_id(dialog_id, message_id, reply_in_dialog_id, top_thread_message_id); + MessageId top_thread_message_id = message_info.reply_header.top_thread_message_id_; + bool is_topic_message = message_info.reply_header.is_topic_message_; + auto reply_to_story_full_id = message_info.reply_header.story_full_id_; + if (reply_to_story_full_id != StoryFullId()) { + auto story_dialog_id = reply_to_story_full_id.get_dialog_id(); + if (story_dialog_id != my_dialog_id && story_dialog_id != dialog_id && + story_dialog_id != DialogId(sender_user_id) && !is_business_message) { + LOG(ERROR) << "Receive reply to " << reply_to_story_full_id << " in " << dialog_id; + reply_to_story_full_id = {}; + } + } UserId via_bot_user_id = message_info.via_bot_user_id; if (!via_bot_user_id.is_valid()) { @@ -14497,13 +13534,16 @@ std::pair> MessagesManager::creat auto content_type = message_info.content->get_type(); if (content_type == MessageContentType::Sticker && - get_message_content_sticker_type(td_, message_info.content.get()) == StickerType::CustomEmoji) { + get_message_content_sticker_type(td, message_info.content.get()) == StickerType::CustomEmoji) { LOG(INFO) << "Replace emoji sticker with an empty message"; - message_info.content = create_text_message_content("Invalid sticker", {}, WebPageId()); + message_info.content = + create_text_message_content("Invalid sticker", {}, WebPageId(), false, false, false, string()); + message_info.invert_media = false; content_type = message_info.content->get_type(); } - if (hide_edit_date && td_->auth_manager_->is_bot()) { + bool hide_edit_date = message_info.hide_edit_date; + if (hide_edit_date && is_bot) { hide_edit_date = false; } if (hide_edit_date && content_type == MessageContentType::LiveLocation) { @@ -14516,24 +13556,30 @@ std::pair> MessagesManager::creat ttl_period = 0; } - int32 ttl = message_info.ttl; - bool is_content_secret = is_secret_message_content(ttl, content_type); // must be calculated before TTL is adjusted - if (ttl < 0 || (message_id.is_scheduled() && ttl != 0)) { - LOG(ERROR) << "Wrong self-destruct time " << ttl << " received in " << message_id << " in " << dialog_id; - ttl = 0; - } else if (ttl > 0) { - ttl = max(ttl, get_message_content_duration(message_info.content.get(), td_) + 1); + auto ttl = message_info.ttl; + bool is_content_secret = ttl.is_secret_message_content(content_type); // must be calculated before TTL is adjusted + if (!ttl.is_empty()) { + if (!ttl.is_valid() || message_id.is_scheduled()) { + LOG(ERROR) << "Wrong " << ttl << " received in " << message_id << " in " << dialog_id; + ttl = {}; + } else { + ttl.ensure_at_least(get_message_content_duration(message_info.content.get(), td) + 1); + } } if (message_id.is_scheduled()) { if (message_info.reply_info != nullptr) { - LOG(ERROR) << "Receive " << message_id << " in " << dialog_id << " with reply info"; + LOG(ERROR) << "Receive " << message_id << " in " << dialog_id << " with " << to_string(message_info.reply_info); message_info.reply_info = nullptr; } if (message_info.reactions != nullptr) { - LOG(ERROR) << "Receive " << message_id << " in " << dialog_id << " with reactions"; + LOG(ERROR) << "Receive " << message_id << " in " << dialog_id << " with " << to_string(message_info.reactions); message_info.reactions = nullptr; } + if (message_info.fact_check != nullptr) { + LOG(ERROR) << "Receive " << message_id << " in " << dialog_id << " with " << to_string(message_info.fact_check); + message_info.fact_check = nullptr; + } } int32 view_count = message_info.view_count; if (view_count < 0) { @@ -14545,8 +13591,9 @@ std::pair> MessagesManager::creat LOG(ERROR) << "Wrong forward_count = " << forward_count << " received in " << message_id << " in " << dialog_id; forward_count = 0; } - MessageReplyInfo reply_info(td_, std::move(message_info.reply_info), td_->auth_manager_->is_bot()); - if (!top_thread_message_id.is_valid() && is_thread_message(dialog_id, message_id, reply_info, content_type)) { + MessageReplyInfo reply_info(td, std::move(message_info.reply_info), is_bot); + if (!top_thread_message_id.is_valid() && + td->messages_manager_->is_thread_message(dialog_id, message_id, reply_info, content_type)) { top_thread_message_id = message_id; is_topic_message = (content_type == MessageContentType::TopicCreate); } @@ -14558,20 +13605,36 @@ std::pair> MessagesManager::creat // just in case is_topic_message = false; } - auto reactions = - MessageReactions::get_message_reactions(td_, std::move(message_info.reactions), td_->auth_manager_->is_bot()); + auto reactions = MessageReactions::get_message_reactions(td, std::move(message_info.reactions), is_bot); if (reactions != nullptr) { - reactions->sort_reactions(active_reaction_pos_); - reactions->fix_chosen_reaction(get_my_dialog_id()); + reactions->sort_reactions(td->messages_manager_->active_reaction_pos_); + reactions->fix_chosen_reaction(); + reactions->fix_my_recent_chooser_dialog_id(my_dialog_id); } + auto fact_check = FactCheck::get_fact_check(td->user_manager_.get(), std::move(message_info.fact_check), is_bot); bool has_forward_info = message_info.forward_header != nullptr; + bool noforwards = message_info.noforwards; + bool is_expired = is_expired_message_content(content_type); + if (is_expired) { + CHECK(ttl.is_empty()); // self-destruct time is ignored/set to 0 if the message has already been expired + message_info.reply_header.replied_message_info_ = {}; + reply_to_story_full_id = StoryFullId(); + noforwards = false; + is_content_secret = false; + message_info.invert_media = false; + } - if (sender_dialog_id.is_valid() && sender_dialog_id != dialog_id && have_dialog_info_force(sender_dialog_id)) { - CHECK(sender_dialog_id.get_type() != DialogType::User); - force_create_dialog(sender_dialog_id, "create_message", true); + bool is_pinned = message_info.is_pinned; + if (is_pinned && message_id.is_scheduled()) { + LOG(ERROR) << "Receive pinned " << message_id << " in " << dialog_id; + is_pinned = false; } + bool has_mention = + message_info.has_mention || (content_type == MessageContentType::PinMessage && + td->option_manager_->get_option_boolean("process_pinned_messages_as_mentions")); + LOG(INFO) << "Receive " << message_id << " in " << dialog_id << " from " << sender_user_id << "/" << sender_dialog_id; auto message = make_unique(); @@ -14584,28 +13647,30 @@ std::pair> MessagesManager::creat message->disable_web_page_preview = message_info.disable_web_page_preview; message->edit_date = edit_date; message->random_id = message_info.random_id; - message->forward_info = get_message_forward_info(std::move(message_info.forward_header), {dialog_id, message_id}); - message->reply_to_message_id = reply_to_message_id; - message->reply_in_dialog_id = reply_in_dialog_id; + message->forward_info = MessageForwardInfo::get_message_forward_info(td, std::move(message_info.forward_header)); + message->replied_message_info = std::move(message_info.reply_header.replied_message_info_); message->top_thread_message_id = top_thread_message_id; message->is_topic_message = is_topic_message; message->via_bot_user_id = via_bot_user_id; + message->via_business_bot_user_id = message_info.via_business_bot_user_id; + message->reply_to_story_full_id = reply_to_story_full_id; message->restriction_reasons = std::move(message_info.restriction_reasons); message->author_signature = std::move(message_info.author_signature); + message->sender_boost_count = message_info.sender_boost_count; + message->saved_messages_topic_id = message_info.saved_messages_topic_id; message->is_outgoing = is_outgoing; message->is_channel_post = is_channel_post; - message->contains_mention = - !is_outgoing && dialog_type != DialogType::User && - ((flags & MESSAGE_FLAG_HAS_MENTION) != 0 || content_type == MessageContentType::PinMessage) && - !td_->auth_manager_->is_bot(); + message->contains_mention = !is_outgoing && dialog_type != DialogType::User && !is_expired && has_mention && !is_bot; message->contains_unread_mention = !message_id.is_scheduled() && message_id.is_server() && message->contains_mention && - (flags & MESSAGE_FLAG_HAS_UNREAD_CONTENT) != 0 && - (dialog_type == DialogType::Chat || (dialog_type == DialogType::Channel && !is_broadcast_channel(dialog_id))); - message->disable_notification = is_silent; + message_info.has_unread_content && + (dialog_type == DialogType::Chat || + (dialog_type == DialogType::Channel && !td->dialog_manager_->is_broadcast_channel(dialog_id))); + message->disable_notification = message_info.is_silent; message->is_content_secret = is_content_secret; message->hide_edit_date = hide_edit_date; - message->is_from_scheduled = is_from_scheduled; + message->is_from_scheduled = message_info.is_from_scheduled; + message->is_from_offline = message_info.is_from_offline; message->is_pinned = is_pinned; message->noforwards = noforwards; message->interaction_info_update_date = G()->unix_time(); @@ -14613,23 +13678,19 @@ std::pair> MessagesManager::creat message->forward_count = forward_count; message->reply_info = std::move(reply_info); message->reactions = std::move(reactions); - message->legacy_layer = (is_legacy ? MTPROTO_LAYER : 0); + message->fact_check = std::move(fact_check); + message->effect_id = message_info.effect_id; + message->legacy_layer = (message_info.is_legacy ? MTPROTO_LAYER : 0); + message->invert_media = message_info.invert_media; message->content = std::move(message_info.content); - message->reply_markup = get_reply_markup(std::move(message_info.reply_markup), td_->auth_manager_->is_bot(), false, + message->reply_markup = get_reply_markup(std::move(message_info.reply_markup), is_bot, false, message->contains_mention || dialog_type == DialogType::User); - - if (content_type == MessageContentType::ExpiredPhoto || content_type == MessageContentType::ExpiredVideo) { - CHECK(message->ttl == 0); // self-destruct time is ignored/set to 0 if the message has already been expired - if (message->reply_markup != nullptr) { - if (message->reply_markup->type != ReplyMarkup::Type::InlineKeyboard) { - message->had_reply_markup = true; - } - message->reply_markup = nullptr; + if (message->reply_markup != nullptr && is_expired) { + // just in case + if (message->reply_markup->type != ReplyMarkup::Type::InlineKeyboard) { + message->had_reply_markup = true; } - message->reply_to_message_id = MessageId(); - message->reply_to_random_id = 0; - message->reply_in_dialog_id = DialogId(); - message->linked_top_thread_message_id = MessageId(); + message->reply_markup = nullptr; } if (message_info.media_album_id != 0) { @@ -14637,8 +13698,8 @@ std::pair> MessagesManager::creat if (content_type != MessageContentType::Unsupported) { LOG(ERROR) << "Receive media group identifier " << message_info.media_album_id << " in " << message_id << " from " << dialog_id << " with content " - << oneline(to_string(get_message_content_object(message->content.get(), td_, dialog_id, - message->date, is_content_secret, false, -1))); + << oneline(to_string( + td->messages_manager_->get_message_message_content_object(dialog_id, message.get()))); } } else { message->media_album_id = message_info.media_album_id; @@ -14649,6 +13710,27 @@ std::pair> MessagesManager::creat message->had_forward_info = true; } + if (dialog_id == my_dialog_id) { + if (!message->saved_messages_topic_id.is_valid()) { + LOG(ERROR) << "Receive no Saved Messages topic for " << message_id << " in " << dialog_id; + message->saved_messages_topic_id = SavedMessagesTopicId(my_dialog_id, message->forward_info.get(), DialogId()); + } + } else { + if (message->saved_messages_topic_id.is_valid()) { + LOG(ERROR) << "Receive Saved Messages " << message_info.saved_messages_topic_id << " for " << message_id << " in " + << dialog_id; + message->saved_messages_topic_id = SavedMessagesTopicId(); + } + } + + Dependencies dependencies; + td->messages_manager_->add_message_dependencies(dependencies, message.get()); + for (auto dependent_dialog_id : dependencies.get_dialog_ids()) { + if (dependent_dialog_id != dialog_id) { + td->dialog_manager_->force_create_dialog(dependent_dialog_id, source, true); + } + } + return {dialog_id, std::move(message)}; } @@ -14664,7 +13746,7 @@ MessageId MessagesManager::find_old_message_id(DialogId dialog_id, MessageId mes } } else { CHECK(message_id.is_server()); - auto it = update_message_ids_.find(FullMessageId(dialog_id, message_id)); + auto it = update_message_ids_.find(MessageFullId(dialog_id, message_id)); if (it != update_message_ids_.end()) { return it->second; } @@ -14684,24 +13766,24 @@ void MessagesManager::delete_update_message_id(DialogId dialog_id, MessageId mes } } else { CHECK(message_id.is_server()); - auto erased_count = update_message_ids_.erase(FullMessageId(dialog_id, message_id)); + auto erased_count = update_message_ids_.erase(MessageFullId(dialog_id, message_id)); CHECK(erased_count > 0); } } -FullMessageId MessagesManager::on_get_message(tl_object_ptr message_ptr, bool from_update, +MessageFullId MessagesManager::on_get_message(tl_object_ptr message_ptr, bool from_update, bool is_channel_message, bool is_scheduled, const char *source) { - return on_get_message(parse_telegram_api_message(std::move(message_ptr), is_scheduled, source), from_update, - is_channel_message, source); + return on_get_message(parse_telegram_api_message(td_, std::move(message_ptr), is_scheduled, false, source), + from_update, is_channel_message, source); } -FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const bool from_update, +MessageFullId MessagesManager::on_get_message(MessageInfo &&message_info, const bool from_update, const bool is_channel_message, const char *source) { DialogId dialog_id; unique_ptr new_message; - std::tie(dialog_id, new_message) = create_message(std::move(message_info), is_channel_message); + std::tie(dialog_id, new_message) = create_message(td_, std::move(message_info), is_channel_message, false, source); if (new_message == nullptr) { - return FullMessageId(); + return MessageFullId(); } MessageId message_id = new_message->message_id; @@ -14713,7 +13795,7 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const MessageId old_message_id = find_old_message_id(dialog_id, message_id); bool is_sent_message = false; if (old_message_id.is_valid() || old_message_id.is_valid_scheduled()) { - LOG(INFO) << "Found temporary " << old_message_id << " for " << FullMessageId{dialog_id, message_id}; + LOG(INFO) << "Found temporary " << old_message_id << " for " << MessageFullId{dialog_id, message_id}; CHECK(d != nullptr); if (!from_update && !message_id.is_scheduled()) { @@ -14721,7 +13803,7 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const if (get_message_force(d, message_id, "receive missed unsent message not from update") != nullptr) { LOG(ERROR) << "New " << old_message_id << "/" << message_id << " in " << dialog_id << " from " << source << " has identifier less than last_new_message_id = " << d->last_new_message_id; - return FullMessageId(); + return MessageFullId(); } // if there is no message yet, then it is likely was missed because of a server bug and is being repaired via // get_message_from_server from after_get_difference @@ -14732,20 +13814,21 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const } else { LOG(INFO) << "Ignore " << old_message_id << "/" << message_id << " received not through update from " << source << ": " << oneline(to_string(get_message_object(dialog_id, new_message.get(), "on_get_message"))); - if (dialog_id.get_type() == DialogType::Channel && have_input_peer(dialog_id, AccessRights::Read)) { - schedule_get_channel_difference(dialog_id, 0, message_id, 0.001); + if (dialog_id.get_type() == DialogType::Channel && + td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { + schedule_get_channel_difference(dialog_id, 0, message_id, 0.001, "on_get_message"); } - return FullMessageId(); + return MessageFullId(); } } delete_update_message_id(dialog_id, message_id); - if (!new_message->is_outgoing && dialog_id != get_my_dialog_id()) { + if (!new_message->is_outgoing && dialog_id != td_->dialog_manager_->get_my_dialog_id()) { // sent message is not from me LOG(ERROR) << "Sent in " << dialog_id << " " << message_id << " is sent by " << new_message->sender_user_id << "/" << new_message->sender_dialog_id; - return FullMessageId(); + return MessageFullId(); } // must be called before delete_message @@ -14756,29 +13839,25 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const delete_message(d, old_message_id, false, &need_update_dialog_pos, "add sent message"); if (old_message == nullptr) { delete_sent_message_on_server(dialog_id, message_id, old_message_id); - being_readded_message_id_ = FullMessageId(); - return FullMessageId(); + being_readded_message_id_ = MessageFullId(); + return MessageFullId(); } old_message_id = old_message->message_id; need_update = false; - if (old_message_id.is_valid() && message_id.is_valid() && message_id < old_message_id && - !d->had_yet_unsent_message_id_overflow) { - LOG(ERROR) << "Sent " << old_message_id << " to " << dialog_id << " as " << message_id; - } - new_message->message_id = old_message_id; update_message(d, old_message.get(), std::move(new_message), false); new_message = std::move(old_message); - if (new_message->reply_to_message_id != MessageId() && new_message->reply_to_message_id.is_yet_unsent()) { - LOG(INFO) << "Drop reply to " << new_message->reply_to_message_id; - new_message->reply_to_message_id = MessageId(); + auto reply_message_full_id = new_message->replied_message_info.get_reply_message_full_id(dialog_id, false); + auto reply_message_id = reply_message_full_id.get_message_id(); + if (reply_message_id.is_valid() && reply_message_id.is_yet_unsent()) { + set_message_reply(d, new_message.get(), MessageInputReplyTo(), false); } new_message->message_id = message_id; - send_update_message_send_succeeded(d, old_message_id, new_message.get()); + send_update_message_send_succeeded(d, old_message_id, new_message.get(), &need_update_dialog_pos); if (!message_id.is_scheduled()) { is_sent_message = true; @@ -14790,7 +13869,7 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const const Message *m = add_message_to_dialog(d, std::move(new_message), false, from_update, &need_update, &need_update_dialog_pos, source); - being_readded_message_id_ = FullMessageId(); + being_readded_message_id_ = MessageFullId(); if (m == nullptr) { if (need_update_dialog_pos) { send_update_chat_last_message(d, "on_get_message"); @@ -14803,14 +13882,7 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const send_update_delete_messages(dialog_id, {message_id.get()}, true); } - return FullMessageId(); - } - - auto pcc_it = pending_created_dialogs_.find(dialog_id); - if (from_update && pcc_it != pending_created_dialogs_.end()) { - pcc_it->second.set_value(Unit()); - - pending_created_dialogs_.erase(pcc_it); + return MessageFullId(); } if (need_update) { @@ -14818,7 +13890,9 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const } if (is_sent_message) { - try_add_active_live_location(dialog_id, m); + if (try_add_active_live_location(dialog_id, m)) { + send_update_active_live_location_messages(); + } // add_message_to_dialog will not update counts, because need_update == false update_message_count_by_index(d, +1, m); @@ -14829,12 +13903,13 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const update_forward_count(dialog_id, m); } - if (dialog_id.get_type() == DialogType::Channel && !have_input_peer(dialog_id, AccessRights::Read)) { + if (dialog_id.get_type() == DialogType::Channel && + !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { auto message = delete_message(d, message_id, false, &need_update_dialog_pos, "get a message in inaccessible chat"); CHECK(message.get() == m); send_update_delete_messages(dialog_id, {m->message_id.get()}, false); // don't need to update chat position - return FullMessageId(); + return MessageFullId(); } if (m->message_id.is_scheduled()) { @@ -14852,7 +13927,22 @@ FullMessageId MessagesManager::on_get_message(MessageInfo &&message_info, const set_dialog_reply_markup(d, message_id); } - return FullMessageId(dialog_id, message_id); + if (from_update) { + auto it = pending_created_dialogs_.find(dialog_id); + if (it != pending_created_dialogs_.end()) { + auto pending_created_dialog = std::move(it->second); + pending_created_dialogs_.erase(it); + + if (pending_created_dialog.chat_promise_) { + pending_created_dialog.chat_promise_.set_value(td_api::make_object( + get_chat_id_object(dialog_id, "on_get_message"), std::move(pending_created_dialog.failed_to_add_members_))); + } else { + pending_created_dialog.channel_promise_.set_value(get_chat_object(d, "on_get_message")); + } + } + } + + return MessageFullId(dialog_id, message_id); } void MessagesManager::set_dialog_last_message_id(Dialog *d, MessageId last_message_id, const char *source, @@ -14889,10 +13979,7 @@ void MessagesManager::set_dialog_last_message_id(Dialog *d, MessageId last_messa d->is_last_message_deleted_locally = false; on_dialog_updated(d->dialog_id, "update_delete_last_message_date"); } - if (d->pending_last_message_date != 0) { - d->pending_last_message_date = 0; - d->pending_last_message_id = MessageId(); - } + d->pending_order = DEFAULT_ORDER; } void MessagesManager::set_dialog_first_database_message_id(Dialog *d, MessageId first_database_message_id, @@ -14930,6 +14017,8 @@ void MessagesManager::remove_dialog_newer_messages(Dialog *d, MessageId from_mes CHECK(!d->last_new_message_id.is_valid()); CHECK(!td_->auth_manager_->is_bot()); + // the function is called to handle channel gaps, and hence must always delete all database messages, + // even first_database_message_id and last_database_message_id are empty delete_all_dialog_messages_from_database(d, MessageId::max(), "remove_dialog_newer_messages"); set_dialog_first_database_message_id(d, MessageId(), "remove_dialog_newer_messages"); set_dialog_last_database_message_id(d, MessageId(), source); @@ -15053,7 +14142,7 @@ void MessagesManager::set_dialog_is_empty(Dialog *d, const char *source) { LOG(INFO) << "Set " << d->dialog_id << " is_empty to true from " << source; CHECK(d->have_full_history); if (!d->is_empty && d->order != DEFAULT_ORDER) { - reload_dialog_info_full(d->dialog_id, "set_dialog_is_empty"); + td_->dialog_manager_->reload_dialog_info_full(d->dialog_id, "set_dialog_is_empty"); } d->is_empty = true; @@ -15094,10 +14183,7 @@ void MessagesManager::set_dialog_is_empty(Dialog *d, const char *source) { on_dialog_updated(d->dialog_id, "set_dialog_is_empty"); } - if (d->pending_last_message_date != 0) { - d->pending_last_message_date = 0; - d->pending_last_message_id = MessageId(); - } + d->pending_order = DEFAULT_ORDER; if (d->last_database_message_id.is_valid()) { set_dialog_first_database_message_id(d, MessageId(), "set_dialog_is_empty"); set_dialog_last_database_message_id(d, MessageId(), "set_dialog_is_empty"); @@ -15161,35 +14247,31 @@ bool MessagesManager::set_dialog_is_pinned(DialogListId dialog_list_id, Dialog * if (!list->are_pinned_dialogs_inited_) { return false; } - bool was_pinned = false; - for (size_t pos = 0; pos < list->pinned_dialogs_.size(); pos++) { - auto &pinned_dialog = list->pinned_dialogs_[pos]; - if (pinned_dialog.get_dialog_id() == d->dialog_id) { - // the dialog was already pinned - if (is_pinned) { - if (pos == 0) { - return false; - } - auto order = get_next_pinned_dialog_order(); - pinned_dialog = DialogDate(order, d->dialog_id); - std::rotate(list->pinned_dialogs_.begin(), list->pinned_dialogs_.begin() + pos, - list->pinned_dialogs_.begin() + pos + 1); - list->pinned_dialog_id_orders_[d->dialog_id] = order; - } else { - list->pinned_dialogs_.erase(list->pinned_dialogs_.begin() + pos); - list->pinned_dialog_id_orders_.erase(d->dialog_id); - } - was_pinned = true; - break; - } - } - if (!was_pinned) { - if (!is_pinned) { + auto dialog_id = d->dialog_id; + auto is_changed_dialog = [dialog_id](const DialogDate &dialog_date) { + return dialog_date.get_dialog_id() == dialog_id; + }; + if (is_pinned) { + if (!list->pinned_dialogs_.empty() && is_changed_dialog(list->pinned_dialogs_[0])) { return false; } auto order = get_next_pinned_dialog_order(); - list->pinned_dialogs_.insert(list->pinned_dialogs_.begin(), {order, d->dialog_id}); - list->pinned_dialog_id_orders_.emplace(d->dialog_id, order); + DialogDate dialog_date(order, dialog_id); + add_to_top_if(list->pinned_dialogs_, list->pinned_dialogs_.size() + 1, dialog_date, is_changed_dialog); + auto it = list->pinned_dialog_id_orders_.find(dialog_id); + if (it != list->pinned_dialog_id_orders_.end()) { + CHECK(list->pinned_dialogs_[0] != dialog_date); + list->pinned_dialogs_[0] = dialog_date; + it->second = order; + } else { + CHECK(list->pinned_dialogs_[0] == dialog_date); + list->pinned_dialog_id_orders_.emplace(dialog_id, order); + } + } else { + if (!td::remove_if(list->pinned_dialogs_, is_changed_dialog)) { + return false; + } + list->pinned_dialog_id_orders_.erase(dialog_id); } LOG(INFO) << "Set " << d->dialog_id << " is pinned in " << dialog_list_id << " to " << is_pinned; @@ -15273,8 +14355,8 @@ void MessagesManager::set_dialog_pinned_message_notification(Dialog *d, MessageI remove_message_notification_id(d, m, true, false, true); on_message_changed(d, m, false, source); } else { - send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_message_id, - notification_info->mention_notification_group_.group_id, old_message_id, false, source); + send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_object_id, + notification_info->mention_notification_group_.get_group_id(), old_message_id, false, source); } } notification_info->pinned_message_notification_message_id_ = message_id; @@ -15290,9 +14372,9 @@ void MessagesManager::remove_scope_pinned_message_notifications(NotificationSett dialogs_.foreach([&](const DialogId &dialog_id, unique_ptr &dialog) { Dialog *d = dialog.get(); if (d->notification_settings.use_default_disable_pinned_message_notifications && d->notification_info != nullptr && - d->notification_info->mention_notification_group_.group_id.is_valid() && + d->notification_info->mention_notification_group_.is_valid() && d->notification_info->pinned_message_notification_message_id_.is_valid() && - get_dialog_notification_setting_scope(dialog_id) == scope) { + td_->dialog_manager_->get_dialog_notification_setting_scope(dialog_id) == scope) { remove_dialog_pinned_message_notification(d, "remove_scope_pinned_message_notifications"); } }); @@ -15304,7 +14386,7 @@ void MessagesManager::on_update_scope_mention_notifications(NotificationSettings dialogs_.foreach([&](const DialogId &dialog_id, unique_ptr &dialog) { Dialog *d = dialog.get(); if (d->notification_settings.use_default_disable_mention_notifications && - get_dialog_notification_setting_scope(dialog_id) == scope) { + td_->dialog_manager_->get_dialog_notification_setting_scope(dialog_id) == scope) { if (!disable_mention_notifications) { update_dialog_mention_notification_count(d); } else { @@ -15315,14 +14397,8 @@ void MessagesManager::on_update_scope_mention_notifications(NotificationSettings } void MessagesManager::remove_dialog_mention_notifications(Dialog *d) { - if (d->notification_info == nullptr) { - return; - } - auto notification_group_id = d->notification_info->mention_notification_group_.group_id; - if (!notification_group_id.is_valid()) { - return; - } - if (d->unread_mention_count == 0) { + if (d->notification_info == nullptr || !d->notification_info->mention_notification_group_.is_valid() || + d->unread_mention_count == 0) { return; } CHECK(!d->being_added_message_id.is_valid()); @@ -15342,15 +14418,19 @@ void MessagesManager::remove_dialog_mention_notifications(Dialog *d) { } } + auto notification_group_id = d->notification_info->mention_notification_group_.get_group_id(); + CHECK(notification_group_id.is_valid()); message_ids = td_->notification_manager_->get_notification_group_message_ids(notification_group_id); VLOG(notifications) << "Found active mention notifications in " << message_ids; for (auto &message_id : message_ids) { CHECK(!message_id.is_scheduled()); if (message_id != d->notification_info->pinned_message_notification_message_id_) { auto m = get_message_force(d, message_id, "remove_dialog_mention_notifications"); - if (m != nullptr && m->notification_id.is_valid() && is_message_notification_active(d, m)) { + if (m != nullptr && m->notification_id.is_valid()) { CHECK(is_from_mention_notification_group(m)); - removed_notification_ids_set.insert(m->notification_id); + if (is_message_notification_active(d, m)) { + removed_notification_ids_set.insert(m->notification_id); + } } } } @@ -15366,20 +14446,20 @@ void MessagesManager::remove_dialog_mention_notifications(Dialog *d) { } } -bool MessagesManager::set_dialog_last_notification(DialogId dialog_id, NotificationGroupInfo &group_info, +void MessagesManager::set_dialog_last_notification(DialogId dialog_id, NotificationGroupInfo &group_info, int32 last_notification_date, NotificationId last_notification_id, const char *source) { - if (group_info.last_notification_date != last_notification_date || - group_info.last_notification_id != last_notification_id) { - VLOG(notifications) << "Set " << group_info.group_id << '/' << dialog_id << " last notification to " - << last_notification_id << " sent at " << last_notification_date << " from " << source; - group_info.last_notification_date = last_notification_date; - group_info.last_notification_id = last_notification_id; - group_info.is_changed = true; + if (group_info.set_last_notification(last_notification_date, last_notification_id, source)) { on_dialog_updated(dialog_id, "set_dialog_last_notification"); - return true; } - return false; +} + +void MessagesManager::set_dialog_last_notification_checked(DialogId dialog_id, NotificationGroupInfo &group_info, + int32 last_notification_date, + NotificationId last_notification_id, const char *source) { + bool is_changed = group_info.set_last_notification(last_notification_date, last_notification_id, source); + CHECK(is_changed); + on_dialog_updated(dialog_id, "set_dialog_last_notification_checked"); } void MessagesManager::on_update_sent_text_message(int64 random_id, @@ -15396,16 +14476,16 @@ void MessagesManager::on_update_sent_text_message(int64 random_id, return; } - auto full_message_id = it->second; - auto dialog_id = full_message_id.get_dialog_id(); + auto message_full_id = it->second; + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog(dialog_id); - auto m = get_message_force(d, full_message_id.get_message_id(), "on_update_sent_text_message"); + auto m = get_message_force(d, message_full_id.get_message_id(), "on_update_sent_text_message"); if (m == nullptr) { // message has already been deleted return; } CHECK(m->message_id.is_yet_unsent()); - full_message_id = FullMessageId(dialog_id, m->message_id); + message_full_id = MessageFullId(dialog_id, m->message_id); if (m->content->get_type() != MessageContentType::Text) { LOG(ERROR) << "Text message content has been already changed to " << m->content->get_type(); @@ -15415,9 +14495,9 @@ void MessagesManager::on_update_sent_text_message(int64 random_id, const FormattedText *old_message_text = get_message_content_text(m->content.get()); CHECK(old_message_text != nullptr); FormattedText new_message_text = get_message_text( - td_->contacts_manager_.get(), old_message_text->text, std::move(entities), true, td_->auth_manager_->is_bot(), - m->forward_info ? m->forward_info->date : m->date, m->media_album_id != 0, "on_update_sent_text_message"); - auto new_content = get_message_content(td_, std::move(new_message_text), std::move(message_media), dialog_id, + td_->user_manager_.get(), old_message_text->text, std::move(entities), true, td_->auth_manager_->is_bot(), + get_message_original_date(m), m->media_album_id != 0, "on_update_sent_text_message"); + auto new_content = get_message_content(td_, std::move(new_message_text), std::move(message_media), dialog_id, m->date, true /*likely ignored*/, UserId() /*likely ignored*/, nullptr /*ignored*/, nullptr, "on_update_sent_text_message"); if (new_content->get_type() != MessageContentType::Text) { @@ -15429,12 +14509,13 @@ void MessagesManager::on_update_sent_text_message(int64 random_id, bool is_content_changed = false; merge_message_contents(td_, m->content.get(), new_content.get(), need_message_changed_warning(m), dialog_id, false, is_content_changed, need_update); + compare_message_contents(td_, m->content.get(), new_content.get(), is_content_changed, need_update); if (is_content_changed || need_update) { - reregister_message_content(td_, m->content.get(), new_content.get(), full_message_id, + reregister_message_content(td_, m->content.get(), new_content.get(), message_full_id, "on_update_sent_text_message"); m->content = std::move(new_content); - m->is_content_secret = is_secret_message_content(m->ttl, MessageContentType::Text); + m->is_content_secret = m->ttl.is_secret_message_content(MessageContentType::Text); if (need_update) { send_update_message_content(d, m, true, "on_update_sent_text_message"); @@ -15443,18 +14524,18 @@ void MessagesManager::on_update_sent_text_message(int64 random_id, } } -void MessagesManager::delete_pending_message_web_page(FullMessageId full_message_id) { - auto dialog_id = full_message_id.get_dialog_id(); +void MessagesManager::delete_pending_message_web_page(MessageFullId message_full_id) { + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - Message *m = get_message(d, full_message_id.get_message_id()); + Message *m = get_message(d, message_full_id.get_message_id()); CHECK(m != nullptr); MessageContent *content = m->content.get(); CHECK(has_message_content_web_page(content)); - unregister_message_content(td_, content, full_message_id, "delete_pending_message_web_page"); + unregister_message_content(td_, content, message_full_id, "delete_pending_message_web_page"); remove_message_content_web_page(content); - register_message_content(td_, content, full_message_id, "delete_pending_message_web_page"); + register_message_content(td_, content, message_full_id, "delete_pending_message_web_page"); // don't need to send an updateMessageContent, because the web page was pending @@ -15521,19 +14602,19 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vector full_message_id_to_dialog_date; - FlatHashMap, FullMessageIdHash> full_message_id_to_message; + FlatHashMap message_full_id_to_dialog_date; + FlatHashMap, MessageFullIdHash> message_full_id_to_message; for (auto &message : messages) { - auto full_message_id = FullMessageId::get_full_message_id(message, false); - if (!full_message_id.get_message_id().is_valid()) { // must not check dialog_id because of messageEmpty + auto message_full_id = MessageFullId::get_message_full_id(message, false); + if (!message_full_id.get_message_id().is_valid()) { // must not check dialog_id because of messageEmpty continue; } if (from_dialog_list) { auto message_date = get_message_date(message); - int64 order = get_dialog_order(full_message_id.get_message_id(), message_date); - full_message_id_to_dialog_date.emplace(full_message_id, DialogDate(order, full_message_id.get_dialog_id())); + int64 order = get_dialog_order(message_full_id.get_message_id(), message_date); + message_full_id_to_dialog_date.emplace(message_full_id, DialogDate(order, message_full_id.get_dialog_id())); } - full_message_id_to_message[full_message_id] = std::move(message); + message_full_id_to_message[message_full_id] = std::move(message); } DialogDate max_dialog_date = MIN_DIALOG_DATE; @@ -15572,12 +14653,12 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vectortop_message_)); if (last_message_id.is_valid()) { - FullMessageId full_message_id(dialog_id, last_message_id); - auto it = full_message_id_to_dialog_date.find(full_message_id); - if (it == full_message_id_to_dialog_date.end() && dialog_id.get_type() != DialogType::Channel) { - it = full_message_id_to_dialog_date.find({DialogId(), last_message_id}); + MessageFullId message_full_id(dialog_id, last_message_id); + auto it = message_full_id_to_dialog_date.find(message_full_id); + if (it == message_full_id_to_dialog_date.end() && dialog_id.get_type() != DialogType::Channel) { + it = message_full_id_to_dialog_date.find({DialogId(), last_message_id}); } - if (it == full_message_id_to_dialog_date.end()) { + if (it == message_full_id_to_dialog_date.end()) { LOG(ERROR) << "Last " << last_message_id << " in " << dialog_id << " not found"; return promise.set_error(Status::Error(500, "Wrong query result returned: last message not found")); } @@ -15633,6 +14714,9 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vectorfolder_id_)); + if (dialog_id.get_type() == DialogType::Channel) { + set_dialog_view_as_messages(d, dialog->view_forum_as_messages_, "on_get_dialogs"); + } on_update_dialog_notify_settings(dialog_id, std::move(dialog->notify_settings_), source); if (!d->notification_settings.is_synchronized && !td_->auth_manager_->is_bot()) { @@ -15669,49 +14753,48 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vectorttl_period_ << " as message auto-delete time in " << dialog_id; dialog->ttl_period_ = 0; } - if (!d->is_is_blocked_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get is_blocked from the server - // TODO add is_blocked to telegram_api::dialog - reload_dialog_info_full(dialog_id, "on_get_dialogs init is_blocked"); - } else if (!d->is_has_bots_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get has_bots from the server - // TODO add has_bots to telegram_api::dialog - reload_dialog_info_full(dialog_id, "on_get_dialogs init has_bots"); - } else if (!d->is_background_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get background from the server - // TODO add background to telegram_api::dialog - reload_dialog_info_full(dialog_id, "on_get_dialogs init background"); - } else if (!d->is_theme_name_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get theme_name from the server - // TODO add theme_name to telegram_api::dialog - reload_dialog_info_full(dialog_id, "on_get_dialogs init theme_name"); - } else if (!d->is_last_pinned_message_id_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get dialog pinned message from the server - get_dialog_pinned_message(dialog_id, Auto()); - } else if (!d->is_available_reactions_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get dialog available reactions from the server - reload_dialog_info_full(dialog_id, "on_get_dialogs init available_reactions"); - } - - need_update_dialog_pos |= update_dialog_draft_message( - d, get_draft_message(td_->contacts_manager_.get(), std::move(dialog->draft_)), true, false); + if (!td_->auth_manager_->is_bot()) { + const char *reload_source = nullptr; + if (!d->is_is_blocked_for_stories_inited) { + reload_source = "on_get_dialogs init is_blocked_for_stories"; + } else if (!d->is_has_bots_inited) { + reload_source = "on_get_dialogs init has_bots"; + } else if (!d->is_background_inited) { + reload_source = "on_get_dialogs init background"; + } else if (!d->is_theme_name_inited) { + reload_source = "on_get_dialogs init theme_name"; + } else if (!d->is_available_reactions_inited) { + reload_source = "on_get_dialogs init available_reactions"; + } else if (!d->is_last_pinned_message_id_inited) { + get_dialog_pinned_message(dialog_id, Auto()); + } + if (reload_source != nullptr) { + // asynchronously get dialog info from the server + // TODO add is_blocked/is_blocked_for_stories/has_bots/background/theme_name/available_reactions + // to telegram_api::dialog + td_->dialog_manager_->reload_dialog_info_full(dialog_id, reload_source); + } + } + + need_update_dialog_pos |= + update_dialog_draft_message(d, get_draft_message(td_, std::move(dialog->draft_)), true, false); if (is_new) { bool has_pts = (dialog->flags_ & DIALOG_FLAG_HAS_PTS) != 0; if (last_message_id.is_valid() && !td_->auth_manager_->is_bot()) { - FullMessageId full_message_id(dialog_id, last_message_id); - auto it = full_message_id_to_message.find(full_message_id); - if (it == full_message_id_to_message.end() && dialog_id.get_type() != DialogType::Channel) { - it = full_message_id_to_message.find({DialogId(), last_message_id}); + MessageFullId message_full_id(dialog_id, last_message_id); + auto it = message_full_id_to_message.find(message_full_id); + if (it == message_full_id_to_message.end() && dialog_id.get_type() != DialogType::Channel) { + it = message_full_id_to_message.find({DialogId(), last_message_id}); } - if (it == full_message_id_to_message.end()) { - LOG(ERROR) << "Last " << full_message_id << " not found"; + if (it == message_full_id_to_message.end()) { + LOG(ERROR) << "Last " << message_full_id << " not found"; } else if (!has_pts || d->pts == 0 || dialog->pts_ <= d->pts || d->is_channel_difference_finished) { - auto last_message = std::move(it->second); - auto added_full_message_id = on_get_message(std::move(last_message), false, has_pts, false, source); + auto added_message_full_id = on_get_message(std::move(it->second), false, has_pts, false, source); + message_full_id_to_message.erase(it); CHECK(d->last_new_message_id == MessageId()); set_dialog_last_new_message_id(d, last_message_id, source); - if (d->last_new_message_id > d->last_message_id && added_full_message_id.get_message_id().is_valid()) { - CHECK(added_full_message_id.get_message_id() == d->last_new_message_id); + if (d->last_new_message_id > d->last_message_id && added_message_full_id.get_message_id().is_valid()) { + CHECK(added_message_full_id.get_message_id() == d->last_new_message_id); set_dialog_last_message_id(d, d->last_new_message_id, source); send_update_chat_last_message(d, source); } @@ -15750,7 +14833,7 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vectorneed_repair_server_unread_count && (d->last_read_inbox_message_id <= read_inbox_max_message_id || !need_unread_counter(d->order) || - !have_input_peer(dialog_id, AccessRights::Read))) { + !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read))) { LOG(INFO) << "Repaired server unread count in " << dialog_id << " from " << d->last_read_inbox_message_id << "/" << d->server_unread_count << " to " << read_inbox_max_message_id << "/" << dialog->unread_count_; d->need_repair_server_unread_count = false; @@ -15842,7 +14925,7 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vectororder == DEFAULT_ORDER) { - get_history_from_the_end_impl(d, false, false, Auto(), "on_get_dialog"); + load_last_dialog_message(d, "on_get_dialog"); } } @@ -15884,47 +14967,12 @@ void MessagesManager::on_get_dialogs(FolderId folder_id, vectorauth_manager_->is_bot()); auto *folder_list = get_dialog_list(DialogListId(folder_id)); CHECK(folder_list != nullptr); - auto pinned_dialog_ids = remove_secret_chat_dialog_ids(get_pinned_dialog_ids(DialogListId(folder_id))); + auto pinned_dialog_ids = DialogId::remove_secret_chat_dialog_ids(get_pinned_dialog_ids(DialogListId(folder_id))); bool are_pinned_dialogs_saved = folder_list->are_pinned_dialogs_inited_; folder_list->are_pinned_dialogs_inited_ = true; if (pinned_dialog_ids != added_dialog_ids) { - LOG(INFO) << "Update pinned chats order from " << format::as_array(pinned_dialog_ids) << " to " - << format::as_array(added_dialog_ids); - FlatHashSet old_pinned_dialog_ids; - for (auto pinned_dialog_id : pinned_dialog_ids) { - old_pinned_dialog_ids.insert(pinned_dialog_id); - } - - std::reverse(pinned_dialog_ids.begin(), pinned_dialog_ids.end()); - std::reverse(added_dialog_ids.begin(), added_dialog_ids.end()); - auto old_it = pinned_dialog_ids.begin(); - for (auto dialog_id : added_dialog_ids) { - old_pinned_dialog_ids.erase(dialog_id); - while (old_it < pinned_dialog_ids.end()) { - if (*old_it == dialog_id) { - break; - } - ++old_it; - } - if (old_it < pinned_dialog_ids.end()) { - // leave dialog where it is - ++old_it; - continue; - } - if (set_dialog_is_pinned(dialog_id, true)) { - are_pinned_dialogs_saved = true; - } - } - for (auto dialog_id : old_pinned_dialog_ids) { - Dialog *d = get_dialog_force(dialog_id, "on_get_dialogs pinned"); - if (d == nullptr) { - LOG(ERROR) << "Failed to find " << dialog_id << " to unpin in " << folder_id; - force_create_dialog(dialog_id, "from_pinned_dialog_list", true); - d = get_dialog_force(dialog_id, "on_get_dialogs pinned 2"); - } - if (d != nullptr && set_dialog_is_pinned(DialogListId(folder_id), d, false)) { - are_pinned_dialogs_saved = true; - } + if (set_folder_pinned_dialogs(folder_id, std::move(pinned_dialog_ids), std::move(added_dialog_ids))) { + are_pinned_dialogs_saved = true; } } else { LOG(INFO) << "Pinned chats are not changed"; @@ -15947,9 +14995,9 @@ bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) cons CHECK(d != nullptr); CHECK(m != nullptr); CHECK(m->message_id.is_valid()); - FullMessageId full_message_id{d->dialog_id, m->message_id}; + MessageFullId message_full_id{d->dialog_id, m->message_id}; if (td_->auth_manager_->is_bot() && !G()->use_message_database()) { - return !m->message_id.is_yet_unsent() && replied_by_yet_unsent_messages_.count(full_message_id) == 0 && + return !m->message_id.is_yet_unsent() && replied_by_yet_unsent_messages_.count(message_full_id) == 0 && m->edited_content == nullptr && m->message_id != d->last_pinned_message_id && m->message_id != d->last_edited_message_id; } @@ -15968,8 +15016,8 @@ bool MessagesManager::can_unload_message(const Dialog *d, const Message *m) cons } } return d->open_count == 0 && m->message_id != d->last_message_id && m->message_id != d->last_database_message_id && - !m->message_id.is_yet_unsent() && active_live_location_full_message_ids_.count(full_message_id) == 0 && - replied_by_yet_unsent_messages_.count(full_message_id) == 0 && m->edited_content == nullptr && + !m->message_id.is_yet_unsent() && active_live_location_message_full_ids_.count(message_full_id) == 0 && + replied_by_yet_unsent_messages_.count(message_full_id) == 0 && m->edited_content == nullptr && m->message_id != d->reply_markup_message_id && m->message_id != d->last_pinned_message_id && m->message_id != d->last_edited_message_id && (m->media_album_id != d->last_media_album_id || m->media_album_id == 0); @@ -15996,7 +15044,9 @@ void MessagesManager::add_random_id_to_message_id_correspondence(Dialog *d, int6 auto it = d->random_id_to_message_id.find(random_id); if (it == d->random_id_to_message_id.end() || it->second.get() < message_id.get()) { LOG(INFO) << "Add correspondence from random_id " << random_id << " to " << message_id << " in " << d->dialog_id; - d->random_id_to_message_id[random_id] = message_id; + if (random_id != 0) { + d->random_id_to_message_id[random_id] = message_id; + } } } @@ -16043,6 +15093,22 @@ void MessagesManager::delete_notification_id_to_message_id_correspondence(Notifi } } +bool MessagesManager::is_notification_info_group_id(const NotificationInfo *notification_info, + NotificationGroupId group_id) { + if (!group_id.is_valid() || notification_info == nullptr) { + return false; + } + return notification_info->message_notification_group_.has_group_id(group_id) || + notification_info->mention_notification_group_.has_group_id(group_id); +} + +bool MessagesManager::is_dialog_notification_group_id(const Dialog *d, NotificationGroupId group_id) { + if (d == nullptr) { + return false; + } + return is_notification_info_group_id(d->notification_info.get(), group_id); +} + void MessagesManager::remove_message_notification_id(Dialog *d, Message *m, bool is_permanent, bool force_update, bool ignore_pinned_message_notification_removal) { CHECK(d != nullptr); @@ -16054,15 +15120,16 @@ void MessagesManager::remove_message_notification_id(Dialog *d, Message *m, bool auto from_mentions = is_from_mention_notification_group(m); auto &group_info = get_notification_group_info(d, m); - if (!group_info.group_id.is_valid()) { + if (!group_info.is_valid()) { return; } bool had_active_notification = is_message_notification_active(d, m); auto notification_id = m->notification_id; - VLOG(notifications) << "Remove " << notification_id << " from " << m->message_id << " in " << group_info.group_id - << '/' << d->dialog_id << " from database, was_active = " << had_active_notification + VLOG(notifications) << "Remove " << notification_id << " from " << m->message_id << " in " + << group_info.get_group_id() << '/' << d->dialog_id + << " from database, was_active = " << had_active_notification << ", is_permanent = " << is_permanent; delete_notification_id_to_message_id_correspondence(d->notification_info.get(), notification_id, m->message_id); m->removed_notification_id = m->notification_id; @@ -16072,15 +15139,15 @@ void MessagesManager::remove_message_notification_id(Dialog *d, Message *m, bool remove_dialog_pinned_message_notification( d, "remove_message_notification_id"); // must be called after notification_id is removed } - if (group_info.last_notification_id == notification_id) { + if (group_info.get_last_notification_id() == notification_id) { // last notification is deleted, need to find new last notification fix_dialog_last_notification_id(d, from_mentions, m->message_id); } if (is_permanent) { if (had_active_notification) { - send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification, group_info.group_id, - notification_id, is_permanent, force_update, Promise(), + send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification, + group_info.get_group_id(), notification_id, is_permanent, force_update, Promise(), "remove_message_notification_id"); } @@ -16097,15 +15164,14 @@ void MessagesManager::remove_new_secret_chat_notification(Dialog *d, bool is_per auto notification_id = d->notification_info->new_secret_chat_notification_id_; CHECK(notification_id.is_valid()); VLOG(notifications) << "Remove " << notification_id << " about new secret " << d->dialog_id << " from " - << d->notification_info->message_notification_group_.group_id; + << d->notification_info->message_notification_group_.get_group_id(); d->notification_info->new_secret_chat_notification_id_ = NotificationId(); - bool is_fixed = set_dialog_last_notification(d->dialog_id, d->notification_info->message_notification_group_, 0, - NotificationId(), "remove_new_secret_chat_notification"); - CHECK(is_fixed); + set_dialog_last_notification_checked(d->dialog_id, d->notification_info->message_notification_group_, 0, + NotificationId(), "remove_new_secret_chat_notification"); if (is_permanent) { - CHECK(d->notification_info->message_notification_group_.group_id.is_valid()); + CHECK(d->notification_info->message_notification_group_.is_valid()); send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification, - d->notification_info->message_notification_group_.group_id, notification_id, true, true, + d->notification_info->message_notification_group_.get_group_id(), notification_id, true, true, Promise(), "remove_new_secret_chat_notification"); } } @@ -16117,18 +15183,18 @@ void MessagesManager::fix_dialog_last_notification_id(Dialog *d, bool from_menti return; } CHECK(!td_->auth_manager_->is_bot()); - auto it = d->ordered_messages.get_const_iterator(message_id); auto &group_info = get_notification_group_info(d, from_mentions); - VLOG(notifications) << "Trying to fix last notification identifier in " << group_info.group_id << " from " - << d->dialog_id << " from " << message_id << "/" << group_info.last_notification_id; + CHECK(group_info.is_valid()); + auto it = d->ordered_messages.get_const_iterator(message_id); + VLOG(notifications) << "Trying to fix last notification identifier in " << group_info.get_group_id() << " from " + << d->dialog_id << " from " << message_id << '/' << group_info.get_last_notification_id(); if (*it != nullptr && ((*it)->get_message_id() == message_id || (*it)->have_next())) { while (*it != nullptr) { const Message *m = get_message(d, (*it)->get_message_id()); if (is_from_mention_notification_group(m) == from_mentions && m->notification_id.is_valid() && is_message_notification_active(d, m) && m->message_id != message_id) { - bool is_fixed = set_dialog_last_notification(d->dialog_id, group_info, m->date, m->notification_id, - "fix_dialog_last_notification_id"); - CHECK(is_fixed); + set_dialog_last_notification(d->dialog_id, group_info, m->date, m->notification_id, + "fix_dialog_last_notification_id"); return; } --it; @@ -16136,10 +15202,10 @@ void MessagesManager::fix_dialog_last_notification_id(Dialog *d, bool from_menti } if (G()->use_message_database()) { get_message_notifications_from_database( - d->dialog_id, group_info.group_id, group_info.last_notification_id, message_id, 1, + d->dialog_id, group_info.get_group_id(), group_info.get_last_notification_id(), message_id, 1, PromiseCreator::lambda( [actor_id = actor_id(this), dialog_id = d->dialog_id, from_mentions, - prev_last_notification_id = group_info.last_notification_id](Result> result) { + prev_last_notification_id = group_info.get_last_notification_id()](Result> result) { send_closure(actor_id, &MessagesManager::do_fix_dialog_last_notification_id, dialog_id, from_mentions, prev_last_notification_id, std::move(result)); })); @@ -16159,9 +15225,12 @@ void MessagesManager::do_fix_dialog_last_notification_id(DialogId dialog_id, boo return; } auto &group_info = get_notification_group_info(d, from_mentions); - VLOG(notifications) << "Receive " << result.ok().size() << " message notifications in " << group_info.group_id << '/' - << dialog_id << " from " << prev_last_notification_id; - if (group_info.last_notification_id != prev_last_notification_id) { + if (!group_info.is_valid()) { + return; + } + VLOG(notifications) << "Receive " << result.ok().size() << " message notifications in " << group_info.get_group_id() + << '/' << dialog_id << " from " << prev_last_notification_id; + if (group_info.get_last_notification_id() != prev_last_notification_id) { // last_notification_id was changed return; } @@ -16176,9 +15245,8 @@ void MessagesManager::do_fix_dialog_last_notification_id(DialogId dialog_id, boo last_notification_id = notifications[0].notification_id; } - bool is_fixed = set_dialog_last_notification(dialog_id, group_info, last_notification_date, last_notification_id, - "do_fix_dialog_last_notification_id"); - CHECK(is_fixed); + set_dialog_last_notification(dialog_id, group_info, last_notification_date, last_notification_id, + "do_fix_dialog_last_notification_id"); } // DO NOT FORGET TO ADD ALL CHANGES OF THIS FUNCTION AS WELL TO delete_all_dialog_messages @@ -16197,7 +15265,7 @@ unique_ptr MessagesManager::do_delete_message(Dialog * return nullptr; } - FullMessageId full_message_id(d->dialog_id, message_id); + MessageFullId message_full_id(d->dialog_id, message_id); const Message *m = get_message(d, message_id); if (m == nullptr) { if (only_from_memory) { @@ -16248,11 +15316,14 @@ unique_ptr MessagesManager::do_delete_message(Dialog * bool need_get_history = false; if (!only_from_memory) { - LOG(INFO) << "Deleting " << full_message_id << " from " << source; + LOG(INFO) << "Deleting " << message_full_id << " from " << source; delete_message_from_database(d, message_id, m, is_permanently_deleted, source); - delete_active_live_location(d->dialog_id, m); + if (delete_active_live_location({d->dialog_id, m->message_id})) { + send_update_active_live_location_messages(); + save_active_live_locations(); + } remove_message_file_sources(d->dialog_id, m); if (message_id == d->last_message_id) { @@ -16283,13 +15354,13 @@ unique_ptr MessagesManager::do_delete_message(Dialog * if (*it != nullptr) { if ((*it)->get_message_id() < d->first_database_message_id && d->dialog_id.get_type() == DialogType::Channel) { - // possible if messages was deleted from database, but not from memory after updateChannelTooLong + // possible if messages were deleted from database, but not from memory after updateChannelTooLong set_dialog_last_database_message_id(d, MessageId(), "do_delete_message 1"); } else { set_dialog_last_database_message_id(d, (*it)->get_message_id(), "do_delete_message 2"); if (d->last_database_message_id < d->first_database_message_id) { LOG(ERROR) << "Last database " << d->last_database_message_id << " became less than first database " - << d->first_database_message_id << " after deletion of " << full_message_id; + << d->first_database_message_id << " after deletion of " << message_full_id; set_dialog_first_database_message_id(d, d->last_database_message_id, "do_delete_message 2"); } } @@ -16345,8 +15416,7 @@ unique_ptr MessagesManager::do_delete_message(Dialog * d->being_deleted_message_id = MessageId(); if (need_get_history) { - send_closure_later(actor_id(this), &MessagesManager::get_history_from_the_end, d->dialog_id, true, false, - Promise()); + send_closure_later(actor_id(this), &MessagesManager::load_last_dialog_message_later, d->dialog_id); } on_message_deleted(d, result.get(), is_permanently_deleted, source); @@ -16405,6 +15475,8 @@ void MessagesManager::on_message_deleted_from_database(Dialog *d, const Message update_message_count_by_index(d, -1, m); update_reply_count_by_message(d, -1, m); + + td_->reaction_manager_->update_saved_messages_tags(m->saved_messages_topic_id, get_chosen_tags(m->reactions), {}); } void MessagesManager::on_message_deleted(Dialog *d, Message *m, bool is_permanently_deleted, const char *source) { @@ -16445,9 +15517,9 @@ void MessagesManager::on_message_deleted(Dialog *d, Message *m, bool is_permanen } break; case DialogType::Channel: - if (m->message_id.is_server()) { - td_->contacts_manager_->unregister_message_users({d->dialog_id, m->message_id}, get_message_user_ids(m)); - td_->contacts_manager_->unregister_message_channels({d->dialog_id, m->message_id}, get_message_channel_ids(m)); + if (m->message_id.is_server() && !td_->auth_manager_->is_bot()) { + td_->user_manager_->unregister_message_users({d->dialog_id, m->message_id}, get_message_user_ids(m)); + td_->chat_manager_->unregister_message_channels({d->dialog_id, m->message_id}, get_message_channel_ids(m)); } break; case DialogType::SecretChat: @@ -16471,6 +15543,10 @@ void MessagesManager::on_message_deleted(Dialog *d, Message *m, bool is_permanen if (m->is_topic_message) { td_->forum_topic_manager_->on_topic_message_count_changed(d->dialog_id, m->top_thread_message_id, -1); } + if (is_permanently_deleted && !td_->auth_manager_->is_bot() && m->saved_messages_topic_id.is_valid()) { + CHECK(d->dialog_id == td_->dialog_manager_->get_my_dialog_id()); + td_->saved_messages_manager_->on_topic_message_deleted(m->saved_messages_topic_id, m->message_id); + } added_message_count_--; } @@ -16519,7 +15595,7 @@ unique_ptr MessagesManager::do_delete_scheduled_messag const Message *m = it->second.get(); CHECK(m->message_id == message_id); - LOG(INFO) << "Deleting " << FullMessageId{d->dialog_id, message_id} << " from " << source; + LOG(INFO) << "Deleting " << MessageFullId{d->dialog_id, message_id} << " from " << source; delete_message_from_database(d, message_id, m, is_permanently_deleted, source); @@ -16559,13 +15635,13 @@ void MessagesManager::load_dialogs(vector dialog_ids, Promisedialog_manager_->have_dialog_info(dialog_id); }); for (auto dialog_id : dialog_ids) { force_create_dialog(dialog_id, "load_dialogs"); @@ -16581,7 +15657,12 @@ bool MessagesManager::load_dialog(DialogId dialog_id, int left_tries, Promiseauth_manager_->is_bot() && dialog_id.get_type() == DialogType::User && + !td_->user_manager_->have_user(dialog_id.get_user_id())) { + need_load = true; + } + if (need_load) { if (G()->use_message_database()) { // TODO load dialog from database, DialogLoader // send_closure_later(actor_id(this), &MessagesManager::load_dialog_from_database, dialog_id, @@ -16592,14 +15673,14 @@ bool MessagesManager::load_dialog(DialogId dialog_id, int left_tries, Promisecontacts_manager_->get_user(user_id, left_tries, std::move(promise)); + auto have_user = td_->user_manager_->get_user(user_id, left_tries, std::move(promise)); if (!have_user) { return false; } break; } case DialogType::Chat: { - auto have_chat = td_->contacts_manager_->get_chat(dialog_id.get_chat_id(), left_tries, std::move(promise)); + auto have_chat = td_->chat_manager_->get_chat(dialog_id.get_chat_id(), left_tries, std::move(promise)); if (!have_chat) { return false; } @@ -16607,7 +15688,7 @@ bool MessagesManager::load_dialog(DialogId dialog_id, int left_tries, Promisecontacts_manager_->get_channel(dialog_id.get_channel_id(), left_tries, std::move(promise)); + td_->chat_manager_->get_channel(dialog_id.get_channel_id(), left_tries, std::move(promise)); if (!have_channel) { return false; } @@ -16620,7 +15701,7 @@ bool MessagesManager::load_dialog(DialogId dialog_id, int left_tries, Promisedialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return false; } @@ -16705,7 +15786,7 @@ vector MessagesManager::get_dialogs(DialogListId dialog_list_id, Dialo auto dialog_id = input_dialog_id.get_dialog_id(); if (!have_dialog_force(dialog_id, "get_dialogs")) { if (dialog_id.get_type() == DialogType::SecretChat) { - if (have_dialog_info_force(dialog_id)) { + if (td_->dialog_manager_->have_dialog_info_force(dialog_id, "get_dialogs")) { force_create_dialog(dialog_id, "get_dialogs"); } } else { @@ -16895,7 +15976,7 @@ void MessagesManager::load_folder_dialog_list(FolderId folder_id, int32 limit, b is_query_sent = true; } if (folder_id == FolderId::main() && folder.last_server_dialog_date_ == MIN_DIALOG_DATE) { - // do not pass promise to not wait for drafts before showing chat list + // do not pass promise to not wait for drafts before showing the chat list load_all_draft_messages(td_); } lock.set_value(Unit()); @@ -16984,8 +16065,8 @@ void MessagesManager::on_get_dialogs_from_database(FolderId folder_id, int32 lim continue; } if (d->folder_id != folder_id) { - LOG(WARNING) << "Skip " << d->dialog_id << " received from database, because it is in " << d->folder_id - << " instead of " << folder_id; + LOG(INFO) << "Skip " << d->dialog_id << " received from database, because it is in " << d->folder_id + << " instead of " << folder_id; dialogs_skipped++; continue; } @@ -17060,7 +16141,8 @@ void MessagesManager::get_dialogs_from_list(DialogListId dialog_list_id, int32 l Promise> &&promise) { CHECK(!td_->auth_manager_->is_bot()); - if (get_dialog_list(dialog_list_id) == nullptr) { + auto *list = get_dialog_list(dialog_list_id); + if (list == nullptr) { return promise.set_error(Status::Error(400, "Chat list not found")); } @@ -17071,6 +16153,7 @@ void MessagesManager::get_dialogs_from_list(DialogListId dialog_list_id, int32 l auto task_id = ++current_get_dialogs_task_id_; auto &task = get_dialogs_tasks_[task_id]; task.dialog_list_id = dialog_list_id; + task.dialog_list_unique_id = list->unique_id_; task.retry_count = 5; task.limit = limit; task.promise = std::move(promise); @@ -17099,7 +16182,8 @@ void MessagesManager::get_dialogs_from_list_impl(int64 task_id) { if (!task_promise) { dialog_ids.clear(); } - return task_promise.set_value(get_chats_object(total_count, dialog_ids, "get_dialogs_from_list_impl")); + return task_promise.set_value( + td_->dialog_manager_->get_chats_object(total_count, dialog_ids, "get_dialogs_from_list_impl")); } // nor the limit, nor the end of the list were reached; wait for the promise } @@ -17107,11 +16191,15 @@ void MessagesManager::get_dialogs_from_list_impl(int64 task_id) { void MessagesManager::on_get_dialogs_from_list(int64 task_id, Result &&result) { auto task_it = get_dialogs_tasks_.find(task_id); if (task_it == get_dialogs_tasks_.end()) { - // the task has already been completed LOG(INFO) << "Chat list load task " << task_id << " has already been completed"; return; } auto &task = task_it->second; + auto list_ptr = get_dialog_list(task.dialog_list_id); + if (result.is_ok() && (list_ptr == nullptr || list_ptr->unique_id_ != task.dialog_list_unique_id)) { + CHECK(!task.dialog_list_id.is_folder()); + result = Status::Error(400, "Chat list not found"); + } if (result.is_error()) { LOG(INFO) << "Chat list load task " << task_id << " failed with the error " << result.error(); auto task_promise = std::move(task.promise); @@ -17119,7 +16207,6 @@ void MessagesManager::on_get_dialogs_from_list(int64 task_id, Result &&res return task_promise.set_error(result.move_as_error()); } - auto list_ptr = get_dialog_list(task.dialog_list_id); CHECK(list_ptr != nullptr); auto &list = *list_ptr; if (task.last_dialog_date == list.list_last_dialog_date_) { @@ -17134,7 +16221,7 @@ void MessagesManager::on_get_dialogs_from_list(int64 task_id, Result &&res } void MessagesManager::mark_dialog_as_read(Dialog *d) { - if (is_forum_channel(d->dialog_id)) { + if (td_->dialog_manager_->is_forum_channel(d->dialog_id)) { // TODO read forum topics } if (d->server_unread_count + d->local_unread_count > 0 && d->last_message_id.is_valid()) { @@ -17222,23 +16309,17 @@ vector MessagesManager::search_public_dialogs(const string &query, Pro for (auto &short_username : get_valid_short_usernames()) { if (2 * username.size() > short_username.size() && begins_with(short_username, username)) { username = short_username.str(); - auto resolved_username = resolved_usernames_.get(username); - if (!resolved_username.dialog_id.is_valid()) { - td_->create_handler(std::move(promise))->send(username); + auto dialog_id = td_->dialog_manager_->resolve_dialog_username(username, promise); + if (!dialog_id.is_valid()) { return {}; } - if (resolved_username.expires_at < Time::now()) { - td_->create_handler(Promise())->send(username); - } - - auto dialog_id = resolved_username.dialog_id; - force_create_dialog(dialog_id, "public dialogs search"); + force_create_dialog(dialog_id, "search_public_dialogs"); auto d = get_dialog(dialog_id); if (d == nullptr || d->order != DEFAULT_ORDER || (dialog_id.get_type() == DialogType::User && - td_->contacts_manager_->is_user_contact(dialog_id.get_user_id()))) { + td_->user_manager_->is_user_contact(dialog_id.get_user_id()))) { continue; } @@ -17296,6 +16377,25 @@ std::pair> MessagesManager::search_dialogs(const string return {narrow_cast(result.first), std::move(dialog_ids)}; } +std::pair> MessagesManager::search_recently_found_dialogs(const string &query, int32 limit, + Promise &&promise) { + auto result = recently_found_dialogs_.get_dialogs(query.empty() ? limit : 50, std::move(promise)); + if (result.first == 0 || query.empty()) { + return result; + } + + Hints hints; + int rating = 1; + for (auto dialog_id : result.second) { + hints.add(dialog_id.get(), td_->dialog_manager_->get_dialog_search_text(dialog_id)); + hints.set_rating(dialog_id.get(), ++rating); + } + + auto hints_result = hints.search(query, limit, false); + return {narrow_cast(hints_result.first), + transform(hints_result.second, [](int64 key) { return DialogId(key); })}; +} + std::pair> MessagesManager::get_recently_opened_dialogs(int32 limit, Promise &&promise) { CHECK(!td_->auth_manager_->is_bot()); return recently_opened_dialogs_.get_dialogs(limit, std::move(promise)); @@ -17352,154 +16452,12 @@ vector MessagesManager::search_dialogs_on_server(const string &query, return {}; } -void MessagesManager::drop_common_dialogs_cache(UserId user_id) { - auto it = found_common_dialogs_.find(user_id); - if (it != found_common_dialogs_.end()) { - it->second.is_outdated = true; - } -} - -std::pair> MessagesManager::get_common_dialogs(UserId user_id, DialogId offset_dialog_id, - int32 limit, bool force, - Promise &&promise) { - auto r_input_user = td_->contacts_manager_->get_input_user(user_id); - if (r_input_user.is_error()) { - promise.set_error(r_input_user.move_as_error()); - return {}; - } - - if (user_id == td_->contacts_manager_->get_my_id()) { - promise.set_error(Status::Error(400, "Can't get common chats with self")); - return {}; - } - if (limit <= 0) { - promise.set_error(Status::Error(400, "Parameter limit must be positive")); - return {}; - } - if (limit > MAX_GET_DIALOGS) { - limit = MAX_GET_DIALOGS; - } - - int64 offset_chat_id = 0; - switch (offset_dialog_id.get_type()) { - case DialogType::Chat: - offset_chat_id = offset_dialog_id.get_chat_id().get(); - break; - case DialogType::Channel: - offset_chat_id = offset_dialog_id.get_channel_id().get(); - break; - case DialogType::None: - if (offset_dialog_id == DialogId()) { - break; - } - // fallthrough - case DialogType::User: - case DialogType::SecretChat: - promise.set_error(Status::Error(400, "Wrong offset_chat_id")); - return {}; - default: - UNREACHABLE(); - break; - } - - auto it = found_common_dialogs_.find(user_id); - if (it != found_common_dialogs_.end() && !it->second.dialog_ids.empty()) { - int32 total_count = it->second.total_count; - vector &common_dialog_ids = it->second.dialog_ids; - bool use_cache = (!it->second.is_outdated && it->second.receive_time >= Time::now() - 3600) || force || - offset_chat_id != 0 || common_dialog_ids.size() >= static_cast(MAX_GET_DIALOGS); - // use cache if it is up-to-date, or we required to use it or we can't update it - if (use_cache) { - auto offset_it = common_dialog_ids.begin(); - if (offset_dialog_id != DialogId()) { - offset_it = std::find(common_dialog_ids.begin(), common_dialog_ids.end(), offset_dialog_id); - if (offset_it == common_dialog_ids.end()) { - promise.set_error(Status::Error(400, "Wrong offset_chat_id")); - return {}; - } - ++offset_it; - } - vector result; - while (result.size() < static_cast(limit)) { - if (offset_it == common_dialog_ids.end()) { - break; - } - auto dialog_id = *offset_it++; - if (dialog_id == DialogId()) { // end of the list - promise.set_value(Unit()); - return {total_count, std::move(result)}; - } - result.push_back(dialog_id); - } - if (result.size() == static_cast(limit) || force) { - promise.set_value(Unit()); - return {total_count, std::move(result)}; - } - } - } - - td_->create_handler(std::move(promise)) - ->send(user_id, r_input_user.move_as_ok(), offset_chat_id, MAX_GET_DIALOGS); - return {}; -} - -void MessagesManager::on_get_common_dialogs(UserId user_id, int64 offset_chat_id, - vector> &&chats, int32 total_count) { - CHECK(user_id.is_valid()); - td_->contacts_manager_->on_update_user_common_chat_count(user_id, total_count); - - auto &common_dialogs = found_common_dialogs_[user_id]; - if (common_dialogs.is_outdated && offset_chat_id == 0 && - common_dialogs.dialog_ids.size() < static_cast(MAX_GET_DIALOGS)) { - // drop outdated cache if possible - common_dialogs = CommonDialogs(); - } - if (common_dialogs.receive_time == 0) { - common_dialogs.receive_time = Time::now(); - } - common_dialogs.is_outdated = false; - auto &result = common_dialogs.dialog_ids; - if (!result.empty() && result.back() == DialogId()) { - return; - } - bool is_last = chats.empty() && offset_chat_id == 0; - for (auto &chat : chats) { - auto dialog_id = ContactsManager::get_dialog_id(chat); - if (!dialog_id.is_valid()) { - LOG(ERROR) << "Receive invalid " << to_string(chat); - continue; - } - td_->contacts_manager_->on_get_chat(std::move(chat), "on_get_common_dialogs"); - - if (!td::contains(result, dialog_id)) { - force_create_dialog(dialog_id, "get common dialogs"); - result.push_back(dialog_id); - } - } - if (result.size() >= static_cast(total_count) || is_last) { - if (result.size() != static_cast(total_count)) { - LOG(ERROR) << "Fix total count of common groups with " << user_id << " from " << total_count << " to " - << result.size(); - total_count = narrow_cast(result.size()); - td_->contacts_manager_->on_update_user_common_chat_count(user_id, total_count); - } - - result.emplace_back(); - } - common_dialogs.total_count = total_count; -} - void MessagesManager::block_message_sender_from_replies(MessageId message_id, bool need_delete_message, bool need_delete_all_messages, bool report_spam, Promise &&promise) { - auto dialog_id = DialogId(ContactsManager::get_replies_bot_user_id()); - Dialog *d = get_dialog_force(dialog_id, "block_message_sender_from_replies"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Not enough rights")); - } + auto dialog_id = DialogId(UserManager::get_replies_bot_user_id()); + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, false, AccessRights::Read, "block_message_sender_from_replies")); auto *m = get_message_force(d, message_id, "block_message_sender_from_replies"); if (m == nullptr) { @@ -17509,14 +16467,15 @@ void MessagesManager::block_message_sender_from_replies(MessageId message_id, bo return promise.set_error(Status::Error(400, "Wrong message specified")); } - UserId sender_user_id; + DialogId sender_dialog_id; if (m->forward_info != nullptr) { - sender_user_id = m->forward_info->sender_user_id; + sender_dialog_id = m->forward_info->get_origin().get_sender(); } vector message_ids; - if (need_delete_all_messages && sender_user_id.is_valid()) { - message_ids = find_dialog_messages(d, [sender_user_id](const Message *m) { - return !m->is_outgoing && m->forward_info != nullptr && m->forward_info->sender_user_id == sender_user_id; + if (need_delete_all_messages && sender_dialog_id.is_valid()) { + message_ids = find_dialog_messages(d, [sender_dialog_id](const Message *m) { + return !m->is_outgoing && m->forward_info != nullptr && + m->forward_info->get_origin().get_sender() == sender_dialog_id; }); CHECK(td::contains(message_ids, message_id)); } else if (need_delete_message) { @@ -17586,8 +16545,8 @@ bool MessagesManager::is_dialog_blocked(DialogId dialog_id) const { return d != nullptr && d->is_blocked; } -void MessagesManager::get_blocked_dialogs(int32 offset, int32 limit, - Promise> &&promise) { +void MessagesManager::get_blocked_dialogs(const td_api::object_ptr &block_list, int32 offset, + int32 limit, Promise> &&promise) { if (offset < 0) { return promise.set_error(Status::Error(400, "Parameter offset must be non-negative")); } @@ -17596,7 +16555,12 @@ void MessagesManager::get_blocked_dialogs(int32 offset, int32 limit, return promise.set_error(Status::Error(400, "Parameter limit must be positive")); } - td_->create_handler(std::move(promise))->send(offset, limit); + auto block_list_id = BlockListId(block_list); + if (!block_list_id.is_valid()) { + return promise.set_error(Status::Error(400, "Block list must be non-empty")); + } + + td_->create_handler(std::move(promise))->send(block_list_id, offset, limit); } void MessagesManager::on_get_blocked_dialogs(int32 offset, int32 limit, int32 total_count, @@ -17619,62 +16583,66 @@ void MessagesManager::on_get_blocked_dialogs(int32 offset, int32 limit, int32 to promise.set_value(td_api::make_object(total_count, std::move(senders))); } -DialogId MessagesManager::get_dialog_message_sender(FullMessageId full_message_id) { - const auto *m = get_message_force(full_message_id, "get_dialog_message_sender"); +DialogId MessagesManager::get_dialog_message_sender(MessageFullId message_full_id) { + const auto *m = get_message_force(message_full_id, "get_dialog_message_sender"); if (m == nullptr) { return DialogId(); } return get_message_sender(m); } -bool MessagesManager::have_message_force(FullMessageId full_message_id, const char *source) { - return get_message_force(full_message_id, source) != nullptr; +bool MessagesManager::have_message_force(MessageFullId message_full_id, const char *source) { + return get_message_force(message_full_id, source) != nullptr; } bool MessagesManager::have_message_force(Dialog *d, MessageId message_id, const char *source) { return get_message_force(d, message_id, source) != nullptr; } -MessagesManager::Message *MessagesManager::get_message(FullMessageId full_message_id) { - Dialog *d = get_dialog(full_message_id.get_dialog_id()); +MessagesManager::Message *MessagesManager::get_message(MessageFullId message_full_id) { + Dialog *d = get_dialog(message_full_id.get_dialog_id()); if (d == nullptr) { return nullptr; } - return get_message(d, full_message_id.get_message_id()); + return get_message(d, message_full_id.get_message_id()); } -const MessagesManager::Message *MessagesManager::get_message(FullMessageId full_message_id) const { - const Dialog *d = get_dialog(full_message_id.get_dialog_id()); +const MessagesManager::Message *MessagesManager::get_message(MessageFullId message_full_id) const { + const Dialog *d = get_dialog(message_full_id.get_dialog_id()); if (d == nullptr) { return nullptr; } - return get_message(d, full_message_id.get_message_id()); + return get_message(d, message_full_id.get_message_id()); } -MessagesManager::Message *MessagesManager::get_message_force(FullMessageId full_message_id, const char *source) { - Dialog *d = get_dialog_force(full_message_id.get_dialog_id(), source); +MessagesManager::Message *MessagesManager::get_message_force(MessageFullId message_full_id, const char *source) { + Dialog *d = get_dialog_force(message_full_id.get_dialog_id(), source); if (d == nullptr) { return nullptr; } - return get_message_force(d, full_message_id.get_message_id(), source); + return get_message_force(d, message_full_id.get_message_id(), source); } -FullMessageId MessagesManager::get_replied_message_id(DialogId dialog_id, const Message *m) { - auto full_message_id = get_message_content_replied_message_id(dialog_id, m->content.get()); - if (full_message_id.get_message_id().is_valid()) { - CHECK(m->reply_to_message_id == MessageId()); - return full_message_id; - } - if (m->reply_to_message_id == MessageId()) { - if (m->top_thread_message_id.is_valid() && is_service_message_content(m->content->get_type())) { - return {dialog_id, m->top_thread_message_id}; - } +MessageFullId MessagesManager::get_replied_message_id(DialogId dialog_id, const Message *m) { + if (m->reply_to_story_full_id.is_valid()) { return {}; } - return {m->reply_in_dialog_id.is_valid() ? m->reply_in_dialog_id : dialog_id, m->reply_to_message_id}; + auto message_full_id = get_message_content_replied_message_id(dialog_id, m->content.get()); + if (message_full_id.get_message_id().is_valid()) { + CHECK(m->replied_message_info.is_empty()); + return message_full_id; + } + auto reply_message_full_id = m->replied_message_info.get_reply_message_full_id(dialog_id, true); + if (reply_message_full_id.get_message_id() != MessageId()) { + return reply_message_full_id; + } + if (m->top_thread_message_id.is_valid() && m->top_thread_message_id != m->message_id) { + return {dialog_id, m->top_thread_message_id}; + } + return {}; } void MessagesManager::get_message_force_from_server(Dialog *d, MessageId message_id, Promise &&promise, @@ -17701,22 +16669,22 @@ void MessagesManager::get_message_force_from_server(Dialog *d, MessageId message promise.set_value(Unit()); } -void MessagesManager::get_message(FullMessageId full_message_id, Promise &&promise) { - Dialog *d = get_dialog_force(full_message_id.get_dialog_id(), "get_message"); +void MessagesManager::get_message(MessageFullId message_full_id, Promise &&promise) { + Dialog *d = get_dialog_force(message_full_id.get_dialog_id(), "get_message"); if (d == nullptr) { return promise.set_error(Status::Error(400, "Chat not found")); } - get_message_force_from_server(d, full_message_id.get_message_id(), std::move(promise)); + get_message_force_from_server(d, message_full_id.get_message_id(), std::move(promise)); } -FullMessageId MessagesManager::get_replied_message(DialogId dialog_id, MessageId message_id, bool force, +MessageFullId MessagesManager::get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise &&promise) { LOG(INFO) << "Get replied message to " << message_id << " in " << dialog_id; Dialog *d = get_dialog_force(dialog_id, "get_replied_message"); if (d == nullptr) { promise.set_error(Status::Error(400, "Chat not found")); - return FullMessageId(); + return MessageFullId(); } message_id = get_persistent_message_id(d, message_id); @@ -17727,18 +16695,18 @@ FullMessageId MessagesManager::get_replied_message(DialogId dialog_id, MessageId } else { get_message_force_from_server(d, message_id, std::move(promise)); } - return FullMessageId(); + return MessageFullId(); } tl_object_ptr input_message; auto replied_message_id = get_replied_message_id(dialog_id, m); if (replied_message_id.get_dialog_id() != dialog_id) { dialog_id = replied_message_id.get_dialog_id(); - if (!have_dialog_info_force(dialog_id)) { + if (!td_->dialog_manager_->have_dialog_info_force(dialog_id, "get_replied_message")) { promise.set_value(Unit()); return {}; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { promise.set_value(Unit()); return {}; } @@ -17757,7 +16725,7 @@ FullMessageId MessagesManager::get_replied_message(DialogId dialog_id, MessageId return replied_message_id; } -Result MessagesManager::get_top_thread_full_message_id(DialogId dialog_id, const Message *m, +Result MessagesManager::get_top_thread_message_full_id(DialogId dialog_id, const Message *m, bool allow_non_root) const { CHECK(m != nullptr); if (m->message_id.is_scheduled()) { @@ -17773,29 +16741,23 @@ Result MessagesManager::get_top_thread_full_message_id(DialogId d if (m->message_id.is_yet_unsent()) { return Status::Error(400, "Message is not sent yet"); } - return FullMessageId{DialogId(m->reply_info.channel_id_), m->linked_top_thread_message_id}; + return MessageFullId{DialogId(m->reply_info.channel_id_), m->linked_top_thread_message_id}; } else { if (!m->top_thread_message_id.is_valid()) { return Status::Error(400, "Message has no thread"); } if (!allow_non_root && m->top_thread_message_id != m->message_id && - !td_->contacts_manager_->get_channel_has_linked_channel(dialog_id.get_channel_id())) { + !td_->chat_manager_->get_channel_has_linked_channel(dialog_id.get_channel_id())) { return Status::Error(400, "Root message must be used to get the message thread"); } - return FullMessageId{dialog_id, m->top_thread_message_id}; + return MessageFullId{dialog_id, m->top_thread_message_id}; } } void MessagesManager::get_message_thread(DialogId dialog_id, MessageId message_id, Promise &&promise) { LOG(INFO) << "Get message thread from " << message_id << " in " << dialog_id; - Dialog *d = get_dialog_force(dialog_id, "get_message_thread"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, false, AccessRights::Read, "get_message_thread")); if (dialog_id.get_type() != DialogType::Channel) { return promise.set_error(Status::Error(400, "Chat is not a supergroup or a channel")); } @@ -17803,9 +16765,9 @@ void MessagesManager::get_message_thread(DialogId dialog_id, MessageId message_i return promise.set_error(Status::Error(400, "Scheduled messages can't have message threads")); } - FullMessageId top_thread_full_message_id; - if (message_id == MessageId(ServerMessageId(1)) && is_forum_channel(dialog_id)) { - top_thread_full_message_id = FullMessageId{dialog_id, message_id}; + MessageFullId top_thread_message_full_id; + if (message_id == MessageId(ServerMessageId(1)) && td_->dialog_manager_->is_forum_channel(dialog_id)) { + top_thread_message_full_id = MessageFullId{dialog_id, message_id}; } else { message_id = get_persistent_message_id(d, message_id); auto m = get_message_force(d, message_id, "get_message_thread"); @@ -17813,12 +16775,12 @@ void MessagesManager::get_message_thread(DialogId dialog_id, MessageId message_i return promise.set_error(Status::Error(400, "Message not found")); } - TRY_RESULT_PROMISE_ASSIGN(promise, top_thread_full_message_id, get_top_thread_full_message_id(dialog_id, m, true)); + TRY_RESULT_PROMISE_ASSIGN(promise, top_thread_message_full_id, get_top_thread_message_full_id(dialog_id, m, true)); if ((m->reply_info.is_empty() || !m->reply_info.is_comment_) && - top_thread_full_message_id.get_message_id() != m->message_id) { - CHECK(dialog_id == top_thread_full_message_id.get_dialog_id()); + top_thread_message_full_id.get_message_id() != m->message_id) { + CHECK(dialog_id == top_thread_message_full_id.get_dialog_id()); // get information about the thread from the top message - message_id = top_thread_full_message_id.get_message_id(); + message_id = top_thread_message_full_id.get_message_id(); CHECK(message_id.is_valid()); } } @@ -17833,8 +16795,8 @@ void MessagesManager::get_message_thread(DialogId dialog_id, MessageId message_i }); td_->create_handler(std::move(query_promise)) - ->send(dialog_id, message_id, top_thread_full_message_id.get_dialog_id(), - top_thread_full_message_id.get_message_id()); + ->send(dialog_id, message_id, top_thread_message_full_id.get_dialog_id(), + top_thread_message_full_id.get_message_id()); } void MessagesManager::process_discussion_message( @@ -17843,8 +16805,8 @@ void MessagesManager::process_discussion_message( Promise promise) { LOG(INFO) << "Receive discussion message for " << message_id << " in " << dialog_id << " with expected " << expected_message_id << " in " << expected_dialog_id << ": " << to_string(result); - td_->contacts_manager_->on_get_users(std::move(result->users_), "process_discussion_message"); - td_->contacts_manager_->on_get_chats(std::move(result->chats_), "process_discussion_message"); + td_->user_manager_->on_get_users(std::move(result->users_), "process_discussion_message"); + td_->chat_manager_->on_get_chats(std::move(result->chats_), "process_discussion_message"); for (auto &message : result->messages_) { auto message_dialog_id = DialogId::get_message_dialog_id(message); @@ -17863,7 +16825,8 @@ void MessagesManager::process_discussion_message( promise = std::move(promise)](Unit ignored) mutable { send_closure(actor_id, &MessagesManager::process_discussion_message_impl, std::move(result), dialog_id, message_id, expected_dialog_id, expected_message_id, std::move(promise)); - })); + }), + "process_discussion_message"); } } @@ -17882,11 +16845,11 @@ void MessagesManager::process_discussion_message_impl( message_thread_info.unread_message_count = max(0, result->unread_count_); MessageId top_message_id; for (auto &message : result->messages_) { - auto full_message_id = on_get_message(std::move(message), false, true, false, "process_discussion_message_impl"); - if (full_message_id.get_message_id().is_valid()) { - CHECK(full_message_id.get_dialog_id() == expected_dialog_id); - message_thread_info.message_ids.push_back(full_message_id.get_message_id()); - if (full_message_id.get_message_id() == expected_message_id) { + auto message_full_id = on_get_message(std::move(message), false, true, false, "process_discussion_message_impl"); + if (message_full_id.get_message_id().is_valid()) { + CHECK(message_full_id.get_dialog_id() == expected_dialog_id); + message_thread_info.message_ids.push_back(message_full_id.get_message_id()); + if (message_full_id.get_message_id() == expected_message_id) { top_message_id = expected_message_id; } } @@ -17923,7 +16886,7 @@ void MessagesManager::on_get_discussion_message(DialogId dialog_id, MessageId me } if (message_thread_info.message_ids.empty()) { if (message_thread_info.dialog_id != dialog_id && - !have_input_peer(message_thread_info.dialog_id, AccessRights::Read)) { + !td_->dialog_manager_->have_input_peer(message_thread_info.dialog_id, false, AccessRights::Read)) { return promise.set_error(Status::Error(400, "Can't access message comments")); } return promise.set_error(Status::Error(400, "Message has no thread")); @@ -17935,7 +16898,7 @@ void MessagesManager::on_get_discussion_message(DialogId dialog_id, MessageId me return promise.set_error(Status::Error(400, "Message has no comments")); } expected_dialog_id = DialogId(m->reply_info.channel_id_); - } else if (message_id == MessageId(ServerMessageId(1)) && is_forum_channel(dialog_id)) { + } else if (message_id == MessageId(ServerMessageId(1)) && td_->dialog_manager_->is_forum_channel(dialog_id)) { // General forum topic expected_dialog_id = dialog_id; } else { @@ -17949,6 +16912,12 @@ void MessagesManager::on_get_discussion_message(DialogId dialog_id, MessageId me m->linked_top_thread_message_id != message_thread_info.message_ids.back()) { auto linked_d = get_dialog_force(expected_dialog_id, "on_get_discussion_message 2"); CHECK(linked_d != nullptr); + td::remove_if(message_thread_info.message_ids, [&](MessageId linked_message_id) { + return !have_message_force(linked_d, linked_message_id, "on_get_discussion_message 4"); + }); + if (message_thread_info.message_ids.empty()) { + return promise.set_error(Status::Error(400, "Message has no thread")); + } auto linked_message_id = message_thread_info.message_ids.back(); Message *linked_m = get_message_force(linked_d, linked_message_id, "on_get_discussion_message 3"); CHECK(linked_m != nullptr && linked_m->message_id.is_server()); @@ -17991,7 +16960,8 @@ td_api::object_ptr MessagesManager::get_message_threa } if (messages.size() != 1) { is_forum_topic = false; - } else if (info.message_ids[0] == MessageId(ServerMessageId(1)) && is_forum_channel(info.dialog_id)) { + } else if (info.message_ids[0] == MessageId(ServerMessageId(1)) && + td_->dialog_manager_->is_forum_channel(info.dialog_id)) { // General forum topic is_forum_topic = true; } @@ -18006,7 +16976,7 @@ td_api::object_ptr MessagesManager::get_message_threa if (can_send_message(d->dialog_id).is_ok()) { const Message *m = get_message_force(d, top_thread_message_id, "get_message_thread_info_object 2"); if (m != nullptr && !m->reply_info.is_comment_ && is_active_message_reply_info(d->dialog_id, m->reply_info)) { - draft_message = get_draft_message_object(m->thread_draft_message); + draft_message = get_draft_message_object(td_, m->thread_draft_message); } } } @@ -18015,14 +16985,80 @@ td_api::object_ptr MessagesManager::get_message_threa info.unread_message_count, std::move(messages), std::move(draft_message)); } -Status MessagesManager::can_get_message_viewers(FullMessageId full_message_id) { - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "get_message_viewers"); +Status MessagesManager::can_get_message_read_date(DialogId dialog_id, const Message *m) const { + if (td_->auth_manager_->is_bot()) { + return Status::Error(400, "User is bot"); + } + CHECK(m != nullptr); + if (!m->is_outgoing) { + return Status::Error(400, "Can't get read date of incoming messages"); + } + if (G()->unix_time() - m->date > td_->option_manager_->get_option_integer("pm_read_date_expire_period")) { + return Status::Error(400, "Message is too old"); + } + + if (dialog_id.get_type() != DialogType::User) { + return Status::Error(400, "Read date can be received only in private chats"); + } + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { + return Status::Error(400, "Can't access the chat"); + } + auto user_id = dialog_id.get_user_id(); + if (td_->user_manager_->is_user_bot(user_id)) { + return Status::Error(400, "The user is a bot"); + } + if (td_->user_manager_->is_user_support(user_id)) { + return Status::Error(400, "The user is a Telegram support account"); + } + + if (m->message_id.is_scheduled()) { + return Status::Error(400, "Scheduled messages can't be read"); + } + if (m->message_id.is_yet_unsent()) { + return Status::Error(400, "Yet unsent messages can't be read"); + } + if (m->message_id.is_local()) { + return Status::Error(400, "Local messages can't be read"); + } + CHECK(m->message_id.is_server()); + + return Status::OK(); +} + +void MessagesManager::get_message_read_date(MessageFullId message_full_id, + Promise> &&promise) { + auto dialog_id = message_full_id.get_dialog_id(); + Dialog *d = get_dialog_force(dialog_id, "get_message_read_date"); + if (d == nullptr) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + + auto m = get_message_force(d, message_full_id.get_message_id(), "get_message_read_date"); + if (m == nullptr) { + return promise.set_error(Status::Error(400, "Message not found")); + } + + TRY_STATUS_PROMISE(promise, can_get_message_read_date(dialog_id, m)); + + if (d->last_read_outbox_message_id < m->message_id) { + return promise.set_value(td_api::make_object()); + } + if (td_->user_manager_->get_user_read_dates_private(dialog_id.get_user_id())) { + return promise.set_value(td_api::make_object()); + } + + td_->create_handler(std::move(promise)) + ->send(message_full_id.get_dialog_id(), message_full_id.get_message_id()); +} + +Status MessagesManager::can_get_message_viewers(MessageFullId message_full_id) { + auto dialog_id = message_full_id.get_dialog_id(); + Dialog *d = get_dialog_force(dialog_id, "can_get_message_viewers"); if (d == nullptr) { return Status::Error(400, "Chat not found"); } - auto m = get_message_force(d, full_message_id.get_message_id(), "get_message_viewers"); + auto m = get_message_force(d, message_full_id.get_message_id(), "can_get_message_viewers"); if (m == nullptr) { return Status::Error(400, "Message not found"); } @@ -18048,20 +17084,20 @@ Status MessagesManager::can_get_message_viewers(DialogId dialog_id, const Messag case DialogType::User: return Status::Error(400, "Can't get message viewers in private chats"); case DialogType::Chat: - if (!td_->contacts_manager_->get_chat_is_active(dialog_id.get_chat_id())) { + if (!td_->chat_manager_->get_chat_is_active(dialog_id.get_chat_id())) { return Status::Error(400, "Chat is deactivated"); } - participant_count = td_->contacts_manager_->get_chat_participant_count(dialog_id.get_chat_id()); + participant_count = td_->chat_manager_->get_chat_participant_count(dialog_id.get_chat_id()); break; case DialogType::Channel: - if (is_broadcast_channel(dialog_id)) { + if (td_->dialog_manager_->is_broadcast_channel(dialog_id)) { return Status::Error(400, "Can't get message viewers in channel chats"); } - if (td_->contacts_manager_->get_channel_effective_has_hidden_participants(dialog_id.get_channel_id(), - "can_get_message_viewers")) { + if (td_->chat_manager_->get_channel_effective_has_hidden_participants(dialog_id.get_channel_id(), + "can_get_message_viewers")) { return Status::Error(400, "Participant list is hidden in the chat"); } - participant_count = td_->contacts_manager_->get_channel_participant_count(dialog_id.get_channel_id()); + participant_count = td_->chat_manager_->get_channel_participant_count(dialog_id.get_channel_id()); break; case DialogType::SecretChat: return Status::Error(400, "Can't get message viewers in secret chats"); @@ -18070,7 +17106,7 @@ Status MessagesManager::can_get_message_viewers(DialogId dialog_id, const Messag UNREACHABLE(); return Status::OK(); } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { return Status::Error(400, "Can't access the chat"); } if (participant_count == 0) { @@ -18099,11 +17135,11 @@ Status MessagesManager::can_get_message_viewers(DialogId dialog_id, const Messag return Status::OK(); } -void MessagesManager::get_message_viewers(FullMessageId full_message_id, +void MessagesManager::get_message_viewers(MessageFullId message_full_id, Promise> &&promise) { - TRY_STATUS_PROMISE(promise, can_get_message_viewers(full_message_id)); + TRY_STATUS_PROMISE(promise, can_get_message_viewers(message_full_id)); - auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = full_message_id.get_dialog_id(), + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = message_full_id.get_dialog_id(), promise = std::move(promise)](Result result) mutable { if (result.is_error()) { return promise.set_error(result.move_as_error()); @@ -18113,20 +17149,15 @@ void MessagesManager::get_message_viewers(FullMessageId full_message_id, }); td_->create_handler(std::move(query_promise)) - ->send(full_message_id.get_dialog_id(), full_message_id.get_message_id()); + ->send(message_full_id.get_dialog_id(), message_full_id.get_message_id()); } void MessagesManager::on_get_message_viewers(DialogId dialog_id, MessageViewers message_viewers, bool is_recursive, Promise> &&promise) { if (!is_recursive) { bool need_participant_list = false; - for (auto message_viewer : message_viewers.message_viewers_) { - auto user_id = message_viewer.get_user_id(); - if (!user_id.is_valid()) { - LOG(ERROR) << "Receive invalid " << user_id << " as viewer of a message in " << dialog_id; - continue; - } - if (!td_->contacts_manager_->have_user_force(user_id)) { + for (auto user_id : message_viewers.get_user_ids()) { + if (!td_->user_manager_->have_user_force(user_id, "on_get_message_viewers")) { need_participant_list = true; } } @@ -18140,9 +17171,10 @@ void MessagesManager::on_get_message_viewers(DialogId dialog_id, MessageViewers switch (dialog_id.get_type()) { case DialogType::Chat: - return td_->contacts_manager_->reload_chat_full(dialog_id.get_chat_id(), std::move(query_promise)); + return td_->chat_manager_->reload_chat_full(dialog_id.get_chat_id(), std::move(query_promise), + "on_get_message_viewers"); case DialogType::Channel: - return td_->contacts_manager_->get_channel_participants( + return td_->dialog_participant_manager_->get_channel_participants( dialog_id.get_channel_id(), td_api::make_object(), string(), 0, 200, 200, PromiseCreator::lambda([query_promise = std::move(query_promise)](DialogParticipants) mutable { query_promise.set_value(Unit()); @@ -18153,105 +17185,36 @@ void MessagesManager::on_get_message_viewers(DialogId dialog_id, MessageViewers } } } - promise.set_value(message_viewers.get_message_viewers_object(td_->contacts_manager_.get())); + promise.set_value(message_viewers.get_message_viewers_object(td_->user_manager_.get())); } -void MessagesManager::translate_message_text(FullMessageId full_message_id, const string &to_language_code, +void MessagesManager::translate_message_text(MessageFullId message_full_id, const string &to_language_code, Promise> &&promise) { - auto m = get_message_force(full_message_id, "recognize_speech"); + auto m = get_message_force(message_full_id, "translate_message_text"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } auto text = get_message_content_text(m->content.get()); - if (text == nullptr) { + if (text == nullptr || text->text.empty()) { return promise.set_value(td_api::make_object()); } - auto skip_bot_commands = need_skip_bot_commands(full_message_id.get_dialog_id(), m); + auto skip_bot_commands = need_skip_bot_commands(message_full_id.get_dialog_id(), m); auto max_media_timestamp = get_message_max_media_timestamp(m); td_->translation_manager_->translate_text(*text, skip_bot_commands, max_media_timestamp, to_language_code, std::move(promise)); } -void MessagesManager::recognize_speech(FullMessageId full_message_id, Promise &&promise) { - auto m = get_message_force(full_message_id, "recognize_speech"); - if (m == nullptr) { - return promise.set_error(Status::Error(400, "Message not found")); - } - - auto message_id = full_message_id.get_message_id(); - if (message_id.is_scheduled() || !message_id.is_server()) { - return promise.set_error(Status::Error(400, "Message must be sent already")); - } - - recognize_message_content_speech(td_, m->content.get(), full_message_id, std::move(promise)); -} - -void MessagesManager::rate_speech_recognition(FullMessageId full_message_id, bool is_good, Promise &&promise) { - auto m = get_message_force(full_message_id, "rate_speech_recognition"); - if (m == nullptr) { - return promise.set_error(Status::Error(400, "Message not found")); - } - - rate_message_content_speech_recognition(td_, m->content.get(), full_message_id, is_good, std::move(promise)); -} - -void MessagesManager::get_dialog_info_full(DialogId dialog_id, Promise &&promise, const char *source) { - switch (dialog_id.get_type()) { - case DialogType::User: - send_closure_later(td_->contacts_manager_actor_, &ContactsManager::load_user_full, dialog_id.get_user_id(), false, - std::move(promise), source); - return; - case DialogType::Chat: - send_closure_later(td_->contacts_manager_actor_, &ContactsManager::load_chat_full, dialog_id.get_chat_id(), false, - std::move(promise), source); - return; - case DialogType::Channel: - send_closure_later(td_->contacts_manager_actor_, &ContactsManager::load_channel_full, dialog_id.get_channel_id(), - false, std::move(promise), source); - return; - case DialogType::SecretChat: - return promise.set_value(Unit()); - case DialogType::None: - default: - UNREACHABLE(); - return promise.set_error(Status::Error(500, "Wrong chat type")); - } -} - -void MessagesManager::reload_dialog_info_full(DialogId dialog_id, const char *source) { - if (G()->close_flag()) { - return; - } - - LOG(INFO) << "Reload full info about " << dialog_id << " from " << source; - switch (dialog_id.get_type()) { - case DialogType::User: - send_closure_later(td_->contacts_manager_actor_, &ContactsManager::reload_user_full, dialog_id.get_user_id(), - Promise()); - return; - case DialogType::Chat: - send_closure_later(td_->contacts_manager_actor_, &ContactsManager::reload_chat_full, dialog_id.get_chat_id(), - Promise()); - return; - case DialogType::Channel: - send_closure_later(td_->contacts_manager_actor_, &ContactsManager::reload_channel_full, - dialog_id.get_channel_id(), Promise(), source); - return; - case DialogType::SecretChat: - return; - case DialogType::None: - default: - UNREACHABLE(); - return; - } -} - -void MessagesManager::on_dialog_info_full_invalidated(DialogId dialog_id) { - Dialog *d = get_dialog(dialog_id); - if (d != nullptr && d->open_count > 0) { - reload_dialog_info_full(dialog_id, "on_dialog_info_full_invalidated"); +void MessagesManager::reload_dialog_notification_settings(DialogId dialog_id, Promise &&promise, + const char *source) { + LOG(INFO) << "Reload notification settings for " << dialog_id << " from " << source; + const Dialog *d = get_dialog(dialog_id); + if (d != nullptr) { + td_->notification_settings_manager_->send_get_dialog_notification_settings_query(dialog_id, MessageId(), + std::move(promise)); + } else { + send_get_dialog_query(dialog_id, std::move(promise), 0, source); } } @@ -18267,11 +17230,11 @@ MessageId MessagesManager::get_dialog_pinned_message(DialogId dialog_id, Promise if (!d->is_last_pinned_message_id_inited) { // must call get_dialog_info_full as expected in fix_new_dialog - get_dialog_info_full(dialog_id, std::move(promise), "get_dialog_pinned_message 1"); + td_->dialog_manager_->get_dialog_info_full(dialog_id, std::move(promise), "get_dialog_pinned_message 1"); return MessageId(); } - get_dialog_info_full(dialog_id, Auto(), "get_dialog_pinned_message 2"); + td_->dialog_manager_->get_dialog_info_full(dialog_id, Auto(), "get_dialog_pinned_message 2"); if (d->last_pinned_message_id.is_valid()) { tl_object_ptr input_message; @@ -18311,7 +17274,7 @@ bool MessagesManager::get_messages(DialogId dialog_id, const vector & } bool is_secret = dialog_id.get_type() == DialogType::SecretChat; - vector missed_message_ids; + vector missed_message_ids; for (auto message_id : message_ids) { if (!message_id.is_valid() && !message_id.is_valid_scheduled()) { promise.set_error(Status::Error(400, "Invalid message identifier")); @@ -18334,13 +17297,13 @@ bool MessagesManager::get_messages(DialogId dialog_id, const vector & return true; } -void MessagesManager::get_message_from_server(FullMessageId full_message_id, Promise &&promise, +void MessagesManager::get_message_from_server(MessageFullId message_full_id, Promise &&promise, const char *source, tl_object_ptr input_message) { - get_messages_from_server({full_message_id}, std::move(promise), source, std::move(input_message)); + get_messages_from_server({message_full_id}, std::move(promise), source, std::move(input_message)); } -void MessagesManager::get_messages_from_server(vector &&message_ids, Promise &&promise, +void MessagesManager::get_messages_from_server(vector &&message_ids, Promise &&promise, const char *source, tl_object_ptr input_message) { TRY_STATUS_PROMISE(promise, G()->close_status()); @@ -18357,9 +17320,9 @@ void MessagesManager::get_messages_from_server(vector &&message_i vector> ordinary_message_ids; FlatHashMap>, ChannelIdHash> channel_message_ids; FlatHashMap, DialogIdHash> scheduled_message_ids; - for (auto &full_message_id : message_ids) { - auto dialog_id = full_message_id.get_dialog_id(); - auto message_id = full_message_id.get_message_id(); + for (auto &message_full_id : message_ids) { + auto dialog_id = message_full_id.get_dialog_id(); + auto message_id = message_full_id.get_message_id(); if (!message_id.is_valid() || !message_id.is_server()) { if (message_id.is_valid_scheduled() && message_id.is_scheduled_server() && dialog_id.is_valid()) { scheduled_message_ids[dialog_id].push_back(message_id.get_scheduled_server_message_id().get()); @@ -18380,7 +17343,7 @@ void MessagesManager::get_messages_from_server(vector &&message_i channel_message_ids[dialog_id.get_channel_id()].push_back(std::move(input_message)); break; case DialogType::SecretChat: - LOG(ERROR) << "Can't get " << full_message_id << " from server from " << source; + LOG(ERROR) << "Can't get " << message_full_id << " from server from " << source; break; case DialogType::None: default: @@ -18400,7 +17363,7 @@ void MessagesManager::get_messages_from_server(vector &&message_i for (auto &it : scheduled_message_ids) { auto dialog_id = it.first; have_dialog_force(dialog_id, "get_messages_from_server"); - auto input_peer = get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { LOG(ERROR) << "Can't find info about " << dialog_id << " to get a message from it from " << source; mpas.get_promise().set_error(Status::Error(400, "Can't access the chat")); @@ -18411,8 +17374,8 @@ void MessagesManager::get_messages_from_server(vector &&message_i } for (auto &it : channel_message_ids) { - td_->contacts_manager_->have_channel_force(it.first); - auto input_channel = td_->contacts_manager_->get_input_channel(it.first); + td_->chat_manager_->have_channel_force(it.first, "get_messages_from_server"); + auto input_channel = td_->chat_manager_->get_input_channel(it.first); if (input_channel == nullptr) { LOG(ERROR) << "Can't find info about " << it.first << " to get a message from it from " << source; mpas.get_promise().set_error(Status::Error(400, "Can't access the chat")); @@ -18426,15 +17389,95 @@ void MessagesManager::get_messages_from_server(vector &&message_i lock.set_value(Unit()); } -bool MessagesManager::is_message_edited_recently(FullMessageId full_message_id, int32 seconds) { +void MessagesManager::get_message_properties(DialogId dialog_id, MessageId message_id, + Promise> &&promise) { + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Read, "get_message_properties")); + const Message *m = get_message_force(d, message_id, "get_message_properties"); + if (m == nullptr) { + if (message_id.is_valid_sponsored()) { + return promise.set_value(td_api::make_object()); + } + return promise.set_error(Status::Error(400, "Message not found")); + } + + bool can_delete = can_delete_message(dialog_id, m); + bool is_scheduled = m->message_id.is_scheduled(); + bool is_from_saved_messages = (dialog_id == td_->dialog_manager_->get_my_dialog_id()); + bool can_delete_for_self = false; + bool can_delete_for_all_users = can_delete && can_revoke_message(dialog_id, m); + auto dialog_type = dialog_id.get_type(); + if (can_delete) { + switch (dialog_type) { + case DialogType::User: + case DialogType::Chat: + // TODO allow to delete yet unsent message just for self + can_delete_for_self = !m->message_id.is_yet_unsent() || is_from_saved_messages; + break; + case DialogType::Channel: + case DialogType::SecretChat: + can_delete_for_self = !can_delete_for_all_users; + break; + case DialogType::None: + default: + UNREACHABLE(); + } + } + if (is_scheduled) { + can_delete_for_self = is_from_saved_messages; + can_delete_for_all_users = !can_delete_for_self; + } + + auto is_bot = td_->auth_manager_->is_bot(); + auto can_be_saved = can_save_message(dialog_id, m); + auto can_be_edited = can_edit_message(dialog_id, m, false, is_bot); + auto can_be_forwarded = can_be_saved && can_forward_message(dialog_id, m); + auto can_be_copied_to_secret_chat = + can_be_forwarded && can_send_message_content_to_secret_chat(m->content->get_type()); + auto can_be_paid = get_invoice_message_info({dialog_id, m->message_id}).is_ok(); + auto can_be_pinned = can_pin_message(dialog_id, m).is_ok(); + auto can_be_replied = + message_id.is_valid() && !(message_id == MessageId(ServerMessageId(1)) && dialog_type == DialogType::Channel) && + !m->message_id.is_yet_unsent() && (!m->message_id.is_local() || dialog_type == DialogType::SecretChat) && + (dialog_type != DialogType::Chat || td_->chat_manager_->get_chat_is_active(dialog_id.get_chat_id())) && + can_send_message(dialog_id).is_ok(); + auto can_be_replied_in_another_chat = can_be_forwarded && m->message_id.is_server(); + auto can_be_shared_in_story = can_share_message_in_story(dialog_id, m); + auto can_edit_scheduling_state = m->message_id.is_valid_scheduled() && m->message_id.is_scheduled_server(); + auto can_get_statistics = can_get_message_statistics(dialog_id, m); + auto can_get_message_thread = get_top_thread_message_full_id(dialog_id, m, false).is_ok(); + auto can_get_read_date = can_get_message_read_date(dialog_id, m).is_ok(); + auto can_get_viewers = can_get_message_viewers(dialog_id, m).is_ok(); + auto can_get_media_timestamp_links = can_get_media_timestamp_link(dialog_id, m).is_ok(); + auto can_get_link = can_get_media_timestamp_links && dialog_type == DialogType::Channel; + auto can_get_embedding_code = can_get_message_embedding_code(dialog_id, m).is_ok(); + auto can_recognize_speech = can_recognize_message_speech(dialog_id, m); + auto can_report_chat = + td_->dialog_manager_->can_report_dialog(dialog_id) && can_report_message(m->message_id).is_ok(); + auto can_report_reactions = can_report_message_reactions(dialog_id, m); + auto can_report_supergroup_spam = + dialog_id.get_type() == DialogType::Channel && + td_->chat_manager_->is_megagroup_channel(dialog_id.get_channel_id()) && + td_->chat_manager_->get_channel_status(dialog_id.get_channel_id()).is_administrator() && + can_report_message(m->message_id).is_ok(); + auto can_set_fact_check = can_set_message_fact_check(dialog_id, m); + auto need_show_statistics = can_get_statistics && (m->view_count >= 100 || m->forward_count > 0); + promise.set_value(td_api::make_object( + can_be_copied_to_secret_chat, can_delete_for_self, can_delete_for_all_users, can_be_edited, can_be_forwarded, + can_be_paid, can_be_pinned, can_be_replied, can_be_replied_in_another_chat, can_be_saved, can_be_shared_in_story, + can_edit_scheduling_state, can_get_embedding_code, can_get_link, can_get_media_timestamp_links, + can_get_message_thread, can_get_read_date, can_get_statistics, can_get_viewers, can_recognize_speech, + can_report_chat, can_report_reactions, can_report_supergroup_spam, can_set_fact_check, need_show_statistics)); +} + +bool MessagesManager::is_message_edited_recently(MessageFullId message_full_id, int32 seconds) { if (seconds < 0) { return false; } - if (!full_message_id.get_message_id().is_valid()) { + if (!message_full_id.get_message_id().is_valid()) { return false; } - auto m = get_message_force(full_message_id, "is_message_edited_recently"); + auto m = get_message_force(message_full_id, "is_message_edited_recently"); if (m == nullptr) { return true; } @@ -18442,18 +17485,45 @@ bool MessagesManager::is_message_edited_recently(FullMessageId full_message_id, return m->edit_date >= G()->unix_time() - seconds; } +MessagesManager::ReportDialogFromActionBar MessagesManager::report_dialog_from_action_bar(DialogId dialog_id, + Promise &promise) { + ReportDialogFromActionBar result; + Dialog *d = nullptr; + if (dialog_id.get_type() == DialogType::SecretChat) { + auto user_dialog_id = DialogId(td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id())); + d = get_dialog_force(user_dialog_id, "report_dialog_from_action_bar"); + if (d == nullptr) { + promise.set_error(Status::Error(400, "Chat with the user not found")); + result.is_reported_ = true; + return result; + } + } else { + d = get_dialog(dialog_id); + CHECK(d != nullptr); + } + result.know_action_bar_ = d->know_action_bar; + + if (d->know_action_bar && d->action_bar != nullptr && d->action_bar->can_report_spam()) { + result.is_reported_ = true; + hide_dialog_action_bar(d); + toggle_dialog_report_spam_state_on_server(dialog_id, true, 0, std::move(promise)); + } + return result; +} + Status MessagesManager::can_get_media_timestamp_link(DialogId dialog_id, const Message *m) { if (m == nullptr) { return Status::Error(400, "Message not found"); } if (dialog_id.get_type() != DialogType::Channel) { - auto forward_info = m->forward_info.get(); - if (!can_message_content_have_media_timestamp(m->content.get()) || forward_info == nullptr || - forward_info->is_imported || is_forward_info_sender_hidden(forward_info) || - !forward_info->message_id.is_valid() || !m->forward_info->message_id.is_server() || - !forward_info->sender_dialog_id.is_valid() || - forward_info->sender_dialog_id.get_type() != DialogType::Channel) { + if (!can_message_content_have_media_timestamp(m->content.get()) || m->forward_info == nullptr || + m->forward_info->is_imported()) { + return Status::Error(400, "Message links are available only for messages in supergroups and channel chats"); + } + auto origin_message_full_id = m->forward_info->get_origin_message_full_id(); + auto origin_message_id = origin_message_full_id.get_message_id(); + if (!origin_message_id.is_valid() || !origin_message_id.is_server()) { return Status::Error(400, "Message links are available only for messages in supergroups and channel chats"); } return Status::OK(); @@ -18471,13 +17541,26 @@ Status MessagesManager::can_get_media_timestamp_link(DialogId dialog_id, const M return Status::OK(); } +Status MessagesManager::can_report_message(MessageId message_id) { + if (message_id.is_valid_scheduled()) { + return Status::Error(400, "Can't report scheduled messages"); + } + if (message_id.is_valid_sponsored()) { + return Status::Error(400, "Can't report sponsored messages"); + } + if (!message_id.is_valid()) { + return Status::Error(400, "Message not found"); + } + if (!message_id.is_server()) { + return Status::Error(400, "Message can't be reported"); + } + return Status::OK(); +} + bool MessagesManager::can_report_message_reactions(DialogId dialog_id, const Message *m) const { CHECK(m != nullptr); - if (dialog_id.get_type() != DialogType::Channel || is_broadcast_channel(dialog_id) || - !td_->contacts_manager_->is_channel_public(dialog_id.get_channel_id())) { - return false; - } - if (m->message_id.is_scheduled() || !m->message_id.is_server()) { + if (dialog_id.get_type() != DialogType::Channel || td_->dialog_manager_->is_broadcast_channel(dialog_id) || + !td_->chat_manager_->is_channel_public(dialog_id.get_channel_id())) { return false; } if (m->message_id.is_scheduled() || !m->message_id.is_server()) { @@ -18490,41 +17573,64 @@ bool MessagesManager::can_report_message_reactions(DialogId dialog_id, const Mes return true; } -Result> MessagesManager::get_message_link(FullMessageId full_message_id, int32 media_timestamp, - bool for_group, bool in_message_thread) { - auto dialog_id = full_message_id.get_dialog_id(); - auto d = get_dialog_force(dialog_id, "get_message_link"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); +bool MessagesManager::can_recognize_message_speech(DialogId dialog_id, const Message *m) const { + if (td_->auth_manager_->is_bot() || m == nullptr || !m->message_id.is_valid() || !m->message_id.is_server() || + dialog_id.get_type() == DialogType::SecretChat) { + return false; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); + auto content_type = m->content->get_type(); + if (content_type != MessageContentType::VideoNote && content_type != MessageContentType::VoiceNote) { + return false; } + return true; +} - auto *m = get_message_force(d, full_message_id.get_message_id(), "get_message_link"); - TRY_STATUS(can_get_media_timestamp_link(dialog_id, m)); - - if (media_timestamp <= 0 || !can_message_content_have_media_timestamp(m->content.get())) { - media_timestamp = 0; +bool MessagesManager::can_set_message_fact_check(DialogId dialog_id, const Message *m) const { + if (!td_->option_manager_->get_option_boolean("can_edit_fact_check")) { + return false; } - if (media_timestamp != 0) { - for_group = false; - auto duration = get_message_content_media_duration(m->content.get(), td_); - if (duration != 0 && media_timestamp > duration) { - media_timestamp = 0; - } + if (td_->auth_manager_->is_bot() || m == nullptr || !m->message_id.is_valid() || !m->message_id.is_server() || + !td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + return false; } + auto content_type = m->content->get_type(); + switch (content_type) { + case MessageContentType::Animation: + case MessageContentType::Audio: + case MessageContentType::Document: + case MessageContentType::Photo: + case MessageContentType::Text: + case MessageContentType::Video: + // ok + break; + default: + return false; + } + return true; +} + +Result> MessagesManager::get_message_link(MessageFullId message_full_id, int32 media_timestamp, + bool for_group, bool in_message_thread) { + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "get_message_link")); + + auto *m = get_message_force(d, message_full_id.get_message_id(), "get_message_link"); + TRY_STATUS(can_get_media_timestamp_link(dialog_id, m)); auto message_id = m->message_id; if (dialog_id.get_type() != DialogType::Channel) { + if (media_timestamp == 0) { + return Status::Error(400, "Message can't have link"); + } CHECK(m->forward_info != nullptr); - CHECK(m->forward_info->sender_dialog_id.get_type() == DialogType::Channel); - dialog_id = m->forward_info->sender_dialog_id; - message_id = m->forward_info->message_id; + auto origin_message_full_id = m->forward_info->get_origin_message_full_id(); + dialog_id = origin_message_full_id.get_dialog_id(); + message_id = origin_message_full_id.get_message_id(); + CHECK(dialog_id.get_type() == DialogType::Channel); for_group = false; in_message_thread = false; - auto channel_message = get_message({dialog_id, message_id}); + auto channel_message = get_message(origin_message_full_id); if (channel_message != nullptr && channel_message->media_album_id == 0) { for_group = true; // default is true } @@ -18533,10 +17639,21 @@ Result> MessagesManager::get_message_link(FullMessageId for_group = true; // default is true } } + if (media_timestamp <= 0 || !can_message_content_have_media_timestamp(m->content.get())) { + media_timestamp = 0; + } + if (media_timestamp != 0) { + for_group = false; + auto duration = get_message_content_media_duration(m->content.get(), td_); + if (duration != 0 && media_timestamp > duration) { + media_timestamp = 0; + } + } - bool is_forum = is_forum_channel(dialog_id); - if (!is_forum && (!m->top_thread_message_id.is_valid() || !m->top_thread_message_id.is_server() || - is_deleted_message(d, m->top_thread_message_id) || is_broadcast_channel(dialog_id))) { + bool is_forum = td_->dialog_manager_->is_forum_channel(dialog_id); + if (in_message_thread && !is_forum && + (!m->top_thread_message_id.is_valid() || !m->top_thread_message_id.is_server() || + is_deleted_message(d, m->top_thread_message_id) || td_->dialog_manager_->is_broadcast_channel(dialog_id))) { in_message_thread = false; } @@ -18550,17 +17667,20 @@ Result> MessagesManager::get_message_link(FullMessageId if (in_message_thread && !is_forum) { // try to generate a comment link + CHECK(dialog_id == d->dialog_id); auto *top_m = get_message_force(d, m->top_thread_message_id, "get_public_message_link"); if (is_discussion_message(dialog_id, top_m) && is_active_message_reply_info(dialog_id, top_m->reply_info)) { - auto linked_dialog_id = top_m->forward_info->from_dialog_id; - auto linked_message_id = top_m->forward_info->from_message_id; + auto linked_message_full_id = top_m->forward_info->get_last_message_full_id(); + auto linked_dialog_id = linked_message_full_id.get_dialog_id(); + auto linked_message_id = linked_message_full_id.get_message_id(); auto linked_d = get_dialog(linked_dialog_id); CHECK(linked_d != nullptr); CHECK(linked_dialog_id.get_type() == DialogType::Channel); auto *linked_m = get_message_force(linked_d, linked_message_id, "get_public_message_link"); - auto channel_username = td_->contacts_manager_->get_channel_first_username(linked_dialog_id.get_channel_id()); + auto channel_username = td_->chat_manager_->get_channel_first_username(linked_dialog_id.get_channel_id()); if (linked_m != nullptr && is_active_message_reply_info(linked_dialog_id, linked_m->reply_info) && - linked_message_id.is_server() && have_input_peer(linked_dialog_id, AccessRights::Read) && + linked_message_id.is_server() && + td_->dialog_manager_->have_input_peer(linked_dialog_id, false, AccessRights::Read) && !channel_username.empty()) { sb << channel_username << '/' << linked_message_id.get_server_message_id().get() << "?comment=" << message_id.get_server_message_id().get(); @@ -18575,9 +17695,10 @@ Result> MessagesManager::get_message_link(FullMessageId } } - auto dialog_username = td_->contacts_manager_->get_channel_first_username(dialog_id.get_channel_id()); + auto dialog_username = td_->chat_manager_->get_channel_first_username(dialog_id.get_channel_id()); bool is_public = !dialog_username.empty(); - if (m->content->get_type() == MessageContentType::VideoNote && is_broadcast_channel(dialog_id) && is_public) { + if (m->content->get_type() == MessageContentType::VideoNote && + td_->dialog_manager_->is_broadcast_channel(dialog_id) && is_public) { return std::make_pair( PSTRING() << "https://telesco.pe/" << dialog_username << '/' << message_id.get_server_message_id().get(), true); } @@ -18609,44 +17730,45 @@ Result> MessagesManager::get_message_link(FullMessageId sb << separator << "t=" << media_timestamp; separator = '&'; } + CHECK(separator == '?' || separator == '&'); return std::make_pair(sb.as_cslice().str(), is_public); } -string MessagesManager::get_message_embedding_code(FullMessageId full_message_id, bool for_group, - Promise &&promise) { - auto dialog_id = full_message_id.get_dialog_id(); - auto d = get_dialog_force(dialog_id, "get_message_embedding_code"); - if (d == nullptr) { - promise.set_error(Status::Error(400, "Chat not found")); - return {}; - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - promise.set_error(Status::Error(400, "Can't access the chat")); - return {}; - } +Status MessagesManager::can_get_message_embedding_code(DialogId dialog_id, const Message *m) const { if (dialog_id.get_type() != DialogType::Channel || - td_->contacts_manager_->get_channel_first_username(dialog_id.get_channel_id()).empty()) { - promise.set_error(Status::Error( - 400, "Message embedding code is available only for messages in public supergroups and channel chats")); - return {}; + td_->chat_manager_->get_channel_first_username(dialog_id.get_channel_id()).empty()) { + return Status::Error( + 400, "Message embedding code is available only for messages in public supergroups and channel chats"); } - - auto *m = get_message_force(d, full_message_id.get_message_id(), "get_message_embedding_code"); if (m == nullptr) { - promise.set_error(Status::Error(400, "Message not found")); - return {}; + return Status::Error(400, "Message not found"); } if (m->message_id.is_yet_unsent()) { - promise.set_error(Status::Error(400, "Message is not sent yet")); - return {}; + return Status::Error(400, "Message is not sent yet"); } if (m->message_id.is_scheduled()) { - promise.set_error(Status::Error(400, "Message is scheduled")); - return {}; + return Status::Error(400, "Message is scheduled"); } if (!m->message_id.is_server()) { - promise.set_error(Status::Error(400, "Message is local")); + return Status::Error(400, "Message is local"); + } + return Status::OK(); +} + +string MessagesManager::get_message_embedding_code(MessageFullId message_full_id, bool for_group, + Promise &&promise) { + auto dialog_id = message_full_id.get_dialog_id(); + auto r_d = check_dialog_access(dialog_id, false, AccessRights::Read, "get_message_embedding_code"); + if (r_d.is_error()) { + promise.set_error(r_d.move_as_error()); + return {}; + } + auto d = r_d.move_as_ok(); + auto *m = get_message_force(d, message_full_id.get_message_id(), "get_message_embedding_code"); + auto status = can_get_message_embedding_code(dialog_id, m); + if (status.is_error()) { + promise.set_error(std::move(status)); return {}; } @@ -18666,11 +17788,11 @@ string MessagesManager::get_message_embedding_code(FullMessageId full_message_id return it->second; } -void MessagesManager::on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url, +void MessagesManager::on_get_public_message_link(MessageFullId message_full_id, bool for_group, string url, string html) { - LOG_IF(ERROR, url.empty() && html.empty()) << "Receive empty public link for " << full_message_id; - auto dialog_id = full_message_id.get_dialog_id(); - auto message_id = full_message_id.get_message_id(); + LOG_IF(ERROR, url.empty() && html.empty()) << "Receive empty public link for " << message_full_id; + auto dialog_id = message_full_id.get_dialog_id(); + auto message_id = message_full_id.get_message_id(); message_embedding_codes_[for_group][dialog_id].embedding_codes_[message_id] = std::move(html); } @@ -18681,53 +17803,24 @@ void MessagesManager::get_message_link_info(Slice url, Promise } auto info = r_message_link_info.move_as_ok(); - CHECK(info.username.empty() == info.channel_id.is_valid()); - - bool have_dialog = info.username.empty() ? td_->contacts_manager_->have_channel_force(info.channel_id) - : resolve_dialog_username(info.username).is_valid(); - if (!have_dialog) { - auto query_promise = PromiseCreator::lambda( - [actor_id = actor_id(this), info, promise = std::move(promise)](Result &&result) mutable { - if (result.is_error()) { - return promise.set_value(std::move(info)); - } - send_closure(actor_id, &MessagesManager::on_get_message_link_dialog, std::move(info), std::move(promise)); - }); - if (info.username.empty()) { - td_->contacts_manager_->reload_channel(info.channel_id, std::move(query_promise)); - } else { - td_->create_handler(std::move(query_promise))->send(info.username); - } - return; - } - - return on_get_message_link_dialog(std::move(info), std::move(promise)); + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), info, promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + return promise.set_value(std::move(info)); + } + send_closure(actor_id, &MessagesManager::on_get_message_link_dialog, std::move(info), result.ok(), + std::move(promise)); + }); + td_->dialog_manager_->resolve_dialog(info.username, info.channel_id, std::move(query_promise)); } -void MessagesManager::on_get_message_link_dialog(MessageLinkInfo &&info, Promise &&promise) { +void MessagesManager::on_get_message_link_dialog(MessageLinkInfo &&info, DialogId dialog_id, + Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); - DialogId dialog_id; - if (info.username.empty()) { - if (!td_->contacts_manager_->have_channel(info.channel_id)) { - return promise.set_error(Status::Error(500, "Chat info not found")); - } - - dialog_id = DialogId(info.channel_id); - force_create_dialog(dialog_id, "on_get_message_link_dialog"); - } else { - dialog_id = resolve_dialog_username(info.username); - if (dialog_id.is_valid()) { - force_create_dialog(dialog_id, "on_get_message_link_dialog", true); - } - } Dialog *d = get_dialog_force(dialog_id, "on_get_message_link_dialog"); - if (d == nullptr) { - return promise.set_error(Status::Error(500, "Chat not found")); - } - - auto message_id = info.message_id; - get_message_force_from_server(d, message_id, + CHECK(d != nullptr); + get_message_force_from_server(d, info.message_id, PromiseCreator::lambda([actor_id = actor_id(this), info = std::move(info), dialog_id, promise = std::move(promise)](Result &&result) mutable { if (result.is_error()) { @@ -18744,12 +17837,13 @@ void MessagesManager::on_get_message_link_message(MessageLinkInfo &&info, Dialog auto message_id = info.message_id; Message *m = get_message_force({dialog_id, message_id}, "on_get_message_link_message"); - if (info.comment_message_id == MessageId() || m == nullptr || !is_broadcast_channel(dialog_id) || - !m->reply_info.is_comment_ || !is_active_message_reply_info(dialog_id, m->reply_info)) { + if (info.comment_message_id == MessageId() || m == nullptr || + !td_->dialog_manager_->is_broadcast_channel(dialog_id) || !m->reply_info.is_comment_ || + !is_active_message_reply_info(dialog_id, m->reply_info)) { return promise.set_value(std::move(info)); } - if (td_->contacts_manager_->have_channel_force(m->reply_info.channel_id_)) { + if (td_->chat_manager_->have_channel_force(m->reply_info.channel_id_, "on_get_message_link_message")) { force_create_dialog(DialogId(m->reply_info.channel_id_), "on_get_message_link_message"); on_get_message_link_discussion_message(std::move(info), DialogId(m->reply_info.channel_id_), std::move(promise)); return; @@ -18795,7 +17889,8 @@ td_api::object_ptr MessagesManager::get_message_link_in bool is_public = !info.username.empty(); DialogId dialog_id = info.comment_dialog_id.is_valid() ? info.comment_dialog_id - : (is_public ? resolve_dialog_username(info.username) : DialogId(info.channel_id)); + : (is_public ? td_->dialog_manager_->get_resolved_dialog_by_username(info.username) + : DialogId(info.channel_id)); MessageId top_thread_message_id; MessageId message_id = info.comment_dialog_id.is_valid() ? info.comment_message_id : info.message_id; td_api::object_ptr message; @@ -18813,7 +17908,8 @@ td_api::object_ptr MessagesManager::get_message_link_in for_album = !info.is_single && m->media_album_id != 0; if (info.comment_dialog_id.is_valid() || info.for_comment || m->is_topic_message) { top_thread_message_id = m->top_thread_message_id; - } else if (is_forum_channel(dialog_id) && info.top_thread_message_id == MessageId(ServerMessageId(1))) { + } else if (td_->dialog_manager_->is_forum_channel(dialog_id) && + info.top_thread_message_id == MessageId(ServerMessageId(1))) { // General topic top_thread_message_id = info.top_thread_message_id; } else { @@ -18831,7 +17927,7 @@ td_api::object_ptr MessagesManager::get_message_link_in CHECK(media_timestamp == 0); } } else if (!info.comment_dialog_id.is_valid() && dialog_id.get_type() == DialogType::Channel && - !is_broadcast_channel(dialog_id)) { + !td_->dialog_manager_->is_broadcast_channel(dialog_id)) { top_thread_message_id = info.top_thread_message_id; } } @@ -18841,27 +17937,11 @@ td_api::object_ptr MessagesManager::get_message_link_in for_album); } -InputDialogId MessagesManager::get_input_dialog_id(DialogId dialog_id) const { - auto input_peer = get_input_peer(dialog_id, AccessRights::Read); - if (input_peer == nullptr || input_peer->get_id() == telegram_api::inputPeerSelf::ID || - input_peer->get_id() == telegram_api::inputPeerEmpty::ID) { - return InputDialogId(dialog_id); - } else { - return InputDialogId(input_peer); - } -} - Status MessagesManager::can_add_dialog_to_filter(DialogId dialog_id) { if (!dialog_id.is_valid()) { return Status::Error(400, "Invalid chat identifier specified"); } - const Dialog *d = get_dialog_force(dialog_id, "can_add_dialog_to_filter"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); - } + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "can_add_dialog_to_filter")); if (d->order == DEFAULT_ORDER) { return Status::Error(400, "Chat is not in the chat list"); } @@ -18937,7 +18017,7 @@ Status MessagesManager::set_dialog_draft_message(DialogId dialog_id, MessageId t } TRY_STATUS(can_send_message(dialog_id)); - TRY_STATUS(can_use_top_thread_message_id(d, top_thread_message_id, MessageId())); + TRY_STATUS(can_use_top_thread_message_id(d, top_thread_message_id, MessageInputReplyTo())); TRY_RESULT(new_draft_message, DraftMessage::get_draft_message(td_, dialog_id, top_thread_message_id, std::move(draft_message))); @@ -18959,7 +18039,7 @@ Status MessagesManager::set_dialog_draft_message(DialogId dialog_id, MessageId t } if (update_dialog_draft_message(d, std::move(new_draft_message), false, true)) { - if (dialog_id.get_type() != DialogType::SecretChat) { + if (dialog_id.get_type() != DialogType::SecretChat && !is_local_draft_message(d->draft_message)) { if (G()->use_message_database()) { SaveDialogDraftMessageOnServerLogEvent log_event; log_event.dialog_id_ = dialog_id; @@ -19034,23 +18114,12 @@ int32 MessagesManager::get_pinned_dialogs_limit(DialogListId dialog_list_id) con return limit; } -vector MessagesManager::remove_secret_chat_dialog_ids(vector dialog_ids) { - td::remove_if(dialog_ids, [](DialogId dialog_id) { return dialog_id.get_type() == DialogType::SecretChat; }); - return dialog_ids; -} - Status MessagesManager::toggle_dialog_is_pinned(DialogListId dialog_list_id, DialogId dialog_id, bool is_pinned) { if (td_->auth_manager_->is_bot()) { return Status::Error(400, "Bots can't change chat pin state"); } - Dialog *d = get_dialog_force(dialog_id, "toggle_dialog_is_pinned"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); - } + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "toggle_dialog_is_pinned")); if (d->order == DEFAULT_ORDER && is_pinned) { return Status::Error(400, "The chat can't be pinned"); } @@ -19069,8 +18138,8 @@ Status MessagesManager::toggle_dialog_is_pinned(DialogListId dialog_list_id, Dia } if (dialog_list_id.is_filter()) { - return td_->dialog_filter_manager_->set_dialog_is_pinned(dialog_list_id.get_filter_id(), - get_input_dialog_id(dialog_id), is_pinned); + return td_->dialog_filter_manager_->set_dialog_is_pinned( + dialog_list_id.get_filter_id(), td_->dialog_manager_->get_input_dialog_id(dialog_id), is_pinned); } CHECK(dialog_list_id.is_folder()); @@ -19144,6 +18213,52 @@ void MessagesManager::toggle_dialog_is_pinned_on_server(DialogId dialog_id, bool td_->create_handler(get_erase_log_event_promise(log_event_id))->send(dialog_id, is_pinned); } +bool MessagesManager::set_folder_pinned_dialogs(FolderId folder_id, vector old_dialog_ids, + vector new_dialog_ids) { + LOG(INFO) << "Reorder pinned chats in " << folder_id << " from " << old_dialog_ids << " to " << new_dialog_ids; + + std::reverse(old_dialog_ids.begin(), old_dialog_ids.end()); + std::reverse(new_dialog_ids.begin(), new_dialog_ids.end()); + + FlatHashSet all_old_pinned_dialog_ids; + for (auto dialog_id : old_dialog_ids) { + CHECK(dialog_id.is_valid()); + all_old_pinned_dialog_ids.insert(dialog_id); + } + + bool are_pinned_dialogs_saved = false; + auto old_it = old_dialog_ids.begin(); + for (auto dialog_id : new_dialog_ids) { + all_old_pinned_dialog_ids.erase(dialog_id); + while (old_it < old_dialog_ids.end()) { + if (*old_it == dialog_id) { + break; + } + ++old_it; + } + if (old_it < old_dialog_ids.end()) { + // leave dialog where it is + ++old_it; + continue; + } + if (set_dialog_is_pinned(dialog_id, true)) { + are_pinned_dialogs_saved = true; + } + } + for (auto dialog_id : all_old_pinned_dialog_ids) { + Dialog *d = get_dialog_force(dialog_id, "set_folder_pinned_dialogs 1"); + if (d == nullptr) { + LOG(ERROR) << "Failed to find " << dialog_id << " to unpin in " << folder_id; + force_create_dialog(dialog_id, "set_folder_pinned_dialogs 2", true); + d = get_dialog_force(dialog_id, "set_folder_pinned_dialogs 3"); + } + if (d != nullptr && set_dialog_is_pinned(DialogListId(folder_id), d, false)) { + are_pinned_dialogs_saved = true; + } + } + return are_pinned_dialogs_saved; +} + Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vector dialog_ids) { if (td_->auth_manager_->is_bot()) { return Status::Error(400, "Bots can't reorder pinned chats"); @@ -19154,13 +18269,7 @@ Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vector new_pinned_dialog_ids; for (auto dialog_id : dialog_ids) { - Dialog *d = get_dialog_force(dialog_id, "set_pinned_dialogs"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); - } + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "set_pinned_dialogs")); if (d->order == DEFAULT_ORDER) { return Status::Error(400, "The chat can't be pinned"); } @@ -19195,57 +18304,23 @@ Status MessagesManager::set_pinned_dialogs(DialogListId dialog_list_id, vectordialog_filter_manager_->set_pinned_dialog_ids( dialog_list_id.get_filter_id(), - transform(dialog_ids, [this](DialogId dialog_id) { return get_input_dialog_id(dialog_id); }), + transform(dialog_ids, + [this](DialogId dialog_id) { return td_->dialog_manager_->get_input_dialog_id(dialog_id); }), server_old_dialog_ids != server_new_dialog_ids); } - CHECK(dialog_list_id.is_folder()); - - std::reverse(pinned_dialog_ids.begin(), pinned_dialog_ids.end()); - std::reverse(dialog_ids.begin(), dialog_ids.end()); - - FlatHashSet old_pinned_dialog_ids; - for (auto dialog_id : pinned_dialog_ids) { - old_pinned_dialog_ids.insert(dialog_id); - } - auto old_it = pinned_dialog_ids.begin(); - for (auto dialog_id : dialog_ids) { - old_pinned_dialog_ids.erase(dialog_id); - while (old_it < pinned_dialog_ids.end()) { - if (*old_it == dialog_id) { - break; - } - ++old_it; - } - if (old_it < pinned_dialog_ids.end()) { - // leave dialog where it is - ++old_it; - continue; - } - set_dialog_is_pinned(dialog_id, true); - } - for (auto dialog_id : old_pinned_dialog_ids) { - Dialog *d = get_dialog_force(dialog_id, "set_pinned_dialogs 2"); - if (d == nullptr) { - LOG(ERROR) << "Failed to find " << dialog_id << " to unpin in " << dialog_list_id; - force_create_dialog(dialog_id, "set_pinned_dialogs", true); - d = get_dialog_force(dialog_id, "set_pinned_dialogs 3"); - } - if (d != nullptr) { - set_dialog_is_pinned(dialog_list_id, d, false); - } - } + auto folder_id = dialog_list_id.get_folder_id(); + set_folder_pinned_dialogs(folder_id, std::move(pinned_dialog_ids), std::move(dialog_ids)); if (server_old_dialog_ids != server_new_dialog_ids) { - reorder_pinned_dialogs_on_server(dialog_list_id.get_folder_id(), server_new_dialog_ids, 0); + reorder_pinned_dialogs_on_server(folder_id, server_new_dialog_ids, 0); } return Status::OK(); } @@ -19289,15 +18364,68 @@ void MessagesManager::reorder_pinned_dialogs_on_server(FolderId folder_id, const ->send(folder_id, dialog_ids); } -Status MessagesManager::toggle_dialog_is_marked_as_unread(DialogId dialog_id, bool is_marked_as_unread) { - Dialog *d = get_dialog_force(dialog_id, "toggle_dialog_is_marked_as_unread"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); +Status MessagesManager::toggle_dialog_view_as_messages(DialogId dialog_id, bool view_as_messages) { + TRY_RESULT(d, check_dialog_access(dialog_id, false, AccessRights::Read, "toggle_dialog_view_as_messages")); + bool is_saved_messages = dialog_id == td_->dialog_manager_->get_my_dialog_id(); + if (!is_saved_messages && !td_->dialog_manager_->is_forum_channel(dialog_id)) { + return Status::Error(400, "The method is available only in forum channels"); } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); + + if (view_as_messages == d->view_as_messages) { + return Status::OK(); + } + + set_dialog_view_as_messages(d, view_as_messages, "toggle_dialog_view_as_messages"); + + if (!is_saved_messages) { + toggle_dialog_view_as_messages_on_server(dialog_id, view_as_messages, 0); + } + return Status::OK(); +} + +class MessagesManager::ToggleDialogViewAsMessagesOnServerLogEvent { + public: + DialogId dialog_id_; + bool view_as_messages_; + + template + void store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + STORE_FLAG(view_as_messages_); + END_STORE_FLAGS(); + + td::store(dialog_id_, storer); + } + + template + void parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(view_as_messages_); + END_PARSE_FLAGS(); + + td::parse(dialog_id_, parser); } +}; +uint64 MessagesManager::save_toggle_dialog_view_as_messages_on_server_log_event(DialogId dialog_id, + bool view_as_messages) { + ToggleDialogViewAsMessagesOnServerLogEvent log_event{dialog_id, view_as_messages}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::ToggleDialogViewAsMessagesOnServer, + get_log_event_storer(log_event)); +} + +void MessagesManager::toggle_dialog_view_as_messages_on_server(DialogId dialog_id, bool view_as_messages, + uint64 log_event_id) { + if (log_event_id == 0 && G()->use_message_database()) { + log_event_id = save_toggle_dialog_view_as_messages_on_server_log_event(dialog_id, view_as_messages); + } + + td_->create_handler(get_erase_log_event_promise(log_event_id)) + ->send(dialog_id, view_as_messages); +} + +Status MessagesManager::toggle_dialog_is_marked_as_unread(DialogId dialog_id, bool is_marked_as_unread) { + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "toggle_dialog_is_marked_as_unread")); if (is_marked_as_unread == d->is_marked_as_unread) { return Status::OK(); } @@ -19355,17 +18483,7 @@ void MessagesManager::toggle_dialog_is_marked_as_unread_on_server(DialogId dialo } Status MessagesManager::toggle_dialog_is_translatable(DialogId dialog_id, bool is_translatable) { - Dialog *d = get_dialog_force(dialog_id, "toggle_dialog_is_translatable"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); - } - if (!td_->option_manager_->get_option_boolean("is_premium")) { - return Status::Error(400, "The method is available to Telegram Premium users only"); - } - + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "toggle_dialog_is_translatable")); if (is_translatable == d->is_translatable) { return Status::OK(); } @@ -19422,13 +18540,17 @@ void MessagesManager::toggle_dialog_is_translatable_on_server(DialogId dialog_id ->send(dialog_id, is_translatable); } -Status MessagesManager::toggle_message_sender_is_blocked(const td_api::object_ptr &sender, - bool is_blocked) { +Status MessagesManager::set_message_sender_block_list(const td_api::object_ptr &sender, + const td_api::object_ptr &block_list) { TRY_RESULT(dialog_id, get_message_sender_dialog_id(td_, sender, true, false)); + BlockListId block_list_id(block_list); + bool is_blocked = block_list_id == BlockListId::main(); + bool is_blocked_for_stories = block_list_id == BlockListId::stories(); switch (dialog_id.get_type()) { case DialogType::User: - if (dialog_id == get_my_dialog_id()) { - return Status::Error(400, is_blocked ? Slice("Can't block self") : Slice("Can't unblock self")); + if (dialog_id == td_->dialog_manager_->get_my_dialog_id()) { + return Status::Error( + 400, is_blocked || is_blocked_for_stories ? Slice("Can't block self") : Slice("Can't unblock self")); } break; case DialogType::Chat: @@ -19437,8 +18559,8 @@ Status MessagesManager::toggle_message_sender_is_blocked(const td_api::object_pt // ok break; case DialogType::SecretChat: { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); - if (!user_id.is_valid() || !td_->contacts_manager_->have_user_force(user_id)) { + auto user_id = td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + if (!user_id.is_valid() || !td_->user_manager_->have_user_force(user_id, "set_message_sender_block_list")) { return Status::Error(400, "The secret chat can't be blocked"); } dialog_id = DialogId(user_id); @@ -19449,21 +18571,21 @@ Status MessagesManager::toggle_message_sender_is_blocked(const td_api::object_pt UNREACHABLE(); } - Dialog *d = get_dialog_force(dialog_id, "toggle_message_sender_is_blocked"); - if (!have_input_peer(dialog_id, AccessRights::Know)) { + Dialog *d = get_dialog_force(dialog_id, "set_message_sender_block_list"); + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Know)) { return Status::Error(400, "Message sender isn't accessible"); } if (d != nullptr) { - if (is_blocked == d->is_blocked) { + if (is_blocked == d->is_blocked && is_blocked_for_stories == d->is_blocked_for_stories) { return Status::OK(); } - set_dialog_is_blocked(d, is_blocked); + set_dialog_is_blocked(d, is_blocked, is_blocked_for_stories); } else { CHECK(dialog_id.get_type() == DialogType::User); - td_->contacts_manager_->on_update_user_is_blocked(dialog_id.get_user_id(), is_blocked); + td_->user_manager_->on_update_user_is_blocked(dialog_id.get_user_id(), is_blocked, is_blocked_for_stories); } - toggle_dialog_is_blocked_on_server(dialog_id, is_blocked, 0); + toggle_dialog_is_blocked_on_server(dialog_id, is_blocked, is_blocked_for_stories, 0); return Status::OK(); } @@ -19471,11 +18593,13 @@ class MessagesManager::ToggleDialogIsBlockedOnServerLogEvent { public: DialogId dialog_id_; bool is_blocked_; + bool is_blocked_for_stories_; template void store(StorerT &storer) const { BEGIN_STORE_FLAGS(); STORE_FLAG(is_blocked_); + STORE_FLAG(is_blocked_for_stories_); END_STORE_FLAGS(); td::store(dialog_id_, storer); @@ -19485,37 +18609,34 @@ class MessagesManager::ToggleDialogIsBlockedOnServerLogEvent { void parse(ParserT &parser) { BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_blocked_); + PARSE_FLAG(is_blocked_for_stories_); END_PARSE_FLAGS(); td::parse(dialog_id_, parser); } }; -uint64 MessagesManager::save_toggle_dialog_is_blocked_on_server_log_event(DialogId dialog_id, bool is_blocked) { - ToggleDialogIsBlockedOnServerLogEvent log_event{dialog_id, is_blocked}; +uint64 MessagesManager::save_toggle_dialog_is_blocked_on_server_log_event(DialogId dialog_id, bool is_blocked, + bool is_blocked_for_stories) { + ToggleDialogIsBlockedOnServerLogEvent log_event{dialog_id, is_blocked, is_blocked_for_stories}; return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::ToggleDialogIsBlockedOnServer, get_log_event_storer(log_event)); } -void MessagesManager::toggle_dialog_is_blocked_on_server(DialogId dialog_id, bool is_blocked, uint64 log_event_id) { +void MessagesManager::toggle_dialog_is_blocked_on_server(DialogId dialog_id, bool is_blocked, + bool is_blocked_for_stories, uint64 log_event_id) { if (log_event_id == 0 && G()->use_message_database()) { - log_event_id = save_toggle_dialog_is_blocked_on_server_log_event(dialog_id, is_blocked); + log_event_id = save_toggle_dialog_is_blocked_on_server_log_event(dialog_id, is_blocked, is_blocked_for_stories); } td_->create_handler(get_erase_log_event_promise(log_event_id)) - ->send(dialog_id, is_blocked); + ->send(dialog_id, is_blocked, is_blocked_for_stories); } Status MessagesManager::toggle_dialog_silent_send_message(DialogId dialog_id, bool silent_send_message) { CHECK(!td_->auth_manager_->is_bot()); - Dialog *d = get_dialog_force(dialog_id, "toggle_dialog_silent_send_message"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); - } + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "toggle_dialog_silent_send_message")); if (update_dialog_silent_send_message(d, silent_send_message)) { update_dialog_notification_settings_on_server(dialog_id, false); @@ -19610,7 +18731,7 @@ int32 MessagesManager::get_dialog_mute_until(const Dialog *d) const { CHECK(!td_->auth_manager_->is_bot()); CHECK(d != nullptr); if (d->notification_settings.use_default_mute_until) { - auto scope = get_dialog_notification_setting_scope(d->dialog_id); + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(d->dialog_id); return td_->notification_settings_manager_->get_scope_mute_until(scope); } else { return d->notification_settings.mute_until; @@ -19625,7 +18746,7 @@ bool MessagesManager::is_dialog_pinned_message_notifications_disabled(const Dial CHECK(!td_->auth_manager_->is_bot()); CHECK(d != nullptr); if (d->notification_settings.use_default_disable_pinned_message_notifications) { - auto scope = get_dialog_notification_setting_scope(d->dialog_id); + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(d->dialog_id); return td_->notification_settings_manager_->get_scope_disable_pinned_message_notifications(scope); } @@ -19636,7 +18757,7 @@ bool MessagesManager::is_dialog_mention_notifications_disabled(const Dialog *d) CHECK(!td_->auth_manager_->is_bot()); CHECK(d != nullptr); if (d->notification_settings.use_default_disable_mention_notifications) { - auto scope = get_dialog_notification_setting_scope(d->dialog_id); + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(d->dialog_id); return td_->notification_settings_manager_->get_scope_disable_mention_notifications(scope); } @@ -19644,11 +18765,11 @@ bool MessagesManager::is_dialog_mention_notifications_disabled(const Dialog *d) } void MessagesManager::create_dialog(DialogId dialog_id, bool force, Promise &&promise) { - if (!have_input_peer(dialog_id, AccessRights::Read)) { - if (!have_dialog_info_force(dialog_id)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { + if (!td_->dialog_manager_->have_dialog_info_force(dialog_id, "create dialog")) { return promise.set_error(Status::Error(400, "Chat info not found")); } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return promise.set_error(Status::Error(400, "Can't access the chat")); } } @@ -19665,138 +18786,6 @@ void MessagesManager::create_dialog(DialogId dialog_id, bool force, Promise &user_ids, const string &title, - MessageTtl message_ttl, int64 &random_id, Promise &&promise) { - LOG(INFO) << "Trying to create group chat \"" << title << "\" with members " << format::as_array(user_ids); - - if (random_id != 0) { - // request has already been sent before - auto it = created_dialogs_.find(random_id); - CHECK(it != created_dialogs_.end()); - auto dialog_id = it->second; - CHECK(dialog_id.get_type() == DialogType::Chat); - CHECK(have_dialog(dialog_id)); - - created_dialogs_.erase(it); - - // set default notification settings to newly created chat - on_update_dialog_notify_settings(dialog_id, nullptr, "create_new_group_chat"); - - promise.set_value(Unit()); - return dialog_id; - } - - auto new_title = clean_name(title, MAX_TITLE_LENGTH); - if (new_title.empty()) { - promise.set_error(Status::Error(400, "Title must be non-empty")); - return DialogId(); - } - - vector> input_users; - for (auto user_id : user_ids) { - auto r_input_user = td_->contacts_manager_->get_input_user(user_id); - if (r_input_user.is_error()) { - promise.set_error(r_input_user.move_as_error()); - return DialogId(); - } - input_users.push_back(r_input_user.move_as_ok()); - } - - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || created_dialogs_.count(random_id) > 0); - created_dialogs_[random_id]; // reserve place for result - - td_->create_handler(std::move(promise)) - ->send(std::move(input_users), new_title, message_ttl, random_id); - return DialogId(); -} - -DialogId MessagesManager::create_new_channel_chat(const string &title, bool is_forum, bool is_megagroup, - const string &description, const DialogLocation &location, - bool for_import, MessageTtl message_ttl, int64 &random_id, - Promise &&promise) { - LOG(INFO) << "Trying to create " << (is_megagroup ? "supergroup" : "broadcast") << " with title \"" << title - << "\", description \"" << description << "\" and " << location; - - if (random_id != 0) { - // request has already been sent before - auto it = created_dialogs_.find(random_id); - CHECK(it != created_dialogs_.end()); - auto dialog_id = it->second; - CHECK(dialog_id.get_type() == DialogType::Channel); - CHECK(have_dialog(dialog_id)); - - created_dialogs_.erase(it); - - // set default notification settings to newly created chat - on_update_dialog_notify_settings(dialog_id, nullptr, "create_new_channel_chat"); - - promise.set_value(Unit()); - return dialog_id; - } - - auto new_title = clean_name(title, MAX_TITLE_LENGTH); - if (new_title.empty()) { - promise.set_error(Status::Error(400, "Title must be non-empty")); - return DialogId(); - } - - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || created_dialogs_.count(random_id) > 0); - created_dialogs_[random_id]; // reserve place for result - - td_->create_handler(std::move(promise)) - ->send(new_title, is_forum, is_megagroup, strip_empty_characters(description, MAX_DESCRIPTION_LENGTH), location, - for_import, message_ttl, random_id); - return DialogId(); -} - -void MessagesManager::create_new_secret_chat(UserId user_id, Promise &&promise) { - TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(user_id)); - if (input_user->get_id() != telegram_api::inputUser::ID) { - return promise.set_error(Status::Error(400, "Can't create secret chat with the user")); - } - auto user = static_cast(input_user.get()); - - send_closure(G()->secret_chats_manager(), &SecretChatsManager::create_chat, UserId(user->user_id_), - user->access_hash_, std::move(promise)); -} - -DialogId MessagesManager::migrate_dialog_to_megagroup(DialogId dialog_id, Promise &&promise) { - LOG(INFO) << "Trying to convert " << dialog_id << " to supergroup"; - - if (dialog_id.get_type() != DialogType::Chat) { - promise.set_error(Status::Error(400, "Only basic group chats can be converted to supergroup")); - return DialogId(); - } - - auto channel_id = td_->contacts_manager_->migrate_chat_to_megagroup(dialog_id.get_chat_id(), promise); - if (!channel_id.is_valid()) { - return DialogId(); - } - - if (!td_->contacts_manager_->have_channel(channel_id)) { - LOG(ERROR) << "Can't find info about supergroup to which the group has migrated"; - promise.set_error(Status::Error(400, "Supergroup is not found")); - return DialogId(); - } - - auto new_dialog_id = DialogId(channel_id); - Dialog *d = get_dialog_force(new_dialog_id, "migrate_dialog_to_megagroup"); - if (d == nullptr) { - d = add_dialog(new_dialog_id, "migrate_dialog_to_megagroup"); - if (d->pts == 0) { - d->pts = 1; - } - update_dialog_pos(d, "migrate_dialog_to_megagroup"); - } - - promise.set_value(Unit()); - return new_dialog_id; -} - bool MessagesManager::is_dialog_opened(DialogId dialog_id) const { const Dialog *d = get_dialog(dialog_id); return d != nullptr && d->open_count > 0; @@ -19822,21 +18811,11 @@ Status MessagesManager::close_dialog(DialogId dialog_id) { return Status::OK(); } -DialogId MessagesManager::get_my_dialog_id() const { - return DialogId(td_->contacts_manager_->get_my_id()); -} - Status MessagesManager::view_messages(DialogId dialog_id, vector message_ids, MessageSource source, bool force_read) { CHECK(!td_->auth_manager_->is_bot()); - Dialog *d = get_dialog_force(dialog_id, "view_messages"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); - } + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "view_messages")); if (source == MessageSource::Auto) { if (d->open_count > 0) { @@ -19852,6 +18831,16 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess source == MessageSource::DialogList || source == MessageSource::Other; bool need_mark_download_as_viewed = is_dialog_history || source == MessageSource::HistoryPreview || source == MessageSource::Search || source == MessageSource::Other; + bool need_invalidate_authentication_code = + dialog_id == DialogId(UserManager::get_service_notifications_user_id()) && source == MessageSource::Screenshot; + auto dialog_type = dialog_id.get_type(); + bool need_screenshot_notification = source == MessageSource::Screenshot && + (dialog_type == DialogType::User || dialog_type == DialogType::SecretChat) && + can_send_message(dialog_id).is_ok(); + + if (source == MessageSource::DialogList && dialog_type == DialogType::User) { + td_->story_manager_->on_view_dialog_active_stories({dialog_id}); + } // keep only valid message identifiers size_t pos = 0; @@ -19865,6 +18854,8 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess if (is_dialog_history) { td_->sponsored_message_manager_->view_sponsored_message(dialog_id, message_id); continue; + } else if (source == MessageSource::HistoryPreview || source == MessageSource::Other) { + continue; } else { return Status::Error(400, "Can't view the message from the specified source"); } @@ -19897,7 +18888,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess // get information about thread of the messages MessageId top_thread_message_id; if (source == MessageSource::MessageThreadHistory) { - if (dialog_id.get_type() != DialogType::Channel || is_broadcast_channel(dialog_id)) { + if (dialog_type != DialogType::Channel || td_->dialog_manager_->is_broadcast_channel(dialog_id)) { return Status::Error(400, "There are no message threads in the chat"); } @@ -19953,7 +18944,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess // get forum topic identifier for the messages MessageId forum_topic_id; if (source == MessageSource::ForumTopicHistory) { - if (!is_forum_channel(dialog_id)) { + if (!td_->dialog_manager_->is_forum_channel(dialog_id)) { return Status::Error(400, "Chat has no topics"); } @@ -19976,7 +18967,9 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess vector read_content_message_ids; vector read_reaction_message_ids; vector new_viewed_message_ids; - vector viewed_reaction_message_ids; + vector viewed_fact_check_message_ids; + vector authentication_codes; + vector screenshotted_secret_message_ids; for (auto message_id : message_ids) { auto *m = get_message_force(d, message_id, "view_messages 4"); if (m != nullptr) { @@ -20007,7 +19000,7 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess on_message_changed(d, m, true, "view_messages 8"); } - auto file_source_id = full_message_id_to_file_source_id_.get({dialog_id, m->message_id}); + auto file_source_id = message_full_id_to_file_source_id_.get({dialog_id, m->message_id}); if (file_source_id.is_valid() && need_mark_download_as_viewed) { LOG(INFO) << "Have " << file_source_id << " for " << m->message_id; CHECK(file_source_id.is_valid()); @@ -20019,6 +19012,11 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess } } + auto story_full_id = get_message_content_story_full_id(td_, m->content.get()); + if (story_full_id.is_valid()) { + td_->story_manager_->view_story_message(story_full_id); + } + if (m->message_id.is_server() && d->open_count > 0) { auto &info = dialog_viewed_messages_[dialog_id]; if (info == nullptr) { @@ -20027,17 +19025,29 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess auto &view_id = info->message_id_to_view_id[message_id]; if (view_id == 0) { new_viewed_message_ids.push_back(message_id); - if (need_poll_message_reactions(d, m)) { - viewed_reaction_message_ids.push_back(message_id); - } } else { info->recently_viewed_messages.erase(view_id); } view_id = ++info->current_view_id; info->recently_viewed_messages[view_id] = message_id; } + + if (m->message_id.is_server() && m->fact_check != nullptr && m->fact_check->need_check() && + being_reloaded_fact_checks_.insert({dialog_id, message_id}).second) { + CHECK(message_id.is_server()); + viewed_fact_check_message_ids.push_back(message_id); + } + + if (need_invalidate_authentication_code) { + extract_authentication_codes(dialog_id, m, authentication_codes); + } + if (need_screenshot_notification && !m->is_outgoing) { + if ((dialog_type == DialogType::User && m->is_content_secret) || dialog_type == DialogType::SecretChat) { + screenshotted_secret_message_ids.push_back(m->message_id); + } + } } else if (!message_id.is_yet_unsent() && message_id > max_message_id) { - if ((d->notification_info != nullptr && message_id <= d->notification_info->max_notification_message_id_) || + if ((d->notification_info != nullptr && message_id <= d->notification_info->max_push_notification_message_id_) || message_id <= d->last_new_message_id || message_id <= max_thread_message_id) { max_message_id = message_id; } @@ -20068,19 +19078,34 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess auto &info = dialog_viewed_messages_[dialog_id]; CHECK(info != nullptr); CHECK(info->message_id_to_view_id.size() == info->recently_viewed_messages.size()); - constexpr size_t MAX_RECENTLY_VIEWED_MESSAGES = 50; + constexpr size_t MAX_RECENTLY_VIEWED_MESSAGES = 25; while (info->recently_viewed_messages.size() > MAX_RECENTLY_VIEWED_MESSAGES) { auto it = info->recently_viewed_messages.begin(); info->message_id_to_view_id.erase(it->second); info->recently_viewed_messages.erase(it); } - if (!viewed_reaction_message_ids.empty()) { - queue_message_reactions_reload(dialog_id, viewed_reaction_message_ids); - } + process_viewed_message(d, new_viewed_message_ids, true); } - if (td_->is_online() && dialog_viewed_messages_.count(dialog_id) != 0) { + if (!viewed_fact_check_message_ids.empty()) { + CHECK(dialog_id.get_type() != DialogType::SecretChat); + auto promise = + PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, message_ids = viewed_fact_check_message_ids]( + Result>> r_fact_checks) { + send_closure(actor_id, &MessagesManager::on_get_message_fact_checks, dialog_id, message_ids, + std::move(r_fact_checks)); + }); + td_->create_handler(std::move(promise)) + ->send(dialog_id, std::move(viewed_fact_check_message_ids)); + } + if (td_->online_manager_->is_online() && dialog_viewed_messages_.count(dialog_id) != 0) { update_viewed_messages_timeout_.add_timeout_in(dialog_id.get(), UPDATE_VIEWED_MESSAGES_PERIOD); } + if (!authentication_codes.empty()) { + td_->account_manager_->invalidate_authentication_codes(std::move(authentication_codes)); + } + if (!screenshotted_secret_message_ids.empty()) { + send_screenshot_taken_notification_message(d); + } if (!need_read) { return Status::OK(); @@ -20102,11 +19127,12 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess max_thread_message_id = top_m->reply_info.max_message_id_; if (is_discussion_message(dialog_id, top_m)) { - auto linked_dialog_id = top_m->forward_info->from_dialog_id; + auto linked_message_full_id = top_m->forward_info->get_last_message_full_id(); + auto linked_dialog_id = linked_message_full_id.get_dialog_id(); auto linked_d = get_dialog(linked_dialog_id); CHECK(linked_d != nullptr); CHECK(linked_dialog_id.get_type() == DialogType::Channel); - auto *linked_m = get_message_force(linked_d, top_m->forward_info->from_message_id, "view_messages 11"); + auto *linked_m = get_message_force(linked_d, linked_message_full_id.get_message_id(), "view_messages 11"); if (linked_m != nullptr && is_active_message_reply_info(linked_dialog_id, linked_m->reply_info)) { if (linked_m->reply_info.last_read_inbox_message_id_ < prev_last_read_inbox_message_id) { prev_last_read_inbox_message_id = linked_m->reply_info.last_read_inbox_message_id_; @@ -20131,7 +19157,11 @@ Status MessagesManager::view_messages(DialogId dialog_id, vector mess return Status::OK(); } if (source == MessageSource::ForumTopicHistory) { - // TODO read forum topic history + if (!forum_topic_id.is_valid() || !max_message_id.is_valid()) { + return Status::OK(); + } + + td_->forum_topic_manager_->read_forum_topic_messages(dialog_id, forum_topic_id, max_message_id); return Status::OK(); } @@ -20203,14 +19233,42 @@ void MessagesManager::finish_get_message_extended_media(DialogId dialog_id, cons } } -Status MessagesManager::open_message_content(FullMessageId full_message_id) { - auto dialog_id = full_message_id.get_dialog_id(); +void MessagesManager::on_get_message_fact_checks( + DialogId dialog_id, const vector &message_ids, + Result>> r_fact_checks) { + G()->ignore_result_if_closing(r_fact_checks); + for (auto message_id : message_ids) { + auto erased_count = being_reloaded_fact_checks_.erase({dialog_id, message_id}); + CHECK(erased_count > 0); + } + if (r_fact_checks.is_error() || !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { + return; + } + auto fact_checks = r_fact_checks.move_as_ok(); + if (fact_checks.size() != message_ids.size()) { + LOG(ERROR) << "Receive " << fact_checks.size() << " fact checks instead of " << message_ids.size(); + return; + } + auto *d = get_dialog(dialog_id); + CHECK(d != nullptr); + for (size_t i = 0; i < message_ids.size(); i++) { + auto *m = get_message_force(d, message_ids[i], "on_get_message_fact_checks"); + if (m == nullptr) { + continue; + } + auto fact_check = FactCheck::get_fact_check(td_->user_manager_.get(), std::move(fact_checks[i]), false); + update_message_fact_check(d, m, std::move(fact_check), true); + } +} + +Status MessagesManager::open_message_content(MessageFullId message_full_id) { + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog_force(dialog_id, "open_message_content"); if (d == nullptr) { return Status::Error(400, "Chat not found"); } - auto *m = get_message_force(d, full_message_id.get_message_id(), "open_message_content"); + auto *m = get_message_force(d, message_full_id.get_message_id(), "open_message_content"); if (m == nullptr) { return Status::Error(400, "Message not found"); } @@ -20219,7 +19277,7 @@ Status MessagesManager::open_message_content(FullMessageId full_message_id) { return Status::OK(); } - if (read_message_content(d, m, true, "open_message_content") && + if (read_message_content(d, m, true, 0, "open_message_content") && (m->message_id.is_server() || dialog_id.get_type() == DialogType::SecretChat)) { read_message_contents_on_server(dialog_id, {m->message_id}, 0, Auto()); } @@ -20301,15 +19359,15 @@ void MessagesManager::read_message_contents_on_server(DialogId dialog_id, vector } } -void MessagesManager::click_animated_emoji_message(FullMessageId full_message_id, +void MessagesManager::click_animated_emoji_message(MessageFullId message_full_id, Promise> &&promise) { - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog_force(dialog_id, "click_animated_emoji_message"); if (d == nullptr) { return promise.set_error(Status::Error(400, "Chat not found")); } - auto message_id = get_persistent_message_id(d, full_message_id.get_message_id()); + auto message_id = get_persistent_message_id(d, message_full_id.get_message_id()); auto *m = get_message_force(d, message_id, "click_animated_emoji_message"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); @@ -20319,13 +19377,13 @@ void MessagesManager::click_animated_emoji_message(FullMessageId full_message_id return promise.set_value(nullptr); } - get_message_content_animated_emoji_click_sticker(m->content.get(), full_message_id, td_, std::move(promise)); + get_message_content_animated_emoji_click_sticker(m->content.get(), message_full_id, td_, std::move(promise)); } void MessagesManager::open_dialog(Dialog *d) { CHECK(!td_->auth_manager_->is_bot()); DialogId dialog_id = d->dialog_id; - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return; } recently_opened_dialogs_.add_dialog(dialog_id); @@ -20372,42 +19430,45 @@ void MessagesManager::open_dialog(Dialog *d) { switch (dialog_id.get_type()) { case DialogType::User: + td_->story_manager_->on_view_dialog_active_stories({dialog_id}); break; case DialogType::Chat: - td_->contacts_manager_->repair_chat_participants(dialog_id.get_chat_id()); + td_->chat_manager_->repair_chat_participants(dialog_id.get_chat_id()); reget_dialog_action_bar(dialog_id, "open_dialog", false); break; case DialogType::Channel: { auto channel_id = dialog_id.get_channel_id(); - if (!is_broadcast_channel(dialog_id)) { - auto participant_count = td_->contacts_manager_->get_channel_participant_count(channel_id); - auto has_hidden_participants = td_->contacts_manager_->get_channel_effective_has_hidden_participants( + if (!td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + auto participant_count = td_->chat_manager_->get_channel_participant_count(channel_id); + auto has_hidden_participants = td_->chat_manager_->get_channel_effective_has_hidden_participants( dialog_id.get_channel_id(), "open_dialog"); if (participant_count < 195 && !has_hidden_participants) { // include unknown participant_count - td_->contacts_manager_->get_channel_participants( + td_->dialog_participant_manager_->get_channel_participants( channel_id, td_api::make_object(), string(), 0, 200, 200, Auto()); } + } else { + td_->story_manager_->on_view_dialog_active_stories({dialog_id}); } get_channel_difference(dialog_id, d->pts, 0, MessageId(), true, "open_dialog"); reget_dialog_action_bar(dialog_id, "open_dialog", false); - if (td_->contacts_manager_->get_channel_has_linked_channel(channel_id)) { - auto linked_channel_id = td_->contacts_manager_->get_channel_linked_channel_id(channel_id, "open_dialog"); + if (td_->chat_manager_->get_channel_has_linked_channel(channel_id)) { + auto linked_channel_id = td_->chat_manager_->get_channel_linked_channel_id(channel_id, "open_dialog"); if (!linked_channel_id.is_valid()) { // load linked_channel_id - send_closure_later(G()->contacts_manager(), &ContactsManager::load_channel_full, channel_id, false, - Promise(), "open_dialog"); + send_closure_later(G()->chat_manager(), &ChatManager::load_channel_full, channel_id, false, Promise(), + "open_dialog"); } else { - get_dialog_info_full(DialogId(linked_channel_id), Auto(), "open_dialog"); + td_->dialog_manager_->get_dialog_info_full(DialogId(linked_channel_id), Auto(), "open_dialog"); } } break; } case DialogType::SecretChat: { // to repair dialog action bar - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); if (user_id.is_valid()) { - td_->contacts_manager_->reload_user_full(user_id, Promise()); + td_->user_manager_->reload_user_full(user_id, Promise(), "open_dialog"); } break; } @@ -20417,15 +19478,7 @@ void MessagesManager::open_dialog(Dialog *d) { } if (!td_->auth_manager_->is_bot()) { - auto online_count_it = dialog_online_member_counts_.find(dialog_id); - if (online_count_it != dialog_online_member_counts_.end()) { - auto &info = online_count_it->second; - CHECK(!info.is_update_sent); - if (Time::now() - info.update_time < ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME) { - info.is_update_sent = true; - send_update_chat_online_member_count(dialog_id, info.online_member_count); - } - } + td_->dialog_participant_manager_->on_dialog_opened(dialog_id); if (d->has_scheduled_database_messages && !d->is_has_scheduled_database_messages_checked) { CHECK(G()->use_message_database()); @@ -20453,7 +19506,7 @@ void MessagesManager::close_dialog(Dialog *d) { } auto dialog_id = d->dialog_id; - if (have_input_peer(dialog_id, AccessRights::Write)) { + if (td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Write)) { if (pending_draft_message_timeout_.has_timeout(dialog_id.get())) { pending_draft_message_timeout_.set_timeout_in(dialog_id.get(), 0.0); } @@ -20461,7 +19514,7 @@ void MessagesManager::close_dialog(Dialog *d) { pending_draft_message_timeout_.cancel_timeout(dialog_id.get()); } - if (have_input_peer(dialog_id, AccessRights::Read)) { + if (td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { if (pending_message_views_timeout_.has_timeout(dialog_id.get())) { pending_message_views_timeout_.set_timeout_in(dialog_id.get(), 0.0); } @@ -20478,6 +19531,11 @@ void MessagesManager::close_dialog(Dialog *d) { CHECK(!d->has_unload_timeout); pending_unload_dialog_timeout_.set_timeout_in(dialog_id.get(), get_next_unload_dialog_delay(d)); d->has_unload_timeout = true; + + if (d->need_unload_on_close) { + unload_dialog(dialog_id, 0); + d->need_unload_on_close = false; + } } dialog_viewed_messages_.erase(dialog_id); @@ -20513,12 +19571,7 @@ void MessagesManager::close_dialog(Dialog *d) { send_update_chat_read_inbox(d, false, "close_dialog"); } - auto online_count_it = dialog_online_member_counts_.find(dialog_id); - if (online_count_it != dialog_online_member_counts_.end()) { - auto &info = online_count_it->second; - info.is_update_sent = false; - } - update_dialog_online_member_count_timeout_.set_timeout_in(dialog_id.get(), ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME); + td_->dialog_participant_manager_->on_dialog_closed(dialog_id); } } @@ -20534,43 +19587,11 @@ int64 MessagesManager::get_chat_id_object(DialogId dialog_id, const char *source return dialog_id.get(); } -vector MessagesManager::get_chat_ids_object(const vector &dialog_ids, const char *source) const { - return transform(dialog_ids, [this, source](DialogId dialog_id) { return get_chat_id_object(dialog_id, source); }); -} - -td_api::object_ptr MessagesManager::get_chat_type_object(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: - return td_api::make_object( - td_->contacts_manager_->get_user_id_object(dialog_id.get_user_id(), "chatTypePrivate")); - case DialogType::Chat: - return td_api::make_object( - td_->contacts_manager_->get_basic_group_id_object(dialog_id.get_chat_id(), "chatTypeBasicGroup")); - case DialogType::Channel: { - auto channel_id = dialog_id.get_channel_id(); - return td_api::make_object( - td_->contacts_manager_->get_supergroup_id_object(channel_id, "chatTypeSupergroup"), - !td_->contacts_manager_->is_megagroup_channel(channel_id)); - } - case DialogType::SecretChat: { - auto secret_chat_id = dialog_id.get_secret_chat_id(); - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(secret_chat_id); - return td_api::make_object( - td_->contacts_manager_->get_secret_chat_id_object(secret_chat_id, "chatTypeSecret"), - td_->contacts_manager_->get_user_id_object(user_id, "chatTypeSecret")); - } - case DialogType::None: - default: - UNREACHABLE(); - return nullptr; - } -} - td_api::object_ptr MessagesManager::get_chat_action_bar_object(const Dialog *d) const { CHECK(d != nullptr); auto dialog_type = d->dialog_id.get_type(); if (dialog_type == DialogType::SecretChat) { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); if (!user_id.is_valid()) { return nullptr; } @@ -20587,10 +19608,19 @@ td_api::object_ptr MessagesManager::get_chat_action_bar_o return d->action_bar->get_chat_action_bar_object(dialog_type, false); } +td_api::object_ptr MessagesManager::get_business_bot_manage_bar_object( + const Dialog *d) const { + CHECK(d != nullptr); + if (d->business_bot_manage_bar == nullptr) { + return nullptr; + } + return d->business_bot_manage_bar->get_business_bot_manage_bar_object(td_); +} + td_api::object_ptr MessagesManager::get_chat_background_object(const Dialog *d) const { CHECK(d != nullptr); if (d->dialog_id.get_type() == DialogType::SecretChat) { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); if (!user_id.is_valid()) { return nullptr; } @@ -20605,7 +19635,7 @@ td_api::object_ptr MessagesManager::get_chat_background_ string MessagesManager::get_dialog_theme_name(const Dialog *d) const { CHECK(d != nullptr); if (d->dialog_id.get_type() == DialogType::SecretChat) { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); if (!user_id.is_valid()) { return string(); } @@ -20623,8 +19653,8 @@ td_api::object_ptr MessagesManager::get_chat_join_ return nullptr; } return td_api::make_object( - d->pending_join_request_count, td_->contacts_manager_->get_user_ids_object(d->pending_join_request_user_ids, - "get_chat_join_requests_info_object")); + d->pending_join_request_count, + td_->user_manager_->get_user_ids_object(d->pending_join_request_user_ids, "get_chat_join_requests_info_object")); } td_api::object_ptr MessagesManager::get_video_chat_object(const Dialog *d) const { @@ -20645,59 +19675,63 @@ td_api::object_ptr MessagesManager::get_default_message_s : nullptr; } -td_api::object_ptr MessagesManager::get_chat_object(const Dialog *d) const { +td_api::object_ptr MessagesManager::get_chat_object(const Dialog *d, const char *source) const { CHECK(d != nullptr); bool is_premium = td_->option_manager_->get_option_boolean("is_premium"); auto chat_source = is_dialog_sponsored(d) ? sponsored_dialog_source_.get_chat_source_object() : nullptr; auto can_delete = can_delete_dialog(d); // TODO hide/show draft message when need_hide_dialog_draft_message changes - auto draft_message = - !need_hide_dialog_draft_message(d->dialog_id) ? get_draft_message_object(d->draft_message) : nullptr; - auto available_reactions = get_dialog_active_reactions(d).get_chat_available_reactions_object(); + auto draft_message = !need_hide_dialog_draft_message(d) ? get_draft_message_object(td_, d->draft_message) : nullptr; + auto available_reactions = get_dialog_active_reactions(d).get_chat_available_reactions_object(td_); auto is_translatable = d->is_translatable && is_premium; + auto block_list_id = BlockListId(d->is_blocked, d->is_blocked_for_stories); + auto chat_lists = transform(get_dialog_list_ids(d), + [](DialogListId dialog_list_id) { return dialog_list_id.get_chat_list_object(); }); return make_tl_object( - d->dialog_id.get(), get_chat_type_object(d->dialog_id), get_dialog_title(d->dialog_id), - get_chat_photo_info_object(td_->file_manager_.get(), get_dialog_photo(d->dialog_id)), - get_dialog_default_permissions(d->dialog_id).get_chat_permissions_object(), - get_message_object(d->dialog_id, get_message(d, d->last_message_id), "get_chat_object"), - get_chat_positions_object(d), get_default_message_sender_object(d), - get_dialog_has_protected_content(d->dialog_id), is_translatable, d->is_marked_as_unread, d->is_blocked, - get_dialog_has_scheduled_messages(d), can_delete.for_self_, can_delete.for_all_users_, - can_report_dialog(d->dialog_id), d->notification_settings.silent_send_message, - d->server_unread_count + d->local_unread_count, d->last_read_inbox_message_id.get(), - d->last_read_outbox_message_id.get(), d->unread_mention_count, d->unread_reaction_count, - get_chat_notification_settings_object(&d->notification_settings), std::move(available_reactions), - d->message_ttl.get_message_auto_delete_time_object(), get_chat_background_object(d), get_dialog_theme_name(d), - get_chat_action_bar_object(d), get_video_chat_object(d), get_chat_join_requests_info_object(d), - d->reply_markup_message_id.get(), std::move(draft_message), d->client_data); -} - -td_api::object_ptr MessagesManager::get_chat_object(DialogId dialog_id) { + d->dialog_id.get(), td_->dialog_manager_->get_chat_type_object(d->dialog_id, source), + td_->dialog_manager_->get_dialog_title(d->dialog_id), + get_chat_photo_info_object(td_->file_manager_.get(), td_->dialog_manager_->get_dialog_photo(d->dialog_id)), + td_->dialog_manager_->get_dialog_accent_color_id_object(d->dialog_id), + td_->dialog_manager_->get_dialog_background_custom_emoji_id(d->dialog_id).get(), + td_->dialog_manager_->get_dialog_profile_accent_color_id_object(d->dialog_id), + td_->dialog_manager_->get_dialog_profile_background_custom_emoji_id(d->dialog_id).get(), + td_->dialog_manager_->get_dialog_default_permissions(d->dialog_id).get_chat_permissions_object(), + get_message_object(d, d->last_message_id, source), get_chat_positions_object(d), std::move(chat_lists), + get_default_message_sender_object(d), block_list_id.get_block_list_object(), + td_->dialog_manager_->get_dialog_has_protected_content(d->dialog_id), is_translatable, d->is_marked_as_unread, + get_dialog_view_as_topics(d), get_dialog_has_scheduled_messages(d), can_delete.for_self_, + can_delete.for_all_users_, td_->dialog_manager_->can_report_dialog(d->dialog_id), + d->notification_settings.silent_send_message, d->server_unread_count + d->local_unread_count, + d->last_read_inbox_message_id.get(), d->last_read_outbox_message_id.get(), d->unread_mention_count, + d->unread_reaction_count, get_chat_notification_settings_object(&d->notification_settings), + std::move(available_reactions), d->message_ttl.get_message_auto_delete_time_object(), + td_->dialog_manager_->get_dialog_emoji_status_object(d->dialog_id), get_chat_background_object(d), + get_dialog_theme_name(d), get_chat_action_bar_object(d), get_business_bot_manage_bar_object(d), + get_video_chat_object(d), get_chat_join_requests_info_object(d), d->reply_markup_message_id.get(), + std::move(draft_message), d->client_data); +} + +td_api::object_ptr MessagesManager::get_chat_object(DialogId dialog_id, const char *source) { const Dialog *d = get_dialog(dialog_id); if (postponed_chat_read_inbox_updates_.erase(dialog_id) > 0) { - send_update_chat_read_inbox(d, true, "get_chat_object"); + send_update_chat_read_inbox(d, true, source); } - return get_chat_object(d); + return get_chat_object(d, source); } -tl_object_ptr MessagesManager::get_chats_object(int32 total_count, const vector &dialog_ids, - const char *source) const { - if (total_count == -1) { - total_count = narrow_cast(dialog_ids.size()); +td_api::object_ptr MessagesManager::get_my_dialog_draft_message_object() const { + const Dialog *d = get_dialog(td_->dialog_manager_->get_my_dialog_id()); + if (d == nullptr) { + return nullptr; } - return td_api::make_object(total_count, get_chat_ids_object(dialog_ids, source)); -} - -tl_object_ptr MessagesManager::get_chats_object(const std::pair> &dialog_ids, - const char *source) const { - return get_chats_object(dialog_ids.first, dialog_ids.second, source); + return get_draft_message_object(td_, d->draft_message); } std::pair MessagesManager::get_dialog_mute_until(DialogId dialog_id, const Dialog *d) const { CHECK(!td_->auth_manager_->is_bot()); if (d == nullptr || !d->notification_settings.is_synchronized) { - auto scope = get_dialog_notification_setting_scope(dialog_id); + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(dialog_id); return {false, td_->notification_settings_manager_->get_scope_mute_until(scope)}; } @@ -20706,28 +19740,54 @@ std::pair MessagesManager::get_dialog_mute_until(DialogId dialog_id int64 MessagesManager::get_dialog_notification_ringtone_id(DialogId dialog_id, const Dialog *d) const { CHECK(!td_->auth_manager_->is_bot()); - if (d == nullptr || !d->notification_settings.is_synchronized || d->notification_settings.use_default_mute_until) { - auto scope = get_dialog_notification_setting_scope(dialog_id); + if (d == nullptr || !d->notification_settings.is_synchronized || + is_notification_sound_default(d->notification_settings.sound)) { + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(dialog_id); return get_notification_sound_ringtone_id(td_->notification_settings_manager_->get_scope_notification_sound(scope)); } return get_notification_sound_ringtone_id(d->notification_settings.sound); } -NotificationSettingsScope MessagesManager::get_dialog_notification_setting_scope(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::SecretChat: - return NotificationSettingsScope::Private; - case DialogType::Chat: - return NotificationSettingsScope::Group; - case DialogType::Channel: - return is_broadcast_channel(dialog_id) ? NotificationSettingsScope::Channel : NotificationSettingsScope::Group; - case DialogType::None: - default: - UNREACHABLE(); - return NotificationSettingsScope::Private; +StoryNotificationSettings MessagesManager::get_story_notification_settings(DialogId dialog_id) { + bool need_dialog_settings = false; + bool need_top_dialogs = false; + bool are_muted = false; + bool hide_sender = false; + int64 ringtone_id = 0; + + const Dialog *d = get_dialog_force(dialog_id, "get_story_notification_settings"); + if (d == nullptr || !d->notification_settings.is_synchronized) { + need_dialog_settings = true; + } + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(dialog_id); + if (need_dialog_settings || d->notification_settings.use_default_mute_stories) { + bool use_default; + std::tie(use_default, are_muted) = td_->notification_settings_manager_->get_scope_mute_stories(scope); + if (use_default) { + auto is_top_dialog = td_->top_dialog_manager_->is_top_dialog(TopDialogCategory::Correspondent, 5, dialog_id); + if (is_top_dialog == -1) { + need_top_dialogs = true; + } else { + are_muted = is_top_dialog != 0; + } + } + } else { + are_muted = d->notification_settings.mute_stories; + } + if (need_dialog_settings || d->notification_settings.use_default_hide_story_sender) { + hide_sender = td_->notification_settings_manager_->get_scope_hide_story_sender(scope); + } else { + hide_sender = d->notification_settings.hide_story_sender; + } + if (need_dialog_settings || is_notification_sound_default(d->notification_settings.story_sound)) { + ringtone_id = get_notification_sound_ringtone_id( + td_->notification_settings_manager_->get_scope_story_notification_sound(scope)); + } else { + ringtone_id = get_notification_sound_ringtone_id(d->notification_settings.story_sound); } + + return {need_dialog_settings, need_top_dialogs, are_muted, hide_sender, ringtone_id}; } vector MessagesManager::get_dialog_notification_settings_exceptions(NotificationSettingsScope scope, @@ -20743,11 +19803,11 @@ vector MessagesManager::get_dialog_notification_settings_exceptions(No if (have_all_dialogs || force) { vector ordered_dialogs; - auto my_dialog_id = get_my_dialog_id(); + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); for (const auto &list : dialog_folders_) { for (const auto &dialog_date : list.second.ordered_dialogs_) { auto dialog_id = dialog_date.get_dialog_id(); - if (filter_scope && get_dialog_notification_setting_scope(dialog_id) != scope) { + if (filter_scope && td_->dialog_manager_->get_dialog_notification_setting_scope(dialog_id) != scope) { continue; } if (dialog_id == my_dialog_id) { @@ -20795,7 +19855,7 @@ DialogNotificationSettings *MessagesManager::get_dialog_notification_settings(Di if (d == nullptr) { return nullptr; } - if (!force && !have_input_peer(dialog_id, AccessRights::Read)) { + if (!force && !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return nullptr; } return &d->notification_settings; @@ -20808,7 +19868,7 @@ Status MessagesManager::set_dialog_notification_settings( if (current_settings == nullptr) { return Status::Error(400, "Wrong chat identifier specified"); } - if (dialog_id == get_my_dialog_id()) { + if (dialog_id == td_->dialog_manager_->get_my_dialog_id()) { return Status::Error(400, "Notification settings of the Saved Messages chat can't be changed"); } @@ -20889,7 +19949,7 @@ tl_object_ptr MessagesManager::get_dialog_history(DialogId dia promise.set_error(Status::Error(400, "Chat not found")); return nullptr; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { promise.set_error(Status::Error(400, "Can't access the chat")); return nullptr; } @@ -20904,21 +19964,20 @@ tl_object_ptr MessagesManager::get_dialog_history(DialogId dia LOG(INFO) << "Get " << (only_local ? "local " : "") << "history in " << dialog_id << " from " << from_message_id << " with offset " << offset << " and limit " << limit << ", " << left_tries - << " tries left, have_full_history = " << d->have_full_history + << " tries left, is_empty = " << d->is_empty << ", have_full_history = " << d->have_full_history << ", have_full_history_source = " << d->have_full_history_source; - auto message_ids = - d->ordered_messages.get_history(d->last_message_id, from_message_id, offset, limit, left_tries == 0); + auto message_ids = d->ordered_messages.get_history(d->last_message_id, from_message_id, offset, limit, + left_tries == 0 && !only_local); if (!message_ids.empty()) { // maybe need some messages CHECK(offset == 0); preload_newer_messages(d, message_ids[0]); preload_older_messages(d, message_ids.back()); - } else if (message_ids.size() < static_cast(limit) && left_tries != 0 && - !(d->is_empty && d->have_full_history && left_tries < 3)) { + } else if (limit > 0 && left_tries != 0 && !(d->is_empty && d->have_full_history && left_tries < 3)) { // there can be more messages in the database or on the server, need to load them - send_closure_later(actor_id(this), &MessagesManager::load_messages, dialog_id, from_message_id, offset, - limit - static_cast(message_ids.size()), left_tries, only_local, std::move(promise)); + send_closure_later(actor_id(this), &MessagesManager::load_messages, dialog_id, from_message_id, offset, limit, + left_tries, only_local, std::move(promise)); return nullptr; } @@ -21068,14 +20127,15 @@ void MessagesManager::do_read_history_on_server(DialogId dialog_id) { auto it = updated_read_history_message_ids_.find(dialog_id); if (it != updated_read_history_message_ids_.end()) { - for (auto top_thread_message_id : it->second) { + auto top_thread_message_ids = std::move(it->second); + updated_read_history_message_ids_.erase(it); + for (auto top_thread_message_id : top_thread_message_ids) { if (!top_thread_message_id.is_valid()) { read_history_on_server_impl(d, MessageId()); } else { read_message_thread_history_on_server_impl(d, top_thread_message_id, MessageId()); } } - updated_read_history_message_ids_.erase(it); } } @@ -21109,7 +20169,7 @@ void MessagesManager::read_history_on_server_impl(Dialog *d, MessageId max_messa repair_server_unread_count(dialog_id, d->server_unread_count, "read_history_on_server_impl"); } - if (!max_message_id.is_valid() || !have_input_peer(dialog_id, AccessRights::Read)) { + if (!max_message_id.is_valid() || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return promise.set_value(Unit()); } @@ -21173,7 +20233,7 @@ void MessagesManager::read_message_thread_history_on_server_impl(Dialog *d, Mess }); } - if (!max_message_id.is_valid() || !have_input_peer(dialog_id, AccessRights::Read)) { + if (!max_message_id.is_valid() || !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { return promise.set_value(Unit()); } @@ -21255,7 +20315,7 @@ std::pair> MessagesManager::get_message_thread_histo promise.set_error(Status::Error(400, "Chat not found")); return {}; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { promise.set_error(Status::Error(400, "Can't access the chat")); return {}; } @@ -21272,9 +20332,9 @@ std::pair> MessagesManager::get_message_thread_histo return {}; } - FullMessageId top_thread_full_message_id; - if (message_id == MessageId(ServerMessageId(1)) && is_forum_channel(dialog_id)) { - top_thread_full_message_id = FullMessageId{dialog_id, message_id}; + MessageFullId top_thread_message_full_id; + if (message_id == MessageId(ServerMessageId(1)) && td_->dialog_manager_->is_forum_channel(dialog_id)) { + top_thread_message_full_id = MessageFullId{dialog_id, message_id}; } else { message_id = get_persistent_message_id(d, message_id); Message *m = get_message_force(d, message_id, "get_message_thread_history 1"); @@ -21283,21 +20343,21 @@ std::pair> MessagesManager::get_message_thread_histo return {}; } - auto r_top_thread_full_message_id = get_top_thread_full_message_id(dialog_id, m, true); - if (r_top_thread_full_message_id.is_error()) { - promise.set_error(r_top_thread_full_message_id.move_as_error()); + auto r_top_thread_message_full_id = get_top_thread_message_full_id(dialog_id, m, true); + if (r_top_thread_message_full_id.is_error()) { + promise.set_error(r_top_thread_message_full_id.move_as_error()); return {}; } - top_thread_full_message_id = r_top_thread_full_message_id.move_as_ok(); + top_thread_message_full_id = r_top_thread_message_full_id.move_as_ok(); if ((m->reply_info.is_empty() || !m->reply_info.is_comment_) && - top_thread_full_message_id.get_message_id() != m->message_id) { - CHECK(dialog_id == top_thread_full_message_id.get_dialog_id()); + top_thread_message_full_id.get_message_id() != m->message_id) { + CHECK(dialog_id == top_thread_message_full_id.get_dialog_id()); // get information about the thread from the top message - message_id = top_thread_full_message_id.get_message_id(); + message_id = top_thread_message_full_id.get_message_id(); CHECK(message_id.is_valid()); } - if (!top_thread_full_message_id.get_message_id().is_valid()) { + if (!top_thread_message_full_id.get_message_id().is_valid()) { CHECK(m->reply_info.is_comment_); get_message_thread( dialog_id, message_id, @@ -21327,12 +20387,12 @@ std::pair> MessagesManager::get_message_thread_histo d = get_dialog(dialog_id); CHECK(d != nullptr); } - if (dialog_id != top_thread_full_message_id.get_dialog_id()) { + if (dialog_id != top_thread_message_full_id.get_dialog_id()) { promise.set_error(Status::Error(500, "Receive messages in an unexpected chat")); return {}; } - auto yet_unsent_it = yet_unsent_thread_message_ids_.find(top_thread_full_message_id); + auto yet_unsent_it = yet_unsent_thread_message_ids_.find(top_thread_message_full_id); if (yet_unsent_it != yet_unsent_thread_message_ids_.end()) { const std::set &message_ids = yet_unsent_it->second; auto merge_message_ids = get_message_history_slice(message_ids.begin(), message_ids.lower_bound(from_message_id), @@ -21343,7 +20403,7 @@ std::pair> MessagesManager::get_message_thread_histo result = std::move(new_result); } - Message *top_m = get_message_force(d, top_thread_full_message_id.get_message_id(), "get_message_thread_history 2"); + Message *top_m = get_message_force(d, top_thread_message_full_id.get_message_id(), "get_message_thread_history 2"); if (top_m != nullptr && !top_m->local_thread_message_ids.empty()) { vector &message_ids = top_m->local_thread_message_ids; vector merge_message_ids; @@ -21392,63 +20452,41 @@ std::pair> MessagesManager::get_message_thread_histo found_dialog_messages_[random_id]; // reserve place for result td_->create_handler(std::move(promise)) - ->send(dialog_id, string(), DialogId(), from_message_id.get_next_server_message_id(), offset, limit, - MessageSearchFilter::Empty, message_id, random_id); + ->send(dialog_id, SavedMessagesTopicId(), string(), DialogId(), from_message_id.get_next_server_message_id(), + offset, limit, MessageSearchFilter::Empty, message_id, ReactionType(), random_id); return {}; } -td_api::object_ptr MessagesManager::get_dialog_message_calendar(DialogId dialog_id, - MessageId from_message_id, - MessageSearchFilter filter, - int64 &random_id, bool use_db, - Promise &&promise) { - if (random_id != 0) { - // request has already been sent before - auto it = found_dialog_message_calendars_.find(random_id); - if (it != found_dialog_message_calendars_.end()) { - auto result = std::move(it->second); - found_dialog_message_calendars_.erase(it); - promise.set_value(Unit()); - return result; - } - random_id = 0; - } - LOG(INFO) << "Get message calendar in " << dialog_id << " filtered by " << filter << " from " << from_message_id; +void MessagesManager::get_dialog_message_calendar(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, + Promise> &&promise) { + LOG(INFO) << "Get message calendar in " << dialog_id << " with " << saved_messages_topic_id << " filtered by " + << filter << " from " << from_message_id; if (from_message_id.get() > MessageId::max().get()) { from_message_id = MessageId::max(); } if (!from_message_id.is_valid() && from_message_id != MessageId()) { - promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of a chat message or 0")); - return {}; + return promise.set_error(Status::Error(400, "Parameter from_message_id must be identifier of a chat message or 0")); } from_message_id = from_message_id.get_next_server_message_id(); - const Dialog *d = get_dialog_force(dialog_id, "get_dialog_message_calendar"); - if (d == nullptr) { - promise.set_error(Status::Error(400, "Chat not found")); - return {}; - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - promise.set_error(Status::Error(400, "Can't access the chat")); - return {}; - } - - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || found_dialog_message_calendars_.count(random_id) > 0); - found_dialog_message_calendars_[random_id]; // reserve place for result + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, true, AccessRights::Read, "get_dialog_message_calendar")); + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_in(td_, dialog_id)); CHECK(filter != MessageSearchFilter::Call && filter != MessageSearchFilter::MissedCall); if (filter == MessageSearchFilter::Empty || filter == MessageSearchFilter::Mention || filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::UnreadReaction) { - promise.set_error(Status::Error(400, "The filter is not supported")); - return {}; + if (filter != MessageSearchFilter::Empty && saved_messages_topic_id.is_valid()) { + return promise.set_value(td_api::make_object()); + } + return promise.set_error(Status::Error(400, "The filter is not supported")); } // Trying to use database - if (use_db && G()->use_message_database()) { + if (G()->use_message_database() && !saved_messages_topic_id.is_valid()) { MessageId first_db_message_id = get_first_database_message_id_by_index(d, filter); int32 message_count = d->message_count_by_index[message_search_filter_index(filter)]; auto fixed_from_message_id = from_message_id; @@ -21460,11 +20498,10 @@ td_api::object_ptr MessagesManager::get_dialog_message_ if (first_db_message_id < fixed_from_message_id && message_count != -1) { LOG(INFO) << "Get message calendar from database in " << dialog_id << " from " << fixed_from_message_id; auto new_promise = - PromiseCreator::lambda([random_id, dialog_id, fixed_from_message_id, first_db_message_id, filter, + PromiseCreator::lambda([dialog_id, fixed_from_message_id, first_db_message_id, filter, promise = std::move(promise)](Result r_calendar) mutable { - send_closure(G()->messages_manager(), &MessagesManager::on_get_message_calendar_from_database, random_id, - dialog_id, fixed_from_message_id, first_db_message_id, filter, std::move(r_calendar), - std::move(promise)); + send_closure(G()->messages_manager(), &MessagesManager::on_get_message_calendar_from_database, dialog_id, + fixed_from_message_id, first_db_message_id, filter, std::move(r_calendar), std::move(promise)); }); MessageDbDialogCalendarQuery db_query; db_query.dialog_id = dialog_id; @@ -21472,48 +20509,48 @@ td_api::object_ptr MessagesManager::get_dialog_message_ db_query.from_message_id = fixed_from_message_id; db_query.tz_offset = static_cast(td_->option_manager_->get_option_integer("utc_time_offset")); G()->td_db()->get_message_db_async()->get_dialog_message_calendar(db_query, std::move(new_promise)); - return {}; + return; } } if (filter == MessageSearchFilter::FailedToSend) { - promise.set_value(Unit()); - return {}; + return promise.set_value(td_api::make_object()); } - LOG(DEBUG) << "Get message calendar from server in " << dialog_id << " from " << from_message_id; - switch (dialog_id.get_type()) { - case DialogType::None: case DialogType::User: case DialogType::Chat: case DialogType::Channel: - td_->create_handler(std::move(promise)) - ->send(dialog_id, from_message_id, filter, random_id); - break; + return get_message_calendar_from_server(dialog_id, saved_messages_topic_id, from_message_id, filter, + std::move(promise)); case DialogType::SecretChat: - promise.set_value(Unit()); - break; + return promise.set_value(td_api::make_object()); + case DialogType::None: default: UNREACHABLE(); - promise.set_error(Status::Error(500, "Search messages is not supported")); + return promise.set_error(Status::Error(500, "Message search is not supported")); } - return {}; } -void MessagesManager::on_get_message_calendar_from_database(int64 random_id, DialogId dialog_id, - MessageId from_message_id, MessageId first_db_message_id, - MessageSearchFilter filter, - Result r_calendar, - Promise promise) { +void MessagesManager::get_message_calendar_from_server(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, + Promise> &&promise) { + td_->create_handler(std::move(promise)) + ->send(dialog_id, saved_messages_topic_id, from_message_id, filter); +} + +void MessagesManager::on_get_message_calendar_from_database( + DialogId dialog_id, MessageId from_message_id, MessageId first_db_message_id, MessageSearchFilter filter, + Result r_calendar, Promise> promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); if (r_calendar.is_error()) { LOG(ERROR) << "Failed to get message calendar from the database: " << r_calendar.error(); if (first_db_message_id != MessageId::min() && dialog_id.get_type() != DialogType::SecretChat && filter != MessageSearchFilter::FailedToSend) { - found_dialog_message_calendars_.erase(random_id); + return get_message_calendar_from_server(dialog_id, SavedMessagesTopicId(), from_message_id, filter, + std::move(promise)); } - return promise.set_value(Unit()); + return promise.set_value(td_api::make_object()); } CHECK(!from_message_id.is_scheduled()); CHECK(!first_db_message_id.is_scheduled()); @@ -21523,10 +20560,6 @@ void MessagesManager::on_get_message_calendar_from_database(int64 random_id, Dia Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - auto it = found_dialog_message_calendars_.find(random_id); - CHECK(it != found_dialog_message_calendars_.end()); - CHECK(it->second == nullptr); - vector> periods; periods.reserve(calendar.messages.size()); for (size_t i = 0; i < calendar.messages.size(); i++) { @@ -21539,7 +20572,8 @@ void MessagesManager::on_get_message_calendar_from_database(int64 random_id, Dia if (periods.empty() && first_db_message_id != MessageId::min() && dialog_id.get_type() != DialogType::SecretChat) { LOG(INFO) << "No messages found in database"; - found_dialog_message_calendars_.erase(it); + return get_message_calendar_from_server(dialog_id, SavedMessagesTopicId(), from_message_id, filter, + std::move(promise)); } else { auto total_count = d->message_count_by_index[message_search_filter_index(filter)]; vector> days; @@ -21549,15 +20583,15 @@ void MessagesManager::on_get_message_calendar_from_database(int64 random_id, Dia days.push_back(td_api::make_object( period.second, get_message_object(dialog_id, m, "on_get_message_calendar_from_database"))); } - it->second = td_api::make_object(total_count, std::move(days)); + return promise.set_value(td_api::make_object(total_count, std::move(days))); } - promise.set_value(Unit()); } MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( DialogId dialog_id, const string &query, const td_api::object_ptr &sender, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, - int64 &random_id, bool use_db, Promise &&promise) { + SavedMessagesTopicId saved_messages_topic_id, const ReactionType &tag, int64 &random_id, bool use_db, + Promise &&promise) { if (random_id != 0) { // request has already been sent before auto it = found_dialog_messages_.find(random_id); @@ -21571,8 +20605,9 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( random_id = 0; } LOG(INFO) << "Search messages with query \"" << query << "\" in " << dialog_id << " sent by " - << oneline(to_string(sender)) << " in thread of " << top_thread_message_id << " filtered by " << filter - << " from " << from_message_id << " with offset " << offset << " and limit " << limit; + << oneline(to_string(sender)) << " in thread of " << top_thread_message_id << " and in " + << saved_messages_topic_id << " filtered by " << filter << " from " << from_message_id << " with offset " + << offset << " and limit " << limit; FoundDialogMessages result; if (limit <= 0) { @@ -21606,7 +20641,7 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( promise.set_error(Status::Error(400, "Chat not found")); return result; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { promise.set_error(Status::Error(400, "Can't access the chat")); return result; } @@ -21617,16 +20652,17 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( return result; } auto sender_dialog_id = r_sender_dialog_id.move_as_ok(); - if (sender_dialog_id != DialogId() && !have_input_peer(sender_dialog_id, AccessRights::Know)) { + if (sender_dialog_id != DialogId() && + !td_->dialog_manager_->have_input_peer(sender_dialog_id, false, AccessRights::Know)) { promise.set_error(Status::Error(400, "Invalid message sender specified")); return result; } - if (sender_dialog_id == dialog_id && is_broadcast_channel(dialog_id)) { + if (sender_dialog_id == dialog_id && td_->dialog_manager_->is_broadcast_channel(dialog_id)) { sender_dialog_id = DialogId(); } if (filter == MessageSearchFilter::FailedToSend && sender_dialog_id.is_valid()) { - if (sender_dialog_id != get_my_dialog_id()) { + if (sender_dialog_id != td_->dialog_manager_->get_my_dialog_id()) { promise.set_value(Unit()); return result; } @@ -21635,11 +20671,18 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( if (top_thread_message_id != MessageId()) { if (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server()) { - promise.set_error(Status::Error(400, "Invalid message thread ID specified")); + promise.set_error(Status::Error(400, "Invalid message thread specified")); return result; } - if (dialog_id.get_type() != DialogType::Channel || is_broadcast_channel(dialog_id)) { - promise.set_error(Status::Error(400, "Can't filter by message thread ID in the chat")); + if (dialog_id.get_type() != DialogType::Channel || td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + promise.set_error(Status::Error(400, "Can't filter by message thread in the chat")); + return result; + } + } + { + auto status = saved_messages_topic_id.is_valid_in(td_, dialog_id); + if (status.is_error()) { + promise.set_error(std::move(status)); return result; } } @@ -21649,11 +20692,6 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( return result; } - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || found_dialog_messages_.count(random_id) > 0); - found_dialog_messages_[random_id]; // reserve place for result - if (filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::UnreadReaction) { if (!query.empty()) { promise.set_error(Status::Error(400, "Non-empty query is unsupported with the specified filter")); @@ -21663,11 +20701,26 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( promise.set_error(Status::Error(400, "Filtering by sender is unsupported with the specified filter")); return result; } + if (saved_messages_topic_id.is_valid()) { + promise.set_value(Unit()); + return result; + } + } + + if (tag.is_paid_reaction()) { + promise.set_value(Unit()); + return result; } + do { + random_id = Random::secure_int64(); + } while (random_id == 0 || found_dialog_messages_.count(random_id) > 0); + found_dialog_messages_[random_id]; // reserve place for result + // Trying to use database if (use_db && query.empty() && G()->use_message_database() && filter != MessageSearchFilter::Empty && - !sender_dialog_id.is_valid() && top_thread_message_id == MessageId()) { + !sender_dialog_id.is_valid() && top_thread_message_id == MessageId() && + saved_messages_topic_id == SavedMessagesTopicId() && tag.is_empty()) { MessageId first_db_message_id = get_first_database_message_id_by_index(d, filter); int32 message_count = d->message_count_by_index[message_search_filter_index(filter)]; auto fixed_from_message_id = from_message_id; @@ -21698,6 +20751,7 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( } } if (filter == MessageSearchFilter::FailedToSend) { + found_dialog_messages_.erase(random_id); promise.set_value(Unit()); return result; } @@ -21711,45 +20765,29 @@ MessagesManager::FoundDialogMessages MessagesManager::search_dialog_messages( case DialogType::Chat: case DialogType::Channel: td_->create_handler(std::move(promise)) - ->send(dialog_id, query, sender_dialog_id, from_message_id, offset, limit, filter, top_thread_message_id, - random_id); + ->send(dialog_id, saved_messages_topic_id, query, sender_dialog_id, from_message_id, offset, limit, filter, + top_thread_message_id, tag, random_id); break; case DialogType::SecretChat: if (filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::Pinned || filter == MessageSearchFilter::UnreadReaction) { promise.set_value(Unit()); } else { - promise.set_error(Status::Error(500, "Search messages in secret chats is not supported")); + promise.set_error(Status::Error(500, "Message search is not supported in secret chats")); } break; case DialogType::None: default: UNREACHABLE(); - promise.set_error(Status::Error(500, "Search messages is not supported")); + promise.set_error(Status::Error(500, "Message search is not supported")); } return result; } -MessagesManager::FoundMessages MessagesManager::search_call_messages(const string &offset, int32 limit, - bool only_missed, int64 &random_id, bool use_db, - Promise &&promise) { - if (random_id != 0) { - // request has already been sent before - auto it = found_call_messages_.find(random_id); - if (it != found_call_messages_.end()) { - auto result = std::move(it->second); - found_call_messages_.erase(it); - promise.set_value(Unit()); - return result; - } - random_id = 0; - } - LOG(INFO) << "Search call messages from " << offset << " with limit " << limit; - - FoundMessages result; +void MessagesManager::search_call_messages(const string &offset, int32 limit, bool only_missed, + Promise> &&promise) { if (limit <= 0) { - promise.set_error(Status::Error(400, "Parameter limit must be positive")); - return result; + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); } if (limit > MAX_SEARCH_MESSAGES) { limit = MAX_SEARCH_MESSAGES; @@ -21759,21 +20797,14 @@ MessagesManager::FoundMessages MessagesManager::search_call_messages(const strin if (!offset.empty()) { auto r_offset_server_message_id = to_integer_safe(offset); if (r_offset_server_message_id.is_error()) { - promise.set_error(Status::Error(400, "Invalid offset specified")); - return result; + return promise.set_error(Status::Error(400, "Invalid offset specified")); } offset_message_id = MessageId(ServerMessageId(r_offset_server_message_id.ok())); } - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || found_call_messages_.count(random_id) > 0); - found_call_messages_[random_id]; // reserve place for result - auto filter = only_missed ? MessageSearchFilter::MissedCall : MessageSearchFilter::Call; - - if (use_db && G()->use_message_database()) { + if (G()->use_message_database()) { // try to use database MessageId first_db_message_id = calls_db_state_.first_calls_database_message_id_by_index[call_message_search_filter_index(filter)]; @@ -21793,18 +20824,17 @@ MessagesManager::FoundMessages MessagesManager::search_call_messages(const strin db_query.from_unique_message_id = fixed_from_message_id.get_server_message_id().get(); db_query.limit = limit; G()->td_db()->get_message_db_async()->get_calls( - db_query, PromiseCreator::lambda([random_id, first_db_message_id, filter, promise = std::move(promise)]( - Result calls_result) mutable { + db_query, + PromiseCreator::lambda([first_db_message_id, offset_message_id, limit, filter, + promise = std::move(promise)](Result calls_result) mutable { send_closure(G()->messages_manager(), &MessagesManager::on_message_db_calls_result, std::move(calls_result), - random_id, first_db_message_id, filter, std::move(promise)); + first_db_message_id, offset_message_id, limit, filter, std::move(promise)); })); - return result; + return; } } - td_->create_handler(std::move(promise)) - ->send(DialogId(), "", DialogId(), offset_message_id, 0, limit, filter, MessageId(), random_id); - return result; + td_->create_handler(std::move(promise))->send(offset_message_id, limit, filter); } void MessagesManager::search_outgoing_document_messages(const string &query, int32 limit, @@ -21819,6 +20849,32 @@ void MessagesManager::search_outgoing_document_messages(const string &query, int td_->create_handler(std::move(promise))->send(query, limit); } +void MessagesManager::search_hashtag_posts(string hashtag, string offset_str, int32 limit, + Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (limit > MAX_SEARCH_MESSAGES) { + limit = MAX_SEARCH_MESSAGES; + } + + TRY_RESULT_PROMISE(promise, offset, MessageSearchOffset::from_string(offset_str)); + + bool is_cashtag = false; + if (hashtag[0] == '#' || hashtag[0] == '$') { + is_cashtag = (hashtag[0] == '$'); + hashtag = hashtag.substr(1); + } + if (hashtag.empty()) { + return promise.set_value(get_found_messages_object({}, "search_hashtag_posts")); + } + send_closure(is_cashtag ? td_->cashtag_search_hints_ : td_->hashtag_search_hints_, &HashtagHints::hashtag_used, + hashtag); + + td_->create_handler(std::move(promise)) + ->send(PSTRING() << (is_cashtag ? '$' : '#') << hashtag, offset, limit); +} + void MessagesManager::search_dialog_recent_location_messages(DialogId dialog_id, int32 limit, Promise> &&promise) { LOG(INFO) << "Search recent location messages in " << dialog_id << " with limit " << limit; @@ -21844,149 +20900,143 @@ void MessagesManager::search_dialog_recent_location_messages(DialogId dialog_id, return promise.set_value(get_messages_object(0, vector>(), false)); default: UNREACHABLE(); - promise.set_error(Status::Error(500, "Search messages is not supported")); + promise.set_error(Status::Error(500, "Message search is not supported")); } } -vector MessagesManager::get_active_live_location_messages(Promise &&promise) { - if (!G()->use_message_database()) { +void MessagesManager::load_active_live_location_messages(Promise &&promise) { + if (!G()->use_message_database() || td_->auth_manager_->is_bot()) { are_active_live_location_messages_loaded_ = true; } - - if (!are_active_live_location_messages_loaded_) { - load_active_live_location_messages_queries_.push_back(std::move(promise)); - if (load_active_live_location_messages_queries_.size() == 1u) { - LOG(INFO) << "Trying to load active live location messages from database"; - G()->td_db()->get_sqlite_pmc()->get( - "di_active_live_location_messages", PromiseCreator::lambda([](string value) { - send_closure(G()->messages_manager(), - &MessagesManager::on_load_active_live_location_full_message_ids_from_database, - std::move(value)); - })); - } - return {}; + if (are_active_live_location_messages_loaded_) { + return promise.set_value(Unit()); } - - promise.set_value(Unit()); - vector result; - for (auto &full_message_id : active_live_location_full_message_ids_) { - auto m = get_message(full_message_id); - CHECK(m != nullptr); - CHECK(m->content->get_type() == MessageContentType::LiveLocation); - CHECK(!m->message_id.is_scheduled()); - - if (m->is_failed_to_send) { - continue; - } - - auto live_period = get_message_content_live_location_period(m->content.get()); - if (live_period <= G()->unix_time() - m->date) { // bool is_expired flag? - // live location is expired - continue; - } - result.push_back(full_message_id); + load_active_live_location_messages_queries_.push_back(std::move(promise)); + if (load_active_live_location_messages_queries_.size() == 1u) { + LOG(INFO) << "Trying to load active live location messages from database"; + G()->td_db()->get_sqlite_pmc()->get( + "di_active_live_location_messages", PromiseCreator::lambda([](string value) { + send_closure(G()->messages_manager(), + &MessagesManager::on_load_active_live_location_message_full_ids_from_database, std::move(value)); + })); } - - return result; } -void MessagesManager::on_load_active_live_location_full_message_ids_from_database(string value) { +void MessagesManager::on_load_active_live_location_message_full_ids_from_database(string value) { if (G()->close_flag()) { return; } if (value.empty()) { LOG(INFO) << "Active live location messages aren't found in the database"; - on_load_active_live_location_messages_finished(); - - if (!active_live_location_full_message_ids_.empty()) { + are_active_live_location_messages_loaded_ = true; + if (!active_live_location_message_full_ids_.empty()) { save_active_live_locations(); } + set_promises(load_active_live_location_messages_queries_); return; } LOG(INFO) << "Successfully loaded active live location messages list of size " << value.size() << " from database"; - auto new_full_message_ids = std::move(active_live_location_full_message_ids_); - vector old_full_message_ids; - log_event_parse(old_full_message_ids, value).ensure(); + const auto new_message_full_ids = std::move(active_live_location_message_full_ids_); + vector old_message_full_ids; + log_event_parse(old_message_full_ids, value).ensure(); // TODO asynchronously load messages from database - active_live_location_full_message_ids_.clear(); - for (const auto &full_message_id : old_full_message_ids) { - Message *m = get_message_force(full_message_id, "on_load_active_live_location_full_message_ids_from_database"); + active_live_location_message_full_ids_.clear(); + for (const auto &message_full_id : old_message_full_ids) { + Message *m = get_message_force(message_full_id, "on_load_active_live_location_message_full_ids_from_database"); if (m != nullptr) { - try_add_active_live_location(full_message_id.get_dialog_id(), m); + try_add_active_live_location(message_full_id.get_dialog_id(), m); } } - for (const auto &full_message_id : new_full_message_ids) { - add_active_live_location(full_message_id); + for (const auto &message_full_id : new_message_full_ids) { + add_active_live_location(message_full_id); } - on_load_active_live_location_messages_finished(); - - if (!new_full_message_ids.empty() || old_full_message_ids.size() != active_live_location_full_message_ids_.size()) { + are_active_live_location_messages_loaded_ = true; + if (new_message_full_ids.size() != active_live_location_message_full_ids_.size()) { + send_update_active_live_location_messages(); + } + if (!new_message_full_ids.empty() || old_message_full_ids.size() != active_live_location_message_full_ids_.size()) { save_active_live_locations(); } -} - -void MessagesManager::on_load_active_live_location_messages_finished() { - are_active_live_location_messages_loaded_ = true; set_promises(load_active_live_location_messages_queries_); } -void MessagesManager::try_add_active_live_location(DialogId dialog_id, const Message *m) { +bool MessagesManager::try_add_active_live_location(DialogId dialog_id, const Message *m) { CHECK(m != nullptr); - if (td_->auth_manager_->is_bot()) { - return; - } - if (m->content->get_type() != MessageContentType::LiveLocation || m->message_id.is_scheduled() || - m->message_id.is_local() || m->via_bot_user_id.is_valid() || m->forward_info != nullptr) { - return; + if (td_->auth_manager_->is_bot() || m->content->get_type() != MessageContentType::LiveLocation || + m->message_id.is_scheduled() || m->message_id.is_local() || m->message_id.is_yet_unsent() || + m->via_bot_user_id.is_valid() || m->via_business_bot_user_id.is_valid() || m->forward_info != nullptr) { + return false; } auto live_period = get_message_content_live_location_period(m->content.get()); if (live_period <= G()->unix_time() - m->date + 1) { // bool is_expired flag? // live location is expired - return; + return false; } - add_active_live_location({dialog_id, m->message_id}); + return add_active_live_location({dialog_id, m->message_id}); } -void MessagesManager::add_active_live_location(FullMessageId full_message_id) { +bool MessagesManager::add_active_live_location(MessageFullId message_full_id) { if (td_->auth_manager_->is_bot()) { - return; + return false; } - if (!active_live_location_full_message_ids_.insert(full_message_id).second) { - return; + CHECK(message_full_id.get_message_id().is_valid()); + if (!active_live_location_message_full_ids_.insert(message_full_id).second) { + return false; } - // TODO add timer for live location expiration - - if (!G()->use_message_database()) { - return; + if (G()->use_message_database()) { + if (are_active_live_location_messages_loaded_) { + save_active_live_locations(); + } else if (load_active_live_location_messages_queries_.empty()) { + // load active live locations and save after that + load_active_live_location_messages(Auto()); + } } + return true; +} - if (are_active_live_location_messages_loaded_) { - save_active_live_locations(); - } else if (load_active_live_location_messages_queries_.empty()) { - // load active live locations and save after that - get_active_live_location_messages(Auto()); - } +bool MessagesManager::delete_active_live_location(MessageFullId message_full_id) { + return active_live_location_message_full_ids_.erase(message_full_id) != 0; } -bool MessagesManager::delete_active_live_location(DialogId dialog_id, const Message *m) { - CHECK(m != nullptr); - return active_live_location_full_message_ids_.erase(FullMessageId{dialog_id, m->message_id}) != 0; +void MessagesManager::schedule_active_live_location_expiration() { + if (active_live_location_message_full_ids_.empty()) { + live_location_expire_timeout_.cancel_timeout(); + } else { + double expires_in = std::numeric_limits::max(); + for (auto message_full_id : active_live_location_message_full_ids_) { + const auto *m = get_message(message_full_id); + CHECK(m != nullptr); + double live_period = get_message_content_live_location_period(m->content.get()); + if (live_period > 2e9) { + continue; + } + expires_in = min(expires_in, live_period + m->date - G()->unix_time()); + } + if (expires_in < 2e9) { + LOG(INFO) << "Schedule live location expiration in " << expires_in; + live_location_expire_timeout_.set_callback(std::move(on_live_location_expire_timeout_callback)); + live_location_expire_timeout_.set_callback_data(static_cast(this)); + live_location_expire_timeout_.set_timeout_in(expires_in); + } else { + LOG(INFO) << "Have no active expiring live locations"; + } + } } void MessagesManager::save_active_live_locations() { CHECK(are_active_live_location_messages_loaded_); - LOG(INFO) << "Save active live locations of size " << active_live_location_full_message_ids_.size() << " to database"; + LOG(INFO) << "Save active live locations of size " << active_live_location_message_full_ids_.size() << " to database"; if (G()->use_message_database()) { G()->td_db()->get_sqlite_pmc()->set("di_active_live_location_messages", - log_event_store(active_live_location_full_message_ids_).as_slice().str(), + log_event_store(active_live_location_message_full_ids_).as_slice().str(), Auto()); } } @@ -22018,8 +21068,9 @@ void MessagesManager::on_message_live_location_viewed(Dialog *d, const Message * return; } - if (m->is_outgoing || !m->message_id.is_server() || m->via_bot_user_id.is_valid() || !m->sender_user_id.is_valid() || - td_->contacts_manager_->is_user_bot(m->sender_user_id) || m->forward_info != nullptr) { + if (m->is_outgoing || !m->message_id.is_server() || m->via_bot_user_id.is_valid() || + m->via_business_bot_user_id.is_valid() || !m->sender_user_id.is_valid() || + td_->user_manager_->is_user_bot(m->sender_user_id) || m->forward_info != nullptr) { return; } @@ -22035,9 +21086,9 @@ void MessagesManager::on_message_live_location_viewed(Dialog *d, const Message * } live_location_task_id = ++viewed_live_location_task_id_; - auto &full_message_id = viewed_live_location_tasks_[live_location_task_id]; - full_message_id = FullMessageId(d->dialog_id, m->message_id); - view_message_live_location_on_server_impl(live_location_task_id, full_message_id); + auto &message_full_id = viewed_live_location_tasks_[live_location_task_id]; + message_full_id = MessageFullId(d->dialog_id, m->message_id); + view_message_live_location_on_server_impl(live_location_task_id, message_full_id); } void MessagesManager::view_message_live_location_on_server(int64 task_id) { @@ -22050,15 +21101,15 @@ void MessagesManager::view_message_live_location_on_server(int64 task_id) { return; } - auto full_message_id = it->second; - Dialog *d = get_dialog(full_message_id.get_dialog_id()); - const Message *m = get_message_force(d, full_message_id.get_message_id(), "view_message_live_location_on_server"); + auto message_full_id = it->second; + Dialog *d = get_dialog(message_full_id.get_dialog_id()); + const Message *m = get_message_force(d, message_full_id.get_message_id(), "view_message_live_location_on_server"); if (m == nullptr || get_message_content_live_location_period(m->content.get()) <= G()->unix_time() - m->date + 1) { // the message was deleted or live location is expired viewed_live_location_tasks_.erase(it); auto live_locations_it = pending_viewed_live_locations_.find(d->dialog_id); CHECK(live_locations_it != pending_viewed_live_locations_.end()); - auto erased_count = live_locations_it->second.erase(full_message_id.get_message_id()); + auto erased_count = live_locations_it->second.erase(message_full_id.get_message_id()); CHECK(erased_count > 0); if (live_locations_it->second.empty()) { pending_viewed_live_locations_.erase(live_locations_it); @@ -22066,14 +21117,14 @@ void MessagesManager::view_message_live_location_on_server(int64 task_id) { return; } - view_message_live_location_on_server_impl(task_id, full_message_id); + view_message_live_location_on_server_impl(task_id, message_full_id); } -void MessagesManager::view_message_live_location_on_server_impl(int64 task_id, FullMessageId full_message_id) { +void MessagesManager::view_message_live_location_on_server_impl(int64 task_id, MessageFullId message_full_id) { auto promise = PromiseCreator::lambda([actor_id = actor_id(this), task_id](Unit result) { send_closure(actor_id, &MessagesManager::on_message_live_location_viewed_on_server, task_id); }); - read_message_contents_on_server(full_message_id.get_dialog_id(), {full_message_id.get_message_id()}, 0, + read_message_contents_on_server(message_full_id.get_dialog_id(), {message_full_id.get_message_id()}, 0, std::move(promise), true); } @@ -22092,8 +21143,8 @@ void MessagesManager::on_message_live_location_viewed_on_server(int64 task_id) { void MessagesManager::try_add_bot_command_message_id(DialogId dialog_id, const Message *m) { CHECK(m != nullptr); - if (td_->auth_manager_->is_bot() || !is_group_dialog(dialog_id) || m->message_id.is_scheduled() || - !has_bot_commands(get_message_content_text(m->content.get()))) { + if (td_->auth_manager_->is_bot() || !td_->dialog_manager_->is_group_dialog(dialog_id) || + m->message_id.is_scheduled() || !has_bot_commands(get_message_content_text(m->content.get()))) { return; } @@ -22113,23 +21164,23 @@ void MessagesManager::delete_bot_command_message_id(DialogId dialog_id, MessageI } } -FileSourceId MessagesManager::get_message_file_source_id(FullMessageId full_message_id, bool force) { +FileSourceId MessagesManager::get_message_file_source_id(MessageFullId message_full_id, bool force) { if (!force) { if (td_->auth_manager_->is_bot()) { return FileSourceId(); } - auto dialog_id = full_message_id.get_dialog_id(); - auto message_id = full_message_id.get_message_id(); + auto dialog_id = message_full_id.get_dialog_id(); + auto message_id = message_full_id.get_message_id(); if (!dialog_id.is_valid() || !(message_id.is_valid() || message_id.is_valid_scheduled()) || dialog_id.get_type() == DialogType::SecretChat || !message_id.is_any_server()) { return FileSourceId(); } } - auto &file_source_id = full_message_id_to_file_source_id_[full_message_id]; + auto &file_source_id = message_full_id_to_file_source_id_[message_full_id]; if (!file_source_id.is_valid()) { - file_source_id = td_->file_reference_manager_->create_message_file_source(full_message_id); + file_source_id = td_->file_reference_manager_->create_message_file_source(message_full_id); } return file_source_id; } @@ -22149,7 +21200,7 @@ void MessagesManager::add_message_file_sources(DialogId dialog_id, const Message } // do not create file_source_id for messages without file_ids - auto file_source_id = get_message_file_source_id(FullMessageId(dialog_id, m->message_id)); + auto file_source_id = get_message_file_source_id(MessageFullId(dialog_id, m->message_id)); if (file_source_id.is_valid()) { for (auto file_id : file_ids) { td_->file_manager_->add_file_source(file_id, file_source_id); @@ -22168,7 +21219,7 @@ void MessagesManager::remove_message_file_sources(DialogId dialog_id, const Mess } // do not create file_source_id for messages without file_ids - auto file_source_id = get_message_file_source_id(FullMessageId(dialog_id, m->message_id)); + auto file_source_id = get_message_file_source_id(MessageFullId(dialog_id, m->message_id)); if (file_source_id.is_valid()) { for (auto file_id : file_ids) { auto file_view = td_->file_manager_->get_file_view(file_id); @@ -22189,12 +21240,12 @@ void MessagesManager::change_message_files(DialogId dialog_id, const Message *m, return; } - FullMessageId full_message_id{dialog_id, m->message_id}; + MessageFullId message_full_id{dialog_id, m->message_id}; bool need_delete_files = need_delete_message_files(dialog_id, m); - auto file_source_id = get_message_file_source_id(full_message_id); + auto file_source_id = get_message_file_source_id(message_full_id); for (auto file_id : old_file_ids) { if (!td::contains(new_file_ids, file_id)) { - if (need_delete_files && need_delete_file(full_message_id, file_id)) { + if (need_delete_files && need_delete_file(message_full_id, file_id)) { send_closure(G()->file_manager(), &FileManager::delete_file, file_id, Promise(), "change_message_files"); } if (file_source_id.is_valid()) { @@ -22312,7 +21363,7 @@ td_api::object_ptr MessagesManager::get_found_chat_me vector> result; result.reserve(found_dialog_messages.message_ids.size()); for (const auto &message_id : found_dialog_messages.message_ids) { - auto message = get_message_object(dialog_id, get_message_force(d, message_id, source), source); + auto message = get_message_object(d, message_id, source); if (message != nullptr) { result.push_back(std::move(message)); } @@ -22325,9 +21376,9 @@ td_api::object_ptr MessagesManager::get_found_chat_me td_api::object_ptr MessagesManager::get_found_messages_object( const FoundMessages &found_messages, const char *source) { vector> result; - result.reserve(found_messages.full_message_ids.size()); - for (const auto &full_message_id : found_messages.full_message_ids) { - auto message = get_message_object(full_message_id, source); + result.reserve(found_messages.message_full_ids.size()); + for (const auto &message_full_id : found_messages.message_full_ids) { + auto message = get_message_object(message_full_id, source); if (message != nullptr) { result.push_back(std::move(message)); } @@ -22337,36 +21388,20 @@ td_api::object_ptr MessagesManager::get_found_messages_ob found_messages.next_offset); } -MessagesManager::FoundMessages MessagesManager::offline_search_messages(DialogId dialog_id, const string &query, - string offset, int32 limit, - MessageSearchFilter filter, int64 &random_id, - Promise &&promise) { +void MessagesManager::offline_search_messages(DialogId dialog_id, const string &query, string offset, int32 limit, + MessageSearchFilter filter, + Promise> &&promise) { if (!G()->use_message_database()) { - promise.set_error(Status::Error(400, "Message database is required to search messages in secret chats")); - return {}; - } - - if (random_id != 0) { - // request has already been sent before - auto it = found_fts_messages_.find(random_id); - CHECK(it != found_fts_messages_.end()); - auto result = std::move(it->second); - found_fts_messages_.erase(it); - promise.set_value(Unit()); - return result; + return promise.set_error(Status::Error(400, "Message database is required to search messages in secret chats")); } - if (query.empty()) { - promise.set_value(Unit()); - return {}; + return promise.set_value(get_found_messages_object({}, "offline_search_messages")); } if (dialog_id != DialogId() && !have_dialog_force(dialog_id, "offline_search_messages")) { - promise.set_error(Status::Error(400, "Chat not found")); - return {}; + return promise.set_error(Status::Error(400, "Chat not found")); } if (limit <= 0) { - promise.set_error(Status::Error(400, "Limit must be positive")); - return {}; + return promise.set_error(Status::Error(400, "Limit must be positive")); } if (limit > MAX_SEARCH_MESSAGES) { limit = MAX_SEARCH_MESSAGES; @@ -22379,71 +21414,53 @@ MessagesManager::FoundMessages MessagesManager::offline_search_messages(DialogId if (!offset.empty()) { auto r_from_search_id = to_integer_safe(offset); if (r_from_search_id.is_error()) { - promise.set_error(Status::Error(400, "Invalid offset specified")); - return {}; + return promise.set_error(Status::Error(400, "Invalid offset specified")); } fts_query.from_search_id = r_from_search_id.ok(); } fts_query.limit = limit; - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || found_fts_messages_.count(random_id) > 0); - found_fts_messages_[random_id]; // reserve place for result - G()->td_db()->get_message_db_async()->get_messages_fts( - std::move(fts_query), - PromiseCreator::lambda([random_id, offset = std::move(offset), limit, - promise = std::move(promise)](Result fts_result) mutable { + std::move(fts_query), PromiseCreator::lambda([offset = std::move(offset), limit, promise = std::move(promise)]( + Result fts_result) mutable { send_closure(G()->messages_manager(), &MessagesManager::on_message_db_fts_result, std::move(fts_result), - std::move(offset), limit, random_id, std::move(promise)); + std::move(offset), limit, std::move(promise)); })); - - return {}; } void MessagesManager::on_message_db_fts_result(Result result, string offset, int32 limit, - int64 random_id, Promise &&promise) { + Promise> &&promise) { G()->ignore_result_if_closing(result); if (result.is_error()) { - found_fts_messages_.erase(random_id); return promise.set_error(result.move_as_error()); } auto fts_result = result.move_as_ok(); - auto it = found_fts_messages_.find(random_id); - CHECK(it != found_fts_messages_.end()); - auto &res = it->second.full_message_ids; - - res.reserve(fts_result.messages.size()); + FoundMessages found_messages; + found_messages.message_full_ids.reserve(fts_result.messages.size()); for (auto &message : fts_result.messages) { auto m = on_get_message_from_database(message, false, "on_message_db_fts_result"); if (m != nullptr) { - res.emplace_back(message.dialog_id, m->message_id); + found_messages.message_full_ids.emplace_back(message.dialog_id, m->message_id); } } - it->second.next_offset = fts_result.next_search_id <= 1 ? string() : to_string(fts_result.next_search_id); - it->second.total_count = offset.empty() && fts_result.messages.size() < static_cast(limit) - ? static_cast(fts_result.messages.size()) - : -1; + found_messages.next_offset = fts_result.next_search_id <= 1 ? string() : to_string(fts_result.next_search_id); + found_messages.total_count = offset.empty() && fts_result.messages.size() < static_cast(limit) + ? static_cast(fts_result.messages.size()) + : -1; - promise.set_value(Unit()); + promise.set_value(get_found_messages_object(found_messages, "on_message_db_fts_result")); } -void MessagesManager::on_message_db_calls_result(Result result, int64 random_id, - MessageId first_db_message_id, MessageSearchFilter filter, - Promise &&promise) { - G()->ignore_result_if_closing(result); - if (result.is_error()) { - found_call_messages_.erase(random_id); - return promise.set_error(result.move_as_error()); - } - auto calls_result = result.move_as_ok(); +void MessagesManager::on_message_db_calls_result(Result result, MessageId first_db_message_id, + MessageId offset_message_id, int32 limit, MessageSearchFilter filter, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + TRY_RESULT_PROMISE(promise, calls_result, std::move(result)); - auto it = found_call_messages_.find(random_id); - CHECK(it != found_call_messages_.end()); - auto &res = it->second.full_message_ids; + FoundMessages found_messages; + auto &res = found_messages.message_full_ids; CHECK(!first_db_message_id.is_scheduled()); res.reserve(calls_result.messages.size()); @@ -22457,145 +21474,78 @@ void MessagesManager::on_message_db_calls_result(Result re res.emplace_back(message.dialog_id, m->message_id); } } - it->second.total_count = calls_db_state_.message_count_by_index[call_message_search_filter_index(filter)]; + found_messages.total_count = calls_db_state_.message_count_by_index[call_message_search_filter_index(filter)]; if (next_offset_message_id.is_valid()) { - it->second.next_offset = PSTRING() << next_offset_message_id.get_server_message_id().get(); + found_messages.next_offset = PSTRING() << next_offset_message_id.get_server_message_id().get(); } if (res.empty() && first_db_message_id != MessageId::min()) { LOG(INFO) << "No messages found in database"; - found_call_messages_.erase(it); + return td_->create_handler(std::move(promise))->send(offset_message_id, limit, filter); } - promise.set_value(Unit()); + promise.set_value(get_found_messages_object(found_messages, "on_message_db_calls_result")); } -MessagesManager::FoundMessages MessagesManager::search_messages(FolderId folder_id, bool ignore_folder_id, - const string &query, const string &offset, int32 limit, - MessageSearchFilter filter, int32 min_date, - int32 max_date, int64 &random_id, - Promise &&promise) { - if (random_id != 0) { - // request has already been sent before - auto it = found_messages_.find(random_id); - CHECK(it != found_messages_.end()); - auto result = std::move(it->second); - found_messages_.erase(it); - promise.set_value(Unit()); - return result; +void MessagesManager::search_messages(DialogListId dialog_list_id, bool ignore_folder_id, bool broadcasts_only, + const string &query, const string &offset_str, int32 limit, + MessageSearchFilter filter, int32 min_date, int32 max_date, + Promise> &&promise) { + if (!dialog_list_id.is_folder()) { + return promise.set_error(Status::Error(400, "Wrong chat list specified")); } - if (limit <= 0) { - promise.set_error(Status::Error(400, "Parameter limit must be positive")); - return {}; + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); } if (limit > MAX_SEARCH_MESSAGES) { limit = MAX_SEARCH_MESSAGES; } - int32 offset_date = std::numeric_limits::max(); - DialogId offset_dialog_id; - MessageId offset_message_id; - bool is_offset_valid = [&] { - if (offset.empty()) { - return true; - } - - auto parts = full_split(offset, ','); - if (parts.size() != 3) { - return false; - } - auto r_offset_date = to_integer_safe(parts[0]); - auto r_offset_dialog_id = to_integer_safe(parts[1]); - auto r_offset_message_id = to_integer_safe(parts[2]); - if (r_offset_date.is_error() || r_offset_date.ok() <= 0 || r_offset_message_id.is_error() || - r_offset_dialog_id.is_error()) { - return false; - } - offset_date = r_offset_date.ok(); - offset_message_id = MessageId(ServerMessageId(r_offset_message_id.ok())); - offset_dialog_id = DialogId(r_offset_dialog_id.ok()); - if (!offset_message_id.is_valid() || !offset_dialog_id.is_valid() || - MessagesManager::get_input_peer_force(offset_dialog_id)->get_id() == telegram_api::inputPeerEmpty::ID) { - return false; - } - return true; - }(); - if (!is_offset_valid) { - promise.set_error(Status::Error(400, "Invalid offset specified")); - return {}; - } + TRY_RESULT_PROMISE(promise, offset, MessageSearchOffset::from_string(offset_str)); CHECK(filter != MessageSearchFilter::Call && filter != MessageSearchFilter::MissedCall); if (filter == MessageSearchFilter::Mention || filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::UnreadReaction || filter == MessageSearchFilter::FailedToSend || filter == MessageSearchFilter::Pinned) { - promise.set_error(Status::Error(400, "The filter is not supported")); - return {}; + return promise.set_error(Status::Error(400, "The filter is not supported")); } if (query.empty() && filter == MessageSearchFilter::Empty) { - promise.set_value(Unit()); - return {}; + return promise.set_value(get_found_messages_object({}, "search_messages")); } - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || found_messages_.count(random_id) > 0); - found_messages_[random_id]; // reserve place for result - - LOG(DEBUG) << "Search all messages filtered by " << filter << " with query = \"" << query << "\" from offset " - << offset << " and limit " << limit; - td_->create_handler(std::move(promise)) - ->send(folder_id, ignore_folder_id, query, offset_date, offset_dialog_id, offset_message_id, limit, filter, - min_date, max_date, random_id); - return {}; + ->send(dialog_list_id.get_folder_id(), ignore_folder_id, broadcasts_only, query, offset.date_, offset.dialog_id_, + offset.message_id_, limit, filter, min_date, max_date); } -int64 MessagesManager::get_dialog_message_by_date(DialogId dialog_id, int32 date, Promise &&promise) { - Dialog *d = get_dialog_force(dialog_id, "get_dialog_message_by_date"); - if (d == nullptr) { - promise.set_error(Status::Error(400, "Chat not found")); - return 0; - } - - if (!have_input_peer(dialog_id, AccessRights::Read)) { - promise.set_error(Status::Error(400, "Can't access the chat")); - return 0; - } +void MessagesManager::get_dialog_message_by_date(DialogId dialog_id, int32 date, + Promise> &&promise) { + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, true, AccessRights::Read, "get_dialog_message_by_date")); if (date <= 0) { date = 1; } - int64 random_id = 0; - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || get_dialog_message_by_date_results_.count(random_id) > 0); - get_dialog_message_by_date_results_[random_id]; // reserve place for result - auto message_id = d->ordered_messages.find_message_by_date(date, get_get_message_date(d)); if (message_id.is_valid() && (message_id == d->last_message_id || (*d->ordered_messages.get_const_iterator(message_id))->have_next())) { - get_dialog_message_by_date_results_[random_id] = {dialog_id, message_id}; - promise.set_value(Unit()); - return random_id; + return promise.set_value(get_message_object(d, message_id, "get_dialog_message_by_date")); } if (G()->use_message_database() && d->last_database_message_id != MessageId()) { CHECK(d->first_database_message_id != MessageId()); G()->td_db()->get_message_db_async()->get_dialog_message_by_date( dialog_id, d->first_database_message_id, d->last_database_message_id, date, - PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, date, random_id, + PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, date, promise = std::move(promise)](Result result) mutable { send_closure(actor_id, &MessagesManager::on_get_dialog_message_by_date_from_database, dialog_id, date, - random_id, std::move(result), std::move(promise)); + std::move(result), std::move(promise)); })); } else { - get_dialog_message_by_date_from_server(d, date, random_id, false, std::move(promise)); + get_dialog_message_by_date_from_server(d, date, false, std::move(promise)); } - return random_id; } void MessagesManager::run_affected_history_query_until_complete(DialogId dialog_id, AffectedHistoryQuery query, @@ -22630,9 +21580,9 @@ void MessagesManager::on_get_affected_history(DialogId dialog_id, AffectedHistor add_pending_channel_update(dialog_id, make_tl_object(), affected_history.pts_, affected_history.pts_count_, std::move(update_promise), "on_get_affected_history"); } else { - td_->updates_manager_->add_pending_pts_update(make_tl_object(), affected_history.pts_, - affected_history.pts_count_, Time::now(), std::move(update_promise), - "on_get_affected_history"); + td_->updates_manager_->add_pending_pts_update( + make_tl_object(), affected_history.pts_, affected_history.pts_count_, + Time::now() - (get_affected_messages ? 10.0 : 0.0), std::move(update_promise), "on_get_affected_history"); } } else if (affected_history.is_final_) { promise.set_value(Unit()); @@ -22644,16 +21594,16 @@ void MessagesManager::on_get_affected_history(DialogId dialog_id, AffectedHistor } std::function MessagesManager::get_get_message_date(const Dialog *d) const { - return [this, d](MessageId message_id) { - auto *m = get_message(d, message_id); + return [d](MessageId message_id) { + const auto *m = get_message_static(d, message_id); CHECK(m != nullptr); return m->date; }; } -void MessagesManager::on_get_dialog_message_by_date_from_database(DialogId dialog_id, int32 date, int64 random_id, - Result result, - Promise promise) { +void MessagesManager::on_get_dialog_message_by_date_from_database( + DialogId dialog_id, int32 date, Result result, + Promise> promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); Dialog *d = get_dialog(dialog_id); @@ -22666,50 +21616,42 @@ void MessagesManager::on_get_dialog_message_by_date_from_database(DialogId dialo LOG(ERROR) << "Failed to find " << m->message_id << " in " << dialog_id << " by date " << date; message_id = m->message_id; } - get_dialog_message_by_date_results_[random_id] = {dialog_id, message_id}; - promise.set_value(Unit()); + promise.set_value(get_message_object(d, message_id, "on_get_dialog_message_by_date_from_database")); return; } // TODO if m == nullptr, we need to just adjust it to the next non-nullptr message, not get from server } - return get_dialog_message_by_date_from_server(d, date, random_id, true, std::move(promise)); + return get_dialog_message_by_date_from_server(d, date, true, std::move(promise)); } -void MessagesManager::get_dialog_message_by_date_from_server(const Dialog *d, int32 date, int64 random_id, - bool after_database_search, Promise &&promise) { +void MessagesManager::get_dialog_message_by_date_from_server(const Dialog *d, int32 date, bool after_database_search, + Promise> &&promise) { CHECK(d != nullptr); if (d->have_full_history) { // request can always be done locally/in memory. There is no need to send request to the server if (after_database_search) { - return promise.set_value(Unit()); + return promise.set_value(nullptr); } auto message_id = d->ordered_messages.find_message_by_date(date, get_get_message_date(d)); if (message_id.is_valid()) { - get_dialog_message_by_date_results_[random_id] = {d->dialog_id, message_id}; + promise.set_value(get_message_object(d, message_id, "get_dialog_message_by_date_from_server")); + } else { + promise.set_value(nullptr); } - promise.set_value(Unit()); return; } - if (d->dialog_id.get_type() == DialogType::SecretChat) { - // there is no way to send request to the server - return promise.set_value(Unit()); - } + CHECK(d->dialog_id.get_type() != DialogType::SecretChat); - td_->create_handler(std::move(promise))->send(d->dialog_id, date, random_id); + td_->create_handler(std::move(promise))->send(d->dialog_id, date); } -void MessagesManager::on_get_dialog_message_by_date_success(DialogId dialog_id, int32 date, int64 random_id, - vector> &&messages, - Promise &&promise) { +void MessagesManager::on_get_dialog_message_by_date(DialogId dialog_id, int32 date, + vector> &&messages, + Promise> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); - auto it = get_dialog_message_by_date_results_.find(random_id); - CHECK(it != get_dialog_message_by_date_results_.end()); - auto &result = it->second; - CHECK(result == FullMessageId()); - for (auto &message : messages) { auto message_date = get_message_date(message); auto message_dialog_id = DialogId::get_message_dialog_id(message); @@ -22718,9 +21660,9 @@ void MessagesManager::on_get_dialog_message_by_date_success(DialogId dialog_id, continue; } if (message_date != 0 && message_date <= date) { - result = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, false, - "on_get_dialog_message_by_date_success"); - if (result != FullMessageId()) { + auto result = on_get_message(std::move(message), false, dialog_id.get_type() == DialogType::Channel, false, + "on_get_dialog_message_by_date_success"); + if (result != MessageFullId()) { const Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); auto message_id = d->ordered_messages.find_message_by_date(date, get_get_message_date(d)); @@ -22728,32 +21670,16 @@ void MessagesManager::on_get_dialog_message_by_date_success(DialogId dialog_id, LOG(ERROR) << "Failed to find " << result.get_message_id() << " in " << dialog_id << " by date " << date; message_id = result.get_message_id(); } - get_dialog_message_by_date_results_[random_id] = {dialog_id, message_id}; - // TODO result must be adjusted by local messages - promise.set_value(Unit()); - return; + return promise.set_value(get_message_object(d, message_id, "on_get_dialog_message_by_date")); } } } - promise.set_value(Unit()); -} - -void MessagesManager::on_get_dialog_message_by_date_fail(int64 random_id) { - auto erased_count = get_dialog_message_by_date_results_.erase(random_id); - CHECK(erased_count > 0); -} - -tl_object_ptr MessagesManager::get_dialog_message_by_date_object(int64 random_id) { - auto it = get_dialog_message_by_date_results_.find(random_id); - CHECK(it != get_dialog_message_by_date_results_.end()); - auto full_message_id = std::move(it->second); - get_dialog_message_by_date_results_.erase(it); - return get_message_object(full_message_id, "get_dialog_message_by_date_object"); + promise.set_value(nullptr); } void MessagesManager::get_dialog_sparse_message_positions( - DialogId dialog_id, MessageSearchFilter filter, MessageId from_message_id, int32 limit, - Promise> &&promise) { + DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageSearchFilter filter, + MessageId from_message_id, int32 limit, Promise> &&promise) { const Dialog *d = get_dialog_force(dialog_id, "get_dialog_sparse_message_positions"); if (d == nullptr) { return promise.set_error(Status::Error(400, "Chat not found")); @@ -22781,8 +21707,12 @@ void MessagesManager::get_dialog_sparse_message_positions( } else { from_message_id = from_message_id.get_next_server_message_id(); } + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_in(td_, dialog_id)); if (filter == MessageSearchFilter::FailedToSend || dialog_id.get_type() == DialogType::SecretChat) { + if (saved_messages_topic_id.is_valid()) { + return promise.set_value(td_api::make_object()); + } if (!G()->use_message_database()) { return promise.set_error(Status::Error(400, "Unsupported without message database")); } @@ -22816,7 +21746,7 @@ void MessagesManager::get_dialog_sparse_message_positions( case DialogType::Chat: case DialogType::Channel: td_->create_handler(std::move(promise)) - ->send(dialog_id, filter, from_message_id, limit); + ->send(dialog_id, saved_messages_topic_id, filter, from_message_id, limit); break; case DialogType::SecretChat: case DialogType::None: @@ -22826,7 +21756,7 @@ void MessagesManager::get_dialog_sparse_message_positions( } void MessagesManager::on_get_dialog_sparse_message_positions( - DialogId dialog_id, MessageSearchFilter filter, + DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageSearchFilter filter, telegram_api::object_ptr positions, Promise> &&promise) { auto message_positions = transform( @@ -22837,7 +21767,8 @@ void MessagesManager::on_get_dialog_sparse_message_positions( promise.set_value(td_api::make_object(positions->count_, std::move(message_positions))); } -void MessagesManager::get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, bool return_local, +void MessagesManager::get_dialog_message_count(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, bool return_local, Promise &&promise) { LOG(INFO) << "Get " << (return_local ? "local " : "") << "number of messages in " << dialog_id << " filtered by " << filter; @@ -22851,31 +21782,44 @@ void MessagesManager::get_dialog_message_count(DialogId dialog_id, MessageSearch return promise.set_error(Status::Error(400, "Can't use searchMessagesFilterEmpty")); } - auto dialog_type = dialog_id.get_type(); - int32 message_count = d->message_count_by_index[message_search_filter_index(filter)]; - if (message_count == -1 && filter == MessageSearchFilter::UnreadMention) { - message_count = d->unread_mention_count; - } - if (message_count == -1 && filter == MessageSearchFilter::UnreadReaction) { - message_count = d->unread_reaction_count; - } - if (message_count != -1 || return_local || dialog_type == DialogType::SecretChat || - filter == MessageSearchFilter::FailedToSend) { - return promise.set_value(std::move(message_count)); + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_in(td_, dialog_id)); + if (saved_messages_topic_id.is_valid()) { + if (filter == MessageSearchFilter::UnreadMention || filter == MessageSearchFilter::UnreadReaction || + filter == MessageSearchFilter::FailedToSend) { + return promise.set_value(static_cast(0)); + } + if (return_local) { + return promise.set_value(static_cast(-1)); + } + } else { + auto dialog_type = dialog_id.get_type(); + int32 message_count = d->message_count_by_index[message_search_filter_index(filter)]; + if (message_count == -1 && filter == MessageSearchFilter::UnreadMention) { + message_count = d->unread_mention_count; + } + if (message_count == -1 && filter == MessageSearchFilter::UnreadReaction) { + message_count = d->unread_reaction_count; + } + if (message_count != -1 || return_local || dialog_type == DialogType::SecretChat || + filter == MessageSearchFilter::FailedToSend) { + return promise.set_value(std::move(message_count)); + } } - get_dialog_message_count_from_server(dialog_id, filter, std::move(promise)); + get_dialog_message_count_from_server(dialog_id, saved_messages_topic_id, filter, std::move(promise)); } -void MessagesManager::get_dialog_message_count_from_server(DialogId dialog_id, MessageSearchFilter filter, - Promise &&promise) { - LOG(INFO) << "Get number of messages in " << dialog_id << " filtered by " << filter << " from the server"; +void MessagesManager::get_dialog_message_count_from_server(DialogId dialog_id, + SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, Promise &&promise) { + LOG(INFO) << "Get number of messages in " << dialog_id << " with " << saved_messages_topic_id << " filtered by " + << filter << " from the server"; switch (dialog_id.get_type()) { case DialogType::User: case DialogType::Chat: case DialogType::Channel: - td_->create_handler(std::move(promise))->send(dialog_id, filter); + td_->create_handler(std::move(promise))->send(dialog_id, saved_messages_topic_id, filter); break; case DialogType::None: case DialogType::SecretChat: @@ -22884,18 +21828,15 @@ void MessagesManager::get_dialog_message_count_from_server(DialogId dialog_id, M } } -void MessagesManager::get_dialog_message_position(FullMessageId full_message_id, MessageSearchFilter filter, - MessageId top_thread_message_id, Promise &&promise) { - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "get_dialog_message_position"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } +void MessagesManager::get_dialog_message_position(MessageFullId message_full_id, MessageSearchFilter filter, + MessageId top_thread_message_id, + SavedMessagesTopicId saved_messages_topic_id, + Promise &&promise) { + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, true, AccessRights::Read, "get_dialog_message_position")); - auto message_id = full_message_id.get_message_id(); + auto message_id = message_full_id.get_message_id(); const Message *m = get_message_force(d, message_id, "get_dialog_message_position"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); @@ -22910,7 +21851,7 @@ void MessagesManager::get_dialog_message_position(FullMessageId full_message_id, if (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server()) { return promise.set_error(Status::Error(400, "Invalid message thread identifier specified")); } - if (dialog_id.get_type() != DialogType::Channel || is_broadcast_channel(dialog_id)) { + if (dialog_id.get_type() != DialogType::Channel || td_->dialog_manager_->is_broadcast_channel(dialog_id)) { return promise.set_error(Status::Error(400, "Can't filter by message thread identifier in the chat")); } if (m->top_thread_message_id != top_thread_message_id || @@ -22918,6 +21859,8 @@ void MessagesManager::get_dialog_message_position(FullMessageId full_message_id, return promise.set_error(Status::Error(400, "Message doesn't belong to the message thread")); } } + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_in(td_, dialog_id)); + if (dialog_id.get_type() == DialogType::SecretChat) { return promise.set_error(Status::Error(400, "The method can't be used in secret chats")); } @@ -22928,7 +21871,7 @@ void MessagesManager::get_dialog_message_position(FullMessageId full_message_id, } td_->create_handler(std::move(promise)) - ->send(dialog_id, message_id, filter, top_thread_message_id); + ->send(dialog_id, message_id, filter, top_thread_message_id, saved_messages_topic_id); } void MessagesManager::preload_newer_messages(const Dialog *d, MessageId max_message_id) { @@ -23039,6 +21982,9 @@ unique_ptr MessagesManager::parse_message(Dialog *d, M break; } } + if (m->reactions != nullptr) { + m->reactions->fix_my_recent_chooser_dialog_id(td_->dialog_manager_->get_my_dialog_id()); + } } if (m->contains_mention && td_->auth_manager_->is_bot()) { m->contains_mention = false; @@ -23061,6 +22007,12 @@ unique_ptr MessagesManager::parse_message(Dialog *d, M break; } } + if (m->is_pinned && is_scheduled) { + m->is_pinned = false; + } + if (dialog_id == td_->dialog_manager_->get_my_dialog_id() && !m->saved_messages_topic_id.is_valid()) { + m->saved_messages_topic_id = SavedMessagesTopicId(dialog_id, m->forward_info.get(), m->real_forward_from_dialog_id); + } LOG(INFO) << "Loaded " << m->message_id << " in " << dialog_id << " of size " << value.size() << " from database"; return message; @@ -23068,9 +22020,10 @@ unique_ptr MessagesManager::parse_message(Dialog *d, M void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId from_message_id, MessageId old_last_database_message_id, int32 offset, int32 limit, - bool from_the_end, bool only_local, - vector &&messages, Promise &&promise) { + bool only_local, vector &&messages, + Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); + bool from_the_end = from_message_id == MessageId::max(); CHECK(-limit < offset && offset <= 0); CHECK(offset < 0 || from_the_end); CHECK(!from_message_id.is_scheduled()); @@ -23084,11 +22037,8 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId LOG(INFO) << "Reget chat history from database in " << dialog_id << ", because last database message was changed from " << old_last_database_message_id << " to " << d->last_database_message_id; - if (from_the_end) { - get_history_from_the_end_impl(d, true, only_local, std::move(promise), "on_get_history_from_database 20"); - } else { - get_history_impl(d, from_message_id, offset, limit, true, only_local, std::move(promise)); - } + get_history_impl(d, from_message_id, offset, limit, true, only_local, std::move(promise), + "on_get_history_from_database 20"); return; } @@ -23190,7 +22140,8 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId if (first_received_message_id < d->last_database_message_id) { set_dialog_last_database_message_id(d, first_received_message_id, "on_get_history_from_database 12"); - get_history_from_the_end_impl(d, true, only_local, std::move(promise), "on_get_history_from_database 21"); + get_history_impl(d, MessageId::max(), 0, -1, true, only_local, std::move(promise), + "on_get_history_from_database 21"); return; } @@ -23221,6 +22172,11 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId } } + if (!first_added_message_id.is_valid() && !only_local && dialog_id.get_type() != DialogType::SecretChat) { + load_messages_impl(d, from_message_id, offset, limit, 1, false, std::move(promise)); + return; + } + bool need_update_dialog_pos = false; if (from_the_end && last_added_message_id.is_valid()) { CHECK(next_message_id.is_valid()); @@ -23279,75 +22235,48 @@ void MessagesManager::on_get_history_from_database(DialogId dialog_id, MessageId promise.set_value(Unit()); } -void MessagesManager::get_history_from_the_end(DialogId dialog_id, bool from_database, bool only_local, - Promise &&promise) { - get_history_from_the_end_impl(get_dialog(dialog_id), from_database, only_local, std::move(promise), - "get_history_from_the_end"); +void MessagesManager::load_last_dialog_message_later(DialogId dialog_id) { + if (G()->close_flag()) { + return; + } + load_last_dialog_message(get_dialog(dialog_id), "load_last_dialog_message"); } -void MessagesManager::get_history_from_the_end_impl(const Dialog *d, bool from_database, bool only_local, - Promise &&promise, const char *source) { - TRY_STATUS_PROMISE(promise, G()->close_status()); - CHECK(d != nullptr); +void MessagesManager::load_last_dialog_message(const Dialog *d, const char *source) { + get_history_impl(d, MessageId::max(), 0, -1, true, false, Promise(), source); +} - auto dialog_id = d->dialog_id; - if (!have_input_peer(dialog_id, AccessRights::Read)) { - // can't get history in dialogs without read access - return promise.set_value(Unit()); - } - if (!d->first_database_message_id.is_valid() && !d->have_full_history) { - from_database = false; - } - int32 limit = MAX_GET_HISTORY; - if (from_database && G()->use_message_database()) { - if (!promise) { - // repair last database message ID - limit = 10; - } - LOG(INFO) << "Get history from the end of " << dialog_id << " from database from " << source; - MessageDbMessagesQuery db_query; - db_query.dialog_id = dialog_id; - db_query.from_message_id = MessageId::max(); - db_query.limit = limit; - G()->td_db()->get_message_db_async()->get_messages( - db_query, PromiseCreator::lambda([dialog_id, old_last_database_message_id = d->last_database_message_id, - only_local, limit, actor_id = actor_id(this), promise = std::move(promise)]( - vector messages) mutable { - send_closure(actor_id, &MessagesManager::on_get_history_from_database, dialog_id, MessageId::max(), - old_last_database_message_id, 0, limit, true, only_local, std::move(messages), - std::move(promise)); - })); - } else { - if (only_local || dialog_id.get_type() == DialogType::SecretChat || d->last_message_id.is_valid()) { - // if last message is known, there are no reasons to get message history from server from the end - promise.set_value(Unit()); - return; - } - if (!promise && !G()->use_message_database()) { - // repair last message ID - limit = 10; - } +void MessagesManager::on_get_history_finished(const PendingGetHistoryQuery &query, Result &&result) { + G()->ignore_result_if_closing(result); - LOG(INFO) << "Get history from the end of " << dialog_id << " from server from " << source; - td_->create_handler(std::move(promise)) - ->send_get_from_the_end(dialog_id, d->last_new_message_id, limit); + auto it = get_history_queries_.find(query); + if (it == get_history_queries_.end()) { + return; } -} + auto promises = std::move(it->second); + CHECK(!promises.empty()); + get_history_queries_.erase(it); -void MessagesManager::get_history(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, - bool from_database, bool only_local, Promise &&promise) { - get_history_impl(get_dialog(dialog_id), from_message_id, offset, limit, from_database, only_local, - std::move(promise)); + if (result.is_ok()) { + set_promises(promises); + } else { + fail_promises(promises, result.move_as_error()); + } } void MessagesManager::get_history_impl(const Dialog *d, MessageId from_message_id, int32 offset, int32 limit, - bool from_database, bool only_local, Promise &&promise) { - TRY_STATUS_PROMISE(promise, G()->close_status()); + bool from_database, bool only_local, Promise &&promise, + const char *source) { CHECK(d != nullptr); - CHECK(from_message_id.is_valid()); + bool from_the_end = from_message_id == MessageId() || from_message_id == MessageId::max(); + if (!from_the_end) { + CHECK(from_message_id.is_valid()); + } else { + from_message_id = MessageId::max(); + } auto dialog_id = d->dialog_id; - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { // can't get history in dialogs without read access return promise.set_value(Unit()); } @@ -23355,9 +22284,51 @@ void MessagesManager::get_history_impl(const Dialog *d, MessageId from_message_i !d->have_full_history) { from_database = false; } - if (from_database && G()->use_message_database()) { + if (!G()->use_message_database()) { + from_database = false; + } + + if (from_the_end) { + // load only 10 messages when repairing the last message and can't save the result to the database + limit = !promise && (from_database || !G()->use_message_database()) ? max(limit, 10) : MAX_GET_HISTORY; + offset = 0; + } else if (offset >= -1) { + // get history before some server or local message + limit = clamp(limit + offset + 1, MAX_GET_HISTORY / 2, MAX_GET_HISTORY); + offset = -1; + } else { + // get history around some server or local message + int32 messages_to_load = max(MAX_GET_HISTORY, limit); + int32 max_add = max(messages_to_load - limit - 2, 0); + offset -= max_add; + limit = MAX_GET_HISTORY; + } + + PendingGetHistoryQuery query; + query.dialog_id_ = dialog_id; + query.from_message_id_ = from_message_id; + query.offset_ = offset; + query.limit_ = limit; + query.from_database_ = from_database; + query.only_local_ = only_local; + + if (from_database) { LOG(INFO) << "Get history in " << dialog_id << " from " << from_message_id << " with offset " << offset - << " and limit " << limit << " from database"; + << " and limit " << limit << " from database from " << source; + + query.old_last_message_id_ = d->last_database_message_id; + + auto &promises = get_history_queries_[query]; + promises.push_back(std::move(promise)); + if (promises.size() != 1) { + // query has already been sent, just wait for the result + return; + } + + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), query](Result &&result) { + send_closure(actor_id, &MessagesManager::on_get_history_finished, query, std::move(result)); + }); + MessageDbMessagesQuery db_query; db_query.dialog_id = dialog_id; db_query.from_message_id = from_message_id; @@ -23365,22 +22336,43 @@ void MessagesManager::get_history_impl(const Dialog *d, MessageId from_message_i db_query.limit = limit; G()->td_db()->get_message_db_async()->get_messages( db_query, - PromiseCreator::lambda([dialog_id, from_message_id, old_last_database_message_id = d->last_database_message_id, - offset, limit, only_local, actor_id = actor_id(this), - promise = std::move(promise)](vector messages) mutable { + PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, from_message_id, + old_last_database_message_id = d->last_database_message_id, offset, limit, only_local, + promise = std::move(query_promise)](vector messages) mutable { send_closure(actor_id, &MessagesManager::on_get_history_from_database, dialog_id, from_message_id, - old_last_database_message_id, offset, limit, false, only_local, std::move(messages), + old_last_database_message_id, offset, limit, only_local, std::move(messages), std::move(promise)); })); } else { - if (only_local || dialog_id.get_type() == DialogType::SecretChat) { + if (only_local || dialog_id.get_type() == DialogType::SecretChat || + (from_the_end && d->last_message_id.is_valid())) { + // if the last message is known, there are no reasons to get message history from server from the end return promise.set_value(Unit()); } - LOG(INFO) << "Get history in " << dialog_id << " from " << from_message_id << " with offset " << offset - << " and limit " << limit << " from server"; - td_->create_handler(std::move(promise)) - ->send(dialog_id, from_message_id.get_next_server_message_id(), d->last_new_message_id, offset, limit); + query.old_last_message_id_ = d->last_new_message_id; + + auto &promises = get_history_queries_[query]; + promises.push_back(std::move(promise)); + if (promises.size() != 1) { + // query has already been sent, just wait for the result + return; + } + + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), query](Result &&result) { + send_closure(actor_id, &MessagesManager::on_get_history_finished, query, std::move(result)); + }); + + if (from_the_end) { + LOG(INFO) << "Get history from the end of " << dialog_id << " from server from " << source; + td_->create_handler(std::move(query_promise)) + ->send_get_from_the_end(dialog_id, d->last_new_message_id, limit); + } else { + LOG(INFO) << "Get history in " << dialog_id << " from " << from_message_id << " with offset " << offset + << " and limit " << limit << " from server from " << source; + td_->create_handler(std::move(query_promise)) + ->send(dialog_id, from_message_id.get_next_server_message_id(), d->last_new_message_id, offset, limit); + } } } @@ -23403,27 +22395,8 @@ void MessagesManager::load_messages_impl(const Dialog *d, MessageId from_message only_local = true; } bool from_database = (left_tries > 2 || only_local) && G()->use_message_database(); - - if (from_message_id == MessageId()) { - get_history_from_the_end_impl(d, from_database, only_local, std::move(promise), "load_messages_impl"); - return; - } - if ((!d->first_database_message_id.is_valid() || from_message_id <= d->first_database_message_id) && - !d->have_full_history) { - from_database = false; - } - if (offset >= -1) { - // get history before some server or local message - limit = min(max(limit + offset + 1, MAX_GET_HISTORY / 2), MAX_GET_HISTORY); - offset = -1; - } else { - // get history around some server or local message - int32 messages_to_load = max(MAX_GET_HISTORY, limit); - int32 max_add = max(messages_to_load - limit - 2, 0); - offset -= max_add; - limit = MAX_GET_HISTORY; - } - get_history_impl(d, from_message_id, offset, limit, from_database, only_local, std::move(promise)); + get_history_impl(d, from_message_id, offset, limit, from_database, only_local, std::move(promise), + "load_messages_impl"); } vector MessagesManager::get_dialog_scheduled_messages(DialogId dialog_id, bool force, bool ignore_result, @@ -23439,12 +22412,12 @@ vector MessagesManager::get_dialog_scheduled_messages(DialogId dialog promise.set_error(Status::Error(400, "Chat not found")); return {}; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { promise.set_error(Status::Error(400, "Can't access the chat")); return {}; } - if (is_broadcast_channel(dialog_id) && - !td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).can_post_messages()) { + if (td_->dialog_manager_->is_broadcast_channel(dialog_id) && + !td_->chat_manager_->get_channel_status(dialog_id.get_channel_id()).can_post_messages()) { promise.set_error(Status::Error(400, "Not enough rights to get scheduled messages")); return {}; } @@ -23520,7 +22493,7 @@ void MessagesManager::load_dialog_scheduled_messages(DialogId dialog_id, bool fr if (queries.size() == 1) { G()->td_db()->get_message_db_async()->get_scheduled_messages( dialog_id, 1000, - PromiseCreator::lambda([dialog_id, actor_id = actor_id(this)](vector messages) { + PromiseCreator::lambda([actor_id = actor_id(this), dialog_id](vector messages) { send_closure(actor_id, &MessagesManager::on_get_scheduled_messages_from_database, dialog_id, std::move(messages)); })); @@ -23585,221 +22558,303 @@ void MessagesManager::on_get_scheduled_messages_from_database(DialogId dialog_id set_promises(promises); } -Result> MessagesManager::get_message_available_reactions( - FullMessageId full_message_id, int32 row_size) { - if (row_size < 5 || row_size > 25) { - row_size = 8; - } +bool MessagesManager::can_add_message_tag(DialogId dialog_id, const MessageReactions *reactions) const { + return dialog_id == td_->dialog_manager_->get_my_dialog_id() && + (reactions == nullptr || reactions->are_empty() || reactions->are_tags_); +} - auto dialog_id = full_message_id.get_dialog_id(); +Result> MessagesManager::get_message_available_reactions( + MessageFullId message_full_id, int32 row_size) { + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog_force(dialog_id, "get_message_available_reactions"); if (d == nullptr) { return Status::Error(400, "Chat not found"); } - const Message *m = get_message_force(d, full_message_id.get_message_id(), "get_message_available_reactions"); + const Message *m = get_message_force(d, message_full_id.get_message_id(), "get_message_available_reactions"); if (m == nullptr) { return Status::Error(400, "Message not found"); } - auto available_reactions = get_message_available_reactions(d, m, false); - bool is_premium = td_->option_manager_->get_option_boolean("is_premium"); - bool show_premium = is_premium; - - auto recent_reactions = get_recent_reactions(td_); - auto top_reactions = get_top_reactions(td_); - auto active_reactions = get_message_active_reactions(d, m); - LOG(INFO) << "Have available reactions " << available_reactions << " to be sorted by top reactions " << top_reactions - << " and recent reactions " << recent_reactions; - if (active_reactions.allow_custom_ && active_reactions.allow_all_) { - for (auto &reaction : recent_reactions) { - if (is_custom_reaction(reaction)) { - show_premium = true; - } - } - for (auto &reaction : top_reactions) { - if (is_custom_reaction(reaction)) { - show_premium = true; - } - } - } - - FlatHashSet all_available_reactions; - for (const auto &reaction : available_reactions.reactions_) { - CHECK(!reaction.empty()); - all_available_reactions.insert(reaction); - } - - vector> top_reaction_objects; - vector> recent_reaction_objects; - vector> popular_reaction_objects; - vector> last_reaction_objects; - - FlatHashSet added_custom_reactions; - auto add_reactions = [&](vector> &reaction_objects, - const vector &reactions) { - for (auto &reaction : reactions) { - if (all_available_reactions.erase(reaction) != 0) { - // add available reaction - if (is_custom_reaction(reaction)) { - added_custom_reactions.insert(reaction); - } - reaction_objects.push_back( - td_api::make_object(get_reaction_type_object(reaction), false)); - } else if (is_custom_reaction(reaction) && available_reactions.allow_custom_ && - added_custom_reactions.insert(reaction).second) { - // add implicitly available custom reaction - reaction_objects.push_back( - td_api::make_object(get_reaction_type_object(reaction), !is_premium)); - } else { - // skip the reaction - } - } - }; - if (show_premium) { - if (top_reactions.size() > 2 * static_cast(row_size)) { - top_reactions.resize(2 * static_cast(row_size)); - } - add_reactions(top_reaction_objects, top_reactions); - - if (!recent_reactions.empty()) { - add_reactions(recent_reaction_objects, recent_reactions); - } - } else { - add_reactions(top_reaction_objects, top_reactions); - } - add_reactions(last_reaction_objects, active_reactions_); - add_reactions(last_reaction_objects, available_reactions.reactions_); - - if (show_premium) { - if (recent_reactions.empty()) { - popular_reaction_objects = std::move(last_reaction_objects); - } else { - auto max_objects = 10 * static_cast(row_size); - if (recent_reaction_objects.size() + last_reaction_objects.size() > max_objects) { - if (last_reaction_objects.size() < max_objects) { - recent_reaction_objects.resize(max_objects - last_reaction_objects.size()); - } else { - recent_reaction_objects.clear(); - } - } - append(recent_reaction_objects, std::move(last_reaction_objects)); - } - } else { - append(top_reaction_objects, std::move(last_reaction_objects)); - } - - CHECK(all_available_reactions.empty()); - - return td_api::make_object( - std::move(top_reaction_objects), std::move(recent_reaction_objects), std::move(popular_reaction_objects), - available_reactions.allow_custom_); + bool is_tag = can_add_message_tag(dialog_id, m->reactions.get()); + ReactionUnavailabilityReason unavailability_reason = ReactionUnavailabilityReason::None; + auto available_reactions = get_message_available_reactions(d, m, false, &unavailability_reason); + return td_->reaction_manager_->get_sorted_available_reactions( + std::move(available_reactions), get_message_active_reactions(d, m), row_size, is_tag, unavailability_reason); } ChatReactions MessagesManager::get_message_available_reactions(const Dialog *d, const Message *m, - bool dissalow_custom_for_non_premium) { + bool disallow_custom_for_non_premium, + ReactionUnavailabilityReason *unavailability_reason) { CHECK(d != nullptr); CHECK(m != nullptr); auto active_reactions = get_message_active_reactions(d, m); - if (!m->message_id.is_valid() || !m->message_id.is_server() || active_reactions.empty()) { + if (active_reactions.empty()) { return {}; } bool can_use_reactions = true; if (d->dialog_id.get_type() == DialogType::Channel) { auto channel_id = d->dialog_id.get_channel_id(); - if (td_->contacts_manager_->is_megagroup_channel(channel_id) && - !td_->contacts_manager_->get_channel_status(channel_id).is_member() && - can_send_message(d->dialog_id).is_error()) { + if (td_->chat_manager_->is_megagroup_channel(channel_id) && + !td_->chat_manager_->get_channel_status(channel_id).is_member() && can_send_message(d->dialog_id).is_error()) { + // can't use reactions if can't send messages to the group without joining + if (unavailability_reason != nullptr) { + *unavailability_reason = ReactionUnavailabilityReason::Guest; + } + can_use_reactions = false; + } else if (td_->dialog_manager_->is_anonymous_administrator(d->dialog_id, nullptr) && + !td_->dialog_manager_->is_broadcast_channel(d->dialog_id) && + !td_->chat_manager_->get_channel_status(channel_id).is_creator() && + get_my_reaction_dialog_id(d) == d->dialog_id) { + // only creator can react as the chat + if (unavailability_reason != nullptr) { + *unavailability_reason = ReactionUnavailabilityReason::AnonymousAdministrator; + } can_use_reactions = false; } } int64 reactions_uniq_max = td_->option_manager_->get_option_integer("reactions_uniq_max", 11); + if (0 < active_reactions.reactions_limit_ && active_reactions.reactions_limit_ < reactions_uniq_max) { + reactions_uniq_max = active_reactions.reactions_limit_; + } bool can_add_new_reactions = - m->reactions == nullptr || static_cast(m->reactions->reactions_.size()) < reactions_uniq_max; + m->reactions == nullptr || m->reactions->get_non_paid_reaction_count() < reactions_uniq_max; - if (!can_use_reactions || !can_add_new_reactions) { + if (!can_use_reactions) { active_reactions = ChatReactions(); + } else if (!can_add_new_reactions) { + active_reactions.ignore_non_paid_reaction_types(); + } + + if (active_reactions.allow_all_regular_) { + if (can_add_message_tag(d->dialog_id, m->reactions.get())) { + auto default_tag_reactions = td_->reaction_manager_->get_default_tag_reactions(); + active_reactions.reaction_types_ = default_tag_reactions; + if (td_->option_manager_->get_option_boolean("is_premium")) { + for (auto &reaction_type : active_reaction_types_) { + if (!td::contains(default_tag_reactions, reaction_type)) { + active_reactions.reaction_types_.push_back(reaction_type); + } + } + } else { + disallow_custom_for_non_premium = true; + } + } else { + active_reactions.reaction_types_ = active_reaction_types_; + } + active_reactions.allow_all_regular_ = false; } - - if (active_reactions.allow_all_) { - active_reactions.reactions_ = active_reactions_; - active_reactions.allow_all_ = false; - } - if (m->reactions != nullptr) { + if (can_use_reactions && m->reactions != nullptr) { for (const auto &reaction : m->reactions->reactions_) { // an already used reaction can be added if it is an active reaction - const string &reaction_str = reaction.get_reaction(); - if (can_use_reactions && is_active_reaction(reaction_str, active_reaction_pos_) && - !td::contains(active_reactions.reactions_, reaction_str)) { - active_reactions.reactions_.push_back(reaction_str); + const auto &reaction_type = reaction.get_reaction_type(); + if (reaction_type.is_active_reaction(active_reaction_pos_) && + !td::contains(active_reactions.reaction_types_, reaction_type)) { + active_reactions.reaction_types_.push_back(reaction_type); } } } - if (dissalow_custom_for_non_premium && !td_->option_manager_->get_option_boolean("is_premium")) { - active_reactions.allow_custom_ = false; + if (disallow_custom_for_non_premium && !td_->option_manager_->get_option_boolean("is_premium")) { + active_reactions.allow_all_custom_ = false; } return active_reactions; } -void MessagesManager::add_message_reaction(FullMessageId full_message_id, string reaction, bool is_big, +DialogId MessagesManager::get_my_reaction_dialog_id(const Dialog *d) const { + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + if (td_->dialog_manager_->is_broadcast_channel(d->dialog_id)) { + return my_dialog_id; + } + auto reaction_dialog_id = + d->default_send_message_as_dialog_id.is_valid() ? d->default_send_message_as_dialog_id : my_dialog_id; + if (reaction_dialog_id == my_dialog_id && td_->dialog_manager_->is_anonymous_administrator(d->dialog_id, nullptr)) { + // react as the supergroup + return d->dialog_id; + } + return reaction_dialog_id; +} + +void MessagesManager::add_message_reaction(MessageFullId message_full_id, ReactionType reaction_type, bool is_big, bool add_to_recent, Promise &&promise) { - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog_force(dialog_id, "add_message_reaction"); if (d == nullptr) { return promise.set_error(Status::Error(400, "Chat not found")); } - Message *m = get_message_force(d, full_message_id.get_message_id(), "add_message_reaction"); + Message *m = get_message_force(d, message_full_id.get_message_id(), "add_message_reaction"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!get_message_available_reactions(d, m, true).is_allowed_reaction(reaction)) { + if (!get_message_available_reactions(d, m, true, nullptr).is_allowed_reaction_type(reaction_type)) { return promise.set_error(Status::Error(400, "The reaction isn't available for the message")); } + if (reaction_type.is_paid_reaction()) { + return promise.set_error(Status::Error(400, "Use addPaidMessageReaction instead to add the paid reaction")); + } - bool have_recent_choosers = !is_broadcast_channel(dialog_id) && !is_discussion_message(dialog_id, m); + bool have_recent_choosers = + !td_->dialog_manager_->is_broadcast_channel(dialog_id) && !is_discussion_message(dialog_id, m); if (m->reactions == nullptr) { m->reactions = make_unique(); m->reactions->can_get_added_reactions_ = have_recent_choosers && dialog_id.get_type() != DialogType::User; m->available_reactions_generation = d->available_reactions_generation; } - if (!m->reactions->add_reaction(reaction, is_big, get_my_dialog_id(), have_recent_choosers)) { + LOG(INFO) << "Have message with " << *m->reactions; + bool is_tag = can_add_message_tag(dialog_id, m->reactions.get()); + auto old_chosen_tags = get_chosen_tags(m->reactions); + if (!m->reactions->add_my_reaction(reaction_type, is_big, get_my_reaction_dialog_id(d), have_recent_choosers, + is_tag)) { return promise.set_value(Unit()); } - if (add_to_recent) { - add_recent_reaction(td_, reaction); - } - set_message_reactions(d, m, is_big, add_to_recent, std::move(promise)); + + if (is_tag) { + td_->reaction_manager_->update_saved_messages_tags(m->saved_messages_topic_id, old_chosen_tags, + get_chosen_tags(m->reactions)); + } else if (add_to_recent) { + td_->reaction_manager_->add_recent_reaction(reaction_type); + } } -void MessagesManager::remove_message_reaction(FullMessageId full_message_id, string reaction, Promise &&promise) { - auto dialog_id = full_message_id.get_dialog_id(); +void MessagesManager::remove_message_reaction(MessageFullId message_full_id, ReactionType reaction_type, + Promise &&promise) { + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog_force(dialog_id, "remove_message_reaction"); if (d == nullptr) { return promise.set_error(Status::Error(400, "Chat not found")); } - Message *m = get_message_force(d, full_message_id.get_message_id(), "remove_message_reaction"); + Message *m = get_message_force(d, message_full_id.get_message_id(), "remove_message_reaction"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (reaction.empty()) { + if (reaction_type.is_empty() || reaction_type.is_paid_reaction()) { return promise.set_error(Status::Error(400, "Invalid reaction specified")); } - bool have_recent_choosers = !is_broadcast_channel(dialog_id) && !is_discussion_message(dialog_id, m); - if (m->reactions == nullptr || !m->reactions->remove_reaction(reaction, get_my_dialog_id(), have_recent_choosers)) { + if (m->reactions == nullptr) { + return promise.set_value(Unit()); + } + + LOG(INFO) << "Have message with " << *m->reactions; + auto old_chosen_tags = get_chosen_tags(m->reactions); + if (!m->reactions->remove_my_reaction(reaction_type, get_my_reaction_dialog_id(d))) { return promise.set_value(Unit()); } set_message_reactions(d, m, false, false, std::move(promise)); + + if (!old_chosen_tags.empty()) { + td_->reaction_manager_->update_saved_messages_tags(m->saved_messages_topic_id, old_chosen_tags, + get_chosen_tags(m->reactions)); + } +} + +void MessagesManager::add_paid_message_reaction(MessageFullId message_full_id, int64 star_count, + bool use_default_is_anonymous, bool is_anonymous, + Promise &&promise) { + auto dialog_id = message_full_id.get_dialog_id(); + Dialog *d = get_dialog_force(dialog_id, "add_paid_message_reaction"); + if (d == nullptr) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + Message *m = get_message_force(d, message_full_id.get_message_id(), "add_paid_message_reaction"); + if (m == nullptr) { + return promise.set_error(Status::Error(400, "Message not found")); + } + if (!get_message_available_reactions(d, m, true, nullptr).is_allowed_reaction_type(ReactionType::paid()) || + !td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + return promise.set_error(Status::Error(400, "The reaction isn't available for the message")); + } + if (star_count <= 0 || star_count > td_->option_manager_->get_option_integer("paid_reaction_star_count_max")) { + return promise.set_error(Status::Error(400, "Invalid number of Telegram Stars specified")); + } + if (!td_->star_manager_->has_owned_star_count(star_count)) { + return promise.set_error(Status::Error(400, "Have not enough Telegram Stars")); + } + + if (m->reactions == nullptr) { + m->reactions = make_unique(); + m->available_reactions_generation = d->available_reactions_generation; + } + + LOG(INFO) << "Have message with " << *m->reactions; + m->reactions->add_my_paid_reaction(td_, narrow_cast(star_count), use_default_is_anonymous, is_anonymous); + m->reactions->sort_reactions(active_reaction_pos_); + LOG(INFO) << "Update message reactions to " << *m->reactions; + + send_update_message_interaction_info(d->dialog_id, m); + on_message_changed(d, m, true, "add_paid_message_reaction"); + + promise.set_value(Unit()); +} + +void MessagesManager::drop_message_pending_paid_reactions(const Dialog *d, Message *m) { + m->reactions->drop_pending_paid_reactions(td_); + send_update_message_interaction_info(d->dialog_id, m); + on_message_changed(d, m, true, "drop_message_pending_paid_reactions"); +} + +void MessagesManager::commit_paid_message_reactions(MessageFullId message_full_id, Promise &&promise) { + TRY_RESULT_PROMISE( + promise, d, + check_dialog_access(message_full_id.get_dialog_id(), false, AccessRights::Read, "commit_paid_message_reactions")); + auto *m = get_message_force(d, message_full_id.get_message_id(), "commit_paid_message_reactions"); + if (m == nullptr || m->reactions == nullptr || !m->reactions->has_pending_paid_reactions()) { + return promise.set_value(Unit()); + } + if (!get_message_available_reactions(d, m, true, nullptr).is_allowed_reaction_type(ReactionType::paid())) { + drop_message_pending_paid_reactions(d, m); + return promise.set_value(Unit()); + } + + pending_reactions_[message_full_id].query_count++; + + int64 random_id = (static_cast(G()->unix_time()) << 32) | static_cast(Random::secure_uint32()); + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), message_full_id, promise = std::move(promise)](Result &&result) mutable { + send_closure(actor_id, &MessagesManager::on_set_message_reactions, message_full_id, std::move(result), + std::move(promise)); + }); + m->reactions->send_paid_message_reaction(td_, message_full_id, random_id, std::move(query_promise)); +} + +void MessagesManager::remove_paid_message_reactions(MessageFullId message_full_id, Promise &&promise) { + TRY_RESULT_PROMISE( + promise, d, + check_dialog_access(message_full_id.get_dialog_id(), false, AccessRights::Read, "remove_paid_message_reactions")); + auto *m = get_message_force(d, message_full_id.get_message_id(), "remove_paid_message_reactions"); + if (m != nullptr && m->reactions != nullptr && m->reactions->has_pending_paid_reactions()) { + drop_message_pending_paid_reactions(d, m); + } + promise.set_value(Unit()); +} + +void MessagesManager::toggle_paid_message_reaction_is_anonymous(MessageFullId message_full_id, bool is_anonymous, + Promise &&promise) { + auto dialog_id = message_full_id.get_dialog_id(); + Dialog *d = get_dialog_force(dialog_id, "toggle_paid_message_reaction_is_anonymous"); + if (d == nullptr) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + Message *m = get_message_force(d, message_full_id.get_message_id(), "toggle_paid_message_reaction_is_anonymous"); + if (m == nullptr) { + return promise.set_error(Status::Error(400, "Message not found")); + } + if (m->reactions == nullptr) { + return promise.set_error(Status::Error(400, "Message has no paid reactions")); + } + if (m->reactions->toggle_paid_message_reaction_is_anonymous(td_, message_full_id, is_anonymous, std::move(promise))) { + send_update_message_interaction_info(d->dialog_id, m); + on_message_changed(d, m, true, "toggle_paid_message_reaction_is_anonymous"); + } } void MessagesManager::set_message_reactions(Dialog *d, Message *m, bool is_big, bool add_to_recent, @@ -23809,40 +22864,40 @@ void MessagesManager::set_message_reactions(Dialog *d, Message *m, bool is_big, LOG(INFO) << "Update message reactions to " << *m->reactions; - FullMessageId full_message_id{d->dialog_id, m->message_id}; - pending_reactions_[full_message_id].query_count++; + MessageFullId message_full_id{d->dialog_id, m->message_id}; + pending_reactions_[message_full_id].query_count++; send_update_message_interaction_info(d->dialog_id, m); on_message_changed(d, m, true, "set_message_reactions"); // TODO cancel previous queries, log event auto query_promise = PromiseCreator::lambda( - [actor_id = actor_id(this), full_message_id, promise = std::move(promise)](Result &&result) mutable { - send_closure(actor_id, &MessagesManager::on_set_message_reactions, full_message_id, std::move(result), + [actor_id = actor_id(this), message_full_id, promise = std::move(promise)](Result &&result) mutable { + send_closure(actor_id, &MessagesManager::on_set_message_reactions, message_full_id, std::move(result), std::move(promise)); }); - send_message_reaction(td_, full_message_id, m->reactions->get_chosen_reactions(), is_big, add_to_recent, + send_message_reaction(td_, message_full_id, m->reactions->get_chosen_reaction_types(), is_big, add_to_recent, std::move(query_promise)); } -void MessagesManager::on_set_message_reactions(FullMessageId full_message_id, Result result, +void MessagesManager::on_set_message_reactions(MessageFullId message_full_id, Result result, Promise promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); bool need_reload = result.is_error(); - auto it = pending_reactions_.find(full_message_id); + auto it = pending_reactions_.find(message_full_id); CHECK(it != pending_reactions_.end()); if (--it->second.query_count == 0) { // need_reload |= it->second.was_updated; pending_reactions_.erase(it); } - if (!have_message_force(full_message_id, "on_set_message_reactions")) { + if (!have_message_force(message_full_id, "on_set_message_reactions")) { return promise.set_value(Unit()); } if (need_reload) { - queue_message_reactions_reload(full_message_id); + queue_message_reactions_reload(message_full_id); } promise.set_result(std::move(result)); @@ -23851,88 +22906,23 @@ void MessagesManager::on_set_message_reactions(FullMessageId full_message_id, Re void MessagesManager::on_read_message_reactions(DialogId dialog_id, vector &&message_ids, Result &&result) { for (auto message_id : message_ids) { - FullMessageId full_message_id{dialog_id, message_id}; - auto it = pending_read_reactions_.find(full_message_id); + MessageFullId message_full_id{dialog_id, message_id}; + auto it = pending_read_reactions_.find(message_full_id); CHECK(it != pending_read_reactions_.end()); if (--it->second == 0) { pending_read_reactions_.erase(it); } - if (!have_message_force(full_message_id, "on_read_message_reactions")) { + if (!have_message_force(message_full_id, "on_read_message_reactions")) { continue; } if (result.is_error()) { - queue_message_reactions_reload(full_message_id); + queue_message_reactions_reload(message_full_id); } } } -void MessagesManager::get_message_public_forwards(FullMessageId full_message_id, string offset, int32 limit, - Promise> &&promise) { - auto dc_id_promise = PromiseCreator::lambda([actor_id = actor_id(this), full_message_id, offset = std::move(offset), - limit, promise = std::move(promise)](Result r_dc_id) mutable { - if (r_dc_id.is_error()) { - return promise.set_error(r_dc_id.move_as_error()); - } - send_closure(actor_id, &MessagesManager::send_get_message_public_forwards_query, r_dc_id.move_as_ok(), - full_message_id, std::move(offset), limit, std::move(promise)); - }); - td_->contacts_manager_->get_channel_statistics_dc_id(full_message_id.get_dialog_id(), false, - std::move(dc_id_promise)); -} - -void MessagesManager::send_get_message_public_forwards_query( - DcId dc_id, FullMessageId full_message_id, string offset, int32 limit, - Promise> &&promise) { - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "send_get_message_public_forwards_query"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - const Message *m = get_message_force(d, full_message_id.get_message_id(), "send_get_message_public_forwards_query"); - if (m == nullptr) { - return promise.set_error(Status::Error(400, "Message not found")); - } - - if (m->view_count == 0 || m->forward_info != nullptr || m->had_forward_info || m->message_id.is_scheduled() || - !m->message_id.is_server()) { - return promise.set_error(Status::Error(400, "Message forwards are inaccessible")); - } - - if (limit <= 0) { - return promise.set_error(Status::Error(400, "Parameter limit must be positive")); - } - if (limit > MAX_SEARCH_MESSAGES) { - limit = MAX_SEARCH_MESSAGES; - } - - int32 offset_date = std::numeric_limits::max(); - DialogId offset_dialog_id; - ServerMessageId offset_server_message_id; - - if (!offset.empty()) { - auto parts = full_split(offset, ','); - if (parts.size() != 3) { - return promise.set_error(Status::Error(400, "Invalid offset specified")); - } - auto r_offset_date = to_integer_safe(parts[0]); - auto r_offset_dialog_id = to_integer_safe(parts[1]); - auto r_offset_server_message_id = to_integer_safe(parts[2]); - if (r_offset_date.is_error() || r_offset_dialog_id.is_error() || r_offset_server_message_id.is_error()) { - return promise.set_error(Status::Error(400, "Invalid offset specified")); - } - - offset_date = r_offset_date.ok(); - offset_dialog_id = DialogId(r_offset_dialog_id.ok()); - offset_server_message_id = ServerMessageId(r_offset_server_message_id.ok()); - } - - td_->create_handler(std::move(promise)) - ->send(dc_id, full_message_id, offset_date, offset_dialog_id, offset_server_message_id, limit); -} - Result MessagesManager::get_message_schedule_date( td_api::object_ptr &&scheduling_state) { if (scheduling_state == nullptr) { @@ -23971,11 +22961,16 @@ tl_object_ptr MessagesManager::get_message_sending_ } if (m->is_failed_to_send) { auto can_retry = can_resend_message(m); + auto error_code = m->send_error_code > 0 ? m->send_error_code : 400; auto need_another_sender = - can_retry && m->send_error_code == 400 && m->send_error_message == CSlice("SEND_AS_PEER_INVALID"); - return td_api::make_object(m->send_error_code, m->send_error_message, can_retry, - need_another_sender, - max(m->try_resend_at - Time::now(), 0.0)); + can_retry && error_code == 400 && m->send_error_message == CSlice("SEND_AS_PEER_INVALID"); + auto need_another_reply_quote = + can_retry && error_code == 400 && m->send_error_message == CSlice("QUOTE_TEXT_INVALID"); + auto need_drop_reply = + can_retry && error_code == 400 && m->send_error_message == CSlice("REPLY_MESSAGE_ID_INVALID"); + return td_api::make_object( + td_api::make_object(error_code, m->send_error_message), can_retry, need_another_sender, + need_another_reply_quote, need_drop_reply, max(m->try_resend_at - Time::now(), 0.0)); } return nullptr; } @@ -23987,10 +22982,20 @@ tl_object_ptr MessagesManager::get_message_sched return td_api::make_object(send_date); } +td_api::object_ptr MessagesManager::get_message_message_content_object(DialogId dialog_id, + const Message *m) const { + auto live_location_date = m->is_failed_to_send ? 0 : m->date; + return get_message_content_object( + m->content.get(), td_, dialog_id, m->message_id.is_any_server() && dialog_id.get_type() != DialogType::SecretChat, + m->is_outgoing, live_location_date, m->is_content_secret, need_skip_bot_commands(dialog_id, m), + get_message_max_media_timestamp(m), m->invert_media, m->disable_web_page_preview); +} + td_api::object_ptr MessagesManager::get_dialog_event_log_message_object( DialogId dialog_id, tl_object_ptr &&message, DialogId &sender_dialog_id) { - auto dialog_message = create_message(parse_telegram_api_message(std::move(message), false, "dialog_event_log"), - dialog_id.get_type() == DialogType::Channel); + auto dialog_message = create_message( + td_, parse_telegram_api_message(td_, std::move(message), false, false, "get_dialog_event_log_message_object"), + dialog_id.get_type() == DialogType::Channel, false, "get_dialog_event_log_message_object"); const Message *m = dialog_message.second.get(); if (m == nullptr || dialog_message.first != dialog_id) { LOG(ERROR) << "Failed to create event log message in " << dialog_id; @@ -24000,148 +23005,210 @@ td_api::object_ptr MessagesManager::get_dialog_event_log_messag auto sender = get_message_sender_object_const(td_, m->sender_user_id, m->sender_dialog_id, "get_dialog_event_log_message_object"); - auto forward_info = get_message_forward_info_object(m->forward_info); + auto forward_info = + m->forward_info == nullptr ? nullptr : m->forward_info->get_message_forward_info_object(td_, false); + auto import_info = m->forward_info == nullptr ? nullptr : m->forward_info->get_message_import_info_object(); auto interaction_info = get_message_interaction_info_object(dialog_id, m); auto can_be_saved = can_save_message(dialog_id, m); - auto via_bot_user_id = td_->contacts_manager_->get_user_id_object(m->via_bot_user_id, "via_bot_user_id"); + auto via_bot_user_id = + td_->user_manager_->get_user_id_object(m->via_bot_user_id, "get_dialog_event_log_message_object via_bot_user_id"); auto edit_date = m->hide_edit_date ? 0 : m->edit_date; - auto reply_markup = get_reply_markup_object(td_->contacts_manager_.get(), m->reply_markup); - auto content = get_message_content_object(m->content.get(), td_, dialog_id, 0, false, true, - get_message_own_max_media_timestamp(m)); + auto reply_markup = get_reply_markup_object(td_->user_manager_.get(), m->reply_markup); + auto content = + get_message_content_object(m->content.get(), td_, dialog_id, true, m->is_outgoing, 0, false, true, + get_message_own_max_media_timestamp(m), m->invert_media, m->disable_web_page_preview); return td_api::make_object( m->message_id.get(), std::move(sender), get_chat_id_object(dialog_id, "get_dialog_event_log_message_object"), - nullptr, nullptr, m->is_outgoing, m->is_pinned, false, false, can_be_saved, false, false, false, false, false, - false, false, false, true, m->is_channel_post, m->is_topic_message, false, m->date, edit_date, - std::move(forward_info), std::move(interaction_info), Auto(), 0, 0, 0, 0, 0.0, 0.0, via_bot_user_id, - m->author_signature, 0, get_restriction_reason_description(m->restriction_reasons), std::move(content), - std::move(reply_markup)); + nullptr, nullptr, m->is_outgoing, m->is_pinned, m->is_from_offline, can_be_saved, true, m->is_channel_post, + m->is_topic_message, false, m->date, edit_date, std::move(forward_info), std::move(import_info), + std::move(interaction_info), Auto(), nullptr, nullptr, 0, 0, nullptr, 0.0, 0.0, via_bot_user_id, 0, + m->sender_boost_count, m->author_signature, 0, 0, + get_restriction_reason_has_sensitive_content(m->restriction_reasons), + get_restriction_reason_description(m->restriction_reasons), std::move(content), std::move(reply_markup)); } -tl_object_ptr MessagesManager::get_message_object(FullMessageId full_message_id, const char *source) { - return get_message_object(full_message_id.get_dialog_id(), get_message_force(full_message_id, source), source); +td_api::object_ptr MessagesManager::get_business_message_object( + telegram_api::object_ptr &&message, + telegram_api::object_ptr &&reply_to_message) { + auto message_object = get_business_message_message_object(std::move(message)); + if (message_object == nullptr) { + LOG(ERROR) << "Failed to create a business message"; + return nullptr; + } + return td_api::make_object(std::move(message_object), + get_business_message_message_object(std::move(reply_to_message))); } -tl_object_ptr MessagesManager::get_message_object(DialogId dialog_id, const Message *m, - const char *source) const { +td_api::object_ptr MessagesManager::get_business_message_message_object( + telegram_api::object_ptr &&message) { + CHECK(td_->auth_manager_->is_bot()); + if (message == nullptr) { + return nullptr; + } + auto dialog_message = create_message( + td_, parse_telegram_api_message(td_, std::move(message), false, true, "get_business_message_message_object"), + false, true, "get_business_message_message_object"); + const Message *m = dialog_message.second.get(); + if (m == nullptr) { + return nullptr; + } + + auto dialog_id = dialog_message.first; + if (dialog_id.get_type() != DialogType::User) { + LOG(ERROR) << "Receive a business message in " << dialog_id; + return nullptr; + } + force_create_dialog(dialog_id, "get_business_message_message_object chat", true); + + auto sender = get_message_sender_object_const(td_, m->sender_user_id, m->sender_dialog_id, + "get_business_message_message_object"); + auto forward_info = + m->forward_info == nullptr ? nullptr : m->forward_info->get_message_forward_info_object(td_, false); + auto import_info = m->forward_info == nullptr ? nullptr : m->forward_info->get_message_import_info_object(); + auto can_be_saved = !m->noforwards && !m->is_content_secret; + auto via_bot_user_id = + td_->user_manager_->get_user_id_object(m->via_bot_user_id, "get_business_message_message_object via_bot_user_id"); + auto via_business_bot_user_id = td_->user_manager_->get_user_id_object( + m->via_business_bot_user_id, "get_business_message_message_object via_business_bot_user_id"); + auto reply_to = [&]() -> td_api::object_ptr { + if (!m->replied_message_info.is_empty()) { + return m->replied_message_info.get_message_reply_to_message_object(td_, dialog_id, true); + } + if (m->reply_to_story_full_id.is_valid()) { + return td_api::make_object( + get_chat_id_object(m->reply_to_story_full_id.get_dialog_id(), + "get_business_message_message_object messageReplyToStory"), + m->reply_to_story_full_id.get_story_id().get()); + } + return nullptr; + }(); + auto reply_markup = get_reply_markup_object(td_->user_manager_.get(), m->reply_markup); + auto content = get_message_message_content_object(dialog_id, m); + auto self_destruct_type = m->ttl.get_message_self_destruct_type_object(); + + return td_api::make_object( + m->message_id.get(), std::move(sender), get_chat_id_object(dialog_id, "get_business_message_message_object"), + nullptr, nullptr, m->is_outgoing, false, m->is_from_offline, can_be_saved, false, false, false, false, m->date, + m->edit_date, std::move(forward_info), std::move(import_info), nullptr, Auto(), nullptr, std::move(reply_to), 0, + 0, std::move(self_destruct_type), 0.0, 0.0, via_bot_user_id, via_business_bot_user_id, 0, string(), + m->media_album_id, m->effect_id.get(), get_restriction_reason_has_sensitive_content(m->restriction_reasons), + get_restriction_reason_description(m->restriction_reasons), std::move(content), std::move(reply_markup)); +} + +td_api::object_ptr MessagesManager::get_message_object(Dialog *d, MessageId message_id, + const char *source) { + return get_message_object(d->dialog_id, get_message_force(d, message_id, source), source); +} + +td_api::object_ptr MessagesManager::get_message_object(const Dialog *d, MessageId message_id, + const char *source) const { + return get_message_object(d->dialog_id, get_message(d, message_id), source); +} + +td_api::object_ptr MessagesManager::get_message_object(MessageFullId message_full_id, + const char *source) { + return get_message_object(message_full_id.get_dialog_id(), get_message_force(message_full_id, source), source); +} + +td_api::object_ptr MessagesManager::get_message_object(DialogId dialog_id, const Message *m, + const char *source) const { if (m == nullptr) { return nullptr; } LOG_CHECK(have_dialog(dialog_id)) << source; + auto is_bot = td_->auth_manager_->is_bot(); auto sending_state = get_message_sending_state_object(m); - if (sending_state == nullptr || !td_->auth_manager_->is_bot()) { + if (sending_state == nullptr || !is_bot) { m->is_update_sent = true; } - bool can_delete = can_delete_message(dialog_id, m); bool is_scheduled = m->message_id.is_scheduled(); - DialogId my_dialog_id = get_my_dialog_id(); - bool can_delete_for_self = false; - bool can_delete_for_all_users = can_delete && can_revoke_message(dialog_id, m); - if (can_delete) { - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::Chat: - // TODO allow to delete yet unsent message just for self - can_delete_for_self = !m->message_id.is_yet_unsent() || dialog_id == my_dialog_id; - break; - case DialogType::Channel: - case DialogType::SecretChat: - can_delete_for_self = !can_delete_for_all_users; - break; - case DialogType::None: - default: - UNREACHABLE(); - } - } - if (is_scheduled) { - can_delete_for_self = (dialog_id == my_dialog_id); - can_delete_for_all_users = !can_delete_for_self; - } - + bool is_from_saved_messages = (dialog_id == td_->dialog_manager_->get_my_dialog_id()); bool is_outgoing = m->is_outgoing; - if (dialog_id == my_dialog_id) { + if (is_from_saved_messages) { // in Saved Messages all non-forwarded messages must be outgoing // a forwarded message is outgoing, only if it doesn't have from_dialog_id and its sender isn't hidden // i.e. a message is incoming only if it's a forwarded message with known from_dialog_id or with a hidden sender - auto forward_info = m->forward_info.get(); - is_outgoing = is_scheduled || forward_info == nullptr || - (!forward_info->from_dialog_id.is_valid() && !is_forward_info_sender_hidden(forward_info)); + is_outgoing = + is_scheduled || m->forward_info == nullptr || + (!m->forward_info->get_last_dialog_id().is_valid() && !m->forward_info->get_origin().is_sender_hidden()); } - double ttl_expires_in = m->ttl_expires_at != 0 ? clamp(m->ttl_expires_at - Time::now(), 1e-3, m->ttl - 1e-3) : m->ttl; + double ttl_expires_in = + m->ttl_expires_at != 0 ? clamp(m->ttl_expires_at - Time::now(), 1e-3, m->ttl.get_input_ttl() - 1e-3) : 0.0; double auto_delete_in = m->ttl_period == 0 ? 0.0 : clamp(m->date + m->ttl_period - G()->server_time(), 1e-3, m->ttl_period - 1e-3); auto sender = get_message_sender_object_const(td_, m->sender_user_id, m->sender_dialog_id, source); auto scheduling_state = is_scheduled ? get_message_scheduling_state_object(m->date) : nullptr; - auto forward_info = get_message_forward_info_object(m->forward_info); - auto interaction_info = get_message_interaction_info_object(dialog_id, m); + auto forward_info = m->forward_info == nullptr + ? nullptr + : m->forward_info->get_message_forward_info_object(td_, is_from_saved_messages); + auto import_info = m->forward_info == nullptr ? nullptr : m->forward_info->get_message_import_info_object(); + auto interaction_info = is_bot ? nullptr : get_message_interaction_info_object(dialog_id, m); auto unread_reactions = get_unread_reactions_object(dialog_id, m); + auto fact_check = get_message_fact_check_object(m); auto can_be_saved = can_save_message(dialog_id, m); - auto can_be_edited = can_edit_message(dialog_id, m, false, td_->auth_manager_->is_bot()); - auto can_be_forwarded = can_be_saved && can_forward_message(dialog_id, m); - auto can_get_added_reactions = m->reactions != nullptr && m->reactions->can_get_added_reactions_; - auto can_get_statistics = can_get_message_statistics(dialog_id, m); - auto can_get_message_thread = get_top_thread_full_message_id(dialog_id, m, false).is_ok(); - auto can_get_viewers = can_get_message_viewers(dialog_id, m).is_ok(); - auto can_get_media_timestamp_links = can_get_media_timestamp_link(dialog_id, m).is_ok(); - auto can_report_reactions = can_report_message_reactions(dialog_id, m); - auto via_bot_user_id = td_->contacts_manager_->get_user_id_object(m->via_bot_user_id, "via_bot_user_id"); - auto reply_to_message_id = m->reply_to_message_id.get(); - auto reply_in_dialog_id = - reply_to_message_id == 0 ? DialogId() : (m->reply_in_dialog_id.is_valid() ? m->reply_in_dialog_id : dialog_id); + auto via_bot_user_id = + td_->user_manager_->get_user_id_object(m->via_bot_user_id, "get_message_object via_bot_user_id"); + auto via_business_bot_user_id = td_->user_manager_->get_user_id_object(m->via_business_bot_user_id, + "get_message_object via_business_bot_user_id"); + auto reply_to = [&]() -> td_api::object_ptr { + if (!m->replied_message_info.is_empty()) { + if (!is_bot && m->is_topic_message && + m->replied_message_info.get_same_chat_reply_to_message_id(false) == m->top_thread_message_id) { + return nullptr; + } + return m->replied_message_info.get_message_reply_to_message_object(td_, dialog_id, m->message_id.is_any_server()); + } + if (m->reply_to_story_full_id.is_valid()) { + return td_api::make_object( + get_chat_id_object(m->reply_to_story_full_id.get_dialog_id(), "get_message_object messageReplyToStory"), + m->reply_to_story_full_id.get_story_id().get()); + } + return nullptr; + }(); auto top_thread_message_id = m->top_thread_message_id.get(); auto date = is_scheduled ? 0 : m->date; auto edit_date = m->hide_edit_date ? 0 : m->edit_date; - auto is_pinned = is_scheduled ? false : m->is_pinned; - auto has_timestamped_media = reply_to_message_id == 0 || m->max_own_media_timestamp >= 0; - auto reply_markup = get_reply_markup_object(td_->contacts_manager_.get(), m->reply_markup); - auto live_location_date = m->is_failed_to_send ? 0 : m->date; - auto skip_bot_commands = need_skip_bot_commands(dialog_id, m); - auto max_media_timestamp = get_message_max_media_timestamp(m); - auto content = get_message_content_object(m->content.get(), td_, dialog_id, live_location_date, m->is_content_secret, - skip_bot_commands, max_media_timestamp); - - if (m->is_topic_message && reply_in_dialog_id == dialog_id && reply_to_message_id == top_thread_message_id && - !td_->auth_manager_->is_bot()) { - reply_in_dialog_id = DialogId(); - reply_to_message_id = 0; - } + auto has_timestamped_media = reply_to == nullptr || m->max_own_media_timestamp >= 0; + auto reply_markup = get_reply_markup_object(td_->user_manager_.get(), m->reply_markup); + auto content = get_message_message_content_object(dialog_id, m); + auto self_destruct_type = m->ttl.get_message_self_destruct_type_object(); return td_api::make_object( m->message_id.get(), std::move(sender), get_chat_id_object(dialog_id, "get_message_object"), - std::move(sending_state), std::move(scheduling_state), is_outgoing, is_pinned, can_be_edited, can_be_forwarded, - can_be_saved, can_delete_for_self, can_delete_for_all_users, can_get_added_reactions, can_get_statistics, - can_get_message_thread, can_get_viewers, can_get_media_timestamp_links, can_report_reactions, - has_timestamped_media, m->is_channel_post, m->is_topic_message, m->contains_unread_mention, date, edit_date, - std::move(forward_info), std::move(interaction_info), std::move(unread_reactions), - get_chat_id_object(reply_in_dialog_id, "get_message_object reply"), reply_to_message_id, top_thread_message_id, - m->ttl, ttl_expires_in, auto_delete_in, via_bot_user_id, m->author_signature, m->media_album_id, + std::move(sending_state), std::move(scheduling_state), is_outgoing, m->is_pinned, m->is_from_offline, + can_be_saved, has_timestamped_media, m->is_channel_post, m->is_topic_message, m->contains_unread_mention, date, + edit_date, std::move(forward_info), std::move(import_info), std::move(interaction_info), + std::move(unread_reactions), std::move(fact_check), std::move(reply_to), top_thread_message_id, + td_->saved_messages_manager_->get_saved_messages_topic_id_object(m->saved_messages_topic_id), + std::move(self_destruct_type), ttl_expires_in, auto_delete_in, via_bot_user_id, via_business_bot_user_id, + m->sender_boost_count, m->author_signature, m->media_album_id, m->effect_id.get(), + get_restriction_reason_has_sensitive_content(m->restriction_reasons), get_restriction_reason_description(m->restriction_reasons), std::move(content), std::move(reply_markup)); } -tl_object_ptr MessagesManager::get_messages_object(int32 total_count, DialogId dialog_id, - const vector &message_ids, - bool skip_not_found, const char *source) { +td_api::object_ptr MessagesManager::get_messages_object(int32 total_count, DialogId dialog_id, + const vector &message_ids, + bool skip_not_found, const char *source) { Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - auto message_objects = transform(message_ids, [this, dialog_id, d, source](MessageId message_id) { - return get_message_object(dialog_id, get_message_force(d, message_id, source), source); - }); + auto message_objects = transform( + message_ids, [this, d, source](MessageId message_id) { return get_message_object(d, message_id, source); }); return get_messages_object(total_count, std::move(message_objects), skip_not_found); } -tl_object_ptr MessagesManager::get_messages_object(int32 total_count, - const vector &full_message_ids, - bool skip_not_found, const char *source) { - auto message_objects = transform(full_message_ids, [this, source](FullMessageId full_message_id) { - return get_message_object(full_message_id, source); +td_api::object_ptr MessagesManager::get_messages_object(int32 total_count, + const vector &message_full_ids, + bool skip_not_found, const char *source) { + auto message_objects = transform(message_full_ids, [this, source](MessageFullId message_full_id) { + return get_message_object(message_full_id, source); }); return get_messages_object(total_count, std::move(message_objects), skip_not_found); } -tl_object_ptr MessagesManager::get_messages_object(int32 total_count, - vector> &&messages, - bool skip_not_found) { +td_api::object_ptr MessagesManager::get_messages_object( + int32 total_count, vector> &&messages, bool skip_not_found) { auto message_count = narrow_cast(messages.size()); if (total_count < message_count) { if (total_count != -1) { @@ -24155,32 +23222,6 @@ tl_object_ptr MessagesManager::get_messages_object(int32 total return td_api::make_object(total_count, std::move(messages)); } -bool MessagesManager::is_anonymous_administrator(DialogId dialog_id, string *author_signature) const { - CHECK(dialog_id.is_valid()); - - if (is_broadcast_channel(dialog_id)) { - return true; - } - - if (td_->auth_manager_->is_bot()) { - return false; - } - - if (dialog_id.get_type() != DialogType::Channel) { - return false; - } - - auto status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()); - if (!status.is_anonymous()) { - return false; - } - - if (author_signature != nullptr) { - *author_signature = status.get_rank(); - } - return true; -} - bool MessagesManager::get_dialog_silent_send_message(DialogId dialog_id) const { auto *d = get_dialog(dialog_id); CHECK(d != nullptr); @@ -24198,9 +23239,10 @@ DialogId MessagesManager::get_dialog_default_send_message_as_dialog_id(DialogId return d->default_send_message_as_dialog_id; } -MessageId MessagesManager::get_reply_to_message_id(DialogId dialog_id, MessageId top_thread_message_id, - MessageId message_id, bool for_draft) { - return get_reply_to_message_id(get_dialog(dialog_id), top_thread_message_id, message_id, for_draft); +MessageInputReplyTo MessagesManager::create_message_input_reply_to( + DialogId dialog_id, MessageId top_thread_message_id, td_api::object_ptr &&reply_to, + bool for_draft) { + return create_message_input_reply_to(get_dialog(dialog_id), top_thread_message_id, std::move(reply_to), for_draft); } int64 MessagesManager::generate_new_random_id(const Dialog *d) { @@ -24213,9 +23255,10 @@ int64 MessagesManager::generate_new_random_id(const Dialog *d) { } unique_ptr MessagesManager::create_message_to_send( - Dialog *d, MessageId top_thread_message_id, MessageId reply_to_message_id, const MessageSendOptions &options, - unique_ptr &&content, bool suppress_reply_info, unique_ptr forward_info, - bool is_copy, DialogId send_as_dialog_id) const { + Dialog *d, MessageId top_thread_message_id, MessageInputReplyTo &&input_reply_to, const MessageSendOptions &options, + unique_ptr &&content, bool invert_media, bool suppress_reply_info, + unique_ptr forward_info, DialogId real_forward_from_dialog_id, bool is_copy, + DialogId send_as_dialog_id) const { CHECK(d != nullptr); CHECK(content != nullptr); @@ -24223,24 +23266,52 @@ unique_ptr MessagesManager::create_message_to_send( DialogId dialog_id = d->dialog_id; auto dialog_type = dialog_id.get_type(); - auto my_id = td_->contacts_manager_->get_my_id(); + auto my_id = td_->user_manager_->get_my_id(); + + int64 reply_to_random_id = 0; + bool is_topic_message = false; + auto initial_top_thread_message_id = top_thread_message_id; + auto same_chat_reply_to_message_id = input_reply_to.get_same_chat_reply_to_message_id(); + if (same_chat_reply_to_message_id.is_valid() || same_chat_reply_to_message_id.is_valid_scheduled()) { + // the message was forcely preloaded in create_message_input_reply_to + // it can be missing, only if it is unknown message from a push notification, or an unknown top thread message + const Message *reply_m = get_message(d, same_chat_reply_to_message_id); + if (reply_m != nullptr && !same_chat_reply_to_message_id.is_scheduled()) { + if (reply_m->top_thread_message_id.is_valid()) { + top_thread_message_id = reply_m->top_thread_message_id; + } + is_topic_message = reply_m->is_topic_message; + } + if (dialog_type == DialogType::SecretChat || same_chat_reply_to_message_id.is_yet_unsent()) { + if (reply_m != nullptr) { + reply_to_random_id = reply_m->random_id; + } else { + CHECK(dialog_type == DialogType::SecretChat); + CHECK(top_thread_message_id == MessageId()); + input_reply_to = MessageInputReplyTo(); + } + } + } + if (top_thread_message_id.is_valid()) { + const Message *top_m = get_message(d, top_thread_message_id); + if (top_m != nullptr) { + is_topic_message = top_m->is_topic_message; + } + } auto message = make_unique(); auto *m = message.get(); - bool is_channel_post = is_broadcast_channel(dialog_id); - if (is_channel_post) { - // sender of the post can be hidden - if (!is_scheduled && td_->contacts_manager_->get_channel_sign_messages(dialog_id.get_channel_id())) { - m->author_signature = td_->contacts_manager_->get_user_title(my_id); - } - m->sender_dialog_id = dialog_id; - } else { + bool is_channel_post = td_->dialog_manager_->is_broadcast_channel(dialog_id); + if (!is_channel_post || + (!is_scheduled && td_->chat_manager_->get_channel_sign_messages(dialog_id.get_channel_id()))) { if (send_as_dialog_id.is_valid()) { + // for resend_messages if (send_as_dialog_id.get_type() == DialogType::User) { m->sender_user_id = send_as_dialog_id.get_user_id(); } else { m->sender_dialog_id = send_as_dialog_id; } + m->has_explicit_sender = true; } else if (d->default_send_message_as_dialog_id.is_valid()) { if (d->default_send_message_as_dialog_id.get_type() == DialogType::User) { m->sender_user_id = my_id; @@ -24249,31 +23320,39 @@ unique_ptr MessagesManager::create_message_to_send( } m->has_explicit_sender = true; } else { - if (is_anonymous_administrator(dialog_id, &m->author_signature)) { + if (!is_channel_post && td_->dialog_manager_->is_anonymous_administrator(dialog_id, &m->author_signature)) { m->sender_dialog_id = dialog_id; } else { m->sender_user_id = my_id; } } + } else { + m->sender_dialog_id = dialog_id; } - m->send_date = G()->unix_time(); - m->date = is_scheduled ? options.schedule_date : m->send_date; - m->reply_to_message_id = reply_to_message_id; - m->top_thread_message_id = top_thread_message_id; - if (reply_to_message_id.is_valid()) { - const Message *reply_m = get_message(d, reply_to_message_id); - if (reply_m != nullptr && reply_m->top_thread_message_id.is_valid()) { - m->top_thread_message_id = reply_m->top_thread_message_id; + if (is_channel_post && !is_scheduled && td_->chat_manager_->get_channel_sign_messages(dialog_id.get_channel_id())) { + auto show_message_sender = td_->chat_manager_->get_channel_show_message_sender(dialog_id.get_channel_id()); + if (m->sender_dialog_id != dialog_id || !m->has_explicit_sender) { + m->author_signature = m->sender_dialog_id == dialog_id || m->sender_dialog_id == DialogId() + ? td_->user_manager_->get_user_title(my_id) + : td_->dialog_manager_->get_dialog_title(m->sender_dialog_id); } - if (reply_m != nullptr && m->top_thread_message_id.is_valid()) { - m->is_topic_message = reply_m->is_topic_message; - } - } else if (m->top_thread_message_id.is_valid()) { - const Message *top_m = get_message(d, m->top_thread_message_id); - if (top_m != nullptr) { - m->is_topic_message = top_m->is_topic_message; + if (!show_message_sender) { + m->initial_sender_dialog_id = get_message_sender(m); + m->sender_user_id = UserId(); + m->sender_dialog_id = dialog_id; } } + m->message_id = options.schedule_date != 0 ? get_next_yet_unsent_scheduled_message_id(d, options.schedule_date) + : get_next_yet_unsent_message_id(d); + m->send_date = G()->unix_time(); + m->date = is_scheduled ? options.schedule_date : m->send_date; + m->replied_message_info = RepliedMessageInfo(td_, input_reply_to); + m->reply_to_story_full_id = input_reply_to.get_story_full_id(); + m->input_reply_to = std::move(input_reply_to); + m->reply_to_random_id = reply_to_random_id; + m->top_thread_message_id = top_thread_message_id; + m->initial_top_thread_message_id = initial_top_thread_message_id; + m->is_topic_message = is_topic_message; m->is_channel_post = is_channel_post; m->is_outgoing = is_scheduled || dialog_id != DialogId(my_id); m->from_background = options.from_background; @@ -24295,22 +23374,28 @@ unique_ptr MessagesManager::create_message_to_send( return false; } if (is_channel_post) { - return td_->contacts_manager_->get_channel_has_linked_channel(dialog_id.get_channel_id()); + return td_->chat_manager_->get_channel_has_linked_channel(dialog_id.get_channel_id()); } - return !reply_to_message_id.is_valid(); + return !m->input_reply_to.is_valid(); }()) { m->reply_info.reply_count_ = 0; if (is_channel_post) { auto linked_channel_id = - td_->contacts_manager_->get_channel_linked_channel_id(dialog_id.get_channel_id(), "create_message_to_send"); + td_->chat_manager_->get_channel_linked_channel_id(dialog_id.get_channel_id(), "create_message_to_send"); if (linked_channel_id.is_valid()) { m->reply_info.is_comment_ = true; m->reply_info.channel_id_ = linked_channel_id; } } } + if (m->sender_user_id == my_id && dialog_type == DialogType::Channel && !is_channel_post) { + m->sender_boost_count = td_->chat_manager_->get_channel_my_boost_count(dialog_id.get_channel_id()); + } + m->effect_id = MessageEffectId(options.effect_id); m->content = std::move(content); + m->invert_media = invert_media; m->forward_info = std::move(forward_info); + m->real_forward_from_dialog_id = real_forward_from_dialog_id; m->is_copy = is_copy || m->forward_info != nullptr; m->sending_id = options.sending_id; @@ -24323,42 +23408,36 @@ unique_ptr MessagesManager::create_message_to_send( if (dialog_type == DialogType::SecretChat) { CHECK(!is_scheduled); - m->ttl = td_->contacts_manager_->get_secret_chat_ttl(dialog_id.get_secret_chat_id()); if (is_service_message_content(m->content->get_type())) { - m->ttl = 0; - } - m->is_content_secret = is_secret_message_content(m->ttl, m->content->get_type()); - } - if ((reply_to_message_id.is_valid() || reply_to_message_id.is_valid_scheduled()) && - (dialog_type == DialogType::SecretChat || reply_to_message_id.is_yet_unsent())) { - // the message was forcely preloaded in get_reply_to_message_id - auto *reply_to_message = get_message(d, reply_to_message_id); - if (reply_to_message == nullptr) { - m->reply_to_message_id = MessageId(); + m->ttl = {}; } else { - m->reply_to_random_id = reply_to_message->random_id; + m->ttl = MessageSelfDestructType(td_->user_manager_->get_secret_chat_ttl(dialog_id.get_secret_chat_id()), false); } + m->is_content_secret = m->ttl.is_secret_message_content(m->content->get_type()); + } + if (dialog_id == DialogId(my_id)) { + m->saved_messages_topic_id = SavedMessagesTopicId(dialog_id, m->forward_info.get(), m->real_forward_from_dialog_id); } return message; } MessagesManager::Message *MessagesManager::get_message_to_send( - Dialog *d, MessageId top_thread_message_id, MessageId reply_to_message_id, const MessageSendOptions &options, - unique_ptr &&content, bool *need_update_dialog_pos, bool suppress_reply_info, - unique_ptr forward_info, bool is_copy, DialogId send_as_dialog_id) { + Dialog *d, MessageId top_thread_message_id, MessageInputReplyTo &&input_reply_to, const MessageSendOptions &options, + unique_ptr &&content, bool invert_media, bool *need_update_dialog_pos, bool suppress_reply_info, + unique_ptr forward_info, DialogId real_forward_from_dialog_id, bool is_copy, + DialogId send_as_dialog_id) { d->was_opened = true; - auto message = create_message_to_send(d, top_thread_message_id, reply_to_message_id, options, std::move(content), - suppress_reply_info, std::move(forward_info), is_copy, send_as_dialog_id); + auto message = create_message_to_send(d, top_thread_message_id, std::move(input_reply_to), options, + std::move(content), invert_media, suppress_reply_info, std::move(forward_info), + real_forward_from_dialog_id, is_copy, send_as_dialog_id); - MessageId message_id = options.schedule_date != 0 ? get_next_yet_unsent_scheduled_message_id(d, options.schedule_date) - : get_next_yet_unsent_message_id(d); - message->message_id = message_id; + auto message_id = message->message_id; message->random_id = generate_new_random_id(d); bool need_update = false; - CHECK(have_input_peer(d->dialog_id, AccessRights::Read)); + CHECK(td_->dialog_manager_->have_input_peer(d->dialog_id, true, AccessRights::Read)); auto result = add_message_to_dialog(d, std::move(message), false, true, &need_update, need_update_dialog_pos, "send message"); LOG_CHECK(result != nullptr) << message_id << " " << debug_add_message_to_dialog_fail_reason_; @@ -24372,23 +23451,23 @@ MessagesManager::Message *MessagesManager::get_message_to_send( } int64 MessagesManager::begin_send_message(DialogId dialog_id, const Message *m) { - LOG(INFO) << "Begin to send " << FullMessageId(dialog_id, m->message_id) << " with random_id = " << m->random_id; + LOG(INFO) << "Begin to send " << MessageFullId(dialog_id, m->message_id) << " with random_id = " << m->random_id; CHECK(m->random_id != 0); CHECK(m->message_id.is_yet_unsent()); - bool is_inserted = being_sent_messages_.emplace(m->random_id, FullMessageId(dialog_id, m->message_id)).second; + bool is_inserted = being_sent_messages_.emplace(m->random_id, MessageFullId(dialog_id, m->message_id)).second; CHECK(is_inserted); return m->random_id; } Status MessagesManager::can_send_message(DialogId dialog_id) const { - if (!have_input_peer(dialog_id, AccessRights::Write)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Write)) { return Status::Error(400, "Have no write access to the chat"); } if (dialog_id.get_type() == DialogType::Channel) { auto channel_id = dialog_id.get_channel_id(); - auto channel_type = td_->contacts_manager_->get_channel_type(channel_id); - auto channel_status = td_->contacts_manager_->get_channel_permissions(channel_id); + auto channel_type = td_->chat_manager_->get_channel_type(channel_id); + auto channel_status = td_->chat_manager_->get_channel_permissions(channel_id); switch (channel_type) { case ChannelType::Unknown: @@ -24414,8 +23493,8 @@ MessageId MessagesManager::get_persistent_message_id(const Dialog *d, MessageId if (message_id.is_yet_unsent()) { // it is possible that user tries to do something with an already sent message by its temporary identifier // we need to use real message in this case and transparently replace message_id - auto it = yet_unsent_full_message_id_to_persistent_message_id_.find({d->dialog_id, message_id}); - if (it != yet_unsent_full_message_id_to_persistent_message_id_.end()) { + auto it = yet_unsent_message_full_id_to_persistent_message_id_.find({d->dialog_id, message_id}); + if (it != yet_unsent_message_full_id_to_persistent_message_id_.end()) { return it->second; } } @@ -24423,81 +23502,143 @@ MessageId MessagesManager::get_persistent_message_id(const Dialog *d, MessageId return message_id; } -MessageId MessagesManager::get_reply_to_message_id(Dialog *d, MessageId top_thread_message_id, MessageId message_id, - bool for_draft) { +MessageInputReplyTo MessagesManager::create_message_input_reply_to( + Dialog *d, MessageId top_thread_message_id, td_api::object_ptr &&reply_to, + bool for_draft) { CHECK(d != nullptr); - if (top_thread_message_id.is_valid() && !have_message_force(d, top_thread_message_id, "get_reply_to_message_id 1")) { - LOG(INFO) << "Have reply to " << message_id << " in the thread of unknown " << top_thread_message_id; + if (top_thread_message_id.is_valid() && + !have_message_force(d, top_thread_message_id, "create_message_input_reply_to 1")) { + LOG(INFO) << "Have reply in the thread of unknown " << top_thread_message_id; } - if (!message_id.is_valid()) { - if (!for_draft && message_id == MessageId() && top_thread_message_id.is_valid() && - top_thread_message_id.is_server()) { - return top_thread_message_id; - } - return MessageId(); - } - message_id = get_persistent_message_id(d, message_id); - const Message *m = get_message_force(d, message_id, "get_reply_to_message_id 2"); - if (m == nullptr || m->message_id.is_yet_unsent() || - (m->message_id.is_local() && d->dialog_id.get_type() != DialogType::SecretChat)) { - if (message_id.is_server() && d->dialog_id.get_type() != DialogType::SecretChat && - message_id > d->last_new_message_id && - (d->notification_info != nullptr && message_id <= d->notification_info->max_notification_message_id_)) { - // allow to reply yet unreceived server message - return message_id; - } + if (reply_to == nullptr) { if (!for_draft && top_thread_message_id.is_valid() && top_thread_message_id.is_server()) { - return top_thread_message_id; + return MessageInputReplyTo{top_thread_message_id, DialogId(), MessageQuote()}; } - - // TODO local replies to local messages can be allowed - // TODO replies to yet unsent messages can be allowed with special handling of them on application restart - return MessageId(); + return {}; } - return m->message_id; -} + switch (reply_to->get_id()) { + case td_api::inputMessageReplyToStory::ID: { + if (for_draft) { + return {}; + } + auto reply_to_story = td_api::move_object_as(reply_to); + auto story_id = StoryId(reply_to_story->story_id_); + auto sender_dialog_id = DialogId(reply_to_story->story_sender_chat_id_); + if (d->dialog_id != sender_dialog_id || td_->dialog_manager_->is_broadcast_channel(sender_dialog_id)) { + LOG(INFO) << "Ignore reply to story from " << sender_dialog_id << " in a wrong " << d->dialog_id; + return {}; + } + if (!story_id.is_server()) { + LOG(INFO) << "Ignore reply to invalid " << story_id; + return {}; + } + return MessageInputReplyTo{StoryFullId(sender_dialog_id, story_id)}; + } + case td_api::inputMessageReplyToMessage::ID: { + auto reply_to_message = td_api::move_object_as(reply_to); + auto message_id = MessageId(reply_to_message->message_id_); + if (!message_id.is_valid()) { + if (!for_draft && message_id == MessageId() && top_thread_message_id.is_valid() && + top_thread_message_id.is_server()) { + return MessageInputReplyTo{top_thread_message_id, DialogId(), MessageQuote()}; + } + return {}; + } + message_id = get_persistent_message_id(d, message_id); + if (message_id == MessageId(ServerMessageId(1)) && d->dialog_id.get_type() == DialogType::Channel) { + return {}; + } + const Message *m = get_message_force(d, message_id, "create_message_input_reply_to 2"); + if (m == nullptr || m->message_id.is_yet_unsent() || + (m->message_id.is_local() && d->dialog_id.get_type() != DialogType::SecretChat)) { + if (message_id.is_server() && d->dialog_id.get_type() != DialogType::SecretChat && + message_id > d->last_new_message_id && + (d->notification_info != nullptr && + message_id <= d->notification_info->max_push_notification_message_id_)) { + // allow to reply yet unreceived server message in the same chat + return MessageInputReplyTo{message_id, DialogId(), MessageQuote{td_, std::move(reply_to_message->quote_)}}; + } + if (!for_draft && top_thread_message_id.is_valid() && top_thread_message_id.is_server()) { + return MessageInputReplyTo{top_thread_message_id, DialogId(), MessageQuote()}; + } + LOG(INFO) << "Can't find " << message_id << " in " << d->dialog_id; -void MessagesManager::fix_server_reply_to_message_id(DialogId dialog_id, MessageId message_id, - DialogId reply_in_dialog_id, - MessageId &reply_to_message_id) const { - if (!reply_to_message_id.is_valid()) { - if (reply_to_message_id.is_valid_scheduled()) { - CHECK(message_id.is_scheduled()); - CHECK(reply_in_dialog_id == DialogId()); - if (message_id == reply_to_message_id) { - LOG(ERROR) << "Receive reply to " << reply_to_message_id << " for " << message_id << " in " << dialog_id; - reply_to_message_id = MessageId(); + // TODO local replies to local messages can be allowed + // TODO replies to yet unsent messages can be allowed with special handling of them on application restart + return {}; } - return; + return MessageInputReplyTo{m->message_id, DialogId(), MessageQuote{td_, std::move(reply_to_message->quote_)}}; } - if (reply_to_message_id != MessageId()) { - LOG(ERROR) << "Receive reply to " << reply_to_message_id << " for " << message_id << " in " << dialog_id; - reply_to_message_id = MessageId(); + case td_api::inputMessageReplyToExternalMessage::ID: { + auto reply_to_message = td_api::move_object_as(reply_to); + if (d->dialog_id.get_type() == DialogType::SecretChat) { + return {}; + } + auto reply_dialog_id = DialogId(reply_to_message->chat_id_); + auto *reply_d = get_dialog_force(reply_dialog_id, "create_message_input_reply_to"); + if (reply_d == nullptr) { + return {}; + } + auto message_id = get_persistent_message_id(reply_d, MessageId(reply_to_message->message_id_)); + if (message_id == MessageId(ServerMessageId(1)) && reply_d->dialog_id.get_type() == DialogType::Channel) { + return {}; + } + const Message *m = get_message_force(reply_d, message_id, "create_message_input_reply_to 2"); + if (!can_forward_message(reply_dialog_id, m) || !m->message_id.is_valid() || !m->message_id.is_server()) { + LOG(INFO) << "Can't reply in another chat " << message_id << " in " << reply_d->dialog_id; + return {}; + } + return MessageInputReplyTo{m->message_id, reply_dialog_id, + MessageQuote{td_, std::move(reply_to_message->quote_)}}; } - return; + default: + UNREACHABLE(); + return {}; } +} - if (!message_id.is_scheduled() && !reply_in_dialog_id.is_valid() && - ((reply_to_message_id > message_id && !has_qts_messages(dialog_id)) || reply_to_message_id == message_id)) { - LOG(ERROR) << "Receive reply to wrong " << reply_to_message_id << " in " << message_id << " in " << dialog_id; - reply_to_message_id = MessageId(); +MessagesManager::ForwardedMessageInfo MessagesManager::get_forwarded_message_info(MessageFullId message_full_id) { + ForwardedMessageInfo result; + auto *m = get_message_force(message_full_id, "get_forwarded_message_info"); + if (m == nullptr || m->message_id.is_scheduled()) { + return result; } + auto dialog_id = message_full_id.get_dialog_id(); + result.origin_date_ = get_message_original_date(m); + result.origin_ = get_forwarded_message_origin(dialog_id, m); + result.content_ = dup_message_content(td_, td_->dialog_manager_->get_my_dialog_id(), m->content.get(), + MessageContentDupType::Forward, MessageCopyOptions()); + return result; +} + +const MessageInputReplyTo *MessagesManager::get_message_input_reply_to(const Message *m) { + CHECK(m != nullptr); + CHECK(!m->message_id.is_any_server()); + return &m->input_reply_to; } vector MessagesManager::get_message_file_ids(const Message *m) const { CHECK(m != nullptr); - return get_message_content_file_ids(m->content.get(), td_); + auto file_ids = get_message_content_file_ids(m->content.get(), td_); + if (!m->replied_message_info.is_empty()) { + append(file_ids, m->replied_message_info.get_file_ids(td_)); + } + return file_ids; } void MessagesManager::cancel_upload_message_content_files(const MessageContent *content) { - auto file_id = get_message_content_upload_file_id(content); + auto file_ids = get_message_content_upload_file_ids(content); // always cancel file upload, it should be a no-op in the worst case - if (being_uploaded_files_.erase(file_id) || file_id.is_valid()) { - cancel_upload_file(file_id, "cancel_upload_message_content_files"); + for (auto file_id : file_ids) { + if (being_uploaded_files_.erase(file_id) || file_id.is_valid()) { + cancel_upload_file(file_id, "cancel_upload_message_content_files"); + } } - file_id = get_message_content_thumbnail_file_id(content, td_); - if (being_uploaded_thumbnails_.erase(file_id) || file_id.is_valid()) { - cancel_upload_file(file_id, "cancel_upload_message_content_files"); + file_ids = get_message_content_thumbnail_file_ids(content, td_); + for (auto file_id : file_ids) { + if (being_uploaded_thumbnails_.erase(file_id) || file_id.is_valid()) { + cancel_upload_file(file_id, "cancel_upload_message_content_files"); + } } } @@ -24531,36 +23672,20 @@ void MessagesManager::cancel_send_message_query(DialogId dialog_id, Message *m) m->send_message_log_event_id = 0; } - if (m->reply_to_message_id.is_valid() && !m->reply_to_message_id.is_yet_unsent()) { - auto it = replied_by_yet_unsent_messages_.find({dialog_id, m->reply_to_message_id}); - CHECK(it != replied_by_yet_unsent_messages_.end()); - it->second--; - CHECK(it->second >= 0); - if (it->second == 0) { - replied_by_yet_unsent_messages_.erase(it); - } - } - if ((m->reply_to_message_id.is_valid() || m->reply_to_message_id.is_valid_scheduled()) && - m->reply_to_message_id.is_yet_unsent()) { - auto it = replied_yet_unsent_messages_.find({dialog_id, m->reply_to_message_id}); - CHECK(it != replied_yet_unsent_messages_.end()); - size_t erased_count = it->second.erase(m->message_id); - CHECK(erased_count > 0); - if (it->second.empty()) { - replied_yet_unsent_messages_.erase(it); - } - } + update_replied_by_message_count(dialog_id, m, false); { auto it = replied_yet_unsent_messages_.find({dialog_id, m->message_id}); if (it != replied_yet_unsent_messages_.end()) { - for (auto message_id : it->second) { - auto replied_m = get_message({dialog_id, message_id}); + for (auto message_full_id : it->second) { + auto reply_d = get_dialog(message_full_id.get_dialog_id()); + CHECK(reply_d != nullptr); + auto replied_m = get_message(reply_d, message_full_id.get_message_id()); CHECK(replied_m != nullptr); - CHECK(replied_m->reply_to_message_id == m->message_id); - unregister_message_reply(dialog_id, replied_m); - replied_m->reply_to_message_id = replied_m->top_thread_message_id; - replied_m->reply_to_random_id = 0; - register_message_reply(dialog_id, replied_m); + const auto *input_reply_to = get_message_input_reply_to(replied_m); + CHECK(input_reply_to != nullptr); + CHECK(input_reply_to->get_reply_message_full_id(reply_d->dialog_id) == MessageFullId(dialog_id, m->message_id)); + set_message_reply(reply_d, replied_m, + MessageInputReplyTo{replied_m->top_thread_message_id, DialogId(), MessageQuote()}, true); } replied_yet_unsent_messages_.erase(it); } @@ -24568,7 +23693,10 @@ void MessagesManager::cancel_send_message_query(DialogId dialog_id, Message *m) if (m->media_album_id != 0) { send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id, dialog_id, - m->message_id, Status::OK()); + m->message_id, -1, Status::OK()); + } else if (m->content->get_type() == MessageContentType::PaidMedia) { + LOG(INFO) << "Remove paid media group send from " << MessageFullId{dialog_id, m->message_id}; + pending_paid_media_group_sends_.erase({dialog_id, m->message_id}); } if (!m->message_id.is_scheduled() && G()->keep_media_order() && !m->is_copy) { @@ -24604,11 +23732,10 @@ bool MessagesManager::is_message_auto_read(DialogId dialog_id, bool is_outgoing) switch (dialog_id.get_type()) { case DialogType::User: { auto user_id = dialog_id.get_user_id(); - if (user_id == td_->contacts_manager_->get_my_id()) { + if (user_id == td_->user_manager_->get_my_id()) { return true; } - if (is_outgoing && td_->contacts_manager_->is_user_bot(user_id) && - !td_->contacts_manager_->is_user_support(user_id)) { + if (is_outgoing && td_->user_manager_->is_user_bot(user_id) && !td_->user_manager_->is_user_support(user_id)) { return true; } return false; @@ -24617,7 +23744,7 @@ bool MessagesManager::is_message_auto_read(DialogId dialog_id, bool is_outgoing) // TODO auto_read message content and messages sent to group with bots only return false; case DialogType::Channel: - return is_outgoing && is_broadcast_channel(dialog_id); + return is_outgoing && td_->dialog_manager_->is_broadcast_channel(dialog_id); case DialogType::SecretChat: return false; case DialogType::None: @@ -24629,19 +23756,21 @@ bool MessagesManager::is_message_auto_read(DialogId dialog_id, bool is_outgoing) } void MessagesManager::add_message_dependencies(Dependencies &dependencies, const Message *m) { + auto is_bot = td_->auth_manager_->is_bot(); dependencies.add(m->sender_user_id); dependencies.add_dialog_and_dependencies(m->sender_dialog_id); - dependencies.add_dialog_and_dependencies(m->reply_in_dialog_id); + m->saved_messages_topic_id.add_dependencies(dependencies); + m->replied_message_info.add_dependencies(dependencies, is_bot); + dependencies.add_dialog_and_dependencies(m->reply_to_story_full_id.get_dialog_id()); dependencies.add_dialog_and_dependencies(m->real_forward_from_dialog_id); dependencies.add(m->via_bot_user_id); + dependencies.add(m->via_business_bot_user_id); if (m->forward_info != nullptr) { - dependencies.add(m->forward_info->sender_user_id); - dependencies.add_dialog_and_dependencies(m->forward_info->sender_dialog_id); - dependencies.add_dialog_and_dependencies(m->forward_info->from_dialog_id); + m->forward_info->add_dependencies(dependencies); } for (const auto &replier_min_channel : m->reply_info.replier_min_channels_) { LOG(INFO) << "Add min replied " << replier_min_channel.first; - td_->contacts_manager_->add_min_channel(replier_min_channel.first, replier_min_channel.second); + td_->chat_manager_->add_min_channel(replier_min_channel.first, replier_min_channel.second); } for (auto recent_replier_dialog_id : m->reply_info.recent_replier_dialog_ids_) { dependencies.add_message_sender_dependencies(recent_replier_dialog_id); @@ -24650,7 +23779,10 @@ void MessagesManager::add_message_dependencies(Dependencies &dependencies, const m->reactions->add_min_channels(td_); m->reactions->add_dependencies(dependencies); } - add_message_content_dependencies(dependencies, m->content.get(), td_->auth_manager_->is_bot()); + if (m->fact_check != nullptr) { + m->fact_check->add_dependencies(dependencies); + } + add_message_content_dependencies(dependencies, m->content.get(), is_bot); add_reply_markup_dependencies(dependencies, m->reply_markup.get()); add_draft_message_dependencies(dependencies, m->thread_draft_message); } @@ -24658,30 +23790,33 @@ void MessagesManager::add_message_dependencies(Dependencies &dependencies, const void MessagesManager::get_dialog_send_message_as_dialog_ids( DialogId dialog_id, Promise> &&promise, bool is_recursive) { TRY_STATUS_PROMISE(promise, G()->close_status()); - - const Dialog *d = get_dialog_force(dialog_id, "get_group_call_join_as"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access chat")); - } - if (!d->default_send_message_as_dialog_id.is_valid()) { + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, true, AccessRights::Read, "get_dialog_send_message_as_dialog_ids")); + if (!d->default_send_message_as_dialog_id.is_valid() || can_send_message(dialog_id).is_error()) { return promise.set_value(td_api::make_object()); } + // checked in on_update_dialog_default_send_message_as_dialog_id CHECK(dialog_id.get_type() == DialogType::Channel); + auto is_broadcast = td_->dialog_manager_->is_broadcast_channel(dialog_id); + if (is_broadcast && !td_->chat_manager_->get_channel_sign_messages(dialog_id.get_channel_id())) { + return promise.set_value(td_api::make_object()); + } - if (created_public_broadcasts_inited_) { + if (td_->chat_manager_->are_created_public_broadcasts_inited()) { auto senders = td_api::make_object(); - if (!created_public_broadcasts_.empty()) { + const auto &created_public_broadcasts = td_->chat_manager_->get_created_public_broadcasts(); + if (!created_public_broadcasts.empty()) { auto add_sender = [&senders, td = td_](DialogId dialog_id, bool needs_premium) { - auto sender = get_message_sender_object_const(td, dialog_id, "add_sender"); + auto sender = get_message_sender_object(td, dialog_id, "add_sender"); senders->senders_.push_back(td_api::make_object(std::move(sender), needs_premium)); }; - if (is_anonymous_administrator(dialog_id, nullptr)) { + if (is_broadcast) { + add_sender(td_->dialog_manager_->get_my_dialog_id(), false); + } + if (td_->dialog_manager_->is_anonymous_administrator(dialog_id, nullptr)) { add_sender(dialog_id, false); } else { - add_sender(get_my_dialog_id(), false); + add_sender(td_->dialog_manager_->get_my_dialog_id(), false); } struct Sender { @@ -24691,12 +23826,15 @@ void MessagesManager::get_dialog_send_message_as_dialog_ids( std::multimap sorted_senders; bool is_premium = td_->option_manager_->get_option_boolean("is_premium"); - auto linked_channel_id = td_->contacts_manager_->get_channel_linked_channel_id( + auto linked_channel_id = td_->chat_manager_->get_channel_linked_channel_id( dialog_id.get_channel_id(), "get_dialog_send_message_as_dialog_ids"); - for (auto channel_id : created_public_broadcasts_) { - int64 score = td_->contacts_manager_->get_channel_participant_count(channel_id); - bool needs_premium = !is_premium && channel_id != linked_channel_id && - !td_->contacts_manager_->get_channel_is_verified(channel_id); + for (auto channel_id : created_public_broadcasts) { + if (DialogId(channel_id) == dialog_id) { + continue; + } + int64 score = td_->chat_manager_->get_channel_participant_count(channel_id); + bool needs_premium = !is_premium && !is_broadcast && channel_id != linked_channel_id && + !td_->chat_manager_->get_channel_is_verified(channel_id); if (needs_premium) { score -= static_cast(1) << 40; } @@ -24723,32 +23861,30 @@ void MessagesManager::get_dialog_send_message_as_dialog_ids( std::move(promise), true); } }); - td_->contacts_manager_->get_created_public_dialogs(PublicDialogType::HasUsername, std::move(new_promise), true); + td_->chat_manager_->get_created_public_dialogs(PublicDialogType::ForPersonalDialog, std::move(new_promise), true); } void MessagesManager::set_dialog_default_send_message_as_dialog_id(DialogId dialog_id, DialogId message_sender_dialog_id, Promise &&promise) { - Dialog *d = get_dialog_force(dialog_id, "set_dialog_default_send_message_as_dialog_id"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!d->default_send_message_as_dialog_id.is_valid()) { + TRY_RESULT_PROMISE( + promise, d, + check_dialog_access(dialog_id, false, AccessRights::Read, "set_dialog_default_send_message_as_dialog_id")); + if (!d->default_send_message_as_dialog_id.is_valid() || can_send_message(dialog_id).is_error()) { return promise.set_error(Status::Error(400, "Can't change message sender in the chat")); } // checked in on_update_dialog_default_send_message_as_dialog_id - CHECK(dialog_id.get_type() == DialogType::Channel && !is_broadcast_channel(dialog_id)); - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + CHECK(dialog_id.get_type() == DialogType::Channel); - bool is_anonymous = is_anonymous_administrator(dialog_id, nullptr); + auto is_broadcast = td_->dialog_manager_->is_broadcast_channel(dialog_id); + auto is_anonymous = td_->dialog_manager_->is_anonymous_administrator(dialog_id, nullptr); switch (message_sender_dialog_id.get_type()) { case DialogType::User: - if (message_sender_dialog_id != DialogId(td_->contacts_manager_->get_my_id())) { + if (message_sender_dialog_id != td_->dialog_manager_->get_my_dialog_id()) { return promise.set_error(Status::Error(400, "Can't send messages as another user")); } - if (is_anonymous) { + if (is_anonymous && + (!is_broadcast || !td_->chat_manager_->get_channel_sign_messages(dialog_id.get_channel_id()))) { return promise.set_error(Status::Error(400, "Can't send messages as self")); } break; @@ -24758,27 +23894,19 @@ void MessagesManager::set_dialog_default_send_message_as_dialog_id(DialogId dial if (is_anonymous && dialog_id == message_sender_dialog_id) { break; } - if (!is_broadcast_channel(message_sender_dialog_id) || - td_->contacts_manager_->get_channel_first_username(message_sender_dialog_id.get_channel_id()).empty()) { + if (!td_->dialog_manager_->is_broadcast_channel(message_sender_dialog_id) || + td_->chat_manager_->get_channel_first_username(message_sender_dialog_id.get_channel_id()).empty()) { return promise.set_error(Status::Error(400, "Message sender chat must be a public channel")); } break; default: return promise.set_error(Status::Error(400, "Invalid message sender specified")); } - if (!have_input_peer(message_sender_dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(message_sender_dialog_id, true, AccessRights::Read)) { return promise.set_error(Status::Error(400, "Can't access specified message sender chat")); } - { - auto it = set_typing_query_.find(dialog_id); - if (it != set_typing_query_.end()) { - if (!it->second.empty()) { - cancel_query(it->second); - } - set_typing_query_.erase(it); - } - } + td_->dialog_action_manager_->cancel_send_dialog_action_queries(dialog_id); td_->create_handler(std::move(promise))->send(dialog_id, message_sender_dialog_id); @@ -24811,8 +23939,9 @@ class MessagesManager::SendMessageLogEvent { }; Result> MessagesManager::send_message( - DialogId dialog_id, MessageId top_thread_message_id, MessageId reply_to_message_id, - tl_object_ptr &&options, tl_object_ptr &&reply_markup, + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr &&reply_to, tl_object_ptr &&options, + tl_object_ptr &&reply_markup, tl_object_ptr &&input_message_content) { if (input_message_content == nullptr) { return Status::Error(400, "Can't send message without content"); @@ -24823,14 +23952,12 @@ Result> MessagesManager::send_message( return Status::Error(400, "Chat not found"); } - LOG(INFO) << "Begin to send message to " << dialog_id << " in reply to " << reply_to_message_id; - - reply_to_message_id = get_reply_to_message_id(d, top_thread_message_id, reply_to_message_id, false); + auto input_reply_to = create_message_input_reply_to(d, top_thread_message_id, std::move(reply_to), false); if (input_message_content->get_id() == td_api::inputMessageForwarded::ID) { auto input_message = td_api::move_object_as(input_message_content); TRY_RESULT(copy_options, process_message_copy_options(dialog_id, std::move(input_message->copy_options_))); - copy_options.reply_to_message_id = reply_to_message_id; + copy_options.input_reply_to = std::move(input_reply_to); TRY_RESULT_ASSIGN(copy_options.reply_markup, get_dialog_reply_markup(dialog_id, std::move(reply_markup))); return forward_message(dialog_id, top_thread_message_id, DialogId(input_message->from_chat_id_), MessageId(input_message->message_id_), std::move(options), input_message->in_game_share_, @@ -24840,35 +23967,43 @@ Result> MessagesManager::send_message( TRY_STATUS(can_send_message(dialog_id)); TRY_RESULT(message_reply_markup, get_dialog_reply_markup(dialog_id, std::move(reply_markup))); TRY_RESULT(message_content, process_input_message_content(dialog_id, std::move(input_message_content))); - TRY_RESULT(message_send_options, process_message_send_options(dialog_id, std::move(options), true)); + TRY_RESULT(message_send_options, process_message_send_options(dialog_id, std::move(options), true, true)); TRY_STATUS(can_use_message_send_options(message_send_options, message_content)); - TRY_STATUS(can_use_top_thread_message_id(d, top_thread_message_id, reply_to_message_id)); + TRY_STATUS(can_use_top_thread_message_id(d, top_thread_message_id, input_reply_to)); // there must be no errors after get_message_to_send call + auto content = dup_message_content(td_, dialog_id, message_content.content.get(), MessageContentDupType::Send, + MessageCopyOptions()); bool need_update_dialog_pos = false; - Message *m = get_message_to_send(d, top_thread_message_id, reply_to_message_id, message_send_options, - dup_message_content(td_, dialog_id, message_content.content.get(), - MessageContentDupType::Send, MessageCopyOptions()), - &need_update_dialog_pos, false, nullptr, message_content.via_bot_user_id.is_valid()); + unique_ptr message; + Message *m; + if (message_send_options.only_preview) { + message = create_message_to_send(d, top_thread_message_id, std::move(input_reply_to), message_send_options, + std::move(content), message_content.invert_media, false, nullptr, DialogId(), + message_content.via_bot_user_id.is_valid(), DialogId()); + m = message.get(); + } else { + m = get_message_to_send(d, top_thread_message_id, std::move(input_reply_to), message_send_options, + std::move(content), message_content.invert_media, &need_update_dialog_pos, false, nullptr, + DialogId(), message_content.via_bot_user_id.is_valid()); + } m->reply_markup = std::move(message_reply_markup); m->via_bot_user_id = message_content.via_bot_user_id; m->disable_web_page_preview = message_content.disable_web_page_preview; m->clear_draft = message_content.clear_draft; - if (message_content.ttl > 0) { + if (message_content.ttl.is_valid()) { m->ttl = message_content.ttl; - m->is_content_secret = is_secret_message_content(m->ttl, m->content->get_type()); + m->is_content_secret = m->ttl.is_secret_message_content(m->content->get_type()); } m->send_emoji = std::move(message_content.emoji); - if (m->clear_draft) { - if (top_thread_message_id.is_valid()) { - set_dialog_draft_message(dialog_id, top_thread_message_id, nullptr).ignore(); - } else { - update_dialog_draft_message(d, nullptr, false, !need_update_dialog_pos); - } + if (message_send_options.only_preview) { + return get_message_object(dialog_id, m, "send_message"); } + clear_dialog_draft_by_sent_message(d, m, !need_update_dialog_pos); + save_send_message_log_event(dialog_id, m); do_send_message(dialog_id, m); @@ -24883,12 +24018,9 @@ Result> MessagesManager::send_message( } Result MessagesManager::process_input_message_content( - DialogId dialog_id, tl_object_ptr &&input_message_content) { - if (input_message_content == nullptr) { - return Status::Error(400, "Can't send message without content"); - } - - if (input_message_content->get_id() == td_api::inputMessageForwarded::ID) { + DialogId dialog_id, tl_object_ptr &&input_message_content, bool check_permissions) { + CHECK(dialog_id.is_valid()); + if (input_message_content != nullptr && input_message_content->get_id() == td_api::inputMessageForwarded::ID) { // for sendMessageAlbum/editMessageMedia/addLocalMessage auto input_message = td_api::move_object_as(input_message_content); TRY_RESULT(copy_options, process_message_copy_options(dialog_id, std::move(input_message->copy_options_))); @@ -24901,12 +24033,9 @@ Result MessagesManager::process_input_message_content( if (from_dialog == nullptr) { return Status::Error(400, "Chat to copy message from not found"); } - if (!have_input_peer(from_dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(from_dialog_id, false, AccessRights::Read)) { return Status::Error(400, "Can't access the chat to copy message from"); } - if (from_dialog_id.get_type() == DialogType::SecretChat) { - return Status::Error(400, "Can't copy message from secret chats"); - } MessageId message_id = get_persistent_message_id(from_dialog, MessageId(input_message->message_id_)); const Message *copied_message = get_message_force(from_dialog, message_id, "process_input_message_content"); @@ -24920,30 +24049,24 @@ Result MessagesManager::process_input_message_content( return Status::Error(400, "Message copying is restricted"); } + auto new_invert_media = + copy_options.replace_caption && is_allowed_invert_caption_message_content(copied_message->content->get_type()) + ? copy_options.new_invert_media + : copied_message->invert_media; unique_ptr content = dup_message_content(td_, dialog_id, copied_message->content.get(), MessageContentDupType::Copy, std::move(copy_options)); if (content == nullptr) { return Status::Error(400, "Can't copy message content"); } - return InputMessageContent(std::move(content), get_message_disable_web_page_preview(copied_message), false, 0, - UserId(), copied_message->send_emoji); + return InputMessageContent(std::move(content), get_message_disable_web_page_preview(copied_message), + new_invert_media, false, MessageSelfDestructType(), UserId(), + copied_message->send_emoji); } bool is_premium = td_->option_manager_->get_option_boolean("is_premium"); TRY_RESULT(content, get_input_message_content(dialog_id, std::move(input_message_content), td_, is_premium)); - - if (content.ttl < 0 || content.ttl > MAX_PRIVATE_MESSAGE_TTL) { - return Status::Error(400, "Invalid message content self-destruct time specified"); - } - if (content.ttl > 0 && dialog_id.get_type() != DialogType::User) { - return Status::Error(400, "Message content self-destruct time can be specified only in private chats"); - } - - if (dialog_id != DialogId()) { - TRY_STATUS(can_send_message_content(dialog_id, content.content.get(), false, td_)); - } - + TRY_STATUS(can_send_message_content(dialog_id, content.content.get(), false, check_permissions, td_)); return std::move(content); } @@ -24958,54 +24081,68 @@ Result MessagesManager::process_message_copy_options( if (result.replace_caption) { TRY_RESULT_ASSIGN(result.new_caption, get_formatted_text(td_, dialog_id, std::move(options->new_caption_), td_->auth_manager_->is_bot(), true, false, false)); + result.new_invert_media = options->new_show_caption_above_media_; } return std::move(result); } Result MessagesManager::process_message_send_options( - DialogId dialog_id, tl_object_ptr &&options, - bool allow_update_stickersets_order) const { + DialogId dialog_id, tl_object_ptr &&options, bool allow_update_stickersets_order, + bool allow_effect) const { MessageSendOptions result; - if (options != nullptr) { - result.disable_notification = options->disable_notification_; - result.from_background = options->from_background_; - if (allow_update_stickersets_order) { - result.update_stickersets_order = options->update_order_of_installed_sticker_sets_; - } + if (options == nullptr) { + return std::move(result); + } + + result.disable_notification = options->disable_notification_; + result.from_background = options->from_background_; + if (allow_update_stickersets_order) { + result.update_stickersets_order = options->update_order_of_installed_sticker_sets_; + } + if (td_->auth_manager_->is_bot()) { result.protect_content = options->protect_content_; - TRY_RESULT_ASSIGN(result.schedule_date, get_message_schedule_date(std::move(options->scheduling_state_))); - result.sending_id = options->sending_id_; } + result.only_preview = options->only_preview_; + TRY_RESULT_ASSIGN(result.schedule_date, get_message_schedule_date(std::move(options->scheduling_state_))); + result.sending_id = options->sending_id_; - auto dialog_type = dialog_id.get_type(); if (result.schedule_date != 0) { + auto dialog_type = dialog_id.get_type(); if (dialog_type == DialogType::SecretChat) { return Status::Error(400, "Can't schedule messages in secret chats"); } if (td_->auth_manager_->is_bot()) { return Status::Error(400, "Bots can't send scheduled messages"); } + + if (result.schedule_date == SCHEDULE_WHEN_ONLINE_DATE) { + if (dialog_type != DialogType::User) { + return Status::Error(400, "Messages can be scheduled till online only in private chats"); + } + if (dialog_id == td_->dialog_manager_->get_my_dialog_id()) { + return Status::Error(400, "Can't scheduled till online messages in chat with self"); + } + } } - if (result.schedule_date == SCHEDULE_WHEN_ONLINE_DATE) { + if (options->effect_id_ != 0) { + auto dialog_type = dialog_id.get_type(); if (dialog_type != DialogType::User) { - return Status::Error(400, "Messages can be scheduled till online only in private chats"); + return Status::Error(400, "Can't use message effects in the chat"); } - if (dialog_id == get_my_dialog_id()) { - return Status::Error(400, "Can't scheduled till online messages in chat with self"); + if (!allow_effect) { + return Status::Error(400, "Can't use message effects in the method"); } + result.effect_id = MessageEffectId(options->effect_id_); } - if (result.protect_content && !td_->auth_manager_->is_bot()) { - result.protect_content = false; - } - - return result; + return std::move(result); } Status MessagesManager::can_use_message_send_options(const MessageSendOptions &options, - const unique_ptr &content, int32 ttl) { + const unique_ptr &content, + MessageSelfDestructType ttl) { if (options.schedule_date != 0) { - if (ttl > 0) { + if (ttl.is_valid()) { return Status::Error(400, "Can't send scheduled self-destructing messages"); } if (content->get_type() == MessageContentType::LiveLocation) { @@ -25022,7 +24159,7 @@ Status MessagesManager::can_use_message_send_options(const MessageSendOptions &o } Status MessagesManager::can_use_top_thread_message_id(Dialog *d, MessageId top_thread_message_id, - MessageId reply_to_message_id) { + const MessageInputReplyTo &input_reply_to) { if (top_thread_message_id == MessageId()) { return Status::OK(); } @@ -25030,21 +24167,25 @@ Status MessagesManager::can_use_top_thread_message_id(Dialog *d, MessageId top_t if (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server()) { return Status::Error(400, "Invalid message thread identifier specified"); } - if (d->dialog_id.get_type() != DialogType::Channel || is_broadcast_channel(d->dialog_id)) { + if (d->dialog_id.get_type() != DialogType::Channel || td_->dialog_manager_->is_broadcast_channel(d->dialog_id)) { return Status::Error(400, "Chat doesn't have threads"); } - if (reply_to_message_id.is_valid()) { - const Message *reply_m = get_message_force(d, reply_to_message_id, "can_use_top_thread_message_id 1"); + if (input_reply_to.get_story_full_id().is_valid()) { + return Status::Error(400, "Can't send story replies to the thread"); + } + auto same_chat_reply_to_message_id = input_reply_to.get_same_chat_reply_to_message_id(); + if (same_chat_reply_to_message_id.is_valid()) { + const Message *reply_m = get_message_force(d, same_chat_reply_to_message_id, "can_use_top_thread_message_id 1"); if (reply_m != nullptr && top_thread_message_id != reply_m->top_thread_message_id) { if (reply_m->top_thread_message_id.is_valid() || reply_m->media_album_id == 0) { - return Status::Error(400, "The message to reply is not in the specified message thread"); + return Status::Error(400, "The message to be replied is not in the specified message thread"); } // if the message is in an album and not in the thread, it can be in the album of top_thread_message_id const Message *top_m = get_message_force(d, top_thread_message_id, "can_use_top_thread_message_id 2"); if (top_m != nullptr && (top_m->media_album_id != reply_m->media_album_id || top_m->top_thread_message_id != top_m->message_id)) { - return Status::Error(400, "The message to reply is not in the specified message thread root album"); + return Status::Error(400, "The message to be replied is not in the specified message thread root album"); } } } @@ -25061,47 +24202,27 @@ int64 MessagesManager::generate_new_media_album_id() { } Result> MessagesManager::send_message_group( - DialogId dialog_id, MessageId top_thread_message_id, MessageId reply_to_message_id, - tl_object_ptr &&options, - vector> &&input_message_contents, bool only_preview) { - if (input_message_contents.size() > MAX_GROUPED_MESSAGES) { - return Status::Error(400, "Too many messages to send as an album"); - } - if (input_message_contents.empty()) { - return Status::Error(400, "There are no messages to send"); - } - + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr &&reply_to, tl_object_ptr &&options, + vector> &&input_message_contents) { Dialog *d = get_dialog_force(dialog_id, "send_message_group"); if (d == nullptr) { return Status::Error(400, "Chat not found"); } TRY_STATUS(can_send_message(dialog_id)); - TRY_RESULT(message_send_options, process_message_send_options(dialog_id, std::move(options), true)); + TRY_RESULT(message_send_options, process_message_send_options(dialog_id, std::move(options), true, true)); - vector, int32>> message_contents; - std::unordered_set message_content_types; + vector message_contents; for (auto &input_message_content : input_message_contents) { TRY_RESULT(message_content, process_input_message_content(dialog_id, std::move(input_message_content))); TRY_STATUS(can_use_message_send_options(message_send_options, message_content)); - auto message_content_type = message_content.content->get_type(); - if (!is_allowed_media_group_content(message_content_type)) { - return Status::Error(400, "Invalid message content type"); - } - message_content_types.insert(message_content_type); - - message_contents.emplace_back(std::move(message_content.content), message_content.ttl); - } - if (message_content_types.size() > 1) { - for (auto message_content_type : message_content_types) { - if (is_homogenous_media_group_content(message_content_type)) { - return Status::Error(400, PSLICE() << message_content_type << " can't be mixed with other media types"); - } - } + message_contents.push_back(std::move(message_content)); } + TRY_STATUS(check_message_group_message_contents(message_contents)); - reply_to_message_id = get_reply_to_message_id(d, top_thread_message_id, reply_to_message_id, false); - TRY_STATUS(can_use_top_thread_message_id(d, top_thread_message_id, reply_to_message_id)); + auto input_reply_to = create_message_input_reply_to(d, top_thread_message_id, std::move(reply_to), false); + TRY_STATUS(can_use_top_thread_message_id(d, top_thread_message_id, input_reply_to)); int64 media_album_id = 0; if (message_contents.size() > 1) { @@ -25116,31 +24237,28 @@ Result> MessagesManager::send_message_group auto &message_content = message_contents[i]; unique_ptr message; Message *m; - if (only_preview) { - message = create_message_to_send(d, top_thread_message_id, reply_to_message_id, message_send_options, - std::move(message_content.first), i != 0, nullptr, false, DialogId()); - MessageId new_message_id = message_send_options.schedule_date != 0 - ? get_next_yet_unsent_scheduled_message_id(d, message_send_options.schedule_date) - : get_next_yet_unsent_message_id(d); - message->message_id = new_message_id; + if (message_send_options.only_preview) { + message = create_message_to_send(d, top_thread_message_id, input_reply_to.clone(), message_send_options, + std::move(message_content.content), message_content.invert_media, i != 0, + nullptr, DialogId(), false, DialogId()); m = message.get(); } else { - m = get_message_to_send(d, top_thread_message_id, reply_to_message_id, message_send_options, - dup_message_content(td_, dialog_id, message_content.first.get(), + m = get_message_to_send(d, top_thread_message_id, input_reply_to.clone(), message_send_options, + dup_message_content(td_, dialog_id, message_content.content.get(), MessageContentDupType::Send, MessageCopyOptions()), - &need_update_dialog_pos, i != 0); + message_content.invert_media, &need_update_dialog_pos, i != 0); } - auto ttl = message_content.second; - if (ttl > 0) { + auto ttl = message_content.ttl; + if (ttl.is_valid()) { m->ttl = ttl; - m->is_content_secret = is_secret_message_content(m->ttl, m->content->get_type()); + m->is_content_secret = m->ttl.is_secret_message_content(m->content->get_type()); } m->media_album_id = media_album_id; result.push_back(get_message_object(dialog_id, m, "send_message_group")); - if (!only_preview) { + if (!message_send_options.only_preview) { save_send_message_log_event(dialog_id, m); do_send_message(dialog_id, m); @@ -25151,7 +24269,7 @@ Result> MessagesManager::send_message_group } if (need_update_dialog_pos) { - CHECK(!only_preview); + CHECK(!message_send_options.only_preview); send_update_chat_last_message(d, "send_message_group"); } @@ -25164,16 +24282,16 @@ void MessagesManager::save_send_message_log_event(DialogId dialog_id, const Mess } CHECK(m != nullptr); - LOG(INFO) << "Save " << FullMessageId(dialog_id, m->message_id) << " to binlog"; + LOG(INFO) << "Save " << MessageFullId(dialog_id, m->message_id) << " to binlog"; auto log_event = SendMessageLogEvent(dialog_id, m); CHECK(m->send_message_log_event_id == 0); m->send_message_log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SendMessage, get_log_event_storer(log_event)); } -void MessagesManager::do_send_message(DialogId dialog_id, const Message *m, vector bad_parts) { +void MessagesManager::do_send_message(DialogId dialog_id, const Message *m, int32 media_pos, vector bad_parts) { bool is_edit = m->message_id.is_any_server(); - LOG(INFO) << "Do " << (is_edit ? "edit" : "send") << ' ' << FullMessageId(dialog_id, m->message_id); + LOG(INFO) << "Do " << (is_edit ? "edit" : "send") << ' ' << MessageFullId(dialog_id, m->message_id); bool is_secret = dialog_id.get_type() == DialogType::SecretChat; if (m->media_album_id != 0 && bad_parts.empty() && !is_secret && !is_edit) { @@ -25194,21 +24312,32 @@ void MessagesManager::do_send_message(DialogId dialog_id, const Message *m, vect return; } - FileId file_id = get_message_content_any_file_id(content); // any_file_id, because it could be a photo sent by ID - FileView file_view = td_->file_manager_->get_file_view(file_id); - FileId thumbnail_file_id = get_message_content_thumbnail_file_id(content, td_); - LOG(DEBUG) << "Need to send file " << file_id << " with thumbnail " << thumbnail_file_id; + auto file_ids = get_message_content_any_file_ids(content); // any_file_ids, because it could be a photo sent by ID + auto thumbnail_file_ids = get_message_content_thumbnail_file_ids(content, td_); + LOG(DEBUG) << "Need to send files " << file_ids << " with thumbnails " << thumbnail_file_ids; + if (!bad_parts.empty()) { + CHECK(file_ids.size() <= 1u || media_pos >= 0); + } + if (file_ids.size() != thumbnail_file_ids.size()) { + CHECK(file_ids.size() == 1u); + CHECK(thumbnail_file_ids.empty()); + } if (is_secret) { + CHECK(file_ids.size() <= 1u); + auto file_id = file_ids.empty() ? FileId() : file_ids[0]; + auto thumbnail_file_id = thumbnail_file_ids.empty() ? FileId() : thumbnail_file_ids[0]; + CHECK(!is_edit); - auto layer = td_->contacts_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); - auto secret_input_media = get_secret_input_media(content, td_, nullptr, BufferSlice(), layer); + auto layer = td_->user_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); + auto secret_input_media = get_message_content_secret_input_media(content, td_, nullptr, BufferSlice(), layer); if (secret_input_media.empty()) { LOG(INFO) << "Ask to upload encrypted file " << file_id; - CHECK(file_view.is_encrypted_secret()); CHECK(file_id.is_valid()); + FileView file_view = td_->file_manager_->get_file_view(file_id); + CHECK(file_view.is_encrypted_secret()); bool is_inserted = being_uploaded_files_ - .emplace(file_id, std::make_pair(FullMessageId(dialog_id, m->message_id), thumbnail_file_id)) + .emplace(file_id, UploadedFileInfo{MessageFullId(dialog_id, m->message_id), thumbnail_file_id, -1}) .second; CHECK(is_inserted); // need to call resume_upload synchronously to make upload process consistent with being_uploaded_files_ @@ -25217,35 +24346,71 @@ void MessagesManager::do_send_message(DialogId dialog_id, const Message *m, vect on_secret_message_media_uploaded(dialog_id, m, std::move(secret_input_media), file_id, thumbnail_file_id); } } else { - auto input_media = - get_input_media(content, td_, m->ttl, m->send_emoji, td_->auth_manager_->is_bot() && bad_parts.empty()); - if (input_media == nullptr) { - if (content_type == MessageContentType::Game || content_type == MessageContentType::Poll) { + if (media_pos >= 0) { + CHECK(!bad_parts.empty()); + CHECK(static_cast(media_pos) < file_ids.size()); + CHECK(static_cast(media_pos) < thumbnail_file_ids.size()); + } + auto input_media = get_message_content_input_media(content, td_, m->ttl, m->send_emoji, + td_->auth_manager_->is_bot() && bad_parts.empty()); + if (input_media == nullptr || media_pos >= 0 || !bad_parts.empty() || + content_type == MessageContentType::PaidMedia) { + if (content_type == MessageContentType::Game || content_type == MessageContentType::Poll || + content_type == MessageContentType::Story) { return; } - if (get_main_file_type(file_view.get_type()) == FileType::Photo) { - thumbnail_file_id = FileId(); - } + CHECK(!file_ids.empty()); + if (content_type == MessageContentType::PaidMedia && bad_parts.empty()) { + CHECK(!is_secret && !is_edit); + CHECK(media_pos == -1); + LOG(INFO) << "Add paid media group send for " << MessageFullId{dialog_id, m->message_id}; + auto &request = pending_paid_media_group_sends_[{dialog_id, m->message_id}]; + CHECK(request.is_finished.empty()); + request.is_finished.resize(file_ids.size()); + request.results.resize(file_ids.size()); + } + for (size_t i = 0; i < file_ids.size(); i++) { + if (media_pos >= 0 && static_cast(media_pos) != i) { + continue; + } + auto file_id = file_ids[i]; + CHECK(file_id.is_valid()); - LOG(INFO) << "Ask to upload file " << file_id << " with bad parts " << bad_parts; - CHECK(file_id.is_valid()); - bool is_inserted = - being_uploaded_files_ - .emplace(file_id, std::make_pair(FullMessageId(dialog_id, m->message_id), thumbnail_file_id)) - .second; - CHECK(is_inserted); - // need to call resume_upload synchronously to make upload process consistent with being_uploaded_files_ - // and to send is_uploading_active == true in the updates - td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_media_callback_, 1, m->message_id.get()); + auto thumbnail_file_id = i < thumbnail_file_ids.size() ? thumbnail_file_ids[i] : FileId(); + FileView file_view = td_->file_manager_->get_file_view(file_id); + if (get_main_file_type(file_view.get_type()) == FileType::Photo) { + thumbnail_file_id = FileId(); + } + + if (content_type == MessageContentType::PaidMedia && !file_view.has_full_remote_location() && + file_view.has_url()) { + do_send_media(dialog_id, m, static_cast(i), file_id, FileId(), nullptr, nullptr); + continue; + } + + LOG(INFO) << "Ask to upload file " << file_id << " with bad parts " << bad_parts; + bool is_inserted = + being_uploaded_files_ + .emplace(file_id, + UploadedFileInfo{MessageFullId(dialog_id, m->message_id), thumbnail_file_id, + content_type == MessageContentType::PaidMedia ? static_cast(i) : -1}) + .second; + CHECK(is_inserted); + // need to call resume_upload synchronously to make upload process consistent with being_uploaded_files_ + // and to send is_uploading_active == true in the updates + td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_media_callback_, 1, + m->message_id.get()); + } } else { - on_message_media_uploaded(dialog_id, m, std::move(input_media), file_id, thumbnail_file_id); + on_message_media_uploaded(dialog_id, m, -1, std::move(input_media), std::move(file_ids), + std::move(thumbnail_file_ids)); } } } -void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Message *m, - tl_object_ptr &&input_media, FileId file_id, - FileId thumbnail_file_id) { +void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Message *m, int32 media_pos, + telegram_api::object_ptr &&input_media, + vector file_ids, vector thumbnail_file_ids) { if (G()->close_flag()) { return; } @@ -25254,8 +24419,12 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Messag CHECK(input_media != nullptr); auto message_id = m->message_id; if (message_id.is_any_server()) { + CHECK(media_pos == -1); + CHECK(file_ids.size() == 1u); + auto file_id = file_ids[0]; + auto thumbnail_file_id = thumbnail_file_ids.empty() ? FileId() : thumbnail_file_ids[0]; const FormattedText *caption = get_message_content_caption(m->edited_content.get()); - auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), m->edited_reply_markup); + auto input_reply_markup = get_input_reply_markup(td_->user_manager_.get(), m->edited_reply_markup); bool was_uploaded = FileManager::extract_was_uploaded(input_media); bool was_thumbnail_uploaded = FileManager::extract_was_thumbnail_uploaded(input_media); @@ -25271,17 +24440,17 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Messag }); td_->create_handler(std::move(promise)) ->send(1 << 11, dialog_id, message_id, caption == nullptr ? "" : caption->text, - get_input_message_entities(td_->contacts_manager_.get(), caption, "edit_message_media"), - std::move(input_media), std::move(input_reply_markup), schedule_date); + get_input_message_entities(td_->user_manager_.get(), caption, "edit_message_media"), + std::move(input_media), m->edited_invert_media, std::move(input_reply_markup), schedule_date); return; } - if (m->media_album_id == 0) { + if (m->media_album_id == 0 && media_pos == -1) { send_closure_later( actor_id(this), &MessagesManager::on_media_message_ready_to_send, dialog_id, message_id, - PromiseCreator::lambda([this, dialog_id, input_media = std::move(input_media), file_id, - thumbnail_file_id](Result result) mutable { - if (result.is_error() || G()->close_flag()) { + PromiseCreator::lambda([this, dialog_id, input_media = std::move(input_media), file_ids = std::move(file_ids), + thumbnail_file_ids = std::move(thumbnail_file_ids)](Result result) mutable { + if (G()->close_flag() || result.is_error()) { return; } @@ -25290,39 +24459,27 @@ void MessagesManager::on_message_media_uploaded(DialogId dialog_id, const Messag CHECK(input_media != nullptr); const FormattedText *caption = get_message_content_caption(m->content.get()); - LOG(INFO) << "Send media from " << m->message_id << " in " << dialog_id << " in reply to " - << m->reply_to_message_id; + LOG(INFO) << "Send media from " << m->message_id << " in " << dialog_id; int64 random_id = begin_send_message(dialog_id, m); td_->create_handler()->send( - file_id, thumbnail_file_id, get_message_flags(m), dialog_id, get_send_message_as_input_peer(m), - m->reply_to_message_id, m->top_thread_message_id, get_message_schedule_date(m), - get_input_reply_markup(td_->contacts_manager_.get(), m->reply_markup), - get_input_message_entities(td_->contacts_manager_.get(), caption, "on_message_media_uploaded"), + std::move(file_ids), std::move(thumbnail_file_ids), get_message_flags(m), dialog_id, + get_send_message_as_input_peer(m), *get_message_input_reply_to(m), m->initial_top_thread_message_id, + get_message_schedule_date(m), m->effect_id, + get_input_reply_markup(td_->user_manager_.get(), m->reply_markup), + get_input_message_entities(td_->user_manager_.get(), caption, "on_message_media_uploaded"), caption == nullptr ? "" : caption->text, std::move(input_media), m->content->get_type(), m->is_copy, random_id, &m->send_query_ref); })); } else { - switch (input_media->get_id()) { - case telegram_api::inputMediaUploadedDocument::ID: - static_cast(input_media.get())->flags_ |= - telegram_api::inputMediaUploadedDocument::NOSOUND_VIDEO_MASK; - // fallthrough - case telegram_api::inputMediaUploadedPhoto::ID: - case telegram_api::inputMediaDocumentExternal::ID: - case telegram_api::inputMediaPhotoExternal::ID: - LOG(INFO) << "Upload media from " << message_id << " in " << dialog_id; - td_->create_handler()->send(dialog_id, message_id, file_id, thumbnail_file_id, - std::move(input_media)); - break; - case telegram_api::inputMediaDocument::ID: - case telegram_api::inputMediaPhoto::ID: - send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id, - dialog_id, message_id, Status::OK()); - break; - default: - LOG(ERROR) << "Have wrong input media " << to_string(input_media); - send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id, - dialog_id, message_id, Status::Error(400, "Invalid input media")); + if (!is_uploaded_input_media(input_media)) { + CHECK(file_ids.size() == 1u); + auto file_id = file_ids[0]; + auto thumbnail_file_id = thumbnail_file_ids.empty() ? FileId() : thumbnail_file_ids[0]; + td_->create_handler()->send(dialog_id, message_id, media_pos, file_id, thumbnail_file_id, + std::move(input_media)); + } else { + send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id, + dialog_id, message_id, media_pos, Status::OK()); } } } @@ -25353,11 +24510,11 @@ void MessagesManager::on_secret_message_media_uploaded(DialogId dialog_id, const return td_->create_handler()->send(dialog_id, m->message_id, std::move(secret_input_media)); case telegram_api::inputEncryptedFile::ID: return send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id, - dialog_id, m->message_id, Status::OK()); + dialog_id, m->message_id, -1, Status::OK()); default: LOG(ERROR) << "Have wrong secret input media " << to_string(secret_input_media->input_file_); return send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id, - dialog_id, m->message_id, Status::Error(400, "Invalid input media")); + dialog_id, m->message_id, -1, Status::Error(400, "Invalid input media")); } */ // TODO use file_id, thumbnail_file_id, was_uploaded, was_thumbnail_uploaded, @@ -25365,7 +24522,7 @@ void MessagesManager::on_secret_message_media_uploaded(DialogId dialog_id, const send_closure_later(actor_id(this), &MessagesManager::on_media_message_ready_to_send, dialog_id, m->message_id, PromiseCreator::lambda([this, dialog_id, secret_input_media = std::move(secret_input_media)]( Result result) mutable { - if (result.is_error() || G()->close_flag()) { + if (G()->close_flag() || result.is_error()) { return; } @@ -25383,7 +24540,7 @@ void MessagesManager::send_secret_message(DialogId dialog_id, const Message *m, auto text = get_message_content_text(m->content.get()); vector> entities; if (text != nullptr && !text->entities.empty()) { - auto layer = td_->contacts_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); + auto layer = td_->user_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); entities = get_input_secret_message_entities(text->entities, layer); } @@ -25411,15 +24568,15 @@ void MessagesManager::send_secret_message(DialogId dialog_id, const Message *m, send_closure( td_->secret_chats_manager_, &SecretChatsManager::send_message, dialog_id.get_secret_chat_id(), make_tl_object( - flags, false /*ignored*/, random_id, m->ttl, + flags, false /*ignored*/, random_id, m->ttl.get_input_ttl(), m->content->get_type() == MessageContentType::Text ? text->text : string(), std::move(media.decrypted_media_), - std::move(entities), td_->contacts_manager_->get_user_first_username(m->via_bot_user_id), - m->reply_to_random_id, -m->media_album_id), + std::move(entities), td_->user_manager_->get_user_first_username(m->via_bot_user_id), m->reply_to_random_id, + -m->media_album_id), std::move(media.input_file_), Promise()); } -void MessagesManager::on_upload_message_media_success(DialogId dialog_id, MessageId message_id, - tl_object_ptr &&media) { +void MessagesManager::on_upload_message_media_success(DialogId dialog_id, MessageId message_id, int32 media_pos, + telegram_api::object_ptr &&media) { Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); @@ -25431,41 +24588,38 @@ void MessagesManager::on_upload_message_media_success(DialogId dialog_id, Messag // don't need to send error to the user, because the message has already been deleted // and there is nothing to be deleted from the server LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " - << FullMessageId{dialog_id, message_id}; + << MessageFullId{dialog_id, message_id}; return; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return; // the message should be deleted soon } - auto caption = get_message_content_caption(m->content.get()); - auto has_spoiler = get_message_content_has_spoiler(m->content.get()); - auto content = get_message_content(td_, caption == nullptr ? FormattedText() : *caption, std::move(media), dialog_id, - false, UserId(), nullptr, nullptr, "on_upload_message_media_success"); - set_message_content_has_spoiler(content.get(), has_spoiler); - + auto content = get_uploaded_message_content(td_, m->content.get(), media_pos, std::move(media), dialog_id, m->date, + "on_upload_message_media_success"); bool is_content_changed = false; - bool need_update = update_message_content(dialog_id, m, std::move(content), true, true, is_content_changed); - if (need_update) { + bool need_update = + update_message_content(dialog_id, m, std::move(content), media_pos == -1, true, is_content_changed); + if (need_update || media_pos >= 0) { send_update_message_content(d, m, true, "on_upload_message_media_success"); } - if (is_content_changed || need_update) { + if (is_content_changed || need_update || media_pos >= 0) { on_message_changed(d, m, need_update, "on_upload_message_media_success"); } - auto input_media = get_input_media(m->content.get(), td_, m->ttl, m->send_emoji, true); + auto input_media = get_message_content_input_media(m->content.get(), td_, m->ttl, m->send_emoji, true, media_pos); Status result; if (input_media == nullptr) { result = Status::Error(400, "Failed to upload file"); } send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id, dialog_id, - m->message_id, std::move(result)); + m->message_id, media_pos, std::move(result)); } -void MessagesManager::on_upload_message_media_file_part_missing(DialogId dialog_id, MessageId message_id, - int bad_part) { +void MessagesManager::on_upload_message_media_file_parts_missing(DialogId dialog_id, MessageId message_id, + int32 media_pos, vector &&bad_parts) { Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); @@ -25475,20 +24629,21 @@ void MessagesManager::on_upload_message_media_file_part_missing(DialogId dialog_ // don't need to send error to the user, because the message has already been deleted // and there is nothing to be deleted from the server LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " - << FullMessageId{dialog_id, message_id}; + << MessageFullId{dialog_id, message_id}; return; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return; // the message should be deleted soon } CHECK(dialog_id.get_type() != DialogType::SecretChat); - do_send_message(dialog_id, m, {bad_part}); + do_send_message(dialog_id, m, media_pos, std::move(bad_parts)); } -void MessagesManager::on_upload_message_media_fail(DialogId dialog_id, MessageId message_id, Status error) { +void MessagesManager::on_upload_message_media_fail(DialogId dialog_id, MessageId message_id, int32 media_pos, + Status error) { Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); @@ -25498,22 +24653,59 @@ void MessagesManager::on_upload_message_media_fail(DialogId dialog_id, MessageId // don't need to send error to the user, because the message has already been deleted // and there is nothing to be deleted from the server LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " - << FullMessageId{dialog_id, message_id}; + << MessageFullId{dialog_id, message_id}; return; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return; // the message should be deleted soon } CHECK(dialog_id.get_type() != DialogType::SecretChat); send_closure_later(actor_id(this), &MessagesManager::on_upload_message_media_finished, m->media_album_id, dialog_id, - m->message_id, std::move(error)); + m->message_id, media_pos, std::move(error)); } void MessagesManager::on_upload_message_media_finished(int64 media_album_id, DialogId dialog_id, MessageId message_id, - Status result) { + int32 media_pos, Status result) { + if (media_pos >= 0) { + CHECK(media_album_id == 0); + LOG(INFO) << "Finished to upload media " << media_pos << " from " << message_id << " in " << dialog_id; + auto it = pending_paid_media_group_sends_.find({dialog_id, message_id}); + if (it == pending_paid_media_group_sends_.end()) { + LOG(INFO) << "The message doesn't need to be sent"; + // the message may be already sent or failed to be sent + return; + } + auto &request = it->second; + CHECK(static_cast(media_pos) < request.is_finished.size()); + if (request.is_finished[media_pos]) { + LOG(INFO) << "Upload media of " << message_id << " in " << dialog_id << " at pos " << media_pos + << " was already finished"; + return; + } + LOG(INFO) << "Finish to upload media of " << message_id << " in " << dialog_id << " at pos " << media_pos + << " with result " << result << " and previous finished_count = " << request.finished_count; + + request.results[media_pos] = std::move(result); + request.is_finished[media_pos] = true; + request.finished_count++; + + if (request.finished_count == request.results.size() || request.results[media_pos].is_error()) { + on_media_message_ready_to_send(dialog_id, message_id, + PromiseCreator::lambda([this, dialog_id](Result result) mutable { + if (G()->close_flag() || result.is_error()) { + return; + } + + auto m = result.move_as_ok(); + CHECK(m != nullptr); + do_send_paid_media_group(dialog_id, m->message_id); + })); + } + return; + } CHECK(media_album_id < 0); auto it = pending_message_group_sends_.find(media_album_id); if (it == pending_message_group_sends_.end()) { @@ -25546,7 +24738,7 @@ void MessagesManager::on_upload_message_media_finished(int64 media_album_id, Dia request.is_finished[pos] = true; request.finished_count++; - if (request.finished_count == request.message_ids.size() || request.results[pos].is_error()) { + if (request.finished_count == request.results.size() || request.results[pos].is_error()) { // must use send_closure_later if some messages may be being deleted now // but this function is called only through send_closure_later, so there should be no being deleted messages // we must use synchronous calls to keep the correct message order during copying of multiple messages @@ -25555,7 +24747,7 @@ void MessagesManager::on_upload_message_media_finished(int64 media_album_id, Dia for (auto request_message_id : message_ids) { LOG(INFO) << "Send on_media_message_ready_to_send for " << request_message_id << " in " << dialog_id; auto promise = PromiseCreator::lambda([this, media_album_id](Result result) { - if (result.is_error() || G()->close_flag()) { + if (G()->close_flag() || result.is_error()) { return; } @@ -25596,10 +24788,11 @@ void MessagesManager::do_send_message_group(int64 media_album_id) { vector random_ids; vector> input_single_media; tl_object_ptr as_input_peer; - MessageId reply_to_message_id; + const MessageInputReplyTo *input_reply_to = nullptr; MessageId top_thread_message_id; int32 flags = 0; int32 schedule_date = 0; + MessageEffectId effect_id; bool is_copy = false; for (size_t i = 0; i < request.message_ids.size(); i++) { auto *m = get_message(d, request.message_ids[i]); @@ -25609,10 +24802,11 @@ void MessagesManager::do_send_message_group(int64 media_album_id) { continue; } - reply_to_message_id = m->reply_to_message_id; - top_thread_message_id = m->top_thread_message_id; + input_reply_to = get_message_input_reply_to(m); + top_thread_message_id = m->initial_top_thread_message_id; flags = get_message_flags(m); schedule_date = get_message_schedule_date(m); + effect_id = m->effect_id; is_copy = m->is_copy; as_input_peer = get_send_message_as_input_peer(m); @@ -25628,22 +24822,21 @@ void MessagesManager::do_send_message_group(int64 media_album_id) { } const FormattedText *caption = get_message_content_caption(m->content.get()); - auto input_media = get_input_media(m->content.get(), td_, m->ttl, m->send_emoji, true); + auto input_media = get_message_content_input_media(m->content.get(), td_, m->ttl, m->send_emoji, true); if (input_media == nullptr) { // TODO return CHECK auto file_id = get_message_content_any_file_id(m->content.get()); auto file_view = td_->file_manager_->get_file_view(file_id); - bool has_remote = file_view.has_remote_location(); - bool is_web = has_remote ? file_view.remote_location().is_web() : false; + const auto *full_remote_location = file_view.get_full_remote_location(); + bool has_remote = full_remote_location != nullptr; + bool is_web = has_remote ? full_remote_location->is_web() : false; LOG(FATAL) << request.dialog_id << " " << request.finished_count << " " << i << " " << request.message_ids << " " << request.is_finished << " " << request.results << " " << m->ttl << " " << has_remote << " " << file_view.has_alive_remote_location() << " " << file_view.has_active_upload_remote_location() << " " << file_view.has_active_download_remote_location() << " " << file_view.is_encrypted() << " " << is_web - << " " << file_view.has_url() << " " - << to_string(get_message_content_object(m->content.get(), td_, dialog_id, m->date, - m->is_content_secret, false, -1)); + << " " << file_view.has_url() << " " << to_string(get_message_message_content_object(dialog_id, m)); } - auto entities = get_input_message_entities(td_->contacts_manager_.get(), caption, "do_send_message_group"); + auto entities = get_input_message_entities(td_->user_manager_.get(), caption, "do_send_message_group"); int32 input_single_media_flags = 0; if (!entities.empty()) { input_single_media_flags |= telegram_api::inputSingleMedia::ENTITIES_MASK; @@ -25676,11 +24869,74 @@ void MessagesManager::do_send_message_group(int64 media_album_id) { if (input_single_media.empty()) { LOG(INFO) << "Media group " << media_album_id << " from " << dialog_id << " is empty"; } - td_->create_handler()->send(flags, dialog_id, std::move(as_input_peer), reply_to_message_id, - top_thread_message_id, schedule_date, std::move(file_ids), + CHECK(input_reply_to != nullptr); + td_->create_handler()->send(flags, dialog_id, std::move(as_input_peer), *input_reply_to, + top_thread_message_id, schedule_date, effect_id, std::move(file_ids), std::move(input_single_media), is_copy); } +void MessagesManager::do_send_paid_media_group(DialogId dialog_id, MessageId message_id) { + if (G()->close_flag()) { + return; + } + + auto it = pending_paid_media_group_sends_.find({dialog_id, message_id}); + if (it == pending_paid_media_group_sends_.end()) { + // the paid media may be already sent or failed to be sent + return; + } + + auto &request = it->second; + + Dialog *d = get_dialog(dialog_id); + CHECK(d != nullptr); + + auto *m = get_message(d, message_id); + CHECK(m != nullptr); + CHECK(m->content->get_type() == MessageContentType::PaidMedia); + + auto random_id = begin_send_message(dialog_id, m); + + auto status = can_send_message(dialog_id); + bool success = status.is_ok(); + for (auto &result : request.results) { + if (success && result.is_error()) { + status = result.clone(); + success = false; + } + } + for (bool is_finished : request.is_finished) { + if (!is_finished) { + success = false; + } + } + if (!success) { + if (status.is_ok()) { + status = Status::Error(400, "Group send failed"); + } + on_send_message_fail(random_id, std::move(status)); + CHECK(pending_paid_media_group_sends_.count({dialog_id, message_id}) == 0); + return; + } + + auto file_ids = get_message_content_any_file_ids(m->content.get()); + auto thumbnail_file_ids = get_message_content_thumbnail_file_ids(m->content.get(), td_); + auto input_media = get_message_content_input_media(m->content.get(), td_, m->ttl, m->send_emoji, true); + CHECK(input_media != nullptr); + pending_paid_media_group_sends_.erase(it); + + LOG(INFO) << "Begin to send paid media group " << message_id << " to " << dialog_id; + + const FormattedText *caption = get_message_content_caption(m->content.get()); + td_->create_handler()->send( + std::move(file_ids), std::move(thumbnail_file_ids), get_message_flags(m), dialog_id, + get_send_message_as_input_peer(m), *get_message_input_reply_to(m), m->initial_top_thread_message_id, + get_message_schedule_date(m), m->effect_id, get_input_reply_markup(td_->user_manager_.get(), m->reply_markup), + get_input_message_entities(td_->user_manager_.get(), caption, "do_send_paid_media_group"), + caption == nullptr ? "" : caption->text, std::move(input_media), m->content->get_type(), m->is_copy, random_id, + &m->send_query_ref); +} + void MessagesManager::on_text_message_ready_to_send(DialogId dialog_id, MessageId message_id) { if (G()->close_flag()) { return; @@ -25700,19 +24956,30 @@ void MessagesManager::on_text_message_ready_to_send(DialogId dialog_id, MessageI if (dialog_id.get_type() == DialogType::SecretChat) { CHECK(!message_id.is_scheduled()); - auto layer = td_->contacts_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); - send_secret_message(dialog_id, m, get_secret_input_media(content, td_, nullptr, BufferSlice(), layer)); + auto layer = td_->user_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()); + send_secret_message(dialog_id, m, + get_message_content_secret_input_media(content, td_, nullptr, BufferSlice(), layer)); } else { const FormattedText *message_text = get_message_content_text(content); CHECK(message_text != nullptr); - int64 random_id = begin_send_message(dialog_id, m); - td_->create_handler()->send( - get_message_flags(m), dialog_id, get_send_message_as_input_peer(m), m->reply_to_message_id, - m->top_thread_message_id, get_message_schedule_date(m), - get_input_reply_markup(td_->contacts_manager_.get(), m->reply_markup), - get_input_message_entities(td_->contacts_manager_.get(), message_text->entities, "do_send_message"), - message_text->text, m->is_copy, random_id, &m->send_query_ref); + auto input_media = get_message_content_input_media_web_page(td_, content); + if (input_media == nullptr) { + td_->create_handler()->send( + get_message_flags(m), dialog_id, get_send_message_as_input_peer(m), *get_message_input_reply_to(m), + m->initial_top_thread_message_id, get_message_schedule_date(m), m->effect_id, + get_input_reply_markup(td_->user_manager_.get(), m->reply_markup), + get_input_message_entities(td_->user_manager_.get(), message_text, "on_text_message_ready_to_send"), + message_text->text, m->is_copy, random_id, &m->send_query_ref); + } else { + td_->create_handler()->send( + {}, {}, get_message_flags(m), dialog_id, get_send_message_as_input_peer(m), *get_message_input_reply_to(m), + m->initial_top_thread_message_id, get_message_schedule_date(m), m->effect_id, + get_input_reply_markup(td_->user_manager_.get(), m->reply_markup), + get_input_message_entities(td_->user_manager_.get(), message_text, "on_text_message_ready_to_send"), + message_text->text, std::move(input_media), MessageContentType::Text, m->is_copy, random_id, + &m->send_query_ref); + } } } @@ -25746,8 +25013,7 @@ void MessagesManager::on_media_message_ready_to_send(DialogId dialog_id, Message return; } if (it->second) { - promise.set_error(Status::Error(500, "Duplicate promise")); - return; + return promise.set_error(Status::Error(500, "Duplicate promise")); } it->second = std::move(promise); @@ -25779,7 +25045,7 @@ void MessagesManager::on_yet_unsent_media_queue_updated(DialogId dialog_id) { // don't use it/queue/first_it after promise is called if (m != nullptr) { - LOG(INFO) << "Can send " << FullMessageId{dialog_id, m->message_id}; + LOG(INFO) << "Can send " << MessageFullId{dialog_id, m->message_id}; promise.set_value(std::move(m)); } else { promise.set_error(Status::Error(400, "Message not found")); @@ -25789,10 +25055,9 @@ void MessagesManager::on_yet_unsent_media_queue_updated(DialogId dialog_id) { Result MessagesManager::send_bot_start_message(UserId bot_user_id, DialogId dialog_id, const string ¶meter) { - LOG(INFO) << "Begin to send bot start message to " << dialog_id; CHECK(!td_->auth_manager_->is_bot()); - TRY_RESULT(bot_data, td_->contacts_manager_->get_bot_data(bot_user_id)); + TRY_RESULT(bot_data, td_->user_manager_->get_bot_data(bot_user_id)); Dialog *d = get_dialog_force(dialog_id, "send_bot_start_message"); if (d == nullptr) { @@ -25813,10 +25078,10 @@ Result MessagesManager::send_bot_start_message(UserId bot_user_id, Di } auto chat_id = dialog_id.get_chat_id(); - if (!td_->contacts_manager_->have_input_peer_chat(chat_id, AccessRights::Write)) { + if (!td_->chat_manager_->have_input_peer_chat(chat_id, AccessRights::Write)) { return Status::Error(400, "Can't access the chat"); } - auto status = td_->contacts_manager_->get_chat_permissions(chat_id); + auto status = td_->chat_manager_->get_chat_permissions(chat_id); if (!status.can_invite_users()) { return Status::Error(400, "Need administrator rights to invite a bot to the group chat"); } @@ -25824,10 +25089,10 @@ Result MessagesManager::send_bot_start_message(UserId bot_user_id, Di } case DialogType::Channel: { auto channel_id = dialog_id.get_channel_id(); - if (!td_->contacts_manager_->have_input_peer_channel(channel_id, AccessRights::Write)) { + if (!td_->chat_manager_->have_input_peer_channel(channel_id, AccessRights::Write)) { return Status::Error(400, "Can't access the chat"); } - switch (td_->contacts_manager_->get_channel_type(channel_id)) { + switch (td_->chat_manager_->get_channel_type(channel_id)) { case ChannelType::Megagroup: if (!bot_data.can_join_groups) { return Status::Error(400, "The bot can't join groups"); @@ -25839,7 +25104,7 @@ Result MessagesManager::send_bot_start_message(UserId bot_user_id, Di default: UNREACHABLE(); } - auto status = td_->contacts_manager_->get_channel_permissions(channel_id); + auto status = td_->chat_manager_->get_channel_permissions(channel_id); if (!status.can_invite_users()) { return Status::Error(400, "Need administrator rights to invite a bot to the supergroup chat"); } @@ -25860,9 +25125,10 @@ Result MessagesManager::send_bot_start_message(UserId bot_user_id, Di vector text_entities; text_entities.emplace_back(MessageEntity::Type::BotCommand, 0, narrow_cast(text.size())); bool need_update_dialog_pos = false; - Message *m = get_message_to_send(d, MessageId(), MessageId(), MessageSendOptions(), - create_text_message_content(text, std::move(text_entities), WebPageId()), - &need_update_dialog_pos); + Message *m = get_message_to_send( + d, MessageId(), MessageInputReplyTo(), MessageSendOptions(), + create_text_message_content(text, std::move(text_entities), WebPageId(), false, false, false, string()), false, + &need_update_dialog_pos); m->is_bot_start_message = true; send_update_new_message(d, m); @@ -25913,7 +25179,7 @@ void MessagesManager::save_send_bot_start_message_log_event(UserId bot_user_id, } CHECK(m != nullptr); - LOG(INFO) << "Save " << FullMessageId(dialog_id, m->message_id) << " to binlog"; + LOG(INFO) << "Save " << MessageFullId(dialog_id, m->message_id) << " to binlog"; SendBotStartMessageLogEvent log_event; log_event.bot_user_id = bot_user_id; log_event.dialog_id = dialog_id; @@ -25930,7 +25196,7 @@ void MessagesManager::do_send_bot_start_message(UserId bot_user_id, DialogId dia return; } - LOG(INFO) << "Do send bot start " << FullMessageId(dialog_id, message_id) << " to bot " << bot_user_id; + LOG(INFO) << "Do send bot start " << MessageFullId(dialog_id, message_id) << " to bot " << bot_user_id; auto m = get_message({dialog_id, message_id}); if (m == nullptr) { @@ -25938,13 +25204,13 @@ void MessagesManager::do_send_bot_start_message(UserId bot_user_id, DialogId dia } int64 random_id = begin_send_message(dialog_id, m); - telegram_api::object_ptr input_peer = dialog_id.get_type() == DialogType::User - ? make_tl_object() - : get_input_peer(dialog_id, AccessRights::Write); + telegram_api::object_ptr input_peer = + dialog_id.get_type() == DialogType::User ? make_tl_object() + : td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { return on_send_message_fail(random_id, Status::Error(400, "Chat is not accessible")); } - auto r_bot_input_user = td_->contacts_manager_->get_input_user(bot_user_id); + auto r_bot_input_user = td_->user_manager_->get_input_user(bot_user_id); if (r_bot_input_user.is_error()) { return on_send_message_fail(random_id, r_bot_input_user.move_as_error()); } @@ -25953,20 +25219,17 @@ void MessagesManager::do_send_bot_start_message(UserId bot_user_id, DialogId dia std::move(input_peer), parameter, random_id); } -Result MessagesManager::send_inline_query_result_message(DialogId dialog_id, MessageId top_thread_message_id, - MessageId reply_to_message_id, - tl_object_ptr &&options, - int64 query_id, const string &result_id, - bool hide_via_bot) { - LOG(INFO) << "Begin to send inline query result message to " << dialog_id << " in reply to " << reply_to_message_id; - +Result> MessagesManager::send_inline_query_result_message( + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr &&reply_to, tl_object_ptr &&options, + int64 query_id, const string &result_id, bool hide_via_bot) { Dialog *d = get_dialog_force(dialog_id, "send_inline_query_result_message"); if (d == nullptr) { return Status::Error(400, "Chat not found"); } TRY_STATUS(can_send_message(dialog_id)); - TRY_RESULT(message_send_options, process_message_send_options(dialog_id, std::move(options), false)); + TRY_RESULT(message_send_options, process_message_send_options(dialog_id, std::move(options), false, false)); bool to_secret = false; switch (dialog_id.get_type()) { case DialogType::User: @@ -25974,7 +25237,7 @@ Result MessagesManager::send_inline_query_result_message(DialogId dia // ok break; case DialogType::Channel: { - auto channel_status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()); + auto channel_status = td_->chat_manager_->get_channel_permissions(dialog_id.get_channel_id()); if (!channel_status.can_use_inline_bots()) { return Status::Error(400, "Can't use inline bots in the chat"); } @@ -25994,16 +25257,27 @@ Result MessagesManager::send_inline_query_result_message(DialogId dia return Status::Error(400, "Inline query result not found"); } - reply_to_message_id = get_reply_to_message_id(d, top_thread_message_id, reply_to_message_id, false); - TRY_STATUS(can_use_message_send_options(message_send_options, content->message_content, 0)); - TRY_STATUS(can_send_message_content(dialog_id, content->message_content.get(), false, td_)); - TRY_STATUS(can_use_top_thread_message_id(d, top_thread_message_id, reply_to_message_id)); + auto input_reply_to = create_message_input_reply_to(d, top_thread_message_id, std::move(reply_to), false); + TRY_STATUS(can_use_message_send_options(message_send_options, content->message_content, MessageSelfDestructType())); + TRY_STATUS(can_send_message_content(dialog_id, content->message_content.get(), false, true, td_)); + TRY_STATUS(can_use_top_thread_message_id(d, top_thread_message_id, input_reply_to)); + auto message_content = dup_message_content(td_, dialog_id, content->message_content.get(), + MessageContentDupType::SendViaBot, MessageCopyOptions()); bool need_update_dialog_pos = false; - Message *m = get_message_to_send(d, top_thread_message_id, reply_to_message_id, message_send_options, - dup_message_content(td_, dialog_id, content->message_content.get(), - MessageContentDupType::SendViaBot, MessageCopyOptions()), - &need_update_dialog_pos, false, nullptr, true); + unique_ptr message; + Message *m; + if (message_send_options.only_preview) { + message = create_message_to_send(d, top_thread_message_id, std::move(input_reply_to), message_send_options, + std::move(message_content), content->invert_media, false, nullptr, DialogId(), + true, DialogId()); + m = message.get(); + } else { + m = get_message_to_send(d, top_thread_message_id, std::move(input_reply_to), message_send_options, + std::move(message_content), content->invert_media, &need_update_dialog_pos, false, nullptr, + DialogId(), true); + } + m->hide_via_bot = hide_via_bot; if (!hide_via_bot) { m->via_bot_user_id = td_->inline_queries_manager_->get_inline_bot_user_id(query_id); @@ -26014,14 +25288,12 @@ Result MessagesManager::send_inline_query_result_message(DialogId dia m->disable_web_page_preview = content->disable_web_page_preview; m->clear_draft = !hide_via_bot; - if (m->clear_draft) { - if (top_thread_message_id.is_valid()) { - set_dialog_draft_message(dialog_id, top_thread_message_id, nullptr).ignore(); - } else { - update_dialog_draft_message(d, nullptr, false, !need_update_dialog_pos); - } + if (message_send_options.only_preview) { + return get_message_object(dialog_id, m, "send_inline_query_result_message"); } + clear_dialog_draft_by_sent_message(d, m, !need_update_dialog_pos); + send_update_new_message(d, m); if (need_update_dialog_pos) { send_update_chat_last_message(d, "send_inline_query_result_message"); @@ -26030,13 +25302,12 @@ Result MessagesManager::send_inline_query_result_message(DialogId dia if (to_secret) { save_send_message_log_event(dialog_id, m); do_send_message(dialog_id, m); - return m->message_id; + } else { + save_send_inline_query_result_message_log_event(dialog_id, m, query_id, result_id); + send_closure_later(actor_id(this), &MessagesManager::do_send_inline_query_result_message, dialog_id, m->message_id, + query_id, result_id); } - - save_send_inline_query_result_message_log_event(dialog_id, m, query_id, result_id); - send_closure_later(actor_id(this), &MessagesManager::do_send_inline_query_result_message, dialog_id, m->message_id, - query_id, result_id); - return m->message_id; + return get_message_object(dialog_id, m, "send_inline_query_result_message"); } class MessagesManager::SendInlineQueryResultMessageLogEvent { @@ -26071,7 +25342,7 @@ void MessagesManager::save_send_inline_query_result_message_log_event(DialogId d } CHECK(m != nullptr); - LOG(INFO) << "Save " << FullMessageId(dialog_id, m->message_id) << " to binlog"; + LOG(INFO) << "Save " << MessageFullId(dialog_id, m->message_id) << " to binlog"; SendInlineQueryResultMessageLogEvent log_event; log_event.dialog_id = dialog_id; log_event.query_id = query_id; @@ -26088,7 +25359,7 @@ void MessagesManager::do_send_inline_query_result_message(DialogId dialog_id, Me return; } - LOG(INFO) << "Do send inline query result " << FullMessageId(dialog_id, message_id); + LOG(INFO) << "Do send inline query result " << MessageFullId(dialog_id, message_id); auto m = get_message({dialog_id, message_id}); if (m == nullptr) { @@ -26101,23 +25372,8 @@ void MessagesManager::do_send_inline_query_result_message(DialogId dialog_id, Me flags |= telegram_api::messages_sendInlineBotResult::HIDE_VIA_MASK; } m->send_query_ref = td_->create_handler()->send( - flags, dialog_id, get_send_message_as_input_peer(m), m->reply_to_message_id, m->top_thread_message_id, - get_message_schedule_date(m), random_id, query_id, result_id); -} - -bool MessagesManager::has_qts_messages(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::Chat: - return td_->option_manager_->get_option_integer("session_count") > 1; - case DialogType::Channel: - case DialogType::SecretChat: - return false; - case DialogType::None: - default: - UNREACHABLE(); - return false; - } + flags, dialog_id, get_send_message_as_input_peer(m), *get_message_input_reply_to(m), + m->initial_top_thread_message_id, get_message_schedule_date(m), random_id, query_id, result_id); } bool MessagesManager::can_edit_message(DialogId dialog_id, const Message *m, bool is_editing, @@ -26142,8 +25398,9 @@ bool MessagesManager::can_edit_message(DialogId dialog_id, const Message *m, boo return false; } - auto my_id = td_->contacts_manager_->get_my_id(); - if (m->via_bot_user_id.is_valid() && (m->via_bot_user_id != my_id || m->message_id.is_scheduled())) { + auto my_id = td_->user_manager_->get_my_id(); + bool is_inline_message = m->via_bot_user_id.is_valid(); + if (is_inline_message && (m->via_bot_user_id != my_id || m->message_id.is_scheduled())) { return false; } @@ -26155,23 +25412,23 @@ bool MessagesManager::can_edit_message(DialogId dialog_id, const Message *m, boo content_type != MessageContentType::LiveLocation && !m->message_id.is_scheduled(); switch (dialog_id.get_type()) { case DialogType::User: - if (!m->is_outgoing && dialog_id != my_dialog_id && !m->via_bot_user_id.is_valid()) { + if (!m->is_outgoing && dialog_id != my_dialog_id && !is_inline_message) { return false; } break; case DialogType::Chat: - if (!m->is_outgoing && !m->via_bot_user_id.is_valid()) { + if (!m->is_outgoing && !is_inline_message) { return false; } break; case DialogType::Channel: { - if (m->via_bot_user_id.is_valid()) { + if (is_inline_message) { // outgoing via_bot messages can always be edited break; } auto channel_id = dialog_id.get_channel_id(); - auto channel_status = td_->contacts_manager_->get_channel_permissions(channel_id); + auto channel_status = td_->chat_manager_->get_channel_permissions(channel_id); if (m->is_channel_post) { if (m->message_id.is_scheduled()) { if (!channel_status.can_post_messages()) { @@ -26209,97 +25466,51 @@ bool MessagesManager::can_edit_message(DialogId dialog_id, const Message *m, boo if (has_edit_time_limit) { const int32 DEFAULT_EDIT_TIME_LIMIT = 2 * 86400; int64 edit_time_limit = td_->option_manager_->get_option_integer("edit_time_limit", DEFAULT_EDIT_TIME_LIMIT); - if (G()->unix_time_cached() - m->date - (is_editing ? 300 : 0) >= edit_time_limit) { + if (G()->unix_time() - m->date - (is_editing ? 300 : 0) >= edit_time_limit) { return false; } } + if (is_editable_message_content(content_type)) { + return true; + } + if (is_bot && only_reply_markup && !is_service_message_content(content_type) && + !is_expired_message_content(content_type)) { + return true; + } switch (content_type) { - case MessageContentType::Animation: - case MessageContentType::Audio: - case MessageContentType::Document: - case MessageContentType::Game: - case MessageContentType::Photo: - case MessageContentType::Text: - case MessageContentType::Video: - case MessageContentType::VoiceNote: - return true; - case MessageContentType::LiveLocation: { - if (is_bot && only_reply_markup) { - // there is no caption to edit, but bot can edit inline reply_markup - return true; - } - return G()->unix_time_cached() - m->date < get_message_content_live_location_period(m->content.get()); - } - case MessageContentType::Poll: { - if (is_bot && only_reply_markup) { - // there is no caption to edit, but bot can edit inline reply_markup - return true; - } - if (m->message_id.is_scheduled()) { - return false; - } - return !get_message_content_poll_is_closed(td_, m->content.get()); - } - case MessageContentType::Contact: - case MessageContentType::Dice: - case MessageContentType::Location: - case MessageContentType::Sticker: - case MessageContentType::Venue: - case MessageContentType::VideoNote: - // there is no caption to edit, but bot can edit inline reply_markup - return is_bot && only_reply_markup; - case MessageContentType::Invoice: - case MessageContentType::Unsupported: - case MessageContentType::ChatCreate: - case MessageContentType::ChatChangeTitle: - case MessageContentType::ChatChangePhoto: - case MessageContentType::ChatDeletePhoto: - case MessageContentType::ChatDeleteHistory: - case MessageContentType::ChatAddUsers: - case MessageContentType::ChatJoinedByLink: - case MessageContentType::ChatDeleteUser: - case MessageContentType::ChatMigrateTo: - case MessageContentType::ChannelCreate: - case MessageContentType::ChannelMigrateFrom: - case MessageContentType::PinMessage: - case MessageContentType::GameScore: - case MessageContentType::ScreenshotTaken: - case MessageContentType::ChatSetTtl: - case MessageContentType::Call: - case MessageContentType::PaymentSuccessful: - case MessageContentType::ContactRegistered: - case MessageContentType::ExpiredPhoto: - case MessageContentType::ExpiredVideo: - case MessageContentType::CustomServiceAction: - case MessageContentType::WebsiteConnected: - case MessageContentType::PassportDataSent: - case MessageContentType::PassportDataReceived: - case MessageContentType::ProximityAlertTriggered: - case MessageContentType::GroupCall: - case MessageContentType::InviteToGroupCall: - case MessageContentType::ChatSetTheme: - case MessageContentType::WebViewDataSent: - case MessageContentType::WebViewDataReceived: - case MessageContentType::GiftPremium: - case MessageContentType::TopicCreate: - case MessageContentType::TopicEdit: - case MessageContentType::SuggestProfilePhoto: - case MessageContentType::WriteAccessAllowed: - case MessageContentType::RequestedDialog: - case MessageContentType::WebViewWriteAccessAllowed: - case MessageContentType::SetBackground: - return false; + case MessageContentType::LiveLocation: + // live location can be edited only during the period + return G()->unix_time() - m->date < get_message_content_live_location_period(m->content.get()); + case MessageContentType::Poll: + // non-closed non-scheduled polls can be closed + return !m->message_id.is_scheduled() && !get_message_content_poll_is_closed(td_, m->content.get()); default: - UNREACHABLE(); + return false; } +} - return false; +Status MessagesManager::can_pin_message(DialogId dialog_id, const Message *m) const { + if (m == nullptr) { + return Status::Error(400, "Message not found"); + } + TRY_STATUS(td_->dialog_manager_->can_pin_messages(dialog_id)); + if (m->message_id.is_scheduled()) { + return Status::Error(400, "Scheduled message can't be pinned"); + } + if (!m->message_id.is_server()) { + return Status::Error(400, "Message can't be pinned"); + } + if (is_service_message_content(m->content->get_type())) { + return Status::Error(400, "Service messages can't be pinned"); + } + return Status::OK(); } bool MessagesManager::can_resend_message(const Message *m) const { if (m->send_error_code != 429 && m->send_error_message != "Message is too old to be re-sent automatically" && - m->send_error_message != "SCHEDULE_TOO_MUCH" && m->send_error_message != "SEND_AS_PEER_INVALID") { + m->send_error_message != "SCHEDULE_TOO_MUCH" && m->send_error_message != "SEND_AS_PEER_INVALID" && + m->send_error_message != "QUOTE_TEXT_INVALID" && m->send_error_message != "REPLY_MESSAGE_ID_INVALID") { return false; } if (m->is_bot_start_message) { @@ -26312,7 +25523,7 @@ bool MessagesManager::can_resend_message(const Message *m) const { auto content_type = m->content->get_type(); if (m->via_bot_user_id.is_valid() || m->hide_via_bot) { // via bot message - if (!can_have_input_media(td_, m->content.get(), false)) { + if (!can_message_content_have_input_media(td_, m->content.get(), false)) { return false; } @@ -26327,30 +25538,6 @@ bool MessagesManager::can_resend_message(const Message *m) const { return true; } -bool MessagesManager::is_group_dialog(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::Chat: - return true; - case DialogType::Channel: - return td_->contacts_manager_->is_megagroup_channel(dialog_id.get_channel_id()); - default: - return false; - } -} - -bool MessagesManager::is_forum_channel(DialogId dialog_id) const { - return dialog_id.get_type() == DialogType::Channel && - td_->contacts_manager_->is_forum_channel(dialog_id.get_channel_id()); -} - -bool MessagesManager::is_broadcast_channel(DialogId dialog_id) const { - if (dialog_id.get_type() != DialogType::Channel) { - return false; - } - - return td_->contacts_manager_->is_broadcast_channel(dialog_id.get_channel_id()); -} - bool MessagesManager::is_deleted_secret_chat(DialogId dialog_id) const { return is_deleted_secret_chat(get_dialog(dialog_id)); } @@ -26367,7 +25554,7 @@ bool MessagesManager::is_deleted_secret_chat(const Dialog *d) const { return false; } - auto state = td_->contacts_manager_->get_secret_chat_state(d->dialog_id.get_secret_chat_id()); + auto state = td_->user_manager_->get_secret_chat_state(d->dialog_id.get_secret_chat_id()); if (state != SecretChatState::Closed) { return false; } @@ -26386,17 +25573,21 @@ int32 MessagesManager::get_message_schedule_date(const Message *m) { return m->date; } +int32 MessagesManager::get_message_original_date(const Message *m) { + CHECK(m != nullptr); + if (m->forward_info != nullptr) { + return m->forward_info->get_origin_date(); + } + return m->date; +} + DialogId MessagesManager::get_message_original_sender(const Message *m) { CHECK(m != nullptr); if (m->forward_info != nullptr) { - auto forward_info = m->forward_info.get(); - if (forward_info->is_imported || is_forward_info_sender_hidden(forward_info)) { + if (m->forward_info->is_imported()) { return DialogId(); } - if (forward_info->message_id.is_valid() || forward_info->sender_dialog_id.is_valid()) { - return forward_info->sender_dialog_id; - } - return DialogId(forward_info->sender_user_id); + return m->forward_info->get_origin().get_sender(); } return get_message_sender(m); } @@ -26406,7 +25597,7 @@ DialogId MessagesManager::get_message_sender(const Message *m) { return m->sender_dialog_id.is_valid() ? m->sender_dialog_id : DialogId(m->sender_user_id); } -void MessagesManager::edit_message_text(FullMessageId full_message_id, +void MessagesManager::edit_message_text(MessageFullId message_full_id, tl_object_ptr &&reply_markup, tl_object_ptr &&input_message_content, Promise &&promise) { @@ -26418,22 +25609,13 @@ void MessagesManager::edit_message_text(FullMessageId full_message_id, return promise.set_error(Status::Error(400, "Input message content type must be InputMessageText")); } - LOG(INFO) << "Begin to edit text of " << full_message_id; - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "edit_message_text"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Edit, "edit_message_text")); - if (!have_input_peer(dialog_id, AccessRights::Edit)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - - const Message *m = get_message_force(d, full_message_id.get_message_id(), "edit_message_text"); + const Message *m = get_message_force(d, message_full_id.get_message_id(), "edit_message_text"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!can_edit_message(dialog_id, m, true)) { return promise.set_error(Status::Error(400, "Message can't be edited")); } @@ -26443,51 +25625,38 @@ void MessagesManager::edit_message_text(FullMessageId full_message_id, return promise.set_error(Status::Error(400, "There is no text in the message to edit")); } - auto r_input_message_text = - process_input_message_text(td_, dialog_id, std::move(input_message_content), td_->auth_manager_->is_bot()); - if (r_input_message_text.is_error()) { - return promise.set_error(r_input_message_text.move_as_error()); - } - InputMessageText input_message_text = r_input_message_text.move_as_ok(); - - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, - has_message_sender_user_id(dialog_id, m)); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok()); + TRY_RESULT_PROMISE( + promise, input_message_text, + process_input_message_text(td_, dialog_id, std::move(input_message_content), td_->auth_manager_->is_bot())); + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, + has_message_sender_user_id(dialog_id, m))); + auto input_reply_markup = get_input_reply_markup(td_->user_manager_.get(), new_reply_markup); int32 flags = 0; if (input_message_text.disable_web_page_preview) { flags |= SEND_MESSAGE_FLAG_DISABLE_WEB_PAGE_PREVIEW; } td_->create_handler(std::move(promise)) - ->send(flags, dialog_id, m->message_id, input_message_text.text.text, - get_input_message_entities(td_->contacts_manager_.get(), input_message_text.text.entities, - "edit_message_text"), - nullptr, std::move(input_reply_markup), get_message_schedule_date(m)); + ->send( + flags, dialog_id, m->message_id, input_message_text.text.text, + get_input_message_entities(td_->user_manager_.get(), input_message_text.text.entities, "edit_message_text"), + input_message_text.get_input_media_web_page(), input_message_text.show_above_text, + std::move(input_reply_markup), get_message_schedule_date(m)); } -void MessagesManager::edit_message_live_location(FullMessageId full_message_id, +void MessagesManager::edit_message_live_location(MessageFullId message_full_id, tl_object_ptr &&reply_markup, - tl_object_ptr &&input_location, int32 heading, - int32 proximity_alert_radius, Promise &&promise) { - LOG(INFO) << "Begin to edit live location of " << full_message_id; - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "edit_message_live_location"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } + tl_object_ptr &&input_location, int32 live_period, + int32 heading, int32 proximity_alert_radius, Promise &&promise) { + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, true, AccessRights::Edit, "edit_message_live_location")); - if (!have_input_peer(dialog_id, AccessRights::Edit)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - - const Message *m = get_message_force(d, full_message_id.get_message_id(), "edit_message_live_location"); + const Message *m = get_message_force(d, message_full_id.get_message_id(), "edit_message_live_location"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!can_edit_message(dialog_id, m, true)) { return promise.set_error(Status::Error(400, "Message can't be edited")); } @@ -26497,7 +25666,7 @@ void MessagesManager::edit_message_live_location(FullMessageId full_message_id, return promise.set_error(Status::Error(400, "There is no live location in the message to edit")); } if (m->message_id.is_scheduled()) { - LOG(ERROR) << "Have " << full_message_id << " with live location"; + LOG(ERROR) << "Have " << message_full_id << " with live location"; return promise.set_error(Status::Error(400, "Can't edit live location in scheduled message")); } @@ -26506,26 +25675,27 @@ void MessagesManager::edit_message_live_location(FullMessageId full_message_id, return promise.set_error(Status::Error(400, "Invalid location specified")); } - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, - has_message_sender_user_id(dialog_id, m)); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok()); + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, + has_message_sender_user_id(dialog_id, m))); + auto input_reply_markup = get_input_reply_markup(td_->user_manager_.get(), new_reply_markup); int32 flags = 0; if (location.empty()) { flags |= telegram_api::inputMediaGeoLive::STOPPED_MASK; } + if (live_period != 0) { + flags |= telegram_api::inputMediaGeoLive::PERIOD_MASK; + } if (heading != 0) { flags |= telegram_api::inputMediaGeoLive::HEADING_MASK; } flags |= telegram_api::inputMediaGeoLive::PROXIMITY_NOTIFICATION_RADIUS_MASK; auto input_media = telegram_api::make_object( - flags, false /*ignored*/, location.get_input_geo_point(), heading, 0, proximity_alert_radius); + flags, false /*ignored*/, location.get_input_geo_point(), heading, live_period, proximity_alert_radius); td_->create_handler(std::move(promise)) ->send(0, dialog_id, m->message_id, string(), vector>(), - std::move(input_media), std::move(input_reply_markup), get_message_schedule_date(m)); + std::move(input_media), false /*ignored*/, std::move(input_reply_markup), get_message_schedule_date(m)); } void MessagesManager::cancel_edit_message_media(DialogId dialog_id, Message *m, Slice error_message) { @@ -26536,6 +25706,7 @@ void MessagesManager::cancel_edit_message_media(DialogId dialog_id, Message *m, cancel_upload_message_content_files(m->edited_content.get()); m->edited_content = nullptr; + m->edited_invert_media = false; m->edited_reply_markup = nullptr; m->edit_generation = 0; m->edit_promise.set_error(Status::Error(400, error_message)); @@ -26547,12 +25718,21 @@ void MessagesManager::on_message_media_edited(DialogId dialog_id, MessageId mess Result &&result) { // must not run getDifference + if (was_thumbnail_uploaded) { + CHECK(thumbnail_file_id.is_valid()); + // always delete partial remote location for the thumbnail, because it can't be reused anyway + td_->file_manager_->delete_partial_remote_location(thumbnail_file_id); + } + CHECK(message_id.is_any_server()); Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); auto m = get_message(d, message_id); if (m == nullptr || m->edit_generation != generation) { // message is already deleted or was edited again + if (was_uploaded) { + cancel_upload_file(file_id, "on_message_media_edited"); + } return; } @@ -26589,20 +25769,18 @@ void MessagesManager::on_message_media_edited(DialogId dialog_id, MessageId mess td_->file_manager_->delete_partial_remote_location(thumbnail_file_id); } CHECK(file_id.is_valid()); - auto error_message = result.error().message(); - if (begins_with(error_message, "FILE_PART_") && ends_with(error_message, "_MISSING")) { - do_send_message(dialog_id, m, {to_integer(error_message.substr(10))}); + auto bad_parts = FileManager::get_missing_file_parts(result.error()); + if (!bad_parts.empty()) { + do_send_message(dialog_id, m, -1, std::move(bad_parts)); return; } - if (result.error().code() != 429 && result.error().code() < 500 && !G()->close_flag()) { - td_->file_manager_->delete_partial_remote_location(file_id); - } + td_->file_manager_->delete_partial_remote_location_if_needed(file_id, result.error()); } else if (!td_->auth_manager_->is_bot() && FileReferenceManager::is_file_reference_error(result.error())) { if (file_id.is_valid()) { VLOG(file_references) << "Receive " << result.error() << " for " << file_id; td_->file_manager_->delete_file_reference(file_id, file_reference); - do_send_message(dialog_id, m, {-1}); + do_send_message(dialog_id, m, -1, {-1}); return; } else { LOG(ERROR) << "Receive file reference error, but have no file_id"; @@ -26615,11 +25793,15 @@ void MessagesManager::on_message_media_edited(DialogId dialog_id, MessageId mess get_message_from_server({dialog_id, m->message_id}, Auto(), "on_message_media_edited"); } } + if (was_uploaded) { + cancel_upload_file(file_id, "on_message_media_edited"); + } if (m->edited_schedule_date == schedule_date) { m->edited_schedule_date = 0; } m->edited_content = nullptr; + m->edited_invert_media = false; m->edited_reply_markup = nullptr; m->edit_generation = 0; if (result.is_ok()) { @@ -26629,7 +25811,7 @@ void MessagesManager::on_message_media_edited(DialogId dialog_id, MessageId mess } } -void MessagesManager::edit_message_media(FullMessageId full_message_id, +void MessagesManager::edit_message_media(MessageFullId message_full_id, tl_object_ptr &&reply_markup, tl_object_ptr &&input_message_content, Promise &&promise) { @@ -26645,22 +25827,13 @@ void MessagesManager::edit_message_media(FullMessageId full_message_id, return promise.set_error(Status::Error(400, "Unsupported input message content type")); } - LOG(INFO) << "Begin to edit media of " << full_message_id; - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "edit_message_media"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Edit)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Edit, "edit_message_media")); - Message *m = get_message_force(d, full_message_id.get_message_id(), "edit_message_media"); + Message *m = get_message_force(d, message_full_id.get_message_id(), "edit_message_media"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!can_edit_message(dialog_id, m, true)) { return promise.set_error(Status::Error(400, "Message can't be edited")); } @@ -26673,16 +25846,12 @@ void MessagesManager::edit_message_media(FullMessageId full_message_id, old_message_content_type != MessageContentType::Photo && old_message_content_type != MessageContentType::Video) { return promise.set_error(Status::Error(400, "There is no media in the message to edit")); } - if (m->ttl > 0) { + if (!m->ttl.is_empty()) { return promise.set_error(Status::Error(400, "Can't edit media in self-destructing message")); } - auto r_input_message_content = process_input_message_content(dialog_id, std::move(input_message_content)); - if (r_input_message_content.is_error()) { - return promise.set_error(r_input_message_content.move_as_error()); - } - InputMessageContent content = r_input_message_content.move_as_ok(); - if (content.ttl > 0) { + TRY_RESULT_PROMISE(promise, content, process_input_message_content(dialog_id, std::move(input_message_content))); + if (!content.ttl.is_empty()) { return promise.set_error(Status::Error(400, "Can't enable self-destruction for media")); } @@ -26699,45 +25868,34 @@ void MessagesManager::edit_message_media(FullMessageId full_message_id, } } - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, - has_message_sender_user_id(dialog_id, m)); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, + has_message_sender_user_id(dialog_id, m))); cancel_edit_message_media(dialog_id, m, "Canceled by new editMessageMedia request"); m->edited_content = dup_message_content(td_, dialog_id, content.content.get(), MessageContentDupType::Send, MessageCopyOptions()); CHECK(m->edited_content != nullptr); - m->edited_reply_markup = r_new_reply_markup.move_as_ok(); + m->edited_invert_media = content.invert_media; + m->edited_reply_markup = std::move(new_reply_markup); m->edit_generation = ++current_message_edit_generation_; m->edit_promise = std::move(promise); do_send_message(dialog_id, m); } -void MessagesManager::edit_message_caption(FullMessageId full_message_id, +void MessagesManager::edit_message_caption(MessageFullId message_full_id, tl_object_ptr &&reply_markup, - tl_object_ptr &&input_caption, + tl_object_ptr &&input_caption, bool invert_media, Promise &&promise) { - LOG(INFO) << "Begin to edit caption of " << full_message_id; - - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "edit_message_caption"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Edit)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Edit, "edit_message_caption")); - const Message *m = get_message_force(d, full_message_id.get_message_id(), "edit_message_caption"); + const Message *m = get_message_force(d, message_full_id.get_message_id(), "edit_message_caption"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!can_edit_message(dialog_id, m, true)) { return promise.set_error(Status::Error(400, "Message can't be edited")); } @@ -26745,262 +25903,59 @@ void MessagesManager::edit_message_caption(FullMessageId full_message_id, if (!can_have_message_content_caption(m->content->get_type())) { return promise.set_error(Status::Error(400, "There is no caption in the message to edit")); } - - auto r_caption = - get_formatted_text(td_, dialog_id, std::move(input_caption), td_->auth_manager_->is_bot(), true, false, false); - if (r_caption.is_error()) { - return promise.set_error(r_caption.move_as_error()); + if (invert_media && !is_allowed_invert_caption_message_content(m->content->get_type())) { + invert_media = false; } - auto caption = r_caption.move_as_ok(); - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, - has_message_sender_user_id(dialog_id, m)); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok()); + TRY_RESULT_PROMISE( + promise, caption, + get_formatted_text(td_, dialog_id, std::move(input_caption), td_->auth_manager_->is_bot(), true, false, false)); + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, + has_message_sender_user_id(dialog_id, m))); + auto input_reply_markup = get_input_reply_markup(td_->user_manager_.get(), new_reply_markup); td_->create_handler(std::move(promise)) ->send(1 << 11, dialog_id, m->message_id, caption.text, - get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_message_caption"), - nullptr, std::move(input_reply_markup), get_message_schedule_date(m)); + get_input_message_entities(td_->user_manager_.get(), caption.entities, "edit_message_caption"), nullptr, + invert_media, std::move(input_reply_markup), get_message_schedule_date(m)); } -void MessagesManager::edit_message_reply_markup(FullMessageId full_message_id, +void MessagesManager::edit_message_reply_markup(MessageFullId message_full_id, tl_object_ptr &&reply_markup, Promise &&promise) { CHECK(td_->auth_manager_->is_bot()); - LOG(INFO) << "Begin to edit reply markup of " << full_message_id; - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "edit_message_reply_markup"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - if (!have_input_peer(dialog_id, AccessRights::Edit)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Edit, "edit_message_reply_markup")); - const Message *m = get_message_force(d, full_message_id.get_message_id(), "edit_message_reply_markup"); + const Message *m = get_message_force(d, message_full_id.get_message_id(), "edit_message_reply_markup"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!can_edit_message(dialog_id, m, true, true)) { return promise.set_error(Status::Error(400, "Message can't be edited")); } - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, - has_message_sender_user_id(dialog_id, m)); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok()); + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, + has_message_sender_user_id(dialog_id, m))); + auto input_reply_markup = get_input_reply_markup(td_->user_manager_.get(), new_reply_markup); td_->create_handler(std::move(promise)) ->send(0, dialog_id, m->message_id, string(), vector>(), nullptr, - std::move(input_reply_markup), get_message_schedule_date(m)); -} - -void MessagesManager::edit_inline_message_text(const string &inline_message_id, - tl_object_ptr &&reply_markup, - tl_object_ptr &&input_message_content, - Promise &&promise) { - CHECK(td_->auth_manager_->is_bot()); - - if (input_message_content == nullptr) { - return promise.set_error(Status::Error(400, "Can't edit message without new content")); - } - int32 new_message_content_type = input_message_content->get_id(); - if (new_message_content_type != td_api::inputMessageText::ID) { - return promise.set_error(Status::Error(400, "Input message content type must be InputMessageText")); - } - - auto r_input_message_text = - process_input_message_text(td_, DialogId(), std::move(input_message_content), td_->auth_manager_->is_bot()); - if (r_input_message_text.is_error()) { - return promise.set_error(r_input_message_text.move_as_error()); - } - InputMessageText input_message_text = r_input_message_text.move_as_ok(); - - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - - auto input_bot_inline_message_id = td_->inline_queries_manager_->get_input_bot_inline_message_id(inline_message_id); - if (input_bot_inline_message_id == nullptr) { - return promise.set_error(Status::Error(400, "Invalid inline message identifier specified")); - } - - int32 flags = 0; - if (input_message_text.disable_web_page_preview) { - flags |= SEND_MESSAGE_FLAG_DISABLE_WEB_PAGE_PREVIEW; - } - td_->create_handler(std::move(promise)) - ->send(flags, std::move(input_bot_inline_message_id), input_message_text.text.text, - get_input_message_entities(td_->contacts_manager_.get(), input_message_text.text.entities, - "edit_inline_message_text"), - nullptr, get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); -} - -void MessagesManager::edit_inline_message_live_location(const string &inline_message_id, - tl_object_ptr &&reply_markup, - tl_object_ptr &&input_location, int32 heading, - int32 proximity_alert_radius, Promise &&promise) { - CHECK(td_->auth_manager_->is_bot()); - - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - - auto input_bot_inline_message_id = td_->inline_queries_manager_->get_input_bot_inline_message_id(inline_message_id); - if (input_bot_inline_message_id == nullptr) { - return promise.set_error(Status::Error(400, "Invalid inline message identifier specified")); - } - - Location location(input_location); - if (location.empty() && input_location != nullptr) { - return promise.set_error(Status::Error(400, "Invalid location specified")); - } - - int32 flags = 0; - if (location.empty()) { - flags |= telegram_api::inputMediaGeoLive::STOPPED_MASK; - } - if (heading != 0) { - flags |= telegram_api::inputMediaGeoLive::HEADING_MASK; - } - flags |= telegram_api::inputMediaGeoLive::PROXIMITY_NOTIFICATION_RADIUS_MASK; - auto input_media = telegram_api::make_object( - flags, false /*ignored*/, location.get_input_geo_point(), heading, 0, proximity_alert_radius); - td_->create_handler(std::move(promise)) - ->send(0, std::move(input_bot_inline_message_id), "", vector>(), - std::move(input_media), get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); -} - -void MessagesManager::edit_inline_message_media(const string &inline_message_id, - tl_object_ptr &&reply_markup, - tl_object_ptr &&input_message_content, - Promise &&promise) { - CHECK(td_->auth_manager_->is_bot()); - - if (input_message_content == nullptr) { - return promise.set_error(Status::Error(400, "Can't edit message without new content")); - } - int32 new_message_content_type = input_message_content->get_id(); - if (new_message_content_type != td_api::inputMessageAnimation::ID && - new_message_content_type != td_api::inputMessageAudio::ID && - new_message_content_type != td_api::inputMessageDocument::ID && - new_message_content_type != td_api::inputMessagePhoto::ID && - new_message_content_type != td_api::inputMessageVideo::ID) { - return promise.set_error(Status::Error(400, "Unsupported input message content type")); - } - - auto r_input_message_content = process_input_message_content(DialogId(), std::move(input_message_content)); - if (r_input_message_content.is_error()) { - return promise.set_error(r_input_message_content.move_as_error()); - } - InputMessageContent content = r_input_message_content.move_as_ok(); - if (content.ttl > 0) { - LOG(ERROR) << "Have message content with self-destruct time " << content.ttl; - return promise.set_error(Status::Error(400, "Can't enable self-destruction for media")); - } - - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - - auto input_bot_inline_message_id = td_->inline_queries_manager_->get_input_bot_inline_message_id(inline_message_id); - if (input_bot_inline_message_id == nullptr) { - return promise.set_error(Status::Error(400, "Invalid inline message identifier specified")); - } - - auto input_media = get_input_media(content.content.get(), td_, 0, string(), true); - if (input_media == nullptr) { - return promise.set_error(Status::Error(400, "Invalid message content specified")); - } - - const FormattedText *caption = get_message_content_caption(content.content.get()); - td_->create_handler(std::move(promise)) - ->send(1 << 11, std::move(input_bot_inline_message_id), caption == nullptr ? "" : caption->text, - get_input_message_entities(td_->contacts_manager_.get(), caption, "edit_inline_message_media"), - std::move(input_media), get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); -} - -void MessagesManager::edit_inline_message_caption(const string &inline_message_id, - tl_object_ptr &&reply_markup, - tl_object_ptr &&input_caption, - Promise &&promise) { - CHECK(td_->auth_manager_->is_bot()); - - auto r_caption = - get_formatted_text(td_, DialogId(), std::move(input_caption), td_->auth_manager_->is_bot(), true, false, false); - if (r_caption.is_error()) { - return promise.set_error(r_caption.move_as_error()); - } - auto caption = r_caption.move_as_ok(); - - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - - auto input_bot_inline_message_id = td_->inline_queries_manager_->get_input_bot_inline_message_id(inline_message_id); - if (input_bot_inline_message_id == nullptr) { - return promise.set_error(Status::Error(400, "Invalid inline message identifier specified")); - } - - td_->create_handler(std::move(promise)) - ->send(1 << 11, std::move(input_bot_inline_message_id), caption.text, - get_input_message_entities(td_->contacts_manager_.get(), caption.entities, "edit_inline_message_caption"), - nullptr, get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); -} - -void MessagesManager::edit_inline_message_reply_markup(const string &inline_message_id, - tl_object_ptr &&reply_markup, - Promise &&promise) { - CHECK(td_->auth_manager_->is_bot()); - - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, true); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } - - auto input_bot_inline_message_id = td_->inline_queries_manager_->get_input_bot_inline_message_id(inline_message_id); - if (input_bot_inline_message_id == nullptr) { - return promise.set_error(Status::Error(400, "Invalid inline message identifier specified")); - } - - td_->create_handler(std::move(promise)) - ->send(0, std::move(input_bot_inline_message_id), string(), vector>(), - nullptr, get_input_reply_markup(td_->contacts_manager_.get(), r_new_reply_markup.ok())); + m->invert_media /*ignored*/, std::move(input_reply_markup), get_message_schedule_date(m)); } void MessagesManager::edit_message_scheduling_state( - FullMessageId full_message_id, td_api::object_ptr &&scheduling_state, + MessageFullId message_full_id, td_api::object_ptr &&scheduling_state, Promise &&promise) { - auto r_schedule_date = get_message_schedule_date(std::move(scheduling_state)); - if (r_schedule_date.is_error()) { - return promise.set_error(r_schedule_date.move_as_error()); - } - auto schedule_date = r_schedule_date.move_as_ok(); - - LOG(INFO) << "Begin to reschedule " << full_message_id << " to " << schedule_date; + TRY_RESULT_PROMISE(promise, schedule_date, get_message_schedule_date(std::move(scheduling_state))); - auto dialog_id = full_message_id.get_dialog_id(); - Dialog *d = get_dialog_force(dialog_id, "edit_message_scheduling_state"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT_PROMISE(promise, d, + check_dialog_access(dialog_id, true, AccessRights::Edit, "edit_message_scheduling_state")); - if (!have_input_peer(dialog_id, AccessRights::Edit)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - - Message *m = get_message_force(d, full_message_id.get_message_id(), "edit_message_scheduling_state"); + Message *m = get_message_force(d, message_full_id.get_message_id(), "edit_message_scheduling_state"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } @@ -27008,7 +25963,7 @@ void MessagesManager::edit_message_scheduling_state( if (!m->message_id.is_scheduled()) { return promise.set_error(Status::Error(400, "Message is not scheduled")); } - if (!m->message_id.is_scheduled_server()) { + if (!m->message_id.is_valid_scheduled() || !m->message_id.is_scheduled_server()) { return promise.set_error(Status::Error(400, "Can't reschedule the message")); } @@ -27020,31 +25975,49 @@ void MessagesManager::edit_message_scheduling_state( if (schedule_date > 0) { td_->create_handler(std::move(promise)) ->send(0, dialog_id, m->message_id, string(), vector>(), nullptr, - nullptr, schedule_date); + m->invert_media /*ignored*/, nullptr, schedule_date); } else { td_->create_handler(std::move(promise))->send(dialog_id, m->message_id); } } +void MessagesManager::set_message_fact_check(MessageFullId message_full_id, + td_api::object_ptr &&text, + Promise &&promise) { + auto dialog_id = message_full_id.get_dialog_id(); + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, false, AccessRights::Read, "set_message_fact_check")); + + const Message *m = get_message_force(d, message_full_id.get_message_id(), "set_message_fact_check"); + if (m == nullptr) { + return promise.set_error(Status::Error(400, "Message not found")); + } + if (!can_set_message_fact_check(dialog_id, m)) { + return promise.set_error(Status::Error(400, "Message fact-check can't be changed for the message")); + } + + TRY_RESULT_PROMISE(promise, fact_check_text, + get_formatted_text(td_, dialog_id, std::move(text), false, true, true, false)); + + td_->create_handler(std::move(promise))->send(dialog_id, m->message_id, fact_check_text); +} + bool MessagesManager::is_discussion_message(DialogId dialog_id, const Message *m) const { if (m == nullptr || m->forward_info == nullptr) { return false; } if (m->sender_user_id.is_valid()) { - if (!td_->auth_manager_->is_bot() || m->sender_user_id != ContactsManager::get_service_notifications_user_id()) { + if (!td_->auth_manager_->is_bot() || m->sender_user_id != UserManager::get_service_notifications_user_id()) { return false; } } - if (!m->forward_info->from_dialog_id.is_valid() || !m->forward_info->from_message_id.is_valid()) { + auto linked_dialog_id = m->forward_info->get_last_dialog_id(); + if (linked_dialog_id.get_type() != DialogType::Channel) { return false; } - if (dialog_id.get_type() != DialogType::Channel || is_broadcast_channel(dialog_id)) { + if (dialog_id.get_type() != DialogType::Channel || td_->dialog_manager_->is_broadcast_channel(dialog_id)) { return false; } - if (m->forward_info->from_dialog_id == dialog_id) { - return false; - } - if (m->forward_info->from_dialog_id.get_type() != DialogType::Channel) { + if (linked_dialog_id == dialog_id) { return false; } return true; @@ -27070,22 +26043,39 @@ int32 MessagesManager::get_message_max_media_timestamp(const Message *m) { } void MessagesManager::update_message_max_reply_media_timestamp(const Dialog *d, Message *m, - bool need_send_update_message_content) { + bool need_send_update_message_content) const { if (td_->auth_manager_->is_bot()) { return; } auto new_max_reply_media_timestamp = -1; - if (m->reply_to_message_id.is_valid() && !m->reply_to_message_id.is_yet_unsent()) { - auto replied_m = get_message(d, m->reply_to_message_id); + auto reply_message_full_id = m->replied_message_info.get_reply_message_full_id(d->dialog_id, false); + auto reply_message_id = reply_message_full_id.get_message_id(); + if (reply_message_id.is_valid() && !reply_message_id.is_yet_unsent()) { + const auto *reply_d = + reply_message_full_id.get_dialog_id() != d->dialog_id ? get_dialog(reply_message_full_id.get_dialog_id()) : d; + if (reply_d == nullptr) { + // replied message isn't loaded yet + return; + } + auto replied_m = get_message(reply_d, reply_message_id); if (replied_m != nullptr) { new_max_reply_media_timestamp = get_message_own_max_media_timestamp(replied_m); - } else if (!is_deleted_message(d, m->reply_to_message_id) && - m->reply_to_message_id > d->last_clear_history_message_id && - m->reply_to_message_id > d->max_unavailable_message_id) { + } else if (!is_deleted_message(reply_d, reply_message_id) && + reply_message_id > reply_d->last_clear_history_message_id && + reply_message_id > reply_d->max_unavailable_message_id) { // replied message isn't deleted and isn't loaded yet return; } + } else if (m->reply_to_story_full_id != StoryFullId()) { + if (!td_->story_manager_->have_story(m->reply_to_story_full_id)) { + if (!td_->story_manager_->is_inaccessible_story(m->reply_to_story_full_id)) { + // replied story isn't loaded yet + return; + } + } else { + new_max_reply_media_timestamp = td_->story_manager_->get_story_duration(m->reply_to_story_full_id); + } } if (m->max_reply_media_timestamp == new_max_reply_media_timestamp) { @@ -27136,44 +26126,98 @@ void MessagesManager::update_message_max_reply_media_timestamp_in_replied_messag return; } - FullMessageId full_message_id{dialog_id, reply_to_message_id}; - auto it = replied_by_media_timestamp_messages_.find(full_message_id); - if (it == replied_by_media_timestamp_messages_.end()) { + MessageFullId message_full_id{dialog_id, reply_to_message_id}; + auto it = message_to_replied_media_timestamp_messages_.find(message_full_id); + if (it == message_to_replied_media_timestamp_messages_.end()) { return; } - LOG(INFO) << "Update max_reply_media_timestamp for replies of " << reply_to_message_id << " in " << dialog_id; + LOG(INFO) << "Update max_reply_media_timestamp for replies of " << message_full_id; - Dialog *d = get_dialog(dialog_id); - CHECK(d != nullptr); - for (auto message_id : it->second) { - auto m = get_message(d, message_id); + for (auto replied_message_full_id : it->second) { + auto replied_dialog_id = replied_message_full_id.get_dialog_id(); + Dialog *d = get_dialog(replied_dialog_id); + auto m = get_message(d, replied_message_full_id.get_message_id()); CHECK(m != nullptr); - CHECK(m->reply_to_message_id == reply_to_message_id); + CHECK(m->replied_message_info.get_reply_message_full_id(replied_dialog_id, false) == message_full_id); update_message_max_reply_media_timestamp(d, m, true); } } +void MessagesManager::update_story_max_reply_media_timestamp_in_replied_messages(StoryFullId story_full_id) { + auto it = story_to_replied_media_timestamp_messages_.find(story_full_id); + if (it == story_to_replied_media_timestamp_messages_.end()) { + return; + } + + LOG(INFO) << "Update max_reply_media_timestamp for replies of " << story_full_id; + + for (auto replied_message_full_id : it->second) { + auto replied_dialog_id = replied_message_full_id.get_dialog_id(); + Dialog *d = get_dialog(replied_dialog_id); + auto m = get_message(d, replied_message_full_id.get_message_id()); + CHECK(m != nullptr); + CHECK(m->reply_to_story_full_id == story_full_id); + update_message_max_reply_media_timestamp(d, m, true); + } +} + +bool MessagesManager::can_register_message_reply(const Message *m) const { + if (td_->auth_manager_->is_bot()) { + return false; + } + auto reply_message_full_id = m->replied_message_info.get_reply_message_full_id(DialogId(), false); + auto reply_message_id = reply_message_full_id.get_message_id(); + if (reply_message_id.is_valid() && !reply_message_id.is_yet_unsent()) { + return true; + } + if (m->reply_to_story_full_id.is_valid()) { + return true; + } + return false; +} + void MessagesManager::register_message_reply(DialogId dialog_id, const Message *m) { - if (!m->reply_to_message_id.is_valid() || m->reply_to_message_id.is_yet_unsent() || td_->auth_manager_->is_bot()) { + m->replied_message_info.register_content(td_); + + if (!can_register_message_reply(m)) { return; } if (has_media_timestamps(get_message_content_text(m->content.get()), 0, std::numeric_limits::max())) { - LOG(INFO) << "Register " << m->message_id << " in " << dialog_id << " as reply to " << m->reply_to_message_id; - FullMessageId full_message_id{dialog_id, m->reply_to_message_id}; - bool is_inserted = replied_by_media_timestamp_messages_[full_message_id].insert(m->message_id).second; - CHECK(is_inserted); + if (m->reply_to_story_full_id.is_valid()) { + LOG(INFO) << "Register " << m->message_id << " in " << dialog_id << " as reply to " << m->reply_to_story_full_id; + bool is_inserted = story_to_replied_media_timestamp_messages_[m->reply_to_story_full_id] + .insert({dialog_id, m->message_id}) + .second; + CHECK(is_inserted); + } else { + auto message_full_id = m->replied_message_info.get_reply_message_full_id(dialog_id, false); + LOG(INFO) << "Register " << m->message_id << " in " << dialog_id << " as reply to " << message_full_id; + bool is_inserted = + message_to_replied_media_timestamp_messages_[message_full_id].insert({dialog_id, m->message_id}).second; + CHECK(is_inserted); + } } } void MessagesManager::reregister_message_reply(DialogId dialog_id, const Message *m) { - if (!m->reply_to_message_id.is_valid() || m->reply_to_message_id.is_yet_unsent() || td_->auth_manager_->is_bot()) { + // reply itself wan't changed, so there is nothing to reregister + if (!can_register_message_reply(m)) { return; } - auto it = replied_by_media_timestamp_messages_.find({dialog_id, m->reply_to_message_id}); - bool was_registered = it != replied_by_media_timestamp_messages_.end() && it->second.count(m->message_id) > 0; + bool was_registered = false; + if (m->reply_to_story_full_id.is_valid()) { + auto it = story_to_replied_media_timestamp_messages_.find(m->reply_to_story_full_id); + was_registered = + it != story_to_replied_media_timestamp_messages_.end() && it->second.count({dialog_id, m->message_id}) > 0; + } else { + auto message_full_id = m->replied_message_info.get_reply_message_full_id(dialog_id, false); + auto it = message_to_replied_media_timestamp_messages_.find(message_full_id); + was_registered = + it != message_to_replied_media_timestamp_messages_.end() && it->second.count({dialog_id, m->message_id}) > 0; + } bool need_register = has_media_timestamps(get_message_content_text(m->content.get()), 0, std::numeric_limits::max()); if (was_registered == need_register) { @@ -27187,16 +26231,39 @@ void MessagesManager::reregister_message_reply(DialogId dialog_id, const Message } void MessagesManager::unregister_message_reply(DialogId dialog_id, const Message *m) { - auto it = replied_by_media_timestamp_messages_.find({dialog_id, m->reply_to_message_id}); - if (it == replied_by_media_timestamp_messages_.end()) { + m->replied_message_info.unregister_content(td_); + + if (!can_register_message_reply(m)) { return; } - auto is_deleted = it->second.erase(m->message_id) > 0; - if (is_deleted) { - LOG(INFO) << "Unregister " << m->message_id << " in " << dialog_id << " as reply to " << m->reply_to_message_id; - if (it->second.empty()) { - replied_by_media_timestamp_messages_.erase(it); + if (m->reply_to_story_full_id.is_valid()) { + auto it = story_to_replied_media_timestamp_messages_.find(m->reply_to_story_full_id); + if (it == story_to_replied_media_timestamp_messages_.end()) { + return; + } + + auto is_deleted = it->second.erase({dialog_id, m->message_id}) > 0; + if (is_deleted) { + LOG(INFO) << "Unregister " << m->message_id << " in " << dialog_id << " as reply to " + << m->reply_to_story_full_id; + if (it->second.empty()) { + story_to_replied_media_timestamp_messages_.erase(it); + } + } + } else { + auto message_full_id = m->replied_message_info.get_reply_message_full_id(dialog_id, false); + auto it = message_to_replied_media_timestamp_messages_.find(message_full_id); + if (it == message_to_replied_media_timestamp_messages_.end()) { + return; + } + + auto is_deleted = it->second.erase({dialog_id, m->message_id}) > 0; + if (is_deleted) { + LOG(INFO) << "Unregister " << m->message_id << " in " << dialog_id << " as reply to " << message_full_id; + if (it->second.empty()) { + message_to_replied_media_timestamp_messages_.erase(it); + } } } } @@ -27213,14 +26280,6 @@ bool MessagesManager::get_message_disable_web_page_preview(const Message *m) { int32 MessagesManager::get_message_flags(const Message *m) { int32 flags = 0; - if (m->reply_to_message_id.is_valid()) { - CHECK(m->reply_to_message_id.is_server()); - flags |= SEND_MESSAGE_FLAG_IS_REPLY; - } - if (m->top_thread_message_id.is_valid()) { - CHECK(m->top_thread_message_id.is_server()); - flags |= SEND_MESSAGE_FLAG_IS_FROM_THREAD; - } if (m->disable_web_page_preview) { flags |= SEND_MESSAGE_FLAG_DISABLE_WEB_PAGE_PREVIEW; } @@ -27245,6 +26304,12 @@ int32 MessagesManager::get_message_flags(const Message *m) { if (m->update_stickersets_order) { flags |= SEND_MESSAGE_FLAG_UPDATE_STICKER_SETS_ORDER; } + if (m->invert_media) { + flags |= SEND_MESSAGE_FLAG_INVERT_MEDIA; + } + if (m->effect_id.is_valid()) { + flags |= SEND_MESSAGE_FLAG_EFFECT; + } return flags; } @@ -27252,11 +26317,12 @@ tl_object_ptr MessagesManager::get_send_message_as_inpu if (!m->has_explicit_sender) { return nullptr; } - return get_input_peer(get_message_sender(m), AccessRights::Write); + auto dialog_id = m->initial_sender_dialog_id != DialogId() ? m->initial_sender_dialog_id : get_message_sender(m); + return td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); } -bool MessagesManager::can_set_game_score(FullMessageId full_message_id) const { - return can_set_game_score(full_message_id.get_dialog_id(), get_message(full_message_id)); +bool MessagesManager::can_set_game_score(MessageFullId message_full_id) const { + return can_set_game_score(message_full_id.get_dialog_id(), get_message(message_full_id)); } bool MessagesManager::can_set_game_score(DialogId dialog_id, const Message *m) const { @@ -27275,7 +26341,8 @@ bool MessagesManager::can_set_game_score(DialogId dialog_id, const Message *m) c if (m->message_id.is_local()) { return false; } - if (m->via_bot_user_id.is_valid() && m->via_bot_user_id != td_->contacts_manager_->get_my_id()) { + auto is_inline_message = m->via_bot_user_id.is_valid(); + if (is_inline_message && m->via_bot_user_id != td_->user_manager_->get_my_id()) { return false; } @@ -27289,7 +26356,7 @@ bool MessagesManager::can_set_game_score(DialogId dialog_id, const Message *m) c switch (dialog_id.get_type()) { case DialogType::User: - if (!m->is_outgoing && dialog_id != get_my_dialog_id()) { + if (!m->is_outgoing && dialog_id != td_->dialog_manager_->get_my_dialog_id()) { return false; } break; @@ -27299,12 +26366,12 @@ bool MessagesManager::can_set_game_score(DialogId dialog_id, const Message *m) c } break; case DialogType::Channel: { - if (m->via_bot_user_id.is_valid()) { + if (is_inline_message) { // outgoing via_bot messages can always be edited break; } auto channel_id = dialog_id.get_channel_id(); - auto channel_status = td_->contacts_manager_->get_channel_permissions(channel_id); + auto channel_status = td_->chat_manager_->get_channel_permissions(channel_id); if (m->is_channel_post) { if (!channel_status.can_edit_messages() && !(channel_status.can_post_messages() && m->is_outgoing)) { return false; @@ -27327,173 +26394,10 @@ bool MessagesManager::can_set_game_score(DialogId dialog_id, const Message *m) c return true; } -bool MessagesManager::is_forward_info_sender_hidden(const MessageForwardInfo *forward_info) { - CHECK(forward_info != nullptr); - if (forward_info->is_imported) { - return false; - } - if (!forward_info->sender_name.empty()) { - return true; - } - DialogId hidden_sender_dialog_id(ChannelId(static_cast(G()->is_test_dc() ? 10460537 : 1228946795))); - return forward_info->sender_dialog_id == hidden_sender_dialog_id && !forward_info->author_signature.empty() && - !forward_info->message_id.is_valid(); -} - -unique_ptr MessagesManager::get_message_forward_info( - tl_object_ptr &&forward_header, FullMessageId full_message_id) { - if (forward_header == nullptr) { - return nullptr; - } - - if (forward_header->date_ <= 0) { - LOG(ERROR) << "Wrong date in message forward header: " << oneline(to_string(forward_header)); - return nullptr; - } - - auto flags = forward_header->flags_; - DialogId sender_dialog_id; - MessageId message_id; - string author_signature = std::move(forward_header->post_author_); - DialogId from_dialog_id; - MessageId from_message_id; - string sender_name = std::move(forward_header->from_name_); - bool is_imported = forward_header->imported_; - if (forward_header->from_id_ != nullptr) { - sender_dialog_id = DialogId(forward_header->from_id_); - if (!sender_dialog_id.is_valid()) { - LOG(ERROR) << "Receive invalid sender identifier in message forward header: " - << oneline(to_string(forward_header)); - sender_dialog_id = DialogId(); - } - } - if ((flags & telegram_api::messageFwdHeader::CHANNEL_POST_MASK) != 0) { - message_id = MessageId(ServerMessageId(forward_header->channel_post_)); - if (!message_id.is_valid()) { - LOG(ERROR) << "Receive " << message_id << " in message forward header: " << oneline(to_string(forward_header)); - message_id = MessageId(); - } - } - if (forward_header->saved_from_peer_ != nullptr) { - from_dialog_id = DialogId(forward_header->saved_from_peer_); - from_message_id = MessageId(ServerMessageId(forward_header->saved_from_msg_id_)); - if (!from_dialog_id.is_valid() || !from_message_id.is_valid()) { - LOG(ERROR) << "Receive " << from_message_id << " in " << from_dialog_id - << " in message forward header: " << oneline(to_string(forward_header)); - from_dialog_id = DialogId(); - from_message_id = MessageId(); - } - } - - UserId sender_user_id; - if (sender_dialog_id.get_type() == DialogType::User) { - sender_user_id = sender_dialog_id.get_user_id(); - sender_dialog_id = DialogId(); - } - if (!sender_dialog_id.is_valid()) { - if (sender_user_id.is_valid()) { - if (message_id.is_valid()) { - LOG(ERROR) << "Receive non-empty message identifier in message forward header: " - << oneline(to_string(forward_header)); - message_id = MessageId(); - } - } else if (sender_name.empty()) { - LOG(ERROR) << "Receive wrong message forward header: " << oneline(to_string(forward_header)); - return nullptr; - } - } else if (sender_dialog_id.get_type() != DialogType::Channel) { - LOG(ERROR) << "Receive wrong message forward header with non-channel sender: " - << oneline(to_string(forward_header)); - return nullptr; - } else { - auto channel_id = sender_dialog_id.get_channel_id(); - if (!td_->contacts_manager_->have_channel(channel_id)) { - LOG(ERROR) << "Receive forward from " - << (td_->contacts_manager_->have_min_channel(channel_id) ? "min" : "unknown") << ' ' << channel_id - << " in " << full_message_id; - } - force_create_dialog(sender_dialog_id, "message forward info", true); - CHECK(!sender_user_id.is_valid()); - } - if (from_dialog_id.is_valid()) { - force_create_dialog(from_dialog_id, "message forward from info", true); - } - - return td::make_unique(sender_user_id, forward_header->date_, sender_dialog_id, message_id, - std::move(author_signature), std::move(sender_name), from_dialog_id, - from_message_id, std::move(forward_header->psa_type_), is_imported); -} - -td_api::object_ptr MessagesManager::get_message_forward_info_object( - const unique_ptr &forward_info) const { - if (forward_info == nullptr) { - return nullptr; - } - - auto origin = [&]() -> td_api::object_ptr { - if (forward_info->is_imported) { - return td_api::make_object(forward_info->sender_name); - } - if (is_forward_info_sender_hidden(forward_info.get())) { - return td_api::make_object( - forward_info->sender_name.empty() ? forward_info->author_signature : forward_info->sender_name); - } - if (forward_info->message_id.is_valid()) { - return td_api::make_object( - get_chat_id_object(forward_info->sender_dialog_id, "messageForwardOriginChannel"), - forward_info->message_id.get(), forward_info->author_signature); - } - if (forward_info->sender_dialog_id.is_valid()) { - return td_api::make_object( - get_chat_id_object(forward_info->sender_dialog_id, "messageForwardOriginChat"), - forward_info->sender_name.empty() ? forward_info->author_signature : forward_info->sender_name); - } - return td_api::make_object( - td_->contacts_manager_->get_user_id_object(forward_info->sender_user_id, "messageForwardOriginUser")); - }(); - - return td_api::make_object( - std::move(origin), forward_info->date, forward_info->psa_type, - get_chat_id_object(forward_info->from_dialog_id, "messageForwardInfo"), forward_info->from_message_id.get()); -} - Result> MessagesManager::get_dialog_reply_markup( - DialogId dialog_id, tl_object_ptr &&reply_markup_ptr) const { - if (reply_markup_ptr == nullptr) { - return nullptr; - } - - auto dialog_type = dialog_id.get_type(); - bool is_anonymous = is_anonymous_administrator(dialog_id, nullptr); - - bool only_inline_keyboard = is_anonymous; - bool request_buttons_allowed = dialog_type == DialogType::User; - bool switch_inline_buttons_allowed = !is_anonymous; - - TRY_RESULT(reply_markup, - get_reply_markup(std::move(reply_markup_ptr), td_->auth_manager_->is_bot(), only_inline_keyboard, - request_buttons_allowed, switch_inline_buttons_allowed)); - if (reply_markup == nullptr) { - return nullptr; - } - - switch (dialog_type) { - case DialogType::User: - if (reply_markup->type != ReplyMarkup::Type::InlineKeyboard) { - reply_markup->is_personal = false; - } - break; - case DialogType::Channel: - case DialogType::Chat: - case DialogType::SecretChat: - case DialogType::None: - // nothing special - break; - default: - UNREACHABLE(); - } - - return std::move(reply_markup); + DialogId dialog_id, tl_object_ptr &&reply_markup) const { + return get_reply_markup(std::move(reply_markup), dialog_id.get_type(), td_->auth_manager_->is_bot(), + td_->dialog_manager_->is_anonymous_administrator(dialog_id, nullptr)); } class MessagesManager::ForwardMessagesLogEvent { @@ -27595,12 +26499,12 @@ void MessagesManager::do_forward_messages(DialogId to_dialog_id, DialogId from_d vector random_ids = transform(messages, [this, to_dialog_id](const Message *m) { return begin_send_message(to_dialog_id, m); }); send_closure_later(actor_id(this), &MessagesManager::send_forward_message_query, flags, to_dialog_id, - messages[0]->top_thread_message_id, from_dialog_id, std::move(as_input_peer), message_ids, + messages[0]->initial_top_thread_message_id, from_dialog_id, std::move(as_input_peer), message_ids, std::move(random_ids), schedule_date, get_erase_log_event_promise(log_event_id)); } -void MessagesManager::send_forward_message_query(int32 flags, DialogId to_dialog_id, MessageId top_thread_message_id, - DialogId from_dialog_id, +void MessagesManager::send_forward_message_query(int32 flags, DialogId to_dialog_id, + const MessageId top_thread_message_id, DialogId from_dialog_id, tl_object_ptr as_input_peer, vector message_ids, vector random_ids, int32 schedule_date, Promise promise) { @@ -27616,7 +26520,7 @@ Result> MessagesManager::forward_message( vector all_copy_options; all_copy_options.push_back(std::move(copy_options)); TRY_RESULT(result, forward_messages(to_dialog_id, top_thread_message_id, from_dialog_id, {message_id}, - std::move(options), in_game_share, std::move(all_copy_options), false)); + std::move(options), in_game_share, std::move(all_copy_options))); CHECK(result->messages_.size() == 1); if (result->messages_[0] == nullptr) { return Status::Error(400, @@ -27625,48 +26529,60 @@ Result> MessagesManager::forward_message( return std::move(result->messages_[0]); } -unique_ptr MessagesManager::create_message_forward_info( - DialogId from_dialog_id, DialogId to_dialog_id, const Message *forwarded_message) const { - auto content_type = forwarded_message->content->get_type(); - if (content_type == MessageContentType::Game || content_type == MessageContentType::Audio) { +MessageOrigin MessagesManager::get_forwarded_message_origin(DialogId dialog_id, const Message *m) const { + CHECK(m != nullptr); + MessageOrigin origin; + if (m->forward_info != nullptr) { + origin = m->forward_info->get_origin(); + } else if (m->is_channel_post) { + if (td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + auto author_signature = + m->sender_user_id.is_valid() ? td_->user_manager_->get_user_title(m->sender_user_id) : m->author_signature; + origin = MessageOrigin{UserId(), dialog_id, m->message_id, std::move(author_signature), string()}; + } else { + LOG(ERROR) << "Don't know how to forward a channel post not from a channel"; + } + } else if (m->sender_user_id.is_valid() || m->sender_dialog_id.is_valid()) { + auto author_signature = m->author_signature; + origin = MessageOrigin{m->sender_user_id, m->sender_dialog_id, MessageId(), string(), std::move(author_signature)}; + } else { + LOG(ERROR) << "Don't know how to forward a non-channel post message without forward info and sender"; + } + origin.hide_sender_if_needed(td_); + return origin; +} + +unique_ptr MessagesManager::create_message_forward_info(DialogId from_dialog_id, + DialogId to_dialog_id, + const Message *m) const { + auto content_type = m->content->get_type(); + if (content_type == MessageContentType::Game) { return nullptr; } - auto my_id = td_->contacts_manager_->get_my_id(); - auto message_id = forwarded_message->message_id; + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); - DialogId saved_from_dialog_id; - MessageId saved_from_message_id; - if (to_dialog_id == DialogId(my_id)) { - saved_from_dialog_id = from_dialog_id; - saved_from_message_id = message_id; + LastForwardedMessageInfo last_message_info; + if (to_dialog_id == my_dialog_id) { + last_message_info = LastForwardedMessageInfo(from_dialog_id, m->message_id, get_message_sender(m), string(), + m->date, m->is_outgoing); + } else if (content_type == MessageContentType::Audio || content_type == MessageContentType::Story) { + return nullptr; } - if (forwarded_message->forward_info != nullptr) { - auto forward_info = make_unique(*forwarded_message->forward_info); - forward_info->from_dialog_id = saved_from_dialog_id; - forward_info->from_message_id = saved_from_message_id; - return forward_info; + if (m->forward_info != nullptr) { + return MessageForwardInfo::copy_message_forward_info(td_, *m->forward_info, std::move(last_message_info)); } - if (from_dialog_id != DialogId(my_id) || content_type == MessageContentType::Dice) { - if (forwarded_message->is_channel_post) { - if (is_broadcast_channel(from_dialog_id)) { - auto author_signature = forwarded_message->sender_user_id.is_valid() - ? td_->contacts_manager_->get_user_title(forwarded_message->sender_user_id) - : forwarded_message->author_signature; - return td::make_unique(UserId(), forwarded_message->date, from_dialog_id, - forwarded_message->message_id, std::move(author_signature), "", - saved_from_dialog_id, saved_from_message_id, "", false); - } else { - LOG(ERROR) << "Don't know how to forward a channel post not from a channel"; + if (from_dialog_id != my_dialog_id || content_type == MessageContentType::Dice) { + auto origin = get_forwarded_message_origin(from_dialog_id, m); + if (!origin.is_empty()) { + last_message_info.hide_sender_if_needed(td_); + if (last_message_info.get_dialog_id() != DialogId()) { + last_message_info = LastForwardedMessageInfo(from_dialog_id, m->message_id, DialogId(), string(), 0, + m->is_outgoing && origin.get_sender() != my_dialog_id); } - } else if (forwarded_message->sender_user_id.is_valid() || forwarded_message->sender_dialog_id.is_valid()) { - return td::make_unique( - forwarded_message->sender_user_id, forwarded_message->date, forwarded_message->sender_dialog_id, MessageId(), - "", forwarded_message->author_signature, saved_from_dialog_id, saved_from_message_id, "", false); - } else { - LOG(ERROR) << "Don't know how to forward a non-channel post message without forward info and sender"; + return td::make_unique(std::move(origin), m->date, std::move(last_message_info), "", false); } } return nullptr; @@ -27683,7 +26599,7 @@ void MessagesManager::fix_forwarded_message(Message *m, DialogId to_dialog_id, c } m->media_album_id = media_album_id; if (!drop_author && forwarded_message->view_count > 0 && m->forward_info != nullptr && m->view_count == 0 && - !(m->message_id.is_scheduled() && is_broadcast_channel(to_dialog_id))) { + !(m->message_id.is_scheduled() && td_->dialog_manager_->is_broadcast_channel(to_dialog_id))) { m->view_count = forwarded_message->view_count; m->forward_count = forwarded_message->forward_count; m->interaction_info_update_date = G()->unix_time(); @@ -27695,8 +26611,8 @@ void MessagesManager::fix_forwarded_message(Message *m, DialogId to_dialog_id, c // if there is no via_bot_user_id, then the original message was sent by the game owner m->via_bot_user_id = forwarded_message->sender_user_id; } - if (m->via_bot_user_id == td_->contacts_manager_->get_my_id()) { - // if via_bot_user_id is the current bot user, then there should be + if (m->via_bot_user_id == td_->user_manager_->get_my_id()) { + // if via_bot_user_id is the current bot user, then there should be no via_bot m->via_bot_user_id = UserId(); } } @@ -27752,13 +26668,10 @@ Result MessagesManager::get_forwarded_messag if (from_dialog == nullptr) { return Status::Error(400, "Chat to forward messages from not found"); } - if (!have_input_peer(from_dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(from_dialog_id, false, AccessRights::Read)) { return Status::Error(400, "Can't access the chat to forward messages from"); } - if (from_dialog_id.get_type() == DialogType::SecretChat) { - return Status::Error(400, "Can't forward messages from secret chats"); - } - if (get_dialog_has_protected_content(from_dialog_id)) { + if (td_->dialog_manager_->get_dialog_has_protected_content(from_dialog_id)) { for (const auto ©_option : copy_options) { if (!copy_option.send_copy || !td_->auth_manager_->is_bot()) { return Status::Error(400, "Message has protected content and can't be forwarded"); @@ -27772,8 +26685,8 @@ Result MessagesManager::get_forwarded_messag } TRY_STATUS(can_send_message(to_dialog_id)); - TRY_RESULT(message_send_options, process_message_send_options(to_dialog_id, std::move(options), false)); - TRY_STATUS(can_use_top_thread_message_id(to_dialog, top_thread_message_id, MessageId())); + TRY_RESULT(message_send_options, process_message_send_options(to_dialog_id, std::move(options), false, false)); + TRY_STATUS(can_use_top_thread_message_id(to_dialog, top_thread_message_id, MessageInputReplyTo())); { MessageId last_message_id; @@ -27852,8 +26765,12 @@ Result MessagesManager::get_forwarded_messag auto type = need_copy ? (is_local_copy ? MessageContentDupType::Copy : MessageContentDupType::ServerCopy) : MessageContentDupType::Forward; - auto reply_to_message_id = copy_options[i].reply_to_message_id; + auto input_reply_to = std::move(copy_options[i].input_reply_to); auto reply_markup = std::move(copy_options[i].reply_markup); + auto new_invert_media = is_local_copy && copy_options[i].replace_caption && + is_allowed_invert_caption_message_content(forwarded_message->content->get_type()) + ? copy_options[i].new_invert_media + : forwarded_message->invert_media; unique_ptr content = dup_message_content(td_, to_dialog_id, forwarded_message->content.get(), type, std::move(copy_options[i])); if (content == nullptr) { @@ -27861,21 +26778,20 @@ Result MessagesManager::get_forwarded_messag continue; } - reply_to_message_id = get_reply_to_message_id(to_dialog, top_thread_message_id, reply_to_message_id, false); - - auto can_send_status = can_send_message_content(to_dialog_id, content.get(), !is_local_copy, td_); + auto can_send_status = can_send_message_content(to_dialog_id, content.get(), !is_local_copy, true, td_); if (can_send_status.is_error()) { LOG(INFO) << "Can't forward " << message_id << ": " << can_send_status.message(); continue; } - auto can_use_options_status = can_use_message_send_options(message_send_options, content, 0); + auto can_use_options_status = + can_use_message_send_options(message_send_options, content, MessageSelfDestructType()); if (can_use_options_status.is_error()) { LOG(INFO) << "Can't forward " << message_id << ": " << can_send_status.message(); continue; } - if (can_use_top_thread_message_id(to_dialog, top_thread_message_id, reply_to_message_id).is_error()) { + if (can_use_top_thread_message_id(to_dialog, top_thread_message_id, input_reply_to).is_error()) { LOG(INFO) << "Ignore invalid message thread ID " << top_thread_message_id; top_thread_message_id = MessageId(); } @@ -27895,12 +26811,15 @@ Result MessagesManager::get_forwarded_messag } if (is_local_copy) { - copied_messages.push_back({std::move(content), reply_to_message_id, forwarded_message->message_id, - forwarded_message->reply_to_message_id, std::move(reply_markup), + auto original_reply_to_message_id = + forwarded_message->replied_message_info.get_same_chat_reply_to_message_id(true); + copied_messages.push_back({std::move(content), std::move(input_reply_to), forwarded_message->message_id, + original_reply_to_message_id, std::move(reply_markup), forwarded_message->media_album_id, - get_message_disable_web_page_preview(forwarded_message), i}); + get_message_disable_web_page_preview(forwarded_message), new_invert_media, i}); } else { - forwarded_message_contents.push_back({std::move(content), forwarded_message->media_album_id, i}); + forwarded_message_contents.push_back( + {std::move(content), new_invert_media, forwarded_message->media_album_id, i}); } } result.top_thread_message_id = top_thread_message_id; @@ -27946,14 +26865,14 @@ Result MessagesManager::get_forwarded_messag Result> MessagesManager::forward_messages( DialogId to_dialog_id, MessageId top_thread_message_id, DialogId from_dialog_id, vector message_ids, - tl_object_ptr &&options, bool in_game_share, vector &©_options, - bool only_preview) { + tl_object_ptr &&options, bool in_game_share, + vector &©_options) { TRY_RESULT(forwarded_messages_info, get_forwarded_messages(to_dialog_id, top_thread_message_id, from_dialog_id, message_ids, std::move(options), in_game_share, std::move(copy_options))); auto from_dialog = forwarded_messages_info.from_dialog; auto to_dialog = forwarded_messages_info.to_dialog; - auto message_send_options = forwarded_messages_info.message_send_options; + const auto message_send_options = forwarded_messages_info.message_send_options; auto &copied_messages = forwarded_messages_info.copied_messages; auto &forwarded_message_contents = forwarded_messages_info.forwarded_message_contents; auto drop_author = forwarded_messages_info.drop_author; @@ -27973,48 +26892,45 @@ Result> MessagesManager::forward_messages( auto content = std::move(forwarded_message_contents[j].content); auto forward_info = drop_author ? nullptr : create_message_forward_info(from_dialog_id, to_dialog_id, forwarded_message); - if (forward_info != nullptr && !forward_info->is_imported && !is_forward_info_sender_hidden(forward_info.get()) && - !forward_info->message_id.is_valid() && !forward_info->sender_dialog_id.is_valid() && - forward_info->sender_user_id.is_valid()) { - auto private_forward_name = td_->contacts_manager_->get_user_private_forward_name(forward_info->sender_user_id); - if (!private_forward_name.empty()) { - forward_info->sender_user_id = UserId(); - forward_info->sender_name = std::move(private_forward_name); - } - } - MessageId reply_to_message_id; - if (forwarded_message->reply_to_message_id.is_valid()) { - auto it = forwarded_message_id_to_new_message_id.find(forwarded_message->reply_to_message_id); + MessageInputReplyTo input_reply_to; + auto original_reply_to_message_id = forwarded_message->replied_message_info.get_same_chat_reply_to_message_id(true); + if (original_reply_to_message_id.is_valid()) { + auto it = forwarded_message_id_to_new_message_id.find(original_reply_to_message_id); if (it != forwarded_message_id_to_new_message_id.end()) { - reply_to_message_id = it->second; + input_reply_to = forwarded_message->replied_message_info.get_input_reply_to(); + input_reply_to.set_message_id(it->second); } } unique_ptr message; Message *m; - if (only_preview) { - message = create_message_to_send(to_dialog, top_thread_message_id, reply_to_message_id, message_send_options, - std::move(content), j + 1 != forwarded_message_contents.size(), - std::move(forward_info), false, DialogId()); - MessageId new_message_id = - message_send_options.schedule_date != 0 - ? get_next_yet_unsent_scheduled_message_id(to_dialog, message_send_options.schedule_date) - : get_next_yet_unsent_message_id(to_dialog); - message->message_id = new_message_id; + if (message_send_options.only_preview) { + message = create_message_to_send( + to_dialog, top_thread_message_id, std::move(input_reply_to), message_send_options, std::move(content), + forwarded_message_contents[j].invert_media, j + 1 != forwarded_message_contents.size(), + std::move(forward_info), from_dialog_id, false, DialogId()); m = message.get(); } else { - m = get_message_to_send(to_dialog, top_thread_message_id, reply_to_message_id, message_send_options, - std::move(content), &need_update_dialog_pos, j + 1 != forwarded_message_contents.size(), - std::move(forward_info)); + m = get_message_to_send(to_dialog, top_thread_message_id, std::move(input_reply_to), message_send_options, + std::move(content), forwarded_message_contents[j].invert_media, &need_update_dialog_pos, + j + 1 != forwarded_message_contents.size(), std::move(forward_info), from_dialog_id); } fix_forwarded_message(m, to_dialog_id, forwarded_message, forwarded_message_contents[j].media_album_id, drop_author); m->in_game_share = in_game_share; - m->real_forward_from_dialog_id = from_dialog_id; m->real_forward_from_message_id = message_id; forwarded_message_id_to_new_message_id.emplace(message_id, m->message_id); + if (forwarded_message->replied_message_info.is_external()) { + if (!message_send_options.only_preview) { + unregister_message_reply(to_dialog_id, m); + } + m->replied_message_info = forwarded_message->replied_message_info.clone(td_); + if (!message_send_options.only_preview) { + register_message_reply(to_dialog_id, m); + } + } - if (!only_preview) { + if (!message_send_options.only_preview) { if (!td_->auth_manager_->is_bot()) { send_update_new_message(to_dialog, m); } @@ -28026,13 +26942,16 @@ Result> MessagesManager::forward_messages( } if (!forwarded_messages.empty()) { - CHECK(!only_preview); + CHECK(!message_send_options.only_preview); do_forward_messages(to_dialog_id, from_dialog_id, forwarded_messages, forwarded_message_ids, drop_author, drop_media_captions, 0); } bool is_secret = to_dialog_id.get_type() == DialogType::SecretChat; bool is_copy = !is_secret; + bool need_invalidate_authentication_code = + from_dialog_id == DialogId(UserManager::get_service_notifications_user_id()) && !td_->auth_manager_->is_bot(); + vector authentication_codes; for (const auto &copied_message : copied_messages) { if (forwarded_message_id_to_new_message_id.count(copied_message.original_reply_to_message_id) > 0) { is_copy = true; @@ -28041,35 +26960,38 @@ Result> MessagesManager::forward_messages( forwarded_message_id_to_new_message_id.emplace(copied_message.original_message_id, MessageId()); } for (auto &copied_message : copied_messages) { - MessageId reply_to_message_id = copied_message.reply_to_message_id; - if (!reply_to_message_id.is_valid() && copied_message.original_reply_to_message_id.is_valid() && is_secret) { + auto input_reply_to = std::move(copied_message.input_reply_to); + if (!input_reply_to.is_valid() && copied_message.original_reply_to_message_id.is_valid() && is_secret) { auto it = forwarded_message_id_to_new_message_id.find(copied_message.original_reply_to_message_id); if (it != forwarded_message_id_to_new_message_id.end()) { - reply_to_message_id = it->second; + input_reply_to = MessageInputReplyTo{it->second, DialogId(), MessageQuote()}; } } unique_ptr message; Message *m; - if (only_preview) { - message = create_message_to_send(to_dialog, top_thread_message_id, reply_to_message_id, message_send_options, - std::move(copied_message.content), false, nullptr, is_copy, DialogId()); - MessageId new_message_id = - message_send_options.schedule_date != 0 - ? get_next_yet_unsent_scheduled_message_id(to_dialog, message_send_options.schedule_date) - : get_next_yet_unsent_message_id(to_dialog); - message->message_id = new_message_id; + if (message_send_options.only_preview) { + message = create_message_to_send(to_dialog, top_thread_message_id, std::move(input_reply_to), + message_send_options, std::move(copied_message.content), + copied_message.invert_media, false, nullptr, DialogId(), is_copy, DialogId()); m = message.get(); } else { - m = get_message_to_send(to_dialog, top_thread_message_id, reply_to_message_id, message_send_options, - std::move(copied_message.content), &need_update_dialog_pos, false, nullptr, is_copy); + if (need_invalidate_authentication_code) { + const Message *forwarded_message = get_message(from_dialog, copied_message.original_message_id); + CHECK(forwarded_message != nullptr); + extract_authentication_codes(from_dialog_id, forwarded_message, authentication_codes); + } + + m = get_message_to_send(to_dialog, top_thread_message_id, std::move(input_reply_to), message_send_options, + std::move(copied_message.content), copied_message.invert_media, &need_update_dialog_pos, + false, nullptr, DialogId(), is_copy); } m->disable_web_page_preview = copied_message.disable_web_page_preview; m->media_album_id = copied_message.media_album_id; m->reply_markup = std::move(copied_message.reply_markup); forwarded_message_id_to_new_message_id[copied_message.original_message_id] = m->message_id; - if (!only_preview) { + if (!message_send_options.only_preview) { save_send_message_log_event(to_dialog_id, m); do_send_message(to_dialog_id, m); if (!td_->auth_manager_->is_bot()) { @@ -28081,14 +27003,159 @@ Result> MessagesManager::forward_messages( } if (need_update_dialog_pos) { - CHECK(!only_preview); + CHECK(!message_send_options.only_preview); send_update_chat_last_message(to_dialog, "forward_messages"); } + if (!authentication_codes.empty()) { + td_->account_manager_->invalidate_authentication_codes(std::move(authentication_codes)); + } + + return get_messages_object(-1, std::move(result), false); +} + +Result> MessagesManager::send_quick_reply_shortcut_messages( + DialogId dialog_id, QuickReplyShortcutId shortcut_id, int32 sending_id) { + TRY_RESULT(message_contents, td_->quick_reply_manager_->get_quick_reply_message_contents(dialog_id, shortcut_id)); + + if (message_contents.empty()) { + return td_api::make_object(); + } + + std::unordered_map, Hash> new_media_album_ids; + for (auto &content : message_contents) { + if (content.media_album_id_ == 0) { + continue; + } + auto &new_media_album_id = new_media_album_ids[content.media_album_id_]; + new_media_album_id.second++; + if (new_media_album_id.second == 2) { // have at least 2 messages in the new album + CHECK(new_media_album_id.first == 0); + new_media_album_id.first = generate_new_media_album_id(); + } + if (new_media_album_id.second == MAX_GROUPED_MESSAGES + 1) { + CHECK(new_media_album_id.first != 0); + new_media_album_id.first = 0; // just in case + } + } + for (auto &content : message_contents) { + content.media_album_id_ = new_media_album_ids[content.media_album_id_].first; + } + + auto *d = get_dialog(dialog_id); + CHECK(d != nullptr); + + MessageSendOptions message_send_options(false, false, false, false, false, 0, sending_id, MessageEffectId()); + FlatHashMap original_message_id_to_new_message_id; + vector> result; + vector sent_messages; + vector sent_message_ids; + bool need_update_dialog_pos = false; + for (auto &content : message_contents) { + MessageInputReplyTo input_reply_to; + if (content.original_reply_to_message_id_.is_valid()) { + auto it = original_message_id_to_new_message_id.find(content.original_reply_to_message_id_); + if (it != original_message_id_to_new_message_id.end()) { + input_reply_to = MessageInputReplyTo{it->second, DialogId(), MessageQuote()}; + } + } + + Message *m = get_message_to_send(d, MessageId(), std::move(input_reply_to), message_send_options, + std::move(content.content_), content.invert_media_, &need_update_dialog_pos, false, + nullptr, DialogId(), true); + m->via_bot_user_id = content.via_bot_user_id_; + m->reply_markup = std::move(content.reply_markup_); + m->disable_web_page_preview = content.disable_web_page_preview_; + m->media_album_id = content.media_album_id_; + original_message_id_to_new_message_id.emplace(content.original_message_id_, m->message_id); + + if (!td_->auth_manager_->is_bot()) { + send_update_new_message(d, m); + } + sent_messages.push_back(m); + sent_message_ids.push_back(content.original_message_id_); + + result.push_back(get_message_object(dialog_id, m, "send_quick_reply_shortcut_messages")); + } + + do_send_quick_reply_shortcut_messages(dialog_id, shortcut_id, sent_messages, sent_message_ids, 0); + + if (need_update_dialog_pos) { + send_update_chat_last_message(d, "send_quick_reply_shortcut_messages"); + } + return get_messages_object(-1, std::move(result), false); } -Result> MessagesManager::resend_messages(DialogId dialog_id, vector message_ids) { +class MessagesManager::SendQuickReplyShortcutMessagesLogEvent { + public: + DialogId dialog_id; + QuickReplyShortcutId shortcut_id; + vector message_ids; + vector messages_in; + vector> messages_out; + + template + void store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + td::store(dialog_id, storer); + td::store(shortcut_id, storer); + td::store(message_ids, storer); + td::store(messages_in, storer); + } + + template + void parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + td::parse(dialog_id, parser); + td::parse(shortcut_id, parser); + td::parse(message_ids, parser); + td::parse(messages_out, parser); + } +}; + +uint64 MessagesManager::save_send_quick_reply_shortcut_messages_log_event(DialogId dialog_id, + QuickReplyShortcutId shortcut_id, + const vector &messages, + const vector &message_ids) { + SendQuickReplyShortcutMessagesLogEvent log_event{dialog_id, shortcut_id, message_ids, messages, Auto()}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SendQuickReplyShortcutMessages, + get_log_event_storer(log_event)); +} + +void MessagesManager::do_send_quick_reply_shortcut_messages(DialogId dialog_id, QuickReplyShortcutId shortcut_id, + const vector &messages, + const vector &message_ids, uint64 log_event_id) { + if (G()->close_flag()) { + return; + } + + CHECK(messages.size() == message_ids.size()); + if (messages.empty()) { + return; + } + + if (log_event_id == 0 && G()->use_message_database()) { + log_event_id = save_send_quick_reply_shortcut_messages_log_event(dialog_id, shortcut_id, messages, message_ids); + } + + vector random_ids = + transform(messages, [this, dialog_id](const Message *m) { return begin_send_message(dialog_id, m); }); + send_closure_later(actor_id(this), &MessagesManager::send_send_quick_reply_messages_query, dialog_id, shortcut_id, + message_ids, std::move(random_ids), get_erase_log_event_promise(log_event_id)); +} + +void MessagesManager::send_send_quick_reply_messages_query(DialogId dialog_id, QuickReplyShortcutId shortcut_id, + vector message_ids, vector random_ids, + Promise promise) { + td_->create_handler(std::move(promise)) + ->send(dialog_id, shortcut_id, std::move(message_ids), std::move(random_ids)); +} + +Result> MessagesManager::resend_messages(DialogId dialog_id, vector message_ids, + td_api::object_ptr &"e) { if (message_ids.empty()) { return Status::Error(400, "There are no messages to resend"); } @@ -28141,7 +27208,7 @@ Result> MessagesManager::resend_messages(DialogId dialog_id, v continue; } - auto can_send_status = can_send_message_content(dialog_id, content.get(), false, td_); + auto can_send_status = can_send_message_content(dialog_id, content.get(), false, true, td_); if (can_send_status.is_error()) { LOG(INFO) << "Can't resend " << m->message_id << ": " << can_send_status.message(); continue; @@ -28177,14 +27244,24 @@ Result> MessagesManager::resend_messages(DialogId dialog_id, v auto need_another_sender = message->send_error_code == 400 && message->send_error_message == CSlice("SEND_AS_PEER_INVALID"); + auto need_another_reply_quote = + message->send_error_code == 400 && message->send_error_message == CSlice("QUOTE_TEXT_INVALID"); + auto need_drop_reply = + message->send_error_code == 400 && message->send_error_message == CSlice("REPLY_MESSAGE_ID_INVALID"); + if (need_another_reply_quote && message_ids.size() == 1 && quote != nullptr) { + CHECK(message->input_reply_to.is_valid()); + CHECK(message->input_reply_to.has_quote()); // checked in on_send_message_fail + message->input_reply_to.set_quote(MessageQuote{td_, std::move(quote)}); + } else if (need_drop_reply) { + message->input_reply_to = {}; + } MessageSendOptions options(message->disable_notification, message->from_background, - message->update_stickersets_order, message->noforwards, - get_message_schedule_date(message.get()), message->sending_id); - Message *m = get_message_to_send( - d, message->top_thread_message_id, - get_reply_to_message_id(d, message->top_thread_message_id, message->reply_to_message_id, false), options, - std::move(new_contents[i]), &need_update_dialog_pos, false, nullptr, message->is_copy, - need_another_sender ? DialogId() : get_message_sender(message.get())); + message->update_stickersets_order, message->noforwards, false, + get_message_schedule_date(message.get()), message->sending_id, message->effect_id); + Message *m = get_message_to_send(d, message->top_thread_message_id, std::move(message->input_reply_to), options, + std::move(new_contents[i]), message->invert_media, &need_update_dialog_pos, false, + nullptr, DialogId(), message->is_copy, + need_another_sender ? DialogId() : get_message_sender(message.get())); m->reply_markup = std::move(message->reply_markup); // m->via_bot_user_id = message->via_bot_user_id; m->disable_web_page_preview = message->disable_web_page_preview; @@ -28201,7 +27278,7 @@ Result> MessagesManager::resend_messages(DialogId dialog_id, v send_update_new_message(d, m); result[i] = m->message_id; - being_readded_message_id_ = FullMessageId(); + being_readded_message_id_ = MessageFullId(); } if (need_update_dialog_pos) { @@ -28211,39 +27288,25 @@ Result> MessagesManager::resend_messages(DialogId dialog_id, v return result; } -Status MessagesManager::send_screenshot_taken_notification_message(DialogId dialog_id) { - auto dialog_type = dialog_id.get_type(); - if (dialog_type != DialogType::User && dialog_type != DialogType::SecretChat) { - return Status::Error(400, "Notification about taken screenshot can be sent only in private and secret chats"); - } - - LOG(INFO) << "Begin to send notification about taken screenshot in " << dialog_id; - - Dialog *d = get_dialog_force(dialog_id, "send_screenshot_taken_notification_message"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); - } - - TRY_STATUS(can_send_message(dialog_id)); - +void MessagesManager::send_screenshot_taken_notification_message(Dialog *d) { + LOG(INFO) << "Begin to send notification about taken screenshot in " << d->dialog_id; + auto dialog_type = d->dialog_id.get_type(); if (dialog_type == DialogType::User) { bool need_update_dialog_pos = false; - const Message *m = get_message_to_send(d, MessageId(), MessageId(), MessageSendOptions(), - create_screenshot_taken_message_content(), &need_update_dialog_pos); + const Message *m = get_message_to_send(d, MessageId(), MessageInputReplyTo(), MessageSendOptions(), + create_screenshot_taken_message_content(), false, &need_update_dialog_pos); - do_send_screenshot_taken_notification_message(dialog_id, m, 0); + do_send_screenshot_taken_notification_message(d->dialog_id, m, 0); send_update_new_message(d, m); if (need_update_dialog_pos) { send_update_chat_last_message(d, "send_screenshot_taken_notification_message"); } } else { + CHECK(dialog_type == DialogType::SecretChat); send_closure(td_->secret_chats_manager_, &SecretChatsManager::notify_screenshot_taken, - dialog_id.get_secret_chat_id(), - Promise()); // TODO Promise + d->dialog_id.get_secret_chat_id(), Promise()); } - - return Status::OK(); } class MessagesManager::SendScreenshotTakenNotificationMessageLogEvent { @@ -28272,7 +27335,7 @@ uint64 MessagesManager::save_send_screenshot_taken_notification_message_log_even } CHECK(m != nullptr); - LOG(INFO) << "Save " << FullMessageId(dialog_id, m->message_id) << " to binlog"; + LOG(INFO) << "Save " << MessageFullId(dialog_id, m->message_id) << " to binlog"; SendScreenshotTakenNotificationMessageLogEvent log_event; log_event.dialog_id = dialog_id; log_event.m_in = m; @@ -28282,7 +27345,7 @@ uint64 MessagesManager::save_send_screenshot_taken_notification_message_log_even void MessagesManager::do_send_screenshot_taken_notification_message(DialogId dialog_id, const Message *m, uint64 log_event_id) { - LOG(INFO) << "Do send screenshot taken notification " << FullMessageId(dialog_id, m->message_id); + LOG(INFO) << "Do send screenshot taken notification " << MessageFullId(dialog_id, m->message_id); CHECK(dialog_id.get_type() == DialogType::User); if (log_event_id == 0) { @@ -28294,9 +27357,10 @@ void MessagesManager::do_send_screenshot_taken_notification_message(DialogId dia ->send(dialog_id, random_id); } -void MessagesManager::share_dialog_with_bot(FullMessageId full_message_id, int32 button_id, DialogId shared_dialog_id, - bool expect_user, bool only_check, Promise &&promise) { - const Message *m = get_message_force(full_message_id, "share_dialog_with_bot"); +void MessagesManager::share_dialogs_with_bot(MessageFullId message_full_id, int32 button_id, + vector shared_dialog_ids, bool expect_user, bool only_check, + Promise &&promise) { + const Message *m = get_message_force(message_full_id, "share_dialog_with_bot"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } @@ -28304,56 +27368,46 @@ void MessagesManager::share_dialog_with_bot(FullMessageId full_message_id, int32 return promise.set_error(Status::Error(400, "Message has no buttons")); } CHECK(m->message_id.is_valid() && m->message_id.is_server()); - if (shared_dialog_id.get_type() != DialogType::User) { - if (!have_dialog_force(shared_dialog_id, "share_dialog_with_bot")) { - return promise.set_error(Status::Error(400, "Shared chat not found")); - } - } else { - if (!expect_user) { - return promise.set_error(Status::Error(400, "Wrong chat type")); - } - if (!td_->contacts_manager_->have_user(shared_dialog_id.get_user_id())) { - return promise.set_error(Status::Error(400, "Shared user not found")); + TRY_STATUS_PROMISE(promise, m->reply_markup->check_shared_dialog_count(button_id, shared_dialog_ids.size())); + for (auto shared_dialog_id : shared_dialog_ids) { + if (shared_dialog_id.get_type() != DialogType::User) { + if (!have_dialog_force(shared_dialog_id, "share_dialogs_with_bot")) { + return promise.set_error(Status::Error(400, "Shared chat not found")); + } + } else { + if (!expect_user) { + return promise.set_error(Status::Error(400, "Wrong chat type")); + } + if (!td_->user_manager_->have_user(shared_dialog_id.get_user_id())) { + return promise.set_error(Status::Error(400, "Shared user not found")); + } } + TRY_STATUS_PROMISE(promise, m->reply_markup->check_shared_dialog(td_, button_id, shared_dialog_id)); } - TRY_STATUS_PROMISE(promise, m->reply_markup->check_shared_dialog(td_, button_id, shared_dialog_id)); if (only_check) { return promise.set_value(Unit()); } td_->create_handler(std::move(promise)) - ->send(full_message_id, button_id, shared_dialog_id); + ->send(message_full_id, button_id, std::move(shared_dialog_ids)); } Result MessagesManager::add_local_message( - DialogId dialog_id, td_api::object_ptr &&sender, MessageId reply_to_message_id, - bool disable_notification, tl_object_ptr &&input_message_content) { + DialogId dialog_id, td_api::object_ptr &&sender, + td_api::object_ptr &&reply_to, bool disable_notification, + tl_object_ptr &&input_message_content) { if (input_message_content == nullptr) { return Status::Error(400, "Can't add local message without content"); } - LOG(INFO) << "Begin to add local message to " << dialog_id << " in reply to " << reply_to_message_id; - Dialog *d = get_dialog_force(dialog_id, "add_local_message"); - if (d == nullptr) { - return Status::Error(400, "Chat not found"); + TRY_RESULT(d, check_dialog_access(dialog_id, true, AccessRights::Read, "add_local_message")); + TRY_RESULT(message_content, process_input_message_content(dialog_id, std::move(input_message_content), false)); + if (!can_be_local_message_content(message_content.content->get_type())) { + return Status::Error(400, "Can't add a local message with the specified content"); } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return Status::Error(400, "Can't access the chat"); - } - TRY_RESULT(message_content, process_input_message_content(dialog_id, std::move(input_message_content))); - if (message_content.content->get_type() == MessageContentType::Poll) { - return Status::Error(400, "Can't add local poll message"); - } - if (message_content.content->get_type() == MessageContentType::Game) { - return Status::Error(400, "Can't add local game message"); - } - if (message_content.content->get_type() == MessageContentType::Dice) { - return Status::Error(400, "Can't add local dice message"); - } - - bool is_channel_post = is_broadcast_channel(dialog_id); + bool is_channel_post = td_->dialog_manager_->is_broadcast_channel(dialog_id); UserId sender_user_id; DialogId sender_dialog_id; if (sender != nullptr) { @@ -28370,27 +27424,27 @@ Result MessagesManager::add_local_message( } else { return Status::Error(400, "The message must have a sender"); } - if (is_channel_post && sender_user_id.is_valid()) { - return Status::Error(400, "Channel post can't have a sender user"); - } - if (is_channel_post && sender_dialog_id != dialog_id) { - return Status::Error(400, "Channel post must have the channel as a sender"); + if (is_channel_post && sender_user_id.is_valid() && + !td_->chat_manager_->get_channel_show_message_sender(dialog_id.get_channel_id())) { + return Status::Error(400, "Channel post can't have user as a sender"); } auto dialog_type = dialog_id.get_type(); - auto my_id = td_->contacts_manager_->get_my_id(); + auto my_id = td_->user_manager_->get_my_id(); if (sender_user_id != my_id) { if (dialog_type == DialogType::User && DialogId(sender_user_id) != dialog_id) { return Status::Error(400, "Wrong sender user"); } if (dialog_type == DialogType::SecretChat) { - auto peer_user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + auto peer_user_id = td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); if (!peer_user_id.is_valid() || sender_user_id != peer_user_id) { return Status::Error(400, "Wrong sender user"); } } } + auto input_reply_to = create_message_input_reply_to(d, MessageId(), std::move(reply_to), false); + MessageId message_id = get_next_local_message_id(d); auto message = make_unique(); @@ -28398,18 +27452,21 @@ Result MessagesManager::add_local_message( m->message_id = message_id; if (is_channel_post) { // sender of the post can be hidden - if (td_->contacts_manager_->get_channel_sign_messages(dialog_id.get_channel_id())) { - m->author_signature = td_->contacts_manager_->get_user_title(sender_user_id); + if (td_->chat_manager_->get_channel_sign_messages(dialog_id.get_channel_id())) { + auto real_sender_user_id = sender_user_id.is_valid() ? sender_user_id : my_id; + m->author_signature = m->sender_dialog_id == dialog_id || m->sender_dialog_id == DialogId() + ? td_->user_manager_->get_user_title(real_sender_user_id) + : td_->dialog_manager_->get_dialog_title(m->sender_dialog_id); } - m->sender_dialog_id = sender_dialog_id; - } else { - m->sender_user_id = sender_user_id; - m->sender_dialog_id = sender_dialog_id; } + m->sender_user_id = sender_user_id; + m->sender_dialog_id = sender_dialog_id; m->date = G()->unix_time(); - m->reply_to_message_id = get_reply_to_message_id(d, MessageId(), reply_to_message_id, false); - if (m->reply_to_message_id.is_valid() && !message_id.is_scheduled()) { - const Message *reply_m = get_message(d, m->reply_to_message_id); + m->replied_message_info = RepliedMessageInfo(td_, input_reply_to); + m->reply_to_story_full_id = input_reply_to.get_story_full_id(); + if (!message_id.is_scheduled()) { + auto reply_to_message_id = input_reply_to.get_same_chat_reply_to_message_id(); + const Message *reply_m = get_message(d, reply_to_message_id); if (reply_m != nullptr) { m->top_thread_message_id = reply_m->top_thread_message_id; if (m->top_thread_message_id.is_valid()) { @@ -28424,19 +27481,25 @@ Result MessagesManager::add_local_message( m->update_stickersets_order = false; m->view_count = 0; m->forward_count = 0; + if (m->sender_user_id == my_id && dialog_type == DialogType::Channel && !is_channel_post) { + m->sender_boost_count = td_->chat_manager_->get_channel_my_boost_count(dialog_id.get_channel_id()); + } m->content = std::move(message_content.content); + m->invert_media = message_content.invert_media; m->disable_web_page_preview = message_content.disable_web_page_preview; m->clear_draft = message_content.clear_draft; if (dialog_type == DialogType::SecretChat) { - m->ttl = td_->contacts_manager_->get_secret_chat_ttl(dialog_id.get_secret_chat_id()); - if (is_service_message_content(m->content->get_type())) { - m->ttl = 0; + if (!is_service_message_content(m->content->get_type())) { + m->ttl = MessageSelfDestructType(td_->user_manager_->get_secret_chat_ttl(dialog_id.get_secret_chat_id()), false); } - } else if (message_content.ttl > 0) { + } else if (message_content.ttl.is_valid()) { m->ttl = message_content.ttl; } - m->is_content_secret = is_secret_message_content(m->ttl, m->content->get_type()); + m->is_content_secret = m->ttl.is_secret_message_content(m->content->get_type()); m->send_emoji = std::move(message_content.emoji); + if (dialog_id == DialogId(my_id)) { + m->saved_messages_topic_id = SavedMessagesTopicId(dialog_id, m->forward_info.get(), DialogId()); + } bool need_update = true; bool need_update_dialog_pos = false; @@ -28453,9 +27516,7 @@ Result MessagesManager::add_local_message( } } - if (result->clear_draft) { - update_dialog_draft_message(d, nullptr, false, !need_update_dialog_pos); - } + clear_dialog_draft_by_sent_message(d, result, !need_update_dialog_pos); send_update_new_message(d, result); if (need_update_dialog_pos) { @@ -28465,164 +27526,7 @@ Result MessagesManager::add_local_message( return message_id; } -void MessagesManager::get_message_file_type(const string &message_file_head, - Promise> &&promise) { - td_->create_handler(std::move(promise))->send(message_file_head); -} - -Status MessagesManager::can_import_messages(DialogId dialog_id) { - if (!have_dialog_force(dialog_id, "can_import_messages")) { - return Status::Error(400, "Chat not found"); - } - - TRY_STATUS(can_send_message(dialog_id)); - - switch (dialog_id.get_type()) { - case DialogType::User: - if (!td_->contacts_manager_->is_user_contact(dialog_id.get_user_id(), true)) { - return Status::Error(400, "User must be a mutual contact"); - } - break; - case DialogType::Chat: - return Status::Error(400, "Basic groups must be updagraded to supergroups first"); - case DialogType::Channel: - if (is_broadcast_channel(dialog_id)) { - return Status::Error(400, "Can't import messages to channels"); - } - if (!td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).can_change_info_and_settings()) { - return Status::Error(400, "Not enough rights to import messages"); - } - break; - case DialogType::SecretChat: - return Status::Error(400, "Can't import messages to secret chats"); - case DialogType::None: - default: - UNREACHABLE(); - } - - return Status::OK(); -} - -void MessagesManager::get_message_import_confirmation_text(DialogId dialog_id, Promise &&promise) { - TRY_STATUS_PROMISE(promise, can_import_messages(dialog_id)); - - td_->create_handler(std::move(promise))->send(dialog_id); -} - -void MessagesManager::import_messages(DialogId dialog_id, const td_api::object_ptr &message_file, - const vector> &attached_files, - Promise &&promise) { - TRY_STATUS_PROMISE(promise, can_import_messages(dialog_id)); - - TRY_RESULT_PROMISE(promise, file_id, - td_->file_manager_->get_input_file_id(FileType::Document, message_file, dialog_id, false, false)); - - vector attached_file_ids; - attached_file_ids.reserve(attached_files.size()); - for (auto &attached_file : attached_files) { - auto file_type = td_->file_manager_->guess_file_type(attached_file); - if (file_type != FileType::Animation && file_type != FileType::Audio && file_type != FileType::Document && - file_type != FileType::Photo && file_type != FileType::Sticker && file_type != FileType::Video && - file_type != FileType::VoiceNote) { - LOG(INFO) << "Skip attached file of type " << file_type; - continue; - } - TRY_RESULT_PROMISE(promise, attached_file_id, - td_->file_manager_->get_input_file_id(file_type, attached_file, dialog_id, false, false)); - attached_file_ids.push_back(attached_file_id); - } - - upload_imported_messages(dialog_id, td_->file_manager_->dup_file_id(file_id, "import_messages"), - std::move(attached_file_ids), false, std::move(promise)); -} - -void MessagesManager::upload_imported_messages(DialogId dialog_id, FileId file_id, vector attached_file_ids, - bool is_reupload, Promise &&promise, vector bad_parts) { - CHECK(file_id.is_valid()); - LOG(INFO) << "Ask to upload imported messages file " << file_id; - auto info = td::make_unique(dialog_id, std::move(attached_file_ids), is_reupload, - std::move(promise)); - bool is_inserted = being_uploaded_imported_messages_.emplace(file_id, std::move(info)).second; - CHECK(is_inserted); - // TODO use force_reupload if is_reupload - td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_imported_messages_callback_, 1, 0, false, - true); -} - -void MessagesManager::start_import_messages(DialogId dialog_id, int64 import_id, vector &&attached_file_ids, - Promise &&promise) { - TRY_STATUS_PROMISE(promise, G()->close_status()); - TRY_STATUS_PROMISE(promise, can_send_message(dialog_id)); - - auto pending_message_import = make_unique(); - pending_message_import->dialog_id = dialog_id; - pending_message_import->import_id = import_id; - pending_message_import->promise = std::move(promise); - - auto &multipromise = pending_message_import->upload_files_multipromise; - - int64 random_id; - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || pending_message_imports_.count(random_id) > 0); - pending_message_imports_[random_id] = std::move(pending_message_import); - - multipromise.add_promise(PromiseCreator::lambda([actor_id = actor_id(this), random_id](Result result) { - send_closure_later(actor_id, &MessagesManager::on_imported_message_attachments_uploaded, random_id, - std::move(result)); - })); - auto lock_promise = multipromise.get_promise(); - - for (auto attached_file_id : attached_file_ids) { - upload_imported_message_attachment(dialog_id, import_id, - td_->file_manager_->dup_file_id(attached_file_id, "start_import_messages"), - false, multipromise.get_promise()); - } - - lock_promise.set_value(Unit()); -} - -void MessagesManager::upload_imported_message_attachment(DialogId dialog_id, int64 import_id, FileId file_id, - bool is_reupload, Promise &&promise, - vector bad_parts) { - CHECK(file_id.is_valid()); - LOG(INFO) << "Ask to upload improted message attached file " << file_id; - auto info = - td::make_unique(dialog_id, import_id, is_reupload, std::move(promise)); - bool is_inserted = being_uploaded_imported_message_attachments_.emplace(file_id, std::move(info)).second; - CHECK(is_inserted); - // TODO use force_reupload if is_reupload - td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_imported_message_attachment_callback_, 1, 0, - false, true); -} - -void MessagesManager::on_imported_message_attachments_uploaded(int64 random_id, Result &&result) { - G()->ignore_result_if_closing(result); - - auto it = pending_message_imports_.find(random_id); - CHECK(it != pending_message_imports_.end()); - - auto pending_message_import = std::move(it->second); - CHECK(pending_message_import != nullptr); - - pending_message_imports_.erase(it); - - if (result.is_error()) { - pending_message_import->promise.set_error(result.move_as_error()); - return; - } - - CHECK(pending_message_import->upload_files_multipromise.promise_count() == 0); - - auto promise = std::move(pending_message_import->promise); - auto dialog_id = pending_message_import->dialog_id; - - TRY_STATUS_PROMISE(promise, can_send_message(dialog_id)); - - td_->create_handler(std::move(promise))->send(dialog_id, pending_message_import->import_id); -} - -bool MessagesManager::on_update_message_id(int64 random_id, MessageId new_message_id, const string &source) { +bool MessagesManager::on_update_message_id(int64 random_id, MessageId new_message_id, const char *source) { if (!new_message_id.is_valid() && !new_message_id.is_valid_scheduled()) { LOG(ERROR) << "Receive " << new_message_id << " in updateMessageId with random_id " << random_id << " from " << source; @@ -28652,39 +27556,19 @@ bool MessagesManager::on_update_message_id(int64 random_id, MessageId new_messag if (new_message_id.is_scheduled()) { update_scheduled_message_ids_[dialog_id][new_message_id.get_scheduled_server_message_id()] = old_message_id; } else { - update_message_ids_[FullMessageId(dialog_id, new_message_id)] = old_message_id; + update_message_ids_[MessageFullId(dialog_id, new_message_id)] = old_message_id; } return true; } -bool MessagesManager::on_get_dialog_error(DialogId dialog_id, const Status &status, const char *source) { - if (status.message() == CSlice("BOT_METHOD_INVALID")) { - LOG(ERROR) << "Receive BOT_METHOD_INVALID from " << source; - return true; - } - if (G()->is_expected_error(status)) { +bool MessagesManager::on_get_message_error(DialogId dialog_id, MessageId message_id, const Status &status, + const char *source) { + if (status.message() == "MSG_ID_INVALID" || status.message() == "MESSAGE_ID_INVALID" || + status.message() == "DATA_INVALID") { + get_message_from_server({dialog_id, message_id}, Promise(), source); return true; } - if (status.message() == CSlice("SEND_AS_PEER_INVALID")) { - reload_dialog_info_full(dialog_id, "SEND_AS_PEER_INVALID"); - return true; - } - - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::Chat: - case DialogType::SecretChat: - // to be implemented if necessary - break; - case DialogType::Channel: - return td_->contacts_manager_->on_get_channel_error(dialog_id.get_channel_id(), status, source); - case DialogType::None: - // to be implemented if necessary - break; - default: - UNREACHABLE(); - } - return false; + return td_->dialog_manager_->on_get_dialog_error(dialog_id, status, source); } void MessagesManager::on_dialog_updated(DialogId dialog_id, const char *source) { @@ -28703,33 +27587,29 @@ void MessagesManager::send_update_new_message(const Dialog *d, const Message *m) td_api::make_object(get_message_object(d->dialog_id, m, "send_update_new_message"))); } -MessagesManager::NotificationGroupInfo &MessagesManager::get_notification_group_info(Dialog *d, bool from_mentions) { +NotificationGroupInfo &MessagesManager::get_notification_group_info(Dialog *d, bool from_mentions) { CHECK(d != nullptr); auto notification_info = add_dialog_notification_info(d); return from_mentions ? notification_info->mention_notification_group_ : notification_info->message_notification_group_; } -MessagesManager::NotificationGroupInfo &MessagesManager::get_notification_group_info(Dialog *d, const Message *m) { +NotificationGroupInfo &MessagesManager::get_notification_group_info(Dialog *d, const Message *m) { return get_notification_group_info(d, is_from_mention_notification_group(m)); } NotificationGroupId MessagesManager::get_dialog_notification_group_id(DialogId dialog_id, NotificationGroupInfo &group_info) { - if (td_->auth_manager_->is_bot()) { - // just in case - return NotificationGroupId(); - } - if (!group_info.group_id.is_valid()) { + CHECK(!td_->auth_manager_->is_bot()); + if (!group_info.is_valid()) { NotificationGroupId next_notification_group_id; do { next_notification_group_id = td_->notification_manager_->get_next_notification_group_id(); if (!next_notification_group_id.is_valid()) { return NotificationGroupId(); } - } while (get_message_notification_group_force(next_notification_group_id).dialog_id.is_valid()); - group_info.group_id = next_notification_group_id; - group_info.is_changed = true; + } while (td_->notification_manager_->have_group_force(next_notification_group_id)); + group_info = NotificationGroupInfo(next_notification_group_id); VLOG(notifications) << "Assign " << next_notification_group_id << " to " << dialog_id; on_dialog_updated(dialog_id, "get_dialog_notification_group_id"); @@ -28740,20 +27620,19 @@ NotificationGroupId MessagesManager::get_dialog_notification_group_id(DialogId d next_notification_group_id); } } - - CHECK(group_info.group_id.is_valid()); + CHECK(group_info.is_valid()); // notification group must be preloaded to guarantee that there is no race between // get_message_notifications_from_database_force and new notifications added right now - td_->notification_manager_->load_group_force(group_info.group_id); + td_->notification_manager_->load_group_force(group_info.get_group_id()); - return group_info.group_id; + return group_info.get_group_id(); } Result MessagesManager::get_message_push_notification_info( DialogId dialog_id, MessageId message_id, int64 random_id, UserId sender_user_id, DialogId sender_dialog_id, int32 date, bool is_from_scheduled, bool contains_mention, bool is_pinned, bool is_from_binlog) { - if (!is_from_scheduled && dialog_id == get_my_dialog_id()) { + if (!is_from_scheduled && dialog_id == td_->dialog_manager_->get_my_dialog_id()) { return Status::Error("Ignore notification in chat with self"); } if (td_->auth_manager_->is_bot()) { @@ -28768,24 +27647,24 @@ Result MessagesManager::get_messag return Status::Error(406, "Ignore notification sent by unknown chat"); } - if (is_from_scheduled && dialog_id != get_my_dialog_id() && + if (is_from_scheduled && dialog_id != td_->dialog_manager_->get_my_dialog_id() && td_->option_manager_->get_option_boolean("disable_sent_scheduled_message_notifications")) { return Status::Error("Ignore notification about sent scheduled message"); } bool is_new_pinned = is_pinned && message_id.is_valid() && - (d->notification_info == nullptr || message_id > d->notification_info->max_notification_message_id_); + (d->notification_info == nullptr || message_id > d->notification_info->max_push_notification_message_id_); CHECK(!message_id.is_scheduled()); if (message_id.is_valid()) { if (message_id <= d->last_new_message_id) { return Status::Error("Ignore notification about known message"); } if (!is_from_binlog && d->notification_info != nullptr) { - if (message_id == d->notification_info->max_notification_message_id_) { + if (message_id == d->notification_info->max_push_notification_message_id_) { return Status::Error("Ignore previously added message push notification"); } - if (message_id < d->notification_info->max_notification_message_id_) { + if (message_id < d->notification_info->max_push_notification_message_id_) { return Status::Error("Ignore out of order message push notification"); } } @@ -28852,13 +27731,12 @@ Result MessagesManager::get_messag if (message_id.is_valid()) { auto notification_info = add_dialog_notification_info(d); - if (message_id > notification_info->max_notification_message_id_) { - if (is_new_pinned) { - set_dialog_pinned_message_notification(d, contains_mention ? message_id : MessageId(), - "get_message_push_notification_info"); + if (message_id > notification_info->max_push_notification_message_id_) { + if (is_new_pinned && contains_mention) { + set_dialog_pinned_message_notification(d, message_id, "get_message_push_notification_info"); } - notification_info->max_notification_message_id_ = message_id; - on_dialog_updated(dialog_id, "set_max_notification_message_id"); + notification_info->max_push_notification_message_id_ = message_id; + on_dialog_updated(dialog_id, "set_max_push_notification_message_id"); } } @@ -28882,19 +27760,15 @@ NotificationId MessagesManager::get_next_notification_id(NotificationInfo *notif } } while (notification_info->notification_id_to_message_id_.count(notification_id) != 0 || notification_info->new_secret_chat_notification_id_ == notification_id || - notification_id.get() <= notification_info->message_notification_group_.last_notification_id.get() || - notification_id.get() <= notification_info->message_notification_group_.max_removed_notification_id.get() || - notification_id.get() <= notification_info->mention_notification_group_.last_notification_id.get() || - notification_id.get() <= - notification_info->mention_notification_group_.max_removed_notification_id.get()); // just in case + notification_info->message_notification_group_.is_used_notification_id(notification_id) || + notification_info->mention_notification_group_.is_used_notification_id(notification_id)); // just in case if (message_id.is_valid()) { add_notification_id_to_message_id_correspondence(notification_info, notification_id, message_id); } return notification_id; } -MessagesManager::MessageNotificationGroup MessagesManager::get_message_notification_group_force( - NotificationGroupId group_id) { +NotificationGroupFromDatabase MessagesManager::get_message_notification_group_force(NotificationGroupId group_id) { CHECK(!td_->auth_manager_->is_bot()); CHECK(group_id.is_valid()); Dialog *d = nullptr; @@ -28917,33 +27791,27 @@ MessagesManager::MessageNotificationGroup MessagesManager::get_message_notificat } if (d == nullptr || d->notification_info == nullptr) { - return MessageNotificationGroup(); + return NotificationGroupFromDatabase(); } - if (d->notification_info->message_notification_group_.group_id != group_id && - d->notification_info->mention_notification_group_.group_id != group_id) { + if (!is_dialog_notification_group_id(d, group_id)) { if (d->dialog_id.get_type() == DialogType::SecretChat && - !d->notification_info->message_notification_group_.group_id.is_valid() && - !d->notification_info->mention_notification_group_.group_id.is_valid()) { + !d->notification_info->message_notification_group_.is_valid() && + !d->notification_info->mention_notification_group_.is_valid()) { // the group was reused, but wasn't deleted from the database, trying to resave it auto &group_info = d->notification_info->message_notification_group_; - group_info.group_id = group_id; - group_info.is_changed = true; - group_info.try_reuse = true; + group_info = NotificationGroupInfo(group_id); + group_info.try_reuse(); save_dialog_to_database(d->dialog_id); - group_info.group_id = NotificationGroupId(); - group_info.is_changed = false; - group_info.try_reuse = false; + group_info = NotificationGroupInfo(); } + CHECK(is_dialog_notification_group_id(d, group_id)); } - LOG_CHECK(d->notification_info->message_notification_group_.group_id == group_id || - d->notification_info->mention_notification_group_.group_id == group_id); - - bool from_mentions = d->notification_info->mention_notification_group_.group_id == group_id; + bool from_mentions = d->notification_info->mention_notification_group_.has_group_id(group_id); auto &group_info = get_notification_group_info(d, from_mentions); - MessageNotificationGroup result; - VLOG(notifications) << "Found " << (from_mentions ? "Mentions " : "Messages ") << group_info.group_id << '/' + NotificationGroupFromDatabase result; + VLOG(notifications) << "Found " << (from_mentions ? "Mentions " : "Messages ") << group_info.get_group_id() << '/' << d->dialog_id << " by " << group_id << " with " << d->unread_mention_count << " unread mentions, " << d->unread_reaction_count << " unread reactions, pinned " << d->notification_info->pinned_message_notification_message_id_ << ", new secret chat " @@ -28963,7 +27831,7 @@ MessagesManager::MessageNotificationGroup MessagesManager::get_message_notificat CHECK(d->dialog_id.get_type() == DialogType::SecretChat); result.type = NotificationGroupType::SecretChat; result.notifications.emplace_back(d->notification_info->new_secret_chat_notification_id_, - td_->contacts_manager_->get_secret_chat_date(d->dialog_id.get_secret_chat_id()), + td_->user_manager_->get_secret_chat_date(d->dialog_id.get_secret_chat_id()), false, create_new_secret_chat_notification()); } else { result.type = from_mentions ? NotificationGroupType::Mentions : NotificationGroupType::Messages; @@ -28977,15 +27845,8 @@ MessagesManager::MessageNotificationGroup MessagesManager::get_message_notificat last_notification_date = result.notifications[0].date; last_notification_id = result.notifications[0].notification_id; } - if (last_notification_date != group_info.last_notification_date || - last_notification_id != group_info.last_notification_id) { - LOG(ERROR) << "Fix last notification date in " << d->dialog_id << " from " << group_info.last_notification_date - << " to " << last_notification_date << " and last notification identifier from " - << group_info.last_notification_id << " to " << last_notification_id << " in " << group_id << " of type " - << result.type; - set_dialog_last_notification(d->dialog_id, group_info, last_notification_date, last_notification_id, - "get_message_notification_group_force"); - } + set_dialog_last_notification(d->dialog_id, group_info, last_notification_date, last_notification_id, + "get_message_notification_group_force"); std::reverse(result.notifications.begin(), result.notifications.end()); @@ -28996,7 +27857,7 @@ bool MessagesManager::get_dialog_show_preview(const Dialog *d) const { CHECK(!td_->auth_manager_->is_bot()); CHECK(d != nullptr); if (d->notification_settings.use_default_show_preview) { - auto scope = get_dialog_notification_setting_scope(d->dialog_id); + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(d->dialog_id); return td_->notification_settings_manager_->get_scope_show_preview(scope); } else { return d->notification_settings.show_preview; @@ -29016,7 +27877,7 @@ bool MessagesManager::is_message_preview_enabled(const Dialog *d, const Message } d = get_dialog_force(sender_dialog_id, "is_message_preview_enabled"); if (d == nullptr) { - auto scope = get_dialog_notification_setting_scope(sender_dialog_id); + auto scope = td_->dialog_manager_->get_dialog_notification_setting_scope(sender_dialog_id); return td_->notification_settings_manager_->get_scope_show_preview(scope); } return get_dialog_show_preview(d); @@ -29037,15 +27898,13 @@ bool MessagesManager::is_message_notification_active(const Dialog *d, const Mess } } if (is_from_mention_notification_group(m)) { - return m->notification_id.get() > - d->notification_info->mention_notification_group_.max_removed_notification_id.get() && - m->message_id > d->notification_info->mention_notification_group_.max_removed_message_id && + return !d->notification_info->mention_notification_group_.is_removed_notification(m->notification_id, + m->message_id) && (m->contains_unread_mention || m->message_id == d->notification_info->pinned_message_notification_message_id_); } else { - return m->notification_id.get() > - d->notification_info->message_notification_group_.max_removed_notification_id.get() && - m->message_id > d->notification_info->message_notification_group_.max_removed_message_id && + return !d->notification_info->message_notification_group_.is_removed_notification(m->notification_id, + m->message_id) && m->message_id > d->last_read_inbox_message_id; } } @@ -29064,8 +27923,7 @@ void MessagesManager::try_add_pinned_message_notification(Dialog *d, vectornotification_id.get() > d->notification_info->mention_notification_group_.max_removed_notification_id.get() && - m->message_id > d->notification_info->mention_notification_group_.max_removed_message_id && + !d->notification_info->mention_notification_group_.is_removed_notification(m->notification_id, m->message_id) && m->message_id > d->last_read_inbox_message_id && !is_dialog_pinned_message_notifications_disabled(d)) { if (m->notification_id.get() < max_notification_id.get()) { VLOG(notifications) << "Add " << m->notification_id << " about pinned " << message_id << " in " << d->dialog_id; @@ -29077,11 +27935,12 @@ void MessagesManager::try_add_pinned_message_notification(Dialog *d, vectornotification_id, m->date, m->disable_notification, create_new_message_notification(message_id, is_message_preview_enabled(d, m, true))); - while (pos > 0 && res[pos - 1].type->get_message_id() < message_id) { + NotificationObjectId object_id(message_id); + while (pos > 0 && res[pos - 1].type->get_object_id() < object_id) { std::swap(res[pos - 1], res[pos]); pos--; } - if (pos > 0 && res[pos - 1].type->get_message_id() == message_id) { + if (pos > 0 && res[pos - 1].type->get_object_id() == object_id) { res.erase(res.begin() + pos); // notification was already there } if (res.size() > static_cast(limit)) { @@ -29117,7 +27976,7 @@ vector MessagesManager::get_message_notifications_from_database_fo bool is_found = false; VLOG(notifications) << "Loaded " << messages.size() << (from_mentions ? " mention" : "") - << " messages with notifications from database in " << group_info.group_id << '/' + << " messages with notifications from database in " << group_info.get_group_id() << '/' << d->dialog_id; for (auto &message : messages) { auto m = on_get_message_from_database(d, message, false, "get_message_notifications_from_database_force"); @@ -29128,8 +27987,13 @@ vector MessagesManager::get_message_notifications_from_database_fo auto notification_id = m->notification_id.is_valid() ? m->notification_id : m->removed_notification_id; if (!notification_id.is_valid()) { - LOG(ERROR) << "Can't find notification identifier for " << m->message_id << " in " << d->dialog_id - << " with from_mentions = " << from_mentions; + if (from_mentions) { + VLOG(notifications) << "Receive " << m->message_id << " with unread mention, but without notification"; + is_found = false; + } else { + LOG(ERROR) << "Can't find notification identifier for " << m->message_id << " in " << d->dialog_id + << " with from_mentions = " << from_mentions; + } continue; } CHECK(m->message_id.is_valid()); @@ -29153,11 +28017,9 @@ vector MessagesManager::get_message_notifications_from_database_fo is_found = true; } - if (notification_id.get() <= group_info.max_removed_notification_id.get() || - m->message_id <= group_info.max_removed_message_id || + if (group_info.is_removed_notification(notification_id, m->message_id) || (!from_mentions && m->message_id <= d->last_read_inbox_message_id)) { - // if message still has notification_id, but it was removed via max_removed_notification_id, - // or max_removed_message_id, or last_read_inbox_message_id, + // if message still has notification_id, but it was removed, // then there will be no more messages with active notifications is_found = false; break; @@ -29246,9 +28108,7 @@ vector MessagesManager::get_message_notification_group_key CHECK(group_key.group_id.is_valid()); CHECK(group_key.dialog_id.is_valid()); const Dialog *d = get_dialog_force(group_key.dialog_id, "get_message_notification_group_keys_from_database"); - if (d == nullptr || d->notification_info == nullptr || - (d->notification_info->message_notification_group_.group_id != group_key.group_id && - d->notification_info->mention_notification_group_.group_id != group_key.group_id)) { + if (!is_dialog_notification_group_id(d, group_key.group_id)) { continue; } @@ -29280,19 +28140,18 @@ void MessagesManager::get_message_notifications_from_database(DialogId dialog_id auto d = get_dialog(dialog_id); CHECK(d != nullptr); - if (d->notification_info == nullptr || (d->notification_info->message_notification_group_.group_id != group_id && - d->notification_info->mention_notification_group_.group_id != group_id)) { + if (!is_dialog_notification_group_id(d, group_id)) { return promise.set_value(vector()); } VLOG(notifications) << "Get " << limit << " message notifications from database in " << group_id << " from " << dialog_id << " from " << from_notification_id << "/" << from_message_id; - bool from_mentions = d->notification_info->mention_notification_group_.group_id == group_id; + bool from_mentions = d->notification_info->mention_notification_group_.has_group_id(group_id); if (d->notification_info->new_secret_chat_notification_id_.is_valid()) { CHECK(dialog_id.get_type() == DialogType::SecretChat); vector notifications; if (!from_mentions && d->notification_info->new_secret_chat_notification_id_.get() < from_notification_id.get()) { - auto date = td_->contacts_manager_->get_secret_chat_date(dialog_id.get_secret_chat_id()); + auto date = td_->user_manager_->get_secret_chat_date(dialog_id.get_secret_chat_id()); if (date <= 0) { remove_new_secret_chat_notification(d, true); } else { @@ -29316,8 +28175,7 @@ void MessagesManager::do_get_message_notifications_from_database(Dialog *d, bool CHECK(!from_message_id.is_scheduled()); auto &group_info = get_notification_group_info(d, from_mentions); - if (from_notification_id.get() <= group_info.max_removed_notification_id.get() || - from_message_id <= group_info.max_removed_message_id || + if (!group_info.is_valid() || group_info.is_removed_notification(from_notification_id, from_message_id) || (!from_mentions && from_message_id <= d->last_read_inbox_message_id)) { return promise.set_value(vector()); } @@ -29332,12 +28190,12 @@ void MessagesManager::do_get_message_notifications_from_database(Dialog *d, bool auto *db = G()->td_db()->get_message_db_async(); if (!from_mentions) { - VLOG(notifications) << "Trying to load " << limit << " messages with notifications in " << group_info.group_id + VLOG(notifications) << "Trying to load " << limit << " messages with notifications in " << group_info.get_group_id() << '/' << dialog_id << " from " << from_notification_id; return db->get_messages_from_notification_id(d->dialog_id, from_notification_id, limit, std::move(new_promise)); } else { - VLOG(notifications) << "Trying to load " << limit << " messages with unread mentions in " << group_info.group_id - << '/' << dialog_id << " from " << from_message_id; + VLOG(notifications) << "Trying to load " << limit << " messages with unread mentions in " + << group_info.get_group_id() << '/' << dialog_id << " from " << from_message_id; // ignore first_db_message_id, notifications can be nonconsecutive MessageDbMessagesQuery db_query; @@ -29364,7 +28222,7 @@ void MessagesManager::on_get_message_notifications_from_database(DialogId dialog CHECK(d != nullptr); auto &group_info = get_notification_group_info(d, from_mentions); - if (!group_info.group_id.is_valid()) { + if (!group_info.is_valid()) { return promise.set_error(Status::Error("Notification group was deleted")); } @@ -29373,7 +28231,7 @@ void MessagesManager::on_get_message_notifications_from_database(DialogId dialog res.reserve(messages.size()); NotificationId from_notification_id; MessageId from_message_id; - VLOG(notifications) << "Loaded " << messages.size() << " messages with notifications in " << group_info.group_id + VLOG(notifications) << "Loaded " << messages.size() << " messages with notifications in " << group_info.get_group_id() << '/' << dialog_id << " from database"; for (auto &message : messages) { auto m = on_get_message_from_database(d, message, false, "on_get_message_notifications_from_database"); @@ -29384,8 +28242,13 @@ void MessagesManager::on_get_message_notifications_from_database(DialogId dialog auto notification_id = m->notification_id.is_valid() ? m->notification_id : m->removed_notification_id; if (!notification_id.is_valid()) { - LOG(ERROR) << "Can't find notification identifier for " << m->message_id << " in " << d->dialog_id - << " with from_mentions = " << from_mentions; + if (from_mentions) { + VLOG(notifications) << "Receive " << m->message_id << " with unread mention, but without notification"; + from_notification_id = NotificationId(); // stop requesting database + } else { + LOG(ERROR) << "Can't find notification identifier for " << m->message_id << " in " << d->dialog_id + << " with from_mentions = " << from_mentions; + } continue; } CHECK(m->message_id.is_valid()); @@ -29406,8 +28269,7 @@ void MessagesManager::on_get_message_notifications_from_database(DialogId dialog from_message_id = m->message_id; } - if (notification_id.get() <= group_info.max_removed_notification_id.get() || - m->message_id <= group_info.max_removed_message_id || + if (group_info.is_removed_notification(notification_id, m->message_id) || (!from_mentions && m->message_id <= d->last_read_inbox_message_id)) { // if message still has notification_id, but it was removed via max_removed_notification_id, // or max_removed_message_id, or last_read_inbox_message_id, @@ -29463,12 +28325,7 @@ void MessagesManager::on_get_message_notifications_from_database(DialogId dialog void MessagesManager::remove_message_notification(DialogId dialog_id, NotificationGroupId group_id, NotificationId notification_id) { Dialog *d = get_dialog_force(dialog_id, "remove_message_notification"); - if (d == nullptr) { - LOG(ERROR) << "Can't find " << dialog_id; - return; - } - if (d->notification_info == nullptr || (d->notification_info->message_notification_group_.group_id != group_id && - d->notification_info->mention_notification_group_.group_id != group_id)) { + if (!is_dialog_notification_group_id(d, group_id)) { LOG(ERROR) << "There is no " << group_id << " in " << dialog_id; return; } @@ -29476,7 +28333,7 @@ void MessagesManager::remove_message_notification(DialogId dialog_id, Notificati return; // there can be no notification with this ID } - bool from_mentions = d->notification_info->mention_notification_group_.group_id == group_id; + bool from_mentions = d->notification_info->mention_notification_group_.has_group_id(group_id); if (d->notification_info->new_secret_chat_notification_id_.is_valid()) { if (!from_mentions && d->notification_info->new_secret_chat_notification_id_ == notification_id) { return remove_new_secret_chat_notification(d, false); @@ -29499,8 +28356,8 @@ void MessagesManager::remove_message_notification(DialogId dialog_id, Notificati if (G()->use_message_database()) { G()->td_db()->get_message_db_async()->get_messages_from_notification_id( dialog_id, NotificationId(notification_id.get() + 1), 1, - PromiseCreator::lambda([dialog_id, from_mentions, notification_id, - actor_id = actor_id(this)](vector result) { + PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, from_mentions, + notification_id](vector result) { send_closure(actor_id, &MessagesManager::do_remove_message_notification, dialog_id, from_mentions, notification_id, std::move(result)); })); @@ -29526,11 +28383,11 @@ void MessagesManager::remove_message_notifications_by_message_ids(DialogId dialo if (message == nullptr) { LOG(INFO) << "Can't delete " << message_id << " because it is not found"; // call synchronously to remove them before ProcessPush returns - td_->notification_manager_->remove_temporary_notification_by_message_id( - d->notification_info->message_notification_group_.group_id, message_id, true, + td_->notification_manager_->remove_temporary_notification_by_object_id( + d->notification_info->message_notification_group_.get_group_id(), message_id, true, "remove_message_notifications_by_message_ids"); - td_->notification_manager_->remove_temporary_notification_by_message_id( - d->notification_info->mention_notification_group_.group_id, message_id, true, + td_->notification_manager_->remove_temporary_notification_by_object_id( + d->notification_info->mention_notification_group_.get_group_id(), message_id, true, "remove_message_notifications_by_message_ids"); continue; } @@ -29546,7 +28403,7 @@ void MessagesManager::remove_message_notifications_by_message_ids(DialogId dialo void MessagesManager::do_remove_message_notification(DialogId dialog_id, bool from_mentions, NotificationId notification_id, vector result) { - if (result.empty() || G()->close_flag()) { + if (G()->close_flag() || result.empty()) { return; } CHECK(result.size() == 1); @@ -29564,12 +28421,7 @@ void MessagesManager::do_remove_message_notification(DialogId dialog_id, bool fr void MessagesManager::remove_message_notifications(DialogId dialog_id, NotificationGroupId group_id, NotificationId max_notification_id, MessageId max_message_id) { Dialog *d = get_dialog_force(dialog_id, "remove_message_notifications"); - if (d == nullptr) { - LOG(ERROR) << "Can't find " << dialog_id; - return; - } - if (d->notification_info == nullptr || (d->notification_info->message_notification_group_.group_id != group_id && - d->notification_info->mention_notification_group_.group_id != group_id)) { + if (!is_dialog_notification_group_id(d, group_id)) { LOG(ERROR) << "There is no " << group_id << " in " << dialog_id; return; } @@ -29578,7 +28430,7 @@ void MessagesManager::remove_message_notifications(DialogId dialog_id, Notificat } CHECK(!max_message_id.is_scheduled()); - bool from_mentions = d->notification_info->mention_notification_group_.group_id == group_id; + bool from_mentions = d->notification_info->mention_notification_group_.has_group_id(group_id); if (d->notification_info->new_secret_chat_notification_id_.is_valid()) { if (!from_mentions && d->notification_info->new_secret_chat_notification_id_.get() <= max_notification_id.get()) { return remove_new_secret_chat_notification(d, false); @@ -29586,25 +28438,9 @@ void MessagesManager::remove_message_notifications(DialogId dialog_id, Notificat return; } auto &group_info = get_notification_group_info(d, from_mentions); - if (max_notification_id.get() <= group_info.max_removed_notification_id.get()) { - return; - } - if (max_message_id > group_info.max_removed_message_id) { - VLOG(notifications) << "Set max_removed_message_id in " << group_info.group_id << '/' << dialog_id << " to " - << max_message_id; - group_info.max_removed_message_id = max_message_id.get_prev_server_message_id(); - } - - VLOG(notifications) << "Set max_removed_notification_id in " << group_info.group_id << '/' << dialog_id << " to " - << max_notification_id; - group_info.max_removed_notification_id = max_notification_id; - on_dialog_updated(dialog_id, "remove_message_notifications"); - - if (group_info.last_notification_id.is_valid() && - max_notification_id.get() >= group_info.last_notification_id.get()) { - bool is_changed = - set_dialog_last_notification(dialog_id, group_info, 0, NotificationId(), "remove_message_notifications"); - CHECK(is_changed); + if (group_info.set_max_removed_notification_id(max_notification_id, max_message_id.get_prev_server_message_id(), + "remove_message_notifications")) { + on_dialog_updated(dialog_id, "remove_message_notifications"); } } @@ -29632,7 +28468,7 @@ int32 MessagesManager::get_dialog_pending_notification_count(const Dialog *d, bo void MessagesManager::update_dialog_mention_notification_count(const Dialog *d) { CHECK(d != nullptr); if (td_->auth_manager_->is_bot() || d->notification_info == nullptr || - !d->notification_info->mention_notification_group_.group_id.is_valid()) { + !d->notification_info->mention_notification_group_.is_valid()) { return; } auto total_count = get_dialog_pending_notification_count(d, true) - @@ -29643,7 +28479,7 @@ void MessagesManager::update_dialog_mention_notification_count(const Dialog *d) total_count = 0; } send_closure_later(G()->notification_manager(), &NotificationManager::set_notification_total_count, - d->notification_info->mention_notification_group_.group_id, total_count); + d->notification_info->mention_notification_group_.get_group_id(), total_count); } bool MessagesManager::is_message_notification_disabled(const Dialog *d, const Message *m) const { @@ -29653,11 +28489,11 @@ bool MessagesManager::is_message_notification_disabled(const Dialog *d, const Me if (!has_incoming_notification(d->dialog_id, m) || td_->auth_manager_->is_bot()) { return true; } - if (m->is_from_scheduled && d->dialog_id != get_my_dialog_id() && + if (m->is_from_scheduled && d->dialog_id != td_->dialog_manager_->get_my_dialog_id() && td_->option_manager_->get_option_boolean("disable_sent_scheduled_message_notifications")) { return true; } - if (m->forward_info != nullptr && m->forward_info->is_imported) { + if (m->forward_info != nullptr && m->forward_info->is_imported()) { return true; } @@ -29667,10 +28503,13 @@ bool MessagesManager::is_message_notification_disabled(const Dialog *d, const Me case MessageContentType::Unsupported: case MessageContentType::ExpiredPhoto: case MessageContentType::ExpiredVideo: + case MessageContentType::ExpiredVideoNote: + case MessageContentType::ExpiredVoiceNote: case MessageContentType::PassportDataSent: case MessageContentType::PassportDataReceived: case MessageContentType::WebViewDataSent: case MessageContentType::WebViewDataReceived: + case MessageContentType::GiveawayLaunch: VLOG(notifications) << "Disable notification for " << m->message_id << " in " << d->dialog_id << " with content of type " << m->content->get_type(); return true; @@ -29691,18 +28530,18 @@ bool MessagesManager::is_dialog_message_notification_disabled(DialogId dialog_id case DialogType::User: break; case DialogType::Chat: - if (!td_->contacts_manager_->get_chat_is_active(dialog_id.get_chat_id())) { + if (!td_->chat_manager_->get_chat_is_active(dialog_id.get_chat_id())) { return true; } break; case DialogType::Channel: - if (!td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()).is_member() || - message_date < td_->contacts_manager_->get_channel_date(dialog_id.get_channel_id())) { + if (!td_->chat_manager_->get_channel_status(dialog_id.get_channel_id()).is_member() || + message_date < td_->chat_manager_->get_channel_date(dialog_id.get_channel_id())) { return true; } break; case DialogType::SecretChat: - if (td_->contacts_manager_->get_secret_chat_state(dialog_id.get_secret_chat_id()) == SecretChatState::Closed) { + if (td_->user_manager_->get_secret_chat_state(dialog_id.get_secret_chat_id()) == SecretChatState::Closed) { return true; } break; @@ -29742,13 +28581,15 @@ bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f CHECK(m->message_id.is_valid()); if (!force && d->notification_info != nullptr) { - if (d->notification_info->message_notification_group_.group_id.is_valid()) { + if (d->notification_info->message_notification_group_.is_valid()) { send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notifications, - d->notification_info->message_notification_group_.group_id, "add_new_message_notification 1"); + d->notification_info->message_notification_group_.get_group_id(), + "add_new_message_notification 1"); } - if (d->notification_info->mention_notification_group_.group_id.is_valid()) { + if (d->notification_info->mention_notification_group_.is_valid()) { send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notifications, - d->notification_info->mention_notification_group_.group_id, "add_new_message_notification 2"); + d->notification_info->mention_notification_group_.get_group_id(), + "add_new_message_notification 2"); } } @@ -29763,13 +28604,13 @@ bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f from_mentions ? m->contains_unread_mention || is_pinned : m->message_id > d->last_read_inbox_message_id; if (is_active) { auto &group_info = get_notification_group_info(d, from_mentions); - if (group_info.max_removed_message_id >= m->message_id) { + if (group_info.is_removed_object_id(m->message_id)) { is_active = false; } } if (!is_active) { VLOG(notifications) << "Disable inactive notification for " << m->message_id << " in " << d->dialog_id; - if (is_pinned) { + if (is_pinned && from_mentions) { remove_dialog_pinned_message_notification(d, "add_new_message_notification"); } return false; @@ -29795,7 +28636,7 @@ bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f std::tie(have_settings, mute_until) = get_dialog_mute_until(settings_dialog_id, settings_dialog); if (mute_until > m->date && (have_settings || force)) { VLOG(notifications) << "Disable notification, because " << settings_dialog_id << " is muted"; - if (is_pinned) { + if (is_pinned && from_mentions) { remove_dialog_pinned_message_notification(d, "add_new_message_notification"); } return false; @@ -29838,16 +28679,7 @@ bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f send_closure(actor_id, &MessagesManager::flush_pending_new_message_notifications, dialog_id, from_mentions, settings_dialog_id); }); - if (settings_dialog == nullptr && have_input_peer(settings_dialog_id, AccessRights::Read)) { - force_create_dialog(settings_dialog_id, "add_new_message_notification 2"); - settings_dialog = get_dialog(settings_dialog_id); - } - if (settings_dialog != nullptr) { - td_->notification_settings_manager_->send_get_dialog_notification_settings_query( - settings_dialog_id, MessageId() /* TODO */, std::move(promise)); - } else { - send_get_dialog_query(settings_dialog_id, std::move(promise), 0, "add_new_message_notification"); - } + reload_dialog_notification_settings(settings_dialog_id, std::move(promise), "add_new_message_notification"); } if (missing_pinned_message_id.is_valid()) { VLOG(notifications) << "Fetch pinned " << missing_pinned_message_id; @@ -29876,27 +28708,25 @@ bool MessagesManager::add_new_message_notification(Dialog *d, Message *m, bool f if (!m->notification_id.is_valid()) { return false; } - bool is_changed = set_dialog_last_notification(d->dialog_id, group_info, m->date, m->notification_id, - "add_new_message_notification 3"); - CHECK(is_changed); - if (is_pinned) { - set_dialog_pinned_message_notification(d, from_mentions ? m->message_id : MessageId(), - "add_new_message_notification"); + set_dialog_last_notification_checked(d->dialog_id, group_info, m->date, m->notification_id, + "add_new_message_notification 3"); + if (is_pinned && from_mentions) { + set_dialog_pinned_message_notification(d, m->message_id, "add_new_message_notification"); } if (!m->notification_id.is_valid()) { // protection from accidental notification_id removal in set_dialog_pinned_message_notification return false; } - VLOG(notifications) << "Create " << m->notification_id << " with " << m->message_id << " in " << group_info.group_id - << '/' << d->dialog_id; + VLOG(notifications) << "Create " << m->notification_id << " with " << m->message_id << " in " + << group_info.get_group_id() << '/' << d->dialog_id; int32 min_delay_ms = 0; - if (need_delay_message_content_notification(m->content.get(), td_->contacts_manager_->get_my_id())) { + if (need_delay_message_content_notification(m->content.get(), td_->user_manager_->get_my_id())) { min_delay_ms = 3000; // 3 seconds - } else if (td_->is_online() && d->open_count > 0) { + } else if (td_->online_manager_->is_online() && d->open_count > 0) { min_delay_ms = 1000; // 1 second } auto ringtone_id = get_dialog_notification_ringtone_id(settings_dialog_id, settings_dialog); - bool is_silent = m->disable_notification || m->message_id <= notification_info->max_notification_message_id_; + bool is_silent = m->disable_notification || m->message_id <= notification_info->max_push_notification_message_id_; send_closure_later(G()->notification_manager(), &NotificationManager::add_notification, notification_group_id, from_mentions ? NotificationGroupType::Mentions : NotificationGroupType::Messages, d->dialog_id, m->date, settings_dialog_id, m->disable_notification, is_silent ? 0 : ringtone_id, min_delay_ms, @@ -29933,7 +28763,9 @@ void MessagesManager::flush_pending_new_message_notifications(DialogId dialog_id auto it = pending_notifications.begin(); while (it != pending_notifications.end() && it->first == DialogId()) { auto m = get_message(d, it->second); - if (m != nullptr && add_new_message_notification(d, m, true)) { + if (m == nullptr) { + VLOG(notifications) << "Can't find " << it->second << " in " << dialog_id << " with pending notification"; + } else if (add_new_message_notification(d, m, true)) { on_message_changed(d, m, false, "flush_pending_new_message_notifications"); } ++it; @@ -29947,21 +28779,18 @@ void MessagesManager::flush_pending_new_message_notifications(DialogId dialog_id } void MessagesManager::remove_all_dialog_notifications(Dialog *d, bool from_mentions, const char *source) { - // removes up to group_info.last_notification_id + // removes up to group_info.get_last_notification_id() CHECK(!td_->auth_manager_->is_bot()); if (d->notification_info == nullptr) { return; } NotificationGroupInfo &group_info = get_notification_group_info(d, from_mentions); - if (group_info.group_id.is_valid() && group_info.last_notification_id.is_valid() && - group_info.max_removed_notification_id != group_info.last_notification_id) { - VLOG(notifications) << "Set max_removed_notification_id in " << group_info.group_id << '/' << d->dialog_id << " to " - << group_info.last_notification_id << " from " << source; - group_info.max_removed_notification_id = group_info.last_notification_id; - if (d->notification_info->max_notification_message_id_ > group_info.max_removed_message_id) { - group_info.max_removed_message_id = - d->notification_info->max_notification_message_id_.get_prev_server_message_id(); - } + if (group_info.is_valid() && group_info.get_last_notification_id().is_valid()) { + auto last_notification_id = group_info.get_last_notification_id(); + group_info.set_max_removed_notification_id(last_notification_id, + d->notification_info->max_push_notification_message_id_, source); + on_dialog_updated(d->dialog_id, source); + if (!d->notification_info->pending_new_message_notifications_.empty()) { for (auto &it : d->notification_info->pending_new_message_notifications_) { it.first = DialogId(); @@ -29970,14 +28799,9 @@ void MessagesManager::remove_all_dialog_notifications(Dialog *d, bool from_menti } // remove_message_notifications will be called by NotificationManager send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification_group, - group_info.group_id, group_info.last_notification_id, MessageId(), 0, true, Promise()); - if (d->notification_info->new_secret_chat_notification_id_.is_valid() && - &group_info == &d->notification_info->message_notification_group_) { - remove_new_secret_chat_notification(d, false); - } else { - bool is_changed = set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(), source); - CHECK(is_changed); - } + group_info.get_group_id(), last_notification_id, MessageId(), 0, true, Promise()); + d->notification_info->new_secret_chat_notification_id_ = NotificationId(); + set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(), source); // just in case } } @@ -29990,11 +28814,11 @@ void MessagesManager::remove_message_dialog_notifications(Dialog *d, MessageId m return; } NotificationGroupInfo &group_info = get_notification_group_info(d, from_mentions); - if (!group_info.group_id.is_valid()) { + if (!group_info.is_valid()) { return; } - VLOG(notifications) << "Remove message dialog notifications in " << group_info.group_id << '/' << d->dialog_id + VLOG(notifications) << "Remove message dialog notifications in " << group_info.get_group_id() << '/' << d->dialog_id << " up to " << max_message_id << " from " << source; if (!d->notification_info->pending_new_message_notifications_.empty()) { @@ -30016,18 +28840,32 @@ void MessagesManager::remove_message_dialog_notifications(Dialog *d, MessageId m set_dialog_last_notification(d->dialog_id, group_info, 0, NotificationId(), "remove_message_dialog_notifications 2"); } else { - LOG(FATAL) << "TODO support notification deletion up to " << max_message_id << " if it would be ever needed"; + LOG(FATAL) << "TODO support notification deletion up to " << max_message_id << " if it would be ever needed from " + << source; } - send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification_group, group_info.group_id, - NotificationId(), max_notification_message_id, 0, true, Promise()); + send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification_group, + group_info.get_group_id(), NotificationId(), max_notification_message_id, 0, true, + Promise()); } -void MessagesManager::send_update_message_send_succeeded(const Dialog *d, MessageId old_message_id, const Message *m) { +void MessagesManager::send_update_message_send_succeeded(Dialog *d, MessageId old_message_id, const Message *m, + bool *need_update_dialog_pos) { CHECK(m != nullptr); + CHECK(d != nullptr); CHECK(d->is_update_new_chat_sent); if (!td_->auth_manager_->is_bot()) { - yet_unsent_full_message_id_to_persistent_message_id_.emplace({d->dialog_id, old_message_id}, m->message_id); + yet_unsent_message_full_id_to_persistent_message_id_.emplace({d->dialog_id, old_message_id}, m->message_id); + + auto message = + delete_message(d, m->message_id, false, need_update_dialog_pos, "send_update_message_send_succeeded"); + if (message != nullptr) { + send_update_delete_messages(d->dialog_id, {message->message_id.get()}, false); + } + } + if (old_message_id.is_valid() && m->message_id.is_valid() && m->message_id < old_message_id && + !d->had_yet_unsent_message_id_overflow && m->message_id != MessageId(ServerMessageId(1))) { + LOG(ERROR) << "Sent " << old_message_id << " to " << d->dialog_id << " as " << m->message_id; } send_closure(G()->td(), &Td::send_update, td_api::make_object( @@ -30055,12 +28893,10 @@ void MessagesManager::send_update_message_content_impl(DialogId dialog_id, const return; } LOG(INFO) << "Send updateMessageContent for " << m->message_id << " in " << dialog_id << " from " << source; - auto content_object = get_message_content_object(m->content.get(), td_, dialog_id, m->is_failed_to_send ? 0 : m->date, - m->is_content_secret, need_skip_bot_commands(dialog_id, m), - get_message_max_media_timestamp(m)); send_closure(G()->td(), &Td::send_update, td_api::make_object(get_chat_id_object(dialog_id, "updateMessageContent"), - m->message_id.get(), std::move(content_object))); + m->message_id.get(), + get_message_message_content_object(dialog_id, m))); } void MessagesManager::send_update_message_edited(DialogId dialog_id, const Message *m) { @@ -30070,7 +28906,7 @@ void MessagesManager::send_update_message_edited(DialogId dialog_id, const Messa send_closure(G()->td(), &Td::send_update, td_api::make_object( get_chat_id_object(dialog_id, "updateMessageEdited"), m->message_id.get(), edit_date, - get_reply_markup_object(td_->contacts_manager_.get(), m->reply_markup))); + get_reply_markup_object(td_->user_manager_.get(), m->reply_markup))); } void MessagesManager::send_update_message_interaction_info(DialogId dialog_id, const Message *m) const { @@ -30105,11 +28941,38 @@ void MessagesManager::send_update_message_unread_reactions(DialogId dialog_id, c get_unread_reactions_object(dialog_id, m), unread_reaction_count)); } -void MessagesManager::send_update_message_live_location_viewed(FullMessageId full_message_id) { - CHECK(get_message(full_message_id) != nullptr); +void MessagesManager::send_update_message_fact_check(DialogId dialog_id, const Message *m) const { + CHECK(m != nullptr); + if (td_->auth_manager_->is_bot() || !m->is_update_sent) { + return; + } + + send_closure( + G()->td(), &Td::send_update, + td_api::make_object(get_chat_id_object(dialog_id, "updateMessageFactCheck"), + m->message_id.get(), get_message_fact_check_object(m))); +} + +void MessagesManager::send_update_message_live_location_viewed(MessageFullId message_full_id) { + CHECK(get_message(message_full_id) != nullptr); send_closure(G()->td(), &Td::send_update, - td_api::make_object(full_message_id.get_dialog_id().get(), - full_message_id.get_message_id().get())); + td_api::make_object(message_full_id.get_dialog_id().get(), + message_full_id.get_message_id().get())); +} + +td_api::object_ptr +MessagesManager::get_update_active_live_location_messages_object() const { + auto message_objects = transform(active_live_location_message_full_ids_, [this](MessageFullId message_full_id) { + const auto *m = get_message(message_full_id); + CHECK(m != nullptr); + return get_message_object(message_full_id.get_dialog_id(), m, "send_update_active_live_location_messages"); + }); + return td_api::make_object(std::move(message_objects)); +} + +void MessagesManager::send_update_active_live_location_messages() { + schedule_active_live_location_expiration(); + send_closure(G()->td(), &Td::send_update, get_update_active_live_location_messages_object()); } void MessagesManager::send_update_delete_messages(DialogId dialog_id, vector &&message_ids, @@ -30124,15 +28987,15 @@ void MessagesManager::send_update_delete_messages(DialogId dialog_id, vectormessages.empty()); if ((d->dialog_id.get_type() == DialogType::User || d->dialog_id.get_type() == DialogType::SecretChat) && td_->auth_manager_->is_bot()) { - (void)get_dialog_photo(d->dialog_id); // to apply pending user photo + (void)td_->dialog_manager_->get_dialog_photo(d->dialog_id); // to apply pending user photo } d->is_update_new_chat_being_sent = true; - auto chat_object = get_chat_object(d); + auto chat_object = get_chat_object(d, source); bool has_action_bar = chat_object->action_bar_ != nullptr; bool has_background = chat_object->background_ != nullptr; bool has_theme = !chat_object->theme_name_.empty(); @@ -30152,8 +29015,11 @@ void MessagesManager::send_update_new_chat(Dialog *d) { } } -bool MessagesManager::need_hide_dialog_draft_message(DialogId dialog_id) const { - return is_forum_channel(dialog_id) || can_send_message(dialog_id).is_error(); +bool MessagesManager::need_hide_dialog_draft_message(const Dialog *d) const { + if (d->dialog_id == td_->dialog_manager_->get_my_dialog_id()) { + return false; + } + return get_dialog_view_as_topics(d) || can_send_message(d->dialog_id).is_error(); } void MessagesManager::send_update_chat_draft_message(const Dialog *d) { @@ -30164,12 +29030,25 @@ void MessagesManager::send_update_chat_draft_message(const Dialog *d) { CHECK(d != nullptr); LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_draft_message"; - on_dialog_updated(d->dialog_id, "send_update_chat_draft_message"); - if (d->draft_message == nullptr || !need_hide_dialog_draft_message(d->dialog_id)) { + if (d->draft_message == nullptr || !need_hide_dialog_draft_message(d)) { send_closure(G()->td(), &Td::send_update, td_api::make_object( get_chat_id_object(d->dialog_id, "updateChatDraftMessage"), - get_draft_message_object(d->draft_message), get_chat_positions_object(d))); + get_draft_message_object(td_, d->draft_message), get_chat_positions_object(d))); + + if (d->dialog_id == td_->dialog_manager_->get_my_dialog_id()) { + td_->saved_messages_manager_->on_topic_draft_message_updated( + SavedMessagesTopicId(d->dialog_id), d->draft_message == nullptr ? 0 : d->draft_message->get_date()); + } + } +} + +void MessagesManager::send_update_last_message_if_needed(const Dialog *d, const Message *m, const char *source) const { + if (m->message_id == d->last_message_id) { + send_update_chat_last_message_impl(d, source); + } + if (d->dialog_id == td_->dialog_manager_->get_my_dialog_id() && m->saved_messages_topic_id.is_valid()) { + td_->saved_messages_manager_->on_topic_message_updated(m->saved_messages_topic_id, m->message_id); } } @@ -30205,10 +29084,12 @@ void MessagesManager::send_update_unread_message_count(DialogList &list, DialogI auto dialog_list_id = list.dialog_list_id; CHECK(list.is_message_unread_count_inited_); if (list.unread_message_muted_count_ < 0 || list.unread_message_muted_count_ > list.unread_message_total_count_) { - LOG(ERROR) << "Unread message count became invalid in " << dialog_list_id << ": " - << list.unread_message_total_count_ << '/' - << list.unread_message_total_count_ - list.unread_message_muted_count_ << " from " << source << " and " - << dialog_id; + if (!list.need_unread_count_recalc_) { + LOG(ERROR) << "Unread message count became invalid in " << dialog_list_id << ": " + << list.unread_message_total_count_ << '/' + << list.unread_message_total_count_ - list.unread_message_muted_count_ << " from " << source << " and " + << dialog_id; + } if (list.unread_message_muted_count_ < 0) { list.unread_message_muted_count_ = 0; } @@ -30250,11 +29131,13 @@ void MessagesManager::send_update_unread_chat_count(DialogList &list, DialogId d list.unread_dialog_muted_count_ < list.unread_dialog_muted_marked_count_ || list.unread_dialog_total_count_ + list.unread_dialog_muted_marked_count_ < list.unread_dialog_muted_count_ + list.unread_dialog_marked_count_) { - LOG(ERROR) << "Unread chat count became invalid in " << dialog_list_id << ": " << list.unread_dialog_total_count_ - << '/' << list.unread_dialog_total_count_ - list.unread_dialog_muted_count_ << '/' - << list.unread_dialog_marked_count_ << '/' - << list.unread_dialog_marked_count_ - list.unread_dialog_muted_marked_count_ << " from " << source - << " and " << dialog_id; + if (!list.need_unread_count_recalc_) { + LOG(ERROR) << "Unread chat count became invalid in " << dialog_list_id << ": " << list.unread_dialog_total_count_ + << '/' << list.unread_dialog_total_count_ - list.unread_dialog_muted_count_ << '/' + << list.unread_dialog_marked_count_ << '/' + << list.unread_dialog_marked_count_ - list.unread_dialog_muted_marked_count_ << " from " << source + << " and " << dialog_id; + } if (list.unread_dialog_muted_marked_count_ < 0) { list.unread_dialog_muted_marked_count_ = 0; } @@ -30311,16 +29194,18 @@ void MessagesManager::send_update_chat_read_inbox(const Dialog *d, bool force, c if (!force && (running_get_difference_ || running_get_channel_difference(d->dialog_id) || get_channel_difference_to_log_event_id_.count(d->dialog_id) != 0 || (d->open_count > 0 && d->server_unread_count + d->local_unread_count > 0))) { - LOG(INFO) << "Postpone updateChatReadInbox in " << d->dialog_id << "(" << get_dialog_title(d->dialog_id) << ") to " - << d->server_unread_count << " + " << d->local_unread_count << " from " << source; + LOG(INFO) << "Postpone updateChatReadInbox in " << d->dialog_id << "(" + << td_->dialog_manager_->get_dialog_title(d->dialog_id) << ") to " << d->server_unread_count << " + " + << d->local_unread_count << " from " << source; postponed_chat_read_inbox_updates_.insert(d->dialog_id); if (d->open_count > 0) { send_update_chat_read_inbox_timeout_.add_timeout_in(d->dialog_id.get(), 0.1); } } else { postponed_chat_read_inbox_updates_.erase(d->dialog_id); - LOG(INFO) << "Send updateChatReadInbox in " << d->dialog_id << "(" << get_dialog_title(d->dialog_id) << ") to " - << d->server_unread_count << " + " << d->local_unread_count << " from " << source; + LOG(INFO) << "Send updateChatReadInbox in " << d->dialog_id << "(" + << td_->dialog_manager_->get_dialog_title(d->dialog_id) << ") to " << d->server_unread_count << " + " + << d->local_unread_count << " from " << source; send_closure(G()->td(), &Td::send_update, td_api::make_object( get_chat_id_object(d->dialog_id, "updateChatReadInbox"), d->last_read_inbox_message_id.get(), @@ -30389,16 +29274,6 @@ void MessagesManager::send_update_chat_position(DialogListId dialog_list_id, con std::move(position))); } -void MessagesManager::send_update_chat_online_member_count(DialogId dialog_id, int32 online_member_count) const { - if (td_->auth_manager_->is_bot()) { - return; - } - - send_closure(G()->td(), &Td::send_update, - td_api::make_object( - get_chat_id_object(dialog_id, "updateChatOnlineMemberCount"), online_member_count)); -} - void MessagesManager::send_update_secret_chats_with_user_action_bar(const Dialog *d) const { if (td_->auth_manager_->is_bot()) { return; @@ -30408,7 +29283,7 @@ void MessagesManager::send_update_secret_chats_with_user_action_bar(const Dialog return; } - td_->contacts_manager_->for_each_secret_chat_with_user( + td_->user_manager_->for_each_secret_chat_with_user( d->dialog_id.get_user_id(), [this, user_d = d](SecretChatId secret_chat_id) { DialogId dialog_id(secret_chat_id); auto secret_chat_d = get_dialog(dialog_id); // must not create the dialog @@ -30438,14 +29313,27 @@ void MessagesManager::send_update_chat_action_bar(Dialog *d) { send_update_secret_chats_with_user_action_bar(d); } -void MessagesManager::send_update_chat_available_reactions(const Dialog *d) { +void MessagesManager::send_update_chat_business_bot_manage_bar(Dialog *d) { if (td_->auth_manager_->is_bot()) { return; } + if (d->business_bot_manage_bar != nullptr && d->business_bot_manage_bar->is_empty()) { + d->business_bot_manage_bar = nullptr; + } + + CHECK(d != nullptr); + LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_business_bot_manage_bar"; + on_dialog_updated(d->dialog_id, "send_update_chat_business_bot_manage_bar"); + send_closure( + G()->td(), &Td::send_update, + td_api::make_object( + get_chat_id_object(d->dialog_id, "updateChatBusinessBotManageBar"), get_business_bot_manage_bar_object(d))); +} +void MessagesManager::send_update_chat_available_reactions(const Dialog *d) { CHECK(d != nullptr); LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in send_update_chat_available_reactions"; - auto available_reactions = get_dialog_active_reactions(d).get_chat_available_reactions_object(); + auto available_reactions = get_dialog_active_reactions(d).get_chat_available_reactions_object(td_); send_closure(G()->td(), &Td::send_update, td_api::make_object( get_chat_id_object(d->dialog_id, "updateChatAvailableReactions"), std::move(available_reactions))); @@ -30460,7 +29348,7 @@ void MessagesManager::send_update_secret_chats_with_user_background(const Dialog return; } - td_->contacts_manager_->for_each_secret_chat_with_user( + td_->user_manager_->for_each_secret_chat_with_user( d->dialog_id.get_user_id(), [this, user_d = d](SecretChatId secret_chat_id) { DialogId dialog_id(secret_chat_id); auto secret_chat_d = get_dialog(dialog_id); // must not create the dialog @@ -30497,7 +29385,7 @@ void MessagesManager::send_update_secret_chats_with_user_theme(const Dialog *d) return; } - td_->contacts_manager_->for_each_secret_chat_with_user( + td_->user_manager_->for_each_secret_chat_with_user( d->dialog_id.get_user_id(), [this, user_d = d](SecretChatId secret_chat_id) { DialogId dialog_id(secret_chat_id); auto secret_chat_d = get_dialog(dialog_id); // must not create the dialog @@ -30607,21 +29495,6 @@ void MessagesManager::send_update_chat_has_scheduled_messages(Dialog *d, bool fr get_chat_id_object(d->dialog_id, "updateChatHasScheduledMessages"), has_scheduled_messages)); } -void MessagesManager::send_update_chat_action(DialogId dialog_id, MessageId top_thread_message_id, - DialogId typing_dialog_id, const DialogAction &action) { - if (td_->auth_manager_->is_bot()) { - return; - } - - LOG(DEBUG) << "Send " << action << " of " << typing_dialog_id << " in thread of " << top_thread_message_id << " in " - << dialog_id; - send_closure(G()->td(), &Td::send_update, - td_api::make_object( - get_chat_id_object(dialog_id, "updateChatAction"), top_thread_message_id.get(), - get_message_sender_object(td_, typing_dialog_id, "send_update_chat_action"), - action.get_chat_action_object())); -} - void MessagesManager::on_send_message_get_quick_ack(int64 random_id) { auto it = being_sent_messages_.find(random_id); if (it == being_sent_messages_.end()) { @@ -30637,6 +29510,22 @@ void MessagesManager::on_send_message_get_quick_ack(int64 random_id) { get_chat_id_object(dialog_id, "updateMessageSendAcknowledged"), message_id.get())); } +bool MessagesManager::is_invalid_poll_message(const telegram_api::Message *message) { + CHECK(message != nullptr); + auto constructor_id = message->get_id(); + if (constructor_id != telegram_api::message::ID) { + return false; + } + + auto media = static_cast(message)->media_.get(); + if (media == nullptr || media->get_id() != telegram_api::messageMediaPoll::ID) { + return false; + } + + auto poll = static_cast(media)->poll_.get(); + return !PollId(poll->id_).is_valid(); +} + void MessagesManager::check_send_message_result(int64 random_id, DialogId dialog_id, const telegram_api::Updates *updates_ptr, const char *source) { CHECK(updates_ptr != nullptr); @@ -30644,25 +29533,6 @@ void MessagesManager::check_send_message_result(int64 random_id, DialogId dialog auto sent_messages = UpdatesManager::get_new_messages(updates_ptr); auto sent_messages_random_ids = UpdatesManager::get_sent_messages_random_ids(updates_ptr); - auto is_invalid_poll_message = [](const telegram_api::Message *message) { - CHECK(message != nullptr); - auto constructor_id = message->get_id(); - if (constructor_id == telegram_api::messageEmpty::ID) { - return true; - } - if (constructor_id != telegram_api::message::ID) { - return false; - } - - auto media = static_cast(message)->media_.get(); - if (media == nullptr || media->get_id() != telegram_api::messageMediaPoll::ID) { - return false; - } - - auto poll = static_cast(media)->poll_.get(); - return !PollId(poll->id_).is_valid(); - }; - if (sent_messages.size() != 1u || sent_messages_random_ids.size() != 1u || *sent_messages_random_ids.begin() != random_id || DialogId::get_message_dialog_id(sent_messages[0].first) != dialog_id || @@ -30682,37 +29552,45 @@ void MessagesManager::check_send_message_result(int64 random_id, DialogId dialog void MessagesManager::update_reply_to_message_id(DialogId dialog_id, MessageId old_message_id, MessageId new_message_id, bool have_new_message, const char *source) { - LOG(INFO) << "Update replies of " << FullMessageId{dialog_id, old_message_id} << " to " << new_message_id << " from " + LOG(INFO) << "Update replies of " << MessageFullId{dialog_id, old_message_id} << " to " << new_message_id << " from " << source; - auto it = replied_yet_unsent_messages_.find({dialog_id, old_message_id}); + MessageFullId old_message_full_id(dialog_id, old_message_id); + auto it = replied_yet_unsent_messages_.find(old_message_full_id); if (it == replied_yet_unsent_messages_.end()) { return; } CHECK(old_message_id.is_yet_unsent()); + CHECK(new_message_id == MessageId() || new_message_id.is_valid() || new_message_id.is_valid_scheduled()); - for (auto message_id : it->second) { - CHECK(message_id.is_yet_unsent()); - FullMessageId full_message_id{dialog_id, message_id}; - auto replied_m = get_message(full_message_id); + for (auto message_full_id : it->second) { + auto reply_d = get_dialog(message_full_id.get_dialog_id()); + CHECK(reply_d != nullptr); + auto replied_m = get_message(reply_d, message_full_id.get_message_id()); CHECK(replied_m != nullptr); - CHECK(replied_m->reply_to_message_id == old_message_id); - LOG(INFO) << "Update replied message in " << full_message_id << " from " << old_message_id << " to " - << new_message_id; - unregister_message_reply(dialog_id, replied_m); - replied_m->reply_to_message_id = new_message_id; - // TODO rewrite send message log event - register_message_reply(dialog_id, replied_m); + const auto *input_reply_to = get_message_input_reply_to(replied_m); + CHECK(input_reply_to != nullptr); + CHECK(input_reply_to->get_reply_message_full_id(reply_d->dialog_id) == old_message_full_id); + if (new_message_id != MessageId()) { + LOG_CHECK(replied_m->replied_message_info.get_reply_message_full_id(reply_d->dialog_id, true) == + old_message_full_id) + << old_message_full_id << ' ' << new_message_id << ' ' << replied_m->replied_message_info << ' ' + << *input_reply_to; + update_message_reply_to_message_id(reply_d, replied_m, new_message_id, true); + } else { + set_message_reply(reply_d, replied_m, MessageInputReplyTo(), true); + } } if (have_new_message) { + CHECK(new_message_id != MessageId()); CHECK(!new_message_id.is_yet_unsent()); - replied_by_yet_unsent_messages_[FullMessageId{dialog_id, new_message_id}] = static_cast(it->second.size()); + replied_by_yet_unsent_messages_[MessageFullId{dialog_id, new_message_id}] = static_cast(it->second.size()); } else { - replied_by_yet_unsent_messages_.erase(FullMessageId{dialog_id, new_message_id}); + replied_by_yet_unsent_messages_.erase(MessageFullId{dialog_id, new_message_id}); } replied_yet_unsent_messages_.erase(it); } -FullMessageId MessagesManager::on_send_message_success(int64 random_id, MessageId new_message_id, int32 date, +MessageFullId MessagesManager::on_send_message_success(int64 random_id, MessageId new_message_id, int32 date, int32 ttl_period, FileId new_file_id, const char *source) { CHECK(source != nullptr); // do not try to run getDifference from this function @@ -30762,7 +29640,7 @@ FullMessageId MessagesManager::on_send_message_success(int64 random_id, MessageI auto sent_message = delete_message(d, old_message_id, false, &need_update_dialog_pos, source); if (sent_message == nullptr) { delete_sent_message_on_server(dialog_id, new_message_id, old_message_id); - being_readded_message_id_ = FullMessageId(); + being_readded_message_id_ = MessageFullId(); return {}; } @@ -30783,18 +29661,15 @@ FullMessageId MessagesManager::on_send_message_success(int64 random_id, MessageI send_update_message_content(d, sent_message.get(), false, source); } - if (old_message_id.is_valid() && new_message_id < old_message_id && !d->had_yet_unsent_message_id_overflow) { - LOG(ERROR) << "Sent " << old_message_id << " to " << dialog_id << " as " << new_message_id; + const auto *input_reply_to = get_message_input_reply_to(sent_message.get()); + if (input_reply_to != nullptr && input_reply_to->is_valid() && + input_reply_to->get_reply_message_full_id(dialog_id).get_message_id().is_yet_unsent()) { + set_message_reply(d, sent_message.get(), MessageInputReplyTo(), false); } sent_message->message_id = new_message_id; - if (sent_message->reply_to_message_id != MessageId() && sent_message->reply_to_message_id.is_yet_unsent()) { - LOG(INFO) << "Drop reply to " << sent_message->reply_to_message_id; - sent_message->reply_to_message_id = MessageId(); - } - - send_update_message_send_succeeded(d, old_message_id, sent_message.get()); + send_update_message_send_succeeded(d, old_message_id, sent_message.get(), &need_update_dialog_pos); bool need_update = true; Message *m = @@ -30812,41 +29687,42 @@ FullMessageId MessagesManager::on_send_message_success(int64 random_id, MessageI << " from " << source << ": " << debug_add_message_to_dialog_fail_reason_; } send_update_delete_messages(dialog_id, {new_message_id.get()}, true); - being_readded_message_id_ = FullMessageId(); + being_readded_message_id_ = MessageFullId(); return {}; } - try_add_active_live_location(dialog_id, m); + if (try_add_active_live_location(dialog_id, m)) { + send_update_active_live_location_messages(); + } update_reply_count_by_message(d, +1, m); update_forward_count(dialog_id, m); - being_readded_message_id_ = FullMessageId(); + being_readded_message_id_ = MessageFullId(); return {dialog_id, new_message_id}; } -void MessagesManager::on_send_message_file_part_missing(int64 random_id, int bad_part) { +void MessagesManager::on_send_message_file_parts_missing(int64 random_id, vector &&bad_parts) { auto it = being_sent_messages_.find(random_id); if (it == being_sent_messages_.end()) { // we can't receive fail more than once // but message can be successfully sent before - LOG(WARNING) << "Receive FILE_PART_" << bad_part - << "_MISSING about successfully sent message with random_id = " << random_id; + LOG(INFO) << "Receive error for successfully sent message with random_id = " << random_id; return; } - auto full_message_id = it->second; + auto message_full_id = it->second; being_sent_messages_.erase(it); - Message *m = get_message(full_message_id); + Message *m = get_message(message_full_id); if (m == nullptr) { // message has already been deleted by the user or sent to inaccessible channel // don't need to send error to the user, because the message has already been deleted // and there is nothing to be deleted from the server - LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " << full_message_id; + LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " << message_full_id; return; } - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); if (dialog_id.get_type() == DialogType::SecretChat) { CHECK(!m->message_id.is_scheduled()); Dialog *d = get_dialog(dialog_id); @@ -30865,10 +29741,10 @@ void MessagesManager::on_send_message_file_part_missing(int64 random_id, int bad get_log_event_storer(log_event)); } - do_send_message(dialog_id, m, {bad_part}); + do_send_message(dialog_id, m, -1, std::move(bad_parts)); } -void MessagesManager::on_send_message_file_reference_error(int64 random_id) { +void MessagesManager::on_send_message_file_reference_error(int64 random_id, size_t pos) { auto it = being_sent_messages_.find(random_id); if (it == being_sent_messages_.end()) { // we can't receive fail more than once @@ -30878,21 +29754,22 @@ void MessagesManager::on_send_message_file_reference_error(int64 random_id) { return; } - auto full_message_id = it->second; + auto message_full_id = it->second; being_sent_messages_.erase(it); - Message *m = get_message(full_message_id); + Message *m = get_message(message_full_id); if (m == nullptr) { // message has already been deleted by the user or sent to inaccessible channel // don't need to send error to the user, because the message has already been deleted // and there is nothing to be deleted from the server - LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " << full_message_id; + LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " << message_full_id; return; } - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); if (dialog_id.get_type() == DialogType::SecretChat) { + CHECK(pos == 0); CHECK(!m->message_id.is_scheduled()); Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); @@ -30910,7 +29787,24 @@ void MessagesManager::on_send_message_file_reference_error(int64 random_id) { get_log_event_storer(log_event)); } - do_send_message(dialog_id, m, {-1}); + int32 media_pos = -1; + auto file_ids = get_message_content_any_file_ids(m->content.get()); + if (m->content->get_type() == MessageContentType::PaidMedia) { + media_pos = static_cast(pos); + + LOG(INFO) << "Add paid media group send for " << message_full_id; + auto &request = pending_paid_media_group_sends_[message_full_id]; + CHECK(request.is_finished.empty()); + CHECK(static_cast(media_pos) < file_ids.size()); + request.is_finished.resize(file_ids.size(), true); + request.is_finished[media_pos] = false; + request.finished_count = file_ids.size() - 1; + request.results.resize(file_ids.size()); + } else { + CHECK(pos == 0); + } + + do_send_message(dialog_id, m, media_pos, {-1}); } void MessagesManager::on_send_media_group_file_reference_error(DialogId dialog_id, vector random_ids) { @@ -30927,16 +29821,16 @@ void MessagesManager::on_send_media_group_file_reference_error(DialogId dialog_i continue; } - auto full_message_id = it->second; + auto message_full_id = it->second; being_sent_messages_.erase(it); - Message *m = get_message(full_message_id); + Message *m = get_message(message_full_id); if (m == nullptr) { // message has already been deleted by the user or sent to inaccessible channel // don't need to send error to the user, because the message has already been deleted // and there is nothing to be deleted from the server - LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " << full_message_id; + LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " << message_full_id; continue; } @@ -30944,7 +29838,7 @@ void MessagesManager::on_send_media_group_file_reference_error(DialogId dialog_i CHECK(media_album_id == 0 || media_album_id == m->media_album_id); media_album_id = m->media_album_id; - CHECK(dialog_id == full_message_id.get_dialog_id()); + CHECK(dialog_id == message_full_id.get_dialog_id()); message_ids.push_back(m->message_id); messages.push_back(m); } @@ -30952,7 +29846,7 @@ void MessagesManager::on_send_media_group_file_reference_error(DialogId dialog_i CHECK(dialog_id.get_type() != DialogType::SecretChat); if (message_ids.empty()) { - // all messages was deleted, nothing to do + // all messages were deleted, nothing to do return; } @@ -30968,7 +29862,7 @@ void MessagesManager::on_send_media_group_file_reference_error(DialogId dialog_i } for (auto m : messages) { - do_send_message(dialog_id, m, {-1}); + do_send_message(dialog_id, m, -1, {-1}); } } @@ -30985,22 +29879,22 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) { return; } - auto full_message_id = it->second; + auto message_full_id = it->second; being_sent_messages_.erase(it); - Message *m = get_message(full_message_id); + Message *m = get_message(message_full_id); if (m == nullptr) { // message has already been deleted by the user or sent to inaccessible channel // don't need to send error to the user, because the message has already been deleted // and there is nothing to be deleted from the server - LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " << full_message_id; + LOG(INFO) << "Don't need to send already deleted by the user or sent to an inaccessible chat " << message_full_id; return; } LOG_IF(ERROR, error.code() == NetQuery::Canceled) << "Receive error " << error << " about sent message with random_id = " << random_id; - auto dialog_id = full_message_id.get_dialog_id(); + auto dialog_id = message_full_id.get_dialog_id(); int error_code = error.code(); string error_message = error.message().str(); switch (error_code) { @@ -31021,48 +29915,11 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) { } else if (error.message() == "INPUT_USER_DEACTIVATED") { error_code = 403; error_message = "User is deactivated"; - } else if (error.message() == "USER_IS_BLOCKED") { - error_code = 403; - if (td_->auth_manager_->is_bot()) { - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::SecretChat: - error_message = "Bot was blocked by the user"; - break; - case DialogType::Chat: - case DialogType::Channel: - error_message = "Bot was kicked from the chat"; - break; - case DialogType::None: - default: - UNREACHABLE(); - } - } else { - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::SecretChat: - error_message = "User was blocked by the other user"; - break; - case DialogType::Chat: - case DialogType::Channel: - error_message = "User is not in the chat"; - break; - case DialogType::None: - default: - UNREACHABLE(); - } - } - // TODO add check to send_message } else if (error.message() == "USER_IS_BOT") { if (td_->auth_manager_->is_bot() && (dialog_id.get_type() == DialogType::User || dialog_id.get_type() == DialogType::SecretChat)) { error_code = 403; - if (td_->contacts_manager_->is_user_bot(dialog_id.get_user_id())) { - error_message = "Bot can't send messages to bots"; - } else { - error_message = "Bot can't send messages to the user"; - } - // TODO move check to send_message + error_message = "Bots can't send messages to bots"; } } else if (error.message() == "PEER_ID_INVALID") { error_code = 403; @@ -31070,12 +29927,6 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) { (dialog_id.get_type() == DialogType::User || dialog_id.get_type() == DialogType::SecretChat)) { error_message = "Bot can't initiate conversation with a user"; } - } else if (error.message() == "WC_CONVERT_URL_INVALID" || error.message() == "EXTERNAL_URL_INVALID") { - error_message = "Wrong HTTP URL specified"; - } else if (error.message() == "WEBPAGE_CURL_FAILED") { - error_message = "Failed to get HTTP URL content"; - } else if (error.message() == "WEBPAGE_MEDIA_EMPTY") { - error_message = "Wrong type of the web page content"; } else if (error.message() == "CHAT_FORWARDS_RESTRICTED") { error_message = "Message has protected content and can't be forwarded"; } else if (error.message() == "MEDIA_EMPTY") { @@ -31088,21 +29939,42 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) { error_message = "Wrong poll data specified"; } else if (content_type == MessageContentType::Contact) { error_message = "Wrong phone number specified"; + } else if (content_type == MessageContentType::Story) { + error_message = "Wrong story data specified"; } else { error_message = "Wrong file identifier/HTTP URL specified"; } } else if (error.message() == "PHOTO_EXT_INVALID") { error_message = "Photo has unsupported extension. Use one of .jpg, .jpeg, .gif, .png, .tif or .bmp"; + } else if (error.message() == "QUOTE_TEXT_INVALID") { + auto *input_reply_to = get_message_input_reply_to(m); + if (input_reply_to != nullptr && !input_reply_to->is_empty() && input_reply_to->has_quote()) { + auto reply_message_full_id = input_reply_to->get_reply_message_full_id(dialog_id); + if (reply_message_full_id.get_message_id().is_valid()) { + get_message_from_server(reply_message_full_id, Auto(), "QUOTE_TEXT_INVALID"); + } + } else { + error_code = 500; + error_message = "Unexpected QUOTE_TEXT_INVALID error"; + } + } else if (error.message() == "REPLY_MESSAGE_ID_INVALID") { + auto *input_reply_to = get_message_input_reply_to(m); + if (input_reply_to != nullptr && !input_reply_to->is_empty()) { + auto reply_message_full_id = input_reply_to->get_reply_message_full_id(dialog_id); + if (reply_message_full_id.get_message_id().is_valid()) { + get_message_from_server(reply_message_full_id, Auto(), "REPLY_MESSAGE_ID_INVALID"); + } + } else { + error_code = 500; + error_message = "Unexpected REPLY_MESSAGE_ID_INVALID error"; + } } break; case 403: - if (error.message() == "MESSAGE_DELETE_FORBIDDEN") { - error_code = 400; - error_message = "Message can't be deleted"; - } else if (error.message() == "CHAT_GUEST_SEND_FORBIDDEN") { + if (error.message() == "CHAT_GUEST_SEND_FORBIDDEN") { error_code = 400; if (dialog_id.get_type() == DialogType::Channel) { - td_->contacts_manager_->reload_channel(dialog_id.get_channel_id(), Promise()); + td_->chat_manager_->reload_channel(dialog_id.get_channel_id(), Promise(), "CHAT_GUEST_SEND_FORBIDDEN"); } } else if (error.message() != "CHANNEL_PUBLIC_GROUP_NA" && error.message() != "USER_IS_BLOCKED" && error.message() != "USER_BOT_INVALID" && error.message() != "USER_DELETED") { @@ -31118,17 +29990,23 @@ void MessagesManager::on_send_message_fail(int64 random_id, Status error) { LOG(ERROR) << "Receive " << error.message() << " for " << oneline(to_string(get_message_object(dialog_id, m, "on_send_message_fail"))); } else { - LOG(ERROR) << "Receive " << error.message() << " for " << full_message_id << " with keyboard " + LOG(ERROR) << "Receive " << error.message() << " for " << message_full_id << " with keyboard " << *m->reply_markup; } } - if (error_code != 403 && !(error_code == 500 && G()->close_flag())) { - LOG(WARNING) << "Failed to send " << full_message_id << " with the error " << error; + if (error.message() == "ENTITY_BOUNDS_INVALID") { + LOG(ERROR) << "Receive ENTITY_BOUNDS_INVALID for " + << to_string(get_message_object(dialog_id, m, "on_send_message_fail")); + auto text = get_message_content_text(m->content.get()); + if (text != nullptr) { + LOG(ERROR) << "Receive ENTITY_BOUNDS_INVALID for " << hex_encode(text->text) << " with entities " + << text->entities; + } } - if (error_code <= 0) { - error_code = 500; + if (error_code != 403 && !(error_code == 500 && G()->close_flag())) { + LOG(WARNING) << "Failed to send " << message_full_id << " with the error " << error; } - fail_send_message(full_message_id, error_code, error_message); + fail_send_message(message_full_id, error_code, error_message); } MessageId MessagesManager::get_next_message_id(Dialog *d, MessageType type) const { @@ -31189,24 +30067,29 @@ MessageId MessagesManager::get_next_yet_unsent_scheduled_message_id(Dialog *d, i return last_assigned_message_id; } -void MessagesManager::fail_send_message(FullMessageId full_message_id, int error_code, const string &error_message) { - auto dialog_id = full_message_id.get_dialog_id(); +void MessagesManager::fail_send_message(MessageFullId message_full_id, int32 error_code, const string &error_message) { + if (error_code <= 0) { + error_code = 500; + } + + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - MessageId old_message_id = full_message_id.get_message_id(); + MessageId old_message_id = message_full_id.get_message_id(); CHECK(old_message_id.is_valid() || old_message_id.is_valid_scheduled()); CHECK(old_message_id.is_yet_unsent()); + // must be called before delete_message update_reply_to_message_id(dialog_id, old_message_id, MessageId(), false, "fail_send_message"); bool need_update_dialog_pos = false; - being_readded_message_id_ = full_message_id; + being_readded_message_id_ = message_full_id; auto message = delete_message(d, old_message_id, false, &need_update_dialog_pos, "fail send message"); if (message == nullptr) { // message has already been deleted by the user or sent to inaccessible channel // don't need to send update to the user, because the message has already been deleted // and there is nothing to be deleted from the server - being_readded_message_id_ = FullMessageId(); + being_readded_message_id_ = MessageFullId(); return; } @@ -31215,7 +30098,11 @@ void MessagesManager::fail_send_message(FullMessageId full_message_id, int error if (get_message_force(d, new_message_id, "fail_send_message") != nullptr || is_deleted_message(d, new_message_id) || new_message_id <= d->last_clear_history_message_id) { new_message_id = get_next_local_message_id(d); - } else if (new_message_id > d->last_assigned_message_id) { + while (get_message_force(d, new_message_id, "fail_send_message") != nullptr) { + new_message_id = new_message_id.get_next_message_id(MessageType::Local); + } + } + if (new_message_id > d->last_assigned_message_id) { d->last_assigned_message_id = new_message_id; } } else { @@ -31256,29 +30143,29 @@ void MessagesManager::fail_send_message(FullMessageId full_message_id, int error } register_new_local_message_id(d, m); - LOG(INFO) << "Send updateMessageSendFailed for " << full_message_id; + LOG(INFO) << "Send updateMessageSendFailed for " << message_full_id; if (!td_->auth_manager_->is_bot()) { - yet_unsent_full_message_id_to_persistent_message_id_.emplace({dialog_id, old_message_id}, m->message_id); + yet_unsent_message_full_id_to_persistent_message_id_.emplace({dialog_id, old_message_id}, m->message_id); } - send_closure( - G()->td(), &Td::send_update, - td_api::make_object(get_message_object(dialog_id, m, "fail_send_message"), - old_message_id.get(), error_code, error_message)); + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + get_message_object(dialog_id, m, "fail_send_message"), old_message_id.get(), + td_api::make_object(error_code, error_message))); if (need_update_dialog_pos) { send_update_chat_last_message(d, "fail_send_message"); } - being_readded_message_id_ = FullMessageId(); + being_readded_message_id_ = MessageFullId(); } -void MessagesManager::fail_send_message(FullMessageId full_message_id, Status error) { - fail_send_message(full_message_id, error.code(), error.message().str()); +void MessagesManager::fail_send_message(MessageFullId message_full_id, Status error) { + fail_send_message(message_full_id, error.code(), error.message().str()); } -void MessagesManager::fail_edit_message_media(FullMessageId full_message_id, Status &&error) { - auto dialog_id = full_message_id.get_dialog_id(); +void MessagesManager::fail_edit_message_media(MessageFullId message_full_id, Status &&error) { + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - MessageId message_id = full_message_id.get_message_id(); + MessageId message_id = message_full_id.get_message_id(); CHECK(message_id.is_any_server()); auto m = get_message(d, message_id); @@ -31292,17 +30179,26 @@ void MessagesManager::fail_edit_message_media(FullMessageId full_message_id, Sta } void MessagesManager::on_update_dialog_draft_message(DialogId dialog_id, MessageId top_thread_message_id, - tl_object_ptr &&draft_message) { + tl_object_ptr &&draft_message, + bool force) { + if (G()->close_flag()) { + return; + } if (!dialog_id.is_valid()) { - LOG(ERROR) << "Receive update chat draft in invalid " << dialog_id; + LOG(ERROR) << "Receive update of draft message in invalid " << dialog_id; + return; + } + if (td_->auth_manager_->is_bot()) { + if (draft_message != nullptr && draft_message->get_id() != telegram_api::draftMessageEmpty::ID) { + LOG(ERROR) << "Receive update of draft message in " << dialog_id; + } return; } - auto draft = get_draft_message(td_->contacts_manager_.get(), std::move(draft_message)); auto d = get_dialog_force(dialog_id, "on_update_dialog_draft_message"); if (d == nullptr) { LOG(INFO) << "Ignore update chat draft in unknown " << dialog_id; - if (draft != nullptr) { - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (draft_message != nullptr && draft_message->get_id() != telegram_api::draftMessageEmpty::ID) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { LOG(ERROR) << "Have no read access to " << dialog_id << " to repair chat draft message"; } else { send_get_dialog_query(dialog_id, Auto(), 0, "on_update_dialog_draft_message"); @@ -31314,23 +30210,82 @@ void MessagesManager::on_update_dialog_draft_message(DialogId dialog_id, Message // TODO update thread message draft return; } - update_dialog_draft_message(d, std::move(draft), true, true); + + if (!force && draft_message != nullptr && draft_message->get_id() == telegram_api::draftMessage::ID) { + auto *input_reply_to = static_cast(draft_message.get())->reply_to_.get(); + if (input_reply_to != nullptr) { + InputDialogId input_dialog_id; + switch (input_reply_to->get_id()) { + case telegram_api::inputReplyToStory::ID: { + auto reply_to = static_cast(input_reply_to); + input_dialog_id = InputDialogId(reply_to->peer_); + break; + } + case telegram_api::inputReplyToMessage::ID: { + auto reply_to = static_cast(input_reply_to); + if (reply_to->reply_to_peer_id_ != nullptr) { + input_dialog_id = InputDialogId(reply_to->reply_to_peer_id_); + } + break; + } + default: + UNREACHABLE(); + } + auto reply_in_dialog_id = input_dialog_id.get_dialog_id(); + if (reply_in_dialog_id.is_valid() && !have_dialog_force(reply_in_dialog_id, "on_update_dialog_draft_message")) { + td_->dialog_filter_manager_->load_input_dialog( + input_dialog_id, [actor_id = actor_id(this), dialog_id, top_thread_message_id, + draft_message = std::move(draft_message)](Unit) mutable { + send_closure(actor_id, &MessagesManager::on_update_dialog_draft_message, dialog_id, top_thread_message_id, + std::move(draft_message), true); + }); + return; + } + } + } + update_dialog_draft_message(d, get_draft_message(td_, std::move(draft_message)), true, true); } bool MessagesManager::update_dialog_draft_message(Dialog *d, unique_ptr &&draft_message, bool from_update, bool need_update_dialog_pos) { CHECK(d != nullptr); - if (need_update_draft_message(d->draft_message, draft_message, from_update)) { + if (!td_->auth_manager_->is_bot() && need_update_draft_message(d->draft_message, draft_message, from_update)) { d->draft_message = std::move(draft_message); if (need_update_dialog_pos) { update_dialog_pos(d, "update_dialog_draft_message", false); } + on_dialog_updated(d->dialog_id, "update_dialog_draft_message"); send_update_chat_draft_message(d); return true; } return false; } +void MessagesManager::clear_dialog_draft_by_sent_message(Dialog *d, const Message *m, bool need_update_dialog_pos) { + if (td_->auth_manager_->is_bot()) { + return; + } + if (!m->clear_draft) { + const DraftMessage *draft_message = nullptr; + if (m->initial_top_thread_message_id.is_valid()) { + auto top_m = get_message_force(d, m->initial_top_thread_message_id, "clear_dialog_draft_by_sent_message"); + if (top_m != nullptr) { + draft_message = top_m->thread_draft_message.get(); + } + } else { + draft_message = d->draft_message.get(); + } + if (draft_message == nullptr || !draft_message->need_clear_local(m->content->get_type())) { + return; + } + } + if (m->initial_top_thread_message_id.is_valid()) { + set_dialog_draft_message(d->dialog_id, m->initial_top_thread_message_id, nullptr).ignore(); + } else { + update_dialog_draft_message(d, nullptr, false, need_update_dialog_pos); + } +} + void MessagesManager::on_update_dialog_is_pinned(FolderId folder_id, DialogId dialog_id, bool is_pinned) { if (td_->auth_manager_->is_bot()) { // just in case @@ -31384,6 +30339,95 @@ void MessagesManager::on_update_pinned_dialogs(FolderId folder_id) { reload_pinned_dialogs(DialogListId(folder_id), Auto()); } +void MessagesManager::on_update_dialog_view_as_topics(const Dialog *d, bool old_view_as_topics) { + auto new_view_as_topics = get_dialog_view_as_topics(d); + if (old_view_as_topics == new_view_as_topics) { + return; + } + + LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in on_update_dialog_view_as_topics"; + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + get_chat_id_object(d->dialog_id, "updateChatViewAsTopics"), new_view_as_topics)); + + if (d->dialog_id != td_->dialog_manager_->get_my_dialog_id() && d->draft_message != nullptr && + can_send_message(d->dialog_id).is_ok()) { + // need_hide_dialog_draft_message has changed and there is draft message + send_update_chat_draft_message(d); + } + + // TODO update unread counters in chat lists +} + +void MessagesManager::on_update_dialog_is_forum(DialogId dialog_id, bool is_forum) { + if (!dialog_id.is_valid()) { + LOG(ERROR) << "Receive is_forum for invalid " << dialog_id; + return; + } + + auto d = get_dialog_force(dialog_id, "on_update_dialog_is_forum"); + if (d == nullptr) { + // nothing to do + return; + } + set_dialog_is_forum(d, is_forum); +} + +void MessagesManager::set_dialog_is_forum(Dialog *d, bool is_forum) { + CHECK(d != nullptr); + if (d->is_forum == is_forum) { + return; + } + auto old_view_as_topics = get_dialog_view_as_topics(d); + d->is_forum = is_forum; + on_dialog_updated(d->dialog_id, "set_dialog_is_forum"); + + LOG(INFO) << "Set " << d->dialog_id << " is_forum to " << is_forum; + on_update_dialog_view_as_topics(d, old_view_as_topics); +} + +void MessagesManager::on_update_dialog_view_as_messages(DialogId dialog_id, bool view_as_messages) { + if (td_->auth_manager_->is_bot()) { + // just in case + return; + } + + if (!dialog_id.is_valid()) { + LOG(ERROR) << "Receive view_as_messages for invalid " << dialog_id; + return; + } + + auto d = get_dialog_force(dialog_id, "on_update_dialog_view_as_messages"); + if (d == nullptr) { + // nothing to do + return; + } + set_dialog_view_as_messages(d, view_as_messages, "on_update_dialog_view_as_messages"); +} + +void MessagesManager::set_dialog_view_as_messages(Dialog *d, bool view_as_messages, const char *source) { + if (td_->auth_manager_->is_bot()) { + // just in case + return; + } + + CHECK(d != nullptr); + if (d->view_as_messages == view_as_messages) { + if (!d->is_view_as_messages_inited) { + d->is_view_as_messages_inited = true; + on_dialog_updated(d->dialog_id, source); + } + return; + } + auto old_view_as_topics = get_dialog_view_as_topics(d); + d->view_as_messages = view_as_messages; + d->is_view_as_messages_inited = true; + on_dialog_updated(d->dialog_id, source); + + LOG(INFO) << "Set " << d->dialog_id << " view_as_messages to " << view_as_messages << " from " << source; + on_update_dialog_view_as_topics(d, old_view_as_topics); +} + void MessagesManager::on_update_dialog_is_marked_as_unread(DialogId dialog_id, bool is_marked_as_unread) { if (td_->auth_manager_->is_bot()) { // just in case @@ -31504,13 +30548,13 @@ void MessagesManager::set_dialog_is_translatable(Dialog *d, bool is_translatable } } -void MessagesManager::on_update_dialog_is_blocked(DialogId dialog_id, bool is_blocked) { +void MessagesManager::on_update_dialog_is_blocked(DialogId dialog_id, bool is_blocked, bool is_blocked_for_stories) { if (!dialog_id.is_valid()) { LOG(ERROR) << "Receive pinned message in invalid " << dialog_id; return; } if (dialog_id.get_type() == DialogType::User) { - td_->contacts_manager_->on_update_user_is_blocked(dialog_id.get_user_id(), is_blocked); + td_->user_manager_->on_update_user_is_blocked(dialog_id.get_user_id(), is_blocked, is_blocked_for_stories); } auto d = get_dialog_force(dialog_id, "on_update_dialog_is_blocked"); @@ -31519,33 +30563,37 @@ void MessagesManager::on_update_dialog_is_blocked(DialogId dialog_id, bool is_bl return; } - if (d->is_blocked == is_blocked) { - if (!d->is_is_blocked_inited) { - CHECK(is_blocked == false); + if (d->is_blocked == is_blocked && d->is_blocked_for_stories == is_blocked_for_stories) { + if (!d->is_is_blocked_for_stories_inited) { + CHECK(is_blocked_for_stories == false); d->is_is_blocked_inited = true; + d->is_is_blocked_for_stories_inited = true; on_dialog_updated(dialog_id, "on_update_dialog_is_blocked"); } return; } - set_dialog_is_blocked(d, is_blocked); + set_dialog_is_blocked(d, is_blocked, is_blocked_for_stories); } -void MessagesManager::set_dialog_is_blocked(Dialog *d, bool is_blocked) { +void MessagesManager::set_dialog_is_blocked(Dialog *d, bool is_blocked, bool is_blocked_for_stories) { CHECK(d != nullptr); - CHECK(d->is_blocked != is_blocked); + CHECK(d->is_blocked != is_blocked || d->is_blocked_for_stories != is_blocked_for_stories); d->is_blocked = is_blocked; + d->is_blocked_for_stories = is_blocked_for_stories; d->is_is_blocked_inited = true; + d->is_is_blocked_for_stories_inited = true; on_dialog_updated(d->dialog_id, "set_dialog_is_blocked"); - LOG(INFO) << "Set " << d->dialog_id << " is_blocked to " << is_blocked; + LOG(INFO) << "Set " << d->dialog_id << " is_blocked to " << is_blocked << '/' << is_blocked_for_stories; LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in set_dialog_is_blocked"; + auto block_list_id = BlockListId(d->is_blocked, d->is_blocked_for_stories); send_closure(G()->td(), &Td::send_update, - td_api::make_object(get_chat_id_object(d->dialog_id, "updateChatIsBlocked"), - is_blocked)); + td_api::make_object(get_chat_id_object(d->dialog_id, "updateChatBlockList"), + block_list_id.get_block_list_object())); if (d->dialog_id.get_type() == DialogType::User) { - td_->contacts_manager_->on_update_user_is_blocked(d->dialog_id.get_user_id(), is_blocked); + td_->user_manager_->on_update_user_is_blocked(d->dialog_id.get_user_id(), is_blocked, is_blocked_for_stories); if (d->know_action_bar) { if (is_blocked) { @@ -31558,17 +30606,35 @@ void MessagesManager::set_dialog_is_blocked(Dialog *d, bool is_blocked) { } } - td_->contacts_manager_->for_each_secret_chat_with_user( - d->dialog_id.get_user_id(), [this, is_blocked](SecretChatId secret_chat_id) { + td_->user_manager_->for_each_secret_chat_with_user( + d->dialog_id.get_user_id(), [this, is_blocked, is_blocked_for_stories](SecretChatId secret_chat_id) { DialogId dialog_id(secret_chat_id); auto d = get_dialog(dialog_id); // must not create the dialog - if (d != nullptr && d->is_update_new_chat_sent && d->is_blocked != is_blocked) { - set_dialog_is_blocked(d, is_blocked); + if (d != nullptr && d->is_update_new_chat_sent && + (d->is_blocked != is_blocked || d->is_blocked_for_stories != is_blocked_for_stories)) { + set_dialog_is_blocked(d, is_blocked, is_blocked_for_stories); } }); } } +void MessagesManager::on_update_dialog_business_bot_is_paused(DialogId dialog_id, bool is_paused) { + auto d = get_dialog_force(dialog_id, "on_update_dialog_business_bot_is_paused"); + CHECK(d != nullptr); + if (d->business_bot_manage_bar != nullptr && d->business_bot_manage_bar->set_business_bot_is_paused(is_paused)) { + send_update_chat_business_bot_manage_bar(d); + } +} + +void MessagesManager::on_update_dialog_business_bot_removed(DialogId dialog_id) { + auto d = get_dialog_force(dialog_id, "on_update_dialog_business_bot_removed"); + CHECK(d != nullptr); + if (d->business_bot_manage_bar != nullptr) { + d->business_bot_manage_bar = nullptr; + send_update_chat_business_bot_manage_bar(d); + } +} + void MessagesManager::on_update_dialog_last_pinned_message_id(DialogId dialog_id, MessageId pinned_message_id) { if (!dialog_id.is_valid()) { LOG(ERROR) << "Receive pinned message in invalid " << dialog_id; @@ -31614,8 +30680,8 @@ void MessagesManager::drop_dialog_last_pinned_message_id(Dialog *d) { create_actor( "ReloadDialogFullInfoActor", 1.0, - PromiseCreator::lambda([actor_id = actor_id(this), dialog_id = d->dialog_id](Result result) { - send_closure(actor_id, &MessagesManager::reload_dialog_info_full, dialog_id, + PromiseCreator::lambda([actor_id = G()->dialog_manager(), dialog_id = d->dialog_id](Result result) { + send_closure(actor_id, &DialogManager::reload_dialog_info_full, dialog_id, "drop_dialog_last_pinned_message_id"); })) .release(); @@ -31637,7 +30703,7 @@ void MessagesManager::on_update_dialog_background(DialogId dialog_id, return; } - set_dialog_background(d, BackgroundInfo(td_, std::move(wallpaper))); + set_dialog_background(d, BackgroundInfo(td_, std::move(wallpaper), true)); } void MessagesManager::set_dialog_background(Dialog *d, BackgroundInfo &&background_info) { @@ -31654,7 +30720,7 @@ void MessagesManager::set_dialog_background(Dialog *d, BackgroundInfo &&backgrou d->is_background_inited = true; if (is_changed) { - LOG(INFO) << "Set " << d->dialog_id << " backgroud to " << d->background_info; + LOG(INFO) << "Set " << d->dialog_id << " background to " << d->background_info; send_update_chat_background(d); } else { on_dialog_updated(d->dialog_id, "set_dialog_background"); @@ -31727,13 +30793,11 @@ void MessagesManager::on_update_dialog_pending_join_requests(DialogId dialog_id, return; } - set_dialog_pending_join_requests(d, pending_join_request_count, UserId::get_user_ids(pending_requesters)); + set_dialog_pending_join_requests(d, pending_join_request_count, UserId::get_user_ids(pending_requesters, true)); } void MessagesManager::fix_pending_join_requests(DialogId dialog_id, int32 &pending_join_request_count, vector &pending_join_request_user_ids) const { - td::remove_if(pending_join_request_user_ids, [](UserId user_id) { return !user_id.is_valid(); }); - bool need_drop_pending_join_requests = [&] { if (pending_join_request_count < 0) { return true; @@ -31744,7 +30808,7 @@ void MessagesManager::fix_pending_join_requests(DialogId dialog_id, int32 &pendi return true; case DialogType::Chat: { auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_status(chat_id); + auto status = td_->chat_manager_->get_chat_status(chat_id); if (!status.can_manage_invite_links()) { return true; } @@ -31752,7 +30816,7 @@ void MessagesManager::fix_pending_join_requests(DialogId dialog_id, int32 &pendi } case DialogType::Channel: { auto channel_id = dialog_id.get_channel_id(); - auto status = td_->contacts_manager_->get_channel_permissions(channel_id); + auto status = td_->chat_manager_->get_channel_permissions(channel_id); if (!status.can_manage_invite_links()) { return true; } @@ -31924,26 +30988,28 @@ void MessagesManager::set_dialog_folder_id(Dialog *d, FolderId folder_id) { void MessagesManager::do_set_dialog_folder_id(Dialog *d, FolderId folder_id) { CHECK(!td_->auth_manager_->is_bot()); - if (d->folder_id == folder_id && d->is_folder_id_inited) { + bool is_changed = d->folder_id != folder_id; + if (!is_changed && d->is_folder_id_inited) { return; } - - d->folder_id = folder_id; d->is_folder_id_inited = true; - if (d->dialog_id.get_type() == DialogType::SecretChat) { - // need to change action bar only for the secret chat and keep unarchive for the main chat - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); - if (d->is_update_new_chat_sent && user_id.is_valid()) { - const Dialog *user_d = get_dialog(DialogId(user_id)); - if (user_d != nullptr && user_d->action_bar != nullptr && user_d->action_bar->can_unarchive()) { - send_closure(G()->td(), &Td::send_update, - td_api::make_object( - get_chat_id_object(d->dialog_id, "updateChatActionBar"), get_chat_action_bar_object(d))); + if (is_changed) { + d->folder_id = folder_id; + if (d->dialog_id.get_type() == DialogType::SecretChat) { + // need to change action bar only for the secret chat and keep unarchive for the main chat + auto user_id = td_->user_manager_->get_secret_chat_user_id(d->dialog_id.get_secret_chat_id()); + if (d->is_update_new_chat_sent && user_id.is_valid()) { + const Dialog *user_d = get_dialog(DialogId(user_id)); + if (user_d != nullptr && user_d->action_bar != nullptr && user_d->action_bar->can_unarchive()) { + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + get_chat_id_object(d->dialog_id, "updateChatActionBar"), get_chat_action_bar_object(d))); + } } + } else if (folder_id != FolderId::archive() && d->action_bar != nullptr && d->action_bar->on_dialog_unarchived()) { + send_update_chat_action_bar(d); } - } else if (folder_id != FolderId::archive() && d->action_bar != nullptr && d->action_bar->on_dialog_unarchived()) { - send_update_chat_action_bar(d); } on_dialog_updated(d->dialog_id, "do_set_dialog_folder_id"); @@ -32037,8 +31103,9 @@ void MessagesManager::on_update_dialog_default_join_group_call_as_dialog_id(Dial if (default_join_as_dialog_id.is_valid()) { if (default_join_as_dialog_id.get_type() != DialogType::User) { force_create_dialog(default_join_as_dialog_id, "on_update_dialog_default_join_group_call_as_dialog_id"); - } else if (!td_->contacts_manager_->have_user_force(default_join_as_dialog_id.get_user_id()) || - default_join_as_dialog_id != get_my_dialog_id()) { + } else if (!td_->user_manager_->have_user_force(default_join_as_dialog_id.get_user_id(), + "on_update_dialog_default_join_group_call_as_dialog_id") || + default_join_as_dialog_id != td_->dialog_manager_->get_my_dialog_id()) { default_join_as_dialog_id = DialogId(); } } @@ -32057,7 +31124,7 @@ void MessagesManager::on_update_dialog_default_send_message_as_dialog_id(DialogI return; } auto dialog_type = dialog_id.get_type(); - if (dialog_type != DialogType::Channel || is_broadcast_channel(dialog_id)) { + if (dialog_type != DialogType::Channel) { if (default_send_as_dialog_id != DialogId()) { LOG(ERROR) << "Receive message sender " << default_send_as_dialog_id << " in " << dialog_id; } @@ -32077,15 +31144,17 @@ void MessagesManager::on_update_dialog_default_send_message_as_dialog_id(DialogI if (default_send_as_dialog_id.is_valid()) { if (default_send_as_dialog_id.get_type() != DialogType::User) { force_create_dialog(default_send_as_dialog_id, "on_update_dialog_default_send_message_as_dialog_id"); - } else if (!td_->contacts_manager_->have_user_force(default_send_as_dialog_id.get_user_id()) || - default_send_as_dialog_id != get_my_dialog_id()) { + } else if (!td_->user_manager_->have_user_force(default_send_as_dialog_id.get_user_id(), + "on_update_dialog_default_send_message_as_dialog_id") || + default_send_as_dialog_id != td_->dialog_manager_->get_my_dialog_id()) { default_send_as_dialog_id = DialogId(); } } if (d->default_send_message_as_dialog_id != default_send_as_dialog_id) { if (force || default_send_as_dialog_id.is_valid() || - (created_public_broadcasts_inited_ && created_public_broadcasts_.empty())) { + (td_->chat_manager_->are_created_public_broadcasts_inited() && + td_->chat_manager_->get_created_public_broadcasts().empty())) { LOG(INFO) << "Set message sender in " << dialog_id << " to " << default_send_as_dialog_id; d->need_drop_default_send_message_as_dialog_id = false; d->default_send_message_as_dialog_id = default_send_as_dialog_id; @@ -32124,13 +31193,21 @@ void MessagesManager::set_dialog_message_ttl(Dialog *d, MessageTtl message_ttl) } } -void MessagesManager::on_create_new_dialog_success(int64 random_id, tl_object_ptr &&updates, - DialogType expected_type, Promise &&promise) { +void MessagesManager::on_create_new_dialog(telegram_api::object_ptr &&updates, + MissingInvitees &&missing_invitees, + Promise> &&chat_promise, + Promise> &&channel_promise) { + LOG(INFO) << "Receive result for creation of a chat: " << to_string(updates); + + auto fail = [&](Slice message) { + chat_promise.set_error(Status::Error(500, message)); + channel_promise.set_error(Status::Error(500, message)); + }; auto sent_messages = UpdatesManager::get_new_messages(updates.get()); auto sent_messages_random_ids = UpdatesManager::get_sent_messages_random_ids(updates.get()); if (sent_messages.size() != 1u || sent_messages_random_ids.size() != 1u) { LOG(ERROR) << "Receive wrong result for create group or channel chat " << oneline(to_string(updates)); - return on_create_new_dialog_fail(random_id, Status::Error(500, "Unsupported server response"), std::move(promise)); + return fail("Unsupported server response"); } auto *message = sent_messages.begin()->first; @@ -32138,71 +31215,52 @@ void MessagesManager::on_create_new_dialog_success(int64 random_id, tl_object_pt // TODO check that message_random_id equals random_id after messages_createChat will be updated if (sent_messages.begin()->second) { - return on_create_new_dialog_fail(random_id, Status::Error(500, "Scheduled message received"), std::move(promise)); + return fail("Scheduled message received"); } + auto expected_type = chat_promise ? DialogType::Chat : DialogType::Channel; auto dialog_id = DialogId::get_message_dialog_id(message); if (dialog_id.get_type() != expected_type) { - return on_create_new_dialog_fail(random_id, Status::Error(500, "Chat of wrong type has been created"), - std::move(promise)); + return fail("Chat of wrong type has been created"); } if (message->get_id() != telegram_api::messageService::ID) { - return on_create_new_dialog_fail(random_id, Status::Error(500, "Invalid message received"), std::move(promise)); + return fail("Invalid message received"); } auto action_id = static_cast(message)->action_->get_id(); if (action_id != telegram_api::messageActionChatCreate::ID && action_id != telegram_api::messageActionChannelCreate::ID) { - return on_create_new_dialog_fail(random_id, Status::Error(500, "Invalid service message received"), - std::move(promise)); + return fail("Invalid service message received"); } - auto it = created_dialogs_.find(random_id); - CHECK(it != created_dialogs_.end()); - CHECK(it->second == DialogId()); - - it->second = dialog_id; - const Dialog *d = get_dialog(dialog_id); if (d != nullptr && d->last_new_message_id.is_valid()) { // dialog have been already created and at least one non-temporary message was added, // i.e. we are not interested in the creation of dialog by searchMessages // then messages have already been added, so just set promise - return promise.set_value(Unit()); + if (chat_promise) { + return chat_promise.set_value(td_api::make_object( + get_chat_id_object(dialog_id, "on_create_new_dialog"), + missing_invitees.get_failed_to_add_members_object(td_->user_manager_.get()))); + } else { + return channel_promise.set_value(get_chat_object(d, "on_create_new_dialog")); + } } if (pending_created_dialogs_.count(dialog_id) == 0) { - auto user_ids = td_->updates_manager_->extract_group_invite_privacy_forbidden_updates(updates); - auto new_promise = PromiseCreator::lambda( - [dialog_id, user_ids = std::move(user_ids), promise = std::move(promise)](Result &&result) mutable { - if (result.is_error()) { - return promise.set_error(result.move_as_error()); - } - promise.set_value(Unit()); - if (!user_ids.empty()) { - send_closure(G()->contacts_manager(), &ContactsManager::send_update_add_chat_members_privacy_forbidden, - dialog_id, std::move(user_ids), "on_create_new_dialog_success"); - } - }); - pending_created_dialogs_.emplace(dialog_id, std::move(new_promise)); + PendingCreatedDialog pending_created_dialog; + pending_created_dialog.failed_to_add_members_ = + missing_invitees.get_failed_to_add_members_object(td_->user_manager_.get()); + pending_created_dialog.chat_promise_ = std::move(chat_promise); + pending_created_dialog.channel_promise_ = std::move(channel_promise); + pending_created_dialogs_.emplace(dialog_id, std::move(pending_created_dialog)); } else { LOG(ERROR) << "Receive twice " << dialog_id << " as result of chat creation"; - return on_create_new_dialog_fail(random_id, Status::Error(500, "Chat was created earlier"), std::move(promise)); + return fail("Chat was created earlier"); } td_->updates_manager_->on_get_updates(std::move(updates), Promise()); } -void MessagesManager::on_create_new_dialog_fail(int64 random_id, Status error, Promise &&promise) { - LOG(INFO) << "Clean up creation of group or channel chat"; - auto it = created_dialogs_.find(random_id); - CHECK(it != created_dialogs_.end()); - CHECK(it->second == DialogId()); - created_dialogs_.erase(it); - - CHECK(error.is_error()); - promise.set_error(std::move(error)); -} - void MessagesManager::on_dialog_bots_updated(DialogId dialog_id, vector bot_user_ids, bool from_database) { if (td_->auth_manager_->is_bot()) { return; @@ -32230,6 +31288,7 @@ void MessagesManager::on_dialog_bots_updated(DialogId dialog_id, vector } void MessagesManager::set_dialog_has_bots(Dialog *d, bool has_bots) { + CHECK(!td_->auth_manager_->is_bot()); CHECK(d != nullptr); LOG_CHECK(d->is_update_new_chat_sent) << "Wrong " << d->dialog_id << " in set_dialog_has_bots"; @@ -32254,12 +31313,13 @@ void MessagesManager::set_dialog_has_bots(Dialog *d, bool has_bots) { void MessagesManager::on_dialog_photo_updated(DialogId dialog_id) { auto d = get_dialog(dialog_id); // called from update_user, must not create the dialog if (d != nullptr && d->is_update_new_chat_sent) { - send_closure(G()->td(), &Td::send_update, - td_api::make_object( - get_chat_id_object(dialog_id, "updateChatPhoto"), - get_chat_photo_info_object(td_->file_manager_.get(), get_dialog_photo(dialog_id)))); + send_closure( + G()->td(), &Td::send_update, + td_api::make_object( + get_chat_id_object(dialog_id, "updateChatPhoto"), + get_chat_photo_info_object(td_->file_manager_.get(), td_->dialog_manager_->get_dialog_photo(dialog_id)))); } else if (d != nullptr && d->is_update_new_chat_being_sent) { - const auto *photo = get_dialog_photo(dialog_id); + const auto *photo = td_->dialog_manager_->get_dialog_photo(dialog_id); if (photo == nullptr) { LOG(ERROR) << "Removed photo of " << dialog_id << " while the chat is being added"; } else { @@ -32268,23 +31328,48 @@ void MessagesManager::on_dialog_photo_updated(DialogId dialog_id) { } } +void MessagesManager::on_dialog_accent_colors_updated(DialogId dialog_id) { + auto d = get_dialog(dialog_id); // called from update_user, must not create the dialog + if (d != nullptr && d->is_update_new_chat_sent) { + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + get_chat_id_object(dialog_id, "updateChatAccentColors"), + td_->dialog_manager_->get_dialog_accent_color_id_object(dialog_id), + td_->dialog_manager_->get_dialog_background_custom_emoji_id(dialog_id).get(), + td_->dialog_manager_->get_dialog_profile_accent_color_id_object(dialog_id), + td_->dialog_manager_->get_dialog_profile_background_custom_emoji_id(dialog_id).get())); + } +} + void MessagesManager::on_dialog_title_updated(DialogId dialog_id) { auto d = get_dialog(dialog_id); // called from update_user, must not create the dialog if (d != nullptr) { update_dialogs_hints(d); if (d->is_update_new_chat_sent) { send_closure(G()->td(), &Td::send_update, - td_api::make_object(dialog_id.get(), get_dialog_title(dialog_id))); + td_api::make_object(dialog_id.get(), + td_->dialog_manager_->get_dialog_title(dialog_id))); } } } +void MessagesManager::on_dialog_emoji_status_updated(DialogId dialog_id) { + auto d = get_dialog(dialog_id); // called from update_user, must not create the dialog + if (d != nullptr && d->is_update_new_chat_sent) { + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + get_chat_id_object(dialog_id, "updateChatEmojiStatus"), + td_->dialog_manager_->get_dialog_emoji_status_object(dialog_id))); + } +} + void MessagesManager::on_dialog_default_permissions_updated(DialogId dialog_id) { auto d = get_dialog(dialog_id); // called from update_user, must not create the dialog if (d != nullptr && d->is_update_new_chat_sent) { send_closure(G()->td(), &Td::send_update, td_api::make_object( - dialog_id.get(), get_dialog_default_permissions(dialog_id).get_chat_permissions_object())); + dialog_id.get(), + td_->dialog_manager_->get_dialog_default_permissions(dialog_id).get_chat_permissions_object())); } } @@ -32293,7 +31378,7 @@ void MessagesManager::on_dialog_has_protected_content_updated(DialogId dialog_id if (d != nullptr && d->is_update_new_chat_sent) { send_closure(G()->td(), &Td::send_update, td_api::make_object( - dialog_id.get(), get_dialog_has_protected_content(dialog_id))); + dialog_id.get(), td_->dialog_manager_->get_dialog_has_protected_content(dialog_id))); } } @@ -32313,7 +31398,7 @@ void MessagesManager::on_dialog_user_is_contact_updated(DialogId dialog_id, bool if (td_->dialog_filter_manager_->have_dialog_filters() && d->order != DEFAULT_ORDER) { update_dialog_lists(d, get_dialog_positions(d), true, false, "on_dialog_user_is_contact_updated"); - td_->contacts_manager_->for_each_secret_chat_with_user( + td_->user_manager_->for_each_secret_chat_with_user( d->dialog_id.get_user_id(), [this](SecretChatId secret_chat_id) { DialogId dialog_id(secret_chat_id); auto d = get_dialog(dialog_id); // must not create the dialog @@ -32334,6 +31419,9 @@ void MessagesManager::on_dialog_user_is_deleted_updated(DialogId dialog_id, bool if (d->action_bar != nullptr && d->action_bar->on_user_deleted()) { send_update_chat_action_bar(d); } + if (d->business_bot_manage_bar != nullptr && d->business_bot_manage_bar->on_user_deleted()) { + send_update_chat_business_bot_manage_bar(d); + } } else { repair_dialog_action_bar(d, "on_dialog_user_is_deleted_updated"); } @@ -32341,26 +31429,24 @@ void MessagesManager::on_dialog_user_is_deleted_updated(DialogId dialog_id, bool if (td_->dialog_filter_manager_->have_dialog_filters() && d->order != DEFAULT_ORDER) { update_dialog_lists(d, get_dialog_positions(d), true, false, "on_dialog_user_is_deleted_updated"); - td_->contacts_manager_->for_each_secret_chat_with_user( - dialog_id.get_user_id(), [this](SecretChatId secret_chat_id) { - DialogId dialog_id(secret_chat_id); - auto d = get_dialog(dialog_id); // must not create the dialog - if (d != nullptr && d->is_update_new_chat_sent && d->order != DEFAULT_ORDER) { - update_dialog_lists(d, get_dialog_positions(d), true, false, "on_dialog_user_is_deleted_updated"); - } - }); + td_->user_manager_->for_each_secret_chat_with_user(dialog_id.get_user_id(), [this](SecretChatId secret_chat_id) { + DialogId dialog_id(secret_chat_id); + auto d = get_dialog(dialog_id); // must not create the dialog + if (d != nullptr && d->is_update_new_chat_sent && d->order != DEFAULT_ORDER) { + update_dialog_lists(d, get_dialog_positions(d), true, false, "on_dialog_user_is_deleted_updated"); + } + }); } if (is_deleted && d->has_bots) { set_dialog_has_bots(d, false); - td_->contacts_manager_->for_each_secret_chat_with_user( - dialog_id.get_user_id(), [this](SecretChatId secret_chat_id) { - DialogId dialog_id(secret_chat_id); - auto d = get_dialog(dialog_id); // must not create the dialog - if (d != nullptr && d->is_update_new_chat_sent && d->has_bots) { - set_dialog_has_bots(d, false); - } - }); + td_->user_manager_->for_each_secret_chat_with_user(dialog_id.get_user_id(), [this](SecretChatId secret_chat_id) { + DialogId dialog_id(secret_chat_id); + auto d = get_dialog(dialog_id); // must not create the dialog + if (d != nullptr && d->is_update_new_chat_sent && d->has_bots) { + set_dialog_has_bots(d, false); + } + }); } } } @@ -32368,7 +31454,7 @@ void MessagesManager::on_dialog_user_is_deleted_updated(DialogId dialog_id, bool void MessagesManager::on_dialog_linked_channel_updated(DialogId dialog_id, ChannelId old_linked_channel_id, ChannelId new_linked_channel_id) const { CHECK(dialog_id.get_type() == DialogType::Channel); - if (td_->auth_manager_->is_bot() || !is_broadcast_channel(dialog_id)) { + if (td_->auth_manager_->is_bot() || !td_->dialog_manager_->is_broadcast_channel(dialog_id)) { return; } auto d = get_dialog(dialog_id); // no need to create the dialog @@ -32382,89 +31468,9 @@ void MessagesManager::on_dialog_linked_channel_updated(DialogId dialog_id, Chann }); LOG(INFO) << "Found discussion messages " << message_ids; for (auto message_id : message_ids) { - send_update_message_interaction_info(dialog_id, get_message(d, message_id)); - if (message_id == d->last_message_id) { - send_update_chat_last_message_impl(d, "on_dialog_linked_channel_updated"); - } - } -} - -DialogId MessagesManager::resolve_dialog_username(const string &username) const { - auto cleaned_username = clean_username(username); - auto resolved_username = resolved_usernames_.get(cleaned_username); - if (resolved_username.dialog_id.is_valid()) { - return resolved_username.dialog_id; - } - - return inaccessible_resolved_usernames_.get(cleaned_username); -} - -DialogId MessagesManager::search_public_dialog(const string &username_to_search, bool force, Promise &&promise) { - string username = clean_username(username_to_search); - if (username[0] == '@') { - username = username.substr(1); - } - if (username.empty()) { - promise.set_error(Status::Error(200, "Username is invalid")); - return DialogId(); - } - - DialogId dialog_id; - auto resolved_username = resolved_usernames_.get(username); - if (resolved_username.dialog_id.is_valid()) { - if (resolved_username.expires_at < Time::now()) { - td_->create_handler(Promise())->send(username); - } - dialog_id = resolved_username.dialog_id; - } else { - dialog_id = inaccessible_resolved_usernames_.get(username); - } - - if (dialog_id.is_valid()) { - if (have_input_peer(dialog_id, AccessRights::Read)) { - if (!force && reload_voice_chat_on_search_usernames_.count(username)) { - reload_voice_chat_on_search_usernames_.erase(username); - if (dialog_id.get_type() == DialogType::Channel) { - td_->contacts_manager_->reload_channel_full(dialog_id.get_channel_id(), std::move(promise), - "search_public_dialog"); - return DialogId(); - } - } - - if (td_->auth_manager_->is_bot()) { - force_create_dialog(dialog_id, "search_public_dialog", true); - } else { - const Dialog *d = get_dialog_force(dialog_id, "search_public_dialog"); - if (!is_dialog_inited(d)) { - send_get_dialog_query(dialog_id, std::move(promise), 0, "search_public_dialog"); - return DialogId(); - } - } - - promise.set_value(Unit()); - return dialog_id; - } else { - // bot username maybe known despite there is no access_hash - if (force || dialog_id.get_type() != DialogType::User) { - force_create_dialog(dialog_id, "search_public_dialog", true); - promise.set_value(Unit()); - return dialog_id; - } - } - } - - td_->create_handler(std::move(promise))->send(username); - return DialogId(); -} - -void MessagesManager::reload_voice_chat_on_search(const string &username) { - if (!td_->auth_manager_->is_authorized()) { - return; - } - - auto cleaned_username = clean_username(username); - if (!cleaned_username.empty()) { - reload_voice_chat_on_search_usernames_.insert(cleaned_username); + const Message *m = get_message(d, message_id); + send_update_message_interaction_info(dialog_id, m); + send_update_last_message_if_needed(d, m, "on_dialog_linked_channel_updated"); } } @@ -32498,7 +31504,7 @@ void MessagesManager::send_get_dialog_query(DialogId dialog_id, Promise && } return promise.set_error(Status::Error(500, "Wrong getDialog query")); } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { if (log_event_id != 0) { binlog_erase(G()->td_db()->get_binlog(), log_event_id); } @@ -32561,151 +31567,31 @@ void MessagesManager::on_get_dialog_query_finished(DialogId dialog_id, Status && void MessagesManager::on_dialog_usernames_updated(DialogId dialog_id, const Usernames &old_usernames, const Usernames &new_usernames) { - CHECK(dialog_id.is_valid()); - const auto *d = get_dialog(dialog_id); - if (d != nullptr) { - update_dialogs_hints(d); - } - if (old_usernames != new_usernames) { - message_embedding_codes_[0].erase(dialog_id); - message_embedding_codes_[1].erase(dialog_id); - - LOG(INFO) << "Update usernames in " << dialog_id << " from " << old_usernames << " to " << new_usernames; - } - if (!old_usernames.is_empty() && old_usernames != new_usernames) { - for (auto &username : old_usernames.get_active_usernames()) { - auto cleaned_username = clean_username(username); - resolved_usernames_.erase(cleaned_username); - inaccessible_resolved_usernames_.erase(cleaned_username); - } - } - if (!new_usernames.is_empty()) { - for (auto &username : new_usernames.get_active_usernames()) { - auto cleaned_username = clean_username(username); - if (!cleaned_username.empty()) { - resolved_usernames_[cleaned_username] = ResolvedUsername{dialog_id, Time::now() + USERNAME_CACHE_EXPIRE_TIME}; - } - } - } -} - -void MessagesManager::on_resolved_username(const string &username, DialogId dialog_id) { - if (!dialog_id.is_valid()) { - LOG(ERROR) << "Resolve username \"" << username << "\" to invalid " << dialog_id; - return; - } - - auto cleaned_username = clean_username(username); - if (cleaned_username.empty()) { - return; - } - - auto resolved_username = resolved_usernames_.get(cleaned_username); - if (resolved_username.dialog_id.is_valid()) { - LOG_IF(ERROR, resolved_username.dialog_id != dialog_id) - << "Resolve username \"" << username << "\" to " << dialog_id << ", but have it in " - << resolved_username.dialog_id; - return; - } - - inaccessible_resolved_usernames_[cleaned_username] = dialog_id; -} - -void MessagesManager::drop_username(const string &username) { - auto cleaned_username = clean_username(username); - if (cleaned_username.empty()) { + if (td_->auth_manager_->is_bot()) { return; } - inaccessible_resolved_usernames_.erase(cleaned_username); - - auto resolved_username = resolved_usernames_.get(cleaned_username); - if (resolved_username.dialog_id.is_valid()) { - auto dialog_id = resolved_username.dialog_id; - if (have_input_peer(dialog_id, AccessRights::Read)) { - CHECK(dialog_id.get_type() != DialogType::SecretChat); - send_get_dialog_query(dialog_id, Auto(), 0, "drop_username"); - } - - resolved_usernames_.erase(cleaned_username); - } -} - -const DialogPhoto *MessagesManager::get_dialog_photo(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: - return td_->contacts_manager_->get_user_dialog_photo(dialog_id.get_user_id()); - case DialogType::Chat: - return td_->contacts_manager_->get_chat_dialog_photo(dialog_id.get_chat_id()); - case DialogType::Channel: - return td_->contacts_manager_->get_channel_dialog_photo(dialog_id.get_channel_id()); - case DialogType::SecretChat: - return td_->contacts_manager_->get_secret_chat_dialog_photo(dialog_id.get_secret_chat_id()); - case DialogType::None: - default: - UNREACHABLE(); - return nullptr; - } -} + LOG(INFO) << "Update usernames in " << dialog_id << " from " << old_usernames << " to " << new_usernames; -string MessagesManager::get_dialog_title(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: - return td_->contacts_manager_->get_user_title(dialog_id.get_user_id()); - case DialogType::Chat: - return td_->contacts_manager_->get_chat_title(dialog_id.get_chat_id()); - case DialogType::Channel: - return td_->contacts_manager_->get_channel_title(dialog_id.get_channel_id()); - case DialogType::SecretChat: - return td_->contacts_manager_->get_secret_chat_title(dialog_id.get_secret_chat_id()); - case DialogType::None: - default: - UNREACHABLE(); - return string(); - } -} + message_embedding_codes_[0].erase(dialog_id); + message_embedding_codes_[1].erase(dialog_id); -RestrictedRights MessagesManager::get_dialog_default_permissions(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: - return td_->contacts_manager_->get_user_default_permissions(dialog_id.get_user_id()); - case DialogType::Chat: - return td_->contacts_manager_->get_chat_default_permissions(dialog_id.get_chat_id()); - case DialogType::Channel: - return td_->contacts_manager_->get_channel_default_permissions(dialog_id.get_channel_id()); - case DialogType::SecretChat: - return td_->contacts_manager_->get_secret_chat_default_permissions(dialog_id.get_secret_chat_id()); - case DialogType::None: - default: - UNREACHABLE(); - return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false); + const auto *d = get_dialog(dialog_id); + if (d != nullptr) { + update_dialogs_hints(d); } } -bool MessagesManager::get_dialog_has_protected_content(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: - return false; - case DialogType::Chat: - return td_->contacts_manager_->get_chat_has_protected_content(dialog_id.get_chat_id()); - case DialogType::Channel: - return td_->contacts_manager_->get_channel_has_protected_content(dialog_id.get_channel_id()); - case DialogType::SecretChat: - return false; - case DialogType::None: - default: - UNREACHABLE(); - return true; - } +bool MessagesManager::get_dialog_view_as_topics(const Dialog *d) const { + return !d->view_as_messages && (d->is_forum || d->dialog_id == td_->dialog_manager_->get_my_dialog_id()); } bool MessagesManager::get_dialog_has_scheduled_messages(const Dialog *d) const { - if (!have_input_peer(d->dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(d->dialog_id, true, AccessRights::Read)) { return false; } - if (is_broadcast_channel(d->dialog_id) && - !td_->contacts_manager_->get_channel_status(d->dialog_id.get_channel_id()).can_post_messages()) { + if (td_->dialog_manager_->is_broadcast_channel(d->dialog_id) && + !td_->chat_manager_->get_channel_status(d->dialog_id.get_channel_id()).can_post_messages()) { return false; } // TODO send updateChatHasScheduledMessage when can_post_messages changes @@ -32728,105 +31614,6 @@ MessagesManager::NotificationInfo *MessagesManager::add_dialog_notification_info return d->notification_info.get(); } -bool MessagesManager::is_dialog_action_unneeded(DialogId dialog_id) const { - if (is_anonymous_administrator(dialog_id, nullptr)) { - return true; - } - - auto dialog_type = dialog_id.get_type(); - if (dialog_type == DialogType::User || dialog_type == DialogType::SecretChat) { - UserId user_id = dialog_type == DialogType::User - ? dialog_id.get_user_id() - : td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); - if (td_->contacts_manager_->is_user_deleted(user_id)) { - return true; - } - if (td_->contacts_manager_->is_user_bot(user_id) && !td_->contacts_manager_->is_user_support(user_id)) { - return true; - } - if (user_id == td_->contacts_manager_->get_my_id()) { - return true; - } - - if (!td_->auth_manager_->is_bot()) { - if (td_->contacts_manager_->is_user_status_exact(user_id)) { - if (!td_->contacts_manager_->is_user_online(user_id, 30)) { - return true; - } - } else { - // return true; - } - } - } - return false; -} - -void MessagesManager::send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogAction action, - Promise &&promise) { - if (!have_dialog_force(dialog_id, "send_dialog_action")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (top_thread_message_id != MessageId() && - (!top_thread_message_id.is_valid() || !top_thread_message_id.is_server())) { - return promise.set_error(Status::Error(400, "Invalid message thread specified")); - } - - if (is_forum_channel(dialog_id) && !top_thread_message_id.is_valid()) { - top_thread_message_id = MessageId(ServerMessageId(1)); - } - - tl_object_ptr input_peer; - if (action == DialogAction::get_speaking_action()) { - input_peer = get_input_peer(dialog_id, AccessRights::Read); - if (input_peer == nullptr) { - return promise.set_error(Status::Error(400, "Have no access to the chat")); - } - } else { - auto can_send_status = can_send_message(dialog_id); - if (can_send_status.is_error()) { - if (td_->auth_manager_->is_bot()) { - return promise.set_error(std::move(can_send_status)); - } - return promise.set_value(Unit()); - } - - if (is_dialog_action_unneeded(dialog_id)) { - LOG(INFO) << "Skip unneeded " << action << " in " << dialog_id; - return promise.set_value(Unit()); - } - - input_peer = get_input_peer(dialog_id, AccessRights::Write); - } - - if (dialog_id.get_type() == DialogType::SecretChat) { - send_closure(G()->secret_chats_manager(), &SecretChatsManager::send_message_action, dialog_id.get_secret_chat_id(), - action.get_secret_input_send_message_action()); - promise.set_value(Unit()); - return; - } - - auto new_query_ref = - td_->create_handler(std::move(promise)) - ->send(dialog_id, std::move(input_peer), top_thread_message_id, action.get_input_send_message_action()); - if (td_->auth_manager_->is_bot()) { - return; - } - - auto &query_ref = set_typing_query_[dialog_id]; - if (!query_ref.empty()) { - LOG(INFO) << "Cancel previous send chat action query"; - cancel_query(query_ref); - } - query_ref = std::move(new_query_ref); -} - -void MessagesManager::after_set_typing_query(DialogId dialog_id, int32 generation) { - auto it = set_typing_query_.find(dialog_id); - if (it != set_typing_query_.end() && (!it->second.is_alive() || it->second.generation() == generation)) { - set_typing_query_.erase(it); - } -} - void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) { LOG(INFO) << "Receive send_chat_action timeout in " << dialog_id; Dialog *d = get_dialog(dialog_id); @@ -32854,15 +31641,14 @@ void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) { } CHECK(m->message_id.is_yet_unsent()); if (m->forward_info != nullptr || m->had_forward_info || m->is_copy || m->message_id.is_scheduled() || - m->sender_dialog_id.is_valid()) { + m->sender_dialog_id.is_valid() || m->content->get_type() == MessageContentType::PaidMedia || + td_->dialog_manager_->is_broadcast_channel(dialog_id)) { return; } auto file_id = get_message_content_upload_file_id(m->content.get()); if (!file_id.is_valid()) { - LOG(ERROR) << "Have no file in " - << to_string(get_message_content_object(m->content.get(), td_, dialog_id, m->date, m->is_content_secret, - false, -1)); + LOG(ERROR) << "Have no file in " << to_string(get_message_message_content_object(dialog_id, m)); return; } auto file_view = td_->file_manager_->get_file_view(file_id); @@ -32884,46 +31670,30 @@ void MessagesManager::on_send_dialog_action_timeout(DialogId dialog_id) { return; } LOG(INFO) << "Send " << action << " in " << dialog_id; - send_dialog_action(dialog_id, m->top_thread_message_id, std::move(action), Promise()); + td_->dialog_action_manager_->send_dialog_action(dialog_id, m->top_thread_message_id, {}, std::move(action), + Promise()); } -void MessagesManager::on_active_dialog_action_timeout(DialogId dialog_id) { - LOG(DEBUG) << "Receive active dialog action timeout in " << dialog_id; - auto actions_it = active_dialog_actions_.find(dialog_id); - if (actions_it == active_dialog_actions_.end()) { - return; - } - CHECK(!actions_it->second.empty()); - - auto now = Time::now(); - DialogId prev_typing_dialog_id; - while (actions_it->second[0].start_time + DIALOG_ACTION_TIMEOUT < now + 0.1) { - CHECK(actions_it->second[0].typing_dialog_id != prev_typing_dialog_id); - prev_typing_dialog_id = actions_it->second[0].typing_dialog_id; - on_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].typing_dialog_id, - DialogAction(), 0); - - actions_it = active_dialog_actions_.find(dialog_id); - if (actions_it == active_dialog_actions_.end()) { - return; - } - CHECK(!actions_it->second.empty()); - } +void MessagesManager::get_dialog_filter_dialog_count(td_api::object_ptr filter, + Promise &&promise) { + TRY_RESULT_PROMISE(promise, dialog_filter, + DialogFilter::create_dialog_filter(td_, DialogFilterId(), std::move(filter))); - LOG(DEBUG) << "Schedule next action timeout in " << dialog_id; - active_dialog_action_timeout_.add_timeout_in(dialog_id.get(), - actions_it->second[0].start_time + DIALOG_ACTION_TIMEOUT - now); -} + int32 total_count = 0; + for (auto folder_id : dialog_filter->get_folder_ids()) { + const auto &folder = *get_dialog_folder(folder_id); + for (const auto &dialog_date : folder.ordered_dialogs_) { + if (dialog_date.get_order() == DEFAULT_ORDER) { + break; + } -void MessagesManager::clear_active_dialog_actions(DialogId dialog_id) { - LOG(DEBUG) << "Clear active dialog actions in " << dialog_id; - auto actions_it = active_dialog_actions_.find(dialog_id); - while (actions_it != active_dialog_actions_.end()) { - CHECK(!actions_it->second.empty()); - on_dialog_action(dialog_id, actions_it->second[0].top_thread_message_id, actions_it->second[0].typing_dialog_id, - DialogAction(), 0); - actions_it = active_dialog_actions_.find(dialog_id); + auto dialog_id = dialog_date.get_dialog_id(); + if (dialog_filter->need_dialog(td_, get_dialog_info_for_dialog_filter(get_dialog(dialog_id)))) { + total_count++; + } + } } + promise.set_value(std::move(total_count)); } void MessagesManager::add_dialog_list_for_dialog_filter(DialogFilterId dialog_filter_id) { @@ -33224,7 +31994,8 @@ vector MessagesManager::get_dialog_lists_to_add_dialog(DialogId di return result; } - if (dialog_id != get_my_dialog_id() && dialog_id != DialogId(ContactsManager::get_service_notifications_user_id())) { + if (dialog_id != td_->dialog_manager_->get_my_dialog_id() && + dialog_id != DialogId(UserManager::get_service_notifications_user_id())) { result.push_back( DialogListId(get_dialog(dialog_id)->folder_id == FolderId::archive() ? FolderId::main() : FolderId::archive())); } @@ -33239,13 +32010,7 @@ void MessagesManager::add_dialog_to_list(DialogId dialog_id, DialogListId dialog LOG(INFO) << "Receive addChatToList request to add " << dialog_id << " to " << dialog_list_id; CHECK(!td_->auth_manager_->is_bot()); - Dialog *d = get_dialog_force(dialog_id, "add_dialog_to_list"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Read, "add_dialog_to_list")); if (d->order == DEFAULT_ORDER) { return promise.set_error(Status::Error(400, "Chat is not in a chat list")); @@ -33256,8 +32021,8 @@ void MessagesManager::add_dialog_to_list(DialogId dialog_id, DialogListId dialog } if (dialog_list_id.is_filter()) { - return promise.set_result( - td_->dialog_filter_manager_->add_dialog(dialog_list_id.get_filter_id(), get_input_dialog_id(dialog_id))); + return promise.set_result(td_->dialog_filter_manager_->add_dialog( + dialog_list_id.get_filter_id(), td_->dialog_manager_->get_input_dialog_id(dialog_id))); } CHECK(dialog_list_id.is_folder()); @@ -33266,9 +32031,8 @@ void MessagesManager::add_dialog_to_list(DialogId dialog_id, DialogListId dialog return promise.set_value(Unit()); } - if (folder_id == FolderId::archive() && - (dialog_id == get_my_dialog_id() || - dialog_id == DialogId(ContactsManager::get_service_notifications_user_id()))) { + if (folder_id == FolderId::archive() && (dialog_id == td_->dialog_manager_->get_my_dialog_id() || + dialog_id == DialogId(UserManager::get_service_notifications_user_id()))) { return promise.set_error(Status::Error(400, "Chat can't be archived")); } @@ -33331,171 +32095,6 @@ void MessagesManager::on_updated_dialog_folder_id(DialogId dialog_id, uint64 gen delete_log_event(d->set_folder_id_log_event_id, generation, "set chat folder"); } -void MessagesManager::set_dialog_photo(DialogId dialog_id, const tl_object_ptr &input_photo, - Promise &&promise) { - if (!have_dialog_force(dialog_id, "set_dialog_photo")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - switch (dialog_id.get_type()) { - case DialogType::User: - return promise.set_error(Status::Error(400, "Can't change private chat photo")); - case DialogType::Chat: { - auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_permissions(chat_id); - if (!status.can_change_info_and_settings() || - (td_->auth_manager_->is_bot() && !td_->contacts_manager_->is_appointed_chat_administrator(chat_id))) { - return promise.set_error(Status::Error(400, "Not enough rights to change chat photo")); - } - break; - } - case DialogType::Channel: { - auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()); - if (!status.can_change_info_and_settings()) { - return promise.set_error(Status::Error(400, "Not enough rights to change chat photo")); - } - break; - } - case DialogType::SecretChat: - return promise.set_error(Status::Error(400, "Can't change secret chat photo")); - case DialogType::None: - default: - UNREACHABLE(); - } - - const td_api::object_ptr *input_file = nullptr; - double main_frame_timestamp = 0.0; - bool is_animation = false; - if (input_photo != nullptr) { - switch (input_photo->get_id()) { - case td_api::inputChatPhotoPrevious::ID: { - auto photo = static_cast(input_photo.get()); - auto file_id = td_->contacts_manager_->get_profile_photo_file_id(photo->chat_photo_id_); - if (!file_id.is_valid()) { - return promise.set_error(Status::Error(400, "Unknown profile photo ID specified")); - } - - auto file_view = td_->file_manager_->get_file_view(file_id); - auto input_chat_photo = - make_tl_object(file_view.main_remote_location().as_input_photo()); - return send_edit_dialog_photo_query(dialog_id, file_id, std::move(input_chat_photo), std::move(promise)); - } - case td_api::inputChatPhotoStatic::ID: { - auto photo = static_cast(input_photo.get()); - input_file = &photo->photo_; - break; - } - case td_api::inputChatPhotoAnimation::ID: { - auto photo = static_cast(input_photo.get()); - input_file = &photo->animation_; - main_frame_timestamp = photo->main_frame_timestamp_; - is_animation = true; - break; - } - case td_api::inputChatPhotoSticker::ID: { - auto photo = static_cast(input_photo.get()); - TRY_RESULT_PROMISE(promise, sticker_photo_size, StickerPhotoSize::get_sticker_photo_size(td_, photo->sticker_)); - - int32 flags = telegram_api::inputChatUploadedPhoto::VIDEO_EMOJI_MARKUP_MASK; - auto input_chat_photo = make_tl_object( - flags, nullptr, nullptr, 0.0, sticker_photo_size->get_input_video_size_object(td_)); - return send_edit_dialog_photo_query(dialog_id, FileId(), std::move(input_chat_photo), std::move(promise)); - } - default: - UNREACHABLE(); - break; - } - } - if (input_file == nullptr) { - send_edit_dialog_photo_query(dialog_id, FileId(), make_tl_object(), - std::move(promise)); - return; - } - - const double MAX_ANIMATION_DURATION = 10.0; - if (main_frame_timestamp < 0.0 || main_frame_timestamp > MAX_ANIMATION_DURATION) { - return promise.set_error(Status::Error(400, "Wrong main frame timestamp specified")); - } - - auto file_type = is_animation ? FileType::Animation : FileType::Photo; - TRY_RESULT_PROMISE(promise, file_id, - td_->file_manager_->get_input_file_id(file_type, *input_file, dialog_id, true, false)); - if (!file_id.is_valid()) { - send_edit_dialog_photo_query(dialog_id, FileId(), make_tl_object(), - std::move(promise)); - return; - } - - upload_dialog_photo(dialog_id, td_->file_manager_->dup_file_id(file_id, "set_dialog_photo"), is_animation, - main_frame_timestamp, false, std::move(promise)); -} - -void MessagesManager::send_edit_dialog_photo_query(DialogId dialog_id, FileId file_id, - tl_object_ptr &&input_chat_photo, - Promise &&promise) { - // TODO invoke after - td_->create_handler(std::move(promise))->send(dialog_id, file_id, std::move(input_chat_photo)); -} - -void MessagesManager::upload_dialog_photo(DialogId dialog_id, FileId file_id, bool is_animation, - double main_frame_timestamp, bool is_reupload, Promise &&promise, - vector bad_parts) { - CHECK(file_id.is_valid()); - LOG(INFO) << "Ask to upload chat photo " << file_id; - bool is_inserted = being_uploaded_dialog_photos_ - .emplace(file_id, UploadedDialogPhotoInfo{dialog_id, main_frame_timestamp, is_animation, - is_reupload, std::move(promise)}) - .second; - CHECK(is_inserted); - // TODO use force_reupload if is_reupload - td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_dialog_photo_callback_, 32, 0); -} - -void MessagesManager::set_dialog_title(DialogId dialog_id, const string &title, Promise &&promise) { - if (!have_dialog_force(dialog_id, "set_dialog_title")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - auto new_title = clean_name(title, MAX_TITLE_LENGTH); - if (new_title.empty()) { - return promise.set_error(Status::Error(400, "Title must be non-empty")); - } - - switch (dialog_id.get_type()) { - case DialogType::User: - return promise.set_error(Status::Error(400, "Can't change private chat title")); - case DialogType::Chat: { - auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_permissions(chat_id); - if (!status.can_change_info_and_settings() || - (td_->auth_manager_->is_bot() && !td_->contacts_manager_->is_appointed_chat_administrator(chat_id))) { - return promise.set_error(Status::Error(400, "Not enough rights to change chat title")); - } - break; - } - case DialogType::Channel: { - auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()); - if (!status.can_change_info_and_settings()) { - return promise.set_error(Status::Error(400, "Not enough rights to change chat title")); - } - break; - } - case DialogType::SecretChat: - return promise.set_error(Status::Error(400, "Can't change secret chat title")); - case DialogType::None: - default: - UNREACHABLE(); - } - - // TODO this can be wrong if there were previous change title requests - if (get_dialog_title(dialog_id) == new_title) { - return promise.set_value(Unit()); - } - - // TODO invoke after - td_->create_handler(std::move(promise))->send(dialog_id, new_title); -} - void MessagesManager::set_dialog_available_reactions( DialogId dialog_id, td_api::object_ptr &&available_reactions_ptr, Promise &&promise) { @@ -33504,9 +32103,10 @@ void MessagesManager::set_dialog_available_reactions( return promise.set_error(Status::Error(400, "Chat not found")); } - ChatReactions available_reactions(std::move(available_reactions_ptr), !is_broadcast_channel(dialog_id)); + ChatReactions available_reactions(std::move(available_reactions_ptr), + !td_->dialog_manager_->is_broadcast_channel(dialog_id)); auto active_reactions = get_active_reactions(available_reactions); - if (active_reactions.reactions_.size() != available_reactions.reactions_.size()) { + if (active_reactions.reaction_types_.size() != available_reactions.reaction_types_.size()) { return promise.set_error(Status::Error(400, "Invalid reactions specified")); } available_reactions = std::move(active_reactions); @@ -33516,15 +32116,15 @@ void MessagesManager::set_dialog_available_reactions( return promise.set_error(Status::Error(400, "Can't change private chat available reactions")); case DialogType::Chat: { auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_permissions(chat_id); + auto status = td_->chat_manager_->get_chat_permissions(chat_id); if (!status.can_change_info_and_settings() || - (td_->auth_manager_->is_bot() && !td_->contacts_manager_->is_appointed_chat_administrator(chat_id))) { + (td_->auth_manager_->is_bot() && !td_->chat_manager_->is_appointed_chat_administrator(chat_id))) { return promise.set_error(Status::Error(400, "Not enough rights to change chat available reactions")); } break; } case DialogType::Channel: { - auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()); + auto status = td_->chat_manager_->get_channel_permissions(dialog_id.get_channel_id()); if (!status.can_change_info_and_settings()) { return promise.set_error(Status::Error(400, "Not enough rights to change chat available reactions")); } @@ -33555,26 +32155,18 @@ void MessagesManager::set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Prom return promise.set_error(Status::Error(400, "Message auto-delete time can't be negative")); } - Dialog *d = get_dialog_force(dialog_id, "set_dialog_message_ttl"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Write)) { - return promise.set_error(Status::Error(400, "Have no write access to the chat")); - } - - LOG(INFO) << "Begin to set message auto-delete time in " << dialog_id << " to " << ttl; + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Write, "set_dialog_message_ttl")); switch (dialog_id.get_type()) { case DialogType::User: - if (dialog_id == get_my_dialog_id() || - dialog_id == DialogId(ContactsManager::get_service_notifications_user_id())) { + if (dialog_id == td_->dialog_manager_->get_my_dialog_id() || + dialog_id == DialogId(UserManager::get_service_notifications_user_id())) { return promise.set_error(Status::Error(400, "Message auto-delete time in the chat can't be changed")); } break; case DialogType::Chat: { auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_permissions(chat_id); + auto status = td_->chat_manager_->get_chat_permissions(chat_id); if (!status.can_change_info_and_settings()) { return promise.set_error( Status::Error(400, "Not enough rights to change message auto-delete time in the chat")); @@ -33582,7 +32174,7 @@ void MessagesManager::set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Prom break; } case DialogType::Channel: { - auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()); + auto status = td_->chat_manager_->get_channel_permissions(dialog_id.get_channel_id()); if (!status.can_change_info_and_settings()) { return promise.set_error( Status::Error(400, "Not enough rights to change message auto-delete time in the chat")); @@ -33601,8 +32193,9 @@ void MessagesManager::set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Prom td_->create_handler(std::move(promise))->send(dialog_id, ttl); } else { bool need_update_dialog_pos = false; - Message *m = get_message_to_send(d, MessageId(), MessageId(), MessageSendOptions(), - create_chat_set_ttl_message_content(ttl, UserId()), &need_update_dialog_pos); + Message *m = + get_message_to_send(d, MessageId(), MessageInputReplyTo(), MessageSendOptions(), + create_chat_set_ttl_message_content(ttl, UserId()), false, &need_update_dialog_pos); send_update_new_message(d, m); if (need_update_dialog_pos) { @@ -33616,109 +32209,8 @@ void MessagesManager::set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Prom } } -void MessagesManager::set_dialog_permissions(DialogId dialog_id, - const td_api::object_ptr &permissions, - Promise &&promise) { - if (!have_dialog_force(dialog_id, "set_dialog_permissions")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Write)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - - if (permissions == nullptr) { - return promise.set_error(Status::Error(400, "New permissions must be non-empty")); - } - - switch (dialog_id.get_type()) { - case DialogType::User: - return promise.set_error(Status::Error(400, "Can't change private chat permissions")); - case DialogType::Chat: { - auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_permissions(chat_id); - if (!status.can_restrict_members()) { - return promise.set_error(Status::Error(400, "Not enough rights to change chat permissions")); - } - break; - } - case DialogType::Channel: { - if (is_broadcast_channel(dialog_id)) { - return promise.set_error(Status::Error(400, "Can't change channel chat permissions")); - } - auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()); - if (!status.can_restrict_members()) { - return promise.set_error(Status::Error(400, "Not enough rights to change chat permissions")); - } - break; - } - case DialogType::SecretChat: - return promise.set_error(Status::Error(400, "Can't change secret chat permissions")); - case DialogType::None: - default: - UNREACHABLE(); - } - - RestrictedRights new_permissions(permissions); - - // TODO this can be wrong if there were previous change permissions requests - if (get_dialog_default_permissions(dialog_id) == new_permissions) { - return promise.set_value(Unit()); - } - - // TODO invoke after - td_->create_handler(std::move(promise))->send(dialog_id, new_permissions); -} - -void MessagesManager::toggle_dialog_has_protected_content(DialogId dialog_id, bool has_protected_content, - Promise &&promise) { - if (!have_dialog_force(dialog_id, "toggle_dialog_has_protected_content")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } - - switch (dialog_id.get_type()) { - case DialogType::User: - case DialogType::SecretChat: - return promise.set_error(Status::Error(400, "Can't restrict saving content in the chat")); - case DialogType::Chat: { - auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_status(chat_id); - if (!status.is_creator()) { - return promise.set_error(Status::Error(400, "Only owner can restrict saving content")); - } - break; - } - case DialogType::Channel: { - auto status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()); - if (!status.is_creator()) { - return promise.set_error(Status::Error(400, "Only owner can restrict saving content")); - } - break; - } - case DialogType::None: - default: - UNREACHABLE(); - } - - // TODO this can be wrong if there were previous toggle_dialog_has_protected_content requests - if (get_dialog_has_protected_content(dialog_id) == has_protected_content) { - return promise.set_value(Unit()); - } - - // TODO invoke after - td_->create_handler(std::move(promise))->send(dialog_id, has_protected_content); -} - void MessagesManager::set_dialog_theme(DialogId dialog_id, const string &theme_name, Promise &&promise) { - auto d = get_dialog_force(dialog_id, "set_dialog_theme"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!have_input_peer(dialog_id, AccessRights::Write)) { - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + TRY_RESULT_PROMISE(promise, d, check_dialog_access(dialog_id, true, AccessRights::Write, "set_dialog_theme")); switch (dialog_id.get_type()) { case DialogType::User: @@ -33727,7 +32219,7 @@ void MessagesManager::set_dialog_theme(DialogId dialog_id, const string &theme_n case DialogType::Channel: return promise.set_error(Status::Error(400, "Can't change theme in the chat")); case DialogType::SecretChat: { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); if (!user_id.is_valid()) { return promise.set_error(Status::Error(400, "Can't access the user")); } @@ -33748,82 +32240,20 @@ void MessagesManager::set_dialog_theme(DialogId dialog_id, const string &theme_n td_->create_handler(std::move(promise))->send(dialog_id, theme_name); } -void MessagesManager::set_dialog_description(DialogId dialog_id, const string &description, Promise &&promise) { - if (!have_dialog_force(dialog_id, "set_dialog_description")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - - switch (dialog_id.get_type()) { - case DialogType::User: - return promise.set_error(Status::Error(400, "Can't change private chat description")); - case DialogType::Chat: - return td_->contacts_manager_->set_chat_description(dialog_id.get_chat_id(), description, std::move(promise)); - case DialogType::Channel: - return td_->contacts_manager_->set_channel_description(dialog_id.get_channel_id(), description, - std::move(promise)); - case DialogType::SecretChat: - return promise.set_error(Status::Error(400, "Can't change secret chat description")); - case DialogType::None: - default: - UNREACHABLE(); - } -} - -Status MessagesManager::can_pin_messages(DialogId dialog_id) const { - switch (dialog_id.get_type()) { - case DialogType::User: - break; - case DialogType::Chat: { - auto chat_id = dialog_id.get_chat_id(); - auto status = td_->contacts_manager_->get_chat_permissions(chat_id); - if (!status.can_pin_messages() || - (td_->auth_manager_->is_bot() && !td_->contacts_manager_->is_appointed_chat_administrator(chat_id))) { - return Status::Error(400, "Not enough rights to manage pinned messages in the chat"); - } - break; - } - case DialogType::Channel: { - auto status = td_->contacts_manager_->get_channel_permissions(dialog_id.get_channel_id()); - bool can_pin = is_broadcast_channel(dialog_id) ? status.can_edit_messages() : status.can_pin_messages(); - if (!can_pin) { - return Status::Error(400, "Not enough rights to manage pinned messages in the chat"); - } - break; +void MessagesManager::pin_dialog_message(BusinessConnectionId business_connection_id, DialogId dialog_id, + MessageId message_id, bool disable_notification, bool only_for_self, + bool is_unpin, Promise &&promise) { + bool as_business = business_connection_id.is_valid(); + if (as_business) { + TRY_STATUS_PROMISE(promise, + td_->business_connection_manager_->check_business_connection(business_connection_id, dialog_id)); + } else { + auto d = get_dialog_force(dialog_id, "pin_dialog_message"); + if (d == nullptr) { + return promise.set_error(Status::Error(400, "Chat not found")); } - case DialogType::SecretChat: - return Status::Error(400, "Secret chats can't have pinned messages"); - case DialogType::None: - default: - UNREACHABLE(); - } - if (!have_input_peer(dialog_id, AccessRights::Write)) { - return Status::Error(400, "Not enough rights"); - } - - return Status::OK(); -} - -void MessagesManager::pin_dialog_message(DialogId dialog_id, MessageId message_id, bool disable_notification, - bool only_for_self, bool is_unpin, Promise &&promise) { - auto d = get_dialog_force(dialog_id, "pin_dialog_message"); - if (d == nullptr) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - TRY_STATUS_PROMISE(promise, can_pin_messages(dialog_id)); - - const Message *m = get_message_force(d, message_id, "pin_dialog_message"); - if (m == nullptr) { - return promise.set_error(Status::Error(400, "Message not found")); - } - if (message_id.is_scheduled()) { - return promise.set_error(Status::Error(400, "Scheduled message can't be pinned")); - } - if (!message_id.is_server()) { - return promise.set_error(Status::Error(400, "Message can't be pinned")); - } - - if (is_service_message_content(m->content->get_type())) { - return promise.set_error(Status::Error(400, "A service message can't be pinned")); + const Message *m = get_message_force(d, message_id, "pin_dialog_message"); + TRY_STATUS_PROMISE(promise, can_pin_message(dialog_id, m)); } if (only_for_self && dialog_id.get_type() != DialogType::User) { @@ -33832,7 +32262,7 @@ void MessagesManager::pin_dialog_message(DialogId dialog_id, MessageId message_i // TODO log event td_->create_handler(std::move(promise)) - ->send(dialog_id, message_id, is_unpin, disable_notification, only_for_self); + ->send(business_connection_id, dialog_id, message_id, is_unpin, disable_notification, only_for_self); } void MessagesManager::unpin_all_dialog_messages(DialogId dialog_id, MessageId top_thread_message_id, @@ -33841,8 +32271,8 @@ void MessagesManager::unpin_all_dialog_messages(DialogId dialog_id, MessageId to if (d == nullptr) { return promise.set_error(Status::Error(400, "Chat not found")); } - TRY_STATUS_PROMISE(promise, can_pin_messages(dialog_id)); - TRY_STATUS_PROMISE(promise, can_use_top_thread_message_id(d, top_thread_message_id, MessageId())); + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->can_pin_messages(dialog_id)); + TRY_STATUS_PROMISE(promise, can_use_top_thread_message_id(d, top_thread_message_id, MessageInputReplyTo())); if (!td_->auth_manager_->is_bot()) { auto message_ids = find_dialog_messages(d, [top_thread_message_id](const Message *m) { @@ -33942,7 +32372,7 @@ const MessagesManager::Message *MessagesManager::get_message(const Dialog *d, Me } else { result = d->messages.get_pointer(message_id); if (result != nullptr) { - auto unix_time = G()->unix_time_cached(); + auto unix_time = G()->unix_time(); if (unix_time > result->last_access_date + 5) { result->last_access_date = unix_time; auto list_node = const_cast(static_cast(result)); @@ -33955,6 +32385,10 @@ const MessagesManager::Message *MessagesManager::get_message(const Dialog *d, Me return result; } +const MessagesManager::Message *MessagesManager::get_message_static(const Dialog *d, MessageId message_id) { + return get_message(d, message_id); +} + MessagesManager::Message *MessagesManager::get_message_force(Dialog *d, MessageId message_id, const char *source) { if (!message_id.is_valid() && !message_id.is_valid_scheduled()) { return nullptr; @@ -33973,7 +32407,7 @@ MessagesManager::Message *MessagesManager::get_message_force(Dialog *d, MessageI return nullptr; } - LOG(INFO) << "Trying to load " << FullMessageId{d->dialog_id, message_id} << " from database from " << source; + LOG(INFO) << "Trying to load " << MessageFullId{d->dialog_id, message_id} << " from database from " << source; auto r_value = G()->td_db()->get_message_db_sync()->get_message({d->dialog_id, message_id}); if (r_value.is_error()) { @@ -34033,7 +32467,7 @@ MessagesManager::Message *MessagesManager::on_get_message_from_database(Dialog * CHECK(d != nullptr); auto dialog_id = d->dialog_id; - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { return nullptr; } @@ -34079,7 +32513,7 @@ vector MessagesManager::on_get_messages_from_database(Dialog *d, vect MessageId first_message_id, bool &have_error, const char *source) { vector result; - if (!first_message_id.is_valid() || !have_input_peer(d->dialog_id, AccessRights::Read)) { + if (!first_message_id.is_valid() || !td_->dialog_manager_->have_input_peer(d->dialog_id, true, AccessRights::Read)) { return result; } bool need_update = false; @@ -34128,11 +32562,11 @@ void MessagesManager::fix_new_message(const Dialog *d, Message *m, bool from_dat DialogId dialog_id = d->dialog_id; if (!has_message_sender_user_id(dialog_id, m) && !m->sender_dialog_id.is_valid()) { - if (is_broadcast_channel(dialog_id)) { + if (td_->dialog_manager_->is_broadcast_channel(dialog_id)) { m->sender_dialog_id = dialog_id; } else { if (is_discussion_message(dialog_id, m)) { - m->sender_dialog_id = m->forward_info->from_dialog_id; + m->sender_dialog_id = m->forward_info->get_last_dialog_id(); } else { LOG(ERROR) << "Failed to repair sender chat in " << m->message_id << " in " << dialog_id; } @@ -34140,8 +32574,8 @@ void MessagesManager::fix_new_message(const Dialog *d, Message *m, bool from_dat } auto dialog_type = dialog_id.get_type(); - if (m->sender_user_id == ContactsManager::get_anonymous_bot_user_id() && !m->sender_dialog_id.is_valid() && - dialog_type == DialogType::Channel && !is_broadcast_channel(dialog_id)) { + if (m->sender_user_id == UserManager::get_anonymous_bot_user_id() && !m->sender_dialog_id.is_valid() && + dialog_type == DialogType::Channel && !td_->dialog_manager_->is_broadcast_channel(dialog_id)) { m->sender_user_id = UserId(); m->sender_dialog_id = dialog_id; } @@ -34166,7 +32600,7 @@ void MessagesManager::fix_new_message(const Dialog *d, Message *m, bool from_dat if (m->message_id.is_scheduled() && !m->message_id.is_yet_unsent()) { m->top_thread_message_id = MessageId(); } else if (m->top_thread_message_id.is_valid()) { - if (is_broadcast_channel(dialog_id)) { + if (td_->dialog_manager_->is_broadcast_channel(dialog_id)) { m->top_thread_message_id = MessageId(); } } else { @@ -34175,9 +32609,9 @@ void MessagesManager::fix_new_message(const Dialog *d, Message *m, bool from_dat } } - m->last_access_date = G()->unix_time_cached(); + m->last_access_date = G()->unix_time(); - if (m->contains_mention) { + if (!from_database && m->contains_mention) { CHECK(!td_->auth_manager_->is_bot()); auto message_content_type = m->content->get_type(); if (message_content_type == MessageContentType::PinMessage) { @@ -34199,7 +32633,7 @@ void MessagesManager::fix_new_message(const Dialog *d, Message *m, bool from_dat if (dialog_type == DialogType::Channel && !m->contains_unread_mention) { auto channel_read_media_period = td_->option_manager_->get_option_integer("channels_read_media_period", (G()->is_test_dc() ? 300 : 7 * 86400)); - if (m->date < G()->unix_time_cached() - channel_read_media_period) { + if (m->date < G()->unix_time() - channel_read_media_period) { update_opened_message_content(m->content.get()); } } @@ -34223,6 +32657,50 @@ void MessagesManager::remove_message_remove_keyboard_reply_markup(Message *m) co m->reply_markup = nullptr; } +void MessagesManager::update_replied_by_message_count(DialogId dialog_id, const Message *m, bool is_add) { + CHECK(m != nullptr); + if (!m->message_id.is_yet_unsent()) { + return; + } + const auto *input_reply_to = get_message_input_reply_to(m); + if (input_reply_to == nullptr || input_reply_to->is_empty()) { + return; + } + auto replied_message_full_id = input_reply_to->get_reply_message_full_id(dialog_id); + auto replied_message_id = replied_message_full_id.get_message_id(); + if (!replied_message_id.is_valid() && !replied_message_id.is_valid_scheduled()) { + return; + } + if (!replied_message_id.is_yet_unsent()) { + if (!replied_message_id.is_scheduled()) { + if (is_add) { + replied_by_yet_unsent_messages_[replied_message_full_id]++; + } else { + auto it = replied_by_yet_unsent_messages_.find(replied_message_full_id); + CHECK(it != replied_by_yet_unsent_messages_.end()); + it->second--; + if (it->second == 0) { + replied_by_yet_unsent_messages_.erase(it); + } else { + CHECK(it->second > 0); + } + } + } + } else { + if (is_add) { + replied_yet_unsent_messages_[replied_message_full_id].insert({dialog_id, m->message_id}); + } else { + auto it = replied_yet_unsent_messages_.find(replied_message_full_id); + CHECK(it != replied_yet_unsent_messages_.end()); + size_t erased_count = it->second.erase({dialog_id, m->message_id}); + CHECK(erased_count > 0); + if (it->second.empty()) { + replied_yet_unsent_messages_.erase(it); + } + } + } +} + void MessagesManager::add_message_to_dialog_message_list(const Message *m, Dialog *d, const bool from_database, const bool from_update, const bool need_update, bool *need_update_dialog_pos, const char *source) { @@ -34253,9 +32731,9 @@ void MessagesManager::add_message_to_dialog_message_list(const Message *m, Dialo if (!(d->have_full_history && from_update) && d->last_message_id.is_valid() && d->last_message_id < MessageId(ServerMessageId(1)) && message_id >= MessageId(ServerMessageId(1))) { - set_dialog_last_message_id(d, MessageId(), "add_message_to_dialog"); + set_dialog_last_message_id(d, MessageId(), "add_message_to_dialog_message_list"); - set_dialog_first_database_message_id(d, MessageId(), "add_message_to_dialog"); + set_dialog_first_database_message_id(d, MessageId(), "add_message_to_dialog_message_list"); set_dialog_last_database_message_id(d, MessageId(), source); d->have_full_history = false; d->have_full_history_source = 0; @@ -34271,7 +32749,7 @@ void MessagesManager::add_message_to_dialog_message_list(const Message *m, Dialo if (from_update && !m->is_failed_to_send && message_id > d->last_new_message_id && !message_id.is_yet_unsent()) { if (dialog_type == DialogType::SecretChat || message_id.is_server()) { // can delete messages, therefore must be called before message attaching/adding - set_dialog_last_new_message_id(d, message_id, "add_message_to_dialog"); + set_dialog_last_new_message_id(d, message_id, "add_message_to_dialog_message_list"); } } @@ -34294,7 +32772,7 @@ void MessagesManager::add_message_to_dialog_message_list(const Message *m, Dialo if (message_id.is_server() && d->last_read_inbox_message_id.is_valid() && d->last_read_inbox_message_id.is_server() && message_id == d->last_read_inbox_message_id.get_next_message_id(MessageType::Server)) { - read_history_inbox(d, message_id, 0, "add_message_to_dialog"); + read_history_inbox(d, message_id, 0, "add_message_to_dialog_message_list"); } } } @@ -34304,13 +32782,13 @@ void MessagesManager::add_message_to_dialog_message_list(const Message *m, Dialo } if (need_update && has_unread_message_reactions(dialog_id, m)) { set_dialog_unread_reaction_count(d, d->unread_reaction_count + 1); - send_update_chat_unread_reaction_count(d, "add_message_to_dialog"); + send_update_chat_unread_reaction_count(d, "add_message_to_dialog_message_list"); } if (need_update) { update_message_count_by_index(d, +1, m); } if (from_update && message_id > d->last_message_id && message_id >= d->last_new_message_id) { - set_dialog_last_message_id(d, message_id, "add_message_to_dialog", m); + set_dialog_last_message_id(d, message_id, "add_message_to_dialog_message_list", m); *need_update_dialog_pos = true; } if (from_update && !message_id.is_yet_unsent() && message_id >= d->last_new_message_id && @@ -34320,9 +32798,9 @@ void MessagesManager::add_message_to_dialog_message_list(const Message *m, Dialo (d->last_database_message_id.is_valid() && message_id > d->last_database_message_id))))) { CHECK(message_id <= d->last_message_id); if (message_id > d->last_database_message_id) { - set_dialog_last_database_message_id(d, message_id, "add_message_to_dialog"); + set_dialog_last_database_message_id(d, message_id, "add_message_to_dialog_message_list"); if (!d->first_database_message_id.is_valid()) { - set_dialog_first_database_message_id(d, message_id, "add_message_to_dialog"); + set_dialog_first_database_message_id(d, message_id, "add_message_to_dialog_message_list"); try_restore_dialog_reply_markup(d, m); } } @@ -34350,8 +32828,7 @@ void MessagesManager::add_message_to_dialog_message_list(const Message *m, Dialo on_dialog_updated(dialog_id, "do delete last message"); - send_closure_later(actor_id(this), &MessagesManager::get_history_from_the_end, dialog_id, false, false, - Promise()); + send_closure_later(actor_id(this), &MessagesManager::load_last_dialog_message_later, dialog_id); } d->ordered_messages.insert(message_id, from_update, old_last_message_id, source); @@ -34435,7 +32912,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq << to_string(get_message_object(dialog_id, message.get(), "add_message_to_dialog")); if (need_channel_difference_to_add_message(dialog_id, nullptr)) { - schedule_get_channel_difference(dialog_id, 0, MessageId(), 0.001); + schedule_get_channel_difference(dialog_id, 0, MessageId(), 0.001, "add_message_to_dialog"); } } else { LOG(INFO) << "Ignore " << message_id << " in " << dialog_id << " received not through update from " << source; @@ -34515,7 +32992,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq CHECK(m->message_id == message_id); CHECK(message->message_id == message_id); LOG(INFO) << "Adding already existing " << message_id << " in " << dialog_id << " from " << source; - if (*need_update) { + if (*need_update && !td_->auth_manager_->is_bot()) { *need_update = false; if (!G()->use_message_database()) { // can happen if the message is received first through getMessage in an unknown chat without @@ -34532,7 +33009,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq const int32 INDEX_MASK_MASK = ~(message_search_filter_index_mask(MessageSearchFilter::UnreadMention) | message_search_filter_index_mask(MessageSearchFilter::UnreadReaction)); auto old_index_mask = get_message_index_mask(dialog_id, m) & INDEX_MASK_MASK; - bool was_deleted = delete_active_live_location(dialog_id, m); + bool was_deleted = delete_active_live_location({dialog_id, m->message_id}); auto old_file_ids = get_message_file_ids(m); bool need_send_update = update_message(d, m, std::move(message), true); @@ -34541,7 +33018,12 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq } auto new_index_mask = get_message_index_mask(dialog_id, m) & INDEX_MASK_MASK; if (was_deleted) { - try_add_active_live_location(dialog_id, m); + if (!try_add_active_live_location(dialog_id, m)) { + send_update_active_live_location_messages(); + save_active_live_locations(); + } else { + schedule_active_live_location_expiration(); + } } change_message_files(dialog_id, m, old_file_ids); if (need_send_update) { @@ -34583,9 +33065,9 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq Message *top_m = get_message(d, message->top_thread_message_id); CHECK(top_m != nullptr); if (is_active_message_reply_info(dialog_id, top_m->reply_info) && is_discussion_message(dialog_id, top_m)) { - FullMessageId top_full_message_id{top_m->forward_info->from_dialog_id, top_m->forward_info->from_message_id}; - if (have_message_force(top_full_message_id, "preload discussed message")) { - LOG(INFO) << "Preloaded discussed " << top_full_message_id << " from database"; + auto linked_message_full_id = top_m->forward_info->get_last_message_full_id(); + if (have_message_force(linked_message_full_id, "preload discussed message")) { + LOG(INFO) << "Preloaded discussed " << linked_message_full_id << " from database"; } } } @@ -34609,13 +33091,14 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq d->max_added_message_id = message->message_id; } - if (d->open_count == 0 && !d->has_unload_timeout && !d->messages.empty() && is_message_unload_enabled()) { + if (d->open_count == 0 && !d->has_unload_timeout && is_message_unload_enabled() && + (!d->messages.empty() || !from_database)) { LOG(INFO) << "Schedule unload of " << dialog_id; pending_unload_dialog_timeout_.add_timeout_in(dialog_id.get(), get_next_unload_dialog_delay(d)); d->has_unload_timeout = true; } - if (message->ttl > 0 && message->ttl_expires_at != 0) { + if (message->ttl.is_valid() && message->ttl_expires_at != 0) { auto now = Time::now(); if (message->ttl_expires_at <= now) { if (dialog_type == DialogType::SecretChat) { @@ -34626,7 +33109,7 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq d->being_added_message_id = MessageId(); return nullptr; } else { - on_message_ttl_expired_impl(d, message.get()); + on_message_ttl_expired_impl(d, message.get(), false); message_content_type = message->content->get_type(); if (from_database) { on_message_changed(d, message.get(), false, "add expired message to dialog"); @@ -34691,14 +33174,14 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq auto notification_id = message->notification_id; VLOG(notifications) << "Remove mention " << notification_id << " in " << message_id << " in " << dialog_id; message->notification_id = NotificationId(); - if (d->notification_info->mention_notification_group_.last_notification_id == notification_id) { + if (d->notification_info->mention_notification_group_.get_last_notification_id() == notification_id) { // last notification is deleted, need to find new last notification fix_dialog_last_notification_id(d, true, message_id); } send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification, - d->notification_info->mention_notification_group_.group_id, notification_id, false, false, - Promise(), "remove disabled mention notification"); + d->notification_info->mention_notification_group_.get_group_id(), notification_id, false, + false, Promise(), "remove disabled mention notification"); on_message_changed(d, message.get(), false, "remove_mention_notification"); } @@ -34711,36 +33194,28 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq add_message_to_dialog_message_list(m, d, from_database, from_update, *need_update, need_update_dialog_pos, source); } - if (m->message_id.is_yet_unsent() && m->reply_to_message_id != MessageId()) { - if (!m->reply_to_message_id.is_yet_unsent()) { - if (!m->reply_to_message_id.is_scheduled()) { - replied_by_yet_unsent_messages_[FullMessageId{dialog_id, m->reply_to_message_id}]++; - } - } else { - replied_yet_unsent_messages_[FullMessageId{dialog_id, m->reply_to_message_id}].insert(m->message_id); - } - } + update_replied_by_message_count(dialog_id, m, true); if (!from_database && !m->message_id.is_yet_unsent()) { add_message_to_database(d, m, "add_message_to_dialog"); } if (from_update && !m->is_failed_to_send && dialog_type == DialogType::Channel) { - auto now = max(G()->unix_time_cached(), m->date); + auto now = max(G()->unix_time(), m->date); if (m->date < now - 2 * 86400 && Slice(source) == Slice("updateNewChannelMessage")) { // if the message is pretty old, we might have missed the update that the message has already been read repair_channel_server_unread_count(d); } if (m->date + 3600 >= now && m->is_outgoing) { auto channel_id = dialog_id.get_channel_id(); - auto slow_mode_delay = td_->contacts_manager_->get_channel_slow_mode_delay(channel_id, "add_message_to_dialog"); - auto status = td_->contacts_manager_->get_channel_status(dialog_id.get_channel_id()); + auto slow_mode_delay = td_->chat_manager_->get_channel_slow_mode_delay(channel_id, "add_message_to_dialog"); + auto status = td_->chat_manager_->get_channel_status(dialog_id.get_channel_id()); if (m->date + slow_mode_delay > now && !status.is_administrator()) { - td_->contacts_manager_->on_update_channel_slow_mode_next_send_date(channel_id, m->date + slow_mode_delay); + td_->chat_manager_->on_update_channel_slow_mode_next_send_date(channel_id, m->date + slow_mode_delay); } } if (m->date > now - 14 * 86400) { - td_->contacts_manager_->remove_inactive_channel(dialog_id.get_channel_id()); + td_->chat_manager_->remove_inactive_channel(dialog_id.get_channel_id()); } } @@ -34749,6 +33224,16 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq on_dialog_updated(dialog_id, "update_has_contact_registered_message"); } + if (m->sender_user_id.is_valid()) { + auto story_full_id = get_message_content_story_full_id(td_, m->content.get()); + if (story_full_id.is_valid()) { + td_->story_manager_->on_story_replied(story_full_id, m->sender_user_id); + } + if (m->reply_to_story_full_id.is_valid()) { + td_->story_manager_->on_story_replied(m->reply_to_story_full_id, m->sender_user_id); + } + } + reget_message_from_server_if_needed(dialog_id, m); add_message_file_sources(dialog_id, m); @@ -34758,17 +33243,30 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq register_message_reply(dialog_id, m); if (*need_update && m->message_id.is_server()) { - if (message_content_type == MessageContentType::PinMessage) { - auto pinned_message_id = get_message_content_pinned_message_id(m->content.get()); - if (d->is_last_pinned_message_id_inited && pinned_message_id > d->last_pinned_message_id) { - set_dialog_last_pinned_message_id(d, pinned_message_id); + switch (message_content_type) { + case MessageContentType::PinMessage: { + auto pinned_message_id = get_message_content_pinned_message_id(m->content.get()); + if (d->is_last_pinned_message_id_inited && pinned_message_id > d->last_pinned_message_id) { + set_dialog_last_pinned_message_id(d, pinned_message_id); + } + break; } - } - if (message_content_type == MessageContentType::SetBackground) { - set_dialog_background(d, get_message_content_background_info(m->content.get())); - } - if (message_content_type == MessageContentType::ChatSetTheme) { - set_dialog_theme_name(d, get_message_content_theme_name(m->content.get())); + case MessageContentType::SetBackground: + set_dialog_background(d, get_message_content_my_background_info( + m->content.get(), m->is_outgoing || dialog_id.get_type() != DialogType::User)); + break; + case MessageContentType::ChatSetTheme: + set_dialog_theme_name(d, get_message_content_theme_name(m->content.get())); + break; + case MessageContentType::ChatCreate: + case MessageContentType::ChannelCreate: + if (m->ttl_period > 0) { + set_dialog_message_ttl(d, MessageTtl(m->ttl_period)); + } + break; + default: + // nothing to do + break; } } @@ -34782,21 +33280,22 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq cancel_dialog_action(dialog_id, m); update_has_outgoing_messages(dialog_id, m); - if (!td_->auth_manager_->is_bot() && d->messages.empty() && !m->is_outgoing && dialog_id != get_my_dialog_id()) { + if (!td_->auth_manager_->is_bot() && d->messages.empty() && !m->is_outgoing && + dialog_id != td_->dialog_manager_->get_my_dialog_id()) { switch (dialog_type) { case DialogType::User: - td_->contacts_manager_->invalidate_user_full(dialog_id.get_user_id()); - td_->contacts_manager_->reload_user_full(dialog_id.get_user_id(), Promise()); + td_->user_manager_->invalidate_user_full(dialog_id.get_user_id()); + td_->user_manager_->reload_user_full(dialog_id.get_user_id(), Promise(), "add_message_to_dialog"); break; case DialogType::Chat: case DialogType::Channel: // nothing to do break; case DialogType::SecretChat: { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); if (user_id.is_valid()) { - td_->contacts_manager_->invalidate_user_full(user_id); - td_->contacts_manager_->reload_user_full(user_id, Promise()); + td_->user_manager_->invalidate_user_full(user_id); + td_->user_manager_->reload_user_full(user_id, Promise(), "add_message_to_dialog"); } break; } @@ -34816,13 +33315,6 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq d->message_lru_list.put_back(result_message); - if (m->message_id.is_yet_unsent() && !m->message_id.is_scheduled() && m->top_thread_message_id.is_valid() && - !td_->auth_manager_->is_bot()) { - auto is_inserted = - yet_unsent_thread_message_ids_[FullMessageId{dialog_id, m->top_thread_message_id}].insert(m->message_id).second; - CHECK(is_inserted); - } - switch (dialog_type) { case DialogType::User: case DialogType::Chat: @@ -34831,9 +33323,9 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq } break; case DialogType::Channel: - if (m->message_id.is_server()) { - td_->contacts_manager_->register_message_users({dialog_id, m->message_id}, get_message_user_ids(m)); - td_->contacts_manager_->register_message_channels({dialog_id, m->message_id}, get_message_channel_ids(m)); + if (!td_->auth_manager_->is_bot() && m->message_id.is_server()) { + td_->user_manager_->register_message_users({dialog_id, m->message_id}, get_message_user_ids(m)); + td_->chat_manager_->register_message_channels({dialog_id, m->message_id}, get_message_channel_ids(m)); } break; case DialogType::SecretChat: @@ -34843,19 +33335,38 @@ MessagesManager::Message *MessagesManager::add_message_to_dialog(Dialog *d, uniq UNREACHABLE(); } - if (m->notification_id.is_valid()) { - auto notification_info = add_dialog_notification_info(d); - add_notification_id_to_message_id_correspondence(notification_info, m->notification_id, m->message_id); - } if (m->message_id.is_yet_unsent() || dialog_type == DialogType::SecretChat) { add_random_id_to_message_id_correspondence(d, m->random_id, m->message_id); } - try_add_bot_command_message_id(dialog_id, m); + if (!td_->auth_manager_->is_bot()) { + if (m->message_id.is_yet_unsent() && !m->message_id.is_scheduled() && m->top_thread_message_id.is_valid()) { + auto is_inserted = yet_unsent_thread_message_ids_[MessageFullId{dialog_id, m->top_thread_message_id}] + .insert(m->message_id) + .second; + CHECK(is_inserted); + } + + if (dialog_type == DialogType::User && !m->is_outgoing) { + td_->user_manager_->allow_send_message_to_user(dialog_id.get_user_id()); + } + + if (m->notification_id.is_valid()) { + auto notification_info = add_dialog_notification_info(d); + add_notification_id_to_message_id_correspondence(notification_info, m->notification_id, m->message_id); + } + + try_add_bot_command_message_id(dialog_id, m); - // must be called after the message is added to correctly update replies - update_message_max_reply_media_timestamp(d, result_message, false); - update_message_max_own_media_timestamp(d, result_message); + // must be called after the message is added to correctly update replies + update_message_max_reply_media_timestamp(d, result_message, false); + update_message_max_own_media_timestamp(d, result_message); + + if (from_update && m->saved_messages_topic_id.is_valid()) { + CHECK(dialog_id == td_->dialog_manager_->get_my_dialog_id()); + td_->saved_messages_manager_->set_topic_last_message_id(m->saved_messages_topic_id, m->message_id, m->date); + } + } result_message->debug_source = source; d->being_added_message_id = MessageId(); @@ -34897,9 +33408,9 @@ MessagesManager::Message *MessagesManager::add_scheduled_message_to_dialog(Dialo debug_add_message_to_dialog_fail_reason_ = "skip adding scheduled message to secret chat"; return nullptr; } - if (message->ttl != 0 || message->ttl_expires_at != 0) { - LOG(ERROR) << "Tried to add " << message_id << " with self-destruct timer " << message->ttl << '/' - << message->ttl_expires_at << " to " << dialog_id << " from " << source; + if (message->ttl != MessageSelfDestructType() || message->ttl_expires_at != 0) { + LOG(ERROR) << "Tried to add " << message_id << " with " << message->ttl << '/' << message->ttl_expires_at << " to " + << dialog_id << " from " << source; debug_add_message_to_dialog_fail_reason_ = "skip adding secret scheduled message"; return nullptr; } @@ -34917,8 +33428,7 @@ MessagesManager::Message *MessagesManager::add_scheduled_message_to_dialog(Dialo auto message_content_type = message->content->get_type(); if (is_service_message_content(message_content_type) || message_content_type == MessageContentType::LiveLocation || - message_content_type == MessageContentType::ExpiredPhoto || - message_content_type == MessageContentType::ExpiredVideo) { + is_expired_message_content(message_content_type)) { LOG(ERROR) << "Tried to add " << message_id << " of type " << message_content_type << " to " << dialog_id << " from " << source; debug_add_message_to_dialog_fail_reason_ = "skip adding message of unexpected type"; @@ -34954,15 +33464,8 @@ MessagesManager::Message *MessagesManager::add_scheduled_message_to_dialog(Dialo LOG(INFO) << "Adding not found " << message_id << " to " << dialog_id << " from " << source; const Message *m = message.get(); - if (m->message_id.is_yet_unsent() && m->reply_to_message_id != MessageId()) { - if (!m->reply_to_message_id.is_yet_unsent()) { - if (!m->reply_to_message_id.is_scheduled()) { - replied_by_yet_unsent_messages_[FullMessageId{dialog_id, m->reply_to_message_id}]++; - } - } else { - replied_yet_unsent_messages_[FullMessageId{dialog_id, m->reply_to_message_id}].insert(m->message_id); - } - } + + update_replied_by_message_count(dialog_id, m, true); if (!from_database && !m->message_id.is_yet_unsent()) { add_message_to_database(d, m, "add_scheduled_message_to_dialog"); @@ -35006,7 +33509,7 @@ MessagesManager::Message *MessagesManager::add_scheduled_message_to_dialog(Dialo auto is_inserted = scheduled_messages->scheduled_messages_.emplace(result_message->message_id, std::move(message)).second; CHECK(is_inserted); - being_readded_message_id_ = FullMessageId(); + being_readded_message_id_ = MessageFullId(); return result_message; } @@ -35037,8 +33540,8 @@ void MessagesManager::register_new_local_message_id(Dialog *d, const Message *m) void MessagesManager::on_message_changed(const Dialog *d, const Message *m, bool need_send_update, const char *source) { CHECK(d != nullptr); CHECK(m != nullptr); - if (need_send_update && m->message_id == d->last_message_id) { - send_update_chat_last_message_impl(d, source); + if (need_send_update) { + send_update_last_message_if_needed(d, m, source); } if (m->message_id == d->last_database_message_id) { @@ -35055,24 +33558,23 @@ void MessagesManager::on_message_notification_changed(Dialog *d, const Message * CHECK(m != nullptr); if (m->notification_id.is_valid() && is_message_notification_active(d, m)) { auto &group_info = get_notification_group_info(d, m); - if (group_info.group_id.is_valid()) { - send_closure_later(G()->notification_manager(), &NotificationManager::edit_notification, group_info.group_id, - m->notification_id, + if (group_info.is_valid()) { + send_closure_later(G()->notification_manager(), &NotificationManager::edit_notification, + group_info.get_group_id(), m->notification_id, create_new_message_notification( m->message_id, is_message_preview_enabled(d, m, is_from_mention_notification_group(m)))); } } if (m->is_pinned && d->notification_info != nullptr && d->notification_info->pinned_message_notification_message_id_.is_valid() && - d->notification_info->mention_notification_group_.group_id.is_valid()) { - auto pinned_message = - get_message_force(d, d->notification_info->pinned_message_notification_message_id_, "after update_message"); + d->notification_info->mention_notification_group_.is_valid()) { + auto pinned_message = get_message_force(d, d->notification_info->pinned_message_notification_message_id_, source); if (pinned_message != nullptr && pinned_message->notification_id.is_valid() && is_message_notification_active(d, pinned_message) && get_message_content_pinned_message_id(pinned_message->content.get()) == m->message_id) { send_closure_later( G()->notification_manager(), &NotificationManager::edit_notification, - d->notification_info->mention_notification_group_.group_id, pinned_message->notification_id, + d->notification_info->mention_notification_group_.get_group_id(), pinned_message->notification_id, create_new_message_notification(pinned_message->message_id, is_message_preview_enabled(d, m, true))); } } @@ -35088,7 +33590,7 @@ void MessagesManager::add_message_to_database(const Dialog *d, const Message *m, MessageId message_id = m->message_id; if (message_id.is_scheduled()) { - LOG(INFO) << "Add " << FullMessageId(d->dialog_id, message_id) << " to database from " << source; + LOG(INFO) << "Add " << MessageFullId(d->dialog_id, message_id) << " to database from " << source; set_dialog_has_scheduled_database_messages(d->dialog_id, true); G()->td_db()->get_message_db_async()->add_scheduled_message({d->dialog_id, message_id}, log_event_store(*m), @@ -35097,7 +33599,7 @@ void MessagesManager::add_message_to_database(const Dialog *d, const Message *m, } LOG_CHECK(message_id.is_server() || message_id.is_local()) << source; - LOG(INFO) << "Add " << FullMessageId(d->dialog_id, message_id) << " to database from " << source; + LOG(INFO) << "Add " << MessageFullId(d->dialog_id, message_id) << " to database from " << source; ServerMessageId unique_message_id; int64 random_id = 0; @@ -35143,22 +33645,26 @@ void MessagesManager::add_message_to_database(const Dialog *d, const Message *m, Auto()); // TODO Promise } +void MessagesManager::delete_all_dialog_notifications(Dialog *d, MessageId max_message_id, const char *source) { + CHECK(d != nullptr); + if (d->notification_info == nullptr) { + return; + } + if (d->notification_info->new_secret_chat_notification_id_.is_valid()) { + remove_new_secret_chat_notification(d, true); + } + if (d->notification_info->pinned_message_notification_message_id_.is_valid() && + d->notification_info->pinned_message_notification_message_id_ <= max_message_id) { + remove_dialog_pinned_message_notification(d, source); + } + remove_message_dialog_notifications(d, max_message_id, false, source); + remove_message_dialog_notifications(d, max_message_id, true, source); +} + void MessagesManager::delete_all_dialog_messages_from_database(Dialog *d, MessageId max_message_id, const char *source) { CHECK(d != nullptr); CHECK(max_message_id.is_valid()); - if (d->notification_info != nullptr) { - if (d->notification_info->new_secret_chat_notification_id_.is_valid()) { - remove_new_secret_chat_notification(d, true); - } - if (d->notification_info->pinned_message_notification_message_id_.is_valid() && - d->notification_info->pinned_message_notification_message_id_ <= max_message_id) { - remove_dialog_pinned_message_notification(d, source); - } - remove_message_dialog_notifications(d, max_message_id, false, source); - remove_message_dialog_notifications(d, max_message_id, true, source); - } - if (!G()->use_message_database()) { return; } @@ -35183,14 +33689,13 @@ void MessagesManager::delete_all_dialog_messages_from_database(Dialog *d, Messag } } */ - G()->td_db()->get_message_db_async()->delete_all_dialog_messages(dialog_id, max_message_id, - Auto()); // TODO Promise + G()->td_db()->get_message_db_async()->delete_all_dialog_messages(dialog_id, max_message_id, Auto()); // TODO Promise } class MessagesManager::DeleteMessageLogEvent { public: LogEvent::Id id_{0}; - FullMessageId full_message_id_; + MessageFullId message_full_id_; std::vector file_ids_; template @@ -35200,7 +33705,7 @@ class MessagesManager::DeleteMessageLogEvent { STORE_FLAG(has_file_ids); END_STORE_FLAGS(); - td::store(full_message_id_, storer); + td::store(message_full_id_, storer); if (has_file_ids) { td::store(file_ids_, storer); } @@ -35213,7 +33718,7 @@ class MessagesManager::DeleteMessageLogEvent { PARSE_FLAG(has_file_ids); END_PARSE_FLAGS(); - td::parse(full_message_id_, parser); + td::parse(message_full_id_, parser); if (has_file_ids) { td::parse(file_ids_, parser); } @@ -35228,17 +33733,17 @@ void MessagesManager::delete_message_files(DialogId dialog_id, const Message *m) } } -bool MessagesManager::need_delete_file(FullMessageId full_message_id, FileId file_id) const { - if (being_readded_message_id_ == full_message_id || td_->auth_manager_->is_bot()) { +bool MessagesManager::need_delete_file(MessageFullId message_full_id, FileId file_id) const { + if (being_readded_message_id_ == message_full_id || td_->auth_manager_->is_bot()) { return false; } auto main_file_id = td_->file_manager_->get_file_view(file_id).get_main_file_id(); - auto full_message_ids = td_->file_reference_manager_->get_some_message_file_sources(main_file_id); - LOG(INFO) << "Receive " << full_message_ids << " as sources for file " << main_file_id << "/" << file_id << " from " - << full_message_id; - for (const auto &other_full_messsage_id : full_message_ids) { - if (other_full_messsage_id != full_message_id) { + auto message_full_ids = td_->file_reference_manager_->get_some_message_file_sources(main_file_id); + LOG(INFO) << "Receive " << message_full_ids << " as sources for file " << main_file_id << "/" << file_id << " from " + << message_full_id; + for (const auto &other_full_message_id : message_full_ids) { + if (other_full_message_id != message_full_id) { return false; } } @@ -35255,15 +33760,14 @@ bool MessagesManager::need_delete_message_files(DialogId dialog_id, const Messag if (!m->message_id.is_scheduled() && !m->message_id.is_server() && dialog_type != DialogType::SecretChat) { return false; } - if (being_readded_message_id_ == FullMessageId{dialog_id, m->message_id}) { + if (being_readded_message_id_ == MessageFullId{dialog_id, m->message_id}) { return false; } - if (m->forward_info != nullptr && m->forward_info->from_dialog_id.is_valid() && - m->forward_info->from_message_id.is_valid()) { + if (m->forward_info != nullptr && m->forward_info->get_last_dialog_id().is_valid()) { // this function must not try to load the message, because it can be called from // do_delete_message or add_scheduled_message_to_dialog - const Message *old_m = get_message({m->forward_info->from_dialog_id, m->forward_info->from_message_id}); + const Message *old_m = get_message(m->forward_info->get_last_message_full_id()); if (old_m != nullptr && get_message_file_ids(old_m) == get_message_file_ids(m)) { return false; } @@ -35315,7 +33819,7 @@ void MessagesManager::delete_message_from_database(Dialog *d, MessageId message_ auto old_message_id = find_old_message_id(d->dialog_id, message_id); if (old_message_id.is_valid()) { bool have_old_message = get_message(d, old_message_id) != nullptr; - LOG(WARNING) << "Sent " << FullMessageId{d->dialog_id, message_id} + LOG(WARNING) << "Sent " << MessageFullId{d->dialog_id, message_id} << " was deleted before it was received. Have old " << old_message_id << " = " << have_old_message; send_closure_later(actor_id(this), &MessagesManager::delete_messages, d->dialog_id, vector{old_message_id}, false, Promise()); @@ -35329,22 +33833,23 @@ void MessagesManager::delete_message_from_database(Dialog *d, MessageId message_ auto from_mentions = is_from_mention_notification_group(m); auto &group_info = get_notification_group_info(d, from_mentions); - if (group_info.group_id.is_valid()) { - if (group_info.last_notification_id == m->notification_id) { + if (group_info.is_valid()) { + if (group_info.get_last_notification_id() == m->notification_id) { // last notification is deleted, need to find new last notification fix_dialog_last_notification_id(d, from_mentions, m->message_id); } if (is_message_notification_active(d, m)) { - send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification, group_info.group_id, - m->notification_id, true, false, Promise(), "delete_message_from_database"); + send_closure_later(G()->notification_manager(), &NotificationManager::remove_notification, + group_info.get_group_id(), m->notification_id, true, false, Promise(), + "delete_message_from_database"); } } } else if (!message_id.is_scheduled() && message_id > d->last_new_message_id && d->notification_info != nullptr) { - send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_message_id, - d->notification_info->message_notification_group_.group_id, message_id, false, + send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_object_id, + d->notification_info->message_notification_group_.get_group_id(), message_id, false, "delete_message_from_database"); - send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_message_id, - d->notification_info->mention_notification_group_.group_id, message_id, false, + send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_object_id, + d->notification_info->mention_notification_group_.get_group_id(), message_id, false, "delete_message_from_database"); } @@ -35356,7 +33861,7 @@ void MessagesManager::delete_message_from_database(Dialog *d, MessageId message_ if (G()->use_message_database()) { DeleteMessageLogEvent log_event; - log_event.full_message_id_ = {d->dialog_id, message_id}; + log_event.message_full_id_ = {d->dialog_id, message_id}; if (need_delete_files) { log_event.file_ids_ = get_message_file_ids(m); @@ -35397,7 +33902,7 @@ void MessagesManager::do_delete_message_log_event(const DeleteMessageLogEvent &l auto lock = mpas.get_promise(); for (auto file_id : log_event.file_ids_) { - if (need_delete_file(log_event.full_message_id_, file_id)) { + if (need_delete_file(log_event.message_full_id_, file_id)) { send_closure(G()->file_manager(), &FileManager::delete_file, file_id, mpas.get_promise(), "do_delete_message_log_event"); } @@ -35407,8 +33912,20 @@ void MessagesManager::do_delete_message_log_event(const DeleteMessageLogEvent &l } // message may not exist in the dialog - LOG(INFO) << "Delete " << log_event.full_message_id_ << " from database"; - G()->td_db()->get_message_db_async()->delete_message(log_event.full_message_id_, std::move(db_promise)); + LOG(INFO) << "Delete " << log_event.message_full_id_ << " from database"; + G()->td_db()->get_message_db_async()->delete_message(log_event.message_full_id_, std::move(db_promise)); +} + +int64 MessagesManager::get_message_reply_to_random_id(const Dialog *d, const Message *m) const { + auto same_chat_reply_to_message_id = m->replied_message_info.get_same_chat_reply_to_message_id(false); + if (same_chat_reply_to_message_id != MessageId() && m->message_id.is_yet_unsent() && + (d->dialog_id.get_type() == DialogType::SecretChat || same_chat_reply_to_message_id.is_yet_unsent())) { + auto *replied_m = get_message(d, same_chat_reply_to_message_id); + if (replied_m != nullptr) { + return replied_m->random_id; + } + } + return 0; } bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr new_message, @@ -35512,67 +34029,41 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr old_message->sender_dialog_id = new_message->sender_dialog_id; need_send_update = true; } - if (old_message->forward_info == nullptr) { - if (new_message->forward_info != nullptr) { - if (!replace_legacy) { - LOG(ERROR) << message_id << " in " << dialog_id << " has received forward info " << *new_message->forward_info - << ", really forwarded from " << old_message->real_forward_from_message_id << " in " - << old_message->real_forward_from_dialog_id << ", message content type is " << old_content_type - << '/' << new_content_type; - } else { - LOG(DEBUG) << "Message forward has changed to " << *new_message->forward_info; - } - old_message->forward_info = std::move(new_message->forward_info); - need_send_update = true; - } - } else { - if (new_message->forward_info != nullptr) { - if (old_message->forward_info->author_signature != new_message->forward_info->author_signature) { - old_message->forward_info->author_signature = new_message->forward_info->author_signature; - LOG(DEBUG) << "Change message signature"; - need_send_update = true; - } - if (*old_message->forward_info != *new_message->forward_info) { - bool need_warning = [&] { - if (replace_legacy) { - return false; - } - if (old_message->forward_info->is_imported != new_message->forward_info->is_imported) { - return true; - } - if (!is_scheduled && !message_id.is_yet_unsent() && !old_message->forward_info->is_imported) { - return true; - } - return !is_forward_info_sender_hidden(new_message->forward_info.get()) && - !is_forward_info_sender_hidden(old_message->forward_info.get()); - }(); - if (need_warning) { - LOG(ERROR) << message_id << " in " << dialog_id << " has changed forward info from " - << *old_message->forward_info << " to " << *new_message->forward_info << ", really forwarded from " - << old_message->real_forward_from_message_id << " in " << old_message->real_forward_from_dialog_id - << ", message content type is " << old_content_type << '/' << new_content_type; - } else { - LOG(DEBUG) << "Message forward info has changed from " << *old_message->forward_info << " to " - << *new_message->forward_info; - } - old_message->forward_info = std::move(new_message->forward_info); - need_send_update = true; - } - } else if (is_new_available) { + if (old_message->sender_boost_count != new_message->sender_boost_count) { + LOG(DEBUG) << "Change sender boost count"; + old_message->sender_boost_count = new_message->sender_boost_count; + need_send_update = true; + } + if (old_message->forward_info != new_message->forward_info) { + if (!replace_legacy && is_new_available && + MessageForwardInfo::need_change_warning(old_message->forward_info.get(), new_message->forward_info.get(), + message_id)) { LOG(ERROR) << message_id << " in " << dialog_id << " sent by " << old_message->sender_user_id << "/" - << old_message->sender_dialog_id << " has lost forward info " << *old_message->forward_info - << ", really forwarded from " << old_message->real_forward_from_message_id << " in " - << old_message->real_forward_from_dialog_id << ", message content type is " << old_content_type << '/' - << new_content_type; - old_message->forward_info = nullptr; - need_send_update = true; + << old_message->sender_dialog_id << " has changed forward info from " << old_message->forward_info + << " to " << new_message->forward_info << ", really forwarded from " + << old_message->real_forward_from_message_id << " in " << old_message->real_forward_from_dialog_id + << ", message content type is " << old_content_type << '/' << new_content_type; + } else { + LOG(DEBUG) << "Message forward info has changed from " << old_message->forward_info << " to " + << new_message->forward_info; } + old_message->forward_info = std::move(new_message->forward_info); + need_send_update = true; } if (old_message->had_forward_info != new_message->had_forward_info) { LOG(DEBUG) << "Message had_forward_info has changed from " << old_message->had_forward_info << " to " << new_message->had_forward_info; old_message->had_forward_info = new_message->had_forward_info; } + if (old_message->saved_messages_topic_id != new_message->saved_messages_topic_id) { + if (!(message_id.is_yet_unsent() && (old_message->saved_messages_topic_id.is_author_hidden() || + new_message->saved_messages_topic_id.is_author_hidden()))) { + LOG(ERROR) << "Saved Messages topic for " << message_id << " in " << dialog_id << " changed from " + << old_message->saved_messages_topic_id << " to " << new_message->saved_messages_topic_id; + } + old_message->saved_messages_topic_id = new_message->saved_messages_topic_id; + need_send_update = true; + } if (old_message->notification_id != new_message->notification_id) { CHECK(!is_scheduled); if (old_message->notification_id.is_valid()) { @@ -35590,7 +34081,9 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr } } if (new_message->is_mention_notification_disabled) { - old_message->is_mention_notification_disabled = true; + // is_mention_notification_disabled must not be changed, because the message notification will not + // be moved to the other group + // old_message->is_mention_notification_disabled = true; } if (old_message->ttl_period != new_message->ttl_period) { @@ -35603,85 +34096,102 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr need_send_update = true; } } - - if (old_message->reply_to_message_id != new_message->reply_to_message_id) { - // Can't check "&& get_message_force(d, old_message->reply_to_message_id, "update_message") == nullptr", because it - // can change message tree and invalidate reference to old_message - if (new_message->reply_to_message_id == MessageId() || replace_legacy) { - LOG(DEBUG) << "Drop message reply_to_message_id"; - unregister_message_reply(dialog_id, old_message); - old_message->reply_to_message_id = MessageId(); - old_message->reply_in_dialog_id = DialogId(); - update_message_max_reply_media_timestamp(d, old_message, is_message_in_dialog); - need_send_update = true; - } else if (is_new_available) { - if (message_id.is_yet_unsent() && old_message->reply_to_message_id == MessageId() && - new_message->reply_in_dialog_id == DialogId() && is_deleted_message(d, new_message->reply_to_message_id) && - get_message(d, new_message->reply_to_message_id) == nullptr && !is_message_in_dialog) { - LOG(INFO) << "Update replied message from " << old_message->reply_to_message_id << " to deleted " - << new_message->reply_to_message_id; - old_message->reply_to_message_id = new_message->reply_to_message_id; - old_message->reply_in_dialog_id = DialogId(); - update_message_max_reply_media_timestamp(d, old_message, is_message_in_dialog); - need_send_update = true; - } else if (old_message->reply_to_message_id.is_valid_scheduled() && - old_message->reply_to_message_id.is_scheduled_server() && - new_message->reply_to_message_id.is_valid_scheduled() && - new_message->reply_to_message_id.is_scheduled_server() && - old_message->reply_to_message_id.get_scheduled_server_message_id() == - new_message->reply_to_message_id.get_scheduled_server_message_id() && - new_message->reply_in_dialog_id == DialogId()) { - // schedule date has changed - old_message->reply_to_message_id = new_message->reply_to_message_id; - old_message->reply_in_dialog_id = DialogId(); - need_send_update = true; - } else if (message_id.is_yet_unsent() && old_message->top_thread_message_id == new_message->reply_to_message_id && - new_message->reply_in_dialog_id == DialogId()) { - LOG(INFO) << "Update replied message from " << old_message->reply_to_message_id << " to top thread " - << new_message->reply_to_message_id; - unregister_message_reply(dialog_id, old_message); - old_message->reply_to_message_id = new_message->reply_to_message_id; - old_message->reply_in_dialog_id = DialogId(); - register_message_reply(dialog_id, old_message); - need_send_update = true; - } else { - LOG(ERROR) << message_id << " in " << dialog_id << " has changed replied message from " - << old_message->reply_to_message_id << " to " << new_message->reply_to_message_id - << ", message content type is " << old_content_type << '/' << new_content_type; + if (old_message->ttl != new_message->ttl && old_message->ttl_expires_at == 0) { + if (message_id.is_yet_unsent() || replace_legacy) { + LOG(INFO) << "Change message self-destruct time from " << old_message->ttl << " to " << new_message->ttl; + old_message->ttl = new_message->ttl; + } else { + LOG(INFO) << "Ignore message self-destruct time change from " << old_message->ttl << " to " << new_message->ttl; + } + } + + const bool is_replied_message_info_changed = old_message->replied_message_info != new_message->replied_message_info; + const bool is_top_thread_message_id_changed = + old_message->top_thread_message_id != new_message->top_thread_message_id; + const bool is_is_topic_message_changed = old_message->is_topic_message != new_message->is_topic_message; + if (is_replied_message_info_changed || is_top_thread_message_id_changed || is_is_topic_message_changed || + old_message->reply_to_story_full_id != new_message->reply_to_story_full_id) { + if (!replace_legacy && is_new_available) { + if (is_replied_message_info_changed) { + LOG(INFO) << "Update replied message of " << MessageFullId{dialog_id, message_id} << " from " + << old_message->replied_message_info << " to " << new_message->replied_message_info; + auto is_reply_to_deleted_message = [&](const RepliedMessageInfo &replied_message_info) { + auto reply_message_full_id = replied_message_info.get_reply_message_full_id(dialog_id, false); + auto *d = get_dialog(reply_message_full_id.get_dialog_id()); + if (d == nullptr) { + return false; + } + return is_deleted_message(d, reply_message_full_id.get_message_id()); + }; + if (RepliedMessageInfo::need_reply_changed_warning( + td_, old_message->replied_message_info, new_message->replied_message_info, + old_message->top_thread_message_id, message_id.is_yet_unsent() && !is_message_in_dialog, + is_reply_to_deleted_message)) { + const MessageInputReplyTo *message_input_reply_to = nullptr; + if (!message_id.is_any_server()) { + message_input_reply_to = get_message_input_reply_to(old_message); + } + LOG(ERROR) << message_id << " in " << dialog_id << " has changed replied message from " + << old_message->replied_message_info << '/' << message_input_reply_to << " to " + << new_message->replied_message_info << ", message content type is " << old_content_type << '/' + << new_content_type; + } } - } - } - if (old_message->reply_in_dialog_id != new_message->reply_in_dialog_id) { - if (new_message->reply_in_dialog_id == DialogId() || replace_legacy) { - LOG(DEBUG) << "Drop message reply_in_dialog_id"; - old_message->reply_in_dialog_id = DialogId(); - need_send_update = true; - } else if (is_new_available && old_message->reply_in_dialog_id.is_valid()) { - LOG(ERROR) << message_id << " in " << dialog_id << " has changed replied message chat from " - << old_message->reply_in_dialog_id << " to " << new_message->reply_in_dialog_id - << ", message content type is " << old_content_type << '/' << new_content_type; - } - } - if (old_message->top_thread_message_id != new_message->top_thread_message_id) { - if ((new_message->top_thread_message_id == MessageId() || old_message->top_thread_message_id == MessageId()) && - (!is_message_in_dialog || replace_legacy)) { - LOG(DEBUG) << "Change message thread from " << old_message->top_thread_message_id << " to " - << new_message->top_thread_message_id; - if (is_message_in_dialog && old_message->is_topic_message) { - if (old_message->top_thread_message_id != MessageId()) { - td_->forum_topic_manager_->on_topic_message_count_changed(dialog_id, old_message->top_thread_message_id, -1); + if (is_top_thread_message_id_changed) { + if ((new_message->top_thread_message_id != MessageId() && old_message->top_thread_message_id != MessageId()) || + is_message_in_dialog) { + LOG(ERROR) << message_id << " in " << dialog_id << " has changed message thread from " + << old_message->top_thread_message_id << " to " << new_message->top_thread_message_id + << ", message content type is " << old_content_type << '/' << new_content_type; + } else { + LOG(INFO) << "Update message thread of " << MessageFullId{dialog_id, message_id} << " from " + << old_message->top_thread_message_id << " to " << new_message->top_thread_message_id; } - if (new_message->top_thread_message_id != MessageId()) { - td_->forum_topic_manager_->on_topic_message_count_changed(dialog_id, new_message->top_thread_message_id, +1); + } + if (is_is_topic_message_changed) { + if (!message_id.is_yet_unsent()) { + LOG(ERROR) << message_id << " in " << dialog_id << " has changed is_topic_message to " + << new_message->is_topic_message; + } else { + LOG(INFO) << "Update is_topic_message of " << MessageFullId{dialog_id, message_id} << " from " + << old_message->is_topic_message << " to " << new_message->is_topic_message; } } - old_message->top_thread_message_id = new_message->top_thread_message_id; - need_send_update = true; - } else if (is_new_available) { - LOG(ERROR) << message_id << " in " << dialog_id << " has changed message thread from " - << old_message->top_thread_message_id << " to " << new_message->top_thread_message_id - << ", message content type is " << old_content_type << '/' << new_content_type; + if (old_message->reply_to_story_full_id != new_message->reply_to_story_full_id) { + if (!message_id.is_yet_unsent() || new_message->reply_to_story_full_id.is_valid() || is_message_in_dialog) { + LOG(ERROR) << message_id << " in " << dialog_id << " has changed replied story from " + << old_message->reply_to_story_full_id << " to " << new_message->reply_to_story_full_id + << ", message content type is " << old_content_type << '/' << new_content_type; + } else { + LOG(INFO) << "Update replied story of " << MessageFullId{dialog_id, message_id} << " from " + << old_message->reply_to_story_full_id << " to " << new_message->reply_to_story_full_id; + } + } + } + + if ((is_top_thread_message_id_changed || is_is_topic_message_changed) && is_message_in_dialog && + old_message->is_topic_message && old_message->top_thread_message_id != MessageId()) { + td_->forum_topic_manager_->on_topic_message_count_changed(dialog_id, old_message->top_thread_message_id, -1); + } + + if (is_message_in_dialog) { + unregister_message_reply(d->dialog_id, old_message); + } + old_message->replied_message_info = std::move(new_message->replied_message_info); + old_message->reply_to_story_full_id = new_message->reply_to_story_full_id; + old_message->top_thread_message_id = new_message->top_thread_message_id; + old_message->is_topic_message = new_message->is_topic_message; + old_message->reply_to_random_id = get_message_reply_to_random_id(d, old_message); + + if (is_message_in_dialog) { + register_message_reply(d->dialog_id, old_message); + } + update_message_max_reply_media_timestamp(d, old_message, is_message_in_dialog); + if ((is_top_thread_message_id_changed || is_is_topic_message_changed) && is_message_in_dialog && + old_message->is_topic_message && old_message->top_thread_message_id != MessageId()) { + td_->forum_topic_manager_->on_topic_message_count_changed(dialog_id, old_message->top_thread_message_id, +1); } + need_send_update = true; } if (old_message->via_bot_user_id != new_message->via_bot_user_id) { if ((!message_id.is_yet_unsent() || old_message->via_bot_user_id.is_valid()) && is_new_available && @@ -35700,8 +34210,12 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr old_message->hide_via_bot = false; } } + if (old_message->via_business_bot_user_id != new_message->via_business_bot_user_id) { + old_message->via_business_bot_user_id = new_message->via_business_bot_user_id; + need_send_update = true; + } if (old_message->is_outgoing != new_message->is_outgoing && is_new_available) { - if (!replace_legacy && !(message_id.is_scheduled() && dialog_id == get_my_dialog_id())) { + if (!replace_legacy && !(message_id.is_scheduled() && dialog_id == td_->dialog_manager_->get_my_dialog_id())) { LOG(ERROR) << message_id << " in " << dialog_id << " has changed is_outgoing from " << old_message->is_outgoing << " to " << new_message->is_outgoing << ", message content type is " << old_content_type << '/' << new_content_type; @@ -35720,25 +34234,9 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr << message_id << " in " << dialog_id << " has changed is_channel_post from " << old_message->is_channel_post << " to " << new_message->is_channel_post << ", message content type is " << old_content_type << '/' << new_content_type; - if (!old_message->top_thread_message_id.is_valid()) { - new_message->is_topic_message = false; - } - if (old_message->is_topic_message != new_message->is_topic_message && - old_message->top_thread_message_id == new_message->top_thread_message_id) { - if (is_message_in_dialog) { - td_->forum_topic_manager_->on_topic_message_count_changed( - dialog_id, old_message->top_thread_message_id, - static_cast(new_message->is_topic_message) - static_cast(old_message->is_topic_message)); - } - LOG_IF(ERROR, !message_id.is_yet_unsent() && !replace_legacy) - << message_id << " in " << dialog_id << " has changed is_topic_message to " << new_message->is_topic_message; - old_message->is_topic_message = new_message->is_topic_message; - need_send_update = true; - } if (old_message->contains_mention != new_message->contains_mention) { - if (old_message->edit_date == 0 && is_new_available && old_content_type != MessageContentType::PinMessage && - old_content_type != MessageContentType::ExpiredPhoto && old_content_type != MessageContentType::ExpiredVideo && - !replace_legacy) { + if (old_message->edit_date == 0 && is_new_available && new_content_type != MessageContentType::PinMessage && + !is_expired_message_content(new_content_type) && !replace_legacy) { LOG(ERROR) << message_id << " in " << dialog_id << " has changed contains_mention from " << old_message->contains_mention << " to " << new_message->contains_mention << ", is_outgoing = " << old_message->is_outgoing << ", message content type is " << old_content_type @@ -35759,9 +34257,6 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr // old_message->disable_notification = new_message->disable_notification; // need_send_update = true; } - if (old_message->disable_web_page_preview != new_message->disable_web_page_preview) { - old_message->disable_web_page_preview = new_message->disable_web_page_preview; - } if (old_message->noforwards != new_message->noforwards) { LOG(DEBUG) << "Message can_be_saved has changed from " << !old_message->noforwards << " to " @@ -35778,11 +34273,17 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr if (old_message->legacy_layer != new_message->legacy_layer) { old_message->legacy_layer = new_message->legacy_layer; } - if ((old_message->media_album_id == 0 || td_->auth_manager_->is_bot()) && new_message->media_album_id != 0) { + if (old_message->media_album_id != new_message->media_album_id && + (old_message->media_album_id == 0 || (new_message->media_album_id == 0 && message_id.is_yet_unsent()) || + td_->auth_manager_->is_bot())) { old_message->media_album_id = new_message->media_album_id; LOG(DEBUG) << "Update message media_album_id"; need_send_update = true; } + if (old_message->effect_id != new_message->effect_id) { + old_message->effect_id = new_message->effect_id; + need_send_update = true; + } if (old_message->hide_edit_date != new_message->hide_edit_date) { old_message->hide_edit_date = new_message->hide_edit_date; } @@ -35797,6 +34298,9 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr // is_from_scheduled flag shouldn't be changed, because we are unable to show/hide message notification // old_message->is_from_scheduled = new_message->is_from_scheduled; } + if (old_message->is_from_offline != new_message->is_from_offline) { + old_message->is_from_offline = new_message->is_from_offline; + } if (old_message->edit_date > 0) { // inline keyboard can be edited @@ -35882,11 +34386,30 @@ bool MessagesManager::update_message(Dialog *d, Message *old_message, unique_ptr "update_message")) { need_send_update = true; } + if (update_message_fact_check(d, old_message, std::move(new_message->fact_check), false)) { + need_send_update = true; + } + + bool is_preview_changed = false; + if (old_message->invert_media != new_message->invert_media) { + old_message->invert_media = new_message->invert_media; + is_preview_changed = true; + } + if (old_message->disable_web_page_preview != new_message->disable_web_page_preview) { + if (old_message->disable_web_page_preview) { + is_preview_changed = has_message_content_web_page(new_message->content.get()); + } else { + CHECK(new_message->disable_web_page_preview); + is_preview_changed = has_message_content_web_page(old_message->content.get()); + } + old_message->disable_web_page_preview = new_message->disable_web_page_preview; + } bool is_content_changed = false; if (update_message_content(dialog_id, old_message, std::move(new_message->content), message_id.is_yet_unsent() && new_message->edit_date == 0, is_message_in_dialog, - is_content_changed)) { + is_content_changed) || + is_preview_changed) { send_update_message_content(d, old_message, is_message_in_dialog, "update_message"); need_send_update = true; } @@ -35918,7 +34441,7 @@ bool MessagesManager::need_message_changed_warning(const Message *old_message) { // original message may be edited return false; } - if (old_message->ttl > 0) { + if (old_message->ttl.is_valid()) { // message can expire return false; } @@ -35938,52 +34461,38 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me MessageContentType old_content_type = old_content->get_type(); MessageContentType new_content_type = new_content->get_type(); - auto old_file_id = get_message_content_any_file_id(old_content.get()); - bool need_finish_upload = old_file_id.is_valid() && need_merge_files; + auto old_file_ids = get_message_content_any_file_ids(old_content.get()); if (old_content_type != new_content_type) { - if (old_message->ttl > 0 && old_message->ttl_expires_at > 0 && - ((new_content_type == MessageContentType::ExpiredPhoto && old_content_type == MessageContentType::Photo) || - (new_content_type == MessageContentType::ExpiredVideo && old_content_type == MessageContentType::Video))) { + if (old_message->ttl.is_valid() && old_message->ttl_expires_at > 0 && + is_expired_message_content(new_content_type) && + get_expired_message_content_type(old_content_type) == new_content_type) { LOG(INFO) << "Do not apply expired message content early"; } else { need_update = true; LOG(INFO) << "Message content has changed type from " << old_content_type << " to " << new_content_type; - old_message->is_content_secret = is_secret_message_content(old_message->ttl, new_content->get_type()); - } - - if (need_merge_files && old_file_id.is_valid()) { - auto new_file_id = get_message_content_any_file_id(new_content.get()); - if (new_file_id.is_valid()) { - FileView old_file_view = td_->file_manager_->get_file_view(old_file_id); - FileView new_file_view = td_->file_manager_->get_file_view(new_file_id); - // if file type has changed, but file size remains the same, we are trying to update local location of the new - // file with the old local location - if (old_file_view.has_local_location() && !new_file_view.has_local_location() && old_file_view.size() != 0 && - old_file_view.size() == new_file_view.size()) { - auto old_file_type = old_file_view.get_type(); - auto new_file_type = new_file_view.get_type(); - - if (is_document_file_type(old_file_type) && is_document_file_type(new_file_type)) { - auto &old_location = old_file_view.local_location(); - auto r_file_id = td_->file_manager_->register_local( - FullLocalFileLocation(new_file_type, old_location.path_, old_location.mtime_nsec_), dialog_id, - old_file_view.size()); - if (r_file_id.is_ok()) { - LOG_STATUS(td_->file_manager_->merge(new_file_id, r_file_id.ok())); - } - } + old_message->is_content_secret = old_message->ttl.is_secret_message_content(new_content->get_type()); + } + + if (need_merge_files) { + auto new_file_ids = get_message_content_any_file_ids(new_content.get()); + if (new_file_ids.size() == old_file_ids.size()) { + for (size_t i = 0; i < old_file_ids.size(); i++) { + td_->file_manager_->try_merge_documents(old_file_ids[i], new_file_ids[i]); } } } } else { merge_message_contents(td_, old_content.get(), new_content.get(), need_message_changed_warning(old_message), dialog_id, need_merge_files, is_content_changed, need_update); + compare_message_contents(td_, old_content.get(), new_content.get(), is_content_changed, need_update); } - if (need_finish_upload) { + if (need_merge_files) { // the file is likely to be already merged with a server file, but if not we need to // cancel file upload of the main file to allow next upload with the same file to succeed - cancel_upload_file(old_file_id, "update_message_content"); + for (auto old_file_id : old_file_ids) { + cancel_upload_file(old_file_id, "update_message_content"); + } } if (is_content_changed || need_update) { @@ -35993,9 +34502,9 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me } old_content = std::move(new_content); old_message->last_edit_pts = 0; - update_message_content_file_id_remote(old_content.get(), old_file_id); + update_message_content_file_id_remotes(old_content.get(), old_file_ids); } else { - update_message_content_file_id_remote(old_content.get(), get_message_content_any_file_id(new_content.get())); + update_message_content_file_id_remotes(old_content.get(), get_message_content_any_file_ids(new_content.get())); } if (is_content_changed && !need_update) { LOG(INFO) << "Content of " << old_message->message_id << " in " << dialog_id << " has changed"; @@ -36004,7 +34513,7 @@ bool MessagesManager::update_message_content(DialogId dialog_id, Message *old_me if (need_update) { auto file_ids = get_message_content_file_ids(old_content.get(), td_); if (!file_ids.empty()) { - auto file_source_id = get_message_file_source_id(FullMessageId(dialog_id, old_message->message_id)); + auto file_source_id = get_message_file_source_id(MessageFullId(dialog_id, old_message->message_id)); if (file_source_id.is_valid()) { auto search_text = get_message_search_text(old_message); for (auto file_id : file_ids) { @@ -36054,7 +34563,7 @@ MessageId MessagesManager::get_message_id_by_random_id(Dialog *d, int64 random_i } auto it = d->random_id_to_message_id.find(random_id); if (it == d->random_id_to_message_id.end()) { - if (G()->use_message_database() && d->dialog_id.get_type() == DialogType::SecretChat) { + if (G()->use_message_database() && d->dialog_id.get_type() == DialogType::SecretChat && random_id != 0) { auto r_value = G()->td_db()->get_message_db_sync()->get_message_by_random_id(d->dialog_id, random_id); if (r_value.is_ok()) { debug_add_message_to_dialog_fail_reason_ = "not called"; @@ -36072,7 +34581,7 @@ MessageId MessagesManager::get_message_id_by_random_id(Dialog *d, int64 random_i << source << " " << random_id << " " << d->random_id_to_message_id[random_id] << " " << m->message_id << " " << m->is_failed_to_send << " " << m->is_outgoing << " " << get_message(d, m->message_id) << " " << m << " " << debug_add_message_to_dialog_fail_reason_; - LOG(INFO) << "Found " << FullMessageId{d->dialog_id, m->message_id} << " by random_id " << random_id + LOG(INFO) << "Found " << MessageFullId{d->dialog_id, m->message_id} << " by random_id " << random_id << " from " << source; return m->message_id; } @@ -36083,7 +34592,7 @@ MessageId MessagesManager::get_message_id_by_random_id(Dialog *d, int64 random_i return MessageId(); } - LOG(INFO) << "Found " << FullMessageId{d->dialog_id, it->second} << " by random_id " << random_id << " from " + LOG(INFO) << "Found " << MessageFullId{d->dialog_id, it->second} << " by random_id " << random_id << " from " << source; return it->second; } @@ -36111,13 +34620,13 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source update_dialog_pos(d, source); if (dialog_id.get_type() == DialogType::SecretChat && !d->notification_settings.is_synchronized && - td_->contacts_manager_->get_secret_chat_state(dialog_id.get_secret_chat_id()) != SecretChatState::Closed) { + td_->user_manager_->get_secret_chat_state(dialog_id.get_secret_chat_id()) != SecretChatState::Closed) { // secret chat is being created // let's copy notification settings from main chat if available VLOG(notifications) << "Create new secret " << dialog_id << " from " << source; auto secret_chat_id = dialog_id.get_secret_chat_id(); { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(secret_chat_id); + auto user_id = td_->user_manager_->get_secret_chat_user_id(secret_chat_id); Dialog *user_d = get_dialog_force(DialogId(user_id), source); if (user_d != nullptr && user_d->notification_settings.is_synchronized) { VLOG(notifications) << "Copy notification settings from " << user_d->dialog_id << " to " << dialog_id; @@ -36125,7 +34634,9 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source auto new_notification_settings = DialogNotificationSettings( user_settings->use_default_mute_until, user_settings->mute_until, dup_notification_sound(user_settings->sound), true /*use_default_show_preview*/, false /*show_preview*/, - user_settings->silent_send_message, true, false, true, false); + user_settings->use_default_mute_stories, user_settings->mute_stories, + dup_notification_sound(user_settings->story_sound), user_settings->use_default_hide_story_sender, + user_settings->hide_story_sender, user_settings->silent_send_message, true, false, true, false); new_notification_settings.is_secret_chat_show_preview_fixed = true; update_dialog_notification_settings(dialog_id, &d->notification_settings, std::move(new_notification_settings)); @@ -36135,7 +34646,7 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source } if (G()->use_message_database() && !td_->auth_manager_->is_bot() && - !td_->contacts_manager_->get_secret_chat_is_outbound(secret_chat_id)) { + !td_->user_manager_->get_secret_chat_is_outbound(secret_chat_id)) { auto notification_info = add_dialog_notification_info(d); auto notification_group_id = get_dialog_notification_group_id(dialog_id, notification_info->message_notification_group_); @@ -36147,11 +34658,10 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source notification_info->new_secret_chat_notification_id_ = get_next_notification_id(notification_info, notification_group_id, MessageId()); if (notification_info->new_secret_chat_notification_id_.is_valid()) { - auto date = td_->contacts_manager_->get_secret_chat_date(secret_chat_id); - bool is_changed = set_dialog_last_notification(dialog_id, notification_info->message_notification_group_, - date, notification_info->new_secret_chat_notification_id_, - "add_new_secret_chat"); - CHECK(is_changed); + auto date = td_->user_manager_->get_secret_chat_date(secret_chat_id); + set_dialog_last_notification_checked(dialog_id, notification_info->message_notification_group_, date, + notification_info->new_secret_chat_notification_id_, + "add_new_secret_chat"); VLOG(notifications) << "Create " << notification_info->new_secret_chat_notification_id_ << " with " << secret_chat_id; auto ringtone_id = get_dialog_notification_ringtone_id(dialog_id, d); @@ -36164,10 +34674,10 @@ void MessagesManager::force_create_dialog(DialogId dialog_id, const char *source } } } - if (!have_input_peer(dialog_id, AccessRights::Read)) { - if (!have_dialog_info(dialog_id)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { + if (!td_->dialog_manager_->have_dialog_info(dialog_id)) { if (expect_no_access && dialog_id.get_type() == DialogType::Channel && - td_->contacts_manager_->have_min_channel(dialog_id.get_channel_id())) { + td_->chat_manager_->have_min_channel(dialog_id.get_channel_id())) { LOG(INFO) << "Created " << dialog_id << " for min-channel from " << source; } else { LOG(ERROR) << "Forced to create unknown " << dialog_id << " from " << source; @@ -36222,26 +34732,33 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di LOG_CHECK(!have_dialog(dialog_id)) << dialog_id << ' ' << is_loaded_from_database << ' ' << source; switch (dialog_id.get_type()) { case DialogType::User: - if (dialog_id == get_my_dialog_id() && d->last_read_inbox_message_id == MessageId::max() && + if (dialog_id == td_->dialog_manager_->get_my_dialog_id() && d->last_read_inbox_message_id == MessageId::max() && d->last_read_outbox_message_id == MessageId::max()) { d->last_read_inbox_message_id = d->last_new_message_id; d->last_read_outbox_message_id = d->last_new_message_id; } - d->has_bots = dialog_id.get_user_id() != ContactsManager::get_replies_bot_user_id() && - td_->contacts_manager_->is_user_bot(dialog_id.get_user_id()); + d->has_bots = !td_->auth_manager_->is_bot() && + dialog_id.get_user_id() != UserManager::get_replies_bot_user_id() && + td_->user_manager_->is_user_bot(dialog_id.get_user_id()); d->is_has_bots_inited = true; d->is_available_reactions_inited = true; + d->is_view_as_messages_inited = true; + if (!d->is_saved_messages_view_as_messages_inited && dialog_id == td_->dialog_manager_->get_my_dialog_id()) { + d->is_saved_messages_view_as_messages_inited = true; + d->view_as_messages = true; + } break; case DialogType::Chat: d->is_is_blocked_inited = true; + d->is_is_blocked_for_stories_inited = true; d->is_background_inited = true; + d->is_view_as_messages_inited = true; break; case DialogType::Channel: { - if (td_->contacts_manager_->is_broadcast_channel(dialog_id.get_channel_id())) { + if (td_->chat_manager_->is_broadcast_channel(dialog_id.get_channel_id())) { d->last_read_outbox_message_id = MessageId::max(); d->is_last_read_outbox_message_id_inited = true; } - d->is_background_inited = true; auto pts = load_channel_pts(dialog_id); if (pts > 0) { @@ -36271,14 +34788,16 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di d->is_background_inited = true; d->is_theme_name_inited = true; d->is_is_blocked_inited = true; + d->is_is_blocked_for_stories_inited = true; + d->is_view_as_messages_inited = true; if (!d->is_folder_id_inited && !td_->auth_manager_->is_bot()) { - do_set_dialog_folder_id( - d, td_->contacts_manager_->get_secret_chat_initial_folder_id(dialog_id.get_secret_chat_id())); + do_set_dialog_folder_id(d, + td_->user_manager_->get_secret_chat_initial_folder_id(dialog_id.get_secret_chat_id())); } - d->message_ttl = MessageTtl(td_->contacts_manager_->get_secret_chat_ttl(dialog_id.get_secret_chat_id())); + d->message_ttl = MessageTtl(td_->user_manager_->get_secret_chat_ttl(dialog_id.get_secret_chat_id())); d->is_message_ttl_inited = true; - d->has_bots = td_->contacts_manager_->is_user_bot( - td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id())); + d->has_bots = + td_->user_manager_->is_user_bot(td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id())); d->is_has_bots_inited = true; d->is_available_reactions_inited = true; d->has_loaded_scheduled_messages_from_database = true; @@ -36298,6 +34817,8 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di d->is_channel_difference_finished = true; } + auto draft_message = std::move(d->draft_message); + d->draft_message = nullptr; unique_ptr last_database_message; if (!d->messages.empty()) { d->messages.foreach([&](const MessageId &message_id, unique_ptr &message) { @@ -36306,9 +34827,10 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di }); d->messages = {}; } - MessageId last_database_message_id = d->last_database_message_id; + auto last_database_message_id = d->last_database_message_id; d->last_database_message_id = MessageId(); if (td_->auth_manager_->is_bot()) { + draft_message = nullptr; last_database_message = nullptr; d->first_database_message_id = MessageId(); last_database_message_id = MessageId(); @@ -36342,12 +34864,12 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di } if (d->notification_info != nullptr) { - if (d->notification_info->message_notification_group_.group_id.is_valid()) { - notification_group_id_to_dialog_id_.emplace(d->notification_info->message_notification_group_.group_id, + if (d->notification_info->message_notification_group_.is_valid()) { + notification_group_id_to_dialog_id_.emplace(d->notification_info->message_notification_group_.get_group_id(), dialog_id); } - if (d->notification_info->mention_notification_group_.group_id.is_valid()) { - notification_group_id_to_dialog_id_.emplace(d->notification_info->mention_notification_group_.group_id, + if (d->notification_info->mention_notification_group_.is_valid()) { + notification_group_id_to_dialog_id_.emplace(d->notification_info->mention_notification_group_.get_group_id(), dialog_id); } } @@ -36369,6 +34891,7 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di if (!is_loaded_from_database) { CHECK(order == DEFAULT_ORDER); + CHECK(draft_message == nullptr); CHECK(last_database_message == nullptr); } @@ -36382,22 +34905,25 @@ MessagesManager::Dialog *MessagesManager::add_new_dialog(unique_ptr &&di failed_to_load_dialogs_.erase(dialog_id); fix_dialog_action_bar(d, d->action_bar.get()); + fix_dialog_business_bot_manage_bar(dialog_id, d->business_bot_manage_bar.get()); - send_update_new_chat(d); + send_update_new_chat(d, source); being_added_new_dialog_id_ = DialogId(); CHECK(d->messages.empty()); - fix_new_dialog(d, std::move(last_database_message), last_database_message_id, order, last_clear_history_date, - last_clear_history_message_id, default_join_group_call_as_dialog_id, default_send_message_as_dialog_id, - need_drop_default_send_message_as_dialog_id, is_loaded_from_database, source); + fix_new_dialog(d, std::move(draft_message), std::move(last_database_message), last_database_message_id, order, + last_clear_history_date, last_clear_history_message_id, default_join_group_call_as_dialog_id, + default_send_message_as_dialog_id, need_drop_default_send_message_as_dialog_id, + is_loaded_from_database, source); return d; } -void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_database_message, - MessageId last_database_message_id, int64 order, int32 last_clear_history_date, +void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&draft_message, + unique_ptr &&last_database_message, MessageId last_database_message_id, + int64 order, int32 last_clear_history_date, MessageId last_clear_history_message_id, DialogId default_join_group_call_as_dialog_id, DialogId default_send_message_as_dialog_id, @@ -36408,13 +34934,14 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab auto dialog_type = dialog_id.get_type(); if (!td_->auth_manager_->is_bot() && dialog_type == DialogType::SecretChat) { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); if (user_id.is_valid()) { force_create_dialog(DialogId(user_id), "add chat with user to load/store action_bar and is_blocked"); Dialog *user_d = get_dialog_force(DialogId(user_id), "fix_new_dialog"); - if (user_d != nullptr && d->is_blocked != user_d->is_blocked) { - set_dialog_is_blocked(d, user_d->is_blocked); + if (user_d != nullptr && + (d->is_blocked != user_d->is_blocked || d->is_blocked_for_stories != user_d->is_blocked_for_stories)) { + set_dialog_is_blocked(d, user_d->is_blocked, user_d->is_blocked_for_stories); } } } @@ -36425,52 +34952,51 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab } if (being_added_dialog_id_ != dialog_id && !td_->auth_manager_->is_bot() && !is_dialog_inited(d) && - dialog_type != DialogType::SecretChat && have_input_peer(dialog_id, AccessRights::Read)) { + td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { // asynchronously get dialog from the server send_get_dialog_query(dialog_id, Auto(), 0, "fix_new_dialog 20"); } - if (being_added_dialog_id_ != dialog_id && !d->is_is_blocked_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get is_blocked from the server - reload_dialog_info_full(dialog_id, "fix_new_dialog init is_blocked"); - } else if (being_added_dialog_id_ != dialog_id && !d->is_has_bots_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get has_bots from the server - reload_dialog_info_full(dialog_id, "fix_new_dialog init has_bots"); - } else if (being_added_dialog_id_ != dialog_id && !d->is_background_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get dialog background from the server - reload_dialog_info_full(dialog_id, "fix_new_dialog init background"); - } else if (being_added_dialog_id_ != dialog_id && !d->is_theme_name_inited && !td_->auth_manager_->is_bot()) { - // asynchronously get dialog theme identifier from the server - reload_dialog_info_full(dialog_id, "fix_new_dialog init theme_name"); - } else if (being_added_dialog_id_ != dialog_id && !d->is_last_pinned_message_id_inited && - !td_->auth_manager_->is_bot()) { - // asynchronously get dialog pinned message from the server - get_dialog_pinned_message(dialog_id, Auto()); - } else if (being_added_dialog_id_ != dialog_id && !d->is_folder_id_inited && !td_->auth_manager_->is_bot() && - order != DEFAULT_ORDER) { - // asynchronously get dialog folder identifier from the server - reload_dialog_info_full(dialog_id, "fix_new_dialog init folder_id"); - } else if (!d->is_message_ttl_inited && !td_->auth_manager_->is_bot() && - have_input_peer(dialog_id, AccessRights::Write)) { - // asynchronously get dialog message auto-delete timer from the server - reload_dialog_info_full(dialog_id, "fix_new_dialog init message_auto_delete_time"); - } else if (being_added_dialog_id_ != dialog_id && !d->is_available_reactions_inited && - !td_->auth_manager_->is_bot()) { - // asynchronously get dialog available reactions from the server - reload_dialog_info_full(dialog_id, "fix_new_dialog init available_reactions"); + if (being_added_dialog_id_ != dialog_id && !td_->auth_manager_->is_bot()) { + const char *reload_source = nullptr; + if (!d->is_is_blocked_for_stories_inited) { + reload_source = "fix_new_dialog init is_blocked_for_stories"; + } else if (!d->is_has_bots_inited) { + reload_source = "fix_new_dialog init has_bots"; + } else if (!d->is_background_inited) { + reload_source = "fix_new_dialog init background"; + } else if (!d->is_theme_name_inited) { + reload_source = "fix_new_dialog init theme_name"; + } else if (!d->is_available_reactions_inited) { + reload_source = "fix_new_dialog init available_reactions"; + } else if (!d->is_folder_id_inited && order != DEFAULT_ORDER) { + reload_source = "fix_new_dialog init folder_id"; + } else if (!d->is_message_ttl_inited && + td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Write)) { + reload_source = "fix_new_dialog init message_auto_delete_time"; + } else if (!d->is_view_as_messages_inited && td_->dialog_manager_->is_forum_channel(dialog_id)) { + reload_source = "fix_new_dialog init view_as_messages"; + } else if (!d->is_last_pinned_message_id_inited) { + get_dialog_pinned_message(dialog_id, Auto()); + } + if (reload_source != nullptr) { + // asynchronously get dialog info from the server + td_->dialog_manager_->reload_dialog_info_full(dialog_id, reload_source); + } } if ((!d->know_action_bar || d->need_repair_action_bar) && !td_->auth_manager_->is_bot() && - dialog_type != DialogType::SecretChat && dialog_id != get_my_dialog_id() && - have_input_peer(dialog_id, AccessRights::Read)) { + dialog_id != td_->dialog_manager_->get_my_dialog_id() && + td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { // asynchronously get action bar from the server reget_dialog_action_bar(dialog_id, "fix_new_dialog", false); } if (d->has_active_group_call && !d->active_group_call_id.is_valid() && !td_->auth_manager_->is_bot()) { repair_dialog_active_group_call_id(dialog_id); } + set_dialog_is_forum(d, td_->dialog_manager_->is_forum_channel(dialog_id)); if (d->notification_settings.is_synchronized && !d->notification_settings.is_use_default_fixed && - have_input_peer(dialog_id, AccessRights::Read) && !td_->auth_manager_->is_bot()) { + td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read) && !td_->auth_manager_->is_bot()) { LOG(INFO) << "Reget notification settings of " << dialog_id; if (dialog_type == DialogType::SecretChat) { d->notification_settings.is_use_default_fixed = true; @@ -36484,52 +35010,43 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab d->notification_settings.mute_until <= G()->unix_time()) { d->notification_settings.mute_until = 0; } else { - schedule_dialog_unmute(dialog_id, false, d->notification_settings.mute_until); + schedule_dialog_unmute(dialog_id, false, d->notification_settings.mute_until, G()->unix_time()); } if (d->notification_info != nullptr && d->notification_info->pinned_message_notification_message_id_.is_valid()) { auto pinned_message_id = d->notification_info->pinned_message_notification_message_id_; - if (!d->notification_info->mention_notification_group_.group_id.is_valid()) { + if (!d->notification_info->mention_notification_group_.is_valid()) { LOG(ERROR) << "Have pinned message notification in " << pinned_message_id << " in " << dialog_id << ", but there is no mention notification group"; d->notification_info->pinned_message_notification_message_id_ = MessageId(); on_dialog_updated(dialog_id, "fix pinned message notification"); } else if (is_dialog_pinned_message_notifications_disabled(d) || pinned_message_id <= d->last_read_inbox_message_id || - pinned_message_id <= d->notification_info->mention_notification_group_.max_removed_message_id) { + d->notification_info->mention_notification_group_.is_removed_object_id(pinned_message_id)) { VLOG(notifications) << "Remove disabled pinned message notification in " << pinned_message_id << " in " << dialog_id; - send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_message_id, - d->notification_info->mention_notification_group_.group_id, pinned_message_id, true, + send_closure_later(G()->notification_manager(), &NotificationManager::remove_temporary_notification_by_object_id, + d->notification_info->mention_notification_group_.get_group_id(), pinned_message_id, true, "fix pinned message notification"); d->notification_info->pinned_message_notification_message_id_ = MessageId(); on_dialog_updated(dialog_id, "fix pinned message notification 2"); } } - if (d->notification_info != nullptr && d->notification_info->new_secret_chat_notification_id_.is_valid()) { - auto &group_info = d->notification_info->message_notification_group_; - if (d->notification_info->new_secret_chat_notification_id_.get() <= group_info.max_removed_notification_id.get() || - (group_info.last_notification_date == 0 && group_info.max_removed_notification_id.get() == 0)) { - VLOG(notifications) << "Fix removing new secret chat " << d->notification_info->new_secret_chat_notification_id_ - << " in " << dialog_id; - d->notification_info->new_secret_chat_notification_id_ = NotificationId(); - on_dialog_updated(dialog_id, "fix new secret chat notification identifier"); - } - } { - auto it = pending_add_dialog_last_database_message_dependent_dialogs_.find(dialog_id); - if (it != pending_add_dialog_last_database_message_dependent_dialogs_.end()) { + auto it = pending_add_dialog_dependent_dialogs_.find(dialog_id); + if (it != pending_add_dialog_dependent_dialogs_.end()) { auto pending_dialog_ids = std::move(it->second); - pending_add_dialog_last_database_message_dependent_dialogs_.erase(it); + pending_add_dialog_dependent_dialogs_.erase(it); for (auto &pending_dialog_id : pending_dialog_ids) { - auto &counter_message = pending_add_dialog_last_database_message_[pending_dialog_id]; - CHECK(counter_message.first > 0); - counter_message.first--; - if (counter_message.first == 0) { + auto &add_dialog_data = pending_add_dialog_data_[pending_dialog_id]; + CHECK(add_dialog_data.dependent_dialog_count_ > 0); + add_dialog_data.dependent_dialog_count_--; + if (add_dialog_data.dependent_dialog_count_ == 0) { LOG(INFO) << "Add postponed last database message in " << pending_dialog_id; - add_dialog_last_database_message(get_dialog(pending_dialog_id), std::move(counter_message.second)); - pending_add_dialog_last_database_message_.erase(pending_dialog_id); + add_pending_dialog_data(get_dialog(pending_dialog_id), std::move(add_dialog_data.last_message_), + std::move(add_dialog_data.draft_message_)); + pending_add_dialog_data_.erase(pending_dialog_id); } } } @@ -36570,6 +35087,9 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab set_dialog_last_clear_history_date(d, last_clear_history_date, last_clear_history_message_id, "fix_new_dialog 8", is_loaded_from_database); + if (td_->dialog_manager_->is_dialog_removed_from_dialog_list(dialog_id)) { + order = DEFAULT_ORDER; + } set_dialog_order(d, order, false, is_loaded_from_database, "fix_new_dialog 9"); } @@ -36621,38 +35141,53 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab d->debug_last_database_message_id = d->last_database_message_id; d->debug_last_new_message_id = d->last_new_message_id; - if (last_database_message != nullptr) { + if (last_database_message != nullptr || draft_message != nullptr) { Dependencies dependencies; - add_message_dependencies(dependencies, last_database_message.get()); + if (last_database_message != nullptr) { + add_message_dependencies(dependencies, last_database_message.get()); + } + if (draft_message != nullptr) { + draft_message->add_dependencies(dependencies); + } int32 dependent_dialog_count = 0; for (const auto &other_dialog_id : dependencies.get_dialog_ids()) { if (other_dialog_id.is_valid() && !have_dialog(other_dialog_id)) { - LOG(INFO) << "Postpone adding of last message in " << dialog_id << " because of cyclic dependency with " + LOG(INFO) << "Postpone adding of data in " << dialog_id << " because of cyclic dependency with " << other_dialog_id; - pending_add_dialog_last_database_message_dependent_dialogs_[other_dialog_id].push_back(dialog_id); + pending_add_dialog_dependent_dialogs_[other_dialog_id].push_back(dialog_id); dependent_dialog_count++; } }; - auto last_message_date = last_database_message->date; + auto pending_order = DEFAULT_ORDER; + if (last_database_message != nullptr) { + auto last_message_order = get_dialog_order(last_message_id, last_database_message->date); + if (last_message_order > pending_order) { + pending_order = last_message_order; + } + } + if (draft_message != nullptr && !need_hide_dialog_draft_message(d)) { + int64 draft_order = get_dialog_order(MessageId(), draft_message->get_date()); + if (draft_order > pending_order) { + pending_order = draft_order; + } + } if (dependent_dialog_count == 0) { - if (!add_dialog_last_database_message(d, std::move(last_database_message))) { + if (!add_pending_dialog_data(d, std::move(last_database_message), std::move(draft_message))) { // failed to add last message; keep the current position and get history from the database - d->pending_last_message_date = last_message_date; - d->pending_last_message_id = last_message_id; + d->pending_order = pending_order; } } else { - // can't add message immediately, because need to notify first about adding of dependent dialogs - d->pending_last_message_date = last_message_date; - d->pending_last_message_id = last_message_id; - pending_add_dialog_last_database_message_[dialog_id] = {dependent_dialog_count, std::move(last_database_message)}; + // can't add data immediately, because need to notify first about adding of dependent dialogs + d->pending_order = pending_order; + pending_add_dialog_data_[dialog_id] = {dependent_dialog_count, std::move(last_database_message), + std::move(draft_message)}; } } else if (last_database_message_id.is_valid()) { auto date = DialogDate(order, dialog_id).get_date(); if (date < MIN_PINNED_DIALOG_DATE) { - d->pending_last_message_date = date; - d->pending_last_message_id = last_message_id; + d->pending_order = get_dialog_order(last_message_id, date); } } @@ -36728,7 +35263,7 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab update_dialog_pos(d, "fix_new_dialog 7", true, is_loaded_from_database); } if (is_loaded_from_database && d->order != order && order < MAX_ORDINARY_DIALOG_ORDER && - !td_->contacts_manager_->is_dialog_info_received_from_server(dialog_id) && !d->had_last_yet_unsent_message && + !td_->dialog_manager_->is_dialog_info_received_from_server(dialog_id) && !d->had_last_yet_unsent_message && !td_->auth_manager_->is_bot()) { LOG(ERROR) << dialog_id << " has order " << d->order << " instead of saved to database order " << order; } @@ -36737,23 +35272,14 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab << d->first_database_message_id << ", last database " << d->last_database_message_id << ", last " << d->last_message_id << " with order " << d->order; if (d->notification_info != nullptr) { - VLOG(notifications) << "Have " << dialog_id << " with message " - << d->notification_info->message_notification_group_.group_id << " with last " - << d->notification_info->message_notification_group_.last_notification_id << " sent at " - << d->notification_info->message_notification_group_.last_notification_date << ", max removed " - << d->notification_info->message_notification_group_.max_removed_notification_id << "/" - << d->notification_info->message_notification_group_.max_removed_message_id + VLOG(notifications) << "Have " << dialog_id << " with message " << d->notification_info->message_notification_group_ << " and new secret chat " << d->notification_info->new_secret_chat_notification_id_; - VLOG(notifications) << "Have " << dialog_id << " with mention " - << d->notification_info->mention_notification_group_.group_id << " with last " - << d->notification_info->mention_notification_group_.last_notification_id << " sent at " - << d->notification_info->mention_notification_group_.last_notification_date << ", max removed " - << d->notification_info->mention_notification_group_.max_removed_notification_id << "/" - << d->notification_info->mention_notification_group_.max_removed_message_id << " and pinned " - << d->notification_info->pinned_message_notification_message_id_; + VLOG(notifications) << "Have " << dialog_id << " with mention " << d->notification_info->mention_notification_group_ + << " and pinned " << d->notification_info->pinned_message_notification_message_id_; VLOG(notifications) << "In " << dialog_id << " have last_read_inbox_message_id = " << d->last_read_inbox_message_id << ", last_new_message_id = " << d->last_new_message_id - << ", max_notification_message_id = " << d->notification_info->max_notification_message_id_; + << ", max_push_notification_message_id = " + << d->notification_info->max_push_notification_message_id_; } LOG_CHECK(d->messages.calc_size() <= 1) @@ -36768,7 +35294,7 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab // must be after checks that dialog has at most one message, because read_history_inbox can load // pinned message to remove notification about it if (d->pending_read_channel_inbox_pts != 0 && !td_->auth_manager_->is_bot() && - have_input_peer(dialog_id, AccessRights::Read) && need_unread_counter(d->order)) { + td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read) && need_unread_counter(d->order)) { if (d->pts == d->pending_read_channel_inbox_pts) { d->pending_read_channel_inbox_pts = 0; read_history_inbox(d, d->pending_read_channel_inbox_max_message_id, @@ -36779,19 +35305,23 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab d->pending_read_channel_inbox_pts = 0; on_dialog_updated(dialog_id, "fix_new_dialog 14"); } else { - schedule_get_channel_difference(dialog_id, d->pending_read_channel_inbox_pts, MessageId(), 0.001); + schedule_get_channel_difference(dialog_id, d->pending_read_channel_inbox_pts, MessageId(), 0.001, source); } } else { d->pending_read_channel_inbox_pts = 0; } if (need_get_history && !td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ && dialog_id != being_added_by_new_message_dialog_id_ && (d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) { - get_history_from_the_end_impl(d, true, false, Auto(), "fix_new_dialog"); + load_last_dialog_message(d, "fix_new_dialog"); } if (d->need_repair_server_unread_count && need_unread_counter(d->order)) { CHECK(dialog_type != DialogType::SecretChat); repair_server_unread_count(dialog_id, d->server_unread_count, "fix_new_dialog"); } + if (dialog_type == DialogType::Channel && need_unread_counter(d->order) && d->server_unread_count > 0 && + !td_->auth_manager_->is_bot() && td_->option_manager_->get_option_integer("since_last_open") >= 2 * 86400) { + d->need_repair_channel_server_unread_count = true; + } if (d->need_repair_channel_server_unread_count) { repair_channel_server_unread_count(d); } @@ -36803,53 +35333,62 @@ void MessagesManager::fix_new_dialog(Dialog *d, unique_ptr &&last_datab } } -bool MessagesManager::add_dialog_last_database_message(Dialog *d, unique_ptr &&last_database_message) { +bool MessagesManager::add_pending_dialog_data(Dialog *d, unique_ptr &&last_database_message, + unique_ptr &&draft_message) { CHECK(d != nullptr); - CHECK(last_database_message != nullptr); + CHECK(last_database_message != nullptr || draft_message != nullptr); CHECK(!td_->auth_manager_->is_bot()); - auto dialog_id = d->dialog_id; - auto message_id = last_database_message->message_id; - CHECK(message_id.is_valid()); - LOG_CHECK(d->last_database_message_id == message_id) - << message_id << " " << d->last_database_message_id << " " << d->debug_set_dialog_last_database_message_id; - bool need_update_dialog_pos = false; - const Message *m = nullptr; - if (have_input_peer(dialog_id, AccessRights::Read)) { - bool need_update = false; - m = add_message_to_dialog(d, std::move(last_database_message), true, false, &need_update, &need_update_dialog_pos, - "add_dialog_last_database_message 1"); - if (need_update_dialog_pos) { - LOG(ERROR) << "Need to update pos in " << dialog_id; - } - } - if (m != nullptr) { - set_dialog_last_message_id(d, m->message_id, "add_dialog_last_database_message 2", m); - send_update_chat_last_message(d, "add_dialog_last_database_message 3"); - } else { - if (d->pending_last_message_date != 0) { - d->pending_last_message_date = 0; - d->pending_last_message_id = MessageId(); - need_update_dialog_pos = true; + bool was_added_last_message = false; + if (last_database_message != nullptr) { + auto dialog_id = d->dialog_id; + auto message_id = last_database_message->message_id; + CHECK(message_id.is_valid()); + LOG_CHECK(d->last_database_message_id == message_id) + << message_id << " " << d->last_database_message_id << " " << d->debug_set_dialog_last_database_message_id; + + const Message *m = nullptr; + if (td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { + bool need_update = false; + m = add_message_to_dialog(d, std::move(last_database_message), true, false, &need_update, &need_update_dialog_pos, + "add_pending_dialog_data 1"); + if (need_update_dialog_pos) { + LOG(ERROR) << "Need to update pos in " << dialog_id; + } } - on_dialog_updated(dialog_id, "add_dialog_last_database_message 4"); // resave without last database message + if (m != nullptr) { + set_dialog_last_message_id(d, m->message_id, "add_pending_dialog_data 2", m); + send_update_chat_last_message(d, "add_pending_dialog_data 3"); + was_added_last_message = true; + } else { + on_dialog_updated(dialog_id, "add_pending_dialog_data 4"); // resave without last database message - if (!td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ && - dialog_id != being_added_by_new_message_dialog_id_ && (d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) { - get_history_from_the_end_impl(d, true, false, Auto(), "add_dialog_last_database_message 5"); + if (!td_->auth_manager_->is_bot() && dialog_id != being_added_dialog_id_ && + dialog_id != being_added_by_new_message_dialog_id_ && (d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) { + load_last_dialog_message(d, "add_pending_dialog_data 5"); + } } } + if (draft_message != nullptr) { + d->draft_message = std::move(draft_message); + need_update_dialog_pos = true; + send_update_chat_draft_message(d); + } + if (d->pending_order != DEFAULT_ORDER) { + d->pending_order = DEFAULT_ORDER; + need_update_dialog_pos = true; + } if (need_update_dialog_pos) { - update_dialog_pos(d, "add_dialog_last_database_message 6"); + update_dialog_pos(d, "add_pending_dialog_data 6"); } - return m != nullptr; + return was_added_last_message; } void MessagesManager::update_dialogs_hints(const Dialog *d) { if (!td_->auth_manager_->is_bot() && d->order != DEFAULT_ORDER) { - dialogs_hints_.add(-d->dialog_id.get(), td_->contacts_manager_->get_dialog_search_text(d->dialog_id)); + dialogs_hints_.add(-d->dialog_id.get(), td_->dialog_manager_->get_dialog_search_text(d->dialog_id)); } } @@ -36955,24 +35494,6 @@ int64 MessagesManager::get_next_pinned_dialog_order() { return current_pinned_dialog_order_; } -bool MessagesManager::is_removed_from_dialog_list(const Dialog *d) const { - switch (d->dialog_id.get_type()) { - case DialogType::User: - break; - case DialogType::Chat: - return !td_->contacts_manager_->get_chat_is_active(d->dialog_id.get_chat_id()); - case DialogType::Channel: - return !td_->contacts_manager_->get_channel_status(d->dialog_id.get_channel_id()).is_member(); - case DialogType::SecretChat: - break; - case DialogType::None: - default: - UNREACHABLE(); - break; - } - return false; -} - void MessagesManager::update_dialog_pos(Dialog *d, const char *source, bool need_send_update, bool is_loaded_from_database) { if (td_->auth_manager_->is_bot()) { @@ -36983,7 +35504,7 @@ void MessagesManager::update_dialog_pos(Dialog *d, const char *source, bool need LOG(INFO) << "Trying to update " << d->dialog_id << " order from " << source; int64 new_order = DEFAULT_ORDER; - if (!is_removed_from_dialog_list(d)) { + if (!td_->dialog_manager_->is_dialog_removed_from_dialog_list(d->dialog_id)) { if (d->last_message_id != MessageId()) { auto m = get_message(d, d->last_message_id); CHECK(m != nullptr); @@ -37005,14 +35526,13 @@ void MessagesManager::update_dialog_pos(Dialog *d, const char *source, bool need new_order = clear_order; } } - if (d->pending_last_message_date > 0) { - LOG(INFO) << "Pending last " << d->pending_last_message_id << " at " << d->pending_last_message_date << " found"; - int64 pending_order = get_dialog_order(d->pending_last_message_id, d->pending_last_message_date); - if (pending_order > new_order) { - new_order = pending_order; + if (d->pending_order != DEFAULT_ORDER) { + LOG(INFO) << "Pending order " << d->pending_order << " found"; + if (d->pending_order > new_order) { + new_order = d->pending_order; } } - if (d->draft_message != nullptr && !need_hide_dialog_draft_message(d->dialog_id)) { + if (d->draft_message != nullptr && !need_hide_dialog_draft_message(d)) { auto draft_message_date = d->draft_message->get_date(); LOG(INFO) << "Draft message at " << draft_message_date << " found"; int64 draft_order = get_dialog_order(MessageId(), draft_message_date); @@ -37023,16 +35543,16 @@ void MessagesManager::update_dialog_pos(Dialog *d, const char *source, bool need switch (d->dialog_id.get_type()) { case DialogType::Chat: { auto chat_id = d->dialog_id.get_chat_id(); - auto date = td_->contacts_manager_->get_chat_date(chat_id); + auto date = td_->chat_manager_->get_chat_date(chat_id); LOG(INFO) << "Creation at " << date << " found"; int64 join_order = get_dialog_order(MessageId(), date); - if (join_order > new_order && td_->contacts_manager_->get_chat_status(chat_id).is_member()) { + if (join_order > new_order && td_->chat_manager_->get_chat_status(chat_id).is_member()) { new_order = join_order; } break; } case DialogType::Channel: { - auto date = td_->contacts_manager_->get_channel_date(d->dialog_id.get_channel_id()); + auto date = td_->chat_manager_->get_channel_date(d->dialog_id.get_channel_id()); LOG(INFO) << "Join at " << date << " found"; int64 join_order = get_dialog_order(MessageId(), date); if (join_order > new_order) { @@ -37041,7 +35561,7 @@ void MessagesManager::update_dialog_pos(Dialog *d, const char *source, bool need break; } case DialogType::SecretChat: { - auto date = td_->contacts_manager_->get_secret_chat_date(d->dialog_id.get_secret_chat_id()); + auto date = td_->user_manager_->get_secret_chat_date(d->dialog_id.get_secret_chat_id()); if (date != 0 && !is_deleted_secret_chat(d)) { LOG(INFO) << "Creation at " << date << " found"; int64 creation_order = get_dialog_order(MessageId(), date); @@ -37057,6 +35577,7 @@ void MessagesManager::update_dialog_pos(Dialog *d, const char *source, bool need if (new_order == DEFAULT_ORDER && !d->is_empty) { LOG(INFO) << "There are no known messages in the chat, just leave it where it is"; new_order = d->order; + load_last_dialog_message(d, source); } } @@ -37085,9 +35606,10 @@ bool MessagesManager::set_dialog_order(Dialog *d, int64 new_order, bool need_sen } auto folder_ptr = get_dialog_folder(d->folder_id); - LOG_CHECK(folder_ptr != nullptr) << is_inited_ << ' ' << G()->close_flag() << ' ' << dialog_id << ' ' << d->folder_id - << ' ' << is_loaded_from_database << ' ' << td_->auth_manager_->is_authorized() - << ' ' << td_->auth_manager_->was_authorized() << ' ' << source; + LOG_CHECK(folder_ptr != nullptr) << is_inited_ << ' ' << create_folders_source_ << ' ' << G()->close_flag() << ' ' + << dialog_id << ' ' << d->folder_id << ' ' << is_loaded_from_database << ' ' + << td_->auth_manager_->is_authorized() << ' ' << td_->auth_manager_->was_authorized() + << ' ' << source; auto &folder = *folder_ptr; if (old_date == new_date) { if (new_order == DEFAULT_ORDER) { @@ -37128,12 +35650,12 @@ bool MessagesManager::set_dialog_order(Dialog *d, int64 new_order, bool need_sen auto dialog_type = dialog_id.get_type(); if (dialog_type == DialogType::Channel && is_added && being_added_dialog_id_ != dialog_id) { repair_channel_server_unread_count(d); - schedule_get_channel_difference(dialog_id, 0, MessageId(), 0.001); + schedule_get_channel_difference(dialog_id, 0, MessageId(), 0.001, source); } if (dialog_type == DialogType::Channel && is_removed) { remove_all_dialog_notifications(d, false, source); remove_all_dialog_notifications(d, true, source); - clear_active_dialog_actions(dialog_id); + td_->dialog_action_manager_->clear_active_dialog_actions(dialog_id); } } @@ -37467,8 +35989,8 @@ unique_ptr MessagesManager::parse_dialog(DialogId dialo invalidate_message_indexes(d); // and try to reget it from the server if possible - have_dialog_info_force(dialog_id); - if (have_input_peer(dialog_id, AccessRights::Read)) { + td_->dialog_manager_->have_dialog_info_force(dialog_id, "parse_dialog"); + if (td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { if (dialog_id.get_type() != DialogType::SecretChat) { send_get_dialog_query(dialog_id, Auto(), 0, source); } @@ -37490,6 +36012,9 @@ unique_ptr MessagesManager::parse_dialog(DialogId dialo add_message_dependencies(dependencies, message.get()); }); add_draft_message_dependencies(dependencies, d->draft_message); + if (d->business_bot_manage_bar != nullptr) { + d->business_bot_manage_bar->add_dependencies(dependencies); + } for (auto user_id : d->pending_join_request_user_ids) { dependencies.add(user_id); } @@ -37513,6 +36038,9 @@ unique_ptr MessagesManager::parse_dialog(DialogId dialo if (get_active_reactions(d->available_reactions).empty() != ((d->available_reactions_generation & 1) == 1)) { set_dialog_next_available_reactions_generation(d, d->available_reactions_generation); } + if (td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + d->available_reactions.fix_broadcast_reactions(active_reaction_types_); + } break; case DialogType::User: case DialogType::SecretChat: @@ -37520,8 +36048,9 @@ unique_ptr MessagesManager::parse_dialog(DialogId dialo break; } if (!d->need_drop_default_send_message_as_dialog_id && d->default_send_message_as_dialog_id.is_valid() && - dialog_type == DialogType::Channel && !td_->contacts_manager_->is_channel_public(dialog_id.get_channel_id()) && - !td_->contacts_manager_->get_channel_has_linked_channel(dialog_id.get_channel_id())) { + dialog_type == DialogType::Channel && !td_->dialog_manager_->is_broadcast_channel(d->dialog_id) && + !td_->chat_manager_->is_channel_public(dialog_id.get_channel_id()) && + !td_->chat_manager_->get_channel_has_linked_channel(dialog_id.get_channel_id())) { LOG(INFO) << "Drop message sender in " << dialog_id; d->need_drop_default_send_message_as_dialog_id = true; } @@ -37555,6 +36084,19 @@ MessagesManager::Dialog *MessagesManager::on_load_dialog_from_database(DialogId return add_new_dialog(parse_dialog(dialog_id, value, source), true, source); } +Result MessagesManager::check_dialog_access(DialogId dialog_id, bool allow_secret_chats, + AccessRights access_rights, const char *source) { + auto *d = get_dialog_force(dialog_id, source); + if (d == nullptr) { + if (!dialog_id.is_valid()) { + return Status::Error(400, "Invalid chat identifier specified"); + } + return Status::Error(400, "Chat not found"); + } + TRY_STATUS(td_->dialog_manager_->check_dialog_access_in_memory(d->dialog_id, allow_secret_chats, access_rights)); + return d; +} + vector MessagesManager::get_dialog_list_folder_ids(const DialogList &list) const { CHECK(!td_->auth_manager_->is_bot()); if (list.dialog_list_id.is_folder()) { @@ -37588,12 +36130,20 @@ void MessagesManager::add_dialog_to_list(Dialog *d, DialogListId dialog_list_id) LOG(INFO) << "Add " << d->dialog_id << " to " << dialog_list_id; CHECK(!is_dialog_in_list(d, dialog_list_id)); d->dialog_list_ids.push_back(dialog_list_id); + CHECK(d->is_update_new_chat_sent); + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + get_chat_id_object(d->dialog_id, "add_dialog_to_list"), dialog_list_id.get_chat_list_object())); } void MessagesManager::remove_dialog_from_list(Dialog *d, DialogListId dialog_list_id) { LOG(INFO) << "Remove " << d->dialog_id << " from " << dialog_list_id; bool is_removed = td::remove(d->dialog_list_ids, dialog_list_id); CHECK(is_removed); + CHECK(d->is_update_new_chat_sent); + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + get_chat_id_object(d->dialog_id, "remove_dialog_from_list"), dialog_list_id.get_chat_list_object())); } DialogFilterDialogInfo MessagesManager::get_dialog_info_for_dialog_filter(const Dialog *d) const { @@ -37684,22 +36234,18 @@ MessagesManager::DialogListView MessagesManager::get_dialog_lists(const Dialog * MessagesManager::DialogList &MessagesManager::add_dialog_list(DialogListId dialog_list_id) { CHECK(!td_->auth_manager_->is_bot()); - if (dialog_list_id.is_folder() && dialog_list_id.get_folder_id() != FolderId::archive()) { - dialog_list_id = DialogListId(FolderId::main()); - } - if (dialog_lists_.count(dialog_list_id) == 0) { - LOG(INFO) << "Create " << dialog_list_id; - } + bool is_new = dialog_lists_.count(dialog_list_id) == 0; auto &list = dialog_lists_[dialog_list_id]; list.dialog_list_id = dialog_list_id; + if (is_new) { + LOG(INFO) << "Create " << dialog_list_id; + list.unique_id_ = ++current_dialog_list_unique_id_; + } return list; } MessagesManager::DialogList *MessagesManager::get_dialog_list(DialogListId dialog_list_id) { CHECK(!td_->auth_manager_->is_bot()); - if (dialog_list_id.is_folder() && dialog_list_id.get_folder_id() != FolderId::archive()) { - dialog_list_id = DialogListId(FolderId::main()); - } auto it = dialog_lists_.find(dialog_list_id); if (it == dialog_lists_.end()) { return nullptr; @@ -37709,9 +36255,6 @@ MessagesManager::DialogList *MessagesManager::get_dialog_list(DialogListId dialo const MessagesManager::DialogList *MessagesManager::get_dialog_list(DialogListId dialog_list_id) const { CHECK(!td_->auth_manager_->is_bot()); - if (dialog_list_id.is_folder() && dialog_list_id.get_folder_id() != FolderId::archive()) { - dialog_list_id = DialogListId(FolderId::main()); - } auto it = dialog_lists_.find(dialog_list_id); if (it == dialog_lists_.end()) { return nullptr; @@ -37721,9 +36264,6 @@ const MessagesManager::DialogList *MessagesManager::get_dialog_list(DialogListId MessagesManager::DialogFolder *MessagesManager::get_dialog_folder(FolderId folder_id) { CHECK(!td_->auth_manager_->is_bot()); - if (folder_id != FolderId::archive()) { - folder_id = FolderId::main(); - } auto it = dialog_folders_.find(folder_id); if (it == dialog_folders_.end()) { return nullptr; @@ -37733,9 +36273,6 @@ MessagesManager::DialogFolder *MessagesManager::get_dialog_folder(FolderId folde const MessagesManager::DialogFolder *MessagesManager::get_dialog_folder(FolderId folder_id) const { CHECK(!td_->auth_manager_->is_bot()); - if (folder_id != FolderId::archive()) { - folder_id = FolderId::main(); - } auto it = dialog_folders_.find(folder_id); if (it == dialog_folders_.end()) { return nullptr; @@ -37750,7 +36287,8 @@ string MessagesManager::get_channel_pts_key(DialogId dialog_id) { } int32 MessagesManager::load_channel_pts(DialogId dialog_id) const { - if (td_->ignore_background_updates() || !have_input_peer(dialog_id, AccessRights::Read)) { + if (td_->ignore_background_updates() || + !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { G()->td_db()->get_binlog_pmc()->erase(get_channel_pts_key(dialog_id)); // just in case return 0; } @@ -37797,7 +36335,8 @@ void MessagesManager::set_channel_pts(Dialog *d, int32 new_pts, const char *sour repair_channel_server_unread_count(d); } } - if (!td_->ignore_background_updates() && have_input_peer(d->dialog_id, AccessRights::Read)) { + if (!td_->ignore_background_updates() && + td_->dialog_manager_->have_input_peer(d->dialog_id, false, AccessRights::Read)) { G()->td_db()->get_binlog_pmc()->set(get_channel_pts_key(d->dialog_id), to_string(new_pts)); } } else if (new_pts < d->pts) { @@ -37808,38 +36347,44 @@ void MessagesManager::set_channel_pts(Dialog *d, int32 new_pts, const char *sour bool MessagesManager::need_channel_difference_to_add_message(DialogId dialog_id, const tl_object_ptr &message_ptr) { - if (dialog_id.get_type() != DialogType::Channel || !have_input_peer(dialog_id, AccessRights::Read) || - dialog_id == debug_channel_difference_dialog_) { + if (message_ptr == nullptr || DialogId::get_message_dialog_id(message_ptr) != dialog_id) { return false; } - if (message_ptr == nullptr) { - return true; - } - if (DialogId::get_message_dialog_id(message_ptr) != dialog_id) { + + return need_channel_difference_to_add_message(dialog_id, MessageId::get_message_id(message_ptr, false)); +} + +bool MessagesManager::need_channel_difference_to_add_message(DialogId dialog_id, MessageId message_id) { + if (td_->auth_manager_->is_bot() || dialog_id.get_type() != DialogType::Channel || + !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read) || + dialog_id == debug_channel_difference_dialog_) { return false; } Dialog *d = get_dialog_force(dialog_id, "need_channel_difference_to_add_message"); if (d == nullptr) { + LOG(DEBUG) << "Can't find " << dialog_id; return load_channel_pts(dialog_id) > 0 && !is_channel_difference_finished_.count(dialog_id); } if (d->last_new_message_id == MessageId()) { + LOG(DEBUG) << "Can't find last message in " << dialog_id; return d->pts > 0 && !d->is_channel_difference_finished; } - return MessageId::get_message_id(message_ptr, false) > d->last_new_message_id; + LOG(DEBUG) << "Check ability to add " << message_id << " to " << dialog_id; + return message_id > d->last_new_message_id; } void MessagesManager::run_after_channel_difference(DialogId dialog_id, MessageId expected_max_message_id, - Promise &&promise) { + Promise &&promise, const char *source) { CHECK(dialog_id.get_type() == DialogType::Channel); - CHECK(have_input_peer(dialog_id, AccessRights::Read)); + CHECK(td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)); run_after_get_channel_difference_[dialog_id].push_back(std::move(promise)); const Dialog *d = get_dialog(dialog_id); get_channel_difference(dialog_id, d == nullptr ? load_channel_pts(dialog_id) : d->pts, 0, expected_max_message_id, - true, "run_after_channel_difference"); + true, source); } bool MessagesManager::running_get_channel_difference(DialogId dialog_id) const { @@ -37886,6 +36431,7 @@ void MessagesManager::update_expected_channel_pts(DialogId dialog_id, int32 expe if (expected_pts <= 0) { return; } + CHECK(dialog_id.is_valid()); auto &old_pts = expected_channel_pts_[dialog_id]; if (old_pts < expected_pts) { old_pts = expected_pts; @@ -37896,6 +36442,7 @@ void MessagesManager::update_expected_channel_max_message_id(DialogId dialog_id, if (expected_max_message_id == MessageId() || td_->auth_manager_->is_bot()) { return; } + CHECK(dialog_id.is_valid()); auto &old_max_message_id = expected_channel_max_message_id_[dialog_id]; if (old_max_message_id < expected_max_message_id) { old_max_message_id = expected_max_message_id; @@ -37903,8 +36450,9 @@ void MessagesManager::update_expected_channel_max_message_id(DialogId dialog_id, } void MessagesManager::schedule_get_channel_difference(DialogId dialog_id, int32 expected_pts, - MessageId expected_max_message_id, double delay) { - LOG(INFO) << "Schedule getDifference in " << dialog_id; + MessageId expected_max_message_id, double delay, + const char *source) { + LOG(INFO) << "Schedule getDifference in " << dialog_id << " from " << source; update_expected_channel_pts(dialog_id, expected_pts); update_expected_channel_max_message_id(dialog_id, expected_max_message_id); channel_get_difference_retry_timeout_.add_timeout_in(dialog_id.get(), delay); @@ -37932,14 +36480,14 @@ void MessagesManager::get_channel_difference(DialogId dialog_id, int32 pts, int3 debug_last_get_channel_difference_dialog_id_ = dialog_id; debug_last_get_channel_difference_source_ = source; - auto input_channel = td_->contacts_manager_->get_input_channel(dialog_id.get_channel_id()); + auto input_channel = td_->chat_manager_->get_input_channel(dialog_id.get_channel_id()); if (input_channel == nullptr) { LOG(ERROR) << "Skip running channels.getDifference for " << dialog_id << " from " << source << " because the channel is unknown"; after_get_channel_difference(dialog_id, false); return; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { LOG(INFO) << "Skip running channels.getDifference for " << dialog_id << " from " << source << " because have no read access to it"; after_get_channel_difference(dialog_id, false); @@ -37974,13 +36522,13 @@ void MessagesManager::do_get_channel_difference(DialogId dialog_id, int32 pts, b // can be called multiple times before after_get_channel_difference const Dialog *d = get_dialog(dialog_id); if (d != nullptr && d->notification_info != nullptr) { - if (d->notification_info->message_notification_group_.group_id.is_valid()) { + if (d->notification_info->message_notification_group_.is_valid()) { send_closure_later(G()->notification_manager(), &NotificationManager::before_get_chat_difference, - d->notification_info->message_notification_group_.group_id); + d->notification_info->message_notification_group_.get_group_id()); } - if (d->notification_info->mention_notification_group_.group_id.is_valid()) { + if (d->notification_info->mention_notification_group_.is_valid()) { send_closure_later(G()->notification_manager(), &NotificationManager::before_get_chat_difference, - d->notification_info->mention_notification_group_.group_id); + d->notification_info->mention_notification_group_.get_group_id()); } } @@ -38049,11 +36597,11 @@ void MessagesManager::process_get_channel_difference_updates( } case telegram_api::updateEditChannelMessage::ID: { auto *update = static_cast(update_ptr.get()); - auto full_message_id = FullMessageId::get_full_message_id(update->message_, false); - if (full_message_id.get_dialog_id() != dialog_id) { + auto message_full_id = MessageFullId::get_message_full_id(update->message_, false); + if (message_full_id.get_dialog_id() != dialog_id) { is_good_update = false; } else { - changed_message_ids.insert(full_message_id.get_message_id()); + changed_message_ids.insert(message_full_id.get_message_id()); } break; } @@ -38113,8 +36661,8 @@ void MessagesManager::process_get_channel_difference_updates( if (update->get_id() == telegram_api::updateNewChannelMessage::ID) { auto update_new_channel_message = static_cast(update.get()); auto message_id = MessageId::get_message_id(update_new_channel_message->message_, false); - FullMessageId full_message_id(dialog_id, message_id); - if (update_message_ids_.count(full_message_id) > 0 && changed_message_ids.count(message_id) > 0) { + MessageFullId message_full_id(dialog_id, message_id); + if (update_message_ids_.count(message_full_id) > 0 && changed_message_ids.count(message_id) > 0) { changed_message_ids.erase(message_id); AwaitedMessage awaited_message; awaited_message.message = std::move(update_new_channel_message->message_); @@ -38185,7 +36733,7 @@ void MessagesManager::on_get_channel_dialog(DialogId dialog_id, MessageId last_m int32 unread_mention_count, int32 unread_reaction_count, MessageId read_outbox_max_message_id, vector> &&messages) { - FlatHashMap, FullMessageIdHash> full_message_id_to_message; + FlatHashMap, MessageFullIdHash> message_full_id_to_message; for (auto &message : messages) { auto message_id = MessageId::get_message_id(message, false); if (!message_id.is_valid()) { @@ -38195,19 +36743,17 @@ void MessagesManager::on_get_channel_dialog(DialogId dialog_id, MessageId last_m if (!message_dialog_id.is_valid()) { message_dialog_id = dialog_id; } - auto full_message_id = FullMessageId(message_dialog_id, message_id); - full_message_id_to_message[full_message_id] = std::move(message); + auto message_full_id = MessageFullId(message_dialog_id, message_id); + message_full_id_to_message[message_full_id] = std::move(message); } - FullMessageId last_full_message_id(dialog_id, last_message_id); - if (last_message_id.is_valid()) { - if (full_message_id_to_message.count(last_full_message_id) == 0) { - LOG(ERROR) << "Last " << last_message_id << " in " << dialog_id << " not found. Have:"; - for (auto &message : full_message_id_to_message) { - LOG(ERROR) << to_string(message.second); - } - return; + MessageFullId last_message_full_id(dialog_id, last_message_id); + if (last_message_id.is_valid() && message_full_id_to_message.count(last_message_full_id) == 0) { + LOG(ERROR) << "Last " << last_message_id << " in " << dialog_id << " not found. Have:"; + for (auto &message : message_full_id_to_message) { + LOG(ERROR) << to_string(message.second); } + return; } CHECK(!last_message_id.is_scheduled()); @@ -38232,6 +36778,14 @@ void MessagesManager::on_get_channel_dialog(DialogId dialog_id, MessageId last_m // offline. It is the best way for gaps support, but it is pretty hard to implement correctly. // It should be also noted that some messages like outgoing live location messages shouldn't be deleted. + if (is_message_unload_enabled()) { + if (d->open_count == 0) { + unload_dialog(dialog_id, 0); + } else { + d->need_unload_on_close = true; + } + } + if (last_message_id > d->last_new_message_id && !td_->auth_manager_->is_bot()) { // TODO properly support last_message_id <= d->last_new_message_id set_dialog_first_database_message_id(d, MessageId(), "on_get_channel_dialog 6"); @@ -38255,19 +36809,19 @@ void MessagesManager::on_get_channel_dialog(DialogId dialog_id, MessageId last_m d->last_new_message_id = MessageId(); set_dialog_last_message_id(d, MessageId(), "on_get_channel_dialog 20"); send_update_chat_last_message(d, "on_get_channel_dialog 30"); - FullMessageId added_full_message_id; - if (last_full_message_id.get_message_id().is_valid()) { - last_full_message_id = on_get_message(std::move(full_message_id_to_message[last_full_message_id]), true, true, - false, "channel difference too long"); - } - if (added_full_message_id.get_message_id().is_valid()) { - if (added_full_message_id.get_message_id() == d->last_new_message_id) { - CHECK(last_full_message_id == added_full_message_id); + MessageFullId added_message_full_id; + if (last_message_id.is_valid()) { + added_message_full_id = on_get_message(std::move(message_full_id_to_message[last_message_full_id]), true, true, + false, "channel difference too long"); + } + if (added_message_full_id.get_message_id().is_valid()) { + if (added_message_full_id.get_message_id() == d->last_new_message_id) { + CHECK(last_message_full_id == added_message_full_id); if (!td_->auth_manager_->is_bot()) { CHECK(d->last_message_id == d->last_new_message_id); } } else { - LOG(ERROR) << added_full_message_id << " doesn't became last new message, which is " << d->last_new_message_id; + LOG(ERROR) << added_message_full_id << " doesn't became last new message, which is " << d->last_new_message_id; } } else if (last_message_id > d->last_new_message_id) { set_dialog_last_new_message_id(d, last_message_id, @@ -38299,9 +36853,22 @@ void MessagesManager::on_get_channel_dialog(DialogId dialog_id, MessageId last_m } } -void MessagesManager::on_get_channel_difference( - DialogId dialog_id, int32 request_pts, int32 request_limit, - tl_object_ptr &&difference_ptr) { +void MessagesManager::retry_get_channel_difference_later(DialogId dialog_id) { + auto &delay = channel_get_difference_retry_timeouts_[dialog_id]; + if (delay == 0) { + delay = 1; + } + schedule_get_channel_difference(dialog_id, 0, MessageId(), Random::fast(delay * 800, delay * 1200) * 1e-3, + "retry_get_channel_difference_later"); + delay *= 2; + if (delay > 60) { + delay = Random::fast(60, 80); + } +} + +void MessagesManager::on_get_channel_difference(DialogId dialog_id, int32 request_pts, int32 request_limit, + tl_object_ptr &&difference_ptr, + Status &&status) { get_channel_difference_count_--; CHECK(get_channel_difference_count_ >= 0); process_pending_get_channel_differences(); @@ -38313,27 +36880,25 @@ void MessagesManager::on_get_channel_difference( auto d = get_dialog_force(dialog_id, "on_get_channel_difference"); if (difference_ptr == nullptr) { - bool have_access = have_input_peer(dialog_id, AccessRights::Read); + CHECK(status.is_error()); + bool have_access = td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read) && + td_->chat_manager_->have_channel(dialog_id.get_channel_id()) && + status.message() != "CHANNEL_INVALID"; if (have_access) { if (d == nullptr) { force_create_dialog(dialog_id, "on_get_channel_difference failed"); + d = get_dialog(dialog_id); + if (d == nullptr) { + return after_get_channel_difference(dialog_id, false); + } } - auto &delay = channel_get_difference_retry_timeouts_[dialog_id]; - if (delay == 0) { - delay = 1; - } - schedule_get_channel_difference(dialog_id, 0, MessageId(), Random::fast(delay * 1000, delay * 1500) * 1e-3); - delay *= 2; - if (delay > 60) { - delay = Random::fast(60, 80); - } + retry_get_channel_difference_later(dialog_id); } else { after_get_channel_difference(dialog_id, false); } return; } - - channel_get_difference_retry_timeouts_.erase(dialog_id); + CHECK(status.is_ok()); LOG(INFO) << "Receive result of getChannelDifference for " << dialog_id << " with PTS = " << request_pts << " and limit = " << request_limit << " from " << source << ": " << to_string(difference_ptr); @@ -38343,6 +36908,7 @@ void MessagesManager::on_get_channel_difference( case telegram_api::updates_channelDifferenceEmpty::ID: if (d == nullptr) { // no need to create the dialog + channel_get_difference_retry_timeouts_.erase(dialog_id); after_get_channel_difference(dialog_id, true); return; } @@ -38350,21 +36916,31 @@ void MessagesManager::on_get_channel_difference( case telegram_api::updates_channelDifference::ID: { auto difference = static_cast(difference_ptr.get()); have_new_messages = !difference->new_messages_.empty(); - td_->contacts_manager_->on_get_users(std::move(difference->users_), "updates.channelDifference"); - td_->contacts_manager_->on_get_chats(std::move(difference->chats_), "updates.channelDifference"); + td_->user_manager_->on_get_users(std::move(difference->users_), "updates.channelDifference"); + td_->chat_manager_->on_get_chats(std::move(difference->chats_), "updates.channelDifference"); + for (const auto &message : difference->new_messages_) { + if (is_invalid_poll_message(message.get())) { + LOG(ERROR) << "Receive invalid poll message in updates.channelDifference: " << oneline(to_string(message)); + if (d != nullptr && channel_get_difference_retry_timeouts_[dialog_id] <= 2) { + return retry_get_channel_difference_later(dialog_id); + } + } + } break; } case telegram_api::updates_channelDifferenceTooLong::ID: { auto difference = static_cast(difference_ptr.get()); have_new_messages = difference->dialog_->get_id() == telegram_api::dialog::ID && !difference->messages_.empty(); - td_->contacts_manager_->on_get_users(std::move(difference->users_), "updates.channelDifferenceTooLong"); - td_->contacts_manager_->on_get_chats(std::move(difference->chats_), "updates.channelDifferenceTooLong"); + td_->user_manager_->on_get_users(std::move(difference->users_), "updates.channelDifferenceTooLong"); + td_->chat_manager_->on_get_chats(std::move(difference->chats_), "updates.channelDifferenceTooLong"); break; } default: UNREACHABLE(); } + channel_get_difference_retry_timeouts_.erase(dialog_id); + bool need_update_dialog_pos = false; if (d == nullptr) { d = add_dialog_for_new_message(dialog_id, have_new_messages, &need_update_dialog_pos, "on_get_channel_difference"); @@ -38392,7 +36968,7 @@ void MessagesManager::on_get_channel_difference( // bots can receive channelDifferenceEmpty with PTS bigger than known PTS // also, this can happen for deleted channels if (request_pts != difference->pts_ && !td_->auth_manager_->is_bot() && - have_input_peer(dialog_id, AccessRights::Read)) { + td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { LOG(ERROR) << "Receive channelDifferenceEmpty as result of getChannelDifference from " << source << " with PTS = " << request_pts << " and limit = " << request_limit << " in " << dialog_id << ", but PTS has changed to " << difference->pts_; @@ -38485,6 +37061,7 @@ void MessagesManager::on_get_channel_difference( } set_dialog_folder_id(d, FolderId(dialog->folder_id_)); + set_dialog_view_as_messages(d, dialog->view_forum_as_messages_, "updates.channelDifferenceTooLong"); on_update_dialog_notify_settings(dialog_id, std::move(dialog->notify_settings_), "updates.channelDifferenceTooLong"); @@ -38494,8 +37071,7 @@ void MessagesManager::on_get_channel_difference( set_dialog_is_marked_as_unread(d, is_marked_as_unread); } - update_dialog_draft_message(d, get_draft_message(td_->contacts_manager_.get(), std::move(dialog->draft_)), true, - false); + update_dialog_draft_message(d, get_draft_message(td_, std::move(dialog->draft_)), true, false); on_get_channel_dialog(dialog_id, MessageId(ServerMessageId(dialog->top_message_)), MessageId(ServerMessageId(dialog->read_inbox_max_id_)), dialog->unread_count_, @@ -38549,7 +37125,8 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ } auto d = get_dialog(dialog_id); - bool have_access = have_input_peer(dialog_id, AccessRights::Read); + bool have_access = td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read) && + td_->chat_manager_->have_channel(dialog_id.get_channel_id()); auto pts = d != nullptr ? d->pts : load_channel_pts(dialog_id); auto postponed_updates_it = postponed_channel_updates_.find(dialog_id); if (postponed_updates_it != postponed_channel_updates_.end()) { @@ -38603,13 +37180,13 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ d->is_channel_difference_finished = true; if (d->notification_info != nullptr) { - if (d->notification_info->message_notification_group_.group_id.is_valid()) { + if (d->notification_info->message_notification_group_.is_valid()) { send_closure_later(G()->notification_manager(), &NotificationManager::after_get_chat_difference, - d->notification_info->message_notification_group_.group_id); + d->notification_info->message_notification_group_.get_group_id()); } - if (d->notification_info->mention_notification_group_.group_id.is_valid()) { + if (d->notification_info->mention_notification_group_.is_valid()) { send_closure_later(G()->notification_manager(), &NotificationManager::after_get_chat_difference, - d->notification_info->mention_notification_group_.group_id); + d->notification_info->mention_notification_group_.get_group_id()); } } } else { @@ -38640,13 +37217,13 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ if (d != nullptr && !td_->auth_manager_->is_bot() && have_access && !d->last_message_id.is_valid() && !d->is_empty && (d->order != DEFAULT_ORDER || is_dialog_sponsored(d))) { - get_history_from_the_end_impl(d, true, false, Auto(), "after_get_channel_difference"); + load_last_dialog_message(d, "after_get_channel_difference"); } auto expected_channel_pts_it = expected_channel_pts_.find(dialog_id); if (expected_channel_pts_it != expected_channel_pts_.end()) { - if (success && expected_channel_pts_it->second > pts) { - schedule_get_channel_difference(dialog_id, 0, MessageId(), 1.0); + if (success && d != nullptr && expected_channel_pts_it->second > pts) { + schedule_get_channel_difference(dialog_id, 0, MessageId(), 1.0, "after_get_channel_difference"); } expected_channel_pts_.erase(expected_channel_pts_it); } @@ -38654,7 +37231,7 @@ void MessagesManager::after_get_channel_difference(DialogId dialog_id, bool succ auto expected_channel_max_message_id_it = expected_channel_max_message_id_.find(dialog_id); if (expected_channel_max_message_id_it != expected_channel_max_message_id_.end()) { if (success && d != nullptr && expected_channel_max_message_id_it->second > d->last_new_message_id) { - schedule_get_channel_difference(dialog_id, 0, MessageId(), 1.0); + schedule_get_channel_difference(dialog_id, 0, MessageId(), 1.0, "after_get_channel_difference 2"); } expected_channel_max_message_id_.erase(expected_channel_max_message_id_it); } @@ -38666,10 +37243,10 @@ void MessagesManager::reget_message_from_server_if_needed(DialogId dialog_id, co } if (need_reget_message_content(m->content.get()) || (m->legacy_layer != 0 && m->legacy_layer < MTPROTO_LAYER) || - m->reply_info.need_reget(td_)) { - FullMessageId full_message_id{dialog_id, m->message_id}; - LOG(INFO) << "Reget from server " << full_message_id; - get_message_from_server(full_message_id, Auto(), "reget_message_from_server_if_needed"); + m->reply_info.need_reget(td_) || m->replied_message_info.need_reget()) { + MessageFullId message_full_id{dialog_id, m->message_id}; + LOG(INFO) << "Reget from server " << message_full_id; + get_message_from_server(message_full_id, Auto(), "reget_message_from_server_if_needed"); } } @@ -38703,19 +37280,19 @@ void MessagesManager::speculatively_update_channel_participants(DialogId dialog_ } auto channel_id = dialog_id.get_channel_id(); - UserId my_user_id(td_->contacts_manager_->get_my_id()); + UserId my_user_id(td_->user_manager_->get_my_id()); bool by_me = m->sender_user_id == my_user_id; switch (m->content->get_type()) { case MessageContentType::ChatAddUsers: - send_closure_later(G()->contacts_manager(), &ContactsManager::speculative_add_channel_participants, channel_id, + send_closure_later(G()->chat_manager(), &ChatManager::speculative_add_channel_participants, channel_id, get_message_content_added_user_ids(m->content.get()), m->sender_user_id, m->date, by_me); break; case MessageContentType::ChatJoinedByLink: - send_closure_later(G()->contacts_manager(), &ContactsManager::speculative_add_channel_participants, channel_id, + send_closure_later(G()->chat_manager(), &ChatManager::speculative_add_channel_participants, channel_id, vector{m->sender_user_id}, m->sender_user_id, m->date, by_me); break; case MessageContentType::ChatDeleteUser: - send_closure_later(G()->contacts_manager(), &ContactsManager::speculative_delete_channel_participant, channel_id, + send_closure_later(G()->chat_manager(), &ChatManager::speculative_delete_channel_participant, channel_id, get_message_content_deleted_user_id(m->content.get()), by_me); break; default: @@ -38725,7 +37302,7 @@ void MessagesManager::speculatively_update_channel_participants(DialogId dialog_ void MessagesManager::update_sent_message_contents(DialogId dialog_id, const Message *m) { CHECK(m != nullptr); - if (td_->auth_manager_->is_bot() || (!m->is_outgoing && dialog_id != get_my_dialog_id()) || + if (td_->auth_manager_->is_bot() || (!m->is_outgoing && dialog_id != td_->dialog_manager_->get_my_dialog_id()) || dialog_id.get_type() == DialogType::SecretChat || m->message_id.is_local() || m->forward_info != nullptr || m->had_forward_info) { return; @@ -38736,8 +37313,9 @@ void MessagesManager::update_sent_message_contents(DialogId dialog_id, const Mes void MessagesManager::update_used_hashtags(DialogId dialog_id, const Message *m) { CHECK(m != nullptr); - if (td_->auth_manager_->is_bot() || (!m->is_outgoing && dialog_id != get_my_dialog_id()) || - m->via_bot_user_id.is_valid() || m->hide_via_bot || m->forward_info != nullptr || m->had_forward_info) { + if (td_->auth_manager_->is_bot() || (!m->is_outgoing && dialog_id != td_->dialog_manager_->get_my_dialog_id()) || + m->via_bot_user_id.is_valid() || m->via_business_bot_user_id.is_valid() || m->hide_via_bot || + m->forward_info != nullptr || m->had_forward_info) { return; } @@ -38747,8 +37325,9 @@ void MessagesManager::update_used_hashtags(DialogId dialog_id, const Message *m) void MessagesManager::update_top_dialogs(DialogId dialog_id, const Message *m) { CHECK(m != nullptr); auto dialog_type = dialog_id.get_type(); - if (td_->auth_manager_->is_bot() || (!m->is_outgoing && dialog_id != get_my_dialog_id()) || - dialog_type == DialogType::SecretChat || !m->message_id.is_any_server()) { + if (td_->auth_manager_->is_bot() || (!m->is_outgoing && dialog_id != td_->dialog_manager_->get_my_dialog_id()) || + dialog_type == DialogType::SecretChat || !m->message_id.is_any_server() || + m->via_business_bot_user_id.is_valid()) { return; } @@ -38771,7 +37350,7 @@ void MessagesManager::update_top_dialogs(DialogId dialog_id, const Message *m) { TopDialogCategory category = TopDialogCategory::Size; switch (dialog_type) { case DialogType::User: { - if (td_->contacts_manager_->is_user_bot(dialog_id.get_user_id())) { + if (td_->user_manager_->is_user_bot(dialog_id.get_user_id())) { category = TopDialogCategory::BotPM; } else { category = TopDialogCategory::Correspondent; @@ -38782,7 +37361,7 @@ void MessagesManager::update_top_dialogs(DialogId dialog_id, const Message *m) { category = TopDialogCategory::Group; break; case DialogType::Channel: - switch (td_->contacts_manager_->get_channel_type(dialog_id.get_channel_id())) { + switch (td_->chat_manager_->get_channel_type(dialog_id.get_channel_id())) { case ChannelType::Broadcast: category = TopDialogCategory::Channel; break; @@ -38807,19 +37386,25 @@ void MessagesManager::update_top_dialogs(DialogId dialog_id, const Message *m) { } void MessagesManager::update_forward_count(DialogId dialog_id, const Message *m) { - if (!td_->auth_manager_->is_bot() && m->forward_info != nullptr && m->forward_info->sender_dialog_id.is_valid() && - m->forward_info->message_id.is_valid() && - (!is_discussion_message(dialog_id, m) || m->forward_info->sender_dialog_id != m->forward_info->from_dialog_id || - m->forward_info->message_id != m->forward_info->from_message_id)) { - update_forward_count(m->forward_info->sender_dialog_id, m->forward_info->message_id, m->date); + if (td_->auth_manager_->is_bot() || m->forward_info == nullptr) { + return; + } + auto origin_message_full_id = m->forward_info->get_origin_message_full_id(); + if (!origin_message_full_id.get_message_id().is_valid()) { + return; + } + if (is_discussion_message(dialog_id, m) && origin_message_full_id == m->forward_info->get_last_message_full_id()) { + return; } + update_forward_count(origin_message_full_id, m->date); } -void MessagesManager::update_forward_count(DialogId dialog_id, MessageId message_id, int32 update_date) { +void MessagesManager::update_forward_count(MessageFullId message_full_id, int32 update_date) { CHECK(!td_->auth_manager_->is_bot()); + auto dialog_id = message_full_id.get_dialog_id(); Dialog *d = get_dialog(dialog_id); CHECK(d != nullptr); - Message *m = get_message_force(d, message_id, "update_forward_count"); + Message *m = get_message_force(d, message_full_id.get_message_id(), "update_forward_count"); if (m != nullptr && !m->message_id.is_scheduled() && m->message_id.is_server() && m->view_count > 0 && m->interaction_info_update_date < update_date) { if (m->forward_count == 0) { @@ -38835,7 +37420,7 @@ void MessagesManager::update_forward_count(DialogId dialog_id, MessageId message void MessagesManager::update_has_outgoing_messages(DialogId dialog_id, const Message *m) { CHECK(m != nullptr); - if (td_->auth_manager_->is_bot() || (!m->is_outgoing && dialog_id != get_my_dialog_id())) { + if (td_->auth_manager_->is_bot() || (!m->is_outgoing && dialog_id != td_->dialog_manager_->get_my_dialog_id())) { return; } @@ -38848,7 +37433,7 @@ void MessagesManager::update_has_outgoing_messages(DialogId dialog_id, const Mes case DialogType::Channel: break; case DialogType::SecretChat: { - auto user_id = td_->contacts_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); + auto user_id = td_->user_manager_->get_secret_chat_user_id(dialog_id.get_secret_chat_id()); if (user_id.is_valid()) { d = get_dialog_force(DialogId(user_id), "update_has_outgoing_messages"); } @@ -38869,19 +37454,61 @@ void MessagesManager::update_has_outgoing_messages(DialogId dialog_id, const Mes } } +void MessagesManager::set_message_reply(const Dialog *d, Message *m, MessageInputReplyTo input_reply_to, + bool is_message_in_dialog) { + LOG(INFO) << "Update replied message of " << MessageFullId{d->dialog_id, m->message_id} << " from " + << m->replied_message_info << " to " << input_reply_to; + if (is_message_in_dialog) { + unregister_message_reply(d->dialog_id, m); + } + m->replied_message_info = RepliedMessageInfo(td_, input_reply_to); + m->reply_to_story_full_id = StoryFullId(); + m->reply_to_random_id = get_message_reply_to_random_id(d, m); + if (!m->message_id.is_any_server()) { + m->input_reply_to = std::move(input_reply_to); + } + if (is_message_in_dialog) { + register_message_reply(d->dialog_id, m); + } + update_message_max_reply_media_timestamp(d, m, is_message_in_dialog); +} + +void MessagesManager::update_message_reply_to_message_id(const Dialog *d, Message *m, MessageId reply_to_message_id, + bool is_message_in_dialog) { + LOG(INFO) << "Update identifier of replied message of " << MessageFullId{d->dialog_id, m->message_id} << " from " + << m->replied_message_info << " to " << reply_to_message_id; + if (is_message_in_dialog) { + unregister_message_reply(d->dialog_id, m); + } + m->replied_message_info.set_message_id(reply_to_message_id); + if (!m->message_id.is_any_server()) { + m->input_reply_to.set_message_id(reply_to_message_id); + } + if (is_message_in_dialog) { + register_message_reply(d->dialog_id, m); + } +} + void MessagesManager::restore_message_reply_to_message_id(Dialog *d, Message *m) { - if (m->reply_to_message_id == MessageId() || !m->reply_to_message_id.is_yet_unsent()) { + const auto *input_reply_to = get_message_input_reply_to(m); + CHECK(input_reply_to != nullptr); + if (input_reply_to->is_empty()) { + return; + } + auto replied_message_full_id = input_reply_to->get_reply_message_full_id(d->dialog_id); + auto replied_message_id = replied_message_full_id.get_message_id(); + if (replied_message_id == MessageId() || !replied_message_id.is_yet_unsent()) { return; } + CHECK(replied_message_full_id.get_dialog_id() == d->dialog_id); + LOG_CHECK(m->replied_message_info.get_reply_message_full_id(d->dialog_id, true) == replied_message_full_id) + << replied_message_full_id << ' ' << m->replied_message_info << ' ' << *input_reply_to; auto message_id = get_message_id_by_random_id(d, m->reply_to_random_id, "restore_message_reply_to_message_id"); - if (!message_id.is_valid() && !message_id.is_valid_scheduled()) { - LOG(INFO) << "Failed to find replied " << m->reply_to_message_id << " with random_id = " << m->reply_to_random_id; - m->reply_to_message_id = m->top_thread_message_id; - m->reply_to_random_id = 0; + if (message_id.is_valid() || message_id.is_valid_scheduled()) { + update_message_reply_to_message_id(d, m, message_id, false); } else { - LOG(INFO) << "Restore message reply to " << message_id << " with random_id = " << m->reply_to_random_id; - m->reply_to_message_id = message_id; + set_message_reply(d, m, MessageInputReplyTo{m->top_thread_message_id, DialogId(), MessageQuote()}, false); } } @@ -38897,7 +37524,7 @@ MessagesManager::Message *MessagesManager::continue_send_message(DialogId dialog binlog_erase(G()->td_db()->get_binlog(), log_event_id); return nullptr; } - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), log_event_id); return nullptr; } @@ -38928,7 +37555,7 @@ MessagesManager::Message *MessagesManager::continue_send_message(DialogId dialog auto can_send_status = can_send_message(dialog_id); if (can_send_status.is_ok() && result_message->send_date < now - MAX_RESEND_DELAY && - dialog_id != get_my_dialog_id()) { + dialog_id != td_->dialog_manager_->get_my_dialog_id()) { can_send_status = Status::Error(400, "Message is too old to be re-sent automatically"); } if (can_send_status.is_error()) { @@ -39010,14 +37637,12 @@ void MessagesManager::on_binlog_events(vector &&events) { CHECK(message->content->get_type() == MessageContentType::Text); + auto bot_user_id = log_event.bot_user_id; Dependencies dependencies; - dependencies.add_dialog_dependencies(dialog_id); + dependencies.add(bot_user_id); + dependencies.add_dialog_and_dependencies(dialog_id); add_message_dependencies(dependencies, message.get()); - dependencies.resolve_force(td_, "SendBotStartMessageLogEvent"); - - auto bot_user_id = log_event.bot_user_id; - if (!td_->contacts_manager_->have_user_force(bot_user_id)) { - LOG(ERROR) << "Can't find bot " << bot_user_id; + if (!dependencies.resolve_force(td_, "SendBotStartMessageLogEvent")) { binlog_erase(G()->td_db()->get_binlog(), event.id_); continue; } @@ -39122,32 +37747,25 @@ void MessagesManager::on_binlog_events(vector &&events) { auto messages = std::move(log_event.messages_out); Dependencies dependencies; - dependencies.add_dialog_dependencies(to_dialog_id); - dependencies.add_dialog_dependencies(from_dialog_id); + dependencies.add_dialog_and_dependencies(to_dialog_id); + dependencies.add_dialog_and_dependencies(from_dialog_id); for (auto &message : messages) { add_message_dependencies(dependencies, message.get()); } - dependencies.resolve_force(td_, "ForwardMessagesLogEvent"); - - Dialog *to_dialog = get_dialog_force(to_dialog_id, "ForwardMessagesLogEvent to"); - if (to_dialog == nullptr) { - LOG(ERROR) << "Can't find " << to_dialog_id << " to forward messages to"; - binlog_erase(G()->td_db()->get_binlog(), event.id_); - continue; - } - Dialog *from_dialog = get_dialog_force(from_dialog_id, "ForwardMessagesLogEvent from"); - if (from_dialog == nullptr) { - LOG(ERROR) << "Can't find " << from_dialog_id << " to forward messages from"; + if (!dependencies.resolve_force(td_, "ForwardMessagesLogEvent")) { binlog_erase(G()->td_db()->get_binlog(), event.id_); continue; } + Dialog *to_dialog = get_dialog(to_dialog_id); + CHECK(to_dialog != nullptr); to_dialog->was_opened = true; auto now = G()->unix_time(); - if (!have_input_peer(from_dialog_id, AccessRights::Read) || can_send_message(to_dialog_id).is_error() || - messages.empty() || - (messages[0]->send_date < now - MAX_RESEND_DELAY && to_dialog_id != get_my_dialog_id())) { + if (!td_->dialog_manager_->have_input_peer(from_dialog_id, false, AccessRights::Read) || + can_send_message(to_dialog_id).is_error() || messages.empty() || + (messages[0]->send_date < now - MAX_RESEND_DELAY && + to_dialog_id != td_->dialog_manager_->get_my_dialog_id())) { LOG(WARNING) << "Can't continue forwarding " << messages.size() << " message(s) to " << to_dialog_id; binlog_erase(G()->td_db()->get_binlog(), event.id_); continue; @@ -39186,6 +37804,71 @@ void MessagesManager::on_binlog_events(vector &&events) { log_event.drop_author, log_event.drop_media_captions, event.id_); break; } + case LogEvent::HandlerType::SendQuickReplyShortcutMessages: { + if (!have_old_message_database) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + continue; + } + + SendQuickReplyShortcutMessagesLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto dialog_id = log_event.dialog_id; + auto messages = std::move(log_event.messages_out); + + Dependencies dependencies; + dependencies.add_dialog_and_dependencies(dialog_id); + for (auto &message : messages) { + add_message_dependencies(dependencies, message.get()); + } + if (!dependencies.resolve_force(td_, "SendQuickReplyShortcutMessagesLogEvent")) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + continue; + } + + Dialog *d = get_dialog(dialog_id); + CHECK(d != nullptr); + d->was_opened = true; + + auto now = G()->unix_time(); + if (can_send_message(dialog_id).is_error() || messages.empty() || + (messages[0]->send_date < now - MAX_RESEND_DELAY && + dialog_id != td_->dialog_manager_->get_my_dialog_id())) { + LOG(WARNING) << "Can't continue sending quick reply shortcut " << messages.size() << " message(s) to " + << dialog_id; + binlog_erase(G()->td_db()->get_binlog(), event.id_); + continue; + } + + LOG(INFO) << "Continue to send quick reply shortcut " << messages.size() << " message(s) to " << dialog_id + << " from binlog"; + + bool need_update = false; + bool need_update_dialog_pos = false; + vector sent_messages; + for (auto &message : messages) { + message->message_id = get_next_yet_unsent_message_id(d); + message->date = now; + message->content = dup_message_content(td_, dialog_id, message->content.get(), + MessageContentDupType::ServerCopy, MessageCopyOptions(true, false)); + CHECK(message->content != nullptr); + + restore_message_reply_to_message_id(d, message.get()); + + sent_messages.push_back(add_message_to_dialog(d, std::move(message), false, true, &need_update, + &need_update_dialog_pos, + "send quick reply shortcut message again")); + send_update_new_message(d, sent_messages.back()); + } + + if (need_update_dialog_pos) { + send_update_chat_last_message(d, "SendQuickReplyShortcutMessagesLogEvent"); + } + + do_send_quick_reply_shortcut_messages(dialog_id, log_event.shortcut_id, sent_messages, log_event.message_ids, + event.id_); + break; + } case LogEvent::HandlerType::DeleteMessage: { if (!have_old_message_database) { binlog_erase(G()->td_db()->get_binlog(), event.id_); @@ -39196,9 +37879,9 @@ void MessagesManager::on_binlog_events(vector &&events) { log_event_parse(log_event, event.get_data()).ensure(); log_event.id_ = event.id_; - Dialog *d = get_dialog_force(log_event.full_message_id_.get_dialog_id(), "DeleteMessageLogEvent"); + Dialog *d = get_dialog_force(log_event.message_full_id_.get_dialog_id(), "DeleteMessageLogEvent"); if (d != nullptr) { - auto message_id = log_event.full_message_id_.get_message_id(); + auto message_id = log_event.message_full_id_.get_message_id(); if (message_id.is_valid_scheduled() && message_id.is_scheduled_server()) { add_dialog_scheduled_messages(d)->deleted_scheduled_server_message_ids_.insert( message_id.get_scheduled_server_message_id()); @@ -39221,7 +37904,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "DeleteMessagesOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39245,7 +37928,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "DeleteScheduledMessagesOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39270,7 +37953,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "DeleteDialogHistoryOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39290,7 +37973,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "DeleteTopicHistoryOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39324,17 +38007,14 @@ void MessagesManager::on_binlog_events(vector &&events) { log_event_parse(log_event, event.get_data()).ensure(); auto channel_id = log_event.channel_id_; - if (!td_->contacts_manager_->have_channel_force(channel_id)) { - LOG(ERROR) << "Can't find " << channel_id; - binlog_erase(G()->td_db()->get_binlog(), event.id_); - break; - } - auto sender_dialog_id = log_event.sender_dialog_id_; - if (!have_dialog_info_force(sender_dialog_id) || !have_input_peer(sender_dialog_id, AccessRights::Know)) { - LOG(ERROR) << "Can't find " << sender_dialog_id; + Dependencies dependencies; + dependencies.add(channel_id); + dependencies.add_dialog_dependencies(sender_dialog_id); + if (!dependencies.resolve_force(td_, "DeleteAllChannelMessagesFromSenderOnServer") || + !td_->dialog_manager_->have_input_peer(sender_dialog_id, false, AccessRights::Know)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); - break; + continue; } delete_all_channel_messages_by_sender_on_server(channel_id, sender_dialog_id, event.id_, Auto()); @@ -39351,7 +38031,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "DeleteDialogMessagesByDateOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39371,7 +38051,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "ReadHistoryOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39391,23 +38071,23 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; CHECK(dialog_id.get_type() == DialogType::SecretChat); - if (!td_->contacts_manager_->have_secret_chat_force(dialog_id.get_secret_chat_id())) { - LOG(ERROR) << "Can't read history in unknown " << dialog_id; - binlog_erase(G()->td_db()->get_binlog(), event.id_); - break; - } - force_create_dialog(dialog_id, "ReadHistoryInSecretChatLogEvent"); - Dialog *d = get_dialog(dialog_id); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + Dependencies dependencies; + dependencies.add_dialog_and_dependencies(dialog_id); + if (!dependencies.resolve_force(td_, "ReadHistoryInSecretChat") || + !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } + auto &log_event_id = read_history_log_event_ids_[dialog_id][0]; if (log_event_id.log_event_id != 0) { // we need only the latest read history event binlog_erase(G()->td_db()->get_binlog(), log_event_id.log_event_id); } log_event_id.log_event_id = event.id_; + + Dialog *d = get_dialog(dialog_id); + CHECK(d != nullptr); d->last_read_inbox_message_date = log_event.max_date_; read_history_on_server_impl(d, MessageId()); @@ -39424,7 +38104,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "ReadMessageThreadHistoryOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39450,7 +38130,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "ReadMessageContentsOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39469,7 +38149,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "ReadAllDialogMentionsOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39488,7 +38168,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "ReadAllDialogReactionsOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39507,7 +38187,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "ToggleDialogIsPinnedOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39527,7 +38207,7 @@ void MessagesManager::on_binlog_events(vector &&events) { vector dialog_ids; for (auto &dialog_id : log_event.dialog_ids_) { Dialog *d = get_dialog_force(dialog_id, "ReorderPinnedDialogsOnServerLogEvent"); - if (d != nullptr && have_input_peer(dialog_id, AccessRights::Read)) { + if (d != nullptr && td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { dialog_ids.push_back(dialog_id); } } @@ -39539,6 +38219,44 @@ void MessagesManager::on_binlog_events(vector &&events) { reorder_pinned_dialogs_on_server(log_event.folder_id_, dialog_ids, event.id_); break; } + case LogEvent::HandlerType::ToggleDialogViewAsMessagesOnServer: { + if (!have_old_message_database) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + ToggleDialogViewAsMessagesOnServerLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto dialog_id = log_event.dialog_id_; + if (!have_dialog_force(dialog_id, "ToggleDialogViewAsMessagesOnServerLogEvent") || + !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + toggle_dialog_view_as_messages_on_server(dialog_id, log_event.view_as_messages_, event.id_); + break; + } + case LogEvent::HandlerType::ToggleDialogIsTranslatableOnServer: { + if (!have_old_message_database) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + ToggleDialogIsTranslatableOnServerLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto dialog_id = log_event.dialog_id_; + if (!have_dialog_force(dialog_id, "ToggleDialogIsTranslatableOnServerLogEvent") || + !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + toggle_dialog_is_translatable_on_server(dialog_id, log_event.is_translatable_, event.id_); + break; + } case LogEvent::HandlerType::ToggleDialogIsMarkedAsUnreadOnServer: { if (!have_old_message_database) { binlog_erase(G()->td_db()->get_binlog(), event.id_); @@ -39549,10 +38267,8 @@ void MessagesManager::on_binlog_events(vector &&events) { log_event_parse(log_event, event.get_data()).ensure(); auto dialog_id = log_event.dialog_id_; - bool have_info = dialog_id.get_type() == DialogType::User - ? td_->contacts_manager_->have_user_force(dialog_id.get_user_id()) - : have_dialog_force(dialog_id, "ToggleDialogIsMarkedAsUnreadOnServerLogEvent"); - if (!have_info || !have_input_peer(dialog_id, AccessRights::Read)) { + if (!have_dialog_force(dialog_id, "ToggleDialogIsMarkedAsUnreadOnServerLogEvent") || + !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39570,13 +38286,15 @@ void MessagesManager::on_binlog_events(vector &&events) { log_event_parse(log_event, event.get_data()).ensure(); auto dialog_id = log_event.dialog_id_; - if (dialog_id.get_type() == DialogType::SecretChat || !have_dialog_info_force(dialog_id) || - !have_input_peer(dialog_id, AccessRights::Know)) { + if (dialog_id.get_type() == DialogType::SecretChat || + !td_->dialog_manager_->have_dialog_info_force(dialog_id, "ToggleDialogIsBlockedOnServerLogEvent") || + !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Know)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } - toggle_dialog_is_blocked_on_server(dialog_id, log_event.is_blocked_, event.id_); + toggle_dialog_is_blocked_on_server(dialog_id, log_event.is_blocked_, log_event.is_blocked_for_stories_, + event.id_); break; } case LogEvent::HandlerType::SaveDialogDraftMessageOnServer: { @@ -39590,7 +38308,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "SaveDialogDraftMessageOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Write)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Write)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39610,7 +38328,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "UpdateDialogNotificationSettingsOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39637,7 +38355,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "ToggleDialogReportSpamStateOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39656,7 +38374,7 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dialog *d = get_dialog_force(dialog_id, "SetDialogFolderIdOnServerLogEvent"); - if (d == nullptr || !have_input_peer(dialog_id, AccessRights::Read)) { + if (d == nullptr || !td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39679,9 +38397,9 @@ void MessagesManager::on_binlog_events(vector &&events) { auto dialog_id = log_event.dialog_id_; Dependencies dependencies; dependencies.add_dialog_and_dependencies(dialog_id); - dependencies.resolve_force(td_, "RegetDialogLogEvent"); + dependencies.resolve_force(td_, "RegetDialogLogEvent", true); // dialog itself may not exist - if (!have_input_peer(dialog_id, AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { binlog_erase(G()->td_db()->get_binlog(), event.id_); break; } @@ -39769,12 +38487,7 @@ void MessagesManager::suffix_load_loop(const Dialog *d, SuffixLoadQueries *queri }); queries->suffix_load_has_query_ = true; queries->suffix_load_query_message_id_ = from_message_id; - if (from_message_id.is_valid()) { - get_history_impl(d, from_message_id, -1, 100, true, true, std::move(promise)); - } else { - CHECK(from_message_id == MessageId()); - get_history_from_the_end_impl(d, true, true, std::move(promise), "suffix_load_loop"); - } + get_history_impl(d, from_message_id, -1, MAX_GET_HISTORY, true, true, std::move(promise), "suffix_load_loop"); } void MessagesManager::suffix_load_update_first_message_id(const Dialog *d, SuffixLoadQueries *queries) { @@ -39859,13 +38572,13 @@ void MessagesManager::suffix_load_till_message_id(Dialog *d, MessageId message_i suffix_load_add_query(d, std::make_pair(std::move(promise), std::move(condition))); } -void MessagesManager::set_poll_answer(FullMessageId full_message_id, vector &&option_ids, +void MessagesManager::set_poll_answer(MessageFullId message_full_id, vector &&option_ids, Promise &&promise) { - auto m = get_message_force(full_message_id, "set_poll_answer"); + auto m = get_message_force(message_full_id, "set_poll_answer"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!have_input_peer(full_message_id.get_dialog_id(), AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(message_full_id.get_dialog_id(), true, AccessRights::Read)) { return promise.set_error(Status::Error(400, "Can't access the chat")); } if (m->content->get_type() != MessageContentType::Poll) { @@ -39878,16 +38591,16 @@ void MessagesManager::set_poll_answer(FullMessageId full_message_id, vectorcontent.get(), full_message_id, std::move(option_ids), std::move(promise)); + set_message_content_poll_answer(td_, m->content.get(), message_full_id, std::move(option_ids), std::move(promise)); } -void MessagesManager::get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit, - Promise>> &&promise) { - auto m = get_message_force(full_message_id, "get_poll_voters"); +void MessagesManager::get_poll_voters(MessageFullId message_full_id, int32 option_id, int32 offset, int32 limit, + Promise> &&promise) { + auto m = get_message_force(message_full_id, "get_poll_voters"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!have_input_peer(full_message_id.get_dialog_id(), AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(message_full_id.get_dialog_id(), true, AccessRights::Read)) { return promise.set_error(Status::Error(400, "Can't access the chat")); } if (m->content->get_type() != MessageContentType::Poll) { @@ -39900,16 +38613,16 @@ void MessagesManager::get_poll_voters(FullMessageId full_message_id, int32 optio return promise.set_error(Status::Error(400, "Poll results can't be received")); } - get_message_content_poll_voters(td_, m->content.get(), full_message_id, option_id, offset, limit, std::move(promise)); + get_message_content_poll_voters(td_, m->content.get(), message_full_id, option_id, offset, limit, std::move(promise)); } -void MessagesManager::stop_poll(FullMessageId full_message_id, td_api::object_ptr &&reply_markup, +void MessagesManager::stop_poll(MessageFullId message_full_id, td_api::object_ptr &&reply_markup, Promise &&promise) { - auto m = get_message_force(full_message_id, "stop_poll"); + auto m = get_message_force(message_full_id, "stop_poll"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } - if (!have_input_peer(full_message_id.get_dialog_id(), AccessRights::Read)) { + if (!td_->dialog_manager_->have_input_peer(message_full_id.get_dialog_id(), true, AccessRights::Read)) { return promise.set_error(Status::Error(400, "Can't access the chat")); } if (m->content->get_type() != MessageContentType::Poll) { @@ -39918,7 +38631,7 @@ void MessagesManager::stop_poll(FullMessageId full_message_id, td_api::object_pt if (get_message_content_poll_is_closed(td_, m->content.get())) { return promise.set_error(Status::Error(400, "Poll has already been closed")); } - if (!can_edit_message(full_message_id.get_dialog_id(), m, true)) { + if (!can_edit_message(message_full_id.get_dialog_id(), m, true)) { return promise.set_error(Status::Error(400, "Poll can't be stopped")); } if (m->message_id.is_scheduled()) { @@ -39928,23 +38641,26 @@ void MessagesManager::stop_poll(FullMessageId full_message_id, td_api::object_pt return promise.set_error(Status::Error(400, "Poll can't be stopped")); } - auto r_new_reply_markup = get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, - has_message_sender_user_id(full_message_id.get_dialog_id(), m)); - if (r_new_reply_markup.is_error()) { - return promise.set_error(r_new_reply_markup.move_as_error()); - } + TRY_RESULT_PROMISE(promise, new_reply_markup, + get_reply_markup(std::move(reply_markup), td_->auth_manager_->is_bot(), true, false, + has_message_sender_user_id(message_full_id.get_dialog_id(), m))); - stop_message_content_poll(td_, m->content.get(), full_message_id, r_new_reply_markup.move_as_ok(), - std::move(promise)); + stop_message_content_poll(td_, m->content.get(), message_full_id, std::move(new_reply_markup), std::move(promise)); } -Result MessagesManager::get_invoice_message_id(FullMessageId full_message_id) { - auto m = get_message_force(full_message_id, "get_invoice_message_id"); +Result MessagesManager::get_invoice_message_info(MessageFullId message_full_id) { + auto m = get_message_force(message_full_id, "get_invoice_message_info"); if (m == nullptr) { return Status::Error(400, "Message not found"); } - if (m->content->get_type() != MessageContentType::Invoice) { - return Status::Error(400, "Message has no invoice"); + auto content_type = m->content->get_type(); + if (content_type != MessageContentType::Invoice) { + if (content_type != MessageContentType::PaidMedia) { + return Status::Error(400, "Message has no invoice"); + } + if (!need_poll_message_content_extended_media(m->content.get())) { + return Status::Error(400, "Message media has already been bought"); + } } if (m->message_id.is_scheduled()) { return Status::Error(400, "Wrong scheduled message identifier"); @@ -39955,14 +38671,20 @@ Result MessagesManager::get_invoice_message_id(FullMessageId fu if (m->reply_markup == nullptr || m->reply_markup->inline_keyboard.empty() || m->reply_markup->inline_keyboard[0].empty() || m->reply_markup->inline_keyboard[0][0].type != InlineKeyboardButton::Type::Buy) { - return Status::Error(400, "Message has no Pay button"); + if (content_type != MessageContentType::PaidMedia) { + return Status::Error(400, "Message has no Pay button"); + } } - return m->message_id.get_server_message_id(); + InvoiceMessageInfo result; + result.server_message_id_ = m->message_id.get_server_message_id(); + result.star_count_ = + content_type != MessageContentType::PaidMedia ? 0 : get_message_content_star_count(m->content.get()); + return std::move(result); } -Result MessagesManager::get_payment_successful_message_id(FullMessageId full_message_id) { - auto m = get_message_force(full_message_id, "get_payment_successful_message_id"); +Result MessagesManager::get_payment_successful_message_id(MessageFullId message_full_id) { + auto m = get_message_force(message_full_id, "get_payment_successful_message_id"); if (m == nullptr) { return Status::Error(400, "Message not found"); } @@ -39979,6 +38701,29 @@ Result MessagesManager::get_payment_successful_message_id(FullM return m->message_id.get_server_message_id(); } +Result MessagesManager::get_giveaway_message_id(MessageFullId message_full_id) { + auto m = get_message_force(message_full_id, "get_giveaway_message_id"); + if (m == nullptr) { + return Status::Error(400, "Message not found"); + } + switch (m->content->get_type()) { + case MessageContentType::Giveaway: + case MessageContentType::GiveawayWinners: + // ok + break; + default: + return Status::Error(400, "Message has wrong type"); + } + if (m->message_id.is_scheduled()) { + return Status::Error(400, "Wrong scheduled message identifier"); + } + if (!m->message_id.is_server()) { + return Status::Error(400, "Wrong message identifier"); + } + + return m->message_id.get_server_message_id(); +} + void MessagesManager::remove_sponsored_dialog() { set_sponsored_dialog(DialogId(), DialogSource()); } @@ -39988,8 +38733,8 @@ void MessagesManager::on_get_sponsored_dialog(tl_object_ptr vector> chats) { CHECK(peer != nullptr); - td_->contacts_manager_->on_get_users(std::move(users), "on_get_sponsored_dialog"); - td_->contacts_manager_->on_get_chats(std::move(chats), "on_get_sponsored_dialog"); + td_->user_manager_->on_get_users(std::move(users), "on_get_sponsored_dialog"); + td_->chat_manager_->on_get_chats(std::move(chats), "on_get_sponsored_dialog"); set_sponsored_dialog(DialogId(peer), std::move(source)); } @@ -40137,28 +38882,24 @@ void MessagesManager::get_current_state(vector> last_message_updates; dialogs_.foreach([&](const DialogId &dialog_id, const unique_ptr &dialog) { const Dialog *d = dialog.get(); - auto update = td_api::make_object(get_chat_object(d)); - if (update->chat_->last_message_ != nullptr && update->chat_->last_message_->forward_info_ != nullptr) { + auto update = td_api::make_object(get_chat_object(d, "get_current_state")); + if (update->chat_->last_message_ != nullptr) { last_message_updates.push_back(td_api::make_object( get_chat_id_object(dialog_id, "updateChatLastMessage"), std::move(update->chat_->last_message_), get_chat_positions_object(d))); } updates.push_back(std::move(update)); - - if (d->open_count > 0) { - auto info_it = dialog_online_member_counts_.find(dialog_id); - if (info_it != dialog_online_member_counts_.end() && info_it->second.is_update_sent) { - updates.push_back(td_api::make_object( - get_chat_id_object(dialog_id, "updateChatOnlineMemberCount"), info_it->second.online_member_count)); - } - } }); append(updates, std::move(last_message_updates)); + + if (!active_live_location_message_full_ids_.empty()) { + updates.push_back(get_update_active_live_location_messages_object()); + } } -void MessagesManager::add_message_file_to_downloads(FullMessageId full_message_id, FileId file_id, int32 priority, +void MessagesManager::add_message_file_to_downloads(MessageFullId message_full_id, FileId file_id, int32 priority, Promise> promise) { - auto m = get_message_force(full_message_id, "add_message_file_to_downloads"); + auto m = get_message_force(message_full_id, "add_message_file_to_downloads"); if (m == nullptr) { return promise.set_error(Status::Error(400, "Message not found")); } @@ -40182,15 +38923,15 @@ void MessagesManager::add_message_file_to_downloads(FullMessageId full_message_i return promise.set_error(Status::Error(400, "Yet unsent messages can't be added to Downloads")); } auto search_text = get_message_search_text(m); - auto file_source_id = get_message_file_source_id(full_message_id, true); + auto file_source_id = get_message_file_source_id(message_full_id, true); CHECK(file_source_id.is_valid()); send_closure(td_->download_manager_actor_, &DownloadManager::add_file, file_id, file_source_id, std::move(search_text), static_cast(priority), std::move(promise)); } -void MessagesManager::get_message_file_search_text(FullMessageId full_message_id, string unique_file_id, +void MessagesManager::get_message_file_search_text(MessageFullId message_full_id, string unique_file_id, Promise promise) { - auto m = get_message_force(full_message_id, "get_message_file_search_text"); + auto m = get_message_force(message_full_id, "get_message_file_search_text"); if (m == nullptr) { return promise.set_error(Status::Error(200, "Message not found")); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h b/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h index 77730ac86b..973d0a8f50 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MessagesManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,16 +9,15 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/AffectedHistory.h" #include "td/telegram/BackgroundInfo.h" +#include "td/telegram/BusinessConnectionId.h" #include "td/telegram/ChannelId.h" #include "td/telegram/ChatReactions.h" -#include "td/telegram/DialogAction.h" #include "td/telegram/DialogDate.h" #include "td/telegram/DialogDb.h" #include "td/telegram/DialogFilterDialogInfo.h" #include "td/telegram/DialogFilterId.h" #include "td/telegram/DialogId.h" #include "td/telegram/DialogListId.h" -#include "td/telegram/DialogLocation.h" #include "td/telegram/DialogNotificationSettings.h" #include "td/telegram/DialogParticipant.h" #include "td/telegram/DialogSource.h" @@ -26,51 +25,60 @@ #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileSourceId.h" #include "td/telegram/FolderId.h" -#include "td/telegram/FullMessageId.h" -#include "td/telegram/InputDialogId.h" #include "td/telegram/InputGroupCallId.h" #include "td/telegram/logevent/LogEventHelper.h" #include "td/telegram/MessageContentType.h" #include "td/telegram/MessageCopyOptions.h" #include "td/telegram/MessageDb.h" +#include "td/telegram/MessageEffectId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/MessageId.h" +#include "td/telegram/MessageInputReplyTo.h" #include "td/telegram/MessageLinkInfo.h" +#include "td/telegram/MessageOrigin.h" #include "td/telegram/MessageReplyHeader.h" #include "td/telegram/MessageReplyInfo.h" #include "td/telegram/MessageSearchFilter.h" +#include "td/telegram/MessageSelfDestructType.h" #include "td/telegram/MessagesInfo.h" #include "td/telegram/MessageSource.h" #include "td/telegram/MessageThreadInfo.h" #include "td/telegram/MessageTtl.h" #include "td/telegram/MessageViewer.h" -#include "td/telegram/net/DcId.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/Notification.h" +#include "td/telegram/NotificationGroupFromDatabase.h" #include "td/telegram/NotificationGroupId.h" +#include "td/telegram/NotificationGroupInfo.h" #include "td/telegram/NotificationGroupKey.h" #include "td/telegram/NotificationGroupType.h" #include "td/telegram/NotificationId.h" #include "td/telegram/NotificationSettingsScope.h" #include "td/telegram/OrderedMessage.h" -#include "td/telegram/Photo.h" +#include "td/telegram/QuickReplyShortcutId.h" +#include "td/telegram/ReactionType.h" +#include "td/telegram/ReactionUnavailabilityReason.h" #include "td/telegram/RecentDialogList.h" +#include "td/telegram/RepliedMessageInfo.h" #include "td/telegram/ReplyMarkup.h" -#include "td/telegram/ReportReason.h" #include "td/telegram/RestrictionReason.h" +#include "td/telegram/SavedMessagesTopicId.h" #include "td/telegram/ScheduledServerMessageId.h" #include "td/telegram/secret_api.h" #include "td/telegram/SecretChatId.h" #include "td/telegram/SecretInputMedia.h" #include "td/telegram/ServerMessageId.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/StoryNotificationSettings.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" -#include "td/telegram/Usernames.h" #include "td/actor/actor.h" #include "td/actor/MultiPromise.h" #include "td/actor/MultiTimeout.h" #include "td/actor/SignalSlot.h" +#include "td/actor/Timeout.h" #include "td/utils/buffer.h" #include "td/utils/ChangesProcessor.h" @@ -101,45 +109,23 @@ namespace td { struct BinlogEvent; +class BusinessBotManageBar; class Dependencies; class DialogActionBar; class DialogFilter; class DraftMessage; +class FactCheck; struct InputMessageContent; class MessageContent; +class MessageForwardInfo; struct MessageReactions; +struct MessageSearchOffset; +class MissingInvitees; class Td; +class Usernames; class MessagesManager final : public Actor { public: - // static constexpr int32 MESSAGE_FLAG_IS_UNREAD = 1 << 0; - static constexpr int32 MESSAGE_FLAG_IS_OUT = 1 << 1; - static constexpr int32 MESSAGE_FLAG_IS_FORWARDED = 1 << 2; - static constexpr int32 MESSAGE_FLAG_IS_REPLY = 1 << 3; - static constexpr int32 MESSAGE_FLAG_HAS_MENTION = 1 << 4; - static constexpr int32 MESSAGE_FLAG_HAS_UNREAD_CONTENT = 1 << 5; - static constexpr int32 MESSAGE_FLAG_HAS_REPLY_MARKUP = 1 << 6; - static constexpr int32 MESSAGE_FLAG_HAS_ENTITIES = 1 << 7; - static constexpr int32 MESSAGE_FLAG_HAS_FROM_ID = 1 << 8; - static constexpr int32 MESSAGE_FLAG_HAS_MEDIA = 1 << 9; - static constexpr int32 MESSAGE_FLAG_HAS_INTERACTION_INFO = 1 << 10; - static constexpr int32 MESSAGE_FLAG_IS_SENT_VIA_BOT = 1 << 11; - static constexpr int32 MESSAGE_FLAG_IS_SILENT = 1 << 13; - static constexpr int32 MESSAGE_FLAG_IS_POST = 1 << 14; - static constexpr int32 MESSAGE_FLAG_HAS_EDIT_DATE = 1 << 15; - static constexpr int32 MESSAGE_FLAG_HAS_AUTHOR_SIGNATURE = 1 << 16; - static constexpr int32 MESSAGE_FLAG_HAS_MEDIA_ALBUM_ID = 1 << 17; - static constexpr int32 MESSAGE_FLAG_IS_FROM_SCHEDULED = 1 << 18; - static constexpr int32 MESSAGE_FLAG_IS_LEGACY = 1 << 19; - static constexpr int32 MESSAGE_FLAG_HAS_REACTIONS = 1 << 20; - static constexpr int32 MESSAGE_FLAG_HIDE_EDIT_DATE = 1 << 21; - static constexpr int32 MESSAGE_FLAG_IS_RESTRICTED = 1 << 22; - static constexpr int32 MESSAGE_FLAG_HAS_REPLY_INFO = 1 << 23; - static constexpr int32 MESSAGE_FLAG_IS_PINNED = 1 << 24; - static constexpr int32 MESSAGE_FLAG_HAS_TTL_PERIOD = 1 << 25; - static constexpr int32 MESSAGE_FLAG_NOFORWARDS = 1 << 26; - - static constexpr int32 SEND_MESSAGE_FLAG_IS_REPLY = 1 << 0; static constexpr int32 SEND_MESSAGE_FLAG_DISABLE_WEB_PAGE_PREVIEW = 1 << 1; static constexpr int32 SEND_MESSAGE_FLAG_HAS_REPLY_MARKUP = 1 << 2; static constexpr int32 SEND_MESSAGE_FLAG_HAS_ENTITIES = 1 << 3; @@ -154,8 +140,8 @@ class MessagesManager final : public Actor { static constexpr int32 SEND_MESSAGE_FLAG_HAS_SEND_AS = 1 << 13; static constexpr int32 SEND_MESSAGE_FLAG_NOFORWARDS = 1 << 14; static constexpr int32 SEND_MESSAGE_FLAG_UPDATE_STICKER_SETS_ORDER = 1 << 15; - - static constexpr int32 ONLINE_MEMBER_COUNT_CACHE_EXPIRE_TIME = 30 * 60; + static constexpr int32 SEND_MESSAGE_FLAG_INVERT_MEDIA = 1 << 16; + static constexpr int32 SEND_MESSAGE_FLAG_EFFECT = 1 << 18; MessagesManager(Td *td, ActorShared<> parent); MessagesManager(const MessagesManager &) = delete; @@ -164,33 +150,23 @@ class MessagesManager final : public Actor { MessagesManager &operator=(MessagesManager &&) = delete; ~MessagesManager() final; - tl_object_ptr get_input_peer(DialogId dialog_id, AccessRights access_rights) const; - - static tl_object_ptr get_input_peer_force(DialogId dialog_id); - - vector> get_input_peers(const vector &dialog_ids, - AccessRights access_rights) const; - - tl_object_ptr get_input_dialog_peer(DialogId dialog_id, - AccessRights access_rights) const; - - vector> get_input_dialog_peers(const vector &dialog_ids, - AccessRights access_rights) const; + static bool is_invalid_poll_message(const telegram_api::Message *message); - tl_object_ptr get_input_encrypted_chat(DialogId dialog_id, - AccessRights access_rights) const; - - bool have_input_peer(DialogId dialog_id, AccessRights access_rights) const; - - vector get_peers_dialog_ids(vector> &&peers, - bool expect_no_access = false); + static int32 get_message_date(const tl_object_ptr &message_ptr); void on_get_empty_messages(DialogId dialog_id, const vector &empty_message_ids); + void get_channel_difference_if_needed(DialogId dialog_id, MessageId message_id, const char *source); + void get_channel_difference_if_needed(DialogId dialog_id, MessagesInfo &&messages_info, - Promise &&promise); + Promise &&promise, const char *source); + + void get_channel_differences_if_needed(MessagesInfo &&messages_info, Promise &&promise, + const char *source); - void get_channel_differences_if_needed(MessagesInfo &&messages_info, Promise &&promise); + void get_channel_differences_if_needed( + const vector *> &messages, Promise &&promise, + const char *source); void on_get_messages(vector> &&messages, bool is_channel_message, bool is_scheduled, Promise &&promise, const char *source); @@ -203,30 +179,36 @@ class MessagesManager final : public Actor { vector> &&peers); void on_failed_public_dialogs_search(const string &query, Status &&error); - void on_get_message_search_result_calendar(DialogId dialog_id, MessageId from_message_id, MessageSearchFilter filter, - int64 random_id, int32 total_count, + void on_get_message_search_result_calendar(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, int32 total_count, vector> &&messages, vector> &&periods, - Promise &&promise); - void on_failed_get_message_search_result_calendar(DialogId dialog_id, int64 random_id); - - void on_get_dialog_messages_search_result(DialogId dialog_id, const string &query, DialogId sender_dialog_id, - MessageId from_message_id, int32 offset, int32 limit, - MessageSearchFilter filter, MessageId top_thread_message_id, - int64 random_id, int32 total_count, - vector> &&messages, + Promise> &&promise); + + void on_get_call_messages(MessageId from_message_id, int32 limit, MessageSearchFilter filter, int32 total_count, + vector> &&messages, + Promise> &&promise); + + void on_get_dialog_messages_search_result(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + const string &query, DialogId sender_dialog_id, MessageId from_message_id, + int32 offset, int32 limit, MessageSearchFilter filter, + MessageId top_thread_message_id, const ReactionType &tag, int64 random_id, + int32 total_count, vector> &&messages, Promise &&promise); void on_failed_dialog_messages_search(DialogId dialog_id, int64 random_id); - void on_get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, int32 total_count, - Promise &&promise); + void on_get_dialog_message_count(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, int32 total_count, Promise &&promise); void on_get_messages_search_result(const string &query, int32 offset_date, DialogId offset_dialog_id, MessageId offset_message_id, int32 limit, MessageSearchFilter filter, - int32 min_date, int32 max_date, int64 random_id, int32 total_count, + int32 min_date, int32 max_date, int32 total_count, vector> &&messages, int32 next_rate, - Promise &&promise); - void on_failed_messages_search(int64 random_id); + Promise> &&promise); + + void on_get_hashtag_search_result(const string &hashtag, const MessageSearchOffset &old_offset, int32 limit, + int32 total_count, vector> &&messages, + int32 next_rate, Promise> &&promise); void on_get_outgoing_document_messages(vector> &&messages, Promise> &&promise); @@ -238,11 +220,7 @@ class MessagesManager final : public Actor { vector> &&messages, Promise> &&promise); - void on_get_message_public_forwards(int32 total_count, vector> &&messages, - int32 next_rate, Promise> &&promise); - - // if message is from_update, flags have_previous and have_next are ignored and must be both true - FullMessageId on_get_message(tl_object_ptr message_ptr, bool from_update, + MessageFullId on_get_message(tl_object_ptr message_ptr, bool from_update, bool is_channel_message, bool is_scheduled, const char *source); void open_secret_message(SecretChatId secret_chat_id, int64 random_id, Promise); @@ -273,31 +251,36 @@ class MessagesManager final : public Actor { void on_update_sent_text_message(int64 random_id, tl_object_ptr message_media, vector> &&entities); - void delete_pending_message_web_page(FullMessageId full_message_id); + void delete_pending_message_web_page(MessageFullId message_full_id); void on_get_dialogs(FolderId folder_id, vector> &&dialog_folders, int32 total_count, vector> &&messages, Promise &&promise); - void on_get_common_dialogs(UserId user_id, int64 offset_chat_id, vector> &&chats, - int32 total_count); - - bool on_update_message_id(int64 random_id, MessageId new_message_id, const string &source); + bool on_update_message_id(int64 random_id, MessageId new_message_id, const char *source); void on_update_dialog_draft_message(DialogId dialog_id, MessageId top_thread_message_id, - tl_object_ptr &&draft_message); + tl_object_ptr &&draft_message, bool force = false); void on_update_dialog_is_pinned(FolderId folder_id, DialogId dialog_id, bool is_pinned); void on_update_pinned_dialogs(FolderId folder_id); + void on_update_dialog_is_forum(DialogId dialog_id, bool is_forum); + + void on_update_dialog_view_as_messages(DialogId dialog_id, bool view_as_messages); + void on_update_dialog_is_marked_as_unread(DialogId dialog_id, bool is_marked_as_unread); void on_update_dialog_is_translatable(DialogId dialog_id, bool is_translatable); void update_is_translatable(bool new_is_premium); - void on_update_dialog_is_blocked(DialogId dialog_id, bool is_blocked); + void on_update_dialog_is_blocked(DialogId dialog_id, bool is_blocked, bool is_blocked_for_stories); + + void on_update_dialog_business_bot_is_paused(DialogId dialog_id, bool is_paused); + + void on_update_dialog_business_bot_removed(DialogId dialog_id); void on_update_dialog_last_pinned_message_id(DialogId dialog_id, MessageId last_pinned_message_id); @@ -341,51 +324,51 @@ class MessagesManager final : public Actor { void on_update_channel_too_long(tl_object_ptr &&update, bool force_apply); - void on_update_message_view_count(FullMessageId full_message_id, int32 view_count); + void on_update_message_view_count(MessageFullId message_full_id, int32 view_count); - void on_update_message_forward_count(FullMessageId full_message_id, int32 forward_count); + void on_update_message_forward_count(MessageFullId message_full_id, int32 forward_count); - void on_update_message_reactions(FullMessageId full_message_id, + void on_update_message_reactions(MessageFullId message_full_id, tl_object_ptr &&reactions, Promise &&promise); - void update_message_reactions(FullMessageId full_message_id, unique_ptr &&reactions); + void update_message_reactions(MessageFullId message_full_id, unique_ptr &&reactions); void try_reload_message_reactions(DialogId dialog_id, bool is_finished); - void on_get_message_reaction_list(FullMessageId full_message_id, const string &reaction, - FlatHashMap> reactions, int32 total_count); + void on_get_message_reaction_list(MessageFullId message_full_id, const ReactionType &reaction_type, + FlatHashMap, ReactionTypeHash> reaction_types, + int32 total_count); - void on_update_message_interaction_info(FullMessageId full_message_id, int32 view_count, int32 forward_count, + void on_update_message_interaction_info(MessageFullId message_full_id, int32 view_count, int32 forward_count, bool has_reply_info, tl_object_ptr &&reply_info); - void on_update_live_location_viewed(FullMessageId full_message_id); + void on_update_live_location_viewed(MessageFullId message_full_id); void on_update_some_live_location_viewed(Promise &&promise); - void on_update_message_extended_media(FullMessageId full_message_id, - telegram_api::object_ptr extended_media); + void on_update_message_extended_media( + MessageFullId message_full_id, + vector> extended_media); - void on_external_update_message_content(FullMessageId full_message_id); + void on_external_update_message_content(MessageFullId message_full_id, const char *source, + bool expect_no_message = false); - void on_update_message_content(FullMessageId full_message_id); + void on_update_message_content(MessageFullId message_full_id); void on_read_channel_inbox(ChannelId channel_id, MessageId max_message_id, int32 server_unread_count, int32 pts, const char *source); void on_read_channel_outbox(ChannelId channel_id, MessageId max_message_id); - void on_update_channel_max_unavailable_message_id(ChannelId channel_id, MessageId max_unavailable_message_id); - - void on_update_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server); + void on_update_channel_max_unavailable_message_id(ChannelId channel_id, MessageId max_unavailable_message_id, + const char *source); void on_update_delete_scheduled_messages(DialogId dialog_id, vector &&server_message_ids); - void on_update_created_public_broadcasts(vector channel_ids); + void on_dialog_speaking_action(DialogId dialog_id, DialogId speaking_dialog_id, int32 date); - void on_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id, - DialogAction action, int32 date, - MessageContentType message_content_type = MessageContentType::None); + void on_message_animated_emoji_clicked(MessageFullId message_full_id, string &&emoji, string &&data); void read_history_inbox(DialogId dialog_id, MessageId max_message_id, int32 unread_count, const char *source); @@ -403,6 +386,8 @@ class MessagesManager final : public Actor { void delete_dialog_messages_by_sender(DialogId dialog_id, DialogId sender_dialog_id, Promise &&promise); + static Status fix_delete_message_min_max_dates(int32 &min_date, int32 &max_date); + void delete_dialog_messages_by_date(DialogId dialog_id, int32 min_date, int32 max_date, bool revoke, Promise &&promise); @@ -420,13 +405,10 @@ class MessagesManager final : public Actor { void clear_recently_found_dialogs(); - std::pair> get_recently_opened_dialogs(int32 limit, Promise &&promise); + std::pair> search_recently_found_dialogs(const string &query, int32 limit, + Promise &&promise); - DialogId resolve_dialog_username(const string &username) const; - - DialogId search_public_dialog(const string &username_to_search, bool force, Promise &&promise); - - void reload_voice_chat_on_search(const string &username); + std::pair> get_recently_opened_dialogs(int32 limit, Promise &&promise); void get_dialog_send_message_as_dialog_ids(DialogId dialog_id, Promise> &&promise, @@ -441,104 +423,82 @@ class MessagesManager final : public Actor { DialogId get_dialog_default_send_message_as_dialog_id(DialogId dialog_id) const; - MessageId get_reply_to_message_id(DialogId dialog_id, MessageId top_thread_message_id, MessageId message_id, - bool for_draft); + struct ForwardedMessageInfo { + int32 origin_date_ = 0; + MessageOrigin origin_; + unique_ptr content_; + }; + ForwardedMessageInfo get_forwarded_message_info(MessageFullId message_full_id); + + MessageInputReplyTo create_message_input_reply_to(DialogId dialog_id, MessageId top_thread_message_id, + td_api::object_ptr &&reply_to, + bool for_draft); Result> send_message( - DialogId dialog_id, MessageId top_thread_message_id, MessageId reply_to_message_id, - tl_object_ptr &&options, tl_object_ptr &&reply_markup, + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr &&reply_to, tl_object_ptr &&options, + tl_object_ptr &&reply_markup, tl_object_ptr &&input_message_content) TD_WARN_UNUSED_RESULT; Result> send_message_group( - DialogId dialog_id, MessageId top_thread_message_id, MessageId reply_to_message_id, - tl_object_ptr &&options, - vector> &&input_message_contents, - bool only_preview) TD_WARN_UNUSED_RESULT; + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr &&reply_to, tl_object_ptr &&options, + vector> &&input_message_contents) TD_WARN_UNUSED_RESULT; Result send_bot_start_message(UserId bot_user_id, DialogId dialog_id, const string ¶meter) TD_WARN_UNUSED_RESULT; - Result send_inline_query_result_message(DialogId dialog_id, MessageId top_thread_message_id, - MessageId reply_to_message_id, - tl_object_ptr &&options, - int64 query_id, const string &result_id, - bool hide_via_bot) TD_WARN_UNUSED_RESULT; - - Result> forward_messages(DialogId to_dialog_id, MessageId top_thread_message_id, - DialogId from_dialog_id, vector message_ids, - tl_object_ptr &&options, - bool in_game_share, - vector &©_options, - bool only_preview) TD_WARN_UNUSED_RESULT; + Result> send_inline_query_result_message( + DialogId dialog_id, const MessageId top_thread_message_id, + td_api::object_ptr &&reply_to, tl_object_ptr &&options, + int64 query_id, const string &result_id, bool hide_via_bot) TD_WARN_UNUSED_RESULT; - Result> resend_messages(DialogId dialog_id, vector message_ids) TD_WARN_UNUSED_RESULT; + Result> forward_messages( + DialogId to_dialog_id, MessageId top_thread_message_id, DialogId from_dialog_id, vector message_ids, + tl_object_ptr &&options, bool in_game_share, + vector &©_options) TD_WARN_UNUSED_RESULT; - void set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Promise &&promise); + Result> send_quick_reply_shortcut_messages( + DialogId dialog_id, QuickReplyShortcutId shortcut_id, int32 sending_id) TD_WARN_UNUSED_RESULT; - Status send_screenshot_taken_notification_message(DialogId dialog_id); + Result> resend_messages(DialogId dialog_id, vector message_ids, + td_api::object_ptr &"e) TD_WARN_UNUSED_RESULT; - void share_dialog_with_bot(FullMessageId full_message_id, int32 button_id, DialogId shared_dialog_id, - bool expect_user, bool only_check, Promise &&promise); - - Result add_local_message(DialogId dialog_id, td_api::object_ptr &&sender, - MessageId reply_to_message_id, bool disable_notification, - tl_object_ptr &&input_message_content) - TD_WARN_UNUSED_RESULT; - - void get_message_file_type(const string &message_file_head, - Promise> &&promise); - - void get_message_import_confirmation_text(DialogId dialog_id, Promise &&promise); + void set_dialog_message_ttl(DialogId dialog_id, int32 ttl, Promise &&promise); - void import_messages(DialogId dialog_id, const td_api::object_ptr &message_file, - const vector> &attached_files, Promise &&promise); + void share_dialogs_with_bot(MessageFullId message_full_id, int32 button_id, vector shared_dialog_ids, + bool expect_user, bool only_check, Promise &&promise); - void start_import_messages(DialogId dialog_id, int64 import_id, vector &&attached_file_ids, - Promise &&promise); + Result add_local_message( + DialogId dialog_id, td_api::object_ptr &&sender, + td_api::object_ptr &&reply_to, bool disable_notification, + tl_object_ptr &&input_message_content) TD_WARN_UNUSED_RESULT; - void edit_message_text(FullMessageId full_message_id, tl_object_ptr &&reply_markup, + void edit_message_text(MessageFullId message_full_id, tl_object_ptr &&reply_markup, tl_object_ptr &&input_message_content, Promise &&promise); - void edit_message_live_location(FullMessageId full_message_id, tl_object_ptr &&reply_markup, - tl_object_ptr &&input_location, int32 heading, + void edit_message_live_location(MessageFullId message_full_id, tl_object_ptr &&reply_markup, + tl_object_ptr &&input_location, int32 live_period, int32 heading, int32 proximity_alert_radius, Promise &&promise); - void edit_message_media(FullMessageId full_message_id, tl_object_ptr &&reply_markup, + void edit_message_media(MessageFullId message_full_id, tl_object_ptr &&reply_markup, tl_object_ptr &&input_message_content, Promise &&promise); - void edit_message_caption(FullMessageId full_message_id, tl_object_ptr &&reply_markup, - tl_object_ptr &&input_caption, Promise &&promise); - - void edit_message_reply_markup(FullMessageId full_message_id, tl_object_ptr &&reply_markup, - Promise &&promise); - - void edit_inline_message_text(const string &inline_message_id, tl_object_ptr &&reply_markup, - tl_object_ptr &&input_message_content, - Promise &&promise); - - void edit_inline_message_live_location(const string &inline_message_id, - tl_object_ptr &&reply_markup, - tl_object_ptr &&input_location, int32 heading, - int32 proximity_alert_radius, Promise &&promise); + void edit_message_caption(MessageFullId message_full_id, tl_object_ptr &&reply_markup, + tl_object_ptr &&input_caption, bool invert_media, + Promise &&promise); - void edit_inline_message_media(const string &inline_message_id, tl_object_ptr &&reply_markup, - tl_object_ptr &&input_message_content, + void edit_message_reply_markup(MessageFullId message_full_id, tl_object_ptr &&reply_markup, Promise &&promise); - void edit_inline_message_caption(const string &inline_message_id, tl_object_ptr &&reply_markup, - tl_object_ptr &&input_caption, Promise &&promise); - - void edit_inline_message_reply_markup(const string &inline_message_id, - tl_object_ptr &&reply_markup, Promise &&promise); - - void edit_message_scheduling_state(FullMessageId full_message_id, + void edit_message_scheduling_state(MessageFullId message_full_id, td_api::object_ptr &&scheduling_state, Promise &&promise); - void send_dialog_action(DialogId dialog_id, MessageId top_thread_message_id, DialogAction action, - Promise &&promise); + void set_message_fact_check(MessageFullId message_full_id, td_api::object_ptr &&text, + Promise &&promise); - void after_set_typing_query(DialogId dialog_id, int32 generation); + void get_dialog_filter_dialog_count(td_api::object_ptr filter, Promise &&promise); void add_dialog_list_for_dialog_filter(DialogFilterId dialog_filter_id); @@ -552,44 +512,23 @@ class MessagesManager final : public Actor { void add_dialog_to_list(DialogId dialog_id, DialogListId dialog_list_id, Promise &&promise); - void set_dialog_photo(DialogId dialog_id, const tl_object_ptr &input_photo, - Promise &&promise); - - void set_dialog_title(DialogId dialog_id, const string &title, Promise &&promise); - - void set_dialog_description(DialogId dialog_id, const string &description, Promise &&promise); - - void set_active_reactions(vector active_reactions); + void set_active_reactions(vector active_reaction_types); void set_dialog_available_reactions(DialogId dialog_id, td_api::object_ptr &&available_reactions_ptr, Promise &&promise); - void set_dialog_permissions(DialogId dialog_id, const td_api::object_ptr &permissions, - Promise &&promise); - - void toggle_dialog_has_protected_content(DialogId dialog_id, bool has_protected_content, Promise &&promise); - void set_dialog_theme(DialogId dialog_id, const string &theme_name, Promise &&promise); - void pin_dialog_message(DialogId dialog_id, MessageId message_id, bool disable_notification, bool only_for_self, - bool is_unpin, Promise &&promise); + void pin_dialog_message(BusinessConnectionId business_connection_id, DialogId dialog_id, MessageId message_id, + bool disable_notification, bool only_for_self, bool is_unpin, Promise &&promise); void unpin_all_dialog_messages(DialogId dialog_id, MessageId top_thread_message_id, Promise &&promise); - void get_dialog_info_full(DialogId dialog_id, Promise &&promise, const char *source); - - string get_dialog_title(DialogId dialog_id) const; - bool have_dialog(DialogId dialog_id) const; bool have_dialog_force(DialogId dialog_id, const char *source); - bool have_dialog_info(DialogId dialog_id) const; - bool have_dialog_info_force(DialogId dialog_id) const; - - void reload_dialog_info_full(DialogId dialog_id, const char *source); - - void on_dialog_info_full_invalidated(DialogId dialog_id); + void reload_dialog_notification_settings(DialogId dialog_id, Promise &&promise, const char *source); bool load_dialog(DialogId dialog_id, int left_tries, Promise &&promise); @@ -611,31 +550,31 @@ class MessagesManager final : public Actor { vector search_dialogs_on_server(const string &query, int32 limit, Promise &&promise); - void drop_common_dialogs_cache(UserId user_id); - - std::pair> get_common_dialogs(UserId user_id, DialogId offset_dialog_id, int32 limit, - bool force, Promise &&promise); - void block_message_sender_from_replies(MessageId message_id, bool need_delete_message, bool need_delete_all_messages, bool report_spam, Promise &&promise); bool is_dialog_blocked(DialogId dialog_id) const; - void get_blocked_dialogs(int32 offset, int32 limit, Promise> &&promise); + void get_blocked_dialogs(const td_api::object_ptr &block_list, int32 offset, int32 limit, + Promise> &&promise); void on_get_blocked_dialogs(int32 offset, int32 limit, int32 total_count, vector> &&blocked_peers, Promise> &&promise); - bool can_get_message_statistics(FullMessageId full_message_id); + static Status can_report_message(MessageId message_id); + + bool can_share_message_in_story(MessageFullId message_full_id); + + bool can_get_message_statistics(MessageFullId message_full_id); - DialogId get_dialog_message_sender(FullMessageId full_message_id); + DialogId get_dialog_message_sender(MessageFullId message_full_id); - bool have_message_force(FullMessageId full_message_id, const char *source); + bool have_message_force(MessageFullId message_full_id, const char *source); - void get_message(FullMessageId full_message_id, Promise &&promise); + void get_message(MessageFullId message_full_id, Promise &&promise); - FullMessageId get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise &&promise); + MessageFullId get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise &&promise); MessageId get_dialog_pinned_message(DialogId dialog_id, Promise &&promise); @@ -644,12 +583,15 @@ class MessagesManager final : public Actor { bool get_messages(DialogId dialog_id, const vector &message_ids, Promise &&promise); - void get_message_from_server(FullMessageId full_message_id, Promise &&promise, const char *source, + void get_message_from_server(MessageFullId message_full_id, Promise &&promise, const char *source, tl_object_ptr input_message = nullptr); - void get_messages_from_server(vector &&message_ids, Promise &&promise, const char *source, + void get_messages_from_server(vector &&message_ids, Promise &&promise, const char *source, tl_object_ptr input_message = nullptr); + void get_message_properties(DialogId dialog_id, MessageId message_id, + Promise> &&promise); + void get_message_thread(DialogId dialog_id, MessageId message_id, Promise &&promise); td_api::object_ptr get_message_thread_info_object(const MessageThreadInfo &info); @@ -658,33 +600,36 @@ class MessagesManager final : public Actor { DialogId dialog_id, MessageId message_id, DialogId expected_dialog_id, MessageId expected_message_id, Promise promise); - void get_message_viewers(FullMessageId full_message_id, + void get_message_read_date(MessageFullId message_full_id, + Promise> &&promise); + + void get_message_viewers(MessageFullId message_full_id, Promise> &&promise); - void translate_message_text(FullMessageId full_message_id, const string &to_language_code, + void translate_message_text(MessageFullId message_full_id, const string &to_language_code, Promise> &&promise); - void recognize_speech(FullMessageId full_message_id, Promise &&promise); + bool is_message_edited_recently(MessageFullId message_full_id, int32 seconds); - void rate_speech_recognition(FullMessageId full_message_id, bool is_good, Promise &&promise); - - bool is_message_edited_recently(FullMessageId full_message_id, int32 seconds); + struct ReportDialogFromActionBar { + bool know_action_bar_ = false; + bool is_reported_ = false; + }; + ReportDialogFromActionBar report_dialog_from_action_bar(DialogId dialog_id, Promise &promise); bool is_deleted_secret_chat(DialogId dialog_id) const; - Result> get_message_link(FullMessageId full_message_id, int32 media_timestamp, bool for_group, + Result> get_message_link(MessageFullId message_full_id, int32 media_timestamp, bool for_group, bool in_message_thread); - string get_message_embedding_code(FullMessageId full_message_id, bool for_group, Promise &&promise); + string get_message_embedding_code(MessageFullId message_full_id, bool for_group, Promise &&promise); - void on_get_public_message_link(FullMessageId full_message_id, bool for_group, string url, string html); + void on_get_public_message_link(MessageFullId message_full_id, bool for_group, string url, string html); void get_message_link_info(Slice url, Promise &&promise); td_api::object_ptr get_message_link_info_object(const MessageLinkInfo &info) const; - InputDialogId get_input_dialog_id(DialogId dialog_id) const; - bool is_dialog_in_dialog_list(DialogId dialog_id) const; Status can_add_dialog_to_filter(DialogId dialog_id); @@ -698,12 +643,14 @@ class MessagesManager final : public Actor { Status toggle_dialog_is_pinned(DialogListId dialog_list_id, DialogId dialog_id, bool is_pinned) TD_WARN_UNUSED_RESULT; + Status toggle_dialog_view_as_messages(DialogId dialog_id, bool view_as_messages) TD_WARN_UNUSED_RESULT; + Status toggle_dialog_is_marked_as_unread(DialogId dialog_id, bool is_marked_as_unread) TD_WARN_UNUSED_RESULT; Status toggle_dialog_is_translatable(DialogId dialog_id, bool is_translatable) TD_WARN_UNUSED_RESULT; - Status toggle_message_sender_is_blocked(const td_api::object_ptr &sender, - bool is_blocked) TD_WARN_UNUSED_RESULT; + Status set_message_sender_block_list(const td_api::object_ptr &sender, + const td_api::object_ptr &block_list) TD_WARN_UNUSED_RESULT; Status toggle_dialog_silent_send_message(DialogId dialog_id, bool silent_send_message) TD_WARN_UNUSED_RESULT; @@ -713,17 +660,6 @@ class MessagesManager final : public Actor { void create_dialog(DialogId dialog_id, bool force, Promise &&promise); - DialogId create_new_group_chat(const vector &user_ids, const string &title, MessageTtl message_ttl, - int64 &random_id, Promise &&promise); - - DialogId create_new_channel_chat(const string &title, bool is_forum, bool is_megagroup, const string &description, - const DialogLocation &location, bool for_import, MessageTtl message_ttl, - int64 &random_id, Promise &&promise); - - void create_new_secret_chat(UserId user_id, Promise &&promise); - - DialogId migrate_dialog_to_megagroup(DialogId dialog_id, Promise &&promise); - bool is_dialog_opened(DialogId dialog_id) const; Status open_dialog(DialogId dialog_id) TD_WARN_UNUSED_RESULT; @@ -737,11 +673,13 @@ class MessagesManager final : public Actor { void finish_get_message_extended_media(DialogId dialog_id, const vector &message_ids); - Status open_message_content(FullMessageId full_message_id) TD_WARN_UNUSED_RESULT; + Status open_message_content(MessageFullId message_full_id) TD_WARN_UNUSED_RESULT; - void click_animated_emoji_message(FullMessageId full_message_id, + void click_animated_emoji_message(MessageFullId message_full_id, Promise> &&promise); + StoryNotificationSettings get_story_notification_settings(DialogId dialog_id); + vector get_dialog_notification_settings_exceptions(NotificationSettingsScope scope, bool filter_scope, bool compare_sound, bool force, Promise &&promise); @@ -751,17 +689,13 @@ class MessagesManager final : public Actor { void reset_all_notification_settings(); - int64 get_chat_id_object(DialogId dialog_id, const char *source) const; - - vector get_chat_ids_object(const vector &dialog_ids, const char *source) const; + void update_story_max_reply_media_timestamp_in_replied_messages(StoryFullId story_full_id); - td_api::object_ptr get_chat_object(DialogId dialog_id); + int64 get_chat_id_object(DialogId dialog_id, const char *source) const; - tl_object_ptr get_chats_object(int32 total_count, const vector &dialog_ids, - const char *source) const; + td_api::object_ptr get_chat_object(DialogId dialog_id, const char *source); - tl_object_ptr get_chats_object(const std::pair> &dialog_ids, - const char *source) const; + td_api::object_ptr get_my_dialog_draft_message_object() const; tl_object_ptr get_dialog_history(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, int left_tries, bool only_local, @@ -772,9 +706,9 @@ class MessagesManager final : public Actor { int32 limit, int64 &random_id, Promise &&promise); - td_api::object_ptr get_dialog_message_calendar(DialogId dialog_id, MessageId from_message_id, - MessageSearchFilter filter, int64 &random_id, - bool use_db, Promise &&promise); + void get_dialog_message_calendar(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, + Promise> &&promise); struct FoundDialogMessages { vector message_ids; @@ -789,10 +723,11 @@ class MessagesManager final : public Actor { const td_api::object_ptr &sender, MessageId from_message_id, int32 offset, int32 limit, MessageSearchFilter filter, MessageId top_thread_message_id, + SavedMessagesTopicId saved_messages_topic_id, const ReactionType &tag, int64 &random_id, bool use_db, Promise &&promise); struct FoundMessages { - vector full_message_ids; + vector message_full_ids; string next_offset; int32 total_count = 0; }; @@ -800,74 +735,93 @@ class MessagesManager final : public Actor { td_api::object_ptr get_found_messages_object(const FoundMessages &found_messages, const char *source); - FoundMessages offline_search_messages(DialogId dialog_id, const string &query, string offset, int32 limit, - MessageSearchFilter filter, int64 &random_id, Promise &&promise); + void offline_search_messages(DialogId dialog_id, const string &query, string offset, int32 limit, + MessageSearchFilter filter, + Promise> &&promise); - FoundMessages search_messages(FolderId folder_id, bool ignore_folder_id, const string &query, const string &offset, - int32 limit, MessageSearchFilter filter, int32 min_date, int32 max_date, - int64 &random_id, Promise &&promise); + void search_messages(DialogListId dialog_list_id, bool ignore_folder_id, bool broadcasts_only, const string &query, + const string &offset_str, int32 limit, MessageSearchFilter filter, int32 min_date, + int32 max_date, Promise> &&promise); - FoundMessages search_call_messages(const string &offset, int32 limit, bool only_missed, int64 &random_id, bool use_db, - Promise &&promise); + void search_call_messages(const string &offset, int32 limit, bool only_missed, + Promise> &&promise); void search_outgoing_document_messages(const string &query, int32 limit, Promise> &&promise); + void search_hashtag_posts(string hashtag, string offset_str, int32 limit, + Promise> &&promise); + void search_dialog_recent_location_messages(DialogId dialog_id, int32 limit, Promise> &&promise); - vector get_active_live_location_messages(Promise &&promise); - - int64 get_dialog_message_by_date(DialogId dialog_id, int32 date, Promise &&promise); + void load_active_live_location_messages(Promise &&promise); - void on_get_dialog_message_by_date_success(DialogId dialog_id, int32 date, int64 random_id, - vector> &&messages, - Promise &&promise); + void get_dialog_message_by_date(DialogId dialog_id, int32 date, + Promise> &&promise); - void on_get_dialog_message_by_date_fail(int64 random_id); + void on_get_dialog_message_by_date(DialogId dialog_id, int32 date, + vector> &&messages, + Promise> &&promise); - void get_dialog_sparse_message_positions(DialogId dialog_id, MessageSearchFilter filter, MessageId from_message_id, - int32 limit, + void get_dialog_sparse_message_positions(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, MessageId from_message_id, int32 limit, Promise> &&promise); - void on_get_dialog_sparse_message_positions( - DialogId dialog_id, MessageSearchFilter filter, + static void on_get_dialog_sparse_message_positions( + DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, MessageSearchFilter filter, telegram_api::object_ptr positions, Promise> &&promise); - void get_dialog_message_count(DialogId dialog_id, MessageSearchFilter filter, bool return_local, - Promise &&promise); + void get_dialog_message_count(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, bool return_local, Promise &&promise); - void get_dialog_message_position(FullMessageId full_message_id, MessageSearchFilter filter, - MessageId top_thread_message_id, Promise &&promise); + void get_dialog_message_position(MessageFullId message_full_id, MessageSearchFilter filter, + MessageId top_thread_message_id, SavedMessagesTopicId saved_messages_topic_id, + Promise &&promise); vector get_dialog_scheduled_messages(DialogId dialog_id, bool force, bool ignore_result, Promise &&promise); - Result> get_message_available_reactions(FullMessageId full_message_id, + using AffectedHistoryQuery = std::function)>; + + void run_affected_history_query_until_complete(DialogId dialog_id, AffectedHistoryQuery query, + bool get_affected_messages, Promise &&promise); + + Result> get_message_available_reactions(MessageFullId message_full_id, int32 row_size); - void add_message_reaction(FullMessageId full_message_id, string reaction, bool is_big, bool add_to_recent, + void add_message_reaction(MessageFullId message_full_id, ReactionType reaction_type, bool is_big, bool add_to_recent, Promise &&promise); - void remove_message_reaction(FullMessageId full_message_id, string reaction, Promise &&promise); + void remove_message_reaction(MessageFullId message_full_id, ReactionType reaction_type, Promise &&promise); + + void add_paid_message_reaction(MessageFullId message_full_id, int64 star_count, bool use_default_is_anonymous, + bool is_anonymous, Promise &&promise); - void get_message_public_forwards(FullMessageId full_message_id, string offset, int32 limit, - Promise> &&promise); + void commit_paid_message_reactions(MessageFullId message_full_id, Promise &&promise); - tl_object_ptr get_dialog_message_by_date_object(int64 random_id); + void remove_paid_message_reactions(MessageFullId message_full_id, Promise &&promise); + + void toggle_paid_message_reaction_is_anonymous(MessageFullId message_full_id, bool is_anonymous, + Promise &&promise); td_api::object_ptr get_dialog_event_log_message_object( DialogId dialog_id, tl_object_ptr &&message, DialogId &sender_dialog_id); - tl_object_ptr get_message_object(FullMessageId full_message_id, const char *source); + td_api::object_ptr get_business_message_object( + telegram_api::object_ptr &&message, + telegram_api::object_ptr &&reply_to_message); + + td_api::object_ptr get_message_object(MessageFullId message_full_id, const char *source); - tl_object_ptr get_messages_object(int32 total_count, DialogId dialog_id, - const vector &message_ids, bool skip_not_found, - const char *source); + td_api::object_ptr get_messages_object(int32 total_count, DialogId dialog_id, + const vector &message_ids, bool skip_not_found, + const char *source); - tl_object_ptr get_messages_object(int32 total_count, const vector &full_message_ids, - bool skip_not_found, const char *source); + td_api::object_ptr get_messages_object(int32 total_count, + const vector &message_full_ids, + bool skip_not_found, const char *source); void process_pts_update(tl_object_ptr &&update_ptr); @@ -883,7 +837,9 @@ class MessagesManager final : public Actor { void on_dialog_bots_updated(DialogId dialog_id, vector bot_user_ids, bool from_database); void on_dialog_photo_updated(DialogId dialog_id); + void on_dialog_accent_colors_updated(DialogId dialog_id); void on_dialog_title_updated(DialogId dialog_id); + void on_dialog_emoji_status_updated(DialogId dialog_id); void on_dialog_usernames_updated(DialogId dialog_id, const Usernames &old_usernames, const Usernames &new_usernames); void on_dialog_default_permissions_updated(DialogId dialog_id); void on_dialog_has_protected_content_updated(DialogId dialog_id); @@ -896,17 +852,15 @@ class MessagesManager final : public Actor { void drop_dialog_pending_join_requests(DialogId dialog_id); - void on_resolved_username(const string &username, DialogId dialog_id); - void drop_username(const string &username); - void on_update_notification_scope_is_muted(NotificationSettingsScope scope, bool is_muted); void on_update_dialog_notify_settings(DialogId dialog_id, tl_object_ptr &&peer_notify_settings, const char *source); - void on_update_dialog_available_reactions( - DialogId dialog_id, telegram_api::object_ptr &&available_reactions); + void on_update_dialog_available_reactions(DialogId dialog_id, + telegram_api::object_ptr &&available_reactions, + int32 reactions_limit, bool paid_reactions_available); void hide_dialog_action_bar(DialogId dialog_id); @@ -914,10 +868,7 @@ class MessagesManager final : public Actor { void reget_dialog_action_bar(DialogId dialog_id, const char *source, bool is_repair = true); - void report_dialog(DialogId dialog_id, const vector &message_ids, ReportReason &&reason, - Promise &&promise); - - void report_dialog_photo(DialogId dialog_id, FileId file_id, ReportReason &&reason, Promise &&promise); + void hide_all_business_bot_manager_bars(); void on_get_peer_settings(DialogId dialog_id, tl_object_ptr &&peer_settings, bool ignore_privacy_exception = false); @@ -928,38 +879,40 @@ class MessagesManager final : public Actor { void after_get_difference(); - bool on_get_dialog_error(DialogId dialog_id, const Status &status, const char *source); + bool on_get_message_error(DialogId dialog_id, MessageId message_id, const Status &status, const char *source); void on_send_message_get_quick_ack(int64 random_id); void check_send_message_result(int64 random_id, DialogId dialog_id, const telegram_api::Updates *updates_ptr, const char *source); - FullMessageId on_send_message_success(int64 random_id, MessageId new_message_id, int32 date, int32 ttl_period, + MessageFullId on_send_message_success(int64 random_id, MessageId new_message_id, int32 date, int32 ttl_period, FileId new_file_id, const char *source); - void on_send_message_file_part_missing(int64 random_id, int bad_part); + void on_send_message_file_parts_missing(int64 random_id, vector &&bad_parts); - void on_send_message_file_reference_error(int64 random_id); + void on_send_message_file_reference_error(int64 random_id, size_t pos); void on_send_media_group_file_reference_error(DialogId dialog_id, vector random_ids); void on_send_message_fail(int64 random_id, Status error); - void on_upload_message_media_success(DialogId dialog_id, MessageId message_id, - tl_object_ptr &&media); + void on_upload_message_media_success(DialogId dialog_id, MessageId message_id, int32 media_pos, + telegram_api::object_ptr &&media); - void on_upload_message_media_file_part_missing(DialogId dialog_id, MessageId message_id, int bad_part); + void on_upload_message_media_file_parts_missing(DialogId dialog_id, MessageId message_id, int32 media_pos, + vector &&bad_parts); - void on_upload_message_media_fail(DialogId dialog_id, MessageId message_id, Status error); + void on_upload_message_media_fail(DialogId dialog_id, MessageId message_id, int32 media_pos, Status error); - void on_create_new_dialog_success(int64 random_id, tl_object_ptr &&updates, - DialogType expected_type, Promise &&promise); - - void on_create_new_dialog_fail(int64 random_id, Status error, Promise &&promise); + void on_create_new_dialog(telegram_api::object_ptr &&updates, + MissingInvitees &&missing_invitees, + Promise> &&chat_promise, + Promise> &&channel_promise); void on_get_channel_difference(DialogId dialog_id, int32 request_pts, int32 request_limit, - tl_object_ptr &&difference_ptr); + tl_object_ptr &&difference_ptr, + Status &&status); void try_update_dialog_pos(DialogId dialog_id); @@ -974,7 +927,7 @@ class MessagesManager final : public Actor { vector> users, vector> chats); - FileSourceId get_message_file_source_id(FullMessageId full_message_id, bool force = false); + FileSourceId get_message_file_source_id(MessageFullId message_full_id, bool force = false); struct MessagePushNotificationInfo { NotificationGroupId group_id; @@ -987,13 +940,7 @@ class MessagesManager final : public Actor { bool is_from_scheduled, bool contains_mention, bool is_pinned, bool is_from_binlog); - struct MessageNotificationGroup { - DialogId dialog_id; - NotificationGroupType type = NotificationGroupType::Calls; - int32 total_count = 0; - vector notifications; - }; - MessageNotificationGroup get_message_notification_group_force(NotificationGroupId group_id); + NotificationGroupFromDatabase get_message_notification_group_force(NotificationGroupId group_id); vector get_message_notification_group_keys_from_database(NotificationGroupKey from_group_key, int32 limit); @@ -1013,33 +960,36 @@ class MessagesManager final : public Actor { void on_update_scope_mention_notifications(NotificationSettingsScope scope, bool disable_mention_notifications); - void upload_dialog_photo(DialogId dialog_id, FileId file_id, bool is_animation, double main_frame_timestamp, - bool is_reupload, Promise &&promise, vector bad_parts = {}); - void on_binlog_events(vector &&events); - void set_poll_answer(FullMessageId full_message_id, vector &&option_ids, Promise &&promise); + void set_poll_answer(MessageFullId message_full_id, vector &&option_ids, Promise &&promise); - void get_poll_voters(FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit, - Promise>> &&promise); + void get_poll_voters(MessageFullId message_full_id, int32 option_id, int32 offset, int32 limit, + Promise> &&promise); - void stop_poll(FullMessageId full_message_id, td_api::object_ptr &&reply_markup, + void stop_poll(MessageFullId message_full_id, td_api::object_ptr &&reply_markup, Promise &&promise); - Result get_login_button_url(FullMessageId full_message_id, int64 button_id); + Result get_login_button_url(MessageFullId message_full_id, int64 button_id); + + struct InvoiceMessageInfo { + ServerMessageId server_message_id_; + int64 star_count_ = 0; + }; + Result get_invoice_message_info(MessageFullId message_full_id); - Result get_invoice_message_id(FullMessageId full_message_id); + Result get_payment_successful_message_id(MessageFullId message_full_id); - Result get_payment_successful_message_id(FullMessageId full_message_id); + Result get_giveaway_message_id(MessageFullId message_full_id); - bool can_set_game_score(FullMessageId full_message_id) const; + bool can_set_game_score(MessageFullId message_full_id) const; void get_current_state(vector> &updates) const; - void add_message_file_to_downloads(FullMessageId full_message_id, FileId file_id, int32 priority, + void add_message_file_to_downloads(MessageFullId message_full_id, FileId file_id, int32 priority, Promise> promise); - void get_message_file_search_text(FullMessageId full_message_id, string unique_file_id, Promise promise); + void get_message_file_search_text(MessageFullId message_full_id, string unique_file_id, Promise promise); private: class PendingPtsUpdate { @@ -1059,114 +1009,75 @@ class MessagesManager final : public Actor { MessageId message_id; UserId sender_user_id; DialogId sender_dialog_id; + SavedMessagesTopicId saved_messages_topic_id; int32 date = 0; int32 ttl_period = 0; - int32 ttl = 0; + MessageSelfDestructType ttl; bool disable_web_page_preview = false; int64 random_id = 0; tl_object_ptr forward_header; MessageReplyHeader reply_header; UserId via_bot_user_id; + UserId via_business_bot_user_id; int32 view_count = 0; int32 forward_count = 0; tl_object_ptr reply_info; tl_object_ptr reactions; - int32 flags = 0; + tl_object_ptr fact_check; + int32 sender_boost_count = 0; int32 edit_date = 0; vector restriction_reasons; string author_signature; int64 media_album_id = 0; + MessageEffectId effect_id; + bool is_outgoing = false; + bool is_silent = false; + bool is_channel_post = false; + bool is_legacy = false; + bool hide_edit_date = false; + bool is_from_scheduled = false; + bool is_from_offline = false; + bool is_pinned = false; + bool noforwards = false; + bool has_mention = false; + bool has_unread_content = false; + bool invert_media = false; unique_ptr content; tl_object_ptr reply_markup; }; - struct MessageForwardInfo { - UserId sender_user_id; - int32 date = 0; - DialogId sender_dialog_id; - MessageId message_id; - string author_signature; - string sender_name; - DialogId from_dialog_id; - MessageId from_message_id; - string psa_type; - bool is_imported = false; - - MessageForwardInfo() = default; - - MessageForwardInfo(UserId sender_user_id, int32 date, DialogId sender_dialog_id, MessageId message_id, - string author_signature, string sender_name, DialogId from_dialog_id, MessageId from_message_id, - string psa_type, bool is_imported) - : sender_user_id(sender_user_id) - , date(date) - , sender_dialog_id(sender_dialog_id) - , message_id(message_id) - , author_signature(std::move(author_signature)) - , sender_name(std::move(sender_name)) - , from_dialog_id(from_dialog_id) - , from_message_id(from_message_id) - , psa_type(std::move(psa_type)) - , is_imported(is_imported) { - } - - bool operator==(const MessageForwardInfo &rhs) const { - return sender_user_id == rhs.sender_user_id && date == rhs.date && sender_dialog_id == rhs.sender_dialog_id && - message_id == rhs.message_id && author_signature == rhs.author_signature && - sender_name == rhs.sender_name && from_dialog_id == rhs.from_dialog_id && - from_message_id == rhs.from_message_id && psa_type == rhs.psa_type && is_imported == rhs.is_imported; - } - - bool operator!=(const MessageForwardInfo &rhs) const { - return !(*this == rhs); - } - - friend StringBuilder &operator<<(StringBuilder &string_builder, const MessageForwardInfo &forward_info) { - string_builder << "MessageForwardInfo[" << (forward_info.is_imported ? "imported " : "") << "sender " - << forward_info.sender_user_id; - if (!forward_info.author_signature.empty() || !forward_info.sender_name.empty()) { - string_builder << '(' << forward_info.author_signature << '/' << forward_info.sender_name << ')'; - } - if (!forward_info.psa_type.empty()) { - string_builder << ", psa_type " << forward_info.psa_type; - } - if (forward_info.sender_dialog_id.is_valid()) { - string_builder << ", source "; - if (forward_info.message_id.is_valid()) { - string_builder << FullMessageId(forward_info.sender_dialog_id, forward_info.message_id); - } else { - string_builder << forward_info.sender_dialog_id; - } - } - if (forward_info.from_dialog_id.is_valid() || forward_info.from_message_id.is_valid()) { - string_builder << ", from " << FullMessageId(forward_info.from_dialog_id, forward_info.from_message_id); - } - return string_builder << " at " << forward_info.date << ']'; - } - }; - // Do not forget to update MessagesManager::update_message and all make_unique when this class is changed struct Message final : public ListNode { MessageId message_id; UserId sender_user_id; DialogId sender_dialog_id; + SavedMessagesTopicId saved_messages_topic_id; int32 date = 0; int32 edit_date = 0; int32 send_date = 0; - int32 sending_id = 0; + int32 sending_id = 0; // for yet unsent messages + int32 sender_boost_count = 0; int64 random_id = 0; unique_ptr forward_info; - MessageId reply_to_message_id; - int64 reply_to_random_id = 0; // for send_message - DialogId reply_in_dialog_id; + RepliedMessageInfo replied_message_info; + StoryFullId reply_to_story_full_id; + MessageId top_thread_message_id; MessageId linked_top_thread_message_id; vector local_thread_message_ids; + DialogId initial_sender_dialog_id; // for send_message + MessageId initial_top_thread_message_id; // for send_message + MessageInputReplyTo input_reply_to; // for send_message + int64 reply_to_random_id = 0; // for send_message + string send_emoji; // for send_message + UserId via_bot_user_id; + UserId via_business_bot_user_id; vector restriction_reasons; @@ -1185,15 +1096,17 @@ class MessagesManager final : public Actor { bool is_content_secret = false; // must be shown only while tapped bool is_mention_notification_disabled = false; bool is_from_scheduled = false; + bool is_from_offline = false; bool is_pinned = false; bool are_media_timestamp_entities_found = false; bool noforwards = false; + bool invert_media = false; + bool disable_web_page_preview = false; bool has_explicit_sender = false; // for send_message bool is_copy = false; // for send_message bool from_background = false; // for send_message bool update_stickersets_order = false; // for send_message - bool disable_web_page_preview = false; // for send_message bool clear_draft = false; // for send_message bool in_game_share = false; // for send_message bool hide_via_bot = false; // for resend_message @@ -1207,8 +1120,6 @@ class MessagesManager final : public Actor { DialogId real_forward_from_dialog_id; // for resend_message MessageId real_forward_from_message_id; // for resend_message - string send_emoji; // for send_message - NotificationId notification_id; NotificationId removed_notification_id; @@ -1219,6 +1130,7 @@ class MessagesManager final : public Actor { int32 forward_count = 0; MessageReplyInfo reply_info; unique_ptr reactions; + unique_ptr fact_check; unique_ptr thread_draft_message; uint32 available_reactions_generation = 0; int32 interaction_info_update_date = 0; @@ -1230,17 +1142,19 @@ class MessagesManager final : public Actor { string send_error_message; double try_resend_at = 0; - int32 ttl_period = 0; // counted from message send date - int32 ttl = 0; // counted from message content view date - double ttl_expires_at = 0; // only for TTL + int32 ttl_period = 0; // counted from message send date + MessageSelfDestructType ttl; // counted from message content view date + double ttl_expires_at = 0; // only for TTL int64 media_album_id = 0; + MessageEffectId effect_id; unique_ptr content; unique_ptr reply_markup; int32 edited_schedule_date = 0; + bool edited_invert_media = false; unique_ptr edited_content; unique_ptr edited_reply_markup; uint64 edit_generation = 0; @@ -1271,22 +1185,6 @@ class MessagesManager final : public Actor { ~Message() = default; }; - struct NotificationGroupInfo { - NotificationGroupId group_id; - int32 last_notification_date = 0; // date of last notification in the group - NotificationId last_notification_id; // identifier of last notification in the group - NotificationId max_removed_notification_id; // notification identifier, up to which all notifications are removed - MessageId max_removed_message_id; // message identifier, up to which all notifications are removed - bool is_changed = false; // true, if the group needs to be saved to database - bool try_reuse = false; // true, if the group needs to be deleted from database and tried to be reused - - template - void store(StorerT &storer) const; - - template - void parse(ParserT &parser); - }; - struct DialogScheduledMessages { FlatHashMap scheduled_message_date_; @@ -1302,7 +1200,7 @@ class MessagesManager final : public Actor { NotificationGroupInfo mention_notification_group_; NotificationId new_secret_chat_notification_id_; // secret chats only MessageId pinned_message_notification_message_id_; - MessageId max_notification_message_id_; + MessageId max_push_notification_message_id_; vector> pending_new_message_notifications_; vector> pending_new_mention_notifications_; @@ -1341,6 +1239,7 @@ class MessagesManager final : public Actor { MessageTtl message_ttl; unique_ptr draft_message; unique_ptr action_bar; + unique_ptr business_bot_manage_bar; LogEventIdWithGeneration save_draft_message_log_event_id; LogEventIdWithGeneration save_notification_settings_log_event_id; LogEventIdWithGeneration set_folder_id_log_event_id; @@ -1368,13 +1267,12 @@ class MessagesManager final : public Actor { MessageId max_unavailable_message_id; // maximum unavailable message identifier for dialogs with cleared/unavailable history - int32 last_clear_history_date = 0; - MessageId last_clear_history_message_id; int64 order = DEFAULT_ORDER; + int64 pending_order = DEFAULT_ORDER; MessageId deleted_last_message_id; int32 delete_last_message_date = 0; - int32 pending_last_message_date = 0; - MessageId pending_last_message_id; + int32 last_clear_history_date = 0; + MessageId last_clear_history_message_id; MessageId last_edited_message_id; uint32 scheduled_messages_sync_generation = 0; uint32 last_repair_scheduled_messages_generation = 0; @@ -1394,6 +1292,7 @@ class MessagesManager final : public Actor { bool has_outgoing_messages = false; bool was_opened = false; + bool need_unload_on_close = false; bool need_restore_reply_markup = true; bool need_drop_default_send_message_as_dialog_id = false; @@ -1407,9 +1306,13 @@ class MessagesManager final : public Actor { bool is_folder_id_inited = false; bool need_repair_server_unread_count = false; bool need_repair_channel_server_unread_count = false; + bool is_forum = false; + bool view_as_messages = false; bool is_marked_as_unread = false; bool is_blocked = false; bool is_is_blocked_inited = false; + bool is_blocked_for_stories = false; + bool is_is_blocked_for_stories_inited = false; bool last_sent_has_scheduled_messages = false; bool has_scheduled_server_messages = false; bool has_scheduled_database_messages = false; @@ -1422,6 +1325,8 @@ class MessagesManager final : public Actor { bool is_message_ttl_inited = false; bool has_expected_active_group_call_id = false; bool has_bots = false; + bool is_view_as_messages_inited = false; + bool is_saved_messages_view_as_messages_inited = false; bool is_has_bots_inited = false; bool is_background_inited = false; bool is_theme_name_inited = false; @@ -1440,8 +1345,7 @@ class MessagesManager final : public Actor { int32 pending_read_channel_inbox_pts = 0; // for channels only int32 pending_read_channel_inbox_server_unread_count = 0; // for channels only MessageId pending_read_channel_inbox_max_message_id; // for channels only - std::unordered_map> - random_id_to_message_id; // for secret chats and yet unsent messages only + FlatHashMap random_id_to_message_id; // for secret chats and yet unsent messages only MessageId last_assigned_message_id; // identifier of the last local or yet unsent message, assigned after // application start, used to guarantee that all assigned message identifiers @@ -1494,6 +1398,7 @@ class MessagesManager final : public Actor { int32 in_memory_dialog_total_count_ = 0; int32 server_dialog_total_count_ = -1; int32 secret_chat_total_count_ = -1; + int64 unique_id_ = 0; vector> load_list_queries_; @@ -1608,18 +1513,23 @@ class MessagesManager final : public Actor { bool from_background = false; bool update_stickersets_order = false; bool protect_content = false; + bool only_preview = false; int32 schedule_date = 0; int32 sending_id = 0; + MessageEffectId effect_id; MessageSendOptions() = default; MessageSendOptions(bool disable_notification, bool from_background, bool update_stickersets_order, - bool protect_content, int32 schedule_date, int32 sending_id) + bool protect_content, bool only_preview, int32 schedule_date, int32 sending_id, + MessageEffectId effect_id) : disable_notification(disable_notification) , from_background(from_background) , update_stickersets_order(update_stickersets_order) , protect_content(protect_content) + , only_preview(only_preview) , schedule_date(schedule_date) - , sending_id(sending_id) { + , sending_id(sending_id) + , effect_id(effect_id) { } }; @@ -1633,6 +1543,34 @@ class MessagesManager final : public Actor { vector, std::function>> suffix_load_queries_; }; + struct PendingGetHistoryQuery { + DialogId dialog_id_; + MessageId from_message_id_; + MessageId old_last_message_id_; + int32 offset_ = 0; + int32 limit_ = 0; + bool from_database_ = false; + bool only_local_ = false; + + bool operator==(const PendingGetHistoryQuery &other) const { + return dialog_id_ == other.dialog_id_ && from_message_id_ == other.from_message_id_ && + old_last_message_id_ == other.old_last_message_id_ && offset_ == other.offset_ && limit_ == other.limit_ && + from_database_ == other.from_database_ && only_local_ == other.only_local_; + } + }; + struct PendingGetHistoryQueryHash { + uint32 operator()(const PendingGetHistoryQuery &query) const { + uint32 hash = DialogIdHash()(query.dialog_id_); + hash = combine_hashes(hash, MessageIdHash()(query.from_message_id_)); + hash = combine_hashes(hash, MessageIdHash()(query.old_last_message_id_)); + hash = combine_hashes(hash, Hash()(query.offset_)); + hash = combine_hashes(hash, Hash()(query.limit_)); + hash = combine_hashes(hash, static_cast(query.from_database_)); + hash = combine_hashes(hash, static_cast(query.only_local_)); + return hash; + } + }; + class BlockMessageSenderFromRepliesOnServerLogEvent; class DeleteAllCallMessagesOnServerLogEvent; class DeleteAllChannelMessagesFromSenderOnServerLogEvent; @@ -1657,9 +1595,11 @@ class MessagesManager final : public Actor { class SendBotStartMessageLogEvent; class SendInlineQueryResultMessageLogEvent; class SendMessageLogEvent; + class SendQuickReplyShortcutMessagesLogEvent; class SendScreenshotTakenNotificationMessageLogEvent; class SetDialogFolderIdOnServerLogEvent; class ToggleDialogIsBlockedOnServerLogEvent; + class ToggleDialogViewAsMessagesOnServerLogEvent; class ToggleDialogIsMarkedAsUnreadOnServerLogEvent; class ToggleDialogIsTranslatableOnServerLogEvent; class ToggleDialogIsPinnedOnServerLogEvent; @@ -1676,10 +1616,7 @@ class MessagesManager final : public Actor { static constexpr int32 MAX_CHANNEL_DIFFERENCE = 100; static constexpr int32 MAX_BOT_CHANNEL_DIFFERENCE = 100000; // server side limit static constexpr int32 MAX_RECENT_DIALOGS = 50; // some reasonable value - static constexpr size_t MAX_TITLE_LENGTH = 128; // server side limit for chat title - static constexpr size_t MAX_DESCRIPTION_LENGTH = 255; // server side limit for chat description - static constexpr int32 MAX_PRIVATE_MESSAGE_TTL = 60; // server side limit - static constexpr size_t MIN_DELETED_ASYNCHRONOUSLY_MESSAGES = 10; + static constexpr size_t MIN_DELETED_ASYNCHRONOUSLY_MESSAGES = 2; static constexpr size_t MAX_UNLOADED_MESSAGES = 5000; static constexpr int64 SPONSORED_DIALOG_ORDER = static_cast(2147483647) << 32; @@ -1705,27 +1642,20 @@ class MessagesManager final : public Actor { static constexpr int32 LIVE_LOCATION_VIEW_PERIOD = 60; // seconds, server-side limit static constexpr int32 UPDATE_VIEWED_MESSAGES_PERIOD = 15; // seconds - static constexpr int32 USERNAME_CACHE_EXPIRE_TIME = 86400; static constexpr int32 AUTH_NOTIFICATION_ID_CACHE_TIME = 7 * 86400; static constexpr size_t MAX_SAVED_AUTH_NOTIFICATION_IDS = 100; - static constexpr int32 ONLINE_MEMBER_COUNT_UPDATE_TIME = 5 * 60; - static constexpr int32 MAX_RESEND_DELAY = 86400; // seconds, some resonable limit static constexpr int32 SCHEDULE_WHEN_ONLINE_DATE = 2147483646; - static constexpr double DIALOG_ACTION_TIMEOUT = 5.5; - static constexpr const char *DELETE_MESSAGE_USER_REQUEST_SOURCE = "user request"; static constexpr bool DROP_SEND_MESSAGE_UPDATES = false; - static int32 get_message_date(const tl_object_ptr &message_ptr); - - static vector get_message_user_ids(const Message *m); + vector get_message_user_ids(const Message *m) const; - static vector get_message_channel_ids(const Message *m); + vector get_message_channel_ids(const Message *m) const; static bool is_dialog_inited(const Dialog *d); @@ -1747,8 +1677,6 @@ class MessagesManager final : public Actor { void close_dialog(Dialog *d); - DialogId get_my_dialog_id() const; - void on_resolve_secret_chat_message_via_bot_username(const string &via_bot_username, MessageInfo *message_info_ptr, Promise &&promise); @@ -1763,50 +1691,56 @@ class MessagesManager final : public Actor { void finish_delete_secret_chat_history(DialogId dialog_id, bool remove_from_dialog_list, MessageId last_message_id, Promise promise); - MessageInfo parse_telegram_api_message(tl_object_ptr message_ptr, bool is_scheduled, - const char *source) const; + static MessageInfo parse_telegram_api_message(Td *td, tl_object_ptr message_ptr, + bool is_scheduled, bool is_business_message, const char *source); - std::pair> create_message(MessageInfo &&message_info, bool is_channel_message); + static std::pair> create_message(Td *td, MessageInfo &&message_info, + bool is_channel_message, bool is_business_message, + const char *source); MessageId find_old_message_id(DialogId dialog_id, MessageId message_id) const; void delete_update_message_id(DialogId dialog_id, MessageId message_id); - void get_dialog_message_count_from_server(DialogId dialog_id, MessageSearchFilter filter, Promise &&promise); + void get_dialog_message_count_from_server(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageSearchFilter filter, Promise &&promise); - FullMessageId on_get_message(MessageInfo &&message_info, const bool from_update, const bool is_channel_message, + MessageFullId on_get_message(MessageInfo &&message_info, const bool from_update, const bool is_channel_message, const char *source); Result process_input_message_content( - DialogId dialog_id, tl_object_ptr &&input_message_content); + DialogId dialog_id, tl_object_ptr &&input_message_content, + bool check_permissions = true); Result process_message_copy_options(DialogId dialog_id, tl_object_ptr &&options) const; Result process_message_send_options(DialogId dialog_id, tl_object_ptr &&options, - bool allow_update_stickersets_order) const; + bool allow_update_stickersets_order, bool allow_effect) const; static Status can_use_message_send_options(const MessageSendOptions &options, - const unique_ptr &content, int32 ttl); + const unique_ptr &content, MessageSelfDestructType ttl); static Status can_use_message_send_options(const MessageSendOptions &options, const InputMessageContent &content); - Status can_use_top_thread_message_id(Dialog *d, MessageId top_thread_message_id, MessageId reply_to_message_id); - - bool is_anonymous_administrator(DialogId dialog_id, string *author_signature) const; + Status can_use_top_thread_message_id(Dialog *d, MessageId top_thread_message_id, + const MessageInputReplyTo &input_reply_to); int64 generate_new_random_id(const Dialog *d); - unique_ptr create_message_to_send(Dialog *d, MessageId top_thread_message_id, MessageId reply_to_message_id, - const MessageSendOptions &options, unique_ptr &&content, + unique_ptr create_message_to_send(Dialog *d, MessageId top_thread_message_id, + MessageInputReplyTo &&input_reply_to, const MessageSendOptions &options, + unique_ptr &&content, bool invert_media, bool suppress_reply_info, unique_ptr forward_info, - bool is_copy, DialogId send_as_dialog_id) const; + DialogId real_forward_from_dialog_id, bool is_copy, + DialogId send_as_dialog_id) const; - Message *get_message_to_send(Dialog *d, MessageId top_thread_message_id, MessageId reply_to_message_id, + Message *get_message_to_send(Dialog *d, MessageId top_thread_message_id, MessageInputReplyTo &&input_reply_to, const MessageSendOptions &options, unique_ptr &&content, - bool *need_update_dialog_pos, bool suppress_reply_info = false, - unique_ptr forward_info = nullptr, bool is_copy = false, + bool invert_media, bool *need_update_dialog_pos, bool suppress_reply_info = false, + unique_ptr forward_info = nullptr, + DialogId real_forward_from_dialog_id = DialogId(), bool is_copy = false, DialogId sender_dialog_id = DialogId()); int64 begin_send_message(DialogId dialog_id, const Message *m); @@ -1817,17 +1751,19 @@ class MessagesManager final : public Actor { bool can_edit_message(DialogId dialog_id, const Message *m, bool is_editing, bool only_reply_markup = false) const; - bool has_qts_messages(DialogId dialog_id) const; - - bool can_report_dialog(DialogId dialog_id) const; - - Status can_pin_messages(DialogId dialog_id) const; + Status can_pin_message(DialogId dialog_id, const Message *m) const TD_WARN_UNUSED_RESULT; static Status can_get_media_timestamp_link(DialogId dialog_id, const Message *m); bool can_report_message_reactions(DialogId dialog_id, const Message *m) const; - Status can_get_message_viewers(FullMessageId full_message_id) TD_WARN_UNUSED_RESULT; + bool can_recognize_message_speech(DialogId dialog_id, const Message *m) const; + + bool can_set_message_fact_check(DialogId dialog_id, const Message *m) const; + + Status can_get_message_read_date(DialogId dialog_id, const Message *m) const TD_WARN_UNUSED_RESULT; + + Status can_get_message_viewers(MessageFullId message_full_id) TD_WARN_UNUSED_RESULT; Status can_get_message_viewers(DialogId dialog_id, const Message *m) const TD_WARN_UNUSED_RESULT; @@ -1839,12 +1775,13 @@ class MessagesManager final : public Actor { MessageId get_persistent_message_id(const Dialog *d, MessageId message_id) const; - static FullMessageId get_replied_message_id(DialogId dialog_id, const Message *m); + static MessageFullId get_replied_message_id(DialogId dialog_id, const Message *m); - MessageId get_reply_to_message_id(Dialog *d, MessageId top_thread_message_id, MessageId message_id, bool for_draft); + MessageInputReplyTo create_message_input_reply_to(Dialog *d, MessageId top_thread_message_id, + td_api::object_ptr &&reply_to, + bool for_draft); - void fix_server_reply_to_message_id(DialogId dialog_id, MessageId message_id, DialogId reply_in_dialog_id, - MessageId &reply_to_message_id) const; + static const MessageInputReplyTo *get_message_input_reply_to(const Message *m); bool can_set_game_score(DialogId dialog_id, const Message *m) const; @@ -1853,9 +1790,9 @@ class MessagesManager final : public Actor { bool process_channel_update(tl_object_ptr &&update_ptr); - void on_message_edited(FullMessageId full_message_id, int32 pts, bool had_message); + void on_message_edited(MessageFullId message_full_id, int32 pts, bool had_message); - void delete_messages_from_updates(const vector &message_ids); + void delete_messages_from_updates(const vector &message_ids, bool is_permanent); void delete_dialog_messages(DialogId dialog_id, const vector &message_ids, bool force_update_for_not_found_messages, const char *source); @@ -1872,7 +1809,19 @@ class MessagesManager final : public Actor { const vector &message_ids, bool drop_author, bool drop_media_captions, uint64 log_event_id); - void send_forward_message_query(int32 flags, DialogId to_dialog_id, MessageId top_thread_message_id, + uint64 save_send_quick_reply_shortcut_messages_log_event(DialogId dialog_id, QuickReplyShortcutId shortcut_id, + const vector &messages, + const vector &message_ids); + + void do_send_quick_reply_shortcut_messages(DialogId dialog_id, QuickReplyShortcutId shortcut_id, + const vector &messages, const vector &message_ids, + uint64 log_event_id); + + void send_send_quick_reply_messages_query(DialogId dialog_id, QuickReplyShortcutId shortcut_id, + vector message_ids, vector random_ids, + Promise promise); + + void send_forward_message_query(int32 flags, DialogId to_dialog_id, const MessageId top_thread_message_id, DialogId from_dialog_id, tl_object_ptr as_input_peer, vector message_ids, vector random_ids, int32 schedule_date, Promise promise); @@ -1883,8 +1832,10 @@ class MessagesManager final : public Actor { bool in_game_share, MessageCopyOptions &©_options) TD_WARN_UNUSED_RESULT; + MessageOrigin get_forwarded_message_origin(DialogId dialog_id, const Message *m) const; + unique_ptr create_message_forward_info(DialogId from_dialog_id, DialogId to_dialog_id, - const Message *forwarded_message) const; + const Message *m) const; void fix_forwarded_message(Message *m, DialogId to_dialog_id, const Message *forwarded_message, int64 media_album_id, bool drop_author) const; @@ -1892,18 +1843,20 @@ class MessagesManager final : public Actor { struct ForwardedMessages { struct CopiedMessage { unique_ptr content; - MessageId reply_to_message_id; + MessageInputReplyTo input_reply_to; MessageId original_message_id; MessageId original_reply_to_message_id; unique_ptr reply_markup; int64 media_album_id; bool disable_web_page_preview; + bool invert_media; size_t index; }; vector copied_messages; struct ForwardedMessageContent { unique_ptr content; + bool invert_media; int64 media_album_id; size_t index; }; @@ -1922,27 +1875,30 @@ class MessagesManager final : public Actor { td_api::object_ptr &&options, bool in_game_share, vector &©_options); - void do_send_media(DialogId dialog_id, Message *m, FileId file_id, FileId thumbnail_file_id, + void do_send_media(DialogId dialog_id, const Message *m, int32 media_pos, FileId file_id, FileId thumbnail_file_id, tl_object_ptr input_file, tl_object_ptr input_thumbnail); - void do_send_secret_media(DialogId dialog_id, Message *m, FileId file_id, FileId thumbnail_file_id, + void do_send_secret_media(DialogId dialog_id, const Message *m, FileId file_id, FileId thumbnail_file_id, tl_object_ptr input_encrypted_file, BufferSlice thumbnail); - void do_send_message(DialogId dialog_id, const Message *m, vector bad_parts = {}); + void do_send_message(DialogId dialog_id, const Message *m, int32 media_pos = -1, vector bad_parts = {}); - void on_message_media_uploaded(DialogId dialog_id, const Message *m, - tl_object_ptr &&input_media, FileId file_id, - FileId thumbnail_file_id); + void on_message_media_uploaded(DialogId dialog_id, const Message *m, int32 media_pos, + telegram_api::object_ptr &&input_media, + vector file_ids, vector thumbnail_file_ids); void on_secret_message_media_uploaded(DialogId dialog_id, const Message *m, SecretInputMedia &&secret_input_media, FileId file_id, FileId thumbnail_file_id); - void on_upload_message_media_finished(int64 media_album_id, DialogId dialog_id, MessageId message_id, Status result); + void on_upload_message_media_finished(int64 media_album_id, DialogId dialog_id, MessageId message_id, int32 media_pos, + Status result); void do_send_message_group(int64 media_album_id); + void do_send_paid_media_group(DialogId dialog_id, MessageId message_id); + void on_text_message_ready_to_send(DialogId dialog_id, MessageId message_id); void on_media_message_ready_to_send(DialogId dialog_id, MessageId message_id, Promise &&promise); @@ -1962,10 +1918,17 @@ class MessagesManager final : public Actor { void do_send_inline_query_result_message(DialogId dialog_id, MessageId message_id, int64 query_id, const string &result_id); + void send_screenshot_taken_notification_message(Dialog *d); + static uint64 save_send_screenshot_taken_notification_message_log_event(DialogId dialog_id, const Message *m); void do_send_screenshot_taken_notification_message(DialogId dialog_id, const Message *m, uint64 log_event_id); + void set_message_reply(const Dialog *d, Message *m, MessageInputReplyTo input_reply_to, bool is_message_in_dialog); + + void update_message_reply_to_message_id(const Dialog *d, Message *m, MessageId reply_to_message_id, + bool is_message_in_dialog); + void restore_message_reply_to_message_id(Dialog *d, Message *m); Message *continue_send_message(DialogId dialog_id, unique_ptr &&message, bool *need_update_dialog_pos, @@ -1979,8 +1942,12 @@ class MessagesManager final : public Actor { bool can_save_message(DialogId dialog_id, const Message *m) const; + bool can_share_message_in_story(DialogId dialog_id, const Message *m) const; + bool can_get_message_statistics(DialogId dialog_id, const Message *m) const; + Status can_get_message_embedding_code(DialogId dialog_id, const Message *m) const; + struct CanDeleteDialog { bool for_self_; bool for_all_users_; @@ -2019,7 +1986,7 @@ class MessagesManager final : public Actor { double get_next_unload_dialog_delay(Dialog *d) const; - void unload_dialog(DialogId dialog_id); + void unload_dialog(DialogId dialog_id, int32 delay); void clear_dialog_message_list(Dialog *d, bool remove_from_dialog_list, int32 last_message_date); @@ -2059,11 +2026,6 @@ class MessagesManager final : public Actor { void unpin_all_dialog_messages_on_server(DialogId dialog_id, uint64 log_event_id, Promise &&promise); - using AffectedHistoryQuery = std::function)>; - - void run_affected_history_query_until_complete(DialogId dialog_id, AffectedHistoryQuery query, - bool get_affected_messages, Promise &&promise); - void on_get_affected_history(DialogId dialog_id, AffectedHistoryQuery query, bool get_affected_messages, AffectedHistory affected_history, Promise &&promise); @@ -2076,7 +2038,7 @@ class MessagesManager final : public Actor { void on_pending_message_views_timeout(DialogId dialog_id); - void update_message_interaction_info(FullMessageId full_message_id, int32 view_count, int32 forward_count, + void update_message_interaction_info(MessageFullId message_full_id, int32 view_count, int32 forward_count, bool has_reply_info, tl_object_ptr &&reply_info, bool has_reactions, unique_ptr &&reactions); @@ -2095,11 +2057,13 @@ class MessagesManager final : public Actor { void on_message_reply_info_changed(DialogId dialog_id, const Message *m) const; - Result get_top_thread_full_message_id(DialogId dialog_id, const Message *m, bool allow_non_root) const; + Result get_top_thread_message_full_id(DialogId dialog_id, const Message *m, bool allow_non_root) const; td_api::object_ptr get_message_interaction_info_object(DialogId dialog_id, const Message *m) const; + td_api::object_ptr get_message_fact_check_object(const Message *m) const; + vector> get_unread_reactions_object(DialogId dialog_id, const Message *m) const; @@ -2107,15 +2071,17 @@ class MessagesManager final : public Actor { bool has_reply_info, MessageReplyInfo &&reply_info, bool has_reactions, unique_ptr &&reactions, const char *source); + bool update_message_fact_check(const Dialog *d, Message *m, unique_ptr &&fact_check, bool need_save); + bool update_message_contains_unread_mention(Dialog *d, Message *m, bool contains_unread_mention, const char *source); bool remove_message_unread_reactions(Dialog *d, Message *m, const char *source); - void read_message_content_from_updates(MessageId message_id); + void read_message_content_from_updates(MessageId message_id, int32 read_date); void read_channel_message_content_from_updates(Dialog *d, MessageId message_id); - bool read_message_content(Dialog *d, Message *m, bool is_local_read, const char *source); + bool read_message_content(Dialog *d, Message *m, bool is_local_read, int32 read_date, const char *source); void read_message_contents_on_server(DialogId dialog_id, vector message_ids, uint64 log_event_id, Promise &&promise, bool skip_log_event = false); @@ -2165,11 +2131,6 @@ class MessagesManager final : public Actor { void set_dialog_max_unavailable_message_id(DialogId dialog_id, MessageId max_unavailable_message_id, bool from_update, const char *source); - void set_dialog_online_member_count(DialogId dialog_id, int32 online_member_count, bool is_from_server, - const char *source); - - void on_update_dialog_online_member_count_timeout(DialogId dialog_id); - void on_update_viewed_messages_timeout(DialogId dialog_id); void on_send_update_chat_read_inbox_timeout(DialogId dialog_id); @@ -2184,21 +2145,18 @@ class MessagesManager final : public Actor { void preload_older_messages(const Dialog *d, MessageId min_message_id); - void on_get_history_from_database(DialogId dialog_id, MessageId from_message_id, - MessageId old_last_database_message_id, int32 offset, int32 limit, - bool from_the_end, bool only_local, vector &&messages, - Promise &&promise); + void load_last_dialog_message_later(DialogId dialog_id); - void get_history_from_the_end(DialogId dialog_id, bool from_database, bool only_local, Promise &&promise); - - void get_history_from_the_end_impl(const Dialog *d, bool from_database, bool only_local, Promise &&promise, - const char *source); + void load_last_dialog_message(const Dialog *d, const char *source); - void get_history(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, bool from_database, - bool only_local, Promise &&promise); + void on_get_history_from_database(DialogId dialog_id, MessageId from_message_id, + MessageId old_last_database_message_id, int32 offset, int32 limit, bool only_local, + vector &&messages, Promise &&promise); void get_history_impl(const Dialog *d, MessageId from_message_id, int32 offset, int32 limit, bool from_database, - bool only_local, Promise &&promise); + bool only_local, Promise &&promise, const char *source); + + void on_get_history_finished(const PendingGetHistoryQuery &query, Result &&result); void load_messages(DialogId dialog_id, MessageId from_message_id, int32 offset, int32 limit, int left_tries, bool only_local, Promise &&promise); @@ -2216,11 +2174,11 @@ class MessagesManager final : public Actor { bool is_message_auto_read(DialogId dialog_id, bool is_outgoing) const; - void fail_send_message(FullMessageId full_message_id, int error_code, const string &error_message); + void fail_send_message(MessageFullId message_full_id, int32 error_code, const string &error_message); - void fail_send_message(FullMessageId full_message_id, Status error); + void fail_send_message(MessageFullId message_full_id, Status error); - void fail_edit_message_media(FullMessageId full_message_id, Status &&error); + void fail_edit_message_media(MessageFullId message_full_id, Status &&error); void on_dialog_updated(DialogId dialog_id, const char *source); @@ -2263,6 +2221,8 @@ class MessagesManager final : public Actor { void remove_message_remove_keyboard_reply_markup(Message *m) const; + void update_replied_by_message_count(DialogId dialog_id, const Message *m, bool is_add); + void add_message_to_dialog_message_list(const Message *m, Dialog *d, const bool from_database, const bool from_update, const bool need_update, bool *need_update_dialog_pos, const char *source); @@ -2279,12 +2239,14 @@ class MessagesManager final : public Actor { void on_message_notification_changed(Dialog *d, const Message *m, const char *source); - bool need_delete_file(FullMessageId full_message_id, FileId file_id) const; + bool need_delete_file(MessageFullId message_full_id, FileId file_id) const; bool need_delete_message_files(DialogId dialog_id, const Message *m) const; void add_message_to_database(const Dialog *d, const Message *m, const char *source); + void delete_all_dialog_notifications(Dialog *d, MessageId max_message_id, const char *source); + void delete_all_dialog_messages_from_database(Dialog *d, MessageId max_message_id, const char *source); void delete_message_from_database(Dialog *d, MessageId message_id, const Message *m, bool is_permanently_deleted, @@ -2305,6 +2267,10 @@ class MessagesManager final : public Actor { static void delete_notification_id_to_message_id_correspondence(NotificationInfo *notification_info, NotificationId notification_id, MessageId message_id); + static bool is_notification_info_group_id(const NotificationInfo *notification_info, NotificationGroupId group_id); + + static bool is_dialog_notification_group_id(const Dialog *d, NotificationGroupId group_id); + void remove_message_notification_id(Dialog *d, Message *m, bool is_permanent, bool force_update, bool ignore_pinned_message_notification_removal = false); @@ -2318,6 +2284,8 @@ class MessagesManager final : public Actor { void do_delete_message_log_event(const DeleteMessageLogEvent &log_event) const; + int64 get_message_reply_to_random_id(const Dialog *d, const Message *m) const; + bool update_message(Dialog *d, Message *old_message, unique_ptr new_message, bool is_message_in_dialog); static bool need_message_changed_warning(const Message *old_message); @@ -2325,12 +2293,15 @@ class MessagesManager final : public Actor { bool update_message_content(DialogId dialog_id, Message *old_message, unique_ptr new_content, bool need_merge_files, bool is_message_in_dialog, bool &is_content_changed); - void update_message_max_reply_media_timestamp(const Dialog *d, Message *m, bool need_send_update_message_content); + void update_message_max_reply_media_timestamp(const Dialog *d, Message *m, + bool need_send_update_message_content) const; void update_message_max_own_media_timestamp(const Dialog *d, Message *m); void update_message_max_reply_media_timestamp_in_replied_messages(DialogId dialog_id, MessageId reply_to_message_id); + bool can_register_message_reply(const Message *m) const; + void register_message_reply(DialogId dialog_id, const Message *m); void reregister_message_reply(DialogId dialog_id, const Message *m); @@ -2397,7 +2368,8 @@ class MessagesManager final : public Actor { bool need_skip_bot_commands(DialogId dialog_id, const Message *m) const; - void send_update_message_send_succeeded(const Dialog *d, MessageId old_message_id, const Message *m); + void send_update_message_send_succeeded(Dialog *d, MessageId old_message_id, const Message *m, + bool *need_update_dialog_pos); void send_update_message_content(const Dialog *d, Message *m, bool is_message_in_dialog, const char *source); @@ -2407,18 +2379,24 @@ class MessagesManager final : public Actor { void send_update_message_interaction_info(DialogId dialog_id, const Message *m) const; + void send_update_message_fact_check(DialogId dialog_id, const Message *m) const; + void send_update_message_unread_reactions(DialogId dialog_id, const Message *m, int32 unread_reaction_count) const; - void send_update_message_live_location_viewed(FullMessageId full_message_id); + void send_update_message_live_location_viewed(MessageFullId message_full_id); + + void send_update_active_live_location_messages(); void send_update_delete_messages(DialogId dialog_id, vector &&message_ids, bool is_permanent) const; - void send_update_new_chat(Dialog *d); + void send_update_new_chat(Dialog *d, const char *source); - bool need_hide_dialog_draft_message(DialogId dialog_id) const; + bool need_hide_dialog_draft_message(const Dialog *d) const; void send_update_chat_draft_message(const Dialog *d); + void send_update_last_message_if_needed(const Dialog *d, const Message *m, const char *source) const; + void send_update_chat_last_message(Dialog *d, const char *source); void send_update_chat_last_message_impl(const Dialog *d, const char *source) const; @@ -2439,12 +2417,12 @@ class MessagesManager final : public Actor { void send_update_chat_position(DialogListId dialog_list_id, const Dialog *d, const char *source) const; - void send_update_chat_online_member_count(DialogId dialog_id, int32 online_member_count) const; - void send_update_secret_chats_with_user_action_bar(const Dialog *d) const; void send_update_chat_action_bar(Dialog *d); + void send_update_chat_business_bot_manage_bar(Dialog *d); + void send_update_chat_available_reactions(const Dialog *d); void send_update_secret_chats_with_user_background(const Dialog *d) const; @@ -2465,9 +2443,6 @@ class MessagesManager final : public Actor { void send_update_chat_has_scheduled_messages(Dialog *d, bool from_deletion); - void send_update_chat_action(DialogId dialog_id, MessageId top_thread_message_id, DialogId typing_dialog_id, - const DialogAction &action); - void repair_dialog_action_bar(Dialog *d, const char *source); void hide_dialog_action_bar(Dialog *d); @@ -2482,11 +2457,25 @@ class MessagesManager final : public Actor { static tl_object_ptr get_message_scheduling_state_object(int32 send_date); - tl_object_ptr get_message_object(DialogId dialog_id, const Message *m, const char *source) const; + td_api::object_ptr get_message_message_content_object(DialogId dialog_id, + const Message *m) const; + + td_api::object_ptr get_message_object(Dialog *d, MessageId message_id, const char *source); + + td_api::object_ptr get_message_object(const Dialog *d, MessageId message_id, + const char *source) const; + + td_api::object_ptr get_message_object(DialogId dialog_id, const Message *m, + const char *source) const; + + static td_api::object_ptr get_messages_object(int32 total_count, + vector> &&messages, + bool skip_not_found); + + td_api::object_ptr get_business_message_message_object( + telegram_api::object_ptr &&message); - static tl_object_ptr get_messages_object(int32 total_count, - vector> &&messages, - bool skip_not_found); + td_api::object_ptr get_update_active_live_location_messages_object() const; vector sort_dialogs_by_order(const vector &dialog_ids, int32 limit) const; @@ -2536,8 +2525,6 @@ class MessagesManager final : public Actor { int32 get_pinned_dialogs_limit(DialogListId dialog_list_id) const; - static vector remove_secret_chat_dialog_ids(vector dialog_ids); - bool set_dialog_is_pinned(DialogId dialog_id, bool is_pinned); bool set_dialog_is_pinned(DialogListId dialog_list_id, Dialog *d, bool is_pinned, @@ -2545,11 +2532,17 @@ class MessagesManager final : public Actor { void save_pinned_folder_dialog_ids(const DialogList &list) const; + void on_update_dialog_view_as_topics(const Dialog *d, bool old_view_as_topics); + + void set_dialog_is_forum(Dialog *d, bool is_forum); + + void set_dialog_view_as_messages(Dialog *d, bool view_as_messages, const char *source); + void set_dialog_is_marked_as_unread(Dialog *d, bool is_marked_as_unread); void set_dialog_is_translatable(Dialog *d, bool is_translatable); - void set_dialog_is_blocked(Dialog *d, bool is_blocked); + void set_dialog_is_blocked(Dialog *d, bool is_blocked, bool is_blocked_for_stories); void set_dialog_has_bots(Dialog *d, bool has_bots); @@ -2581,11 +2574,14 @@ class MessagesManager final : public Actor { void toggle_dialog_is_pinned_on_server(DialogId dialog_id, bool is_pinned, uint64 log_event_id); + void toggle_dialog_view_as_messages_on_server(DialogId dialog_id, bool view_as_messages, uint64 log_event_id); + void toggle_dialog_is_marked_as_unread_on_server(DialogId dialog_id, bool is_marked_as_unread, uint64 log_event_id); void toggle_dialog_is_translatable_on_server(DialogId dialog_id, bool is_translatable, uint64 log_event_id); - void toggle_dialog_is_blocked_on_server(DialogId dialog_id, bool is_blocked, uint64 log_event_id); + void toggle_dialog_is_blocked_on_server(DialogId dialog_id, bool is_blocked, bool is_blocked_for_stories, + uint64 log_event_id); void reorder_pinned_dialogs_on_server(FolderId folder_id, const vector &dialog_ids, uint64 log_event_id); @@ -2599,13 +2595,17 @@ class MessagesManager final : public Actor { void remove_dialog_mention_notifications(Dialog *d); - bool set_dialog_last_notification(DialogId dialog_id, NotificationGroupInfo &group_info, int32 last_notification_date, + void set_dialog_last_notification(DialogId dialog_id, NotificationGroupInfo &group_info, int32 last_notification_date, NotificationId last_notification_id, const char *source); + void set_dialog_last_notification_checked(DialogId dialog_id, NotificationGroupInfo &group_info, + int32 last_notification_date, NotificationId last_notification_id, + const char *source); + bool update_dialog_notification_settings(DialogId dialog_id, DialogNotificationSettings *current_settings, DialogNotificationSettings &&new_settings); - void schedule_dialog_unmute(DialogId dialog_id, bool use_default, int32 mute_until); + void schedule_dialog_unmute(DialogId dialog_id, bool use_default, int32 mute_until, int32 unix_time); void update_dialog_unmute_timeout(Dialog *d, bool &old_use_default, int32 &old_mute_until, bool new_use_default, int32 new_mute_until); @@ -2616,12 +2616,18 @@ class MessagesManager final : public Actor { void set_dialog_message_ttl(Dialog *d, MessageTtl message_ttl); - ChatReactions get_message_available_reactions(const Dialog *d, const Message *m, - bool dissalow_custom_for_non_premium); + bool can_add_message_tag(DialogId dialog_id, const MessageReactions *reactions) const; + + ChatReactions get_message_available_reactions(const Dialog *d, const Message *m, bool disallow_custom_for_non_premium, + ReactionUnavailabilityReason *unavailability_reason); + + DialogId get_my_reaction_dialog_id(const Dialog *d) const; + + void drop_message_pending_paid_reactions(const Dialog *d, Message *m); void set_message_reactions(Dialog *d, Message *m, bool is_big, bool add_to_recent, Promise &&promise); - void on_set_message_reactions(FullMessageId full_message_id, Result result, Promise promise); + void on_set_message_reactions(MessageFullId message_full_id, Result result, Promise promise); void on_read_message_reactions(DialogId dialog_id, vector &&message_ids, Result &&result); @@ -2641,18 +2647,15 @@ class MessagesManager final : public Actor { static bool need_poll_message_reactions(const Dialog *d, const Message *m); - void queue_message_reactions_reload(FullMessageId full_message_id); + void queue_message_reactions_reload(MessageFullId message_full_id); void queue_message_reactions_reload(DialogId dialog_id, const vector &message_ids); - bool is_dialog_action_unneeded(DialogId dialog_id) const; + void on_get_message_fact_checks(DialogId dialog_id, const vector &message_ids, + Result>> r_fact_checks); void on_send_dialog_action_timeout(DialogId dialog_id); - void on_active_dialog_action_timeout(DialogId dialog_id); - - void clear_active_dialog_actions(DialogId dialog_id); - void cancel_dialog_action(DialogId dialog_id, const Message *m); Dialog *get_dialog_by_message_id(MessageId message_id); @@ -2666,20 +2669,23 @@ class MessagesManager final : public Actor { Dialog *add_new_dialog(unique_ptr &&dialog, bool is_loaded_from_database, const char *source); - void fix_new_dialog(Dialog *d, unique_ptr &&last_database_message, MessageId last_database_message_id, - int64 order, int32 last_clear_history_date, MessageId last_clear_history_message_id, - DialogId default_join_group_call_as_dialog_id, DialogId default_send_message_as_dialog_id, - bool need_drop_default_send_message_as_dialog_id, bool is_loaded_from_database, - const char *source); + void fix_new_dialog(Dialog *d, unique_ptr &&draft_message, unique_ptr &&last_database_message, + MessageId last_database_message_id, int64 order, int32 last_clear_history_date, + MessageId last_clear_history_message_id, DialogId default_join_group_call_as_dialog_id, + DialogId default_send_message_as_dialog_id, bool need_drop_default_send_message_as_dialog_id, + bool is_loaded_from_database, const char *source); - bool add_dialog_last_database_message(Dialog *d, unique_ptr &&last_database_message); + bool add_pending_dialog_data(Dialog *d, unique_ptr &&last_database_message, + unique_ptr &&draft_message); void fix_dialog_action_bar(const Dialog *d, DialogActionBar *action_bar); - td_api::object_ptr get_chat_type_object(DialogId dialog_id) const; + void fix_dialog_business_bot_manage_bar(DialogId dialog_id, BusinessBotManageBar *business_bot_manage_bar); td_api::object_ptr get_chat_action_bar_object(const Dialog *d) const; + td_api::object_ptr get_business_bot_manage_bar_object(const Dialog *d) const; + td_api::object_ptr get_chat_background_object(const Dialog *d) const; string get_dialog_theme_name(const Dialog *d) const; @@ -2690,7 +2696,7 @@ class MessagesManager final : public Actor { td_api::object_ptr get_default_message_sender_object(const Dialog *d) const; - td_api::object_ptr get_chat_object(const Dialog *d) const; + td_api::object_ptr get_chat_object(const Dialog *d, const char *source) const; Dialog *get_dialog(DialogId dialog_id); const Dialog *get_dialog(DialogId dialog_id) const; @@ -2702,12 +2708,17 @@ class MessagesManager final : public Actor { void on_get_dialogs_from_database(FolderId folder_id, int32 limit, DialogDbGetDialogsResult &&dialogs, Promise &&promise); + Result check_dialog_access(DialogId dialog_id, bool allow_secret_chats, AccessRights access_rights, + const char *source); + void send_get_dialog_query(DialogId dialog_id, Promise &&promise, uint64 log_event_id, const char *source); void send_search_public_dialogs_query(const string &query, Promise &&promise); vector get_pinned_dialog_ids(DialogListId dialog_list_id) const; + bool set_folder_pinned_dialogs(FolderId folder_id, vector old_dialog_ids, vector new_dialog_ids); + void reload_pinned_dialogs(DialogListId dialog_list_id, Promise &&promise); void update_dialogs_hints(const Dialog *d); @@ -2719,9 +2730,9 @@ class MessagesManager final : public Actor { static bool is_dialog_in_list(const Dialog *d, DialogListId dialog_list_id); - static void add_dialog_to_list(Dialog *d, DialogListId dialog_list_id); + void add_dialog_to_list(Dialog *d, DialogListId dialog_list_id); - static void remove_dialog_from_list(Dialog *d, DialogListId dialog_list_id); + void remove_dialog_from_list(Dialog *d, DialogListId dialog_list_id); DialogFilterDialogInfo get_dialog_info_for_dialog_filter(const Dialog *d) const; @@ -2748,15 +2759,16 @@ class MessagesManager final : public Actor { static Message *get_message(Dialog *d, MessageId message_id); static const Message *get_message(const Dialog *d, MessageId message_id); + static const Message *get_message_static(const Dialog *d, MessageId message_id); - Message *get_message(FullMessageId full_message_id); - const Message *get_message(FullMessageId full_message_id) const; + Message *get_message(MessageFullId message_full_id); + const Message *get_message(MessageFullId message_full_id) const; bool have_message_force(Dialog *d, MessageId message_id, const char *source); Message *get_message_force(Dialog *d, MessageId message_id, const char *source); - Message *get_message_force(FullMessageId full_message_id, const char *source); + Message *get_message_force(MessageFullId message_full_id, const char *source); void get_message_force_from_server(Dialog *d, MessageId message_id, Promise &&promise, tl_object_ptr input_message = nullptr); @@ -2772,18 +2784,17 @@ class MessagesManager final : public Actor { vector on_get_messages_from_database(Dialog *d, vector &&messages, MessageId first_message_id, bool &have_error, const char *source); - void get_dialog_message_by_date_from_server(const Dialog *d, int32 date, int64 random_id, bool after_database_search, - Promise &&promise); + void get_dialog_message_by_date_from_server(const Dialog *d, int32 date, bool after_database_search, + Promise> &&promise); - void on_get_dialog_message_by_date_from_database(DialogId dialog_id, int32 date, int64 random_id, - Result result, Promise promise); + void on_get_dialog_message_by_date_from_database(DialogId dialog_id, int32 date, + Result result, + Promise> promise); std::pair get_dialog_mute_until(DialogId dialog_id, const Dialog *d) const; int64 get_dialog_notification_ringtone_id(DialogId dialog_id, const Dialog *d) const; - NotificationSettingsScope get_dialog_notification_setting_scope(DialogId dialog_id) const; - DialogNotificationSettings *get_dialog_notification_settings(DialogId dialog_id, bool force); vector get_message_file_ids(const Message *m) const; @@ -2810,20 +2821,12 @@ class MessagesManager final : public Actor { tl_object_ptr get_send_message_as_input_peer(const Message *m) const; - static bool is_forward_info_sender_hidden(const MessageForwardInfo *forward_info); - - unique_ptr get_message_forward_info( - tl_object_ptr &&forward_header, FullMessageId full_message_id); - - td_api::object_ptr get_message_forward_info_object( - const unique_ptr &forward_info) const; - void ttl_read_history(Dialog *d, bool is_outgoing, MessageId from_message_id, MessageId till_message_id, double view_date); void ttl_read_history_impl(DialogId dialog_id, bool is_outgoing, MessageId from_message_id, MessageId till_message_id, double view_date); void ttl_on_view(const Dialog *d, Message *m, double view_date, double now); - bool ttl_on_open(Dialog *d, Message *m, double now, bool is_local_read); + bool ttl_on_open(Dialog *d, Message *m, double now, bool is_local_read, int32 read_date); void ttl_register_message(DialogId dialog_id, const Message *m, double now); void ttl_unregister_message(DialogId dialog_id, const Message *m, const char *source); void ttl_period_register_message(DialogId dialog_id, const Message *m, double server_time); @@ -2832,7 +2835,8 @@ class MessagesManager final : public Actor { void ttl_update_timeout(double now); void on_message_ttl_expired(Dialog *d, Message *m); - void on_message_ttl_expired_impl(Dialog *d, Message *m); + + void on_message_ttl_expired_impl(Dialog *d, Message *m, bool is_message_in_dialog); void start_up() final; @@ -2842,7 +2846,7 @@ class MessagesManager final : public Actor { void hangup() final; - void create_folders(); + void create_folders(int source); void init(); @@ -2850,10 +2854,10 @@ class MessagesManager final : public Actor { void ttl_db_on_result(Result> r_result, bool dummy); - void on_restore_missing_message_after_get_difference(FullMessageId full_message_id, MessageId old_message_id, + void on_restore_missing_message_after_get_difference(MessageFullId message_full_id, MessageId old_message_id, Result result); - void on_get_message_link_dialog(MessageLinkInfo &&info, Promise &&promise); + void on_get_message_link_dialog(MessageLinkInfo &&info, DialogId dialog_id, Promise &&promise); void on_get_message_link_message(MessageLinkInfo &&info, DialogId dialog_id, Promise &&promise); @@ -2872,30 +2876,38 @@ class MessagesManager final : public Actor { static MessageId get_first_database_message_id_by_index(const Dialog *d, MessageSearchFilter filter); - void on_get_message_calendar_from_database(int64 random_id, DialogId dialog_id, MessageId from_message_id, + void get_message_calendar_from_server(DialogId dialog_id, SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, MessageSearchFilter filter, + Promise> &&promise); + + void on_get_message_calendar_from_database(DialogId dialog_id, MessageId from_message_id, MessageId first_db_message_id, MessageSearchFilter filter, - Result r_calendar, Promise promise); + Result r_calendar, + Promise> promise); void on_search_dialog_message_db_result(int64 random_id, DialogId dialog_id, MessageId from_message_id, MessageId first_db_message_id, MessageSearchFilter filter, int32 offset, int32 limit, Result> r_messages, Promise promise); - void on_message_db_fts_result(Result result, string offset, int32 limit, int64 random_id, - Promise &&promise); + void on_message_db_fts_result(Result result, string offset, int32 limit, + Promise> &&promise); + + void on_message_db_calls_result(Result result, MessageId first_db_message_id, + MessageId offset_message_id, int32 limit, MessageSearchFilter filter, + Promise> &&promise); - void on_message_db_calls_result(Result result, int64 random_id, MessageId first_db_message_id, - MessageSearchFilter filter, Promise &&promise); + void process_viewed_message(Dialog *d, const vector &viewed_message_ids, bool is_first); - void on_load_active_live_location_full_message_ids_from_database(string value); + void on_load_active_live_location_message_full_ids_from_database(string value); - void on_load_active_live_location_messages_finished(); + bool try_add_active_live_location(DialogId dialog_id, const Message *m); - void try_add_active_live_location(DialogId dialog_id, const Message *m); + bool add_active_live_location(MessageFullId message_full_id); - void add_active_live_location(FullMessageId full_message_id); + bool delete_active_live_location(MessageFullId message_full_id); - bool delete_active_live_location(DialogId dialog_id, const Message *m); + void schedule_active_live_location_expiration(); void save_active_live_locations(); @@ -2903,7 +2915,7 @@ class MessagesManager final : public Actor { void view_message_live_location_on_server(int64 task_id); - void view_message_live_location_on_server_impl(int64 task_id, FullMessageId full_message_id); + void view_message_live_location_on_server_impl(int64 task_id, MessageFullId message_full_id); void on_message_live_location_viewed_on_server(int64 task_id); @@ -2918,13 +2930,9 @@ class MessagesManager final : public Actor { void change_message_files(DialogId dialog_id, const Message *m, const vector &old_file_ids); Result> get_dialog_reply_markup( - DialogId dialog_id, tl_object_ptr &&reply_markup_ptr) const TD_WARN_UNUSED_RESULT; - - const DialogPhoto *get_dialog_photo(DialogId dialog_id) const; - - RestrictedRights get_dialog_default_permissions(DialogId dialog_id) const; + DialogId dialog_id, tl_object_ptr &&reply_markup) const TD_WARN_UNUSED_RESULT; - bool get_dialog_has_protected_content(DialogId dialog_id) const; + bool get_dialog_view_as_topics(const Dialog *d) const; bool get_dialog_has_scheduled_messages(const Dialog *d) const; @@ -2947,6 +2955,8 @@ class MessagesManager final : public Actor { bool update_dialog_draft_message(Dialog *d, unique_ptr &&draft_message, bool from_update, bool need_update_dialog_pos); + void clear_dialog_draft_by_sent_message(Dialog *d, const Message *m, bool need_update_dialog_pos); + void save_dialog_draft_message_on_server(DialogId dialog_id); void on_saved_dialog_draft_message(DialogId dialog_id, uint64 generation); @@ -2968,8 +2978,6 @@ class MessagesManager final : public Actor { int64 get_next_pinned_dialog_order(); - bool is_removed_from_dialog_list(const Dialog *d) const; - void update_dialog_pos(Dialog *d, const char *source, bool need_send_update = true, bool is_loaded_from_database = false); @@ -2999,10 +3007,15 @@ class MessagesManager final : public Actor { bool need_channel_difference_to_add_message(DialogId dialog_id, const tl_object_ptr &message_ptr); - void run_after_channel_difference(DialogId dialog_id, MessageId expected_max_message_id, Promise &&promise); + bool need_channel_difference_to_add_message(DialogId dialog_id, MessageId message_id); + + void run_after_channel_difference(DialogId dialog_id, MessageId expected_max_message_id, Promise &&promise, + const char *source); bool running_get_channel_difference(DialogId dialog_id) const; + void retry_get_channel_difference_later(DialogId dialog_id); + void on_channel_get_difference_timeout(DialogId dialog_id); void update_expected_channel_pts(DialogId dialog_id, int32 expected_pts); @@ -3010,7 +3023,7 @@ class MessagesManager final : public Actor { void update_expected_channel_max_message_id(DialogId dialog_id, MessageId expected_max_message_id); void schedule_get_channel_difference(DialogId dialog_id, int32 expected_pts, MessageId expected_max_message_id, - double delay); + double delay, const char *source); void get_channel_difference(DialogId dialog_id, int32 pts, int32 expected_pts, MessageId expected_max_message_id, bool force, const char *source, bool is_old = false); @@ -3050,16 +3063,16 @@ class MessagesManager final : public Actor { static void on_pending_send_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); - static void on_active_dialog_action_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); - - static void on_update_dialog_online_member_count_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); - static void on_preload_folder_dialog_list_timeout_callback(void *messages_manager_ptr, int64 folder_id_int); static void on_update_viewed_messages_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); static void on_send_update_chat_read_inbox_timeout_callback(void *messages_manager_ptr, int64 dialog_id_int); + static void on_live_location_expire_timeout_callback(void *messages_manager_ptr); + + void on_live_location_expire_timeout(); + void load_secret_thumbnail(FileId thumbnail_file_id); void on_upload_media(FileId file_id, tl_object_ptr input_file, @@ -3069,32 +3082,6 @@ class MessagesManager final : public Actor { void on_load_secret_thumbnail(FileId thumbnail_file_id, BufferSlice thumbnail); void on_upload_thumbnail(FileId thumbnail_file_id, tl_object_ptr thumbnail_input_file); - void on_upload_dialog_photo(FileId file_id, tl_object_ptr input_file); - void on_upload_dialog_photo_error(FileId file_id, Status status); - - void send_edit_dialog_photo_query(DialogId dialog_id, FileId file_id, - tl_object_ptr &&input_chat_photo, - Promise &&promise); - - void upload_imported_messages(DialogId dialog_id, FileId file_id, vector attached_file_ids, bool is_reupload, - Promise &&promise, vector bad_parts = {}); - - void on_upload_imported_messages(FileId file_id, tl_object_ptr input_file); - void on_upload_imported_messages_error(FileId file_id, Status status); - - void upload_imported_message_attachment(DialogId dialog_id, int64 import_id, FileId file_id, bool is_reupload, - Promise &&promise, vector bad_parts = {}); - - void on_upload_imported_message_attachment(FileId file_id, tl_object_ptr input_file); - void on_upload_imported_message_attachment_error(FileId file_id, Status status); - - void on_imported_message_attachments_uploaded(int64 random_id, Result &&result); - - Status can_import_messages(DialogId dialog_id); - - void send_get_message_public_forwards_query(DcId dc_id, FullMessageId full_message_id, string offset, int32 limit, - Promise> &&promise); - void add_sponsored_dialog(const Dialog *d, DialogSource source); void save_sponsored_dialog(); @@ -3103,6 +3090,8 @@ class MessagesManager final : public Actor { Dialog *get_service_notifications_dialog(); + static void extract_authentication_codes(DialogId dialog_id, const Message *m, vector &authentication_codes); + void save_auth_notification_ids(); MessageId get_next_message_id(Dialog *d, MessageType type) const; @@ -3127,7 +3116,7 @@ class MessagesManager final : public Actor { void update_forward_count(DialogId dialog_id, const Message *m); - void update_forward_count(DialogId dialog_id, MessageId message_id, int32 update_date); + void update_forward_count(MessageFullId message_full_id, int32 update_date); void update_has_outgoing_messages(DialogId dialog_id, const Message *m); @@ -3179,12 +3168,15 @@ class MessagesManager final : public Actor { static uint64 save_reorder_pinned_dialogs_on_server_log_event(FolderId folder_id, const vector &dialog_ids); + static uint64 save_toggle_dialog_view_as_messages_on_server_log_event(DialogId dialog_id, bool view_as_messages); + static uint64 save_toggle_dialog_is_marked_as_unread_on_server_log_event(DialogId dialog_id, bool is_marked_as_unread); static uint64 save_toggle_dialog_is_translatable_on_server_log_event(DialogId dialog_id, bool is_translatable); - static uint64 save_toggle_dialog_is_blocked_on_server_log_event(DialogId dialog_id, bool is_blocked); + static uint64 save_toggle_dialog_is_blocked_on_server_log_event(DialogId dialog_id, bool is_blocked, + bool is_blocked_for_stories); static uint64 save_read_message_contents_on_server_log_event(DialogId dialog_id, const vector &message_ids); @@ -3206,16 +3198,12 @@ class MessagesManager final : public Actor { void suffix_load_till_date(Dialog *d, int32 date, Promise promise); void suffix_load_till_message_id(Dialog *d, MessageId message_id, Promise promise); - bool is_group_dialog(DialogId dialog_id) const; - - bool is_forum_channel(DialogId dialog_id) const; - - bool is_broadcast_channel(DialogId dialog_id) const; - bool is_deleted_secret_chat(const Dialog *d) const; static int32 get_message_schedule_date(const Message *m); + static int32 get_message_original_date(const Message *m); + static DialogId get_message_original_sender(const Message *m); static DialogId get_message_sender(const Message *m); @@ -3225,28 +3213,27 @@ class MessagesManager final : public Actor { class UploadMediaCallback; class UploadThumbnailCallback; - class UploadDialogPhotoCallback; - class UploadImportedMessagesCallback; - class UploadImportedMessageAttachmentCallback; std::shared_ptr upload_media_callback_; std::shared_ptr upload_thumbnail_callback_; - std::shared_ptr upload_dialog_photo_callback_; - std::shared_ptr upload_imported_messages_callback_; - std::shared_ptr upload_imported_message_attachment_callback_; double last_channel_pts_jump_warning_time_ = 0; - FlatHashMap, FileIdHash> - being_uploaded_files_; // file_id -> message, thumbnail_file_id + struct UploadedFileInfo { + MessageFullId message_full_id; + FileId thumbnail_file_id; + int32 media_pos; + }; + FlatHashMap being_uploaded_files_; struct UploadedThumbnailInfo { - FullMessageId full_message_id; + MessageFullId message_full_id; FileId file_id; // original file file_id tl_object_ptr input_file; // original file InputFile + int32 media_pos; }; FlatHashMap being_uploaded_thumbnails_; // thumbnail_file_id -> ... struct UploadedSecretThumbnailInfo { - FullMessageId full_message_id; + MessageFullId message_full_id; FileId file_id; // original file file_id tl_object_ptr input_file; // original file InputEncryptedFile }; @@ -3257,10 +3244,10 @@ class MessagesManager final : public Actor { class TtlNode final : private HeapNode { public: TtlNode(DialogId dialog_id, MessageId message_id, bool by_ttl_period) - : full_message_id_(dialog_id, message_id), by_ttl_period_(by_ttl_period) { + : message_full_id_(dialog_id, message_id), by_ttl_period_(by_ttl_period) { } - FullMessageId full_message_id_; + MessageFullId message_full_id_; bool by_ttl_period_; HeapNode *as_heap_node() const { @@ -3271,12 +3258,12 @@ class MessagesManager final : public Actor { } bool operator==(const TtlNode &other) const { - return full_message_id_ == other.full_message_id_; + return message_full_id_ == other.message_full_id_ && by_ttl_period_ == other.by_ttl_period_; } }; struct TtlNodeHash { uint32 operator()(const TtlNode &ttl_node) const { - return FullMessageIdHash()(ttl_node.full_message_id_) * 2 + static_cast(ttl_node.by_ttl_period_); + return MessageFullIdHash()(ttl_node.message_full_id_) * 2 + static_cast(ttl_node.by_ttl_period_); } }; std::unordered_set ttl_nodes_; @@ -3289,71 +3276,15 @@ class MessagesManager final : public Actor { bool ttl_db_has_query_ = false; Slot ttl_db_slot_; - FlatHashMap being_sent_messages_; // message_random_id -> message + FlatHashMap being_sent_messages_; // message_random_id -> message - FlatHashMap update_message_ids_; // new_message_id -> temporary_id + FlatHashMap update_message_ids_; // new_message_id -> temporary_id FlatHashMap, DialogIdHash> update_scheduled_message_ids_; // new_message_id -> temporary_id const char *debug_add_message_to_dialog_fail_reason_ = ""; - struct UploadedDialogPhotoInfo { - DialogId dialog_id; - double main_frame_timestamp; - bool is_animation; - bool is_reupload; - Promise promise; - - UploadedDialogPhotoInfo(DialogId dialog_id, double main_frame_timestamp, bool is_animation, bool is_reupload, - Promise promise) - : dialog_id(dialog_id) - , main_frame_timestamp(main_frame_timestamp) - , is_animation(is_animation) - , is_reupload(is_reupload) - , promise(std::move(promise)) { - } - }; - FlatHashMap being_uploaded_dialog_photos_; - - struct UploadedImportedMessagesInfo { - DialogId dialog_id; - vector attached_file_ids; - bool is_reupload; - Promise promise; - - UploadedImportedMessagesInfo(DialogId dialog_id, vector &&attached_file_ids, bool is_reupload, - Promise &&promise) - : dialog_id(dialog_id) - , attached_file_ids(std::move(attached_file_ids)) - , is_reupload(is_reupload) - , promise(std::move(promise)) { - } - }; - FlatHashMap, FileIdHash> being_uploaded_imported_messages_; - - struct UploadedImportedMessageAttachmentInfo { - DialogId dialog_id; - int64 import_id; - bool is_reupload; - Promise promise; - - UploadedImportedMessageAttachmentInfo(DialogId dialog_id, int64 import_id, bool is_reupload, - Promise &&promise) - : dialog_id(dialog_id), import_id(import_id), is_reupload(is_reupload), promise(std::move(promise)) { - } - }; - FlatHashMap, FileIdHash> - being_uploaded_imported_message_attachments_; - - struct PendingMessageImport { - MultiPromiseActor upload_files_multipromise{"UploadAttachedFilesMultiPromiseActor"}; - DialogId dialog_id; - int64 import_id = 0; - Promise promise; - }; - FlatHashMap> pending_message_imports_; - struct PendingMessageGroupSend { DialogId dialog_id; size_t finished_count = 0; @@ -3363,14 +3294,22 @@ class MessagesManager final : public Actor { }; FlatHashMap pending_message_group_sends_; // media_album_id -> ... + struct PendingPaidMediaGroupSend { + size_t finished_count = 0; + vector is_finished; + vector results; + }; + FlatHashMap pending_paid_media_group_sends_; + WaitFreeHashMap message_id_to_dialog_id_; FlatHashMap last_clear_history_message_id_to_dialog_id_; - bool created_public_broadcasts_inited_ = false; - vector created_public_broadcasts_; - - FlatHashMap created_dialogs_; // random_id -> dialog_id - FlatHashMap, DialogIdHash> pending_created_dialogs_; // dialog_id -> promise + struct PendingCreatedDialog { + td_api::object_ptr failed_to_add_members_; + Promise> chat_promise_; + Promise> channel_promise_; + }; + FlatHashMap pending_created_dialogs_; bool running_get_difference_ = false; // true after before_get_difference and false after after_get_difference @@ -3386,23 +3325,8 @@ class MessagesManager final : public Actor { FlatHashMap> found_public_dialogs_; // TODO time bound cache FlatHashMap> found_on_server_dialogs_; // TODO time bound cache - struct CommonDialogs { - vector dialog_ids; - double receive_time = 0; - int32 total_count = 0; - bool is_outdated = false; - }; - FlatHashMap found_common_dialogs_; - - FlatHashMap get_dialog_message_by_date_results_; - - FlatHashMap> found_dialog_message_calendars_; FlatHashMap found_dialog_messages_; // random_id -> FoundDialogMessages FlatHashMap found_dialog_messages_dialog_id_; // random_id -> dialog_id - FlatHashMap found_messages_; // random_id -> FoundMessages - FlatHashMap found_call_messages_; // random_id -> FoundMessages - - FlatHashMap found_fts_messages_; // random_id -> FoundMessages struct MessageEmbeddingCodes { FlatHashMap embedding_codes_; @@ -3412,29 +3336,17 @@ class MessagesManager final : public Actor { FlatHashMap>, DialogIdHash> get_dialog_queries_; FlatHashMap get_dialog_query_log_event_id_; - FlatHashMap replied_by_yet_unsent_messages_; - FlatHashMap, FullMessageIdHash> replied_yet_unsent_messages_; + FlatHashMap replied_by_yet_unsent_messages_; + FlatHashMap, MessageFullIdHash> + replied_yet_unsent_messages_; - // full_message_id -> replies with media timestamps - FlatHashMap, FullMessageIdHash> - replied_by_media_timestamp_messages_; + // message_full_id -> replies with media timestamps + FlatHashMap, MessageFullIdHash> + message_to_replied_media_timestamp_messages_; - struct ActiveDialogAction { - MessageId top_thread_message_id; - DialogId typing_dialog_id; - DialogAction action; - double start_time; - - ActiveDialogAction(MessageId top_thread_message_id, DialogId typing_dialog_id, DialogAction action, - double start_time) - : top_thread_message_id(top_thread_message_id) - , typing_dialog_id(typing_dialog_id) - , action(std::move(action)) - , start_time(start_time) { - } - }; - - FlatHashMap, DialogIdHash> active_dialog_actions_; + // story_full_id -> replies with media timestamps + FlatHashMap, StoryFullIdHash> + story_to_replied_media_timestamp_messages_; FlatHashMap notification_group_id_to_dialog_id_; @@ -3445,6 +3357,7 @@ class MessagesManager final : public Actor { int64 current_pinned_dialog_order_ = static_cast(MIN_PINNED_DIALOG_DATE) << 32; + int64 current_dialog_list_unique_id_ = 0; std::unordered_map dialog_lists_; std::unordered_map dialog_folders_; @@ -3488,35 +3401,23 @@ class MessagesManager final : public Actor { MultiTimeout pending_unload_dialog_timeout_{"PendingUnloadDialogTimeout"}; MultiTimeout dialog_unmute_timeout_{"DialogUnmuteTimeout"}; MultiTimeout pending_send_dialog_action_timeout_{"PendingSendDialogActionTimeout"}; - MultiTimeout active_dialog_action_timeout_{"ActiveDialogActionTimeout"}; - MultiTimeout update_dialog_online_member_count_timeout_{"UpdateDialogOnlineMemberCountTimeout"}; MultiTimeout preload_folder_dialog_list_timeout_{"PreloadFolderDialogListTimeout"}; MultiTimeout update_viewed_messages_timeout_{"UpdateViewedMessagesTimeout"}; MultiTimeout send_update_chat_read_inbox_timeout_{"SendUpdateChatReadInboxTimeout"}; + Timeout live_location_expire_timeout_; + Hints dialogs_hints_; // search dialogs by title and usernames - FlatHashSet active_live_location_full_message_ids_; + FlatHashSet active_live_location_message_full_ids_; bool are_active_live_location_messages_loaded_ = false; vector> load_active_live_location_messages_queries_; FlatHashMap>, DialogIdHash> load_scheduled_messages_from_database_queries_; - struct ResolvedUsername { - DialogId dialog_id; - double expires_at = 0.0; - - ResolvedUsername() = default; - ResolvedUsername(DialogId dialog_id, double expires_at) : dialog_id(dialog_id), expires_at(expires_at) { - } - }; - - WaitFreeHashMap resolved_usernames_; - WaitFreeHashMap inaccessible_resolved_usernames_; - FlatHashSet reload_voice_chat_on_search_usernames_; - struct GetDialogsTask { DialogListId dialog_list_id; + int64 dialog_list_unique_id; int32 limit; int32 retry_count; DialogDate last_dialog_date = MIN_DIALOG_DATE; @@ -3544,9 +3445,17 @@ class MessagesManager final : public Actor { FlatHashMap, DialogIdHash> pending_secret_message_ids_; // random_id -> message_id - FlatHashMap, DialogIdHash> pending_add_dialog_last_database_message_dependent_dialogs_; - FlatHashMap>, DialogIdHash> - pending_add_dialog_last_database_message_; // dialog -> dependency counter + message + struct AddDialogData { + int32 dependent_dialog_count_ = 0; + unique_ptr last_message_; + unique_ptr draft_message_; + + AddDialogData() = default; + AddDialogData(int32 dependent_dialog_count, unique_ptr &&last_message, + unique_ptr &&draft_message); + }; + FlatHashMap, DialogIdHash> pending_add_dialog_dependent_dialogs_; + FlatHashMap pending_add_dialog_data_; FlatHashMap, DialogIdHash> pending_add_default_join_group_call_as_dialog_id_; // dialog_id -> dependent dialogs @@ -3573,7 +3482,7 @@ class MessagesManager final : public Actor { CallsDbState calls_db_state_; int64 viewed_live_location_task_id_ = 0; - FlatHashMap viewed_live_location_tasks_; // task_id -> task + FlatHashMap viewed_live_location_tasks_; // task_id -> task FlatHashMap, DialogIdHash> pending_viewed_live_locations_; // ... -> task_id @@ -3583,9 +3492,7 @@ class MessagesManager final : public Actor { }; FlatHashMap yet_unsent_media_queues_; - FlatHashMap set_typing_query_; - - WaitFreeHashMap full_message_id_to_file_source_id_; + WaitFreeHashMap message_full_id_to_file_source_id_; FlatHashMap last_outgoing_forwarded_message_date_; @@ -3596,27 +3503,22 @@ class MessagesManager final : public Actor { }; FlatHashMap, DialogIdHash> dialog_viewed_messages_; - struct OnlineMemberCountInfo { - int32 online_member_count = 0; - double update_time = 0; - bool is_update_sent = false; - }; - FlatHashMap dialog_online_member_counts_; - struct ReactionsToReload { FlatHashSet message_ids; bool is_request_sent = false; }; FlatHashMap being_reloaded_reactions_; + FlatHashSet being_reloaded_fact_checks_; + FlatHashMap, DialogIdHash> pending_dialog_group_call_updates_; FlatHashMap auth_notification_id_date_; FlatHashMap previous_repaired_read_inbox_max_message_id_; - FlatHashMap yet_unsent_full_message_id_to_persistent_message_id_; - FlatHashMap, FullMessageIdHash> + FlatHashMap yet_unsent_message_full_id_to_persistent_message_id_; + FlatHashMap, MessageFullIdHash> yet_unsent_thread_message_ids_; // {dialog_id, top_thread_message_id} -> yet unsent message IDs FlatHashMap, DialogIdHash> dialog_suffix_load_queries_; @@ -3636,12 +3538,14 @@ class MessagesManager final : public Actor { int32 query_count = 0; bool was_updated = false; }; - FlatHashMap pending_reactions_; + FlatHashMap pending_reactions_; + + FlatHashMap pending_read_reactions_; - FlatHashMap pending_read_reactions_; + vector active_reaction_types_; + FlatHashMap active_reaction_pos_; - vector active_reactions_; - FlatHashMap active_reaction_pos_; + FlatHashMap>, PendingGetHistoryQueryHash> get_history_queries_; uint32 scheduled_messages_sync_generation_ = 1; @@ -3651,7 +3555,7 @@ class MessagesManager final : public Actor { DialogId sponsored_dialog_id_; DialogSource sponsored_dialog_source_; - FullMessageId being_readded_message_id_; + MessageFullId being_readded_message_id_; DialogId being_added_dialog_id_; DialogId being_added_by_new_message_dialog_id_; @@ -3663,6 +3567,7 @@ class MessagesManager final : public Actor { double start_time_ = 0; bool is_inited_ = false; + int create_folders_source_ = 0; Td *td_; ActorShared<> parent_; diff --git a/protocols/Telegram/tdlib/td/td/telegram/MinChannel.h b/protocols/Telegram/tdlib/td/td/telegram/MinChannel.h index 5d2b25c68f..ea2fdb22c0 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MinChannel.h +++ b/protocols/Telegram/tdlib/td/td/telegram/MinChannel.h @@ -1,11 +1,12 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once +#include "td/telegram/AccentColorId.h" #include "td/telegram/Photo.h" #include "td/utils/common.h" @@ -15,6 +16,7 @@ namespace td { struct MinChannel { string title_; DialogPhoto photo_; + AccentColorId accent_color_id_; bool is_megagroup_ = false; }; diff --git a/protocols/Telegram/tdlib/td/td/telegram/MinChannel.hpp b/protocols/Telegram/tdlib/td/td/telegram/MinChannel.hpp index b5e40c50af..4b8f1f2592 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/MinChannel.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/MinChannel.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -18,10 +18,12 @@ template void store(const MinChannel &min_channel, StorerT &storer) { bool has_title = !min_channel.title_.empty(); bool has_photo = min_channel.photo_.small_file_id.is_valid(); + bool has_accent_color_id = min_channel.accent_color_id_.is_valid(); BEGIN_STORE_FLAGS(); STORE_FLAG(has_title); STORE_FLAG(has_photo); STORE_FLAG(min_channel.is_megagroup_); + STORE_FLAG(has_accent_color_id); END_STORE_FLAGS(); if (has_title) { store(min_channel.title_, storer); @@ -29,16 +31,21 @@ void store(const MinChannel &min_channel, StorerT &storer) { if (has_photo) { store(min_channel.photo_, storer); } + if (has_accent_color_id) { + store(min_channel.accent_color_id_, storer); + } } template void parse(MinChannel &min_channel, ParserT &parser) { bool has_title; bool has_photo; + bool has_accent_color_id; BEGIN_PARSE_FLAGS(); PARSE_FLAG(has_title); PARSE_FLAG(has_photo); PARSE_FLAG(min_channel.is_megagroup_); + PARSE_FLAG(has_accent_color_id); END_PARSE_FLAGS(); if (has_title) { parse(min_channel.title_, parser); @@ -46,6 +53,9 @@ void parse(MinChannel &min_channel, ParserT &parser) { if (has_photo) { parse(min_channel.photo_, parser); } + if (has_accent_color_id) { + parse(min_channel.accent_color_id_, parser); + } } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MissingInvitee.cpp b/protocols/Telegram/tdlib/td/td/telegram/MissingInvitee.cpp new file mode 100644 index 0000000000..2d83021d50 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MissingInvitee.cpp @@ -0,0 +1,57 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/MissingInvitee.h" + +#include "td/telegram/UserManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/format.h" +#include "td/utils/logging.h" + +namespace td { + +MissingInvitee::MissingInvitee(telegram_api::object_ptr &&invitee) + : user_id_(invitee->user_id_) + , premium_would_allow_invite_(invitee->premium_would_allow_invite_) + , premium_required_for_pm_(invitee->premium_required_for_pm_) { +} + +td_api::object_ptr MissingInvitee::get_failed_to_add_member_object( + UserManager *user_manager) const { + return td_api::make_object( + user_manager->get_user_id_object(user_id_, "get_failed_to_add_member_object"), premium_would_allow_invite_, + premium_required_for_pm_); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MissingInvitee &invitee) { + return string_builder << '[' << invitee.user_id_ << ' ' << invitee.premium_would_allow_invite_ << ' ' + << invitee.premium_required_for_pm_ << ']'; +} + +MissingInvitees::MissingInvitees(vector> &&invitees) { + for (auto &invitee : invitees) { + missing_invitees_.emplace_back(std::move(invitee)); + if (!missing_invitees_.back().is_valid()) { + LOG(ERROR) << "Receive invalid " << missing_invitees_.back() << " as a missing invitee"; + missing_invitees_.pop_back(); + } + } +} + +td_api::object_ptr MissingInvitees::get_failed_to_add_members_object( + UserManager *user_manager) const { + return td_api::make_object( + transform(missing_invitees_, [user_manager](const MissingInvitee &message_invitee) { + return message_invitee.get_failed_to_add_member_object(user_manager); + })); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const MissingInvitees &invitees) { + return string_builder << invitees.missing_invitees_; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/MissingInvitee.h b/protocols/Telegram/tdlib/td/td/telegram/MissingInvitee.h new file mode 100644 index 0000000000..73ff7a7577 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/MissingInvitee.h @@ -0,0 +1,54 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class UserManager; + +class MissingInvitee { + UserId user_id_; + bool premium_would_allow_invite_ = false; + bool premium_required_for_pm_ = false; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MissingInvitee &invitee); + + public: + explicit MissingInvitee(telegram_api::object_ptr &&invitee); + + bool is_valid() const { + return user_id_.is_valid(); + } + + td_api::object_ptr get_failed_to_add_member_object(UserManager *user_manager) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const MissingInvitee &invitee); + +class MissingInvitees { + vector missing_invitees_; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const MissingInvitees &invitees); + + public: + MissingInvitees() = default; + + explicit MissingInvitees(vector> &&invitees); + + td_api::object_ptr get_failed_to_add_members_object(UserManager *user_manager) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const MissingInvitees &invitees); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Notification.h b/protocols/Telegram/tdlib/td/td/telegram/Notification.h index 20698114bf..966ee540a9 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Notification.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Notification.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -31,12 +31,12 @@ class Notification { } }; -inline td_api::object_ptr get_notification_object(DialogId dialog_id, +inline td_api::object_ptr get_notification_object(Td *td, DialogId dialog_id, const Notification ¬ification) { CHECK(notification.type != nullptr); return td_api::make_object(notification.notification_id.get(), notification.date, notification.disable_notification, - notification.type->get_notification_type_object(dialog_id)); + notification.type->get_notification_type_object(td, dialog_id)); } inline StringBuilder &operator<<(StringBuilder &sb, const Notification ¬ification) { diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupFromDatabase.h b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupFromDatabase.h new file mode 100644 index 0000000000..ae7774fcc5 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupFromDatabase.h @@ -0,0 +1,24 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/Notification.h" +#include "td/telegram/NotificationGroupType.h" + +#include "td/utils/common.h" + +namespace td { + +struct NotificationGroupFromDatabase { + DialogId dialog_id; + NotificationGroupType type = NotificationGroupType::Calls; + int32 total_count = 0; + vector notifications; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.cpp new file mode 100644 index 0000000000..781fbb2415 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.cpp @@ -0,0 +1,133 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/NotificationGroupInfo.h" + +#include "td/telegram/NotificationManager.h" + +#include "td/utils/logging.h" + +namespace td { + +bool NotificationGroupInfo::set_last_notification(int32 last_notification_date, NotificationId last_notification_id, + const char *source) { + if (is_removed_notification_id(last_notification_id)) { + last_notification_id = NotificationId(); + last_notification_date = 0; + } + if (last_notification_date_ != last_notification_date || last_notification_id_ != last_notification_id) { + VLOG(notifications) << "Set " << group_id_ << " last notification to " << last_notification_id << " sent at " + << last_notification_date << " from " << source; + if (last_notification_date_ != last_notification_date) { + last_notification_date_ = last_notification_date; + is_key_changed_ = true; + } + last_notification_id_ = last_notification_id; + return true; + } + return false; +} + +bool NotificationGroupInfo::set_max_removed_notification_id(NotificationId max_removed_notification_id, + NotificationObjectId max_removed_object_id, + const char *source) { + if (max_removed_notification_id.get() <= max_removed_notification_id_.get()) { + return false; + } + if (max_removed_object_id > max_removed_object_id_) { + VLOG(notifications) << "Set max_removed_object_id in " << group_id_ << " to " << max_removed_object_id << " from " + << source; + max_removed_object_id_ = max_removed_object_id; + } + + VLOG(notifications) << "Set max_removed_notification_id in " << group_id_ << " to " << max_removed_notification_id + << " from " << source; + max_removed_notification_id_ = max_removed_notification_id; + + if (last_notification_id_.is_valid() && is_removed_notification_id(last_notification_id_)) { + last_notification_id_ = NotificationId(); + last_notification_date_ = 0; + is_key_changed_ = true; + } + + return true; +} + +void NotificationGroupInfo::drop_max_removed_notification_id() { + if (!max_removed_notification_id_.is_valid()) { + return; + } + + VLOG(notifications) << "Drop max_removed_notification_id in " << group_id_; + max_removed_object_id_ = {}; + max_removed_notification_id_ = NotificationId(); +} + +bool NotificationGroupInfo::is_removed_notification(NotificationId notification_id, + NotificationObjectId object_id) const { + return is_removed_notification_id(notification_id) || is_removed_object_id(object_id); +} + +bool NotificationGroupInfo::is_removed_notification_id(NotificationId notification_id) const { + return notification_id.get() <= max_removed_notification_id_.get(); +} + +bool NotificationGroupInfo::is_removed_object_id(NotificationObjectId object_id) const { + return object_id <= max_removed_object_id_; +} + +bool NotificationGroupInfo::is_used_notification_id(NotificationId notification_id) const { + return notification_id.get() <= max_removed_notification_id_.get() || + notification_id.get() <= last_notification_id_.get(); +} + +void NotificationGroupInfo::try_reuse() { + CHECK(is_valid()); + CHECK(last_notification_date_ == 0); + if (!try_reuse_) { + try_reuse_ = true; + is_key_changed_ = true; + } +} + +void NotificationGroupInfo::add_group_key_if_changed(vector &group_keys, DialogId dialog_id) { + if (!is_key_changed_) { + return; + } + is_key_changed_ = false; + + group_keys.emplace_back(group_id_, try_reuse_ ? DialogId() : dialog_id, last_notification_date_); +} + +NotificationGroupId NotificationGroupInfo::get_reused_group_id() { + if (!try_reuse_) { + return {}; + } + if (is_key_changed_) { + LOG(ERROR) << "Failed to reuse changed " << group_id_; + return {}; + } + try_reuse_ = false; + if (!is_valid()) { + LOG(ERROR) << "Failed to reuse invalid " << group_id_; + return {}; + } + CHECK(last_notification_id_ == NotificationId()); + CHECK(last_notification_date_ == 0); + auto result = group_id_; + group_id_ = NotificationGroupId(); + max_removed_notification_id_ = NotificationId(); + max_removed_object_id_ = {}; + return result; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const NotificationGroupInfo &group_info) { + return string_builder << group_info.group_id_ << " with last " << group_info.last_notification_id_ << " sent at " + << group_info.last_notification_date_ << ", max removed " + << group_info.max_removed_notification_id_ << '/' << group_info.max_removed_object_id_; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.h b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.h new file mode 100644 index 0000000000..ddc8438c9e --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.h @@ -0,0 +1,87 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/NotificationGroupId.h" +#include "td/telegram/NotificationGroupKey.h" +#include "td/telegram/NotificationId.h" +#include "td/telegram/NotificationObjectId.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class NotificationGroupInfo { + NotificationGroupId group_id_; + int32 last_notification_date_ = 0; // date of the last notification in the group + NotificationId last_notification_id_; // identifier of the last notification in the group + NotificationId max_removed_notification_id_; // notification identifier, up to which all notifications are removed + NotificationObjectId max_removed_object_id_; // object identifier, up to which all notifications are removed + bool is_key_changed_ = false; // true, if the group needs to be saved to database + bool try_reuse_ = false; // true, if the group needs to be deleted from database and tried to be reused + + friend StringBuilder &operator<<(StringBuilder &string_builder, const NotificationGroupInfo &group_info); + + public: + NotificationGroupInfo() = default; + + explicit NotificationGroupInfo(NotificationGroupId group_id) : group_id_(group_id), is_key_changed_(true) { + } + + bool is_valid() const { + return group_id_.is_valid(); + } + + bool is_active() const { + return is_valid() && !try_reuse_; + } + + NotificationGroupId get_group_id() const { + return group_id_; + } + + bool has_group_id(NotificationGroupId group_id) const { + return group_id_ == group_id; + } + + NotificationId get_last_notification_id() const { + return last_notification_id_; + } + + bool set_last_notification(int32 last_notification_date, NotificationId last_notification_id, const char *source); + + bool set_max_removed_notification_id(NotificationId max_removed_notification_id, + NotificationObjectId max_removed_object_id, const char *source); + + void drop_max_removed_notification_id(); + + bool is_removed_notification(NotificationId notification_id, NotificationObjectId object_id) const; + + bool is_removed_notification_id(NotificationId notification_id) const; + + bool is_removed_object_id(NotificationObjectId object_id) const; + + bool is_used_notification_id(NotificationId notification_id) const; + + void try_reuse(); + + void add_group_key_if_changed(vector &group_keys, DialogId dialog_id); + + NotificationGroupId get_reused_group_id(); + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const NotificationGroupInfo &group_info); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.hpp b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.hpp new file mode 100644 index 0000000000..f62f2c2fd0 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupInfo.hpp @@ -0,0 +1,39 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/NotificationGroupInfo.h" +#include "td/telegram/Version.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void NotificationGroupInfo::store(StorerT &storer) const { + using td::store; + store(group_id_, storer); + store(last_notification_date_, storer); + store(last_notification_id_, storer); + store(max_removed_notification_id_, storer); + store(max_removed_object_id_, storer); +} + +template +void NotificationGroupInfo::parse(ParserT &parser) { + using td::parse; + parse(group_id_, parser); + parse(last_notification_date_, parser); + parse(last_notification_id_, parser); + parse(max_removed_notification_id_, parser); + if (parser.version() >= static_cast(Version::AddNotificationGroupInfoMaxRemovedMessageId)) { + parse(max_removed_object_id_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupType.cpp b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupType.cpp new file mode 100644 index 0000000000..510ec3c0b2 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupType.cpp @@ -0,0 +1,88 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/NotificationGroupType.h" + +namespace td { + +bool is_database_notification_group_type(NotificationGroupType type) { + switch (type) { + case NotificationGroupType::Messages: + case NotificationGroupType::Mentions: + case NotificationGroupType::SecretChat: + return true; + case NotificationGroupType::Calls: + return false; + default: + UNREACHABLE(); + return false; + } +} + +bool is_partial_notification_group_type(NotificationGroupType type) { + switch (type) { + case NotificationGroupType::Messages: + case NotificationGroupType::Mentions: + return true; + case NotificationGroupType::SecretChat: + case NotificationGroupType::Calls: + return false; + default: + UNREACHABLE(); + return false; + } +} + +td_api::object_ptr get_notification_group_type_object(NotificationGroupType type) { + switch (type) { + case NotificationGroupType::Messages: + return td_api::make_object(); + case NotificationGroupType::Mentions: + return td_api::make_object(); + case NotificationGroupType::SecretChat: + return td_api::make_object(); + case NotificationGroupType::Calls: + return td_api::make_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +NotificationGroupType get_notification_group_type(const td_api::object_ptr &type) { + CHECK(type != nullptr); + switch (type->get_id()) { + case td_api::notificationGroupTypeMessages::ID: + return NotificationGroupType::Messages; + case td_api::notificationGroupTypeMentions::ID: + return NotificationGroupType::Mentions; + case td_api::notificationGroupTypeSecretChat::ID: + return NotificationGroupType::SecretChat; + case td_api::notificationGroupTypeCalls::ID: + return NotificationGroupType::Calls; + default: + UNREACHABLE(); + return NotificationGroupType::Calls; + } +} + +StringBuilder &operator<<(StringBuilder &string_builder, const NotificationGroupType &type) { + switch (type) { + case NotificationGroupType::Messages: + return string_builder << "Messages"; + case NotificationGroupType::Mentions: + return string_builder << "Mentions"; + case NotificationGroupType::SecretChat: + return string_builder << "SecretChat"; + case NotificationGroupType::Calls: + return string_builder << "Calls"; + default: + UNREACHABLE(); + return string_builder; + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupType.h b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupType.h index 795346c16d..543ef46c6d 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupType.h +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationGroupType.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,55 +15,14 @@ namespace td { enum class NotificationGroupType : int8 { Messages, Mentions, SecretChat, Calls }; -inline td_api::object_ptr get_notification_group_type_object( - NotificationGroupType type) { - switch (type) { - case NotificationGroupType::Messages: - return td_api::make_object(); - case NotificationGroupType::Mentions: - return td_api::make_object(); - case NotificationGroupType::SecretChat: - return td_api::make_object(); - case NotificationGroupType::Calls: - return td_api::make_object(); - default: - UNREACHABLE(); - return nullptr; - } -} +bool is_database_notification_group_type(NotificationGroupType type); -inline NotificationGroupType get_notification_group_type( - const td_api::object_ptr &type) { - CHECK(type != nullptr); - switch (type->get_id()) { - case td_api::notificationGroupTypeMessages::ID: - return NotificationGroupType::Messages; - case td_api::notificationGroupTypeMentions::ID: - return NotificationGroupType::Mentions; - case td_api::notificationGroupTypeSecretChat::ID: - return NotificationGroupType::SecretChat; - case td_api::notificationGroupTypeCalls::ID: - return NotificationGroupType::Calls; - default: - UNREACHABLE(); - return NotificationGroupType::Calls; - } -} +bool is_partial_notification_group_type(NotificationGroupType type); -inline StringBuilder &operator<<(StringBuilder &sb, const NotificationGroupType &type) { - switch (type) { - case NotificationGroupType::Messages: - return sb << "Messages"; - case NotificationGroupType::Mentions: - return sb << "Mentions"; - case NotificationGroupType::SecretChat: - return sb << "SecretChat"; - case NotificationGroupType::Calls: - return sb << "Calls"; - default: - UNREACHABLE(); - return sb; - } -} +td_api::object_ptr get_notification_group_type_object(NotificationGroupType type); + +NotificationGroupType get_notification_group_type(const td_api::object_ptr &type); + +StringBuilder &operator<<(StringBuilder &string_builder, const NotificationGroupType &type); } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/NotificationManager.cpp index 2bc46e15b6..f224acc1f1 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/NotificationManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,8 +9,8 @@ #include "td/telegram/AuthManager.h" #include "td/telegram/ChannelId.h" #include "td/telegram/ChatId.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/DeviceTokenManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Document.h" #include "td/telegram/Document.hpp" #include "td/telegram/DocumentsManager.h" @@ -21,18 +21,22 @@ #include "td/telegram/misc.h" #include "td/telegram/net/ConnectionCreator.h" #include "td/telegram/net/DcId.h" +#include "td/telegram/OnlineManager.h" #include "td/telegram/OptionManager.h" #include "td/telegram/Photo.h" #include "td/telegram/Photo.hpp" #include "td/telegram/SecretChatId.h" #include "td/telegram/ServerMessageId.h" +#include "td/telegram/StarManager.h" #include "td/telegram/StateManager.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/StoryManager.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" #include "td/mtproto/AuthKey.h" -#include "td/mtproto/mtproto_api.h" #include "td/mtproto/PacketInfo.h" #include "td/mtproto/Transport.h" @@ -163,7 +167,7 @@ void NotificationManager::on_flush_pending_updates_timeout_callback(void *notifi } bool NotificationManager::is_disabled() const { - return !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot() || G()->close_flag(); + return G()->close_flag() || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot(); } StringBuilder &operator<<(StringBuilder &string_builder, const NotificationManager::ActiveNotificationsUpdate &update) { @@ -342,7 +346,7 @@ td_api::object_ptr NotificationManager::get_u vector> notifications; for (auto ¬ification : reversed(group.second.notifications)) { - auto notification_object = get_notification_object(group.first.dialog_id, notification); + auto notification_object = get_notification_object(td_, group.first.dialog_id, notification); if (notification_object->type_ != nullptr) { notifications.push_back(std::move(notification_object)); } @@ -354,7 +358,7 @@ td_api::object_ptr NotificationManager::get_u std::reverse(notifications.begin(), notifications.end()); groups.push_back(td_api::make_object( group.first.group_id.get(), get_notification_group_type_object(group.second.type), - td_->messages_manager_->get_chat_id_object(group.first.dialog_id, "updateActiveNotifications"), + td_->dialog_manager_->get_chat_id_object(group.first.dialog_id, "updateActiveNotifications"), group.second.total_count, std::move(notifications))); } } @@ -390,10 +394,18 @@ void NotificationManager::load_group_force(NotificationGroupId group_id) { return; } - auto group_it = get_group_force(group_id, true); + auto group_it = get_group_force(group_id); CHECK(group_it != groups_.end()); } +bool NotificationManager::have_group_force(NotificationGroupId group_id) { + if (is_disabled()) { + return false; + } + + return td::contains(call_notification_group_ids_, group_id) || get_group_force(group_id) != groups_.end(); +} + NotificationManager::NotificationGroups::iterator NotificationManager::get_group_force(NotificationGroupId group_id, bool send_update) { auto group_it = get_group(group_id); @@ -502,61 +514,55 @@ NotificationId NotificationManager::get_last_notification_id(const NotificationG return NotificationId(); } -MessageId NotificationManager::get_first_message_id(const NotificationGroup &group) { - // it's fine to return MessageId() if first notification has no message_id, because - // non-message notification can't be mixed with message notifications +NotificationObjectId NotificationManager::get_first_object_id(const NotificationGroup &group) { + // it's fine to return NotificationObjectId() if first notification has no object_id, because + // object_id is from the same scope within a notification group if (!group.notifications.empty()) { - return group.notifications[0].type->get_message_id(); + return group.notifications[0].type->get_object_id(); } if (!group.pending_notifications.empty()) { - return group.pending_notifications[0].type->get_message_id(); + return group.pending_notifications[0].type->get_object_id(); } - return MessageId(); + return NotificationObjectId(); } -MessageId NotificationManager::get_last_message_id(const NotificationGroup &group) { - // it's fine to return MessageId() if last notification has no message_id, because - // non-message notification can't be mixed with message notifications +NotificationObjectId NotificationManager::get_last_object_id(const NotificationGroup &group) { + // it's fine to return NotificationObjectId() if last notification has no object_id, because + // object_id is from the same scope within a notification group if (!group.pending_notifications.empty()) { - return group.pending_notifications.back().type->get_message_id(); + return group.pending_notifications.back().type->get_object_id(); } if (!group.notifications.empty()) { - return group.notifications.back().type->get_message_id(); + return group.notifications.back().type->get_object_id(); } - return MessageId(); + return NotificationObjectId(); } -MessageId NotificationManager::get_last_message_id_by_notification_id(const NotificationGroup &group, - NotificationId max_notification_id) { +NotificationObjectId NotificationManager::get_last_object_id_by_notification_id(const NotificationGroup &group, + NotificationId max_notification_id) { for (auto ¬ification : reversed(group.pending_notifications)) { if (notification.notification_id.get() <= max_notification_id.get()) { - auto message_id = notification.type->get_message_id(); - if (message_id.is_valid()) { - return message_id; + auto object_id = notification.type->get_object_id(); + if (object_id.is_valid()) { + return object_id; } } } for (auto ¬ification : reversed(group.notifications)) { if (notification.notification_id.get() <= max_notification_id.get()) { - auto message_id = notification.type->get_message_id(); - if (message_id.is_valid()) { - return message_id; + auto object_id = notification.type->get_object_id(); + if (object_id.is_valid()) { + return object_id; } } } - return MessageId(); + return NotificationObjectId(); } -void NotificationManager::load_message_notifications_from_database(const NotificationGroupKey &group_key, - NotificationGroup &group, size_t desired_size) { - if (!G()->use_message_database()) { - return; - } - if (group.is_loaded_from_database || group.is_being_loaded_from_database || - group.type == NotificationGroupType::Calls) { - return; - } - if (group.total_count == 0) { +void NotificationManager::load_notifications_from_database(const NotificationGroupKey &group_key, + NotificationGroup &group, size_t desired_size) { + if (!G()->use_message_database() || group.is_loaded_from_database || group.is_being_loaded_from_database || + group.total_count == 0 || !is_database_notification_group_type(group.type)) { return; } @@ -569,19 +575,32 @@ void NotificationManager::load_message_notifications_from_database(const Notific size_t limit = desired_size - group.notifications.size(); auto first_notification_id = get_first_notification_id(group); auto from_notification_id = first_notification_id.is_valid() ? first_notification_id : NotificationId::max(); - auto first_message_id = get_first_message_id(group); - auto from_message_id = first_message_id.is_valid() ? first_message_id : MessageId::max(); - send_closure(G()->messages_manager(), &MessagesManager::get_message_notifications_from_database, group_key.dialog_id, - group_key.group_id, from_notification_id, from_message_id, static_cast(limit), - PromiseCreator::lambda([actor_id = actor_id(this), group_id = group_key.group_id, - limit](Result> r_notifications) { - send_closure_later(actor_id, &NotificationManager::on_get_message_notifications_from_database, - group_id, limit, std::move(r_notifications)); - })); + auto first_object_id = get_first_object_id(group); + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this), group_id = group_key.group_id, limit](Result> r_notifications) { + send_closure_later(actor_id, &NotificationManager::on_get_notifications_from_database, group_id, limit, + std::move(r_notifications)); + }); + + switch (group.type) { + case NotificationGroupType::SecretChat: + case NotificationGroupType::Messages: + case NotificationGroupType::Mentions: { + auto from_message_id = first_object_id.is_valid() ? MessageId(first_object_id.get()) : MessageId::max(); + send_closure(G()->messages_manager(), &MessagesManager::get_message_notifications_from_database, + group_key.dialog_id, group_key.group_id, from_notification_id, from_message_id, + static_cast(limit), std::move(promise)); + break; + } + case NotificationGroupType::Calls: + default: + UNREACHABLE(); + break; + } } -void NotificationManager::on_get_message_notifications_from_database(NotificationGroupId group_id, size_t limit, - Result> r_notifications) { +void NotificationManager::on_get_notifications_from_database(NotificationGroupId group_id, size_t limit, + Result> r_notifications) { auto group_it = get_group(group_id); CHECK(group_it != groups_.end()); auto &group = group_it->second; @@ -602,14 +621,14 @@ void NotificationManager::on_get_message_notifications_from_database(Notificatio auto first_notification_id = get_first_notification_id(group); if (first_notification_id.is_valid()) { while (!notifications.empty() && notifications.back().notification_id.get() >= first_notification_id.get()) { - // possible if notifications was added after the database request was sent + // possible if notifications were added after the database request was sent notifications.pop_back(); } } - auto first_message_id = get_first_message_id(group); - if (first_message_id.is_valid()) { - while (!notifications.empty() && notifications.back().type->get_message_id() >= first_message_id) { - // possible if notifications was added after the database request was sent + auto first_object_id = get_first_object_id(group); + if (first_object_id.is_valid()) { + while (!notifications.empty() && notifications.back().type->get_object_id() >= first_object_id) { + // possible if notifications were added after the database request was sent notifications.pop_back(); } } @@ -619,7 +638,7 @@ void NotificationManager::on_get_message_notifications_from_database(Notificatio group_it = get_group(group_id); CHECK(group_it != groups_.end()); if (max_notification_group_size_ > group_it->second.notifications.size()) { - load_message_notifications_from_database(group_it->first, group_it->second, keep_notification_group_size_); + load_notifications_from_database(group_it->first, group_it->second, keep_notification_group_size_); } } @@ -627,8 +646,8 @@ void NotificationManager::add_notifications_to_group_begin(NotificationGroups::i vector notifications) { CHECK(group_it != groups_.end()); - td::remove_if(notifications, [dialog_id = group_it->first.dialog_id](const Notification ¬ification) { - return notification.type->get_notification_type_object(dialog_id) == nullptr; + td::remove_if(notifications, [td = td_, dialog_id = group_it->first.dialog_id](const Notification ¬ification) { + return notification.type->get_notification_type_object(td, dialog_id) == nullptr; }); if (notifications.empty()) { @@ -685,7 +704,7 @@ void NotificationManager::add_notifications_to_group_begin(NotificationGroups::i new_notifications.reserve(notifications.size()); added_notifications.reserve(notifications.size()); for (auto ¬ification : notifications) { - added_notifications.push_back(get_notification_object(group_key.dialog_id, notification)); + added_notifications.push_back(get_notification_object(td_, group_key.dialog_id, notification)); CHECK(added_notifications.back()->type_ != nullptr); new_notifications.push_back(std::move(notification)); } @@ -715,7 +734,7 @@ void NotificationManager::add_notifications_to_group_begin(NotificationGroups::i if (!added_notifications.empty()) { add_update_notification_group(td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup"), 0, 0, + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup"), 0, 0, group.total_count, std::move(added_notifications), vector())); } } @@ -826,8 +845,9 @@ int32 NotificationManager::get_notification_delay_ms(DialogId dialog_id, const P return MIN_NOTIFICATION_DELAY_MS; } + auto server_time = G()->server_time(); auto delay_ms = [&] { - auto online_info = td_->contacts_manager_->get_my_online_status(); + auto online_info = td_->user_manager_->get_my_online_status(); if (!online_info.is_online_local && online_info.is_online_remote) { // If we are offline, but online from some other client, then delay notification // for 'notification_cloud_delay' seconds. @@ -835,8 +855,8 @@ int32 NotificationManager::get_notification_delay_ms(DialogId dialog_id, const P } if (!online_info.is_online_local && - online_info.was_online_remote > max(static_cast(online_info.was_online_local), - G()->server_time_cached() - online_cloud_timeout_ms_ * 1e-3)) { + online_info.was_online_remote > + max(static_cast(online_info.was_online_local), server_time - online_cloud_timeout_ms_ * 1e-3)) { // If we are offline, but was online from some other client in last 'online_cloud_timeout' seconds // after we had gone offline, then delay notification for 'notification_cloud_delay' seconds. return notification_cloud_delay_ms_; @@ -851,8 +871,7 @@ int32 NotificationManager::get_notification_delay_ms(DialogId dialog_id, const P return 0; }(); - auto passed_time_ms = - static_cast(clamp(G()->server_time_cached() - notification.date - 1, 0.0, 1000000.0) * 1000); + auto passed_time_ms = static_cast(clamp(server_time - notification.date - 1, 0.0, 1000000.0) * 1000); return max(max(min_delay_ms, delay_ms) - passed_time_ms, MIN_NOTIFICATION_DELAY_MS); } @@ -895,14 +914,17 @@ void NotificationManager::add_notification(NotificationGroupId group_id, Notific on_notification_removed(notification_id); return; } - auto message_id = type->get_message_id(); - if (message_id.is_valid() && message_id <= get_last_message_id(group)) { + auto object_id = type->get_object_id(); + if (object_id.is_valid() && object_id <= get_last_object_id(group)) { LOG(ERROR) << "Failed to add " << notification_id << " of type " << *type << " to " << group_id << " of type " << group_type << " in " << dialog_id << ", because have already added notification about " - << get_last_message_id(group); + << get_last_object_id(group); on_notification_removed(notification_id); return; } + if (notification_settings_dialog_id != dialog_id) { + td_->dialog_manager_->force_create_dialog(notification_settings_dialog_id, "add_notification", true); + } PendingNotification notification; notification.date = date; @@ -1002,7 +1024,7 @@ void NotificationManager::add_update_notification_group(td_api::object_ptrtype_ == nullptr) { return; } @@ -1413,7 +1435,7 @@ bool NotificationManager::do_flush_pending_notifications(NotificationGroupKey &g for (auto &pending_notification : pending_notifications) { Notification notification(pending_notification.notification_id, pending_notification.date, pending_notification.disable_notification, std::move(pending_notification.type)); - added_notifications.push_back(get_notification_object(group_key.dialog_id, notification)); + added_notifications.push_back(get_notification_object(td_, group_key.dialog_id, notification)); CHECK(added_notifications.back()->type_ != nullptr); if (!notification.type->can_be_delayed()) { @@ -1440,9 +1462,9 @@ bool NotificationManager::do_flush_pending_notifications(NotificationGroupKey &g if (!added_notifications.empty()) { add_update_notification_group(td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 2"), - td_->messages_manager_->get_chat_id_object(pending_notifications[0].settings_dialog_id, - "updateNotificationGroup 3"), + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 2"), + td_->dialog_manager_->get_chat_id_object(pending_notifications[0].settings_dialog_id, + "updateNotificationGroup 3"), pending_notifications[0].ringtone_id, group.total_count, std::move(added_notifications), std::move(removed_notification_ids))); } else { @@ -1468,9 +1490,9 @@ td_api::object_ptr NotificationManager::get_rem } return td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 4"), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 10"), 0, - group.total_count, vector>(), std::move(removed_notification_ids)); + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 4"), + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 10"), 0, group.total_count, + vector>(), std::move(removed_notification_ids)); } void NotificationManager::send_remove_group_update(const NotificationGroupKey &group_key, @@ -1491,7 +1513,7 @@ void NotificationManager::send_add_group_update(const NotificationGroupKey &grou vector> added_notifications; added_notifications.reserve(added_size); for (size_t i = total_size - added_size; i < total_size; i++) { - added_notifications.push_back(get_notification_object(group_key.dialog_id, group.notifications[i])); + added_notifications.push_back(get_notification_object(td_, group_key.dialog_id, group.notifications[i])); if (added_notifications.back()->type_ == nullptr) { added_notifications.pop_back(); } @@ -1500,7 +1522,7 @@ void NotificationManager::send_add_group_update(const NotificationGroupKey &grou if (!added_notifications.empty()) { add_update_notification_group(td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 5"), 0, 0, + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 5"), 0, 0, group.total_count, std::move(added_notifications), vector())); } } @@ -1512,8 +1534,8 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_ } td::remove_if(group_it->second.pending_notifications, - [dialog_id = group_it->first.dialog_id](const PendingNotification &pending_notification) { - return pending_notification.type->get_notification_type_object(dialog_id) == nullptr; + [td = td_, dialog_id = group_it->first.dialog_id](const PendingNotification &pending_notification) { + return pending_notification.type->get_notification_type_object(td, dialog_id) == nullptr; }); if (group_it->second.pending_notifications.empty()) { @@ -1587,7 +1609,7 @@ void NotificationManager::flush_pending_notifications(NotificationGroupId group_ on_delayed_notification_update_count_changed(-1, group_id.get(), "flush_pending_notifications"); // if we can delete a lot of notifications simultaneously if (group.notifications.size() > keep_notification_group_size_ + EXTRA_GROUP_SIZE && - group.type != NotificationGroupType::Calls) { + is_database_notification_group_type(group.type)) { // keep only keep_notification_group_size_ last notifications in memory for (auto it = group.notifications.begin(); it != group.notifications.end() - keep_notification_group_size_; ++it) { on_notification_removed(it->notification_id); @@ -1645,7 +1667,7 @@ void NotificationManager::edit_notification(NotificationGroupId group_id, Notifi for (size_t i = 0; i < group.notifications.size(); i++) { auto ¬ification = group.notifications[i]; if (notification.notification_id == notification_id) { - if (notification.type->get_message_id() != type->get_message_id() || + if (notification.type->get_object_id() != type->get_object_id() || notification.type->is_temporary() != type->is_temporary()) { LOG(ERROR) << "Ignore edit of " << notification_id << " with " << *type << ", because previous type is " << *notification.type; @@ -1663,7 +1685,7 @@ void NotificationManager::edit_notification(NotificationGroupId group_id, Notifi } for (auto ¬ification : group.pending_notifications) { if (notification.notification_id == notification_id) { - if (notification.type->get_message_id() != type->get_message_id() || + if (notification.type->get_object_id() != type->get_object_id() || notification.type->is_temporary() != type->is_temporary()) { LOG(ERROR) << "Ignore edit of " << notification_id << " with " << *type << ", because previous type is " << *notification.type; @@ -1709,8 +1731,8 @@ void NotificationManager::on_notification_removed(NotificationId notification_id } temporary_notification_log_event_ids_.erase(add_it); - auto erased_notification_count = temporary_notifications_.erase(temporary_notification_message_ids_[notification_id]); - auto erased_message_id_count = temporary_notification_message_ids_.erase(notification_id); + auto erased_notification_count = temporary_notifications_.erase(temporary_notification_object_ids_[notification_id]); + auto erased_message_id_count = temporary_notification_object_ids_.erase(notification_id); CHECK(erased_notification_count > 0); CHECK(erased_message_id_count > 0); @@ -1756,7 +1778,7 @@ void NotificationManager::on_notifications_removed( // send update about empty invisible group anyway add_update_notification_group(td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 6"), 0, 0, 0, + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 6"), 0, 0, 0, vector>(), vector())); } else { VLOG(notifications) << "There is no need to send updateNotificationGroup about " << group_key.group_id; @@ -1766,7 +1788,7 @@ void NotificationManager::on_notifications_removed( // group is still visible add_update_notification_group(td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 7"), 0, 0, + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 7"), 0, 0, group.total_count, std::move(added_notifications), std::move(removed_notification_ids))); } else { // group needs to be removed @@ -1861,8 +1883,20 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti return promise.set_value(Unit()); } - if (!is_permanent && group_it->second.type != NotificationGroupType::Calls) { - td_->messages_manager_->remove_message_notification(group_it->first.dialog_id, group_id, notification_id); + if (!is_permanent) { + switch (group_it->second.type) { + case NotificationGroupType::Messages: + case NotificationGroupType::Mentions: + case NotificationGroupType::SecretChat: + td_->messages_manager_->remove_message_notification(group_it->first.dialog_id, group_id, notification_id); + break; + case NotificationGroupType::Calls: + // nothing to do + break; + default: + UNREACHABLE(); + break; + } } for (auto it = group_it->second.pending_notifications.begin(); it != group_it->second.pending_notifications.end(); @@ -1893,8 +1927,7 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti } } - bool have_all_notifications = group_it->second.type == NotificationGroupType::Calls || - group_it->second.type == NotificationGroupType::SecretChat; + bool have_all_notifications = !is_partial_notification_group_type(group_it->second.type); bool is_total_count_changed = false; if ((!have_all_notifications && is_permanent) || (have_all_notifications && is_found)) { if (group_it->second.total_count == 0) { @@ -1917,14 +1950,14 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti removed_notification_ids.push_back(notification_id.get()); if (old_group_size >= max_notification_group_size_ + 1) { added_notifications.push_back( - get_notification_object(group_it->first.dialog_id, + get_notification_object(td_, group_it->first.dialog_id, group_it->second.notifications[old_group_size - max_notification_group_size_ - 1])); if (added_notifications.back()->type_ == nullptr) { added_notifications.pop_back(); } } if (added_notifications.empty() && max_notification_group_size_ > group_it->second.notifications.size()) { - load_message_notifications_from_database(group_it->first, group_it->second, keep_notification_group_size_); + load_notifications_from_database(group_it->first, group_it->second, keep_notification_group_size_); } } @@ -1941,44 +1974,44 @@ void NotificationManager::remove_notification(NotificationGroupId group_id, Noti promise.set_value(Unit()); } -void NotificationManager::remove_temporary_notification_by_message_id(NotificationGroupId group_id, - MessageId message_id, bool force_update, - const char *source) { +void NotificationManager::remove_temporary_notification_by_object_id(NotificationGroupId group_id, + NotificationObjectId object_id, bool force_update, + const char *source) { if (!group_id.is_valid()) { return; } - VLOG(notifications) << "Remove notification for " << message_id << " in " << group_id << " from " << source; - CHECK(message_id.is_valid()); + VLOG(notifications) << "Remove notification for " << object_id << " in " << group_id << " from " << source; + CHECK(object_id.is_valid()); auto group_it = get_group(group_id); if (group_it == groups_.end()) { return; } - auto remove_notification_by_message_id = [&](auto ¬ifications) { + auto remove_notification_by_object_id = [&](auto ¬ifications) { for (auto ¬ification : notifications) { - if (notification.type->get_message_id() == message_id) { + if (notification.type->get_object_id() == object_id) { for (auto file_id : notification.type->get_file_ids(td_)) { - this->td_->file_manager_->delete_file(file_id, Promise<>(), "remove_temporary_notification_by_message_id"); + this->td_->file_manager_->delete_file(file_id, Promise<>(), "remove_temporary_notification_by_object_id"); } return this->remove_notification(group_id, notification.notification_id, true, force_update, Auto(), - "remove_temporary_notification_by_message_id"); + "remove_temporary_notification_by_object_id"); } } }; - remove_notification_by_message_id(group_it->second.pending_notifications); - remove_notification_by_message_id(group_it->second.notifications); + remove_notification_by_object_id(group_it->second.pending_notifications); + remove_notification_by_object_id(group_it->second.notifications); } void NotificationManager::remove_notification_group(NotificationGroupId group_id, NotificationId max_notification_id, - MessageId max_message_id, int32 new_total_count, bool force_update, - Promise &&promise) { + NotificationObjectId max_object_id, int32 new_total_count, + bool force_update, Promise &&promise) { if (!group_id.is_valid()) { return promise.set_error(Status::Error(400, "Group identifier is invalid")); } - if (!max_notification_id.is_valid() && !max_message_id.is_valid()) { + if (!max_notification_id.is_valid() && !max_object_id.is_valid()) { return promise.set_error(Status::Error(400, "Notification identifier is invalid")); } @@ -1990,7 +2023,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id remove_temporary_notifications(group_id, "remove_notification_group"); } - VLOG(notifications) << "Remove " << group_id << " up to " << max_notification_id << " or " << max_message_id + VLOG(notifications) << "Remove " << group_id << " up to " << max_notification_id << " or " << max_object_id << " with new_total_count = " << new_total_count << " and force_update = " << force_update; auto group_it = get_group_force(group_id); @@ -2003,10 +2036,20 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id if (max_notification_id.get() > current_notification_id_.get()) { max_notification_id = current_notification_id_; } - if (group_it->second.type != NotificationGroupType::Calls) { - td_->messages_manager_->remove_message_notifications( - group_it->first.dialog_id, group_id, max_notification_id, - get_last_message_id_by_notification_id(group_it->second, max_notification_id)); + switch (group_it->second.type) { + case NotificationGroupType::Messages: + case NotificationGroupType::Mentions: + case NotificationGroupType::SecretChat: + td_->messages_manager_->remove_message_notifications( + group_it->first.dialog_id, group_id, max_notification_id, + MessageId(get_last_object_id_by_notification_id(group_it->second, max_notification_id).get())); + break; + case NotificationGroupType::Calls: + // nothing to do + break; + default: + UNREACHABLE(); + break; } } @@ -2014,7 +2057,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id for (auto it = group_it->second.pending_notifications.begin(); it != group_it->second.pending_notifications.end(); ++it) { if (it->notification_id.get() <= max_notification_id.get() || - (max_message_id.is_valid() && it->type->get_message_id() <= max_message_id)) { + (max_object_id.is_valid() && it->type->get_object_id() <= max_object_id)) { pending_delete_end = it + 1; on_notification_removed(it->notification_id); } @@ -2043,7 +2086,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id for (size_t pos = 0; pos < notification_delete_end; pos++) { auto ¬ification = group_it->second.notifications[pos]; if (notification.notification_id.get() > max_notification_id.get() && - (!max_message_id.is_valid() || notification.type->get_message_id() > max_message_id)) { + (!max_object_id.is_valid() || notification.type->get_object_id() > max_object_id)) { notification_delete_end = pos; } else { on_notification_removed(notification.notification_id); @@ -2066,8 +2109,7 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id group_it->second.notifications.erase(group_it->second.notifications.begin(), group_it->second.notifications.begin() + notification_delete_end); } - if (group_it->second.type == NotificationGroupType::Calls || - group_it->second.type == NotificationGroupType::SecretChat) { + if (!is_partial_notification_group_type(group_it->second.type)) { new_total_count = static_cast(group_it->second.notifications.size()); } if (group_it->second.total_count == new_total_count) { @@ -2095,10 +2137,16 @@ void NotificationManager::remove_notification_group(NotificationGroupId group_id }); } else { remove_added_notifications_from_pending_updates( - group_id, [max_message_id](const td_api::object_ptr ¬ification) { - return notification->type_->get_id() == td_api::notificationTypeNewMessage::ID && - static_cast(notification->type_.get())->message_->id_ <= - max_message_id.get(); + group_id, [max_id = max_object_id.get()](const td_api::object_ptr ¬ification) { + const auto *type = notification->type_.get(); + switch (type->get_id()) { + case td_api::notificationTypeNewMessage::ID: + return static_cast(type)->message_->id_ <= max_id; + case td_api::notificationTypeNewPushMessage::ID: + return static_cast(type)->message_id_ <= max_id; + default: + return false; + } }); } @@ -2179,14 +2227,14 @@ void NotificationManager::remove_temporary_notifications(NotificationGroupId gro size_t added_notification_count = 0; for (size_t i = min(old_group_size - max_notification_group_size_, notification_pos); i-- > 0 && added_notification_count++ < removed_notification_ids.size();) { - added_notifications.push_back(get_notification_object(group_it->first.dialog_id, group.notifications[i])); + added_notifications.push_back(get_notification_object(td_, group_it->first.dialog_id, group.notifications[i])); if (added_notifications.back()->type_ == nullptr) { added_notifications.pop_back(); } } if (added_notification_count < removed_notification_ids.size() && max_notification_group_size_ > group.notifications.size()) { - load_message_notifications_from_database(group_it->first, group, keep_notification_group_size_); + load_notifications_from_database(group_it->first, group, keep_notification_group_size_); } std::reverse(added_notifications.begin(), added_notifications.end()); } @@ -2195,10 +2243,16 @@ void NotificationManager::remove_temporary_notifications(NotificationGroupId gro on_notifications_removed(std::move(group_it), std::move(added_notifications), std::move(removed_notification_ids), false); - remove_added_notifications_from_pending_updates( - group_id, [](const td_api::object_ptr ¬ification) { - return notification->get_id() == td_api::notificationTypeNewPushMessage::ID; - }); + remove_added_notifications_from_pending_updates(group_id, + [](const td_api::object_ptr ¬ification) { + const auto *type = notification->type_.get(); + switch (type->get_id()) { + case td_api::notificationTypeNewPushMessage::ID: + return true; + default: + return false; + } + }); } int32 NotificationManager::get_temporary_notification_total_count(const NotificationGroup &group) { @@ -2268,17 +2322,22 @@ vector NotificationManager::get_notification_group_message_ids(Notifi return {}; } + if (group_it->second.type != NotificationGroupType::Mentions && + group_it->second.type != NotificationGroupType::Messages) { + return {}; + } + vector message_ids; for (auto ¬ification : group_it->second.notifications) { - auto message_id = notification.type->get_message_id(); - if (message_id.is_valid()) { - message_ids.push_back(message_id); + auto object_id = notification.type->get_object_id(); + if (object_id.is_valid()) { + message_ids.push_back(MessageId(object_id.get())); } } for (auto ¬ification : group_it->second.pending_notifications) { - auto message_id = notification.type->get_message_id(); - if (message_id.is_valid()) { - message_ids.push_back(message_id); + auto object_id = notification.type->get_object_id(); + if (object_id.is_valid()) { + message_ids.push_back(MessageId(object_id.get())); } } @@ -2340,7 +2399,7 @@ void NotificationManager::add_call_notification(DialogId dialog_id, CallId call_ return; } - G()->td().get_actor_unsafe()->messages_manager_->force_create_dialog(dialog_id, "add_call_notification"); + td_->dialog_manager_->force_create_dialog(dialog_id, "add_call_notification"); auto &active_notifications = active_call_notifications_[dialog_id]; if (active_notifications.size() >= MAX_CALL_NOTIFICATIONS) { @@ -2524,7 +2583,7 @@ void NotificationManager::on_notification_group_size_max_changed() { CHECK(!removed_notification_ids.empty()); } else { if (new_max_notification_group_size_size_t > notification_count) { - load_message_notifications_from_database(group_key, group, new_keep_notification_group_size); + load_notifications_from_database(group_key, group, new_keep_notification_group_size); } if (notification_count <= max_notification_group_size_) { VLOG(notifications) << "There is no need to update " << group_key.group_id; @@ -2532,7 +2591,7 @@ void NotificationManager::on_notification_group_size_max_changed() { } for (size_t i = notification_count - min(notification_count, new_max_notification_group_size_size_t); i < notification_count - max_notification_group_size_; i++) { - added_notifications.push_back(get_notification_object(group_key.dialog_id, group.notifications[i])); + added_notifications.push_back(get_notification_object(td_, group_key.dialog_id, group.notifications[i])); if (added_notifications.back()->type_ == nullptr) { added_notifications.pop_back(); } @@ -2544,8 +2603,8 @@ void NotificationManager::on_notification_group_size_max_changed() { if (!is_destroyed_) { auto update = td_api::make_object( group_key.group_id.get(), get_notification_group_type_object(group.type), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 8"), - td_->messages_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 9"), 0, + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 8"), + td_->dialog_manager_->get_chat_id_object(group_key.dialog_id, "updateNotificationGroup 9"), 0, group.total_count, std::move(added_notifications), std::move(removed_notification_ids)); VLOG(notifications) << "Send " << as_notification_update(update.get()); send_closure(G()->td(), &Td::send_update, std::move(update)); @@ -2731,7 +2790,7 @@ void NotificationManager::process_push_notification(string payload, Promiseis_online()) { + if (!td_->online_manager_->is_online()) { // reset online flag to false to immediately check all connections aliveness send_closure(G()->state_manager(), &StateManager::on_online, false); } @@ -2775,6 +2834,9 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "MESSAGE_AUDIO") { return "MESSAGE_VOICE_NOTE"; } + if (loc_key == "PINNED_PAID_MEDIA") { + return "PINNED_MESSAGE_PAID_MEDIA"; + } break; case 'C': if (loc_key == "MESSAGE_CONTACT") { @@ -2830,6 +2892,15 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "MESSAGE_GIF") { return "MESSAGE_ANIMATION"; } + if (loc_key == "MESSAGE_GIFTCODE") { + return "MESSAGE_GIFTCODE"; + } + if (loc_key == "MESSAGE_GIVEAWAY") { + return "MESSAGE_GIVEAWAY"; + } + if (loc_key == "MESSAGE_GIVEAWAY_STARS") { + return "MESSAGE_GIVEAWAY_STARS"; + } break; case 'H': if (loc_key == "PINNED_PHOTO") { @@ -2843,6 +2914,12 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "PINNED_GIF") { return "PINNED_MESSAGE_ANIMATION"; } + if (loc_key == "PINNED_GIVEAWAY") { + return "PINNED_MESSAGE_GIVEAWAY"; + } + if (loc_key == "PINNED_GIVEAWAY_STARS") { + return "PINNED_MESSAGE_GIVEAWAY_STARS"; + } if (loc_key == "MESSAGE_INVOICE") { return "MESSAGE_INVOICE"; } @@ -2904,6 +2981,9 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "MESSAGE_POLL") { return "MESSAGE_POLL"; } + if (loc_key == "MESSAGE_PAID_MEDIA") { + return "MESSAGE_PAID_MEDIA"; + } break; case 'Q': if (loc_key == "MESSAGE_QUIZ") { @@ -2928,6 +3008,9 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "MESSAGE_STICKER") { return "MESSAGE_STICKER"; } + if (loc_key == "MESSAGE_STORY") { + return "MESSAGE_STORY"; + } if (loc_key == "MESSAGE_SUGGEST_PHOTO") { return "MESSAGE_SUGGEST_PHOTO"; } @@ -2942,6 +3025,9 @@ string NotificationManager::convert_loc_key(const string &loc_key) { if (loc_key == "PINNED_STICKER") { return "PINNED_MESSAGE_STICKER"; } + if (loc_key == "PINNED_STORY") { + return "PINNED_MESSAGE_STORY"; + } if (loc_key == "CHAT_PHOTO_EDITED") { return "MESSAGE_CHAT_CHANGE_PHOTO"; } @@ -2991,6 +3077,127 @@ string NotificationManager::convert_loc_key(const string &loc_key) { return string(); } +void NotificationManager::add_push_notification_user( + UserId sender_user_id, int64 sender_access_hash, const string &sender_name, + telegram_api::object_ptr &&sender_photo) { + int32 flags = USER_FLAG_IS_INACCESSIBLE; + if (sender_access_hash != -1) { + // set phone number flag to show that this is a full access hash + flags |= USER_FLAG_HAS_ACCESS_HASH | USER_FLAG_HAS_PHONE_NUMBER; + } else { + sender_access_hash = 0; + } + auto user_name = sender_user_id.get() == 136817688 ? "Channel" : sender_name; + auto user = telegram_api::make_object( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, 0, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, sender_user_id.get(), sender_access_hash, user_name, + string(), string(), string(), std::move(sender_photo), nullptr, 0, Auto(), string(), string(), nullptr, + vector>(), 0, nullptr, nullptr, 0); + td_->user_manager_->on_get_user(std::move(user), "add_push_notification_user"); +} + +Status NotificationManager::parse_push_notification_attach(DialogId dialog_id, string &loc_key, JsonObject &custom, + Photo &attached_photo, Document &attached_document) { + if (!custom.has_field("attachb64")) { + return Status::OK(); + } + TRY_RESULT(attachb64, custom.get_required_string_field("attachb64")); + TRY_RESULT(attach, base64url_decode(attachb64)); + + TlParser gzip_parser(attach); + int32 id = gzip_parser.fetch_int(); + if (gzip_parser.get_error()) { + return Status::Error(PSLICE() << "Failed to parse attach: " << gzip_parser.get_error()); + } + BufferSlice buffer; + static constexpr int32 GZIP_PACKED_ID = 812830625; + if (id == GZIP_PACKED_ID) { + auto packed_data = gzip_parser.template fetch_string(); + gzip_parser.fetch_end(); + if (gzip_parser.get_error()) { + return Status::Error(PSLICE() << "Failed to parse gzip_packed in attach: " << gzip_parser.get_error()); + } + buffer = gzdecode(packed_data); + if (buffer.empty()) { + return Status::Error("Failed to uncompress attach"); + } + } else { + buffer = BufferSlice(attach); + } + + TlBufferParser parser(&buffer); + auto result = telegram_api::Object::fetch(parser); + parser.fetch_end(); + const char *error = parser.get_error(); + if (error != nullptr) { + LOG(ERROR) << "Can't parse attach: " << Slice(error) << " at " << parser.get_error_pos() << ": " + << format::as_hex_dump<4>(Slice(attach)); + return Status::OK(); + } + switch (result->get_id()) { + case telegram_api::photo::ID: + if (ends_with(loc_key, "MESSAGE_PHOTO") || ends_with(loc_key, "MESSAGE_TEXT")) { + VLOG(notifications) << "Have attached photo"; + loc_key.resize(loc_key.rfind('_') + 1); + loc_key += "PHOTO"; + attached_photo = get_photo(td_, telegram_api::move_object_as(result), dialog_id); + } else { + LOG(ERROR) << "Receive attached photo for " << loc_key; + } + break; + case telegram_api::document::ID: { + if (ends_with(loc_key, "MESSAGE_ANIMATION") || ends_with(loc_key, "MESSAGE_AUDIO") || + ends_with(loc_key, "MESSAGE_DOCUMENT") || ends_with(loc_key, "MESSAGE_STICKER") || + ends_with(loc_key, "MESSAGE_VIDEO") || ends_with(loc_key, "MESSAGE_VIDEO_NOTE") || + ends_with(loc_key, "MESSAGE_VOICE_NOTE") || ends_with(loc_key, "MESSAGE_TEXT")) { + VLOG(notifications) << "Have attached document"; + attached_document = td_->documents_manager_->on_get_document( + telegram_api::move_object_as(result), dialog_id); + if (!attached_document.empty()) { + if (ends_with(loc_key, "_NOTE")) { + loc_key.resize(loc_key.rfind('_')); + } + loc_key.resize(loc_key.rfind('_') + 1); + + auto type = [attached_document] { + switch (attached_document.type) { + case Document::Type::Animation: + return "ANIMATION"; + case Document::Type::Audio: + return "AUDIO"; + case Document::Type::General: + return "DOCUMENT"; + case Document::Type::Sticker: + return "STICKER"; + case Document::Type::Video: + return "VIDEO"; + case Document::Type::VideoNote: + return "VIDEO_NOTE"; + case Document::Type::VoiceNote: + return "VOICE_NOTE"; + case Document::Type::Unknown: + default: + UNREACHABLE(); + return "UNREACHABLE"; + } + }(); + + loc_key += type; + } + } else { + LOG(ERROR) << "Receive attached document for " << loc_key; + } + break; + } + default: + LOG(ERROR) << "Receive unexpected attached " << to_string(result); + } + return Status::OK(); +} + Status NotificationManager::process_push_notification_payload(string payload, bool was_encrypted, Promise &promise) { VLOG(notifications) << "Process push notification payload " << payload; @@ -3006,73 +3213,59 @@ Status NotificationManager::process_push_notification_payload(string payload, bo auto data = std::move(json_value.get_object()); int32 sent_date = G()->unix_time(); - if (has_json_object_field(data, "data")) { - TRY_RESULT(date, get_json_object_int_field(data, "date", true, sent_date)); + if (data.has_field("data")) { + TRY_RESULT(date, data.get_optional_int_field("date", sent_date)); if (sent_date - 28 * 86400 <= date && date <= sent_date + 5) { sent_date = date; } - TRY_RESULT(data_data, get_json_object_field(data, "data", JsonValue::Type::Object, false)); + TRY_RESULT(data_data, data.extract_required_field("data", JsonValue::Type::Object)); data = std::move(data_data.get_object()); } - string loc_key; - JsonObject custom; - string announcement_message_text; + TRY_RESULT(loc_key, data.get_required_string_field("loc_key")); + if (!clean_input_string(loc_key)) { + return Status::Error(PSLICE() << "Receive invalid loc_key " << format::escaped(loc_key)); + } + if (loc_key.empty()) { + return Status::Error("Receive empty loc_key"); + } + vector loc_args; - string sender_name; - for (auto &field_value : data) { - if (field_value.first == "loc_key") { - if (field_value.second.type() != JsonValue::Type::String) { - return Status::Error("Expected loc_key as a String"); - } - loc_key = field_value.second.get_string().str(); - } else if (field_value.first == "loc_args") { - if (field_value.second.type() != JsonValue::Type::Array) { - return Status::Error("Expected loc_args as an Array"); - } - loc_args.reserve(field_value.second.get_array().size()); - for (auto &arg : field_value.second.get_array()) { - if (arg.type() != JsonValue::Type::String) { - return Status::Error("Expected loc_arg as a String"); - } - loc_args.push_back(arg.get_string().str()); - } - } else if (field_value.first == "custom") { - if (field_value.second.type() != JsonValue::Type::Object) { - return Status::Error("Expected custom as an Object"); - } - custom = std::move(field_value.second.get_object()); - } else if (field_value.first == "message") { - if (field_value.second.type() != JsonValue::Type::String) { - return Status::Error("Expected announcement message text as a String"); + TRY_RESULT(loc_args_array, data.extract_optional_field("loc_args", JsonValue::Type::Array)); + if (loc_args_array.type() == JsonValue::Type::Array) { + loc_args.reserve(loc_args_array.get_array().size()); + for (auto &arg : loc_args_array.get_array()) { + if (arg.type() != JsonValue::Type::String) { + return Status::Error("Expected loc_arg as a String"); } - announcement_message_text = field_value.second.get_string().str(); - } else if (field_value.first == "google.sent_time") { - TRY_RESULT(google_sent_time, get_json_object_long_field(data, "google.sent_time")); - google_sent_time /= 1000; - if (sent_date - 28 * 86400 <= google_sent_time && google_sent_time <= sent_date + 5) { - sent_date = narrow_cast(google_sent_time); + auto loc_arg = arg.get_string().str(); + if (!clean_input_string(loc_arg)) { + return Status::Error(PSLICE() << "Receive invalid loc_arg " << format::escaped(loc_arg)); } + loc_args.push_back(std::move(loc_arg)); } } - if (!clean_input_string(loc_key)) { - return Status::Error(PSLICE() << "Receive invalid loc_key " << format::escaped(loc_key)); - } - if (loc_key.empty()) { - return Status::Error("Receive empty loc_key"); + JsonObject custom; + TRY_RESULT(custom_value, data.extract_optional_field("custom", JsonValue::Type::Object)); + if (custom_value.type() == JsonValue::Type::Object) { + custom = std::move(custom_value.get_object()); } - for (auto &loc_arg : loc_args) { - if (!clean_input_string(loc_arg)) { - return Status::Error(PSLICE() << "Receive invalid loc_arg " << format::escaped(loc_arg)); + + TRY_RESULT(google_sent_time, data.get_optional_long_field("google.sent_time")); + if (google_sent_time > 0) { + google_sent_time /= 1000; + if (sent_date - 28 * 86400 <= google_sent_time && google_sent_time <= sent_date + 5) { + sent_date = narrow_cast(google_sent_time); } } + TRY_RESULT(announcement_message_text, data.get_optional_string_field("message")); if (loc_key == "MESSAGE_ANNOUNCEMENT") { if (announcement_message_text.empty()) { return Status::Error("Receive empty announcement message text"); } - TRY_RESULT(announcement_id, get_json_object_int_field(custom, "announcement")); + TRY_RESULT(announcement_id, custom.get_optional_int_field("announcement")); if (announcement_id == 0) { return Status::Error(200, "Receive unsupported announcement ID"); } @@ -3085,7 +3278,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo date = now; auto update = telegram_api::make_object( - telegram_api::updateServiceNotification::INBOX_DATE_MASK, false, G()->unix_time(), string(), + telegram_api::updateServiceNotification::INBOX_DATE_MASK, false, false, G()->unix_time(), string(), announcement_message_text, nullptr, vector>()); send_closure(G()->messages_manager(), &MessagesManager::on_update_service_notification, std::move(update), false, std::move(promise)); @@ -3097,13 +3290,13 @@ Status NotificationManager::process_push_notification_payload(string payload, bo } if (loc_key == "DC_UPDATE") { - TRY_RESULT(dc_id, get_json_object_int_field(custom, "dc", false)); - TRY_RESULT(addr, get_json_object_string_field(custom, "addr", false)); + TRY_RESULT(dc_id, custom.get_required_int_field("dc")); + TRY_RESULT(addr, custom.get_required_string_field("addr")); if (!DcId::is_valid(dc_id)) { - return Status::Error("Invalid datacenter ID"); + return Status::Error("Invalid datacenter identifier"); } if (!clean_input_string(addr)) { - return Status::Error(PSLICE() << "Receive invalid addr " << format::escaped(addr)); + return Status::Error(PSLICE() << "Receive invalid datacenter address " << format::escaped(addr)); } send_closure(G()->connection_creator(), &ConnectionCreator::on_dc_update, DcId::internal(dc_id), std::move(addr), std::move(promise)); @@ -3135,35 +3328,35 @@ Status NotificationManager::process_push_notification_payload(string payload, bo } DialogId dialog_id; - if (has_json_object_field(custom, "from_id")) { - TRY_RESULT(user_id_int, get_json_object_long_field(custom, "from_id")); + if (custom.has_field("from_id")) { + TRY_RESULT(user_id_int, custom.get_optional_long_field("from_id")); UserId user_id(user_id_int); if (!user_id.is_valid()) { - return Status::Error("Receive invalid user_id"); + return Status::Error("Receive invalid user identifier"); } dialog_id = DialogId(user_id); } - if (has_json_object_field(custom, "chat_id")) { - TRY_RESULT(chat_id_int, get_json_object_long_field(custom, "chat_id")); + if (custom.has_field("chat_id")) { + TRY_RESULT(chat_id_int, custom.get_optional_long_field("chat_id")); ChatId chat_id(chat_id_int); if (!chat_id.is_valid()) { - return Status::Error("Receive invalid chat_id"); + return Status::Error("Receive invalid basic group identifier"); } dialog_id = DialogId(chat_id); } - if (has_json_object_field(custom, "channel_id")) { - TRY_RESULT(channel_id_int, get_json_object_long_field(custom, "channel_id")); + if (custom.has_field("channel_id")) { + TRY_RESULT(channel_id_int, custom.get_optional_long_field("channel_id")); ChannelId channel_id(channel_id_int); if (!channel_id.is_valid()) { - return Status::Error("Receive invalid channel_id"); + return Status::Error("Receive invalid supergroup identifier"); } dialog_id = DialogId(channel_id); } - if (has_json_object_field(custom, "encryption_id")) { - TRY_RESULT(secret_chat_id_int, get_json_object_int_field(custom, "encryption_id")); + if (custom.has_field("encryption_id")) { + TRY_RESULT(secret_chat_id_int, custom.get_optional_int_field("encryption_id")); SecretChatId secret_chat_id(secret_chat_id_int); if (!secret_chat_id.is_valid()) { - return Status::Error("Receive invalid secret_chat_id"); + return Status::Error("Receive invalid secret chat identifier"); } dialog_id = DialogId(secret_chat_id); } @@ -3171,7 +3364,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo if (loc_key == "ENCRYPTED_MESSAGE" || loc_key == "MESSAGE_MUTED") { return Status::Error(406, "Force loading data from the server"); } - return Status::Error("Can't find dialog_id"); + return Status::Error("Can't find chat identifier"); } if (loc_key == "READ_HISTORY") { @@ -3179,7 +3372,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo return Status::Error("Receive read history in a secret chat"); } - TRY_RESULT(max_id, get_json_object_int_field(custom, "max_id")); + TRY_RESULT(max_id, custom.get_optional_int_field("max_id")); ServerMessageId max_server_message_id(max_id); if (!max_server_message_id.is_valid()) { return Status::Error("Receive invalid max_id"); @@ -3195,14 +3388,14 @@ Status NotificationManager::process_push_notification_payload(string payload, bo if (dialog_id.get_type() == DialogType::SecretChat) { return Status::Error("Receive MESSAGE_DELETED in a secret chat"); } - TRY_RESULT(server_message_ids_str, get_json_object_string_field(custom, "messages", false)); + TRY_RESULT(server_message_ids_str, custom.get_required_string_field("messages")); auto server_message_ids = full_split(server_message_ids_str, ','); vector message_ids; for (const auto &server_message_id_str : server_message_ids) { TRY_RESULT(server_message_id_int, to_integer_safe(server_message_id_str)); ServerMessageId server_message_id(server_message_id_int); if (!server_message_id.is_valid()) { - return Status::Error("Receive invalid message_id"); + return Status::Error("Receive invalid message identifier"); } message_ids.push_back(MessageId(server_message_id)); } @@ -3215,30 +3408,66 @@ Status NotificationManager::process_push_notification_payload(string payload, bo return Status::Error(406, "Notifications about muted messages force loading data from the server"); } - TRY_RESULT(msg_id, get_json_object_int_field(custom, "msg_id")); + if (loc_key == "READ_STORIES") { + if (dialog_id.get_type() == DialogType::SecretChat) { + return Status::Error("Receive READ_STORIES in a secret chat"); + } + + TRY_RESULT(max_id, custom.get_optional_int_field("max_id")); + StoryId max_story_id(max_id); + if (!max_story_id.is_server()) { + return Status::Error("Receive invalid max_id"); + } + + td_->story_manager_->on_update_read_stories(dialog_id, max_story_id); + promise.set_value(Unit()); + return Status::OK(); + } + + if (loc_key == "STORY_DELETED") { + if (dialog_id.get_type() != DialogType::SecretChat) { + return Status::Error("Receive STORY_DELETED in a secret chat"); + } + TRY_RESULT(server_story_ids_str, custom.get_required_string_field("story_id")); + auto server_story_ids = full_split(server_story_ids_str, ','); + vector story_ids; + for (const auto &server_story_id_str : server_story_ids) { + TRY_RESULT(story_id_int, to_integer_safe(server_story_id_str)); + StoryId story_id(story_id_int); + if (!story_id.is_server()) { + return Status::Error("Receive invalid story identifier"); + } + story_ids.push_back(story_id); + } + td_->story_manager_->remove_story_notifications_by_story_ids(dialog_id, story_ids); + promise.set_value(Unit()); + return Status::OK(); + } + + TRY_RESULT(msg_id, custom.get_optional_int_field("msg_id")); ServerMessageId server_message_id(msg_id); if (server_message_id != ServerMessageId() && !server_message_id.is_valid()) { return Status::Error("Receive invalid msg_id"); } - TRY_RESULT(random_id, get_json_object_long_field(custom, "random_id")); + TRY_RESULT(random_id, custom.get_optional_long_field("random_id")); UserId sender_user_id; DialogId sender_dialog_id; - if (has_json_object_field(custom, "chat_from_broadcast_id")) { - TRY_RESULT(sender_channel_id_int, get_json_object_long_field(custom, "chat_from_broadcast_id")); + if (custom.has_field("chat_from_broadcast_id")) { + TRY_RESULT(sender_channel_id_int, custom.get_optional_long_field("chat_from_broadcast_id")); sender_dialog_id = DialogId(ChannelId(sender_channel_id_int)); if (!sender_dialog_id.is_valid()) { return Status::Error("Receive invalid chat_from_broadcast_id"); } - } else if (has_json_object_field(custom, "chat_from_group_id")) { - TRY_RESULT(sender_channel_id_int, get_json_object_long_field(custom, "chat_from_group_id")); + } else if (custom.has_field("chat_from_group_id")) { + TRY_RESULT(sender_channel_id_int, custom.get_optional_long_field("chat_from_group_id")); sender_dialog_id = DialogId(ChannelId(sender_channel_id_int)); if (!sender_dialog_id.is_valid()) { return Status::Error("Receive invalid chat_from_group_id"); } - } else if (has_json_object_field(custom, "chat_from_id")) { - TRY_RESULT(sender_user_id_int, get_json_object_long_field(custom, "chat_from_id")); + } else if (custom.has_field("chat_from_id")) { + TRY_RESULT(sender_user_id_int, custom.get_optional_long_field("chat_from_id")); sender_user_id = UserId(sender_user_id_int); if (!sender_user_id.is_valid()) { return Status::Error("Receive invalid chat_from_id"); @@ -3249,7 +3478,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo sender_dialog_id = dialog_id; } - TRY_RESULT(contains_mention_int, get_json_object_int_field(custom, "mention")); + TRY_RESULT(contains_mention_int, custom.get_optional_int_field("mention")); bool contains_mention = contains_mention_int != 0; if (begins_with(loc_key, "CHANNEL_MESSAGE") || loc_key == "CHANNEL_ALBUM") { @@ -3258,6 +3487,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo } loc_key = loc_key.substr(8); } + string sender_name; if (begins_with(loc_key, "CHAT_")) { auto dialog_type = dialog_id.get_type(); if (dialog_type != DialogType::Chat && dialog_type != DialogType::Channel) { @@ -3268,13 +3498,13 @@ Status NotificationManager::process_push_notification_payload(string payload, bo loc_key = loc_key.substr(5); } if (loc_args.empty()) { - return Status::Error("Expect sender name as first argument"); + return Status::Error("Expect sender name as the first argument"); } sender_name = std::move(loc_args[0]); loc_args.erase(loc_args.begin()); } if (begins_with(loc_key, "MESSAGE") && !server_message_id.is_valid()) { - return Status::Error("Receive no message ID"); + return Status::Error("Receive no message identifier"); } if (begins_with(loc_key, "ENCRYPT") || random_id != 0) { if (dialog_id.get_type() != DialogType::SecretChat) { @@ -3282,7 +3512,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo } } if (server_message_id.is_valid() && dialog_id.get_type() == DialogType::SecretChat) { - return Status::Error("Receive message ID in secret chat push"); + return Status::Error("Receive message identifier in a secret chat push notification"); } if (begins_with(loc_key, "ENCRYPTION_")) { @@ -3306,7 +3536,7 @@ Status NotificationManager::process_push_notification_payload(string payload, bo } if (loc_args.empty()) { - return Status::Error("Expected chat name as next argument"); + return Status::Error("Expected chat name as the next argument"); } if (dialog_id.get_type() == DialogType::User) { sender_name = std::move(loc_args[0]); @@ -3332,6 +3562,42 @@ Status NotificationManager::process_push_notification_payload(string payload, bo arg = PSTRING() << loc_args[1] << ' ' << loc_args[0]; loc_args.clear(); } + if (loc_key == "MESSAGE_GIVEAWAY") { + if (loc_args.size() != 2) { + return Status::Error("Expected 2 arguments for MESSAGE_GIVEAWAY"); + } + TRY_RESULT(user_count, to_integer_safe(loc_args[0])); + if (user_count <= 0) { + return Status::Error("Expected user count to be non-negative"); + } + TRY_RESULT(month_count, to_integer_safe(loc_args[1])); + if (month_count <= 0) { + return Status::Error("Expected month count to be non-negative"); + } + arg = PSTRING() << user_count << ' ' << month_count; + loc_args.clear(); + } + if (loc_key == "MESSAGE_GIVEAWAY_STARS") { + if (loc_args.size() != 2) { + return Status::Error("Expected 2 arguments for MESSAGE_GIVEAWAY_STARS"); + } + TRY_RESULT(user_count, to_integer_safe(loc_args[0])); + if (user_count <= 0) { + return Status::Error("Expected user count to be non-negative"); + } + TRY_RESULT(star_count, to_integer_safe(loc_args[1])); + arg = PSTRING() << user_count << ' ' << StarManager::get_star_count(star_count); + loc_args.clear(); + } + if (loc_key == "MESSAGE_PAID_MEDIA") { + if (loc_args.size() != 1) { + return Status::Error("Expected 1 argument for MESSAGE_PAID_MEDIA"); + } + TRY_RESULT(star_count, to_integer_safe(loc_args[0])); + star_count = StarManager::get_star_count(star_count); + arg = to_string(star_count); + loc_args.clear(); + } if (loc_args.size() > 1) { return Status::Error("Receive too many arguments"); } @@ -3340,132 +3606,30 @@ Status NotificationManager::process_push_notification_payload(string payload, bo arg = std::move(loc_args[0]); } - if (sender_user_id.is_valid() && !td_->contacts_manager_->have_user_force(sender_user_id)) { + if (sender_user_id.is_valid() && + !td_->user_manager_->have_user_force(sender_user_id, "process_push_notification_payload")) { int64 sender_access_hash = -1; telegram_api::object_ptr sender_photo; - TRY_RESULT(mtpeer, get_json_object_field(custom, "mtpeer", JsonValue::Type::Object)); + TRY_RESULT(mtpeer, custom.extract_optional_field("mtpeer", JsonValue::Type::Object)); if (mtpeer.type() != JsonValue::Type::Null) { - TRY_RESULT(ah, get_json_object_string_field(mtpeer.get_object(), "ah")); + auto &mtpeer_object = mtpeer.get_object(); + TRY_RESULT(ah, mtpeer_object.get_optional_string_field("ah")); if (!ah.empty()) { TRY_RESULT_ASSIGN(sender_access_hash, to_integer_safe(ah)); } - TRY_RESULT(ph, get_json_object_field(mtpeer.get_object(), "ph", JsonValue::Type::Object)); + TRY_RESULT(ph, mtpeer_object.extract_optional_field("ph", JsonValue::Type::Object)); if (ph.type() != JsonValue::Type::Null) { // TODO parse sender photo } } - int32 flags = USER_FLAG_IS_INACCESSIBLE; - if (sender_access_hash != -1) { - // set phone number flag to show that this is a full access hash - flags |= USER_FLAG_HAS_ACCESS_HASH | USER_FLAG_HAS_PHONE_NUMBER; - } - auto user_name = sender_user_id.get() == 136817688 ? "Channel" : sender_name; - auto user = telegram_api::make_object( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, 0, false /*ignored*/, sender_user_id.get(), - sender_access_hash, user_name, string(), string(), string(), std::move(sender_photo), nullptr, 0, Auto(), - string(), string(), nullptr, vector>()); - td_->contacts_manager_->on_get_user(std::move(user), "process_push_notification_payload"); + add_push_notification_user(sender_user_id, sender_access_hash, sender_name, std::move(sender_photo)); } Photo attached_photo; Document attached_document; - if (has_json_object_field(custom, "attachb64")) { - TRY_RESULT(attachb64, get_json_object_string_field(custom, "attachb64", false)); - TRY_RESULT(attach, base64url_decode(attachb64)); + TRY_STATUS(parse_push_notification_attach(dialog_id, loc_key, custom, attached_photo, attached_document)); - TlParser gzip_parser(attach); - int32 id = gzip_parser.fetch_int(); - if (gzip_parser.get_error()) { - return Status::Error(PSLICE() << "Failed to parse attach: " << gzip_parser.get_error()); - } - BufferSlice buffer; - if (id == mtproto_api::gzip_packed::ID) { - mtproto_api::gzip_packed gzip(gzip_parser); - gzip_parser.fetch_end(); - if (gzip_parser.get_error()) { - return Status::Error(PSLICE() << "Failed to parse mtproto_api::gzip_packed in attach: " - << gzip_parser.get_error()); - } - buffer = gzdecode(gzip.packed_data_); - if (buffer.empty()) { - return Status::Error("Failed to uncompress attach"); - } - } else { - buffer = BufferSlice(attach); - } - - TlBufferParser parser(&buffer); - auto result = telegram_api::Object::fetch(parser); - parser.fetch_end(); - const char *error = parser.get_error(); - if (error != nullptr) { - LOG(ERROR) << "Can't parse attach: " << Slice(error) << " at " << parser.get_error_pos() << ": " - << format::as_hex_dump<4>(Slice(attach)); - } else { - switch (result->get_id()) { - case telegram_api::photo::ID: - if (ends_with(loc_key, "MESSAGE_PHOTO") || ends_with(loc_key, "MESSAGE_TEXT")) { - VLOG(notifications) << "Have attached photo"; - loc_key.resize(loc_key.rfind('_') + 1); - loc_key += "PHOTO"; - attached_photo = get_photo(td_, telegram_api::move_object_as(result), dialog_id); - } else { - LOG(ERROR) << "Receive attached photo for " << loc_key; - } - break; - case telegram_api::document::ID: { - if (ends_with(loc_key, "MESSAGE_ANIMATION") || ends_with(loc_key, "MESSAGE_AUDIO") || - ends_with(loc_key, "MESSAGE_DOCUMENT") || ends_with(loc_key, "MESSAGE_STICKER") || - ends_with(loc_key, "MESSAGE_VIDEO") || ends_with(loc_key, "MESSAGE_VIDEO_NOTE") || - ends_with(loc_key, "MESSAGE_VOICE_NOTE") || ends_with(loc_key, "MESSAGE_TEXT")) { - VLOG(notifications) << "Have attached document"; - attached_document = td_->documents_manager_->on_get_document( - telegram_api::move_object_as(result), dialog_id); - if (!attached_document.empty()) { - if (ends_with(loc_key, "_NOTE")) { - loc_key.resize(loc_key.rfind('_')); - } - loc_key.resize(loc_key.rfind('_') + 1); - - auto type = [attached_document] { - switch (attached_document.type) { - case Document::Type::Animation: - return "ANIMATION"; - case Document::Type::Audio: - return "AUDIO"; - case Document::Type::General: - return "DOCUMENT"; - case Document::Type::Sticker: - return "STICKER"; - case Document::Type::Video: - return "VIDEO"; - case Document::Type::VideoNote: - return "VIDEO_NOTE"; - case Document::Type::VoiceNote: - return "VOICE_NOTE"; - case Document::Type::Unknown: - default: - UNREACHABLE(); - return "UNREACHABLE"; - } - }(); - - loc_key += type; - } - } else { - LOG(ERROR) << "Receive attached document for " << loc_key; - } - break; - } - default: - LOG(ERROR) << "Receive unexpected attached " << to_string(result); - } - } - } if (!arg.empty()) { uint32 emoji = [&] { if (ends_with(loc_key, "PHOTO")) { @@ -3492,11 +3656,11 @@ Status NotificationManager::process_push_notification_payload(string payload, bo } } - if (has_json_object_field(custom, "edit_date")) { + if (custom.has_field("edit_date")) { if (random_id != 0) { return Status::Error("Receive edit of secret message"); } - TRY_RESULT(edit_date, get_json_object_int_field(custom, "edit_date")); + TRY_RESULT(edit_date, custom.get_optional_int_field("edit_date")); if (edit_date <= 0) { return Status::Error("Receive wrong edit date"); } @@ -3504,14 +3668,14 @@ Status NotificationManager::process_push_notification_payload(string payload, bo std::move(arg), std::move(attached_photo), std::move(attached_document), 0, std::move(promise)); } else { - bool is_from_scheduled = has_json_object_field(custom, "schedule"); + bool is_from_scheduled = custom.has_field("schedule"); bool disable_notification = false; int64 ringtone_id = -1; - if (has_json_object_field(custom, "silent")) { + if (custom.has_field("silent")) { disable_notification = true; ringtone_id = 0; - } else if (has_json_object_field(custom, "ringtone")) { - TRY_RESULT_ASSIGN(ringtone_id, get_json_object_long_field(custom, "ringtone")); + } else if (custom.has_field("ringtone")) { + TRY_RESULT_ASSIGN(ringtone_id, custom.get_optional_long_field("ringtone")); } add_message_push_notification(dialog_id, MessageId(server_message_id), random_id, sender_user_id, sender_dialog_id, std::move(sender_name), sent_date, is_from_scheduled, contains_mention, @@ -3716,17 +3880,9 @@ void NotificationManager::add_message_push_notification(DialogId dialog_id, Mess CHECK(log_event_id != 0); } - if (sender_user_id.is_valid() && !td_->contacts_manager_->have_user_force(sender_user_id)) { - int32 flags = USER_FLAG_IS_INACCESSIBLE; - auto user_name = sender_user_id.get() == 136817688 ? "Channel" : sender_name; - auto user = telegram_api::make_object( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, 0, false /*ignored*/, sender_user_id.get(), 0, - user_name, string(), string(), string(), nullptr, nullptr, 0, Auto(), string(), string(), nullptr, - vector>()); - td_->contacts_manager_->on_get_user(std::move(user), "add_message_push_notification"); + if (sender_user_id.is_valid() && + !td_->user_manager_->have_user_force(sender_user_id, "add_message_push_notification")) { + add_push_notification_user(sender_user_id, -1, sender_name, nullptr); } if (log_event_id == 0 && G()->use_message_database()) { @@ -3753,14 +3909,14 @@ void NotificationManager::add_message_push_notification(DialogId dialog_id, Mess auto group_id = info.group_id; CHECK(group_id.is_valid()); - bool is_outgoing = - sender_user_id.is_valid() ? td_->contacts_manager_->get_my_id() == sender_user_id : is_from_scheduled; + bool is_outgoing = sender_user_id.is_valid() ? td_->user_manager_->get_my_id() == sender_user_id : is_from_scheduled; if (log_event_id != 0) { VLOG(notifications) << "Register temporary " << notification_id << " with log event " << log_event_id; + NotificationObjectFullId object_full_id(dialog_id, message_id); temporary_notification_log_event_ids_[notification_id] = log_event_id; - temporary_notifications_[FullMessageId(dialog_id, message_id)] = {group_id, notification_id, sender_user_id, - sender_dialog_id, sender_name, is_outgoing}; - temporary_notification_message_ids_[notification_id] = FullMessageId(dialog_id, message_id); + temporary_notifications_[object_full_id] = {group_id, notification_id, sender_user_id, + sender_dialog_id, sender_name, is_outgoing}; + temporary_notification_object_ids_[notification_id] = object_full_id; } push_notification_promises_[notification_id].push_back(std::move(promise)); @@ -3856,7 +4012,7 @@ void NotificationManager::edit_message_push_notification(DialogId dialog_id, Mes return promise.set_error(Status::Error(200, "Immediate success")); } - auto it = temporary_notifications_.find(FullMessageId(dialog_id, message_id)); + auto it = temporary_notifications_.find({dialog_id, message_id}); if (it == temporary_notifications_.end()) { VLOG(notifications) << "Ignore edit of message push notification for " << message_id << " in " << dialog_id << " edited at " << edit_date; @@ -3915,8 +4071,8 @@ Result NotificationManager::get_push_receiver_id(string payload) { } auto data = std::move(json_value.get_object()); - if (has_json_object_field(data, "data")) { - auto r_data_data = get_json_object_field(data, "data", JsonValue::Type::Object, false); + if (data.has_field("data")) { + auto r_data_data = data.extract_required_field("data", JsonValue::Type::Object); if (r_data_data.is_error()) { return Status::Error(400, r_data_data.error().message()); } @@ -3924,38 +4080,24 @@ Result NotificationManager::get_push_receiver_id(string payload) { data = std::move(data_data.get_object()); } - for (auto &field_value : data) { - if (field_value.first == "p") { - auto encrypted_payload = std::move(field_value.second); - if (encrypted_payload.type() != JsonValue::Type::String) { - return Status::Error(400, "Expected encrypted payload as a String"); - } - Slice encrypted_data = encrypted_payload.get_string(); - if (encrypted_data.size() < 12) { - return Status::Error(400, "Encrypted payload is too small"); - } - auto r_decoded = base64url_decode(encrypted_data.substr(0, 12)); - if (r_decoded.is_error()) { - return Status::Error(400, "Failed to base64url-decode payload"); - } - CHECK(r_decoded.ok().size() == 9); - return as(r_decoded.ok().c_str()); + if (data.has_field("p")) { + TRY_RESULT(encrypted_data, data.get_required_string_field("p")); + if (encrypted_data.size() < 12) { + return Status::Error(400, "Encrypted payload is too small"); } - if (field_value.first == "user_id") { - auto user_id = std::move(field_value.second); - if (user_id.type() != JsonValue::Type::String && user_id.type() != JsonValue::Type::Number) { - return Status::Error(400, "Expected user_id as a String or a Number"); - } - Slice user_id_str = user_id.type() == JsonValue::Type::String ? user_id.get_string() : user_id.get_number(); - auto r_user_id = to_integer_safe(user_id_str); - if (r_user_id.is_error()) { - return Status::Error(400, PSLICE() << "Failed to get user_id from " << user_id_str); - } - if (r_user_id.ok() <= 0) { - return Status::Error(400, PSLICE() << "Receive wrong user_id " << user_id_str); - } - return r_user_id.ok(); + auto r_decoded = base64url_decode(encrypted_data.substr(0, 12)); + if (r_decoded.is_error()) { + return Status::Error(400, "Failed to base64url-decode payload"); } + CHECK(r_decoded.ok().size() == 9); + return as(r_decoded.ok().c_str()); + } + if (data.has_field("user_id")) { + TRY_RESULT(user_id, data.get_required_long_field("user_id")); + if (user_id <= 0) { + return Status::Error(400, PSLICE() << "Receive wrong user_id " << user_id); + } + return user_id; } return static_cast(0); @@ -3972,24 +4114,16 @@ Result NotificationManager::decrypt_push(int64 encryption_key_id, string return Status::Error(400, "Expected JSON object"); } - for (auto &field_value : json_value.get_object()) { - if (field_value.first == "p") { - auto encrypted_payload = std::move(field_value.second); - if (encrypted_payload.type() != JsonValue::Type::String) { - return Status::Error(400, "Expected encrypted payload as a String"); - } - Slice encrypted_data = encrypted_payload.get_string(); - if (encrypted_data.size() < 12) { - return Status::Error(400, "Encrypted payload is too small"); - } - auto r_decoded = base64url_decode(encrypted_data); - if (r_decoded.is_error()) { - return Status::Error(400, "Failed to base64url-decode payload"); - } - return decrypt_push_payload(encryption_key_id, std::move(encryption_key), r_decoded.move_as_ok()); - } + const auto &object = json_value.get_object(); + TRY_RESULT(encrypted_data, object.get_required_string_field("p")); + if (encrypted_data.size() < 12) { + return Status::Error(400, "Encrypted payload is too small"); + } + auto r_decoded = base64url_decode(encrypted_data); + if (r_decoded.is_error()) { + return Status::Error(400, "Failed to base64url-decode payload"); } - return Status::Error(400, "No 'p'(payload) field found in push"); + return decrypt_push_payload(encryption_key_id, std::move(encryption_key), r_decoded.move_as_ok()); } Result NotificationManager::decrypt_push_payload(int64 encryption_key_id, string encryption_key, diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationManager.h b/protocols/Telegram/tdlib/td/td/telegram/NotificationManager.h index 16aab4e866..526e7c5e05 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/NotificationManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,16 +9,18 @@ #include "td/telegram/CallId.h" #include "td/telegram/DialogId.h" #include "td/telegram/Document.h" -#include "td/telegram/FullMessageId.h" #include "td/telegram/MessageId.h" #include "td/telegram/Notification.h" #include "td/telegram/NotificationGroupId.h" #include "td/telegram/NotificationGroupKey.h" #include "td/telegram/NotificationGroupType.h" #include "td/telegram/NotificationId.h" +#include "td/telegram/NotificationObjectFullId.h" +#include "td/telegram/NotificationObjectId.h" #include "td/telegram/NotificationType.h" #include "td/telegram/Photo.h" #include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" #include "td/actor/actor.h" @@ -41,7 +43,7 @@ namespace td { extern int VERBOSITY_NAME(notifications); struct BinlogEvent; - +class JsonObject; class Td; class NotificationManager final : public Actor { @@ -67,6 +69,8 @@ class NotificationManager final : public Actor { void load_group_force(NotificationGroupId group_id); + bool have_group_force(NotificationGroupId group_id); + void add_notification(NotificationGroupId group_id, NotificationGroupType group_type, DialogId dialog_id, int32 date, DialogId notification_settings_dialog_id, bool disable_notification, int64 ringtone_id, int32 min_delay_ms, NotificationId notification_id, unique_ptr type, @@ -80,11 +84,11 @@ class NotificationManager final : public Actor { void remove_temporary_notifications(NotificationGroupId group_id, const char *source); - void remove_temporary_notification_by_message_id(NotificationGroupId group_id, MessageId message_id, - bool force_update, const char *source); + void remove_temporary_notification_by_object_id(NotificationGroupId group_id, NotificationObjectId object_id, + bool force_update, const char *source); void remove_notification_group(NotificationGroupId group_id, NotificationId max_notification_id, - MessageId max_message_id, int32 new_total_count, bool force_update, + NotificationObjectId max_object_id, int32 new_total_count, bool force_update, Promise &&promise); void set_notification_total_count(NotificationGroupId group_id, int32 new_total_count); @@ -236,22 +240,22 @@ class NotificationManager final : public Actor { static NotificationId get_last_notification_id(const NotificationGroup &group); - static MessageId get_first_message_id(const NotificationGroup &group); + static NotificationObjectId get_first_object_id(const NotificationGroup &group); - static MessageId get_last_message_id(const NotificationGroup &group); + static NotificationObjectId get_last_object_id(const NotificationGroup &group); - static MessageId get_last_message_id_by_notification_id(const NotificationGroup &group, - NotificationId max_notification_id); + static NotificationObjectId get_last_object_id_by_notification_id(const NotificationGroup &group, + NotificationId max_notification_id); static int32 get_temporary_notification_total_count(const NotificationGroup &group); int32 load_message_notification_groups_from_database(int32 limit, bool send_update); - void load_message_notifications_from_database(const NotificationGroupKey &group_key, NotificationGroup &group, - size_t desired_size); + void load_notifications_from_database(const NotificationGroupKey &group_key, NotificationGroup &group, + size_t desired_size); - void on_get_message_notifications_from_database(NotificationGroupId group_id, size_t limit, - Result> r_notifications); + void on_get_notifications_from_database(NotificationGroupId group_id, size_t limit, + Result> r_notifications); void add_notifications_to_group_begin(NotificationGroups::iterator group_it, vector notifications); @@ -308,6 +312,12 @@ class NotificationManager final : public Actor { static string convert_loc_key(const string &loc_key); + void add_push_notification_user(UserId sender_user_id, int64 sender_access_hash, const string &sender_name, + telegram_api::object_ptr &&sender_photo); + + Status parse_push_notification_attach(DialogId dialog_id, string &loc_key, JsonObject &custom, Photo &attached_photo, + Document &attached_document); + Status process_push_notification_payload(string payload, bool was_encrypted, Promise &promise); void add_message_push_notification(DialogId dialog_id, MessageId message_id, int64 random_id, UserId sender_user_id, @@ -398,8 +408,8 @@ class NotificationManager final : public Actor { string sender_name; bool is_outgoing; }; - FlatHashMap temporary_notifications_; - FlatHashMap temporary_notification_message_ids_; + FlatHashMap temporary_notifications_; + FlatHashMap temporary_notification_object_ids_; FlatHashMap>, NotificationIdHash> push_notification_promises_; struct ActiveCallNotification { diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationObjectFullId.h b/protocols/Telegram/tdlib/td/td/telegram/NotificationObjectFullId.h new file mode 100644 index 0000000000..dcd272543f --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationObjectFullId.h @@ -0,0 +1,60 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/NotificationObjectId.h" + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +struct NotificationObjectFullId { + private: + DialogId dialog_id; + NotificationObjectId notification_object_id; + + public: + NotificationObjectFullId() : dialog_id(), notification_object_id() { + } + + NotificationObjectFullId(DialogId dialog_id, NotificationObjectId notification_object_id) + : dialog_id(dialog_id), notification_object_id(notification_object_id) { + } + + bool operator==(const NotificationObjectFullId &other) const { + return dialog_id == other.dialog_id && notification_object_id == other.notification_object_id; + } + + bool operator!=(const NotificationObjectFullId &other) const { + return !(*this == other); + } + + DialogId get_dialog_id() const { + return dialog_id; + } + + NotificationObjectId get_notification_object_id() const { + return notification_object_id; + } +}; + +struct NotificationObjectFullIdHash { + uint32 operator()(NotificationObjectFullId full_notification_object_id) const { + return combine_hashes(DialogIdHash()(full_notification_object_id.get_dialog_id()), + NotificationObjectIdHash()(full_notification_object_id.get_notification_object_id())); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, NotificationObjectFullId full_notification_object_id) { + return string_builder << full_notification_object_id.get_notification_object_id() << " in " + << full_notification_object_id.get_dialog_id(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationObjectId.h b/protocols/Telegram/tdlib/td/td/telegram/NotificationObjectId.h new file mode 100644 index 0000000000..79032a3b49 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationObjectId.h @@ -0,0 +1,83 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageId.h" + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class NotificationObjectId { + int64 id = 0; + + public: + NotificationObjectId() = default; + + NotificationObjectId(MessageId message_id) : id(message_id.get()) { + } + + static NotificationObjectId max() { + return NotificationObjectId(MessageId::max()); + } + + int64 get() const { + return id; + } + + bool is_valid() const { + return id > 0; + } + + bool operator==(const NotificationObjectId &other) const { + return id == other.id; + } + + bool operator!=(const NotificationObjectId &other) const { + return id != other.id; + } + + friend bool operator<(const NotificationObjectId &lhs, const NotificationObjectId &rhs) { + return lhs.id < rhs.id; + } + + friend bool operator>(const NotificationObjectId &lhs, const NotificationObjectId &rhs) { + return lhs.id > rhs.id; + } + + friend bool operator<=(const NotificationObjectId &lhs, const NotificationObjectId &rhs) { + return lhs.id <= rhs.id; + } + + friend bool operator>=(const NotificationObjectId &lhs, const NotificationObjectId &rhs) { + return lhs.id >= rhs.id; + } + + template + void store(StorerT &storer) const { + storer.store_long(id); + } + + template + void parse(ParserT &parser) { + id = parser.fetch_long(); + } +}; + +struct NotificationObjectIdHash { + uint32 operator()(NotificationObjectId notification_object_id) const { + return Hash()(notification_object_id.get()); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, NotificationObjectId notification_object_id) { + return string_builder << "notification object " << notification_object_id.get(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationSettingsManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/NotificationSettingsManager.cpp index ac6a26a0e4..3e8204e680 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/NotificationSettingsManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationSettingsManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,8 @@ #include "td/telegram/AudiosManager.h" #include "td/telegram/AudiosManager.hpp" #include "td/telegram/AuthManager.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Document.h" #include "td/telegram/DocumentsManager.h" #include "td/telegram/FileReferenceManager.h" @@ -25,11 +26,13 @@ #include "td/telegram/NotificationManager.h" #include "td/telegram/NotificationSound.h" #include "td/telegram/OptionManager.h" +#include "td/telegram/ReactionNotificationSettings.hpp" #include "td/telegram/ScopeNotificationSettings.hpp" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" #include "td/telegram/VoiceNotesManager.h" #include "td/db/binlog/BinlogEvent.h" @@ -42,7 +45,6 @@ #include "td/utils/misc.h" #include "td/utils/PathView.h" #include "td/utils/Random.h" -#include "td/utils/SliceBuilder.h" #include "td/utils/tl_helpers.h" #include @@ -84,8 +86,9 @@ class UploadRingtoneQuery final : public Td::ResultHandler { if (FileReferenceManager::is_file_reference_error(status)) { LOG(ERROR) << "Receive file reference error " << status; } - if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) { - // TODO support FILE_PART_*_MISSING + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + // TODO reupload the file } td_->file_manager_->delete_partial_remote_location(file_id_); @@ -215,7 +218,7 @@ class GetDialogNotifySettingsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetDialogNotifySettingsQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetDialogNotifySettingsQuery"); td_->notification_settings_manager_->on_get_dialog_notification_settings_query_finished( dialog_id_, top_thread_message_id_, std::move(status)); } @@ -238,8 +241,8 @@ class GetNotifySettingsExceptionsQuery final : public Td::ResultHandler { if (compare_sound) { flags |= telegram_api::account_getNotifyExceptions::COMPARE_SOUND_MASK; } - send_query(G()->net_query_creator().create( - telegram_api::account_getNotifyExceptions(flags, false /*ignored*/, std::move(input_notify_peer)))); + send_query(G()->net_query_creator().create(telegram_api::account_getNotifyExceptions( + flags, false /*ignored*/, false /*ignored*/, std::move(input_notify_peer)))); } void on_result(BufferSlice packet) final { @@ -270,10 +273,10 @@ class GetNotifySettingsExceptionsQuery final : public Td::ResultHandler { break; } } - td_->contacts_manager_->on_get_users(std::move(users), "GetNotifySettingsExceptionsQuery"); - td_->contacts_manager_->on_get_chats(std::move(chats), "GetNotifySettingsExceptionsQuery"); + td_->user_manager_->on_get_users(std::move(users), "GetNotifySettingsExceptionsQuery"); + td_->chat_manager_->on_get_chats(std::move(chats), "GetNotifySettingsExceptionsQuery"); for (auto &dialog_id : dialog_ids) { - td_->messages_manager_->force_create_dialog(dialog_id, "GetNotifySettingsExceptionsQuery"); + td_->dialog_manager_->force_create_dialog(dialog_id, "GetNotifySettingsExceptionsQuery"); } td_->updates_manager_->on_get_updates(std::move(updates_ptr), std::move(promise_)); } @@ -283,6 +286,64 @@ class GetNotifySettingsExceptionsQuery final : public Td::ResultHandler { } }; +class GetStoryNotifySettingsExceptionsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetStoryNotifySettingsExceptionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send() { + int32 flags = telegram_api::account_getNotifyExceptions::COMPARE_STORIES_MASK; + send_query(G()->net_query_creator().create( + telegram_api::account_getNotifyExceptions(flags, false /*ignored*/, false /*ignored*/, nullptr))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto updates_ptr = result_ptr.move_as_ok(); + auto dialog_ids = UpdatesManager::get_update_notify_settings_dialog_ids(updates_ptr.get()); + vector> users; + vector> chats; + switch (updates_ptr->get_id()) { + case telegram_api::updatesCombined::ID: { + auto updates = static_cast(updates_ptr.get()); + users = std::move(updates->users_); + chats = std::move(updates->chats_); + reset_to_empty(updates->users_); + reset_to_empty(updates->chats_); + break; + } + case telegram_api::updates::ID: { + auto updates = static_cast(updates_ptr.get()); + users = std::move(updates->users_); + chats = std::move(updates->chats_); + reset_to_empty(updates->users_); + reset_to_empty(updates->chats_); + break; + } + } + td_->user_manager_->on_get_users(std::move(users), "GetStoryNotifySettingsExceptionsQuery"); + td_->chat_manager_->on_get_chats(std::move(chats), "GetStoryNotifySettingsExceptionsQuery"); + for (auto &dialog_id : dialog_ids) { + td_->dialog_manager_->force_create_dialog(dialog_id, "GetStoryNotifySettingsExceptionsQuery"); + } + auto chat_ids = td_->dialog_manager_->get_chats_object(-1, dialog_ids, "GetStoryNotifySettingsExceptionsQuery"); + auto promise = PromiseCreator::lambda([promise = std::move(promise_), chat_ids = std::move(chat_ids)]( + Result) mutable { promise.set_value(std::move(chat_ids)); }); + td_->updates_manager_->on_get_updates(std::move(updates_ptr), std::move(promise)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + class GetScopeNotifySettingsQuery final : public Td::ResultHandler { Promise promise_; NotificationSettingsScope scope_; @@ -315,6 +376,34 @@ class GetScopeNotifySettingsQuery final : public Td::ResultHandler { } }; +class GetReactionsNotifySettingsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetReactionsNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::account_getReactionsNotifySettings())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + td_->notification_settings_manager_->on_update_reaction_notification_settings( + ReactionNotificationSettings(std::move(ptr))); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + class UpdateDialogNotifySettingsQuery final : public Td::ResultHandler { Promise promise_; DialogId dialog_id_; @@ -334,23 +423,8 @@ class UpdateDialogNotifySettingsQuery final : public Td::ResultHandler { return on_error(Status::Error(500, "Can't update chat notification settings")); } - int32 flags = 0; - if (!new_settings.use_default_mute_until) { - flags |= telegram_api::inputPeerNotifySettings::MUTE_UNTIL_MASK; - } - if (new_settings.sound != nullptr) { - flags |= telegram_api::inputPeerNotifySettings::SOUND_MASK; - } - if (!new_settings.use_default_show_preview) { - flags |= telegram_api::inputPeerNotifySettings::SHOW_PREVIEWS_MASK; - } - if (new_settings.silent_send_message) { - flags |= telegram_api::inputPeerNotifySettings::SILENT_MASK; - } send_query(G()->net_query_creator().create(telegram_api::account_updateNotifySettings( - std::move(input_notify_peer), make_tl_object( - flags, new_settings.show_preview, new_settings.silent_send_message, - new_settings.mute_until, get_input_notification_sound(new_settings.sound))))); + std::move(input_notify_peer), new_settings.get_input_peer_notify_settings()))); } void on_result(BufferSlice packet) final { @@ -368,7 +442,7 @@ class UpdateDialogNotifySettingsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "UpdateDialogNotifySettingsQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "UpdateDialogNotifySettingsQuery")) { LOG(INFO) << "Receive error for set chat notification settings: " << status; } @@ -394,15 +468,8 @@ class UpdateScopeNotifySettingsQuery final : public Td::ResultHandler { void send(NotificationSettingsScope scope, const ScopeNotificationSettings &new_settings) { auto input_notify_peer = get_input_notify_peer(scope); CHECK(input_notify_peer != nullptr); - int32 flags = telegram_api::inputPeerNotifySettings::MUTE_UNTIL_MASK | - telegram_api::inputPeerNotifySettings::SHOW_PREVIEWS_MASK; - if (new_settings.sound != nullptr) { - flags |= telegram_api::inputPeerNotifySettings::SOUND_MASK; - } send_query(G()->net_query_creator().create(telegram_api::account_updateNotifySettings( - std::move(input_notify_peer), make_tl_object( - flags, new_settings.show_preview, false, new_settings.mute_until, - get_input_notification_sound(new_settings.sound))))); + std::move(input_notify_peer), new_settings.get_input_peer_notify_settings()))); scope_ = scope; } @@ -432,6 +499,41 @@ class UpdateScopeNotifySettingsQuery final : public Td::ResultHandler { } }; +class SetReactionsNotifySettingsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit SetReactionsNotifySettingsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const ReactionNotificationSettings &settings) { + send_query(G()->net_query_creator().create( + telegram_api::account_setReactionsNotifySettings(settings.get_input_reactions_notify_settings()))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SetReactionsNotifySettingsQuery: " << to_string(ptr); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for set reaction notification settings: " << status; + + if (!td_->auth_manager_->is_bot()) { + // trying to repair notification settings + td_->notification_settings_manager_->send_get_reaction_notification_settings_query(Promise<>()); + } + + promise_.set_error(std::move(status)); + } +}; + class ResetNotifySettingsQuery final : public Td::ResultHandler { Promise promise_; @@ -554,7 +656,7 @@ void NotificationSettingsManager::init() { VLOG(notifications) << "Loaded notification settings in " << scope << ": " << *current_settings; - schedule_scope_unmute(scope, current_settings->mute_until); + schedule_scope_unmute(scope, current_settings->mute_until, G()->unix_time()); send_closure(G()->td(), &Td::send_update, get_update_scope_notification_settings_object(scope)); } @@ -562,10 +664,22 @@ void NotificationSettingsManager::init() { if (!channels_notification_settings_.is_synchronized && is_authorized) { channels_notification_settings_ = ScopeNotificationSettings( chats_notification_settings_.mute_until, dup_notification_sound(chats_notification_settings_.sound), - chats_notification_settings_.show_preview, false, false); + chats_notification_settings_.show_preview, chats_notification_settings_.use_default_mute_stories, + chats_notification_settings_.mute_stories, nullptr, false, false, false); channels_notification_settings_.is_synchronized = false; send_get_scope_notification_settings_query(NotificationSettingsScope::Channel, Promise<>()); } + auto reaction_notification_settings_string = + G()->td_db()->get_binlog_pmc()->get(get_reaction_notification_settings_database_key()); + if (!reaction_notification_settings_string.empty()) { + log_event_parse(reaction_notification_settings_, reaction_notification_settings_string).ensure(); + have_reaction_notification_settings_ = true; + + VLOG(notifications) << "Loaded reaction notification settings: " << reaction_notification_settings_; + } else { + send_get_reaction_notification_settings_query(Promise()); + } + send_closure(G()->td(), &Td::send_update, get_update_reaction_notification_settings_object()); } G()->td_db()->get_binlog_pmc()->erase("nsfac"); } @@ -591,15 +705,29 @@ int32 NotificationSettingsManager::get_scope_mute_until(NotificationSettingsScop return get_scope_notification_settings(scope)->mute_until; } +std::pair NotificationSettingsManager::get_scope_mute_stories(NotificationSettingsScope scope) const { + auto *settings = get_scope_notification_settings(scope); + return {settings->use_default_mute_stories, settings->mute_stories}; +} + const unique_ptr &NotificationSettingsManager::get_scope_notification_sound( NotificationSettingsScope scope) const { return get_scope_notification_settings(scope)->sound; } +const unique_ptr &NotificationSettingsManager::get_scope_story_notification_sound( + NotificationSettingsScope scope) const { + return get_scope_notification_settings(scope)->story_sound; +} + bool NotificationSettingsManager::get_scope_show_preview(NotificationSettingsScope scope) const { return get_scope_notification_settings(scope)->show_preview; } +bool NotificationSettingsManager::get_scope_hide_story_sender(NotificationSettingsScope scope) const { + return get_scope_notification_settings(scope)->hide_story_sender; +} + bool NotificationSettingsManager::get_scope_disable_pinned_message_notifications( NotificationSettingsScope scope) const { return get_scope_notification_settings(scope)->disable_pinned_message_notifications; @@ -614,7 +742,7 @@ tl_object_ptr NotificationSettingsManager::get_in if (!td_->messages_manager_->have_dialog(dialog_id)) { return nullptr; } - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return nullptr; } @@ -664,6 +792,12 @@ NotificationSettingsManager::get_update_scope_notification_settings_object(Notif get_notification_settings_scope_object(scope), get_scope_notification_settings_object(notification_settings)); } +td_api::object_ptr +NotificationSettingsManager::get_update_reaction_notification_settings_object() const { + return td_api::make_object( + reaction_notification_settings_.get_reaction_notification_settings_object()); +} + void NotificationSettingsManager::on_scope_unmute(NotificationSettingsScope scope) { if (td_->auth_manager_->is_bot()) { // just in case @@ -677,11 +811,11 @@ void NotificationSettingsManager::on_scope_unmute(NotificationSettingsScope scop return; } - auto now = G()->unix_time(); - if (notification_settings->mute_until > now) { - LOG(ERROR) << "Failed to unmute " << scope << " in " << now << ", will be unmuted in " - << notification_settings->mute_until; - schedule_scope_unmute(scope, notification_settings->mute_until); + auto unix_time = G()->unix_time(); + if (notification_settings->mute_until > unix_time) { + LOG(INFO) << "Failed to unmute " << scope << " in " << unix_time << ", will be unmuted in " + << notification_settings->mute_until; + schedule_scope_unmute(scope, notification_settings->mute_until, unix_time); return; } @@ -773,10 +907,50 @@ bool NotificationSettingsManager::update_scope_notification_settings(Notificatio return need_update_server; } -void NotificationSettingsManager::schedule_scope_unmute(NotificationSettingsScope scope, int32 mute_until) { - auto now = G()->unix_time_cached(); - if (mute_until >= now && mute_until < now + 366 * 86400) { - scope_unmute_timeout_.set_timeout_in(static_cast(scope) + 1, mute_until - now + 1); +void NotificationSettingsManager::send_get_reaction_notification_settings_query(Promise &&promise) { + if (td_->auth_manager_->is_bot()) { + LOG(ERROR) << "Can't get reaction notification settings"; + return promise.set_error(Status::Error(500, "Wrong getReactionNotificationSettings query")); + } + + td_->create_handler(std::move(promise))->send(); +} + +void NotificationSettingsManager::on_update_reaction_notification_settings( + ReactionNotificationSettings reaction_notification_settings) { + CHECK(!td_->auth_manager_->is_bot()); + if (reaction_notification_settings == reaction_notification_settings_) { + if (!have_reaction_notification_settings_) { + have_reaction_notification_settings_ = true; + save_reaction_notification_settings(); + } + return; + } + + VLOG(notifications) << "Update reaction notification settings from " << reaction_notification_settings_ << " to " + << reaction_notification_settings; + + reaction_notification_settings_ = std::move(reaction_notification_settings); + have_reaction_notification_settings_ = true; + + save_reaction_notification_settings(); + + send_closure(G()->td(), &Td::send_update, get_update_reaction_notification_settings_object()); +} + +string NotificationSettingsManager::get_reaction_notification_settings_database_key() { + return "rns"; +} + +void NotificationSettingsManager::save_reaction_notification_settings() const { + string key = get_reaction_notification_settings_database_key(); + G()->td_db()->get_binlog_pmc()->set(key, log_event_store(reaction_notification_settings_).as_slice().str()); +} + +void NotificationSettingsManager::schedule_scope_unmute(NotificationSettingsScope scope, int32 mute_until, + int32 unix_time) { + if (mute_until >= unix_time && mute_until < unix_time + 366 * 86400) { + scope_unmute_timeout_.set_timeout_in(static_cast(scope) + 1, mute_until - unix_time + 1); } else { scope_unmute_timeout_.cancel_timeout(static_cast(scope) + 1); } @@ -795,7 +969,7 @@ void NotificationSettingsManager::update_scope_unmute_timeout(NotificationSettin } CHECK(old_mute_until >= 0); - schedule_scope_unmute(scope, new_mute_until); + schedule_scope_unmute(scope, new_mute_until, G()->unix_time()); auto was_muted = old_mute_until != 0; auto is_muted = new_mute_until != 0; @@ -835,8 +1009,9 @@ FileId NotificationSettingsManager::get_saved_ringtone(int64 ringtone_id, Promis auto file_view = td_->file_manager_->get_file_view(file_id); CHECK(!file_view.empty()); CHECK(file_view.get_type() == FileType::Ringtone); - CHECK(file_view.has_remote_location()); - if (file_view.remote_location().get_id() == ringtone_id) { + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + if (full_remote_location->get_id() == ringtone_id) { return file_view.get_main_file_id(); } } @@ -861,11 +1036,12 @@ void NotificationSettingsManager::send_save_ringtone_query( // TODO log event auto file_view = td_->file_manager_->get_file_view(ringtone_file_id); CHECK(!file_view.empty()); - CHECK(file_view.has_remote_location()); - CHECK(file_view.remote_location().is_document()); - CHECK(!file_view.remote_location().is_web()); + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + CHECK(full_remote_location->is_document()); + CHECK(!full_remote_location->is_web()); td_->create_handler(std::move(promise)) - ->send(ringtone_file_id, file_view.remote_location().as_input_document(), unsave); + ->send(ringtone_file_id, full_remote_location->as_input_document(), unsave); } void NotificationSettingsManager::add_saved_ringtone(td_api::object_ptr &&input_file, @@ -907,9 +1083,10 @@ void NotificationSettingsManager::add_saved_ringtone(td_api::object_ptr td_->option_manager_->get_option_integer("notification_sound_duration_max")) { return promise.set_error(Status::Error(400, "Notification sound is too long")); } - if (file_view.has_remote_location() && !file_view.is_encrypted()) { - CHECK(file_view.remote_location().is_document()); - if (file_view.main_remote_location().is_web()) { + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr && !file_view.is_encrypted()) { + CHECK(main_remote_location->is_document()); + if (main_remote_location->is_web()) { return promise.set_error(Status::Error(400, "Can't use web document as notification sound")); } @@ -918,7 +1095,7 @@ void NotificationSettingsManager::add_saved_ringtone(td_api::object_ptrfile_manager_->register_remote( FullRemoteFileLocation(FileType::Ringtone, remote.get_id(), remote.get_access_hash(), remote.get_dc_id(), remote.get_file_reference().str()), @@ -984,23 +1161,25 @@ void NotificationSettingsManager::on_upload_ringtone(FileId file_id, FileView file_view = td_->file_manager_->get_file_view(file_id); CHECK(!file_view.is_encrypted()); CHECK(file_view.get_type() == FileType::Ringtone); - if (input_file == nullptr && file_view.has_remote_location()) { - if (file_view.main_remote_location().is_web()) { + const auto *main_remote_location = file_view.get_main_remote_location(); + if (input_file == nullptr && main_remote_location != nullptr) { + if (main_remote_location->is_web()) { return promise.set_error(Status::Error(400, "Can't use web document as notification sound")); } if (is_reupload) { return promise.set_error(Status::Error(400, "Failed to reupload the file")); } + auto main_file_id = file_view.get_main_file_id(); send_save_ringtone_query( - file_view.get_main_file_id(), false, + main_file_id, false, PromiseCreator::lambda( - [actor_id = actor_id(this), file_id = file_view.get_main_file_id(), promise = std::move(promise)]( + [actor_id = actor_id(this), main_file_id, promise = std::move(promise)]( Result> &&result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { - send_closure(actor_id, &NotificationSettingsManager::on_add_saved_ringtone, file_id, + send_closure(actor_id, &NotificationSettingsManager::on_add_saved_ringtone, main_file_id, result.move_as_ok(), std::move(promise)); } })); @@ -1099,8 +1278,9 @@ void NotificationSettingsManager::remove_saved_ringtone(int64 ringtone_id, Promi auto file_view = td_->file_manager_->get_file_view(file_id); CHECK(!file_view.empty()); CHECK(file_view.get_type() == FileType::Ringtone); - CHECK(file_view.has_remote_location()); - if (file_view.remote_location().get_id() == ringtone_id) { + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + if (full_remote_location->get_id() == ringtone_id) { send_save_ringtone_query( file_view.get_main_file_id(), true, PromiseCreator::lambda( @@ -1138,8 +1318,9 @@ void NotificationSettingsManager::on_remove_saved_ringtone(int64 ringtone_id, Pr auto file_view = td_->file_manager_->get_file_view(*it); CHECK(!file_view.empty()); CHECK(file_view.get_type() == FileType::Ringtone); - CHECK(file_view.has_remote_location()); - if (file_view.remote_location().get_id() == ringtone_id) { + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + if (full_remote_location->get_id() == ringtone_id) { saved_ringtone_file_ids_.erase(it); saved_ringtone_hash_ = 0; on_saved_ringtones_updated(false); @@ -1309,8 +1490,9 @@ NotificationSettingsManager::get_update_saved_notification_sounds_object() const auto file_view = file_manager->get_file_view(file_id); CHECK(!file_view.empty()); CHECK(file_view.get_type() == FileType::Ringtone); - CHECK(file_view.has_remote_location()); - return file_view.remote_location().get_id(); + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + return full_remote_location->get_id(); }); return td_api::make_object(std::move(ringtone_ids)); } @@ -1352,14 +1534,12 @@ FileSourceId NotificationSettingsManager::get_saved_ringtones_file_source_id() { void NotificationSettingsManager::send_get_dialog_notification_settings_query(DialogId dialog_id, MessageId top_thread_message_id, Promise &&promise) { - if (td_->auth_manager_->is_bot() || dialog_id.get_type() == DialogType::SecretChat) { - LOG(WARNING) << "Can't get notification settings for " << dialog_id; + if (td_->auth_manager_->is_bot()) { + LOG(ERROR) << "Can't get notification settings for " << dialog_id; return promise.set_error(Status::Error(500, "Wrong getDialogNotificationSettings query")); } - if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { - LOG(WARNING) << "Have no access to " << dialog_id << " to get notification settings"; - return promise.set_error(Status::Error(400, "Can't access the chat")); - } + TRY_STATUS_PROMISE(promise, + td_->dialog_manager_->check_dialog_access_in_memory(dialog_id, false, AccessRights::Read)); auto &promises = get_dialog_notification_settings_queries_[{dialog_id, top_thread_message_id}]; promises.push_back(std::move(promise)); @@ -1471,11 +1651,71 @@ void NotificationSettingsManager::reset_notify_settings(Promise &&promise) td_->create_handler(std::move(promise))->send(); } +Status NotificationSettingsManager::set_reaction_notification_settings( + ReactionNotificationSettings &¬ification_settings) { + CHECK(!td_->auth_manager_->is_bot()); + notification_settings.update_default_notification_sound(reaction_notification_settings_); + if (notification_settings == reaction_notification_settings_) { + have_reaction_notification_settings_ = true; + return Status::OK(); + } + + VLOG(notifications) << "Update reaction notification settings from " << reaction_notification_settings_ << " to " + << notification_settings; + + reaction_notification_settings_ = std::move(notification_settings); + have_reaction_notification_settings_ = true; + + save_reaction_notification_settings(); + + send_closure(G()->td(), &Td::send_update, get_update_reaction_notification_settings_object()); + + update_reaction_notification_settings_on_server(0); + return Status::OK(); +} + +class NotificationSettingsManager::UpdateReactionNotificationSettingsOnServerLogEvent { + public: + template + void store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + } + + template + void parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + } +}; + +uint64 NotificationSettingsManager::save_update_reaction_notification_settings_on_server_log_event() { + UpdateReactionNotificationSettingsOnServerLogEvent log_event; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::UpdateReactionNotificationSettingsOnServer, + get_log_event_storer(log_event)); +} + +void NotificationSettingsManager::update_reaction_notification_settings_on_server(uint64 log_event_id) { + CHECK(!td_->auth_manager_->is_bot()); + if (log_event_id == 0) { + log_event_id = save_update_reaction_notification_settings_on_server_log_event(); + } + + LOG(INFO) << "Update reaction notification settings on server with log_event " << log_event_id; + td_->create_handler(get_erase_log_event_promise(log_event_id)) + ->send(reaction_notification_settings_); +} + void NotificationSettingsManager::get_notify_settings_exceptions(NotificationSettingsScope scope, bool filter_scope, bool compare_sound, Promise &&promise) { td_->create_handler(std::move(promise))->send(scope, filter_scope, compare_sound); } +void NotificationSettingsManager::get_story_notification_settings_exceptions( + Promise> &&promise) { + td_->create_handler(std::move(promise))->send(); +} + void NotificationSettingsManager::on_binlog_events(vector &&events) { if (G()->close_flag()) { return; @@ -1490,6 +1730,13 @@ void NotificationSettingsManager::on_binlog_events(vector &&events) update_scope_notification_settings_on_server(log_event.scope_, event.id_); break; } + case LogEvent::HandlerType::UpdateReactionNotificationSettingsOnServer: { + UpdateReactionNotificationSettingsOnServerLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + update_reaction_notification_settings_on_server(event.id_); + break; + } default: LOG(FATAL) << "Unsupported log event type " << event.type_; } @@ -1510,6 +1757,8 @@ void NotificationSettingsManager::get_current_state(vector +#include namespace td { @@ -46,10 +48,16 @@ class NotificationSettingsManager final : public Actor { int32 get_scope_mute_until(NotificationSettingsScope scope) const; + std::pair get_scope_mute_stories(NotificationSettingsScope scope) const; + const unique_ptr &get_scope_notification_sound(NotificationSettingsScope scope) const; + const unique_ptr &get_scope_story_notification_sound(NotificationSettingsScope scope) const; + bool get_scope_show_preview(NotificationSettingsScope scope) const; + bool get_scope_hide_story_sender(NotificationSettingsScope scope) const; + bool get_scope_disable_pinned_message_notifications(NotificationSettingsScope scope) const; bool get_scope_disable_mention_notifications(NotificationSettingsScope scope) const; @@ -60,6 +68,8 @@ class NotificationSettingsManager final : public Actor { void on_update_scope_notify_settings(NotificationSettingsScope scope, tl_object_ptr &&peer_notify_settings); + void on_update_reaction_notification_settings(ReactionNotificationSettings reaction_notification_settings); + void add_saved_ringtone(td_api::object_ptr &&input_file, Promise> &&promise); @@ -85,6 +95,8 @@ class NotificationSettingsManager final : public Actor { Promise &&promise); void send_get_scope_notification_settings_query(NotificationSettingsScope scope, Promise &&promise); + void send_get_reaction_notification_settings_query(Promise &&promise); + void on_get_dialog_notification_settings_query_finished(DialogId dialog_id, MessageId top_thread_message_id, Status &&status); @@ -95,6 +107,8 @@ class NotificationSettingsManager final : public Actor { td_api::object_ptr &¬ification_settings) TD_WARN_UNUSED_RESULT; + Status set_reaction_notification_settings(ReactionNotificationSettings &¬ification_settings) TD_WARN_UNUSED_RESULT; + void reset_scope_notification_settings(); void reset_notify_settings(Promise &&promise); @@ -102,6 +116,8 @@ class NotificationSettingsManager final : public Actor { void get_notify_settings_exceptions(NotificationSettingsScope scope, bool filter_scope, bool compare_sound, Promise &&promise); + void get_story_notification_settings_exceptions(Promise> &&promise); + void init(); void on_binlog_events(vector &&events); @@ -110,6 +126,7 @@ class NotificationSettingsManager final : public Actor { private: class UpdateScopeNotificationSettingsOnServerLogEvent; + class UpdateReactionNotificationSettingsOnServerLogEvent; class RingtoneListLogEvent; @@ -163,6 +180,9 @@ class NotificationSettingsManager final : public Actor { td_api::object_ptr get_update_scope_notification_settings_object( NotificationSettingsScope scope) const; + td_api::object_ptr get_update_reaction_notification_settings_object() + const; + td_api::object_ptr get_update_saved_notification_sounds_object() const; void on_scope_unmute(NotificationSettingsScope scope); @@ -179,10 +199,18 @@ class NotificationSettingsManager final : public Actor { void update_scope_notification_settings_on_server(NotificationSettingsScope scope, uint64 log_event_id); - void schedule_scope_unmute(NotificationSettingsScope scope, int32 mute_until); + void schedule_scope_unmute(NotificationSettingsScope scope, int32 mute_until, int32 unix_time); void update_scope_unmute_timeout(NotificationSettingsScope scope, int32 &old_mute_until, int32 new_mute_until); + static string get_reaction_notification_settings_database_key(); + + void save_reaction_notification_settings() const; + + uint64 save_update_reaction_notification_settings_on_server_log_event(); + + void update_reaction_notification_settings_on_server(uint64 log_event_id); + Td *td_; ActorShared<> parent_; @@ -194,6 +222,9 @@ class NotificationSettingsManager final : public Actor { ScopeNotificationSettings chats_notification_settings_; ScopeNotificationSettings channels_notification_settings_; + ReactionNotificationSettings reaction_notification_settings_; + bool have_reaction_notification_settings_ = false; + MultiTimeout scope_unmute_timeout_{"ScopeUnmuteTimeout"}; int64 saved_ringtone_hash_ = 0; @@ -216,7 +247,7 @@ class NotificationSettingsManager final : public Actor { vector> reload_saved_ringtones_queries_; vector> repair_saved_ringtones_queries_; - FlatHashMap>, FullMessageIdHash> get_dialog_notification_settings_queries_; + FlatHashMap>, MessageFullIdHash> get_dialog_notification_settings_queries_; }; } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationSound.cpp b/protocols/Telegram/tdlib/td/td/telegram/NotificationSound.cpp index 38cc8f53ae..395fc1f617 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/NotificationSound.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationSound.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -223,7 +223,7 @@ unique_ptr get_notification_sound(bool use_default_sound, int return td::make_unique(ringtone_id); } -static unique_ptr get_notification_sound(telegram_api::NotificationSound *notification_sound) { +unique_ptr get_notification_sound(telegram_api::NotificationSound *notification_sound) { if (notification_sound == nullptr) { return nullptr; } @@ -251,22 +251,25 @@ static unique_ptr get_notification_sound(telegram_api::Notifi } } -unique_ptr get_notification_sound(telegram_api::peerNotifySettings *settings) { +unique_ptr get_notification_sound(telegram_api::peerNotifySettings *settings, bool for_stories) { CHECK(settings != nullptr); telegram_api::NotificationSound *sound = #if TD_ANDROID - settings->android_sound_.get(); -#elif TD_DARWIN_IOS || TD_DARWIN_TV_OS || TD_DARWIN_WATCH_OS - settings->ios_sound_.get(); + for_stories ? settings->stories_android_sound_.get() : settings->android_sound_.get(); +#elif TD_DARWIN_IOS || TD_DARWIN_TV_OS || TD_DARWIN_VISION_OS || TD_DARWIN_WATCH_OS || TD_DARWIN_UNKNOWN + for_stories ? settings->stories_ios_sound_.get() : settings->ios_sound_.get(); #else - settings->other_sound_.get(); + for_stories ? settings->stories_other_sound_.get() : settings->other_sound_.get(); #endif return get_notification_sound(sound); } telegram_api::object_ptr get_input_notification_sound( - const unique_ptr ¬ification_sound) { + const unique_ptr ¬ification_sound, bool return_non_null) { if (notification_sound == nullptr) { + if (return_non_null) { + return telegram_api::make_object(); + } return nullptr; } diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationSound.h b/protocols/Telegram/tdlib/td/td/telegram/NotificationSound.h index accfb141dc..19ca253891 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/NotificationSound.h +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationSound.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -55,12 +55,14 @@ int64 get_notification_sound_ringtone_id(const unique_ptr &no unique_ptr get_legacy_notification_sound(const string &sound); +unique_ptr get_notification_sound(telegram_api::NotificationSound *notification_sound); + unique_ptr get_notification_sound(bool use_default_sound, int64 ringtone_id); -unique_ptr get_notification_sound(telegram_api::peerNotifySettings *settings); +unique_ptr get_notification_sound(telegram_api::peerNotifySettings *settings, bool for_stories); telegram_api::object_ptr get_input_notification_sound( - const unique_ptr ¬ification_sound); + const unique_ptr ¬ification_sound, bool return_non_null = false); unique_ptr dup_notification_sound(const unique_ptr ¬ification_sound); diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationType.cpp b/protocols/Telegram/tdlib/td/td/telegram/NotificationType.cpp index 947123e90d..f249e1f391 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/NotificationType.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationType.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,7 +9,6 @@ #include "td/telegram/AnimationsManager.h" #include "td/telegram/AudiosManager.h" #include "td/telegram/DocumentsManager.h" -#include "td/telegram/Global.h" #include "td/telegram/MessageSender.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/PhotoFormat.h" @@ -19,6 +18,7 @@ #include "td/telegram/VideosManager.h" #include "td/telegram/VoiceNotesManager.h" +#include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/Slice.h" @@ -35,7 +35,7 @@ class NotificationTypeMessage final : public NotificationType { return false; } - MessageId get_message_id() const final { + NotificationObjectId get_object_id() const final { return message_id_; } @@ -43,9 +43,9 @@ class NotificationTypeMessage final : public NotificationType { return {}; } - td_api::object_ptr get_notification_type_object(DialogId dialog_id) const final { - auto message_object = G()->td().get_actor_unsafe()->messages_manager_->get_message_object( - {dialog_id, message_id_}, "get_notification_type_object"); + td_api::object_ptr get_notification_type_object(Td *td, DialogId dialog_id) const final { + auto message_object = + td->messages_manager_->get_message_object({dialog_id, message_id_}, "get_notification_type_object"); if (message_object == nullptr) { return nullptr; } @@ -74,15 +74,15 @@ class NotificationTypeSecretChat final : public NotificationType { return false; } - MessageId get_message_id() const final { - return MessageId(); + NotificationObjectId get_object_id() const final { + return NotificationObjectId(); } vector get_file_ids(const Td *td) const final { return {}; } - td_api::object_ptr get_notification_type_object(DialogId dialog_id) const final { + td_api::object_ptr get_notification_type_object(Td *, DialogId) const final { return td_api::make_object(); } @@ -104,15 +104,15 @@ class NotificationTypeCall final : public NotificationType { return false; } - MessageId get_message_id() const final { - return MessageId::max(); + NotificationObjectId get_object_id() const final { + return NotificationObjectId::max(); } vector get_file_ids(const Td *td) const final { return {}; } - td_api::object_ptr get_notification_type_object(DialogId dialog_id) const final { + td_api::object_ptr get_notification_type_object(Td *, DialogId) const final { return td_api::make_object(call_id_.get()); } @@ -136,7 +136,7 @@ class NotificationTypePushMessage final : public NotificationType { return true; } - MessageId get_message_id() const final { + NotificationObjectId get_object_id() const final { return message_id_; } @@ -148,7 +148,8 @@ class NotificationTypePushMessage final : public NotificationType { return photo_get_file_ids(photo_); } - static td_api::object_ptr get_push_message_content_object(Slice key, const string &arg, + static td_api::object_ptr get_push_message_content_object(Td *td, Slice key, + const string &arg, const Photo &photo, const Document &document) { bool is_pinned = false; @@ -167,14 +168,12 @@ class NotificationTypePushMessage final : public NotificationType { switch (key[8]) { case 'A': if (key == "MESSAGE_ANIMATION") { - auto animations_manager = G()->td().get_actor_unsafe()->animations_manager_.get(); return td_api::make_object( - animations_manager->get_animation_object(document.file_id), arg, is_pinned); + td->animations_manager_->get_animation_object(document.file_id), arg, is_pinned); } if (key == "MESSAGE_AUDIO") { - auto audios_manager = G()->td().get_actor_unsafe()->audios_manager_.get(); return td_api::make_object( - audios_manager->get_audio_object(document.file_id), is_pinned); + td->audios_manager_->get_audio_object(document.file_id), is_pinned); } if (key == "MESSAGE_AUDIOS") { return td_api::make_object(to_integer(arg), false, false, true, @@ -229,9 +228,8 @@ class NotificationTypePushMessage final : public NotificationType { break; case 'D': if (key == "MESSAGE_DOCUMENT") { - auto documents_manager = G()->td().get_actor_unsafe()->documents_manager_.get(); return td_api::make_object( - documents_manager->get_document_object(document.file_id, PhotoFormat::Jpeg), is_pinned); + td->documents_manager_->get_document_object(document.file_id, PhotoFormat::Jpeg), is_pinned); } if (key == "MESSAGE_DOCUMENTS") { return td_api::make_object(to_integer(arg), false, false, false, @@ -257,6 +255,37 @@ class NotificationTypePushMessage final : public NotificationType { } return td_api::make_object(title, score, is_pinned); } + if (key == "MESSAGE_GIFTCODE") { + auto month_count = to_integer(arg); + return td_api::make_object(month_count); + } + if (key == "MESSAGE_GIVEAWAY") { + int32 user_count = 0; + int32 month_count = 0; + if (!is_pinned) { + string user_count_str; + string month_count_str; + std::tie(user_count_str, month_count_str) = split(arg); + user_count = to_integer(user_count_str); + month_count = to_integer(month_count_str); + } + return td_api::make_object( + user_count, is_pinned ? nullptr : td_api::make_object(month_count), + is_pinned); + } + if (key == "MESSAGE_GIVEAWAY_STARS") { + int32 user_count = 0; + int64 star_count = 0; + if (!is_pinned) { + string user_count_str; + string star_count_str; + std::tie(user_count_str, star_count_str) = split(arg); + user_count = to_integer(user_count_str); + star_count = to_integer(star_count_str); + } + return td_api::make_object( + user_count, is_pinned ? nullptr : td_api::make_object(star_count), is_pinned); + } break; case 'I': if (key == "MESSAGE_INVOICE") { @@ -273,9 +302,8 @@ class NotificationTypePushMessage final : public NotificationType { break; case 'P': if (key == "MESSAGE_PHOTO") { - auto file_manager = G()->td().get_actor_unsafe()->file_manager_.get(); - return td_api::make_object(get_photo_object(file_manager, photo), arg, false, - is_pinned); + return td_api::make_object(get_photo_object(td->file_manager_.get(), photo), + arg, false, is_pinned); } if (key == "MESSAGE_PHOTOS") { return td_api::make_object(to_integer(arg), true, false, false, @@ -284,6 +312,13 @@ class NotificationTypePushMessage final : public NotificationType { if (key == "MESSAGE_POLL") { return td_api::make_object(arg, true, is_pinned); } + if (key == "MESSAGE_PAID_MEDIA") { + int64 star_count = 0; + if (!is_pinned) { + star_count = to_integer(arg); + } + return td_api::make_object(star_count, is_pinned); + } break; case 'Q': if (key == "MESSAGE_QUIZ") { @@ -309,9 +344,11 @@ class NotificationTypePushMessage final : public NotificationType { return td_api::make_object(nullptr, arg, true, false); } if (key == "MESSAGE_STICKER") { - auto stickers_manager = G()->td().get_actor_unsafe()->stickers_manager_.get(); return td_api::make_object( - stickers_manager->get_sticker_object(document.file_id), trim(arg), is_pinned); + td->stickers_manager_->get_sticker_object(document.file_id), trim(arg), is_pinned); + } + if (key == "MESSAGE_STORY") { + return td_api::make_object(is_pinned); } if (key == "MESSAGE_SUGGEST_PHOTO") { return td_api::make_object(); @@ -324,23 +361,20 @@ class NotificationTypePushMessage final : public NotificationType { break; case 'V': if (key == "MESSAGE_VIDEO") { - auto videos_manager = G()->td().get_actor_unsafe()->videos_manager_.get(); return td_api::make_object( - videos_manager->get_video_object(document.file_id), arg, false, is_pinned); + td->videos_manager_->get_video_object(document.file_id), arg, false, is_pinned); } if (key == "MESSAGE_VIDEO_NOTE") { - auto video_notes_manager = G()->td().get_actor_unsafe()->video_notes_manager_.get(); return td_api::make_object( - video_notes_manager->get_video_note_object(document.file_id), is_pinned); + td->video_notes_manager_->get_video_note_object(document.file_id), is_pinned); } if (key == "MESSAGE_VIDEOS") { return td_api::make_object(to_integer(arg), false, true, false, false); } if (key == "MESSAGE_VOICE_NOTE") { - auto voice_notes_manager = G()->td().get_actor_unsafe()->voice_notes_manager_.get(); return td_api::make_object( - voice_notes_manager->get_voice_note_object(document.file_id), is_pinned); + td->voice_notes_manager_->get_voice_note_object(document.file_id), is_pinned); } break; case 'W': @@ -351,15 +385,15 @@ class NotificationTypePushMessage final : public NotificationType { default: break; } - UNREACHABLE(); + LOG(FATAL) << "Have unsupported push notification key " << key; + return nullptr; } - td_api::object_ptr get_notification_type_object(DialogId dialog_id) const final { - auto sender = get_message_sender_object(G()->td().get_actor_unsafe(), sender_user_id_, sender_dialog_id_, - "get_notification_type_object"); + td_api::object_ptr get_notification_type_object(Td *td, DialogId) const final { + auto sender = get_message_sender_object(td, sender_user_id_, sender_dialog_id_, "get_notification_type_object"); return td_api::make_object( message_id_.get(), std::move(sender), sender_name_, is_outgoing_, - get_push_message_content_object(key_, arg_, photo_, document_)); + get_push_message_content_object(td, key_, arg_, photo_, document_)); } StringBuilder &to_string_builder(StringBuilder &string_builder) const final { diff --git a/protocols/Telegram/tdlib/td/td/telegram/NotificationType.h b/protocols/Telegram/tdlib/td/td/telegram/NotificationType.h index ce2091a75f..1aaf1aeb2f 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/NotificationType.h +++ b/protocols/Telegram/tdlib/td/td/telegram/NotificationType.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +11,7 @@ #include "td/telegram/Document.h" #include "td/telegram/files/FileId.h" #include "td/telegram/MessageId.h" +#include "td/telegram/NotificationObjectId.h" #include "td/telegram/Photo.h" #include "td/telegram/td_api.h" #include "td/telegram/UserId.h" @@ -33,11 +34,12 @@ class NotificationType { virtual bool is_temporary() const = 0; - virtual MessageId get_message_id() const = 0; + virtual NotificationObjectId get_object_id() const = 0; virtual vector get_file_ids(const Td *td) const = 0; - virtual td_api::object_ptr get_notification_type_object(DialogId dialog_id) const = 0; + virtual td_api::object_ptr get_notification_type_object(Td *td, + DialogId dialog_id) const = 0; virtual StringBuilder &to_string_builder(StringBuilder &string_builder) const = 0; }; diff --git a/protocols/Telegram/tdlib/td/td/telegram/OnlineManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/OnlineManager.cpp new file mode 100644 index 0000000000..96a3a9fcaa --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/OnlineManager.cpp @@ -0,0 +1,164 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/OnlineManager.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/StateManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/Random.h" +#include "td/utils/Status.h" + +namespace td { + +class UpdateStatusQuery final : public Td::ResultHandler { + bool is_offline_; + + public: + NetQueryRef send(bool is_offline) { + is_offline_ = is_offline; + auto net_query = G()->net_query_creator().create(telegram_api::account_updateStatus(is_offline)); + auto result = net_query.get_weak(); + send_query(std::move(net_query)); + return result; + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + LOG(INFO) << "Receive result for UpdateStatusQuery: " << result; + td_->online_manager_->on_update_status_success(!is_offline_); + } + + void on_error(Status status) final { + if (status.code() != NetQuery::Canceled && !G()->is_expected_error(status)) { + LOG(ERROR) << "Receive error for UpdateStatusQuery: " << status; + } + } +}; + +OnlineManager::OnlineManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void OnlineManager::tear_down() { + parent_.reset(); +} + +void OnlineManager::start_up() { + init(); +} + +void OnlineManager::init() { + if (is_online_) { + on_online_updated(false /*ignored*/, true); + } + if (td_->auth_manager_->is_bot()) { + set_is_bot_online(true); + } +} + +void OnlineManager::on_online_timeout_callback(void *online_manager_ptr) { + if (G()->close_flag()) { + return; + } + + auto online_manager = static_cast(online_manager_ptr); + send_closure_later(online_manager->actor_id(online_manager), &OnlineManager::on_online_updated, false, true); +} + +void OnlineManager::on_ping_server_timeout_callback(void *online_manager_ptr) { + if (G()->close_flag()) { + return; + } + + auto online_manager = static_cast(online_manager_ptr); + send_closure_later(online_manager->actor_id(online_manager), &OnlineManager::on_ping_server_timeout); +} + +void OnlineManager::on_online_updated(bool force, bool send_update) { + if (G()->close_flag() || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { + return; + } + if (force || is_online_) { + td_->user_manager_->set_my_online_status(is_online_, send_update, true); + if (!update_status_query_.empty()) { + LOG(INFO) << "Cancel previous update status query"; + cancel_query(update_status_query_); + } + update_status_query_ = td_->create_handler()->send(!is_online_); + } + if (is_online_) { + online_timeout_.set_callback(std::move(on_online_timeout_callback)); + online_timeout_.set_callback_data(static_cast(this)); + online_timeout_.set_timeout_in(static_cast(G()->get_option_integer("online_update_period_ms", 210000)) * + 1e-3); + } else { + online_timeout_.cancel_timeout(); + } +} + +void OnlineManager::on_update_status_success(bool is_online) { + if (is_online == is_online_) { + if (!update_status_query_.empty()) { + update_status_query_ = NetQueryRef(); + } + td_->user_manager_->set_my_online_status(is_online_, true, false); + } +} + +bool OnlineManager::is_online() const { + return is_online_; +} + +void OnlineManager::set_is_online(bool is_online) { + if (is_online == is_online_) { + return; + } + + is_online_ = is_online; + if (td_->auth_manager_ != nullptr) { // postpone if there is no AuthManager yet + on_online_updated(true, true); + } +} + +void OnlineManager::set_is_bot_online(bool is_bot_online) { + ping_server_timeout_.set_callback(std::move(on_ping_server_timeout_callback)); + ping_server_timeout_.set_callback_data(static_cast(this)); + ping_server_timeout_.set_timeout_in(PING_SERVER_TIMEOUT + Random::fast(0, PING_SERVER_TIMEOUT / 5)); + + if (td_->option_manager_->get_option_integer("session_count") > 1) { + is_bot_online = false; + } + + if (is_bot_online == is_bot_online_) { + return; + } + + is_bot_online_ = is_bot_online; + send_closure(G()->state_manager(), &StateManager::on_online, is_bot_online_); +} + +void OnlineManager::on_ping_server_timeout() { + if (G()->close_flag() || td_->updates_manager_ == nullptr || !td_->auth_manager_->is_authorized()) { + return; + } + td_->updates_manager_->ping_server(); + set_is_bot_online(false); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/OnlineManager.h b/protocols/Telegram/tdlib/td/td/telegram/OnlineManager.h new file mode 100644 index 0000000000..fda4803e8a --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/OnlineManager.h @@ -0,0 +1,60 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/net/NetQuery.h" + +#include "td/actor/actor.h" +#include "td/actor/Timeout.h" + +#include "td/utils/common.h" + +namespace td { + +class Td; + +class OnlineManager final : public Actor { + public: + OnlineManager(Td *td, ActorShared<> parent); + + void init(); + + void on_online_updated(bool force, bool send_update); + + void on_update_status_success(bool is_online); + + bool is_online() const; + + void set_is_online(bool is_online); + + void set_is_bot_online(bool is_bot_online); + + private: + static constexpr int32 PING_SERVER_TIMEOUT = 300; + + void tear_down() final; + + void start_up() final; + + static void on_online_timeout_callback(void *online_manager_ptr); + + static void on_ping_server_timeout_callback(void *online_manager_ptr); + + void on_ping_server_timeout(); + + Td *td_; + ActorShared<> parent_; + + bool is_online_ = false; + bool is_bot_online_ = false; + NetQueryRef update_status_query_; + + Timeout online_timeout_; + Timeout ping_server_timeout_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/OptionManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/OptionManager.cpp index b3454ad04c..64f00b133a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/OptionManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/OptionManager.cpp @@ -1,33 +1,38 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/OptionManager.h" +#include "td/telegram/AccountManager.h" #include "td/telegram/AnimationsManager.h" #include "td/telegram/AttachMenuManager.h" #include "td/telegram/AuthManager.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/ConfigManager.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/CountryInfoManager.h" #include "td/telegram/DialogId.h" #include "td/telegram/GitCommitHash.h" #include "td/telegram/Global.h" #include "td/telegram/JsonValue.h" #include "td/telegram/LanguagePackManager.h" -#include "td/telegram/MessageReaction.h" #include "td/telegram/net/MtprotoHeader.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/NotificationManager.h" +#include "td/telegram/OnlineManager.h" +#include "td/telegram/PeopleNearbyManager.h" +#include "td/telegram/ReactionType.h" #include "td/telegram/StateManager.h" #include "td/telegram/StickersManager.h" #include "td/telegram/StorageManager.h" +#include "td/telegram/StoryManager.h" #include "td/telegram/SuggestedAction.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" #include "td/telegram/TopDialogManager.h" +#include "td/telegram/UserManager.h" #include "td/db/KeyValueSyncInterface.h" #include "td/db/TsSeqKeyValue.h" @@ -35,6 +40,7 @@ #include "td/actor/actor.h" #include "td/utils/algorithm.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/logging.h" #include "td/utils/misc.h" #include "td/utils/port/Clocks.h" @@ -54,71 +60,180 @@ OptionManager::OptionManager(Td *td) , option_pmc_(G()->td_db()->get_config_pmc_shared()) { send_unix_time_update(); - auto all_options = option_pmc_->get_all(); - all_options["utc_time_offset"] = PSTRING() << 'I' << Clocks::tz_offset(); - for (const auto &name_value : all_options) { - const string &name = name_value.first; - options_->set(name, name_value.second); + auto &options = options_->inner(); + + option_pmc_->for_each([&](Slice name, Slice value) { + if (name == "utc_time_offset") { + return; + } + CHECK(!name.empty()); + options.set(name, value); if (!is_internal_option(name)) { send_closure(G()->td(), &Td::send_update, - td_api::make_object(name, get_option_value_object(name_value.second))); + td_api::make_object(name.str(), get_option_value_object(value))); } else { auto update = get_internal_option_update(name); if (update != nullptr) { send_closure(G()->td(), &Td::send_update, std::move(update)); } } - } + }); - if (!have_option("message_text_length_max")) { - set_option_integer("message_text_length_max", 4096); - } - if (!have_option("message_caption_length_max")) { - set_option_integer("message_caption_length_max", 1024); - } - if (!have_option("bio_length_max")) { - set_option_integer("bio_length_max", 70); - } - if (!have_option("suggested_video_note_length")) { - set_option_integer("suggested_video_note_length", 384); - } - if (!have_option("suggested_video_note_video_bitrate")) { - set_option_integer("suggested_video_note_video_bitrate", 1000); - } - if (!have_option("suggested_video_note_audio_bitrate")) { - set_option_integer("suggested_video_note_audio_bitrate", 64); - } - if (!have_option("notification_sound_duration_max")) { - set_option_integer("notification_sound_duration_max", 5); - } - if (!have_option("notification_sound_size_max")) { - set_option_integer("notification_sound_size_max", 307200); - } - if (!have_option("notification_sound_count_max")) { - set_option_integer("notification_sound_count_max", G()->is_test_dc() ? 5 : 100); - } - if (!have_option("chat_folder_count_max")) { - set_option_integer("chat_folder_count_max", G()->is_test_dc() ? 3 : 10); - } - if (!have_option("chat_folder_chosen_chat_count_max")) { - set_option_integer("chat_folder_chosen_chat_count_max", G()->is_test_dc() ? 5 : 100); - } - if (!have_option("aggressive_anti_spam_supergroup_member_count_min")) { - set_option_integer("aggressive_anti_spam_supergroup_member_count_min", G()->is_test_dc() ? 1 : 100); - } - if (!have_option("pinned_forum_topic_count_max")) { - set_option_integer("pinned_forum_topic_count_max", G()->is_test_dc() ? 3 : 5); + auto utc_time_offset = PSTRING() << 'I' << Clocks::tz_offset(); + options.set("utc_time_offset", utc_time_offset); + send_closure(G()->td(), &Td::send_update, + td_api::make_object("utc_time_offset", get_option_value_object(utc_time_offset))); + + bool is_test_dc = G()->is_test_dc(); + auto set_default_integer_option = [&](string name, int64 value) { + if (options.isset(name)) { + return; + } + auto str_value = PSTRING() << 'I' << value; + options.set(name, str_value); + option_pmc_->set(name, str_value); + + if (!is_internal_option(name)) { + send_closure( + G()->td(), &Td::send_update, + td_api::make_object(name, td_api::make_object(value))); + } + }; + set_default_integer_option("telegram_service_notifications_chat_id", + DialogId(UserManager::get_service_notifications_user_id()).get()); + set_default_integer_option("replies_bot_chat_id", DialogId(UserManager::get_replies_bot_user_id()).get()); + set_default_integer_option("group_anonymous_bot_user_id", UserManager::get_anonymous_bot_user_id().get()); + set_default_integer_option("channel_bot_user_id", UserManager::get_channel_bot_user_id().get()); + set_default_integer_option("anti_spam_bot_user_id", UserManager::get_anti_spam_bot_user_id().get()); + set_default_integer_option("message_caption_length_max", 1024); + set_default_integer_option("message_reply_quote_length_max", 1024); + set_default_integer_option("story_caption_length_max", 200); + set_default_integer_option("bio_length_max", 70); + set_default_integer_option("suggested_video_note_length", 384); + set_default_integer_option("suggested_video_note_video_bitrate", 1000); + set_default_integer_option("suggested_video_note_audio_bitrate", 64); + set_default_integer_option("notification_sound_duration_max", 5); + set_default_integer_option("notification_sound_size_max", 307200); + set_default_integer_option("notification_sound_count_max", is_test_dc ? 5 : 100); + set_default_integer_option("chat_folder_count_max", is_test_dc ? 3 : 10); + set_default_integer_option("chat_folder_chosen_chat_count_max", is_test_dc ? 5 : 100); + set_default_integer_option("aggressive_anti_spam_supergroup_member_count_min", is_test_dc ? 1 : 100); + set_default_integer_option("pinned_forum_topic_count_max", is_test_dc ? 3 : 5); + set_default_integer_option("story_stealth_mode_past_period", 300); + set_default_integer_option("story_stealth_mode_future_period", 1500); + set_default_integer_option("story_stealth_mode_cooldown_period", 3600); + set_default_integer_option("giveaway_additional_chat_count_max", is_test_dc ? 3 : 10); + set_default_integer_option("giveaway_country_count_max", is_test_dc ? 3 : 10); + set_default_integer_option("giveaway_boost_count_per_premium", 4); + set_default_integer_option("giveaway_duration_max", 7 * 86400); + set_default_integer_option("premium_gift_boost_count", 3); + set_default_integer_option("chat_boost_level_max", is_test_dc ? 10 : 100); + set_default_integer_option("chat_available_reaction_count_max", 100); + set_default_integer_option("channel_bg_icon_level_min", is_test_dc ? 1 : 4); + set_default_integer_option("channel_custom_wallpaper_level_min", is_test_dc ? 4 : 10); + set_default_integer_option("channel_emoji_status_level_min", is_test_dc ? 2 : 8); + set_default_integer_option("channel_profile_bg_icon_level_min", is_test_dc ? 1 : 7); + set_default_integer_option("channel_restrict_sponsored_level_min", is_test_dc ? 5 : 50); + set_default_integer_option("channel_wallpaper_level_min", is_test_dc ? 3 : 9); + set_default_integer_option("pm_read_date_expire_period", 604800); + set_default_integer_option("group_transcribe_level_min", is_test_dc ? 4 : 6); + set_default_integer_option("group_emoji_stickers_level_min", is_test_dc ? 1 : 4); + set_default_integer_option("group_profile_bg_icon_level_min", is_test_dc ? 1 : 5); + set_default_integer_option("group_emoji_status_level_min", is_test_dc ? 2 : 8); + set_default_integer_option("group_wallpaper_level_min", is_test_dc ? 3 : 9); + set_default_integer_option("group_custom_wallpaper_level_min", is_test_dc ? 4 : 10); + set_default_integer_option("quick_reply_shortcut_count_max", is_test_dc ? 10 : 100); + set_default_integer_option("quick_reply_shortcut_message_count_max", 20); + set_default_integer_option("business_start_page_title_length_max", 32); + set_default_integer_option("business_start_page_message_length_max", 70); + set_default_integer_option("premium_download_speedup", 10); + set_default_integer_option("premium_upload_speedup", 10); + set_default_integer_option("upload_premium_speedup_notify_period", 3600); + set_default_integer_option("business_chat_link_count_max", is_test_dc ? 5 : 100); + set_default_integer_option("pinned_story_count_max", 3); + set_default_integer_option("fact_check_length_max", 1024); + set_default_integer_option("star_withdrawal_count_min", is_test_dc ? 10 : 1000); + set_default_integer_option("story_link_area_count_max", 3); + set_default_integer_option("paid_media_message_star_count_max", 10000); + set_default_integer_option("bot_media_preview_count_max", 12); + set_default_integer_option("paid_reaction_star_count_max", 2500); + set_default_integer_option("subscription_star_count_max", 2500); + set_default_integer_option("usd_to_thousand_star_rate", 1410); + set_default_integer_option("thousand_star_to_usd_rate", 1300); + + if (options.isset("my_phone_number") || !options.isset("my_id")) { + update_premium_options(); } + set_option_empty("archive_and_mute_new_chats_from_unknown_users"); + set_option_empty("business_intro_title_length_max"); + set_option_empty("business_intro_message_length_max"); + set_option_empty("channel_custom_accent_color_boost_level_min"); set_option_empty("chat_filter_count_max"); set_option_empty("chat_filter_chosen_chat_count_max"); set_option_empty("forum_member_count_min"); set_option_empty("themed_emoji_statuses_sticker_set_id"); set_option_empty("themed_premium_statuses_sticker_set_id"); + set_option_empty("usd_to_1000_star_rate"); + set_option_empty("1000_star_to_usd_rate"); } OptionManager::~OptionManager() = default; +void OptionManager::update_premium_options() { + bool is_premium = get_option_boolean("is_premium"); + if (is_premium) { + set_option_integer("saved_animations_limit", get_option_integer("saved_gifs_limit_premium", 400)); + set_option_integer("favorite_stickers_limit", get_option_integer("stickers_faved_limit_premium", 10)); + set_option_integer("chat_folder_count_max", get_option_integer("dialog_filters_limit_premium", 20)); + set_option_integer("chat_folder_chosen_chat_count_max", + get_option_integer("dialog_filters_chats_limit_premium", 200)); + set_option_integer("pinned_chat_count_max", get_option_integer("dialogs_pinned_limit_premium", 100)); + set_option_integer("pinned_archived_chat_count_max", + get_option_integer("dialogs_folder_pinned_limit_premium", 200)); + set_option_integer("pinned_saved_messages_topic_count_max", + get_option_integer("saved_dialogs_pinned_limit_premium", 100)); + set_option_integer("bio_length_max", get_option_integer("about_length_limit_premium", 140)); + set_option_integer("chat_folder_invite_link_count_max", get_option_integer("chatlist_invites_limit_premium", 20)); + set_option_integer("added_shareable_chat_folder_count_max", + get_option_integer("chatlists_joined_limit_premium", 20)); + set_option_integer("active_story_count_max", get_option_integer("story_expiring_limit_premium", 100)); + set_option_integer("story_caption_length_max", get_option_integer("story_caption_length_limit_premium", 2048)); + set_option_integer("weekly_sent_story_count_max", get_option_integer("stories_sent_weekly_limit_premium", 700)); + set_option_integer("monthly_sent_story_count_max", get_option_integer("stories_sent_monthly_limit_premium", 3000)); + set_option_integer("story_suggested_reaction_area_count_max", + get_option_integer("stories_suggested_reactions_limit_premium", 5)); + + set_option_boolean("can_set_new_chat_privacy_settings", true); + set_option_boolean("can_use_text_entities_in_story_caption", true); + } else { + set_option_integer("saved_animations_limit", get_option_integer("saved_gifs_limit_default", 200)); + set_option_integer("favorite_stickers_limit", get_option_integer("stickers_faved_limit_default", 5)); + set_option_integer("chat_folder_count_max", get_option_integer("dialog_filters_limit_default", 10)); + set_option_integer("chat_folder_chosen_chat_count_max", + get_option_integer("dialog_filters_chats_limit_default", 100)); + set_option_integer("pinned_chat_count_max", get_option_integer("dialogs_pinned_limit_default", 5)); + set_option_integer("pinned_archived_chat_count_max", + get_option_integer("dialogs_folder_pinned_limit_default", 100)); + set_option_integer("pinned_saved_messages_topic_count_max", + get_option_integer("saved_dialogs_pinned_limit_default", 5)); + set_option_integer("bio_length_max", get_option_integer("about_length_limit_default", 70)); + set_option_integer("chat_folder_invite_link_count_max", get_option_integer("chatlist_invites_limit_default", 3)); + set_option_integer("added_shareable_chat_folder_count_max", + get_option_integer("chatlists_joined_limit_default", 2)); + set_option_integer("active_story_count_max", get_option_integer("story_expiring_limit_default", 3)); + set_option_integer("story_caption_length_max", get_option_integer("story_caption_length_limit_default", 200)); + set_option_integer("weekly_sent_story_count_max", get_option_integer("stories_sent_weekly_limit_default", 7)); + set_option_integer("monthly_sent_story_count_max", get_option_integer("stories_sent_monthly_limit_default", 30)); + set_option_integer("story_suggested_reaction_area_count_max", + get_option_integer("stories_suggested_reactions_limit_default", 1)); + + set_option_boolean("can_set_new_chat_privacy_settings", !get_option_boolean("need_premium_for_new_chat_privacy")); + set_option_boolean("can_use_text_entities_in_story_caption", + !get_option_boolean("need_premium_for_story_caption_entities")); + } +} + void OptionManager::on_td_inited() { is_td_inited_ = true; @@ -240,66 +355,121 @@ void OptionManager::on_update_server_time_difference() { } bool OptionManager::is_internal_option(Slice name) { - switch (name[0]) { - case 'a': - return name == "about_length_limit_default" || name == "about_length_limit_premium" || - name == "aggressive_anti_spam_supergroup_member_count_min" || name == "animated_emoji_zoom" || - name == "animation_search_emojis" || name == "animation_search_provider"; - case 'b': - return name == "base_language_pack_version"; - case 'c': - return name == "call_receive_timeout_ms" || name == "call_ring_timeout_ms" || - name == "caption_length_limit_default" || name == "caption_length_limit_premium" || - name == "channels_limit_default" || name == "channels_limit_premium" || - name == "channels_public_limit_default" || name == "channels_public_limit_premium" || - name == "channels_read_media_period" || name == "chat_read_mark_expire_period" || - name == "chat_read_mark_size_threshold"; - case 'd': - return name == "dc_txt_domain_name" || name == "default_reaction" || name == "default_reaction_needs_sync" || - name == "dialog_filters_chats_limit_default" || name == "dialog_filters_chats_limit_premium" || - name == "dialog_filters_limit_default" || name == "dialog_filters_limit_premium" || - name == "dialogs_folder_pinned_limit_default" || name == "dialogs_folder_pinned_limit_premium" || - name == "dialogs_pinned_limit_default" || name == "dialogs_pinned_limit_premium" || - name == "dice_emojis" || name == "dice_success_values"; - case 'e': - return name == "edit_time_limit" || name == "emoji_sounds"; - case 'f': - return name == "fragment_prefixes"; - case 'h': - return name == "hidden_members_group_size_min"; - case 'i': - return name == "ignored_restriction_reasons"; - case 'l': - return name == "language_pack_version"; - case 'm': - return name == "my_phone_number"; - case 'n': - return name == "notification_cloud_delay_ms" || name == "notification_default_delay_ms"; - case 'o': - return name == "online_cloud_timeout_ms" || name == "online_update_period_ms" || name == "otherwise_relogin_days"; - case 'p': - return name == "premium_bot_username" || name == "premium_features" || name == "premium_invoice_slug"; - case 'r': - return name == "rating_e_decay" || name == "reactions_uniq_max" || name == "reactions_user_max_default" || - name == "reactions_user_max_premium" || name == "recent_stickers_limit" || name == "revoke_pm_inbox" || - name == "revoke_time_limit" || name == "revoke_pm_time_limit"; - case 's': - return name == "saved_animations_limit" || name == "saved_gifs_limit_default" || - name == "saved_gifs_limit_premium" || name == "session_count" || name == "since_last_open" || - name == "stickers_faved_limit_default" || name == "stickers_faved_limit_premium" || - name == "stickers_normal_by_emoji_per_premium_num" || name == "stickers_premium_by_emoji_num"; - case 'v': - return name == "video_note_size_max"; - case 'w': - return name == "webfile_dc_id"; - default: - return false; - } + static const FlatHashSet internal_options{"about_length_limit_default", + "about_length_limit_premium", + "aggressive_anti_spam_supergroup_member_count_min", + "animated_emoji_zoom", + "animation_search_emojis", + "animation_search_provider", + "authorization_autoconfirm_period", + "base_language_pack_version", + "business_features", + "call_receive_timeout_ms", + "call_ring_timeout_ms", + "can_edit_fact_check", + "caption_length_limit_default", + "caption_length_limit_premium", + "channel_bg_icon_level_min", + "channel_custom_wallpaper_level_min", + "channel_emoji_status_level_min", + "channel_profile_bg_icon_level_min", + "channel_restrict_sponsored_level_min", + "channel_wallpaper_level_min", + "channels_limit_default", + "channels_limit_premium", + "channels_public_limit_default", + "channels_public_limit_premium", + "channels_read_media_period", + "chat_read_mark_expire_period", + "chat_read_mark_size_threshold", + "chatlist_invites_limit_default", + "chatlist_invites_limit_premium", + "chatlists_joined_limit_default", + "chatlists_joined_limit_premium", + "dc_txt_domain_name", + "default_reaction", + "default_reaction_needs_sync", + "dialog_filters_chats_limit_default", + "dialog_filters_chats_limit_premium", + "dialog_filters_limit_default", + "dialog_filters_limit_premium", + "dialogs_folder_pinned_limit_default", + "dialogs_folder_pinned_limit_premium", + "dialogs_pinned_limit_default", + "dialogs_pinned_limit_premium", + "dice_emojis", + "dice_success_values", + "dismiss_birthday_contact_today", + "edit_time_limit", + "emoji_sounds", + "fragment_prefixes", + "group_transcribe_level_min", + "group_emoji_stickers_level_min", + "group_profile_bg_icon_level_min", + "group_emoji_status_level_min", + "group_wallpaper_level_min", + "group_custom_wallpaper_level_min", + "hidden_members_group_size_min", + "ignored_restriction_reasons", + "language_pack_version", + "my_phone_number", + "need_premium_for_new_chat_privacy", + "need_premium_for_story_caption_entities", + "need_synchronize_archive_all_stories", + "notification_cloud_delay_ms", + "notification_default_delay_ms", + "online_cloud_timeout_ms", + "online_update_period_ms", + "otherwise_relogin_days", + "pm_read_date_expire_period", + "premium_bot_username", + "premium_features", + "premium_invoice_slug", + "premium_manage_subscription_url", + "rating_e_decay", + "reactions_uniq_max", + "reactions_user_max_default", + "reactions_user_max_premium", + "recent_stickers_limit", + "recommended_channels_limit_default", + "recommended_channels_limit_premium", + "restriction_add_platforms", + "revoke_pm_inbox", + "revoke_time_limit", + "revoke_pm_time_limit", + "saved_animations_limit", + "saved_dialogs_pinned_limit_default", + "saved_dialogs_pinned_limit_premium", + "saved_gifs_limit_default", + "saved_gifs_limit_premium", + "session_count", + "since_last_open", + "stickers_faved_limit_default", + "stickers_faved_limit_premium", + "stickers_normal_by_emoji_per_premium_num", + "stickers_premium_by_emoji_num", + "stories_changelog_user_id", + "stories_sent_monthly_limit_default", + "stories_sent_monthly_limit_premium", + "stories_sent_weekly_limit_default", + "stories_sent_weekly_limit_premium", + "stories_suggested_reactions_limit_default", + "stories_suggested_reactions_limit_premium", + "story_caption_length_limit_default", + "story_caption_length_limit_premium", + "story_expiring_limit_default", + "story_expiring_limit_premium", + "ton_proxy_address", + "upload_premium_speedup_notify_period", + "video_note_size_max", + "weather_bot_username", + "webfile_dc_id"}; + return internal_options.count(name) > 0; } td_api::object_ptr OptionManager::get_internal_option_update(Slice name) const { if (name == "default_reaction") { - return get_update_default_reaction_type(get_option_string(name)); + return ReactionType(get_option_string(name)).get_update_default_reaction_type(); } if (name == "otherwise_relogin_days") { auto days = narrow_cast(get_option_integer(name)); @@ -332,6 +502,9 @@ void OptionManager::on_option_updated(Slice name) { if (name == "animation_search_provider") { td_->animations_manager_->on_update_animation_search_provider(); } + if (name == "authorization_autoconfirm_period") { + td_->account_manager_->update_unconfirmed_authorization_timeout(true); + } break; case 'b': if (name == "base_language_pack_version") { @@ -362,6 +535,9 @@ void OptionManager::on_option_updated(Slice name) { if (name == "disable_top_chats") { send_closure(td_->top_dialog_manager_actor_, &TopDialogManager::update_is_enabled, !get_option_boolean(name)); } + if (name == "dismiss_birthday_contact_today") { + send_closure(td_->user_manager_actor_, &UserManager::reload_contact_birthdates, true); + } break; case 'e': if (name == "emoji_sounds") { @@ -378,13 +554,17 @@ void OptionManager::on_option_updated(Slice name) { break; case 'i': if (name == "ignored_restriction_reasons") { - send_closure(td_->contacts_manager_actor_, &ContactsManager::on_ignored_restriction_reasons_changed); + send_closure(td_->chat_manager_actor_, &ChatManager::on_ignored_restriction_reasons_changed); + send_closure(td_->user_manager_actor_, &UserManager::on_ignored_restriction_reasons_changed); } if (name == "is_emulator") { if (G()->mtproto_header().set_is_emulator(get_option_boolean(name))) { G()->net_query_dispatcher().update_mtproto_header(); } } + if (name == "is_premium") { + update_premium_options(); + } break; case 'l': if (name == "language_pack_id") { @@ -404,7 +584,21 @@ void OptionManager::on_option_updated(Slice name) { } } break; + case 'm': + if (name == "my_phone_number") { + send_closure(G()->config_manager(), &ConfigManager::reget_config, Promise()); + } + break; case 'n': + if (name == "need_premium_for_new_chat_privacy") { + update_premium_options(); + } + if (name == "need_premium_for_story_caption_entities") { + update_premium_options(); + } + if (name == "need_synchronize_archive_all_stories") { + send_closure(td_->story_manager_actor_, &StoryManager::try_synchronize_archive_all_stories); + } if (name == "notification_cloud_delay_ms") { send_closure(td_->notification_manager_actor_, &NotificationManager::on_notification_cloud_delay_changed); } @@ -468,11 +662,6 @@ void OptionManager::get_option(const string &name, Promiseconfig_manager_, &ConfigManager::get_global_privacy_settings, wrap_promise()); - } - break; case 'c': if (!is_bot && name == "can_ignore_sensitive_content_restrictions") { return send_closure_later(td_->config_manager_, &ConfigManager::get_content_settings, wrap_promise()); @@ -495,7 +684,8 @@ void OptionManager::get_option(const string &name, Promisecontacts_manager_actor_, &ContactsManager::get_is_location_visible, wrap_promise()); + send_closure_later(td_->people_nearby_manager_actor_, &PeopleNearbyManager::get_is_location_visible, + wrap_promise()); } else { pending_get_options_.emplace_back(name, std::move(promise)); } @@ -504,7 +694,7 @@ void OptionManager::get_option(const string &name, Promise(td_->is_online())); + return promise.set_value(td_api::make_object(td_->online_manager_->is_online())); } break; case 'u': @@ -526,7 +716,7 @@ td_api::object_ptr OptionManager::get_option_synchronously( break; case 'v': if (name == "version") { - return td_api::make_object("1.8.14"); + return td_api::make_object("1.8.36"); } break; } @@ -616,19 +806,12 @@ void OptionManager::set_option(const string &name, td_api::object_ptr(value.get())->value_; - send_closure_later(td_->config_manager_, &ConfigManager::set_archive_and_mute, archive_and_mute, - std::move(promise)); + /* + if (!is_bot && set_boolean_option("archive_all_stories")) { + set_option_boolean("need_synchronize_archive_all_stories", true); return; } + */ break; case 'c': if (!is_bot && set_string_option("connection_parameters", [](Slice value) { @@ -649,19 +832,19 @@ void OptionManager::set_option(const string &name, td_api::object_ptr(value.get())->value_; - td_->set_is_online(is_online); + td_->online_manager_->set_is_online(is_online); if (!is_bot) { send_closure(td_->state_manager_, &StateManager::on_online, is_online); } @@ -760,6 +943,9 @@ void OptionManager::set_option(const string &name, td_api::object_ptrstate_manager_, &StateManager::on_network_updated); return; } + if (set_boolean_option("process_pinned_messages_as_mentions")) { + return; + } break; case 'r': // temporary option @@ -867,7 +1053,7 @@ void OptionManager::get_current_state(vector> get_common_state(updates); updates.push_back(td_api::make_object( - "online", td_api::make_object(td_->is_online()))); + "online", td_api::make_object(td_->online_manager_->is_online()))); updates.push_back(td_api::make_object("unix_time", get_unix_time_option_value_object())); diff --git a/protocols/Telegram/tdlib/td/td/telegram/OptionManager.h b/protocols/Telegram/tdlib/td/td/telegram/OptionManager.h index 2ffe26f4b2..13bc7fdf6f 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/OptionManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/OptionManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -31,6 +31,8 @@ class OptionManager { OptionManager &operator=(OptionManager &&) = delete; ~OptionManager(); + void update_premium_options(); + void on_td_inited(); void set_option_boolean(Slice name, bool value); diff --git a/protocols/Telegram/tdlib/td/td/telegram/OrderInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/OrderInfo.cpp index 310b24966b..2b2c43183e 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/OrderInfo.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/OrderInfo.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -132,12 +132,12 @@ Result
address_from_json(Slice json) { } auto &object = value.get_object(); - TRY_RESULT(country_code, get_json_object_string_field(object, "country_code")); - TRY_RESULT(state, get_json_object_string_field(object, "state")); - TRY_RESULT(city, get_json_object_string_field(object, "city")); - TRY_RESULT(street_line1, get_json_object_string_field(object, "street_line1")); - TRY_RESULT(street_line2, get_json_object_string_field(object, "street_line2")); - TRY_RESULT(postal_code, get_json_object_string_field(object, "post_code")); + TRY_RESULT(country_code, object.get_optional_string_field("country_code")); + TRY_RESULT(state, object.get_optional_string_field("state")); + TRY_RESULT(city, object.get_optional_string_field("city")); + TRY_RESULT(street_line1, object.get_optional_string_field("street_line1")); + TRY_RESULT(street_line2, object.get_optional_string_field("street_line2")); + TRY_RESULT(postal_code, object.get_optional_string_field("post_code")); TRY_STATUS(check_country_code(country_code)); TRY_STATUS(check_state(state)); diff --git a/protocols/Telegram/tdlib/td/td/telegram/OrderedMessage.cpp b/protocols/Telegram/tdlib/td/td/telegram/OrderedMessage.cpp index a46f35c318..f1681ccab0 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/OrderedMessage.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/OrderedMessage.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -29,9 +29,7 @@ void OrderedMessages::insert(MessageId message_id, bool auto_attach, MessageId o message->random_y_ = random_y; if (auto_attach) { - auto attach_info = auto_attach_message(message_id, old_last_message_id, source); - message->have_previous_ = attach_info.have_previous_; - message->have_next_ = attach_info.have_next_; + auto_attach_message(message.get(), old_last_message_id, source); } else { auto it = get_iterator(message_id); if (*it != nullptr && (*it)->have_next_) { @@ -156,8 +154,8 @@ void OrderedMessages::attach_message_to_next(MessageId message_id, const char *s } } -OrderedMessages::AttachInfo OrderedMessages::auto_attach_message(MessageId message_id, MessageId last_message_id, - const char *source) { +void OrderedMessages::auto_attach_message(OrderedMessage *message, MessageId last_message_id, const char *source) { + auto message_id = message->message_id_; auto it = get_iterator(message_id); OrderedMessage *previous_message = *it; if (previous_message != nullptr) { @@ -175,9 +173,10 @@ OrderedMessages::AttachInfo OrderedMessages::auto_attach_message(MessageId messa } LOG(INFO) << "Attach " << message_id << " to the previous " << previous_message_id << " from " << source; - auto have_next = previous_message->have_next_; + message->have_next_ = previous_message->have_next_; + message->have_previous_ = true; previous_message->have_next_ = true; - return {true, have_next}; + return; } } if (!message_id.is_yet_unsent()) { @@ -195,13 +194,13 @@ OrderedMessages::AttachInfo OrderedMessages::auto_attach_message(MessageId messa if (next_message != nullptr) { CHECK(!next_message->have_previous_); LOG(INFO) << "Attach " << message_id << " to the next " << next_message->message_id_ << " from " << source; - auto have_previous = next_message->have_previous_; - return {have_previous, true}; + message->have_next_ = true; + next_message->have_previous_ = true; + return; } } LOG(INFO) << "Can't auto-attach " << message_id << " from " << source; - return {false, false}; } void OrderedMessages::do_find_older_messages(const OrderedMessage *ordered_message, MessageId max_message_id, diff --git a/protocols/Telegram/tdlib/td/td/telegram/OrderedMessage.h b/protocols/Telegram/tdlib/td/td/telegram/OrderedMessage.h index f8962ab677..556d38b8a3 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/OrderedMessage.h +++ b/protocols/Telegram/tdlib/td/td/telegram/OrderedMessage.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -187,14 +187,6 @@ class OrderedMessages { } private: - struct AttachInfo { - bool have_previous_ = false; - bool have_next_ = false; - - AttachInfo(bool have_previous, bool have_next) : have_previous_(have_previous), have_next_(have_next) { - } - }; - class Iterator final : public IteratorBase { public: Iterator() = default; @@ -207,7 +199,7 @@ class OrderedMessages { } }; - AttachInfo auto_attach_message(MessageId message_id, MessageId last_message_id, const char *source); + void auto_attach_message(OrderedMessage *message, MessageId last_message_id, const char *source); Iterator get_iterator(MessageId message_id) { return Iterator(messages_.get(), message_id); diff --git a/protocols/Telegram/tdlib/td/td/telegram/PasswordManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/PasswordManager.cpp index 7450738c7b..5e95fb3fda 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PasswordManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/PasswordManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -14,6 +14,7 @@ #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/SuggestedAction.h" #include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" #include "td/mtproto/DhHandshake.h" @@ -31,10 +32,11 @@ namespace td { tl_object_ptr TempPasswordState::get_temporary_password_state_object() const { - if (!has_temp_password || valid_until <= G()->unix_time()) { + auto unix_time = G()->unix_time(); + if (!has_temp_password || valid_until <= unix_time) { return make_tl_object(false, 0); } - return make_tl_object(true, valid_until - G()->unix_time_cached()); + return make_tl_object(true, valid_until - unix_time); } static void hash_sha256(Slice data, Slice salt, MutableSlice dest) { @@ -186,11 +188,9 @@ void PasswordManager::set_login_email_address(string new_login_email_address, Pr make_tl_object(), std::move(new_login_email_address))); send_with_promise(std::move(query), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - return promise.set_value(SentEmailCode(r_result.move_as_ok())); + TRY_RESULT_PROMISE(promise, result, + fetch_result(std::move(r_query))); + promise.set_value(SentEmailCode(std::move(result))); })); } @@ -212,11 +212,8 @@ void PasswordManager::check_login_email_address_code(EmailVerification &&code, P make_tl_object(), code.get_input_email_verification())); send_with_promise(std::move(query), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - return promise.set_value(Unit()); + TRY_STATUS_PROMISE(promise, fetch_result(std::move(r_query))); + promise.set_value(Unit()); })); } @@ -243,8 +240,8 @@ void PasswordManager::do_get_secure_secret(bool allow_recursive, string password return promise.set_error(Status::Error(400, "PASSWORD_HASH_INVALID")); } get_full_state( - password, PromiseCreator::lambda([password, allow_recursive, promise = std::move(promise), - actor_id = actor_id(this)](Result r_state) mutable { + password, PromiseCreator::lambda([actor_id = actor_id(this), password, allow_recursive, + promise = std::move(promise)](Result r_state) mutable { if (r_state.is_error()) { return promise.set_error(r_state.move_as_error()); } @@ -261,7 +258,7 @@ void PasswordManager::do_get_secure_secret(bool allow_recursive, string password } auto new_promise = - PromiseCreator::lambda([password, promise = std::move(promise), actor_id](Result r_ok) mutable { + PromiseCreator::lambda([actor_id, password, promise = std::move(promise)](Result r_ok) mutable { if (r_ok.is_error()) { return promise.set_error(r_ok.move_as_error()); } @@ -301,8 +298,8 @@ void PasswordManager::create_temp_password(string password, int32 timeout, Promi send_closure(actor_id, &PasswordManager::on_finish_create_temp_password, std::move(result), false); }); - do_get_state(PromiseCreator::lambda([password = std::move(password), timeout, promise = std::move(new_promise), - actor_id = actor_id(this)](Result r_state) mutable { + do_get_state(PromiseCreator::lambda([actor_id = actor_id(this), password = std::move(password), timeout, + promise = std::move(new_promise)](Result r_state) mutable { if (r_state.is_error()) { return promise.set_error(r_state.move_as_error()); } @@ -321,11 +318,8 @@ void PasswordManager::do_create_temp_password(string password, int32 timeout, Pa auto hash = get_input_check_password(password, password_state); send_with_promise(G()->net_query_creator().create(telegram_api::account_getTmpPassword(std::move(hash), timeout)), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - auto result = r_result.move_as_ok(); + TRY_RESULT_PROMISE(promise, result, + fetch_result(std::move(r_query))); TempPasswordState res; res.has_temp_password = true; res.temp_password = result->tmp_password_.as_slice().str(); @@ -349,8 +343,8 @@ void PasswordManager::get_full_state(string password, Promise send_closure(G()->config_manager(), &ConfigManager::hide_suggested_action, SuggestedAction{SuggestedAction::Type::CheckPassword}); - do_get_state(PromiseCreator::lambda([password = std::move(password), promise = std::move(promise), - actor_id = actor_id(this)](Result r_state) mutable { + do_get_state(PromiseCreator::lambda([actor_id = actor_id(this), password = std::move(password), + promise = std::move(promise)](Result r_state) mutable { if (r_state.is_error()) { return promise.set_error(r_state.move_as_error()); } @@ -460,17 +454,27 @@ void PasswordManager::resend_recovery_email_address_code(Promise promise) })); } +void PasswordManager::cancel_recovery_email_address_verification(Promise promise) { + auto query = G()->net_query_creator().create(telegram_api::account_cancelPasswordEmail()); + send_with_promise(std::move(query), PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( + Result r_query) mutable { + auto r_result = fetch_result(std::move(r_query)); + if (r_result.is_error() && r_result.error().message() != "EMAIL_HASH_EXPIRED") { + return promise.set_error(r_result.move_as_error()); + } + send_closure(actor_id, &PasswordManager::get_state, std::move(promise)); + })); +} + void PasswordManager::send_email_address_verification_code(string email, Promise promise) { last_verified_email_address_ = email; auto query = G()->net_query_creator().create(telegram_api::account_sendVerifyEmailCode( make_tl_object(), std::move(email))); send_with_promise(std::move(query), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - return promise.set_value(SentEmailCode(r_result.move_as_ok())); + TRY_RESULT_PROMISE(promise, result, + fetch_result(std::move(r_query))); + promise.set_value(SentEmailCode(std::move(result))); })); } @@ -488,25 +492,19 @@ void PasswordManager::check_email_address_verification_code(string code, Promise auto verification_code = make_tl_object(std::move(code)); auto query = G()->net_query_creator().create(telegram_api::account_verifyEmail( make_tl_object(), std::move(verification_code))); - send_with_promise(std::move(query), - PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - return promise.set_value(Unit()); - })); + send_with_promise( + std::move(query), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { + TRY_STATUS_PROMISE(promise, fetch_result(std::move(r_query))); + promise.set_value(Unit()); + })); } void PasswordManager::request_password_recovery(Promise promise) { // is called only after authorization send_with_promise(G()->net_query_creator().create(telegram_api::auth_requestPasswordRecovery()), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - auto result = r_result.move_as_ok(); + TRY_RESULT_PROMISE(promise, result, + fetch_result(std::move(r_query))); return promise.set_value(SentEmailCode(std::move(result->email_pattern_), 0)); })); } @@ -515,14 +513,12 @@ void PasswordManager::check_password_recovery_code(string code, Promise pr // is called only after authorization send_with_promise(G()->net_query_creator().create(telegram_api::auth_checkRecoveryPassword(code)), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - if (!r_result.ok()) { + TRY_RESULT_PROMISE(promise, result, + fetch_result(std::move(r_query))); + if (!result) { return promise.set_error(Status::Error(400, "Invalid recovery code")); } - return promise.set_value(Unit()); + promise.set_value(Unit()); })); } @@ -560,25 +556,18 @@ void PasswordManager::do_recover_password(string code, PasswordInputSettings &&n } send_with_promise(G()->net_query_creator().create( telegram_api::auth_recoverPassword(flags, std::move(code), std::move(new_settings))), - PromiseCreator::lambda( - [actor_id = actor_id(this), promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - send_closure(actor_id, &PasswordManager::get_state, std::move(promise)); - })); + PromiseCreator::lambda([actor_id = actor_id(this), + promise = std::move(promise)](Result r_query) mutable { + TRY_STATUS_PROMISE(promise, fetch_result(std::move(r_query))); + send_closure(actor_id, &PasswordManager::get_state, std::move(promise)); + })); } void PasswordManager::reset_password(Promise promise) { send_with_promise( G()->net_query_creator().create(telegram_api::account_resetPassword()), PromiseCreator::lambda([promise = std::move(promise)](Result r_query) mutable { - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - auto result_ptr = r_result.move_as_ok(); + TRY_RESULT_PROMISE(promise, result_ptr, fetch_result(std::move(r_query))); switch (result_ptr->get_id()) { case telegram_api::account_resetPasswordOk::ID: return promise.set_value(td_api::make_object()); @@ -781,12 +770,7 @@ void PasswordManager::do_get_state(Promise promise) { std::move(query), PromiseCreator::lambda([actor_id = actor_id(this), code_length = last_code_length_, promise = std::move(promise)](Result r_query) mutable { TRY_STATUS_PROMISE(promise, G()->close_status()); - - auto r_result = fetch_result(std::move(r_query)); - if (r_result.is_error()) { - return promise.set_error(r_result.move_as_error()); - } - auto password = r_result.move_as_ok(); + TRY_RESULT_PROMISE(promise, password, fetch_result(std::move(r_query))); LOG(INFO) << "Receive password info: " << to_string(password); Random::add_seed(password->secure_random_.as_slice()); diff --git a/protocols/Telegram/tdlib/td/td/telegram/PasswordManager.h b/protocols/Telegram/tdlib/td/td/telegram/PasswordManager.h index 3ad9081809..fc3cfb6342 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PasswordManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/PasswordManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -80,6 +80,7 @@ class PasswordManager final : public NetQueryCallback { void get_recovery_email_address(string password, Promise> promise); void check_recovery_email_address_code(string code, Promise promise); void resend_recovery_email_address_code(Promise promise); + void cancel_recovery_email_address_verification(Promise promise); void send_email_address_verification_code(string email, Promise promise); void resend_email_address_verification_code(Promise promise); diff --git a/protocols/Telegram/tdlib/td/td/telegram/Payments.cpp b/protocols/Telegram/tdlib/td/td/telegram/Payments.cpp index cbc7f4e1e3..7e0ce0414b 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Payments.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/Payments.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,28 +7,36 @@ #include "td/telegram/Payments.h" #include "td/telegram/AccessRights.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/DialogId.h" +#include "td/telegram/DialogInviteLink.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/GiveawayParameters.h" #include "td/telegram/Global.h" #include "td/telegram/InputInvoice.h" +#include "td/telegram/LinkManager.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" #include "td/telegram/PasswordManager.h" #include "td/telegram/Photo.h" +#include "td/telegram/Premium.h" #include "td/telegram/ServerMessageId.h" +#include "td/telegram/StarManager.h" +#include "td/telegram/SuggestedAction.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" #include "td/telegram/ThemeManager.h" #include "td/telegram/UpdatesManager.h" #include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" #include "td/utils/common.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" +#include "td/utils/misc.h" #include "td/utils/Status.h" namespace td { @@ -38,6 +46,7 @@ namespace { struct InputInvoiceInfo { DialogId dialog_id_; telegram_api::object_ptr input_invoice_; + int64 star_count_ = 0; }; Result get_input_invoice_info(Td *td, td_api::object_ptr &&input_invoice) { @@ -51,16 +60,17 @@ Result get_input_invoice_info(Td *td, td_api::object_ptr(input_invoice); DialogId dialog_id(invoice->chat_id_); MessageId message_id(invoice->message_id_); - TRY_RESULT(server_message_id, td->messages_manager_->get_invoice_message_id({dialog_id, message_id})); + TRY_RESULT(invoice_message_info, td->messages_manager_->get_invoice_message_info({dialog_id, message_id})); - auto input_peer = td->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return Status::Error(400, "Can't access the chat"); } result.dialog_id_ = dialog_id; - result.input_invoice_ = - make_tl_object(std::move(input_peer), server_message_id.get()); + result.input_invoice_ = telegram_api::make_object( + std::move(input_peer), invoice_message_info.server_message_id_.get()); + result.star_count_ = invoice_message_info.star_count_; break; } case td_api::inputInvoiceName::ID: { @@ -68,6 +78,117 @@ Result get_input_invoice_info(Td *td, td_api::object_ptr(invoice->name_); break; } + case td_api::inputInvoiceTelegram::ID: { + auto invoice = td_api::move_object_as(input_invoice); + if (invoice->purpose_ == nullptr) { + return Status::Error(400, "Purpose must be non-empty"); + } + switch (invoice->purpose_->get_id()) { + case td_api::telegramPaymentPurposePremiumGiftCodes::ID: { + auto p = static_cast(invoice->purpose_.get()); + vector> input_users; + for (auto user_id : p->user_ids_) { + TRY_RESULT(input_user, td->user_manager_->get_input_user(UserId(user_id))); + input_users.push_back(std::move(input_user)); + } + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + DialogId boosted_dialog_id(p->boosted_chat_id_); + TRY_RESULT(boost_input_peer, get_boost_input_peer(td, boosted_dialog_id)); + int32 flags = 0; + if (boost_input_peer != nullptr) { + flags |= telegram_api::inputStorePaymentPremiumGiftCode::BOOST_PEER_MASK; + } + auto option = telegram_api::make_object( + 0, static_cast(input_users.size()), p->month_count_, string(), 0, p->currency_, p->amount_); + auto purpose = telegram_api::make_object( + flags, std::move(input_users), std::move(boost_input_peer), p->currency_, p->amount_); + + result.dialog_id_ = boosted_dialog_id; + result.input_invoice_ = telegram_api::make_object( + std::move(purpose), std::move(option)); + break; + } + case td_api::telegramPaymentPurposePremiumGiveaway::ID: { + auto p = static_cast(invoice->purpose_.get()); + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + TRY_RESULT(parameters, GiveawayParameters::get_giveaway_parameters(td, p->parameters_.get())); + auto option = telegram_api::make_object( + 0, p->winner_count_, p->month_count_, string(), 0, p->currency_, p->amount_); + result.input_invoice_ = telegram_api::make_object( + parameters.get_input_store_payment_premium_giveaway(td, p->currency_, p->amount_), std::move(option)); + break; + } + case td_api::telegramPaymentPurposeStars::ID: { + auto p = static_cast(invoice->purpose_.get()); + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::StarsSubscriptionLowBalance}, + Promise()); + auto purpose = telegram_api::make_object(p->star_count_, + p->currency_, p->amount_); + result.input_invoice_ = telegram_api::make_object(std::move(purpose)); + break; + } + case td_api::telegramPaymentPurposeGiftedStars::ID: { + auto p = static_cast(invoice->purpose_.get()); + UserId user_id(p->user_id_); + TRY_RESULT(input_user, td->user_manager_->get_input_user(user_id)); + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + auto purpose = telegram_api::make_object( + std::move(input_user), p->star_count_, p->currency_, p->amount_); + result.input_invoice_ = telegram_api::make_object(std::move(purpose)); + break; + } + case td_api::telegramPaymentPurposeStarGiveaway::ID: { + auto p = static_cast(invoice->purpose_.get()); + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + TRY_RESULT(parameters, GiveawayParameters::get_giveaway_parameters(td, p->parameters_.get())); + auto purpose = parameters.get_input_store_payment_stars_giveaway(td, p->currency_, p->amount_, + p->winner_count_, p->star_count_); + result.input_invoice_ = telegram_api::make_object(std::move(purpose)); + break; + } + case td_api::telegramPaymentPurposeJoinChat::ID: { + auto p = static_cast(invoice->purpose_.get()); + if (!DialogInviteLink::is_valid_invite_link(p->invite_link_)) { + return Status::Error(400, "Invalid invite link"); + } + auto hash = LinkManager::get_dialog_invite_link_hash(p->invite_link_); + if (!clean_input_string(hash)) { + return Status::Error(400, "Invalid invite link"); + } + result.input_invoice_ = telegram_api::make_object(hash); + break; + } + default: + UNREACHABLE(); + } + break; + } default: UNREACHABLE(); } @@ -193,15 +314,22 @@ static tl_object_ptr convert_invoice(tl_object_ptrsuggested_tip_amounts_.resize(4); } + string recurring_terms_url; + string terms_url; + if (invoice->recurring_) { + recurring_terms_url = std::move(invoice->terms_url_); + } else { + terms_url = std::move(invoice->terms_url_); + } return make_tl_object(std::move(invoice->currency_), std::move(labeled_prices), invoice->max_tip_amount_, std::move(invoice->suggested_tip_amounts_), - std::move(invoice->recurring_terms_url_), is_test, need_name, - need_phone_number, need_email_address, need_shipping_address, - send_phone_number_to_provider, send_email_address_to_provider, is_flexible); + recurring_terms_url, terms_url, is_test, need_name, need_phone_number, + need_email_address, need_shipping_address, send_phone_number_to_provider, + send_email_address_to_provider, is_flexible); } static tl_object_ptr convert_payment_provider( - const string &native_provider_name, tl_object_ptr native_parameters) { + const string &native_provider_name, tl_object_ptr native_parameters, bool is_test) { if (native_parameters == nullptr) { return nullptr; } @@ -220,17 +348,23 @@ static tl_object_ptr convert_payment_provider( return nullptr; } - auto r_public_token = get_json_object_string_field(value.get_object(), "public_token", false); - + const auto &object = value.get_object(); + auto r_public_token = object.get_required_string_field("public_token"); if (r_public_token.is_error()) { LOG(ERROR) << "Unsupported JSON data \"" << native_parameters->data_ << '"'; return nullptr; } - if (value.get_object().size() != 1) { + string tokenize_url = is_test ? "https://tgb-playground.smart-glocal.com/cds/v1/tokenize/card" + : "https://tgb.smart-glocal.com/cds/v1/tokenize/card"; + auto r_tokenize_url = object.get_optional_string_field("tokenize_url"); + if (r_tokenize_url.is_ok() && begins_with(r_tokenize_url.ok(), "https://") && + ends_with(r_tokenize_url.ok(), ".smart-glocal.com/cds/v1/tokenize/card")) { + tokenize_url = r_tokenize_url.move_as_ok(); + } + if (object.field_count() > 2) { LOG(ERROR) << "Unsupported JSON data \"" << native_parameters->data_ << '"'; } - - return make_tl_object(r_public_token.move_as_ok()); + return make_tl_object(r_public_token.move_as_ok(), tokenize_url); } if (native_provider_name == "stripe") { string data = native_parameters->data_; @@ -246,10 +380,11 @@ static tl_object_ptr convert_payment_provider( return nullptr; } - auto r_need_country = get_json_object_bool_field(value.get_object(), "need_country", false); - auto r_need_postal_code = get_json_object_bool_field(value.get_object(), "need_zip", false); - auto r_need_cardholder_name = get_json_object_bool_field(value.get_object(), "need_cardholder_name", false); - auto r_publishable_key = get_json_object_string_field(value.get_object(), "publishable_key", false); + const auto &object = value.get_object(); + auto r_need_country = object.get_required_bool_field("need_country"); + auto r_need_postal_code = object.get_required_bool_field("need_zip"); + auto r_need_cardholder_name = object.get_required_bool_field("need_cardholder_name"); + auto r_publishable_key = object.get_required_string_field("publishable_key"); // TODO support "gpay_parameters":{"gateway":"stripe","stripe:publishableKey":"...","stripe:version":"..."} if (r_need_country.is_error() || r_need_postal_code.is_error() || r_need_cardholder_name.is_error() || @@ -257,7 +392,7 @@ static tl_object_ptr convert_payment_provider( LOG(ERROR) << "Unsupported JSON data \"" << native_parameters->data_ << '"'; return nullptr; } - if (value.get_object().size() != 5) { + if (object.field_count() != 5) { LOG(ERROR) << "Unsupported JSON data \"" << native_parameters->data_ << '"'; } @@ -363,46 +498,80 @@ class GetPaymentFormQuery final : public Td::ResultHandler { return on_error(result_ptr.move_as_error()); } - auto payment_form = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for GetPaymentFormQuery: " << to_string(payment_form); - - td_->contacts_manager_->on_get_users(std::move(payment_form->users_), "GetPaymentFormQuery"); - - UserId payments_provider_user_id(payment_form->provider_id_); - if (!payments_provider_user_id.is_valid()) { - LOG(ERROR) << "Receive invalid payments provider " << payments_provider_user_id; - return on_error(Status::Error(500, "Receive invalid payments provider identifier")); - } - UserId seller_bot_user_id(payment_form->bot_id_); - if (!seller_bot_user_id.is_valid()) { - LOG(ERROR) << "Receive invalid seller " << seller_bot_user_id; - return on_error(Status::Error(500, "Receive invalid seller identifier")); - } - bool can_save_credentials = payment_form->can_save_credentials_; - bool need_password = payment_form->password_missing_; - auto photo = get_web_document_photo(td_->file_manager_.get(), std::move(payment_form->photo_), dialog_id_); - auto payment_provider = - convert_payment_provider(payment_form->native_provider_, std::move(payment_form->native_params_)); - if (payment_provider == nullptr) { - payment_provider = td_api::make_object(std::move(payment_form->url_)); - } - auto additional_payment_options = transform( - payment_form->additional_methods_, [](const telegram_api::object_ptr &method) { - return td_api::make_object(method->title_, method->url_); - }); - promise_.set_value(make_tl_object( - payment_form->form_id_, convert_invoice(std::move(payment_form->invoice_)), - td_->contacts_manager_->get_user_id_object(seller_bot_user_id, "paymentForm seller"), - td_->contacts_manager_->get_user_id_object(payments_provider_user_id, "paymentForm provider"), - std::move(payment_provider), std::move(additional_payment_options), - convert_order_info(std::move(payment_form->saved_info_)), - convert_saved_credentials(std::move(payment_form->saved_credentials_)), can_save_credentials, need_password, - payment_form->title_, get_product_description_object(payment_form->description_), - get_photo_object(td_->file_manager_.get(), photo))); + auto payment_form_ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetPaymentFormQuery: " << to_string(payment_form_ptr); + switch (payment_form_ptr->get_id()) { + case telegram_api::payments_paymentForm::ID: { + auto payment_form = telegram_api::move_object_as(payment_form_ptr); + + td_->user_manager_->on_get_users(std::move(payment_form->users_), "GetPaymentFormQuery 1"); + + UserId payments_provider_user_id(payment_form->provider_id_); + if (!payments_provider_user_id.is_valid()) { + LOG(ERROR) << "Receive invalid payments provider " << payments_provider_user_id; + return on_error(Status::Error(500, "Receive invalid payments provider identifier")); + } + UserId seller_bot_user_id(payment_form->bot_id_); + if (!seller_bot_user_id.is_valid()) { + LOG(ERROR) << "Receive invalid seller " << seller_bot_user_id; + return on_error(Status::Error(500, "Receive invalid seller identifier")); + } + bool can_save_credentials = payment_form->can_save_credentials_; + bool need_password = payment_form->password_missing_; + auto photo = get_web_document_photo(td_->file_manager_.get(), std::move(payment_form->photo_), dialog_id_); + auto payment_provider = convert_payment_provider( + payment_form->native_provider_, std::move(payment_form->native_params_), payment_form->invoice_->test_); + if (payment_provider == nullptr) { + payment_provider = td_api::make_object(std::move(payment_form->url_)); + } + auto additional_payment_options = + transform(payment_form->additional_methods_, + [](const telegram_api::object_ptr &method) { + return td_api::make_object(method->title_, method->url_); + }); + auto type = td_api::make_object( + convert_invoice(std::move(payment_form->invoice_)), + td_->user_manager_->get_user_id_object(payments_provider_user_id, "paymentForm provider"), + std::move(payment_provider), std::move(additional_payment_options), + convert_order_info(std::move(payment_form->saved_info_)), + convert_saved_credentials(std::move(payment_form->saved_credentials_)), can_save_credentials, + need_password); + promise_.set_value(td_api::make_object( + payment_form->form_id_, std::move(type), + td_->user_manager_->get_user_id_object(seller_bot_user_id, "paymentForm seller"), + get_product_info_object(td_, payment_form->title_, payment_form->description_, photo))); + break; + } + case telegram_api::payments_paymentFormStars::ID: { + auto payment_form = telegram_api::move_object_as(payment_form_ptr); + + td_->user_manager_->on_get_users(std::move(payment_form->users_), "GetPaymentFormQuery 2"); + + UserId seller_bot_user_id(payment_form->bot_id_); + if (!seller_bot_user_id.is_valid()) { + LOG(ERROR) << "Receive invalid seller " << seller_bot_user_id; + return on_error(Status::Error(500, "Receive invalid seller identifier")); + } + if (payment_form->invoice_->prices_.size() != 1u) { + LOG(ERROR) << "Receive invalid prices " << to_string(payment_form->invoice_->prices_); + return on_error(Status::Error(500, "Receive invalid price")); + } + auto photo = get_web_document_photo(td_->file_manager_.get(), std::move(payment_form->photo_), dialog_id_); + auto type = td_api::make_object( + StarManager::get_star_count(payment_form->invoice_->prices_[0]->amount_)); + promise_.set_value(td_api::make_object( + payment_form->form_id_, std::move(type), + td_->user_manager_->get_user_id_object(seller_bot_user_id, "paymentForm seller"), + get_product_info_object(td_, payment_form->title_, payment_form->description_, photo))); + break; + } + default: + UNREACHABLE(); + } } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetPaymentFormQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetPaymentFormQuery"); promise_.set_error(std::move(status)); } }; @@ -447,7 +616,7 @@ class ValidateRequestedInfoQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ValidateRequestedInfoQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ValidateRequestedInfoQuery"); promise_.set_error(std::move(status)); } }; @@ -512,7 +681,62 @@ class SendPaymentFormQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendPaymentFormQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendPaymentFormQuery"); + promise_.set_error(std::move(status)); + } +}; + +class SendStarPaymentFormQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + int64 star_count_; + + public: + explicit SendStarPaymentFormQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(InputInvoiceInfo &&input_invoice_info, int64 payment_form_id) { + dialog_id_ = input_invoice_info.dialog_id_; + star_count_ = input_invoice_info.star_count_; + td_->star_manager_->add_pending_owned_star_count(-star_count_, false); + + send_query(G()->net_query_creator().create( + telegram_api::payments_sendStarsForm(0, payment_form_id, std::move(input_invoice_info.input_invoice_)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto payment_result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendStarPaymentFormQuery: " << to_string(payment_result); + + td_->star_manager_->add_pending_owned_star_count(star_count_, true); + switch (payment_result->get_id()) { + case telegram_api::payments_paymentResult::ID: { + auto result = telegram_api::move_object_as(payment_result); + td_->updates_manager_->on_get_updates( + std::move(result->updates_), PromiseCreator::lambda([promise = std::move(promise_)](Unit) mutable { + promise.set_value(td_api::make_object(true, string())); + })); + return; + } + case telegram_api::payments_paymentVerificationNeeded::ID: { + auto result = telegram_api::move_object_as(payment_result); + promise_.set_value(td_api::make_object(false, std::move(result->url_))); + return; + } + default: + UNREACHABLE(); + } + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendStarPaymentFormQuery"); + td_->star_manager_->add_pending_owned_star_count(star_count_, false); promise_.set_error(std::move(status)); } }; @@ -528,7 +752,7 @@ class GetPaymentReceiptQuery final : public Td::ResultHandler { void send(DialogId dialog_id, ServerMessageId server_message_id) { dialog_id_ = dialog_id; - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } @@ -543,39 +767,70 @@ class GetPaymentReceiptQuery final : public Td::ResultHandler { return on_error(result_ptr.move_as_error()); } - auto payment_receipt = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for GetPaymentReceiptQuery: " << to_string(payment_receipt); - - td_->contacts_manager_->on_get_users(std::move(payment_receipt->users_), "GetPaymentReceiptQuery"); - - UserId payments_provider_user_id(payment_receipt->provider_id_); - if (!payments_provider_user_id.is_valid()) { - LOG(ERROR) << "Receive invalid payments provider " << payments_provider_user_id; - return on_error(Status::Error(500, "Receive invalid payments provider identifier")); - } - UserId seller_bot_user_id(payment_receipt->bot_id_); - if (!seller_bot_user_id.is_valid()) { - LOG(ERROR) << "Receive invalid seller " << seller_bot_user_id; - return on_error(Status::Error(500, "Receive invalid seller identifier")); - } - auto photo = get_web_document_photo(td_->file_manager_.get(), std::move(payment_receipt->photo_), dialog_id_); - if (payment_receipt->tip_amount_ < 0 || !check_currency_amount(payment_receipt->tip_amount_)) { - LOG(ERROR) << "Receive invalid tip amount " << payment_receipt->tip_amount_; - payment_receipt->tip_amount_ = 0; + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetPaymentReceiptQuery: " << to_string(ptr); + switch (ptr->get_id()) { + case telegram_api::payments_paymentReceiptStars::ID: { + auto payment_receipt = telegram_api::move_object_as(ptr); + + td_->user_manager_->on_get_users(std::move(payment_receipt->users_), "GetPaymentReceiptQuery 1"); + UserId seller_bot_user_id(payment_receipt->bot_id_); + if (!seller_bot_user_id.is_valid()) { + LOG(ERROR) << "Receive invalid seller " << seller_bot_user_id; + return on_error(Status::Error(500, "Receive invalid seller identifier")); + } + auto photo = get_web_document_photo(td_->file_manager_.get(), std::move(payment_receipt->photo_), dialog_id_); + if (payment_receipt->invoice_->prices_.size() != 1u) { + LOG(ERROR) << "Receive invalid prices " << to_string(payment_receipt->invoice_->prices_); + return on_error(Status::Error(500, "Receive invalid price")); + } + promise_.set_value(make_tl_object( + get_product_info_object(td_, payment_receipt->title_, payment_receipt->description_, photo), + payment_receipt->date_, td_->user_manager_->get_user_id_object(seller_bot_user_id, "paymentReceipt seller"), + td_api::make_object( + StarManager::get_star_count(payment_receipt->invoice_->prices_[0]->amount_), + payment_receipt->transaction_id_))); + break; + } + case telegram_api::payments_paymentReceipt::ID: { + auto payment_receipt = telegram_api::move_object_as(ptr); + + td_->user_manager_->on_get_users(std::move(payment_receipt->users_), "GetPaymentReceiptQuery 2"); + + UserId payments_provider_user_id(payment_receipt->provider_id_); + if (!payments_provider_user_id.is_valid()) { + LOG(ERROR) << "Receive invalid payments provider " << payments_provider_user_id; + return on_error(Status::Error(500, "Receive invalid payments provider identifier")); + } + UserId seller_bot_user_id(payment_receipt->bot_id_); + if (!seller_bot_user_id.is_valid()) { + LOG(ERROR) << "Receive invalid seller " << seller_bot_user_id; + return on_error(Status::Error(500, "Receive invalid seller identifier")); + } + auto photo = get_web_document_photo(td_->file_manager_.get(), std::move(payment_receipt->photo_), dialog_id_); + if (payment_receipt->tip_amount_ < 0 || !check_currency_amount(payment_receipt->tip_amount_)) { + LOG(ERROR) << "Receive invalid tip amount " << payment_receipt->tip_amount_; + payment_receipt->tip_amount_ = 0; + } + + promise_.set_value(make_tl_object( + get_product_info_object(td_, payment_receipt->title_, payment_receipt->description_, photo), + payment_receipt->date_, td_->user_manager_->get_user_id_object(seller_bot_user_id, "paymentReceipt seller"), + td_api::make_object( + td_->user_manager_->get_user_id_object(payments_provider_user_id, "paymentReceipt provider"), + convert_invoice(std::move(payment_receipt->invoice_)), + convert_order_info(std::move(payment_receipt->info_)), + convert_shipping_option(std::move(payment_receipt->shipping_)), + std::move(payment_receipt->credentials_title_), payment_receipt->tip_amount_))); + break; + } + default: + UNREACHABLE(); } - - promise_.set_value(make_tl_object( - payment_receipt->title_, get_product_description_object(payment_receipt->description_), - get_photo_object(td_->file_manager_.get(), photo), payment_receipt->date_, - td_->contacts_manager_->get_user_id_object(seller_bot_user_id, "paymentReceipt seller"), - td_->contacts_manager_->get_user_id_object(payments_provider_user_id, "paymentReceipt provider"), - convert_invoice(std::move(payment_receipt->invoice_)), convert_order_info(std::move(payment_receipt->info_)), - convert_shipping_option(std::move(payment_receipt->shipping_)), std::move(payment_receipt->credentials_title_), - payment_receipt->tip_amount_)); } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetPaymentReceiptQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetPaymentReceiptQuery"); promise_.set_error(std::move(status)); } }; @@ -698,6 +953,44 @@ class GetBankCardInfoQuery final : public Td::ResultHandler { } }; +class GetCollectibleInfoQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetCollectibleInfoQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(telegram_api::object_ptr &&input_collectible) { + send_query( + G()->net_query_creator().create(telegram_api::fragment_getCollectibleInfo(std::move(input_collectible)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + if (result->amount_ <= 0 || !check_currency_amount(result->amount_)) { + LOG(ERROR) << "Receive invalid collectible item price " << result->amount_; + result->amount_ = 0; + } + if (result->crypto_currency_.empty() || result->crypto_amount_ <= 0) { + LOG(ERROR) << "Receive invalid collectible item cryptocurrency price " << result->crypto_amount_; + result->crypto_amount_ = 0; + } + promise_.set_value(td_api::make_object(result->purchase_date_, result->currency_, + result->amount_, result->crypto_currency_, + result->crypto_amount_, result->url_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + void answer_shipping_query(Td *td, int64 shipping_query_id, vector> &&shipping_options, const string &error_message, Promise &&promise) { @@ -749,7 +1042,7 @@ void get_payment_form(Td *td, td_api::object_ptr &&input_i tl_object_ptr theme_parameters; if (theme != nullptr) { theme_parameters = make_tl_object(string()); - theme_parameters->data_ = ThemeManager::get_theme_parameters_json_string(theme, false); + theme_parameters->data_ = ThemeManager::get_theme_parameters_json_string(theme); } td->create_handler(std::move(promise)) ->send(std::move(input_invoice_info), std::move(theme_parameters)); @@ -803,7 +1096,15 @@ void send_payment_form(Td *td, td_api::object_ptr &&input_ TRY_RESULT_PROMISE(promise, input_invoice_info, get_input_invoice_info(td, std::move(input_invoice))); if (credentials == nullptr) { - return promise.set_error(Status::Error(400, "Input payment credentials must be non-empty")); + if (tip_amount != 0 || !order_info_id.empty() || !shipping_option_id.empty()) { + return promise.set_error(Status::Error(400, "Invalid payment form parameters specified")); + } + if (!td->star_manager_->has_owned_star_count(input_invoice_info.star_count_)) { + return promise.set_error(Status::Error(400, "Have not enough Telegram Stars to complete payment")); + } + td->create_handler(std::move(promise)) + ->send(std::move(input_invoice_info), payment_form_id); + return; } tl_object_ptr input_credentials; @@ -855,12 +1156,12 @@ void send_payment_form(Td *td, td_api::object_ptr &&input_ std::move(input_credentials), tip_amount); } -void get_payment_receipt(Td *td, FullMessageId full_message_id, +void get_payment_receipt(Td *td, MessageFullId message_full_id, Promise> &&promise) { TRY_RESULT_PROMISE(promise, server_message_id, - td->messages_manager_->get_payment_successful_message_id(full_message_id)); + td->messages_manager_->get_payment_successful_message_id(message_full_id)); td->create_handler(std::move(promise)) - ->send(full_message_id.get_dialog_id(), server_message_id); + ->send(message_full_id.get_dialog_id(), server_message_id); } void get_saved_order_info(Td *td, Promise> &&promise) { @@ -880,7 +1181,7 @@ void export_invoice(Td *td, td_api::object_ptr &&in return promise.set_error(Status::Error(400, "Invoice must be non-empty")); } TRY_RESULT_PROMISE(promise, input_invoice, - InputInvoice::process_input_message_invoice(std::move(invoice), td, DialogId(), false)); + InputInvoice::process_input_message_invoice(std::move(invoice), td, DialogId())); auto input_media = input_invoice.get_input_media_invoice(td, nullptr, nullptr); CHECK(input_media != nullptr); td->create_handler(std::move(promise))->send(std::move(input_media)); @@ -891,4 +1192,33 @@ void get_bank_card_info(Td *td, const string &bank_card_number, td->create_handler(std::move(promise))->send(bank_card_number); } +void get_collectible_info(Td *td, td_api::object_ptr type, + Promise> &&promise) { + if (type == nullptr) { + return promise.set_error(Status::Error(400, "Item type must be non-empty")); + } + switch (type->get_id()) { + case td_api::collectibleItemTypeUsername::ID: { + auto username = td_api::move_object_as(type); + if (!clean_input_string(username->username_)) { + return promise.set_error(Status::Error(400, "Username must be encoded in UTF-8")); + } + td->create_handler(std::move(promise)) + ->send(telegram_api::make_object(username->username_)); + break; + } + case td_api::collectibleItemTypePhoneNumber::ID: { + auto phone_number = td_api::move_object_as(type); + if (!clean_input_string(phone_number->phone_number_)) { + return promise.set_error(Status::Error(400, "Phone number must be encoded in UTF-8")); + } + td->create_handler(std::move(promise)) + ->send(telegram_api::make_object(phone_number->phone_number_)); + break; + } + default: + UNREACHABLE(); + } +} + } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Payments.h b/protocols/Telegram/tdlib/td/td/telegram/Payments.h index 4ca87b9614..667fa9db85 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Payments.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Payments.h @@ -1,12 +1,12 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once -#include "td/telegram/FullMessageId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/td_api.h" #include "td/utils/common.h" @@ -37,7 +37,7 @@ void send_payment_form(Td *td, td_api::object_ptr &&input_ const td_api::object_ptr &credentials, int64 tip_amount, Promise> &&promise); -void get_payment_receipt(Td *td, FullMessageId full_message_id, +void get_payment_receipt(Td *td, MessageFullId message_full_id, Promise> &&promise); void get_saved_order_info(Td *td, Promise> &&promise); @@ -51,4 +51,7 @@ void export_invoice(Td *td, td_api::object_ptr &&in void get_bank_card_info(Td *td, const string &bank_card_number, Promise> &&promise); +void get_collectible_info(Td *td, td_api::object_ptr type, + Promise> &&promise); + } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PeerColor.cpp b/protocols/Telegram/tdlib/td/td/telegram/PeerColor.cpp new file mode 100644 index 0000000000..a0843de32f --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/PeerColor.cpp @@ -0,0 +1,33 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/PeerColor.h" + +#include "td/utils/logging.h" + +namespace td { + +PeerColor::PeerColor(const telegram_api::object_ptr &peer_color) { + if (peer_color == nullptr) { + return; + } + if ((peer_color->flags_ & telegram_api::peerColor::COLOR_MASK) != 0) { + accent_color_id_ = AccentColorId(peer_color->color_); + if (!accent_color_id_.is_valid()) { + LOG(ERROR) << "Receive " << to_string(peer_color); + accent_color_id_ = AccentColorId(); + } + } + if ((peer_color->flags_ & telegram_api::peerColor::BACKGROUND_EMOJI_ID_MASK) != 0) { + background_custom_emoji_id_ = CustomEmojiId(peer_color->background_emoji_id_); + if (!background_custom_emoji_id_.is_valid()) { + LOG(ERROR) << "Receive " << to_string(peer_color); + background_custom_emoji_id_ = CustomEmojiId(); + } + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PeerColor.h b/protocols/Telegram/tdlib/td/td/telegram/PeerColor.h new file mode 100644 index 0000000000..923ada109c --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/PeerColor.h @@ -0,0 +1,22 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/AccentColorId.h" +#include "td/telegram/CustomEmojiId.h" +#include "td/telegram/telegram_api.h" + +namespace td { + +struct PeerColor { + AccentColorId accent_color_id_; + CustomEmojiId background_custom_emoji_id_; + + explicit PeerColor(const telegram_api::object_ptr &peer_color); +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PeopleNearbyManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/PeopleNearbyManager.cpp new file mode 100644 index 0000000000..fddb2a3579 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/PeopleNearbyManager.cpp @@ -0,0 +1,450 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/PeopleNearbyManager.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" + +#include +#include + +namespace td { + +class SearchDialogsNearbyQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit SearchDialogsNearbyQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(const Location &location, bool from_background, int32 expire_date) { + int32 flags = 0; + if (from_background) { + flags |= telegram_api::contacts_getLocated::BACKGROUND_MASK; + } + if (expire_date != -1) { + flags |= telegram_api::contacts_getLocated::SELF_EXPIRES_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::contacts_getLocated(flags, false /*ignored*/, location.get_input_geo_point(), expire_date))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(result_ptr.move_as_ok()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +PeopleNearbyManager::PeopleNearbyManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { + if (!td_->auth_manager_->is_bot()) { + location_visibility_expire_date_ = + to_integer(G()->td_db()->get_binlog_pmc()->get("location_visibility_expire_date")); + if (location_visibility_expire_date_ != 0 && location_visibility_expire_date_ <= G()->unix_time()) { + location_visibility_expire_date_ = 0; + G()->td_db()->get_binlog_pmc()->erase("location_visibility_expire_date"); + } + auto pending_location_visibility_expire_date_string = + G()->td_db()->get_binlog_pmc()->get("pending_location_visibility_expire_date"); + if (!pending_location_visibility_expire_date_string.empty()) { + pending_location_visibility_expire_date_ = to_integer(pending_location_visibility_expire_date_string); + } + update_is_location_visible(); + LOG(INFO) << "Loaded location_visibility_expire_date = " << location_visibility_expire_date_ + << " and pending_location_visibility_expire_date = " << pending_location_visibility_expire_date_; + } + + user_nearby_timeout_.set_callback(on_user_nearby_timeout_callback); + user_nearby_timeout_.set_callback_data(static_cast(this)); +} + +void PeopleNearbyManager::tear_down() { + parent_.reset(); +} + +void PeopleNearbyManager::start_up() { + if (!pending_location_visibility_expire_date_) { + try_send_set_location_visibility_query(); + } +} + +void PeopleNearbyManager::on_user_nearby_timeout_callback(void *people_nearby_manager_ptr, int64 user_id_long) { + if (G()->close_flag()) { + return; + } + + auto people_nearby_manager = static_cast(people_nearby_manager_ptr); + send_closure_later(people_nearby_manager->actor_id(people_nearby_manager), + &PeopleNearbyManager::on_user_nearby_timeout, UserId(user_id_long)); +} + +void PeopleNearbyManager::on_user_nearby_timeout(UserId user_id) { + if (G()->close_flag()) { + return; + } + + LOG(INFO) << "Remove " << user_id << " from nearby list"; + DialogId dialog_id(user_id); + for (size_t i = 0; i < users_nearby_.size(); i++) { + if (users_nearby_[i].dialog_id == dialog_id) { + users_nearby_.erase(users_nearby_.begin() + i); + send_update_users_nearby(); + return; + } + } +} + +bool PeopleNearbyManager::is_user_nearby(UserId user_id) const { + return all_users_nearby_.count(user_id) != 0; +} + +void PeopleNearbyManager::search_dialogs_nearby(const Location &location, + Promise> &&promise) { + if (location.empty()) { + return promise.set_error(Status::Error(400, "Invalid location specified")); + } + last_user_location_ = location; + try_send_set_location_visibility_query(); + + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( + Result> result) mutable { + send_closure(actor_id, &PeopleNearbyManager::on_get_dialogs_nearby, std::move(result), std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(location, false, -1); +} + +vector> PeopleNearbyManager::get_chats_nearby_object( + const vector &dialogs_nearby) const { + return transform(dialogs_nearby, [td = td_](const DialogNearby &dialog_nearby) { + return td_api::make_object( + td->dialog_manager_->get_chat_id_object(dialog_nearby.dialog_id, "chatNearby"), dialog_nearby.distance); + }); +} + +void PeopleNearbyManager::send_update_users_nearby() const { + send_closure(G()->td(), &Td::send_update, + td_api::make_object(get_chats_nearby_object(users_nearby_))); +} + +void PeopleNearbyManager::on_get_dialogs_nearby(Result> result, + Promise> &&promise) { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + + auto updates_ptr = result.move_as_ok(); + if (updates_ptr->get_id() != telegram_api::updates::ID) { + LOG(ERROR) << "Receive " << oneline(to_string(*updates_ptr)) << " instead of updates"; + return promise.set_error(Status::Error(500, "Receive unsupported response from the server")); + } + + auto update = telegram_api::move_object_as(updates_ptr); + LOG(INFO) << "Receive chats nearby in " << to_string(update); + + td_->user_manager_->on_get_users(std::move(update->users_), "on_get_dialogs_nearby"); + td_->chat_manager_->on_get_chats(std::move(update->chats_), "on_get_dialogs_nearby"); + + for (auto &dialog_nearby : users_nearby_) { + user_nearby_timeout_.cancel_timeout(dialog_nearby.dialog_id.get_user_id().get()); + } + auto old_users_nearby = std::move(users_nearby_); + users_nearby_.clear(); + channels_nearby_.clear(); + int32 location_visibility_expire_date = 0; + for (auto &update_ptr : update->updates_) { + if (update_ptr->get_id() != telegram_api::updatePeerLocated::ID) { + LOG(ERROR) << "Receive unexpected " << to_string(update); + continue; + } + + auto expire_date = on_update_peer_located( + std::move(static_cast(update_ptr.get())->peers_), false); + if (expire_date != -1) { + location_visibility_expire_date = expire_date; + } + } + if (location_visibility_expire_date != location_visibility_expire_date_) { + set_location_visibility_expire_date(location_visibility_expire_date); + update_is_location_visible(); + } + + std::sort(users_nearby_.begin(), users_nearby_.end()); + if (old_users_nearby != users_nearby_) { + send_update_users_nearby(); // for other clients connected to the same TDLib instance + } + promise.set_value(td_api::make_object(get_chats_nearby_object(users_nearby_), + get_chats_nearby_object(channels_nearby_))); +} + +void PeopleNearbyManager::set_location(const Location &location, Promise &&promise) { + if (location.empty()) { + return promise.set_error(Status::Error(400, "Invalid location specified")); + } + last_user_location_ = location; + try_send_set_location_visibility_query(); + + auto query_promise = PromiseCreator::lambda( + [promise = std::move(promise)](Result> result) mutable { + promise.set_value(Unit()); + }); + td_->create_handler(std::move(query_promise))->send(location, true, -1); +} + +void PeopleNearbyManager::set_location_visibility(Td *td) { + bool is_location_visible = td->option_manager_->get_option_boolean("is_location_visible"); + auto pending_location_visibility_expire_date = is_location_visible ? std::numeric_limits::max() : 0; + if (td->people_nearby_manager_ == nullptr) { + G()->td_db()->get_binlog_pmc()->set("pending_location_visibility_expire_date", + to_string(pending_location_visibility_expire_date)); + return; + } + if (td->people_nearby_manager_->pending_location_visibility_expire_date_ == -1 && + pending_location_visibility_expire_date == td->people_nearby_manager_->location_visibility_expire_date_) { + return; + } + if (td->people_nearby_manager_->pending_location_visibility_expire_date_ != pending_location_visibility_expire_date) { + td->people_nearby_manager_->pending_location_visibility_expire_date_ = pending_location_visibility_expire_date; + G()->td_db()->get_binlog_pmc()->set("pending_location_visibility_expire_date", + to_string(pending_location_visibility_expire_date)); + } + td->people_nearby_manager_->try_send_set_location_visibility_query(); +} + +void PeopleNearbyManager::try_send_set_location_visibility_query() { + if (G()->close_flag()) { + return; + } + if (pending_location_visibility_expire_date_ == -1) { + return; + } + + LOG(INFO) << "Trying to send set location visibility query"; + if (is_set_location_visibility_request_sent_) { + return; + } + if (pending_location_visibility_expire_date_ != 0 && last_user_location_.empty()) { + return; + } + + is_set_location_visibility_request_sent_ = true; + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), set_expire_date = pending_location_visibility_expire_date_]( + Result> result) { + send_closure(actor_id, &PeopleNearbyManager::on_set_location_visibility_expire_date, set_expire_date, + result.is_ok() ? 0 : result.error().code()); + }); + td_->create_handler(std::move(query_promise)) + ->send(last_user_location_, true, pending_location_visibility_expire_date_); +} + +void PeopleNearbyManager::on_set_location_visibility_expire_date(int32 set_expire_date, int32 error_code) { + bool success = error_code == 0; + is_set_location_visibility_request_sent_ = false; + + if (set_expire_date != pending_location_visibility_expire_date_) { + return try_send_set_location_visibility_query(); + } + + if (success) { + set_location_visibility_expire_date(pending_location_visibility_expire_date_); + } else { + if (G()->close_flag()) { + // request will be re-sent after restart + return; + } + if (error_code != 406) { + LOG(ERROR) << "Failed to set location visibility expire date to " << pending_location_visibility_expire_date_; + } + } + G()->td_db()->get_binlog_pmc()->erase("pending_location_visibility_expire_date"); + pending_location_visibility_expire_date_ = -1; + update_is_location_visible(); +} + +void PeopleNearbyManager::get_is_location_visible(Promise &&promise) { + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)]( + Result> result) mutable { + send_closure(actor_id, &PeopleNearbyManager::on_get_is_location_visible, std::move(result), std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(Location(), true, -1); +} + +void PeopleNearbyManager::on_get_is_location_visible(Result> &&result, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + if (result.is_error()) { + if (result.error().message() == "GEO_POINT_INVALID" && pending_location_visibility_expire_date_ == -1 && + location_visibility_expire_date_ > 0) { + set_location_visibility_expire_date(0); + update_is_location_visible(); + } + return promise.set_value(Unit()); + } + + auto updates_ptr = result.move_as_ok(); + if (updates_ptr->get_id() != telegram_api::updates::ID) { + LOG(ERROR) << "Receive " << oneline(to_string(*updates_ptr)) << " instead of updates"; + return promise.set_value(Unit()); + } + + auto updates = std::move(telegram_api::move_object_as(updates_ptr)->updates_); + if (updates.size() != 1 || updates[0]->get_id() != telegram_api::updatePeerLocated::ID) { + LOG(ERROR) << "Receive unexpected " << to_string(updates); + return promise.set_value(Unit()); + } + + auto peers = std::move(static_cast(updates[0].get())->peers_); + if (peers.size() != 1 || peers[0]->get_id() != telegram_api::peerSelfLocated::ID) { + LOG(ERROR) << "Receive unexpected " << to_string(peers); + return promise.set_value(Unit()); + } + + auto location_visibility_expire_date = static_cast(peers[0].get())->expires_; + if (location_visibility_expire_date != location_visibility_expire_date_) { + set_location_visibility_expire_date(location_visibility_expire_date); + update_is_location_visible(); + } + + promise.set_value(Unit()); +} + +int32 PeopleNearbyManager::on_update_peer_located(vector> &&peers, + bool from_update) { + auto now = G()->unix_time(); + bool need_update = false; + int32 location_visibility_expire_date = -1; + for (auto &peer_located_ptr : peers) { + if (peer_located_ptr->get_id() == telegram_api::peerSelfLocated::ID) { + auto peer_self_located = telegram_api::move_object_as(peer_located_ptr); + if (peer_self_located->expires_ == 0 || peer_self_located->expires_ > G()->unix_time()) { + location_visibility_expire_date = peer_self_located->expires_; + } + continue; + } + + CHECK(peer_located_ptr->get_id() == telegram_api::peerLocated::ID); + auto peer_located = telegram_api::move_object_as(peer_located_ptr); + DialogId dialog_id(peer_located->peer_); + int32 expires_at = peer_located->expires_; + int32 distance = peer_located->distance_; + if (distance < 0 || distance > 50000000) { + LOG(ERROR) << "Receive wrong distance to " << to_string(peer_located); + continue; + } + if (expires_at <= now) { + LOG(INFO) << "Skip expired result " << to_string(peer_located); + continue; + } + + auto dialog_type = dialog_id.get_type(); + if (dialog_type == DialogType::User) { + auto user_id = dialog_id.get_user_id(); + if (!td_->user_manager_->have_user(user_id)) { + LOG(ERROR) << "Can't find " << user_id; + continue; + } + if (expires_at < now + 86400) { + user_nearby_timeout_.set_timeout_in(user_id.get(), expires_at - now + 1); + } + } else if (dialog_type == DialogType::Channel) { + auto channel_id = dialog_id.get_channel_id(); + if (!td_->chat_manager_->have_channel(channel_id)) { + LOG(ERROR) << "Can't find " << channel_id; + continue; + } + if (expires_at != std::numeric_limits::max()) { + LOG(ERROR) << "Receive expiring at " << expires_at << " group location in " << to_string(peer_located); + } + if (from_update) { + LOG(ERROR) << "Receive nearby " << channel_id << " from update"; + continue; + } + } else { + LOG(ERROR) << "Receive chat of wrong type in " << to_string(peer_located); + continue; + } + + td_->dialog_manager_->force_create_dialog(dialog_id, "on_update_peer_located"); + + if (from_update) { + CHECK(dialog_type == DialogType::User); + bool is_found = false; + for (auto &dialog_nearby : users_nearby_) { + if (dialog_nearby.dialog_id == dialog_id) { + if (dialog_nearby.distance != distance) { + dialog_nearby.distance = distance; + need_update = true; + } + is_found = true; + break; + } + } + if (!is_found) { + users_nearby_.emplace_back(dialog_id, distance); + all_users_nearby_.insert(dialog_id.get_user_id()); + need_update = true; + } + } else { + if (dialog_type == DialogType::User) { + users_nearby_.emplace_back(dialog_id, distance); + all_users_nearby_.insert(dialog_id.get_user_id()); + } else { + channels_nearby_.emplace_back(dialog_id, distance); + } + } + } + if (need_update) { + std::sort(users_nearby_.begin(), users_nearby_.end()); + send_update_users_nearby(); + } + return location_visibility_expire_date; +} + +void PeopleNearbyManager::set_location_visibility_expire_date(int32 expire_date) { + if (location_visibility_expire_date_ == expire_date) { + return; + } + + LOG(INFO) << "Set set_location_visibility_expire_date to " << expire_date; + location_visibility_expire_date_ = expire_date; + if (expire_date == 0) { + G()->td_db()->get_binlog_pmc()->erase("location_visibility_expire_date"); + } else { + G()->td_db()->get_binlog_pmc()->set("location_visibility_expire_date", to_string(expire_date)); + } + // the caller must call update_is_location_visible() itself +} + +void PeopleNearbyManager::update_is_location_visible() { + auto expire_date = pending_location_visibility_expire_date_ != -1 ? pending_location_visibility_expire_date_ + : location_visibility_expire_date_; + td_->option_manager_->set_option_boolean("is_location_visible", expire_date != 0); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PeopleNearbyManager.h b/protocols/Telegram/tdlib/td/td/telegram/PeopleNearbyManager.h new file mode 100644 index 0000000000..ded03d378e --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/PeopleNearbyManager.h @@ -0,0 +1,105 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/Location.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/actor/actor.h" +#include "td/actor/MultiTimeout.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" + +namespace td { + +class Td; + +class PeopleNearbyManager final : public Actor { + public: + PeopleNearbyManager(Td *td, ActorShared<> parent); + + void search_dialogs_nearby(const Location &location, Promise> &&promise); + + void set_location(const Location &location, Promise &&promise); + + static void set_location_visibility(Td *td); + + void get_is_location_visible(Promise &&promise); + + int32 on_update_peer_located(vector> &&peers, bool from_update); + + bool is_user_nearby(UserId user_id) const; + + private: + struct DialogNearby { + DialogId dialog_id; + int32 distance; + + DialogNearby(DialogId dialog_id, int32 distance) : dialog_id(dialog_id), distance(distance) { + } + + bool operator<(const DialogNearby &other) const { + return distance < other.distance || (distance == other.distance && dialog_id.get() < other.dialog_id.get()); + } + + bool operator==(const DialogNearby &other) const { + return distance == other.distance && dialog_id == other.dialog_id; + } + + bool operator!=(const DialogNearby &other) const { + return !(*this == other); + } + }; + + void start_up() final; + + void tear_down() final; + + static void on_user_nearby_timeout_callback(void *people_nearby_manager_ptr, int64 user_id_long); + + void on_user_nearby_timeout(UserId user_id); + + vector> get_chats_nearby_object( + const vector &dialogs_nearby) const; + + void send_update_users_nearby() const; + + void on_get_dialogs_nearby(Result> result, + Promise> &&promise); + + void try_send_set_location_visibility_query(); + + void on_set_location_visibility_expire_date(int32 set_expire_date, int32 error_code); + + void set_location_visibility_expire_date(int32 expire_date); + + void on_get_is_location_visible(Result> &&result, + Promise &&promise); + + void update_is_location_visible(); + + Td *td_; + ActorShared<> parent_; + + vector users_nearby_; + vector channels_nearby_; + FlatHashSet all_users_nearby_; + MultiTimeout user_nearby_timeout_{"UserNearbyTimeout"}; + + int32 location_visibility_expire_date_ = 0; + int32 pending_location_visibility_expire_date_ = -1; + bool is_set_location_visibility_request_sent_ = false; + Location last_user_location_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PhoneNumberManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/PhoneNumberManager.cpp index 650523b759..f83c5beafe 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PhoneNumberManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/PhoneNumberManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,263 +7,343 @@ #include "td/telegram/PhoneNumberManager.h" #include "td/telegram/ConfigManager.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/Global.h" -#include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/misc.h" #include "td/telegram/SuggestedAction.h" #include "td/telegram/Td.h" -#include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" +#include "td/utils/buffer.h" #include "td/utils/logging.h" -#include "td/utils/ScopeGuard.h" namespace td { -void PhoneNumberManager::get_state(uint64 query_id) { - tl_object_ptr obj; - switch (state_) { - case State::Ok: - obj = make_tl_object(); - break; - case State::WaitCode: - obj = send_code_helper_.get_authentication_code_info_object(); - break; +class SendCodeQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit SendCodeQuery(Promise> &&promise) + : promise_(std::move(promise)) { } - CHECK(obj); - send_closure(G()->td(), &Td::send_result, query_id, std::move(obj)); -} -PhoneNumberManager::PhoneNumberManager(PhoneNumberManager::Type type, ActorShared<> parent) - : type_(type), parent_(std::move(parent)) { -} + void send(const telegram_api::Function &send_code) { + send_query(G()->net_query_creator().create(send_code)); + } -void PhoneNumberManager::send_new_send_code_query(uint64 query_id, const telegram_api::Function &send_code) { - on_new_query(query_id); - start_net_query(NetQueryType::SendCode, G()->net_query_creator().create(send_code)); -} + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } -void PhoneNumberManager::set_phone_number(uint64 query_id, string phone_number, Settings settings) { - if (phone_number.empty()) { - return on_query_error(query_id, Status::Error(400, "Phone number must be non-empty")); + auto ptr = result_ptr.move_as_ok(); + switch (ptr->get_id()) { + case telegram_api::auth_sentCodeSuccess::ID: + return on_error(Status::Error(500, "Receive invalid response")); + case telegram_api::auth_sentCode::ID: + return promise_.set_value(telegram_api::move_object_as(ptr)); + default: + UNREACHABLE(); + } } - switch (type_) { - case Type::ChangePhone: - send_closure(G()->config_manager(), &ConfigManager::hide_suggested_action, - SuggestedAction{SuggestedAction::Type::CheckPhoneNumber}); - return send_new_send_code_query(query_id, send_code_helper_.send_change_phone_code(phone_number, settings)); - case Type::VerifyPhone: - return send_new_send_code_query(query_id, send_code_helper_.send_verify_phone_code(phone_number, settings)); - case Type::ConfirmPhone: - default: - UNREACHABLE(); + void on_error(Status status) final { + promise_.set_error(std::move(status)); } -} +}; -void PhoneNumberManager::set_phone_number_and_hash(uint64 query_id, string hash, string phone_number, - Settings settings) { - if (phone_number.empty()) { - return on_query_error(query_id, Status::Error(400, "Phone number must be non-empty")); +class RequestFirebaseSmsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit RequestFirebaseSmsQuery(Promise &&promise) : promise_(std::move(promise)) { } - if (hash.empty()) { - return on_query_error(query_id, Status::Error(400, "Hash must be non-empty")); + + void send(const telegram_api::auth_requestFirebaseSms &query) { + send_query(G()->net_query_creator().create(query)); } - switch (type_) { - case Type::ConfirmPhone: - return send_new_send_code_query(query_id, - send_code_helper_.send_confirm_phone_code(hash, phone_number, settings)); - case Type::ChangePhone: - case Type::VerifyPhone: - default: - UNREACHABLE(); + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); } -} -void PhoneNumberManager::resend_authentication_code(uint64 query_id) { - if (state_ != State::WaitCode) { - return on_query_error(query_id, Status::Error(400, "resendAuthenticationCode unexpected")); + void on_error(Status status) final { + promise_.set_error(std::move(status)); } +}; - auto r_resend_code = send_code_helper_.resend_code(); - if (r_resend_code.is_error()) { - return on_query_error(query_id, r_resend_code.move_as_error()); +class ReportMissingCodeQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ReportMissingCodeQuery(Promise &&promise) : promise_(std::move(promise)) { } - on_new_query(query_id); + void send(const telegram_api::auth_reportMissingCode &query) { + send_query(G()->net_query_creator().create(query)); + } - start_net_query(NetQueryType::SendCode, G()->net_query_creator().create_unauth(r_resend_code.move_as_ok())); -} + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } -void PhoneNumberManager::send_new_check_code_query(const telegram_api::Function &check_code) { - start_net_query(NetQueryType::CheckCode, G()->net_query_creator().create(check_code)); -} + promise_.set_value(Unit()); + } -void PhoneNumberManager::check_code(uint64 query_id, string code) { - if (state_ != State::WaitCode) { - return on_query_error(query_id, Status::Error(400, "checkAuthenticationCode unexpected")); + void on_error(Status status) final { + promise_.set_error(std::move(status)); } +}; - on_new_query(query_id); +class ChangePhoneQuery final : public Td::ResultHandler { + Promise promise_; - switch (type_) { - case Type::ChangePhone: - return send_new_check_code_query(telegram_api::account_changePhone( - send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code)); - case Type::ConfirmPhone: - return send_new_check_code_query( - telegram_api::account_confirmPhone(send_code_helper_.phone_code_hash().str(), code)); - case Type::VerifyPhone: - return send_new_check_code_query(telegram_api::account_verifyPhone( - send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code)); - default: - UNREACHABLE(); + public: + explicit ChangePhoneQuery(Promise &&promise) : promise_(std::move(promise)) { } -} -void PhoneNumberManager::on_new_query(uint64 query_id) { - if (query_id_ != 0) { - on_query_error(Status::Error(400, "Another authorization query has started")); + void send(const string &phone_number, const string &phone_code_hash, const string &code) { + send_query(G()->net_query_creator().create(telegram_api::account_changePhone(phone_number, phone_code_hash, code))); } - net_query_id_ = 0; - net_query_type_ = NetQueryType::None; - query_id_ = query_id; - // TODO: cancel older net_query -} -void PhoneNumberManager::on_query_error(Status status) { - CHECK(query_id_ != 0); - auto id = query_id_; - query_id_ = 0; - net_query_id_ = 0; - net_query_type_ = NetQueryType::None; - on_query_error(id, std::move(status)); -} + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } -void PhoneNumberManager::on_query_error(uint64 id, Status status) { - send_closure(G()->td(), &Td::send_error, id, std::move(status)); -} + td_->user_manager_->on_get_user(result_ptr.move_as_ok(), "ChangePhoneQuery"); + promise_.set_value(Unit()); + } -void PhoneNumberManager::on_query_ok() { - CHECK(query_id_ != 0); - auto id = query_id_; - net_query_id_ = 0; - net_query_type_ = NetQueryType::None; - query_id_ = 0; - get_state(id); -} + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; -void PhoneNumberManager::start_net_query(NetQueryType net_query_type, NetQueryPtr net_query) { - // TODO: cancel old net_query? - net_query_type_ = net_query_type; - net_query_id_ = net_query->id(); - G()->net_query_dispatcher().dispatch_with_callback(std::move(net_query), actor_shared(this)); -} +class VerifyPhoneQuery final : public Td::ResultHandler { + Promise promise_; -void PhoneNumberManager::process_check_code_result(Result> &&result) { - if (result.is_error()) { - return on_query_error(result.move_as_error()); + public: + explicit VerifyPhoneQuery(Promise &&promise) : promise_(std::move(promise)) { } - send_closure(G()->contacts_manager(), &ContactsManager::on_get_user, result.move_as_ok(), "process_check_code_result", - true); - state_ = State::Ok; - on_query_ok(); -} -void PhoneNumberManager::process_check_code_result(Result &&result) { - if (result.is_error()) { - return on_query_error(result.move_as_error()); + void send(const string &phone_number, const string &phone_code_hash, const string &code) { + send_query(G()->net_query_creator().create(telegram_api::account_verifyPhone(phone_number, phone_code_hash, code))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class ConfirmPhoneQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ConfirmPhoneQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &phone_code_hash, const string &code) { + send_query(G()->net_query_creator().create(telegram_api::account_confirmPhone(phone_code_hash, code))); } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +PhoneNumberManager::PhoneNumberManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void PhoneNumberManager::tear_down() { + parent_.reset(); +} + +void PhoneNumberManager::inc_generation() { + generation_++; state_ = State::Ok; - on_query_ok(); + send_code_helper_ = {}; } -void PhoneNumberManager::on_check_code_result(NetQueryPtr &result) { - switch (type_) { - case Type::ChangePhone: - return process_check_code_result(fetch_result(result->ok())); - case Type::VerifyPhone: - return process_check_code_result(fetch_result(result->ok())); - case Type::ConfirmPhone: - return process_check_code_result(fetch_result(result->ok())); - default: - UNREACHABLE(); - } +void PhoneNumberManager::send_new_send_code_query( + const telegram_api::Function &send_code, Promise> &&promise) { + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), generation = generation_, promise = std::move(promise)]( + Result> r_sent_code) mutable { + send_closure(actor_id, &PhoneNumberManager::on_send_code_result, std::move(r_sent_code), generation, + std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(send_code); } -void PhoneNumberManager::on_send_code_result(NetQueryPtr &result) { - auto r_sent_code = [&] { - switch (type_) { - case Type::ChangePhone: - return fetch_result(result->ok()); - case Type::VerifyPhone: - return fetch_result(result->ok()); - case Type::ConfirmPhone: - return fetch_result(result->ok()); - default: - UNREACHABLE(); - return fetch_result(result->ok()); - } - }(); +void PhoneNumberManager::on_send_code_result(Result> r_sent_code, + int64 generation, + Promise> &&promise) { + G()->ignore_result_if_closing(r_sent_code); if (r_sent_code.is_error()) { - return on_query_error(r_sent_code.move_as_error()); + return promise.set_error(r_sent_code.move_as_error()); } - auto sent_code_ptr = r_sent_code.move_as_ok(); - auto sent_code_id = sent_code_ptr->get_id(); - if (sent_code_id != telegram_api::auth_sentCode::ID) { - CHECK(sent_code_id == telegram_api::auth_sentCodeSuccess::ID); - return on_query_error(Status::Error(500, "Receive invalid response")); + if (generation != generation_) { + return promise.set_error(Status::Error(500, "Request was canceled")); } - auto sent_code = telegram_api::move_object_as(sent_code_ptr); + auto sent_code = r_sent_code.move_as_ok(); LOG(INFO) << "Receive " << to_string(sent_code); switch (sent_code->type_->get_id()) { case telegram_api::auth_sentCodeTypeSetUpEmailRequired::ID: case telegram_api::auth_sentCodeTypeEmailCode::ID: - return on_query_error(Status::Error(500, "Receive incorrect response")); + return promise.set_error(Status::Error(500, "Receive incorrect response")); default: break; } send_code_helper_.on_sent_code(std::move(sent_code)); - state_ = State::WaitCode; - on_query_ok(); + + promise.set_value(send_code_helper_.get_authentication_code_info_object()); } -void PhoneNumberManager::on_result(NetQueryPtr result) { - SCOPE_EXIT { - result->clear(); - }; - NetQueryType type = NetQueryType::None; - if (result->id() == net_query_id_) { - net_query_id_ = 0; - type = net_query_type_; - net_query_type_ = NetQueryType::None; - if (result->is_error()) { - if (query_id_ != 0) { - on_query_error(std::move(result->error())); +void PhoneNumberManager::set_phone_number(string phone_number, + td_api::object_ptr settings, + td_api::object_ptr type, + Promise> &&promise) { + inc_generation(); + if (phone_number.empty()) { + return promise.set_error(Status::Error(400, "Phone number must be non-empty")); + } + if (type == nullptr) { + return promise.set_error(Status::Error(400, "Type must be non-empty")); + } + + switch (type->get_id()) { + case td_api::phoneNumberCodeTypeChange::ID: + type_ = Type::ChangePhone; + send_closure(G()->config_manager(), &ConfigManager::hide_suggested_action, + SuggestedAction{SuggestedAction::Type::CheckPhoneNumber}); + return send_new_send_code_query(send_code_helper_.send_change_phone_code(phone_number, settings), + std::move(promise)); + case td_api::phoneNumberCodeTypeVerify::ID: + type_ = Type::VerifyPhone; + return send_new_send_code_query(send_code_helper_.send_verify_phone_code(phone_number, settings), + std::move(promise)); + case td_api::phoneNumberCodeTypeConfirmOwnership::ID: { + auto hash = std::move(static_cast(type.get())->hash_); + if (!clean_input_string(hash)) { + return promise.set_error(Status::Error(400, "Hash must be encoded in UTF-8")); + } + if (hash.empty()) { + return promise.set_error(Status::Error(400, "Hash must be non-empty")); } - return; + + type_ = Type::ConfirmPhone; + return send_new_send_code_query(send_code_helper_.send_confirm_phone_code(hash, phone_number, settings), + std::move(promise)); } + default: + UNREACHABLE(); } - switch (type) { - case NetQueryType::None: - result->ignore(); +} + +void PhoneNumberManager::send_firebase_sms(const string &token, Promise &&promise) { + if (state_ != State::WaitCode) { + return promise.set_error(Status::Error(400, "Can't send Firebase SMS")); + } + + td_->create_handler(std::move(promise))->send(send_code_helper_.request_firebase_sms(token)); +} + +void PhoneNumberManager::report_missing_code(const string &mobile_network_code, Promise &&promise) { + if (state_ != State::WaitCode) { + return promise.set_error(Status::Error(400, "Can't report missing code")); + } + + td_->create_handler(std::move(promise)) + ->send(send_code_helper_.report_missing_code(mobile_network_code)); +} + +void PhoneNumberManager::resend_authentication_code( + td_api::object_ptr &&reason, + Promise> &&promise) { + if (state_ != State::WaitCode) { + return promise.set_error(Status::Error(400, "Can't resend code")); + } + + auto r_resend_code = send_code_helper_.resend_code(std::move(reason)); + if (r_resend_code.is_error()) { + return promise.set_error(r_resend_code.move_as_error()); + } + + send_new_send_code_query(r_resend_code.move_as_ok(), std::move(promise)); +} + +void PhoneNumberManager::check_code(string code, Promise &&promise) { + if (state_ != State::WaitCode) { + return promise.set_error(Status::Error(400, "Can't check code")); + } + + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), generation = generation_, promise = std::move(promise)](Result result) mutable { + send_closure(actor_id, &PhoneNumberManager::on_check_code_result, std::move(result), generation, + std::move(promise)); + }); + switch (type_) { + case Type::ChangePhone: + td_->create_handler(std::move(query_promise)) + ->send(send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code); break; - case NetQueryType::SendCode: - on_send_code_result(result); + case Type::VerifyPhone: + td_->create_handler(std::move(query_promise)) + ->send(send_code_helper_.phone_number().str(), send_code_helper_.phone_code_hash().str(), code); break; - case NetQueryType::CheckCode: - on_check_code_result(result); + case Type::ConfirmPhone: + td_->create_handler(std::move(query_promise)) + ->send(send_code_helper_.phone_code_hash().str(), code); break; + default: + UNREACHABLE(); } } -void PhoneNumberManager::tear_down() { - parent_.reset(); +void PhoneNumberManager::on_check_code_result(Result result, int64 generation, Promise &&promise) { + G()->ignore_result_if_closing(result); + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + if (generation != generation_) { + return promise.set_error(Status::Error(500, "Request was canceled")); + } + + inc_generation(); + + promise.set_value(Unit()); } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PhoneNumberManager.h b/protocols/Telegram/tdlib/td/td/telegram/PhoneNumberManager.h index b9456ca82e..3c09f0ed5e 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PhoneNumberManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/PhoneNumberManager.h @@ -1,13 +1,11 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once -#include "td/telegram/net/NetActor.h" -#include "td/telegram/net/NetQuery.h" #include "td/telegram/SendCodeHelper.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" @@ -15,62 +13,52 @@ #include "td/actor/actor.h" #include "td/utils/common.h" +#include "td/utils/Promise.h" #include "td/utils/Status.h" namespace td { -class PhoneNumberManager final : public NetActor { - public: - enum class Type : int32 { ChangePhone, VerifyPhone, ConfirmPhone }; - PhoneNumberManager(Type type, ActorShared<> parent); - void get_state(uint64 query_id); - - using Settings = td_api::object_ptr; - - void set_phone_number(uint64 query_id, string phone_number, Settings settings); - void set_phone_number_and_hash(uint64 query_id, string hash, string phone_number, Settings settings); - - void resend_authentication_code(uint64 query_id); - void check_code(uint64 query_id, string code); - - private: - Type type_; - - enum class State : int32 { Ok, WaitCode } state_ = State::Ok; - enum class NetQueryType : int32 { None, SendCode, CheckCode }; - - ActorShared<> parent_; - uint64 query_id_ = 0; - uint64 net_query_id_ = 0; - NetQueryType net_query_type_ = NetQueryType::None; +class Td; - SendCodeHelper send_code_helper_; +class PhoneNumberManager final : public Actor { + public: + PhoneNumberManager(Td *td, ActorShared<> parent); - void on_new_query(uint64 query_id); + void set_phone_number(string phone_number, td_api::object_ptr settings, + td_api::object_ptr type, + Promise> &&promise); - void on_query_ok(); + void send_firebase_sms(const string &token, Promise &&promise); - void on_query_error(Status status); + void report_missing_code(const string &mobile_network_code, Promise &&promise); - static void on_query_error(uint64 id, Status status); + void resend_authentication_code(td_api::object_ptr &&reason, + Promise> &&promise); - void start_net_query(NetQueryType net_query_type, NetQueryPtr net_query); + void check_code(string code, Promise &&promise); - void send_new_send_code_query(uint64 query_id, const telegram_api::Function &send_code); + private: + enum class Type : int32 { ChangePhone, VerifyPhone, ConfirmPhone }; + enum class State : int32 { Ok, WaitCode } state_ = State::Ok; - void send_new_check_code_query(const telegram_api::Function &check_code); + void tear_down() final; - void process_check_code_result(Result> &&result); + void inc_generation(); - void process_check_code_result(Result &&result); + void send_new_send_code_query(const telegram_api::Function &send_code, + Promise> &&promise); - void on_result(NetQueryPtr result) final; + void on_send_code_result(Result> r_sent_code, int64 generation, + Promise> &&promise); - void on_send_code_result(NetQueryPtr &result); + void on_check_code_result(Result result, int64 generation, Promise &&promise); - void on_check_code_result(NetQueryPtr &result); + Td *td_; + ActorShared<> parent_; - void tear_down() final; + Type type_; + SendCodeHelper send_code_helper_; + int64 generation_ = 0; }; } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Photo.cpp b/protocols/Telegram/tdlib/td/td/telegram/Photo.cpp index 37daed2e64..9f0a0fa5e9 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Photo.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/Photo.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,6 +16,7 @@ #include "td/telegram/PhotoFormat.h" #include "td/telegram/PhotoSizeSource.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" #include "td/utils/algorithm.h" #include "td/utils/common.h" @@ -180,8 +181,9 @@ DialogPhoto as_dialog_photo(FileManager *file_manager, DialogId dialog_id, int64 auto reregister_photo = [&](bool is_big, FileId file_id) { auto file_view = file_manager->get_file_view(file_id); - CHECK(file_view.has_remote_location()); - auto remote = file_view.remote_location(); + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + auto remote = *full_remote_location; CHECK(remote.is_photo()); CHECK(!remote.is_web()); remote.set_source(PhotoSizeSource::dialog_photo(dialog_id, dialog_access_hash, is_big)); @@ -297,15 +299,15 @@ Photo get_encrypted_file_photo(FileManager *file_manager, unique_ptr &&photo, DialogId owner_dialog_id) { +Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId owner_dialog_id, FileType file_type) { if (photo == nullptr || photo->get_id() == telegram_api::photoEmpty::ID) { return Photo(); } CHECK(photo->get_id() == telegram_api::photo::ID); - return get_photo(td, move_tl_object_as(photo), owner_dialog_id); + return get_photo(td, move_tl_object_as(photo), owner_dialog_id, file_type); } -Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId owner_dialog_id) { +Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId owner_dialog_id, FileType file_type) { CHECK(photo != nullptr); Photo res; @@ -320,8 +322,8 @@ Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId own DcId dc_id = DcId::create(photo->dc_id_); for (auto &size_ptr : photo->sizes_) { - auto photo_size = get_photo_size(td->file_manager_.get(), PhotoSizeSource::thumbnail(FileType::Photo, 0), - photo->id_, photo->access_hash_, photo->file_reference_.as_slice().str(), dc_id, + auto photo_size = get_photo_size(td->file_manager_.get(), PhotoSizeSource::thumbnail(file_type, 0), photo->id_, + photo->access_hash_, photo->file_reference_.as_slice().str(), dc_id, owner_dialog_id, std::move(size_ptr), PhotoFormat::Jpeg); if (photo_size.get_offset() == 0) { PhotoSize &size = photo_size.get<0>(); @@ -338,7 +340,7 @@ Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId own for (auto &size_ptr : photo->video_sizes_) { auto animation = - process_video_size(td, PhotoSizeSource::thumbnail(FileType::Photo, 0), photo->id_, photo->access_hash_, + process_video_size(td, PhotoSizeSource::thumbnail(file_type, 0), photo->id_, photo->access_hash_, photo->file_reference_.as_slice().str(), dc_id, owner_dialog_id, std::move(size_ptr)); if (animation.empty()) { continue; @@ -374,8 +376,9 @@ Result create_photo(FileManager *file_manager, FileId file_id, PhotoSize Photo photo; auto file_view = file_manager->get_file_view(file_id); - if (file_view.has_remote_location() && !file_view.remote_location().is_web()) { - photo.id = file_view.remote_location().get_id(); + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location != nullptr && !full_remote_location->is_web()) { + photo.id = full_remote_location->get_id(); } if (photo.is_empty()) { photo.id = 0; @@ -390,6 +393,56 @@ Result create_photo(FileManager *file_manager, FileId file_id, PhotoSize return std::move(photo); } +Photo dup_photo(Photo photo) { + CHECK(!photo.photos.empty()); + + // Find 'i' or largest + PhotoSize input_size; + for (const auto &size : photo.photos) { + if (size.type == 'i') { + input_size = size; + } + } + if (input_size.type == 0) { + for (const auto &size : photo.photos) { + if (input_size.type == 0 || input_size < size) { + input_size = size; + } + } + } + + // Find 't' or smallest + PhotoSize thumbnail; + for (const auto &size : photo.photos) { + if (size.type == 't') { + thumbnail = size; + } + } + if (thumbnail.type == 0) { + for (const auto &size : photo.photos) { + if (size.type != input_size.type && (thumbnail.type == 0 || size < thumbnail)) { + thumbnail = size; + } + } + } + + Photo result; + result.id = std::move(photo.id); + result.date = photo.date; + result.minithumbnail = std::move(photo.minithumbnail); + result.has_stickers = photo.has_stickers; + result.sticker_file_ids = std::move(photo.sticker_file_ids); + + if (thumbnail.type != 0) { + thumbnail.type = 't'; + result.photos.push_back(std::move(thumbnail)); + } + input_size.type = 'i'; + result.photos.push_back(std::move(input_size)); + + return result; +} + tl_object_ptr get_photo_object(FileManager *file_manager, const Photo &photo) { if (photo.is_empty()) { return nullptr; @@ -482,23 +535,23 @@ void merge_photos(Td *td, const Photo *old_photo, Photo *new_photo, DialogId dia if (need_merge && new_photos_size != 0) { FileId old_file_id = get_photo_upload_file_id(*old_photo); FileView old_file_view = td->file_manager_->get_file_view(old_file_id); + const auto *old_main_remote_location = old_file_view.get_main_remote_location(); FileId new_file_id = new_photo->photos[0].file_id; FileView new_file_view = td->file_manager_->get_file_view(new_file_id); - CHECK(new_file_view.has_remote_location()); + const auto *new_full_remote_location = new_file_view.get_full_remote_location(); + CHECK(new_full_remote_location != nullptr); LOG(DEBUG) << "Trying to merge old file " << old_file_id << " and new file " << new_file_id; - if (new_file_view.remote_location().is_web()) { + + if (new_full_remote_location->is_web()) { LOG(ERROR) << "Have remote web photo location"; - } else if (!old_file_view.has_remote_location() || - old_file_view.main_remote_location().get_file_reference() != - new_file_view.remote_location().get_file_reference() || - old_file_view.main_remote_location().get_access_hash() != - new_file_view.remote_location().get_access_hash()) { + } else if (old_main_remote_location == nullptr || + old_main_remote_location->get_file_reference() != new_full_remote_location->get_file_reference() || + old_main_remote_location->get_access_hash() != new_full_remote_location->get_access_hash()) { FileId file_id = td->file_manager_->register_remote( FullRemoteFileLocation(PhotoSizeSource::thumbnail(new_file_view.get_type(), 'i'), - new_file_view.remote_location().get_id(), - new_file_view.remote_location().get_access_hash(), DcId::invalid(), - new_file_view.remote_location().get_file_reference().str()), + new_full_remote_location->get_id(), new_full_remote_location->get_access_hash(), + DcId::invalid(), new_full_remote_location->get_file_reference().str()), FileLocationSource::FromServer, dialog_id, old_photo->photos.back().size, 0, ""); LOG_STATUS(td->file_manager_->merge(file_id, old_file_id)); } @@ -523,7 +576,7 @@ bool photo_has_input_media(FileManager *file_manager, const Photo &photo, bool i auto file_id = photo.photos.back().file_id; auto file_view = file_manager->get_file_view(file_id); if (is_secret) { - if (!file_view.is_encrypted_secret() || !file_view.has_remote_location()) { + if (!file_view.is_encrypted_secret() || !file_view.has_full_remote_location()) { return false; } @@ -538,10 +591,10 @@ bool photo_has_input_media(FileManager *file_manager, const Photo &photo, bool i if (file_view.is_encrypted()) { return false; } - if (is_bot && file_view.has_remote_location()) { + if (is_bot && file_view.has_full_remote_location()) { return true; } - return /* file_view.has_remote_location() || */ file_view.has_url(); + return /* file_view.has_full_remote_location() || */ file_view.has_url(); } } @@ -554,7 +607,8 @@ tl_object_ptr photo_get_input_media(FileManager *file_ if (file_view.is_encrypted()) { return nullptr; } - if (file_view.has_remote_location() && !file_view.main_remote_location().is_web() && input_file == nullptr) { + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr && !main_remote_location->is_web() && input_file == nullptr) { int32 flags = 0; if (ttl != 0) { flags |= telegram_api::inputMediaPhoto::TTL_SECONDS_MASK; @@ -563,9 +617,10 @@ tl_object_ptr photo_get_input_media(FileManager *file_ flags |= telegram_api::inputMediaPhoto::SPOILER_MASK; } return make_tl_object(flags, false /*ignored*/, - file_view.main_remote_location().as_input_photo(), ttl); + main_remote_location->as_input_photo(), ttl); } - if (file_view.has_url()) { + const auto *url = file_view.get_url(); + if (url != nullptr) { int32 flags = 0; if (ttl != 0) { flags |= telegram_api::inputMediaPhotoExternal::TTL_SECONDS_MASK; @@ -573,11 +628,11 @@ tl_object_ptr photo_get_input_media(FileManager *file_ if (has_spoiler) { flags |= telegram_api::inputMediaPhotoExternal::SPOILER_MASK; } - LOG(INFO) << "Create inputMediaPhotoExternal with a URL " << file_view.url() << " and self-destruct time " << ttl; - return make_tl_object(flags, false /*ignored*/, file_view.url(), ttl); + LOG(INFO) << "Create inputMediaPhotoExternal with a URL " << *url << " and self-destruct time " << ttl; + return make_tl_object(flags, false /*ignored*/, *url, ttl); } if (input_file == nullptr) { - CHECK(!file_view.has_remote_location()); + CHECK(main_remote_location == nullptr); } } if (input_file != nullptr) { @@ -633,9 +688,10 @@ SecretInputMedia photo_get_secret_input_media(FileManager *file_manager, const P if (!file_view.is_encrypted_secret() || encryption_key.empty()) { return {}; } - if (file_view.has_remote_location()) { + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr) { LOG(INFO) << "Photo has remote location"; - input_file = file_view.main_remote_location().as_input_encrypted_file(); + input_file = main_remote_location->as_input_encrypted_file(); } if (input_file == nullptr) { return {}; diff --git a/protocols/Telegram/tdlib/td/td/telegram/Photo.h b/protocols/Telegram/tdlib/td/td/telegram/Photo.h index f3c2470bbc..653f7ed664 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Photo.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Photo.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,6 +9,7 @@ #include "td/telegram/DialogId.h" #include "td/telegram/EncryptedFile.h" #include "td/telegram/files/FileId.h" +#include "td/telegram/files/FileType.h" #include "td/telegram/PhotoSize.h" #include "td/telegram/secret_api.h" #include "td/telegram/SecretInputMedia.h" @@ -84,6 +85,7 @@ StringBuilder &operator<<(StringBuilder &string_builder, const ProfilePhoto &pro DialogPhoto get_dialog_photo(FileManager *file_manager, DialogId dialog_id, int64 dialog_access_hash, tl_object_ptr &&chat_photo_ptr); + tl_object_ptr get_chat_photo_info_object(FileManager *file_manager, const DialogPhoto *dialog_photo); @@ -104,9 +106,11 @@ bool need_update_dialog_photo(const DialogPhoto &from, const DialogPhoto &to); StringBuilder &operator<<(StringBuilder &string_builder, const DialogPhoto &dialog_photo); -Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId owner_dialog_id); +Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId owner_dialog_id, + FileType file_type = FileType::Photo); -Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId owner_dialog_id); +Photo get_photo(Td *td, tl_object_ptr &&photo, DialogId owner_dialog_id, + FileType file_type = FileType::Photo); Photo get_encrypted_file_photo(FileManager *file_manager, unique_ptr &&file, tl_object_ptr &&photo, DialogId owner_dialog_id); @@ -117,6 +121,8 @@ Photo get_web_document_photo(FileManager *file_manager, tl_object_ptr create_photo(FileManager *file_manager, FileId file_id, PhotoSize &&thumbnail, int32 width, int32 height, vector &&sticker_file_ids); +Photo dup_photo(Photo photo); + tl_object_ptr get_photo_object(FileManager *file_manager, const Photo &photo); tl_object_ptr get_chat_photo_object(FileManager *file_manager, const Photo &photo); diff --git a/protocols/Telegram/tdlib/td/td/telegram/PhotoSize.cpp b/protocols/Telegram/tdlib/td/td/telegram/PhotoSize.cpp index 5dc463441f..483d973155 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PhotoSize.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/PhotoSize.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,6 +9,7 @@ #include "td/telegram/files/FileLocation.h" #include "td/telegram/files/FileManager.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" #include "td/utils/base64.h" #include "td/utils/HttpUrl.h" @@ -241,6 +242,16 @@ Variant get_photo_size(FileManager *file_manager, PhotoSizeSo res.type = 0; } } + if (format == PhotoFormat::Tgs) { + if (res.type == 's') { + format = PhotoFormat::Webp; + } else if (res.type == 'v') { + format = PhotoFormat::Webm; + } else if (res.type != 'a') { + LOG(ERROR) << "Receive sticker set thumbnail of type " << res.type; + format = PhotoFormat::Webp; + } + } if (source.get_type("get_photo_size") == PhotoSizeSource::Type::Thumbnail) { source.thumbnail().thumbnail_type = res.type; } @@ -410,25 +421,26 @@ PhotoSize get_web_document_photo_size(FileManager *file_manager, FileType file_t Result get_input_photo_size(FileManager *file_manager, FileId file_id, int32 width, int32 height) { if (width < 0 || width > 10000) { - return Status::Error(400, "Wrong photo width"); + return Status::Error(400, "Width of the photo is too big"); } if (height < 0 || height > 10000) { - return Status::Error(400, "Wrong photo height"); + return Status::Error(400, "Height of the photo is too big"); } if (width + height > 10000) { - return Status::Error(400, "Photo dimensions are too big"); + return Status::Error(400, "Dimensions of the photo are too big"); } auto file_view = file_manager->get_file_view(file_id); auto file_size = file_view.size(); if (file_size < 0 || file_size >= 1000000000) { - return Status::Error(400, "Photo is too big"); + return Status::Error(400, "Size of the photo is too big"); } int32 type = 'i'; - if (file_view.has_remote_location() && !file_view.remote_location().is_web()) { - auto photo_size_source = file_view.remote_location().get_source(); - if (photo_size_source.get_type("create_input_message_content") == PhotoSizeSource::Type::Thumbnail) { + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location != nullptr && !full_remote_location->is_web()) { + auto photo_size_source = full_remote_location->get_source(); + if (photo_size_source.get_type("get_input_photo_size") == PhotoSizeSource::Type::Thumbnail) { auto old_type = photo_size_source.thumbnail().thumbnail_type; if (old_type != 't') { type = old_type; @@ -459,7 +471,7 @@ PhotoSize get_input_thumbnail_photo_size(FileManager *file_manager, const td_api CHECK(thumbnail.file_id.is_valid()); FileView thumbnail_file_view = file_manager->get_file_view(thumbnail.file_id); - if (thumbnail_file_view.has_remote_location()) { + if (thumbnail_file_view.has_full_remote_location()) { // TODO file_manager->delete_remote_location(thumbnail.file_id); } } diff --git a/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.cpp b/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.cpp index 9218af27d9..76f4b82c39 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -65,67 +65,121 @@ FileType PhotoSizeSource::get_file_type(const char *source) const { } string PhotoSizeSource::get_unique(const char *source) const { + auto compare_type = get_compare_type(source); + if (compare_type != 2 && compare_type != 3) { + return string(1, static_cast(compare_type)); + } + auto ptr = StackAllocator::alloc(16); MutableSlice data = ptr.as_slice(); TlStorerUnsafe storer(data.ubegin()); + if (compare_type == 2) { + storer.store_slice(Slice("\x02")); + } + td::store(get_compare_volume_id(), storer); + td::store(get_compare_local_id(), storer); + auto size = storer.get_buf() - data.ubegin(); + CHECK(size <= 13); + return string(data.begin(), size); +} + +int32 PhotoSizeSource::get_compare_type(const char *source) const { switch (get_type(source)) { case Type::Legacy: - UNREACHABLE(); break; case Type::Thumbnail: { auto type = thumbnail().thumbnail_type; CHECK(0 <= type && type <= 127); if (type == 'a') { - type = 0; - } else if (type == 'c') { - type = 1; - } else { - type += 5; + return 0; } - return string(1, static_cast(type)); + if (type == 'c') { + return 1; + } + return type + 5; } case Type::DialogPhotoSmall: - // it doesn't matter to which Dialog the photo belongs - return string(1, '\x00'); + return 0; case Type::DialogPhotoBig: - // it doesn't matter to which Dialog the photo belongs - return string(1, '\x01'); + return 1; case Type::StickerSetThumbnail: - UNREACHABLE(); break; - case Type::FullLegacy: { - auto &legacy = full_legacy(); - td::store(legacy.volume_id, storer); - td::store(legacy.local_id, storer); - break; - } + case Type::FullLegacy: case Type::DialogPhotoSmallLegacy: - case Type::DialogPhotoBigLegacy: { - auto &legacy = dialog_photo_legacy(); - td::store(legacy.volume_id, storer); - td::store(legacy.local_id, storer); - break; - } - case Type::StickerSetThumbnailLegacy: { - auto &legacy = sticker_set_thumbnail_legacy(); - td::store(legacy.volume_id, storer); - td::store(legacy.local_id, storer); - break; - } - case Type::StickerSetThumbnailVersion: { - auto &thumbnail = sticker_set_thumbnail_version(); - storer.store_slice(Slice("\x02")); - td::store(thumbnail.sticker_set_id, storer); - td::store(thumbnail.version, storer); + case Type::DialogPhotoBigLegacy: + case Type::StickerSetThumbnailLegacy: + return 3; + case Type::StickerSetThumbnailVersion: + return 2; + default: break; - } + } + UNREACHABLE(); + return -1; +} + +int64 PhotoSizeSource::get_compare_volume_id() const { + switch (get_type("get_compare_volume_id")) { + case Type::FullLegacy: + return full_legacy().volume_id; + case Type::DialogPhotoSmallLegacy: + case Type::DialogPhotoBigLegacy: + return dialog_photo_legacy().volume_id; + case Type::StickerSetThumbnailLegacy: + return sticker_set_thumbnail_legacy().volume_id; + case Type::StickerSetThumbnailVersion: + return sticker_set_thumbnail_version().sticker_set_id; default: UNREACHABLE(); - break; + return 0; } - auto size = storer.get_buf() - data.ubegin(); - CHECK(size <= 13); - return string(data.begin(), size); +} + +int32 PhotoSizeSource::get_compare_local_id() const { + switch (get_type("get_compare_volume_id")) { + case Type::FullLegacy: + return full_legacy().local_id; + case Type::DialogPhotoSmallLegacy: + case Type::DialogPhotoBigLegacy: + return dialog_photo_legacy().local_id; + case Type::StickerSetThumbnailLegacy: + return sticker_set_thumbnail_legacy().local_id; + case Type::StickerSetThumbnailVersion: + return sticker_set_thumbnail_version().version; + default: + UNREACHABLE(); + return 0; + } +} + +bool PhotoSizeSource::unique_less(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs) { + auto lhs_compare_type = lhs.get_compare_type("unique_less"); + auto rhs_compare_type = rhs.get_compare_type("unique_less"); + if (lhs_compare_type != rhs_compare_type) { + return lhs_compare_type < rhs_compare_type; + } + if (lhs_compare_type != 2 && lhs_compare_type != 3) { + return false; + } + auto lhs_volume_id = lhs.get_compare_volume_id(); + auto rhs_volume_id = rhs.get_compare_volume_id(); + if (lhs_volume_id != rhs_volume_id) { + return lhs_volume_id < rhs_volume_id; + } + return lhs.get_compare_local_id() < rhs.get_compare_local_id(); +} + +bool PhotoSizeSource::unique_equal(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs) { + auto lhs_compare_type = lhs.get_compare_type("unique_equal"); + auto rhs_compare_type = rhs.get_compare_type("unique_equal"); + if (lhs_compare_type != rhs_compare_type) { + return false; + } + if (lhs_compare_type != 2 && lhs_compare_type != 3) { + return true; + } + return lhs.get_compare_volume_id() == rhs.get_compare_volume_id() && + lhs.get_compare_local_id() == rhs.get_compare_local_id(); } string PhotoSizeSource::get_unique_name(int64 photo_id, const char *source) const { @@ -233,18 +287,18 @@ StringBuilder &operator<<(StringBuilder &string_builder, const PhotoSizeSource & return string_builder << "PhotoSizeSourceThumbnail[" << source.thumbnail().file_type << ", type = " << source.thumbnail().thumbnail_type << ']'; case PhotoSizeSource::Type::DialogPhotoSmall: - return string_builder << "PhotoSizeSourceChatPhotoSmall[" << source.dialog_photo().dialog_id << ']'; + return string_builder << "PhotoSizeSourceChatPhotoSmall[]"; case PhotoSizeSource::Type::DialogPhotoBig: - return string_builder << "PhotoSizeSourceChatPhotoBig[" << source.dialog_photo().dialog_id << ']'; + return string_builder << "PhotoSizeSourceChatPhotoBig[]"; case PhotoSizeSource::Type::StickerSetThumbnail: return string_builder << "PhotoSizeSourceStickerSetThumbnail[" << source.sticker_set_thumbnail().sticker_set_id << ']'; case PhotoSizeSource::Type::FullLegacy: return string_builder << "PhotoSizeSourceFullLegacy[]"; case PhotoSizeSource::Type::DialogPhotoSmallLegacy: - return string_builder << "PhotoSizeSourceChatPhotoSmallLegacy[" << source.dialog_photo().dialog_id << ']'; + return string_builder << "PhotoSizeSourceChatPhotoSmallLegacy[]"; case PhotoSizeSource::Type::DialogPhotoBigLegacy: - return string_builder << "PhotoSizeSourceChatPhotoBigLegacy[" << source.dialog_photo().dialog_id << ']'; + return string_builder << "PhotoSizeSourceChatPhotoBigLegacy[]"; case PhotoSizeSource::Type::StickerSetThumbnailLegacy: return string_builder << "PhotoSizeSourceStickerSetThumbnailLegacy[" << source.sticker_set_thumbnail().sticker_set_id << ']'; diff --git a/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.h b/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.h index d3dd2d227a..e49bca238c 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.h +++ b/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -152,10 +152,6 @@ struct PhotoSizeSource { } } - static PhotoSizeSource sticker_set_thumbnail(int64 sticker_set_id, int64 sticker_set_access_hash) { - return PhotoSizeSource(StickerSetThumbnail(sticker_set_id, sticker_set_access_hash)); - } - static PhotoSizeSource full_legacy(int64 volume_id, int32 local_id, int64 secret) { return PhotoSizeSource(FullLegacy(volume_id, local_id, secret)); } @@ -178,6 +174,10 @@ struct PhotoSizeSource { return PhotoSizeSource(StickerSetThumbnailVersion(sticker_set_id, sticker_set_access_hash, version)); } + static bool unique_less(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs); + + static bool unique_equal(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs); + Type get_type(const char *source) const { auto offset = variant_.get_offset(); LOG_CHECK(offset >= 0) << offset << ' ' << source; @@ -262,6 +262,12 @@ struct PhotoSizeSource { template explicit PhotoSizeSource(const T &variant) : variant_(variant) { } + + int32 get_compare_type(const char *source) const; + + int64 get_compare_volume_id() const; + + int32 get_compare_local_id() const; }; bool operator==(const PhotoSizeSource &lhs, const PhotoSizeSource &rhs); diff --git a/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.hpp b/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.hpp index 51563d1912..02526c3db7 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/PhotoSizeSource.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,6 +7,7 @@ #pragma once #include "td/telegram/PhotoSizeSource.h" +#include "td/telegram/Version.h" #include "td/utils/SliceBuilder.h" #include "td/utils/tl_helpers.h" @@ -186,6 +187,17 @@ void PhotoSizeSource::store(StorerT &storer) const { template void PhotoSizeSource::parse(ParserT &parser) { td::parse(variant_, parser); + if (parser.get_error() == nullptr && parser.version() >= static_cast(Version::RemovePhotoVolumeAndLocalId)) { + switch (get_type("PhotoSizeSource::parse")) { + case Type::Legacy: + case Type::StickerSetThumbnail: + parser.set_error("Invalid photo size source stored"); + break; + default: + // ok + break; + } + } } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PollManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/PollManager.cpp index c1cece5bda..b04597f0f3 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PollManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/PollManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,21 +9,24 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/AuthManager.h" #include "td/telegram/ChainId.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/Dependencies.h" #include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Global.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/MessageId.h" +#include "td/telegram/MessageSender.h" #include "td/telegram/MessagesManager.h" -#include "td/telegram/misc.h" +#include "td/telegram/OnlineManager.h" #include "td/telegram/PollId.hpp" #include "td/telegram/PollManager.hpp" #include "td/telegram/StateManager.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" -#include "td/telegram/telegram_api.hpp" +#include "td/telegram/telegram_api.h" #include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" #include "td/db/binlog/BinlogEvent.h" #include "td/db/binlog/BinlogHelper.h" @@ -56,11 +59,11 @@ class GetPollResultsQuery final : public Td::ResultHandler { explicit GetPollResultsQuery(Promise> &&promise) : promise_(std::move(promise)) { } - void send(PollId poll_id, FullMessageId full_message_id) { + void send(PollId poll_id, MessageFullId message_full_id) { poll_id_ = poll_id; - dialog_id_ = full_message_id.get_dialog_id(); - message_id_ = full_message_id.get_message_id(); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + dialog_id_ = message_full_id.get_dialog_id(); + message_id_ = message_full_id.get_message_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { LOG(INFO) << "Can't reget poll, because have no read access to " << dialog_id_; return promise_.set_value(nullptr); @@ -81,13 +84,7 @@ class GetPollResultsQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (status.message() == "MESSAGE_ID_INVALID") { - // likely, the message has already been deleted - if (dialog_id_.get_type() == DialogType::Channel) { - td_->messages_manager_->get_message_from_server({dialog_id_, message_id_}, Promise(), - "GetPollResultsQuery"); - } - } else if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetPollResultsQuery")) { + if (!td_->messages_manager_->on_get_message_error(dialog_id_, message_id_, status, "GetPollResultsQuery")) { LOG(ERROR) << "Receive " << status << ", while trying to get results of " << poll_id_; } promise_.set_error(std::move(status)); @@ -104,10 +101,10 @@ class GetPollVotersQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(PollId poll_id, FullMessageId full_message_id, BufferSlice &&option, const string &offset, int32 limit) { + void send(PollId poll_id, MessageFullId message_full_id, BufferSlice &&option, const string &offset, int32 limit) { poll_id_ = poll_id; - dialog_id_ = full_message_id.get_dialog_id(); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + dialog_id_ = message_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { LOG(INFO) << "Can't get poll, because have no read access to " << dialog_id_; return promise_.set_error(Status::Error(400, "Chat is not accessible")); @@ -119,7 +116,7 @@ class GetPollVotersQuery final : public Td::ResultHandler { flags |= telegram_api::messages_getPollVotes::OFFSET_MASK; } - auto message_id = full_message_id.get_message_id().get_server_message_id().get(); + auto message_id = message_full_id.get_message_id().get_server_message_id().get(); send_query(G()->net_query_creator().create(telegram_api::messages_getPollVotes( flags, std::move(input_peer), message_id, std::move(option), offset, limit))); } @@ -134,7 +131,7 @@ class GetPollVotersQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "GetPollVotersQuery") && + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetPollVotersQuery") && status.message() != "MESSAGE_ID_INVALID") { LOG(ERROR) << "Receive " << status << ", while trying to get voters of " << poll_id_; } @@ -150,16 +147,16 @@ class SendVoteQuery final : public Td::ResultHandler { explicit SendVoteQuery(Promise> &&promise) : promise_(std::move(promise)) { } - void send(FullMessageId full_message_id, vector &&options, PollId poll_id, uint64 generation, + void send(MessageFullId message_full_id, vector &&options, PollId poll_id, uint64 generation, NetQueryRef *query_ref) { - dialog_id_ = full_message_id.get_dialog_id(); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + dialog_id_ = message_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { LOG(INFO) << "Can't set poll answer, because have no read access to " << dialog_id_; return on_error(Status::Error(400, "Can't access the chat")); } - auto message_id = full_message_id.get_message_id().get_server_message_id().get(); + auto message_id = message_full_id.get_message_id().get_server_message_id().get(); auto query = G()->net_query_creator().create( telegram_api::messages_sendVote(std::move(input_peer), message_id, std::move(options)), {{poll_id}, {dialog_id_}}); @@ -179,7 +176,7 @@ class SendVoteQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendVoteQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendVoteQuery"); promise_.set_error(std::move(status)); } }; @@ -192,29 +189,30 @@ class StopPollQuery final : public Td::ResultHandler { explicit StopPollQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(FullMessageId full_message_id, unique_ptr &&reply_markup, PollId poll_id) { - dialog_id_ = full_message_id.get_dialog_id(); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Edit); + void send(MessageFullId message_full_id, unique_ptr &&reply_markup, PollId poll_id) { + dialog_id_ = message_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Edit); if (input_peer == nullptr) { LOG(INFO) << "Can't close poll, because have no edit access to " << dialog_id_; return on_error(Status::Error(400, "Can't access the chat")); } int32 flags = telegram_api::messages_editMessage::MEDIA_MASK; - auto input_reply_markup = get_input_reply_markup(td_->contacts_manager_.get(), reply_markup); + auto input_reply_markup = get_input_reply_markup(td_->user_manager_.get(), reply_markup); if (input_reply_markup != nullptr) { flags |= telegram_api::messages_editMessage::REPLY_MARKUP_MASK; } - auto message_id = full_message_id.get_message_id().get_server_message_id().get(); - auto poll = telegram_api::make_object(); - poll->flags_ |= telegram_api::poll::CLOSED_MASK; + auto message_id = message_full_id.get_message_id().get_server_message_id().get(); + auto poll = telegram_api::make_object( + poll_id.get(), telegram_api::poll::CLOSED_MASK, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, telegram_api::make_object(string(), Auto()), Auto(), 0, 0); auto input_media = telegram_api::make_object(0, std::move(poll), vector(), string(), Auto()); send_query(G()->net_query_creator().create( - telegram_api::messages_editMessage(flags, false /*ignored*/, std::move(input_peer), message_id, string(), - std::move(input_media), std::move(input_reply_markup), - vector>(), 0), + telegram_api::messages_editMessage(flags, false /*ignored*/, false /*ignored*/, std::move(input_peer), + message_id, string(), std::move(input_media), std::move(input_reply_markup), + vector>(), 0, 0), {{poll_id}, {dialog_id_}})); } @@ -233,7 +231,7 @@ class StopPollQuery final : public Td::ResultHandler { if (!td_->auth_manager_->is_bot() && status.message() == "MESSAGE_NOT_MODIFIED") { return promise_.set_value(Unit()); } - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "StopPollQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "StopPollQuery"); promise_.set_error(std::move(status)); } }; @@ -250,6 +248,10 @@ PollManager::PollManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::m } void PollManager::start_up() { + if (td_->auth_manager_->is_bot()) { + return; + } + class StateCallback final : public StateManager::Callback { public: explicit StateCallback(ActorId parent) : parent_(std::move(parent)) { @@ -273,7 +275,8 @@ void PollManager::tear_down() { PollManager::~PollManager() { Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), polls_, server_poll_messages_, - other_poll_messages_, poll_voters_, loaded_from_database_polls_); + other_poll_messages_, reply_poll_counts_, poll_voters_, + loaded_from_database_polls_); } void PollManager::on_update_poll_timeout_callback(void *poll_manager_ptr, int64 poll_id_int) { @@ -337,14 +340,14 @@ void PollManager::notify_on_poll_update(PollId poll_id) { } if (server_poll_messages_.count(poll_id) > 0) { - server_poll_messages_[poll_id].foreach([&](const FullMessageId &full_message_id) { - td_->messages_manager_->on_external_update_message_content(full_message_id); + server_poll_messages_[poll_id].foreach([&](const MessageFullId &message_full_id) { + td_->messages_manager_->on_external_update_message_content(message_full_id, "notify_on_poll_update 1"); }); } if (other_poll_messages_.count(poll_id) > 0) { - other_poll_messages_[poll_id].foreach([&](const FullMessageId &full_message_id) { - td_->messages_manager_->on_external_update_message_content(full_message_id); + other_poll_messages_[poll_id].foreach([&](const MessageFullId &message_full_id) { + td_->messages_manager_->on_external_update_message_content(message_full_id, "notify_on_poll_update 2"); }); } } @@ -380,8 +383,17 @@ void PollManager::on_load_poll_from_database(PollId poll_id, string value) { if (log_event_parse(*poll, value).is_error()) { return; } - for (auto &user_id : poll->recent_voter_user_ids_) { - td_->contacts_manager_->have_user_force(user_id); + for (const auto &recent_voter_min_channel : poll->recent_voter_min_channels_) { + LOG(INFO) << "Add min voted " << recent_voter_min_channel.first; + td_->chat_manager_->add_min_channel(recent_voter_min_channel.first, recent_voter_min_channel.second); + } + Dependencies dependencies; + for (auto dialog_id : poll->recent_voter_dialog_ids_) { + dependencies.add_message_sender_dependencies(dialog_id); + } + if (!dependencies.resolve_force(td_, "on_load_poll_from_database")) { + poll->recent_voter_dialog_ids_.clear(); + poll->recent_voter_min_channels_.clear(); } if (!poll->is_closed_ && poll->close_date_ != 0) { if (poll->close_date_ <= G()->server_time()) { @@ -418,9 +430,13 @@ PollManager::Poll *PollManager::get_poll_force(PollId poll_id) { return get_poll_editable(poll_id); } +void PollManager::remove_unallowed_entities(FormattedText &text) { + td::remove_if(text.entities, [](MessageEntity &entity) { return entity.type != MessageEntity::Type::CustomEmoji; }); +} + td_api::object_ptr PollManager::get_poll_option_object(const PollOption &poll_option) { - return td_api::make_object(poll_option.text_, poll_option.voter_count_, 0, poll_option.is_chosen_, - false); + return td_api::make_object(get_formatted_text_object(nullptr, poll_option.text_, true, -1), + poll_option.voter_count_, 0, poll_option.is_chosen_, false); } vector PollManager::get_vote_percentage(const vector &voter_counts, int32 total_voter_count) { @@ -537,18 +553,19 @@ td_api::object_ptr PollManager::get_poll_object(PollId poll_id, co vector> poll_options; auto it = pending_answers_.find(poll_id); int32 voter_count_diff = 0; - if (it == pending_answers_.end()) { + if (it == pending_answers_.end() || (it->second.is_finished_ && poll->was_saved_)) { poll_options = transform(poll->options_, get_poll_option_object); } else { - auto &chosen_options = it->second.options_; + const auto &chosen_options = it->second.options_; + LOG(INFO) << "Have pending chosen options " << chosen_options << " in " << poll_id; for (auto &poll_option : poll->options_) { auto is_being_chosen = td::contains(chosen_options, poll_option.data_); if (poll_option.is_chosen_) { voter_count_diff = -1; } poll_options.push_back(td_api::make_object( - poll_option.text_, poll_option.voter_count_ - static_cast(poll_option.is_chosen_), 0, false, - is_being_chosen)); + get_formatted_text_object(nullptr, poll_option.text_, true, -1), + poll_option.voter_count_ - static_cast(poll_option.is_chosen_), 0, false, is_being_chosen)); } } @@ -591,7 +608,7 @@ td_api::object_ptr PollManager::get_poll_object(PollId poll_id, co auto correct_option_id = is_local_poll_id(poll_id) ? -1 : poll->correct_option_id_; poll_type = td_api::make_object( correct_option_id, - get_formatted_text_object(is_local_poll_id(poll_id) ? FormattedText() : poll->explanation_, true, -1)); + get_formatted_text_object(nullptr, is_local_poll_id(poll_id) ? FormattedText() : poll->explanation_, true, -1)); } else { poll_type = td_api::make_object(poll->allow_multiple_answers_); } @@ -613,19 +630,33 @@ td_api::object_ptr PollManager::get_poll_object(PollId poll_id, co open_period = 0; close_date = 0; } - return td_api::make_object( - poll_id.get(), poll->question_, std::move(poll_options), total_voter_count, - td_->contacts_manager_->get_user_ids_object(poll->recent_voter_user_ids_, "get_poll_object"), poll->is_anonymous_, - std::move(poll_type), open_period, close_date, poll->is_closed_); + + vector> recent_voters; + for (auto dialog_id : poll->recent_voter_dialog_ids_) { + auto recent_voter = get_min_message_sender_object(td_, dialog_id, "get_poll_object"); + if (recent_voter != nullptr) { + recent_voters.push_back(std::move(recent_voter)); + } + } + return td_api::make_object(poll_id.get(), get_formatted_text_object(nullptr, poll->question_, true, -1), + std::move(poll_options), total_voter_count, std::move(recent_voters), + poll->is_anonymous_, std::move(poll_type), open_period, close_date, + poll->is_closed_); } telegram_api::object_ptr PollManager::get_input_poll_option(const PollOption &poll_option) { - return telegram_api::make_object(poll_option.text_, BufferSlice(poll_option.data_)); + return telegram_api::make_object( + get_input_text_with_entities(nullptr, poll_option.text_, "get_input_poll_option"), + BufferSlice(poll_option.data_)); } -PollId PollManager::create_poll(string &&question, vector &&options, bool is_anonymous, +PollId PollManager::create_poll(FormattedText &&question, vector &&options, bool is_anonymous, bool allow_multiple_answers, bool is_quiz, int32 correct_option_id, FormattedText &&explanation, int32 open_period, int32 close_date, bool is_closed) { + remove_unallowed_entities(question); + for (auto &option : options) { + remove_unallowed_entities(option); + } auto poll = make_unique(); poll->question_ = std::move(question); int pos = '0'; @@ -650,17 +681,17 @@ PollId PollManager::create_poll(string &&question, vector &&options, boo return poll_id; } -void PollManager::register_poll(PollId poll_id, FullMessageId full_message_id, const char *source) { +void PollManager::register_poll(PollId poll_id, MessageFullId message_full_id, const char *source) { CHECK(have_poll(poll_id)); - if (full_message_id.get_message_id().is_scheduled() || !full_message_id.get_message_id().is_server()) { - other_poll_messages_[poll_id].insert(full_message_id); + if (message_full_id.get_message_id().is_scheduled() || !message_full_id.get_message_id().is_server()) { + other_poll_messages_[poll_id].insert(message_full_id); if (!G()->close_flag()) { unload_poll_timeout_.cancel_timeout(poll_id.get()); } return; } - LOG(INFO) << "Register " << poll_id << " from " << full_message_id << " from " << source; - server_poll_messages_[poll_id].insert(full_message_id); + LOG(INFO) << "Register " << poll_id << " from " << message_full_id << " from " << source; + server_poll_messages_[poll_id].insert(message_full_id); auto poll = get_poll(poll_id); CHECK(poll != nullptr); if (!td_->auth_manager_->is_bot() && !is_local_poll_id(poll_id) && @@ -672,12 +703,12 @@ void PollManager::register_poll(PollId poll_id, FullMessageId full_message_id, c } } -void PollManager::unregister_poll(PollId poll_id, FullMessageId full_message_id, const char *source) { +void PollManager::unregister_poll(PollId poll_id, MessageFullId message_full_id, const char *source) { CHECK(have_poll(poll_id)); - if (full_message_id.get_message_id().is_scheduled() || !full_message_id.get_message_id().is_server()) { + if (message_full_id.get_message_id().is_scheduled() || !message_full_id.get_message_id().is_server()) { auto &message_ids = other_poll_messages_[poll_id]; - auto is_deleted = message_ids.erase(full_message_id) > 0; - LOG_CHECK(is_deleted) << source << ' ' << poll_id << ' ' << full_message_id; + auto is_deleted = message_ids.erase(message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << poll_id << ' ' << message_full_id; if (is_local_poll_id(poll_id)) { CHECK(message_ids.empty()); forget_local_poll(poll_id); @@ -689,10 +720,10 @@ void PollManager::unregister_poll(PollId poll_id, FullMessageId full_message_id, } return; } - LOG(INFO) << "Unregister " << poll_id << " from " << full_message_id << " from " << source; + LOG(INFO) << "Unregister " << poll_id << " from " << message_full_id << " from " << source; auto &message_ids = server_poll_messages_[poll_id]; - auto is_deleted = message_ids.erase(full_message_id) > 0; - LOG_CHECK(is_deleted) << source << ' ' << poll_id << ' ' << full_message_id; + auto is_deleted = message_ids.erase(message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << poll_id << ' ' << message_full_id; if (is_local_poll_id(poll_id)) { CHECK(message_ids.empty()); forget_local_poll(poll_id); @@ -707,13 +738,36 @@ void PollManager::unregister_poll(PollId poll_id, FullMessageId full_message_id, } } +void PollManager::register_reply_poll(PollId poll_id) { + CHECK(have_poll(poll_id)); + CHECK(!is_local_poll_id(poll_id)); + LOG(INFO) << "Register replied " << poll_id; + reply_poll_counts_[poll_id]++; + if (!G()->close_flag()) { + unload_poll_timeout_.cancel_timeout(poll_id.get()); + } +} + +void PollManager::unregister_reply_poll(PollId poll_id) { + CHECK(have_poll(poll_id)); + CHECK(!is_local_poll_id(poll_id)); + LOG(INFO) << "Unregister replied " << poll_id; + auto &count = reply_poll_counts_[poll_id]; + CHECK(count > 0); + count--; + if (count == 0) { + reply_poll_counts_.erase(poll_id); + schedule_poll_unload(poll_id); + } +} + bool PollManager::can_unload_poll(PollId poll_id) { if (G()->close_flag()) { return false; } if (is_local_poll_id(poll_id) || server_poll_messages_.count(poll_id) != 0 || - other_poll_messages_.count(poll_id) != 0 || pending_answers_.count(poll_id) != 0 || - being_closed_polls_.count(poll_id) != 0) { + other_poll_messages_.count(poll_id) != 0 || reply_poll_counts_.count(poll_id) != 0 || + pending_answers_.count(poll_id) != 0 || being_closed_polls_.count(poll_id) != 0) { return false; } @@ -751,15 +805,15 @@ string PollManager::get_poll_search_text(PollId poll_id) const { auto poll = get_poll(poll_id); CHECK(poll != nullptr); - string result = poll->question_; + string result = poll->question_.text; for (auto &option : poll->options_) { result += ' '; - result += option.text_; + result += option.text_.text; } return result; } -void PollManager::set_poll_answer(PollId poll_id, FullMessageId full_message_id, vector &&option_ids, +void PollManager::set_poll_answer(PollId poll_id, MessageFullId message_full_id, vector &&option_ids, Promise &&promise) { td::unique(option_ids); @@ -807,35 +861,35 @@ void PollManager::set_poll_answer(PollId poll_id, FullMessageId full_message_id, } } - do_set_poll_answer(poll_id, full_message_id, std::move(options), 0, std::move(promise)); + do_set_poll_answer(poll_id, message_full_id, std::move(options), 0, std::move(promise)); } class PollManager::SetPollAnswerLogEvent { public: PollId poll_id_; - FullMessageId full_message_id_; + MessageFullId message_full_id_; vector options_; template void store(StorerT &storer) const { td::store(poll_id_, storer); - td::store(full_message_id_, storer); + td::store(message_full_id_, storer); td::store(options_, storer); } template void parse(ParserT &parser) { td::parse(poll_id_, parser); - td::parse(full_message_id_, parser); + td::parse(message_full_id_, parser); td::parse(options_, parser); } }; -void PollManager::do_set_poll_answer(PollId poll_id, FullMessageId full_message_id, vector &&options, +void PollManager::do_set_poll_answer(PollId poll_id, MessageFullId message_full_id, vector &&options, uint64 log_event_id, Promise &&promise) { - LOG(INFO) << "Set answer in " << poll_id << " from " << full_message_id; - if (!poll_id.is_valid() || !full_message_id.get_dialog_id().is_valid() || - !full_message_id.get_message_id().is_valid()) { + LOG(INFO) << "Set answer in " << poll_id << " from " << message_full_id; + if (!poll_id.is_valid() || !message_full_id.get_dialog_id().is_valid() || + !message_full_id.get_message_id().is_valid()) { CHECK(log_event_id != 0); LOG(ERROR) << "Invalid SetPollAnswer log event"; binlog_erase(G()->td_db()->get_binlog(), log_event_id); @@ -859,18 +913,19 @@ void PollManager::do_set_poll_answer(PollId poll_id, FullMessageId full_message_ if (log_event_id == 0 && G()->use_message_database()) { SetPollAnswerLogEvent log_event; log_event.poll_id_ = poll_id; - log_event.full_message_id_ = full_message_id; + log_event.message_full_id_ = message_full_id; log_event.options_ = options; auto storer = get_log_event_storer(log_event); - if (pending_answer.generation_ == 0) { + if (pending_answer.generation_ == 0 || pending_answer.is_finished_) { CHECK(pending_answer.log_event_id_ == 0); log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SetPollAnswer, storer); LOG(INFO) << "Add set poll answer log event " << log_event_id; + CHECK(log_event_id != 0); } else { CHECK(pending_answer.log_event_id_ != 0); log_event_id = pending_answer.log_event_id_; - auto new_log_event_id = binlog_rewrite(G()->td_db()->get_binlog(), pending_answer.log_event_id_, - LogEvent::HandlerType::SetPollAnswer, storer); + auto new_log_event_id = + binlog_rewrite(G()->td_db()->get_binlog(), log_event_id, LogEvent::HandlerType::SetPollAnswer, storer); LOG(INFO) << "Rewrite set poll answer log event " << log_event_id << " with " << new_log_event_id; } } @@ -898,15 +953,16 @@ void PollManager::do_set_poll_answer(PollId poll_id, FullMessageId full_message_ pending_answer.promises_.push_back(std::move(promise)); pending_answer.generation_ = generation; pending_answer.log_event_id_ = log_event_id; + pending_answer.is_finished_ = false; notify_on_poll_update(poll_id); auto query_promise = PromiseCreator::lambda( - [poll_id, generation, actor_id = actor_id(this)](Result> &&result) { + [actor_id = actor_id(this), poll_id, generation](Result> &&result) { send_closure(actor_id, &PollManager::on_set_poll_answer, poll_id, generation, std::move(result)); }); td_->create_handler(std::move(query_promise)) - ->send(full_message_id, std::move(sent_options), poll_id, generation, &pending_answer.query_ref_); + ->send(message_full_id, std::move(sent_options), poll_id, generation, &pending_answer.query_ref_); } void PollManager::on_set_poll_answer(PollId poll_id, uint64 generation, @@ -930,10 +986,10 @@ void PollManager::on_set_poll_answer(PollId poll_id, uint64 generation, if (pending_answer.log_event_id_ != 0) { LOG(INFO) << "Delete set poll answer log event " << pending_answer.log_event_id_; binlog_erase(G()->td_db()->get_binlog(), pending_answer.log_event_id_); + pending_answer.log_event_id_ = 0; } - auto promises = std::move(pending_answer.promises_); - pending_answers_.erase(it); + pending_answer.is_finished_ = true; auto poll = get_poll(poll_id); if (poll != nullptr) { @@ -941,20 +997,35 @@ void PollManager::on_set_poll_answer(PollId poll_id, uint64 generation, } if (result.is_ok()) { td_->updates_manager_->on_get_updates( - result.move_as_ok(), PromiseCreator::lambda([actor_id = actor_id(this), poll_id, - promises = std::move(promises)](Result &&result) mutable { - send_closure(actor_id, &PollManager::on_set_poll_answer_finished, poll_id, Unit(), std::move(promises)); + result.move_as_ok(), + PromiseCreator::lambda([actor_id = actor_id(this), poll_id, generation](Result &&result) mutable { + send_closure(actor_id, &PollManager::on_set_poll_answer_finished, poll_id, Unit(), generation); })); } else { - on_set_poll_answer_finished(poll_id, result.move_as_error(), std::move(promises)); + on_set_poll_answer_finished(poll_id, result.move_as_error(), generation); } } -void PollManager::on_set_poll_answer_finished(PollId poll_id, Result &&result, vector> &&promises) { +void PollManager::on_set_poll_answer_finished(PollId poll_id, Result &&result, uint64 generation) { + auto it = pending_answers_.find(poll_id); + if (it == pending_answers_.end()) { + return; + } + + auto &pending_answer = it->second; + CHECK(!pending_answer.promises_.empty()); + if (pending_answer.generation_ != generation) { + return; + } + CHECK(pending_answer.is_finished_); + + auto promises = std::move(pending_answer.promises_); + pending_answers_.erase(it); + if (!G()->close_flag()) { auto poll = get_poll(poll_id); if (poll != nullptr && !poll->was_saved_) { - // no updates was sent during updates processing, so send them + // no updates were sent during updates processing, so send them // poll wasn't changed, so there is no reason to actually save it if (!(poll->is_closed_ && poll->is_updated_after_close_)) { LOG(INFO) << "Schedule updating of " << poll_id << " soon"; @@ -966,6 +1037,8 @@ void PollManager::on_set_poll_answer_finished(PollId poll_id, Result &&res } } + LOG(INFO) << "Finish to set answer for " << poll_id; + if (result.is_ok()) { set_promises(promises); } else { @@ -1014,8 +1087,21 @@ PollManager::PollOptionVoters &PollManager::get_poll_option_voters(const Poll *p return poll_voters[index]; } -void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset, - int32 limit, Promise>> &&promise) { +td_api::object_ptr PollManager::get_poll_voters_object( + int32 total_count, const vector &voter_dialog_ids) const { + auto result = td_api::make_object(); + result->total_count_ = total_count; + for (auto dialog_id : voter_dialog_ids) { + auto message_sender = get_min_message_sender_object(td_, dialog_id, "get_poll_voters_object"); + if (message_sender != nullptr) { + result->senders_.push_back(std::move(message_sender)); + } + } + return result; +} + +void PollManager::get_poll_voters(PollId poll_id, MessageFullId message_full_id, int32 option_id, int32 offset, + int32 limit, Promise> &&promise) { if (is_local_poll_id(poll_id)) { return promise.set_error(Status::Error(400, "Poll results can't be received")); } @@ -1040,26 +1126,27 @@ void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id, auto &voters = get_poll_option_voters(poll, poll_id, option_id); if (voters.pending_queries_.empty() && voters.was_invalidated_ && offset == 0) { - voters.voter_user_ids_.clear(); + voters.voter_dialog_ids_.clear(); voters.next_offset_.clear(); voters.was_invalidated_ = false; } - auto cur_offset = narrow_cast(voters.voter_user_ids_.size()); + auto cur_offset = narrow_cast(voters.voter_dialog_ids_.size()); if (offset > cur_offset) { return promise.set_error(Status::Error(400, "Too big offset specified; voters can be received only consequently")); } if (offset < cur_offset) { - vector result; + vector result; for (int32 i = offset; i != cur_offset && i - offset < limit; i++) { - result.push_back(voters.voter_user_ids_[i]); + result.push_back(voters.voter_dialog_ids_[i]); } - return promise.set_value({max(poll->options_[option_id].voter_count_, cur_offset), std::move(result)}); + return promise.set_value( + get_poll_voters_object(max(poll->options_[option_id].voter_count_, cur_offset), std::move(result))); } if (poll->options_[option_id].voter_count_ == 0 || (voters.next_offset_.empty() && cur_offset > 0)) { - return promise.set_value({0, vector()}); + return promise.set_value(get_poll_voters_object(0, vector())); } voters.pending_queries_.push_back(std::move(promise)); @@ -1076,7 +1163,7 @@ void PollManager::get_poll_voters(PollId poll_id, FullMessageId full_message_id, std::move(result)); }); td_->create_handler(std::move(query_promise)) - ->send(poll_id, full_message_id, BufferSlice(poll->options_[option_id].data_), voters.next_offset_, + ->send(poll_id, message_full_id, BufferSlice(poll->options_[option_id].data_), voters.next_offset_, max(limit, 10)); } @@ -1113,7 +1200,8 @@ void PollManager::on_get_poll_voters(PollId poll_id, int32 option_id, string off } auto vote_list = result.move_as_ok(); - td_->contacts_manager_->on_get_users(std::move(vote_list->users_), "on_get_poll_voters"); + td_->user_manager_->on_get_users(std::move(vote_list->users_), "on_get_poll_voters"); + td_->chat_manager_->on_get_chats(std::move(vote_list->chats_), "on_get_poll_voters"); voters.next_offset_ = std::move(vote_list->next_offset_); if (poll->options_[option_id].voter_count_ != vote_list->count_) { @@ -1121,61 +1209,61 @@ void PollManager::on_get_poll_voters(PollId poll_id, int32 option_id, string off update_poll_timeout_.set_timeout_in(poll_id.get(), 0.0); } - vector user_ids; - for (auto &user_vote : vote_list->votes_) { - UserId user_id; - switch (user_vote->get_id()) { - case telegram_api::messageUserVote::ID: { - auto voter = telegram_api::move_object_as(user_vote); + vector dialog_ids; + for (auto &peer_vote : vote_list->votes_) { + DialogId dialog_id; + switch (peer_vote->get_id()) { + case telegram_api::messagePeerVote::ID: { + auto voter = telegram_api::move_object_as(peer_vote); if (voter->option_ != poll->options_[option_id].data_) { continue; } - user_id = UserId(voter->user_id_); + dialog_id = DialogId(voter->peer_); break; } - case telegram_api::messageUserVoteInputOption::ID: { - auto voter = telegram_api::move_object_as(user_vote); - user_id = UserId(voter->user_id_); + case telegram_api::messagePeerVoteInputOption::ID: { + auto voter = telegram_api::move_object_as(peer_vote); + dialog_id = DialogId(voter->peer_); break; } - case telegram_api::messageUserVoteMultiple::ID: { - auto voter = telegram_api::move_object_as(user_vote); + case telegram_api::messagePeerVoteMultiple::ID: { + auto voter = telegram_api::move_object_as(peer_vote); if (!td::contains(voter->options_, poll->options_[option_id].data_)) { continue; } - user_id = UserId(voter->user_id_); + dialog_id = DialogId(voter->peer_); break; } default: UNREACHABLE(); } - if (user_id.is_valid()) { - user_ids.push_back(user_id); + if (dialog_id.is_valid()) { + dialog_ids.push_back(dialog_id); } else { - LOG(ERROR) << "Receive " << user_id << " as voter in " << poll_id; + LOG(ERROR) << "Receive " << dialog_id << " as voter in " << poll_id; } } - voters.voter_user_ids_.insert(voters.voter_user_ids_.end(), user_ids.begin(), user_ids.end()); - if (static_cast(user_ids.size()) > limit) { - user_ids.resize(limit); + append(voters.voter_dialog_ids_, dialog_ids); + if (static_cast(dialog_ids.size()) > limit) { + dialog_ids.resize(limit); } - auto known_voter_count = narrow_cast(voters.voter_user_ids_.size()); + auto known_voter_count = narrow_cast(voters.voter_dialog_ids_.size()); if (voters.next_offset_.empty() && known_voter_count != vote_list->count_) { // invalidate_poll_option_voters(poll, poll_id, option_id); voters.was_invalidated_ = true; } for (auto &promise : promises) { - promise.set_value({max(vote_list->count_, known_voter_count), vector(user_ids)}); + promise.set_value(get_poll_voters_object(max(vote_list->count_, known_voter_count), vector(dialog_ids))); } } -void PollManager::stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr &&reply_markup, +void PollManager::stop_poll(PollId poll_id, MessageFullId message_full_id, unique_ptr &&reply_markup, Promise &&promise) { if (is_local_poll_id(poll_id)) { - LOG(ERROR) << "Receive local " << poll_id << " from " << full_message_id << " in stop_poll"; + LOG(ERROR) << "Receive local " << poll_id << " from " << message_full_id << " in stop_poll"; stop_local_poll(poll_id); promise.set_value(Unit()); return; @@ -1190,37 +1278,37 @@ void PollManager::stop_poll(PollId poll_id, FullMessageId full_message_id, uniqu ++current_generation_; poll->is_closed_ = true; - notify_on_poll_update(poll_id); save_poll(poll, poll_id); + notify_on_poll_update(poll_id); - do_stop_poll(poll_id, full_message_id, std::move(reply_markup), 0, std::move(promise)); + do_stop_poll(poll_id, message_full_id, std::move(reply_markup), 0, std::move(promise)); } class PollManager::StopPollLogEvent { public: PollId poll_id_; - FullMessageId full_message_id_; + MessageFullId message_full_id_; template void store(StorerT &storer) const { td::store(poll_id_, storer); - td::store(full_message_id_, storer); + td::store(message_full_id_, storer); } template void parse(ParserT &parser) { td::parse(poll_id_, parser); - td::parse(full_message_id_, parser); + td::parse(message_full_id_, parser); } }; -void PollManager::do_stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr &&reply_markup, +void PollManager::do_stop_poll(PollId poll_id, MessageFullId message_full_id, unique_ptr &&reply_markup, uint64 log_event_id, Promise &&promise) { - LOG(INFO) << "Stop " << poll_id << " from " << full_message_id; + LOG(INFO) << "Stop " << poll_id << " from " << message_full_id; CHECK(poll_id.is_valid()); if (log_event_id == 0 && G()->use_message_database() && reply_markup == nullptr) { - StopPollLogEvent log_event{poll_id, full_message_id}; + StopPollLogEvent log_event{poll_id, message_full_id}; log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::StopPoll, get_log_event_storer(log_event)); } @@ -1229,16 +1317,16 @@ void PollManager::do_stop_poll(PollId poll_id, FullMessageId full_message_id, un bool is_inserted = being_closed_polls_.insert(poll_id).second; CHECK(is_inserted); - auto new_promise = PromiseCreator::lambda([actor_id = actor_id(this), poll_id, full_message_id, log_event_id, + auto new_promise = PromiseCreator::lambda([actor_id = actor_id(this), poll_id, message_full_id, log_event_id, promise = std::move(promise)](Result result) mutable { - send_closure(actor_id, &PollManager::on_stop_poll_finished, poll_id, full_message_id, log_event_id, + send_closure(actor_id, &PollManager::on_stop_poll_finished, poll_id, message_full_id, log_event_id, std::move(result), std::move(promise)); }); - td_->create_handler(std::move(new_promise))->send(full_message_id, std::move(reply_markup), poll_id); + td_->create_handler(std::move(new_promise))->send(message_full_id, std::move(reply_markup), poll_id); } -void PollManager::on_stop_poll_finished(PollId poll_id, FullMessageId full_message_id, uint64 log_event_id, +void PollManager::on_stop_poll_finished(PollId poll_id, MessageFullId message_full_id, uint64 log_event_id, Result &&result, Promise &&promise) { being_closed_polls_.erase(poll_id); @@ -1247,9 +1335,9 @@ void PollManager::on_stop_poll_finished(PollId poll_id, FullMessageId full_messa } if (td_->auth_manager_->is_bot()) { - if ((server_poll_messages_.count(poll_id) > 0 && server_poll_messages_[poll_id].count(full_message_id) > 0) || - (other_poll_messages_.count(poll_id) > 0 && other_poll_messages_[poll_id].count(full_message_id) > 0)) { - td_->messages_manager_->on_external_update_message_content(full_message_id); + if ((server_poll_messages_.count(poll_id) > 0 && server_poll_messages_[poll_id].count(message_full_id) > 0) || + (other_poll_messages_.count(poll_id) > 0 && other_poll_messages_[poll_id].count(message_full_id) > 0)) { + td_->messages_manager_->on_external_update_message_content(message_full_id, "on_stop_poll_finished"); } } @@ -1269,7 +1357,7 @@ void PollManager::stop_local_poll(PollId poll_id) { } double PollManager::get_polling_timeout() const { - double result = td_->is_online() ? 60 : 30 * 60; + double result = td_->online_manager_->is_online() ? 60 : 30 * 60; return result * Random::fast(70, 100) * 0.01; } @@ -1293,13 +1381,13 @@ void PollManager::on_update_poll_timeout(PollId poll_id) { return; } - auto full_message_id = server_poll_messages_[poll_id].get_random(); - LOG(INFO) << "Fetching results of " << poll_id << " from " << full_message_id; - auto query_promise = PromiseCreator::lambda([poll_id, generation = current_generation_, actor_id = actor_id(this)]( + auto message_full_id = server_poll_messages_[poll_id].get_random(); + LOG(INFO) << "Fetching results of " << poll_id << " from " << message_full_id; + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), poll_id, generation = current_generation_]( Result> &&result) { send_closure(actor_id, &PollManager::on_get_poll_results, poll_id, generation, std::move(result)); }); - td_->create_handler(std::move(query_promise))->send(poll_id, full_message_id); + td_->create_handler(std::move(query_promise))->send(poll_id, message_full_id); } void PollManager::on_close_poll_timeout(PollId poll_id) { @@ -1316,8 +1404,8 @@ void PollManager::on_close_poll_timeout(PollId poll_id) { LOG(INFO) << "Trying to close " << poll_id << " by timer"; if (poll->close_date_ <= G()->server_time()) { poll->is_closed_ = true; - notify_on_poll_update(poll_id); save_poll(poll, poll_id); + notify_on_poll_update(poll_id); // don't send updatePoll for bots, because there is no way to guarantee it @@ -1407,7 +1495,7 @@ void PollManager::on_online() { return; } - server_poll_messages_.foreach([&](const PollId &poll_id, WaitFreeHashSet &) { + server_poll_messages_.foreach([&](const PollId &poll_id, WaitFreeHashSet &) { if (update_poll_timeout_.has_timeout(poll_id.get())) { auto timeout = Random::fast(3, 30); LOG(INFO) << "Schedule updating of " << poll_id << " in " << timeout; @@ -1416,13 +1504,18 @@ void PollManager::on_online() { }); } -PollId PollManager::dup_poll(PollId poll_id) { +PollId PollManager::dup_poll(DialogId dialog_id, PollId poll_id) { auto poll = get_poll(poll_id); CHECK(poll != nullptr); auto question = poll->question_; + ::td::remove_unallowed_entities(td_, question, dialog_id); auto options = transform(poll->options_, [](auto &option) { return option.text_; }); + for (auto &option : options) { + ::td::remove_unallowed_entities(td_, option, dialog_id); + } auto explanation = poll->explanation_; + ::td::remove_unallowed_entities(td_, explanation, dialog_id); return create_poll(std::move(question), std::move(options), poll->is_anonymous_, poll->allow_multiple_answers_, poll->is_quiz_, poll->correct_option_id_, std::move(explanation), poll->open_period_, poll->open_period_ == 0 ? 0 : G()->unix_time(), false); @@ -1473,17 +1566,19 @@ tl_object_ptr PollManager::get_input_media(PollId poll return telegram_api::make_object( flags, telegram_api::make_object( - 0, poll_flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, poll->question_, + 0, poll_flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + get_input_text_with_entities(nullptr, poll->question_, "get_input_media_poll"), transform(poll->options_, get_input_poll_option), poll->open_period_, poll->close_date_), std::move(correct_answers), poll->explanation_.text, - get_input_message_entities(td_->contacts_manager_.get(), poll->explanation_.entities, "get_input_media_poll")); + get_input_message_entities(td_->user_manager_.get(), poll->explanation_.entities, "get_input_media_poll")); } vector PollManager::get_poll_options( - vector> &&poll_options) { - return transform(std::move(poll_options), [](tl_object_ptr &&poll_option) { + vector> &&poll_options) { + return transform(std::move(poll_options), [](telegram_api::object_ptr &&poll_option) { PollOption option; - option.text_ = std::move(poll_option->text_); + option.text_ = get_formatted_text(nullptr, std::move(poll_option->text_), true, true, "get_poll_options"); + remove_unallowed_entities(option.text_); option.data_ = poll_option->option_.as_slice().str(); return option; }); @@ -1541,7 +1636,11 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr(); poll = p.get(); polls_.set(poll_id, std::move(p)); + } else if (poll_results != nullptr && poll_results->min_ && pending_answers_.count(poll_id) != 0) { + LOG(INFO) << "Ignore being answered min-" << poll_id; + return poll_id; } + CHECK(poll != nullptr); bool poll_server_is_closed = false; @@ -1556,13 +1655,14 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptroptions_ = get_poll_options(std::move(poll_server->answers_)); are_options_changed = true; } else { - for (size_t i = 0; i < poll->options_.size(); i++) { - if (poll->options_[i].text_ != poll_server->answers_[i]->text_) { - poll->options_[i].text_ = std::move(poll_server->answers_[i]->text_); + auto options = get_poll_options(std::move(poll_server->answers_)); + for (size_t i = 0; i < options.size(); i++) { + if (poll->options_[i].text_ != options[i].text_) { + poll->options_[i].text_ = std::move(options[i].text_); is_changed = true; } - if (poll->options_[i].data_ != poll_server->answers_[i]->option_.as_slice()) { - poll->options_[i].data_ = poll_server->answers_[i]->option_.as_slice().str(); + if (poll->options_[i].data_ != options[i].data_) { + poll->options_[i].data_ = std::move(options[i].data_); poll->options_[i].voter_count_ = 0; poll->options_[i].is_chosen_ = false; are_options_changed = true; @@ -1588,8 +1688,10 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptrquestion_ != poll_server->question_) { - poll->question_ = std::move(poll_server->question_); + auto question = get_formatted_text(nullptr, std::move(poll_server->question_), true, true, "on_get_poll"); + remove_unallowed_entities(question); + if (poll->question_ != question) { + poll->question_ = std::move(question); is_changed = true; } poll_server_is_closed = (poll_server->flags_ & telegram_api::poll::CLOSED_MASK) != 0; @@ -1698,7 +1800,8 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptrvoters_ = 0; } if (option.is_chosen_ && poll_result->voters_ == 0) { - LOG(ERROR) << "Receive 0 voters for the chosen option in " << poll_id << " from " << source; + LOG(ERROR) << "Receive 0 voters for the chosen option " << option_index << " in " << poll_id << " from " + << source; poll_result->voters_ = 1; } if (poll_result->voters_ > poll->total_voter_count_) { @@ -1731,17 +1834,8 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptrcontacts_manager_.get(), std::move(poll_results->solution_entities_), source); - auto status = fix_formatted_text(poll_results->solution_, entities, true, true, true, true, false); - if (status.is_error()) { - if (!clean_input_string(poll_results->solution_)) { - poll_results->solution_.clear(); - } - entities = find_entities(poll_results->solution_, true, true); - } - FormattedText explanation{std::move(poll_results->solution_), std::move(entities)}; - + auto explanation = get_formatted_text(td_->user_manager_.get(), std::move(poll_results->solution_), + std::move(poll_results->solution_entities_), true, false, source); if (poll->is_quiz_) { if (poll->correct_option_id_ != correct_option_id) { if (correct_option_id == -1 && poll->correct_option_id_ != -1) { @@ -1769,24 +1863,24 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr recent_voter_user_ids; + vector recent_voter_dialog_ids; if (!is_bot) { - for (auto &user_id_int : poll_results->recent_voters_) { - UserId user_id(user_id_int); - if (user_id.is_valid()) { - recent_voter_user_ids.push_back(user_id); + for (auto &peer_id : poll_results->recent_voters_) { + DialogId dialog_id(peer_id); + if (dialog_id.is_valid()) { + recent_voter_dialog_ids.push_back(dialog_id); } else { - LOG(ERROR) << "Receive " << user_id << " as recent voter in " << poll_id << " from " << source; + LOG(ERROR) << "Receive " << dialog_id << " as recent voter in " << poll_id << " from " << source; } } } - if (poll->is_anonymous_ && !recent_voter_user_ids.empty()) { - LOG(ERROR) << "Receive anonymous " << poll_id << " with recent voters " << recent_voter_user_ids << " from " + if (poll->is_anonymous_ && !recent_voter_dialog_ids.empty()) { + LOG(ERROR) << "Receive anonymous " << poll_id << " with recent voters " << recent_voter_dialog_ids << " from " << source; - recent_voter_user_ids.clear(); + recent_voter_dialog_ids.clear(); } - if (recent_voter_user_ids != poll->recent_voter_user_ids_) { - poll->recent_voter_user_ids_ = std::move(recent_voter_user_ids); + if (recent_voter_dialog_ids != poll->recent_voter_dialog_ids_) { + poll->recent_voter_dialog_ids_ = std::move(recent_voter_dialog_ids); invalidate_poll_voters(poll, poll_id); is_changed = true; } @@ -1796,12 +1890,12 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptris_closed_ && being_closed_polls_.erase(poll_id) != 0))) { send_closure(G()->td(), &Td::send_update, td_api::make_object(get_poll_object(poll_id, poll))); @@ -1810,18 +1904,16 @@ PollId PollManager::on_get_poll(PollId poll_id, tl_object_ptr &&options) { +void PollManager::on_get_poll_vote(PollId poll_id, DialogId dialog_id, vector &&options) { if (!poll_id.is_valid()) { LOG(ERROR) << "Receive updateMessagePollVote about invalid " << poll_id; return; } - if (!user_id.is_valid()) { - LOG(ERROR) << "Receive updateMessagePollVote from invalid " << user_id; - return; - } - if (!td_->auth_manager_->is_bot()) { + if (!dialog_id.is_valid()) { + LOG(ERROR) << "Receive updateMessagePollVote from invalid " << dialog_id; return; } + CHECK(td_->auth_manager_->is_bot()); vector option_ids; for (auto &option : options) { @@ -1833,10 +1925,10 @@ void PollManager::on_get_poll_vote(PollId poll_id, UserId user_id, vector(slice[0] - '0')); } - send_closure(G()->td(), &Td::send_update, - td_api::make_object( - poll_id.get(), td_->contacts_manager_->get_user_id_object(user_id, "on_get_poll_vote"), - std::move(option_ids))); + send_closure( + G()->td(), &Td::send_update, + td_api::make_object( + poll_id.get(), get_message_sender_object(td_, dialog_id, "on_get_poll_vote"), std::move(option_ids))); } void PollManager::on_binlog_events(vector &&events) { @@ -1855,13 +1947,13 @@ void PollManager::on_binlog_events(vector &&events) { SetPollAnswerLogEvent log_event; log_event_parse(log_event, event.get_data()).ensure(); - auto dialog_id = log_event.full_message_id_.get_dialog_id(); + auto dialog_id = log_event.message_full_id_.get_dialog_id(); Dependencies dependencies; dependencies.add_dialog_dependencies(dialog_id); // do not load the dialog itself dependencies.resolve_force(td_, "SetPollAnswerLogEvent"); - do_set_poll_answer(log_event.poll_id_, log_event.full_message_id_, std::move(log_event.options_), event.id_, + do_set_poll_answer(log_event.poll_id_, log_event.message_full_id_, std::move(log_event.options_), event.id_, Auto()); break; } @@ -1874,13 +1966,13 @@ void PollManager::on_binlog_events(vector &&events) { StopPollLogEvent log_event; log_event_parse(log_event, event.get_data()).ensure(); - auto dialog_id = log_event.full_message_id_.get_dialog_id(); + auto dialog_id = log_event.message_full_id_.get_dialog_id(); Dependencies dependencies; dependencies.add_dialog_dependencies(dialog_id); // do not load the dialog itself dependencies.resolve_force(td_, "StopPollLogEvent"); - do_stop_poll(log_event.poll_id_, log_event.full_message_id_, nullptr, event.id_, Auto()); + do_stop_poll(log_event.poll_id_, log_event.message_full_id_, nullptr, event.id_, Auto()); break; } default: diff --git a/protocols/Telegram/tdlib/td/td/telegram/PollManager.h b/protocols/Telegram/tdlib/td/td/telegram/PollManager.h index 7d6a8bc925..e7a7659b9b 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PollManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/PollManager.h @@ -1,19 +1,21 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once -#include "td/telegram/FullMessageId.h" +#include "td/telegram/ChannelId.h" +#include "td/telegram/DialogId.h" #include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/MinChannel.h" #include "td/telegram/net/NetQuery.h" #include "td/telegram/PollId.h" #include "td/telegram/ReplyMarkup.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" -#include "td/telegram/UserId.h" #include "td/actor/actor.h" #include "td/actor/MultiTimeout.h" @@ -47,13 +49,17 @@ class PollManager final : public Actor { static bool is_local_poll_id(PollId poll_id); - PollId create_poll(string &&question, vector &&options, bool is_anonymous, bool allow_multiple_answers, - bool is_quiz, int32 correct_option_id, FormattedText &&explanation, int32 open_period, - int32 close_date, bool is_closed); + PollId create_poll(FormattedText &&question, vector &&options, bool is_anonymous, + bool allow_multiple_answers, bool is_quiz, int32 correct_option_id, FormattedText &&explanation, + int32 open_period, int32 close_date, bool is_closed); - void register_poll(PollId poll_id, FullMessageId full_message_id, const char *source); + void register_poll(PollId poll_id, MessageFullId message_full_id, const char *source); - void unregister_poll(PollId poll_id, FullMessageId full_message_id, const char *source); + void unregister_poll(PollId poll_id, MessageFullId message_full_id, const char *source); + + void register_reply_poll(PollId poll_id); + + void unregister_reply_poll(PollId poll_id); bool get_poll_is_closed(PollId poll_id) const; @@ -61,18 +67,18 @@ class PollManager final : public Actor { string get_poll_search_text(PollId poll_id) const; - void set_poll_answer(PollId poll_id, FullMessageId full_message_id, vector &&option_ids, + void set_poll_answer(PollId poll_id, MessageFullId message_full_id, vector &&option_ids, Promise &&promise); - void get_poll_voters(PollId poll_id, FullMessageId full_message_id, int32 option_id, int32 offset, int32 limit, - Promise>> &&promise); + void get_poll_voters(PollId poll_id, MessageFullId message_full_id, int32 option_id, int32 offset, int32 limit, + Promise> &&promise); - void stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr &&reply_markup, + void stop_poll(PollId poll_id, MessageFullId message_full_id, unique_ptr &&reply_markup, Promise &&promise); void stop_local_poll(PollId poll_id); - PollId dup_poll(PollId poll_id); + PollId dup_poll(DialogId dialog_id, PollId poll_id); bool has_input_media(PollId poll_id) const; @@ -81,7 +87,7 @@ class PollManager final : public Actor { PollId on_get_poll(PollId poll_id, tl_object_ptr &&poll_server, tl_object_ptr &&poll_results, const char *source); - void on_get_poll_vote(PollId poll_id, UserId user_id, vector &&options); + void on_get_poll_vote(PollId poll_id, DialogId dialog_id, vector &&options); td_api::object_ptr get_poll_object(PollId poll_id) const; @@ -97,7 +103,7 @@ class PollManager final : public Actor { private: struct PollOption { - string text_; + FormattedText text_; string data_; int32 voter_count_ = 0; bool is_chosen_ = false; @@ -109,9 +115,10 @@ class PollManager final : public Actor { }; struct Poll { - string question_; + FormattedText question_; vector options_; - vector recent_voter_user_ids_; + vector recent_voter_dialog_ids_; + vector> recent_voter_min_channels_; FormattedText explanation_; int32 total_voter_count_ = 0; int32 correct_option_id_ = -1; @@ -131,9 +138,9 @@ class PollManager final : public Actor { }; struct PollOptionVoters { - vector voter_user_ids_; + vector voter_dialog_ids_; string next_offset_; - vector>>> pending_queries_; + vector>> pending_queries_; bool was_invalidated_ = false; // the list needs to be invalidated when voters are changed }; @@ -152,6 +159,8 @@ class PollManager final : public Actor { static void on_unload_poll_timeout_callback(void *poll_manager_ptr, int64 poll_id_int); + static void remove_unallowed_entities(FormattedText &text); + static td_api::object_ptr get_poll_option_object(const PollOption &poll_option); static telegram_api::object_ptr get_input_poll_option(const PollOption &poll_option); @@ -196,12 +205,12 @@ class PollManager final : public Actor { void on_get_poll_results(PollId poll_id, uint64 generation, Result> result); - void do_set_poll_answer(PollId poll_id, FullMessageId full_message_id, vector &&options, uint64 log_event_id, + void do_set_poll_answer(PollId poll_id, MessageFullId message_full_id, vector &&options, uint64 log_event_id, Promise &&promise); void on_set_poll_answer(PollId poll_id, uint64 generation, Result> &&result); - void on_set_poll_answer_finished(PollId poll_id, Result &&result, vector> &&promises); + void on_set_poll_answer_finished(PollId poll_id, Result &&result, uint64 generation); void invalidate_poll_voters(const Poll *poll, PollId poll_id); @@ -209,13 +218,16 @@ class PollManager final : public Actor { PollOptionVoters &get_poll_option_voters(const Poll *poll, PollId poll_id, int32 option_id); + td_api::object_ptr get_poll_voters_object(int32 total_count, + const vector &voter_dialog_ids) const; + void on_get_poll_voters(PollId poll_id, int32 option_id, string offset, int32 limit, Result> &&result); - void do_stop_poll(PollId poll_id, FullMessageId full_message_id, unique_ptr &&reply_markup, + void do_stop_poll(PollId poll_id, MessageFullId message_full_id, unique_ptr &&reply_markup, uint64 log_event_id, Promise &&promise); - void on_stop_poll_finished(PollId poll_id, FullMessageId full_message_id, uint64 log_event_id, Result &&result, + void on_stop_poll_finished(PollId poll_id, MessageFullId message_full_id, uint64 log_event_id, Result &&result, Promise &&promise); void forget_local_poll(PollId poll_id); @@ -224,12 +236,12 @@ class PollManager final : public Actor { MultiTimeout close_poll_timeout_{"ClosePollTimeout"}; MultiTimeout unload_poll_timeout_{"UnloadPollTimeout"}; - Td *td_; - ActorShared<> parent_; WaitFreeHashMap, PollIdHash> polls_; - WaitFreeHashMap, PollIdHash> server_poll_messages_; - WaitFreeHashMap, PollIdHash> other_poll_messages_; + WaitFreeHashMap, PollIdHash> server_poll_messages_; + WaitFreeHashMap, PollIdHash> other_poll_messages_; + + WaitFreeHashMap reply_poll_counts_; struct PendingPollAnswer { vector options_; @@ -237,6 +249,7 @@ class PollManager final : public Actor { uint64 generation_ = 0; uint64 log_event_id_ = 0; NetQueryRef query_ref_; + bool is_finished_ = false; }; FlatHashMap pending_answers_; @@ -249,6 +262,9 @@ class PollManager final : public Actor { FlatHashSet loaded_from_database_polls_; FlatHashSet being_closed_polls_; + + Td *td_; + ActorShared<> parent_; }; } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PollManager.hpp b/protocols/Telegram/tdlib/td/td/telegram/PollManager.hpp index 85cb4ae3ca..681a6a1d81 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PollManager.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/PollManager.hpp @@ -1,12 +1,15 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once +#include "td/telegram/MessageEntity.hpp" +#include "td/telegram/MinChannel.hpp" #include "td/telegram/PollManager.h" +#include "td/telegram/UserId.h" #include "td/telegram/Version.h" #include "td/utils/algorithm.h" @@ -18,56 +21,68 @@ namespace td { template void PollManager::PollOption::store(StorerT &storer) const { using ::td::store; + bool has_entities = !text_.entities.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(is_chosen_); + STORE_FLAG(has_entities); END_STORE_FLAGS(); - store(text_, storer); + store(text_.text, storer); store(data_, storer); store(voter_count_, storer); + if (has_entities) { + store(text_.entities, storer); + } } template void PollManager::PollOption::parse(ParserT &parser) { using ::td::parse; + bool has_entities; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_chosen_); + PARSE_FLAG(has_entities); END_PARSE_FLAGS(); - parse(text_, parser); + parse(text_.text, parser); parse(data_, parser); parse(voter_count_, parser); + if (has_entities) { + parse(text_.entities, parser); + } } template void PollManager::Poll::store(StorerT &storer) const { using ::td::store; bool is_public = !is_anonymous_; - bool has_recent_voters = !recent_voter_user_ids_.empty(); bool has_open_period = open_period_ != 0; bool has_close_date = close_date_ != 0; bool has_explanation = !explanation_.text.empty(); + bool has_recent_voter_dialog_ids = !recent_voter_dialog_ids_.empty(); + bool has_recent_voter_min_channels = !recent_voter_min_channels_.empty(); + bool has_question_entities = !question_.entities.empty(); BEGIN_STORE_FLAGS(); STORE_FLAG(is_closed_); STORE_FLAG(is_public); STORE_FLAG(allow_multiple_answers_); STORE_FLAG(is_quiz_); - STORE_FLAG(has_recent_voters); + STORE_FLAG(false); STORE_FLAG(has_open_period); STORE_FLAG(has_close_date); STORE_FLAG(has_explanation); STORE_FLAG(is_updated_after_close_); + STORE_FLAG(has_recent_voter_dialog_ids); + STORE_FLAG(has_recent_voter_min_channels); + STORE_FLAG(has_question_entities); END_STORE_FLAGS(); - store(question_, storer); + store(question_.text, storer); store(options_, storer); store(total_voter_count_, storer); if (is_quiz_) { store(correct_option_id_, storer); } - if (has_recent_voters) { - store(recent_voter_user_ids_, storer); - } if (has_open_period) { store(open_period_, storer); } @@ -77,40 +92,57 @@ void PollManager::Poll::store(StorerT &storer) const { if (has_explanation) { store(explanation_, storer); } + if (has_recent_voter_dialog_ids) { + store(recent_voter_dialog_ids_, storer); + } + if (has_recent_voter_min_channels) { + store(recent_voter_min_channels_, storer); + } + if (has_question_entities) { + store(question_.entities, storer); + } } template void PollManager::Poll::parse(ParserT &parser) { using ::td::parse; bool is_public; - bool has_recent_voters; + bool has_recent_voter_user_ids; bool has_open_period; bool has_close_date; bool has_explanation; + bool has_recent_voter_dialog_ids; + bool has_recent_voter_min_channels; + bool has_question_entities; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_closed_); PARSE_FLAG(is_public); PARSE_FLAG(allow_multiple_answers_); PARSE_FLAG(is_quiz_); - PARSE_FLAG(has_recent_voters); + PARSE_FLAG(has_recent_voter_user_ids); PARSE_FLAG(has_open_period); PARSE_FLAG(has_close_date); PARSE_FLAG(has_explanation); PARSE_FLAG(is_updated_after_close_); + PARSE_FLAG(has_recent_voter_dialog_ids); + PARSE_FLAG(has_recent_voter_min_channels); + PARSE_FLAG(has_question_entities); END_PARSE_FLAGS(); is_anonymous_ = !is_public; - parse(question_, parser); + parse(question_.text, parser); parse(options_, parser); parse(total_voter_count_, parser); if (is_quiz_) { parse(correct_option_id_, parser); if (correct_option_id_ < -1 || correct_option_id_ >= static_cast(options_.size())) { - parser.set_error("Wrong correct_option_id"); + parser.set_error("Wrong quiz correct_option_id"); } } - if (has_recent_voters) { - parse(recent_voter_user_ids_, parser); + if (has_recent_voter_user_ids) { + vector recent_voter_user_ids; + parse(recent_voter_user_ids, parser); + recent_voter_dialog_ids_ = transform(recent_voter_user_ids, [](UserId user_id) { return DialogId(user_id); }); } if (has_open_period) { parse(open_period_, parser); @@ -121,6 +153,15 @@ void PollManager::Poll::parse(ParserT &parser) { if (has_explanation) { parse(explanation_, parser); } + if (has_recent_voter_dialog_ids) { + parse(recent_voter_dialog_ids_, parser); + } + if (has_recent_voter_min_channels) { + parse(recent_voter_min_channels_, parser); + } + if (has_question_entities) { + parse(question_.entities, parser); + } } template @@ -132,6 +173,9 @@ void PollManager::store_poll(PollId poll_id, StorerT &storer) const { bool has_open_period = poll->open_period_ != 0; bool has_close_date = poll->close_date_ != 0; bool has_explanation = !poll->explanation_.text.empty(); + bool has_question_entities = !poll->question_.entities.empty(); + bool has_option_entities = + any_of(poll->options_, [](const auto &option) { return !option.text_.entities.empty(); }); BEGIN_STORE_FLAGS(); STORE_FLAG(poll->is_closed_); STORE_FLAG(poll->is_anonymous_); @@ -140,9 +184,11 @@ void PollManager::store_poll(PollId poll_id, StorerT &storer) const { STORE_FLAG(has_open_period); STORE_FLAG(has_close_date); STORE_FLAG(has_explanation); + STORE_FLAG(has_question_entities); + STORE_FLAG(has_option_entities); END_STORE_FLAGS(); - store(poll->question_, storer); - vector options = transform(poll->options_, [](const PollOption &option) { return option.text_; }); + store(poll->question_.text, storer); + vector options = transform(poll->options_, [](const PollOption &option) { return option.text_.text; }); store(options, storer); if (poll->is_quiz_) { store(poll->correct_option_id_, storer); @@ -156,6 +202,13 @@ void PollManager::store_poll(PollId poll_id, StorerT &storer) const { if (has_explanation) { store(poll->explanation_, storer); } + if (has_question_entities) { + store(poll->question_.entities, storer); + } + if (has_option_entities) { + auto option_entities = transform(poll->options_, [](const PollOption &option) { return option.text_.entities; }); + store(option_entities, storer); + } } } @@ -165,8 +218,7 @@ PollId PollManager::parse_poll(ParserT &parser) { td::parse(poll_id_int, parser); PollId poll_id(poll_id_int); if (is_local_poll_id(poll_id)) { - string question; - vector options; + FormattedText question; FormattedText explanation; int32 open_period = 0; int32 close_date = 0; @@ -177,6 +229,8 @@ PollId PollManager::parse_poll(ParserT &parser) { bool has_open_period = false; bool has_close_date = false; bool has_explanation = false; + bool has_question_entities = false; + bool has_option_entities = false; int32 correct_option_id = -1; if (parser.version() >= static_cast(Version::SupportPolls2_0)) { @@ -188,14 +242,17 @@ PollId PollManager::parse_poll(ParserT &parser) { PARSE_FLAG(has_open_period); PARSE_FLAG(has_close_date); PARSE_FLAG(has_explanation); + PARSE_FLAG(has_question_entities); + PARSE_FLAG(has_option_entities); END_PARSE_FLAGS(); } - parse(question, parser); - parse(options, parser); + parse(question.text, parser); + vector option_texts; + parse(option_texts, parser); if (is_quiz) { parse(correct_option_id, parser); - if (correct_option_id < -1 || correct_option_id >= static_cast(options.size())) { - parser.set_error("Wrong correct_option_id"); + if (correct_option_id < -1 || correct_option_id >= static_cast(option_texts.size())) { + parser.set_error("Wrong local quiz correct_option_id"); } } if (has_open_period) { @@ -207,6 +264,21 @@ PollId PollManager::parse_poll(ParserT &parser) { if (has_explanation) { parse(explanation, parser); } + if (has_question_entities) { + parse(question.entities, parser); + } + vector> option_entities; + if (has_option_entities) { + parse(option_entities, parser); + CHECK(option_entities.size() == option_texts.size()); + } else { + option_entities.resize(option_texts.size()); + } + vector options; + for (size_t i = 0; i < option_texts.size(); i++) { + options.push_back({std::move(option_texts[i]), std::move(option_entities[i])}); + } + if (parser.get_error() != nullptr) { return PollId(); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/Premium.cpp b/protocols/Telegram/tdlib/td/td/telegram/Premium.cpp index ef67bcf829..f6589cd5a2 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Premium.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/Premium.cpp @@ -1,29 +1,40 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/Premium.h" +#include "td/telegram/AccessRights.h" #include "td/telegram/AnimationsManager.h" #include "td/telegram/Application.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChannelId.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Document.h" #include "td/telegram/DocumentsManager.h" +#include "td/telegram/GiveawayParameters.h" #include "td/telegram/Global.h" #include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessageSender.h" +#include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" #include "td/telegram/PremiumGiftOption.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/StarManager.h" #include "td/telegram/SuggestedAction.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UpdatesManager.h" #include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" +#include "td/utils/FlatHashSet.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" #include "td/utils/misc.h" @@ -78,18 +89,107 @@ static td_api::object_ptr get_premium_feature_object(Sli if (premium_feature == "translations") { return td_api::make_object(); } + if (premium_feature == "stories") { + return td_api::make_object(); + } + if (premium_feature == "channel_boost") { + return td_api::make_object(); + } + if (premium_feature == "peer_colors") { + return td_api::make_object(); + } + if (premium_feature == "wallpapers") { + return td_api::make_object(); + } + if (premium_feature == "saved_tags") { + return td_api::make_object(); + } + if (premium_feature == "message_privacy") { + return td_api::make_object(); + } + if (premium_feature == "last_seen") { + return td_api::make_object(); + } + if (premium_feature == "business") { + return td_api::make_object(); + } + if (premium_feature == "effects") { + return td_api::make_object(); + } + if (G()->is_test_dc()) { + LOG(ERROR) << "Receive unsupported premium feature " << premium_feature; + } return nullptr; } +static td_api::object_ptr get_business_feature_object(Slice business_feature) { + if (business_feature == "business_location") { + return td_api::make_object(); + } + if (business_feature == "business_hours") { + return td_api::make_object(); + } + if (business_feature == "quick_replies") { + return td_api::make_object(); + } + if (business_feature == "greeting_message") { + return td_api::make_object(); + } + if (business_feature == "away_message") { + return td_api::make_object(); + } + if (business_feature == "business_links") { + return td_api::make_object(); + } + if (business_feature == "business_intro") { + return td_api::make_object(); + } + if (business_feature == "business_bots") { + return td_api::make_object(); + } + if (business_feature == "emoji_status") { + return td_api::make_object(); + } + if (business_feature == "folder_tags") { + return td_api::make_object(); + } + if (business_feature == "stories") { + return td_api::make_object(); + } + if (G()->is_test_dc()) { + LOG(ERROR) << "Receive unsupported business feature " << business_feature; + } + return nullptr; +} + +Result> get_boost_input_peer(Td *td, DialogId dialog_id) { + if (dialog_id == DialogId()) { + return nullptr; + } + + if (!td->dialog_manager_->have_dialog_force(dialog_id, "get_boost_input_peer")) { + return Status::Error(400, "Chat to boost not found"); + } + if (dialog_id.get_type() != DialogType::Channel) { + return Status::Error(400, "Can't boost the chat"); + } + if (!td->chat_manager_->get_channel_status(dialog_id.get_channel_id()).is_administrator()) { + return Status::Error(400, "Not enough rights in the chat"); + } + auto boost_input_peer = td->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + CHECK(boost_input_peer != nullptr); + return std::move(boost_input_peer); +} + static Result> get_input_store_payment_purpose( - Td *td, const td_api::object_ptr &purpose) { + Td *td, td_api::object_ptr &purpose) { if (purpose == nullptr) { return Status::Error(400, "Purchase purpose must be non-empty"); } switch (purpose->get_id()) { case td_api::storePaymentPurposePremiumSubscription::ID: { - auto p = static_cast(purpose.get()); + auto p = static_cast(purpose.get()); int32 flags = 0; if (p->is_restore_) { flags |= telegram_api::inputStorePaymentPremiumSubscription::RESTORE_MASK; @@ -101,15 +201,91 @@ static Result> get_input_s false /*ignored*/); } case td_api::storePaymentPurposeGiftedPremium::ID: { - auto p = static_cast(purpose.get()); + auto p = static_cast(purpose.get()); UserId user_id(p->user_id_); - TRY_RESULT(input_user, td->contacts_manager_->get_input_user(user_id)); + TRY_RESULT(input_user, td->user_manager_->get_input_user(user_id)); if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { return Status::Error(400, "Invalid amount of the currency specified"); } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } return make_tl_object(std::move(input_user), p->currency_, p->amount_); } + case td_api::storePaymentPurposePremiumGiftCodes::ID: { + auto p = static_cast(purpose.get()); + vector> input_users; + for (auto user_id : p->user_ids_) { + TRY_RESULT(input_user, td->user_manager_->get_input_user(UserId(user_id))); + input_users.push_back(std::move(input_user)); + } + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + DialogId boosted_dialog_id(p->boosted_chat_id_); + TRY_RESULT(boost_input_peer, get_boost_input_peer(td, boosted_dialog_id)); + int32 flags = 0; + if (boost_input_peer != nullptr) { + flags |= telegram_api::inputStorePaymentPremiumGiftCode::BOOST_PEER_MASK; + } + return telegram_api::make_object( + flags, std::move(input_users), std::move(boost_input_peer), p->currency_, p->amount_); + } + case td_api::storePaymentPurposePremiumGiveaway::ID: { + auto p = static_cast(purpose.get()); + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + TRY_RESULT(parameters, GiveawayParameters::get_giveaway_parameters(td, p->parameters_.get())); + return parameters.get_input_store_payment_premium_giveaway(td, p->currency_, p->amount_); + } + case td_api::storePaymentPurposeStarGiveaway::ID: { + auto p = static_cast(purpose.get()); + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + if (p->winner_count_ <= 0 || p->star_count_ <= 0) { + return Status::Error(400, "Invalid giveaway parameters specified"); + } + TRY_RESULT(parameters, GiveawayParameters::get_giveaway_parameters(td, p->parameters_.get())); + return parameters.get_input_store_payment_stars_giveaway(td, p->currency_, p->amount_, p->winner_count_, + p->star_count_); + } + case td_api::storePaymentPurposeStars::ID: { + auto p = static_cast(purpose.get()); + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::StarsSubscriptionLowBalance}, Promise()); + return telegram_api::make_object(p->star_count_, p->currency_, + p->amount_); + } + case td_api::storePaymentPurposeGiftedStars::ID: { + auto p = static_cast(purpose.get()); + UserId user_id(p->user_id_); + TRY_RESULT(input_user, td->user_manager_->get_input_user(user_id)); + if (p->amount_ <= 0 || !check_currency_amount(p->amount_)) { + return Status::Error(400, "Invalid amount of the currency specified"); + } + if (!clean_input_string(p->currency_)) { + return Status::Error(400, "Strings must be encoded in UTF-8"); + } + return telegram_api::make_object(std::move(input_user), p->star_count_, + p->currency_, p->amount_); + } default: UNREACHABLE(); return nullptr; @@ -137,9 +313,9 @@ class GetPremiumPromoQuery final : public Td::ResultHandler { auto promo = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for GetPremiumPromoQuery: " << to_string(promo); - td_->contacts_manager_->on_get_users(std::move(promo->users_), "GetPremiumPromoQuery"); + td_->user_manager_->on_get_users(std::move(promo->users_), "GetPremiumPromoQuery"); - auto state = get_message_text(td_->contacts_manager_.get(), std::move(promo->status_text_), + auto state = get_message_text(td_->user_manager_.get(), std::move(promo->status_text_), std::move(promo->status_entities_), true, true, 0, false, "GetPremiumPromoQuery"); if (promo->video_sections_.size() != promo->videos_.size()) { @@ -147,9 +323,11 @@ class GetPremiumPromoQuery final : public Td::ResultHandler { } vector> animations; + vector> business_animations; + FlatHashSet video_sections; for (size_t i = 0; i < promo->video_sections_.size(); i++) { - auto feature = get_premium_feature_object(promo->video_sections_[i]); - if (feature == nullptr) { + if (promo->video_sections_[i].empty() || !video_sections.insert(promo->video_sections_[i]).second) { + LOG(ERROR) << "Receive duplicate Premium feature animation " << promo->video_sections_[i]; continue; } @@ -167,18 +345,302 @@ class GetPremiumPromoQuery final : public Td::ResultHandler { continue; } - auto animation_object = td_->animations_manager_->get_animation_object(parsed_document.file_id); - animations.push_back(td_api::make_object(std::move(feature), - std::move(animation_object))); + auto feature = get_premium_feature_object(promo->video_sections_[i]); + if (feature != nullptr) { + auto animation_object = td_->animations_manager_->get_animation_object(parsed_document.file_id); + animations.push_back(td_api::make_object( + std::move(feature), std::move(animation_object))); + } else { + auto business_feature = get_business_feature_object(promo->video_sections_[i]); + if (business_feature != nullptr) { + auto animation_object = td_->animations_manager_->get_animation_object(parsed_document.file_id); + business_animations.push_back(td_api::make_object( + std::move(business_feature), std::move(animation_object))); + } else if (G()->is_test_dc()) { + LOG(ERROR) << "Receive unsupported feature " << promo->video_sections_[i]; + } + } } auto period_options = get_premium_gift_options(std::move(promo->period_options_)); - promise_.set_value(td_api::make_object( - get_formatted_text_object(state, true, 0), get_premium_state_payment_options_object(period_options), - std::move(animations))); + promise_.set_value( + td_api::make_object(get_formatted_text_object(td_->user_manager_.get(), state, true, 0), + get_premium_state_payment_options_object(period_options), + std::move(animations), std::move(business_animations))); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetPremiumGiftCodeOptionsQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId boosted_dialog_id_; + + public: + explicit GetPremiumGiftCodeOptionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId boosted_dialog_id) { + auto r_boost_input_peer = get_boost_input_peer(td_, boosted_dialog_id); + if (r_boost_input_peer.is_error()) { + return on_error(r_boost_input_peer.move_as_error()); + } + auto boost_input_peer = r_boost_input_peer.move_as_ok(); + + int32 flags = 0; + if (boost_input_peer != nullptr) { + flags |= telegram_api::payments_getPremiumGiftCodeOptions::BOOST_PEER_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::payments_getPremiumGiftCodeOptions(flags, std::move(boost_input_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto results = result_ptr.move_as_ok(); + vector> options; + for (auto &result : results) { + if (result->store_product_.empty()) { + result->store_quantity_ = 0; + } else if (result->store_quantity_ <= 0) { + result->store_quantity_ = 1; + } + options.push_back(td_api::make_object( + result->currency_, result->amount_, result->users_, result->months_, result->store_product_, + result->store_quantity_)); + } + + promise_.set_value(td_api::make_object(std::move(options))); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(boosted_dialog_id_, status, "GetPremiumGiftCodeOptionsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class CheckGiftCodeQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit CheckGiftCodeQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(const string &code) { + send_query(G()->net_query_creator().create(telegram_api::payments_checkGiftCode(code))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for CheckGiftCodeQuery: " << to_string(result); + td_->user_manager_->on_get_users(std::move(result->users_), "CheckGiftCodeQuery"); + td_->chat_manager_->on_get_chats(std::move(result->chats_), "CheckGiftCodeQuery"); + + if (result->date_ <= 0 || result->months_ <= 0 || result->used_date_ < 0) { + LOG(ERROR) << "Receive " << to_string(result); + return on_error(Status::Error(500, "Receive invalid response")); + } + + DialogId creator_dialog_id; + if (result->from_id_ != nullptr) { + creator_dialog_id = DialogId(result->from_id_); + if (!creator_dialog_id.is_valid() || + !td_->dialog_manager_->have_dialog_info_force(creator_dialog_id, "CheckGiftCodeQuery")) { + LOG(ERROR) << "Receive " << to_string(result); + return on_error(Status::Error(500, "Receive invalid response")); + } + if (creator_dialog_id.get_type() != DialogType::User) { + td_->dialog_manager_->force_create_dialog(creator_dialog_id, "CheckGiftCodeQuery", true); + } + } + UserId user_id(result->to_id_); + if (!user_id.is_valid() && user_id != UserId()) { + LOG(ERROR) << "Receive " << to_string(result); + user_id = UserId(); + } + MessageId message_id(ServerMessageId(result->giveaway_msg_id_)); + if (!message_id.is_valid() && message_id != MessageId()) { + LOG(ERROR) << "Receive " << to_string(result); + message_id = MessageId(); + } + if (message_id != MessageId() && creator_dialog_id.get_type() != DialogType::Channel) { + LOG(ERROR) << "Receive " << to_string(result); + message_id = MessageId(); + } + promise_.set_value(td_api::make_object( + creator_dialog_id == DialogId() ? nullptr + : get_message_sender_object(td_, creator_dialog_id, "premiumGiftCodeInfo"), + result->date_, result->via_giveaway_, message_id.get(), result->months_, + td_->user_manager_->get_user_id_object(user_id, "premiumGiftCodeInfo"), result->used_date_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class ApplyGiftCodeQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ApplyGiftCodeQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &code) { + send_query(G()->net_query_creator().create(telegram_api::payments_applyGiftCode(code))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for ApplyGiftCodeQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class LaunchPrepaidGiveawayQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit LaunchPrepaidGiveawayQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(int64 giveaway_id, const GiveawayParameters ¶meters, int32 user_count, int64 star_count) { + auto dialog_id = parameters.get_boosted_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + CHECK(input_peer != nullptr); + telegram_api::object_ptr purpose; + if (star_count == 0) { + purpose = parameters.get_input_store_payment_premium_giveaway(td_, string(), 0); + } else { + purpose = parameters.get_input_store_payment_stars_giveaway(td_, string(), 12345, user_count, star_count); + } + send_query(G()->net_query_creator().create( + telegram_api::payments_launchPrepaidGiveaway(std::move(input_peer), giveaway_id, std::move(purpose)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for LaunchPrepaidGiveawayQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetGiveawayInfoQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetGiveawayInfoQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, ServerMessageId server_message_id) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::payments_getGiveawayInfo(std::move(input_peer), server_message_id.get()))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetGiveawayInfoQuery: " << to_string(ptr); + switch (ptr->get_id()) { + case telegram_api::payments_giveawayInfo::ID: { + auto info = telegram_api::move_object_as(ptr); + auto status = [&]() -> td_api::object_ptr { + if (info->joined_too_early_date_ > 0) { + return td_api::make_object(info->joined_too_early_date_); + } + if (info->admin_disallowed_chat_id_ > 0) { + ChannelId channel_id(info->admin_disallowed_chat_id_); + if (!channel_id.is_valid() || !td_->chat_manager_->have_channel_force(channel_id, "GetGiveawayInfoQuery")) { + LOG(ERROR) << "Receive " << to_string(info); + } else { + DialogId dialog_id(channel_id); + td_->dialog_manager_->force_create_dialog(dialog_id, "GetGiveawayInfoQuery"); + return td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "giveawayParticipantStatusAdministrator")); + } + } + if (!info->disallowed_country_.empty()) { + return td_api::make_object(info->disallowed_country_); + } + if (info->participating_) { + return td_api::make_object(); + } + return td_api::make_object(); + }(); + promise_.set_value(td_api::make_object( + max(0, info->start_date_), std::move(status), info->preparing_results_)); + break; + } + case telegram_api::payments_giveawayInfoResults::ID: { + auto info = telegram_api::move_object_as(ptr); + auto winner_count = info->winners_count_; + auto activated_count = info->activated_count_; + if (activated_count < 0 || activated_count > winner_count) { + LOG(ERROR) << "Receive " << to_string(info); + if (activated_count < 0) { + activated_count = 0; + } + if (winner_count < 0) { + winner_count = 0; + } + if (activated_count > winner_count) { + activated_count = winner_count; + } + } + promise_.set_value(td_api::make_object( + max(0, info->start_date_), max(0, info->finish_date_), info->refunded_, info->winner_, winner_count, + activated_count, info->gift_code_slug_, StarManager::get_star_count(info->stars_prize_))); + break; + } + default: + UNREACHABLE(); + } } void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetGiveawayInfoQuery"); promise_.set_error(std::move(status)); } }; @@ -302,7 +764,14 @@ const vector &get_premium_limit_keys() { "caption_length", "about_length", "chatlist_invites", - "chatlists_joined"}; + "chatlists_joined", + "story_expiring", + "story_caption_length", + "stories_sent_weekly", + "stories_sent_monthly", + "stories_suggested_reactions", + "recommended_channels", + "saved_dialogs_pinned"}; return limit_keys; } @@ -323,6 +792,8 @@ static Slice get_limit_type_key(const td_api::PremiumLimitType *limit_type) { return Slice("dialogs_pinned"); case td_api::premiumLimitTypePinnedArchivedChatCount::ID: return Slice("dialogs_folder_pinned"); + case td_api::premiumLimitTypePinnedSavedMessagesTopicCount::ID: + return Slice("saved_dialogs_pinned"); case td_api::premiumLimitTypeCreatedPublicChatCount::ID: return Slice("channels_public"); case td_api::premiumLimitTypeCaptionLength::ID: @@ -333,6 +804,18 @@ static Slice get_limit_type_key(const td_api::PremiumLimitType *limit_type) { return Slice("chatlist_invites"); case td_api::premiumLimitTypeShareableChatFolderCount::ID: return Slice("chatlists_joined"); + case td_api::premiumLimitTypeActiveStoryCount::ID: + return Slice("story_expiring"); + case td_api::premiumLimitTypeStoryCaptionLength::ID: + return Slice("story_caption_length"); + case td_api::premiumLimitTypeWeeklySentStoryCount::ID: + return Slice("stories_sent_weekly"); + case td_api::premiumLimitTypeMonthlySentStoryCount::ID: + return Slice("stories_sent_monthly"); + case td_api::premiumLimitTypeStorySuggestedReactionAreaCount::ID: + return Slice("stories_suggested_reactions"); + case td_api::premiumLimitTypeSimilarChatCount::ID: + return Slice("recommended_channels"); default: UNREACHABLE(); return Slice(); @@ -383,12 +866,90 @@ static string get_premium_source(const td_api::PremiumFeature *feature) { return "app_icons"; case td_api::premiumFeatureRealTimeChatTranslation::ID: return "translations"; + case td_api::premiumFeatureUpgradedStories::ID: + return "stories"; + case td_api::premiumFeatureChatBoost::ID: + return "channel_boost"; + case td_api::premiumFeatureAccentColor::ID: + return "peer_colors"; + case td_api::premiumFeatureBackgroundForBoth::ID: + return "wallpapers"; + case td_api::premiumFeatureSavedMessagesTags::ID: + return "saved_tags"; + case td_api::premiumFeatureMessagePrivacy::ID: + return "message_privacy"; + case td_api::premiumFeatureLastSeenTimes::ID: + return "last_seen"; + case td_api::premiumFeatureBusiness::ID: + return "business"; + case td_api::premiumFeatureMessageEffects::ID: + return "effects"; default: UNREACHABLE(); } return string(); } +static string get_premium_source(const td_api::BusinessFeature *feature) { + if (feature == nullptr) { + return "business"; + } + + switch (feature->get_id()) { + case td_api::businessFeatureLocation::ID: + return "business_location"; + case td_api::businessFeatureOpeningHours::ID: + return "business_hours"; + case td_api::businessFeatureQuickReplies::ID: + return "quick_replies"; + case td_api::businessFeatureGreetingMessage::ID: + return "greeting_message"; + case td_api::businessFeatureAwayMessage::ID: + return "away_message"; + case td_api::businessFeatureAccountLinks::ID: + return "business_links"; + case td_api::businessFeatureStartPage::ID: + return "business_intro"; + case td_api::businessFeatureBots::ID: + return "business_bots"; + case td_api::businessFeatureEmojiStatus::ID: + return "emoji_status"; + case td_api::businessFeatureChatFolderTags::ID: + return "folder_tags"; + case td_api::businessFeatureUpgradedStories::ID: + return "stories"; + default: + UNREACHABLE(); + } + return string(); +} + +static string get_premium_source(const td_api::PremiumStoryFeature *feature) { + if (feature == nullptr) { + return string(); + } + + switch (feature->get_id()) { + case td_api::premiumStoryFeaturePriorityOrder::ID: + return "stories__priority_order"; + case td_api::premiumStoryFeatureStealthMode::ID: + return "stories__stealth_mode"; + case td_api::premiumStoryFeaturePermanentViewsHistory::ID: + return "stories__permanent_views_history"; + case td_api::premiumStoryFeatureCustomExpirationDuration::ID: + return "stories__expiration_durations"; + case td_api::premiumStoryFeatureSaveStories::ID: + return "stories__save_stories_to_gallery"; + case td_api::premiumStoryFeatureLinksAndFormatting::ID: + return "stories__links_and_formatting"; + case td_api::premiumStoryFeatureVideoQuality::ID: + return "stories__quality"; + default: + UNREACHABLE(); + return string(); + } +} + static string get_premium_source(const td_api::object_ptr &source) { if (source == nullptr) { return string(); @@ -402,6 +963,14 @@ static string get_premium_source(const td_api::object_ptr auto *feature = static_cast(source.get())->feature_.get(); return get_premium_source(feature); } + case td_api::premiumSourceBusinessFeature::ID: { + auto *feature = static_cast(source.get())->feature_.get(); + return get_premium_source(feature); + } + case td_api::premiumSourceStoryFeature::ID: { + auto *feature = static_cast(source.get())->feature_.get(); + return get_premium_source(feature); + } case td_api::premiumSourceLink::ID: { auto &referrer = static_cast(source.get())->referrer_; if (referrer.empty()) { @@ -445,6 +1014,9 @@ static td_api::object_ptr get_premium_limit_object(Slice k if (key == "dialogs_folder_pinned") { return td_api::make_object(); } + if (key == "saved_dialogs_pinned") { + return td_api::make_object(); + } if (key == "channels_public") { return td_api::make_object(); } @@ -460,6 +1032,24 @@ static td_api::object_ptr get_premium_limit_object(Slice k if (key == "chatlists_joined") { return td_api::make_object(); } + if (key == "story_expiring") { + return td_api::make_object(); + } + if (key == "story_caption_length") { + return td_api::make_object(); + } + if (key == "stories_sent_weekly") { + return td_api::make_object(); + } + if (key == "stories_sent_monthly") { + return td_api::make_object(); + } + if (key == "stories_suggested_reactions") { + return td_api::make_object(); + } + if (key == "recommended_channels") { + return td_api::make_object(); + } UNREACHABLE(); return nullptr; }(); @@ -477,13 +1067,13 @@ void get_premium_limit(const td_api::object_ptr &limit void get_premium_features(Td *td, const td_api::object_ptr &source, Promise> &&promise) { - auto premium_features = full_split( - G()->get_option_string( - "premium_features", - "double_limits,more_upload,faster_download,voice_to_text,no_ads,infinite_reactions,premium_stickers," - "animated_emoji,advanced_chat_management,profile_badge,emoji_status,animated_userpics,app_icons," - "translations"), - ','); + auto premium_features = + full_split(G()->get_option_string( + "premium_features", + "stories,more_upload,double_limits,last_seen,voice_to_text,faster_download,translations,animated_" + "emoji,emoji_status,saved_tags,peer_colors,wallpapers,profile_badge,message_privacy,advanced_chat_" + "management,no_ads,app_icons,infinite_reactions,animated_userpics,premium_stickers,effects"), + ','); vector> features; for (const auto &premium_feature : premium_features) { auto feature = get_premium_feature_object(premium_feature); @@ -525,6 +1115,39 @@ void get_premium_features(Td *td, const td_api::object_ptr(std::move(features), std::move(limits), std::move(payment_link))); } +void get_business_features(Td *td, const td_api::object_ptr &source, + Promise> &&promise) { + auto business_features = + full_split(G()->get_option_string("business_features", + "business_location,business_hours,quick_replies,greeting_message,away_message," + "business_links,business_intro,business_bots,emoji_status,folder_tags,stories"), + ','); + vector> features; + for (const auto &business_feature : business_features) { + auto feature = get_business_feature_object(business_feature); + if (feature != nullptr) { + features.push_back(std::move(feature)); + } + } + + auto source_str = get_premium_source(source.get()); + if (!source_str.empty()) { + vector> data; + vector> promo_order; + for (const auto &business_feature : business_features) { + promo_order.push_back(telegram_api::make_object(business_feature)); + } + data.push_back(telegram_api::make_object( + "business_promo_order", telegram_api::make_object(std::move(promo_order)))); + data.push_back(telegram_api::make_object( + "source", telegram_api::make_object(source_str))); + save_app_log(td, "business.promo_screen_show", DialogId(), + telegram_api::make_object(std::move(data)), Promise()); + } + + promise.set_value(td_api::make_object(std::move(features))); +} + void view_premium_feature(Td *td, const td_api::object_ptr &feature, Promise &&promise) { auto source = get_premium_source(feature.get()); if (source.empty()) { @@ -548,6 +1171,35 @@ void get_premium_state(Td *td, Promise> td->create_handler(std::move(promise))->send(); } +void get_premium_gift_code_options(Td *td, DialogId boosted_dialog_id, + Promise> &&promise) { + td->create_handler(std::move(promise))->send(boosted_dialog_id); +} + +void check_premium_gift_code(Td *td, const string &code, + Promise> &&promise) { + td->create_handler(std::move(promise))->send(code); +} + +void apply_premium_gift_code(Td *td, const string &code, Promise &&promise) { + td->create_handler(std::move(promise))->send(code); +} + +void launch_prepaid_premium_giveaway(Td *td, int64 giveaway_id, + td_api::object_ptr &¶meters, int32 user_count, + int64 star_count, Promise &&promise) { + TRY_RESULT_PROMISE(promise, giveaway_parameters, GiveawayParameters::get_giveaway_parameters(td, parameters.get())); + td->create_handler(std::move(promise)) + ->send(giveaway_id, giveaway_parameters, user_count, star_count); +} + +void get_premium_giveaway_info(Td *td, MessageFullId message_full_id, + Promise> &&promise) { + TRY_RESULT_PROMISE(promise, server_message_id, td->messages_manager_->get_giveaway_message_id(message_full_id)); + td->create_handler(std::move(promise)) + ->send(message_full_id.get_dialog_id(), server_message_id); +} + void can_purchase_premium(Td *td, td_api::object_ptr &&purpose, Promise &&promise) { td->create_handler(std::move(promise))->send(std::move(purpose)); } @@ -557,6 +1209,7 @@ void assign_app_store_transaction(Td *td, const string &receipt, if (purpose != nullptr && purpose->get_id() == td_api::storePaymentPurposePremiumSubscription::ID) { dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::UpgradePremium}, Promise()); dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::SubscribeToAnnualPremium}, Promise()); + dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::RestorePremium}, Promise()); } td->create_handler(std::move(promise))->send(receipt, std::move(purpose)); } @@ -568,6 +1221,7 @@ void assign_play_market_transaction(Td *td, const string &package_name, const st if (purpose != nullptr && purpose->get_id() == td_api::storePaymentPurposePremiumSubscription::ID) { dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::UpgradePremium}, Promise()); dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::SubscribeToAnnualPremium}, Promise()); + dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::RestorePremium}, Promise()); } td->create_handler(std::move(promise)) ->send(package_name, store_product_id, purchase_token, std::move(purpose)); diff --git a/protocols/Telegram/tdlib/td/td/telegram/Premium.h b/protocols/Telegram/tdlib/td/td/telegram/Premium.h index 0b6278a5a1..d8b5f1e37a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Premium.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Premium.h @@ -1,21 +1,27 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" #include "td/utils/common.h" #include "td/utils/Promise.h" #include "td/utils/Slice.h" +#include "td/utils/Status.h" namespace td { class Td; +Result> get_boost_input_peer(Td *td, DialogId dialog_id); + const vector &get_premium_limit_keys(); void get_premium_limit(const td_api::object_ptr &limit_type, @@ -24,12 +30,30 @@ void get_premium_limit(const td_api::object_ptr &limit void get_premium_features(Td *td, const td_api::object_ptr &source, Promise> &&promise); +void get_business_features(Td *td, const td_api::object_ptr &source, + Promise> &&promise); + void view_premium_feature(Td *td, const td_api::object_ptr &feature, Promise &&promise); void click_premium_subscription_button(Td *td, Promise &&promise); void get_premium_state(Td *td, Promise> &&promise); +void get_premium_gift_code_options(Td *td, DialogId boosted_dialog_id, + Promise> &&promise); + +void check_premium_gift_code(Td *td, const string &code, + Promise> &&promise); + +void apply_premium_gift_code(Td *td, const string &code, Promise &&promise); + +void launch_prepaid_premium_giveaway(Td *td, int64 giveaway_id, + td_api::object_ptr &¶meters, int32 user_count, + int64 star_count, Promise &&promise); + +void get_premium_giveaway_info(Td *td, MessageFullId message_full_id, + Promise> &&promise); + void can_purchase_premium(Td *td, td_api::object_ptr &&purpose, Promise &&promise); void assign_app_store_transaction(Td *td, const string &receipt, diff --git a/protocols/Telegram/tdlib/td/td/telegram/PrivacyManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/PrivacyManager.cpp index 4556e6f19a..2466f7a454 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PrivacyManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/PrivacyManager.cpp @@ -1,22 +1,21 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/PrivacyManager.h" -#include "td/telegram/ChannelId.h" -#include "td/telegram/ChatId.h" -#include "td/telegram/ContactsManager.h" -#include "td/telegram/DialogId.h" #include "td/telegram/Global.h" -#include "td/telegram/MessagesManager.h" #include "td/telegram/net/NetQueryCreator.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" +#include "td/utils/buffer.h" #include "td/utils/logging.h" #include @@ -24,403 +23,67 @@ namespace td { -Result PrivacyManager::UserPrivacySetting::get_user_privacy_setting( - tl_object_ptr key) { - if (key == nullptr) { - return Status::Error(400, "UserPrivacySetting must be non-empty"); - } - return UserPrivacySetting(*key); -} - -PrivacyManager::UserPrivacySetting::UserPrivacySetting(const telegram_api::PrivacyKey &key) { - switch (key.get_id()) { - case telegram_api::privacyKeyStatusTimestamp::ID: - type_ = Type::UserStatus; - break; - case telegram_api::privacyKeyChatInvite::ID: - type_ = Type::ChatInvite; - break; - case telegram_api::privacyKeyPhoneCall::ID: - type_ = Type::Call; - break; - case telegram_api::privacyKeyPhoneP2P::ID: - type_ = Type::PeerToPeerCall; - break; - case telegram_api::privacyKeyForwards::ID: - type_ = Type::LinkInForwardedMessages; - break; - case telegram_api::privacyKeyProfilePhoto::ID: - type_ = Type::UserProfilePhoto; - break; - case telegram_api::privacyKeyPhoneNumber::ID: - type_ = Type::UserPhoneNumber; - break; - case telegram_api::privacyKeyAddedByPhone::ID: - type_ = Type::FindByPhoneNumber; - break; - case telegram_api::privacyKeyVoiceMessages::ID: - type_ = Type::VoiceMessages; - break; - default: - UNREACHABLE(); - type_ = Type::UserStatus; - } -} +class GetPrivacyQuery final : public Td::ResultHandler { + Promise promise_; -tl_object_ptr PrivacyManager::UserPrivacySetting::get_user_privacy_setting_object() const { - switch (type_) { - case Type::UserStatus: - return make_tl_object(); - case Type::ChatInvite: - return make_tl_object(); - case Type::Call: - return make_tl_object(); - case Type::PeerToPeerCall: - return make_tl_object(); - case Type::LinkInForwardedMessages: - return make_tl_object(); - case Type::UserProfilePhoto: - return make_tl_object(); - case Type::UserPhoneNumber: - return make_tl_object(); - case Type::FindByPhoneNumber: - return make_tl_object(); - case Type::VoiceMessages: - return make_tl_object(); - default: - UNREACHABLE(); - return nullptr; + public: + explicit GetPrivacyQuery(Promise &&promise) : promise_(std::move(promise)) { } -} -tl_object_ptr PrivacyManager::UserPrivacySetting::get_input_privacy_key() const { - switch (type_) { - case Type::UserStatus: - return make_tl_object(); - case Type::ChatInvite: - return make_tl_object(); - case Type::Call: - return make_tl_object(); - case Type::PeerToPeerCall: - return make_tl_object(); - case Type::LinkInForwardedMessages: - return make_tl_object(); - case Type::UserProfilePhoto: - return make_tl_object(); - case Type::UserPhoneNumber: - return make_tl_object(); - case Type::FindByPhoneNumber: - return make_tl_object(); - case Type::VoiceMessages: - return make_tl_object(); - default: - UNREACHABLE(); - return nullptr; - } -} -PrivacyManager::UserPrivacySetting::UserPrivacySetting(const td_api::UserPrivacySetting &key) { - switch (key.get_id()) { - case td_api::userPrivacySettingShowStatus::ID: - type_ = Type::UserStatus; - break; - case td_api::userPrivacySettingAllowChatInvites::ID: - type_ = Type::ChatInvite; - break; - case td_api::userPrivacySettingAllowCalls::ID: - type_ = Type::Call; - break; - case td_api::userPrivacySettingAllowPeerToPeerCalls::ID: - type_ = Type::PeerToPeerCall; - break; - case td_api::userPrivacySettingShowLinkInForwardedMessages::ID: - type_ = Type::LinkInForwardedMessages; - break; - case td_api::userPrivacySettingShowProfilePhoto::ID: - type_ = Type::UserProfilePhoto; - break; - case td_api::userPrivacySettingShowPhoneNumber::ID: - type_ = Type::UserPhoneNumber; - break; - case td_api::userPrivacySettingAllowFindingByPhoneNumber::ID: - type_ = Type::FindByPhoneNumber; - break; - case td_api::userPrivacySettingAllowPrivateVoiceAndVideoNoteMessages::ID: - type_ = Type::VoiceMessages; - break; - default: - UNREACHABLE(); - type_ = Type::UserStatus; + void send(UserPrivacySetting user_privacy_setting) { + send_query(G()->net_query_creator().create( + telegram_api::account_getPrivacy(user_privacy_setting.get_input_privacy_key()))); } -} -void PrivacyManager::UserPrivacySettingRule::set_chat_ids(const vector &dialog_ids) { - chat_ids_.clear(); - auto td = G()->td().get_actor_unsafe(); - for (auto dialog_id_int : dialog_ids) { - DialogId dialog_id(dialog_id_int); - if (!td->messages_manager_->have_dialog_force(dialog_id, "UserPrivacySettingRule::set_chat_ids")) { - LOG(ERROR) << "Ignore not found " << dialog_id; - continue; + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); } - switch (dialog_id.get_type()) { - case DialogType::Chat: - chat_ids_.push_back(dialog_id.get_chat_id().get()); - break; - case DialogType::Channel: { - auto channel_id = dialog_id.get_channel_id(); - if (!td->contacts_manager_->is_megagroup_channel(channel_id)) { - LOG(ERROR) << "Ignore broadcast " << channel_id; - break; - } - chat_ids_.push_back(channel_id.get()); - break; - } - default: - LOG(ERROR) << "Ignore " << dialog_id; - } + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetPrivacyQuery: " << to_string(ptr); + promise_.set_value(UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(ptr))); } -} -PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const td_api::UserPrivacySettingRule &rule) { - switch (rule.get_id()) { - case td_api::userPrivacySettingRuleAllowContacts::ID: - type_ = Type::AllowContacts; - break; - case td_api::userPrivacySettingRuleAllowAll::ID: - type_ = Type::AllowAll; - break; - case td_api::userPrivacySettingRuleAllowUsers::ID: - type_ = Type::AllowUsers; - user_ids_ = UserId::get_user_ids(static_cast(rule).user_ids_); - break; - case td_api::userPrivacySettingRuleAllowChatMembers::ID: - type_ = Type::AllowChatParticipants; - set_chat_ids(static_cast(rule).chat_ids_); - break; - case td_api::userPrivacySettingRuleRestrictContacts::ID: - type_ = Type::RestrictContacts; - break; - case td_api::userPrivacySettingRuleRestrictAll::ID: - type_ = Type::RestrictAll; - break; - case td_api::userPrivacySettingRuleRestrictUsers::ID: - type_ = Type::RestrictUsers; - user_ids_ = - UserId::get_user_ids(static_cast(rule).user_ids_); - break; - case td_api::userPrivacySettingRuleRestrictChatMembers::ID: - type_ = Type::RestrictChatParticipants; - set_chat_ids(static_cast(rule).chat_ids_); - break; - default: - UNREACHABLE(); + void on_error(Status status) final { + promise_.set_error(std::move(status)); } -} +}; -PrivacyManager::UserPrivacySettingRule::UserPrivacySettingRule(const telegram_api::PrivacyRule &rule) { - switch (rule.get_id()) { - case telegram_api::privacyValueAllowContacts::ID: - type_ = Type::AllowContacts; - break; - case telegram_api::privacyValueAllowAll::ID: - type_ = Type::AllowAll; - break; - case telegram_api::privacyValueAllowUsers::ID: - type_ = Type::AllowUsers; - user_ids_ = UserId::get_user_ids(static_cast(rule).users_); - break; - case telegram_api::privacyValueAllowChatParticipants::ID: - type_ = Type::AllowChatParticipants; - chat_ids_ = static_cast(rule).chats_; - break; - case telegram_api::privacyValueDisallowContacts::ID: - type_ = Type::RestrictContacts; - break; - case telegram_api::privacyValueDisallowAll::ID: - type_ = Type::RestrictAll; - break; - case telegram_api::privacyValueDisallowUsers::ID: - type_ = Type::RestrictUsers; - user_ids_ = UserId::get_user_ids(static_cast(rule).users_); - break; - case telegram_api::privacyValueDisallowChatParticipants::ID: - type_ = Type::RestrictChatParticipants; - chat_ids_ = static_cast(rule).chats_; - break; - default: - UNREACHABLE(); - } -} +class SetPrivacyQuery final : public Td::ResultHandler { + Promise promise_; -tl_object_ptr -PrivacyManager::UserPrivacySettingRule::get_user_privacy_setting_rule_object() const { - switch (type_) { - case Type::AllowContacts: - return make_tl_object(); - case Type::AllowAll: - return make_tl_object(); - case Type::AllowUsers: - return make_tl_object(UserId::get_input_user_ids(user_ids_)); - case Type::AllowChatParticipants: - return make_tl_object(chat_ids_as_dialog_ids()); - case Type::RestrictContacts: - return make_tl_object(); - case Type::RestrictAll: - return make_tl_object(); - case Type::RestrictUsers: - return make_tl_object(UserId::get_input_user_ids(user_ids_)); - case Type::RestrictChatParticipants: - return make_tl_object(chat_ids_as_dialog_ids()); - default: - UNREACHABLE(); + public: + explicit SetPrivacyQuery(Promise &&promise) : promise_(std::move(promise)) { } -} -tl_object_ptr PrivacyManager::UserPrivacySettingRule::get_input_privacy_rule() const { - switch (type_) { - case Type::AllowContacts: - return make_tl_object(); - case Type::AllowAll: - return make_tl_object(); - case Type::AllowUsers: - return make_tl_object(get_input_users()); - case Type::AllowChatParticipants: - return make_tl_object(vector{chat_ids_}); - case Type::RestrictContacts: - return make_tl_object(); - case Type::RestrictAll: - return make_tl_object(); - case Type::RestrictUsers: - return make_tl_object(get_input_users()); - case Type::RestrictChatParticipants: - return make_tl_object(vector{chat_ids_}); - default: - UNREACHABLE(); + void send(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules) { + send_query(G()->net_query_creator().create(telegram_api::account_setPrivacy( + user_privacy_setting.get_input_privacy_key(), privacy_rules.get_input_privacy_rules(td_)))); } -} -Result PrivacyManager::UserPrivacySettingRule::get_user_privacy_setting_rule( - tl_object_ptr rule) { - CHECK(rule != nullptr); - UserPrivacySettingRule result(*rule); - auto td = G()->td().get_actor_unsafe(); - for (auto user_id : result.user_ids_) { - if (!td->contacts_manager_->have_user(user_id)) { - return Status::Error(500, "Receive inaccessible user from the server"); + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); } - } - for (auto chat_id_int : result.chat_ids_) { - ChatId chat_id(chat_id_int); - DialogId dialog_id(chat_id); - if (!td->contacts_manager_->have_chat(chat_id)) { - ChannelId channel_id(chat_id_int); - dialog_id = DialogId(channel_id); - if (!td->contacts_manager_->have_channel(channel_id)) { - return Status::Error(500, "Receive inaccessible chat from the server"); - } - } - td->messages_manager_->force_create_dialog(dialog_id, "UserPrivacySettingRule"); - } - return result; -} - -vector> PrivacyManager::UserPrivacySettingRule::get_input_users() const { - vector> result; - for (auto user_id : user_ids_) { - auto r_input_user = G()->td().get_actor_unsafe()->contacts_manager_->get_input_user(user_id); - if (r_input_user.is_ok()) { - result.push_back(r_input_user.move_as_ok()); - } else { - LOG(ERROR) << "Have no access to " << user_id; - } - } - return result; -} - -vector PrivacyManager::UserPrivacySettingRule::chat_ids_as_dialog_ids() const { - vector result; - auto td = G()->td().get_actor_unsafe(); - for (auto chat_id_int : chat_ids_) { - ChatId chat_id(chat_id_int); - DialogId dialog_id(chat_id); - if (!td->contacts_manager_->have_chat(chat_id)) { - ChannelId channel_id(chat_id_int); - dialog_id = DialogId(channel_id); - CHECK(td->contacts_manager_->have_channel(channel_id)); - } - CHECK(td->messages_manager_->have_dialog(dialog_id)); - result.push_back(td->messages_manager_->get_chat_id_object(dialog_id, "UserPrivacySettingRule")); - } - return result; -} - -vector PrivacyManager::UserPrivacySettingRule::get_restricted_user_ids() const { - if (type_ == Type::RestrictUsers) { - return user_ids_; - } - return {}; -} - -Result PrivacyManager::UserPrivacySettingRules::get_user_privacy_setting_rules( - tl_object_ptr rules) { - G()->td().get_actor_unsafe()->contacts_manager_->on_get_users(std::move(rules->users_), "on get privacy rules"); - G()->td().get_actor_unsafe()->contacts_manager_->on_get_chats(std::move(rules->chats_), "on get privacy rules"); - return get_user_privacy_setting_rules(std::move(rules->rules_)); -} -Result PrivacyManager::UserPrivacySettingRules::get_user_privacy_setting_rules( - vector> rules) { - UserPrivacySettingRules result; - for (auto &rule : rules) { - TRY_RESULT(new_rule, UserPrivacySettingRule::get_user_privacy_setting_rule(std::move(rule))); - result.rules_.push_back(new_rule); - } - if (!result.rules_.empty() && result.rules_.back().get_user_privacy_setting_rule_object()->get_id() == - td_api::userPrivacySettingRuleRestrictAll::ID) { - result.rules_.pop_back(); + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SetPrivacyQuery: " << to_string(ptr); + promise_.set_value(UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(ptr))); } - return result; -} -Result PrivacyManager::UserPrivacySettingRules::get_user_privacy_setting_rules( - tl_object_ptr rules) { - if (rules == nullptr) { - return Status::Error(400, "UserPrivacySettingRules must be non-empty"); - } - UserPrivacySettingRules result; - for (auto &rule : rules->rules_) { - if (rule == nullptr) { - return Status::Error(400, "UserPrivacySettingRule must be non-empty"); - } - result.rules_.emplace_back(*rule); + void on_error(Status status) final { + promise_.set_error(std::move(status)); } - return result; -} +}; -tl_object_ptr -PrivacyManager::UserPrivacySettingRules::get_user_privacy_setting_rules_object() const { - return make_tl_object( - transform(rules_, [](const auto &rule) { return rule.get_user_privacy_setting_rule_object(); })); +PrivacyManager::PrivacyManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { } -vector> PrivacyManager::UserPrivacySettingRules::get_input_privacy_rules() - const { - auto result = transform(rules_, [](const auto &rule) { return rule.get_input_privacy_rule(); }); - if (!result.empty() && result.back()->get_id() == telegram_api::inputPrivacyValueDisallowAll::ID) { - result.pop_back(); - } - return result; -} - -vector PrivacyManager::UserPrivacySettingRules::get_restricted_user_ids() const { - vector result; - for (auto &rule : rules_) { - combine(result, rule.get_restricted_user_ids()); - } - std::sort(result.begin(), result.end(), [](UserId lhs, UserId rhs) { return lhs.get() < rhs.get(); }); - result.erase(std::unique(result.begin(), result.end()), result.end()); - return result; +void PrivacyManager::tear_down() { + parent_.reset(); } void PrivacyManager::get_privacy(tl_object_ptr key, @@ -431,81 +94,69 @@ void PrivacyManager::get_privacy(tl_object_ptr key, } auto user_privacy_setting = r_user_privacy_setting.move_as_ok(); auto &info = get_info(user_privacy_setting); - if (info.is_synchronized) { - return promise.set_value(info.rules.get_user_privacy_setting_rules_object()); + if (info.is_synchronized_) { + return promise.set_value(info.rules_.get_user_privacy_setting_rules_object(td_)); } - info.get_promises.push_back(std::move(promise)); - if (info.get_promises.size() > 1u) { + info.get_promises_.push_back(std::move(promise)); + if (info.get_promises_.size() > 1u) { // query has already been sent, just wait for the result return; } - auto net_query = - G()->net_query_creator().create(telegram_api::account_getPrivacy(user_privacy_setting.get_input_privacy_key())); - - send_with_promise(std::move(net_query), - PromiseCreator::lambda([this, user_privacy_setting](Result x_net_query) { - on_get_result(user_privacy_setting, [&]() -> Result { - TRY_RESULT(net_query, std::move(x_net_query)); - TRY_RESULT(rules, fetch_result(std::move(net_query))); - LOG(INFO) << "Receive " << to_string(rules); - return UserPrivacySettingRules::get_user_privacy_setting_rules(std::move(rules)); - }()); - })); + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), user_privacy_setting](Result r_privacy_rules) { + send_closure(actor_id, &PrivacyManager::on_get_user_privacy_settings, user_privacy_setting, + std::move(r_privacy_rules)); + }); + td_->create_handler(std::move(query_promise))->send(user_privacy_setting); } void PrivacyManager::set_privacy(tl_object_ptr key, tl_object_ptr rules, Promise promise) { TRY_RESULT_PROMISE(promise, user_privacy_setting, UserPrivacySetting::get_user_privacy_setting(std::move(key))); - TRY_RESULT_PROMISE(promise, privacy_rules, UserPrivacySettingRules::get_user_privacy_setting_rules(std::move(rules))); + TRY_RESULT_PROMISE(promise, privacy_rules, + UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(rules))); auto &info = get_info(user_privacy_setting); - if (info.has_set_query) { - // TODO cancel previous query - return promise.set_error(Status::Error(400, "Another set_privacy query is active")); + if (info.has_set_query_) { + info.pending_rules_ = std::move(privacy_rules); + info.set_promises_.push_back(std::move(promise)); + return; } - auto net_query = G()->net_query_creator().create(telegram_api::account_setPrivacy( - user_privacy_setting.get_input_privacy_key(), privacy_rules.get_input_privacy_rules())); - - info.has_set_query = true; - send_with_promise( - std::move(net_query), PromiseCreator::lambda([this, user_privacy_setting, promise = std::move(promise)]( - Result x_net_query) mutable { - promise.set_result([&]() -> Result { - get_info(user_privacy_setting).has_set_query = false; - TRY_RESULT(net_query, std::move(x_net_query)); - TRY_RESULT(rules, fetch_result(std::move(net_query))); - LOG(INFO) << "Receive " << to_string(rules); - TRY_RESULT(privacy_rules, UserPrivacySettingRules::get_user_privacy_setting_rules(std::move(rules))); - do_update_privacy(user_privacy_setting, std::move(privacy_rules), true); - return Unit(); - }()); - })); + info.has_set_query_ = true; + + set_privacy_impl(user_privacy_setting, std::move(privacy_rules), std::move(promise)); } -void PrivacyManager::update_privacy(tl_object_ptr update) { +void PrivacyManager::set_privacy_impl(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules, + Promise &&promise) { + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), user_privacy_setting, + promise = std::move(promise)](Result r_privacy_rules) mutable { + send_closure(actor_id, &PrivacyManager::on_set_user_privacy_settings, user_privacy_setting, + std::move(r_privacy_rules), std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(user_privacy_setting, std::move(privacy_rules)); +} + +void PrivacyManager::on_update_privacy(tl_object_ptr update) { CHECK(update != nullptr); CHECK(update->key_ != nullptr); UserPrivacySetting user_privacy_setting(*update->key_); - auto r_privacy_rules = UserPrivacySettingRules::get_user_privacy_setting_rules(std::move(update->rules_)); - if (r_privacy_rules.is_error()) { - LOG(INFO) << "Skip updatePrivacy: " << r_privacy_rules.error().message(); - auto &info = get_info(user_privacy_setting); - info.is_synchronized = false; - } else { - do_update_privacy(user_privacy_setting, r_privacy_rules.move_as_ok(), true); - } + auto privacy_rules = UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(update->rules_)); + do_update_privacy(user_privacy_setting, std::move(privacy_rules), true); } -void PrivacyManager::on_get_result(UserPrivacySetting user_privacy_setting, - Result r_privacy_rules) { +void PrivacyManager::on_get_user_privacy_settings(UserPrivacySetting user_privacy_setting, + Result r_privacy_rules) { + G()->ignore_result_if_closing(r_privacy_rules); auto &info = get_info(user_privacy_setting); - auto promises = std::move(info.get_promises); - reset_to_empty(info.get_promises); + auto promises = std::move(info.get_promises_); + reset_to_empty(info.get_promises_); for (auto &promise : promises) { if (r_privacy_rules.is_error()) { promise.set_error(r_privacy_rules.error().clone()); } else { - promise.set_value(r_privacy_rules.ok().get_user_privacy_setting_rules_object()); + promise.set_value(r_privacy_rules.ok().get_user_privacy_setting_rules_object(td_)); } } if (r_privacy_rules.is_ok()) { @@ -513,19 +164,56 @@ void PrivacyManager::on_get_result(UserPrivacySetting user_privacy_setting, } } +void PrivacyManager::on_set_user_privacy_settings(UserPrivacySetting user_privacy_setting, + Result r_privacy_rules, + Promise &&promise) { + if (G()->close_flag()) { + auto &info = get_info(user_privacy_setting); + CHECK(info.has_set_query_); + info.has_set_query_ = false; + auto promises = std::move(info.set_promises_); + fail_promises(promises, Global::request_aborted_error()); + promise.set_error(Global::request_aborted_error()); + return; + } + + auto &info = get_info(user_privacy_setting); + CHECK(info.has_set_query_); + info.has_set_query_ = false; + if (r_privacy_rules.is_error()) { + promise.set_error(r_privacy_rules.move_as_error()); + } else { + do_update_privacy(user_privacy_setting, r_privacy_rules.move_as_ok(), true); + promise.set_value(Unit()); + } + if (!info.set_promises_.empty()) { + info.has_set_query_ = true; + auto join_promise = + PromiseCreator::lambda([promises = std::move(info.set_promises_)](Result &&result) mutable { + if (result.is_ok()) { + set_promises(promises); + } else { + fail_promises(promises, result.move_as_error()); + } + }); + reset_to_empty(info.set_promises_); + set_privacy_impl(user_privacy_setting, std::move(info.pending_rules_), std::move(join_promise)); + } +} + void PrivacyManager::do_update_privacy(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules, bool from_update) { auto &info = get_info(user_privacy_setting); - bool was_synchronized = info.is_synchronized; - info.is_synchronized = true; + bool was_synchronized = info.is_synchronized_; + info.is_synchronized_ = true; - if (!(info.rules == privacy_rules)) { - if ((from_update || was_synchronized) && !G()->close_flag()) { + if (!(info.rules_ == privacy_rules)) { + if (!G()->close_flag() && (from_update || was_synchronized)) { switch (user_privacy_setting.type()) { case UserPrivacySetting::Type::UserStatus: { - send_closure_later(G()->contacts_manager(), &ContactsManager::on_update_online_status_privacy); + send_closure_later(G()->user_manager(), &UserManager::on_update_online_status_privacy); - auto old_restricted = info.rules.get_restricted_user_ids(); + auto old_restricted = info.rules_.get_restricted_user_ids(); auto new_restricted = privacy_rules.get_restricted_user_ids(); if (old_restricted != new_restricted) { // if a user was unrestricted, it is not received from the server anymore @@ -535,41 +223,26 @@ void PrivacyManager::do_update_privacy(UserPrivacySetting user_privacy_setting, new_restricted.end(), std::back_inserter(unrestricted), [](UserId lhs, UserId rhs) { return lhs.get() < rhs.get(); }); for (auto &user_id : unrestricted) { - send_closure_later(G()->contacts_manager(), &ContactsManager::reload_user, user_id, Promise()); + send_closure_later(G()->user_manager(), &UserManager::reload_user, user_id, Promise(), + "do_update_privacy"); } } break; } case UserPrivacySetting::Type::UserPhoneNumber: - send_closure_later(G()->contacts_manager(), &ContactsManager::on_update_phone_number_privacy); + send_closure_later(G()->user_manager(), &UserManager::on_update_phone_number_privacy); break; default: break; } } - info.rules = std::move(privacy_rules); + info.rules_ = std::move(privacy_rules); send_closure( G()->td(), &Td::send_update, make_tl_object(user_privacy_setting.get_user_privacy_setting_object(), - info.rules.get_user_privacy_setting_rules_object())); + info.rules_.get_user_privacy_setting_rules_object(td_))); } } -void PrivacyManager::on_result(NetQueryPtr query) { - auto token = get_link_token(); - container_.extract(token).set_value(std::move(query)); -} - -void PrivacyManager::send_with_promise(NetQueryPtr query, Promise promise) { - auto id = container_.create(std::move(promise)); - G()->net_query_dispatcher().dispatch_with_callback(std::move(query), actor_shared(this, id)); -} - -void PrivacyManager::hangup() { - container_.for_each( - [](auto id, Promise &promise) { promise.set_error(Global::request_aborted_error()); }); - stop(); -} - } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PrivacyManager.h b/protocols/Telegram/tdlib/td/td/telegram/PrivacyManager.h index c0bda46466..fd8e0d379e 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PrivacyManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/PrivacyManager.h @@ -1,20 +1,19 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once -#include "td/telegram/net/NetQuery.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" -#include "td/telegram/UserId.h" +#include "td/telegram/UserPrivacySetting.h" +#include "td/telegram/UserPrivacySettingRule.h" #include "td/actor/actor.h" #include "td/utils/common.h" -#include "td/utils/Container.h" #include "td/utils/Promise.h" #include "td/utils/Status.h" @@ -22,10 +21,11 @@ namespace td { -class PrivacyManager final : public NetQueryCallback { +class Td; + +class PrivacyManager final : public Actor { public: - explicit PrivacyManager(ActorShared<> parent) : parent_(std::move(parent)) { - } + PrivacyManager(Td *td, ActorShared<> parent); void get_privacy(tl_object_ptr key, Promise> promise); @@ -33,134 +33,40 @@ class PrivacyManager final : public NetQueryCallback { void set_privacy(tl_object_ptr key, tl_object_ptr rules, Promise promise); - void update_privacy(tl_object_ptr update); + void on_update_privacy(tl_object_ptr update); private: - class UserPrivacySetting { - public: - enum class Type : int32 { - UserStatus, - ChatInvite, - Call, - PeerToPeerCall, - LinkInForwardedMessages, - UserProfilePhoto, - UserPhoneNumber, - FindByPhoneNumber, - VoiceMessages, - Size - }; - - explicit UserPrivacySetting(const telegram_api::PrivacyKey &key); - - static Result get_user_privacy_setting(tl_object_ptr key); - - tl_object_ptr get_user_privacy_setting_object() const; - - tl_object_ptr get_input_privacy_key() const; - - Type type() const { - return type_; - } - - private: - Type type_; - - explicit UserPrivacySetting(const td_api::UserPrivacySetting &key); - }; - - class UserPrivacySettingRule { - public: - UserPrivacySettingRule() = default; - - explicit UserPrivacySettingRule(const td_api::UserPrivacySettingRule &rule); - - static Result get_user_privacy_setting_rule(tl_object_ptr rule); - - tl_object_ptr get_user_privacy_setting_rule_object() const; - - tl_object_ptr get_input_privacy_rule() const; - - bool operator==(const UserPrivacySettingRule &other) const { - return type_ == other.type_ && user_ids_ == other.user_ids_ && chat_ids_ == other.chat_ids_; - } - - vector get_restricted_user_ids() const; - - private: - enum class Type : int32 { - AllowContacts, - AllowAll, - AllowUsers, - AllowChatParticipants, - RestrictContacts, - RestrictAll, - RestrictUsers, - RestrictChatParticipants - } type_ = Type::RestrictAll; - - vector user_ids_; - vector chat_ids_; - - vector> get_input_users() const; - - void set_chat_ids(const vector &dialog_ids); - - vector chat_ids_as_dialog_ids() const; - - explicit UserPrivacySettingRule(const telegram_api::PrivacyRule &rule); - }; - - class UserPrivacySettingRules { - public: - UserPrivacySettingRules() = default; - - static Result get_user_privacy_setting_rules( - tl_object_ptr rules); - - static Result get_user_privacy_setting_rules( - vector> rules); - - static Result get_user_privacy_setting_rules( - tl_object_ptr rules); - - tl_object_ptr get_user_privacy_setting_rules_object() const; - - vector> get_input_privacy_rules() const; - - bool operator==(const UserPrivacySettingRules &other) const { - return rules_ == other.rules_; - } - - vector get_restricted_user_ids() const; - - private: - vector rules_; - }; - - ActorShared<> parent_; - struct PrivacyInfo { - UserPrivacySettingRules rules; - vector>> get_promises; - bool has_set_query = false; - bool is_synchronized = false; + UserPrivacySettingRules rules_; + UserPrivacySettingRules pending_rules_; + vector>> get_promises_; + vector> set_promises_; + bool has_set_query_ = false; + bool is_synchronized_ = false; }; - std::array(UserPrivacySetting::Type::Size)> info_; + + void tear_down() final; PrivacyInfo &get_info(UserPrivacySetting key) { return info_[static_cast(key.type())]; } - void on_get_result(UserPrivacySetting user_privacy_setting, Result r_privacy_rules); + void on_get_user_privacy_settings(UserPrivacySetting user_privacy_setting, + Result r_privacy_rules); + + void set_privacy_impl(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules, + Promise &&promise); + + void on_set_user_privacy_settings(UserPrivacySetting user_privacy_setting, + Result r_privacy_rules, Promise &&promise); + void do_update_privacy(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules, bool from_update); - void on_result(NetQueryPtr query) final; - Container> container_; - void send_with_promise(NetQueryPtr query, Promise promise); + std::array(UserPrivacySetting::Type::Size)> info_; - void hangup() final; + Td *td_; + ActorShared<> parent_; }; } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PromoDataManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/PromoDataManager.cpp new file mode 100644 index 0000000000..7f22497e82 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/PromoDataManager.cpp @@ -0,0 +1,148 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/PromoDataManager.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/DialogSource.h" +#include "td/telegram/Global.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/Promise.h" + +namespace td { + +class GetPromoDataQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetPromoDataQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send() { + // we don't poll promo data before authorization + send_query(G()->net_query_creator().create(telegram_api::help_getPromoData())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(result_ptr.move_as_ok()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +PromoDataManager::PromoDataManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void PromoDataManager::tear_down() { + parent_.reset(); +} + +void PromoDataManager::start_up() { + init(); +} + +void PromoDataManager::init() { + if (G()->close_flag()) { + return; + } + if (is_inited_ || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { + return; + } + is_inited_ = true; + + reload_promo_data(); +} + +void PromoDataManager::reload_promo_data() { + if (reloading_promo_data_) { + need_reload_promo_data_ = true; + return; + } + schedule_get_promo_data(0); +} + +void PromoDataManager::schedule_get_promo_data(int32 expires_in) { + if (!is_inited_) { + return; + } + + expires_in = expires_in <= 0 ? 0 : clamp(expires_in, 60, 86400); + LOG(INFO) << "Schedule getPromoData in " << expires_in; + set_timeout_in(expires_in); +} + +void PromoDataManager::timeout_expired() { + if (G()->close_flag() || !is_inited_) { + return; + } + + reloading_promo_data_ = true; + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this)](Result> result) { + send_closure(actor_id, &PromoDataManager::on_get_promo_data, std::move(result), false); + }); + td_->create_handler(std::move(promise))->send(); +} + +void PromoDataManager::on_get_promo_data(Result> r_promo_data, + bool dummy) { + if (G()->close_flag()) { + return; + } + reloading_promo_data_ = false; + + if (r_promo_data.is_error()) { + LOG(ERROR) << "Receive error for GetPromoData: " << r_promo_data.error(); + return schedule_get_promo_data(60); + } + + auto promo_data_ptr = r_promo_data.move_as_ok(); + CHECK(promo_data_ptr != nullptr); + LOG(DEBUG) << "Receive " << to_string(promo_data_ptr); + int32 expires_at = 0; + switch (promo_data_ptr->get_id()) { + case telegram_api::help_promoDataEmpty::ID: { + auto promo = telegram_api::move_object_as(promo_data_ptr); + expires_at = promo->expires_; + td_->messages_manager_->remove_sponsored_dialog(); + break; + } + case telegram_api::help_promoData::ID: { + auto promo = telegram_api::move_object_as(promo_data_ptr); + expires_at = promo->expires_; + bool is_proxy = promo->proxy_; + td_->messages_manager_->on_get_sponsored_dialog( + std::move(promo->peer_), + is_proxy ? DialogSource::mtproto_proxy() + : DialogSource::public_service_announcement(promo->psa_type_, promo->psa_message_), + std::move(promo->users_), std::move(promo->chats_)); + break; + } + default: + UNREACHABLE(); + } + if (need_reload_promo_data_) { + need_reload_promo_data_ = false; + expires_at = 0; + } + schedule_get_promo_data(expires_at == 0 ? 0 : expires_at - G()->unix_time()); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PromoDataManager.h b/protocols/Telegram/tdlib/td/td/telegram/PromoDataManager.h new file mode 100644 index 0000000000..e749477da2 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/PromoDataManager.h @@ -0,0 +1,47 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/telegram_api.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" + +namespace td { + +class Td; + +class PromoDataManager final : public Actor { + public: + PromoDataManager(Td *td, ActorShared<> parent); + + void init(); + + void reload_promo_data(); + + private: + void tear_down() final; + + void start_up() final; + + void timeout_expired() final; + + void on_get_promo_data(Result> r_promo_data, bool dummy); + + void schedule_get_promo_data(int32 expires_in); + + Td *td_; + ActorShared<> parent_; + + bool is_inited_ = false; + bool reloading_promo_data_ = false; + bool need_reload_promo_data_ = false; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/PublicDialogType.h b/protocols/Telegram/tdlib/td/td/telegram/PublicDialogType.h index 5d6ec6608e..a6bbd88440 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/PublicDialogType.h +++ b/protocols/Telegram/tdlib/td/td/telegram/PublicDialogType.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ namespace td { -enum class PublicDialogType : int32 { HasUsername, IsLocationBased }; +enum class PublicDialogType : int32 { HasUsername, IsLocationBased, ForPersonalDialog }; inline PublicDialogType get_public_dialog_type(const td_api::object_ptr &type) { if (type == nullptr || type->get_id() == td_api::publicChatTypeHasUsername::ID) { diff --git a/protocols/Telegram/tdlib/td/td/telegram/QueryMerger.cpp b/protocols/Telegram/tdlib/td/td/telegram/QueryMerger.cpp index 850ca1ee69..c1d3dd5654 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/QueryMerger.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/QueryMerger.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,8 +15,8 @@ QueryMerger::QueryMerger(Slice name, size_t max_concurrent_query_count, size_t m register_actor(name, this).release(); } -void QueryMerger::add_query(int64 query_id, Promise &&promise) { - LOG(INFO) << "Add query " << query_id << " with" << (promise ? "" : "out") << " promise"; +void QueryMerger::add_query(int64 query_id, Promise &&promise, const char *source) { + LOG(INFO) << "Add query " << query_id << " with" << (promise ? "" : "out") << " promise from " << source; CHECK(query_id != 0); auto &query = queries_[query_id]; query.promises_.push_back(std::move(promise)); diff --git a/protocols/Telegram/tdlib/td/td/telegram/QueryMerger.h b/protocols/Telegram/tdlib/td/td/telegram/QueryMerger.h index e87f816666..49dde4c0c5 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/QueryMerger.h +++ b/protocols/Telegram/tdlib/td/td/telegram/QueryMerger.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -29,7 +29,7 @@ class QueryMerger final : public Actor { merge_function_ = std::move(merge_function); } - void add_query(int64 query_id, Promise &&promise); + void add_query(int64 query_id, Promise &&promise, const char *source); private: struct QueryInfo { diff --git a/protocols/Telegram/tdlib/td/td/telegram/QuickReplyManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/QuickReplyManager.cpp new file mode 100644 index 0000000000..304400e07d --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/QuickReplyManager.cpp @@ -0,0 +1,3737 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/QuickReplyManager.h" + +#include "td/telegram/AccessRights.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/FileReferenceManager.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/files/FileType.h" +#include "td/telegram/Global.h" +#include "td/telegram/InlineQueriesManager.h" +#include "td/telegram/logevent/LogEvent.h" +#include "td/telegram/logevent/LogEventHelper.h" +#include "td/telegram/MessageContent.h" +#include "td/telegram/MessageContentType.h" +#include "td/telegram/MessageCopyOptions.h" +#include "td/telegram/MessageInputReplyTo.h" +#include "td/telegram/MessageQuote.h" +#include "td/telegram/MessageReplyHeader.h" +#include "td/telegram/MessageSelfDestructType.h" +#include "td/telegram/misc.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/ReplyMarkup.h" +#include "td/telegram/ReplyMarkup.hpp" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" +#include "td/telegram/Version.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/format.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/Random.h" +#include "td/utils/Time.h" +#include "td/utils/tl_helpers.h" +#include "td/utils/unicode.h" +#include "td/utils/utf8.h" + +#include +#include +#include + +namespace td { + +class GetQuickRepliesQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetQuickRepliesQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(int64 hash) { + send_query(G()->net_query_creator().create(telegram_api::messages_getQuickReplies(hash), {{"quick_reply"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetQuickRepliesQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class EditQuickReplyShortcutQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit EditQuickReplyShortcutQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(QuickReplyShortcutId shortcut_id, const string &name) { + send_query(G()->net_query_creator().create(telegram_api::messages_editQuickReplyShortcut(shortcut_id.get(), name), + {{"quick_reply"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class DeleteQuickReplyShortcutQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit DeleteQuickReplyShortcutQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(QuickReplyShortcutId shortcut_id) { + send_query(G()->net_query_creator().create(telegram_api::messages_deleteQuickReplyShortcut(shortcut_id.get()), + {{"quick_reply"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->quick_reply_manager_->reload_quick_reply_shortcuts(); + promise_.set_error(std::move(status)); + } +}; + +class ReorderQuickRepliesQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ReorderQuickRepliesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(vector shortcut_ids) { + send_query( + G()->net_query_creator().create(telegram_api::messages_reorderQuickReplies( + QuickReplyShortcutId::get_input_quick_reply_shortcut_ids(shortcut_ids)), + {{"quick_reply"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->quick_reply_manager_->reload_quick_reply_shortcuts(); + promise_.set_error(std::move(status)); + } +}; + +class GetQuickReplyMessagesQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetQuickReplyMessagesQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(QuickReplyShortcutId shortcut_id, const vector &message_ids, int64 hash) { + int32 flags = 0; + if (!message_ids.empty()) { + flags |= telegram_api::messages_getQuickReplyMessages::ID_MASK; + } + CHECK(shortcut_id.is_server()); + send_query(G()->net_query_creator().create( + telegram_api::messages_getQuickReplyMessages(flags, shortcut_id.get(), + MessageId::get_server_message_ids(message_ids), hash), + {{"quick_reply"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetQuickReplyMessagesQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class DeleteQuickReplyMessagesQuery final : public Td::ResultHandler { + Promise promise_; + QuickReplyShortcutId shortcut_id_; + + public: + explicit DeleteQuickReplyMessagesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(QuickReplyShortcutId shortcut_id, const vector &message_ids) { + shortcut_id_ = shortcut_id; + CHECK(shortcut_id.is_server()); + send_query(G()->net_query_creator().create(telegram_api::messages_deleteQuickReplyMessages( + shortcut_id.get(), MessageId::get_server_message_ids(message_ids)), + {{"quick_reply"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->quick_reply_manager_->reload_quick_reply_messages(shortcut_id_, Promise()); + promise_.set_error(std::move(status)); + } +}; + +class QuickReplyManager::SendQuickReplyMessageQuery final : public Td::ResultHandler { + int64 random_id_; + QuickReplyShortcutId shortcut_id_; + + public: + void send(const QuickReplyMessage *m) { + random_id_ = m->random_id; + shortcut_id_ = m->shortcut_id; + + int32 flags = telegram_api::messages_sendMessage::QUICK_REPLY_SHORTCUT_MASK; + if (m->disable_web_page_preview) { + flags |= telegram_api::messages_sendMessage::NO_WEBPAGE_MASK; + } + if (m->invert_media) { + flags |= telegram_api::messages_sendMessage::INVERT_MEDIA_MASK; + } + auto reply_to = + MessageInputReplyTo(m->reply_to_message_id, DialogId(), MessageQuote()).get_input_reply_to(td_, MessageId()); + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendMessage::REPLY_TO_MASK; + } + CHECK(m->edited_content == nullptr); + const FormattedText *message_text = get_message_content_text(m->content.get()); + CHECK(message_text != nullptr); + auto entities = get_input_message_entities(td_->user_manager_.get(), message_text, "SendQuickReplyMessageQuery"); + if (!entities.empty()) { + flags |= telegram_api::messages_sendMessage::ENTITIES_MASK; + } + + send_query(G()->net_query_creator().create( + telegram_api::messages_sendMessage( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, telegram_api::make_object(), + std::move(reply_to), message_text->text, m->random_id, nullptr, std::move(entities), 0, nullptr, + td_->quick_reply_manager_->get_input_quick_reply_shortcut(m->shortcut_id), 0), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendQuickReplyMessageQuery for " << random_id_ << ": " << to_string(ptr); + td_->quick_reply_manager_->process_send_quick_reply_updates(shortcut_id_, std::move(ptr), {random_id_}); + } + + void on_error(Status status) final { + if (G()->close_flag()) { + // do not send error, message will be re-sent after restart + return; + } + LOG(INFO) << "Receive error for SendQuickReplyMessageQuery: " << status; + td_->quick_reply_manager_->on_failed_send_quick_reply_messages(shortcut_id_, {random_id_}, std::move(status)); + } +}; + +class QuickReplyManager::SendQuickReplyInlineMessageQuery final : public Td::ResultHandler { + int64 random_id_; + QuickReplyShortcutId shortcut_id_; + + public: + void send(const QuickReplyMessage *m) { + random_id_ = m->random_id; + shortcut_id_ = m->shortcut_id; + + int32 flags = telegram_api::messages_sendInlineBotResult::QUICK_REPLY_SHORTCUT_MASK; + if (m->hide_via_bot) { + flags |= telegram_api::messages_sendInlineBotResult::HIDE_VIA_MASK; + } + auto reply_to = + MessageInputReplyTo(m->reply_to_message_id, DialogId(), MessageQuote()).get_input_reply_to(td_, MessageId()); + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendInlineBotResult::REPLY_TO_MASK; + } + + send_query(G()->net_query_creator().create( + telegram_api::messages_sendInlineBotResult( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + telegram_api::make_object(), std::move(reply_to), m->random_id, + m->inline_query_id, m->inline_result_id, 0, nullptr, + td_->quick_reply_manager_->get_input_quick_reply_shortcut(m->shortcut_id)), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendQuickReplyInlineMessageQuery for " << random_id_ << ": " << to_string(ptr); + td_->quick_reply_manager_->process_send_quick_reply_updates(shortcut_id_, std::move(ptr), {random_id_}); + } + + void on_error(Status status) final { + if (G()->close_flag()) { + // do not send error, message will be re-sent after restart + return; + } + LOG(INFO) << "Receive error for SendQuickReplyInlineMessageQuery: " << status; + td_->quick_reply_manager_->on_failed_send_quick_reply_messages(shortcut_id_, {random_id_}, std::move(status)); + } +}; + +class QuickReplyManager::SendQuickReplyMediaQuery final : public Td::ResultHandler { + int64 random_id_; + QuickReplyShortcutId shortcut_id_; + FileId file_id_; + FileId thumbnail_file_id_; + string file_reference_; + bool was_uploaded_ = false; + bool was_thumbnail_uploaded_ = false; + + public: + void send(FileId file_id, FileId thumbnail_file_id, const QuickReplyMessage *m, + telegram_api::object_ptr &&input_media) { + random_id_ = m->random_id; + shortcut_id_ = m->shortcut_id; + file_id_ = file_id; + thumbnail_file_id_ = thumbnail_file_id; + file_reference_ = FileManager::extract_file_reference(input_media); + was_uploaded_ = FileManager::extract_was_uploaded(input_media); + was_thumbnail_uploaded_ = FileManager::extract_was_thumbnail_uploaded(input_media); + + int32 flags = telegram_api::messages_sendMedia::QUICK_REPLY_SHORTCUT_MASK; + if (m->invert_media) { + flags |= telegram_api::messages_sendMedia::INVERT_MEDIA_MASK; + } + auto reply_to = + MessageInputReplyTo(m->reply_to_message_id, DialogId(), MessageQuote()).get_input_reply_to(td_, MessageId()); + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendMedia::REPLY_TO_MASK; + } + CHECK(m->edited_content == nullptr); + vector> entities; + const FormattedText *message_text = get_message_content_text(m->content.get()); + if (message_text != nullptr) { + entities = get_input_message_entities(td_->user_manager_.get(), message_text, "SendQuickReplyMediaQuery"); + if (!entities.empty()) { + flags |= telegram_api::messages_sendMedia::ENTITIES_MASK; + } + } + + send_query(G()->net_query_creator().create( + telegram_api::messages_sendMedia( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, telegram_api::make_object(), std::move(reply_to), + std::move(input_media), message_text == nullptr ? string() : message_text->text, m->random_id, nullptr, + std::move(entities), 0, nullptr, td_->quick_reply_manager_->get_input_quick_reply_shortcut(m->shortcut_id), + 0), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + if (was_thumbnail_uploaded_) { + CHECK(thumbnail_file_id_.is_valid()); + // always delete partial remote location for the thumbnail, because it can't be reused anyway + td_->file_manager_->delete_partial_remote_location(thumbnail_file_id_); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendQuickReplyMediaQuery for " << random_id_ << ": " << to_string(ptr); + td_->quick_reply_manager_->process_send_quick_reply_updates(shortcut_id_, std::move(ptr), {random_id_}); + } + + void on_error(Status status) final { + if (G()->close_flag()) { + // do not send error, message will be re-sent after restart + return; + } + LOG(INFO) << "Receive error for SendQuickReplyMediaQuery: " << status; + if (was_uploaded_) { + if (was_thumbnail_uploaded_) { + CHECK(thumbnail_file_id_.is_valid()); + // always delete partial remote location for the thumbnail, because it can't be reused anyway + td_->file_manager_->delete_partial_remote_location(thumbnail_file_id_); + } + + CHECK(file_id_.is_valid()); + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + td_->quick_reply_manager_->on_send_message_file_parts_missing(shortcut_id_, random_id_, std::move(bad_parts)); + return; + } else { + td_->file_manager_->delete_partial_remote_location_if_needed(file_id_, status); + } + } else if (FileReferenceManager::is_file_reference_error(status)) { + if (file_id_.is_valid() && !was_uploaded_) { + VLOG(file_references) << "Receive " << status << " for " << file_id_; + td_->file_manager_->delete_file_reference(file_id_, file_reference_); + td_->quick_reply_manager_->on_send_message_file_reference_error(shortcut_id_, random_id_); + return; + } else { + LOG(ERROR) << "Receive file reference error, but file_id = " << file_id_ + << ", was_uploaded = " << was_uploaded_; + } + } + + td_->quick_reply_manager_->on_failed_send_quick_reply_messages(shortcut_id_, {random_id_}, std::move(status)); + } +}; + +class QuickReplyManager::UploadQuickReplyMediaQuery final : public Td::ResultHandler { + int64 random_id_; + QuickReplyShortcutId shortcut_id_; + MessageId message_id_; + FileId file_id_; + FileId thumbnail_file_id_; + string file_reference_; + bool was_uploaded_ = false; + bool was_thumbnail_uploaded_ = false; + + public: + void send(FileId file_id, FileId thumbnail_file_id, const QuickReplyMessage *m, + telegram_api::object_ptr &&input_media) { + random_id_ = m->random_id; + shortcut_id_ = m->shortcut_id; + message_id_ = m->message_id; + file_id_ = file_id; + thumbnail_file_id_ = thumbnail_file_id; + file_reference_ = FileManager::extract_file_reference(input_media); + was_uploaded_ = FileManager::extract_was_uploaded(input_media); + was_thumbnail_uploaded_ = FileManager::extract_was_thumbnail_uploaded(input_media); + + int32 flags = 0; + send_query(G()->net_query_creator().create(telegram_api::messages_uploadMedia( + flags, string(), telegram_api::make_object(), std::move(input_media)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + if (was_thumbnail_uploaded_) { + CHECK(thumbnail_file_id_.is_valid()); + // always delete partial remote location for the thumbnail, because it can't be reused anyway + td_->file_manager_->delete_partial_remote_location(thumbnail_file_id_); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for UploadQuickReplyMediaQuery: " << to_string(ptr); + td_->quick_reply_manager_->on_upload_message_media_success(shortcut_id_, message_id_, file_id_, std::move(ptr)); + } + + void on_error(Status status) final { + if (G()->close_flag()) { + // do not send error, message will be re-sent after restart + return; + } + LOG(INFO) << "Receive error for UploadQuickReplyMediaQuery: " << status; + if (was_uploaded_) { + if (was_thumbnail_uploaded_) { + CHECK(thumbnail_file_id_.is_valid()); + // always delete partial remote location for the thumbnail, because it can't be reused anyway + td_->file_manager_->delete_partial_remote_location(thumbnail_file_id_); + } + + CHECK(file_id_.is_valid()); + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + td_->quick_reply_manager_->on_send_message_file_parts_missing(shortcut_id_, random_id_, std::move(bad_parts)); + return; + } else { + td_->file_manager_->delete_partial_remote_location_if_needed(file_id_, status); + } + } else if (FileReferenceManager::is_file_reference_error(status)) { + LOG(ERROR) << "Receive file reference error for UploadMediaQuery"; + } + + td_->quick_reply_manager_->on_upload_message_media_fail(shortcut_id_, message_id_, std::move(status)); + } +}; + +class QuickReplyManager::SendQuickReplyMultiMediaQuery final : public Td::ResultHandler { + vector file_ids_; + vector file_references_; + vector random_ids_; + QuickReplyShortcutId shortcut_id_; + + public: + void send(QuickReplyShortcutId shortcut_id, MessageId reply_to_message_id, bool invert_media, + vector &&random_ids, vector &&file_ids, + vector> &&input_single_media) { + for (auto &single_media : input_single_media) { + CHECK(FileManager::extract_was_uploaded(single_media->media_) == false); + file_references_.push_back(FileManager::extract_file_reference(single_media->media_)); + } + shortcut_id_ = shortcut_id; + file_ids_ = std::move(file_ids); + random_ids_ = std::move(random_ids); + CHECK(file_ids_.size() == random_ids_.size()); + + int32 flags = telegram_api::messages_sendMultiMedia::QUICK_REPLY_SHORTCUT_MASK; + auto reply_to = + MessageInputReplyTo(reply_to_message_id, DialogId(), MessageQuote()).get_input_reply_to(td_, MessageId()); + if (reply_to != nullptr) { + flags |= telegram_api::messages_sendMultiMedia::REPLY_TO_MASK; + } + if (invert_media) { + flags |= telegram_api::messages_sendMultiMedia::INVERT_MEDIA_MASK; + } + + send_query(G()->net_query_creator().create( + telegram_api::messages_sendMultiMedia( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, telegram_api::make_object(), std::move(reply_to), + std::move(input_single_media), 0, nullptr, + td_->quick_reply_manager_->get_input_quick_reply_shortcut(shortcut_id_), 0), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendMultiMedia for " << format::as_array(random_ids_) << ": " << to_string(ptr); + td_->quick_reply_manager_->process_send_quick_reply_updates(shortcut_id_, std::move(ptr), std::move(random_ids_)); + } + + void on_error(Status status) final { + if (G()->close_flag()) { + // do not send error, message will be re-sent after restart + return; + } + LOG(INFO) << "Receive error for SendQuickReplyMultiMediaQuery: " << status; + if (FileReferenceManager::is_file_reference_error(status)) { + auto pos = FileReferenceManager::get_file_reference_error_pos(status); + if (1 <= pos && pos <= file_ids_.size() && file_ids_[pos - 1].is_valid()) { + VLOG(file_references) << "Receive " << status << " for " << file_ids_[pos - 1]; + td_->file_manager_->delete_file_reference(file_ids_[pos - 1], file_references_[pos - 1]); + td_->quick_reply_manager_->on_send_media_group_file_reference_error(shortcut_id_, std::move(random_ids_)); + return; + } else { + LOG(ERROR) << "Receive file reference error " << status << ", but file_ids = " << file_ids_ + << ", message_count = " << file_ids_.size(); + } + } + td_->quick_reply_manager_->on_failed_send_quick_reply_messages(shortcut_id_, std::move(random_ids_), + std::move(status)); + } +}; + +class QuickReplyManager::EditQuickReplyMessageQuery final : public Td::ResultHandler { + QuickReplyShortcutId shortcut_id_; + MessageId message_id_; + int64 edit_generation_ = 0; + FileId file_id_; + FileId thumbnail_file_id_; + string file_reference_; + bool was_uploaded_ = false; + bool was_thumbnail_uploaded_ = false; + + public: + void send(FileId file_id, FileId thumbnail_file_id, const QuickReplyMessage *m, + telegram_api::object_ptr &&input_media) { + CHECK(m != nullptr); + CHECK(m->edited_content != nullptr); + CHECK(m->edit_generation > 0); + shortcut_id_ = m->shortcut_id; + message_id_ = m->message_id; + edit_generation_ = m->edit_generation; + file_id_ = file_id; + thumbnail_file_id_ = thumbnail_file_id; + file_reference_ = FileManager::extract_file_reference(input_media); + was_uploaded_ = FileManager::extract_was_uploaded(input_media); + was_thumbnail_uploaded_ = FileManager::extract_was_thumbnail_uploaded(input_media); + + auto *content = m->edited_content.get(); + const auto *text = get_message_content_text(content); + vector> entities; + int32 flags = telegram_api::messages_editMessage::QUICK_REPLY_SHORTCUT_ID_MASK; + if (text != nullptr) { + entities = get_input_message_entities(td_->user_manager_.get(), text, "EditQuickReplyMessageQuery"); + if (!entities.empty()) { + flags |= telegram_api::messages_editMessage::ENTITIES_MASK; + } + flags |= telegram_api::messages_editMessage::MESSAGE_MASK; + } + if (m->edited_invert_media) { + flags |= telegram_api::messages_editMessage::INVERT_MEDIA_MASK; + } + if (m->edited_disable_web_page_preview) { + flags |= telegram_api::messages_editMessage::NO_WEBPAGE_MASK; + } + if (input_media != nullptr) { + flags |= telegram_api::messages_editMessage::MEDIA_MASK; + } + + CHECK(m->shortcut_id.is_server()); + send_query(G()->net_query_creator().create( + telegram_api::messages_editMessage( + flags, false /*ignored*/, false /*ignored*/, telegram_api::make_object(), + m->message_id.get_server_message_id().get(), text != nullptr ? text->text : string(), + std::move(input_media), nullptr, std::move(entities), 0, m->shortcut_id.get()), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + if (was_thumbnail_uploaded_) { + CHECK(thumbnail_file_id_.is_valid()); + // always delete partial remote location for the thumbnail, because it can't be reused anyway + td_->file_manager_->delete_partial_remote_location(thumbnail_file_id_); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for EditQuickReplyMessageQuery: " << to_string(ptr); + td_->quick_reply_manager_->on_edit_quick_reply_message(shortcut_id_, message_id_, edit_generation_, file_id_, + was_uploaded_, std::move(ptr)); + } + + void on_error(Status status) final { + if (G()->close_flag()) { + // do not send error, message will be re-edited after restart + return; + } + if (status.message() == "MESSAGE_NOT_MODIFIED") { + if (was_thumbnail_uploaded_) { + CHECK(thumbnail_file_id_.is_valid()); + // always delete partial remote location for the thumbnail, because it can't be reused anyway + td_->file_manager_->delete_partial_remote_location(thumbnail_file_id_); + } + + return td_->quick_reply_manager_->on_edit_quick_reply_message(shortcut_id_, message_id_, edit_generation_, + file_id_, was_uploaded_, nullptr); + } + td_->quick_reply_manager_->fail_edit_quick_reply_message(shortcut_id_, message_id_, edit_generation_, file_id_, + thumbnail_file_id_, file_reference_, was_uploaded_, + was_thumbnail_uploaded_, std::move(status)); + } +}; + +class QuickReplyManager::UploadMediaCallback final : public FileManager::UploadCallback { + public: + void on_upload_ok(FileId file_id, telegram_api::object_ptr input_file) final { + send_closure_later(G()->quick_reply_manager(), &QuickReplyManager::on_upload_media, file_id, std::move(input_file)); + } + void on_upload_encrypted_ok(FileId file_id, + telegram_api::object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_secure_ok(FileId file_id, telegram_api::object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_error(FileId file_id, Status error) final { + send_closure_later(G()->quick_reply_manager(), &QuickReplyManager::on_upload_media_error, file_id, + std::move(error)); + } +}; + +class QuickReplyManager::UploadThumbnailCallback final : public FileManager::UploadCallback { + public: + void on_upload_ok(FileId file_id, telegram_api::object_ptr input_file) final { + send_closure_later(G()->quick_reply_manager(), &QuickReplyManager::on_upload_thumbnail, file_id, + std::move(input_file)); + } + void on_upload_encrypted_ok(FileId file_id, + telegram_api::object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_secure_ok(FileId file_id, telegram_api::object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_error(FileId file_id, Status error) final { + send_closure_later(G()->quick_reply_manager(), &QuickReplyManager::on_upload_thumbnail, file_id, nullptr); + } +}; + +QuickReplyManager::QuickReplyMessage::~QuickReplyMessage() = default; + +template +void QuickReplyManager::QuickReplyMessage::store(StorerT &storer) const { + bool is_server = message_id.is_server(); + bool has_edit_date = edit_date != 0; + bool has_random_id = !is_server && random_id != 0; + bool has_reply_to_message_id = reply_to_message_id != MessageId(); + bool has_send_emoji = !is_server && !send_emoji.empty(); + bool has_via_bot_user_id = via_bot_user_id != UserId(); + bool has_legacy_layer = legacy_layer != 0; + bool has_send_error_code = !is_server && send_error_code != 0; + bool has_send_error_message = !is_server && !send_error_message.empty(); + bool has_try_resend_at = !is_server && try_resend_at != 0; + bool has_media_album_id = media_album_id != 0; + bool has_reply_markup = reply_markup != nullptr; + bool has_inline_query_id = inline_query_id != 0; + bool has_inline_result_id = !inline_result_id.empty(); + bool has_edited_content = edited_content != nullptr; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_edit_date); + STORE_FLAG(has_random_id); + STORE_FLAG(has_reply_to_message_id); + STORE_FLAG(has_send_emoji); + STORE_FLAG(has_via_bot_user_id); + STORE_FLAG(is_failed_to_send); + STORE_FLAG(disable_notification); + STORE_FLAG(invert_media); + STORE_FLAG(from_background); + STORE_FLAG(disable_web_page_preview); + STORE_FLAG(hide_via_bot); + STORE_FLAG(has_legacy_layer); + STORE_FLAG(has_send_error_code); + STORE_FLAG(has_send_error_message); + STORE_FLAG(has_try_resend_at); + STORE_FLAG(has_media_album_id); + STORE_FLAG(has_reply_markup); + STORE_FLAG(has_inline_query_id); + STORE_FLAG(has_inline_result_id); + STORE_FLAG(has_edited_content); + STORE_FLAG(edited_invert_media); + STORE_FLAG(edited_disable_web_page_preview); + END_STORE_FLAGS(); + td::store(message_id, storer); + td::store(shortcut_id, storer); + if (has_edit_date) { + td::store(edit_date, storer); + } + if (has_random_id) { + td::store(random_id, storer); + } + if (has_reply_to_message_id) { + td::store(reply_to_message_id, storer); + } + if (has_send_emoji) { + td::store(send_emoji, storer); + } + if (has_via_bot_user_id) { + td::store(via_bot_user_id, storer); + } + if (has_legacy_layer) { + td::store(legacy_layer, storer); + } + if (has_send_error_code) { + td::store(send_error_code, storer); + } + if (has_send_error_message) { + td::store(send_error_message, storer); + } + if (has_try_resend_at) { + td::store_time(try_resend_at, storer); + } + if (has_media_album_id) { + td::store(media_album_id, storer); + } + store_message_content(content.get(), storer); + if (has_reply_markup) { + td::store(reply_markup, storer); + } + if (has_inline_query_id) { + td::store(inline_query_id, storer); + } + if (has_inline_result_id) { + td::store(inline_result_id, storer); + } + if (has_edited_content) { + store_message_content(edited_content.get(), storer); + } +} + +template +void QuickReplyManager::QuickReplyMessage::parse(ParserT &parser) { + bool has_edit_date; + bool has_random_id; + bool has_reply_to_message_id; + bool has_send_emoji; + bool has_via_bot_user_id; + bool has_legacy_layer; + bool has_send_error_code; + bool has_send_error_message; + bool has_try_resend_at; + bool has_media_album_id; + bool has_reply_markup; + bool has_inline_query_id; + bool has_inline_result_id; + bool has_edited_content; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_edit_date); + PARSE_FLAG(has_random_id); + PARSE_FLAG(has_reply_to_message_id); + PARSE_FLAG(has_send_emoji); + PARSE_FLAG(has_via_bot_user_id); + PARSE_FLAG(is_failed_to_send); + PARSE_FLAG(disable_notification); + PARSE_FLAG(invert_media); + PARSE_FLAG(from_background); + PARSE_FLAG(disable_web_page_preview); + PARSE_FLAG(hide_via_bot); + PARSE_FLAG(has_legacy_layer); + PARSE_FLAG(has_send_error_code); + PARSE_FLAG(has_send_error_message); + PARSE_FLAG(has_try_resend_at); + PARSE_FLAG(has_media_album_id); + PARSE_FLAG(has_reply_markup); + PARSE_FLAG(has_inline_query_id); + PARSE_FLAG(has_inline_result_id); + PARSE_FLAG(has_edited_content); + PARSE_FLAG(edited_invert_media); + PARSE_FLAG(edited_disable_web_page_preview); + END_PARSE_FLAGS(); + td::parse(message_id, parser); + td::parse(shortcut_id, parser); + if (has_edit_date) { + td::parse(edit_date, parser); + } + if (has_random_id) { + td::parse(random_id, parser); + } + if (has_reply_to_message_id) { + td::parse(reply_to_message_id, parser); + } + if (has_send_emoji) { + td::parse(send_emoji, parser); + } + if (has_via_bot_user_id) { + td::parse(via_bot_user_id, parser); + } + if (has_legacy_layer) { + td::parse(legacy_layer, parser); + } + if (has_send_error_code) { + td::parse(send_error_code, parser); + } + if (has_send_error_message) { + td::parse(send_error_message, parser); + } + if (has_try_resend_at) { + td::parse_time(try_resend_at, parser); + } + if (has_media_album_id) { + td::parse(media_album_id, parser); + } + parse_message_content(content, parser); + if (has_reply_markup) { + td::parse(reply_markup, parser); + } + if (has_inline_query_id) { + td::parse(inline_query_id, parser); + } + if (has_inline_result_id) { + td::parse(inline_result_id, parser); + } + if (has_edited_content) { + parse_message_content(edited_content, parser); + } +} + +QuickReplyManager::Shortcut::~Shortcut() = default; + +template +void QuickReplyManager::Shortcut::store(StorerT &storer) const { + int32 server_total_count = 0; + int32 local_total_count = 0; + for (const auto &message : messages_) { + if (message->message_id.is_server()) { + server_total_count++; + } else { + local_total_count++; + } + } + CHECK(server_total_count <= server_total_count_); + CHECK(local_total_count <= local_total_count_); + + bool has_server_total_count = server_total_count != 0; + bool has_local_total_count = local_total_count != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_server_total_count); + STORE_FLAG(has_local_total_count); + END_STORE_FLAGS(); + td::store(name_, storer); + td::store(shortcut_id_, storer); + if (has_server_total_count) { + td::store(server_total_count, storer); + } + if (has_local_total_count) { + td::store(local_total_count, storer); + } + for (const auto &message : messages_) { + td::store(message, storer); + } +} + +template +void QuickReplyManager::Shortcut::parse(ParserT &parser) { + bool has_server_total_count; + bool has_local_total_count; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_server_total_count); + PARSE_FLAG(has_local_total_count); + END_PARSE_FLAGS(); + td::parse(name_, parser); + td::parse(shortcut_id_, parser); + if (has_server_total_count) { + td::parse(server_total_count_, parser); + } + if (has_local_total_count) { + td::parse(local_total_count_, parser); + } + if (server_total_count_ < 0 || local_total_count_ < 0) { + return parser.set_error("Wrong message count"); + } + auto size = static_cast(server_total_count_) + static_cast(local_total_count_); + if (parser.get_left_len() < size) { + return parser.set_error("Wrong message count"); + } + messages_ = vector>(size); + for (auto &message : messages_) { + td::parse(message, parser); + } +} + +template +void QuickReplyManager::Shortcuts::store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + td::store(shortcuts_, storer); +} + +template +void QuickReplyManager::Shortcuts::parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + td::parse(shortcuts_, parser); +} + +QuickReplyManager::QuickReplyManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { + upload_media_callback_ = std::make_shared(); + upload_thumbnail_callback_ = std::make_shared(); +} + +void QuickReplyManager::tear_down() { + parent_.reset(); +} + +bool QuickReplyManager::is_shortcut_name_letter(uint32 code) { + auto category = get_unicode_simple_category(code); + if (code == '_' || code == 0x200c || code == 0xb7 || (0xd80 <= code && code <= 0xdff)) { + return true; + } + switch (category) { + case UnicodeSimpleCategory::DecimalNumber: + case UnicodeSimpleCategory::Letter: + return true; + default: + return false; + } +} + +Status QuickReplyManager::check_shortcut_name(CSlice name) { + if (!check_utf8(name)) { + return Status::Error("Strings must be encoded in UTF-8"); + } + int32 length = 0; + auto *ptr = name.ubegin(); + while (ptr != name.uend()) { + uint32 code; + ptr = next_utf8_unsafe(ptr, &code); + if (!is_shortcut_name_letter(code)) { + return Status::Error("A letter is not allowed"); + } + length++; + } + if (length == 0) { + return Status::Error("Name must be non-empty"); + } + if (length > 32) { + return Status::Error("Name is too long"); + } + return Status::OK(); +} + +unique_ptr QuickReplyManager::create_message( + telegram_api::object_ptr message_ptr, const char *source) const { + LOG(DEBUG) << "Receive from " << source << " " << to_string(message_ptr); + CHECK(message_ptr != nullptr); + + switch (message_ptr->get_id()) { + case telegram_api::messageEmpty::ID: + break; + case telegram_api::message::ID: { + auto message_id = MessageId::get_message_id(message_ptr, false); + auto message = move_tl_object_as(message_ptr); + auto shortcut_id = QuickReplyShortcutId(message->quick_reply_shortcut_id_); + if (!shortcut_id.is_server()) { + LOG(ERROR) << "Receive invalid quick reply " << shortcut_id << " from " << source; + break; + } + if (!message_id.is_valid() || !message_id.is_server()) { + LOG(ERROR) << "Receive invalid " << message_id << " in quick reply " << shortcut_id << " from " << source; + break; + } + if (deleted_message_full_ids_.count({shortcut_id, message_id})) { + // a previously deleted message + break; + } + + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + if (DialogId(message->peer_id_) != my_dialog_id || message->from_id_ != nullptr || + message->fwd_from_ != nullptr || message->views_ != 0 || message->forwards_ != 0 || + message->replies_ != nullptr || message->reactions_ != nullptr || message->ttl_period_ != 0 || + !message->out_ || message->post_ || message->from_scheduled_ || message->pinned_ || message->noforwards_ || + message->mentioned_ || !message->restriction_reason_.empty() || !message->post_author_.empty() || + message->from_boosts_applied_ != 0 || message->effect_ != 0) { + LOG(ERROR) << "Receive an invalid quick reply from " << source << ": " << to_string(message); + } + if (message->saved_peer_id_ != nullptr) { + LOG(DEBUG) << "Receive unneeded Saved Messages topic in quick reply " << message_id << " from " << source; + } + + UserId via_bot_user_id; + if (message->flags_ & telegram_api::message::VIA_BOT_ID_MASK) { + via_bot_user_id = UserId(message->via_bot_id_); + if (!via_bot_user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << via_bot_user_id << " from " << source; + via_bot_user_id = UserId(); + } + } + auto media_album_id = message->grouped_id_; + + MessageSelfDestructType ttl; + bool disable_web_page_preview = false; + auto content = get_message_content( + td_, + get_message_text(td_->user_manager_.get(), std::move(message->message_), std::move(message->entities_), true, + td_->auth_manager_->is_bot(), 0, media_album_id != 0, source), + std::move(message->media_), my_dialog_id, message->date_, true, via_bot_user_id, &ttl, + &disable_web_page_preview, source); + + auto reply_header = MessageReplyHeader(td_, std::move(message->reply_to_), my_dialog_id, message_id, -1, false); + if (reply_header.story_full_id_ != StoryFullId()) { + LOG(ERROR) << "Receive reply to " << reply_header.story_full_id_; + reply_header.story_full_id_ = {}; + } + if (reply_header.replied_message_info_.is_external() || + reply_header.replied_message_info_.get_reply_message_full_id(DialogId(), true).get_dialog_id() != + DialogId()) { + LOG(ERROR) << "Receive reply to " << reply_header.replied_message_info_; + reply_header.replied_message_info_ = {}; + } + auto reply_to_message_id = reply_header.replied_message_info_.get_same_chat_reply_to_message_id(true); + + if (!ttl.is_empty()) { + LOG(ERROR) << "Wrong " << ttl << " received in " << message_id << " from " << source; + break; + } + + auto content_type = content->get_type(); + if (is_service_message_content(content_type) || content_type == MessageContentType::LiveLocation || + is_expired_message_content(content_type) || content_type == MessageContentType::Poll || + content_type == MessageContentType::PaidMedia) { + LOG(ERROR) << "Receive " << content_type << " from " << source; + break; + } + + auto result = make_unique(); + result->shortcut_id = shortcut_id; + result->message_id = message_id; + result->edit_date = max(message->edit_date_, 0); + result->disable_web_page_preview = disable_web_page_preview; + result->reply_to_message_id = reply_to_message_id; + result->via_bot_user_id = via_bot_user_id; + result->disable_notification = message->silent_; + result->legacy_layer = (message->legacy_ ? MTPROTO_LAYER : 0); + result->invert_media = message->invert_media_; + result->content = std::move(content); + result->reply_markup = + get_reply_markup(std::move(message->reply_markup_), td_->auth_manager_->is_bot(), true, false); + + if (media_album_id != 0) { + if (!is_allowed_media_group_content(content_type)) { + if (content_type != MessageContentType::Unsupported) { + LOG(ERROR) << "Receive media group identifier " << media_album_id << " in " << message_id + << " with content " + << oneline(to_string(get_quick_reply_message_message_content_object(result.get()))); + } + } else { + result->media_album_id = media_album_id; + } + } + + Dependencies dependencies; + add_quick_reply_message_dependencies(dependencies, result.get()); + for (auto dependent_dialog_id : dependencies.get_dialog_ids()) { + td_->dialog_manager_->force_create_dialog(dependent_dialog_id, source, true); + } + + return result; + } + case telegram_api::messageService::ID: + LOG(ERROR) << "Receive " << to_string(message_ptr); + break; + default: + UNREACHABLE(); + break; + } + return nullptr; +} + +void QuickReplyManager::add_quick_reply_message_dependencies(Dependencies &dependencies, + const QuickReplyMessage *m) const { + auto is_bot = td_->auth_manager_->is_bot(); + dependencies.add(m->via_bot_user_id); + add_message_content_dependencies(dependencies, m->content.get(), is_bot); + if (m->edited_content != nullptr) { + add_message_content_dependencies(dependencies, m->edited_content.get(), is_bot); + } + add_reply_markup_dependencies(dependencies, m->reply_markup.get()); +} + +bool QuickReplyManager::can_edit_quick_reply_message(const QuickReplyMessage *m) const { + return m->message_id.is_server() && !m->via_bot_user_id.is_valid() && + is_editable_message_content(m->content->get_type()) && m->content->get_type() != MessageContentType::Game; +} + +bool QuickReplyManager::can_resend_quick_reply_message(const QuickReplyMessage *m) const { + if (m->send_error_code != 429) { + return false; + } + return true; +} + +td_api::object_ptr QuickReplyManager::get_message_sending_state_object( + const QuickReplyMessage *m) const { + CHECK(m != nullptr); + if (m->message_id.is_yet_unsent()) { + return td_api::make_object(0); + } + if (m->is_failed_to_send) { + auto can_retry = can_resend_quick_reply_message(m); + auto error_code = m->send_error_code > 0 ? m->send_error_code : 400; + auto need_another_reply_quote = + can_retry && error_code == 400 && m->send_error_message == CSlice("QUOTE_TEXT_INVALID"); + return td_api::make_object( + td_api::make_object(error_code, m->send_error_message), can_retry, false, + need_another_reply_quote, false, max(m->try_resend_at - Time::now(), 0.0)); + } + return nullptr; +} + +td_api::object_ptr QuickReplyManager::get_quick_reply_message_message_content_object( + const QuickReplyMessage *m) const { + if (m->edited_content != nullptr) { + return get_message_content_object(m->edited_content.get(), td_, DialogId(), false, false, 0, false, true, -1, + m->edited_invert_media, m->edited_disable_web_page_preview); + } + return get_message_content_object(m->content.get(), td_, DialogId(), + m->message_id.is_valid() && m->message_id.is_server(), false, 0, false, true, -1, + m->invert_media, m->disable_web_page_preview); +} + +td_api::object_ptr QuickReplyManager::get_quick_reply_message_object( + const QuickReplyMessage *m, const char *source) const { + CHECK(m != nullptr); + auto can_be_edited = can_edit_quick_reply_message(m); + return td_api::make_object( + m->message_id.get(), get_message_sending_state_object(m), can_be_edited, m->reply_to_message_id.get(), + td_->user_manager_->get_user_id_object(m->via_bot_user_id, "via_bot_user_id"), m->media_album_id, + get_quick_reply_message_message_content_object(m), + get_reply_markup_object(td_->user_manager_.get(), m->reply_markup)); +} + +int32 QuickReplyManager::get_shortcut_message_count(const Shortcut *s) { + return s->server_total_count_ + s->local_total_count_; +} + +bool QuickReplyManager::have_all_shortcut_messages(const Shortcut *s) { + return static_cast(s->messages_.size()) == get_shortcut_message_count(s); +} + +td_api::object_ptr QuickReplyManager::get_quick_reply_shortcut_object( + const Shortcut *s, const char *source) const { + CHECK(s != nullptr); + CHECK(!s->messages_.empty()); + return td_api::make_object(s->shortcut_id_.get(), s->name_, + get_quick_reply_message_object(s->messages_[0].get(), source), + get_shortcut_message_count(s)); +} + +void QuickReplyManager::get_quick_reply_shortcuts(Promise &&promise) { + load_quick_reply_shortcuts(); + if (shortcuts_.are_inited_) { + return promise.set_value(Unit()); + } + + shortcuts_.load_queries_.push_back(std::move(promise)); + if (shortcuts_.load_queries_.size() != 1) { + return; + } + reload_quick_reply_shortcuts(); +} + +void QuickReplyManager::reload_quick_reply_shortcuts() { + if (td_->auth_manager_->is_bot()) { + return; + } + + load_quick_reply_shortcuts(); + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this)](Result> r_shortcuts) { + send_closure(actor_id, &QuickReplyManager::on_reload_quick_reply_shortcuts, std::move(r_shortcuts)); + }); + td_->create_handler(std::move(promise))->send(get_shortcuts_hash()); +} + +void QuickReplyManager::on_reload_quick_reply_shortcuts( + Result> r_shortcuts) { + G()->ignore_result_if_closing(r_shortcuts); + if (r_shortcuts.is_error()) { + return on_load_quick_reply_fail(r_shortcuts.move_as_error()); + } + auto shortcuts_ptr = r_shortcuts.move_as_ok(); + switch (shortcuts_ptr->get_id()) { + case telegram_api::messages_quickRepliesNotModified::ID: + if (!shortcuts_.are_inited_) { + shortcuts_.are_inited_ = true; + save_quick_reply_shortcuts(); + send_update_quick_reply_shortcuts(); + } + break; + case telegram_api::messages_quickReplies::ID: { + auto shortcuts = telegram_api::move_object_as(shortcuts_ptr); + td_->user_manager_->on_get_users(std::move(shortcuts->users_), "messages.quickReplies"); + td_->chat_manager_->on_get_chats(std::move(shortcuts->chats_), "messages.quickReplies"); + + FlatHashMap, MessageIdHash> message_id_to_message; + for (auto &message : shortcuts->messages_) { + auto message_id = MessageId::get_message_id(message, false); + if (!message_id.is_valid()) { + continue; + } + message_id_to_message[message_id] = std::move(message); + } + + FlatHashSet old_shortcut_ids; + for (auto &shortcut : shortcuts_.shortcuts_) { + CHECK(shortcut->shortcut_id_.is_valid()); + old_shortcut_ids.insert(shortcut->shortcut_id_); + } + FlatHashSet added_shortcut_ids; + FlatHashSet added_shortcut_names; + vector> new_shortcuts; + vector changed_shortcut_ids; + vector changed_message_shortcut_ids; + vector deleted_shortcut_ids; + for (auto &quick_reply : shortcuts->quick_replies_) { + auto shortcut_id = QuickReplyShortcutId(quick_reply->shortcut_id_); + if (!shortcut_id.is_server() || quick_reply->shortcut_.empty() || quick_reply->count_ <= 0 || + quick_reply->top_message_ <= 0) { + LOG(ERROR) << "Receive " << to_string(quick_reply); + continue; + } + if (added_shortcut_ids.count(shortcut_id) || added_shortcut_names.count(quick_reply->shortcut_)) { + LOG(ERROR) << "Receive duplicate " << to_string(quick_reply); + continue; + } + if (deleted_shortcut_ids_.count(shortcut_id)) { + continue; + } + added_shortcut_ids.insert(shortcut_id); + added_shortcut_names.insert(quick_reply->shortcut_); + + MessageId first_message_id(ServerMessageId(quick_reply->top_message_)); + auto it = message_id_to_message.find(first_message_id); + if (it == message_id_to_message.end()) { + LOG(ERROR) << "Can't find last " << first_message_id << " in " << shortcut_id; + continue; + } + auto message = create_message(std::move(it->second), "on_reload_quick_reply_shortcuts"); + message_id_to_message.erase(it); + if (message == nullptr) { + continue; + } + if (message->shortcut_id != shortcut_id) { + LOG(ERROR) << "Receive message from " << message->shortcut_id << " instead of " << shortcut_id; + continue; + } + + auto shortcut = td::make_unique(); + shortcut->name_ = std::move(quick_reply->shortcut_); + shortcut->shortcut_id_ = shortcut_id; + shortcut->server_total_count_ = quick_reply->count_; + shortcut->messages_.push_back(std::move(message)); + + auto old_shortcut = get_shortcut(shortcut_id); + if (old_shortcut == nullptr) { + changed_shortcut_ids.push_back(shortcut_id); + changed_message_shortcut_ids.push_back(shortcut_id); + register_new_message(shortcut->messages_[0].get(), "on_reload_quick_reply_shortcuts 1"); + } else { + bool is_shortcut_changed = false; + bool are_messages_changed = false; + update_shortcut_from(shortcut.get(), old_shortcut, true, &is_shortcut_changed, &are_messages_changed); + if (are_messages_changed) { + changed_message_shortcut_ids.push_back(shortcut_id); + } + if (is_shortcut_changed) { + changed_shortcut_ids.push_back(shortcut_id); + } + old_shortcut_ids.erase(shortcut_id); + } + + new_shortcuts.push_back(std::move(shortcut)); + } + for (auto shortcut_id : old_shortcut_ids) { + auto old_shortcut = get_shortcut(shortcut_id); + CHECK(old_shortcut != nullptr); + auto is_changed = td::remove_if(old_shortcut->messages_, [&](const unique_ptr &message) { + if (message->message_id.is_server()) { + delete_message_files(message.get()); + return true; + } + return false; + }); + if (old_shortcut->messages_.empty()) { + CHECK(is_changed); + send_update_quick_reply_shortcut_deleted(old_shortcut); + } else { + // some local messages left + if (added_shortcut_names.count(old_shortcut->name_)) { + LOG(INFO) << "Local shortcut " << old_shortcut->name_ << " has been created server-side"; + for (auto &shortcut : new_shortcuts) { + if (shortcut->name_ == old_shortcut->name_) { + LOG(INFO) << "Move local messages from " << old_shortcut->shortcut_id_ << " to " + << shortcut->shortcut_id_; + CHECK(shortcut->local_total_count_ == 0); + shortcut->local_total_count_ = static_cast(old_shortcut->messages_.size()); + for (auto &message : old_shortcut->messages_) { + CHECK(message->shortcut_id == shortcut_id); + unregister_message_content(message.get(), "on_reload_quick_reply_shortcuts 2"); + message->shortcut_id = shortcut->shortcut_id_; + register_message_content(message.get(), "on_reload_quick_reply_shortcuts 3"); + } + append(shortcut->messages_, std::move(old_shortcut->messages_)); + sort_quick_reply_messages(shortcut->messages_); + send_update_quick_reply_shortcut_deleted(old_shortcut); + changed_shortcut_ids.push_back(shortcut->shortcut_id_); + changed_message_shortcut_ids.push_back(shortcut->shortcut_id_); + persistent_shortcut_ids_[shortcut_id] = shortcut->shortcut_id_; + break; + } + } + continue; + } + + LOG(INFO) << "Keep local shortcut " << old_shortcut->name_; + auto shortcut = td::make_unique(); + shortcut->name_ = std::move(old_shortcut->name_); + shortcut->shortcut_id_ = old_shortcut->shortcut_id_; + shortcut->server_total_count_ = 0; + shortcut->local_total_count_ = static_cast(old_shortcut->messages_.size()); + shortcut->messages_ = std::move(old_shortcut->messages_); + if (is_changed) { + changed_shortcut_ids.push_back(shortcut->shortcut_id_); + changed_message_shortcut_ids.push_back(shortcut->shortcut_id_); + } + new_shortcuts.push_back(std::move(shortcut)); + } + } + bool is_list_changed = is_shortcut_list_changed(new_shortcuts); + shortcuts_.shortcuts_ = std::move(new_shortcuts); + shortcuts_.are_inited_ = true; + + save_quick_reply_shortcuts(); + for (auto shortcut_id : changed_shortcut_ids) { + send_update_quick_reply_shortcut(get_shortcut(shortcut_id), "on_reload_quick_reply_shortcuts"); + } + for (auto shortcut_id : changed_message_shortcut_ids) { + const auto *s = get_shortcut(shortcut_id); + send_update_quick_reply_shortcut_messages(s, "on_reload_quick_reply_shortcuts"); + } + if (is_list_changed) { + send_update_quick_reply_shortcuts(); + } + break; + } + default: + UNREACHABLE(); + } + on_load_quick_reply_success(); +} + +bool QuickReplyManager::is_shortcut_list_changed(const vector> &new_shortcuts) const { + if (!shortcuts_.are_inited_ || shortcuts_.shortcuts_.size() != new_shortcuts.size()) { + return true; + } + for (size_t i = 0; i < new_shortcuts.size(); i++) { + if (shortcuts_.shortcuts_[i]->shortcut_id_ != new_shortcuts[i]->shortcut_id_) { + return true; + } + } + return false; +} + +void QuickReplyManager::on_load_quick_reply_success() { + for (auto &shortcut : shortcuts_.shortcuts_) { + reload_quick_reply_messages(shortcut->shortcut_id_, Auto()); + } + set_promises(shortcuts_.load_queries_); +} + +void QuickReplyManager::on_load_quick_reply_fail(Status error) { + fail_promises(shortcuts_.load_queries_, std::move(error)); +} + +int64 QuickReplyManager::get_shortcuts_hash() const { + vector numbers; + for (auto &shortcut : shortcuts_.shortcuts_) { + for (auto &message : shortcut->messages_) { + if (message->message_id.is_server()) { + CHECK(shortcut->shortcut_id_.is_server()); + numbers.push_back(shortcut->shortcut_id_.get()); + numbers.push_back(get_md5_string_hash(shortcut->name_)); + numbers.push_back(message->message_id.get_server_message_id().get()); + numbers.push_back(message->edit_date); + break; + } + } + } + return get_vector_hash(numbers); +} + +void QuickReplyManager::set_quick_reply_shortcut_name(QuickReplyShortcutId shortcut_id, const string &name, + Promise &&promise) { + load_quick_reply_shortcuts(); + const auto *shortcut = get_shortcut(shortcut_id); + if (shortcut == nullptr) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + if (check_shortcut_name(name).is_error()) { + return promise.set_error(Status::Error(400, "Shortcut name is invalid")); + } + if (!shortcut_id.is_server()) { + return promise.set_error(Status::Error(400, "Shortcut isn't created yet")); + } + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), shortcut_id, name, promise = std::move(promise)](Result &&result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &QuickReplyManager::on_set_quick_reply_shortcut_name, shortcut_id, name, + std::move(promise)); + } else { + promise.set_error(result.move_as_error()); + } + }); + set_quick_reply_shortcut_name_on_server(shortcut_id, name, std::move(query_promise)); +} + +void QuickReplyManager::set_quick_reply_shortcut_name_on_server(QuickReplyShortcutId shortcut_id, const string &name, + Promise &&promise) { + CHECK(shortcut_id.is_server()); + td_->create_handler(std::move(promise))->send(shortcut_id, name); +} + +void QuickReplyManager::on_set_quick_reply_shortcut_name(QuickReplyShortcutId shortcut_id, const string &name, + Promise &&promise) { + auto *shortcut = get_shortcut(shortcut_id); + if (shortcut == nullptr || shortcut->name_ == name) { + return promise.set_value(Unit()); + } + shortcut->name_ = name; + send_update_quick_reply_shortcut(shortcut, "on_set_quick_reply_shortcut_name"); + save_quick_reply_shortcuts(); + promise.set_value(Unit()); +} + +void QuickReplyManager::delete_quick_reply_shortcut(QuickReplyShortcutId shortcut_id, Promise &&promise) { + load_quick_reply_shortcuts(); + auto it = get_shortcut_it(shortcut_id); + if (it == shortcuts_.shortcuts_.end()) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + send_update_quick_reply_shortcut_deleted(it->get()); + shortcuts_.shortcuts_.erase(it); + save_quick_reply_shortcuts(); + send_update_quick_reply_shortcuts(); + + if (!shortcut_id.is_server()) { + return promise.set_value(Unit()); + } + + delete_quick_reply_shortcut_from_server(shortcut_id, std::move(promise)); +} + +void QuickReplyManager::delete_quick_reply_shortcut_from_server(QuickReplyShortcutId shortcut_id, + Promise &&promise) { + CHECK(shortcut_id.is_server()); + + deleted_shortcut_ids_.insert(shortcut_id); + td_->create_handler(std::move(promise))->send(shortcut_id); +} + +void QuickReplyManager::reorder_quick_reply_shortcuts(const vector &shortcut_ids, + Promise &&promise) { + load_quick_reply_shortcuts(); + FlatHashSet unique_shortcut_ids; + for (const auto &shortcut_id : shortcut_ids) { + if (get_shortcut(shortcut_id) == nullptr) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + CHECK(shortcut_id.is_valid()); + unique_shortcut_ids.insert(shortcut_id); + } + if (unique_shortcut_ids.size() != shortcut_ids.size()) { + return promise.set_error(Status::Error(400, "Duplicate shortcut identifiers specified")); + } + if (!shortcuts_.are_inited_) { + return promise.set_value(Unit()); + } + auto old_shortcut_ids = get_shortcut_ids(); + auto old_server_shortcut_ids = get_server_shortcut_ids(); + vector> shortcuts; + for (const auto &shortcut_id : shortcut_ids) { + auto it = get_shortcut_it(shortcut_id); + CHECK(it != shortcuts_.shortcuts_.end() && *it != nullptr); + shortcuts.push_back(std::move(*it)); + } + for (auto &shortcut : shortcuts_.shortcuts_) { + if (shortcut != nullptr) { + CHECK(unique_shortcut_ids.count(shortcut->shortcut_id_) == 0); + shortcuts.push_back(std::move(shortcut)); + } + } + shortcuts_.shortcuts_ = std::move(shortcuts); + if (old_shortcut_ids == get_shortcut_ids()) { + return promise.set_value(Unit()); + } + save_quick_reply_shortcuts(); + send_update_quick_reply_shortcuts(); + + auto new_server_shortcut_ids = get_server_shortcut_ids(); + if (new_server_shortcut_ids == old_server_shortcut_ids) { + return promise.set_value(Unit()); + } + + reorder_quick_reply_shortcuts_on_server(new_server_shortcut_ids, std::move(promise)); +} + +void QuickReplyManager::reorder_quick_reply_shortcuts_on_server(vector shortcut_ids, + Promise &&promise) { + td_->create_handler(std::move(promise))->send(std::move(shortcut_ids)); +} + +void QuickReplyManager::update_quick_reply_message(telegram_api::object_ptr &&message_ptr) { + if (td_->auth_manager_->is_bot()) { + return; + } + + load_quick_reply_shortcuts(); + auto message = create_message(std::move(message_ptr), "update_quick_reply_message"); + if (message == nullptr) { + return; + } + auto shortcut_id = message->shortcut_id; + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return reload_quick_reply_messages(shortcut_id, Promise()); + } + on_get_quick_reply_message(s, std::move(message)); +} + +void QuickReplyManager::on_get_quick_reply_message(Shortcut *s, unique_ptr message) { + CHECK(s->shortcut_id_ == message->shortcut_id); + auto it = get_message_it(s, message->message_id); + if (it == s->messages_.end()) { + register_new_message(message.get(), "on_get_quick_reply_message"); + s->messages_.push_back(std::move(message)); + s->server_total_count_++; + sort_quick_reply_messages(s->messages_); + send_update_quick_reply_shortcut(s, "on_get_quick_reply_message 1"); + } else { + if (get_quick_reply_unique_id(it->get()) == get_quick_reply_unique_id(message.get())) { + return; + } + update_quick_reply_message(*it, std::move(message)); + if (it == s->messages_.begin()) { + send_update_quick_reply_shortcut(s, "on_get_quick_reply_message 2"); + } + } + send_update_quick_reply_shortcut_messages(s, "on_get_quick_reply_message 2"); + save_quick_reply_shortcuts(); +} + +void QuickReplyManager::update_quick_reply_message(unique_ptr &old_message, + unique_ptr &&new_message) { + CHECK(old_message != nullptr); + CHECK(new_message != nullptr); + CHECK(old_message->shortcut_id == new_message->shortcut_id); + CHECK(old_message->message_id == new_message->message_id); + CHECK(old_message->message_id.is_server()); + if (old_message->edit_date > new_message->edit_date) { + LOG(INFO) << "Ignore update of " << old_message->message_id << " from " << old_message->shortcut_id + << " to its old version"; + return; + } + auto old_file_ids = get_message_file_ids(old_message.get()); + new_message->edited_content = std::move(old_message->edited_content); + new_message->edited_invert_media = old_message->edited_invert_media; + new_message->edited_disable_web_page_preview = old_message->edited_disable_web_page_preview; + new_message->edit_generation = old_message->edit_generation; + unregister_message_content(old_message.get(), "update_quick_reply_message"); + old_message = std::move(new_message); + register_message_content(old_message.get(), "update_quick_reply_message"); + change_message_files(old_message.get(), old_file_ids); +} + +void QuickReplyManager::on_external_update_message_content(QuickReplyMessageFullId message_full_id, const char *source, + bool expect_no_message) { + const auto *s = get_shortcut(message_full_id.get_quick_reply_shortcut_id()); + auto message_id = message_full_id.get_message_id(); + const auto *m = get_message(s, message_id); + if (expect_no_message && m == nullptr) { + return; + } + CHECK(m != nullptr); + if (s->messages_[0]->message_id == message_id) { + send_update_quick_reply_shortcut(s, "on_external_update_message_content"); + } + send_update_quick_reply_shortcut_messages(s, "on_external_update_message_content"); + // must not call save_quick_reply_shortcuts, because the message itself wasn't changed +} + +void QuickReplyManager::delete_pending_message_web_page(QuickReplyMessageFullId message_full_id) { + auto *m = get_message_editable(message_full_id); + CHECK(has_message_content_web_page(m->content.get())); + unregister_message_content(m, "delete_pending_message_web_page"); + remove_message_content_web_page(m->content.get()); + register_message_content(m, "delete_pending_message_web_page"); + + // don't need to send updates, because the web page was pending + + save_quick_reply_shortcuts(); +} + +void QuickReplyManager::delete_quick_reply_messages_from_updates(QuickReplyShortcutId shortcut_id, + const vector &message_ids) { + if (td_->auth_manager_->is_bot()) { + return; + } + + load_quick_reply_shortcuts(); + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return; + } + for (auto message_id : message_ids) { + if (!message_id.is_server()) { + LOG(ERROR) << "Receive delete of " << message_ids; + return; + } + } + delete_quick_reply_messages(s, message_ids, "delete_quick_reply_messages_from_updates"); +} + +void QuickReplyManager::delete_quick_reply_messages(Shortcut *s, const vector &message_ids, + const char *source) { + LOG(INFO) << "Delete " << message_ids << " from " << s->shortcut_id_ << " from " << source; + bool is_changed = false; + for (auto &message_id : message_ids) { + auto it = get_message_it(s, message_id); + if (it != s->messages_.end()) { + const auto *m = it->get(); + delete_message_files(m); + if (message_id.is_server()) { + s->server_total_count_--; + } else { + if (m->media_album_id != 0 && m->message_id.is_yet_unsent()) { + send_closure_later(actor_id(this), &QuickReplyManager::on_upload_message_media_finished, m->media_album_id, + m->shortcut_id, m->message_id, Status::OK()); + } + s->local_total_count_--; + } + is_changed = true; + s->messages_.erase(it); + } + if (message_id.is_server()) { + deleted_message_full_ids_.insert({s->shortcut_id_, message_id}); + } + } + if (s->messages_.empty()) { + send_update_quick_reply_shortcut_deleted(s); + shortcuts_.shortcuts_.erase(get_shortcut_it(s->shortcut_id_)); + CHECK(is_changed); + send_update_quick_reply_shortcuts(); + save_quick_reply_shortcuts(); + } else if (is_changed) { + send_update_quick_reply_shortcut(s, source); + send_update_quick_reply_shortcut_messages(s, source); + save_quick_reply_shortcuts(); + } +} + +void QuickReplyManager::delete_quick_reply_shortcut_messages(QuickReplyShortcutId shortcut_id, + const vector &message_ids, + Promise &&promise) { + load_quick_reply_shortcuts(); + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + if (message_ids.empty()) { + return promise.set_value(Unit()); + } + + vector deleted_server_message_ids; + for (auto &message_id : message_ids) { + if (!message_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid message identifier")); + } + + // message_id = get_persistent_message_id(s, message_id); + if (message_id.is_server()) { + deleted_server_message_ids.push_back(message_id); + } + } + + delete_quick_reply_messages_on_server(shortcut_id, std::move(deleted_server_message_ids), std::move(promise)); + + delete_quick_reply_messages(s, message_ids, "delete_quick_reply_shortcut_messages"); +} + +void QuickReplyManager::delete_quick_reply_messages_on_server(QuickReplyShortcutId shortcut_id, + const vector &message_ids, + Promise &&promise) { + if (message_ids.empty()) { + return promise.set_value(Unit()); + } + td_->create_handler(std::move(promise))->send(shortcut_id, message_ids); +} + +telegram_api::object_ptr QuickReplyManager::get_input_quick_reply_shortcut( + QuickReplyShortcutId shortcut_id) const { + if (shortcut_id.is_server()) { + return telegram_api::make_object(shortcut_id.get()); + } + const auto *s = get_shortcut(shortcut_id); + CHECK(s != nullptr); + return telegram_api::make_object(s->name_); +} + +Status QuickReplyManager::check_send_quick_reply_messages_response( + QuickReplyShortcutId shortcut_id, const telegram_api::object_ptr &updates_ptr, + const vector &random_ids) { + if (updates_ptr->get_id() != telegram_api::updates::ID) { + return Status::Error("Receive unexpected updates class"); + } + const auto &updates = static_cast(updates_ptr.get())->updates_; + FlatHashSet sent_random_ids; + for (auto &update : updates) { + if (update->get_id() == telegram_api::updateMessageID::ID) { + auto update_message_id = static_cast(update.get()); + int64 random_id = update_message_id->random_id_; + if (random_id == 0) { + return Status::Error("Receive zero random_id"); + } + if (!sent_random_ids.insert(random_id).second) { + return Status::Error("Receive duplicate random_id"); + } + } + } + if (sent_random_ids.size() != random_ids.size()) { + return Status::Error("Receive duplicate random_id"); + } + for (auto random_id : random_ids) { + if (sent_random_ids.count(random_id) != 1) { + return Status::Error("Don't receive expected random_id"); + } + } + int32 new_shortcut_count = 0; + for (auto &update : updates) { + if (update->get_id() == telegram_api::updateNewQuickReply::ID) { + if (!QuickReplyShortcutId( + static_cast(update.get())->quick_reply_->shortcut_id_) + .is_server()) { + return Status::Error("Receive unexpected new shortcut"); + } + new_shortcut_count++; + } + } + if (new_shortcut_count >= 2 || (new_shortcut_count >= 1 && shortcut_id.is_server())) { + return Status::Error("Receive unexpected number of new shortcuts"); + } + return Status::OK(); +} + +void QuickReplyManager::process_send_quick_reply_updates(QuickReplyShortcutId shortcut_id, + telegram_api::object_ptr updates_ptr, + vector random_ids) { + auto check_status = check_send_quick_reply_messages_response(shortcut_id, updates_ptr, random_ids); + if (check_status.is_error()) { + LOG(ERROR) << check_status << " for sending messages " << random_ids << ": " << to_string(updates_ptr); + on_failed_send_quick_reply_messages(shortcut_id, std::move(random_ids), + Status::Error(500, "Receive wrong response")); + return; + } + + auto updates = telegram_api::move_object_as(updates_ptr); + td_->user_manager_->on_get_users(std::move(updates->users_), "process_send_quick_reply_updates"); + td_->chat_manager_->on_get_chats(std::move(updates->chats_), "process_send_quick_reply_updates"); + + bool is_shortcut_new = false; + if (shortcut_id.is_local()) { + QuickReplyShortcutId new_shortcut_id; + for (auto &update : updates->updates_) { + if (update->get_id() == telegram_api::updateNewQuickReply::ID) { + new_shortcut_id = QuickReplyShortcutId( + static_cast(update.get())->quick_reply_->shortcut_id_); + update = nullptr; + } + } + if (!new_shortcut_id.is_server()) { + for (const auto &update : updates->updates_) { + if (update != nullptr && update->get_id() == telegram_api::updateQuickReplyMessage::ID) { + auto &message = static_cast(update.get())->message_; + if (message->get_id() == telegram_api::message::ID) { + new_shortcut_id = QuickReplyShortcutId( + static_cast(message.get())->quick_reply_shortcut_id_); + break; + } + } + } + } + if (!new_shortcut_id.is_server()) { + LOG(ERROR) << "Failed to find new shortcut identifier for " << shortcut_id; + reload_quick_reply_shortcuts(); + on_failed_send_quick_reply_messages(shortcut_id, std::move(random_ids), + Status::Error(500, "Receive wrong response")); + return; + } + auto it = get_shortcut_it(shortcut_id); + if (it != shortcuts_.shortcuts_.end() && (*it)->shortcut_id_ == shortcut_id) { + send_update_quick_reply_shortcut_deleted(it->get()); + + for (auto &message : (*it)->messages_) { + CHECK(message->shortcut_id == shortcut_id); + unregister_message_content(message.get(), "process_send_quick_reply_updates 1"); + message->shortcut_id = new_shortcut_id; + register_message_content(message.get(), "process_send_quick_reply_updates 1"); + } + + auto *s = get_shortcut(new_shortcut_id); + if (s == nullptr) { + (*it)->shortcut_id_ = new_shortcut_id; + is_shortcut_new = true; + } else { + if ((*it)->last_assigned_message_id_ > s->last_assigned_message_id_) { + s->last_assigned_message_id_ = (*it)->last_assigned_message_id_; + } + for (auto &message : (*it)->messages_) { + CHECK(!message->message_id.is_server()); + s->messages_.push_back(std::move(message)); + s->local_total_count_++; + } + shortcuts_.shortcuts_.erase(it); + } + persistent_shortcut_ids_[shortcut_id] = new_shortcut_id; + } else if (get_shortcut(new_shortcut_id) == nullptr) { + return; + } + shortcut_id = new_shortcut_id; + } + auto *s = get_shortcut(shortcut_id); + CHECK(s != nullptr); + + for (auto &random_id : random_ids) { + for (auto it = s->messages_.begin(); it != s->messages_.end(); ++it) { + if ((*it)->random_id == random_id && (*it)->message_id.is_yet_unsent()) { + MessageId new_message_id; + for (auto &update : updates->updates_) { + if (update != nullptr && update->get_id() == telegram_api::updateMessageID::ID && + static_cast(update.get())->random_id_ == random_id) { + new_message_id = + MessageId(ServerMessageId(static_cast(update.get())->id_)); + update = nullptr; + } + } + if (new_message_id.is_valid()) { + for (auto &update : updates->updates_) { + if (update != nullptr && update->get_id() == telegram_api::updateQuickReplyMessage::ID && + MessageId::get_message_id( + static_cast(update.get())->message_, false) == + new_message_id) { + auto message = create_message( + std::move(static_cast(update.get())->message_), + "process_send_quick_reply_updates"); + if (message != nullptr && message->shortcut_id == shortcut_id) { + update_sent_message_content_from_temporary_message(it->get(), message.get(), false); + unregister_message_content(it->get(), "process_send_quick_reply_updates 2"); + auto old_message_it = get_message_it(s, message->message_id); + if (old_message_it == s->messages_.end()) { + *it = std::move(message); + register_new_message(it->get(), "process_send_quick_reply_updates 2"); + s->server_total_count_++; + } else { + // the message has already been added + update_quick_reply_message(*old_message_it, std::move(message)); + s->messages_.erase(it); + } + s->local_total_count_--; + } + update = nullptr; + break; + } + } + } + + break; + } + } + } + + sort_quick_reply_messages(s->messages_); + send_update_quick_reply_shortcut(s, "process_send_quick_reply_updates"); + send_update_quick_reply_shortcut_messages(s, "process_send_quick_reply_updates"); + if (is_shortcut_new) { + send_update_quick_reply_shortcuts(); + } + save_quick_reply_shortcuts(); +} + +void QuickReplyManager::update_sent_message_content_from_temporary_message(const QuickReplyMessage *old_message, + QuickReplyMessage *new_message, + bool is_edit) { + CHECK(is_edit ? old_message->message_id.is_server() : old_message->message_id.is_yet_unsent()); + CHECK(new_message->edited_content == nullptr); + update_sent_message_content_from_temporary_message(is_edit ? old_message->edited_content : old_message->content, + new_message->content, is_edit || new_message->edit_date == 0); +} + +void QuickReplyManager::update_sent_message_content_from_temporary_message( + const unique_ptr &old_content, unique_ptr &new_content, bool need_merge_files) { + MessageContentType old_content_type = old_content->get_type(); + MessageContentType new_content_type = new_content->get_type(); + + auto old_file_id = get_message_content_any_file_id(old_content.get()); + need_merge_files = need_merge_files && old_file_id.is_valid(); + if (old_content_type != new_content_type) { + if (need_merge_files) { + td_->file_manager_->try_merge_documents(old_file_id, get_message_content_any_file_id(new_content.get())); + } + } else { + bool is_content_changed = false; + bool need_update = false; + merge_message_contents(td_, old_content.get(), new_content.get(), true, DialogId(), need_merge_files, + is_content_changed, need_update); + } + if (old_file_id.is_valid()) { + // the file is likely to be already merged with a server file, but if not we need to + // cancel file upload of the main file to allow next upload with the same file to succeed + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, old_file_id); + + update_message_content_file_id_remote(new_content.get(), old_file_id); + } +} + +void QuickReplyManager::on_failed_send_quick_reply_messages(QuickReplyShortcutId shortcut_id, vector random_ids, + Status error) { + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + // the shortcut was deleted + return; + } + + for (auto &random_id : random_ids) { + for (auto it = s->messages_.begin(); it != s->messages_.end(); ++it) { + if ((*it)->random_id == random_id && (*it)->message_id.is_yet_unsent()) { + auto old_message_id = (*it)->message_id; + auto new_message_id = old_message_id.get_next_message_id(MessageType::Local); + if (get_message_it(s, new_message_id) != s->messages_.end() || + deleted_message_full_ids_.count({shortcut_id, new_message_id})) { + new_message_id = get_next_local_message_id(s); + } else if (new_message_id > s->last_assigned_message_id_) { + s->last_assigned_message_id_ = new_message_id; + } + CHECK(new_message_id.is_valid()); + unregister_message_content(it->get(), "on_failed_send_quick_reply_messages"); + (*it)->message_id = new_message_id; + (*it)->is_failed_to_send = true; + (*it)->send_error_code = error.code(); + (*it)->send_error_message = error.message().str(); + (*it)->try_resend_at = 0.0; + auto retry_after = Global::get_retry_after((*it)->send_error_code, (*it)->send_error_message); + if (retry_after > 0) { + (*it)->try_resend_at = Time::now() + retry_after; + } + CHECK((*it)->edited_content == nullptr); + update_failed_to_send_message_content(td_, (*it)->content); + register_message_content(it->get(), "on_failed_send_quick_reply_messages"); + + break; + } + } + } + + sort_quick_reply_messages(s->messages_); + send_update_quick_reply_shortcut(s, "on_failed_send_quick_reply_messages"); + send_update_quick_reply_shortcut_messages(s, "on_failed_send_quick_reply_messages"); + save_quick_reply_shortcuts(); +} + +Result> QuickReplyManager::send_message( + const string &shortcut_name, MessageId reply_to_message_id, + td_api::object_ptr &&input_message_content) { + TRY_RESULT(message_content, process_input_message_content(std::move(input_message_content))); + TRY_RESULT(s, create_new_local_shortcut(shortcut_name, 1)); + bool is_new = s->messages_.empty(); + reply_to_message_id = get_input_reply_to_message_id(s, reply_to_message_id); + + auto content = dup_message_content(td_, td_->dialog_manager_->get_my_dialog_id(), message_content.content.get(), + MessageContentDupType::Send, MessageCopyOptions()); + auto *m = add_local_message(s, reply_to_message_id, std::move(content), message_content.invert_media, + message_content.via_bot_user_id, false, message_content.disable_web_page_preview, + std::move(message_content.emoji)); + + send_update_quick_reply_shortcut(s, "send_message"); + send_update_quick_reply_shortcut_messages(s, "send_message"); + if (is_new) { + send_update_quick_reply_shortcuts(); + } + save_quick_reply_shortcuts(); + + do_send_message(m); + + return get_quick_reply_message_object(m, "send_message"); +} + +Result> QuickReplyManager::send_inline_query_result_message( + const string &shortcut_name, MessageId reply_to_message_id, int64 query_id, const string &result_id, + bool hide_via_bot) { + const InlineMessageContent *message_content = + td_->inline_queries_manager_->get_inline_message_content(query_id, result_id); + if (message_content == nullptr || query_id == 0) { + return Status::Error(400, "Inline query result not found"); + } + TRY_RESULT(s, create_new_local_shortcut(shortcut_name, 1)); + bool is_new = s->messages_.empty(); + reply_to_message_id = get_input_reply_to_message_id(s, reply_to_message_id); + + UserId via_bot_user_id; + if (!hide_via_bot) { + via_bot_user_id = td_->inline_queries_manager_->get_inline_bot_user_id(query_id); + } + auto content = + dup_message_content(td_, td_->dialog_manager_->get_my_dialog_id(), message_content->message_content.get(), + MessageContentDupType::SendViaBot, MessageCopyOptions()); + auto *m = add_local_message(s, reply_to_message_id, std::move(content), message_content->invert_media, + via_bot_user_id, hide_via_bot, message_content->disable_web_page_preview, string()); + m->reply_markup = dup_reply_markup(message_content->message_reply_markup); + m->inline_query_id = query_id; + m->inline_result_id = result_id; + + send_update_quick_reply_shortcut(s, "send_inline_query_result_message"); + send_update_quick_reply_shortcut_messages(s, "send_inline_query_result_message"); + if (is_new) { + send_update_quick_reply_shortcuts(); + } + save_quick_reply_shortcuts(); + + do_send_message(m); + + return get_quick_reply_message_object(m, "send_inline_query_result_message"); +} + +Result> QuickReplyManager::send_message_group( + const string &shortcut_name, MessageId reply_to_message_id, + vector> &&input_message_contents) { + vector message_contents; + for (auto &input_message_content : input_message_contents) { + TRY_RESULT(message_content, process_input_message_content(std::move(input_message_content))); + message_contents.push_back(std::move(message_content)); + } + TRY_STATUS(check_message_group_message_contents(message_contents)); + + TRY_RESULT(s, create_new_local_shortcut(shortcut_name, static_cast(message_contents.size()))); + bool is_new = s->messages_.empty(); + reply_to_message_id = get_input_reply_to_message_id(s, reply_to_message_id); + + int64 media_album_id = 0; + if (message_contents.size() > 1) { + media_album_id = generate_new_media_album_id(); + } + + vector> messages; + for (auto &message_content : message_contents) { + auto content = dup_message_content(td_, td_->dialog_manager_->get_my_dialog_id(), message_content.content.get(), + MessageContentDupType::Send, MessageCopyOptions()); + auto *m = add_local_message(s, reply_to_message_id, std::move(content), message_content.invert_media, + message_content.via_bot_user_id, false, message_content.disable_web_page_preview, + std::move(message_content.emoji)); + m->media_album_id = media_album_id; + + do_send_message(m); + + messages.push_back(get_quick_reply_message_object(m, "send_message_group")); + } + + send_update_quick_reply_shortcut(s, "send_message_group"); + send_update_quick_reply_shortcut_messages(s, "send_message_group"); + if (is_new) { + send_update_quick_reply_shortcuts(); + } + save_quick_reply_shortcuts(); + + return td_api::make_object(std::move(messages)); +} + +void QuickReplyManager::do_send_message(const QuickReplyMessage *m, vector bad_parts) { + CHECK(m != nullptr); + bool is_edit = m->message_id.is_server(); + auto message_full_id = QuickReplyMessageFullId(m->shortcut_id, m->message_id); + LOG(INFO) << "Do " << (is_edit ? "edit" : "send") << ' ' << message_full_id; + + if (m->media_album_id != 0 && bad_parts.empty() && !is_edit) { + auto &request = pending_message_group_sends_[m->media_album_id]; + request.message_ids.push_back(m->message_id); + request.is_finished.push_back(false); + request.results.push_back(Status::OK()); + } + + auto content = is_edit ? m->edited_content.get() : m->content.get(); + CHECK(content != nullptr); + auto content_type = content->get_type(); + if (content_type == MessageContentType::Unsupported) { + if (is_edit) { + return fail_edit_quick_reply_message(m->shortcut_id, m->message_id, m->edit_generation, FileId(), FileId(), + string(), false, false, Status::Error(400, "Failed to upload file")); + } + return on_failed_send_quick_reply_messages(m->shortcut_id, {m->random_id}, + Status::Error(400, "Failed to upload file")); + } + + if (!is_edit && m->inline_query_id != 0) { + td_->create_handler()->send(m); + return; + } + + if (content_type == MessageContentType::Text) { + if (is_edit) { + td_->create_handler()->send(FileId(), FileId(), m, nullptr); + return; + } + auto input_media = get_message_content_input_media_web_page(td_, content); + if (input_media == nullptr) { + td_->create_handler()->send(m); + } else { + td_->create_handler()->send(FileId(), FileId(), m, std::move(input_media)); + } + return; + } + + FileId file_id = get_message_content_any_file_id(content); // any_file_id, because it could be a photo sent by ID + FileId thumbnail_file_id = get_message_content_thumbnail_file_id(content, td_); + LOG(DEBUG) << "Need to send file " << file_id << " with thumbnail " << thumbnail_file_id; + auto input_media = get_message_content_input_media(content, td_, {}, m->send_emoji, false); + if (input_media == nullptr) { + if (content_type == MessageContentType::Game || content_type == MessageContentType::Story) { + return; + } + CHECK(file_id.is_valid()); + FileView file_view = td_->file_manager_->get_file_view(file_id); + if (get_main_file_type(file_view.get_type()) == FileType::Photo) { + thumbnail_file_id = FileId(); + } + + LOG(INFO) << "Ask to upload file " << file_id << " with bad parts " << bad_parts; + CHECK(file_id.is_valid()); + + bool is_inserted = + being_uploaded_files_.emplace(file_id, std::make_tuple(message_full_id, thumbnail_file_id, m->edit_generation)) + .second; + CHECK(is_inserted); + td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_media_callback_, 1, m->message_id.get()); + } else { + on_message_media_uploaded(m, std::move(input_media), file_id, thumbnail_file_id); + } +} + +void QuickReplyManager::on_send_message_file_parts_missing(QuickReplyShortcutId shortcut_id, int64 random_id, + vector &&bad_parts) { + auto *s = get_shortcut(shortcut_id); + if (s != nullptr) { + for (auto &message : s->messages_) { + if (message->random_id == random_id && message->message_id.is_yet_unsent()) { + do_send_message(message.get(), std::move(bad_parts)); + } + } + } +} + +void QuickReplyManager::on_send_message_file_reference_error(QuickReplyShortcutId shortcut_id, int64 random_id) { + auto *s = get_shortcut(shortcut_id); + if (s != nullptr) { + for (auto &message : s->messages_) { + if (message->random_id == random_id && message->message_id.is_yet_unsent()) { + do_send_message(message.get(), {-1}); + } + } + } +} + +void QuickReplyManager::on_upload_media(FileId file_id, telegram_api::object_ptr input_file) { + LOG(INFO) << "File " << file_id << " has been uploaded"; + + auto it = being_uploaded_files_.find(file_id); + CHECK(it != being_uploaded_files_.end()); + + auto message_full_id = std::get<0>(it->second); + auto thumbnail_file_id = std::get<1>(it->second); + auto edit_generation = std::get<2>(it->second); + + being_uploaded_files_.erase(it); + + const auto *m = get_message(message_full_id); + if (m == nullptr || (m->message_id.is_server() && m->edit_generation != edit_generation)) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + return; + } + + if (input_file && thumbnail_file_id.is_valid()) { + // TODO: download thumbnail if needed (like in secret chats) + LOG(INFO) << "Ask to upload thumbnail " << thumbnail_file_id; + bool is_inserted = being_uploaded_thumbnails_ + .emplace(thumbnail_file_id, UploadedThumbnailInfo{message_full_id, file_id, + std::move(input_file), edit_generation}) + .second; + CHECK(is_inserted); + td_->file_manager_->upload(thumbnail_file_id, upload_thumbnail_callback_, 32, m->message_id.get()); + } else { + do_send_media(m, file_id, thumbnail_file_id, std::move(input_file), nullptr); + } +} + +void QuickReplyManager::do_send_media(const QuickReplyMessage *m, FileId file_id, FileId thumbnail_file_id, + telegram_api::object_ptr input_file, + telegram_api::object_ptr input_thumbnail) { + CHECK(m != nullptr); + + bool have_input_file = input_file != nullptr; + bool have_input_thumbnail = input_thumbnail != nullptr; + LOG(INFO) << "Do send media file " << file_id << " with thumbnail " << thumbnail_file_id + << ", have_input_file = " << have_input_file << ", have_input_thumbnail = " << have_input_thumbnail; + + auto content = m->message_id.is_server() ? m->edited_content.get() : m->content.get(); + CHECK(content != nullptr); + auto input_media = + get_message_content_input_media(content, -1, td_, std::move(input_file), std::move(input_thumbnail), file_id, + thumbnail_file_id, {}, m->send_emoji, true); + CHECK(input_media != nullptr); + + on_message_media_uploaded(m, std::move(input_media), file_id, thumbnail_file_id); +} + +void QuickReplyManager::on_upload_media_error(FileId file_id, Status status) { + if (G()->close_flag()) { + // do not fail upload if closing + return; + } + + LOG(WARNING) << "File " << file_id << " has upload error " << status; + CHECK(status.is_error()); + + auto it = being_uploaded_files_.find(file_id); + CHECK(it != being_uploaded_files_.end()); + + auto message_full_id = std::get<0>(it->second); + + being_uploaded_files_.erase(it); + + const auto *m = get_message(message_full_id); + if (m == nullptr) { + return; + } + + on_failed_send_quick_reply_messages(message_full_id.get_quick_reply_shortcut_id(), {m->random_id}, std::move(status)); +} + +void QuickReplyManager::on_upload_thumbnail(FileId thumbnail_file_id, + telegram_api::object_ptr thumbnail_input_file) { + if (G()->close_flag()) { + // do not fail upload if closing + return; + } + + LOG(INFO) << "Thumbnail " << thumbnail_file_id << " has been uploaded as " << to_string(thumbnail_input_file); + + auto it = being_uploaded_thumbnails_.find(thumbnail_file_id); + CHECK(it != being_uploaded_thumbnails_.end()); + + auto message_full_id = it->second.quick_reply_message_full_id; + auto file_id = it->second.file_id; + auto input_file = std::move(it->second.input_file); + auto edit_generation = it->second.edit_generation; + + being_uploaded_thumbnails_.erase(it); + + auto *m = get_message_editable(message_full_id); + if (m == nullptr || (m->message_id.is_server() && m->edit_generation != edit_generation)) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, thumbnail_file_id); + return; + } + + if (thumbnail_input_file == nullptr) { + auto content = m->message_id.is_server() ? m->edited_content.get() : m->content.get(); + delete_message_content_thumbnail(content, td_); + } + + do_send_media(m, file_id, thumbnail_file_id, std::move(input_file), std::move(thumbnail_input_file)); +} + +void QuickReplyManager::on_message_media_uploaded(const QuickReplyMessage *m, + telegram_api::object_ptr &&input_media, + FileId file_id, FileId thumbnail_file_id) { + if (G()->close_flag()) { + return; + } + + CHECK(m != nullptr); + CHECK(input_media != nullptr); + auto message_id = m->message_id; + if (message_id.is_any_server()) { + CHECK(m->edited_content != nullptr); + CHECK(m->edited_content->get_type() != MessageContentType::Text); + td_->create_handler()->send(file_id, thumbnail_file_id, m, std::move(input_media)); + return; + } + + if (m->media_album_id != 0) { + if (!is_uploaded_input_media(input_media)) { + td_->create_handler()->send(file_id, thumbnail_file_id, m, std::move(input_media)); + } else { + send_closure_later(actor_id(this), &QuickReplyManager::on_upload_message_media_finished, m->media_album_id, + m->shortcut_id, m->message_id, Status::OK()); + } + return; + } + + td_->create_handler()->send(file_id, thumbnail_file_id, m, std::move(input_media)); +} + +void QuickReplyManager::on_upload_message_media_success(QuickReplyShortcutId shortcut_id, MessageId message_id, + FileId file_id, + telegram_api::object_ptr &&media) { + const auto *m = get_message({shortcut_id, message_id}); + if (m == nullptr) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + return; + } + + CHECK(message_id.is_yet_unsent()); + + auto content = + get_uploaded_message_content(td_, m->content.get(), -1, std::move(media), + td_->dialog_manager_->get_my_dialog_id(), 0, "on_upload_message_media_success"); + update_sent_message_content_from_temporary_message(m->content, content, true); + + save_quick_reply_shortcuts(); + + auto input_media = get_message_content_input_media(content.get(), td_, {}, m->send_emoji, true); + Status result; + if (input_media == nullptr) { + result = Status::Error(400, "Failed to upload file"); + } + + send_closure_later(actor_id(this), &QuickReplyManager::on_upload_message_media_finished, m->media_album_id, + shortcut_id, message_id, std::move(result)); +} + +void QuickReplyManager::on_upload_message_media_fail(QuickReplyShortcutId shortcut_id, MessageId message_id, + Status error) { + const auto *m = get_message({shortcut_id, message_id}); + if (m == nullptr) { + return; + } + + send_closure_later(actor_id(this), &QuickReplyManager::on_upload_message_media_finished, m->media_album_id, + shortcut_id, m->message_id, std::move(error)); +} + +void QuickReplyManager::on_upload_message_media_finished(int64 media_album_id, QuickReplyShortcutId shortcut_id, + MessageId message_id, Status result) { + CHECK(media_album_id < 0); + auto it = pending_message_group_sends_.find(media_album_id); + if (it == pending_message_group_sends_.end()) { + CHECK(result.is_ok()); + // the message is being sent but was deleted + return; + } + + auto &request = it->second; + auto message_it = std::find(request.message_ids.begin(), request.message_ids.end(), message_id); + CHECK(message_it != request.message_ids.end()); + auto pos = static_cast(message_it - request.message_ids.begin()); + + if (request.is_finished[pos]) { + LOG(INFO) << "Upload media of " << message_id << " in " << shortcut_id << " from group " << media_album_id + << " at pos " << pos << " has already been finished"; + return; + } + LOG(INFO) << "Finish to upload media of " << message_id << " in " << shortcut_id << " from group " << media_album_id + << " at pos " << pos << " with result " << result + << " and previous finished_count = " << request.finished_count; + + request.results[pos] = std::move(result); + request.is_finished[pos] = true; + request.finished_count++; + + if (request.finished_count == request.message_ids.size()) { + do_send_message_group(shortcut_id, media_album_id); + } +} + +void QuickReplyManager::do_send_message_group(QuickReplyShortcutId shortcut_id, int64 media_album_id) { + if (G()->close_flag()) { + return; + } + + CHECK(media_album_id < 0); + auto it = pending_message_group_sends_.find(media_album_id); + CHECK(it != pending_message_group_sends_.end()); + + auto &request = it->second; + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return; + } + + vector file_ids; + vector random_ids; + MessageId reply_to_message_id; + bool invert_media = false; + vector> input_single_media; + Status error = Status::OK(); + for (size_t i = 0; i < request.message_ids.size(); i++) { + CHECK(request.is_finished[i]); + const auto *m = get_message(s, request.message_ids[i]); + if (m == nullptr) { + // skip deleted messages + continue; + } + if (request.results[i].is_error()) { + if (error.is_ok()) { + error = std::move(request.results[i]); + } + continue; + } + + reply_to_message_id = m->reply_to_message_id; + invert_media = m->invert_media; + file_ids.push_back(get_message_content_any_file_id(m->content.get())); + random_ids.push_back(m->random_id); + + LOG(INFO) << "Have file " << file_ids.back() << " in " << m->message_id << " with result " << request.results[i] + << " and is_finished = " << static_cast(request.is_finished[i]); + + const FormattedText *caption = get_message_content_caption(m->content.get()); + auto input_media = get_message_content_input_media(m->content.get(), td_, {}, m->send_emoji, true); + CHECK(input_media != nullptr); + auto entities = get_input_message_entities(td_->user_manager_.get(), caption, "do_send_message_group"); + int32 input_single_media_flags = 0; + if (!entities.empty()) { + input_single_media_flags |= telegram_api::inputSingleMedia::ENTITIES_MASK; + } + input_single_media.push_back(telegram_api::make_object( + input_single_media_flags, std::move(input_media), random_ids.back(), caption == nullptr ? "" : caption->text, + std::move(entities))); + } + pending_message_group_sends_.erase(it); + if (error.is_error()) { + on_failed_send_quick_reply_messages(shortcut_id, std::move(random_ids), std::move(error)); + return; + } + + LOG(INFO) << "Begin to send media group " << media_album_id << " to " << shortcut_id; + + if (input_single_media.empty()) { + LOG(INFO) << "Media group " << media_album_id << " from " << shortcut_id << " is empty"; + } + td_->create_handler()->send(shortcut_id, reply_to_message_id, invert_media, + std::move(random_ids), std::move(file_ids), + std::move(input_single_media)); +} + +void QuickReplyManager::on_send_media_group_file_reference_error(QuickReplyShortcutId shortcut_id, + vector random_ids) { + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return; + } + + int64 media_album_id = 0; + vector message_ids; + for (auto &random_id : random_ids) { + for (auto it = s->messages_.begin(); it != s->messages_.end(); ++it) { + const auto *m = it->get(); + if (m->random_id == random_id && m->message_id.is_yet_unsent()) { + CHECK(m->media_album_id != 0); + CHECK(media_album_id == 0 || media_album_id == m->media_album_id); + media_album_id = m->media_album_id; + + message_ids.push_back(m->message_id); + } + } + } + if (message_ids.empty()) { + // all messages were deleted, nothing to do + return; + } + + auto &request = pending_message_group_sends_[media_album_id]; + CHECK(request.finished_count == 0); + CHECK(request.is_finished.empty()); + CHECK(request.results.empty()); + request.message_ids = std::move(message_ids); + request.is_finished.resize(request.message_ids.size()); + for (size_t i = 0; i < request.message_ids.size(); i++) { + request.results.push_back(Status::OK()); + } + + for (auto message_id : request.message_ids) { + do_send_message(get_message(s, message_id), {-1}); + } +} + +int64 QuickReplyManager::generate_new_media_album_id() const { + int64 media_album_id = 0; + do { + media_album_id = Random::secure_int64(); + } while (media_album_id >= 0 || pending_message_group_sends_.count(media_album_id) > 0); + return media_album_id; +} + +Result> QuickReplyManager::resend_messages( + const string &shortcut_name, vector message_ids) { + if (message_ids.empty()) { + return Status::Error(400, "There are no messages to resend"); + } + + load_quick_reply_shortcuts(); + + auto *s = get_shortcut(shortcut_name); + if (s == nullptr) { + return Status::Error(400, "Quick reply shortcut not found"); + } + + MessageId last_message_id; + for (auto &message_id : message_ids) { + const auto *m = get_message(s, message_id); + if (m == nullptr) { + return Status::Error(400, "Message not found"); + } + if (!m->is_failed_to_send) { + return Status::Error(400, "Message is not failed to send"); + } + if (!can_resend_quick_reply_message(m)) { + return Status::Error(400, "Message can't be re-sent"); + } + if (m->try_resend_at > Time::now()) { + return Status::Error(400, "Message can't be re-sent yet"); + } + if (last_message_id != MessageId() && m->message_id <= last_message_id) { + return Status::Error(400, "Message identifiers must be in a strictly increasing order"); + } + last_message_id = m->message_id; + } + + vector> new_contents(message_ids.size()); + std::unordered_map, Hash> new_media_album_ids; + for (size_t i = 0; i < message_ids.size(); i++) { + MessageId message_id = message_ids[i]; + const auto *m = get_message(s, message_id); + CHECK(m != nullptr); + CHECK(m->edited_content == nullptr); + + unique_ptr content = + dup_message_content(td_, td_->dialog_manager_->get_my_dialog_id(), m->content.get(), + m->inline_query_id != 0 ? MessageContentDupType::SendViaBot : MessageContentDupType::Send, + MessageCopyOptions()); + if (content == nullptr) { + LOG(INFO) << "Can't resend " << m->message_id; + continue; + } + + new_contents[i] = std::move(content); + + if (m->media_album_id != 0) { + auto &new_media_album_id = new_media_album_ids[m->media_album_id]; + new_media_album_id.second++; + if (new_media_album_id.second == 2) { // have at least 2 messages in the new album + CHECK(new_media_album_id.first == 0); + new_media_album_id.first = generate_new_media_album_id(); + } + if (new_media_album_id.second == MAX_GROUPED_MESSAGES + 1) { + CHECK(new_media_album_id.first != 0); + new_media_album_id.first = 0; // just in case + } + } + } + + bool is_changed = false; + auto result = td_api::make_object(); + for (size_t i = 0; i < message_ids.size(); i++) { + if (new_contents[i] == nullptr) { + result->messages_.push_back(nullptr); + continue; + } + + auto *m = get_message_editable(s, message_ids[i]); + CHECK(m != nullptr); + unregister_message_content(m, "resend_message"); + m->message_id = get_next_yet_unsent_message_id(s); + m->media_album_id = new_media_album_ids[m->media_album_id].first; + m->is_failed_to_send = false; + m->send_error_code = 0; + m->send_error_message = string(); + m->try_resend_at = 0.0; + register_message_content(m, "resend_message"); + + do_send_message(m); + + result->messages_.push_back(get_quick_reply_message_object(m, "resend_message")); + is_changed = true; + } + + if (is_changed) { + sort_quick_reply_messages(s->messages_); + send_update_quick_reply_shortcut(s, "resend_message"); + send_update_quick_reply_shortcut_messages(s, "resend_message"); + save_quick_reply_shortcuts(); + } + + return std::move(result); +} + +void QuickReplyManager::edit_quick_reply_message( + QuickReplyShortcutId shortcut_id, MessageId message_id, + td_api::object_ptr &&input_message_content, Promise &&promise) { + load_quick_reply_shortcuts(); + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + auto *m = get_message_editable(s, message_id); + if (m == nullptr) { + return promise.set_error(Status::Error(400, "Message not found")); + } + if (!can_edit_quick_reply_message(m)) { + return promise.set_error(Status::Error(400, "Message can't be edited")); + } + + TRY_RESULT_PROMISE(promise, message_content, process_input_message_content(std::move(input_message_content))); + auto new_message_content_type = message_content.content->get_type(); + auto old_message_content_type = m->content->get_type(); + switch (old_message_content_type) { + case MessageContentType::Text: + if (new_message_content_type != MessageContentType::Text) { + return promise.set_error(Status::Error(400, "Text messages can be edited only to text messages")); + } + break; + case MessageContentType::Animation: + case MessageContentType::Audio: + case MessageContentType::Document: + case MessageContentType::Photo: + case MessageContentType::Video: + if (new_message_content_type != MessageContentType::Animation && + new_message_content_type != MessageContentType::Audio && + new_message_content_type != MessageContentType::Document && + new_message_content_type != MessageContentType::Photo && + new_message_content_type != MessageContentType::Video) { + return promise.set_error(Status::Error(400, "Media messages can be edited only to media messages")); + } + if (m->media_album_id != 0) { + if (old_message_content_type != new_message_content_type) { + if (!is_allowed_media_group_content(new_message_content_type)) { + return promise.set_error(Status::Error(400, "Message content type can't be used in an album")); + } + if (is_homogenous_media_group_content(old_message_content_type) || + is_homogenous_media_group_content(new_message_content_type)) { + return promise.set_error(Status::Error(400, "Can't change media type in the album")); + } + } + } + break; + case MessageContentType::VoiceNote: + if (new_message_content_type != MessageContentType::VoiceNote || + get_message_content_any_file_id(m->content.get()) != + get_message_content_any_file_id(message_content.content.get())) { + return promise.set_error(Status::Error(400, "Only caption can be edited in voice note messages")); + } + break; + default: + UNREACHABLE(); + } + + auto old_file_ids = get_message_file_ids(m); + m->edited_content = dup_message_content(td_, td_->dialog_manager_->get_my_dialog_id(), message_content.content.get(), + MessageContentDupType::Send, MessageCopyOptions()); + CHECK(m->edited_content != nullptr); + m->edited_invert_media = message_content.invert_media; + m->edited_disable_web_page_preview = message_content.disable_web_page_preview; + m->edit_generation = ++current_message_edit_generation_; + + change_message_files(m, old_file_ids); + + if (s->messages_[0]->message_id == message_id) { + send_update_quick_reply_shortcut(s, "edit_quick_reply_message 1"); + } + send_update_quick_reply_shortcut_messages(s, "edit_quick_reply_message 2"); + save_quick_reply_shortcuts(); + + do_send_message(m); + + promise.set_value(Unit()); +} + +void QuickReplyManager::on_edit_quick_reply_message(QuickReplyShortcutId shortcut_id, MessageId message_id, + int64 edit_generation, FileId file_id, bool was_uploaded, + telegram_api::object_ptr updates_ptr) { + auto *s = get_shortcut(shortcut_id); + auto *m = get_message_editable(s, message_id); + if (m == nullptr) { + if (was_uploaded) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + } + return; + } + if (m->edit_generation != edit_generation) { + LOG(INFO) << "Ignore successful edit of " << QuickReplyMessageFullId(m->shortcut_id, m->message_id) + << " with generation " << edit_generation << " instead of " << m->edit_generation; + if (was_uploaded) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + } + return; + } + LOG(INFO) << "Receive result for editing of " << QuickReplyMessageFullId(m->shortcut_id, m->message_id) << ": " + << to_string(updates_ptr); + + bool was_updated = updates_ptr == nullptr; + if (updates_ptr == nullptr || updates_ptr->get_id() != telegram_api::updates::ID) { + if (was_uploaded) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + } + reload_quick_reply_message(shortcut_id, message_id, Promise()); + } else { + auto updates = telegram_api::move_object_as(updates_ptr); + td_->user_manager_->on_get_users(std::move(updates->users_), "on_edit_quick_reply_message"); + td_->chat_manager_->on_get_chats(std::move(updates->chats_), "on_edit_quick_reply_message"); + + if (updates->updates_.size() != 1 || updates->updates_[0]->get_id() != telegram_api::updateQuickReplyMessage::ID) { + LOG(ERROR) << "Receive " << to_string(updates); + if (was_uploaded) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + } + } else { + auto update_message = telegram_api::move_object_as(updates->updates_[0]); + auto message = create_message(std::move(update_message->message_), "on_edit_quick_reply_message"); + if (message == nullptr || message->shortcut_id != shortcut_id || message->message_id != message_id) { + LOG(ERROR) << "Receive unexpected message"; + if (was_uploaded) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + } + } else { + update_sent_message_content_from_temporary_message(m, message.get(), true); + auto old_message_it = get_message_it(s, message_id); + CHECK(old_message_it != s->messages_.end()); + update_quick_reply_message(*old_message_it, std::move(message)); + m = old_message_it->get(); + was_updated = true; + } + } + } + + auto old_file_ids = get_message_file_ids(m); + CHECK(m->edited_content != nullptr); + if (!was_updated) { + unregister_message_content(m, "on_edit_quick_reply_message"); + m->content = std::move(m->edited_content); + m->invert_media = m->edited_invert_media; + m->disable_web_page_preview = m->edited_disable_web_page_preview; + register_message_content(m, "on_edit_quick_reply_message"); + } + + m->edit_generation = 0; + m->edited_content = nullptr; + m->edited_invert_media = false; + m->edited_disable_web_page_preview = false; + change_message_files(m, old_file_ids); + + if (s->messages_[0]->message_id == m->message_id) { + send_update_quick_reply_shortcut(s, "on_edit_quick_reply_message 1"); + } + send_update_quick_reply_shortcut_messages(s, "on_edit_quick_reply_message 2"); + save_quick_reply_shortcuts(); +} + +void QuickReplyManager::fail_edit_quick_reply_message(QuickReplyShortcutId shortcut_id, MessageId message_id, + int64 edit_generation, FileId file_id, FileId thumbnail_file_id, + string file_reference, bool was_uploaded, + bool was_thumbnail_uploaded, Status status) { + auto *m = get_message_editable({shortcut_id, message_id}); + if (m == nullptr) { + if (was_uploaded) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + } + return; + } + if (m->edit_generation != edit_generation) { + LOG(INFO) << "Ignore failed edit of " << QuickReplyMessageFullId(m->shortcut_id, m->message_id) + << " with generation " << edit_generation << " instead of " << m->edit_generation; + if (was_uploaded) { + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + } + return; + } + if (was_uploaded) { + if (was_thumbnail_uploaded) { + CHECK(thumbnail_file_id.is_valid()); + // always delete partial remote location for the thumbnail, because it can't be reused anyway + td_->file_manager_->delete_partial_remote_location(thumbnail_file_id); + } + + CHECK(file_id.is_valid()); + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + do_send_message(m, std::move(bad_parts)); + return; + } else { + td_->file_manager_->delete_partial_remote_location_if_needed(file_id, status); + } + } else if (FileReferenceManager::is_file_reference_error(status)) { + if (file_id.is_valid() && !was_uploaded) { + VLOG(file_references) << "Receive " << status << " for " << file_id; + td_->file_manager_->delete_file_reference(file_id, file_reference); + do_send_message(m, {-1}); + return; + } else { + LOG(ERROR) << "Receive file reference error, but file_id = " << file_id << ", was_uploaded = " << was_uploaded; + } + } + + auto old_file_ids = get_message_file_ids(m); + m->edit_generation = 0; + m->edited_content = nullptr; + m->edited_invert_media = false; + m->edited_disable_web_page_preview = false; + change_message_files(m, old_file_ids); + + auto *s = get_shortcut(m->shortcut_id); + CHECK(s != nullptr); + if (s->messages_[0]->message_id == m->message_id) { + send_update_quick_reply_shortcut(s, "fail_edit_quick_reply_message 1"); + } + send_update_quick_reply_shortcut_messages(s, "fail_edit_quick_reply_message 2"); + save_quick_reply_shortcuts(); + reload_quick_reply_message(shortcut_id, message_id, Promise()); +} + +void QuickReplyManager::get_quick_reply_shortcut_messages(QuickReplyShortcutId shortcut_id, Promise &&promise) { + load_quick_reply_shortcuts(); + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + if (have_all_shortcut_messages(s)) { + return promise.set_value(Unit()); + } + + CHECK(shortcut_id.is_server()); + reload_quick_reply_messages(shortcut_id, std::move(promise)); +} + +void QuickReplyManager::reload_quick_reply_messages(QuickReplyShortcutId shortcut_id, Promise &&promise) { + if (td_->auth_manager_->is_bot()) { + return promise.set_error(Status::Error(400, "Not supported by bots")); + } + + load_quick_reply_shortcuts(); + CHECK(shortcut_id.is_valid()); + if (!shortcut_id.is_server()) { + return promise.set_value(Unit()); + } + auto &queries = get_shortcut_messages_queries_[shortcut_id]; + queries.push_back(std::move(promise)); + if (queries.size() != 1) { + return; + } + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), shortcut_id]( + Result> r_messages) { + send_closure(actor_id, &QuickReplyManager::on_reload_quick_reply_messages, shortcut_id, std::move(r_messages)); + }); + td_->create_handler(std::move(query_promise)) + ->send(shortcut_id, vector(), get_quick_reply_messages_hash(get_shortcut(shortcut_id))); +} + +void QuickReplyManager::on_reload_quick_reply_messages( + QuickReplyShortcutId shortcut_id, Result> r_messages) { + G()->ignore_result_if_closing(r_messages); + auto queries_it = get_shortcut_messages_queries_.find(shortcut_id); + CHECK(queries_it != get_shortcut_messages_queries_.end()); + CHECK(!queries_it->second.empty()); + auto promises = std::move(queries_it->second); + get_shortcut_messages_queries_.erase(queries_it); + if (r_messages.is_error()) { + return fail_promises(promises, r_messages.move_as_error()); + } + auto messages_ptr = r_messages.move_as_ok(); + switch (messages_ptr->get_id()) { + case telegram_api::messages_messagesSlice::ID: + case telegram_api::messages_channelMessages::ID: + LOG(ERROR) << "Receive " << to_string(messages_ptr); + break; + case telegram_api::messages_messagesNotModified::ID: + break; + case telegram_api::messages_messages::ID: { + auto messages = telegram_api::move_object_as(messages_ptr); + td_->user_manager_->on_get_users(std::move(messages->users_), "on_reload_quick_reply_messages"); + td_->chat_manager_->on_get_chats(std::move(messages->chats_), "on_reload_quick_reply_messages"); + + vector> quick_reply_messages; + for (auto &server_message : messages->messages_) { + auto message = create_message(std::move(server_message), "on_reload_quick_reply_messages"); + if (message == nullptr) { + continue; + } + if (message->shortcut_id != shortcut_id) { + LOG(ERROR) << "Receive message from " << message->shortcut_id << " instead of " << shortcut_id; + continue; + } + + quick_reply_messages.push_back(std::move(message)); + } + auto it = get_shortcut_it(shortcut_id); + if (quick_reply_messages.empty()) { + if (it != shortcuts_.shortcuts_.end()) { + send_update_quick_reply_shortcut_deleted(it->get()); + shortcuts_.shortcuts_.erase(it); + save_quick_reply_shortcuts(); + send_update_quick_reply_shortcuts(); + } + break; + } + + auto *old_shortcut = it != shortcuts_.shortcuts_.end() ? it->get() : nullptr; + auto shortcut = td::make_unique(); + shortcut->name_ = old_shortcut->name_; + shortcut->shortcut_id_ = shortcut_id; + shortcut->server_total_count_ = static_cast(quick_reply_messages.size()); + shortcut->messages_ = std::move(quick_reply_messages); + + if (old_shortcut == nullptr) { + CHECK(have_all_shortcut_messages(shortcut.get())); + send_update_quick_reply_shortcut(shortcut.get(), "on_reload_quick_reply_messages 1"); + send_update_quick_reply_shortcut_messages(shortcut.get(), "on_reload_quick_reply_messages 2"); + for (auto &message : shortcut->messages_) { + register_new_message(message.get(), "on_reload_quick_reply_messages 5"); + } + shortcuts_.shortcuts_.push_back(std::move(shortcut)); + } else { + bool is_shortcut_changed = false; + bool are_messages_changed = false; + update_shortcut_from(shortcut.get(), old_shortcut, false, &is_shortcut_changed, &are_messages_changed); + CHECK(have_all_shortcut_messages(shortcut.get())); + if (is_shortcut_changed) { + send_update_quick_reply_shortcut(shortcut.get(), "on_reload_quick_reply_messages 3"); + } + if (are_messages_changed) { + send_update_quick_reply_shortcut_messages(shortcut.get(), "on_reload_quick_reply_messages 4"); + } + *it = std::move(shortcut); + } + + save_quick_reply_shortcuts(); + break; + } + default: + UNREACHABLE(); + } + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return fail_promises(promises, Status::Error(400, "Shortcut not found")); + } + set_promises(promises); +} + +int64 QuickReplyManager::get_quick_reply_messages_hash(const Shortcut *s) { + if (s == nullptr) { + return 0; + } + vector numbers; + for (const auto &message : s->messages_) { + if (message->message_id.is_server()) { + numbers.push_back(message->message_id.get_server_message_id().get()); + numbers.push_back(message->edit_date); + } + } + return get_vector_hash(numbers); +} + +void QuickReplyManager::reload_quick_reply_message(QuickReplyShortcutId shortcut_id, MessageId message_id, + Promise &&promise) { + if (td_->auth_manager_->is_bot()) { + return promise.set_error(Status::Error(400, "Not supported by bots")); + } + + load_quick_reply_shortcuts(); + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + if (!message_id.is_server()) { + return promise.set_error(Status::Error(400, "Message can't be reloaded")); + } + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), shortcut_id, message_id, promise = std::move(promise)]( + Result> r_messages) mutable { + send_closure(actor_id, &QuickReplyManager::on_reload_quick_reply_message, shortcut_id, message_id, + std::move(r_messages), std::move(promise)); + }); + td_->create_handler(std::move(query_promise)) + ->send(shortcut_id, vector{message_id}, 0); +} + +void QuickReplyManager::on_reload_quick_reply_message( + QuickReplyShortcutId shortcut_id, MessageId message_id, + Result> r_messages, Promise &&promise) { + G()->ignore_result_if_closing(r_messages); + if (r_messages.is_error()) { + return promise.set_error(r_messages.move_as_error()); + } + auto *s = get_shortcut(shortcut_id); + if (s == nullptr) { + return promise.set_error(Status::Error(400, "Shortcut not found")); + } + auto messages_ptr = r_messages.move_as_ok(); + switch (messages_ptr->get_id()) { + case telegram_api::messages_messagesSlice::ID: + case telegram_api::messages_channelMessages::ID: + case telegram_api::messages_messagesNotModified::ID: + LOG(ERROR) << "Receive " << to_string(messages_ptr); + return promise.set_error(Status::Error(400, "Receive wrong response")); + case telegram_api::messages_messages::ID: { + auto messages = telegram_api::move_object_as(messages_ptr); + td_->user_manager_->on_get_users(std::move(messages->users_), "on_reload_quick_reply_message"); + td_->chat_manager_->on_get_chats(std::move(messages->chats_), "on_reload_quick_reply_message"); + + if (messages->messages_.size() > 1u) { + LOG(ERROR) << "Receive " << to_string(messages_ptr); + break; + } + unique_ptr message; + if (messages->messages_.size() == 1u) { + message = create_message(std::move(messages->messages_[0]), "on_reload_quick_reply_message"); + } + if (message == nullptr) { + delete_quick_reply_messages(s, {message_id}, "on_reload_quick_reply_message"); + return promise.set_error(Status::Error(400, "Message not found")); + } + if (message->shortcut_id != shortcut_id) { + LOG(ERROR) << "Receive message from " << message->shortcut_id << " instead of " << shortcut_id; + return promise.set_error(Status::Error(400, "Message not found")); + } + on_get_quick_reply_message(s, std::move(message)); + break; + } + default: + UNREACHABLE(); + } + promise.set_value(Unit()); +} + +Result> QuickReplyManager::get_quick_reply_message_contents( + DialogId dialog_id, QuickReplyShortcutId shortcut_id) const { + const auto *shortcut = get_shortcut(shortcut_id); + if (shortcut == nullptr) { + return Status::Error(400, "Shortcut not found"); + } + if (!shortcut_id.is_server()) { + return Status::Error(400, "Shortcut isn't created yet"); + } + if (!have_all_shortcut_messages(shortcut)) { + return Status::Error(400, "Shortcut messages aren't loaded yet"); + } + + TRY_STATUS(td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Write, + "get_quick_reply_message_contents")); + if (dialog_id.get_type() != DialogType::User || td_->user_manager_->is_user_bot(dialog_id.get_user_id())) { + return Status::Error(400, "Can't use quick replies in the chat"); + } + + vector result; + for (const auto &message : shortcut->messages_) { + if (!message->message_id.is_server()) { + continue; + } + auto content = dup_message_content(td_, dialog_id, message->content.get(), MessageContentDupType::ServerCopy, + MessageCopyOptions(true, false)); + + auto can_send_status = can_send_message_content(dialog_id, content.get(), false, true, td_); + if (can_send_status.is_error()) { + LOG(INFO) << "Can't send " << message->message_id << ": " << can_send_status.message(); + // if we skip the message, the sending will fail anyway with MESSAGE_IDS_MISMATCH + // continue; + } + + auto disable_web_page_preview = message->disable_web_page_preview && + content->get_type() == MessageContentType::Text && + !has_message_content_web_page(content.get()); + result.push_back({std::move(content), message->message_id, message->reply_to_message_id, + dup_reply_markup(message->reply_markup), + message->hide_via_bot ? UserId() : message->via_bot_user_id, message->media_album_id, + message->invert_media, disable_web_page_preview}); + } + + return std::move(result); +} + +QuickReplyManager::Shortcut *QuickReplyManager::get_shortcut(QuickReplyShortcutId shortcut_id) { + if (!shortcuts_.are_inited_) { + return nullptr; + } + for (auto &shortcut : shortcuts_.shortcuts_) { + if (shortcut->shortcut_id_ == shortcut_id) { + return shortcut.get(); + } + } + if (shortcut_id.is_local()) { + auto it = persistent_shortcut_ids_.find(shortcut_id); + if (it != persistent_shortcut_ids_.end()) { + return get_shortcut(it->second); + } + } + return nullptr; +} + +const QuickReplyManager::Shortcut *QuickReplyManager::get_shortcut(QuickReplyShortcutId shortcut_id) const { + if (!shortcuts_.are_inited_) { + return nullptr; + } + for (auto &shortcut : shortcuts_.shortcuts_) { + if (shortcut->shortcut_id_ == shortcut_id) { + return shortcut.get(); + } + } + if (shortcut_id.is_local()) { + auto it = persistent_shortcut_ids_.find(shortcut_id); + if (it != persistent_shortcut_ids_.end()) { + return get_shortcut(it->second); + } + } + return nullptr; +} + +QuickReplyManager::Shortcut *QuickReplyManager::get_shortcut(const string &name) { + if (!shortcuts_.are_inited_) { + return nullptr; + } + for (auto &shortcut : shortcuts_.shortcuts_) { + if (shortcut->name_ == name) { + return shortcut.get(); + } + } + return nullptr; +} + +vector>::iterator QuickReplyManager::get_shortcut_it( + QuickReplyShortcutId shortcut_id) { + for (auto it = shortcuts_.shortcuts_.begin(); it != shortcuts_.shortcuts_.end(); ++it) { + if (*it != nullptr && (*it)->shortcut_id_ == shortcut_id) { + return it; + } + } + if (shortcut_id.is_local()) { + auto it = persistent_shortcut_ids_.find(shortcut_id); + if (it != persistent_shortcut_ids_.end()) { + return get_shortcut_it(it->second); + } + } + return shortcuts_.shortcuts_.end(); +} + +vector>::iterator QuickReplyManager::get_message_it( + Shortcut *s, MessageId message_id) { + CHECK(s != nullptr); + for (auto it = s->messages_.begin(); it != s->messages_.end(); ++it) { + if ((*it)->message_id == message_id) { + return it; + } + } + return s->messages_.end(); +} + +const QuickReplyManager::QuickReplyMessage *QuickReplyManager::get_message( + QuickReplyMessageFullId message_full_id) const { + const auto *s = get_shortcut(message_full_id.get_quick_reply_shortcut_id()); + return get_message(s, message_full_id.get_message_id()); +} + +const QuickReplyManager::QuickReplyMessage *QuickReplyManager::get_message(const Shortcut *s, + MessageId message_id) const { + if (s != nullptr) { + for (auto it = s->messages_.begin(); it != s->messages_.end(); ++it) { + if ((*it)->message_id == message_id) { + return it->get(); + } + } + } + return nullptr; +} + +QuickReplyManager::QuickReplyMessage *QuickReplyManager::get_message_editable(QuickReplyMessageFullId message_full_id) { + auto *s = get_shortcut(message_full_id.get_quick_reply_shortcut_id()); + return get_message_editable(s, message_full_id.get_message_id()); +} + +QuickReplyManager::QuickReplyMessage *QuickReplyManager::get_message_editable(Shortcut *s, MessageId message_id) { + if (s != nullptr) { + for (auto it = s->messages_.begin(); it != s->messages_.end(); ++it) { + if ((*it)->message_id == message_id) { + return it->get(); + } + } + } + return nullptr; +} + +Result QuickReplyManager::create_new_local_shortcut(const string &name, + int32 new_message_count) { + TRY_STATUS(check_shortcut_name(name)); + + load_quick_reply_shortcuts(); + if (!shortcuts_.are_inited_) { + return Status::Error(400, "Quick reply shortcuts must be loaded first"); + } + + auto *s = get_shortcut(name); + auto max_message_count = td_->option_manager_->get_option_integer("quick_reply_shortcut_message_count_max"); + if (s != nullptr) { + if (!have_all_shortcut_messages(s)) { + return Status::Error(400, "The quick reply shortcut must be loaded first"); + } + max_message_count -= s->server_total_count_ + s->local_total_count_; + } else { + auto max_shortcut_count = td_->option_manager_->get_option_integer("quick_reply_shortcut_count_max"); + if (static_cast(shortcuts_.shortcuts_.size()) >= max_shortcut_count) { + return Status::Error(400, "Quick reply shortcut count exceeded"); + } + } + if (new_message_count > max_message_count) { + return Status::Error(400, "Quick reply message count exceeded"); + } + if (s != nullptr) { + return s; + } + if (next_local_shortcut_id_ >= std::numeric_limits::max() - 10) { + return Status::Error(400, "Too many local shortcuts created"); + } + + auto shortcut = td::make_unique(); + shortcut->name_ = name; + shortcut->shortcut_id_ = QuickReplyShortcutId(next_local_shortcut_id_++); + s = shortcut.get(); + + shortcuts_.shortcuts_.push_back(std::move(shortcut)); + + return s; +} + +MessageId QuickReplyManager::get_input_reply_to_message_id(const Shortcut *s, MessageId reply_to_message_id) { + if (s == nullptr || !reply_to_message_id.is_valid() || !reply_to_message_id.is_server()) { + return MessageId(); + } + for (const auto &message : s->messages_) { + CHECK(message != nullptr); + if (message->message_id == reply_to_message_id) { + return reply_to_message_id; + } + } + return MessageId(); +} + +Result QuickReplyManager::process_input_message_content( + td_api::object_ptr &&input_message_content) { + if (input_message_content == nullptr) { + return Status::Error(400, "Can't add quick reply without content"); + } + auto message_content_id = input_message_content->get_id(); + if (message_content_id == td_api::inputMessageForwarded::ID) { + return Status::Error(400, "Can't forward messages to quick replies"); + } + if (message_content_id == td_api::inputMessagePoll::ID) { + return Status::Error(400, "Can't add poll as a quick reply"); + } + if (message_content_id == td_api::inputMessagePaidMedia::ID) { + return Status::Error(400, "Can't add paid media as a quick reply"); + } + if (message_content_id == td_api::inputMessageLocation::ID && + static_cast(input_message_content.get())->live_period_ != 0) { + return Status::Error(400, "Can't add live location as a quick reply"); + } + return get_input_message_content(DialogId(), std::move(input_message_content), td_, true); +} + +MessageId QuickReplyManager::get_next_message_id(Shortcut *s, MessageType type) const { + CHECK(s != nullptr); + MessageId last_message_id = s->last_assigned_message_id_; + if (!s->messages_.empty() && s->messages_.back() != nullptr && s->messages_.back()->message_id > last_message_id) { + last_message_id = s->messages_.back()->message_id; + } + s->last_assigned_message_id_ = last_message_id.get_next_message_id(type); + CHECK(s->last_assigned_message_id_.is_valid()); + return s->last_assigned_message_id_; +} + +MessageId QuickReplyManager::get_next_yet_unsent_message_id(Shortcut *s) const { + return get_next_message_id(s, MessageType::YetUnsent); +} + +MessageId QuickReplyManager::get_next_local_message_id(Shortcut *s) const { + return get_next_message_id(s, MessageType::Local); +} + +QuickReplyManager::QuickReplyMessage *QuickReplyManager::add_local_message( + Shortcut *s, MessageId reply_to_message_id, unique_ptr &&content, bool invert_media, + UserId via_bot_user_id, bool hide_via_bot, bool disable_web_page_preview, string &&send_emoji) { + CHECK(s != nullptr); + auto message = make_unique(); + auto *m = message.get(); + m->shortcut_id = s->shortcut_id_; + m->message_id = get_next_yet_unsent_message_id(s); + m->reply_to_message_id = reply_to_message_id; + m->send_emoji = std::move(send_emoji); + m->via_bot_user_id = via_bot_user_id; + m->hide_via_bot = hide_via_bot; + m->invert_media = invert_media; + m->disable_web_page_preview = disable_web_page_preview; + m->content = std::move(content); + do { + m->random_id = Random::secure_int64(); + } while (m->random_id == 0); + + register_new_message(m, "add_local_message"); + + s->messages_.push_back(std::move(message)); + s->local_total_count_++; + + return m; +} + +vector QuickReplyManager::get_shortcut_ids() const { + return transform(shortcuts_.shortcuts_, [](const unique_ptr &shortcut) { return shortcut->shortcut_id_; }); +} + +vector QuickReplyManager::get_server_shortcut_ids() const { + vector shortcut_ids; + for (auto &shortcut : shortcuts_.shortcuts_) { + if (shortcut->shortcut_id_.is_server()) { + shortcut_ids.push_back(shortcut->shortcut_id_); + } + } + return shortcut_ids; +} + +void QuickReplyManager::sort_quick_reply_messages(vector> &messages) { + std::sort(messages.begin(), messages.end(), + [](const unique_ptr &lhs, const unique_ptr &rhs) { + return lhs->message_id < rhs->message_id; + }); +} + +QuickReplyManager::QuickReplyMessageUniqueId QuickReplyManager::get_quick_reply_unique_id(const QuickReplyMessage *m) { + return QuickReplyMessageUniqueId(m->message_id, m->edit_date); +} + +vector QuickReplyManager::get_quick_reply_unique_ids( + const vector> &messages) { + return transform( + messages, [](const unique_ptr &message) { return get_quick_reply_unique_id(message.get()); }); +} + +vector QuickReplyManager::get_server_quick_reply_unique_ids( + const vector> &messages) { + auto message_ids = get_quick_reply_unique_ids(messages); + td::remove_if(message_ids, [](const QuickReplyMessageUniqueId &message_id) { return !message_id.first.is_server(); }); + return message_ids; +} + +void QuickReplyManager::update_shortcut_from(Shortcut *new_shortcut, Shortcut *old_shortcut, bool is_partial, + bool *is_shortcut_changed, bool *are_messages_changed) { + CHECK(old_shortcut != nullptr); + CHECK(new_shortcut != nullptr); + CHECK(old_shortcut->shortcut_id_.is_server()); + CHECK(old_shortcut->shortcut_id_ == new_shortcut->shortcut_id_); + CHECK(!old_shortcut->messages_.empty()); + CHECK(!new_shortcut->messages_.empty()); + auto old_unique_id = get_quick_reply_unique_id(old_shortcut->messages_[0].get()); + auto old_message_count = get_shortcut_message_count(old_shortcut); + if (is_partial) { + // only the first server message is known + // delete all definitely deleted server messages and insert the new message in the correct place + auto old_message_ids = get_quick_reply_unique_ids(old_shortcut->messages_); + auto new_first_message_id = new_shortcut->messages_[0]->message_id; + auto it = old_shortcut->messages_.begin(); + while (it != old_shortcut->messages_.end() && (*it)->message_id < new_first_message_id) { + if ((*it)->message_id.is_server()) { + delete_message_files(it->get()); + it = old_shortcut->messages_.erase(it); + } else { + ++it; + } + } + if (it == old_shortcut->messages_.end() || (*it)->message_id != new_first_message_id) { + register_new_message(new_shortcut->messages_[0].get(), "update_shortcut_from"); + old_shortcut->messages_.insert(it, std::move(new_shortcut->messages_[0])); + } else { + update_quick_reply_message(*it, std::move(new_shortcut->messages_[0])); + } + new_shortcut->messages_ = std::move(old_shortcut->messages_); + *are_messages_changed = (old_message_ids != get_quick_reply_unique_ids(new_shortcut->messages_)); + + int32 server_total_count = 0; + for (const auto &message : new_shortcut->messages_) { + if (message->message_id.is_server()) { + server_total_count++; + } + } + if (server_total_count > new_shortcut->server_total_count_) { + new_shortcut->server_total_count_ = server_total_count; + } + } else { + auto old_server_message_ids = get_server_quick_reply_unique_ids(old_shortcut->messages_); + auto new_server_message_ids = get_server_quick_reply_unique_ids(new_shortcut->messages_); + CHECK(static_cast(new_shortcut->server_total_count_) == new_server_message_ids.size()); + if (old_server_message_ids == new_server_message_ids) { + *are_messages_changed = false; + new_shortcut->messages_ = std::move(old_shortcut->messages_); + } else { + *are_messages_changed = true; + for (auto &old_message : old_shortcut->messages_) { + CHECK(old_message != nullptr); + if (!old_message->message_id.is_server()) { + new_shortcut->messages_.push_back(std::move(old_message)); + } else { + bool is_deleted = true; + for (auto &new_message : new_shortcut->messages_) { + if (new_message->message_id == old_message->message_id) { + update_quick_reply_message(old_message, std::move(new_message)); + new_message = std::move(old_message); + is_deleted = false; + break; + } + } + if (is_deleted) { + delete_message_files(old_message.get()); + } + } + } + sort_quick_reply_messages(new_shortcut->messages_); + } + } + new_shortcut->local_total_count_ = old_shortcut->local_total_count_; + *is_shortcut_changed = old_unique_id != get_quick_reply_unique_id(new_shortcut->messages_[0].get()) || + new_shortcut->name_ != old_shortcut->name_ || + old_message_count != get_shortcut_message_count(new_shortcut); +} + +string QuickReplyManager::get_quick_reply_shortcuts_database_key() { + return "quick_reply_shortcuts"; +} + +void QuickReplyManager::save_quick_reply_shortcuts() { + CHECK(shortcuts_.are_inited_); + LOG(INFO) << "Save quick reply shortcuts"; + G()->td_db()->get_binlog_pmc()->set(get_quick_reply_shortcuts_database_key(), + log_event_store(shortcuts_).as_slice().str()); +} + +void QuickReplyManager::load_quick_reply_shortcuts() { + CHECK(!td_->auth_manager_->is_bot()); + if (shortcuts_.are_loaded_from_database_) { + return; + } + shortcuts_.are_loaded_from_database_ = true; + CHECK(shortcuts_.load_queries_.empty()); + + auto shortcuts_str = G()->td_db()->get_binlog_pmc()->get(get_quick_reply_shortcuts_database_key()); + if (shortcuts_str.empty()) { + return reload_quick_reply_shortcuts(); + } + auto status = log_event_parse(shortcuts_, shortcuts_str); + if (status.is_error()) { + LOG(ERROR) << "Can't load quick replies: " << status; + G()->td_db()->get_binlog_pmc()->erase(get_quick_reply_shortcuts_database_key()); + shortcuts_.shortcuts_.clear(); + return reload_quick_reply_shortcuts(); + } + + Dependencies dependencies; + for (const auto &shortcut : shortcuts_.shortcuts_) { + for (const auto &message : shortcut->messages_) { + add_quick_reply_message_dependencies(dependencies, message.get()); + } + } + if (!dependencies.resolve_force(td_, "load_quick_reply_shortcuts")) { + shortcuts_.shortcuts_.clear(); + return reload_quick_reply_shortcuts(); + } + + shortcuts_.are_inited_ = true; + for (auto &shortcut : shortcuts_.shortcuts_) { + if (shortcut->shortcut_id_.get() >= next_local_shortcut_id_) { + next_local_shortcut_id_ = shortcut->shortcut_id_.get() + 1; + } + for (auto &message : shortcut->messages_) { + if (message->shortcut_id != shortcut->shortcut_id_) { + LOG(ERROR) << "Receive quick reply " << message->message_id << " in " << message->shortcut_id << " instead of " + << shortcut->shortcut_id_; + message->shortcut_id = shortcut->shortcut_id_; + } + register_new_message(message.get(), "load_quick_reply_shortcuts"); + + if (message->message_id.is_server()) { + if (need_reget_message_content(message->content.get()) || + (message->legacy_layer != 0 && message->legacy_layer < MTPROTO_LAYER)) { + reload_quick_reply_message(shortcut->shortcut_id_, message->message_id, Promise()); + } + if (message->edited_content != nullptr) { + message->edit_generation = ++current_message_edit_generation_; + do_send_message(message.get()); + } + } else if (message->message_id.is_yet_unsent()) { + do_send_message(message.get()); + } + } + send_update_quick_reply_shortcut(shortcut.get(), "load_quick_reply_shortcuts"); + send_update_quick_reply_shortcut_messages(shortcut.get(), "load_quick_reply_shortcuts"); + } + + send_update_quick_reply_shortcuts(); + + reload_quick_reply_shortcuts(); +} + +td_api::object_ptr QuickReplyManager::get_update_quick_reply_shortcut_object( + const Shortcut *s, const char *source) const { + return td_api::make_object(get_quick_reply_shortcut_object(s, source)); +} + +void QuickReplyManager::send_update_quick_reply_shortcut(const Shortcut *s, const char *source) { + send_closure(G()->td(), &Td::send_update, get_update_quick_reply_shortcut_object(s, source)); +} + +td_api::object_ptr +QuickReplyManager::get_update_quick_reply_shortcut_deleted_object(const Shortcut *s) const { + CHECK(s != nullptr); + return td_api::make_object(s->shortcut_id_.get()); +} + +void QuickReplyManager::send_update_quick_reply_shortcut_deleted(const Shortcut *s) { + send_closure(G()->td(), &Td::send_update, get_update_quick_reply_shortcut_deleted_object(s)); +} + +td_api::object_ptr QuickReplyManager::get_update_quick_reply_shortcuts_object() + const { + CHECK(shortcuts_.are_inited_); + return td_api::make_object(transform( + shortcuts_.shortcuts_, [](const unique_ptr &shortcut) { return shortcut->shortcut_id_.get(); })); +} + +void QuickReplyManager::send_update_quick_reply_shortcuts() { + send_closure(G()->td(), &Td::send_update, get_update_quick_reply_shortcuts_object()); +} + +td_api::object_ptr +QuickReplyManager::get_update_quick_reply_shortcut_messages_object(const Shortcut *s, const char *source) const { + CHECK(s != nullptr); + auto messages = transform(s->messages_, [this, source](const unique_ptr &message) { + return get_quick_reply_message_object(message.get(), source); + }); + return td_api::make_object(s->shortcut_id_.get(), std::move(messages)); +} + +void QuickReplyManager::send_update_quick_reply_shortcut_messages(const Shortcut *s, const char *source) { + if (have_all_shortcut_messages(s)) { + send_closure(G()->td(), &Td::send_update, get_update_quick_reply_shortcut_messages_object(s, source)); + } +} + +vector QuickReplyManager::get_message_file_ids(const QuickReplyMessage *m) const { + if (m == nullptr) { + return {}; + } + if (m->edited_content != nullptr) { + auto file_ids = get_message_content_file_ids(m->edited_content.get(), td_); + if (!file_ids.empty()) { + for (auto file_id : get_message_content_file_ids(m->content.get(), td_)) { + if (!td::contains(file_ids, file_id)) { + file_ids.push_back(file_id); + } + } + } + return file_ids; + } + return get_message_content_file_ids(m->content.get(), td_); +} + +void QuickReplyManager::delete_message_files(const QuickReplyMessage *m) const { + CHECK(m != nullptr); + unregister_message_content(m, "delete_message_files"); + auto file_ids = get_message_file_ids(m); + if (file_ids.empty()) { + return; + } + for (auto file_id : file_ids) { + send_closure(G()->file_manager(), &FileManager::delete_file, file_id, Promise(), "delete_message_files"); + } + auto it = message_full_id_to_file_source_id_.find({m->shortcut_id, m->message_id}); + if (it != message_full_id_to_file_source_id_.end()) { + td_->file_manager_->change_files_source(it->second, file_ids, {}); + } +} + +void QuickReplyManager::change_message_files(const QuickReplyMessage *m, const vector &old_file_ids) { + CHECK(m != nullptr); + auto new_file_ids = get_message_file_ids(m); + if (new_file_ids == old_file_ids) { + return; + } + + QuickReplyMessageFullId message_full_id(m->shortcut_id, m->message_id); + LOG(INFO) << "Change files of " << message_full_id << " from " << old_file_ids << " to " << new_file_ids; + for (auto file_id : old_file_ids) { + if (!td::contains(new_file_ids, file_id)) { + send_closure(G()->file_manager(), &FileManager::delete_file, file_id, Promise(), "change_message_files"); + } + } + + auto file_source_id = get_quick_reply_message_file_source_id(message_full_id); + if (file_source_id.is_valid()) { + td_->file_manager_->change_files_source(file_source_id, old_file_ids, new_file_ids); + } +} + +void QuickReplyManager::register_new_message(const QuickReplyMessage *m, const char *source) { + change_message_files(m, {}); + register_message_content(m, source); +} + +void QuickReplyManager::register_message_content(const QuickReplyMessage *m, const char *source) const { + register_quick_reply_message_content(td_, m->content.get(), {m->shortcut_id, m->message_id}, source); +} + +void QuickReplyManager::unregister_message_content(const QuickReplyMessage *m, const char *source) const { + unregister_quick_reply_message_content(td_, m->content.get(), {m->shortcut_id, m->message_id}, source); +} + +FileSourceId QuickReplyManager::get_quick_reply_message_file_source_id(QuickReplyMessageFullId message_full_id) { + if (td_->auth_manager_->is_bot()) { + return FileSourceId(); + } + if (!message_full_id.is_server()) { + return FileSourceId(); + } + + auto &file_source_id = message_full_id_to_file_source_id_[message_full_id]; + if (!file_source_id.is_valid()) { + file_source_id = td_->file_reference_manager_->create_quick_reply_message_file_source(message_full_id); + } + return file_source_id; +} + +void QuickReplyManager::get_current_state(vector> &updates) const { + if (td_->auth_manager_->is_bot()) { + return; + } + + if (shortcuts_.are_inited_) { + for (auto &shortcut : shortcuts_.shortcuts_) { + updates.push_back(get_update_quick_reply_shortcut_object(shortcut.get(), "get_current_state")); + if (have_all_shortcut_messages(shortcut.get())) { + updates.push_back(get_update_quick_reply_shortcut_messages_object(shortcut.get(), "get_current_state")); + } + } + + updates.push_back(get_update_quick_reply_shortcuts_object()); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/QuickReplyManager.h b/protocols/Telegram/tdlib/td/td/telegram/QuickReplyManager.h new file mode 100644 index 0000000000..c6807bc1a1 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/QuickReplyManager.h @@ -0,0 +1,479 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/files/FileSourceId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/QuickReplyMessageFullId.h" +#include "td/telegram/QuickReplyShortcutId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" +#include "td/utils/Slice.h" +#include "td/utils/Status.h" + +#include +#include +#include + +namespace td { + +class Dependencies; +struct InputMessageContent; +class MessageContent; +struct ReplyMarkup; +class Td; + +class QuickReplyManager final : public Actor { + public: + QuickReplyManager(Td *td, ActorShared<> parent); + + static Status check_shortcut_name(CSlice name); + + void get_quick_reply_shortcuts(Promise &&promise); + + void set_quick_reply_shortcut_name(QuickReplyShortcutId shortcut_id, const string &name, Promise &&promise); + + void delete_quick_reply_shortcut(QuickReplyShortcutId shortcut_id, Promise &&promise); + + void reorder_quick_reply_shortcuts(const vector &shortcut_ids, Promise &&promise); + + void update_quick_reply_message(telegram_api::object_ptr &&message_ptr); + + void delete_pending_message_web_page(QuickReplyMessageFullId message_full_id); + + void on_external_update_message_content(QuickReplyMessageFullId message_full_id, const char *source, + bool expect_no_message = false); + + void delete_quick_reply_messages_from_updates(QuickReplyShortcutId shortcut_id, const vector &message_ids); + + void get_quick_reply_shortcut_messages(QuickReplyShortcutId shortcut_id, Promise &&promise); + + void delete_quick_reply_shortcut_messages(QuickReplyShortcutId shortcut_id, const vector &message_ids, + Promise &&promise); + + Result> send_message( + const string &shortcut_name, MessageId reply_to_message_id, + td_api::object_ptr &&input_message_content); + + Result> send_inline_query_result_message(const string &shortcut_name, + MessageId reply_to_message_id, + int64 query_id, + const string &result_id, + bool hide_via_bot); + + Result> send_message_group( + const string &shortcut_name, MessageId reply_to_message_id, + vector> &&input_message_contents); + + Result> resend_messages(const string &shortcut_name, + vector message_ids); + + void edit_quick_reply_message(QuickReplyShortcutId shortcut_id, MessageId message_id, + td_api::object_ptr &&input_message_content, + Promise &&promise); + + void reload_quick_reply_shortcuts(); + + void reload_quick_reply_messages(QuickReplyShortcutId shortcut_id, Promise &&promise); + + void reload_quick_reply_message(QuickReplyShortcutId shortcut_id, MessageId message_id, Promise &&promise); + + struct QuickReplyMessageContent { + unique_ptr content_; + MessageId original_message_id_; + MessageId original_reply_to_message_id_; + unique_ptr reply_markup_; + UserId via_bot_user_id_; + int64 media_album_id_; + bool invert_media_; + bool disable_web_page_preview_; + }; + Result> get_quick_reply_message_contents(DialogId dialog_id, + QuickReplyShortcutId shortcut_id) const; + + FileSourceId get_quick_reply_message_file_source_id(QuickReplyMessageFullId message_full_id); + + void get_current_state(vector> &updates) const; + + private: + static constexpr size_t MAX_GROUPED_MESSAGES = 10; // server side limit + + struct QuickReplyMessage { + QuickReplyMessage() = default; + QuickReplyMessage(const QuickReplyMessage &) = delete; + QuickReplyMessage &operator=(const QuickReplyMessage &) = delete; + QuickReplyMessage(QuickReplyMessage &&) = delete; + QuickReplyMessage &operator=(QuickReplyMessage &&) = delete; + ~QuickReplyMessage(); + + MessageId message_id; + QuickReplyShortcutId shortcut_id; + int32 edit_date = 0; + + int64 random_id = 0; // for send_message + + MessageId reply_to_message_id; + + string send_emoji; // for send_message + + int64 inline_query_id = 0; // for send_message + string inline_result_id; // for send_message + + UserId via_bot_user_id; + + bool is_failed_to_send = false; + bool disable_notification = false; + bool invert_media = false; + bool disable_web_page_preview = false; + + bool from_background = false; // for send_message + bool hide_via_bot = false; // for resend_message + + bool edited_invert_media = false; + bool edited_disable_web_page_preview = false; + + int32 legacy_layer = 0; + + int32 send_error_code = 0; + string send_error_message; + double try_resend_at = 0; + + int64 media_album_id = 0; + + unique_ptr content; + unique_ptr reply_markup; + + unique_ptr edited_content; + int64 edit_generation = 0; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct Shortcut { + Shortcut() = default; + Shortcut(const Shortcut &) = delete; + Shortcut &operator=(const Shortcut &) = delete; + Shortcut(Shortcut &&) = delete; + Shortcut &operator=(Shortcut &&) = delete; + ~Shortcut(); + + string name_; + QuickReplyShortcutId shortcut_id_; + int32 server_total_count_ = 0; + int32 local_total_count_ = 0; + vector> messages_; + MessageId last_assigned_message_id_; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct Shortcuts { + vector> shortcuts_; + bool are_inited_ = false; + bool are_loaded_from_database_ = false; + + vector> load_queries_; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + class EditQuickReplyMessageQuery; + class SendQuickReplyInlineMessageQuery; + class SendQuickReplyMediaQuery; + class SendQuickReplyMessageQuery; + class SendQuickReplyMultiMediaQuery; + class UploadQuickReplyMediaQuery; + + class UploadMediaCallback; + class UploadThumbnailCallback; + + std::shared_ptr upload_media_callback_; + std::shared_ptr upload_thumbnail_callback_; + + void tear_down() final; + + static bool is_shortcut_name_letter(uint32 code); + + void add_quick_reply_message_dependencies(Dependencies &dependencies, const QuickReplyMessage *m) const; + + unique_ptr create_message(telegram_api::object_ptr message_ptr, + const char *source) const; + + bool can_edit_quick_reply_message(const QuickReplyMessage *m) const; + + bool can_resend_quick_reply_message(const QuickReplyMessage *m) const; + + td_api::object_ptr get_message_sending_state_object(const QuickReplyMessage *m) const; + + td_api::object_ptr get_quick_reply_message_message_content_object( + const QuickReplyMessage *m) const; + + td_api::object_ptr get_quick_reply_message_object(const QuickReplyMessage *m, + const char *source) const; + + td_api::object_ptr get_quick_reply_shortcut_object(const Shortcut *s, + const char *source) const; + + static int32 get_shortcut_message_count(const Shortcut *s); + + static bool have_all_shortcut_messages(const Shortcut *s); + + void on_reload_quick_reply_shortcuts( + Result> r_shortcuts); + + void on_load_quick_reply_success(); + + void on_load_quick_reply_fail(Status error); + + void on_set_quick_reply_shortcut_name(QuickReplyShortcutId shortcut_id, const string &name, Promise &&promise); + + int64 get_shortcuts_hash() const; + + void on_reload_quick_reply_messages(QuickReplyShortcutId shortcut_id, + Result> r_messages); + + static int64 get_quick_reply_messages_hash(const Shortcut *s); + + void on_reload_quick_reply_message(QuickReplyShortcutId shortcut_id, MessageId message_id, + Result> r_messages, + Promise &&promise); + + void on_get_quick_reply_message(Shortcut *s, unique_ptr message); + + void update_quick_reply_message(unique_ptr &old_message, + unique_ptr &&new_message); + + void delete_quick_reply_messages(Shortcut *s, const vector &message_ids, const char *source); + + Shortcut *get_shortcut(QuickReplyShortcutId shortcut_id); + + const Shortcut *get_shortcut(QuickReplyShortcutId shortcut_id) const; + + Shortcut *get_shortcut(const string &name); + + vector>::iterator get_shortcut_it(QuickReplyShortcutId shortcut_id); + + vector>::iterator get_message_it(Shortcut *s, MessageId message_id); + + const QuickReplyMessage *get_message(QuickReplyMessageFullId message_full_id) const; + + const QuickReplyMessage *get_message(const Shortcut *s, MessageId message_id) const; + + QuickReplyMessage *get_message_editable(QuickReplyMessageFullId message_full_id); + + QuickReplyMessage *get_message_editable(Shortcut *s, MessageId message_id); + + Result create_new_local_shortcut(const string &name, int32 new_message_count); + + static MessageId get_input_reply_to_message_id(const Shortcut *s, MessageId reply_to_message_id); + + Result process_input_message_content( + td_api::object_ptr &&input_message_content); + + MessageId get_next_message_id(Shortcut *s, MessageType type) const; + + MessageId get_next_yet_unsent_message_id(Shortcut *s) const; + + MessageId get_next_local_message_id(Shortcut *s) const; + + QuickReplyMessage *add_local_message(Shortcut *s, MessageId reply_to_message_id, unique_ptr &&content, + bool invert_media, UserId via_bot_user_id, bool hide_via_bot, + bool disable_web_page_preview, string &&send_emoji); + + bool is_shortcut_list_changed(const vector> &new_shortcuts) const; + + vector get_shortcut_ids() const; + + vector get_server_shortcut_ids() const; + + static void sort_quick_reply_messages(vector> &messages); + + using QuickReplyMessageUniqueId = std::pair; + + static QuickReplyMessageUniqueId get_quick_reply_unique_id(const QuickReplyMessage *m); + + static vector get_quick_reply_unique_ids( + const vector> &messages); + + static vector get_server_quick_reply_unique_ids( + const vector> &messages); + + void update_shortcut_from(Shortcut *new_shortcut, Shortcut *old_shortcut, bool is_partial, bool *is_shortcut_changed, + bool *are_messages_changed); + + td_api::object_ptr get_update_quick_reply_shortcut_object(const Shortcut *s, + const char *source) const; + + void send_update_quick_reply_shortcut(const Shortcut *s, const char *source); + + td_api::object_ptr get_update_quick_reply_shortcut_deleted_object( + const Shortcut *s) const; + + void send_update_quick_reply_shortcut_deleted(const Shortcut *s); + + td_api::object_ptr get_update_quick_reply_shortcuts_object() const; + + void send_update_quick_reply_shortcuts(); + + td_api::object_ptr get_update_quick_reply_shortcut_messages_object( + const Shortcut *s, const char *source) const; + + void send_update_quick_reply_shortcut_messages(const Shortcut *s, const char *source); + + void set_quick_reply_shortcut_name_on_server(QuickReplyShortcutId shortcut_id, const string &name, + Promise &&promise); + + void delete_quick_reply_shortcut_from_server(QuickReplyShortcutId shortcut_id, Promise &&promise); + + void reorder_quick_reply_shortcuts_on_server(vector shortcut_ids, Promise &&promise); + + void delete_quick_reply_messages_on_server(QuickReplyShortcutId shortcut_id, const vector &message_ids, + Promise &&promise); + + telegram_api::object_ptr get_input_quick_reply_shortcut( + QuickReplyShortcutId shortcut_id) const; + + Status check_send_quick_reply_messages_response(QuickReplyShortcutId shortcut_id, + const telegram_api::object_ptr &updates_ptr, + const vector &random_ids); + + void process_send_quick_reply_updates(QuickReplyShortcutId shortcut_id, + telegram_api::object_ptr updates_ptr, + vector random_ids); + + void on_failed_send_quick_reply_messages(QuickReplyShortcutId shortcut_id, vector random_ids, Status error); + + void update_sent_message_content_from_temporary_message(const QuickReplyMessage *old_message, + QuickReplyMessage *new_message, bool is_edit); + + void update_sent_message_content_from_temporary_message(const unique_ptr &old_content, + unique_ptr &new_content, + bool need_merge_files); + + void do_send_message(const QuickReplyMessage *m, vector bad_parts = {}); + + void on_send_message_file_parts_missing(QuickReplyShortcutId shortcut_id, int64 random_id, vector &&bad_parts); + + void on_send_message_file_reference_error(QuickReplyShortcutId shortcut_id, int64 random_id); + + void on_upload_media(FileId file_id, telegram_api::object_ptr input_file); + + void do_send_media(const QuickReplyMessage *m, FileId file_id, FileId thumbnail_file_id, + telegram_api::object_ptr input_file, + telegram_api::object_ptr input_thumbnail); + + void on_upload_media_error(FileId file_id, Status status); + + void on_upload_thumbnail(FileId thumbnail_file_id, + telegram_api::object_ptr thumbnail_input_file); + + void on_upload_message_media_success(QuickReplyShortcutId shortcut_id, MessageId message_id, FileId file_id, + telegram_api::object_ptr &&media); + + void on_upload_message_media_fail(QuickReplyShortcutId shortcut_id, MessageId message_id, Status error); + + void on_upload_message_media_finished(int64 media_album_id, QuickReplyShortcutId shortcut_id, MessageId message_id, + Status result); + + void do_send_message_group(QuickReplyShortcutId shortcut_id, int64 media_album_id); + + void on_message_media_uploaded(const QuickReplyMessage *m, + telegram_api::object_ptr &&input_media, FileId file_id, + FileId thumbnail_file_id); + + void on_send_media_group_file_reference_error(QuickReplyShortcutId shortcut_id, vector random_ids); + + int64 generate_new_media_album_id() const; + + void on_edit_quick_reply_message(QuickReplyShortcutId shortcut_id, MessageId message_id, int64 edit_generation, + FileId file_id, bool was_uploaded, + telegram_api::object_ptr updates_ptr); + + void fail_edit_quick_reply_message(QuickReplyShortcutId shortcut_id, MessageId message_id, int64 edit_generation, + FileId file_id, FileId thumbnail_file_id, string file_reference, bool was_uploaded, + bool was_thumbnail_uploaded, Status status); + + string get_quick_reply_shortcuts_database_key(); + + void save_quick_reply_shortcuts(); + + void load_quick_reply_shortcuts(); + + vector get_message_file_ids(const QuickReplyMessage *m) const; + + void delete_message_files(const QuickReplyMessage *m) const; + + void change_message_files(const QuickReplyMessage *m, const vector &old_file_ids); + + void register_new_message(const QuickReplyMessage *m, const char *source); + + void register_message_content(const QuickReplyMessage *m, const char *source) const; + + void unregister_message_content(const QuickReplyMessage *m, const char *source) const; + + Shortcuts shortcuts_; + + int32 next_local_shortcut_id_ = QuickReplyShortcutId::MAX_SERVER_SHORTCUT_ID + 1; + + FlatHashSet deleted_shortcut_ids_; + + FlatHashMap persistent_shortcut_ids_; + + FlatHashMap>, QuickReplyShortcutIdHash> get_shortcut_messages_queries_; + + FlatHashSet deleted_message_full_ids_; + + FlatHashMap message_full_id_to_file_source_id_; + + FlatHashMap, FileIdHash> + being_uploaded_files_; // file_id -> message, thumbnail_file_id + + struct UploadedThumbnailInfo { + QuickReplyMessageFullId quick_reply_message_full_id; + FileId file_id; // original file file_id + telegram_api::object_ptr input_file; // original file InputFile + int64 edit_generation; + }; + FlatHashMap being_uploaded_thumbnails_; // thumbnail_file_id -> ... + + struct PendingMessageGroupSend { + size_t finished_count = 0; + vector message_ids; + vector is_finished; + vector results; + }; + FlatHashMap pending_message_group_sends_; // media_album_id -> ... + + int64 current_message_edit_generation_ = 0; + + Td *td_; + ActorShared<> parent_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/QuickReplyMessageFullId.h b/protocols/Telegram/tdlib/td/td/telegram/QuickReplyMessageFullId.h new file mode 100644 index 0000000000..4a84711068 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/QuickReplyMessageFullId.h @@ -0,0 +1,79 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/MessageId.h" +#include "td/telegram/QuickReplyShortcutId.h" + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +struct QuickReplyMessageFullId { + private: + QuickReplyShortcutId quick_reply_shortcut_id; + MessageId message_id; + + public: + QuickReplyMessageFullId() = default; + + QuickReplyMessageFullId(QuickReplyShortcutId quick_reply_shortcut_id, MessageId message_id) + : quick_reply_shortcut_id(quick_reply_shortcut_id), message_id(message_id) { + } + + bool operator==(const QuickReplyMessageFullId &other) const { + return quick_reply_shortcut_id == other.quick_reply_shortcut_id && message_id == other.message_id; + } + + bool operator!=(const QuickReplyMessageFullId &other) const { + return !(*this == other); + } + + QuickReplyShortcutId get_quick_reply_shortcut_id() const { + return quick_reply_shortcut_id; + } + + MessageId get_message_id() const { + return message_id; + } + + bool is_valid() const { + return quick_reply_shortcut_id.is_valid() && message_id.is_valid(); + } + + bool is_server() const { + return quick_reply_shortcut_id.is_valid() && message_id.is_server(); + } + + template + void store(StorerT &storer) const { + quick_reply_shortcut_id.store(storer); + message_id.store(storer); + } + + template + void parse(ParserT &parser) { + quick_reply_shortcut_id.parse(parser); + message_id.parse(parser); + } +}; + +struct QuickReplyMessageFullIdHash { + uint32 operator()(QuickReplyMessageFullId quick_reply_message_full_id) const { + return combine_hashes(QuickReplyShortcutIdHash()(quick_reply_message_full_id.get_quick_reply_shortcut_id()), + MessageIdHash()(quick_reply_message_full_id.get_message_id())); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, QuickReplyMessageFullId quick_reply_message_full_id) { + return string_builder << quick_reply_message_full_id.get_message_id() << " from " + << quick_reply_message_full_id.get_quick_reply_shortcut_id(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/QuickReplyShortcutId.h b/protocols/Telegram/tdlib/td/td/telegram/QuickReplyShortcutId.h new file mode 100644 index 0000000000..b213ccd3e6 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/QuickReplyShortcutId.h @@ -0,0 +1,94 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +#include + +namespace td { + +class QuickReplyShortcutId { + int32 id = 0; + + public: + static constexpr int32 MAX_SERVER_SHORTCUT_ID = 1999999999; + + QuickReplyShortcutId() = default; + + explicit constexpr QuickReplyShortcutId(int32 quick_reply_shortcut_id) : id(quick_reply_shortcut_id) { + } + template ::value>> + QuickReplyShortcutId(T quick_reply_shortcut_id) = delete; + + int32 get() const { + return id; + } + + static vector get_input_quick_reply_shortcut_ids( + const vector &quick_reply_shortcut_ids) { + vector input_quick_reply_shortcut_ids; + input_quick_reply_shortcut_ids.reserve(quick_reply_shortcut_ids.size()); + for (auto &quick_reply_shortcut_id : quick_reply_shortcut_ids) { + input_quick_reply_shortcut_ids.emplace_back(quick_reply_shortcut_id.get()); + } + return input_quick_reply_shortcut_ids; + } + + static vector get_quick_reply_shortcut_ids(const vector &shortcut_ids) { + vector quick_reply_shortcut_ids; + quick_reply_shortcut_ids.reserve(shortcut_ids.size()); + for (auto &shortcut_id : shortcut_ids) { + quick_reply_shortcut_ids.emplace_back(shortcut_id); + } + return quick_reply_shortcut_ids; + } + + bool operator==(const QuickReplyShortcutId &other) const { + return id == other.id; + } + + bool operator!=(const QuickReplyShortcutId &other) const { + return id != other.id; + } + + bool is_valid() const { + return id > 0; + } + + bool is_server() const { + return id > 0 && id <= MAX_SERVER_SHORTCUT_ID; + } + + bool is_local() const { + return id > MAX_SERVER_SHORTCUT_ID; + } + + template + void store(StorerT &storer) const { + storer.store_int(id); + } + + template + void parse(ParserT &parser) { + id = parser.fetch_int(); + } +}; + +struct QuickReplyShortcutIdHash { + uint32 operator()(QuickReplyShortcutId quick_reply_shortcut_id) const { + return Hash()(quick_reply_shortcut_id.get()); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, QuickReplyShortcutId quick_reply_shortcut_id) { + return string_builder << "shortcut " << quick_reply_shortcut_id.get(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionListType.cpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionListType.cpp new file mode 100644 index 0000000000..e3afbdee5a --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionListType.cpp @@ -0,0 +1,39 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/ReactionListType.h" + +namespace td { + +string get_reaction_list_type_database_key(ReactionListType reaction_list_type) { + switch (reaction_list_type) { + case ReactionListType::Recent: + return "recent_reactions"; + case ReactionListType::Top: + return "top_reactions"; + case ReactionListType::DefaultTag: + return "default_tag_reactions"; + default: + UNREACHABLE(); + return string(); + } +} + +StringBuilder &operator<<(StringBuilder &string_builder, ReactionListType reaction_list_type) { + switch (reaction_list_type) { + case ReactionListType::Recent: + return string_builder << "recent reactions"; + case ReactionListType::Top: + return string_builder << "top reactions"; + case ReactionListType::DefaultTag: + return string_builder << "default tag reactions"; + default: + UNREACHABLE(); + return string_builder; + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionListType.h b/protocols/Telegram/tdlib/td/td/telegram/ReactionListType.h new file mode 100644 index 0000000000..0d1c8ee782 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionListType.h @@ -0,0 +1,22 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +enum class ReactionListType : int32 { Recent, Top, DefaultTag }; + +static constexpr int32 MAX_REACTION_LIST_TYPE = 3; + +string get_reaction_list_type_database_key(ReactionListType reaction_list_type); + +StringBuilder &operator<<(StringBuilder &string_builder, ReactionListType reaction_list_type); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.cpp new file mode 100644 index 0000000000..9825517136 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.cpp @@ -0,0 +1,1489 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/ReactionManager.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/ConfigManager.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/logevent/LogEvent.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/misc.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/ReactionManager.hpp" +#include "td/telegram/ReactionType.hpp" +#include "td/telegram/SavedMessagesManager.h" +#include "td/telegram/StickerFormat.h" +#include "td/telegram/StickersManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" + +#include "td/db/SqliteKeyValue.h" +#include "td/db/SqliteKeyValueAsync.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/FlatHashSet.h" +#include "td/utils/logging.h" +#include "td/utils/ScopeGuard.h" +#include "td/utils/SliceBuilder.h" +#include "td/utils/Status.h" +#include "td/utils/tl_helpers.h" + +#include +#include + +namespace td { + +class GetAvailableReactionsQuery final : public Td::ResultHandler { + public: + void send(int32 hash) { + send_query(G()->net_query_creator().create(telegram_api::messages_getAvailableReactions(hash))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetAvailableReactionsQuery: " << to_string(ptr); + td_->reaction_manager_->on_get_available_reactions(std::move(ptr)); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for GetAvailableReactionsQuery: " << status; + td_->reaction_manager_->on_get_available_reactions(nullptr); + } +}; + +class GetReactionListQuery final : public Td::ResultHandler { + ReactionListType reaction_list_type_; + + public: + void send(ReactionListType reaction_list_type, int64 hash) { + reaction_list_type_ = reaction_list_type; + switch (reaction_list_type) { + case ReactionListType::Recent: + send_query(G()->net_query_creator().create( + telegram_api::messages_getRecentReactions(ReactionManager::MAX_RECENT_REACTIONS, hash))); + break; + case ReactionListType::Top: + send_query(G()->net_query_creator().create(telegram_api::messages_getTopReactions(200, hash))); + break; + case ReactionListType::DefaultTag: + send_query(G()->net_query_creator().create(telegram_api::messages_getDefaultTagReactions(hash))); + break; + default: + UNREACHABLE(); + break; + } + } + + void on_result(BufferSlice packet) final { + static_assert(std::is_same::value, + ""); + static_assert(std::is_same::value, + ""); + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetReactionListQuery: " << to_string(ptr); + td_->reaction_manager_->on_get_reaction_list(reaction_list_type_, std::move(ptr)); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for GetReactionListQuery: " << status; + td_->reaction_manager_->on_get_reaction_list(reaction_list_type_, nullptr); + } +}; + +class ClearRecentReactionsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ClearRecentReactionsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::messages_clearRecentReactions())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->reaction_manager_->reload_reaction_list(ReactionListType::Recent, "ClearRecentReactionsQuery"); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + if (!G()->is_expected_error(status)) { + LOG(ERROR) << "Receive error for clear recent reactions: " << status; + } + td_->reaction_manager_->reload_reaction_list(ReactionListType::Recent, "ClearRecentReactionsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class SetDefaultReactionQuery final : public Td::ResultHandler { + ReactionType reaction_type_; + + public: + void send(const ReactionType &reaction_type) { + reaction_type_ = reaction_type; + send_query( + G()->net_query_creator().create(telegram_api::messages_setDefaultReaction(reaction_type.get_input_reaction()))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + if (!result_ptr.ok()) { + return on_error(Status::Error(400, "Receive false")); + } + + auto default_reaction = td_->option_manager_->get_option_string("default_reaction", "-"); + if (default_reaction != reaction_type_.get_string()) { + td_->reaction_manager_->send_set_default_reaction_query(); + } else { + td_->option_manager_->set_option_empty("default_reaction_needs_sync"); + } + } + + void on_error(Status status) final { + if (G()->close_flag()) { + return; + } + + LOG(INFO) << "Receive error for SetDefaultReactionQuery: " << status; + td_->option_manager_->set_option_empty("default_reaction_needs_sync"); + send_closure(G()->config_manager(), &ConfigManager::request_config, false); + } +}; + +class GetSavedReactionTagsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetSavedReactionTagsQuery( + Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(SavedMessagesTopicId saved_messages_topic_id, int64 hash) { + int32 flags = 0; + telegram_api::object_ptr saved_input_peer; + if (saved_messages_topic_id.is_valid()) { + flags |= telegram_api::messages_getSavedReactionTags::PEER_MASK; + saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + } + send_query(G()->net_query_creator().create( + telegram_api::messages_getSavedReactionTags(flags, std::move(saved_input_peer), hash), + {td_->dialog_manager_->get_my_dialog_id()})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetSavedReactionTagsQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class UpdateSavedReactionTagQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit UpdateSavedReactionTagQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const ReactionType &reaction_type, const string &title) { + int32 flags = 0; + if (!title.empty()) { + flags |= telegram_api::messages_updateSavedReactionTag::TITLE_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::messages_updateSavedReactionTag(flags, reaction_type.get_input_reaction(), title))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetMessageAvailableEffectsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetMessageAvailableEffectsQuery( + Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(int32 hash) { + send_query(G()->net_query_creator().create(telegram_api::messages_getAvailableEffects(hash))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetMessageAvailableEffectsQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +ReactionManager::SavedReactionTag::SavedReactionTag(telegram_api::object_ptr &&tag) + : reaction_type_(tag->reaction_) + , hash_(reaction_type_.get_hash()) + , title_(std::move(tag->title_)) + , count_(tag->count_) { +} + +ReactionManager::SavedReactionTag::SavedReactionTag(const ReactionType &reaction_type, const string &title, int32 count) + : reaction_type_(reaction_type), hash_(reaction_type_.get_hash()), title_(title), count_(count) { +} + +td_api::object_ptr ReactionManager::SavedReactionTag::get_saved_messages_tag_object() const { + return td_api::make_object(reaction_type_.get_reaction_type_object(), title_, count_); +} + +template +void ReactionManager::SavedReactionTag::store(StorerT &storer) const { + bool has_title = !title_.empty(); + bool has_count = count_ != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_title); + STORE_FLAG(has_count); + END_STORE_FLAGS(); + td::store(reaction_type_, storer); + if (has_title) { + td::store(title_, storer); + } + if (has_count) { + td::store(count_, storer); + } +} + +template +void ReactionManager::SavedReactionTag::parse(ParserT &parser) { + bool has_title; + bool has_count; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_title); + PARSE_FLAG(has_count); + END_PARSE_FLAGS(); + td::parse(reaction_type_, parser); + hash_ = reaction_type_.get_hash(); + if (has_title) { + td::parse(title_, parser); + } + if (has_count) { + td::parse(count_, parser); + } +} + +bool operator==(const ReactionManager::SavedReactionTag &lhs, const ReactionManager::SavedReactionTag &rhs) { + return lhs.reaction_type_ == rhs.reaction_type_ && lhs.title_ == rhs.title_ && lhs.count_ == rhs.count_; +} + +bool operator!=(const ReactionManager::SavedReactionTag &lhs, const ReactionManager::SavedReactionTag &rhs) { + return !(lhs == rhs); +} + +bool operator<(const ReactionManager::SavedReactionTag &lhs, const ReactionManager::SavedReactionTag &rhs) { + if (lhs.count_ != rhs.count_) { + return lhs.count_ > rhs.count_; + } + return lhs.hash_ > rhs.hash_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const ReactionManager::SavedReactionTag &saved_reaction_tag) { + return string_builder << "SavedMessagesTag{" << saved_reaction_tag.reaction_type_ << '(' << saved_reaction_tag.title_ + << ") X " << saved_reaction_tag.count_ << '}'; +} + +td_api::object_ptr ReactionManager::SavedReactionTags::get_saved_messages_tags_object() + const { + return td_api::make_object( + transform(tags_, [](const SavedReactionTag &tag) { return tag.get_saved_messages_tag_object(); })); +} + +bool ReactionManager::SavedReactionTags::update_saved_messages_tags(const vector &old_tags, + const vector &new_tags) { + if (!is_inited_) { + return false; + } + bool is_changed = false; + for (const auto &old_tag : old_tags) { + if (!td::contains(new_tags, old_tag)) { + CHECK(!old_tag.is_empty()); + for (auto it = tags_.begin(); it != tags_.end(); ++it) { + auto &tag = *it; + if (tag.reaction_type_ == old_tag) { + tag.count_--; + if (!tag.is_valid()) { + tags_.erase(it); + } + is_changed = true; + break; + } + } + } + } + for (const auto &new_tag : new_tags) { + if (!td::contains(old_tags, new_tag)) { + CHECK(!new_tag.is_empty()); + is_changed = true; + bool is_found = false; + for (auto &tag : tags_) { + if (tag.reaction_type_ == new_tag) { + tag.count_++; + is_found = true; + break; + } + } + if (!is_found) { + tags_.emplace_back(new_tag, string(), 1); + } + } + } + if (is_changed) { + std::sort(tags_.begin(), tags_.end()); + hash_ = calc_hash(); + } + return is_changed; +} + +bool ReactionManager::SavedReactionTags::set_tag_title(const ReactionType &reaction_type, const string &title) { + if (!is_inited_) { + return false; + } + for (auto it = tags_.begin(); it != tags_.end(); ++it) { + auto &tag = *it; + if (tag.reaction_type_ == reaction_type) { + if (tag.title_ == title) { + return false; + } + tag.title_ = title; + if (!tag.is_valid()) { + tags_.erase(it); + } + hash_ = calc_hash(); + return true; + } + } + tags_.emplace_back(reaction_type, title, 0); + std::sort(tags_.begin(), tags_.end()); + hash_ = calc_hash(); + return true; +} + +int64 ReactionManager::SavedReactionTags::calc_hash() const { + vector numbers; + for (const auto &tag : tags_) { + numbers.push_back(tag.hash_); + if (!tag.title_.empty()) { + numbers.push_back(get_md5_string_hash(tag.title_)); + } + numbers.push_back(tag.count_); + } + return get_vector_hash(numbers); +} + +template +void ReactionManager::SavedReactionTags::store(StorerT &storer) const { + CHECK(is_inited_); + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + td::store(tags_, storer); +} + +template +void ReactionManager::SavedReactionTags::parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + td::parse(tags_, parser); + hash_ = calc_hash(); + is_inited_ = true; +} + +ReactionManager::ReactionManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +ReactionManager::~ReactionManager() = default; + +void ReactionManager::start_up() { + init(); +} + +void ReactionManager::tear_down() { + parent_.reset(); +} + +void ReactionManager::init() { + if (G()->close_flag()) { + return; + } + if (is_inited_ || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { + return; + } + is_inited_ = true; + + td_->stickers_manager_->init(); + + load_active_reactions(); + load_active_message_effects(); + + if (td_->option_manager_->get_option_boolean("default_reaction_needs_sync")) { + send_set_default_reaction_query(); + } +} + +td_api::object_ptr ReactionManager::get_emoji_reaction_object(const string &emoji) const { + for (auto &reaction : reactions_.reactions_) { + if (reaction.reaction_type_.get_string() == emoji) { + return td_api::make_object( + reaction.reaction_type_.get_string(), reaction.title_, reaction.is_active_, + td_->stickers_manager_->get_sticker_object(reaction.static_icon_), + td_->stickers_manager_->get_sticker_object(reaction.appear_animation_), + td_->stickers_manager_->get_sticker_object(reaction.select_animation_), + td_->stickers_manager_->get_sticker_object(reaction.activate_animation_), + td_->stickers_manager_->get_sticker_object(reaction.effect_animation_), + td_->stickers_manager_->get_sticker_object(reaction.around_animation_), + td_->stickers_manager_->get_sticker_object(reaction.center_animation_)); + } + } + return nullptr; +} + +void ReactionManager::get_emoji_reaction(const string &emoji, + Promise> &&promise) { + load_reactions(); + if (reactions_.reactions_.empty() && reactions_.are_being_reloaded_) { + pending_get_emoji_reaction_queries_.emplace_back(emoji, std::move(promise)); + return; + } + promise.set_value(get_emoji_reaction_object(emoji)); +} + +td_api::object_ptr ReactionManager::get_sorted_available_reactions( + ChatReactions available_reactions, ChatReactions active_reactions, int32 row_size, bool is_tag, + ReactionUnavailabilityReason unavailability_reason) { + if (is_tag) { + load_reaction_list(ReactionListType::DefaultTag); + } else { + load_reaction_list(ReactionListType::Recent); + } + load_reaction_list(ReactionListType::Top); + + if (row_size < 5 || row_size > 25) { + row_size = 8; + } + + bool is_premium = td_->option_manager_->get_option_boolean("is_premium"); + bool show_premium = is_premium || is_tag; + vector recent_reactions; + vector top_reactions; + if (is_tag) { + if (is_premium) { + auto all_tags = get_saved_reaction_tags(SavedMessagesTopicId()); + for (auto &tag : all_tags->tags_) { + top_reactions.push_back(tag.reaction_type_); + } + for (auto &reaction_type : get_reaction_list(ReactionListType::DefaultTag).reaction_types_) { + if (!td::contains(top_reactions, reaction_type)) { + top_reactions.push_back(reaction_type); + } + } + for (auto &reaction_type : get_reaction_list(ReactionListType::Top).reaction_types_) { + if (!td::contains(top_reactions, reaction_type)) { + top_reactions.push_back(reaction_type); + } + } + } else { + top_reactions = get_reaction_list(ReactionListType::DefaultTag).reaction_types_; + } + } else { + recent_reactions = get_reaction_list(ReactionListType::Recent).reaction_types_; + top_reactions = get_reaction_list(ReactionListType::Top).reaction_types_; + } + LOG(INFO) << "Have available reactions " << available_reactions << " to be sorted by top reactions " << top_reactions + << " and recent reactions " << recent_reactions + << " and paid reaction = " << available_reactions.paid_reactions_available_; + if (active_reactions.allow_all_custom_ && active_reactions.allow_all_regular_) { + for (auto &reaction_type : recent_reactions) { + if (reaction_type.is_custom_reaction()) { + show_premium = true; + } + } + for (auto &reaction_type : top_reactions) { + if (reaction_type.is_custom_reaction()) { + show_premium = true; + } + } + } + + FlatHashSet all_available_reaction_types; + for (const auto &reaction_type : available_reactions.reaction_types_) { + CHECK(!reaction_type.is_empty()); + all_available_reaction_types.insert(reaction_type); + } + if (available_reactions.paid_reactions_available_ || + (!available_reactions.reaction_types_.empty() && available_reactions.reaction_types_[0].is_paid_reaction())) { + all_available_reaction_types.insert(ReactionType::paid()); + top_reactions.insert(top_reactions.begin(), ReactionType::paid()); + } + + vector> top_reaction_objects; + vector> recent_reaction_objects; + vector> popular_reaction_objects; + vector> last_reaction_objects; + + FlatHashSet added_custom_reaction_types; + auto add_reactions = [&](vector> &reaction_objects, + const vector &reaction_types) { + for (auto &reaction_type : reaction_types) { + if (all_available_reaction_types.erase(reaction_type) != 0) { + // add available reaction + if (reaction_type.is_custom_reaction()) { + added_custom_reaction_types.insert(reaction_type); + } + reaction_objects.push_back(td_api::make_object( + reaction_type.get_reaction_type_object(), is_tag && !is_premium)); + } else if (reaction_type.is_custom_reaction() && available_reactions.allow_all_custom_ && + added_custom_reaction_types.insert(reaction_type).second) { + // add implicitly available custom reaction + reaction_objects.push_back( + td_api::make_object(reaction_type.get_reaction_type_object(), !is_premium)); + } else { + // skip the reaction + } + } + }; + if (show_premium) { + if (!is_tag && top_reactions.size() > 2 * static_cast(row_size)) { + top_reactions.resize(2 * static_cast(row_size)); + } + add_reactions(top_reaction_objects, top_reactions); + add_reactions(recent_reaction_objects, recent_reactions); + } else { + add_reactions(top_reaction_objects, top_reactions); + } + add_reactions(last_reaction_objects, active_reaction_types_); + add_reactions(last_reaction_objects, available_reactions.reaction_types_); + + if (show_premium) { + if (recent_reactions.empty()) { + popular_reaction_objects = std::move(last_reaction_objects); + } else { + auto max_objects = 10 * static_cast(row_size); + if (recent_reaction_objects.size() + last_reaction_objects.size() > max_objects) { + if (last_reaction_objects.size() < max_objects) { + recent_reaction_objects.resize(max_objects - last_reaction_objects.size()); + } else { + recent_reaction_objects.clear(); + } + } + append(recent_reaction_objects, std::move(last_reaction_objects)); + } + } else { + append(top_reaction_objects, std::move(last_reaction_objects)); + } + + CHECK(all_available_reaction_types.empty()); + + td_api::object_ptr reason; + switch (unavailability_reason) { + case ReactionUnavailabilityReason::None: + break; + case ReactionUnavailabilityReason::AnonymousAdministrator: + reason = td_api::make_object(); + break; + case ReactionUnavailabilityReason::Guest: + reason = td_api::make_object(); + break; + default: + UNREACHABLE(); + } + + return td_api::make_object( + std::move(top_reaction_objects), std::move(recent_reaction_objects), std::move(popular_reaction_objects), + available_reactions.allow_all_custom_, is_tag, std::move(reason)); +} + +td_api::object_ptr ReactionManager::get_available_reactions(int32 row_size) { + ChatReactions available_reactions; + available_reactions.reaction_types_ = active_reaction_types_; + available_reactions.allow_all_custom_ = true; + return get_sorted_available_reactions(std::move(available_reactions), ChatReactions(true, true), row_size, false, + ReactionUnavailabilityReason::None); +} + +void ReactionManager::add_recent_reaction(const ReactionType &reaction_type) { + load_reaction_list(ReactionListType::Recent); + + auto &recent_reactions = get_reaction_list(ReactionListType::Recent); + auto &reactions = recent_reactions.reaction_types_; + if (!reactions.empty() && reactions[0] == reaction_type) { + return; + } + CHECK(!reaction_type.is_paid_reaction()); + + add_to_top(reactions, MAX_RECENT_REACTIONS, reaction_type); + + recent_reactions.hash_ = get_reaction_types_hash(reactions); +} + +void ReactionManager::clear_recent_reactions(Promise &&promise) { + load_reaction_list(ReactionListType::Recent); + + auto &recent_reactions = get_reaction_list(ReactionListType::Recent); + if (recent_reactions.reaction_types_.empty()) { + return promise.set_value(Unit()); + } + + recent_reactions.hash_ = 0; + recent_reactions.reaction_types_.clear(); + + td_->create_handler(std::move(promise))->send(); +} + +vector ReactionManager::get_default_tag_reactions() { + load_reaction_list(ReactionListType::DefaultTag); + + return get_reaction_list(ReactionListType::DefaultTag).reaction_types_; +} + +void ReactionManager::reload_reactions() { + if (G()->close_flag() || reactions_.are_being_reloaded_) { + return; + } + CHECK(!td_->auth_manager_->is_bot()); + reactions_.are_being_reloaded_ = true; + load_reactions(); // must be after are_being_reloaded_ is set to true to avoid recursion + td_->create_handler()->send(reactions_.hash_); +} + +void ReactionManager::reload_reaction_list(ReactionListType reaction_list_type, const char *source) { + if (G()->close_flag()) { + return; + } + LOG(INFO) << "Reload " << reaction_list_type << " from " << source; + auto &reaction_list = get_reaction_list(reaction_list_type); + if (reaction_list.is_being_reloaded_) { + return; + } + CHECK(!td_->auth_manager_->is_bot()); + reaction_list.is_being_reloaded_ = true; + load_reaction_list(reaction_list_type); // must be after is_being_reloaded_ is set to true to avoid recursion + td_->create_handler()->send(reaction_list_type, reaction_list.hash_); +} + +td_api::object_ptr ReactionManager::get_update_active_emoji_reactions_object() + const { + return td_api::make_object( + transform(active_reaction_types_, [](const ReactionType &reaction_type) { return reaction_type.get_string(); })); +} + +ReactionManager::ReactionList &ReactionManager::get_reaction_list(ReactionListType reaction_list_type) { + return reaction_lists_[static_cast(reaction_list_type)]; +} + +void ReactionManager::save_active_reactions() { + LOG(INFO) << "Save " << active_reaction_types_.size() << " active reactions"; + G()->td_db()->get_binlog_pmc()->set("active_reactions", log_event_store(active_reaction_types_).as_slice().str()); +} + +void ReactionManager::save_reactions() { + LOG(INFO) << "Save " << reactions_.reactions_.size() << " available reactions"; + are_reactions_loaded_from_database_ = true; + G()->td_db()->get_binlog_pmc()->set("reactions", log_event_store(reactions_).as_slice().str()); +} + +void ReactionManager::save_reaction_list(ReactionListType reaction_list_type) { + auto &reaction_list = get_reaction_list(reaction_list_type); + LOG(INFO) << "Save " << reaction_list.reaction_types_.size() << ' ' << reaction_list_type; + reaction_list.is_loaded_from_database_ = true; + G()->td_db()->get_binlog_pmc()->set(get_reaction_list_type_database_key(reaction_list_type), + log_event_store(reaction_list).as_slice().str()); +} + +void ReactionManager::load_active_reactions() { + LOG(INFO) << "Loading active reactions"; + string active_reaction_types = G()->td_db()->get_binlog_pmc()->get("active_reactions"); + if (active_reaction_types.empty()) { + return reload_reactions(); + } + + auto status = log_event_parse(active_reaction_types_, active_reaction_types); + if (status.is_error()) { + LOG(ERROR) << "Can't load active reactions: " << status; + active_reaction_types_ = {}; + return reload_reactions(); + } + + LOG(INFO) << "Successfully loaded " << active_reaction_types_.size() << " active reactions"; + + td_->messages_manager_->set_active_reactions(active_reaction_types_); + + send_closure(G()->td(), &Td::send_update, get_update_active_emoji_reactions_object()); +} + +void ReactionManager::load_reactions() { + if (are_reactions_loaded_from_database_) { + return; + } + are_reactions_loaded_from_database_ = true; + + string reactions = G()->td_db()->get_binlog_pmc()->get("reactions"); + if (reactions.empty()) { + return reload_reactions(); + } + + LOG(INFO) << "Loaded available reactions of size " << reactions.size(); + Reactions new_reactions; + new_reactions.are_being_reloaded_ = reactions_.are_being_reloaded_; + auto status = log_event_parse(new_reactions, reactions); + if (status.is_error()) { + LOG(ERROR) << "Can't load available reactions: " << status; + return reload_reactions(); + } + for (auto &reaction_type : new_reactions.reactions_) { + if (!reaction_type.is_valid()) { + LOG(ERROR) << "Loaded invalid reaction"; + return reload_reactions(); + } + } + reactions_ = std::move(new_reactions); + + LOG(INFO) << "Successfully loaded " << reactions_.reactions_.size() << " available reactions"; + + update_active_reactions(); +} + +void ReactionManager::load_reaction_list(ReactionListType reaction_list_type) { + auto &reaction_list = get_reaction_list(reaction_list_type); + if (reaction_list.is_loaded_from_database_) { + return; + } + reaction_list.is_loaded_from_database_ = true; + + LOG(INFO) << "Loading " << reaction_list_type; + string reactions_str = G()->td_db()->get_binlog_pmc()->get(get_reaction_list_type_database_key(reaction_list_type)); + if (reactions_str.empty()) { + return reload_reaction_list(reaction_list_type, "load_reaction_list 1"); + } + + auto status = log_event_parse(reaction_list, reactions_str); + if (status.is_error()) { + LOG(ERROR) << "Can't load " << reaction_list_type << ": " << status; + reaction_list = {}; + return reload_reaction_list(reaction_list_type, "load_reaction_list 2"); + } + + LOG(INFO) << "Successfully loaded " << reaction_list.reaction_types_.size() << ' ' << reaction_list_type; +} + +void ReactionManager::update_active_reactions() { + vector active_reaction_types; + for (auto &reaction : reactions_.reactions_) { + if (reaction.is_active_) { + active_reaction_types.emplace_back(reaction.reaction_type_); + } + } + if (active_reaction_types == active_reaction_types_) { + return; + } + active_reaction_types_ = active_reaction_types; + + save_active_reactions(); + + send_closure(G()->td(), &Td::send_update, get_update_active_emoji_reactions_object()); + + td_->messages_manager_->set_active_reactions(std::move(active_reaction_types)); +} + +void ReactionManager::on_get_available_reactions( + tl_object_ptr &&available_reactions_ptr) { + CHECK(reactions_.are_being_reloaded_); + reactions_.are_being_reloaded_ = false; + + auto get_emoji_reaction_queries = std::move(pending_get_emoji_reaction_queries_); + pending_get_emoji_reaction_queries_.clear(); + SCOPE_EXIT { + for (auto &query : get_emoji_reaction_queries) { + query.second.set_value(get_emoji_reaction_object(query.first)); + } + }; + + if (available_reactions_ptr == nullptr) { + // failed to get available reactions + return; + } + + int32 constructor_id = available_reactions_ptr->get_id(); + if (constructor_id == telegram_api::messages_availableReactionsNotModified::ID) { + LOG(INFO) << "Available reactions are not modified"; + return; + } + + CHECK(constructor_id == telegram_api::messages_availableReactions::ID); + auto available_reactions = move_tl_object_as(available_reactions_ptr); + vector new_reactions; + for (auto &available_reaction : available_reactions->reactions_) { + Reaction reaction; + reaction.is_active_ = !available_reaction->inactive_; + reaction.is_premium_ = available_reaction->premium_; + reaction.reaction_type_ = ReactionType(std::move(available_reaction->reaction_)); + reaction.title_ = std::move(available_reaction->title_); + reaction.static_icon_ = + td_->stickers_manager_ + ->on_get_sticker_document(std::move(available_reaction->static_icon_), StickerFormat::Webp, "static_icon") + .second; + reaction.appear_animation_ = td_->stickers_manager_ + ->on_get_sticker_document(std::move(available_reaction->appear_animation_), + StickerFormat::Tgs, "appear_animation") + .second; + reaction.select_animation_ = td_->stickers_manager_ + ->on_get_sticker_document(std::move(available_reaction->select_animation_), + StickerFormat::Tgs, "select_animation") + .second; + reaction.activate_animation_ = td_->stickers_manager_ + ->on_get_sticker_document(std::move(available_reaction->activate_animation_), + StickerFormat::Tgs, "activate_animation") + .second; + reaction.effect_animation_ = td_->stickers_manager_ + ->on_get_sticker_document(std::move(available_reaction->effect_animation_), + StickerFormat::Tgs, "effect_animation") + .second; + reaction.around_animation_ = td_->stickers_manager_ + ->on_get_sticker_document(std::move(available_reaction->around_animation_), + StickerFormat::Tgs, "around_animation") + .second; + reaction.center_animation_ = td_->stickers_manager_ + ->on_get_sticker_document(std::move(available_reaction->center_icon_), + StickerFormat::Tgs, "center_animation") + .second; + + if (!reaction.is_valid()) { + LOG(ERROR) << "Receive invalid " << reaction.reaction_type_; + continue; + } + if (reaction.is_premium_) { + LOG(ERROR) << "Receive premium " << reaction.reaction_type_; + continue; + } + + new_reactions.push_back(std::move(reaction)); + } + reactions_.reactions_ = std::move(new_reactions); + reactions_.hash_ = available_reactions->hash_; + + save_reactions(); + + update_active_reactions(); +} + +void ReactionManager::on_get_reaction_list(ReactionListType reaction_list_type, + tl_object_ptr &&reactions_ptr) { + auto &reaction_list = get_reaction_list(reaction_list_type); + CHECK(reaction_list.is_being_reloaded_); + reaction_list.is_being_reloaded_ = false; + + if (reactions_ptr == nullptr) { + // failed to get reactions + return; + } + + int32 constructor_id = reactions_ptr->get_id(); + if (constructor_id == telegram_api::messages_reactionsNotModified::ID) { + LOG(INFO) << "List of " << reaction_list_type << " is not modified"; + return; + } + + CHECK(constructor_id == telegram_api::messages_reactions::ID); + auto reactions = move_tl_object_as(reactions_ptr); + auto new_reaction_types = ReactionType::get_reaction_types(reactions->reactions_); + if (new_reaction_types == reaction_list.reaction_types_ && reaction_list.hash_ == reactions->hash_) { + LOG(INFO) << "List of " << reaction_list_type << " is not modified"; + return; + } + reaction_list.reaction_types_ = std::move(new_reaction_types); + reaction_list.hash_ = reactions->hash_; + + auto expected_hash = get_reaction_types_hash(reaction_list.reaction_types_); + if (reaction_list.hash_ != expected_hash) { + LOG(ERROR) << "Receive hash " << reaction_list.hash_ << " instead of " << expected_hash << " for " + << reaction_list_type << reaction_list.reaction_types_; + } + + save_reaction_list(reaction_list_type); +} + +bool ReactionManager::is_active_reaction(const ReactionType &reaction_type) const { + return td::contains(active_reaction_types_, reaction_type); +} + +void ReactionManager::set_default_reaction(ReactionType reaction_type, Promise &&promise) { + if (reaction_type.is_empty()) { + return promise.set_error(Status::Error(400, "Default reaction must be non-empty")); + } + if (reaction_type.is_paid_reaction()) { + return promise.set_error(Status::Error(400, "Can't set paid reaction as default")); + } + if (!reaction_type.is_custom_reaction() && !is_active_reaction(reaction_type)) { + return promise.set_error(Status::Error(400, "Can't set inactive reaction as default")); + } + + if (td_->option_manager_->get_option_string("default_reaction", "-") != reaction_type.get_string()) { + td_->option_manager_->set_option_string("default_reaction", reaction_type.get_string()); + if (!td_->option_manager_->get_option_boolean("default_reaction_needs_sync")) { + td_->option_manager_->set_option_boolean("default_reaction_needs_sync", true); + send_set_default_reaction_query(); + } + } + promise.set_value(Unit()); +} + +void ReactionManager::send_set_default_reaction_query() { + td_->create_handler()->send( + ReactionType(td_->option_manager_->get_option_string("default_reaction"))); +} + +void ReactionManager::load_all_saved_reaction_tags_from_database() { + if (are_all_tags_loaded_from_database_ || all_tags_.is_inited_ || !G()->use_message_database()) { + return; + } + are_all_tags_loaded_from_database_ = true; + + auto value = G()->td_db()->get_sqlite_sync_pmc()->get(get_saved_messages_tags_database_key(SavedMessagesTopicId())); + if (!value.empty()) { + if (log_event_parse(all_tags_, value).is_ok()) { + send_update_saved_messages_tags(SavedMessagesTopicId(), &all_tags_, true); + } else { + LOG(ERROR) << "Failed to load all tags from database"; + all_tags_ = {}; + } + } + reget_saved_messages_tags(SavedMessagesTopicId(), Auto()); +} + +void ReactionManager::load_saved_reaction_tags_from_database(SavedMessagesTopicId saved_messages_topic_id, + SavedReactionTags *tags) { + if (!G()->use_message_database()) { + return; + } + + auto value = G()->td_db()->get_sqlite_sync_pmc()->get(get_saved_messages_tags_database_key(saved_messages_topic_id)); + if (value.empty()) { + return; + } + if (log_event_parse(*tags, value).is_error()) { + LOG(ERROR) << "Failed to load all tags from database"; + *tags = {}; + return; + } + + send_update_saved_messages_tags(saved_messages_topic_id, tags, true); + reget_saved_messages_tags(saved_messages_topic_id, Auto()); +} + +ReactionManager::SavedReactionTags *ReactionManager::get_saved_reaction_tags( + SavedMessagesTopicId saved_messages_topic_id) { + if (saved_messages_topic_id == SavedMessagesTopicId()) { + load_all_saved_reaction_tags_from_database(); + return &all_tags_; + } + auto &tags = topic_tags_[saved_messages_topic_id]; + if (tags == nullptr) { + tags = make_unique(); + load_saved_reaction_tags_from_database(saved_messages_topic_id, tags.get()); + } + return tags.get(); +} + +void ReactionManager::get_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, + Promise> &&promise) { + if (!saved_messages_topic_id.is_valid() && saved_messages_topic_id != SavedMessagesTopicId()) { + return promise.set_error(Status::Error(400, "Invalid Saved Messages topic specified")); + } + const auto *tags = get_saved_reaction_tags(saved_messages_topic_id); + if (tags->is_inited_) { + return promise.set_value(tags->get_saved_messages_tags_object()); + } + reget_saved_messages_tags(saved_messages_topic_id, std::move(promise)); +} + +void ReactionManager::reget_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, + Promise> &&promise) { + auto &promises = saved_messages_topic_id == SavedMessagesTopicId() + ? pending_get_all_saved_reaction_tags_queries_ + : pending_get_topic_saved_reaction_tags_queries_[saved_messages_topic_id]; + promises.push_back(std::move(promise)); + if (promises.size() != 1) { + return; + } + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), saved_messages_topic_id]( + Result> r_tags) { + send_closure(actor_id, &ReactionManager::on_get_saved_messages_tags, saved_messages_topic_id, + std::move(r_tags)); + }); + const auto *tags = get_saved_reaction_tags(saved_messages_topic_id); + td_->create_handler(std::move(query_promise))->send(saved_messages_topic_id, tags->hash_); +} + +void ReactionManager::on_get_saved_messages_tags( + SavedMessagesTopicId saved_messages_topic_id, + Result> &&r_tags) { + G()->ignore_result_if_closing(r_tags); + vector>> promises; + if (saved_messages_topic_id == SavedMessagesTopicId()) { + promises = std::move(pending_get_all_saved_reaction_tags_queries_); + reset_to_empty(pending_get_all_saved_reaction_tags_queries_); + } else { + auto it = pending_get_topic_saved_reaction_tags_queries_.find(saved_messages_topic_id); + CHECK(it != pending_get_topic_saved_reaction_tags_queries_.end()); + promises = std::move(it->second); + pending_get_topic_saved_reaction_tags_queries_.erase(it); + } + CHECK(!promises.empty()); + + if (r_tags.is_error()) { + return fail_promises(promises, r_tags.move_as_error()); + } + + auto tags_ptr = r_tags.move_as_ok(); + bool need_send_update = false; + auto *reaction_tags = get_saved_reaction_tags(saved_messages_topic_id); + switch (tags_ptr->get_id()) { + case telegram_api::messages_savedReactionTagsNotModified::ID: + if (!reaction_tags->is_inited_) { + LOG(ERROR) << "Receive messages.savedReactionTagsNotModified for non-inited tags"; + } + break; + case telegram_api::messages_savedReactionTags::ID: { + auto tags = telegram_api::move_object_as(tags_ptr); + vector saved_reaction_tags; + for (auto &tag : tags->tags_) { + saved_reaction_tags.emplace_back(std::move(tag)); + if (!saved_reaction_tags.back().is_valid()) { + LOG(ERROR) << "Receive " << saved_reaction_tags.back(); + saved_reaction_tags.pop_back(); + } + } + std::sort(saved_reaction_tags.begin(), saved_reaction_tags.end()); + reaction_tags->hash_ = tags->hash_; + if (saved_reaction_tags != reaction_tags->tags_) { + reaction_tags->tags_ = std::move(saved_reaction_tags); + need_send_update = true; + } + if (reaction_tags->hash_ != reaction_tags->calc_hash()) { + LOG(ERROR) << "Receive unexpected Saved Messages tag hash"; + } + reaction_tags->is_inited_ = true; + break; + } + default: + UNREACHABLE(); + } + + if (need_send_update) { + send_update_saved_messages_tags(saved_messages_topic_id, reaction_tags); + } + for (auto &promise : promises) { + if (promise) { + promise.set_value(reaction_tags->get_saved_messages_tags_object()); + } + } +} + +string ReactionManager::get_saved_messages_tags_database_key(SavedMessagesTopicId saved_messages_topic_id) { + return PSTRING() << "saved_messages_tags" << saved_messages_topic_id.get_unique_id(); +} + +td_api::object_ptr ReactionManager::get_update_saved_messages_tags_object( + SavedMessagesTopicId saved_messages_topic_id, const SavedReactionTags *tags) const { + CHECK(tags != nullptr); + return td_api::make_object( + td_->saved_messages_manager_->get_saved_messages_topic_id_object(saved_messages_topic_id), + tags->get_saved_messages_tags_object()); +} + +void ReactionManager::send_update_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, + const SavedReactionTags *tags, bool from_database) { + send_closure(G()->td(), &Td::send_update, get_update_saved_messages_tags_object(saved_messages_topic_id, tags)); + if (!from_database && G()->use_message_database()) { + G()->td_db()->get_sqlite_pmc()->set(get_saved_messages_tags_database_key(saved_messages_topic_id), + log_event_store(*tags).as_slice().str(), Promise()); + } +} + +void ReactionManager::on_update_saved_reaction_tags(Promise &&promise) { + reget_saved_messages_tags( + SavedMessagesTopicId(), + PromiseCreator::lambda( + [promise = std::move(promise)](Result> result) mutable { + promise.set_value(Unit()); + })); +} + +void ReactionManager::update_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, + const vector &old_tags, + const vector &new_tags) { + if (old_tags == new_tags) { + return; + } + auto *all_tags = get_saved_reaction_tags(SavedMessagesTopicId()); + if (all_tags->update_saved_messages_tags(old_tags, new_tags)) { + send_update_saved_messages_tags(SavedMessagesTopicId(), all_tags); + } + if (saved_messages_topic_id != SavedMessagesTopicId()) { + auto tags = get_saved_reaction_tags(saved_messages_topic_id); + if (tags->update_saved_messages_tags(old_tags, new_tags)) { + send_update_saved_messages_tags(saved_messages_topic_id, tags); + } + } +} + +void ReactionManager::set_saved_messages_tag_title(ReactionType reaction_type, string title, Promise &&promise) { + if (reaction_type.is_empty()) { + return promise.set_error(Status::Error(400, "Reaction type must be non-empty")); + } + if (reaction_type.is_paid_reaction()) { + return promise.set_error(Status::Error(400, "Invalid reaction specified")); + } + title = clean_name(title, MAX_TAG_TITLE_LENGTH); + + auto *all_tags = get_saved_reaction_tags(SavedMessagesTopicId()); + if (all_tags->set_tag_title(reaction_type, title)) { + send_update_saved_messages_tags(SavedMessagesTopicId(), all_tags); + } + + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)](Result result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &ReactionManager::on_update_saved_reaction_tags, std::move(promise)); + } else { + promise.set_error(result.move_as_error()); + } + }); + td_->create_handler(std::move(query_promise))->send(reaction_type, title); +} + +td_api::object_ptr ReactionManager::get_message_effect_object(const Effect &effect) const { + auto type = [&]() -> td_api::object_ptr { + if (effect.is_sticker()) { + return td_api::make_object( + td_->stickers_manager_->get_sticker_object(effect.effect_sticker_id_)); + } + return td_api::make_object( + td_->stickers_manager_->get_sticker_object(effect.effect_sticker_id_), + td_->stickers_manager_->get_sticker_object(effect.effect_animation_id_)); + }(); + return td_api::make_object(effect.id_.get(), + td_->stickers_manager_->get_sticker_object(effect.static_icon_id_), + effect.emoji_, effect.is_premium_, std::move(type)); +} + +td_api::object_ptr ReactionManager::get_message_effect_object(MessageEffectId effect_id) const { + for (auto &effect : message_effects_.effects_) { + if (effect.id_ == effect_id) { + return get_message_effect_object(effect); + } + } + return nullptr; +} + +td_api::object_ptr ReactionManager::get_update_available_message_effects_object() + const { + auto get_raw_effect_ids = [](const vector &message_effect_ids) { + return transform(message_effect_ids, [](MessageEffectId effect_id) { return effect_id.get(); }); + }; + return td_api::make_object( + get_raw_effect_ids(active_message_effects_.reaction_effects_), + get_raw_effect_ids(active_message_effects_.sticker_effects_)); +} + +void ReactionManager::reload_message_effects() { + if (G()->close_flag() || message_effects_.are_being_reloaded_) { + return; + } + CHECK(!td_->auth_manager_->is_bot()); + message_effects_.are_being_reloaded_ = true; + load_message_effects(); // must be after are_being_reloaded_ is set to true to avoid recursion + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this)]( + Result> r_effects) mutable { + send_closure(actor_id, &ReactionManager::on_get_message_effects, std::move(r_effects)); + }); + td_->create_handler(std::move(promise))->send(message_effects_.hash_); +} + +void ReactionManager::load_message_effects() { + if (are_message_effects_loaded_from_database_) { + return; + } + are_message_effects_loaded_from_database_ = true; + + string message_effects = G()->td_db()->get_binlog_pmc()->get("message_effects"); + if (message_effects.empty()) { + return reload_message_effects(); + } + LOG(INFO) << "Loaded message effects of size " << message_effects.size(); + + Effects new_message_effects; + new_message_effects.are_being_reloaded_ = message_effects_.are_being_reloaded_; + auto status = log_event_parse(new_message_effects, message_effects); + if (status.is_error()) { + LOG(ERROR) << "Can't load message effects: " << status; + return reload_message_effects(); + } + for (auto &effect : new_message_effects.effects_) { + if (!effect.is_valid()) { + LOG(ERROR) << "Loaded invalid message effect"; + return reload_message_effects(); + } + } + message_effects_ = std::move(new_message_effects); + + LOG(INFO) << "Successfully loaded " << message_effects_.effects_.size() << " message effects"; + + update_active_message_effects(); +} + +void ReactionManager::save_message_effects() { + LOG(INFO) << "Save " << message_effects_.effects_.size() << " message effects"; + are_message_effects_loaded_from_database_ = true; + G()->td_db()->get_binlog_pmc()->set("message_effects", log_event_store(message_effects_).as_slice().str()); +} + +void ReactionManager::on_get_message_effects( + Result> r_effects) { + G()->ignore_result_if_closing(r_effects); + CHECK(message_effects_.are_being_reloaded_); + message_effects_.are_being_reloaded_ = false; + + auto get_message_effect_queries = std::move(pending_get_message_effect_queries_); + pending_get_message_effect_queries_.clear(); + SCOPE_EXIT { + for (auto &query : get_message_effect_queries) { + query.second.set_value(get_message_effect_object(query.first)); + } + }; + + if (r_effects.is_error()) { + return; + } + auto message_effects = r_effects.move_as_ok(); + + switch (message_effects->get_id()) { + case telegram_api::messages_availableEffectsNotModified::ID: + break; + case telegram_api::messages_availableEffects::ID: { + auto effects = telegram_api::move_object_as(message_effects); + FlatHashMap stickers; + for (auto &document : effects->documents_) { + auto sticker = td_->stickers_manager_->on_get_sticker_document(std::move(document), StickerFormat::Unknown, + "on_get_message_effects"); + if (sticker.first != 0 && sticker.second.is_valid()) { + stickers.emplace(sticker.first, sticker.second); + } else { + LOG(ERROR) << "Receive " << sticker.first << ' ' << sticker.second; + } + } + vector new_effects; + bool was_sticker = false; + bool have_invalid_order = false; + for (const auto &available_effect : effects->effects_) { + Effect effect; + effect.id_ = MessageEffectId(available_effect->id_); + effect.emoji_ = std::move(available_effect->emoticon_); + effect.is_premium_ = available_effect->premium_required_; + if (available_effect->static_icon_id_ != 0) { + auto it = stickers.find(available_effect->static_icon_id_); + if (it == stickers.end()) { + LOG(ERROR) << "Can't find " << available_effect->static_icon_id_; + } else { + auto sticker_id = it->second; + if (td_->stickers_manager_->get_sticker_format(sticker_id) != StickerFormat::Webp) { + LOG(ERROR) << "Receive static sticker in wrong format"; + } else { + effect.static_icon_id_ = sticker_id; + } + } + } + if (available_effect->effect_sticker_id_ != 0) { + auto it = stickers.find(available_effect->effect_sticker_id_); + if (it == stickers.end()) { + LOG(ERROR) << "Can't find " << available_effect->effect_sticker_id_; + } else { + auto sticker_id = it->second; + if (td_->stickers_manager_->get_sticker_format(sticker_id) != StickerFormat::Tgs) { + LOG(ERROR) << "Receive effect sticker in wrong format"; + } else { + effect.effect_sticker_id_ = sticker_id; + } + } + } + if (available_effect->effect_animation_id_ != 0) { + auto it = stickers.find(available_effect->effect_animation_id_); + if (it == stickers.end()) { + LOG(ERROR) << "Can't find " << available_effect->effect_animation_id_; + } else { + auto sticker_id = it->second; + if (td_->stickers_manager_->get_sticker_format(sticker_id) != StickerFormat::Tgs) { + LOG(ERROR) << "Receive effect animation in wrong format"; + } else { + effect.effect_animation_id_ = sticker_id; + } + } + } + if (effect.is_valid()) { + if (was_sticker && !effect.is_sticker()) { + have_invalid_order = true; + } + new_effects.push_back(std::move(effect)); + } else { + LOG(ERROR) << "Receive " << to_string(available_effect); + } + } + if (have_invalid_order) { + LOG(ERROR) << "Have invalid effect order"; + std::stable_sort(new_effects.begin(), new_effects.end(), + [](const Effect &lhs, const Effect &rhs) { return !lhs.is_sticker() && rhs.is_sticker(); }); + } + + message_effects_.effects_ = std::move(new_effects); + message_effects_.hash_ = effects->hash_; + + save_message_effects(); + + update_active_message_effects(); + break; + } + default: + UNREACHABLE(); + } +} + +void ReactionManager::save_active_message_effects() { + LOG(INFO) << "Save " << active_message_effects_.reaction_effects_.size() << " + " + << active_message_effects_.sticker_effects_.size() << " available message effects"; + G()->td_db()->get_binlog_pmc()->set("active_message_effects", + log_event_store(active_message_effects_).as_slice().str()); +} + +void ReactionManager::load_active_message_effects() { + LOG(INFO) << "Loading active message effects"; + string active_message_effects = G()->td_db()->get_binlog_pmc()->get("active_message_effects"); + if (active_message_effects.empty()) { + return reload_message_effects(); + } + + auto status = log_event_parse(active_message_effects_, active_message_effects); + if (status.is_error()) { + LOG(ERROR) << "Can't load active message effects: " << status; + active_message_effects_ = {}; + return reload_message_effects(); + } + + LOG(INFO) << "Successfully loaded " << active_message_effects_.reaction_effects_.size() << " + " + << active_message_effects_.sticker_effects_.size() << " active message effects"; + + send_closure(G()->td(), &Td::send_update, get_update_available_message_effects_object()); +} + +void ReactionManager::update_active_message_effects() { + ActiveEffects active_message_effects; + for (auto &effect : message_effects_.effects_) { + if (effect.is_sticker()) { + active_message_effects.sticker_effects_.push_back(effect.id_); + } else { + active_message_effects.reaction_effects_.push_back(effect.id_); + } + } + if (active_message_effects.reaction_effects_ == active_message_effects_.reaction_effects_ && + active_message_effects.sticker_effects_ == active_message_effects_.sticker_effects_) { + return; + } + active_message_effects_ = std::move(active_message_effects); + + save_active_message_effects(); + + send_closure(G()->td(), &Td::send_update, get_update_available_message_effects_object()); +} + +void ReactionManager::get_message_effect(MessageEffectId effect_id, + Promise> &&promise) { + load_message_effects(); + if (message_effects_.effects_.empty() && message_effects_.are_being_reloaded_) { + pending_get_message_effect_queries_.emplace_back(effect_id, std::move(promise)); + return; + } + promise.set_value(get_message_effect_object(effect_id)); +} + +void ReactionManager::get_current_state(vector> &updates) const { + if (td_->auth_manager_->is_bot()) { + return; + } + + if (!active_reaction_types_.empty()) { + updates.push_back(get_update_active_emoji_reactions_object()); + } + if (all_tags_.is_inited_) { + updates.push_back(get_update_saved_messages_tags_object(SavedMessagesTopicId(), &all_tags_)); + } + for (auto &it : topic_tags_) { + updates.push_back(get_update_saved_messages_tags_object(it.first, it.second.get())); + } + if (!active_message_effects_.is_empty()) { + updates.push_back(get_update_available_message_effects_object()); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.h b/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.h new file mode 100644 index 0000000000..b18b428995 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.h @@ -0,0 +1,339 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ChatReactions.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/MessageEffectId.h" +#include "td/telegram/ReactionListType.h" +#include "td/telegram/ReactionType.h" +#include "td/telegram/ReactionUnavailabilityReason.h" +#include "td/telegram/SavedMessagesTopicId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" +#include "td/utils/StringBuilder.h" + +#include + +namespace td { + +class Td; + +class ReactionManager final : public Actor { + public: + ReactionManager(Td *td, ActorShared<> parent); + ReactionManager(const ReactionManager &) = delete; + ReactionManager &operator=(const ReactionManager &) = delete; + ReactionManager(ReactionManager &&) = delete; + ReactionManager &operator=(ReactionManager &&) = delete; + ~ReactionManager() final; + + static constexpr size_t MAX_RECENT_REACTIONS = 100; // some reasonable value + + void init(); + + bool is_active_reaction(const ReactionType &reaction_type) const; + + void get_emoji_reaction(const string &emoji, Promise> &&promise); + + td_api::object_ptr get_sorted_available_reactions( + ChatReactions available_reactions, ChatReactions active_reactions, int32 row_size, bool is_tag, + ReactionUnavailabilityReason unavailability_reason); + + td_api::object_ptr get_available_reactions(int32 row_size); + + void add_recent_reaction(const ReactionType &reaction_type); + + void clear_recent_reactions(Promise &&promise); + + vector get_default_tag_reactions(); + + void reload_reactions(); + + void reload_reaction_list(ReactionListType reaction_list_type, const char *source); + + void on_get_reaction_list(ReactionListType reaction_list_type, + tl_object_ptr &&reactions_ptr); + + void on_get_available_reactions(tl_object_ptr &&available_reactions_ptr); + + void set_default_reaction(ReactionType reaction_type, Promise &&promise); + + void send_set_default_reaction_query(); + + void get_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, + Promise> &&promise); + + void on_update_saved_reaction_tags(Promise &&promise); + + void update_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, const vector &old_tags, + const vector &new_tags); + + void set_saved_messages_tag_title(ReactionType reaction_type, string title, Promise &&promise); + + void reload_message_effects(); + + void get_message_effect(MessageEffectId effect_id, Promise> &&promise); + + void get_current_state(vector> &updates) const; + + private: + struct Reaction { + ReactionType reaction_type_; + string title_; + bool is_active_ = false; + bool is_premium_ = false; + FileId static_icon_; + FileId appear_animation_; + FileId select_animation_; + FileId activate_animation_; + FileId effect_animation_; + FileId around_animation_; + FileId center_animation_; + + bool is_valid() const { + return static_icon_.is_valid() && appear_animation_.is_valid() && select_animation_.is_valid() && + activate_animation_.is_valid() && effect_animation_.is_valid() && !reaction_type_.is_empty(); + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct Reactions { + int32 hash_ = 0; + bool are_being_reloaded_ = false; + vector reactions_; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct ReactionList { + int64 hash_ = 0; + bool is_loaded_from_database_ = false; + bool is_being_reloaded_ = false; + vector reaction_types_; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + static constexpr int32 MAX_TAG_TITLE_LENGTH = 12; + + struct SavedReactionTag { + ReactionType reaction_type_; + uint64 hash_ = 0; + string title_; + int32 count_ = 0; + + SavedReactionTag() = default; + + explicit SavedReactionTag(telegram_api::object_ptr &&tag); + + SavedReactionTag(const ReactionType &reaction_type, const string &title, int32 count); + + bool is_valid() const { + return !reaction_type_.is_empty() && count_ >= 0 && (count_ > 0 || !title_.empty()); + } + + td_api::object_ptr get_saved_messages_tag_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + friend bool operator==(const SavedReactionTag &lhs, const SavedReactionTag &rhs); + + friend bool operator!=(const SavedReactionTag &lhs, const SavedReactionTag &rhs); + + friend bool operator<(const SavedReactionTag &lhs, const SavedReactionTag &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const SavedReactionTag &saved_reaction_tag); + + struct SavedReactionTags { + vector tags_; + int64 hash_ = 0; + bool is_inited_ = false; + + td_api::object_ptr get_saved_messages_tags_object() const; + + bool update_saved_messages_tags(const vector &old_tags, const vector &new_tags); + + bool set_tag_title(const ReactionType &reaction_type, const string &title); + + int64 calc_hash() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct Effect { + MessageEffectId id_; + string emoji_; + FileId static_icon_id_; + FileId effect_sticker_id_; + FileId effect_animation_id_; + bool is_premium_ = false; + + bool is_valid() const { + return id_.is_valid() && effect_sticker_id_.is_valid(); + } + + bool is_sticker() const { + return effect_animation_id_ == FileId(); + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct Effects { + int32 hash_ = 0; + bool are_being_reloaded_ = false; + vector effects_; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct ActiveEffects { + vector reaction_effects_; + vector sticker_effects_; + + bool is_empty() const { + return reaction_effects_.empty() && sticker_effects_.empty(); + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + td_api::object_ptr get_emoji_reaction_object(const string &emoji) const; + + ReactionList &get_reaction_list(ReactionListType reaction_list_type); + + void start_up() final; + + void tear_down() final; + + void save_active_reactions(); + + void save_reactions(); + + void save_reaction_list(ReactionListType reaction_list_type); + + void load_active_reactions(); + + void load_reactions(); + + void load_reaction_list(ReactionListType reaction_list_type); + + void update_active_reactions(); + + td_api::object_ptr get_update_active_emoji_reactions_object() const; + + SavedReactionTags *get_saved_reaction_tags(SavedMessagesTopicId saved_messages_topic_id); + + void reget_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, + Promise> &&promise); + + void on_get_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, + Result> &&r_tags); + + string get_saved_messages_tags_database_key(SavedMessagesTopicId saved_messages_topic_id); + + void load_all_saved_reaction_tags_from_database(); + + void load_saved_reaction_tags_from_database(SavedMessagesTopicId saved_messages_topic_id, SavedReactionTags *tags); + + td_api::object_ptr get_update_saved_messages_tags_object( + SavedMessagesTopicId saved_messages_topic_id, const SavedReactionTags *tags) const; + + void send_update_saved_messages_tags(SavedMessagesTopicId saved_messages_topic_id, const SavedReactionTags *tags, + bool from_database = false); + + td_api::object_ptr get_message_effect_object(const Effect &effect) const; + + td_api::object_ptr get_message_effect_object(MessageEffectId effect_id) const; + + td_api::object_ptr get_update_available_message_effects_object() const; + + void load_message_effects(); + + void save_message_effects(); + + void on_get_message_effects(Result> r_effects); + + void save_active_message_effects(); + + void load_active_message_effects(); + + void update_active_message_effects(); + + Td *td_; + ActorShared<> parent_; + + bool is_inited_ = false; + bool are_reactions_loaded_from_database_ = false; + bool are_all_tags_loaded_from_database_ = false; + bool are_message_effects_loaded_from_database_ = false; + + vector>>> pending_get_emoji_reaction_queries_; + + Reactions reactions_; + vector active_reaction_types_; + + ReactionList reaction_lists_[MAX_REACTION_LIST_TYPE]; + + SavedReactionTags all_tags_; + FlatHashMap, SavedMessagesTopicIdHash> topic_tags_; + + vector>> pending_get_all_saved_reaction_tags_queries_; + FlatHashMap>>, + SavedMessagesTopicIdHash> + pending_get_topic_saved_reaction_tags_queries_; + + Effects message_effects_; + ActiveEffects active_message_effects_; + + vector>>> + pending_get_message_effect_queries_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.hpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.hpp new file mode 100644 index 0000000000..dc5af62259 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionManager.hpp @@ -0,0 +1,220 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ReactionManager.h" + +#include "td/telegram/ReactionType.hpp" +#include "td/telegram/StickersManager.h" +#include "td/telegram/StickersManager.hpp" +#include "td/telegram/Td.h" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void ReactionManager::Reaction::store(StorerT &storer) const { + StickersManager *stickers_manager = storer.context()->td().get_actor_unsafe()->stickers_manager_.get(); + bool has_around_animation = !around_animation_.empty(); + bool has_center_animation = !center_animation_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_active_); + STORE_FLAG(has_around_animation); + STORE_FLAG(has_center_animation); + STORE_FLAG(is_premium_); + END_STORE_FLAGS(); + td::store(reaction_type_, storer); + td::store(title_, storer); + stickers_manager->store_sticker(static_icon_, false, storer, "Reaction"); + stickers_manager->store_sticker(appear_animation_, false, storer, "Reaction"); + stickers_manager->store_sticker(select_animation_, false, storer, "Reaction"); + stickers_manager->store_sticker(activate_animation_, false, storer, "Reaction"); + stickers_manager->store_sticker(effect_animation_, false, storer, "Reaction"); + if (has_around_animation) { + stickers_manager->store_sticker(around_animation_, false, storer, "Reaction"); + } + if (has_center_animation) { + stickers_manager->store_sticker(center_animation_, false, storer, "Reaction"); + } +} + +template +void ReactionManager::Reaction::parse(ParserT &parser) { + StickersManager *stickers_manager = parser.context()->td().get_actor_unsafe()->stickers_manager_.get(); + bool has_around_animation; + bool has_center_animation; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_active_); + PARSE_FLAG(has_around_animation); + PARSE_FLAG(has_center_animation); + PARSE_FLAG(is_premium_); + END_PARSE_FLAGS(); + td::parse(reaction_type_, parser); + td::parse(title_, parser); + static_icon_ = stickers_manager->parse_sticker(false, parser); + appear_animation_ = stickers_manager->parse_sticker(false, parser); + select_animation_ = stickers_manager->parse_sticker(false, parser); + activate_animation_ = stickers_manager->parse_sticker(false, parser); + effect_animation_ = stickers_manager->parse_sticker(false, parser); + if (has_around_animation) { + around_animation_ = stickers_manager->parse_sticker(false, parser); + } + if (has_center_animation) { + center_animation_ = stickers_manager->parse_sticker(false, parser); + } + + is_premium_ = false; +} + +template +void ReactionManager::Reactions::store(StorerT &storer) const { + bool has_reactions = !reactions_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_reactions); + END_STORE_FLAGS(); + if (has_reactions) { + td::store(reactions_, storer); + td::store(hash_, storer); + } +} + +template +void ReactionManager::Reactions::parse(ParserT &parser) { + bool has_reactions; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_reactions); + END_PARSE_FLAGS(); + if (has_reactions) { + td::parse(reactions_, parser); + td::parse(hash_, parser); + } +} + +template +void ReactionManager::ReactionList::store(StorerT &storer) const { + bool has_reaction_types = !reaction_types_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_reaction_types); + END_STORE_FLAGS(); + if (has_reaction_types) { + td::store(reaction_types_, storer); + td::store(hash_, storer); + } +} + +template +void ReactionManager::ReactionList::parse(ParserT &parser) { + bool has_reaction_types; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_reaction_types); + END_PARSE_FLAGS(); + if (has_reaction_types) { + td::parse(reaction_types_, parser); + td::parse(hash_, parser); + } +} + +template +void ReactionManager::Effect::store(StorerT &storer) const { + StickersManager *stickers_manager = storer.context()->td().get_actor_unsafe()->stickers_manager_.get(); + bool has_static_icon = static_icon_id_.is_valid(); + bool has_effect_animation = effect_animation_id_.is_valid(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_premium_); + STORE_FLAG(has_static_icon); + STORE_FLAG(has_effect_animation); + END_STORE_FLAGS(); + td::store(id_, storer); + td::store(emoji_, storer); + if (has_static_icon) { + stickers_manager->store_sticker(static_icon_id_, false, storer, "Effect"); + } + stickers_manager->store_sticker(effect_sticker_id_, false, storer, "Effect"); + if (has_effect_animation) { + stickers_manager->store_sticker(effect_animation_id_, false, storer, "Effect"); + } +} + +template +void ReactionManager::Effect::parse(ParserT &parser) { + StickersManager *stickers_manager = parser.context()->td().get_actor_unsafe()->stickers_manager_.get(); + bool has_static_icon; + bool has_effect_animation; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_premium_); + PARSE_FLAG(has_static_icon); + PARSE_FLAG(has_effect_animation); + END_PARSE_FLAGS(); + td::parse(id_, parser); + td::parse(emoji_, parser); + if (has_static_icon) { + static_icon_id_ = stickers_manager->parse_sticker(false, parser); + } + effect_sticker_id_ = stickers_manager->parse_sticker(false, parser); + if (has_effect_animation) { + effect_animation_id_ = stickers_manager->parse_sticker(false, parser); + } +} + +template +void ReactionManager::Effects::store(StorerT &storer) const { + bool has_effects = !effects_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_effects); + END_STORE_FLAGS(); + if (has_effects) { + td::store(effects_, storer); + td::store(hash_, storer); + } +} + +template +void ReactionManager::Effects::parse(ParserT &parser) { + bool has_effects; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_effects); + END_PARSE_FLAGS(); + if (has_effects) { + td::parse(effects_, parser); + td::parse(hash_, parser); + } +} + +template +void ReactionManager::ActiveEffects::store(StorerT &storer) const { + bool has_reaction_effects = !reaction_effects_.empty(); + bool has_sticker_effects = !sticker_effects_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_reaction_effects); + STORE_FLAG(has_sticker_effects); + END_STORE_FLAGS(); + if (has_reaction_effects) { + td::store(reaction_effects_, storer); + } + if (has_sticker_effects) { + td::store(sticker_effects_, storer); + } +} + +template +void ReactionManager::ActiveEffects::parse(ParserT &parser) { + bool has_reaction_effects; + bool has_sticker_effects; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_reaction_effects); + PARSE_FLAG(has_sticker_effects); + END_PARSE_FLAGS(); + if (has_reaction_effects) { + td::parse(reaction_effects_, parser); + } + if (has_sticker_effects) { + td::parse(sticker_effects_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.cpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.cpp new file mode 100644 index 0000000000..ef34e1b66f --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.cpp @@ -0,0 +1,75 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/ReactionNotificationSettings.h" + +namespace td { + +ReactionNotificationSettings::ReactionNotificationSettings( + td_api::object_ptr &¬ification_settings) { + if (notification_settings == nullptr) { + return; + } + message_reactions_ = ReactionNotificationsFrom(std::move(notification_settings->message_reaction_source_)); + story_reactions_ = ReactionNotificationsFrom(std::move(notification_settings->story_reaction_source_)); + sound_ = get_notification_sound(false, notification_settings->sound_id_); + show_preview_ = notification_settings->show_preview_; +} + +ReactionNotificationSettings::ReactionNotificationSettings( + telegram_api::object_ptr &¬ify_settings) { + if (notify_settings == nullptr) { + return; + } + message_reactions_ = ReactionNotificationsFrom(std::move(notify_settings->messages_notify_from_)); + story_reactions_ = ReactionNotificationsFrom(std::move(notify_settings->stories_notify_from_)); + sound_ = get_notification_sound(notify_settings->sound_.get()); + show_preview_ = notify_settings->show_previews_; +} + +td_api::object_ptr +ReactionNotificationSettings::get_reaction_notification_settings_object() const { + return td_api::make_object( + message_reactions_.get_reaction_notification_source_object(), + story_reactions_.get_reaction_notification_source_object(), get_notification_sound_ringtone_id(sound_), + show_preview_); +} + +telegram_api::object_ptr +ReactionNotificationSettings::get_input_reactions_notify_settings() const { + int32 flags = 0; + auto messages_notify_from = message_reactions_.get_input_reaction_notifications_from(); + if (messages_notify_from != nullptr) { + flags |= telegram_api::reactionsNotifySettings::MESSAGES_NOTIFY_FROM_MASK; + } + auto stories_notify_from = story_reactions_.get_input_reaction_notifications_from(); + if (stories_notify_from != nullptr) { + flags |= telegram_api::reactionsNotifySettings::STORIES_NOTIFY_FROM_MASK; + } + return telegram_api::make_object( + flags, std::move(messages_notify_from), std::move(stories_notify_from), + get_input_notification_sound(sound_, true), show_preview_); +} + +void ReactionNotificationSettings::update_default_notification_sound(const ReactionNotificationSettings &other) { + if (is_notification_sound_default(sound_) && is_notification_sound_default(other.sound_)) { + sound_ = dup_notification_sound(other.sound_); + } +} + +bool operator==(const ReactionNotificationSettings &lhs, const ReactionNotificationSettings &rhs) { + return lhs.message_reactions_ == rhs.message_reactions_ && lhs.story_reactions_ == rhs.story_reactions_ && + are_equivalent_notification_sounds(lhs.sound_, rhs.sound_) && lhs.show_preview_ == rhs.show_preview_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const ReactionNotificationSettings ¬ification_settings) { + return string_builder << "ReactionNotificationSettings[messages: " << notification_settings.message_reactions_ + << ", stories: " << notification_settings.story_reactions_ + << ", sound: " << notification_settings.sound_ + << ", show_preview: " << notification_settings.show_preview_ << ']'; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.h b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.h new file mode 100644 index 0000000000..6200e97362 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.h @@ -0,0 +1,60 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/NotificationSound.h" +#include "td/telegram/ReactionNotificationsFrom.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class ReactionNotificationSettings { + ReactionNotificationsFrom message_reactions_; + ReactionNotificationsFrom story_reactions_; + unique_ptr sound_; + bool show_preview_ = true; + + friend bool operator==(const ReactionNotificationSettings &lhs, const ReactionNotificationSettings &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, + const ReactionNotificationSettings ¬ification_settings); + + public: + ReactionNotificationSettings() = default; + + explicit ReactionNotificationSettings( + td_api::object_ptr &¬ification_settings); + + explicit ReactionNotificationSettings( + telegram_api::object_ptr &¬ify_settings); + + td_api::object_ptr get_reaction_notification_settings_object() const; + + telegram_api::object_ptr get_input_reactions_notify_settings() const; + + void update_default_notification_sound(const ReactionNotificationSettings &other); + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const ReactionNotificationSettings &lhs, const ReactionNotificationSettings &rhs); + +inline bool operator!=(const ReactionNotificationSettings &lhs, const ReactionNotificationSettings &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const ReactionNotificationSettings ¬ification_settings); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.hpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.hpp new file mode 100644 index 0000000000..90c09d8ec7 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationSettings.hpp @@ -0,0 +1,45 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/NotificationSound.h" +#include "td/telegram/ReactionNotificationSettings.h" +#include "td/telegram/ReactionNotificationsFrom.hpp" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void ReactionNotificationSettings::store(StorerT &storer) const { + bool has_sound = sound_ != nullptr; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_sound); + STORE_FLAG(show_preview_); + END_STORE_FLAGS(); + td::store(message_reactions_, storer); + td::store(story_reactions_, storer); + if (has_sound) { + td::store(sound_, storer); + } +} + +template +void ReactionNotificationSettings::parse(ParserT &parser) { + bool has_sound; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_sound); + PARSE_FLAG(show_preview_); + END_PARSE_FLAGS(); + td::parse(message_reactions_, parser); + td::parse(story_reactions_, parser); + if (has_sound) { + parse_notification_sound(sound_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.cpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.cpp new file mode 100644 index 0000000000..18bc2f0002 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.cpp @@ -0,0 +1,98 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/ReactionNotificationsFrom.h" + +namespace td { + +ReactionNotificationsFrom::ReactionNotificationsFrom( + td_api::object_ptr &¬ification_source) { + if (notification_source == nullptr) { + type_ = Type::None; + return; + } + switch (notification_source->get_id()) { + case td_api::reactionNotificationSourceNone::ID: + type_ = Type::None; + break; + case td_api::reactionNotificationSourceContacts::ID: + type_ = Type::Contacts; + break; + case td_api::reactionNotificationSourceAll::ID: + type_ = Type::All; + break; + default: + UNREACHABLE(); + } +} + +ReactionNotificationsFrom::ReactionNotificationsFrom( + telegram_api::object_ptr &¬ifications_from) { + if (notifications_from == nullptr) { + type_ = Type::None; + return; + } + switch (notifications_from->get_id()) { + case telegram_api::reactionNotificationsFromContacts::ID: + type_ = Type::Contacts; + break; + case telegram_api::reactionNotificationsFromAll::ID: + type_ = Type::All; + break; + default: + UNREACHABLE(); + } +} + +td_api::object_ptr +ReactionNotificationsFrom::get_reaction_notification_source_object() const { + switch (type_) { + case Type::None: + return td_api::make_object(); + case Type::Contacts: + return td_api::make_object(); + case Type::All: + return td_api::make_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +telegram_api::object_ptr +ReactionNotificationsFrom::get_input_reaction_notifications_from() const { + switch (type_) { + case Type::None: + return nullptr; + case Type::Contacts: + return telegram_api::make_object(); + case Type::All: + return telegram_api::make_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +bool operator==(const ReactionNotificationsFrom &lhs, const ReactionNotificationsFrom &rhs) { + return lhs.type_ == rhs.type_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const ReactionNotificationsFrom ¬ifications_from) { + switch (notifications_from.type_) { + case ReactionNotificationsFrom::Type::None: + return string_builder << "disabled"; + case ReactionNotificationsFrom::Type::Contacts: + return string_builder << "contacts"; + case ReactionNotificationsFrom::Type::All: + return string_builder << "all"; + default: + UNREACHABLE(); + return string_builder; + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.h b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.h new file mode 100644 index 0000000000..67e8de6513 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.h @@ -0,0 +1,52 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class ReactionNotificationsFrom { + enum class Type : int32 { None, Contacts, All }; + Type type_ = Type::Contacts; + + friend bool operator==(const ReactionNotificationsFrom &lhs, const ReactionNotificationsFrom &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const ReactionNotificationsFrom ¬ifications_from); + + public: + ReactionNotificationsFrom() = default; + + explicit ReactionNotificationsFrom(td_api::object_ptr &¬ification_source); + + explicit ReactionNotificationsFrom( + telegram_api::object_ptr &¬ifications_from); + + td_api::object_ptr get_reaction_notification_source_object() const; + + telegram_api::object_ptr get_input_reaction_notifications_from() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const ReactionNotificationsFrom &lhs, const ReactionNotificationsFrom &rhs); + +inline bool operator!=(const ReactionNotificationsFrom &lhs, const ReactionNotificationsFrom &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const ReactionNotificationsFrom ¬ifications_from); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.hpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.hpp new file mode 100644 index 0000000000..2c1673d220 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionNotificationsFrom.hpp @@ -0,0 +1,29 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ReactionNotificationsFrom.h" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void ReactionNotificationsFrom::store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + td::store(type_, storer); +} + +template +void ReactionNotificationsFrom::parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + td::parse(type_, parser); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionType.cpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionType.cpp new file mode 100644 index 0000000000..8f41856089 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionType.cpp @@ -0,0 +1,236 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/ReactionType.h" + +#include "td/telegram/misc.h" + +#include "td/utils/algorithm.h" +#include "td/utils/as.h" +#include "td/utils/base64.h" +#include "td/utils/crypto.h" +#include "td/utils/emoji.h" +#include "td/utils/logging.h" +#include "td/utils/Slice.h" +#include "td/utils/SliceBuilder.h" +#include "td/utils/utf8.h" + +namespace td { + +static int64 get_custom_emoji_id(const string &reaction) { + auto r_decoded = base64_decode(Slice(&reaction[1], reaction.size() - 1)); + CHECK(r_decoded.is_ok()); + CHECK(r_decoded.ok().size() == 8); + return as(r_decoded.ok().c_str()); +} + +static string get_custom_emoji_string(int64 custom_emoji_id) { + char s[8]; + as(&s) = custom_emoji_id; + return PSTRING() << '#' << base64_encode(Slice(s, 8)); +} + +ReactionType::ReactionType(string &&emoji) : reaction_(std::move(emoji)) { +} + +ReactionType::ReactionType(const telegram_api::object_ptr &reaction) { + if (reaction == nullptr) { + return; + } + switch (reaction->get_id()) { + case telegram_api::reactionEmpty::ID: + break; + case telegram_api::reactionEmoji::ID: + reaction_ = static_cast(reaction.get())->emoticon_; + if (is_custom_reaction() || is_paid_reaction()) { + reaction_ = string(); + } + break; + case telegram_api::reactionCustomEmoji::ID: + reaction_ = + get_custom_emoji_string(static_cast(reaction.get())->document_id_); + break; + case telegram_api::reactionPaid::ID: + reaction_ = "$"; + break; + default: + UNREACHABLE(); + break; + } +} + +ReactionType::ReactionType(const td_api::object_ptr &type) { + if (type == nullptr) { + return; + } + switch (type->get_id()) { + case td_api::reactionTypeEmoji::ID: { + const string &emoji = static_cast(type.get())->emoji_; + if (!check_utf8(emoji)) { + break; + } + reaction_ = emoji; + if (is_custom_reaction() || is_paid_reaction()) { + reaction_ = string(); + break; + } + break; + } + case td_api::reactionTypeCustomEmoji::ID: + reaction_ = + get_custom_emoji_string(static_cast(type.get())->custom_emoji_id_); + break; + case td_api::reactionTypePaid::ID: + reaction_ = "$"; + break; + default: + UNREACHABLE(); + break; + } +} + +ReactionType ReactionType::paid() { + ReactionType reaction_type; + reaction_type.reaction_ = "$"; + return reaction_type; +} + +vector ReactionType::get_reaction_types( + const vector> &reactions) { + return transform(reactions, [](const auto &reaction) { return ReactionType(reaction); }); +} + +vector ReactionType::get_reaction_types( + const vector> &reactions) { + return transform(reactions, [](const auto &reaction) { return ReactionType(reaction); }); +} + +vector> ReactionType::get_input_reactions( + const vector &reaction_types) { + return transform(reaction_types, + [](const ReactionType &reaction_type) { return reaction_type.get_input_reaction(); }); +} + +vector> ReactionType::get_reaction_types_object( + const vector &reaction_types, bool paid_reactions_available) { + vector> result; + result.reserve(reaction_types.size() + (paid_reactions_available ? 1 : 0)); + if (paid_reactions_available) { + result.push_back(paid().get_reaction_type_object()); + } + for (auto &reaction_type : reaction_types) { + result.push_back(reaction_type.get_reaction_type_object()); + } + return result; +} + +telegram_api::object_ptr ReactionType::get_input_reaction() const { + if (is_empty()) { + return telegram_api::make_object(); + } + if (is_custom_reaction()) { + return telegram_api::make_object(get_custom_emoji_id(reaction_)); + } + if (is_paid_reaction()) { + return telegram_api::make_object(); + } + return telegram_api::make_object(reaction_); +} + +td_api::object_ptr ReactionType::get_reaction_type_object() const { + if (is_empty()) { + return nullptr; + } + if (is_custom_reaction()) { + return td_api::make_object(get_custom_emoji_id(reaction_)); + } + if (is_paid_reaction()) { + return td_api::make_object(); + } + return td_api::make_object(reaction_); +} + +td_api::object_ptr ReactionType::get_update_default_reaction_type() const { + if (is_empty()) { + return nullptr; + } + return td_api::make_object(get_reaction_type_object()); +} + +uint64 ReactionType::get_hash() const { + if (is_custom_reaction()) { + return static_cast(get_custom_emoji_id(reaction_)); + } else { + return get_md5_string_hash(remove_emoji_selectors(reaction_)); + } +} + +bool ReactionType::is_custom_reaction() const { + return reaction_[0] == '#'; +} + +bool ReactionType::is_paid_reaction() const { + return reaction_ == "$"; +} + +bool ReactionType::is_active_reaction( + const FlatHashMap &active_reaction_pos) const { + return !is_empty() && (is_custom_reaction() || is_paid_reaction() || active_reaction_pos.count(*this) > 0); +} + +bool operator<(const ReactionType &lhs, const ReactionType &rhs) { + if (lhs.is_paid_reaction()) { + return !rhs.is_paid_reaction(); + } + if (rhs.is_paid_reaction()) { + return false; + } + return lhs.reaction_ < rhs.reaction_; +} + +bool operator==(const ReactionType &lhs, const ReactionType &rhs) { + return lhs.reaction_ == rhs.reaction_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const ReactionType &reaction_type) { + if (reaction_type.is_empty()) { + return string_builder << "empty reaction"; + } + if (reaction_type.is_custom_reaction()) { + return string_builder << "custom reaction " << get_custom_emoji_id(reaction_type.reaction_); + } + if (reaction_type.is_paid_reaction()) { + return string_builder << "paid reaction"; + } + return string_builder << "reaction " << reaction_type.reaction_; +} + +int64 get_reaction_types_hash(const vector &reaction_types) { + vector numbers; + for (auto &reaction_type : reaction_types) { + if (reaction_type.is_custom_reaction()) { + auto custom_emoji_id = static_cast(get_custom_emoji_id(reaction_type.get_string())); + numbers.push_back(custom_emoji_id >> 32); + numbers.push_back(custom_emoji_id & 0xFFFFFFFF); + } else { + if (reaction_type.is_paid_reaction()) { + LOG(ERROR) << "Have paid reaction"; + } + auto emoji = remove_emoji_selectors(reaction_type.get_string()); + unsigned char hash[16]; + md5(emoji, {hash, sizeof(hash)}); + auto get = [hash](int num) { + return static_cast(hash[num]); + }; + + numbers.push_back(0); + numbers.push_back(static_cast((get(0) << 24) + (get(1) << 16) + (get(2) << 8) + get(3))); + } + } + return get_vector_hash(numbers); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionType.h b/protocols/Telegram/tdlib/td/td/telegram/ReactionType.h new file mode 100644 index 0000000000..cfa49eb5f0 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionType.h @@ -0,0 +1,101 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +struct ReactionTypeHash; + +class ReactionType { + string reaction_; + + friend bool operator<(const ReactionType &lhs, const ReactionType &rhs); + + friend bool operator==(const ReactionType &lhs, const ReactionType &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const ReactionType &reaction_type); + + friend struct ReactionTypeHash; + + public: + ReactionType() = default; + + explicit ReactionType(string &&emoji); + + explicit ReactionType(const telegram_api::object_ptr &reaction); + + explicit ReactionType(const td_api::object_ptr &type); + + static ReactionType paid(); + + static vector get_reaction_types( + const vector> &reactions); + + static vector get_reaction_types(const vector> &reactions); + + static vector> get_input_reactions( + const vector &reaction_types); + + static vector> get_reaction_types_object( + const vector &reaction_types, bool paid_reactions_available); + + telegram_api::object_ptr get_input_reaction() const; + + td_api::object_ptr get_reaction_type_object() const; + + td_api::object_ptr get_update_default_reaction_type() const; + + uint64 get_hash() const; + + bool is_custom_reaction() const; + + bool is_paid_reaction() const; + + bool is_active_reaction(const FlatHashMap &active_reaction_pos) const; + + bool is_empty() const { + return reaction_.empty(); + } + + const string &get_string() const { + return reaction_; + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +struct ReactionTypeHash { + uint32 operator()(const ReactionType &reaction_type) const { + return Hash()(reaction_type.reaction_); + } +}; + +bool operator<(const ReactionType &lhs, const ReactionType &rhs); + +bool operator==(const ReactionType &lhs, const ReactionType &rhs); + +inline bool operator!=(const ReactionType &lhs, const ReactionType &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const ReactionType &reaction_type); + +int64 get_reaction_types_hash(const vector &reaction_types); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionType.hpp b/protocols/Telegram/tdlib/td/td/telegram/ReactionType.hpp new file mode 100644 index 0000000000..b2fa18acfb --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionType.hpp @@ -0,0 +1,27 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ReactionType.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void ReactionType::store(StorerT &storer) const { + CHECK(!is_empty()); + td::store(reaction_, storer); +} + +template +void ReactionType::parse(ParserT &parser) { + td::parse(reaction_, parser); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReactionUnavailabilityReason.h b/protocols/Telegram/tdlib/td/td/telegram/ReactionUnavailabilityReason.h new file mode 100644 index 0000000000..35d7758c22 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ReactionUnavailabilityReason.h @@ -0,0 +1,15 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" + +namespace td { + +enum class ReactionUnavailabilityReason : int32 { None, AnonymousAdministrator, Guest }; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/RecentDialogList.cpp b/protocols/Telegram/tdlib/td/td/telegram/RecentDialogList.cpp index c65767877c..b336145719 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/RecentDialogList.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/RecentDialogList.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,14 +7,16 @@ #include "td/telegram/RecentDialogList.h" #include "td/telegram/AccessRights.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/DialogListId.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/FolderId.h" #include "td/telegram/Global.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/Td.h" #include "td/telegram/td_api.h" #include "td/telegram/TdDb.h" +#include "td/telegram/UserManager.h" #include "td/actor/MultiPromise.h" @@ -23,8 +25,6 @@ #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" -#include - namespace td { RecentDialogList::RecentDialogList(Td *td, const char *name, size_t max_size) @@ -50,14 +50,14 @@ void RecentDialogList::save_dialogs() const { string username; switch (dialog_id.get_type()) { case DialogType::User: - if (!td_->contacts_manager_->is_user_contact(dialog_id.get_user_id())) { - username = td_->contacts_manager_->get_user_first_username(dialog_id.get_user_id()); + if (!td_->user_manager_->is_user_contact(dialog_id.get_user_id())) { + username = td_->user_manager_->get_user_first_username(dialog_id.get_user_id()); } break; case DialogType::Chat: break; case DialogType::Channel: - username = td_->contacts_manager_->get_channel_first_username(dialog_id.get_channel_id()); + username = td_->chat_manager_->get_channel_first_username(dialog_id.get_channel_id()); break; case DialogType::SecretChat: break; @@ -100,13 +100,13 @@ void RecentDialogList::load_dialogs(Promise &&promise) { vector dialog_ids; for (auto &found_dialog : found_dialogs) { if (found_dialog[0] == '@') { - td_->messages_manager_->search_public_dialog(found_dialog, false, mpas.get_promise()); + td_->dialog_manager_->search_public_dialog(found_dialog, false, mpas.get_promise()); } else { dialog_ids.push_back(DialogId(to_integer(found_dialog))); } } if (!dialog_ids.empty()) { - if (G()->use_chat_info_database()) { + if (G()->use_chat_info_database() && !G()->td_db()->was_dialog_db_created()) { td_->messages_manager_->load_dialogs( std::move(dialog_ids), PromiseCreator::lambda( @@ -117,7 +117,7 @@ void RecentDialogList::load_dialogs(Promise &&promise) { PromiseCreator::lambda([promise = mpas.get_promise()](td_api::object_ptr &&chats) mutable { promise.set_value(Unit()); })); - td_->contacts_manager_->search_contacts("", 1, mpas.get_promise()); + td_->user_manager_->search_contacts("", 1, mpas.get_promise()); } } @@ -138,14 +138,14 @@ void RecentDialogList::on_load_dialogs(vector &&found_dialogs) { for (auto it = found_dialogs.rbegin(); it != found_dialogs.rend(); ++it) { DialogId dialog_id; if ((*it)[0] == '@') { - dialog_id = td_->messages_manager_->resolve_dialog_username(it->substr(1)); + dialog_id = td_->dialog_manager_->get_resolved_dialog_by_username(it->substr(1)); } else { dialog_id = DialogId(to_integer(*it)); } - if (dialog_id.is_valid() && removed_dialog_ids_.count(dialog_id) == 0 && - td_->messages_manager_->have_dialog_info(dialog_id) && - td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Read)) { - td_->messages_manager_->force_create_dialog(dialog_id, "recent dialog"); + if (dialog_id.is_valid() && td::contains(removed_dialog_ids_, dialog_id) == 0 && + td_->dialog_manager_->have_dialog_info(dialog_id) && + td_->dialog_manager_->have_input_peer(dialog_id, true, AccessRights::Read)) { + td_->dialog_manager_->force_create_dialog(dialog_id, "recent dialog"); do_add_dialog(dialog_id); } } @@ -175,19 +175,9 @@ bool RecentDialogList::do_add_dialog(DialogId dialog_id) { return false; } - // TODO create function - auto it = std::find(dialog_ids_.begin(), dialog_ids_.end(), dialog_id); - if (it == dialog_ids_.end()) { - if (dialog_ids_.size() == max_size_) { - CHECK(!dialog_ids_.empty()); - dialog_ids_.back() = dialog_id; - } else { - dialog_ids_.push_back(dialog_id); - } - it = dialog_ids_.end() - 1; - } - std::rotate(dialog_ids_.begin(), it, it + 1); - removed_dialog_ids_.erase(dialog_id); + add_to_top(dialog_ids_, max_size_, dialog_id); + + td::remove(removed_dialog_ids_, dialog_id); return true; } @@ -200,8 +190,8 @@ void RecentDialogList::remove_dialog(DialogId dialog_id) { } if (td::remove(dialog_ids_, dialog_id)) { save_dialogs(); - } else if (!is_loaded_) { - removed_dialog_ids_.insert(dialog_id); + } else if (!is_loaded_ && !td::contains(removed_dialog_ids_, dialog_id)) { + removed_dialog_ids_.push_back(dialog_id); } } @@ -217,7 +207,7 @@ void RecentDialogList::update_dialogs() { // always keep break; case DialogType::Chat: { - auto channel_id = td_->contacts_manager_->get_chat_migrated_to_channel_id(dialog_id.get_chat_id()); + auto channel_id = td_->chat_manager_->get_chat_migrated_to_channel_id(dialog_id.get_chat_id()); if (channel_id.is_valid() && td_->messages_manager_->have_dialog(DialogId(channel_id))) { dialog_id = DialogId(channel_id); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/RecentDialogList.h b/protocols/Telegram/tdlib/td/td/telegram/RecentDialogList.h index 0a0e3c7c67..67c15b2ca1 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/RecentDialogList.h +++ b/protocols/Telegram/tdlib/td/td/telegram/RecentDialogList.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,7 +11,6 @@ #include "td/actor/actor.h" #include "td/utils/common.h" -#include "td/utils/FlatHashSet.h" #include "td/utils/Promise.h" #include @@ -38,7 +37,7 @@ class RecentDialogList final : public Actor { const char *name_; size_t max_size_; vector dialog_ids_; - FlatHashSet removed_dialog_ids_; + vector removed_dialog_ids_; bool is_loaded_ = false; vector> load_list_queries_; diff --git a/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.cpp new file mode 100644 index 0000000000..a1a3488f89 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.cpp @@ -0,0 +1,391 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/RepliedMessageInfo.h" + +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/MessageContent.h" +#include "td/telegram/MessageContentType.h" +#include "td/telegram/MessageCopyOptions.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/ScheduledServerMessageId.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/algorithm.h" +#include "td/utils/logging.h" + +namespace td { + +static bool has_qts_messages(const Td *td, DialogId dialog_id) { + switch (dialog_id.get_type()) { + case DialogType::User: + case DialogType::Chat: + return td->option_manager_->get_option_integer("session_count") > 1; + case DialogType::Channel: + case DialogType::SecretChat: + return false; + case DialogType::None: + default: + UNREACHABLE(); + return false; + } +} + +RepliedMessageInfo::~RepliedMessageInfo() = default; + +RepliedMessageInfo::RepliedMessageInfo(Td *td, tl_object_ptr &&reply_header, + DialogId dialog_id, MessageId message_id, int32 date) { + CHECK(reply_header != nullptr); + if (reply_header->reply_to_scheduled_) { + message_id_ = MessageId(ScheduledServerMessageId(reply_header->reply_to_msg_id_), date); + if (message_id.is_valid_scheduled()) { + if (reply_header->reply_to_peer_id_ != nullptr) { + dialog_id_ = DialogId(reply_header->reply_to_peer_id_); + LOG(ERROR) << "Receive reply to " << MessageFullId{dialog_id_, message_id_} << " in " + << MessageFullId{dialog_id, message_id}; + message_id_ = MessageId(); + dialog_id_ = DialogId(); + } + if (message_id == message_id_) { + LOG(ERROR) << "Receive reply to " << message_id_ << " in " << MessageFullId{dialog_id, message_id}; + message_id_ = MessageId(); + } + } else { + LOG(ERROR) << "Receive reply to " << message_id_ << " in " << MessageFullId{dialog_id, message_id}; + message_id_ = MessageId(); + } + if (reply_header->reply_from_ != nullptr || reply_header->reply_media_ != nullptr) { + LOG(ERROR) << "Receive reply from other chat " << to_string(reply_header) << " in " + << MessageFullId{dialog_id, message_id}; + } + } else { + if (reply_header->reply_to_msg_id_ != 0) { + message_id_ = MessageId(ServerMessageId(reply_header->reply_to_msg_id_)); + if (reply_header->reply_to_peer_id_ != nullptr) { + dialog_id_ = DialogId(reply_header->reply_to_peer_id_); + if (!dialog_id_.is_valid()) { + LOG(ERROR) << "Receive reply in invalid " << to_string(reply_header->reply_to_peer_id_); + message_id_ = MessageId(); + dialog_id_ = DialogId(); + } + } + if (!message_id_.is_valid()) { + LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id}; + message_id_ = MessageId(); + dialog_id_ = DialogId(); + } else if (!message_id.is_scheduled() && !dialog_id_.is_valid() && + ((message_id_ > message_id && !has_qts_messages(td, dialog_id)) || message_id_ == message_id)) { + LOG(ERROR) << "Receive reply to " << message_id_ << " in " << MessageFullId{dialog_id, message_id}; + message_id_ = MessageId(); + } + } else if (reply_header->reply_to_peer_id_ != nullptr) { + LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id}; + } + if (reply_header->reply_from_ != nullptr) { + origin_date_ = reply_header->reply_from_->date_; + if (origin_date_ <= 0) { + LOG(ERROR) << "Receive " << to_string(reply_header) << " in " << MessageFullId{dialog_id, message_id}; + origin_date_ = 0; + } else { + auto r_reply_origin = MessageOrigin::get_message_origin(td, std::move(reply_header->reply_from_)); + if (r_reply_origin.is_error()) { + origin_date_ = 0; + } else { + origin_ = r_reply_origin.move_as_ok(); + } + } + } + if (!origin_.is_empty() && reply_header->reply_media_ != nullptr && + reply_header->reply_media_->get_id() != telegram_api::messageMediaEmpty::ID) { + content_ = get_message_content(td, FormattedText(), std::move(reply_header->reply_media_), dialog_id, + origin_date_, true, UserId(), nullptr, nullptr, "messageReplyHeader"); + CHECK(content_ != nullptr); + if (!is_supported_reply_message_content(content_->get_type())) { + LOG(ERROR) << "Receive reply with media of the type " << content_->get_type(); + content_ = nullptr; + } + } + } + if (!origin_.is_empty() || message_id_ != MessageId()) { + quote_ = MessageQuote(td, reply_header); + } +} + +RepliedMessageInfo::RepliedMessageInfo(Td *td, const MessageInputReplyTo &input_reply_to) { + if (!input_reply_to.message_id_.is_valid() && !input_reply_to.message_id_.is_valid_scheduled()) { + return; + } + message_id_ = input_reply_to.message_id_; + quote_ = input_reply_to.quote_.clone(); + if (input_reply_to.dialog_id_ != DialogId() && input_reply_to.message_id_.is_valid()) { + auto info = + td->messages_manager_->get_forwarded_message_info({input_reply_to.dialog_id_, input_reply_to.message_id_}); + if (info.origin_date_ == 0 || info.origin_.is_empty() || info.content_ == nullptr) { + *this = {}; + return; + } + origin_date_ = info.origin_date_; + origin_ = std::move(info.origin_); + content_ = std::move(info.content_); + auto content_text = get_message_content_text_mutable(content_.get()); + if (content_text != nullptr) { + if (quote_.is_empty()) { + quote_ = MessageQuote::create_automatic_quote(td, std::move(*content_text)); + } + *content_text = FormattedText(); + } + auto origin_message_full_id = origin_.get_message_full_id(); + if (origin_message_full_id.get_message_id().is_valid()) { + message_id_ = origin_message_full_id.get_message_id(); + dialog_id_ = origin_message_full_id.get_dialog_id(); + } else if (input_reply_to.dialog_id_.get_type() == DialogType::Channel) { + dialog_id_ = input_reply_to.dialog_id_; + } else { + message_id_ = MessageId(); + } + } +} + +RepliedMessageInfo RepliedMessageInfo::clone(Td *td) const { + RepliedMessageInfo result; + result.message_id_ = message_id_; + result.dialog_id_ = dialog_id_; + result.origin_date_ = origin_date_; + result.origin_ = origin_; + if (content_ != nullptr) { + result.content_ = dup_message_content(td, td->dialog_manager_->get_my_dialog_id(), content_.get(), + MessageContentDupType::Forward, MessageCopyOptions()); + } + result.quote_ = quote_.clone(); + return result; +} + +bool RepliedMessageInfo::need_reget() const { + return content_ != nullptr && need_reget_message_content(content_.get()); +} + +bool RepliedMessageInfo::need_reply_changed_warning( + const Td *td, const RepliedMessageInfo &old_info, const RepliedMessageInfo &new_info, + MessageId old_top_thread_message_id, bool is_yet_unsent, + std::function is_reply_to_deleted_message) { + if (old_info.origin_date_ != new_info.origin_date_ && old_info.origin_date_ != 0 && new_info.origin_date_ != 0) { + // date of the original message can't change + return true; + } + if (old_info.origin_ != new_info.origin_ && !old_info.origin_.has_sender_signature() && + !new_info.origin_.has_sender_signature() && !old_info.origin_.is_empty() && !new_info.origin_.is_empty()) { + // only signature can change in the message origin + return true; + } + auto need_quote_warning = MessageQuote::need_quote_changed_warning(old_info.quote_, new_info.quote_); + if (need_quote_warning != 0) { + return need_quote_warning > 0; + } + if (old_info.dialog_id_ != new_info.dialog_id_ && old_info.dialog_id_ != DialogId() && + new_info.dialog_id_ != DialogId()) { + // reply chat can't change + return true; + } + if (old_info.message_id_ == new_info.message_id_ && old_info.dialog_id_ == new_info.dialog_id_) { + if (old_info.message_id_ != MessageId()) { + if (old_info.origin_date_ != new_info.origin_date_) { + // date of the original message can't change + return true; + } + if (old_info.origin_ != new_info.origin_ && !old_info.origin_.has_sender_signature() && + !new_info.origin_.has_sender_signature()) { + // only signature can change in the message origin + return true; + } + } + return false; + } + if (is_yet_unsent && is_reply_to_deleted_message(old_info) && new_info.message_id_ == MessageId()) { + // reply to a deleted message, which was available locally + return false; + } + if (is_yet_unsent && is_reply_to_deleted_message(new_info) && old_info.message_id_ == MessageId()) { + // reply to a locally deleted yet unsent message, which was available server-side + return false; + } + if (old_info.message_id_.is_valid_scheduled() && old_info.message_id_.is_scheduled_server() && + new_info.message_id_.is_valid_scheduled() && new_info.message_id_.is_scheduled_server() && + old_info.message_id_.get_scheduled_server_message_id() == + new_info.message_id_.get_scheduled_server_message_id()) { + // schedule date change + return false; + } + if (is_yet_unsent && old_top_thread_message_id == new_info.message_id_ && new_info.dialog_id_ == DialogId()) { + // move of reply to the top thread message after deletion of the replied message + return false; + } + return true; +} + +vector RepliedMessageInfo::get_file_ids(Td *td) const { + if (content_ != nullptr) { + return get_message_content_file_ids(content_.get(), td); + } + return {}; +} + +vector RepliedMessageInfo::get_min_user_ids(Td *td) const { + vector user_ids; + if (dialog_id_.get_type() == DialogType::User) { + user_ids.push_back(dialog_id_.get_user_id()); + } + origin_.add_user_ids(user_ids); + // not supported server-side: quote_.add_user_ids(user_ids); + if (content_ != nullptr) { + append(user_ids, get_message_content_min_user_ids(td, content_.get())); + } + return user_ids; +} + +vector RepliedMessageInfo::get_min_channel_ids(Td *td) const { + vector channel_ids; + if (dialog_id_.get_type() == DialogType::Channel) { + channel_ids.push_back(dialog_id_.get_channel_id()); + } + origin_.add_channel_ids(channel_ids); + if (content_ != nullptr) { + append(channel_ids, get_message_content_min_channel_ids(td, content_.get())); + } + return channel_ids; +} + +void RepliedMessageInfo::add_dependencies(Dependencies &dependencies, bool is_bot) const { + dependencies.add_dialog_and_dependencies(dialog_id_); + origin_.add_dependencies(dependencies); + quote_.add_dependencies(dependencies); + if (content_ != nullptr) { + add_message_content_dependencies(dependencies, content_.get(), is_bot); + } +} + +td_api::object_ptr RepliedMessageInfo::get_message_reply_to_message_object( + Td *td, DialogId dialog_id, bool is_server) const { + if (dialog_id_.is_valid()) { + dialog_id = dialog_id_; + } else { + CHECK(dialog_id.is_valid()); + } + auto chat_id = td->dialog_manager_->get_chat_id_object(dialog_id, "messageReplyToMessage"); + if (message_id_ == MessageId()) { + chat_id = 0; + } + + td_api::object_ptr origin; + if (!origin_.is_empty()) { + origin = origin_.get_message_origin_object(td); + CHECK(origin != nullptr); + } + + td_api::object_ptr content; + if (content_ != nullptr) { + content = + get_message_content_object(content_.get(), td, dialog_id, is_server, false, 0, false, true, -1, false, false); + switch (content->get_id()) { + case td_api::messageUnsupported::ID: + content = nullptr; + break; + case td_api::messageText::ID: { + const auto *message_text = static_cast(content.get()); + if (message_text->link_preview_ == nullptr && message_text->link_preview_options_ == nullptr) { + content = nullptr; + } + break; + } + default: + // nothing to do + break; + } + } + + return td_api::make_object(chat_id, message_id_.get(), + quote_.get_text_quote_object(td->user_manager_.get()), + std::move(origin), origin_date_, std::move(content)); +} + +MessageInputReplyTo RepliedMessageInfo::get_input_reply_to() const { + CHECK(!is_external()); + if (message_id_.is_valid() || message_id_.is_valid_scheduled()) { + return MessageInputReplyTo(message_id_, dialog_id_, quote_.clone(true)); + } + return {}; +} + +MessageId RepliedMessageInfo::get_same_chat_reply_to_message_id(bool ignore_external) const { + if (message_id_ == MessageId()) { + return {}; + } + if (ignore_external && !origin_.is_empty()) { + return {}; + } + return dialog_id_ == DialogId() ? message_id_ : MessageId(); +} + +MessageFullId RepliedMessageInfo::get_reply_message_full_id(DialogId owner_dialog_id, bool ignore_external) const { + if (message_id_ == MessageId()) { + return {}; + } + if (ignore_external && !origin_.is_empty()) { + return {}; + } + return {dialog_id_.is_valid() ? dialog_id_ : owner_dialog_id, message_id_}; +} + +void RepliedMessageInfo::register_content(Td *td) const { + if (content_ != nullptr) { + register_reply_message_content(td, content_.get()); + } +} + +void RepliedMessageInfo::unregister_content(Td *td) const { + if (content_ != nullptr) { + unregister_reply_message_content(td, content_.get()); + } +} + +bool operator==(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs) { + if (!(lhs.message_id_ == rhs.message_id_ && lhs.dialog_id_ == rhs.dialog_id_ && + lhs.origin_date_ == rhs.origin_date_ && lhs.origin_ == rhs.origin_ && lhs.quote_ == rhs.quote_)) { + return false; + } + bool need_update = false; + bool is_content_changed = false; + compare_message_contents(nullptr, lhs.content_.get(), rhs.content_.get(), is_content_changed, need_update); + if (need_update || is_content_changed) { + return false; + } + return true; +} + +bool operator!=(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const RepliedMessageInfo &info) { + string_builder << "reply to " << info.message_id_; + if (info.dialog_id_ != DialogId()) { + string_builder << " in " << info.dialog_id_; + } + if (info.origin_date_ != 0) { + string_builder << " sent at " << info.origin_date_ << " by " << info.origin_; + } + string_builder << info.quote_; + if (info.content_ != nullptr) { + string_builder << " and content of the type " << info.content_->get_type(); + } + return string_builder; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.h b/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.h new file mode 100644 index 0000000000..fdeae7bf47 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.h @@ -0,0 +1,121 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ChannelId.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/MessageContent.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessageInputReplyTo.h" +#include "td/telegram/MessageOrigin.h" +#include "td/telegram/MessageQuote.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +#include + +namespace td { + +class Dependencies; + +class Td; + +class RepliedMessageInfo { + MessageId message_id_; + DialogId dialog_id_; // for replies from another known chats + int32 origin_date_ = 0; // for replies in other chats + MessageOrigin origin_; // for replies in other chats + unique_ptr content_; // for replies in other chats + MessageQuote quote_; + + friend bool operator==(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const RepliedMessageInfo &info); + + public: + RepliedMessageInfo() = default; + RepliedMessageInfo(const RepliedMessageInfo &) = delete; + RepliedMessageInfo &operator=(const RepliedMessageInfo &) = delete; + RepliedMessageInfo(RepliedMessageInfo &&) = default; + RepliedMessageInfo &operator=(RepliedMessageInfo &&) = default; + ~RepliedMessageInfo(); + + static RepliedMessageInfo legacy(MessageId reply_to_message_id, DialogId reply_in_dialog_id = DialogId()) { + RepliedMessageInfo result; + result.message_id_ = reply_to_message_id; + result.dialog_id_ = reply_in_dialog_id; + return result; + } + + RepliedMessageInfo(Td *td, tl_object_ptr &&reply_header, DialogId dialog_id, + MessageId message_id, int32 date); + + RepliedMessageInfo(Td *td, const MessageInputReplyTo &input_reply_to); + + RepliedMessageInfo clone(Td *td) const; + + bool is_empty() const { + return message_id_ == MessageId() && origin_.is_empty(); + } + + bool is_external() const { + return origin_date_ != 0; + } + + bool need_reget() const; + + static bool need_reply_changed_warning( + const Td *td, const RepliedMessageInfo &old_info, const RepliedMessageInfo &new_info, + MessageId old_top_thread_message_id, bool is_yet_unsent, + std::function is_reply_to_deleted_message); + + vector get_file_ids(Td *td) const; + + vector get_min_user_ids(Td *td) const; + + vector get_min_channel_ids(Td *td) const; + + void add_dependencies(Dependencies &dependencies, bool is_bot) const; + + td_api::object_ptr get_message_reply_to_message_object(Td *td, DialogId dialog_id, + bool is_server) const; + + MessageInputReplyTo get_input_reply_to() const; + + void set_message_id(MessageId new_message_id) { + CHECK(message_id_.is_valid() || message_id_.is_valid_scheduled()); + message_id_ = new_message_id; + } + + MessageId get_same_chat_reply_to_message_id(bool ignore_external) const; + + MessageFullId get_reply_message_full_id(DialogId owner_dialog_id, bool ignore_external) const; + + void register_content(Td *td) const; + + void unregister_content(Td *td) const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs); + +bool operator!=(const RepliedMessageInfo &lhs, const RepliedMessageInfo &rhs); + +StringBuilder &operator<<(StringBuilder &string_builder, const RepliedMessageInfo &info); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.hpp b/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.hpp new file mode 100644 index 0000000000..f28dadb138 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/RepliedMessageInfo.hpp @@ -0,0 +1,110 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/RepliedMessageInfo.h" + +#include "td/telegram/MessageContent.h" +#include "td/telegram/MessageEntity.hpp" +#include "td/telegram/MessageOrigin.hpp" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void RepliedMessageInfo::store(StorerT &storer) const { + bool has_message_id = message_id_.is_valid() || message_id_.is_valid_scheduled(); + bool has_dialog_id = dialog_id_.is_valid(); + bool has_origin_date = origin_date_ != 0; + bool has_origin = !origin_.is_empty(); + bool has_content = content_ != nullptr; + bool has_quote = !quote_.is_empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_message_id); + STORE_FLAG(has_dialog_id); + STORE_FLAG(has_origin_date); + STORE_FLAG(has_origin); + STORE_FLAG(false); + STORE_FLAG(false); + STORE_FLAG(has_content); + STORE_FLAG(false); + STORE_FLAG(has_quote); + END_STORE_FLAGS(); + if (has_message_id) { + td::store(message_id_, storer); + } + if (has_dialog_id) { + td::store(dialog_id_, storer); + } + if (has_origin_date) { + td::store(origin_date_, storer); + } + if (has_origin) { + td::store(origin_, storer); + } + if (has_content) { + store_message_content(content_.get(), storer); + } + if (has_quote) { + td::store(quote_, storer); + } +} + +template +void RepliedMessageInfo::parse(ParserT &parser) { + bool has_message_id; + bool has_dialog_id; + bool has_origin_date; + bool has_origin; + bool has_quote_legacy; + bool is_quote_manual_legacy; + bool has_content; + bool has_quote_position_legacy; + bool has_quote; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_message_id); + PARSE_FLAG(has_dialog_id); + PARSE_FLAG(has_origin_date); + PARSE_FLAG(has_origin); + PARSE_FLAG(has_quote_legacy); + PARSE_FLAG(is_quote_manual_legacy); + PARSE_FLAG(has_content); + PARSE_FLAG(has_quote_position_legacy); + PARSE_FLAG(has_quote); + END_PARSE_FLAGS(); + if (has_message_id) { + td::parse(message_id_, parser); + } + if (has_dialog_id) { + td::parse(dialog_id_, parser); + } + if (has_origin_date) { + td::parse(origin_date_, parser); + } + if (has_origin) { + td::parse(origin_, parser); + } + FormattedText quote_legacy; + if (has_quote_legacy) { + td::parse(quote_legacy, parser); + } + if (has_content) { + parse_message_content(content_, parser); + } + int32 quote_position_legacy = 0; + if (has_quote_position_legacy) { + td::parse(quote_position_legacy, parser); + } + if (has_quote) { + td::parse(quote_, parser); + } else if (has_quote_legacy) { + quote_ = MessageQuote(std::move(quote_legacy), quote_position_legacy, is_quote_manual_legacy); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReplyMarkup.cpp b/protocols/Telegram/tdlib/td/td/telegram/ReplyMarkup.cpp index c5d186e0c3..d56c188521 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ReplyMarkup.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/ReplyMarkup.cpp @@ -1,18 +1,18 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/ReplyMarkup.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/Dependencies.h" #include "td/telegram/Global.h" #include "td/telegram/LinkManager.h" #include "td/telegram/misc.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" @@ -244,8 +244,8 @@ static KeyboardButton get_keyboard_button(tl_object_ptr(keyboard_button_ptr); button.type = KeyboardButton::Type::RequestDialog; button.text = std::move(keyboard_button->text_); - button.requested_dialog_type = - td::make_unique(std::move(keyboard_button->peer_type_), keyboard_button->button_id_); + button.requested_dialog_type = td::make_unique( + std::move(keyboard_button->peer_type_), keyboard_button->button_id_, keyboard_button->max_quantity_); break; } default: @@ -474,8 +474,7 @@ static Result get_keyboard_button(tl_object_ptrtext_); - int32 button_type_id = button->type_ == nullptr ? td_api::keyboardButtonTypeText::ID : button->type_->get_id(); - switch (button_type_id) { + switch (button->type_ == nullptr ? td_api::keyboardButtonTypeText::ID : button->type_->get_id()) { case td_api::keyboardButtonTypeText::ID: current_button.type = KeyboardButton::Type::Text; break; @@ -526,11 +525,11 @@ static Result get_keyboard_button(tl_object_ptrurl_); break; } - case td_api::keyboardButtonTypeRequestUser::ID: { + case td_api::keyboardButtonTypeRequestUsers::ID: { if (!request_buttons_allowed) { return Status::Error(400, "Users can be requested in private chats only"); } - auto button_type = move_tl_object_as(button->type_); + auto button_type = move_tl_object_as(button->type_); current_button.type = KeyboardButton::Type::RequestDialog; current_button.requested_dialog_type = td::make_unique(std::move(button_type)); break; @@ -566,8 +565,7 @@ static Result get_inline_keyboard_button(tl_object_ptrtext_); - int32 button_type_id = button->type_->get_id(); - switch (button_type_id) { + switch (button->type_->get_id()) { case td_api::inlineKeyboardButtonTypeUrl::ID: { auto button_type = move_tl_object_as(button->type_); auto user_id = LinkManager::get_link_user_id(button_type->url_); @@ -712,8 +710,8 @@ static Result get_inline_keyboard_button(tl_object_ptr> get_reply_markup(tl_object_ptr &&reply_markup_ptr, bool is_bot, - bool only_inline_keyboard, bool request_buttons_allowed, +Result> get_reply_markup(td_api::object_ptr &&reply_markup_ptr, + bool is_bot, bool only_inline_keyboard, bool request_buttons_allowed, bool switch_inline_buttons_allowed) { CHECK(!only_inline_keyboard || !request_buttons_allowed); if (reply_markup_ptr == nullptr || !is_bot) { @@ -826,6 +824,35 @@ Result> get_reply_markup(tl_object_ptr> get_reply_markup(td_api::object_ptr &&reply_markup_ptr, + DialogType dialog_type, bool is_bot, bool is_anonymous) { + bool only_inline_keyboard = is_anonymous; + bool request_buttons_allowed = dialog_type == DialogType::User; + bool switch_inline_buttons_allowed = !is_anonymous; + + TRY_RESULT(reply_markup, get_reply_markup(std::move(reply_markup_ptr), is_bot, only_inline_keyboard, + request_buttons_allowed, switch_inline_buttons_allowed)); + if (reply_markup == nullptr) { + return nullptr; + } + switch (dialog_type) { + case DialogType::User: + if (reply_markup->type != ReplyMarkup::Type::InlineKeyboard) { + reply_markup->is_personal = false; + } + break; + case DialogType::Channel: + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + // nothing special + break; + default: + UNREACHABLE(); + } + return std::move(reply_markup); +} + unique_ptr dup_reply_markup(const unique_ptr &reply_markup) { if (reply_markup == nullptr) { return nullptr; @@ -867,9 +894,8 @@ static tl_object_ptr get_input_keyboard_button(con case KeyboardButton::Type::WebView: return make_tl_object(keyboard_button.text, keyboard_button.url); case KeyboardButton::Type::RequestDialog: - return make_tl_object( - keyboard_button.text, keyboard_button.requested_dialog_type->get_button_id(), - keyboard_button.requested_dialog_type->get_input_request_peer_type_object()); + CHECK(keyboard_button.requested_dialog_type != nullptr); + return keyboard_button.requested_dialog_type->get_input_keyboard_button_request_peer(keyboard_button.text); default: UNREACHABLE(); return nullptr; @@ -877,12 +903,12 @@ static tl_object_ptr get_input_keyboard_button(con } static tl_object_ptr get_input_keyboard_button( - ContactsManager *contacts_manager, const InlineKeyboardButton &keyboard_button) { + UserManager *user_manager, const InlineKeyboardButton &keyboard_button) { switch (keyboard_button.type) { case InlineKeyboardButton::Type::Url: return make_tl_object(keyboard_button.text, keyboard_button.data); case InlineKeyboardButton::Type::Callback: - return make_tl_object(0, false /*ignored*/, keyboard_button.text, + return make_tl_object(0, false, keyboard_button.text, BufferSlice(keyboard_button.data)); case InlineKeyboardButton::Type::CallbackGame: return make_tl_object(keyboard_button.text); @@ -906,13 +932,13 @@ static tl_object_ptr get_input_keyboard_button( peer_types.push_back(telegram_api::make_object()); } } - return make_tl_object(flags, false /*ignored*/, keyboard_button.text, + return make_tl_object(flags, false, keyboard_button.text, keyboard_button.data, std::move(peer_types)); } case InlineKeyboardButton::Type::SwitchInlineCurrentDialog: return make_tl_object( - telegram_api::keyboardButtonSwitchInline::SAME_PEER_MASK, false /*ignored*/, keyboard_button.text, - keyboard_button.data, vector>()); + telegram_api::keyboardButtonSwitchInline::SAME_PEER_MASK, true, keyboard_button.text, keyboard_button.data, + vector>()); case InlineKeyboardButton::Type::Buy: return make_tl_object(keyboard_button.text); case InlineKeyboardButton::Type::UrlAuth: { @@ -926,7 +952,7 @@ static tl_object_ptr get_input_keyboard_button( if (!keyboard_button.forward_text.empty()) { flags |= telegram_api::inputKeyboardButtonUrlAuth::FWD_TEXT_MASK; } - auto r_input_user = contacts_manager->get_input_user(UserId(bot_user_id)); + auto r_input_user = user_manager->get_input_user(UserId(bot_user_id)); if (r_input_user.is_error()) { LOG(ERROR) << "Failed to get InputUser for " << bot_user_id << ": " << r_input_user.error(); return make_tl_object(keyboard_button.text, keyboard_button.data); @@ -939,7 +965,7 @@ static tl_object_ptr get_input_keyboard_button( UNREACHABLE(); break; case InlineKeyboardButton::Type::User: { - auto r_input_user = contacts_manager->get_input_user(keyboard_button.user_id); + auto r_input_user = user_manager->get_input_user(keyboard_button.user_id); if (r_input_user.is_error()) { LOG(ERROR) << "Failed to get InputUser for " << keyboard_button.user_id << ": " << r_input_user.error(); r_input_user = make_tl_object(); @@ -955,7 +981,7 @@ static tl_object_ptr get_input_keyboard_button( } } -tl_object_ptr ReplyMarkup::get_input_reply_markup(ContactsManager *contacts_manager) const { +tl_object_ptr ReplyMarkup::get_input_reply_markup(UserManager *user_manager) const { LOG(DEBUG) << "Send " << *this; switch (type) { case ReplyMarkup::Type::InlineKeyboard: { @@ -965,7 +991,7 @@ tl_object_ptr ReplyMarkup::get_input_reply_markup(Con vector> buttons; buttons.reserve(row.size()); for (auto &button : row) { - buttons.push_back(get_input_keyboard_button(contacts_manager, button)); + buttons.push_back(get_input_keyboard_button(user_manager, button)); } rows.push_back(make_tl_object(std::move(buttons))); } @@ -1041,7 +1067,7 @@ static tl_object_ptr get_keyboard_button_object(const Ke } static tl_object_ptr get_inline_keyboard_button_object( - ContactsManager *contacts_manager, const InlineKeyboardButton &keyboard_button) { + UserManager *user_manager, const InlineKeyboardButton &keyboard_button) { tl_object_ptr type; switch (keyboard_button.type) { case InlineKeyboardButton::Type::Url: @@ -1080,9 +1106,9 @@ static tl_object_ptr get_inline_keyboard_button_ob type = make_tl_object(keyboard_button.data); break; case InlineKeyboardButton::Type::User: { - bool need_user = contacts_manager != nullptr && !contacts_manager->is_user_bot(contacts_manager->get_my_id()); + bool need_user = user_manager != nullptr && !user_manager->is_user_bot(user_manager->get_my_id()); auto user_id = - need_user ? contacts_manager->get_user_id_object(keyboard_button.user_id, "get_inline_keyboard_button_object") + need_user ? user_manager->get_user_id_object(keyboard_button.user_id, "get_inline_keyboard_button_object") : keyboard_button.user_id.get(); type = make_tl_object(user_id); break; @@ -1097,7 +1123,7 @@ static tl_object_ptr get_inline_keyboard_button_ob return make_tl_object(keyboard_button.text, std::move(type)); } -tl_object_ptr ReplyMarkup::get_reply_markup_object(ContactsManager *contacts_manager) const { +tl_object_ptr ReplyMarkup::get_reply_markup_object(UserManager *user_manager) const { switch (type) { case ReplyMarkup::Type::InlineKeyboard: { vector>> rows; @@ -1106,7 +1132,7 @@ tl_object_ptr ReplyMarkup::get_reply_markup_object(Contacts vector> buttons; buttons.reserve(row.size()); for (auto &button : row) { - buttons.push_back(get_inline_keyboard_button_object(contacts_manager, button)); + buttons.push_back(get_inline_keyboard_button_object(user_manager, button)); } rows.push_back(std::move(buttons)); } @@ -1149,22 +1175,33 @@ Status ReplyMarkup::check_shared_dialog(Td *td, int32 button_id, DialogId dialog return Status::Error(400, "Button not found"); } -tl_object_ptr get_input_reply_markup(ContactsManager *contacts_manager, +Status ReplyMarkup::check_shared_dialog_count(int32 button_id, size_t count) const { + for (auto &row : keyboard) { + for (auto &button : row) { + if (button.requested_dialog_type != nullptr && button.requested_dialog_type->get_button_id() == button_id) { + return button.requested_dialog_type->check_shared_dialog_count(count); + } + } + } + return Status::Error(400, "Button not found"); +} + +tl_object_ptr get_input_reply_markup(UserManager *user_manager, const unique_ptr &reply_markup) { if (reply_markup == nullptr) { return nullptr; } - return reply_markup->get_input_reply_markup(contacts_manager); + return reply_markup->get_input_reply_markup(user_manager); } -tl_object_ptr get_reply_markup_object(ContactsManager *contacts_manager, +tl_object_ptr get_reply_markup_object(UserManager *user_manager, const unique_ptr &reply_markup) { if (reply_markup == nullptr) { return nullptr; } - return reply_markup->get_reply_markup_object(contacts_manager); + return reply_markup->get_reply_markup_object(user_manager); } void add_reply_markup_dependencies(Dependencies &dependencies, const ReplyMarkup *reply_markup) { @@ -1173,9 +1210,7 @@ void add_reply_markup_dependencies(Dependencies &dependencies, const ReplyMarkup } for (auto &row : reply_markup->inline_keyboard) { for (auto &button : row) { - if (button.user_id.is_valid()) { - dependencies.add(button.user_id); - } + dependencies.add(button.user_id); } } } diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReplyMarkup.h b/protocols/Telegram/tdlib/td/td/telegram/ReplyMarkup.h index 036210e169..5f4ad3d712 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ReplyMarkup.h +++ b/protocols/Telegram/tdlib/td/td/telegram/ReplyMarkup.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -18,8 +18,8 @@ namespace td { -class ContactsManager; class Dependencies; +class UserManager; struct KeyboardButton { // append only @@ -86,11 +86,13 @@ struct ReplyMarkup { StringBuilder &print(StringBuilder &string_builder) const; - tl_object_ptr get_input_reply_markup(ContactsManager *contacts_manager) const; + tl_object_ptr get_input_reply_markup(UserManager *user_manager) const; - tl_object_ptr get_reply_markup_object(ContactsManager *contacts_manager) const; + tl_object_ptr get_reply_markup_object(UserManager *user_manager) const; Status check_shared_dialog(Td *td, int32 button_id, DialogId dialog_id) const; + + Status check_shared_dialog_count(int32 button_id, size_t count) const; }; bool operator==(const ReplyMarkup &lhs, const ReplyMarkup &rhs); @@ -101,16 +103,19 @@ StringBuilder &operator<<(StringBuilder &string_builder, const ReplyMarkup &repl unique_ptr get_reply_markup(tl_object_ptr &&reply_markup_ptr, bool is_bot, bool only_inline_keyboard, bool message_contains_mention); -Result> get_reply_markup(tl_object_ptr &&reply_markup_ptr, bool is_bot, - bool only_inline_keyboard, bool request_buttons_allowed, - bool switch_inline_buttons_allowed) TD_WARN_UNUSED_RESULT; +Result> get_reply_markup(td_api::object_ptr &&reply_markup_ptr, + bool is_bot, bool only_inline_keyboard, bool request_buttons_allowed, + bool switch_inline_buttons_allowed); + +Result> get_reply_markup(td_api::object_ptr &&reply_markup_ptr, + DialogType dialog_type, bool is_bot, bool is_anonymous); unique_ptr dup_reply_markup(const unique_ptr &reply_markup); -tl_object_ptr get_input_reply_markup(ContactsManager *contacts_manager, +tl_object_ptr get_input_reply_markup(UserManager *user_manager, const unique_ptr &reply_markup); -tl_object_ptr get_reply_markup_object(ContactsManager *contacts_manager, +tl_object_ptr get_reply_markup_object(UserManager *user_manager, const unique_ptr &reply_markup); void add_reply_markup_dependencies(Dependencies &dependencies, const ReplyMarkup *reply_markup); diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReportReason.cpp b/protocols/Telegram/tdlib/td/td/telegram/ReportReason.cpp index 36e629b607..ad2c2367fb 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ReportReason.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/ReportReason.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ namespace td { -Result ReportReason::get_report_reason(td_api::object_ptr reason, +Result ReportReason::get_report_reason(td_api::object_ptr reason, string &&message) { if (reason == nullptr) { return Status::Error(400, "Chat report reason must be non-empty"); @@ -21,25 +21,25 @@ Result ReportReason::get_report_reason(td_api::object_ptrget_id()) { - case td_api::chatReportReasonSpam::ID: + case td_api::reportReasonSpam::ID: return ReportReason::Type::Spam; - case td_api::chatReportReasonViolence::ID: + case td_api::reportReasonViolence::ID: return ReportReason::Type::Violence; - case td_api::chatReportReasonPornography::ID: + case td_api::reportReasonPornography::ID: return ReportReason::Type::Pornography; - case td_api::chatReportReasonChildAbuse::ID: + case td_api::reportReasonChildAbuse::ID: return ReportReason::Type::ChildAbuse; - case td_api::chatReportReasonCopyright::ID: + case td_api::reportReasonCopyright::ID: return ReportReason::Type::Copyright; - case td_api::chatReportReasonUnrelatedLocation::ID: + case td_api::reportReasonUnrelatedLocation::ID: return ReportReason::Type::UnrelatedLocation; - case td_api::chatReportReasonFake::ID: + case td_api::reportReasonFake::ID: return ReportReason::Type::Fake; - case td_api::chatReportReasonIllegalDrugs::ID: + case td_api::reportReasonIllegalDrugs::ID: return ReportReason::Type::IllegalDrugs; - case td_api::chatReportReasonPersonalDetails::ID: + case td_api::reportReasonPersonalDetails::ID: return ReportReason::Type::PersonalDetails; - case td_api::chatReportReasonCustom::ID: + case td_api::reportReasonCustom::ID: return ReportReason::Type::Custom; default: UNREACHABLE(); diff --git a/protocols/Telegram/tdlib/td/td/telegram/ReportReason.h b/protocols/Telegram/tdlib/td/td/telegram/ReportReason.h index 3ea27d70b2..faa08c8c17 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ReportReason.h +++ b/protocols/Telegram/tdlib/td/td/telegram/ReportReason.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -39,7 +39,7 @@ class ReportReason { public: ReportReason() = default; - static Result get_report_reason(td_api::object_ptr reason, string &&message); + static Result get_report_reason(td_api::object_ptr reason, string &&message); tl_object_ptr get_input_report_reason() const; diff --git a/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.cpp b/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.cpp index 1de9f11dfa..2afedb1cbb 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,19 +7,24 @@ #include "td/telegram/RequestedDialogType.h" #include "td/telegram/ChannelType.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/Td.h" +#include "td/telegram/UserManager.h" namespace td { -RequestedDialogType::RequestedDialogType(td_api::object_ptr &&request_user) { - CHECK(request_user != nullptr); +RequestedDialogType::RequestedDialogType(td_api::object_ptr &&request_users) { + CHECK(request_users != nullptr); type_ = Type::User; - button_id_ = request_user->id_; - restrict_is_bot_ = request_user->restrict_user_is_bot_; - is_bot_ = request_user->user_is_bot_; - restrict_is_premium_ = request_user->restrict_user_is_premium_; - is_premium_ = request_user->user_is_premium_; + button_id_ = request_users->id_; + max_quantity_ = max(request_users->max_quantity_, 1); + restrict_is_bot_ = request_users->restrict_user_is_bot_; + is_bot_ = request_users->user_is_bot_; + restrict_is_premium_ = request_users->restrict_user_is_premium_; + is_premium_ = request_users->user_is_premium_; + request_name_ = request_users->request_name_; + request_username_ = request_users->request_username_; + request_photo_ = request_users->request_photo_; } RequestedDialogType::RequestedDialogType(td_api::object_ptr &&request_dialog) { @@ -37,12 +42,16 @@ RequestedDialogType::RequestedDialogType(td_api::object_ptrchat_is_channel_ ? ChannelType::Broadcast : ChannelType::Megagroup; user_administrator_rights_ = AdministratorRights(request_dialog->user_administrator_rights_, channel_type); bot_administrator_rights_ = AdministratorRights(request_dialog->bot_administrator_rights_, channel_type); + request_name_ = request_dialog->request_title_; + request_username_ = request_dialog->request_username_; + request_photo_ = request_dialog->request_photo_; } RequestedDialogType::RequestedDialogType(telegram_api::object_ptr &&peer_type, - int32 button_id) { + int32 button_id, int32 max_quantity) { CHECK(peer_type != nullptr); button_id_ = button_id; + max_quantity_ = max(max_quantity, 1); switch (peer_type->get_id()) { case telegram_api::requestPeerTypeUser::ID: { auto type = telegram_api::move_object_as(peer_type); @@ -87,8 +96,9 @@ RequestedDialogType::RequestedDialogType(telegram_api::object_ptr RequestedDialogType::get_keyboard_button_type_object() const { if (type_ == Type::User) { - return td_api::make_object(button_id_, restrict_is_bot_, is_bot_, - restrict_is_premium_, is_premium_); + return td_api::make_object( + button_id_, restrict_is_bot_, is_bot_, restrict_is_premium_, is_premium_, max_quantity_, request_name_, + request_username_, request_photo_); } else { auto user_administrator_rights = restrict_user_administrator_rights_ ? user_administrator_rights_.get_chat_administrator_rights_object() @@ -97,7 +107,8 @@ td_api::object_ptr RequestedDialogType::get_keyboard restrict_bot_administrator_rights_ ? bot_administrator_rights_.get_chat_administrator_rights_object() : nullptr; return td_api::make_object( button_id_, type_ == Type::Channel, restrict_is_forum_, is_forum_, restrict_has_username_, has_username_, - is_created_, std::move(user_administrator_rights), std::move(bot_administrator_rights), bot_is_participant_); + is_created_, std::move(user_administrator_rights), std::move(bot_administrator_rights), bot_is_participant_, + request_name_, request_username_, request_photo_); } } @@ -169,6 +180,23 @@ telegram_api::object_ptr RequestedDialogType::get } } +telegram_api::object_ptr +RequestedDialogType::get_input_keyboard_button_request_peer(const string &text) const { + int32 flags = 0; + if (request_name_) { + flags |= telegram_api::inputKeyboardButtonRequestPeer::NAME_REQUESTED_MASK; + } + if (request_username_) { + flags |= telegram_api::inputKeyboardButtonRequestPeer::USERNAME_REQUESTED_MASK; + } + if (request_photo_) { + flags |= telegram_api::inputKeyboardButtonRequestPeer::PHOTO_REQUESTED_MASK; + } + return telegram_api::make_object( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, text, button_id_, + get_input_request_peer_type_object(), max_quantity_); +} + int32 RequestedDialogType::get_button_id() const { return button_id_; } @@ -180,10 +208,10 @@ Status RequestedDialogType::check_shared_dialog(Td *td, DialogId dialog_id) cons return Status::Error(400, "Wrong chat type"); } auto user_id = dialog_id.get_user_id(); - if (restrict_is_bot_ && td->contacts_manager_->is_user_bot(user_id) != is_bot_) { + if (restrict_is_bot_ && td->user_manager_->is_user_bot(user_id) != is_bot_) { return Status::Error(400, "Wrong is_bot value"); } - if (restrict_is_premium_ && td->contacts_manager_->is_user_premium(user_id) != is_premium_) { + if (restrict_is_premium_ && td->user_manager_->is_user_premium(user_id) != is_premium_) { return Status::Error(400, "Wrong is_premium value"); } break; @@ -199,10 +227,10 @@ Status RequestedDialogType::check_shared_dialog(Td *td, DialogId dialog_id) cons return Status::Error(400, "Wrong has_username value"); } auto chat_id = dialog_id.get_chat_id(); - if (!td->contacts_manager_->get_chat_is_active(chat_id)) { + if (!td->chat_manager_->get_chat_is_active(chat_id)) { return Status::Error(400, "Chat is deactivated"); } - auto status = td->contacts_manager_->get_chat_status(chat_id); + auto status = td->chat_manager_->get_chat_status(chat_id); if (is_created_ && !status.is_creator()) { return Status::Error(400, "The chat must be created by the current user"); } @@ -225,23 +253,23 @@ Status RequestedDialogType::check_shared_dialog(Td *td, DialogId dialog_id) cons } case DialogType::Channel: { auto channel_id = dialog_id.get_channel_id(); - bool is_broadcast = td->contacts_manager_->is_broadcast_channel(channel_id); + bool is_broadcast = td->chat_manager_->is_broadcast_channel(channel_id); if (type_ != (is_broadcast ? Type::Channel : Type::Group)) { return Status::Error(400, "Wrong chat type"); } - if (!is_broadcast && restrict_is_forum_ && td->contacts_manager_->is_forum_channel(channel_id) != is_forum_) { + if (!is_broadcast && restrict_is_forum_ && td->chat_manager_->is_forum_channel(channel_id) != is_forum_) { return Status::Error(400, "Wrong is_forum value"); } if (restrict_has_username_ && - td->contacts_manager_->get_channel_first_username(channel_id).empty() == has_username_) { + td->chat_manager_->get_channel_first_username(channel_id).empty() == has_username_) { return Status::Error(400, "Wrong has_username value"); } - auto status = td->contacts_manager_->get_channel_status(channel_id); + auto status = td->chat_manager_->get_channel_status(channel_id); if (is_created_ && !status.is_creator()) { return Status::Error(400, "The chat must be created by the current user"); } - bool can_invite_bot = status.can_invite_users() && - (status.is_administrator() || !td->contacts_manager_->is_channel_public(channel_id)); + bool can_invite_bot = + status.can_invite_users() && (status.is_administrator() || !td->chat_manager_->is_channel_public(channel_id)); if (!is_broadcast && bot_is_participant_) { // can't synchronously check that the bot is already participant if (!can_invite_bot) { @@ -267,4 +295,14 @@ Status RequestedDialogType::check_shared_dialog(Td *td, DialogId dialog_id) cons return Status::OK(); } +Status RequestedDialogType::check_shared_dialog_count(size_t count) const { + if (count == 0) { + return Status::Error(400, "Too few chats are chosen"); + } + if (count > static_cast(max_quantity_)) { + return Status::Error(400, "Too many chats are chosen"); + } + return Status::OK(); +} + } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.h b/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.h index 989598c735..721dc9c075 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.h +++ b/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -22,11 +22,16 @@ class RequestedDialogType { enum class Type : int32 { User, Group, Channel }; Type type_ = Type::User; int32 button_id_ = 0; + int32 max_quantity_ = 1; // User only bool restrict_is_bot_ = false; // User only bool is_bot_ = false; // User only bool restrict_is_premium_ = false; // User only bool is_premium_ = false; // User only + bool request_name_ = false; + bool request_username_ = false; + bool request_photo_ = false; + bool restrict_is_forum_ = false; // Group only bool is_forum_ = false; // Group only bool bot_is_participant_ = false; // Group only @@ -38,23 +43,29 @@ class RequestedDialogType { AdministratorRights user_administrator_rights_; // Group and Channel only AdministratorRights bot_administrator_rights_; // Group and Channel only + telegram_api::object_ptr get_input_request_peer_type_object() const; + public: RequestedDialogType() = default; - explicit RequestedDialogType(td_api::object_ptr &&request_user); + explicit RequestedDialogType(td_api::object_ptr &&request_users); explicit RequestedDialogType(td_api::object_ptr &&request_dialog); - explicit RequestedDialogType(telegram_api::object_ptr &&peer_type, int32 button_id); + RequestedDialogType(telegram_api::object_ptr &&peer_type, int32 button_id, + int32 max_quantity); td_api::object_ptr get_keyboard_button_type_object() const; - telegram_api::object_ptr get_input_request_peer_type_object() const; + telegram_api::object_ptr get_input_keyboard_button_request_peer( + const string &text) const; int32 get_button_id() const; Status check_shared_dialog(Td *td, DialogId dialog_id) const; + Status check_shared_dialog_count(size_t count) const; + template void store(StorerT &storer) const; diff --git a/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.hpp b/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.hpp index 62f7789c84..f5547b92d9 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/RequestedDialogType.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -14,6 +14,7 @@ namespace td { template void RequestedDialogType::store(StorerT &storer) const { + bool has_max_quantity = max_quantity_ != 1; BEGIN_STORE_FLAGS(); STORE_FLAG(restrict_is_bot_); STORE_FLAG(is_bot_); @@ -27,6 +28,7 @@ void RequestedDialogType::store(StorerT &storer) const { STORE_FLAG(is_created_); STORE_FLAG(restrict_user_administrator_rights_); STORE_FLAG(restrict_bot_administrator_rights_); + STORE_FLAG(has_max_quantity); END_STORE_FLAGS(); td::store(type_, storer); td::store(button_id_, storer); @@ -36,10 +38,14 @@ void RequestedDialogType::store(StorerT &storer) const { if (restrict_bot_administrator_rights_) { td::store(bot_administrator_rights_, storer); } + if (has_max_quantity) { + td::store(max_quantity_, storer); + } } template void RequestedDialogType::parse(ParserT &parser) { + bool has_max_quantity; BEGIN_PARSE_FLAGS(); PARSE_FLAG(restrict_is_bot_); PARSE_FLAG(is_bot_); @@ -53,6 +59,7 @@ void RequestedDialogType::parse(ParserT &parser) { PARSE_FLAG(is_created_); PARSE_FLAG(restrict_user_administrator_rights_); PARSE_FLAG(restrict_bot_administrator_rights_); + PARSE_FLAG(has_max_quantity); END_PARSE_FLAGS(); td::parse(type_, parser); td::parse(button_id_, parser); @@ -62,6 +69,11 @@ void RequestedDialogType::parse(ParserT &parser) { if (restrict_bot_administrator_rights_) { td::parse(bot_administrator_rights_, parser); } + if (has_max_quantity) { + td::parse(max_quantity_, parser); + } else { + max_quantity_ = 1; + } } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Requests.cpp b/protocols/Telegram/tdlib/td/td/telegram/Requests.cpp new file mode 100644 index 0000000000..4d4165dd0a --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/Requests.cpp @@ -0,0 +1,7836 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/Requests.h" + +#include "td/telegram/AccentColorId.h" +#include "td/telegram/AccountManager.h" +#include "td/telegram/AlarmManager.h" +#include "td/telegram/AnimationsManager.h" +#include "td/telegram/Application.h" +#include "td/telegram/AttachMenuManager.h" +#include "td/telegram/AudiosManager.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/AutoDownloadSettings.h" +#include "td/telegram/AutosaveManager.h" +#include "td/telegram/BackgroundId.h" +#include "td/telegram/BackgroundManager.h" +#include "td/telegram/BackgroundType.h" +#include "td/telegram/Birthdate.h" +#include "td/telegram/BoostManager.h" +#include "td/telegram/BotCommand.h" +#include "td/telegram/BotInfoManager.h" +#include "td/telegram/BotMenuButton.h" +#include "td/telegram/BotQueries.h" +#include "td/telegram/BusinessAwayMessage.h" +#include "td/telegram/BusinessConnectionId.h" +#include "td/telegram/BusinessConnectionManager.h" +#include "td/telegram/BusinessGreetingMessage.h" +#include "td/telegram/BusinessIntro.h" +#include "td/telegram/BusinessManager.h" +#include "td/telegram/BusinessWorkHours.h" +#include "td/telegram/CallbackQueriesManager.h" +#include "td/telegram/CallId.h" +#include "td/telegram/CallManager.h" +#include "td/telegram/ChannelId.h" +#include "td/telegram/ChannelRecommendationManager.h" +#include "td/telegram/ChannelType.h" +#include "td/telegram/ChatId.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/CommonDialogManager.h" +#include "td/telegram/ConfigManager.h" +#include "td/telegram/ConnectionStateManager.h" +#include "td/telegram/CountryInfoManager.h" +#include "td/telegram/CustomEmojiId.h" +#include "td/telegram/DeviceTokenManager.h" +#include "td/telegram/DialogAction.h" +#include "td/telegram/DialogActionManager.h" +#include "td/telegram/DialogBoostLinkInfo.h" +#include "td/telegram/DialogEventLog.h" +#include "td/telegram/DialogFilterId.h" +#include "td/telegram/DialogFilterManager.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/DialogInviteLinkManager.h" +#include "td/telegram/DialogListId.h" +#include "td/telegram/DialogLocation.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/DialogParticipant.h" +#include "td/telegram/DialogParticipantFilter.h" +#include "td/telegram/DialogParticipantManager.h" +#include "td/telegram/DownloadManager.h" +#include "td/telegram/DownloadManagerCallback.h" +#include "td/telegram/EmailVerification.h" +#include "td/telegram/EmojiGroupType.h" +#include "td/telegram/EmojiStatus.h" +#include "td/telegram/files/FileGcParameters.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/files/FileSourceId.h" +#include "td/telegram/files/FileStats.h" +#include "td/telegram/files/FileType.h" +#include "td/telegram/ForumTopicManager.h" +#include "td/telegram/GameManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/GlobalPrivacySettings.h" +#include "td/telegram/GroupCallId.h" +#include "td/telegram/GroupCallManager.h" +#include "td/telegram/HashtagHints.h" +#include "td/telegram/InlineMessageManager.h" +#include "td/telegram/InlineQueriesManager.h" +#include "td/telegram/JsonValue.h" +#include "td/telegram/LanguagePackManager.h" +#include "td/telegram/LinkManager.h" +#include "td/telegram/Location.h" +#include "td/telegram/MessageCopyOptions.h" +#include "td/telegram/MessageEffectId.h" +#include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessageImportManager.h" +#include "td/telegram/MessageLinkInfo.h" +#include "td/telegram/MessageReaction.h" +#include "td/telegram/MessageSearchFilter.h" +#include "td/telegram/MessageSender.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/MessageSource.h" +#include "td/telegram/MessageThreadInfo.h" +#include "td/telegram/MessageTtl.h" +#include "td/telegram/misc.h" +#include "td/telegram/net/ConnectionCreator.h" +#include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/net/NetStatsManager.h" +#include "td/telegram/net/NetType.h" +#include "td/telegram/net/Proxy.h" +#include "td/telegram/NotificationGroupId.h" +#include "td/telegram/NotificationId.h" +#include "td/telegram/NotificationManager.h" +#include "td/telegram/NotificationObjectId.h" +#include "td/telegram/NotificationSettingsManager.h" +#include "td/telegram/NotificationSettingsScope.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/PasswordManager.h" +#include "td/telegram/Payments.h" +#include "td/telegram/PeopleNearbyManager.h" +#include "td/telegram/PhoneNumberManager.h" +#include "td/telegram/Premium.h" +#include "td/telegram/PrivacyManager.h" +#include "td/telegram/PublicDialogType.h" +#include "td/telegram/QuickReplyManager.h" +#include "td/telegram/ReactionManager.h" +#include "td/telegram/ReactionNotificationSettings.h" +#include "td/telegram/ReactionType.h" +#include "td/telegram/ReportReason.h" +#include "td/telegram/RequestActor.h" +#include "td/telegram/SavedMessagesManager.h" +#include "td/telegram/SavedMessagesTopicId.h" +#include "td/telegram/ScopeNotificationSettings.h" +#include "td/telegram/SecretChatId.h" +#include "td/telegram/SecretChatsManager.h" +#include "td/telegram/SecureManager.h" +#include "td/telegram/SecureValue.h" +#include "td/telegram/SentEmailCode.h" +#include "td/telegram/SponsoredMessageManager.h" +#include "td/telegram/StarManager.h" +#include "td/telegram/StarSubscriptionPricing.h" +#include "td/telegram/StateManager.h" +#include "td/telegram/StatisticsManager.h" +#include "td/telegram/StickerFormat.h" +#include "td/telegram/StickerListType.h" +#include "td/telegram/StickerSetId.h" +#include "td/telegram/StickersManager.h" +#include "td/telegram/StickerType.h" +#include "td/telegram/StorageManager.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/StoryListId.h" +#include "td/telegram/StoryManager.h" +#include "td/telegram/SuggestedAction.h" +#include "td/telegram/Support.h" +#include "td/telegram/SynchronousRequests.h" +#include "td/telegram/td_api.hpp" +#include "td/telegram/TdDb.h" +#include "td/telegram/TermsOfServiceManager.h" +#include "td/telegram/TimeZoneManager.h" +#include "td/telegram/TopDialogCategory.h" +#include "td/telegram/TopDialogManager.h" +#include "td/telegram/TranscriptionManager.h" +#include "td/telegram/TranslationManager.h" +#include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" +#include "td/telegram/WebPageId.h" +#include "td/telegram/WebPagesManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/Slice.h" +#include "td/utils/Status.h" + +#include +#include +#include +#include + +namespace td { + +class GetMeRequest final : public RequestActor<> { + UserId user_id_; + + void do_run(Promise &&promise) final { + user_id_ = td_->user_manager_->get_me(std::move(promise)); + } + + void do_send_result() final { + send_result(td_->user_manager_->get_user_object(user_id_)); + } + + public: + GetMeRequest(ActorShared
td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class GetUserRequest final : public RequestActor<> { + UserId user_id_; + + void do_run(Promise &&promise) final { + td_->user_manager_->get_user(user_id_, get_tries(), std::move(promise)); + } + + void do_send_result() final { + send_result(td_->user_manager_->get_user_object(user_id_)); + } + + public: + GetUserRequest(ActorShared td, uint64 request_id, int64 user_id) + : RequestActor(std::move(td), request_id), user_id_(user_id) { + set_tries(3); + } +}; + +class GetUserFullInfoRequest final : public RequestActor<> { + UserId user_id_; + + void do_run(Promise &&promise) final { + td_->user_manager_->load_user_full(user_id_, get_tries() < 2, std::move(promise), "GetUserFullInfoRequest"); + } + + void do_send_result() final { + send_result(td_->user_manager_->get_user_full_info_object(user_id_)); + } + + public: + GetUserFullInfoRequest(ActorShared td, uint64 request_id, int64 user_id) + : RequestActor(std::move(td), request_id), user_id_(user_id) { + } +}; + +class GetGroupRequest final : public RequestActor<> { + ChatId chat_id_; + + void do_run(Promise &&promise) final { + td_->chat_manager_->get_chat(chat_id_, get_tries(), std::move(promise)); + } + + void do_send_result() final { + send_result(td_->chat_manager_->get_basic_group_object(chat_id_)); + } + + public: + GetGroupRequest(ActorShared td, uint64 request_id, int64 chat_id) + : RequestActor(std::move(td), request_id), chat_id_(chat_id) { + set_tries(3); + } +}; + +class GetGroupFullInfoRequest final : public RequestActor<> { + ChatId chat_id_; + + void do_run(Promise &&promise) final { + td_->chat_manager_->load_chat_full(chat_id_, get_tries() < 2, std::move(promise), "getBasicGroupFullInfo"); + } + + void do_send_result() final { + send_result(td_->chat_manager_->get_basic_group_full_info_object(chat_id_)); + } + + public: + GetGroupFullInfoRequest(ActorShared td, uint64 request_id, int64 chat_id) + : RequestActor(std::move(td), request_id), chat_id_(chat_id) { + } +}; + +class GetSupergroupRequest final : public RequestActor<> { + ChannelId channel_id_; + + void do_run(Promise &&promise) final { + td_->chat_manager_->get_channel(channel_id_, get_tries(), std::move(promise)); + } + + void do_send_result() final { + send_result(td_->chat_manager_->get_supergroup_object(channel_id_)); + } + + public: + GetSupergroupRequest(ActorShared td, uint64 request_id, int64 channel_id) + : RequestActor(std::move(td), request_id), channel_id_(channel_id) { + set_tries(3); + } +}; + +class GetSupergroupFullInfoRequest final : public RequestActor<> { + ChannelId channel_id_; + + void do_run(Promise &&promise) final { + td_->chat_manager_->load_channel_full(channel_id_, get_tries() < 2, std::move(promise), + "GetSupergroupFullInfoRequest"); + } + + void do_send_result() final { + send_result(td_->chat_manager_->get_supergroup_full_info_object(channel_id_)); + } + + public: + GetSupergroupFullInfoRequest(ActorShared td, uint64 request_id, int64 channel_id) + : RequestActor(std::move(td), request_id), channel_id_(channel_id) { + } +}; + +class GetSecretChatRequest final : public RequestActor<> { + SecretChatId secret_chat_id_; + + void do_run(Promise &&promise) final { + td_->user_manager_->get_secret_chat(secret_chat_id_, get_tries() < 2, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->user_manager_->get_secret_chat_object(secret_chat_id_)); + } + + public: + GetSecretChatRequest(ActorShared td, uint64 request_id, int32 secret_chat_id) + : RequestActor(std::move(td), request_id), secret_chat_id_(secret_chat_id) { + } +}; + +class GetChatRequest final : public RequestActor<> { + DialogId dialog_id_; + + bool dialog_found_ = false; + + void do_run(Promise &&promise) final { + dialog_found_ = td_->messages_manager_->load_dialog(dialog_id_, get_tries(), std::move(promise)); + } + + void do_send_result() final { + if (!dialog_found_) { + send_error(Status::Error(400, "Chat is not accessible")); + } else { + send_result(td_->messages_manager_->get_chat_object(dialog_id_, "GetChatRequest")); + } + } + + public: + GetChatRequest(ActorShared td, uint64 request_id, int64 dialog_id) + : RequestActor(std::move(td), request_id), dialog_id_(dialog_id) { + set_tries(3); + } +}; + +class SearchUserByPhoneNumberRequest final : public RequestActor<> { + string phone_number_; + bool only_local_; + + UserId user_id_; + + void do_run(Promise &&promise) final { + user_id_ = td_->user_manager_->search_user_by_phone_number(phone_number_, only_local_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->user_manager_->get_user_object(user_id_)); + } + + public: + SearchUserByPhoneNumberRequest(ActorShared td, uint64 request_id, string &&phone_number, bool only_local) + : RequestActor(std::move(td), request_id), phone_number_(std::move(phone_number)), only_local_(only_local) { + } +}; + +class LoadChatsRequest final : public RequestActor<> { + DialogListId dialog_list_id_; + DialogDate offset_; + int32 limit_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->get_dialogs(dialog_list_id_, offset_, limit_, false, get_tries() < 2, std::move(promise)); + } + + public: + LoadChatsRequest(ActorShared td, uint64 request_id, DialogListId dialog_list_id, DialogDate offset, int32 limit) + : RequestActor(std::move(td), request_id), dialog_list_id_(dialog_list_id), offset_(offset), limit_(limit) { + // 1 for database + 1 for server request + 1 for server request at the end + 1 for return + 1 just in case + set_tries(5); + + if (limit_ > 100) { + limit_ = 100; + } + } +}; + +class SearchPublicChatRequest final : public RequestActor<> { + string username_; + + DialogId dialog_id_; + + void do_run(Promise &&promise) final { + dialog_id_ = td_->dialog_manager_->search_public_dialog(username_, get_tries() < 3, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_chat_object(dialog_id_, "SearchPublicChatRequest")); + } + + public: + SearchPublicChatRequest(ActorShared td, uint64 request_id, string username) + : RequestActor(std::move(td), request_id), username_(std::move(username)) { + set_tries(4); // 1 for server request + 1 for reload voice chat + 1 for reload dialog + 1 for result + } +}; + +class SearchPublicChatsRequest final : public RequestActor<> { + string query_; + + vector dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->messages_manager_->search_public_dialogs(query_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->dialog_manager_->get_chats_object(-1, dialog_ids_, "SearchPublicChatsRequest")); + } + + public: + SearchPublicChatsRequest(ActorShared td, uint64 request_id, string query) + : RequestActor(std::move(td), request_id), query_(std::move(query)) { + } +}; + +class SearchChatsRequest final : public RequestActor<> { + string query_; + int32 limit_; + + std::pair> dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->messages_manager_->search_dialogs(query_, limit_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->dialog_manager_->get_chats_object(dialog_ids_, "SearchChatsRequest")); + } + + public: + SearchChatsRequest(ActorShared td, uint64 request_id, string query, int32 limit) + : RequestActor(std::move(td), request_id), query_(std::move(query)), limit_(limit) { + } +}; + +class SearchChatsOnServerRequest final : public RequestActor<> { + string query_; + int32 limit_; + + vector dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->messages_manager_->search_dialogs_on_server(query_, limit_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->dialog_manager_->get_chats_object(-1, dialog_ids_, "SearchChatsOnServerRequest")); + } + + public: + SearchChatsOnServerRequest(ActorShared td, uint64 request_id, string query, int32 limit) + : RequestActor(std::move(td), request_id), query_(std::move(query)), limit_(limit) { + } +}; + +class GetGroupsInCommonRequest final : public RequestActor<> { + UserId user_id_; + DialogId offset_dialog_id_; + int32 limit_; + + std::pair> dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->common_dialog_manager_->get_common_dialogs(user_id_, offset_dialog_id_, limit_, get_tries() < 2, + std::move(promise)); + } + + void do_send_result() final { + send_result(td_->dialog_manager_->get_chats_object(dialog_ids_, "GetGroupsInCommonRequest")); + } + + public: + GetGroupsInCommonRequest(ActorShared td, uint64 request_id, int64 user_id, int64 offset_dialog_id, int32 limit) + : RequestActor(std::move(td), request_id), user_id_(user_id), offset_dialog_id_(offset_dialog_id), limit_(limit) { + } +}; + +class GetSuitableDiscussionChatsRequest final : public RequestActor<> { + vector dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->chat_manager_->get_dialogs_for_discussion(std::move(promise)); + } + + void do_send_result() final { + send_result(td_->dialog_manager_->get_chats_object(-1, dialog_ids_, "GetSuitableDiscussionChatsRequest")); + } + + public: + GetSuitableDiscussionChatsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class GetInactiveSupergroupChatsRequest final : public RequestActor<> { + vector dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->chat_manager_->get_inactive_channels(std::move(promise)); + } + + void do_send_result() final { + send_result(td_->dialog_manager_->get_chats_object(-1, dialog_ids_, "GetInactiveSupergroupChatsRequest")); + } + + public: + GetInactiveSupergroupChatsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class SearchRecentlyFoundChatsRequest final : public RequestActor<> { + string query_; + int32 limit_; + + std::pair> dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->messages_manager_->search_recently_found_dialogs(query_, limit_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->dialog_manager_->get_chats_object(dialog_ids_, "SearchRecentlyFoundChatsRequest")); + } + + public: + SearchRecentlyFoundChatsRequest(ActorShared td, uint64 request_id, string query, int32 limit) + : RequestActor(std::move(td), request_id), query_(std::move(query)), limit_(limit) { + } +}; + +class GetRecentlyOpenedChatsRequest final : public RequestActor<> { + int32 limit_; + + std::pair> dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->messages_manager_->get_recently_opened_dialogs(limit_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->dialog_manager_->get_chats_object(dialog_ids_, "GetRecentlyOpenedChatsRequest")); + } + + public: + GetRecentlyOpenedChatsRequest(ActorShared td, uint64 request_id, int32 limit) + : RequestActor(std::move(td), request_id), limit_(limit) { + } +}; + +class GetMessageRequest final : public RequestOnceActor { + MessageFullId message_full_id_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->get_message(message_full_id_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_object(message_full_id_, "GetMessageRequest")); + } + + public: + GetMessageRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id) + : RequestOnceActor(std::move(td), request_id), message_full_id_(DialogId(dialog_id), MessageId(message_id)) { + } +}; + +class GetRepliedMessageRequest final : public RequestOnceActor { + DialogId dialog_id_; + MessageId message_id_; + + MessageFullId replied_message_id_; + + void do_run(Promise &&promise) final { + replied_message_id_ = + td_->messages_manager_->get_replied_message(dialog_id_, message_id_, get_tries() < 3, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_object(replied_message_id_, "GetRepliedMessageRequest")); + } + + public: + GetRepliedMessageRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id) + : RequestOnceActor(std::move(td), request_id), dialog_id_(dialog_id), message_id_(message_id) { + set_tries(3); // 1 to get initial message, 1 to get the reply and 1 for result + } +}; + +class GetMessageThreadRequest final : public RequestActor { + DialogId dialog_id_; + MessageId message_id_; + + MessageThreadInfo message_thread_info_; + + void do_run(Promise &&promise) final { + if (get_tries() < 2) { + promise.set_value(std::move(message_thread_info_)); + return; + } + td_->messages_manager_->get_message_thread(dialog_id_, message_id_, std::move(promise)); + } + + void do_set_result(MessageThreadInfo &&result) final { + message_thread_info_ = std::move(result); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_thread_info_object(message_thread_info_)); + } + + public: + GetMessageThreadRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id) + : RequestActor(std::move(td), request_id), dialog_id_(dialog_id), message_id_(message_id) { + } +}; + +class GetChatPinnedMessageRequest final : public RequestOnceActor { + DialogId dialog_id_; + + MessageId pinned_message_id_; + + void do_run(Promise &&promise) final { + pinned_message_id_ = td_->messages_manager_->get_dialog_pinned_message(dialog_id_, std::move(promise)); + } + + void do_send_result() final { + send_result( + td_->messages_manager_->get_message_object({dialog_id_, pinned_message_id_}, "GetChatPinnedMessageRequest")); + } + + public: + GetChatPinnedMessageRequest(ActorShared td, uint64 request_id, int64 dialog_id) + : RequestOnceActor(std::move(td), request_id), dialog_id_(dialog_id) { + set_tries(3); // 1 to get pinned_message_id, 1 to get the message and 1 for result + } +}; + +class GetCallbackQueryMessageRequest final : public RequestOnceActor { + DialogId dialog_id_; + MessageId message_id_; + int64 callback_query_id_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->get_callback_query_message(dialog_id_, message_id_, callback_query_id_, std::move(promise)); + } + + void do_send_result() final { + send_result( + td_->messages_manager_->get_message_object({dialog_id_, message_id_}, "GetCallbackQueryMessageRequest")); + } + + public: + GetCallbackQueryMessageRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, + int64 callback_query_id) + : RequestOnceActor(std::move(td), request_id) + , dialog_id_(dialog_id) + , message_id_(message_id) + , callback_query_id_(callback_query_id) { + } +}; + +class GetMessagesRequest final : public RequestOnceActor { + DialogId dialog_id_; + vector message_ids_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->get_messages(dialog_id_, message_ids_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_messages_object(-1, dialog_id_, message_ids_, false, "GetMessagesRequest")); + } + + public: + GetMessagesRequest(ActorShared td, uint64 request_id, int64 dialog_id, const vector &message_ids) + : RequestOnceActor(std::move(td), request_id) + , dialog_id_(dialog_id) + , message_ids_(MessageId::get_message_ids(message_ids)) { + } +}; + +class GetMessageEmbeddingCodeRequest final : public RequestActor<> { + MessageFullId message_full_id_; + bool for_group_; + + string html_; + + void do_run(Promise &&promise) final { + html_ = td_->messages_manager_->get_message_embedding_code(message_full_id_, for_group_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_api::make_object(html_)); + } + + public: + GetMessageEmbeddingCodeRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, + bool for_group) + : RequestActor(std::move(td), request_id) + , message_full_id_(DialogId(dialog_id), MessageId(message_id)) + , for_group_(for_group) { + } +}; + +class GetMessageLinkInfoRequest final : public RequestActor { + string url_; + + MessageLinkInfo message_link_info_; + + void do_run(Promise &&promise) final { + if (get_tries() < 2) { + promise.set_value(std::move(message_link_info_)); + return; + } + td_->messages_manager_->get_message_link_info(url_, std::move(promise)); + } + + void do_set_result(MessageLinkInfo &&result) final { + message_link_info_ = std::move(result); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_link_info_object(message_link_info_)); + } + + public: + GetMessageLinkInfoRequest(ActorShared td, uint64 request_id, string url) + : RequestActor(std::move(td), request_id), url_(std::move(url)) { + } +}; + +class GetDialogBoostLinkInfoRequest final : public RequestActor { + string url_; + + DialogBoostLinkInfo dialog_boost_link_info_; + + void do_run(Promise &&promise) final { + if (get_tries() < 2) { + promise.set_value(std::move(dialog_boost_link_info_)); + return; + } + td_->boost_manager_->get_dialog_boost_link_info(url_, std::move(promise)); + } + + void do_set_result(DialogBoostLinkInfo &&result) final { + dialog_boost_link_info_ = std::move(result); + } + + void do_send_result() final { + send_result(td_->boost_manager_->get_chat_boost_link_info_object(dialog_boost_link_info_)); + } + + public: + GetDialogBoostLinkInfoRequest(ActorShared td, uint64 request_id, string url) + : RequestActor(std::move(td), request_id), url_(std::move(url)) { + } +}; + +class EditMessageTextRequest final : public RequestOnceActor { + MessageFullId message_full_id_; + td_api::object_ptr reply_markup_; + td_api::object_ptr input_message_content_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->edit_message_text(message_full_id_, std::move(reply_markup_), + std::move(input_message_content_), std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_object(message_full_id_, "EditMessageTextRequest")); + } + + public: + EditMessageTextRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, + td_api::object_ptr reply_markup, + td_api::object_ptr input_message_content) + : RequestOnceActor(std::move(td), request_id) + , message_full_id_(DialogId(dialog_id), MessageId(message_id)) + , reply_markup_(std::move(reply_markup)) + , input_message_content_(std::move(input_message_content)) { + } +}; + +class EditMessageLiveLocationRequest final : public RequestOnceActor { + MessageFullId message_full_id_; + td_api::object_ptr reply_markup_; + td_api::object_ptr location_; + int32 live_period_; + int32 heading_; + int32 proximity_alert_radius_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->edit_message_live_location(message_full_id_, std::move(reply_markup_), std::move(location_), + live_period_, heading_, proximity_alert_radius_, + std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_object(message_full_id_, "EditMessageLiveLocationRequest")); + } + + public: + EditMessageLiveLocationRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, + td_api::object_ptr reply_markup, + td_api::object_ptr location, int32 live_period, int32 heading, + int32 proximity_alert_radius) + : RequestOnceActor(std::move(td), request_id) + , message_full_id_(DialogId(dialog_id), MessageId(message_id)) + , reply_markup_(std::move(reply_markup)) + , location_(std::move(location)) + , live_period_(live_period) + , heading_(heading) + , proximity_alert_radius_(proximity_alert_radius) { + } +}; + +class EditMessageMediaRequest final : public RequestOnceActor { + MessageFullId message_full_id_; + td_api::object_ptr reply_markup_; + td_api::object_ptr input_message_content_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->edit_message_media(message_full_id_, std::move(reply_markup_), + std::move(input_message_content_), std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_object(message_full_id_, "EditMessageMediaRequest")); + } + + public: + EditMessageMediaRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, + td_api::object_ptr reply_markup, + td_api::object_ptr input_message_content) + : RequestOnceActor(std::move(td), request_id) + , message_full_id_(DialogId(dialog_id), MessageId(message_id)) + , reply_markup_(std::move(reply_markup)) + , input_message_content_(std::move(input_message_content)) { + } +}; + +class EditMessageCaptionRequest final : public RequestOnceActor { + MessageFullId message_full_id_; + td_api::object_ptr reply_markup_; + td_api::object_ptr caption_; + bool invert_media_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->edit_message_caption(message_full_id_, std::move(reply_markup_), std::move(caption_), + invert_media_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_object(message_full_id_, "EditMessageCaptionRequest")); + } + + public: + EditMessageCaptionRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, + td_api::object_ptr reply_markup, + td_api::object_ptr caption, bool invert_media) + : RequestOnceActor(std::move(td), request_id) + , message_full_id_(DialogId(dialog_id), MessageId(message_id)) + , reply_markup_(std::move(reply_markup)) + , caption_(std::move(caption)) + , invert_media_(invert_media) { + } +}; + +class EditMessageReplyMarkupRequest final : public RequestOnceActor { + MessageFullId message_full_id_; + td_api::object_ptr reply_markup_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->edit_message_reply_markup(message_full_id_, std::move(reply_markup_), std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_message_object(message_full_id_, "EditMessageReplyMarkupRequest")); + } + + public: + EditMessageReplyMarkupRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, + td_api::object_ptr reply_markup) + : RequestOnceActor(std::move(td), request_id) + , message_full_id_(DialogId(dialog_id), MessageId(message_id)) + , reply_markup_(std::move(reply_markup)) { + } +}; + +class GetChatHistoryRequest final : public RequestActor<> { + DialogId dialog_id_; + MessageId from_message_id_; + int32 offset_; + int32 limit_; + bool only_local_; + + td_api::object_ptr messages_; + + void do_run(Promise &&promise) final { + messages_ = td_->messages_manager_->get_dialog_history(dialog_id_, from_message_id_, offset_, limit_, + get_tries() - 1, only_local_, std::move(promise)); + } + + void do_send_result() final { + send_result(std::move(messages_)); + } + + public: + GetChatHistoryRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 from_message_id, int32 offset, + int32 limit, bool only_local) + : RequestActor(std::move(td), request_id) + , dialog_id_(dialog_id) + , from_message_id_(from_message_id) + , offset_(offset) + , limit_(limit) + , only_local_(only_local) { + if (!only_local_) { + set_tries(4); + } + } +}; + +class GetMessageThreadHistoryRequest final : public RequestActor<> { + DialogId dialog_id_; + MessageId message_id_; + MessageId from_message_id_; + int32 offset_; + int32 limit_; + int64 random_id_; + + std::pair> messages_; + + void do_run(Promise &&promise) final { + messages_ = td_->messages_manager_->get_message_thread_history(dialog_id_, message_id_, from_message_id_, offset_, + limit_, random_id_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_messages_object(-1, messages_.first, messages_.second, true, + "GetMessageThreadHistoryRequest")); + } + + public: + GetMessageThreadHistoryRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, + int64 from_message_id, int32 offset, int32 limit) + : RequestActor(std::move(td), request_id) + , dialog_id_(dialog_id) + , message_id_(message_id) + , from_message_id_(from_message_id) + , offset_(offset) + , limit_(limit) + , random_id_(0) { + set_tries(3); + } +}; + +class SearchChatMessagesRequest final : public RequestActor<> { + DialogId dialog_id_; + string query_; + td_api::object_ptr sender_id_; + MessageId from_message_id_; + int32 offset_; + int32 limit_; + MessageSearchFilter filter_; + MessageId top_thread_message_id_; + SavedMessagesTopicId saved_messages_topic_id_; + ReactionType tag_; + int64 random_id_; + + MessagesManager::FoundDialogMessages messages_; + + void do_run(Promise &&promise) final { + messages_ = td_->messages_manager_->search_dialog_messages( + dialog_id_, query_, sender_id_, from_message_id_, offset_, limit_, filter_, top_thread_message_id_, + saved_messages_topic_id_, tag_, random_id_, get_tries() == 3, std::move(promise)); + } + + void do_send_result() final { + send_result( + td_->messages_manager_->get_found_chat_messages_object(dialog_id_, messages_, "SearchChatMessagesRequest")); + } + + void do_send_error(Status &&status) final { + if (status.message() == "SEARCH_QUERY_EMPTY") { + messages_ = {}; + return do_send_result(); + } + send_error(std::move(status)); + } + + public: + SearchChatMessagesRequest(ActorShared td, uint64 request_id, int64 dialog_id, string query, + td_api::object_ptr sender_id, int64 from_message_id, int32 offset, + int32 limit, td_api::object_ptr filter, + int64 message_thread_id, SavedMessagesTopicId saved_messages_topic_id, ReactionType tag) + : RequestActor(std::move(td), request_id) + , dialog_id_(dialog_id) + , query_(std::move(query)) + , sender_id_(std::move(sender_id)) + , from_message_id_(from_message_id) + , offset_(offset) + , limit_(limit) + , filter_(get_message_search_filter(filter)) + , top_thread_message_id_(message_thread_id) + , saved_messages_topic_id_(saved_messages_topic_id) + , tag_(std::move(tag)) + , random_id_(0) { + set_tries(3); + } +}; + +class GetChatScheduledMessagesRequest final : public RequestActor<> { + DialogId dialog_id_; + + vector message_ids_; + + void do_run(Promise &&promise) final { + message_ids_ = + td_->messages_manager_->get_dialog_scheduled_messages(dialog_id_, get_tries() < 2, false, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_messages_object(-1, dialog_id_, message_ids_, true, + "GetChatScheduledMessagesRequest")); + } + + public: + GetChatScheduledMessagesRequest(ActorShared td, uint64 request_id, int64 dialog_id) + : RequestActor(std::move(td), request_id), dialog_id_(dialog_id) { + set_tries(4); + } +}; + +class GetWebPageInstantViewRequest final : public RequestActor { + string url_; + bool force_full_; + + WebPageId web_page_id_; + + void do_run(Promise &&promise) final { + if (get_tries() < 2) { + promise.set_value(std::move(web_page_id_)); + return; + } + td_->web_pages_manager_->get_web_page_instant_view(url_, force_full_, std::move(promise)); + } + + void do_set_result(WebPageId &&result) final { + web_page_id_ = result; + } + + void do_send_result() final { + send_result(td_->web_pages_manager_->get_web_page_instant_view_object(web_page_id_)); + } + + public: + GetWebPageInstantViewRequest(ActorShared td, uint64 request_id, string url, bool force_full) + : RequestActor(std::move(td), request_id), url_(std::move(url)), force_full_(force_full) { + } +}; + +class CreateChatRequest final : public RequestActor<> { + DialogId dialog_id_; + bool force_; + + void do_run(Promise &&promise) final { + td_->messages_manager_->create_dialog(dialog_id_, force_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->messages_manager_->get_chat_object(dialog_id_, "CreateChatRequest")); + } + + public: + CreateChatRequest(ActorShared td, uint64 request_id, DialogId dialog_id, bool force) + : RequestActor<>(std::move(td), request_id), dialog_id_(dialog_id), force_(force) { + } +}; + +class CheckChatInviteLinkRequest final : public RequestActor<> { + string invite_link_; + + void do_run(Promise &&promise) final { + td_->dialog_invite_link_manager_->check_dialog_invite_link(invite_link_, get_tries() < 2, std::move(promise)); + } + + void do_send_result() final { + auto result = td_->dialog_invite_link_manager_->get_chat_invite_link_info_object(invite_link_); + CHECK(result != nullptr); + send_result(std::move(result)); + } + + public: + CheckChatInviteLinkRequest(ActorShared td, uint64 request_id, string invite_link) + : RequestActor(std::move(td), request_id), invite_link_(std::move(invite_link)) { + } +}; + +class JoinChatByInviteLinkRequest final : public RequestActor { + string invite_link_; + + DialogId dialog_id_; + + void do_run(Promise &&promise) final { + if (get_tries() < 2) { + promise.set_value(std::move(dialog_id_)); + return; + } + td_->dialog_invite_link_manager_->import_dialog_invite_link(invite_link_, std::move(promise)); + } + + void do_set_result(DialogId &&result) final { + dialog_id_ = result; + } + + void do_send_result() final { + CHECK(dialog_id_.is_valid()); + td_->dialog_manager_->force_create_dialog(dialog_id_, "join chat via an invite link"); + send_result(td_->messages_manager_->get_chat_object(dialog_id_, "JoinChatByInviteLinkRequest")); + } + + public: + JoinChatByInviteLinkRequest(ActorShared td, uint64 request_id, string invite_link) + : RequestActor(std::move(td), request_id), invite_link_(std::move(invite_link)) { + } +}; + +class ImportContactsRequest final : public RequestActor<> { + vector contacts_; + int64 random_id_; + + std::pair, vector> imported_contacts_; + + void do_run(Promise &&promise) final { + imported_contacts_ = td_->user_manager_->import_contacts(contacts_, random_id_, std::move(promise)); + } + + void do_send_result() final { + CHECK(imported_contacts_.first.size() == contacts_.size()); + CHECK(imported_contacts_.second.size() == contacts_.size()); + send_result(td_api::make_object(transform(imported_contacts_.first, + [this](UserId user_id) { + return td_->user_manager_->get_user_id_object( + user_id, "ImportContactsRequest"); + }), + std::move(imported_contacts_.second))); + } + + public: + ImportContactsRequest(ActorShared td, uint64 request_id, vector &&contacts) + : RequestActor(std::move(td), request_id), contacts_(std::move(contacts)), random_id_(0) { + set_tries(3); // load_contacts + import_contacts + } +}; + +class SearchContactsRequest final : public RequestActor<> { + string query_; + int32 limit_; + + std::pair> user_ids_; + + void do_run(Promise &&promise) final { + user_ids_ = td_->user_manager_->search_contacts(query_, limit_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->user_manager_->get_users_object(user_ids_.first, user_ids_.second)); + } + + public: + SearchContactsRequest(ActorShared td, uint64 request_id, string query, int32 limit) + : RequestActor(std::move(td), request_id), query_(std::move(query)), limit_(limit) { + } +}; + +class RemoveContactsRequest final : public RequestActor<> { + vector user_ids_; + + void do_run(Promise &&promise) final { + td_->user_manager_->remove_contacts(user_ids_, std::move(promise)); + } + + public: + RemoveContactsRequest(ActorShared td, uint64 request_id, vector &&user_ids) + : RequestActor(std::move(td), request_id), user_ids_(std::move(user_ids)) { + set_tries(3); // load_contacts + delete_contacts + } +}; + +class GetImportedContactCountRequest final : public RequestActor<> { + int32 imported_contact_count_ = 0; + + void do_run(Promise &&promise) final { + imported_contact_count_ = td_->user_manager_->get_imported_contact_count(std::move(promise)); + } + + void do_send_result() final { + send_result(td_api::make_object(imported_contact_count_)); + } + + public: + GetImportedContactCountRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class ChangeImportedContactsRequest final : public RequestActor<> { + vector contacts_; + size_t contacts_size_; + int64 random_id_; + + std::pair, vector> imported_contacts_; + + void do_run(Promise &&promise) final { + imported_contacts_ = td_->user_manager_->change_imported_contacts(contacts_, random_id_, std::move(promise)); + } + + void do_send_result() final { + CHECK(imported_contacts_.first.size() == contacts_size_); + CHECK(imported_contacts_.second.size() == contacts_size_); + send_result(td_api::make_object(transform(imported_contacts_.first, + [this](UserId user_id) { + return td_->user_manager_->get_user_id_object( + user_id, "ChangeImportedContactsRequest"); + }), + std::move(imported_contacts_.second))); + } + + public: + ChangeImportedContactsRequest(ActorShared td, uint64 request_id, vector &&contacts) + : RequestActor(std::move(td), request_id) + , contacts_(std::move(contacts)) + , contacts_size_(contacts_.size()) + , random_id_(0) { + set_tries(4); // load_contacts + load_local_contacts + (import_contacts + delete_contacts) + } +}; + +class GetCloseFriendsRequest final : public RequestActor<> { + vector user_ids_; + + void do_run(Promise &&promise) final { + user_ids_ = td_->user_manager_->get_close_friends(std::move(promise)); + } + + void do_send_result() final { + send_result(td_->user_manager_->get_users_object(-1, user_ids_)); + } + + public: + GetCloseFriendsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class GetRecentInlineBotsRequest final : public RequestActor<> { + vector user_ids_; + + void do_run(Promise &&promise) final { + user_ids_ = td_->inline_queries_manager_->get_recent_inline_bots(std::move(promise)); + } + + void do_send_result() final { + send_result(td_->user_manager_->get_users_object(-1, user_ids_)); + } + + public: + GetRecentInlineBotsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class GetChatNotificationSettingsExceptionsRequest final : public RequestActor<> { + NotificationSettingsScope scope_; + bool filter_scope_; + bool compare_sound_; + + vector dialog_ids_; + + void do_run(Promise &&promise) final { + dialog_ids_ = td_->messages_manager_->get_dialog_notification_settings_exceptions( + scope_, filter_scope_, compare_sound_, get_tries() < 3, std::move(promise)); + } + + void do_send_result() final { + send_result( + td_->dialog_manager_->get_chats_object(-1, dialog_ids_, "GetChatNotificationSettingsExceptionsRequest")); + } + + public: + GetChatNotificationSettingsExceptionsRequest(ActorShared td, uint64 request_id, NotificationSettingsScope scope, + bool filter_scope, bool compare_sound) + : RequestActor(std::move(td), request_id) + , scope_(scope) + , filter_scope_(filter_scope) + , compare_sound_(compare_sound) { + set_tries(3); + } +}; + +class GetScopeNotificationSettingsRequest final : public RequestActor<> { + NotificationSettingsScope scope_; + + const ScopeNotificationSettings *notification_settings_ = nullptr; + + void do_run(Promise &&promise) final { + notification_settings_ = + td_->notification_settings_manager_->get_scope_notification_settings(scope_, std::move(promise)); + } + + void do_send_result() final { + CHECK(notification_settings_ != nullptr); + send_result(get_scope_notification_settings_object(notification_settings_)); + } + + public: + GetScopeNotificationSettingsRequest(ActorShared td, uint64 request_id, NotificationSettingsScope scope) + : RequestActor(std::move(td), request_id), scope_(scope) { + } +}; + +class GetStickersRequest final : public RequestActor<> { + StickerType sticker_type_; + string query_; + int32 limit_; + DialogId dialog_id_; + + vector sticker_ids_; + + void do_run(Promise &&promise) final { + sticker_ids_ = td_->stickers_manager_->get_stickers(sticker_type_, query_, limit_, dialog_id_, get_tries() < 2, + std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_stickers_object(sticker_ids_)); + } + + public: + GetStickersRequest(ActorShared td, uint64 request_id, StickerType sticker_type, string &&query, int32 limit, + int64 dialog_id) + : RequestActor(std::move(td), request_id) + , sticker_type_(sticker_type) + , query_(std::move(query)) + , limit_(limit) + , dialog_id_(dialog_id) { + set_tries(4); + } +}; + +class GetAllStickerEmojisRequest final : public RequestActor<> { + StickerType sticker_type_; + string query_; + DialogId dialog_id_; + bool return_only_main_emoji_; + + vector sticker_ids_; + + void do_run(Promise &&promise) final { + sticker_ids_ = td_->stickers_manager_->get_stickers(sticker_type_, query_, 1000000, dialog_id_, get_tries() < 2, + std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_sticker_emojis_object(sticker_ids_, return_only_main_emoji_)); + } + + public: + GetAllStickerEmojisRequest(ActorShared td, uint64 request_id, StickerType sticker_type, string &&query, + int64 dialog_id, bool return_only_main_emoji) + : RequestActor(std::move(td), request_id) + , sticker_type_(sticker_type) + , query_(std::move(query)) + , dialog_id_(dialog_id) + , return_only_main_emoji_(return_only_main_emoji) { + set_tries(4); + } +}; + +class GetInstalledStickerSetsRequest final : public RequestActor<> { + StickerType sticker_type_; + + vector sticker_set_ids_; + + void do_run(Promise &&promise) final { + sticker_set_ids_ = td_->stickers_manager_->get_installed_sticker_sets(sticker_type_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_sticker_sets_object(-1, sticker_set_ids_, 1)); + } + + public: + GetInstalledStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type) + : RequestActor(std::move(td), request_id), sticker_type_(sticker_type) { + } +}; + +class GetArchivedStickerSetsRequest final : public RequestActor<> { + StickerType sticker_type_; + StickerSetId offset_sticker_set_id_; + int32 limit_; + + int32 total_count_ = -1; + vector sticker_set_ids_; + + void do_run(Promise &&promise) final { + std::tie(total_count_, sticker_set_ids_) = td_->stickers_manager_->get_archived_sticker_sets( + sticker_type_, offset_sticker_set_id_, limit_, get_tries() < 2, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_sticker_sets_object(total_count_, sticker_set_ids_, 1)); + } + + public: + GetArchivedStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type, + int64 offset_sticker_set_id, int32 limit) + : RequestActor(std::move(td), request_id) + , sticker_type_(sticker_type) + , offset_sticker_set_id_(offset_sticker_set_id) + , limit_(limit) { + } +}; + +class GetTrendingStickerSetsRequest final : public RequestActor<> { + td_api::object_ptr result_; + StickerType sticker_type_; + int32 offset_; + int32 limit_; + + void do_run(Promise &&promise) final { + result_ = td_->stickers_manager_->get_featured_sticker_sets(sticker_type_, offset_, limit_, std::move(promise)); + } + + void do_send_result() final { + send_result(std::move(result_)); + } + + public: + GetTrendingStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type, int32 offset, + int32 limit) + : RequestActor(std::move(td), request_id), sticker_type_(sticker_type), offset_(offset), limit_(limit) { + set_tries(3); + } +}; + +class GetAttachedStickerSetsRequest final : public RequestActor<> { + FileId file_id_; + + vector sticker_set_ids_; + + void do_run(Promise &&promise) final { + sticker_set_ids_ = td_->stickers_manager_->get_attached_sticker_sets(file_id_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_sticker_sets_object(-1, sticker_set_ids_, 5)); + } + + public: + GetAttachedStickerSetsRequest(ActorShared td, uint64 request_id, int32 file_id) + : RequestActor(std::move(td), request_id), file_id_(file_id, 0) { + } +}; + +class GetStickerSetRequest final : public RequestActor<> { + StickerSetId set_id_; + + StickerSetId sticker_set_id_; + + void do_run(Promise &&promise) final { + sticker_set_id_ = td_->stickers_manager_->get_sticker_set(set_id_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_sticker_set_object(sticker_set_id_)); + } + + public: + GetStickerSetRequest(ActorShared td, uint64 request_id, int64 set_id) + : RequestActor(std::move(td), request_id), set_id_(set_id) { + set_tries(3); + } +}; + +class SearchStickerSetRequest final : public RequestActor<> { + string name_; + + StickerSetId sticker_set_id_; + + void do_run(Promise &&promise) final { + sticker_set_id_ = td_->stickers_manager_->search_sticker_set(name_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_sticker_set_object(sticker_set_id_)); + } + + public: + SearchStickerSetRequest(ActorShared td, uint64 request_id, string &&name) + : RequestActor(std::move(td), request_id), name_(std::move(name)) { + set_tries(3); + } +}; + +class SearchInstalledStickerSetsRequest final : public RequestActor<> { + StickerType sticker_type_; + string query_; + int32 limit_; + + std::pair> sticker_set_ids_; + + void do_run(Promise &&promise) final { + sticker_set_ids_ = + td_->stickers_manager_->search_installed_sticker_sets(sticker_type_, query_, limit_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_sticker_sets_object(sticker_set_ids_.first, sticker_set_ids_.second, 5)); + } + + public: + SearchInstalledStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type, string &&query, + int32 limit) + : RequestActor(std::move(td), request_id), sticker_type_(sticker_type), query_(std::move(query)), limit_(limit) { + } +}; + +class SearchStickerSetsRequest final : public RequestActor<> { + StickerType sticker_type_; + string query_; + + vector sticker_set_ids_; + + void do_run(Promise &&promise) final { + sticker_set_ids_ = td_->stickers_manager_->search_sticker_sets(sticker_type_, query_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_sticker_sets_object(-1, sticker_set_ids_, 5)); + } + + public: + SearchStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type, string &&query) + : RequestActor(std::move(td), request_id), sticker_type_(sticker_type), query_(std::move(query)) { + } +}; + +class ChangeStickerSetRequest final : public RequestOnceActor { + StickerSetId set_id_; + bool is_installed_; + bool is_archived_; + + void do_run(Promise &&promise) final { + td_->stickers_manager_->change_sticker_set(set_id_, is_installed_, is_archived_, std::move(promise)); + } + + public: + ChangeStickerSetRequest(ActorShared td, uint64 request_id, int64 set_id, bool is_installed, bool is_archived) + : RequestOnceActor(std::move(td), request_id) + , set_id_(set_id) + , is_installed_(is_installed) + , is_archived_(is_archived) { + set_tries(4); + } +}; + +class GetRecentStickersRequest final : public RequestActor<> { + bool is_attached_; + + vector sticker_ids_; + + void do_run(Promise &&promise) final { + sticker_ids_ = td_->stickers_manager_->get_recent_stickers(is_attached_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_stickers_object(sticker_ids_)); + } + + public: + GetRecentStickersRequest(ActorShared td, uint64 request_id, bool is_attached) + : RequestActor(std::move(td), request_id), is_attached_(is_attached) { + } +}; + +class AddRecentStickerRequest final : public RequestActor<> { + bool is_attached_; + td_api::object_ptr input_file_; + + void do_run(Promise &&promise) final { + td_->stickers_manager_->add_recent_sticker(is_attached_, input_file_, std::move(promise)); + } + + public: + AddRecentStickerRequest(ActorShared td, uint64 request_id, bool is_attached, + td_api::object_ptr &&input_file) + : RequestActor(std::move(td), request_id), is_attached_(is_attached), input_file_(std::move(input_file)) { + set_tries(3); + } +}; + +class RemoveRecentStickerRequest final : public RequestActor<> { + bool is_attached_; + td_api::object_ptr input_file_; + + void do_run(Promise &&promise) final { + td_->stickers_manager_->remove_recent_sticker(is_attached_, input_file_, std::move(promise)); + } + + public: + RemoveRecentStickerRequest(ActorShared td, uint64 request_id, bool is_attached, + td_api::object_ptr &&input_file) + : RequestActor(std::move(td), request_id), is_attached_(is_attached), input_file_(std::move(input_file)) { + set_tries(3); + } +}; + +class ClearRecentStickersRequest final : public RequestActor<> { + bool is_attached_; + + void do_run(Promise &&promise) final { + td_->stickers_manager_->clear_recent_stickers(is_attached_, std::move(promise)); + } + + public: + ClearRecentStickersRequest(ActorShared td, uint64 request_id, bool is_attached) + : RequestActor(std::move(td), request_id), is_attached_(is_attached) { + set_tries(3); + } +}; + +class GetFavoriteStickersRequest final : public RequestActor<> { + vector sticker_ids_; + + void do_run(Promise &&promise) final { + sticker_ids_ = td_->stickers_manager_->get_favorite_stickers(std::move(promise)); + } + + void do_send_result() final { + send_result(td_->stickers_manager_->get_stickers_object(sticker_ids_)); + } + + public: + GetFavoriteStickersRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class AddFavoriteStickerRequest final : public RequestOnceActor { + td_api::object_ptr input_file_; + + void do_run(Promise &&promise) final { + td_->stickers_manager_->add_favorite_sticker(input_file_, std::move(promise)); + } + + public: + AddFavoriteStickerRequest(ActorShared td, uint64 request_id, td_api::object_ptr &&input_file) + : RequestOnceActor(std::move(td), request_id), input_file_(std::move(input_file)) { + set_tries(3); + } +}; + +class RemoveFavoriteStickerRequest final : public RequestOnceActor { + td_api::object_ptr input_file_; + + void do_run(Promise &&promise) final { + td_->stickers_manager_->remove_favorite_sticker(input_file_, std::move(promise)); + } + + public: + RemoveFavoriteStickerRequest(ActorShared td, uint64 request_id, + td_api::object_ptr &&input_file) + : RequestOnceActor(std::move(td), request_id), input_file_(std::move(input_file)) { + set_tries(3); + } +}; + +class GetStickerEmojisRequest final : public RequestActor<> { + td_api::object_ptr input_file_; + + vector emojis_; + + void do_run(Promise &&promise) final { + emojis_ = td_->stickers_manager_->get_sticker_emojis(input_file_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_api::make_object(std::move(emojis_))); + } + + public: + GetStickerEmojisRequest(ActorShared td, uint64 request_id, td_api::object_ptr &&input_file) + : RequestActor(std::move(td), request_id), input_file_(std::move(input_file)) { + set_tries(3); + } +}; + +class SearchEmojisRequest final : public RequestActor<> { + string text_; + vector input_language_codes_; + + vector> emoji_keywords_; + + void do_run(Promise &&promise) final { + emoji_keywords_ = + td_->stickers_manager_->search_emojis(text_, input_language_codes_, get_tries() < 2, std::move(promise)); + } + + void do_send_result() final { + send_result(td_api::make_object( + transform(emoji_keywords_, [](const std::pair &emoji_keyword) { + return td_api::make_object(emoji_keyword.first, emoji_keyword.second); + }))); + } + + public: + SearchEmojisRequest(ActorShared td, uint64 request_id, string &&text, vector &&input_language_codes) + : RequestActor(std::move(td), request_id) + , text_(std::move(text)) + , input_language_codes_(std::move(input_language_codes)) { + set_tries(3); + } +}; + +class GetKeywordEmojisRequest final : public RequestActor<> { + string text_; + vector input_language_codes_; + + vector emojis_; + + void do_run(Promise &&promise) final { + emojis_ = + td_->stickers_manager_->get_keyword_emojis(text_, input_language_codes_, get_tries() < 2, std::move(promise)); + } + + void do_send_result() final { + send_result(td_api::make_object(std::move(emojis_))); + } + + public: + GetKeywordEmojisRequest(ActorShared td, uint64 request_id, string &&text, vector &&input_language_codes) + : RequestActor(std::move(td), request_id) + , text_(std::move(text)) + , input_language_codes_(std::move(input_language_codes)) { + set_tries(3); + } +}; + +class GetSavedAnimationsRequest final : public RequestActor<> { + vector animation_ids_; + + void do_run(Promise &&promise) final { + animation_ids_ = td_->animations_manager_->get_saved_animations(std::move(promise)); + } + + void do_send_result() final { + send_result(td_api::make_object(transform(animation_ids_, [td = td_](FileId animation_id) { + return td->animations_manager_->get_animation_object(animation_id); + }))); + } + + public: + GetSavedAnimationsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class AddSavedAnimationRequest final : public RequestOnceActor { + td_api::object_ptr input_file_; + + void do_run(Promise &&promise) final { + td_->animations_manager_->add_saved_animation(input_file_, std::move(promise)); + } + + public: + AddSavedAnimationRequest(ActorShared td, uint64 request_id, td_api::object_ptr &&input_file) + : RequestOnceActor(std::move(td), request_id), input_file_(std::move(input_file)) { + set_tries(3); + } +}; + +class RemoveSavedAnimationRequest final : public RequestOnceActor { + td_api::object_ptr input_file_; + + void do_run(Promise &&promise) final { + td_->animations_manager_->remove_saved_animation(input_file_, std::move(promise)); + } + + public: + RemoveSavedAnimationRequest(ActorShared td, uint64 request_id, td_api::object_ptr &&input_file) + : RequestOnceActor(std::move(td), request_id), input_file_(std::move(input_file)) { + set_tries(3); + } +}; + +class GetSavedNotificationSoundRequest final : public RequestActor<> { + int64 ringtone_id_; + FileId ringtone_file_id_; + + void do_run(Promise &&promise) final { + ringtone_file_id_ = td_->notification_settings_manager_->get_saved_ringtone(ringtone_id_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->audios_manager_->get_notification_sound_object(ringtone_file_id_)); + } + + public: + GetSavedNotificationSoundRequest(ActorShared td, uint64 request_id, int64 ringtone_id) + : RequestActor(std::move(td), request_id), ringtone_id_(ringtone_id) { + } +}; + +class GetSavedNotificationSoundsRequest final : public RequestActor<> { + vector ringtone_file_ids_; + + void do_run(Promise &&promise) final { + ringtone_file_ids_ = td_->notification_settings_manager_->get_saved_ringtones(std::move(promise)); + } + + void do_send_result() final { + send_result(td_api::make_object( + transform(ringtone_file_ids_, [td = td_](FileId ringtone_file_id) { + return td->audios_manager_->get_notification_sound_object(ringtone_file_id); + }))); + } + + public: + GetSavedNotificationSoundsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + } +}; + +class RemoveSavedNotificationSoundRequest final : public RequestOnceActor { + int64 ringtone_id_; + + void do_run(Promise &&promise) final { + td_->notification_settings_manager_->remove_saved_ringtone(ringtone_id_, std::move(promise)); + } + + public: + RemoveSavedNotificationSoundRequest(ActorShared td, uint64 request_id, int64 ringtone_id) + : RequestOnceActor(std::move(td), request_id), ringtone_id_(ringtone_id) { + set_tries(3); + } +}; + +class SearchBackgroundRequest final : public RequestActor<> { + string name_; + + std::pair background_; + + void do_run(Promise &&promise) final { + background_ = td_->background_manager_->search_background(name_, std::move(promise)); + } + + void do_send_result() final { + send_result(td_->background_manager_->get_background_object(background_.first, false, &background_.second)); + } + + public: + SearchBackgroundRequest(ActorShared td, uint64 request_id, string &&name) + : RequestActor(std::move(td), request_id), name_(std::move(name)) { + set_tries(3); + } +}; + +class Requests::DownloadFileCallback final : public FileManager::DownloadCallback { + public: + void on_download_ok(FileId file_id) final { + send_closure(G()->td(), &Td::on_file_download_finished, file_id); + } + + void on_download_error(FileId file_id, Status error) final { + send_closure(G()->td(), &Td::on_file_download_finished, file_id); + } +}; + +Requests::Requests(Td *td) + : td_(td), td_actor_(td->actor_id(td)), download_file_callback_(std::make_shared()) { +} + +void Requests::run_request(uint64 id, td_api::object_ptr &&function) { + CHECK(td_ != nullptr); + downcast_call(*function, [this, id](auto &request) { this->on_request(id, request); }); +} + +void Requests::send_error_raw(uint64 id, int32 code, CSlice error) { + send_closure(td_actor_, &Td::send_error_impl, id, td_api::make_object(code, error.str())); +} + +void Requests::answer_ok_query(uint64 id, Status status) { + if (status.is_error()) { + send_closure(td_actor_, &Td::send_error, id, std::move(status)); + } else { + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); + } +} + +Promise Requests::create_ok_request_promise(uint64 id) { + return PromiseCreator::lambda([actor_id = td_actor_, id](Result result) { + if (result.is_error()) { + send_closure(actor_id, &Td::send_error, id, result.move_as_error()); + } else { + send_closure(actor_id, &Td::send_result, id, td_api::make_object()); + } + }); +} + +Promise Requests::create_text_request_promise(uint64 id) { + return PromiseCreator::lambda([actor_id = td_actor_, id](Result result) mutable { + if (result.is_error()) { + send_closure(actor_id, &Td::send_error, id, result.move_as_error()); + } else { + send_closure(actor_id, &Td::send_result, id, td_api::make_object(result.move_as_ok())); + } + }); +} + +Promise Requests::create_http_url_request_promise(uint64 id) { + return PromiseCreator::lambda([actor_id = td_actor_, id](Result result) mutable { + if (result.is_error()) { + send_closure(actor_id, &Td::send_error, id, result.move_as_error()); + } else { + send_closure(actor_id, &Td::send_result, id, td_api::make_object(result.move_as_ok())); + } + }); +} + +#define CLEAN_INPUT_STRING(field_name) \ + if (!clean_input_string(field_name)) { \ + return send_error_raw(id, 400, "Strings must be encoded in UTF-8"); \ + } +#define CHECK_IS_BOT() \ + if (!td_->auth_manager_->is_bot()) { \ + return send_error_raw(id, 400, "Only bots can use the method"); \ + } +#define CHECK_IS_USER() \ + if (td_->auth_manager_->is_bot()) { \ + return send_error_raw(id, 400, "The method is not available to bots"); \ + } + +#define CREATE_NO_ARGS_REQUEST(name) \ + auto slot_id = td_->request_actors_.create(ActorOwn<>(), Td::RequestActorIdType); \ + td_->inc_request_actor_refcnt(); \ + *td_->request_actors_.get(slot_id) = create_actor(#name, td_->actor_shared(td_, slot_id), id); +#define CREATE_REQUEST(name, ...) \ + auto slot_id = td_->request_actors_.create(ActorOwn<>(), Td::RequestActorIdType); \ + td_->inc_request_actor_refcnt(); \ + *td_->request_actors_.get(slot_id) = create_actor(#name, td_->actor_shared(td_, slot_id), id, __VA_ARGS__); + +#define CREATE_REQUEST_PROMISE() auto promise = create_request_promise::ReturnType>(id) +#define CREATE_OK_REQUEST_PROMISE() \ + static_assert(std::is_same::ReturnType, td_api::object_ptr>::value, ""); \ + auto promise = create_ok_request_promise(id) +#define CREATE_TEXT_REQUEST_PROMISE() \ + static_assert(std::is_same::ReturnType, td_api::object_ptr>::value, \ + ""); \ + auto promise = create_text_request_promise(id) +#define CREATE_HTTP_URL_REQUEST_PROMISE() \ + static_assert(std::is_same::ReturnType, td_api::object_ptr>::value, \ + ""); \ + auto promise = create_http_url_request_promise(id) + +void Requests::on_request(uint64 id, const td_api::setTdlibParameters &request) { + send_error_raw(id, 400, "Unexpected setTdlibParameters"); +} + +void Requests::on_request(uint64 id, td_api::setDatabaseEncryptionKey &request) { + CREATE_OK_REQUEST_PROMISE(); + G()->td_db()->get_binlog()->change_key(TdDb::as_db_key(std::move(request.new_encryption_key_)), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getAuthorizationState &request) { + send_closure(td_->auth_manager_actor_, &AuthManager::get_state, id); +} + +void Requests::on_request(uint64 id, td_api::setAuthenticationPhoneNumber &request) { + CLEAN_INPUT_STRING(request.phone_number_); + send_closure(td_->auth_manager_actor_, &AuthManager::set_phone_number, id, std::move(request.phone_number_), + std::move(request.settings_)); +} + +void Requests::on_request(uint64 id, td_api::sendAuthenticationFirebaseSms &request) { + CLEAN_INPUT_STRING(request.token_); + send_closure(td_->auth_manager_actor_, &AuthManager::set_firebase_token, id, std::move(request.token_)); +} + +void Requests::on_request(uint64 id, td_api::reportAuthenticationCodeMissing &request) { + CLEAN_INPUT_STRING(request.mobile_network_code_); + send_closure(td_->auth_manager_actor_, &AuthManager::report_missing_code, id, + std::move(request.mobile_network_code_)); +} + +void Requests::on_request(uint64 id, td_api::setAuthenticationEmailAddress &request) { + CLEAN_INPUT_STRING(request.email_address_); + send_closure(td_->auth_manager_actor_, &AuthManager::set_email_address, id, std::move(request.email_address_)); +} + +void Requests::on_request(uint64 id, td_api::resendAuthenticationCode &request) { + send_closure(td_->auth_manager_actor_, &AuthManager::resend_authentication_code, id, std::move(request.reason_)); +} + +void Requests::on_request(uint64 id, td_api::checkAuthenticationEmailCode &request) { + send_closure(td_->auth_manager_actor_, &AuthManager::check_email_code, id, + EmailVerification(std::move(request.code_))); +} + +void Requests::on_request(uint64 id, td_api::checkAuthenticationCode &request) { + CLEAN_INPUT_STRING(request.code_); + send_closure(td_->auth_manager_actor_, &AuthManager::check_code, id, std::move(request.code_)); +} + +void Requests::on_request(uint64 id, td_api::registerUser &request) { + CLEAN_INPUT_STRING(request.first_name_); + CLEAN_INPUT_STRING(request.last_name_); + send_closure(td_->auth_manager_actor_, &AuthManager::register_user, id, std::move(request.first_name_), + std::move(request.last_name_), request.disable_notification_); +} + +void Requests::on_request(uint64 id, td_api::requestQrCodeAuthentication &request) { + send_closure(td_->auth_manager_actor_, &AuthManager::request_qr_code_authentication, id, + UserId::get_user_ids(request.other_user_ids_)); +} + +void Requests::on_request(uint64 id, const td_api::resetAuthenticationEmailAddress &request) { + send_closure(td_->auth_manager_actor_, &AuthManager::reset_email_address, id); +} + +void Requests::on_request(uint64 id, td_api::checkAuthenticationPassword &request) { + CLEAN_INPUT_STRING(request.password_); + send_closure(td_->auth_manager_actor_, &AuthManager::check_password, id, std::move(request.password_)); +} + +void Requests::on_request(uint64 id, const td_api::requestAuthenticationPasswordRecovery &request) { + send_closure(td_->auth_manager_actor_, &AuthManager::request_password_recovery, id); +} + +void Requests::on_request(uint64 id, td_api::checkAuthenticationPasswordRecoveryCode &request) { + CLEAN_INPUT_STRING(request.recovery_code_); + send_closure(td_->auth_manager_actor_, &AuthManager::check_password_recovery_code, id, + std::move(request.recovery_code_)); +} + +void Requests::on_request(uint64 id, td_api::recoverAuthenticationPassword &request) { + CLEAN_INPUT_STRING(request.recovery_code_); + CLEAN_INPUT_STRING(request.new_password_); + CLEAN_INPUT_STRING(request.new_hint_); + send_closure(td_->auth_manager_actor_, &AuthManager::recover_password, id, std::move(request.recovery_code_), + std::move(request.new_password_), std::move(request.new_hint_)); +} + +void Requests::on_request(uint64 id, const td_api::logOut &request) { + // will call Td::destroy later + send_closure(td_->auth_manager_actor_, &AuthManager::log_out, id); +} + +void Requests::on_request(uint64 id, const td_api::close &request) { + // send response before actually closing + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); + send_closure(td_actor_, &Td::close); +} + +void Requests::on_request(uint64 id, const td_api::destroy &request) { + // send response before actually destroying + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); + send_closure(td_actor_, &Td::destroy); +} + +void Requests::on_request(uint64 id, td_api::checkAuthenticationBotToken &request) { + CLEAN_INPUT_STRING(request.token_); + send_closure(td_->auth_manager_actor_, &AuthManager::check_bot_token, id, std::move(request.token_)); +} + +void Requests::on_request(uint64 id, td_api::confirmQrCodeAuthentication &request) { + CLEAN_INPUT_STRING(request.link_); + CREATE_REQUEST_PROMISE(); + td_->account_manager_->confirm_qr_code_authentication(request.link_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getCurrentState &request) { + vector> updates; + + td_->option_manager_->get_current_state(updates); + + auto state = td_->auth_manager_->get_current_authorization_state_object(); + if (state != nullptr) { + updates.push_back(td_api::make_object(std::move(state))); + } + + td_->connection_state_manager_->get_current_state(updates); + + if (td_->auth_manager_->is_authorized()) { + td_->user_manager_->get_current_state(updates); + + td_->chat_manager_->get_current_state(updates); + + td_->background_manager_->get_current_state(updates); + + td_->animations_manager_->get_current_state(updates); + + td_->attach_menu_manager_->get_current_state(updates); + + td_->stickers_manager_->get_current_state(updates); + + td_->reaction_manager_->get_current_state(updates); + + td_->notification_settings_manager_->get_current_state(updates); + + td_->dialog_filter_manager_->get_current_state(updates); + + td_->messages_manager_->get_current_state(updates); + + td_->dialog_participant_manager_->get_current_state(updates); + + td_->notification_manager_->get_current_state(updates); + + td_->quick_reply_manager_->get_current_state(updates); + + td_->saved_messages_manager_->get_current_state(updates); + + td_->story_manager_->get_current_state(updates); + + td_->config_manager_.get_actor_unsafe()->get_current_state(updates); + + td_->transcription_manager_->get_current_state(updates); + + td_->autosave_manager_->get_current_state(updates); + + td_->account_manager_->get_current_state(updates); + + td_->business_connection_manager_->get_current_state(updates); + + td_->terms_of_service_manager_->get_current_state(updates); + + td_->star_manager_->get_current_state(updates); + + // TODO updateFileGenerationStart generation_id:int64 original_path:string destination_path:string conversion:string = Update; + // TODO updateCall call:call = Update; + // TODO updateGroupCall call:groupCall = Update; + } + + // send response synchronously to prevent "Request aborted" or other changes of the current state + td_->send_result(id, td_api::make_object(std::move(updates))); +} + +void Requests::on_request(uint64 id, const td_api::getPasswordState &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::get_state, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setPassword &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.old_password_); + CLEAN_INPUT_STRING(request.new_password_); + CLEAN_INPUT_STRING(request.new_hint_); + CLEAN_INPUT_STRING(request.new_recovery_email_address_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::set_password, std::move(request.old_password_), + std::move(request.new_password_), std::move(request.new_hint_), request.set_recovery_email_address_, + std::move(request.new_recovery_email_address_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setLoginEmailAddress &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.new_login_email_address_); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_email_address_authentication_code_info_object()); + } + }); + send_closure(td_->password_manager_, &PasswordManager::set_login_email_address, + std::move(request.new_login_email_address_), std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::resendLoginEmailAddressCode &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_email_address_authentication_code_info_object()); + } + }); + send_closure(td_->password_manager_, &PasswordManager::resend_login_email_address_code, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::checkLoginEmailAddressCode &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::check_login_email_address_code, + EmailVerification(std::move(request.code_)), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setRecoveryEmailAddress &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + CLEAN_INPUT_STRING(request.new_recovery_email_address_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::set_recovery_email_address, std::move(request.password_), + std::move(request.new_recovery_email_address_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getRecoveryEmailAddress &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::get_recovery_email_address, std::move(request.password_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::checkRecoveryEmailAddressCode &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.code_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::check_recovery_email_address_code, std::move(request.code_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::resendRecoveryEmailAddressCode &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::resend_recovery_email_address_code, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::cancelRecoveryEmailAddressVerification &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::cancel_recovery_email_address_verification, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::requestPasswordRecovery &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_email_address_authentication_code_info_object()); + } + }); + send_closure(td_->password_manager_, &PasswordManager::request_password_recovery, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::checkPasswordRecoveryCode &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.recovery_code_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::check_password_recovery_code, + std::move(request.recovery_code_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::recoverPassword &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.recovery_code_); + CLEAN_INPUT_STRING(request.new_password_); + CLEAN_INPUT_STRING(request.new_hint_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::recover_password, std::move(request.recovery_code_), + std::move(request.new_password_), std::move(request.new_hint_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::resetPassword &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::reset_password, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::cancelPasswordReset &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::cancel_password_reset, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getTemporaryPasswordState &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::get_temp_password_state, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createTemporaryPassword &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::create_temp_password, std::move(request.password_), + request.valid_for_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::processPushNotification &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.payload_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->notification_manager(), &NotificationManager::process_push_notification, + std::move(request.payload_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::registerDevice &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(td_->device_token_manager_, &DeviceTokenManager::register_device, std::move(request.device_token_), + UserId::get_user_ids(request.other_user_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getUserPrivacySettingRules &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->privacy_manager_->get_privacy(std::move(request.setting_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setUserPrivacySettingRules &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->privacy_manager_->set_privacy(std::move(request.setting_), std::move(request.rules_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getDefaultMessageAutoDeleteTime &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.ok())); + } + }); + td_->account_manager_->get_default_message_ttl(std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::setDefaultMessageAutoDeleteTime &request) { + CHECK_IS_USER(); + if (request.message_auto_delete_time_ == nullptr) { + return send_error_raw(id, 400, "New default message auto-delete time must be non-empty"); + } + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->set_default_message_ttl(request.message_auto_delete_time_->time_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getAccountTtl &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.ok())); + } + }); + td_->account_manager_->get_account_ttl(std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::setAccountTtl &request) { + CHECK_IS_USER(); + if (request.ttl_ == nullptr) { + return send_error_raw(id, 400, "New account TTL must be non-empty"); + } + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->set_account_ttl(request.ttl_->days_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::deleteAccount &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.reason_); + send_closure(td_->auth_manager_actor_, &AuthManager::delete_account, id, request.reason_, request.password_); +} + +void Requests::on_request(uint64 id, td_api::sendPhoneNumberCode &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.phone_number_); + CREATE_REQUEST_PROMISE(); + td_->phone_number_manager_->set_phone_number(std::move(request.phone_number_), std::move(request.settings_), + std::move(request.type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendPhoneNumberFirebaseSms &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.token_); + CREATE_OK_REQUEST_PROMISE(); + td_->phone_number_manager_->send_firebase_sms(std::move(request.token_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::reportPhoneNumberCodeMissing &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.mobile_network_code_); + CREATE_OK_REQUEST_PROMISE(); + td_->phone_number_manager_->report_missing_code(std::move(request.mobile_network_code_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::resendPhoneNumberCode &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->phone_number_manager_->resend_authentication_code(std::move(request.reason_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::checkPhoneNumberCode &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.code_); + CREATE_OK_REQUEST_PROMISE(); + td_->phone_number_manager_->check_code(std::move(request.code_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getUserLink &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->account_manager_->get_user_link(std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchUserByToken &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.token_); + CREATE_REQUEST_PROMISE(); + td_->account_manager_->import_contact_token(std::move(request.token_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getActiveSessions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->account_manager_->get_active_sessions(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::terminateSession &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->terminate_session(request.session_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::terminateAllOtherSessions &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->terminate_all_other_sessions(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::confirmSession &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->confirm_session(request.session_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSessionCanAcceptCalls &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->toggle_session_can_accept_calls(request.session_id_, request.can_accept_calls_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSessionCanAcceptSecretChats &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->toggle_session_can_accept_secret_chats(request.session_id_, request.can_accept_secret_chats_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setInactiveSessionTtl &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->set_inactive_session_ttl_days(request.inactive_session_ttl_days_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getConnectedWebsites &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->account_manager_->get_connected_websites(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::disconnectWebsite &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->disconnect_website(request.website_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::disconnectAllWebsites &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->account_manager_->disconnect_all_websites(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMe &request) { + CREATE_NO_ARGS_REQUEST(GetMeRequest); +} + +void Requests::on_request(uint64 id, const td_api::getUser &request) { + CREATE_REQUEST(GetUserRequest, request.user_id_); +} + +void Requests::on_request(uint64 id, const td_api::getUserFullInfo &request) { + CREATE_REQUEST(GetUserFullInfoRequest, request.user_id_); +} + +void Requests::on_request(uint64 id, const td_api::getBasicGroup &request) { + CREATE_REQUEST(GetGroupRequest, request.basic_group_id_); +} + +void Requests::on_request(uint64 id, const td_api::getBasicGroupFullInfo &request) { + CREATE_REQUEST(GetGroupFullInfoRequest, request.basic_group_id_); +} + +void Requests::on_request(uint64 id, const td_api::getSupergroup &request) { + CREATE_REQUEST(GetSupergroupRequest, request.supergroup_id_); +} + +void Requests::on_request(uint64 id, const td_api::getSupergroupFullInfo &request) { + CREATE_REQUEST(GetSupergroupFullInfoRequest, request.supergroup_id_); +} + +void Requests::on_request(uint64 id, const td_api::getSecretChat &request) { + CREATE_REQUEST(GetSecretChatRequest, request.secret_chat_id_); +} + +void Requests::on_request(uint64 id, const td_api::getChat &request) { + CREATE_REQUEST(GetChatRequest, request.chat_id_); +} + +void Requests::on_request(uint64 id, const td_api::getMessage &request) { + CREATE_REQUEST(GetMessageRequest, request.chat_id_, request.message_id_); +} + +void Requests::on_request(uint64 id, const td_api::getMessageLocally &request) { + MessageFullId message_full_id(DialogId(request.chat_id_), MessageId(request.message_id_)); + send_closure(td_actor_, &Td::send_result, id, + td_->messages_manager_->get_message_object(message_full_id, "getMessageLocally")); +} + +void Requests::on_request(uint64 id, const td_api::getRepliedMessage &request) { + CREATE_REQUEST(GetRepliedMessageRequest, request.chat_id_, request.message_id_); +} + +void Requests::on_request(uint64 id, const td_api::getChatPinnedMessage &request) { + CREATE_REQUEST(GetChatPinnedMessageRequest, request.chat_id_); +} + +void Requests::on_request(uint64 id, const td_api::getCallbackQueryMessage &request) { + CHECK_IS_BOT(); + CREATE_REQUEST(GetCallbackQueryMessageRequest, request.chat_id_, request.message_id_, request.callback_query_id_); +} + +void Requests::on_request(uint64 id, const td_api::getMessages &request) { + CREATE_REQUEST(GetMessagesRequest, request.chat_id_, request.message_ids_); +} + +void Requests::on_request(uint64 id, const td_api::getMessageProperties &request) { + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_message_properties(DialogId(request.chat_id_), MessageId(request.message_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatSponsoredMessages &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->sponsored_message_manager_->get_dialog_sponsored_messages(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::clickChatSponsoredMessage &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->sponsored_message_manager_->click_sponsored_message(DialogId(request.chat_id_), MessageId(request.message_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::reportChatSponsoredMessage &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->sponsored_message_manager_->report_sponsored_message(DialogId(request.chat_id_), MessageId(request.message_id_), + request.option_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMessageThread &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetMessageThreadRequest, request.chat_id_, request.message_id_); +} + +void Requests::on_request(uint64 id, const td_api::getMessageReadDate &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_message_read_date({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMessageViewers &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_message_viewers({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMessageLink &request) { + auto r_message_link = td_->messages_manager_->get_message_link( + {DialogId(request.chat_id_), MessageId(request.message_id_)}, request.media_timestamp_, request.for_album_, + request.in_message_thread_); + if (r_message_link.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_message_link.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, + td_api::make_object(r_message_link.ok().first, r_message_link.ok().second)); + } +} + +void Requests::on_request(uint64 id, const td_api::getMessageEmbeddingCode &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetMessageEmbeddingCodeRequest, request.chat_id_, request.message_id_, request.for_album_); +} + +void Requests::on_request(uint64 id, td_api::getMessageLinkInfo &request) { + CLEAN_INPUT_STRING(request.url_); + CREATE_REQUEST(GetMessageLinkInfoRequest, std::move(request.url_)); +} + +void Requests::on_request(uint64 id, td_api::translateText &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.to_language_code_); + CREATE_REQUEST_PROMISE(); + td_->translation_manager_->translate_text(std::move(request.text_), request.to_language_code_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::translateMessageText &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.to_language_code_); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->translate_message_text({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.to_language_code_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::recognizeSpeech &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->transcription_manager_->recognize_speech({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::rateSpeechRecognition &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->transcription_manager_->rate_speech_recognition({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.is_good_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getFile &request) { + auto file_object = td_->file_manager_->get_file_object(FileId(request.file_id_, 0)); + if (file_object->id_ == 0) { + file_object = nullptr; + } else { + file_object->id_ = request.file_id_; + } + send_closure(td_actor_, &Td::send_result, id, std::move(file_object)); +} + +void Requests::on_request(uint64 id, td_api::getRemoteFile &request) { + CLEAN_INPUT_STRING(request.remote_file_id_); + auto file_type = request.file_type_ == nullptr ? FileType::Temp : get_file_type(*request.file_type_); + auto r_file_id = td_->file_manager_->from_persistent_id(request.remote_file_id_, file_type); + if (r_file_id.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_file_id.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, td_->file_manager_->get_file_object(r_file_id.ok())); + } +} + +void Requests::on_request(uint64 id, td_api::getStorageStatistics &request) { + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_storage_statistics_object()); + } + }); + send_closure(td_->storage_manager_, &StorageManager::get_storage_stats, false /*need_all_files*/, request.chat_limit_, + std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::getStorageStatisticsFast &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_storage_statistics_fast_object()); + } + }); + send_closure(td_->storage_manager_, &StorageManager::get_storage_stats_fast, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::getDatabaseStatistics &request) { + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_database_statistics_object()); + } + }); + send_closure(td_->storage_manager_, &StorageManager::get_database_stats, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::optimizeStorage &request) { + std::vector file_types; + for (auto &file_type : request.file_types_) { + if (file_type == nullptr) { + return send_error_raw(id, 400, "File type must be non-empty"); + } + + file_types.push_back(get_file_type(*file_type)); + } + FileGcParameters parameters(request.size_, request.ttl_, request.count_, request.immunity_delay_, + std::move(file_types), DialogId::get_dialog_ids(request.chat_ids_), + DialogId::get_dialog_ids(request.exclude_chat_ids_), request.chat_limit_); + + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_storage_statistics_object()); + } + }); + send_closure(td_->storage_manager_, &StorageManager::run_gc, std::move(parameters), + request.return_deleted_file_statistics_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::getNetworkStatistics &request) { + if (td_->net_stats_manager_.empty()) { + return send_error_raw(id, 400, "Network statistics are disabled"); + } + if (!request.only_current_ && G()->get_option_boolean("disable_persistent_network_statistics")) { + return send_error_raw(id, 400, "Persistent network statistics are disabled"); + } + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_network_statistics_object()); + } + }); + send_closure(td_->net_stats_manager_, &NetStatsManager::get_network_stats, request.only_current_, + std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::resetNetworkStatistics &request) { + if (td_->net_stats_manager_.empty()) { + return send_error_raw(id, 400, "Network statistics are disabled"); + } + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->net_stats_manager_, &NetStatsManager::reset_network_stats); + promise.set_value(Unit()); +} + +void Requests::on_request(uint64 id, td_api::addNetworkStatistics &request) { + if (request.entry_ == nullptr) { + return send_error_raw(id, 400, "Network statistics entry must be non-empty"); + } + if (td_->net_stats_manager_.empty()) { + return send_error_raw(id, 400, "Network statistics are disabled"); + } + + NetworkStatsEntry entry; + switch (request.entry_->get_id()) { + case td_api::networkStatisticsEntryFile::ID: { + auto file_entry = move_tl_object_as(request.entry_); + entry.is_call = false; + if (file_entry->file_type_ != nullptr) { + entry.file_type = get_file_type(*file_entry->file_type_); + } + entry.net_type = get_net_type(file_entry->network_type_); + entry.rx = file_entry->received_bytes_; + entry.tx = file_entry->sent_bytes_; + break; + } + case td_api::networkStatisticsEntryCall::ID: { + auto call_entry = move_tl_object_as(request.entry_); + entry.is_call = true; + entry.net_type = get_net_type(call_entry->network_type_); + entry.rx = call_entry->received_bytes_; + entry.tx = call_entry->sent_bytes_; + entry.duration = call_entry->duration_; + break; + } + default: + UNREACHABLE(); + } + + if (entry.net_type == NetType::None) { + return send_error_raw(id, 400, "Network statistics entry can't be increased for NetworkTypeNone"); + } + if (entry.rx > (static_cast(1) << 40) || entry.rx < 0) { + return send_error_raw(id, 400, "Wrong received bytes value"); + } + if (entry.tx > (static_cast(1) << 40) || entry.tx < 0) { + return send_error_raw(id, 400, "Wrong sent bytes value"); + } + if (entry.count > (1 << 30) || entry.count < 0) { + return send_error_raw(id, 400, "Wrong count value"); + } + if (entry.duration > (1 << 30) || entry.duration < 0) { + return send_error_raw(id, 400, "Wrong duration value"); + } + + send_closure(td_->net_stats_manager_, &NetStatsManager::add_network_stats, entry); + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); +} + +void Requests::on_request(uint64 id, const td_api::setNetworkType &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->state_manager_, &StateManager::on_network, get_net_type(request.type_)); + promise.set_value(Unit()); +} + +void Requests::on_request(uint64 id, const td_api::getAutoDownloadSettingsPresets &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_auto_download_settings_presets(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setAutoDownloadSettings &request) { + CHECK_IS_USER(); + if (request.settings_ == nullptr) { + return send_error_raw(id, 400, "New settings must be non-empty"); + } + CREATE_OK_REQUEST_PROMISE(); + set_auto_download_settings(td_, get_net_type(request.type_), get_auto_download_settings(request.settings_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getAutosaveSettings &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->autosave_manager_->get_autosave_settings(std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setAutosaveSettings &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->autosave_manager_->set_autosave_settings(std::move(request.scope_), std::move(request.settings_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::clearAutosaveSettingsExceptions &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->autosave_manager_->clear_autosave_settings_exceptions(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getRecommendedChats &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->channel_recommendation_manager_->get_recommended_channels(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatSimilarChats &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->channel_recommendation_manager_->get_channel_recommendations(DialogId(request.chat_id_), false, + std::move(promise), Auto()); +} + +void Requests::on_request(uint64 id, const td_api::getChatSimilarChatCount &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->channel_recommendation_manager_->get_channel_recommendations(DialogId(request.chat_id_), request.return_local_, + Auto(), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::openChatSimilarChat &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->channel_recommendation_manager_->open_channel_recommended_channel( + DialogId(request.chat_id_), DialogId(request.opened_chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getTopChats &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(td_->top_dialog_manager_actor_, &TopDialogManager::get_top_dialogs, + get_top_dialog_category(request.category_), request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeTopChat &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->top_dialog_manager_actor_, &TopDialogManager::remove_dialog, + get_top_dialog_category(request.category_), DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::loadChats &request) { + CHECK_IS_USER(); + + DialogListId dialog_list_id(request.chat_list_); + auto r_offset = td_->messages_manager_->get_dialog_list_last_date(dialog_list_id); + if (r_offset.is_error()) { + return send_error_raw(id, 400, r_offset.error().message()); + } + auto offset = r_offset.move_as_ok(); + if (offset == MAX_DIALOG_DATE) { + return send_closure(td_actor_, &Td::send_result, id, nullptr); + } + + CREATE_REQUEST(LoadChatsRequest, dialog_list_id, offset, request.limit_); +} + +void Requests::on_request(uint64 id, const td_api::getChats &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_dialogs_from_list(DialogListId(request.chat_list_), request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::loadSavedMessagesTopics &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->saved_messages_manager_->load_saved_messages_topics(request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getSavedMessagesTopicHistory &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->saved_messages_manager_->get_saved_messages_topic_history( + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), MessageId(request.from_message_id_), + request.offset_, request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getSavedMessagesTopicMessageByDate &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->saved_messages_manager_->get_saved_messages_topic_message_by_date( + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), request.date_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteSavedMessagesTopicHistory &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->saved_messages_manager_->delete_saved_messages_topic_history( + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteSavedMessagesTopicMessagesByDate &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->saved_messages_manager_->delete_saved_messages_topic_messages_by_date( + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), request.min_date_, + request.max_date_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSavedMessagesTopicIsPinned &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->saved_messages_manager_->toggle_saved_messages_topic_is_pinned( + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), request.is_pinned_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setPinnedSavedMessagesTopics &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->saved_messages_manager_->set_pinned_saved_messages_topics( + td_->saved_messages_manager_->get_topic_ids(request.saved_messages_topic_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchPublicChat &request) { + CLEAN_INPUT_STRING(request.username_); + CREATE_REQUEST(SearchPublicChatRequest, request.username_); +} + +void Requests::on_request(uint64 id, td_api::searchPublicChats &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchPublicChatsRequest, request.query_); +} + +void Requests::on_request(uint64 id, td_api::searchChats &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchChatsRequest, request.query_, request.limit_); +} + +void Requests::on_request(uint64 id, td_api::searchChatsOnServer &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchChatsOnServerRequest, request.query_, request.limit_); +} + +void Requests::on_request(uint64 id, const td_api::searchChatsNearby &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->people_nearby_manager_->search_dialogs_nearby(Location(request.location_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getGroupsInCommon &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetGroupsInCommonRequest, request.user_id_, request.offset_chat_id_, request.limit_); +} + +void Requests::on_request(uint64 id, td_api::checkChatUsername &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.username_); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda( + [promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(DialogManager::get_check_chat_username_result_object(result.ok())); + } + }); + td_->dialog_manager_->check_dialog_username(DialogId(request.chat_id_), request.username_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::getCreatedPublicChats &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->chat_manager_->get_created_public_dialogs(get_public_dialog_type(request.type_), std::move(promise), false); +} + +void Requests::on_request(uint64 id, const td_api::checkCreatedPublicChatsLimit &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->check_created_public_dialogs_limit(get_public_dialog_type(request.type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getSuitableDiscussionChats &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetSuitableDiscussionChatsRequest); +} + +void Requests::on_request(uint64 id, const td_api::getInactiveSupergroupChats &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetInactiveSupergroupChatsRequest); +} + +void Requests::on_request(uint64 id, const td_api::getSuitablePersonalChats &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->chat_manager_->get_created_public_dialogs(PublicDialogType::ForPersonalDialog, std::move(promise), false); +} + +void Requests::on_request(uint64 id, td_api::searchRecentlyFoundChats &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchRecentlyFoundChatsRequest, request.query_, request.limit_); +} + +void Requests::on_request(uint64 id, const td_api::addRecentlyFoundChat &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->add_recently_found_dialog(DialogId(request.chat_id_))); +} + +void Requests::on_request(uint64 id, const td_api::removeRecentlyFoundChat &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->remove_recently_found_dialog(DialogId(request.chat_id_))); +} + +void Requests::on_request(uint64 id, const td_api::clearRecentlyFoundChats &request) { + CHECK_IS_USER(); + td_->messages_manager_->clear_recently_found_dialogs(); + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); +} + +void Requests::on_request(uint64 id, const td_api::getRecentlyOpenedChats &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetRecentlyOpenedChatsRequest, request.limit_); +} + +void Requests::on_request(uint64 id, const td_api::openChat &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->open_dialog(DialogId(request.chat_id_))); +} + +void Requests::on_request(uint64 id, const td_api::closeChat &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->close_dialog(DialogId(request.chat_id_))); +} + +void Requests::on_request(uint64 id, const td_api::viewMessages &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->view_messages(DialogId(request.chat_id_), + MessageId::get_message_ids(request.message_ids_), + get_message_source(request.source_), request.force_read_)); +} + +void Requests::on_request(uint64 id, const td_api::openMessageContent &request) { + CHECK_IS_USER(); + answer_ok_query( + id, td_->messages_manager_->open_message_content({DialogId(request.chat_id_), MessageId(request.message_id_)})); +} + +void Requests::on_request(uint64 id, const td_api::clickAnimatedEmojiMessage &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->click_animated_emoji_message({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getInternalLink &request) { + auto r_link = LinkManager::get_internal_link(request.type_, !request.is_http_); + if (r_link.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_link.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(r_link.move_as_ok())); + } +} + +void Requests::on_request(uint64 id, const td_api::getInternalLinkType &request) { + auto type = LinkManager::parse_internal_link(request.link_); + send_closure(td_actor_, &Td::send_result, id, type == nullptr ? nullptr : type->get_internal_link_type_object()); +} + +void Requests::on_request(uint64 id, td_api::getExternalLinkInfo &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.link_); + CREATE_REQUEST_PROMISE(); + td_->link_manager_->get_external_link_info(std::move(request.link_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getExternalLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.link_); + CREATE_REQUEST_PROMISE(); + td_->link_manager_->get_link_login_url(request.link_, request.allow_write_access_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatHistory &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetChatHistoryRequest, request.chat_id_, request.from_message_id_, request.offset_, request.limit_, + request.only_local_); +} + +void Requests::on_request(uint64 id, const td_api::deleteChatHistory &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->delete_dialog_history(DialogId(request.chat_id_), request.remove_from_chat_list_, + request.revoke_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteChat &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + DialogId dialog_id(request.chat_id_); + auto query_promise = [actor_id = td_->messages_manager_actor_.get(), dialog_id, + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &MessagesManager::on_dialog_deleted, dialog_id, std::move(promise)); + } + }; + td_->dialog_manager_->delete_dialog(dialog_id, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMessageThreadHistory &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetMessageThreadHistoryRequest, request.chat_id_, request.message_id_, request.from_message_id_, + request.offset_, request.limit_); +} + +void Requests::on_request(uint64 id, const td_api::getChatMessageCalendar &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_dialog_message_calendar( + DialogId(request.chat_id_), td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), + MessageId(request.from_message_id_), get_message_search_filter(request.filter_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchChatMessages &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchChatMessagesRequest, request.chat_id_, std::move(request.query_), std::move(request.sender_id_), + request.from_message_id_, request.offset_, request.limit_, std::move(request.filter_), + request.message_thread_id_, + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), ReactionType()); +} + +void Requests::on_request(uint64 id, td_api::searchSecretMessages &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->offline_search_messages(DialogId(request.chat_id_), std::move(request.query_), + std::move(request.offset_), request.limit_, + get_message_search_filter(request.filter_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchMessages &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->search_messages( + DialogListId(request.chat_list_), request.chat_list_ == nullptr, request.only_in_channels_, + std::move(request.query_), std::move(request.offset_), request.limit_, get_message_search_filter(request.filter_), + request.min_date_, request.max_date_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchSavedMessages &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchChatMessagesRequest, td_->dialog_manager_->get_my_dialog_id().get(), std::move(request.query_), + nullptr, request.from_message_id_, request.offset_, request.limit_, nullptr, 0, + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), + ReactionType(request.tag_)); +} + +void Requests::on_request(uint64 id, const td_api::searchCallMessages &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->search_call_messages(request.offset_, request.limit_, request.only_missed_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchOutgoingDocumentMessages &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->search_outgoing_document_messages(request.query_, request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchPublicMessagesByTag &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.tag_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->search_hashtag_posts(std::move(request.tag_), std::move(request.offset_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchPublicStoriesByTag &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.tag_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->search_hashtag_posts(std::move(request.tag_), std::move(request.offset_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchPublicStoriesByLocation &request) { + CHECK_IS_USER(); + if (request.address_ == nullptr) { + return send_error_raw(id, 400, "Address must be non-empty"); + } + CLEAN_INPUT_STRING(request.address_->country_code_); + CLEAN_INPUT_STRING(request.address_->state_); + CLEAN_INPUT_STRING(request.address_->city_); + CLEAN_INPUT_STRING(request.address_->street_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->search_location_posts(std::move(request.address_), std::move(request.offset_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchPublicStoriesByVenue &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.venue_provider_); + CLEAN_INPUT_STRING(request.venue_id_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->search_venue_posts(std::move(request.venue_provider_), std::move(request.venue_id_), + std::move(request.offset_), request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getSearchedForTags &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.tag_prefix_); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result> result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.move_as_ok())); + } + }); + send_closure(request.tag_prefix_[0] == '$' ? td_->cashtag_search_hints_ : td_->hashtag_search_hints_, + &HashtagHints::query, std::move(request.tag_prefix_), request.limit_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::removeSearchedForTag &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.tag_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(request.tag_[0] == '$' ? td_->cashtag_search_hints_ : td_->hashtag_search_hints_, + &HashtagHints::remove_hashtag, std::move(request.tag_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::clearSearchedForTags &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(request.clear_cashtags_ ? td_->cashtag_search_hints_ : td_->hashtag_search_hints_, &HashtagHints::clear, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteAllCallMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->delete_all_call_messages(request.revoke_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::searchChatRecentLocationMessages &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->search_dialog_recent_location_messages(DialogId(request.chat_id_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatMessageByDate &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_dialog_message_by_date(DialogId(request.chat_id_), request.date_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatSparseMessagePositions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_dialog_sparse_message_positions( + DialogId(request.chat_id_), td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), + get_message_search_filter(request.filter_), MessageId(request.from_message_id_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatMessageCount &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.move_as_ok())); + } + }); + td_->messages_manager_->get_dialog_message_count( + DialogId(request.chat_id_), td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), + get_message_search_filter(request.filter_), request.return_local_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatMessagePosition &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.move_as_ok())); + } + }); + td_->messages_manager_->get_dialog_message_position( + {DialogId(request.chat_id_), MessageId(request.message_id_)}, get_message_search_filter(request.filter_), + MessageId(request.message_thread_id_), + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatScheduledMessages &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetChatScheduledMessagesRequest, request.chat_id_); +} + +void Requests::on_request(uint64 id, const td_api::getEmojiReaction &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->reaction_manager_->get_emoji_reaction(request.emoji_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getCustomEmojiReactionAnimations &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_custom_emoji_reaction_generic_animations(false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMessageAvailableReactions &request) { + CHECK_IS_USER(); + auto r_reactions = td_->messages_manager_->get_message_available_reactions( + {DialogId(request.chat_id_), MessageId(request.message_id_)}, request.row_size_); + if (r_reactions.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_reactions.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_reactions.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, const td_api::clearRecentReactions &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->reaction_manager_->clear_recent_reactions(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::addMessageReaction &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->add_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)}, + ReactionType(request.reaction_type_), request.is_big_, + request.update_recent_reactions_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::addPendingPaidMessageReaction &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->add_paid_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.star_count_, request.use_default_is_anonymous_, + request.is_anonymous_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::commitPendingPaidMessageReactions &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->commit_paid_message_reactions({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removePendingPaidMessageReactions &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->remove_paid_message_reactions({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::togglePaidMessageReactionIsAnonymous &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->toggle_paid_message_reaction_is_anonymous( + {DialogId(request.chat_id_), MessageId(request.message_id_)}, request.is_anonymous_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeMessageReaction &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->remove_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)}, + ReactionType(request.reaction_type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setMessageReactions &request) { + CHECK_IS_BOT(); + CREATE_OK_REQUEST_PROMISE(); + set_message_reactions(td_, {DialogId(request.chat_id_), MessageId(request.message_id_)}, + ReactionType::get_reaction_types(request.reaction_types_), request.is_big_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getMessageAddedReactions &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + get_message_added_reactions(td_, {DialogId(request.chat_id_), MessageId(request.message_id_)}, + ReactionType(request.reaction_type_), std::move(request.offset_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setDefaultReactionType &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->reaction_manager_->set_default_reaction(ReactionType(request.reaction_type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getSavedMessagesTags &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->reaction_manager_->get_saved_messages_tags( + td_->saved_messages_manager_->get_topic_id(request.saved_messages_topic_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setSavedMessagesTagLabel &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.label_); + CREATE_OK_REQUEST_PROMISE(); + td_->reaction_manager_->set_saved_messages_tag_title(ReactionType(request.tag_), std::move(request.label_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMessageEffect &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->reaction_manager_->get_message_effect(MessageEffectId(request.effect_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getMessagePublicForwards &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->statistics_manager_->get_message_public_forwards({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(request.offset_), request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getStoryPublicForwards &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->statistics_manager_->get_story_public_forwards( + {DialogId(request.story_sender_chat_id_), StoryId(request.story_id_)}, std::move(request.offset_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeNotification &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->notification_manager_actor_, &NotificationManager::remove_notification, + NotificationGroupId(request.notification_group_id_), NotificationId(request.notification_id_), false, + true, std::move(promise), "td_api::removeNotification"); +} + +void Requests::on_request(uint64 id, const td_api::removeNotificationGroup &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->notification_manager_actor_, &NotificationManager::remove_notification_group, + NotificationGroupId(request.notification_group_id_), NotificationId(request.max_notification_id_), + NotificationObjectId(), -1, true, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteMessages &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->delete_messages(DialogId(request.chat_id_), MessageId::get_message_ids(request.message_ids_), + request.revoke_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteChatMessagesBySender &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, sender_dialog_id, get_message_sender_dialog_id(td_, request.sender_id_, false, false)); + td_->messages_manager_->delete_dialog_messages_by_sender(DialogId(request.chat_id_), sender_dialog_id, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteChatMessagesByDate &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->delete_dialog_messages_by_date(DialogId(request.chat_id_), request.min_date_, + request.max_date_, request.revoke_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::readAllChatMentions &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->read_all_dialog_mentions(DialogId(request.chat_id_), MessageId(), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::readAllMessageThreadMentions &request) { + CHECK_IS_USER(); + if (request.message_thread_id_ == 0) { + return send_error_raw(id, 400, "Invalid message thread identifier specified"); + } + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->read_all_dialog_mentions(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::readAllChatReactions &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->read_all_dialog_reactions(DialogId(request.chat_id_), MessageId(), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::readAllMessageThreadReactions &request) { + CHECK_IS_USER(); + if (request.message_thread_id_ == 0) { + return send_error_raw(id, 400, "Invalid message thread identifier specified"); + } + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->read_all_dialog_reactions(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatAvailableMessageSenders &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_dialog_send_message_as_dialog_ids(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatMessageSender &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, message_sender_dialog_id, + get_message_sender_dialog_id(td_, request.message_sender_id_, true, false)); + td_->messages_manager_->set_dialog_default_send_message_as_dialog_id(DialogId(request.chat_id_), + message_sender_dialog_id, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendMessage &request) { + auto r_sent_message = td_->messages_manager_->send_message( + DialogId(request.chat_id_), MessageId(request.message_thread_id_), std::move(request.reply_to_), + std::move(request.options_), std::move(request.reply_markup_), std::move(request.input_message_content_)); + if (r_sent_message.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_sent_message.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_sent_message.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, td_api::sendMessageAlbum &request) { + auto r_messages = td_->messages_manager_->send_message_group( + DialogId(request.chat_id_), MessageId(request.message_thread_id_), std::move(request.reply_to_), + std::move(request.options_), std::move(request.input_message_contents_)); + if (r_messages.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_messages.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_messages.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, td_api::sendBotStartMessage &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.parameter_); + + DialogId dialog_id(request.chat_id_); + auto r_new_message_id = + td_->messages_manager_->send_bot_start_message(UserId(request.bot_user_id_), dialog_id, request.parameter_); + if (r_new_message_id.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_new_message_id.move_as_error()); + } + + CHECK(r_new_message_id.ok().is_valid() || r_new_message_id.ok().is_valid_scheduled()); + send_closure(td_actor_, &Td::send_result, id, + td_->messages_manager_->get_message_object({dialog_id, r_new_message_id.ok()}, "sendBotStartMessage")); +} + +void Requests::on_request(uint64 id, td_api::sendInlineQueryResultMessage &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.result_id_); + + auto r_sent_message = td_->messages_manager_->send_inline_query_result_message( + DialogId(request.chat_id_), MessageId(request.message_thread_id_), std::move(request.reply_to_), + std::move(request.options_), request.query_id_, request.result_id_, request.hide_via_bot_); + if (r_sent_message.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_sent_message.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_sent_message.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, td_api::addLocalMessage &request) { + CHECK_IS_USER(); + + DialogId dialog_id(request.chat_id_); + auto r_new_message_id = td_->messages_manager_->add_local_message( + dialog_id, std::move(request.sender_id_), std::move(request.reply_to_), request.disable_notification_, + std::move(request.input_message_content_)); + if (r_new_message_id.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_new_message_id.move_as_error()); + } + + CHECK(r_new_message_id.ok().is_valid()); + send_closure(td_actor_, &Td::send_result, id, + td_->messages_manager_->get_message_object({dialog_id, r_new_message_id.ok()}, "addLocalMessage")); +} + +void Requests::on_request(uint64 id, td_api::editMessageText &request) { + CREATE_REQUEST(EditMessageTextRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_), + std::move(request.input_message_content_)); +} + +void Requests::on_request(uint64 id, td_api::editMessageLiveLocation &request) { + CREATE_REQUEST(EditMessageLiveLocationRequest, request.chat_id_, request.message_id_, + std::move(request.reply_markup_), std::move(request.location_), request.live_period_, request.heading_, + request.proximity_alert_radius_); +} + +void Requests::on_request(uint64 id, td_api::editMessageMedia &request) { + CREATE_REQUEST(EditMessageMediaRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_), + std::move(request.input_message_content_)); +} + +void Requests::on_request(uint64 id, td_api::editMessageCaption &request) { + CREATE_REQUEST(EditMessageCaptionRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_), + std::move(request.caption_), request.show_caption_above_media_); +} + +void Requests::on_request(uint64 id, td_api::editMessageReplyMarkup &request) { + CHECK_IS_BOT(); + CREATE_REQUEST(EditMessageReplyMarkupRequest, request.chat_id_, request.message_id_, + std::move(request.reply_markup_)); +} + +void Requests::on_request(uint64 id, td_api::editInlineMessageText &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.inline_message_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->inline_message_manager_->edit_inline_message_text(request.inline_message_id_, std::move(request.reply_markup_), + std::move(request.input_message_content_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editInlineMessageLiveLocation &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.inline_message_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->inline_message_manager_->edit_inline_message_live_location( + request.inline_message_id_, std::move(request.reply_markup_), std::move(request.location_), request.live_period_, + request.heading_, request.proximity_alert_radius_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editInlineMessageMedia &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.inline_message_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->inline_message_manager_->edit_inline_message_media(request.inline_message_id_, std::move(request.reply_markup_), + std::move(request.input_message_content_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editInlineMessageCaption &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.inline_message_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->inline_message_manager_->edit_inline_message_caption( + request.inline_message_id_, std::move(request.reply_markup_), std::move(request.caption_), + request.show_caption_above_media_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editInlineMessageReplyMarkup &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.inline_message_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->inline_message_manager_->edit_inline_message_reply_markup(request.inline_message_id_, + std::move(request.reply_markup_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editMessageSchedulingState &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->edit_message_scheduling_state({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(request.scheduling_state_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setMessageFactCheck &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->set_message_fact_check({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(request.text_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendBusinessMessage &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->send_message(BusinessConnectionId(std::move(request.business_connection_id_)), + DialogId(request.chat_id_), std::move(request.reply_to_), + request.disable_notification_, request.protect_content_, + MessageEffectId(request.effect_id_), std::move(request.reply_markup_), + std::move(request.input_message_content_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendBusinessMessageAlbum &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->send_message_album( + BusinessConnectionId(std::move(request.business_connection_id_)), DialogId(request.chat_id_), + std::move(request.reply_to_), request.disable_notification_, request.protect_content_, + MessageEffectId(request.effect_id_), std::move(request.input_message_contents_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editBusinessMessageText &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->edit_business_message_text( + BusinessConnectionId(std::move(request.business_connection_id_)), DialogId(request.chat_id_), + MessageId(request.message_id_), std::move(request.reply_markup_), std::move(request.input_message_content_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editBusinessMessageLiveLocation &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->edit_business_message_live_location( + BusinessConnectionId(std::move(request.business_connection_id_)), DialogId(request.chat_id_), + MessageId(request.message_id_), std::move(request.reply_markup_), std::move(request.location_), + request.live_period_, request.heading_, request.proximity_alert_radius_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editBusinessMessageMedia &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->edit_business_message_media( + BusinessConnectionId(std::move(request.business_connection_id_)), DialogId(request.chat_id_), + MessageId(request.message_id_), std::move(request.reply_markup_), std::move(request.input_message_content_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editBusinessMessageCaption &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->edit_business_message_caption( + BusinessConnectionId(std::move(request.business_connection_id_)), DialogId(request.chat_id_), + MessageId(request.message_id_), std::move(request.reply_markup_), std::move(request.caption_), + request.show_caption_above_media_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editBusinessMessageReplyMarkup &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->edit_business_message_reply_markup( + BusinessConnectionId(std::move(request.business_connection_id_)), DialogId(request.chat_id_), + MessageId(request.message_id_), std::move(request.reply_markup_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::stopBusinessPoll &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->stop_poll(BusinessConnectionId(std::move(request.business_connection_id_)), + DialogId(request.chat_id_), MessageId(request.message_id_), + std::move(request.reply_markup_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBusinessMessageIsPinned &request) { + CHECK_IS_BOT(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->pin_dialog_message(BusinessConnectionId(std::move(request.business_connection_id_)), + DialogId(request.chat_id_), MessageId(request.message_id_), true, false, + !request.is_pinned_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::loadQuickReplyShortcuts &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->quick_reply_manager_->get_quick_reply_shortcuts(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setQuickReplyShortcutName &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->quick_reply_manager_->set_quick_reply_shortcut_name(QuickReplyShortcutId(request.shortcut_id_), request.name_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteQuickReplyShortcut &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->quick_reply_manager_->delete_quick_reply_shortcut(QuickReplyShortcutId(request.shortcut_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::reorderQuickReplyShortcuts &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->quick_reply_manager_->reorder_quick_reply_shortcuts( + QuickReplyShortcutId::get_quick_reply_shortcut_ids(request.shortcut_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::loadQuickReplyShortcutMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->quick_reply_manager_->get_quick_reply_shortcut_messages(QuickReplyShortcutId(request.shortcut_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteQuickReplyShortcutMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->quick_reply_manager_->delete_quick_reply_shortcut_messages( + QuickReplyShortcutId(request.shortcut_id_), MessageId::get_message_ids(request.message_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::addQuickReplyShortcutMessage &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.shortcut_name_); + auto r_sent_message = td_->quick_reply_manager_->send_message( + request.shortcut_name_, MessageId(request.reply_to_message_id_), std::move(request.input_message_content_)); + if (r_sent_message.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_sent_message.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_sent_message.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, td_api::addQuickReplyShortcutInlineQueryResultMessage &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.shortcut_name_); + CLEAN_INPUT_STRING(request.result_id_); + auto r_sent_message = td_->quick_reply_manager_->send_inline_query_result_message( + request.shortcut_name_, MessageId(request.reply_to_message_id_), request.query_id_, request.result_id_, + request.hide_via_bot_); + if (r_sent_message.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_sent_message.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_sent_message.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, td_api::addQuickReplyShortcutMessageAlbum &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.shortcut_name_); + auto r_messages = td_->quick_reply_manager_->send_message_group( + request.shortcut_name_, MessageId(request.reply_to_message_id_), std::move(request.input_message_contents_)); + if (r_messages.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_messages.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_messages.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, td_api::readdQuickReplyShortcutMessages &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.shortcut_name_); + auto r_messages = td_->quick_reply_manager_->resend_messages(request.shortcut_name_, + MessageId::get_message_ids(request.message_ids_)); + if (r_messages.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_messages.move_as_error()); + } + send_closure(td_actor_, &Td::send_result, id, r_messages.move_as_ok()); +} + +void Requests::on_request(uint64 id, td_api::editQuickReplyMessage &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->quick_reply_manager_->edit_quick_reply_message(QuickReplyShortcutId(request.shortcut_id_), + MessageId(request.message_id_), + std::move(request.input_message_content_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getCurrentWeather &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->inline_queries_manager_->get_weather(Location(request.location_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStory &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->get_story(DialogId(request.story_sender_chat_id_), StoryId(request.story_id_), + request.only_local_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatsToSendStories &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->get_dialogs_to_send_stories(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::canSendStory &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->can_send_story(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendStory &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->send_story(DialogId(request.chat_id_), std::move(request.content_), std::move(request.areas_), + std::move(request.caption_), std::move(request.privacy_settings_), + request.active_period_, std::move(request.from_story_full_id_), + request.is_posted_to_chat_page_, request.protect_content_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editStory &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->edit_story(DialogId(request.story_sender_chat_id_), StoryId(request.story_id_), + std::move(request.content_), std::move(request.areas_), std::move(request.caption_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::editStoryCover &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->edit_story_cover(DialogId(request.story_sender_chat_id_), StoryId(request.story_id_), + request.cover_frame_timestamp_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setStoryPrivacySettings &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->set_story_privacy_settings(StoryId(request.story_id_), std::move(request.privacy_settings_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleStoryIsPostedToChatPage &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->toggle_story_is_pinned(DialogId(request.story_sender_chat_id_), StoryId(request.story_id_), + request.is_posted_to_chat_page_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteStory &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->delete_story(DialogId(request.story_sender_chat_id_), StoryId(request.story_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::loadActiveStories &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->load_active_stories(StoryListId(request.story_list_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatActiveStoriesList &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->toggle_dialog_stories_hidden(DialogId(request.chat_id_), StoryListId(request.story_list_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getForumTopicDefaultIcons &request) { + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_default_topic_icons(false, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createForumTopic &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST_PROMISE(); + td_->forum_topic_manager_->create_forum_topic(DialogId(request.chat_id_), std::move(request.name_), + std::move(request.icon_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editForumTopic &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_OK_REQUEST_PROMISE(); + td_->forum_topic_manager_->edit_forum_topic(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(request.name_), request.edit_icon_custom_emoji_, + CustomEmojiId(request.icon_custom_emoji_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getForumTopic &request) { + CREATE_REQUEST_PROMISE(); + td_->forum_topic_manager_->get_forum_topic(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getForumTopicLink &request) { + CREATE_REQUEST_PROMISE(); + td_->forum_topic_manager_->get_forum_topic_link(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getForumTopics &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST_PROMISE(); + td_->forum_topic_manager_->get_forum_topics(DialogId(request.chat_id_), std::move(request.query_), + request.offset_date_, MessageId(request.offset_message_id_), + MessageId(request.offset_message_thread_id_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleForumTopicIsClosed &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->forum_topic_manager_->toggle_forum_topic_is_closed( + DialogId(request.chat_id_), MessageId(request.message_thread_id_), request.is_closed_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleGeneralForumTopicIsHidden &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->forum_topic_manager_->toggle_forum_topic_is_hidden(DialogId(request.chat_id_), request.is_hidden_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleForumTopicIsPinned &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->forum_topic_manager_->toggle_forum_topic_is_pinned( + DialogId(request.chat_id_), MessageId(request.message_thread_id_), request.is_pinned_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setPinnedForumTopics &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->forum_topic_manager_->set_pinned_forum_topics( + DialogId(request.chat_id_), MessageId::get_message_ids(request.message_thread_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteForumTopic &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->forum_topic_manager_->delete_forum_topic(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setGameScore &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->game_manager_->set_game_score({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.edit_message_, UserId(request.user_id_), request.score_, request.force_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setInlineGameScore &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.inline_message_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->inline_message_manager_->set_inline_game_score(request.inline_message_id_, request.edit_message_, + UserId(request.user_id_), request.score_, request.force_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getGameHighScores &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->game_manager_->get_game_high_scores({DialogId(request.chat_id_), MessageId(request.message_id_)}, + UserId(request.user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getInlineGameHighScores &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.inline_message_id_); + CREATE_REQUEST_PROMISE(); + td_->inline_message_manager_->get_inline_game_high_scores(request.inline_message_id_, UserId(request.user_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteChatReplyMarkup &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->delete_dialog_reply_markup(DialogId(request.chat_id_), + MessageId(request.message_id_))); +} + +void Requests::on_request(uint64 id, td_api::sendChatAction &request) { + CLEAN_INPUT_STRING(request.business_connection_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_action_manager_->send_dialog_action(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + BusinessConnectionId(std::move(request.business_connection_id_)), + DialogAction(std::move(request.action_)), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::forwardMessages &request) { + auto input_message_ids = MessageId::get_message_ids(request.message_ids_); + auto message_copy_options = + transform(input_message_ids, [send_copy = request.send_copy_, remove_caption = request.remove_caption_]( + MessageId) { return MessageCopyOptions(send_copy, remove_caption); }); + auto r_messages = td_->messages_manager_->forward_messages( + DialogId(request.chat_id_), MessageId(request.message_thread_id_), DialogId(request.from_chat_id_), + std::move(input_message_ids), std::move(request.options_), false, std::move(message_copy_options)); + if (r_messages.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_messages.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_messages.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, const td_api::sendQuickReplyShortcutMessages &request) { + auto r_messages = td_->messages_manager_->send_quick_reply_shortcut_messages( + DialogId(request.chat_id_), QuickReplyShortcutId(request.shortcut_id_), request.sending_id_); + if (r_messages.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_messages.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, r_messages.move_as_ok()); + } +} + +void Requests::on_request(uint64 id, td_api::resendMessages &request) { + DialogId dialog_id(request.chat_id_); + auto r_message_ids = td_->messages_manager_->resend_messages( + dialog_id, MessageId::get_message_ids(request.message_ids_), std::move(request.quote_)); + if (r_message_ids.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_message_ids.move_as_error()); + } + + send_closure(td_actor_, &Td::send_result, id, + td_->messages_manager_->get_messages_object(-1, dialog_id, r_message_ids.ok(), false, "resendMessages")); +} + +void Requests::on_request(uint64 id, td_api::getLinkPreview &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->web_pages_manager_->get_web_page_preview(std::move(request.text_), std::move(request.link_preview_options_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getWebPageInstantView &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.url_); + CREATE_REQUEST(GetWebPageInstantViewRequest, std::move(request.url_), request.force_full_); +} + +void Requests::on_request(uint64 id, const td_api::createPrivateChat &request) { + CREATE_REQUEST(CreateChatRequest, DialogId(UserId(request.user_id_)), request.force_); +} + +void Requests::on_request(uint64 id, const td_api::createBasicGroupChat &request) { + CREATE_REQUEST(CreateChatRequest, DialogId(ChatId(request.basic_group_id_)), request.force_); +} + +void Requests::on_request(uint64 id, const td_api::createSupergroupChat &request) { + CREATE_REQUEST(CreateChatRequest, DialogId(ChannelId(request.supergroup_id_)), request.force_); +} + +void Requests::on_request(uint64 id, const td_api::createSecretChat &request) { + CREATE_REQUEST(CreateChatRequest, DialogId(SecretChatId(request.secret_chat_id_)), true); +} + +void Requests::on_request(uint64 id, td_api::createNewBasicGroupChat &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.title_); + CREATE_REQUEST_PROMISE(); + td_->chat_manager_->create_new_chat(UserId::get_user_ids(request.user_ids_), std::move(request.title_), + MessageTtl(request.message_auto_delete_time_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createNewSupergroupChat &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.title_); + CLEAN_INPUT_STRING(request.description_); + CREATE_REQUEST_PROMISE(); + td_->chat_manager_->create_new_channel(std::move(request.title_), request.is_forum_, !request.is_channel_, + std::move(request.description_), DialogLocation(std::move(request.location_)), + request.for_import_, MessageTtl(request.message_auto_delete_time_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::createNewSecretChat &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->user_manager_->create_new_secret_chat(UserId(request.user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::createCall &request) { + CHECK_IS_USER(); + + if (request.protocol_ == nullptr) { + return send_error_raw(id, 400, "Call protocol must be non-empty"); + } + + UserId user_id(request.user_id_); + auto r_input_user = td_->user_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return send_error_raw(id, r_input_user.error().code(), r_input_user.error().message()); + } + + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_call_id_object()); + } + }); + send_closure(G()->call_manager(), &CallManager::create_call, user_id, r_input_user.move_as_ok(), + CallProtocol(*request.protocol_), request.is_video_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::acceptCall &request) { + CHECK_IS_USER(); + if (request.protocol_ == nullptr) { + return send_error_raw(id, 400, "Call protocol must be non-empty"); + } + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->call_manager(), &CallManager::accept_call, CallId(request.call_id_), + CallProtocol(*request.protocol_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendCallSignalingData &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->call_manager(), &CallManager::send_call_signaling_data, CallId(request.call_id_), + std::move(request.data_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::discardCall &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->call_manager(), &CallManager::discard_call, CallId(request.call_id_), request.is_disconnected_, + request.duration_, request.is_video_, request.connection_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendCallRating &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.comment_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->call_manager(), &CallManager::rate_call, CallId(request.call_id_), request.rating_, + std::move(request.comment_), std::move(request.problems_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendCallDebugInformation &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.debug_information_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->call_manager(), &CallManager::send_call_debug_information, CallId(request.call_id_), + std::move(request.debug_information_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendCallLog &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->call_manager(), &CallManager::send_call_log, CallId(request.call_id_), std::move(request.log_file_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getVideoChatAvailableParticipants &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->group_call_manager_->get_group_call_join_as(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setVideoChatDefaultParticipant &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, default_join_as_dialog_id, + get_message_sender_dialog_id(td_, request.default_participant_id_, true, false)); + td_->group_call_manager_->set_group_call_default_join_as(DialogId(request.chat_id_), default_join_as_dialog_id, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createVideoChat &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.title_); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.ok().get())); + } + }); + td_->group_call_manager_->create_voice_chat(DialogId(request.chat_id_), std::move(request.title_), + request.start_date_, request.is_rtmp_stream_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::getVideoChatRtmpUrl &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->group_call_manager_->get_voice_chat_rtmp_stream_url(DialogId(request.chat_id_), false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::replaceVideoChatRtmpUrl &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->group_call_manager_->get_voice_chat_rtmp_stream_url(DialogId(request.chat_id_), true, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getGroupCall &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->group_call_manager_->get_group_call(GroupCallId(request.group_call_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::startScheduledGroupCall &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->start_scheduled_group_call(GroupCallId(request.group_call_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleGroupCallEnabledStartNotification &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->toggle_group_call_start_subscribed(GroupCallId(request.group_call_id_), + request.enabled_start_notification_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::joinGroupCall &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_hash_); + CLEAN_INPUT_STRING(request.payload_); + CREATE_TEXT_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, join_as_dialog_id, + get_message_sender_dialog_id(td_, request.participant_id_, true, true)); + td_->group_call_manager_->join_group_call(GroupCallId(request.group_call_id_), join_as_dialog_id, + request.audio_source_id_, std::move(request.payload_), request.is_muted_, + request.is_my_video_enabled_, request.invite_hash_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::startGroupCallScreenSharing &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.payload_); + CREATE_TEXT_REQUEST_PROMISE(); + td_->group_call_manager_->start_group_call_screen_sharing( + GroupCallId(request.group_call_id_), request.audio_source_id_, std::move(request.payload_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleGroupCallScreenSharingIsPaused &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->toggle_group_call_is_my_presentation_paused(GroupCallId(request.group_call_id_), + request.is_paused_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::endGroupCallScreenSharing &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->end_group_call_screen_sharing(GroupCallId(request.group_call_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setGroupCallTitle &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.title_); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->set_group_call_title(GroupCallId(request.group_call_id_), std::move(request.title_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleGroupCallMuteNewParticipants &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->toggle_group_call_mute_new_participants(GroupCallId(request.group_call_id_), + request.mute_new_participants_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::revokeGroupCallInviteLink &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->revoke_group_call_invite_link(GroupCallId(request.group_call_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::inviteGroupCallParticipants &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->invite_group_call_participants(GroupCallId(request.group_call_id_), + UserId::get_user_ids(request.user_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getGroupCallInviteLink &request) { + CHECK_IS_USER(); + CREATE_HTTP_URL_REQUEST_PROMISE(); + td_->group_call_manager_->get_group_call_invite_link(GroupCallId(request.group_call_id_), request.can_self_unmute_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::startGroupCallRecording &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.title_); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->toggle_group_call_recording(GroupCallId(request.group_call_id_), true, + std::move(request.title_), request.record_video_, + request.use_portrait_orientation_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::endGroupCallRecording &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->toggle_group_call_recording(GroupCallId(request.group_call_id_), false, string(), false, + false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoPaused &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->toggle_group_call_is_my_video_paused(GroupCallId(request.group_call_id_), + request.is_my_video_paused_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoEnabled &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->toggle_group_call_is_my_video_enabled(GroupCallId(request.group_call_id_), + request.is_my_video_enabled_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->set_group_call_participant_is_speaking( + GroupCallId(request.group_call_id_), request.audio_source_, request.is_speaking_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, participant_dialog_id, + get_message_sender_dialog_id(td_, request.participant_id_, true, false)); + td_->group_call_manager_->toggle_group_call_participant_is_muted( + GroupCallId(request.group_call_id_), participant_dialog_id, request.is_muted_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setGroupCallParticipantVolumeLevel &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, participant_dialog_id, + get_message_sender_dialog_id(td_, request.participant_id_, true, false)); + td_->group_call_manager_->set_group_call_participant_volume_level( + GroupCallId(request.group_call_id_), participant_dialog_id, request.volume_level_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleGroupCallParticipantIsHandRaised &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, participant_dialog_id, + get_message_sender_dialog_id(td_, request.participant_id_, true, false)); + td_->group_call_manager_->toggle_group_call_participant_is_hand_raised( + GroupCallId(request.group_call_id_), participant_dialog_id, request.is_hand_raised_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::loadGroupCallParticipants &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->load_group_call_participants(GroupCallId(request.group_call_id_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::leaveGroupCall &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->leave_group_call(GroupCallId(request.group_call_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::endGroupCall &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->group_call_manager_->discard_group_call(GroupCallId(request.group_call_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getGroupCallStreams &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->group_call_manager_->get_group_call_streams(GroupCallId(request.group_call_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getGroupCallStreamSegment &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + auto file_part = td_api::make_object(); + file_part->data_ = result.move_as_ok(); + promise.set_value(std::move(file_part)); + } + }); + td_->group_call_manager_->get_group_call_stream_segment(GroupCallId(request.group_call_id_), request.time_offset_, + request.scale_, request.channel_id_, + std::move(request.video_quality_), std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_manager_->migrate_dialog_to_megagroup(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatListsToAddChat &request) { + CHECK_IS_USER(); + auto dialog_lists = td_->messages_manager_->get_dialog_lists_to_add_dialog(DialogId(request.chat_id_)); + auto chat_lists = + transform(dialog_lists, [](DialogListId dialog_list_id) { return dialog_list_id.get_chat_list_object(); }); + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(std::move(chat_lists))); +} + +void Requests::on_request(uint64 id, const td_api::addChatToList &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->add_dialog_to_list(DialogId(request.chat_id_), DialogListId(request.chat_list_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatFolder &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->get_dialog_filter(DialogFilterId(request.chat_folder_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getRecommendedChatFolders &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->get_recommended_dialog_filters(std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createChatFolder &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->create_dialog_filter(std::move(request.folder_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editChatFolder &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->edit_dialog_filter(DialogFilterId(request.chat_folder_id_), std::move(request.folder_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteChatFolder &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_filter_manager_->delete_dialog_filter( + DialogFilterId(request.chat_folder_id_), DialogId::get_dialog_ids(request.leave_chat_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatFolderChatsToLeave &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->get_leave_dialog_filter_suggestions(DialogFilterId(request.chat_folder_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getChatFolderChatCount &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.move_as_ok())); + } + }); + td_->messages_manager_->get_dialog_filter_dialog_count(std::move(request.folder_), std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::reorderChatFolders &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_filter_manager_->reorder_dialog_filters( + transform(request.chat_folder_ids_, [](int32 id) { return DialogFilterId(id); }), + request.main_chat_list_position_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleChatFolderTags &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_filter_manager_->toggle_dialog_filter_tags(request.are_tags_enabled_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatsForChatFolderInviteLink &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->get_dialogs_for_dialog_filter_invite_link(DialogFilterId(request.chat_folder_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createChatFolderInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->create_dialog_filter_invite_link( + DialogFilterId(request.chat_folder_id_), std::move(request.name_), DialogId::get_dialog_ids(request.chat_ids_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getChatFolderInviteLinks &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->get_dialog_filter_invite_links(DialogFilterId(request.chat_folder_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editChatFolderInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->edit_dialog_filter_invite_link( + DialogFilterId(request.chat_folder_id_), std::move(request.invite_link_), std::move(request.name_), + DialogId::get_dialog_ids(request.chat_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::deleteChatFolderInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_filter_manager_->delete_dialog_filter_invite_link(DialogFilterId(request.chat_folder_id_), + std::move(request.invite_link_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::checkChatFolderInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->check_dialog_filter_invite_link(std::move(request.invite_link_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::addChatFolderByInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_filter_manager_->add_dialog_filter_by_invite_link( + std::move(request.invite_link_), DialogId::get_dialog_ids(request.chat_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatFolderNewChats &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_filter_manager_->get_dialog_filter_new_chats(DialogFilterId(request.chat_folder_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::processChatFolderNewChats &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_filter_manager_->add_dialog_filter_new_chats( + DialogFilterId(request.chat_folder_id_), DialogId::get_dialog_ids(request.added_chat_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getArchiveChatListSettings &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = + PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_archive_chat_list_settings_object()); + } + }); + GlobalPrivacySettings::get_global_privacy_settings(td_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::setArchiveChatListSettings &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + GlobalPrivacySettings::set_global_privacy_settings(td_, GlobalPrivacySettings(std::move(request.settings_)), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getReadDatePrivacySettings &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = + PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_read_date_privacy_settings_object()); + } + }); + GlobalPrivacySettings::get_global_privacy_settings(td_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::setReadDatePrivacySettings &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + GlobalPrivacySettings::set_global_privacy_settings(td_, GlobalPrivacySettings(std::move(request.settings_)), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getNewChatPrivacySettings &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = + PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_new_chat_privacy_settings_object()); + } + }); + GlobalPrivacySettings::get_global_privacy_settings(td_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::setNewChatPrivacySettings &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + GlobalPrivacySettings::set_global_privacy_settings(td_, GlobalPrivacySettings(std::move(request.settings_)), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::canSendMessageToUser &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->user_manager_->can_send_message_to_user(UserId(request.user_id_), request.only_local_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatTitle &request) { + CLEAN_INPUT_STRING(request.title_); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->set_dialog_title(DialogId(request.chat_id_), request.title_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatPhoto &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->set_dialog_photo(DialogId(request.chat_id_), request.photo_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatAccentColor &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->set_dialog_accent_color(DialogId(request.chat_id_), AccentColorId(request.accent_color_id_), + CustomEmojiId(request.background_custom_emoji_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatProfileAccentColor &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->set_dialog_profile_accent_color( + DialogId(request.chat_id_), AccentColorId(request.profile_accent_color_id_), + CustomEmojiId(request.profile_background_custom_emoji_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatMessageAutoDeleteTime &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->set_dialog_message_ttl(DialogId(request.chat_id_), request.message_auto_delete_time_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatEmojiStatus &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->set_dialog_emoji_status(DialogId(request.chat_id_), EmojiStatus(request.emoji_status_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatPermissions &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->set_dialog_permissions(DialogId(request.chat_id_), request.permissions_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatBackground &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->background_manager_->set_dialog_background(DialogId(request.chat_id_), request.background_.get(), + request.type_.get(), request.dark_theme_dimming_, + !request.only_for_self_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteChatBackground &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->background_manager_->delete_dialog_background(DialogId(request.chat_id_), request.restore_previous_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatTheme &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.theme_name_); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->set_dialog_theme(DialogId(request.chat_id_), request.theme_name_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatDraftMessage &request) { + CHECK_IS_USER(); + answer_ok_query( + id, td_->messages_manager_->set_dialog_draft_message( + DialogId(request.chat_id_), MessageId(request.message_thread_id_), std::move(request.draft_message_))); +} + +void Requests::on_request(uint64 id, const td_api::toggleChatHasProtectedContent &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->toggle_dialog_has_protected_content(DialogId(request.chat_id_), request.has_protected_content_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleChatIsPinned &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->toggle_dialog_is_pinned(DialogListId(request.chat_list_), + DialogId(request.chat_id_), request.is_pinned_)); +} + +void Requests::on_request(uint64 id, const td_api::toggleChatViewAsTopics &request) { + CHECK_IS_USER(); + answer_ok_query( + id, td_->messages_manager_->toggle_dialog_view_as_messages(DialogId(request.chat_id_), !request.view_as_topics_)); +} + +void Requests::on_request(uint64 id, const td_api::toggleChatIsTranslatable &request) { + CHECK_IS_USER(); + answer_ok_query( + id, td_->messages_manager_->toggle_dialog_is_translatable(DialogId(request.chat_id_), request.is_translatable_)); +} + +void Requests::on_request(uint64 id, const td_api::toggleChatIsMarkedAsUnread &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->toggle_dialog_is_marked_as_unread(DialogId(request.chat_id_), + request.is_marked_as_unread_)); +} + +void Requests::on_request(uint64 id, const td_api::setMessageSenderBlockList &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->set_message_sender_block_list(request.sender_id_, request.block_list_)); +} + +void Requests::on_request(uint64 id, const td_api::toggleChatDefaultDisableNotification &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->toggle_dialog_silent_send_message(DialogId(request.chat_id_), + request.default_disable_notification_)); +} + +void Requests::on_request(uint64 id, const td_api::setPinnedChats &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->set_pinned_dialogs(DialogListId(request.chat_list_), + DialogId::get_dialog_ids(request.chat_ids_))); +} + +void Requests::on_request(uint64 id, const td_api::readChatList &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->read_all_dialogs_from_list(DialogListId(request.chat_list_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStoryNotificationSettingsExceptions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->notification_settings_manager_->get_story_notification_settings_exceptions(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatActiveStories &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->get_dialog_expiring_stories(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatPostedToChatPageStories &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->get_dialog_pinned_stories(DialogId(request.chat_id_), StoryId(request.from_story_id_), + request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatArchivedStories &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->get_story_archive(DialogId(request.chat_id_), StoryId(request.from_story_id_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatPinnedStories &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->set_pinned_stories(DialogId(request.chat_id_), StoryId::get_story_ids(request.story_ids_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::openStory &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->open_story(DialogId(request.story_sender_chat_id_), StoryId(request.story_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::closeStory &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->close_story(DialogId(request.story_sender_chat_id_), StoryId(request.story_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStoryAvailableReactions &request) { + CHECK_IS_USER(); + send_closure(td_actor_, &Td::send_result, id, td_->reaction_manager_->get_available_reactions(request.row_size_)); +} + +void Requests::on_request(uint64 id, const td_api::setStoryReaction &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->set_story_reaction({DialogId(request.story_sender_chat_id_), StoryId(request.story_id_)}, + ReactionType(request.reaction_type_), request.update_recent_reactions_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getStoryInteractions &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->get_story_interactions(StoryId(request.story_id_), request.query_, request.only_contacts_, + request.prefer_forwards_, request.prefer_with_reaction_, request.offset_, + request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getChatStoryInteractions &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->story_manager_->get_dialog_story_interactions( + {DialogId(request.story_sender_chat_id_), StoryId(request.story_id_)}, ReactionType(request.reaction_type_), + request.prefer_forwards_, request.offset_, request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::reportStory &request) { + CHECK_IS_USER(); + auto r_report_reason = ReportReason::get_report_reason(std::move(request.reason_), std::move(request.text_)); + if (r_report_reason.is_error()) { + return send_error_raw(id, r_report_reason.error().code(), r_report_reason.error().message()); + } + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->report_story({DialogId(request.story_sender_chat_id_), StoryId(request.story_id_)}, + r_report_reason.move_as_ok(), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::activateStoryStealthMode &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->story_manager_->activate_stealth_mode(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatBoostLevelFeatures &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + promise.set_value(td_->boost_manager_->get_chat_boost_level_features_object(!request.is_channel_, request.level_)); +} + +void Requests::on_request(uint64 id, const td_api::getChatBoostFeatures &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + promise.set_value(td_->boost_manager_->get_chat_boost_features_object(!request.is_channel_)); +} + +void Requests::on_request(uint64 id, const td_api::getAvailableChatBoostSlots &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->boost_manager_->get_boost_slots(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatBoostStatus &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->boost_manager_->get_dialog_boost_status(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::boostChat &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->boost_manager_->boost_dialog(DialogId(request.chat_id_), std::move(request.slot_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatBoostLink &request) { + auto r_boost_link = td_->boost_manager_->get_dialog_boost_link(DialogId(request.chat_id_)); + if (r_boost_link.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_boost_link.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, + td_api::make_object(r_boost_link.ok().first, r_boost_link.ok().second)); + } +} + +void Requests::on_request(uint64 id, td_api::getChatBoostLinkInfo &request) { + CLEAN_INPUT_STRING(request.url_); + CREATE_REQUEST(GetDialogBoostLinkInfoRequest, std::move(request.url_)); +} + +void Requests::on_request(uint64 id, td_api::getChatBoosts &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->boost_manager_->get_dialog_boosts(DialogId(request.chat_id_), request.only_gift_codes_, request.offset_, + request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getUserChatBoosts &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + td_->boost_manager_->get_user_dialog_boosts(DialogId(request.chat_id_), UserId(request.user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getAttachmentMenuBot &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->attach_menu_manager_->get_attach_menu_bot(UserId(request.bot_user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleBotIsAddedToAttachmentMenu &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->attach_menu_manager_->toggle_bot_is_added_to_attach_menu(UserId(request.bot_user_id_), request.is_added_, + request.allow_write_access_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatAvailableReactions &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->set_dialog_available_reactions(DialogId(request.chat_id_), + std::move(request.available_reactions_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatClientData &request) { + answer_ok_query( + id, td_->messages_manager_->set_dialog_client_data(DialogId(request.chat_id_), std::move(request.client_data_))); +} + +void Requests::on_request(uint64 id, td_api::setChatDescription &request) { + CLEAN_INPUT_STRING(request.description_); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->set_dialog_description(DialogId(request.chat_id_), request.description_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatDiscussionGroup &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->set_channel_discussion_group(DialogId(request.chat_id_), DialogId(request.discussion_chat_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatLocation &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->set_dialog_location(DialogId(request.chat_id_), DialogLocation(std::move(request.location_)), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setChatSlowModeDelay &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->set_channel_slow_mode_delay(DialogId(request.chat_id_), request.slow_mode_delay_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::pinChatMessage &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->pin_dialog_message(BusinessConnectionId(), DialogId(request.chat_id_), + MessageId(request.message_id_), request.disable_notification_, + request.only_for_self_, false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::unpinChatMessage &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->pin_dialog_message(BusinessConnectionId(), DialogId(request.chat_id_), + MessageId(request.message_id_), false, false, true, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::unpinAllChatMessages &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->unpin_all_dialog_messages(DialogId(request.chat_id_), MessageId(), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::unpinAllMessageThreadMessages &request) { + if (request.message_thread_id_ == 0) { + return send_error_raw(id, 400, "Invalid message thread identifier specified"); + } + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->unpin_all_dialog_messages(DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::joinChat &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_participant_manager_->add_dialog_participant( + DialogId(request.chat_id_), td_->user_manager_->get_my_id(), 0, + DialogParticipantManager::wrap_failed_to_add_members_promise(std::move(promise))); +} + +void Requests::on_request(uint64 id, const td_api::leaveChat &request) { + CREATE_OK_REQUEST_PROMISE(); + DialogId dialog_id(request.chat_id_); + td_api::object_ptr new_status = td_api::make_object(); + if (dialog_id.get_type() == DialogType::Channel && td_->dialog_manager_->have_dialog_force(dialog_id, "leaveChat")) { + auto status = td_->chat_manager_->get_channel_status(dialog_id.get_channel_id()); + if (status.is_creator()) { + if (!status.is_member()) { + return promise.set_value(Unit()); + } + + new_status = + td_api::make_object(status.get_rank(), status.is_anonymous(), false); + } + } + td_->dialog_participant_manager_->set_dialog_participant_status(dialog_id, td_->dialog_manager_->get_my_dialog_id(), + std::move(new_status), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::addChatMember &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_participant_manager_->add_dialog_participant(DialogId(request.chat_id_), UserId(request.user_id_), + request.forward_limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::addChatMembers &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_participant_manager_->add_dialog_participants( + DialogId(request.chat_id_), UserId::get_user_ids(request.user_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatMemberStatus &request) { + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, participant_dialog_id, + get_message_sender_dialog_id(td_, request.member_id_, false, false)); + td_->dialog_participant_manager_->set_dialog_participant_status(DialogId(request.chat_id_), participant_dialog_id, + std::move(request.status_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::banChatMember &request) { + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, participant_dialog_id, + get_message_sender_dialog_id(td_, request.member_id_, false, false)); + td_->dialog_participant_manager_->ban_dialog_participant(DialogId(request.chat_id_), participant_dialog_id, + request.banned_until_date_, request.revoke_messages_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::canTransferOwnership &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda( + [promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(DialogParticipantManager::get_can_transfer_ownership_result_object(result.ok())); + } + }); + td_->dialog_participant_manager_->can_transfer_ownership(std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::transferChatOwnership &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_participant_manager_->transfer_dialog_ownership(DialogId(request.chat_id_), UserId(request.user_id_), + request.password_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatMember &request) { + CREATE_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, participant_dialog_id, + get_message_sender_dialog_id(td_, request.member_id_, false, false)); + td_->dialog_participant_manager_->get_dialog_participant(DialogId(request.chat_id_), participant_dialog_id, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchChatMembers &request) { + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST_PROMISE(); + auto query_promise = + PromiseCreator::lambda([promise = std::move(promise), td = td_](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_chat_members_object(td, "searchChatMembers")); + } + }); + td_->dialog_participant_manager_->search_dialog_participants(DialogId(request.chat_id_), request.query_, + request.limit_, DialogParticipantFilter(request.filter_), + std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatAdministrators &request) { + CREATE_REQUEST_PROMISE(); + td_->dialog_participant_manager_->get_dialog_administrators(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::replacePrimaryChatInviteLink &request) { + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->export_dialog_invite_link( + DialogId(request.chat_id_), string(), 0, 0, false, StarSubscriptionPricing(), false, true, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createChatInviteLink &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->export_dialog_invite_link( + DialogId(request.chat_id_), std::move(request.name_), request.expiration_date_, request.member_limit_, + request.creates_join_request_, StarSubscriptionPricing(), false, false, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createChatSubscriptionInviteLink &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->export_dialog_invite_link( + DialogId(request.chat_id_), std::move(request.name_), 0, 0, false, + StarSubscriptionPricing(std::move(request.subscription_pricing_)), true, false, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editChatInviteLink &request) { + CLEAN_INPUT_STRING(request.name_); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->edit_dialog_invite_link( + DialogId(request.chat_id_), request.invite_link_, std::move(request.name_), request.expiration_date_, + request.member_limit_, request.creates_join_request_, false, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editChatSubscriptionInviteLink &request) { + CLEAN_INPUT_STRING(request.name_); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->edit_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, + std::move(request.name_), 0, 0, false, true, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getChatInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->get_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatInviteLinkCounts &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->get_dialog_invite_link_counts(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getChatInviteLinks &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_invite_link_); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->get_dialog_invite_links( + DialogId(request.chat_id_), UserId(request.creator_user_id_), request.is_revoked_, request.offset_date_, + request.offset_invite_link_, request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getChatInviteLinkMembers &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->get_dialog_invite_link_users( + DialogId(request.chat_id_), request.invite_link_, request.only_with_expired_subscription_, + std::move(request.offset_member_), request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getChatJoinRequests &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST_PROMISE(); + td_->dialog_participant_manager_->get_dialog_join_requests(DialogId(request.chat_id_), request.invite_link_, + request.query_, std::move(request.offset_request_), + request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::processChatJoinRequest &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_participant_manager_->process_dialog_join_request(DialogId(request.chat_id_), UserId(request.user_id_), + request.approve_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::processChatJoinRequests &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_participant_manager_->process_dialog_join_requests(DialogId(request.chat_id_), request.invite_link_, + request.approve_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::revokeChatInviteLink &request) { + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->revoke_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::deleteRevokedChatInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->delete_revoked_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteAllRevokedChatInviteLinks &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_invite_link_manager_->delete_all_revoked_dialog_invite_links( + DialogId(request.chat_id_), UserId(request.creator_user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::checkChatInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST(CheckChatInviteLinkRequest, request.invite_link_); +} + +void Requests::on_request(uint64 id, td_api::joinChatByInviteLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.invite_link_); + CREATE_REQUEST(JoinChatByInviteLinkRequest, request.invite_link_); +} + +void Requests::on_request(uint64 id, td_api::getChatEventLog &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST_PROMISE(); + get_dialog_event_log(td_, DialogId(request.chat_id_), std::move(request.query_), request.from_event_id_, + request.limit_, std::move(request.filters_), UserId::get_user_ids(request.user_ids_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getTimeZones &request) { + CREATE_REQUEST_PROMISE(); + td_->time_zone_manager_->get_time_zones(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::clearAllDraftMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->clear_all_draft_messages(request.exclude_secret_chats_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::downloadFile &request) { + auto priority = request.priority_; + if (!(1 <= priority && priority <= 32)) { + return send_error_raw(id, 400, "Download priority must be between 1 and 32"); + } + auto offset = request.offset_; + if (offset < 0) { + return send_error_raw(id, 400, "Download offset must be non-negative"); + } + auto limit = request.limit_; + if (limit < 0) { + return send_error_raw(id, 400, "Download limit must be non-negative"); + } + + FileId file_id(request.file_id_, 0); + auto file_view = td_->file_manager_->get_file_view(file_id); + if (file_view.empty()) { + return send_error_raw(id, 400, "Invalid file identifier"); + } + + auto info_it = pending_file_downloads_.find(file_id); + DownloadInfo *info = info_it == pending_file_downloads_.end() ? nullptr : &info_it->second; + if (info != nullptr && (offset != info->offset || limit != info->limit)) { + // we can't have two pending requests with different offset and limit, so cancel all previous requests + auto request_ids = std::move(info->request_ids); + info->request_ids.clear(); + for (auto request_id : request_ids) { + send_closure(td_actor_, &Td::send_error, request_id, + Status::Error(200, "Canceled by another downloadFile request")); + } + } + if (request.synchronous_) { + if (info == nullptr) { + info = &pending_file_downloads_[file_id]; + } + info->offset = offset; + info->limit = limit; + info->request_ids.push_back(id); + } + Promise> download_promise; + if (!request.synchronous_) { + CREATE_REQUEST_PROMISE(); + download_promise = std::move(promise); + } + td_->file_manager_->download(file_id, download_file_callback_, priority, offset, limit, std::move(download_promise)); +} + +void Requests::on_file_download_finished(FileId file_id) { + auto it = pending_file_downloads_.find(file_id); + if (it == pending_file_downloads_.end()) { + return; + } + for (auto id : it->second.request_ids) { + // there was send_closure to call td_ function + auto file_object = td_->file_manager_->get_file_object(file_id, false); + CHECK(file_object != nullptr); + auto download_offset = file_object->local_->download_offset_; + auto downloaded_size = file_object->local_->downloaded_prefix_size_; + auto file_size = file_object->size_; + auto limit = it->second.limit; + if (limit == 0) { + limit = std::numeric_limits::max(); + } + if (file_object->local_->is_downloading_completed_ || + (download_offset <= it->second.offset && download_offset + downloaded_size >= it->second.offset && + ((file_size != 0 && download_offset + downloaded_size == file_size) || + download_offset + downloaded_size - it->second.offset >= limit))) { + td_->send_result(id, std::move(file_object)); + } else { + td_->send_error_impl(id, td_api::make_object(400, "File download has failed or was canceled")); + } + } + pending_file_downloads_.erase(it); +} + +void Requests::on_request(uint64 id, const td_api::getFileDownloadedPrefixSize &request) { + if (request.offset_ < 0) { + return send_error_raw(id, 400, "Parameter offset must be non-negative"); + } + auto file_view = td_->file_manager_->get_file_view(FileId(request.file_id_, 0)); + if (file_view.empty()) { + return send_closure(td_actor_, &Td::send_error, id, Status::Error(400, "Unknown file ID")); + } + send_closure(td_actor_, &Td::send_result, id, + td_api::make_object(file_view.downloaded_prefix(request.offset_))); +} + +void Requests::on_request(uint64 id, const td_api::cancelDownloadFile &request) { + td_->file_manager_->download(FileId(request.file_id_, 0), nullptr, request.only_if_pending_ ? -1 : 0, + FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::KEEP_DOWNLOAD_LIMIT, + Promise>()); + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); +} + +void Requests::on_request(uint64 id, const td_api::getSuggestedFileName &request) { + Result r_file_name = + td_->file_manager_->get_suggested_file_name(FileId(request.file_id_, 0), request.directory_); + if (r_file_name.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_file_name.move_as_error()); + } + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(r_file_name.ok())); +} + +void Requests::on_request(uint64 id, const td_api::preliminaryUploadFile &request) { + CREATE_REQUEST_PROMISE(); + auto file_type = request.file_type_ == nullptr ? FileType::Temp : get_file_type(*request.file_type_); + td_->file_manager_->preliminary_upload_file(request.file_, file_type, request.priority_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::cancelPreliminaryUploadFile &request) { + td_->file_manager_->cancel_upload(FileId(request.file_id_, 0)); + + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); +} + +void Requests::on_request(uint64 id, td_api::writeGeneratedFilePart &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->file_manager_actor_, &FileManager::external_file_generate_write_part, request.generation_id_, + request.offset_, std::move(request.data_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setFileGenerationProgress &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->file_manager_actor_, &FileManager::external_file_generate_progress, request.generation_id_, + request.expected_size_, request.local_prefix_size_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::finishFileGeneration &request) { + Status status; + if (request.error_ != nullptr) { + CLEAN_INPUT_STRING(request.error_->message_); + status = Status::Error(request.error_->code_, request.error_->message_); + } + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->file_manager_actor_, &FileManager::external_file_generate_finish, request.generation_id_, + std::move(status), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::readFilePart &request) { + CREATE_REQUEST_PROMISE(); + send_closure(td_->file_manager_actor_, &FileManager::read_file_part, FileId(request.file_id_, 0), request.offset_, + request.count_, 2, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteFile &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->file_manager_actor_, &FileManager::delete_file, FileId(request.file_id_, 0), std::move(promise), + "td_api::deleteFile"); +} + +void Requests::on_request(uint64 id, const td_api::addFileToDownloads &request) { + if (!(1 <= request.priority_ && request.priority_ <= 32)) { + return send_error_raw(id, 400, "Download priority must be between 1 and 32"); + } + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->add_message_file_to_downloads( + MessageFullId(DialogId(request.chat_id_), MessageId(request.message_id_)), FileId(request.file_id_, 0), + request.priority_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleDownloadIsPaused &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->download_manager_actor_, &DownloadManager::toggle_is_paused, FileId(request.file_id_, 0), + request.is_paused_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleAllDownloadsArePaused &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->download_manager_actor_, &DownloadManager::toggle_all_is_paused, request.are_paused_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeFileFromDownloads &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->download_manager_actor_, &DownloadManager::remove_file, FileId(request.file_id_, 0), FileSourceId(), + request.delete_from_cache_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeAllFilesFromDownloads &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->download_manager_actor_, &DownloadManager::remove_all_files, request.only_active_, + request.only_completed_, request.delete_from_cache_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchFileDownloads &request) { + CLEAN_INPUT_STRING(request.query_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->download_manager_actor_, &DownloadManager::search, std::move(request.query_), request.only_active_, + request.only_completed_, std::move(request.offset_), request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setApplicationVerificationToken &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.token_); + CREATE_OK_REQUEST_PROMISE(); + G()->net_query_dispatcher().set_verification_token(request.verification_id_, std::move(request.token_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getMessageFileType &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.message_file_head_); + CREATE_REQUEST_PROMISE(); + td_->message_import_manager_->get_message_file_type(request.message_file_head_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMessageImportConfirmationText &request) { + CHECK_IS_USER(); + CREATE_TEXT_REQUEST_PROMISE(); + td_->message_import_manager_->get_message_import_confirmation_text(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::importMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->message_import_manager_->import_messages(DialogId(request.chat_id_), request.message_file_, + request.attached_files_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::blockMessageSenderFromReplies &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->block_message_sender_from_replies(MessageId(request.message_id_), request.delete_message_, + request.delete_all_messages_, request.report_spam_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBlockedMessageSenders &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_blocked_dialogs(request.block_list_, request.offset_, request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::addContact &request) { + CHECK_IS_USER(); + auto r_contact = get_contact(td_, std::move(request.contact_)); + if (r_contact.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_contact.move_as_error()); + } + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->add_contact(r_contact.move_as_ok(), request.share_phone_number_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::importContacts &request) { + CHECK_IS_USER(); + vector contacts; + contacts.reserve(request.contacts_.size()); + for (auto &contact : request.contacts_) { + auto r_contact = get_contact(td_, std::move(contact)); + if (r_contact.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_contact.move_as_error()); + } + contacts.push_back(r_contact.move_as_ok()); + } + CREATE_REQUEST(ImportContactsRequest, std::move(contacts)); +} + +void Requests::on_request(uint64 id, const td_api::getContacts &request) { + CHECK_IS_USER(); + CREATE_REQUEST(SearchContactsRequest, string(), 1000000); +} + +void Requests::on_request(uint64 id, td_api::searchContacts &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchContactsRequest, request.query_, request.limit_); +} + +void Requests::on_request(uint64 id, td_api::removeContacts &request) { + CHECK_IS_USER(); + CREATE_REQUEST(RemoveContactsRequest, UserId::get_user_ids(request.user_ids_)); +} + +void Requests::on_request(uint64 id, const td_api::getImportedContactCount &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetImportedContactCountRequest); +} + +void Requests::on_request(uint64 id, td_api::changeImportedContacts &request) { + CHECK_IS_USER(); + vector contacts; + contacts.reserve(request.contacts_.size()); + for (auto &contact : request.contacts_) { + auto r_contact = get_contact(td_, std::move(contact)); + if (r_contact.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_contact.move_as_error()); + } + contacts.push_back(r_contact.move_as_ok()); + } + CREATE_REQUEST(ChangeImportedContactsRequest, std::move(contacts)); +} + +void Requests::on_request(uint64 id, const td_api::clearImportedContacts &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->clear_imported_contacts(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getCloseFriends &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetCloseFriendsRequest); +} + +void Requests::on_request(uint64 id, const td_api::setCloseFriends &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_close_friends(UserId::get_user_ids(request.user_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setUserPersonalProfilePhoto &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_user_profile_photo(UserId(request.user_id_), request.photo_, false, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::suggestUserProfilePhoto &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_user_profile_photo(UserId(request.user_id_), request.photo_, true, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchUserByPhoneNumber &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.phone_number_); + CREATE_REQUEST(SearchUserByPhoneNumberRequest, std::move(request.phone_number_), request.only_local_); +} + +void Requests::on_request(uint64 id, const td_api::sharePhoneNumber &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->share_phone_number(UserId(request.user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getRecentInlineBots &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetRecentInlineBotsRequest); +} + +void Requests::on_request(uint64 id, td_api::setName &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.first_name_); + CLEAN_INPUT_STRING(request.last_name_); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_name(request.first_name_, request.last_name_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBio &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.bio_); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_bio(request.bio_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setUsername &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.username_); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_username(request.username_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::toggleUsernameIsActive &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.username_); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->toggle_username_is_active(std::move(request.username_), request.is_active_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::reorderActiveUsernames &request) { + CHECK_IS_USER(); + for (auto &username : request.usernames_) { + CLEAN_INPUT_STRING(username); + } + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->reorder_usernames(std::move(request.usernames_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBirthdate &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_birthdate(Birthdate(std::move(request.birthdate_)), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setPersonalChat &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_personal_channel(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setEmojiStatus &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_emoji_status(EmojiStatus(request.emoji_status_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleHasSponsoredMessagesEnabled &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->toggle_sponsored_messages(request.has_sponsored_messages_enabled_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getThemedEmojiStatuses &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_default_emoji_statuses(false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getThemedChatEmojiStatuses &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_default_channel_emoji_statuses(false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getDefaultEmojiStatuses &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_default_emoji_statuses(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getDefaultChatEmojiStatuses &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_default_channel_emoji_statuses(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getRecentEmojiStatuses &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_recent_emoji_statuses(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::clearRecentEmojiStatuses &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + clear_recent_emoji_statuses(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setCommands &request) { + CHECK_IS_BOT(); + CREATE_OK_REQUEST_PROMISE(); + set_commands(td_, std::move(request.scope_), std::move(request.language_code_), std::move(request.commands_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::deleteCommands &request) { + CHECK_IS_BOT(); + CREATE_OK_REQUEST_PROMISE(); + delete_commands(td_, std::move(request.scope_), std::move(request.language_code_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getCommands &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + get_commands(td_, std::move(request.scope_), std::move(request.language_code_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setMenuButton &request) { + CHECK_IS_BOT(); + CREATE_OK_REQUEST_PROMISE(); + set_menu_button(td_, UserId(request.user_id_), std::move(request.menu_button_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMenuButton &request) { + CHECK_IS_BOT(); + CREATE_REQUEST_PROMISE(); + get_menu_button(td_, UserId(request.user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setDefaultGroupAdministratorRights &request) { + CHECK_IS_BOT(); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->set_default_group_administrator_rights( + AdministratorRights(request.default_group_administrator_rights_, ChannelType::Megagroup), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setDefaultChannelAdministratorRights &request) { + CHECK_IS_BOT(); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->set_default_channel_administrator_rights( + AdministratorRights(request.default_channel_administrator_rights_, ChannelType::Broadcast), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::canBotSendMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->can_bot_send_messages(UserId(request.bot_user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::allowBotToSendMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->allow_bot_to_send_messages(UserId(request.bot_user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendWebAppCustomRequest &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.method_); + CLEAN_INPUT_STRING(request.parameters_); + CREATE_REQUEST_PROMISE(); + td_->attach_menu_manager_->invoke_web_view_custom_method(UserId(request.bot_user_id_), request.method_, + request.parameters_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBotMediaPreviews &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->bot_info_manager_->get_bot_media_previews(UserId(request.bot_user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBotMediaPreviewInfo &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->bot_info_manager_->get_bot_media_preview_info(UserId(request.bot_user_id_), request.language_code_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::addBotMediaPreview &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->bot_info_manager_->add_bot_media_preview(UserId(request.bot_user_id_), request.language_code_, + std::move(request.content_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editBotMediaPreview &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->bot_info_manager_->edit_bot_media_preview(UserId(request.bot_user_id_), request.language_code_, + FileId(request.file_id_, 0), std::move(request.content_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::reorderBotMediaPreviews &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->reorder_bot_media_previews(UserId(request.bot_user_id_), request.language_code_, + request.file_ids_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteBotMediaPreviews &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->delete_bot_media_previews(UserId(request.bot_user_id_), request.language_code_, + request.file_ids_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBotName &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->set_bot_name(UserId(request.bot_user_id_), request.language_code_, request.name_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBotName &request) { + CREATE_TEXT_REQUEST_PROMISE(); + td_->bot_info_manager_->get_bot_name(UserId(request.bot_user_id_), request.language_code_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBotProfilePhoto &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_bot_profile_photo(UserId(request.bot_user_id_), request.photo_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::toggleBotUsernameIsActive &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.username_); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->toggle_bot_username_is_active(UserId(request.bot_user_id_), std::move(request.username_), + request.is_active_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::reorderBotActiveUsernames &request) { + CHECK_IS_USER(); + for (auto &username : request.usernames_) { + CLEAN_INPUT_STRING(username); + } + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->reorder_bot_usernames(UserId(request.bot_user_id_), std::move(request.usernames_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBotInfoDescription &request) { + CLEAN_INPUT_STRING(request.description_); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->set_bot_info_description(UserId(request.bot_user_id_), request.language_code_, + request.description_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBotInfoDescription &request) { + CREATE_TEXT_REQUEST_PROMISE(); + td_->bot_info_manager_->get_bot_info_description(UserId(request.bot_user_id_), request.language_code_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBotInfoShortDescription &request) { + CLEAN_INPUT_STRING(request.short_description_); + CREATE_OK_REQUEST_PROMISE(); + td_->bot_info_manager_->set_bot_info_about(UserId(request.bot_user_id_), request.language_code_, + request.short_description_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBotInfoShortDescription &request) { + CREATE_TEXT_REQUEST_PROMISE(); + td_->bot_info_manager_->get_bot_info_about(UserId(request.bot_user_id_), request.language_code_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setLocation &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->people_nearby_manager_->set_location(Location(request.location_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBusinessLocation &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->set_business_location(DialogLocation(std::move(request.location_)), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBusinessOpeningHours &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->set_business_work_hours(BusinessWorkHours(std::move(request.opening_hours_)), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBusinessGreetingMessageSettings &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->set_business_greeting_message( + BusinessGreetingMessage(std::move(request.greeting_message_settings_)), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBusinessAwayMessageSettings &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->set_business_away_message(BusinessAwayMessage(std::move(request.away_message_settings_)), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBusinessStartPage &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->set_business_intro(BusinessIntro(td_, std::move(request.start_page_)), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setProfilePhoto &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_profile_photo(request.photo_, request.is_public_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteProfilePhoto &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->delete_profile_photo(request.profile_photo_id_, false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getUserProfilePhotos &request) { + CREATE_REQUEST_PROMISE(); + td_->user_manager_->get_user_profile_photos(UserId(request.user_id_), request.offset_, request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setAccentColor &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_accent_color(AccentColorId(request.accent_color_id_), + CustomEmojiId(request.background_custom_emoji_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setProfileAccentColor &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->user_manager_->set_profile_accent_color(AccentColorId(request.profile_accent_color_id_), + CustomEmojiId(request.profile_background_custom_emoji_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBusinessConnectedBot &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->business_manager_->get_business_connected_bot(std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBusinessConnectedBot &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->set_business_connected_bot(std::move(request.bot_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteBusinessConnectedBot &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->delete_business_connected_bot(UserId(request.bot_user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleBusinessConnectedBotChatIsPaused &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->toggle_business_connected_bot_dialog_is_paused(DialogId(request.chat_id_), request.is_paused_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeBusinessConnectedBotFromChat &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->remove_business_connected_bot_from_dialog(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBusinessChatLinks &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->business_manager_->get_business_chat_links(std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createBusinessChatLink &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->business_manager_->create_business_chat_link(std::move(request.link_info_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editBusinessChatLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.link_); + CREATE_REQUEST_PROMISE(); + td_->business_manager_->edit_business_chat_link(request.link_, std::move(request.link_info_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::deleteBusinessChatLink &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.link_); + CREATE_OK_REQUEST_PROMISE(); + td_->business_manager_->delete_business_chat_link(request.link_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getBusinessChatLinkInfo &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.link_name_); + CREATE_REQUEST_PROMISE(); + td_->business_manager_->get_business_chat_link_info(request.link_name_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setSupergroupUsername &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.username_); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->set_channel_username(ChannelId(request.supergroup_id_), request.username_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::toggleSupergroupUsernameIsActive &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.username_); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_username_is_active(ChannelId(request.supergroup_id_), std::move(request.username_), + request.is_active_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::disableAllSupergroupUsernames &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->disable_all_channel_usernames(ChannelId(request.supergroup_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::reorderSupergroupActiveUsernames &request) { + CHECK_IS_USER(); + for (auto &username : request.usernames_) { + CLEAN_INPUT_STRING(username); + } + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->reorder_channel_usernames(ChannelId(request.supergroup_id_), std::move(request.usernames_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setSupergroupStickerSet &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->set_channel_sticker_set(ChannelId(request.supergroup_id_), StickerSetId(request.sticker_set_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setSupergroupCustomEmojiStickerSet &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->set_channel_emoji_sticker_set( + ChannelId(request.supergroup_id_), StickerSetId(request.custom_emoji_sticker_set_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setSupergroupUnrestrictBoostCount &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->set_channel_unrestrict_boost_count(ChannelId(request.supergroup_id_), + request.unrestrict_boost_count_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupSignMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_sign_messages(ChannelId(request.supergroup_id_), request.sign_messages_, + request.show_message_sender_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupJoinToSendMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_join_to_send(ChannelId(request.supergroup_id_), request.join_to_send_messages_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupJoinByRequest &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_join_request(ChannelId(request.supergroup_id_), request.join_by_request_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupIsAllHistoryAvailable &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_is_all_history_available(ChannelId(request.supergroup_id_), + request.is_all_history_available_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupCanHaveSponsoredMessages &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_can_have_sponsored_messages( + ChannelId(request.supergroup_id_), request.can_have_sponsored_messages_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupHasHiddenMembers &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_has_hidden_participants(ChannelId(request.supergroup_id_), + request.has_hidden_members_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupHasAggressiveAntiSpamEnabled &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_has_aggressive_anti_spam_enabled( + ChannelId(request.supergroup_id_), request.has_aggressive_anti_spam_enabled_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupIsForum &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->toggle_channel_is_forum(ChannelId(request.supergroup_id_), request.is_forum_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::toggleSupergroupIsBroadcastGroup &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->convert_channel_to_gigagroup(ChannelId(request.supergroup_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::reportSupergroupSpam &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->report_channel_spam(ChannelId(request.supergroup_id_), + MessageId::get_message_ids(request.message_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::reportSupergroupAntiSpamFalsePositive &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->chat_manager_->report_channel_anti_spam_false_positive(ChannelId(request.supergroup_id_), + MessageId(request.message_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getSupergroupMembers &request) { + CREATE_REQUEST_PROMISE(); + auto query_promise = + PromiseCreator::lambda([promise = std::move(promise), td = td_](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_chat_members_object(td, "getSupergroupMembers")); + } + }); + td_->dialog_participant_manager_->get_channel_participants(ChannelId(request.supergroup_id_), + std::move(request.filter_), string(), request.offset_, + request.limit_, -1, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::closeSecretChat &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->secret_chats_manager_, &SecretChatsManager::cancel_chat, SecretChatId(request.secret_chat_id_), + false, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getStickers &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(GetStickersRequest, get_sticker_type(request.sticker_type_), std::move(request.query_), request.limit_, + request.chat_id_); +} + +void Requests::on_request(uint64 id, td_api::getAllStickerEmojis &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(GetAllStickerEmojisRequest, get_sticker_type(request.sticker_type_), std::move(request.query_), + request.chat_id_, request.return_only_main_emoji_); +} + +void Requests::on_request(uint64 id, td_api::searchStickers &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.emojis_); + CREATE_REQUEST_PROMISE(); + auto sticker_type = get_sticker_type(request.sticker_type_); + if (sticker_type == StickerType::Regular) { + // legacy + if (request.emojis_ == "⭐️⭐️") { + request.emojis_ = "⭐️"; + } else if (request.emojis_ == "📂⭐️") { + request.emojis_ = "📂"; + } else if (request.emojis_ == "👋⭐️") { + request.emojis_ = "👋"; + } + } + td_->stickers_manager_->search_stickers(sticker_type, std::move(request.emojis_), request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getGreetingStickers &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->search_stickers(StickerType::Regular, "👋⭐️", 100, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getPremiumStickers &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_premium_stickers(request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getInstalledStickerSets &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetInstalledStickerSetsRequest, get_sticker_type(request.sticker_type_)); +} + +void Requests::on_request(uint64 id, const td_api::getArchivedStickerSets &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetArchivedStickerSetsRequest, get_sticker_type(request.sticker_type_), request.offset_sticker_set_id_, + request.limit_); +} + +void Requests::on_request(uint64 id, const td_api::getTrendingStickerSets &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetTrendingStickerSetsRequest, get_sticker_type(request.sticker_type_), request.offset_, + request.limit_); +} + +void Requests::on_request(uint64 id, const td_api::getAttachedStickerSets &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetAttachedStickerSetsRequest, request.file_id_); +} + +void Requests::on_request(uint64 id, const td_api::getStickerSet &request) { + CREATE_REQUEST(GetStickerSetRequest, request.set_id_); +} + +void Requests::on_request(uint64 id, const td_api::getStickerSetName &request) { + CREATE_TEXT_REQUEST_PROMISE(); + td_->stickers_manager_->get_sticker_set_name(StickerSetId(request.set_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchStickerSet &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST(SearchStickerSetRequest, std::move(request.name_)); +} + +void Requests::on_request(uint64 id, td_api::searchInstalledStickerSets &request) { + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchInstalledStickerSetsRequest, get_sticker_type(request.sticker_type_), std::move(request.query_), + request.limit_); +} + +void Requests::on_request(uint64 id, td_api::searchStickerSets &request) { + CLEAN_INPUT_STRING(request.query_); + CREATE_REQUEST(SearchStickerSetsRequest, get_sticker_type(request.sticker_type_), std::move(request.query_)); +} + +void Requests::on_request(uint64 id, const td_api::changeStickerSet &request) { + CHECK_IS_USER(); + CREATE_REQUEST(ChangeStickerSetRequest, request.set_id_, request.is_installed_, request.is_archived_); +} + +void Requests::on_request(uint64 id, const td_api::viewTrendingStickerSets &request) { + CHECK_IS_USER(); + td_->stickers_manager_->view_featured_sticker_sets( + StickersManager::convert_sticker_set_ids(request.sticker_set_ids_)); + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); +} + +void Requests::on_request(uint64 id, td_api::reorderInstalledStickerSets &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->reorder_installed_sticker_sets( + get_sticker_type(request.sticker_type_), StickersManager::convert_sticker_set_ids(request.sticker_set_ids_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::uploadStickerFile &request) { + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->upload_sticker_file(UserId(request.user_id_), get_sticker_format(request.sticker_format_), + std::move(request.sticker_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getSuggestedStickerSetName &request) { + CLEAN_INPUT_STRING(request.title_); + CREATE_TEXT_REQUEST_PROMISE(); + td_->stickers_manager_->get_suggested_sticker_set_name(std::move(request.title_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::checkStickerSetName &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda( + [promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(StickersManager::get_check_sticker_set_name_result_object(result.ok())); + } + }); + td_->stickers_manager_->check_sticker_set_name(request.name_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::createNewStickerSet &request) { + CLEAN_INPUT_STRING(request.title_); + CLEAN_INPUT_STRING(request.name_); + CLEAN_INPUT_STRING(request.source_); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->create_new_sticker_set(UserId(request.user_id_), std::move(request.title_), + std::move(request.name_), get_sticker_type(request.sticker_type_), + request.needs_repainting_, std::move(request.stickers_), + std::move(request.source_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::addStickerToSet &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->add_sticker_to_set(UserId(request.user_id_), std::move(request.name_), + std::move(request.sticker_), nullptr, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::replaceStickerInSet &request) { + CLEAN_INPUT_STRING(request.name_); + if (request.old_sticker_ == nullptr) { + return send_error_raw(id, 400, "Old sticker must be non-empty"); + } + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->add_sticker_to_set(UserId(request.user_id_), std::move(request.name_), + std::move(request.new_sticker_), std::move(request.old_sticker_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setStickerSetThumbnail &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->set_sticker_set_thumbnail(UserId(request.user_id_), std::move(request.name_), + std::move(request.thumbnail_), get_sticker_format(request.format_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setCustomEmojiStickerSetThumbnail &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->set_custom_emoji_sticker_set_thumbnail( + std::move(request.name_), CustomEmojiId(request.custom_emoji_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setStickerSetTitle &request) { + CLEAN_INPUT_STRING(request.name_); + CLEAN_INPUT_STRING(request.title_); + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->set_sticker_set_title(std::move(request.name_), std::move(request.title_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::deleteStickerSet &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->delete_sticker_set(std::move(request.name_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setStickerPositionInSet &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->set_sticker_position_in_set(request.sticker_, request.position_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeStickerFromSet &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->remove_sticker_from_set(request.sticker_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setStickerEmojis &request) { + CLEAN_INPUT_STRING(request.emojis_); + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->set_sticker_emojis(request.sticker_, request.emojis_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setStickerKeywords &request) { + for (auto &keyword : request.keywords_) { + CLEAN_INPUT_STRING(keyword); + } + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->set_sticker_keywords(request.sticker_, std::move(request.keywords_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setStickerMaskPosition &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->stickers_manager_->set_sticker_mask_position(request.sticker_, std::move(request.mask_position_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getOwnedStickerSets &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_created_sticker_sets(StickerSetId(request.offset_sticker_set_id_), request.limit_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getRecentStickers &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetRecentStickersRequest, request.is_attached_); +} + +void Requests::on_request(uint64 id, td_api::addRecentSticker &request) { + CHECK_IS_USER(); + CREATE_REQUEST(AddRecentStickerRequest, request.is_attached_, std::move(request.sticker_)); +} + +void Requests::on_request(uint64 id, td_api::removeRecentSticker &request) { + CHECK_IS_USER(); + CREATE_REQUEST(RemoveRecentStickerRequest, request.is_attached_, std::move(request.sticker_)); +} + +void Requests::on_request(uint64 id, td_api::clearRecentStickers &request) { + CHECK_IS_USER(); + CREATE_REQUEST(ClearRecentStickersRequest, request.is_attached_); +} + +void Requests::on_request(uint64 id, const td_api::getFavoriteStickers &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetFavoriteStickersRequest); +} + +void Requests::on_request(uint64 id, td_api::addFavoriteSticker &request) { + CHECK_IS_USER(); + CREATE_REQUEST(AddFavoriteStickerRequest, std::move(request.sticker_)); +} + +void Requests::on_request(uint64 id, td_api::removeFavoriteSticker &request) { + CHECK_IS_USER(); + CREATE_REQUEST(RemoveFavoriteStickerRequest, std::move(request.sticker_)); +} + +void Requests::on_request(uint64 id, td_api::getStickerEmojis &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetStickerEmojisRequest, std::move(request.sticker_)); +} + +void Requests::on_request(uint64 id, td_api::searchEmojis &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.text_); + for (auto &input_language_code : request.input_language_codes_) { + CLEAN_INPUT_STRING(input_language_code); + } + CREATE_REQUEST(SearchEmojisRequest, std::move(request.text_), std::move(request.input_language_codes_)); +} + +void Requests::on_request(uint64 id, td_api::getKeywordEmojis &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.text_); + for (auto &input_language_code : request.input_language_codes_) { + CLEAN_INPUT_STRING(input_language_code); + } + CREATE_REQUEST(GetKeywordEmojisRequest, std::move(request.text_), std::move(request.input_language_codes_)); +} + +void Requests::on_request(uint64 id, const td_api::getEmojiCategories &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_emoji_groups(get_emoji_group_type(request.type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getAnimatedEmoji &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.emoji_); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_animated_emoji(std::move(request.emoji_), false, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getEmojiSuggestionsUrl &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.language_code_); + CREATE_HTTP_URL_REQUEST_PROMISE(); + td_->stickers_manager_->get_emoji_suggestions_url(request.language_code_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getCustomEmojiStickers &request) { + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_custom_emoji_stickers(CustomEmojiId::get_custom_emoji_ids(request.custom_emoji_ids_), + true, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getDefaultChatPhotoCustomEmojiStickers &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_default_custom_emoji_stickers(StickerListType::DialogPhoto, false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getDefaultProfilePhotoCustomEmojiStickers &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_default_custom_emoji_stickers(StickerListType::UserProfilePhoto, false, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getDefaultBackgroundCustomEmojiStickers &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_default_custom_emoji_stickers(StickerListType::Background, false, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getDisallowedChatEmojiStatuses &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->get_sticker_list_emoji_statuses(StickerListType::DisallowedChannelEmojiStatus, false, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getSavedAnimations &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetSavedAnimationsRequest); +} + +void Requests::on_request(uint64 id, td_api::addSavedAnimation &request) { + CHECK_IS_USER(); + CREATE_REQUEST(AddSavedAnimationRequest, std::move(request.animation_)); +} + +void Requests::on_request(uint64 id, td_api::removeSavedAnimation &request) { + CHECK_IS_USER(); + CREATE_REQUEST(RemoveSavedAnimationRequest, std::move(request.animation_)); +} + +void Requests::on_request(uint64 id, const td_api::getSavedNotificationSound &request) { + CHECK_IS_USER(); + CREATE_REQUEST(GetSavedNotificationSoundRequest, request.notification_sound_id_); +} + +void Requests::on_request(uint64 id, const td_api::getSavedNotificationSounds &request) { + CHECK_IS_USER(); + CREATE_NO_ARGS_REQUEST(GetSavedNotificationSoundsRequest); +} + +void Requests::on_request(uint64 id, td_api::addSavedNotificationSound &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->notification_settings_manager_->add_saved_ringtone(std::move(request.sound_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeSavedNotificationSound &request) { + CHECK_IS_USER(); + CREATE_REQUEST(RemoveSavedNotificationSoundRequest, request.notification_sound_id_); +} + +void Requests::on_request(uint64 id, const td_api::getChatNotificationSettingsExceptions &request) { + CHECK_IS_USER(); + bool filter_scope = false; + NotificationSettingsScope scope = NotificationSettingsScope::Private; + if (request.scope_ != nullptr) { + filter_scope = true; + scope = get_notification_settings_scope(request.scope_); + } + CREATE_REQUEST(GetChatNotificationSettingsExceptionsRequest, scope, filter_scope, request.compare_sound_); +} + +void Requests::on_request(uint64 id, const td_api::getScopeNotificationSettings &request) { + CHECK_IS_USER(); + if (request.scope_ == nullptr) { + return send_error_raw(id, 400, "Scope must be non-empty"); + } + CREATE_REQUEST(GetScopeNotificationSettingsRequest, get_notification_settings_scope(request.scope_)); +} + +void Requests::on_request(uint64 id, const td_api::removeChatActionBar &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->remove_dialog_action_bar(DialogId(request.chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::reportChat &request) { + CHECK_IS_USER(); + auto r_report_reason = ReportReason::get_report_reason(std::move(request.reason_), std::move(request.text_)); + if (r_report_reason.is_error()) { + return send_error_raw(id, r_report_reason.error().code(), r_report_reason.error().message()); + } + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->report_dialog(DialogId(request.chat_id_), MessageId::get_message_ids(request.message_ids_), + r_report_reason.move_as_ok(), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::reportChatPhoto &request) { + CHECK_IS_USER(); + auto r_report_reason = ReportReason::get_report_reason(std::move(request.reason_), std::move(request.text_)); + if (r_report_reason.is_error()) { + return send_error_raw(id, r_report_reason.error().code(), r_report_reason.error().message()); + } + CREATE_OK_REQUEST_PROMISE(); + td_->dialog_manager_->report_dialog_photo(DialogId(request.chat_id_), FileId(request.file_id_, 0), + r_report_reason.move_as_ok(), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::reportMessageReactions &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + TRY_RESULT_PROMISE(promise, sender_dialog_id, get_message_sender_dialog_id(td_, request.sender_id_, false, false)); + report_message_reactions(td_, {DialogId(request.chat_id_), MessageId(request.message_id_)}, sender_dialog_id, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatStatistics &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->statistics_manager_->get_channel_statistics(DialogId(request.chat_id_), request.is_dark_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatRevenueStatistics &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->statistics_manager_->get_channel_revenue_statistics(DialogId(request.chat_id_), request.is_dark_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatRevenueWithdrawalUrl &request) { + CHECK_IS_USER(); + CREATE_HTTP_URL_REQUEST_PROMISE(); + td_->statistics_manager_->get_channel_revenue_withdrawal_url(DialogId(request.chat_id_), request.password_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getChatRevenueTransactions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->statistics_manager_->get_channel_revenue_transactions(DialogId(request.chat_id_), request.offset_, + request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStarRevenueStatistics &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->star_manager_->get_star_revenue_statistics(request.owner_id_, request.is_dark_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStarWithdrawalUrl &request) { + CHECK_IS_USER(); + CREATE_HTTP_URL_REQUEST_PROMISE(); + td_->star_manager_->get_star_withdrawal_url(request.owner_id_, request.star_count_, request.password_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStarAdAccountUrl &request) { + CHECK_IS_USER(); + CREATE_HTTP_URL_REQUEST_PROMISE(); + td_->star_manager_->get_star_ad_account_url(request.owner_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getMessageStatistics &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->statistics_manager_->get_channel_message_statistics({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.is_dark_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStoryStatistics &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->statistics_manager_->get_channel_story_statistics({DialogId(request.chat_id_), StoryId(request.story_id_)}, + request.is_dark_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getStatisticalGraph &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.token_); + CREATE_REQUEST_PROMISE(); + td_->statistics_manager_->load_statistics_graph(DialogId(request.chat_id_), std::move(request.token_), request.x_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setChatNotificationSettings &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->messages_manager_->set_dialog_notification_settings( + DialogId(request.chat_id_), std::move(request.notification_settings_))); +} + +void Requests::on_request(uint64 id, td_api::setForumTopicNotificationSettings &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->forum_topic_manager_->set_forum_topic_notification_settings( + DialogId(request.chat_id_), MessageId(request.message_thread_id_), + std::move(request.notification_settings_))); +} + +void Requests::on_request(uint64 id, td_api::setScopeNotificationSettings &request) { + CHECK_IS_USER(); + if (request.scope_ == nullptr) { + return send_error_raw(id, 400, "Scope must be non-empty"); + } + answer_ok_query(id, td_->notification_settings_manager_->set_scope_notification_settings( + get_notification_settings_scope(request.scope_), std::move(request.notification_settings_))); +} + +void Requests::on_request(uint64 id, td_api::setReactionNotificationSettings &request) { + CHECK_IS_USER(); + answer_ok_query(id, td_->notification_settings_manager_->set_reaction_notification_settings( + ReactionNotificationSettings(std::move(request.notification_settings_)))); +} + +void Requests::on_request(uint64 id, const td_api::resetAllNotificationSettings &request) { + CHECK_IS_USER(); + td_->messages_manager_->reset_all_notification_settings(); + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); +} + +void Requests::on_request(uint64 id, const td_api::getMapThumbnailFile &request) { + DialogId dialog_id(request.chat_id_); + if (!td_->dialog_manager_->have_dialog_force(dialog_id, "getMapThumbnailFile")) { + dialog_id = DialogId(); + } + + auto r_file_id = td_->file_manager_->get_map_thumbnail_file_id( + Location(request.location_), request.zoom_, request.width_, request.height_, request.scale_, dialog_id); + if (r_file_id.is_error()) { + send_closure(td_actor_, &Td::send_error, id, r_file_id.move_as_error()); + } else { + send_closure(td_actor_, &Td::send_result, id, td_->file_manager_->get_file_object(r_file_id.ok())); + } +} + +void Requests::on_request(uint64 id, const td_api::getLocalizationTargetInfo &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::get_languages, request.only_local_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getLanguagePackInfo &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.language_pack_id_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::search_language_info, request.language_pack_id_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getLanguagePackStrings &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.language_pack_id_); + for (auto &key : request.keys_) { + CLEAN_INPUT_STRING(key); + } + CREATE_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::get_language_pack_strings, + std::move(request.language_pack_id_), std::move(request.keys_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::synchronizeLanguagePack &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.language_pack_id_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::synchronize_language_pack, + std::move(request.language_pack_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::addCustomServerLanguagePack &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.language_pack_id_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::add_custom_server_language, + std::move(request.language_pack_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setCustomLanguagePack &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::set_custom_language, std::move(request.info_), + std::move(request.strings_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editCustomLanguagePackInfo &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::edit_custom_language_info, std::move(request.info_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setCustomLanguagePackString &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.language_pack_id_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::set_custom_language_string, + std::move(request.language_pack_id_), std::move(request.new_string_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::deleteLanguagePack &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.language_pack_id_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->language_pack_manager_, &LanguagePackManager::delete_language, std::move(request.language_pack_id_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getOption &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST_PROMISE(); + td_->option_manager_->get_option(request.name_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setOption &request) { + CLEAN_INPUT_STRING(request.name_); + CREATE_OK_REQUEST_PROMISE(); + td_->option_manager_->set_option(request.name_, std::move(request.value_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setPollAnswer &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->set_poll_answer({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(request.option_ids_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getPollVoters &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->messages_manager_->get_poll_voters({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.option_id_, request.offset_, request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::stopPoll &request) { + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->stop_poll({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(request.reply_markup_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::hideSuggestedAction &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + dismiss_suggested_action(SuggestedAction(request.action_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::hideContactCloseBirthdays &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->option_manager_->set_option_boolean("dismiss_birthday_contact_today", true); + td_->user_manager_->hide_contact_birthdays(std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getBusinessConnection &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.connection_id_); + CREATE_REQUEST_PROMISE(); + td_->business_connection_manager_->get_business_connection(BusinessConnectionId(std::move(request.connection_id_)), + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getLoginUrlInfo &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->link_manager_->get_login_url_info({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.button_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getLoginUrl &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->link_manager_->get_login_url({DialogId(request.chat_id_), MessageId(request.message_id_)}, request.button_id_, + request.allow_write_access_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::shareUsersWithBot &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + auto user_ids = UserId::get_user_ids(request.shared_user_ids_); + auto dialog_ids = transform(user_ids, [](UserId user_id) { return DialogId(user_id); }); + td_->messages_manager_->share_dialogs_with_bot({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.button_id_, std::move(dialog_ids), true, request.only_check_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::shareChatWithBot &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->messages_manager_->share_dialogs_with_bot({DialogId(request.chat_id_), MessageId(request.message_id_)}, + request.button_id_, {DialogId(request.shared_chat_id_)}, false, + request.only_check_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getInlineQueryResults &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.query_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->inline_queries_manager_->send_inline_query(UserId(request.bot_user_id_), DialogId(request.chat_id_), + Location(request.user_location_), request.query_, request.offset_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::answerInlineQuery &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.next_offset_); + CREATE_OK_REQUEST_PROMISE(); + td_->inline_queries_manager_->answer_inline_query(request.inline_query_id_, request.is_personal_, + std::move(request.button_), std::move(request.results_), + request.cache_time_, request.next_offset_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getGrossingWebAppBots &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->attach_menu_manager_->get_popular_app_bots(request.offset_, request.limit_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchWebApp &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.web_app_short_name_); + CREATE_REQUEST_PROMISE(); + td_->attach_menu_manager_->get_web_app(UserId(request.bot_user_id_), request.web_app_short_name_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getWebAppLinkUrl &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.web_app_short_name_); + CLEAN_INPUT_STRING(request.start_parameter_); + CLEAN_INPUT_STRING(request.application_name_); + CREATE_HTTP_URL_REQUEST_PROMISE(); + td_->attach_menu_manager_->request_app_web_view( + DialogId(request.chat_id_), UserId(request.bot_user_id_), std::move(request.web_app_short_name_), + std::move(request.start_parameter_), std::move(request.theme_), std::move(request.application_name_), + request.allow_write_access_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getMainWebApp &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.start_parameter_); + CLEAN_INPUT_STRING(request.application_name_); + CREATE_REQUEST_PROMISE(); + td_->attach_menu_manager_->request_main_web_view(DialogId(request.chat_id_), UserId(request.bot_user_id_), + std::move(request.start_parameter_), std::move(request.theme_), + std::move(request.application_name_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getWebAppUrl &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.url_); + CLEAN_INPUT_STRING(request.application_name_); + CREATE_HTTP_URL_REQUEST_PROMISE(); + td_->inline_queries_manager_->get_simple_web_view_url(UserId(request.bot_user_id_), std::move(request.url_), + std::move(request.theme_), std::move(request.application_name_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendWebAppData &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.button_text_); + CLEAN_INPUT_STRING(request.data_); + CREATE_OK_REQUEST_PROMISE(); + td_->inline_queries_manager_->send_web_view_data(UserId(request.bot_user_id_), std::move(request.button_text_), + std::move(request.data_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::openWebApp &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.url_); + CLEAN_INPUT_STRING(request.application_name_); + CREATE_REQUEST_PROMISE(); + td_->attach_menu_manager_->request_web_view(DialogId(request.chat_id_), UserId(request.bot_user_id_), + MessageId(request.message_thread_id_), std::move(request.reply_to_), + std::move(request.url_), std::move(request.theme_), + std::move(request.application_name_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::closeWebApp &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->attach_menu_manager_->close_web_view(request.web_app_launch_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::answerWebAppQuery &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.web_app_query_id_); + CREATE_REQUEST_PROMISE(); + td_->inline_queries_manager_->answer_web_view_query(request.web_app_query_id_, std::move(request.result_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getCallbackQueryAnswer &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->callback_queries_manager_->send_callback_query({DialogId(request.chat_id_), MessageId(request.message_id_)}, + std::move(request.payload_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::answerCallbackQuery &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.text_); + CLEAN_INPUT_STRING(request.url_); + CREATE_OK_REQUEST_PROMISE(); + td_->callback_queries_manager_->answer_callback_query(request.callback_query_id_, request.text_, request.show_alert_, + request.url_, request.cache_time_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::answerShippingQuery &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.error_message_); + CREATE_OK_REQUEST_PROMISE(); + answer_shipping_query(td_, request.shipping_query_id_, std::move(request.shipping_options_), request.error_message_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::answerPreCheckoutQuery &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.error_message_); + CREATE_OK_REQUEST_PROMISE(); + answer_pre_checkout_query(td_, request.pre_checkout_query_id_, request.error_message_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getBankCardInfo &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.bank_card_number_); + CREATE_REQUEST_PROMISE(); + get_bank_card_info(td_, request.bank_card_number_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getPaymentForm &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_payment_form(td_, std::move(request.input_invoice_), request.theme_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::validateOrderInfo &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + validate_order_info(td_, std::move(request.input_invoice_), std::move(request.order_info_), request.allow_save_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendPaymentForm &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.order_info_id_); + CLEAN_INPUT_STRING(request.shipping_option_id_); + CREATE_REQUEST_PROMISE(); + send_payment_form(td_, std::move(request.input_invoice_), request.payment_form_id_, request.order_info_id_, + request.shipping_option_id_, request.credentials_, request.tip_amount_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getPaymentReceipt &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_payment_receipt(td_, {DialogId(request.chat_id_), MessageId(request.message_id_)}, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getSavedOrderInfo &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_saved_order_info(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteSavedOrderInfo &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + delete_saved_order_info(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteSavedCredentials &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + delete_saved_credentials(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::createInvoiceLink &request) { + CHECK_IS_BOT(); + CREATE_HTTP_URL_REQUEST_PROMISE(); + export_invoice(td_, std::move(request.invoice_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::refundStarPayment &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.telegram_payment_charge_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->star_manager_->refund_star_payment(UserId(request.user_id_), request.telegram_payment_charge_id_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getPassportElement &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + if (request.type_ == nullptr) { + return send_error_raw(id, 400, "Type must be non-empty"); + } + CREATE_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::get_secure_value, std::move(request.password_), + get_secure_value_type_td_api(request.type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getAllPassportElements &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::get_all_secure_values, std::move(request.password_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setPassportElement &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + auto r_secure_value = get_secure_value(td_->file_manager_.get(), std::move(request.element_)); + if (r_secure_value.is_error()) { + return send_error_raw(id, 400, r_secure_value.error().message()); + } + CREATE_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::set_secure_value, std::move(request.password_), + r_secure_value.move_as_ok(), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deletePassportElement &request) { + CHECK_IS_USER(); + if (request.type_ == nullptr) { + return send_error_raw(id, 400, "Type must be non-empty"); + } + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::delete_secure_value, get_secure_value_type_td_api(request.type_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setPassportElementErrors &request) { + CHECK_IS_BOT(); + auto r_input_user = td_->user_manager_->get_input_user(UserId(request.user_id_)); + if (r_input_user.is_error()) { + return send_error_raw(id, r_input_user.error().code(), r_input_user.error().message()); + } + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::set_secure_value_errors, td_, r_input_user.move_as_ok(), + std::move(request.errors_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getPreferredCountryLanguage &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.country_code_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::get_preferred_country_language, std::move(request.country_code_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendEmailAddressVerificationCode &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.email_address_); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_email_address_authentication_code_info_object()); + } + }); + send_closure(td_->password_manager_, &PasswordManager::send_email_address_verification_code, + std::move(request.email_address_), std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::resendEmailAddressVerificationCode &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(result.ok().get_email_address_authentication_code_info_object()); + } + }); + send_closure(td_->password_manager_, &PasswordManager::resend_email_address_verification_code, + std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::checkEmailAddressVerificationCode &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.code_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->password_manager_, &PasswordManager::check_email_address_verification_code, + std::move(request.code_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.public_key_); + CLEAN_INPUT_STRING(request.scope_); + CLEAN_INPUT_STRING(request.nonce_); + UserId bot_user_id(request.bot_user_id_); + if (!bot_user_id.is_valid()) { + return send_error_raw(id, 400, "Bot user identifier invalid"); + } + if (request.nonce_.empty()) { + return send_error_raw(id, 400, "Nonce must be non-empty"); + } + CREATE_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::get_passport_authorization_form, bot_user_id, + std::move(request.scope_), std::move(request.public_key_), std::move(request.nonce_), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getPassportAuthorizationFormAvailableElements &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.password_); + CREATE_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::get_passport_authorization_form_available_elements, + request.authorization_form_id_, std::move(request.password_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendPassportAuthorizationForm &request) { + CHECK_IS_USER(); + for (auto &type : request.types_) { + if (type == nullptr) { + return send_error_raw(id, 400, "Type must be non-empty"); + } + } + + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->secure_manager_, &SecureManager::send_passport_authorization_form, request.authorization_form_id_, + get_secure_value_types_td_api(request.types_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getSupportUser &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->user_manager_->get_support_user(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getInstalledBackgrounds &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->background_manager_->get_backgrounds(request.for_dark_theme_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getBackgroundUrl &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.name_); + Result r_url = LinkManager::get_background_url(request.name_, std::move(request.type_)); + if (r_url.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_url.move_as_error()); + } + + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(r_url.ok())); +} + +void Requests::on_request(uint64 id, td_api::searchBackground &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.name_); + CREATE_REQUEST(SearchBackgroundRequest, std::move(request.name_)); +} + +void Requests::on_request(uint64 id, td_api::setDefaultBackground &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->background_manager_->set_background(request.background_.get(), request.type_.get(), request.for_dark_theme_, + std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::deleteDefaultBackground &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->background_manager_->delete_background(request.for_dark_theme_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeInstalledBackground &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->background_manager_->remove_background(BackgroundId(request.background_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::resetInstalledBackgrounds &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + td_->background_manager_->reset_backgrounds(std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.referrer_); + CREATE_REQUEST_PROMISE(); + td_->link_manager_->get_recent_me_urls(request.referrer_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setBotUpdatesStatus &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.error_message_); + CREATE_OK_REQUEST_PROMISE(); + set_bot_updates_status(td_, request.pending_update_count_, request.error_message_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::sendCustomRequest &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.method_); + CLEAN_INPUT_STRING(request.parameters_); + CREATE_REQUEST_PROMISE(); + send_bot_custom_query(td_, request.method_, request.parameters_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::answerCustomQuery &request) { + CHECK_IS_BOT(); + CLEAN_INPUT_STRING(request.data_); + CREATE_OK_REQUEST_PROMISE(); + answer_bot_custom_query(td_, request.custom_query_id_, request.data_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::setAlarm &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->alarm_manager_, &AlarmManager::set_alarm, request.seconds_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::searchHashtags &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.prefix_); + CREATE_REQUEST_PROMISE(); + auto query_promise = + PromiseCreator::lambda([promise = std::move(promise)](Result> result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.move_as_ok())); + } + }); + send_closure(td_->hashtag_hints_, &HashtagHints::query, std::move(request.prefix_), request.limit_, + std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::removeRecentHashtag &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.hashtag_); + CREATE_OK_REQUEST_PROMISE(); + send_closure(td_->hashtag_hints_, &HashtagHints::remove_hashtag, std::move(request.hashtag_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getPremiumLimit &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_premium_limit(request.limit_type_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getPremiumFeatures &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_premium_features(td_, request.source_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getPremiumStickerExamples &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->stickers_manager_->search_stickers(StickerType::Regular, "⭐️⭐️", 100, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::viewPremiumFeature &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + view_premium_feature(td_, request.feature_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::clickPremiumSubscriptionButton &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + click_premium_subscription_button(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getPremiumState &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_premium_state(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getPremiumGiftCodePaymentOptions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_premium_gift_code_options(td_, DialogId(request.boosted_chat_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::checkPremiumGiftCode &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.code_); + CREATE_REQUEST_PROMISE(); + check_premium_gift_code(td_, request.code_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::applyPremiumGiftCode &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.code_); + CREATE_OK_REQUEST_PROMISE(); + apply_premium_gift_code(td_, request.code_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::launchPrepaidGiveaway &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + launch_prepaid_premium_giveaway(td_, request.giveaway_id_, std::move(request.parameters_), request.winner_count_, + request.star_count_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getGiveawayInfo &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_premium_giveaway_info(td_, {DialogId(request.chat_id_), MessageId(request.message_id_)}, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStarPaymentOptions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->star_manager_->get_star_payment_options(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStarGiftPaymentOptions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->star_manager_->get_star_gift_payment_options(UserId(request.user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getStarGiveawayPaymentOptions &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + td_->star_manager_->get_star_giveaway_payment_options(std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getStarTransactions &request) { + CLEAN_INPUT_STRING(request.subscription_id_); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->star_manager_->get_star_transactions(std::move(request.owner_id_), request.subscription_id_, request.offset_, + request.limit_, std::move(request.direction_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getStarSubscriptions &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.offset_); + CREATE_REQUEST_PROMISE(); + td_->star_manager_->get_star_subscriptions(request.only_expiring_, request.offset_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editStarSubscription &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.subscription_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->star_manager_->edit_star_subscriptions(request.subscription_id_, request.is_canceled_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::reuseStarSubscription &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.subscription_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->star_manager_->reuse_star_subscriptions(request.subscription_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::canPurchaseFromStore &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + can_purchase_premium(td_, std::move(request.purpose_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::assignAppStoreTransaction &request) { + CHECK_IS_USER(); + CREATE_OK_REQUEST_PROMISE(); + assign_app_store_transaction(td_, request.receipt_, std::move(request.purpose_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::assignGooglePlayTransaction &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.package_name_); + CLEAN_INPUT_STRING(request.store_product_id_); + CLEAN_INPUT_STRING(request.purchase_token_); + CREATE_OK_REQUEST_PROMISE(); + assign_play_market_transaction(td_, request.package_name_, request.store_product_id_, request.purchase_token_, + std::move(request.purpose_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getBusinessFeatures &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_business_features(td_, request.source_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::acceptTermsOfService &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.terms_of_service_id_); + CREATE_OK_REQUEST_PROMISE(); + td_->terms_of_service_manager_->accept_terms_of_service(std::move(request.terms_of_service_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getCountries &request) { + CREATE_REQUEST_PROMISE(); + td_->country_info_manager_->get_countries(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getCountryCode &request) { + CREATE_TEXT_REQUEST_PROMISE(); + td_->country_info_manager_->get_current_country_code(std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getPhoneNumberInfo &request) { + CREATE_REQUEST_PROMISE(); + td_->country_info_manager_->get_phone_number_info(request.phone_number_prefix_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getCollectibleItemInfo &request) { + CREATE_REQUEST_PROMISE(); + get_collectible_info(td_, std::move(request.type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getApplicationDownloadLink &request) { + CHECK_IS_USER(); + CREATE_HTTP_URL_REQUEST_PROMISE(); + get_invite_text(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::getDeepLinkInfo &request) { + CLEAN_INPUT_STRING(request.link_); + CREATE_REQUEST_PROMISE(); + td_->link_manager_->get_deep_link_info(request.link_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getApplicationConfig &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + send_closure(G()->config_manager(), &ConfigManager::get_app_config, std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::saveApplicationLogEvent &request) { + CHECK_IS_USER(); + CLEAN_INPUT_STRING(request.type_); + CREATE_OK_REQUEST_PROMISE(); + save_app_log(td_, request.type_, DialogId(request.chat_id_), convert_json_value(std::move(request.data_)), + std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::addProxy &request) { + CLEAN_INPUT_STRING(request.server_); + CREATE_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::add_proxy, -1, std::move(request.server_), request.port_, + request.enable_, std::move(request.type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::editProxy &request) { + if (request.proxy_id_ < 0) { + return send_error_raw(id, 400, "Proxy identifier invalid"); + } + CLEAN_INPUT_STRING(request.server_); + CREATE_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::add_proxy, request.proxy_id_, std::move(request.server_), + request.port_, request.enable_, std::move(request.type_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::enableProxy &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::enable_proxy, request.proxy_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::disableProxy &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::disable_proxy, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::removeProxy &request) { + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::remove_proxy, request.proxy_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getProxies &request) { + CREATE_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::get_proxies, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getProxyLink &request) { + CREATE_HTTP_URL_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::get_proxy_link, request.proxy_id_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::pingProxy &request) { + CREATE_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(td_api::make_object(result.move_as_ok())); + } + }); + send_closure(G()->connection_creator(), &ConnectionCreator::ping_proxy, request.proxy_id_, std::move(query_promise)); +} + +void Requests::on_request(uint64 id, const td_api::getUserSupportInfo &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + get_user_info(td_, UserId(request.user_id_), std::move(promise)); +} + +void Requests::on_request(uint64 id, td_api::setUserSupportInfo &request) { + CHECK_IS_USER(); + CREATE_REQUEST_PROMISE(); + set_user_info(td_, UserId(request.user_id_), std::move(request.message_), std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::getSupportName &request) { + CHECK_IS_USER(); + CREATE_TEXT_REQUEST_PROMISE(); + get_support_name(td_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::searchQuote &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getTextEntities &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::parseTextEntities &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::parseMarkdown &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getMarkdownText &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::searchStringsByPrefix &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::checkQuickReplyShortcutName &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getCountryFlagEmoji &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getFileMimeType &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getFileExtension &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::cleanFileName &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getLanguagePackString &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getPhoneNumberInfoSync &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getPushReceiverId &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getChatFolderDefaultIconName &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getJsonValue &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getJsonString &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getThemeParametersJsonString &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::setLogStream &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getLogStream &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::setLogVerbosityLevel &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getLogVerbosityLevel &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getLogTags &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::setLogTagVerbosityLevel &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::getLogTagVerbosityLevel &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::addLogMessage &request) { + UNREACHABLE(); +} + +// test +void Requests::on_request(uint64 id, const td_api::testNetwork &request) { + CREATE_OK_REQUEST_PROMISE(); + auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(Unit()); + } + }); + td_->country_info_manager_->get_current_country_code(std::move(query_promise)); +} + +void Requests::on_request(uint64 id, td_api::testProxy &request) { + auto r_proxy = Proxy::create_proxy(std::move(request.server_), request.port_, request.type_.get()); + if (r_proxy.is_error()) { + return send_closure(td_actor_, &Td::send_error, id, r_proxy.move_as_error()); + } + CREATE_OK_REQUEST_PROMISE(); + send_closure(G()->connection_creator(), &ConnectionCreator::test_proxy, r_proxy.move_as_ok(), request.dc_id_, + request.timeout_, std::move(promise)); +} + +void Requests::on_request(uint64 id, const td_api::testGetDifference &request) { + td_->updates_manager_->get_difference("testGetDifference"); + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); +} + +void Requests::on_request(uint64 id, const td_api::testUseUpdate &request) { + send_closure(td_actor_, &Td::send_result, id, nullptr); +} + +void Requests::on_request(uint64 id, const td_api::testReturnError &request) { + UNREACHABLE(); +} + +void Requests::on_request(uint64 id, const td_api::testCallEmpty &request) { + send_closure(td_actor_, &Td::send_result, id, td_api::make_object()); +} + +void Requests::on_request(uint64 id, const td_api::testSquareInt &request) { + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(request.x_ * request.x_)); +} + +void Requests::on_request(uint64 id, td_api::testCallString &request) { + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(std::move(request.x_))); +} + +void Requests::on_request(uint64 id, td_api::testCallBytes &request) { + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(std::move(request.x_))); +} + +void Requests::on_request(uint64 id, td_api::testCallVectorInt &request) { + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(std::move(request.x_))); +} + +void Requests::on_request(uint64 id, td_api::testCallVectorIntObject &request) { + send_closure(td_actor_, &Td::send_result, id, + td_api::make_object(std::move(request.x_))); +} + +void Requests::on_request(uint64 id, td_api::testCallVectorString &request) { + send_closure(td_actor_, &Td::send_result, id, td_api::make_object(std::move(request.x_))); +} + +void Requests::on_request(uint64 id, td_api::testCallVectorStringObject &request) { + send_closure(td_actor_, &Td::send_result, id, + td_api::make_object(std::move(request.x_))); +} + +#undef CLEAN_INPUT_STRING +#undef CHECK_IS_BOT +#undef CHECK_IS_USER +#undef CREATE_NO_ARGS_REQUEST +#undef CREATE_REQUEST +#undef CREATE_REQUEST_PROMISE +#undef CREATE_OK_REQUEST_PROMISE +#undef CREATE_TEXT_REQUEST_PROMISE +#undef CREATE_HTTP_URL_REQUEST_PROMISE + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Requests.h b/protocols/Telegram/tdlib/td/td/telegram/Requests.h new file mode 100644 index 0000000000..33de9496e5 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/Requests.h @@ -0,0 +1,1692 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/files/FileId.h" +#include "td/telegram/Td.h" +#include "td/telegram/td_api.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/MovableValue.h" +#include "td/utils/Promise.h" +#include "td/utils/Slice.h" +#include "td/utils/Status.h" + +#include + +namespace td { + +class Requests { + public: + explicit Requests(Td *td); + + void run_request(uint64 id, td_api::object_ptr &&function); + + void on_file_download_finished(FileId file_id); + + private: + Td *td_ = nullptr; + ActorId td_actor_; + + void send_error_raw(uint64 id, int32 code, CSlice error); + + void answer_ok_query(uint64 id, Status status); + + struct DownloadInfo { + int64 offset = -1; + int64 limit = -1; + vector request_ids; + }; + FlatHashMap pending_file_downloads_; + + class DownloadFileCallback; + + std::shared_ptr download_file_callback_; + + class RequestPromiseBase { + enum class State : int32 { Empty, Ready, Complete }; + ActorId td_actor_; + uint64 request_id_; + MovableValue state_{State::Empty}; + + public: + void set_value(td_api::object_ptr value) { + CHECK(state_.get() == State::Ready); + send_closure(td_actor_, &Td::send_result, request_id_, std::move(value)); + state_ = State::Complete; + } + + void set_error(Status &&error) { + if (state_.get() == State::Ready) { + send_closure(td_actor_, &Td::send_error, request_id_, std::move(error)); + state_ = State::Complete; + } + } + + RequestPromiseBase(const RequestPromiseBase &) = delete; + RequestPromiseBase &operator=(const RequestPromiseBase &) = delete; + RequestPromiseBase(RequestPromiseBase &&) = default; + RequestPromiseBase &operator=(RequestPromiseBase &&) = default; + virtual ~RequestPromiseBase() { + if (state_.get() == State::Ready) { + send_closure(td_actor_, &Td::send_error, request_id_, Status::Error("Lost promise")); + } + } + + RequestPromiseBase(ActorId td_actor, uint64 request_id) + : td_actor_(std::move(td_actor)), request_id_(request_id), state_(State::Ready) { + } + }; + + template + class RequestPromise final + : public PromiseInterface + , private RequestPromiseBase { + public: + void set_value(T &&value) final { + RequestPromiseBase::set_value(std::move(value)); + } + + void set_error(Status &&error) final { + RequestPromiseBase::set_error(std::move(error)); + } + + RequestPromise(ActorId td_actor, uint64 request_id) : RequestPromiseBase(std::move(td_actor), request_id) { + } + }; + + template + Promise create_request_promise(uint64 request_id) const { + return Promise(td::make_unique>(td_actor_, request_id)); + } + + Promise create_ok_request_promise(uint64 id); + + Promise create_text_request_promise(uint64 id); + + Promise create_http_url_request_promise(uint64 id); + + template + void on_request(uint64 id, const T &) = delete; + + void on_request(uint64 id, const td_api::setTdlibParameters &request); + + void on_request(uint64 id, const td_api::getAuthorizationState &request); + + void on_request(uint64 id, td_api::setAuthenticationPhoneNumber &request); + + void on_request(uint64 id, td_api::sendAuthenticationFirebaseSms &request); + + void on_request(uint64 id, td_api::reportAuthenticationCodeMissing &request); + + void on_request(uint64 id, td_api::setAuthenticationEmailAddress &request); + + void on_request(uint64 id, td_api::resendAuthenticationCode &request); + + void on_request(uint64 id, td_api::checkAuthenticationEmailCode &request); + + void on_request(uint64 id, td_api::checkAuthenticationCode &request); + + void on_request(uint64 id, td_api::registerUser &request); + + void on_request(uint64 id, td_api::requestQrCodeAuthentication &request); + + void on_request(uint64 id, const td_api::resetAuthenticationEmailAddress &request); + + void on_request(uint64 id, td_api::checkAuthenticationPassword &request); + + void on_request(uint64 id, const td_api::requestAuthenticationPasswordRecovery &request); + + void on_request(uint64 id, td_api::checkAuthenticationPasswordRecoveryCode &request); + + void on_request(uint64 id, td_api::recoverAuthenticationPassword &request); + + void on_request(uint64 id, const td_api::logOut &request); + + void on_request(uint64 id, const td_api::close &request); + + void on_request(uint64 id, const td_api::destroy &request); + + void on_request(uint64 id, td_api::checkAuthenticationBotToken &request); + + void on_request(uint64 id, td_api::confirmQrCodeAuthentication &request); + + void on_request(uint64 id, td_api::setDatabaseEncryptionKey &request); + + void on_request(uint64 id, const td_api::getCurrentState &request); + + void on_request(uint64 id, const td_api::getPasswordState &request); + + void on_request(uint64 id, td_api::setPassword &request); + + void on_request(uint64 id, td_api::setLoginEmailAddress &request); + + void on_request(uint64 id, const td_api::resendLoginEmailAddressCode &request); + + void on_request(uint64 id, td_api::checkLoginEmailAddressCode &request); + + void on_request(uint64 id, td_api::getRecoveryEmailAddress &request); + + void on_request(uint64 id, td_api::setRecoveryEmailAddress &request); + + void on_request(uint64 id, td_api::checkRecoveryEmailAddressCode &request); + + void on_request(uint64 id, const td_api::resendRecoveryEmailAddressCode &request); + + void on_request(uint64 id, const td_api::cancelRecoveryEmailAddressVerification &request); + + void on_request(uint64 id, td_api::requestPasswordRecovery &request); + + void on_request(uint64 id, td_api::checkPasswordRecoveryCode &request); + + void on_request(uint64 id, td_api::recoverPassword &request); + + void on_request(uint64 id, const td_api::resetPassword &request); + + void on_request(uint64 id, const td_api::cancelPasswordReset &request); + + void on_request(uint64 id, td_api::getTemporaryPasswordState &request); + + void on_request(uint64 id, td_api::createTemporaryPassword &request); + + void on_request(uint64 id, td_api::processPushNotification &request); + + void on_request(uint64 id, td_api::registerDevice &request); + + void on_request(uint64 id, td_api::getUserPrivacySettingRules &request); + + void on_request(uint64 id, td_api::setUserPrivacySettingRules &request); + + void on_request(uint64 id, const td_api::getDefaultMessageAutoDeleteTime &request); + + void on_request(uint64 id, const td_api::setDefaultMessageAutoDeleteTime &request); + + void on_request(uint64 id, const td_api::getAccountTtl &request); + + void on_request(uint64 id, const td_api::setAccountTtl &request); + + void on_request(uint64 id, td_api::deleteAccount &request); + + void on_request(uint64 id, td_api::sendPhoneNumberCode &request); + + void on_request(uint64 id, td_api::sendPhoneNumberFirebaseSms &request); + + void on_request(uint64 id, td_api::reportPhoneNumberCodeMissing &request); + + void on_request(uint64 id, td_api::resendPhoneNumberCode &request); + + void on_request(uint64 id, td_api::checkPhoneNumberCode &request); + + void on_request(uint64 id, const td_api::getUserLink &request); + + void on_request(uint64 id, td_api::searchUserByToken &request); + + void on_request(uint64 id, const td_api::getActiveSessions &request); + + void on_request(uint64 id, const td_api::terminateSession &request); + + void on_request(uint64 id, const td_api::terminateAllOtherSessions &request); + + void on_request(uint64 id, const td_api::confirmSession &request); + + void on_request(uint64 id, const td_api::toggleSessionCanAcceptCalls &request); + + void on_request(uint64 id, const td_api::toggleSessionCanAcceptSecretChats &request); + + void on_request(uint64 id, const td_api::setInactiveSessionTtl &request); + + void on_request(uint64 id, const td_api::getConnectedWebsites &request); + + void on_request(uint64 id, const td_api::disconnectWebsite &request); + + void on_request(uint64 id, const td_api::disconnectAllWebsites &request); + + void on_request(uint64 id, const td_api::getMe &request); + + void on_request(uint64 id, const td_api::getUser &request); + + void on_request(uint64 id, const td_api::getUserFullInfo &request); + + void on_request(uint64 id, const td_api::getBasicGroup &request); + + void on_request(uint64 id, const td_api::getBasicGroupFullInfo &request); + + void on_request(uint64 id, const td_api::getSupergroup &request); + + void on_request(uint64 id, const td_api::getSupergroupFullInfo &request); + + void on_request(uint64 id, const td_api::getSecretChat &request); + + void on_request(uint64 id, const td_api::getChat &request); + + void on_request(uint64 id, const td_api::getMessage &request); + + void on_request(uint64 id, const td_api::getMessageLocally &request); + + void on_request(uint64 id, const td_api::getRepliedMessage &request); + + void on_request(uint64 id, const td_api::getChatPinnedMessage &request); + + void on_request(uint64 id, const td_api::getCallbackQueryMessage &request); + + void on_request(uint64 id, const td_api::getMessageThread &request); + + void on_request(uint64 id, const td_api::getMessageReadDate &request); + + void on_request(uint64 id, const td_api::getMessageViewers &request); + + void on_request(uint64 id, const td_api::getMessages &request); + + void on_request(uint64 id, const td_api::getMessageProperties &request); + + void on_request(uint64 id, const td_api::getChatSponsoredMessages &request); + + void on_request(uint64 id, const td_api::clickChatSponsoredMessage &request); + + void on_request(uint64 id, const td_api::reportChatSponsoredMessage &request); + + void on_request(uint64 id, const td_api::getMessageLink &request); + + void on_request(uint64 id, const td_api::getMessageEmbeddingCode &request); + + void on_request(uint64 id, td_api::getMessageLinkInfo &request); + + void on_request(uint64 id, td_api::translateText &request); + + void on_request(uint64 id, td_api::translateMessageText &request); + + void on_request(uint64 id, const td_api::recognizeSpeech &request); + + void on_request(uint64 id, const td_api::rateSpeechRecognition &request); + + void on_request(uint64 id, const td_api::getFile &request); + + void on_request(uint64 id, td_api::getRemoteFile &request); + + void on_request(uint64 id, td_api::getStorageStatistics &request); + + void on_request(uint64 id, td_api::getStorageStatisticsFast &request); + + void on_request(uint64 id, const td_api::getDatabaseStatistics &request); + + void on_request(uint64 id, td_api::optimizeStorage &request); + + void on_request(uint64 id, td_api::getNetworkStatistics &request); + + void on_request(uint64 id, td_api::resetNetworkStatistics &request); + + void on_request(uint64 id, td_api::addNetworkStatistics &request); + + void on_request(uint64 id, const td_api::setNetworkType &request); + + void on_request(uint64 id, const td_api::getAutoDownloadSettingsPresets &request); + + void on_request(uint64 id, const td_api::setAutoDownloadSettings &request); + + void on_request(uint64 id, const td_api::getAutosaveSettings &request); + + void on_request(uint64 id, td_api::setAutosaveSettings &request); + + void on_request(uint64 id, const td_api::clearAutosaveSettingsExceptions &request); + + void on_request(uint64 id, const td_api::getRecommendedChats &request); + + void on_request(uint64 id, const td_api::getChatSimilarChats &request); + + void on_request(uint64 id, const td_api::getChatSimilarChatCount &request); + + void on_request(uint64 id, const td_api::openChatSimilarChat &request); + + void on_request(uint64 id, const td_api::getTopChats &request); + + void on_request(uint64 id, const td_api::removeTopChat &request); + + void on_request(uint64 id, const td_api::loadChats &request); + + void on_request(uint64 id, const td_api::getChats &request); + + void on_request(uint64 id, const td_api::loadSavedMessagesTopics &request); + + void on_request(uint64 id, const td_api::getSavedMessagesTopicHistory &request); + + void on_request(uint64 id, const td_api::getSavedMessagesTopicMessageByDate &request); + + void on_request(uint64 id, const td_api::deleteSavedMessagesTopicHistory &request); + + void on_request(uint64 id, const td_api::deleteSavedMessagesTopicMessagesByDate &request); + + void on_request(uint64 id, const td_api::toggleSavedMessagesTopicIsPinned &request); + + void on_request(uint64 id, const td_api::setPinnedSavedMessagesTopics &request); + + void on_request(uint64 id, td_api::searchPublicChat &request); + + void on_request(uint64 id, td_api::searchPublicChats &request); + + void on_request(uint64 id, td_api::searchChats &request); + + void on_request(uint64 id, td_api::searchChatsOnServer &request); + + void on_request(uint64 id, const td_api::searchChatsNearby &request); + + void on_request(uint64 id, td_api::searchRecentlyFoundChats &request); + + void on_request(uint64 id, const td_api::addRecentlyFoundChat &request); + + void on_request(uint64 id, const td_api::removeRecentlyFoundChat &request); + + void on_request(uint64 id, const td_api::clearRecentlyFoundChats &request); + + void on_request(uint64 id, const td_api::getRecentlyOpenedChats &request); + + void on_request(uint64 id, const td_api::getGroupsInCommon &request); + + void on_request(uint64 id, td_api::checkChatUsername &request); + + void on_request(uint64 id, const td_api::getCreatedPublicChats &request); + + void on_request(uint64 id, const td_api::checkCreatedPublicChatsLimit &request); + + void on_request(uint64 id, const td_api::getSuitableDiscussionChats &request); + + void on_request(uint64 id, const td_api::getInactiveSupergroupChats &request); + + void on_request(uint64 id, const td_api::getSuitablePersonalChats &request); + + void on_request(uint64 id, const td_api::openChat &request); + + void on_request(uint64 id, const td_api::closeChat &request); + + void on_request(uint64 id, const td_api::viewMessages &request); + + void on_request(uint64 id, const td_api::openMessageContent &request); + + void on_request(uint64 id, const td_api::clickAnimatedEmojiMessage &request); + + void on_request(uint64 id, const td_api::getInternalLink &request); + + void on_request(uint64 id, const td_api::getInternalLinkType &request); + + void on_request(uint64 id, td_api::getExternalLinkInfo &request); + + void on_request(uint64 id, td_api::getExternalLink &request); + + void on_request(uint64 id, const td_api::getChatHistory &request); + + void on_request(uint64 id, const td_api::deleteChatHistory &request); + + void on_request(uint64 id, const td_api::deleteChat &request); + + void on_request(uint64 id, const td_api::getMessageThreadHistory &request); + + void on_request(uint64 id, const td_api::getChatMessageCalendar &request); + + void on_request(uint64 id, td_api::searchChatMessages &request); + + void on_request(uint64 id, td_api::searchSecretMessages &request); + + void on_request(uint64 id, td_api::searchMessages &request); + + void on_request(uint64 id, td_api::searchSavedMessages &request); + + void on_request(uint64 id, const td_api::searchCallMessages &request); + + void on_request(uint64 id, td_api::searchOutgoingDocumentMessages &request); + + void on_request(uint64 id, td_api::searchPublicMessagesByTag &request); + + void on_request(uint64 id, td_api::searchPublicStoriesByTag &request); + + void on_request(uint64 id, td_api::searchPublicStoriesByLocation &request); + + void on_request(uint64 id, td_api::searchPublicStoriesByVenue &request); + + void on_request(uint64 id, td_api::getSearchedForTags &request); + + void on_request(uint64 id, td_api::removeSearchedForTag &request); + + void on_request(uint64 id, td_api::clearSearchedForTags &request); + + void on_request(uint64 id, const td_api::deleteAllCallMessages &request); + + void on_request(uint64 id, const td_api::searchChatRecentLocationMessages &request); + + void on_request(uint64 id, const td_api::getChatMessageByDate &request); + + void on_request(uint64 id, const td_api::getChatSparseMessagePositions &request); + + void on_request(uint64 id, const td_api::getChatMessageCount &request); + + void on_request(uint64 id, const td_api::getChatMessagePosition &request); + + void on_request(uint64 id, const td_api::getChatScheduledMessages &request); + + void on_request(uint64 id, const td_api::getEmojiReaction &request); + + void on_request(uint64 id, const td_api::getCustomEmojiReactionAnimations &request); + + void on_request(uint64 id, const td_api::getMessageAvailableReactions &request); + + void on_request(uint64 id, const td_api::clearRecentReactions &request); + + void on_request(uint64 id, const td_api::addMessageReaction &request); + + void on_request(uint64 id, const td_api::addPendingPaidMessageReaction &request); + + void on_request(uint64 id, const td_api::commitPendingPaidMessageReactions &request); + + void on_request(uint64 id, const td_api::removePendingPaidMessageReactions &request); + + void on_request(uint64 id, const td_api::togglePaidMessageReactionIsAnonymous &request); + + void on_request(uint64 id, const td_api::removeMessageReaction &request); + + void on_request(uint64 id, const td_api::setMessageReactions &request); + + void on_request(uint64 id, td_api::getMessageAddedReactions &request); + + void on_request(uint64 id, const td_api::setDefaultReactionType &request); + + void on_request(uint64 id, const td_api::getSavedMessagesTags &request); + + void on_request(uint64 id, td_api::setSavedMessagesTagLabel &request); + + void on_request(uint64 id, const td_api::getMessageEffect &request); + + void on_request(uint64 id, td_api::getMessagePublicForwards &request); + + void on_request(uint64 id, td_api::getStoryPublicForwards &request); + + void on_request(uint64 id, const td_api::removeNotification &request); + + void on_request(uint64 id, const td_api::removeNotificationGroup &request); + + void on_request(uint64 id, const td_api::deleteMessages &request); + + void on_request(uint64 id, const td_api::deleteChatMessagesBySender &request); + + void on_request(uint64 id, const td_api::deleteChatMessagesByDate &request); + + void on_request(uint64 id, const td_api::readAllChatMentions &request); + + void on_request(uint64 id, const td_api::readAllMessageThreadMentions &request); + + void on_request(uint64 id, const td_api::readAllChatReactions &request); + + void on_request(uint64 id, const td_api::readAllMessageThreadReactions &request); + + void on_request(uint64 id, const td_api::getChatAvailableMessageSenders &request); + + void on_request(uint64 id, const td_api::setChatMessageSender &request); + + void on_request(uint64 id, td_api::sendMessage &request); + + void on_request(uint64 id, td_api::sendMessageAlbum &request); + + void on_request(uint64 id, td_api::sendBotStartMessage &request); + + void on_request(uint64 id, td_api::sendInlineQueryResultMessage &request); + + void on_request(uint64 id, td_api::addLocalMessage &request); + + void on_request(uint64 id, td_api::editMessageText &request); + + void on_request(uint64 id, td_api::editMessageLiveLocation &request); + + void on_request(uint64 id, td_api::editMessageMedia &request); + + void on_request(uint64 id, td_api::editMessageCaption &request); + + void on_request(uint64 id, td_api::editMessageReplyMarkup &request); + + void on_request(uint64 id, td_api::editInlineMessageText &request); + + void on_request(uint64 id, td_api::editInlineMessageLiveLocation &request); + + void on_request(uint64 id, td_api::editInlineMessageMedia &request); + + void on_request(uint64 id, td_api::editInlineMessageCaption &request); + + void on_request(uint64 id, td_api::editInlineMessageReplyMarkup &request); + + void on_request(uint64 id, td_api::editMessageSchedulingState &request); + + void on_request(uint64 id, td_api::setMessageFactCheck &request); + + void on_request(uint64 id, td_api::sendBusinessMessage &request); + + void on_request(uint64 id, td_api::sendBusinessMessageAlbum &request); + + void on_request(uint64 id, td_api::editBusinessMessageText &request); + + void on_request(uint64 id, td_api::editBusinessMessageLiveLocation &request); + + void on_request(uint64 id, td_api::editBusinessMessageMedia &request); + + void on_request(uint64 id, td_api::editBusinessMessageCaption &request); + + void on_request(uint64 id, td_api::editBusinessMessageReplyMarkup &request); + + void on_request(uint64 id, td_api::stopBusinessPoll &request); + + void on_request(uint64 id, td_api::setBusinessMessageIsPinned &request); + + void on_request(uint64 id, const td_api::loadQuickReplyShortcuts &request); + + void on_request(uint64 id, const td_api::setQuickReplyShortcutName &request); + + void on_request(uint64 id, const td_api::deleteQuickReplyShortcut &request); + + void on_request(uint64 id, const td_api::reorderQuickReplyShortcuts &request); + + void on_request(uint64 id, const td_api::loadQuickReplyShortcutMessages &request); + + void on_request(uint64 id, const td_api::deleteQuickReplyShortcutMessages &request); + + void on_request(uint64 id, td_api::addQuickReplyShortcutMessage &request); + + void on_request(uint64 id, td_api::addQuickReplyShortcutInlineQueryResultMessage &request); + + void on_request(uint64 id, td_api::addQuickReplyShortcutMessageAlbum &request); + + void on_request(uint64 id, td_api::readdQuickReplyShortcutMessages &request); + + void on_request(uint64 id, td_api::editQuickReplyMessage &request); + + void on_request(uint64 id, const td_api::getCurrentWeather &request); + + void on_request(uint64 id, const td_api::getStory &request); + + void on_request(uint64 id, const td_api::getChatsToSendStories &request); + + void on_request(uint64 id, const td_api::canSendStory &request); + + void on_request(uint64 id, td_api::sendStory &request); + + void on_request(uint64 id, td_api::editStory &request); + + void on_request(uint64 id, const td_api::editStoryCover &request); + + void on_request(uint64 id, td_api::setStoryPrivacySettings &request); + + void on_request(uint64 id, const td_api::toggleStoryIsPostedToChatPage &request); + + void on_request(uint64 id, const td_api::deleteStory &request); + + void on_request(uint64 id, const td_api::loadActiveStories &request); + + void on_request(uint64 id, const td_api::setChatActiveStoriesList &request); + + void on_request(uint64 id, const td_api::getForumTopicDefaultIcons &request); + + void on_request(uint64 id, td_api::createForumTopic &request); + + void on_request(uint64 id, td_api::editForumTopic &request); + + void on_request(uint64 id, const td_api::getForumTopic &request); + + void on_request(uint64 id, const td_api::getForumTopicLink &request); + + void on_request(uint64 id, td_api::getForumTopics &request); + + void on_request(uint64 id, const td_api::toggleForumTopicIsClosed &request); + + void on_request(uint64 id, const td_api::toggleGeneralForumTopicIsHidden &request); + + void on_request(uint64 id, const td_api::toggleForumTopicIsPinned &request); + + void on_request(uint64 id, const td_api::setPinnedForumTopics &request); + + void on_request(uint64 id, const td_api::deleteForumTopic &request); + + void on_request(uint64 id, td_api::setGameScore &request); + + void on_request(uint64 id, td_api::setInlineGameScore &request); + + void on_request(uint64 id, td_api::getGameHighScores &request); + + void on_request(uint64 id, td_api::getInlineGameHighScores &request); + + void on_request(uint64 id, const td_api::deleteChatReplyMarkup &request); + + void on_request(uint64 id, td_api::sendChatAction &request); + + void on_request(uint64 id, td_api::forwardMessages &request); + + void on_request(uint64 id, const td_api::sendQuickReplyShortcutMessages &request); + + void on_request(uint64 id, td_api::resendMessages &request); + + void on_request(uint64 id, td_api::getLinkPreview &request); + + void on_request(uint64 id, td_api::getWebPageInstantView &request); + + void on_request(uint64 id, const td_api::createPrivateChat &request); + + void on_request(uint64 id, const td_api::createBasicGroupChat &request); + + void on_request(uint64 id, const td_api::createSupergroupChat &request); + + void on_request(uint64 id, const td_api::createSecretChat &request); + + void on_request(uint64 id, td_api::createNewBasicGroupChat &request); + + void on_request(uint64 id, td_api::createNewSupergroupChat &request); + + void on_request(uint64 id, const td_api::createNewSecretChat &request); + + void on_request(uint64 id, const td_api::createCall &request); + + void on_request(uint64 id, const td_api::acceptCall &request); + + void on_request(uint64 id, td_api::sendCallSignalingData &request); + + void on_request(uint64 id, const td_api::discardCall &request); + + void on_request(uint64 id, td_api::sendCallRating &request); + + void on_request(uint64 id, td_api::sendCallDebugInformation &request); + + void on_request(uint64 id, td_api::sendCallLog &request); + + void on_request(uint64 id, const td_api::getVideoChatAvailableParticipants &request); + + void on_request(uint64 id, const td_api::setVideoChatDefaultParticipant &request); + + void on_request(uint64 id, td_api::createVideoChat &request); + + void on_request(uint64 id, const td_api::getVideoChatRtmpUrl &request); + + void on_request(uint64 id, const td_api::replaceVideoChatRtmpUrl &request); + + void on_request(uint64 id, const td_api::getGroupCall &request); + + void on_request(uint64 id, const td_api::startScheduledGroupCall &request); + + void on_request(uint64 id, const td_api::toggleGroupCallEnabledStartNotification &request); + + void on_request(uint64 id, td_api::joinGroupCall &request); + + void on_request(uint64 id, td_api::startGroupCallScreenSharing &request); + + void on_request(uint64 id, const td_api::endGroupCallScreenSharing &request); + + void on_request(uint64 id, td_api::setGroupCallTitle &request); + + void on_request(uint64 id, const td_api::toggleGroupCallMuteNewParticipants &request); + + void on_request(uint64 id, const td_api::revokeGroupCallInviteLink &request); + + void on_request(uint64 id, const td_api::inviteGroupCallParticipants &request); + + void on_request(uint64 id, const td_api::getGroupCallInviteLink &request); + + void on_request(uint64 id, td_api::startGroupCallRecording &request); + + void on_request(uint64 id, const td_api::toggleGroupCallScreenSharingIsPaused &request); + + void on_request(uint64 id, const td_api::endGroupCallRecording &request); + + void on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoPaused &request); + + void on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoEnabled &request); + + void on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request); + + void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &request); + + void on_request(uint64 id, const td_api::setGroupCallParticipantVolumeLevel &request); + + void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsHandRaised &request); + + void on_request(uint64 id, const td_api::loadGroupCallParticipants &request); + + void on_request(uint64 id, const td_api::leaveGroupCall &request); + + void on_request(uint64 id, const td_api::endGroupCall &request); + + void on_request(uint64 id, const td_api::getGroupCallStreams &request); + + void on_request(uint64 id, td_api::getGroupCallStreamSegment &request); + + void on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request); + + void on_request(uint64 id, const td_api::getChatListsToAddChat &request); + + void on_request(uint64 id, const td_api::addChatToList &request); + + void on_request(uint64 id, const td_api::getChatFolder &request); + + void on_request(uint64 id, const td_api::getRecommendedChatFolders &request); + + void on_request(uint64 id, td_api::createChatFolder &request); + + void on_request(uint64 id, td_api::editChatFolder &request); + + void on_request(uint64 id, const td_api::deleteChatFolder &request); + + void on_request(uint64 id, const td_api::getChatFolderChatsToLeave &request); + + void on_request(uint64 id, td_api::getChatFolderChatCount &request); + + void on_request(uint64 id, const td_api::reorderChatFolders &request); + + void on_request(uint64 id, const td_api::toggleChatFolderTags &request); + + void on_request(uint64 id, const td_api::getChatsForChatFolderInviteLink &request); + + void on_request(uint64 id, td_api::createChatFolderInviteLink &request); + + void on_request(uint64 id, td_api::getChatFolderInviteLinks &request); + + void on_request(uint64 id, td_api::editChatFolderInviteLink &request); + + void on_request(uint64 id, td_api::deleteChatFolderInviteLink &request); + + void on_request(uint64 id, td_api::checkChatFolderInviteLink &request); + + void on_request(uint64 id, td_api::addChatFolderByInviteLink &request); + + void on_request(uint64 id, const td_api::getChatFolderNewChats &request); + + void on_request(uint64 id, const td_api::processChatFolderNewChats &request); + + void on_request(uint64 id, const td_api::getArchiveChatListSettings &request); + + void on_request(uint64 id, td_api::setArchiveChatListSettings &request); + + void on_request(uint64 id, const td_api::getReadDatePrivacySettings &request); + + void on_request(uint64 id, td_api::setReadDatePrivacySettings &request); + + void on_request(uint64 id, const td_api::getNewChatPrivacySettings &request); + + void on_request(uint64 id, td_api::setNewChatPrivacySettings &request); + + void on_request(uint64 id, const td_api::canSendMessageToUser &request); + + void on_request(uint64 id, td_api::setChatTitle &request); + + void on_request(uint64 id, const td_api::setChatPhoto &request); + + void on_request(uint64 id, const td_api::setChatAccentColor &request); + + void on_request(uint64 id, const td_api::setChatProfileAccentColor &request); + + void on_request(uint64 id, const td_api::setChatMessageAutoDeleteTime &request); + + void on_request(uint64 id, const td_api::setChatEmojiStatus &request); + + void on_request(uint64 id, const td_api::setChatPermissions &request); + + void on_request(uint64 id, td_api::setChatBackground &request); + + void on_request(uint64 id, const td_api::deleteChatBackground &request); + + void on_request(uint64 id, td_api::setChatTheme &request); + + void on_request(uint64 id, td_api::setChatDraftMessage &request); + + void on_request(uint64 id, const td_api::toggleChatHasProtectedContent &request); + + void on_request(uint64 id, const td_api::toggleChatIsPinned &request); + + void on_request(uint64 id, const td_api::toggleChatViewAsTopics &request); + + void on_request(uint64 id, const td_api::toggleChatIsTranslatable &request); + + void on_request(uint64 id, const td_api::toggleChatIsMarkedAsUnread &request); + + void on_request(uint64 id, const td_api::setMessageSenderBlockList &request); + + void on_request(uint64 id, const td_api::toggleChatDefaultDisableNotification &request); + + void on_request(uint64 id, const td_api::setPinnedChats &request); + + void on_request(uint64 id, const td_api::readChatList &request); + + void on_request(uint64 id, const td_api::getStoryNotificationSettingsExceptions &request); + + void on_request(uint64 id, const td_api::getChatActiveStories &request); + + void on_request(uint64 id, const td_api::getChatPostedToChatPageStories &request); + + void on_request(uint64 id, const td_api::getChatArchivedStories &request); + + void on_request(uint64 id, const td_api::setChatPinnedStories &request); + + void on_request(uint64 id, const td_api::openStory &request); + + void on_request(uint64 id, const td_api::closeStory &request); + + void on_request(uint64 id, const td_api::getStoryAvailableReactions &request); + + void on_request(uint64 id, const td_api::setStoryReaction &request); + + void on_request(uint64 id, td_api::getStoryInteractions &request); + + void on_request(uint64 id, td_api::getChatStoryInteractions &request); + + void on_request(uint64 id, td_api::reportStory &request); + + void on_request(uint64 id, const td_api::activateStoryStealthMode &request); + + void on_request(uint64 id, const td_api::getChatBoostLevelFeatures &request); + + void on_request(uint64 id, const td_api::getChatBoostFeatures &request); + + void on_request(uint64 id, const td_api::getAvailableChatBoostSlots &request); + + void on_request(uint64 id, const td_api::getChatBoostStatus &request); + + void on_request(uint64 id, td_api::boostChat &request); + + void on_request(uint64 id, const td_api::getChatBoostLink &request); + + void on_request(uint64 id, td_api::getChatBoostLinkInfo &request); + + void on_request(uint64 id, td_api::getChatBoosts &request); + + void on_request(uint64 id, const td_api::getUserChatBoosts &request); + + void on_request(uint64 id, const td_api::getAttachmentMenuBot &request); + + void on_request(uint64 id, const td_api::toggleBotIsAddedToAttachmentMenu &request); + + void on_request(uint64 id, td_api::setChatAvailableReactions &request); + + void on_request(uint64 id, td_api::setChatClientData &request); + + void on_request(uint64 id, td_api::setChatDescription &request); + + void on_request(uint64 id, const td_api::setChatDiscussionGroup &request); + + void on_request(uint64 id, td_api::setChatLocation &request); + + void on_request(uint64 id, const td_api::setChatSlowModeDelay &request); + + void on_request(uint64 id, const td_api::pinChatMessage &request); + + void on_request(uint64 id, const td_api::unpinChatMessage &request); + + void on_request(uint64 id, const td_api::unpinAllChatMessages &request); + + void on_request(uint64 id, const td_api::unpinAllMessageThreadMessages &request); + + void on_request(uint64 id, const td_api::joinChat &request); + + void on_request(uint64 id, const td_api::leaveChat &request); + + void on_request(uint64 id, const td_api::addChatMember &request); + + void on_request(uint64 id, const td_api::addChatMembers &request); + + void on_request(uint64 id, td_api::setChatMemberStatus &request); + + void on_request(uint64 id, const td_api::banChatMember &request); + + void on_request(uint64 id, const td_api::canTransferOwnership &request); + + void on_request(uint64 id, td_api::transferChatOwnership &request); + + void on_request(uint64 id, const td_api::getChatMember &request); + + void on_request(uint64 id, td_api::searchChatMembers &request); + + void on_request(uint64 id, const td_api::getChatAdministrators &request); + + void on_request(uint64 id, const td_api::replacePrimaryChatInviteLink &request); + + void on_request(uint64 id, td_api::createChatInviteLink &request); + + void on_request(uint64 id, td_api::createChatSubscriptionInviteLink &request); + + void on_request(uint64 id, td_api::editChatInviteLink &request); + + void on_request(uint64 id, td_api::editChatSubscriptionInviteLink &request); + + void on_request(uint64 id, td_api::getChatInviteLink &request); + + void on_request(uint64 id, const td_api::getChatInviteLinkCounts &request); + + void on_request(uint64 id, td_api::getChatInviteLinks &request); + + void on_request(uint64 id, td_api::getChatInviteLinkMembers &request); + + void on_request(uint64 id, td_api::getChatJoinRequests &request); + + void on_request(uint64 id, const td_api::processChatJoinRequest &request); + + void on_request(uint64 id, td_api::processChatJoinRequests &request); + + void on_request(uint64 id, td_api::revokeChatInviteLink &request); + + void on_request(uint64 id, td_api::deleteRevokedChatInviteLink &request); + + void on_request(uint64 id, const td_api::deleteAllRevokedChatInviteLinks &request); + + void on_request(uint64 id, td_api::checkChatInviteLink &request); + + void on_request(uint64 id, td_api::joinChatByInviteLink &request); + + void on_request(uint64 id, td_api::getChatEventLog &request); + + void on_request(uint64 id, const td_api::getTimeZones &request); + + void on_request(uint64 id, const td_api::clearAllDraftMessages &request); + + void on_request(uint64 id, const td_api::downloadFile &request); + + void on_request(uint64 id, const td_api::getFileDownloadedPrefixSize &request); + + void on_request(uint64 id, const td_api::cancelDownloadFile &request); + + void on_request(uint64 id, const td_api::getSuggestedFileName &request); + + void on_request(uint64 id, const td_api::preliminaryUploadFile &request); + + void on_request(uint64 id, const td_api::cancelPreliminaryUploadFile &request); + + void on_request(uint64 id, td_api::writeGeneratedFilePart &request); + + void on_request(uint64 id, const td_api::setFileGenerationProgress &request); + + void on_request(uint64 id, td_api::finishFileGeneration &request); + + void on_request(uint64 id, const td_api::readFilePart &request); + + void on_request(uint64 id, const td_api::deleteFile &request); + + void on_request(uint64 id, const td_api::addFileToDownloads &request); + + void on_request(uint64 id, const td_api::toggleDownloadIsPaused &request); + + void on_request(uint64 id, const td_api::toggleAllDownloadsArePaused &request); + + void on_request(uint64 id, const td_api::removeFileFromDownloads &request); + + void on_request(uint64 id, const td_api::removeAllFilesFromDownloads &request); + + void on_request(uint64 id, td_api::searchFileDownloads &request); + + void on_request(uint64 id, td_api::setApplicationVerificationToken &request); + + void on_request(uint64 id, td_api::getMessageFileType &request); + + void on_request(uint64 id, const td_api::getMessageImportConfirmationText &request); + + void on_request(uint64 id, const td_api::importMessages &request); + + void on_request(uint64 id, const td_api::blockMessageSenderFromReplies &request); + + void on_request(uint64 id, const td_api::getBlockedMessageSenders &request); + + void on_request(uint64 id, td_api::addContact &request); + + void on_request(uint64 id, td_api::importContacts &request); + + void on_request(uint64 id, const td_api::getContacts &request); + + void on_request(uint64 id, td_api::searchContacts &request); + + void on_request(uint64 id, td_api::removeContacts &request); + + void on_request(uint64 id, const td_api::getImportedContactCount &request); + + void on_request(uint64 id, td_api::changeImportedContacts &request); + + void on_request(uint64 id, const td_api::clearImportedContacts &request); + + void on_request(uint64 id, const td_api::getCloseFriends &request); + + void on_request(uint64 id, const td_api::setCloseFriends &request); + + void on_request(uint64 id, td_api::setUserPersonalProfilePhoto &request); + + void on_request(uint64 id, td_api::suggestUserProfilePhoto &request); + + void on_request(uint64 id, td_api::searchUserByPhoneNumber &request); + + void on_request(uint64 id, const td_api::sharePhoneNumber &request); + + void on_request(uint64 id, const td_api::getRecentInlineBots &request); + + void on_request(uint64 id, td_api::setName &request); + + void on_request(uint64 id, td_api::setBio &request); + + void on_request(uint64 id, td_api::setUsername &request); + + void on_request(uint64 id, td_api::toggleUsernameIsActive &request); + + void on_request(uint64 id, td_api::reorderActiveUsernames &request); + + void on_request(uint64 id, td_api::setBirthdate &request); + + void on_request(uint64 id, const td_api::setPersonalChat &request); + + void on_request(uint64 id, const td_api::setEmojiStatus &request); + + void on_request(uint64 id, const td_api::toggleHasSponsoredMessagesEnabled &request); + + void on_request(uint64 id, const td_api::getThemedEmojiStatuses &request); + + void on_request(uint64 id, const td_api::getThemedChatEmojiStatuses &request); + + void on_request(uint64 id, const td_api::getDefaultEmojiStatuses &request); + + void on_request(uint64 id, const td_api::getDefaultChatEmojiStatuses &request); + + void on_request(uint64 id, const td_api::getRecentEmojiStatuses &request); + + void on_request(uint64 id, const td_api::clearRecentEmojiStatuses &request); + + void on_request(uint64 id, td_api::setCommands &request); + + void on_request(uint64 id, td_api::deleteCommands &request); + + void on_request(uint64 id, td_api::getCommands &request); + + void on_request(uint64 id, td_api::setMenuButton &request); + + void on_request(uint64 id, const td_api::getMenuButton &request); + + void on_request(uint64 id, const td_api::setDefaultGroupAdministratorRights &request); + + void on_request(uint64 id, const td_api::setDefaultChannelAdministratorRights &request); + + void on_request(uint64 id, const td_api::canBotSendMessages &request); + + void on_request(uint64 id, const td_api::allowBotToSendMessages &request); + + void on_request(uint64 id, td_api::sendWebAppCustomRequest &request); + + void on_request(uint64 id, const td_api::getBotMediaPreviews &request); + + void on_request(uint64 id, const td_api::getBotMediaPreviewInfo &request); + + void on_request(uint64 id, td_api::addBotMediaPreview &request); + + void on_request(uint64 id, td_api::editBotMediaPreview &request); + + void on_request(uint64 id, const td_api::reorderBotMediaPreviews &request); + + void on_request(uint64 id, const td_api::deleteBotMediaPreviews &request); + + void on_request(uint64 id, td_api::setBotName &request); + + void on_request(uint64 id, const td_api::getBotName &request); + + void on_request(uint64 id, td_api::setBotProfilePhoto &request); + + void on_request(uint64 id, td_api::toggleBotUsernameIsActive &request); + + void on_request(uint64 id, td_api::reorderBotActiveUsernames &request); + + void on_request(uint64 id, td_api::setBotInfoDescription &request); + + void on_request(uint64 id, const td_api::getBotInfoDescription &request); + + void on_request(uint64 id, td_api::setBotInfoShortDescription &request); + + void on_request(uint64 id, const td_api::getBotInfoShortDescription &request); + + void on_request(uint64 id, const td_api::setLocation &request); + + void on_request(uint64 id, td_api::setBusinessLocation &request); + + void on_request(uint64 id, td_api::setBusinessOpeningHours &request); + + void on_request(uint64 id, td_api::setBusinessGreetingMessageSettings &request); + + void on_request(uint64 id, td_api::setBusinessAwayMessageSettings &request); + + void on_request(uint64 id, td_api::setBusinessStartPage &request); + + void on_request(uint64 id, td_api::setProfilePhoto &request); + + void on_request(uint64 id, const td_api::deleteProfilePhoto &request); + + void on_request(uint64 id, const td_api::getUserProfilePhotos &request); + + void on_request(uint64 id, const td_api::setAccentColor &request); + + void on_request(uint64 id, const td_api::setProfileAccentColor &request); + + void on_request(uint64 id, const td_api::getBusinessConnectedBot &request); + + void on_request(uint64 id, td_api::setBusinessConnectedBot &request); + + void on_request(uint64 id, const td_api::deleteBusinessConnectedBot &request); + + void on_request(uint64 id, const td_api::toggleBusinessConnectedBotChatIsPaused &request); + + void on_request(uint64 id, const td_api::removeBusinessConnectedBotFromChat &request); + + void on_request(uint64 id, const td_api::getBusinessChatLinks &request); + + void on_request(uint64 id, td_api::createBusinessChatLink &request); + + void on_request(uint64 id, td_api::editBusinessChatLink &request); + + void on_request(uint64 id, td_api::deleteBusinessChatLink &request); + + void on_request(uint64 id, td_api::getBusinessChatLinkInfo &request); + + void on_request(uint64 id, td_api::setSupergroupUsername &request); + + void on_request(uint64 id, td_api::toggleSupergroupUsernameIsActive &request); + + void on_request(uint64 id, const td_api::disableAllSupergroupUsernames &request); + + void on_request(uint64 id, td_api::reorderSupergroupActiveUsernames &request); + + void on_request(uint64 id, const td_api::setSupergroupStickerSet &request); + + void on_request(uint64 id, const td_api::setSupergroupCustomEmojiStickerSet &request); + + void on_request(uint64 id, const td_api::setSupergroupUnrestrictBoostCount &request); + + void on_request(uint64 id, const td_api::toggleSupergroupSignMessages &request); + + void on_request(uint64 id, const td_api::toggleSupergroupJoinToSendMessages &request); + + void on_request(uint64 id, const td_api::toggleSupergroupJoinByRequest &request); + + void on_request(uint64 id, const td_api::toggleSupergroupIsAllHistoryAvailable &request); + + void on_request(uint64 id, const td_api::toggleSupergroupCanHaveSponsoredMessages &request); + + void on_request(uint64 id, const td_api::toggleSupergroupHasHiddenMembers &request); + + void on_request(uint64 id, const td_api::toggleSupergroupHasAggressiveAntiSpamEnabled &request); + + void on_request(uint64 id, const td_api::toggleSupergroupIsForum &request); + + void on_request(uint64 id, const td_api::toggleSupergroupIsBroadcastGroup &request); + + void on_request(uint64 id, const td_api::reportSupergroupSpam &request); + + void on_request(uint64 id, const td_api::reportSupergroupAntiSpamFalsePositive &request); + + void on_request(uint64 id, td_api::getSupergroupMembers &request); + + void on_request(uint64 id, td_api::closeSecretChat &request); + + void on_request(uint64 id, td_api::getStickers &request); + + void on_request(uint64 id, td_api::getAllStickerEmojis &request); + + void on_request(uint64 id, td_api::searchStickers &request); + + void on_request(uint64 id, const td_api::getGreetingStickers &request); + + void on_request(uint64 id, const td_api::getPremiumStickers &request); + + void on_request(uint64 id, const td_api::getInstalledStickerSets &request); + + void on_request(uint64 id, const td_api::getArchivedStickerSets &request); + + void on_request(uint64 id, const td_api::getTrendingStickerSets &request); + + void on_request(uint64 id, const td_api::getAttachedStickerSets &request); + + void on_request(uint64 id, const td_api::getStickerSet &request); + + void on_request(uint64 id, const td_api::getStickerSetName &request); + + void on_request(uint64 id, td_api::searchStickerSet &request); + + void on_request(uint64 id, td_api::searchInstalledStickerSets &request); + + void on_request(uint64 id, td_api::searchStickerSets &request); + + void on_request(uint64 id, const td_api::changeStickerSet &request); + + void on_request(uint64 id, const td_api::viewTrendingStickerSets &request); + + void on_request(uint64 id, td_api::reorderInstalledStickerSets &request); + + void on_request(uint64 id, td_api::uploadStickerFile &request); + + void on_request(uint64 id, td_api::getSuggestedStickerSetName &request); + + void on_request(uint64 id, td_api::checkStickerSetName &request); + + void on_request(uint64 id, td_api::createNewStickerSet &request); + + void on_request(uint64 id, td_api::addStickerToSet &request); + + void on_request(uint64 id, td_api::replaceStickerInSet &request); + + void on_request(uint64 id, td_api::setStickerSetThumbnail &request); + + void on_request(uint64 id, td_api::setCustomEmojiStickerSetThumbnail &request); + + void on_request(uint64 id, td_api::setStickerSetTitle &request); + + void on_request(uint64 id, td_api::deleteStickerSet &request); + + void on_request(uint64 id, td_api::setStickerPositionInSet &request); + + void on_request(uint64 id, const td_api::removeStickerFromSet &request); + + void on_request(uint64 id, td_api::setStickerEmojis &request); + + void on_request(uint64 id, td_api::setStickerKeywords &request); + + void on_request(uint64 id, td_api::setStickerMaskPosition &request); + + void on_request(uint64 id, const td_api::getOwnedStickerSets &request); + + void on_request(uint64 id, const td_api::getRecentStickers &request); + + void on_request(uint64 id, td_api::addRecentSticker &request); + + void on_request(uint64 id, td_api::removeRecentSticker &request); + + void on_request(uint64 id, td_api::clearRecentStickers &request); + + void on_request(uint64 id, const td_api::getSavedAnimations &request); + + void on_request(uint64 id, td_api::addSavedAnimation &request); + + void on_request(uint64 id, td_api::removeSavedAnimation &request); + + void on_request(uint64 id, td_api::getStickerEmojis &request); + + void on_request(uint64 id, td_api::searchEmojis &request); + + void on_request(uint64 id, td_api::getKeywordEmojis &request); + + void on_request(uint64 id, const td_api::getEmojiCategories &request); + + void on_request(uint64 id, td_api::getAnimatedEmoji &request); + + void on_request(uint64 id, td_api::getEmojiSuggestionsUrl &request); + + void on_request(uint64 id, const td_api::getCustomEmojiStickers &request); + + void on_request(uint64 id, const td_api::getDefaultChatPhotoCustomEmojiStickers &request); + + void on_request(uint64 id, const td_api::getDefaultProfilePhotoCustomEmojiStickers &request); + + void on_request(uint64 id, const td_api::getDefaultBackgroundCustomEmojiStickers &request); + + void on_request(uint64 id, const td_api::getDisallowedChatEmojiStatuses &request); + + void on_request(uint64 id, const td_api::getFavoriteStickers &request); + + void on_request(uint64 id, td_api::addFavoriteSticker &request); + + void on_request(uint64 id, td_api::removeFavoriteSticker &request); + + void on_request(uint64 id, const td_api::getSavedNotificationSound &request); + + void on_request(uint64 id, const td_api::getSavedNotificationSounds &request); + + void on_request(uint64 id, td_api::addSavedNotificationSound &request); + + void on_request(uint64 id, const td_api::removeSavedNotificationSound &request); + + void on_request(uint64 id, const td_api::getChatNotificationSettingsExceptions &request); + + void on_request(uint64 id, const td_api::getScopeNotificationSettings &request); + + void on_request(uint64 id, td_api::setChatNotificationSettings &request); + + void on_request(uint64 id, td_api::setForumTopicNotificationSettings &request); + + void on_request(uint64 id, td_api::setScopeNotificationSettings &request); + + void on_request(uint64 id, td_api::setReactionNotificationSettings &request); + + void on_request(uint64 id, const td_api::resetAllNotificationSettings &request); + + void on_request(uint64 id, const td_api::removeChatActionBar &request); + + void on_request(uint64 id, td_api::reportChat &request); + + void on_request(uint64 id, td_api::reportChatPhoto &request); + + void on_request(uint64 id, const td_api::reportMessageReactions &request); + + void on_request(uint64 id, const td_api::getChatStatistics &request); + + void on_request(uint64 id, const td_api::getChatRevenueStatistics &request); + + void on_request(uint64 id, const td_api::getChatRevenueWithdrawalUrl &request); + + void on_request(uint64 id, const td_api::getChatRevenueTransactions &request); + + void on_request(uint64 id, const td_api::getStarRevenueStatistics &request); + + void on_request(uint64 id, const td_api::getStarWithdrawalUrl &request); + + void on_request(uint64 id, const td_api::getStarAdAccountUrl &request); + + void on_request(uint64 id, const td_api::getMessageStatistics &request); + + void on_request(uint64 id, const td_api::getStoryStatistics &request); + + void on_request(uint64 id, td_api::getStatisticalGraph &request); + + void on_request(uint64 id, const td_api::getMapThumbnailFile &request); + + void on_request(uint64 id, const td_api::getLocalizationTargetInfo &request); + + void on_request(uint64 id, td_api::getLanguagePackInfo &request); + + void on_request(uint64 id, td_api::getLanguagePackStrings &request); + + void on_request(uint64 id, td_api::synchronizeLanguagePack &request); + + void on_request(uint64 id, td_api::addCustomServerLanguagePack &request); + + void on_request(uint64 id, td_api::setCustomLanguagePack &request); + + void on_request(uint64 id, td_api::editCustomLanguagePackInfo &request); + + void on_request(uint64 id, td_api::setCustomLanguagePackString &request); + + void on_request(uint64 id, td_api::deleteLanguagePack &request); + + void on_request(uint64 id, td_api::getOption &request); + + void on_request(uint64 id, td_api::setOption &request); + + void on_request(uint64 id, td_api::setPollAnswer &request); + + void on_request(uint64 id, td_api::getPollVoters &request); + + void on_request(uint64 id, td_api::stopPoll &request); + + void on_request(uint64 id, const td_api::hideSuggestedAction &request); + + void on_request(uint64 id, const td_api::hideContactCloseBirthdays &request); + + void on_request(uint64 id, td_api::getBusinessConnection &request); + + void on_request(uint64 id, const td_api::getLoginUrlInfo &request); + + void on_request(uint64 id, const td_api::getLoginUrl &request); + + void on_request(uint64 id, const td_api::shareUsersWithBot &request); + + void on_request(uint64 id, const td_api::shareChatWithBot &request); + + void on_request(uint64 id, td_api::getInlineQueryResults &request); + + void on_request(uint64 id, td_api::answerInlineQuery &request); + + void on_request(uint64 id, td_api::getGrossingWebAppBots &request); + + void on_request(uint64 id, td_api::searchWebApp &request); + + void on_request(uint64 id, td_api::getWebAppLinkUrl &request); + + void on_request(uint64 id, td_api::getMainWebApp &request); + + void on_request(uint64 id, td_api::getWebAppUrl &request); + + void on_request(uint64 id, td_api::sendWebAppData &request); + + void on_request(uint64 id, td_api::openWebApp &request); + + void on_request(uint64 id, const td_api::closeWebApp &request); + + void on_request(uint64 id, td_api::answerWebAppQuery &request); + + void on_request(uint64 id, td_api::getCallbackQueryAnswer &request); + + void on_request(uint64 id, td_api::answerCallbackQuery &request); + + void on_request(uint64 id, td_api::answerShippingQuery &request); + + void on_request(uint64 id, td_api::answerPreCheckoutQuery &request); + + void on_request(uint64 id, td_api::getBankCardInfo &request); + + void on_request(uint64 id, td_api::getPaymentForm &request); + + void on_request(uint64 id, td_api::validateOrderInfo &request); + + void on_request(uint64 id, td_api::sendPaymentForm &request); + + void on_request(uint64 id, const td_api::getPaymentReceipt &request); + + void on_request(uint64 id, const td_api::getSavedOrderInfo &request); + + void on_request(uint64 id, const td_api::deleteSavedOrderInfo &request); + + void on_request(uint64 id, const td_api::deleteSavedCredentials &request); + + void on_request(uint64 id, td_api::createInvoiceLink &request); + + void on_request(uint64 id, td_api::refundStarPayment &request); + + void on_request(uint64 id, td_api::getPassportElement &request); + + void on_request(uint64 id, td_api::getAllPassportElements &request); + + void on_request(uint64 id, td_api::setPassportElement &request); + + void on_request(uint64 id, const td_api::deletePassportElement &request); + + void on_request(uint64 id, td_api::setPassportElementErrors &request); + + void on_request(uint64 id, td_api::getPreferredCountryLanguage &request); + + void on_request(uint64 id, td_api::sendEmailAddressVerificationCode &request); + + void on_request(uint64 id, const td_api::resendEmailAddressVerificationCode &request); + + void on_request(uint64 id, td_api::checkEmailAddressVerificationCode &request); + + void on_request(uint64 id, td_api::getPassportAuthorizationForm &request); + + void on_request(uint64 id, td_api::getPassportAuthorizationFormAvailableElements &request); + + void on_request(uint64 id, td_api::sendPassportAuthorizationForm &request); + + void on_request(uint64 id, const td_api::getSupportUser &request); + + void on_request(uint64 id, const td_api::getInstalledBackgrounds &request); + + void on_request(uint64 id, td_api::getBackgroundUrl &request); + + void on_request(uint64 id, td_api::searchBackground &request); + + void on_request(uint64 id, td_api::setDefaultBackground &request); + + void on_request(uint64 id, const td_api::deleteDefaultBackground &request); + + void on_request(uint64 id, const td_api::removeInstalledBackground &request); + + void on_request(uint64 id, const td_api::resetInstalledBackgrounds &request); + + void on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request); + + void on_request(uint64 id, td_api::setBotUpdatesStatus &request); + + void on_request(uint64 id, td_api::sendCustomRequest &request); + + void on_request(uint64 id, td_api::answerCustomQuery &request); + + void on_request(uint64 id, const td_api::setAlarm &request); + + void on_request(uint64 id, td_api::searchHashtags &request); + + void on_request(uint64 id, td_api::removeRecentHashtag &request); + + void on_request(uint64 id, const td_api::getPremiumLimit &request); + + void on_request(uint64 id, const td_api::getPremiumFeatures &request); + + void on_request(uint64 id, const td_api::getPremiumStickerExamples &request); + + void on_request(uint64 id, const td_api::viewPremiumFeature &request); + + void on_request(uint64 id, const td_api::clickPremiumSubscriptionButton &request); + + void on_request(uint64 id, const td_api::getPremiumState &request); + + void on_request(uint64 id, const td_api::getPremiumGiftCodePaymentOptions &request); + + void on_request(uint64 id, td_api::checkPremiumGiftCode &request); + + void on_request(uint64 id, td_api::applyPremiumGiftCode &request); + + void on_request(uint64 id, td_api::launchPrepaidGiveaway &request); + + void on_request(uint64 id, const td_api::getGiveawayInfo &request); + + void on_request(uint64 id, const td_api::getStarPaymentOptions &request); + + void on_request(uint64 id, const td_api::getStarGiftPaymentOptions &request); + + void on_request(uint64 id, const td_api::getStarGiveawayPaymentOptions &request); + + void on_request(uint64 id, td_api::getStarTransactions &request); + + void on_request(uint64 id, td_api::getStarSubscriptions &request); + + void on_request(uint64 id, td_api::editStarSubscription &request); + + void on_request(uint64 id, td_api::reuseStarSubscription &request); + + void on_request(uint64 id, td_api::canPurchaseFromStore &request); + + void on_request(uint64 id, td_api::assignAppStoreTransaction &request); + + void on_request(uint64 id, td_api::assignGooglePlayTransaction &request); + + void on_request(uint64 id, const td_api::getBusinessFeatures &request); + + void on_request(uint64 id, td_api::acceptTermsOfService &request); + + void on_request(uint64 id, const td_api::getCountries &request); + + void on_request(uint64 id, const td_api::getCountryCode &request); + + void on_request(uint64 id, const td_api::getPhoneNumberInfo &request); + + void on_request(uint64 id, td_api::getCollectibleItemInfo &request); + + void on_request(uint64 id, const td_api::getApplicationDownloadLink &request); + + void on_request(uint64 id, td_api::getDeepLinkInfo &request); + + void on_request(uint64 id, const td_api::getApplicationConfig &request); + + void on_request(uint64 id, td_api::saveApplicationLogEvent &request); + + void on_request(uint64 id, td_api::addProxy &request); + + void on_request(uint64 id, td_api::editProxy &request); + + void on_request(uint64 id, const td_api::enableProxy &request); + + void on_request(uint64 id, const td_api::disableProxy &request); + + void on_request(uint64 id, const td_api::removeProxy &request); + + void on_request(uint64 id, const td_api::getProxies &request); + + void on_request(uint64 id, const td_api::getProxyLink &request); + + void on_request(uint64 id, const td_api::pingProxy &request); + + void on_request(uint64 id, const td_api::getUserSupportInfo &request); + + void on_request(uint64 id, td_api::setUserSupportInfo &request); + + void on_request(uint64 id, const td_api::getSupportName &request); + + void on_request(uint64 id, const td_api::searchQuote &request); + + void on_request(uint64 id, const td_api::getTextEntities &request); + + void on_request(uint64 id, const td_api::parseTextEntities &request); + + void on_request(uint64 id, const td_api::parseMarkdown &request); + + void on_request(uint64 id, const td_api::getMarkdownText &request); + + void on_request(uint64 id, const td_api::searchStringsByPrefix &request); + + void on_request(uint64 id, const td_api::checkQuickReplyShortcutName &request); + + void on_request(uint64 id, const td_api::getCountryFlagEmoji &request); + + void on_request(uint64 id, const td_api::getFileMimeType &request); + + void on_request(uint64 id, const td_api::getFileExtension &request); + + void on_request(uint64 id, const td_api::cleanFileName &request); + + void on_request(uint64 id, const td_api::getLanguagePackString &request); + + void on_request(uint64 id, const td_api::getPhoneNumberInfoSync &request); + + void on_request(uint64 id, const td_api::getPushReceiverId &request); + + void on_request(uint64 id, const td_api::getChatFolderDefaultIconName &request); + + void on_request(uint64 id, const td_api::getJsonValue &request); + + void on_request(uint64 id, const td_api::getJsonString &request); + + void on_request(uint64 id, const td_api::getThemeParametersJsonString &request); + + void on_request(uint64 id, const td_api::setLogStream &request); + + void on_request(uint64 id, const td_api::getLogStream &request); + + void on_request(uint64 id, const td_api::setLogVerbosityLevel &request); + + void on_request(uint64 id, const td_api::getLogVerbosityLevel &request); + + void on_request(uint64 id, const td_api::getLogTags &request); + + void on_request(uint64 id, const td_api::setLogTagVerbosityLevel &request); + + void on_request(uint64 id, const td_api::getLogTagVerbosityLevel &request); + + void on_request(uint64 id, const td_api::addLogMessage &request); + + void on_request(uint64 id, const td_api::testNetwork &request); + + void on_request(uint64 id, td_api::testProxy &request); + + void on_request(uint64 id, const td_api::testGetDifference &request); + + void on_request(uint64 id, const td_api::testUseUpdate &request); + + void on_request(uint64 id, const td_api::testReturnError &request); + + void on_request(uint64 id, const td_api::testCallEmpty &request); + + void on_request(uint64 id, const td_api::testSquareInt &request); + + void on_request(uint64 id, td_api::testCallString &request); + + void on_request(uint64 id, td_api::testCallBytes &request); + + void on_request(uint64 id, td_api::testCallVectorInt &request); + + void on_request(uint64 id, td_api::testCallVectorIntObject &request); + + void on_request(uint64 id, td_api::testCallVectorString &request); + + void on_request(uint64 id, td_api::testCallVectorStringObject &request); +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/RestrictionReason.cpp b/protocols/Telegram/tdlib/td/td/telegram/RestrictionReason.cpp index 084f06276e..c187a70bda 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/RestrictionReason.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/RestrictionReason.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -16,9 +16,9 @@ namespace td { -string get_restriction_reason_description(const vector &restriction_reasons) { +const RestrictionReason *get_restriction_reason(const vector &restriction_reasons, bool sensitive) { if (restriction_reasons.empty()) { - return string(); + return nullptr; } auto ignored_restriction_reasons = full_split(G()->get_option_string("ignored_restriction_reasons"), ','); @@ -44,8 +44,9 @@ string get_restriction_reason_description(const vector &restr // first find restriction for the current platform for (auto &restriction_reason : restriction_reasons) { if (restriction_reason.platform_ == platform && - !td::contains(ignored_restriction_reasons, restriction_reason.reason_)) { - return restriction_reason.description_; + !td::contains(ignored_restriction_reasons, restriction_reason.reason_) && + restriction_reason.is_sensitive() == sensitive) { + return &restriction_reason; } } } @@ -54,8 +55,9 @@ string get_restriction_reason_description(const vector &restr // then find restriction for added platforms for (auto &restriction_reason : restriction_reasons) { if (td::contains(restriction_add_platforms, restriction_reason.platform_) && - !td::contains(ignored_restriction_reasons, restriction_reason.reason_)) { - return restriction_reason.description_; + !td::contains(ignored_restriction_reasons, restriction_reason.reason_) && + restriction_reason.is_sensitive() == sensitive) { + return &restriction_reason; } } } @@ -63,12 +65,25 @@ string get_restriction_reason_description(const vector &restr // then find restriction for all platforms for (auto &restriction_reason : restriction_reasons) { if (restriction_reason.platform_ == "all" && - !td::contains(ignored_restriction_reasons, restriction_reason.reason_)) { - return restriction_reason.description_; + !td::contains(ignored_restriction_reasons, restriction_reason.reason_) && + restriction_reason.is_sensitive() == sensitive) { + return &restriction_reason; } } - return string(); + return nullptr; +} + +bool get_restriction_reason_has_sensitive_content(const vector &restriction_reasons) { + return get_restriction_reason(restriction_reasons, true) != nullptr; +} + +string get_restriction_reason_description(const vector &restriction_reasons) { + const auto *restriction_reason = get_restriction_reason(restriction_reasons, false); + if (restriction_reason == nullptr) { + return string(); + } + return restriction_reason->description_; } vector get_restriction_reasons(Slice legacy_restriction_reason) { diff --git a/protocols/Telegram/tdlib/td/td/telegram/RestrictionReason.h b/protocols/Telegram/tdlib/td/td/telegram/RestrictionReason.h index 4eff9abb69..391a0983c6 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/RestrictionReason.h +++ b/protocols/Telegram/tdlib/td/td/telegram/RestrictionReason.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -29,8 +29,15 @@ class RestrictionReason { return lhs.platform_ == rhs.platform_ && lhs.reason_ == rhs.reason_ && lhs.description_ == rhs.description_; } + friend const RestrictionReason *get_restriction_reason(const vector &restriction_reasons, + bool sensitive); + friend string get_restriction_reason_description(const vector &restriction_reasons); + bool is_sensitive() const { + return reason_ == "sensitive"; + } + public: RestrictionReason() = default; @@ -60,6 +67,8 @@ inline bool operator!=(const RestrictionReason &lhs, const RestrictionReason &rh return !(lhs == rhs); } +bool get_restriction_reason_has_sensitive_content(const vector &restriction_reasons); + string get_restriction_reason_description(const vector &restriction_reasons); vector get_restriction_reasons(Slice legacy_restriction_reason); diff --git a/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesManager.cpp new file mode 100644 index 0000000000..d9dad76b16 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesManager.cpp @@ -0,0 +1,1053 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/SavedMessagesManager.h" + +#include "td/telegram/AffectedHistory.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/FlatHashSet.h" +#include "td/utils/format.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" + +#include + +namespace td { + +class GetPinnedSavedDialogsQuery final : public Td::ResultHandler { + Promise promise_; + int32 limit_; + + public: + explicit GetPinnedSavedDialogsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(int32 limit) { + limit_ = limit; + send_query(G()->net_query_creator().create(telegram_api::messages_getPinnedSavedDialogs())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetPinnedSavedDialogsQuery: " << to_string(result); + td_->saved_messages_manager_->on_get_saved_messages_topics(true, limit_, std::move(result), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetSavedDialogsQuery final : public Td::ResultHandler { + Promise promise_; + int32 limit_; + + public: + explicit GetSavedDialogsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(int32 offset_date, MessageId offset_message_id, DialogId offset_dialog_id, int32 limit) { + limit_ = limit; + auto input_peer = DialogManager::get_input_peer_force(offset_dialog_id); + CHECK(input_peer != nullptr); + + int32 flags = telegram_api::messages_getSavedDialogs::EXCLUDE_PINNED_MASK; + send_query(G()->net_query_creator().create(telegram_api::messages_getSavedDialogs( + flags, false /*ignored*/, offset_date, offset_message_id.get_server_message_id().get(), std::move(input_peer), + limit, 0))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetSavedDialogsQuery: " << to_string(result); + td_->saved_messages_manager_->on_get_saved_messages_topics(false, limit_, std::move(result), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetSavedHistoryQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetSavedHistoryQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, int32 offset, int32 limit) { + auto saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + send_query(G()->net_query_creator().create(telegram_api::messages_getSavedHistory( + std::move(saved_input_peer), from_message_id.get_server_message_id().get(), 0, offset, limit, 0, 0, 0))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + auto info = get_messages_info(td_, my_dialog_id, result_ptr.move_as_ok(), "GetSavedHistoryQuery"); + LOG_IF(ERROR, info.is_channel_messages) << "Receive channel messages in GetSavedHistoryQuery"; + promise_.set_value(std::move(info)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetSavedMessageByDateQuery final : public Td::ResultHandler { + Promise> promise_; + int32 date_ = 0; + + public: + explicit GetSavedMessageByDateQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(SavedMessagesTopicId saved_messages_topic_id, int32 date) { + date_ = date; + auto saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + + send_query(G()->net_query_creator().create( + telegram_api::messages_getSavedHistory(std::move(saved_input_peer), 0, date, -3, 5, 0, 0, 0))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + auto info = get_messages_info(td_, my_dialog_id, result_ptr.move_as_ok(), "GetSavedMessageByDateQuery"); + LOG_IF(ERROR, info.is_channel_messages) << "Receive channel messages in GetSavedMessageByDateQuery"; + for (auto &message : info.messages) { + auto message_date = MessagesManager::get_message_date(message); + auto message_dialog_id = DialogId::get_message_dialog_id(message); + if (message_dialog_id != my_dialog_id) { + LOG(ERROR) << "Receive message in wrong " << message_dialog_id << " instead of " << my_dialog_id; + continue; + } + if (message_date != 0 && message_date <= date_) { + auto message_full_id = td_->messages_manager_->on_get_message(std::move(message), false, false, false, + "GetSavedMessageByDateQuery"); + if (message_full_id != MessageFullId()) { + return promise_.set_value( + td_->messages_manager_->get_message_object(message_full_id, "GetSavedMessageByDateQuery")); + } + } + } + promise_.set_value(nullptr); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class DeleteSavedHistoryQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit DeleteSavedHistoryQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(SavedMessagesTopicId saved_messages_topic_id) { + auto saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + + int32 flags = 0; + send_query(G()->net_query_creator().create(telegram_api::messages_deleteSavedHistory( + flags, std::move(saved_input_peer), std::numeric_limits::max(), 0, 0))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(AffectedHistory(result_ptr.move_as_ok())); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class DeleteSavedMessagesByDateQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit DeleteSavedMessagesByDateQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(SavedMessagesTopicId saved_messages_topic_id, int32 min_date, int32 max_date) { + auto saved_input_peer = saved_messages_topic_id.get_input_peer(td_); + CHECK(saved_input_peer != nullptr); + + int32 flags = + telegram_api::messages_deleteHistory::MIN_DATE_MASK | telegram_api::messages_deleteHistory::MAX_DATE_MASK; + + send_query(G()->net_query_creator().create( + telegram_api::messages_deleteSavedHistory(flags, std::move(saved_input_peer), 0, min_date, max_date))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(AffectedHistory(result_ptr.move_as_ok())); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class ToggleSavedDialogPinQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ToggleSavedDialogPinQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(SavedMessagesTopicId saved_messages_topic_id, bool is_pinned) { + auto saved_input_peer = saved_messages_topic_id.get_input_dialog_peer(td_); + CHECK(saved_input_peer != nullptr); + + int32 flags = 0; + if (is_pinned) { + flags |= telegram_api::messages_toggleSavedDialogPin::PINNED_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::messages_toggleSavedDialogPin(flags, false /*ignored*/, std::move(saved_input_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->saved_messages_manager_->reload_pinned_saved_messages_topics(); + promise_.set_error(std::move(status)); + } +}; + +class ReorderPinnedSavedDialogsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ReorderPinnedSavedDialogsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const vector &saved_messages_topic_ids) { + auto order = transform(saved_messages_topic_ids, [td = td_](SavedMessagesTopicId saved_messages_topic_id) { + auto saved_input_peer = saved_messages_topic_id.get_input_dialog_peer(td); + CHECK(saved_input_peer != nullptr); + return saved_input_peer; + }); + int32 flags = telegram_api::messages_reorderPinnedSavedDialogs::FORCE_MASK; + send_query(G()->net_query_creator().create( + telegram_api::messages_reorderPinnedSavedDialogs(flags, true /*ignored*/, std::move(order)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.move_as_ok(); + if (!result) { + return on_error(Status::Error(400, "Result is false")); + } + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->saved_messages_manager_->reload_pinned_saved_messages_topics(); + promise_.set_error(std::move(status)); + } +}; + +SavedMessagesManager::SavedMessagesManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void SavedMessagesManager::tear_down() { + parent_.reset(); +} + +SavedMessagesTopicId SavedMessagesManager::get_topic_id(int64 topic_id) const { + if (topic_id == 0) { + return SavedMessagesTopicId(); + } + auto saved_messages_topic_id = SavedMessagesTopicId(DialogId(topic_id)); + if (saved_messages_topics_.count(saved_messages_topic_id) == 0) { + return SavedMessagesTopicId(DialogId(std::numeric_limits::max())); // an invalid topic identifier + } + return saved_messages_topic_id; +} + +vector SavedMessagesManager::get_topic_ids(const vector &topic_ids) const { + return transform(topic_ids, [this](int64 topic_id) { return get_topic_id(topic_id); }); +} + +int64 SavedMessagesManager::get_saved_messages_topic_id_object(SavedMessagesTopicId saved_messages_topic_id) { + if (saved_messages_topic_id == SavedMessagesTopicId()) { + return 0; + } + + add_topic(saved_messages_topic_id); + + return saved_messages_topic_id.get_unique_id(); +} + +SavedMessagesManager::SavedMessagesTopic *SavedMessagesManager::get_topic( + SavedMessagesTopicId saved_messages_topic_id) { + CHECK(saved_messages_topic_id.is_valid()); + auto it = saved_messages_topics_.find(saved_messages_topic_id); + if (it == saved_messages_topics_.end()) { + return nullptr; + } + return it->second.get(); +} + +SavedMessagesManager::SavedMessagesTopic *SavedMessagesManager::add_topic( + SavedMessagesTopicId saved_messages_topic_id) { + CHECK(saved_messages_topic_id.is_valid()); + auto &result = saved_messages_topics_[saved_messages_topic_id]; + if (result == nullptr) { + result = make_unique(); + result->saved_messages_topic_id_ = saved_messages_topic_id; + if (saved_messages_topic_id == SavedMessagesTopicId(td_->dialog_manager_->get_my_dialog_id())) { + auto draft_message_object = td_->messages_manager_->get_my_dialog_draft_message_object(); + if (draft_message_object != nullptr) { + result->draft_message_date_ = draft_message_object->date_; + } + } + send_update_saved_messages_topic(result.get(), "add_topic"); + } + return result.get(); +} + +void SavedMessagesManager::set_topic_last_message_id(SavedMessagesTopicId saved_messages_topic_id, + MessageId last_message_id, int32 last_message_date) { + auto *topic = add_topic(saved_messages_topic_id); + do_set_topic_last_message_id(topic, last_message_id, last_message_date); + on_topic_changed(topic, "set_topic_last_message_id"); +} + +void SavedMessagesManager::do_set_topic_last_message_id(SavedMessagesTopic *topic, MessageId last_message_id, + int32 last_message_date) { + if (topic->last_message_id_ == last_message_id) { + return; + } + + CHECK(last_message_id == MessageId() || last_message_id.is_valid()); + LOG(INFO) << "Set last message in " << topic->saved_messages_topic_id_ << " to " << last_message_id; + topic->last_message_id_ = last_message_id; + topic->last_message_date_ = last_message_date; + topic->is_changed_ = true; +} + +void SavedMessagesManager::on_topic_message_updated(SavedMessagesTopicId saved_messages_topic_id, + MessageId message_id) { + auto *topic = get_topic(saved_messages_topic_id); + if (topic == nullptr || topic->last_message_id_ != message_id) { + return; + } + + send_update_saved_messages_topic(topic, "on_topic_message_updated"); +} + +void SavedMessagesManager::on_topic_message_deleted(SavedMessagesTopicId saved_messages_topic_id, + MessageId message_id) { + auto *topic = get_topic(saved_messages_topic_id); + if (topic == nullptr || topic->last_message_id_ != message_id) { + return; + } + + do_set_topic_last_message_id(topic, MessageId(), 0); + + on_topic_changed(topic, "on_topic_message_deleted"); + + get_saved_messages_topic_history(saved_messages_topic_id, MessageId(), 0, 1, Auto()); +} + +void SavedMessagesManager::on_topic_draft_message_updated(SavedMessagesTopicId saved_messages_topic_id, + int32 draft_message_date) { + auto *topic = get_topic(saved_messages_topic_id); + if (topic == nullptr) { + LOG(INFO) << "Updated draft in unknown " << saved_messages_topic_id; + return; + } + + LOG(INFO) << "Set draft message date in " << topic->saved_messages_topic_id_ << " to " << draft_message_date; + topic->draft_message_date_ = draft_message_date; + topic->is_changed_ = true; + + on_topic_changed(topic, "on_topic_draft_message_updated"); +} + +int64 SavedMessagesManager::get_topic_order(int32 message_date, MessageId message_id) { + return (static_cast(message_date) << 31) + + message_id.get_prev_server_message_id().get_server_message_id().get(); +} + +int64 SavedMessagesManager::get_topic_public_order(const SavedMessagesTopic *topic) const { + if (TopicDate(topic->private_order_, topic->saved_messages_topic_id_) <= topic_list_.last_topic_date_) { + return topic->private_order_; + } + return 0; +} + +void SavedMessagesManager::on_topic_changed(SavedMessagesTopic *topic, const char *source) { + CHECK(topic != nullptr); + if (!topic->is_changed_) { + return; + } + topic->is_changed_ = false; + + int64 new_private_order; + if (topic->pinned_order_ != 0) { + new_private_order = topic->pinned_order_; + } else if (topic->last_message_id_ != MessageId()) { + new_private_order = get_topic_order(topic->last_message_date_, topic->last_message_id_); + } else { + new_private_order = 0; + } + if (topic->draft_message_date_ != 0) { + int64 draft_order = get_topic_order(topic->draft_message_date_, MessageId()); + if (new_private_order < draft_order) { + new_private_order = draft_order; + } + } + if (topic->private_order_ != new_private_order) { + if (topic->private_order_ != 0) { + bool is_deleted = topic_list_.ordered_topics_.erase({topic->private_order_, topic->saved_messages_topic_id_}) > 0; + CHECK(is_deleted); + if (topic_list_.server_total_count_ > 0) { + topic_list_.server_total_count_--; + } + } + topic->private_order_ = new_private_order; + if (topic->private_order_ != 0) { + bool is_inserted = + topic_list_.ordered_topics_.insert({topic->private_order_, topic->saved_messages_topic_id_}).second; + CHECK(is_inserted); + if (topic_list_.server_total_count_ >= 0) { + topic_list_.server_total_count_++; + } + } + } + LOG(INFO) << "Update order of " << topic->saved_messages_topic_id_ << " to " << topic->private_order_ << " from " + << source; + + send_update_saved_messages_topic(topic, source); + + update_saved_messages_topic_sent_total_count(source); +} + +void SavedMessagesManager::load_saved_messages_topics(int32 limit, Promise &&promise) { + if (limit < 0) { + return promise.set_error(Status::Error(400, "Limit must be non-negative")); + } + if (limit == 0) { + return promise.set_value(Unit()); + } + if (topic_list_.last_topic_date_ == MAX_TOPIC_DATE) { + return promise.set_error(Status::Error(404, "Not Found")); + } + if (!topic_list_.are_pinned_saved_messages_topics_inited_) { + return get_pinned_saved_dialogs(limit, std::move(promise)); + } + get_saved_dialogs(limit, std::move(promise)); +} + +void SavedMessagesManager::get_pinned_saved_dialogs(int32 limit, Promise &&promise) { + topic_list_.load_pinned_queries_.push_back(std::move(promise)); + if (topic_list_.load_pinned_queries_.size() == 1) { + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this)](Result &&result) { + send_closure(actor_id, &SavedMessagesManager::on_get_pinned_saved_dialogs, std::move(result)); + }); + td_->create_handler(std::move(query_promise))->send(limit); + } +} + +void SavedMessagesManager::on_get_pinned_saved_dialogs(Result &&result) { + G()->ignore_result_if_closing(result); + if (result.is_error()) { + fail_promises(topic_list_.load_pinned_queries_, result.move_as_error()); + } else { + set_promises(topic_list_.load_pinned_queries_); + } +} + +void SavedMessagesManager::get_saved_dialogs(int32 limit, Promise &&promise) { + topic_list_.load_queries_.push_back(std::move(promise)); + if (topic_list_.load_queries_.size() == 1) { + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this)](Result &&result) { + send_closure(actor_id, &SavedMessagesManager::on_get_saved_dialogs, std::move(result)); + }); + td_->create_handler(std::move(query_promise)) + ->send(topic_list_.offset_date_, topic_list_.offset_message_id_, topic_list_.offset_dialog_id_, limit); + } +} + +void SavedMessagesManager::on_get_saved_dialogs(Result &&result) { + G()->ignore_result_if_closing(result); + if (result.is_error()) { + fail_promises(topic_list_.load_queries_, result.move_as_error()); + } else { + set_promises(topic_list_.load_queries_); + } +} + +void SavedMessagesManager::on_get_saved_messages_topics( + bool is_pinned, int32 limit, telegram_api::object_ptr &&saved_dialogs_ptr, + Promise &&promise) { + CHECK(saved_dialogs_ptr != nullptr); + int32 total_count = -1; + vector> dialogs; + vector> messages; + vector> chats; + vector> users; + bool is_last = false; + switch (saved_dialogs_ptr->get_id()) { + case telegram_api::messages_savedDialogsNotModified::ID: + LOG(ERROR) << "Receive messages.savedDialogsNotModified"; + return promise.set_error(Status::Error(500, "Receive messages.savedDialogsNotModified")); + case telegram_api::messages_savedDialogs::ID: { + auto saved_dialogs = telegram_api::move_object_as(saved_dialogs_ptr); + total_count = static_cast(saved_dialogs->dialogs_.size()); + dialogs = std::move(saved_dialogs->dialogs_); + messages = std::move(saved_dialogs->messages_); + chats = std::move(saved_dialogs->chats_); + users = std::move(saved_dialogs->users_); + is_last = true; + break; + } + case telegram_api::messages_savedDialogsSlice::ID: { + auto saved_dialogs = telegram_api::move_object_as(saved_dialogs_ptr); + total_count = saved_dialogs->count_; + if (total_count < static_cast(saved_dialogs->dialogs_.size())) { + LOG(ERROR) << "Receive total_count = " << total_count << ", but " << saved_dialogs->dialogs_.size() + << " Saved Messages topics"; + total_count = static_cast(saved_dialogs->dialogs_.size()); + } + dialogs = std::move(saved_dialogs->dialogs_); + messages = std::move(saved_dialogs->messages_); + chats = std::move(saved_dialogs->chats_); + users = std::move(saved_dialogs->users_); + is_last = dialogs.empty(); + break; + } + default: + UNREACHABLE(); + } + td_->user_manager_->on_get_users(std::move(users), "on_get_saved_messages_topics"); + td_->chat_manager_->on_get_chats(std::move(chats), "on_get_saved_messages_topics"); + + FlatHashMap, MessageIdHash> message_id_to_message; + for (auto &message : messages) { + auto message_id = MessageId::get_message_id(message, false); + if (!message_id.is_valid()) { + continue; + } + message_id_to_message[message_id] = std::move(message); + } + + int32 last_message_date = 0; + MessageId last_message_id; + DialogId last_dialog_id; + vector added_saved_messages_topic_ids; + for (auto &dialog : dialogs) { + auto peer_dialog_id = DialogId(dialog->peer_); + if (!peer_dialog_id.is_valid()) { + LOG(ERROR) << "Receive " << peer_dialog_id << " in result of getSavedMessagesTopics"; + total_count--; + continue; + } + SavedMessagesTopicId saved_messages_topic_id(peer_dialog_id); + if (td::contains(added_saved_messages_topic_ids, saved_messages_topic_id)) { + LOG(ERROR) << "Receive " << saved_messages_topic_id + << " twice in result of getSavedMessagesTopics with total_count = " << total_count; + total_count--; + continue; + } + added_saved_messages_topic_ids.push_back(saved_messages_topic_id); + + MessageId last_topic_message_id(ServerMessageId(dialog->top_message_)); + if (!last_topic_message_id.is_valid()) { + // skip topics without messages + LOG(ERROR) << "Receive " << saved_messages_topic_id << " without last message"; + total_count--; + continue; + } + + auto it = message_id_to_message.find(last_topic_message_id); + if (it == message_id_to_message.end()) { + LOG(ERROR) << "Can't find last " << last_topic_message_id << " in " << saved_messages_topic_id; + total_count--; + continue; + } + auto message_date = MessagesManager::get_message_date(it->second); + if (!is_pinned && message_date > 0) { + if (last_message_date != 0 && (last_message_date < message_date || last_message_id < last_topic_message_id)) { + LOG(ERROR) << "Receive " << last_topic_message_id << " at " << message_date << " after " << last_message_id + << " at " << last_message_date; + } + last_message_date = message_date; + last_message_id = last_topic_message_id; + last_dialog_id = peer_dialog_id; + } + auto full_message_id = td_->messages_manager_->on_get_message(std::move(it->second), false, false, false, + "on_get_saved_messages_topics"); + message_id_to_message.erase(it); + + if (full_message_id.get_dialog_id() != td_->dialog_manager_->get_my_dialog_id()) { + if (full_message_id.get_dialog_id() != DialogId()) { + LOG(ERROR) << "Can't add last " << last_topic_message_id << " to " << saved_messages_topic_id; + } + total_count--; + continue; + } + CHECK(full_message_id.get_message_id() == last_topic_message_id); + + auto *topic = add_topic(saved_messages_topic_id); + if (topic->last_message_id_ == MessageId()) { + do_set_topic_last_message_id(topic, last_topic_message_id, message_date); + } + on_topic_changed(topic, "on_get_saved_messages_topics"); + } + + if (!is_pinned) { + topic_list_.server_total_count_ = total_count; + + topic_list_.offset_date_ = last_message_date; + topic_list_.offset_dialog_id_ = last_dialog_id; + topic_list_.offset_message_id_ = last_message_id; + } else if (topic_list_.server_total_count_ <= total_count) { + topic_list_.server_total_count_ = total_count + 1; + } + update_saved_messages_topic_sent_total_count("on_get_saved_messages_topics"); + + if (is_pinned) { + if (!topic_list_.are_pinned_saved_messages_topics_inited_ && total_count < limit) { + get_saved_dialogs(limit - total_count, std::move(promise)); + promise = Promise(); + } + topic_list_.are_pinned_saved_messages_topics_inited_ = true; + set_pinned_saved_messages_topics(std::move(added_saved_messages_topic_ids)); + set_last_topic_date({MIN_PINNED_TOPIC_ORDER - 1, SavedMessagesTopicId()}); + } else if (is_last) { + set_last_topic_date(MAX_TOPIC_DATE); + + if (dialogs.empty()) { + return promise.set_error(Status::Error(404, "Not Found")); + } + } else if (last_message_date > 0) { + set_last_topic_date({get_topic_order(last_message_date, last_message_id), SavedMessagesTopicId(last_dialog_id)}); + } else { + LOG(ERROR) << "Receive no suitable topics"; + set_last_topic_date(MAX_TOPIC_DATE); + return promise.set_error(Status::Error(404, "Not Found")); + } + + promise.set_value(Unit()); +} + +td_api::object_ptr SavedMessagesManager::get_saved_messages_topic_object( + const SavedMessagesTopic *topic) const { + CHECK(topic != nullptr); + td_api::object_ptr last_message_object; + if (topic->last_message_id_ != MessageId()) { + last_message_object = td_->messages_manager_->get_message_object( + {td_->dialog_manager_->get_my_dialog_id(), topic->last_message_id_}, "get_saved_messages_topic_object"); + } + td_api::object_ptr draft_message_object; + if (topic->draft_message_date_ != 0) { + draft_message_object = td_->messages_manager_->get_my_dialog_draft_message_object(); + } + return td_api::make_object( + topic->saved_messages_topic_id_.get_unique_id(), + topic->saved_messages_topic_id_.get_saved_messages_topic_type_object(td_), topic->pinned_order_ != 0, + get_topic_public_order(topic), std::move(last_message_object), std::move(draft_message_object)); +} + +td_api::object_ptr SavedMessagesManager::get_update_saved_messages_topic_object( + const SavedMessagesTopic *topic) const { + return td_api::make_object(get_saved_messages_topic_object(topic)); +} + +void SavedMessagesManager::send_update_saved_messages_topic(const SavedMessagesTopic *topic, const char *source) const { + CHECK(topic != nullptr); + LOG(INFO) << "Send update about " << topic->saved_messages_topic_id_ << " with order " + << get_topic_public_order(topic) << " and last " << topic->last_message_id_ << " sent at " + << topic->last_message_date_ << " with draft at " << topic->draft_message_date_ << " from " << source; + send_closure(G()->td(), &Td::send_update, get_update_saved_messages_topic_object(topic)); +} + +int64 SavedMessagesManager::get_next_pinned_saved_messages_topic_order() { + current_pinned_saved_messages_topic_order_++; + LOG(INFO) << "Assign pinned_order = " << current_pinned_saved_messages_topic_order_; + return current_pinned_saved_messages_topic_order_; +} + +td_api::object_ptr +SavedMessagesManager::get_update_saved_messages_topic_count_object() const { + CHECK(topic_list_.sent_total_count_ != -1); + return td_api::make_object(topic_list_.sent_total_count_); +} + +void SavedMessagesManager::update_saved_messages_topic_sent_total_count(const char *source) { + if (td_->auth_manager_->is_bot()) { + return; + } + if (topic_list_.server_total_count_ == -1) { + return; + } + LOG(INFO) << "Update Saved Messages topic sent total count from " << source; + auto new_total_count = static_cast(topic_list_.ordered_topics_.size()); + if (topic_list_.last_topic_date_ != MAX_TOPIC_DATE) { + new_total_count = max(new_total_count, topic_list_.server_total_count_); + } else if (topic_list_.server_total_count_ != new_total_count) { + topic_list_.server_total_count_ = new_total_count; + } + if (topic_list_.sent_total_count_ != new_total_count) { + topic_list_.sent_total_count_ = new_total_count; + send_closure(G()->td(), &Td::send_update, get_update_saved_messages_topic_count_object()); + } +} + +bool SavedMessagesManager::set_pinned_saved_messages_topics(vector saved_messages_topic_ids) { + if (topic_list_.pinned_saved_messages_topic_ids_ == saved_messages_topic_ids) { + return false; + } + LOG(INFO) << "Update pinned Saved Messages topics from " << topic_list_.pinned_saved_messages_topic_ids_ << " to " + << saved_messages_topic_ids; + FlatHashSet old_pinned_saved_messages_topic_ids; + for (auto pinned_saved_messages_topic_id : topic_list_.pinned_saved_messages_topic_ids_) { + CHECK(pinned_saved_messages_topic_id.is_valid()); + old_pinned_saved_messages_topic_ids.insert(pinned_saved_messages_topic_id); + } + + auto pinned_saved_messages_topic_ids = topic_list_.pinned_saved_messages_topic_ids_; + std::reverse(pinned_saved_messages_topic_ids.begin(), pinned_saved_messages_topic_ids.end()); + std::reverse(saved_messages_topic_ids.begin(), saved_messages_topic_ids.end()); + auto old_it = pinned_saved_messages_topic_ids.begin(); + for (auto saved_messages_topic_id : saved_messages_topic_ids) { + old_pinned_saved_messages_topic_ids.erase(saved_messages_topic_id); + while (old_it < pinned_saved_messages_topic_ids.end()) { + if (*old_it == saved_messages_topic_id) { + break; + } + ++old_it; + } + if (old_it < pinned_saved_messages_topic_ids.end()) { + // leave saved_messages_topic where it is + ++old_it; + continue; + } + set_saved_messages_topic_is_pinned(saved_messages_topic_id, true); + } + for (auto saved_messages_topic_id : old_pinned_saved_messages_topic_ids) { + set_saved_messages_topic_is_pinned(saved_messages_topic_id, false); + } + return true; +} + +bool SavedMessagesManager::set_saved_messages_topic_is_pinned(SavedMessagesTopicId saved_messages_topic_id, + bool is_pinned) { + return set_saved_messages_topic_is_pinned(get_topic(saved_messages_topic_id), is_pinned); +} + +bool SavedMessagesManager::set_saved_messages_topic_is_pinned(SavedMessagesTopic *topic, bool is_pinned) { + CHECK(!td_->auth_manager_->is_bot()); + CHECK(topic != nullptr); + if (!topic_list_.are_pinned_saved_messages_topics_inited_) { + return false; + } + auto saved_messages_topic_id = topic->saved_messages_topic_id_; + if (is_pinned) { + if (!topic_list_.pinned_saved_messages_topic_ids_.empty() && + topic_list_.pinned_saved_messages_topic_ids_[0] == saved_messages_topic_id) { + return false; + } + topic->pinned_order_ = get_next_pinned_saved_messages_topic_order(); + add_to_top(topic_list_.pinned_saved_messages_topic_ids_, topic_list_.pinned_saved_messages_topic_ids_.size() + 1, + saved_messages_topic_id); + } else { + if (topic->pinned_order_ == 0 || + !td::remove(topic_list_.pinned_saved_messages_topic_ids_, saved_messages_topic_id)) { + return false; + } + topic->pinned_order_ = 0; + } + + LOG(INFO) << "Set " << saved_messages_topic_id << " pinned order to " << topic->pinned_order_; + topic->is_changed_ = true; + on_topic_changed(topic, "set_saved_messages_topic_is_pinned"); + return true; +} + +void SavedMessagesManager::set_last_topic_date(TopicDate topic_date) { + if (topic_date <= topic_list_.last_topic_date_) { + return; + } + auto min_topic_date = topic_list_.last_topic_date_; + topic_list_.last_topic_date_ = topic_date; + for (auto it = topic_list_.ordered_topics_.upper_bound(min_topic_date); + it != topic_list_.ordered_topics_.end() && *it <= topic_date; ++it) { + auto topic = get_topic(it->get_topic_id()); + CHECK(topic != nullptr); + send_update_saved_messages_topic(topic, "set_last_topic_date"); + } +} + +void SavedMessagesManager::get_saved_messages_topic_history(SavedMessagesTopicId saved_messages_topic_id, + MessageId from_message_id, int32 offset, int32 limit, + Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (limit > MAX_GET_HISTORY) { + limit = MAX_GET_HISTORY; + } + if (offset > 0) { + return promise.set_error(Status::Error(400, "Parameter offset must be non-positive")); + } + if (offset <= -MAX_GET_HISTORY) { + return promise.set_error(Status::Error(400, "Parameter offset must be greater than -100")); + } + if (offset < -limit) { + return promise.set_error(Status::Error(400, "Parameter offset must be greater than or equal to -limit")); + } + + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_status(td_)); + + if (from_message_id == MessageId() || from_message_id.get() > MessageId::max().get()) { + from_message_id = MessageId::max(); + limit += offset; + offset = 0; + } + if (!from_message_id.is_valid() || !from_message_id.is_server()) { + return promise.set_error(Status::Error(400, "Invalid value of parameter from_message_id specified")); + } + + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), saved_messages_topic_id, from_message_id, + promise = std::move(promise)](Result &&r_info) mutable { + send_closure(actor_id, &SavedMessagesManager::on_get_saved_messages_topic_history, saved_messages_topic_id, + from_message_id, std::move(r_info), std::move(promise)); + }); + td_->create_handler(std::move(query_promise)) + ->send(saved_messages_topic_id, from_message_id, offset, limit); +} + +void SavedMessagesManager::on_get_saved_messages_topic_history( + SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, Result &&r_info, + Promise> &&promise) { + G()->ignore_result_if_closing(r_info); + if (r_info.is_error()) { + return promise.set_error(r_info.move_as_error()); + } + auto info = r_info.move_as_ok(); + + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + vector> messages; + MessageId last_message_id; + int32 last_message_date = 0; + for (auto &message : info.messages) { + auto message_date = MessagesManager::get_message_date(message); + auto full_message_id = td_->messages_manager_->on_get_message(std::move(message), false, false, false, + "on_get_saved_messages_topic_history"); + auto dialog_id = full_message_id.get_dialog_id(); + if (dialog_id == DialogId()) { + continue; + } + if (dialog_id != my_dialog_id) { + LOG(ERROR) << "Receive " << full_message_id << " in history of " << saved_messages_topic_id; + continue; + } + if (!last_message_id.is_valid()) { + last_message_id = full_message_id.get_message_id(); + last_message_date = message_date; + } + messages.push_back( + td_->messages_manager_->get_message_object(full_message_id, "on_get_saved_messages_topic_history")); + } + if (from_message_id == MessageId::max()) { + auto *topic = add_topic(saved_messages_topic_id); + if (info.messages.empty()) { + do_set_topic_last_message_id(topic, MessageId(), 0); + } else { + if (last_message_id.is_valid() && topic->last_message_id_ == MessageId()) { + do_set_topic_last_message_id(topic, last_message_id, last_message_date); + } + } + on_topic_changed(topic, "on_get_saved_messages_topic_history"); + } + promise.set_value(td_api::make_object(info.total_count, std::move(messages))); +} + +void SavedMessagesManager::delete_saved_messages_topic_history(SavedMessagesTopicId saved_messages_topic_id, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_status(td_)); + + MessagesManager::AffectedHistoryQuery query = [td = td_, saved_messages_topic_id]( + DialogId, Promise &&query_promise) { + td->create_handler(std::move(query_promise))->send(saved_messages_topic_id); + }; + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + td_->messages_manager_->run_affected_history_query_until_complete(my_dialog_id, std::move(query), true, + std::move(promise)); +} + +void SavedMessagesManager::get_saved_messages_topic_message_by_date( + SavedMessagesTopicId saved_messages_topic_id, int32 date, Promise> &&promise) { + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_status(td_)); + + if (date <= 0) { + date = 1; + } + + td_->create_handler(std::move(promise))->send(saved_messages_topic_id, date); +} + +void SavedMessagesManager::delete_saved_messages_topic_messages_by_date(SavedMessagesTopicId saved_messages_topic_id, + int32 min_date, int32 max_date, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_status(td_)); + + TRY_STATUS_PROMISE(promise, MessagesManager::fix_delete_message_min_max_dates(min_date, max_date)); + if (max_date == 0) { + return promise.set_value(Unit()); + } + + MessagesManager::AffectedHistoryQuery query = [td = td_, saved_messages_topic_id, min_date, max_date]( + DialogId, Promise &&query_promise) { + td->create_handler(std::move(query_promise)) + ->send(saved_messages_topic_id, min_date, max_date); + }; + auto my_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + td_->messages_manager_->run_affected_history_query_until_complete(my_dialog_id, std::move(query), true, + std::move(promise)); +} + +int32 SavedMessagesManager::get_pinned_saved_messages_topic_limit() const { + return clamp(narrow_cast(td_->option_manager_->get_option_integer("pinned_saved_messages_topic_count_max")), 0, + 1000); +} + +void SavedMessagesManager::toggle_saved_messages_topic_is_pinned(SavedMessagesTopicId saved_messages_topic_id, + bool is_pinned, Promise &&promise) { + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_status(td_)); + if (!topic_list_.are_pinned_saved_messages_topics_inited_) { + return promise.set_error(Status::Error(400, "Pinned Saved Messages topics must be loaded first")); + } + if (get_topic(saved_messages_topic_id) == nullptr) { + return promise.set_error(Status::Error(400, "Can't find Saved Messages topic")); + } + if (is_pinned && !td::contains(topic_list_.pinned_saved_messages_topic_ids_, saved_messages_topic_id) && + static_cast(get_pinned_saved_messages_topic_limit()) <= + topic_list_.pinned_saved_messages_topic_ids_.size()) { + return promise.set_error(Status::Error(400, "The maximum number of pinned chats exceeded")); + } + if (!set_saved_messages_topic_is_pinned(saved_messages_topic_id, is_pinned)) { + return promise.set_value(Unit()); + } + td_->create_handler(std::move(promise))->send(saved_messages_topic_id, is_pinned); +} + +void SavedMessagesManager::set_pinned_saved_messages_topics(vector saved_messages_topic_ids, + Promise &&promise) { + for (const auto &saved_messages_topic_id : saved_messages_topic_ids) { + TRY_STATUS_PROMISE(promise, saved_messages_topic_id.is_valid_status(td_)); + if (get_topic(saved_messages_topic_id) == nullptr) { + return promise.set_error(Status::Error(400, "Can't find Saved Messages topic")); + } + } + if (!topic_list_.are_pinned_saved_messages_topics_inited_) { + return promise.set_error(Status::Error(400, "Pinned Saved Messages topics must be loaded first")); + } + if (static_cast(get_pinned_saved_messages_topic_limit()) < saved_messages_topic_ids.size()) { + return promise.set_error(Status::Error(400, "The maximum number of pinned chats exceeded")); + } + if (!set_pinned_saved_messages_topics(saved_messages_topic_ids)) { + return promise.set_value(Unit()); + } + td_->create_handler(std::move(promise))->send(std::move(saved_messages_topic_ids)); +} + +void SavedMessagesManager::reload_pinned_saved_messages_topics() { + if (td_->auth_manager_->is_bot()) { + // just in case + return; + } + if (!topic_list_.are_pinned_saved_messages_topics_inited_) { + return; + } + + get_pinned_saved_dialogs(0, Auto()); +} + +void SavedMessagesManager::get_current_state(vector> &updates) const { + if (td_->auth_manager_->is_bot()) { + return; + } + + if (topic_list_.sent_total_count_ != -1) { + updates.push_back(get_update_saved_messages_topic_count_object()); + } + + for (const auto &it : saved_messages_topics_) { + const auto *topic = it.second.get(); + updates.push_back(get_update_saved_messages_topic_object(topic)); + } +} + +const SavedMessagesManager::TopicDate SavedMessagesManager::MIN_TOPIC_DATE{std::numeric_limits::max(), + SavedMessagesTopicId()}; +const SavedMessagesManager::TopicDate SavedMessagesManager::MAX_TOPIC_DATE{0, SavedMessagesTopicId()}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesManager.h b/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesManager.h new file mode 100644 index 0000000000..6b79327ffc --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesManager.h @@ -0,0 +1,203 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessagesInfo.h" +#include "td/telegram/SavedMessagesTopicId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" + +#include +#include + +namespace td { + +class Td; + +class SavedMessagesManager final : public Actor { + public: + SavedMessagesManager(Td *td, ActorShared<> parent); + + SavedMessagesTopicId get_topic_id(int64 topic_id) const; + + vector get_topic_ids(const vector &topic_ids) const; + + int64 get_saved_messages_topic_id_object(SavedMessagesTopicId saved_messages_topic_id); + + void set_topic_last_message_id(SavedMessagesTopicId saved_messages_topic_id, MessageId last_message_id, + int32 last_message_date); + + void on_topic_message_updated(SavedMessagesTopicId saved_messages_topic_id, MessageId message_id); + + void on_topic_message_deleted(SavedMessagesTopicId saved_messages_topic_id, MessageId message_id); + + void on_topic_draft_message_updated(SavedMessagesTopicId saved_messages_topic_id, int32 draft_message_date); + + void load_saved_messages_topics(int32 limit, Promise &&promsie); + + void on_get_saved_messages_topics(bool is_pinned, int32 limit, + telegram_api::object_ptr &&saved_dialogs_ptr, + Promise &&promise); + + void get_saved_messages_topic_history(SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, + int32 offset, int32 limit, + Promise> &&promise); + + void delete_saved_messages_topic_history(SavedMessagesTopicId saved_messages_topic_id, Promise &&promise); + + void get_saved_messages_topic_message_by_date(SavedMessagesTopicId saved_messages_topic_id, int32 date, + Promise> &&promise); + + void delete_saved_messages_topic_messages_by_date(SavedMessagesTopicId saved_messages_topic_id, int32 min_date, + int32 max_date, Promise &&promise); + + void toggle_saved_messages_topic_is_pinned(SavedMessagesTopicId saved_messages_topic_id, bool is_pinned, + Promise &&promise); + + void set_pinned_saved_messages_topics(vector saved_messages_topic_ids, Promise &&promise); + + void reload_pinned_saved_messages_topics(); + + void get_current_state(vector> &updates) const; + + private: + static constexpr int32 MAX_GET_HISTORY = 100; // server side limit + + static constexpr int64 MIN_PINNED_TOPIC_ORDER = static_cast(2147000000) << 32; + + struct SavedMessagesTopic { + SavedMessagesTopicId saved_messages_topic_id_; + MessageId last_message_id_; + int32 last_message_date_ = 0; + int32 draft_message_date_ = 0; + int64 pinned_order_ = 0; + int64 private_order_ = 0; + bool is_changed_ = false; + }; + + class TopicDate { + int64 order_; + SavedMessagesTopicId topic_id_; + + public: + TopicDate(int64 order, SavedMessagesTopicId topic_id) : order_(order), topic_id_(topic_id) { + } + + bool operator<(const TopicDate &other) const { + return order_ > other.order_ || + (order_ == other.order_ && topic_id_.get_unique_id() > other.topic_id_.get_unique_id()); + } + + bool operator<=(const TopicDate &other) const { + return order_ > other.order_ || + (order_ == other.order_ && topic_id_.get_unique_id() >= other.topic_id_.get_unique_id()); + } + + bool operator==(const TopicDate &other) const { + return order_ == other.order_ && topic_id_ == other.topic_id_; + } + + bool operator!=(const TopicDate &other) const { + return !(*this == other); + } + + SavedMessagesTopicId get_topic_id() const { + return topic_id_; + } + }; + + static const TopicDate MIN_TOPIC_DATE; + static const TopicDate MAX_TOPIC_DATE; + + struct TopicList { + int32 server_total_count_ = -1; + int32 sent_total_count_ = -1; + + vector pinned_saved_messages_topic_ids_; + bool are_pinned_saved_messages_topics_inited_ = false; + + std::set ordered_topics_; + + TopicDate last_topic_date_ = MIN_TOPIC_DATE; // in memory + + vector> load_pinned_queries_; + vector> load_queries_; + + int32 offset_date_ = std::numeric_limits::max(); + DialogId offset_dialog_id_; + MessageId offset_message_id_; + }; + + void tear_down() final; + + SavedMessagesTopic *get_topic(SavedMessagesTopicId saved_messages_topic_id); + + SavedMessagesTopic *add_topic(SavedMessagesTopicId saved_messages_topic_id); + + void get_pinned_saved_dialogs(int32 limit, Promise &&promise); + + void on_get_pinned_saved_dialogs(Result &&result); + + void get_saved_dialogs(int32 limit, Promise &&promise); + + void on_get_saved_dialogs(Result &&result); + + void on_get_saved_messages_topic_history(SavedMessagesTopicId saved_messages_topic_id, MessageId from_message_id, + Result &&r_info, + Promise> &&promise); + + void do_set_topic_last_message_id(SavedMessagesTopic *topic, MessageId last_message_id, int32 last_message_date); + + int64 get_next_pinned_saved_messages_topic_order(); + + bool set_pinned_saved_messages_topics(vector added_saved_messages_topic_ids); + + bool set_saved_messages_topic_is_pinned(SavedMessagesTopicId saved_messages_topic_id, bool is_pinned); + + bool set_saved_messages_topic_is_pinned(SavedMessagesTopic *topic, bool is_pinned); + + int32 get_pinned_saved_messages_topic_limit() const; + + int64 get_topic_order(int32 message_date, MessageId message_id); + + int64 get_topic_public_order(const SavedMessagesTopic *topic) const; + + void set_last_topic_date(TopicDate topic_date); + + void on_topic_changed(SavedMessagesTopic *topic, const char *source); + + td_api::object_ptr get_saved_messages_topic_object(const SavedMessagesTopic *topic) const; + + td_api::object_ptr get_update_saved_messages_topic_object( + const SavedMessagesTopic *topic) const; + + void send_update_saved_messages_topic(const SavedMessagesTopic *topic, const char *source) const; + + td_api::object_ptr get_update_saved_messages_topic_count_object() const; + + void update_saved_messages_topic_sent_total_count(const char *source); + + Td *td_; + ActorShared<> parent_; + + FlatHashMap, SavedMessagesTopicIdHash> saved_messages_topics_; + + int64 current_pinned_saved_messages_topic_order_ = MIN_PINNED_TOPIC_ORDER; + + TopicList topic_list_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesTopicId.cpp b/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesTopicId.cpp new file mode 100644 index 0000000000..61df0fa8a3 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesTopicId.cpp @@ -0,0 +1,126 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/SavedMessagesTopicId.h" + +#include "td/telegram/AccessRights.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/MessageForwardInfo.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" + +namespace td { + +static constexpr DialogId HIDDEN_AUTHOR_DIALOG_ID = DialogId(static_cast(2666000)); + +SavedMessagesTopicId::SavedMessagesTopicId(DialogId my_dialog_id, const MessageForwardInfo *message_forward_info, + DialogId real_forward_from_dialog_id) { + if (message_forward_info != nullptr) { + auto last_dialog_id = message_forward_info->get_last_dialog_id(); + if (last_dialog_id.is_valid()) { + dialog_id_ = last_dialog_id; + return; + } + if (real_forward_from_dialog_id != DialogId() && message_forward_info->has_last_sender_name()) { + if (real_forward_from_dialog_id.get_type() == DialogType::User) { + dialog_id_ = HIDDEN_AUTHOR_DIALOG_ID; + } else { + dialog_id_ = real_forward_from_dialog_id; + } + return; + } + auto from_dialog_id = message_forward_info->get_origin().get_sender(); + if (from_dialog_id.is_valid()) { + dialog_id_ = my_dialog_id; + return; + } + if (message_forward_info->get_origin().is_sender_hidden()) { + dialog_id_ = HIDDEN_AUTHOR_DIALOG_ID; + return; + } + } + dialog_id_ = my_dialog_id; +} + +td_api::object_ptr SavedMessagesTopicId::get_saved_messages_topic_type_object( + const Td *td) const { + if (dialog_id_ == DialogId()) { + return nullptr; + } + if (dialog_id_ == td->dialog_manager_->get_my_dialog_id()) { + return td_api::make_object(); + } + if (is_author_hidden()) { + return td_api::make_object(); + } + return td_api::make_object( + td->messages_manager_->get_chat_id_object(dialog_id_, "savedMessagesTopicTypeSavedFromChat")); +} + +bool SavedMessagesTopicId::have_input_peer(Td *td) const { + if (dialog_id_.get_type() == DialogType::SecretChat || + !td->dialog_manager_->have_dialog_info_force(dialog_id_, "SavedMessagesTopicId::have_input_peer")) { + return false; + } + return td->dialog_manager_->have_input_peer(dialog_id_, false, AccessRights::Know); +} + +Status SavedMessagesTopicId::is_valid_status(Td *td) const { + if (!dialog_id_.is_valid()) { + return Status::Error(400, "Invalid Saved Messages topic specified"); + } + if (!have_input_peer(td)) { + return Status::Error(400, "Unknown Saved Messages topic specified"); + } + return Status::OK(); +} + +Status SavedMessagesTopicId::is_valid_in(Td *td, DialogId dialog_id) const { + if (dialog_id_ != DialogId()) { + if (dialog_id != td->dialog_manager_->get_my_dialog_id()) { + return Status::Error(400, "Can't use Saved Messages topic in the chat"); + } + if (!have_input_peer(td)) { + return Status::Error(400, "Unknown Saved Messages topic specified"); + } + } + return Status::OK(); +} + +bool SavedMessagesTopicId::is_author_hidden() const { + return dialog_id_ == HIDDEN_AUTHOR_DIALOG_ID; +} + +telegram_api::object_ptr SavedMessagesTopicId::get_input_peer(const Td *td) const { + return td->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Know); +} + +telegram_api::object_ptr SavedMessagesTopicId::get_input_dialog_peer( + const Td *td) const { + return telegram_api::make_object(get_input_peer(td)); +} + +void SavedMessagesTopicId::add_dependencies(Dependencies &dependencies) const { + if (is_author_hidden()) { + dependencies.add_dialog_dependencies(dialog_id_); + } else { + dependencies.add_dialog_and_dependencies(dialog_id_); + } +} + +StringBuilder &operator<<(StringBuilder &string_builder, SavedMessagesTopicId saved_messages_topic_id) { + if (!saved_messages_topic_id.dialog_id_.is_valid()) { + return string_builder << "[no Saved Messages topic]"; + } + if (saved_messages_topic_id.is_author_hidden()) { + return string_builder << "[Author Hidden topic]"; + } + return string_builder << "[topic of " << saved_messages_topic_id.dialog_id_ << ']'; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesTopicId.h b/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesTopicId.h new file mode 100644 index 0000000000..2de568a0ed --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SavedMessagesTopicId.h @@ -0,0 +1,92 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Dependencies; +class MessageForwardInfo; +class Td; + +class SavedMessagesTopicId { + DialogId dialog_id_; + + friend struct SavedMessagesTopicIdHash; + + friend bool operator==(const SavedMessagesTopicId &lhs, const SavedMessagesTopicId &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, SavedMessagesTopicId saved_messages_topic_id); + + bool have_input_peer(Td *td) const; + + public: + SavedMessagesTopicId() = default; + + explicit SavedMessagesTopicId(DialogId dialog_id) : dialog_id_(dialog_id) { + } + + SavedMessagesTopicId(DialogId my_dialog_id, const MessageForwardInfo *message_forward_info, + DialogId real_forward_from_dialog_id); + + bool is_valid() const { + return dialog_id_.is_valid(); + } + + Status is_valid_status(Td *td) const; + + Status is_valid_in(Td *td, DialogId dialog_id) const; + + bool is_author_hidden() const; + + int64 get_unique_id() const { + return dialog_id_.get(); + } + + td_api::object_ptr get_saved_messages_topic_type_object(const Td *td) const; + + telegram_api::object_ptr get_input_peer(const Td *td) const; + + telegram_api::object_ptr get_input_dialog_peer(const Td *td) const; + + void add_dependencies(Dependencies &dependencies) const; + + template + void store(StorerT &storer) const { + dialog_id_.store(storer); + } + + template + void parse(ParserT &parser) { + dialog_id_.parse(parser); + } +}; + +struct SavedMessagesTopicIdHash { + uint32 operator()(SavedMessagesTopicId saved_messages_topic_id) const { + return DialogIdHash()(saved_messages_topic_id.dialog_id_); + } +}; + +inline bool operator==(const SavedMessagesTopicId &lhs, const SavedMessagesTopicId &rhs) { + return lhs.dialog_id_ == rhs.dialog_id_; +} + +inline bool operator!=(const SavedMessagesTopicId &lhs, const SavedMessagesTopicId &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, SavedMessagesTopicId saved_messages_topic_id); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.cpp b/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.cpp index 2e12161333..78828f4d3a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -12,9 +12,31 @@ namespace td { +telegram_api::object_ptr +ScopeNotificationSettings::get_input_peer_notify_settings() const { + int32 flags = telegram_api::inputPeerNotifySettings::MUTE_UNTIL_MASK | + telegram_api::inputPeerNotifySettings::SHOW_PREVIEWS_MASK | + telegram_api::inputPeerNotifySettings::STORIES_HIDE_SENDER_MASK; + if (sound != nullptr) { + flags |= telegram_api::inputPeerNotifySettings::SOUND_MASK; + } + if (story_sound != nullptr) { + flags |= telegram_api::inputPeerNotifySettings::STORIES_SOUND_MASK; + } + if (!use_default_mute_stories) { + flags |= telegram_api::inputPeerNotifySettings::STORIES_MUTED_MASK; + } + return telegram_api::make_object( + flags, show_preview, false, mute_until, get_input_notification_sound(sound), mute_stories, hide_story_sender, + get_input_notification_sound(story_sound)); +} + StringBuilder &operator<<(StringBuilder &string_builder, const ScopeNotificationSettings ¬ification_settings) { return string_builder << "[" << notification_settings.mute_until << ", " << notification_settings.sound << ", " - << notification_settings.show_preview << ", " << notification_settings.is_synchronized << ", " + << notification_settings.show_preview << ", " << notification_settings.use_default_mute_stories + << ", " << notification_settings.mute_stories << ", " << notification_settings.story_sound + << ", " << notification_settings.hide_story_sender << ", " + << notification_settings.is_synchronized << ", " << notification_settings.disable_pinned_message_notifications << ", " << notification_settings.disable_mention_notifications << "]"; } @@ -25,6 +47,8 @@ td_api::object_ptr get_scope_notification_set return td_api::make_object( max(0, notification_settings->mute_until - G()->unix_time()), get_notification_sound_ringtone_id(notification_settings->sound), notification_settings->show_preview, + notification_settings->use_default_mute_stories, notification_settings->mute_stories, + get_notification_sound_ringtone_id(notification_settings->story_sound), !notification_settings->hide_story_sender, notification_settings->disable_pinned_message_notifications, notification_settings->disable_mention_notifications); } @@ -49,10 +73,12 @@ Result get_scope_notification_settings( } auto mute_until = get_mute_until(notification_settings->mute_for_); - return ScopeNotificationSettings(mute_until, get_notification_sound(false, notification_settings->sound_id_), - notification_settings->show_preview_, - notification_settings->disable_pinned_message_notifications_, - notification_settings->disable_mention_notifications_); + return ScopeNotificationSettings( + mute_until, get_notification_sound(false, notification_settings->sound_id_), notification_settings->show_preview_, + notification_settings->use_default_mute_stories_, notification_settings->mute_stories_, + get_notification_sound(false, notification_settings->story_sound_id_), !notification_settings->show_story_sender_, + notification_settings->disable_pinned_message_notifications_, + notification_settings->disable_mention_notifications_); } ScopeNotificationSettings get_scope_notification_settings(tl_object_ptr &&settings, @@ -66,7 +92,17 @@ ScopeNotificationSettings get_scope_notification_settings(tl_object_ptrshow_previews_; - return {mute_until, get_notification_sound(settings.get()), show_preview, old_disable_pinned_message_notifications, + auto use_default_mute_stories = (settings->flags_ & telegram_api::peerNotifySettings::STORIES_MUTED_MASK) == 0; + auto mute_stories = settings->stories_muted_; + auto hide_story_sender = settings->stories_hide_sender_; + return {mute_until, + get_notification_sound(settings.get(), false), + show_preview, + use_default_mute_stories, + mute_stories, + get_notification_sound(settings.get(), true), + hide_story_sender, + old_disable_pinned_message_notifications, old_disable_mention_notifications}; } diff --git a/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.h b/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.h index f6a59caeab..325f85c1cf 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.h +++ b/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -20,7 +20,11 @@ class ScopeNotificationSettings { public: int32 mute_until = 0; unique_ptr sound; + unique_ptr story_sound; bool show_preview = true; + bool use_default_mute_stories = true; + bool mute_stories = false; + bool hide_story_sender = false; bool is_synchronized = false; // local settings @@ -30,14 +34,22 @@ class ScopeNotificationSettings { ScopeNotificationSettings() = default; ScopeNotificationSettings(int32 mute_until, unique_ptr &&sound, bool show_preview, + bool use_default_mute_stories, bool mute_stories, + unique_ptr &&story_sound, bool hide_story_sender, bool disable_pinned_message_notifications, bool disable_mention_notifications) : mute_until(mute_until) , sound(std::move(sound)) + , story_sound(std::move(story_sound)) , show_preview(show_preview) + , use_default_mute_stories(use_default_mute_stories) + , mute_stories(mute_stories) + , hide_story_sender(hide_story_sender) , is_synchronized(true) , disable_pinned_message_notifications(disable_pinned_message_notifications) , disable_mention_notifications(disable_mention_notifications) { } + + telegram_api::object_ptr get_input_peer_notify_settings() const; }; StringBuilder &operator<<(StringBuilder &string_builder, const ScopeNotificationSettings ¬ification_settings); diff --git a/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.hpp b/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.hpp index 25f2f3ce32..d783a113b4 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/ScopeNotificationSettings.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -19,6 +19,8 @@ void store(const ScopeNotificationSettings ¬ification_settings, StorerT &stor bool is_muted = notification_settings.mute_until != 0 && notification_settings.mute_until > G()->unix_time(); bool has_sound = notification_settings.sound != nullptr; bool has_ringtone_support = true; + bool has_story_sound = notification_settings.story_sound != nullptr; + bool use_mute_stories = !notification_settings.use_default_mute_stories; BEGIN_STORE_FLAGS(); STORE_FLAG(is_muted); STORE_FLAG(has_sound); @@ -28,6 +30,10 @@ void store(const ScopeNotificationSettings ¬ification_settings, StorerT &stor STORE_FLAG(notification_settings.disable_pinned_message_notifications); STORE_FLAG(notification_settings.disable_mention_notifications); STORE_FLAG(has_ringtone_support); + STORE_FLAG(notification_settings.mute_stories); + STORE_FLAG(has_story_sound); + STORE_FLAG(notification_settings.hide_story_sender); + STORE_FLAG(use_mute_stories); END_STORE_FLAGS(); if (is_muted) { store(notification_settings.mute_until, storer); @@ -35,6 +41,9 @@ void store(const ScopeNotificationSettings ¬ification_settings, StorerT &stor if (has_sound) { store(notification_settings.sound, storer); } + if (has_story_sound) { + store(notification_settings.story_sound, storer); + } } template @@ -43,6 +52,8 @@ void parse(ScopeNotificationSettings ¬ification_settings, ParserT &parser) { bool has_sound; bool silent_send_message_ignored; bool has_ringtone_support; + bool has_story_sound; + bool use_mute_stories; BEGIN_PARSE_FLAGS(); PARSE_FLAG(is_muted); PARSE_FLAG(has_sound); @@ -52,6 +63,10 @@ void parse(ScopeNotificationSettings ¬ification_settings, ParserT &parser) { PARSE_FLAG(notification_settings.disable_pinned_message_notifications); PARSE_FLAG(notification_settings.disable_mention_notifications); PARSE_FLAG(has_ringtone_support); + PARSE_FLAG(notification_settings.mute_stories); + PARSE_FLAG(has_story_sound); + PARSE_FLAG(notification_settings.hide_story_sender); + PARSE_FLAG(use_mute_stories); END_PARSE_FLAGS(); (void)silent_send_message_ignored; if (is_muted) { @@ -66,6 +81,10 @@ void parse(ScopeNotificationSettings ¬ification_settings, ParserT &parser) { notification_settings.sound = get_legacy_notification_sound(sound); } } + if (has_story_sound) { + parse_notification_sound(notification_settings.story_sound, parser); + } + notification_settings.use_default_mute_stories = !use_mute_stories; } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SecretChatActor.cpp b/protocols/Telegram/tdlib/td/td/telegram/SecretChatActor.cpp index 76ab0aa241..2acd2dc5da 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SecretChatActor.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SecretChatActor.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,6 +10,7 @@ #include "td/telegram/net/NetQueryCreator.h" #include "td/telegram/secret_api.hpp" #include "td/telegram/ServerMessageId.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.hpp" #include "td/telegram/UniqueId.h" @@ -44,10 +45,6 @@ namespace td { -inline TLObjectStorer create_storer(const secret_api::Object &object) { - return TLObjectStorer(object); -} - class SecretImpl { public: explicit SecretImpl(const Storer &data) : data(data) { @@ -70,7 +67,7 @@ SecretChatActor::SecretChatActor(int32 id, unique_ptr context, bool can template NetQueryPtr SecretChatActor::create_net_query(QueryType type, const T &function) { return context_->net_query_creator().create(UniqueId::next(UniqueId::Type::Default, static_cast(type)), - function, {}, DcId::main(), NetQuery::Type::Common, + nullptr, function, {}, DcId::main(), NetQuery::Type::Common, NetQuery::AuthFlag::On); } @@ -220,14 +217,13 @@ Result SecretChatActor::create_encrypted_message(int32 my_in_seq_no auto message_with_layer = secret_api::make_object( std::move(random_bytes), layer, in_seq_no, out_seq_no, std::move(message)); LOG(INFO) << "Create message " << to_string(message_with_layer); - auto storer = create_storer(*message_with_layer); + auto storer = TLObjectStorer(*message_with_layer); auto new_storer = mtproto::PacketStorer(storer); - mtproto::PacketInfo info; - info.type = mtproto::PacketInfo::EndToEnd; - info.version = 2; - info.is_creator = auth_state_.x == 0; - auto packet_writer = BufferWriter{mtproto::Transport::write(new_storer, *auth_key, &info), 0, 0}; - mtproto::Transport::write(new_storer, *auth_key, &info, packet_writer.as_mutable_slice()); + mtproto::PacketInfo packet_info; + packet_info.type = mtproto::PacketInfo::EndToEnd; + packet_info.version = 2; + packet_info.is_creator = auth_state_.x == 0; + auto packet_writer = mtproto::Transport::write(new_storer, *auth_key, &packet_info); message = std::move(message_with_layer->message_); return packet_writer.as_buffer_slice(); } @@ -681,7 +677,7 @@ void SecretChatActor::cancel_chat(bool delete_history, bool is_already_discarded } }); - context_->binlog()->force_sync(std::move(on_sync)); + context_->binlog()->force_sync(std::move(on_sync), "cancel_chat"); yield(); } @@ -792,12 +788,12 @@ Result> SecretChatActor::decrypt(BufferSl data = encrypted_message_copy.as_mutable_slice(); CHECK(is_aligned_pointer<4>(data.data())); - mtproto::PacketInfo info; - info.type = mtproto::PacketInfo::EndToEnd; + mtproto::PacketInfo packet_info; + packet_info.type = mtproto::PacketInfo::EndToEnd; mtproto_version = versions[i]; - info.version = mtproto_version; - info.is_creator = auth_state_.x == 0; - r_read_result = mtproto::Transport::read(data, *auth_key, &info); + packet_info.version = mtproto_version; + packet_info.is_creator = auth_state_.x == 0; + r_read_result = mtproto::Transport::read(data, *auth_key, &packet_info); if (i + 1 != versions.size() && r_read_result.is_error()) { if (config_state_.his_layer >= static_cast(SecretChatLayer::Mtproto2)) { LOG(WARNING) << tag("mtproto", mtproto_version) << " decryption failed " << r_read_result.error(); @@ -1076,7 +1072,7 @@ void SecretChatActor::do_outbound_message_impl(unique_ptrbinlog(), LogEvent::HandlerType::SecretChats, create_storer(*state->message)); LOG(INFO) << "Outbound secret message [save_log_event] start " << tag("log_event_id", log_event_id); - context_->binlog()->force_sync(std::move(save_log_event_finish)); + context_->binlog()->force_sync(std::move(save_log_event_finish), "do_outbound_message_impl"); state->message->set_log_event_id(log_event_id); } else { LOG(INFO) << "Outbound secret message [save_log_event] skip " << tag("log_event_id", log_event_id); @@ -1333,7 +1329,7 @@ Status SecretChatActor::do_inbound_message_decrypted(unique_ptrbinlog()->force_sync(std::move(save_log_event_finish)); + context_->binlog()->force_sync(std::move(save_log_event_finish), "do_inbound_message_decrypted"); } else { save_log_event_finish.set_value(Unit()); } @@ -1491,7 +1487,7 @@ void SecretChatActor::outbound_resend(uint64 state_id) { "on_outbound_send_message_start"); } }); - context_->binlog()->force_sync(std::move(send_message_start)); + context_->binlog()->force_sync(std::move(send_message_start), "outbound_resend"); } Status SecretChatActor::outbound_rewrite_with_empty(uint64 state_id) { @@ -1672,7 +1668,7 @@ void SecretChatActor::on_outbound_send_message_error(uint64 state_id, Status err } }); if (need_sync) { - context_->binlog()->force_sync(std::move(send_message_start)); + context_->binlog()->force_sync(std::move(send_message_start), "on_outbound_send_message_error"); } else { send_message_start.set_value(Unit()); } @@ -1776,9 +1772,7 @@ Status SecretChatActor::on_update_chat(telegram_api::encryptedChatRequested &upd auth_state_.date = context_->unix_time(); TRY_STATUS(save_common_info(update)); auth_state_.handshake.set_g_a(update.g_a_.as_slice()); - if ((update.flags_ & telegram_api::encryptedChatRequested::FOLDER_ID_MASK) != 0) { - auth_state_.initial_folder_id = FolderId(update.folder_id_); - } + auth_state_.initial_folder_id = FolderId(update.folder_id_); send_update_secret_chat(); return Status::OK(); @@ -1839,7 +1833,7 @@ Status SecretChatActor::on_update_chat(NetQueryPtr query) { TRY_STATUS(on_update_chat(std::move(config))); if (auth_state_.state == State::WaitRequestResponse) { context_->secret_chat_db()->set_value(auth_state_); - context_->binlog()->force_sync(Promise<>()); + context_->binlog()->force_sync(Promise<>(), "on_update_chat"); } return Status::OK(); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/SecretChatActor.h b/protocols/Telegram/tdlib/td/td/telegram/SecretChatActor.h index 478b5a4fc0..0bfb670585 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SecretChatActor.h +++ b/protocols/Telegram/tdlib/td/td/telegram/SecretChatActor.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -71,7 +71,7 @@ class SecretChatActor final : public NetQueryCallback { virtual bool close_flag() = 0; - // We don't want to expose the whole NetQueryDispatcher, MessagesManager and ContactsManager. + // We don't want to expose the whole NetQueryDispatcher, MessagesManager and UserManager. // So it is more clear which parts of MessagesManager are really used. And it is much easier to create tests. virtual void send_net_query(NetQueryPtr query, ActorShared callback, bool ordered) = 0; @@ -115,7 +115,7 @@ class SecretChatActor final : public NetQueryCallback { void add_inbound_message(unique_ptr message); // Outbound messages - // Promise will be set just after corresponding log event will be SENT to binlog. + // Promise will be set just after corresponding log event is SENT to binlog. void send_message(tl_object_ptr message, tl_object_ptr file, Promise<> promise); void send_message_action(tl_object_ptr action); @@ -485,7 +485,7 @@ class SecretChatActor final : public NetQueryCallback { // 3. Then, we are able to ERASE EVENT just AFTER the CHANGE is SAVED to the binlog. // // Actually the change will be saved to binlog too. - // So we can do it immediatelly after EVENT is SENT to the binlog, because SEND CHANGE and ERASE EVENT will be + // So we can do it immediately after EVENT is SENT to the binlog, because SEND CHANGE and ERASE EVENT will be // ordered automatically. // // We will use common ChangesProcessor for all changes (inside one SecretChatActor). diff --git a/protocols/Telegram/tdlib/td/td/telegram/SecretChatsManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/SecretChatsManager.cpp index 47e7911c14..693c30deb4 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SecretChatsManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SecretChatsManager.cpp @@ -1,12 +1,11 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/SecretChatsManager.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/DhCache.h" #include "td/telegram/EncryptedFile.h" #include "td/telegram/FolderId.h" @@ -14,11 +13,14 @@ #include "td/telegram/logevent/SecretChatEvent.h" #include "td/telegram/MessageId.h" #include "td/telegram/MessagesManager.h" +#include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQueryDispatcher.h" +#include "td/telegram/SecretChatDb.h" #include "td/telegram/SequenceDispatcher.h" #include "td/telegram/StateManager.h" #include "td/telegram/TdDb.h" -#include "td/telegram/telegram_api.hpp" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" #include "td/mtproto/DhCallback.h" @@ -167,7 +169,7 @@ void SecretChatsManager::on_update_chat(tl_object_ptrchat_->get_id() == telegram_api::encryptedChatRequested::ID) { -#if TD_ANDROID || TD_DARWIN_IOS || TD_DARWIN_WATCH_OS || TD_TIZEN +#if TD_ANDROID || TD_DARWIN_IOS pending_update.offline_process_time_ = Timestamp::in(1.0); #else pending_update.online_process_time_ = Timestamp::in(2.0); @@ -181,12 +183,24 @@ void SecretChatsManager::on_update_chat(tl_object_ptr update) { - int32 id = 0; - downcast_call(*update->chat_, [&](auto &x) { id = x.id_; }); - - send_closure( - update->chat_->get_id() == telegram_api::encryptedChatDiscarded::ID ? get_chat_actor(id) : create_chat_actor(id), - &SecretChatActor::update_chat, std::move(update->chat_)); + auto actor_id = [this, chat = update->chat_.get()] { + switch (chat->get_id()) { + case telegram_api::encryptedChatEmpty::ID: + return create_chat_actor(static_cast(chat)->id_); + case telegram_api::encryptedChatWaiting::ID: + return create_chat_actor(static_cast(chat)->id_); + case telegram_api::encryptedChatRequested::ID: + return create_chat_actor(static_cast(chat)->id_); + case telegram_api::encryptedChat::ID: + return create_chat_actor(static_cast(chat)->id_); + case telegram_api::encryptedChatDiscarded::ID: + return get_chat_actor(static_cast(chat)->id_); + default: + UNREACHABLE(); + return ActorId(); + } + }(); + send_closure(actor_id, &SecretChatActor::update_chat, std::move(update->chat_)); } void SecretChatsManager::on_new_message(tl_object_ptr &&message_ptr, @@ -198,14 +212,24 @@ void SecretChatsManager::on_new_message(tl_object_ptr(); event->promise = std::move(promise); - downcast_call(*message_ptr, [&](auto &x) { - event->chat_id = x.chat_id_; - event->date = x.date_; - event->encrypted_message = std::move(x.bytes_); - }); - if (message_ptr->get_id() == telegram_api::encryptedMessage::ID) { - auto message = move_tl_object_as(message_ptr); - event->file = EncryptedFile::get_encrypted_file(std::move(message->file_)); + switch (message_ptr->get_id()) { + case telegram_api::encryptedMessage::ID: { + auto message = telegram_api::move_object_as(message_ptr); + event->chat_id = message->chat_id_; + event->date = message->date_; + event->encrypted_message = std::move(message->bytes_); + event->file = EncryptedFile::get_encrypted_file(std::move(message->file_)); + break; + } + case telegram_api::encryptedMessageService::ID: { + auto message = telegram_api::move_object_as(message_ptr); + event->chat_id = message->chat_id_; + event->date = message->date_; + event->encrypted_message = std::move(message->bytes_); + break; + } + default: + UNREACHABLE(); } add_inbound_message(std::move(event)); } @@ -343,8 +367,8 @@ unique_ptr SecretChatsManager::make_secret_chat_contex void on_update_secret_chat(int64 access_hash, UserId user_id, SecretChatState state, bool is_outbound, int32 ttl, int32 date, string key_hash, int32 layer, FolderId initial_folder_id) final { - send_closure(G()->contacts_manager(), &ContactsManager::on_update_secret_chat, secret_chat_id_, access_hash, - user_id, state, is_outbound, ttl, date, key_hash, layer, initial_folder_id); + send_closure(G()->user_manager(), &UserManager::on_update_secret_chat, secret_chat_id_, access_hash, user_id, + state, is_outbound, ttl, date, key_hash, layer, initial_folder_id); } void on_inbound_message(UserId user_id, MessageId message_id, int32 date, unique_ptr file, diff --git a/protocols/Telegram/tdlib/td/td/telegram/SecureManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/SecureManager.cpp index 69dae9aaaf..b1b0c768ac 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SecureManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SecureManager.cpp @@ -1,12 +1,11 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/SecureManager.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/DialogId.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileManager.h" @@ -16,6 +15,8 @@ #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/PasswordManager.h" #include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" @@ -986,8 +987,8 @@ void SecureManager::on_get_passport_authorization_form( auto authorization_form = r_authorization_form.move_as_ok(); LOG(INFO) << "Receive " << to_string(authorization_form); - G()->td().get_actor_unsafe()->contacts_manager_->on_get_users(std::move(authorization_form->users_), - "on_get_passport_authorization_form"); + G()->td().get_actor_unsafe()->user_manager_->on_get_users(std::move(authorization_form->users_), + "on_get_passport_authorization_form"); vector> required_types; std::map all_types; diff --git a/protocols/Telegram/tdlib/td/td/telegram/SecureStorage.cpp b/protocols/Telegram/tdlib/td/td/telegram/SecureStorage.cpp index e67a3f561e..44b48b2f66 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SecureStorage.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SecureStorage.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -354,9 +354,9 @@ Result decrypt_value(const Secret &secret, const ValueHash &hash, S auto aes_cbc_state = calc_aes_cbc_state_sha512(PSLICE() << secret.as_slice() << hash.as_slice()); Decryptor decryptor(std::move(aes_cbc_state)); TRY_RESULT(decrypted_value, decryptor.append(BufferSlice(data))); - TRY_RESULT(got_hash, decryptor.finish()); - if (got_hash.as_slice() != hash.as_slice()) { - return Status::Error(PSLICE() << "Hash mismatch " << format::as_hex_dump<4>(got_hash.as_slice()) << " " + TRY_RESULT(stored_hash, decryptor.finish()); + if (stored_hash.as_slice() != hash.as_slice()) { + return Status::Error(PSLICE() << "Hash mismatch " << format::as_hex_dump<4>(stored_hash.as_slice()) << " " << format::as_hex_dump<4>(hash.as_slice())); } return std::move(decrypted_value); @@ -395,9 +395,9 @@ Status decrypt_file(const Secret &secret, const ValueHash &hash, const string &s return Status::OK(); })); - TRY_RESULT(got_hash, decryptor.finish()); + TRY_RESULT(stored_hash, decryptor.finish()); - if (hash.as_slice() != got_hash.as_slice()) { + if (hash.as_slice() != stored_hash.as_slice()) { return Status::Error("Hash mismatch"); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/SecureValue.cpp b/protocols/Telegram/tdlib/td/td/telegram/SecureValue.cpp index 402a4101e0..9fc9286b45 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SecureValue.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SecureValue.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -15,7 +15,7 @@ #include "td/telegram/misc.h" #include "td/telegram/net/DcId.h" #include "td/telegram/OrderInfo.h" -#include "td/telegram/telegram_api.hpp" +#include "td/telegram/telegram_api.h" #include "td/utils/algorithm.h" #include "td/utils/base64.h" @@ -24,7 +24,6 @@ #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" #include "td/utils/misc.h" -#include "td/utils/overloaded.h" #include "td/utils/SliceBuilder.h" #include "td/utils/utf8.h" @@ -397,14 +396,15 @@ telegram_api::object_ptr get_input_secure_file_ob file_manager->get_file_view(input_file.file_id).get_main_file_id()); auto res = std::move(input_file.input_file); if (res == nullptr) { - return file_manager->get_file_view(file.file.file_id).remote_location().as_input_secure_file(); - } - telegram_api::downcast_call(*res, overloaded( - [&](telegram_api::inputSecureFileUploaded &uploaded) { - uploaded.secret_ = BufferSlice(file.encrypted_secret); - uploaded.file_hash_ = BufferSlice(file.file_hash); - }, - [&](telegram_api::inputSecureFile &) { UNREACHABLE(); })); + auto file_view = file_manager->get_file_view(file.file.file_id); + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + return full_remote_location->as_input_secure_file(); + } + CHECK(res->get_id() == telegram_api::inputSecureFileUploaded::ID); + auto uploaded = static_cast(res.get()); + uploaded->secret_ = BufferSlice(file.encrypted_secret); + uploaded->file_hash_ = BufferSlice(file.file_hash); return res; } @@ -423,7 +423,8 @@ static td_api::object_ptr get_dated_file_object(FileManager * auto file_id = dated_file.file_id; CHECK(file_id.is_valid()); auto file_view = file_manager->get_file_view(file_id); - if (!file_view.has_remote_location() || file_view.remote_location().is_web()) { + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location == nullptr || full_remote_location->is_web()) { LOG(ERROR) << "Have wrong file in get_dated_file_object"; return nullptr; } @@ -433,9 +434,8 @@ static td_api::object_ptr get_dated_file_object(FileManager * return get_dated_file_object(file_manager, dated_file); } dated_file.file_id = file_manager->register_remote( - FullRemoteFileLocation(FileType::SecureDecrypted, file_view.remote_location().get_id(), - file_view.remote_location().get_access_hash(), file_view.remote_location().get_dc_id(), - ""), + FullRemoteFileLocation(FileType::SecureDecrypted, full_remote_location->get_id(), + full_remote_location->get_access_hash(), full_remote_location->get_dc_id(), ""), FileLocationSource::FromServer, DialogId(), 0, file_view.expected_size(), file_view.suggested_path()); return get_dated_file_object(file_manager, dated_file); } @@ -802,19 +802,19 @@ static Result> get_personal_details_ } auto &object = value.get_object(); - TRY_RESULT(first_name, get_json_object_string_field(object, "first_name")); - TRY_RESULT(middle_name, get_json_object_string_field(object, "middle_name")); - TRY_RESULT(last_name, get_json_object_string_field(object, "last_name")); - TRY_RESULT(native_first_name, get_json_object_string_field(object, "first_name_native")); - TRY_RESULT(native_middle_name, get_json_object_string_field(object, "middle_name_native")); - TRY_RESULT(native_last_name, get_json_object_string_field(object, "last_name_native")); - TRY_RESULT(birthdate, get_json_object_string_field(object, "birth_date")); + TRY_RESULT(first_name, object.get_optional_string_field("first_name")); + TRY_RESULT(middle_name, object.get_optional_string_field("middle_name")); + TRY_RESULT(last_name, object.get_optional_string_field("last_name")); + TRY_RESULT(native_first_name, object.get_optional_string_field("first_name_native")); + TRY_RESULT(native_middle_name, object.get_optional_string_field("middle_name_native")); + TRY_RESULT(native_last_name, object.get_optional_string_field("last_name_native")); + TRY_RESULT(birthdate, object.get_optional_string_field("birth_date")); if (birthdate.empty()) { return Status::Error(400, "Birthdate must be non-empty"); } - TRY_RESULT(gender, get_json_object_string_field(object, "gender")); - TRY_RESULT(country_code, get_json_object_string_field(object, "country_code")); - TRY_RESULT(residence_country_code, get_json_object_string_field(object, "residence_country_code")); + TRY_RESULT(gender, object.get_optional_string_field("gender")); + TRY_RESULT(country_code, object.get_optional_string_field("country_code")); + TRY_RESULT(residence_country_code, object.get_optional_string_field("residence_country_code")); TRY_STATUS(check_name(first_name)); TRY_STATUS(check_name(middle_name)); @@ -872,7 +872,7 @@ static Result get_identity_document(SecureValueType type, FileManag return Status::Error(400, "Identity document must be non-empty"); } TRY_STATUS(check_document_number(identity_document->number_)); - TRY_RESULT(date, get_date(std::move(identity_document->expiry_date_))); + TRY_RESULT(date, get_date(std::move(identity_document->expiration_date_))); SecureValue res; res.type = type; @@ -936,8 +936,8 @@ static Result> get_identity_documen } auto &object = json_value.get_object(); - TRY_RESULT(number, get_json_object_string_field(object, "document_no")); - TRY_RESULT(expiry_date, get_json_object_string_field(object, "expiry_date")); + TRY_RESULT(number, object.get_optional_string_field("document_no")); + TRY_RESULT(expiry_date, object.get_optional_string_field("expiry_date")); TRY_STATUS(check_document_number(number)); TRY_RESULT(date, get_date_object(expiry_date)); diff --git a/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.cpp b/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.cpp index 9c24213590..f8091d5589 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.cpp @@ -1,14 +1,18 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/SendCodeHelper.h" +#include "td/telegram/misc.h" + #include "td/utils/base64.h" #include "td/utils/buffer.h" +#include "td/utils/logging.h" #include "td/utils/Time.h" +#include "td/utils/utf8.h" namespace td { @@ -19,7 +23,8 @@ void SendCodeHelper::on_sent_code(telegram_api::object_ptrtimeout_; if (next_code_info_.type == AuthenticationCodeInfo::Type::None && - (sent_code_info_.type == AuthenticationCodeInfo::Type::FirebaseAndroid || + (sent_code_info_.type == AuthenticationCodeInfo::Type::FirebaseAndroidSafetyNet || + sent_code_info_.type == AuthenticationCodeInfo::Type::FirebaseAndroidPlayIntegrity || sent_code_info_.type == AuthenticationCodeInfo::Type::FirebaseIos)) { next_code_info_ = {AuthenticationCodeInfo::Type::Sms, sent_code_info_.length, string()}; } @@ -40,11 +45,20 @@ td_api::object_ptr SendCodeHelper::get_authentic max(static_cast(next_code_timestamp_ - Time::now() + 1 - 1e-9), 0)); } -Result SendCodeHelper::resend_code() const { +Result SendCodeHelper::resend_code( + td_api::object_ptr &&reason) const { if (next_code_info_.type == AuthenticationCodeInfo::Type::None) { return Status::Error(400, "Authentication code can't be resend"); } - return telegram_api::auth_resendCode(phone_number_, phone_code_hash_); + int32 flags = 0; + string reason_str; + if (reason->get_id() == td_api::resendCodeReasonVerificationFailed::ID) { + reason_str = std::move(static_cast(reason.get())->error_message_); + } + if (!reason_str.empty() && clean_input_string(reason_str)) { + flags |= telegram_api::auth_resendCode::REASON_MASK; + } + return telegram_api::auth_resendCode(flags, phone_number_, phone_code_hash_, reason_str); } telegram_api::object_ptr SendCodeHelper::get_input_code_settings(const Settings &settings) { @@ -62,6 +76,9 @@ telegram_api::object_ptr SendCodeHelper::get_input_c if (settings->is_current_phone_number_) { flags |= telegram_api::codeSettings::CURRENT_NUMBER_MASK; } + if (settings->has_unknown_phone_number_) { + flags |= telegram_api::codeSettings::UNKNOWN_NUMBER_MASK; + } if (settings->allow_sms_retriever_api_) { flags |= telegram_api::codeSettings::ALLOW_APP_HASH_MASK; } @@ -89,9 +106,9 @@ telegram_api::object_ptr SendCodeHelper::get_input_c flags |= telegram_api::codeSettings::LOGOUT_TOKENS_MASK; } } - return telegram_api::make_object(flags, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, - std::move(logout_tokens), device_token, is_app_sandbox); + return telegram_api::make_object( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, std::move(logout_tokens), device_token, is_app_sandbox); } telegram_api::auth_sendCode SendCodeHelper::send_code(string phone_number, const Settings &settings, int32 api_id, @@ -102,17 +119,29 @@ telegram_api::auth_sendCode SendCodeHelper::send_code(string phone_number, const telegram_api::auth_requestFirebaseSms SendCodeHelper::request_firebase_sms(const string &token) { string safety_net_token; + string play_integrity_token; string ios_push_secret; int32 flags = 0; #if TD_ANDROID - flags |= telegram_api::auth_requestFirebaseSms::SAFETY_NET_TOKEN_MASK; - safety_net_token = token; + if (sent_code_info_.type == AuthenticationCodeInfo::Type::FirebaseAndroidSafetyNet) { + flags |= telegram_api::auth_requestFirebaseSms::SAFETY_NET_TOKEN_MASK; + safety_net_token = token; + } else if (sent_code_info_.type == AuthenticationCodeInfo::Type::FirebaseAndroidPlayIntegrity) { + flags |= telegram_api::auth_requestFirebaseSms::PLAY_INTEGRITY_TOKEN_MASK; + play_integrity_token = token; + } #elif TD_DARWIN - flags |= telegram_api::auth_requestFirebaseSms::IOS_PUSH_SECRET_MASK; - ios_push_secret = token; + if (sent_code_info_.type == AuthenticationCodeInfo::Type::FirebaseIos) { + flags |= telegram_api::auth_requestFirebaseSms::IOS_PUSH_SECRET_MASK; + ios_push_secret = token; + } #endif return telegram_api::auth_requestFirebaseSms(flags, phone_number_, phone_code_hash_, safety_net_token, - ios_push_secret); + play_integrity_token, ios_push_secret); +} + +telegram_api::auth_reportMissingCode SendCodeHelper::report_missing_code(const string &mobile_network_code) { + return telegram_api::auth_reportMissingCode(phone_number_, phone_code_hash_, mobile_network_code); } telegram_api::account_sendVerifyEmailCode SendCodeHelper::send_verify_email_code(const string &email_address) { @@ -193,16 +222,36 @@ SendCodeHelper::AuthenticationCodeInfo SendCodeHelper::get_sent_authentication_c } case telegram_api::auth_sentCodeTypeFirebaseSms::ID: { auto code_type = move_tl_object_as(sent_code_type_ptr); +#if TD_ANDROID if ((code_type->flags_ & telegram_api::auth_sentCodeTypeFirebaseSms::NONCE_MASK) != 0) { - return AuthenticationCodeInfo{AuthenticationCodeInfo::Type::FirebaseAndroid, code_type->length_, + return AuthenticationCodeInfo{AuthenticationCodeInfo::Type::FirebaseAndroidSafetyNet, code_type->length_, code_type->nonce_.as_slice().str()}; } + if ((code_type->flags_ & telegram_api::auth_sentCodeTypeFirebaseSms::PLAY_INTEGRITY_NONCE_MASK) != 0) { + return AuthenticationCodeInfo{AuthenticationCodeInfo::Type::FirebaseAndroidPlayIntegrity, code_type->length_, + code_type->play_integrity_nonce_.as_slice().str(), 0, + code_type->play_integrity_project_id_}; + } +#elif TD_DARWIN if ((code_type->flags_ & telegram_api::auth_sentCodeTypeFirebaseSms::RECEIPT_MASK) != 0) { return AuthenticationCodeInfo{AuthenticationCodeInfo::Type::FirebaseIos, code_type->length_, std::move(code_type->receipt_), code_type->push_timeout_}; } +#endif return AuthenticationCodeInfo{AuthenticationCodeInfo::Type::Sms, code_type->length_, ""}; } + case telegram_api::auth_sentCodeTypeSmsWord::ID: { + auto code_type = move_tl_object_as(sent_code_type_ptr); + if (utf8_length(code_type->beginning_) > 1u) { + LOG(ERROR) << "Receive \"" << code_type->beginning_ << "\" as word first letter"; + code_type->beginning_ = string(); + } + return AuthenticationCodeInfo{AuthenticationCodeInfo::Type::SmsWord, 0, code_type->beginning_}; + } + case telegram_api::auth_sentCodeTypeSmsPhrase::ID: { + auto code_type = move_tl_object_as(sent_code_type_ptr); + return AuthenticationCodeInfo{AuthenticationCodeInfo::Type::SmsPhrase, 0, code_type->beginning_}; + } case telegram_api::auth_sentCodeTypeEmailCode::ID: case telegram_api::auth_sentCodeTypeSetUpEmailRequired::ID: default: @@ -230,12 +279,22 @@ td_api::object_ptr SendCodeHelper::get_authentic case AuthenticationCodeInfo::Type::Fragment: return td_api::make_object(authentication_code_info.pattern, authentication_code_info.length); - case AuthenticationCodeInfo::Type::FirebaseAndroid: - return td_api::make_object(authentication_code_info.pattern, - authentication_code_info.length); + case AuthenticationCodeInfo::Type::FirebaseAndroidSafetyNet: + return td_api::make_object( + td_api::make_object(authentication_code_info.pattern), + authentication_code_info.length); + case AuthenticationCodeInfo::Type::FirebaseAndroidPlayIntegrity: + return td_api::make_object( + td_api::make_object( + base64url_encode(authentication_code_info.pattern), authentication_code_info.cloud_project_number), + authentication_code_info.length); case AuthenticationCodeInfo::Type::FirebaseIos: return td_api::make_object( authentication_code_info.pattern, authentication_code_info.push_timeout, authentication_code_info.length); + case AuthenticationCodeInfo::Type::SmsWord: + return td_api::make_object(authentication_code_info.pattern); + case AuthenticationCodeInfo::Type::SmsPhrase: + return td_api::make_object(authentication_code_info.pattern); default: UNREACHABLE(); return nullptr; diff --git a/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.h b/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.h index 25d3a34342..3b356253fd 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.h +++ b/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -25,7 +25,7 @@ class SendCodeHelper { td_api::object_ptr get_authentication_code_info_object() const; - Result resend_code() const; + Result resend_code(td_api::object_ptr &&reason) const; using Settings = td_api::object_ptr; @@ -34,6 +34,8 @@ class SendCodeHelper { telegram_api::auth_requestFirebaseSms request_firebase_sms(const string &token); + telegram_api::auth_reportMissingCode report_missing_code(const string &mobile_network_code); + telegram_api::account_sendVerifyEmailCode send_verify_email_code(const string &email_address); telegram_api::account_sendChangePhoneCode send_change_phone_code(Slice phone_number, const Settings &settings); @@ -59,15 +61,34 @@ class SendCodeHelper { private: struct AuthenticationCodeInfo { - enum class Type : int32 { None, Message, Sms, Call, FlashCall, MissedCall, Fragment, FirebaseAndroid, FirebaseIos }; + enum class Type : int32 { + None, + Message, + Sms, + Call, + FlashCall, + MissedCall, + Fragment, + FirebaseAndroidSafetyNet, + FirebaseIos, + SmsWord, + SmsPhrase, + FirebaseAndroidPlayIntegrity + }; Type type = Type::None; int32 length = 0; int32 push_timeout = 0; + int64 cloud_project_number = 0; string pattern; AuthenticationCodeInfo() = default; - AuthenticationCodeInfo(Type type, int32 length, string pattern, int32 push_timeout = 0) - : type(type), length(length), push_timeout(push_timeout), pattern(std::move(pattern)) { + AuthenticationCodeInfo(Type type, int32 length, string pattern, int32 push_timeout = 0, + int64 cloud_project_number = 0) + : type(type) + , length(length) + , push_timeout(push_timeout) + , cloud_project_number(cloud_project_number) + , pattern(std::move(pattern)) { } template diff --git a/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.hpp b/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.hpp index 04141680c0..59f380c717 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SendCodeHelper.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -19,6 +19,7 @@ void SendCodeHelper::AuthenticationCodeInfo::store(StorerT &storer) const { store(type, storer); store(length, storer); store(push_timeout, storer); + store(cloud_project_number, storer); store(pattern, storer); } @@ -28,6 +29,7 @@ void SendCodeHelper::AuthenticationCodeInfo::parse(ParserT &parser) { parse(type, parser); parse(length, parser); parse(push_timeout, parser); + parse(cloud_project_number, parser); parse(pattern, parser); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.cpp b/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.cpp new file mode 100644 index 0000000000..edcfb44f8f --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.cpp @@ -0,0 +1,83 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/SharedDialog.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/ChannelId.h" +#include "td/telegram/ChatId.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" + +namespace td { + +SharedDialog::SharedDialog(Td *td, telegram_api::object_ptr &&requested_peer_ptr) { + CHECK(requested_peer_ptr != nullptr); + switch (requested_peer_ptr->get_id()) { + case telegram_api::requestedPeerUser::ID: { + auto requested_peer = telegram_api::move_object_as(requested_peer_ptr); + dialog_id_ = DialogId(UserId(requested_peer->user_id_)); + first_name_ = std::move(requested_peer->first_name_); + last_name_ = std::move(requested_peer->last_name_); + username_ = std::move(requested_peer->username_); + photo_ = get_photo(td, std::move(requested_peer->photo_), dialog_id_); + break; + } + case telegram_api::requestedPeerChat::ID: { + auto requested_peer = telegram_api::move_object_as(requested_peer_ptr); + dialog_id_ = DialogId(ChatId(requested_peer->chat_id_)); + first_name_ = std::move(requested_peer->title_); + photo_ = get_photo(td, std::move(requested_peer->photo_), dialog_id_); + break; + } + case telegram_api::requestedPeerChannel::ID: { + auto requested_peer = telegram_api::move_object_as(requested_peer_ptr); + dialog_id_ = DialogId(ChannelId(requested_peer->channel_id_)); + first_name_ = std::move(requested_peer->title_); + username_ = std::move(requested_peer->username_); + photo_ = get_photo(td, std::move(requested_peer->photo_), dialog_id_); + break; + } + default: + UNREACHABLE(); + } +} + +td_api::object_ptr SharedDialog::get_shared_user_object(Td *td) const { + CHECK(is_user()); + auto user_id = td->auth_manager_->is_bot() + ? dialog_id_.get_user_id().get() + : td->user_manager_->get_user_id_object(dialog_id_.get_user_id(), "sharedUser"); + return td_api::make_object(user_id, first_name_, last_name_, username_, + get_photo_object(td->file_manager_.get(), photo_)); +} + +td_api::object_ptr SharedDialog::get_shared_chat_object(Td *td) const { + CHECK(is_dialog()); + auto chat_id = td->auth_manager_->is_bot() ? dialog_id_.get() + : td->dialog_manager_->get_chat_id_object(dialog_id_, "sharedChat"); + return td_api::make_object(chat_id, first_name_, username_, + get_photo_object(td->file_manager_.get(), photo_)); +} + +bool operator==(const SharedDialog &lhs, const SharedDialog &rhs) { + return lhs.dialog_id_ == rhs.dialog_id_ && lhs.first_name_ == rhs.first_name_ && lhs.last_name_ == rhs.last_name_ && + lhs.username_ == rhs.username_ && lhs.photo_ == rhs.photo_; +} + +bool operator!=(const SharedDialog &lhs, const SharedDialog &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const SharedDialog &shared_dialog) { + return string_builder << "shared " << shared_dialog.dialog_id_ << '(' << shared_dialog.first_name_ << ' ' + << shared_dialog.last_name_ << ' ' << shared_dialog.username_ << ' ' << shared_dialog.photo_ + << ')'; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.h b/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.h new file mode 100644 index 0000000000..3258cbafad --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.h @@ -0,0 +1,71 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/Photo.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Td; + +class SharedDialog { + public: + SharedDialog() = default; + + explicit SharedDialog(DialogId dialog_id) : dialog_id_(dialog_id) { + } + + SharedDialog(Td *td, telegram_api::object_ptr &&requested_peer_ptr); + + bool is_valid() const { + return dialog_id_.is_valid(); + } + + bool is_user() const { + return dialog_id_.get_type() == DialogType::User; + } + + bool is_dialog() const { + auto dialog_type = dialog_id_.get_type(); + return dialog_type == DialogType::Chat || dialog_type == DialogType::Channel; + } + + td_api::object_ptr get_shared_user_object(Td *td) const; + + td_api::object_ptr get_shared_chat_object(Td *td) const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + + private: + friend bool operator==(const SharedDialog &lhs, const SharedDialog &rhs); + friend bool operator!=(const SharedDialog &lhs, const SharedDialog &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const SharedDialog &shared_dialog); + + DialogId dialog_id_; + string first_name_; + string last_name_; + string username_; + Photo photo_; +}; + +bool operator==(const SharedDialog &lhs, const SharedDialog &rhs); +bool operator!=(const SharedDialog &lhs, const SharedDialog &rhs); + +StringBuilder &operator<<(StringBuilder &string_builder, const SharedDialog &shared_dialog); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.hpp b/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.hpp new file mode 100644 index 0000000000..ae050612bb --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SharedDialog.hpp @@ -0,0 +1,70 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/Photo.hpp" +#include "td/telegram/SharedDialog.h" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void SharedDialog::store(StorerT &storer) const { + bool has_first_name = !first_name_.empty(); + bool has_last_name = !last_name_.empty(); + bool has_username = !username_.empty(); + bool has_photo = !photo_.is_empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_first_name); + STORE_FLAG(has_last_name); + STORE_FLAG(has_username); + STORE_FLAG(has_photo); + END_STORE_FLAGS(); + td::store(dialog_id_, storer); + if (has_first_name) { + td::store(first_name_, storer); + } + if (has_last_name) { + td::store(last_name_, storer); + } + if (has_username) { + td::store(username_, storer); + } + if (has_photo) { + td::store(photo_, storer); + } +} + +template +void SharedDialog::parse(ParserT &parser) { + bool has_first_name; + bool has_last_name; + bool has_username; + bool has_photo; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_first_name); + PARSE_FLAG(has_last_name); + PARSE_FLAG(has_username); + PARSE_FLAG(has_photo); + END_PARSE_FLAGS(); + td::parse(dialog_id_, parser); + if (has_first_name) { + td::parse(first_name_, parser); + } + if (has_last_name) { + td::parse(last_name_, parser); + } + if (has_username) { + td::parse(username_, parser); + } + if (has_photo) { + td::parse(photo_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SpecialStickerSetType.cpp b/protocols/Telegram/tdlib/td/td/telegram/SpecialStickerSetType.cpp index 7d6ae2e633..c8b53a4c7a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SpecialStickerSetType.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SpecialStickerSetType.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -37,6 +37,10 @@ SpecialStickerSetType SpecialStickerSetType::default_statuses() { return SpecialStickerSetType("default_statuses_sticker_set"); } +SpecialStickerSetType SpecialStickerSetType::default_channel_statuses() { + return SpecialStickerSetType("default_channel_statuses_sticker_set"); +} + SpecialStickerSetType SpecialStickerSetType::default_topic_icons() { return SpecialStickerSetType("default_topic_icons_sticker_set"); } @@ -63,6 +67,9 @@ SpecialStickerSetType::SpecialStickerSetType( case telegram_api::inputStickerSetEmojiDefaultStatuses::ID: *this = default_statuses(); break; + case telegram_api::inputStickerSetEmojiChannelDefaultStatuses::ID: + *this = default_channel_statuses(); + break; case telegram_api::inputStickerSetEmojiDefaultTopicIcons::ID: *this = default_topic_icons(); break; @@ -96,6 +103,9 @@ telegram_api::object_ptr SpecialStickerSetType::g if (*this == default_statuses()) { return telegram_api::make_object(); } + if (*this == default_channel_statuses()) { + return telegram_api::make_object(); + } if (*this == default_topic_icons()) { return telegram_api::make_object(); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/SpecialStickerSetType.h b/protocols/Telegram/tdlib/td/td/telegram/SpecialStickerSetType.h index df7c1f0c03..35eca97c59 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SpecialStickerSetType.h +++ b/protocols/Telegram/tdlib/td/td/telegram/SpecialStickerSetType.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -34,6 +34,8 @@ class SpecialStickerSetType { static SpecialStickerSetType default_statuses(); + static SpecialStickerSetType default_channel_statuses(); + static SpecialStickerSetType default_topic_icons(); string get_dice_emoji() const; diff --git a/protocols/Telegram/tdlib/td/td/telegram/SponsoredMessageManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/SponsoredMessageManager.cpp index 6770d97fb0..745c0f8f5c 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SponsoredMessageManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SponsoredMessageManager.cpp @@ -1,29 +1,33 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/SponsoredMessageManager.h" +#include "td/telegram/AccentColorId.h" #include "td/telegram/ChannelId.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Global.h" -#include "td/telegram/LinkManager.h" #include "td/telegram/MessageContent.h" +#include "td/telegram/MessageContentType.h" #include "td/telegram/MessageEntity.h" -#include "td/telegram/MessagesManager.h" +#include "td/telegram/MessageSelfDestructType.h" #include "td/telegram/net/NetQueryCreator.h" #include "td/telegram/OptionManager.h" -#include "td/telegram/ServerMessageId.h" +#include "td/telegram/PeerColor.h" +#include "td/telegram/Photo.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/ThemeManager.h" #include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" #include "td/utils/logging.h" -#include "td/utils/SliceBuilder.h" #include "td/utils/Status.h" namespace td { @@ -40,7 +44,7 @@ class GetSponsoredMessagesQuery final : public Td::ResultHandler { void send(ChannelId channel_id) { channel_id_ = channel_id; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return promise_.set_error(Status::Error(400, "Chat info not found")); } @@ -53,11 +57,13 @@ class GetSponsoredMessagesQuery final : public Td::ResultHandler { return on_error(result_ptr.move_as_error()); } - promise_.set_value(result_ptr.move_as_ok()); + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetSponsoredMessagesQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr)); } void on_error(Status status) final { - td_->contacts_manager_->on_get_channel_error(channel_id_, status, "GetSponsoredMessagesQuery"); + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetSponsoredMessagesQuery"); promise_.set_error(std::move(status)); } }; @@ -68,7 +74,7 @@ class ViewSponsoredMessageQuery final : public Td::ResultHandler { public: void send(ChannelId channel_id, const string &message_id) { channel_id_ = channel_id; - auto input_channel = td_->contacts_manager_->get_input_channel(channel_id); + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); if (input_channel == nullptr) { return; } @@ -84,42 +90,145 @@ class ViewSponsoredMessageQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->contacts_manager_->on_get_channel_error(channel_id_, status, "ViewSponsoredMessageQuery"); + td_->chat_manager_->on_get_channel_error(channel_id_, status, "ViewSponsoredMessageQuery"); + } +}; + +class ClickSponsoredMessageQuery final : public Td::ResultHandler { + Promise promise_; + ChannelId channel_id_; + + public: + explicit ClickSponsoredMessageQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, const string &message_id) { + channel_id_ = channel_id; + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); + if (input_channel == nullptr) { + return promise_.set_value(Unit()); + } + send_query(G()->net_query_creator().create( + telegram_api::channels_clickSponsoredMessage(std::move(input_channel), BufferSlice(message_id)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "ClickSponsoredMessageQuery"); + promise_.set_error(std::move(status)); + } +}; + +class ReportSponsoredMessageQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit ReportSponsoredMessageQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, const string &message_id, const string &option_id) { + channel_id_ = channel_id; + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); + if (input_channel == nullptr) { + return promise_.set_value(td_api::make_object()); + } + send_query(G()->net_query_creator().create(telegram_api::channels_reportSponsoredMessage( + std::move(input_channel), BufferSlice(message_id), BufferSlice(option_id)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for ReportSponsoredMessageQuery: " << to_string(ptr); + switch (ptr->get_id()) { + case telegram_api::channels_sponsoredMessageReportResultReported::ID: + return promise_.set_value(td_api::make_object()); + case telegram_api::channels_sponsoredMessageReportResultAdsHidden::ID: + return promise_.set_value(td_api::make_object()); + case telegram_api::channels_sponsoredMessageReportResultChooseOption::ID: { + auto options = + telegram_api::move_object_as(ptr); + if (options->options_.empty()) { + return promise_.set_value(td_api::make_object()); + } + vector> report_options; + for (auto &option : options->options_) { + report_options.push_back(td_api::make_object( + option->option_.as_slice().str(), option->text_)); + } + return promise_.set_value(td_api::make_object( + options->title_, std::move(report_options))); + } + default: + UNREACHABLE(); + } + } + + void on_error(Status status) final { + if (status.message() == "AD_EXPIRED") { + return promise_.set_value(td_api::make_object()); + } + if (status.message() == "PREMIUM_ACCOUNT_REQUIRED") { + return promise_.set_value(td_api::make_object()); + } + td_->chat_manager_->on_get_channel_error(channel_id_, status, "ReportSponsoredMessageQuery"); + promise_.set_error(std::move(status)); } }; struct SponsoredMessageManager::SponsoredMessage { int64 local_id = 0; bool is_recommended = false; - bool show_dialog_photo = false; - DialogId sponsor_dialog_id; - ServerMessageId server_message_id; - string start_param; - string invite_hash; + bool can_be_reported = false; unique_ptr content; + string url; + Photo photo; + string title; + string button_text; + PeerColor peer_color; string sponsor_info; string additional_info; - SponsoredMessage(int64 local_id, bool is_recommended, bool show_dialog_photo, DialogId sponsor_dialog_id, - ServerMessageId server_message_id, string start_param, string invite_hash, - unique_ptr content, string sponsor_info, string additional_info) + SponsoredMessage(int64 local_id, bool is_recommended, bool can_be_reported, unique_ptr content, + string url, Photo photo, string title, string button_text, PeerColor peer_color, string sponsor_info, + string additional_info) : local_id(local_id) , is_recommended(is_recommended) - , show_dialog_photo(show_dialog_photo) - , sponsor_dialog_id(sponsor_dialog_id) - , server_message_id(server_message_id) - , start_param(std::move(start_param)) - , invite_hash(std::move(invite_hash)) + , can_be_reported(can_be_reported) , content(std::move(content)) + , url(std::move(url)) + , photo(std::move(photo)) + , title(std::move(title)) + , button_text(std::move(button_text)) + , peer_color(std::move(peer_color)) , sponsor_info(std::move(sponsor_info)) , additional_info(std::move(additional_info)) { } }; +struct SponsoredMessageManager::SponsoredMessageInfo { + string random_id_; + bool is_viewed_ = false; + bool is_clicked_ = false; +}; + struct SponsoredMessageManager::DialogSponsoredMessages { vector>> promises; vector messages; - FlatHashMap message_random_ids; + FlatHashMap message_infos; int32 messages_between = 0; bool is_premium = false; }; @@ -157,63 +266,26 @@ void SponsoredMessageManager::delete_cached_sponsored_messages(DialogId dialog_i } } +td_api::object_ptr SponsoredMessageManager::get_message_sponsor_object( + const SponsoredMessage &sponsored_message) const { + return td_api::make_object( + sponsored_message.url, get_photo_object(td_->file_manager_.get(), sponsored_message.photo), + sponsored_message.sponsor_info); +} + td_api::object_ptr SponsoredMessageManager::get_sponsored_message_object( DialogId dialog_id, const SponsoredMessage &sponsored_message) const { - td_api::object_ptr chat_invite_link_info; - td_api::object_ptr link; - switch (sponsored_message.sponsor_dialog_id.get_type()) { - case DialogType::User: { - auto user_id = sponsored_message.sponsor_dialog_id.get_user_id(); - if (!td_->contacts_manager_->is_user_bot(user_id)) { - LOG(ERROR) << "Sponsor " << user_id << " is not a bot"; - return nullptr; - } - auto bot_username = td_->contacts_manager_->get_user_first_username(user_id); - if (bot_username.empty()) { - LOG(ERROR) << "Sponsor " << user_id << " has no username"; - return nullptr; - } - link = td_api::make_object(bot_username, sponsored_message.start_param, false); - break; - } - case DialogType::Channel: { - auto channel_id = sponsored_message.sponsor_dialog_id.get_channel_id(); - if (!td_->contacts_manager_->is_broadcast_channel(channel_id)) { - LOG(ERROR) << "Sponsor " << channel_id << " is not a channel"; - return nullptr; - } - if (sponsored_message.server_message_id.is_valid()) { - link = td_api::make_object( - PSTRING() << LinkManager::get_t_me_url() << "c/" << channel_id.get() << '/' - << sponsored_message.server_message_id.get()); - } - break; - } - case DialogType::None: { - CHECK(!sponsored_message.invite_hash.empty()); - auto invite_link = LinkManager::get_dialog_invite_link(sponsored_message.invite_hash, false); - chat_invite_link_info = td_->contacts_manager_->get_chat_invite_link_info_object(invite_link); - if (chat_invite_link_info == nullptr) { - LOG(ERROR) << "Failed to get invite link info for " << invite_link; - return nullptr; - } - if (chat_invite_link_info->type_->get_id() != td_api::chatTypeSupergroup::ID || - !static_cast(chat_invite_link_info->type_.get())->is_channel_) { - LOG(ERROR) << "Receive sponsor chat of a wrong type " << to_string(chat_invite_link_info->type_); - return nullptr; - } - link = td_api::make_object( - LinkManager::get_dialog_invite_link(sponsored_message.invite_hash, true)); - } - default: - break; + auto sponsor = get_message_sponsor_object(sponsored_message); + if (sponsor == nullptr) { + return nullptr; } return td_api::make_object( - sponsored_message.local_id, sponsored_message.is_recommended, - td_->messages_manager_->get_chat_id_object(sponsored_message.sponsor_dialog_id, "sponsoredMessage"), - std::move(chat_invite_link_info), sponsored_message.show_dialog_photo, std::move(link), - get_message_content_object(sponsored_message.content.get(), td_, dialog_id, 0, false, true, -1), - sponsored_message.sponsor_info, sponsored_message.additional_info); + sponsored_message.local_id, sponsored_message.is_recommended, sponsored_message.can_be_reported, + get_message_content_object(sponsored_message.content.get(), td_, dialog_id, true, false, 0, false, true, -1, + false, true), + std::move(sponsor), sponsored_message.title, sponsored_message.button_text, + td_->theme_manager_->get_accent_color_id_object(sponsored_message.peer_color.accent_color_id_, AccentColorId()), + sponsored_message.peer_color.background_custom_emoji_id_.get(), sponsored_message.additional_info); } td_api::object_ptr SponsoredMessageManager::get_sponsored_messages_object( @@ -227,7 +299,7 @@ td_api::object_ptr SponsoredMessageManager::get_spons void SponsoredMessageManager::get_dialog_sponsored_messages( DialogId dialog_id, Promise> &&promise) { - if (!td_->messages_manager_->have_dialog_force(dialog_id, "get_dialog_sponsored_message")) { + if (!td_->dialog_manager_->have_dialog_force(dialog_id, "get_dialog_sponsored_message")) { return promise.set_error(Status::Error(400, "Chat not found")); } if (dialog_id.get_type() != DialogType::Channel) { @@ -270,7 +342,7 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages( auto promises = std::move(messages->promises); reset_to_empty(messages->promises); CHECK(messages->messages.empty()); - CHECK(messages->message_random_ids.empty()); + CHECK(messages->message_infos.empty()); if (result.is_error()) { dialog_sponsored_messages_.erase(dialog_id); @@ -284,74 +356,55 @@ void SponsoredMessageManager::on_get_dialog_sponsored_messages( auto sponsored_messages = telegram_api::move_object_as(sponsored_messages_ptr); - td_->contacts_manager_->on_get_users(std::move(sponsored_messages->users_), "on_get_dialog_sponsored_messages"); - td_->contacts_manager_->on_get_chats(std::move(sponsored_messages->chats_), "on_get_dialog_sponsored_messages"); + td_->user_manager_->on_get_users(std::move(sponsored_messages->users_), "on_get_dialog_sponsored_messages"); + td_->chat_manager_->on_get_chats(std::move(sponsored_messages->chats_), "on_get_dialog_sponsored_messages"); for (auto &sponsored_message : sponsored_messages->messages_) { - DialogId sponsor_dialog_id; - ServerMessageId server_message_id; - string invite_hash; - if (sponsored_message->from_id_ != nullptr) { - sponsor_dialog_id = DialogId(sponsored_message->from_id_); - if (!sponsor_dialog_id.is_valid() || !td_->messages_manager_->have_dialog_info_force(sponsor_dialog_id)) { - LOG(ERROR) << "Receive unknown sponsor " << sponsor_dialog_id; - continue; - } - server_message_id = ServerMessageId(sponsored_message->channel_post_); - if (!server_message_id.is_valid() && server_message_id != ServerMessageId()) { - LOG(ERROR) << "Receive invalid channel post in " << to_string(sponsored_message); - server_message_id = ServerMessageId(); - } - td_->messages_manager_->force_create_dialog(sponsor_dialog_id, "on_get_dialog_sponsored_messages"); - } else if (sponsored_message->chat_invite_ != nullptr && !sponsored_message->chat_invite_hash_.empty()) { - auto invite_link = LinkManager::get_dialog_invite_link(sponsored_message->chat_invite_hash_, false); - if (invite_link.empty()) { - LOG(ERROR) << "Receive invalid invite link hash in " << to_string(sponsored_message); - continue; - } - auto chat_invite = to_string(sponsored_message->chat_invite_); - td_->contacts_manager_->on_get_dialog_invite_link_info( - invite_link, std::move(sponsored_message->chat_invite_), Promise()); - auto chat_invite_link_info = td_->contacts_manager_->get_chat_invite_link_info_object(invite_link); - if (chat_invite_link_info == nullptr) { - LOG(ERROR) << "Failed to get invite link info from " << chat_invite << " for " - << to_string(sponsored_message); - continue; - } - invite_hash = std::move(sponsored_message->chat_invite_hash_); - } else { - LOG(ERROR) << "Receive " << to_string(sponsored_message); - continue; - } - - auto message_text = get_message_text(td_->contacts_manager_.get(), std::move(sponsored_message->message_), + Photo photo = get_photo(td_, std::move(sponsored_message->photo_), DialogId()); + auto message_text = get_message_text(td_->user_manager_.get(), std::move(sponsored_message->message_), std::move(sponsored_message->entities_), true, true, 0, false, "on_get_dialog_sponsored_messages"); - int32 ttl = 0; - bool disable_web_page_preview = false; - auto content = get_message_content(td_, std::move(message_text), nullptr, sponsor_dialog_id, true, UserId(), - &ttl, &disable_web_page_preview, "on_get_dialog_sponsored_messages"); - if (ttl != 0) { - LOG(ERROR) << "Receive sponsored message with self-destruct time " << ttl; + MessageSelfDestructType ttl; + auto content = + get_message_content(td_, std::move(message_text), std::move(sponsored_message->media_), DialogId(), + G()->unix_time(), true, UserId(), &ttl, nullptr, "on_get_dialog_sponsored_messages"); + if (!ttl.is_empty()) { + LOG(ERROR) << "Receive sponsored message with " << ttl; + continue; + } + bool is_allowed_content_type = [&] { + switch (content->get_type()) { + case MessageContentType::Animation: + case MessageContentType::Photo: + case MessageContentType::Text: + case MessageContentType::Video: + return true; + default: + return false; + } + }(); + if (!is_allowed_content_type) { + LOG(ERROR) << "Receive sponsored message with " << content->get_type(); continue; } - CHECK(disable_web_page_preview); current_sponsored_message_id_ = current_sponsored_message_id_.get_next_message_id(MessageType::Local); if (!current_sponsored_message_id_.is_valid_sponsored()) { - LOG(ERROR) << "Sponsored message ID overflowed"; + LOG(ERROR) << "Sponsored message identifier overflowed"; current_sponsored_message_id_ = MessageId::max().get_next_message_id(MessageType::Local); CHECK(current_sponsored_message_id_.is_valid_sponsored()); } auto local_id = current_sponsored_message_id_.get(); CHECK(!current_sponsored_message_id_.is_valid()); CHECK(!current_sponsored_message_id_.is_scheduled()); - auto is_inserted = - messages->message_random_ids.emplace(local_id, sponsored_message->random_id_.as_slice().str()).second; + SponsoredMessageInfo message_info; + message_info.random_id_ = sponsored_message->random_id_.as_slice().str(); + auto is_inserted = messages->message_infos.emplace(local_id, std::move(message_info)).second; CHECK(is_inserted); messages->messages.emplace_back( - local_id, sponsored_message->recommended_, sponsored_message->show_peer_photo_, sponsor_dialog_id, - server_message_id, std::move(sponsored_message->start_param_), std::move(invite_hash), std::move(content), + local_id, sponsored_message->recommended_, sponsored_message->can_report_, std::move(content), + std::move(sponsored_message->url_), std::move(photo), std::move(sponsored_message->title_), + std::move(sponsored_message->button_text_), PeerColor(sponsored_message->color_), std::move(sponsored_message->sponsor_info_), std::move(sponsored_message->additional_info_)); } messages->messages_between = sponsored_messages->posts_between_; @@ -375,14 +428,51 @@ void SponsoredMessageManager::view_sponsored_message(DialogId dialog_id, Message if (it == dialog_sponsored_messages_.end()) { return; } - auto random_id_it = it->second->message_random_ids.find(sponsored_message_id.get()); - if (random_id_it == it->second->message_random_ids.end()) { + auto random_id_it = it->second->message_infos.find(sponsored_message_id.get()); + if (random_id_it == it->second->message_infos.end() || random_id_it->second.is_viewed_) { return; } - auto random_id = std::move(random_id_it->second); - it->second->message_random_ids.erase(random_id_it); - td_->create_handler()->send(dialog_id.get_channel_id(), random_id); + random_id_it->second.is_viewed_ = true; + td_->create_handler()->send(dialog_id.get_channel_id(), random_id_it->second.random_id_); +} + +void SponsoredMessageManager::click_sponsored_message(DialogId dialog_id, MessageId sponsored_message_id, + Promise &&promise) { + if (!dialog_id.is_valid() || !sponsored_message_id.is_valid_sponsored()) { + return promise.set_error(Status::Error(400, "Invalid message specified")); + } + auto it = dialog_sponsored_messages_.find(dialog_id); + if (it == dialog_sponsored_messages_.end()) { + return promise.set_value(Unit()); + } + auto random_id_it = it->second->message_infos.find(sponsored_message_id.get()); + if (random_id_it == it->second->message_infos.end() || random_id_it->second.is_clicked_) { + return promise.set_value(Unit()); + } + + random_id_it->second.is_clicked_ = true; + td_->create_handler(std::move(promise)) + ->send(dialog_id.get_channel_id(), random_id_it->second.random_id_); +} + +void SponsoredMessageManager::report_sponsored_message( + DialogId dialog_id, MessageId sponsored_message_id, const string &option_id, + Promise> &&promise) { + if (!dialog_id.is_valid() || !sponsored_message_id.is_valid_sponsored()) { + return promise.set_error(Status::Error(400, "Invalid message specified")); + } + auto it = dialog_sponsored_messages_.find(dialog_id); + if (it == dialog_sponsored_messages_.end()) { + return promise.set_value(td_api::make_object()); + } + auto random_id_it = it->second->message_infos.find(sponsored_message_id.get()); + if (random_id_it == it->second->message_infos.end()) { + return promise.set_value(td_api::make_object()); + } + + td_->create_handler(std::move(promise)) + ->send(dialog_id.get_channel_id(), random_id_it->second.random_id_, option_id); } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SponsoredMessageManager.h b/protocols/Telegram/tdlib/td/td/telegram/SponsoredMessageManager.h index ceda66e6ea..b28157d24c 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SponsoredMessageManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/SponsoredMessageManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -37,8 +37,14 @@ class SponsoredMessageManager final : public Actor { void view_sponsored_message(DialogId dialog_id, MessageId sponsored_message_id); + void click_sponsored_message(DialogId dialog_id, MessageId sponsored_message_id, Promise &&promise); + + void report_sponsored_message(DialogId dialog_id, MessageId sponsored_message_id, const string &option_id, + Promise> &&promise); + private: struct SponsoredMessage; + struct SponsoredMessageInfo; struct DialogSponsoredMessages; void tear_down() final; @@ -48,6 +54,9 @@ class SponsoredMessageManager final : public Actor { void delete_cached_sponsored_messages(DialogId dialog_id); + td_api::object_ptr get_message_sponsor_object( + const SponsoredMessage &sponsored_message) const; + td_api::object_ptr get_sponsored_message_object( DialogId dialog_id, const SponsoredMessage &sponsored_message) const; diff --git a/protocols/Telegram/tdlib/td/td/telegram/StarManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/StarManager.cpp new file mode 100644 index 0000000000..b17750555c --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StarManager.cpp @@ -0,0 +1,997 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StarManager.h" + +#include "td/telegram/AccessRights.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/FileReferenceManager.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/InputInvoice.h" +#include "td/telegram/MessageExtendedMedia.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessageSender.h" +#include "td/telegram/PasswordManager.h" +#include "td/telegram/Photo.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/StarSubscription.h" +#include "td/telegram/StatisticsManager.h" +#include "td/telegram/StickersManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/ScopeGuard.h" + +#include + +namespace td { + +class GetStarsTopupOptionsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetStarsTopupOptionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::payments_getStarsTopupOptions())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto results = result_ptr.move_as_ok(); + vector> options; + for (auto &result : results) { + options.push_back(td_api::make_object(result->currency_, result->amount_, + StarManager::get_star_count(result->stars_), + result->store_product_, result->extended_)); + } + + promise_.set_value(td_api::make_object(std::move(options))); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetStarsGiftOptionsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetStarsGiftOptionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(telegram_api::object_ptr input_user) { + int32 flags = 0; + if (input_user != nullptr) { + flags |= telegram_api::payments_getStarsGiftOptions::USER_ID_MASK; + } + send_query( + G()->net_query_creator().create(telegram_api::payments_getStarsGiftOptions(flags, std::move(input_user)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto results = result_ptr.move_as_ok(); + vector> options; + for (auto &result : results) { + options.push_back(td_api::make_object(result->currency_, result->amount_, + StarManager::get_star_count(result->stars_), + result->store_product_, result->extended_)); + } + + promise_.set_value(td_api::make_object(std::move(options))); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetStarsGiveawayOptionsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetStarsGiveawayOptionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::payments_getStarsGiveawayOptions())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto results = result_ptr.move_as_ok(); + vector> options; + for (auto &result : results) { + vector> winner_options; + for (auto &winner : result->winners_) { + winner_options.push_back(td_api::make_object( + winner->users_, StarManager::get_star_count(winner->per_user_stars_), winner->default_)); + } + options.push_back(td_api::make_object( + result->currency_, result->amount_, StarManager::get_star_count(result->stars_), result->store_product_, + result->yearly_boosts_, std::move(winner_options), result->default_, result->extended_)); + } + + promise_.set_value(td_api::make_object(std::move(options))); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetStarsTransactionsQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetStarsTransactionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, const string &subscription_id, const string &offset, int32 limit, + td_api::object_ptr &&direction) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Have no access to the chat")); + } + int32 flags = 0; + if (!subscription_id.empty()) { + flags |= telegram_api::payments_getStarsTransactions::SUBSCRIPTION_ID_MASK; + } + if (direction != nullptr) { + switch (direction->get_id()) { + case td_api::starTransactionDirectionIncoming::ID: + flags |= telegram_api::payments_getStarsTransactions::INBOUND_MASK; + break; + case td_api::starTransactionDirectionOutgoing::ID: + flags |= telegram_api::payments_getStarsTransactions::OUTBOUND_MASK; + break; + default: + UNREACHABLE(); + } + } + if (td_->auth_manager_->is_bot()) { + flags |= telegram_api::payments_getStarsTransactions::ASCENDING_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::payments_getStarsTransactions(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, + subscription_id, std::move(input_peer), offset, limit))); + } + + void send(DialogId dialog_id, const string &transaction_id, bool is_refund) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Have no access to the chat")); + } + int32 flags = 0; + if (is_refund) { + flags |= telegram_api::inputStarsTransaction::REFUND_MASK; + } + vector> transaction_ids; + transaction_ids.push_back( + telegram_api::make_object(flags, false /*ignored*/, transaction_id)); + send_query(G()->net_query_creator().create( + telegram_api::payments_getStarsTransactionsByID(std::move(input_peer), std::move(transaction_ids)))); + } + + void on_result(BufferSlice packet) final { + static_assert(std::is_same::value, + ""); + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetStarsTransactionsQuery: " << to_string(result); + + td_->user_manager_->on_get_users(std::move(result->users_), "GetStarsTransactionsQuery"); + td_->chat_manager_->on_get_chats(std::move(result->chats_), "GetStarsTransactionsQuery"); + + auto star_count = StarManager::get_star_count(result->balance_, true); + bool for_bot = + (dialog_id_.get_type() == DialogType::User && td_->user_manager_->is_user_bot(dialog_id_.get_user_id())) || + td_->auth_manager_->is_bot(); + vector> transactions; + for (auto &transaction : result->history_) { + vector file_ids; + td_api::object_ptr product_info; + string bot_payload; + if (!transaction->title_.empty() || !transaction->description_.empty() || transaction->photo_ != nullptr) { + auto photo = get_web_document_photo(td_->file_manager_.get(), std::move(transaction->photo_), DialogId()); + append(file_ids, photo_get_file_ids(photo)); + product_info = get_product_info_object(td_, transaction->title_, transaction->description_, photo); + } + if (!transaction->bot_payload_.empty()) { + if (td_->auth_manager_->is_bot()) { + bot_payload = transaction->bot_payload_.as_slice().str(); + } else if (!for_bot) { + LOG(ERROR) << "Receive Star transaction with bot payload"; + } + } + auto get_paid_media_object = [&](DialogId dialog_id) -> vector> { + auto extended_media = transform(std::move(transaction->extended_media_), [td = td_, dialog_id](auto &&media) { + return MessageExtendedMedia(td, std::move(media), dialog_id); + }); + for (auto &media : extended_media) { + media.append_file_ids(td_, file_ids); + } + auto extended_media_objects = + transform(std::move(extended_media), [td = td_](auto &&media) { return media.get_paid_media_object(td); }); + transaction->extended_media_.clear(); + return extended_media_objects; + }; + auto partner = [&]() -> td_api::object_ptr { + switch (transaction->peer_->get_id()) { + case telegram_api::starsTransactionPeerUnsupported::ID: + return td_api::make_object(); + case telegram_api::starsTransactionPeerPremiumBot::ID: + return td_api::make_object(); + case telegram_api::starsTransactionPeerAppStore::ID: + return td_api::make_object(); + case telegram_api::starsTransactionPeerPlayMarket::ID: + return td_api::make_object(); + case telegram_api::starsTransactionPeerFragment::ID: { + if (transaction->gift_) { + transaction->gift_ = false; + return td_api::make_object( + 0, td_->stickers_manager_->get_premium_gift_sticker_object(0, star_count)); + } + auto state = [&]() -> td_api::object_ptr { + if (transaction->transaction_date_ > 0) { + SCOPE_EXIT { + transaction->transaction_date_ = 0; + transaction->transaction_url_.clear(); + }; + return td_api::make_object(transaction->transaction_date_, + transaction->transaction_url_); + } + if (transaction->pending_) { + SCOPE_EXIT { + transaction->pending_ = false; + }; + return td_api::make_object(); + } + if (transaction->failed_) { + SCOPE_EXIT { + transaction->failed_ = false; + }; + return td_api::make_object(); + } + if (!transaction->refund_) { + LOG(ERROR) << "Receive " << to_string(transaction); + } + return nullptr; + }(); + return td_api::make_object(std::move(state)); + } + case telegram_api::starsTransactionPeer::ID: { + DialogId dialog_id( + static_cast(transaction->peer_.get())->peer_); + if (dialog_id.get_type() == DialogType::User) { + auto user_id = dialog_id.get_user_id(); + if (for_bot == td_->user_manager_->is_user_bot(user_id)) { + if (transaction->gift_ && !for_bot) { + transaction->gift_ = false; + return td_api::make_object( + user_id == UserManager::get_service_notifications_user_id() + ? 0 + : td_->user_manager_->get_user_id_object(user_id, "starTransactionPartnerUser"), + td_->stickers_manager_->get_premium_gift_sticker_object(0, star_count)); + } + if (!transaction->extended_media_.empty()) { // TODO + return td_api::make_object( + td_->user_manager_->get_user_id_object(user_id, "starTransactionPartnerBusiness"), + get_paid_media_object(DialogId(user_id))); + } + LOG(ERROR) << "Receive Telegram Star transaction with " << user_id; + return td_api::make_object(); + } + SCOPE_EXIT { + bot_payload.clear(); + }; + if (product_info == nullptr || !transaction->extended_media_.empty()) { + return td_api::make_object( + td_->user_manager_->get_user_id_object(user_id, "starTransactionPartnerBot"), + td_api::make_object( + get_paid_media_object(DialogId(user_id)), bot_payload)); + } + return td_api::make_object( + td_->user_manager_->get_user_id_object(user_id, "starTransactionPartnerBot"), + td_api::make_object(std::move(product_info), + bot_payload)); + } + if (dialog_id.get_type() == DialogType::Channel && transaction->giveaway_post_id_ > 0) { + SCOPE_EXIT { + transaction->giveaway_post_id_ = 0; + }; + td_->dialog_manager_->force_create_dialog(dialog_id, "starsTransactionPeer", true); + return td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "starTransactionPartnerChat"), + td_api::make_object( + MessageId(ServerMessageId(transaction->giveaway_post_id_)).get())); + } + if (td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + if (transaction->subscription_period_ > 0) { + SCOPE_EXIT { + transaction->subscription_period_ = 0; + }; + td_->dialog_manager_->force_create_dialog(dialog_id, "starsTransactionPeer", true); + return td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "starTransactionPartnerChat"), + td_api::make_object(transaction->subscription_period_)); + } + if (transaction->reaction_) { + SCOPE_EXIT { + transaction->msg_id_ = 0; + transaction->reaction_ = false; + }; + auto message_id = MessageId(ServerMessageId(transaction->msg_id_)); + if (message_id != MessageId() && !message_id.is_valid()) { + LOG(ERROR) << "Receive " << message_id << " in " << to_string(transaction); + message_id = MessageId(); + } + td_->dialog_manager_->force_create_dialog(dialog_id, "starsTransactionPeer", true); + return td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "starTransactionPartnerChat"), + td_api::make_object(message_id.get())); + } + + SCOPE_EXIT { + transaction->msg_id_ = 0; + }; + auto message_id = MessageId(ServerMessageId(transaction->msg_id_)); + if (message_id != MessageId() && !message_id.is_valid()) { + LOG(ERROR) << "Receive " << message_id << " in " << to_string(transaction); + message_id = MessageId(); + } + td_->dialog_manager_->force_create_dialog(dialog_id, "starsTransactionPeer", true); + return td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "starTransactionPartnerChat"), + td_api::make_object(message_id.get(), + get_paid_media_object(dialog_id))); + } + LOG(ERROR) << "Receive Telegram Star transaction with " << dialog_id; + return td_api::make_object(); + } + case telegram_api::starsTransactionPeerAds::ID: + return td_api::make_object(); + default: + UNREACHABLE(); + } + }(); + auto star_transaction = td_api::make_object( + transaction->id_, StarManager::get_star_count(transaction->stars_, true), transaction->refund_, + transaction->date_, std::move(partner)); + if (star_transaction->partner_->get_id() != td_api::starTransactionPartnerUnsupported::ID) { + if (product_info != nullptr) { + LOG(ERROR) << "Receive product info with " << to_string(star_transaction); + } + if (!bot_payload.empty()) { + LOG(ERROR) << "Receive bot payload with " << to_string(star_transaction); + } + if (transaction->transaction_date_ || !transaction->transaction_url_.empty() || transaction->pending_ || + transaction->failed_) { + LOG(ERROR) << "Receive withdrawal state with " << to_string(star_transaction); + } + if (transaction->msg_id_ != 0) { + LOG(ERROR) << "Receive message identifier with " << to_string(star_transaction); + } + if (transaction->gift_) { + LOG(ERROR) << "Receive gift with " << to_string(star_transaction); + } + if (transaction->subscription_period_ != 0) { + LOG(ERROR) << "Receive subscription period with " << to_string(star_transaction); + } + if (transaction->reaction_) { + LOG(ERROR) << "Receive reaction with " << to_string(star_transaction); + } + if (!transaction->extended_media_.empty()) { + LOG(ERROR) << "Receive paid media with " << to_string(star_transaction); + } + if (transaction->giveaway_post_id_ != 0) { + LOG(ERROR) << "Receive giveaway message with " << to_string(star_transaction); + } + } + if (!file_ids.empty()) { + auto file_source_id = + td_->star_manager_->get_star_transaction_file_source_id(dialog_id_, transaction->id_, transaction->refund_); + for (auto file_id : file_ids) { + td_->file_manager_->add_file_source(file_id, file_source_id); + } + } + transactions.push_back(std::move(star_transaction)); + } + if (dialog_id_ == td_->dialog_manager_->get_my_dialog_id()) { + td_->star_manager_->on_update_owned_star_count(star_count); + } + + promise_.set_value( + td_api::make_object(star_count, std::move(transactions), result->next_offset_)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStarsTransactionsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStarsSubscriptionsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetStarsSubscriptionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(bool only_expiring, const string &offset) { + int32 flags = 0; + if (only_expiring) { + flags |= telegram_api::payments_getStarsSubscriptions::MISSING_BALANCE_MASK; + } + send_query(G()->net_query_creator().create(telegram_api::payments_getStarsSubscriptions( + flags, false /*ignored*/, telegram_api::make_object(), offset))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetStarsSubscriptionsQuery: " << to_string(result); + + td_->user_manager_->on_get_users(std::move(result->users_), "GetStarsSubscriptionsQuery"); + td_->chat_manager_->on_get_chats(std::move(result->chats_), "GetStarsSubscriptionsQuery"); + + vector> subscriptions; + for (auto &subscription : result->subscriptions_) { + StarSubscription star_subscription(std::move(subscription)); + if (!star_subscription.is_valid()) { + LOG(ERROR) << "Receive invalid subscription " << star_subscription; + } else { + subscriptions.push_back(star_subscription.get_star_subscription_object(td_)); + } + } + auto star_count = StarManager::get_star_count(result->balance_, true); + td_->star_manager_->on_update_owned_star_count(star_count); + promise_.set_value(td_api::make_object( + star_count, std::move(subscriptions), StarManager::get_star_count(result->subscriptions_missing_balance_), + result->subscriptions_next_offset_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class ChangeStarsSubscriptionQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ChangeStarsSubscriptionQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &subscription_id, bool is_canceled) { + send_query(G()->net_query_creator().create(telegram_api::payments_changeStarsSubscription( + telegram_api::payments_changeStarsSubscription::CANCELED_MASK, + telegram_api::make_object(), subscription_id, is_canceled))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class FulfillStarsSubscriptionQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit FulfillStarsSubscriptionQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &subscription_id) { + send_query(G()->net_query_creator().create(telegram_api::payments_fulfillStarsSubscription( + telegram_api::make_object(), subscription_id))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class RefundStarsChargeQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit RefundStarsChargeQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(telegram_api::object_ptr &&input_user, const string &telegram_payment_charge_id) { + send_query(G()->net_query_creator().create( + telegram_api::payments_refundStarsCharge(std::move(input_user), telegram_payment_charge_id))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for RefundStarsChargeQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +static td_api::object_ptr convert_stars_revenue_status( + telegram_api::object_ptr obj) { + CHECK(obj != nullptr); + int32 next_withdrawal_in = 0; + if (obj->withdrawal_enabled_ && obj->next_withdrawal_at_ > 0) { + next_withdrawal_in = max(obj->next_withdrawal_at_ - G()->unix_time(), 1); + } + return td_api::make_object( + StarManager::get_star_count(obj->overall_revenue_), StarManager::get_star_count(obj->current_balance_), + StarManager::get_star_count(obj->available_balance_), obj->withdrawal_enabled_, next_withdrawal_in); +} + +class GetStarsRevenueStatsQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetStarsRevenueStatsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, bool is_dark) { + dialog_id_ = dialog_id; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Have no access to the chat")); + } + + int32 flags = 0; + if (is_dark) { + flags |= telegram_api::payments_getStarsRevenueStats::DARK_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::payments_getStarsRevenueStats(flags, false /*ignored*/, std::move(input_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetStarsRevenueStatsQuery: " << to_string(ptr); + promise_.set_value(td_api::make_object( + StatisticsManager::convert_stats_graph(std::move(ptr->revenue_graph_)), + convert_stars_revenue_status(std::move(ptr->status_)), + ptr->usd_rate_ > 0 ? clamp(ptr->usd_rate_ * 1e2, 1e-18, 1e18) : 1.3)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStarsRevenueStatsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStarsRevenueWithdrawalUrlQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit GetStarsRevenueWithdrawalUrlQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, int64 star_count, + telegram_api::object_ptr input_check_password) { + dialog_id_ = dialog_id; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Have no access to the chat")); + } + + send_query(G()->net_query_creator().create(telegram_api::payments_getStarsRevenueWithdrawalUrl( + std::move(input_peer), star_count, std::move(input_check_password)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(std::move(result_ptr.ok_ref()->url_)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStarsRevenueWithdrawalUrlQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStarsRevenueAdsAccountUrlQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit GetStarsRevenueAdsAccountUrlQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id) { + dialog_id_ = dialog_id; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Have no access to the chat")); + } + + send_query( + G()->net_query_creator().create(telegram_api::payments_getStarsRevenueAdsAccountUrl(std::move(input_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(std::move(result_ptr.ok_ref()->url_)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStarsRevenueAdsAccountUrlQuery"); + promise_.set_error(std::move(status)); + } +}; + +StarManager::StarManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void StarManager::start_up() { + if (td_->auth_manager_->is_bot() || !td_->auth_manager_->is_authorized()) { + return; + } + auto owned_star_count = G()->td_db()->get_binlog_pmc()->get("owned_star_count"); + if (!owned_star_count.empty()) { + is_owned_star_count_inited_ = true; + owned_star_count_ = to_integer(owned_star_count); + sent_star_count_ = owned_star_count_; + send_closure(G()->td(), &Td::send_update, get_update_owned_star_count_object()); + } +} + +void StarManager::tear_down() { + parent_.reset(); +} + +td_api::object_ptr StarManager::get_update_owned_star_count_object() const { + CHECK(is_owned_star_count_inited_); + // sent_star_count_ can be negative as well as owned_star_count_ + return td_api::make_object(sent_star_count_); +} + +void StarManager::on_update_owned_star_count(int64 star_count) { + if (td_->auth_manager_->is_bot()) { + return; + } + if (is_owned_star_count_inited_ && star_count == owned_star_count_) { + return; + } + is_owned_star_count_inited_ = true; + owned_star_count_ = star_count; + if (owned_star_count_ + pending_owned_star_count_ != sent_star_count_) { + sent_star_count_ = owned_star_count_ + pending_owned_star_count_; + send_closure(G()->td(), &Td::send_update, get_update_owned_star_count_object()); + } + G()->td_db()->get_binlog_pmc()->set("owned_star_count", to_string(owned_star_count_)); +} + +void StarManager::add_pending_owned_star_count(int64 star_count, bool move_to_owned) { + if (star_count == 0) { + return; + } + pending_owned_star_count_ += star_count; + if (is_owned_star_count_inited_) { + if (move_to_owned) { + owned_star_count_ -= star_count; + G()->td_db()->get_binlog_pmc()->set("owned_star_count", to_string(owned_star_count_)); + } else { + sent_star_count_ += star_count; + send_closure(G()->td(), &Td::send_update, get_update_owned_star_count_object()); + } + } +} + +bool StarManager::has_owned_star_count(int64 star_count) const { + if (star_count <= 0 || !is_owned_star_count_inited_) { + return true; + } + return sent_star_count_ >= star_count; +} + +Status StarManager::can_manage_stars(DialogId dialog_id, bool allow_self) const { + switch (dialog_id.get_type()) { + case DialogType::User: { + auto user_id = dialog_id.get_user_id(); + if (allow_self && user_id == td_->user_manager_->get_my_id()) { + break; + } + TRY_RESULT(bot_data, td_->user_manager_->get_bot_data(user_id)); + if (!bot_data.can_be_edited) { + return Status::Error(400, "The bot isn't owned"); + } + break; + } + case DialogType::Channel: { + auto channel_id = dialog_id.get_channel_id(); + if (!td_->chat_manager_->is_broadcast_channel(channel_id)) { + return Status::Error(400, "Chat is not a channel"); + } + if (!td_->chat_manager_->get_channel_permissions(channel_id).is_creator() && !allow_self) { + return Status::Error(400, "Not enough rights"); + } + break; + } + default: + return Status::Error(400, "Unallowed chat specified"); + } + return Status::OK(); +} + +void StarManager::get_star_payment_options(Promise> &&promise) { + td_->create_handler(std::move(promise))->send(); +} + +void StarManager::get_star_gift_payment_options(UserId user_id, + Promise> &&promise) { + if (user_id == UserId()) { + td_->create_handler(std::move(promise))->send(nullptr); + return; + } + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(user_id)); + td_->create_handler(std::move(promise))->send(std::move(input_user)); +} + +void StarManager::get_star_giveaway_payment_options( + Promise> &&promise) { + td_->create_handler(std::move(promise))->send(); +} + +void StarManager::get_star_transactions(td_api::object_ptr owner_id, + const string &subscription_id, const string &offset, int32 limit, + td_api::object_ptr &&direction, + Promise> &&promise) { + TRY_RESULT_PROMISE(promise, dialog_id, get_message_sender_dialog_id(td_, owner_id, true, false)); + TRY_STATUS_PROMISE(promise, can_manage_stars(dialog_id, true)); + if (limit < 0) { + return promise.set_error(Status::Error(400, "Limit must be non-negative")); + } + td_->stickers_manager_->load_premium_gift_sticker_set(PromiseCreator::lambda( + [actor_id = actor_id(this), dialog_id, subscription_id, offset, limit, direction = std::move(direction), + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &StarManager::do_get_star_transactions, dialog_id, subscription_id, offset, limit, + std::move(direction), std::move(promise)); + } + })); +} + +void StarManager::do_get_star_transactions(DialogId dialog_id, const string &subscription_id, const string &offset, + int32 limit, + td_api::object_ptr &&direction, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + TRY_STATUS_PROMISE(promise, can_manage_stars(dialog_id, true)); + + td_->create_handler(std::move(promise)) + ->send(dialog_id, subscription_id, offset, limit, std::move(direction)); +} + +void StarManager::get_star_subscriptions(bool only_expiring, const string &offset, + Promise> &&promise) { + td_->create_handler(std::move(promise))->send(only_expiring, offset); +} + +void StarManager::edit_star_subscriptions(const string &subscription_id, bool is_canceled, Promise &&promise) { + td_->create_handler(std::move(promise))->send(subscription_id, is_canceled); +} + +void StarManager::reuse_star_subscriptions(const string &subscription_id, Promise &&promise) { + td_->create_handler(std::move(promise))->send(subscription_id); +} + +void StarManager::refund_star_payment(UserId user_id, const string &telegram_payment_charge_id, + Promise &&promise) { + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(user_id)); + td_->create_handler(std::move(promise)) + ->send(std::move(input_user), telegram_payment_charge_id); +} + +void StarManager::get_star_revenue_statistics(const td_api::object_ptr &owner_id, bool is_dark, + Promise> &&promise) { + TRY_RESULT_PROMISE(promise, dialog_id, get_message_sender_dialog_id(td_, owner_id, true, false)); + TRY_STATUS_PROMISE(promise, can_manage_stars(dialog_id)); + td_->create_handler(std::move(promise))->send(dialog_id, is_dark); +} + +void StarManager::get_star_withdrawal_url(const td_api::object_ptr &owner_id, int64 star_count, + const string &password, Promise &&promise) { + TRY_RESULT_PROMISE(promise, dialog_id, get_message_sender_dialog_id(td_, owner_id, true, false)); + TRY_STATUS_PROMISE(promise, can_manage_stars(dialog_id)); + if (password.empty()) { + return promise.set_error(Status::Error(400, "PASSWORD_HASH_INVALID")); + } + send_closure( + td_->password_manager_, &PasswordManager::get_input_check_password_srp, password, + PromiseCreator::lambda([actor_id = actor_id(this), dialog_id, star_count, promise = std::move(promise)]( + Result> result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &StarManager::send_get_star_withdrawal_url_query, dialog_id, star_count, + result.move_as_ok(), std::move(promise)); + })); +} + +void StarManager::send_get_star_withdrawal_url_query( + DialogId dialog_id, int64 star_count, + telegram_api::object_ptr input_check_password, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + td_->create_handler(std::move(promise)) + ->send(dialog_id, star_count, std::move(input_check_password)); +} + +void StarManager::get_star_ad_account_url(const td_api::object_ptr &owner_id, + Promise &&promise) { + TRY_RESULT_PROMISE(promise, dialog_id, get_message_sender_dialog_id(td_, owner_id, true, false)); + TRY_STATUS_PROMISE(promise, can_manage_stars(dialog_id)); + td_->create_handler(std::move(promise))->send(dialog_id); +} + +void StarManager::reload_star_transaction(DialogId dialog_id, const string &transaction_id, bool is_refund, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, can_manage_stars(dialog_id, true)); + auto query_promise = PromiseCreator::lambda( + [promise = std::move(promise)](Result> r_transactions) mutable { + if (r_transactions.is_error()) { + promise.set_error(r_transactions.move_as_error()); + } else { + promise.set_value(Unit()); + } + }); + td_->create_handler(std::move(query_promise))->send(dialog_id, transaction_id, is_refund); +} + +void StarManager::reload_owned_star_count() { + do_get_star_transactions(td_->dialog_manager_->get_my_dialog_id(), string(), string(), 1, nullptr, Auto()); +} + +void StarManager::on_update_stars_revenue_status( + telegram_api::object_ptr &&update) { + DialogId dialog_id(update->peer_); + if (can_manage_stars(dialog_id).is_error()) { + LOG(ERROR) << "Receive " << to_string(update); + return; + } + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + get_message_sender_object(td_, dialog_id, "updateStarRevenueStatus"), + convert_stars_revenue_status(std::move(update->status_)))); +} + +FileSourceId StarManager::get_star_transaction_file_source_id(DialogId dialog_id, const string &transaction_id, + bool is_refund) { + if (!dialog_id.is_valid() || transaction_id.empty()) { + return FileSourceId(); + } + + auto &source_id = star_transaction_file_source_ids_[is_refund][dialog_id][transaction_id]; + if (!source_id.is_valid()) { + source_id = td_->file_reference_manager_->create_star_transaction_file_source(dialog_id, transaction_id, is_refund); + } + VLOG(file_references) << "Return " << source_id << " for " << (is_refund ? "refund " : "") << "transaction " + << transaction_id << " in " << dialog_id; + return source_id; +} + +int64 StarManager::get_star_count(int64 amount, bool allow_negative) { + auto max_amount = static_cast(1) << 51; + if (amount < 0) { + if (!allow_negative) { + LOG(ERROR) << "Receive Telegram Star amount = " << amount; + return 0; + } + if (amount < -max_amount) { + LOG(ERROR) << "Receive Telegram Star amount = " << amount; + return -max_amount; + } + } + if (amount > max_amount) { + LOG(ERROR) << "Receive Telegram Star amount = " << amount; + return max_amount; + } + return amount; +} + +int32 StarManager::get_months_by_star_count(int64 star_count) { + return star_count <= 1000 ? 3 : (star_count < 2500 ? 6 : 12); +} + +void StarManager::get_current_state(vector> &updates) const { + if (is_owned_star_count_inited_) { + updates.push_back(get_update_owned_star_count_object()); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StarManager.h b/protocols/Telegram/tdlib/td/td/telegram/StarManager.h new file mode 100644 index 0000000000..188a1fb10b --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StarManager.h @@ -0,0 +1,107 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/files/FileSourceId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" + +namespace td { + +class Td; + +class StarManager final : public Actor { + public: + StarManager(Td *td, ActorShared<> parent); + + void on_update_owned_star_count(int64 star_count); + + void add_pending_owned_star_count(int64 star_count, bool move_to_owned); + + bool has_owned_star_count(int64 star_count) const; + + void get_star_payment_options(Promise> &&promise); + + void get_star_gift_payment_options(UserId user_id, Promise> &&promise); + + void get_star_giveaway_payment_options(Promise> &&promise); + + void get_star_transactions(td_api::object_ptr owner_id, const string &subscription_id, + const string &offset, int32 limit, + td_api::object_ptr &&direction, + Promise> &&promise); + + void get_star_subscriptions(bool only_expiring, const string &offset, + Promise> &&promise); + + void edit_star_subscriptions(const string &subscription_id, bool is_canceled, Promise &&promise); + + void reuse_star_subscriptions(const string &subscription_id, Promise &&promise); + + void refund_star_payment(UserId user_id, const string &telegram_payment_charge_id, Promise &&promise); + + void get_star_revenue_statistics(const td_api::object_ptr &owner_id, bool is_dark, + Promise> &&promise); + + void get_star_withdrawal_url(const td_api::object_ptr &owner_id, int64 star_count, + const string &password, Promise &&promise); + + void get_star_ad_account_url(const td_api::object_ptr &owner_id, Promise &&promise); + + void reload_star_transaction(DialogId dialog_id, const string &transaction_id, bool is_refund, + Promise &&promise); + + void reload_owned_star_count(); + + void on_update_stars_revenue_status(telegram_api::object_ptr &&update); + + FileSourceId get_star_transaction_file_source_id(DialogId dialog_id, const string &transaction_id, bool is_refund); + + static int64 get_star_count(int64 amount, bool allow_negative = false); + + static int32 get_months_by_star_count(int64 star_count); + + void get_current_state(vector> &updates) const; + + private: + void start_up() final; + + void tear_down() final; + + Status can_manage_stars(DialogId dialog_id, bool allow_self = false) const; + + void do_get_star_transactions(DialogId dialog_id, const string &subscription_id, const string &offset, int32 limit, + td_api::object_ptr &&direction, + Promise> &&promise); + + void send_get_star_withdrawal_url_query( + DialogId dialog_id, int64 star_count, + telegram_api::object_ptr input_check_password, Promise &&promise); + + td_api::object_ptr get_update_owned_star_count_object() const; + + Td *td_; + ActorShared<> parent_; + + bool is_owned_star_count_inited_ = false; + int64 owned_star_count_ = 0; + int64 pending_owned_star_count_ = 0; + int64 sent_star_count_ = 0; + + FlatHashMap, DialogIdHash> star_transaction_file_source_ids_[2]; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StarSubscription.cpp b/protocols/Telegram/tdlib/td/td/telegram/StarSubscription.cpp new file mode 100644 index 0000000000..a0b4f78aac --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StarSubscription.cpp @@ -0,0 +1,41 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StarSubscription.h" + +#include "td/telegram/DialogManager.h" +#include "td/telegram/LinkManager.h" +#include "td/telegram/Td.h" + +namespace td { + +StarSubscription::StarSubscription(telegram_api::object_ptr &&subscription) + : id_(std::move(subscription->id_)) + , dialog_id_(subscription->peer_) + , until_date_(subscription->until_date_) + , can_reuse_(subscription->can_refulfill_) + , is_canceled_(subscription->canceled_) + , missing_balance_(subscription->missing_balance_) + , invite_hash_(std::move(subscription->chat_invite_hash_)) + , pricing_(std::move(subscription->pricing_)) { +} + +td_api::object_ptr StarSubscription::get_star_subscription_object(Td *td) const { + td->dialog_manager_->force_create_dialog(dialog_id_, "starSubscription", true); + return td_api::make_object( + id_, td->dialog_manager_->get_chat_id_object(dialog_id_, "starSubscription"), until_date_, can_reuse_, + is_canceled_, missing_balance_, LinkManager::get_dialog_invite_link(invite_hash_, false), + pricing_.get_star_subscription_pricing_object()); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StarSubscription &subscription) { + return string_builder << (subscription.is_canceled_ ? "canceled " : "") + << (subscription.missing_balance_ ? "expiring " : "") << "subscription " << subscription.id_ + << " to " << subscription.dialog_id_ << '/' << subscription.invite_hash_ << " until " + << subscription.until_date_ << " for " << subscription.pricing_; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StarSubscription.h b/protocols/Telegram/tdlib/td/td/telegram/StarSubscription.h new file mode 100644 index 0000000000..5238cce3f7 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StarSubscription.h @@ -0,0 +1,47 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/StarSubscriptionPricing.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Td; + +class StarSubscription { + string id_; + DialogId dialog_id_; + int32 until_date_ = 0; + bool can_reuse_ = false; + bool is_canceled_ = false; + bool missing_balance_ = false; + string invite_hash_; + StarSubscriptionPricing pricing_; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const StarSubscription &subscription); + + public: + StarSubscription() = default; + + explicit StarSubscription(telegram_api::object_ptr &&subscription); + + bool is_valid() const { + return !id_.empty() && dialog_id_.is_valid() && until_date_ >= 0 && !pricing_.is_empty(); + } + + td_api::object_ptr get_star_subscription_object(Td *td) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const StarSubscription &subscription); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.cpp b/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.cpp new file mode 100644 index 0000000000..9a434b0c10 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.cpp @@ -0,0 +1,58 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StarSubscriptionPricing.h" + +#include "td/telegram/StarManager.h" + +namespace td { + +StarSubscriptionPricing::StarSubscriptionPricing( + telegram_api::object_ptr &&pricing) { + if (pricing != nullptr) { + period_ = pricing->period_; + amount_ = StarManager::get_star_count(pricing->amount_); + } +} + +StarSubscriptionPricing::StarSubscriptionPricing(td_api::object_ptr &&pricing) { + if (pricing != nullptr) { + period_ = pricing->period_; + amount_ = pricing->star_count_; + if (amount_ > 1000000000) { + amount_ = 0; + } + } +} + +td_api::object_ptr StarSubscriptionPricing::get_star_subscription_pricing_object() + const { + if (is_empty()) { + return nullptr; + } + return td_api::make_object(period_, amount_); +} + +telegram_api::object_ptr +StarSubscriptionPricing::get_input_stars_subscription_pricing() const { + if (is_empty()) { + return nullptr; + } + return telegram_api::make_object(period_, amount_); +} + +bool operator==(const StarSubscriptionPricing &lhs, const StarSubscriptionPricing &rhs) { + return lhs.period_ == rhs.period_ && lhs.amount_ == rhs.amount_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StarSubscriptionPricing &pricing) { + if (pricing.is_empty()) { + return string_builder << "no subscription"; + } + return string_builder << "subscription for " << pricing.period_ << " days for " << pricing.amount_ << " stars"; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.h b/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.h new file mode 100644 index 0000000000..350e32ffb0 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.h @@ -0,0 +1,55 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class StarSubscriptionPricing { + int32 period_ = 0; + int64 amount_ = 0; + + friend bool operator==(const StarSubscriptionPricing &lhs, const StarSubscriptionPricing &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const StarSubscriptionPricing &pricing); + + public: + StarSubscriptionPricing() = default; + + explicit StarSubscriptionPricing(telegram_api::object_ptr &&pricing); + + explicit StarSubscriptionPricing(td_api::object_ptr &&pricing); + + bool is_empty() const { + return period_ <= 0 || amount_ <= 0; + } + + td_api::object_ptr get_star_subscription_pricing_object() const; + + telegram_api::object_ptr get_input_stars_subscription_pricing() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const StarSubscriptionPricing &lhs, const StarSubscriptionPricing &rhs); + +inline bool operator!=(const StarSubscriptionPricing &lhs, const StarSubscriptionPricing &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StarSubscriptionPricing &pricing); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.hpp b/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.hpp new file mode 100644 index 0000000000..e09eb6ef91 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StarSubscriptionPricing.hpp @@ -0,0 +1,32 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/StarSubscriptionPricing.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void StarSubscriptionPricing::store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + td::store(period_, storer); + td::store(amount_, storer); +} + +template +void StarSubscriptionPricing::parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + td::parse(period_, parser); + td::parse(amount_, parser); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StateManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/StateManager.cpp index 69901cc342..1234b54ccb 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/StateManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/StateManager.cpp @@ -1,11 +1,13 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/StateManager.h" +#include "td/telegram/Global.h" + #include "td/actor/PromiseFuture.h" #include "td/actor/SleepActor.h" @@ -129,8 +131,10 @@ void StateManager::on_network_soft() { } void StateManager::start_up() { - create_actor("SleepActor", 1, create_event_promise(self_closure(this, &StateManager::on_network_soft))) - .release(); + if (!G()->get_option_boolean("disable_network_statistics")) { + create_actor("SleepActor", 1, create_event_promise(self_closure(this, &StateManager::on_network_soft))) + .release(); + } loop(); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/StatisticsManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/StatisticsManager.cpp new file mode 100644 index 0000000000..f11e716a55 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StatisticsManager.cpp @@ -0,0 +1,1008 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StatisticsManager.h" + +#include "td/telegram/AccessRights.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/PasswordManager.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/StoryManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/Status.h" + +namespace td { + +static td_api::object_ptr convert_date_range( + const telegram_api::object_ptr &obj) { + return td_api::make_object(obj->min_date_, obj->max_date_); +} + +static td_api::object_ptr convert_stats_graph( + telegram_api::object_ptr obj) { + CHECK(obj != nullptr); + + switch (obj->get_id()) { + case telegram_api::statsGraphAsync::ID: { + auto graph = move_tl_object_as(obj); + return td_api::make_object(std::move(graph->token_)); + } + case telegram_api::statsGraphError::ID: { + auto graph = move_tl_object_as(obj); + return td_api::make_object(std::move(graph->error_)); + } + case telegram_api::statsGraph::ID: { + auto graph = move_tl_object_as(obj); + return td_api::make_object(std::move(graph->json_->data_), + std::move(graph->zoom_token_)); + } + default: + UNREACHABLE(); + return nullptr; + } +} + +static double get_percentage_value(double part, double total, bool is_percentage) { + if (total < 1e-6 && total > -1e-6) { + if (part < 1e-6 && part > -1e-6) { + return 0.0; + } + return 100.0; + } + if (part > 1e20) { + return 100.0; + } + auto value = part / total * 100; + if (is_percentage) { + return clamp(value, 0.0, 100.0); + } else { + return max(value, -100.0); + } +} + +static td_api::object_ptr convert_stats_absolute_value( + const telegram_api::object_ptr &obj) { + return td_api::make_object( + obj->current_, obj->previous_, get_percentage_value(obj->current_ - obj->previous_, obj->previous_, false)); +} + +static td_api::object_ptr convert_megagroup_stats( + Td *td, telegram_api::object_ptr obj) { + CHECK(obj != nullptr); + + td->user_manager_->on_get_users(std::move(obj->users_), "convert_megagroup_stats"); + + // just in case + td::remove_if(obj->top_posters_, [](auto &obj) { + return !UserId(obj->user_id_).is_valid() || obj->messages_ < 0 || obj->avg_chars_ < 0; + }); + td::remove_if(obj->top_admins_, [](auto &obj) { + return !UserId(obj->user_id_).is_valid() || obj->deleted_ < 0 || obj->kicked_ < 0 || obj->banned_ < 0; + }); + td::remove_if(obj->top_inviters_, + [](auto &obj) { return !UserId(obj->user_id_).is_valid() || obj->invitations_ < 0; }); + + auto top_senders = transform( + std::move(obj->top_posters_), [td](telegram_api::object_ptr &&top_poster) { + return td_api::make_object( + td->user_manager_->get_user_id_object(UserId(top_poster->user_id_), "get_top_senders"), + top_poster->messages_, top_poster->avg_chars_); + }); + auto top_administrators = transform( + std::move(obj->top_admins_), [td](telegram_api::object_ptr &&top_admin) { + return td_api::make_object( + td->user_manager_->get_user_id_object(UserId(top_admin->user_id_), "get_top_administrators"), + top_admin->deleted_, top_admin->kicked_, top_admin->banned_); + }); + auto top_inviters = transform( + std::move(obj->top_inviters_), [td](telegram_api::object_ptr &&top_inviter) { + return td_api::make_object( + td->user_manager_->get_user_id_object(UserId(top_inviter->user_id_), "get_top_inviters"), + top_inviter->invitations_); + }); + + return td_api::make_object( + convert_date_range(obj->period_), convert_stats_absolute_value(obj->members_), + convert_stats_absolute_value(obj->messages_), convert_stats_absolute_value(obj->viewers_), + convert_stats_absolute_value(obj->posters_), convert_stats_graph(std::move(obj->growth_graph_)), + convert_stats_graph(std::move(obj->members_graph_)), + convert_stats_graph(std::move(obj->new_members_by_source_graph_)), + convert_stats_graph(std::move(obj->languages_graph_)), convert_stats_graph(std::move(obj->messages_graph_)), + convert_stats_graph(std::move(obj->actions_graph_)), convert_stats_graph(std::move(obj->top_hours_graph_)), + convert_stats_graph(std::move(obj->weekdays_graph_)), std::move(top_senders), std::move(top_administrators), + std::move(top_inviters)); +} + +static td_api::object_ptr convert_broadcast_stats( + telegram_api::object_ptr obj) { + CHECK(obj != nullptr); + auto recent_interactions = transform( + std::move(obj->recent_posts_interactions_), + [](telegram_api::object_ptr &&interaction_ptr) + -> td_api::object_ptr { + switch (interaction_ptr->get_id()) { + case telegram_api::postInteractionCountersMessage::ID: { + auto interaction = + telegram_api::move_object_as(interaction_ptr); + return td_api::make_object( + td_api::make_object( + MessageId(ServerMessageId(interaction->msg_id_)).get()), + interaction->views_, interaction->forwards_, interaction->reactions_); + } + case telegram_api::postInteractionCountersStory::ID: { + auto interaction = + telegram_api::move_object_as(interaction_ptr); + return td_api::make_object( + td_api::make_object(StoryId(interaction->story_id_).get()), + interaction->views_, interaction->forwards_, interaction->reactions_); + } + default: + UNREACHABLE(); + return nullptr; + } + }); + return td_api::make_object( + convert_date_range(obj->period_), convert_stats_absolute_value(obj->followers_), + convert_stats_absolute_value(obj->views_per_post_), convert_stats_absolute_value(obj->shares_per_post_), + convert_stats_absolute_value(obj->reactions_per_post_), convert_stats_absolute_value(obj->views_per_story_), + convert_stats_absolute_value(obj->shares_per_story_), convert_stats_absolute_value(obj->reactions_per_story_), + get_percentage_value(obj->enabled_notifications_->part_, obj->enabled_notifications_->total_, true), + convert_stats_graph(std::move(obj->growth_graph_)), convert_stats_graph(std::move(obj->followers_graph_)), + convert_stats_graph(std::move(obj->mute_graph_)), convert_stats_graph(std::move(obj->top_hours_graph_)), + convert_stats_graph(std::move(obj->views_by_source_graph_)), + convert_stats_graph(std::move(obj->new_followers_by_source_graph_)), + convert_stats_graph(std::move(obj->languages_graph_)), convert_stats_graph(std::move(obj->interactions_graph_)), + convert_stats_graph(std::move(obj->reactions_by_emotion_graph_)), + convert_stats_graph(std::move(obj->story_interactions_graph_)), + convert_stats_graph(std::move(obj->story_reactions_by_emotion_graph_)), + convert_stats_graph(std::move(obj->iv_interactions_graph_)), std::move(recent_interactions)); +} + +class GetMegagroupStatsQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit GetMegagroupStatsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, bool is_dark, DcId dc_id) { + channel_id_ = channel_id; + + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); + CHECK(input_channel != nullptr); + + int32 flags = 0; + if (is_dark) { + flags |= telegram_api::stats_getMegagroupStats::DARK_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::stats_getMegagroupStats(flags, false /*ignored*/, std::move(input_channel)), {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(convert_megagroup_stats(td_, result_ptr.move_as_ok())); + } + + void on_error(Status status) final { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetMegagroupStatsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetBroadcastStatsQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit GetBroadcastStatsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, bool is_dark, DcId dc_id) { + channel_id_ = channel_id; + + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); + CHECK(input_channel != nullptr); + + int32 flags = 0; + if (is_dark) { + flags |= telegram_api::stats_getBroadcastStats::DARK_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::stats_getBroadcastStats(flags, false /*ignored*/, std::move(input_channel)), {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = convert_broadcast_stats(result_ptr.move_as_ok()); + for (auto &info : result->recent_interactions_) { + switch (info->object_type_->get_id()) { + case td_api::chatStatisticsObjectTypeMessage::ID: { + MessageId message_id( + static_cast(info->object_type_.get())->message_id_); + td_->messages_manager_->on_update_message_interaction_info( + {DialogId(channel_id_), message_id}, info->view_count_, info->forward_count_, false, nullptr); + break; + } + case td_api::chatStatisticsObjectTypeStory::ID: + break; + default: + UNREACHABLE(); + } + } + promise_.set_value(std::move(result)); + } + + void on_error(Status status) final { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetBroadcastStatsQuery"); + promise_.set_error(std::move(status)); + } +}; + +static int64 get_amount(int64 amount, bool allow_negative = false) { + if (!allow_negative && amount < 0) { + LOG(ERROR) << "Receive currency amount = " << amount; + return 0; + } + return amount; +} + +static td_api::object_ptr convert_broadcast_revenue_balances( + telegram_api::object_ptr obj) { + CHECK(obj != nullptr); + return td_api::make_object("TON", get_amount(obj->overall_revenue_), + get_amount(obj->current_balance_), + get_amount(obj->available_balance_), obj->withdrawal_enabled_); +} + +static td_api::object_ptr convert_broadcast_revenue_stats( + telegram_api::object_ptr obj) { + CHECK(obj != nullptr); + return td_api::make_object( + convert_stats_graph(std::move(obj->top_hours_graph_)), convert_stats_graph(std::move(obj->revenue_graph_)), + convert_broadcast_revenue_balances(std::move(obj->balances_)), + obj->usd_rate_ > 0 ? clamp(obj->usd_rate_ * 1e-7, 1e-18, 1e18) : 1.0); +} + +class GetBroadcastRevenueStatsQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit GetBroadcastRevenueStatsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, bool is_dark) { + channel_id_ = channel_id; + + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); + if (input_channel == nullptr) { + return on_error(Status::Error(500, "Chat info not found")); + } + + int32 flags = 0; + if (is_dark) { + flags |= telegram_api::stats_getBroadcastRevenueStats::DARK_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::stats_getBroadcastRevenueStats(flags, false /*ignored*/, std::move(input_channel)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(convert_broadcast_revenue_stats(result_ptr.move_as_ok())); + } + + void on_error(Status status) final { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetBroadcastRevenueStatsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetBroadcastRevenueWithdrawalUrlQuery final : public Td::ResultHandler { + Promise promise_; + ChannelId channel_id_; + + public: + explicit GetBroadcastRevenueWithdrawalUrlQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, telegram_api::object_ptr input_check_password) { + channel_id_ = channel_id; + + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); + if (input_channel == nullptr) { + return on_error(Status::Error(500, "Chat info not found")); + } + + send_query(G()->net_query_creator().create(telegram_api::stats_getBroadcastRevenueWithdrawalUrl( + std::move(input_channel), std::move(input_check_password)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(std::move(result_ptr.ok_ref()->url_)); + } + + void on_error(Status status) final { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetBroadcastRevenueWithdrawalUrlQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetBroadcastRevenueTransactionsQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit GetBroadcastRevenueTransactionsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, int32 offset, int32 limit) { + channel_id_ = channel_id; + + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); + if (input_channel == nullptr) { + return on_error(Status::Error(500, "Chat info not found")); + } + + send_query(G()->net_query_creator().create( + telegram_api::stats_getBroadcastRevenueTransactions(std::move(input_channel), offset, limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetBroadcastRevenueTransactionsQuery: " << to_string(ptr); + auto total_count = ptr->count_; + if (total_count < static_cast(ptr->transactions_.size())) { + LOG(ERROR) << "Receive total_count = " << total_count << " and " << ptr->transactions_.size() << " transactions"; + total_count = static_cast(ptr->transactions_.size()); + } + vector> transactions; + for (auto &transaction_ptr : ptr->transactions_) { + int64 amount = 0; + auto type = [&]() -> td_api::object_ptr { + switch (transaction_ptr->get_id()) { + case telegram_api::broadcastRevenueTransactionProceeds::ID: { + auto transaction = + telegram_api::move_object_as(transaction_ptr); + amount = get_amount(transaction->amount_); + return td_api::make_object(transaction->from_date_, + transaction->to_date_); + } + case telegram_api::broadcastRevenueTransactionWithdrawal::ID: { + auto transaction = + telegram_api::move_object_as(transaction_ptr); + amount = get_amount(transaction->amount_, true); + auto state = [&]() -> td_api::object_ptr { + if (transaction->transaction_date_ > 0) { + return td_api::make_object(transaction->transaction_date_, + transaction->transaction_url_); + } + if (transaction->pending_) { + return td_api::make_object(); + } + if (!transaction->failed_) { + LOG(ERROR) << "Transaction has unknown state"; + } + return td_api::make_object(); + }(); + return td_api::make_object( + transaction->date_, transaction->provider_, std::move(state)); + } + case telegram_api::broadcastRevenueTransactionRefund::ID: { + auto transaction = + telegram_api::move_object_as(transaction_ptr); + amount = get_amount(transaction->amount_); + return td_api::make_object(transaction->date_, + transaction->provider_); + } + default: + UNREACHABLE(); + return nullptr; + } + }(); + transactions.push_back(td_api::make_object("TON", amount, std::move(type))); + } + promise_.set_value(td_api::make_object(total_count, std::move(transactions))); + } + + void on_error(Status status) final { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetBroadcastRevenueTransactionsQuery"); + promise_.set_error(std::move(status)); + } +}; + +static td_api::object_ptr convert_message_stats( + telegram_api::object_ptr obj) { + return td_api::make_object( + convert_stats_graph(std::move(obj->views_graph_)), + convert_stats_graph(std::move(obj->reactions_by_emotion_graph_))); +} + +class GetMessageStatsQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit GetMessageStatsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, MessageId message_id, bool is_dark, DcId dc_id) { + channel_id_ = channel_id; + + auto input_channel = td_->chat_manager_->get_input_channel(channel_id); + if (input_channel == nullptr) { + return promise_.set_error(Status::Error(400, "Supergroup not found")); + } + + int32 flags = 0; + if (is_dark) { + flags |= telegram_api::stats_getMessageStats::DARK_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::stats_getMessageStats(flags, false /*ignored*/, std::move(input_channel), + message_id.get_server_message_id().get()), + {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(convert_message_stats(result_ptr.move_as_ok())); + } + + void on_error(Status status) final { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetMessageStatsQuery"); + promise_.set_error(std::move(status)); + } +}; + +static td_api::object_ptr convert_story_stats( + telegram_api::object_ptr obj) { + return td_api::make_object(convert_stats_graph(std::move(obj->views_graph_)), + convert_stats_graph(std::move(obj->reactions_by_emotion_graph_))); +} + +class GetStoryStatsQuery final : public Td::ResultHandler { + Promise> promise_; + ChannelId channel_id_; + + public: + explicit GetStoryStatsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id, StoryId story_id, bool is_dark, DcId dc_id) { + channel_id_ = channel_id; + + auto input_peer = td_->dialog_manager_->get_input_peer(DialogId(channel_id), AccessRights::Read); + if (input_peer == nullptr) { + return promise_.set_error(Status::Error(400, "Chat not found")); + } + + int32 flags = 0; + if (is_dark) { + flags |= telegram_api::stats_getStoryStats::DARK_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::stats_getStoryStats(flags, false /*ignored*/, std::move(input_peer), story_id.get()), {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(convert_story_stats(result_ptr.move_as_ok())); + } + + void on_error(Status status) final { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "GetStoryStatsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class LoadAsyncGraphQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit LoadAsyncGraphQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(const string &token, int64 x, DcId dc_id) { + int32 flags = 0; + if (x != 0) { + flags |= telegram_api::stats_loadAsyncGraph::X_MASK; + } + send_query(G()->net_query_creator().create(telegram_api::stats_loadAsyncGraph(flags, token, x), {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + promise_.set_value(convert_stats_graph(std::move(result))); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetMessagePublicForwardsQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetMessagePublicForwardsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DcId dc_id, MessageFullId message_full_id, const string &offset, int32 limit) { + dialog_id_ = message_full_id.get_dialog_id(); + + auto input_channel = td_->chat_manager_->get_input_channel(dialog_id_.get_channel_id()); + CHECK(input_channel != nullptr); + + send_query(G()->net_query_creator().create( + telegram_api::stats_getMessagePublicForwards( + std::move(input_channel), message_full_id.get_message_id().get_server_message_id().get(), offset, limit), + {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->statistics_manager_->get_channel_differences_if_needed(result_ptr.move_as_ok(), std::move(promise_), + "GetMessagePublicForwardsQuery"); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetMessagePublicForwardsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStoryPublicForwardsQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetStoryPublicForwardsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DcId dc_id, StoryFullId story_full_id, const string &offset, int32 limit) { + dialog_id_ = story_full_id.get_dialog_id(); + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't get story statistics")); + } + + send_query( + G()->net_query_creator().create(telegram_api::stats_getStoryPublicForwards( + std::move(input_peer), story_full_id.get_story_id().get(), offset, limit), + {}, dc_id)); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->statistics_manager_->get_channel_differences_if_needed(result_ptr.move_as_ok(), std::move(promise_), + "GetStoryPublicForwardsQuery"); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStoryPublicForwardsQuery"); + promise_.set_error(std::move(status)); + } +}; + +StatisticsManager::StatisticsManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void StatisticsManager::tear_down() { + parent_.reset(); +} + +void StatisticsManager::get_channel_statistics(DialogId dialog_id, bool is_dark, + Promise> &&promise) { + auto dc_id_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), dialog_id, is_dark, promise = std::move(promise)](Result r_dc_id) mutable { + if (r_dc_id.is_error()) { + return promise.set_error(r_dc_id.move_as_error()); + } + send_closure(actor_id, &StatisticsManager::send_get_channel_stats_query, r_dc_id.move_as_ok(), + dialog_id.get_channel_id(), is_dark, std::move(promise)); + }); + td_->chat_manager_->get_channel_statistics_dc_id(dialog_id, true, std::move(dc_id_promise)); +} + +void StatisticsManager::send_get_channel_stats_query(DcId dc_id, ChannelId channel_id, bool is_dark, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + if (td_->chat_manager_->is_megagroup_channel(channel_id)) { + td_->create_handler(std::move(promise))->send(channel_id, is_dark, dc_id); + } else { + td_->create_handler(std::move(promise))->send(channel_id, is_dark, dc_id); + } +} + +void StatisticsManager::get_channel_revenue_statistics( + DialogId dialog_id, bool is_dark, Promise> &&promise) { + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Write, + "get_channel_revenue_statistics")); + if (!td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + return promise.set_error(Status::Error(400, "Chat is not a channel")); + } + td_->create_handler(std::move(promise))->send(dialog_id.get_channel_id(), is_dark); +} + +void StatisticsManager::on_update_dialog_revenue_transactions( + DialogId dialog_id, telegram_api::object_ptr balances) { + if (!dialog_id.is_valid()) { + LOG(ERROR) << "Receive updateBroadcastRevenueTransactions in invalid " << dialog_id; + return; + } + if (!td_->messages_manager_->have_dialog(dialog_id)) { + LOG(INFO) << "Ignore unneeded updateBroadcastRevenueTransactions in " << dialog_id; + return; + } + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "updateChatRevenueAmount"), + convert_broadcast_revenue_balances(std::move(balances)))); +} + +void StatisticsManager::get_channel_revenue_withdrawal_url(DialogId dialog_id, const string &password, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Write, + "get_channel_revenue_withdrawal_url")); + if (!td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + return promise.set_error(Status::Error(400, "Chat is not a channel")); + } + auto channel_id = dialog_id.get_channel_id(); + if (!td_->chat_manager_->get_channel_permissions(channel_id).is_creator()) { + return promise.set_error(Status::Error(400, "Not enough rights to withdraw revenue")); + } + if (password.empty()) { + return promise.set_error(Status::Error(400, "PASSWORD_HASH_INVALID")); + } + send_closure( + td_->password_manager_, &PasswordManager::get_input_check_password_srp, password, + PromiseCreator::lambda([actor_id = actor_id(this), channel_id, promise = std::move(promise)]( + Result> result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &StatisticsManager::send_get_channel_revenue_withdrawal_url_query, channel_id, + result.move_as_ok(), std::move(promise)); + })); +} + +void StatisticsManager::send_get_channel_revenue_withdrawal_url_query( + ChannelId channel_id, telegram_api::object_ptr input_check_password, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + td_->create_handler(std::move(promise)) + ->send(channel_id, std::move(input_check_password)); +} + +void StatisticsManager::get_channel_revenue_transactions( + DialogId dialog_id, int32 offset, int32 limit, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Write, + "get_channel_revenue_transactions")); + if (!td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + return promise.set_error(Status::Error(400, "Chat is not a channel")); + } + td_->create_handler(std::move(promise)) + ->send(dialog_id.get_channel_id(), offset, limit); +} + +void StatisticsManager::get_channel_message_statistics( + MessageFullId message_full_id, bool is_dark, Promise> &&promise) { + auto dc_id_promise = PromiseCreator::lambda([actor_id = actor_id(this), message_full_id, is_dark, + promise = std::move(promise)](Result r_dc_id) mutable { + if (r_dc_id.is_error()) { + return promise.set_error(r_dc_id.move_as_error()); + } + send_closure(actor_id, &StatisticsManager::send_get_channel_message_stats_query, r_dc_id.move_as_ok(), + message_full_id, is_dark, std::move(promise)); + }); + td_->chat_manager_->get_channel_statistics_dc_id(message_full_id.get_dialog_id(), false, std::move(dc_id_promise)); +} + +void StatisticsManager::send_get_channel_message_stats_query( + DcId dc_id, MessageFullId message_full_id, bool is_dark, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + auto dialog_id = message_full_id.get_dialog_id(); + if (!td_->messages_manager_->have_message_force(message_full_id, "send_get_channel_message_stats_query")) { + return promise.set_error(Status::Error(400, "Message not found")); + } + if (!td_->messages_manager_->can_get_message_statistics(message_full_id)) { + return promise.set_error(Status::Error(400, "Message statistics are inaccessible")); + } + CHECK(dialog_id.get_type() == DialogType::Channel); + td_->create_handler(std::move(promise)) + ->send(dialog_id.get_channel_id(), message_full_id.get_message_id(), is_dark, dc_id); +} + +void StatisticsManager::get_channel_story_statistics(StoryFullId story_full_id, bool is_dark, + Promise> &&promise) { + auto dc_id_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), story_full_id, is_dark, promise = std::move(promise)](Result r_dc_id) mutable { + if (r_dc_id.is_error()) { + return promise.set_error(r_dc_id.move_as_error()); + } + send_closure(actor_id, &StatisticsManager::send_get_channel_story_stats_query, r_dc_id.move_as_ok(), + story_full_id, is_dark, std::move(promise)); + }); + td_->chat_manager_->get_channel_statistics_dc_id(story_full_id.get_dialog_id(), false, std::move(dc_id_promise)); +} + +void StatisticsManager::send_get_channel_story_stats_query( + DcId dc_id, StoryFullId story_full_id, bool is_dark, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + auto dialog_id = story_full_id.get_dialog_id(); + if (!td_->story_manager_->have_story_force(story_full_id)) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!td_->story_manager_->can_get_story_statistics(story_full_id)) { + return promise.set_error(Status::Error(400, "Story statistics are inaccessible")); + } + CHECK(dialog_id.get_type() == DialogType::Channel); + td_->create_handler(std::move(promise)) + ->send(dialog_id.get_channel_id(), story_full_id.get_story_id(), is_dark, dc_id); +} + +void StatisticsManager::load_statistics_graph(DialogId dialog_id, string token, int64 x, + Promise> &&promise) { + auto dc_id_promise = PromiseCreator::lambda([actor_id = actor_id(this), token = std::move(token), x, + promise = std::move(promise)](Result r_dc_id) mutable { + if (r_dc_id.is_error()) { + return promise.set_error(r_dc_id.move_as_error()); + } + send_closure(actor_id, &StatisticsManager::send_load_async_graph_query, r_dc_id.move_as_ok(), std::move(token), x, + std::move(promise)); + }); + td_->chat_manager_->get_channel_statistics_dc_id(dialog_id, false, std::move(dc_id_promise)); +} + +void StatisticsManager::send_load_async_graph_query(DcId dc_id, string token, int64 x, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + td_->create_handler(std::move(promise))->send(token, x, dc_id); +} + +void StatisticsManager::get_message_public_forwards(MessageFullId message_full_id, string offset, int32 limit, + Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + + auto dc_id_promise = PromiseCreator::lambda([actor_id = actor_id(this), message_full_id, offset = std::move(offset), + limit, promise = std::move(promise)](Result r_dc_id) mutable { + if (r_dc_id.is_error()) { + return promise.set_error(r_dc_id.move_as_error()); + } + send_closure(actor_id, &StatisticsManager::send_get_message_public_forwards_query, r_dc_id.move_as_ok(), + message_full_id, std::move(offset), limit, std::move(promise)); + }); + td_->chat_manager_->get_channel_statistics_dc_id(message_full_id.get_dialog_id(), false, std::move(dc_id_promise)); +} + +void StatisticsManager::send_get_message_public_forwards_query( + DcId dc_id, MessageFullId message_full_id, string offset, int32 limit, + Promise> &&promise) { + if (!td_->messages_manager_->have_message_force(message_full_id, "send_get_message_public_forwards_query")) { + return promise.set_error(Status::Error(400, "Message not found")); + } + if (!td_->messages_manager_->can_get_message_statistics(message_full_id)) { + return promise.set_error(Status::Error(400, "Message forwards are inaccessible")); + } + + static constexpr int32 MAX_MESSAGE_FORWARDS = 100; // server side limit + if (limit > MAX_MESSAGE_FORWARDS) { + limit = MAX_MESSAGE_FORWARDS; + } + + td_->create_handler(std::move(promise))->send(dc_id, message_full_id, offset, limit); +} + +void StatisticsManager::get_story_public_forwards(StoryFullId story_full_id, string offset, int32 limit, + Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + auto dialog_id = story_full_id.get_dialog_id(); + if (dialog_id.get_type() == DialogType::User) { + if (dialog_id != td_->dialog_manager_->get_my_dialog_id()) { + return promise.set_error(Status::Error(400, "Have no access to story statistics")); + } + return send_get_story_public_forwards_query(DcId::main(), story_full_id, std::move(offset), limit, + std::move(promise)); + } + + auto dc_id_promise = PromiseCreator::lambda([actor_id = actor_id(this), story_full_id, offset = std::move(offset), + limit, promise = std::move(promise)](Result r_dc_id) mutable { + if (r_dc_id.is_error()) { + return promise.set_error(r_dc_id.move_as_error()); + } + send_closure(actor_id, &StatisticsManager::send_get_story_public_forwards_query, r_dc_id.move_as_ok(), + story_full_id, std::move(offset), limit, std::move(promise)); + }); + td_->chat_manager_->get_channel_statistics_dc_id(dialog_id, false, std::move(dc_id_promise)); +} + +void StatisticsManager::send_get_story_public_forwards_query( + DcId dc_id, StoryFullId story_full_id, string offset, int32 limit, + Promise> &&promise) { + if (!td_->story_manager_->have_story_force(story_full_id)) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!td_->story_manager_->can_get_story_statistics(story_full_id) && + story_full_id.get_dialog_id() != td_->dialog_manager_->get_my_dialog_id()) { + return promise.set_error(Status::Error(400, "Story forwards are inaccessible")); + } + + static constexpr int32 MAX_STORY_FORWARDS = 100; // server side limit + if (limit > MAX_STORY_FORWARDS) { + limit = MAX_STORY_FORWARDS; + } + + td_->create_handler(std::move(promise))->send(dc_id, story_full_id, offset, limit); +} + +void StatisticsManager::on_get_public_forwards( + telegram_api::object_ptr &&public_forwards, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + auto total_count = public_forwards->count_; + LOG(INFO) << "Receive " << public_forwards->forwards_.size() << " forwarded stories out of " + << public_forwards->count_; + vector> result; + for (auto &forward_ptr : public_forwards->forwards_) { + switch (forward_ptr->get_id()) { + case telegram_api::publicForwardMessage::ID: { + auto forward = telegram_api::move_object_as(forward_ptr); + auto dialog_id = DialogId::get_message_dialog_id(forward->message_); + auto message_full_id = td_->messages_manager_->on_get_message(std::move(forward->message_), false, + dialog_id.get_type() == DialogType::Channel, + false, "on_get_public_forwards"); + if (message_full_id != MessageFullId()) { + CHECK(dialog_id == message_full_id.get_dialog_id()); + result.push_back(td_api::make_object( + td_->messages_manager_->get_message_object(message_full_id, "on_get_public_forwards"))); + CHECK(result.back() != nullptr); + } else { + total_count--; + } + break; + } + case telegram_api::publicForwardStory::ID: { + auto forward = telegram_api::move_object_as(forward_ptr); + auto dialog_id = DialogId(forward->peer_); + auto story_id = td_->story_manager_->on_get_story(dialog_id, std::move(forward->story_)); + if (story_id.is_valid() && td_->story_manager_->have_story({dialog_id, story_id})) { + result.push_back(td_api::make_object( + td_->story_manager_->get_story_object({dialog_id, story_id}))); + CHECK(result.back() != nullptr); + } else { + total_count--; + } + break; + } + default: + UNREACHABLE(); + } + } + if (total_count < static_cast(result.size())) { + LOG(ERROR) << "Receive " << result.size() << " valid story sorwards out of " << total_count; + total_count = static_cast(result.size()); + } + promise.set_value( + td_api::make_object(total_count, std::move(result), public_forwards->next_offset_)); +} + +void StatisticsManager::get_channel_differences_if_needed( + telegram_api::object_ptr &&public_forwards, + Promise> promise, const char *source) { + td_->user_manager_->on_get_users(std::move(public_forwards->users_), "stats_publicForwards"); + td_->chat_manager_->on_get_chats(std::move(public_forwards->chats_), "stats_publicForwards"); + + vector *> messages; + for (const auto &forward : public_forwards->forwards_) { + CHECK(forward != nullptr); + if (forward->get_id() != telegram_api::publicForwardMessage::ID) { + continue; + } + messages.push_back(&static_cast(forward.get())->message_); + } + td_->messages_manager_->get_channel_differences_if_needed( + messages, + PromiseCreator::lambda([actor_id = actor_id(this), public_forwards = std::move(public_forwards), + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &StatisticsManager::on_get_public_forwards, std::move(public_forwards), + std::move(promise)); + } + }), + source); +} + +td_api::object_ptr StatisticsManager::convert_stats_graph( + telegram_api::object_ptr obj) { + return ::td::convert_stats_graph(std::move(obj)); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StatisticsManager.h b/protocols/Telegram/tdlib/td/td/telegram/StatisticsManager.h new file mode 100644 index 0000000000..0e635f197f --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StatisticsManager.h @@ -0,0 +1,98 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ChannelId.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/net/DcId.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/Promise.h" + +namespace td { + +class Td; + +class StatisticsManager final : public Actor { + public: + StatisticsManager(Td *td, ActorShared<> parent); + + void get_channel_statistics(DialogId dialog_id, bool is_dark, + Promise> &&promise); + + void get_channel_revenue_statistics(DialogId dialog_id, bool is_dark, + Promise> &&promise); + + void get_channel_revenue_withdrawal_url(DialogId dialog_id, const string &password, Promise &&promise); + + void get_channel_revenue_transactions(DialogId dialog_id, int32 offset, int32 limit, + Promise> &&promise); + + void on_update_dialog_revenue_transactions(DialogId dialog_id, + telegram_api::object_ptr balances); + + void get_channel_message_statistics(MessageFullId message_full_id, bool is_dark, + Promise> &&promise); + + void get_channel_story_statistics(StoryFullId message_full_id, bool is_dark, + Promise> &&promise); + + void load_statistics_graph(DialogId dialog_id, string token, int64 x, + Promise> &&promise); + + void get_message_public_forwards(MessageFullId message_full_id, string offset, int32 limit, + Promise> &&promise); + + void get_story_public_forwards(StoryFullId story_full_id, string offset, int32 limit, + Promise> &&promise); + + void on_get_public_forwards(telegram_api::object_ptr &&public_forwards, + Promise> &&promise); + + void get_channel_differences_if_needed(telegram_api::object_ptr &&public_forwards, + Promise> promise, + const char *source); + + static td_api::object_ptr convert_stats_graph( + telegram_api::object_ptr obj); + + private: + void tear_down() final; + + void send_get_channel_stats_query(DcId dc_id, ChannelId channel_id, bool is_dark, + Promise> &&promise); + + void send_get_channel_message_stats_query(DcId dc_id, MessageFullId message_full_id, bool is_dark, + Promise> &&promise); + + void send_get_channel_story_stats_query(DcId dc_id, StoryFullId story_full_id, bool is_dark, + Promise> &&promise); + + void send_load_async_graph_query(DcId dc_id, string token, int64 x, + Promise> &&promise); + + void send_get_message_public_forwards_query(DcId dc_id, MessageFullId message_full_id, string offset, int32 limit, + Promise> &&promise); + + void send_get_story_public_forwards_query(DcId dc_id, StoryFullId story_full_id, string offset, int32 limit, + Promise> &&promise); + + void send_get_channel_revenue_withdrawal_url_query( + ChannelId channel_id, telegram_api::object_ptr input_check_password, + Promise &&promise); + + Td *td_; + ActorShared<> parent_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StickerListType.cpp b/protocols/Telegram/tdlib/td/td/telegram/StickerListType.cpp new file mode 100644 index 0000000000..fb45121553 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StickerListType.cpp @@ -0,0 +1,43 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StickerListType.h" + +namespace td { + +string get_sticker_list_type_database_key(StickerListType sticker_list_type) { + switch (sticker_list_type) { + case StickerListType::DialogPhoto: + return "default_dialog_photo_custom_emoji_ids"; + case StickerListType::UserProfilePhoto: + return "default_profile_photo_custom_emoji_ids"; + case StickerListType::Background: + return "default_background_custom_emoji_ids"; + case StickerListType::DisallowedChannelEmojiStatus: + return "disallowed_channel_emoji_status_custom_emoji_ids"; + default: + UNREACHABLE(); + return string(); + } +} + +StringBuilder &operator<<(StringBuilder &string_builder, StickerListType sticker_list_type) { + switch (sticker_list_type) { + case StickerListType::DialogPhoto: + return string_builder << "default chat photo custom emoji identifiers"; + case StickerListType::UserProfilePhoto: + return string_builder << "default user profile photo custom emoji identifiers"; + case StickerListType::Background: + return string_builder << "default background custom emoji identifiers"; + case StickerListType::DisallowedChannelEmojiStatus: + return string_builder << "disallowed chat emoji status custom emoji identifiers"; + default: + UNREACHABLE(); + return string_builder; + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StickerListType.h b/protocols/Telegram/tdlib/td/td/telegram/StickerListType.h new file mode 100644 index 0000000000..aeab69678c --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StickerListType.h @@ -0,0 +1,22 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +enum class StickerListType : int32 { DialogPhoto, UserProfilePhoto, Background, DisallowedChannelEmojiStatus }; + +static constexpr int32 MAX_STICKER_LIST_TYPE = 4; + +string get_sticker_list_type_database_key(StickerListType sticker_list_type); + +StringBuilder &operator<<(StringBuilder &string_builder, StickerListType sticker_list_type); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StickersManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/StickersManager.cpp index 50e6f83c2b..57dd1f267b 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/StickersManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/StickersManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,11 +9,12 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/AuthManager.h" #include "td/telegram/ConfigManager.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Document.h" #include "td/telegram/DocumentsManager.h" #include "td/telegram/EmojiGroup.hpp" +#include "td/telegram/EmojiStatus.h" #include "td/telegram/FileReferenceManager.h" #include "td/telegram/files/FileLocation.h" #include "td/telegram/files/FileManager.h" @@ -22,7 +23,6 @@ #include "td/telegram/LanguagePackManager.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/logevent/LogEventHelper.h" -#include "td/telegram/MessageReaction.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" #include "td/telegram/net/DcId.h" @@ -30,13 +30,16 @@ #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/OptionManager.h" #include "td/telegram/PhotoSizeSource.h" +#include "td/telegram/QuickReplyManager.h" #include "td/telegram/secret_api.h" #include "td/telegram/SecretChatLayer.h" +#include "td/telegram/StarManager.h" #include "td/telegram/StickersManager.hpp" #include "td/telegram/Td.h" #include "td/telegram/td_api.h" #include "td/telegram/TdDb.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" #include "td/telegram/Version.h" #include "td/db/SqliteKeyValue.h" @@ -54,7 +57,6 @@ #include "td/utils/misc.h" #include "td/utils/PathView.h" #include "td/utils/Random.h" -#include "td/utils/ScopeGuard.h" #include "td/utils/Slice.h" #include "td/utils/SliceBuilder.h" #include "td/utils/StackAllocator.h" @@ -70,105 +72,6 @@ namespace td { -class GetAvailableReactionsQuery final : public Td::ResultHandler { - public: - void send(int32 hash) { - send_query(G()->net_query_creator().create(telegram_api::messages_getAvailableReactions(hash))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for GetAvailableReactionsQuery: " << to_string(ptr); - td_->stickers_manager_->on_get_available_reactions(std::move(ptr)); - } - - void on_error(Status status) final { - LOG(INFO) << "Receive error for GetAvailableReactionsQuery: " << status; - td_->stickers_manager_->on_get_available_reactions(nullptr); - } -}; - -class GetRecentReactionsQuery final : public Td::ResultHandler { - public: - void send(int32 limit, int64 hash) { - send_query(G()->net_query_creator().create(telegram_api::messages_getRecentReactions(limit, hash))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for GetRecentReactionsQuery: " << to_string(ptr); - td_->stickers_manager_->on_get_recent_reactions(std::move(ptr)); - } - - void on_error(Status status) final { - LOG(INFO) << "Receive error for GetRecentReactionsQuery: " << status; - td_->stickers_manager_->on_get_recent_reactions(nullptr); - } -}; - -class GetTopReactionsQuery final : public Td::ResultHandler { - public: - void send(int64 hash) { - send_query(G()->net_query_creator().create(telegram_api::messages_getTopReactions(50, hash))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for GetTopReactionsQuery: " << to_string(ptr); - td_->stickers_manager_->on_get_top_reactions(std::move(ptr)); - } - - void on_error(Status status) final { - LOG(INFO) << "Receive error for GetTopReactionsQuery: " << status; - td_->stickers_manager_->on_get_top_reactions(nullptr); - } -}; - -class ClearRecentReactionsQuery final : public Td::ResultHandler { - Promise promise_; - - public: - explicit ClearRecentReactionsQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send() { - send_query(G()->net_query_creator().create(telegram_api::messages_clearRecentReactions())); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - td_->stickers_manager_->reload_recent_reactions(); - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - if (!G()->is_expected_error(status)) { - LOG(ERROR) << "Receive error for clear recent reactions: " << status; - } - td_->stickers_manager_->reload_recent_reactions(); - promise_.set_error(std::move(status)); - } -}; - class GetAllStickersQuery final : public Td::ResultHandler { StickerType sticker_type_; @@ -191,6 +94,9 @@ class GetAllStickersQuery final : public Td::ResultHandler { static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, + ""); auto result_ptr = fetch_result(packet); if (result_ptr.is_error()) { return on_error(result_ptr.move_as_error()); @@ -347,11 +253,10 @@ class GetEmojiKeywordsDifferenceQuery final : public Td::ResultHandler { }; class GetEmojiUrlQuery final : public Td::ResultHandler { - Promise> promise_; + Promise promise_; public: - explicit GetEmojiUrlQuery(Promise> &&promise) - : promise_(std::move(promise)) { + explicit GetEmojiUrlQuery(Promise &&promise) : promise_(std::move(promise)) { } void send(const string &language_code) { @@ -364,7 +269,8 @@ class GetEmojiUrlQuery final : public Td::ResultHandler { return on_error(result_ptr.move_as_error()); } - promise_.set_value(result_ptr.move_as_ok()); + auto ptr = result_ptr.move_as_ok(); + promise_.set_value(std::move(ptr->url_)); } void on_error(Status status) final { @@ -860,6 +766,29 @@ class GetStickerSetQuery final : public Td::ResultHandler { } }; +class GetStickerSetNameQuery final : public Td::ResultHandler { + StickerSetId sticker_set_id_; + + public: + void send(StickerSetId sticker_set_id, telegram_api::object_ptr &&input_sticker_set) { + sticker_set_id_ = sticker_set_id; + send_query(G()->net_query_creator().create(telegram_api::messages_getStickerSet(std::move(input_sticker_set), 0))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->stickers_manager_->on_get_sticker_set_name(sticker_set_id_, result_ptr.move_as_ok()); + } + + void on_error(Status status) final { + td_->stickers_manager_->on_get_sticker_set_name(sticker_set_id_, nullptr); + } +}; + class ReloadSpecialStickerSetQuery final : public Td::ResultHandler { StickerSetId sticker_set_id_; SpecialStickerSetType type_; @@ -904,31 +833,46 @@ class ReloadSpecialStickerSetQuery final : public Td::ResultHandler { }; class SearchStickerSetsQuery final : public Td::ResultHandler { + StickerType sticker_type_; string query_; public: - void send(string query) { + void send(StickerType sticker_type, string query) { + sticker_type_ = sticker_type; query_ = std::move(query); - send_query( - G()->net_query_creator().create(telegram_api::messages_searchStickerSets(0, false /*ignored*/, query_, 0))); + switch (sticker_type) { + case StickerType::Regular: + send_query( + G()->net_query_creator().create(telegram_api::messages_searchStickerSets(0, false /*ignored*/, query_, 0))); + break; + case StickerType::CustomEmoji: + send_query(G()->net_query_creator().create( + telegram_api::messages_searchEmojiStickerSets(0, false /*ignored*/, query_, 0))); + break; + default: + UNREACHABLE(); + } } void on_result(BufferSlice packet) final { + static_assert(std::is_same::value, + ""); auto result_ptr = fetch_result(packet); if (result_ptr.is_error()) { return on_error(result_ptr.move_as_error()); } auto ptr = result_ptr.move_as_ok(); - LOG(INFO) << "Receive result for search sticker sets: " << to_string(ptr); - td_->stickers_manager_->on_find_sticker_sets_success(query_, std::move(ptr)); + LOG(INFO) << "Receive result for search " << sticker_type_ << " sticker sets: " << to_string(ptr); + td_->stickers_manager_->on_find_sticker_sets_success(sticker_type_, query_, std::move(ptr)); } void on_error(Status status) final { if (!G()->is_expected_error(status)) { - LOG(ERROR) << "Receive error for search sticker sets: " << status; + LOG(ERROR) << "Receive error for search " << sticker_type_ << " sticker sets: " << status; } - td_->stickers_manager_->on_find_sticker_sets_fail(query_, std::move(status)); + td_->stickers_manager_->on_find_sticker_sets_fail(sticker_type_, query_, std::move(status)); } }; @@ -1042,7 +986,7 @@ class UploadStickerFileQuery final : public Td::ResultHandler { is_url_ = is_url; was_uploaded_ = FileManager::extract_was_uploaded(input_media); send_query(G()->net_query_creator().create( - telegram_api::messages_uploadMedia(std::move(input_peer), std::move(input_media)))); + telegram_api::messages_uploadMedia(0, string(), std::move(input_peer), std::move(input_media)))); } void on_result(BufferSlice packet) final { @@ -1057,13 +1001,12 @@ class UploadStickerFileQuery final : public Td::ResultHandler { void on_error(Status status) final { if (was_uploaded_) { CHECK(file_id_.is_valid()); - if (begins_with(status.message(), "FILE_PART_") && ends_with(status.message(), "_MISSING")) { - // TODO td_->stickers_manager_->on_upload_sticker_file_part_missing(file_id_, to_integer(status.message().substr(10))); + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + // TODO td_->stickers_manager_->on_upload_sticker_file_parts_missing(file_id_, std::move(bad_parts)); // return; } else { - if (status.code() != 429 && status.code() < 500 && !G()->close_flag()) { - td_->file_manager_->delete_partial_remote_location(file_id_); - } + td_->file_manager_->delete_partial_remote_location_if_needed(file_id_, status); } } else if (FileReferenceManager::is_file_reference_error(status)) { LOG(ERROR) << "Receive file reference error for UploadStickerFileQuery"; @@ -1135,7 +1078,7 @@ class CreateNewStickerSetQuery final : public Td::ResultHandler { } void send(tl_object_ptr &&input_user, const string &title, const string &short_name, - StickerType sticker_type, bool has_text_color, StickerFormat sticker_format, + StickerType sticker_type, bool has_text_color, vector> &&input_stickers, const string &software) { CHECK(input_user != nullptr); @@ -1149,20 +1092,14 @@ class CreateNewStickerSetQuery final : public Td::ResultHandler { if (has_text_color) { flags |= telegram_api::stickers_createStickerSet::TEXT_COLOR_MASK; } - if (sticker_format == StickerFormat::Tgs) { - flags |= telegram_api::stickers_createStickerSet::ANIMATED_MASK; - } - if (sticker_format == StickerFormat::Webm) { - flags |= telegram_api::stickers_createStickerSet::VIDEOS_MASK; - } if (!software.empty()) { flags |= telegram_api::stickers_createStickerSet::SOFTWARE_MASK; } send_query(G()->net_query_creator().create( telegram_api::stickers_createStickerSet(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, std::move(input_user), title, - short_name, nullptr, std::move(input_stickers), software), + std::move(input_user), title, short_name, nullptr, + std::move(input_stickers), software), {{short_name}})); } @@ -1192,14 +1129,23 @@ class AddStickerToSetQuery final : public Td::ResultHandler { explicit AddStickerToSetQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(const string &short_name, tl_object_ptr &&input_sticker) { - send_query(G()->net_query_creator().create( - telegram_api::stickers_addStickerToSet(make_tl_object(short_name), - std::move(input_sticker)), - {{short_name}})); + void send(const string &short_name, telegram_api::object_ptr &&input_sticker, + telegram_api::object_ptr &&input_document) { + if (input_document != nullptr) { + send_query(G()->net_query_creator().create( + telegram_api::stickers_replaceSticker(std::move(input_document), std::move(input_sticker)), {{short_name}})); + } else { + send_query(G()->net_query_creator().create( + telegram_api::stickers_addStickerToSet(make_tl_object(short_name), + std::move(input_sticker)), + {{short_name}})); + } } void on_result(BufferSlice packet) final { + static_assert(std::is_same::value, + ""); auto result_ptr = fetch_result(packet); if (result_ptr.is_error()) { return on_error(result_ptr.move_as_error()); @@ -1465,6 +1411,35 @@ class ChangeStickerQuery final : public Td::ResultHandler { } }; +class GetMyStickersQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetMyStickersQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(StickerSetId offset_sticker_set_id, int32 limit) { + send_query( + G()->net_query_creator().create(telegram_api::messages_getMyStickers(offset_sticker_set_id.get(), limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetMyStickersQuery: " << to_string(ptr); + promise_.set_value(std::move(ptr)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + class GetCustomEmojiDocumentsQuery final : public Td::ResultHandler { Promise>> promise_; @@ -1513,6 +1488,9 @@ class GetEmojiGroupsQuery final : public Td::ResultHandler { case EmojiGroupType::ProfilePhoto: send_query(G()->net_query_creator().create(telegram_api::messages_getEmojiProfilePhotoGroups(hash))); break; + case EmojiGroupType::RegularStickers: + send_query(G()->net_query_creator().create(telegram_api::messages_getEmojiStickerGroups(hash))); + break; default: UNREACHABLE(); } @@ -1525,6 +1503,9 @@ class GetEmojiGroupsQuery final : public Td::ResultHandler { static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, + ""); auto result_ptr = fetch_result(packet); if (result_ptr.is_error()) { return on_error(result_ptr.move_as_error()); @@ -1546,11 +1527,23 @@ class GetDefaultDialogPhotoEmojisQuery final : public Td::ResultHandler { : promise_(std::move(promise)) { } - void send(bool for_user, int64 hash) { - if (for_user) { - send_query(G()->net_query_creator().create(telegram_api::account_getDefaultProfilePhotoEmojis(hash))); - } else { - send_query(G()->net_query_creator().create(telegram_api::account_getDefaultGroupPhotoEmojis(hash))); + void send(StickerListType sticker_list_type, int64 hash) { + switch (sticker_list_type) { + case StickerListType::DialogPhoto: + send_query(G()->net_query_creator().create(telegram_api::account_getDefaultGroupPhotoEmojis(hash))); + break; + case StickerListType::UserProfilePhoto: + send_query(G()->net_query_creator().create(telegram_api::account_getDefaultProfilePhotoEmojis(hash))); + break; + case StickerListType::Background: + send_query(G()->net_query_creator().create(telegram_api::account_getDefaultBackgroundEmojis(hash))); + break; + case StickerListType::DisallowedChannelEmojiStatus: + send_query(G()->net_query_creator().create(telegram_api::account_getChannelRestrictedStatusEmojis(hash))); + break; + default: + UNREACHABLE(); + break; } } @@ -1558,6 +1551,12 @@ class GetDefaultDialogPhotoEmojisQuery final : public Td::ResultHandler { static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, + ""); + static_assert(std::is_same::value, + ""); auto result_ptr = fetch_result(packet); if (result_ptr.is_error()) { return on_error(result_ptr.move_as_error()); @@ -1598,7 +1597,7 @@ class SendAnimatedEmojiClicksQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "SendAnimatedEmojiClicksQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendAnimatedEmojiClicksQuery")) { LOG(INFO) << "Receive error for send animated emoji clicks: " << status; } @@ -1712,9 +1711,11 @@ class StickersManager::UploadStickerFileCallback final : public FileManager::Upl StickersManager::StickersManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { upload_sticker_file_callback_ = std::make_shared(); - on_update_animated_emoji_zoom(); - on_update_recent_stickers_limit(); - on_update_favorite_stickers_limit(); + if (!td_->auth_manager_->is_bot()) { + on_update_animated_emoji_zoom(); + on_update_recent_stickers_limit(); + on_update_favorite_stickers_limit(); + } next_click_animated_emoji_message_time_ = Time::now(); next_update_animated_emoji_clicked_time_ = Time::now(); @@ -1723,9 +1724,10 @@ StickersManager::StickersManager(Td *td, ActorShared<> parent) : td_(td), parent StickersManager::~StickersManager() { Scheduler::instance()->destroy_on_scheduler( G()->get_gc_scheduler_id(), stickers_, sticker_sets_, short_name_to_sticker_set_id_, attached_sticker_sets_, - found_stickers_, found_sticker_sets_, emoji_language_codes_, emoji_language_code_versions_, + found_stickers_[0], found_stickers_[1], found_stickers_[2], found_sticker_sets_[0], found_sticker_sets_[1], + found_sticker_sets_[2], emoji_language_codes_, emoji_language_code_versions_, emoji_language_code_last_difference_times_, reloaded_emoji_keywords_, premium_gift_messages_, dice_messages_, - emoji_messages_, custom_emoji_messages_, custom_emoji_to_sticker_id_); + dice_quick_reply_messages_, emoji_messages_, custom_emoji_messages_, custom_emoji_to_sticker_id_); } void StickersManager::start_up() { @@ -1733,7 +1735,10 @@ void StickersManager::start_up() { } void StickersManager::init() { - if (is_inited_ || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot() || G()->close_flag()) { + if (G()->close_flag()) { + return; + } + if (is_inited_ || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { return; } LOG(INFO) << "Init StickersManager"; @@ -1764,6 +1769,10 @@ void StickersManager::init() { auto &sticker_set = add_special_sticker_set(SpecialStickerSetType::default_statuses()); load_special_sticker_set_info_from_binlog(sticker_set); } + { + auto &sticker_set = add_special_sticker_set(SpecialStickerSetType::default_channel_statuses()); + load_special_sticker_set_info_from_binlog(sticker_set); + } { auto &sticker_set = add_special_sticker_set(SpecialStickerSetType::default_topic_icons()); load_special_sticker_set_info_from_binlog(sticker_set); @@ -1777,8 +1786,6 @@ void StickersManager::init() { } send_closure(G()->td(), &Td::send_update, get_update_dice_emojis_object()); - load_active_reactions(); - on_update_dice_success_values(); on_update_dice_emojis(); @@ -1809,104 +1816,6 @@ void StickersManager::init() { td_->option_manager_->set_option_empty("animated_emoji_sticker_set_name"); // legacy } -td_api::object_ptr StickersManager::get_emoji_reaction_object(const string &emoji) const { - for (auto &reaction : reactions_.reactions_) { - if (reaction.reaction_ == emoji) { - return td_api::make_object( - reaction.reaction_, reaction.title_, reaction.is_active_, get_sticker_object(reaction.static_icon_), - get_sticker_object(reaction.appear_animation_), get_sticker_object(reaction.select_animation_), - get_sticker_object(reaction.activate_animation_), get_sticker_object(reaction.effect_animation_), - get_sticker_object(reaction.around_animation_), get_sticker_object(reaction.center_animation_)); - } - } - return nullptr; -} - -void StickersManager::get_emoji_reaction(const string &emoji, - Promise> &&promise) { - load_reactions(); - if (reactions_.reactions_.empty() && reactions_.are_being_reloaded_) { - pending_get_emoji_reaction_queries_.emplace_back(emoji, std::move(promise)); - return; - } - promise.set_value(get_emoji_reaction_object(emoji)); -} - -vector StickersManager::get_recent_reactions() { - load_recent_reactions(); - return recent_reactions_.reactions_; -} - -vector StickersManager::get_top_reactions() { - load_top_reactions(); - return top_reactions_.reactions_; -} - -void StickersManager::add_recent_reaction(const string &reaction) { - load_recent_reactions(); - - auto &reactions = recent_reactions_.reactions_; - if (!reactions.empty() && reactions[0] == reaction) { - return; - } - - auto it = std::find(reactions.begin(), reactions.end(), reaction); - if (it == reactions.end()) { - if (static_cast(reactions.size()) == MAX_RECENT_REACTIONS) { - reactions.back() = reaction; - } else { - reactions.push_back(reaction); - } - it = reactions.end() - 1; - } - std::rotate(reactions.begin(), it, it + 1); - - recent_reactions_.hash_ = get_reactions_hash(reactions); -} - -void StickersManager::clear_recent_reactions(Promise &&promise) { - load_recent_reactions(); - - if (recent_reactions_.reactions_.empty()) { - return promise.set_value(Unit()); - } - - recent_reactions_.hash_ = 0; - recent_reactions_.reactions_.clear(); - - td_->create_handler(std::move(promise))->send(); -} - -void StickersManager::reload_reactions() { - if (G()->close_flag() || reactions_.are_being_reloaded_) { - return; - } - CHECK(!td_->auth_manager_->is_bot()); - reactions_.are_being_reloaded_ = true; - load_reactions(); // must be after are_being_reloaded_ is set to true to avoid recursion - td_->create_handler()->send(reactions_.hash_); -} - -void StickersManager::reload_recent_reactions() { - if (G()->close_flag() || recent_reactions_.is_being_reloaded_) { - return; - } - CHECK(!td_->auth_manager_->is_bot()); - recent_reactions_.is_being_reloaded_ = true; - load_recent_reactions(); // must be after is_being_reloaded_ is set to true to avoid recursion - td_->create_handler()->send(MAX_RECENT_REACTIONS, recent_reactions_.hash_); -} - -void StickersManager::reload_top_reactions() { - if (G()->close_flag() || top_reactions_.is_being_reloaded_) { - return; - } - CHECK(!td_->auth_manager_->is_bot()); - top_reactions_.is_being_reloaded_ = true; - load_top_reactions(); // must be after is_being_reloaded_ is set to true to avoid recursion - td_->create_handler()->send(top_reactions_.hash_); -} - StickersManager::SpecialStickerSet &StickersManager::add_special_sticker_set(const SpecialStickerSetType &type) { CHECK(!type.is_empty()); auto &result_ptr = special_sticker_sets_[type]; @@ -1983,7 +1892,7 @@ void StickersManager::load_special_sticker_set(SpecialStickerSet &sticker_set) { return; } sticker_set.is_being_loaded_ = true; - LOG(INFO) << "Load " << sticker_set.type_.type_ << " " << sticker_set.id_; + LOG(INFO) << "Load " << sticker_set.type_.type_ << ' ' << sticker_set.id_; if (sticker_set.id_.is_valid()) { auto s = get_sticker_set(sticker_set.id_); CHECK(s != nullptr); @@ -2056,6 +1965,10 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t if (result.is_error()) { LOG(INFO) << "Failed to load special sticker set " << type.type_ << ": " << result.error(); + if (type == SpecialStickerSetType::premium_gifts()) { + set_promises(pending_get_premium_gift_option_sticker_queries_); + } + // failed to load the special sticker set; repeat after some time create_actor("RetryLoadSpecialStickerSetActor", Random::fast(300, 600), PromiseCreator::lambda([actor_id = actor_id(this), type](Result result) mutable { @@ -2086,6 +1999,10 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t set_promises(pending_get_default_statuses_queries_); return; } + if (type == SpecialStickerSetType::default_channel_statuses()) { + set_promises(pending_get_default_channel_statuses_queries_); + return; + } if (type == SpecialStickerSetType::default_topic_icons()) { set_promises(pending_get_default_topic_icons_queries_); return; @@ -2101,13 +2018,13 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t reset_to_empty(pending_get_animated_emoji_click_stickers_); for (auto &pending_request : pending_get_requests) { choose_animated_emoji_click_sticker(sticker_set, std::move(pending_request.message_text_), - pending_request.full_message_id_, pending_request.start_time_, + pending_request.message_full_id_, pending_request.start_time_, std::move(pending_request.promise_)); } auto pending_click_requests = std::move(pending_on_animated_emoji_message_clicked_); reset_to_empty(pending_on_animated_emoji_message_clicked_); for (auto &pending_request : pending_click_requests) { - schedule_update_animated_emoji_clicked(sticker_set, pending_request.emoji_, pending_request.full_message_id_, + schedule_update_animated_emoji_clicked(sticker_set, pending_request.emoji_, pending_request.message_full_id_, std::move(pending_request.clicks_)); } return; @@ -2116,16 +2033,28 @@ void StickersManager::on_load_special_sticker_set(const SpecialStickerSetType &t auto emoji = type.get_dice_emoji(); CHECK(!emoji.empty()); - auto it = dice_messages_.find(emoji); - if (it == dice_messages_.end()) { - return; + { + auto it = dice_messages_.find(emoji); + if (it != dice_messages_.end()) { + vector message_full_ids; + it->second.foreach([&](const MessageFullId &message_full_id) { message_full_ids.push_back(message_full_id); }); + CHECK(!message_full_ids.empty()); + for (const auto &message_full_id : message_full_ids) { + td_->messages_manager_->on_external_update_message_content(message_full_id, "on_load_special_sticker_set"); + } + } } - - vector full_message_ids; - it->second.foreach([&](const FullMessageId &full_message_id) { full_message_ids.push_back(full_message_id); }); - CHECK(!full_message_ids.empty()); - for (const auto &full_message_id : full_message_ids) { - td_->messages_manager_->on_external_update_message_content(full_message_id); + { + auto it = dice_quick_reply_messages_.find(emoji); + if (it != dice_quick_reply_messages_.end()) { + vector message_full_ids; + it->second.foreach( + [&](const QuickReplyMessageFullId &message_full_id) { message_full_ids.push_back(message_full_id); }); + CHECK(!message_full_ids.empty()); + for (const auto &message_full_id : message_full_ids) { + td_->quick_reply_manager_->on_external_update_message_content(message_full_id, "on_load_special_sticker_set"); + } + } } } @@ -2139,6 +2068,12 @@ StickerType StickersManager::get_sticker_type(FileId file_id) const { return sticker->type_; } +StickerFormat StickersManager::get_sticker_format(FileId file_id) const { + const auto *sticker = get_sticker(file_id); + CHECK(sticker != nullptr); + return sticker->format_; +} + bool StickersManager::is_premium_custom_emoji(CustomEmojiId custom_emoji_id, bool default_result) const { auto sticker_id = custom_emoji_to_sticker_id_.get(custom_emoji_id); if (!sticker_id.is_valid()) { @@ -2167,12 +2102,12 @@ bool StickersManager::have_custom_emoji(CustomEmojiId custom_emoji_id) { } int64 StickersManager::get_sticker_id(FileId sticker_id) const { - auto sticker_file_view = td_->file_manager_->get_file_view(sticker_id); - if (sticker_file_view.is_encrypted() || !sticker_file_view.has_remote_location() || - !sticker_file_view.remote_location().is_document()) { + auto file_view = td_->file_manager_->get_file_view(sticker_id); + const auto *full_remote_location = file_view.get_full_remote_location(); + if (file_view.is_encrypted() || full_remote_location == nullptr || !full_remote_location->is_document()) { return 0; } - return sticker_file_view.remote_location().get_id(); + return full_remote_location->get_id(); } CustomEmojiId StickersManager::get_custom_emoji_id(FileId sticker_id) const { @@ -2429,13 +2364,14 @@ tl_object_ptr StickersManager::get_sticker_object(FileId file_i auto thumbnail_format = PhotoFormat::Webp; int64 document_id = 0; if (!sticker->set_id_.is_valid()) { - auto sticker_file_view = td_->file_manager_->get_file_view(sticker->file_id_); - if (sticker_file_view.is_encrypted()) { + auto file_view = td_->file_manager_->get_file_view(sticker->file_id_); + if (file_view.is_encrypted()) { // uploaded to secret chats stickers have JPEG thumbnail instead of server-generated WEBP thumbnail_format = PhotoFormat::Jpeg; } else { - if (sticker_file_view.has_remote_location() && sticker_file_view.remote_location().is_document()) { - document_id = sticker_file_view.remote_location().get_id(); + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location != nullptr && full_remote_location->is_document()) { + document_id = full_remote_location->get_id(); } if (thumbnail.file_id.is_valid()) { @@ -2496,6 +2432,34 @@ tl_object_ptr StickersManager::get_stickers_object(const vecto transform(sticker_ids, [&](FileId sticker_id) { return get_sticker_object(sticker_id); })); } +td_api::object_ptr StickersManager::get_sticker_emojis_object(const vector &sticker_ids, + bool return_only_main_emoji) { + auto emojis = td_api::make_object(); + FlatHashSet added_emojis; + auto add_emoji = [&](const string &emoji) { + if (!emoji.empty() && added_emojis.insert(emoji).second) { + emojis->emojis_.push_back(emoji); + } + }; + for (auto sticker_id : sticker_ids) { + auto sticker = get_sticker(sticker_id); + CHECK(sticker != nullptr); + add_emoji(sticker->alt_); + if (!return_only_main_emoji && sticker->set_id_.is_valid()) { + const StickerSet *sticker_set = get_sticker_set(sticker->set_id_); + if (sticker_set != nullptr) { + auto it = sticker_set->sticker_emojis_map_.find(sticker_id); + if (it != sticker_set->sticker_emojis_map_.end()) { + for (auto emoji : it->second) { + add_emoji(emoji); + } + } + } + } + } + return emojis; +} + tl_object_ptr StickersManager::get_dice_stickers_object(const string &emoji, int32 value) const { if (td_->auth_manager_->is_bot()) { return nullptr; @@ -2566,24 +2530,34 @@ int32 StickersManager::get_dice_success_animation_frame_number(const string &emo return result.first == value ? result.second : std::numeric_limits::max(); } -PhotoFormat StickersManager::get_sticker_set_thumbnail_format(StickerFormat sticker_format) { - switch (sticker_format) { - case StickerFormat::Unknown: - return PhotoFormat::Webp; - case StickerFormat::Webp: - return PhotoFormat::Webp; - case StickerFormat::Tgs: - return PhotoFormat::Tgs; - case StickerFormat::Webm: - return PhotoFormat::Webm; - default: - UNREACHABLE(); - return PhotoFormat::Webp; +PhotoFormat StickersManager::get_sticker_set_thumbnail_format(const StickerSet *sticker_set) const { + if (sticker_set->thumbnail_document_id_ != 0 && sticker_set->sticker_type_ == StickerType::CustomEmoji) { + for (auto sticker_id : sticker_set->sticker_ids_) { + auto file_view = td_->file_manager_->get_file_view(sticker_id); + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location != nullptr && !full_remote_location->is_web() && + full_remote_location->get_id() == sticker_set->thumbnail_document_id_) { + const Sticker *s = get_sticker(sticker_id); + CHECK(s != nullptr); + return get_sticker_format_photo_format(s->format_); + } + } + } + auto type = sticker_set->thumbnail_.type; + if (type == 's') { + return PhotoFormat::Webp; } + if (type == 'v') { + return PhotoFormat::Webm; + } + if (type == 'a') { + return PhotoFormat::Tgs; + } + return PhotoFormat::Tgs; } -double StickersManager::get_sticker_set_minithumbnail_zoom(const StickerSet *sticker_set) { - if (sticker_set->sticker_format_ == StickerFormat::Tgs) { +double StickersManager::get_sticker_set_minithumbnail_zoom(const StickerSet *sticker_set) const { + if (get_sticker_set_thumbnail_format(sticker_set) == PhotoFormat::Tgs) { return 100.0 / 512.0; } return 1.0; @@ -2595,10 +2569,11 @@ td_api::object_ptr StickersManager::get_sticker_set_thumbnail if (sticker_set->thumbnail_document_id_ != 0 && sticker_set->sticker_type_ == StickerType::CustomEmoji) { for (auto sticker_id : sticker_set->sticker_ids_) { auto file_view = td_->file_manager_->get_file_view(sticker_id); - if (file_view.has_remote_location() && !file_view.remote_location().is_web() && - file_view.remote_location().get_id() == sticker_set->thumbnail_document_id_) { + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location != nullptr && !full_remote_location->is_web() && + full_remote_location->get_id() == sticker_set->thumbnail_document_id_) { const Sticker *s = get_sticker(sticker_id); - auto thumbnail_format = get_sticker_set_thumbnail_format(s->format_); + auto thumbnail_format = get_sticker_format_photo_format(s->format_); PhotoSize thumbnail; thumbnail.type = 't'; thumbnail.size = static_cast(file_view.size()); @@ -2608,7 +2583,7 @@ td_api::object_ptr StickersManager::get_sticker_set_thumbnail } } } - auto thumbnail_format = get_sticker_set_thumbnail_format(sticker_set->sticker_format_); + auto thumbnail_format = get_sticker_set_thumbnail_format(sticker_set); return get_thumbnail_object(td_->file_manager_.get(), sticker_set->thumbnail_, thumbnail_format); } @@ -2635,9 +2610,9 @@ tl_object_ptr StickersManager::get_sticker_set_object(Sticke get_sticker_set_thumbnail_object(sticker_set), get_sticker_minithumbnail(sticker_set->minithumbnail_, sticker_set->id_, -2, get_sticker_set_minithumbnail_zoom(sticker_set)), - sticker_set->is_installed_ && !sticker_set->is_archived_, sticker_set->is_archived_, sticker_set->is_official_, - get_sticker_format_object(sticker_set->sticker_format_), get_sticker_type_object(sticker_set->sticker_type_), - sticker_set->is_viewed_, std::move(stickers), std::move(emojis)); + sticker_set->is_created_, sticker_set->is_installed_ && !sticker_set->is_archived_, sticker_set->is_archived_, + sticker_set->is_official_, get_sticker_type_object(sticker_set->sticker_type_), sticker_set->has_text_color_, + sticker_set->channel_emoji_status_, sticker_set->is_viewed_, std::move(stickers), std::move(emojis)); } tl_object_ptr StickersManager::get_sticker_sets_object(int32 total_count, @@ -2711,13 +2686,17 @@ tl_object_ptr StickersManager::get_sticker_set_info_obje get_sticker_set_thumbnail_object(sticker_set), get_sticker_minithumbnail(sticker_set->minithumbnail_, sticker_set->id_, -3, get_sticker_set_minithumbnail_zoom(sticker_set)), - sticker_set->is_installed_ && !sticker_set->is_archived_, sticker_set->is_archived_, sticker_set->is_official_, - get_sticker_format_object(sticker_set->sticker_format_), get_sticker_type_object(sticker_set->sticker_type_), - sticker_set->is_viewed_, sticker_set->was_loaded_ ? actual_count : max(actual_count, sticker_set->sticker_count_), - std::move(stickers)); + sticker_set->is_created_, sticker_set->is_installed_ && !sticker_set->is_archived_, sticker_set->is_archived_, + sticker_set->is_official_, get_sticker_type_object(sticker_set->sticker_type_), sticker_set->has_text_color_, + sticker_set->channel_emoji_status_, sticker_set->is_viewed_, + sticker_set->was_loaded_ ? actual_count : max(actual_count, sticker_set->sticker_count_), std::move(stickers)); } -td_api::object_ptr StickersManager::get_premium_gift_sticker_object(int32 month_count) { +td_api::object_ptr StickersManager::get_premium_gift_sticker_object(int32 month_count, + int64 star_count) { + if (month_count == 0) { + month_count = StarManager::get_months_by_star_count(star_count); + } auto it = premium_gift_messages_.find(month_count); if (it == premium_gift_messages_.end()) { return get_sticker_object(get_premium_gift_option_sticker_id(month_count)); @@ -2787,6 +2766,13 @@ FileId StickersManager::get_premium_gift_option_sticker_id(int32 month_count) { return get_premium_gift_option_sticker_id(get_premium_gift_sticker_set(), month_count); } +void StickersManager::load_premium_gift_sticker_set(Promise &&promise) { + if (td_->auth_manager_->is_bot() || get_premium_gift_sticker_set() != nullptr) { + return promise.set_value(Unit()); + } + pending_get_premium_gift_option_sticker_queries_.push_back(std::move(promise)); +} + const StickersManager::StickerSet *StickersManager::get_animated_emoji_sticker_set() { if (td_->auth_manager_->is_bot() || disable_animated_emojis_) { return nullptr; @@ -3074,20 +3060,20 @@ bool StickersManager::has_webp_thumbnail(const vector StickersManager::on_get_sticker_document(tl_object_ptr &&document_ptr, - StickerFormat expected_format) { + StickerFormat expected_format, const char *source) { if (document_ptr == nullptr) { return {}; } int32 document_constructor_id = document_ptr->get_id(); if (document_constructor_id == telegram_api::documentEmpty::ID) { - LOG(ERROR) << "Empty sticker document received"; + LOG(ERROR) << "Empty sticker document received from " << source; return {}; } CHECK(document_constructor_id == telegram_api::document::ID); auto document = move_tl_object_as(document_ptr); if (!DcId::is_valid(document->dc_id_)) { - LOG(ERROR) << "Wrong dc_id = " << document->dc_id_ << " in document " << to_string(document); + LOG(ERROR) << "Wrong dc_id = " << document->dc_id_ << " from " << source << " in document " << to_string(document); return {}; } auto dc_id = DcId::internal(document->dc_id_); @@ -3119,14 +3105,15 @@ std::pair StickersManager::on_get_sticker_document(tl_object_ptr< } if (sticker == nullptr && custom_emoji == nullptr) { if (document->mime_type_ != "application/x-bad-tgsticker") { - LOG(ERROR) << "Have no attributeSticker in sticker " << to_string(document); + LOG(ERROR) << "Have no attributeSticker from " << source << " in " << to_string(document); } return {}; } auto format = get_sticker_format_by_mime_type(document->mime_type_); if (format == StickerFormat::Unknown || (expected_format != StickerFormat::Unknown && format != expected_format)) { - LOG(ERROR) << "Expected sticker of the type " << expected_format << ", but received of the type " << format; + LOG(ERROR) << "Expected sticker of the type " << expected_format << ", but received of the type " << format + << " from " << source; return {}; } int64 document_id = document->id_; @@ -3207,6 +3194,7 @@ StickerSetId StickersManager::get_sticker_set_id(const tl_object_ptrset_id_ == new_->set_id_ && - (old_->alt_ != new_->alt_ || old_->set_id_ != new_->set_id_ || - (!is_sticker_format_vector(old_->format_) && !is_sticker_format_vector(new_->format_) && - old_->dimensions_.width != 0 && old_->dimensions_.height != 0 && old_->dimensions_ != new_->dimensions_))) { + if (old_->set_id_ == new_->set_id_ && old_->dimensions_ != new_->dimensions_ && old_->dimensions_.width != 0 && + old_->dimensions_.height != 0 && !is_sticker_format_vector(old_->format_) && + !is_sticker_format_vector(new_->format_)) { LOG(ERROR) << "Sticker has changed: alt = (" << old_->alt_ << ", " << new_->alt_ << "), set_id = (" << old_->set_id_ << ", " << new_->set_id_ << "), dimensions = (" << old_->dimensions_ << ", " << new_->dimensions_ << ")"; @@ -3438,6 +3426,7 @@ StickerSetId StickersManager::on_get_input_sticker_set(FileId sticker_file_id, case telegram_api::inputStickerSetPremiumGifts::ID: case telegram_api::inputStickerSetEmojiGenericAnimations::ID: case telegram_api::inputStickerSetEmojiDefaultStatuses::ID: + case telegram_api::inputStickerSetEmojiChannelDefaultStatuses::ID: case telegram_api::inputStickerSetEmojiDefaultTopicIcons::ID: return add_special_sticker_set(SpecialStickerSetType(set_ptr)).id_; case telegram_api::inputStickerSetDice::ID: @@ -3542,7 +3531,7 @@ bool StickersManager::has_input_media(FileId sticker_file_id, bool is_secret) co const Sticker *sticker = get_sticker(sticker_file_id); CHECK(sticker != nullptr); if (file_view.is_encrypted_secret()) { - if (!file_view.encryption_key().empty() && file_view.has_remote_location() && + if (!file_view.encryption_key().empty() && file_view.has_full_remote_location() && !sticker->s_thumbnail_.file_id.is_valid()) { return true; } @@ -3559,7 +3548,7 @@ bool StickersManager::has_input_media(FileId sticker_file_id, bool is_secret) co if (file_view.is_encrypted()) { return false; } - if (td_->auth_manager_->is_bot() && file_view.has_remote_location()) { + if (td_->auth_manager_->is_bot() && file_view.has_full_remote_location()) { return true; } const Sticker *sticker = get_sticker(sticker_file_id); @@ -3572,7 +3561,7 @@ bool StickersManager::has_input_media(FileId sticker_file_id, bool is_secret) co // having remote location is not enough to have InputMedia, because the file may not have valid file_reference // also file_id needs to be duped, because upload can be called to repair the file_reference and every upload // request must have unique file_id - if (/* file_view.has_remote_location() || */ file_view.has_url()) { + if (/* file_view.has_full_remote_location() || */ file_view.has_url()) { return true; } } @@ -3587,8 +3576,9 @@ SecretInputMedia StickersManager::get_secret_input_media(FileId sticker_file_id, CHECK(sticker != nullptr); auto file_view = td_->file_manager_->get_file_view(sticker_file_id); if (file_view.is_encrypted_secret()) { - if (file_view.has_remote_location()) { - input_file = file_view.main_remote_location().as_input_encrypted_file(); + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr) { + input_file = main_remote_location->as_input_encrypted_file(); } if (!input_file) { return {}; @@ -3635,8 +3625,9 @@ SecretInputMedia StickersManager::get_secret_input_media(FileId sticker_file_id, layer}; } else { CHECK(!file_view.is_encrypted()); - auto &remote_location = file_view.remote_location(); - if (remote_location.is_web()) { + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); // because it has set_id + if (full_remote_location->is_web()) { // web stickers shouldn't have set_id LOG(ERROR) << "Have a web sticker in " << sticker->set_id_; return {}; @@ -3647,9 +3638,9 @@ SecretInputMedia StickersManager::get_secret_input_media(FileId sticker_file_id, } return SecretInputMedia{ nullptr, make_tl_object( - remote_location.get_id(), remote_location.get_access_hash(), 0 /*date*/, + full_remote_location->get_id(), full_remote_location->get_access_hash(), 0 /*date*/, get_sticker_format_mime_type(sticker->format_), narrow_cast(file_view.size()), - make_tl_object("t"), remote_location.get_dc_id().get_raw_id(), + make_tl_object("t"), full_remote_location->get_dc_id().get_raw_id(), std::move(attributes))}; } } @@ -3661,16 +3652,18 @@ tl_object_ptr StickersManager::get_input_media( if (file_view.is_encrypted()) { return nullptr; } - if (file_view.has_remote_location() && !file_view.main_remote_location().is_web() && input_file == nullptr) { + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr && !main_remote_location->is_web() && input_file == nullptr) { int32 flags = 0; if (!emoji.empty()) { flags |= telegram_api::inputMediaDocument::QUERY_MASK; } - return make_tl_object( - flags, false /*ignored*/, file_view.main_remote_location().as_input_document(), 0, emoji); + return make_tl_object(flags, false /*ignored*/, + main_remote_location->as_input_document(), 0, emoji); } - if (file_view.has_url()) { - return make_tl_object(0, false /*ignored*/, file_view.url(), 0); + const auto *url = file_view.get_url(); + if (url != nullptr) { + return make_tl_object(0, false /*ignored*/, *url, 0); } if (input_file != nullptr) { @@ -3696,7 +3689,7 @@ tl_object_ptr StickersManager::get_input_media( std::move(input_thumbnail), mime_type, std::move(attributes), vector>(), 0); } else { - CHECK(!file_view.has_remote_location()); + CHECK(main_remote_location == nullptr); } return nullptr; @@ -3714,8 +3707,9 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptrflags_ & telegram_api::stickerSet::INSTALLED_DATE_MASK) != 0; bool is_archived = set->archived_; bool is_official = set->official_; - StickerFormat sticker_format = - set->videos_ ? StickerFormat::Webm : (set->animated_ ? StickerFormat::Tgs : StickerFormat::Webp); + bool is_created = set->creator_; + bool has_text_color = set->emojis_ && set->text_color_; + bool channel_emoji_status = set->emojis_ && set->channel_emoji_status_; StickerType sticker_type = set->emojis_ ? StickerType::CustomEmoji : (set->masks_ ? StickerType::Mask : StickerType::Regular); @@ -3725,8 +3719,7 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptrfile_manager_.get(), PhotoSizeSource::sticker_set_thumbnail(set_id.get(), s->access_hash_, set->thumb_version_), 0, 0, - "", DcId::create(set->thumb_dc_id_), DialogId(), std::move(thumbnail_ptr), - get_sticker_set_thumbnail_format(sticker_format)); + "", DcId::create(set->thumb_dc_id_), DialogId(), std::move(thumbnail_ptr), PhotoFormat::Tgs); if (photo_size.get_offset() == 0) { if (!thumbnail.file_id.is_valid()) { thumbnail = std::move(photo_size.get<0>()); @@ -3750,8 +3743,10 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptrsticker_count_ = set->count_; s->hash_ = set->hash_; s->is_official_ = is_official; - s->sticker_format_ = sticker_format; s->sticker_type_ = sticker_type; + s->has_text_color_ = has_text_color; + s->channel_emoji_status_ = channel_emoji_status; + s->is_created_ = is_created; s->is_changed_ = true; } else { CHECK(s->id_ == set_id); @@ -3822,10 +3817,18 @@ StickerSetId StickersManager::on_get_sticker_set(tl_object_ptris_official_ = is_official; s->is_changed_ = true; } - if (s->sticker_format_ != sticker_format) { - LOG(ERROR) << "Format of stickers in " << set_id << '/' << s->short_name_ << " has changed from " - << s->sticker_format_ << " to " << sticker_format << " from " << source; - s->sticker_format_ = sticker_format; + if (s->is_created_ != is_created) { + s->is_created_ = is_created; + s->is_changed_ = true; + } + if (s->has_text_color_ != has_text_color) { + LOG(INFO) << "Needs repainting flag of " << set_id << " changed to " << has_text_color; + s->has_text_color_ = has_text_color; + s->is_changed_ = true; + } + if (s->channel_emoji_status_ != channel_emoji_status) { + LOG(INFO) << "Channel e,oji status flag of " << set_id << " changed to " << channel_emoji_status; + s->channel_emoji_status_ = channel_emoji_status; s->is_changed_ = true; } LOG_IF(ERROR, s->sticker_type_ != sticker_type) @@ -3865,7 +3868,7 @@ StickerSetId StickersManager::on_get_sticker_set_covered(tl_object_ptrsticker_ids_; - auto sticker_id = on_get_sticker_document(std::move(covered_set->cover_), sticker_set->sticker_format_).second; + auto sticker_id = on_get_sticker_document(std::move(covered_set->cover_), StickerFormat::Unknown, source).second; if (sticker_id.is_valid() && !td::contains(sticker_ids, sticker_id)) { sticker_ids.push_back(sticker_id); sticker_set->is_changed_ = true; @@ -3889,7 +3892,7 @@ StickerSetId StickersManager::on_get_sticker_set_covered(tl_object_ptrsticker_ids_; for (auto &cover : multicovered_set->covers_) { - auto sticker_id = on_get_sticker_document(std::move(cover), sticker_set->sticker_format_).second; + auto sticker_id = on_get_sticker_document(std::move(cover), StickerFormat::Unknown, source).second; if (sticker_id.is_valid() && !td::contains(sticker_ids, sticker_id)) { sticker_ids.push_back(sticker_id); sticker_set->is_changed_ = true; @@ -3963,6 +3966,8 @@ StickerSetId StickersManager::on_get_messages_sticker_set(StickerSetId sticker_s s->is_changed_ = true; s->are_keywords_loaded_ = true; s->is_sticker_has_text_color_loaded_ = true; + s->is_sticker_channel_emoji_status_loaded_ = true; + s->is_created_loaded_ = true; FlatHashMap document_id_to_sticker_id; @@ -3970,7 +3975,7 @@ StickerSetId StickersManager::on_get_messages_sticker_set(StickerSetId sticker_s s->premium_sticker_positions_.clear(); bool is_bot = td_->auth_manager_->is_bot(); for (auto &document_ptr : set->documents_) { - auto sticker_id = on_get_sticker_document(std::move(document_ptr), s->sticker_format_); + auto sticker_id = on_get_sticker_document(std::move(document_ptr), StickerFormat::Unknown, source); if (!sticker_id.second.is_valid() || sticker_id.first == 0) { continue; } @@ -4106,6 +4111,32 @@ void StickersManager::update_load_request(uint32 load_request_id, const Status & } } +void StickersManager::on_get_sticker_set_name(StickerSetId sticker_set_id, + telegram_api::object_ptr &&set_ptr) { + auto it = sticker_set_name_load_queries_.find(sticker_set_id); + CHECK(it != sticker_set_name_load_queries_.end()); + auto promises = std::move(it->second); + sticker_set_name_load_queries_.erase(it); + if (set_ptr == nullptr || set_ptr->get_id() != telegram_api::messages_stickerSet::ID) { + return fail_promises(promises, Status::Error(500, "Failed to get sticker set name")); + } + auto set = telegram_api::move_object_as(set_ptr); + if (sticker_set_id != StickerSetId(set->set_->id_)) { + LOG(ERROR) << "Expected " << sticker_set_id << ", but receive " << StickerSetId(set->set_->id_); + return fail_promises(promises, Status::Error(500, "Failed to get correct sticker set name")); + } + + StickerSet *sticker_set = get_sticker_set(sticker_set_id); + CHECK(sticker_set != nullptr); + if (!sticker_set->is_inited_) { + sticker_set->short_name_ = std::move(set->set_->short_name_); + } + + for (auto &promise : promises) { + promise.set_value(string(sticker_set->short_name_)); + } +} + void StickersManager::on_get_special_sticker_set(const SpecialStickerSetType &type, StickerSetId sticker_set_id) { auto s = get_sticker_set(sticker_set_id); CHECK(s != nullptr); @@ -4136,284 +4167,6 @@ void StickersManager::on_get_special_sticker_set(const SpecialStickerSetType &ty on_load_special_sticker_set(type, Status::OK()); } -td_api::object_ptr StickersManager::get_update_active_emoji_reactions_object() - const { - return td_api::make_object(vector(active_reactions_)); -} - -void StickersManager::save_active_reactions() { - LOG(INFO) << "Save " << active_reactions_.size() << " active reactions"; - G()->td_db()->get_binlog_pmc()->set("active_reactions", log_event_store(active_reactions_).as_slice().str()); -} - -void StickersManager::save_reactions() { - LOG(INFO) << "Save " << reactions_.reactions_.size() << " available reactions"; - are_reactions_loaded_from_database_ = true; - G()->td_db()->get_binlog_pmc()->set("reactions", log_event_store(reactions_).as_slice().str()); -} - -void StickersManager::save_recent_reactions() { - LOG(INFO) << "Save " << recent_reactions_.reactions_.size() << " recent reactions"; - are_recent_reactions_loaded_from_database_ = true; - G()->td_db()->get_binlog_pmc()->set("recent_reactions", log_event_store(recent_reactions_).as_slice().str()); -} - -void StickersManager::save_top_reactions() { - LOG(INFO) << "Save " << top_reactions_.reactions_.size() << " top reactions"; - are_top_reactions_loaded_from_database_ = true; - G()->td_db()->get_binlog_pmc()->set("top_reactions", log_event_store(top_reactions_).as_slice().str()); -} - -void StickersManager::load_active_reactions() { - LOG(INFO) << "Loading active reactions"; - string active_reactions = G()->td_db()->get_binlog_pmc()->get("active_reactions"); - if (active_reactions.empty()) { - return reload_reactions(); - } - - auto status = log_event_parse(active_reactions_, active_reactions); - if (status.is_error()) { - LOG(ERROR) << "Can't load active reactions: " << status; - active_reactions_ = {}; - return reload_reactions(); - } - - LOG(INFO) << "Successfully loaded " << active_reactions_.size() << " active reactions"; - - td_->messages_manager_->set_active_reactions(vector(active_reactions_)); - - send_closure(G()->td(), &Td::send_update, get_update_active_emoji_reactions_object()); -} - -void StickersManager::load_reactions() { - if (are_reactions_loaded_from_database_) { - return; - } - are_reactions_loaded_from_database_ = true; - - LOG(INFO) << "Loading available reactions"; - string reactions = G()->td_db()->get_binlog_pmc()->get("reactions"); - if (reactions.empty()) { - return reload_reactions(); - } - - auto new_reactions = reactions_; - auto status = log_event_parse(new_reactions, reactions); - if (status.is_error()) { - LOG(ERROR) << "Can't load available reactions: " << status; - return reload_reactions(); - } - for (auto &reaction : new_reactions.reactions_) { - if (!reaction.is_valid()) { - LOG(ERROR) << "Loaded invalid reaction"; - return reload_reactions(); - } - } - reactions_ = std::move(new_reactions); - - LOG(INFO) << "Successfully loaded " << reactions_.reactions_.size() << " available reactions"; - - update_active_reactions(); -} - -void StickersManager::load_recent_reactions() { - if (are_recent_reactions_loaded_from_database_) { - return; - } - are_recent_reactions_loaded_from_database_ = true; - - LOG(INFO) << "Loading recent reactions"; - string recent_reactions = G()->td_db()->get_binlog_pmc()->get("recent_reactions"); - if (recent_reactions.empty()) { - return reload_recent_reactions(); - } - - auto status = log_event_parse(recent_reactions_, recent_reactions); - if (status.is_error()) { - LOG(ERROR) << "Can't load recent reactions: " << status; - recent_reactions_ = {}; - return reload_recent_reactions(); - } - - LOG(INFO) << "Successfully loaded " << recent_reactions_.reactions_.size() << " recent reactions"; -} - -void StickersManager::load_top_reactions() { - if (are_top_reactions_loaded_from_database_) { - return; - } - are_top_reactions_loaded_from_database_ = true; - - LOG(INFO) << "Loading top reactions"; - string top_reactions = G()->td_db()->get_binlog_pmc()->get("top_reactions"); - if (top_reactions.empty()) { - return reload_top_reactions(); - } - - auto status = log_event_parse(top_reactions_, top_reactions); - if (status.is_error()) { - LOG(ERROR) << "Can't load top reactions: " << status; - top_reactions_ = {}; - return reload_top_reactions(); - } - - LOG(INFO) << "Successfully loaded " << top_reactions_.reactions_.size() << " top reactions"; -} - -void StickersManager::update_active_reactions() { - vector active_reactions; - for (auto &reaction : reactions_.reactions_) { - if (reaction.is_active_) { - active_reactions.emplace_back(reaction.reaction_); - } - } - if (active_reactions == active_reactions_) { - return; - } - active_reactions_ = active_reactions; - - save_active_reactions(); - - send_closure(G()->td(), &Td::send_update, get_update_active_emoji_reactions_object()); - - td_->messages_manager_->set_active_reactions(std::move(active_reactions)); -} - -void StickersManager::on_get_available_reactions( - tl_object_ptr &&available_reactions_ptr) { - CHECK(reactions_.are_being_reloaded_); - reactions_.are_being_reloaded_ = false; - - auto get_emoji_reaction_queries = std::move(pending_get_emoji_reaction_queries_); - pending_get_emoji_reaction_queries_.clear(); - SCOPE_EXIT { - for (auto &query : get_emoji_reaction_queries) { - query.second.set_value(get_emoji_reaction_object(query.first)); - } - }; - - if (available_reactions_ptr == nullptr) { - // failed to get available reactions - return; - } - - int32 constructor_id = available_reactions_ptr->get_id(); - if (constructor_id == telegram_api::messages_availableReactionsNotModified::ID) { - LOG(INFO) << "Available reactions are not modified"; - return; - } - - CHECK(constructor_id == telegram_api::messages_availableReactions::ID); - auto available_reactions = move_tl_object_as(available_reactions_ptr); - vector new_reactions; - for (auto &available_reaction : available_reactions->reactions_) { - Reaction reaction; - reaction.is_active_ = !available_reaction->inactive_; - reaction.is_premium_ = available_reaction->premium_; - reaction.reaction_ = std::move(available_reaction->reaction_); - reaction.title_ = std::move(available_reaction->title_); - reaction.static_icon_ = - on_get_sticker_document(std::move(available_reaction->static_icon_), StickerFormat::Webp).second; - reaction.appear_animation_ = - on_get_sticker_document(std::move(available_reaction->appear_animation_), StickerFormat::Tgs).second; - reaction.select_animation_ = - on_get_sticker_document(std::move(available_reaction->select_animation_), StickerFormat::Tgs).second; - reaction.activate_animation_ = - on_get_sticker_document(std::move(available_reaction->activate_animation_), StickerFormat::Tgs).second; - reaction.effect_animation_ = - on_get_sticker_document(std::move(available_reaction->effect_animation_), StickerFormat::Tgs).second; - reaction.around_animation_ = - on_get_sticker_document(std::move(available_reaction->around_animation_), StickerFormat::Tgs).second; - reaction.center_animation_ = - on_get_sticker_document(std::move(available_reaction->center_icon_), StickerFormat::Tgs).second; - - if (!reaction.is_valid()) { - LOG(ERROR) << "Receive invalid reaction " << reaction.reaction_; - continue; - } - if (reaction.is_premium_) { - LOG(ERROR) << "Receive premium reaction " << reaction.reaction_; - continue; - } - - new_reactions.push_back(std::move(reaction)); - } - reactions_.reactions_ = std::move(new_reactions); - reactions_.hash_ = available_reactions->hash_; - - save_reactions(); - - update_active_reactions(); -} - -void StickersManager::on_get_recent_reactions(tl_object_ptr &&reactions_ptr) { - CHECK(recent_reactions_.is_being_reloaded_); - recent_reactions_.is_being_reloaded_ = false; - - if (reactions_ptr == nullptr) { - // failed to get recent reactions - return; - } - - int32 constructor_id = reactions_ptr->get_id(); - if (constructor_id == telegram_api::messages_reactionsNotModified::ID) { - LOG(INFO) << "Top reactions are not modified"; - return; - } - - CHECK(constructor_id == telegram_api::messages_reactions::ID); - auto reactions = move_tl_object_as(reactions_ptr); - auto new_reactions = - transform(reactions->reactions_, [](const telegram_api::object_ptr &reaction) { - return get_message_reaction_string(reaction); - }); - if (new_reactions == recent_reactions_.reactions_ && recent_reactions_.hash_ == reactions->hash_) { - LOG(INFO) << "Top reactions are not modified"; - return; - } - recent_reactions_.reactions_ = std::move(new_reactions); - recent_reactions_.hash_ = reactions->hash_; - - auto expected_hash = get_reactions_hash(recent_reactions_.reactions_); - if (recent_reactions_.hash_ != expected_hash) { - LOG(ERROR) << "Receive hash " << recent_reactions_.hash_ << " instead of " << expected_hash << " for reactions " - << recent_reactions_.reactions_; - } - - save_recent_reactions(); -} - -void StickersManager::on_get_top_reactions(tl_object_ptr &&reactions_ptr) { - CHECK(top_reactions_.is_being_reloaded_); - top_reactions_.is_being_reloaded_ = false; - - if (reactions_ptr == nullptr) { - // failed to get top reactions - return; - } - - int32 constructor_id = reactions_ptr->get_id(); - if (constructor_id == telegram_api::messages_reactionsNotModified::ID) { - LOG(INFO) << "Top reactions are not modified"; - return; - } - - CHECK(constructor_id == telegram_api::messages_reactions::ID); - auto reactions = move_tl_object_as(reactions_ptr); - auto new_reactions = - transform(reactions->reactions_, [](const telegram_api::object_ptr &reaction) { - return get_message_reaction_string(reaction); - }); - if (new_reactions == top_reactions_.reactions_ && top_reactions_.hash_ == reactions->hash_) { - LOG(INFO) << "Top reactions are not modified"; - return; - } - top_reactions_.reactions_ = std::move(new_reactions); - top_reactions_.hash_ = reactions->hash_; - - save_top_reactions(); -} - void StickersManager::on_get_installed_sticker_sets(StickerType sticker_type, tl_object_ptr &&stickers_ptr) { auto type = static_cast(sticker_type); @@ -4513,7 +4266,7 @@ const std::map> &StickersManager::get_sticker_set_keyword } void StickersManager::find_sticker_set_stickers(const StickerSet *sticker_set, const vector &emojis, - const string &query, vector &result) { + const string &query, vector> &result) const { CHECK(sticker_set != nullptr); FlatHashSet found_sticker_ids; for (auto &emoji : emojis) { @@ -4532,8 +4285,9 @@ void StickersManager::find_sticker_set_stickers(const StickerSet *sticker_set, c if (!found_sticker_ids.empty()) { for (auto sticker_id : sticker_set->sticker_ids_) { if (found_sticker_ids.count(sticker_id) != 0) { + const Sticker *s = get_sticker(sticker_id); LOG(INFO) << "Add " << sticker_id << " sticker from " << sticker_set->id_; - result.push_back(sticker_id); + result.emplace_back(is_sticker_format_animated(s->format_), sticker_id); } } } @@ -4749,12 +4503,12 @@ vector StickersManager::get_stickers(StickerType sticker_type, string qu if (sticker_type == StickerType::CustomEmoji) { switch (dialog_id.get_type()) { case DialogType::User: - if (dialog_id.get_user_id() == td_->contacts_manager_->get_my_id()) { + if (dialog_id.get_user_id() == td_->user_manager_->get_my_id()) { allow_premium = true; } break; case DialogType::SecretChat: - if (td_->contacts_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()) < + if (td_->user_manager_->get_secret_chat_layer(dialog_id.get_secret_chat_id()) < static_cast(SecretChatLayer::SpoilerAndCustomEmojiEntities)) { promise.set_value(Unit()); return {}; @@ -4794,18 +4548,20 @@ vector StickersManager::get_stickers(StickerType sticker_type, string qu examined_sticker_sets.push_back(sticker_set); } } - std::stable_sort( - examined_sticker_sets.begin(), examined_sticker_sets.end(), [](const StickerSet *lhs, const StickerSet *rhs) { - if (lhs->is_installed_ != rhs->is_installed_) { - return lhs->is_installed_; - } - if (lhs->is_archived_ != rhs->is_archived_) { - return lhs->is_archived_; - } - return is_sticker_format_animated(lhs->sticker_format_) && !is_sticker_format_animated(rhs->sticker_format_); - }); + vector> partial_results[2][2]; for (auto sticker_set : examined_sticker_sets) { - find_sticker_set_stickers(sticker_set, emojis, prepared_query, result); + find_sticker_set_stickers(sticker_set, emojis, prepared_query, + partial_results[sticker_set->is_installed_][sticker_set->is_archived_]); + } + for (int is_installed = 1; is_installed >= 0; is_installed--) { + for (int is_archived = 1; is_archived >= 0; is_archived--) { + auto &partial_result = partial_results[is_installed][is_archived]; + std::stable_sort(partial_result.begin(), partial_result.end(), + [](const auto &lhs, const auto &rhs) { return lhs.first && !rhs.first; }); + for (auto &is_animated_sticker_id_pair : partial_result) { + result.push_back(is_animated_sticker_id_pair.second); + } + } } vector sorted; @@ -5060,7 +4816,8 @@ void StickersManager::on_find_stickers_success(const string &emoji, vector sticker_ids; for (auto &sticker : received_stickers->stickers_) { - FileId sticker_id = on_get_sticker_document(std::move(sticker), StickerFormat::Unknown).second; + FileId sticker_id = + on_get_sticker_document(std::move(sticker), StickerFormat::Unknown, "on_find_stickers_success").second; if (sticker_id.is_valid()) { sticker_ids.push_back(sticker_id); } @@ -5271,8 +5028,28 @@ StickerSetId StickersManager::get_sticker_set(StickerSetId set_id, Promise return StickerSetId(); } - promise.set_value(Unit()); - return set_id; + promise.set_value(Unit()); + return set_id; +} + +void StickersManager::get_sticker_set_name(StickerSetId set_id, Promise &&promise) { + constexpr int64 GREAT_MINDS_COLOR_SET_ID = 151353307481243663; + if (set_id.get() == GREAT_MINDS_SET_ID || set_id.get() == GREAT_MINDS_COLOR_SET_ID) { + return promise.set_value("TelegramGreatMinds"); + } + + const StickerSet *sticker_set = get_sticker_set(set_id); + if (sticker_set == nullptr) { + return promise.set_error(Status::Error(400, "Sticker set not found")); + } + if (!sticker_set->short_name_.empty()) { + return promise.set_value(string(sticker_set->short_name_)); + } + auto &queries = sticker_set_name_load_queries_[set_id]; + queries.push_back(std::move(promise)); + if (queries.size() == 1u) { + td_->create_handler()->send(set_id, get_input_sticker_set(sticker_set)); + } } StickerSetId StickersManager::search_sticker_set(const string &short_name_to_search, Promise &&promise) { @@ -5316,32 +5093,48 @@ std::pair> StickersManager::search_installed_sticker return {narrow_cast(result.first), convert_sticker_set_ids(result.second)}; } -vector StickersManager::search_sticker_sets(const string &query, Promise &&promise) { +vector StickersManager::search_sticker_sets(StickerType sticker_type, const string &query, + Promise &&promise) { + if (sticker_type == StickerType::Mask) { + promise.set_value(Unit()); + return {}; + } + auto type = static_cast(sticker_type); + auto q = clean_name(query, 1000); - auto it = found_sticker_sets_.find(q); - if (it != found_sticker_sets_.end()) { + auto it = found_sticker_sets_[type].find(q); + if (it != found_sticker_sets_[type].end()) { promise.set_value(Unit()); - return it->second; + auto result = it->second; + td::remove_if(result, [&](StickerSetId sticker_set_id) { + const auto *sticker_set = get_sticker_set(sticker_set_id); + CHECK(sticker_set != nullptr); + return sticker_set->is_inited_ && sticker_set->is_installed_; + }); + return result; } - auto &promises = search_sticker_sets_queries_[q]; + auto &promises = search_sticker_sets_queries_[type][q]; promises.push_back(std::move(promise)); if (promises.size() == 1u) { - td_->create_handler()->send(std::move(q)); + td_->create_handler()->send(sticker_type, std::move(q)); } return {}; } void StickersManager::on_find_sticker_sets_success( - const string &query, tl_object_ptr &&sticker_sets) { + StickerType sticker_type, const string &query, + tl_object_ptr &&sticker_sets) { + auto type = static_cast(sticker_type); CHECK(sticker_sets != nullptr); switch (sticker_sets->get_id()) { case telegram_api::messages_foundStickerSetsNotModified::ID: - return on_find_sticker_sets_fail(query, Status::Error(500, "Receive messages.foundStickerSetsNotModified")); + return on_find_sticker_sets_fail(sticker_type, query, + Status::Error(500, "Receive messages.foundStickerSetsNotModified")); case telegram_api::messages_foundStickerSets::ID: { auto found_stickers_sets = move_tl_object_as(sticker_sets); - vector &sticker_set_ids = found_sticker_sets_[query]; + vector &sticker_set_ids = found_sticker_sets_[type][query]; CHECK(sticker_set_ids.empty()); for (auto &sticker_set : found_stickers_sets->sets_) { @@ -5349,8 +5142,15 @@ void StickersManager::on_find_sticker_sets_success( if (!set_id.is_valid()) { continue; } + auto *s = get_sticker_set(set_id); + CHECK(s != nullptr); + if (s->sticker_type_ != sticker_type) { + LOG(ERROR) << "Receive " << set_id << " of type " << s->sticker_type_ << " while searching for " + << sticker_type << " sticker sets with query " << query; + continue; + } - update_sticker_set(get_sticker_set(set_id), "on_find_sticker_sets_success"); + update_sticker_set(s, "on_find_sticker_sets_success"); sticker_set_ids.push_back(set_id); } @@ -5361,23 +5161,24 @@ void StickersManager::on_find_sticker_sets_success( UNREACHABLE(); } - auto it = search_sticker_sets_queries_.find(query); - CHECK(it != search_sticker_sets_queries_.end()); + auto it = search_sticker_sets_queries_[type].find(query); + CHECK(it != search_sticker_sets_queries_[type].end()); CHECK(!it->second.empty()); auto promises = std::move(it->second); - search_sticker_sets_queries_.erase(it); + search_sticker_sets_queries_[type].erase(it); set_promises(promises); } -void StickersManager::on_find_sticker_sets_fail(const string &query, Status &&error) { - CHECK(found_sticker_sets_.count(query) == 0); +void StickersManager::on_find_sticker_sets_fail(StickerType sticker_type, const string &query, Status &&error) { + auto type = static_cast(sticker_type); + CHECK(found_sticker_sets_[type].count(query) == 0); - auto it = search_sticker_sets_queries_.find(query); - CHECK(it != search_sticker_sets_queries_.end()); + auto it = search_sticker_sets_queries_[type].find(query); + CHECK(it != search_sticker_sets_queries_[type].end()); CHECK(!it->second.empty()); auto promises = std::move(it->second); - search_sticker_sets_queries_.erase(it); + search_sticker_sets_queries_[type].erase(it); fail_promises(promises, std::move(error)); } @@ -5642,8 +5443,7 @@ void StickersManager::update_sticker_set(StickerSet *sticker_set, const char *so void StickersManager::load_sticker_sets(vector &&sticker_set_ids, Promise &&promise) { if (sticker_set_ids.empty()) { - promise.set_value(Unit()); - return; + return promise.set_value(Unit()); } CHECK(current_sticker_set_load_request_ < std::numeric_limits::max()); @@ -5766,7 +5566,8 @@ void StickersManager::on_load_sticker_set_from_database(StickerSetId sticker_set << format::as_hex_dump<4>(Slice(value)); } } - if (!sticker_set->is_sticker_has_text_color_loaded_ || !sticker_set->are_keywords_loaded_ || + if (!sticker_set->is_created_loaded_ || !sticker_set->is_sticker_channel_emoji_status_loaded_ || + !sticker_set->is_sticker_has_text_color_loaded_ || !sticker_set->are_keywords_loaded_ || !sticker_set->is_thumbnail_reloaded_ || !sticker_set->are_legacy_sticker_thumbnails_reloaded_) { do_reload_sticker_set(sticker_set_id, get_input_sticker_set(sticker_set), 0, Auto(), "on_load_sticker_set_from_database 2"); @@ -6049,7 +5850,8 @@ void StickersManager::on_update_sticker_sets(StickerType sticker_type) { void StickersManager::try_update_animated_emoji_messages() { auto sticker_set = get_animated_emoji_sticker_set(); - vector full_message_ids; + vector message_full_ids; + vector quick_reply_message_full_ids; for (auto &it : emoji_messages_) { auto new_animated_sticker = get_animated_emoji_sticker(sticker_set, it.first); auto new_sound_file_id = get_animated_emoji_sound_file_id(it.first); @@ -6057,12 +5859,19 @@ void StickersManager::try_update_animated_emoji_messages() { (new_animated_sticker.first.is_valid() && new_sound_file_id != it.second->sound_file_id_)) { it.second->animated_emoji_sticker_ = new_animated_sticker; it.second->sound_file_id_ = new_sound_file_id; - it.second->full_message_ids_.foreach( - [&](const FullMessageId &full_message_id) { full_message_ids.push_back(full_message_id); }); + it.second->message_full_ids_.foreach( + [&](const MessageFullId &message_full_id) { message_full_ids.push_back(message_full_id); }); + it.second->quick_reply_message_full_ids_.foreach([&](const QuickReplyMessageFullId &message_full_id) { + quick_reply_message_full_ids.push_back(message_full_id); + }); } } - for (const auto &full_message_id : full_message_ids) { - td_->messages_manager_->on_external_update_message_content(full_message_id); + for (const auto &message_full_id : message_full_ids) { + td_->messages_manager_->on_external_update_message_content(message_full_id, "try_update_animated_emoji_messages"); + } + for (const auto &message_full_id : quick_reply_message_full_ids) { + td_->quick_reply_manager_->on_external_update_message_content(message_full_id, + "try_update_animated_emoji_messages"); } } @@ -6072,86 +5881,107 @@ void StickersManager::try_update_custom_emoji_messages(CustomEmojiId custom_emoj return; } - vector full_message_ids; + vector message_full_ids; + vector quick_reply_message_full_ids; auto new_sticker_id = get_custom_animated_emoji_sticker_id(custom_emoji_id); if (new_sticker_id != it->second->sticker_id_) { it->second->sticker_id_ = new_sticker_id; - it->second->full_message_ids_.foreach( - [&](const FullMessageId &full_message_id) { full_message_ids.push_back(full_message_id); }); + it->second->message_full_ids_.foreach( + [&](const MessageFullId &message_full_id) { message_full_ids.push_back(message_full_id); }); + it->second->quick_reply_message_full_ids_.foreach([&](const QuickReplyMessageFullId &message_full_id) { + quick_reply_message_full_ids.push_back(message_full_id); + }); + } + for (const auto &message_full_id : message_full_ids) { + td_->messages_manager_->on_external_update_message_content(message_full_id, "try_update_custom_emoji_messages"); } - for (const auto &full_message_id : full_message_ids) { - td_->messages_manager_->on_external_update_message_content(full_message_id); + for (const auto &message_full_id : quick_reply_message_full_ids) { + td_->quick_reply_manager_->on_external_update_message_content(message_full_id, "try_update_custom_emoji_messages"); } } void StickersManager::try_update_premium_gift_messages() { auto sticker_set = get_premium_gift_sticker_set(); - vector full_message_ids; + vector message_full_ids; for (auto &it : premium_gift_messages_) { auto new_sticker_id = get_premium_gift_option_sticker_id(sticker_set, it.first); if (new_sticker_id != it.second->sticker_id_) { it.second->sticker_id_ = new_sticker_id; - for (const auto &full_message_id : it.second->full_message_ids_) { - full_message_ids.push_back(full_message_id); + for (const auto &message_full_id : it.second->message_full_ids_) { + message_full_ids.push_back(message_full_id); } } } - for (const auto &full_message_id : full_message_ids) { - td_->messages_manager_->on_external_update_message_content(full_message_id); + for (const auto &message_full_id : message_full_ids) { + td_->messages_manager_->on_external_update_message_content(message_full_id, "try_update_premium_gift_messages"); } } -void StickersManager::register_premium_gift(int32 months, FullMessageId full_message_id, const char *source) { +void StickersManager::register_premium_gift(int32 months, int64 star_count, MessageFullId message_full_id, + const char *source) { + if (months == 0) { + months = StarManager::get_months_by_star_count(star_count); + } if (td_->auth_manager_->is_bot() || months == 0) { return; } - LOG(INFO) << "Register premium gift for " << months << " months from " << full_message_id << " from " << source; + LOG(INFO) << "Register premium gift for " << months << " months from " << message_full_id << " from " << source; auto &premium_gift_messages_ptr = premium_gift_messages_[months]; if (premium_gift_messages_ptr == nullptr) { premium_gift_messages_ptr = make_unique(); } auto &premium_gift_messages = *premium_gift_messages_ptr; - if (premium_gift_messages.full_message_ids_.empty()) { + if (premium_gift_messages.message_full_ids_.empty()) { premium_gift_messages.sticker_id_ = get_premium_gift_option_sticker_id(months); } - bool is_inserted = premium_gift_messages.full_message_ids_.insert(full_message_id).second; - LOG_CHECK(is_inserted) << source << " " << months << " " << full_message_id; + bool is_inserted = premium_gift_messages.message_full_ids_.insert(message_full_id).second; + LOG_CHECK(is_inserted) << source << ' ' << months << ' ' << message_full_id; } -void StickersManager::unregister_premium_gift(int32 months, FullMessageId full_message_id, const char *source) { +void StickersManager::unregister_premium_gift(int32 months, int64 star_count, MessageFullId message_full_id, + const char *source) { + if (months == 0) { + months = StarManager::get_months_by_star_count(star_count); + } if (td_->auth_manager_->is_bot() || months == 0) { return; } - LOG(INFO) << "Unregister premium gift for " << months << " months from " << full_message_id << " from " << source; + LOG(INFO) << "Unregister premium gift for " << months << " months from " << message_full_id << " from " << source; auto it = premium_gift_messages_.find(months); CHECK(it != premium_gift_messages_.end()); - auto &message_ids = it->second->full_message_ids_; - auto is_deleted = message_ids.erase(full_message_id) > 0; - LOG_CHECK(is_deleted) << source << " " << months << " " << full_message_id; + auto &message_ids = it->second->message_full_ids_; + auto is_deleted = message_ids.erase(message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << months << ' ' << message_full_id; if (message_ids.empty()) { premium_gift_messages_.erase(it); } } -void StickersManager::register_dice(const string &emoji, int32 value, FullMessageId full_message_id, - const char *source) { +void StickersManager::register_dice(const string &emoji, int32 value, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source) { CHECK(!emoji.empty()); if (td_->auth_manager_->is_bot()) { return; } - LOG(INFO) << "Register dice " << emoji << " with value " << value << " from " << full_message_id << " from " - << source; - dice_messages_[emoji].insert(full_message_id); + LOG(INFO) << "Register dice " << emoji << " with value " << value << " from " << message_full_id << '/' + << quick_reply_message_full_id << " from " << source; + if (quick_reply_message_full_id.is_valid()) { + dice_quick_reply_messages_[emoji].insert(quick_reply_message_full_id); + } else { + CHECK(message_full_id.get_dialog_id().is_valid()); + dice_messages_[emoji].insert(message_full_id); + } if (!td::contains(dice_emojis_, emoji)) { - if (full_message_id.get_message_id().is_any_server() && - full_message_id.get_dialog_id().get_type() != DialogType::SecretChat) { + if (quick_reply_message_full_id.is_valid() || + (message_full_id.get_message_id().is_any_server() && + message_full_id.get_dialog_id().get_type() != DialogType::SecretChat)) { send_closure(G()->config_manager(), &ConfigManager::reget_app_config, Promise()); } return; @@ -6169,7 +5999,7 @@ void StickersManager::register_dice(const string &emoji, int32 value, FullMessag } if (need_load) { - LOG(INFO) << "Waiting for a dice sticker set needed in " << full_message_id; + LOG(INFO) << "Waiting for a dice sticker set needed in " << message_full_id << '/' << quick_reply_message_full_id; load_special_sticker_set(special_sticker_set); } else { // TODO reload once in a while @@ -6177,40 +6007,50 @@ void StickersManager::register_dice(const string &emoji, int32 value, FullMessag } } -void StickersManager::unregister_dice(const string &emoji, int32 value, FullMessageId full_message_id, - const char *source) { +void StickersManager::unregister_dice(const string &emoji, int32 value, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source) { CHECK(!emoji.empty()); if (td_->auth_manager_->is_bot()) { return; } - LOG(INFO) << "Unregister dice " << emoji << " with value " << value << " from " << full_message_id << " from " - << source; - auto &message_ids = dice_messages_[emoji]; - auto is_deleted = message_ids.erase(full_message_id) > 0; - LOG_CHECK(is_deleted) << source << " " << emoji << " " << value << " " << full_message_id; + LOG(INFO) << "Unregister dice " << emoji << " with value " << value << " from " << message_full_id << '/' + << quick_reply_message_full_id << " from " << source; + if (quick_reply_message_full_id.is_valid()) { + auto &message_ids = dice_quick_reply_messages_[emoji]; + auto is_deleted = message_ids.erase(quick_reply_message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << emoji << ' ' << value << ' ' << quick_reply_message_full_id; - if (message_ids.empty()) { - dice_messages_.erase(emoji); + if (message_ids.empty()) { + dice_quick_reply_messages_.erase(emoji); + } + } else { + auto &message_ids = dice_messages_[emoji]; + auto is_deleted = message_ids.erase(message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << emoji << ' ' << value << ' ' << message_full_id; + + if (message_ids.empty()) { + dice_messages_.erase(emoji); + } } } -void StickersManager::register_emoji(const string &emoji, CustomEmojiId custom_emoji_id, FullMessageId full_message_id, - const char *source) { +void StickersManager::register_emoji(const string &emoji, CustomEmojiId custom_emoji_id, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source) { CHECK(!emoji.empty()); if (td_->auth_manager_->is_bot()) { return; } - LOG(INFO) << "Register emoji " << emoji << " with " << custom_emoji_id << " from " << full_message_id << " from " - << source; + LOG(INFO) << "Register emoji " << emoji << " with " << custom_emoji_id << " from " << message_full_id << '/' + << quick_reply_message_full_id << " from " << source; if (custom_emoji_id.is_valid()) { auto &emoji_messages_ptr = custom_emoji_messages_[custom_emoji_id]; if (emoji_messages_ptr == nullptr) { emoji_messages_ptr = make_unique(); } auto &emoji_messages = *emoji_messages_ptr; - if (emoji_messages.full_message_ids_.empty()) { + if (emoji_messages.message_full_ids_.empty() && emoji_messages.quick_reply_message_full_ids_.empty()) { if (!disable_animated_emojis_ && custom_emoji_to_sticker_id_.count(custom_emoji_id) == 0) { load_custom_emoji_sticker_from_database_force(custom_emoji_id); if (custom_emoji_to_sticker_id_.count(custom_emoji_id) == 0) { @@ -6219,7 +6059,12 @@ void StickersManager::register_emoji(const string &emoji, CustomEmojiId custom_e } emoji_messages.sticker_id_ = get_custom_animated_emoji_sticker_id(custom_emoji_id); } - emoji_messages.full_message_ids_.insert(full_message_id); + if (quick_reply_message_full_id.is_valid()) { + emoji_messages.quick_reply_message_full_ids_.insert(quick_reply_message_full_id); + } else { + CHECK(message_full_id.get_dialog_id().is_valid()); + emoji_messages.message_full_ids_.insert(message_full_id); + } return; } @@ -6228,30 +6073,39 @@ void StickersManager::register_emoji(const string &emoji, CustomEmojiId custom_e emoji_messages_ptr = make_unique(); } auto &emoji_messages = *emoji_messages_ptr; - if (emoji_messages.full_message_ids_.empty()) { + if (emoji_messages.message_full_ids_.empty() && emoji_messages.quick_reply_message_full_ids_.empty()) { emoji_messages.animated_emoji_sticker_ = get_animated_emoji_sticker(emoji); emoji_messages.sound_file_id_ = get_animated_emoji_sound_file_id(emoji); } - emoji_messages.full_message_ids_.insert(full_message_id); + if (quick_reply_message_full_id.is_valid()) { + emoji_messages.quick_reply_message_full_ids_.insert(quick_reply_message_full_id); + } else { + CHECK(message_full_id.get_dialog_id().is_valid()); + emoji_messages.message_full_ids_.insert(message_full_id); + } } void StickersManager::unregister_emoji(const string &emoji, CustomEmojiId custom_emoji_id, - FullMessageId full_message_id, const char *source) { + MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source) { CHECK(!emoji.empty()); if (td_->auth_manager_->is_bot()) { return; } - LOG(INFO) << "Unregister emoji " << emoji << " with " << custom_emoji_id << " from " << full_message_id << " from " - << source; + LOG(INFO) << "Unregister emoji " << emoji << " with " << custom_emoji_id << " from " << message_full_id << '/' + << quick_reply_message_full_id << " from " << source; if (custom_emoji_id.is_valid()) { auto it = custom_emoji_messages_.find(custom_emoji_id); CHECK(it != custom_emoji_messages_.end()); - auto &full_message_ids = it->second->full_message_ids_; - auto is_deleted = full_message_ids.erase(full_message_id) > 0; - LOG_CHECK(is_deleted) << source << ' ' << custom_emoji_id << ' ' << full_message_id; - - if (full_message_ids.empty()) { + if (quick_reply_message_full_id.is_valid()) { + auto is_deleted = it->second->quick_reply_message_full_ids_.erase(quick_reply_message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << custom_emoji_id << ' ' << quick_reply_message_full_id; + } else { + auto is_deleted = it->second->message_full_ids_.erase(message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << custom_emoji_id << ' ' << message_full_id; + } + if (it->second->message_full_ids_.empty() && it->second->quick_reply_message_full_ids_.empty()) { custom_emoji_messages_.erase(it); } return; @@ -6259,11 +6113,14 @@ void StickersManager::unregister_emoji(const string &emoji, CustomEmojiId custom auto it = emoji_messages_.find(emoji); CHECK(it != emoji_messages_.end()); - auto &full_message_ids = it->second->full_message_ids_; - auto is_deleted = full_message_ids.erase(full_message_id) > 0; - LOG_CHECK(is_deleted) << source << ' ' << emoji << ' ' << full_message_id; - - if (full_message_ids.empty()) { + if (quick_reply_message_full_id.is_valid()) { + auto is_deleted = it->second->quick_reply_message_full_ids_.erase(quick_reply_message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << custom_emoji_id << ' ' << quick_reply_message_full_id; + } else { + auto is_deleted = it->second->message_full_ids_.erase(message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << custom_emoji_id << ' ' << message_full_id; + } + if (it->second->message_full_ids_.empty() && it->second->quick_reply_message_full_ids_.empty()) { emoji_messages_.erase(it); } } @@ -6377,33 +6234,78 @@ void StickersManager::get_default_emoji_statuses(bool is_recursive, return; } - vector> statuses; + vector custom_emoji_ids; for (auto sticker_id : sticker_set->sticker_ids_) { auto custom_emoji_id = get_custom_emoji_id(sticker_id); if (!custom_emoji_id.is_valid()) { LOG(ERROR) << "Ignore wrong sticker " << sticker_id; continue; } - statuses.push_back(td_api::make_object(custom_emoji_id.get())); - if (statuses.size() >= 8) { + custom_emoji_ids.push_back(custom_emoji_id.get()); + if (custom_emoji_ids.size() >= 8) { break; } } - promise.set_value(td_api::make_object(std::move(statuses))); + promise.set_value(td_api::make_object(std::move(custom_emoji_ids))); +} + +int StickersManager::is_custom_emoji_from_sticker_set(CustomEmojiId custom_emoji_id, + StickerSetId sticker_set_id) const { + const auto *sticker_set = get_sticker_set(sticker_set_id); + if (sticker_set == nullptr || !sticker_set->was_loaded_) { + return -1; + } + for (auto sticker_id : sticker_set->sticker_ids_) { + if (get_custom_emoji_id(sticker_id) == custom_emoji_id) { + return 1; + } + } + return 0; } bool StickersManager::is_default_emoji_status(CustomEmojiId custom_emoji_id) { - auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::default_statuses()); + return is_custom_emoji_from_sticker_set( + custom_emoji_id, add_special_sticker_set(SpecialStickerSetType::default_statuses()).id_) == 1 || + is_custom_emoji_from_sticker_set( + custom_emoji_id, add_special_sticker_set(SpecialStickerSetType::default_channel_statuses()).id_) == 1; +} + +void StickersManager::get_default_channel_emoji_statuses(bool is_recursive, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::default_channel_statuses()); auto sticker_set = get_sticker_set(special_sticker_set.id_); if (sticker_set == nullptr || !sticker_set->was_loaded_) { - return false; + if (is_recursive) { + return promise.set_value(td_api::make_object()); + } + + pending_get_default_channel_statuses_queries_.push_back(PromiseCreator::lambda( + [actor_id = actor_id(this), promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &StickersManager::get_default_channel_emoji_statuses, true, std::move(promise)); + } + })); + load_special_sticker_set(special_sticker_set); + return; } + + vector custom_emoji_ids; for (auto sticker_id : sticker_set->sticker_ids_) { - if (get_custom_emoji_id(sticker_id) == custom_emoji_id) { - return true; + auto custom_emoji_id = get_custom_emoji_id(sticker_id); + if (!custom_emoji_id.is_valid()) { + LOG(ERROR) << "Ignore wrong sticker " << sticker_id; + continue; + } + custom_emoji_ids.push_back(custom_emoji_id.get()); + if (custom_emoji_ids.size() >= 8) { + break; } } - return false; + promise.set_value(td_api::make_object(std::move(custom_emoji_ids))); } void StickersManager::get_default_topic_icons(bool is_recursive, @@ -6664,42 +6566,54 @@ void StickersManager::on_get_custom_emoji_documents( continue; } - on_get_sticker_document(std::move(document), StickerFormat::Unknown); + on_get_sticker_document(std::move(document), StickerFormat::Unknown, "on_get_custom_emoji_documents"); } promise.set_value(get_custom_emoji_stickers_object(custom_emoji_ids)); } -string StickersManager::get_default_dialog_photo_custom_emoji_ids_database_key(bool for_user) { - return for_user ? "default_profile_photo_custom_emoji_ids" : "default_dialog_photo_custom_emoji_ids"; +void StickersManager::get_default_custom_emoji_stickers(StickerListType sticker_list_type, bool force_reload, + Promise> &&promise) { + auto index = static_cast(sticker_list_type); + if (are_default_custom_emoji_ids_loaded_[index] && !force_reload) { + return get_custom_emoji_stickers_unlimited(default_custom_emoji_ids_[index], std::move(promise)); + } + + auto &queries = default_custom_emoji_ids_load_queries_[index]; + queries.push_back(std::move(promise)); + load_default_custom_emoji_ids(sticker_list_type, force_reload); } -void StickersManager::get_default_dialog_photo_custom_emoji_stickers( - bool for_user, bool force_reload, Promise> &&promise) { - if (are_default_dialog_photo_custom_emoji_ids_loaded_[for_user] && !force_reload) { - return get_custom_emoji_stickers_unlimited(default_dialog_photo_custom_emoji_ids_[for_user], std::move(promise)); +void StickersManager::get_sticker_list_emoji_statuses(StickerListType sticker_list_type, bool force_reload, + Promise> &&promise) { + auto index = static_cast(sticker_list_type); + if (are_default_custom_emoji_ids_loaded_[index] && !force_reload) { + return promise.set_value(get_emoji_statuses_object(default_custom_emoji_ids_[index])); } - auto &queries = default_dialog_photo_custom_emoji_ids_load_queries_[for_user]; + auto &queries = default_emoji_statuses_load_queries_[index]; queries.push_back(std::move(promise)); - if (queries.size() != 1) { + load_default_custom_emoji_ids(sticker_list_type, force_reload); +} + +void StickersManager::load_default_custom_emoji_ids(StickerListType sticker_list_type, bool force_reload) { + auto index = static_cast(sticker_list_type); + if (default_custom_emoji_ids_load_queries_[index].size() + default_emoji_statuses_load_queries_[index].size() != 1) { // query has already been sent, just wait for the result return; } - if (G()->use_sqlite_pmc() && !are_default_dialog_photo_custom_emoji_ids_loaded_[for_user]) { - LOG(INFO) << "Trying to load " << (for_user ? "profile" : "chat") - << " photo custom emoji identifiers from database"; + if (G()->use_sqlite_pmc() && !are_default_custom_emoji_ids_loaded_[index]) { + LOG(INFO) << "Trying to load " << sticker_list_type << " from database"; return G()->td_db()->get_sqlite_pmc()->get( - get_default_dialog_photo_custom_emoji_ids_database_key(for_user), - PromiseCreator::lambda([for_user, force_reload](string value) { - send_closure(G()->stickers_manager(), - &StickersManager::on_load_default_dialog_photo_custom_emoji_ids_from_database, for_user, - force_reload, std::move(value)); + get_sticker_list_type_database_key(sticker_list_type), + PromiseCreator::lambda([sticker_list_type, force_reload](string value) { + send_closure(G()->stickers_manager(), &StickersManager::on_load_default_custom_emoji_ids_from_database, + sticker_list_type, force_reload, std::move(value)); })); } - reload_default_dialog_photo_custom_emoji_ids(for_user); + reload_default_custom_emoji_ids(sticker_list_type); } class StickersManager::CustomEmojiIdsLogEvent { @@ -6726,77 +6640,86 @@ class StickersManager::CustomEmojiIdsLogEvent { } }; -void StickersManager::on_load_default_dialog_photo_custom_emoji_ids_from_database(bool for_user, bool force_reload, - string value) { +void StickersManager::on_load_default_custom_emoji_ids_from_database(StickerListType sticker_list_type, + bool force_reload, string value) { if (G()->close_flag()) { - fail_promises(default_dialog_photo_custom_emoji_ids_load_queries_[for_user], Global::request_aborted_error()); + auto index = static_cast(sticker_list_type); + fail_promises(default_custom_emoji_ids_load_queries_[index], Global::request_aborted_error()); + fail_promises(default_emoji_statuses_load_queries_[index], Global::request_aborted_error()); return; } if (value.empty()) { - return reload_default_dialog_photo_custom_emoji_ids(for_user); + return reload_default_custom_emoji_ids(sticker_list_type); } - LOG(INFO) << "Successfully loaded default " << (for_user ? "profile" : "chat") - << " photo custom emoji identifiers of size " << value.size() << " from database"; + LOG(INFO) << "Successfully loaded " << sticker_list_type << " of size " << value.size() << " from database"; CustomEmojiIdsLogEvent log_event; if (log_event_parse(log_event, value).is_error()) { - LOG(ERROR) << "Delete invalid default " << (for_user ? "profile" : "chat") - << " photo custom emoji identifiers from database"; - G()->td_db()->get_sqlite_pmc()->erase(get_default_dialog_photo_custom_emoji_ids_database_key(for_user), Auto()); - return reload_default_dialog_photo_custom_emoji_ids(for_user); + LOG(ERROR) << "Delete invalid " << sticker_list_type << " from database"; + G()->td_db()->get_sqlite_pmc()->erase(get_sticker_list_type_database_key(sticker_list_type), Auto()); + return reload_default_custom_emoji_ids(sticker_list_type); } - on_get_default_dialog_photo_custom_emoji_ids_success(for_user, std::move(log_event.custom_emoji_ids_), - log_event.hash_); + on_get_default_custom_emoji_ids_success(sticker_list_type, std::move(log_event.custom_emoji_ids_), log_event.hash_); if (force_reload) { - reload_default_dialog_photo_custom_emoji_ids(for_user); + reload_default_custom_emoji_ids(sticker_list_type); } } -void StickersManager::reload_default_dialog_photo_custom_emoji_ids(bool for_user) { +void StickersManager::reload_default_custom_emoji_ids(StickerListType sticker_list_type) { if (G()->close_flag()) { - fail_promises(default_dialog_photo_custom_emoji_ids_load_queries_[for_user], Global::request_aborted_error()); + auto index = static_cast(sticker_list_type); + fail_promises(default_custom_emoji_ids_load_queries_[index], Global::request_aborted_error()); + fail_promises(default_emoji_statuses_load_queries_[index], Global::request_aborted_error()); return; } CHECK(!td_->auth_manager_->is_bot()); - if (are_default_dialog_photo_custom_emoji_ids_being_loaded_[for_user]) { + auto index = static_cast(sticker_list_type); + if (are_default_custom_emoji_ids_being_loaded_[index]) { return; } - are_default_dialog_photo_custom_emoji_ids_being_loaded_[for_user] = true; + are_default_custom_emoji_ids_being_loaded_[index] = true; auto query_promise = - PromiseCreator::lambda([actor_id = actor_id(this), for_user]( + PromiseCreator::lambda([actor_id = actor_id(this), sticker_list_type]( Result> r_emoji_list) mutable { - send_closure(actor_id, &StickersManager::on_get_default_dialog_photo_custom_emoji_ids, for_user, + send_closure(actor_id, &StickersManager::on_get_default_custom_emoji_ids, sticker_list_type, std::move(r_emoji_list)); }); td_->create_handler(std::move(query_promise)) - ->send(for_user, default_dialog_photo_custom_emoji_ids_hash_[for_user]); + ->send(sticker_list_type, default_custom_emoji_ids_hash_[index]); } -void StickersManager::on_get_default_dialog_photo_custom_emoji_ids( - bool for_user, Result> r_emoji_list) { +void StickersManager::on_get_default_custom_emoji_ids( + StickerListType sticker_list_type, Result> r_emoji_list) { G()->ignore_result_if_closing(r_emoji_list); - CHECK(are_default_dialog_photo_custom_emoji_ids_being_loaded_[for_user]); - are_default_dialog_photo_custom_emoji_ids_being_loaded_[for_user] = false; + auto index = static_cast(sticker_list_type); + CHECK(are_default_custom_emoji_ids_being_loaded_[index]); + are_default_custom_emoji_ids_being_loaded_[index] = false; if (r_emoji_list.is_error()) { - fail_promises(default_dialog_photo_custom_emoji_ids_load_queries_[for_user], r_emoji_list.move_as_error()); + fail_promises(default_custom_emoji_ids_load_queries_[index], r_emoji_list.move_as_error()); + fail_promises(default_emoji_statuses_load_queries_[index], r_emoji_list.move_as_error()); return; } auto emoji_list_ptr = r_emoji_list.move_as_ok(); int32 constructor_id = emoji_list_ptr->get_id(); if (constructor_id == telegram_api::emojiListNotModified::ID) { - LOG(INFO) << "Default " << (for_user ? "profile" : "chat") << " photo custom emoji identifiers aren't modified"; - if (!are_default_dialog_photo_custom_emoji_ids_loaded_[for_user]) { - on_get_default_dialog_photo_custom_emoji_ids_success(for_user, {}, 0); + LOG(INFO) << "The " << sticker_list_type << " isn't modified"; + if (!are_default_custom_emoji_ids_loaded_[index]) { + on_get_default_custom_emoji_ids_success(sticker_list_type, {}, 0); + } + auto sticker_promises = std::move(default_custom_emoji_ids_load_queries_[index]); + auto status_promises = std::move(default_emoji_statuses_load_queries_[index]); + reset_to_empty(default_custom_emoji_ids_load_queries_[index]); + reset_to_empty(default_emoji_statuses_load_queries_[index]); + for (auto &promise : sticker_promises) { + CHECK(!promise); } - auto promises = std::move(default_dialog_photo_custom_emoji_ids_load_queries_[for_user]); - reset_to_empty(default_dialog_photo_custom_emoji_ids_load_queries_[for_user]); - for (auto &promise : promises) { + for (auto &promise : status_promises) { CHECK(!promise); } return; @@ -6808,57 +6731,34 @@ void StickersManager::on_get_default_dialog_photo_custom_emoji_ids( if (G()->use_sqlite_pmc()) { CustomEmojiIdsLogEvent log_event(custom_emoji_ids, hash); - G()->td_db()->get_sqlite_pmc()->set(get_default_dialog_photo_custom_emoji_ids_database_key(for_user), + G()->td_db()->get_sqlite_pmc()->set(get_sticker_list_type_database_key(sticker_list_type), log_event_store(log_event).as_slice().str(), Auto()); } - on_get_default_dialog_photo_custom_emoji_ids_success(for_user, std::move(custom_emoji_ids), hash); + on_get_default_custom_emoji_ids_success(sticker_list_type, std::move(custom_emoji_ids), hash); } -void StickersManager::on_get_default_dialog_photo_custom_emoji_ids_success(bool for_user, - vector custom_emoji_ids, - int64 hash) { - LOG(INFO) << "Load " << custom_emoji_ids.size() << " default " << (for_user ? "profile" : "chat") - << " photo custom emoji identifiers"; - default_dialog_photo_custom_emoji_ids_[for_user] = std::move(custom_emoji_ids); - default_dialog_photo_custom_emoji_ids_hash_[for_user] = hash; - are_default_dialog_photo_custom_emoji_ids_loaded_[for_user] = true; +void StickersManager::on_get_default_custom_emoji_ids_success(StickerListType sticker_list_type, + vector custom_emoji_ids, int64 hash) { + auto index = static_cast(sticker_list_type); + LOG(INFO) << "Load " << custom_emoji_ids.size() << ' ' << sticker_list_type; + default_custom_emoji_ids_[index] = std::move(custom_emoji_ids); + default_custom_emoji_ids_hash_[index] = hash; + are_default_custom_emoji_ids_loaded_[index] = true; - auto promises = std::move(default_dialog_photo_custom_emoji_ids_load_queries_[for_user]); - reset_to_empty(default_dialog_photo_custom_emoji_ids_load_queries_[for_user]); - for (auto &promise : promises) { - get_custom_emoji_stickers_unlimited(default_dialog_photo_custom_emoji_ids_[for_user], std::move(promise)); + auto sticker_promises = std::move(default_custom_emoji_ids_load_queries_[index]); + auto status_promises = std::move(default_emoji_statuses_load_queries_[index]); + reset_to_empty(default_custom_emoji_ids_load_queries_[index]); + reset_to_empty(default_emoji_statuses_load_queries_[index]); + for (auto &promise : sticker_promises) { + get_custom_emoji_stickers_unlimited(default_custom_emoji_ids_[index], std::move(promise)); } -} - -void StickersManager::get_premium_gift_option_sticker(int32 month_count, bool is_recursive, - Promise> &&promise) { - TRY_STATUS_PROMISE(promise, G()->close_status()); - - auto &special_sticker_set = add_special_sticker_set(SpecialStickerSetType::premium_gifts()); - auto sticker_set = get_sticker_set(special_sticker_set.id_); - if (sticker_set == nullptr || !sticker_set->was_loaded_) { - if (is_recursive) { - return promise.set_value(nullptr); - } - - pending_get_premium_gift_option_sticker_queries_.push_back(PromiseCreator::lambda( - [actor_id = actor_id(this), month_count, promise = std::move(promise)](Result &&result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - send_closure(actor_id, &StickersManager::get_premium_gift_option_sticker, month_count, true, - std::move(promise)); - } - })); - load_special_sticker_set(special_sticker_set); - return; + for (auto &promise : status_promises) { + promise.set_value(get_emoji_statuses_object(default_custom_emoji_ids_[index])); } - - promise.set_value(get_sticker_object(get_premium_gift_option_sticker_id(sticker_set, month_count))); } -void StickersManager::get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id, +void StickersManager::get_animated_emoji_click_sticker(const string &message_text, MessageFullId message_full_id, Promise> &&promise) { if (disable_animated_emojis_ || td_->auth_manager_->is_bot()) { return promise.set_value(nullptr); @@ -6874,16 +6774,16 @@ void StickersManager::get_animated_emoji_click_sticker(const string &message_tex auto sticker_set = get_sticker_set(special_sticker_set.id_); CHECK(sticker_set != nullptr); if (sticker_set->was_loaded_) { - return choose_animated_emoji_click_sticker(sticker_set, message_text, full_message_id, Time::now(), + return choose_animated_emoji_click_sticker(sticker_set, message_text, message_full_id, Time::now(), std::move(promise)); } - LOG(INFO) << "Waiting for an emoji click sticker set needed in " << full_message_id; + LOG(INFO) << "Waiting for an emoji click sticker set needed in " << message_full_id; load_special_sticker_set(special_sticker_set); PendingGetAnimatedEmojiClickSticker pending_request; pending_request.message_text_ = message_text; - pending_request.full_message_id_ = full_message_id; + pending_request.message_full_id_ = message_full_id; pending_request.start_time_ = Time::now(); pending_request.promise_ = std::move(promise); pending_get_animated_emoji_click_stickers_.push_back(std::move(pending_request)); @@ -6917,7 +6817,7 @@ vector StickersManager::get_animated_emoji_click_stickers(const StickerS } void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *sticker_set, string message_text, - FullMessageId full_message_id, double start_time, + MessageFullId message_full_id, double start_time, Promise> &&promise) { CHECK(sticker_set->was_loaded_); remove_emoji_modifiers_in_place(message_text); @@ -6930,7 +6830,7 @@ void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *stic } auto now = Time::now(); - if (last_clicked_animated_emoji_ == message_text && last_clicked_animated_emoji_full_message_id_ == full_message_id && + if (last_clicked_animated_emoji_ == message_text && last_clicked_animated_emoji_message_full_id_ == message_full_id && next_click_animated_emoji_message_time_ >= now + 2 * MIN_ANIMATED_EMOJI_CLICK_DELAY) { return promise.set_value(nullptr); } @@ -6949,13 +6849,13 @@ void StickersManager::choose_animated_emoji_click_sticker(const StickerSet *stic } } if (found_stickers.empty()) { - LOG(INFO) << "There is no click effect for " << message_text << " from " << full_message_id; + LOG(INFO) << "There is no click effect for " << message_text << " from " << message_full_id; return promise.set_value(nullptr); } - if (last_clicked_animated_emoji_full_message_id_ != full_message_id) { + if (last_clicked_animated_emoji_message_full_id_ != message_full_id) { flush_pending_animated_emoji_clicks(); - last_clicked_animated_emoji_full_message_id_ = full_message_id; + last_clicked_animated_emoji_message_full_id_ = message_full_id; } if (last_clicked_animated_emoji_ != message_text) { pending_animated_emoji_clicks_.clear(); @@ -7014,17 +6914,17 @@ void StickersManager::flush_pending_animated_emoji_clicks() { } auto clicks = std::move(pending_animated_emoji_clicks_); pending_animated_emoji_clicks_.clear(); - auto full_message_id = last_clicked_animated_emoji_full_message_id_; - last_clicked_animated_emoji_full_message_id_ = FullMessageId(); + auto message_full_id = last_clicked_animated_emoji_message_full_id_; + last_clicked_animated_emoji_message_full_id_ = MessageFullId(); auto emoji = std::move(last_clicked_animated_emoji_); last_clicked_animated_emoji_.clear(); - if (td_->messages_manager_->is_message_edited_recently(full_message_id, 1)) { - // includes deleted full_message_id + if (td_->messages_manager_->is_message_edited_recently(message_full_id, 1)) { + // includes deleted message_full_id return; } - auto dialog_id = full_message_id.get_dialog_id(); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto dialog_id = message_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { return; } @@ -7044,7 +6944,7 @@ void StickersManager::flush_pending_animated_emoji_clicks() { td_->create_handler()->send( dialog_id, std::move(input_peer), make_tl_object( - emoji, full_message_id.get_message_id().get_server_message_id().get(), + emoji, message_full_id.get_message_id().get_server_message_id().get(), make_tl_object(data))); on_send_animated_emoji_clicks(dialog_id, emoji); @@ -7088,7 +6988,7 @@ bool StickersManager::is_sent_animated_emoji_click(DialogId dialog_id, const str return false; } -Status StickersManager::on_animated_emoji_message_clicked(string &&emoji, FullMessageId full_message_id, string data) { +Status StickersManager::on_animated_emoji_message_clicked(string &&emoji, MessageFullId message_full_id, string data) { if (td_->auth_manager_->is_bot() || disable_animated_emojis_) { return Status::OK(); } @@ -7098,11 +6998,11 @@ Status StickersManager::on_animated_emoji_message_clicked(string &&emoji, FullMe return Status::Error("Expected an object"); } auto &object = value.get_object(); - TRY_RESULT(version, get_json_object_int_field(object, "v", false)); + TRY_RESULT(version, object.get_required_int_field("v")); if (version != 1) { return Status::OK(); } - TRY_RESULT(array_value, get_json_object_field(object, "a", JsonValue::Type::Array, false)); + TRY_RESULT(array_value, object.extract_required_field("a", JsonValue::Type::Array)); auto &array = array_value.get_array(); if (array.size() > 20) { return Status::Error("Click array is too big"); @@ -7115,11 +7015,11 @@ Status StickersManager::on_animated_emoji_message_clicked(string &&emoji, FullMe return Status::Error("Expected clicks as JSON objects"); } auto &click_object = click.get_object(); - TRY_RESULT(index, get_json_object_int_field(click_object, "i", false)); + TRY_RESULT(index, click_object.get_required_int_field("i")); if (index <= 0 || index > 9) { return Status::Error("Wrong index"); } - TRY_RESULT(start_time, get_json_object_double_field(click_object, "t", false)); + TRY_RESULT(start_time, click_object.get_required_double_field("t")); if (!std::isfinite(start_time)) { return Status::Error("Receive invalid start time"); } @@ -7142,34 +7042,34 @@ Status StickersManager::on_animated_emoji_message_clicked(string &&emoji, FullMe auto sticker_set = get_sticker_set(special_sticker_set.id_); CHECK(sticker_set != nullptr); if (sticker_set->was_loaded_) { - schedule_update_animated_emoji_clicked(sticker_set, emoji, full_message_id, std::move(clicks)); + schedule_update_animated_emoji_clicked(sticker_set, emoji, message_full_id, std::move(clicks)); return Status::OK(); } } - LOG(INFO) << "Waiting for an emoji click sticker set needed in " << full_message_id; + LOG(INFO) << "Waiting for an emoji click sticker set needed in " << message_full_id; load_special_sticker_set(special_sticker_set); PendingOnAnimatedEmojiClicked pending_request; pending_request.emoji_ = std::move(emoji); - pending_request.full_message_id_ = full_message_id; + pending_request.message_full_id_ = message_full_id; pending_request.clicks_ = std::move(clicks); pending_on_animated_emoji_message_clicked_.push_back(std::move(pending_request)); return Status::OK(); } void StickersManager::schedule_update_animated_emoji_clicked(const StickerSet *sticker_set, Slice emoji, - FullMessageId full_message_id, + MessageFullId message_full_id, vector> clicks) { if (clicks.empty()) { return; } - if (td_->messages_manager_->is_message_edited_recently(full_message_id, 2)) { - // includes deleted full_message_id + if (td_->messages_manager_->is_message_edited_recently(message_full_id, 2)) { + // includes deleted message_full_id return; } - auto dialog_id = full_message_id.get_dialog_id(); - if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Write)) { + auto dialog_id = message_full_id.get_dialog_id(); + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Write)) { return; } @@ -7201,40 +7101,31 @@ void StickersManager::schedule_update_animated_emoji_clicked(const StickerSet *s } create_actor( "SendUpdateAnimatedEmojiClicked", start_time + click.second - now, - PromiseCreator::lambda([actor_id = actor_id(this), full_message_id, sticker_id](Result result) { - send_closure(actor_id, &StickersManager::send_update_animated_emoji_clicked, full_message_id, sticker_id); + PromiseCreator::lambda([actor_id = actor_id(this), message_full_id, sticker_id](Result result) { + send_closure(actor_id, &StickersManager::send_update_animated_emoji_clicked, message_full_id, sticker_id); })) .release(); } next_update_animated_emoji_clicked_time_ = start_time + clicks.back().second + MIN_ANIMATED_EMOJI_CLICK_DELAY; } -void StickersManager::send_update_animated_emoji_clicked(FullMessageId full_message_id, FileId sticker_id) { +void StickersManager::send_update_animated_emoji_clicked(MessageFullId message_full_id, FileId sticker_id) { if (G()->close_flag() || disable_animated_emojis_ || td_->auth_manager_->is_bot()) { return; } - if (td_->messages_manager_->is_message_edited_recently(full_message_id, 2)) { - // includes deleted full_message_id + if (td_->messages_manager_->is_message_edited_recently(message_full_id, 2)) { + // includes deleted message_full_id return; } - auto dialog_id = full_message_id.get_dialog_id(); - if (!td_->messages_manager_->have_input_peer(dialog_id, AccessRights::Write)) { + auto dialog_id = message_full_id.get_dialog_id(); + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Write)) { return; } send_closure(G()->td(), &Td::send_update, td_api::make_object( - td_->messages_manager_->get_chat_id_object(dialog_id, "updateAnimatedEmojiMessageClicked"), - full_message_id.get_message_id().get(), get_sticker_object(sticker_id, false, true))); -} - -bool StickersManager::is_active_reaction(const string &reaction) const { - for (auto &supported_reaction : reactions_.reactions_) { - if (supported_reaction.reaction_ == reaction) { - return supported_reaction.is_active_; - } - } - return false; + td_->dialog_manager_->get_chat_id_object(dialog_id, "updateAnimatedEmojiMessageClicked"), + message_full_id.get_message_id().get(), get_sticker_object(sticker_id, false, true))); } void StickersManager::view_featured_sticker_sets(const vector &sticker_set_ids) { @@ -7817,20 +7708,20 @@ void StickersManager::send_get_attached_stickers_query(FileId file_id, Promiseis_document() && !full_remote_location->is_photo()) || + full_remote_location->is_web()) { return promise.set_value(Unit()); } tl_object_ptr input_stickered_media; string file_reference; - if (file_view.main_remote_location().is_photo()) { - auto input_photo = file_view.main_remote_location().as_input_photo(); + if (full_remote_location->is_photo()) { + auto input_photo = full_remote_location->as_input_photo(); file_reference = input_photo->file_reference_.as_slice().str(); input_stickered_media = make_tl_object(std::move(input_photo)); } else { - auto input_document = file_view.main_remote_location().as_input_document(); + auto input_document = full_remote_location->as_input_document(); file_reference = input_document->file_reference_.as_slice().str(); input_stickered_media = make_tl_object(std::move(input_document)); } @@ -7936,16 +7827,13 @@ int StickersManager::move_installed_sticker_set_to_top(StickerType sticker_type, } vector ¤t_sticker_set_ids = installed_sticker_set_ids_[type]; - auto it = std::find(current_sticker_set_ids.begin(), current_sticker_set_ids.end(), sticker_set_id); - if (it == current_sticker_set_ids.end()) { - return -1; - } - if (sticker_set_id == current_sticker_set_ids[0]) { - CHECK(it == current_sticker_set_ids.begin()); + if (!current_sticker_set_ids.empty() && sticker_set_id == current_sticker_set_ids[0]) { return 0; } - - std::rotate(current_sticker_set_ids.begin(), it, it + 1); + if (!td::contains(current_sticker_set_ids, sticker_set_id)) { + return -1; + } + add_to_top(current_sticker_set_ids, current_sticker_set_ids.size(), sticker_set_id); need_update_installed_sticker_sets_[type] = true; return 1; @@ -8019,7 +7907,6 @@ void StickersManager::move_sticker_set_to_top_by_custom_emoji_ids(const vector> StickersManager::prepare_input_sticker(td_api::inputSticker *sticker, - StickerFormat sticker_format, StickerType sticker_type) { if (sticker == nullptr) { return Status::Error(400, "Input sticker must be non-empty"); @@ -8040,7 +7927,7 @@ Result> StickersManager::prepare_input_sticker(td } } - return prepare_input_file(sticker->sticker_, sticker_format, sticker_type, false); + return prepare_input_file(sticker->sticker_, ::td::get_sticker_format(sticker->format_), sticker_type, false); } Result> StickersManager::prepare_input_file( @@ -8071,18 +7958,19 @@ Result> StickersManager::prepare_input_file( return Status::Error(400, "Can't use encrypted file"); } - if (file_view.has_remote_location() && file_view.main_remote_location().is_web()) { + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr && main_remote_location->is_web()) { return Status::Error(400, "Can't use web file to create a sticker"); } bool is_url = false; bool is_local = false; - if (file_view.has_remote_location()) { - CHECK(file_view.main_remote_location().is_document()); + if (main_remote_location != nullptr) { + CHECK(main_remote_location->is_document()); } else { if (file_view.has_url()) { is_url = true; } else { - if (file_view.has_local_location() && + if (file_view.has_full_local_location() && file_view.expected_size() > get_max_sticker_file_size(sticker_format, sticker_type, for_thumbnail)) { return Status::Error(400, "File is too big"); } @@ -8100,47 +7988,51 @@ Result> StickersManager::prepare_input_file( return std::make_tuple(file_id, is_url, is_local); } -FileId StickersManager::upload_sticker_file(UserId user_id, StickerFormat sticker_format, - const td_api::object_ptr &input_file, - Promise &&promise) { +void StickersManager::upload_sticker_file(UserId user_id, StickerFormat sticker_format, + const td_api::object_ptr &input_file, + Promise> &&promise) { bool is_bot = td_->auth_manager_->is_bot(); if (!is_bot) { - user_id = td_->contacts_manager_->get_my_id(); + user_id = td_->user_manager_->get_my_id(); } - auto r_input_user = td_->contacts_manager_->get_input_user(user_id); - if (r_input_user.is_error()) { - promise.set_error(r_input_user.move_as_error()); - return FileId(); - } + TRY_STATUS_PROMISE(promise, td_->user_manager_->get_input_user(user_id)); // StickerType::Regular has less restrictions - auto r_file_id = prepare_input_file(input_file, sticker_format, StickerType::Regular, false); - if (r_file_id.is_error()) { - promise.set_error(r_file_id.move_as_error()); - return FileId(); - } - auto file_id = std::get<0>(r_file_id.ok()); - auto is_url = std::get<1>(r_file_id.ok()); - auto is_local = std::get<2>(r_file_id.ok()); + TRY_RESULT_PROMISE(promise, file_info, prepare_input_file(input_file, sticker_format, StickerType::Regular, false)); + auto file_id = std::get<0>(file_info); + auto is_url = std::get<1>(file_info); + auto is_local = std::get<2>(file_info); + + auto upload_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), file_id, promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &StickersManager::finish_upload_sticker_file, file_id, std::move(promise)); + }); if (is_url) { - do_upload_sticker_file(user_id, file_id, nullptr, std::move(promise)); + do_upload_sticker_file(user_id, file_id, nullptr, std::move(upload_promise)); } else if (is_local) { - upload_sticker_file(user_id, file_id, std::move(promise)); + upload_sticker_file(user_id, file_id, std::move(upload_promise)); } else { - promise.set_value(Unit()); + upload_promise.set_value(Unit()); } +} - return file_id; +void StickersManager::finish_upload_sticker_file(FileId file_id, Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + promise.set_value(td_->file_manager_->get_file_object(file_id)); } -tl_object_ptr StickersManager::get_input_sticker(const td_api::inputSticker *sticker, - FileId file_id) const { +telegram_api::object_ptr StickersManager::get_input_sticker( + const td_api::inputSticker *sticker, FileId file_id) const { CHECK(sticker != nullptr); FileView file_view = td_->file_manager_->get_file_view(file_id); - CHECK(file_view.has_remote_location()); - auto input_document = file_view.main_remote_location().as_input_document(); + const auto *main_remote_location = file_view.get_main_remote_location(); + CHECK(main_remote_location != nullptr); + auto input_document = main_remote_location->as_input_document(); int32 flags = 0; @@ -8205,18 +8097,17 @@ td_api::object_ptr StickersManager::get_check } } -void StickersManager::create_new_sticker_set(UserId user_id, string title, string short_name, - StickerFormat sticker_format, StickerType sticker_type, +void StickersManager::create_new_sticker_set(UserId user_id, string title, string short_name, StickerType sticker_type, bool has_text_color, vector> &&stickers, string software, Promise> &&promise) { bool is_bot = td_->auth_manager_->is_bot(); if (!is_bot) { - user_id = td_->contacts_manager_->get_my_id(); + user_id = td_->user_manager_->get_my_id(); } - TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(user_id)); + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(user_id)); title = strip_empty_characters(title, MAX_STICKER_SET_TITLE_LENGTH); if (title.empty()) { @@ -8224,7 +8115,7 @@ void StickersManager::create_new_sticker_set(UserId user_id, string title, strin } short_name = strip_empty_characters(short_name, MAX_STICKER_SET_SHORT_NAME_LENGTH); - if (short_name.empty()) { + if (short_name.empty() && is_bot) { return promise.set_error(Status::Error(400, "Sticker set name must be non-empty")); } @@ -8241,13 +8132,10 @@ void StickersManager::create_new_sticker_set(UserId user_id, string title, strin vector local_file_ids; vector url_file_ids; for (auto &sticker : stickers) { - auto r_file_id = prepare_input_sticker(sticker.get(), sticker_format, sticker_type); - if (r_file_id.is_error()) { - return promise.set_error(r_file_id.move_as_error()); - } - auto file_id = std::get<0>(r_file_id.ok()); - auto is_url = std::get<1>(r_file_id.ok()); - auto is_local = std::get<2>(r_file_id.ok()); + TRY_RESULT_PROMISE(promise, file_info, prepare_input_sticker(sticker.get(), sticker_type)); + auto file_id = std::get<0>(file_info); + auto is_url = std::get<1>(file_info); + auto is_local = std::get<2>(file_info); file_ids.push_back(file_id); if (is_url) { @@ -8261,7 +8149,6 @@ void StickersManager::create_new_sticker_set(UserId user_id, string title, strin pending_new_sticker_set->user_id_ = user_id; pending_new_sticker_set->title_ = std::move(title); pending_new_sticker_set->short_name_ = short_name; - pending_new_sticker_set->sticker_format_ = sticker_format; pending_new_sticker_set->sticker_type_ = sticker_type; pending_new_sticker_set->has_text_color_ = has_text_color; pending_new_sticker_set->file_ids_ = std::move(file_ids); @@ -8310,7 +8197,8 @@ void StickersManager::upload_sticker_file(UserId user_id, FileId file_id, Promis td_->file_manager_->upload(upload_file_id, upload_sticker_file_callback_, 2, 0); } -void StickersManager::on_upload_sticker_file(FileId file_id, tl_object_ptr input_file) { +void StickersManager::on_upload_sticker_file(FileId file_id, + telegram_api::object_ptr input_file) { LOG(INFO) << "Sticker file " << file_id << " has been uploaded"; auto it = being_uploaded_files_.find(file_id); @@ -8340,8 +8228,6 @@ void StickersManager::on_upload_sticker_file_error(FileId file_id, Status status being_uploaded_files_.erase(it); - // TODO FILE_PART_X_MISSING support - promise.set_error(Status::Error(status.code() > 0 ? status.code() : 500, status.message())); // TODO CHECK that status has always a code } @@ -8352,7 +8238,7 @@ void StickersManager::do_upload_sticker_file(UserId user_id, FileId file_id, TRY_STATUS_PROMISE(promise, G()->close_status()); DialogId dialog_id(user_id); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Write); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Write); if (input_peer == nullptr) { if (input_file != nullptr) { td_->file_manager_->cancel_upload(file_id); @@ -8407,8 +8293,9 @@ void StickersManager::on_uploaded_sticker_file(FileId file_id, bool is_url, // uploaded by a URL WEBP sticker // re-register as document FileView sticker_file_view = td_->file_manager_->get_file_view(parsed_document.file_id); - CHECK(sticker_file_view.has_remote_location()); - auto remote_location = sticker_file_view.main_remote_location(); + const auto *full_remote_location = sticker_file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + auto remote_location = *full_remote_location; CHECK(remote_location.is_common()); remote_location.file_type_ = FileType::Document; auto document_file_id = @@ -8453,9 +8340,8 @@ void StickersManager::on_new_stickers_uploaded(int64 random_id, Result res CHECK(pending_new_sticker_set->upload_files_multipromise_.promise_count() == 0); auto &promise = pending_new_sticker_set->promise_; - TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(pending_new_sticker_set->user_id_)); + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(pending_new_sticker_set->user_id_)); - StickerFormat sticker_format = pending_new_sticker_set->sticker_format_; StickerType sticker_type = pending_new_sticker_set->sticker_type_; auto sticker_count = pending_new_sticker_set->stickers_.size(); @@ -8468,13 +8354,31 @@ void StickersManager::on_new_stickers_uploaded(int64 random_id, Result res td_->create_handler(std::move(promise)) ->send(std::move(input_user), pending_new_sticker_set->title_, pending_new_sticker_set->short_name_, sticker_type, - pending_new_sticker_set->has_text_color_, sticker_format, std::move(input_stickers), - pending_new_sticker_set->software_); + pending_new_sticker_set->has_text_color_, std::move(input_stickers), pending_new_sticker_set->software_); +} + +StickerFormat StickersManager::guess_sticker_set_format(const StickerSet *sticker_set) const { + auto format = StickerFormat::Unknown; + for (auto sticker_id : sticker_set->sticker_ids_) { + const auto *s = get_sticker(sticker_id); + if (format == StickerFormat::Unknown) { + format = s->format_; + } else if (format != s->format_) { + return StickerFormat::Unknown; + } + } + return format; } void StickersManager::add_sticker_to_set(UserId user_id, string short_name, - td_api::object_ptr &&sticker, Promise &&promise) { - TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(user_id)); + td_api::object_ptr &&sticker, + td_api::object_ptr &&old_sticker, Promise &&promise) { + bool is_bot = td_->auth_manager_->is_bot(); + if (!is_bot) { + user_id = td_->user_manager_->get_my_id(); + } + + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(user_id)); short_name = clean_username(strip_empty_characters(short_name, MAX_STICKER_SET_SHORT_NAME_LENGTH)); if (short_name.empty()) { @@ -8483,25 +8387,27 @@ void StickersManager::add_sticker_to_set(UserId user_id, string short_name, const StickerSet *sticker_set = get_sticker_set(short_name_to_sticker_set_id_.get(short_name)); if (sticker_set != nullptr && sticker_set->was_loaded_) { - return do_add_sticker_to_set(user_id, short_name, std::move(sticker), std::move(promise)); + return do_add_sticker_to_set(user_id, short_name, std::move(sticker), std::move(old_sticker), std::move(promise)); } - do_reload_sticker_set( - StickerSetId(), make_tl_object(short_name), 0, - PromiseCreator::lambda([actor_id = actor_id(this), user_id, short_name, sticker = std::move(sticker), - promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - send_closure(actor_id, &StickersManager::do_add_sticker_to_set, user_id, std::move(short_name), - std::move(sticker), std::move(promise)); - } - }), - "add_sticker_to_set"); + do_reload_sticker_set(StickerSetId(), make_tl_object(short_name), 0, + PromiseCreator::lambda([actor_id = actor_id(this), user_id, short_name, + sticker = std::move(sticker), old_sticker = std::move(old_sticker), + promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &StickersManager::do_add_sticker_to_set, user_id, + std::move(short_name), std::move(sticker), std::move(old_sticker), + std::move(promise)); + } + }), + "add_sticker_to_set"); } void StickersManager::do_add_sticker_to_set(UserId user_id, string short_name, td_api::object_ptr &&sticker, + td_api::object_ptr &&old_sticker, Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); @@ -8509,19 +8415,31 @@ void StickersManager::do_add_sticker_to_set(UserId user_id, string short_name, if (sticker_set == nullptr || !sticker_set->was_loaded_) { return promise.set_error(Status::Error(400, "Sticker set not found")); } + telegram_api::object_ptr input_document; + if (old_sticker != nullptr) { + TRY_RESULT_PROMISE(promise, sticker_input_document, get_sticker_input_document(old_sticker)); + if (sticker_input_document.sticker_set_short_name_ != short_name) { + return promise.set_error(Status::Error(400, "The old sticker isn't from the set")); + } + input_document = std::move(sticker_input_document.input_document_); + } - auto r_file_id = prepare_input_sticker(sticker.get(), sticker_set->sticker_format_, sticker_set->sticker_type_); - if (r_file_id.is_error()) { - return promise.set_error(r_file_id.move_as_error()); + if (sticker != nullptr && sticker->format_ == nullptr) { + auto format = guess_sticker_set_format(sticker_set); + if (format != StickerFormat::Unknown) { + sticker->format_ = get_sticker_format_object(format); + } } - auto file_id = std::get<0>(r_file_id.ok()); - auto is_url = std::get<1>(r_file_id.ok()); - auto is_local = std::get<2>(r_file_id.ok()); + TRY_RESULT_PROMISE(promise, file_info, prepare_input_sticker(sticker.get(), sticker_set->sticker_type_)); + auto file_id = std::get<0>(file_info); + auto is_url = std::get<1>(file_info); + auto is_local = std::get<2>(file_info); auto pending_add_sticker_to_set = make_unique(); pending_add_sticker_to_set->short_name_ = short_name; pending_add_sticker_to_set->file_id_ = file_id; pending_add_sticker_to_set->sticker_ = std::move(sticker); + pending_add_sticker_to_set->input_document_ = std::move(input_document); pending_add_sticker_to_set->promise_ = std::move(promise); int64 random_id; @@ -8561,12 +8479,19 @@ void StickersManager::on_added_sticker_uploaded(int64 random_id, Result re td_->create_handler(std::move(pending_add_sticker_to_set->promise_)) ->send(pending_add_sticker_to_set->short_name_, - get_input_sticker(pending_add_sticker_to_set->sticker_.get(), pending_add_sticker_to_set->file_id_)); + get_input_sticker(pending_add_sticker_to_set->sticker_.get(), pending_add_sticker_to_set->file_id_), + std::move(pending_add_sticker_to_set->input_document_)); } void StickersManager::set_sticker_set_thumbnail(UserId user_id, string short_name, - tl_object_ptr &&thumbnail, Promise &&promise) { - TRY_RESULT_PROMISE(promise, input_user, td_->contacts_manager_->get_input_user(user_id)); + td_api::object_ptr &&thumbnail, StickerFormat format, + Promise &&promise) { + bool is_bot = td_->auth_manager_->is_bot(); + if (!is_bot) { + user_id = td_->user_manager_->get_my_id(); + } + + TRY_RESULT_PROMISE(promise, input_user, td_->user_manager_->get_input_user(user_id)); short_name = clean_username(strip_empty_characters(short_name, MAX_STICKER_SET_SHORT_NAME_LENGTH)); if (short_name.empty()) { @@ -8575,26 +8500,26 @@ void StickersManager::set_sticker_set_thumbnail(UserId user_id, string short_nam const StickerSet *sticker_set = get_sticker_set(short_name_to_sticker_set_id_.get(short_name)); if (sticker_set != nullptr && sticker_set->was_loaded_) { - return do_set_sticker_set_thumbnail(user_id, short_name, std::move(thumbnail), std::move(promise)); + return do_set_sticker_set_thumbnail(user_id, short_name, std::move(thumbnail), format, std::move(promise)); } do_reload_sticker_set( StickerSetId(), make_tl_object(short_name), 0, - PromiseCreator::lambda([actor_id = actor_id(this), user_id, short_name, thumbnail = std::move(thumbnail), + PromiseCreator::lambda([actor_id = actor_id(this), user_id, short_name, thumbnail = std::move(thumbnail), format, promise = std::move(promise)](Result result) mutable { if (result.is_error()) { promise.set_error(result.move_as_error()); } else { send_closure(actor_id, &StickersManager::do_set_sticker_set_thumbnail, user_id, std::move(short_name), - std::move(thumbnail), std::move(promise)); + std::move(thumbnail), format, std::move(promise)); } }), "set_sticker_set_thumbnail"); } void StickersManager::do_set_sticker_set_thumbnail(UserId user_id, string short_name, - tl_object_ptr &&thumbnail, - Promise &&promise) { + td_api::object_ptr &&thumbnail, + StickerFormat format, Promise &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); const StickerSet *sticker_set = get_sticker_set(short_name_to_sticker_set_id_.get(short_name)); @@ -8605,14 +8530,14 @@ void StickersManager::do_set_sticker_set_thumbnail(UserId user_id, string short_ return promise.set_error( Status::Error(400, "The method can't be used to set thumbnail of custom emoji sticker sets")); } - - auto r_file_id = prepare_input_file(thumbnail, sticker_set->sticker_format_, sticker_set->sticker_type_, true); - if (r_file_id.is_error()) { - return promise.set_error(r_file_id.move_as_error()); + if (format == StickerFormat::Unknown) { + format = guess_sticker_set_format(sticker_set); } - auto file_id = std::get<0>(r_file_id.ok()); - auto is_url = std::get<1>(r_file_id.ok()); - auto is_local = std::get<2>(r_file_id.ok()); + + TRY_RESULT_PROMISE(promise, file_info, prepare_input_file(thumbnail, format, sticker_set->sticker_type_, true)); + auto file_id = std::get<0>(file_info); + auto is_url = std::get<1>(file_info); + auto is_local = std::get<2>(file_info); if (!file_id.is_valid()) { td_->create_handler(std::move(promise)) @@ -8662,10 +8587,11 @@ void StickersManager::on_sticker_set_thumbnail_uploaded(int64 random_id, Result< } FileView file_view = td_->file_manager_->get_file_view(pending_set_sticker_set_thumbnail->file_id_); - CHECK(file_view.has_remote_location()); + const auto *main_remote_location = file_view.get_main_remote_location(); + CHECK(main_remote_location != nullptr); td_->create_handler(std::move(pending_set_sticker_set_thumbnail->promise_)) - ->send(pending_set_sticker_set_thumbnail->short_name_, file_view.main_remote_location().as_input_document()); + ->send(pending_set_sticker_set_thumbnail->short_name_, main_remote_location->as_input_document()); } void StickersManager::set_custom_emoji_sticker_set_thumbnail(string short_name, CustomEmojiId custom_emoji_id, @@ -8737,8 +8663,8 @@ Result StickersManager::get_sticker_input TRY_RESULT(file_id, td_->file_manager_->get_input_file_id(FileType::Sticker, sticker, DialogId(), false, false)); auto file_view = td_->file_manager_->get_file_view(file_id); - if (!file_view.has_remote_location() || !file_view.main_remote_location().is_document() || - file_view.main_remote_location().is_web()) { + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location == nullptr || !main_remote_location->is_document() || main_remote_location->is_web()) { return Status::Error(400, "Wrong sticker file specified"); } @@ -8752,7 +8678,7 @@ Result StickersManager::get_sticker_input result.sticker_set_short_name_ = to_string(s->set_id_.get()); } } - result.input_document_ = file_view.main_remote_location().as_input_document(); + result.input_document_ = main_remote_location->as_input_document(); return std::move(result); } @@ -8810,6 +8736,52 @@ void StickersManager::set_sticker_mask_position(const td_api::object_ptr> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), promise = std::move(promise)]( + Result> r_my_stickers) mutable { + send_closure(actor_id, &StickersManager::on_get_created_sticker_sets, std::move(r_my_stickers), + std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(offset_sticker_set_id, limit); +} + +void StickersManager::on_get_created_sticker_sets( + Result> r_my_stickers, + Promise> &&promise) { + G()->ignore_result_if_closing(r_my_stickers); + if (r_my_stickers.is_error()) { + return promise.set_error(r_my_stickers.move_as_error()); + } + auto my_stickers = r_my_stickers.move_as_ok(); + auto total_count = my_stickers->count_; + vector sticker_set_ids; + for (auto &sticker_set_covered : my_stickers->sets_) { + auto sticker_set_id = + on_get_sticker_set_covered(std::move(sticker_set_covered), false, "on_get_created_sticker_sets"); + if (sticker_set_id.is_valid()) { + auto sticker_set = get_sticker_set(sticker_set_id); + CHECK(sticker_set != nullptr); + update_sticker_set(sticker_set, "on_get_created_sticker_sets"); + + if (!td::contains(sticker_set_ids, sticker_set_id) && sticker_set->is_created_) { + sticker_set_ids.push_back(sticker_set_id); + } + } + } + if (static_cast(sticker_set_ids.size()) > total_count) { + LOG(ERROR) << "Expected total of " << total_count << " owned sticker sets, but " << sticker_set_ids.size() + << " received"; + total_count = static_cast(sticker_set_ids.size()); + } + send_update_installed_sticker_sets(); + promise.set_value(get_sticker_sets_object(total_count, sticker_set_ids, 1)); +} + vector StickersManager::get_attached_sticker_file_ids(const vector &int_file_ids) { vector result; @@ -8828,15 +8800,13 @@ vector StickersManager::get_attached_sticker_file_ids(const vectorfile_manager_->get_file_view(file_id); CHECK(!file_view.empty()); - if (!file_view.has_remote_location()) { - LOG(ERROR) << "Sticker " << file_id << " has no remote location"; - continue; - } - if (file_view.remote_location().is_web()) { + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + if (full_remote_location->is_web()) { LOG(ERROR) << "Sticker " << file_id << " is web"; continue; } - if (!file_view.remote_location().is_document()) { + if (!full_remote_location->is_document()) { LOG(ERROR) << "Sticker " << file_id << " is encrypted"; continue; } @@ -9100,7 +9070,8 @@ void StickersManager::on_get_recent_stickers(bool is_repair, bool is_attached, vector recent_sticker_ids; recent_sticker_ids.reserve(stickers->stickers_.size()); for (auto &document_ptr : stickers->stickers_) { - auto sticker_id = on_get_sticker_document(std::move(document_ptr), StickerFormat::Unknown).second; + auto sticker_id = + on_get_sticker_document(std::move(document_ptr), StickerFormat::Unknown, "on_get_recent_stickers").second; if (!sticker_id.is_valid()) { continue; } @@ -9132,13 +9103,13 @@ int64 StickersManager::get_recent_stickers_hash(const vector &sticker_id auto sticker = get_sticker(sticker_id); LOG_CHECK(sticker != nullptr) << sticker_id << ' ' << stickers_.calc_size() << ' ' << source; auto file_view = td_->file_manager_->get_file_view(sticker_id); - CHECK(file_view.has_remote_location()); - if (!file_view.remote_location().is_document()) { - LOG(ERROR) << "Recent sticker remote location is not document: " << file_view.remote_location() << " from " - << source; + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + if (!full_remote_location->is_document()) { + LOG(ERROR) << "Recent sticker remote location is not document: " << *full_remote_location << " from " << source; continue; } - numbers.push_back(file_view.remote_location().get_id()); + numbers.push_back(full_remote_location->get_id()); } return get_vector_hash(numbers); } @@ -9170,11 +9141,12 @@ void StickersManager::send_save_recent_sticker_query(bool is_attached, FileId st // TODO invokeAfter and log event auto file_view = td_->file_manager_->get_file_view(sticker_id); - CHECK(file_view.has_remote_location()); - CHECK(file_view.remote_location().is_document()); - CHECK(!file_view.remote_location().is_web()); + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + CHECK(full_remote_location->is_document()); + CHECK(!full_remote_location->is_web()); td_->create_handler(std::move(promise)) - ->send(is_attached, sticker_id, file_view.remote_location().as_input_document(), unsave); + ->send(is_attached, sticker_id, full_remote_location->as_input_document(), unsave); } void StickersManager::add_recent_sticker_by_id(bool is_attached, FileId sticker_id) { @@ -9218,34 +9190,28 @@ void StickersManager::add_recent_sticker_impl(bool is_attached, FileId sticker_i if (sticker == nullptr) { return promise.set_error(Status::Error(400, "Sticker not found")); } - if (!sticker->set_id_.is_valid()) { - return promise.set_error(Status::Error(400, "Stickers without sticker set can't be added to recent")); + if (!sticker->set_id_.is_valid() && + (!add_on_server || (sticker->format_ != StickerFormat::Webp && sticker->format_ != StickerFormat::Webm))) { + return promise.set_error(Status::Error(400, "The sticker must be from a sticker set")); } if (sticker->type_ == StickerType::CustomEmoji) { return promise.set_error(Status::Error(400, "Custom emoji stickers can't be added to recent")); } auto file_view = td_->file_manager_->get_file_view(sticker_id); - if (!file_view.has_remote_location()) { + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location == nullptr) { return promise.set_error(Status::Error(400, "Can save only sent stickers")); } - if (file_view.remote_location().is_web()) { + if (full_remote_location->is_web()) { return promise.set_error(Status::Error(400, "Can't save web stickers")); } - if (!file_view.remote_location().is_document()) { + if (!full_remote_location->is_document()) { return promise.set_error(Status::Error(400, "Can't save encrypted stickers")); } - auto it = std::find_if(sticker_ids.begin(), sticker_ids.end(), is_equal); - if (it == sticker_ids.end()) { - if (static_cast(sticker_ids.size()) == recent_stickers_limit_) { - sticker_ids.back() = sticker_id; - } else { - sticker_ids.push_back(sticker_id); - } - it = sticker_ids.end() - 1; - } - std::rotate(sticker_ids.begin(), it, it + 1); + add_to_top_if(sticker_ids, static_cast(recent_stickers_limit_), sticker_id, is_equal); + if (sticker_ids[0].get_remote() == 0 && sticker_id.get_remote() != 0) { sticker_ids[0] = sticker_id; } @@ -9501,7 +9467,8 @@ void StickersManager::on_get_favorite_stickers( vector favorite_sticker_ids; favorite_sticker_ids.reserve(favorite_stickers->stickers_.size()); for (auto &document_ptr : favorite_stickers->stickers_) { - auto sticker_id = on_get_sticker_document(std::move(document_ptr), StickerFormat::Unknown).second; + auto sticker_id = + on_get_sticker_document(std::move(document_ptr), StickerFormat::Unknown, "on_get_favorite_stickers").second; if (!sticker_id.is_valid()) { continue; } @@ -9562,11 +9529,12 @@ void StickersManager::send_fave_sticker_query(FileId sticker_id, bool unsave, Pr // TODO invokeAfter and log event auto file_view = td_->file_manager_->get_file_view(sticker_id); - CHECK(file_view.has_remote_location()); - CHECK(file_view.remote_location().is_document()); - CHECK(!file_view.remote_location().is_web()); + const auto *full_remote_location = file_view.get_full_remote_location(); + CHECK(full_remote_location != nullptr); + CHECK(full_remote_location->is_document()); + CHECK(!full_remote_location->is_web()); td_->create_handler(std::move(promise)) - ->send(sticker_id, file_view.remote_location().as_input_document(), unsave); + ->send(sticker_id, full_remote_location->as_input_document(), unsave); } void StickersManager::add_favorite_sticker_by_id(FileId sticker_id) { @@ -9607,34 +9575,28 @@ void StickersManager::add_favorite_sticker_impl(FileId sticker_id, bool add_on_s if (sticker == nullptr) { return promise.set_error(Status::Error(400, "Sticker not found")); } - if (!sticker->set_id_.is_valid()) { - return promise.set_error(Status::Error(400, "Stickers without sticker set can't be added to favorite")); + if (!sticker->set_id_.is_valid() && + (!add_on_server || (sticker->format_ != StickerFormat::Webp && sticker->format_ != StickerFormat::Webm))) { + return promise.set_error(Status::Error(400, "The sticker must be from a sticker set")); } if (sticker->type_ == StickerType::CustomEmoji) { return promise.set_error(Status::Error(400, "Custom emoji stickers can't be added to favorite")); } auto file_view = td_->file_manager_->get_file_view(sticker_id); - if (!file_view.has_remote_location()) { + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location == nullptr) { return promise.set_error(Status::Error(400, "Can add to favorites only sent stickers")); } - if (file_view.remote_location().is_web()) { + if (full_remote_location->is_web()) { return promise.set_error(Status::Error(400, "Can't add to favorites web stickers")); } - if (!file_view.remote_location().is_document()) { + if (!full_remote_location->is_document()) { return promise.set_error(Status::Error(400, "Can't add to favorites encrypted stickers")); } - auto it = std::find_if(favorite_sticker_ids_.begin(), favorite_sticker_ids_.end(), is_equal); - if (it == favorite_sticker_ids_.end()) { - if (static_cast(favorite_sticker_ids_.size()) == favorite_stickers_limit_) { - favorite_sticker_ids_.back() = sticker_id; - } else { - favorite_sticker_ids_.push_back(sticker_id); - } - it = favorite_sticker_ids_.end() - 1; - } - std::rotate(favorite_sticker_ids_.begin(), it, it + 1); + add_to_top_if(favorite_sticker_ids_, static_cast(favorite_stickers_limit_), sticker_id, is_equal); + if (favorite_sticker_ids_[0].get_remote() == 0 && sticker_id.get_remote() != 0) { favorite_sticker_ids_[0] = sticker_id; } @@ -9727,15 +9689,16 @@ vector StickersManager::get_sticker_emojis(const tl_object_ptrfile_manager_->get_file_view(file_id); - if (!file_view.has_remote_location()) { + const auto *full_remote_location = file_view.get_full_remote_location(); + if (full_remote_location == nullptr) { promise.set_value(Unit()); return {}; } - if (!file_view.remote_location().is_document()) { + if (!full_remote_location->is_document()) { promise.set_value(Unit()); return {}; } - if (file_view.remote_location().is_web()) { + if (full_remote_location->is_web()) { promise.set_value(Unit()); return {}; } @@ -9796,23 +9759,25 @@ string StickersManager::get_language_emojis_database_key(const string &language_ return PSTRING() << "emoji$" << language_code << '$' << text; } -vector StickersManager::search_language_emojis(const string &language_code, const string &text, - bool exact_match) { - LOG(INFO) << "Search for \"" << text << "\" in language " << language_code; +vector> StickersManager::search_language_emojis(const string &language_code, + const string &text) { + LOG(INFO) << "Search emoji for \"" << text << "\" in language " << language_code; auto key = get_language_emojis_database_key(language_code, text); - if (exact_match) { - string emojis = G()->td_db()->get_sqlite_sync_pmc()->get(key); - return full_split(emojis, '$'); - } else { - vector result; - G()->td_db()->get_sqlite_sync_pmc()->get_by_prefix(key, [&result](Slice key, Slice value) { - for (auto &emoji : full_split(value, '$')) { - result.push_back(emoji.str()); - } - return true; - }); - return result; - } + vector> result; + G()->td_db()->get_sqlite_sync_pmc()->get_by_prefix(key, [&text, &result](Slice key, Slice value) { + for (const auto &emoji : full_split(value, '$')) { + result.emplace_back(emoji.str(), PSTRING() << text << key); + } + return true; + }); + return result; +} + +vector StickersManager::get_keyword_language_emojis(const string &language_code, const string &text) { + LOG(INFO) << "Get emoji for \"" << text << "\" in language " << language_code; + auto key = get_language_emojis_database_key(language_code, text); + string emojis = G()->td_db()->get_sqlite_sync_pmc()->get(key); + return full_split(emojis, '$'); } string StickersManager::get_emoji_language_codes_database_key(const vector &language_codes) { @@ -10104,7 +10069,7 @@ void StickersManager::on_get_emoji_keywords_difference( } } if (is_good) { - vector emojis = search_language_emojis(language_code, text, true); + vector emojis = get_keyword_language_emojis(language_code, text); bool is_changed = false; for (auto &emoji : keyword->emoticons_) { if (!td::contains(emojis, emoji)) { @@ -10124,7 +10089,7 @@ void StickersManager::on_get_emoji_keywords_difference( case telegram_api::emojiKeywordDeleted::ID: { auto keyword = telegram_api::move_object_as(keyword_ptr); auto text = utf8_to_lower(keyword->keyword_); - vector emojis = search_language_emojis(language_code, text, true); + vector emojis = get_keyword_language_emojis(language_code, text); bool is_changed = false; for (auto &emoji : keyword->emoticons_) { if (td::remove(emojis, emoji)) { @@ -10161,18 +10126,17 @@ void StickersManager::finish_get_emoji_keywords_difference(string language_code, emoji_language_code_last_difference_times_[language_code] = static_cast(Time::now_cached()); } -vector StickersManager::search_emojis(const string &text, bool exact_match, - const vector &input_language_codes, bool force, - Promise &&promise) { +bool StickersManager::prepare_search_emoji_query(const string &text, const vector &input_language_codes, + bool force, Promise &promise, SearchEmojiQuery &query) { if (text.empty() || !G()->use_sqlite_pmc()) { promise.set_value(Unit()); - return {}; + return false; } auto language_codes = get_emoji_language_codes(input_language_codes, text, promise); if (language_codes.empty()) { // promise was consumed - return {}; + return false; } vector languages_to_load; @@ -10196,64 +10160,54 @@ vector StickersManager::search_emojis(const string &text, bool exact_mat load_emoji_keywords(language_code, mpas.get_promise()); } lock.set_value(Unit()); - return {}; + return false; } else { LOG(ERROR) << "Have no " << languages_to_load << " emoji keywords"; } } - auto text_lowered = utf8_to_lower(text); - vector result; - for (auto &language_code : language_codes) { - combine(result, search_language_emojis(language_code, text_lowered, exact_match)); + query.text_ = utf8_to_lower(text); + query.language_codes_ = std::move(language_codes); + return true; +} + +vector> StickersManager::search_emojis(const string &text, + const vector &input_language_codes, bool force, + Promise &&promise) { + SearchEmojiQuery query; + if (!prepare_search_emoji_query(text, input_language_codes, force, promise, query)) { + return {}; } + vector> result; + for (auto &language_code : query.language_codes_) { + combine(result, search_language_emojis(language_code, query.text_)); + } td::unique(result); promise.set_value(Unit()); return result; } -int64 StickersManager::get_emoji_suggestions_url(const string &language_code, Promise &&promise) { - int64 random_id = 0; - do { - random_id = Random::secure_int64(); - } while (random_id == 0 || emoji_suggestions_urls_.count(random_id) > 0); - emoji_suggestions_urls_[random_id]; // reserve place for result - - auto query_promise = - PromiseCreator::lambda([actor_id = actor_id(this), random_id, promise = std::move(promise)]( - Result> &&result) mutable { - send_closure(actor_id, &StickersManager::on_get_emoji_suggestions_url, random_id, std::move(promise), - std::move(result)); - }); - td_->create_handler(std::move(query_promise))->send(language_code); - return random_id; -} - -void StickersManager::on_get_emoji_suggestions_url( - int64 random_id, Promise &&promise, Result> &&r_emoji_url) { - auto it = emoji_suggestions_urls_.find(random_id); - CHECK(it != emoji_suggestions_urls_.end()); - auto &result = it->second; - CHECK(result.empty()); +vector StickersManager::get_keyword_emojis(const string &text, const vector &input_language_codes, + bool force, Promise &&promise) { + SearchEmojiQuery query; + if (!prepare_search_emoji_query(text, input_language_codes, force, promise, query)) { + return {}; + } - if (r_emoji_url.is_error()) { - emoji_suggestions_urls_.erase(it); - return promise.set_error(r_emoji_url.move_as_error()); + vector result; + for (auto &language_code : query.language_codes_) { + combine(result, get_keyword_language_emojis(language_code, query.text_)); } + td::unique(result); - auto emoji_url = r_emoji_url.move_as_ok(); - result = std::move(emoji_url->url_); promise.set_value(Unit()); + return result; } -td_api::object_ptr StickersManager::get_emoji_suggestions_url_result(int64 random_id) { - auto it = emoji_suggestions_urls_.find(random_id); - CHECK(it != emoji_suggestions_urls_.end()); - auto result = td_api::make_object(it->second); - emoji_suggestions_urls_.erase(it); - return result; +void StickersManager::get_emoji_suggestions_url(const string &language_code, Promise &&promise) { + td_->create_handler(std::move(promise))->send(language_code); } string StickersManager::get_emoji_groups_database_key(EmojiGroupType group_type) { @@ -10413,9 +10367,6 @@ void StickersManager::get_current_state(vector(type))); diff --git a/protocols/Telegram/tdlib/td/td/telegram/StickersManager.h b/protocols/Telegram/tdlib/td/td/telegram/StickersManager.h index 6a82fc00c4..f0ceea2581 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/StickersManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/StickersManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,12 +13,14 @@ #include "td/telegram/EmojiGroupType.h" #include "td/telegram/files/FileId.h" #include "td/telegram/files/FileSourceId.h" -#include "td/telegram/FullMessageId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/PhotoFormat.h" #include "td/telegram/PhotoSize.h" +#include "td/telegram/QuickReplyMessageFullId.h" #include "td/telegram/SecretInputMedia.h" #include "td/telegram/SpecialStickerSetType.h" #include "td/telegram/StickerFormat.h" +#include "td/telegram/StickerListType.h" #include "td/telegram/StickerMaskPosition.h" #include "td/telegram/StickerSetId.h" #include "td/telegram/StickerType.h" @@ -70,6 +72,8 @@ class StickersManager final : public Actor { StickerType get_sticker_type(FileId file_id) const; + StickerFormat get_sticker_format(FileId file_id) const; + bool is_premium_custom_emoji(CustomEmojiId custom_emoji_id, bool default_result) const; bool have_sticker(StickerSetId sticker_set_id, int64 sticker_id); @@ -81,6 +85,9 @@ class StickersManager final : public Actor { tl_object_ptr get_stickers_object(const vector &sticker_ids) const; + td_api::object_ptr get_sticker_emojis_object(const vector &sticker_ids, + bool return_only_main_emoji); + td_api::object_ptr get_custom_emoji_sticker_object(CustomEmojiId custom_emoji_id); tl_object_ptr get_dice_stickers_object(const string &emoji, int32 value) const; @@ -93,26 +100,30 @@ class StickersManager final : public Actor { const vector &sticker_set_ids, size_t covers_limit) const; - td_api::object_ptr get_premium_gift_sticker_object(int32 month_count); + td_api::object_ptr get_premium_gift_sticker_object(int32 month_count, int64 star_count); td_api::object_ptr get_animated_emoji_object(const string &emoji, CustomEmojiId custom_emoji_id); tl_object_ptr get_input_sticker_set(StickerSetId sticker_set_id) const; - void register_premium_gift(int32 months, FullMessageId full_message_id, const char *source); + void load_premium_gift_sticker_set(Promise &&promise); + + void register_premium_gift(int32 months, int64 star_count, MessageFullId message_full_id, const char *source); - void unregister_premium_gift(int32 months, FullMessageId full_message_id, const char *source); + void unregister_premium_gift(int32 months, int64 star_count, MessageFullId message_full_id, const char *source); - void register_dice(const string &emoji, int32 value, FullMessageId full_message_id, const char *source); + void register_dice(const string &emoji, int32 value, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source); - void unregister_dice(const string &emoji, int32 value, FullMessageId full_message_id, const char *source); + void unregister_dice(const string &emoji, int32 value, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source); - void register_emoji(const string &emoji, CustomEmojiId custom_emoji_id, FullMessageId full_message_id, - const char *source); + void register_emoji(const string &emoji, CustomEmojiId custom_emoji_id, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source); - void unregister_emoji(const string &emoji, CustomEmojiId custom_emoji_id, FullMessageId full_message_id, - const char *source); + void unregister_emoji(const string &emoji, CustomEmojiId custom_emoji_id, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source); void get_animated_emoji(string emoji, bool is_recursive, Promise> &&promise); @@ -126,27 +137,28 @@ class StickersManager final : public Actor { bool is_default_emoji_status(CustomEmojiId custom_emoji_id); + void get_default_channel_emoji_statuses(bool is_recursive, + Promise> &&promise); + void get_default_topic_icons(bool is_recursive, Promise> &&promise); void get_custom_emoji_stickers(vector custom_emoji_ids, bool use_database, Promise> &&promise); - void get_default_dialog_photo_custom_emoji_stickers(bool for_user, bool force_reload, - Promise> &&promise); + void get_default_custom_emoji_stickers(StickerListType sticker_list_type, bool force_reload, + Promise> &&promise); - void get_premium_gift_option_sticker(int32 month_count, bool is_recursive, - Promise> &&promise); + void get_sticker_list_emoji_statuses(StickerListType sticker_list_type, bool force_reload, + Promise> &&promise); - void get_animated_emoji_click_sticker(const string &message_text, FullMessageId full_message_id, + void get_animated_emoji_click_sticker(const string &message_text, MessageFullId message_full_id, Promise> &&promise); void on_send_animated_emoji_clicks(DialogId dialog_id, const string &emoji); bool is_sent_animated_emoji_click(DialogId dialog_id, const string &emoji); - Status on_animated_emoji_message_clicked(string &&emoji, FullMessageId full_message_id, string data); - - bool is_active_reaction(const string &reaction) const; + Status on_animated_emoji_message_clicked(string &&emoji, MessageFullId message_full_id, string data); void create_sticker(FileId file_id, FileId premium_animation_file_id, string minithumbnail, PhotoSize thumbnail, Dimensions dimensions, tl_object_ptr sticker, @@ -182,40 +194,23 @@ class StickersManager final : public Actor { StickerSetId get_sticker_set(StickerSetId set_id, Promise &&promise); + void get_sticker_set_name(StickerSetId set_id, Promise &&promise); + StickerSetId search_sticker_set(const string &short_name_to_search, Promise &&promise); std::pair> search_installed_sticker_sets(StickerType sticker_type, const string &query, int32 limit, Promise &&promise); - vector search_sticker_sets(const string &query, Promise &&promise); + vector search_sticker_sets(StickerType sticker_type, const string &query, Promise &&promise); void change_sticker_set(StickerSetId set_id, bool is_installed, bool is_archived, Promise &&promise); void view_featured_sticker_sets(const vector &sticker_set_ids); - void get_emoji_reaction(const string &emoji, Promise> &&promise); - - vector get_recent_reactions(); - - vector get_top_reactions(); - - void add_recent_reaction(const string &reaction); - - void clear_recent_reactions(Promise &&promise); - - void reload_reactions(); - - void reload_recent_reactions(); - - void reload_top_reactions(); - void reload_special_sticker_set_by_type(SpecialStickerSetType type, bool is_recursive = false); - void on_get_available_reactions(tl_object_ptr &&available_reactions_ptr); - - void on_get_recent_reactions(tl_object_ptr &&reactions_ptr); - - void on_get_top_reactions(tl_object_ptr &&reactions_ptr); + std::pair on_get_sticker_document(tl_object_ptr &&document_ptr, + StickerFormat expected_format, const char *source); void on_get_installed_sticker_sets(StickerType sticker_type, tl_object_ptr &&stickers_ptr); @@ -231,6 +226,9 @@ class StickersManager final : public Actor { StickerSetId on_get_sticker_set_covered(tl_object_ptr &&set_ptr, bool is_changed, const char *source); + void on_get_sticker_set_name(StickerSetId sticker_set_id, + telegram_api::object_ptr &&set_ptr); + void on_get_special_sticker_set(const SpecialStickerSetType &type, StickerSetId sticker_set_id); void on_load_special_sticker_set(const SpecialStickerSetType &type, Status result); @@ -289,8 +287,9 @@ class StickersManager final : public Actor { void move_sticker_set_to_top_by_custom_emoji_ids(const vector &custom_emoji_ids); - FileId upload_sticker_file(UserId user_id, StickerFormat sticker_format, - const td_api::object_ptr &input_file, Promise &&promise); + void upload_sticker_file(UserId user_id, StickerFormat sticker_format, + const td_api::object_ptr &input_file, + Promise> &&promise); void get_suggested_sticker_set_name(string title, Promise &&promise); @@ -300,16 +299,15 @@ class StickersManager final : public Actor { static td_api::object_ptr get_check_sticker_set_name_result_object( CheckStickerSetNameResult result); - void create_new_sticker_set(UserId user_id, string title, string short_name, StickerFormat sticker_format, - StickerType sticker_type, bool has_text_color, - vector> &&stickers, string software, - Promise> &&promise); + void create_new_sticker_set(UserId user_id, string title, string short_name, StickerType sticker_type, + bool has_text_color, vector> &&stickers, + string software, Promise> &&promise); void add_sticker_to_set(UserId user_id, string short_name, td_api::object_ptr &&sticker, - Promise &&promise); + td_api::object_ptr &&old_sticker, Promise &&promise); - void set_sticker_set_thumbnail(UserId user_id, string short_name, tl_object_ptr &&thumbnail, - Promise &&promise); + void set_sticker_set_thumbnail(UserId user_id, string short_name, td_api::object_ptr &&thumbnail, + StickerFormat format, Promise &&promise); void set_custom_emoji_sticker_set_thumbnail(string short_name, CustomEmojiId custom_emoji_id, Promise &&promise); @@ -332,6 +330,9 @@ class StickersManager final : public Actor { void set_sticker_mask_position(const td_api::object_ptr &sticker, td_api::object_ptr &&mask_position, Promise &&promise); + void get_created_sticker_sets(StickerSetId offset_sticker_set_id, int32 limit, + Promise> &&promise); + vector get_recent_stickers(bool is_attached, Promise &&promise); void on_get_recent_stickers(bool is_repair, bool is_attached, @@ -384,15 +385,16 @@ class StickersManager final : public Actor { vector get_sticker_emojis(const tl_object_ptr &input_file, Promise &&promise); - vector search_emojis(const string &text, bool exact_match, const vector &input_language_codes, - bool force, Promise &&promise); + vector> search_emojis(const string &text, const vector &input_language_codes, + bool force, Promise &&promise); + + vector get_keyword_emojis(const string &text, const vector &input_language_codes, bool force, + Promise &&promise); - int64 get_emoji_suggestions_url(const string &language_code, Promise &&promise); + void get_emoji_suggestions_url(const string &language_code, Promise &&promise); void get_emoji_groups(EmojiGroupType group_type, Promise> &&promise); - td_api::object_ptr get_emoji_suggestions_url_result(int64 random_id); - void reload_sticker_set(StickerSetId sticker_set_id, int64 access_hash, Promise &&promise); void reload_installed_sticker_sets(StickerType sticker_type, bool force); @@ -430,10 +432,10 @@ class StickersManager final : public Actor { void on_find_custom_emojis_fail(const string &emoji, Status &&error); - void on_find_sticker_sets_success(const string &query, + void on_find_sticker_sets_success(StickerType sticker_type, const string &query, tl_object_ptr &&sticker_sets); - void on_find_sticker_sets_fail(const string &query, Status &&error); + void on_find_sticker_sets_fail(StickerType sticker_type, const string &query, Status &&error); void send_get_attached_stickers_query(FileId file_id, Promise &&promise); @@ -457,8 +459,6 @@ class StickersManager final : public Actor { static constexpr int32 EMOJI_KEYWORDS_UPDATE_DELAY = 3600; static constexpr double MIN_ANIMATED_EMOJI_CLICK_DELAY = 0.2; - static constexpr int32 MAX_RECENT_REACTIONS = 100; // some reasonable value - class Sticker { public: StickerSetId set_id_; @@ -484,14 +484,15 @@ class StickersManager final : public Actor { bool is_inited_ = false; // basic information about the set bool was_loaded_ = false; bool is_loaded_ = false; - bool are_keywords_loaded_ = false; // stored in telegram_api::messages_stickerSet - bool is_sticker_has_text_color_loaded_ = false; // stored in telegram_api::messages_stickerSet + bool are_keywords_loaded_ = false; // stored in telegram_api::messages_stickerSet + bool is_sticker_has_text_color_loaded_ = false; + bool is_sticker_channel_emoji_status_loaded_ = false; + bool is_created_loaded_ = false; StickerSetId id_; int64 access_hash_ = 0; string title_; string short_name_; - StickerFormat sticker_format_ = StickerFormat::Unknown; StickerType sticker_type_ = StickerType::Regular; int32 sticker_count_ = 0; int32 hash_ = 0; @@ -508,9 +509,12 @@ class StickersManager final : public Actor { mutable std::map> keyword_stickers_map_; // keyword -> stickers FlatHashMap, FileIdHash> sticker_keywords_map_; // sticker -> keywords + bool is_created_ = false; bool is_installed_ = false; bool is_archived_ = false; bool is_official_ = false; + bool has_text_color_ = false; + bool channel_emoji_status_ = false; bool is_viewed_ = true; bool is_thumbnail_reloaded_ = false; // stored in telegram_api::stickerSet bool are_legacy_sticker_thumbnails_reloaded_ = false; // stored in telegram_api::stickerSet @@ -528,7 +532,6 @@ class StickersManager final : public Actor { string title_; string short_name_; StickerType sticker_type_ = StickerType::Regular; - StickerFormat sticker_format_ = StickerFormat::Unknown; bool has_text_color_ = false; vector file_ids_; vector> stickers_; @@ -539,7 +542,8 @@ class StickersManager final : public Actor { struct PendingAddStickerToSet { string short_name_; FileId file_id_; - tl_object_ptr sticker_; + td_api::object_ptr sticker_; + telegram_api::object_ptr input_document_; Promise promise_; }; @@ -551,14 +555,14 @@ class StickersManager final : public Actor { struct PendingGetAnimatedEmojiClickSticker { string message_text_; - FullMessageId full_message_id_; + MessageFullId message_full_id_; double start_time_ = 0; Promise> promise_; }; struct PendingOnAnimatedEmojiClicked { string emoji_; - FullMessageId full_message_id_; + MessageFullId message_full_id_; vector> clicks_; }; @@ -583,55 +587,6 @@ class StickersManager final : public Actor { void parse(ParserT &parser); }; - struct Reaction { - string reaction_; - string title_; - bool is_active_ = false; - bool is_premium_ = false; - FileId static_icon_; - FileId appear_animation_; - FileId select_animation_; - FileId activate_animation_; - FileId effect_animation_; - FileId around_animation_; - FileId center_animation_; - - bool is_valid() const { - return static_icon_.is_valid() && appear_animation_.is_valid() && select_animation_.is_valid() && - activate_animation_.is_valid() && effect_animation_.is_valid() && !reaction_.empty(); - } - - template - void store(StorerT &storer) const; - - template - void parse(ParserT &parser); - }; - - struct Reactions { - int32 hash_ = 0; - bool are_being_reloaded_ = false; - vector reactions_; - - template - void store(StorerT &storer) const; - - template - void parse(ParserT &parser); - }; - - struct ReactionList { - int64 hash_ = 0; - bool is_being_reloaded_ = false; - vector reactions_; - - template - void store(StorerT &storer) const; - - template - void parse(ParserT &parser); - }; - class CustomEmojiLogEvent; class CustomEmojiIdsLogEvent; class StickerListLogEvent; @@ -647,15 +602,15 @@ class StickersManager final : public Actor { StickerSetId sticker_set_id, int64 document_id, double zoom); - static double get_sticker_set_minithumbnail_zoom(const StickerSet *sticker_set); + PhotoFormat get_sticker_set_thumbnail_format(const StickerSet *sticker_set) const; + + double get_sticker_set_minithumbnail_zoom(const StickerSet *sticker_set) const; td_api::object_ptr get_sticker_set_thumbnail_object(const StickerSet *sticker_set) const; tl_object_ptr get_sticker_set_info_object(StickerSetId sticker_set_id, size_t covers_limit, bool prefer_premium) const; - td_api::object_ptr get_emoji_reaction_object(const string &emoji) const; - Sticker *get_sticker(FileId file_id); const Sticker *get_sticker(FileId file_id) const; @@ -688,15 +643,18 @@ class StickersManager final : public Actor { void on_load_custom_emoji_from_database(CustomEmojiId custom_emoji_id, string value); - void on_load_default_dialog_photo_custom_emoji_ids_from_database(bool for_user, bool force_reload, string value); + void load_default_custom_emoji_ids(StickerListType sticker_list_type, bool force_reload); - void reload_default_dialog_photo_custom_emoji_ids(bool for_user); + void on_load_default_custom_emoji_ids_from_database(StickerListType sticker_list_type, bool force_reload, + string value); - void on_get_default_dialog_photo_custom_emoji_ids( - bool for_user, Result> r_emoji_list); + void reload_default_custom_emoji_ids(StickerListType sticker_list_type); - void on_get_default_dialog_photo_custom_emoji_ids_success(bool for_user, vector custom_emoji_ids, - int64 hash); + void on_get_default_custom_emoji_ids(StickerListType sticker_list_type, + Result> r_emoji_list); + + void on_get_default_custom_emoji_ids_success(StickerListType sticker_list_type, + vector custom_emoji_ids, int64 hash); FileId on_get_sticker(unique_ptr new_sticker, bool replace); @@ -706,11 +664,6 @@ class StickersManager final : public Actor { StickerSet *add_sticker_set(StickerSetId sticker_set_id, int64 access_hash); - static PhotoFormat get_sticker_set_thumbnail_format(StickerFormat sticker_format); - - std::pair on_get_sticker_document(tl_object_ptr &&document_ptr, - StickerFormat expected_format); - static tl_object_ptr get_input_sticker_set(const StickerSet *set); StickerSetId on_get_input_sticker_set(FileId sticker_file_id, tl_object_ptr &&set_ptr, @@ -855,15 +808,16 @@ class StickersManager final : public Actor { StickerFormat sticker_format, StickerType sticker_type, bool for_thumbnail); - Result> prepare_input_sticker(td_api::inputSticker *sticker, - StickerFormat sticker_format, StickerType sticker_type); + Result> prepare_input_sticker(td_api::inputSticker *sticker, StickerType sticker_type); + + void finish_upload_sticker_file(FileId file_id, Promise> &&promise); - tl_object_ptr get_input_sticker(const td_api::inputSticker *sticker, - FileId file_id) const; + telegram_api::object_ptr get_input_sticker(const td_api::inputSticker *sticker, + FileId file_id) const; void upload_sticker_file(UserId user_id, FileId file_id, Promise &&promise); - void on_upload_sticker_file(FileId file_id, tl_object_ptr input_file); + void on_upload_sticker_file(FileId file_id, telegram_api::object_ptr input_file); void on_upload_sticker_file_error(FileId file_id, Status status); @@ -874,12 +828,15 @@ class StickersManager final : public Actor { void on_added_sticker_uploaded(int64 random_id, Result result); + StickerFormat guess_sticker_set_format(const StickerSet *sticker_set) const; + void do_add_sticker_to_set(UserId user_id, string short_name, td_api::object_ptr &&sticker, - Promise &&promise); + td_api::object_ptr &&old_sticker, Promise &&promise); void on_sticker_set_thumbnail_uploaded(int64 random_id, Result result); - void do_set_sticker_set_thumbnail(UserId user_id, string short_name, tl_object_ptr &&thumbnail, + void do_set_sticker_set_thumbnail(UserId user_id, string short_name, + td_api::object_ptr &&thumbnail, StickerFormat format, Promise &&promise); void do_set_custom_emoji_sticker_set_thumbnail(string short_name, CustomEmojiId custom_emoji_id, @@ -891,6 +848,9 @@ class StickersManager final : public Actor { }; Result get_sticker_input_document(const tl_object_ptr &sticker) const; + void on_get_created_sticker_sets(Result> r_my_stickers, + Promise> &&promise); + bool update_sticker_set_cache(const StickerSet *sticker_set, Promise &promise); const StickerSet *get_premium_gift_sticker_set(); @@ -923,7 +883,7 @@ class StickersManager final : public Actor { vector get_animated_emoji_click_stickers(const StickerSet *sticker_set, Slice emoji) const; void choose_animated_emoji_click_sticker(const StickerSet *sticker_set, string message_text, - FullMessageId full_message_id, double start_time, + MessageFullId message_full_id, double start_time, Promise> &&promise); void send_click_animated_emoji_message_response(FileId sticker_id, @@ -933,10 +893,10 @@ class StickersManager final : public Actor { void flush_pending_animated_emoji_clicks(); - void schedule_update_animated_emoji_clicked(const StickerSet *sticker_set, Slice emoji, FullMessageId full_message_id, + void schedule_update_animated_emoji_clicked(const StickerSet *sticker_set, Slice emoji, MessageFullId message_full_id, vector> clicks); - void send_update_animated_emoji_clicked(FullMessageId full_message_id, FileId sticker_id); + void send_update_animated_emoji_clicked(MessageFullId message_full_id, FileId sticker_id); td_api::object_ptr get_update_dice_emojis_object() const; @@ -946,26 +906,6 @@ class StickersManager final : public Actor { void tear_down() final; - void save_active_reactions(); - - void save_reactions(); - - void save_recent_reactions(); - - void save_top_reactions(); - - void load_active_reactions(); - - void load_reactions(); - - void load_recent_reactions(); - - void load_top_reactions(); - - void update_active_reactions(); - - td_api::object_ptr get_update_active_emoji_reactions_object() const; - SpecialStickerSet &add_special_sticker_set(const SpecialStickerSetType &type); static void init_special_sticker_set(SpecialStickerSet &sticker_set, int64 sticker_set_id, int64 access_hash, @@ -979,6 +919,8 @@ class StickersManager final : public Actor { void reload_special_sticker_set(SpecialStickerSet &sticker_set, int32 hash); + int is_custom_emoji_from_sticker_set(CustomEmojiId custom_emoji_id, StickerSetId sticker_set_id) const; + static void add_sticker_thumbnail(Sticker *s, PhotoSize thumbnail); td_api::object_ptr get_custom_emoji_stickers_object(const vector &custom_emoji_ids); @@ -989,8 +931,8 @@ class StickersManager final : public Actor { static const std::map> &get_sticker_set_keywords(const StickerSet *sticker_set); - static void find_sticker_set_stickers(const StickerSet *sticker_set, const vector &emojis, - const string &query, vector &result); + void find_sticker_set_stickers(const StickerSet *sticker_set, const vector &emojis, const string &query, + vector> &result) const; bool can_find_sticker_by_query(FileId sticker_id, const vector &emojis, const string &query) const; @@ -1002,8 +944,6 @@ class StickersManager final : public Actor { static string get_emoji_language_codes_database_key(const vector &language_codes); - static string get_default_dialog_photo_custom_emoji_ids_database_key(bool for_user); - static string get_emoji_groups_database_key(EmojiGroupType group_type); int32 get_emoji_language_code_version(const string &language_code); @@ -1014,6 +954,13 @@ class StickersManager final : public Actor { string get_used_language_codes_string() const; + struct SearchEmojiQuery { + string text_; + vector language_codes_; + }; + bool prepare_search_emoji_query(const string &text, const vector &input_language_codes, bool force, + Promise &promise, SearchEmojiQuery &query); + vector get_emoji_language_codes(const vector &input_language_codes, Slice text, Promise &promise); @@ -1021,7 +968,9 @@ class StickersManager final : public Actor { void on_get_language_codes(const string &key, Result> &&result); - static vector search_language_emojis(const string &language_code, const string &text, bool exact_match); + static vector> search_language_emojis(const string &language_code, const string &text); + + static vector get_keyword_language_emojis(const string &language_code, const string &text); void load_emoji_keywords(const string &language_code, Promise &&promise); @@ -1036,9 +985,6 @@ class StickersManager final : public Actor { void finish_get_emoji_keywords_difference(string language_code, int32 version); - void on_get_emoji_suggestions_url(int64 random_id, Promise &&promise, - Result> &&r_emoji_url); - void on_load_emoji_groups_from_database(EmojiGroupType group_type, string used_language_codes, string value); void on_load_emoji_group_icons(EmojiGroupType group_type, EmojiGroupList group_list); @@ -1053,10 +999,11 @@ class StickersManager final : public Actor { bool is_inited_ = false; - WaitFreeHashMap, FileIdHash> stickers_; // file_id -> Sticker + WaitFreeHashMap, FileIdHash> stickers_; WaitFreeHashMap, StickerSetIdHash> sticker_sets_; // sticker_set_id -> StickerSet WaitFreeHashMap short_name_to_sticker_set_id_; + FlatHashMap>, StickerSetIdHash> sticker_set_name_load_queries_; vector installed_sticker_set_ids_[MAX_STICKER_TYPE]; vector featured_sticker_set_ids_[MAX_STICKER_TYPE]; @@ -1121,8 +1068,8 @@ class StickersManager final : public Actor { FlatHashMap>>>> search_stickers_queries_[MAX_STICKER_TYPE]; - std::unordered_map, Hash> found_sticker_sets_; - std::unordered_map>, Hash> search_sticker_sets_queries_; + std::unordered_map, Hash> found_sticker_sets_[MAX_STICKER_TYPE]; + std::unordered_map>, Hash> search_sticker_sets_queries_[MAX_STICKER_TYPE]; FlatHashSet pending_viewed_featured_sticker_set_ids_; Timeout pending_featured_sticker_set_views_timeout_; @@ -1153,17 +1100,16 @@ class StickersManager final : public Actor { vector> pending_get_premium_gift_option_sticker_queries_; vector> pending_get_generic_animations_queries_; vector> pending_get_default_statuses_queries_; + vector> pending_get_default_channel_statuses_queries_; vector> pending_get_default_topic_icons_queries_; - vector>>> pending_get_emoji_reaction_queries_; - double next_click_animated_emoji_message_time_ = 0; double next_update_animated_emoji_clicked_time_ = 0; vector pending_get_animated_emoji_click_stickers_; vector pending_on_animated_emoji_message_clicked_; string last_clicked_animated_emoji_; - FullMessageId last_clicked_animated_emoji_full_message_id_; + MessageFullId last_clicked_animated_emoji_message_full_id_; std::vector> pending_animated_emoji_clicks_; struct SentAnimatedEmojiClicks { @@ -1177,41 +1123,33 @@ class StickersManager final : public Actor { FlatHashMap>, FileIdHash> being_uploaded_files_; - Reactions reactions_; - vector active_reactions_; - - ReactionList recent_reactions_; - ReactionList top_reactions_; - - bool are_reactions_loaded_from_database_ = false; - bool are_recent_reactions_loaded_from_database_ = false; - bool are_top_reactions_loaded_from_database_ = false; - FlatHashMap> emoji_language_codes_; FlatHashMap emoji_language_code_versions_; FlatHashMap emoji_language_code_last_difference_times_; FlatHashSet reloaded_emoji_keywords_; FlatHashMap>> load_emoji_keywords_queries_; FlatHashMap>> load_language_codes_queries_; - FlatHashMap emoji_suggestions_urls_; struct GiftPremiumMessages { - FlatHashSet full_message_ids_; + FlatHashSet message_full_ids_; FileId sticker_id_; }; FlatHashMap> premium_gift_messages_; - FlatHashMap> dice_messages_; + FlatHashMap> dice_messages_; + FlatHashMap> dice_quick_reply_messages_; struct EmojiMessages { - WaitFreeHashSet full_message_ids_; + WaitFreeHashSet message_full_ids_; + WaitFreeHashSet quick_reply_message_full_ids_; std::pair animated_emoji_sticker_; FileId sound_file_id_; }; FlatHashMap> emoji_messages_; struct CustomEmojiMessages { - WaitFreeHashSet full_message_ids_; + WaitFreeHashSet message_full_ids_; + WaitFreeHashSet quick_reply_message_full_ids_; FileId sticker_id_; }; FlatHashMap, CustomEmojiIdHash> custom_emoji_messages_; @@ -1228,15 +1166,17 @@ class StickersManager final : public Actor { EmojiGroupList emoji_group_list_[MAX_EMOJI_GROUP_TYPE]; vector>> emoji_group_load_queries_[MAX_EMOJI_GROUP_TYPE]; - vector default_dialog_photo_custom_emoji_ids_[2]; - int64 default_dialog_photo_custom_emoji_ids_hash_[2] = {0, 0}; - vector>> default_dialog_photo_custom_emoji_ids_load_queries_[2]; - bool are_default_dialog_photo_custom_emoji_ids_loaded_[2] = {false, false}; - bool are_default_dialog_photo_custom_emoji_ids_being_loaded_[2] = {false, false}; + vector default_custom_emoji_ids_[MAX_STICKER_LIST_TYPE]; + int64 default_custom_emoji_ids_hash_[MAX_STICKER_LIST_TYPE] = {0, 0, 0, 0}; + vector>> default_custom_emoji_ids_load_queries_[MAX_STICKER_LIST_TYPE]; + vector>> + default_emoji_statuses_load_queries_[MAX_STICKER_LIST_TYPE]; + bool are_default_custom_emoji_ids_loaded_[MAX_STICKER_LIST_TYPE] = {false, false, false, false}; + bool are_default_custom_emoji_ids_being_loaded_[MAX_STICKER_LIST_TYPE] = {false, false, false, false}; WaitFreeHashMap custom_emoji_to_sticker_id_; - double animated_emoji_zoom_ = 0.0; + double animated_emoji_zoom_ = 0.625; bool disable_animated_emojis_ = false; }; diff --git a/protocols/Telegram/tdlib/td/td/telegram/StickersManager.hpp b/protocols/Telegram/tdlib/td/td/telegram/StickersManager.hpp index 674f2e4e5c..368fb1ecbc 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/StickersManager.hpp +++ b/protocols/Telegram/tdlib/td/td/telegram/StickersManager.hpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,8 +13,6 @@ #include "td/telegram/PhotoSize.hpp" #include "td/telegram/StickerFormat.h" #include "td/telegram/StickerMaskPosition.hpp" -#include "td/telegram/StickersManager.h" -#include "td/telegram/Td.h" #include "td/utils/emoji.h" #include "td/utils/logging.h" @@ -178,31 +176,36 @@ void StickersManager::store_sticker_set(const StickerSet *sticker_set, bool with bool has_expires_at = !sticker_set->is_installed_ && sticker_set->expires_at_ != 0; bool has_thumbnail = sticker_set->thumbnail_.file_id.is_valid(); bool has_minithumbnail = !sticker_set->minithumbnail_.empty(); - bool is_tgs = sticker_set->sticker_format_ == StickerFormat::Tgs; - bool is_webm = sticker_set->sticker_format_ == StickerFormat::Webm; bool is_masks = sticker_set->sticker_type_ == StickerType::Mask; bool is_emojis = sticker_set->sticker_type_ == StickerType::CustomEmoji; bool has_thumbnail_document_id = sticker_set->thumbnail_document_id_ != 0; + bool is_mixed_format = true; BEGIN_STORE_FLAGS(); STORE_FLAG(sticker_set->is_inited_); STORE_FLAG(was_loaded); STORE_FLAG(is_loaded); STORE_FLAG(sticker_set->is_installed_); STORE_FLAG(sticker_set->is_archived_); - STORE_FLAG(sticker_set->is_official_); + STORE_FLAG(sticker_set->is_official_); // 5 STORE_FLAG(is_masks); STORE_FLAG(sticker_set->is_viewed_); STORE_FLAG(has_expires_at); STORE_FLAG(has_thumbnail); - STORE_FLAG(sticker_set->is_thumbnail_reloaded_); - STORE_FLAG(is_tgs); + STORE_FLAG(sticker_set->is_thumbnail_reloaded_); // 10 + STORE_FLAG(false); STORE_FLAG(sticker_set->are_legacy_sticker_thumbnails_reloaded_); STORE_FLAG(has_minithumbnail); - STORE_FLAG(is_webm); - STORE_FLAG(is_emojis); + STORE_FLAG(false); + STORE_FLAG(is_emojis); // 15 STORE_FLAG(has_thumbnail_document_id); STORE_FLAG(sticker_set->are_keywords_loaded_); STORE_FLAG(sticker_set->is_sticker_has_text_color_loaded_); + STORE_FLAG(sticker_set->has_text_color_); + STORE_FLAG(sticker_set->is_sticker_channel_emoji_status_loaded_); // 20 + STORE_FLAG(sticker_set->channel_emoji_status_); + STORE_FLAG(is_mixed_format); + STORE_FLAG(sticker_set->is_created_); + STORE_FLAG(sticker_set->is_created_loaded_); END_STORE_FLAGS(); store(sticker_set->id_.get(), storer); store(sticker_set->access_hash_, storer); @@ -261,11 +264,16 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser bool is_masks; bool has_expires_at; bool has_thumbnail; - bool is_tgs; + bool legacy_is_tgs; bool has_minithumbnail; - bool is_webm; + bool legacy_is_webm; bool is_emojis; bool has_thumbnail_document_id; + bool has_text_color; + bool channel_emoji_status; + bool is_mixed_format; + bool is_created; + bool is_created_loaded; BEGIN_PARSE_FLAGS(); PARSE_FLAG(sticker_set->is_inited_); PARSE_FLAG(sticker_set->was_loaded_); @@ -278,14 +286,20 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser PARSE_FLAG(has_expires_at); PARSE_FLAG(has_thumbnail); PARSE_FLAG(sticker_set->is_thumbnail_reloaded_); - PARSE_FLAG(is_tgs); + PARSE_FLAG(legacy_is_tgs); PARSE_FLAG(sticker_set->are_legacy_sticker_thumbnails_reloaded_); PARSE_FLAG(has_minithumbnail); - PARSE_FLAG(is_webm); + PARSE_FLAG(legacy_is_webm); PARSE_FLAG(is_emojis); PARSE_FLAG(has_thumbnail_document_id); PARSE_FLAG(sticker_set->are_keywords_loaded_); PARSE_FLAG(sticker_set->is_sticker_has_text_color_loaded_); + PARSE_FLAG(has_text_color); + PARSE_FLAG(sticker_set->is_sticker_channel_emoji_status_loaded_); + PARSE_FLAG(channel_emoji_status); + PARSE_FLAG(is_mixed_format); + PARSE_FLAG(is_created); + PARSE_FLAG(is_created_loaded); END_PARSE_FLAGS(); int64 sticker_set_id; int64 access_hash; @@ -296,17 +310,10 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser } (void)access_hash; // unused, because only known sticker sets with access hash can be loaded from database - StickerFormat sticker_format = StickerFormat::Unknown; - if (is_webm) { - sticker_format = StickerFormat::Webm; - } else if (is_tgs) { - sticker_format = StickerFormat::Tgs; - } else { - sticker_format = StickerFormat::Webp; - } auto sticker_type = ::td::get_sticker_type(is_masks, is_emojis); if (!is_emojis) { sticker_set->is_sticker_has_text_color_loaded_ = true; + sticker_set->is_sticker_channel_emoji_status_loaded_ = true; } if (sticker_set->is_inited_) { @@ -334,7 +341,15 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser if (has_thumbnail_document_id) { parse(thumbnail_document_id, parser); } - + if (!is_mixed_format && thumbnail.file_id.is_valid()) { + if (legacy_is_webm) { + thumbnail.type = 'v'; + } else if (legacy_is_tgs) { + thumbnail.type = 'a'; + } else { + thumbnail.type = 's'; + } + } if (!was_inited) { sticker_set->title_ = std::move(title); sticker_set->short_name_ = std::move(short_name); @@ -346,7 +361,10 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser sticker_set->expires_at_ = expires_at; sticker_set->is_official_ = is_official; sticker_set->sticker_type_ = sticker_type; - sticker_set->sticker_format_ = sticker_format; + sticker_set->has_text_color_ = has_text_color; + sticker_set->channel_emoji_status_ = channel_emoji_status; + sticker_set->is_created_ = is_created; + sticker_set->is_created_loaded_ = is_created_loaded; auto cleaned_username = clean_username(sticker_set->short_name_); if (!cleaned_username.empty()) { @@ -356,7 +374,9 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser } else { if (sticker_set->title_ != title || sticker_set->minithumbnail_ != minithumbnail || sticker_set->thumbnail_ != thumbnail || sticker_set->thumbnail_document_id_ != thumbnail_document_id || - sticker_set->is_official_ != is_official) { + sticker_set->is_official_ != is_official || sticker_set->has_text_color_ != has_text_color || + sticker_set->channel_emoji_status_ != channel_emoji_status || sticker_set->is_created_ != is_created || + sticker_set->is_created_loaded_ != is_created_loaded) { sticker_set->is_changed_ = true; } if (sticker_set->short_name_ != short_name) { @@ -368,10 +388,6 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser sticker_set->is_loaded_ = false; sticker_set->is_changed_ = true; } - if (sticker_set->sticker_format_ != sticker_format) { - LOG(ERROR) << "Sticker format of " << sticker_set->id_ << " has changed from \"" << sticker_format << "\" to \"" - << sticker_set->sticker_format_ << "\""; - } if (sticker_set->sticker_type_ != sticker_type) { LOG(ERROR) << "Type of " << sticker_set->id_ << " has changed from \"" << sticker_type << "\" to \"" << sticker_set->sticker_type_ << "\""; @@ -403,6 +419,9 @@ void StickersManager::parse_sticker_set(StickerSet *sticker_set, ParserT &parser if (sticker->set_id_ != sticker_set->id_) { LOG_IF(ERROR, sticker->set_id_.is_valid()) << "Sticker " << sticker_id << " set_id has changed"; sticker->set_id_ = sticker_set->id_; + if (sticker->has_text_color_) { + sticker_set->has_text_color_ = true; + } } if (sticker->is_premium_) { sticker_set->premium_sticker_positions_.push_back(static_cast(sticker_set->sticker_ids_.size() - 1)); @@ -465,106 +484,4 @@ void StickersManager::parse_sticker_set_id(StickerSetId &sticker_set_id, ParserT add_sticker_set(sticker_set_id, sticker_set_access_hash); } -template -void StickersManager::Reaction::store(StorerT &storer) const { - StickersManager *stickers_manager = storer.context()->td().get_actor_unsafe()->stickers_manager_.get(); - bool has_around_animation = !around_animation_.empty(); - bool has_center_animation = !center_animation_.empty(); - BEGIN_STORE_FLAGS(); - STORE_FLAG(is_active_); - STORE_FLAG(has_around_animation); - STORE_FLAG(has_center_animation); - STORE_FLAG(is_premium_); - END_STORE_FLAGS(); - td::store(reaction_, storer); - td::store(title_, storer); - stickers_manager->store_sticker(static_icon_, false, storer, "Reaction"); - stickers_manager->store_sticker(appear_animation_, false, storer, "Reaction"); - stickers_manager->store_sticker(select_animation_, false, storer, "Reaction"); - stickers_manager->store_sticker(activate_animation_, false, storer, "Reaction"); - stickers_manager->store_sticker(effect_animation_, false, storer, "Reaction"); - if (has_around_animation) { - stickers_manager->store_sticker(around_animation_, false, storer, "Reaction"); - } - if (has_center_animation) { - stickers_manager->store_sticker(center_animation_, false, storer, "Reaction"); - } -} - -template -void StickersManager::Reaction::parse(ParserT &parser) { - StickersManager *stickers_manager = parser.context()->td().get_actor_unsafe()->stickers_manager_.get(); - bool has_around_animation; - bool has_center_animation; - BEGIN_PARSE_FLAGS(); - PARSE_FLAG(is_active_); - PARSE_FLAG(has_around_animation); - PARSE_FLAG(has_center_animation); - PARSE_FLAG(is_premium_); - END_PARSE_FLAGS(); - td::parse(reaction_, parser); - td::parse(title_, parser); - static_icon_ = stickers_manager->parse_sticker(false, parser); - appear_animation_ = stickers_manager->parse_sticker(false, parser); - select_animation_ = stickers_manager->parse_sticker(false, parser); - activate_animation_ = stickers_manager->parse_sticker(false, parser); - effect_animation_ = stickers_manager->parse_sticker(false, parser); - if (has_around_animation) { - around_animation_ = stickers_manager->parse_sticker(false, parser); - } - if (has_center_animation) { - center_animation_ = stickers_manager->parse_sticker(false, parser); - } - - is_premium_ = false; -} - -template -void StickersManager::Reactions::store(StorerT &storer) const { - bool has_reactions = !reactions_.empty(); - BEGIN_STORE_FLAGS(); - STORE_FLAG(has_reactions); - END_STORE_FLAGS(); - if (has_reactions) { - td::store(reactions_, storer); - td::store(hash_, storer); - } -} - -template -void StickersManager::Reactions::parse(ParserT &parser) { - bool has_reactions; - BEGIN_PARSE_FLAGS(); - PARSE_FLAG(has_reactions); - END_PARSE_FLAGS(); - if (has_reactions) { - td::parse(reactions_, parser); - td::parse(hash_, parser); - } -} - -template -void StickersManager::ReactionList::store(StorerT &storer) const { - bool has_reactions = !reactions_.empty(); - BEGIN_STORE_FLAGS(); - STORE_FLAG(has_reactions); - END_STORE_FLAGS(); - if (has_reactions) { - td::store(reactions_, storer); - td::store(hash_, storer); - } -} - -template -void StickersManager::ReactionList::parse(ParserT &parser) { - bool has_reactions; - BEGIN_PARSE_FLAGS(); - PARSE_FLAG(has_reactions); - END_PARSE_FLAGS(); - if (has_reactions) { - td::parse(reactions_, parser); - td::parse(hash_, parser); - } -} - } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryContent.cpp b/protocols/Telegram/tdlib/td/td/telegram/StoryContent.cpp new file mode 100644 index 0000000000..b2c89915ee --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryContent.cpp @@ -0,0 +1,538 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StoryContent.h" + +#include "td/telegram/Dependencies.h" +#include "td/telegram/Dimensions.h" +#include "td/telegram/Document.h" +#include "td/telegram/DocumentsManager.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/files/FileType.h" +#include "td/telegram/Photo.h" +#include "td/telegram/Photo.hpp" +#include "td/telegram/PhotoSize.h" +#include "td/telegram/StickersManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/VideosManager.h" + +#include "td/utils/common.h" +#include "td/utils/logging.h" +#include "td/utils/tl_helpers.h" + +#include + +namespace td { + +class StoryContentPhoto final : public StoryContent { + public: + Photo photo_; + + StoryContentPhoto() = default; + explicit StoryContentPhoto(Photo &&photo) : photo_(std::move(photo)) { + } + + StoryContentType get_type() const final { + return StoryContentType::Photo; + } +}; + +class StoryContentVideo final : public StoryContent { + public: + FileId file_id_; + FileId alt_file_id_; + + StoryContentVideo() = default; + StoryContentVideo(FileId file_id, FileId alt_file_id) : file_id_(file_id), alt_file_id_(alt_file_id) { + } + + StoryContentType get_type() const final { + return StoryContentType::Video; + } +}; + +class StoryContentUnsupported final : public StoryContent { + public: + static constexpr int32 CURRENT_VERSION = 1; + int32 version_ = CURRENT_VERSION; + + StoryContentUnsupported() = default; + explicit StoryContentUnsupported(int32 version) : version_(version) { + } + + StoryContentType get_type() const final { + return StoryContentType::Unsupported; + } +}; + +template +static void store(const StoryContent *content, StorerT &storer) { + CHECK(content != nullptr); + + Td *td = storer.context()->td().get_actor_unsafe(); + CHECK(td != nullptr); + + auto content_type = content->get_type(); + store(content_type, storer); + + switch (content_type) { + case StoryContentType::Photo: { + const auto *story_content = static_cast(content); + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + store(story_content->photo_, storer); + break; + } + case StoryContentType::Video: { + const auto *story_content = static_cast(content); + bool has_alt_file_id = story_content->alt_file_id_.is_valid(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_alt_file_id); + END_STORE_FLAGS(); + td->videos_manager_->store_video(story_content->file_id_, storer); + if (has_alt_file_id) { + td->videos_manager_->store_video(story_content->alt_file_id_, storer); + } + break; + } + case StoryContentType::Unsupported: { + const auto *story_content = static_cast(content); + store(story_content->version_, storer); + break; + } + default: + UNREACHABLE(); + } +} + +template +static void parse(unique_ptr &content, ParserT &parser) { + Td *td = parser.context()->td().get_actor_unsafe(); + CHECK(td != nullptr); + + StoryContentType content_type; + parse(content_type, parser); + + bool is_bad = false; + switch (content_type) { + case StoryContentType::Photo: { + auto story_content = make_unique(); + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + parse(story_content->photo_, parser); + is_bad |= story_content->photo_.is_bad(); + content = std::move(story_content); + break; + } + case StoryContentType::Video: { + auto story_content = make_unique(); + bool has_alt_file_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_alt_file_id); + END_PARSE_FLAGS(); + story_content->file_id_ = td->videos_manager_->parse_video(parser); + if (has_alt_file_id) { + story_content->alt_file_id_ = td->videos_manager_->parse_video(parser); + if (!story_content->alt_file_id_.is_valid()) { + LOG(ERROR) << "Failed to parse alternative video"; + } + } + content = std::move(story_content); + break; + } + case StoryContentType::Unsupported: { + auto story_content = make_unique(); + parse(story_content->version_, parser); + content = std::move(story_content); + break; + } + default: + is_bad = true; + } + if (is_bad) { + LOG(ERROR) << "Load a story with an invalid content of type " << content_type; + content = make_unique(0); + } +} + +void store_story_content(const StoryContent *content, LogEventStorerCalcLength &storer) { + store(content, storer); +} + +void store_story_content(const StoryContent *content, LogEventStorerUnsafe &storer) { + store(content, storer); +} + +void parse_story_content(unique_ptr &content, LogEventParser &parser) { + parse(content, parser); +} + +void add_story_content_dependencies(Dependencies &dependencies, const StoryContent *story_content) { + switch (story_content->get_type()) { + case StoryContentType::Photo: + break; + case StoryContentType::Video: + break; + case StoryContentType::Unsupported: + break; + default: + UNREACHABLE(); + break; + } +} + +unique_ptr get_story_content(Td *td, tl_object_ptr &&media_ptr, + DialogId owner_dialog_id) { + CHECK(media_ptr != nullptr); + switch (media_ptr->get_id()) { + case telegram_api::messageMediaPhoto::ID: { + auto media = move_tl_object_as(media_ptr); + if (media->photo_ == nullptr || (media->flags_ & telegram_api::messageMediaPhoto::TTL_SECONDS_MASK) != 0 || + media->spoiler_) { + LOG(ERROR) << "Receive a story with content " << to_string(media); + break; + } + + auto photo = get_photo(td, std::move(media->photo_), owner_dialog_id, FileType::PhotoStory); + if (photo.is_empty()) { + LOG(ERROR) << "Receive a story with empty photo"; + break; + } + return make_unique(std::move(photo)); + } + case telegram_api::messageMediaDocument::ID: { + auto media = move_tl_object_as(media_ptr); + if (media->document_ == nullptr || (media->flags_ & telegram_api::messageMediaDocument::TTL_SECONDS_MASK) != 0 || + media->spoiler_) { + LOG(ERROR) << "Receive a story with content " << to_string(media); + break; + } + + auto document_ptr = std::move(media->document_); + int32 document_id = document_ptr->get_id(); + if (document_id == telegram_api::documentEmpty::ID) { + LOG(ERROR) << "Receive a story with empty document"; + break; + } + CHECK(document_id == telegram_api::document::ID); + auto parsed_document = td->documents_manager_->on_get_document( + move_tl_object_as(document_ptr), owner_dialog_id, nullptr, Document::Type::Video, + DocumentsManager::Subtype::Story); + if (parsed_document.empty() || parsed_document.type != Document::Type::Video) { + LOG(ERROR) << "Receive a story with " << parsed_document; + break; + } + CHECK(parsed_document.file_id.is_valid()); + + FileId alt_file_id; + if (media->alt_document_ != nullptr) { + auto alt_document_ptr = std::move(media->alt_document_); + int32 alt_document_id = alt_document_ptr->get_id(); + if (alt_document_id == telegram_api::documentEmpty::ID) { + LOG(ERROR) << "Receive alternative " << to_string(alt_document_ptr); + } else { + CHECK(alt_document_id == telegram_api::document::ID); + auto parsed_alt_document = td->documents_manager_->on_get_document( + move_tl_object_as(alt_document_ptr), owner_dialog_id, nullptr, + Document::Type::Video, DocumentsManager::Subtype::Story); + if (parsed_alt_document.empty() || parsed_alt_document.type != Document::Type::Video) { + LOG(ERROR) << "Receive alternative " << to_string(alt_document_ptr); + } else { + alt_file_id = parsed_alt_document.file_id; + } + } + } + + return make_unique(parsed_document.file_id, alt_file_id); + } + case telegram_api::messageMediaUnsupported::ID: + return make_unique(); + default: + break; + } + return nullptr; +} + +Result> get_input_story_content( + Td *td, td_api::object_ptr &&input_story_content, DialogId owner_dialog_id) { + LOG(INFO) << "Get input story content from " << to_string(input_story_content); + if (input_story_content == nullptr) { + return Status::Error(400, "Input story content must be non-empty"); + } + + switch (input_story_content->get_id()) { + case td_api::inputStoryContentPhoto::ID: { + auto input_story = static_cast(input_story_content.get()); + TRY_RESULT(file_id, td->file_manager_->get_input_file_id(FileType::Photo, input_story->photo_, owner_dialog_id, + false, false)); + file_id = + td->file_manager_->copy_file_id(file_id, FileType::PhotoStory, owner_dialog_id, "get_input_story_content"); + auto sticker_file_ids = + td->stickers_manager_->get_attached_sticker_file_ids(input_story->added_sticker_file_ids_); + TRY_RESULT(photo, + create_photo(td->file_manager_.get(), file_id, PhotoSize(), 720, 1280, std::move(sticker_file_ids))); + return make_unique(std::move(photo)); + } + case td_api::inputStoryContentVideo::ID: { + auto input_story = static_cast(input_story_content.get()); + TRY_RESULT(file_id, td->file_manager_->get_input_file_id(FileType::Video, input_story->video_, owner_dialog_id, + false, false)); + if (input_story->duration_ < 0 || input_story->duration_ > 60.0) { + return Status::Error(400, "Invalid video duration specified"); + } + if (input_story->cover_frame_timestamp_ < 0.0) { + return Status::Error(400, "Wrong cover timestamp specified"); + } + file_id = + td->file_manager_->copy_file_id(file_id, FileType::VideoStory, owner_dialog_id, "get_input_story_content"); + auto sticker_file_ids = + td->stickers_manager_->get_attached_sticker_file_ids(input_story->added_sticker_file_ids_); + bool has_stickers = !sticker_file_ids.empty(); + td->videos_manager_->create_video(file_id, string(), PhotoSize(), AnimationSize(), has_stickers, + std::move(sticker_file_ids), "story.mp4", "video/mp4", + static_cast(std::ceil(input_story->duration_)), input_story->duration_, + get_dimensions(720, 1280, nullptr), true, input_story->is_animation_, 0, + input_story->cover_frame_timestamp_, false); + + return make_unique(file_id, FileId()); + } + default: + UNREACHABLE(); + return nullptr; + } +} + +telegram_api::object_ptr get_story_content_input_media( + Td *td, const StoryContent *content, telegram_api::object_ptr input_file) { + switch (content->get_type()) { + case StoryContentType::Photo: { + const auto *story_content = static_cast(content); + return photo_get_input_media(td->file_manager_.get(), story_content->photo_, std::move(input_file), 0, false); + } + case StoryContentType::Video: { + const auto *story_content = static_cast(content); + return td->videos_manager_->get_input_media(story_content->file_id_, std::move(input_file), nullptr, 0, false); + } + case StoryContentType::Unsupported: + default: + UNREACHABLE(); + return nullptr; + } +} + +telegram_api::object_ptr get_story_content_document_input_media(Td *td, + const StoryContent *content, + double main_frame_timestamp) { + switch (content->get_type()) { + case StoryContentType::Video: { + const auto *story_content = static_cast(content); + return td->videos_manager_->get_story_document_input_media(story_content->file_id_, main_frame_timestamp); + } + case StoryContentType::Photo: + case StoryContentType::Unsupported: + default: + UNREACHABLE(); + return nullptr; + } +} + +void compare_story_contents(const StoryContent *old_content, const StoryContent *new_content, bool &is_content_changed, + bool &need_update) { + StoryContentType content_type = new_content->get_type(); + if (old_content->get_type() != content_type) { + need_update = true; + return; + } + + switch (content_type) { + case StoryContentType::Photo: { + const auto *old_ = static_cast(old_content); + const auto *new_ = static_cast(new_content); + if (old_->photo_ != new_->photo_) { + need_update = true; + } + break; + } + case StoryContentType::Video: { + const auto *old_ = static_cast(old_content); + const auto *new_ = static_cast(new_content); + if (old_->file_id_ != new_->file_id_ || old_->alt_file_id_ != new_->alt_file_id_) { + need_update = true; + } + break; + } + case StoryContentType::Unsupported: { + const auto *old_ = static_cast(old_content); + const auto *new_ = static_cast(new_content); + if (old_->version_ != new_->version_) { + is_content_changed = true; + } + break; + } + default: + UNREACHABLE(); + break; + } +} + +void merge_story_contents(Td *td, const StoryContent *old_content, StoryContent *new_content, DialogId dialog_id, + bool &is_content_changed, bool &need_update) { + StoryContentType content_type = new_content->get_type(); + CHECK(old_content->get_type() == content_type); + + switch (content_type) { + case StoryContentType::Photo: { + const auto *old_ = static_cast(old_content); + auto *new_ = static_cast(new_content); + merge_photos(td, &old_->photo_, &new_->photo_, dialog_id, false, is_content_changed, need_update); + break; + } + case StoryContentType::Video: { + const auto *old_ = static_cast(old_content); + const auto *new_ = static_cast(new_content); + if (old_->file_id_ != new_->file_id_ || old_->alt_file_id_ != new_->alt_file_id_) { + need_update = true; + } + break; + } + case StoryContentType::Unsupported: { + const auto *old_ = static_cast(old_content); + const auto *new_ = static_cast(new_content); + if (old_->version_ != new_->version_) { + is_content_changed = true; + } + break; + } + default: + UNREACHABLE(); + break; + } +} + +unique_ptr copy_story_content(const StoryContent *content) { + if (content == nullptr) { + return nullptr; + } + switch (content->get_type()) { + case StoryContentType::Photo: { + const auto *story_content = static_cast(content); + return make_unique(Photo(story_content->photo_)); + } + case StoryContentType::Video: { + const auto *story_content = static_cast(content); + return make_unique(story_content->file_id_, story_content->alt_file_id_); + } + case StoryContentType::Unsupported: { + const auto *story_content = static_cast(content); + return make_unique(story_content->version_); + } + default: + UNREACHABLE(); + return nullptr; + } +} + +unique_ptr dup_story_content(Td *td, const StoryContent *content) { + if (content == nullptr) { + return nullptr; + } + + auto fix_file_id = [file_manager = td->file_manager_.get()](FileId file_id) { + return file_manager->dup_file_id(file_id, "dup_story_content"); + }; + + switch (content->get_type()) { + case StoryContentType::Photo: { + const auto *old_content = static_cast(content); + auto photo = dup_photo(old_content->photo_); + photo.photos.back().file_id = fix_file_id(photo.photos.back().file_id); + if (photo.photos.size() > 1) { + photo.photos[0].file_id = fix_file_id(photo.photos[0].file_id); + } + return make_unique(std::move(photo)); + } + case StoryContentType::Video: { + const auto *old_content = static_cast(content); + return make_unique( + td->videos_manager_->dup_video(fix_file_id(old_content->file_id_), old_content->file_id_), FileId()); + } + case StoryContentType::Unsupported: + return nullptr; + default: + UNREACHABLE(); + return nullptr; + } +} + +td_api::object_ptr get_story_content_object(Td *td, const StoryContent *content) { + CHECK(content != nullptr); + switch (content->get_type()) { + case StoryContentType::Photo: { + const auto *s = static_cast(content); + auto photo = get_photo_object(td->file_manager_.get(), s->photo_); + if (photo == nullptr) { + return td_api::make_object(); + } + return td_api::make_object(std::move(photo)); + } + case StoryContentType::Video: { + const auto *s = static_cast(content); + return td_api::make_object( + td->videos_manager_->get_story_video_object(s->file_id_), + td->videos_manager_->get_story_video_object(s->alt_file_id_)); + } + case StoryContentType::Unsupported: + return td_api::make_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +FileId get_story_content_any_file_id(const StoryContent *content) { + switch (content->get_type()) { + case StoryContentType::Photo: + return get_photo_any_file_id(static_cast(content)->photo_); + case StoryContentType::Video: + return static_cast(content)->file_id_; + case StoryContentType::Unsupported: + default: + return {}; + } +} + +vector get_story_content_file_ids(const Td *td, const StoryContent *content) { + switch (content->get_type()) { + case StoryContentType::Photo: + return photo_get_file_ids(static_cast(content)->photo_); + case StoryContentType::Video: { + vector result; + const auto *s = static_cast(content); + Document(Document::Type::Video, s->file_id_).append_file_ids(td, result); + Document(Document::Type::Video, s->alt_file_id_).append_file_ids(td, result); + return result; + } + case StoryContentType::Unsupported: + default: + return {}; + } +} + +int32 get_story_content_duration(const Td *td, const StoryContent *content) { + CHECK(content != nullptr); + switch (content->get_type()) { + case StoryContentType::Video: { + auto file_id = static_cast(content)->file_id_; + return td->videos_manager_->get_video_duration(file_id); + } + default: + return -1; + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryContent.h b/protocols/Telegram/tdlib/td/td/telegram/StoryContent.h new file mode 100644 index 0000000000..6669e7436f --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryContent.h @@ -0,0 +1,75 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/logevent/LogEvent.h" +#include "td/telegram/StoryContentType.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" + +namespace td { + +class Dependencies; +class Td; + +class StoryContent { + public: + StoryContent() = default; + StoryContent(const StoryContent &) = default; + StoryContent &operator=(const StoryContent &) = default; + StoryContent(StoryContent &&) = default; + StoryContent &operator=(StoryContent &&) = default; + + virtual StoryContentType get_type() const = 0; + virtual ~StoryContent() = default; +}; + +void store_story_content(const StoryContent *content, LogEventStorerCalcLength &storer); + +void store_story_content(const StoryContent *content, LogEventStorerUnsafe &storer); + +void parse_story_content(unique_ptr &content, LogEventParser &parser); + +void add_story_content_dependencies(Dependencies &dependencies, const StoryContent *story_content); + +unique_ptr get_story_content(Td *td, telegram_api::object_ptr &&media_ptr, + DialogId owner_dialog_id); + +Result> get_input_story_content( + Td *td, td_api::object_ptr &&input_story_content, DialogId owner_dialog_id); + +telegram_api::object_ptr get_story_content_input_media( + Td *td, const StoryContent *content, telegram_api::object_ptr input_file); + +telegram_api::object_ptr get_story_content_document_input_media(Td *td, + const StoryContent *content, + double main_frame_timestamp); + +void compare_story_contents(Td *td, const StoryContent *old_content, const StoryContent *new_content, + bool &is_content_changed, bool &need_update); + +void merge_story_contents(Td *td, const StoryContent *old_content, StoryContent *new_content, DialogId dialog_id, + bool &is_content_changed, bool &need_update); + +unique_ptr copy_story_content(const StoryContent *content); + +unique_ptr dup_story_content(Td *td, const StoryContent *content); + +td_api::object_ptr get_story_content_object(Td *td, const StoryContent *content); + +FileId get_story_content_any_file_id(const StoryContent *content); + +vector get_story_content_file_ids(const Td *td, const StoryContent *content); + +int32 get_story_content_duration(const Td *td, const StoryContent *content); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryContentType.cpp b/protocols/Telegram/tdlib/td/td/telegram/StoryContentType.cpp new file mode 100644 index 0000000000..ba4ae50ab9 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryContentType.cpp @@ -0,0 +1,24 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StoryContentType.h" + +namespace td { + +StringBuilder &operator<<(StringBuilder &string_builder, StoryContentType content_type) { + switch (content_type) { + case StoryContentType::Photo: + return string_builder << "Photo"; + case StoryContentType::Video: + return string_builder << "Video"; + case StoryContentType::Unsupported: + return string_builder << "Unsupported"; + default: + return string_builder << "Invalid type " << static_cast(content_type); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryContentType.h b/protocols/Telegram/tdlib/td/td/telegram/StoryContentType.h new file mode 100644 index 0000000000..3b4491ae20 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryContentType.h @@ -0,0 +1,26 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +// increase StoryContentUnsupported::CURRENT_VERSION each time a new Story content type is added +enum class StoryContentType : int32 { Photo, Video, Unsupported }; + +StringBuilder &operator<<(StringBuilder &string_builder, StoryContentType content_type); + +struct StoryContentTypeHash { + uint32 operator()(StoryContentType content_type) const { + return Hash()(static_cast(content_type)); + } +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryDb.cpp b/protocols/Telegram/tdlib/td/td/telegram/StoryDb.cpp new file mode 100644 index 0000000000..f7b50d6e71 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryDb.cpp @@ -0,0 +1,569 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StoryDb.h" + +#include "td/telegram/StoryId.h" +#include "td/telegram/Version.h" + +#include "td/db/SqliteConnectionSafe.h" +#include "td/db/SqliteDb.h" +#include "td/db/SqliteStatement.h" + +#include "td/actor/actor.h" +#include "td/actor/SchedulerLocalStorage.h" + +#include "td/utils/format.h" +#include "td/utils/logging.h" +#include "td/utils/ScopeGuard.h" +#include "td/utils/StringBuilder.h" +#include "td/utils/Time.h" + +#include + +namespace td { + +// NB: must happen inside a transaction +Status init_story_db(SqliteDb &db, int32 version) { + LOG(INFO) << "Init story database " << tag("version", version); + + // Check if database exists + TRY_RESULT(has_stories_table, db.has_table("stories")); + TRY_RESULT(has_active_stories_table, db.has_table("active_stories")); + TRY_RESULT(has_story_list_table, db.has_table("active_story_lists")); + if ((!has_stories_table || !has_active_stories_table || !has_story_list_table) || version > current_db_version()) { + TRY_STATUS(drop_story_db(db, version)); + version = 0; + } + + if (version == 0) { + LOG(INFO) << "Create new story database"; + TRY_STATUS( + db.exec("CREATE TABLE IF NOT EXISTS stories (dialog_id INT8, story_id INT4, expires_at INT4, notification_id " + "INT4, data BLOB, PRIMARY KEY (dialog_id, story_id))")); + + TRY_STATUS(db.exec("CREATE INDEX IF NOT EXISTS story_by_ttl ON stories (expires_at) WHERE expires_at IS NOT NULL")); + + TRY_STATUS( + db.exec("CREATE INDEX IF NOT EXISTS story_by_notification_id ON stories (dialog_id, notification_id) WHERE " + "notification_id IS NOT NULL")); + + TRY_STATUS( + db.exec("CREATE TABLE IF NOT EXISTS active_stories (dialog_id INT8 PRIMARY KEY, story_list_id INT4, " + "dialog_order INT8, data BLOB)")); + + TRY_STATUS( + db.exec("CREATE INDEX IF NOT EXISTS active_stories_by_order ON active_stories (story_list_id, dialog_order, " + "dialog_id) WHERE story_list_id IS NOT NULL")); + + TRY_STATUS(db.exec("CREATE TABLE IF NOT EXISTS active_story_lists (story_list_id INT4 PRIMARY KEY, data BLOB)")); + + version = current_db_version(); + } + return Status::OK(); +} + +// NB: must happen inside a transaction +Status drop_story_db(SqliteDb &db, int32 version) { + if (version != 0) { + LOG(WARNING) << "Drop story database " << tag("version", version) + << tag("current_db_version", current_db_version()); + } + auto status = db.exec("DROP TABLE IF EXISTS stories"); + TRY_STATUS(db.exec("DROP TABLE IF EXISTS active_stories")); + TRY_STATUS(db.exec("DROP TABLE IF EXISTS active_story_lists")); + return status; +} + +class StoryDbImpl final : public StoryDbSyncInterface { + public: + explicit StoryDbImpl(SqliteDb db) : db_(std::move(db)) { + init().ensure(); + } + + Status init() { + TRY_RESULT_ASSIGN(add_story_stmt_, db_.get_statement("INSERT OR REPLACE INTO stories VALUES(?1, ?2, ?3, ?4, ?5)")); + + TRY_RESULT_ASSIGN(delete_story_stmt_, + db_.get_statement("DELETE FROM stories WHERE dialog_id = ?1 AND story_id = ?2")); + + TRY_RESULT_ASSIGN(get_story_stmt_, + db_.get_statement("SELECT data FROM stories WHERE dialog_id = ?1 AND story_id = ?2")); + + TRY_RESULT_ASSIGN( + get_expiring_stories_stmt_, + db_.get_statement("SELECT dialog_id, story_id, data FROM stories WHERE expires_at <= ?1 LIMIT ?2")); + + TRY_RESULT_ASSIGN(get_stories_from_notification_id_stmt_, + db_.get_statement("SELECT story_id, data FROM stories WHERE dialog_id = ?1 AND " + "notification_id < ?2 ORDER BY notification_id DESC LIMIT ?3")); + + TRY_RESULT_ASSIGN(add_active_stories_stmt_, + db_.get_statement("INSERT OR REPLACE INTO active_stories VALUES(?1, ?2, ?3, ?4)")); + + TRY_RESULT_ASSIGN(delete_active_stories_stmt_, + db_.get_statement("DELETE FROM active_stories WHERE dialog_id = ?1")); + + TRY_RESULT_ASSIGN( + get_active_story_list_stmt_, + db_.get_statement("SELECT data, dialog_id, dialog_order FROM active_stories WHERE " + "story_list_id = ?1 AND (dialog_order < ?2 OR (dialog_order = ?2 AND dialog_id < ?3)) ORDER " + "BY dialog_order DESC, dialog_id DESC LIMIT ?4")); + + TRY_RESULT_ASSIGN(get_active_stories_stmt_, + db_.get_statement("SELECT data FROM active_stories WHERE dialog_id = ?1")); + + TRY_RESULT_ASSIGN(add_active_story_list_state_stmt_, + db_.get_statement("INSERT OR REPLACE INTO active_story_lists VALUES(?1, ?2)")); + + TRY_RESULT_ASSIGN(get_active_story_list_state_stmt_, + db_.get_statement("SELECT data FROM active_story_lists WHERE story_list_id = ?1")); + + return Status::OK(); + } + + void add_story(StoryFullId story_full_id, int32 expires_at, NotificationId notification_id, BufferSlice data) final { + LOG(INFO) << "Add " << story_full_id << " to database"; + CHECK(story_full_id.is_server()); + auto dialog_id = story_full_id.get_dialog_id(); + auto story_id = story_full_id.get_story_id(); + SCOPE_EXIT { + add_story_stmt_.reset(); + }; + + add_story_stmt_.bind_int64(1, dialog_id.get()).ensure(); + add_story_stmt_.bind_int32(2, story_id.get()).ensure(); + if (expires_at != 0) { + add_story_stmt_.bind_int32(3, expires_at).ensure(); + } else { + add_story_stmt_.bind_null(3).ensure(); + } + if (notification_id.is_valid()) { + add_story_stmt_.bind_int32(4, notification_id.get()).ensure(); + } else { + add_story_stmt_.bind_null(4).ensure(); + } + add_story_stmt_.bind_blob(5, data.as_slice()).ensure(); + + add_story_stmt_.step().ensure(); + } + + void delete_story(StoryFullId story_full_id) final { + LOG(INFO) << "Delete " << story_full_id << " from database"; + CHECK(story_full_id.is_valid()); + auto dialog_id = story_full_id.get_dialog_id(); + auto story_id = story_full_id.get_story_id(); + SCOPE_EXIT { + delete_story_stmt_.reset(); + }; + delete_story_stmt_.bind_int64(1, dialog_id.get()).ensure(); + delete_story_stmt_.bind_int32(2, story_id.get()).ensure(); + delete_story_stmt_.step().ensure(); + } + + Result get_story(StoryFullId story_full_id) final { + CHECK(story_full_id.is_server()); + auto dialog_id = story_full_id.get_dialog_id(); + auto story_id = story_full_id.get_story_id(); + SCOPE_EXIT { + get_story_stmt_.reset(); + }; + + get_story_stmt_.bind_int64(1, dialog_id.get()).ensure(); + get_story_stmt_.bind_int32(2, story_id.get()).ensure(); + get_story_stmt_.step().ensure(); + if (!get_story_stmt_.has_row()) { + return Status::Error("Not found"); + } + return BufferSlice(get_story_stmt_.view_blob(0)); + } + + vector get_expiring_stories(int32 expires_till, int32 limit) final { + auto &stmt = get_expiring_stories_stmt_; + SCOPE_EXIT { + stmt.reset(); + }; + + stmt.bind_int32(1, expires_till).ensure(); + stmt.bind_int32(2, limit).ensure(); + stmt.step().ensure(); + + vector stories; + while (stmt.has_row()) { + DialogId dialog_id(stmt.view_int64(0)); + StoryId story_id(stmt.view_int32(1)); + BufferSlice data(stmt.view_blob(2)); + stories.emplace_back(StoryFullId{dialog_id, story_id}, std::move(data)); + stmt.step().ensure(); + } + + return stories; + } + + vector get_stories_from_notification_id(DialogId dialog_id, NotificationId from_notification_id, + int32 limit) final { + auto &stmt = get_stories_from_notification_id_stmt_; + SCOPE_EXIT { + stmt.reset(); + }; + stmt.bind_int64(1, dialog_id.get()).ensure(); + stmt.bind_int32(2, from_notification_id.get()).ensure(); + stmt.bind_int32(3, limit).ensure(); + stmt.step().ensure(); + + vector stories; + while (stmt.has_row()) { + StoryId story_id(stmt.view_int32(0)); + BufferSlice data(stmt.view_blob(1)); + stories.emplace_back(StoryFullId{dialog_id, story_id}, std::move(data)); + stmt.step().ensure(); + } + return stories; + } + + void add_active_stories(DialogId dialog_id, StoryListId story_list_id, int64 dialog_order, BufferSlice data) final { + SCOPE_EXIT { + add_active_stories_stmt_.reset(); + }; + add_active_stories_stmt_.bind_int64(1, dialog_id.get()).ensure(); + if (story_list_id.is_valid()) { + add_active_stories_stmt_.bind_int32(2, story_list_id == StoryListId::archive() ? 1 : 0).ensure(); + } else { + add_active_stories_stmt_.bind_null(2).ensure(); + } + add_active_stories_stmt_.bind_int64(3, dialog_order).ensure(); + add_active_stories_stmt_.bind_blob(4, data.as_slice()).ensure(); + add_active_stories_stmt_.step().ensure(); + } + + void delete_active_stories(DialogId dialog_id) final { + SCOPE_EXIT { + delete_active_stories_stmt_.reset(); + }; + delete_active_stories_stmt_.bind_int64(1, dialog_id.get()).ensure(); + delete_active_stories_stmt_.step().ensure(); + } + + Result get_active_stories(DialogId dialog_id) final { + SCOPE_EXIT { + get_active_stories_stmt_.reset(); + }; + + get_active_stories_stmt_.bind_int64(1, dialog_id.get()).ensure(); + get_active_stories_stmt_.step().ensure(); + if (!get_active_stories_stmt_.has_row()) { + return Status::Error("Not found"); + } + return BufferSlice(get_active_stories_stmt_.view_blob(0)); + } + + StoryDbGetActiveStoryListResult get_active_story_list(StoryListId story_list_id, int64 order, DialogId dialog_id, + int32 limit) final { + SCOPE_EXIT { + get_active_story_list_stmt_.reset(); + }; + + get_active_story_list_stmt_.bind_int32(1, story_list_id == StoryListId::archive() ? 1 : 0).ensure(); + get_active_story_list_stmt_.bind_int64(2, order).ensure(); + get_active_story_list_stmt_.bind_int64(3, dialog_id.get()).ensure(); + get_active_story_list_stmt_.bind_int32(4, limit).ensure(); + + StoryDbGetActiveStoryListResult result; + result.next_dialog_id_ = dialog_id; + result.next_order_ = order; + get_active_story_list_stmt_.step().ensure(); + while (get_active_story_list_stmt_.has_row()) { + BufferSlice data(get_active_story_list_stmt_.view_blob(0)); + result.next_dialog_id_ = DialogId(get_active_story_list_stmt_.view_int64(1)); + result.next_order_ = get_active_story_list_stmt_.view_int64(2); + LOG(INFO) << "Load active stories in " << result.next_dialog_id_ << " with order " << result.next_order_; + result.active_stories_.emplace_back(result.next_dialog_id_, std::move(data)); + get_active_story_list_stmt_.step().ensure(); + } + + return result; + } + + void add_active_story_list_state(StoryListId story_list_id, BufferSlice data) final { + SCOPE_EXIT { + add_active_story_list_state_stmt_.reset(); + }; + add_active_story_list_state_stmt_.bind_int32(1, story_list_id == StoryListId::archive() ? 1 : 0).ensure(); + add_active_story_list_state_stmt_.bind_blob(2, data.as_slice()).ensure(); + add_active_story_list_state_stmt_.step().ensure(); + } + + Result get_active_story_list_state(StoryListId story_list_id) final { + SCOPE_EXIT { + get_active_story_list_state_stmt_.reset(); + }; + + get_active_story_list_state_stmt_.bind_int64(1, story_list_id == StoryListId::archive() ? 1 : 0).ensure(); + get_active_story_list_state_stmt_.step().ensure(); + if (!get_active_story_list_state_stmt_.has_row()) { + return Status::Error("Not found"); + } + return BufferSlice(get_active_story_list_state_stmt_.view_blob(0)); + } + + Status begin_write_transaction() final { + return db_.begin_write_transaction(); + } + Status commit_transaction() final { + return db_.commit_transaction(); + } + + private: + SqliteDb db_; + + SqliteStatement add_story_stmt_; + SqliteStatement delete_story_stmt_; + SqliteStatement get_story_stmt_; + SqliteStatement get_expiring_stories_stmt_; + SqliteStatement get_stories_from_notification_id_stmt_; + + SqliteStatement add_active_stories_stmt_; + SqliteStatement delete_active_stories_stmt_; + SqliteStatement get_active_stories_stmt_; + SqliteStatement get_active_story_list_stmt_; + + SqliteStatement add_active_story_list_state_stmt_; + SqliteStatement get_active_story_list_state_stmt_; +}; + +std::shared_ptr create_story_db_sync( + std::shared_ptr sqlite_connection) { + class StoryDbSyncSafe final : public StoryDbSyncSafeInterface { + public: + explicit StoryDbSyncSafe(std::shared_ptr sqlite_connection) + : lsls_db_([safe_connection = std::move(sqlite_connection)] { + return make_unique(safe_connection->get().clone()); + }) { + } + StoryDbSyncInterface &get() final { + return *lsls_db_.get(); + } + + private: + LazySchedulerLocalStorage> lsls_db_; + }; + return std::make_shared(std::move(sqlite_connection)); +} + +class StoryDbAsync final : public StoryDbAsyncInterface { + public: + StoryDbAsync(std::shared_ptr sync_db, int32 scheduler_id) { + impl_ = create_actor_on_scheduler("StoryDbActor", scheduler_id, std::move(sync_db)); + } + + void add_story(StoryFullId story_full_id, int32 expires_at, NotificationId notification_id, BufferSlice data, + Promise promise) final { + send_closure_later(impl_, &Impl::add_story, story_full_id, expires_at, notification_id, std::move(data), + std::move(promise)); + } + + void delete_story(StoryFullId story_full_id, Promise promise) final { + send_closure_later(impl_, &Impl::delete_story, story_full_id, std::move(promise)); + } + + void get_story(StoryFullId story_full_id, Promise promise) final { + send_closure_later(impl_, &Impl::get_story, story_full_id, std::move(promise)); + } + + void get_expiring_stories(int32 expires_till, int32 limit, Promise> promise) final { + send_closure_later(impl_, &Impl::get_expiring_stories, expires_till, limit, std::move(promise)); + } + + void get_stories_from_notification_id(DialogId dialog_id, NotificationId from_notification_id, int32 limit, + Promise> promise) final { + send_closure_later(impl_, &Impl::get_stories_from_notification_id, dialog_id, from_notification_id, limit, + std::move(promise)); + } + + void add_active_stories(DialogId dialog_id, StoryListId story_list_id, int64 dialog_order, BufferSlice data, + Promise promise) final { + send_closure_later(impl_, &Impl::add_active_stories, dialog_id, story_list_id, dialog_order, std::move(data), + std::move(promise)); + } + + void delete_active_stories(DialogId dialog_id, Promise promise) final { + send_closure_later(impl_, &Impl::delete_active_stories, dialog_id, std::move(promise)); + } + + void get_active_stories(DialogId dialog_id, Promise promise) final { + send_closure_later(impl_, &Impl::get_active_stories, dialog_id, std::move(promise)); + } + + void get_active_story_list(StoryListId story_list_id, int64 order, DialogId dialog_id, int32 limit, + Promise promise) final { + send_closure_later(impl_, &Impl::get_active_story_list, story_list_id, order, dialog_id, limit, std::move(promise)); + } + + void add_active_story_list_state(StoryListId story_list_id, BufferSlice data, Promise promise) final { + send_closure_later(impl_, &Impl::add_active_story_list_state, story_list_id, std::move(data), std::move(promise)); + } + + void get_active_story_list_state(StoryListId story_list_id, Promise promise) final { + send_closure_later(impl_, &Impl::get_active_story_list_state, story_list_id, std::move(promise)); + } + + void close(Promise promise) final { + send_closure_later(impl_, &Impl::close, std::move(promise)); + } + + void force_flush() final { + send_closure_later(impl_, &Impl::force_flush); + } + + private: + class Impl final : public Actor { + public: + explicit Impl(std::shared_ptr sync_db_safe) : sync_db_safe_(std::move(sync_db_safe)) { + } + void add_story(StoryFullId story_full_id, int32 expires_at, NotificationId notification_id, BufferSlice data, + Promise promise) { + add_write_query([this, story_full_id, expires_at, notification_id, data = std::move(data), + promise = std::move(promise)](Unit) mutable { + sync_db_->add_story(story_full_id, expires_at, notification_id, std::move(data)); + on_write_result(std::move(promise)); + }); + } + + void delete_story(StoryFullId story_full_id, Promise promise) { + add_write_query([this, story_full_id, promise = std::move(promise)](Unit) mutable { + sync_db_->delete_story(story_full_id); + on_write_result(std::move(promise)); + }); + } + + void on_write_result(Promise &&promise) { + // We are inside a transaction and don't know how to handle errors + finished_writes_.push_back(std::move(promise)); + } + + void get_story(StoryFullId story_full_id, Promise promise) { + add_read_query(); + promise.set_result(sync_db_->get_story(story_full_id)); + } + + void get_expiring_stories(int32 expires_till, int32 limit, Promise> promise) { + add_read_query(); + promise.set_value(sync_db_->get_expiring_stories(expires_till, limit)); + } + + void get_stories_from_notification_id(DialogId dialog_id, NotificationId from_notification_id, int32 limit, + Promise> promise) { + add_read_query(); + promise.set_value(sync_db_->get_stories_from_notification_id(dialog_id, from_notification_id, limit)); + } + + void add_active_stories(DialogId dialog_id, StoryListId story_list_id, int64 dialog_order, BufferSlice data, + Promise promise) { + add_write_query([this, dialog_id, story_list_id, dialog_order, data = std::move(data), + promise = std::move(promise)](Unit) mutable { + sync_db_->add_active_stories(dialog_id, story_list_id, dialog_order, std::move(data)); + on_write_result(std::move(promise)); + }); + } + + void delete_active_stories(DialogId dialog_id, Promise promise) { + add_write_query([this, dialog_id, promise = std::move(promise)](Unit) mutable { + sync_db_->delete_active_stories(dialog_id); + on_write_result(std::move(promise)); + }); + } + + void get_active_stories(DialogId dialog_id, Promise promise) { + add_read_query(); + promise.set_result(sync_db_->get_active_stories(dialog_id)); + } + + void get_active_story_list(StoryListId story_list_id, int64 order, DialogId dialog_id, int32 limit, + Promise promise) { + add_read_query(); + promise.set_value(sync_db_->get_active_story_list(story_list_id, order, dialog_id, limit)); + } + + void add_active_story_list_state(StoryListId story_list_id, BufferSlice data, Promise promise) { + add_write_query([this, story_list_id, data = std::move(data), promise = std::move(promise)](Unit) mutable { + sync_db_->add_active_story_list_state(story_list_id, std::move(data)); + on_write_result(std::move(promise)); + }); + } + + void get_active_story_list_state(StoryListId story_list_id, Promise promise) { + add_read_query(); + promise.set_result(sync_db_->get_active_story_list_state(story_list_id)); + } + + void close(Promise promise) { + do_flush(); + sync_db_safe_.reset(); + sync_db_ = nullptr; + promise.set_value(Unit()); + stop(); + } + + void force_flush() { + do_flush(); + LOG(INFO) << "StoryDb flushed"; + } + + private: + std::shared_ptr sync_db_safe_; + StoryDbSyncInterface *sync_db_ = nullptr; + + static constexpr size_t MAX_PENDING_QUERIES_COUNT{50}; + static constexpr double MAX_PENDING_QUERIES_DELAY{0.01}; + + //NB: order is important, destructor of pending_writes_ will change finished_writes_ + vector> finished_writes_; + vector> pending_writes_; // TODO use Action + double wakeup_at_ = 0; + + template + void add_write_query(F &&f) { + pending_writes_.push_back(PromiseCreator::lambda(std::forward(f))); + if (pending_writes_.size() > MAX_PENDING_QUERIES_COUNT) { + do_flush(); + wakeup_at_ = 0; + } else if (wakeup_at_ == 0) { + wakeup_at_ = Time::now_cached() + MAX_PENDING_QUERIES_DELAY; + } + if (wakeup_at_ != 0) { + set_timeout_at(wakeup_at_); + } + } + void add_read_query() { + do_flush(); + } + void do_flush() { + if (pending_writes_.empty()) { + return; + } + sync_db_->begin_write_transaction().ensure(); + set_promises(pending_writes_); + sync_db_->commit_transaction().ensure(); + set_promises(finished_writes_); + cancel_timeout(); + } + void timeout_expired() final { + do_flush(); + } + + void start_up() final { + sync_db_ = &sync_db_safe_->get(); + } + }; + ActorOwn impl_; +}; + +std::shared_ptr create_story_db_async(std::shared_ptr sync_db, + int32 scheduler_id) { + return std::make_shared(std::move(sync_db), scheduler_id); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryDb.h b/protocols/Telegram/tdlib/td/td/telegram/StoryDb.h new file mode 100644 index 0000000000..46544646d7 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryDb.h @@ -0,0 +1,133 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/NotificationId.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/StoryListId.h" + +#include "td/utils/buffer.h" +#include "td/utils/common.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" + +#include +#include + +namespace td { + +class SqliteConnectionSafe; +class SqliteDb; + +struct StoryDbStory { + StoryFullId story_full_id_; + BufferSlice data_; + + StoryDbStory(StoryFullId story_full_id, BufferSlice &&data) : story_full_id_(story_full_id), data_(std::move(data)) { + } +}; + +struct StoryDbGetActiveStoryListResult { + vector> active_stories_; + int64 next_order_ = 0; + DialogId next_dialog_id_; +}; + +class StoryDbSyncInterface { + public: + StoryDbSyncInterface() = default; + StoryDbSyncInterface(const StoryDbSyncInterface &) = delete; + StoryDbSyncInterface &operator=(const StoryDbSyncInterface &) = delete; + virtual ~StoryDbSyncInterface() = default; + + virtual void add_story(StoryFullId story_full_id, int32 expires_at, NotificationId notification_id, + BufferSlice data) = 0; + + virtual void delete_story(StoryFullId story_full_id) = 0; + + virtual Result get_story(StoryFullId story_full_id) = 0; + + virtual vector get_expiring_stories(int32 expires_till, int32 limit) = 0; + + virtual vector get_stories_from_notification_id(DialogId dialog_id, NotificationId from_notification_id, + int32 limit) = 0; + + virtual void add_active_stories(DialogId dialog_id, StoryListId story_list_id, int64 dialog_order, + BufferSlice data) = 0; + + virtual void delete_active_stories(DialogId dialog_id) = 0; + + virtual Result get_active_stories(DialogId dialog_id) = 0; + + virtual StoryDbGetActiveStoryListResult get_active_story_list(StoryListId story_list_id, int64 order, + DialogId dialog_id, int32 limit) = 0; + + virtual void add_active_story_list_state(StoryListId story_list_id, BufferSlice data) = 0; + + virtual Result get_active_story_list_state(StoryListId story_list_id) = 0; + + virtual Status begin_write_transaction() = 0; + virtual Status commit_transaction() = 0; +}; + +class StoryDbSyncSafeInterface { + public: + StoryDbSyncSafeInterface() = default; + StoryDbSyncSafeInterface(const StoryDbSyncSafeInterface &) = delete; + StoryDbSyncSafeInterface &operator=(const StoryDbSyncSafeInterface &) = delete; + virtual ~StoryDbSyncSafeInterface() = default; + + virtual StoryDbSyncInterface &get() = 0; +}; + +class StoryDbAsyncInterface { + public: + StoryDbAsyncInterface() = default; + StoryDbAsyncInterface(const StoryDbAsyncInterface &) = delete; + StoryDbAsyncInterface &operator=(const StoryDbAsyncInterface &) = delete; + virtual ~StoryDbAsyncInterface() = default; + + virtual void add_story(StoryFullId story_full_id, int32 expires_at, NotificationId notification_id, BufferSlice data, + Promise promise) = 0; + + virtual void delete_story(StoryFullId story_full_id, Promise promise) = 0; + + virtual void get_story(StoryFullId story_full_id, Promise promise) = 0; + + virtual void get_expiring_stories(int32 expires_till, int32 limit, Promise> promise) = 0; + + virtual void get_stories_from_notification_id(DialogId dialog_id, NotificationId from_notification_id, int32 limit, + Promise> promise) = 0; + + virtual void add_active_stories(DialogId dialog_id, StoryListId story_list_id, int64 dialog_order, BufferSlice data, + Promise promise) = 0; + + virtual void delete_active_stories(DialogId dialog_id, Promise promise) = 0; + + virtual void get_active_stories(DialogId dialog_id, Promise promise) = 0; + + virtual void get_active_story_list(StoryListId story_list_id, int64 order, DialogId dialog_id, int32 limit, + Promise promise) = 0; + + virtual void add_active_story_list_state(StoryListId story_list_id, BufferSlice data, Promise promise) = 0; + + virtual void get_active_story_list_state(StoryListId story_list_id, Promise promise) = 0; + + virtual void close(Promise promise) = 0; + virtual void force_flush() = 0; +}; + +Status init_story_db(SqliteDb &db, int version) TD_WARN_UNUSED_RESULT; +Status drop_story_db(SqliteDb &db, int version) TD_WARN_UNUSED_RESULT; + +std::shared_ptr create_story_db_sync(std::shared_ptr sqlite_connection); + +std::shared_ptr create_story_db_async(std::shared_ptr sync_db, + int32 scheduler_id = -1); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.cpp new file mode 100644 index 0000000000..b86bfeded2 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.cpp @@ -0,0 +1,71 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StoryForwardInfo.h" + +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/Td.h" + +#include "td/utils/logging.h" + +namespace td { + +StoryForwardInfo::StoryForwardInfo(Td *td, telegram_api::object_ptr &&fwd_header) { + CHECK(fwd_header != nullptr); + is_modified_ = fwd_header->modified_; + if (fwd_header->from_ != nullptr) { + dialog_id_ = DialogId(fwd_header->from_); + story_id_ = StoryId(fwd_header->story_id_); + if (!dialog_id_.is_valid() || !story_id_.is_server()) { + LOG(ERROR) << "Receive " << to_string(fwd_header); + dialog_id_ = {}; + story_id_ = {}; + } else { + td->dialog_manager_->force_create_dialog(dialog_id_, "StoryForwardInfo", true); + } + } else if ((fwd_header->flags_ & telegram_api::storyFwdHeader::FROM_NAME_MASK) != 0) { + if (fwd_header->story_id_ != 0) { + LOG(ERROR) << "Receive " << to_string(fwd_header); + } + sender_name_ = std::move(fwd_header->from_name_); + } else { + LOG(ERROR) << "Receive " << to_string(fwd_header); + } +} + +void StoryForwardInfo::hide_sender_if_needed(Td *td) { + // currently, there is no need to hide sender client-side +} + +void StoryForwardInfo::add_dependencies(Dependencies &dependencies) const { + // don't try to load original story + dependencies.add_dialog_and_dependencies(dialog_id_); +} + +td_api::object_ptr StoryForwardInfo::get_story_repost_info_object(Td *td) const { + auto origin = [&]() -> td_api::object_ptr { + if (dialog_id_.is_valid() && story_id_.is_valid()) { + return td_api::make_object( + td->dialog_manager_->get_chat_id_object(dialog_id_, "storyOriginPublicStory"), story_id_.get()); + } + return td_api::make_object(sender_name_); + }(); + return td_api::make_object(std::move(origin), is_modified_); +} + +bool operator==(const unique_ptr &lhs, const unique_ptr &rhs) { + if (lhs == nullptr) { + return rhs == nullptr; + } + if (rhs == nullptr) { + return false; + } + return lhs->dialog_id_ == rhs->dialog_id_ && lhs->story_id_ == rhs->story_id_ && + lhs->sender_name_ == rhs->sender_name_ && lhs->is_modified_ == rhs->is_modified_; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.h b/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.h new file mode 100644 index 0000000000..f464c15c48 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.h @@ -0,0 +1,60 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" + +#include + +namespace td { + +class Dependencies; +class Td; + +class StoryForwardInfo { + DialogId dialog_id_; + StoryId story_id_; + string sender_name_; + bool is_modified_ = false; + + friend bool operator==(const unique_ptr &lhs, const unique_ptr &rhs); + + public: + StoryForwardInfo() = default; + + StoryForwardInfo(Td *td, telegram_api::object_ptr &&fwd_header); + + StoryForwardInfo(StoryFullId story_full_id, bool is_modified) + : dialog_id_(story_full_id.get_dialog_id()), story_id_(story_full_id.get_story_id()), is_modified_(is_modified) { + } + + void hide_sender_if_needed(Td *td); + + void add_dependencies(Dependencies &dependencies) const; + + td_api::object_ptr get_story_repost_info_object(Td *td) const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const unique_ptr &lhs, const unique_ptr &rhs); + +inline bool operator!=(const unique_ptr &lhs, const unique_ptr &rhs) { + return !(lhs == rhs); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.hpp b/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.hpp new file mode 100644 index 0000000000..8df22c98cc --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryForwardInfo.hpp @@ -0,0 +1,62 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/StoryForwardInfo.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void StoryForwardInfo::store(StorerT &storer) const { + using td::store; + bool has_dialog_id = dialog_id_.is_valid(); + bool has_story_id = story_id_.is_valid(); + bool has_sender_name = !sender_name_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_dialog_id); + STORE_FLAG(has_story_id); + STORE_FLAG(has_sender_name); + STORE_FLAG(is_modified_); + END_STORE_FLAGS(); + if (has_dialog_id) { + store(dialog_id_, storer); + } + if (has_story_id) { + store(story_id_, storer); + } + if (has_sender_name) { + store(sender_name_, storer); + } +} + +template +void StoryForwardInfo::parse(ParserT &parser) { + using td::parse; + bool has_dialog_id; + bool has_story_id; + bool has_sender_name; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_dialog_id); + PARSE_FLAG(has_story_id); + PARSE_FLAG(has_sender_name); + PARSE_FLAG(is_modified_); + END_PARSE_FLAGS(); + if (has_dialog_id) { + parse(dialog_id_, parser); + } + if (has_story_id) { + parse(story_id_, parser); + } + if (has_sender_name) { + parse(sender_name_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryFullId.h b/protocols/Telegram/tdlib/td/td/telegram/StoryFullId.h new file mode 100644 index 0000000000..95753b328b --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryFullId.h @@ -0,0 +1,77 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/StoryId.h" + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +struct StoryFullId { + private: + DialogId dialog_id; + StoryId story_id; + + public: + StoryFullId() : dialog_id(), story_id() { + } + + StoryFullId(DialogId dialog_id, StoryId story_id) : dialog_id(dialog_id), story_id(story_id) { + } + + bool operator==(const StoryFullId &other) const { + return dialog_id == other.dialog_id && story_id == other.story_id; + } + + bool operator!=(const StoryFullId &other) const { + return !(*this == other); + } + + DialogId get_dialog_id() const { + return dialog_id; + } + + StoryId get_story_id() const { + return story_id; + } + + bool is_valid() const { + return dialog_id.is_valid() && story_id.is_valid(); + } + + bool is_server() const { + return dialog_id.is_valid() && story_id.is_server(); + } + + template + void store(StorerT &storer) const { + dialog_id.store(storer); + story_id.store(storer); + } + + template + void parse(ParserT &parser) { + dialog_id.parse(parser); + story_id.parse(parser); + } +}; + +struct StoryFullIdHash { + uint32 operator()(StoryFullId story_full_id) const { + return combine_hashes(DialogIdHash()(story_full_id.get_dialog_id()), StoryIdHash()(story_full_id.get_story_id())); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, StoryFullId story_full_id) { + return string_builder << story_full_id.get_story_id() << " in " << story_full_id.get_dialog_id(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryId.h b/protocols/Telegram/tdlib/td/td/telegram/StoryId.h new file mode 100644 index 0000000000..66db93385c --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryId.h @@ -0,0 +1,90 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" +#include "td/utils/tl_helpers.h" + +#include + +namespace td { + +class StoryId { + int32 id = 0; + + public: + static constexpr int32 MAX_SERVER_STORY_ID = 1999999999; + + StoryId() = default; + + explicit constexpr StoryId(int32 story_id) : id(story_id) { + } + template ::value>> + StoryId(T story_id) = delete; + + static vector get_input_story_ids(const vector &story_ids) { + vector input_story_ids; + input_story_ids.reserve(story_ids.size()); + for (auto &story_id : story_ids) { + input_story_ids.emplace_back(story_id.get()); + } + return input_story_ids; + } + + static vector get_story_ids(const vector &input_story_ids) { + vector story_ids; + story_ids.reserve(input_story_ids.size()); + for (auto &input_story_id : input_story_ids) { + story_ids.emplace_back(input_story_id); + } + return story_ids; + } + + int32 get() const { + return id; + } + + bool operator==(const StoryId &other) const { + return id == other.id; + } + + bool operator!=(const StoryId &other) const { + return id != other.id; + } + + bool is_valid() const { + return id > 0; + } + + bool is_server() const { + return id > 0 && id <= MAX_SERVER_STORY_ID; + } + + template + void store(StorerT &storer) const { + td::store(id, storer); + } + + template + void parse(ParserT &parser) { + td::parse(id, parser); + } +}; + +struct StoryIdHash { + uint32 operator()(StoryId story_id) const { + return Hash()(story_id.get()); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, StoryId story_id) { + return string_builder << "story " << story_id.get(); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.cpp new file mode 100644 index 0000000000..5b52529b76 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.cpp @@ -0,0 +1,154 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StoryInteractionInfo.h" + +#include "td/telegram/Dependencies.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/FlatHashSet.h" +#include "td/utils/logging.h" + +#include + +namespace td { + +StoryInteractionInfo::StoryInteractionInfo(Td *td, telegram_api::object_ptr &&story_views) { + if (story_views == nullptr) { + return; + } + for (auto &viewer_id : story_views->recent_viewers_) { + UserId user_id(viewer_id); + if (user_id.is_valid() && td->user_manager_->have_min_user(user_id)) { + if (recent_viewer_user_ids_.size() == MAX_RECENT_VIEWERS) { + LOG(ERROR) << "Receive too many recent story viewers: " << story_views->recent_viewers_; + break; + } + recent_viewer_user_ids_.push_back(user_id); + } else { + LOG(ERROR) << "Receive " << user_id << " as recent viewer"; + } + } + view_count_ = story_views->views_count_; + if (view_count_ < 0) { + LOG(ERROR) << "Receive " << view_count_ << " story views"; + view_count_ = 0; + } + forward_count_ = story_views->forwards_count_; + if (forward_count_ < 0) { + LOG(ERROR) << "Receive " << forward_count_ << " story forwards"; + forward_count_ = 0; + } + reaction_count_ = story_views->reactions_count_; + if (reaction_count_ < 0) { + LOG(ERROR) << "Receive " << reaction_count_ << " story reactions"; + reaction_count_ = 0; + } + has_viewers_ = story_views->has_viewers_; + + FlatHashSet added_reaction_types; + for (auto &reaction : story_views->reactions_) { + ReactionType reaction_type(reaction->reaction_); + if (reaction_type.is_empty() || reaction_type.is_paid_reaction()) { + LOG(ERROR) << "Receive " << to_string(reaction); + continue; + } + if (!added_reaction_types.insert(reaction_type).second) { + LOG(ERROR) << "Receive again " << to_string(reaction); + continue; + } + if (reaction->count_ == 0) { + LOG(ERROR) << "Receive " << to_string(reaction); + continue; + } + reaction_counts_.emplace_back(std::move(reaction_type), reaction->count_); + } + std::sort(reaction_counts_.begin(), reaction_counts_.end()); +} + +void StoryInteractionInfo::add_dependencies(Dependencies &dependencies) const { + for (auto user_id : recent_viewer_user_ids_) { + dependencies.add(user_id); + } +} + +void StoryInteractionInfo::set_chosen_reaction_type(const ReactionType &new_reaction_type, + const ReactionType &old_reaction_type) { + if (!old_reaction_type.is_empty()) { + CHECK(!old_reaction_type.is_paid_reaction()); + for (auto it = reaction_counts_.begin(); it != reaction_counts_.end(); ++it) { + if (it->first == old_reaction_type) { + it->second--; + if (it->second == 0) { + reaction_counts_.erase(it); + } + break; + } + } + } + if (!new_reaction_type.is_empty()) { + CHECK(!new_reaction_type.is_paid_reaction()); + bool is_found = false; + for (auto it = reaction_counts_.begin(); it != reaction_counts_.end(); ++it) { + if (it->first == old_reaction_type) { + it->second++; + is_found = true; + } + } + if (!is_found) { + reaction_counts_.emplace_back(new_reaction_type, 1); + } + } + std::sort(reaction_counts_.begin(), reaction_counts_.end()); +} + +bool StoryInteractionInfo::set_recent_viewer_user_ids(vector &&user_ids) { + if (recent_viewer_user_ids_.empty() && view_count_ > 0) { + // don't update recent viewers for stories with expired viewers + return false; + } + if (user_ids.size() > MAX_RECENT_VIEWERS) { + user_ids.resize(MAX_RECENT_VIEWERS); + } + if (recent_viewer_user_ids_.size() < user_ids.size() && user_ids.size() <= static_cast(view_count_)) { + return false; + } + if (recent_viewer_user_ids_ != user_ids) { + recent_viewer_user_ids_ = std::move(user_ids); + return true; + } + return false; +} + +bool StoryInteractionInfo::definitely_has_no_user(UserId user_id) const { + return !is_empty() && view_count_ == static_cast(recent_viewer_user_ids_.size()) && + !contains(recent_viewer_user_ids_, user_id); +} + +td_api::object_ptr StoryInteractionInfo::get_story_interaction_info_object(Td *td) const { + if (is_empty()) { + return nullptr; + } + return td_api::make_object( + view_count_, forward_count_, reaction_count_, + td->user_manager_->get_user_ids_object(recent_viewer_user_ids_, "get_story_interaction_info_object")); +} + +bool operator==(const StoryInteractionInfo &lhs, const StoryInteractionInfo &rhs) { + return lhs.recent_viewer_user_ids_ == rhs.recent_viewer_user_ids_ && lhs.reaction_counts_ == rhs.reaction_counts_ && + lhs.view_count_ == rhs.view_count_ && lhs.forward_count_ == rhs.forward_count_ && + lhs.reaction_count_ == rhs.reaction_count_ && lhs.has_viewers_ == rhs.has_viewers_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StoryInteractionInfo &info) { + return string_builder << info.view_count_ << " views and " << info.forward_count_ << " forwards with " + << info.reaction_count_ << " reactions by " << info.recent_viewer_user_ids_; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.h b/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.h new file mode 100644 index 0000000000..18edacacc5 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.h @@ -0,0 +1,97 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ReactionType.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +#include + +namespace td { + +class Dependencies; +class Td; + +class StoryInteractionInfo { + vector recent_viewer_user_ids_; + vector> reaction_counts_; + int32 view_count_ = -1; + int32 forward_count_ = 0; + int32 reaction_count_ = 0; + bool has_viewers_ = false; + + static constexpr size_t MAX_RECENT_VIEWERS = 3; + + friend bool operator==(const StoryInteractionInfo &lhs, const StoryInteractionInfo &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const StoryInteractionInfo &info); + + public: + StoryInteractionInfo() = default; + + StoryInteractionInfo(Td *td, telegram_api::object_ptr &&story_views); + + bool is_empty() const { + return view_count_ < 0; + } + + bool has_hidden_viewers() const { + return view_count_ < 0 || !has_viewers_; + } + + void add_dependencies(Dependencies &dependencies) const; + + bool set_counts(int32 view_count, int32 reaction_count) { + if (view_count != view_count_ || reaction_count != reaction_count_) { + view_count = view_count_; + reaction_count = reaction_count_; + return true; + } + return false; + } + + void set_chosen_reaction_type(const ReactionType &new_reaction_type, const ReactionType &old_reaction_type); + + int32 get_view_count() const { + return view_count_; + } + + int32 get_reaction_count() const { + return reaction_count_; + } + + const vector> &get_reaction_counts() const { + return reaction_counts_; + } + + bool definitely_has_no_user(UserId user_id) const; + + bool set_recent_viewer_user_ids(vector &&user_ids); + + td_api::object_ptr get_story_interaction_info_object(Td *td) const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const StoryInteractionInfo &lhs, const StoryInteractionInfo &rhs); + +inline bool operator!=(const StoryInteractionInfo &lhs, const StoryInteractionInfo &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StoryInteractionInfo &info); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.hpp b/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.hpp new file mode 100644 index 0000000000..e562b4ba82 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryInteractionInfo.hpp @@ -0,0 +1,82 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/StoryInteractionInfo.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void StoryInteractionInfo::store(StorerT &storer) const { + using td::store; + bool has_recent_viewer_user_ids = !recent_viewer_user_ids_.empty(); + bool has_reaction_count = reaction_count_ > 0; + bool know_has_viewers = true; + bool has_forward_count = forward_count_ > 0; + bool has_reaction_counts = !reaction_counts_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_recent_viewer_user_ids); + STORE_FLAG(has_reaction_count); + STORE_FLAG(know_has_viewers); + STORE_FLAG(has_viewers_); + STORE_FLAG(has_forward_count); + STORE_FLAG(has_reaction_counts); + END_STORE_FLAGS(); + store(view_count_, storer); + if (has_recent_viewer_user_ids) { + store(recent_viewer_user_ids_, storer); + } + if (has_reaction_count) { + store(reaction_count_, storer); + } + if (has_forward_count) { + store(forward_count_, storer); + } + if (has_reaction_counts) { + store(reaction_counts_, storer); + } +} + +template +void StoryInteractionInfo::parse(ParserT &parser) { + using td::parse; + bool has_recent_viewer_user_ids; + bool has_reaction_count; + bool know_has_viewers; + bool has_forward_count; + bool has_reaction_counts; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_recent_viewer_user_ids); + PARSE_FLAG(has_reaction_count); + PARSE_FLAG(know_has_viewers); + PARSE_FLAG(has_viewers_); + PARSE_FLAG(has_forward_count); + PARSE_FLAG(has_reaction_counts); + END_PARSE_FLAGS(); + parse(view_count_, parser); + if (has_recent_viewer_user_ids) { + parse(recent_viewer_user_ids_, parser); + } + if (has_reaction_count) { + parse(reaction_count_, parser); + } + if (has_forward_count) { + parse(forward_count_, parser); + } + if (has_reaction_counts) { + parse(reaction_counts_, parser); + } + + if (!know_has_viewers) { + has_viewers_ = (view_count_ > 0 && !has_recent_viewer_user_ids) || reaction_count_ > 0; + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryListId.h b/protocols/Telegram/tdlib/td/td/telegram/StoryListId.h new file mode 100644 index 0000000000..f2934f9533 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryListId.h @@ -0,0 +1,95 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" + +#include "td/utils/common.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class StoryListId { + enum class Type : int32 { None = -1, Main, Archive }; + Type type_ = Type::None; + + friend struct StoryListIdHash; + + explicit StoryListId(Type type) : type_(type) { + } + + public: + StoryListId() = default; + + explicit StoryListId(const td_api::object_ptr &story_list) { + if (story_list == nullptr) { + return; + } + switch (story_list->get_id()) { + case td_api::storyListMain::ID: + type_ = Type::Main; + break; + case td_api::storyListArchive::ID: + type_ = Type::Archive; + break; + default: + UNREACHABLE(); + } + } + + static StoryListId main() { + return StoryListId(Type::Main); + } + + static StoryListId archive() { + return StoryListId(Type::Archive); + } + + td_api::object_ptr get_story_list_object() const { + switch (type_) { + case Type::None: + return nullptr; + case Type::Main: + return td_api::make_object(); + case Type::Archive: + return td_api::make_object(); + default: + UNREACHABLE(); + } + } + + bool is_valid() const { + return type_ == Type::Main || type_ == Type::Archive; + } + + bool operator==(const StoryListId &other) const { + return type_ == other.type_; + } + + bool operator!=(const StoryListId &other) const { + return type_ != other.type_; + } +}; + +struct StoryListIdHash { + uint32 operator()(StoryListId story_list_id) const { + return Hash()(static_cast(story_list_id.type_)); + } +}; + +inline StringBuilder &operator<<(StringBuilder &string_builder, StoryListId story_list_id) { + if (story_list_id == StoryListId::main()) { + return string_builder << "MainStoryList"; + } + if (story_list_id == StoryListId::archive()) { + return string_builder << "ArchiveStoryList"; + } + return string_builder << "InvalidStoryList"; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/StoryManager.cpp new file mode 100644 index 0000000000..e88f11f7b0 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryManager.cpp @@ -0,0 +1,6016 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StoryManager.h" + +#include "td/telegram/AccessRights.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/ConfigManager.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/FileReferenceManager.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/HashtagHints.h" +#include "td/telegram/logevent/LogEvent.h" +#include "td/telegram/logevent/LogEventHelper.h" +#include "td/telegram/MediaArea.hpp" +#include "td/telegram/MessageEntity.hpp" +#include "td/telegram/MessageSender.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/NotificationId.h" +#include "td/telegram/NotificationManager.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/QuickReplyManager.h" +#include "td/telegram/ReactionManager.h" +#include "td/telegram/ReactionType.hpp" +#include "td/telegram/ReportReason.h" +#include "td/telegram/StoryContent.h" +#include "td/telegram/StoryContentType.h" +#include "td/telegram/StoryForwardInfo.h" +#include "td/telegram/StoryForwardInfo.hpp" +#include "td/telegram/StoryInteractionInfo.hpp" +#include "td/telegram/StoryStealthMode.hpp" +#include "td/telegram/StoryViewer.h" +#include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UpdatesManager.h" +#include "td/telegram/UserManager.h" +#include "td/telegram/WebPagesManager.h" + +#include "td/db/binlog/BinlogEvent.h" +#include "td/db/binlog/BinlogHelper.h" + +#include "td/actor/MultiPromise.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/format.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/Random.h" +#include "td/utils/Slice.h" +#include "td/utils/SliceBuilder.h" +#include "td/utils/Status.h" +#include "td/utils/Time.h" +#include "td/utils/tl_helpers.h" + +#include + +namespace td { + +class GetAllStoriesQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetAllStoriesQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(StoryListId story_list_id, bool is_next, const string &state) { + int32 flags = 0; + if (!state.empty()) { + flags |= telegram_api::stories_getAllStories::STATE_MASK; + } + if (is_next) { + flags |= telegram_api::stories_getAllStories::NEXT_MASK; + } + if (story_list_id == StoryListId::archive()) { + flags |= telegram_api::stories_getAllStories::HIDDEN_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::stories_getAllStories(flags, false /*ignored*/, false /*ignored*/, state))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetAllStoriesQuery: " << to_string(result); + promise_.set_value(std::move(result)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class ToggleStoriesHiddenQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + bool are_hidden_ = false; + + public: + explicit ToggleStoriesHiddenQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, bool are_hidden) { + dialog_id_ = dialog_id; + are_hidden_ = are_hidden; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + CHECK(input_peer != nullptr); + send_query(G()->net_query_creator().create( + telegram_api::stories_togglePeerStoriesHidden(std::move(input_peer), are_hidden), {{dialog_id_}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for ToggleStoriesHiddenQuery: " << result; + if (result) { + td_->story_manager_->on_update_dialog_stories_hidden(dialog_id_, are_hidden_); + } + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ToggleStoriesHiddenQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetAllReadPeerStoriesQuery final : public Td::ResultHandler { + public: + void send() { + send_query(G()->net_query_creator().create(telegram_api::stories_getAllReadPeerStories())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetAllReadPeerStoriesQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), Promise()); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for GetAllReadPeerStoriesQuery: " << status; + } +}; + +class ToggleAllStoriesHiddenQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ToggleAllStoriesHiddenQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(bool all_stories_hidden) { + send_query( + G()->net_query_creator().create(telegram_api::stories_toggleAllStoriesHidden(all_stories_hidden), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for ToggleAllStoriesHiddenQuery: " << result; + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class IncrementStoryViewsQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit IncrementStoryViewsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, const vector &story_ids) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::stories_incrementStoryViews(std::move(input_peer), StoryId::get_input_story_ids(story_ids)), + {{"view_story"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "IncrementStoryViewsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class ReadStoriesQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit ReadStoriesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, StoryId max_read_story_id) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::stories_readStories(std::move(input_peer), max_read_story_id.get()), {{"view_story"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ReadStoriesQuery"); + promise_.set_error(std::move(status)); + } +}; + +class SendStoryReactionQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit SendStoryReactionQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(StoryFullId story_full_id, const ReactionType &reaction_type, bool add_to_recent) { + dialog_id_ = story_full_id.get_dialog_id(); + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + CHECK(!reaction_type.is_paid_reaction()); + + int32 flags = 0; + if (!reaction_type.is_empty() && add_to_recent) { + flags |= telegram_api::stories_sendReaction::ADD_TO_RECENT_MASK; + } + + send_query(G()->net_query_creator().create( + telegram_api::stories_sendReaction(flags, false /*ignored*/, std::move(input_peer), + story_full_id.get_story_id().get(), reaction_type.get_input_reaction()), + {{story_full_id}, {"view_story"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendStoryReactionQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + if (status.message() == "STORY_NOT_MODIFIED") { + return promise_.set_value(Unit()); + } + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendStoryReactionQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStoryViewsListQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetStoryViewsListQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, StoryId story_id, const string &query, bool only_contacts, bool prefer_forwards, + bool prefer_with_reaction, const string &offset, int32 limit) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + int32 flags = 0; + if (!query.empty()) { + flags |= telegram_api::stories_getStoryViewsList::Q_MASK; + } + if (only_contacts) { + flags |= telegram_api::stories_getStoryViewsList::JUST_CONTACTS_MASK; + } + if (prefer_forwards) { + flags |= telegram_api::stories_getStoryViewsList::FORWARDS_FIRST_MASK; + } + if (prefer_with_reaction) { + flags |= telegram_api::stories_getStoryViewsList::REACTIONS_FIRST_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::stories_getStoryViewsList(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, + std::move(input_peer), query, story_id.get(), offset, limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetStoryViewsListQuery: " << to_string(result); + td_->story_manager_->get_channel_differences_if_needed(std::move(result), std::move(promise_)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStoryViewsListQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStoryReactionsListQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetStoryReactionsListQuery( + Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(StoryFullId story_full_id, const ReactionType &reaction_type, bool prefer_forwards, const string &offset, + int32 limit) { + dialog_id_ = story_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + CHECK(!reaction_type.is_paid_reaction()); + + int32 flags = 0; + if (!reaction_type.is_empty()) { + flags |= telegram_api::stories_getStoryReactionsList::REACTION_MASK; + } + if (!offset.empty()) { + flags |= telegram_api::stories_getStoryReactionsList::OFFSET_MASK; + } + if (prefer_forwards) { + flags |= telegram_api::stories_getStoryReactionsList::FORWARDS_FIRST_MASK; + } + send_query(G()->net_query_creator().create(telegram_api::stories_getStoryReactionsList( + flags, false /*ignored*/, std::move(input_peer), story_full_id.get_story_id().get(), + reaction_type.get_input_reaction(), offset, limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetStoryReactionsListQuery: " << to_string(result); + td_->story_manager_->get_channel_differences_if_needed(std::move(result), std::move(promise_)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStoryReactionsListQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStoriesByIDQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + vector story_ids_; + + public: + explicit GetStoriesByIDQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, vector story_ids) { + dialog_id_ = dialog_id; + story_ids_ = std::move(story_ids); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::stories_getStoriesByID(std::move(input_peer), StoryId::get_input_story_ids(story_ids_)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetStoriesByIDQuery: " << to_string(result); + td_->story_manager_->on_get_stories(dialog_id_, std::move(story_ids_), std::move(result)); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStoriesByIDQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetPinnedStoriesQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetPinnedStoriesQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, StoryId offset_story_id, int32 limit) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::stories_getPinnedStories(std::move(input_peer), offset_story_id.get(), limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetPinnedStoriesQuery: " << to_string(result); + promise_.set_value(std::move(result)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetPinnedStoriesQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStoriesArchiveQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetStoriesArchiveQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, StoryId offset_story_id, int32 limit) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::stories_getStoriesArchive(std::move(input_peer), offset_story_id.get(), limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetStoriesArchiveQuery: " << to_string(result); + promise_.set_value(std::move(result)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStoriesArchiveQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetPeerStoriesQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit GetPeerStoriesQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query( + G()->net_query_creator().create(telegram_api::stories_getPeerStories(std::move(input_peer)), {{dialog_id}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetPeerStoriesQuery: " << to_string(result); + promise_.set_value(std::move(result)); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetPeerStoriesQuery"); + promise_.set_error(std::move(status)); + } +}; + +class EditStoryCoverQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + StoryId story_id_; + double main_frame_timestamp_; + FileId file_id_; + string file_reference_; + + public: + explicit EditStoryCoverQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId owner_dialog_id, StoryId story_id, double main_frame_timestamp, FileId file_id, + telegram_api::object_ptr input_media) { + dialog_id_ = owner_dialog_id; + story_id_ = story_id; + main_frame_timestamp_ = main_frame_timestamp; + file_id_ = file_id; + file_reference_ = FileManager::extract_file_reference(input_media); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + send_query(G()->net_query_creator().create( + telegram_api::stories_editStory(telegram_api::stories_editStory::MEDIA_MASK, std::move(input_peer), + story_id.get(), std::move(input_media), + vector>(), string(), + vector>(), Auto()), + {{StoryFullId{dialog_id_, story_id}}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for EditStoryCoverQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for EditStoryCoverQuery: " << status; + if (!td_->auth_manager_->is_bot() && status.message() == "STORY_NOT_MODIFIED") { + return promise_.set_value(Unit()); + } + if (!td_->auth_manager_->is_bot() && FileReferenceManager::is_file_reference_error(status)) { + td_->file_manager_->delete_file_reference(file_id_, file_reference_); + td_->file_reference_manager_->repair_file_reference( + file_id_, PromiseCreator::lambda([dialog_id = dialog_id_, story_id = story_id_, + main_frame_timestamp = main_frame_timestamp_, + promise = std::move(promise_)](Result result) mutable { + if (result.is_error()) { + return promise.set_error(Status::Error(400, "Failed to edit cover")); + } + + send_closure(G()->story_manager(), &StoryManager::edit_story_cover, dialog_id, story_id, + main_frame_timestamp, std::move(promise)); + })); + return; + } + + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "EditStoryCoverQuery"); + promise_.set_error(std::move(status)); + } +}; + +class EditStoryPrivacyQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit EditStoryPrivacyQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, StoryId story_id, UserPrivacySettingRules &&privacy_rules) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + int32 flags = telegram_api::stories_editStory::PRIVACY_RULES_MASK; + send_query(G()->net_query_creator().create( + telegram_api::stories_editStory(flags, std::move(input_peer), story_id.get(), nullptr, + vector>(), string(), + vector>(), + privacy_rules.get_input_privacy_rules(td_)), + {{StoryFullId{dialog_id, story_id}}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for EditStoryPrivacyQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + if (!td_->auth_manager_->is_bot() && status.message() == "STORY_NOT_MODIFIED") { + return promise_.set_value(Unit()); + } + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "EditStoryPrivacyQuery"); + promise_.set_error(std::move(status)); + } +}; + +class ToggleStoryPinnedQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit ToggleStoryPinnedQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, StoryId story_id, bool is_pinned) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::stories_togglePinned(std::move(input_peer), {story_id.get()}, is_pinned), + {{StoryFullId{dialog_id, story_id}}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for ToggleStoryPinnedQuery: " << ptr; + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ToggleStoryPinnedQuery"); + promise_.set_error(std::move(status)); + } +}; + +class DeleteStoriesQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit DeleteStoriesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, const vector &story_ids) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::stories_deleteStories(std::move(input_peer), StoryId::get_input_story_ids(story_ids)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for DeleteStoriesQuery: " << ptr; + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "DeleteStoriesQuery"); + promise_.set_error(std::move(status)); + } +}; + +class SearchStoriesQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit SearchStoriesQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(string hashtag, const string &offset, int32 limit) { + int32 flags = telegram_api::stories_searchPosts::HASHTAG_MASK; + send_query( + G()->net_query_creator().create(telegram_api::stories_searchPosts(flags, hashtag, nullptr, offset, limit))); + } + + void send(td_api::object_ptr &&address, const string &offset, int32 limit) { + int32 flags = telegram_api::stories_searchPosts::AREA_MASK; + + int32 address_flags = 0; + if (!address->state_.empty()) { + address_flags |= telegram_api::geoPointAddress::STATE_MASK; + } + if (!address->city_.empty()) { + address_flags |= telegram_api::geoPointAddress::CITY_MASK; + } + if (!address->street_.empty()) { + address_flags |= telegram_api::geoPointAddress::STREET_MASK; + } + + auto area = telegram_api::make_object( + telegram_api::mediaAreaGeoPoint::ADDRESS_MASK, + telegram_api::make_object(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), + telegram_api::make_object(0, 0.0, 0.0, 0, 0), + telegram_api::make_object(address_flags, address->country_code_, address->state_, + address->city_, address->street_)); + send_query(G()->net_query_creator().create( + telegram_api::stories_searchPosts(flags, string(), std::move(area), offset, limit))); + } + + void send(const string &venue_provider, const string &venue_id, const string &offset, int32 limit) { + int32 flags = telegram_api::stories_searchPosts::AREA_MASK; + auto area = telegram_api::make_object( + telegram_api::make_object(0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0), + telegram_api::make_object(0, 0.0, 0.0, 0, 0), string(), string(), venue_provider, + venue_id, string()); + send_query(G()->net_query_creator().create( + telegram_api::stories_searchPosts(flags, string(), std::move(area), offset, limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for SearchStoriesQuery: " << to_string(ptr); + td_->user_manager_->on_get_users(std::move(ptr->users_), "SearchStoriesQuery"); + td_->chat_manager_->on_get_chats(std::move(ptr->chats_), "SearchStoriesQuery"); + + auto total_count = ptr->count_; + if (total_count < static_cast(ptr->stories_.size())) { + LOG(ERROR) << "Receive total count = " << total_count << " and " << ptr->stories_.size() << " stories"; + total_count = static_cast(ptr->stories_.size()); + } + vector> stories; + for (auto &found_story : ptr->stories_) { + DialogId owner_dialog_id(found_story->peer_); + auto story_id = td_->story_manager_->on_get_story(owner_dialog_id, std::move(found_story->story_)); + if (story_id.is_valid()) { + auto story_object = td_->story_manager_->get_story_object({owner_dialog_id, story_id}); + if (story_object == nullptr) { + LOG(ERROR) << "Receive deleted " << story_id << " from " << owner_dialog_id; + } else { + stories.push_back(std::move(story_object)); + } + } + } + + promise_.set_value(td_api::make_object(total_count, std::move(stories), ptr->next_offset_)); + } + + void on_error(Status status) final { + if (status.message() == "SEARCH_QUERY_EMPTY") { + return promise_.set_value(td_api::make_object()); + } + promise_.set_error(std::move(status)); + } +}; + +class TogglePinnedStoriesToTopQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit TogglePinnedStoriesToTopQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id, vector story_ids) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + CHECK(input_peer != nullptr); + send_query(G()->net_query_creator().create( + telegram_api::stories_togglePinnedToTop(std::move(input_peer), StoryId::get_input_story_ids(story_ids)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for TogglePinnedStoriesToTopQuery: " << ptr; + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStoriesViewsQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStoriesViewsQuery final : public Td::ResultHandler { + vector story_ids_; + DialogId dialog_id_; + + public: + void send(DialogId dialog_id, vector story_ids) { + dialog_id_ = dialog_id; + story_ids_ = std::move(story_ids); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create( + telegram_api::stories_getStoriesViews(std::move(input_peer), StoryId::get_input_story_ids(story_ids_)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetStoriesViewsQuery: " << to_string(ptr); + td_->story_manager_->on_get_story_views(dialog_id_, story_ids_, std::move(ptr)); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for GetStoriesViewsQuery for " << story_ids_ << ": " << status; + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "GetStoriesViewsQuery"); + } +}; + +class ReportStoryQuery final : public Td::ResultHandler { + Promise promise_; + DialogId dialog_id_; + + public: + explicit ReportStoryQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(StoryFullId story_full_id, ReportReason &&report_reason) { + dialog_id_ = story_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + send_query(G()->net_query_creator().create( + telegram_api::stories_report(std::move(input_peer), {story_full_id.get_story_id().get()}, + report_reason.get_input_report_reason(), report_reason.get_message()))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ReportStoryQuery"); + promise_.set_error(std::move(status)); + } +}; + +class GetStoriesMaxIdsQuery final : public Td::ResultHandler { + vector dialog_ids_; + + public: + void send(vector dialog_ids, vector> &&input_peers) { + dialog_ids_ = std::move(dialog_ids); + send_query(G()->net_query_creator().create(telegram_api::stories_getPeerMaxIDs(std::move(input_peers)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->story_manager_->on_get_dialog_max_active_story_ids(dialog_ids_, result_ptr.move_as_ok()); + } + + void on_error(Status status) final { + td_->story_manager_->on_get_dialog_max_active_story_ids(dialog_ids_, Auto()); + } +}; + +class ActivateStealthModeQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ActivateStealthModeQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + int32 flags = + telegram_api::stories_activateStealthMode::PAST_MASK | telegram_api::stories_activateStealthMode::FUTURE_MASK; + + send_query(G()->net_query_creator().create( + telegram_api::stories_activateStealthMode(flags, false /*ignored*/, false /*ignored*/), {{"view_story"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for ActivateStealthModeQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetChatsToSendStoriesQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetChatsToSendStoriesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::stories_getChatsToSend())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto chats_ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetChatsToSendStoriesQuery: " << to_string(chats_ptr); + switch (chats_ptr->get_id()) { + case telegram_api::messages_chats::ID: { + auto chats = move_tl_object_as(chats_ptr); + td_->story_manager_->on_get_dialogs_to_send_stories(std::move(chats->chats_)); + break; + } + case telegram_api::messages_chatsSlice::ID: { + auto chats = move_tl_object_as(chats_ptr); + LOG(ERROR) << "Receive chatsSlice in result of GetCreatedPublicChannelsQuery"; + td_->story_manager_->on_get_dialogs_to_send_stories(std::move(chats->chats_)); + break; + } + default: + UNREACHABLE(); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class CanSendStoryQuery final : public Td::ResultHandler { + Promise> promise_; + DialogId dialog_id_; + + public: + explicit CanSendStoryQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(DialogId dialog_id) { + dialog_id_ = dialog_id; + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + send_query(G()->net_query_creator().create(telegram_api::stories_canSendStory(std::move(input_peer)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(td_api::make_object()); + } + + void on_error(Status status) final { + auto result = StoryManager::get_can_send_story_result_object(status); + if (result != nullptr) { + return promise_.set_value(std::move(result)); + } + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "CanSendStoryQuery"); + promise_.set_error(std::move(status)); + } +}; + +class StoryManager::SendStoryQuery final : public Td::ResultHandler { + DialogId dialog_id_; + FileId file_id_; + unique_ptr pending_story_; + + public: + void send(FileId file_id, unique_ptr pending_story, + telegram_api::object_ptr input_file) { + file_id_ = file_id; + pending_story_ = std::move(pending_story); + CHECK(pending_story_ != nullptr); + dialog_id_ = pending_story_->dialog_id_; + + const auto *story = pending_story_->story_.get(); + const StoryContent *content = story->content_.get(); + CHECK(input_file != nullptr); + auto input_media = get_story_content_input_media(td_, content, std::move(input_file)); + CHECK(input_media != nullptr); + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + telegram_api::object_ptr fwd_input_peer; + int32 fwd_story_id = 0; + if (story->forward_info_ != nullptr) { + fwd_input_peer = td_->dialog_manager_->get_input_peer(pending_story_->forward_from_story_full_id_.get_dialog_id(), + AccessRights::Read); + if (fwd_input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the story to repost")); + } + fwd_story_id = pending_story_->forward_from_story_full_id_.get_story_id().get(); + } + + const FormattedText &caption = story->caption_; + auto entities = get_input_message_entities(td_->user_manager_.get(), &caption, "SendStoryQuery"); + if (!td_->option_manager_->get_option_boolean("can_use_text_entities_in_story_caption")) { + entities.clear(); + } + auto privacy_rules = story->privacy_rules_.get_input_privacy_rules(td_); + auto period = story->expire_date_ - story->date_; + int32 flags = 0; + if (!caption.text.empty()) { + flags |= telegram_api::stories_sendStory::CAPTION_MASK; + } + if (!entities.empty()) { + flags |= telegram_api::stories_sendStory::ENTITIES_MASK; + } + if (pending_story_->story_->is_pinned_) { + flags |= telegram_api::stories_sendStory::PINNED_MASK; + } + if (period != 86400) { + flags |= telegram_api::stories_sendStory::PERIOD_MASK; + } + if (story->forward_info_ != nullptr) { + flags |= telegram_api::stories_sendStory::FWD_MODIFIED_MASK; + flags |= telegram_api::stories_sendStory::FWD_FROM_ID_MASK; + flags |= telegram_api::stories_sendStory::FWD_FROM_STORY_MASK; + } + if (story->noforwards_) { + flags |= telegram_api::stories_sendStory::NOFORWARDS_MASK; + } + auto input_media_areas = MediaArea::get_input_media_areas(td_, story->areas_); + if (!input_media_areas.empty()) { + flags |= telegram_api::stories_sendStory::MEDIA_AREAS_MASK; + } + + send_query(G()->net_query_creator().create( + telegram_api::stories_sendStory(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, + std::move(input_peer), std::move(input_media), std::move(input_media_areas), + caption.text, std::move(entities), std::move(privacy_rules), + pending_story_->random_id_, period, std::move(fwd_input_peer), fwd_story_id), + {{pending_story_->dialog_id_}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for SendStoryQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates( + std::move(ptr), PromiseCreator::lambda([file_id = file_id_, pending_story = std::move(pending_story_)]( + Result &&result) mutable { + send_closure(G()->story_manager(), &StoryManager::delete_pending_story, file_id, std::move(pending_story), + result.is_ok() ? Status::OK() : result.move_as_error()); + })); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for SendStoryQuery: " << status; + if (G()->close_flag() && G()->use_message_database()) { + // do not send error, story will be re-sent after restart + return; + } + + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + td_->story_manager_->on_send_story_file_parts_missing(std::move(pending_story_), std::move(bad_parts)); + return; + } + + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "SendStoryQuery"); + td_->story_manager_->delete_pending_story(file_id_, std::move(pending_story_), std::move(status)); + } +}; + +class StoryManager::EditStoryQuery final : public Td::ResultHandler { + DialogId dialog_id_; + FileId file_id_; + unique_ptr pending_story_; + + public: + void send(FileId file_id, const Story *story, unique_ptr pending_story, + telegram_api::object_ptr input_file, const BeingEditedStory *edited_story) { + file_id_ = file_id; + pending_story_ = std::move(pending_story); + CHECK(pending_story_ != nullptr); + dialog_id_ = pending_story_->dialog_id_; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Write); + if (input_peer == nullptr) { + return on_error(Status::Error(400, "Can't access the chat")); + } + + int32 flags = 0; + + telegram_api::object_ptr input_media; + const StoryContent *content = edited_story->content_.get(); + if (content != nullptr) { + CHECK(input_file != nullptr); + input_media = get_story_content_input_media(td_, content, std::move(input_file)); + CHECK(input_media != nullptr); + flags |= telegram_api::stories_editStory::MEDIA_MASK; + } + vector> input_media_areas; + if (edited_story->edit_media_areas_) { + input_media_areas = MediaArea::get_input_media_areas(td_, edited_story->areas_); + flags |= telegram_api::stories_editStory::MEDIA_AREAS_MASK; + } + vector> entities; + if (edited_story->edit_caption_) { + flags |= telegram_api::stories_editStory::CAPTION_MASK; + if (td_->option_manager_->get_option_boolean("can_use_text_entities_in_story_caption")) { + flags |= telegram_api::stories_editStory::ENTITIES_MASK; + entities = get_input_message_entities(td_->user_manager_.get(), &edited_story->caption_, "EditStoryQuery"); + } + } + + send_query(G()->net_query_creator().create( + telegram_api::stories_editStory(flags, std::move(input_peer), pending_story_->story_id_.get(), + std::move(input_media), std::move(input_media_areas), + edited_story->caption_.text, std::move(entities), Auto()), + {{StoryFullId{pending_story_->dialog_id_, pending_story_->story_id_}}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for EditStoryQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates( + std::move(ptr), PromiseCreator::lambda([file_id = file_id_, pending_story = std::move(pending_story_)]( + Result &&result) mutable { + send_closure(G()->story_manager(), &StoryManager::delete_pending_story, file_id, std::move(pending_story), + result.is_ok() ? Status::OK() : result.move_as_error()); + })); + } + + void on_error(Status status) final { + LOG(INFO) << "Receive error for EditStoryQuery: " << status; + if (G()->close_flag() && G()->use_message_database()) { + // do not send error, story will be edited after restart + return; + } + + if (!td_->auth_manager_->is_bot() && status.message() == "STORY_NOT_MODIFIED") { + return td_->story_manager_->delete_pending_story(file_id_, std::move(pending_story_), Status::OK()); + } + + auto bad_parts = FileManager::get_missing_file_parts(status); + if (!bad_parts.empty()) { + td_->story_manager_->on_send_story_file_parts_missing(std::move(pending_story_), std::move(bad_parts)); + return; + } + + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "EditStoryQuery"); + td_->story_manager_->delete_pending_story(file_id_, std::move(pending_story_), std::move(status)); + } +}; + +class StoryManager::UploadMediaCallback final : public FileManager::UploadCallback { + public: + void on_upload_ok(FileId file_id, telegram_api::object_ptr input_file) final { + send_closure_later(G()->story_manager(), &StoryManager::on_upload_story, file_id, std::move(input_file)); + } + void on_upload_encrypted_ok(FileId file_id, + telegram_api::object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_secure_ok(FileId file_id, telegram_api::object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_error(FileId file_id, Status error) final { + send_closure_later(G()->story_manager(), &StoryManager::on_upload_story_error, file_id, std::move(error)); + } +}; + +StoryManager::PendingStory::PendingStory(DialogId dialog_id, StoryId story_id, StoryFullId forward_from_story_full_id, + uint32 send_story_num, int64 random_id, unique_ptr &&story) + : dialog_id_(dialog_id) + , story_id_(story_id) + , forward_from_story_full_id_(forward_from_story_full_id) + , send_story_num_(send_story_num) + , random_id_(random_id) + , story_(std::move(story)) { +} + +StoryManager::ReadyToSendStory::ReadyToSendStory(FileId file_id, unique_ptr &&pending_story, + telegram_api::object_ptr &&input_file) + : file_id_(file_id), pending_story_(std::move(pending_story)), input_file_(std::move(input_file)) { +} + +template +void StoryManager::Story::store(StorerT &storer) const { + using td::store; + bool has_receive_date = receive_date_ != 0; + bool has_interaction_info = !interaction_info_.is_empty(); + bool has_privacy_rules = privacy_rules_ != UserPrivacySettingRules(); + bool has_content = content_ != nullptr; + bool has_caption = !caption_.text.empty(); + bool has_areas = !areas_.empty(); + bool has_chosen_reaction_type = !chosen_reaction_type_.is_empty(); + bool has_forward_info = forward_info_ != nullptr; + bool has_sender_dialog_id = sender_dialog_id_ != DialogId(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_edited_); + STORE_FLAG(is_pinned_); + STORE_FLAG(is_public_); + STORE_FLAG(is_for_close_friends_); + STORE_FLAG(noforwards_); + STORE_FLAG(has_receive_date); + STORE_FLAG(has_interaction_info); + STORE_FLAG(has_privacy_rules); + STORE_FLAG(has_content); + STORE_FLAG(has_caption); + STORE_FLAG(is_for_contacts_); + STORE_FLAG(is_for_selected_contacts_); + STORE_FLAG(has_areas); + STORE_FLAG(has_chosen_reaction_type); + STORE_FLAG(is_outgoing_); + STORE_FLAG(has_forward_info); + STORE_FLAG(has_sender_dialog_id); + END_STORE_FLAGS(); + store(date_, storer); + store(expire_date_, storer); + if (has_receive_date) { + store(receive_date_, storer); + } + if (has_interaction_info) { + store(interaction_info_, storer); + } + if (has_privacy_rules) { + store(privacy_rules_, storer); + } + if (has_content) { + store_story_content(content_.get(), storer); + } + if (has_caption) { + store(caption_, storer); + } + if (has_areas) { + store(areas_, storer); + } + if (has_chosen_reaction_type) { + store(chosen_reaction_type_, storer); + } + if (has_forward_info) { + store(forward_info_, storer); + } + if (has_sender_dialog_id) { + store(sender_dialog_id_, storer); + } +} + +template +void StoryManager::Story::parse(ParserT &parser) { + using td::parse; + bool has_receive_date; + bool has_interaction_info; + bool has_privacy_rules; + bool has_content; + bool has_caption; + bool has_areas; + bool has_chosen_reaction_type; + bool has_forward_info; + bool has_sender_dialog_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_edited_); + PARSE_FLAG(is_pinned_); + PARSE_FLAG(is_public_); + PARSE_FLAG(is_for_close_friends_); + PARSE_FLAG(noforwards_); + PARSE_FLAG(has_receive_date); + PARSE_FLAG(has_interaction_info); + PARSE_FLAG(has_privacy_rules); + PARSE_FLAG(has_content); + PARSE_FLAG(has_caption); + PARSE_FLAG(is_for_contacts_); + PARSE_FLAG(is_for_selected_contacts_); + PARSE_FLAG(has_areas); + PARSE_FLAG(has_chosen_reaction_type); + PARSE_FLAG(is_outgoing_); + PARSE_FLAG(has_forward_info); + PARSE_FLAG(has_sender_dialog_id); + END_PARSE_FLAGS(); + parse(date_, parser); + parse(expire_date_, parser); + if (has_receive_date) { + parse(receive_date_, parser); + } + if (has_interaction_info) { + parse(interaction_info_, parser); + } + if (has_privacy_rules) { + parse(privacy_rules_, parser); + } + if (has_content) { + parse_story_content(content_, parser); + } + if (has_caption) { + parse(caption_, parser); + } + if (has_areas) { + parse(areas_, parser); + } + if (has_chosen_reaction_type) { + parse(chosen_reaction_type_, parser); + } + if (has_forward_info) { + parse(forward_info_, parser); + } + if (has_sender_dialog_id) { + parse(sender_dialog_id_, parser); + } +} + +template +void StoryManager::StoryInfo::store(StorerT &storer) const { + using td::store; + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_for_close_friends_); + END_STORE_FLAGS(); + store(story_id_, storer); + store(date_, storer); + store(expire_date_, storer); +} + +template +void StoryManager::StoryInfo::parse(ParserT &parser) { + using td::parse; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_for_close_friends_); + END_PARSE_FLAGS(); + parse(story_id_, parser); + parse(date_, parser); + parse(expire_date_, parser); +} + +template +void StoryManager::PendingStory::store(StorerT &storer) const { + using td::store; + bool is_edit = story_id_.is_server(); + bool has_forward_from_story_full_id = forward_from_story_full_id_.is_valid(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_edit); + STORE_FLAG(has_forward_from_story_full_id); + END_STORE_FLAGS(); + store(dialog_id_, storer); + if (is_edit) { + store(story_id_, storer); + } else { + store(random_id_, storer); + } + store(story_, storer); + if (has_forward_from_story_full_id) { + store(forward_from_story_full_id_, storer); + } +} + +template +void StoryManager::PendingStory::parse(ParserT &parser) { + using td::parse; + bool is_edit; + bool has_forward_from_story_full_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_edit); + PARSE_FLAG(has_forward_from_story_full_id); + END_PARSE_FLAGS(); + parse(dialog_id_, parser); + if (is_edit) { + parse(story_id_, parser); + } else { + parse(random_id_, parser); + } + parse(story_, parser); + if (has_forward_from_story_full_id) { + parse(forward_from_story_full_id_, parser); + } +} + +template +void StoryManager::SavedActiveStories::store(StorerT &storer) const { + using td::store; + CHECK(!story_infos_.empty()); + bool has_max_read_story_id = max_read_story_id_.is_valid(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_max_read_story_id); + END_STORE_FLAGS(); + store(story_infos_, storer); + if (has_max_read_story_id) { + store(max_read_story_id_, storer); + } +} + +template +void StoryManager::SavedActiveStories::parse(ParserT &parser) { + using td::parse; + bool has_max_read_story_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_max_read_story_id); + END_PARSE_FLAGS(); + parse(story_infos_, parser); + if (has_max_read_story_id) { + parse(max_read_story_id_, parser); + } +} + +template +void StoryManager::SavedStoryList::store(StorerT &storer) const { + using td::store; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_more_); + END_STORE_FLAGS(); + store(state_, storer); + store(total_count_, storer); +} + +template +void StoryManager::SavedStoryList::parse(ParserT &parser) { + using td::parse; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_more_); + END_PARSE_FLAGS(); + parse(state_, parser); + parse(total_count_, parser); +} + +StoryManager::StoryManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { + upload_media_callback_ = std::make_shared(); + + story_reload_timeout_.set_callback(on_story_reload_timeout_callback); + story_reload_timeout_.set_callback_data(static_cast(this)); + + story_expire_timeout_.set_callback(on_story_expire_timeout_callback); + story_expire_timeout_.set_callback_data(static_cast(this)); + + story_can_get_viewers_timeout_.set_callback(on_story_can_get_viewers_timeout_callback); + story_can_get_viewers_timeout_.set_callback_data(static_cast(this)); + + if (G()->use_message_database() && td_->auth_manager_->is_authorized() && !td_->auth_manager_->is_bot()) { + for (auto story_list_id : {StoryListId::main(), StoryListId::archive()}) { + auto r_value = G()->td_db()->get_story_db_sync()->get_active_story_list_state(story_list_id); + if (r_value.is_ok() && !r_value.ok().empty()) { + SavedStoryList saved_story_list; + auto status = log_event_parse(saved_story_list, r_value.ok().as_slice()); + if (status.is_error()) { + LOG(ERROR) << "Load invalid state for " << story_list_id << " from database"; + } else { + LOG(INFO) << "Load state for " << story_list_id << " from database: " << saved_story_list.state_; + auto &story_list = get_story_list(story_list_id); + story_list.state_ = std::move(saved_story_list.state_); + story_list.server_total_count_ = td::max(saved_story_list.total_count_, 0); + story_list.server_has_more_ = saved_story_list.has_more_; + story_list.database_has_more_ = true; + } + } + } + } +} + +StoryManager::~StoryManager() { + Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), story_full_id_to_file_source_id_, stories_, + stories_by_global_id_, inaccessible_story_full_ids_, + deleted_story_full_ids_, failed_to_load_story_full_ids_, story_messages_, + story_quick_reply_messages_, active_stories_, updated_active_stories_, + max_read_story_ids_, failed_to_load_active_stories_); +} + +void StoryManager::start_up() { + if (!td_->auth_manager_->is_authorized()) { + return; + } + + auto stealth_mode_str = G()->td_db()->get_binlog_pmc()->get(get_story_stealth_mode_key()); + if (!stealth_mode_str.empty()) { + log_event_parse(stealth_mode_, stealth_mode_str).ensure(); + stealth_mode_.update(); + LOG(INFO) << stealth_mode_; + if (stealth_mode_.is_empty()) { + G()->td_db()->get_binlog_pmc()->erase(get_story_stealth_mode_key()); + } else { + schedule_stealth_mode_update(); + } + } + send_update_story_stealth_mode(); + + try_synchronize_archive_all_stories(); + load_expired_database_stories(); + + for (auto story_list_id : {StoryListId::main(), StoryListId::archive()}) { + update_story_list_sent_total_count(story_list_id, "start_up"); + } +} + +void StoryManager::timeout_expired() { + load_expired_database_stories(); + + if (channels_to_send_stories_inited_ && get_dialogs_to_send_stories_queries_.empty() && + Time::now() > next_reload_channels_to_send_stories_time_ && !td_->auth_manager_->is_bot()) { + reload_dialogs_to_send_stories(Auto()); + } +} + +void StoryManager::hangup() { + auto fail_promise_map = [](auto &queries) { + while (!queries.empty()) { + auto it = queries.begin(); + auto promises = std::move(it->second); + queries.erase(it); + fail_promises(promises, Global::request_aborted_error()); + } + }; + fail_promise_map(reload_story_queries_); + fail_promise_map(delete_yet_unsent_story_queries_); + + stop(); +} + +void StoryManager::tear_down() { + parent_.reset(); +} + +void StoryManager::on_story_reload_timeout_callback(void *story_manager_ptr, int64 story_global_id) { + if (G()->close_flag()) { + return; + } + + auto story_manager = static_cast(story_manager_ptr); + send_closure_later(story_manager->actor_id(story_manager), &StoryManager::on_story_reload_timeout, story_global_id); +} + +void StoryManager::on_story_reload_timeout(int64 story_global_id) { + if (G()->close_flag()) { + return; + } + + auto story_full_id = stories_by_global_id_.get(story_global_id); + auto story = get_story(story_full_id); + if (story == nullptr || opened_stories_.count(story_full_id) == 0) { + LOG(INFO) << "There is no need to reload " << story_full_id; + return; + } + + reload_story(story_full_id, Promise(), "on_story_reload_timeout"); + story_reload_timeout_.set_timeout_in(story_global_id, OPENED_STORY_POLL_PERIOD); +} + +void StoryManager::on_story_expire_timeout_callback(void *story_manager_ptr, int64 story_global_id) { + if (G()->close_flag()) { + return; + } + + auto story_manager = static_cast(story_manager_ptr); + send_closure_later(story_manager->actor_id(story_manager), &StoryManager::on_story_expire_timeout, story_global_id); +} + +void StoryManager::on_story_expire_timeout(int64 story_global_id) { + if (G()->close_flag()) { + return; + } + + auto story_full_id = stories_by_global_id_.get(story_global_id); + auto story = get_story(story_full_id); + if (story == nullptr) { + return; + } + if (is_active_story(story)) { + // timeout used monotonic time instead of wall clock time + LOG(INFO) << "Receive timeout for non-expired " << story_full_id << ": expire_date = " << story->expire_date_ + << ", current time = " << G()->unix_time(); + return set_story_expire_timeout(story); + } + + LOG(INFO) << "Have expired " << story_full_id; + auto owner_dialog_id = story_full_id.get_dialog_id(); + CHECK(owner_dialog_id.is_valid()); + if (story->content_ != nullptr && !can_access_expired_story(owner_dialog_id, story)) { + on_delete_story(story_full_id); // also updates active stories + } else { + auto active_stories = get_active_stories(owner_dialog_id); + if (active_stories != nullptr && contains(active_stories->story_ids_, story_full_id.get_story_id())) { + auto story_ids = active_stories->story_ids_; + on_update_active_stories(owner_dialog_id, active_stories->max_read_story_id_, std::move(story_ids), + Promise(), "on_story_expire_timeout"); + } + } +} + +void StoryManager::on_story_can_get_viewers_timeout_callback(void *story_manager_ptr, int64 story_global_id) { + if (G()->close_flag()) { + return; + } + + auto story_manager = static_cast(story_manager_ptr); + send_closure_later(story_manager->actor_id(story_manager), &StoryManager::on_story_can_get_viewers_timeout, + story_global_id); +} + +void StoryManager::on_story_can_get_viewers_timeout(int64 story_global_id) { + if (G()->close_flag()) { + return; + } + + auto story_full_id = stories_by_global_id_.get(story_global_id); + auto story = get_story(story_full_id); + if (story == nullptr) { + return; + } + + LOG(INFO) << "Have expired viewers in " << story_full_id; + if (has_unexpired_viewers(story_full_id, story)) { + // timeout used monotonic time instead of wall clock time + // also a reaction could have been added on the story + LOG(INFO) << "Receive timeout for " << story_full_id + << " with available viewers: expire_date = " << story->expire_date_ + << ", current time = " << G()->unix_time(); + return set_story_can_get_viewers_timeout(story); + } + + // can_get_viewers flag could have been changed; reload the story to repair it + reload_story(story_full_id, Promise(), "on_story_can_get_viewers_timeout"); +} + +void StoryManager::load_expired_database_stories() { + if (!G()->use_message_database()) { + if (!td_->auth_manager_->is_bot()) { + set_timeout_in(Random::fast(300, 420)); + } + return; + } + + LOG(INFO) << "Load " << load_expired_database_stories_next_limit_ << " expired stories"; + G()->td_db()->get_story_db_async()->get_expiring_stories( + G()->unix_time() - 1, load_expired_database_stories_next_limit_, + PromiseCreator::lambda([actor_id = actor_id(this)](Result> r_stories) { + if (G()->close_flag()) { + return; + } + CHECK(r_stories.is_ok()); + send_closure(actor_id, &StoryManager::on_load_expired_database_stories, r_stories.move_as_ok()); + })); +} + +void StoryManager::on_load_expired_database_stories(vector stories) { + if (G()->close_flag()) { + return; + } + + int32 next_request_delay; + if (stories.size() == static_cast(load_expired_database_stories_next_limit_)) { + CHECK(load_expired_database_stories_next_limit_ < (1 << 30)); + load_expired_database_stories_next_limit_ *= 2; + next_request_delay = 1; + } else { + load_expired_database_stories_next_limit_ = DEFAULT_LOADED_EXPIRED_STORIES; + next_request_delay = Random::fast(300, 420); + } + set_timeout_in(next_request_delay); + + LOG(INFO) << "Receive " << stories.size() << " expired stories with next request in " << next_request_delay + << " seconds"; + for (auto &database_story : stories) { + auto story = parse_story(database_story.story_full_id_, std::move(database_story.data_)); + if (story != nullptr) { + LOG(ERROR) << "Receive non-expired " << database_story.story_full_id_; + } + } +} + +bool StoryManager::is_my_story(DialogId owner_dialog_id) const { + return owner_dialog_id == td_->dialog_manager_->get_my_dialog_id(); +} + +bool StoryManager::can_access_expired_story(DialogId owner_dialog_id, const Story *story) const { + CHECK(story != nullptr); + CHECK(story->content_ != nullptr); + // non-pinned non-editable stories can't be accessed after they expire + return story->is_pinned_ || can_edit_stories(owner_dialog_id); +} + +bool StoryManager::can_get_story_view_count(DialogId owner_dialog_id) { + // result must be stable over time + switch (owner_dialog_id.get_type()) { + case DialogType::User: + return is_my_story(owner_dialog_id); + case DialogType::Chat: + case DialogType::Channel: + case DialogType::SecretChat: + case DialogType::None: + default: + return true; + } +} + +bool StoryManager::can_post_stories(DialogId owner_dialog_id) const { + switch (owner_dialog_id.get_type()) { + case DialogType::User: + return is_my_story(owner_dialog_id); + case DialogType::Channel: + return td_->chat_manager_->get_channel_status(owner_dialog_id.get_channel_id()).can_post_stories(); + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + return false; + } +} + +bool StoryManager::can_edit_stories(DialogId owner_dialog_id) const { + switch (owner_dialog_id.get_type()) { + case DialogType::User: + return is_my_story(owner_dialog_id); + case DialogType::Channel: + return td_->chat_manager_->get_channel_status(owner_dialog_id.get_channel_id()).can_edit_stories(); + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + return false; + } +} + +bool StoryManager::can_delete_stories(DialogId owner_dialog_id) const { + switch (owner_dialog_id.get_type()) { + case DialogType::User: + return is_my_story(owner_dialog_id); + case DialogType::Channel: + return td_->chat_manager_->get_channel_status(owner_dialog_id.get_channel_id()).can_delete_stories(); + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + return false; + } +} + +bool StoryManager::can_edit_story(StoryFullId story_full_id, const Story *story) const { + if (!story_full_id.get_story_id().is_server()) { + return false; + } + auto owner_dialog_id = story_full_id.get_dialog_id(); + return can_edit_stories(owner_dialog_id) || (story->is_outgoing_ && can_post_stories(owner_dialog_id)); +} + +bool StoryManager::can_toggle_story_is_pinned(StoryFullId story_full_id, const Story *story) const { + if (!story_full_id.get_story_id().is_server()) { + return false; + } + return can_edit_stories(story_full_id.get_dialog_id()); +} + +bool StoryManager::can_delete_story(StoryFullId story_full_id, const Story *story) const { + if (!story_full_id.get_story_id().is_server()) { + return true; + } + auto owner_dialog_id = story_full_id.get_dialog_id(); + return can_delete_stories(owner_dialog_id) || (story->is_outgoing_ && can_post_stories(owner_dialog_id)); +} + +bool StoryManager::is_active_story(const Story *story) { + return story != nullptr && G()->unix_time() < story->expire_date_; +} + +int32 StoryManager::get_story_viewers_expire_date(const Story *story) const { + return story->expire_date_ + + narrow_cast(td_->option_manager_->get_option_integer("story_viewers_expiration_delay", 86400)); +} + +const StoryManager::Story *StoryManager::get_story(StoryFullId story_full_id) const { + return stories_.get_pointer(story_full_id); +} + +StoryManager::Story *StoryManager::get_story_editable(StoryFullId story_full_id) { + return stories_.get_pointer(story_full_id); +} + +StoryManager::Story *StoryManager::get_story_force(StoryFullId story_full_id, const char *source) { + if (!story_full_id.is_valid()) { + return nullptr; + } + + auto story = get_story_editable(story_full_id); + if (story != nullptr && story->content_ != nullptr) { + return story; + } + + if (!G()->use_message_database() || failed_to_load_story_full_ids_.count(story_full_id) > 0 || + is_inaccessible_story(story_full_id) || deleted_story_full_ids_.count(story_full_id) > 0 || + !story_full_id.get_story_id().is_server()) { + return nullptr; + } + + LOG(INFO) << "Trying to load " << story_full_id << " from database from " << source; + + auto r_value = G()->td_db()->get_story_db_sync()->get_story(story_full_id); + if (r_value.is_error()) { + failed_to_load_story_full_ids_.insert(story_full_id); + return nullptr; + } + return on_get_story_from_database(story_full_id, r_value.ok(), source); +} + +unique_ptr StoryManager::parse_story(StoryFullId story_full_id, const BufferSlice &value) { + auto story = make_unique(); + auto status = log_event_parse(*story, value.as_slice()); + if (status.is_error()) { + LOG(ERROR) << "Receive invalid " << story_full_id << " from database: " << status << ' ' + << format::as_hex_dump<4>(value.as_slice()); + delete_story_from_database(story_full_id); + reload_story(story_full_id, Auto(), "parse_story"); + return nullptr; + } + if (story->content_ == nullptr) { + LOG(ERROR) << "Receive " << story_full_id << " without content from database"; + delete_story_from_database(story_full_id); + return nullptr; + } + if (!story_full_id.get_story_id().is_server()) { + LOG(ERROR) << "Receive " << story_full_id << " from database"; + delete_story_from_database(story_full_id); + return nullptr; + } + + auto owner_dialog_id = story_full_id.get_dialog_id(); + if (is_active_story(story.get())) { + auto active_stories = get_active_stories(owner_dialog_id); + if (active_stories != nullptr && !contains(active_stories->story_ids_, story_full_id.get_story_id())) { + LOG(INFO) << "Ignore unavailable active " << story_full_id << " from database"; + delete_story_files(story.get()); + delete_story_from_database(story_full_id); + return nullptr; + } + } else { + if (!can_access_expired_story(owner_dialog_id, story.get())) { + LOG(INFO) << "Delete expired " << story_full_id; + delete_story_files(story.get()); + delete_story_from_database(story_full_id); + return nullptr; + } + } + if (is_my_story(owner_dialog_id)) { + story->is_outgoing_ = true; + } + + return story; +} + +StoryManager::Story *StoryManager::on_get_story_from_database(StoryFullId story_full_id, const BufferSlice &value, + const char *source) { + auto old_story = get_story_editable(story_full_id); + if (old_story != nullptr && old_story->content_ != nullptr) { + return old_story; + } + + if (value.empty()) { + failed_to_load_story_full_ids_.insert(story_full_id); + return nullptr; + } + + auto story = parse_story(story_full_id, value); + if (story == nullptr) { + failed_to_load_story_full_ids_.insert(story_full_id); + return nullptr; + } + + Dependencies dependencies; + add_story_dependencies(dependencies, story.get()); + if (!dependencies.resolve_force(td_, "on_get_story_from_database")) { + reload_story(story_full_id, Auto(), "on_get_story_from_database"); + failed_to_load_story_full_ids_.insert(story_full_id); + return nullptr; + } + + LOG(INFO) << "Load new " << story_full_id << " from " << source; + + auto result = story.get(); + stories_.set(story_full_id, std::move(story)); + register_story_global_id(story_full_id, result); + + CHECK(!is_inaccessible_story(story_full_id)); + CHECK(being_edited_stories_.count(story_full_id) == 0); + + on_story_changed(story_full_id, result, true, false, true); + + return result; +} + +bool StoryManager::can_get_story_statistics(StoryFullId story_full_id) { + return can_get_story_statistics(story_full_id, get_story_force(story_full_id, "can_get_story_statistics")); +} + +bool StoryManager::can_get_story_statistics(StoryFullId story_full_id, const Story *story) const { + if (td_->auth_manager_->is_bot()) { + return false; + } + if (story == nullptr || !story_full_id.get_story_id().is_server()) { + return false; + } + auto dialog_id = story_full_id.get_dialog_id(); + return dialog_id.get_type() == DialogType::Channel && + td_->chat_manager_->can_get_channel_story_statistics(dialog_id.get_channel_id()); +} + +const StoryManager::ActiveStories *StoryManager::get_active_stories(DialogId owner_dialog_id) const { + return active_stories_.get_pointer(owner_dialog_id); +} + +StoryManager::ActiveStories *StoryManager::get_active_stories_editable(DialogId owner_dialog_id) { + return active_stories_.get_pointer(owner_dialog_id); +} + +StoryManager::ActiveStories *StoryManager::get_active_stories_force(DialogId owner_dialog_id, const char *source) { + auto active_stories = get_active_stories_editable(owner_dialog_id); + if (active_stories != nullptr) { + return active_stories; + } + + if (!G()->use_message_database() || failed_to_load_active_stories_.count(owner_dialog_id) > 0 || + !owner_dialog_id.is_valid()) { + return nullptr; + } + + LOG(INFO) << "Trying to load active stories of " << owner_dialog_id << " from database from " << source; + auto r_value = G()->td_db()->get_story_db_sync()->get_active_stories(owner_dialog_id); + if (r_value.is_error()) { + failed_to_load_active_stories_.insert(owner_dialog_id); + return nullptr; + } + return on_get_active_stories_from_database(StoryListId(), owner_dialog_id, r_value.ok(), source); +} + +StoryManager::ActiveStories *StoryManager::on_get_active_stories_from_database(StoryListId story_list_id, + DialogId owner_dialog_id, + const BufferSlice &value, + const char *source) { + auto active_stories = get_active_stories_editable(owner_dialog_id); + if (active_stories != nullptr) { + return active_stories; + } + + if (value.empty()) { + failed_to_load_active_stories_.insert(owner_dialog_id); + return nullptr; + } + + SavedActiveStories saved_active_stories; + auto status = log_event_parse(saved_active_stories, value.as_slice()); + if (status.is_error()) { + LOG(ERROR) << "Receive invalid active stories in " << owner_dialog_id << " from database: " << status << ' ' + << format::as_hex_dump<4>(value.as_slice()); + save_active_stories(owner_dialog_id, nullptr, Promise(), "on_get_active_stories_from_database"); + failed_to_load_active_stories_.insert(owner_dialog_id); + return nullptr; + } + + vector story_ids; + for (auto &story_info : saved_active_stories.story_infos_) { + story_ids.push_back(on_get_story_info(owner_dialog_id, std::move(story_info))); + } + + on_update_active_stories(owner_dialog_id, saved_active_stories.max_read_story_id_, std::move(story_ids), + Promise(), "on_get_active_stories_from_database", true); + + active_stories = get_active_stories_editable(owner_dialog_id); + if (active_stories == nullptr) { + if (!story_list_id.is_valid()) { + story_list_id = get_dialog_story_list_id(owner_dialog_id); + } + if (story_list_id.is_valid()) { + auto &story_list = get_story_list(story_list_id); + if (!story_list.is_reloaded_server_total_count_ && + story_list.server_total_count_ > static_cast(story_list.ordered_stories_.size())) { + story_list.server_total_count_--; + update_story_list_sent_total_count(story_list_id, story_list, "on_get_active_stories_from_database"); + save_story_list(story_list_id, story_list.state_, story_list.server_total_count_, story_list.server_has_more_); + } + } + } + return active_stories; +} + +void StoryManager::add_story_dependencies(Dependencies &dependencies, const Story *story) { + if (story->forward_info_ != nullptr) { + story->forward_info_->add_dependencies(dependencies); + } + story->interaction_info_.add_dependencies(dependencies); + dependencies.add_message_sender_dependencies(story->sender_dialog_id_); + story->privacy_rules_.add_dependencies(dependencies); + if (story->content_ != nullptr) { + add_story_content_dependencies(dependencies, story->content_.get()); + } + add_formatted_text_dependencies(dependencies, &story->caption_); + for (const auto &media_area : story->areas_) { + media_area.add_dependencies(dependencies); + } +} + +void StoryManager::add_pending_story_dependencies(Dependencies &dependencies, const PendingStory *pending_story) { + dependencies.add_dialog_and_dependencies(pending_story->dialog_id_); + add_story_dependencies(dependencies, pending_story->story_.get()); +} + +void StoryManager::load_active_stories(StoryListId story_list_id, Promise &&promise) { + if (!story_list_id.is_valid()) { + return promise.set_error(Status::Error(400, "Story list must be non-empty")); + } + auto &story_list = get_story_list(story_list_id); + if (story_list.list_last_story_date_ == MAX_DIALOG_DATE) { + return promise.set_error(Status::Error(404, "Not found")); + } + + if (story_list.database_has_more_) { + CHECK(G()->use_message_database()); + story_list.load_list_from_database_queries_.push_back(std::move(promise)); + if (story_list.load_list_from_database_queries_.size() == 1u) { + G()->td_db()->get_story_db_async()->get_active_story_list( + story_list_id, story_list.last_loaded_database_dialog_date_.get_order(), + story_list.last_loaded_database_dialog_date_.get_dialog_id(), 10, + PromiseCreator::lambda( + [actor_id = actor_id(this), story_list_id](Result &&result) { + send_closure(actor_id, &StoryManager::on_load_active_stories_from_database, story_list_id, + std::move(result)); + })); + } + return; + } + + if (!story_list.server_has_more_) { + if (story_list.list_last_story_date_ != MAX_DIALOG_DATE) { + auto min_story_date = story_list.list_last_story_date_; + story_list.list_last_story_date_ = MAX_DIALOG_DATE; + for (auto it = story_list.ordered_stories_.upper_bound(min_story_date); it != story_list.ordered_stories_.end(); + ++it) { + on_dialog_active_stories_order_updated(it->get_dialog_id(), "load_active_stories"); + } + update_story_list_sent_total_count(story_list_id, story_list, "load_active_stories"); + } + return promise.set_error(Status::Error(404, "Not found")); + } + + load_active_stories_from_server(story_list_id, story_list, !story_list.state_.empty(), std::move(promise)); +} + +void StoryManager::on_load_active_stories_from_database(StoryListId story_list_id, + Result result) { + G()->ignore_result_if_closing(result); + auto &story_list = get_story_list(story_list_id); + auto promises = std::move(story_list.load_list_from_database_queries_); + CHECK(!promises.empty()); + if (result.is_error()) { + return fail_promises(promises, result.move_as_error()); + } + + auto active_story_list = result.move_as_ok(); + + LOG(INFO) << "Load " << active_story_list.active_stories_.size() << " chats with active stories in " << story_list_id + << " from database"; + + bool is_bad = false; + FlatHashSet owner_dialog_ids; + Dependencies dependencies; + for (auto &active_stories_it : active_story_list.active_stories_) { + auto owner_dialog_id = active_stories_it.first; + if (owner_dialog_id.is_valid()) { + dependencies.add_dialog_and_dependencies(owner_dialog_id); + owner_dialog_ids.insert(owner_dialog_id); + } else { + is_bad = true; + } + } + if (is_bad || !dependencies.resolve_force(td_, "on_load_active_stories_from_database")) { + active_story_list.active_stories_.clear(); + story_list.state_.clear(); + story_list.server_has_more_ = true; + } + + if (active_story_list.active_stories_.empty()) { + story_list.last_loaded_database_dialog_date_ = MAX_DIALOG_DATE; + story_list.database_has_more_ = false; + } else { + for (auto &active_stories_it : active_story_list.active_stories_) { + on_get_active_stories_from_database(story_list_id, active_stories_it.first, active_stories_it.second, + "on_load_active_stories_from_database"); + } + DialogDate max_story_date(active_story_list.next_order_, active_story_list.next_dialog_id_); + if (story_list.last_loaded_database_dialog_date_ < max_story_date) { + story_list.last_loaded_database_dialog_date_ = max_story_date; + + if (story_list.list_last_story_date_ < max_story_date) { + auto min_story_date = story_list.list_last_story_date_; + story_list.list_last_story_date_ = max_story_date; + for (auto it = story_list.ordered_stories_.upper_bound(min_story_date); + it != story_list.ordered_stories_.end() && *it <= max_story_date; ++it) { + auto dialog_id = it->get_dialog_id(); + owner_dialog_ids.erase(dialog_id); + on_dialog_active_stories_order_updated(dialog_id, "on_load_active_stories_from_database 1"); + } + for (auto owner_dialog_id : owner_dialog_ids) { + on_dialog_active_stories_order_updated(owner_dialog_id, "on_load_active_stories_from_database 2"); + } + } + } else { + LOG(ERROR) << "Last database story date didn't increase"; + } + update_story_list_sent_total_count(story_list_id, story_list, "on_load_active_stories_from_database"); + } + + set_promises(promises); +} + +void StoryManager::load_active_stories_from_server(StoryListId story_list_id, StoryList &story_list, bool is_next, + Promise &&promise) { + story_list.load_list_from_server_queries_.push_back(std::move(promise)); + if (story_list.load_list_from_server_queries_.size() == 1u) { + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), story_list_id, is_next, state = story_list.state_]( + Result> r_all_stories) { + send_closure(actor_id, &StoryManager::on_load_active_stories_from_server, story_list_id, is_next, state, + std::move(r_all_stories)); + }); + td_->create_handler(std::move(query_promise))->send(story_list_id, is_next, story_list.state_); + } +} + +void StoryManager::reload_active_stories() { + for (auto story_list_id : {StoryListId::main(), StoryListId::archive()}) { + load_active_stories_from_server(story_list_id, get_story_list(story_list_id), false, Promise()); + } +} + +void StoryManager::on_load_active_stories_from_server( + StoryListId story_list_id, bool is_next, string old_state, + Result> r_all_stories) { + G()->ignore_result_if_closing(r_all_stories); + auto &story_list = get_story_list(story_list_id); + auto promises = std::move(story_list.load_list_from_server_queries_); + CHECK(!promises.empty()); + if (r_all_stories.is_error()) { + return fail_promises(promises, r_all_stories.move_as_error()); + } + auto all_stories = r_all_stories.move_as_ok(); + switch (all_stories->get_id()) { + case telegram_api::stories_allStoriesNotModified::ID: { + auto stories = telegram_api::move_object_as(all_stories); + if (stories->state_.empty()) { + LOG(ERROR) << "Receive empty state in " << to_string(stories); + } else { + story_list.state_ = std::move(stories->state_); + save_story_list(story_list_id, story_list.state_, story_list.server_total_count_, story_list.server_has_more_); + } + on_update_story_stealth_mode(std::move(stories->stealth_mode_)); + break; + } + case telegram_api::stories_allStories::ID: { + auto stories = telegram_api::move_object_as(all_stories); + td_->user_manager_->on_get_users(std::move(stories->users_), "on_load_active_stories_from_server"); + td_->chat_manager_->on_get_chats(std::move(stories->chats_), "on_load_active_stories_from_server"); + if (stories->state_.empty()) { + LOG(ERROR) << "Receive empty state in " << to_string(stories); + } else { + story_list.state_ = std::move(stories->state_); + } + story_list.server_total_count_ = max(stories->count_, 0); + story_list.is_reloaded_server_total_count_ = true; + if (!stories->has_more_ || stories->peer_stories_.empty()) { + story_list.server_has_more_ = false; + } + + MultiPromiseActorSafe mpas{"SaveActiveStoryMultiPromiseActor"}; + mpas.add_promise(PromiseCreator::lambda([actor_id = actor_id(this), story_list_id, state = story_list.state_, + server_total_count = story_list.server_total_count_, + has_more = story_list.server_has_more_](Result &&result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &StoryManager::save_story_list, story_list_id, std::move(state), server_total_count, + has_more); + } + })); + auto lock = mpas.get_promise(); + + if (stories->peer_stories_.empty() && stories->has_more_) { + LOG(ERROR) << "Receive no stories, but expected more"; + stories->has_more_ = false; + } + + auto max_story_date = MIN_DIALOG_DATE; + vector owner_dialog_ids; + for (auto &peer_stories : stories->peer_stories_) { + auto owner_dialog_id = on_get_dialog_stories(DialogId(), std::move(peer_stories), mpas.get_promise()); + auto active_stories = get_active_stories(owner_dialog_id); + if (active_stories == nullptr) { + LOG(ERROR) << "Receive invalid stories"; + } else { + DialogDate story_date(active_stories->private_order_, owner_dialog_id); + if (max_story_date < story_date) { + max_story_date = story_date; + } else { + LOG(ERROR) << "Receive " << story_date << " after " << max_story_date << " for " + << (is_next ? "next" : "first") << " request with state \"" << old_state << "\" in " + << story_list_id << " of " << td_->user_manager_->get_my_id(); + } + owner_dialog_ids.push_back(owner_dialog_id); + } + } + if (!stories->has_more_) { + max_story_date = MAX_DIALOG_DATE; + } + + vector delete_dialog_ids; + auto min_story_date = is_next ? story_list.list_last_story_date_ : MIN_DIALOG_DATE; + for (auto it = story_list.ordered_stories_.upper_bound(min_story_date); + it != story_list.ordered_stories_.end() && *it <= max_story_date; ++it) { + auto dialog_id = it->get_dialog_id(); + if (!td::contains(owner_dialog_ids, dialog_id)) { + delete_dialog_ids.push_back(dialog_id); + } + } + if (story_list.list_last_story_date_ < max_story_date) { + story_list.list_last_story_date_ = max_story_date; + for (auto owner_dialog_id : owner_dialog_ids) { + on_dialog_active_stories_order_updated(owner_dialog_id, "on_load_active_stories_from_server"); + } + } else if (is_next) { + LOG(ERROR) << "Last story date didn't increase"; + } + if (!delete_dialog_ids.empty()) { + LOG(INFO) << "Delete active stories in " << delete_dialog_ids; + } + for (auto dialog_id : delete_dialog_ids) { + on_update_active_stories(dialog_id, StoryId(), vector(), mpas.get_promise(), + "on_load_active_stories_from_server"); + load_dialog_expiring_stories(dialog_id, 0, "on_load_active_stories_from_server 1"); + } + update_story_list_sent_total_count(story_list_id, story_list, "on_load_active_stories_from_server"); + + lock.set_value(Unit()); + + on_update_story_stealth_mode(std::move(stories->stealth_mode_)); + break; + } + default: + UNREACHABLE(); + } + + set_promises(promises); +} + +void StoryManager::save_story_list(StoryListId story_list_id, string state, int32 total_count, bool has_more) { + if (G()->close_flag() || !G()->use_message_database()) { + return; + } + + SavedStoryList saved_story_list; + saved_story_list.state_ = std::move(state); + saved_story_list.total_count_ = total_count; + saved_story_list.has_more_ = has_more; + G()->td_db()->get_story_db_async()->add_active_story_list_state(story_list_id, log_event_store(saved_story_list), + Promise()); +} + +StoryManager::StoryList &StoryManager::get_story_list(StoryListId story_list_id) { + CHECK(!td_->auth_manager_->is_bot()); + CHECK(story_list_id.is_valid()); + return story_lists_[story_list_id == StoryListId::archive()]; +} + +const StoryManager::StoryList &StoryManager::get_story_list(StoryListId story_list_id) const { + CHECK(!td_->auth_manager_->is_bot()); + CHECK(story_list_id.is_valid()); + return story_lists_[story_list_id == StoryListId::archive()]; +} + +td_api::object_ptr StoryManager::get_update_story_list_chat_count_object( + StoryListId story_list_id, const StoryList &story_list) const { + CHECK(story_list_id.is_valid()); + return td_api::make_object(story_list_id.get_story_list_object(), + story_list.sent_total_count_); +} + +void StoryManager::update_story_list_sent_total_count(StoryListId story_list_id, const char *source) { + if (td_->auth_manager_->is_bot()) { + return; + } + update_story_list_sent_total_count(story_list_id, get_story_list(story_list_id), source); +} + +void StoryManager::update_story_list_sent_total_count(StoryListId story_list_id, StoryList &story_list, + const char *source) { + if (story_list.server_total_count_ == -1 || td_->auth_manager_->is_bot()) { + return; + } + LOG(INFO) << "Update story list sent total chat count in " << story_list_id << " from " << source; + auto new_total_count = static_cast(story_list.ordered_stories_.size()); + auto yet_unsent_total_count = 0; + for (const auto &it : yet_unsent_story_ids_) { + if (active_stories_.count(it.first) == 0) { + yet_unsent_total_count++; + } + } + new_total_count += yet_unsent_total_count; + if (story_list.list_last_story_date_ != MAX_DIALOG_DATE) { + new_total_count = max(new_total_count, story_list.server_total_count_ + yet_unsent_total_count); + } else if (story_list.server_total_count_ != new_total_count) { + story_list.server_total_count_ = new_total_count; + save_story_list(story_list_id, story_list.state_, story_list.server_total_count_, story_list.server_has_more_); + } + if (story_list.sent_total_count_ != new_total_count) { + story_list.sent_total_count_ = new_total_count; + send_closure(G()->td(), &Td::send_update, get_update_story_list_chat_count_object(story_list_id, story_list)); + } +} + +void StoryManager::reload_all_read_stories() { + td_->create_handler()->send(); +} + +void StoryManager::try_synchronize_archive_all_stories() { + if (G()->close_flag()) { + return; + } + if (has_active_synchronize_archive_all_stories_query_) { + return; + } + if (!td_->option_manager_->get_option_boolean("need_synchronize_archive_all_stories")) { + return; + } + + has_active_synchronize_archive_all_stories_query_ = true; + auto archive_all_stories = td_->option_manager_->get_option_boolean("archive_all_stories"); + + auto promise = PromiseCreator::lambda([actor_id = actor_id(this), archive_all_stories](Result result) { + send_closure(actor_id, &StoryManager::on_synchronized_archive_all_stories, archive_all_stories, std::move(result)); + }); + td_->create_handler(std::move(promise))->send(archive_all_stories); +} + +void StoryManager::on_synchronized_archive_all_stories(bool set_archive_all_stories, Result result) { + if (G()->close_flag()) { + return; + } + CHECK(has_active_synchronize_archive_all_stories_query_); + has_active_synchronize_archive_all_stories_query_ = false; + + auto archive_all_stories = td_->option_manager_->get_option_boolean("archive_all_stories"); + if (archive_all_stories != set_archive_all_stories) { + return try_synchronize_archive_all_stories(); + } + td_->option_manager_->set_option_empty("need_synchronize_archive_all_stories"); + + if (result.is_error()) { + send_closure(G()->config_manager(), &ConfigManager::reget_app_config, Promise()); + } +} + +void StoryManager::toggle_dialog_stories_hidden(DialogId dialog_id, StoryListId story_list_id, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Read, + "toggle_dialog_stories_hidden")); + if (story_list_id == get_dialog_story_list_id(dialog_id)) { + return promise.set_value(Unit()); + } + if (!story_list_id.is_valid()) { + return promise.set_error(Status::Error(400, "Story list must be non-empty")); + } + + td_->create_handler(std::move(promise)) + ->send(dialog_id, story_list_id == StoryListId::archive()); +} + +void StoryManager::get_dialog_pinned_stories(DialogId owner_dialog_id, StoryId from_story_id, int32 limit, + Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(owner_dialog_id, false, AccessRights::Read, + "get_dialog_pinned_stories")); + + if (from_story_id != StoryId() && !from_story_id.is_server()) { + return promise.set_error(Status::Error(400, "Invalid value of parameter from_story_id specified")); + } + + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), owner_dialog_id, promise = std::move(promise)]( + Result> &&result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &StoryManager::on_get_dialog_pinned_stories, owner_dialog_id, result.move_as_ok(), + std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(owner_dialog_id, from_story_id, limit); +} + +void StoryManager::on_get_dialog_pinned_stories(DialogId owner_dialog_id, + telegram_api::object_ptr &&stories, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + auto pinned_story_ids = StoryId::get_story_ids(stories->pinned_to_top_); + auto result = on_get_stories(owner_dialog_id, {}, std::move(stories)); + on_update_dialog_has_pinned_stories(owner_dialog_id, result.first > 0); + promise.set_value(get_stories_object( + result.first, + transform(result.second, [owner_dialog_id](StoryId story_id) { return StoryFullId(owner_dialog_id, story_id); }), + pinned_story_ids)); +} + +void StoryManager::get_story_archive(DialogId owner_dialog_id, StoryId from_story_id, int32 limit, + Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (from_story_id != StoryId() && !from_story_id.is_server()) { + return promise.set_error(Status::Error(400, "Invalid value of parameter from_story_id specified")); + } + if (!td_->dialog_manager_->have_dialog_force(owner_dialog_id, "get_story_archive")) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + if (!can_edit_stories(owner_dialog_id)) { + return promise.set_error(Status::Error(400, "Can't get story archive in the chat")); + } + + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), owner_dialog_id, promise = std::move(promise)]( + Result> &&result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &StoryManager::on_get_story_archive, owner_dialog_id, result.move_as_ok(), + std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(owner_dialog_id, from_story_id, limit); +} + +void StoryManager::on_get_story_archive(DialogId owner_dialog_id, + telegram_api::object_ptr &&stories, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + LOG_IF(ERROR, !stories->pinned_to_top_.empty()) << "Receive pinned stories in archive"; + auto result = on_get_stories(owner_dialog_id, {}, std::move(stories)); + promise.set_value(get_stories_object( + result.first, + transform(result.second, [owner_dialog_id](StoryId story_id) { return StoryFullId(owner_dialog_id, story_id); }), + {})); +} + +void StoryManager::get_dialog_expiring_stories(DialogId owner_dialog_id, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(owner_dialog_id, false, AccessRights::Read, + "get_dialog_expiring_stories")); + + LOG(INFO) << "Get active stories in " << owner_dialog_id; + auto active_stories = get_active_stories_force(owner_dialog_id, "get_dialog_expiring_stories"); + if (active_stories != nullptr) { + if (!promise) { + return promise.set_value(nullptr); + } + if (updated_active_stories_.insert(owner_dialog_id)) { + send_update_chat_active_stories(owner_dialog_id, active_stories, "get_dialog_expiring_stories 2"); + } + promise.set_value(get_chat_active_stories_object(owner_dialog_id, active_stories)); + promise = {}; + } + + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), owner_dialog_id, promise = std::move(promise)]( + Result> &&result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &StoryManager::on_get_dialog_expiring_stories, owner_dialog_id, result.move_as_ok(), + std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(owner_dialog_id); +} + +void StoryManager::reload_dialog_expiring_stories(DialogId dialog_id) { + if (!td_->dialog_manager_->have_input_peer(dialog_id, false, AccessRights::Read)) { + return; + } + td_->dialog_manager_->force_create_dialog(dialog_id, "reload_dialog_expiring_stories"); + load_dialog_expiring_stories(dialog_id, 0, "reload_dialog_expiring_stories"); +} + +class StoryManager::LoadDialogExpiringStoriesLogEvent { + public: + DialogId dialog_id_; + + template + void store(StorerT &storer) const { + td::store(dialog_id_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(dialog_id_, parser); + } +}; + +uint64 StoryManager::save_load_dialog_expiring_stories_log_event(DialogId owner_dialog_id) { + LoadDialogExpiringStoriesLogEvent log_event{owner_dialog_id}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::LoadDialogExpiringStories, + get_log_event_storer(log_event)); +} + +void StoryManager::load_dialog_expiring_stories(DialogId owner_dialog_id, uint64 log_event_id, const char *source) { + if (load_expiring_stories_log_event_ids_.count(owner_dialog_id) > 0) { + if (log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), log_event_id); + } + return; + } + LOG(INFO) << "Load active stories in " << owner_dialog_id << " from " << source; + if (log_event_id == 0 && G()->use_message_database()) { + log_event_id = save_load_dialog_expiring_stories_log_event(owner_dialog_id); + } + load_expiring_stories_log_event_ids_[owner_dialog_id] = log_event_id; + + // send later to ensure that active stories are inited before sending the request + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this), owner_dialog_id](Result> &&) { + if (!G()->close_flag()) { + send_closure(actor_id, &StoryManager::on_load_dialog_expiring_stories, owner_dialog_id); + } + }); + send_closure_later(actor_id(this), &StoryManager::get_dialog_expiring_stories, owner_dialog_id, std::move(promise)); +} + +void StoryManager::on_load_dialog_expiring_stories(DialogId owner_dialog_id) { + if (G()->close_flag()) { + return; + } + auto it = load_expiring_stories_log_event_ids_.find(owner_dialog_id); + if (it == load_expiring_stories_log_event_ids_.end()) { + return; + } + auto log_event_id = it->second; + load_expiring_stories_log_event_ids_.erase(it); + if (log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), log_event_id); + } + LOG(INFO) << "Finished loading of active stories in " << owner_dialog_id; +} + +void StoryManager::on_get_dialog_expiring_stories(DialogId owner_dialog_id, + telegram_api::object_ptr &&stories, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + td_->user_manager_->on_get_users(std::move(stories->users_), "on_get_dialog_expiring_stories"); + td_->chat_manager_->on_get_chats(std::move(stories->chats_), "on_get_dialog_expiring_stories"); + owner_dialog_id = on_get_dialog_stories(owner_dialog_id, std::move(stories->stories_), Promise()); + if (promise) { + CHECK(owner_dialog_id.is_valid()); + auto active_stories = get_active_stories(owner_dialog_id); + if (updated_active_stories_.insert(owner_dialog_id)) { + send_update_chat_active_stories(owner_dialog_id, active_stories, "on_get_dialog_expiring_stories"); + } + promise.set_value(get_chat_active_stories_object(owner_dialog_id, active_stories)); + } else { + promise.set_value(nullptr); + } +} + +void StoryManager::search_hashtag_posts(string hashtag, string offset, int32 limit, + Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (limit > MAX_SEARCH_STORIES) { + limit = MAX_SEARCH_STORIES; + } + + bool is_cashtag = false; + if (hashtag[0] == '#' || hashtag[0] == '$') { + is_cashtag = (hashtag[0] == '$'); + hashtag = hashtag.substr(1); + } + if (hashtag.empty()) { + return promise.set_value(td_api::make_object()); + } + send_closure(is_cashtag ? td_->cashtag_search_hints_ : td_->hashtag_search_hints_, &HashtagHints::hashtag_used, + hashtag); + + td_->create_handler(std::move(promise)) + ->send(PSTRING() << (is_cashtag ? '$' : '#') << hashtag, offset, limit); +} + +void StoryManager::search_location_posts(td_api::object_ptr &&address, string offset, + int32 limit, Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (limit > MAX_SEARCH_STORIES) { + limit = MAX_SEARCH_STORIES; + } + + td_->create_handler(std::move(promise))->send(std::move(address), offset, limit); +} + +void StoryManager::search_venue_posts(string venue_provider, string venue_id, string offset, int32 limit, + Promise> &&promise) { + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (limit > MAX_SEARCH_STORIES) { + limit = MAX_SEARCH_STORIES; + } + + td_->create_handler(std::move(promise))->send(venue_provider, venue_id, offset, limit); +} + +void StoryManager::set_pinned_stories(DialogId owner_dialog_id, vector story_ids, Promise &&promise) { + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(owner_dialog_id, false, AccessRights::Write, + "set_pinned_stories")); + if (!can_edit_stories(owner_dialog_id)) { + return promise.set_error(Status::Error(400, "Can't change pinned stories in the chat")); + } + for (const auto &story_id : story_ids) { + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!story->is_pinned_) { + return promise.set_error(Status::Error(400, "The story must be posted to the chat page first")); + } + if (!story_id.is_server()) { + return promise.set_error(Status::Error(400, "Story must be sent first")); + } + } + td_->create_handler(std::move(promise))->send(owner_dialog_id, std::move(story_ids)); +} + +void StoryManager::open_story(DialogId owner_dialog_id, StoryId story_id, Promise &&promise) { + TRY_STATUS_PROMISE( + promise, td_->dialog_manager_->check_dialog_access(owner_dialog_id, false, AccessRights::Read, "open_story")); + if (!story_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid story identifier specified")); + } + + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story == nullptr) { + return promise.set_value(Unit()); + } + + if (can_get_story_view_count(owner_dialog_id) && story_id.is_server()) { + if (opened_stories_with_view_count_.empty()) { + schedule_interaction_info_update(); + } + auto &open_count = opened_stories_with_view_count_[story_full_id]; + if (++open_count == 1) { + td_->create_handler()->send(owner_dialog_id, {story_id}); + } + } + + if (story->content_ == nullptr) { + return promise.set_value(Unit()); + } + + if (story_id.is_server()) { + auto &open_count = opened_stories_[story_full_id]; + if (++open_count == 1) { + CHECK(story->global_id_ > 0); + story_reload_timeout_.set_timeout_in(story->global_id_, + story->receive_date_ + OPENED_STORY_POLL_PERIOD - G()->unix_time()); + } + } + + for (auto file_id : get_story_file_ids(story)) { + td_->file_manager_->check_local_location_async(file_id, true); + } + + bool is_active = is_active_story(story); + bool need_increment_story_views = story_id.is_server() && !is_active && story->is_pinned_; + bool need_read_story = story_id.is_server() && is_active; + + if (need_increment_story_views) { + auto &story_views = pending_story_views_[owner_dialog_id]; + story_views.story_ids_.insert(story_id); + if (!story_views.has_query_) { + increment_story_views(owner_dialog_id, story_views); + } + } + + if (need_read_story && on_update_read_stories(owner_dialog_id, story_id)) { + read_stories_on_server(owner_dialog_id, story_id, 0); + } + + promise.set_value(Unit()); +} + +void StoryManager::close_story(DialogId owner_dialog_id, StoryId story_id, Promise &&promise) { + TRY_STATUS_PROMISE( + promise, td_->dialog_manager_->check_dialog_access(owner_dialog_id, false, AccessRights::Read, "close_story")); + if (!story_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid story identifier specified")); + } + + StoryFullId story_full_id{owner_dialog_id, story_id}; + if (can_get_story_view_count(owner_dialog_id) && story_id.is_server()) { + auto &open_count = opened_stories_with_view_count_[story_full_id]; + if (open_count == 0) { + return promise.set_error(Status::Error(400, "The story wasn't opened")); + } + if (--open_count == 0) { + opened_stories_with_view_count_.erase(story_full_id); + if (opened_stories_with_view_count_.empty()) { + interaction_info_update_timeout_.cancel_timeout(); + } + } + } + + const Story *story = get_story(story_full_id); + if (story == nullptr) { + return promise.set_value(Unit()); + } + + if (story_id.is_server()) { + auto &open_count = opened_stories_[story_full_id]; + if (open_count > 0 && --open_count == 0) { + opened_stories_.erase(story_full_id); + story_reload_timeout_.cancel_timeout(story->global_id_); + } + } + + promise.set_value(Unit()); +} + +void StoryManager::view_story_message(StoryFullId story_full_id) { + if (!story_full_id.get_story_id().is_server()) { + return; + } + + const Story *story = get_story_force(story_full_id, "view_story_message"); + if (story == nullptr || story->receive_date_ < G()->unix_time() - VIEWED_STORY_POLL_PERIOD) { + reload_story(story_full_id, Promise(), "view_story_message"); + } +} + +void StoryManager::on_story_replied(StoryFullId story_full_id, UserId replier_user_id) { + if (!replier_user_id.is_valid() || replier_user_id == td_->user_manager_->get_my_id() || + !story_full_id.get_story_id().is_server()) { + return; + } + const Story *story = get_story_force(story_full_id, "on_story_replied"); + if (story == nullptr || !is_my_story(story_full_id.get_dialog_id())) { + return; + } + + if (story->content_ != nullptr && G()->unix_time() < get_story_viewers_expire_date(story) && + story->interaction_info_.definitely_has_no_user(replier_user_id)) { + td_->create_handler()->send(story_full_id.get_dialog_id(), {story_full_id.get_story_id()}); + } +} + +bool StoryManager::has_suggested_reaction(const Story *story, const ReactionType &reaction_type) { + if (reaction_type.is_empty() || reaction_type.is_paid_reaction()) { + return false; + } + CHECK(story != nullptr); + return any_of(story->areas_, [&reaction_type](const auto &area) { return area.has_reaction_type(reaction_type); }); +} + +bool StoryManager::can_use_story_reaction(const Story *story, const ReactionType &reaction_type) const { + if (reaction_type.is_empty()) { + return true; + } + if (reaction_type.is_custom_reaction()) { + if (td_->option_manager_->get_option_boolean("is_premium")) { + return true; + } + if (has_suggested_reaction(story, reaction_type)) { + return true; + } + return false; + } + if (reaction_type.is_paid_reaction()) { + return false; + } + return td_->reaction_manager_->is_active_reaction(reaction_type); +} + +void StoryManager::on_story_chosen_reaction_changed(StoryFullId story_full_id, Story *story, + const ReactionType &reaction_type) { + if (story == nullptr || story->chosen_reaction_type_ == reaction_type) { + return; + } + + if (story_full_id.get_dialog_id().get_type() != DialogType::User) { + bool need_add = has_suggested_reaction(story, reaction_type); + bool need_remove = has_suggested_reaction(story, story->chosen_reaction_type_); + if (need_add || need_remove) { + story->interaction_info_.set_chosen_reaction_type(need_add ? reaction_type : ReactionType(), + story->chosen_reaction_type_); + } + } + story->chosen_reaction_type_ = reaction_type; + on_story_changed(story_full_id, story, true, true); +} + +void StoryManager::set_story_reaction(StoryFullId story_full_id, ReactionType reaction_type, bool add_to_recent, + Promise &&promise) { + auto owner_dialog_id = story_full_id.get_dialog_id(); + TRY_STATUS_PROMISE(promise, td_->dialog_manager_->check_dialog_access(owner_dialog_id, false, AccessRights::Read, + "set_story_reaction")); + if (!story_full_id.get_story_id().is_valid()) { + return promise.set_error(Status::Error(400, "Invalid story identifier specified")); + } + if (!story_full_id.get_story_id().is_server()) { + return promise.set_error(Status::Error(400, "Can't react to the story")); + } + + Story *story = get_story_force(story_full_id, "set_story_reaction"); + if (story == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + + if (!can_use_story_reaction(story, reaction_type)) { + return promise.set_error(Status::Error(400, "The reaction isn't available for the story")); + } + + if (story->chosen_reaction_type_ == reaction_type) { + return promise.set_value(Unit()); + } + + if (add_to_recent) { + td_->reaction_manager_->add_recent_reaction(reaction_type); + } + + on_story_chosen_reaction_changed(story_full_id, story, reaction_type); + + being_set_story_reactions_[story_full_id] += 2; + + // TODO cancel previous queries, log event + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), story_full_id, + promise = std::move(promise)](Result &&result) mutable { + send_closure(actor_id, &StoryManager::on_set_story_reaction, story_full_id, std::move(result), std::move(promise)); + }); + + td_->create_handler(std::move(query_promise)) + ->send(story_full_id, reaction_type, add_to_recent); +} + +void StoryManager::on_set_story_reaction(StoryFullId story_full_id, Result &&result, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + auto need_reload_story = result.is_error(); + + auto it = being_set_story_reactions_.find(story_full_id); + CHECK(it != being_set_story_reactions_.end()); + it->second -= 2; + if (it->second <= 1) { + if (it->second == 1) { + need_reload_story = true; + } + being_set_story_reactions_.erase(it); + } + + if (!have_story_force(story_full_id)) { + return promise.set_value(Unit()); + } + + if (need_reload_story) { + reload_story(story_full_id, Promise(), "on_set_story_reaction"); + } + + promise.set_result(std::move(result)); +} + +void StoryManager::schedule_interaction_info_update() { + if (interaction_info_update_timeout_.has_timeout()) { + return; + } + + interaction_info_update_timeout_.set_callback(std::move(update_interaction_info_static)); + interaction_info_update_timeout_.set_callback_data(static_cast(this)); + interaction_info_update_timeout_.set_timeout_in(10.0); +} + +void StoryManager::update_interaction_info_static(void *story_manager) { + if (G()->close_flag()) { + return; + } + + CHECK(story_manager != nullptr); + static_cast(story_manager)->update_interaction_info(); +} + +void StoryManager::update_interaction_info() { + if (opened_stories_with_view_count_.empty()) { + return; + } + FlatHashMap, DialogIdHash> split_story_ids; + for (auto &it : opened_stories_with_view_count_) { + auto story_full_id = it.first; + auto &story_ids = split_story_ids[story_full_id.get_dialog_id()]; + if (story_ids.size() < 100) { + auto story_id = story_full_id.get_story_id(); + CHECK(story_id.is_server()); + story_ids.push_back(story_id); + } + } + for (auto &story_ids : split_story_ids) { + td_->create_handler()->send(story_ids.first, std::move(story_ids.second)); + } +} + +void StoryManager::increment_story_views(DialogId owner_dialog_id, PendingStoryViews &story_views) { + CHECK(!story_views.has_query_); + vector viewed_story_ids; + const size_t MAX_VIEWED_STORIES = 200; // server-side limit + while (!story_views.story_ids_.empty() && viewed_story_ids.size() < MAX_VIEWED_STORIES) { + auto story_id_it = story_views.story_ids_.begin(); + auto story_id = *story_id_it; + story_views.story_ids_.erase(story_id_it); + CHECK(story_id.is_server()); + viewed_story_ids.push_back(story_id); + } + CHECK(!viewed_story_ids.empty()); + story_views.has_query_ = true; + auto promise = PromiseCreator::lambda([actor_id = actor_id(this), owner_dialog_id](Result) { + send_closure(actor_id, &StoryManager::on_increment_story_views, owner_dialog_id); + }); + td_->create_handler(std::move(promise))->send(owner_dialog_id, std::move(viewed_story_ids)); +} + +void StoryManager::on_increment_story_views(DialogId owner_dialog_id) { + if (G()->close_flag()) { + return; + } + + auto &story_views = pending_story_views_[owner_dialog_id]; + CHECK(story_views.has_query_); + story_views.has_query_ = false; + if (story_views.story_ids_.empty()) { + pending_story_views_.erase(owner_dialog_id); + return; + } + increment_story_views(owner_dialog_id, story_views); +} + +class StoryManager::ReadStoriesOnServerLogEvent { + public: + DialogId dialog_id_; + StoryId max_story_id_; + + template + void store(StorerT &storer) const { + td::store(dialog_id_, storer); + td::store(max_story_id_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(dialog_id_, parser); + td::parse(max_story_id_, parser); + } +}; + +uint64 StoryManager::save_read_stories_on_server_log_event(DialogId dialog_id, StoryId max_story_id) { + ReadStoriesOnServerLogEvent log_event{dialog_id, max_story_id}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::ReadStoriesOnServer, + get_log_event_storer(log_event)); +} + +void StoryManager::read_stories_on_server(DialogId owner_dialog_id, StoryId story_id, uint64 log_event_id) { + CHECK(story_id.is_server()); + if (log_event_id == 0 && G()->use_message_database()) { + log_event_id = save_read_stories_on_server_log_event(owner_dialog_id, story_id); + } + + td_->create_handler(get_erase_log_event_promise(log_event_id))->send(owner_dialog_id, story_id); +} + +Status StoryManager::can_get_story_viewers(StoryFullId story_full_id, const Story *story, int32 unix_time) const { + CHECK(story != nullptr); + if (!is_my_story(story_full_id.get_dialog_id())) { + return Status::Error(400, "Story must be outgoing"); + } + if (!story_full_id.get_story_id().is_server()) { + return Status::Error(400, "Story is not sent yet"); + } + if (story->interaction_info_.get_reaction_count() > 0) { + return Status::OK(); + } + if (story->interaction_info_.has_hidden_viewers() && unix_time >= get_story_viewers_expire_date(story)) { + return Status::Error(400, "Story is too old"); + } + return Status::OK(); +} + +bool StoryManager::has_unexpired_viewers(StoryFullId story_full_id, const Story *story) const { + CHECK(story != nullptr); + return is_my_story(story_full_id.get_dialog_id()) && story_full_id.get_story_id().is_server() && + G()->unix_time() < get_story_viewers_expire_date(story); +} + +void StoryManager::get_channel_differences_if_needed( + telegram_api::object_ptr &&story_views, + Promise> promise) { + td_->user_manager_->on_get_users(std::move(story_views->users_), "stories_storyViewsList"); + td_->chat_manager_->on_get_chats(std::move(story_views->chats_), "stories_storyViewsList"); + + vector *> messages; + for (const auto &view : story_views->views_) { + CHECK(view != nullptr); + if (view->get_id() != telegram_api::storyViewPublicForward::ID) { + continue; + } + messages.push_back(&static_cast(view.get())->message_); + } + td_->messages_manager_->get_channel_differences_if_needed( + messages, + PromiseCreator::lambda([actor_id = actor_id(this), story_views = std::move(story_views), + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(std::move(story_views)); + } + }), + "stories_storyViewsList"); +} + +void StoryManager::get_story_interactions(StoryId story_id, const string &query, bool only_contacts, + bool prefer_forwards, bool prefer_with_reaction, const string &offset, + int32 limit, + Promise> &&promise) { + auto owner_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (!story_id.is_server()) { + return promise.set_value(td_api::make_object()); + } + + bool is_full = query.empty() && !only_contacts; + bool is_first = is_full && offset.empty(); + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), story_id, is_full, is_first, promise = std::move(promise)]( + Result> result) mutable { + send_closure(actor_id, &StoryManager::on_get_story_interactions, story_id, is_full, is_first, std::move(result), + std::move(promise)); + }); + + td_->create_handler(std::move(query_promise)) + ->send(owner_dialog_id, story_id, query, only_contacts, prefer_forwards, prefer_with_reaction, offset, limit); +} + +void StoryManager::on_get_story_interactions( + StoryId story_id, bool is_full, bool is_first, + Result> r_view_list, + Promise> &&promise) { + G()->ignore_result_if_closing(r_view_list); + if (r_view_list.is_error()) { + return promise.set_error(r_view_list.move_as_error()); + } + auto view_list = r_view_list.move_as_ok(); + + auto owner_dialog_id = td_->dialog_manager_->get_my_dialog_id(); + CHECK(story_id.is_server()); + StoryFullId story_full_id{owner_dialog_id, story_id}; + Story *story = get_story_editable(story_full_id); + if (story == nullptr) { + return promise.set_value(td_api::make_object()); + } + + auto total_count = view_list->count_; + if (total_count < 0 || static_cast(total_count) < view_list->views_.size()) { + LOG(ERROR) << "Receive total_count = " << total_count << " and " << view_list->views_.size() << " story viewers"; + total_count = static_cast(view_list->views_.size()); + } + auto total_reaction_count = view_list->reactions_count_; + if (total_reaction_count < 0 || total_reaction_count > total_count) { + LOG(ERROR) << "Receive total_reaction_count = " << total_reaction_count << " with " << total_count + << " story viewers"; + total_reaction_count = total_count; + } + auto total_forward_count = max(view_list->forwards_count_, 0); + + StoryViewers story_viewers(td_, total_count, total_forward_count, total_reaction_count, std::move(view_list->views_), + std::move(view_list->next_offset_)); + if (story->content_ != nullptr) { + bool is_changed = false; + if (is_full && story->interaction_info_.set_counts(total_count, total_reaction_count)) { + is_changed = true; + } + if (is_first && story->interaction_info_.set_recent_viewer_user_ids(story_viewers.get_viewer_user_ids())) { + is_changed = true; + } + if (is_changed) { + on_story_changed(story_full_id, story, true, true); + } + } + + on_view_dialog_active_stories(story_viewers.get_actor_dialog_ids()); + promise.set_value(story_viewers.get_story_interactions_object(td_)); +} + +void StoryManager::get_channel_differences_if_needed( + telegram_api::object_ptr &&story_reactions, + Promise> promise) { + td_->user_manager_->on_get_users(std::move(story_reactions->users_), "stories_storyReactionsList"); + td_->chat_manager_->on_get_chats(std::move(story_reactions->chats_), "stories_storyReactionsList"); + + vector *> messages; + for (const auto &reaction : story_reactions->reactions_) { + CHECK(reaction != nullptr); + if (reaction->get_id() != telegram_api::storyReactionPublicForward::ID) { + continue; + } + messages.push_back(&static_cast(reaction.get())->message_); + } + td_->messages_manager_->get_channel_differences_if_needed( + messages, + PromiseCreator::lambda([actor_id = actor_id(this), story_reactions = std::move(story_reactions), + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + promise.set_value(std::move(story_reactions)); + } + }), + "stories_storyReactionsList"); +} + +void StoryManager::get_dialog_story_interactions(StoryFullId story_full_id, ReactionType reaction_type, + bool prefer_forwards, const string &offset, int32 limit, + Promise> &&promise) { + const Story *story = get_story(story_full_id); + if (story == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (!story_full_id.get_story_id().is_server()) { + return promise.set_value(td_api::make_object()); + } + if (reaction_type.is_paid_reaction()) { + return promise.set_error(Status::Error(400, "Stories can't have paid reactions")); + } + + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), story_full_id, promise = std::move(promise)]( + Result> result) mutable { + send_closure(actor_id, &StoryManager::on_get_dialog_story_interactions, story_full_id, std::move(result), + std::move(promise)); + }); + + td_->create_handler(std::move(query_promise)) + ->send(story_full_id, reaction_type, prefer_forwards, offset, limit); +} + +void StoryManager::on_get_dialog_story_interactions( + StoryFullId story_full_id, + Result> r_reaction_list, + Promise> &&promise) { + G()->ignore_result_if_closing(r_reaction_list); + if (r_reaction_list.is_error()) { + return promise.set_error(r_reaction_list.move_as_error()); + } + auto reaction_list = r_reaction_list.move_as_ok(); + + Story *story = get_story_editable(story_full_id); + if (story == nullptr) { + return promise.set_value(td_api::make_object()); + } + + auto total_count = reaction_list->count_; + if (total_count < 0 || static_cast(total_count) < reaction_list->reactions_.size()) { + LOG(ERROR) << "Receive total_count = " << total_count << " and " << reaction_list->reactions_.size() + << " story reactioners"; + total_count = static_cast(reaction_list->reactions_.size()); + } + + StoryViewers story_viewers(td_, total_count, std::move(reaction_list->reactions_), + std::move(reaction_list->next_offset_)); + on_view_dialog_active_stories(story_viewers.get_actor_dialog_ids()); + promise.set_value(story_viewers.get_story_interactions_object(td_)); +} + +void StoryManager::report_story(StoryFullId story_full_id, ReportReason &&reason, Promise &&promise) { + if (!have_story_force(story_full_id)) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!story_full_id.is_server()) { + return promise.set_error(Status::Error(400, "Story can't be reported")); + } + + td_->create_handler(std::move(promise))->send(story_full_id, std::move(reason)); +} + +void StoryManager::activate_stealth_mode(Promise &&promise) { + td_->create_handler(std::move(promise))->send(); +} + +bool StoryManager::have_story(StoryFullId story_full_id) const { + return get_story(story_full_id) != nullptr; +} + +bool StoryManager::have_story_force(StoryFullId story_full_id) { + return get_story_force(story_full_id, "have_story_force") != nullptr; +} + +int32 StoryManager::get_story_date(StoryFullId story_full_id) { + const auto *story = get_story_force(story_full_id, "get_story_date"); + return story != nullptr ? story->date_ : 0; +} + +bool StoryManager::is_inaccessible_story(StoryFullId story_full_id) const { + return inaccessible_story_full_ids_.count(story_full_id) > 0; +} + +int32 StoryManager::get_story_duration(StoryFullId story_full_id) const { + const Story *story = get_story(story_full_id); + if (story == nullptr || story->content_ == nullptr) { + return -1; + } + auto *content = story->content_.get(); + auto it = being_edited_stories_.find(story_full_id); + if (it != being_edited_stories_.end()) { + if (it->second->content_ != nullptr) { + content = it->second->content_.get(); + } + } + return get_story_content_duration(td_, content); +} + +void StoryManager::register_story(StoryFullId story_full_id, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source) { + if (td_->auth_manager_->is_bot()) { + return; + } + CHECK(story_full_id.is_server()); + + LOG(INFO) << "Register " << story_full_id << " from " << message_full_id << '/' << quick_reply_message_full_id + << " from " << source; + if (quick_reply_message_full_id.is_valid()) { + story_quick_reply_messages_[story_full_id].insert(quick_reply_message_full_id); + } else { + CHECK(message_full_id.get_dialog_id().is_valid()); + story_messages_[story_full_id].insert(message_full_id); + } +} + +void StoryManager::unregister_story(StoryFullId story_full_id, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source) { + if (td_->auth_manager_->is_bot()) { + return; + } + CHECK(story_full_id.is_server()); + LOG(INFO) << "Unregister " << story_full_id << " from " << message_full_id << '/' << quick_reply_message_full_id + << " from " << source; + if (quick_reply_message_full_id.is_valid()) { + auto &message_ids = story_quick_reply_messages_[story_full_id]; + auto is_deleted = message_ids.erase(quick_reply_message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << story_full_id << ' ' << quick_reply_message_full_id; + if (message_ids.empty()) { + story_quick_reply_messages_.erase(story_full_id); + } + } else { + auto &message_ids = story_messages_[story_full_id]; + auto is_deleted = message_ids.erase(message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << story_full_id << ' ' << message_full_id; + if (message_ids.empty()) { + story_messages_.erase(story_full_id); + } + } +} + +StoryManager::StoryInfo StoryManager::get_story_info(StoryFullId story_full_id) const { + const auto *story = get_story(story_full_id); + auto story_id = story_full_id.get_story_id(); + if (story == nullptr) { + LOG(INFO) << "Tried to get info about deleted " << story_full_id; + return {}; + } + if (story_id.is_server() && !is_active_story(story)) { + LOG(INFO) << "Tried to get info about expired " << story_full_id; + return {}; + } + StoryInfo story_info; + story_info.story_id_ = story_id; + story_info.date_ = story->date_; + story_info.expire_date_ = story->expire_date_; + story_info.is_for_close_friends_ = story->is_for_close_friends_; + return story_info; +} + +td_api::object_ptr StoryManager::get_story_info_object(StoryFullId story_full_id) const { + auto story_info = get_story_info(story_full_id); + if (!story_info.story_id_.is_valid()) { + return nullptr; + } + return td_api::make_object(story_info.story_id_.get(), story_info.date_, + story_info.is_for_close_friends_); +} + +td_api::object_ptr StoryManager::get_story_object(StoryFullId story_full_id) const { + return get_story_object(story_full_id, get_story(story_full_id)); +} + +td_api::object_ptr StoryManager::get_story_object(StoryFullId story_full_id, const Story *story) const { + if (story == nullptr || story->content_ == nullptr) { + return nullptr; + } + auto owner_dialog_id = story_full_id.get_dialog_id(); + if (!can_access_expired_story(owner_dialog_id, story) && !is_active_story(story)) { + return nullptr; + } + + td_api::object_ptr privacy_settings = + story->privacy_rules_.get_story_privacy_settings_object(td_); + if (privacy_settings == nullptr) { + if (story->is_public_) { + privacy_settings = td_api::make_object(); + } else if (story->is_for_contacts_) { + privacy_settings = td_api::make_object(); + } else if (story->is_for_close_friends_) { + privacy_settings = td_api::make_object(); + } else { + privacy_settings = td_api::make_object(); + } + } + + bool is_being_edited = false; + bool is_edited = story->is_edited_; + + auto story_id = story_full_id.get_story_id(); + CHECK(story_id.is_valid()); + auto *content = story->content_.get(); + auto *areas = &story->areas_; + auto *caption = &story->caption_; + if (story_id.is_server()) { + auto it = being_edited_stories_.find(story_full_id); + if (it != being_edited_stories_.end()) { + if (it->second->content_ != nullptr) { + content = it->second->content_.get(); + } + if (it->second->edit_media_areas_) { + areas = &it->second->areas_; + } + if (it->second->edit_caption_) { + caption = &it->second->caption_; + } + is_being_edited = true; + } + } + + auto is_being_sent = !story_id.is_server(); + auto changelog_dialog_id = get_changelog_story_dialog_id(); + auto is_visible_only_for_self = !story_id.is_server() || owner_dialog_id == changelog_dialog_id || + (!story->is_pinned_ && !is_active_story(story)); + auto can_be_deleted = can_delete_story(story_full_id, story); + auto can_be_edited = can_edit_story(story_full_id, story); + auto can_be_forwarded = !story->noforwards_ && story_id.is_server() && + privacy_settings->get_id() == td_api::storyPrivacySettingsEveryone::ID; + auto can_be_replied = + story_id.is_server() && owner_dialog_id != changelog_dialog_id && owner_dialog_id.get_type() == DialogType::User; + auto can_toggle_is_pinned = can_toggle_story_is_pinned(story_full_id, story); + auto unix_time = G()->unix_time(); + auto can_get_statistics = can_get_story_statistics(story_full_id, story); + auto can_get_interactions = can_get_story_viewers(story_full_id, story, unix_time).is_ok(); + auto repost_info = + story->forward_info_ != nullptr ? story->forward_info_->get_story_repost_info_object(td_) : nullptr; + auto interaction_info = story->interaction_info_.get_story_interaction_info_object(td_); + auto has_expired_viewers = is_my_story(owner_dialog_id) && story_id.is_server() && + unix_time >= get_story_viewers_expire_date(story) && interaction_info != nullptr && + interaction_info->view_count_ > interaction_info->reaction_count_; + const auto &reaction_counts = story->interaction_info_.get_reaction_counts(); + auto story_areas = transform(*areas, [td = td_, &reaction_counts](const MediaArea &media_area) { + return media_area.get_story_area_object(td, reaction_counts); + }); + + story->is_update_sent_ = true; + + return td_api::make_object( + story_id.get(), td_->dialog_manager_->get_chat_id_object(owner_dialog_id, "get_story_object"), + story->sender_dialog_id_ == DialogId() + ? nullptr + : get_message_sender_object(td_, story->sender_dialog_id_, "get_story_object 2"), + story->date_, is_being_sent, is_being_edited, is_edited, story->is_pinned_, is_visible_only_for_self, + can_be_deleted, can_be_edited, can_be_forwarded, can_be_replied, can_toggle_is_pinned, can_get_statistics, + can_get_interactions, has_expired_viewers, std::move(repost_info), std::move(interaction_info), + story->chosen_reaction_type_.get_reaction_type_object(), std::move(privacy_settings), + get_story_content_object(td_, content), std::move(story_areas), + get_formatted_text_object(td_->user_manager_.get(), *caption, true, get_story_content_duration(td_, content))); +} + +td_api::object_ptr StoryManager::get_stories_object(int32 total_count, + const vector &story_full_ids, + const vector &pinned_story_ids) const { + if (total_count == -1) { + total_count = static_cast(story_full_ids.size()); + } + return td_api::make_object( + total_count, + transform(story_full_ids, [this](StoryFullId story_full_id) { return get_story_object(story_full_id); }), + StoryId::get_input_story_ids(pinned_story_ids)); +} + +td_api::object_ptr StoryManager::get_chat_active_stories_object( + DialogId owner_dialog_id, const ActiveStories *active_stories) const { + StoryListId story_list_id; + StoryId max_read_story_id; + vector> stories; + int64 order = 0; + if (active_stories != nullptr) { + story_list_id = active_stories->story_list_id_; + max_read_story_id = active_stories->max_read_story_id_; + for (auto story_id : active_stories->story_ids_) { + auto story_info = get_story_info_object({owner_dialog_id, story_id}); + if (story_info != nullptr) { + stories.push_back(std::move(story_info)); + } + } + if (stories.size() != active_stories->story_ids_.size()) { + send_closure_later(G()->story_manager(), &StoryManager::update_active_stories, owner_dialog_id); + } + if (story_list_id.is_valid()) { + order = active_stories->public_order_; + } + } else { + story_list_id = get_dialog_story_list_id(owner_dialog_id); + } + auto yet_unsent_story_ids_it = yet_unsent_story_ids_.find(owner_dialog_id); + if (yet_unsent_story_ids_it != yet_unsent_story_ids_.end()) { + for (auto story_id : yet_unsent_story_ids_it->second) { + auto story_info = get_story_info_object({owner_dialog_id, story_id}); + if (story_info != nullptr) { + stories.push_back(std::move(story_info)); + } + } + } + return td_api::make_object( + td_->dialog_manager_->get_chat_id_object(owner_dialog_id, "updateChatActiveStories"), + story_list_id.get_story_list_object(), order, max_read_story_id.get(), std::move(stories)); +} + +td_api::object_ptr StoryManager::get_can_send_story_result_object(const Status &error, + bool force) { + CHECK(error.is_error()); + if (error.message() == "PREMIUM_ACCOUNT_REQUIRED") { + return td_api::make_object(); + } + if (error.message() == "BOOSTS_REQUIRED") { + return td_api::make_object(); + } + if (error.message() == "STORIES_TOO_MUCH") { + return td_api::make_object(); + } + if (begins_with(error.message(), "STORY_SEND_FLOOD_WEEKLY_")) { + auto r_next_date = to_integer_safe(error.message().substr(Slice("STORY_SEND_FLOOD_WEEKLY_").size())); + if (r_next_date.is_ok() && r_next_date.ok() > 0) { + auto retry_after = r_next_date.ok() - G()->unix_time(); + if (retry_after > 0 || force) { + return td_api::make_object(max(retry_after, 0)); + } else { + return td_api::make_object(); + } + } + } + if (begins_with(error.message(), "STORY_SEND_FLOOD_MONTHLY_")) { + auto r_next_date = to_integer_safe(error.message().substr(Slice("STORY_SEND_FLOOD_MONTHLY_").size())); + if (r_next_date.is_ok() && r_next_date.ok() > 0) { + auto retry_after = r_next_date.ok() - G()->unix_time(); + if (retry_after > 0 || force) { + return td_api::make_object(max(retry_after, 0)); + } else { + return td_api::make_object(); + } + } + } + return nullptr; +} + +vector StoryManager::get_story_file_ids(const Story *story) const { + if (story == nullptr || story->content_ == nullptr) { + return {}; + } + return get_story_content_file_ids(td_, story->content_.get()); +} + +void StoryManager::delete_story_files(const Story *story) const { + for (auto file_id : get_story_file_ids(story)) { + send_closure(G()->file_manager(), &FileManager::delete_file, file_id, Promise(), "delete_story_files"); + } +} + +void StoryManager::change_story_files(StoryFullId story_full_id, const Story *story, + const vector &old_file_ids) { + auto new_file_ids = get_story_file_ids(story); + if (new_file_ids == old_file_ids) { + return; + } + + for (auto file_id : old_file_ids) { + if (!td::contains(new_file_ids, file_id)) { + send_closure(G()->file_manager(), &FileManager::delete_file, file_id, Promise(), "change_story_files"); + } + } + + auto file_source_id = get_story_file_source_id(story_full_id); + if (file_source_id.is_valid()) { + td_->file_manager_->change_files_source(file_source_id, old_file_ids, new_file_ids); + } +} + +StoryId StoryManager::on_get_story(DialogId owner_dialog_id, + telegram_api::object_ptr &&story_item_ptr) { + if (!owner_dialog_id.is_valid()) { + LOG(ERROR) << "Receive a story in " << owner_dialog_id; + return {}; + } + if (td_->auth_manager_->is_bot()) { + return {}; + } + CHECK(story_item_ptr != nullptr); + switch (story_item_ptr->get_id()) { + case telegram_api::storyItemDeleted::ID: + return on_get_deleted_story(owner_dialog_id, + telegram_api::move_object_as(story_item_ptr)); + case telegram_api::storyItemSkipped::ID: + LOG(ERROR) << "Receive " << to_string(story_item_ptr); + return {}; + case telegram_api::storyItem::ID: { + return on_get_new_story(owner_dialog_id, telegram_api::move_object_as(story_item_ptr)); + } + default: + UNREACHABLE(); + } +} + +StoryId StoryManager::on_get_new_story(DialogId owner_dialog_id, + telegram_api::object_ptr &&story_item) { + CHECK(story_item != nullptr); + StoryId story_id(story_item->id_); + if (!story_id.is_server()) { + LOG(ERROR) << "Receive " << to_string(story_item); + return StoryId(); + } + CHECK(owner_dialog_id.is_valid()); + StoryFullId story_full_id{owner_dialog_id, story_id}; + if (deleted_story_full_ids_.count(story_full_id) > 0) { + return StoryId(); + } + + td_->dialog_manager_->force_create_dialog(owner_dialog_id, "on_get_new_story"); + + StoryId old_story_id; + auto updates_story_ids_it = update_story_ids_.find(story_full_id); + if (updates_story_ids_it != update_story_ids_.end()) { + old_story_id = updates_story_ids_it->second; + update_story_ids_.erase(updates_story_ids_it); + + LOG(INFO) << "Receive sent " << old_story_id << " as " << story_full_id; + + auto old_story_full_id = StoryFullId(owner_dialog_id, old_story_id); + const Story *old_story = get_story_force(old_story_full_id, "on_get_new_story"); + if (old_story != nullptr) { + delete_story_files(old_story); + stories_.erase(old_story_full_id); + } else { + old_story_id = StoryId(); + } + } + + bool is_bot = td_->auth_manager_->is_bot(); + auto caption = + get_message_text(td_->user_manager_.get(), std::move(story_item->caption_), std::move(story_item->entities_), + true, is_bot, story_item->date_, false, "on_get_new_story"); + auto content = get_story_content(td_, std::move(story_item->media_), owner_dialog_id); + if (content == nullptr) { + return StoryId(); + } + + Story *story = get_story_force(story_full_id, "on_get_new_story"); + bool is_changed = false; + bool need_save_to_database = false; + if (story == nullptr) { + auto s = make_unique(); + story = s.get(); + stories_.set(story_full_id, std::move(s)); + is_changed = true; + story_item->min_ = false; + register_story_global_id(story_full_id, story); + + inaccessible_story_full_ids_.erase(story_full_id); + failed_to_load_story_full_ids_.erase(story_full_id); + LOG(INFO) << "Add new " << story_full_id; + } + CHECK(story != nullptr); + + story->receive_date_ = G()->unix_time(); + + const BeingEditedStory *edited_story = nullptr; + auto it = being_edited_stories_.find(story_full_id); + if (it != being_edited_stories_.end()) { + edited_story = it->second.get(); + } + + auto content_type = content->get_type(); + auto old_file_ids = get_story_file_ids(story); + if (edited_story != nullptr && edited_story->content_ != nullptr) { + story->content_ = std::move(content); + need_save_to_database = true; + } else if (story->content_ == nullptr || story->content_->get_type() != content_type) { + story->content_ = std::move(content); + is_changed = true; + } else { + merge_story_contents(td_, story->content_.get(), content.get(), owner_dialog_id, need_save_to_database, is_changed); + story->content_ = std::move(content); + } + + if (is_changed || need_save_to_database) { + change_story_files(story_full_id, story, old_file_ids); + } + + if (story_item->date_ <= 0) { + LOG(ERROR) << "Receive " << story_full_id << " sent at " << story_item->date_; + story_item->date_ = 1; + } + if (story_item->expire_date_ <= story_item->date_) { + LOG(ERROR) << "Receive " << story_full_id << " sent at " << story_item->date_ << ", but expired at " + << story_item->expire_date_; + story_item->expire_date_ = story_item->date_ + 1; + } + + if (story->is_edited_ != story_item->edited_ || story->is_pinned_ != story_item->pinned_ || + story->is_public_ != story_item->public_ || story->is_for_close_friends_ != story_item->close_friends_ || + story->is_for_contacts_ != story_item->contacts_ || + story->is_for_selected_contacts_ != story_item->selected_contacts_ || + story->noforwards_ != story_item->noforwards_ || story->date_ != story_item->date_ || + story->expire_date_ != story_item->expire_date_) { + story->is_edited_ = story_item->edited_; + story->is_pinned_ = story_item->pinned_; + story->is_public_ = story_item->public_; + story->is_for_close_friends_ = story_item->close_friends_; + story->is_for_contacts_ = story_item->contacts_; + story->is_for_selected_contacts_ = story_item->selected_contacts_; + story->noforwards_ = story_item->noforwards_; + story->date_ = story_item->date_; + story->expire_date_ = story_item->expire_date_; + is_changed = true; + } + if (owner_dialog_id.get_type() == DialogType::User && !is_my_story(owner_dialog_id)) { + story_item->min_ = false; + } + unique_ptr forward_info = + story_item->fwd_from_ != nullptr ? make_unique(td_, std::move(story_item->fwd_from_)) : nullptr; + if (story->forward_info_ != forward_info) { + story->forward_info_ = std::move(forward_info); + is_changed = true; + } + auto sender_dialog_id = story_item->from_id_ != nullptr ? DialogId(story_item->from_id_) : DialogId(); + if (sender_dialog_id != story->sender_dialog_id_) { + story->sender_dialog_id_ = sender_dialog_id; + is_changed = true; + } + if (!story_item->min_) { + auto privacy_rules = UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(story_item->privacy_)); + auto interaction_info = StoryInteractionInfo(td_, std::move(story_item->views_)); + auto chosen_reaction_type = ReactionType(std::move(story_item->sent_reaction_)); + + if (story->privacy_rules_ != privacy_rules) { + story->privacy_rules_ = std::move(privacy_rules); + is_changed = true; + } + if (story->interaction_info_ != interaction_info || story->chosen_reaction_type_ != chosen_reaction_type) { + auto pending_reaction_it = being_set_story_reactions_.find(story_full_id); + if (pending_reaction_it != being_set_story_reactions_.end()) { + LOG(INFO) << "Postpone " << story_full_id << " interaction info update, because there is a pending reaction"; + pending_reaction_it->second |= 1; + } else { + story->interaction_info_ = std::move(interaction_info); + story->chosen_reaction_type_ = std::move(chosen_reaction_type); + is_changed = true; + } + } + + if (is_my_story(owner_dialog_id)) { + story_item->out_ = true; + } + if (story->is_outgoing_ != story_item->out_) { + story->is_outgoing_ = story_item->out_; + need_save_to_database = true; + } + } + if (story->caption_ != caption) { + story->caption_ = std::move(caption); + if (edited_story != nullptr && edited_story->edit_caption_) { + need_save_to_database = true; + } else { + is_changed = true; + } + } + vector media_areas; + for (auto &media_area_ptr : story_item->media_areas_) { + MediaArea media_area(td_, std::move(media_area_ptr)); + if (media_area.is_valid()) { + media_areas.push_back(std::move(media_area)); + } + } + if (story->areas_ != media_areas) { + story->areas_ = std::move(media_areas); + if (edited_story != nullptr && edited_story->edit_media_areas_) { + need_save_to_database = true; + } else { + is_changed = true; + } + } + + Dependencies dependencies; + add_story_dependencies(dependencies, story); + for (auto dependent_dialog_id : dependencies.get_dialog_ids()) { + td_->dialog_manager_->force_create_dialog(dependent_dialog_id, "on_get_new_story", true); + } + + on_story_changed(story_full_id, story, is_changed, need_save_to_database); + + LOG(INFO) << "Receive " << story_full_id; + + if (is_active_story(story)) { + auto active_stories = get_active_stories_force(owner_dialog_id, "on_get_new_story"); + if (active_stories == nullptr) { + if (is_subscribed_to_dialog_stories(owner_dialog_id)) { + load_dialog_expiring_stories(owner_dialog_id, 0, "on_get_new_story"); + + if (updated_active_stories_.count(owner_dialog_id)) { + on_update_active_stories(owner_dialog_id, StoryId(), vector{story_id}, Promise(), + "on_get_new_story 1"); + } else if (old_story_id.is_valid()) { + send_update_chat_active_stories(owner_dialog_id, active_stories, "on_get_new_story 2"); + } + } else if (old_story_id.is_valid()) { + send_update_chat_active_stories(owner_dialog_id, active_stories, "on_get_new_story 3"); + } + } else if (!contains(active_stories->story_ids_, story_id)) { + auto story_ids = active_stories->story_ids_; + story_ids.push_back(story_id); + size_t i = story_ids.size() - 1; + while (i > 0 && story_ids[i - 1].get() > story_id.get()) { + story_ids[i] = story_ids[i - 1]; + i--; + } + story_ids[i] = story_id; + on_update_active_stories(owner_dialog_id, active_stories->max_read_story_id_, std::move(story_ids), + Promise(), "on_get_new_story"); + } else if (old_story_id.is_valid()) { + send_update_chat_active_stories(owner_dialog_id, active_stories, "on_get_new_story 4"); + } + } + + if (old_story_id.is_valid()) { + send_closure(G()->td(), &Td::send_update, + td_api::make_object(get_story_object(story_full_id, story), + old_story_id.get())); + } + + return story_id; +} + +StoryId StoryManager::on_get_skipped_story(DialogId owner_dialog_id, + telegram_api::object_ptr &&story_item) { + CHECK(story_item != nullptr); + StoryInfo story_info; + story_info.story_id_ = StoryId(story_item->id_); + story_info.date_ = story_item->date_; + story_info.expire_date_ = story_item->expire_date_; + story_info.is_for_close_friends_ = story_item->close_friends_; + return on_get_story_info(owner_dialog_id, std::move(story_info)); +} + +StoryId StoryManager::on_get_story_info(DialogId owner_dialog_id, StoryInfo &&story_info) { + StoryId story_id = story_info.story_id_; + if (!story_id.is_server()) { + LOG(ERROR) << "Receive " << story_id; + return StoryId(); + } + if (deleted_story_full_ids_.count({owner_dialog_id, story_id}) > 0) { + return StoryId(); + } + + td_->dialog_manager_->force_create_dialog(owner_dialog_id, "on_get_story_info"); + + StoryFullId story_full_id{owner_dialog_id, story_id}; + Story *story = get_story_editable(story_full_id); + if (story == nullptr) { + auto s = make_unique(); + story = s.get(); + stories_.set(story_full_id, std::move(s)); + register_story_global_id(story_full_id, story); + story->is_outgoing_ = is_my_story(owner_dialog_id); + + inaccessible_story_full_ids_.erase(story_full_id); + } + CHECK(story != nullptr); + + if (story_info.date_ <= 0) { + LOG(ERROR) << "Receive " << story_full_id << " sent at " << story_info.date_; + story_info.date_ = 1; + } + if (story_info.expire_date_ <= story_info.date_) { + LOG(ERROR) << "Receive " << story_full_id << " sent at " << story_info.date_ << ", but expired at " + << story_info.expire_date_; + story_info.expire_date_ = story_info.date_ + 1; + } + + if (story->date_ != story_info.date_ || story->expire_date_ != story_info.expire_date_ || + story->is_for_close_friends_ != story_info.is_for_close_friends_) { + story->date_ = story_info.date_; + story->expire_date_ = story_info.expire_date_; + story->is_for_close_friends_ = story_info.is_for_close_friends_; + on_story_changed(story_full_id, story, true, true); + } + return story_id; +} + +StoryId StoryManager::on_get_deleted_story(DialogId owner_dialog_id, + telegram_api::object_ptr &&story_item) { + StoryId story_id(story_item->id_); + on_delete_story({owner_dialog_id, story_id}); + return story_id; +} + +void StoryManager::on_delete_story(StoryFullId story_full_id) { + auto story_id = story_full_id.get_story_id(); + if (!story_id.is_server()) { + LOG(ERROR) << "Receive deleted " << story_full_id; + return; + } + + update_story_ids_.erase(story_full_id); + + inaccessible_story_full_ids_.set(story_full_id, Time::now()); + send_closure_later(G()->messages_manager(), + &MessagesManager::update_story_max_reply_media_timestamp_in_replied_messages, story_full_id); + + const Story *story = get_story_force(story_full_id, "on_delete_story"); + auto owner_dialog_id = story_full_id.get_dialog_id(); + if (story != nullptr) { + LOG(INFO) << "Delete " << story_full_id; + if (story->is_update_sent_) { + send_closure( + G()->td(), &Td::send_update, + td_api::make_object( + td_->dialog_manager_->get_chat_id_object(owner_dialog_id, "updateStoryDeleted"), story_id.get())); + } + delete_story_files(story); + unregister_story_global_id(story); + stories_.erase(story_full_id); + auto edited_stories_it = being_edited_stories_.find(story_full_id); + if (edited_stories_it != being_edited_stories_.end()) { + CHECK(edited_stories_it->second != nullptr); + auto log_event_id = edited_stories_it->second->log_event_id_; + if (log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), log_event_id); + } + being_edited_stories_.erase(edited_stories_it); + } + edit_generations_.erase(story_full_id); + } else { + LOG(INFO) << "Delete not found " << story_full_id; + } + + auto active_stories = get_active_stories_force(owner_dialog_id, "on_get_deleted_story"); + if (active_stories != nullptr && contains(active_stories->story_ids_, story_id)) { + auto story_ids = active_stories->story_ids_; + td::remove(story_ids, story_id); + on_update_active_stories(owner_dialog_id, active_stories->max_read_story_id_, std::move(story_ids), Promise(), + "on_delete_story"); + } + + delete_story_from_database(story_full_id); +} + +void StoryManager::delete_story_from_database(StoryFullId story_full_id) { + if (G()->use_message_database()) { + LOG(INFO) << "Delete " << story_full_id << " from database"; + G()->td_db()->get_story_db_async()->delete_story(story_full_id, Promise()); + } +} + +void StoryManager::set_story_expire_timeout(const Story *story) { + CHECK(story->global_id_ > 0); + story_expire_timeout_.set_timeout_in(story->global_id_, story->expire_date_ - G()->unix_time()); +} + +void StoryManager::set_story_can_get_viewers_timeout(const Story *story) { + CHECK(story->global_id_ > 0); + story_can_get_viewers_timeout_.set_timeout_in(story->global_id_, + get_story_viewers_expire_date(story) - G()->unix_time() + 2); +} + +void StoryManager::on_story_changed(StoryFullId story_full_id, const Story *story, bool is_changed, + bool need_save_to_database, bool from_database) { + if (!story_full_id.get_story_id().is_server()) { + return; + } + if (is_active_story(story)) { + set_story_expire_timeout(story); + } + if (has_unexpired_viewers(story_full_id, story)) { + set_story_can_get_viewers_timeout(story); + } + if (story->content_ == nullptr) { + return; + } + if (is_changed || need_save_to_database) { + if (G()->use_message_database() && !from_database) { + LOG(INFO) << "Add " << story_full_id << " to database"; + + int32 expires_at = 0; + if (is_active_story(story) && !can_access_expired_story(story_full_id.get_dialog_id(), story)) { + expires_at = story->expire_date_; + } + + G()->td_db()->get_story_db_async()->add_story(story_full_id, expires_at, NotificationId(), + log_event_store(*story), Promise()); + } + + if (is_changed && story->is_update_sent_) { + send_update_story(story_full_id, story); + } + + send_closure_later(G()->messages_manager(), + &MessagesManager::update_story_max_reply_media_timestamp_in_replied_messages, story_full_id); + send_closure_later(G()->web_pages_manager(), &WebPagesManager::on_story_changed, story_full_id); + + if (story_messages_.count(story_full_id) != 0) { + vector message_full_ids; + story_messages_[story_full_id].foreach( + [&message_full_ids](const MessageFullId &message_full_id) { message_full_ids.push_back(message_full_id); }); + CHECK(!message_full_ids.empty()); + for (const auto &message_full_id : message_full_ids) { + send_closure_later(G()->messages_manager(), &MessagesManager::on_external_update_message_content, + message_full_id, "on_story_changed", true); + } + } + + if (story_quick_reply_messages_.count(story_full_id) != 0) { + vector message_full_ids; + story_quick_reply_messages_[story_full_id].foreach( + [&message_full_ids](const QuickReplyMessageFullId &message_full_id) { + message_full_ids.push_back(message_full_id); + }); + CHECK(!message_full_ids.empty()); + for (const auto &message_full_id : message_full_ids) { + send_closure_later(G()->quick_reply_manager(), &QuickReplyManager::on_external_update_message_content, + message_full_id, "on_story_changed", true); + } + } + } +} + +void StoryManager::register_story_global_id(StoryFullId story_full_id, Story *story) { + CHECK(story_full_id.is_server()); + CHECK(story->global_id_ == 0); + story->global_id_ = ++max_story_global_id_; + stories_by_global_id_[story->global_id_] = story_full_id; +} + +void StoryManager::unregister_story_global_id(const Story *story) { + CHECK(story->global_id_ > 0); + stories_by_global_id_.erase(story->global_id_); +} + +std::pair> StoryManager::on_get_stories( + DialogId owner_dialog_id, vector &&expected_story_ids, + telegram_api::object_ptr &&stories) { + td_->user_manager_->on_get_users(std::move(stories->users_), "on_get_stories"); + td_->chat_manager_->on_get_chats(std::move(stories->chats_), "on_get_stories"); + + vector story_ids; + for (auto &story : stories->stories_) { + switch (story->get_id()) { + case telegram_api::storyItemDeleted::ID: + on_get_deleted_story(owner_dialog_id, telegram_api::move_object_as(story)); + break; + case telegram_api::storyItemSkipped::ID: + LOG(ERROR) << "Receive " << to_string(story); + break; + case telegram_api::storyItem::ID: { + auto story_id = on_get_new_story(owner_dialog_id, telegram_api::move_object_as(story)); + if (story_id.is_valid()) { + story_ids.push_back(story_id); + } + break; + } + default: + UNREACHABLE(); + } + } + + auto total_count = stories->count_; + if (total_count < static_cast(story_ids.size())) { + LOG(ERROR) << "Expected at most " << total_count << " stories, but receive " << story_ids.size(); + total_count = static_cast(story_ids.size()); + } + if (!expected_story_ids.empty()) { + FlatHashSet all_story_ids; + for (auto expected_story_id : expected_story_ids) { + CHECK(expected_story_id != StoryId()); + all_story_ids.insert(expected_story_id); + } + for (auto story_id : story_ids) { + if (all_story_ids.erase(story_id) == 0) { + LOG(ERROR) << "Receive " << story_id << " in " << owner_dialog_id << ", but didn't request it"; + } + } + for (auto story_id : all_story_ids) { + on_delete_story({owner_dialog_id, story_id}); + } + } + return {total_count, std::move(story_ids)}; +} + +DialogId StoryManager::on_get_dialog_stories(DialogId owner_dialog_id, + telegram_api::object_ptr &&peer_stories, + Promise &&promise) { + if (peer_stories == nullptr) { + if (owner_dialog_id.is_valid()) { + LOG(INFO) << "Receive no stories in " << owner_dialog_id; + on_update_active_stories(owner_dialog_id, StoryId(), {}, std::move(promise), "on_get_dialog_stories"); + } else { + promise.set_value(Unit()); + } + return owner_dialog_id; + } + + DialogId story_dialog_id(peer_stories->peer_); + if (owner_dialog_id.is_valid() && owner_dialog_id != story_dialog_id) { + LOG(ERROR) << "Receive stories from " << story_dialog_id << " instead of " << owner_dialog_id; + on_update_active_stories(owner_dialog_id, StoryId(), {}, std::move(promise), "on_get_dialog_stories 2"); + return owner_dialog_id; + } + if (!story_dialog_id.is_valid()) { + LOG(ERROR) << "Receive stories in " << story_dialog_id; + promise.set_value(Unit()); + return owner_dialog_id; + } + owner_dialog_id = story_dialog_id; + + StoryId max_read_story_id(peer_stories->max_read_id_); + if (!max_read_story_id.is_server() && max_read_story_id != StoryId()) { + LOG(ERROR) << "Receive max read " << max_read_story_id; + max_read_story_id = StoryId(); + } + + vector story_ids; + for (auto &story : peer_stories->stories_) { + switch (story->get_id()) { + case telegram_api::storyItemDeleted::ID: + on_get_deleted_story(owner_dialog_id, telegram_api::move_object_as(story)); + break; + case telegram_api::storyItemSkipped::ID: + story_ids.push_back( + on_get_skipped_story(owner_dialog_id, telegram_api::move_object_as(story))); + break; + case telegram_api::storyItem::ID: + story_ids.push_back( + on_get_new_story(owner_dialog_id, telegram_api::move_object_as(story))); + break; + default: + UNREACHABLE(); + } + } + + on_update_active_stories(story_dialog_id, max_read_story_id, std::move(story_ids), std::move(promise), + "on_get_dialog_stories 3"); + return story_dialog_id; +} + +void StoryManager::on_update_dialog_max_story_ids(DialogId owner_dialog_id, StoryId max_story_id, + StoryId max_read_story_id) { + switch (owner_dialog_id.get_type()) { + case DialogType::User: + // use send_closure_later because story order can be updated from update_user + send_closure_later(td_->user_manager_actor_, &UserManager::on_update_user_story_ids, + owner_dialog_id.get_user_id(), max_story_id, max_read_story_id); + break; + case DialogType::Channel: + // use send_closure_later because story order can be updated from update_channel + send_closure_later(td_->chat_manager_actor_, &ChatManager::on_update_channel_story_ids, + owner_dialog_id.get_channel_id(), max_story_id, max_read_story_id); + break; + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + break; + } +} + +void StoryManager::on_update_dialog_max_read_story_id(DialogId owner_dialog_id, StoryId max_read_story_id) { + switch (owner_dialog_id.get_type()) { + case DialogType::User: + td_->user_manager_->on_update_user_max_read_story_id(owner_dialog_id.get_user_id(), max_read_story_id); + break; + case DialogType::Channel: + td_->chat_manager_->on_update_channel_max_read_story_id(owner_dialog_id.get_channel_id(), max_read_story_id); + break; + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + break; + } +} + +void StoryManager::on_update_dialog_has_pinned_stories(DialogId owner_dialog_id, bool has_pinned_stories) { + switch (owner_dialog_id.get_type()) { + case DialogType::User: + td_->user_manager_->on_update_user_has_pinned_stories(owner_dialog_id.get_user_id(), has_pinned_stories); + break; + case DialogType::Channel: + td_->chat_manager_->on_update_channel_has_pinned_stories(owner_dialog_id.get_channel_id(), has_pinned_stories); + break; + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + break; + } +} + +void StoryManager::on_update_dialog_stories_hidden(DialogId owner_dialog_id, bool stories_hidden) { + switch (owner_dialog_id.get_type()) { + case DialogType::User: + td_->user_manager_->on_update_user_stories_hidden(owner_dialog_id.get_user_id(), stories_hidden); + break; + case DialogType::Channel: + td_->chat_manager_->on_update_channel_stories_hidden(owner_dialog_id.get_channel_id(), stories_hidden); + break; + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + break; + } +} + +void StoryManager::update_active_stories(DialogId owner_dialog_id) { + auto active_stories = get_active_stories(owner_dialog_id); + if (active_stories != nullptr) { + auto story_ids = active_stories->story_ids_; + on_update_active_stories(owner_dialog_id, active_stories->max_read_story_id_, std::move(story_ids), Promise(), + "update_active_stories"); + } +} + +void StoryManager::on_update_active_stories(DialogId owner_dialog_id, StoryId max_read_story_id, + vector &&story_ids, Promise &&promise, const char *source, + bool from_database) { + CHECK(owner_dialog_id.is_valid()); + if (td::remove_if(story_ids, [&](StoryId story_id) { + if (!story_id.is_server()) { + CHECK(!from_database); + return true; + } + if (!is_active_story(get_story({owner_dialog_id, story_id}))) { + LOG(INFO) << "Receive expired " << story_id << " in " << owner_dialog_id << " from " << source; + return true; + } + return false; + })) { + from_database = false; + } + if (story_ids.empty() || max_read_story_id.get() < story_ids[0].get()) { + max_read_story_id = StoryId(); + } else if (max_read_story_id != StoryId()) { + CHECK(max_read_story_id.is_server()); + } + + LOG(INFO) << "Update active stories in " << owner_dialog_id << " to " << story_ids << " with max read " + << max_read_story_id << " from " << source; + + if (story_ids.empty()) { + on_update_dialog_max_story_ids(owner_dialog_id, StoryId(), StoryId()); + auto *active_stories = get_active_stories(owner_dialog_id); + if (active_stories != nullptr) { + LOG(INFO) << "Delete active stories for " << owner_dialog_id; + if (active_stories->story_list_id_.is_valid()) { + delete_active_stories_from_story_list(owner_dialog_id, active_stories); + auto &story_list = get_story_list(active_stories->story_list_id_); + if (!from_database && story_list.is_reloaded_server_total_count_ && + story_list.server_total_count_ > static_cast(story_list.ordered_stories_.size())) { + story_list.server_total_count_--; + save_story_list(active_stories->story_list_id_, story_list.state_, story_list.server_total_count_, + story_list.server_has_more_); + } + update_story_list_sent_total_count(active_stories->story_list_id_, story_list, "on_update_active_stories"); + } + active_stories_.erase(owner_dialog_id); + send_update_chat_active_stories(owner_dialog_id, nullptr, "on_update_active_stories 1"); + } else { + max_read_story_ids_.erase(owner_dialog_id); + } + if (!from_database) { + save_active_stories(owner_dialog_id, nullptr, std::move(promise), source); + } + failed_to_load_active_stories_.insert(owner_dialog_id); + return; + } + failed_to_load_active_stories_.erase(owner_dialog_id); + + auto &active_stories = active_stories_[owner_dialog_id]; + if (active_stories == nullptr) { + LOG(INFO) << "Create active stories for " << owner_dialog_id << " from " << source; + active_stories = make_unique(); + auto old_max_read_story_id = max_read_story_ids_.get(owner_dialog_id); + if (old_max_read_story_id != StoryId()) { + max_read_story_ids_.erase(owner_dialog_id); + if (old_max_read_story_id.get() > max_read_story_id.get() && old_max_read_story_id.get() >= story_ids[0].get()) { + max_read_story_id = old_max_read_story_id; + } + } + } + on_update_dialog_max_story_ids(owner_dialog_id, story_ids.back(), max_read_story_id); + bool need_save_to_database = false; + if (active_stories->max_read_story_id_ != max_read_story_id || active_stories->story_ids_ != story_ids) { + need_save_to_database = true; + active_stories->max_read_story_id_ = max_read_story_id; + active_stories->story_ids_ = std::move(story_ids); + update_active_stories_order(owner_dialog_id, active_stories.get(), &need_save_to_database); + send_update_chat_active_stories(owner_dialog_id, active_stories.get(), "on_update_active_stories 2"); + } else if (update_active_stories_order(owner_dialog_id, active_stories.get(), &need_save_to_database)) { + send_update_chat_active_stories(owner_dialog_id, active_stories.get(), "on_update_active_stories 3"); + } + if (need_save_to_database && !from_database) { + save_active_stories(owner_dialog_id, active_stories.get(), std::move(promise), source); + } else { + promise.set_value(Unit()); + } +} + +bool StoryManager::update_active_stories_order(DialogId owner_dialog_id, ActiveStories *active_stories, + bool *need_save_to_database) { + if (td_->auth_manager_->is_bot()) { + return false; + } + + CHECK(active_stories != nullptr); + CHECK(!active_stories->story_ids_.empty()); + CHECK(owner_dialog_id.is_valid()); + + auto last_story_id = active_stories->story_ids_.back(); + const Story *last_story = get_story({owner_dialog_id, last_story_id}); + CHECK(last_story != nullptr); + + int64 new_private_order = 0; + new_private_order += last_story->date_; + if (owner_dialog_id.get_type() == DialogType::User && + td_->user_manager_->is_user_premium(owner_dialog_id.get_user_id())) { + new_private_order += static_cast(1) << 33; + } + if (owner_dialog_id == get_changelog_story_dialog_id()) { + new_private_order += static_cast(1) << 34; + } + if (active_stories->max_read_story_id_.get() < last_story_id.get()) { + new_private_order += static_cast(1) << 35; + } + if (owner_dialog_id == td_->dialog_manager_->get_my_dialog_id()) { + new_private_order += static_cast(1) << 36; + } + CHECK(new_private_order != 0); + + StoryListId story_list_id = get_dialog_story_list_id(owner_dialog_id); + LOG(INFO) << "Update order of active stories of " << owner_dialog_id << " in " << story_list_id << " from " + << active_stories->private_order_ << '/' << active_stories->public_order_ << " to " << new_private_order; + + int64 new_public_order = 0; + if (story_list_id.is_valid()) { + auto &story_list = get_story_list(story_list_id); + if (DialogDate(new_private_order, owner_dialog_id) <= story_list.list_last_story_date_) { + new_public_order = new_private_order; + } + + if (active_stories->private_order_ != new_private_order || active_stories->story_list_id_ != story_list_id) { + delete_active_stories_from_story_list(owner_dialog_id, active_stories); + bool is_inserted = story_list.ordered_stories_.insert({new_private_order, owner_dialog_id}).second; + CHECK(is_inserted); + + if (active_stories->story_list_id_ != story_list_id && active_stories->story_list_id_.is_valid()) { + update_story_list_sent_total_count(active_stories->story_list_id_, "update_active_stories_order 1"); + } + update_story_list_sent_total_count(story_list_id, story_list, "update_active_stories_order 2"); + } + } else if (active_stories->story_list_id_.is_valid()) { + delete_active_stories_from_story_list(owner_dialog_id, active_stories); + update_story_list_sent_total_count(active_stories->story_list_id_, "update_active_stories_order 3"); + } + + if (active_stories->private_order_ != new_private_order || active_stories->public_order_ != new_public_order || + active_stories->story_list_id_ != story_list_id) { + LOG(INFO) << "Update order of active stories of " << owner_dialog_id << " to " << new_private_order << '/' + << new_public_order << " in list " << story_list_id; + if (active_stories->private_order_ != new_private_order || active_stories->story_list_id_ != story_list_id) { + *need_save_to_database = true; + } + active_stories->private_order_ = new_private_order; + if (active_stories->public_order_ != new_public_order || active_stories->story_list_id_ != story_list_id) { + if (active_stories->story_list_id_ != story_list_id) { + if (active_stories->story_list_id_.is_valid() && active_stories->public_order_ != 0) { + active_stories->public_order_ = 0; + send_update_chat_active_stories(owner_dialog_id, active_stories, "update_active_stories_order"); + } + active_stories->story_list_id_ = story_list_id; + } + active_stories->public_order_ = new_public_order; + return true; + } + } + + return false; +} + +void StoryManager::delete_active_stories_from_story_list(DialogId owner_dialog_id, + const ActiveStories *active_stories) { + if (!active_stories->story_list_id_.is_valid()) { + return; + } + auto &story_list = get_story_list(active_stories->story_list_id_); + bool is_deleted = story_list.ordered_stories_.erase({active_stories->private_order_, owner_dialog_id}) > 0; + CHECK(is_deleted); +} + +void StoryManager::send_update_story(StoryFullId story_full_id, const Story *story) { + auto story_object = get_story_object(story_full_id, story); + if (story_object == nullptr) { + CHECK(story != nullptr); + CHECK(story->content_ != nullptr); + // the story can be just expired + return; + } + send_closure(G()->td(), &Td::send_update, td_api::make_object(std::move(story_object))); +} + +td_api::object_ptr StoryManager::get_update_chat_active_stories_object( + DialogId owner_dialog_id, const ActiveStories *active_stories) const { + return td_api::make_object( + get_chat_active_stories_object(owner_dialog_id, active_stories)); +} + +void StoryManager::send_update_chat_active_stories(DialogId owner_dialog_id, const ActiveStories *active_stories, + const char *source) { + if (updated_active_stories_.count(owner_dialog_id) == 0) { + if (active_stories == nullptr || active_stories->public_order_ == 0) { + LOG(INFO) << "Skip update about active stories in " << owner_dialog_id << " from " << source; + return; + } + CHECK(owner_dialog_id.is_valid()); + updated_active_stories_.insert(owner_dialog_id); + } + LOG(INFO) << "Send update about active stories in " << owner_dialog_id << " from " << source; + send_closure(G()->td(), &Td::send_update, get_update_chat_active_stories_object(owner_dialog_id, active_stories)); +} + +void StoryManager::save_active_stories(DialogId owner_dialog_id, const ActiveStories *active_stories, + Promise &&promise, const char *source) const { + if (!G()->use_message_database()) { + return promise.set_value(Unit()); + } + if (active_stories == nullptr) { + LOG(INFO) << "Delete active stories of " << owner_dialog_id << " from database from " << source; + G()->td_db()->get_story_db_async()->delete_active_stories(owner_dialog_id, std::move(promise)); + } else { + LOG(INFO) << "Add " << active_stories->story_ids_.size() << " active stories of " << owner_dialog_id + << " to database from " << source; + auto order = active_stories->story_list_id_.is_valid() ? active_stories->private_order_ : 0; + SavedActiveStories saved_active_stories; + saved_active_stories.max_read_story_id_ = active_stories->max_read_story_id_; + for (auto story_id : active_stories->story_ids_) { + auto story_info = get_story_info({owner_dialog_id, story_id}); + if (story_info.story_id_.is_valid()) { + saved_active_stories.story_infos_.push_back(std::move(story_info)); + } + } + if (saved_active_stories.story_infos_.size() != active_stories->story_ids_.size()) { + send_closure_later(G()->story_manager(), &StoryManager::update_active_stories, owner_dialog_id); + } + if (saved_active_stories.story_infos_.empty()) { + LOG(INFO) << "Have no active stories to save"; + G()->td_db()->get_story_db_async()->delete_active_stories(owner_dialog_id, std::move(promise)); + } else { + G()->td_db()->get_story_db_async()->add_active_stories(owner_dialog_id, active_stories->story_list_id_, order, + log_event_store(saved_active_stories), std::move(promise)); + } + } +} + +void StoryManager::on_update_story_id(int64 random_id, StoryId new_story_id, const char *source) { + if (!new_story_id.is_server()) { + LOG(ERROR) << "Receive " << new_story_id << " with random_id " << random_id << " from " << source; + return; + } + + auto it = being_sent_stories_.find(random_id); + if (it == being_sent_stories_.end()) { + // update about a new story sent from another device + LOG(INFO) << "Receive not sent outgoing " << new_story_id << " with random_id = " << random_id; + return; + } + auto old_story_full_id = it->second; + being_sent_stories_.erase(it); + auto is_deleted = being_sent_story_random_ids_.erase(old_story_full_id) > 0; + CHECK(is_deleted); + + if (!have_story_force(old_story_full_id)) { + LOG(INFO) << "Can't find sent story " << old_story_full_id; + // delete_sent_story_on_server(old_story_full_id, new_story_id); + return; + } + + auto old_story_id = old_story_full_id.get_story_id(); + auto new_story_full_id = StoryFullId(old_story_full_id.get_dialog_id(), new_story_id); + + LOG(INFO) << "Save correspondence from " << new_story_full_id << " to " << old_story_id; + CHECK(!old_story_id.is_server()); + update_story_ids_[new_story_full_id] = old_story_id; +} + +bool StoryManager::on_update_read_stories(DialogId owner_dialog_id, StoryId max_read_story_id) { + if (!td_->dialog_manager_->have_dialog_info_force(owner_dialog_id, "on_update_read_stories")) { + LOG(INFO) << "Can't read stories in unknown " << owner_dialog_id; + return false; + } + if (max_read_story_id != StoryId() && !max_read_story_id.is_server()) { + LOG(ERROR) << "Receive max read " << max_read_story_id; + return false; + } + auto active_stories = get_active_stories_force(owner_dialog_id, "on_update_read_stories"); + if (active_stories == nullptr) { + LOG(INFO) << "Can't find active stories in " << owner_dialog_id; + auto old_max_read_story_id = max_read_story_ids_.get(owner_dialog_id); + if (max_read_story_id.get() > old_max_read_story_id.get()) { + LOG(INFO) << "Set max read story identifier in " << owner_dialog_id << " to " << max_read_story_id; + max_read_story_ids_.set(owner_dialog_id, max_read_story_id); + on_update_dialog_max_read_story_id(owner_dialog_id, max_read_story_id); + return true; + } + } else if (max_read_story_id.get() > active_stories->max_read_story_id_.get()) { + LOG(INFO) << "Update max read story identifier in " << owner_dialog_id << " with stories " + << active_stories->story_ids_ << " from " << active_stories->max_read_story_id_ << " to " + << max_read_story_id; + auto story_ids = active_stories->story_ids_; + on_update_active_stories(owner_dialog_id, max_read_story_id, std::move(story_ids), Promise(), + "on_update_read_stories"); + return true; + } else { + LOG(DEBUG) << "Don't need update max read story from " << active_stories->max_read_story_id_ << " to " + << max_read_story_id; + } + return false; +} + +td_api::object_ptr StoryManager::get_update_story_stealth_mode() const { + return stealth_mode_.get_update_story_stealth_mode_object(); +} + +void StoryManager::send_update_story_stealth_mode() const { + send_closure(G()->td(), &Td::send_update, get_update_story_stealth_mode()); +} + +void StoryManager::on_update_story_stealth_mode( + telegram_api::object_ptr &&stealth_mode) { + set_story_stealth_mode(StoryStealthMode(std::move(stealth_mode))); +} + +void StoryManager::on_update_story_chosen_reaction_type(DialogId owner_dialog_id, StoryId story_id, + ReactionType chosen_reaction_type) { + if (!owner_dialog_id.is_valid() || !story_id.is_server()) { + LOG(ERROR) << "Receive chosen reaction in " << story_id << " in " << owner_dialog_id; + return; + } + if (!td_->dialog_manager_->have_dialog_info_force(owner_dialog_id, "on_update_story_chosen_reaction_type")) { + return; + } + if (chosen_reaction_type.is_paid_reaction()) { + LOG(ERROR) << "Receive paid reaction for " << story_id << " in " << owner_dialog_id; + return; + } + StoryFullId story_full_id{owner_dialog_id, story_id}; + auto pending_reaction_it = being_set_story_reactions_.find(story_full_id); + if (pending_reaction_it != being_set_story_reactions_.end()) { + LOG(INFO) << "Postpone " << story_full_id << " chosen reaction update, because there is a pending reaction"; + pending_reaction_it->second |= 1; + return; + } + Story *story = get_story_force(story_full_id, "on_update_story_chosen_reaction_type"); + on_story_chosen_reaction_changed(story_full_id, story, chosen_reaction_type); +} + +string StoryManager::get_story_stealth_mode_key() { + return "stealth_mode"; +} + +void StoryManager::schedule_stealth_mode_update() { + if (stealth_mode_.is_empty()) { + stealth_mode_update_timeout_.cancel_timeout(); + return; + } + + auto timeout = max(static_cast(stealth_mode_.get_update_date() - G()->unix_time()), 0.1); + LOG(INFO) << "Schedule stealth mode update in " << timeout; + stealth_mode_update_timeout_.set_callback(std::move(update_stealth_mode_static)); + stealth_mode_update_timeout_.set_callback_data(static_cast(this)); + stealth_mode_update_timeout_.set_timeout_in(timeout); +} + +void StoryManager::set_story_stealth_mode(StoryStealthMode stealth_mode) { + stealth_mode.update(); + if (stealth_mode == stealth_mode_) { + return; + } + + stealth_mode_ = stealth_mode; + LOG(INFO) << stealth_mode_; + schedule_stealth_mode_update(); + send_update_story_stealth_mode(); + + if (stealth_mode_.is_empty()) { + G()->td_db()->get_binlog_pmc()->erase(get_story_stealth_mode_key()); + } else { + G()->td_db()->get_binlog_pmc()->set(get_story_stealth_mode_key(), log_event_store(stealth_mode_).as_slice().str()); + } +} + +void StoryManager::update_stealth_mode_static(void *story_manager) { + if (G()->close_flag()) { + return; + } + + CHECK(story_manager != nullptr); + static_cast(story_manager)->update_stealth_mode(); +} + +void StoryManager::update_stealth_mode() { + if (stealth_mode_.update()) { + LOG(INFO) << stealth_mode_; + send_update_story_stealth_mode(); + } + schedule_stealth_mode_update(); +} + +DialogId StoryManager::get_changelog_story_dialog_id() const { + return DialogId(UserId(td_->option_manager_->get_option_integer( + "stories_changelog_user_id", UserManager::get_service_notifications_user_id().get()))); +} + +bool StoryManager::is_subscribed_to_dialog_stories(DialogId owner_dialog_id) const { + if (owner_dialog_id == get_changelog_story_dialog_id()) { + return true; + } + switch (owner_dialog_id.get_type()) { + case DialogType::User: + if (is_my_story(owner_dialog_id)) { + return true; + } + return td_->user_manager_->is_user_contact(owner_dialog_id.get_user_id()); + case DialogType::Channel: + return td_->chat_manager_->get_channel_status(owner_dialog_id.get_channel_id()).is_member(); + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + return false; + } +} + +StoryListId StoryManager::get_dialog_story_list_id(DialogId owner_dialog_id) const { + if (!is_subscribed_to_dialog_stories(owner_dialog_id)) { + return StoryListId(); + } + switch (owner_dialog_id.get_type()) { + case DialogType::User: + if (!is_my_story(owner_dialog_id) && td_->user_manager_->get_user_stories_hidden(owner_dialog_id.get_user_id())) { + return StoryListId::archive(); + } + return StoryListId::main(); + case DialogType::Channel: + if (td_->chat_manager_->get_channel_stories_hidden(owner_dialog_id.get_channel_id())) { + return StoryListId::archive(); + } + return StoryListId::main(); + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + return StoryListId::archive(); + } +} + +void StoryManager::on_dialog_active_stories_order_updated(DialogId owner_dialog_id, const char *source) { + // called from update_user/on_channel_status_changed, must not create the dialog and hence must not load active stories + auto active_stories = get_active_stories_editable(owner_dialog_id); + bool need_save_to_database = false; + if (active_stories != nullptr && + update_active_stories_order(owner_dialog_id, active_stories, &need_save_to_database)) { + send_update_chat_active_stories(owner_dialog_id, active_stories, source); + } + if (need_save_to_database) { + save_active_stories(owner_dialog_id, active_stories, Promise(), source); + } +} + +void StoryManager::on_get_story_views(DialogId owner_dialog_id, const vector &story_ids, + telegram_api::object_ptr &&story_views) { + schedule_interaction_info_update(); + td_->user_manager_->on_get_users(std::move(story_views->users_), "on_get_story_views"); + if (story_ids.size() != story_views->views_.size()) { + LOG(ERROR) << "Receive invalid views for " << story_ids << ": " << to_string(story_views); + return; + } + for (size_t i = 0; i < story_ids.size(); i++) { + auto story_id = story_ids[i]; + CHECK(story_id.is_server()); + + StoryFullId story_full_id{owner_dialog_id, story_id}; + Story *story = get_story_editable(story_full_id); + if (story == nullptr || story->content_ == nullptr) { + continue; + } + + StoryInteractionInfo interaction_info(td_, std::move(story_views->views_[i])); + CHECK(!interaction_info.is_empty()); + if (story->interaction_info_ != interaction_info) { + auto pending_reaction_it = being_set_story_reactions_.find(story_full_id); + if (pending_reaction_it != being_set_story_reactions_.end()) { + LOG(INFO) << "Postpone " << story_full_id << " interaction info update, because there is a pending reaction"; + pending_reaction_it->second |= 1; + } else { + story->interaction_info_ = std::move(interaction_info); + on_story_changed(story_full_id, story, true, true); + } + } + } +} + +void StoryManager::on_view_dialog_active_stories(vector dialog_ids) { + if (dialog_ids.empty() || td_->auth_manager_->is_bot()) { + return; + } + LOG(DEBUG) << "View active stories of " << dialog_ids; + + const size_t MAX_SLICE_SIZE = 100; // server side limit + vector input_dialog_ids; + vector> input_peers; + for (auto &dialog_id : dialog_ids) { + if (td::contains(input_dialog_ids, dialog_id)) { + continue; + } + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + continue; + } + + bool need_poll = [&] { + switch (dialog_id.get_type()) { + case DialogType::User: + return td_->user_manager_->can_poll_user_active_stories(dialog_id.get_user_id()); + case DialogType::Channel: + return td_->chat_manager_->can_poll_channel_active_stories(dialog_id.get_channel_id()); + case DialogType::Chat: + case DialogType::SecretChat: + case DialogType::None: + default: + return false; + } + }(); + if (!need_poll) { + continue; + } + if (!being_reloaded_active_stories_dialog_ids_.insert(dialog_id).second) { + continue; + } + + input_dialog_ids.push_back(dialog_id); + input_peers.push_back(std::move(input_peer)); + if (input_peers.size() == MAX_SLICE_SIZE) { + td_->create_handler()->send(std::move(input_dialog_ids), std::move(input_peers)); + input_dialog_ids.clear(); + input_peers.clear(); + } + } + if (!input_peers.empty()) { + td_->create_handler()->send(std::move(input_dialog_ids), std::move(input_peers)); + } +} + +void StoryManager::on_get_dialog_max_active_story_ids(const vector &dialog_ids, + const vector &max_story_ids) { + for (auto &dialog_id : dialog_ids) { + auto is_deleted = being_reloaded_active_stories_dialog_ids_.erase(dialog_id) > 0; + CHECK(is_deleted); + } + if (dialog_ids.size() != max_story_ids.size()) { + if (!max_story_ids.empty()) { + LOG(ERROR) << "Receive " << max_story_ids.size() << " max active story identifiers for " << dialog_ids; + } + return; + } + for (size_t i = 0; i < dialog_ids.size(); i++) { + auto max_story_id = StoryId(max_story_ids[i]); + auto dialog_id = dialog_ids[i]; + if (max_story_id == StoryId() || max_story_id.is_server()) { + if (dialog_id.get_type() == DialogType::User) { + td_->user_manager_->on_update_user_story_ids(dialog_id.get_user_id(), max_story_id, StoryId()); + } else { + td_->chat_manager_->on_update_channel_story_ids(dialog_id.get_channel_id(), max_story_id, StoryId()); + } + } else { + LOG(ERROR) << "Receive " << max_story_id << " as maximum active story for " << dialog_id; + } + } +} + +FileSourceId StoryManager::get_story_file_source_id(StoryFullId story_full_id) { + if (td_->auth_manager_->is_bot()) { + return FileSourceId(); + } + + if (!story_full_id.is_server()) { + return FileSourceId(); + } + + auto &file_source_id = story_full_id_to_file_source_id_[story_full_id]; + if (!file_source_id.is_valid()) { + file_source_id = td_->file_reference_manager_->create_story_file_source(story_full_id); + } + return file_source_id; +} + +void StoryManager::reload_story(StoryFullId story_full_id, Promise &&promise, const char *source) { + if (deleted_story_full_ids_.count(story_full_id) > 0) { + return promise.set_value(Unit()); + } + double last_reloaded_at = inaccessible_story_full_ids_.get(story_full_id); + if (last_reloaded_at >= Time::now() - OPENED_STORY_POLL_PERIOD / 2 && last_reloaded_at > 0.0) { + return promise.set_value(Unit()); + } + + LOG(INFO) << "Reload " << story_full_id << " from " << source; + auto dialog_id = story_full_id.get_dialog_id(); + auto story_id = story_full_id.get_story_id(); + if (!story_id.is_server()) { + return promise.set_error(Status::Error(400, "Invalid story identifier")); + } + + auto &queries = reload_story_queries_[story_full_id]; + if (!queries.empty() && !promise) { + return; + } + queries.push_back(std::move(promise)); + if (queries.size() != 1) { + return; + } + + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), story_full_id](Result &&result) mutable { + send_closure(actor_id, &StoryManager::on_reload_story, story_full_id, std::move(result)); + }); + td_->create_handler(std::move(query_promise))->send(dialog_id, {story_id}); +} + +void StoryManager::on_reload_story(StoryFullId story_full_id, Result &&result) { + if (G()->close_flag()) { + return; + } + auto it = reload_story_queries_.find(story_full_id); + CHECK(it != reload_story_queries_.end()); + CHECK(!it->second.empty()); + auto promises = std::move(it->second); + reload_story_queries_.erase(it); + + if (result.is_ok()) { + set_promises(promises); + } else { + fail_promises(promises, result.move_as_error()); + } +} + +void StoryManager::get_story(DialogId owner_dialog_id, StoryId story_id, bool only_local, + Promise> &&promise) { + TRY_STATUS_PROMISE( + promise, td_->dialog_manager_->check_dialog_access(owner_dialog_id, false, AccessRights::Read, "get_story")); + if (!story_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid story identifier specified")); + } + + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story_force(story_full_id, "get_story"); + if (story != nullptr && story->content_ != nullptr) { + if (!story->is_update_sent_) { + send_update_story(story_full_id, story); + } + return promise.set_value(get_story_object(story_full_id, story)); + } + if (only_local || !story_id.is_server()) { + return promise.set_value(nullptr); + } + + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), story_full_id, promise = std::move(promise)](Result &&result) mutable { + send_closure(actor_id, &StoryManager::do_get_story, story_full_id, std::move(result), std::move(promise)); + }); + reload_story(story_full_id, std::move(query_promise), "get_story"); +} + +void StoryManager::do_get_story(StoryFullId story_full_id, Result &&result, + Promise> &&promise) { + G()->ignore_result_if_closing(result); + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + const Story *story = get_story(story_full_id); + if (story != nullptr && story->content_ != nullptr && !story->is_update_sent_) { + send_update_story(story_full_id, story); + } + promise.set_value(get_story_object(story_full_id, story)); +} + +Result StoryManager::get_next_yet_unsent_story_id(DialogId dialog_id) { + auto &story_id = current_yet_unsent_story_ids_[dialog_id]; + if (story_id == 0) { + story_id = StoryId::MAX_SERVER_STORY_ID; + } else if (story_id == std::numeric_limits::max()) { + return Status::Error(400, "Tried to send too many stories above daily limit"); + } + return StoryId(++story_id); +} + +void StoryManager::return_dialogs_to_send_stories(Promise> &&promise, + const vector &channel_ids) { + if (!promise) { + return; + } + + auto total_count = narrow_cast(channel_ids.size()); + promise.set_value(td_api::make_object( + total_count, transform(channel_ids, [](ChannelId channel_id) { return DialogId(channel_id).get(); }))); +} + +void StoryManager::get_dialogs_to_send_stories(Promise> &&promise) { + if (channels_to_send_stories_inited_) { + return return_dialogs_to_send_stories(std::move(promise), channels_to_send_stories_); + } + + if (get_dialogs_to_send_stories_queries_.empty() && G()->use_message_database()) { + auto pmc_key = "channels_to_send_stories"; + auto str = G()->td_db()->get_binlog_pmc()->get(pmc_key); + if (!str.empty()) { + auto r_channel_ids = transform(full_split(Slice(str), ','), [](Slice str) -> Result { + TRY_RESULT(channel_id_int, to_integer_safe(str)); + ChannelId channel_id(channel_id_int); + if (!channel_id.is_valid()) { + return Status::Error("Have invalid channel ID"); + } + return channel_id; + }); + if (any_of(r_channel_ids, [](const auto &r_channel_id) { return r_channel_id.is_error(); })) { + LOG(ERROR) << "Can't parse " << str; + G()->td_db()->get_binlog_pmc()->erase(pmc_key); + } else { + Dependencies dependencies; + vector channel_ids; + for (auto &r_channel_id : r_channel_ids) { + auto channel_id = r_channel_id.move_as_ok(); + dependencies.add_dialog_and_dependencies(DialogId(channel_id)); + channel_ids.push_back(channel_id); + } + if (!dependencies.resolve_force(td_, "get_dialogs_to_send_stories")) { + G()->td_db()->get_binlog_pmc()->erase(pmc_key); + } else { + for (auto channel_id : channel_ids) { + if (td_->chat_manager_->get_channel_status(channel_id).can_post_stories()) { + channels_to_send_stories_.push_back(channel_id); + } + } + channels_to_send_stories_inited_ = true; + + return_dialogs_to_send_stories(std::move(promise), channels_to_send_stories_); + promise = {}; + } + } + } + } + + reload_dialogs_to_send_stories(std::move(promise)); +} + +void StoryManager::reload_dialogs_to_send_stories(Promise> &&promise) { + get_dialogs_to_send_stories_queries_.push_back(std::move(promise)); + if (get_dialogs_to_send_stories_queries_.size() == 1) { + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this)](Result &&result) { + send_closure(actor_id, &StoryManager::finish_get_dialogs_to_send_stories, std::move(result)); + }); + td_->create_handler(std::move(query_promise))->send(); + } +} + +void StoryManager::finish_get_dialogs_to_send_stories(Result &&result) { + G()->ignore_result_if_closing(result); + + auto promises = std::move(get_dialogs_to_send_stories_queries_); + reset_to_empty(get_dialogs_to_send_stories_queries_); + if (result.is_error()) { + return fail_promises(promises, result.move_as_error()); + } + + next_reload_channels_to_send_stories_time_ = Time::now() + 86400; + + CHECK(channels_to_send_stories_inited_); + for (auto &promise : promises) { + return_dialogs_to_send_stories(std::move(promise), channels_to_send_stories_); + } +} + +void StoryManager::update_dialogs_to_send_stories(ChannelId channel_id, bool can_send_stories) { + if (channels_to_send_stories_inited_) { + CHECK(!td_->auth_manager_->is_bot()); + bool was_changed = false; + if (!can_send_stories) { + was_changed = td::remove(channels_to_send_stories_, channel_id); + } else { + if (!td::contains(channels_to_send_stories_, channel_id)) { + channels_to_send_stories_.push_back(channel_id); + was_changed = true; + + next_reload_channels_to_send_stories_time_ = Time::now(); + set_timeout_in(1.0); + } + } + if (was_changed) { + save_channels_to_send_stories(); + } + } +} + +void StoryManager::on_get_dialogs_to_send_stories(vector> &&chats) { + auto channel_ids = td_->chat_manager_->get_channel_ids(std::move(chats), "on_get_dialogs_to_send_stories"); + if (channels_to_send_stories_inited_ && channels_to_send_stories_ == channel_ids) { + return; + } + channels_to_send_stories_.clear(); + for (auto channel_id : channel_ids) { + td_->dialog_manager_->force_create_dialog(DialogId(channel_id), "on_get_dialogs_to_send_stories"); + if (td_->chat_manager_->get_channel_status(channel_id).can_post_stories()) { + channels_to_send_stories_.push_back(channel_id); + } + } + channels_to_send_stories_inited_ = true; + + save_channels_to_send_stories(); +} + +void StoryManager::save_channels_to_send_stories() { + CHECK(channels_to_send_stories_inited_); + if (G()->use_message_database()) { + G()->td_db()->get_binlog_pmc()->set( + "channels_to_send_stories", + implode(transform(channels_to_send_stories_, [](auto channel_id) { return PSTRING() << channel_id.get(); }), + ',')); + } +} + +void StoryManager::can_send_story(DialogId dialog_id, + Promise> &&promise) { + if (!td_->dialog_manager_->have_dialog_force(dialog_id, "can_send_story")) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + if (!can_post_stories(dialog_id)) { + return promise.set_error(Status::Error(400, "Not enough rights to post stories in the chat")); + } + td_->create_handler(std::move(promise))->send(dialog_id); +} + +void StoryManager::send_story(DialogId dialog_id, td_api::object_ptr &&input_story_content, + td_api::object_ptr &&input_areas, + td_api::object_ptr &&input_caption, + td_api::object_ptr &&settings, int32 active_period, + td_api::object_ptr &&from_story_full_id, bool is_pinned, + bool protect_content, Promise> &&promise) { + if (!td_->dialog_manager_->have_dialog_force(dialog_id, "send_story")) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + if (!can_post_stories(dialog_id)) { + return promise.set_error(Status::Error(400, "Not enough rights to post stories in the chat")); + } + + bool is_bot = td_->auth_manager_->is_bot(); + TRY_RESULT_PROMISE(promise, content, get_input_story_content(td_, std::move(input_story_content), dialog_id)); + TRY_RESULT_PROMISE(promise, caption, + get_formatted_text(td_, DialogId(), std::move(input_caption), is_bot, true, false, false)); + if (dialog_id != td_->dialog_manager_->get_my_dialog_id()) { + settings = td_api::make_object(); + } + TRY_RESULT_PROMISE(promise, privacy_rules, + UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(settings))); + unique_ptr forward_info; + StoryFullId forward_from_story_full_id; + if (from_story_full_id != nullptr) { + forward_from_story_full_id = + StoryFullId(DialogId(from_story_full_id->sender_chat_id_), StoryId(from_story_full_id->story_id_)); + const Story *story = get_story(forward_from_story_full_id); + if (story == nullptr || story->content_ == nullptr) { + return promise.set_error(Status::Error(400, "Story to repost not found")); + } + if (story->noforwards_) { + return promise.set_error(Status::Error(400, "Story can't be reposted")); + } + if (story->forward_info_ != nullptr) { + forward_info = make_unique(*story->forward_info_); + } else { + forward_info = make_unique(forward_from_story_full_id, true); + } + forward_info->hide_sender_if_needed(td_); + } + if (active_period != 86400 && !(G()->is_test_dc() && (active_period == 60 || active_period == 300))) { + bool is_premium = td_->option_manager_->get_option_boolean("is_premium"); + if (!is_premium || !td::contains(vector{6 * 3600, 12 * 3600, 2 * 86400}, active_period)) { + return promise.set_error(Status::Error(400, "Invalid story active period specified")); + } + } + TRY_RESULT_PROMISE(promise, story_id, get_next_yet_unsent_story_id(dialog_id)); + vector areas; + if (input_areas != nullptr) { + for (auto &input_area : input_areas->areas_) { + MediaArea media_area(td_, std::move(input_area), Auto()); + if (media_area.is_valid()) { + areas.push_back(std::move(media_area)); + } + } + } + if (!td_->option_manager_->get_option_boolean("can_use_text_entities_in_story_caption")) { + caption.entities.clear(); + } + + td_->dialog_manager_->force_create_dialog(dialog_id, "send_story"); + + auto story = make_unique(); + if (dialog_id.get_type() == DialogType::Channel && + td_->chat_manager_->is_megagroup_channel(dialog_id.get_channel_id())) { + story->sender_dialog_id_ = td_->messages_manager_->get_dialog_default_send_message_as_dialog_id(dialog_id); + if (story->sender_dialog_id_ == DialogId() && + !td_->dialog_manager_->is_anonymous_administrator(dialog_id, nullptr)) { + story->sender_dialog_id_ = td_->dialog_manager_->get_my_dialog_id(); + } + } + story->date_ = G()->unix_time(); + story->expire_date_ = story->date_ + active_period; + story->is_pinned_ = is_pinned; + story->is_outgoing_ = true; + story->noforwards_ = protect_content; + story->privacy_rules_ = std::move(privacy_rules); + story->content_ = std::move(content); + story->forward_info_ = std::move(forward_info); + story->areas_ = std::move(areas); + story->caption_ = std::move(caption); + + int64 random_id; + do { + random_id = Random::secure_int64(); + } while (random_id == 0 || being_sent_stories_.count(random_id) > 0); + + auto story_ptr = story.get(); + + auto pending_story = td::make_unique(dialog_id, story_id, forward_from_story_full_id, + ++send_story_count_, random_id, std::move(story)); + pending_story->log_event_id_ = save_send_story_log_event(pending_story.get()); + + do_send_story(std::move(pending_story), {}); + + promise.set_value(get_story_object({dialog_id, story_id}, story_ptr)); +} + +class StoryManager::SendStoryLogEvent { + public: + const PendingStory *pending_story_in_; + unique_ptr pending_story_out_; + + SendStoryLogEvent() : pending_story_in_(nullptr) { + } + + explicit SendStoryLogEvent(const PendingStory *pending_story) : pending_story_in_(pending_story) { + } + + template + void store(StorerT &storer) const { + td::store(*pending_story_in_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(pending_story_out_, parser); + } +}; + +int64 StoryManager::save_send_story_log_event(const PendingStory *pending_story) { + if (!G()->use_message_database()) { + return 0; + } + + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SendStory, + get_log_event_storer(SendStoryLogEvent(pending_story))); +} + +void StoryManager::do_send_story(unique_ptr &&pending_story, vector bad_parts) { + CHECK(pending_story != nullptr); + CHECK(pending_story->story_id_.is_valid()); + CHECK(pending_story->story_ != nullptr); + CHECK(pending_story->story_->content_ != nullptr); + CHECK(pending_story->story_id_.is_valid()); + + auto story_full_id = StoryFullId(pending_story->dialog_id_, pending_story->story_id_); + if (bad_parts.empty()) { + if (!pending_story->story_id_.is_server()) { + auto story = make_unique(); + story->sender_dialog_id_ = pending_story->story_->sender_dialog_id_; + story->date_ = pending_story->story_->date_; + story->expire_date_ = pending_story->story_->expire_date_; + story->is_pinned_ = pending_story->story_->is_pinned_; + story->is_outgoing_ = true; + story->noforwards_ = pending_story->story_->noforwards_; + story->privacy_rules_ = pending_story->story_->privacy_rules_; + story->content_ = std::move(pending_story->story_->content_); + pending_story->story_->content_ = dup_story_content(td_, story->content_.get()); + story->areas_ = pending_story->story_->areas_; + story->caption_ = pending_story->story_->caption_; + send_update_story(story_full_id, story.get()); + stories_.set(story_full_id, std::move(story)); + + auto active_stories = get_active_stories_force(pending_story->dialog_id_, "do_send_story"); + + CHECK(pending_story->dialog_id_.is_valid()); + CHECK(pending_story->random_id_ != 0); + yet_unsent_stories_[pending_story->dialog_id_].insert(pending_story->send_story_num_); + yet_unsent_story_ids_[pending_story->dialog_id_].push_back(pending_story->story_id_); + being_sent_stories_[pending_story->random_id_] = story_full_id; + being_sent_story_random_ids_[story_full_id] = pending_story->random_id_; + + updated_active_stories_.insert(pending_story->dialog_id_); + send_update_chat_active_stories(pending_story->dialog_id_, active_stories, "do_send_story"); + update_story_list_sent_total_count(StoryListId::main(), "do_send_story"); + } else { + pending_story->story_->content_ = dup_story_content(td_, pending_story->story_->content_.get()); + } + } + + auto content = pending_story->story_->content_.get(); + auto upload_order = pending_story->send_story_num_; + + FileId file_id = get_story_content_any_file_id(content); + CHECK(file_id.is_valid()); + + LOG(INFO) << "Ask to upload file " << file_id << " with bad parts " << bad_parts; + if (!pending_story->story_id_.is_server()) { + being_uploaded_file_ids_[story_full_id] = file_id; + } + bool is_inserted = being_uploaded_files_.emplace(file_id, std::move(pending_story)).second; + CHECK(is_inserted); + // need to call resume_upload synchronously to make upload process consistent with being_uploaded_files_ + // and to send is_uploading_active == true in response + td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_media_callback_, 1, upload_order); +} + +void StoryManager::on_upload_story(FileId file_id, telegram_api::object_ptr input_file) { + if (G()->close_flag()) { + return; + } + + LOG(INFO) << "File " << file_id << " has been uploaded"; + + auto it = being_uploaded_files_.find(file_id); + if (it == being_uploaded_files_.end()) { + // callback may be called just before the file upload was canceled + return; + } + + auto pending_story = std::move(it->second); + + being_uploaded_files_.erase(it); + + if (!pending_story->story_id_.is_server()) { + being_uploaded_file_ids_.erase({pending_story->dialog_id_, pending_story->story_id_}); + + auto deleted_story_it = delete_yet_unsent_story_queries_.find(pending_story->random_id_); + if (deleted_story_it != delete_yet_unsent_story_queries_.end()) { + auto promises = std::move(deleted_story_it->second); + delete_yet_unsent_story_queries_.erase(deleted_story_it); + fail_promises(promises, Status::Error(400, "Story upload has been already completed")); + } + } + + FileView file_view = td_->file_manager_->get_file_view(file_id); + CHECK(!file_view.is_encrypted()); + const auto *main_remote_location = file_view.get_main_remote_location(); + if (input_file == nullptr && main_remote_location != nullptr) { + if (main_remote_location->is_web()) { + delete_pending_story(file_id, std::move(pending_story), Status::Error(400, "Can't use web photo as a story")); + return; + } + if (pending_story->was_reuploaded_) { + delete_pending_story(file_id, std::move(pending_story), Status::Error(500, "Failed to reupload story")); + return; + } + pending_story->was_reuploaded_ = true; + + // delete file reference and forcely reupload the file + td_->file_manager_->delete_file_reference(file_id, main_remote_location->get_file_reference()); + do_send_story(std::move(pending_story), {-1}); + return; + } + CHECK(input_file != nullptr); + + bool is_edit = pending_story->story_id_.is_server(); + if (is_edit) { + do_edit_story(file_id, std::move(pending_story), std::move(input_file)); + } else { + auto dialog_id = pending_story->dialog_id_; + auto send_story_num = pending_story->send_story_num_; + LOG(INFO) << "Story " << send_story_num << " is ready to be sent"; + ready_to_send_stories_.emplace( + send_story_num, td::make_unique(file_id, std::move(pending_story), std::move(input_file))); + try_send_story(dialog_id); + } +} + +void StoryManager::on_upload_story_error(FileId file_id, Status status) { + if (G()->close_flag()) { + // do not fail upload if closing + return; + } + + LOG(INFO) << "File " << file_id << " has upload error " << status; + + auto it = being_uploaded_files_.find(file_id); + if (it == being_uploaded_files_.end()) { + // callback may be called just before the file upload was canceled + return; + } + + auto pending_story = std::move(it->second); + + being_uploaded_files_.erase(it); + + vector> promises; + if (!pending_story->story_id_.is_server()) { + being_uploaded_file_ids_.erase({pending_story->dialog_id_, pending_story->story_id_}); + + auto deleted_story_it = delete_yet_unsent_story_queries_.find(pending_story->random_id_); + if (deleted_story_it != delete_yet_unsent_story_queries_.end()) { + promises = std::move(deleted_story_it->second); + delete_yet_unsent_story_queries_.erase(deleted_story_it); + status = Status::Error(406, "Canceled"); + } + } + + delete_pending_story(file_id, std::move(pending_story), std::move(status)); + set_promises(promises); +} + +void StoryManager::try_send_story(DialogId dialog_id) { + const auto yet_unsent_story_it = yet_unsent_stories_.find(dialog_id); + if (yet_unsent_story_it == yet_unsent_stories_.end()) { + LOG(INFO) << "There is no more stories to send in " << dialog_id; + return; + } + CHECK(!yet_unsent_story_it->second.empty()); + auto send_story_num = *yet_unsent_story_it->second.begin(); + auto it = ready_to_send_stories_.find(send_story_num); + if (it == ready_to_send_stories_.end()) { + LOG(INFO) << "Story " << send_story_num << " isn't ready to be sent or is being sent"; + return; + } + auto ready_to_send_story = std::move(it->second); + ready_to_send_stories_.erase(it); + + td_->create_handler()->send(ready_to_send_story->file_id_, + std::move(ready_to_send_story->pending_story_), + std::move(ready_to_send_story->input_file_)); +} + +void StoryManager::on_send_story_file_parts_missing(unique_ptr &&pending_story, vector &&bad_parts) { + do_send_story(std::move(pending_story), std::move(bad_parts)); +} + +class StoryManager::EditStoryLogEvent { + public: + const PendingStory *pending_story_in_; + unique_ptr pending_story_out_; + bool edit_media_areas_; + vector areas_; + bool edit_caption_; + FormattedText caption_; + + EditStoryLogEvent() : pending_story_in_(nullptr), edit_caption_(false) { + } + + EditStoryLogEvent(const PendingStory *pending_story, bool edit_media_areas, vector areas, + bool edit_caption, const FormattedText &caption) + : pending_story_in_(pending_story) + , edit_media_areas_(edit_media_areas) + , areas_(std::move(areas)) + , edit_caption_(edit_caption) + , caption_(caption) { + } + + template + void store(StorerT &storer) const { + bool has_caption = edit_caption_ && !caption_.text.empty(); + bool has_media_areas = edit_media_areas_ && !areas_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(edit_caption_); + STORE_FLAG(has_caption); + STORE_FLAG(edit_media_areas_); + STORE_FLAG(has_media_areas); + END_STORE_FLAGS(); + td::store(*pending_story_in_, storer); + if (has_caption) { + td::store(caption_, storer); + } + if (has_media_areas) { + td::store(areas_, storer); + } + } + + template + void parse(ParserT &parser) { + bool has_caption; + bool has_media_areas; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(edit_caption_); + PARSE_FLAG(has_caption); + PARSE_FLAG(edit_media_areas_); + PARSE_FLAG(has_media_areas); + END_PARSE_FLAGS(); + td::parse(pending_story_out_, parser); + if (has_caption) { + td::parse(caption_, parser); + } + if (has_media_areas) { + td::parse(areas_, parser); + } + } +}; + +void StoryManager::edit_story(DialogId owner_dialog_id, StoryId story_id, + td_api::object_ptr &&input_story_content, + td_api::object_ptr &&input_areas, + td_api::object_ptr &&input_caption, Promise &&promise) { + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story == nullptr || story->content_ == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!can_edit_story(story_full_id, story)) { + return promise.set_error(Status::Error(400, "Story can't be edited")); + } + + bool is_bot = td_->auth_manager_->is_bot(); + unique_ptr content; + bool are_media_areas_edited = input_areas != nullptr; + vector areas; + bool is_caption_edited = input_caption != nullptr; + FormattedText caption; + if (input_story_content != nullptr) { + TRY_RESULT_PROMISE_ASSIGN(promise, content, + get_input_story_content(td_, std::move(input_story_content), owner_dialog_id)); + } + if (are_media_areas_edited) { + for (auto &input_area : input_areas->areas_) { + MediaArea media_area(td_, std::move(input_area), story->areas_); + if (media_area.is_valid()) { + areas.push_back(std::move(media_area)); + } + } + auto *current_areas = &story->areas_; + auto it = being_edited_stories_.find(story_full_id); + if (it != being_edited_stories_.end() && it->second->edit_media_areas_) { + current_areas = &it->second->areas_; + } + if (*current_areas == areas) { + are_media_areas_edited = false; + } else if (content == nullptr) { + return promise.set_error(Status::Error(400, "Can't edit story areas without content")); + } + } + if (is_caption_edited) { + TRY_RESULT_PROMISE_ASSIGN( + promise, caption, get_formatted_text(td_, DialogId(), std::move(input_caption), is_bot, true, false, false)); + if (!td_->option_manager_->get_option_boolean("can_use_text_entities_in_story_caption")) { + caption.entities.clear(); + } + auto *current_caption = &story->caption_; + auto it = being_edited_stories_.find(story_full_id); + if (it != being_edited_stories_.end() && it->second->edit_caption_) { + current_caption = &it->second->caption_; + } + if (*current_caption == caption) { + is_caption_edited = false; + } + } + if (content == nullptr && !are_media_areas_edited && !is_caption_edited) { + return promise.set_value(Unit()); + } + + auto &edited_story = being_edited_stories_[story_full_id]; + if (edited_story == nullptr) { + edited_story = make_unique(); + } + auto &edit_generation = edit_generations_[story_full_id]; + if (content != nullptr) { + edited_story->content_ = std::move(content); + edit_generation++; + } + if (are_media_areas_edited) { + edited_story->areas_ = std::move(areas); + edited_story->edit_media_areas_ = true; + edit_generation++; + } + if (is_caption_edited) { + edited_story->caption_ = std::move(caption); + edited_story->edit_caption_ = true; + edit_generation++; + } + edited_story->promises_.push_back(std::move(promise)); + + auto new_story = make_unique(); + new_story->content_ = copy_story_content(edited_story->content_.get()); + + auto pending_story = td::make_unique(owner_dialog_id, story_id, StoryFullId(), + std::numeric_limits::max() - (++send_story_count_), + edit_generation, std::move(new_story)); + if (G()->use_message_database()) { + EditStoryLogEvent log_event(pending_story.get(), edited_story->edit_media_areas_, edited_story->areas_, + edited_story->edit_caption_, edited_story->caption_); + auto storer = get_log_event_storer(log_event); + auto &cur_log_event_id = edited_story->log_event_id_; + if (cur_log_event_id == 0) { + cur_log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::EditStory, storer); + LOG(INFO) << "Add edit story log event " << cur_log_event_id; + } else { + auto new_log_event_id = + binlog_rewrite(G()->td_db()->get_binlog(), cur_log_event_id, LogEvent::HandlerType::EditStory, storer); + LOG(INFO) << "Rewrite edit story log event " << cur_log_event_id << " with " << new_log_event_id; + } + } + + on_story_changed(story_full_id, story, true, true); + + if (edited_story->content_ == nullptr) { + return do_edit_story(FileId(), std::move(pending_story), nullptr); + } + + do_send_story(std::move(pending_story), {}); +} + +void StoryManager::do_edit_story(FileId file_id, unique_ptr &&pending_story, + telegram_api::object_ptr input_file) { + StoryFullId story_full_id{pending_story->dialog_id_, pending_story->story_id_}; + const Story *story = get_story(story_full_id); + auto it = being_edited_stories_.find(story_full_id); + if (story == nullptr || it == being_edited_stories_.end() || + edit_generations_[story_full_id] != pending_story->random_id_) { + LOG(INFO) << "Skip outdated edit of " << story_full_id; + if (file_id.is_valid()) { + td_->file_manager_->cancel_upload(file_id); + } + return; + } + CHECK(story->content_ != nullptr); + td_->create_handler()->send(file_id, story, std::move(pending_story), std::move(input_file), + it->second.get()); +} + +void StoryManager::edit_story_cover(DialogId owner_dialog_id, StoryId story_id, double main_frame_timestamp, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story == nullptr || story->content_ == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!can_edit_story(story_full_id, story)) { + return promise.set_error(Status::Error(400, "Story can't be edited")); + } + if (being_edited_stories_.count(story_full_id) > 0) { + return promise.set_error(Status::Error(400, "Story is being edited")); + } + if (main_frame_timestamp < 0.0) { + return promise.set_error(Status::Error(400, "Wrong cover timestamp specified")); + } + if (story->content_->get_type() != StoryContentType::Video) { + return promise.set_error(Status::Error(400, "Cover timestamp can't be edited for the story")); + } + auto input_media = get_story_content_document_input_media(td_, story->content_.get(), main_frame_timestamp); + if (input_media == nullptr) { + return promise.set_error(Status::Error(400, "Can't edit story cover")); + } + + td_->create_handler(std::move(promise)) + ->send(owner_dialog_id, story_id, main_frame_timestamp, get_story_content_any_file_id(story->content_.get()), + std::move(input_media)); +} + +void StoryManager::delete_pending_story(FileId file_id, unique_ptr &&pending_story, Status status) { + if (G()->close_flag() && G()->use_message_database()) { + return; + } + if (file_id.is_valid()) { + td_->file_manager_->delete_partial_remote_location(file_id); + } + + CHECK(pending_story != nullptr); + StoryFullId story_full_id{pending_story->dialog_id_, pending_story->story_id_}; + const Story *story = get_story(story_full_id); + bool is_edit = pending_story->story_id_.is_server(); + if (is_edit) { + auto it = being_edited_stories_.find(story_full_id); + if (story == nullptr || it == being_edited_stories_.end() || + edit_generations_[story_full_id] != pending_story->random_id_) { + LOG(INFO) << "Ignore outdated edit of " << story_full_id; + return; + } + CHECK(story->content_ != nullptr); + auto promises = std::move(it->second->promises_); + auto log_event_id = it->second->log_event_id_; + if (log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), log_event_id); + } + being_edited_stories_.erase(it); + + on_story_changed(story_full_id, story, true, true); + + if (status.is_ok()) { + set_promises(promises); + } else { + fail_promises(promises, std::move(status)); + } + CHECK(pending_story->log_event_id_ == 0); + } else { + LOG(INFO) << "Finish sending of story " << pending_story->send_story_num_; + if (story != nullptr) { + if (status.is_ok()) { + LOG(ERROR) << "Failed to receive sent " << story_full_id; + status = Status::Error(500, "Failed to receive a sent story"); + } + auto story_object = get_story_object(story_full_id, story); + delete_story_files(story); + stories_.erase(story_full_id); + send_update_chat_active_stories(pending_story->dialog_id_, get_active_stories(pending_story->dialog_id_), + "delete_pending_story"); + send_closure( + G()->td(), &Td::send_update, + td_api::make_object( + std::move(story_object), td_api::make_object(status.code(), status.message().str()), + get_can_send_story_result_object(status, true))); + } + auto it = yet_unsent_stories_.find(pending_story->dialog_id_); + CHECK(it != yet_unsent_stories_.end()); + bool is_deleted = it->second.erase(pending_story->send_story_num_) > 0; + CHECK(is_deleted); + if (it->second.empty()) { + yet_unsent_stories_.erase(it); + yet_unsent_story_ids_.erase(pending_story->dialog_id_); + update_story_list_sent_total_count(StoryListId::main(), "delete_pending_story"); + } else { + auto story_id_it = yet_unsent_story_ids_.find(pending_story->dialog_id_); + CHECK(story_id_it != yet_unsent_story_ids_.end()); + bool is_story_id_deleted = remove(story_id_it->second, pending_story->story_id_); + CHECK(is_story_id_deleted); + CHECK(!yet_unsent_story_ids_.empty()); + } + being_sent_stories_.erase(pending_story->random_id_); + being_sent_story_random_ids_.erase(story_full_id); + try_send_story(pending_story->dialog_id_); + + if (pending_story->log_event_id_ != 0) { + binlog_erase(G()->td_db()->get_binlog(), pending_story->log_event_id_); + } + } +} + +void StoryManager::set_story_privacy_settings(StoryId story_id, + td_api::object_ptr &&settings, + Promise &&promise) { + DialogId owner_dialog_id(td_->dialog_manager_->get_my_dialog_id()); + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story == nullptr || story->content_ == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!can_edit_story(story_full_id, story)) { + return promise.set_error(Status::Error(400, "Story privacy settings can't be edited")); + } + TRY_RESULT_PROMISE(promise, privacy_rules, + UserPrivacySettingRules::get_user_privacy_setting_rules(td_, std::move(settings))); + td_->create_handler(std::move(promise)) + ->send(owner_dialog_id, story_id, std::move(privacy_rules)); +} + +void StoryManager::toggle_story_is_pinned(DialogId owner_dialog_id, StoryId story_id, bool is_pinned, + Promise &&promise) { + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story == nullptr || story->content_ == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!can_toggle_story_is_pinned(story_full_id, story)) { + return promise.set_error(Status::Error(400, "Story can't be pinned/unpinned")); + } + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), story_full_id, is_pinned, + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &StoryManager::on_toggle_story_is_pinned, story_full_id, is_pinned, std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(owner_dialog_id, story_id, is_pinned); +} + +void StoryManager::on_toggle_story_is_pinned(StoryFullId story_full_id, bool is_pinned, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + Story *story = get_story_editable(story_full_id); + if (story != nullptr) { + CHECK(story->content_ != nullptr); + story->is_pinned_ = is_pinned; + on_story_changed(story_full_id, story, true, true); + } + promise.set_value(Unit()); +} + +void StoryManager::delete_story(DialogId owner_dialog_id, StoryId story_id, Promise &&promise) { + StoryFullId story_full_id{owner_dialog_id, story_id}; + const Story *story = get_story(story_full_id); + if (story == nullptr) { + return promise.set_error(Status::Error(400, "Story not found")); + } + if (!can_delete_story(story_full_id, story)) { + return promise.set_error(Status::Error(400, "Story can't be deleted")); + } + if (!story_id.is_server()) { + auto file_id_it = being_uploaded_file_ids_.find(story_full_id); + if (file_id_it == being_uploaded_file_ids_.end()) { + return promise.set_error(Status::Error(400, "Story upload has been already completed")); + } + auto file_id = file_id_it->second; + auto random_id_it = being_sent_story_random_ids_.find(story_full_id); + if (random_id_it == being_sent_story_random_ids_.end()) { + return promise.set_error(Status::Error(400, "Story not found")); + } + int64 random_id = random_id_it->second; + CHECK(random_id != 0); + + LOG(INFO) << "Cancel uploading of " << story_full_id; + + send_closure_later(G()->file_manager(), &FileManager::cancel_upload, file_id); + + delete_yet_unsent_story_queries_[random_id].push_back(std::move(promise)); + return; + } + + delete_story_on_server(story_full_id, 0, std::move(promise)); +} + +class StoryManager::DeleteStoryOnServerLogEvent { + public: + StoryFullId story_full_id_; + + template + void store(StorerT &storer) const { + td::store(story_full_id_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(story_full_id_, parser); + } +}; + +uint64 StoryManager::save_delete_story_on_server_log_event(StoryFullId story_full_id) { + DeleteStoryOnServerLogEvent log_event{story_full_id}; + return binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::DeleteStoryOnServer, + get_log_event_storer(log_event)); +} + +void StoryManager::delete_story_on_server(StoryFullId story_full_id, uint64 log_event_id, Promise &&promise) { + LOG(INFO) << "Delete " << story_full_id << " from server"; + CHECK(story_full_id.is_server()); + + if (log_event_id == 0) { + log_event_id = save_delete_story_on_server_log_event(story_full_id); + } + + auto new_promise = get_erase_log_event_promise(log_event_id, std::move(promise)); + promise = std::move(new_promise); // to prevent self-move + + deleted_story_full_ids_.insert(story_full_id); + + td_->create_handler(std::move(promise)) + ->send(story_full_id.get_dialog_id(), {story_full_id.get_story_id()}); + + on_delete_story(story_full_id); +} + +telegram_api::object_ptr StoryManager::get_input_media(StoryFullId story_full_id) const { + auto dialog_id = story_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); + if (input_peer == nullptr) { + return nullptr; + } + return telegram_api::make_object(std::move(input_peer), + story_full_id.get_story_id().get()); +} + +void StoryManager::remove_story_notifications_by_story_ids(DialogId dialog_id, const vector &story_ids) { + VLOG(notifications) << "Trying to remove notification about " << story_ids << " in " << dialog_id; + for (auto story_id : story_ids) { + if (!story_id.is_server()) { + LOG(ERROR) << "Tried to delete " << story_id << " in " << dialog_id; + continue; + } + StoryFullId story_full_id{dialog_id, story_id}; + if (!have_story_force(story_full_id)) { + LOG(INFO) << "Can't delete " << story_full_id << " because it is not found"; + // call synchronously to remove them before ProcessPush returns + // td_->notification_manager_->remove_temporary_notification_by_story_id( + // story_notification_group_id, story_full_id, true, "remove_story_notifications_by_story_ids"); + continue; + } + on_delete_story(story_full_id); + } +} + +void StoryManager::get_current_state(vector> &updates) const { + active_stories_.foreach([&](const DialogId &dialog_id, const unique_ptr &active_stories) { + if (updated_active_stories_.count(dialog_id) > 0) { + updates.push_back(get_update_chat_active_stories_object(dialog_id, active_stories.get())); + } + }); + if (!td_->auth_manager_->is_bot()) { + for (auto story_list_id : {StoryListId::main(), StoryListId::archive()}) { + const auto &story_list = get_story_list(story_list_id); + if (story_list.sent_total_count_ != -1) { + updates.push_back(get_update_story_list_chat_count_object(story_list_id, story_list)); + } + } + + updates.push_back(get_update_story_stealth_mode()); + } +} + +void StoryManager::on_binlog_events(vector &&events) { + if (G()->close_flag()) { + return; + } + bool have_old_message_database = G()->use_message_database() && !G()->td_db()->was_dialog_db_created(); + for (auto &event : events) { + CHECK(event.id_ != 0); + switch (event.type_) { + case LogEvent::HandlerType::DeleteStoryOnServer: { + DeleteStoryOnServerLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto owner_dialog_id = log_event.story_full_id_.get_dialog_id(); + td_->dialog_manager_->have_dialog_force(owner_dialog_id, "DeleteStoryOnServerLogEvent"); + delete_story_on_server(log_event.story_full_id_, event.id_, Auto()); + break; + } + case LogEvent::HandlerType::ReadStoriesOnServer: { + ReadStoriesOnServerLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto owner_dialog_id = log_event.dialog_id_; + if (!td_->dialog_manager_->have_dialog_force(owner_dialog_id, "ReadStoriesOnServerLogEvent")) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + auto max_read_story_id = log_event.max_story_id_; + auto active_stories = get_active_stories_force(owner_dialog_id, "ReadStoriesOnServerLogEvent"); + if (active_stories == nullptr) { + max_read_story_ids_[owner_dialog_id] = max_read_story_id; + on_update_dialog_max_read_story_id(owner_dialog_id, max_read_story_id); + } else { + auto story_ids = active_stories->story_ids_; + on_update_active_stories(owner_dialog_id, max_read_story_id, std::move(story_ids), Promise(), + "ReadStoriesOnServerLogEvent"); + } + read_stories_on_server(owner_dialog_id, max_read_story_id, event.id_); + break; + } + case LogEvent::HandlerType::LoadDialogExpiringStories: { + LoadDialogExpiringStoriesLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto owner_dialog_id = log_event.dialog_id_; + if (!td_->dialog_manager_->have_dialog_force(owner_dialog_id, "LoadDialogExpiringStoriesLogEvent")) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + load_dialog_expiring_stories(owner_dialog_id, event.id_, "LoadDialogExpiringStoriesLogEvent"); + break; + } + case LogEvent::HandlerType::SendStory: { + if (!have_old_message_database) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + SendStoryLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto pending_story = std::move(log_event.pending_story_out_); + pending_story->log_event_id_ = event.id_; + + CHECK(pending_story->story_->content_ != nullptr); + if (pending_story->story_->content_->get_type() == StoryContentType::Unsupported) { + LOG(ERROR) << "Sent story content is invalid: " << format::as_hex_dump<4>(event.get_data()); + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + Dependencies dependencies; + add_pending_story_dependencies(dependencies, pending_story.get()); + if (!dependencies.resolve_force(td_, "SendStoryLogEvent")) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + ++send_story_count_; + CHECK(!pending_story->story_id_.is_server()); + pending_story->story_id_ = get_next_yet_unsent_story_id(pending_story->dialog_id_).move_as_ok(); + pending_story->send_story_num_ = send_story_count_; + do_send_story(std::move(pending_story), {}); + break; + } + case LogEvent::HandlerType::EditStory: { + if (!have_old_message_database) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + EditStoryLogEvent log_event; + log_event_parse(log_event, event.get_data()).ensure(); + + auto pending_story = std::move(log_event.pending_story_out_); + CHECK(pending_story->story_id_.is_server()); + StoryFullId story_full_id{pending_story->dialog_id_, pending_story->story_id_}; + const Story *story = get_story_force(story_full_id, "EditStoryLogEvent"); + if (story == nullptr || story->content_ == nullptr) { + LOG(INFO) << "Failed to find " << story_full_id; + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + if (pending_story->story_->content_ != nullptr && + pending_story->story_->content_->get_type() == StoryContentType::Unsupported) { + LOG(ERROR) << "Sent story content is invalid: " << format::as_hex_dump<4>(event.get_data()); + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + Dependencies dependencies; + add_pending_story_dependencies(dependencies, pending_story.get()); + if (!dependencies.resolve_force(td_, "EditStoryLogEvent")) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + + auto &edited_story = being_edited_stories_[story_full_id]; + if (edited_story != nullptr) { + LOG(INFO) << "Ignore outdated edit of " << story_full_id; + binlog_erase(G()->td_db()->get_binlog(), event.id_); + break; + } + edited_story = make_unique(); + if (pending_story->story_->content_ != nullptr) { + edited_story->content_ = std::move(pending_story->story_->content_); + } + if (log_event.edit_media_areas_) { + edited_story->areas_ = std::move(log_event.areas_); + edited_story->edit_media_areas_ = true; + } + if (log_event.edit_caption_) { + edited_story->caption_ = std::move(log_event.caption_); + edited_story->edit_caption_ = true; + } + edited_story->log_event_id_ = event.id_; + + ++send_story_count_; + pending_story->send_story_num_ = std::numeric_limits::max() - send_story_count_; + pending_story->random_id_ = ++edit_generations_[story_full_id]; + + if (edited_story->content_ == nullptr) { + do_edit_story(FileId(), std::move(pending_story), nullptr); + } else { + pending_story->story_->content_ = copy_story_content(edited_story->content_.get()); + do_send_story(std::move(pending_story), {}); + } + break; + } + default: + LOG(FATAL) << "Unsupported log event type " << event.type_; + } + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryManager.h b/protocols/Telegram/tdlib/td/td/telegram/StoryManager.h new file mode 100644 index 0000000000..a2876005d2 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryManager.h @@ -0,0 +1,753 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ChannelId.h" +#include "td/telegram/DialogDate.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/files/FileSourceId.h" +#include "td/telegram/MediaArea.h" +#include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/QuickReplyMessageFullId.h" +#include "td/telegram/ReactionType.h" +#include "td/telegram/StoryDb.h" +#include "td/telegram/StoryFullId.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/StoryInteractionInfo.h" +#include "td/telegram/StoryListId.h" +#include "td/telegram/StoryStealthMode.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" +#include "td/telegram/UserPrivacySettingRule.h" + +#include "td/actor/actor.h" +#include "td/actor/MultiTimeout.h" +#include "td/actor/Timeout.h" + +#include "td/utils/buffer.h" +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" +#include "td/utils/WaitFreeHashMap.h" +#include "td/utils/WaitFreeHashSet.h" + +#include +#include +#include + +namespace td { + +struct BinlogEvent; +class Dependencies; +class ReportReason; +class StoryContent; +class StoryForwardInfo; +struct StoryDbStory; +class Td; + +class StoryManager final : public Actor { + struct Story { + DialogId sender_dialog_id_; + int32 date_ = 0; + int32 expire_date_ = 0; + int32 receive_date_ = 0; + bool is_edited_ = false; + bool is_pinned_ = false; + bool is_public_ = false; + bool is_for_close_friends_ = false; + bool is_for_contacts_ = false; + bool is_for_selected_contacts_ = false; + bool is_outgoing_ = false; + bool noforwards_ = false; + mutable bool is_update_sent_ = false; // whether the story is known to the app + unique_ptr forward_info_; + StoryInteractionInfo interaction_info_; + ReactionType chosen_reaction_type_; + UserPrivacySettingRules privacy_rules_; + unique_ptr content_; + vector areas_; + FormattedText caption_; + int64 global_id_ = 0; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct StoryInfo { + StoryId story_id_; + int32 date_ = 0; + int32 expire_date_ = 0; + bool is_for_close_friends_ = false; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct BeingEditedStory { + unique_ptr content_; + vector areas_; + FormattedText caption_; + bool edit_media_areas_ = false; + bool edit_caption_ = false; + vector> promises_; + int64 log_event_id_ = 0; + }; + + struct PendingStory { + DialogId dialog_id_; + StoryId story_id_; + StoryFullId forward_from_story_full_id_; + uint64 log_event_id_ = 0; + uint32 send_story_num_ = 0; + int64 random_id_ = 0; + bool was_reuploaded_ = false; + unique_ptr story_; + + PendingStory() = default; + + PendingStory(DialogId dialog_id, StoryId story_id, StoryFullId forward_from_story_full_id, uint32 send_story_num, + int64 random_id, unique_ptr &&story); + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct ReadyToSendStory { + FileId file_id_; + unique_ptr pending_story_; + telegram_api::object_ptr input_file_; + + ReadyToSendStory(FileId file_id, unique_ptr &&pending_story, + telegram_api::object_ptr &&input_file); + }; + + struct PendingStoryViews { + FlatHashSet story_ids_; + bool has_query_ = false; + }; + + struct ActiveStories { + StoryId max_read_story_id_; + vector story_ids_; + StoryListId story_list_id_; + int64 private_order_ = 0; + int64 public_order_ = 0; + }; + + struct SavedActiveStories { + StoryId max_read_story_id_; + vector story_infos_; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct StoryList { + int32 server_total_count_ = -1; + int32 sent_total_count_ = -1; + string state_; + + bool is_reloaded_server_total_count_ = false; + bool server_has_more_ = true; + bool database_has_more_ = false; + + vector> load_list_from_server_queries_; + vector> load_list_from_database_queries_; + + std::set ordered_stories_; // all known active stories from the story list + + DialogDate last_loaded_database_dialog_date_ = MIN_DIALOG_DATE; // in memory + DialogDate list_last_story_date_ = MIN_DIALOG_DATE; // in memory + }; + + struct SavedStoryList { + string state_; + int32 total_count_ = -1; + bool has_more_ = true; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + public: + StoryManager(Td *td, ActorShared<> parent); + StoryManager(const StoryManager &) = delete; + StoryManager &operator=(const StoryManager &) = delete; + StoryManager(StoryManager &&) = delete; + StoryManager &operator=(StoryManager &&) = delete; + ~StoryManager() final; + + void get_story(DialogId owner_dialog_id, StoryId story_id, bool only_local, + Promise> &&promise); + + void get_dialogs_to_send_stories(Promise> &&promise); + + void reload_dialogs_to_send_stories(Promise> &&promise); + + void on_get_dialogs_to_send_stories(vector> &&chats); + + void update_dialogs_to_send_stories(ChannelId channel_id, bool can_send_stories); + + void can_send_story(DialogId dialog_id, Promise> &&promise); + + void send_story(DialogId dialog_id, td_api::object_ptr &&input_story_content, + td_api::object_ptr &&input_areas, + td_api::object_ptr &&input_caption, + td_api::object_ptr &&settings, int32 active_period, + td_api::object_ptr &&from_story_full_id, bool is_pinned, bool protect_content, + Promise> &&promise); + + void on_send_story_file_parts_missing(unique_ptr &&pending_story, vector &&bad_parts); + + void edit_story(DialogId owner_dialog_id, StoryId story_id, + td_api::object_ptr &&input_story_content, + td_api::object_ptr &&input_areas, + td_api::object_ptr &&input_caption, Promise &&promise); + + void edit_story_cover(DialogId owner_dialog_id, StoryId story_id, double main_frame_timestamp, + Promise &&promise); + + void set_story_privacy_settings(StoryId story_id, td_api::object_ptr &&settings, + Promise &&promise); + + void toggle_story_is_pinned(DialogId owner_dialog_id, StoryId story_id, bool is_pinned, Promise &&promise); + + void delete_story(DialogId owner_dialog_id, StoryId story_id, Promise &&promise); + + void load_active_stories(StoryListId story_list_id, Promise &&promise); + + void reload_active_stories(); + + void reload_all_read_stories(); + + void toggle_dialog_stories_hidden(DialogId dialog_id, StoryListId story_list_id, Promise &&promise); + + void get_dialog_pinned_stories(DialogId owner_dialog_id, StoryId from_story_id, int32 limit, + Promise> &&promise); + + void get_story_archive(DialogId owner_dialog_id, StoryId from_story_id, int32 limit, + Promise> &&promise); + + void get_dialog_expiring_stories(DialogId owner_dialog_id, + Promise> &&promise); + + void reload_dialog_expiring_stories(DialogId dialog_id); + + void search_hashtag_posts(string hashtag, string offset, int32 limit, + Promise> &&promise); + + void search_location_posts(td_api::object_ptr &&address, string offset, int32 limit, + Promise> &&promise); + + void search_venue_posts(string venue_provider, string venue_id, string offset, int32 limit, + Promise> &&promise); + + void set_pinned_stories(DialogId owner_dialog_id, vector story_ids, Promise &&promise); + + void open_story(DialogId owner_dialog_id, StoryId story_id, Promise &&promise); + + void close_story(DialogId owner_dialog_id, StoryId story_id, Promise &&promise); + + void view_story_message(StoryFullId story_full_id); + + void on_story_replied(StoryFullId story_full_id, UserId replier_user_id); + + void set_story_reaction(StoryFullId story_full_id, ReactionType reaction_type, bool add_to_recent, + Promise &&promise); + + void get_story_interactions(StoryId story_id, const string &query, bool only_contacts, bool prefer_forwards, + bool prefer_with_reaction, const string &offset, int32 limit, + Promise> &&promise); + + void get_dialog_story_interactions(StoryFullId story_full_id, ReactionType reaction_type, bool prefer_forwards, + const string &offset, int32 limit, + Promise> &&promise); + + void get_channel_differences_if_needed( + telegram_api::object_ptr &&story_views, + Promise> promise); + + void get_channel_differences_if_needed( + telegram_api::object_ptr &&story_reactions, + Promise> promise); + + void report_story(StoryFullId story_full_id, ReportReason &&reason, Promise &&promise); + + void activate_stealth_mode(Promise &&promise); + + void remove_story_notifications_by_story_ids(DialogId dialog_id, const vector &story_ids); + + StoryId on_get_story(DialogId owner_dialog_id, telegram_api::object_ptr &&story_item_ptr); + + std::pair> on_get_stories(DialogId owner_dialog_id, vector &&expected_story_ids, + telegram_api::object_ptr &&stories); + + DialogId on_get_dialog_stories(DialogId owner_dialog_id, + telegram_api::object_ptr &&peer_stories, + Promise &&promise); + + void on_update_story_id(int64 random_id, StoryId new_story_id, const char *source); + + bool on_update_read_stories(DialogId owner_dialog_id, StoryId max_read_story_id); + + void on_update_story_stealth_mode(telegram_api::object_ptr &&stealth_mode); + + void on_update_story_chosen_reaction_type(DialogId owner_dialog_id, StoryId story_id, + ReactionType chosen_reaction_type); + + void on_update_dialog_stories_hidden(DialogId owner_dialog_id, bool stories_hidden); + + void on_dialog_active_stories_order_updated(DialogId owner_dialog_id, const char *source); + + Status can_get_story_viewers(StoryFullId story_full_id, const Story *story, int32 unix_time) const; + + bool has_unexpired_viewers(StoryFullId story_full_id, const Story *story) const; + + void on_get_story_views(DialogId owner_dialog_id, const vector &story_ids, + telegram_api::object_ptr &&story_views); + + void on_view_dialog_active_stories(vector dialog_ids); + + void on_get_dialog_max_active_story_ids(const vector &dialog_ids, const vector &max_story_ids); + + bool have_story(StoryFullId story_full_id) const; + + bool have_story_force(StoryFullId story_full_id); + + int32 get_story_date(StoryFullId story_full_id); + + bool can_get_story_statistics(StoryFullId story_full_id); + + bool is_inaccessible_story(StoryFullId story_full_id) const; + + int32 get_story_duration(StoryFullId story_full_id) const; + + void register_story(StoryFullId story_full_id, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source); + + void unregister_story(StoryFullId story_full_id, MessageFullId message_full_id, + QuickReplyMessageFullId quick_reply_message_full_id, const char *source); + + td_api::object_ptr get_story_object(StoryFullId story_full_id) const; + + td_api::object_ptr get_stories_object(int32 total_count, const vector &story_full_ids, + const vector &pinned_story_ids) const; + + static td_api::object_ptr get_can_send_story_result_object(const Status &error, + bool force = false); + + FileSourceId get_story_file_source_id(StoryFullId story_full_id); + + telegram_api::object_ptr get_input_media(StoryFullId story_full_id) const; + + void reload_story(StoryFullId story_full_id, Promise &&promise, const char *source); + + void try_synchronize_archive_all_stories(); + + void get_current_state(vector> &updates) const; + + void on_binlog_events(vector &&events); + + private: + class UploadMediaCallback; + + class SendStoryQuery; + class EditStoryQuery; + + class DeleteStoryOnServerLogEvent; + class ReadStoriesOnServerLogEvent; + class LoadDialogExpiringStoriesLogEvent; + class SendStoryLogEvent; + class EditStoryLogEvent; + + static constexpr int32 MAX_SEARCH_STORIES = 100; // server-side limit + + static constexpr int32 OPENED_STORY_POLL_PERIOD = 60; + static constexpr int32 VIEWED_STORY_POLL_PERIOD = 300; + + static constexpr int32 DEFAULT_LOADED_EXPIRED_STORIES = 50; + + void start_up() final; + + void timeout_expired() final; + + void hangup() final; + + void tear_down() final; + + static void on_story_reload_timeout_callback(void *story_manager_ptr, int64 story_global_id); + + void on_story_reload_timeout(int64 story_global_id); + + static void on_story_expire_timeout_callback(void *story_manager_ptr, int64 story_global_id); + + void on_story_expire_timeout(int64 story_global_id); + + static void on_story_can_get_viewers_timeout_callback(void *story_manager_ptr, int64 story_global_id); + + void on_story_can_get_viewers_timeout(int64 story_global_id); + + bool is_my_story(DialogId owner_dialog_id) const; + + bool can_access_expired_story(DialogId owner_dialog_id, const Story *story) const; + + bool can_get_story_statistics(StoryFullId story_full_id, const Story *story) const; + + bool can_get_story_view_count(DialogId owner_dialog_id); + + bool can_post_stories(DialogId owner_dialog_id) const; + + bool can_edit_stories(DialogId owner_dialog_id) const; + + bool can_delete_stories(DialogId owner_dialog_id) const; + + bool can_edit_story(StoryFullId story_full_id, const Story *story) const; + + bool can_toggle_story_is_pinned(StoryFullId story_full_id, const Story *story) const; + + bool can_delete_story(StoryFullId story_full_id, const Story *story) const; + + int32 get_story_viewers_expire_date(const Story *story) const; + + static bool is_active_story(const Story *story); + + DialogId get_changelog_story_dialog_id() const; + + bool is_subscribed_to_dialog_stories(DialogId owner_dialog_id) const; + + StoryListId get_dialog_story_list_id(DialogId owner_dialog_id) const; + + void add_story_dependencies(Dependencies &dependencies, const Story *story); + + void add_pending_story_dependencies(Dependencies &dependencies, const PendingStory *pending_story); + + const Story *get_story(StoryFullId story_full_id) const; + + Story *get_story_editable(StoryFullId story_full_id); + + Story *get_story_force(StoryFullId story_full_id, const char *source); + + unique_ptr parse_story(StoryFullId story_full_id, const BufferSlice &value); + + Story *on_get_story_from_database(StoryFullId story_full_id, const BufferSlice &value, const char *source); + + const ActiveStories *get_active_stories(DialogId owner_dialog_id) const; + + ActiveStories *get_active_stories_editable(DialogId owner_dialog_id); + + ActiveStories *get_active_stories_force(DialogId owner_dialog_id, const char *source); + + ActiveStories *on_get_active_stories_from_database(StoryListId story_list_id, DialogId owner_dialog_id, + const BufferSlice &value, const char *source); + + void set_story_expire_timeout(const Story *story); + + void set_story_can_get_viewers_timeout(const Story *story); + + void on_story_changed(StoryFullId story_full_id, const Story *story, bool is_changed, bool need_save_to_database, + bool from_database = false); + + void register_story_global_id(StoryFullId story_full_id, Story *story); + + void unregister_story_global_id(const Story *story); + + StoryId on_get_story_info(DialogId owner_dialog_id, StoryInfo &&story_info); + + StoryInfo get_story_info(StoryFullId story_full_id) const; + + td_api::object_ptr get_story_info_object(StoryFullId story_full_id) const; + + td_api::object_ptr get_story_object(StoryFullId story_full_id, const Story *story) const; + + td_api::object_ptr get_chat_active_stories_object( + DialogId owner_dialog_id, const ActiveStories *active_stories) const; + + StoryId on_get_new_story(DialogId owner_dialog_id, telegram_api::object_ptr &&story_item); + + StoryId on_get_skipped_story(DialogId owner_dialog_id, + telegram_api::object_ptr &&story_item); + + StoryId on_get_deleted_story(DialogId owner_dialog_id, + telegram_api::object_ptr &&story_item); + + void on_delete_story(StoryFullId story_full_id); + + void return_dialogs_to_send_stories(Promise> &&promise, + const vector &channel_ids); + + void finish_get_dialogs_to_send_stories(Result &&result); + + void save_channels_to_send_stories(); + + void on_get_dialog_pinned_stories(DialogId owner_dialog_id, + telegram_api::object_ptr &&stories, + Promise> &&promise); + + void on_get_story_archive(DialogId owner_dialog_id, telegram_api::object_ptr &&stories, + Promise> &&promise); + + void on_get_dialog_expiring_stories(DialogId owner_dialog_id, + telegram_api::object_ptr &&stories, + Promise> &&promise); + + static uint64 save_load_dialog_expiring_stories_log_event(DialogId owner_dialog_id); + + void load_dialog_expiring_stories(DialogId owner_dialog_id, uint64 log_event_id, const char *source); + + void on_load_dialog_expiring_stories(DialogId owner_dialog_id); + + void on_load_active_stories_from_database(StoryListId story_list_id, Result result); + + void load_active_stories_from_server(StoryListId story_list_id, StoryList &story_list, bool is_next, + Promise &&promise); + + void on_load_active_stories_from_server( + StoryListId story_list_id, bool is_next, string old_state, + Result> r_all_stories); + + void save_story_list(StoryListId story_list_id, string state, int32 total_count, bool has_more); + + StoryList &get_story_list(StoryListId story_list_id); + + const StoryList &get_story_list(StoryListId story_list_id) const; + + td_api::object_ptr get_update_story_list_chat_count_object( + StoryListId story_list_id, const StoryList &story_list) const; + + void update_story_list_sent_total_count(StoryListId story_list_id, const char *source); + + void update_story_list_sent_total_count(StoryListId story_list_id, StoryList &story_list, const char *source); + + vector get_story_file_ids(const Story *story) const; + + static uint64 save_delete_story_on_server_log_event(StoryFullId story_full_id); + + void delete_story_on_server(StoryFullId story_full_id, uint64 log_event_id, Promise &&promise); + + void delete_story_from_database(StoryFullId story_full_id); + + void delete_story_files(const Story *story) const; + + void change_story_files(StoryFullId story_full_id, const Story *story, const vector &old_file_ids); + + void do_get_story(StoryFullId story_full_id, Result &&result, + Promise> &&promise); + + void on_reload_story(StoryFullId story_full_id, Result &&result); + + int64 save_send_story_log_event(const PendingStory *pending_story); + + void delete_pending_story(FileId file_id, unique_ptr &&pending_story, Status status); + + Result get_next_yet_unsent_story_id(DialogId dialog_id); + + void do_send_story(unique_ptr &&pending_story, vector bad_parts); + + void on_upload_story(FileId file_id, telegram_api::object_ptr input_file); + + void on_upload_story_error(FileId file_id, Status status); + + void try_send_story(DialogId dialog_id); + + void do_edit_story(FileId file_id, unique_ptr &&pending_story, + telegram_api::object_ptr input_file); + + void on_toggle_story_is_pinned(StoryFullId story_full_id, bool is_pinned, Promise &&promise); + + void on_update_dialog_max_story_ids(DialogId owner_dialog_id, StoryId max_story_id, StoryId max_read_story_id); + + void on_update_dialog_max_read_story_id(DialogId owner_dialog_id, StoryId max_read_story_id); + + void on_update_dialog_has_pinned_stories(DialogId owner_dialog_id, bool has_pinned_stories); + + void update_active_stories(DialogId owner_dialog_id); + + void on_update_active_stories(DialogId owner_dialog_id, StoryId max_read_story_id, vector &&story_ids, + Promise &&promise, const char *source, bool from_database = false); + + bool update_active_stories_order(DialogId owner_dialog_id, ActiveStories *active_stories, + bool *need_save_to_database); + + void delete_active_stories_from_story_list(DialogId owner_dialog_id, const ActiveStories *active_stories); + + void send_update_story(StoryFullId story_full_id, const Story *story); + + td_api::object_ptr get_update_chat_active_stories_object( + DialogId owner_dialog_id, const ActiveStories *active_stories) const; + + void send_update_chat_active_stories(DialogId owner_dialog_id, const ActiveStories *active_stories, + const char *source); + + void save_active_stories(DialogId owner_dialog_id, const ActiveStories *active_stories, Promise &&promise, + const char *source) const; + + void increment_story_views(DialogId owner_dialog_id, PendingStoryViews &story_views); + + void on_increment_story_views(DialogId owner_dialog_id); + + static uint64 save_read_stories_on_server_log_event(DialogId dialog_id, StoryId max_story_id); + + void read_stories_on_server(DialogId owner_dialog_id, StoryId story_id, uint64 log_event_id); + + static bool has_suggested_reaction(const Story *story, const ReactionType &reaction_type); + + bool can_use_story_reaction(const Story *story, const ReactionType &reaction_type) const; + + void on_story_chosen_reaction_changed(StoryFullId story_full_id, Story *story, const ReactionType &reaction_type); + + void schedule_interaction_info_update(); + + static void update_interaction_info_static(void *story_manager); + + void update_interaction_info(); + + void on_synchronized_archive_all_stories(bool set_archive_all_stories, Result result); + + td_api::object_ptr get_update_story_stealth_mode() const; + + void send_update_story_stealth_mode() const; + + void schedule_stealth_mode_update(); + + static void update_stealth_mode_static(void *story_manager); + + void update_stealth_mode(); + + static string get_story_stealth_mode_key(); + + void set_story_stealth_mode(StoryStealthMode stealth_mode); + + void on_get_story_interactions(StoryId story_id, bool is_full, bool is_first, + Result> r_view_list, + Promise> &&promise); + + void on_get_dialog_story_interactions( + StoryFullId story_full_id, + Result> r_reaction_list, + Promise> &&promise); + + void on_set_story_reaction(StoryFullId story_full_id, Result &&result, Promise &&promise); + + void load_expired_database_stories(); + + void on_load_expired_database_stories(vector stories); + + std::shared_ptr upload_media_callback_; + + WaitFreeHashMap story_full_id_to_file_source_id_; + + WaitFreeHashMap, StoryFullIdHash> stories_; + + WaitFreeHashMap stories_by_global_id_; + + WaitFreeHashMap inaccessible_story_full_ids_; + + WaitFreeHashSet deleted_story_full_ids_; + + WaitFreeHashSet failed_to_load_story_full_ids_; + + WaitFreeHashMap, StoryFullIdHash> story_messages_; + + WaitFreeHashMap, StoryFullIdHash> + story_quick_reply_messages_; + + WaitFreeHashMap, DialogIdHash> active_stories_; + + WaitFreeHashSet updated_active_stories_; + + WaitFreeHashMap max_read_story_ids_; + + WaitFreeHashSet failed_to_load_active_stories_; + + FlatHashMap load_expiring_stories_log_event_ids_; + + FlatHashMap, StoryFullIdHash> being_edited_stories_; + + FlatHashMap edit_generations_; + + FlatHashMap pending_story_views_; + + FlatHashMap opened_stories_with_view_count_; + + FlatHashMap opened_stories_; + + FlatHashMap>, StoryFullIdHash> reload_story_queries_; + + FlatHashMap, FileIdHash> being_uploaded_files_; + + FlatHashMap, DialogIdHash> yet_unsent_stories_; + + FlatHashMap, DialogIdHash> yet_unsent_story_ids_; + + FlatHashMap being_sent_stories_; + + FlatHashMap being_sent_story_random_ids_; + + FlatHashMap being_uploaded_file_ids_; + + FlatHashMap update_story_ids_; + + FlatHashMap>> delete_yet_unsent_story_queries_; + + FlatHashMap> ready_to_send_stories_; + + FlatHashSet being_reloaded_active_stories_dialog_ids_; + + bool channels_to_send_stories_inited_ = false; + vector channels_to_send_stories_; + vector>> get_dialogs_to_send_stories_queries_; + double next_reload_channels_to_send_stories_time_ = 0.0; + + FlatHashMap being_set_story_reactions_; + + StoryList story_lists_[2]; + + StoryStealthMode stealth_mode_; + + uint32 send_story_count_ = 0; + + int64 max_story_global_id_ = 0; + + FlatHashMap current_yet_unsent_story_ids_; + + bool has_active_synchronize_archive_all_stories_query_ = false; + + Timeout stealth_mode_update_timeout_; + + Timeout interaction_info_update_timeout_; + + int32 load_expired_database_stories_next_limit_ = DEFAULT_LOADED_EXPIRED_STORIES; + + MultiTimeout story_reload_timeout_{"StoryReloadTimeout"}; + MultiTimeout story_expire_timeout_{"StoryExpireTimeout"}; + MultiTimeout story_can_get_viewers_timeout_{"StoryCanGetViewersTimeout"}; + + Td *td_; + ActorShared<> parent_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryNotificationSettings.h b/protocols/Telegram/tdlib/td/td/telegram/StoryNotificationSettings.h new file mode 100644 index 0000000000..95b85471af --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryNotificationSettings.h @@ -0,0 +1,31 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/utils/common.h" + +namespace td { + +class StoryNotificationSettings { + public: + const bool need_dialog_settings_ = false; + const bool need_top_dialogs_ = false; + const bool are_muted_ = false; + const bool hide_sender_ = false; + const int64 ringtone_id_ = 0; + + StoryNotificationSettings(bool need_dialog_settings, bool need_top_dialogs, bool are_muted, bool hide_sender, + int64 ringtone_id) + : need_dialog_settings_(need_dialog_settings) + , need_top_dialogs_(need_top_dialogs) + , are_muted_(are_muted) + , hide_sender_(hide_sender) + , ringtone_id_(ringtone_id) { + } +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.cpp b/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.cpp new file mode 100644 index 0000000000..d44ed53bae --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.cpp @@ -0,0 +1,63 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StoryStealthMode.h" + +#include "td/telegram/Global.h" + +namespace td { + +StoryStealthMode::StoryStealthMode(telegram_api::object_ptr &&stealth_mode) + : active_until_date_(stealth_mode->active_until_date_), cooldown_until_date_(stealth_mode->cooldown_until_date_) { + update(); +} + +bool StoryStealthMode::update() { + auto current_time = G()->unix_time(); + bool result = false; + if (active_until_date_ != 0 && active_until_date_ <= current_time) { + active_until_date_ = 0; + result = true; + } + if (cooldown_until_date_ != 0 && cooldown_until_date_ <= current_time) { + cooldown_until_date_ = 0; + result = true; + } + return result; +} + +int32 StoryStealthMode::get_update_date() const { + if (active_until_date_ > 0) { + if (cooldown_until_date_ > 0) { + return min(active_until_date_, cooldown_until_date_); + } + return active_until_date_; + } + if (cooldown_until_date_ > 0) { + return cooldown_until_date_; + } + return 0; +} + +td_api::object_ptr StoryStealthMode::get_update_story_stealth_mode_object() const { + return td_api::make_object(active_until_date_, cooldown_until_date_); +} + +bool operator==(const StoryStealthMode &lhs, const StoryStealthMode &rhs) { + return lhs.active_until_date_ == rhs.active_until_date_ && lhs.cooldown_until_date_ == rhs.cooldown_until_date_; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StoryStealthMode &mode) { + if (mode.active_until_date_) { + return string_builder << "Stealth mode is active until " << mode.active_until_date_; + } + if (mode.cooldown_until_date_) { + return string_builder << "Stealth mode can't be activated until " << mode.cooldown_until_date_; + } + return string_builder << "Stealth mode can be activated"; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.h b/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.h new file mode 100644 index 0000000000..eb479930d6 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.h @@ -0,0 +1,55 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class StoryStealthMode { + int32 active_until_date_ = 0; + int32 cooldown_until_date_ = 0; + + friend bool operator==(const StoryStealthMode &lhs, const StoryStealthMode &rhs); + + friend StringBuilder &operator<<(StringBuilder &string_builder, const StoryStealthMode &mode); + + public: + StoryStealthMode() = default; + + explicit StoryStealthMode(telegram_api::object_ptr &&stealth_mode); + + bool is_empty() const { + return active_until_date_ == 0 && cooldown_until_date_ == 0; + } + + int32 get_update_date() const; + + bool update(); + + td_api::object_ptr get_update_story_stealth_mode_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const StoryStealthMode &lhs, const StoryStealthMode &rhs); + +inline bool operator!=(const StoryStealthMode &lhs, const StoryStealthMode &rhs) { + return !(lhs == rhs); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StoryStealthMode &mode); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.hpp b/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.hpp new file mode 100644 index 0000000000..e6254f7caa --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryStealthMode.hpp @@ -0,0 +1,50 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/StoryStealthMode.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void StoryStealthMode::store(StorerT &storer) const { + using td::store; + bool has_active_until_date = active_until_date_ != 0; + bool has_cooldown_until_date = cooldown_until_date_ != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_active_until_date); + STORE_FLAG(has_cooldown_until_date); + END_STORE_FLAGS(); + if (has_active_until_date) { + store(active_until_date_, storer); + } + if (has_cooldown_until_date) { + store(cooldown_until_date_, storer); + } +} + +template +void StoryStealthMode::parse(ParserT &parser) { + using td::parse; + bool has_active_until_date; + bool has_cooldown_until_date; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_active_until_date); + PARSE_FLAG(has_cooldown_until_date); + END_PARSE_FLAGS(); + if (has_active_until_date) { + parse(active_until_date_, parser); + } + if (has_cooldown_until_date) { + parse(cooldown_until_date_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryViewer.cpp b/protocols/Telegram/tdlib/td/td/telegram/StoryViewer.cpp new file mode 100644 index 0000000000..ad7187eb73 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryViewer.cpp @@ -0,0 +1,229 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/StoryViewer.h" + +#include "td/telegram/BlockListId.h" +#include "td/telegram/MessageSender.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/StoryManager.h" +#include "td/telegram/Td.h" + +#include "td/utils/algorithm.h" +#include "td/utils/logging.h" + +namespace td { + +StoryViewer::StoryViewer(Td *td, telegram_api::object_ptr &&story_view_ptr) { + CHECK(story_view_ptr != nullptr); + switch (story_view_ptr->get_id()) { + case telegram_api::storyView::ID: { + auto story_view = telegram_api::move_object_as(story_view_ptr); + UserId user_id(story_view->user_id_); + if (!user_id.is_valid() || story_view->date_ <= 0) { + break; + } + type_ = Type::View; + actor_dialog_id_ = DialogId(user_id); + date_ = story_view->date_; + is_blocked_ = story_view->blocked_; + is_blocked_for_stories_ = story_view->blocked_my_stories_from_; + reaction_type_ = ReactionType(story_view->reaction_); + break; + } + case telegram_api::storyViewPublicForward::ID: { + auto story_view = telegram_api::move_object_as(story_view_ptr); + auto date = MessagesManager::get_message_date(story_view->message_); + auto message_full_id = td->messages_manager_->on_get_message(std::move(story_view->message_), false, true, false, + "storyViewPublicForward"); + if (!message_full_id.get_message_id().is_valid() || date <= 0) { + break; + } + type_ = Type::Forward; + actor_dialog_id_ = td->messages_manager_->get_dialog_message_sender(message_full_id); + date_ = date; + is_blocked_ = story_view->blocked_; + is_blocked_for_stories_ = story_view->blocked_my_stories_from_; + message_full_id_ = message_full_id; + break; + } + case telegram_api::storyViewPublicRepost::ID: { + auto story_view = telegram_api::move_object_as(story_view_ptr); + auto owner_dialog_id = DialogId(story_view->peer_id_); + if (!owner_dialog_id.is_valid()) { + break; + } + auto story_id = td->story_manager_->on_get_story(owner_dialog_id, std::move(story_view->story_)); + auto date = td->story_manager_->get_story_date({owner_dialog_id, story_id}); + if (date <= 0) { + break; + } + type_ = Type::Repost; + actor_dialog_id_ = owner_dialog_id; + date_ = date; + is_blocked_ = story_view->blocked_; + is_blocked_for_stories_ = story_view->blocked_my_stories_from_; + story_id_ = story_id; + break; + } + default: + UNREACHABLE(); + break; + } + + if (is_valid()) { + td->messages_manager_->on_update_dialog_is_blocked(actor_dialog_id_, is_blocked_, is_blocked_for_stories_); + } +} + +StoryViewer::StoryViewer(Td *td, telegram_api::object_ptr &&story_reaction_ptr) { + CHECK(story_reaction_ptr != nullptr); + switch (story_reaction_ptr->get_id()) { + case telegram_api::storyReaction::ID: { + auto story_reaction = telegram_api::move_object_as(story_reaction_ptr); + DialogId actor_dialog_id(story_reaction->peer_id_); + if (!actor_dialog_id.is_valid() || story_reaction->date_ <= 0) { + break; + } + type_ = Type::View; + actor_dialog_id_ = actor_dialog_id; + date_ = story_reaction->date_; + reaction_type_ = ReactionType(story_reaction->reaction_); + break; + } + case telegram_api::storyReactionPublicForward::ID: { + auto story_reaction = telegram_api::move_object_as(story_reaction_ptr); + auto date = MessagesManager::get_message_date(story_reaction->message_); + auto message_full_id = td->messages_manager_->on_get_message(std::move(story_reaction->message_), false, true, + false, "storyReactionPublicForward"); + if (!message_full_id.get_message_id().is_valid() || date <= 0) { + break; + } + type_ = Type::Forward; + actor_dialog_id_ = td->messages_manager_->get_dialog_message_sender(message_full_id); + date_ = date; + message_full_id_ = message_full_id; + break; + } + case telegram_api::storyReactionPublicRepost::ID: { + auto story_reaction = telegram_api::move_object_as(story_reaction_ptr); + auto owner_dialog_id = DialogId(story_reaction->peer_id_); + if (!owner_dialog_id.is_valid()) { + break; + } + auto story_id = td->story_manager_->on_get_story(owner_dialog_id, std::move(story_reaction->story_)); + auto date = td->story_manager_->get_story_date({owner_dialog_id, story_id}); + if (date <= 0) { + break; + } + type_ = Type::Repost; + actor_dialog_id_ = owner_dialog_id; + date_ = date; + story_id_ = story_id; + break; + } + default: + UNREACHABLE(); + break; + } +} + +td_api::object_ptr StoryViewer::get_story_interaction_object(Td *td) const { + CHECK(is_valid()); + auto type = [&]() -> td_api::object_ptr { + switch (type_) { + case Type::View: + return td_api::make_object(reaction_type_.get_reaction_type_object()); + case Type::Forward: { + auto message_object = + td->messages_manager_->get_message_object(message_full_id_, "storyInteractionTypeForward"); + CHECK(message_object != nullptr); + return td_api::make_object(std::move(message_object)); + } + case Type::Repost: { + auto story_object = td->story_manager_->get_story_object({actor_dialog_id_, story_id_}); + CHECK(story_object != nullptr); + return td_api::make_object(std::move(story_object)); + } + default: + UNREACHABLE(); + return nullptr; + } + }(); + auto block_list_id = BlockListId(is_blocked_, is_blocked_for_stories_); + return td_api::make_object( + get_message_sender_object(td, actor_dialog_id_, "storyInteraction"), date_, block_list_id.get_block_list_object(), + std::move(type)); +} + +bool StoryViewer::is_valid() const { + return type_ != Type::None && actor_dialog_id_.is_valid() && date_ > 0; +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StoryViewer &viewer) { + return string_builder << '[' << viewer.actor_dialog_id_ << " with " << viewer.reaction_type_ << " at " << viewer.date_ + << ']'; +} + +StoryViewers::StoryViewers(Td *td, int32 total_count, int32 total_forward_count, int32 total_reaction_count, + vector> &&story_views, + string &&next_offset) + : total_count_(total_count) + , total_forward_count_(total_forward_count) + , total_reaction_count_(total_reaction_count) + , next_offset_(std::move(next_offset)) { + for (auto &story_view : story_views) { + StoryViewer story_viewer(td, std::move(story_view)); + if (!story_viewer.is_valid()) { + LOG(ERROR) << "Receive invalid story interaction"; + continue; + } + story_viewers_.push_back(std::move(story_viewer)); + } +} + +StoryViewers::StoryViewers(Td *td, int32 total_count, + vector> &&story_reactions, + string &&next_offset) + : total_count_(total_count), next_offset_(std::move(next_offset)) { + for (auto &story_reaction : story_reactions) { + StoryViewer story_viewer(td, std::move(story_reaction)); + if (!story_viewer.is_valid()) { + LOG(ERROR) << "Receive invalid story interaction"; + continue; + } + story_viewers_.push_back(std::move(story_viewer)); + } +} + +vector StoryViewers::get_viewer_user_ids() const { + vector result; + for (const auto &story_viewer : story_viewers_) { + auto user_id = story_viewer.get_viewer_user_id(); + if (user_id.is_valid()) { + result.push_back(user_id); + } + } + return result; +} + +vector StoryViewers::get_actor_dialog_ids() const { + return transform(story_viewers_, [](auto &viewer) { return viewer.get_actor_dialog_id(); }); +} + +td_api::object_ptr StoryViewers::get_story_interactions_object(Td *td) const { + return td_api::make_object( + total_count_, total_forward_count_, total_reaction_count_, + transform(story_viewers_, + [td](const StoryViewer &story_viewer) { return story_viewer.get_story_interaction_object(td); }), + next_offset_); +} + +StringBuilder &operator<<(StringBuilder &string_builder, const StoryViewers &viewers) { + return string_builder << viewers.story_viewers_; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/StoryViewer.h b/protocols/Telegram/tdlib/td/td/telegram/StoryViewer.h new file mode 100644 index 0000000000..ab88d7ef24 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/StoryViewer.h @@ -0,0 +1,84 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/ReactionType.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/StringBuilder.h" + +namespace td { + +class Td; + +class StoryViewer { + enum class Type : int32 { None, View, Forward, Repost }; + Type type_ = Type::None; + + DialogId actor_dialog_id_; + int32 date_ = 0; + bool is_blocked_ = false; + bool is_blocked_for_stories_ = false; + + ReactionType reaction_type_; // for View + MessageFullId message_full_id_; // for Forward + StoryId story_id_; // for Repost + + friend StringBuilder &operator<<(StringBuilder &string_builder, const StoryViewer &viewer); + + public: + StoryViewer(Td *td, telegram_api::object_ptr &&story_view_ptr); + + StoryViewer(Td *td, telegram_api::object_ptr &&story_reaction_ptr); + + UserId get_viewer_user_id() const { + return type_ == Type::View ? actor_dialog_id_.get_user_id() : UserId(); + } + + DialogId get_actor_dialog_id() const { + return actor_dialog_id_; + } + + bool is_valid() const; + + td_api::object_ptr get_story_interaction_object(Td *td) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const StoryViewer &viewer); + +class StoryViewers { + int32 total_count_ = 0; + int32 total_forward_count_ = 0; + int32 total_reaction_count_ = 0; + vector story_viewers_; + string next_offset_; + + friend StringBuilder &operator<<(StringBuilder &string_builder, const StoryViewers &viewers); + + public: + StoryViewers(Td *td, int32 total_count, int32 total_forward_count, int32 total_reaction_count, + vector> &&story_views, string &&next_offset); + + StoryViewers(Td *td, int32 total_count, + vector> &&story_reactions, string &&next_offset); + + vector get_viewer_user_ids() const; + + vector get_actor_dialog_ids() const; + + td_api::object_ptr get_story_interactions_object(Td *td) const; +}; + +StringBuilder &operator<<(StringBuilder &string_builder, const StoryViewers &viewers); + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.cpp b/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.cpp index dc35bd8564..9dd0a89b57 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,7 +8,7 @@ #include "td/telegram/ChannelId.h" #include "td/telegram/ConfigManager.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Global.h" #include "td/telegram/Td.h" @@ -42,6 +42,16 @@ SuggestedAction::SuggestedAction(Slice action_str) { init(Type::UpgradePremium); } else if (action_str == Slice("PREMIUM_ANNUAL")) { init(Type::SubscribeToAnnualPremium); + } else if (action_str == Slice("PREMIUM_RESTORE")) { + init(Type::RestorePremium); + } else if (action_str == Slice("PREMIUM_CHRISTMAS")) { + init(Type::GiftPremiumForChristmas); + } else if (action_str == Slice("BIRTHDAY_SETUP")) { + init(Type::BirthdaySetup); + } else if (action_str == Slice("PREMIUM_GRACE")) { + init(Type::PremiumGrace); + } else if (action_str == Slice("STARS_SUBSCRIPTION_LOW_BALANCE")) { + init(Type::StarsSubscriptionLowBalance); } } @@ -91,6 +101,21 @@ SuggestedAction::SuggestedAction(const td_api::object_ptr SuggestedAction::get_suggested_actio return td_api::make_object(); case Type::SubscribeToAnnualPremium: return td_api::make_object(); + case Type::RestorePremium: + return td_api::make_object(); + case Type::GiftPremiumForChristmas: + return td_api::make_object(); + case Type::BirthdaySetup: + return td_api::make_object(); + case Type::PremiumGrace: + return td_api::make_object( + G()->get_option_string("premium_manage_subscription_url", "https://t.me/premiumbot?start=status")); + case Type::StarsSubscriptionLowBalance: + return td_api::make_object(); default: UNREACHABLE(); return nullptr; @@ -155,11 +201,11 @@ td_api::object_ptr get_update_suggested_actions_ transform(removed_actions, get_object)); } -void update_suggested_actions(vector &suggested_actions, +bool update_suggested_actions(vector &suggested_actions, vector &&new_suggested_actions) { td::unique(new_suggested_actions); if (new_suggested_actions == suggested_actions) { - return; + return false; } vector added_actions; @@ -180,13 +226,16 @@ void update_suggested_actions(vector &suggested_actions, suggested_actions = std::move(new_suggested_actions); send_closure(G()->td(), &Td::send_update, get_update_suggested_actions_object(added_actions, removed_actions, "update_suggested_actions")); + return true; } -void remove_suggested_action(vector &suggested_actions, SuggestedAction suggested_action) { +bool remove_suggested_action(vector &suggested_actions, SuggestedAction suggested_action) { if (td::remove(suggested_actions, suggested_action)) { send_closure(G()->td(), &Td::send_update, get_update_suggested_actions_object({}, {suggested_action}, "remove_suggested_action")); + return true; } + return false; } void dismiss_suggested_action(SuggestedAction action, Promise &&promise) { @@ -199,10 +248,15 @@ void dismiss_suggested_action(SuggestedAction action, Promise &&promise) { case SuggestedAction::Type::ViewChecksHint: case SuggestedAction::Type::UpgradePremium: case SuggestedAction::Type::SubscribeToAnnualPremium: + case SuggestedAction::Type::RestorePremium: + case SuggestedAction::Type::GiftPremiumForChristmas: + case SuggestedAction::Type::BirthdaySetup: + case SuggestedAction::Type::PremiumGrace: + case SuggestedAction::Type::StarsSubscriptionLowBalance: return send_closure_later(G()->config_manager(), &ConfigManager::dismiss_suggested_action, std::move(action), std::move(promise)); case SuggestedAction::Type::ConvertToGigagroup: - return send_closure_later(G()->contacts_manager(), &ContactsManager::dismiss_dialog_suggested_action, + return send_closure_later(G()->dialog_manager(), &DialogManager::dismiss_dialog_suggested_action, std::move(action), std::move(promise)); case SuggestedAction::Type::SetPassword: { if (action.otherwise_relogin_days_ < 0) { diff --git a/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.h b/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.h index 7b61d45aba..ca4833c699 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.h +++ b/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -25,7 +25,12 @@ struct SuggestedAction { CheckPassword, SetPassword, UpgradePremium, - SubscribeToAnnualPremium + SubscribeToAnnualPremium, + RestorePremium, + GiftPremiumForChristmas, + BirthdaySetup, + PremiumGrace, + StarsSubscriptionLowBalance }; Type type_ = Type::Empty; DialogId dialog_id_; @@ -52,6 +57,12 @@ struct SuggestedAction { string get_suggested_action_str() const; td_api::object_ptr get_suggested_action_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); }; inline bool operator==(const SuggestedAction &lhs, const SuggestedAction &rhs) { @@ -71,10 +82,10 @@ inline bool operator<(const SuggestedAction &lhs, const SuggestedAction &rhs) { td_api::object_ptr get_update_suggested_actions_object( const vector &added_actions, const vector &removed_actions, const char *source); -void update_suggested_actions(vector &suggested_actions, +bool update_suggested_actions(vector &suggested_actions, vector &&new_suggested_actions); -void remove_suggested_action(vector &suggested_actions, SuggestedAction suggested_action); +bool remove_suggested_action(vector &suggested_actions, SuggestedAction suggested_action); void dismiss_suggested_action(SuggestedAction action, Promise &&promise); diff --git a/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.hpp b/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.hpp new file mode 100644 index 0000000000..a168227d5e --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SuggestedAction.hpp @@ -0,0 +1,50 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/SuggestedAction.h" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void SuggestedAction::store(StorerT &storer) const { + bool has_dialog_id = dialog_id_ != DialogId(); + bool has_otherwise_relogin_days = otherwise_relogin_days_ != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_dialog_id); + STORE_FLAG(has_otherwise_relogin_days); + END_STORE_FLAGS(); + td::store(type_, storer); + if (has_dialog_id) { + td::store(dialog_id_, storer); + } + if (has_otherwise_relogin_days) { + td::store(otherwise_relogin_days_, storer); + } +} + +template +void SuggestedAction::parse(ParserT &parser) { + bool has_dialog_id; + bool has_otherwise_relogin_days; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_dialog_id); + PARSE_FLAG(has_otherwise_relogin_days); + END_PARSE_FLAGS(); + td::parse(type_, parser); + if (has_dialog_id) { + td::parse(dialog_id_, parser); + } + if (has_otherwise_relogin_days) { + td::parse(otherwise_relogin_days_, parser); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Support.cpp b/protocols/Telegram/tdlib/td/td/telegram/Support.cpp index 191a10a635..95904baedd 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Support.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/Support.cpp @@ -1,17 +1,17 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/Support.h" -#include "td/telegram/ContactsManager.h" -#include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Global.h" #include "td/telegram/MessageEntity.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" #include "td/utils/buffer.h" #include "td/utils/Status.h" @@ -25,12 +25,12 @@ static td_api::object_ptr get_user_support_info_object( FormattedText message; if (user_info->get_id() == telegram_api::help_userInfo::ID) { auto info = telegram_api::move_object_as(user_info); - message = get_message_text(td->contacts_manager_.get(), std::move(info->message_), std::move(info->entities_), true, + message = get_message_text(td->user_manager_.get(), std::move(info->message_), std::move(info->entities_), true, true, info->date_, false, "get_user_support_info_object"); result->author_ = std::move(info->author_); result->date_ = info->date_; } - result->message_ = get_formatted_text_object(message, true, 0); + result->message_ = get_formatted_text_object(td->user_manager_.get(), message, true, 0); return result; } @@ -43,7 +43,7 @@ class GetUserInfoQuery final : public Td::ResultHandler { } void send(UserId user_id) { - auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + auto r_input_user = td_->user_manager_->get_input_user(user_id); if (r_input_user.is_error()) { return on_error(r_input_user.move_as_error()); } @@ -74,14 +74,14 @@ class EditUserInfoQuery final : public Td::ResultHandler { } void send(UserId user_id, FormattedText &&formatted_text) { - auto r_input_user = td_->contacts_manager_->get_input_user(user_id); + auto r_input_user = td_->user_manager_->get_input_user(user_id); if (r_input_user.is_error()) { return on_error(r_input_user.move_as_error()); } send_query(G()->net_query_creator().create(telegram_api::help_editUserInfo( r_input_user.move_as_ok(), formatted_text.text, - get_input_message_entities(td_->contacts_manager_.get(), &formatted_text, "EditUserInfoQuery")))); + get_input_message_entities(td_->user_manager_.get(), &formatted_text, "EditUserInfoQuery")))); } void on_result(BufferSlice packet) final { @@ -129,9 +129,9 @@ void get_user_info(Td *td, UserId user_id, Promise &&message, Promise> &&promise) { - TRY_RESULT_PROMISE(promise, formatted_text, - get_formatted_text(td, DialogId(td->contacts_manager_->get_my_id()), std::move(message), false, - true, true, false)); + TRY_RESULT_PROMISE( + promise, formatted_text, + get_formatted_text(td, td->dialog_manager_->get_my_dialog_id(), std::move(message), false, true, true, false)); td->create_handler(std::move(promise))->send(user_id, std::move(formatted_text)); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/SynchronousRequests.cpp b/protocols/Telegram/tdlib/td/td/telegram/SynchronousRequests.cpp new file mode 100644 index 0000000000..53a37996b7 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SynchronousRequests.cpp @@ -0,0 +1,400 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/SynchronousRequests.h" + +#include "td/telegram/CountryInfoManager.h" +#include "td/telegram/DialogFilter.h" +#include "td/telegram/JsonValue.h" +#include "td/telegram/LanguagePackManager.h" +#include "td/telegram/Logging.h" +#include "td/telegram/MessageEntity.h" +#include "td/telegram/MessageQuote.h" +#include "td/telegram/misc.h" +#include "td/telegram/NotificationManager.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/QuickReplyManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/td_api.hpp" +#include "td/telegram/ThemeManager.h" + +#include "td/utils/filesystem.h" +#include "td/utils/format.h" +#include "td/utils/logging.h" +#include "td/utils/MimeType.h" +#include "td/utils/PathView.h" +#include "td/utils/SliceBuilder.h" +#include "td/utils/Status.h" +#include "td/utils/utf8.h" + +#include + +namespace td { + +td_api::object_ptr SynchronousRequests::run_request(td_api::object_ptr &&function) { + if (function == nullptr) { + return td_api::make_object(400, "Request is empty"); + } + + auto function_id = function->get_id(); + bool need_logging = [function_id] { + switch (function_id) { + case td_api::parseTextEntities::ID: + case td_api::parseMarkdown::ID: + case td_api::getMarkdownText::ID: + case td_api::searchStringsByPrefix::ID: + case td_api::checkQuickReplyShortcutName::ID: + case td_api::getCountryFlagEmoji::ID: + case td_api::getFileMimeType::ID: + case td_api::getFileExtension::ID: + case td_api::cleanFileName::ID: + case td_api::getChatFolderDefaultIconName::ID: + case td_api::getJsonValue::ID: + case td_api::getJsonString::ID: + case td_api::getThemeParametersJsonString::ID: + case td_api::testReturnError::ID: + return true; + default: + return false; + } + }(); + + if (need_logging) { + VLOG(td_requests) << "Receive static request: " << to_string(function); + } + + td_api::object_ptr response; + downcast_call(*function, [&response](auto &request) { response = SynchronousRequests::do_request(request); }); + LOG_CHECK(response != nullptr) << function_id; + + if (need_logging) { + VLOG(td_requests) << "Sending result for static request: " << to_string(response); + } + return response; +} + +bool SynchronousRequests::is_synchronous_request(const td_api::Function *function) { + switch (function->get_id()) { + case td_api::searchQuote::ID: + case td_api::getTextEntities::ID: + case td_api::parseTextEntities::ID: + case td_api::parseMarkdown::ID: + case td_api::getMarkdownText::ID: + case td_api::searchStringsByPrefix::ID: + case td_api::checkQuickReplyShortcutName::ID: + case td_api::getCountryFlagEmoji::ID: + case td_api::getFileMimeType::ID: + case td_api::getFileExtension::ID: + case td_api::cleanFileName::ID: + case td_api::getLanguagePackString::ID: + case td_api::getPhoneNumberInfoSync::ID: + case td_api::getChatFolderDefaultIconName::ID: + case td_api::getJsonValue::ID: + case td_api::getJsonString::ID: + case td_api::getThemeParametersJsonString::ID: + case td_api::getPushReceiverId::ID: + case td_api::setLogStream::ID: + case td_api::getLogStream::ID: + case td_api::setLogVerbosityLevel::ID: + case td_api::getLogVerbosityLevel::ID: + case td_api::getLogTags::ID: + case td_api::setLogTagVerbosityLevel::ID: + case td_api::getLogTagVerbosityLevel::ID: + case td_api::addLogMessage::ID: + case td_api::testReturnError::ID: + return true; + case td_api::getOption::ID: + return OptionManager::is_synchronous_option(static_cast(function)->name_); + default: + return false; + } +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::searchQuote &request) { + if (request.text_ == nullptr || request.quote_ == nullptr) { + return make_error(400, "Text and quote must be non-empty"); + } + if (!check_utf8(request.text_->text_) || !check_utf8(request.quote_->text_)) { + return make_error(400, "Strings must be encoded in UTF-8"); + } + auto r_text_entities = get_message_entities(nullptr, std::move(request.text_->entities_), false); + if (r_text_entities.is_error()) { + return make_error(400, r_text_entities.error().message()); + } + auto r_quote_entities = get_message_entities(nullptr, std::move(request.quote_->entities_), false); + if (r_quote_entities.is_error()) { + return make_error(400, r_quote_entities.error().message()); + } + auto position = MessageQuote::search_quote({std::move(request.text_->text_), r_text_entities.move_as_ok()}, + {std::move(request.quote_->text_), r_quote_entities.move_as_ok()}, + request.quote_position_); + if (position == -1) { + return make_error(404, "Not Found"); + } + return td_api::make_object(position); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getTextEntities &request) { + if (!check_utf8(request.text_)) { + return make_error(400, "Text must be encoded in UTF-8"); + } + auto text_entities = find_entities(request.text_, false, false); + return td_api::make_object( + get_text_entities_object(nullptr, text_entities, false, std::numeric_limits::max())); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::parseTextEntities &request) { + if (!check_utf8(request.text_)) { // must not use clean_input_string, because \r may be used as a separator + return make_error(400, "Text must be encoded in UTF-8"); + } + if (request.parse_mode_ == nullptr) { + return make_error(400, "Parse mode must be non-empty"); + } + + auto r_entities = [&]() -> Result> { + if (utf8_length(request.text_) > 65536) { + return Status::Error("Text is too long"); + } + switch (request.parse_mode_->get_id()) { + case td_api::textParseModeHTML::ID: + return parse_html(request.text_); + case td_api::textParseModeMarkdown::ID: { + auto version = static_cast(request.parse_mode_.get())->version_; + if (version == 0 || version == 1) { + return parse_markdown(request.text_); + } + if (version == 2) { + return parse_markdown_v2(request.text_); + } + return Status::Error("Wrong Markdown version specified"); + } + default: + UNREACHABLE(); + return Status::Error(500, "Unknown parse mode"); + } + }(); + if (r_entities.is_error()) { + return make_error(400, PSLICE() << "Can't parse entities: " << r_entities.error().message()); + } + + return td_api::make_object(std::move(request.text_), + get_text_entities_object(nullptr, r_entities.ok(), false, -1)); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::parseMarkdown &request) { + if (request.text_ == nullptr) { + return make_error(400, "Text must be non-empty"); + } + + auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_), true); + if (r_entities.is_error()) { + return make_error(400, r_entities.error().message()); + } + auto entities = r_entities.move_as_ok(); + auto status = fix_formatted_text(request.text_->text_, entities, true, true, true, true, true); + if (status.is_error()) { + return make_error(400, status.message()); + } + + auto parsed_text = parse_markdown_v3({std::move(request.text_->text_), std::move(entities)}); + fix_formatted_text(parsed_text.text, parsed_text.entities, true, true, true, true, true).ensure(); + return get_formatted_text_object(nullptr, parsed_text, false, std::numeric_limits::max()); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getOption &request) { + if (!is_synchronous_request(&request)) { + return make_error(400, "The option can't be get synchronously"); + } + return OptionManager::get_option_synchronously(request.name_); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::getMarkdownText &request) { + if (request.text_ == nullptr) { + return make_error(400, "Text must be non-empty"); + } + + auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_)); + if (r_entities.is_error()) { + return make_error(400, r_entities.error().message()); + } + auto entities = r_entities.move_as_ok(); + auto status = fix_formatted_text(request.text_->text_, entities, true, true, true, true, true); + if (status.is_error()) { + return make_error(400, status.message()); + } + + return get_formatted_text_object(nullptr, get_markdown_v3({std::move(request.text_->text_), std::move(entities)}), + false, std::numeric_limits::max()); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::searchStringsByPrefix &request) { + if (!clean_input_string(request.query_)) { + return make_error(400, "Strings must be encoded in UTF-8"); + } + for (auto &str : request.strings_) { + if (!clean_input_string(str)) { + return make_error(400, "Strings must be encoded in UTF-8"); + } + } + int32 total_count = 0; + auto result = search_strings_by_prefix(std::move(request.strings_), std::move(request.query_), request.limit_, + !request.return_none_for_empty_query_, total_count); + return td_api::make_object(total_count, std::move(result)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::checkQuickReplyShortcutName &request) { + // don't check name UTF-8 correctness + auto status = QuickReplyManager::check_shortcut_name(request.name_); + if (status.is_ok()) { + return td_api::make_object(); + } + return make_error(200, status.message()); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getCountryFlagEmoji &request) { + // don't check country code UTF-8 correctness + return td_api::make_object(CountryInfoManager::get_country_flag_emoji(request.country_code_)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getFileMimeType &request) { + // don't check file name UTF-8 correctness + return td_api::make_object(MimeType::from_extension(PathView(request.file_name_).extension())); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getFileExtension &request) { + // don't check MIME type UTF-8 correctness + return td_api::make_object(MimeType::to_extension(request.mime_type_)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::cleanFileName &request) { + // don't check file name UTF-8 correctness + return td_api::make_object(clean_filename(request.file_name_)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLanguagePackString &request) { + return LanguagePackManager::get_language_pack_string( + request.language_pack_database_path_, request.localization_target_, request.language_pack_id_, request.key_); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::getPhoneNumberInfoSync &request) { + // don't check language_code/phone number UTF-8 correctness + return CountryInfoManager::get_phone_number_info_sync(request.language_code_, + std::move(request.phone_number_prefix_)); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getPushReceiverId &request) { + // don't check push payload UTF-8 correctness + auto r_push_receiver_id = NotificationManager::get_push_receiver_id(request.payload_); + if (r_push_receiver_id.is_error()) { + VLOG(notifications) << "Failed to get push notification receiver from \"" << format::escaped(request.payload_) + << '"'; + return make_error(r_push_receiver_id.error().code(), r_push_receiver_id.error().message()); + } + return td_api::make_object(r_push_receiver_id.ok()); +} + +td_api::object_ptr SynchronousRequests::do_request( + const td_api::getChatFolderDefaultIconName &request) { + if (request.folder_ == nullptr) { + return make_error(400, "Chat folder must be non-empty"); + } + if (!check_utf8(request.folder_->title_)) { + return make_error(400, "Chat folder title must be encoded in UTF-8"); + } + if (request.folder_->icon_ != nullptr && !check_utf8(request.folder_->icon_->name_)) { + return make_error(400, "Chat folder icon name must be encoded in UTF-8"); + } + return td_api::make_object(DialogFilter::get_default_icon_name(request.folder_.get())); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::getJsonValue &request) { + if (!check_utf8(request.json_)) { + return make_error(400, "JSON has invalid encoding"); + } + auto result = get_json_value(request.json_); + if (result.is_error()) { + return make_error(400, result.error().message()); + } else { + return result.move_as_ok(); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getJsonString &request) { + return td_api::make_object(get_json_string(request.json_value_.get())); +} + +td_api::object_ptr SynchronousRequests::do_request( + const td_api::getThemeParametersJsonString &request) { + return td_api::make_object(ThemeManager::get_theme_parameters_json_string(request.theme_)); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::setLogStream &request) { + auto result = Logging::set_current_stream(std::move(request.log_stream_)); + if (result.is_ok()) { + return td_api::make_object(); + } else { + return make_error(400, result.message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLogStream &request) { + auto result = Logging::get_current_stream(); + if (result.is_ok()) { + return result.move_as_ok(); + } else { + return make_error(400, result.error().message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::setLogVerbosityLevel &request) { + auto result = Logging::set_verbosity_level(static_cast(request.new_verbosity_level_)); + if (result.is_ok()) { + return td_api::make_object(); + } else { + return make_error(400, result.message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLogVerbosityLevel &request) { + return td_api::make_object(Logging::get_verbosity_level()); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLogTags &request) { + return td_api::make_object(Logging::get_tags()); +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::setLogTagVerbosityLevel &request) { + auto result = Logging::set_tag_verbosity_level(request.tag_, static_cast(request.new_verbosity_level_)); + if (result.is_ok()) { + return td_api::make_object(); + } else { + return make_error(400, result.message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::getLogTagVerbosityLevel &request) { + auto result = Logging::get_tag_verbosity_level(request.tag_); + if (result.is_ok()) { + return td_api::make_object(result.ok()); + } else { + return make_error(400, result.error().message()); + } +} + +td_api::object_ptr SynchronousRequests::do_request(const td_api::addLogMessage &request) { + Logging::add_message(request.verbosity_level_, request.text_); + return td_api::make_object(); +} + +td_api::object_ptr SynchronousRequests::do_request(td_api::testReturnError &request) { + if (request.error_ == nullptr) { + return td_api::make_object(404, "Not Found"); + } + + return std::move(request.error_); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/SynchronousRequests.h b/protocols/Telegram/tdlib/td/td/telegram/SynchronousRequests.h new file mode 100644 index 0000000000..472c23d992 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/SynchronousRequests.h @@ -0,0 +1,89 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" + +#include "td/utils/common.h" +#include "td/utils/Slice.h" + +namespace td { + +class SynchronousRequests { + public: + static td_api::object_ptr run_request(td_api::object_ptr &&function); + + static bool is_synchronous_request(const td_api::Function *function); + + private: + static td_api::object_ptr make_error(int32 code, Slice error) { + return td_api::make_object(code, error.str()); + } + + template + static td_api::object_ptr do_request(const T &request) { + return td_api::make_object(400, "The method can't be executed synchronously"); + } + + static td_api::object_ptr do_request(const td_api::getOption &request); + + static td_api::object_ptr do_request(td_api::searchQuote &request); + + static td_api::object_ptr do_request(const td_api::getTextEntities &request); + + static td_api::object_ptr do_request(td_api::parseTextEntities &request); + + static td_api::object_ptr do_request(td_api::parseMarkdown &request); + + static td_api::object_ptr do_request(td_api::getMarkdownText &request); + + static td_api::object_ptr do_request(td_api::searchStringsByPrefix &request); + + static td_api::object_ptr do_request(const td_api::checkQuickReplyShortcutName &request); + + static td_api::object_ptr do_request(const td_api::getCountryFlagEmoji &request); + + static td_api::object_ptr do_request(const td_api::getFileMimeType &request); + + static td_api::object_ptr do_request(const td_api::getFileExtension &request); + + static td_api::object_ptr do_request(const td_api::cleanFileName &request); + + static td_api::object_ptr do_request(const td_api::getLanguagePackString &request); + + static td_api::object_ptr do_request(td_api::getPhoneNumberInfoSync &request); + + static td_api::object_ptr do_request(const td_api::getPushReceiverId &request); + + static td_api::object_ptr do_request(const td_api::getChatFolderDefaultIconName &request); + + static td_api::object_ptr do_request(td_api::getJsonValue &request); + + static td_api::object_ptr do_request(const td_api::getJsonString &request); + + static td_api::object_ptr do_request(const td_api::getThemeParametersJsonString &request); + + static td_api::object_ptr do_request(td_api::setLogStream &request); + + static td_api::object_ptr do_request(const td_api::getLogStream &request); + + static td_api::object_ptr do_request(const td_api::setLogVerbosityLevel &request); + + static td_api::object_ptr do_request(const td_api::getLogVerbosityLevel &request); + + static td_api::object_ptr do_request(const td_api::getLogTags &request); + + static td_api::object_ptr do_request(const td_api::setLogTagVerbosityLevel &request); + + static td_api::object_ptr do_request(const td_api::getLogTagVerbosityLevel &request); + + static td_api::object_ptr do_request(const td_api::addLogMessage &request); + + static td_api::object_ptr do_request(td_api::testReturnError &request); +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Td.cpp b/protocols/Telegram/tdlib/td/td/telegram/Td.cpp index 7b42c7be6c..b3b993116b 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Td.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/Td.cpp @@ -1,176 +1,111 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/Td.h" -#include "td/telegram/Account.h" +#include "td/telegram/AccountManager.h" +#include "td/telegram/AlarmManager.h" #include "td/telegram/AnimationsManager.h" #include "td/telegram/Application.h" #include "td/telegram/AttachMenuManager.h" #include "td/telegram/AudiosManager.h" #include "td/telegram/AuthManager.h" -#include "td/telegram/AutoDownloadSettings.h" #include "td/telegram/AutosaveManager.h" -#include "td/telegram/BackgroundId.h" #include "td/telegram/BackgroundManager.h" -#include "td/telegram/BackgroundType.h" -#include "td/telegram/BotCommand.h" +#include "td/telegram/BoostManager.h" #include "td/telegram/BotInfoManager.h" -#include "td/telegram/BotMenuButton.h" +#include "td/telegram/BusinessConnectionManager.h" +#include "td/telegram/BusinessManager.h" #include "td/telegram/CallbackQueriesManager.h" -#include "td/telegram/CallId.h" #include "td/telegram/CallManager.h" -#include "td/telegram/ChannelId.h" -#include "td/telegram/ChannelType.h" -#include "td/telegram/ChatId.h" +#include "td/telegram/ChannelRecommendationManager.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/CommonDialogManager.h" #include "td/telegram/ConfigManager.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ConnectionStateManager.h" #include "td/telegram/CountryInfoManager.h" -#include "td/telegram/CustomEmojiId.h" #include "td/telegram/DeviceTokenManager.h" -#include "td/telegram/DialogAction.h" -#include "td/telegram/DialogEventLog.h" -#include "td/telegram/DialogFilter.h" -#include "td/telegram/DialogFilterId.h" +#include "td/telegram/DialogActionManager.h" #include "td/telegram/DialogFilterManager.h" -#include "td/telegram/DialogId.h" -#include "td/telegram/DialogListId.h" -#include "td/telegram/DialogLocation.h" -#include "td/telegram/DialogParticipant.h" -#include "td/telegram/DialogParticipantFilter.h" -#include "td/telegram/DialogSource.h" +#include "td/telegram/DialogInviteLinkManager.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/DialogParticipantManager.h" #include "td/telegram/DocumentsManager.h" #include "td/telegram/DownloadManager.h" #include "td/telegram/DownloadManagerCallback.h" -#include "td/telegram/EmailVerification.h" -#include "td/telegram/EmojiGroupType.h" -#include "td/telegram/EmojiStatus.h" #include "td/telegram/FileReferenceManager.h" -#include "td/telegram/files/FileGcParameters.h" -#include "td/telegram/files/FileId.h" #include "td/telegram/files/FileManager.h" #include "td/telegram/files/FileSourceId.h" -#include "td/telegram/files/FileStats.h" -#include "td/telegram/files/FileType.h" -#include "td/telegram/FolderId.h" #include "td/telegram/ForumTopicManager.h" -#include "td/telegram/FullMessageId.h" #include "td/telegram/GameManager.h" #include "td/telegram/Global.h" -#include "td/telegram/GroupCallId.h" #include "td/telegram/GroupCallManager.h" #include "td/telegram/HashtagHints.h" +#include "td/telegram/InlineMessageManager.h" #include "td/telegram/InlineQueriesManager.h" -#include "td/telegram/JsonValue.h" #include "td/telegram/LanguagePackManager.h" #include "td/telegram/LinkManager.h" -#include "td/telegram/Location.h" -#include "td/telegram/Logging.h" -#include "td/telegram/MessageCopyOptions.h" -#include "td/telegram/MessageEntity.h" -#include "td/telegram/MessageId.h" -#include "td/telegram/MessageLinkInfo.h" -#include "td/telegram/MessageReaction.h" -#include "td/telegram/MessageSearchFilter.h" -#include "td/telegram/MessageSender.h" +#include "td/telegram/MessageImportManager.h" #include "td/telegram/MessagesManager.h" -#include "td/telegram/MessageSource.h" -#include "td/telegram/MessageThreadInfo.h" -#include "td/telegram/MessageTtl.h" #include "td/telegram/misc.h" #include "td/telegram/net/ConnectionCreator.h" -#include "td/telegram/net/DcId.h" #include "td/telegram/net/MtprotoHeader.h" #include "td/telegram/net/NetQuery.h" -#include "td/telegram/net/NetQueryDelayer.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/net/NetStatsManager.h" -#include "td/telegram/net/NetType.h" #include "td/telegram/net/Proxy.h" -#include "td/telegram/net/PublicRsaKeyShared.h" #include "td/telegram/net/TempAuthKeyWatchdog.h" -#include "td/telegram/NotificationGroupId.h" -#include "td/telegram/NotificationId.h" #include "td/telegram/NotificationManager.h" #include "td/telegram/NotificationSettingsManager.h" -#include "td/telegram/NotificationSettingsScope.h" +#include "td/telegram/OnlineManager.h" #include "td/telegram/OptionManager.h" #include "td/telegram/PasswordManager.h" -#include "td/telegram/Payments.h" +#include "td/telegram/PeopleNearbyManager.h" #include "td/telegram/PhoneNumberManager.h" #include "td/telegram/PhotoSizeSource.h" #include "td/telegram/PollManager.h" -#include "td/telegram/Premium.h" #include "td/telegram/PrivacyManager.h" -#include "td/telegram/PublicDialogType.h" -#include "td/telegram/ReportReason.h" +#include "td/telegram/PromoDataManager.h" +#include "td/telegram/QuickReplyManager.h" +#include "td/telegram/ReactionManager.h" #include "td/telegram/RequestActor.h" -#include "td/telegram/ScopeNotificationSettings.h" -#include "td/telegram/SecretChatId.h" +#include "td/telegram/Requests.h" +#include "td/telegram/SavedMessagesManager.h" #include "td/telegram/SecretChatsManager.h" #include "td/telegram/SecureManager.h" -#include "td/telegram/SecureValue.h" -#include "td/telegram/SentEmailCode.h" #include "td/telegram/SponsoredMessageManager.h" +#include "td/telegram/StarManager.h" #include "td/telegram/StateManager.h" -#include "td/telegram/StickerFormat.h" -#include "td/telegram/StickerSetId.h" +#include "td/telegram/StatisticsManager.h" #include "td/telegram/StickersManager.h" -#include "td/telegram/StickerType.h" #include "td/telegram/StorageManager.h" -#include "td/telegram/SuggestedAction.h" -#include "td/telegram/Support.h" -#include "td/telegram/td_api.hpp" +#include "td/telegram/StoryManager.h" +#include "td/telegram/SynchronousRequests.h" #include "td/telegram/TdDb.h" -#include "td/telegram/telegram_api.hpp" +#include "td/telegram/TermsOfServiceManager.h" #include "td/telegram/ThemeManager.h" -#include "td/telegram/TopDialogCategory.h" +#include "td/telegram/TimeZoneManager.h" #include "td/telegram/TopDialogManager.h" +#include "td/telegram/TranscriptionManager.h" #include "td/telegram/TranslationManager.h" #include "td/telegram/UpdatesManager.h" -#include "td/telegram/UserId.h" +#include "td/telegram/UserManager.h" #include "td/telegram/Version.h" #include "td/telegram/VideoNotesManager.h" #include "td/telegram/VideosManager.h" #include "td/telegram/VoiceNotesManager.h" -#include "td/telegram/WebPageId.h" #include "td/telegram/WebPagesManager.h" #include "td/db/binlog/BinlogEvent.h" -#include "td/mtproto/DhCallback.h" -#include "td/mtproto/Handshake.h" -#include "td/mtproto/HandshakeActor.h" -#include "td/mtproto/RawConnection.h" -#include "td/mtproto/RSA.h" -#include "td/mtproto/TransportType.h" - #include "td/actor/actor.h" -#include "td/utils/algorithm.h" -#include "td/utils/buffer.h" -#include "td/utils/filesystem.h" -#include "td/utils/format.h" -#include "td/utils/MimeType.h" #include "td/utils/misc.h" -#include "td/utils/PathView.h" -#include "td/utils/port/IPAddress.h" -#include "td/utils/port/SocketFd.h" #include "td/utils/port/uname.h" -#include "td/utils/Random.h" -#include "td/utils/Slice.h" -#include "td/utils/SliceBuilder.h" -#include "td/utils/Status.h" #include "td/utils/Timer.h" -#include "td/utils/tl_parsers.h" -#include "td/utils/utf8.h" - -#include -#include -#include namespace td { @@ -190,8786 +125,1297 @@ void Td::ResultHandler::send_query(NetQueryPtr query) { G()->net_query_dispatcher().dispatch(std::move(query)); } -class GetPromoDataQuery final : public Td::ResultHandler { - Promise> promise_; +Td::Td(unique_ptr callback, Options options) + : callback_(std::move(callback)), td_options_(std::move(options)) { + CHECK(callback_ != nullptr); + LOG(INFO) << "Create Td with layer " << MTPROTO_LAYER << ", database version " << current_db_version() + << " and version " << static_cast(Version::Next) - 1 << " on " + << Scheduler::instance()->sched_count() << " threads"; +} + +Td::~Td() = default; + +bool Td::ignore_background_updates() const { + return can_ignore_background_updates_ && option_manager_->get_option_boolean("ignore_background_updates"); +} - public: - explicit GetPromoDataQuery(Promise> &&promise) - : promise_(std::move(promise)) { +bool Td::is_authentication_request(int32 id) { + switch (id) { + case td_api::setTdlibParameters::ID: + case td_api::getAuthorizationState::ID: + case td_api::setAuthenticationPhoneNumber::ID: + case td_api::sendAuthenticationFirebaseSms::ID: + case td_api::reportAuthenticationCodeMissing::ID: + case td_api::setAuthenticationEmailAddress::ID: + case td_api::resendAuthenticationCode::ID: + case td_api::checkAuthenticationEmailCode::ID: + case td_api::checkAuthenticationCode::ID: + case td_api::registerUser::ID: + case td_api::requestQrCodeAuthentication::ID: + case td_api::resetAuthenticationEmailAddress::ID: + case td_api::checkAuthenticationPassword::ID: + case td_api::requestAuthenticationPasswordRecovery::ID: + case td_api::checkAuthenticationPasswordRecoveryCode::ID: + case td_api::recoverAuthenticationPassword::ID: + case td_api::deleteAccount::ID: + case td_api::logOut::ID: + case td_api::close::ID: + case td_api::destroy::ID: + case td_api::checkAuthenticationBotToken::ID: + return true; + default: + return false; } +} - void send() { - // we don't poll promo data before authorization - send_query(G()->net_query_creator().create(telegram_api::help_getPromoData())); +bool Td::is_preinitialization_request(int32 id) { + switch (id) { + case td_api::getCurrentState::ID: + case td_api::setAlarm::ID: + case td_api::testUseUpdate::ID: + case td_api::testCallEmpty::ID: + case td_api::testSquareInt::ID: + case td_api::testCallString::ID: + case td_api::testCallBytes::ID: + case td_api::testCallVectorInt::ID: + case td_api::testCallVectorIntObject::ID: + case td_api::testCallVectorString::ID: + case td_api::testCallVectorStringObject::ID: + case td_api::testProxy::ID: + return true; + default: + return false; } +} - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } +bool Td::is_preauthentication_request(int32 id) { + switch (id) { + case td_api::getInternalLink::ID: + case td_api::getInternalLinkType::ID: + case td_api::getLocalizationTargetInfo::ID: + case td_api::getLanguagePackInfo::ID: + case td_api::getLanguagePackStrings::ID: + case td_api::synchronizeLanguagePack::ID: + case td_api::addCustomServerLanguagePack::ID: + case td_api::setCustomLanguagePack::ID: + case td_api::editCustomLanguagePackInfo::ID: + case td_api::setCustomLanguagePackString::ID: + case td_api::deleteLanguagePack::ID: + case td_api::processPushNotification::ID: + case td_api::getOption::ID: + case td_api::setOption::ID: + case td_api::getStorageStatistics::ID: + case td_api::getStorageStatisticsFast::ID: + case td_api::getDatabaseStatistics::ID: + case td_api::setNetworkType::ID: + case td_api::getNetworkStatistics::ID: + case td_api::addNetworkStatistics::ID: + case td_api::resetNetworkStatistics::ID: + case td_api::setApplicationVerificationToken::ID: + case td_api::getCountries::ID: + case td_api::getCountryCode::ID: + case td_api::getPhoneNumberInfo::ID: + case td_api::getDeepLinkInfo::ID: + case td_api::getApplicationConfig::ID: + case td_api::saveApplicationLogEvent::ID: + case td_api::addProxy::ID: + case td_api::editProxy::ID: + case td_api::enableProxy::ID: + case td_api::disableProxy::ID: + case td_api::removeProxy::ID: + case td_api::getProxies::ID: + case td_api::getProxyLink::ID: + case td_api::pingProxy::ID: + case td_api::testNetwork::ID: + return true; + default: + return false; + } +} - promise_.set_value(result_ptr.move_as_ok()); +td_api::object_ptr Td::get_fake_authorization_state_object() const { + switch (state_) { + case State::WaitParameters: + return td_api::make_object(); + case State::Run: + UNREACHABLE(); + return nullptr; + case State::Close: + if (close_flag_ == 5) { + return td_api::make_object(); + } else { + return td_api::make_object(); + } + default: + UNREACHABLE(); + return nullptr; } +} + +vector> Td::get_fake_current_state() const { + CHECK(state_ != State::Run); + vector> updates; + OptionManager::get_common_state(updates); + updates.push_back(td_api::make_object(get_fake_authorization_state_object())); + return updates; +} - void on_error(Status status) final { - promise_.set_error(std::move(status)); +void Td::request(uint64 id, tl_object_ptr function) { + if (id == 0) { + LOG(ERROR) << "Ignore request with ID == 0: " << to_string(function); + return; } -}; -class GetRecentMeUrlsQuery final : public Td::ResultHandler { - Promise> promise_; + if (function == nullptr) { + return callback_->on_error(id, make_error(400, "Request is empty")); + } - public: - explicit GetRecentMeUrlsQuery(Promise> &&promise) : promise_(std::move(promise)) { + VLOG(td_requests) << "Receive request " << id << ": " << to_string(function); + request_set_.emplace(id, function->get_id()); + if (SynchronousRequests::is_synchronous_request(function.get())) { + // send response synchronously + return send_result(id, static_request(std::move(function))); } - void send(const string &referrer) { - send_query(G()->net_query_creator().create(telegram_api::help_getRecentMeUrls(referrer))); + run_request(id, std::move(function)); +} + +void Td::run_request(uint64 id, td_api::object_ptr function) { + if (set_parameters_request_id_ > 0) { + pending_set_parameters_requests_.emplace_back(id, std::move(function)); + return; } - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); + int32 function_id = function->get_id(); + if (state_ != State::Run) { + switch (function_id) { + case td_api::getAuthorizationState::ID: + // send response synchronously to prevent "Request aborted" + return send_result(id, get_fake_authorization_state_object()); + case td_api::getCurrentState::ID: + // send response synchronously to prevent "Request aborted" + return send_result(id, td_api::make_object(get_fake_current_state())); + case td_api::close::ID: + // need to send response before actual closing + send_closure(actor_id(this), &Td::send_result, id, td_api::make_object()); + send_closure(actor_id(this), &Td::close); + return; + default: + break; } - - auto urls_full = result_ptr.move_as_ok(); - td_->contacts_manager_->on_get_users(std::move(urls_full->users_), "GetRecentMeUrlsQuery"); - td_->contacts_manager_->on_get_chats(std::move(urls_full->chats_), "GetRecentMeUrlsQuery"); - - auto urls = std::move(urls_full->urls_); - auto results = make_tl_object(); - results->urls_.reserve(urls.size()); - for (auto &url_ptr : urls) { - CHECK(url_ptr != nullptr); - tl_object_ptr result = make_tl_object(); - switch (url_ptr->get_id()) { - case telegram_api::recentMeUrlUser::ID: { - auto url = move_tl_object_as(url_ptr); - result->url_ = std::move(url->url_); - UserId user_id(url->user_id_); - if (!user_id.is_valid()) { - LOG(ERROR) << "Receive invalid " << user_id; - result = nullptr; - break; - } - result->type_ = make_tl_object( - td_->contacts_manager_->get_user_id_object(user_id, "tMeUrlTypeUser")); - break; - } - case telegram_api::recentMeUrlChat::ID: { - auto url = move_tl_object_as(url_ptr); - result->url_ = std::move(url->url_); - ChannelId channel_id(url->chat_id_); - if (!channel_id.is_valid()) { - LOG(ERROR) << "Receive invalid " << channel_id; - result = nullptr; - break; + } + switch (state_) { + case State::WaitParameters: { + switch (function_id) { + case td_api::setTdlibParameters::ID: { + auto r_parameters = get_parameters(move_tl_object_as(function)); + if (r_parameters.is_error()) { + return send_closure(actor_id(this), &Td::send_error, id, r_parameters.move_as_error()); } - result->type_ = make_tl_object( - td_->contacts_manager_->get_supergroup_id_object(channel_id, "tMeUrlTypeSupergroup")); - break; + auto parameters = r_parameters.move_as_ok(); + + VLOG(td_init) << "Begin to open database"; + set_parameters_request_id_ = id; + can_ignore_background_updates_ = !parameters.second.use_chat_info_database_ && + !parameters.second.use_message_database_ && + !parameters.first.use_secret_chats_; + + auto promise = PromiseCreator::lambda( + [actor_id = actor_id(this), parameters = std::move(parameters.first), + parent = create_reference()](Result r_opened_database) mutable { + send_closure(actor_id, &Td::init, std::move(parameters), std::move(r_opened_database)); + }); + auto use_sqlite_pmc = parameters.second.use_message_database_ || parameters.second.use_chat_info_database_ || + parameters.second.use_file_database_; + return TdDb::open(use_sqlite_pmc ? G()->get_database_scheduler_id() : G()->get_slow_net_scheduler_id(), + std::move(parameters.second), std::move(promise)); } - case telegram_api::recentMeUrlChatInvite::ID: { - auto url = move_tl_object_as(url_ptr); - result->url_ = std::move(url->url_); - td_->contacts_manager_->on_get_dialog_invite_link_info(result->url_, std::move(url->chat_invite_), - Promise()); - auto info_object = td_->contacts_manager_->get_chat_invite_link_info_object(result->url_); - if (info_object == nullptr) { - result = nullptr; - break; + default: + if (is_preinitialization_request(function_id)) { + return requests_->run_request(id, std::move(function)); } - result->type_ = make_tl_object(std::move(info_object)); - break; - } - case telegram_api::recentMeUrlStickerSet::ID: { - auto url = move_tl_object_as(url_ptr); - result->url_ = std::move(url->url_); - auto sticker_set_id = - td_->stickers_manager_->on_get_sticker_set_covered(std::move(url->set_), false, "recentMeUrlStickerSet"); - if (!sticker_set_id.is_valid()) { - LOG(ERROR) << "Receive invalid sticker set"; - result = nullptr; - break; + if (is_preauthentication_request(function_id)) { + pending_preauthentication_requests_.emplace_back(id, std::move(function)); + return; } - result->type_ = make_tl_object(sticker_set_id.get()); - break; - } - case telegram_api::recentMeUrlUnknown::ID: - // skip - result = nullptr; - break; - default: - UNREACHABLE(); - } - if (result != nullptr) { - results->urls_.push_back(std::move(result)); + return send_error_impl( + id, make_error(400, "Initialization parameters are needed: call setTdlibParameters first")); } + UNREACHABLE(); } - promise_.set_value(std::move(results)); + case State::Close: + return send_error_impl(id, make_error(destroy_flag_ ? 401 : 500, + destroy_flag_ ? CSlice("Unauthorized") : CSlice("Request aborted"))); + case State::Run: + if (!auth_manager_->is_authorized() && !is_preauthentication_request(function_id) && + !is_preinitialization_request(function_id) && !is_authentication_request(function_id)) { + return send_error_impl(id, make_error(401, "Unauthorized")); + } + return requests_->run_request(id, std::move(function)); + default: + UNREACHABLE(); } +} - void on_error(Status status) final { - promise_.set_error(std::move(status)); - } -}; +td_api::object_ptr Td::static_request(td_api::object_ptr function) { + return SynchronousRequests::run_request(std::move(function)); +} -class SendCustomRequestQuery final : public Td::ResultHandler { - Promise> promise_; +void Td::add_handler(uint64 id, std::shared_ptr handler) { + result_handlers_[id] = std::move(handler); +} - public: - explicit SendCustomRequestQuery(Promise> &&promise) - : promise_(std::move(promise)) { +std::shared_ptr Td::extract_handler(uint64 id) { + auto it = result_handlers_.find(id); + if (it == result_handlers_.end()) { + return nullptr; } + auto result = std::move(it->second); + result_handlers_.erase(it); + return result; +} - void send(const string &method, const string ¶meters) { - send_query(G()->net_query_creator().create( - telegram_api::bots_sendCustomRequest(method, make_tl_object(parameters)))); +void Td::on_update(telegram_api::object_ptr updates, uint64 auth_key_id) { + if (close_flag_ > 1) { + return; } - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); + if (updates == nullptr) { + if (auth_manager_->is_bot()) { + G()->net_query_dispatcher().update_mtproto_header(); + } else { + // this could be a min-channel update + updates_manager_->schedule_get_difference("failed to fetch updates"); + } + } else { + updates_manager_->on_update_from_auth_key_id(auth_key_id); + updates_manager_->on_get_updates(std::move(updates), Promise()); + if (auth_manager_->is_bot() && auth_manager_->is_authorized()) { + online_manager_->set_is_bot_online(true); } - - auto result = result_ptr.move_as_ok(); - promise_.set_value(td_api::make_object(result->data_)); - } - - void on_error(Status status) final { - promise_.set_error(std::move(status)); - } -}; - -class AnswerCustomQueryQuery final : public Td::ResultHandler { - Promise promise_; - - public: - explicit AnswerCustomQueryQuery(Promise &&promise) : promise_(std::move(promise)) { } +} - void send(int64 custom_query_id, const string &data) { - send_query(G()->net_query_creator().create( - telegram_api::bots_answerWebhookJSONQuery(custom_query_id, make_tl_object(data)))); +void Td::on_result(NetQueryPtr query) { + query->debug("Td: received from DcManager"); + VLOG(net_query) << "Receive result of " << query; + if (close_flag_ > 1) { + return; } - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); + auto handler = extract_handler(query->id()); + if (handler != nullptr) { + CHECK(query->is_ready()); + if (query->is_ok()) { + handler->on_result(query->move_as_ok()); + } else { + handler->on_error(query->move_as_error()); } - - bool result = result_ptr.ok(); - if (!result) { - LOG(INFO) << "Sending answer to a custom query has failed"; + } else { + if (!query->is_ok() || query->ok_tl_constructor() != telegram_api::upload_file::ID) { + LOG(WARNING) << query << " is ignored: no handlers found"; } - promise_.set_value(Unit()); + query->clear(); } +} - void on_error(Status status) final { - promise_.set_error(std::move(status)); +void Td::start_up() { + uint64 check_endianness = 0x0706050403020100; + auto check_endianness_raw = reinterpret_cast(&check_endianness); + for (unsigned char c = 0; c < 8; c++) { + auto symbol = check_endianness_raw[static_cast(c)]; + LOG_IF(FATAL, symbol != c) << "TDLib requires little-endian platform"; } -}; -class SetBotUpdatesStatusQuery final : public Td::ResultHandler { - public: - void send(int32 pending_update_count, const string &error_message) { - send_query( - G()->net_query_creator().create(telegram_api::help_setBotUpdatesStatus(pending_update_count, error_message))); - } + requests_ = make_unique(this); - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } + VLOG(td_init) << "Create Global"; + old_context_ = set_context(std::make_shared()); + G()->set_net_query_stats(td_options_.net_query_stats); + inc_request_actor_refcnt(); // guard + inc_actor_refcnt(); // guard - bool result = result_ptr.ok(); - LOG_IF(WARNING, !result) << "Set bot updates status has failed"; - } + alarm_manager_ = create_actor("AlarmManager", create_reference()); - void on_error(Status status) final { - if (!G()->is_expected_error(status)) { - LOG(WARNING) << "Receive error for SetBotUpdatesStatusQuery: " << status; - } - status.ignore(); - } -}; - -class UpdateStatusQuery final : public Td::ResultHandler { - bool is_offline_; - - public: - NetQueryRef send(bool is_offline) { - is_offline_ = is_offline; - auto net_query = G()->net_query_creator().create(telegram_api::account_updateStatus(is_offline)); - auto result = net_query.get_weak(); - send_query(std::move(net_query)); - return result; - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - bool result = result_ptr.ok(); - LOG(INFO) << "Receive result for UpdateStatusQuery: " << result; - td_->on_update_status_success(!is_offline_); - } - - void on_error(Status status) final { - if (status.code() != NetQuery::Canceled && !G()->is_expected_error(status)) { - LOG(ERROR) << "Receive error for UpdateStatusQuery: " << status; - } - status.ignore(); + CHECK(state_ == State::WaitParameters); + for (auto &update : get_fake_current_state()) { + send_update(std::move(update)); } -}; +} -class TestNetworkQuery final : public Td::ResultHandler { - Promise promise_; +void Td::tear_down() { + LOG_CHECK(close_flag_ == 5) << close_flag_; +} - public: - explicit TestNetworkQuery(Promise &&promise) : promise_(std::move(promise)) { - } +void Td::hangup_shared() { + auto token = get_link_token(); + auto type = Container::type_from_id(token); - void send() { - send_query(G()->net_query_creator().create_unauth(telegram_api::help_getConfig())); + if (type == RequestActorIdType) { + request_actors_.erase(token); + dec_request_actor_refcnt(); + } else if (type == ActorIdType) { + dec_actor_refcnt(); + } else { + LOG(FATAL) << "Unknown hangup_shared of type " << type; } +} - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(Status::Error(500, "Fetch failed")); - } - - LOG(DEBUG) << "TestNetwork OK: " << to_string(result_ptr.ok()); - promise_.set_value(Unit()); - } +void Td::hangup() { + LOG(INFO) << "Receive Td::hangup"; + close(); + dec_stop_cnt(); +} - void on_error(Status status) final { - LOG(ERROR) << "Test query failed: " << status; - promise_.set_error(std::move(status)); - } -}; +ActorShared Td::create_reference() { + inc_actor_refcnt(); + return actor_shared(this, ActorIdType); +} -class TestProxyRequest final : public RequestOnceActor { - Proxy proxy_; - int16 dc_id_; - double timeout_; - ActorOwn<> child_; - Promise<> promise_; +void Td::inc_actor_refcnt() { + actor_refcnt_++; +} - auto get_transport() { - return mtproto::TransportType{mtproto::TransportType::ObfuscatedTcp, dc_id_, proxy_.secret()}; +void Td::dec_actor_refcnt() { + actor_refcnt_--; + if (actor_refcnt_ < 3) { + LOG(DEBUG) << "Decrease reference count to " << actor_refcnt_; } + if (actor_refcnt_ == 0) { + if (close_flag_ == 2) { + create_reference(); + close_flag_ = 3; + } else if (close_flag_ == 3) { + LOG(INFO) << "All actors were closed"; + Timer timer; + auto reset_manager = [&timer](auto &manager, Slice name) { + manager.reset(); + LOG(DEBUG) << name << " was cleared" << timer; + }; + reset_manager(account_manager_, "AccountManager"); + reset_manager(animations_manager_, "AnimationsManager"); + reset_manager(attach_menu_manager_, "AttachMenuManager"); + reset_manager(audios_manager_, "AudiosManager"); + reset_manager(auth_manager_, "AuthManager"); + reset_manager(autosave_manager_, "AutosaveManager"); + reset_manager(background_manager_, "BackgroundManager"); + reset_manager(boost_manager_, "BoostManager"); + reset_manager(bot_info_manager_, "BotInfoManager"); + reset_manager(business_connection_manager_, "BusinessConnectionManager"); + reset_manager(business_manager_, "BusinessManager"); + reset_manager(callback_queries_manager_, "CallbackQueriesManager"); + reset_manager(channel_recommendation_manager_, "ChannelRecommendationManager"); + reset_manager(chat_manager_, "ChatManager"); + reset_manager(common_dialog_manager_, "CommonDialogManager"); + reset_manager(connection_state_manager_, "ConnectionStateManager"); + reset_manager(country_info_manager_, "CountryInfoManager"); + reset_manager(dialog_action_manager_, "DialogActionManager"); + reset_manager(dialog_filter_manager_, "DialogFilterManager"); + reset_manager(dialog_invite_link_manager_, "DialogInviteLinkManager"); + reset_manager(dialog_manager_, "DialogManager"); + reset_manager(dialog_participant_manager_, "DialogParticipantManager"); + reset_manager(documents_manager_, "DocumentsManager"); + reset_manager(download_manager_, "DownloadManager"); + reset_manager(file_manager_, "FileManager"); + reset_manager(file_reference_manager_, "FileReferenceManager"); + reset_manager(forum_topic_manager_, "ForumTopicManager"); + reset_manager(game_manager_, "GameManager"); + reset_manager(group_call_manager_, "GroupCallManager"); + reset_manager(inline_message_manager_, "InlineMessageManager"); + reset_manager(inline_queries_manager_, "InlineQueriesManager"); + reset_manager(link_manager_, "LinkManager"); + reset_manager(message_import_manager_, "MessageImportManager"); + reset_manager(messages_manager_, "MessagesManager"); + reset_manager(notification_manager_, "NotificationManager"); + reset_manager(notification_settings_manager_, "NotificationSettingsManager"); + reset_manager(online_manager_, "OnlineManager"); + reset_manager(people_nearby_manager_, "PeopleNearbyManager"); + reset_manager(phone_number_manager_, "PhoneNumberManager"); + reset_manager(poll_manager_, "PollManager"); + reset_manager(privacy_manager_, "PrivacyManager"); + reset_manager(promo_data_manager_, "PromoDataManager"); + reset_manager(quick_reply_manager_, "QuickReplyManager"); + reset_manager(reaction_manager_, "ReactionManager"); + reset_manager(saved_messages_manager_, "SavedMessagesManager"); + reset_manager(sponsored_message_manager_, "SponsoredMessageManager"); + reset_manager(star_manager_, "StarManager"); + reset_manager(statistics_manager_, "StatisticsManager"); + reset_manager(stickers_manager_, "StickersManager"); + reset_manager(story_manager_, "StoryManager"); + reset_manager(terms_of_service_manager_, "TermsOfServiceManager"); + reset_manager(theme_manager_, "ThemeManager"); + reset_manager(time_zone_manager_, "TimeZoneManager"); + reset_manager(top_dialog_manager_, "TopDialogManager"); + reset_manager(transcription_manager_, "TranscriptionManager"); + reset_manager(translation_manager_, "TranslationManager"); + reset_manager(updates_manager_, "UpdatesManager"); + reset_manager(user_manager_, "UserManager"); + reset_manager(video_notes_manager_, "VideoNotesManager"); + reset_manager(videos_manager_, "VideosManager"); + reset_manager(voice_notes_manager_, "VoiceNotesManager"); + reset_manager(web_pages_manager_, "WebPagesManager"); - void do_run(Promise &&promise) final { - set_timeout_in(timeout_); - - promise_ = std::move(promise); - IPAddress ip_address; - auto status = ip_address.init_host_port(proxy_.server(), proxy_.port()); - if (status.is_error()) { - return promise_.set_error(Status::Error(400, status.public_message())); - } - auto r_socket_fd = SocketFd::open(ip_address); - if (r_socket_fd.is_error()) { - return promise_.set_error(Status::Error(400, r_socket_fd.error().public_message())); - } - - auto dc_options = ConnectionCreator::get_default_dc_options(false); - IPAddress mtproto_ip_address; - for (auto &dc_option : dc_options.dc_options) { - if (dc_option.get_dc_id().get_raw_id() == dc_id_) { - mtproto_ip_address = dc_option.get_ip_address(); - break; - } - } - - auto connection_promise = - PromiseCreator::lambda([actor_id = actor_id(this)](Result r_data) mutable { - send_closure(actor_id, &TestProxyRequest::on_connection_data, std::move(r_data)); - }); - - child_ = ConnectionCreator::prepare_connection(ip_address, r_socket_fd.move_as_ok(), proxy_, mtproto_ip_address, - get_transport(), "Test", "TestPingDC2", nullptr, {}, false, - std::move(connection_promise)); - } + G()->set_option_manager(nullptr); + option_manager_.reset(); + LOG(DEBUG) << "OptionManager was cleared" << timer; - void on_connection_data(Result r_data) { - if (r_data.is_error()) { - return promise_.set_error(r_data.move_as_error()); - } - class HandshakeContext final : public mtproto::AuthKeyHandshakeContext { - public: - mtproto::DhCallback *get_dh_callback() final { - return nullptr; - } - mtproto::PublicRsaKeyInterface *get_public_rsa_key_interface() final { - return &public_rsa_key; - } + G()->close_all(destroy_flag_, + PromiseCreator::lambda([actor_id = create_reference()](Unit) mutable { actor_id.reset(); })); - private: - PublicRsaKeyShared public_rsa_key{DcId::empty(), false}; - }; - auto handshake = make_unique(dc_id_, 3600); - auto data = r_data.move_as_ok(); - auto raw_connection = - mtproto::RawConnection::create(data.ip_address, std::move(data.buffered_socket_fd), get_transport(), nullptr); - child_ = create_actor( - "HandshakeActor", std::move(handshake), std::move(raw_connection), make_unique(), 10.0, - PromiseCreator::lambda([actor_id = actor_id(this)](Result> raw_connection) { - send_closure(actor_id, &TestProxyRequest::on_handshake_connection, std::move(raw_connection)); - }), - PromiseCreator::lambda( - [actor_id = actor_id(this)](Result> handshake) mutable { - send_closure(actor_id, &TestProxyRequest::on_handshake, std::move(handshake)); - })); - } - void on_handshake_connection(Result> r_raw_connection) { - if (r_raw_connection.is_error()) { - return promise_.set_error(Status::Error(400, r_raw_connection.move_as_error().public_message())); + // NetQueryDispatcher will be closed automatically + close_flag_ = 4; + } else if (close_flag_ == 4) { + on_closed(); + } else { + UNREACHABLE(); } } - void on_handshake(Result> r_handshake) { - if (!promise_) { - return; - } - if (r_handshake.is_error()) { - return promise_.set_error(Status::Error(400, r_handshake.move_as_error().public_message())); - } +} - auto handshake = r_handshake.move_as_ok(); - if (!handshake->is_ready_for_finish()) { - promise_.set_error(Status::Error(400, "Handshake is not ready")); - } - promise_.set_value(Unit()); - } +void Td::on_closed() { + close_flag_ = 5; + send_update( + td_api::make_object(td_api::make_object())); + dec_stop_cnt(); +} - void timeout_expired() final { - send_error(Status::Error(400, "Timeout expired")); +void Td::dec_stop_cnt() { + stop_cnt_--; + if (stop_cnt_ == 0) { + LOG(INFO) << "Stop Td"; + set_context(std::move(old_context_)); stop(); } +} - public: - TestProxyRequest(ActorShared td, uint64 request_id, Proxy proxy, int32 dc_id, double timeout) - : RequestOnceActor(std::move(td), request_id) - , proxy_(std::move(proxy)) - , dc_id_(static_cast(dc_id)) - , timeout_(timeout) { - } -}; - -class GetMeRequest final : public RequestActor<> { - UserId user_id_; - - void do_run(Promise &&promise) final { - user_id_ = td_->contacts_manager_->get_me(std::move(promise)); - } - - void do_send_result() final { - send_result(td_->contacts_manager_->get_user_object(user_id_)); - } - - public: - GetMeRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { - } -}; - -class GetUserRequest final : public RequestActor<> { - UserId user_id_; +void Td::inc_request_actor_refcnt() { + request_actor_refcnt_++; +} - void do_run(Promise &&promise) final { - td_->contacts_manager_->get_user(user_id_, get_tries(), std::move(promise)); +void Td::dec_request_actor_refcnt() { + request_actor_refcnt_--; + LOG(DEBUG) << "Decrease request actor count to " << request_actor_refcnt_; + if (request_actor_refcnt_ == 0) { + clear(); + dec_actor_refcnt(); // remove guard } +} - void do_send_result() final { - send_result(td_->contacts_manager_->get_user_object(user_id_)); +void Td::clear_requests() { + while (!request_set_.empty()) { + uint64 id = request_set_.begin()->first; + if (destroy_flag_) { + send_error_impl(id, make_error(401, "Unauthorized")); + } else { + send_error_impl(id, make_error(500, "Request aborted")); + } } +} - public: - GetUserRequest(ActorShared td, uint64 request_id, int64 user_id) - : RequestActor(std::move(td), request_id), user_id_(user_id) { - set_tries(3); +void Td::clear() { + if (close_flag_ >= 2) { + return; } -}; -class GetUserFullInfoRequest final : public RequestActor<> { - UserId user_id_; + LOG(INFO) << "Clear Td"; + close_flag_ = 2; - void do_run(Promise &&promise) final { - td_->contacts_manager_->load_user_full(user_id_, get_tries() < 2, std::move(promise), "GetUserFullInfoRequest"); + Timer timer; + if (!auth_manager_->is_bot()) { + if (destroy_flag_) { + notification_manager_->destroy_all_notifications(); + } else { + notification_manager_->flush_all_notifications(); + } } - void do_send_result() final { - send_result(td_->contacts_manager_->get_user_full_info_object(user_id_)); - } + G()->net_query_creator().stop_check(); + result_handlers_.clear(); + LOG(DEBUG) << "Handlers were cleared" << timer; + G()->net_query_dispatcher().stop(); + LOG(DEBUG) << "NetQueryDispatcher was stopped" << timer; + state_manager_.reset(); + LOG(DEBUG) << "StateManager was cleared" << timer; + clear_requests(); - public: - GetUserFullInfoRequest(ActorShared td, uint64 request_id, int64 user_id) - : RequestActor(std::move(td), request_id), user_id_(user_id) { - } -}; + auto reset_actor = [&timer](ActorOwn actor) { + if (!actor.empty()) { + LOG(DEBUG) << "Start clearing " << actor.get().get_name() << timer; + } + }; -class GetGroupRequest final : public RequestActor<> { - ChatId chat_id_; + // close all pure actors + reset_actor(ActorOwn(std::move(alarm_manager_))); + reset_actor(ActorOwn(std::move(call_manager_))); + reset_actor(ActorOwn(std::move(cashtag_search_hints_))); + reset_actor(ActorOwn(std::move(config_manager_))); + reset_actor(ActorOwn(std::move(device_token_manager_))); + reset_actor(ActorOwn(std::move(hashtag_hints_))); + reset_actor(ActorOwn(std::move(hashtag_search_hints_))); + reset_actor(ActorOwn(std::move(language_pack_manager_))); + reset_actor(ActorOwn(std::move(net_stats_manager_))); + reset_actor(ActorOwn(std::move(password_manager_))); + reset_actor(ActorOwn(std::move(secure_manager_))); + reset_actor(ActorOwn(std::move(secret_chats_manager_))); + reset_actor(ActorOwn(std::move(storage_manager_))); - void do_run(Promise &&promise) final { - td_->contacts_manager_->get_chat(chat_id_, get_tries(), std::move(promise)); - } + G()->set_connection_creator(ActorOwn()); + LOG(DEBUG) << "ConnectionCreator was cleared" << timer; + G()->set_temp_auth_key_watchdog(ActorOwn()); + LOG(DEBUG) << "TempAuthKeyWatchdog was cleared" << timer; - void do_send_result() final { - send_result(td_->contacts_manager_->get_basic_group_object(chat_id_)); - } + // clear actors which are unique pointers + reset_actor(ActorOwn(std::move(account_manager_actor_))); + reset_actor(ActorOwn(std::move(animations_manager_actor_))); + reset_actor(ActorOwn(std::move(attach_menu_manager_actor_))); + reset_actor(ActorOwn(std::move(auth_manager_actor_))); + reset_actor(ActorOwn(std::move(autosave_manager_actor_))); + reset_actor(ActorOwn(std::move(background_manager_actor_))); + reset_actor(ActorOwn(std::move(boost_manager_actor_))); + reset_actor(ActorOwn(std::move(bot_info_manager_actor_))); + reset_actor(ActorOwn(std::move(business_connection_manager_actor_))); + reset_actor(ActorOwn(std::move(business_manager_actor_))); + reset_actor(ActorOwn(std::move(channel_recommendation_manager_actor_))); + reset_actor(ActorOwn(std::move(chat_manager_actor_))); + reset_actor(ActorOwn(std::move(common_dialog_manager_actor_))); + reset_actor(ActorOwn(std::move(connection_state_manager_actor_))); + reset_actor(ActorOwn(std::move(country_info_manager_actor_))); + reset_actor(ActorOwn(std::move(dialog_action_manager_actor_))); + reset_actor(ActorOwn(std::move(dialog_filter_manager_actor_))); + reset_actor(ActorOwn(std::move(dialog_invite_link_manager_actor_))); + reset_actor(ActorOwn(std::move(dialog_manager_actor_))); + reset_actor(ActorOwn(std::move(dialog_participant_manager_actor_))); + reset_actor(ActorOwn(std::move(download_manager_actor_))); + reset_actor(ActorOwn(std::move(file_manager_actor_))); + reset_actor(ActorOwn(std::move(file_reference_manager_actor_))); + reset_actor(ActorOwn(std::move(forum_topic_manager_actor_))); + reset_actor(ActorOwn(std::move(game_manager_actor_))); + reset_actor(ActorOwn(std::move(group_call_manager_actor_))); + reset_actor(ActorOwn(std::move(inline_message_manager_actor_))); + reset_actor(ActorOwn(std::move(inline_queries_manager_actor_))); + reset_actor(ActorOwn(std::move(link_manager_actor_))); + reset_actor(ActorOwn(std::move(message_import_manager_actor_))); + reset_actor(ActorOwn(std::move(messages_manager_actor_))); + reset_actor(ActorOwn(std::move(notification_manager_actor_))); + reset_actor(ActorOwn(std::move(notification_settings_manager_actor_))); + reset_actor(ActorOwn(std::move(online_manager_actor_))); + reset_actor(ActorOwn(std::move(people_nearby_manager_actor_))); + reset_actor(ActorOwn(std::move(phone_number_manager_actor_))); + reset_actor(ActorOwn(std::move(poll_manager_actor_))); + reset_actor(ActorOwn(std::move(privacy_manager_actor_))); + reset_actor(ActorOwn(std::move(promo_data_manager_actor_))); + reset_actor(ActorOwn(std::move(quick_reply_manager_actor_))); + reset_actor(ActorOwn(std::move(reaction_manager_actor_))); + reset_actor(ActorOwn(std::move(saved_messages_manager_actor_))); + reset_actor(ActorOwn(std::move(sponsored_message_manager_actor_))); + reset_actor(ActorOwn(std::move(star_manager_actor_))); + reset_actor(ActorOwn(std::move(statistics_manager_actor_))); + reset_actor(ActorOwn(std::move(stickers_manager_actor_))); + reset_actor(ActorOwn(std::move(story_manager_actor_))); + reset_actor(ActorOwn(std::move(terms_of_service_manager_actor_))); + reset_actor(ActorOwn(std::move(theme_manager_actor_))); + reset_actor(ActorOwn(std::move(time_zone_manager_actor_))); + reset_actor(ActorOwn(std::move(top_dialog_manager_actor_))); + reset_actor(ActorOwn(std::move(transcription_manager_actor_))); + reset_actor(ActorOwn(std::move(translation_manager_actor_))); + reset_actor(ActorOwn(std::move(updates_manager_actor_))); + reset_actor(ActorOwn(std::move(user_manager_actor_))); + reset_actor(ActorOwn(std::move(video_notes_manager_actor_))); + reset_actor(ActorOwn(std::move(voice_notes_manager_actor_))); + reset_actor(ActorOwn(std::move(web_pages_manager_actor_))); + LOG(DEBUG) << "All actors were cleared" << timer; +} - public: - GetGroupRequest(ActorShared td, uint64 request_id, int64 chat_id) - : RequestActor(std::move(td), request_id), chat_id_(chat_id) { - set_tries(3); - } -}; +void Td::close() { + close_impl(false); +} -class GetGroupFullInfoRequest final : public RequestActor<> { - ChatId chat_id_; +void Td::destroy() { + close_impl(true); +} - void do_run(Promise &&promise) final { - td_->contacts_manager_->load_chat_full(chat_id_, get_tries() < 2, std::move(promise), "getBasicGroupFullInfo"); +void Td::close_impl(bool destroy_flag) { + destroy_flag_ |= destroy_flag; + if (close_flag_) { + return; } - void do_send_result() final { - send_result(td_->contacts_manager_->get_basic_group_full_info_object(chat_id_)); - } + LOG(WARNING) << (destroy_flag ? "Destroy" : "Close") << " Td in state " << static_cast(state_); + if (state_ == State::WaitParameters) { + state_ = State::Close; + close_flag_ = 4; + G()->set_close_flag(); + clear_requests(); + alarm_manager_.reset(); + send_update(td_api::make_object( + td_api::make_object())); - public: - GetGroupFullInfoRequest(ActorShared td, uint64 request_id, int64 chat_id) - : RequestActor(std::move(td), request_id), chat_id_(chat_id) { + request_actors_.clear(); + return send_closure_later(actor_id(this), &Td::dec_request_actor_refcnt); // remove guard } -}; -class GetSupergroupRequest final : public RequestActor<> { - ChannelId channel_id_; - - void do_run(Promise &&promise) final { - td_->contacts_manager_->get_channel(channel_id_, get_tries(), std::move(promise)); - } + state_ = State::Close; + close_flag_ = 1; + G()->set_close_flag(); + send_closure(auth_manager_actor_, &AuthManager::on_closing, destroy_flag); + updates_manager_->timeout_expired(); // save PTS and QTS - void do_send_result() final { - send_result(td_->contacts_manager_->get_supergroup_object(channel_id_)); - } + // wait till all request_actors will stop + request_actors_.clear(); + G()->td_db()->flush_all(); + send_closure_later(actor_id(this), &Td::dec_request_actor_refcnt); // remove guard +} - public: - GetSupergroupRequest(ActorShared td, uint64 request_id, int64 channel_id) - : RequestActor(std::move(td), request_id), channel_id_(channel_id) { - set_tries(3); +template +void Td::complete_pending_preauthentication_requests(const T &func) { + for (auto &request : pending_preauthentication_requests_) { + if (request.second != nullptr && func(request.second->get_id())) { + requests_->run_request(request.first, std::move(request.second)); + request.second = nullptr; + } } -}; +} -class GetSupergroupFullInfoRequest final : public RequestActor<> { - ChannelId channel_id_; +void Td::finish_set_parameters() { + CHECK(set_parameters_request_id_ != 0); + set_parameters_request_id_ = 0; - void do_run(Promise &&promise) final { - td_->contacts_manager_->load_channel_full(channel_id_, get_tries() < 2, std::move(promise), - "GetSupergroupFullInfoRequest"); + if (pending_set_parameters_requests_.empty()) { + return; } - void do_send_result() final { - send_result(td_->contacts_manager_->get_supergroup_full_info_object(channel_id_)); + VLOG(td_init) << "Continue to execute " << pending_set_parameters_requests_.size() << " pending requests"; + auto requests = std::move(pending_set_parameters_requests_); + for (auto &request : requests) { + run_request(request.first, std::move(request.second)); } + CHECK(pending_set_parameters_requests_.size() < requests.size()); +} - public: - GetSupergroupFullInfoRequest(ActorShared td, uint64 request_id, int64 channel_id) - : RequestActor(std::move(td), request_id), channel_id_(channel_id) { +void Td::init(Parameters parameters, Result r_opened_database) { + CHECK(set_parameters_request_id_ != 0); + if (r_opened_database.is_error()) { + LOG(WARNING) << "Failed to open database: " << r_opened_database.error(); + send_closure(actor_id(this), &Td::send_error, set_parameters_request_id_, r_opened_database.move_as_error()); + return finish_set_parameters(); } -}; + auto events = r_opened_database.move_as_ok(); -class GetSecretChatRequest final : public RequestActor<> { - SecretChatId secret_chat_id_; + VLOG(td_init) << "Successfully inited database"; - void do_run(Promise &&promise) final { - td_->contacts_manager_->get_secret_chat(secret_chat_id_, get_tries() < 2, std::move(promise)); + if (state_ == State::Close) { + LOG(INFO) << "Close asynchronously opened database"; + auto database_ptr = events.database.get(); + auto promise = PromiseCreator::lambda([database = std::move(events.database)](Unit) { + // destroy the database after closing + }); + database_ptr->close( + database_ptr->use_file_database() ? G()->get_database_scheduler_id() : G()->get_slow_net_scheduler_id(), + destroy_flag_, std::move(promise)); + return finish_set_parameters(); } - void do_send_result() final { - send_result(td_->contacts_manager_->get_secret_chat_object(secret_chat_id_)); - } + G()->init(actor_id(this), std::move(events.database)).ensure(); - public: - GetSecretChatRequest(ActorShared td, uint64 request_id, int32 secret_chat_id) - : RequestActor(std::move(td), request_id), secret_chat_id_(secret_chat_id) { - } -}; + init_options_and_network(); -class GetChatRequest final : public RequestActor<> { - DialogId dialog_id_; + // we need to process td_api::getOption along with td_api::setOption for consistency + // we need to process td_api::setOption before managers and MTProto header are created, + // because their initialiation may be affected by the options + complete_pending_preauthentication_requests([](int32 id) { + switch (id) { + case td_api::getOption::ID: + case td_api::setOption::ID: + return true; + default: + return false; + } + }); - bool dialog_found_ = false; + if (!option_manager_->get_option_boolean("disable_network_statistics")) { + net_stats_manager_ = create_actor("NetStatsManager", create_reference()); - void do_run(Promise &&promise) final { - dialog_found_ = td_->messages_manager_->load_dialog(dialog_id_, get_tries(), std::move(promise)); + // How else could I let two actor know about each other, without quite complex async logic? + auto net_stats_manager_ptr = net_stats_manager_.get_actor_unsafe(); + net_stats_manager_ptr->init(); + G()->connection_creator().get_actor_unsafe()->set_net_stats_callback( + net_stats_manager_ptr->get_common_stats_callback(), net_stats_manager_ptr->get_media_stats_callback()); + G()->set_net_stats_file_callbacks(net_stats_manager_ptr->get_file_stats_callbacks()); } - void do_send_result() final { - if (!dialog_found_) { - send_error(Status::Error(400, "Chat is not accessible")); - } else { - send_result(td_->messages_manager_->get_chat_object(dialog_id_)); + complete_pending_preauthentication_requests([](int32 id) { + switch (id) { + case td_api::getNetworkStatistics::ID: + case td_api::addNetworkStatistics::ID: + case td_api::resetNetworkStatistics::ID: + return true; + default: + return false; } - } + }); - public: - GetChatRequest(ActorShared td, uint64 request_id, int64 dialog_id) - : RequestActor(std::move(td), request_id), dialog_id_(dialog_id) { - set_tries(3); + if (events.since_last_open >= 3600) { + auto old_since_last_open = option_manager_->get_option_integer("since_last_open"); + if (events.since_last_open > old_since_last_open) { + option_manager_->set_option_integer("since_last_open", events.since_last_open); + } } -}; -class SearchUserByPhoneNumberRequest final : public RequestActor<> { - string phone_number_; - - UserId user_id_; - - void do_run(Promise &&promise) final { - user_id_ = td_->contacts_manager_->search_user_by_phone_number(phone_number_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->contacts_manager_->get_user_object(user_id_)); - } - - public: - SearchUserByPhoneNumberRequest(ActorShared td, uint64 request_id, string &&phone_number) - : RequestActor(std::move(td), request_id), phone_number_(std::move(phone_number)) { - } -}; - -class LoadChatsRequest final : public RequestActor<> { - DialogListId dialog_list_id_; - DialogDate offset_; - int32 limit_; - - void do_run(Promise &&promise) final { - td_->messages_manager_->get_dialogs(dialog_list_id_, offset_, limit_, false, get_tries() < 2, std::move(promise)); - } - - public: - LoadChatsRequest(ActorShared td, uint64 request_id, DialogListId dialog_list_id, DialogDate offset, int32 limit) - : RequestActor(std::move(td), request_id), dialog_list_id_(dialog_list_id), offset_(offset), limit_(limit) { - // 1 for database + 1 for server request + 1 for server request at the end + 1 for return + 1 just in case - set_tries(5); - - if (limit_ > 100) { - limit_ = 100; - } - } -}; - -class SearchPublicChatRequest final : public RequestActor<> { - string username_; - - DialogId dialog_id_; - - void do_run(Promise &&promise) final { - dialog_id_ = td_->messages_manager_->search_public_dialog(username_, get_tries() < 3, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_chat_object(dialog_id_)); - } - - public: - SearchPublicChatRequest(ActorShared td, uint64 request_id, string username) - : RequestActor(std::move(td), request_id), username_(std::move(username)) { - set_tries(4); // 1 for server request + 1 for reload voice chat + 1 for reload dialog + 1 for result - } -}; - -class SearchPublicChatsRequest final : public RequestActor<> { - string query_; - - vector dialog_ids_; - - void do_run(Promise &&promise) final { - dialog_ids_ = td_->messages_manager_->search_public_dialogs(query_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_chats_object(-1, dialog_ids_, "SearchPublicChatsRequest")); - } - - public: - SearchPublicChatsRequest(ActorShared td, uint64 request_id, string query) - : RequestActor(std::move(td), request_id), query_(std::move(query)) { - } -}; - -class SearchChatsRequest final : public RequestActor<> { - string query_; - int32 limit_; + options_.language_pack = option_manager_->get_option_string("localization_target"); + options_.language_code = option_manager_->get_option_string("language_pack_id"); + options_.parameters = option_manager_->get_option_string("connection_parameters"); + options_.tz_offset = static_cast(option_manager_->get_option_integer("utc_time_offset")); + options_.is_emulator = option_manager_->get_option_boolean("is_emulator"); + // options_.proxy = Proxy(); + G()->set_mtproto_header(make_unique(options_)); + G()->set_store_all_files_in_files_directory( + option_manager_->get_option_boolean("store_all_files_in_files_directory")); - std::pair> dialog_ids_; + VLOG(td_init) << "Create NetQueryDispatcher"; + auto net_query_dispatcher = make_unique([&] { return create_reference(); }); + G()->set_net_query_dispatcher(std::move(net_query_dispatcher)); - void do_run(Promise &&promise) final { - dialog_ids_ = td_->messages_manager_->search_dialogs(query_, limit_, std::move(promise)); - } + complete_pending_preauthentication_requests([](int32 id) { + // pingProxy uses NetQueryDispatcher to get main_dc_id, so must be called after NetQueryDispatcher is created + return id == td_api::pingProxy::ID; + }); - void do_send_result() final { - send_result(td_->messages_manager_->get_chats_object(dialog_ids_, "SearchChatsRequest")); - } + VLOG(td_init) << "Create AuthManager"; + auth_manager_ = td::make_unique(parameters.api_id_, parameters.api_hash_, create_reference()); + auth_manager_actor_ = register_actor("AuthManager", auth_manager_.get()); + G()->set_auth_manager(auth_manager_actor_.get()); - public: - SearchChatsRequest(ActorShared td, uint64 request_id, string query, int32 limit) - : RequestActor(std::move(td), request_id), query_(std::move(query)), limit_(limit) { - } -}; + init_file_manager(); -class SearchChatsOnServerRequest final : public RequestActor<> { - string query_; - int32 limit_; + init_non_actor_managers(); - vector dialog_ids_; + init_managers(); - void do_run(Promise &&promise) final { - dialog_ids_ = td_->messages_manager_->search_dialogs_on_server(query_, limit_, std::move(promise)); - } + init_pure_actor_managers(); - void do_send_result() final { - send_result(td_->messages_manager_->get_chats_object(-1, dialog_ids_, "SearchChatsOnServerRequest")); - } + secret_chats_manager_ = + create_actor("SecretChatsManager", create_reference(), parameters.use_secret_chats_); + G()->set_secret_chats_manager(secret_chats_manager_.get()); - public: - SearchChatsOnServerRequest(ActorShared td, uint64 request_id, string query, int32 limit) - : RequestActor(std::move(td), request_id), query_(std::move(query)), limit_(limit) { - } -}; + storage_manager_ = create_actor("StorageManager", create_reference(), G()->get_gc_scheduler_id()); + G()->set_storage_manager(storage_manager_.get()); -class GetGroupsInCommonRequest final : public RequestActor<> { - UserId user_id_; - DialogId offset_dialog_id_; - int32 limit_; + option_manager_->on_td_inited(); - std::pair> dialog_ids_; + process_binlog_events(std::move(events)); - void do_run(Promise &&promise) final { - dialog_ids_ = td_->messages_manager_->get_common_dialogs(user_id_, offset_dialog_id_, limit_, get_tries() < 2, - std::move(promise)); + VLOG(td_init) << "Ping datacenter"; + if (!auth_manager_->is_authorized()) { + country_info_manager_->get_current_country_code(Promise()); + } else { + updates_manager_->get_difference("init"); } - void do_send_result() final { - send_result(td_->messages_manager_->get_chats_object(dialog_ids_, "GetGroupsInCommonRequest")); - } + complete_pending_preauthentication_requests([](int32 id) { return true; }); - public: - GetGroupsInCommonRequest(ActorShared td, uint64 request_id, int64 user_id, int64 offset_dialog_id, int32 limit) - : RequestActor(std::move(td), request_id), user_id_(user_id), offset_dialog_id_(offset_dialog_id), limit_(limit) { - } -}; + VLOG(td_init) << "Finish initialization"; -class GetSuitableDiscussionChatsRequest final : public RequestActor<> { - vector dialog_ids_; + state_ = State::Run; - void do_run(Promise &&promise) final { - dialog_ids_ = td_->contacts_manager_->get_dialogs_for_discussion(std::move(promise)); - } + send_closure(actor_id(this), &Td::send_result, set_parameters_request_id_, td_api::make_object()); + return finish_set_parameters(); +} - void do_send_result() final { - send_result(td_->messages_manager_->get_chats_object(-1, dialog_ids_, "GetSuitableDiscussionChatsRequest")); +void Td::process_binlog_events(TdDb::OpenedDatabase &&events) { + VLOG(td_init) << "Send binlog events"; + for (auto &event : events.user_events) { + user_manager_->on_binlog_user_event(std::move(event)); } - public: - GetSuitableDiscussionChatsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + for (auto &event : events.channel_events) { + chat_manager_->on_binlog_channel_event(std::move(event)); } -}; -class GetInactiveSupergroupChatsRequest final : public RequestActor<> { - vector dialog_ids_; - - void do_run(Promise &&promise) final { - dialog_ids_ = td_->contacts_manager_->get_inactive_channels(std::move(promise)); + // chats may contain links to channels, so should be inited after + for (auto &event : events.chat_events) { + chat_manager_->on_binlog_chat_event(std::move(event)); } - void do_send_result() final { - send_result(td_->messages_manager_->get_chats_object(-1, dialog_ids_, "GetInactiveSupergroupChatsRequest")); + for (auto &event : events.secret_chat_events) { + user_manager_->on_binlog_secret_chat_event(std::move(event)); } - public: - GetInactiveSupergroupChatsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { + for (auto &event : events.web_page_events) { + web_pages_manager_->on_binlog_web_page_event(std::move(event)); } -}; -class GetRecentlyOpenedChatsRequest final : public RequestActor<> { - int32 limit_; - - std::pair> dialog_ids_; - - void do_run(Promise &&promise) final { - dialog_ids_ = td_->messages_manager_->get_recently_opened_dialogs(limit_, std::move(promise)); + for (auto &event : events.save_app_log_events) { + on_save_app_log_binlog_event(this, std::move(event)); } - void do_send_result() final { - send_result(td_->messages_manager_->get_chats_object(dialog_ids_, "GetRecentlyOpenedChatsRequest")); - } + // Send binlog events to managers + // + // 1. Actors must receive all binlog events before other queries. + // + // -- All actors have one "entry point". So there is only one way to send query to them. So all queries are ordered + // for each Actor. + // + // 2. An actor must not make some decisions before all binlog events are processed. + // For example, SecretChatActor must not send RequestKey, before it receives log event with RequestKey and understands + // that RequestKey was already sent. + // + // 3. During replay of binlog some queries may be sent to other actors. They shouldn't process such events before all + // their binlog events are processed. So actor may receive some old queries. It must be in its actual state in + // order to handle them properly. + // + // -- Use send_closure_later, so actors don't even start process binlog events, before all binlog events are sent - public: - GetRecentlyOpenedChatsRequest(ActorShared td, uint64 request_id, int32 limit) - : RequestActor(std::move(td), request_id), limit_(limit) { + for (auto &event : events.to_secret_chats_manager) { + send_closure_later(secret_chats_manager_, &SecretChatsManager::replay_binlog_event, std::move(event)); } -}; -class GetMessageRequest final : public RequestOnceActor { - FullMessageId full_message_id_; - - void do_run(Promise &&promise) final { - td_->messages_manager_->get_message(full_message_id_, std::move(promise)); - } + send_closure_later(account_manager_actor_, &AccountManager::on_binlog_events, std::move(events.to_account_manager)); - void do_send_result() final { - send_result(td_->messages_manager_->get_message_object(full_message_id_, "GetMessageRequest")); - } + send_closure_later(poll_manager_actor_, &PollManager::on_binlog_events, std::move(events.to_poll_manager)); - public: - GetMessageRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id) - : RequestOnceActor(std::move(td), request_id), full_message_id_(DialogId(dialog_id), MessageId(message_id)) { - } -}; + send_closure_later(messages_manager_actor_, &MessagesManager::on_binlog_events, + std::move(events.to_messages_manager)); -class GetRepliedMessageRequest final : public RequestOnceActor { - DialogId dialog_id_; - MessageId message_id_; + send_closure_later(story_manager_actor_, &StoryManager::on_binlog_events, std::move(events.to_story_manager)); - FullMessageId replied_message_id_; + send_closure_later(notification_manager_actor_, &NotificationManager::on_binlog_events, + std::move(events.to_notification_manager)); - void do_run(Promise &&promise) final { - replied_message_id_ = - td_->messages_manager_->get_replied_message(dialog_id_, message_id_, get_tries() < 3, std::move(promise)); - } + send_closure_later(notification_settings_manager_actor_, &NotificationSettingsManager::on_binlog_events, + std::move(events.to_notification_settings_manager)); - void do_send_result() final { - send_result(td_->messages_manager_->get_message_object(replied_message_id_, "GetRepliedMessageRequest")); - } + send_closure(secret_chats_manager_, &SecretChatsManager::binlog_replay_finish); +} - public: - GetRepliedMessageRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id) - : RequestOnceActor(std::move(td), request_id), dialog_id_(dialog_id), message_id_(message_id) { - set_tries(3); // 1 to get initial message, 1 to get the reply and 1 for result - } -}; +void Td::init_options_and_network() { + VLOG(td_init) << "Create StateManager"; + state_manager_ = create_actor("State manager", create_reference()); + G()->set_state_manager(state_manager_.get()); -class GetMessageThreadRequest final : public RequestActor { - DialogId dialog_id_; - MessageId message_id_; + VLOG(td_init) << "Create OptionManager"; + option_manager_ = make_unique(this); + G()->set_option_manager(option_manager_.get()); - MessageThreadInfo message_thread_info_; + VLOG(td_init) << "Create ConnectionCreator"; + G()->set_connection_creator(create_actor("ConnectionCreator", create_reference())); - void do_run(Promise &&promise) final { - if (get_tries() < 2) { - promise.set_value(std::move(message_thread_info_)); - return; + complete_pending_preauthentication_requests([](int32 id) { + switch (id) { + case td_api::setNetworkType::ID: + case td_api::addProxy::ID: + case td_api::editProxy::ID: + case td_api::enableProxy::ID: + case td_api::disableProxy::ID: + case td_api::removeProxy::ID: + case td_api::getProxies::ID: + case td_api::getProxyLink::ID: + return true; + default: + return false; } - td_->messages_manager_->get_message_thread(dialog_id_, message_id_, std::move(promise)); - } - - void do_set_result(MessageThreadInfo &&result) final { - message_thread_info_ = std::move(result); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_message_thread_info_object(message_thread_info_)); - } - - public: - GetMessageThreadRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id) - : RequestActor(std::move(td), request_id), dialog_id_(dialog_id), message_id_(message_id) { - } -}; - -class GetChatPinnedMessageRequest final : public RequestOnceActor { - DialogId dialog_id_; - - MessageId pinned_message_id_; - - void do_run(Promise &&promise) final { - pinned_message_id_ = td_->messages_manager_->get_dialog_pinned_message(dialog_id_, std::move(promise)); - } - - void do_send_result() final { - send_result( - td_->messages_manager_->get_message_object({dialog_id_, pinned_message_id_}, "GetChatPinnedMessageRequest")); - } - - public: - GetChatPinnedMessageRequest(ActorShared td, uint64 request_id, int64 dialog_id) - : RequestOnceActor(std::move(td), request_id), dialog_id_(dialog_id) { - set_tries(3); // 1 to get pinned_message_id, 1 to get the message and 1 for result - } -}; - -class GetCallbackQueryMessageRequest final : public RequestOnceActor { - DialogId dialog_id_; - MessageId message_id_; - int64 callback_query_id_; - - void do_run(Promise &&promise) final { - td_->messages_manager_->get_callback_query_message(dialog_id_, message_id_, callback_query_id_, std::move(promise)); - } - - void do_send_result() final { - send_result( - td_->messages_manager_->get_message_object({dialog_id_, message_id_}, "GetCallbackQueryMessageRequest")); - } - - public: - GetCallbackQueryMessageRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, - int64 callback_query_id) - : RequestOnceActor(std::move(td), request_id) - , dialog_id_(dialog_id) - , message_id_(message_id) - , callback_query_id_(callback_query_id) { - } -}; - -class GetMessagesRequest final : public RequestOnceActor { - DialogId dialog_id_; - vector message_ids_; - - void do_run(Promise &&promise) final { - td_->messages_manager_->get_messages(dialog_id_, message_ids_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_messages_object(-1, dialog_id_, message_ids_, false, "GetMessagesRequest")); - } - - public: - GetMessagesRequest(ActorShared td, uint64 request_id, int64 dialog_id, const vector &message_ids) - : RequestOnceActor(std::move(td), request_id) - , dialog_id_(dialog_id) - , message_ids_(MessageId::get_message_ids(message_ids)) { - } -}; + }); -class GetMessageEmbeddingCodeRequest final : public RequestActor<> { - FullMessageId full_message_id_; - bool for_group_; + VLOG(td_init) << "Create TempAuthKeyWatchdog"; + G()->set_temp_auth_key_watchdog(create_actor("TempAuthKeyWatchdog", create_reference())); - string html_; + VLOG(td_init) << "Create ConfigManager"; + config_manager_ = create_actor("ConfigManager", create_reference()); + G()->set_config_manager(config_manager_.get()); - void do_run(Promise &&promise) final { - html_ = td_->messages_manager_->get_message_embedding_code(full_message_id_, for_group_, std::move(promise)); - } + VLOG(td_init) << "Create OnlineManager"; + online_manager_ = make_unique(this, create_reference()); + online_manager_actor_ = register_actor("OnlineManager", online_manager_.get()); + G()->set_online_manager(online_manager_actor_.get()); +} - void do_send_result() final { - send_result(make_tl_object(html_)); - } +void Td::init_file_manager() { + VLOG(td_init) << "Create FileManager"; + class FileManagerContext final : public FileManager::Context { + public: + explicit FileManagerContext(Td *td) : td_(td) { + } - public: - GetMessageEmbeddingCodeRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, - bool for_group) - : RequestActor(std::move(td), request_id) - , full_message_id_(DialogId(dialog_id), MessageId(message_id)) - , for_group_(for_group) { - } -}; + bool need_notify_on_new_files() final { + return !td_->auth_manager_->is_bot(); + } -class GetMessageLinkInfoRequest final : public RequestActor { - string url_; + void on_new_file(int64 size, int64 real_size, int32 cnt) final { + send_closure(G()->storage_manager(), &StorageManager::on_new_file, size, real_size, cnt); + } - MessageLinkInfo message_link_info_; + void on_file_updated(FileId file_id) final { + send_closure(G()->td(), &Td::send_update, + make_tl_object(td_->file_manager_->get_file_object(file_id))); + } - void do_run(Promise &&promise) final { - if (get_tries() < 2) { - promise.set_value(std::move(message_link_info_)); - return; + bool add_file_source(FileId file_id, FileSourceId file_source_id) final { + return td_->file_reference_manager_->add_file_source(file_id, file_source_id); } - td_->messages_manager_->get_message_link_info(url_, std::move(promise)); - } - void do_set_result(MessageLinkInfo &&result) final { - message_link_info_ = std::move(result); - } + bool remove_file_source(FileId file_id, FileSourceId file_source_id) final { + return td_->file_reference_manager_->remove_file_source(file_id, file_source_id); + } - void do_send_result() final { - send_result(td_->messages_manager_->get_message_link_info_object(message_link_info_)); - } + void on_merge_files(FileId to_file_id, FileId from_file_id) final { + td_->file_reference_manager_->merge(to_file_id, from_file_id); + } - public: - GetMessageLinkInfoRequest(ActorShared td, uint64 request_id, string url) - : RequestActor(std::move(td), request_id), url_(std::move(url)) { - } -}; + vector get_some_file_sources(FileId file_id) final { + return td_->file_reference_manager_->get_some_file_sources(file_id); + } -class EditMessageTextRequest final : public RequestOnceActor { - FullMessageId full_message_id_; - tl_object_ptr reply_markup_; - tl_object_ptr input_message_content_; + void repair_file_reference(FileId file_id, Promise promise) final { + send_closure(G()->file_reference_manager(), &FileReferenceManager::repair_file_reference, file_id, + std::move(promise)); + } - void do_run(Promise &&promise) final { - td_->messages_manager_->edit_message_text(full_message_id_, std::move(reply_markup_), - std::move(input_message_content_), std::move(promise)); - } + void reload_photo(PhotoSizeSource source, Promise promise) final { + FileReferenceManager::reload_photo(std::move(source), std::move(promise)); + } - void do_send_result() final { - send_result(td_->messages_manager_->get_message_object(full_message_id_, "EditMessageTextRequest")); - } + bool keep_exact_remote_location() final { + return !td_->auth_manager_->is_bot(); + } - public: - EditMessageTextRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, - tl_object_ptr reply_markup, - tl_object_ptr input_message_content) - : RequestOnceActor(std::move(td), request_id) - , full_message_id_(DialogId(dialog_id), MessageId(message_id)) - , reply_markup_(std::move(reply_markup)) - , input_message_content_(std::move(input_message_content)) { - } -}; - -class EditMessageLiveLocationRequest final : public RequestOnceActor { - FullMessageId full_message_id_; - tl_object_ptr reply_markup_; - tl_object_ptr location_; - int32 heading_; - int32 proximity_alert_radius_; - - void do_run(Promise &&promise) final { - td_->messages_manager_->edit_message_live_location(full_message_id_, std::move(reply_markup_), std::move(location_), - heading_, proximity_alert_radius_, std::move(promise)); - } + ActorShared<> create_reference() final { + return td_->create_reference(); + } - void do_send_result() final { - send_result(td_->messages_manager_->get_message_object(full_message_id_, "EditMessageLiveLocationRequest")); - } + private: + Td *td_; + }; - public: - EditMessageLiveLocationRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, - tl_object_ptr reply_markup, - tl_object_ptr location, int32 heading, int32 proximity_alert_radius) - : RequestOnceActor(std::move(td), request_id) - , full_message_id_(DialogId(dialog_id), MessageId(message_id)) - , reply_markup_(std::move(reply_markup)) - , location_(std::move(location)) - , heading_(heading) - , proximity_alert_radius_(proximity_alert_radius) { - } -}; + file_manager_ = make_unique(make_unique(this)); + file_manager_actor_ = register_actor("FileManager", file_manager_.get()); + file_manager_->init_actor(); + G()->set_file_manager(file_manager_actor_.get()); -class EditMessageMediaRequest final : public RequestOnceActor { - FullMessageId full_message_id_; - tl_object_ptr reply_markup_; - tl_object_ptr input_message_content_; + file_reference_manager_ = make_unique(create_reference()); + file_reference_manager_actor_ = register_actor("FileReferenceManager", file_reference_manager_.get()); + G()->set_file_reference_manager(file_reference_manager_actor_.get()); +} - void do_run(Promise &&promise) final { - td_->messages_manager_->edit_message_media(full_message_id_, std::move(reply_markup_), - std::move(input_message_content_), std::move(promise)); - } +void Td::init_non_actor_managers() { + VLOG(td_init) << "Create Managers"; + audios_manager_ = make_unique(this); + callback_queries_manager_ = make_unique(this); + documents_manager_ = make_unique(this); + videos_manager_ = make_unique(this); +} - void do_send_result() final { - send_result(td_->messages_manager_->get_message_object(full_message_id_, "EditMessageMediaRequest")); - } - - public: - EditMessageMediaRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, - tl_object_ptr reply_markup, - tl_object_ptr input_message_content) - : RequestOnceActor(std::move(td), request_id) - , full_message_id_(DialogId(dialog_id), MessageId(message_id)) - , reply_markup_(std::move(reply_markup)) - , input_message_content_(std::move(input_message_content)) { - } -}; - -class EditMessageCaptionRequest final : public RequestOnceActor { - FullMessageId full_message_id_; - tl_object_ptr reply_markup_; - tl_object_ptr caption_; - - void do_run(Promise &&promise) final { - td_->messages_manager_->edit_message_caption(full_message_id_, std::move(reply_markup_), std::move(caption_), - std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_message_object(full_message_id_, "EditMessageCaptionRequest")); - } - - public: - EditMessageCaptionRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, - tl_object_ptr reply_markup, - tl_object_ptr caption) - : RequestOnceActor(std::move(td), request_id) - , full_message_id_(DialogId(dialog_id), MessageId(message_id)) - , reply_markup_(std::move(reply_markup)) - , caption_(std::move(caption)) { - } -}; - -class EditMessageReplyMarkupRequest final : public RequestOnceActor { - FullMessageId full_message_id_; - tl_object_ptr reply_markup_; - - void do_run(Promise &&promise) final { - td_->messages_manager_->edit_message_reply_markup(full_message_id_, std::move(reply_markup_), std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_message_object(full_message_id_, "EditMessageReplyMarkupRequest")); - } - - public: - EditMessageReplyMarkupRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, - tl_object_ptr reply_markup) - : RequestOnceActor(std::move(td), request_id) - , full_message_id_(DialogId(dialog_id), MessageId(message_id)) - , reply_markup_(std::move(reply_markup)) { - } -}; - -class GetChatHistoryRequest final : public RequestActor<> { - DialogId dialog_id_; - MessageId from_message_id_; - int32 offset_; - int32 limit_; - bool only_local_; - - tl_object_ptr messages_; - - void do_run(Promise &&promise) final { - messages_ = td_->messages_manager_->get_dialog_history(dialog_id_, from_message_id_, offset_, limit_, - get_tries() - 1, only_local_, std::move(promise)); - } - - void do_send_result() final { - send_result(std::move(messages_)); - } - - public: - GetChatHistoryRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 from_message_id, int32 offset, - int32 limit, bool only_local) - : RequestActor(std::move(td), request_id) - , dialog_id_(dialog_id) - , from_message_id_(from_message_id) - , offset_(offset) - , limit_(limit) - , only_local_(only_local) { - if (!only_local_) { - set_tries(4); - } - } -}; - -class GetMessageThreadHistoryRequest final : public RequestActor<> { - DialogId dialog_id_; - MessageId message_id_; - MessageId from_message_id_; - int32 offset_; - int32 limit_; - int64 random_id_; - - std::pair> messages_; - - void do_run(Promise &&promise) final { - messages_ = td_->messages_manager_->get_message_thread_history(dialog_id_, message_id_, from_message_id_, offset_, - limit_, random_id_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_messages_object(-1, messages_.first, messages_.second, true, - "GetMessageThreadHistoryRequest")); - } - - public: - GetMessageThreadHistoryRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 message_id, - int64 from_message_id, int32 offset, int32 limit) - : RequestActor(std::move(td), request_id) - , dialog_id_(dialog_id) - , message_id_(message_id) - , from_message_id_(from_message_id) - , offset_(offset) - , limit_(limit) - , random_id_(0) { - set_tries(3); - } -}; - -class GetChatMessageCalendarRequest final : public RequestActor<> { - DialogId dialog_id_; - MessageId from_message_id_; - MessageSearchFilter filter_; - int64 random_id_; - - td_api::object_ptr calendar_; - - void do_run(Promise &&promise) final { - calendar_ = td_->messages_manager_->get_dialog_message_calendar(dialog_id_, from_message_id_, filter_, random_id_, - get_tries() == 3, std::move(promise)); - } - - void do_send_result() final { - send_result(std::move(calendar_)); - } - - public: - GetChatMessageCalendarRequest(ActorShared td, uint64 request_id, int64 dialog_id, int64 from_message_id, - tl_object_ptr filter) - : RequestActor(std::move(td), request_id) - , dialog_id_(dialog_id) - , from_message_id_(from_message_id) - , filter_(get_message_search_filter(filter)) - , random_id_(0) { - set_tries(3); - } -}; - -class SearchChatMessagesRequest final : public RequestActor<> { - DialogId dialog_id_; - string query_; - td_api::object_ptr sender_id_; - MessageId from_message_id_; - int32 offset_; - int32 limit_; - MessageSearchFilter filter_; - MessageId top_thread_message_id_; - int64 random_id_; - - MessagesManager::FoundDialogMessages messages_; - - void do_run(Promise &&promise) final { - messages_ = td_->messages_manager_->search_dialog_messages(dialog_id_, query_, sender_id_, from_message_id_, - offset_, limit_, filter_, top_thread_message_id_, - random_id_, get_tries() == 3, std::move(promise)); - } - - void do_send_result() final { - send_result( - td_->messages_manager_->get_found_chat_messages_object(dialog_id_, messages_, "SearchChatMessagesRequest")); - } - - void do_send_error(Status &&status) final { - if (status.message() == "SEARCH_QUERY_EMPTY") { - messages_ = {}; - return do_send_result(); - } - send_error(std::move(status)); - } - - public: - SearchChatMessagesRequest(ActorShared td, uint64 request_id, int64 dialog_id, string query, - td_api::object_ptr sender_id, int64 from_message_id, int32 offset, - int32 limit, tl_object_ptr filter, int64 message_thread_id) - : RequestActor(std::move(td), request_id) - , dialog_id_(dialog_id) - , query_(std::move(query)) - , sender_id_(std::move(sender_id)) - , from_message_id_(from_message_id) - , offset_(offset) - , limit_(limit) - , filter_(get_message_search_filter(filter)) - , top_thread_message_id_(message_thread_id) - , random_id_(0) { - set_tries(3); - } -}; - -class SearchSecretMessagesRequest final : public RequestActor<> { - DialogId dialog_id_; - string query_; - string offset_; - int32 limit_; - MessageSearchFilter filter_; - int64 random_id_; - - MessagesManager::FoundMessages found_messages_; - - void do_run(Promise &&promise) final { - found_messages_ = td_->messages_manager_->offline_search_messages(dialog_id_, query_, offset_, limit_, filter_, - random_id_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_found_messages_object(found_messages_, "SearchSecretMessagesRequest")); - } - - public: - SearchSecretMessagesRequest(ActorShared td, uint64 request_id, int64 dialog_id, string query, string offset, - int32 limit, tl_object_ptr filter) - : RequestActor(std::move(td), request_id) - , dialog_id_(dialog_id) - , query_(std::move(query)) - , offset_(std::move(offset)) - , limit_(limit) - , filter_(get_message_search_filter(filter)) - , random_id_(0) { - } -}; - -class SearchMessagesRequest final : public RequestActor<> { - FolderId folder_id_; - bool ignore_folder_id_; - string query_; - string offset_; - int32 limit_; - MessageSearchFilter filter_; - int32 min_date_; - int32 max_date_; - int64 random_id_; - - MessagesManager::FoundMessages messages_; - - void do_run(Promise &&promise) final { - messages_ = td_->messages_manager_->search_messages(folder_id_, ignore_folder_id_, query_, offset_, limit_, filter_, - min_date_, max_date_, random_id_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_found_messages_object(messages_, "SearchMessagesRequest")); - } - - void do_send_error(Status &&status) final { - if (status.message() == "SEARCH_QUERY_EMPTY") { - messages_ = {}; - return do_send_result(); - } - send_error(std::move(status)); - } - - public: - SearchMessagesRequest(ActorShared td, uint64 request_id, FolderId folder_id, bool ignore_folder_id, string query, - string offset, int32 limit, tl_object_ptr &&filter, - int32 min_date, int32 max_date) - : RequestActor(std::move(td), request_id) - , folder_id_(folder_id) - , ignore_folder_id_(ignore_folder_id) - , query_(std::move(query)) - , offset_(std::move(offset)) - , limit_(limit) - , filter_(get_message_search_filter(filter)) - , min_date_(min_date) - , max_date_(max_date) - , random_id_(0) { - } -}; - -class SearchCallMessagesRequest final : public RequestActor<> { - string offset_; - int32 limit_; - bool only_missed_; - int64 random_id_; - - MessagesManager::FoundMessages messages_; - - void do_run(Promise &&promise) final { - messages_ = td_->messages_manager_->search_call_messages(offset_, limit_, only_missed_, random_id_, - get_tries() == 3, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_found_messages_object(messages_, "SearchCallMessagesRequest")); - } - - public: - SearchCallMessagesRequest(ActorShared td, uint64 request_id, string offset, int32 limit, bool only_missed) - : RequestActor(std::move(td), request_id) - , offset_(std::move(offset)) - , limit_(limit) - , only_missed_(only_missed) - , random_id_(0) { - set_tries(3); - } -}; - -class GetActiveLiveLocationMessagesRequest final : public RequestActor<> { - vector full_message_ids_; - - void do_run(Promise &&promise) final { - full_message_ids_ = td_->messages_manager_->get_active_live_location_messages(std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_messages_object(-1, full_message_ids_, true, - "GetActiveLiveLocationMessagesRequest")); - } - - public: - GetActiveLiveLocationMessagesRequest(ActorShared td, uint64 request_id) - : RequestActor(std::move(td), request_id) { - } -}; - -class GetChatMessageByDateRequest final : public RequestOnceActor { - DialogId dialog_id_; - int32 date_; - - int64 random_id_; - - void do_run(Promise &&promise) final { - random_id_ = td_->messages_manager_->get_dialog_message_by_date(dialog_id_, date_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_dialog_message_by_date_object(random_id_)); - } - - public: - GetChatMessageByDateRequest(ActorShared td, uint64 request_id, int64 dialog_id, int32 date) - : RequestOnceActor(std::move(td), request_id), dialog_id_(dialog_id), date_(date), random_id_(0) { - } -}; - -class GetChatScheduledMessagesRequest final : public RequestActor<> { - DialogId dialog_id_; - - vector message_ids_; - - void do_run(Promise &&promise) final { - message_ids_ = - td_->messages_manager_->get_dialog_scheduled_messages(dialog_id_, get_tries() < 2, false, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_messages_object(-1, dialog_id_, message_ids_, true, - "GetChatScheduledMessagesRequest")); - } - - public: - GetChatScheduledMessagesRequest(ActorShared td, uint64 request_id, int64 dialog_id) - : RequestActor(std::move(td), request_id), dialog_id_(dialog_id) { - set_tries(4); - } -}; - -class GetWebPageInstantViewRequest final : public RequestActor { - string url_; - bool force_full_; - - WebPageId web_page_id_; - - void do_run(Promise &&promise) final { - if (get_tries() < 2) { - promise.set_value(std::move(web_page_id_)); - return; - } - td_->web_pages_manager_->get_web_page_instant_view(url_, force_full_, std::move(promise)); - } - - void do_set_result(WebPageId &&result) final { - web_page_id_ = result; - } - - void do_send_result() final { - send_result(td_->web_pages_manager_->get_web_page_instant_view_object(web_page_id_)); - } - - public: - GetWebPageInstantViewRequest(ActorShared td, uint64 request_id, string url, bool force_full) - : RequestActor(std::move(td), request_id), url_(std::move(url)), force_full_(force_full) { - } -}; - -class CreateChatRequest final : public RequestActor<> { - DialogId dialog_id_; - bool force_; - - void do_run(Promise &&promise) final { - td_->messages_manager_->create_dialog(dialog_id_, force_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->messages_manager_->get_chat_object(dialog_id_)); - } - - public: - CreateChatRequest(ActorShared td, uint64 request_id, DialogId dialog_id, bool force) - : RequestActor<>(std::move(td), request_id), dialog_id_(dialog_id), force_(force) { - } -}; - -class CreateNewGroupChatRequest final : public RequestActor<> { - vector user_ids_; - string title_; - MessageTtl message_ttl_; - int64 random_id_; - - DialogId dialog_id_; - - void do_run(Promise &&promise) final { - dialog_id_ = - td_->messages_manager_->create_new_group_chat(user_ids_, title_, message_ttl_, random_id_, std::move(promise)); - } - - void do_send_result() final { - CHECK(dialog_id_.is_valid()); - send_result(td_->messages_manager_->get_chat_object(dialog_id_)); - } - - public: - CreateNewGroupChatRequest(ActorShared td, uint64 request_id, vector user_ids, string title, - int32 message_ttl) - : RequestActor(std::move(td), request_id) - , user_ids_(std::move(user_ids)) - , title_(std::move(title)) - , message_ttl_(message_ttl) - , random_id_(0) { - } -}; - -class CreateNewSecretChatRequest final : public RequestActor { - UserId user_id_; - SecretChatId secret_chat_id_; - - void do_run(Promise &&promise) final { - if (get_tries() < 2) { - promise.set_value(std::move(secret_chat_id_)); - return; - } - td_->messages_manager_->create_new_secret_chat(user_id_, std::move(promise)); - } - - void do_set_result(SecretChatId &&result) final { - secret_chat_id_ = result; - LOG(INFO) << "New " << secret_chat_id_ << " created"; - } - - void do_send_result() final { - CHECK(secret_chat_id_.is_valid()); - // SecretChatActor will send this update by itself - // But since the update may still be on its way, we will update essential fields here. - td_->contacts_manager_->on_update_secret_chat( - secret_chat_id_, 0 /* no access_hash */, user_id_, SecretChatState::Unknown, true /* it is outbound chat */, - -1 /* unknown TTL */, 0 /* unknown creation date */, "" /* no key_hash */, 0, FolderId()); - DialogId dialog_id(secret_chat_id_); - td_->messages_manager_->force_create_dialog(dialog_id, "create new secret chat", true); - send_result(td_->messages_manager_->get_chat_object(dialog_id)); - } - - public: - CreateNewSecretChatRequest(ActorShared td, uint64 request_id, int64 user_id) - : RequestActor(std::move(td), request_id), user_id_(user_id) { - } -}; - -class CreateNewSupergroupChatRequest final : public RequestActor<> { - string title_; - bool is_forum_; - bool is_megagroup_; - string description_; - DialogLocation location_; - bool for_import_; - MessageTtl message_ttl_; - int64 random_id_; - - DialogId dialog_id_; - - void do_run(Promise &&promise) final { - dialog_id_ = - td_->messages_manager_->create_new_channel_chat(title_, is_forum_, is_megagroup_, description_, location_, - for_import_, message_ttl_, random_id_, std::move(promise)); - } - - void do_send_result() final { - CHECK(dialog_id_.is_valid()); - send_result(td_->messages_manager_->get_chat_object(dialog_id_)); - } - - public: - CreateNewSupergroupChatRequest(ActorShared td, uint64 request_id, string title, bool is_forum, bool is_megagroup, - string description, td_api::object_ptr &&location, - bool for_import, int32 message_ttl) - : RequestActor(std::move(td), request_id) - , title_(std::move(title)) - , is_forum_(is_forum) - , is_megagroup_(is_megagroup) - , description_(std::move(description)) - , location_(std::move(location)) - , for_import_(for_import) - , message_ttl_(message_ttl) - , random_id_(0) { - } -}; - -class UpgradeGroupChatToSupergroupChatRequest final : public RequestActor<> { - string title_; - DialogId dialog_id_; - - DialogId result_dialog_id_; - - void do_run(Promise &&promise) final { - result_dialog_id_ = td_->messages_manager_->migrate_dialog_to_megagroup(dialog_id_, std::move(promise)); - } - - void do_send_result() final { - CHECK(result_dialog_id_.is_valid()); - send_result(td_->messages_manager_->get_chat_object(result_dialog_id_)); - } - - public: - UpgradeGroupChatToSupergroupChatRequest(ActorShared td, uint64 request_id, int64 dialog_id) - : RequestActor(std::move(td), request_id), dialog_id_(dialog_id) { - } -}; - -class CheckChatInviteLinkRequest final : public RequestActor<> { - string invite_link_; - - void do_run(Promise &&promise) final { - td_->contacts_manager_->check_dialog_invite_link(invite_link_, get_tries() < 2, std::move(promise)); - } - - void do_send_result() final { - auto result = td_->contacts_manager_->get_chat_invite_link_info_object(invite_link_); - CHECK(result != nullptr); - send_result(std::move(result)); - } - - public: - CheckChatInviteLinkRequest(ActorShared td, uint64 request_id, string invite_link) - : RequestActor(std::move(td), request_id), invite_link_(std::move(invite_link)) { - } -}; - -class JoinChatByInviteLinkRequest final : public RequestActor { - string invite_link_; - - DialogId dialog_id_; - - void do_run(Promise &&promise) final { - if (get_tries() < 2) { - promise.set_value(std::move(dialog_id_)); - return; - } - td_->contacts_manager_->import_dialog_invite_link(invite_link_, std::move(promise)); - } - - void do_set_result(DialogId &&result) final { - dialog_id_ = result; - } - - void do_send_result() final { - CHECK(dialog_id_.is_valid()); - td_->messages_manager_->force_create_dialog(dialog_id_, "join chat via an invite link"); - send_result(td_->messages_manager_->get_chat_object(dialog_id_)); - } - - public: - JoinChatByInviteLinkRequest(ActorShared td, uint64 request_id, string invite_link) - : RequestActor(std::move(td), request_id), invite_link_(std::move(invite_link)) { - } -}; - -class ImportContactsRequest final : public RequestActor<> { - vector contacts_; - int64 random_id_; - - std::pair, vector> imported_contacts_; - - void do_run(Promise &&promise) final { - imported_contacts_ = td_->contacts_manager_->import_contacts(contacts_, random_id_, std::move(promise)); - } - - void do_send_result() final { - CHECK(imported_contacts_.first.size() == contacts_.size()); - CHECK(imported_contacts_.second.size() == contacts_.size()); - send_result(make_tl_object(transform(imported_contacts_.first, - [this](UserId user_id) { - return td_->contacts_manager_->get_user_id_object( - user_id, "ImportContactsRequest"); - }), - std::move(imported_contacts_.second))); - } - - public: - ImportContactsRequest(ActorShared td, uint64 request_id, vector &&contacts) - : RequestActor(std::move(td), request_id), contacts_(std::move(contacts)), random_id_(0) { - set_tries(3); // load_contacts + import_contacts - } -}; - -class SearchContactsRequest final : public RequestActor<> { - string query_; - int32 limit_; - - std::pair> user_ids_; - - void do_run(Promise &&promise) final { - user_ids_ = td_->contacts_manager_->search_contacts(query_, limit_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->contacts_manager_->get_users_object(user_ids_.first, user_ids_.second)); - } - - public: - SearchContactsRequest(ActorShared td, uint64 request_id, string query, int32 limit) - : RequestActor(std::move(td), request_id), query_(std::move(query)), limit_(limit) { - } -}; - -class RemoveContactsRequest final : public RequestActor<> { - vector user_ids_; - - void do_run(Promise &&promise) final { - td_->contacts_manager_->remove_contacts(user_ids_, std::move(promise)); - } - - public: - RemoveContactsRequest(ActorShared td, uint64 request_id, vector &&user_ids) - : RequestActor(std::move(td), request_id), user_ids_(std::move(user_ids)) { - set_tries(3); // load_contacts + delete_contacts - } -}; - -class GetImportedContactCountRequest final : public RequestActor<> { - int32 imported_contact_count_ = 0; - - void do_run(Promise &&promise) final { - imported_contact_count_ = td_->contacts_manager_->get_imported_contact_count(std::move(promise)); - } - - void do_send_result() final { - send_result(td_api::make_object(imported_contact_count_)); - } - - public: - GetImportedContactCountRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { - } -}; - -class ChangeImportedContactsRequest final : public RequestActor<> { - vector contacts_; - size_t contacts_size_; - int64 random_id_; - - std::pair, vector> imported_contacts_; - - void do_run(Promise &&promise) final { - imported_contacts_ = td_->contacts_manager_->change_imported_contacts(contacts_, random_id_, std::move(promise)); - } - - void do_send_result() final { - CHECK(imported_contacts_.first.size() == contacts_size_); - CHECK(imported_contacts_.second.size() == contacts_size_); - send_result(make_tl_object(transform(imported_contacts_.first, - [this](UserId user_id) { - return td_->contacts_manager_->get_user_id_object( - user_id, "ChangeImportedContactsRequest"); - }), - std::move(imported_contacts_.second))); - } - - public: - ChangeImportedContactsRequest(ActorShared td, uint64 request_id, vector &&contacts) - : RequestActor(std::move(td), request_id) - , contacts_(std::move(contacts)) - , contacts_size_(contacts_.size()) - , random_id_(0) { - set_tries(4); // load_contacts + load_local_contacts + (import_contacts + delete_contacts) - } -}; - -class GetRecentInlineBotsRequest final : public RequestActor<> { - vector user_ids_; - - void do_run(Promise &&promise) final { - user_ids_ = td_->inline_queries_manager_->get_recent_inline_bots(std::move(promise)); - } - - void do_send_result() final { - send_result(td_->contacts_manager_->get_users_object(-1, user_ids_)); - } - - public: - GetRecentInlineBotsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { - } -}; - -class GetChatNotificationSettingsExceptionsRequest final : public RequestActor<> { - NotificationSettingsScope scope_; - bool filter_scope_; - bool compare_sound_; - - vector dialog_ids_; - - void do_run(Promise &&promise) final { - dialog_ids_ = td_->messages_manager_->get_dialog_notification_settings_exceptions( - scope_, filter_scope_, compare_sound_, get_tries() < 3, std::move(promise)); - } - - void do_send_result() final { - send_result( - td_->messages_manager_->get_chats_object(-1, dialog_ids_, "GetChatNotificationSettingsExceptionsRequest")); - } - - public: - GetChatNotificationSettingsExceptionsRequest(ActorShared td, uint64 request_id, NotificationSettingsScope scope, - bool filter_scope, bool compare_sound) - : RequestActor(std::move(td), request_id) - , scope_(scope) - , filter_scope_(filter_scope) - , compare_sound_(compare_sound) { - set_tries(3); - } -}; - -class GetScopeNotificationSettingsRequest final : public RequestActor<> { - NotificationSettingsScope scope_; - - const ScopeNotificationSettings *notification_settings_ = nullptr; - - void do_run(Promise &&promise) final { - notification_settings_ = - td_->notification_settings_manager_->get_scope_notification_settings(scope_, std::move(promise)); - } - - void do_send_result() final { - CHECK(notification_settings_ != nullptr); - send_result(get_scope_notification_settings_object(notification_settings_)); - } - - public: - GetScopeNotificationSettingsRequest(ActorShared td, uint64 request_id, NotificationSettingsScope scope) - : RequestActor(std::move(td), request_id), scope_(scope) { - } -}; - -class GetStickersRequest final : public RequestActor<> { - StickerType sticker_type_; - string query_; - int32 limit_; - DialogId dialog_id_; - - vector sticker_ids_; - - void do_run(Promise &&promise) final { - sticker_ids_ = td_->stickers_manager_->get_stickers(sticker_type_, query_, limit_, dialog_id_, get_tries() < 2, - std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_stickers_object(sticker_ids_)); - } - - public: - GetStickersRequest(ActorShared td, uint64 request_id, StickerType sticker_type, string &&query, int32 limit, - int64 dialog_id) - : RequestActor(std::move(td), request_id) - , sticker_type_(sticker_type) - , query_(std::move(query)) - , limit_(limit) - , dialog_id_(dialog_id) { - set_tries(4); - } -}; - -class GetInstalledStickerSetsRequest final : public RequestActor<> { - StickerType sticker_type_; - - vector sticker_set_ids_; - - void do_run(Promise &&promise) final { - sticker_set_ids_ = td_->stickers_manager_->get_installed_sticker_sets(sticker_type_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_sticker_sets_object(-1, sticker_set_ids_, 1)); - } - - public: - GetInstalledStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type) - : RequestActor(std::move(td), request_id), sticker_type_(sticker_type) { - } -}; - -class GetArchivedStickerSetsRequest final : public RequestActor<> { - StickerType sticker_type_; - StickerSetId offset_sticker_set_id_; - int32 limit_; - - int32 total_count_ = -1; - vector sticker_set_ids_; - - void do_run(Promise &&promise) final { - std::tie(total_count_, sticker_set_ids_) = td_->stickers_manager_->get_archived_sticker_sets( - sticker_type_, offset_sticker_set_id_, limit_, get_tries() < 2, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_sticker_sets_object(total_count_, sticker_set_ids_, 1)); - } - - public: - GetArchivedStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type, - int64 offset_sticker_set_id, int32 limit) - : RequestActor(std::move(td), request_id) - , sticker_type_(sticker_type) - , offset_sticker_set_id_(offset_sticker_set_id) - , limit_(limit) { - } -}; - -class GetTrendingStickerSetsRequest final : public RequestActor<> { - td_api::object_ptr result_; - StickerType sticker_type_; - int32 offset_; - int32 limit_; - - void do_run(Promise &&promise) final { - result_ = td_->stickers_manager_->get_featured_sticker_sets(sticker_type_, offset_, limit_, std::move(promise)); - } - - void do_send_result() final { - send_result(std::move(result_)); - } - - public: - GetTrendingStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type, int32 offset, - int32 limit) - : RequestActor(std::move(td), request_id), sticker_type_(sticker_type), offset_(offset), limit_(limit) { - set_tries(3); - } -}; - -class GetAttachedStickerSetsRequest final : public RequestActor<> { - FileId file_id_; - - vector sticker_set_ids_; - - void do_run(Promise &&promise) final { - sticker_set_ids_ = td_->stickers_manager_->get_attached_sticker_sets(file_id_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_sticker_sets_object(-1, sticker_set_ids_, 5)); - } - - public: - GetAttachedStickerSetsRequest(ActorShared td, uint64 request_id, int32 file_id) - : RequestActor(std::move(td), request_id), file_id_(file_id, 0) { - } -}; - -class GetStickerSetRequest final : public RequestActor<> { - StickerSetId set_id_; - - StickerSetId sticker_set_id_; - - void do_run(Promise &&promise) final { - sticker_set_id_ = td_->stickers_manager_->get_sticker_set(set_id_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_sticker_set_object(sticker_set_id_)); - } - - public: - GetStickerSetRequest(ActorShared td, uint64 request_id, int64 set_id) - : RequestActor(std::move(td), request_id), set_id_(set_id) { - set_tries(3); - } -}; - -class SearchStickerSetRequest final : public RequestActor<> { - string name_; - - StickerSetId sticker_set_id_; - - void do_run(Promise &&promise) final { - sticker_set_id_ = td_->stickers_manager_->search_sticker_set(name_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_sticker_set_object(sticker_set_id_)); - } - - public: - SearchStickerSetRequest(ActorShared td, uint64 request_id, string &&name) - : RequestActor(std::move(td), request_id), name_(std::move(name)) { - set_tries(3); - } -}; - -class SearchInstalledStickerSetsRequest final : public RequestActor<> { - StickerType sticker_type_; - string query_; - int32 limit_; - - std::pair> sticker_set_ids_; - - void do_run(Promise &&promise) final { - sticker_set_ids_ = - td_->stickers_manager_->search_installed_sticker_sets(sticker_type_, query_, limit_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_sticker_sets_object(sticker_set_ids_.first, sticker_set_ids_.second, 5)); - } - - public: - SearchInstalledStickerSetsRequest(ActorShared td, uint64 request_id, StickerType sticker_type, string &&query, - int32 limit) - : RequestActor(std::move(td), request_id), sticker_type_(sticker_type), query_(std::move(query)), limit_(limit) { - } -}; - -class SearchStickerSetsRequest final : public RequestActor<> { - string query_; - - vector sticker_set_ids_; - - void do_run(Promise &&promise) final { - sticker_set_ids_ = td_->stickers_manager_->search_sticker_sets(query_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_sticker_sets_object(-1, sticker_set_ids_, 5)); - } - - public: - SearchStickerSetsRequest(ActorShared td, uint64 request_id, string &&query) - : RequestActor(std::move(td), request_id), query_(std::move(query)) { - } -}; - -class ChangeStickerSetRequest final : public RequestOnceActor { - StickerSetId set_id_; - bool is_installed_; - bool is_archived_; - - void do_run(Promise &&promise) final { - td_->stickers_manager_->change_sticker_set(set_id_, is_installed_, is_archived_, std::move(promise)); - } - - public: - ChangeStickerSetRequest(ActorShared td, uint64 request_id, int64 set_id, bool is_installed, bool is_archived) - : RequestOnceActor(std::move(td), request_id) - , set_id_(set_id) - , is_installed_(is_installed) - , is_archived_(is_archived) { - set_tries(4); - } -}; - -class UploadStickerFileRequest final : public RequestOnceActor { - UserId user_id_; - StickerFormat sticker_format_; - td_api::object_ptr input_file_; - - FileId file_id; - - void do_run(Promise &&promise) final { - file_id = td_->stickers_manager_->upload_sticker_file(user_id_, sticker_format_, input_file_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->file_manager_->get_file_object(file_id)); - } - - public: - UploadStickerFileRequest(ActorShared td, uint64 request_id, int64 user_id, StickerFormat sticker_format, - td_api::object_ptr input_file) - : RequestOnceActor(std::move(td), request_id) - , user_id_(user_id) - , sticker_format_(sticker_format) - , input_file_(std::move(input_file)) { - } -}; - -class GetRecentStickersRequest final : public RequestActor<> { - bool is_attached_; - - vector sticker_ids_; - - void do_run(Promise &&promise) final { - sticker_ids_ = td_->stickers_manager_->get_recent_stickers(is_attached_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_stickers_object(sticker_ids_)); - } - - public: - GetRecentStickersRequest(ActorShared td, uint64 request_id, bool is_attached) - : RequestActor(std::move(td), request_id), is_attached_(is_attached) { - } -}; - -class AddRecentStickerRequest final : public RequestActor<> { - bool is_attached_; - tl_object_ptr input_file_; - - void do_run(Promise &&promise) final { - td_->stickers_manager_->add_recent_sticker(is_attached_, input_file_, std::move(promise)); - } - - public: - AddRecentStickerRequest(ActorShared td, uint64 request_id, bool is_attached, - tl_object_ptr &&input_file) - : RequestActor(std::move(td), request_id), is_attached_(is_attached), input_file_(std::move(input_file)) { - set_tries(3); - } -}; - -class RemoveRecentStickerRequest final : public RequestActor<> { - bool is_attached_; - tl_object_ptr input_file_; - - void do_run(Promise &&promise) final { - td_->stickers_manager_->remove_recent_sticker(is_attached_, input_file_, std::move(promise)); - } - - public: - RemoveRecentStickerRequest(ActorShared td, uint64 request_id, bool is_attached, - tl_object_ptr &&input_file) - : RequestActor(std::move(td), request_id), is_attached_(is_attached), input_file_(std::move(input_file)) { - set_tries(3); - } -}; - -class ClearRecentStickersRequest final : public RequestActor<> { - bool is_attached_; - - void do_run(Promise &&promise) final { - td_->stickers_manager_->clear_recent_stickers(is_attached_, std::move(promise)); - } - - public: - ClearRecentStickersRequest(ActorShared td, uint64 request_id, bool is_attached) - : RequestActor(std::move(td), request_id), is_attached_(is_attached) { - set_tries(3); - } -}; - -class GetFavoriteStickersRequest final : public RequestActor<> { - vector sticker_ids_; - - void do_run(Promise &&promise) final { - sticker_ids_ = td_->stickers_manager_->get_favorite_stickers(std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_stickers_object(sticker_ids_)); - } - - public: - GetFavoriteStickersRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { - } -}; - -class AddFavoriteStickerRequest final : public RequestOnceActor { - tl_object_ptr input_file_; - - void do_run(Promise &&promise) final { - td_->stickers_manager_->add_favorite_sticker(input_file_, std::move(promise)); - } - - public: - AddFavoriteStickerRequest(ActorShared td, uint64 request_id, tl_object_ptr &&input_file) - : RequestOnceActor(std::move(td), request_id), input_file_(std::move(input_file)) { - set_tries(3); - } -}; - -class RemoveFavoriteStickerRequest final : public RequestOnceActor { - tl_object_ptr input_file_; - - void do_run(Promise &&promise) final { - td_->stickers_manager_->remove_favorite_sticker(input_file_, std::move(promise)); - } - - public: - RemoveFavoriteStickerRequest(ActorShared td, uint64 request_id, tl_object_ptr &&input_file) - : RequestOnceActor(std::move(td), request_id), input_file_(std::move(input_file)) { - set_tries(3); - } -}; - -class GetStickerEmojisRequest final : public RequestActor<> { - tl_object_ptr input_file_; - - vector emojis_; - - void do_run(Promise &&promise) final { - emojis_ = td_->stickers_manager_->get_sticker_emojis(input_file_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_api::make_object(std::move(emojis_))); - } - - public: - GetStickerEmojisRequest(ActorShared td, uint64 request_id, tl_object_ptr &&input_file) - : RequestActor(std::move(td), request_id), input_file_(std::move(input_file)) { - set_tries(3); - } -}; - -class SearchEmojisRequest final : public RequestActor<> { - string text_; - bool exact_match_; - vector input_language_codes_; - - vector emojis_; - - void do_run(Promise &&promise) final { - emojis_ = td_->stickers_manager_->search_emojis(text_, exact_match_, input_language_codes_, get_tries() < 2, - std::move(promise)); - } - - void do_send_result() final { - send_result(td_api::make_object(std::move(emojis_))); - } - - public: - SearchEmojisRequest(ActorShared td, uint64 request_id, string &&text, bool exact_match, - vector &&input_language_codes) - : RequestActor(std::move(td), request_id) - , text_(std::move(text)) - , exact_match_(exact_match) - , input_language_codes_(std::move(input_language_codes)) { - set_tries(3); - } -}; - -class GetEmojiSuggestionsUrlRequest final : public RequestOnceActor { - string language_code_; - - int64 random_id_; - - void do_run(Promise &&promise) final { - random_id_ = td_->stickers_manager_->get_emoji_suggestions_url(language_code_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->stickers_manager_->get_emoji_suggestions_url_result(random_id_)); - } - - public: - GetEmojiSuggestionsUrlRequest(ActorShared td, uint64 request_id, string &&language_code) - : RequestOnceActor(std::move(td), request_id), language_code_(std::move(language_code)), random_id_(0) { - } -}; - -class GetSavedAnimationsRequest final : public RequestActor<> { - vector animation_ids_; - - void do_run(Promise &&promise) final { - animation_ids_ = td_->animations_manager_->get_saved_animations(std::move(promise)); - } - - void do_send_result() final { - send_result(make_tl_object(transform(animation_ids_, [td = td_](FileId animation_id) { - return td->animations_manager_->get_animation_object(animation_id); - }))); - } - - public: - GetSavedAnimationsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { - } -}; - -class AddSavedAnimationRequest final : public RequestOnceActor { - tl_object_ptr input_file_; - - void do_run(Promise &&promise) final { - td_->animations_manager_->add_saved_animation(input_file_, std::move(promise)); - } - - public: - AddSavedAnimationRequest(ActorShared td, uint64 request_id, tl_object_ptr &&input_file) - : RequestOnceActor(std::move(td), request_id), input_file_(std::move(input_file)) { - set_tries(3); - } -}; - -class RemoveSavedAnimationRequest final : public RequestOnceActor { - tl_object_ptr input_file_; - - void do_run(Promise &&promise) final { - td_->animations_manager_->remove_saved_animation(input_file_, std::move(promise)); - } - - public: - RemoveSavedAnimationRequest(ActorShared td, uint64 request_id, tl_object_ptr &&input_file) - : RequestOnceActor(std::move(td), request_id), input_file_(std::move(input_file)) { - set_tries(3); - } -}; - -class GetSavedNotificationSoundRequest final : public RequestActor<> { - int64 ringtone_id_; - FileId ringtone_file_id_; - - void do_run(Promise &&promise) final { - ringtone_file_id_ = td_->notification_settings_manager_->get_saved_ringtone(ringtone_id_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->audios_manager_->get_notification_sound_object(ringtone_file_id_)); - } - - public: - GetSavedNotificationSoundRequest(ActorShared td, uint64 request_id, int64 ringtone_id) - : RequestActor(std::move(td), request_id), ringtone_id_(ringtone_id) { - } -}; - -class GetSavedNotificationSoundsRequest final : public RequestActor<> { - vector ringtone_file_ids_; - - void do_run(Promise &&promise) final { - ringtone_file_ids_ = td_->notification_settings_manager_->get_saved_ringtones(std::move(promise)); - } - - void do_send_result() final { - send_result(td_api::make_object( - transform(ringtone_file_ids_, [td = td_](FileId ringtone_file_id) { - return td->audios_manager_->get_notification_sound_object(ringtone_file_id); - }))); - } - - public: - GetSavedNotificationSoundsRequest(ActorShared td, uint64 request_id) : RequestActor(std::move(td), request_id) { - } -}; - -class RemoveSavedNotificationSoundRequest final : public RequestOnceActor { - int64 ringtone_id_; - - void do_run(Promise &&promise) final { - td_->notification_settings_manager_->remove_saved_ringtone(ringtone_id_, std::move(promise)); - } - - public: - RemoveSavedNotificationSoundRequest(ActorShared td, uint64 request_id, int64 ringtone_id) - : RequestOnceActor(std::move(td), request_id), ringtone_id_(ringtone_id) { - set_tries(3); - } -}; - -class GetInlineQueryResultsRequest final : public RequestOnceActor { - UserId bot_user_id_; - DialogId dialog_id_; - Location user_location_; - string query_; - string offset_; - - uint64 query_hash_; - - void do_run(Promise &&promise) final { - query_hash_ = td_->inline_queries_manager_->send_inline_query(bot_user_id_, dialog_id_, user_location_, query_, - offset_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->inline_queries_manager_->get_inline_query_results_object(query_hash_)); - } - - public: - GetInlineQueryResultsRequest(ActorShared td, uint64 request_id, int64 bot_user_id, int64 dialog_id, - const tl_object_ptr &user_location, string query, string offset) - : RequestOnceActor(std::move(td), request_id) - , bot_user_id_(bot_user_id) - , dialog_id_(dialog_id) - , user_location_(user_location) - , query_(std::move(query)) - , offset_(std::move(offset)) - , query_hash_(0) { - } -}; - -class SearchBackgroundRequest final : public RequestActor<> { - string name_; - - std::pair background_; - - void do_run(Promise &&promise) final { - background_ = td_->background_manager_->search_background(name_, std::move(promise)); - } - - void do_send_result() final { - send_result(td_->background_manager_->get_background_object(background_.first, false, &background_.second)); - } - - public: - SearchBackgroundRequest(ActorShared td, uint64 request_id, string &&name) - : RequestActor(std::move(td), request_id), name_(std::move(name)) { - set_tries(3); - } -}; - -Td::Td(unique_ptr callback, Options options) - : callback_(std::move(callback)), td_options_(std::move(options)) { - CHECK(callback_ != nullptr); - LOG(INFO) << "Create Td with layer " << MTPROTO_LAYER << ", database version " << current_db_version() - << " and version " << static_cast(Version::Next) - 1 << " on " - << Scheduler::instance()->sched_count() << " threads"; -} - -Td::~Td() = default; - -void Td::on_alarm_timeout_callback(void *td_ptr, int64 alarm_id) { - auto td = static_cast(td_ptr); - auto td_id = td->actor_id(td); - send_closure_later(td_id, &Td::on_alarm_timeout, alarm_id); -} - -void Td::on_alarm_timeout(int64 alarm_id) { - if (alarm_id == ONLINE_ALARM_ID) { - on_online_updated(false, true); - return; - } - if (alarm_id == PING_SERVER_ALARM_ID) { - if (!close_flag_ && updates_manager_ != nullptr && auth_manager_->is_authorized()) { - updates_manager_->ping_server(); - alarm_timeout_.set_timeout_in(PING_SERVER_ALARM_ID, - PING_SERVER_TIMEOUT + Random::fast(0, PING_SERVER_TIMEOUT / 5)); - set_is_bot_online(false); - } - return; - } - if (alarm_id == TERMS_OF_SERVICE_ALARM_ID) { - if (!close_flag_ && !auth_manager_->is_bot()) { - get_terms_of_service( - this, PromiseCreator::lambda([actor_id = actor_id(this)](Result> result) { - send_closure(actor_id, &Td::on_get_terms_of_service, std::move(result), false); - })); - } - return; - } - if (alarm_id == PROMO_DATA_ALARM_ID) { - if (!close_flag_ && !auth_manager_->is_bot()) { - reloading_promo_data_ = true; - auto promise = PromiseCreator::lambda( - [actor_id = actor_id(this)](Result> result) { - send_closure(actor_id, &Td::on_get_promo_data, std::move(result), false); - }); - create_handler(std::move(promise))->send(); - } - return; - } - if (close_flag_ >= 2) { - // pending_alarms_ was already cleared - return; - } - - auto it = pending_alarms_.find(alarm_id); - CHECK(it != pending_alarms_.end()); - uint64 request_id = it->second; - pending_alarms_.erase(alarm_id); - send_result(request_id, make_tl_object()); -} - -void Td::on_online_updated(bool force, bool send_update) { - if (close_flag_ >= 2 || !auth_manager_->is_authorized() || auth_manager_->is_bot()) { - return; - } - if (force || is_online_) { - contacts_manager_->set_my_online_status(is_online_, send_update, true); - if (!update_status_query_.empty()) { - LOG(INFO) << "Cancel previous update status query"; - cancel_query(update_status_query_); - } - update_status_query_ = create_handler()->send(!is_online_); - } - if (is_online_) { - alarm_timeout_.set_timeout_in( - ONLINE_ALARM_ID, static_cast(G()->get_option_integer("online_update_period_ms", 210000)) * 1e-3); - } else { - alarm_timeout_.cancel_timeout(ONLINE_ALARM_ID); - } -} - -void Td::on_update_status_success(bool is_online) { - if (is_online == is_online_) { - if (!update_status_query_.empty()) { - update_status_query_ = NetQueryRef(); - } - contacts_manager_->set_my_online_status(is_online_, true, false); - } -} - -td_api::object_ptr Td::get_update_terms_of_service_object() const { - auto terms_of_service = pending_terms_of_service_.get_terms_of_service_object(); - if (terms_of_service == nullptr) { - return nullptr; - } - return td_api::make_object(pending_terms_of_service_.get_id().str(), - std::move(terms_of_service)); -} - -void Td::on_get_terms_of_service(Result> result, bool dummy) { - int32 expires_in = 0; - if (result.is_error()) { - expires_in = Random::fast(10, 60); - } else { - auto terms = result.move_as_ok(); - pending_terms_of_service_ = std::move(terms.second); - auto update = get_update_terms_of_service_object(); - if (update == nullptr) { - expires_in = min(max(terms.first, G()->unix_time() + 3600) - G()->unix_time(), 86400); - } else { - send_update(std::move(update)); - } - } - if (expires_in > 0) { - schedule_get_terms_of_service(expires_in); - } -} - -void Td::schedule_get_terms_of_service(int32 expires_in) { - if (expires_in == 0) { - // drop pending Terms of Service after successful accept - pending_terms_of_service_ = TermsOfService(); - } - if (!close_flag_ && !auth_manager_->is_bot()) { - alarm_timeout_.set_timeout_in(TERMS_OF_SERVICE_ALARM_ID, expires_in); - } -} - -void Td::on_get_promo_data(Result> r_promo_data, bool dummy) { - if (G()->close_flag()) { - return; - } - reloading_promo_data_ = false; - - if (r_promo_data.is_error()) { - LOG(ERROR) << "Receive error for GetPromoData: " << r_promo_data.error(); - return schedule_get_promo_data(60); - } - - auto promo_data_ptr = r_promo_data.move_as_ok(); - CHECK(promo_data_ptr != nullptr); - LOG(DEBUG) << "Receive " << to_string(promo_data_ptr); - int32 expires_at = 0; - switch (promo_data_ptr->get_id()) { - case telegram_api::help_promoDataEmpty::ID: { - auto promo = telegram_api::move_object_as(promo_data_ptr); - expires_at = promo->expires_; - messages_manager_->remove_sponsored_dialog(); - break; - } - case telegram_api::help_promoData::ID: { - auto promo = telegram_api::move_object_as(promo_data_ptr); - expires_at = promo->expires_; - bool is_proxy = promo->proxy_; - messages_manager_->on_get_sponsored_dialog( - std::move(promo->peer_), - is_proxy ? DialogSource::mtproto_proxy() - : DialogSource::public_service_announcement(promo->psa_type_, promo->psa_message_), - std::move(promo->users_), std::move(promo->chats_)); - break; - } - default: - UNREACHABLE(); - } - if (need_reload_promo_data_) { - need_reload_promo_data_ = false; - expires_at = 0; - } - schedule_get_promo_data(expires_at == 0 ? 0 : expires_at - G()->unix_time()); -} - -void Td::reload_promo_data() { - if (reloading_promo_data_) { - need_reload_promo_data_ = true; - return; - } - schedule_get_promo_data(0); -} - -void Td::schedule_get_promo_data(int32 expires_in) { - expires_in = expires_in <= 0 ? 0 : clamp(expires_in, 60, 86400); - if (!close_flag_ && auth_manager_->is_authorized() && !auth_manager_->is_bot()) { - LOG(INFO) << "Schedule getPromoData in " << expires_in; - alarm_timeout_.set_timeout_in(PROMO_DATA_ALARM_ID, expires_in); - } -} - -bool Td::is_online() const { - return is_online_; -} - -void Td::set_is_online(bool is_online) { - if (is_online == is_online_) { - return; - } - - is_online_ = is_online; - if (auth_manager_ != nullptr) { // postpone if there is no AuthManager yet - on_online_updated(true, true); - } -} - -void Td::set_is_bot_online(bool is_bot_online) { - if (G()->get_option_integer("session_count") > 1) { - is_bot_online = false; - } - - if (is_bot_online == is_bot_online_) { - return; - } - - is_bot_online_ = is_bot_online; - send_closure(G()->state_manager(), &StateManager::on_online, is_bot_online_); -} - -bool Td::ignore_background_updates() const { - return can_ignore_background_updates_ && option_manager_->get_option_boolean("ignore_background_updates"); -} - -bool Td::is_authentication_request(int32 id) { - switch (id) { - case td_api::setTdlibParameters::ID: - case td_api::getAuthorizationState::ID: - case td_api::setAuthenticationPhoneNumber::ID: - case td_api::sendAuthenticationFirebaseSms::ID: - case td_api::setAuthenticationEmailAddress::ID: - case td_api::resendAuthenticationCode::ID: - case td_api::checkAuthenticationEmailCode::ID: - case td_api::checkAuthenticationCode::ID: - case td_api::registerUser::ID: - case td_api::requestQrCodeAuthentication::ID: - case td_api::resetAuthenticationEmailAddress::ID: - case td_api::checkAuthenticationPassword::ID: - case td_api::requestAuthenticationPasswordRecovery::ID: - case td_api::checkAuthenticationPasswordRecoveryCode::ID: - case td_api::recoverAuthenticationPassword::ID: - case td_api::deleteAccount::ID: - case td_api::logOut::ID: - case td_api::close::ID: - case td_api::destroy::ID: - case td_api::checkAuthenticationBotToken::ID: - return true; - default: - return false; - } -} - -bool Td::is_synchronous_request(const td_api::Function *function) { - switch (function->get_id()) { - case td_api::getTextEntities::ID: - case td_api::parseTextEntities::ID: - case td_api::parseMarkdown::ID: - case td_api::getMarkdownText::ID: - case td_api::getFileMimeType::ID: - case td_api::getFileExtension::ID: - case td_api::cleanFileName::ID: - case td_api::getLanguagePackString::ID: - case td_api::getPhoneNumberInfoSync::ID: - case td_api::getChatFolderDefaultIconName::ID: - case td_api::getJsonValue::ID: - case td_api::getJsonString::ID: - case td_api::getThemeParametersJsonString::ID: - case td_api::getPushReceiverId::ID: - case td_api::setLogStream::ID: - case td_api::getLogStream::ID: - case td_api::setLogVerbosityLevel::ID: - case td_api::getLogVerbosityLevel::ID: - case td_api::getLogTags::ID: - case td_api::setLogTagVerbosityLevel::ID: - case td_api::getLogTagVerbosityLevel::ID: - case td_api::addLogMessage::ID: - case td_api::testReturnError::ID: - return true; - case td_api::getOption::ID: - return OptionManager::is_synchronous_option(static_cast(function)->name_); - default: - return false; - } -} - -bool Td::is_preinitialization_request(int32 id) { - switch (id) { - case td_api::getCurrentState::ID: - case td_api::setAlarm::ID: - case td_api::testUseUpdate::ID: - case td_api::testCallEmpty::ID: - case td_api::testSquareInt::ID: - case td_api::testCallString::ID: - case td_api::testCallBytes::ID: - case td_api::testCallVectorInt::ID: - case td_api::testCallVectorIntObject::ID: - case td_api::testCallVectorString::ID: - case td_api::testCallVectorStringObject::ID: - case td_api::testProxy::ID: - return true; - default: - return false; - } -} - -bool Td::is_preauthentication_request(int32 id) { - switch (id) { - case td_api::getInternalLink::ID: - case td_api::getInternalLinkType::ID: - case td_api::getLocalizationTargetInfo::ID: - case td_api::getLanguagePackInfo::ID: - case td_api::getLanguagePackStrings::ID: - case td_api::synchronizeLanguagePack::ID: - case td_api::addCustomServerLanguagePack::ID: - case td_api::setCustomLanguagePack::ID: - case td_api::editCustomLanguagePackInfo::ID: - case td_api::setCustomLanguagePackString::ID: - case td_api::deleteLanguagePack::ID: - case td_api::processPushNotification::ID: - case td_api::getOption::ID: - case td_api::setOption::ID: - case td_api::getStorageStatistics::ID: - case td_api::getStorageStatisticsFast::ID: - case td_api::getDatabaseStatistics::ID: - case td_api::setNetworkType::ID: - case td_api::getNetworkStatistics::ID: - case td_api::addNetworkStatistics::ID: - case td_api::resetNetworkStatistics::ID: - case td_api::getCountries::ID: - case td_api::getCountryCode::ID: - case td_api::getPhoneNumberInfo::ID: - case td_api::getDeepLinkInfo::ID: - case td_api::getApplicationConfig::ID: - case td_api::saveApplicationLogEvent::ID: - case td_api::addProxy::ID: - case td_api::editProxy::ID: - case td_api::enableProxy::ID: - case td_api::disableProxy::ID: - case td_api::removeProxy::ID: - case td_api::getProxies::ID: - case td_api::getProxyLink::ID: - case td_api::pingProxy::ID: - case td_api::testNetwork::ID: - return true; - default: - return false; - } -} - -td_api::object_ptr Td::get_fake_authorization_state_object() const { - switch (state_) { - case State::WaitParameters: - return td_api::make_object(); - case State::Run: - UNREACHABLE(); - return nullptr; - case State::Close: - if (close_flag_ == 5) { - return td_api::make_object(); - } else { - return td_api::make_object(); - } - default: - UNREACHABLE(); - return nullptr; - } -} - -vector> Td::get_fake_current_state() const { - CHECK(state_ != State::Run); - vector> updates; - OptionManager::get_common_state(updates); - updates.push_back(td_api::make_object(get_fake_authorization_state_object())); - return updates; -} - -DbKey Td::as_db_key(string key) { - // Database will still be effectively not encrypted, but - // 1. SQLite database will be protected from corruption, because that's how sqlcipher works - // 2. security through obscurity - // 3. no need for reencryption of SQLite database - if (key.empty()) { - return DbKey::raw_key("cucumber"); - } - return DbKey::raw_key(std::move(key)); -} - -void Td::request(uint64 id, tl_object_ptr function) { - if (id == 0) { - LOG(ERROR) << "Ignore request with ID == 0: " << to_string(function); - return; - } - - if (function == nullptr) { - return callback_->on_error(id, make_error(400, "Request is empty")); - } - - VLOG(td_requests) << "Receive request " << id << ": " << to_string(function); - request_set_.emplace(id, function->get_id()); - if (is_synchronous_request(function.get())) { - // send response synchronously - return send_result(id, static_request(std::move(function))); - } - - run_request(id, std::move(function)); -} - -void Td::run_request(uint64 id, tl_object_ptr function) { - if (set_parameters_request_id_ > 0) { - pending_set_parameters_requests_.emplace_back(id, std::move(function)); - return; - } - - int32 function_id = function->get_id(); - if (state_ != State::Run) { - switch (function_id) { - case td_api::getAuthorizationState::ID: - // send response synchronously to prevent "Request aborted" - return send_result(id, get_fake_authorization_state_object()); - case td_api::getCurrentState::ID: - // send response synchronously to prevent "Request aborted" - return send_result(id, td_api::make_object(get_fake_current_state())); - case td_api::close::ID: - // need to send response before actual closing - send_closure(actor_id(this), &Td::send_result, id, td_api::make_object()); - send_closure(actor_id(this), &Td::close); - return; - default: - break; - } - } - switch (state_) { - case State::WaitParameters: { - switch (function_id) { - case td_api::setTdlibParameters::ID: { - auto r_parameters = get_parameters(move_tl_object_as(function)); - if (r_parameters.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_parameters.move_as_error()); - } - auto parameters = r_parameters.move_as_ok(); - - VLOG(td_init) << "Begin to open database"; - set_parameters_request_id_ = id; - can_ignore_background_updates_ = !parameters.second.use_chat_info_database_ && - !parameters.second.use_message_database_ && - !parameters.first.use_secret_chats_; - - auto promise = PromiseCreator::lambda([actor_id = actor_id(this), parameters = std::move(parameters.first)]( - Result r_opened_database) mutable { - send_closure(actor_id, &Td::init, std::move(parameters), std::move(r_opened_database)); - }); - return TdDb::open(get_database_scheduler_id(), std::move(parameters.second), std::move(promise)); - } - default: - if (is_preinitialization_request(function_id)) { - break; - } - if (is_preauthentication_request(function_id)) { - pending_preauthentication_requests_.emplace_back(id, std::move(function)); - return; - } - return send_error_impl( - id, make_error(400, "Initialization parameters are needed: call setTdlibParameters first")); - } - break; - } - case State::Close: - if (destroy_flag_) { - return send_error_impl(id, make_error(401, "Unauthorized")); - } else { - return send_error_impl(id, make_error(500, "Request aborted")); - } - case State::Run: - break; - } - - if ((auth_manager_ == nullptr || !auth_manager_->is_authorized()) && !is_preauthentication_request(function_id) && - !is_preinitialization_request(function_id) && !is_authentication_request(function_id)) { - return send_error_impl(id, make_error(401, "Unauthorized")); - } - downcast_call(*function, [this, id](auto &request) { this->on_request(id, request); }); -} - -td_api::object_ptr Td::static_request(td_api::object_ptr function) { - if (function == nullptr) { - return td_api::make_object(400, "Request is empty"); - } - - auto function_id = function->get_id(); - bool need_logging = [function_id] { - switch (function_id) { - case td_api::parseTextEntities::ID: - case td_api::parseMarkdown::ID: - case td_api::getMarkdownText::ID: - case td_api::getFileMimeType::ID: - case td_api::getFileExtension::ID: - case td_api::cleanFileName::ID: - case td_api::getChatFolderDefaultIconName::ID: - case td_api::getJsonValue::ID: - case td_api::getJsonString::ID: - case td_api::getThemeParametersJsonString::ID: - case td_api::testReturnError::ID: - return true; - default: - return false; - } - }(); - - if (need_logging) { - VLOG(td_requests) << "Receive static request: " << to_string(function); - } - - td_api::object_ptr response; - downcast_call(*function, [&response](auto &request) { response = Td::do_static_request(request); }); - LOG_CHECK(response != nullptr) << function_id; - - if (need_logging) { - VLOG(td_requests) << "Sending result for static request: " << to_string(response); - } - return response; -} - -void Td::add_handler(uint64 id, std::shared_ptr handler) { - result_handlers_[id] = std::move(handler); -} - -std::shared_ptr Td::extract_handler(uint64 id) { - auto it = result_handlers_.find(id); - if (it == result_handlers_.end()) { - return nullptr; - } - auto result = std::move(it->second); - result_handlers_.erase(it); - return result; -} - -void Td::on_update(BufferSlice &&update, uint64 auth_key_id) { - if (close_flag_ > 1) { - return; - } - - TlBufferParser parser(&update); - auto ptr = telegram_api::Updates::fetch(parser); - parser.fetch_end(); - if (parser.get_error()) { - LOG(ERROR) << "Failed to fetch update: " << parser.get_error() << format::as_hex_dump<4>(update.as_slice()); - updates_manager_->schedule_get_difference("failed to fetch update"); - } else { - updates_manager_->on_update_from_auth_key_id(auth_key_id); - updates_manager_->on_get_updates(std::move(ptr), Promise()); - if (auth_manager_->is_bot() && auth_manager_->is_authorized()) { - alarm_timeout_.set_timeout_in(PING_SERVER_ALARM_ID, - PING_SERVER_TIMEOUT + Random::fast(0, PING_SERVER_TIMEOUT / 5)); - set_is_bot_online(true); - } - } -} - -void Td::on_result(NetQueryPtr query) { - query->debug("Td: received from DcManager"); - VLOG(net_query) << "Receive result of " << query; - if (close_flag_ > 1) { - return; - } - - auto handler = extract_handler(query->id()); - if (handler != nullptr) { - CHECK(query->is_ready()); - if (query->is_ok()) { - handler->on_result(std::move(query->ok())); - } else { - handler->on_error(std::move(query->error())); - } - } else if (!query->is_ok() || query->ok_tl_constructor() != telegram_api::upload_file::ID) { - LOG(WARNING) << query << " is ignored: no handlers found"; - } - query->clear(); -} - -void Td::on_connection_state_changed(ConnectionState new_state) { - if (G()->close_flag()) { - return; - } - if (new_state == connection_state_) { - LOG(ERROR) << "State manager sends update about unchanged state " << static_cast(new_state); - return; - } - connection_state_ = new_state; - - send_closure(actor_id(this), &Td::send_update, get_update_connection_state_object(connection_state_)); -} - -void Td::start_up() { - uint64 check_endianness = 0x0706050403020100; - auto check_endianness_raw = reinterpret_cast(&check_endianness); - for (unsigned char c = 0; c < 8; c++) { - auto symbol = check_endianness_raw[static_cast(c)]; - LOG_IF(FATAL, symbol != c) << "TDLib requires little-endian platform"; - } - - VLOG(td_init) << "Create Global"; - old_context_ = set_context(std::make_shared()); - G()->set_net_query_stats(td_options_.net_query_stats); - inc_request_actor_refcnt(); // guard - inc_actor_refcnt(); // guard - - alarm_timeout_.set_callback(on_alarm_timeout_callback); - alarm_timeout_.set_callback_data(static_cast(this)); - - CHECK(state_ == State::WaitParameters); - for (auto &update : get_fake_current_state()) { - send_update(std::move(update)); - } -} - -void Td::tear_down() { - LOG_CHECK(close_flag_ == 5) << close_flag_; -} - -void Td::hangup_shared() { - auto token = get_link_token(); - auto type = Container::type_from_id(token); - - if (type == RequestActorIdType) { - request_actors_.erase(token); - dec_request_actor_refcnt(); - } else if (type == ActorIdType) { - dec_actor_refcnt(); - } else { - LOG(FATAL) << "Unknown hangup_shared of type " << type; - } -} - -void Td::hangup() { - LOG(INFO) << "Receive Td::hangup"; - close(); - dec_stop_cnt(); -} - -ActorShared Td::create_reference() { - inc_actor_refcnt(); - return actor_shared(this, ActorIdType); -} - -void Td::inc_actor_refcnt() { - actor_refcnt_++; -} - -void Td::dec_actor_refcnt() { - actor_refcnt_--; - if (actor_refcnt_ < 3) { - LOG(DEBUG) << "Decrease reference count to " << actor_refcnt_; - } - if (actor_refcnt_ == 0) { - if (close_flag_ == 2) { - create_reference(); - close_flag_ = 3; - } else if (close_flag_ == 3) { - LOG(INFO) << "All actors were closed"; - Timer timer; - animations_manager_.reset(); - LOG(DEBUG) << "AnimationsManager was cleared" << timer; - attach_menu_manager_.reset(); - LOG(DEBUG) << "AttachMenuManager was cleared" << timer; - audios_manager_.reset(); - LOG(DEBUG) << "AudiosManager was cleared" << timer; - auth_manager_.reset(); - LOG(DEBUG) << "AuthManager was cleared" << timer; - autosave_manager_.reset(); - LOG(DEBUG) << "AutosaveManager was cleared" << timer; - background_manager_.reset(); - LOG(DEBUG) << "BackgroundManager was cleared" << timer; - bot_info_manager_.reset(); - LOG(DEBUG) << "BotInfoManager was cleared" << timer; - callback_queries_manager_.reset(); - LOG(DEBUG) << "CallbackQueriesManager was cleared" << timer; - contacts_manager_.reset(); - LOG(DEBUG) << "ContactsManager was cleared" << timer; - country_info_manager_.reset(); - LOG(DEBUG) << "CountryInfoManager was cleared" << timer; - dialog_filter_manager_.reset(); - LOG(DEBUG) << "DialogFilterManager was cleared" << timer; - documents_manager_.reset(); - LOG(DEBUG) << "DocumentsManager was cleared" << timer; - download_manager_.reset(); - LOG(DEBUG) << "DownloadManager was cleared" << timer; - file_manager_.reset(); - LOG(DEBUG) << "FileManager was cleared" << timer; - file_reference_manager_.reset(); - LOG(DEBUG) << "FileReferenceManager was cleared" << timer; - forum_topic_manager_.reset(); - LOG(DEBUG) << "ForumTopicManager was cleared" << timer; - game_manager_.reset(); - LOG(DEBUG) << "GameManager was cleared" << timer; - group_call_manager_.reset(); - LOG(DEBUG) << "GroupCallManager was cleared" << timer; - inline_queries_manager_.reset(); - LOG(DEBUG) << "InlineQueriesManager was cleared" << timer; - link_manager_.reset(); - LOG(DEBUG) << "LinkManager was cleared" << timer; - messages_manager_.reset(); - LOG(DEBUG) << "MessagesManager was cleared" << timer; - notification_manager_.reset(); - LOG(DEBUG) << "NotificationManager was cleared" << timer; - notification_settings_manager_.reset(); - LOG(DEBUG) << "NotificationSettingsManager was cleared" << timer; - poll_manager_.reset(); - LOG(DEBUG) << "PollManager was cleared" << timer; - sponsored_message_manager_.reset(); - LOG(DEBUG) << "SponsoredMessageManager was cleared" << timer; - stickers_manager_.reset(); - LOG(DEBUG) << "StickersManager was cleared" << timer; - theme_manager_.reset(); - LOG(DEBUG) << "ThemeManager was cleared" << timer; - top_dialog_manager_.reset(); - LOG(DEBUG) << "TopDialogManager was cleared" << timer; - translation_manager_.reset(); - LOG(DEBUG) << "TranslationManager was cleared" << timer; - updates_manager_.reset(); - LOG(DEBUG) << "UpdatesManager was cleared" << timer; - video_notes_manager_.reset(); - LOG(DEBUG) << "VideoNotesManager was cleared" << timer; - videos_manager_.reset(); - LOG(DEBUG) << "VideosManager was cleared" << timer; - voice_notes_manager_.reset(); - LOG(DEBUG) << "VoiceNotesManager was cleared" << timer; - web_pages_manager_.reset(); - LOG(DEBUG) << "WebPagesManager was cleared" << timer; - - G()->set_option_manager(nullptr); - option_manager_.reset(); - LOG(DEBUG) << "OptionManager was cleared" << timer; - - Promise<> promise = PromiseCreator::lambda([actor_id = create_reference()](Unit) mutable { actor_id.reset(); }); - if (destroy_flag_) { - G()->close_and_destroy_all(std::move(promise)); - } else { - G()->close_all(std::move(promise)); - } - // NetQueryDispatcher will be closed automatically - close_flag_ = 4; - } else if (close_flag_ == 4) { - on_closed(); - } else { - UNREACHABLE(); - } - } -} - -void Td::on_closed() { - close_flag_ = 5; - send_update( - td_api::make_object(td_api::make_object())); - dec_stop_cnt(); -} - -void Td::dec_stop_cnt() { - stop_cnt_--; - if (stop_cnt_ == 0) { - LOG(INFO) << "Stop Td"; - set_context(std::move(old_context_)); - stop(); - } -} - -void Td::inc_request_actor_refcnt() { - request_actor_refcnt_++; -} - -void Td::dec_request_actor_refcnt() { - request_actor_refcnt_--; - LOG(DEBUG) << "Decrease request actor count to " << request_actor_refcnt_; - if (request_actor_refcnt_ == 0) { - LOG(INFO) << "Have no request actors"; - clear(); - dec_actor_refcnt(); // remove guard - } -} - -void Td::clear_requests() { - while (!pending_alarms_.empty()) { - auto it = pending_alarms_.begin(); - auto alarm_id = it->first; - pending_alarms_.erase(it); - alarm_timeout_.cancel_timeout(alarm_id); - } - while (!request_set_.empty()) { - uint64 id = request_set_.begin()->first; - if (destroy_flag_) { - send_error_impl(id, make_error(401, "Unauthorized")); - } else { - send_error_impl(id, make_error(500, "Request aborted")); - } - } -} - -void Td::clear() { - if (close_flag_ >= 2) { - return; - } - - LOG(INFO) << "Clear Td"; - close_flag_ = 2; - - Timer timer; - if (!auth_manager_->is_bot()) { - if (destroy_flag_) { - notification_manager_->destroy_all_notifications(); - } else { - notification_manager_->flush_all_notifications(); - } - } - - G()->net_query_creator().stop_check(); - result_handlers_.clear(); - LOG(DEBUG) << "Handlers were cleared" << timer; - G()->net_query_dispatcher().stop(); - LOG(DEBUG) << "NetQueryDispatcher was stopped" << timer; - state_manager_.reset(); - LOG(DEBUG) << "StateManager was cleared" << timer; - clear_requests(); - if (is_online_) { - is_online_ = false; - alarm_timeout_.cancel_timeout(ONLINE_ALARM_ID); - } - alarm_timeout_.cancel_timeout(PING_SERVER_ALARM_ID); - alarm_timeout_.cancel_timeout(TERMS_OF_SERVICE_ALARM_ID); - alarm_timeout_.cancel_timeout(PROMO_DATA_ALARM_ID); - LOG(DEBUG) << "Requests were answered" << timer; - - // close all pure actors - call_manager_.reset(); - LOG(DEBUG) << "CallManager was cleared" << timer; - change_phone_number_manager_.reset(); - LOG(DEBUG) << "ChangePhoneNumberManager was cleared" << timer; - config_manager_.reset(); - LOG(DEBUG) << "ConfigManager was cleared" << timer; - confirm_phone_number_manager_.reset(); - LOG(DEBUG) << "ConfirmPhoneNumberManager was cleared" << timer; - device_token_manager_.reset(); - LOG(DEBUG) << "DeviceTokenManager was cleared" << timer; - hashtag_hints_.reset(); - LOG(DEBUG) << "HashtagHints was cleared" << timer; - language_pack_manager_.reset(); - LOG(DEBUG) << "LanguagePackManager was cleared" << timer; - net_stats_manager_.reset(); - LOG(DEBUG) << "NetStatsManager was cleared" << timer; - password_manager_.reset(); - LOG(DEBUG) << "PasswordManager was cleared" << timer; - privacy_manager_.reset(); - LOG(DEBUG) << "PrivacyManager was cleared" << timer; - secure_manager_.reset(); - LOG(DEBUG) << "SecureManager was cleared" << timer; - secret_chats_manager_.reset(); - LOG(DEBUG) << "SecretChatsManager was cleared" << timer; - storage_manager_.reset(); - LOG(DEBUG) << "StorageManager was cleared" << timer; - verify_phone_number_manager_.reset(); - LOG(DEBUG) << "VerifyPhoneNumberManager was cleared" << timer; - - G()->set_connection_creator(ActorOwn()); - LOG(DEBUG) << "ConnectionCreator was cleared" << timer; - G()->set_temp_auth_key_watchdog(ActorOwn()); - LOG(DEBUG) << "TempAuthKeyWatchdog was cleared" << timer; - - // clear actors which are unique pointers - animations_manager_actor_.reset(); - LOG(DEBUG) << "AnimationsManager actor was cleared" << timer; - attach_menu_manager_actor_.reset(); - LOG(DEBUG) << "AttachMenuManager actor was cleared" << timer; - auth_manager_actor_.reset(); - LOG(DEBUG) << "AuthManager actor was cleared" << timer; - autosave_manager_actor_.reset(); - LOG(DEBUG) << "AutosaveManager actor was cleared" << timer; - background_manager_actor_.reset(); - LOG(DEBUG) << "BackgroundManager actor was cleared" << timer; - bot_info_manager_actor_.reset(); - LOG(DEBUG) << "BotInfoManager actor was cleared" << timer; - contacts_manager_actor_.reset(); - LOG(DEBUG) << "ContactsManager actor was cleared" << timer; - country_info_manager_actor_.reset(); - LOG(DEBUG) << "CountryInfoManager actor was cleared" << timer; - dialog_filter_manager_actor_.reset(); - LOG(DEBUG) << "DialogFilterManager actor was cleared" << timer; - download_manager_actor_.reset(); - LOG(DEBUG) << "DownloadManager actor was cleared" << timer; - file_manager_actor_.reset(); - LOG(DEBUG) << "FileManager actor was cleared" << timer; - file_reference_manager_actor_.reset(); - LOG(DEBUG) << "FileReferenceManager actor was cleared" << timer; - forum_topic_manager_actor_.reset(); - LOG(DEBUG) << "ForumTopicManager actor was cleared" << timer; - game_manager_actor_.reset(); - LOG(DEBUG) << "GameManager actor was cleared" << timer; - group_call_manager_actor_.reset(); - LOG(DEBUG) << "GroupCallManager actor was cleared" << timer; - inline_queries_manager_actor_.reset(); - LOG(DEBUG) << "InlineQueriesManager actor was cleared" << timer; - link_manager_actor_.reset(); - LOG(DEBUG) << "LinkManager actor was cleared" << timer; - messages_manager_actor_.reset(); // TODO: Stop silent - LOG(DEBUG) << "MessagesManager actor was cleared" << timer; - notification_manager_actor_.reset(); - LOG(DEBUG) << "NotificationManager actor was cleared" << timer; - notification_settings_manager_actor_.reset(); - LOG(DEBUG) << "NotificationSettingsManager actor was cleared" << timer; - poll_manager_actor_.reset(); - LOG(DEBUG) << "PollManager actor was cleared" << timer; - sponsored_message_manager_actor_.reset(); - LOG(DEBUG) << "SponsoredMessageManager actor was cleared" << timer; - stickers_manager_actor_.reset(); - LOG(DEBUG) << "StickersManager actor was cleared" << timer; - theme_manager_actor_.reset(); - LOG(DEBUG) << "ThemeManager actor was cleared" << timer; - top_dialog_manager_actor_.reset(); - LOG(DEBUG) << "TopDialogManager actor was cleared" << timer; - translation_manager_actor_.reset(); - LOG(DEBUG) << "TranslationManager actor was cleared" << timer; - updates_manager_actor_.reset(); - LOG(DEBUG) << "UpdatesManager actor was cleared" << timer; - video_notes_manager_actor_.reset(); - LOG(DEBUG) << "VideoNotesManager actor was cleared" << timer; - voice_notes_manager_actor_.reset(); - LOG(DEBUG) << "VoiceNotesManager actor was cleared" << timer; - web_pages_manager_actor_.reset(); - LOG(DEBUG) << "WebPagesManager actor was cleared" << timer; -} - -void Td::close() { - close_impl(false); -} - -void Td::destroy() { - close_impl(true); -} - -void Td::close_impl(bool destroy_flag) { - destroy_flag_ |= destroy_flag; - if (close_flag_) { - return; - } - - LOG(WARNING) << (destroy_flag ? "Destroy" : "Close") << " Td in state " << static_cast(state_); - if (state_ == State::WaitParameters) { - clear_requests(); - state_ = State::Close; - close_flag_ = 4; - G()->set_close_flag(); - send_update(td_api::make_object( - td_api::make_object())); - - request_actors_.clear(); - return send_closure_later(actor_id(this), &Td::dec_request_actor_refcnt); // remove guard - } - - state_ = State::Close; - close_flag_ = 1; - G()->set_close_flag(); - send_closure(auth_manager_actor_, &AuthManager::on_closing, destroy_flag); - updates_manager_->timeout_expired(); // save PTS and QTS - - // wait till all request_actors will stop - request_actors_.clear(); - G()->td_db()->flush_all(); - send_closure_later(actor_id(this), &Td::dec_request_actor_refcnt); // remove guard -} - -class Td::DownloadFileCallback final : public FileManager::DownloadCallback { - public: - void on_download_ok(FileId file_id) final { - send_closure(G()->td(), &Td::on_file_download_finished, file_id); - } - - void on_download_error(FileId file_id, Status error) final { - send_closure(G()->td(), &Td::on_file_download_finished, file_id); - } -}; - -class Td::UploadFileCallback final : public FileManager::UploadCallback { - public: - void on_upload_ok(FileId file_id, tl_object_ptr input_file) final { - // cancel file upload of the file to allow next upload with the same file to succeed - send_closure(G()->file_manager(), &FileManager::cancel_upload, file_id); - } - - void on_upload_encrypted_ok(FileId file_id, tl_object_ptr input_file) final { - // cancel file upload of the file to allow next upload with the same file to succeed - send_closure(G()->file_manager(), &FileManager::cancel_upload, file_id); - } - - void on_upload_secure_ok(FileId file_id, tl_object_ptr input_file) final { - // cancel file upload of the file to allow next upload with the same file to succeed - send_closure(G()->file_manager(), &FileManager::cancel_upload, file_id); - } - - void on_upload_error(FileId file_id, Status error) final { - } -}; - -template -void Td::complete_pending_preauthentication_requests(const T &func) { - for (auto &request : pending_preauthentication_requests_) { - if (request.second != nullptr && func(request.second->get_id())) { - downcast_call(*request.second, [this, id = request.first](auto &request) { this->on_request(id, request); }); - request.second = nullptr; - } - } -} - -int32 Td::get_database_scheduler_id() { - auto current_scheduler_id = Scheduler::instance()->sched_id(); - auto scheduler_count = Scheduler::instance()->sched_count(); - return min(current_scheduler_id + 1, scheduler_count - 1); -} - -void Td::finish_set_parameters() { - CHECK(set_parameters_request_id_ != 0); - set_parameters_request_id_ = 0; - - if (pending_set_parameters_requests_.empty()) { - return; - } - - VLOG(td_init) << "Continue to execute " << pending_set_parameters_requests_.size() << " pending requests"; - auto requests = std::move(pending_set_parameters_requests_); - for (auto &request : requests) { - run_request(request.first, std::move(request.second)); - } - CHECK(pending_set_parameters_requests_.size() < requests.size()); -} - -void Td::init(Parameters parameters, Result r_opened_database) { - CHECK(set_parameters_request_id_ != 0); - if (r_opened_database.is_error()) { - LOG(WARNING) << "Failed to open database: " << r_opened_database.error(); - send_closure(actor_id(this), &Td::send_error, set_parameters_request_id_, r_opened_database.move_as_error()); - return finish_set_parameters(); - } - auto events = r_opened_database.move_as_ok(); - - VLOG(td_init) << "Successfully inited database"; - - G()->init(actor_id(this), std::move(events.database)).ensure(); - - init_options_and_network(); - - option_manager_->set_option_boolean("use_storage_optimizer", parameters.enable_storage_optimizer_); - option_manager_->set_option_boolean("ignore_file_names", parameters.ignore_file_names_); - - // we need to process td_api::getOption along with td_api::setOption for consistency - // we need to process td_api::setOption before managers and MTProto header are created, - // because their initialiation may be affected by the options - complete_pending_preauthentication_requests([](int32 id) { - switch (id) { - case td_api::getOption::ID: - case td_api::setOption::ID: - return true; - default: - return false; - } - }); - - if (!option_manager_->get_option_boolean("disable_network_statistics")) { - net_stats_manager_ = create_actor("NetStatsManager", create_reference()); - - // How else could I let two actor know about each other, without quite complex async logic? - auto net_stats_manager_ptr = net_stats_manager_.get_actor_unsafe(); - net_stats_manager_ptr->init(); - G()->connection_creator().get_actor_unsafe()->set_net_stats_callback( - net_stats_manager_ptr->get_common_stats_callback(), net_stats_manager_ptr->get_media_stats_callback()); - G()->set_net_stats_file_callbacks(net_stats_manager_ptr->get_file_stats_callbacks()); - } - - complete_pending_preauthentication_requests([](int32 id) { - switch (id) { - case td_api::getNetworkStatistics::ID: - case td_api::addNetworkStatistics::ID: - case td_api::resetNetworkStatistics::ID: - return true; - default: - return false; - } - }); - - if (events.since_last_open >= 3600) { - auto old_since_last_open = option_manager_->get_option_integer("since_last_open"); - if (events.since_last_open > old_since_last_open) { - option_manager_->set_option_integer("since_last_open", events.since_last_open); - } - } - - options_.language_pack = option_manager_->get_option_string("localization_target"); - options_.language_code = option_manager_->get_option_string("language_pack_id"); - options_.parameters = option_manager_->get_option_string("connection_parameters"); - options_.tz_offset = static_cast(option_manager_->get_option_integer("utc_time_offset")); - options_.is_emulator = option_manager_->get_option_boolean("is_emulator"); - // options_.proxy = Proxy(); - G()->set_mtproto_header(make_unique(options_)); - G()->set_store_all_files_in_files_directory( - option_manager_->get_option_boolean("store_all_files_in_files_directory")); - - VLOG(td_init) << "Create NetQueryDispatcher"; - auto net_query_dispatcher = make_unique([&] { return create_reference(); }); - G()->set_net_query_dispatcher(std::move(net_query_dispatcher)); - - complete_pending_preauthentication_requests([](int32 id) { - // pingProxy uses NetQueryDispatcher to get main_dc_id, so must be called after NetQueryDispatcher is created - return id == td_api::pingProxy::ID; - }); - - VLOG(td_init) << "Create AuthManager"; - auth_manager_ = td::make_unique(parameters.api_id_, parameters.api_hash_, create_reference()); - auth_manager_actor_ = register_actor("AuthManager", auth_manager_.get()); - G()->set_auth_manager(auth_manager_actor_.get()); - - init_file_manager(); - - init_managers(); - - secret_chats_manager_ = - create_actor("SecretChatsManager", create_reference(), parameters.use_secret_chats_); - G()->set_secret_chats_manager(secret_chats_manager_.get()); - - storage_manager_ = create_actor("StorageManager", create_reference(), G()->get_gc_scheduler_id()); - G()->set_storage_manager(storage_manager_.get()); - - option_manager_->on_td_inited(); - - VLOG(td_init) << "Send binlog events"; - for (auto &event : events.user_events) { - contacts_manager_->on_binlog_user_event(std::move(event)); - } - - for (auto &event : events.channel_events) { - contacts_manager_->on_binlog_channel_event(std::move(event)); - } - - // chats may contain links to channels, so should be inited after - for (auto &event : events.chat_events) { - contacts_manager_->on_binlog_chat_event(std::move(event)); - } - - for (auto &event : events.secret_chat_events) { - contacts_manager_->on_binlog_secret_chat_event(std::move(event)); - } - - for (auto &event : events.web_page_events) { - web_pages_manager_->on_binlog_web_page_event(std::move(event)); - } - - for (auto &event : events.save_app_log_events) { - on_save_app_log_binlog_event(this, std::move(event)); - } - - if (option_manager_->get_option_boolean("default_reaction_needs_sync")) { - send_set_default_reaction_query(this); - } - - if (is_online_) { - on_online_updated(true, true); - } - if (auth_manager_->is_bot()) { - set_is_bot_online(true); - } - - // Send binlog events to managers - // - // 1. Actors must receive all binlog events before other queries. - // - // -- All actors have one "entry point". So there is only one way to send query to them. So all queries are ordered - // for each Actor. - // - // 2. An actor must not make some decisions before all binlog events are processed. - // For example, SecretChatActor must not send RequestKey, before it receives log event with RequestKey and understands - // that RequestKey was already sent. - // - // 3. During replay of binlog some queries may be sent to other actors. They shouldn't process such events before all - // their binlog events are processed. So actor may receive some old queries. It must be in its actual state in - // orded to handle them properly. - // - // -- Use send_closure_later, so actors don't even start process binlog events, before all binlog events are sent - - for (auto &event : events.to_secret_chats_manager) { - send_closure_later(secret_chats_manager_, &SecretChatsManager::replay_binlog_event, std::move(event)); - } - - send_closure_later(poll_manager_actor_, &PollManager::on_binlog_events, std::move(events.to_poll_manager)); - - send_closure_later(messages_manager_actor_, &MessagesManager::on_binlog_events, - std::move(events.to_messages_manager)); - - send_closure_later(notification_manager_actor_, &NotificationManager::on_binlog_events, - std::move(events.to_notification_manager)); - - send_closure_later(notification_settings_manager_actor_, &NotificationSettingsManager::on_binlog_events, - std::move(events.to_notification_settings_manager)); - - send_closure(secret_chats_manager_, &SecretChatsManager::binlog_replay_finish); - - VLOG(td_init) << "Ping datacenter"; - if (!auth_manager_->is_authorized()) { - country_info_manager_->get_current_country_code(Promise()); - } else { - updates_manager_->get_difference("init"); - schedule_get_terms_of_service(0); - reload_promo_data(); - } - - complete_pending_preauthentication_requests([](int32 id) { return true; }); - - VLOG(td_init) << "Finish initialization"; - - state_ = State::Run; - - send_closure(actor_id(this), &Td::send_result, set_parameters_request_id_, td_api::make_object()); - return finish_set_parameters(); -} - -void Td::init_options_and_network() { - VLOG(td_init) << "Create StateManager"; - class StateManagerCallback final : public StateManager::Callback { - public: - explicit StateManagerCallback(ActorShared td) : td_(std::move(td)) { - } - bool on_state(ConnectionState state) final { - send_closure(td_, &Td::on_connection_state_changed, state); - return td_.is_alive(); - } - - private: - ActorShared td_; - }; - state_manager_ = create_actor("State manager", create_reference()); - send_closure(state_manager_, &StateManager::add_callback, make_unique(create_reference())); - G()->set_state_manager(state_manager_.get()); - - VLOG(td_init) << "Create OptionManager"; - option_manager_ = make_unique(this); - G()->set_option_manager(option_manager_.get()); - - VLOG(td_init) << "Create ConnectionCreator"; - G()->set_connection_creator(create_actor("ConnectionCreator", create_reference())); - - complete_pending_preauthentication_requests([](int32 id) { - switch (id) { - case td_api::setNetworkType::ID: - case td_api::addProxy::ID: - case td_api::editProxy::ID: - case td_api::enableProxy::ID: - case td_api::disableProxy::ID: - case td_api::removeProxy::ID: - case td_api::getProxies::ID: - case td_api::getProxyLink::ID: - return true; - default: - return false; - } - }); - - VLOG(td_init) << "Create TempAuthKeyWatchdog"; - G()->set_temp_auth_key_watchdog(create_actor("TempAuthKeyWatchdog", create_reference())); - - VLOG(td_init) << "Create ConfigManager"; - config_manager_ = create_actor("ConfigManager", create_reference()); - G()->set_config_manager(config_manager_.get()); -} - -void Td::init_file_manager() { - VLOG(td_init) << "Create FileManager"; - download_file_callback_ = std::make_shared(); - upload_file_callback_ = std::make_shared(); - - class FileManagerContext final : public FileManager::Context { - public: - explicit FileManagerContext(Td *td) : td_(td) { - } - - bool need_notify_on_new_files() final { - return !td_->auth_manager_->is_bot(); - } - - void on_new_file(int64 size, int64 real_size, int32 cnt) final { - send_closure(G()->storage_manager(), &StorageManager::on_new_file, size, real_size, cnt); - } - - void on_file_updated(FileId file_id) final { - send_closure(G()->td(), &Td::send_update, - make_tl_object(td_->file_manager_->get_file_object(file_id))); - } - - bool add_file_source(FileId file_id, FileSourceId file_source_id) final { - return td_->file_reference_manager_->add_file_source(file_id, file_source_id); - } - - bool remove_file_source(FileId file_id, FileSourceId file_source_id) final { - return td_->file_reference_manager_->remove_file_source(file_id, file_source_id); - } - - void on_merge_files(FileId to_file_id, FileId from_file_id) final { - td_->file_reference_manager_->merge(to_file_id, from_file_id); - } - - vector get_some_file_sources(FileId file_id) final { - return td_->file_reference_manager_->get_some_file_sources(file_id); - } - - void repair_file_reference(FileId file_id, Promise promise) final { - send_closure(G()->file_reference_manager(), &FileReferenceManager::repair_file_reference, file_id, - std::move(promise)); - } - - void reload_photo(PhotoSizeSource source, Promise promise) final { - FileReferenceManager::reload_photo(std::move(source), std::move(promise)); - } - - bool keep_exact_remote_location() final { - return !td_->auth_manager_->is_bot(); - } - - ActorShared<> create_reference() final { - return td_->create_reference(); - } - - private: - Td *td_; - }; - - file_manager_ = make_unique(make_unique(this)); - file_manager_actor_ = register_actor("FileManager", file_manager_.get()); - file_manager_->init_actor(); - G()->set_file_manager(file_manager_actor_.get()); - - file_reference_manager_ = make_unique(create_reference()); - file_reference_manager_actor_ = register_actor("FileReferenceManager", file_reference_manager_.get()); - G()->set_file_reference_manager(file_reference_manager_actor_.get()); -} - -void Td::init_managers() { - VLOG(td_init) << "Create Managers"; - audios_manager_ = make_unique(this); - callback_queries_manager_ = make_unique(this); - documents_manager_ = make_unique(this); - videos_manager_ = make_unique(this); - - animations_manager_ = make_unique(this, create_reference()); - animations_manager_actor_ = register_actor("AnimationsManager", animations_manager_.get()); - G()->set_animations_manager(animations_manager_actor_.get()); - attach_menu_manager_ = make_unique(this, create_reference()); - attach_menu_manager_actor_ = register_actor("AttachMenuManager", attach_menu_manager_.get()); - G()->set_attach_menu_manager(attach_menu_manager_actor_.get()); - autosave_manager_ = make_unique(this, create_reference()); - autosave_manager_actor_ = register_actor("AutosaveManager", autosave_manager_.get()); - G()->set_autosave_manager(autosave_manager_actor_.get()); - background_manager_ = make_unique(this, create_reference()); - background_manager_actor_ = register_actor("BackgroundManager", background_manager_.get()); - G()->set_background_manager(background_manager_actor_.get()); - bot_info_manager_ = make_unique(this, create_reference()); - bot_info_manager_actor_ = register_actor("BotInfoManager", bot_info_manager_.get()); - contacts_manager_ = make_unique(this, create_reference()); - contacts_manager_actor_ = register_actor("ContactsManager", contacts_manager_.get()); - G()->set_contacts_manager(contacts_manager_actor_.get()); - country_info_manager_ = make_unique(this, create_reference()); - country_info_manager_actor_ = register_actor("CountryInfoManager", country_info_manager_.get()); - dialog_filter_manager_ = make_unique(this, create_reference()); - dialog_filter_manager_actor_ = register_actor("DialogFilterManager", dialog_filter_manager_.get()); - G()->set_download_manager(download_manager_actor_.get()); - download_manager_ = DownloadManager::create(td::make_unique(this, create_reference())); - download_manager_actor_ = register_actor("DownloadManager", download_manager_.get()); - G()->set_download_manager(download_manager_actor_.get()); - forum_topic_manager_ = make_unique(this, create_reference()); - forum_topic_manager_actor_ = register_actor("ForumTopicManager", forum_topic_manager_.get()); - G()->set_forum_topic_manager(forum_topic_manager_actor_.get()); - game_manager_ = make_unique(this, create_reference()); - game_manager_actor_ = register_actor("GameManager", game_manager_.get()); - G()->set_game_manager(game_manager_actor_.get()); - group_call_manager_ = make_unique(this, create_reference()); - group_call_manager_actor_ = register_actor("GroupCallManager", group_call_manager_.get()); - G()->set_group_call_manager(group_call_manager_actor_.get()); - inline_queries_manager_ = make_unique(this, create_reference()); - inline_queries_manager_actor_ = register_actor("InlineQueriesManager", inline_queries_manager_.get()); - link_manager_ = make_unique(this, create_reference()); - link_manager_actor_ = register_actor("LinkManager", link_manager_.get()); - G()->set_link_manager(link_manager_actor_.get()); - messages_manager_ = make_unique(this, create_reference()); - messages_manager_actor_ = register_actor("MessagesManager", messages_manager_.get()); - G()->set_messages_manager(messages_manager_actor_.get()); - notification_manager_ = make_unique(this, create_reference()); - notification_manager_actor_ = register_actor("NotificationManager", notification_manager_.get()); - G()->set_notification_manager(notification_manager_actor_.get()); - notification_settings_manager_ = make_unique(this, create_reference()); - notification_settings_manager_actor_ = - register_actor("NotificationSettingsManager", notification_settings_manager_.get()); - G()->set_notification_settings_manager(notification_settings_manager_actor_.get()); - poll_manager_ = make_unique(this, create_reference()); - poll_manager_actor_ = register_actor("PollManager", poll_manager_.get()); - sponsored_message_manager_ = make_unique(this, create_reference()); - sponsored_message_manager_actor_ = register_actor("SponsoredMessageManager", sponsored_message_manager_.get()); - G()->set_sponsored_message_manager(sponsored_message_manager_actor_.get()); - stickers_manager_ = make_unique(this, create_reference()); - stickers_manager_actor_ = register_actor("StickersManager", stickers_manager_.get()); - G()->set_stickers_manager(stickers_manager_actor_.get()); - theme_manager_ = make_unique(this, create_reference()); - theme_manager_actor_ = register_actor("ThemeManager", theme_manager_.get()); - G()->set_theme_manager(theme_manager_actor_.get()); - top_dialog_manager_ = make_unique(this, create_reference()); - top_dialog_manager_actor_ = register_actor("TopDialogManager", top_dialog_manager_.get()); - G()->set_top_dialog_manager(top_dialog_manager_actor_.get()); - translation_manager_ = make_unique(this, create_reference()); - translation_manager_actor_ = register_actor("TranslationManager", translation_manager_.get()); - updates_manager_ = make_unique(this, create_reference()); - updates_manager_actor_ = register_actor("UpdatesManager", updates_manager_.get()); - G()->set_updates_manager(updates_manager_actor_.get()); - video_notes_manager_ = make_unique(this, create_reference()); - video_notes_manager_actor_ = register_actor("VideoNotesManager", video_notes_manager_.get()); - voice_notes_manager_ = make_unique(this, create_reference()); - voice_notes_manager_actor_ = register_actor("VoiceNotesManager", voice_notes_manager_.get()); - web_pages_manager_ = make_unique(this, create_reference()); - web_pages_manager_actor_ = register_actor("WebPagesManager", web_pages_manager_.get()); - G()->set_web_pages_manager(web_pages_manager_actor_.get()); - - call_manager_ = create_actor("CallManager", create_reference()); - G()->set_call_manager(call_manager_.get()); - change_phone_number_manager_ = create_actor( - "ChangePhoneNumberManager", PhoneNumberManager::Type::ChangePhone, create_reference()); - confirm_phone_number_manager_ = create_actor( - "ConfirmPhoneNumberManager", PhoneNumberManager::Type::ConfirmPhone, create_reference()); - device_token_manager_ = create_actor("DeviceTokenManager", create_reference()); - hashtag_hints_ = create_actor("HashtagHints", "text", create_reference()); - language_pack_manager_ = create_actor("LanguagePackManager", create_reference()); - G()->set_language_pack_manager(language_pack_manager_.get()); - password_manager_ = create_actor("PasswordManager", create_reference()); - G()->set_password_manager(password_manager_.get()); - privacy_manager_ = create_actor("PrivacyManager", create_reference()); - secure_manager_ = create_actor("SecureManager", create_reference()); - verify_phone_number_manager_ = create_actor( - "VerifyPhoneNumberManager", PhoneNumberManager::Type::VerifyPhone, create_reference()); -} - -void Td::send_update(tl_object_ptr &&object) { - CHECK(object != nullptr); - auto object_id = object->get_id(); - if (close_flag_ >= 5 && object_id != td_api::updateAuthorizationState::ID) { - // just in case - return; - } - - switch (object_id) { - case td_api::updateChatThemes::ID: - case td_api::updateFavoriteStickers::ID: - case td_api::updateInstalledStickerSets::ID: - case td_api::updateRecentStickers::ID: - case td_api::updateSavedAnimations::ID: - case td_api::updateSavedNotificationSounds::ID: - case td_api::updateUserStatus::ID: - VLOG(td_requests) << "Sending update: " << oneline(to_string(object)); - break; - case td_api::updateTrendingStickerSets::ID: { - auto update = static_cast(object.get()); - auto sticker_sets = update->sticker_sets_.get(); - VLOG(td_requests) << "Sending update: updateTrendingStickerSets { " << oneline(to_string(update->sticker_type_)) - << ", total_count = " << sticker_sets->total_count_ - << ", count = " << sticker_sets->sets_.size() << " }"; - break; - } - case td_api::updateAnimatedEmojiMessageClicked::ID / 2: - case td_api::updateOption::ID / 2: - case td_api::updateChatReadInbox::ID / 2: - case td_api::updateUnreadMessageCount::ID / 2: - case td_api::updateUnreadChatCount::ID / 2: - case td_api::updateChatOnlineMemberCount::ID / 2: - case td_api::updateChatAction::ID / 2: - case td_api::updateChatFolders::ID / 2: - case td_api::updateChatPosition::ID / 2: - case td_api::updateFileAddedToDownloads::ID / 2: - case td_api::updateFileDownload::ID / 2: - case td_api::updateFileRemovedFromDownloads::ID / 2: - case td_api::updateDefaultReactionType::ID / 2: - LOG(ERROR) << "Sending update: " << oneline(to_string(object)); - break; - default: - VLOG(td_requests) << "Sending update: " << to_string(object); - } - - callback_->on_result(0, std::move(object)); -} - -void Td::send_result(uint64 id, tl_object_ptr object) { - if (id == 0) { - LOG(ERROR) << "Sending " << to_string(object) << " through send_result"; - return; - } - - auto it = request_set_.find(id); - if (it != request_set_.end()) { - if (object == nullptr) { - object = make_tl_object(404, "Not Found"); - } - VLOG(td_requests) << "Sending result for request " << id << ": " << to_string(object); - request_set_.erase(it); - callback_->on_result(id, std::move(object)); - } -} - -void Td::send_error_impl(uint64 id, tl_object_ptr error) { - CHECK(id != 0); - CHECK(error != nullptr); - auto it = request_set_.find(id); - if (it != request_set_.end()) { - if (error->code_ == 0 && error->message_ == "Lost promise") { - LOG(FATAL) << "Lost promise for query " << id << " of type " << it->second << " in close state " << close_flag_; - } - VLOG(td_requests) << "Sending error for request " << id << ": " << oneline(to_string(error)); - request_set_.erase(it); - callback_->on_error(id, std::move(error)); - } -} - -void Td::send_error(uint64 id, Status error) { - send_error_impl(id, make_tl_object(error.code(), error.message().str())); - error.ignore(); -} - -void Td::send_error_raw(uint64 id, int32 code, CSlice error) { - send_closure(actor_id(this), &Td::send_error_impl, id, make_error(code, error)); -} - -void Td::answer_ok_query(uint64 id, Status status) { - if (status.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, std::move(status)); - } else { - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); - } -} - -Promise Td::create_ok_request_promise(uint64 id) { - return PromiseCreator::lambda([id = id, actor_id = actor_id(this)](Result result) { - if (result.is_error()) { - send_closure(actor_id, &Td::send_error, id, result.move_as_error()); - } else { - send_closure(actor_id, &Td::send_result, id, td_api::make_object()); - } - }); -} - -#define CLEAN_INPUT_STRING(field_name) \ - if (!clean_input_string(field_name)) { \ - return send_error_raw(id, 400, "Strings must be encoded in UTF-8"); \ - } -#define CHECK_IS_BOT() \ - if (!auth_manager_->is_bot()) { \ - return send_error_raw(id, 400, "Only bots can use the method"); \ - } -#define CHECK_IS_USER() \ - if (auth_manager_->is_bot()) { \ - return send_error_raw(id, 400, "The method is not available to bots"); \ - } - -#define CREATE_NO_ARGS_REQUEST(name) \ - auto slot_id = request_actors_.create(ActorOwn<>(), RequestActorIdType); \ - inc_request_actor_refcnt(); \ - *request_actors_.get(slot_id) = create_actor(#name, actor_shared(this, slot_id), id); -#define CREATE_REQUEST(name, ...) \ - auto slot_id = request_actors_.create(ActorOwn<>(), RequestActorIdType); \ - inc_request_actor_refcnt(); \ - *request_actors_.get(slot_id) = create_actor(#name, actor_shared(this, slot_id), id, __VA_ARGS__); -#define CREATE_REQUEST_PROMISE() auto promise = create_request_promise::ReturnType>(id) -#define CREATE_OK_REQUEST_PROMISE() \ - static_assert(std::is_same::ReturnType, td_api::object_ptr>::value, ""); \ - auto promise = create_ok_request_promise(id) - -Result> Td::get_parameters( - td_api::object_ptr parameters) { - VLOG(td_init) << "Begin to set TDLib parameters"; - if (!clean_input_string(parameters->api_hash_) || !clean_input_string(parameters->system_language_code_) || - !clean_input_string(parameters->device_model_) || !clean_input_string(parameters->system_version_) || - !clean_input_string(parameters->application_version_)) { - VLOG(td_init) << "Wrong string encoding"; - return Status::Error(400, "Strings must be encoded in UTF-8"); - } - - if (parameters->api_id_ <= 0) { - return Status::Error(400, "Valid api_id must be provided. Can be obtained at https://my.telegram.org"); - } - if (parameters->api_hash_.empty()) { - return Status::Error(400, "Valid api_hash must be provided. Can be obtained at https://my.telegram.org"); - } - - std::pair result; - result.first.api_id_ = parameters->api_id_; - result.first.api_hash_ = std::move(parameters->api_hash_); - result.first.use_secret_chats_ = parameters->use_secret_chats_; - result.first.enable_storage_optimizer_ = parameters->enable_storage_optimizer_; - result.first.ignore_file_names_ = parameters->ignore_file_names_; - - result.second.encryption_key_ = as_db_key(std::move(parameters->database_encryption_key_)); - result.second.database_directory_ = std::move(parameters->database_directory_); - result.second.files_directory_ = std::move(parameters->files_directory_); - result.second.is_test_dc_ = parameters->use_test_dc_; - result.second.use_file_database_ = parameters->use_file_database_; - result.second.use_chat_info_database_ = parameters->use_chat_info_database_; - result.second.use_message_database_ = parameters->use_message_database_; - - VLOG(td_init) << "Create MtprotoHeader::Options"; - options_.api_id = parameters->api_id_; - options_.system_language_code = trim(parameters->system_language_code_); - options_.device_model = trim(parameters->device_model_); - options_.system_version = trim(parameters->system_version_); - options_.application_version = trim(parameters->application_version_); - if (options_.system_language_code.empty()) { - return Status::Error(400, "System language code must be non-empty"); - } - if (options_.device_model.empty()) { - return Status::Error(400, "Device model must be non-empty"); - } - if (options_.system_version.empty()) { - options_.system_version = get_operating_system_version().str(); - VLOG(td_init) << "Set system version to " << options_.system_version; - } - if (options_.application_version.empty()) { - return Status::Error(400, "Application version must be non-empty"); - } - if (options_.api_id != 21724) { - options_.application_version += ", TDLib "; - auto version = OptionManager::get_option_synchronously("version"); - CHECK(version->get_id() == td_api::optionValueString::ID); - options_.application_version += static_cast(version.get())->value_; - } - options_.language_pack = string(); - options_.language_code = string(); - options_.parameters = string(); - options_.is_emulator = false; - options_.proxy = Proxy(); - - return std::move(result); -} - -void Td::on_request(uint64 id, const td_api::setTdlibParameters &request) { - send_error_raw(id, 400, "Unexpected setTdlibParameters"); -} - -void Td::on_request(uint64 id, td_api::setDatabaseEncryptionKey &request) { - CREATE_OK_REQUEST_PROMISE(); - G()->td_db()->get_binlog()->change_key(as_db_key(std::move(request.new_encryption_key_)), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getAuthorizationState &request) { - send_closure(auth_manager_actor_, &AuthManager::get_state, id); -} - -void Td::on_request(uint64 id, td_api::setAuthenticationPhoneNumber &request) { - CLEAN_INPUT_STRING(request.phone_number_); - send_closure(auth_manager_actor_, &AuthManager::set_phone_number, id, std::move(request.phone_number_), - std::move(request.settings_)); -} - -void Td::on_request(uint64 id, td_api::sendAuthenticationFirebaseSms &request) { - CLEAN_INPUT_STRING(request.token_); - send_closure(auth_manager_actor_, &AuthManager::set_firebase_token, id, std::move(request.token_)); -} - -void Td::on_request(uint64 id, td_api::setAuthenticationEmailAddress &request) { - CLEAN_INPUT_STRING(request.email_address_); - send_closure(auth_manager_actor_, &AuthManager::set_email_address, id, std::move(request.email_address_)); -} - -void Td::on_request(uint64 id, const td_api::resendAuthenticationCode &request) { - send_closure(auth_manager_actor_, &AuthManager::resend_authentication_code, id); -} - -void Td::on_request(uint64 id, td_api::checkAuthenticationEmailCode &request) { - send_closure(auth_manager_actor_, &AuthManager::check_email_code, id, EmailVerification(std::move(request.code_))); -} - -void Td::on_request(uint64 id, td_api::checkAuthenticationCode &request) { - CLEAN_INPUT_STRING(request.code_); - send_closure(auth_manager_actor_, &AuthManager::check_code, id, std::move(request.code_)); -} - -void Td::on_request(uint64 id, td_api::registerUser &request) { - CLEAN_INPUT_STRING(request.first_name_); - CLEAN_INPUT_STRING(request.last_name_); - send_closure(auth_manager_actor_, &AuthManager::register_user, id, std::move(request.first_name_), - std::move(request.last_name_)); -} - -void Td::on_request(uint64 id, td_api::requestQrCodeAuthentication &request) { - send_closure(auth_manager_actor_, &AuthManager::request_qr_code_authentication, id, - UserId::get_user_ids(request.other_user_ids_)); -} - -void Td::on_request(uint64 id, const td_api::resetAuthenticationEmailAddress &request) { - send_closure(auth_manager_actor_, &AuthManager::reset_email_address, id); -} - -void Td::on_request(uint64 id, td_api::checkAuthenticationPassword &request) { - CLEAN_INPUT_STRING(request.password_); - send_closure(auth_manager_actor_, &AuthManager::check_password, id, std::move(request.password_)); -} - -void Td::on_request(uint64 id, const td_api::requestAuthenticationPasswordRecovery &request) { - send_closure(auth_manager_actor_, &AuthManager::request_password_recovery, id); -} - -void Td::on_request(uint64 id, td_api::checkAuthenticationPasswordRecoveryCode &request) { - CLEAN_INPUT_STRING(request.recovery_code_); - send_closure(auth_manager_actor_, &AuthManager::check_password_recovery_code, id, std::move(request.recovery_code_)); -} - -void Td::on_request(uint64 id, td_api::recoverAuthenticationPassword &request) { - CLEAN_INPUT_STRING(request.recovery_code_); - CLEAN_INPUT_STRING(request.new_password_); - CLEAN_INPUT_STRING(request.new_hint_); - send_closure(auth_manager_actor_, &AuthManager::recover_password, id, std::move(request.recovery_code_), - std::move(request.new_password_), std::move(request.new_hint_)); -} - -void Td::on_request(uint64 id, const td_api::logOut &request) { - // will call Td::destroy later - send_closure(auth_manager_actor_, &AuthManager::log_out, id); -} - -void Td::on_request(uint64 id, const td_api::close &request) { - // send response before actually closing - send_closure(actor_id(this), &Td::send_result, id, td_api::make_object()); - send_closure(actor_id(this), &Td::close); -} - -void Td::on_request(uint64 id, const td_api::destroy &request) { - // send response before actually destroying - send_closure(actor_id(this), &Td::send_result, id, td_api::make_object()); - send_closure(actor_id(this), &Td::destroy); -} - -void Td::on_request(uint64 id, td_api::checkAuthenticationBotToken &request) { - CLEAN_INPUT_STRING(request.token_); - send_closure(auth_manager_actor_, &AuthManager::check_bot_token, id, std::move(request.token_)); -} - -void Td::on_request(uint64 id, td_api::confirmQrCodeAuthentication &request) { - CLEAN_INPUT_STRING(request.link_); - CREATE_REQUEST_PROMISE(); - confirm_qr_code_authentication(this, request.link_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getCurrentState &request) { - vector> updates; - - option_manager_->get_current_state(updates); - - auto state = auth_manager_->get_current_authorization_state_object(); - if (state != nullptr) { - updates.push_back(td_api::make_object(std::move(state))); - } - - updates.push_back(get_update_connection_state_object(connection_state_)); - - if (auth_manager_->is_authorized()) { - contacts_manager_->get_current_state(updates); - - background_manager_->get_current_state(updates); - - animations_manager_->get_current_state(updates); - - attach_menu_manager_->get_current_state(updates); - - stickers_manager_->get_current_state(updates); - - notification_settings_manager_->get_current_state(updates); - - dialog_filter_manager_->get_current_state(updates); - - messages_manager_->get_current_state(updates); - - notification_manager_->get_current_state(updates); - - config_manager_.get_actor_unsafe()->get_current_state(updates); - - autosave_manager_->get_current_state(updates); - - // TODO updateFileGenerationStart generation_id:int64 original_path:string destination_path:string conversion:string = Update; - // TODO updateCall call:call = Update; - // TODO updateGroupCall call:groupCall = Update; - } - - auto update_terms_of_service = get_update_terms_of_service_object(); - if (update_terms_of_service != nullptr) { - updates.push_back(std::move(update_terms_of_service)); - } - - // send response synchronously to prevent "Request aborted" or other changes of the current state - send_result(id, td_api::make_object(std::move(updates))); -} - -void Td::on_request(uint64 id, td_api::getPasswordState &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::get_state, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setPassword &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.old_password_); - CLEAN_INPUT_STRING(request.new_password_); - CLEAN_INPUT_STRING(request.new_hint_); - CLEAN_INPUT_STRING(request.new_recovery_email_address_); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::set_password, std::move(request.old_password_), - std::move(request.new_password_), std::move(request.new_hint_), request.set_recovery_email_address_, - std::move(request.new_recovery_email_address_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setLoginEmailAddress &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.new_login_email_address_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_email_address_authentication_code_info_object()); - } - }); - send_closure(password_manager_, &PasswordManager::set_login_email_address, - std::move(request.new_login_email_address_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::resendLoginEmailAddressCode &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_email_address_authentication_code_info_object()); - } - }); - send_closure(password_manager_, &PasswordManager::resend_login_email_address_code, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::checkLoginEmailAddressCode &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::check_login_email_address_code, - EmailVerification(std::move(request.code_)), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setRecoveryEmailAddress &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); - CLEAN_INPUT_STRING(request.new_recovery_email_address_); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::set_recovery_email_address, std::move(request.password_), - std::move(request.new_recovery_email_address_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getRecoveryEmailAddress &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::get_recovery_email_address, std::move(request.password_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::checkRecoveryEmailAddressCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.code_); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::check_recovery_email_address_code, std::move(request.code_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::resendRecoveryEmailAddressCode &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::resend_recovery_email_address_code, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::requestPasswordRecovery &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_email_address_authentication_code_info_object()); - } - }); - send_closure(password_manager_, &PasswordManager::request_password_recovery, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::checkPasswordRecoveryCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.recovery_code_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::check_password_recovery_code, std::move(request.recovery_code_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::recoverPassword &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.recovery_code_); - CLEAN_INPUT_STRING(request.new_password_); - CLEAN_INPUT_STRING(request.new_hint_); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::recover_password, std::move(request.recovery_code_), - std::move(request.new_password_), std::move(request.new_hint_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::resetPassword &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::reset_password, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::cancelPasswordReset &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::cancel_password_reset, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getTemporaryPasswordState &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::get_temp_password_state, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::createTemporaryPassword &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); - CREATE_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::create_temp_password, std::move(request.password_), - request.valid_for_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::processPushNotification &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.payload_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->notification_manager(), &NotificationManager::process_push_notification, - std::move(request.payload_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::registerDevice &request) { - CHECK_IS_USER(); - if (request.device_token_ == nullptr) { - return send_error_raw(id, 400, "Device token must be non-empty"); - } - CREATE_REQUEST_PROMISE(); - send_closure(device_token_manager_, &DeviceTokenManager::register_device, std::move(request.device_token_), - UserId::get_user_ids(request.other_user_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getUserPrivacySettingRules &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - send_closure(privacy_manager_, &PrivacyManager::get_privacy, std::move(request.setting_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setUserPrivacySettingRules &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(privacy_manager_, &PrivacyManager::set_privacy, std::move(request.setting_), std::move(request.rules_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getDefaultMessageAutoDeleteTime &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.ok())); - } - }); - get_default_message_ttl(this, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::setDefaultMessageAutoDeleteTime &request) { - CHECK_IS_USER(); - if (request.message_auto_delete_time_ == nullptr) { - return send_error_raw(id, 400, "New default message auto-delete time must be non-empty"); - } - CREATE_OK_REQUEST_PROMISE(); - set_default_message_ttl(this, request.message_auto_delete_time_->time_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getAccountTtl &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.ok())); - } - }); - get_account_ttl(this, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::setAccountTtl &request) { - CHECK_IS_USER(); - if (request.ttl_ == nullptr) { - return send_error_raw(id, 400, "New account TTL must be non-empty"); - } - CREATE_OK_REQUEST_PROMISE(); - set_account_ttl(this, request.ttl_->days_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::deleteAccount &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.reason_); - send_closure(auth_manager_actor_, &AuthManager::delete_account, id, request.reason_, request.password_); -} - -void Td::on_request(uint64 id, td_api::changePhoneNumber &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.phone_number_); - send_closure(change_phone_number_manager_, &PhoneNumberManager::set_phone_number, id, - std::move(request.phone_number_), std::move(request.settings_)); -} - -void Td::on_request(uint64 id, td_api::checkChangePhoneNumberCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.code_); - send_closure(change_phone_number_manager_, &PhoneNumberManager::check_code, id, std::move(request.code_)); -} - -void Td::on_request(uint64 id, td_api::resendChangePhoneNumberCode &request) { - CHECK_IS_USER(); - send_closure(change_phone_number_manager_, &PhoneNumberManager::resend_authentication_code, id); -} - -void Td::on_request(uint64 id, const td_api::getUserLink &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_user_link(std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::searchUserByToken &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.token_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->search_user_by_token(std::move(request.token_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getActiveSessions &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_active_sessions(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::terminateSession &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - terminate_session(this, request.session_id_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::terminateAllOtherSessions &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - terminate_all_other_sessions(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSessionCanAcceptCalls &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - toggle_session_can_accept_calls(this, request.session_id_, request.can_accept_calls_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSessionCanAcceptSecretChats &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - toggle_session_can_accept_secret_chats(this, request.session_id_, request.can_accept_secret_chats_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setInactiveSessionTtl &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - set_inactive_session_ttl_days(this, request.inactive_session_ttl_days_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getConnectedWebsites &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_connected_websites(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::disconnectWebsite &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - disconnect_website(this, request.website_id_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::disconnectAllWebsites &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - disconnect_all_websites(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getMe &request) { - CREATE_NO_ARGS_REQUEST(GetMeRequest); -} - -void Td::on_request(uint64 id, const td_api::getUser &request) { - CREATE_REQUEST(GetUserRequest, request.user_id_); -} - -void Td::on_request(uint64 id, const td_api::getUserFullInfo &request) { - CREATE_REQUEST(GetUserFullInfoRequest, request.user_id_); -} - -void Td::on_request(uint64 id, const td_api::getBasicGroup &request) { - CREATE_REQUEST(GetGroupRequest, request.basic_group_id_); -} - -void Td::on_request(uint64 id, const td_api::getBasicGroupFullInfo &request) { - CREATE_REQUEST(GetGroupFullInfoRequest, request.basic_group_id_); -} - -void Td::on_request(uint64 id, const td_api::getSupergroup &request) { - CREATE_REQUEST(GetSupergroupRequest, request.supergroup_id_); -} - -void Td::on_request(uint64 id, const td_api::getSupergroupFullInfo &request) { - CREATE_REQUEST(GetSupergroupFullInfoRequest, request.supergroup_id_); -} - -void Td::on_request(uint64 id, const td_api::getSecretChat &request) { - CREATE_REQUEST(GetSecretChatRequest, request.secret_chat_id_); -} - -void Td::on_request(uint64 id, const td_api::getChat &request) { - CREATE_REQUEST(GetChatRequest, request.chat_id_); -} - -void Td::on_request(uint64 id, const td_api::getMessage &request) { - CREATE_REQUEST(GetMessageRequest, request.chat_id_, request.message_id_); -} - -void Td::on_request(uint64 id, const td_api::getMessageLocally &request) { - FullMessageId full_message_id(DialogId(request.chat_id_), MessageId(request.message_id_)); - send_closure(actor_id(this), &Td::send_result, id, - messages_manager_->get_message_object(full_message_id, "getMessageLocally")); -} - -void Td::on_request(uint64 id, const td_api::getRepliedMessage &request) { - CREATE_REQUEST(GetRepliedMessageRequest, request.chat_id_, request.message_id_); -} - -void Td::on_request(uint64 id, const td_api::getChatPinnedMessage &request) { - CREATE_REQUEST(GetChatPinnedMessageRequest, request.chat_id_); -} - -void Td::on_request(uint64 id, const td_api::getCallbackQueryMessage &request) { - CHECK_IS_BOT(); - CREATE_REQUEST(GetCallbackQueryMessageRequest, request.chat_id_, request.message_id_, request.callback_query_id_); -} - -void Td::on_request(uint64 id, const td_api::getMessages &request) { - CREATE_REQUEST(GetMessagesRequest, request.chat_id_, request.message_ids_); -} - -void Td::on_request(uint64 id, const td_api::getChatSponsoredMessages &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - sponsored_message_manager_->get_dialog_sponsored_messages(DialogId(request.chat_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getMessageThread &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetMessageThreadRequest, request.chat_id_, request.message_id_); -} - -void Td::on_request(uint64 id, const td_api::getMessageViewers &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - messages_manager_->get_message_viewers({DialogId(request.chat_id_), MessageId(request.message_id_)}, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getMessageLink &request) { - auto r_message_link = - messages_manager_->get_message_link({DialogId(request.chat_id_), MessageId(request.message_id_)}, - request.media_timestamp_, request.for_album_, request.in_message_thread_); - if (r_message_link.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, r_message_link.move_as_error()); - } else { - send_closure(actor_id(this), &Td::send_result, id, - td_api::make_object(r_message_link.ok().first, r_message_link.ok().second)); - } -} - -void Td::on_request(uint64 id, const td_api::getMessageEmbeddingCode &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetMessageEmbeddingCodeRequest, request.chat_id_, request.message_id_, request.for_album_); -} - -void Td::on_request(uint64 id, td_api::getMessageLinkInfo &request) { - CLEAN_INPUT_STRING(request.url_); - CREATE_REQUEST(GetMessageLinkInfoRequest, std::move(request.url_)); -} - -void Td::on_request(uint64 id, td_api::translateText &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.to_language_code_); - CREATE_REQUEST_PROMISE(); - translation_manager_->translate_text(std::move(request.text_), request.to_language_code_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::translateMessageText &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.to_language_code_); - CREATE_REQUEST_PROMISE(); - messages_manager_->translate_message_text({DialogId(request.chat_id_), MessageId(request.message_id_)}, - request.to_language_code_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::recognizeSpeech &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->recognize_speech({DialogId(request.chat_id_), MessageId(request.message_id_)}, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::rateSpeechRecognition &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->rate_speech_recognition({DialogId(request.chat_id_), MessageId(request.message_id_)}, - request.is_good_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getFile &request) { - auto file_object = file_manager_->get_file_object(FileId(request.file_id_, 0)); - if (file_object->id_ == 0) { - file_object = nullptr; - } else { - file_object->id_ = request.file_id_; - } - send_closure(actor_id(this), &Td::send_result, id, std::move(file_object)); -} - -void Td::on_request(uint64 id, td_api::getRemoteFile &request) { - CLEAN_INPUT_STRING(request.remote_file_id_); - auto file_type = request.file_type_ == nullptr ? FileType::Temp : get_file_type(*request.file_type_); - auto r_file_id = file_manager_->from_persistent_id(request.remote_file_id_, file_type); - if (r_file_id.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, r_file_id.move_as_error()); - } else { - send_closure(actor_id(this), &Td::send_result, id, file_manager_->get_file_object(r_file_id.ok())); - } -} - -void Td::on_request(uint64 id, td_api::getStorageStatistics &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_storage_statistics_object()); - } - }); - send_closure(storage_manager_, &StorageManager::get_storage_stats, false /*need_all_files*/, request.chat_limit_, - std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::getStorageStatisticsFast &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_storage_statistics_fast_object()); - } - }); - send_closure(storage_manager_, &StorageManager::get_storage_stats_fast, std::move(query_promise)); -} -void Td::on_request(uint64 id, td_api::getDatabaseStatistics &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_database_statistics_object()); - } - }); - send_closure(storage_manager_, &StorageManager::get_database_stats, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::optimizeStorage &request) { - std::vector file_types; - for (auto &file_type : request.file_types_) { - if (file_type == nullptr) { - return send_error_raw(id, 400, "File type must be non-empty"); - } - - file_types.push_back(get_file_type(*file_type)); - } - FileGcParameters parameters(request.size_, request.ttl_, request.count_, request.immunity_delay_, - std::move(file_types), DialogId::get_dialog_ids(request.chat_ids_), - DialogId::get_dialog_ids(request.exclude_chat_ids_), request.chat_limit_); - - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_storage_statistics_object()); - } - }); - send_closure(storage_manager_, &StorageManager::run_gc, std::move(parameters), - request.return_deleted_file_statistics_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::getNetworkStatistics &request) { - if (net_stats_manager_.empty()) { - return send_error_raw(id, 400, "Network statistics is disabled"); - } - if (!request.only_current_ && G()->get_option_boolean("disable_persistent_network_statistics")) { - return send_error_raw(id, 400, "Persistent network statistics is disabled"); - } - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_network_statistics_object()); - } - }); - send_closure(net_stats_manager_, &NetStatsManager::get_network_stats, request.only_current_, - std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::resetNetworkStatistics &request) { - if (net_stats_manager_.empty()) { - return send_error_raw(id, 400, "Network statistics is disabled"); - } - CREATE_OK_REQUEST_PROMISE(); - send_closure(net_stats_manager_, &NetStatsManager::reset_network_stats); - promise.set_value(Unit()); -} - -void Td::on_request(uint64 id, td_api::addNetworkStatistics &request) { - if (request.entry_ == nullptr) { - return send_error_raw(id, 400, "Network statistics entry must be non-empty"); - } - if (net_stats_manager_.empty()) { - return send_error_raw(id, 400, "Network statistics is disabled"); - } - - NetworkStatsEntry entry; - switch (request.entry_->get_id()) { - case td_api::networkStatisticsEntryFile::ID: { - auto file_entry = move_tl_object_as(request.entry_); - entry.is_call = false; - if (file_entry->file_type_ != nullptr) { - entry.file_type = get_file_type(*file_entry->file_type_); - } - entry.net_type = get_net_type(file_entry->network_type_); - entry.rx = file_entry->received_bytes_; - entry.tx = file_entry->sent_bytes_; - break; - } - case td_api::networkStatisticsEntryCall::ID: { - auto call_entry = move_tl_object_as(request.entry_); - entry.is_call = true; - entry.net_type = get_net_type(call_entry->network_type_); - entry.rx = call_entry->received_bytes_; - entry.tx = call_entry->sent_bytes_; - entry.duration = call_entry->duration_; - break; - } - default: - UNREACHABLE(); - } - - if (entry.net_type == NetType::None) { - return send_error_raw(id, 400, "Network statistics entry can't be increased for NetworkTypeNone"); - } - if (entry.rx > (static_cast(1) << 40) || entry.rx < 0) { - return send_error_raw(id, 400, "Wrong received bytes value"); - } - if (entry.tx > (static_cast(1) << 40) || entry.tx < 0) { - return send_error_raw(id, 400, "Wrong sent bytes value"); - } - if (entry.count > (1 << 30) || entry.count < 0) { - return send_error_raw(id, 400, "Wrong count value"); - } - if (entry.duration > (1 << 30) || entry.duration < 0) { - return send_error_raw(id, 400, "Wrong duration value"); - } - - send_closure(net_stats_manager_, &NetStatsManager::add_network_stats, entry); - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, const td_api::setNetworkType &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(state_manager_, &StateManager::on_network, get_net_type(request.type_)); - promise.set_value(Unit()); -} - -void Td::on_request(uint64 id, const td_api::getAutoDownloadSettingsPresets &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_auto_download_settings_presets(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setAutoDownloadSettings &request) { - CHECK_IS_USER(); - if (request.settings_ == nullptr) { - return send_error_raw(id, 400, "New settings must be non-empty"); - } - CREATE_OK_REQUEST_PROMISE(); - set_auto_download_settings(this, get_net_type(request.type_), get_auto_download_settings(request.settings_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getAutosaveSettings &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - autosave_manager_->get_autosave_settings(std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setAutosaveSettings &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - autosave_manager_->set_autosave_settings(std::move(request.scope_), std::move(request.settings_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::clearAutosaveSettingsExceptions &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - autosave_manager_->clear_autosave_settings_excpetions(std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getTopChats &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - send_closure(top_dialog_manager_actor_, &TopDialogManager::get_top_dialogs, - get_top_dialog_category(request.category_), request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::removeTopChat &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(top_dialog_manager_actor_, &TopDialogManager::remove_dialog, get_top_dialog_category(request.category_), - DialogId(request.chat_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::loadChats &request) { - CHECK_IS_USER(); - - DialogListId dialog_list_id(request.chat_list_); - auto r_offset = messages_manager_->get_dialog_list_last_date(dialog_list_id); - if (r_offset.is_error()) { - return send_error_raw(id, 400, r_offset.error().message()); - } - auto offset = r_offset.move_as_ok(); - if (offset == MAX_DIALOG_DATE) { - return send_closure(actor_id(this), &Td::send_result, id, nullptr); - } - - CREATE_REQUEST(LoadChatsRequest, dialog_list_id, offset, request.limit_); -} - -void Td::on_request(uint64 id, const td_api::getChats &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - messages_manager_->get_dialogs_from_list(DialogListId(request.chat_list_), request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::searchPublicChat &request) { - CLEAN_INPUT_STRING(request.username_); - CREATE_REQUEST(SearchPublicChatRequest, request.username_); -} - -void Td::on_request(uint64 id, td_api::searchPublicChats &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST(SearchPublicChatsRequest, request.query_); -} - -void Td::on_request(uint64 id, td_api::searchChats &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST(SearchChatsRequest, request.query_, request.limit_); -} - -void Td::on_request(uint64 id, td_api::searchChatsOnServer &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST(SearchChatsOnServerRequest, request.query_, request.limit_); -} - -void Td::on_request(uint64 id, const td_api::searchChatsNearby &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - contacts_manager_->search_dialogs_nearby(Location(request.location_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getGroupsInCommon &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetGroupsInCommonRequest, request.user_id_, request.offset_chat_id_, request.limit_); -} - -void Td::on_request(uint64 id, td_api::checkChatUsername &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.username_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda( - [promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(ContactsManager::get_check_chat_username_result_object(result.ok())); - } - }); - contacts_manager_->check_dialog_username(DialogId(request.chat_id_), request.username_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getCreatedPublicChats &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_created_public_dialogs(get_public_dialog_type(request.type_), std::move(promise), false); -} - -void Td::on_request(uint64 id, const td_api::checkCreatedPublicChatsLimit &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->check_created_public_dialogs_limit(get_public_dialog_type(request.type_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getSuitableDiscussionChats &request) { - CHECK_IS_USER(); - CREATE_NO_ARGS_REQUEST(GetSuitableDiscussionChatsRequest); -} - -void Td::on_request(uint64 id, const td_api::getInactiveSupergroupChats &request) { - CHECK_IS_USER(); - CREATE_NO_ARGS_REQUEST(GetInactiveSupergroupChatsRequest); -} - -void Td::on_request(uint64 id, const td_api::addRecentlyFoundChat &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->add_recently_found_dialog(DialogId(request.chat_id_))); -} - -void Td::on_request(uint64 id, const td_api::removeRecentlyFoundChat &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->remove_recently_found_dialog(DialogId(request.chat_id_))); -} - -void Td::on_request(uint64 id, const td_api::clearRecentlyFoundChats &request) { - CHECK_IS_USER(); - messages_manager_->clear_recently_found_dialogs(); - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, const td_api::getRecentlyOpenedChats &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetRecentlyOpenedChatsRequest, request.limit_); -} - -void Td::on_request(uint64 id, const td_api::openChat &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->open_dialog(DialogId(request.chat_id_))); -} - -void Td::on_request(uint64 id, const td_api::closeChat &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->close_dialog(DialogId(request.chat_id_))); -} - -void Td::on_request(uint64 id, const td_api::viewMessages &request) { - CHECK_IS_USER(); - answer_ok_query( - id, messages_manager_->view_messages(DialogId(request.chat_id_), MessageId::get_message_ids(request.message_ids_), - get_message_source(request.source_), request.force_read_)); -} - -void Td::on_request(uint64 id, const td_api::openMessageContent &request) { - CHECK_IS_USER(); - answer_ok_query( - id, messages_manager_->open_message_content({DialogId(request.chat_id_), MessageId(request.message_id_)})); -} - -void Td::on_request(uint64 id, const td_api::clickAnimatedEmojiMessage &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - messages_manager_->click_animated_emoji_message({DialogId(request.chat_id_), MessageId(request.message_id_)}, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getInternalLink &request) { - auto r_link = LinkManager::get_internal_link(request.type_, !request.is_http_); - if (r_link.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, r_link.move_as_error()); - } else { - send_closure(actor_id(this), &Td::send_result, id, td_api::make_object(r_link.move_as_ok())); - } -} - -void Td::on_request(uint64 id, const td_api::getInternalLinkType &request) { - auto type = LinkManager::parse_internal_link(request.link_); - send_closure(actor_id(this), &Td::send_result, id, type == nullptr ? nullptr : type->get_internal_link_type_object()); -} - -void Td::on_request(uint64 id, td_api::getExternalLinkInfo &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.link_); - CREATE_REQUEST_PROMISE(); - link_manager_->get_external_link_info(std::move(request.link_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getExternalLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.link_); - CREATE_REQUEST_PROMISE(); - link_manager_->get_link_login_url(request.link_, request.allow_write_access_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatHistory &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetChatHistoryRequest, request.chat_id_, request.from_message_id_, request.offset_, request.limit_, - request.only_local_); -} - -void Td::on_request(uint64 id, const td_api::deleteChatHistory &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->delete_dialog_history(DialogId(request.chat_id_), request.remove_from_chat_list_, request.revoke_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteChat &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - DialogId dialog_id(request.chat_id_); - auto query_promise = [actor_id = messages_manager_actor_.get(), dialog_id, - promise = std::move(promise)](Result &&result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - send_closure(actor_id, &MessagesManager::on_dialog_deleted, dialog_id, std::move(promise)); - } - }; - contacts_manager_->delete_dialog(dialog_id, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getMessageThreadHistory &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetMessageThreadHistoryRequest, request.chat_id_, request.message_id_, request.from_message_id_, - request.offset_, request.limit_); -} - -void Td::on_request(uint64 id, td_api::getChatMessageCalendar &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetChatMessageCalendarRequest, request.chat_id_, request.from_message_id_, std::move(request.filter_)); -} - -void Td::on_request(uint64 id, td_api::searchChatMessages &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST(SearchChatMessagesRequest, request.chat_id_, std::move(request.query_), std::move(request.sender_id_), - request.from_message_id_, request.offset_, request.limit_, std::move(request.filter_), - request.message_thread_id_); -} - -void Td::on_request(uint64 id, td_api::searchSecretMessages &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CLEAN_INPUT_STRING(request.offset_); - CREATE_REQUEST(SearchSecretMessagesRequest, request.chat_id_, std::move(request.query_), std::move(request.offset_), - request.limit_, std::move(request.filter_)); -} - -void Td::on_request(uint64 id, td_api::searchMessages &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CLEAN_INPUT_STRING(request.offset_); - DialogListId dialog_list_id(request.chat_list_); - if (!dialog_list_id.is_folder()) { - return send_error_raw(id, 400, "Wrong chat list specified"); - } - CREATE_REQUEST(SearchMessagesRequest, dialog_list_id.get_folder_id(), request.chat_list_ == nullptr, - std::move(request.query_), std::move(request.offset_), request.limit_, std::move(request.filter_), - request.min_date_, request.max_date_); -} - -void Td::on_request(uint64 id, const td_api::searchCallMessages &request) { - CHECK_IS_USER(); - CREATE_REQUEST(SearchCallMessagesRequest, std::move(request.offset_), request.limit_, request.only_missed_); -} - -void Td::on_request(uint64 id, td_api::searchOutgoingDocumentMessages &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST_PROMISE(); - messages_manager_->search_outgoing_document_messages(request.query_, request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteAllCallMessages &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->delete_all_call_messages(request.revoke_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::searchChatRecentLocationMessages &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - messages_manager_->search_dialog_recent_location_messages(DialogId(request.chat_id_), request.limit_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getActiveLiveLocationMessages &request) { - CHECK_IS_USER(); - CREATE_NO_ARGS_REQUEST(GetActiveLiveLocationMessagesRequest); -} - -void Td::on_request(uint64 id, const td_api::getChatMessageByDate &request) { - CREATE_REQUEST(GetChatMessageByDateRequest, request.chat_id_, request.date_); -} - -void Td::on_request(uint64 id, const td_api::getChatSparseMessagePositions &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - messages_manager_->get_dialog_sparse_message_positions( - DialogId(request.chat_id_), get_message_search_filter(request.filter_), MessageId(request.from_message_id_), - request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatMessageCount &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - messages_manager_->get_dialog_message_count(DialogId(request.chat_id_), get_message_search_filter(request.filter_), - request.return_local_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatMessagePosition &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - messages_manager_->get_dialog_message_position({DialogId(request.chat_id_), MessageId(request.message_id_)}, - get_message_search_filter(request.filter_), - MessageId(request.message_thread_id_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatScheduledMessages &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetChatScheduledMessagesRequest, request.chat_id_); -} - -void Td::on_request(uint64 id, const td_api::getEmojiReaction &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_emoji_reaction(request.emoji_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getCustomEmojiReactionAnimations &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_custom_emoji_reaction_generic_animations(false, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getMessageAvailableReactions &request) { - CHECK_IS_USER(); - auto r_reactions = messages_manager_->get_message_available_reactions( - {DialogId(request.chat_id_), MessageId(request.message_id_)}, request.row_size_); - if (r_reactions.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, r_reactions.move_as_error()); - } else { - send_closure(actor_id(this), &Td::send_result, id, r_reactions.move_as_ok()); - } -} - -void Td::on_request(uint64 id, const td_api::clearRecentReactions &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->clear_recent_reactions(std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::addMessageReaction &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->add_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)}, - get_message_reaction_string(request.reaction_type_), request.is_big_, - request.update_recent_reactions_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::removeMessageReaction &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->remove_message_reaction({DialogId(request.chat_id_), MessageId(request.message_id_)}, - get_message_reaction_string(request.reaction_type_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getMessageAddedReactions &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.offset_); - CREATE_REQUEST_PROMISE(); - get_message_added_reactions(this, {DialogId(request.chat_id_), MessageId(request.message_id_)}, - get_message_reaction_string(request.reaction_type_), std::move(request.offset_), - request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setDefaultReactionType &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - set_default_reaction(this, get_message_reaction_string(request.reaction_type_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getMessagePublicForwards &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.offset_); - CREATE_REQUEST_PROMISE(); - messages_manager_->get_message_public_forwards({DialogId(request.chat_id_), MessageId(request.message_id_)}, - std::move(request.offset_), request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::removeNotification &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(notification_manager_actor_, &NotificationManager::remove_notification, - NotificationGroupId(request.notification_group_id_), NotificationId(request.notification_id_), false, - true, std::move(promise), "td_api::removeNotification"); -} - -void Td::on_request(uint64 id, const td_api::removeNotificationGroup &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(notification_manager_actor_, &NotificationManager::remove_notification_group, - NotificationGroupId(request.notification_group_id_), NotificationId(request.max_notification_id_), - MessageId(), -1, true, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteMessages &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->delete_messages(DialogId(request.chat_id_), MessageId::get_message_ids(request.message_ids_), - request.revoke_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteChatMessagesBySender &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, sender_dialog_id, get_message_sender_dialog_id(this, request.sender_id_, false, false)); - messages_manager_->delete_dialog_messages_by_sender(DialogId(request.chat_id_), sender_dialog_id, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteChatMessagesByDate &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->delete_dialog_messages_by_date(DialogId(request.chat_id_), request.min_date_, request.max_date_, - request.revoke_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::readAllChatMentions &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->read_all_dialog_mentions(DialogId(request.chat_id_), MessageId(), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::readAllMessageThreadMentions &request) { - CHECK_IS_USER(); - if (request.message_thread_id_ == 0) { - return send_error_raw(id, 400, "Invalid message thread identifier specified"); - } - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->read_all_dialog_mentions(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::readAllChatReactions &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->read_all_dialog_reactions(DialogId(request.chat_id_), MessageId(), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::readAllMessageThreadReactions &request) { - CHECK_IS_USER(); - if (request.message_thread_id_ == 0) { - return send_error_raw(id, 400, "Invalid message thread identifier specified"); - } - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->read_all_dialog_reactions(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatAvailableMessageSenders &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - messages_manager_->get_dialog_send_message_as_dialog_ids(DialogId(request.chat_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setChatMessageSender &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, message_sender_dialog_id, - get_message_sender_dialog_id(this, request.message_sender_id_, true, false)); - messages_manager_->set_dialog_default_send_message_as_dialog_id(DialogId(request.chat_id_), message_sender_dialog_id, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendMessage &request) { - auto r_sent_message = messages_manager_->send_message( - DialogId(request.chat_id_), MessageId(request.message_thread_id_), MessageId(request.reply_to_message_id_), - std::move(request.options_), std::move(request.reply_markup_), std::move(request.input_message_content_)); - if (r_sent_message.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, r_sent_message.move_as_error()); - } else { - send_closure(actor_id(this), &Td::send_result, id, r_sent_message.move_as_ok()); - } -} - -void Td::on_request(uint64 id, td_api::sendMessageAlbum &request) { - auto r_messages = messages_manager_->send_message_group( - DialogId(request.chat_id_), MessageId(request.message_thread_id_), MessageId(request.reply_to_message_id_), - std::move(request.options_), std::move(request.input_message_contents_), request.only_preview_); - if (r_messages.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, r_messages.move_as_error()); - } else { - send_closure(actor_id(this), &Td::send_result, id, r_messages.move_as_ok()); - } -} - -void Td::on_request(uint64 id, td_api::sendBotStartMessage &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.parameter_); - - DialogId dialog_id(request.chat_id_); - auto r_new_message_id = - messages_manager_->send_bot_start_message(UserId(request.bot_user_id_), dialog_id, request.parameter_); - if (r_new_message_id.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_new_message_id.move_as_error()); - } - - CHECK(r_new_message_id.ok().is_valid() || r_new_message_id.ok().is_valid_scheduled()); - send_closure(actor_id(this), &Td::send_result, id, - messages_manager_->get_message_object({dialog_id, r_new_message_id.ok()}, "sendBotStartMessage")); -} - -void Td::on_request(uint64 id, td_api::sendInlineQueryResultMessage &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.result_id_); - - DialogId dialog_id(request.chat_id_); - auto r_new_message_id = messages_manager_->send_inline_query_result_message( - dialog_id, MessageId(request.message_thread_id_), MessageId(request.reply_to_message_id_), - std::move(request.options_), request.query_id_, request.result_id_, request.hide_via_bot_); - if (r_new_message_id.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_new_message_id.move_as_error()); - } - - CHECK(r_new_message_id.ok().is_valid() || r_new_message_id.ok().is_valid_scheduled()); - send_closure( - actor_id(this), &Td::send_result, id, - messages_manager_->get_message_object({dialog_id, r_new_message_id.ok()}, "sendInlineQueryResultMessage")); -} - -void Td::on_request(uint64 id, td_api::addLocalMessage &request) { - CHECK_IS_USER(); - - DialogId dialog_id(request.chat_id_); - auto r_new_message_id = messages_manager_->add_local_message( - dialog_id, std::move(request.sender_id_), MessageId(request.reply_to_message_id_), request.disable_notification_, - std::move(request.input_message_content_)); - if (r_new_message_id.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_new_message_id.move_as_error()); - } - - CHECK(r_new_message_id.ok().is_valid()); - send_closure(actor_id(this), &Td::send_result, id, - messages_manager_->get_message_object({dialog_id, r_new_message_id.ok()}, "addLocalMessage")); -} - -void Td::on_request(uint64 id, td_api::editMessageText &request) { - CREATE_REQUEST(EditMessageTextRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_), - std::move(request.input_message_content_)); -} - -void Td::on_request(uint64 id, td_api::editMessageLiveLocation &request) { - CREATE_REQUEST(EditMessageLiveLocationRequest, request.chat_id_, request.message_id_, - std::move(request.reply_markup_), std::move(request.location_), request.heading_, - request.proximity_alert_radius_); -} - -void Td::on_request(uint64 id, td_api::editMessageMedia &request) { - CREATE_REQUEST(EditMessageMediaRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_), - std::move(request.input_message_content_)); -} - -void Td::on_request(uint64 id, td_api::editMessageCaption &request) { - CREATE_REQUEST(EditMessageCaptionRequest, request.chat_id_, request.message_id_, std::move(request.reply_markup_), - std::move(request.caption_)); -} - -void Td::on_request(uint64 id, td_api::editMessageReplyMarkup &request) { - CHECK_IS_BOT(); - CREATE_REQUEST(EditMessageReplyMarkupRequest, request.chat_id_, request.message_id_, - std::move(request.reply_markup_)); -} - -void Td::on_request(uint64 id, td_api::editInlineMessageText &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.inline_message_id_); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->edit_inline_message_text(request.inline_message_id_, std::move(request.reply_markup_), - std::move(request.input_message_content_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editInlineMessageLiveLocation &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.inline_message_id_); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->edit_inline_message_live_location(request.inline_message_id_, std::move(request.reply_markup_), - std::move(request.location_), request.heading_, - request.proximity_alert_radius_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editInlineMessageMedia &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.inline_message_id_); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->edit_inline_message_media(request.inline_message_id_, std::move(request.reply_markup_), - std::move(request.input_message_content_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editInlineMessageCaption &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.inline_message_id_); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->edit_inline_message_caption(request.inline_message_id_, std::move(request.reply_markup_), - std::move(request.caption_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editInlineMessageReplyMarkup &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.inline_message_id_); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->edit_inline_message_reply_markup(request.inline_message_id_, std::move(request.reply_markup_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editMessageSchedulingState &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->edit_message_scheduling_state({DialogId(request.chat_id_), MessageId(request.message_id_)}, - std::move(request.scheduling_state_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getForumTopicDefaultIcons &request) { - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_default_topic_icons(false, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::createForumTopic &request) { - CLEAN_INPUT_STRING(request.name_); - CREATE_REQUEST_PROMISE(); - forum_topic_manager_->create_forum_topic(DialogId(request.chat_id_), std::move(request.name_), - std::move(request.icon_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editForumTopic &request) { - CLEAN_INPUT_STRING(request.name_); - CREATE_OK_REQUEST_PROMISE(); - forum_topic_manager_->edit_forum_topic(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(request.name_), request.edit_icon_custom_emoji_, - CustomEmojiId(request.icon_custom_emoji_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getForumTopic &request) { - CREATE_REQUEST_PROMISE(); - forum_topic_manager_->get_forum_topic(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getForumTopicLink &request) { - CREATE_REQUEST_PROMISE(); - forum_topic_manager_->get_forum_topic_link(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getForumTopics &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST_PROMISE(); - forum_topic_manager_->get_forum_topics(DialogId(request.chat_id_), std::move(request.query_), request.offset_date_, - MessageId(request.offset_message_id_), - MessageId(request.offset_message_thread_id_), request.limit_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleForumTopicIsClosed &request) { - CREATE_OK_REQUEST_PROMISE(); - forum_topic_manager_->toggle_forum_topic_is_closed(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - request.is_closed_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleGeneralForumTopicIsHidden &request) { - CREATE_OK_REQUEST_PROMISE(); - forum_topic_manager_->toggle_forum_topic_is_hidden(DialogId(request.chat_id_), request.is_hidden_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleForumTopicIsPinned &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - forum_topic_manager_->toggle_forum_topic_is_pinned(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - request.is_pinned_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setPinnedForumTopics &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - forum_topic_manager_->set_pinned_forum_topics( - DialogId(request.chat_id_), MessageId::get_message_ids(request.message_thread_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteForumTopic &request) { - CREATE_OK_REQUEST_PROMISE(); - forum_topic_manager_->delete_forum_topic(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setGameScore &request) { - CHECK_IS_BOT(); - CREATE_REQUEST_PROMISE(); - game_manager_->set_game_score({DialogId(request.chat_id_), MessageId(request.message_id_)}, request.edit_message_, - UserId(request.user_id_), request.score_, request.force_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setInlineGameScore &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.inline_message_id_); - CREATE_OK_REQUEST_PROMISE(); - game_manager_->set_inline_game_score(request.inline_message_id_, request.edit_message_, UserId(request.user_id_), - request.score_, request.force_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getGameHighScores &request) { - CHECK_IS_BOT(); - CREATE_REQUEST_PROMISE(); - game_manager_->get_game_high_scores({DialogId(request.chat_id_), MessageId(request.message_id_)}, - UserId(request.user_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getInlineGameHighScores &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.inline_message_id_); - CREATE_REQUEST_PROMISE(); - game_manager_->get_inline_game_high_scores(request.inline_message_id_, UserId(request.user_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteChatReplyMarkup &request) { - CHECK_IS_USER(); - answer_ok_query( - id, messages_manager_->delete_dialog_reply_markup(DialogId(request.chat_id_), MessageId(request.message_id_))); -} - -void Td::on_request(uint64 id, td_api::sendChatAction &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->send_dialog_action(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - DialogAction(std::move(request.action_)), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendChatScreenshotTakenNotification &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->send_screenshot_taken_notification_message(DialogId(request.chat_id_))); -} - -void Td::on_request(uint64 id, td_api::forwardMessages &request) { - auto input_message_ids = MessageId::get_message_ids(request.message_ids_); - auto message_copy_options = - transform(input_message_ids, [send_copy = request.send_copy_, remove_caption = request.remove_caption_]( - MessageId) { return MessageCopyOptions(send_copy, remove_caption); }); - auto r_messages = messages_manager_->forward_messages( - DialogId(request.chat_id_), MessageId(request.message_thread_id_), DialogId(request.from_chat_id_), - std::move(input_message_ids), std::move(request.options_), false, std::move(message_copy_options), - request.only_preview_); - if (r_messages.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, r_messages.move_as_error()); - } else { - send_closure(actor_id(this), &Td::send_result, id, r_messages.move_as_ok()); - } -} - -void Td::on_request(uint64 id, const td_api::resendMessages &request) { - DialogId dialog_id(request.chat_id_); - auto r_message_ids = messages_manager_->resend_messages(dialog_id, MessageId::get_message_ids(request.message_ids_)); - if (r_message_ids.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_message_ids.move_as_error()); - } - - send_closure(actor_id(this), &Td::send_result, id, - messages_manager_->get_messages_object(-1, dialog_id, r_message_ids.ok(), false, "resendMessages")); -} - -void Td::on_request(uint64 id, td_api::getWebPagePreview &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - web_pages_manager_->get_web_page_preview(std::move(request.text_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getWebPageInstantView &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.url_); - CREATE_REQUEST(GetWebPageInstantViewRequest, std::move(request.url_), request.force_full_); -} - -void Td::on_request(uint64 id, const td_api::createPrivateChat &request) { - CREATE_REQUEST(CreateChatRequest, DialogId(UserId(request.user_id_)), request.force_); -} - -void Td::on_request(uint64 id, const td_api::createBasicGroupChat &request) { - CREATE_REQUEST(CreateChatRequest, DialogId(ChatId(request.basic_group_id_)), request.force_); -} - -void Td::on_request(uint64 id, const td_api::createSupergroupChat &request) { - CREATE_REQUEST(CreateChatRequest, DialogId(ChannelId(request.supergroup_id_)), request.force_); -} - -void Td::on_request(uint64 id, td_api::createSecretChat &request) { - CREATE_REQUEST(CreateChatRequest, DialogId(SecretChatId(request.secret_chat_id_)), true); -} - -void Td::on_request(uint64 id, td_api::createNewBasicGroupChat &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.title_); - CREATE_REQUEST(CreateNewGroupChatRequest, UserId::get_user_ids(request.user_ids_), std::move(request.title_), - request.message_auto_delete_time_); -} - -void Td::on_request(uint64 id, td_api::createNewSupergroupChat &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.title_); - CLEAN_INPUT_STRING(request.description_); - CREATE_REQUEST(CreateNewSupergroupChatRequest, std::move(request.title_), request.is_forum_, !request.is_channel_, - std::move(request.description_), std::move(request.location_), request.for_import_, - request.message_auto_delete_time_); -} - -void Td::on_request(uint64 id, td_api::createNewSecretChat &request) { - CREATE_REQUEST(CreateNewSecretChatRequest, request.user_id_); -} - -void Td::on_request(uint64 id, const td_api::createCall &request) { - CHECK_IS_USER(); - - if (request.protocol_ == nullptr) { - return send_error_raw(id, 400, "Call protocol must be non-empty"); - } - - UserId user_id(request.user_id_); - auto r_input_user = contacts_manager_->get_input_user(user_id); - if (r_input_user.is_error()) { - return send_error_raw(id, r_input_user.error().code(), r_input_user.error().message()); - } - - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_call_id_object()); - } - }); - send_closure(G()->call_manager(), &CallManager::create_call, user_id, r_input_user.move_as_ok(), - CallProtocol(*request.protocol_), request.is_video_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::acceptCall &request) { - CHECK_IS_USER(); - if (request.protocol_ == nullptr) { - return send_error_raw(id, 400, "Call protocol must be non-empty"); - } - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->call_manager(), &CallManager::accept_call, CallId(request.call_id_), - CallProtocol(*request.protocol_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendCallSignalingData &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->call_manager(), &CallManager::send_call_signaling_data, CallId(request.call_id_), - std::move(request.data_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::discardCall &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->call_manager(), &CallManager::discard_call, CallId(request.call_id_), request.is_disconnected_, - request.duration_, request.is_video_, request.connection_id_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendCallRating &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.comment_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->call_manager(), &CallManager::rate_call, CallId(request.call_id_), request.rating_, - std::move(request.comment_), std::move(request.problems_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendCallDebugInformation &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.debug_information_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->call_manager(), &CallManager::send_call_debug_information, CallId(request.call_id_), - std::move(request.debug_information_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendCallLog &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->call_manager(), &CallManager::send_call_log, CallId(request.call_id_), std::move(request.log_file_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getVideoChatAvailableParticipants &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - group_call_manager_->get_group_call_join_as(DialogId(request.chat_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setVideoChatDefaultParticipant &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, default_join_as_dialog_id, - get_message_sender_dialog_id(this, request.default_participant_id_, true, false)); - group_call_manager_->set_group_call_default_join_as(DialogId(request.chat_id_), default_join_as_dialog_id, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::createVideoChat &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.title_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.ok().get())); - } - }); - group_call_manager_->create_voice_chat(DialogId(request.chat_id_), std::move(request.title_), request.start_date_, - request.is_rtmp_stream_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getVideoChatRtmpUrl &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - group_call_manager_->get_voice_chat_rtmp_stream_url(DialogId(request.chat_id_), false, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::replaceVideoChatRtmpUrl &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - group_call_manager_->get_voice_chat_rtmp_stream_url(DialogId(request.chat_id_), true, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getGroupCall &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - group_call_manager_->get_group_call(GroupCallId(request.group_call_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::startScheduledGroupCall &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->start_scheduled_group_call(GroupCallId(request.group_call_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleGroupCallEnabledStartNotification &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->toggle_group_call_start_subscribed(GroupCallId(request.group_call_id_), - request.enabled_start_notification_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::joinGroupCall &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_hash_); - CLEAN_INPUT_STRING(request.payload_); - CREATE_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, join_as_dialog_id, - get_message_sender_dialog_id(this, request.participant_id_, true, true)); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - group_call_manager_->join_group_call(GroupCallId(request.group_call_id_), join_as_dialog_id, request.audio_source_id_, - std::move(request.payload_), request.is_muted_, request.is_my_video_enabled_, - request.invite_hash_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::startGroupCallScreenSharing &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.payload_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - group_call_manager_->start_group_call_screen_sharing(GroupCallId(request.group_call_id_), request.audio_source_id_, - std::move(request.payload_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleGroupCallScreenSharingIsPaused &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->toggle_group_call_is_my_presentation_paused(GroupCallId(request.group_call_id_), - request.is_paused_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::endGroupCallScreenSharing &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->end_group_call_screen_sharing(GroupCallId(request.group_call_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setGroupCallTitle &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.title_); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->set_group_call_title(GroupCallId(request.group_call_id_), std::move(request.title_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleGroupCallMuteNewParticipants &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->toggle_group_call_mute_new_participants(GroupCallId(request.group_call_id_), - request.mute_new_participants_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::revokeGroupCallInviteLink &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->revoke_group_call_invite_link(GroupCallId(request.group_call_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::inviteGroupCallParticipants &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->invite_group_call_participants(GroupCallId(request.group_call_id_), - UserId::get_user_ids(request.user_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getGroupCallInviteLink &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.move_as_ok())); - } - }); - group_call_manager_->get_group_call_invite_link(GroupCallId(request.group_call_id_), request.can_self_unmute_, - std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::startGroupCallRecording &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.title_); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->toggle_group_call_recording(GroupCallId(request.group_call_id_), true, std::move(request.title_), - request.record_video_, request.use_portrait_orientation_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::endGroupCallRecording &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->toggle_group_call_recording(GroupCallId(request.group_call_id_), false, string(), false, false, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoPaused &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->toggle_group_call_is_my_video_paused(GroupCallId(request.group_call_id_), - request.is_my_video_paused_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoEnabled &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->toggle_group_call_is_my_video_enabled(GroupCallId(request.group_call_id_), - request.is_my_video_enabled_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->set_group_call_participant_is_speaking( - GroupCallId(request.group_call_id_), request.audio_source_, request.is_speaking_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, participant_dialog_id, - get_message_sender_dialog_id(this, request.participant_id_, true, false)); - group_call_manager_->toggle_group_call_participant_is_muted( - GroupCallId(request.group_call_id_), participant_dialog_id, request.is_muted_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setGroupCallParticipantVolumeLevel &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, participant_dialog_id, - get_message_sender_dialog_id(this, request.participant_id_, true, false)); - group_call_manager_->set_group_call_participant_volume_level( - GroupCallId(request.group_call_id_), participant_dialog_id, request.volume_level_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleGroupCallParticipantIsHandRaised &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, participant_dialog_id, - get_message_sender_dialog_id(this, request.participant_id_, true, false)); - group_call_manager_->toggle_group_call_participant_is_hand_raised( - GroupCallId(request.group_call_id_), participant_dialog_id, request.is_hand_raised_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::loadGroupCallParticipants &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->load_group_call_participants(GroupCallId(request.group_call_id_), request.limit_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::leaveGroupCall &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->leave_group_call(GroupCallId(request.group_call_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::endGroupCall &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - group_call_manager_->discard_group_call(GroupCallId(request.group_call_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getGroupCallStreams &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - group_call_manager_->get_group_call_streams(GroupCallId(request.group_call_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getGroupCallStreamSegment &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - auto file_part = td_api::make_object(); - file_part->data_ = result.move_as_ok(); - promise.set_value(std::move(file_part)); - } - }); - group_call_manager_->get_group_call_stream_segment(GroupCallId(request.group_call_id_), request.time_offset_, - request.scale_, request.channel_id_, - std::move(request.video_quality_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request) { - CHECK_IS_USER(); - CREATE_REQUEST(UpgradeGroupChatToSupergroupChatRequest, request.chat_id_); -} - -void Td::on_request(uint64 id, const td_api::getChatListsToAddChat &request) { - CHECK_IS_USER(); - auto dialog_lists = messages_manager_->get_dialog_lists_to_add_dialog(DialogId(request.chat_id_)); - auto chat_lists = - transform(dialog_lists, [](DialogListId dialog_list_id) { return dialog_list_id.get_chat_list_object(); }); - send_closure(actor_id(this), &Td::send_result, id, td_api::make_object(std::move(chat_lists))); -} - -void Td::on_request(uint64 id, const td_api::addChatToList &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->add_dialog_to_list(DialogId(request.chat_id_), DialogListId(request.chat_list_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatFolder &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->get_dialog_filter(DialogFilterId(request.chat_folder_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getRecommendedChatFolders &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->get_recommended_dialog_filters(std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::createChatFolder &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->create_dialog_filter(std::move(request.folder_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editChatFolder &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->edit_dialog_filter(DialogFilterId(request.chat_folder_id_), std::move(request.folder_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteChatFolder &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - dialog_filter_manager_->delete_dialog_filter(DialogFilterId(request.chat_folder_id_), - DialogId::get_dialog_ids(request.leave_chat_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatFolderChatsToLeave &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->get_leave_dialog_filter_suggestions(DialogFilterId(request.chat_folder_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::reorderChatFolders &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - dialog_filter_manager_->reorder_dialog_filters( - transform(request.chat_folder_ids_, [](int32 id) { return DialogFilterId(id); }), - request.main_chat_list_position_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatsForChatFolderInviteLink &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->get_dialogs_for_dialog_filter_invite_link(DialogFilterId(request.chat_folder_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::createChatFolderInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.name_); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->create_dialog_filter_invite_link( - DialogFilterId(request.chat_folder_id_), std::move(request.name_), DialogId::get_dialog_ids(request.chat_ids_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getChatFolderInviteLinks &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->get_dialog_filter_invite_links(DialogFilterId(request.chat_folder_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editChatFolderInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CLEAN_INPUT_STRING(request.name_); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->edit_dialog_filter_invite_link( - DialogFilterId(request.chat_folder_id_), std::move(request.invite_link_), std::move(request.name_), - DialogId::get_dialog_ids(request.chat_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::deleteChatFolderInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_OK_REQUEST_PROMISE(); - dialog_filter_manager_->delete_dialog_filter_invite_link(DialogFilterId(request.chat_folder_id_), - std::move(request.invite_link_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::checkChatFolderInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->check_dialog_filter_invite_link(std::move(request.invite_link_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::addChatFolderByInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_OK_REQUEST_PROMISE(); - dialog_filter_manager_->add_dialog_filter_by_invite_link( - std::move(request.invite_link_), DialogId::get_dialog_ids(request.chat_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatFolderNewChats &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - dialog_filter_manager_->get_dialog_filter_new_chats(DialogFilterId(request.chat_folder_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::processChatFolderNewChats &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - dialog_filter_manager_->add_dialog_filter_new_chats( - DialogFilterId(request.chat_folder_id_), DialogId::get_dialog_ids(request.added_chat_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatTitle &request) { - CLEAN_INPUT_STRING(request.title_); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->set_dialog_title(DialogId(request.chat_id_), request.title_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setChatPhoto &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->set_dialog_photo(DialogId(request.chat_id_), request.photo_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setChatMessageAutoDeleteTime &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->set_dialog_message_ttl(DialogId(request.chat_id_), request.message_auto_delete_time_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setChatPermissions &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->set_dialog_permissions(DialogId(request.chat_id_), request.permissions_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatBackground &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - background_manager_->set_dialog_background(DialogId(request.chat_id_), request.background_.get(), request.type_.get(), - request.dark_theme_dimming_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatTheme &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.theme_name_); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->set_dialog_theme(DialogId(request.chat_id_), request.theme_name_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatDraftMessage &request) { - CHECK_IS_USER(); - answer_ok_query( - id, messages_manager_->set_dialog_draft_message(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(request.draft_message_))); -} - -void Td::on_request(uint64 id, const td_api::toggleChatHasProtectedContent &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->toggle_dialog_has_protected_content(DialogId(request.chat_id_), request.has_protected_content_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleChatIsPinned &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->toggle_dialog_is_pinned(DialogListId(request.chat_list_), - DialogId(request.chat_id_), request.is_pinned_)); -} - -void Td::on_request(uint64 id, const td_api::toggleChatIsTranslatable &request) { - CHECK_IS_USER(); - answer_ok_query( - id, messages_manager_->toggle_dialog_is_translatable(DialogId(request.chat_id_), request.is_translatable_)); -} - -void Td::on_request(uint64 id, const td_api::toggleChatIsMarkedAsUnread &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->toggle_dialog_is_marked_as_unread(DialogId(request.chat_id_), - request.is_marked_as_unread_)); -} - -void Td::on_request(uint64 id, const td_api::toggleMessageSenderIsBlocked &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->toggle_message_sender_is_blocked(request.sender_id_, request.is_blocked_)); -} - -void Td::on_request(uint64 id, const td_api::toggleChatDefaultDisableNotification &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->toggle_dialog_silent_send_message(DialogId(request.chat_id_), - request.default_disable_notification_)); -} - -void Td::on_request(uint64 id, const td_api::setPinnedChats &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->set_pinned_dialogs(DialogListId(request.chat_list_), - DialogId::get_dialog_ids(request.chat_ids_))); -} - -void Td::on_request(uint64 id, const td_api::readChatList &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->read_all_dialogs_from_list(DialogListId(request.chat_list_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getAttachmentMenuBot &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - attach_menu_manager_->get_attach_menu_bot(UserId(request.bot_user_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleBotIsAddedToAttachmentMenu &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - attach_menu_manager_->toggle_bot_is_added_to_attach_menu(UserId(request.bot_user_id_), request.is_added_, - request.allow_write_access_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatAvailableReactions &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->set_dialog_available_reactions(DialogId(request.chat_id_), std::move(request.available_reactions_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatClientData &request) { - answer_ok_query( - id, messages_manager_->set_dialog_client_data(DialogId(request.chat_id_), std::move(request.client_data_))); -} - -void Td::on_request(uint64 id, td_api::setChatDescription &request) { - CLEAN_INPUT_STRING(request.description_); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->set_dialog_description(DialogId(request.chat_id_), request.description_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setChatDiscussionGroup &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_channel_discussion_group(DialogId(request.chat_id_), DialogId(request.discussion_chat_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatLocation &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_channel_location(DialogId(request.chat_id_), DialogLocation(std::move(request.location_)), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setChatSlowModeDelay &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_channel_slow_mode_delay(DialogId(request.chat_id_), request.slow_mode_delay_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::pinChatMessage &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->pin_dialog_message(DialogId(request.chat_id_), MessageId(request.message_id_), - request.disable_notification_, request.only_for_self_, false, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::unpinChatMessage &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->pin_dialog_message(DialogId(request.chat_id_), MessageId(request.message_id_), false, false, true, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::unpinAllChatMessages &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->unpin_all_dialog_messages(DialogId(request.chat_id_), MessageId(), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::unpinAllMessageThreadMessages &request) { - if (request.message_thread_id_ == 0) { - return send_error_raw(id, 400, "Invalid message thread identifier specified"); - } - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->unpin_all_dialog_messages(DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::joinChat &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->add_dialog_participant(DialogId(request.chat_id_), contacts_manager_->get_my_id(), 0, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::leaveChat &request) { - CREATE_OK_REQUEST_PROMISE(); - DialogId dialog_id(request.chat_id_); - td_api::object_ptr new_status = td_api::make_object(); - if (dialog_id.get_type() == DialogType::Channel && messages_manager_->have_dialog_force(dialog_id, "leaveChat")) { - auto status = contacts_manager_->get_channel_status(dialog_id.get_channel_id()); - if (status.is_creator()) { - if (!status.is_member()) { - return promise.set_value(Unit()); - } - - new_status = - td_api::make_object(status.get_rank(), status.is_anonymous(), false); - } - } - contacts_manager_->set_dialog_participant_status(dialog_id, DialogId(contacts_manager_->get_my_id()), - std::move(new_status), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::addChatMember &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->add_dialog_participant(DialogId(request.chat_id_), UserId(request.user_id_), - request.forward_limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::addChatMembers &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->add_dialog_participants(DialogId(request.chat_id_), UserId::get_user_ids(request.user_ids_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatMemberStatus &request) { - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, participant_dialog_id, - get_message_sender_dialog_id(this, request.member_id_, false, false)); - contacts_manager_->set_dialog_participant_status(DialogId(request.chat_id_), participant_dialog_id, - std::move(request.status_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::banChatMember &request) { - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, participant_dialog_id, - get_message_sender_dialog_id(this, request.member_id_, false, false)); - contacts_manager_->ban_dialog_participant(DialogId(request.chat_id_), participant_dialog_id, - request.banned_until_date_, request.revoke_messages_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::canTransferOwnership &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda( - [promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(ContactsManager::get_can_transfer_ownership_result_object(result.ok())); - } - }); - contacts_manager_->can_transfer_ownership(std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::transferChatOwnership &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->transfer_dialog_ownership(DialogId(request.chat_id_), UserId(request.user_id_), request.password_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatMember &request) { - CREATE_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, participant_dialog_id, - get_message_sender_dialog_id(this, request.member_id_, false, false)); - contacts_manager_->get_dialog_participant(DialogId(request.chat_id_), participant_dialog_id, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::searchChatMembers &request) { - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST_PROMISE(); - auto query_promise = - PromiseCreator::lambda([promise = std::move(promise), td = this](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_chat_members_object(td)); - } - }); - contacts_manager_->search_dialog_participants(DialogId(request.chat_id_), request.query_, request.limit_, - DialogParticipantFilter(request.filter_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatAdministrators &request) { - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_dialog_administrators(DialogId(request.chat_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::replacePrimaryChatInviteLink &request) { - CREATE_REQUEST_PROMISE(); - contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), string(), 0, 0, false, true, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::createChatInviteLink &request) { - CLEAN_INPUT_STRING(request.name_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->export_dialog_invite_link(DialogId(request.chat_id_), std::move(request.name_), - request.expiration_date_, request.member_limit_, - request.creates_join_request_, false, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editChatInviteLink &request) { - CLEAN_INPUT_STRING(request.name_); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->edit_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, std::move(request.name_), - request.expiration_date_, request.member_limit_, - request.creates_join_request_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getChatInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatInviteLinkCounts &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_dialog_invite_link_counts(DialogId(request.chat_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getChatInviteLinks &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.offset_invite_link_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_dialog_invite_links(DialogId(request.chat_id_), UserId(request.creator_user_id_), - request.is_revoked_, request.offset_date_, request.offset_invite_link_, - request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getChatInviteLinkMembers &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_dialog_invite_link_users(DialogId(request.chat_id_), request.invite_link_, - std::move(request.offset_member_), request.limit_, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getChatJoinRequests &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_dialog_join_requests(DialogId(request.chat_id_), request.invite_link_, request.query_, - std::move(request.offset_request_), request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::processChatJoinRequest &request) { - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->process_dialog_join_request(DialogId(request.chat_id_), UserId(request.user_id_), request.approve_, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::processChatJoinRequests &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->process_dialog_join_requests(DialogId(request.chat_id_), request.invite_link_, request.approve_, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::revokeChatInviteLink &request) { - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->revoke_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::deleteRevokedChatInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->delete_revoked_dialog_invite_link(DialogId(request.chat_id_), request.invite_link_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteAllRevokedChatInviteLinks &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->delete_all_revoked_dialog_invite_links(DialogId(request.chat_id_), - UserId(request.creator_user_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::checkChatInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_REQUEST(CheckChatInviteLinkRequest, request.invite_link_); -} - -void Td::on_request(uint64 id, td_api::joinChatByInviteLink &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.invite_link_); - CREATE_REQUEST(JoinChatByInviteLinkRequest, request.invite_link_); -} - -void Td::on_request(uint64 id, td_api::getChatEventLog &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST_PROMISE(); - get_dialog_event_log(this, DialogId(request.chat_id_), std::move(request.query_), request.from_event_id_, - request.limit_, std::move(request.filters_), UserId::get_user_ids(request.user_ids_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::clearAllDraftMessages &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->clear_all_draft_messages(request.exclude_secret_chats_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::downloadFile &request) { - auto priority = request.priority_; - if (!(1 <= priority && priority <= 32)) { - return send_error_raw(id, 400, "Download priority must be between 1 and 32"); - } - auto offset = request.offset_; - if (offset < 0) { - return send_error_raw(id, 400, "Download offset must be non-negative"); - } - auto limit = request.limit_; - if (limit < 0) { - return send_error_raw(id, 400, "Download limit must be non-negative"); - } - - FileId file_id(request.file_id_, 0); - auto file_view = file_manager_->get_file_view(file_id); - if (file_view.empty()) { - return send_error_raw(id, 400, "Invalid file identifier"); - } - - auto info_it = pending_file_downloads_.find(file_id); - DownloadInfo *info = info_it == pending_file_downloads_.end() ? nullptr : &info_it->second; - if (info != nullptr && (offset != info->offset || limit != info->limit)) { - // we can't have two pending requests with different offset and limit, so cancel all previous requests - auto request_ids = std::move(info->request_ids); - info->request_ids.clear(); - for (auto request_id : request_ids) { - send_closure(actor_id(this), &Td::send_error, request_id, - Status::Error(200, "Canceled by another downloadFile request")); - } - } - if (request.synchronous_) { - if (info == nullptr) { - info = &pending_file_downloads_[file_id]; - } - info->offset = offset; - info->limit = limit; - info->request_ids.push_back(id); - } - Promise> download_promise; - if (!request.synchronous_) { - CREATE_REQUEST_PROMISE(); - download_promise = std::move(promise); - } - file_manager_->download(file_id, download_file_callback_, priority, offset, limit, std::move(download_promise)); -} - -void Td::on_file_download_finished(FileId file_id) { - auto it = pending_file_downloads_.find(file_id); - if (it == pending_file_downloads_.end()) { - return; - } - for (auto id : it->second.request_ids) { - // there was send_closure to call this function - auto file_object = file_manager_->get_file_object(file_id, false); - CHECK(file_object != nullptr); - auto download_offset = file_object->local_->download_offset_; - auto downloaded_size = file_object->local_->downloaded_prefix_size_; - auto file_size = file_object->size_; - auto limit = it->second.limit; - if (limit == 0) { - limit = std::numeric_limits::max(); - } - if (file_object->local_->is_downloading_completed_ || - (download_offset <= it->second.offset && download_offset + downloaded_size >= it->second.offset && - ((file_size != 0 && download_offset + downloaded_size == file_size) || - download_offset + downloaded_size - it->second.offset >= limit))) { - send_result(id, std::move(file_object)); - } else { - send_error_impl(id, td_api::make_object(400, "File download has failed or was canceled")); - } - } - pending_file_downloads_.erase(it); -} - -void Td::on_request(uint64 id, const td_api::getFileDownloadedPrefixSize &request) { - if (request.offset_ < 0) { - return send_error_raw(id, 400, "Parameter offset must be non-negative"); - } - auto file_view = file_manager_->get_file_view(FileId(request.file_id_, 0)); - if (file_view.empty()) { - return send_closure(actor_id(this), &Td::send_error, id, Status::Error(400, "Unknown file ID")); - } - send_closure(actor_id(this), &Td::send_result, id, - td_api::make_object(file_view.downloaded_prefix(request.offset_))); -} - -void Td::on_request(uint64 id, const td_api::cancelDownloadFile &request) { - file_manager_->download(FileId(request.file_id_, 0), nullptr, request.only_if_pending_ ? -1 : 0, - FileManager::KEEP_DOWNLOAD_OFFSET, FileManager::KEEP_DOWNLOAD_LIMIT, - Promise>()); - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, const td_api::getSuggestedFileName &request) { - Result r_file_name = file_manager_->get_suggested_file_name(FileId(request.file_id_, 0), request.directory_); - if (r_file_name.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_file_name.move_as_error()); - } - send_closure(actor_id(this), &Td::send_result, id, td_api::make_object(r_file_name.ok())); -} - -void Td::on_request(uint64 id, td_api::preliminaryUploadFile &request) { - auto priority = request.priority_; - if (!(1 <= priority && priority <= 32)) { - return send_error_raw(id, 400, "Upload priority must be between 1 and 32"); - } - - auto file_type = request.file_type_ == nullptr ? FileType::Temp : get_file_type(*request.file_type_); - bool is_secret = file_type == FileType::Encrypted || file_type == FileType::EncryptedThumbnail; - bool is_secure = file_type == FileType::SecureEncrypted; - auto r_file_id = file_manager_->get_input_file_id(file_type, request.file_, DialogId(), false, is_secret, - !is_secure && !is_secret, is_secure); - if (r_file_id.is_error()) { - return send_error_raw(id, r_file_id.error().code(), r_file_id.error().message()); - } - auto file_id = r_file_id.ok(); - auto upload_file_id = file_manager_->dup_file_id(file_id, "preliminaryUploadFile"); - - file_manager_->upload(upload_file_id, upload_file_callback_, priority, 0); - - send_closure(actor_id(this), &Td::send_result, id, file_manager_->get_file_object(upload_file_id, false)); -} - -void Td::on_request(uint64 id, const td_api::cancelPreliminaryUploadFile &request) { - file_manager_->cancel_upload(FileId(request.file_id_, 0)); - - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, td_api::writeGeneratedFilePart &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(file_manager_actor_, &FileManager::external_file_generate_write_part, request.generation_id_, - request.offset_, std::move(request.data_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setFileGenerationProgress &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(file_manager_actor_, &FileManager::external_file_generate_progress, request.generation_id_, - request.expected_size_, request.local_prefix_size_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::finishFileGeneration &request) { - Status status; - if (request.error_ != nullptr) { - CLEAN_INPUT_STRING(request.error_->message_); - status = Status::Error(request.error_->code_, request.error_->message_); - } - CREATE_OK_REQUEST_PROMISE(); - send_closure(file_manager_actor_, &FileManager::external_file_generate_finish, request.generation_id_, - std::move(status), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::readFilePart &request) { - CREATE_REQUEST_PROMISE(); - send_closure(file_manager_actor_, &FileManager::read_file_part, FileId(request.file_id_, 0), request.offset_, - request.count_, 2, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteFile &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(file_manager_actor_, &FileManager::delete_file, FileId(request.file_id_, 0), std::move(promise), - "td_api::deleteFile"); -} - -void Td::on_request(uint64 id, const td_api::addFileToDownloads &request) { - if (!(1 <= request.priority_ && request.priority_ <= 32)) { - return send_error_raw(id, 400, "Download priority must be between 1 and 32"); - } - CREATE_REQUEST_PROMISE(); - messages_manager_->add_message_file_to_downloads( - FullMessageId(DialogId(request.chat_id_), MessageId(request.message_id_)), FileId(request.file_id_, 0), - request.priority_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleDownloadIsPaused &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(download_manager_actor_, &DownloadManager::toggle_is_paused, FileId(request.file_id_, 0), - request.is_paused_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleAllDownloadsArePaused &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(download_manager_actor_, &DownloadManager::toggle_all_is_paused, request.are_paused_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::removeFileFromDownloads &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(download_manager_actor_, &DownloadManager::remove_file, FileId(request.file_id_, 0), FileSourceId(), - request.delete_from_cache_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::removeAllFilesFromDownloads &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(download_manager_actor_, &DownloadManager::remove_all_files, request.only_active_, - request.only_completed_, request.delete_from_cache_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::searchFileDownloads &request) { - CLEAN_INPUT_STRING(request.query_); - CLEAN_INPUT_STRING(request.offset_); - CREATE_REQUEST_PROMISE(); - send_closure(download_manager_actor_, &DownloadManager::search, std::move(request.query_), request.only_active_, - request.only_completed_, std::move(request.offset_), request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getMessageFileType &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.message_file_head_); - CREATE_REQUEST_PROMISE(); - messages_manager_->get_message_file_type(request.message_file_head_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getMessageImportConfirmationText &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - messages_manager_->get_message_import_confirmation_text(DialogId(request.chat_id_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::importMessages &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->import_messages(DialogId(request.chat_id_), request.message_file_, request.attached_files_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::blockMessageSenderFromReplies &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->block_message_sender_from_replies(MessageId(request.message_id_), request.delete_message_, - request.delete_all_messages_, request.report_spam_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getBlockedMessageSenders &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - messages_manager_->get_blocked_dialogs(request.offset_, request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::addContact &request) { - CHECK_IS_USER(); - auto r_contact = get_contact(std::move(request.contact_)); - if (r_contact.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_contact.move_as_error()); - } - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->add_contact(r_contact.move_as_ok(), request.share_phone_number_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::importContacts &request) { - CHECK_IS_USER(); - vector contacts; - contacts.reserve(request.contacts_.size()); - for (auto &contact : request.contacts_) { - auto r_contact = get_contact(std::move(contact)); - if (r_contact.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_contact.move_as_error()); - } - contacts.push_back(r_contact.move_as_ok()); - } - CREATE_REQUEST(ImportContactsRequest, std::move(contacts)); -} - -void Td::on_request(uint64 id, const td_api::getContacts &request) { - CHECK_IS_USER(); - CREATE_REQUEST(SearchContactsRequest, string(), 1000000); -} - -void Td::on_request(uint64 id, td_api::searchContacts &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST(SearchContactsRequest, request.query_, request.limit_); -} - -void Td::on_request(uint64 id, td_api::removeContacts &request) { - CHECK_IS_USER(); - CREATE_REQUEST(RemoveContactsRequest, UserId::get_user_ids(request.user_ids_)); -} - -void Td::on_request(uint64 id, const td_api::getImportedContactCount &request) { - CHECK_IS_USER(); - CREATE_NO_ARGS_REQUEST(GetImportedContactCountRequest); -} - -void Td::on_request(uint64 id, td_api::changeImportedContacts &request) { - CHECK_IS_USER(); - vector contacts; - contacts.reserve(request.contacts_.size()); - for (auto &contact : request.contacts_) { - auto r_contact = get_contact(std::move(contact)); - if (r_contact.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_contact.move_as_error()); - } - contacts.push_back(r_contact.move_as_ok()); - } - CREATE_REQUEST(ChangeImportedContactsRequest, std::move(contacts)); -} - -void Td::on_request(uint64 id, const td_api::clearImportedContacts &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->clear_imported_contacts(std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setUserPersonalProfilePhoto &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_user_profile_photo(UserId(request.user_id_), request.photo_, false, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::suggestUserProfilePhoto &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_user_profile_photo(UserId(request.user_id_), request.photo_, true, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::searchUserByPhoneNumber &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.phone_number_); - CREATE_REQUEST(SearchUserByPhoneNumberRequest, std::move(request.phone_number_)); -} - -void Td::on_request(uint64 id, const td_api::sharePhoneNumber &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->share_phone_number(UserId(request.user_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getRecentInlineBots &request) { - CHECK_IS_USER(); - CREATE_NO_ARGS_REQUEST(GetRecentInlineBotsRequest); -} - -void Td::on_request(uint64 id, td_api::setName &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.first_name_); - CLEAN_INPUT_STRING(request.last_name_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_name(request.first_name_, request.last_name_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setBio &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.bio_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_bio(request.bio_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setUsername &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.username_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_username(request.username_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::toggleUsernameIsActive &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.username_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_username_is_active(std::move(request.username_), request.is_active_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::reorderActiveUsernames &request) { - CHECK_IS_USER(); - for (auto &username : request.usernames_) { - CLEAN_INPUT_STRING(username); - } - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->reorder_usernames(std::move(request.usernames_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setEmojiStatus &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_emoji_status(EmojiStatus(request.emoji_status_, request.duration_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getThemedEmojiStatuses &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_default_emoji_statuses(false, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getDefaultEmojiStatuses &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_default_emoji_statuses(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getRecentEmojiStatuses &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_recent_emoji_statuses(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::clearRecentEmojiStatuses &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - clear_recent_emoji_statuses(this, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setCommands &request) { - CHECK_IS_BOT(); - CREATE_OK_REQUEST_PROMISE(); - set_commands(this, std::move(request.scope_), std::move(request.language_code_), std::move(request.commands_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::deleteCommands &request) { - CHECK_IS_BOT(); - CREATE_OK_REQUEST_PROMISE(); - delete_commands(this, std::move(request.scope_), std::move(request.language_code_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getCommands &request) { - CHECK_IS_BOT(); - CREATE_REQUEST_PROMISE(); - get_commands(this, std::move(request.scope_), std::move(request.language_code_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setMenuButton &request) { - CHECK_IS_BOT(); - CREATE_OK_REQUEST_PROMISE(); - set_menu_button(this, UserId(request.user_id_), std::move(request.menu_button_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getMenuButton &request) { - CHECK_IS_BOT(); - CREATE_REQUEST_PROMISE(); - get_menu_button(this, UserId(request.user_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setDefaultGroupAdministratorRights &request) { - CHECK_IS_BOT(); - CREATE_OK_REQUEST_PROMISE(); - bot_info_manager_->set_default_group_administrator_rights( - AdministratorRights(request.default_group_administrator_rights_, ChannelType::Megagroup), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setDefaultChannelAdministratorRights &request) { - CHECK_IS_BOT(); - CREATE_OK_REQUEST_PROMISE(); - bot_info_manager_->set_default_channel_administrator_rights( - AdministratorRights(request.default_channel_administrator_rights_, ChannelType::Broadcast), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setBotName &request) { - CLEAN_INPUT_STRING(request.name_); - CREATE_OK_REQUEST_PROMISE(); - bot_info_manager_->set_bot_name(UserId(request.bot_user_id_), request.language_code_, request.name_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getBotName &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.move_as_ok())); - } - }); - bot_info_manager_->get_bot_name(UserId(request.bot_user_id_), request.language_code_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::setBotProfilePhoto &request) { - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_bot_profile_photo(UserId(request.bot_user_id_), request.photo_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::toggleBotUsernameIsActive &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.username_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_bot_username_is_active(UserId(request.bot_user_id_), std::move(request.username_), - request.is_active_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::reorderActiveBotUsernames &request) { - CHECK_IS_USER(); - for (auto &username : request.usernames_) { - CLEAN_INPUT_STRING(username); - } - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->reorder_bot_usernames(UserId(request.bot_user_id_), std::move(request.usernames_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setBotInfoDescription &request) { - CLEAN_INPUT_STRING(request.description_); - CREATE_OK_REQUEST_PROMISE(); - bot_info_manager_->set_bot_info_description(UserId(request.bot_user_id_), request.language_code_, - request.description_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getBotInfoDescription &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.move_as_ok())); - } - }); - bot_info_manager_->get_bot_info_description(UserId(request.bot_user_id_), request.language_code_, - std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::setBotInfoShortDescription &request) { - CLEAN_INPUT_STRING(request.short_description_); - CREATE_OK_REQUEST_PROMISE(); - bot_info_manager_->set_bot_info_about(UserId(request.bot_user_id_), request.language_code_, - request.short_description_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getBotInfoShortDescription &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.move_as_ok())); - } - }); - bot_info_manager_->get_bot_info_about(UserId(request.bot_user_id_), request.language_code_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::setLocation &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_location(Location(request.location_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setProfilePhoto &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_profile_photo(request.photo_, request.is_public_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteProfilePhoto &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->delete_profile_photo(request.profile_photo_id_, false, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getUserProfilePhotos &request) { - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_user_profile_photos(UserId(request.user_id_), request.offset_, request.limit_, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setSupergroupUsername &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.username_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_channel_username(ChannelId(request.supergroup_id_), request.username_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::toggleSupergroupUsernameIsActive &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.username_); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_channel_username_is_active(ChannelId(request.supergroup_id_), std::move(request.username_), - request.is_active_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::disableAllSupergroupUsernames &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->disable_all_channel_usernames(ChannelId(request.supergroup_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::reorderSupergroupActiveUsernames &request) { - CHECK_IS_USER(); - for (auto &username : request.usernames_) { - CLEAN_INPUT_STRING(username); - } - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->reorder_channel_usernames(ChannelId(request.supergroup_id_), std::move(request.usernames_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::setSupergroupStickerSet &request) { - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->set_channel_sticker_set(ChannelId(request.supergroup_id_), StickerSetId(request.sticker_set_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSupergroupSignMessages &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_channel_sign_messages(ChannelId(request.supergroup_id_), request.sign_messages_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSupergroupJoinToSendMessages &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_channel_join_to_send(ChannelId(request.supergroup_id_), request.join_to_send_messages_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSupergroupJoinByRequest &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_channel_join_request(ChannelId(request.supergroup_id_), request.join_by_request_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSupergroupIsAllHistoryAvailable &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_channel_is_all_history_available(ChannelId(request.supergroup_id_), - request.is_all_history_available_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSupergroupHasHiddenMembers &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_channel_has_hidden_participants(ChannelId(request.supergroup_id_), - request.has_hidden_members_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSupergroupHasAggressiveAntiSpamEnabled &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_channel_has_aggressive_anti_spam_enabled( - ChannelId(request.supergroup_id_), request.has_aggressive_anti_spam_enabled_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSupergroupIsForum &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->toggle_channel_is_forum(ChannelId(request.supergroup_id_), request.is_forum_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::toggleSupergroupIsBroadcastGroup &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->convert_channel_to_gigagroup(ChannelId(request.supergroup_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::reportSupergroupSpam &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->report_channel_spam(ChannelId(request.supergroup_id_), - MessageId::get_message_ids(request.message_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::reportSupergroupAntiSpamFalsePositive &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - contacts_manager_->report_channel_anti_spam_false_positive(ChannelId(request.supergroup_id_), - MessageId(request.message_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getSupergroupMembers &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = - PromiseCreator::lambda([promise = std::move(promise), td = this](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_chat_members_object(td)); - } - }); - contacts_manager_->get_channel_participants(ChannelId(request.supergroup_id_), std::move(request.filter_), string(), - request.offset_, request.limit_, -1, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::closeSecretChat &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(secret_chats_manager_, &SecretChatsManager::cancel_chat, SecretChatId(request.secret_chat_id_), false, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getStickers &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST(GetStickersRequest, get_sticker_type(request.sticker_type_), std::move(request.query_), request.limit_, - request.chat_id_); -} - -void Td::on_request(uint64 id, td_api::searchStickers &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.emojis_); - CREATE_REQUEST_PROMISE(); - auto sticker_type = get_sticker_type(request.sticker_type_); - if (sticker_type == StickerType::Regular) { - // legacy - if (request.emojis_ == "⭐️⭐️") { - request.emojis_ = "⭐️"; - } else if (request.emojis_ == "📂⭐️") { - request.emojis_ = "📂"; - } - } - stickers_manager_->search_stickers(sticker_type, std::move(request.emojis_), request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getPremiumStickers &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_premium_stickers(request.limit_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getInstalledStickerSets &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetInstalledStickerSetsRequest, get_sticker_type(request.sticker_type_)); -} - -void Td::on_request(uint64 id, const td_api::getArchivedStickerSets &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetArchivedStickerSetsRequest, get_sticker_type(request.sticker_type_), request.offset_sticker_set_id_, - request.limit_); -} - -void Td::on_request(uint64 id, const td_api::getTrendingStickerSets &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetTrendingStickerSetsRequest, get_sticker_type(request.sticker_type_), request.offset_, - request.limit_); -} - -void Td::on_request(uint64 id, const td_api::getAttachedStickerSets &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetAttachedStickerSetsRequest, request.file_id_); -} - -void Td::on_request(uint64 id, const td_api::getStickerSet &request) { - CREATE_REQUEST(GetStickerSetRequest, request.set_id_); -} - -void Td::on_request(uint64 id, td_api::searchStickerSet &request) { - CLEAN_INPUT_STRING(request.name_); - CREATE_REQUEST(SearchStickerSetRequest, std::move(request.name_)); -} - -void Td::on_request(uint64 id, td_api::searchInstalledStickerSets &request) { - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST(SearchInstalledStickerSetsRequest, get_sticker_type(request.sticker_type_), std::move(request.query_), - request.limit_); -} - -void Td::on_request(uint64 id, td_api::searchStickerSets &request) { - CLEAN_INPUT_STRING(request.query_); - CREATE_REQUEST(SearchStickerSetsRequest, std::move(request.query_)); -} - -void Td::on_request(uint64 id, const td_api::changeStickerSet &request) { - CHECK_IS_USER(); - CREATE_REQUEST(ChangeStickerSetRequest, request.set_id_, request.is_installed_, request.is_archived_); -} - -void Td::on_request(uint64 id, const td_api::viewTrendingStickerSets &request) { - CHECK_IS_USER(); - stickers_manager_->view_featured_sticker_sets(StickersManager::convert_sticker_set_ids(request.sticker_set_ids_)); - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, td_api::reorderInstalledStickerSets &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->reorder_installed_sticker_sets(get_sticker_type(request.sticker_type_), - StickersManager::convert_sticker_set_ids(request.sticker_set_ids_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::uploadStickerFile &request) { - CREATE_REQUEST(UploadStickerFileRequest, request.user_id_, get_sticker_format(request.sticker_format_), - std::move(request.sticker_)); -} - -void Td::on_request(uint64 id, td_api::getSuggestedStickerSetName &request) { - CLEAN_INPUT_STRING(request.title_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - stickers_manager_->get_suggested_sticker_set_name(std::move(request.title_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::checkStickerSetName &request) { - CLEAN_INPUT_STRING(request.name_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda( - [promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(StickersManager::get_check_sticker_set_name_result_object(result.ok())); - } - }); - stickers_manager_->check_sticker_set_name(request.name_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::createNewStickerSet &request) { - CLEAN_INPUT_STRING(request.title_); - CLEAN_INPUT_STRING(request.name_); - CLEAN_INPUT_STRING(request.source_); - CREATE_REQUEST_PROMISE(); - stickers_manager_->create_new_sticker_set( - UserId(request.user_id_), std::move(request.title_), std::move(request.name_), - get_sticker_format(request.sticker_format_), get_sticker_type(request.sticker_type_), request.needs_repainting_, - std::move(request.stickers_), std::move(request.source_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::addStickerToSet &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.name_); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->add_sticker_to_set(UserId(request.user_id_), std::move(request.name_), std::move(request.sticker_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setStickerSetThumbnail &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.name_); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->set_sticker_set_thumbnail(UserId(request.user_id_), std::move(request.name_), - std::move(request.thumbnail_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setCustomEmojiStickerSetThumbnail &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.name_); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->set_custom_emoji_sticker_set_thumbnail( - std::move(request.name_), CustomEmojiId(request.custom_emoji_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setStickerSetTitle &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.name_); - CLEAN_INPUT_STRING(request.title_); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->set_sticker_set_title(std::move(request.name_), std::move(request.title_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::deleteStickerSet &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.name_); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->delete_sticker_set(std::move(request.name_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setStickerPositionInSet &request) { - CHECK_IS_BOT(); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->set_sticker_position_in_set(request.sticker_, request.position_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::removeStickerFromSet &request) { - CHECK_IS_BOT(); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->remove_sticker_from_set(request.sticker_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setStickerEmojis &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.emojis_); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->set_sticker_emojis(request.sticker_, request.emojis_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setStickerKeywords &request) { - CHECK_IS_BOT(); - for (auto &keyword : request.keywords_) { - CLEAN_INPUT_STRING(keyword); - } - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->set_sticker_keywords(request.sticker_, std::move(request.keywords_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setStickerMaskPosition &request) { - CHECK_IS_BOT(); - CREATE_OK_REQUEST_PROMISE(); - stickers_manager_->set_sticker_mask_position(request.sticker_, std::move(request.mask_position_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getRecentStickers &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetRecentStickersRequest, request.is_attached_); -} - -void Td::on_request(uint64 id, td_api::addRecentSticker &request) { - CHECK_IS_USER(); - CREATE_REQUEST(AddRecentStickerRequest, request.is_attached_, std::move(request.sticker_)); -} - -void Td::on_request(uint64 id, td_api::removeRecentSticker &request) { - CHECK_IS_USER(); - CREATE_REQUEST(RemoveRecentStickerRequest, request.is_attached_, std::move(request.sticker_)); -} - -void Td::on_request(uint64 id, td_api::clearRecentStickers &request) { - CHECK_IS_USER(); - CREATE_REQUEST(ClearRecentStickersRequest, request.is_attached_); -} - -void Td::on_request(uint64 id, const td_api::getFavoriteStickers &request) { - CHECK_IS_USER(); - CREATE_NO_ARGS_REQUEST(GetFavoriteStickersRequest); -} - -void Td::on_request(uint64 id, td_api::addFavoriteSticker &request) { - CHECK_IS_USER(); - CREATE_REQUEST(AddFavoriteStickerRequest, std::move(request.sticker_)); -} - -void Td::on_request(uint64 id, td_api::removeFavoriteSticker &request) { - CHECK_IS_USER(); - CREATE_REQUEST(RemoveFavoriteStickerRequest, std::move(request.sticker_)); -} - -void Td::on_request(uint64 id, td_api::getStickerEmojis &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetStickerEmojisRequest, std::move(request.sticker_)); -} - -void Td::on_request(uint64 id, td_api::searchEmojis &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.text_); - for (auto &input_language_code : request.input_language_codes_) { - CLEAN_INPUT_STRING(input_language_code); - } - CREATE_REQUEST(SearchEmojisRequest, std::move(request.text_), request.exact_match_, - std::move(request.input_language_codes_)); -} - -void Td::on_request(uint64 id, const td_api::getEmojiCategories &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_emoji_groups(get_emoji_group_type(request.type_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getAnimatedEmoji &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.emoji_); - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_animated_emoji(std::move(request.emoji_), false, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getEmojiSuggestionsUrl &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.language_code_); - CREATE_REQUEST(GetEmojiSuggestionsUrlRequest, std::move(request.language_code_)); -} - -void Td::on_request(uint64 id, const td_api::getCustomEmojiStickers &request) { - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_custom_emoji_stickers(CustomEmojiId::get_custom_emoji_ids(request.custom_emoji_ids_), true, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getDefaultChatPhotoCustomEmojiStickers &request) { - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_default_dialog_photo_custom_emoji_stickers(false, false, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getDefaultProfilePhotoCustomEmojiStickers &request) { - CREATE_REQUEST_PROMISE(); - stickers_manager_->get_default_dialog_photo_custom_emoji_stickers(true, false, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getSavedAnimations &request) { - CHECK_IS_USER(); - CREATE_NO_ARGS_REQUEST(GetSavedAnimationsRequest); -} - -void Td::on_request(uint64 id, td_api::addSavedAnimation &request) { - CHECK_IS_USER(); - CREATE_REQUEST(AddSavedAnimationRequest, std::move(request.animation_)); -} - -void Td::on_request(uint64 id, td_api::removeSavedAnimation &request) { - CHECK_IS_USER(); - CREATE_REQUEST(RemoveSavedAnimationRequest, std::move(request.animation_)); -} - -void Td::on_request(uint64 id, const td_api::getSavedNotificationSound &request) { - CHECK_IS_USER(); - CREATE_REQUEST(GetSavedNotificationSoundRequest, request.notification_sound_id_); -} - -void Td::on_request(uint64 id, const td_api::getSavedNotificationSounds &request) { - CHECK_IS_USER(); - CREATE_NO_ARGS_REQUEST(GetSavedNotificationSoundsRequest); -} - -void Td::on_request(uint64 id, td_api::addSavedNotificationSound &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - notification_settings_manager_->add_saved_ringtone(std::move(request.sound_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::removeSavedNotificationSound &request) { - CHECK_IS_USER(); - CREATE_REQUEST(RemoveSavedNotificationSoundRequest, request.notification_sound_id_); -} - -void Td::on_request(uint64 id, const td_api::getChatNotificationSettingsExceptions &request) { - CHECK_IS_USER(); - bool filter_scope = false; - NotificationSettingsScope scope = NotificationSettingsScope::Private; - if (request.scope_ != nullptr) { - filter_scope = true; - scope = get_notification_settings_scope(request.scope_); - } - CREATE_REQUEST(GetChatNotificationSettingsExceptionsRequest, scope, filter_scope, request.compare_sound_); -} - -void Td::on_request(uint64 id, const td_api::getScopeNotificationSettings &request) { - CHECK_IS_USER(); - if (request.scope_ == nullptr) { - return send_error_raw(id, 400, "Scope must be non-empty"); - } - CREATE_REQUEST(GetScopeNotificationSettingsRequest, get_notification_settings_scope(request.scope_)); -} - -void Td::on_request(uint64 id, const td_api::removeChatActionBar &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->remove_dialog_action_bar(DialogId(request.chat_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::reportChat &request) { - CHECK_IS_USER(); - auto r_report_reason = ReportReason::get_report_reason(std::move(request.reason_), std::move(request.text_)); - if (r_report_reason.is_error()) { - return send_error_raw(id, r_report_reason.error().code(), r_report_reason.error().message()); - } - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->report_dialog(DialogId(request.chat_id_), MessageId::get_message_ids(request.message_ids_), - r_report_reason.move_as_ok(), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::reportChatPhoto &request) { - CHECK_IS_USER(); - auto r_report_reason = ReportReason::get_report_reason(std::move(request.reason_), std::move(request.text_)); - if (r_report_reason.is_error()) { - return send_error_raw(id, r_report_reason.error().code(), r_report_reason.error().message()); - } - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->report_dialog_photo(DialogId(request.chat_id_), FileId(request.file_id_, 0), - r_report_reason.move_as_ok(), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::reportMessageReactions &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - TRY_RESULT_PROMISE(promise, sender_dialog_id, get_message_sender_dialog_id(this, request.sender_id_, false, false)); - report_message_reactions(this, {DialogId(request.chat_id_), MessageId(request.message_id_)}, sender_dialog_id, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getChatStatistics &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_channel_statistics(DialogId(request.chat_id_), request.is_dark_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getMessageStatistics &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_channel_message_statistics({DialogId(request.chat_id_), MessageId(request.message_id_)}, - request.is_dark_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getStatisticalGraph &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.token_); - CREATE_REQUEST_PROMISE(); - contacts_manager_->load_statistics_graph(DialogId(request.chat_id_), std::move(request.token_), request.x_, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setChatNotificationSettings &request) { - CHECK_IS_USER(); - answer_ok_query(id, messages_manager_->set_dialog_notification_settings(DialogId(request.chat_id_), - std::move(request.notification_settings_))); -} - -void Td::on_request(uint64 id, td_api::setForumTopicNotificationSettings &request) { - CHECK_IS_USER(); - answer_ok_query(id, forum_topic_manager_->set_forum_topic_notification_settings( - DialogId(request.chat_id_), MessageId(request.message_thread_id_), - std::move(request.notification_settings_))); -} - -void Td::on_request(uint64 id, td_api::setScopeNotificationSettings &request) { - CHECK_IS_USER(); - if (request.scope_ == nullptr) { - return send_error_raw(id, 400, "Scope must be non-empty"); - } - answer_ok_query(id, notification_settings_manager_->set_scope_notification_settings( - get_notification_settings_scope(request.scope_), std::move(request.notification_settings_))); -} - -void Td::on_request(uint64 id, const td_api::resetAllNotificationSettings &request) { - CHECK_IS_USER(); - messages_manager_->reset_all_notification_settings(); - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, const td_api::getMapThumbnailFile &request) { - DialogId dialog_id(request.chat_id_); - if (!messages_manager_->have_dialog_force(dialog_id, "getMapThumbnailFile")) { - dialog_id = DialogId(); - } - - auto r_file_id = file_manager_->get_map_thumbnail_file_id(Location(request.location_), request.zoom_, request.width_, - request.height_, request.scale_, dialog_id); - if (r_file_id.is_error()) { - send_closure(actor_id(this), &Td::send_error, id, r_file_id.move_as_error()); - } else { - send_closure(actor_id(this), &Td::send_result, id, file_manager_->get_file_object(r_file_id.ok())); - } -} - -void Td::on_request(uint64 id, const td_api::getLocalizationTargetInfo &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::get_languages, request.only_local_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getLanguagePackInfo &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.language_pack_id_); - CREATE_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::search_language_info, request.language_pack_id_, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getLanguagePackStrings &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.language_pack_id_); - for (auto &key : request.keys_) { - CLEAN_INPUT_STRING(key); - } - CREATE_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::get_language_pack_strings, - std::move(request.language_pack_id_), std::move(request.keys_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::synchronizeLanguagePack &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.language_pack_id_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::synchronize_language_pack, - std::move(request.language_pack_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::addCustomServerLanguagePack &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.language_pack_id_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::add_custom_server_language, - std::move(request.language_pack_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setCustomLanguagePack &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::set_custom_language, std::move(request.info_), - std::move(request.strings_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editCustomLanguagePackInfo &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::edit_custom_language_info, std::move(request.info_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setCustomLanguagePackString &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.language_pack_id_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::set_custom_language_string, - std::move(request.language_pack_id_), std::move(request.new_string_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::deleteLanguagePack &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.language_pack_id_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(language_pack_manager_, &LanguagePackManager::delete_language, std::move(request.language_pack_id_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getOption &request) { - CLEAN_INPUT_STRING(request.name_); - CREATE_REQUEST_PROMISE(); - option_manager_->get_option(request.name_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setOption &request) { - CLEAN_INPUT_STRING(request.name_); - CREATE_OK_REQUEST_PROMISE(); - option_manager_->set_option(request.name_, std::move(request.value_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setPollAnswer &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->set_poll_answer({DialogId(request.chat_id_), MessageId(request.message_id_)}, - std::move(request.option_ids_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getPollVoters &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda( - [promise = std::move(promise), td = this](Result>> result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td->contacts_manager_->get_users_object(result.ok().first, result.ok().second)); - } - }); - messages_manager_->get_poll_voters({DialogId(request.chat_id_), MessageId(request.message_id_)}, request.option_id_, - request.offset_, request.limit_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::stopPoll &request) { - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->stop_poll({DialogId(request.chat_id_), MessageId(request.message_id_)}, - std::move(request.reply_markup_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::hideSuggestedAction &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - dismiss_suggested_action(SuggestedAction(request.action_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getLoginUrlInfo &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - link_manager_->get_login_url_info({DialogId(request.chat_id_), MessageId(request.message_id_)}, request.button_id_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getLoginUrl &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - link_manager_->get_login_url({DialogId(request.chat_id_), MessageId(request.message_id_)}, request.button_id_, - request.allow_write_access_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::shareUserWithBot &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->share_dialog_with_bot({DialogId(request.chat_id_), MessageId(request.message_id_)}, - request.button_id_, DialogId(UserId(request.shared_user_id_)), true, - request.only_check_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::shareChatWithBot &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - messages_manager_->share_dialog_with_bot({DialogId(request.chat_id_), MessageId(request.message_id_)}, - request.button_id_, DialogId(request.shared_chat_id_), false, - request.only_check_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getInlineQueryResults &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.query_); - CLEAN_INPUT_STRING(request.offset_); - CREATE_REQUEST(GetInlineQueryResultsRequest, request.bot_user_id_, request.chat_id_, request.user_location_, - std::move(request.query_), std::move(request.offset_)); -} - -void Td::on_request(uint64 id, td_api::answerInlineQuery &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.next_offset_); - CREATE_OK_REQUEST_PROMISE(); - inline_queries_manager_->answer_inline_query(request.inline_query_id_, request.is_personal_, - std::move(request.button_), std::move(request.results_), - request.cache_time_, request.next_offset_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::searchWebApp &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.web_app_short_name_); - CREATE_REQUEST_PROMISE(); - attach_menu_manager_->get_web_app(UserId(request.bot_user_id_), request.web_app_short_name_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getWebAppLinkUrl &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.web_app_short_name_); - CLEAN_INPUT_STRING(request.start_parameter_); - CLEAN_INPUT_STRING(request.application_name_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.move_as_ok())); - } - }); - attach_menu_manager_->request_app_web_view( - DialogId(request.chat_id_), UserId(request.bot_user_id_), std::move(request.web_app_short_name_), - std::move(request.start_parameter_), std::move(request.theme_), std::move(request.application_name_), - request.allow_write_access_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::getWebAppUrl &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.url_); - CLEAN_INPUT_STRING(request.application_name_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.move_as_ok())); - } - }); - inline_queries_manager_->get_simple_web_view_url(UserId(request.bot_user_id_), std::move(request.url_), - std::move(request.theme_), std::move(request.application_name_), - std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::sendWebAppData &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.button_text_); - CLEAN_INPUT_STRING(request.data_); - CREATE_OK_REQUEST_PROMISE(); - inline_queries_manager_->send_web_view_data(UserId(request.bot_user_id_), std::move(request.button_text_), - std::move(request.data_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::openWebApp &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.url_); - CLEAN_INPUT_STRING(request.application_name_); - CREATE_REQUEST_PROMISE(); - attach_menu_manager_->request_web_view(DialogId(request.chat_id_), UserId(request.bot_user_id_), - MessageId(request.message_thread_id_), MessageId(request.reply_to_message_id_), - std::move(request.url_), std::move(request.theme_), - std::move(request.application_name_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::closeWebApp &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - attach_menu_manager_->close_web_view(request.web_app_launch_id_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::answerWebAppQuery &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.web_app_query_id_); - CREATE_REQUEST_PROMISE(); - inline_queries_manager_->answer_web_view_query(request.web_app_query_id_, std::move(request.result_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getCallbackQueryAnswer &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - callback_queries_manager_->send_callback_query({DialogId(request.chat_id_), MessageId(request.message_id_)}, - std::move(request.payload_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::answerCallbackQuery &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.text_); - CLEAN_INPUT_STRING(request.url_); - CREATE_OK_REQUEST_PROMISE(); - callback_queries_manager_->answer_callback_query(request.callback_query_id_, request.text_, request.show_alert_, - request.url_, request.cache_time_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::answerShippingQuery &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.error_message_); - CREATE_OK_REQUEST_PROMISE(); - answer_shipping_query(this, request.shipping_query_id_, std::move(request.shipping_options_), request.error_message_, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::answerPreCheckoutQuery &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.error_message_); - CREATE_OK_REQUEST_PROMISE(); - answer_pre_checkout_query(this, request.pre_checkout_query_id_, request.error_message_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getBankCardInfo &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.bank_card_number_); - CREATE_REQUEST_PROMISE(); - get_bank_card_info(this, request.bank_card_number_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getPaymentForm &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_payment_form(this, std::move(request.input_invoice_), request.theme_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::validateOrderInfo &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - validate_order_info(this, std::move(request.input_invoice_), std::move(request.order_info_), request.allow_save_, - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendPaymentForm &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.order_info_id_); - CLEAN_INPUT_STRING(request.shipping_option_id_); - CREATE_REQUEST_PROMISE(); - send_payment_form(this, std::move(request.input_invoice_), request.payment_form_id_, request.order_info_id_, - request.shipping_option_id_, request.credentials_, request.tip_amount_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getPaymentReceipt &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_payment_receipt(this, {DialogId(request.chat_id_), MessageId(request.message_id_)}, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getSavedOrderInfo &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_saved_order_info(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteSavedOrderInfo &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - delete_saved_order_info(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deleteSavedCredentials &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - delete_saved_credentials(this, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::createInvoiceLink &request) { - CHECK_IS_BOT(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(td_api::make_object(result.move_as_ok())); - } - }); - export_invoice(this, std::move(request.invoice_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::getPassportElement &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); - if (request.type_ == nullptr) { - return send_error_raw(id, 400, "Type must be non-empty"); - } - CREATE_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::get_secure_value, std::move(request.password_), - get_secure_value_type_td_api(request.type_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getAllPassportElements &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); - CREATE_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::get_all_secure_values, std::move(request.password_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setPassportElement &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); - auto r_secure_value = get_secure_value(file_manager_.get(), std::move(request.element_)); - if (r_secure_value.is_error()) { - return send_error_raw(id, 400, r_secure_value.error().message()); - } - CREATE_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::set_secure_value, std::move(request.password_), - r_secure_value.move_as_ok(), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::deletePassportElement &request) { - CHECK_IS_USER(); - if (request.type_ == nullptr) { - return send_error_raw(id, 400, "Type must be non-empty"); - } - CREATE_OK_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::delete_secure_value, get_secure_value_type_td_api(request.type_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setPassportElementErrors &request) { - CHECK_IS_BOT(); - auto r_input_user = contacts_manager_->get_input_user(UserId(request.user_id_)); - if (r_input_user.is_error()) { - return send_error_raw(id, r_input_user.error().code(), r_input_user.error().message()); - } - CREATE_OK_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::set_secure_value_errors, this, r_input_user.move_as_ok(), - std::move(request.errors_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getPreferredCountryLanguage &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.country_code_); - CREATE_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::get_preferred_country_language, std::move(request.country_code_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendPhoneNumberVerificationCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.phone_number_); - send_closure(verify_phone_number_manager_, &PhoneNumberManager::set_phone_number, id, - std::move(request.phone_number_), std::move(request.settings_)); -} - -void Td::on_request(uint64 id, const td_api::resendPhoneNumberVerificationCode &request) { - CHECK_IS_USER(); - send_closure(verify_phone_number_manager_, &PhoneNumberManager::resend_authentication_code, id); -} - -void Td::on_request(uint64 id, td_api::checkPhoneNumberVerificationCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.code_); - send_closure(verify_phone_number_manager_, &PhoneNumberManager::check_code, id, std::move(request.code_)); -} - -void Td::on_request(uint64 id, td_api::sendEmailAddressVerificationCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.email_address_); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_email_address_authentication_code_info_object()); - } - }); - send_closure(password_manager_, &PasswordManager::send_email_address_verification_code, - std::move(request.email_address_), std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::resendEmailAddressVerificationCode &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(result.ok().get_email_address_authentication_code_info_object()); - } - }); - send_closure(password_manager_, &PasswordManager::resend_email_address_verification_code, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::checkEmailAddressVerificationCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.code_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(password_manager_, &PasswordManager::check_email_address_verification_code, std::move(request.code_), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getPassportAuthorizationForm &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.public_key_); - CLEAN_INPUT_STRING(request.scope_); - CLEAN_INPUT_STRING(request.nonce_); - UserId bot_user_id(request.bot_user_id_); - if (!bot_user_id.is_valid()) { - return send_error_raw(id, 400, "Bot user identifier invalid"); - } - if (request.nonce_.empty()) { - return send_error_raw(id, 400, "Nonce must be non-empty"); - } - CREATE_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::get_passport_authorization_form, bot_user_id, std::move(request.scope_), - std::move(request.public_key_), std::move(request.nonce_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getPassportAuthorizationFormAvailableElements &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.password_); - CREATE_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::get_passport_authorization_form_available_elements, - request.authorization_form_id_, std::move(request.password_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendPassportAuthorizationForm &request) { - CHECK_IS_USER(); - for (auto &type : request.types_) { - if (type == nullptr) { - return send_error_raw(id, 400, "Type must be non-empty"); - } - } - - CREATE_OK_REQUEST_PROMISE(); - send_closure(secure_manager_, &SecureManager::send_passport_authorization_form, request.authorization_form_id_, - get_secure_value_types_td_api(request.types_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::sendPhoneNumberConfirmationCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.phone_number_); - CLEAN_INPUT_STRING(request.hash_); - send_closure(confirm_phone_number_manager_, &PhoneNumberManager::set_phone_number_and_hash, id, - std::move(request.hash_), std::move(request.phone_number_), std::move(request.settings_)); -} - -void Td::on_request(uint64 id, const td_api::resendPhoneNumberConfirmationCode &request) { - CHECK_IS_USER(); - send_closure(confirm_phone_number_manager_, &PhoneNumberManager::resend_authentication_code, id); -} - -void Td::on_request(uint64 id, td_api::checkPhoneNumberConfirmationCode &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.code_); - send_closure(confirm_phone_number_manager_, &PhoneNumberManager::check_code, id, std::move(request.code_)); -} - -void Td::on_request(uint64 id, const td_api::getSupportUser &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - contacts_manager_->get_support_user(std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getBackgrounds &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - background_manager_->get_backgrounds(request.for_dark_theme_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getBackgroundUrl &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.name_); - Result r_url = LinkManager::get_background_url(request.name_, std::move(request.type_)); - if (r_url.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_url.move_as_error()); - } - - send_closure(actor_id(this), &Td::send_result, id, td_api::make_object(r_url.ok())); -} - -void Td::on_request(uint64 id, td_api::searchBackground &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.name_); - CREATE_REQUEST(SearchBackgroundRequest, std::move(request.name_)); -} - -void Td::on_request(uint64 id, td_api::setBackground &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - background_manager_->set_background(request.background_.get(), request.type_.get(), request.for_dark_theme_, - std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::removeBackground &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - background_manager_->remove_background(BackgroundId(request.background_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::resetBackgrounds &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - background_manager_->reset_backgrounds(std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.referrer_); - CREATE_REQUEST_PROMISE(); - create_handler(std::move(promise))->send(request.referrer_); -} - -void Td::on_request(uint64 id, td_api::setBotUpdatesStatus &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.error_message_); - create_handler()->send(request.pending_update_count_, request.error_message_); - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, td_api::sendCustomRequest &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.method_); - CLEAN_INPUT_STRING(request.parameters_); - CREATE_REQUEST_PROMISE(); - create_handler(std::move(promise))->send(request.method_, request.parameters_); -} - -void Td::on_request(uint64 id, td_api::answerCustomQuery &request) { - CHECK_IS_BOT(); - CLEAN_INPUT_STRING(request.data_); - CREATE_OK_REQUEST_PROMISE(); - create_handler(std::move(promise))->send(request.custom_query_id_, request.data_); -} - -void Td::on_request(uint64 id, const td_api::setAlarm &request) { - if (request.seconds_ < 0 || request.seconds_ > 3e9) { - return send_error_raw(id, 400, "Wrong parameter seconds specified"); - } - - int64 alarm_id = alarm_id_++; - pending_alarms_.emplace(alarm_id, id); - alarm_timeout_.set_timeout_in(alarm_id, request.seconds_); -} - -void Td::on_request(uint64 id, td_api::searchHashtags &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.prefix_); - CREATE_REQUEST_PROMISE(); - auto query_promise = - PromiseCreator::lambda([promise = std::move(promise)](Result> result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - send_closure(hashtag_hints_, &HashtagHints::query, std::move(request.prefix_), request.limit_, - std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::removeRecentHashtag &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.hashtag_); - CREATE_OK_REQUEST_PROMISE(); - send_closure(hashtag_hints_, &HashtagHints::remove_hashtag, std::move(request.hashtag_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getPremiumLimit &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_premium_limit(request.limit_type_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getPremiumFeatures &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_premium_features(this, request.source_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getPremiumStickerExamples &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - stickers_manager_->search_stickers(StickerType::Regular, "⭐️⭐️", 100, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::viewPremiumFeature &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - view_premium_feature(this, request.feature_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::clickPremiumSubscriptionButton &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - click_premium_subscription_button(this, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getPremiumState &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_premium_state(this, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::canPurchasePremium &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - can_purchase_premium(this, std::move(request.purpose_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::assignAppStoreTransaction &request) { - CHECK_IS_USER(); - CREATE_OK_REQUEST_PROMISE(); - assign_app_store_transaction(this, request.receipt_, std::move(request.purpose_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::assignGooglePlayTransaction &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.package_name_); - CLEAN_INPUT_STRING(request.store_product_id_); - CLEAN_INPUT_STRING(request.purchase_token_); - CREATE_OK_REQUEST_PROMISE(); - assign_play_market_transaction(this, request.package_name_, request.store_product_id_, request.purchase_token_, - std::move(request.purpose_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::acceptTermsOfService &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.terms_of_service_id_); - auto promise = PromiseCreator::lambda([id = id, actor_id = actor_id(this)](Result<> result) { - if (result.is_error()) { - send_closure(actor_id, &Td::send_error, id, result.move_as_error()); - } else { - send_closure(actor_id, &Td::send_result, id, td_api::make_object()); - send_closure(actor_id, &Td::schedule_get_terms_of_service, 0); - } - }); - accept_terms_of_service(this, std::move(request.terms_of_service_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getCountries &request) { - CREATE_REQUEST_PROMISE(); - country_info_manager_->get_countries(std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getCountryCode &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - country_info_manager_->get_current_country_code(std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getPhoneNumberInfo &request) { - CREATE_REQUEST_PROMISE(); - country_info_manager_->get_phone_number_info(request.phone_number_prefix_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getApplicationDownloadLink &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - get_invite_text(this, std::move(query_promise)); -} - -void Td::on_request(uint64 id, td_api::getDeepLinkInfo &request) { - CLEAN_INPUT_STRING(request.link_); - CREATE_REQUEST_PROMISE(); - link_manager_->get_deep_link_info(request.link_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getApplicationConfig &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - send_closure(G()->config_manager(), &ConfigManager::get_app_config, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::addApplicationChangelog &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.previous_application_version_); - CREATE_OK_REQUEST_PROMISE(); - add_app_changelog(this, request.previous_application_version_, std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::saveApplicationLogEvent &request) { - CHECK_IS_USER(); - CLEAN_INPUT_STRING(request.type_); - CREATE_OK_REQUEST_PROMISE(); - save_app_log(this, request.type_, DialogId(request.chat_id_), convert_json_value(std::move(request.data_)), - std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::addProxy &request) { - CLEAN_INPUT_STRING(request.server_); - CREATE_REQUEST_PROMISE(); - send_closure(G()->connection_creator(), &ConnectionCreator::add_proxy, -1, std::move(request.server_), request.port_, - request.enable_, std::move(request.type_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::editProxy &request) { - if (request.proxy_id_ < 0) { - return send_error_raw(id, 400, "Proxy identifier invalid"); - } - CLEAN_INPUT_STRING(request.server_); - CREATE_REQUEST_PROMISE(); - send_closure(G()->connection_creator(), &ConnectionCreator::add_proxy, request.proxy_id_, std::move(request.server_), - request.port_, request.enable_, std::move(request.type_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::enableProxy &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->connection_creator(), &ConnectionCreator::enable_proxy, request.proxy_id_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::disableProxy &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->connection_creator(), &ConnectionCreator::disable_proxy, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::removeProxy &request) { - CREATE_OK_REQUEST_PROMISE(); - send_closure(G()->connection_creator(), &ConnectionCreator::remove_proxy, request.proxy_id_, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getProxies &request) { - CREATE_REQUEST_PROMISE(); - send_closure(G()->connection_creator(), &ConnectionCreator::get_proxies, std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getProxyLink &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - send_closure(G()->connection_creator(), &ConnectionCreator::get_proxy_link, request.proxy_id_, - std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::pingProxy &request) { - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - send_closure(G()->connection_creator(), &ConnectionCreator::ping_proxy, request.proxy_id_, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getUserSupportInfo &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - get_user_info(this, UserId(request.user_id_), std::move(promise)); -} - -void Td::on_request(uint64 id, td_api::setUserSupportInfo &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - set_user_info(this, UserId(request.user_id_), std::move(request.message_), std::move(promise)); -} - -void Td::on_request(uint64 id, const td_api::getSupportName &request) { - CHECK_IS_USER(); - CREATE_REQUEST_PROMISE(); - auto query_promise = PromiseCreator::lambda([promise = std::move(promise)](Result result) mutable { - if (result.is_error()) { - promise.set_error(result.move_as_error()); - } else { - promise.set_value(make_tl_object(result.move_as_ok())); - } - }); - get_support_name(this, std::move(query_promise)); -} - -void Td::on_request(uint64 id, const td_api::getTextEntities &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::parseTextEntities &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::parseMarkdown &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getMarkdownText &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getFileMimeType &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getFileExtension &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::cleanFileName &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getLanguagePackString &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getPhoneNumberInfoSync &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getPushReceiverId &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getChatFolderDefaultIconName &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getJsonValue &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getJsonString &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getThemeParametersJsonString &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::setLogStream &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getLogStream &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::setLogVerbosityLevel &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getLogVerbosityLevel &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getLogTags &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::setLogTagVerbosityLevel &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::getLogTagVerbosityLevel &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::addLogMessage &request) { - UNREACHABLE(); +void Td::init_managers() { + account_manager_ = make_unique(this, create_reference()); + account_manager_actor_ = register_actor("AccountManager", account_manager_.get()); + G()->set_account_manager(account_manager_actor_.get()); + animations_manager_ = make_unique(this, create_reference()); + animations_manager_actor_ = register_actor("AnimationsManager", animations_manager_.get()); + G()->set_animations_manager(animations_manager_actor_.get()); + attach_menu_manager_ = make_unique(this, create_reference()); + attach_menu_manager_actor_ = register_actor("AttachMenuManager", attach_menu_manager_.get()); + G()->set_attach_menu_manager(attach_menu_manager_actor_.get()); + autosave_manager_ = make_unique(this, create_reference()); + autosave_manager_actor_ = register_actor("AutosaveManager", autosave_manager_.get()); + G()->set_autosave_manager(autosave_manager_actor_.get()); + background_manager_ = make_unique(this, create_reference()); + background_manager_actor_ = register_actor("BackgroundManager", background_manager_.get()); + G()->set_background_manager(background_manager_actor_.get()); + boost_manager_ = make_unique(this, create_reference()); + boost_manager_actor_ = register_actor("BoostManager", boost_manager_.get()); + G()->set_boost_manager(boost_manager_actor_.get()); + bot_info_manager_ = make_unique(this, create_reference()); + bot_info_manager_actor_ = register_actor("BotInfoManager", bot_info_manager_.get()); + G()->set_bot_info_manager(bot_info_manager_actor_.get()); + business_connection_manager_ = make_unique(this, create_reference()); + business_connection_manager_actor_ = register_actor("BusinessConnectionManager", business_connection_manager_.get()); + G()->set_business_connection_manager(business_connection_manager_actor_.get()); + business_manager_ = make_unique(this, create_reference()); + business_manager_actor_ = register_actor("BusinessManager", business_manager_.get()); + G()->set_business_manager(business_manager_actor_.get()); + channel_recommendation_manager_ = make_unique(this, create_reference()); + channel_recommendation_manager_actor_ = + register_actor("ChannelRecommendationManager", channel_recommendation_manager_.get()); + chat_manager_ = make_unique(this, create_reference()); + chat_manager_actor_ = register_actor("ChatManager", chat_manager_.get()); + G()->set_chat_manager(chat_manager_actor_.get()); + common_dialog_manager_ = make_unique(this, create_reference()); + common_dialog_manager_actor_ = register_actor("CommonDialogManager", common_dialog_manager_.get()); + connection_state_manager_ = make_unique(this, create_reference()); + connection_state_manager_actor_ = register_actor("ConnectionStateManager", connection_state_manager_.get()); + country_info_manager_ = make_unique(this, create_reference()); + country_info_manager_actor_ = register_actor("CountryInfoManager", country_info_manager_.get()); + dialog_action_manager_ = make_unique(this, create_reference()); + dialog_action_manager_actor_ = register_actor("DialogActionManager", dialog_action_manager_.get()); + G()->set_dialog_action_manager(dialog_action_manager_actor_.get()); + dialog_filter_manager_ = make_unique(this, create_reference()); + dialog_filter_manager_actor_ = register_actor("DialogFilterManager", dialog_filter_manager_.get()); + G()->set_dialog_filter_manager(dialog_filter_manager_actor_.get()); + dialog_invite_link_manager_ = make_unique(this, create_reference()); + dialog_invite_link_manager_actor_ = register_actor("DialogInviteLinkManager", dialog_invite_link_manager_.get()); + G()->set_dialog_invite_link_manager(dialog_invite_link_manager_actor_.get()); + dialog_manager_ = make_unique(this, create_reference()); + dialog_manager_actor_ = register_actor("DialogManager", dialog_manager_.get()); + G()->set_dialog_manager(dialog_manager_actor_.get()); + dialog_participant_manager_ = make_unique(this, create_reference()); + dialog_participant_manager_actor_ = register_actor("DialogParticipantManager", dialog_participant_manager_.get()); + G()->set_dialog_participant_manager(dialog_participant_manager_actor_.get()); + download_manager_ = DownloadManager::create(td::make_unique(this, create_reference())); + download_manager_actor_ = register_actor("DownloadManager", download_manager_.get()); + G()->set_download_manager(download_manager_actor_.get()); + forum_topic_manager_ = make_unique(this, create_reference()); + forum_topic_manager_actor_ = register_actor("ForumTopicManager", forum_topic_manager_.get()); + G()->set_forum_topic_manager(forum_topic_manager_actor_.get()); + game_manager_ = make_unique(this, create_reference()); + game_manager_actor_ = register_actor("GameManager", game_manager_.get()); + G()->set_game_manager(game_manager_actor_.get()); + group_call_manager_ = make_unique(this, create_reference()); + group_call_manager_actor_ = register_actor("GroupCallManager", group_call_manager_.get()); + G()->set_group_call_manager(group_call_manager_actor_.get()); + inline_message_manager_ = make_unique(this, create_reference()); + inline_message_manager_actor_ = register_actor("InlineMessageManager", inline_message_manager_.get()); + G()->set_inline_message_manager(inline_message_manager_actor_.get()); + inline_queries_manager_ = make_unique(this, create_reference()); + inline_queries_manager_actor_ = register_actor("InlineQueriesManager", inline_queries_manager_.get()); + link_manager_ = make_unique(this, create_reference()); + link_manager_actor_ = register_actor("LinkManager", link_manager_.get()); + G()->set_link_manager(link_manager_actor_.get()); + message_import_manager_ = make_unique(this, create_reference()); + message_import_manager_actor_ = register_actor("MessageImportManager", message_import_manager_.get()); + G()->set_message_import_manager(message_import_manager_actor_.get()); + messages_manager_ = make_unique(this, create_reference()); + messages_manager_actor_ = register_actor("MessagesManager", messages_manager_.get()); + G()->set_messages_manager(messages_manager_actor_.get()); + notification_manager_ = make_unique(this, create_reference()); + notification_manager_actor_ = register_actor("NotificationManager", notification_manager_.get()); + G()->set_notification_manager(notification_manager_actor_.get()); + notification_settings_manager_ = make_unique(this, create_reference()); + notification_settings_manager_actor_ = + register_actor("NotificationSettingsManager", notification_settings_manager_.get()); + G()->set_notification_settings_manager(notification_settings_manager_actor_.get()); + people_nearby_manager_ = make_unique(this, create_reference()); + people_nearby_manager_actor_ = register_actor("PeopleNearbyManager", people_nearby_manager_.get()); + G()->set_people_nearby_manager(people_nearby_manager_actor_.get()); + phone_number_manager_ = make_unique(this, create_reference()); + phone_number_manager_actor_ = register_actor("PhoneNumberManager", phone_number_manager_.get()); + poll_manager_ = make_unique(this, create_reference()); + poll_manager_actor_ = register_actor("PollManager", poll_manager_.get()); + privacy_manager_ = make_unique(this, create_reference()); + privacy_manager_actor_ = register_actor("PrivacyManager", privacy_manager_.get()); + promo_data_manager_ = make_unique(this, create_reference()); + promo_data_manager_actor_ = register_actor("PromoDataManager", promo_data_manager_.get()); + G()->set_promo_data_manager(promo_data_manager_actor_.get()); + quick_reply_manager_ = make_unique(this, create_reference()); + quick_reply_manager_actor_ = register_actor("QuickReplyManager", quick_reply_manager_.get()); + G()->set_quick_reply_manager(quick_reply_manager_actor_.get()); + reaction_manager_ = make_unique(this, create_reference()); + reaction_manager_actor_ = register_actor("ReactionManager", reaction_manager_.get()); + G()->set_reaction_manager(reaction_manager_actor_.get()); + saved_messages_manager_ = make_unique(this, create_reference()); + saved_messages_manager_actor_ = register_actor("SavedMessagesManager", saved_messages_manager_.get()); + G()->set_saved_messages_manager(saved_messages_manager_actor_.get()); + sponsored_message_manager_ = make_unique(this, create_reference()); + sponsored_message_manager_actor_ = register_actor("SponsoredMessageManager", sponsored_message_manager_.get()); + G()->set_sponsored_message_manager(sponsored_message_manager_actor_.get()); + star_manager_ = make_unique(this, create_reference()); + star_manager_actor_ = register_actor("StarManager", star_manager_.get()); + G()->set_star_manager(star_manager_actor_.get()); + statistics_manager_ = make_unique(this, create_reference()); + statistics_manager_actor_ = register_actor("StatisticsManager", statistics_manager_.get()); + stickers_manager_ = make_unique(this, create_reference()); + stickers_manager_actor_ = register_actor("StickersManager", stickers_manager_.get()); + G()->set_stickers_manager(stickers_manager_actor_.get()); + story_manager_ = make_unique(this, create_reference()); + story_manager_actor_ = register_actor("StoryManager", story_manager_.get()); + G()->set_story_manager(story_manager_actor_.get()); + terms_of_service_manager_ = make_unique(this, create_reference()); + terms_of_service_manager_actor_ = register_actor("TermsOfServiceManager", terms_of_service_manager_.get()); + theme_manager_ = make_unique(this, create_reference()); + theme_manager_actor_ = register_actor("ThemeManager", theme_manager_.get()); + G()->set_theme_manager(theme_manager_actor_.get()); + time_zone_manager_ = make_unique(this, create_reference()); + time_zone_manager_actor_ = register_actor("TimeZoneManager", time_zone_manager_.get()); + G()->set_time_zone_manager(time_zone_manager_actor_.get()); + top_dialog_manager_ = make_unique(this, create_reference()); + top_dialog_manager_actor_ = register_actor("TopDialogManager", top_dialog_manager_.get()); + G()->set_top_dialog_manager(top_dialog_manager_actor_.get()); + transcription_manager_ = make_unique(this, create_reference()); + transcription_manager_actor_ = register_actor("TranscriptionManager", transcription_manager_.get()); + G()->set_transcription_manager(transcription_manager_actor_.get()); + translation_manager_ = make_unique(this, create_reference()); + translation_manager_actor_ = register_actor("TranslationManager", translation_manager_.get()); + updates_manager_ = make_unique(this, create_reference()); + updates_manager_actor_ = register_actor("UpdatesManager", updates_manager_.get()); + G()->set_updates_manager(updates_manager_actor_.get()); + user_manager_ = make_unique(this, create_reference()); + user_manager_actor_ = register_actor("UserManager", user_manager_.get()); + G()->set_user_manager(user_manager_actor_.get()); + video_notes_manager_ = make_unique(this, create_reference()); + video_notes_manager_actor_ = register_actor("VideoNotesManager", video_notes_manager_.get()); + voice_notes_manager_ = make_unique(this, create_reference()); + voice_notes_manager_actor_ = register_actor("VoiceNotesManager", voice_notes_manager_.get()); + web_pages_manager_ = make_unique(this, create_reference()); + web_pages_manager_actor_ = register_actor("WebPagesManager", web_pages_manager_.get()); + G()->set_web_pages_manager(web_pages_manager_actor_.get()); } -td_api::object_ptr Td::do_static_request(const td_api::getTextEntities &request) { - if (!check_utf8(request.text_)) { - return make_error(400, "Text must be encoded in UTF-8"); - } - auto text_entities = find_entities(request.text_, false, false); - return make_tl_object( - get_text_entities_object(text_entities, false, std::numeric_limits::max())); +void Td::init_pure_actor_managers() { + call_manager_ = create_actor("CallManager", create_reference()); + G()->set_call_manager(call_manager_.get()); + cashtag_search_hints_ = create_actor("CashtagSearchHints", "cashtag_search", '$', create_reference()); + device_token_manager_ = create_actor("DeviceTokenManager", create_reference()); + hashtag_hints_ = create_actor("HashtagHints", "text", '#', create_reference()); + hashtag_search_hints_ = create_actor("HashtagSearchHints", "search", '#', create_reference()); + language_pack_manager_ = create_actor("LanguagePackManager", create_reference()); + G()->set_language_pack_manager(language_pack_manager_.get()); + password_manager_ = create_actor("PasswordManager", create_reference()); + G()->set_password_manager(password_manager_.get()); + secure_manager_ = create_actor("SecureManager", create_reference()); } -td_api::object_ptr Td::do_static_request(td_api::parseTextEntities &request) { - if (!check_utf8(request.text_)) { - return make_error(400, "Text must be encoded in UTF-8"); - } - if (request.parse_mode_ == nullptr) { - return make_error(400, "Parse mode must be non-empty"); +void Td::send_update(tl_object_ptr &&object) { + CHECK(object != nullptr); + auto object_id = object->get_id(); + if (close_flag_ >= 5 && object_id != td_api::updateAuthorizationState::ID) { + // just in case + return; } - auto r_entities = [&]() -> Result> { - if (utf8_length(request.text_) > 65536) { - return Status::Error("Text is too long"); + switch (object_id) { + case td_api::updateAccentColors::ID: + case td_api::updateChatThemes::ID: + case td_api::updateFavoriteStickers::ID: + case td_api::updateInstalledStickerSets::ID: + case td_api::updateProfileAccentColors::ID: + case td_api::updateRecentStickers::ID: + case td_api::updateSavedAnimations::ID: + case td_api::updateSavedNotificationSounds::ID: + case td_api::updateUserStatus::ID: + VLOG(td_requests) << "Sending update: " << oneline(to_string(object)); + break; + case td_api::updateTrendingStickerSets::ID: { + auto update = static_cast(object.get()); + auto sticker_sets = update->sticker_sets_.get(); + VLOG(td_requests) << "Sending update: updateTrendingStickerSets { " << oneline(to_string(update->sticker_type_)) + << ", total_count = " << sticker_sets->total_count_ + << ", count = " << sticker_sets->sets_.size() << " }"; + break; } - switch (request.parse_mode_->get_id()) { - case td_api::textParseModeHTML::ID: - return parse_html(request.text_); - case td_api::textParseModeMarkdown::ID: { - auto version = static_cast(request.parse_mode_.get())->version_; - if (version == 0 || version == 1) { - return parse_markdown(request.text_); - } - if (version == 2) { - return parse_markdown_v2(request.text_); - } - return Status::Error("Wrong Markdown version specified"); + case td_api::updateOption::ID: + if (auth_manager_ == nullptr || !auth_manager_->is_bot()) { + VLOG(td_requests) << "Sending update: " << to_string(object); } - default: - UNREACHABLE(); - return Status::Error(500, "Unknown parse mode"); - } - }(); - if (r_entities.is_error()) { - return make_error(400, PSLICE() << "Can't parse entities: " << r_entities.error().message()); + break; + case td_api::updateDefaultReactionType::ID / 2: + LOG(ERROR) << "Sending update: " << oneline(to_string(object)); + break; + default: + VLOG(td_requests) << "Sending update: " << to_string(object); } - return make_tl_object(std::move(request.text_), - get_text_entities_object(r_entities.ok(), false, -1)); + callback_->on_result(0, std::move(object)); } -td_api::object_ptr Td::do_static_request(td_api::parseMarkdown &request) { - if (request.text_ == nullptr) { - return make_error(400, "Text must be non-empty"); - } - - auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_), true); - if (r_entities.is_error()) { - return make_error(400, r_entities.error().message()); - } - auto entities = r_entities.move_as_ok(); - auto status = fix_formatted_text(request.text_->text_, entities, true, true, true, true, true); - if (status.is_error()) { - return make_error(400, status.message()); +void Td::send_result(uint64 id, tl_object_ptr object) { + if (id == 0) { + LOG(ERROR) << "Sending " << to_string(object) << " through send_result"; + return; } - auto parsed_text = parse_markdown_v3({std::move(request.text_->text_), std::move(entities)}); - fix_formatted_text(parsed_text.text, parsed_text.entities, true, true, true, true, true).ensure(); - return get_formatted_text_object(parsed_text, false, std::numeric_limits::max()); -} - -td_api::object_ptr Td::do_static_request(const td_api::getOption &request) { - if (!is_synchronous_request(&request)) { - return make_error(400, "The option can't be get synchronously"); + auto it = request_set_.find(id); + if (it != request_set_.end()) { + if (object == nullptr) { + object = make_tl_object(404, "Not Found"); + } + VLOG(td_requests) << "Sending result for request " << id << ": " << to_string(object); + request_set_.erase(it); + callback_->on_result(id, std::move(object)); } - return OptionManager::get_option_synchronously(request.name_); } -td_api::object_ptr Td::do_static_request(td_api::getMarkdownText &request) { - if (request.text_ == nullptr) { - return make_error(400, "Text must be non-empty"); - } - - auto r_entities = get_message_entities(nullptr, std::move(request.text_->entities_)); - if (r_entities.is_error()) { - return make_error(400, r_entities.error().message()); - } - auto entities = r_entities.move_as_ok(); - auto status = fix_formatted_text(request.text_->text_, entities, true, true, true, true, true); - if (status.is_error()) { - return make_error(400, status.message()); +void Td::send_error_impl(uint64 id, tl_object_ptr error) { + CHECK(id != 0); + CHECK(error != nullptr); + auto it = request_set_.find(id); + if (it != request_set_.end()) { + if (error->code_ == 0 && error->message_ == "Lost promise") { + LOG(FATAL) << "Lost promise for query " << id << " of type " << it->second << " in close state " << close_flag_; + } + VLOG(td_requests) << "Sending error for request " << id << ": " << oneline(to_string(error)); + request_set_.erase(it); + callback_->on_error(id, std::move(error)); } - - return get_formatted_text_object(get_markdown_v3({std::move(request.text_->text_), std::move(entities)}), false, - std::numeric_limits::max()); -} - -td_api::object_ptr Td::do_static_request(const td_api::getFileMimeType &request) { - // don't check file name UTF-8 correctness - return make_tl_object(MimeType::from_extension(PathView(request.file_name_).extension())); -} - -td_api::object_ptr Td::do_static_request(const td_api::getFileExtension &request) { - // don't check MIME type UTF-8 correctness - return make_tl_object(MimeType::to_extension(request.mime_type_)); -} - -td_api::object_ptr Td::do_static_request(const td_api::cleanFileName &request) { - // don't check file name UTF-8 correctness - return make_tl_object(clean_filename(request.file_name_)); } -td_api::object_ptr Td::do_static_request(const td_api::getLanguagePackString &request) { - return LanguagePackManager::get_language_pack_string( - request.language_pack_database_path_, request.localization_target_, request.language_pack_id_, request.key_); -} - -td_api::object_ptr Td::do_static_request(td_api::getPhoneNumberInfoSync &request) { - // don't check language_code/phone number UTF-8 correctness - return CountryInfoManager::get_phone_number_info_sync(request.language_code_, - std::move(request.phone_number_prefix_)); -} - -td_api::object_ptr Td::do_static_request(const td_api::getPushReceiverId &request) { - // don't check push payload UTF-8 correctness - auto r_push_receiver_id = NotificationManager::get_push_receiver_id(request.payload_); - if (r_push_receiver_id.is_error()) { - VLOG(notifications) << "Failed to get push notification receiver from \"" << format::escaped(request.payload_) - << '"'; - return make_error(r_push_receiver_id.error().code(), r_push_receiver_id.error().message()); - } - return td_api::make_object(r_push_receiver_id.ok()); +void Td::send_error(uint64 id, Status error) { + send_error_impl(id, make_tl_object(error.code(), error.message().str())); + error.ignore(); } -td_api::object_ptr Td::do_static_request(const td_api::getChatFolderDefaultIconName &request) { - if (request.folder_ == nullptr) { - return make_error(400, "Chat folder must be non-empty"); - } - if (!check_utf8(request.folder_->title_)) { - return make_error(400, "Chat folder title must be encoded in UTF-8"); - } - if (request.folder_->icon_ != nullptr && !check_utf8(request.folder_->icon_->name_)) { - return make_error(400, "Chat folder icon name must be encoded in UTF-8"); +Result> Td::get_parameters( + td_api::object_ptr parameters) { + VLOG(td_init) << "Begin to set TDLib parameters"; + if (!clean_input_string(parameters->api_hash_) || !clean_input_string(parameters->system_language_code_) || + !clean_input_string(parameters->device_model_) || !clean_input_string(parameters->system_version_) || + !clean_input_string(parameters->application_version_)) { + VLOG(td_init) << "Wrong string encoding"; + return Status::Error(400, "Strings must be encoded in UTF-8"); } - return td_api::make_object(DialogFilter::get_default_icon_name(request.folder_.get())); -} -td_api::object_ptr Td::do_static_request(td_api::getJsonValue &request) { - if (!check_utf8(request.json_)) { - return make_error(400, "JSON has invalid encoding"); + if (parameters->api_id_ <= 0) { + return Status::Error(400, "Valid api_id must be provided. Can be obtained at https://my.telegram.org"); } - auto result = get_json_value(request.json_); - if (result.is_error()) { - return make_error(400, result.error().message()); - } else { - return result.move_as_ok(); + if (parameters->api_hash_.empty()) { + return Status::Error(400, "Valid api_hash must be provided. Can be obtained at https://my.telegram.org"); } -} - -td_api::object_ptr Td::do_static_request(const td_api::getJsonString &request) { - return td_api::make_object(get_json_string(request.json_value_.get())); -} - -td_api::object_ptr Td::do_static_request(const td_api::getThemeParametersJsonString &request) { - return td_api::make_object(ThemeManager::get_theme_parameters_json_string(request.theme_, true)); -} -td_api::object_ptr Td::do_static_request(td_api::setLogStream &request) { - auto result = Logging::set_current_stream(std::move(request.log_stream_)); - if (result.is_ok()) { - return td_api::make_object(); - } else { - return make_error(400, result.message()); - } -} + std::pair result; + result.first.api_id_ = parameters->api_id_; + result.first.api_hash_ = std::move(parameters->api_hash_); + result.first.use_secret_chats_ = parameters->use_secret_chats_; -td_api::object_ptr Td::do_static_request(const td_api::getLogStream &request) { - auto result = Logging::get_current_stream(); - if (result.is_ok()) { - return result.move_as_ok(); - } else { - return make_error(400, result.error().message()); - } -} + result.second.encryption_key_ = TdDb::as_db_key(std::move(parameters->database_encryption_key_)); + result.second.database_directory_ = std::move(parameters->database_directory_); + result.second.files_directory_ = std::move(parameters->files_directory_); + result.second.is_test_dc_ = parameters->use_test_dc_; + result.second.use_file_database_ = parameters->use_file_database_; + result.second.use_chat_info_database_ = parameters->use_chat_info_database_; + result.second.use_message_database_ = parameters->use_message_database_; -td_api::object_ptr Td::do_static_request(const td_api::setLogVerbosityLevel &request) { - auto result = Logging::set_verbosity_level(static_cast(request.new_verbosity_level_)); - if (result.is_ok()) { - return td_api::make_object(); - } else { - return make_error(400, result.message()); + VLOG(td_init) << "Create MtprotoHeader::Options"; + options_.api_id = parameters->api_id_; + options_.system_language_code = trim(parameters->system_language_code_); + options_.device_model = trim(parameters->device_model_); + options_.system_version = trim(parameters->system_version_); + options_.application_version = trim(parameters->application_version_); + if (options_.system_language_code.empty()) { + return Status::Error(400, "System language code must be non-empty"); } -} - -td_api::object_ptr Td::do_static_request(const td_api::getLogVerbosityLevel &request) { - return td_api::make_object(Logging::get_verbosity_level()); -} - -td_api::object_ptr Td::do_static_request(const td_api::getLogTags &request) { - return td_api::make_object(Logging::get_tags()); -} - -td_api::object_ptr Td::do_static_request(const td_api::setLogTagVerbosityLevel &request) { - auto result = Logging::set_tag_verbosity_level(request.tag_, static_cast(request.new_verbosity_level_)); - if (result.is_ok()) { - return td_api::make_object(); - } else { - return make_error(400, result.message()); + if (options_.device_model.empty()) { + return Status::Error(400, "Device model must be non-empty"); } -} - -td_api::object_ptr Td::do_static_request(const td_api::getLogTagVerbosityLevel &request) { - auto result = Logging::get_tag_verbosity_level(request.tag_); - if (result.is_ok()) { - return td_api::make_object(result.ok()); - } else { - return make_error(400, result.error().message()); + if (options_.system_version.empty()) { + options_.system_version = get_operating_system_version().str(); + VLOG(td_init) << "Set system version to " << options_.system_version; } -} - -td_api::object_ptr Td::do_static_request(const td_api::addLogMessage &request) { - Logging::add_message(request.verbosity_level_, request.text_); - return td_api::make_object(); -} - -td_api::object_ptr Td::do_static_request(td_api::testReturnError &request) { - if (request.error_ == nullptr) { - return td_api::make_object(404, "Not Found"); + if (options_.application_version.empty()) { + return Status::Error(400, "Application version must be non-empty"); } - - return std::move(request.error_); -} - -// test -void Td::on_request(uint64 id, const td_api::testNetwork &request) { - CREATE_OK_REQUEST_PROMISE(); - create_handler(std::move(promise))->send(); -} - -void Td::on_request(uint64 id, td_api::testProxy &request) { - auto r_proxy = Proxy::create_proxy(std::move(request.server_), request.port_, request.type_.get()); - if (r_proxy.is_error()) { - return send_closure(actor_id(this), &Td::send_error, id, r_proxy.move_as_error()); + if (options_.api_id != 21724) { + options_.application_version += ", TDLib "; + auto version = OptionManager::get_option_synchronously("version"); + CHECK(version->get_id() == td_api::optionValueString::ID); + options_.application_version += static_cast(version.get())->value_; } - CREATE_REQUEST(TestProxyRequest, r_proxy.move_as_ok(), request.dc_id_, request.timeout_); -} - -void Td::on_request(uint64 id, const td_api::testGetDifference &request) { - updates_manager_->get_difference("testGetDifference"); - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, const td_api::testUseUpdate &request) { - send_closure(actor_id(this), &Td::send_result, id, nullptr); -} - -void Td::on_request(uint64 id, const td_api::testReturnError &request) { - UNREACHABLE(); -} - -void Td::on_request(uint64 id, const td_api::testCallEmpty &request) { - send_closure(actor_id(this), &Td::send_result, id, make_tl_object()); -} - -void Td::on_request(uint64 id, const td_api::testSquareInt &request) { - send_closure(actor_id(this), &Td::send_result, id, make_tl_object(request.x_ * request.x_)); -} - -void Td::on_request(uint64 id, td_api::testCallString &request) { - send_closure(actor_id(this), &Td::send_result, id, make_tl_object(std::move(request.x_))); -} - -void Td::on_request(uint64 id, td_api::testCallBytes &request) { - send_closure(actor_id(this), &Td::send_result, id, make_tl_object(std::move(request.x_))); -} - -void Td::on_request(uint64 id, td_api::testCallVectorInt &request) { - send_closure(actor_id(this), &Td::send_result, id, make_tl_object(std::move(request.x_))); -} - -void Td::on_request(uint64 id, td_api::testCallVectorIntObject &request) { - send_closure(actor_id(this), &Td::send_result, id, - make_tl_object(std::move(request.x_))); -} + options_.language_pack = string(); + options_.language_code = string(); + options_.parameters = string(); + options_.is_emulator = false; + options_.proxy = Proxy(); -void Td::on_request(uint64 id, td_api::testCallVectorString &request) { - send_closure(actor_id(this), &Td::send_result, id, make_tl_object(std::move(request.x_))); + return std::move(result); } -void Td::on_request(uint64 id, td_api::testCallVectorStringObject &request) { - send_closure(actor_id(this), &Td::send_result, id, - make_tl_object(std::move(request.x_))); +void Td::on_file_download_finished(FileId file_id) { + requests_->on_file_download_finished(file_id); } -#undef CLEAN_INPUT_STRING -#undef CHECK_IS_BOT -#undef CHECK_IS_USER -#undef CREATE_NO_ARGS_REQUEST -#undef CREATE_REQUEST -#undef CREATE_REQUEST_PROMISE -#undef CREATE_OK_REQUEST_PROMISE - } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Td.h b/protocols/Telegram/tdlib/td/td/telegram/Td.h index e6ac45bd73..27374be2a0 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Td.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Td.h @@ -1,12 +1,11 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once -#include "td/telegram/ConnectionState.h" #include "td/telegram/files/FileId.h" #include "td/telegram/net/MtprotoHeader.h" #include "td/telegram/net/NetQuery.h" @@ -15,12 +14,8 @@ #include "td/telegram/TdCallback.h" #include "td/telegram/TdDb.h" #include "td/telegram/telegram_api.h" -#include "td/telegram/TermsOfService.h" - -#include "td/db/DbKey.h" #include "td/actor/actor.h" -#include "td/actor/MultiTimeout.h" #include "td/utils/buffer.h" #include "td/utils/common.h" @@ -37,20 +32,32 @@ namespace td { +class AccountManager; +class AlarmManager; class AnimationsManager; class AttachMenuManager; class AudiosManager; class AuthManager; class AutosaveManager; class BackgroundManager; +class BoostManager; class BotInfoManager; +class BusinessConnectionManager; +class BusinessManager; class CallManager; class CallbackQueriesManager; +class ChannelRecommendationManager; +class ChatManager; +class CommonDialogManager; class ConfigManager; -class ContactsManager; +class ConnectionStateManager; class CountryInfoManager; class DeviceTokenManager; +class DialogActionManager; class DialogFilterManager; +class DialogInviteLinkManager; +class DialogManager; +class DialogParticipantManager; class DocumentsManager; class DownloadManager; class FileManager; @@ -58,29 +65,45 @@ class FileReferenceManager; class ForumTopicManager; class GameManager; class GroupCallManager; +class InlineMessageManager; class InlineQueriesManager; class HashtagHints; class LanguagePackManager; class LinkManager; +class MessageImportManager; class MessagesManager; class NetStatsManager; class NotificationManager; class NotificationSettingsManager; +class OnlineManager; class OptionManager; class PasswordManager; +class PeopleNearbyManager; class PhoneNumberManager; class PollManager; class PrivacyManager; +class PromoDataManager; +class QuickReplyManager; +class ReactionManager; +class Requests; +class SavedMessagesManager; class SecureManager; class SecretChatsManager; class SponsoredMessageManager; +class StarManager; class StateManager; +class StatisticsManager; class StickersManager; class StorageManager; +class StoryManager; +class TermsOfServiceManager; class ThemeManager; +class TimeZoneManager; class TopDialogManager; +class TranscriptionManager; class TranslationManager; class UpdatesManager; +class UserManager; class VideoNotesManager; class VideosManager; class VoiceNotesManager; @@ -116,24 +139,10 @@ class Td final : public Actor { void destroy(); - void schedule_get_terms_of_service(int32 expires_in); - - void reload_promo_data(); - - void on_update(BufferSlice &&update, uint64 auth_key_id); + void on_update(telegram_api::object_ptr updates, uint64 auth_key_id); void on_result(NetQueryPtr query); - void on_online_updated(bool force, bool send_update); - - void on_update_status_success(bool is_online); - - bool is_online() const; - - void set_is_online(bool is_online); - - void set_is_bot_online(bool is_bot_online); - bool can_ignore_background_updates() const { return can_ignore_background_updates_; } @@ -146,6 +155,8 @@ class Td final : public Actor { unique_ptr option_manager_; unique_ptr videos_manager_; + unique_ptr account_manager_; + ActorOwn account_manager_actor_; unique_ptr animations_manager_; ActorOwn animations_manager_actor_; unique_ptr attach_menu_manager_; @@ -156,14 +167,34 @@ class Td final : public Actor { ActorOwn autosave_manager_actor_; unique_ptr background_manager_; ActorOwn background_manager_actor_; + unique_ptr boost_manager_; + ActorOwn boost_manager_actor_; unique_ptr bot_info_manager_; ActorOwn bot_info_manager_actor_; - unique_ptr contacts_manager_; - ActorOwn contacts_manager_actor_; + unique_ptr business_connection_manager_; + ActorOwn business_connection_manager_actor_; + unique_ptr business_manager_; + ActorOwn business_manager_actor_; + unique_ptr channel_recommendation_manager_; + ActorOwn channel_recommendation_manager_actor_; + unique_ptr chat_manager_; + ActorOwn chat_manager_actor_; + unique_ptr common_dialog_manager_; + ActorOwn common_dialog_manager_actor_; + unique_ptr connection_state_manager_; + ActorOwn connection_state_manager_actor_; unique_ptr country_info_manager_; ActorOwn country_info_manager_actor_; + unique_ptr dialog_action_manager_; + ActorOwn dialog_action_manager_actor_; unique_ptr dialog_filter_manager_; ActorOwn dialog_filter_manager_actor_; + unique_ptr dialog_invite_link_manager_; + ActorOwn dialog_invite_link_manager_actor_; + unique_ptr dialog_manager_; + ActorOwn dialog_manager_actor_; + unique_ptr dialog_participant_manager_; + ActorOwn dialog_participant_manager_actor_; unique_ptr download_manager_; ActorOwn download_manager_actor_; unique_ptr file_manager_; @@ -176,30 +207,64 @@ class Td final : public Actor { ActorOwn game_manager_actor_; unique_ptr group_call_manager_; ActorOwn group_call_manager_actor_; + unique_ptr inline_message_manager_; + ActorOwn inline_message_manager_actor_; unique_ptr inline_queries_manager_; ActorOwn inline_queries_manager_actor_; unique_ptr link_manager_; ActorOwn link_manager_actor_; + unique_ptr message_import_manager_; + ActorOwn message_import_manager_actor_; unique_ptr messages_manager_; ActorOwn messages_manager_actor_; unique_ptr notification_manager_; ActorOwn notification_manager_actor_; unique_ptr notification_settings_manager_; ActorOwn notification_settings_manager_actor_; + unique_ptr online_manager_; + ActorOwn online_manager_actor_; + unique_ptr people_nearby_manager_; + ActorOwn people_nearby_manager_actor_; + unique_ptr phone_number_manager_; + ActorOwn phone_number_manager_actor_; unique_ptr poll_manager_; ActorOwn poll_manager_actor_; + unique_ptr privacy_manager_; + ActorOwn privacy_manager_actor_; + unique_ptr promo_data_manager_; + ActorOwn promo_data_manager_actor_; + unique_ptr quick_reply_manager_; + ActorOwn quick_reply_manager_actor_; + unique_ptr reaction_manager_; + ActorOwn reaction_manager_actor_; + unique_ptr saved_messages_manager_; + ActorOwn saved_messages_manager_actor_; unique_ptr sponsored_message_manager_; ActorOwn sponsored_message_manager_actor_; + unique_ptr star_manager_; + ActorOwn star_manager_actor_; + unique_ptr statistics_manager_; + ActorOwn statistics_manager_actor_; unique_ptr stickers_manager_; ActorOwn stickers_manager_actor_; + unique_ptr story_manager_; + ActorOwn story_manager_actor_; + unique_ptr terms_of_service_manager_; + ActorOwn terms_of_service_manager_actor_; unique_ptr theme_manager_; ActorOwn theme_manager_actor_; + unique_ptr time_zone_manager_; + ActorOwn time_zone_manager_actor_; unique_ptr top_dialog_manager_; ActorOwn top_dialog_manager_actor_; + unique_ptr transcription_manager_; + ActorOwn transcription_manager_actor_; unique_ptr translation_manager_; ActorOwn translation_manager_actor_; unique_ptr updates_manager_; ActorOwn updates_manager_actor_; + unique_ptr user_manager_; + ActorOwn user_manager_actor_; unique_ptr video_notes_manager_; ActorOwn video_notes_manager_actor_; unique_ptr voice_notes_manager_; @@ -207,21 +272,20 @@ class Td final : public Actor { unique_ptr web_pages_manager_; ActorOwn web_pages_manager_actor_; + ActorOwn alarm_manager_; ActorOwn call_manager_; - ActorOwn change_phone_number_manager_; + ActorOwn cashtag_search_hints_; ActorOwn config_manager_; - ActorOwn confirm_phone_number_manager_; ActorOwn device_token_manager_; ActorOwn hashtag_hints_; + ActorOwn hashtag_search_hints_; ActorOwn language_pack_manager_; ActorOwn net_stats_manager_; ActorOwn password_manager_; - ActorOwn privacy_manager_; ActorOwn secret_chats_manager_; ActorOwn secure_manager_; ActorOwn state_manager_; ActorOwn storage_manager_; - ActorOwn verify_phone_number_manager_; class ResultHandler : public std::enable_shared_from_this { public: @@ -267,21 +331,13 @@ class Td final : public Actor { static td_api::object_ptr static_request(td_api::object_ptr function); private: - static constexpr int64 ONLINE_ALARM_ID = 0; - static constexpr int64 PING_SERVER_ALARM_ID = -1; - static constexpr int32 PING_SERVER_TIMEOUT = 300; - static constexpr int64 TERMS_OF_SERVICE_ALARM_ID = -2; - static constexpr int64 PROMO_DATA_ALARM_ID = -3; - - void on_connection_state_changed(ConnectionState new_state); - - void run_request(uint64 id, tl_object_ptr function); + void run_request(uint64 id, td_api::object_ptr function); void send_result(uint64 id, tl_object_ptr object); + void send_error(uint64 id, Status error); + void send_error_impl(uint64 id, tl_object_ptr error); - void send_error_raw(uint64 id, int32 code, CSlice error); - void answer_ok_query(uint64 id, Status status); ActorShared create_reference(); @@ -301,8 +357,7 @@ class Td final : public Actor { MtprotoHeader::Options options_; - ConnectionState connection_state_ = ConnectionState::Empty; - + unique_ptr requests_; std::unordered_multimap request_set_; int actor_refcnt_ = 0; int request_actor_refcnt_ = 0; @@ -319,29 +374,10 @@ class Td final : public Actor { bool can_ignore_background_updates_ = false; - bool reloading_promo_data_ = false; - bool need_reload_promo_data_ = false; - - bool is_online_ = false; - bool is_bot_online_ = false; - NetQueryRef update_status_query_; - - int64 alarm_id_ = 1; - FlatHashMap pending_alarms_; - MultiTimeout alarm_timeout_{"AlarmTimeout"}; - - TermsOfService pending_terms_of_service_; - - struct DownloadInfo { - int64 offset = -1; - int64 limit = -1; - vector request_ids; - }; - FlatHashMap pending_file_downloads_; - vector>> pending_preauthentication_requests_; vector>> pending_set_parameters_requests_; + vector>> pending_init_requests_; template @@ -351,19 +387,10 @@ class Td final : public Actor { vector> get_fake_current_state() const; - static void on_alarm_timeout_callback(void *td_ptr, int64 alarm_id); - void on_alarm_timeout(int64 alarm_id); - - td_api::object_ptr get_update_terms_of_service_object() const; - - void on_get_terms_of_service(Result> result, bool dummy); - - void on_get_promo_data(Result> r_promo_data, bool dummy); - template - friend class RequestActor; // uses send_result/send_error - friend class AuthManager; // uses send_result/send_error, TODO pass Promise<> - friend class PhoneNumberManager; // uses send_result/send_error, TODO pass Promise<> + friend class RequestActor; // uses send_result/send_error + friend class AuthManager; // uses send_result/send_error, TODO pass Promise<> + friend class Requests; void add_handler(uint64 id, std::shared_ptr handler); std::shared_ptr extract_handler(uint64 id); @@ -372,1299 +399,35 @@ class Td final : public Actor { void on_file_download_finished(FileId file_id); - class OnRequest; - - class DownloadFileCallback; - - std::shared_ptr download_file_callback_; - - class UploadFileCallback; - - std::shared_ptr upload_file_callback_; - std::shared_ptr old_context_; - void schedule_get_promo_data(int32 expires_in); - - static int *get_log_verbosity_level(Slice name); - - template - Promise create_request_promise(uint64 id) { - return PromiseCreator::lambda([id = id, actor_id = actor_id(this)](Result r_state) { - if (r_state.is_error()) { - send_closure(actor_id, &Td::send_error, id, r_state.move_as_error()); - } else { - send_closure(actor_id, &Td::send_result, id, r_state.move_as_ok()); - } - }); - } - - Promise create_ok_request_promise(uint64 id); - static bool is_authentication_request(int32 id); - static bool is_synchronous_request(const td_api::Function *function); - static bool is_preinitialization_request(int32 id); static bool is_preauthentication_request(int32 id); - template - void on_request(uint64 id, const T &) = delete; - - void on_request(uint64 id, const td_api::setTdlibParameters &request); - - void on_request(uint64 id, const td_api::getAuthorizationState &request); - - void on_request(uint64 id, td_api::setAuthenticationPhoneNumber &request); - - void on_request(uint64 id, td_api::sendAuthenticationFirebaseSms &request); - - void on_request(uint64 id, td_api::setAuthenticationEmailAddress &request); - - void on_request(uint64 id, const td_api::resendAuthenticationCode &request); - - void on_request(uint64 id, td_api::checkAuthenticationEmailCode &request); - - void on_request(uint64 id, td_api::checkAuthenticationCode &request); - - void on_request(uint64 id, td_api::registerUser &request); - - void on_request(uint64 id, td_api::requestQrCodeAuthentication &request); - - void on_request(uint64 id, const td_api::resetAuthenticationEmailAddress &request); - - void on_request(uint64 id, td_api::checkAuthenticationPassword &request); - - void on_request(uint64 id, const td_api::requestAuthenticationPasswordRecovery &request); - - void on_request(uint64 id, td_api::checkAuthenticationPasswordRecoveryCode &request); - - void on_request(uint64 id, td_api::recoverAuthenticationPassword &request); - - void on_request(uint64 id, const td_api::logOut &request); - - void on_request(uint64 id, const td_api::close &request); - - void on_request(uint64 id, const td_api::destroy &request); - - void on_request(uint64 id, td_api::checkAuthenticationBotToken &request); - - void on_request(uint64 id, td_api::confirmQrCodeAuthentication &request); - - void on_request(uint64 id, td_api::setDatabaseEncryptionKey &request); - - void on_request(uint64 id, const td_api::getCurrentState &request); - - void on_request(uint64 id, td_api::getPasswordState &request); - - void on_request(uint64 id, td_api::setPassword &request); - - void on_request(uint64 id, td_api::setLoginEmailAddress &request); - - void on_request(uint64 id, const td_api::resendLoginEmailAddressCode &request); - - void on_request(uint64 id, td_api::checkLoginEmailAddressCode &request); - - void on_request(uint64 id, td_api::getRecoveryEmailAddress &request); - - void on_request(uint64 id, td_api::setRecoveryEmailAddress &request); - - void on_request(uint64 id, td_api::checkRecoveryEmailAddressCode &request); - - void on_request(uint64 id, const td_api::resendRecoveryEmailAddressCode &request); - - void on_request(uint64 id, td_api::requestPasswordRecovery &request); - - void on_request(uint64 id, td_api::checkPasswordRecoveryCode &request); - - void on_request(uint64 id, td_api::recoverPassword &request); - - void on_request(uint64 id, const td_api::resetPassword &request); - - void on_request(uint64 id, const td_api::cancelPasswordReset &request); - - void on_request(uint64 id, td_api::getTemporaryPasswordState &request); - - void on_request(uint64 id, td_api::createTemporaryPassword &request); - - void on_request(uint64 id, td_api::processPushNotification &request); - - void on_request(uint64 id, td_api::registerDevice &request); - - void on_request(uint64 id, td_api::getUserPrivacySettingRules &request); - - void on_request(uint64 id, td_api::setUserPrivacySettingRules &request); - - void on_request(uint64 id, const td_api::getDefaultMessageAutoDeleteTime &request); - - void on_request(uint64 id, const td_api::setDefaultMessageAutoDeleteTime &request); - - void on_request(uint64 id, const td_api::getAccountTtl &request); - - void on_request(uint64 id, const td_api::setAccountTtl &request); - - void on_request(uint64 id, td_api::deleteAccount &request); - - void on_request(uint64 id, td_api::changePhoneNumber &request); - - void on_request(uint64 id, td_api::checkChangePhoneNumberCode &request); - - void on_request(uint64 id, td_api::resendChangePhoneNumberCode &request); - - void on_request(uint64 id, const td_api::getUserLink &request); - - void on_request(uint64 id, td_api::searchUserByToken &request); - - void on_request(uint64 id, const td_api::getActiveSessions &request); - - void on_request(uint64 id, const td_api::terminateSession &request); - - void on_request(uint64 id, const td_api::terminateAllOtherSessions &request); - - void on_request(uint64 id, const td_api::toggleSessionCanAcceptCalls &request); - - void on_request(uint64 id, const td_api::toggleSessionCanAcceptSecretChats &request); - - void on_request(uint64 id, const td_api::setInactiveSessionTtl &request); - - void on_request(uint64 id, const td_api::getConnectedWebsites &request); - - void on_request(uint64 id, const td_api::disconnectWebsite &request); - - void on_request(uint64 id, const td_api::disconnectAllWebsites &request); - - void on_request(uint64 id, const td_api::getMe &request); - - void on_request(uint64 id, const td_api::getUser &request); - - void on_request(uint64 id, const td_api::getUserFullInfo &request); - - void on_request(uint64 id, const td_api::getBasicGroup &request); - - void on_request(uint64 id, const td_api::getBasicGroupFullInfo &request); - - void on_request(uint64 id, const td_api::getSupergroup &request); - - void on_request(uint64 id, const td_api::getSupergroupFullInfo &request); - - void on_request(uint64 id, const td_api::getSecretChat &request); - - void on_request(uint64 id, const td_api::getChat &request); - - void on_request(uint64 id, const td_api::getMessage &request); - - void on_request(uint64 id, const td_api::getMessageLocally &request); - - void on_request(uint64 id, const td_api::getRepliedMessage &request); - - void on_request(uint64 id, const td_api::getChatPinnedMessage &request); - - void on_request(uint64 id, const td_api::getCallbackQueryMessage &request); - - void on_request(uint64 id, const td_api::getMessageThread &request); - - void on_request(uint64 id, const td_api::getMessageViewers &request); - - void on_request(uint64 id, const td_api::getMessages &request); - - void on_request(uint64 id, const td_api::getChatSponsoredMessages &request); - - void on_request(uint64 id, const td_api::getMessageLink &request); - - void on_request(uint64 id, const td_api::getMessageEmbeddingCode &request); - - void on_request(uint64 id, td_api::getMessageLinkInfo &request); - - void on_request(uint64 id, td_api::translateText &request); - - void on_request(uint64 id, td_api::translateMessageText &request); - - void on_request(uint64 id, const td_api::recognizeSpeech &request); - - void on_request(uint64 id, const td_api::rateSpeechRecognition &request); - - void on_request(uint64 id, const td_api::getFile &request); - - void on_request(uint64 id, td_api::getRemoteFile &request); - - void on_request(uint64 id, td_api::getStorageStatistics &request); - - void on_request(uint64 id, td_api::getStorageStatisticsFast &request); - - void on_request(uint64 id, td_api::getDatabaseStatistics &request); - - void on_request(uint64 id, td_api::optimizeStorage &request); - - void on_request(uint64 id, td_api::getNetworkStatistics &request); - - void on_request(uint64 id, td_api::resetNetworkStatistics &request); - - void on_request(uint64 id, td_api::addNetworkStatistics &request); - - void on_request(uint64 id, const td_api::setNetworkType &request); - - void on_request(uint64 id, const td_api::getAutoDownloadSettingsPresets &request); - - void on_request(uint64 id, const td_api::setAutoDownloadSettings &request); - - void on_request(uint64 id, const td_api::getAutosaveSettings &request); - - void on_request(uint64 id, td_api::setAutosaveSettings &request); - - void on_request(uint64 id, const td_api::clearAutosaveSettingsExceptions &request); - - void on_request(uint64 id, const td_api::getTopChats &request); - - void on_request(uint64 id, const td_api::removeTopChat &request); - - void on_request(uint64 id, const td_api::loadChats &request); - - void on_request(uint64 id, const td_api::getChats &request); - - void on_request(uint64 id, td_api::searchPublicChat &request); - - void on_request(uint64 id, td_api::searchPublicChats &request); - - void on_request(uint64 id, td_api::searchChats &request); - - void on_request(uint64 id, td_api::searchChatsOnServer &request); - - void on_request(uint64 id, const td_api::searchChatsNearby &request); - - void on_request(uint64 id, const td_api::addRecentlyFoundChat &request); - - void on_request(uint64 id, const td_api::removeRecentlyFoundChat &request); - - void on_request(uint64 id, const td_api::clearRecentlyFoundChats &request); - - void on_request(uint64 id, const td_api::getRecentlyOpenedChats &request); - - void on_request(uint64 id, const td_api::getGroupsInCommon &request); - - void on_request(uint64 id, td_api::checkChatUsername &request); - - void on_request(uint64 id, const td_api::getCreatedPublicChats &request); - - void on_request(uint64 id, const td_api::checkCreatedPublicChatsLimit &request); - - void on_request(uint64 id, const td_api::getSuitableDiscussionChats &request); - - void on_request(uint64 id, const td_api::getInactiveSupergroupChats &request); - - void on_request(uint64 id, const td_api::openChat &request); - - void on_request(uint64 id, const td_api::closeChat &request); - - void on_request(uint64 id, const td_api::viewMessages &request); - - void on_request(uint64 id, const td_api::openMessageContent &request); - - void on_request(uint64 id, const td_api::clickAnimatedEmojiMessage &request); - - void on_request(uint64 id, const td_api::getInternalLink &request); - - void on_request(uint64 id, const td_api::getInternalLinkType &request); - - void on_request(uint64 id, td_api::getExternalLinkInfo &request); - - void on_request(uint64 id, td_api::getExternalLink &request); - - void on_request(uint64 id, const td_api::getChatHistory &request); - - void on_request(uint64 id, const td_api::deleteChatHistory &request); - - void on_request(uint64 id, const td_api::deleteChat &request); - - void on_request(uint64 id, const td_api::getMessageThreadHistory &request); - - void on_request(uint64 id, td_api::getChatMessageCalendar &request); - - void on_request(uint64 id, td_api::searchChatMessages &request); - - void on_request(uint64 id, td_api::searchSecretMessages &request); - - void on_request(uint64 id, td_api::searchMessages &request); - - void on_request(uint64 id, const td_api::searchCallMessages &request); - - void on_request(uint64 id, td_api::searchOutgoingDocumentMessages &request); - - void on_request(uint64 id, const td_api::deleteAllCallMessages &request); - - void on_request(uint64 id, const td_api::searchChatRecentLocationMessages &request); - - void on_request(uint64 id, const td_api::getActiveLiveLocationMessages &request); - - void on_request(uint64 id, const td_api::getChatMessageByDate &request); - - void on_request(uint64 id, const td_api::getChatSparseMessagePositions &request); - - void on_request(uint64 id, const td_api::getChatMessageCount &request); - - void on_request(uint64 id, const td_api::getChatMessagePosition &request); - - void on_request(uint64 id, const td_api::getChatScheduledMessages &request); - - void on_request(uint64 id, const td_api::getEmojiReaction &request); - - void on_request(uint64 id, const td_api::getCustomEmojiReactionAnimations &request); - - void on_request(uint64 id, const td_api::getMessageAvailableReactions &request); - - void on_request(uint64 id, const td_api::clearRecentReactions &request); - - void on_request(uint64 id, td_api::addMessageReaction &request); - - void on_request(uint64 id, td_api::removeMessageReaction &request); - - void on_request(uint64 id, td_api::getMessageAddedReactions &request); - - void on_request(uint64 id, td_api::setDefaultReactionType &request); - - void on_request(uint64 id, td_api::getMessagePublicForwards &request); - - void on_request(uint64 id, const td_api::removeNotification &request); - - void on_request(uint64 id, const td_api::removeNotificationGroup &request); - - void on_request(uint64 id, const td_api::deleteMessages &request); - - void on_request(uint64 id, const td_api::deleteChatMessagesBySender &request); - - void on_request(uint64 id, const td_api::deleteChatMessagesByDate &request); - - void on_request(uint64 id, const td_api::readAllChatMentions &request); - - void on_request(uint64 id, const td_api::readAllMessageThreadMentions &request); - - void on_request(uint64 id, const td_api::readAllChatReactions &request); - - void on_request(uint64 id, const td_api::readAllMessageThreadReactions &request); - - void on_request(uint64 id, const td_api::getChatAvailableMessageSenders &request); - - void on_request(uint64 id, const td_api::setChatMessageSender &request); - - void on_request(uint64 id, td_api::sendMessage &request); - - void on_request(uint64 id, td_api::sendMessageAlbum &request); - - void on_request(uint64 id, td_api::sendBotStartMessage &request); - - void on_request(uint64 id, td_api::sendInlineQueryResultMessage &request); - - void on_request(uint64 id, td_api::addLocalMessage &request); - - void on_request(uint64 id, td_api::editMessageText &request); - - void on_request(uint64 id, td_api::editMessageLiveLocation &request); - - void on_request(uint64 id, td_api::editMessageMedia &request); - - void on_request(uint64 id, td_api::editMessageCaption &request); - - void on_request(uint64 id, td_api::editMessageReplyMarkup &request); - - void on_request(uint64 id, td_api::editInlineMessageText &request); - - void on_request(uint64 id, td_api::editInlineMessageLiveLocation &request); - - void on_request(uint64 id, td_api::editInlineMessageMedia &request); - - void on_request(uint64 id, td_api::editInlineMessageCaption &request); - - void on_request(uint64 id, td_api::editInlineMessageReplyMarkup &request); - - void on_request(uint64 id, td_api::editMessageSchedulingState &request); - - void on_request(uint64 id, const td_api::getForumTopicDefaultIcons &request); - - void on_request(uint64 id, td_api::createForumTopic &request); - - void on_request(uint64 id, td_api::editForumTopic &request); - - void on_request(uint64 id, const td_api::getForumTopic &request); - - void on_request(uint64 id, const td_api::getForumTopicLink &request); - - void on_request(uint64 id, td_api::getForumTopics &request); - - void on_request(uint64 id, const td_api::toggleForumTopicIsClosed &request); - - void on_request(uint64 id, const td_api::toggleGeneralForumTopicIsHidden &request); - - void on_request(uint64 id, const td_api::toggleForumTopicIsPinned &request); - - void on_request(uint64 id, const td_api::setPinnedForumTopics &request); - - void on_request(uint64 id, const td_api::deleteForumTopic &request); - - void on_request(uint64 id, td_api::setGameScore &request); - - void on_request(uint64 id, td_api::setInlineGameScore &request); - - void on_request(uint64 id, td_api::getGameHighScores &request); - - void on_request(uint64 id, td_api::getInlineGameHighScores &request); - - void on_request(uint64 id, const td_api::deleteChatReplyMarkup &request); - - void on_request(uint64 id, td_api::sendChatAction &request); - - void on_request(uint64 id, td_api::sendChatScreenshotTakenNotification &request); - - void on_request(uint64 id, td_api::forwardMessages &request); - - void on_request(uint64 id, const td_api::resendMessages &request); - - void on_request(uint64 id, td_api::getWebPagePreview &request); - - void on_request(uint64 id, td_api::getWebPageInstantView &request); - - void on_request(uint64 id, const td_api::createPrivateChat &request); - - void on_request(uint64 id, const td_api::createBasicGroupChat &request); - - void on_request(uint64 id, const td_api::createSupergroupChat &request); - - void on_request(uint64 id, td_api::createSecretChat &request); + struct Parameters { + int32 api_id_ = 0; + string api_hash_; + bool use_secret_chats_ = false; + }; - void on_request(uint64 id, td_api::createNewBasicGroupChat &request); + void finish_set_parameters(); - void on_request(uint64 id, td_api::createNewSupergroupChat &request); + void init(Parameters parameters, Result r_opened_database); - void on_request(uint64 id, td_api::createNewSecretChat &request); + void init_options_and_network(); - void on_request(uint64 id, const td_api::createCall &request); + void init_file_manager(); - void on_request(uint64 id, const td_api::acceptCall &request); + void init_non_actor_managers(); - void on_request(uint64 id, td_api::sendCallSignalingData &request); + void init_managers(); - void on_request(uint64 id, const td_api::discardCall &request); + void init_pure_actor_managers(); - void on_request(uint64 id, td_api::sendCallRating &request); - - void on_request(uint64 id, td_api::sendCallDebugInformation &request); - - void on_request(uint64 id, td_api::sendCallLog &request); - - void on_request(uint64 id, const td_api::getVideoChatAvailableParticipants &request); - - void on_request(uint64 id, const td_api::setVideoChatDefaultParticipant &request); - - void on_request(uint64 id, td_api::createVideoChat &request); - - void on_request(uint64 id, const td_api::getVideoChatRtmpUrl &request); - - void on_request(uint64 id, const td_api::replaceVideoChatRtmpUrl &request); - - void on_request(uint64 id, const td_api::getGroupCall &request); - - void on_request(uint64 id, const td_api::startScheduledGroupCall &request); - - void on_request(uint64 id, const td_api::toggleGroupCallEnabledStartNotification &request); - - void on_request(uint64 id, td_api::joinGroupCall &request); - - void on_request(uint64 id, td_api::startGroupCallScreenSharing &request); - - void on_request(uint64 id, const td_api::endGroupCallScreenSharing &request); - - void on_request(uint64 id, td_api::setGroupCallTitle &request); - - void on_request(uint64 id, const td_api::toggleGroupCallMuteNewParticipants &request); - - void on_request(uint64 id, const td_api::revokeGroupCallInviteLink &request); - - void on_request(uint64 id, const td_api::inviteGroupCallParticipants &request); - - void on_request(uint64 id, const td_api::getGroupCallInviteLink &request); - - void on_request(uint64 id, td_api::startGroupCallRecording &request); - - void on_request(uint64 id, const td_api::toggleGroupCallScreenSharingIsPaused &request); - - void on_request(uint64 id, const td_api::endGroupCallRecording &request); - - void on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoPaused &request); - - void on_request(uint64 id, const td_api::toggleGroupCallIsMyVideoEnabled &request); - - void on_request(uint64 id, const td_api::setGroupCallParticipantIsSpeaking &request); - - void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsMuted &request); - - void on_request(uint64 id, const td_api::setGroupCallParticipantVolumeLevel &request); - - void on_request(uint64 id, const td_api::toggleGroupCallParticipantIsHandRaised &request); - - void on_request(uint64 id, const td_api::loadGroupCallParticipants &request); - - void on_request(uint64 id, const td_api::leaveGroupCall &request); - - void on_request(uint64 id, const td_api::endGroupCall &request); - - void on_request(uint64 id, const td_api::getGroupCallStreams &request); - - void on_request(uint64 id, td_api::getGroupCallStreamSegment &request); - - void on_request(uint64 id, const td_api::upgradeBasicGroupChatToSupergroupChat &request); - - void on_request(uint64 id, const td_api::getChatListsToAddChat &request); - - void on_request(uint64 id, const td_api::addChatToList &request); - - void on_request(uint64 id, const td_api::getChatFolder &request); - - void on_request(uint64 id, const td_api::getRecommendedChatFolders &request); - - void on_request(uint64 id, td_api::createChatFolder &request); - - void on_request(uint64 id, td_api::editChatFolder &request); - - void on_request(uint64 id, const td_api::deleteChatFolder &request); - - void on_request(uint64 id, const td_api::getChatFolderChatsToLeave &request); - - void on_request(uint64 id, const td_api::reorderChatFolders &request); - - void on_request(uint64 id, const td_api::getChatsForChatFolderInviteLink &request); - - void on_request(uint64 id, td_api::createChatFolderInviteLink &request); - - void on_request(uint64 id, td_api::getChatFolderInviteLinks &request); - - void on_request(uint64 id, td_api::editChatFolderInviteLink &request); - - void on_request(uint64 id, td_api::deleteChatFolderInviteLink &request); - - void on_request(uint64 id, td_api::checkChatFolderInviteLink &request); - - void on_request(uint64 id, td_api::addChatFolderByInviteLink &request); - - void on_request(uint64 id, const td_api::getChatFolderNewChats &request); - - void on_request(uint64 id, const td_api::processChatFolderNewChats &request); - - void on_request(uint64 id, td_api::setChatTitle &request); - - void on_request(uint64 id, const td_api::setChatPhoto &request); - - void on_request(uint64 id, const td_api::setChatMessageAutoDeleteTime &request); - - void on_request(uint64 id, const td_api::setChatPermissions &request); - - void on_request(uint64 id, td_api::setChatBackground &request); - - void on_request(uint64 id, td_api::setChatTheme &request); - - void on_request(uint64 id, td_api::setChatDraftMessage &request); - - void on_request(uint64 id, const td_api::toggleChatHasProtectedContent &request); - - void on_request(uint64 id, const td_api::toggleChatIsPinned &request); - - void on_request(uint64 id, const td_api::toggleChatIsTranslatable &request); - - void on_request(uint64 id, const td_api::toggleChatIsMarkedAsUnread &request); - - void on_request(uint64 id, const td_api::toggleMessageSenderIsBlocked &request); - - void on_request(uint64 id, const td_api::toggleChatDefaultDisableNotification &request); - - void on_request(uint64 id, const td_api::setPinnedChats &request); - - void on_request(uint64 id, const td_api::readChatList &request); - - void on_request(uint64 id, const td_api::getAttachmentMenuBot &request); - - void on_request(uint64 id, const td_api::toggleBotIsAddedToAttachmentMenu &request); - - void on_request(uint64 id, td_api::setChatAvailableReactions &request); - - void on_request(uint64 id, td_api::setChatClientData &request); - - void on_request(uint64 id, td_api::setChatDescription &request); - - void on_request(uint64 id, const td_api::setChatDiscussionGroup &request); - - void on_request(uint64 id, td_api::setChatLocation &request); - - void on_request(uint64 id, const td_api::setChatSlowModeDelay &request); - - void on_request(uint64 id, const td_api::pinChatMessage &request); - - void on_request(uint64 id, const td_api::unpinChatMessage &request); - - void on_request(uint64 id, const td_api::unpinAllChatMessages &request); - - void on_request(uint64 id, const td_api::unpinAllMessageThreadMessages &request); - - void on_request(uint64 id, const td_api::joinChat &request); - - void on_request(uint64 id, const td_api::leaveChat &request); - - void on_request(uint64 id, const td_api::addChatMember &request); - - void on_request(uint64 id, const td_api::addChatMembers &request); - - void on_request(uint64 id, td_api::setChatMemberStatus &request); - - void on_request(uint64 id, const td_api::banChatMember &request); - - void on_request(uint64 id, const td_api::canTransferOwnership &request); - - void on_request(uint64 id, td_api::transferChatOwnership &request); - - void on_request(uint64 id, const td_api::getChatMember &request); - - void on_request(uint64 id, td_api::searchChatMembers &request); - - void on_request(uint64 id, const td_api::getChatAdministrators &request); - - void on_request(uint64 id, const td_api::replacePrimaryChatInviteLink &request); - - void on_request(uint64 id, td_api::createChatInviteLink &request); - - void on_request(uint64 id, td_api::editChatInviteLink &request); - - void on_request(uint64 id, td_api::getChatInviteLink &request); - - void on_request(uint64 id, const td_api::getChatInviteLinkCounts &request); - - void on_request(uint64 id, td_api::getChatInviteLinks &request); - - void on_request(uint64 id, td_api::getChatInviteLinkMembers &request); - - void on_request(uint64 id, td_api::getChatJoinRequests &request); - - void on_request(uint64 id, const td_api::processChatJoinRequest &request); - - void on_request(uint64 id, td_api::processChatJoinRequests &request); - - void on_request(uint64 id, td_api::revokeChatInviteLink &request); - - void on_request(uint64 id, td_api::deleteRevokedChatInviteLink &request); - - void on_request(uint64 id, const td_api::deleteAllRevokedChatInviteLinks &request); - - void on_request(uint64 id, td_api::checkChatInviteLink &request); - - void on_request(uint64 id, td_api::joinChatByInviteLink &request); - - void on_request(uint64 id, td_api::getChatEventLog &request); - - void on_request(uint64 id, const td_api::clearAllDraftMessages &request); - - void on_request(uint64 id, const td_api::downloadFile &request); - - void on_request(uint64 id, const td_api::getFileDownloadedPrefixSize &request); - - void on_request(uint64 id, const td_api::cancelDownloadFile &request); - - void on_request(uint64 id, const td_api::getSuggestedFileName &request); - - void on_request(uint64 id, td_api::preliminaryUploadFile &request); - - void on_request(uint64 id, const td_api::cancelPreliminaryUploadFile &request); - - void on_request(uint64 id, td_api::writeGeneratedFilePart &request); - - void on_request(uint64 id, const td_api::setFileGenerationProgress &request); - - void on_request(uint64 id, td_api::finishFileGeneration &request); - - void on_request(uint64 id, const td_api::readFilePart &request); - - void on_request(uint64 id, const td_api::deleteFile &request); - - void on_request(uint64 id, const td_api::addFileToDownloads &request); - - void on_request(uint64 id, const td_api::toggleDownloadIsPaused &request); - - void on_request(uint64 id, const td_api::toggleAllDownloadsArePaused &request); - - void on_request(uint64 id, const td_api::removeFileFromDownloads &request); - - void on_request(uint64 id, const td_api::removeAllFilesFromDownloads &request); - - void on_request(uint64 id, td_api::searchFileDownloads &request); - - void on_request(uint64 id, td_api::getMessageFileType &request); - - void on_request(uint64 id, const td_api::getMessageImportConfirmationText &request); - - void on_request(uint64 id, const td_api::importMessages &request); - - void on_request(uint64 id, const td_api::blockMessageSenderFromReplies &request); - - void on_request(uint64 id, const td_api::getBlockedMessageSenders &request); - - void on_request(uint64 id, td_api::addContact &request); - - void on_request(uint64 id, td_api::importContacts &request); - - void on_request(uint64 id, const td_api::getContacts &request); - - void on_request(uint64 id, td_api::searchContacts &request); - - void on_request(uint64 id, td_api::removeContacts &request); - - void on_request(uint64 id, const td_api::getImportedContactCount &request); - - void on_request(uint64 id, td_api::changeImportedContacts &request); - - void on_request(uint64 id, const td_api::clearImportedContacts &request); - - void on_request(uint64 id, td_api::setUserPersonalProfilePhoto &request); - - void on_request(uint64 id, td_api::suggestUserProfilePhoto &request); - - void on_request(uint64 id, td_api::searchUserByPhoneNumber &request); - - void on_request(uint64 id, const td_api::sharePhoneNumber &request); - - void on_request(uint64 id, const td_api::getRecentInlineBots &request); - - void on_request(uint64 id, td_api::setName &request); - - void on_request(uint64 id, td_api::setBio &request); - - void on_request(uint64 id, td_api::setUsername &request); - - void on_request(uint64 id, td_api::toggleUsernameIsActive &request); - - void on_request(uint64 id, td_api::reorderActiveUsernames &request); - - void on_request(uint64 id, const td_api::setEmojiStatus &request); - - void on_request(uint64 id, const td_api::getThemedEmojiStatuses &request); - - void on_request(uint64 id, const td_api::getDefaultEmojiStatuses &request); - - void on_request(uint64 id, const td_api::getRecentEmojiStatuses &request); - - void on_request(uint64 id, const td_api::clearRecentEmojiStatuses &request); - - void on_request(uint64 id, td_api::setCommands &request); - - void on_request(uint64 id, td_api::deleteCommands &request); - - void on_request(uint64 id, td_api::getCommands &request); - - void on_request(uint64 id, td_api::setMenuButton &request); - - void on_request(uint64 id, const td_api::getMenuButton &request); - - void on_request(uint64 id, const td_api::setDefaultGroupAdministratorRights &request); - - void on_request(uint64 id, const td_api::setDefaultChannelAdministratorRights &request); - - void on_request(uint64 id, td_api::setBotName &request); - - void on_request(uint64 id, const td_api::getBotName &request); - - void on_request(uint64 id, td_api::setBotProfilePhoto &request); - - void on_request(uint64 id, td_api::toggleBotUsernameIsActive &request); - - void on_request(uint64 id, td_api::reorderActiveBotUsernames &request); - - void on_request(uint64 id, td_api::setBotInfoDescription &request); - - void on_request(uint64 id, const td_api::getBotInfoDescription &request); - - void on_request(uint64 id, td_api::setBotInfoShortDescription &request); - - void on_request(uint64 id, const td_api::getBotInfoShortDescription &request); - - void on_request(uint64 id, const td_api::setLocation &request); - - void on_request(uint64 id, td_api::setProfilePhoto &request); - - void on_request(uint64 id, const td_api::deleteProfilePhoto &request); - - void on_request(uint64 id, const td_api::getUserProfilePhotos &request); - - void on_request(uint64 id, td_api::setSupergroupUsername &request); - - void on_request(uint64 id, td_api::toggleSupergroupUsernameIsActive &request); - - void on_request(uint64 id, const td_api::disableAllSupergroupUsernames &request); - - void on_request(uint64 id, td_api::reorderSupergroupActiveUsernames &request); - - void on_request(uint64 id, const td_api::setSupergroupStickerSet &request); - - void on_request(uint64 id, const td_api::toggleSupergroupSignMessages &request); - - void on_request(uint64 id, const td_api::toggleSupergroupJoinToSendMessages &request); - - void on_request(uint64 id, const td_api::toggleSupergroupJoinByRequest &request); - - void on_request(uint64 id, const td_api::toggleSupergroupIsAllHistoryAvailable &request); - - void on_request(uint64 id, const td_api::toggleSupergroupHasHiddenMembers &request); - - void on_request(uint64 id, const td_api::toggleSupergroupHasAggressiveAntiSpamEnabled &request); - - void on_request(uint64 id, const td_api::toggleSupergroupIsForum &request); - - void on_request(uint64 id, const td_api::toggleSupergroupIsBroadcastGroup &request); - - void on_request(uint64 id, const td_api::reportSupergroupSpam &request); - - void on_request(uint64 id, const td_api::reportSupergroupAntiSpamFalsePositive &request); - - void on_request(uint64 id, td_api::getSupergroupMembers &request); - - void on_request(uint64 id, td_api::closeSecretChat &request); - - void on_request(uint64 id, td_api::getStickers &request); - - void on_request(uint64 id, td_api::searchStickers &request); - - void on_request(uint64 id, const td_api::getPremiumStickers &request); - - void on_request(uint64 id, const td_api::getInstalledStickerSets &request); - - void on_request(uint64 id, const td_api::getArchivedStickerSets &request); - - void on_request(uint64 id, const td_api::getTrendingStickerSets &request); - - void on_request(uint64 id, const td_api::getAttachedStickerSets &request); - - void on_request(uint64 id, const td_api::getStickerSet &request); - - void on_request(uint64 id, td_api::searchStickerSet &request); - - void on_request(uint64 id, td_api::searchInstalledStickerSets &request); - - void on_request(uint64 id, td_api::searchStickerSets &request); - - void on_request(uint64 id, const td_api::changeStickerSet &request); - - void on_request(uint64 id, const td_api::viewTrendingStickerSets &request); - - void on_request(uint64 id, td_api::reorderInstalledStickerSets &request); - - void on_request(uint64 id, td_api::uploadStickerFile &request); - - void on_request(uint64 id, td_api::getSuggestedStickerSetName &request); - - void on_request(uint64 id, td_api::checkStickerSetName &request); - - void on_request(uint64 id, td_api::createNewStickerSet &request); - - void on_request(uint64 id, td_api::addStickerToSet &request); - - void on_request(uint64 id, td_api::setStickerSetThumbnail &request); - - void on_request(uint64 id, td_api::setCustomEmojiStickerSetThumbnail &request); - - void on_request(uint64 id, td_api::setStickerSetTitle &request); - - void on_request(uint64 id, td_api::deleteStickerSet &request); - - void on_request(uint64 id, td_api::setStickerPositionInSet &request); - - void on_request(uint64 id, const td_api::removeStickerFromSet &request); - - void on_request(uint64 id, td_api::setStickerEmojis &request); - - void on_request(uint64 id, td_api::setStickerKeywords &request); - - void on_request(uint64 id, td_api::setStickerMaskPosition &request); - - void on_request(uint64 id, const td_api::getRecentStickers &request); - - void on_request(uint64 id, td_api::addRecentSticker &request); - - void on_request(uint64 id, td_api::removeRecentSticker &request); - - void on_request(uint64 id, td_api::clearRecentStickers &request); - - void on_request(uint64 id, const td_api::getSavedAnimations &request); - - void on_request(uint64 id, td_api::addSavedAnimation &request); - - void on_request(uint64 id, td_api::removeSavedAnimation &request); - - void on_request(uint64 id, td_api::getStickerEmojis &request); - - void on_request(uint64 id, td_api::searchEmojis &request); - - void on_request(uint64 id, const td_api::getEmojiCategories &request); - - void on_request(uint64 id, td_api::getAnimatedEmoji &request); - - void on_request(uint64 id, td_api::getEmojiSuggestionsUrl &request); - - void on_request(uint64 id, const td_api::getCustomEmojiStickers &request); - - void on_request(uint64 id, const td_api::getDefaultChatPhotoCustomEmojiStickers &request); - - void on_request(uint64 id, const td_api::getDefaultProfilePhotoCustomEmojiStickers &request); - - void on_request(uint64 id, const td_api::getFavoriteStickers &request); - - void on_request(uint64 id, td_api::addFavoriteSticker &request); - - void on_request(uint64 id, td_api::removeFavoriteSticker &request); - - void on_request(uint64 id, const td_api::getSavedNotificationSound &request); - - void on_request(uint64 id, const td_api::getSavedNotificationSounds &request); - - void on_request(uint64 id, td_api::addSavedNotificationSound &request); - - void on_request(uint64 id, const td_api::removeSavedNotificationSound &request); - - void on_request(uint64 id, const td_api::getChatNotificationSettingsExceptions &request); - - void on_request(uint64 id, const td_api::getScopeNotificationSettings &request); - - void on_request(uint64 id, td_api::setChatNotificationSettings &request); - - void on_request(uint64 id, td_api::setForumTopicNotificationSettings &request); - - void on_request(uint64 id, td_api::setScopeNotificationSettings &request); - - void on_request(uint64 id, const td_api::resetAllNotificationSettings &request); - - void on_request(uint64 id, const td_api::removeChatActionBar &request); - - void on_request(uint64 id, td_api::reportChat &request); - - void on_request(uint64 id, td_api::reportChatPhoto &request); - - void on_request(uint64 id, const td_api::reportMessageReactions &request); - - void on_request(uint64 id, const td_api::getChatStatistics &request); - - void on_request(uint64 id, const td_api::getMessageStatistics &request); - - void on_request(uint64 id, td_api::getStatisticalGraph &request); - - void on_request(uint64 id, const td_api::getMapThumbnailFile &request); - - void on_request(uint64 id, const td_api::getLocalizationTargetInfo &request); - - void on_request(uint64 id, td_api::getLanguagePackInfo &request); - - void on_request(uint64 id, td_api::getLanguagePackStrings &request); - - void on_request(uint64 id, td_api::synchronizeLanguagePack &request); - - void on_request(uint64 id, td_api::addCustomServerLanguagePack &request); - - void on_request(uint64 id, td_api::setCustomLanguagePack &request); - - void on_request(uint64 id, td_api::editCustomLanguagePackInfo &request); - - void on_request(uint64 id, td_api::setCustomLanguagePackString &request); - - void on_request(uint64 id, td_api::deleteLanguagePack &request); - - void on_request(uint64 id, td_api::getOption &request); - - void on_request(uint64 id, td_api::setOption &request); - - void on_request(uint64 id, td_api::setPollAnswer &request); - - void on_request(uint64 id, td_api::getPollVoters &request); - - void on_request(uint64 id, td_api::stopPoll &request); - - void on_request(uint64 id, const td_api::hideSuggestedAction &request); - - void on_request(uint64 id, const td_api::getLoginUrlInfo &request); - - void on_request(uint64 id, const td_api::getLoginUrl &request); - - void on_request(uint64 id, const td_api::shareUserWithBot &request); - - void on_request(uint64 id, const td_api::shareChatWithBot &request); - - void on_request(uint64 id, td_api::getInlineQueryResults &request); - - void on_request(uint64 id, td_api::answerInlineQuery &request); - - void on_request(uint64 id, td_api::searchWebApp &request); - - void on_request(uint64 id, td_api::getWebAppLinkUrl &request); - - void on_request(uint64 id, td_api::getWebAppUrl &request); - - void on_request(uint64 id, td_api::sendWebAppData &request); - - void on_request(uint64 id, td_api::openWebApp &request); - - void on_request(uint64 id, const td_api::closeWebApp &request); - - void on_request(uint64 id, td_api::answerWebAppQuery &request); - - void on_request(uint64 id, td_api::getCallbackQueryAnswer &request); - - void on_request(uint64 id, td_api::answerCallbackQuery &request); - - void on_request(uint64 id, td_api::answerShippingQuery &request); - - void on_request(uint64 id, td_api::answerPreCheckoutQuery &request); - - void on_request(uint64 id, td_api::getBankCardInfo &request); - - void on_request(uint64 id, td_api::getPaymentForm &request); - - void on_request(uint64 id, td_api::validateOrderInfo &request); - - void on_request(uint64 id, td_api::sendPaymentForm &request); - - void on_request(uint64 id, const td_api::getPaymentReceipt &request); - - void on_request(uint64 id, const td_api::getSavedOrderInfo &request); - - void on_request(uint64 id, const td_api::deleteSavedOrderInfo &request); - - void on_request(uint64 id, const td_api::deleteSavedCredentials &request); - - void on_request(uint64 id, td_api::createInvoiceLink &request); - - void on_request(uint64 id, td_api::getPassportElement &request); - - void on_request(uint64 id, td_api::getAllPassportElements &request); - - void on_request(uint64 id, td_api::setPassportElement &request); - - void on_request(uint64 id, const td_api::deletePassportElement &request); - - void on_request(uint64 id, td_api::setPassportElementErrors &request); - - void on_request(uint64 id, td_api::getPreferredCountryLanguage &request); - - void on_request(uint64 id, td_api::sendPhoneNumberVerificationCode &request); - - void on_request(uint64 id, const td_api::resendPhoneNumberVerificationCode &request); - - void on_request(uint64 id, td_api::checkPhoneNumberVerificationCode &request); - - void on_request(uint64 id, td_api::sendEmailAddressVerificationCode &request); - - void on_request(uint64 id, const td_api::resendEmailAddressVerificationCode &request); - - void on_request(uint64 id, td_api::checkEmailAddressVerificationCode &request); - - void on_request(uint64 id, td_api::getPassportAuthorizationForm &request); - - void on_request(uint64 id, td_api::getPassportAuthorizationFormAvailableElements &request); - - void on_request(uint64 id, td_api::sendPassportAuthorizationForm &request); - - void on_request(uint64 id, td_api::sendPhoneNumberConfirmationCode &request); - - void on_request(uint64 id, const td_api::resendPhoneNumberConfirmationCode &request); - - void on_request(uint64 id, td_api::checkPhoneNumberConfirmationCode &request); - - void on_request(uint64 id, const td_api::getSupportUser &request); - - void on_request(uint64 id, const td_api::getBackgrounds &request); - - void on_request(uint64 id, td_api::getBackgroundUrl &request); - - void on_request(uint64 id, td_api::searchBackground &request); - - void on_request(uint64 id, td_api::setBackground &request); - - void on_request(uint64 id, const td_api::removeBackground &request); - - void on_request(uint64 id, const td_api::resetBackgrounds &request); - - void on_request(uint64 id, td_api::getRecentlyVisitedTMeUrls &request); - - void on_request(uint64 id, td_api::setBotUpdatesStatus &request); - - void on_request(uint64 id, td_api::sendCustomRequest &request); - - void on_request(uint64 id, td_api::answerCustomQuery &request); - - void on_request(uint64 id, const td_api::setAlarm &request); - - void on_request(uint64 id, td_api::searchHashtags &request); - - void on_request(uint64 id, td_api::removeRecentHashtag &request); - - void on_request(uint64 id, const td_api::getPremiumLimit &request); - - void on_request(uint64 id, const td_api::getPremiumFeatures &request); - - void on_request(uint64 id, const td_api::getPremiumStickerExamples &request); - - void on_request(uint64 id, const td_api::viewPremiumFeature &request); - - void on_request(uint64 id, const td_api::clickPremiumSubscriptionButton &request); - - void on_request(uint64 id, const td_api::getPremiumState &request); - - void on_request(uint64 id, td_api::canPurchasePremium &request); - - void on_request(uint64 id, td_api::assignAppStoreTransaction &request); - - void on_request(uint64 id, td_api::assignGooglePlayTransaction &request); - - void on_request(uint64 id, td_api::acceptTermsOfService &request); - - void on_request(uint64 id, const td_api::getCountries &request); - - void on_request(uint64 id, const td_api::getCountryCode &request); - - void on_request(uint64 id, const td_api::getPhoneNumberInfo &request); - - void on_request(uint64 id, const td_api::getApplicationDownloadLink &request); - - void on_request(uint64 id, td_api::getDeepLinkInfo &request); - - void on_request(uint64 id, const td_api::getApplicationConfig &request); - - void on_request(uint64 id, td_api::addApplicationChangelog &request); - - void on_request(uint64 id, td_api::saveApplicationLogEvent &request); - - void on_request(uint64 id, td_api::addProxy &request); - - void on_request(uint64 id, td_api::editProxy &request); - - void on_request(uint64 id, const td_api::enableProxy &request); - - void on_request(uint64 id, const td_api::disableProxy &request); - - void on_request(uint64 id, const td_api::removeProxy &request); - - void on_request(uint64 id, const td_api::getProxies &request); - - void on_request(uint64 id, const td_api::getProxyLink &request); - - void on_request(uint64 id, const td_api::pingProxy &request); - - void on_request(uint64 id, const td_api::getUserSupportInfo &request); - - void on_request(uint64 id, td_api::setUserSupportInfo &request); - - void on_request(uint64 id, const td_api::getSupportName &request); - - void on_request(uint64 id, const td_api::getTextEntities &request); - - void on_request(uint64 id, const td_api::parseTextEntities &request); - - void on_request(uint64 id, const td_api::parseMarkdown &request); - - void on_request(uint64 id, const td_api::getMarkdownText &request); - - void on_request(uint64 id, const td_api::getFileMimeType &request); - - void on_request(uint64 id, const td_api::getFileExtension &request); - - void on_request(uint64 id, const td_api::cleanFileName &request); - - void on_request(uint64 id, const td_api::getLanguagePackString &request); - - void on_request(uint64 id, const td_api::getPhoneNumberInfoSync &request); - - void on_request(uint64 id, const td_api::getPushReceiverId &request); - - void on_request(uint64 id, const td_api::getChatFolderDefaultIconName &request); - - void on_request(uint64 id, const td_api::getJsonValue &request); - - void on_request(uint64 id, const td_api::getJsonString &request); - - void on_request(uint64 id, const td_api::getThemeParametersJsonString &request); - - void on_request(uint64 id, const td_api::setLogStream &request); - - void on_request(uint64 id, const td_api::getLogStream &request); - - void on_request(uint64 id, const td_api::setLogVerbosityLevel &request); - - void on_request(uint64 id, const td_api::getLogVerbosityLevel &request); - - void on_request(uint64 id, const td_api::getLogTags &request); - - void on_request(uint64 id, const td_api::setLogTagVerbosityLevel &request); - - void on_request(uint64 id, const td_api::getLogTagVerbosityLevel &request); - - void on_request(uint64 id, const td_api::addLogMessage &request); - - // test - void on_request(uint64 id, const td_api::testNetwork &request); - void on_request(uint64 id, td_api::testProxy &request); - void on_request(uint64 id, const td_api::testGetDifference &request); - void on_request(uint64 id, const td_api::testUseUpdate &request); - void on_request(uint64 id, const td_api::testReturnError &request); - void on_request(uint64 id, const td_api::testCallEmpty &request); - void on_request(uint64 id, const td_api::testSquareInt &request); - void on_request(uint64 id, td_api::testCallString &request); - void on_request(uint64 id, td_api::testCallBytes &request); - void on_request(uint64 id, td_api::testCallVectorInt &request); - void on_request(uint64 id, td_api::testCallVectorIntObject &request); - void on_request(uint64 id, td_api::testCallVectorString &request); - void on_request(uint64 id, td_api::testCallVectorStringObject &request); - - template - static td_api::object_ptr do_static_request(const T &request) { - return td_api::make_object(400, "The method can't be executed synchronously"); - } - static td_api::object_ptr do_static_request(const td_api::getOption &request); - static td_api::object_ptr do_static_request(const td_api::getTextEntities &request); - static td_api::object_ptr do_static_request(td_api::parseTextEntities &request); - static td_api::object_ptr do_static_request(td_api::parseMarkdown &request); - static td_api::object_ptr do_static_request(td_api::getMarkdownText &request); - static td_api::object_ptr do_static_request(const td_api::getFileMimeType &request); - static td_api::object_ptr do_static_request(const td_api::getFileExtension &request); - static td_api::object_ptr do_static_request(const td_api::cleanFileName &request); - static td_api::object_ptr do_static_request(const td_api::getLanguagePackString &request); - static td_api::object_ptr do_static_request(td_api::getPhoneNumberInfoSync &request); - static td_api::object_ptr do_static_request(const td_api::getPushReceiverId &request); - static td_api::object_ptr do_static_request(const td_api::getChatFolderDefaultIconName &request); - static td_api::object_ptr do_static_request(td_api::getJsonValue &request); - static td_api::object_ptr do_static_request(const td_api::getJsonString &request); - static td_api::object_ptr do_static_request(const td_api::getThemeParametersJsonString &request); - static td_api::object_ptr do_static_request(td_api::setLogStream &request); - static td_api::object_ptr do_static_request(const td_api::getLogStream &request); - static td_api::object_ptr do_static_request(const td_api::setLogVerbosityLevel &request); - static td_api::object_ptr do_static_request(const td_api::getLogVerbosityLevel &request); - static td_api::object_ptr do_static_request(const td_api::getLogTags &request); - static td_api::object_ptr do_static_request(const td_api::setLogTagVerbosityLevel &request); - static td_api::object_ptr do_static_request(const td_api::getLogTagVerbosityLevel &request); - static td_api::object_ptr do_static_request(const td_api::addLogMessage &request); - static td_api::object_ptr do_static_request(td_api::testReturnError &request); - - static DbKey as_db_key(string key); - - static int32 get_database_scheduler_id(); - - struct Parameters { - int32 api_id_ = 0; - string api_hash_; - bool use_secret_chats_ = false; - - // TODO move to options and remove - bool enable_storage_optimizer_ = false; - bool ignore_file_names_ = false; - }; - - void finish_set_parameters(); - - void init(Parameters parameters, Result r_opened_database); - - void init_options_and_network(); - - void init_file_manager(); - - void init_managers(); + void process_binlog_events(TdDb::OpenedDatabase &&events); void clear(); diff --git a/protocols/Telegram/tdlib/td/td/telegram/TdDb.cpp b/protocols/Telegram/tdlib/td/td/telegram/TdDb.cpp index b143733b03..5998610c48 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TdDb.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/TdDb.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -13,6 +13,7 @@ #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/MessageDb.h" #include "td/telegram/MessageThreadDb.h" +#include "td/telegram/StoryDb.h" #include "td/telegram/Td.h" #include "td/telegram/Version.h" @@ -124,9 +125,19 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p case LogEvent::HandlerType::ReadAllDialogReactionsOnServer: case LogEvent::HandlerType::DeleteTopicHistoryOnServer: case LogEvent::HandlerType::ToggleDialogIsTranslatableOnServer: + case LogEvent::HandlerType::ToggleDialogViewAsMessagesOnServer: + case LogEvent::HandlerType::SendQuickReplyShortcutMessages: events.to_messages_manager.push_back(event.clone()); break; + case LogEvent::HandlerType::DeleteStoryOnServer: + case LogEvent::HandlerType::ReadStoriesOnServer: + case LogEvent::HandlerType::LoadDialogExpiringStories: + case LogEvent::HandlerType::SendStory: + case LogEvent::HandlerType::EditStory: + events.to_story_manager.push_back(event.clone()); + break; case LogEvent::HandlerType::UpdateScopeNotificationSettingsOnServer: + case LogEvent::HandlerType::UpdateReactionNotificationSettingsOnServer: events.to_notification_settings_manager.push_back(event.clone()); break; case LogEvent::HandlerType::AddMessagePushNotification: @@ -136,6 +147,17 @@ Status init_binlog(Binlog &binlog, string path, BinlogKeyValue &binlog_p case LogEvent::HandlerType::SaveAppLog: events.save_app_log_events.push_back(event.clone()); break; + case LogEvent::HandlerType::ChangeAuthorizationSettingsOnServer: + case LogEvent::HandlerType::InvalidateSignInCodesOnServer: + case LogEvent::HandlerType::ResetAuthorizationOnServer: + case LogEvent::HandlerType::ResetAuthorizationsOnServer: + case LogEvent::HandlerType::ResetWebAuthorizationOnServer: + case LogEvent::HandlerType::ResetWebAuthorizationsOnServer: + case LogEvent::HandlerType::SetAccountTtlOnServer: + case LogEvent::HandlerType::SetAuthorizationTtlOnServer: + case LogEvent::HandlerType::SetDefaultHistoryTtlOnServer: + events.to_account_manager.push_back(event.clone()); + break; case LogEvent::HandlerType::BinlogPmcMagic: binlog_pmc.external_init_handle(event); break; @@ -226,6 +248,14 @@ DialogDbAsyncInterface *TdDb::get_dialog_db_async() { return dialog_db_async_.get(); } +StoryDbSyncInterface *TdDb::get_story_db_sync() { + return &story_db_sync_safe_->get(); +} + +StoryDbAsyncInterface *TdDb::get_story_db_async() { + return story_db_async_.get(); +} + void TdDb::flush_all() { LOG(INFO) << "Flush all databases"; if (message_db_async_) { @@ -237,20 +267,26 @@ void TdDb::flush_all() { if (dialog_db_async_) { dialog_db_async_->force_flush(); } + if (story_db_async_) { + story_db_async_->force_flush(); + } + CHECK(binlog_ != nullptr); binlog_->force_flush(); } -void TdDb::close_all(Promise<> on_finished) { - LOG(INFO) << "Close all databases"; - do_close(std::move(on_finished), false /*destroy_flag*/); -} - -void TdDb::close_and_destroy_all(Promise<> on_finished) { - LOG(INFO) << "Destroy all databases"; - do_close(std::move(on_finished), true /*destroy_flag*/); +void TdDb::close(int32 scheduler_id, bool destroy_flag, Promise on_finished) { + Scheduler::instance()->run_on_scheduler(scheduler_id, + [this, destroy_flag, on_finished = std::move(on_finished)](Unit) mutable { + do_close(destroy_flag, std::move(on_finished)); + }); } -void TdDb::do_close(Promise<> on_finished, bool destroy_flag) { +void TdDb::do_close(bool destroy_flag, Promise on_finished) { + if (destroy_flag) { + LOG(INFO) << "Destroy all databases"; + } else { + LOG(INFO) << "Close all databases"; + } MultiPromiseActorSafe mpas{"TdDbCloseMultiPromiseActor"}; mpas.add_promise(PromiseCreator::lambda( [promise = std::move(on_finished), sql_connection = std::move(sql_connection_), destroy_flag](Unit) mutable { @@ -292,6 +328,11 @@ void TdDb::do_close(Promise<> on_finished, bool destroy_flag) { dialog_db_async_->close(mpas.get_promise()); } + story_db_sync_safe_.reset(); + if (story_db_async_) { + story_db_async_->close(mpas.get_promise()); + } + // binlog_pmc is dependent on binlog_ and anyway it doesn't support close_and_destroy CHECK(binlog_pmc_.unique()); binlog_pmc_.reset(); @@ -318,10 +359,11 @@ Status TdDb::init_sqlite(const Parameters ¶meters, const DbKey &key, const D const string sql_database_path = get_sqlite_path(parameters); bool use_sqlite = parameters.use_file_database_; - bool use_file_database_ = parameters.use_file_database_; + bool use_file_database = parameters.use_file_database_; bool use_dialog_db = parameters.use_message_database_; bool use_message_thread_db = parameters.use_message_database_ && false; - bool use_message_database_ = parameters.use_message_database_; + bool use_message_database = parameters.use_message_database_; + bool use_story_database = parameters.use_message_database_; was_dialog_db_created_ = false; @@ -363,14 +405,21 @@ Status TdDb::init_sqlite(const Parameters ¶meters, const DbKey &key, const D } // init MessageDb - if (use_message_database_) { + if (use_message_database) { TRY_STATUS(init_message_db(db, user_version)); } else { TRY_STATUS(drop_message_db(db, user_version)); } + // init StoryDb + if (use_story_database) { + TRY_STATUS(init_story_db(db, user_version)); + } else { + TRY_STATUS(drop_story_db(db, user_version)); + } + // init FileDb - if (use_file_database_) { + if (use_file_database) { TRY_STATUS(init_file_db(db, user_version)); } else { TRY_STATUS(drop_file_db(db, user_version)); @@ -389,10 +438,13 @@ Status TdDb::init_sqlite(const Parameters ¶meters, const DbKey &key, const D binlog_pmc.erase_by_prefix("unread_message_count"); binlog_pmc.erase_by_prefix("unread_dialog_count"); binlog_pmc.erase("sponsored_dialog_id"); - binlog_pmc.erase_by_prefix("top_dialogs"); + binlog_pmc.erase_by_prefix("top_dialogs#"); binlog_pmc.erase("dlds_counter"); binlog_pmc.erase_by_prefix("dlds#"); binlog_pmc.erase("fetched_marks_as_unread"); + binlog_pmc.erase_by_prefix("public_channels"); + binlog_pmc.erase("channels_to_send_stories"); + binlog_pmc.erase_by_prefix("saved_messages_tags"); } if (user_version == 0) { binlog_pmc.erase("next_contacts_sync_date"); @@ -401,7 +453,7 @@ Status TdDb::init_sqlite(const Parameters ¶meters, const DbKey &key, const D binlog_pmc.erase("invalidate_old_featured_sticker_sets"); binlog_pmc.erase(AttachMenuManager::get_attach_menu_bots_database_key()); } - binlog_pmc.force_sync({}); + binlog_pmc.force_sync(Auto(), "init_sqlite"); TRY_STATUS(db.exec("COMMIT TRANSACTION")); @@ -411,8 +463,10 @@ Status TdDb::init_sqlite(const Parameters ¶meters, const DbKey &key, const D common_kv_async_ = create_sqlite_key_value_async(common_kv_safe_); if (was_dialog_db_created_) { - get_sqlite_sync_pmc()->erase("calls_db_state"); - get_sqlite_sync_pmc()->erase("di_active_live_location_messages"); + auto *sqlite_pmc = get_sqlite_sync_pmc(); + sqlite_pmc->erase("calls_db_state"); + sqlite_pmc->erase("di_active_live_location_messages"); + sqlite_pmc->erase_by_prefix("channel_recommendations"); } if (use_dialog_db) { @@ -425,11 +479,16 @@ Status TdDb::init_sqlite(const Parameters ¶meters, const DbKey &key, const D message_thread_db_async_ = create_message_thread_db_async(message_thread_db_sync_safe_); } - if (use_message_database_) { + if (use_message_database) { message_db_sync_safe_ = create_message_db_sync(sql_connection_); message_db_async_ = create_message_db_async(message_db_sync_safe_); } + if (use_story_database) { + story_db_sync_safe_ = create_story_db_sync(sql_connection_); + story_db_async_ = create_story_db_async(story_db_sync_safe_); + } + return Status::OK(); } @@ -480,7 +539,9 @@ void TdDb::open_impl(Parameters parameters, Promise &&promise) { sqlite_key = string(32, ' '); Random::secure_bytes(sqlite_key); binlog_pmc->set("sqlite_key", sqlite_key); - binlog_pmc->force_sync(Auto()); + if (parameters.use_file_database_) { + binlog_pmc->force_sync(Auto(), "TdDb::open_impl 1"); + } } new_sqlite_key = DbKey::raw_key(std::move(sqlite_key)); } else { @@ -506,7 +567,7 @@ void TdDb::open_impl(Parameters parameters, Promise &&promise) { } if (drop_sqlite_key) { binlog_pmc->erase("sqlite_key"); - binlog_pmc->force_sync(Auto()); + binlog_pmc->force_sync(Auto(), "TdDb::open_impl 2"); } VLOG(td_init) << "Create concurrent_binlog_pmc"; @@ -546,7 +607,10 @@ void TdDb::open_impl(Parameters parameters, Promise &&promise) { } TdDb::TdDb() = default; -TdDb::~TdDb() = default; + +TdDb::~TdDb() { + LOG_IF(ERROR, binlog_ != nullptr) << "Failed to close the database"; +} Status TdDb::check_parameters(Parameters ¶meters) { if (parameters.database_directory_.empty()) { @@ -598,6 +662,13 @@ Status TdDb::check_parameters(Parameters ¶meters) { return Status::OK(); } +DbKey TdDb::as_db_key(string key) { + if (key.empty()) { + return DbKey::raw_key("cucumber"); + } + return DbKey::raw_key(std::move(key)); +} + void TdDb::change_key(DbKey key, Promise<> promise) { get_binlog()->change_key(std::move(key), std::move(promise)); } @@ -610,6 +681,7 @@ Status TdDb::destroy(const Parameters ¶meters) { void TdDb::with_db_path(const std::function &callback) { SqliteDb::with_db_path(get_sqlite_path(parameters_), callback); + CHECK(binlog_ != nullptr); callback(binlog_->get_path()); } @@ -637,6 +709,7 @@ Result TdDb::get_stats() { << mask << "'", PSLICE() << table << ":" << mask); }; + TRY_STATUS(run_query("SELECT 0, SUM(length(data)), COUNT(*) FROM stories WHERE 1", "stories")); TRY_STATUS(run_query("SELECT 0, SUM(length(data)), COUNT(*) FROM messages WHERE 1", "messages")); TRY_STATUS(run_query("SELECT 0, SUM(length(data)), COUNT(*) FROM dialogs WHERE 1", "dialogs")); TRY_STATUS(run_kv_query("%", "common")); diff --git a/protocols/Telegram/tdlib/td/td/telegram/TdDb.h b/protocols/Telegram/tdlib/td/td/telegram/TdDb.h index 8dc9977f81..7081392325 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TdDb.h +++ b/protocols/Telegram/tdlib/td/td/telegram/TdDb.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,6 +11,7 @@ #include "td/db/DbKey.h" #include "td/db/KeyValueSyncInterface.h" +#include "td/utils/common.h" #include "td/utils/Promise.h" #include "td/utils/Slice.h" #include "td/utils/Status.h" @@ -38,6 +39,9 @@ class SqliteConnectionSafe; class SqliteKeyValueSafe; class SqliteKeyValueAsyncInterface; class SqliteKeyValue; +class StoryDbSyncInterface; +class StoryDbSyncSafeInterface; +class StoryDbAsyncInterface; class TdDb { public: @@ -68,10 +72,12 @@ class TdDb { vector secret_chat_events; vector web_page_events; vector save_app_log_events; - vector to_poll_manager; + vector to_account_manager; vector to_messages_manager; vector to_notification_manager; vector to_notification_settings_manager; + vector to_poll_manager; + vector to_story_manager; int64 since_last_open = 0; }; @@ -128,8 +134,7 @@ class TdDb { void flush_all(); - void close_all(Promise<> on_finished); - void close_and_destroy_all(Promise<> on_finished); + void close(int32 scheduler_id, bool destroy_flag, Promise on_finished); MessageDbSyncInterface *get_message_db_sync(); MessageDbAsyncInterface *get_message_db_async(); @@ -140,6 +145,11 @@ class TdDb { DialogDbSyncInterface *get_dialog_db_sync(); DialogDbAsyncInterface *get_dialog_db_async(); + StoryDbSyncInterface *get_story_db_sync(); + StoryDbAsyncInterface *get_story_db_async(); + + static DbKey as_db_key(string key); + void change_key(DbKey key, Promise<> promise); void with_db_path(const std::function &callback); @@ -167,6 +177,9 @@ class TdDb { std::shared_ptr dialog_db_sync_safe_; std::shared_ptr dialog_db_async_; + std::shared_ptr story_db_sync_safe_; + std::shared_ptr story_db_async_; + std::shared_ptr> binlog_pmc_; std::shared_ptr> config_pmc_; std::shared_ptr binlog_; @@ -178,7 +191,7 @@ class TdDb { Status init_sqlite(const Parameters ¶meters, const DbKey &key, const DbKey &old_key, BinlogKeyValue &binlog_pmc); - void do_close(Promise<> on_finished, bool destroy_flag); + void do_close(bool destroy_flag, Promise on_finished); }; } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.cpp b/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.cpp index 5aab9c4876..2faff6006a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.cpp @@ -1,121 +1,35 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/TermsOfService.h" -#include "td/telegram/Global.h" -#include "td/telegram/misc.h" -#include "td/telegram/net/NetQueryCreator.h" -#include "td/telegram/Td.h" - -#include "td/utils/buffer.h" -#include "td/utils/logging.h" -#include "td/utils/Status.h" - namespace td { -class GetTermsOfServiceUpdateQuery final : public Td::ResultHandler { - Promise> promise_; - - public: - explicit GetTermsOfServiceUpdateQuery(Promise> &&promise) - : promise_(std::move(promise)) { - } - - void send() { - // we don't poll terms of service before authorization - send_query(G()->net_query_creator().create(telegram_api::help_getTermsOfServiceUpdate())); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto result = result_ptr.move_as_ok(); - switch (result->get_id()) { - case telegram_api::help_termsOfServiceUpdateEmpty::ID: { - auto update = move_tl_object_as(result); - promise_.set_value(std::make_pair(update->expires_, TermsOfService())); - break; - } - case telegram_api::help_termsOfServiceUpdate::ID: { - auto update = move_tl_object_as(result); - promise_.set_value(std::make_pair(update->expires_, TermsOfService(std::move(update->terms_of_service_)))); - break; - } - default: - UNREACHABLE(); - } - } - - void on_error(Status status) final { - promise_.set_error(std::move(status)); - } -}; - -class AcceptTermsOfServiceQuery final : public Td::ResultHandler { - Promise promise_; - - public: - explicit AcceptTermsOfServiceQuery(Promise &&promise) : promise_(std::move(promise)) { - } - - void send(const string &terms_of_service_id) { - send_query(G()->net_query_creator().create(telegram_api::help_acceptTermsOfService( - telegram_api::make_object(terms_of_service_id)))); - } - - void on_result(BufferSlice packet) final { - auto result_ptr = fetch_result(packet); - if (result_ptr.is_error()) { - return on_error(result_ptr.move_as_error()); - } - - auto result = result_ptr.ok(); - if (!result) { - LOG(ERROR) << "Failed to accept terms of service"; - } - promise_.set_value(Unit()); - } - - void on_error(Status status) final { - promise_.set_error(std::move(status)); - } -}; - TermsOfService::TermsOfService(telegram_api::object_ptr terms) { if (terms == nullptr) { return; } id_ = std::move(terms->id_->data_); - auto entities = get_message_entities(nullptr, std::move(terms->entities_), "TermsOfService"); - auto status = fix_formatted_text(terms->text_, entities, true, true, true, true, false); - if (status.is_error()) { - if (!clean_input_string(terms->text_)) { - terms->text_.clear(); - } - entities = find_entities(terms->text_, true, true); - } - if (terms->text_.empty()) { + text_ = + get_formatted_text(nullptr, std::move(terms->text_), std::move(terms->entities_), true, false, "TermsOfService"); + if (text_.text.empty()) { id_.clear(); } - text_ = FormattedText{std::move(terms->text_), std::move(entities)}; min_user_age_ = terms->min_age_confirm_; show_popup_ = terms->popup_; } -void get_terms_of_service(Td *td, Promise> promise) { - td->create_handler(std::move(promise))->send(); -} +td_api::object_ptr TermsOfService::get_terms_of_service_object() const { + if (id_.empty()) { + return nullptr; + } -void accept_terms_of_service(Td *td, string &&terms_of_service_id, Promise &&promise) { - td->create_handler(std::move(promise))->send(terms_of_service_id); + return td_api::make_object(get_formatted_text_object(nullptr, text_, true, -1), min_user_age_, + show_popup_); } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.h b/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.h index 69a680cc76..929d3a0765 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.h +++ b/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,21 +7,14 @@ #pragma once #include "td/telegram/MessageEntity.h" -#include "td/telegram/MessageEntity.hpp" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" #include "td/utils/common.h" -#include "td/utils/Promise.h" #include "td/utils/Slice.h" -#include "td/utils/tl_helpers.h" - -#include namespace td { -class Td; - class TermsOfService { string id_; FormattedText text_; @@ -35,40 +28,13 @@ class TermsOfService { return id_; } - td_api::object_ptr get_terms_of_service_object() const { - if (id_.empty()) { - return nullptr; - } - - return td_api::make_object(get_formatted_text_object(text_, true, -1), min_user_age_, - show_popup_); - } + td_api::object_ptr get_terms_of_service_object() const; template - void store(StorerT &storer) const { - using td::store; - BEGIN_STORE_FLAGS(); - STORE_FLAG(show_popup_); - END_STORE_FLAGS(); - store(id_, storer); - store(text_, storer); - store(min_user_age_, storer); - } + void store(StorerT &storer) const; template - void parse(ParserT &parser) { - using td::parse; - BEGIN_PARSE_FLAGS(); - PARSE_FLAG(show_popup_); - END_PARSE_FLAGS(); - parse(id_, parser); - parse(text_, parser); - parse(min_user_age_, parser); - } + void parse(ParserT &parser); }; -void get_terms_of_service(Td *td, Promise> promise); - -void accept_terms_of_service(Td *td, string &&terms_of_service_id, Promise &&promise); - } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.hpp b/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.hpp new file mode 100644 index 0000000000..e106c39fac --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/TermsOfService.hpp @@ -0,0 +1,40 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/TermsOfService.h" + +#include "td/telegram/MessageEntity.hpp" + +#include "td/utils/common.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void TermsOfService::store(StorerT &storer) const { + using td::store; + BEGIN_STORE_FLAGS(); + STORE_FLAG(show_popup_); + END_STORE_FLAGS(); + store(id_, storer); + store(text_, storer); + store(min_user_age_, storer); +} + +template +void TermsOfService::parse(ParserT &parser) { + using td::parse; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(show_popup_); + END_PARSE_FLAGS(); + parse(id_, parser); + parse(text_, parser); + parse(min_user_age_, parser); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TermsOfServiceManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/TermsOfServiceManager.cpp new file mode 100644 index 0000000000..5e1a9123ed --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/TermsOfServiceManager.cpp @@ -0,0 +1,201 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/TermsOfServiceManager.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/Global.h" +#include "td/telegram/net/NetQueryCreator.h" +#include "td/telegram/Td.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/Random.h" +#include "td/utils/Status.h" + +namespace td { + +class GetTermsOfServiceUpdateQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetTermsOfServiceUpdateQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send() { + // we don't poll terms of service before authorization + send_query(G()->net_query_creator().create(telegram_api::help_getTermsOfServiceUpdate())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + switch (result->get_id()) { + case telegram_api::help_termsOfServiceUpdateEmpty::ID: { + auto update = move_tl_object_as(result); + promise_.set_value(std::make_pair(update->expires_, TermsOfService())); + break; + } + case telegram_api::help_termsOfServiceUpdate::ID: { + auto update = move_tl_object_as(result); + promise_.set_value(std::make_pair(update->expires_, TermsOfService(std::move(update->terms_of_service_)))); + break; + } + default: + UNREACHABLE(); + } + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class AcceptTermsOfServiceQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit AcceptTermsOfServiceQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &terms_of_service_id) { + send_query(G()->net_query_creator().create(telegram_api::help_acceptTermsOfService( + telegram_api::make_object(terms_of_service_id)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.ok(); + if (!result) { + LOG(ERROR) << "Failed to accept terms of service"; + } + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +TermsOfServiceManager::TermsOfServiceManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +void TermsOfServiceManager::tear_down() { + parent_.reset(); +} + +void TermsOfServiceManager::start_up() { + init(); +} + +void TermsOfServiceManager::init() { + if (G()->close_flag()) { + return; + } + if (is_inited_ || !td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { + return; + } + is_inited_ = true; + + schedule_get_terms_of_service(0); +} + +void TermsOfServiceManager::schedule_get_terms_of_service(int32 expires_in) { + if (G()->close_flag() || !is_inited_) { + return; + } + + set_timeout_in(expires_in); +} + +void TermsOfServiceManager::timeout_expired() { + if (G()->close_flag() || !is_inited_) { + return; + } + + get_terms_of_service( + PromiseCreator::lambda([actor_id = actor_id(this)](Result> result) { + send_closure(actor_id, &TermsOfServiceManager::on_get_terms_of_service, std::move(result), false); + })); +} + +td_api::object_ptr TermsOfServiceManager::get_update_terms_of_service_object() const { + auto terms_of_service = pending_terms_of_service_.get_terms_of_service_object(); + if (terms_of_service == nullptr) { + return nullptr; + } + return td_api::make_object(pending_terms_of_service_.get_id().str(), + std::move(terms_of_service)); +} + +void TermsOfServiceManager::on_get_terms_of_service(Result> result, bool dummy) { + if (G()->close_flag()) { + return; + } + CHECK(is_inited_); + + int32 expires_in = 0; + if (result.is_error()) { + expires_in = Random::fast(10, 60); + } else { + auto terms = result.move_as_ok(); + pending_terms_of_service_ = std::move(terms.second); + auto update = get_update_terms_of_service_object(); + if (update == nullptr) { + expires_in = clamp(terms.first - G()->unix_time(), 3600, 86400); + } else { + send_closure(G()->td(), &Td::send_update, std::move(update)); + } + } + if (expires_in > 0) { + schedule_get_terms_of_service(expires_in); + } +} + +void TermsOfServiceManager::get_terms_of_service(Promise> promise) { + td_->create_handler(std::move(promise))->send(); +} + +void TermsOfServiceManager::accept_terms_of_service(string &&terms_of_service_id, Promise &&promise) { + auto query_promise = + PromiseCreator::lambda([actor_id = actor_id(this), promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &TermsOfServiceManager::on_accept_terms_of_service, std::move(promise)); + }); + td_->create_handler(std::move(query_promise))->send(terms_of_service_id); +} + +void TermsOfServiceManager::on_accept_terms_of_service(Promise &&promise) { + pending_terms_of_service_ = TermsOfService(); + promise.set_value(Unit()); + schedule_get_terms_of_service(0); +} + +void TermsOfServiceManager::get_current_state(vector> &updates) const { + if (!is_inited_) { + return; + } + + auto update_terms_of_service_object = get_update_terms_of_service_object(); + if (update_terms_of_service_object != nullptr) { + updates.push_back(std::move(update_terms_of_service_object)); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TermsOfServiceManager.h b/protocols/Telegram/tdlib/td/td/telegram/TermsOfServiceManager.h new file mode 100644 index 0000000000..aef96d8dec --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/TermsOfServiceManager.h @@ -0,0 +1,59 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/TermsOfService.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" + +#include + +namespace td { + +class Td; + +class TermsOfServiceManager final : public Actor { + public: + TermsOfServiceManager(Td *td, ActorShared<> parent); + + void init(); + + void accept_terms_of_service(string &&terms_of_service_id, Promise &&promise); + + void get_current_state(vector> &updates) const; + + private: + void tear_down() final; + + void start_up() final; + + void timeout_expired() final; + + void schedule_get_terms_of_service(int32 expires_in); + + void get_terms_of_service(Promise> promise); + + td_api::object_ptr get_update_terms_of_service_object() const; + + void on_get_terms_of_service(Result> result, bool dummy); + + void on_accept_terms_of_service(Promise &&promise); + + Td *td_; + ActorShared<> parent_; + + TermsOfService pending_terms_of_service_; + + bool is_inited_ = false; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ThemeManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/ThemeManager.cpp index b02783100d..8cf852f25a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ThemeManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/ThemeManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -7,24 +7,37 @@ #include "td/telegram/ThemeManager.h" #include "td/telegram/AuthManager.h" -#include "td/telegram/BackgroundInfo.hpp" #include "td/telegram/Global.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/net/NetQueryCreator.h" +#include "td/telegram/OptionManager.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/ThemeSettings.hpp" #include "td/utils/algorithm.h" #include "td/utils/buffer.h" #include "td/utils/emoji.h" #include "td/utils/JsonBuilder.h" #include "td/utils/logging.h" -#include "td/utils/Random.h" -#include "td/utils/Time.h" +#include "td/utils/Slice.h" #include "td/utils/tl_helpers.h" namespace td { +static bool are_colors_valid(const vector &colors, size_t min_size, size_t max_size) { + if (min_size > colors.size() || colors.size() > max_size) { + return false; + } + for (auto &color : colors) { + if (color < 0 || color > 0xFFFFFF) { + return false; + } + } + return true; +} + class GetChatThemesQuery final : public Td::ResultHandler { Promise> promise_; @@ -51,58 +64,65 @@ class GetChatThemesQuery final : public Td::ResultHandler { } }; -bool operator==(const ThemeManager::ThemeSettings &lhs, const ThemeManager::ThemeSettings &rhs) { - return lhs.accent_color == rhs.accent_color && lhs.message_accent_color == rhs.message_accent_color && - lhs.background_info == rhs.background_info && lhs.base_theme == rhs.base_theme && - lhs.message_colors == rhs.message_colors && lhs.animate_message_colors == rhs.animate_message_colors; -} +class GetPeerColorsQuery final : public Td::ResultHandler { + Promise> promise_; -bool operator!=(const ThemeManager::ThemeSettings &lhs, const ThemeManager::ThemeSettings &rhs) { - return !(lhs == rhs); -} + public: + explicit GetPeerColorsQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } -template -void ThemeManager::ThemeSettings::store(StorerT &storer) const { - using td::store; - bool has_message_accent_color = message_accent_color != accent_color; - bool has_background = background_info.is_valid(); - BEGIN_STORE_FLAGS(); - STORE_FLAG(animate_message_colors); - STORE_FLAG(has_message_accent_color); - STORE_FLAG(has_background); - END_STORE_FLAGS(); - store(accent_color, storer); - if (has_message_accent_color) { - store(message_accent_color, storer); + void send(int32 hash) { + send_query(G()->net_query_creator().create(telegram_api::help_getPeerColors(hash))); } - if (has_background) { - store(background_info, storer); + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(result_ptr.move_as_ok()); } - store(base_theme, storer); - store(message_colors, storer); -} -template -void ThemeManager::ThemeSettings::parse(ParserT &parser) { - using td::parse; - bool has_message_accent_color; - bool has_background; - BEGIN_PARSE_FLAGS(); - PARSE_FLAG(animate_message_colors); - PARSE_FLAG(has_message_accent_color); - PARSE_FLAG(has_background); - END_PARSE_FLAGS(); - parse(accent_color, parser); - if (has_message_accent_color) { - parse(message_accent_color, parser); - } else { - message_accent_color = accent_color; + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetPeerProfileColorsQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetPeerProfileColorsQuery(Promise> &&promise) + : promise_(std::move(promise)) { } - if (has_background) { - parse(background_info, parser); + + void send(int32 hash) { + send_query(G()->net_query_creator().create(telegram_api::help_getPeerProfileColors(hash))); } - parse(base_theme, parser); - parse(message_colors, parser); + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(result_ptr.move_as_ok()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +bool operator==(const ThemeManager::ProfileAccentColor &lhs, const ThemeManager::ProfileAccentColor &rhs) { + return lhs.palette_colors_ == rhs.palette_colors_ && lhs.background_colors_ == rhs.background_colors_ && + lhs.story_colors_ == rhs.story_colors_; +} + +bool operator!=(const ThemeManager::ProfileAccentColor &lhs, const ThemeManager::ProfileAccentColor &rhs) { + return !(lhs == rhs); } template @@ -137,14 +157,182 @@ void ThemeManager::ChatThemes::parse(ParserT &parser) { td::parse(themes, parser); } +template +void ThemeManager::AccentColors::store(StorerT &storer) const { + bool has_hash = hash_ != 0; + bool has_min_broadcast_boost_levels = !min_broadcast_boost_levels_.empty(); + bool has_min_megagroup_boost_levels = !min_megagroup_boost_levels_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_hash); + STORE_FLAG(has_min_broadcast_boost_levels); + STORE_FLAG(has_min_megagroup_boost_levels); + END_STORE_FLAGS(); + td::store(static_cast(light_colors_.size()), storer); + for (auto &it : light_colors_) { + td::store(it.first, storer); + td::store(it.second, storer); + } + td::store(static_cast(dark_colors_.size()), storer); + for (auto &it : dark_colors_) { + td::store(it.first, storer); + td::store(it.second, storer); + } + td::store(accent_color_ids_, storer); + if (has_hash) { + td::store(hash_, storer); + } + if (has_min_broadcast_boost_levels) { + td::store(min_broadcast_boost_levels_, storer); + } + if (has_min_megagroup_boost_levels) { + td::store(min_megagroup_boost_levels_, storer); + } +} + +template +void ThemeManager::AccentColors::parse(ParserT &parser) { + bool has_hash; + bool has_min_broadcast_boost_levels; + bool has_min_megagroup_boost_levels; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_hash); + PARSE_FLAG(has_min_broadcast_boost_levels); + PARSE_FLAG(has_min_megagroup_boost_levels); + END_PARSE_FLAGS(); + int32 size; + td::parse(size, parser); + for (int32 i = 0; i < size; i++) { + AccentColorId accent_color_id; + vector colors; + td::parse(accent_color_id, parser); + td::parse(colors, parser); + CHECK(accent_color_id.is_valid()); + light_colors_.emplace(accent_color_id, std::move(colors)); + } + td::parse(size, parser); + for (int32 i = 0; i < size; i++) { + AccentColorId accent_color_id; + vector colors; + td::parse(accent_color_id, parser); + td::parse(colors, parser); + CHECK(accent_color_id.is_valid()); + dark_colors_.emplace(accent_color_id, std::move(colors)); + } + td::parse(accent_color_ids_, parser); + if (has_hash) { + td::parse(hash_, parser); + } + if (has_min_broadcast_boost_levels) { + td::parse(min_broadcast_boost_levels_, parser); + } else { + hash_ = 0; + } + if (has_min_megagroup_boost_levels) { + td::parse(min_megagroup_boost_levels_, parser); + } +} + +template +void ThemeManager::ProfileAccentColor::store(StorerT &storer) const { + td::store(palette_colors_, storer); + td::store(background_colors_, storer); + td::store(story_colors_, storer); +} + +template +void ThemeManager::ProfileAccentColor::parse(ParserT &parser) { + td::parse(palette_colors_, parser); + td::parse(background_colors_, parser); + td::parse(story_colors_, parser); +} + +template +void ThemeManager::ProfileAccentColors::store(StorerT &storer) const { + bool has_hash = hash_ != 0; + bool has_min_broadcast_boost_levels = !min_broadcast_boost_levels_.empty(); + bool has_min_megagroup_boost_levels = !min_megagroup_boost_levels_.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_hash); + STORE_FLAG(has_min_broadcast_boost_levels); + STORE_FLAG(has_min_megagroup_boost_levels); + END_STORE_FLAGS(); + td::store(static_cast(light_colors_.size()), storer); + for (auto &it : light_colors_) { + td::store(it.first, storer); + td::store(it.second, storer); + } + td::store(static_cast(dark_colors_.size()), storer); + for (auto &it : dark_colors_) { + td::store(it.first, storer); + td::store(it.second, storer); + } + td::store(accent_color_ids_, storer); + if (has_hash) { + td::store(hash_, storer); + } + if (has_min_broadcast_boost_levels) { + td::store(min_broadcast_boost_levels_, storer); + } + if (has_min_megagroup_boost_levels) { + td::store(min_megagroup_boost_levels_, storer); + } +} + +template +void ThemeManager::ProfileAccentColors::parse(ParserT &parser) { + bool has_hash; + bool has_min_broadcast_boost_levels; + bool has_min_megagroup_boost_levels; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_hash); + PARSE_FLAG(has_min_broadcast_boost_levels); + PARSE_FLAG(has_min_megagroup_boost_levels); + END_PARSE_FLAGS(); + int32 size; + td::parse(size, parser); + for (int32 i = 0; i < size; i++) { + AccentColorId accent_color_id; + ProfileAccentColor colors; + td::parse(accent_color_id, parser); + td::parse(colors, parser); + CHECK(accent_color_id.is_valid()); + light_colors_.emplace(accent_color_id, std::move(colors)); + } + td::parse(size, parser); + for (int32 i = 0; i < size; i++) { + AccentColorId accent_color_id; + ProfileAccentColor colors; + td::parse(accent_color_id, parser); + td::parse(colors, parser); + CHECK(accent_color_id.is_valid()); + dark_colors_.emplace(accent_color_id, std::move(colors)); + } + td::parse(accent_color_ids_, parser); + if (has_hash) { + td::parse(hash_, parser); + } + if (has_min_broadcast_boost_levels) { + td::parse(min_broadcast_boost_levels_, parser); + } else { + hash_ = 0; + } + if (has_min_megagroup_boost_levels) { + td::parse(min_megagroup_boost_levels_, parser); + } else { + hash_ = 0; + } +} + ThemeManager::ThemeManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { + load_accent_colors(); + load_profile_accent_colors(); } void ThemeManager::start_up() { init(); } -void ThemeManager::init() { +void ThemeManager::load_chat_themes() { // must not be called in constructor, because uses other managers if (!td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { return; } @@ -159,44 +347,98 @@ void ThemeManager::init() { chat_themes_ = ChatThemes(); } } - chat_themes_.next_reload_time = Time::now(); - loop(); } -void ThemeManager::tear_down() { - parent_.reset(); +void ThemeManager::load_accent_colors() { + if (!td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { + return; + } + + auto log_event_string = G()->td_db()->get_binlog_pmc()->get(get_accent_colors_database_key()); + if (!log_event_string.empty()) { + auto status = log_event_parse(accent_colors_, log_event_string); + if (status.is_ok()) { + send_update_accent_colors(); + } else { + LOG(ERROR) << "Failed to parse accent colors from binlog: " << status; + accent_colors_ = AccentColors(); + } + } } -void ThemeManager::loop() { +void ThemeManager::load_profile_accent_colors() { if (!td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { return; } - if (Time::now() < chat_themes_.next_reload_time) { - return set_timeout_at(chat_themes_.next_reload_time); + auto log_event_string = G()->td_db()->get_binlog_pmc()->get(get_profile_accent_colors_database_key()); + if (!log_event_string.empty()) { + auto status = log_event_parse(profile_accent_colors_, log_event_string); + if (status.is_ok()) { + send_update_profile_accent_colors(); + } else { + LOG(ERROR) << "Failed to parse profile accent colors from binlog: " << status; + profile_accent_colors_ = ProfileAccentColors(); + } } +} - auto request_promise = PromiseCreator::lambda( - [actor_id = actor_id(this)](Result> result) { - send_closure(actor_id, &ThemeManager::on_get_chat_themes, std::move(result)); - }); +void ThemeManager::init() { + load_chat_themes(); + if (td_->auth_manager_->is_authorized() && !td_->auth_manager_->is_bot()) { + if (chat_themes_.hash == 0) { + reload_chat_themes(); + } + if (accent_colors_.hash_ == 0) { + reload_accent_colors(); + } + if (profile_accent_colors_.hash_ == 0) { + reload_profile_accent_colors(); + } + } +} - td_->create_handler(std::move(request_promise))->send(chat_themes_.hash); +void ThemeManager::tear_down() { + parent_.reset(); } -bool ThemeManager::is_dark_base_theme(BaseTheme base_theme) { - switch (base_theme) { - case BaseTheme::Classic: - case BaseTheme::Day: - case BaseTheme::Arctic: - return false; - case BaseTheme::Night: - case BaseTheme::Tinted: - return true; - default: - UNREACHABLE(); - return false; +ThemeManager::DialogBoostAvailableCounts ThemeManager::get_dialog_boost_available_count(int32 level, + bool for_megagroup) { + DialogBoostAvailableCounts result; + if (level >= td_->option_manager_->get_option_integer(for_megagroup ? Slice("group_wallpaper_level_min") + : Slice("channel_wallpaper_level_min"))) { + result.chat_theme_count_ = static_cast(chat_themes_.themes.size()); } + { + auto &min_boost_levels = + for_megagroup ? accent_colors_.min_megagroup_boost_levels_ : accent_colors_.min_broadcast_boost_levels_; + for (size_t i = 0; i < min_boost_levels.size(); i++) { + if (level >= min_boost_levels[i] && min_boost_levels[i] != 0) { + result.accent_color_count_++; + + if (accent_colors_.accent_color_ids_[i].is_built_in()) { + result.title_color_count_++; + continue; + } + + auto it = accent_colors_.light_colors_.find(accent_colors_.accent_color_ids_[i]); + CHECK(it != accent_colors_.light_colors_.end()); + if (it->second.size() == 1) { + result.title_color_count_++; + } + } + } + } + { + auto &min_profile_boost_levels = for_megagroup ? profile_accent_colors_.min_megagroup_boost_levels_ + : profile_accent_colors_.min_broadcast_boost_levels_; + for (size_t i = 0; i < min_profile_boost_levels.size(); i++) { + if (level >= min_profile_boost_levels[i] && min_profile_boost_levels[i] != 0) { + result.profile_accent_color_count_++; + } + } + } + return result; } void ThemeManager::on_update_theme(telegram_api::object_ptr &&theme, Promise &&promise) { @@ -207,11 +449,11 @@ void ThemeManager::on_update_theme(telegram_api::object_ptr for (auto &chat_theme : chat_themes_.themes) { if (chat_theme.id == theme->id_) { for (auto &settings : theme->settings_) { - auto theme_settings = get_chat_theme_settings(std::move(settings)); - if (theme_settings.message_colors.empty()) { + ThemeSettings theme_settings(td_, std::move(settings)); + if (theme_settings.is_empty()) { continue; } - if (is_dark_base_theme(theme_settings.base_theme)) { + if (theme_settings.are_dark()) { if (!was_dark) { was_dark = true; if (chat_theme.dark_theme != theme_settings) { @@ -238,34 +480,91 @@ void ThemeManager::on_update_theme(telegram_api::object_ptr promise.set_value(Unit()); } -namespace { -template -static auto get_color_json(int32 color); +bool ThemeManager::on_update_accent_colors(FlatHashMap, AccentColorIdHash> light_colors, + FlatHashMap, AccentColorIdHash> dark_colors, + vector accent_color_ids, + vector min_broadcast_boost_levels, + vector min_megagroup_boost_levels) { + auto are_equal = [](const FlatHashMap, AccentColorIdHash> &lhs, + const FlatHashMap, AccentColorIdHash> &rhs) { + for (auto &lhs_it : lhs) { + auto rhs_it = rhs.find(lhs_it.first); + if (rhs_it == rhs.end() || rhs_it->second != lhs_it.second) { + return false; + } + } + return true; + }; + if (accent_color_ids == accent_colors_.accent_color_ids_ && + min_broadcast_boost_levels == accent_colors_.min_broadcast_boost_levels_ && + min_megagroup_boost_levels == accent_colors_.min_megagroup_boost_levels_ && + are_equal(light_colors, accent_colors_.light_colors_) && are_equal(dark_colors, accent_colors_.dark_colors_)) { + return false; + } + for (auto &it : light_colors) { + accent_colors_.light_colors_[it.first] = std::move(it.second); + } + for (auto &it : dark_colors) { + accent_colors_.dark_colors_[it.first] = std::move(it.second); + } + accent_colors_.accent_color_ids_ = std::move(accent_color_ids); + accent_colors_.min_broadcast_boost_levels_ = std::move(min_broadcast_boost_levels); + accent_colors_.min_megagroup_boost_levels_ = std::move(min_megagroup_boost_levels); -template <> -auto get_color_json(int32 color) { - return static_cast(static_cast(color) | 0xFF000000); + save_accent_colors(); + send_update_accent_colors(); + return true; } -template <> -auto get_color_json(int32 color) { - string res(7, '#'); - const char *hex = "0123456789abcdef"; - for (int i = 0; i < 3; i++) { - int32 num = (color >> (i * 8)) & 0xFF; - res[2 * i + 1] = hex[num >> 4]; - res[2 * i + 2] = hex[num & 15]; +bool ThemeManager::on_update_profile_accent_colors( + FlatHashMap light_colors, + FlatHashMap dark_colors, + vector accent_color_ids, vector min_broadcast_boost_levels, + vector min_megagroup_boost_levels) { + auto are_equal = [](const FlatHashMap &lhs, + const FlatHashMap &rhs) { + for (auto &lhs_it : lhs) { + auto rhs_it = rhs.find(lhs_it.first); + if (rhs_it == rhs.end() || rhs_it->second != lhs_it.second) { + return false; + } + } + return true; + }; + if (accent_color_ids == profile_accent_colors_.accent_color_ids_ && + min_broadcast_boost_levels == profile_accent_colors_.min_broadcast_boost_levels_ && + min_megagroup_boost_levels == profile_accent_colors_.min_megagroup_boost_levels_ && + are_equal(light_colors, profile_accent_colors_.light_colors_) && + are_equal(dark_colors, profile_accent_colors_.dark_colors_)) { + return false; } - return res; + for (auto &it : light_colors) { + profile_accent_colors_.light_colors_[it.first] = std::move(it.second); + } + for (auto &it : dark_colors) { + profile_accent_colors_.dark_colors_[it.first] = std::move(it.second); + } + profile_accent_colors_.accent_color_ids_ = std::move(accent_color_ids); + profile_accent_colors_.min_broadcast_boost_levels_ = std::move(min_broadcast_boost_levels); + profile_accent_colors_.min_megagroup_boost_levels_ = std::move(min_megagroup_boost_levels); + + save_profile_accent_colors(); + send_update_profile_accent_colors(); + return true; } -template -string get_theme_parameters_json_string_impl(const td_api::object_ptr &theme) { - if (for_web_view && theme == nullptr) { - return "null"; - } +string ThemeManager::get_theme_parameters_json_string(const td_api::object_ptr &theme) { return json_encode(json_object([&theme](auto &o) { - auto get_color = &get_color_json; + auto get_color = [](int32 color) { + string res(7, '#'); + const char *hex = "0123456789abcdef"; + for (int i = 0; i < 3; i++) { + int32 num = (color >> (i * 8)) & 0xFF; + res[2 * i + 1] = hex[num >> 4]; + res[2 * i + 2] = hex[num & 15]; + } + return res; + }; o("bg_color", get_color(theme->background_color_)); o("secondary_bg_color", get_color(theme->secondary_background_color_)); o("text_color", get_color(theme->text_color_)); @@ -273,40 +572,43 @@ string get_theme_parameters_json_string_impl(const td_api::object_ptrlink_color_)); o("button_color", get_color(theme->button_color_)); o("button_text_color", get_color(theme->button_text_color_)); + o("header_bg_color", get_color(theme->header_background_color_)); + o("bottom_bar_bg_color", get_color(theme->bottom_bar_background_color_)); + o("section_bg_color", get_color(theme->section_background_color_)); + o("section_separator_color", get_color(theme->section_separator_color_)); + o("accent_text_color", get_color(theme->accent_text_color_)); + o("section_header_text_color", get_color(theme->section_header_text_color_)); + o("subtitle_text_color", get_color(theme->subtitle_text_color_)); + o("destructive_text_color", get_color(theme->destructive_text_color_)); })); } -} // namespace -string ThemeManager::get_theme_parameters_json_string(const td_api::object_ptr &theme, - bool for_web_view) { - if (for_web_view) { - return get_theme_parameters_json_string_impl(theme); - } else { - return get_theme_parameters_json_string_impl(theme); +int32 ThemeManager::get_accent_color_id_object(AccentColorId accent_color_id, + AccentColorId fallback_accent_color_id) const { + if (accent_color_id.is_valid() && (td_->auth_manager_->is_bot() || accent_color_id.is_built_in() || + accent_colors_.light_colors_.count(accent_color_id) != 0)) { + return accent_color_id.get(); } + if (!fallback_accent_color_id.is_valid()) { + return 5; // blue + } + CHECK(fallback_accent_color_id.is_built_in()); + return fallback_accent_color_id.get(); } -td_api::object_ptr ThemeManager::get_theme_settings_object(const ThemeSettings &settings) const { - auto fill = [colors = settings.message_colors]() mutable -> td_api::object_ptr { - if (colors.size() >= 3) { - return td_api::make_object(std::move(colors)); - } - CHECK(!colors.empty()); - if (colors.size() == 1 || colors[0] == colors[1]) { - return td_api::make_object(colors[0]); - } - return td_api::make_object(colors[1], colors[0], 0); - }(); - - // ignore settings.base_theme for now - return td_api::make_object( - settings.accent_color, settings.background_info.get_background_object(td_), std::move(fill), - settings.animate_message_colors, settings.message_accent_color); +int32 ThemeManager::get_profile_accent_color_id_object(AccentColorId accent_color_id) const { + if (!accent_color_id.is_valid()) { + return -1; + } + if (td_->auth_manager_->is_bot() || profile_accent_colors_.light_colors_.count(accent_color_id) != 0) { + return accent_color_id.get(); + } + return -1; } td_api::object_ptr ThemeManager::get_chat_theme_object(const ChatTheme &theme) const { - return td_api::make_object(theme.emoji, get_theme_settings_object(theme.light_theme), - get_theme_settings_object(theme.dark_theme)); + return td_api::make_object(theme.emoji, theme.light_theme.get_theme_settings_object(td_), + theme.dark_theme.get_theme_settings_object(td_)); } td_api::object_ptr ThemeManager::get_update_chat_themes_object() const { @@ -314,27 +616,146 @@ td_api::object_ptr ThemeManager::get_update_chat_theme transform(chat_themes_.themes, [this](const ChatTheme &theme) { return get_chat_theme_object(theme); })); } +td_api::object_ptr ThemeManager::get_update_accent_colors_object() const { + return accent_colors_.get_update_accent_colors_object(); +} + +td_api::object_ptr ThemeManager::AccentColors::get_update_accent_colors_object() const { + vector> colors; + int32 base_colors[] = {0xDF2020, 0xDFA520, 0xA040A0, 0x208020, 0x20DFDF, 0x2044DF, 0xDF1493}; + auto get_distance = [](int32 lhs_color, int32 rhs_color) { + auto get_color_distance = [](int32 lhs, int32 rhs) { + auto diff = max(lhs & 255, 0) - max(rhs & 255, 0); + return diff * diff; + }; + return get_color_distance(lhs_color, rhs_color) + get_color_distance(lhs_color >> 8, rhs_color >> 8) + + get_color_distance(lhs_color >> 16, rhs_color >> 16); + }; + FlatHashMap min_broadcast_boost_levels; + for (size_t i = 0; i < min_broadcast_boost_levels_.size(); i++) { + CHECK(i < accent_color_ids_.size()); + min_broadcast_boost_levels[accent_color_ids_[i]] = min_broadcast_boost_levels_[i]; + } + for (auto &it : light_colors_) { + auto light_colors = it.second; + auto dark_it = dark_colors_.find(it.first); + auto dark_colors = dark_it != dark_colors_.end() ? dark_it->second : light_colors; + CHECK(!light_colors.empty()); + CHECK(!dark_colors.empty()); + auto first_color = light_colors[0]; + int best_index = 0; + int32 best_distance = get_distance(base_colors[0], first_color); + for (int i = 1; i < 7; i++) { + auto cur_distance = get_distance(base_colors[i], first_color); + if (cur_distance < best_distance) { + best_distance = cur_distance; + best_index = i; + } + } + colors.push_back(td_api::make_object(it.first.get(), best_index, std::move(light_colors), + std::move(dark_colors), + min_broadcast_boost_levels[it.first])); + } + auto available_accent_color_ids = + transform(accent_color_ids_, [](AccentColorId accent_color_id) { return accent_color_id.get(); }); + return td_api::make_object(std::move(colors), std::move(available_accent_color_ids)); +} + +td_api::object_ptr ThemeManager::get_update_profile_accent_colors_object() const { + return profile_accent_colors_.get_update_profile_accent_colors_object(); +} + +bool ThemeManager::ProfileAccentColor::is_valid() const { + return are_colors_valid(palette_colors_, 1, 2) && are_colors_valid(background_colors_, 1, 2) && + are_colors_valid(story_colors_, 2, 2); +} + +td_api::object_ptr ThemeManager::ProfileAccentColor::get_profile_accent_colors_object() + const { + return td_api::make_object( + vector(palette_colors_), vector(background_colors_), vector(story_colors_)); +} + +td_api::object_ptr +ThemeManager::ProfileAccentColors::get_update_profile_accent_colors_object() const { + FlatHashMap min_broadcast_boost_levels; + for (size_t i = 0; i < min_broadcast_boost_levels_.size(); i++) { + CHECK(i < accent_color_ids_.size()); + min_broadcast_boost_levels[accent_color_ids_[i]] = min_broadcast_boost_levels_[i]; + } + FlatHashMap min_megagroup_boost_levels; + for (size_t i = 0; i < min_megagroup_boost_levels_.size(); i++) { + CHECK(i < accent_color_ids_.size()); + min_megagroup_boost_levels[accent_color_ids_[i]] = min_megagroup_boost_levels_[i]; + } + vector> colors; + for (auto &it : light_colors_) { + auto light_colors = it.second.get_profile_accent_colors_object(); + auto dark_it = dark_colors_.find(it.first); + auto dark_colors = dark_it != dark_colors_.end() ? dark_it->second.get_profile_accent_colors_object() + : it.second.get_profile_accent_colors_object(); + colors.push_back(td_api::make_object( + it.first.get(), std::move(light_colors), std::move(dark_colors), min_megagroup_boost_levels[it.first], + min_broadcast_boost_levels[it.first])); + } + auto available_accent_color_ids = + transform(accent_color_ids_, [](AccentColorId accent_color_id) { return accent_color_id.get(); }); + return td_api::make_object(std::move(colors), + std::move(available_accent_color_ids)); +} + string ThemeManager::get_chat_themes_database_key() { return "chat_themes"; } +string ThemeManager::get_accent_colors_database_key() { + return "accent_colors"; +} + +string ThemeManager::get_profile_accent_colors_database_key() { + return "profile_accent_colors"; +} + void ThemeManager::save_chat_themes() { G()->td_db()->get_binlog_pmc()->set(get_chat_themes_database_key(), log_event_store(chat_themes_).as_slice().str()); } +void ThemeManager::save_accent_colors() { + G()->td_db()->get_binlog_pmc()->set(get_accent_colors_database_key(), + log_event_store(accent_colors_).as_slice().str()); +} + +void ThemeManager::save_profile_accent_colors() { + G()->td_db()->get_binlog_pmc()->set(get_profile_accent_colors_database_key(), + log_event_store(profile_accent_colors_).as_slice().str()); +} + void ThemeManager::send_update_chat_themes() const { send_closure(G()->td(), &Td::send_update, get_update_chat_themes_object()); } +void ThemeManager::send_update_accent_colors() const { + send_closure(G()->td(), &Td::send_update, get_update_accent_colors_object()); +} + +void ThemeManager::send_update_profile_accent_colors() const { + send_closure(G()->td(), &Td::send_update, get_update_profile_accent_colors_object()); +} + +void ThemeManager::reload_chat_themes() { + auto request_promise = PromiseCreator::lambda( + [actor_id = actor_id(this)](Result> result) { + send_closure(actor_id, &ThemeManager::on_get_chat_themes, std::move(result)); + }); + + td_->create_handler(std::move(request_promise))->send(chat_themes_.hash); +} + void ThemeManager::on_get_chat_themes(Result> result) { if (result.is_error()) { - set_timeout_in(Random::fast(40, 60)); return; } - chat_themes_.next_reload_time = Time::now() + THEME_CACHE_TIME; - set_timeout_at(chat_themes_.next_reload_time); - auto chat_themes_ptr = result.move_as_ok(); LOG(DEBUG) << "Receive " << to_string(chat_themes_ptr); if (chat_themes_ptr->get_id() == telegram_api::account_themesNotModified::ID) { @@ -356,11 +777,11 @@ void ThemeManager::on_get_chat_themes(Resultemoticon_); chat_theme.id = theme->id_; for (auto &settings : theme->settings_) { - auto theme_settings = get_chat_theme_settings(std::move(settings)); - if (theme_settings.message_colors.empty()) { + ThemeSettings theme_settings(td_, std::move(settings)); + if (theme_settings.is_empty()) { continue; } - if (is_dark_base_theme(theme_settings.base_theme)) { + if (theme_settings.are_dark()) { if (!was_dark) { was_dark = true; if (chat_theme.dark_theme != theme_settings) { @@ -376,7 +797,7 @@ void ThemeManager::on_get_chat_themes(Result &base_theme) { - CHECK(base_theme != nullptr); - switch (base_theme->get_id()) { - case telegram_api::baseThemeClassic::ID: - return BaseTheme::Classic; - case telegram_api::baseThemeDay::ID: - return BaseTheme::Day; - case telegram_api::baseThemeNight::ID: - return BaseTheme::Night; - case telegram_api::baseThemeTinted::ID: - return BaseTheme::Tinted; - case telegram_api::baseThemeArctic::ID: - return BaseTheme::Arctic; - default: - UNREACHABLE(); - return BaseTheme::Classic; - } -} - -ThemeManager::ThemeSettings ThemeManager::get_chat_theme_settings( - telegram_api::object_ptr settings) { - ThemeSettings result; - if (settings != nullptr && !settings->message_colors_.empty() && settings->message_colors_.size() <= 4) { - result.accent_color = settings->accent_color_; - bool has_outbox_accent_color = (settings->flags_ & telegram_api::themeSettings::OUTBOX_ACCENT_COLOR_MASK) != 0; - result.message_accent_color = (has_outbox_accent_color ? settings->outbox_accent_color_ : result.accent_color); - result.background_info = BackgroundInfo(td_, std::move(settings->wallpaper_)); - result.base_theme = get_base_theme(settings->base_theme_); - result.message_colors = std::move(settings->message_colors_); - result.animate_message_colors = settings->message_colors_animated_; +void ThemeManager::reload_accent_colors() { + auto request_promise = PromiseCreator::lambda( + [actor_id = actor_id(this)](Result> result) { + send_closure(actor_id, &ThemeManager::on_get_accent_colors, std::move(result)); + }); + + td_->create_handler(std::move(request_promise))->send(accent_colors_.hash_); +} + +void ThemeManager::on_get_accent_colors(Result> result) { + if (result.is_error()) { + return; + } + + auto peer_colors_ptr = result.move_as_ok(); + LOG(DEBUG) << "Receive " << to_string(peer_colors_ptr); + if (peer_colors_ptr->get_id() == telegram_api::help_peerColorsNotModified::ID) { + return; + } + CHECK(peer_colors_ptr->get_id() == telegram_api::help_peerColors::ID); + auto peer_colors = telegram_api::move_object_as(peer_colors_ptr); + FlatHashMap, AccentColorIdHash> light_colors; + FlatHashMap, AccentColorIdHash> dark_colors; + vector accent_color_ids; + vector min_broadcast_boost_levels; + vector min_megagroup_boost_levels; + for (auto &option : peer_colors->colors_) { + if ((option->colors_ != nullptr && option->colors_->get_id() != telegram_api::help_peerColorSet::ID) || + (option->dark_colors_ != nullptr && option->dark_colors_->get_id() != telegram_api::help_peerColorSet::ID)) { + LOG(ERROR) << "Receive " << to_string(option); + continue; + } + AccentColorId accent_color_id(option->color_id_); + if (!accent_color_id.is_valid() || td::contains(accent_color_ids, accent_color_id) || + (accent_color_id.is_built_in() && (option->colors_ != nullptr || option->dark_colors_ != nullptr)) || + (!accent_color_id.is_built_in() && option->colors_ == nullptr)) { + LOG(ERROR) << "Receive " << to_string(option); + continue; + } + bool is_valid = true; + vector current_light_colors; + vector current_dark_colors; + if (option->colors_ != nullptr) { + auto colors = telegram_api::move_object_as(option->colors_); + current_light_colors = std::move(colors->colors_); + if (!are_colors_valid(current_light_colors, 1, 3)) { + is_valid = false; + } + } + if (option->dark_colors_ != nullptr) { + auto colors = telegram_api::move_object_as(option->dark_colors_); + current_dark_colors = std::move(colors->colors_); + if (!are_colors_valid(current_dark_colors, 1, 3)) { + is_valid = false; + } + } + if (!is_valid) { + LOG(ERROR) << "Receive invalid colors for " << accent_color_id; + continue; + } + if (!option->hidden_) { + accent_color_ids.push_back(accent_color_id); + min_broadcast_boost_levels.push_back(max(0, option->channel_min_level_)); + min_megagroup_boost_levels.push_back(max(0, option->group_min_level_)); + } + if (!current_light_colors.empty()) { + light_colors[accent_color_id] = std::move(current_light_colors); + } + if (!current_dark_colors.empty()) { + dark_colors[accent_color_id] = std::move(current_dark_colors); + } + } + + bool is_changed = false; + if (accent_colors_.hash_ != peer_colors->hash_) { + accent_colors_.hash_ = peer_colors->hash_; + is_changed = true; + } + if (!on_update_accent_colors(std::move(light_colors), std::move(dark_colors), std::move(accent_color_ids), + std::move(min_broadcast_boost_levels), std::move(min_megagroup_boost_levels)) && + is_changed) { + save_accent_colors(); + } +} + +void ThemeManager::reload_profile_accent_colors() { + auto request_promise = PromiseCreator::lambda( + [actor_id = actor_id(this)](Result> result) { + send_closure(actor_id, &ThemeManager::on_get_profile_accent_colors, std::move(result)); + }); + + td_->create_handler(std::move(request_promise))->send(profile_accent_colors_.hash_); +} + +ThemeManager::ProfileAccentColor ThemeManager::get_profile_accent_color( + telegram_api::object_ptr &&color_set) const { + CHECK(color_set != nullptr); + CHECK(color_set->get_id() == telegram_api::help_peerColorProfileSet::ID); + auto colors = telegram_api::move_object_as(color_set); + ProfileAccentColor color; + color.palette_colors_ = std::move(colors->palette_colors_); + color.background_colors_ = std::move(colors->bg_colors_); + color.story_colors_ = std::move(colors->story_colors_); + return color; +} + +void ThemeManager::on_get_profile_accent_colors( + Result> result) { + if (result.is_error()) { + return; + } + + auto peer_colors_ptr = result.move_as_ok(); + LOG(DEBUG) << "Receive " << to_string(peer_colors_ptr); + if (peer_colors_ptr->get_id() == telegram_api::help_peerColorsNotModified::ID) { + return; + } + CHECK(peer_colors_ptr->get_id() == telegram_api::help_peerColors::ID); + auto peer_colors = telegram_api::move_object_as(peer_colors_ptr); + FlatHashMap light_colors; + FlatHashMap dark_colors; + vector accent_color_ids; + vector min_broadcast_boost_levels; + vector min_megagroup_boost_levels; + for (auto &option : peer_colors->colors_) { + AccentColorId accent_color_id(option->color_id_); + if (option->colors_ == nullptr || option->colors_->get_id() != telegram_api::help_peerColorProfileSet::ID || + option->dark_colors_ == nullptr || + option->dark_colors_->get_id() != telegram_api::help_peerColorProfileSet::ID || !accent_color_id.is_valid() || + td::contains(accent_color_ids, accent_color_id)) { + LOG(ERROR) << "Receive " << to_string(option); + continue; + } + auto current_light_color = get_profile_accent_color(std::move(option->colors_)); + auto current_dark_color = get_profile_accent_color(std::move(option->dark_colors_)); + if (!current_light_color.is_valid() || !current_dark_color.is_valid()) { + LOG(ERROR) << "Receive invalid colors for " << accent_color_id; + continue; + } + if (!option->hidden_) { + accent_color_ids.push_back(accent_color_id); + min_broadcast_boost_levels.push_back(max(0, option->channel_min_level_)); + min_megagroup_boost_levels.push_back(max(0, option->group_min_level_)); + } + light_colors[accent_color_id] = std::move(current_light_color); + dark_colors[accent_color_id] = std::move(current_dark_color); + } + + bool is_changed = false; + if (profile_accent_colors_.hash_ != peer_colors->hash_) { + profile_accent_colors_.hash_ = peer_colors->hash_; + is_changed = true; + } + if (!on_update_profile_accent_colors(std::move(light_colors), std::move(dark_colors), std::move(accent_color_ids), + std::move(min_broadcast_boost_levels), std::move(min_megagroup_boost_levels)) && + is_changed) { + save_profile_accent_colors(); } - return result; } void ThemeManager::get_current_state(vector> &updates) const { - if (!td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot() || chat_themes_.themes.empty()) { + if (!td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { return; } - updates.push_back(get_update_chat_themes_object()); + if (!chat_themes_.themes.empty()) { + updates.push_back(get_update_chat_themes_object()); + } + if (!accent_colors_.accent_color_ids_.empty()) { + updates.push_back(get_update_accent_colors_object()); + } + if (!profile_accent_colors_.accent_color_ids_.empty()) { + updates.push_back(get_update_profile_accent_colors_object()); + } } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ThemeManager.h b/protocols/Telegram/tdlib/td/td/telegram/ThemeManager.h index 831bc53d89..333e47ba03 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/ThemeManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/ThemeManager.h @@ -1,18 +1,20 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once -#include "td/telegram/BackgroundInfo.h" +#include "td/telegram/AccentColorId.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" +#include "td/telegram/ThemeSettings.h" #include "td/actor/actor.h" #include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" #include "td/utils/Promise.h" #include "td/utils/Status.h" @@ -28,36 +30,30 @@ class ThemeManager final : public Actor { void on_update_theme(telegram_api::object_ptr &&theme, Promise &&promise); - static string get_theme_parameters_json_string(const td_api::object_ptr &theme, - bool for_web_view); + void reload_chat_themes(); - void get_current_state(vector> &updates) const; + void reload_accent_colors(); - private: - // apeend-only - enum class BaseTheme : int32 { Classic, Day, Night, Tinted, Arctic }; + void reload_profile_accent_colors(); - static constexpr int32 THEME_CACHE_TIME = 3600; + static string get_theme_parameters_json_string(const td_api::object_ptr &theme); - struct ThemeSettings { - int32 accent_color = 0; - int32 message_accent_color = 0; - BackgroundInfo background_info; - BaseTheme base_theme = BaseTheme::Classic; - vector message_colors; - bool animate_message_colors = false; + int32 get_accent_color_id_object(AccentColorId accent_color_id, + AccentColorId fallback_accent_color_id = AccentColorId()) const; - template - void store(StorerT &storer) const; + int32 get_profile_accent_color_id_object(AccentColorId accent_color_id) const; - template - void parse(ParserT &parser); + struct DialogBoostAvailableCounts { + int32 title_color_count_ = 0; + int32 accent_color_count_ = 0; + int32 profile_accent_color_count_ = 0; + int32 chat_theme_count_ = 0; }; + DialogBoostAvailableCounts get_dialog_boost_available_count(int32 level, bool for_megagroup); - friend bool operator==(const ThemeSettings &lhs, const ThemeSettings &rhs); - - friend bool operator!=(const ThemeSettings &lhs, const ThemeSettings &rhs); + void get_current_state(vector> &updates) const; + private: struct ChatTheme { string emoji; int64 id = 0; @@ -73,7 +69,6 @@ class ThemeManager final : public Actor { struct ChatThemes { int64 hash = 0; - double next_reload_time = 0; vector themes; template @@ -83,17 +78,88 @@ class ThemeManager final : public Actor { void parse(ParserT &parser); }; - void start_up() final; + struct AccentColors { + FlatHashMap, AccentColorIdHash> light_colors_; + FlatHashMap, AccentColorIdHash> dark_colors_; + vector accent_color_ids_; + vector min_broadcast_boost_levels_; + vector min_megagroup_boost_levels_; + int32 hash_ = 0; + + td_api::object_ptr get_update_accent_colors_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct ProfileAccentColor { + vector palette_colors_; + vector background_colors_; + vector story_colors_; + + bool is_valid() const; + + td_api::object_ptr get_profile_accent_colors_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + friend bool operator==(const ProfileAccentColor &lhs, const ProfileAccentColor &rhs); + + friend bool operator!=(const ProfileAccentColor &lhs, const ProfileAccentColor &rhs); + + struct ProfileAccentColors { + FlatHashMap light_colors_; + FlatHashMap dark_colors_; + vector accent_color_ids_; + vector min_broadcast_boost_levels_; + vector min_megagroup_boost_levels_; + int32 hash_ = 0; + + td_api::object_ptr get_update_profile_accent_colors_object() const; + + template + void store(StorerT &storer) const; - void loop() final; + template + void parse(ParserT &parser); + }; + + void start_up() final; void tear_down() final; - static bool is_dark_base_theme(BaseTheme base_theme); + void load_chat_themes(); + + void load_accent_colors(); + + void load_profile_accent_colors(); void on_get_chat_themes(Result> result); - td_api::object_ptr get_theme_settings_object(const ThemeSettings &settings) const; + bool on_update_accent_colors(FlatHashMap, AccentColorIdHash> light_colors, + FlatHashMap, AccentColorIdHash> dark_colors, + vector accent_color_ids, vector min_broadcast_boost_levels, + vector min_megagroup_boost_levels); + + void on_get_accent_colors(Result> result); + + bool on_update_profile_accent_colors(FlatHashMap light_colors, + FlatHashMap dark_colors, + vector accent_color_ids, vector min_broadcast_boost_levels, + vector min_megagroup_boost_levels); + + ProfileAccentColor get_profile_accent_color( + telegram_api::object_ptr &&color_set) const; + + void on_get_profile_accent_colors(Result> result); td_api::object_ptr get_chat_theme_object(const ChatTheme &theme) const; @@ -101,16 +167,32 @@ class ThemeManager final : public Actor { static string get_chat_themes_database_key(); + string get_accent_colors_database_key(); + + string get_profile_accent_colors_database_key(); + void save_chat_themes(); + void save_accent_colors(); + + void save_profile_accent_colors(); + void send_update_chat_themes() const; - static BaseTheme get_base_theme(const telegram_api::object_ptr &base_theme); + td_api::object_ptr get_update_accent_colors_object() const; + + td_api::object_ptr get_update_profile_accent_colors_object() const; - ThemeSettings get_chat_theme_settings(telegram_api::object_ptr settings); + void send_update_accent_colors() const; + + void send_update_profile_accent_colors() const; ChatThemes chat_themes_; + AccentColors accent_colors_; + + ProfileAccentColors profile_accent_colors_; + Td *td_; ActorShared<> parent_; }; diff --git a/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.cpp b/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.cpp new file mode 100644 index 0000000000..0c2c48f910 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.cpp @@ -0,0 +1,46 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/ThemeSettings.h" + +namespace td { + +ThemeSettings::ThemeSettings(Td *td, telegram_api::object_ptr settings) { + if (settings != nullptr && !settings->message_colors_.empty() && settings->message_colors_.size() <= 4) { + accent_color_ = settings->accent_color_; + bool has_outbox_accent_color = (settings->flags_ & telegram_api::themeSettings::OUTBOX_ACCENT_COLOR_MASK) != 0; + message_accent_color_ = (has_outbox_accent_color ? settings->outbox_accent_color_ : accent_color_); + background_info_ = BackgroundInfo(td, std::move(settings->wallpaper_), true); + base_theme_ = get_base_theme(settings->base_theme_); + message_colors_ = std::move(settings->message_colors_); + animate_message_colors_ = settings->message_colors_animated_; + } +} + +td_api::object_ptr ThemeSettings::get_theme_settings_object(Td *td) const { + auto fill = [&]() -> td_api::object_ptr { + if (message_colors_.size() >= 3) { + return td_api::make_object(vector(message_colors_)); + } + CHECK(!message_colors_.empty()); + if (message_colors_.size() == 1 || message_colors_[0] == message_colors_[1]) { + return td_api::make_object(message_colors_[0]); + } + return td_api::make_object(message_colors_[1], message_colors_[0], 0); + }(); + + // ignore base_theme_ for now + return td_api::make_object(accent_color_, background_info_.get_background_object(td), + std::move(fill), animate_message_colors_, message_accent_color_); +} + +bool operator==(const ThemeSettings &lhs, const ThemeSettings &rhs) { + return lhs.accent_color_ == rhs.accent_color_ && lhs.message_accent_color_ == rhs.message_accent_color_ && + lhs.background_info_ == rhs.background_info_ && lhs.base_theme_ == rhs.base_theme_ && + lhs.message_colors_ == rhs.message_colors_ && lhs.animate_message_colors_ == rhs.animate_message_colors_; +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.h b/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.h new file mode 100644 index 0000000000..fb42915c0a --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.h @@ -0,0 +1,58 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/BackgroundInfo.h" +#include "td/telegram/BaseTheme.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" + +namespace td { + +class Td; + +class ThemeSettings { + int32 accent_color_ = 0; + int32 message_accent_color_ = 0; + BackgroundInfo background_info_; + BaseTheme base_theme_ = BaseTheme::Classic; + vector message_colors_; + bool animate_message_colors_ = false; + + friend bool operator==(const ThemeSettings &lhs, const ThemeSettings &rhs); + + public: + ThemeSettings() = default; + + ThemeSettings(Td *td, telegram_api::object_ptr settings); + + td_api::object_ptr get_theme_settings_object(Td *td) const; + + bool is_empty() const { + return message_colors_.empty(); + } + + bool are_dark() const { + return is_dark_base_theme(base_theme_); + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); +}; + +bool operator==(const ThemeSettings &lhs, const ThemeSettings &rhs); + +inline bool operator!=(const ThemeSettings &lhs, const ThemeSettings &rhs) { + return !(lhs == rhs); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.hpp b/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.hpp new file mode 100644 index 0000000000..7b91b859c7 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/ThemeSettings.hpp @@ -0,0 +1,59 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/ThemeSettings.h" + +#include "td/telegram/BackgroundInfo.hpp" + +#include "td/utils/tl_helpers.h" + +namespace td { + +template +void ThemeSettings::store(StorerT &storer) const { + bool has_message_accent_color = message_accent_color_ != accent_color_; + bool has_background = background_info_.is_valid(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(animate_message_colors_); + STORE_FLAG(has_message_accent_color); + STORE_FLAG(has_background); + END_STORE_FLAGS(); + td::store(accent_color_, storer); + if (has_message_accent_color) { + td::store(message_accent_color_, storer); + } + if (has_background) { + td::store(background_info_, storer); + } + td::store(base_theme_, storer); + td::store(message_colors_, storer); +} + +template +void ThemeSettings::parse(ParserT &parser) { + bool has_message_accent_color; + bool has_background; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(animate_message_colors_); + PARSE_FLAG(has_message_accent_color); + PARSE_FLAG(has_background); + END_PARSE_FLAGS(); + td::parse(accent_color_, parser); + if (has_message_accent_color) { + td::parse(message_accent_color_, parser); + } else { + message_accent_color_ = accent_color_; + } + if (has_background) { + td::parse(background_info_, parser); + } + td::parse(base_theme_, parser); + td::parse(message_colors_, parser); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TimeZoneManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/TimeZoneManager.cpp new file mode 100644 index 0000000000..939fdeac3d --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/TimeZoneManager.cpp @@ -0,0 +1,206 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/TimeZoneManager.h" + +#include "td/telegram/Global.h" +#include "td/telegram/logevent/LogEvent.h" +#include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +class GetTimezonesListQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetTimezonesListQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(int32 hash) { + send_query(G()->net_query_creator().create(telegram_api::help_getTimezonesList(hash))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(result_ptr.move_as_ok()); + } + + void on_error(Status status) final { + if (!G()->is_expected_error(status)) { + LOG(ERROR) << "GetTimezonesListQuery returned " << status; + } + promise_.set_error(std::move(status)); + } +}; + +TimeZoneManager::TimeZone::TimeZone(string &&id, string &&name, int32 utc_offset) + : id_(std::move(id)), name_(std::move(name)), utc_offset_(utc_offset) { +} + +td_api::object_ptr TimeZoneManager::TimeZone::get_time_zone_object() const { + return td_api::make_object(id_, name_, utc_offset_); +} + +bool operator==(const TimeZoneManager::TimeZone &lhs, const TimeZoneManager::TimeZone &rhs) { + return lhs.id_ == rhs.id_ && lhs.name_ == rhs.name_ && lhs.utc_offset_ == rhs.utc_offset_; +} + +bool operator!=(const TimeZoneManager::TimeZone &lhs, const TimeZoneManager::TimeZone &rhs) { + return !(lhs == rhs); +} + +template +void TimeZoneManager::TimeZone::store(StorerT &storer) const { + BEGIN_STORE_FLAGS(); + END_STORE_FLAGS(); + td::store(id_, storer); + td::store(name_, storer); + td::store(utc_offset_, storer); +} + +template +void TimeZoneManager::TimeZone::parse(ParserT &parser) { + BEGIN_PARSE_FLAGS(); + END_PARSE_FLAGS(); + td::parse(id_, parser); + td::parse(name_, parser); + td::parse(utc_offset_, parser); +} + +td_api::object_ptr TimeZoneManager::TimeZoneList::get_time_zones_object() const { + return td_api::make_object( + transform(time_zones_, [](const TimeZone &time_zone) { return time_zone.get_time_zone_object(); })); +} + +template +void TimeZoneManager::TimeZoneList::store(StorerT &storer) const { + td::store(time_zones_, storer); + td::store(hash_, storer); +} + +template +void TimeZoneManager::TimeZoneList::parse(ParserT &parser) { + td::parse(time_zones_, parser); + td::parse(hash_, parser); + is_loaded_ = true; +} + +TimeZoneManager::TimeZoneManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { +} + +TimeZoneManager::~TimeZoneManager() = default; + +void TimeZoneManager::tear_down() { + parent_.reset(); +} + +int32 TimeZoneManager::get_time_zone_offset(const string &time_zone_id) { + load_time_zones(); + for (auto &time_zone : time_zones_.time_zones_) { + if (time_zone.id_ == time_zone_id) { + return time_zone.utc_offset_; + } + } + return narrow_cast(G()->get_option_integer("utc_time_offset")); +} + +void TimeZoneManager::get_time_zones(Promise> &&promise) { + load_time_zones(); + if (time_zones_.hash_ != 0) { + return promise.set_value(time_zones_.get_time_zones_object()); + } + reload_time_zones(std::move(promise)); +} + +void TimeZoneManager::reload_time_zones(Promise> &&promise) { + load_time_zones(); + get_time_zones_queries_.push_back(std::move(promise)); + if (get_time_zones_queries_.size() == 1) { + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this)](Result> &&r_time_zones) { + send_closure(actor_id, &TimeZoneManager::on_get_time_zones, std::move(r_time_zones)); + }); + td_->create_handler(std::move(query_promise))->send(time_zones_.hash_); + } +} + +void TimeZoneManager::on_get_time_zones( + Result> &&r_time_zones) { + G()->ignore_result_if_closing(r_time_zones); + if (r_time_zones.is_error()) { + return fail_promises(get_time_zones_queries_, r_time_zones.move_as_error()); + } + + auto time_zones_ptr = r_time_zones.move_as_ok(); + switch (time_zones_ptr->get_id()) { + case telegram_api::help_timezonesListNotModified::ID: + break; + case telegram_api::help_timezonesList::ID: { + auto zone_list = telegram_api::move_object_as(time_zones_ptr); + vector time_zones; + for (auto &time_zone : zone_list->timezones_) { + time_zones.emplace_back(std::move(time_zone->id_), std::move(time_zone->name_), time_zone->utc_offset_); + } + if (time_zones_.time_zones_ != time_zones || time_zones_.hash_ != zone_list->hash_) { + time_zones_.time_zones_ = std::move(time_zones); + time_zones_.hash_ = zone_list->hash_; + save_time_zones(); + } + break; + } + default: + UNREACHABLE(); + } + time_zones_.is_loaded_ = true; + + auto promises = std::move(get_time_zones_queries_); + reset_to_empty(get_time_zones_queries_); + for (auto &promise : promises) { + if (promise) { + promise.set_value(time_zones_.get_time_zones_object()); + } + } +} + +string TimeZoneManager::get_time_zones_database_key() { + return "time_zones"; +} + +void TimeZoneManager::load_time_zones() { + if (time_zones_.is_loaded_) { + return; + } + time_zones_.is_loaded_ = true; + + auto log_event_string = G()->td_db()->get_binlog_pmc()->get(get_time_zones_database_key()); + if (log_event_string.empty()) { + return; + } + auto status = log_event_parse(time_zones_, log_event_string); + if (status.is_error()) { + LOG(ERROR) << "Failed to parse time zones from binlog: " << status; + time_zones_ = TimeZoneList(); + } +} + +void TimeZoneManager::save_time_zones() { + G()->td_db()->get_binlog_pmc()->set(get_time_zones_database_key(), log_event_store(time_zones_).as_slice().str()); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TimeZoneManager.h b/protocols/Telegram/tdlib/td/td/telegram/TimeZoneManager.h new file mode 100644 index 0000000000..0fe9ae8b18 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/TimeZoneManager.h @@ -0,0 +1,91 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/actor/actor.h" + +#include "td/utils/common.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" + +namespace td { + +class Td; + +class TimeZoneManager final : public Actor { + public: + TimeZoneManager(Td *td, ActorShared<> parent); + TimeZoneManager(const TimeZoneManager &) = delete; + TimeZoneManager &operator=(const TimeZoneManager &) = delete; + TimeZoneManager(TimeZoneManager &&) = delete; + TimeZoneManager &operator=(TimeZoneManager &&) = delete; + ~TimeZoneManager() final; + + int32 get_time_zone_offset(const string &time_zone_id); + + void get_time_zones(Promise> &&promise); + + void reload_time_zones(Promise> &&promise); + + private: + void tear_down() final; + + struct TimeZone { + string id_; + string name_; + int32 utc_offset_ = 0; + + TimeZone() = default; + TimeZone(string &&id, string &&name, int32 utc_offset); + + td_api::object_ptr get_time_zone_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct TimeZoneList { + vector time_zones_; + int32 hash_ = 0; + bool is_loaded_ = false; + + td_api::object_ptr get_time_zones_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + friend bool operator==(const TimeZone &lhs, const TimeZone &rhs); + + friend bool operator!=(const TimeZone &lhs, const TimeZone &rhs); + + void on_get_time_zones(Result> &&r_time_zones); + + static string get_time_zones_database_key(); + + void load_time_zones(); + + void save_time_zones(); + + vector>> get_time_zones_queries_; + + TimeZoneList time_zones_; + + Td *td_; + ActorShared<> parent_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TopDialogCategory.cpp b/protocols/Telegram/tdlib/td/td/telegram/TopDialogCategory.cpp index 59e3ba9506..70cb794ece 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TopDialogCategory.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/TopDialogCategory.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -26,6 +26,8 @@ CSlice get_top_dialog_category_name(TopDialogCategory category) { return CSlice("forward_users"); case TopDialogCategory::ForwardChats: return CSlice("forward_chats"); + case TopDialogCategory::BotApp: + return CSlice("bot_app"); default: UNREACHABLE(); return CSlice(); @@ -51,6 +53,8 @@ TopDialogCategory get_top_dialog_category(const td_api::object_ptr get_input_top_peer_categ return make_tl_object(); case TopDialogCategory::ForwardChats: return make_tl_object(); + case TopDialogCategory::BotApp: + return make_tl_object(); default: UNREACHABLE(); return nullptr; diff --git a/protocols/Telegram/tdlib/td/td/telegram/TopDialogCategory.h b/protocols/Telegram/tdlib/td/td/telegram/TopDialogCategory.h index 43bd562385..6bcec0d2c6 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TopDialogCategory.h +++ b/protocols/Telegram/tdlib/td/td/telegram/TopDialogCategory.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -23,6 +23,7 @@ enum class TopDialogCategory : int32 { Call, ForwardUsers, ForwardChats, + BotApp, Size }; diff --git a/protocols/Telegram/tdlib/td/td/telegram/TopDialogManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/TopDialogManager.cpp index 0f3d995dda..d2dafbf451 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TopDialogManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/TopDialogManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,17 +8,19 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/AuthManager.h" -#include "td/telegram/ContactsManager.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Global.h" #include "td/telegram/logevent/LogEvent.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/misc.h" -#include "td/telegram/net/NetQuery.h" #include "td/telegram/net/NetQueryDispatcher.h" #include "td/telegram/StateManager.h" #include "td/telegram/Td.h" #include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserManager.h" #include "td/actor/PromiseFuture.h" @@ -50,10 +52,12 @@ class GetTopPeersQuery final : public Td::ResultHandler { telegram_api::contacts_getTopPeers::CORRESPONDENTS_MASK | telegram_api::contacts_getTopPeers::BOTS_PM_MASK | telegram_api::contacts_getTopPeers::BOTS_INLINE_MASK | telegram_api::contacts_getTopPeers::GROUPS_MASK | telegram_api::contacts_getTopPeers::CHANNELS_MASK | telegram_api::contacts_getTopPeers::PHONE_CALLS_MASK | - telegram_api::contacts_getTopPeers::FORWARD_USERS_MASK | telegram_api::contacts_getTopPeers::FORWARD_CHATS_MASK; - send_query(G()->net_query_creator().create(telegram_api::contacts_getTopPeers( - flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, 0 /*offset*/, 100 /*limit*/, hash))); + telegram_api::contacts_getTopPeers::FORWARD_USERS_MASK | + telegram_api::contacts_getTopPeers::FORWARD_CHATS_MASK | telegram_api::contacts_getTopPeers::BOTS_APP_MASK; + send_query(G()->net_query_creator().create( + telegram_api::contacts_getTopPeers(flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, 0 /*offset*/, 100 /*limit*/, hash))); } void on_result(BufferSlice packet) final { @@ -100,12 +104,10 @@ class ResetTopPeerRatingQuery final : public Td::ResultHandler { public: void send(TopDialogCategory category, DialogId dialog_id) { - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id, AccessRights::Read); - if (input_peer == nullptr) { - return; - } - dialog_id_ = dialog_id; + + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id, AccessRights::Read); + CHECK(input_peer != nullptr); send_query(G()->net_query_creator().create( telegram_api::contacts_resetTopPeerRating(get_input_top_peer_category(category), std::move(input_peer)))); } @@ -120,7 +122,7 @@ class ResetTopPeerRatingQuery final : public Td::ResultHandler { } void on_error(Status status) final { - if (!td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "ResetTopPeerRatingQuery")) { + if (!td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "ResetTopPeerRatingQuery")) { LOG(INFO) << "Receive error for ResetTopPeerRatingQuery: " << status; } } @@ -196,7 +198,8 @@ void TopDialogManager::on_toggle_top_peers(bool is_enabled, Result &&resul } void TopDialogManager::on_dialog_used(TopDialogCategory category, DialogId dialog_id, int32 date) { - if (!is_active_ || !is_enabled_) { + CHECK(!td_->auth_manager_->is_bot()); + if (!is_enabled_) { return; } auto pos = static_cast(category); @@ -236,10 +239,10 @@ void TopDialogManager::remove_dialog(TopDialogCategory category, DialogId dialog if (category == TopDialogCategory::Size) { return promise.set_error(Status::Error(400, "Top chat category must be non-empty")); } - if (!td_->messages_manager_->have_dialog_force(dialog_id, "remove_dialog")) { - return promise.set_error(Status::Error(400, "Chat not found")); - } - if (!is_active_ || !is_enabled_) { + TRY_STATUS_PROMISE(promise, + td_->dialog_manager_->check_dialog_access(dialog_id, false, AccessRights::Read, "remove_dialog")); + CHECK(!td_->auth_manager_->is_bot()); + if (!is_enabled_) { return promise.set_value(Unit()); } @@ -276,11 +279,8 @@ void TopDialogManager::get_top_dialogs(TopDialogCategory category, int32 limit, if (limit <= 0) { return promise.set_error(Status::Error(400, "Limit must be positive")); } - if (!is_active_) { - return promise.set_error(Status::Error(400, "Not supported without chat info database")); - } if (!is_enabled_) { - return promise.set_error(Status::Error(400, "Top chats computation is disabled")); + return promise.set_error(Status::Error(400, "Top chat computation is disabled")); } GetTopDialogsQuery query; @@ -291,8 +291,29 @@ void TopDialogManager::get_top_dialogs(TopDialogCategory category, int32 limit, loop(); } +int TopDialogManager::is_top_dialog(TopDialogCategory category, size_t limit, DialogId dialog_id) const { + CHECK(category != TopDialogCategory::Size); + CHECK(category != TopDialogCategory::ForwardUsers); + CHECK(limit > 0); + CHECK(!td_->auth_manager_->is_bot()); + if (!is_enabled_) { + return 0; + } + + vector dialog_ids; + auto pos = static_cast(category); + CHECK(pos < by_category_.size()); + const auto &dialogs = by_category_[pos].dialogs; + for (size_t i = 0; i < limit && i < dialogs.size(); i++) { + if (dialogs[i].dialog_id == dialog_id) { + return 1; + } + } + return is_synchronized_ ? 0 : -1; +} + void TopDialogManager::update_rating_e_decay() { - if (!is_active_) { + if (td_->auth_manager_->is_bot()) { return; } rating_e_decay_ = narrow_cast(G()->get_option_integer("rating_e_decay", rating_e_decay_)); @@ -330,14 +351,15 @@ double TopDialogManager::rating_add(double now, double rating_timestamp) const { return std::exp((now - rating_timestamp) / rating_e_decay_); } -double TopDialogManager::current_rating_add(double rating_timestamp) const { - return rating_add(G()->server_time_cached(), rating_timestamp); +double TopDialogManager::current_rating_add(double server_time, double rating_timestamp) const { + return rating_add(server_time, rating_timestamp); } void TopDialogManager::normalize_rating() { + auto server_time = G()->server_time(); for (auto &top_dialogs : by_category_) { - auto div_by = current_rating_add(top_dialogs.rating_timestamp); - top_dialogs.rating_timestamp = G()->server_time_cached(); + auto div_by = current_rating_add(server_time, top_dialogs.rating_timestamp); + top_dialogs.rating_timestamp = server_time; for (auto &dialog : top_dialogs.dialogs) { dialog.rating /= div_by; } @@ -385,16 +407,16 @@ void TopDialogManager::on_load_dialogs(GetTopDialogsQuery &&query, vectorcontacts_manager_->is_user_deleted(user_id)) { + if (td_->user_manager_->is_user_deleted(user_id)) { LOG(INFO) << "Skip deleted " << user_id; continue; } - if (td_->contacts_manager_->get_my_id() == user_id) { + if (td_->user_manager_->get_my_id() == user_id) { LOG(INFO) << "Skip self " << user_id; continue; } if (query.category == TopDialogCategory::BotInline || query.category == TopDialogCategory::BotPM) { - auto r_bot_info = td_->contacts_manager_->get_bot_data(user_id); + auto r_bot_info = td_->user_manager_->get_bot_data(user_id); if (r_bot_info.is_error()) { LOG(INFO) << "Skip not a bot " << user_id; continue; @@ -414,7 +436,7 @@ void TopDialogManager::on_load_dialogs(GetTopDialogsQuery &&query, vectormessages_manager_->get_chats_object(-1, std::move(result), "TopDialogManager::on_load_dialogs")); + td_->dialog_manager_->get_chats_object(-1, std::move(result), "TopDialogManager::on_load_dialogs")); } void TopDialogManager::do_get_top_peers() { @@ -455,6 +477,7 @@ void TopDialogManager::on_get_top_peers(Result(std::move(top_peers_parent)); - td_->contacts_manager_->on_get_users(std::move(top_peers->users_), "on get top chats"); - td_->contacts_manager_->on_get_chats(std::move(top_peers->chats_), "on get top chats"); + td_->user_manager_->on_get_users(std::move(top_peers->users_), "on get top chats"); + td_->chat_manager_->on_get_chats(std::move(top_peers->chats_), "on get top chats"); for (auto &category : top_peers->categories_) { auto dialog_category = get_top_dialog_category(category->category_); auto pos = static_cast(dialog_category); @@ -502,16 +525,17 @@ void TopDialogManager::on_get_top_peers(Resulttd_db()->get_binlog_pmc()->set(key, log_event_store(top_dialogs).as_slice().str()); + if (G()->use_chat_info_database()) { + auto top_dialog_category = TopDialogCategory(top_dialog_category_i); + auto key = PSTRING() << "top_dialogs#" << get_top_dialog_category_name(top_dialog_category); + G()->td_db()->get_binlog_pmc()->set(key, log_event_store(top_dialogs).as_slice().str()); + } } db_sync_state_ = SyncState::Ok; first_unsync_change_ = Timestamp(); @@ -530,7 +554,6 @@ void TopDialogManager::init() { return; } - is_active_ = G()->use_chat_info_database() && !td_->auth_manager_->is_bot(); is_enabled_ = !G()->get_option_boolean("disable_top_chats"); update_rating_e_decay(); @@ -548,23 +571,23 @@ void TopDialogManager::try_start() { first_unsync_change_ = Timestamp(); server_sync_state_ = SyncState::None; last_server_sync_ = Timestamp(); - CHECK(pending_get_top_dialogs_.empty()); - LOG(DEBUG) << "Init is enabled: " << is_enabled_; - if (!is_active_) { - G()->td_db()->get_binlog_pmc()->erase_by_prefix("top_dialogs"); + if (td_->auth_manager_->is_bot()) { return; } + LOG(DEBUG) << "Init is enabled: " << is_enabled_; + auto di_top_dialogs_ts = G()->td_db()->get_binlog_pmc()->get("top_dialogs_ts"); if (!di_top_dialogs_ts.empty()) { last_server_sync_ = Timestamp::in(to_integer(di_top_dialogs_ts) - Clocks::system()); if (last_server_sync_.is_in_past()) { server_sync_state_ = SyncState::Ok; } + is_synchronized_ = G()->use_chat_info_database(); } - if (is_enabled_) { + if (is_enabled_ && G()->use_chat_info_database()) { for (size_t top_dialog_category_i = 0; top_dialog_category_i < by_category_.size(); top_dialog_category_i++) { auto top_dialog_category = TopDialogCategory(top_dialog_category_i); auto key = PSTRING() << "top_dialogs#" << get_top_dialog_category_name(top_dialog_category); @@ -581,9 +604,7 @@ void TopDialogManager::try_start() { } else { G()->td_db()->get_binlog_pmc()->erase_by_prefix("top_dialogs#"); for (auto &top_dialogs : by_category_) { - top_dialogs.is_dirty = false; - top_dialogs.rating_timestamp = 0; - top_dialogs.dialogs.clear(); + top_dialogs = {}; } } db_sync_state_ = SyncState::Ok; @@ -594,19 +615,15 @@ void TopDialogManager::try_start() { void TopDialogManager::on_first_sync() { was_first_sync_ = true; - if (!G()->close_flag() && td_->auth_manager_->is_bot()) { - is_active_ = false; - try_start(); - } loop(); } void TopDialogManager::loop() { - if (!is_active_ || G()->close_flag()) { + if (G()->close_flag() || td_->auth_manager_->is_bot()) { return; } - if (!pending_get_top_dialogs_.empty()) { + if (!pending_get_top_dialogs_.empty() && (is_synchronized_ || !is_enabled_)) { for (auto &query : pending_get_top_dialogs_) { do_get_top_dialogs(std::move(query)); } @@ -616,7 +633,8 @@ void TopDialogManager::loop() { // server sync Timestamp server_sync_timeout; if (server_sync_state_ == SyncState::Ok) { - server_sync_timeout = Timestamp::at(last_server_sync_.at() + SERVER_SYNC_DELAY); + server_sync_timeout = pending_get_top_dialogs_.empty() ? Timestamp::at(last_server_sync_.at() + SERVER_SYNC_DELAY) + : Timestamp::now_cached(); if (server_sync_timeout.is_in_past()) { server_sync_state_ = SyncState::None; } @@ -625,7 +643,7 @@ void TopDialogManager::loop() { Timestamp wakeup_timeout; if (server_sync_state_ == SyncState::Ok) { wakeup_timeout.relax(server_sync_timeout); - } else if (server_sync_state_ == SyncState::None && was_first_sync_) { + } else if (server_sync_state_ == SyncState::None && (was_first_sync_ || !pending_get_top_dialogs_.empty())) { server_sync_state_ = SyncState::Pending; do_get_top_peers(); } diff --git a/protocols/Telegram/tdlib/td/td/telegram/TopDialogManager.h b/protocols/Telegram/tdlib/td/td/telegram/TopDialogManager.h index afb35a5e45..347c61e35a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TopDialogManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/TopDialogManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -37,6 +37,8 @@ class TopDialogManager final : public Actor { void get_top_dialogs(TopDialogCategory category, int32 limit, Promise> &&promise); + int is_top_dialog(TopDialogCategory category, size_t limit, DialogId dialog_id) const; + void update_rating_e_decay(); void update_is_enabled(bool is_enabled); @@ -50,8 +52,8 @@ class TopDialogManager final : public Actor { Td *td_; ActorShared<> parent_; - bool is_active_ = false; bool is_enabled_ = true; + bool is_synchronized_ = false; int32 rating_e_decay_ = 241920; bool have_toggle_top_peers_query_ = false; @@ -96,7 +98,7 @@ class TopDialogManager final : public Actor { std::array(TopDialogCategory::Size)> by_category_; double rating_add(double now, double rating_timestamp) const; - double current_rating_add(double rating_timestamp) const; + double current_rating_add(double server_time, double rating_timestamp) const; void normalize_rating(); bool set_is_enabled(bool is_enabled); diff --git a/protocols/Telegram/tdlib/td/td/telegram/TranscriptionInfo.cpp b/protocols/Telegram/tdlib/td/td/telegram/TranscriptionInfo.cpp index 8258182183..16c802516f 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TranscriptionInfo.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/TranscriptionInfo.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,8 +8,8 @@ #include "td/telegram/AccessRights.h" #include "td/telegram/DialogId.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/Global.h" -#include "td/telegram/MessagesManager.h" #include "td/telegram/Td.h" #include "td/telegram/telegram_api.h" @@ -20,19 +20,21 @@ namespace td { class TranscribeAudioQuery final : public Td::ResultHandler { DialogId dialog_id_; - std::function>)> handler_; + std::function>)> handler_; public: - void send(FullMessageId full_message_id, - std::function>)> &&handler) { - dialog_id_ = full_message_id.get_dialog_id(); + void send(MessageFullId message_full_id, + std::function>)> &&handler) { + dialog_id_ = message_full_id.get_dialog_id(); handler_ = std::move(handler); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } - send_query(G()->net_query_creator().create(telegram_api::messages_transcribeAudio( - std::move(input_peer), full_message_id.get_message_id().get_server_message_id().get()))); + auto query = G()->net_query_creator().create(telegram_api::messages_transcribeAudio( + std::move(input_peer), message_full_id.get_message_id().get_server_message_id().get())); + query->total_timeout_limit_ = 8; + send_query(std::move(query)); } void on_result(BufferSlice packet) final { @@ -43,18 +45,11 @@ class TranscribeAudioQuery final : public Td::ResultHandler { auto result = result_ptr.move_as_ok(); LOG(INFO) << "Receive result for TranscribeAudioQuery: " << to_string(result); - if (result->transcription_id_ == 0) { - return on_error(Status::Error(500, "Receive no recognition identifier")); - } - auto update = telegram_api::make_object(); - update->text_ = std::move(result->text_); - update->transcription_id_ = result->transcription_id_; - update->pending_ = result->pending_; - handler_(std::move(update)); + handler_(std::move(result)); } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "TranscribeAudioQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "TranscribeAudioQuery"); handler_(std::move(status)); } }; @@ -67,14 +62,14 @@ class RateTranscribedAudioQuery final : public Td::ResultHandler { explicit RateTranscribedAudioQuery(Promise &&promise) : promise_(std::move(promise)) { } - void send(FullMessageId full_message_id, int64 transcription_id, bool is_good) { - dialog_id_ = full_message_id.get_dialog_id(); - auto input_peer = td_->messages_manager_->get_input_peer(dialog_id_, AccessRights::Read); + void send(MessageFullId message_full_id, int64 transcription_id, bool is_good) { + dialog_id_ = message_full_id.get_dialog_id(); + auto input_peer = td_->dialog_manager_->get_input_peer(dialog_id_, AccessRights::Read); if (input_peer == nullptr) { return on_error(Status::Error(400, "Can't access the chat")); } send_query(G()->net_query_creator().create(telegram_api::messages_rateTranscribedAudio( - std::move(input_peer), full_message_id.get_message_id().get_server_message_id().get(), transcription_id, + std::move(input_peer), message_full_id.get_message_id().get_server_message_id().get(), transcription_id, is_good))); } @@ -90,14 +85,14 @@ class RateTranscribedAudioQuery final : public Td::ResultHandler { } void on_error(Status status) final { - td_->messages_manager_->on_get_dialog_error(dialog_id_, status, "RateTranscribedAudioQuery"); + td_->dialog_manager_->on_get_dialog_error(dialog_id_, status, "RateTranscribedAudioQuery"); promise_.set_error(std::move(status)); } }; bool TranscriptionInfo::recognize_speech( - Td *td, FullMessageId full_message_id, Promise &&promise, - std::function>)> &&handler) { + Td *td, MessageFullId message_full_id, Promise &&promise, + std::function>)> &&handler) { if (is_transcribed_) { promise.set_value(Unit()); return false; @@ -105,7 +100,7 @@ bool TranscriptionInfo::recognize_speech( speech_recognition_queries_.push_back(std::move(promise)); if (speech_recognition_queries_.size() == 1) { last_transcription_error_ = Status::OK(); - td->create_handler()->send(full_message_id, std::move(handler)); + td->create_handler()->send(message_full_id, std::move(handler)); return true; } return false; @@ -151,13 +146,13 @@ vector> TranscriptionInfo::on_failed_transcription(Status &&error) return promises; } -void TranscriptionInfo::rate_speech_recognition(Td *td, FullMessageId full_message_id, bool is_good, +void TranscriptionInfo::rate_speech_recognition(Td *td, MessageFullId message_full_id, bool is_good, Promise &&promise) const { if (!is_transcribed_) { return promise.set_value(Unit()); } CHECK(transcription_id_ != 0); - td->create_handler(std::move(promise))->send(full_message_id, transcription_id_, is_good); + td->create_handler(std::move(promise))->send(message_full_id, transcription_id_, is_good); } unique_ptr TranscriptionInfo::copy_if_transcribed(const unique_ptr &info) { diff --git a/protocols/Telegram/tdlib/td/td/telegram/TranscriptionInfo.h b/protocols/Telegram/tdlib/td/td/telegram/TranscriptionInfo.h index 2a2bfedcd7..5e981b24d4 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TranscriptionInfo.h +++ b/protocols/Telegram/tdlib/td/td/telegram/TranscriptionInfo.h @@ -1,12 +1,12 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #pragma once -#include "td/telegram/FullMessageId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" @@ -35,8 +35,8 @@ class TranscriptionInfo { } bool recognize_speech( - Td *td, FullMessageId full_message_id, Promise &&promise, - std::function>)> &&handler); + Td *td, MessageFullId message_full_id, Promise &&promise, + std::function>)> &&handler); vector> on_final_transcription(string &&text, int64 transcription_id); @@ -44,7 +44,7 @@ class TranscriptionInfo { vector> on_failed_transcription(Status &&error); - void rate_speech_recognition(Td *td, FullMessageId full_message_id, bool is_good, Promise &&promise) const; + void rate_speech_recognition(Td *td, MessageFullId message_full_id, bool is_good, Promise &&promise) const; static unique_ptr copy_if_transcribed(const unique_ptr &info); diff --git a/protocols/Telegram/tdlib/td/td/telegram/TranscriptionManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/TranscriptionManager.cpp new file mode 100644 index 0000000000..1c362db524 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/TranscriptionManager.cpp @@ -0,0 +1,444 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/TranscriptionManager.h" + +#include "td/telegram/AuthManager.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/Global.h" +#include "td/telegram/logevent/LogEvent.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/VideoNotesManager.h" +#include "td/telegram/VoiceNotesManager.h" + +#include "td/utils/logging.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +void TranscriptionManager::TrialParameters::update_left_tries() { + if (next_reset_date_ <= G()->unix_time()) { + next_reset_date_ = 0; + left_tries_ = weekly_number_; + } else if (left_tries_ > weekly_number_) { + left_tries_ = weekly_number_; + } +} + +template +void TranscriptionManager::TrialParameters::store(StorerT &storer) const { + bool has_weekly_number = weekly_number_ != 0; + bool has_duration_max = duration_max_ != 0; + bool has_left_tries = left_tries_ != 0; + bool has_next_reset_date = next_reset_date_ != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_weekly_number); + STORE_FLAG(has_duration_max); + STORE_FLAG(has_left_tries); + STORE_FLAG(has_next_reset_date); + END_STORE_FLAGS(); + if (has_weekly_number) { + td::store(weekly_number_, storer); + } + if (has_duration_max) { + td::store(duration_max_, storer); + } + if (has_left_tries) { + td::store(left_tries_, storer); + } + if (has_next_reset_date) { + td::store(next_reset_date_, storer); + } +} + +template +void TranscriptionManager::TrialParameters::parse(ParserT &parser) { + bool has_weekly_number; + bool has_duration_max; + bool has_left_tries; + bool has_next_reset_date; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_weekly_number); + PARSE_FLAG(has_duration_max); + PARSE_FLAG(has_left_tries); + PARSE_FLAG(has_next_reset_date); + END_PARSE_FLAGS(); + if (has_weekly_number) { + td::parse(weekly_number_, parser); + } + if (has_duration_max) { + td::parse(duration_max_, parser); + } + if (has_left_tries) { + td::parse(left_tries_, parser); + } + if (has_next_reset_date) { + td::parse(next_reset_date_, parser); + } +} + +bool operator==(const TranscriptionManager::TrialParameters &lhs, const TranscriptionManager::TrialParameters &rhs) { + return lhs.weekly_number_ == rhs.weekly_number_ && lhs.duration_max_ == rhs.duration_max_ && + lhs.left_tries_ == rhs.left_tries_ && lhs.next_reset_date_ == rhs.next_reset_date_; +} + +TranscriptionManager::TranscriptionManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { + load_trial_parameters(); + + pending_audio_transcription_timeout_.set_callback(on_pending_audio_transcription_timeout_callback); + pending_audio_transcription_timeout_.set_callback_data(static_cast(td_)); +} + +TranscriptionManager::~TranscriptionManager() { + Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), voice_messages_, message_file_ids_); +} + +void TranscriptionManager::tear_down() { + parent_.reset(); +} + +void TranscriptionManager::on_pending_audio_transcription_timeout_callback(void *td, int64 transcription_id) { + if (G()->close_flag()) { + return; + } + CHECK(td != nullptr); + if (!static_cast(td)->auth_manager_->is_authorized()) { + return; + } + + auto transcription_manager = static_cast(td)->transcription_manager_.get(); + send_closure_later(transcription_manager->actor_id(transcription_manager), + &TranscriptionManager::on_pending_audio_transcription_failed, transcription_id, + Status::Error(500, "Timeout expired")); +} + +string TranscriptionManager::get_trial_parameters_database_key() { + return "speech_recognition_trial"; +} + +void TranscriptionManager::load_trial_parameters() { + if (!td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { + return; + } + + auto log_event_string = G()->td_db()->get_binlog_pmc()->get(get_trial_parameters_database_key()); + if (!log_event_string.empty()) { + auto status = log_event_parse(trial_parameters_, log_event_string); + if (status.is_ok()) { + trial_parameters_.update_left_tries(); + } else { + LOG(ERROR) << "Failed to parse speech recognition trial parameters from binlog: " << status; + trial_parameters_ = TrialParameters(); + save_trial_parameters(); + } + } + send_update_speech_recognition_trial(); + set_speech_recognition_trial_timeout(); +} + +void TranscriptionManager::save_trial_parameters() { + G()->td_db()->get_binlog_pmc()->set(get_trial_parameters_database_key(), + log_event_store(trial_parameters_).as_slice().str()); +} + +void TranscriptionManager::on_update_trial_parameters(int32 weekly_number, int32 duration_max, int32 cooldown_until) { + if (!td_->auth_manager_->is_authorized()) { + return; + } + CHECK(!td_->auth_manager_->is_bot()); + TrialParameters new_trial_parameters; + new_trial_parameters.weekly_number_ = max(0, weekly_number); + new_trial_parameters.duration_max_ = max(0, duration_max); + new_trial_parameters.next_reset_date_ = cooldown_until > 0 ? cooldown_until : trial_parameters_.next_reset_date_; + new_trial_parameters.left_tries_ = trial_parameters_.left_tries_; + set_trial_parameters(new_trial_parameters); +} + +void TranscriptionManager::set_trial_parameters(TrialParameters new_trial_parameters) { + new_trial_parameters.update_left_tries(); + if (new_trial_parameters == trial_parameters_) { + return; + } + + trial_parameters_ = std::move(new_trial_parameters); + send_update_speech_recognition_trial(); + set_speech_recognition_trial_timeout(); + save_trial_parameters(); +} + +void TranscriptionManager::set_speech_recognition_trial_timeout() { + if (trial_parameters_.next_reset_date_ == 0) { + trial_parameters_timeout_.cancel_timeout(); + } else { + trial_parameters_timeout_.set_callback(std::move(trial_parameters_timeout_static)); + trial_parameters_timeout_.set_callback_data(static_cast(td_)); + trial_parameters_timeout_.set_timeout_in(trial_parameters_.next_reset_date_ - G()->unix_time() + 1); + } +} + +void TranscriptionManager::trial_parameters_timeout_static(void *td) { + if (G()->close_flag()) { + return; + } + + CHECK(td != nullptr); + static_cast(td)->transcription_manager_->on_trial_parameters_timeout(); +} + +void TranscriptionManager::on_trial_parameters_timeout() { + if (!td_->auth_manager_->is_authorized()) { + return; + } + CHECK(!td_->auth_manager_->is_bot()); + set_trial_parameters(trial_parameters_); +} + +void TranscriptionManager::send_update_speech_recognition_trial() const { + send_closure(G()->td(), &Td::send_update, get_update_speech_recognition_trial_object()); +} + +td_api::object_ptr +TranscriptionManager::get_update_speech_recognition_trial_object() const { + CHECK(td_->auth_manager_->is_authorized()); + CHECK(!td_->auth_manager_->is_bot()); + return trial_parameters_.get_update_speech_recognition_trial_object(); +} + +td_api::object_ptr +TranscriptionManager::TrialParameters::get_update_speech_recognition_trial_object() const { + return td_api::make_object(duration_max_, weekly_number_, left_tries_, + next_reset_date_); +} + +void TranscriptionManager::register_voice(FileId file_id, MessageContentType content_type, + MessageFullId message_full_id, const char *source) { + if (td_->auth_manager_->is_bot() || message_full_id.get_message_id().is_scheduled() || + !message_full_id.get_message_id().is_server() || + message_full_id.get_dialog_id().get_type() == DialogType::SecretChat) { + return; + } + LOG(INFO) << "Register voice " << file_id << " from " << message_full_id << " from " << source; + CHECK(file_id.is_valid()); + bool is_inserted = voice_messages_[file_id].emplace(message_full_id).second; + LOG_CHECK(is_inserted) << source << ' ' << file_id << ' ' << message_full_id; + is_inserted = message_file_ids_.emplace(message_full_id, FileInfo(content_type, file_id)).second; + CHECK(is_inserted); +} + +void TranscriptionManager::unregister_voice(FileId file_id, MessageContentType content_type, + MessageFullId message_full_id, const char *source) { + if (td_->auth_manager_->is_bot() || message_full_id.get_message_id().is_scheduled() || + !message_full_id.get_message_id().is_server() || + message_full_id.get_dialog_id().get_type() == DialogType::SecretChat) { + return; + } + LOG(INFO) << "Unregister voice " << file_id << " from " << message_full_id << " from " << source; + CHECK(file_id.is_valid()); + auto &message_full_ids = voice_messages_[file_id]; + auto is_deleted = message_full_ids.erase(message_full_id) > 0; + LOG_CHECK(is_deleted) << source << ' ' << file_id << ' ' << message_full_id; + if (message_full_ids.empty()) { + voice_messages_.erase(file_id); + } + is_deleted = message_file_ids_.erase(message_full_id) > 0; + CHECK(is_deleted); +} + +TranscriptionInfo *TranscriptionManager::get_transcription_info(const FileInfo &file_info, bool allow_creation) { + switch (file_info.first) { + case MessageContentType::VideoNote: + return td_->video_notes_manager_->get_video_note_transcription_info(file_info.second, allow_creation); + case MessageContentType::VoiceNote: + return td_->voice_notes_manager_->get_voice_note_transcription_info(file_info.second, allow_creation); + default: + UNREACHABLE(); + return nullptr; + } +} + +void TranscriptionManager::recognize_speech(MessageFullId message_full_id, Promise &&promise) { + if (!td_->messages_manager_->have_message_force(message_full_id, "recognize_speech")) { + return promise.set_error(Status::Error(400, "Message not found")); + } + + auto it = message_file_ids_.find(message_full_id); + if (it == message_file_ids_.end()) { + return promise.set_error(Status::Error(400, "Message can't be transcribed")); + } + + auto *transcription_info = get_transcription_info(it->second, true); + auto handler = [actor_id = actor_id(this), file_info = it->second]( + Result> r_audio) { + send_closure(actor_id, &TranscriptionManager::on_transcribed_audio, file_info, std::move(r_audio)); + }; + if (transcription_info->recognize_speech(td_, message_full_id, std::move(promise), std::move(handler))) { + on_transcription_updated(it->second.second); + } +} + +void TranscriptionManager::on_transcribed_audio( + FileInfo file_info, Result> r_audio) { + if (G()->close_flag() || !td_->auth_manager_->is_authorized()) { + return; + } + if (r_audio.is_error()) { + auto retry_after = Global::get_retry_after(r_audio.error()); + on_transcribed_audio_update(file_info, true, r_audio.move_as_error()); + if (retry_after > 0 && trial_parameters_.left_tries_ > 0) { + TrialParameters new_trial_parameters = trial_parameters_; + new_trial_parameters.next_reset_date_ = G()->unix_time() + retry_after; + new_trial_parameters.left_tries_ = 0; + set_trial_parameters(new_trial_parameters); + } + return; + } + auto audio = r_audio.move_as_ok(); + if (audio->transcription_id_ == 0) { + return on_transcribed_audio_update(file_info, true, Status::Error(500, "Receive no transcription identifier")); + } + auto update = telegram_api::make_object(); + update->text_ = std::move(audio->text_); + update->transcription_id_ = audio->transcription_id_; + update->pending_ = audio->pending_; + on_transcribed_audio_update(file_info, true, std::move(update)); + + if ((audio->flags_ & telegram_api::messages_transcribedAudio::TRIAL_REMAINS_NUM_MASK) != 0) { + TrialParameters new_trial_parameters = trial_parameters_; + new_trial_parameters.next_reset_date_ = max(0, audio->trial_remains_until_date_); + new_trial_parameters.left_tries_ = audio->trial_remains_num_; + set_trial_parameters(new_trial_parameters); + } +} + +void TranscriptionManager::on_transcribed_audio_update( + FileInfo file_info, bool is_initial, + Result> r_update) { + if (G()->close_flag() || !td_->auth_manager_->is_authorized()) { + return; + } + + auto *transcription_info = get_transcription_info(file_info, false); + CHECK(transcription_info != nullptr); + if (r_update.is_error()) { + auto promises = transcription_info->on_failed_transcription(r_update.move_as_error()); + on_transcription_updated(file_info.second); + set_promises(promises); + return; + } + auto update = r_update.move_as_ok(); + auto transcription_id = update->transcription_id_; + if (!update->pending_) { + auto promises = transcription_info->on_final_transcription(std::move(update->text_), transcription_id); + on_transcription_completed(file_info.second); + set_promises(promises); + } else { + auto is_changed = transcription_info->on_partial_transcription(std::move(update->text_), transcription_id); + if (is_changed) { + on_transcription_updated(file_info.second); + } + + if (is_initial) { + subscribe_to_transcribed_audio_updates( + transcription_id, [actor_id = actor_id(this), file_info]( + Result> r_update) { + send_closure(actor_id, &TranscriptionManager::on_transcribed_audio_update, file_info, false, + std::move(r_update)); + }); + } + } +} + +void TranscriptionManager::on_transcription_updated(FileId file_id) { + auto it = voice_messages_.find(file_id); + if (it != voice_messages_.end()) { + for (const auto &message_full_id : it->second) { + td_->messages_manager_->on_external_update_message_content(message_full_id, "on_transcription_updated"); + } + } +} + +void TranscriptionManager::on_transcription_completed(FileId file_id) { + auto it = voice_messages_.find(file_id); + if (it != voice_messages_.end()) { + for (const auto &message_full_id : it->second) { + td_->messages_manager_->on_update_message_content(message_full_id); + } + } +} + +void TranscriptionManager::rate_speech_recognition(MessageFullId message_full_id, bool is_good, + Promise &&promise) { + if (!td_->messages_manager_->have_message_force(message_full_id, "recognize_speech")) { + return promise.set_error(Status::Error(400, "Message not found")); + } + + auto it = message_file_ids_.find(message_full_id); + if (it == message_file_ids_.end()) { + return promise.set_error(Status::Error(400, "Message can't be transcribed")); + } + + const auto *transcription_info = get_transcription_info(it->second, false); + if (transcription_info == nullptr) { + return promise.set_value(Unit()); + } + transcription_info->rate_speech_recognition(td_, message_full_id, is_good, std::move(promise)); +} + +void TranscriptionManager::subscribe_to_transcribed_audio_updates(int64 transcription_id, + TranscribedAudioHandler on_update) { + CHECK(transcription_id != 0); + if (pending_audio_transcriptions_.count(transcription_id) != 0) { + on_pending_audio_transcription_failed(transcription_id, + Status::Error(500, "Receive duplicate speech recognition identifier")); + } + bool is_inserted = pending_audio_transcriptions_.emplace(transcription_id, std::move(on_update)).second; + CHECK(is_inserted); + pending_audio_transcription_timeout_.set_timeout_in(transcription_id, AUDIO_TRANSCRIPTION_TIMEOUT); +} + +void TranscriptionManager::on_update_transcribed_audio( + telegram_api::object_ptr &&update) { + auto it = pending_audio_transcriptions_.find(update->transcription_id_); + if (it == pending_audio_transcriptions_.end()) { + return; + } + // flags_, peer_ and msg_id_ must not be used + if (!update->pending_) { + auto on_update = std::move(it->second); + pending_audio_transcriptions_.erase(it); + pending_audio_transcription_timeout_.cancel_timeout(update->transcription_id_); + on_update(std::move(update)); + } else { + it->second(std::move(update)); + } +} + +void TranscriptionManager::on_pending_audio_transcription_failed(int64 transcription_id, Status &&error) { + if (G()->close_flag()) { + return; + } + auto it = pending_audio_transcriptions_.find(transcription_id); + if (it == pending_audio_transcriptions_.end()) { + return; + } + auto on_update = std::move(it->second); + pending_audio_transcriptions_.erase(it); + pending_audio_transcription_timeout_.cancel_timeout(transcription_id); + + on_update(std::move(error)); +} + +void TranscriptionManager::get_current_state(vector> &updates) const { + if (!td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot()) { + return; + } + + updates.push_back(get_update_speech_recognition_trial_object()); +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TranscriptionManager.h b/protocols/Telegram/tdlib/td/td/telegram/TranscriptionManager.h new file mode 100644 index 0000000000..adad709945 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/TranscriptionManager.h @@ -0,0 +1,135 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/files/FileId.h" +#include "td/telegram/MessageContentType.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/TranscriptionInfo.h" + +#include "td/actor/actor.h" +#include "td/actor/MultiTimeout.h" +#include "td/actor/Timeout.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" + +#include +#include + +namespace td { + +class Td; + +class TranscriptionManager final : public Actor { + public: + TranscriptionManager(Td *td, ActorShared<> parent); + TranscriptionManager(const TranscriptionManager &) = delete; + TranscriptionManager &operator=(const TranscriptionManager &) = delete; + TranscriptionManager(TranscriptionManager &&) = delete; + TranscriptionManager &operator=(TranscriptionManager &&) = delete; + ~TranscriptionManager() final; + + void on_update_trial_parameters(int32 weekly_number, int32 duration_max, int32 cooldown_until); + + void register_voice(FileId file_id, MessageContentType content_type, MessageFullId message_full_id, + const char *source); + + void unregister_voice(FileId file_id, MessageContentType content_type, MessageFullId message_full_id, + const char *source); + + void recognize_speech(MessageFullId message_full_id, Promise &&promise); + + void on_transcription_completed(FileId file_id); + + void rate_speech_recognition(MessageFullId message_full_id, bool is_good, Promise &&promise); + + void on_update_transcribed_audio(telegram_api::object_ptr &&update); + + void get_current_state(vector> &updates) const; + + private: + static constexpr int32 AUDIO_TRANSCRIPTION_TIMEOUT = 60; + + struct TrialParameters { + int32 weekly_number_ = 0; + int32 duration_max_ = 0; + int32 left_tries_ = 0; + int32 next_reset_date_ = 0; + + void update_left_tries(); + + td_api::object_ptr get_update_speech_recognition_trial_object() const; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + friend bool operator==(const TrialParameters &lhs, const TrialParameters &rhs); + + void tear_down() final; + + static void on_pending_audio_transcription_timeout_callback(void *td, int64 transcription_id); + + static string get_trial_parameters_database_key(); + + void load_trial_parameters(); + + void set_trial_parameters(TrialParameters new_trial_parameters); + + void set_speech_recognition_trial_timeout(); + + static void trial_parameters_timeout_static(void *td); + + void on_trial_parameters_timeout(); + + void save_trial_parameters(); + + void send_update_speech_recognition_trial() const; + + td_api::object_ptr get_update_speech_recognition_trial_object() const; + + using FileInfo = std::pair; + + TranscriptionInfo *get_transcription_info(const FileInfo &file_info, bool allow_creation); + + void on_transcribed_audio(FileInfo file_info, + Result> r_audio); + + using TranscribedAudioHandler = + std::function>)>; + void subscribe_to_transcribed_audio_updates(int64 transcription_id, TranscribedAudioHandler on_update); + + void on_transcribed_audio_update(FileInfo file_info, bool is_initial, + Result> r_update); + + void on_transcription_updated(FileId file_id); + + void on_pending_audio_transcription_failed(int64 transcription_id, Status &&error); + + Td *td_; + ActorShared<> parent_; + + TrialParameters trial_parameters_; + Timeout trial_parameters_timeout_; + + FlatHashMap pending_audio_transcriptions_; + MultiTimeout pending_audio_transcription_timeout_{"PendingAudioTranscriptionTimeout"}; + + FlatHashMap, FileIdHash> voice_messages_; + FlatHashMap message_file_ids_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/TranslationManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/TranslationManager.cpp index fb831c4133..e7ecdd5759 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/TranslationManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/TranslationManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -28,10 +28,9 @@ class TranslateTextQuery final : public Td::ResultHandler { void send(vector &&texts, const string &to_language_code) { int flags = telegram_api::messages_translateText::TEXT_MASK; - auto input_texts = - transform(std::move(texts), [contacts_manager = td_->contacts_manager_.get()](FormattedText &&text) { - return get_input_text_with_entities(contacts_manager, std::move(text), "TranslateTextQuery"); - }); + auto input_texts = transform(std::move(texts), [user_manager = td_->user_manager_.get()](FormattedText &&text) { + return get_input_text_with_entities(user_manager, std::move(text), "TranslateTextQuery"); + }); send_query(G()->net_query_creator().create(telegram_api::messages_translateText( flags, nullptr, vector{}, std::move(input_texts), to_language_code))); } @@ -48,6 +47,11 @@ class TranslateTextQuery final : public Td::ResultHandler { } void on_error(Status status) final { + if (status.message() == "INPUT_TEXT_EMPTY") { + vector> result; + result.push_back(telegram_api::make_object(string(), Auto())); + return promise_.set_value(std::move(result)); + } promise_.set_error(std::move(status)); } }; @@ -87,7 +91,7 @@ void TranslationManager::translate_text(td_api::object_ptrcontacts_manager_.get(), std::move(text->entities_))); + TRY_RESULT_PROMISE(promise, entities, get_message_entities(td_->user_manager_.get(), std::move(text->entities_))); TRY_STATUS_PROMISE(promise, fix_formatted_text(text->text_, entities, true, true, true, true, true)); translate_text(FormattedText{std::move(text->text_), std::move(entities)}, skip_bot_commands, max_media_timestamp, @@ -118,12 +122,15 @@ void TranslationManager::on_get_translated_texts(vector> &&promise) { TRY_STATUS_PROMISE(promise, G()->close_status()); if (texts.size() != 1u) { + if (texts.empty()) { + return promise.set_error(Status::Error(500, "Translation failed")); + } return promise.set_error(Status::Error(500, "Receive invalid number of results")); } - auto formatted_text = - get_formatted_text(td_->contacts_manager_.get(), std::move(texts[0]), true, true, skip_bot_commands, - max_media_timestamp == -1, true, "on_get_translated_texts"); - promise.set_value(get_formatted_text_object(formatted_text, skip_bot_commands, max_media_timestamp)); + auto formatted_text = get_formatted_text(td_->user_manager_.get(), std::move(texts[0]), max_media_timestamp == -1, + true, "on_get_translated_texts"); + promise.set_value( + get_formatted_text_object(td_->user_manager_.get(), formatted_text, skip_bot_commands, max_media_timestamp)); } } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/UpdatesManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/UpdatesManager.cpp index 279ec5f1e3..2f0fb7ba11 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/UpdatesManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/UpdatesManager.cpp @@ -1,26 +1,34 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "td/telegram/UpdatesManager.h" +#include "td/telegram/AccountManager.h" #include "td/telegram/AnimationsManager.h" #include "td/telegram/AttachMenuManager.h" #include "td/telegram/AuthManager.h" #include "td/telegram/AutosaveManager.h" +#include "td/telegram/BoostManager.h" +#include "td/telegram/BusinessConnectionId.h" +#include "td/telegram/BusinessConnectionManager.h" #include "td/telegram/CallbackQueriesManager.h" #include "td/telegram/CallManager.h" #include "td/telegram/ChannelId.h" +#include "td/telegram/ChannelType.h" #include "td/telegram/ChatId.h" +#include "td/telegram/ChatManager.h" #include "td/telegram/ConfigManager.h" -#include "td/telegram/ContactsManager.h" #include "td/telegram/DialogAction.h" +#include "td/telegram/DialogActionManager.h" #include "td/telegram/DialogFilterManager.h" #include "td/telegram/DialogId.h" #include "td/telegram/DialogInviteLink.h" +#include "td/telegram/DialogManager.h" #include "td/telegram/DialogParticipant.h" +#include "td/telegram/DialogParticipantManager.h" #include "td/telegram/DownloadManager.h" #include "td/telegram/EmojiStatus.h" #include "td/telegram/FolderId.h" @@ -31,34 +39,52 @@ #include "td/telegram/LanguagePackManager.h" #include "td/telegram/Location.h" #include "td/telegram/MessageId.h" +#include "td/telegram/MessageReaction.h" +#include "td/telegram/MessageSender.h" #include "td/telegram/MessagesManager.h" #include "td/telegram/MessageTtl.h" #include "td/telegram/misc.h" #include "td/telegram/net/DcOptions.h" -#include "td/telegram/net/NetQuery.h" #include "td/telegram/NotificationManager.h" #include "td/telegram/NotificationSettingsManager.h" #include "td/telegram/NotificationSettingsScope.h" +#include "td/telegram/OnlineManager.h" #include "td/telegram/OptionManager.h" #include "td/telegram/OrderInfo.h" +#include "td/telegram/PeopleNearbyManager.h" #include "td/telegram/PollId.h" #include "td/telegram/PollManager.h" #include "td/telegram/PrivacyManager.h" #include "td/telegram/PublicDialogType.h" +#include "td/telegram/QuickReplyManager.h" +#include "td/telegram/QuickReplyShortcutId.h" +#include "td/telegram/ReactionListType.h" +#include "td/telegram/ReactionManager.h" +#include "td/telegram/ReactionType.h" +#include "td/telegram/SavedMessagesManager.h" #include "td/telegram/ScheduledServerMessageId.h" #include "td/telegram/SecretChatId.h" #include "td/telegram/SecretChatsManager.h" #include "td/telegram/ServerMessageId.h" #include "td/telegram/SpecialStickerSetType.h" +#include "td/telegram/StarManager.h" #include "td/telegram/StateManager.h" +#include "td/telegram/StatisticsManager.h" +#include "td/telegram/StickerListType.h" #include "td/telegram/StickerSetId.h" #include "td/telegram/StickersManager.h" #include "td/telegram/StickerType.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/StoryManager.h" #include "td/telegram/Td.h" #include "td/telegram/td_api.h" #include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" #include "td/telegram/telegram_api.hpp" #include "td/telegram/ThemeManager.h" +#include "td/telegram/TimeZoneManager.h" +#include "td/telegram/TranscriptionManager.h" +#include "td/telegram/UserManager.h" #include "td/telegram/Usernames.h" #include "td/telegram/WebPagesManager.h" @@ -77,30 +103,12 @@ #include "td/utils/StringBuilder.h" #include "td/utils/Time.h" -#include #include namespace td { int VERBOSITY_NAME(get_difference) = VERBOSITY_NAME(INFO); -class OnUpdate { - UpdatesManager *updates_manager_; - tl_object_ptr &update_; - mutable Promise promise_; - - public: - OnUpdate(UpdatesManager *updates_manager, tl_object_ptr &update, Promise &&promise) - : updates_manager_(updates_manager), update_(update), promise_(std::move(promise)) { - } - - template - void operator()(T &obj) const { - CHECK(&*update_ == &obj); - updates_manager_->on_update(move_tl_object_as(update_), std::move(promise_)); - } -}; - class GetUpdatesStateQuery final : public Td::ResultHandler { Promise> promise_; @@ -153,6 +161,19 @@ class PingServerQuery final : public Td::ResultHandler { } }; +class InitSessionQuery final : public Td::ResultHandler { + public: + void send() { + send_query(G()->net_query_creator().create(telegram_api::help_getCdnConfig())); + } + + void on_result(BufferSlice) final { + } + + void on_error(Status) final { + } +}; + class GetDifferenceQuery final : public Td::ResultHandler { Promise> promise_; @@ -162,7 +183,7 @@ class GetDifferenceQuery final : public Td::ResultHandler { } void send(int32 pts, int32 date, int32 qts) { - send_query(G()->net_query_creator().create(telegram_api::updates_getDifference(0, pts, 0, date, qts))); + send_query(G()->net_query_creator().create(telegram_api::updates_getDifference(0, pts, 0, 0, date, qts, 0))); } void on_result(BufferSlice packet) final { @@ -180,14 +201,63 @@ class GetDifferenceQuery final : public Td::ResultHandler { } }; +class ConfirmPtsQtsQuery final : public Td::ResultHandler { + public: + void send(int32 pts, int32 qts) { + int32 flags = + telegram_api::updates_getDifference::PTS_LIMIT_MASK | telegram_api::updates_getDifference::QTS_LIMIT_MASK; + send_query(G()->net_query_creator().create( + telegram_api::updates_getDifference(flags, pts, 1, 0, std::numeric_limits::max(), qts, 1))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + } + + void on_error(Status status) final { + if (!G()->is_expected_error(status)) { + LOG(ERROR) << "Failed to confirm PTS/QTS: " << status; + } + } +}; + +class GetPtsUpdateQuery final : public Td::ResultHandler { + Promise> promise_; + + public: + explicit GetPtsUpdateQuery(Promise> &&promise) + : promise_(std::move(promise)) { + } + + void send(int32 pts) { + int32 flags = + telegram_api::updates_getDifference::PTS_LIMIT_MASK | telegram_api::updates_getDifference::QTS_LIMIT_MASK; + send_query(G()->net_query_creator().create( + telegram_api::updates_getDifference(flags, pts, 1, 0, std::numeric_limits::max(), 0, 0))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(result_ptr.move_as_ok()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + UpdatesManager::UpdatesManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { last_pts_save_time_ = last_qts_save_time_ = Time::now() - 2 * MAX_PTS_SAVE_DELAY; - pending_audio_transcription_timeout_.set_callback(on_pending_audio_transcription_timeout_callback); - pending_audio_transcription_timeout_.set_callback_data(static_cast(td_)); - - if (td_->option_manager_->get_option_integer("since_last_open") < 3600) { - finished_first_get_difference_ = true; + if (!td_->auth_manager_->is_authorized() || !td_->auth_manager_->is_bot()) { + skipped_postponed_updates_after_start_ = 0; } } @@ -198,6 +268,10 @@ void UpdatesManager::tear_down() { } void UpdatesManager::start_up() { + if (td_->auth_manager_->is_bot()) { + return; + } + class StateCallback final : public StateManager::Callback { public: explicit StateCallback(ActorId parent) : parent_(std::move(parent)) { @@ -239,6 +313,44 @@ ActorShared UpdatesManager::create_reference() { return actor_shared(this, 1); } +void UpdatesManager::check_pts_gap(void *td) { + if (G()->close_flag()) { + return; + } + + CHECK(td != nullptr); + static_cast(td)->updates_manager_.get()->repair_pts_gap(); +} + +void UpdatesManager::repair_pts_gap() { + if (!td_->auth_manager_->is_authorized() || running_get_difference_ || !postponed_pts_updates_.empty()) { + return; + } + auto pts = get_pts() + 1; + if (pending_pts_updates_.empty()) { + return; + } + auto it = pending_pts_updates_.begin(); + if (it->pts != pts + it->pts_count) { + return; + } + if (last_fetched_pts_ == pts) { + VLOG(get_difference) << "Don't fetch again update with PTS = " << pts; + return; + } + last_fetched_pts_ = pts; + + VLOG(get_difference) << "Fetch update with PTS = " << pts; + pts_short_gap_++; + auto promise = + PromiseCreator::lambda([pts](Result> result) { + if (result.is_ok()) { + send_closure(G()->updates_manager(), &UpdatesManager::on_get_pts_update, pts, result.move_as_ok()); + } + }); + td_->create_handler(std::move(promise))->send(pts - 1); +} + void UpdatesManager::fill_pts_gap(void *td) { if (G()->close_flag()) { return; @@ -246,18 +358,37 @@ void UpdatesManager::fill_pts_gap(void *td) { CHECK(td != nullptr); auto updates_manager = static_cast(td)->updates_manager_.get(); + if (updates_manager->expect_pts_gap_) { + updates_manager->expect_pts_gap_ = false; + return fill_gap(td, string()); + } + auto min_pts = std::numeric_limits::max(); + auto min_pts_count = 0; + const telegram_api::Update *first_update = nullptr; auto max_pts = 0; if (!updates_manager->pending_pts_updates_.empty()) { - min_pts = min(min_pts, updates_manager->pending_pts_updates_.begin()->first); - max_pts = max(max_pts, updates_manager->pending_pts_updates_.rbegin()->first); + auto &min_update = *updates_manager->pending_pts_updates_.begin(); + if (min_update.pts < min_pts) { + min_pts = min_update.pts; + min_pts_count = min_update.pts_count; + first_update = min_update.update.get(); + } + max_pts = max(max_pts, updates_manager->pending_pts_updates_.rbegin()->pts); } if (!updates_manager->postponed_pts_updates_.empty()) { - min_pts = min(min_pts, updates_manager->postponed_pts_updates_.begin()->first); - max_pts = max(max_pts, updates_manager->postponed_pts_updates_.rbegin()->first); + auto &min_update = *updates_manager->postponed_pts_updates_.begin(); + if (min_update.pts < min_pts) { + min_pts = min_update.pts; + min_pts_count = min_update.pts_count; + first_update = min_update.update.get(); + } + max_pts = max(max_pts, updates_manager->postponed_pts_updates_.rbegin()->pts); } - string source = PSTRING() << "PTS from " << updates_manager->get_pts() << " to " << min_pts << '-' << max_pts; - fill_gap(td, source.c_str()); + updates_manager->pts_gap_++; + fill_gap(td, PSTRING() << "PTS from " << updates_manager->get_pts() << " to " << min_pts << "(-" << min_pts_count + << ")-" << max_pts << ' ' + << (first_update == nullptr ? string() : oneline(to_string(*first_update)))); } void UpdatesManager::fill_seq_gap(void *td) { @@ -270,11 +401,10 @@ void UpdatesManager::fill_seq_gap(void *td) { auto min_seq = std::numeric_limits::max(); auto max_seq = 0; if (!updates_manager->pending_seq_updates_.empty()) { - min_seq = updates_manager->pending_seq_updates_.begin()->first; - max_seq = updates_manager->pending_seq_updates_.rbegin()->second.seq_end; + min_seq = updates_manager->pending_seq_updates_.begin()->seq_begin; + max_seq = updates_manager->pending_seq_updates_.rbegin()->seq_end; } - string source = PSTRING() << "seq from " << updates_manager->seq_ << " to " << min_seq << '-' << max_seq; - fill_gap(td, source.c_str()); + fill_gap(td, PSTRING() << "seq from " << updates_manager->seq_ << " to " << min_seq << '-' << max_seq); } void UpdatesManager::fill_qts_gap(void *td) { @@ -290,15 +420,15 @@ void UpdatesManager::fill_qts_gap(void *td) { min_qts = updates_manager->pending_qts_updates_.begin()->first; max_qts = updates_manager->pending_qts_updates_.rbegin()->first; } - string source = PSTRING() << "QTS from " << updates_manager->get_qts() << " to " << min_qts << '-' << max_qts; - fill_gap(td, source.c_str()); + updates_manager->qts_gap_++; + fill_gap(td, PSTRING() << "QTS from " << updates_manager->get_qts() << " to " << min_qts << '-' << max_qts); } void UpdatesManager::fill_get_difference_gap(void *td) { - fill_gap(td, nullptr); + fill_gap(td, string()); } -void UpdatesManager::fill_gap(void *td, const char *source) { +void UpdatesManager::fill_gap(void *td, const string &source) { if (G()->close_flag()) { return; } @@ -308,7 +438,7 @@ void UpdatesManager::fill_gap(void *td, const char *source) { } auto updates_manager = static_cast(td)->updates_manager_.get(); - if (source != nullptr && !updates_manager->running_get_difference_) { + if (!source.empty() && !updates_manager->running_get_difference_) { auto auth_key_id = updates_manager->get_most_unused_auth_key_id(); uint64 update_count = 0; double active_time = 0.0; @@ -330,20 +460,6 @@ void UpdatesManager::fill_gap(void *td, const char *source) { updates_manager->get_difference("fill_gap"); } -void UpdatesManager::on_pending_audio_transcription_timeout_callback(void *td, int64 transcription_id) { - if (G()->close_flag()) { - return; - } - CHECK(td != nullptr); - if (!static_cast(td)->auth_manager_->is_authorized()) { - return; - } - - auto updates_manager = static_cast(td)->updates_manager_.get(); - send_closure_later(updates_manager->actor_id(updates_manager), &UpdatesManager::on_pending_audio_transcription_failed, - transcription_id, Status::Error(500, "Timeout expired")); -} - void UpdatesManager::get_difference(const char *source) { if (G()->close_flag() || !td_->auth_manager_->is_authorized()) { return; @@ -401,14 +517,20 @@ void UpdatesManager::before_get_difference(bool is_initial) { // may be called many times before after_get_difference is called send_closure(G()->state_manager(), &StateManager::on_synchronized, false); + td_->messages_manager_->before_get_difference(); + + vector> promises; if (can_postpone_updates()) { - postponed_pts_updates_.insert(std::make_move_iterator(pending_pts_updates_.begin()), - std::make_move_iterator(pending_pts_updates_.end())); + for (auto &update : pending_pts_updates_) { + postponed_pts_updates_.emplace(std::move(update.update), update.pts, update.pts_count, update.receive_time, + std::move(update.promise)); + } } else { for (auto &update : pending_pts_updates_) { - update.second.promise.set_value(Unit()); + promises.push_back(std::move(update.promise)); } } + set_promises(promises); drop_all_pending_pts_updates(); @@ -499,25 +621,36 @@ void UpdatesManager::timeout_expired() { Promise<> UpdatesManager::set_pts(int32 pts, const char *source) { if (pts == std::numeric_limits::max()) { LOG(WARNING) << "Update PTS from " << get_pts() << " to -1 from " << source; - save_pts(pts); + save_pts(pts); // drop saved PTS value auto result = add_pts(pts); init_state(); return result; } Promise<> result; - if (pts > get_pts() || (0 < pts && pts < get_pts() - 399999)) { // PTS can only go up or drop cardinally - if (pts < get_pts() - 399999) { - LOG(WARNING) << "PTS decreases from " << get_pts() << " to " << pts << " from " << source; + auto old_pts = get_pts(); + if (pts > old_pts || (0 < pts && pts < old_pts - 1000009)) { // PTS can only go up or drop cardinally + if (pts < old_pts - 1000009) { + LOG(WARNING) << "PTS decreases from " << old_pts << " to " << pts << " from " << source; } else { - LOG(INFO) << "Update PTS from " << get_pts() << " to " << pts << " from " << source; + LOG(INFO) << "Update PTS from " << old_pts << " to " << pts << " from " << source; + if (old_pts > 0) { + pts_diff_ += pts - old_pts; + if (pts_diff_ >= 1000000) { + if (pts_gap_ > 0 || pts_short_gap_ > 0) { + LOG(WARNING) << "Fixed " << pts_gap_ << " PTS gaps and " << pts_fixed_short_gap_ << " short gaps up to PTS " + << pts << " by sending " << pts_short_gap_ << " requests"; + pts_short_gap_ = 0; + pts_fixed_short_gap_ = 0; + pts_gap_ = 0; + } + pts_diff_ = 0; + } + } } result = add_pts(pts); - if (last_confirmed_pts_ < get_pts() - FORCED_GET_DIFFERENCE_PTS_DIFF) { - if (last_confirmed_pts_ != 0) { - schedule_get_difference("rare PTS getDifference"); - } - last_confirmed_pts_ = get_pts(); + if (last_confirmed_pts_ < get_pts() - FORCED_GET_DIFFERENCE_PTS_DIFF && last_confirmed_pts_ != 0) { + confirm_pts_qts(get_qts()); } } else if (pts < get_pts() && (pts > 1 || td_->option_manager_->get_option_integer("session_count") <= 1)) { LOG(ERROR) << "Receive wrong PTS = " << pts << " from " << source << ". Current PTS = " << get_pts(); @@ -563,15 +696,15 @@ void UpdatesManager::set_date(int32 date, bool from_update, string date_source) } bool UpdatesManager::is_acceptable_user(UserId user_id) const { - return td_->contacts_manager_->have_user_force(user_id) && td_->contacts_manager_->have_user(user_id); + return td_->user_manager_->have_user_force(user_id, "is_acceptable_user") && td_->user_manager_->have_user(user_id); } bool UpdatesManager::is_acceptable_chat(ChatId chat_id) const { - return td_->contacts_manager_->have_chat_force(chat_id); + return td_->chat_manager_->have_chat_force(chat_id, "is_acceptable_chat"); } bool UpdatesManager::is_acceptable_channel(ChannelId channel_id) const { - return td_->contacts_manager_->have_channel_force(channel_id); + return td_->chat_manager_->have_channel_force(channel_id, "is_acceptable_channel"); } bool UpdatesManager::is_acceptable_peer(const tl_object_ptr &peer) const { @@ -612,7 +745,7 @@ bool UpdatesManager::is_acceptable_message_entities( if (entity->get_id() == telegram_api::messageEntityMentionName::ID) { auto entity_mention_name = static_cast(entity.get()); UserId user_id(entity_mention_name->user_id_); - if (!is_acceptable_user(user_id) || td_->contacts_manager_->get_input_user(user_id).is_error()) { + if (!is_acceptable_user(user_id) || td_->user_manager_->get_input_user(user_id).is_error()) { return false; } } @@ -629,7 +762,7 @@ bool UpdatesManager::is_acceptable_reply_markup(const tl_object_ptrget_id() == telegram_api::keyboardButtonUserProfile::ID) { auto user_profile_button = static_cast(button.get()); UserId user_id(user_profile_button->user_id_); - if (!is_acceptable_user(user_id) || td_->contacts_manager_->get_input_user(user_id).is_error()) { + if (!is_acceptable_user(user_id) || td_->user_manager_->get_input_user(user_id).is_error()) { return false; } } @@ -639,15 +772,27 @@ bool UpdatesManager::is_acceptable_reply_markup(const tl_object_ptr &header) const { + const telegram_api::object_ptr &header) const { if (header == nullptr) { return true; } - if (!is_acceptable_peer(header->reply_to_peer_id_)) { - return false; + switch (header->get_id()) { + case telegram_api::messageReplyHeader::ID: { + auto reply_header = static_cast(header.get()); + return is_acceptable_peer(reply_header->reply_to_peer_id_) && + is_acceptable_message_forward_header(reply_header->reply_from_) && + is_acceptable_message_entities(reply_header->quote_entities_) && + is_acceptable_message_media(reply_header->reply_media_); + } + case telegram_api::messageReplyStoryHeader::ID: { + auto reply_header = static_cast(header.get()); + return is_acceptable_peer(reply_header->peer_); + } + default: + UNREACHABLE(); + return true; } - return true; } bool UpdatesManager::is_acceptable_message_forward_header( @@ -665,6 +810,85 @@ bool UpdatesManager::is_acceptable_message_forward_header( return true; } +bool UpdatesManager::is_acceptable_message_media( + const telegram_api::object_ptr &media_ptr) const { + if (media_ptr == nullptr) { + return true; + } + switch (media_ptr->get_id()) { + case telegram_api::messageMediaContact::ID: { + auto message_media = static_cast(media_ptr.get()); + UserId user_id(message_media->user_id_); + return user_id == UserId() || is_acceptable_user(user_id); + } + case telegram_api::messageMediaStory::ID: { + auto message_media = static_cast(media_ptr.get()); + return is_acceptable_peer(message_media->peer_); + } + case telegram_api::messageMediaGiveaway::ID: { + auto message_media = static_cast(media_ptr.get()); + for (auto channel_id : message_media->channels_) { + if (!is_acceptable_channel(ChannelId(channel_id))) { + return false; + } + } + return true; + } + case telegram_api::messageMediaGiveawayResults::ID: { + auto message_media = static_cast(media_ptr.get()); + if (!is_acceptable_channel(ChannelId(message_media->channel_id_))) { + return false; + } + for (auto user_id : message_media->winners_) { + if (!is_acceptable_user(UserId(user_id))) { + return false; + } + } + return true; + } + case telegram_api::messageMediaPoll::ID: + /* + // the users and chats are always min, so no need to check + auto message_media_poll = static_cast(media_ptr.get()); + for (auto recent_voter : message_media_poll->results_->recent_voters_) { + if (!is_acceptable_peer(recent_voter)) { + return false; + } + } + */ + return true; + case telegram_api::messageMediaWebPage::ID: + /* + // the channel is always min, so no need to check + auto message_media_web_page = static_cast(media_ptr.get()); + if (message_media_web_page->webpage_->get_id() == telegram_api::webPage::ID) { + auto web_page = static_cast(message_media_web_page->webpage_.get()); + if (web_page->cached_page_ != nullptr) { + const vector> *page_blocks = nullptr; + downcast_call(*web_page->cached_page_, [&page_blocks](auto &page) { page_blocks = &page.blocks_; }); + CHECK(page_blocks != nullptr); + for (auto &page_block : *page_blocks) { + if (page_block->get_id() == telegram_api::pageBlockChannel::ID) { + auto page_block_channel = static_cast(page_block.get()); + auto channel_id = ChatManager::get_channel_id(page_block_channel->channel_); + if (channel_id.is_valid()) { + if (!is_acceptable_channel(channel_id)) { + return false; + } + } else { + LOG(ERROR) << "Receive wrong channel " << to_string(page_block_channel->channel_); + } + } + } + } + } + */ + return true; + default: + return true; + } +} + bool UpdatesManager::is_acceptable_message(const telegram_api::Message *message_ptr) const { CHECK(message_ptr != nullptr); int32 constructor_id = message_ptr->get_id(); @@ -689,7 +913,7 @@ bool UpdatesManager::is_acceptable_message(const telegram_api::Message *message_ return false; } - if ((message->flags_ & MessagesManager::MESSAGE_FLAG_IS_SENT_VIA_BOT) && + if ((message->flags_ & telegram_api::message::VIA_BOT_ID_MASK) && !is_acceptable_user(UserId(message->via_bot_id_))) { return false; } @@ -698,56 +922,8 @@ bool UpdatesManager::is_acceptable_message(const telegram_api::Message *message_ return false; } - if (message->media_ != nullptr) { - auto media_id = message->media_->get_id(); - if (media_id == telegram_api::messageMediaContact::ID) { - auto message_media_contact = static_cast(message->media_.get()); - UserId user_id(message_media_contact->user_id_); - if (user_id != UserId() && !is_acceptable_user(user_id)) { - return false; - } - } - /* - // the users are always min, so no need to check - if (media_id == telegram_api::messageMediaPoll::ID) { - auto message_media_poll = static_cast(message->media_.get()); - for (auto recent_voter_user_id : message_media_poll->results_->recent_voters_) { - UserId user_id(recent_voter_user_id); - if (!is_acceptable_user(user_id)) { - return false; - } - } - } - */ - /* - // the channel is always min, so no need to check - if (media_id == telegram_api::messageMediaWebPage::ID) { - auto message_media_web_page = static_cast(message->media_.get()); - if (message_media_web_page->webpage_->get_id() == telegram_api::webPage::ID) { - auto web_page = static_cast(message_media_web_page->webpage_.get()); - if (web_page->cached_page_ != nullptr) { - const vector> *page_blocks = nullptr; - downcast_call(*web_page->cached_page_, [&page_blocks](auto &page) { page_blocks = &page.blocks_; }); - CHECK(page_blocks != nullptr); - for (auto &page_block : *page_blocks) { - if (page_block->get_id() == telegram_api::pageBlockChannel::ID) { - auto page_block_channel = static_cast(page_block.get()); - auto channel_id = ContactsManager::get_channel_id(page_block_channel->channel_); - if (channel_id.is_valid()) { - if (!is_acceptable_channel(channel_id)) { - return false; - } - } else { - LOG(ERROR) << "Receive wrong channel " << to_string(page_block_channel->channel_); - } - } - } - } - } - } - */ - } else { - CHECK(message->media_ == nullptr); + if (!is_acceptable_message_media(message->media_)) { + return false; } /* @@ -805,7 +981,12 @@ bool UpdatesManager::is_acceptable_message(const telegram_api::Message *message_ case telegram_api::messageActionTopicEdit::ID: case telegram_api::messageActionSuggestProfilePhoto::ID: case telegram_api::messageActionSetChatWallPaper::ID: - case telegram_api::messageActionSetSameChatWallPaper::ID: + case telegram_api::messageActionGiveawayLaunch::ID: + case telegram_api::messageActionGiveawayResults::ID: + case telegram_api::messageActionBoostApply::ID: + case telegram_api::messageActionRequestedPeerSentMe::ID: + case telegram_api::messageActionGiftStars::ID: + case telegram_api::messageActionPrizeStars::ID: break; case telegram_api::messageActionChatCreate::ID: { auto chat_create = static_cast(action); @@ -878,7 +1059,25 @@ bool UpdatesManager::is_acceptable_message(const telegram_api::Message *message_ } case telegram_api::messageActionRequestedPeer::ID: { auto requested_peer = static_cast(action); - if (!td_->auth_manager_->is_bot() && !is_acceptable_peer(requested_peer->peer_)) { + if (!td_->auth_manager_->is_bot()) { + for (auto &peer : requested_peer->peers_) { + if (!is_acceptable_peer(peer)) { + return false; + } + } + } + break; + } + case telegram_api::messageActionGiftCode::ID: { + auto gift_code = static_cast(action); + if (!is_acceptable_peer(gift_code->boost_peer_)) { + return false; + } + break; + } + case telegram_api::messageActionPaymentRefunded::ID: { + auto payment_refunded = static_cast(action); + if (!is_acceptable_peer(payment_refunded->peer_)) { return false; } break; @@ -922,19 +1121,29 @@ bool UpdatesManager::is_acceptable_update(const telegram_api::Update *update) co return is_acceptable_message(message); } - if (id == telegram_api::updateDraftMessage::ID) { - auto update_draft_message = static_cast(update); - CHECK(update_draft_message->draft_ != nullptr); - if (update_draft_message->draft_->get_id() == telegram_api::draftMessage::ID) { - auto draft_message = static_cast(update_draft_message->draft_.get()); - return is_acceptable_message_entities(draft_message->entities_); - } - } - return true; } +int32 UpdatesManager::fix_short_message_flags(int32 flags) { + static constexpr int32 MESSAGE_FLAG_HAS_REPLY_MARKUP = 1 << 6; + static constexpr int32 MESSAGE_FLAG_HAS_MEDIA = 1 << 9; + static constexpr int32 MESSAGE_FLAG_HAS_REACTIONS = 1 << 20; + static constexpr int32 MESSAGE_FLAG_HAS_REPLY_INFO = 1 << 23; + static constexpr int32 MESSAGE_FLAG_HAS_SAVED_PEER_ID = 1 << 28; + auto disallowed_flags = MESSAGE_FLAG_HAS_REPLY_MARKUP | MESSAGE_FLAG_HAS_MEDIA | MESSAGE_FLAG_HAS_REACTIONS | + MESSAGE_FLAG_HAS_REPLY_INFO | MESSAGE_FLAG_HAS_SAVED_PEER_ID; + if ((flags & disallowed_flags) != 0) { + LOG(ERROR) << "Receive short message with flags " << flags; + flags = flags & ~disallowed_flags; + } + return flags; +} + void UpdatesManager::on_get_updates(tl_object_ptr &&updates_ptr, Promise &&promise) { + send_closure_later(actor_id(this), &UpdatesManager::on_get_updates_impl, std::move(updates_ptr), std::move(promise)); +} + +void UpdatesManager::on_get_updates_impl(tl_object_ptr updates_ptr, Promise promise) { CHECK(updates_ptr != nullptr); promise = PromiseCreator::lambda( [promise = std::move(promise), update_ids = get_update_ids(updates_ptr.get())](Result result) mutable { @@ -981,52 +1190,32 @@ void UpdatesManager::on_get_updates(tl_object_ptr &&updat break; case telegram_api::updateShortMessage::ID: { auto update = move_tl_object_as(updates_ptr); - if (update->flags_ & MessagesManager::MESSAGE_FLAG_HAS_REPLY_MARKUP) { - LOG(ERROR) << "Receive updateShortMessage with reply_markup"; - update->flags_ ^= MessagesManager::MESSAGE_FLAG_HAS_REPLY_MARKUP; - } - if (update->flags_ & MessagesManager::MESSAGE_FLAG_HAS_MEDIA) { - LOG(ERROR) << "Receive updateShortMessage with media"; - update->flags_ ^= MessagesManager::MESSAGE_FLAG_HAS_MEDIA; - } - - auto from_id = update->out_ ? td_->contacts_manager_->get_my_id().get() : update->user_id_; - update->flags_ |= MessagesManager::MESSAGE_FLAG_HAS_FROM_ID; - + auto from_id = update->out_ ? td_->user_manager_->get_my_id().get() : update->user_id_; auto message = make_tl_object( - update->flags_, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, update->id_, - make_tl_object(from_id), make_tl_object(update->user_id_), - std::move(update->fwd_from_), update->via_bot_id_, std::move(update->reply_to_), update->date_, + fix_short_message_flags(update->flags_), update->out_, update->mentioned_, update->media_unread_, + update->silent_, false, false, false, false, false, false, false, 0, false, update->id_, + make_tl_object(from_id), 0, make_tl_object(update->user_id_), + nullptr, std::move(update->fwd_from_), update->via_bot_id_, 0, std::move(update->reply_to_), update->date_, update->message_, nullptr, nullptr, std::move(update->entities_), 0, 0, nullptr, 0, string(), 0, nullptr, - Auto(), update->ttl_period_); + Auto(), update->ttl_period_, 0, 0, nullptr); on_pending_update( make_tl_object(std::move(message), update->pts_, update->pts_count_), 0, - std::move(promise), "telegram_api::updatesShortMessage"); + std::move(promise), "telegram_api::updateShortMessage"); break; } case telegram_api::updateShortChatMessage::ID: { auto update = move_tl_object_as(updates_ptr); - if (update->flags_ & MessagesManager::MESSAGE_FLAG_HAS_REPLY_MARKUP) { - LOG(ERROR) << "Receive updateShortChatMessage with reply_markup"; - update->flags_ ^= MessagesManager::MESSAGE_FLAG_HAS_REPLY_MARKUP; - } - if (update->flags_ & MessagesManager::MESSAGE_FLAG_HAS_MEDIA) { - LOG(ERROR) << "Receive updateShortChatMessage with media"; - update->flags_ ^= MessagesManager::MESSAGE_FLAG_HAS_MEDIA; - } - - update->flags_ |= MessagesManager::MESSAGE_FLAG_HAS_FROM_ID; auto message = make_tl_object( - update->flags_, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, - false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, update->id_, - make_tl_object(update->from_id_), - make_tl_object(update->chat_id_), std::move(update->fwd_from_), update->via_bot_id_, - std::move(update->reply_to_), update->date_, update->message_, nullptr, nullptr, std::move(update->entities_), - 0, 0, nullptr, 0, string(), 0, nullptr, Auto(), update->ttl_period_); + fix_short_message_flags(update->flags_), update->out_, update->mentioned_, update->media_unread_, + update->silent_, false, false, false, false, false, false, false, 0, false, update->id_, + make_tl_object(update->from_id_), 0, + make_tl_object(update->chat_id_), nullptr, std::move(update->fwd_from_), + update->via_bot_id_, 0, std::move(update->reply_to_), update->date_, update->message_, nullptr, nullptr, + std::move(update->entities_), 0, 0, nullptr, 0, string(), 0, nullptr, Auto(), update->ttl_period_, 0, 0, + nullptr); on_pending_update( make_tl_object(std::move(message), update->pts_, update->pts_count_), 0, - std::move(promise), "telegram_api::updatesShortChatMessage"); + std::move(promise), "telegram_api::updateShortChatMessage"); break; } case telegram_api::updateShort::ID: { @@ -1044,8 +1233,8 @@ void UpdatesManager::on_get_updates(tl_object_ptr &&updat } case telegram_api::updatesCombined::ID: { auto updates = move_tl_object_as(updates_ptr); - td_->contacts_manager_->on_get_users(std::move(updates->users_), "updatesCombined"); - td_->contacts_manager_->on_get_chats(std::move(updates->chats_), "updatesCombined"); + td_->user_manager_->on_get_users(std::move(updates->users_), "updatesCombined"); + td_->chat_manager_->on_get_chats(std::move(updates->chats_), "updatesCombined"); on_pending_updates(std::move(updates->updates_), updates->seq_start_, updates->seq_, updates->date_, Time::now(), std::move(promise), "telegram_api::updatesCombined"); break; @@ -1058,8 +1247,8 @@ void UpdatesManager::on_get_updates(tl_object_ptr &&updat source_str = PSTRING() << "update " << updates->updates_[0]->get_id(); source = source_str.c_str(); } - td_->contacts_manager_->on_get_users(std::move(updates->users_), source); - td_->contacts_manager_->on_get_chats(std::move(updates->chats_), source); + td_->user_manager_->on_get_users(std::move(updates->users_), source); + td_->chat_manager_->on_get_chats(std::move(updates->chats_), source); on_pending_updates(std::move(updates->updates_), updates->seq_, updates->seq_, updates->date_, Time::now(), std::move(promise), "telegram_api::updates"); break; @@ -1198,33 +1387,6 @@ bool UpdatesManager::are_empty_updates(const telegram_api::Updates *updates_ptr) } } -vector UpdatesManager::extract_group_invite_privacy_forbidden_updates( - tl_object_ptr &updates_ptr) { - auto updates = get_updates(updates_ptr.get()); - if (updates == nullptr) { - LOG(ERROR) << "Can't find updateGroupInvitePrivacyForbidden updates"; - return {}; - } - LOG(INFO) << "Extract updateGroupInvitePrivacyForbidden updates from " << updates->size() << " updates"; - vector user_ids; - for (auto &update_ptr : *updates) { - if (update_ptr->get_id() != telegram_api::updateGroupInvitePrivacyForbidden::ID) { - continue; - } - auto update = telegram_api::move_object_as(update_ptr); - UserId user_id(update->user_id_); - if (!user_id.is_valid()) { - LOG(ERROR) << "Receive " << to_string(update); - continue; - } - user_ids.push_back(user_id); - } - if (!user_ids.empty()) { - td::remove_if(*updates, [](auto &update) { return update == nullptr; }); - } - return user_ids; -} - FlatHashSet UpdatesManager::get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr) { FlatHashSet random_ids; auto updates = get_updates(updates_ptr); @@ -1280,7 +1442,7 @@ const telegram_api::Message *UpdatesManager::get_message_by_random_id(const tele } const telegram_api::Message *result = nullptr; - FullMessageId full_message_id(dialog_id, MessageId(ServerMessageId(message_id))); + MessageFullId message_full_id(dialog_id, MessageId(ServerMessageId(message_id))); for (auto &update : *updates) { auto constructor_id = update->get_id(); const tl_object_ptr *message = nullptr; @@ -1289,7 +1451,7 @@ const telegram_api::Message *UpdatesManager::get_message_by_random_id(const tele } else if (constructor_id == telegram_api::updateNewChannelMessage::ID) { message = &static_cast(update.get())->message_; } - if (message != nullptr && FullMessageId::get_full_message_id(*message, false) == full_message_id) { + if (message != nullptr && MessageFullId::get_message_full_id(*message, false) == message_full_id) { if (result != nullptr) { return nullptr; } @@ -1456,18 +1618,21 @@ vector UpdatesManager::get_chat_dialog_ids(const telegram_api::Updates vector dialog_ids; dialog_ids.reserve(chats->size()); for (const auto &chat : *chats) { - auto dialog_id = ContactsManager::get_dialog_id(chat); + auto dialog_id = ChatManager::get_dialog_id(chat); if (dialog_id.is_valid()) { dialog_ids.push_back(dialog_id); } else { LOG(ERROR) << "Can't find identifier of " << oneline(to_string(chat)); } } + if (dialog_ids.size() > 1) { + td::remove(dialog_ids, DialogId(ChatManager::get_unsupported_channel_id())); + } return dialog_ids; } int32 UpdatesManager::get_update_edit_message_pts(const telegram_api::Updates *updates_ptr, - FullMessageId full_message_id) { + MessageFullId message_full_id) { int32 pts = 0; auto updates = get_updates(updates_ptr); if (updates != nullptr) { @@ -1476,24 +1641,24 @@ int32 UpdatesManager::get_update_edit_message_pts(const telegram_api::Updates *u switch (update_ptr->get_id()) { case telegram_api::updateEditMessage::ID: { auto update = static_cast(update_ptr.get()); - if (FullMessageId::get_full_message_id(update->message_, false) == full_message_id) { + if (MessageFullId::get_message_full_id(update->message_, false) == message_full_id) { return update->pts_; } return 0; } case telegram_api::updateEditChannelMessage::ID: { auto update = static_cast(update_ptr.get()); - if (FullMessageId::get_full_message_id(update->message_, false) == full_message_id) { + if (MessageFullId::get_message_full_id(update->message_, false) == message_full_id) { return update->pts_; } return 0; } case telegram_api::updateNewScheduledMessage::ID: { auto update = static_cast(update_ptr.get()); - auto new_full_message_id = FullMessageId::get_full_message_id(update->message_, true); - if (new_full_message_id.get_dialog_id() == full_message_id.get_dialog_id()) { - auto new_message_id = new_full_message_id.get_message_id(); - auto old_message_id = full_message_id.get_message_id(); + auto new_message_full_id = MessageFullId::get_message_full_id(update->message_, true); + if (new_message_full_id.get_dialog_id() == message_full_id.get_dialog_id()) { + auto new_message_id = new_message_full_id.get_message_id(); + auto old_message_id = message_full_id.get_message_id(); if (new_message_id.is_valid_scheduled() && new_message_id.is_scheduled_server() && old_message_id.is_valid_scheduled() && old_message_id.is_scheduled_server() && old_message_id.get_scheduled_server_message_id() == @@ -1520,7 +1685,7 @@ int32 UpdatesManager::get_update_edit_message_pts(const telegram_api::Updates *u LOG(ERROR) << "Receive multiple edit message updates in " << to_string(*updates_ptr); pts = 0; } else if (pts == 0) { - LOG(ERROR) << "Receive no edit message updates for " << full_message_id << " in " << to_string(*updates_ptr); + LOG(ERROR) << "Receive no edit message updates for " << message_full_id << " in " << to_string(*updates_ptr); } return pts; } @@ -1530,7 +1695,7 @@ void UpdatesManager::init_state() { return; } - bool drop_state = td_->can_ignore_background_updates() && td_->auth_manager_->is_bot() && + bool drop_state = get_pts() == -1 && td_->can_ignore_background_updates() && td_->auth_manager_->is_bot() && td_->option_manager_->get_option_integer("since_last_open") >= 2 * 86400; auto pmc = G()->td_db()->get_binlog_pmc(); @@ -1621,6 +1786,16 @@ void UpdatesManager::on_server_pong(tl_object_ptr & } } +void UpdatesManager::notify_speed_limited(bool is_upload) { + if (Time::now() < next_notify_speed_limited_[is_upload]) { + return; + } + next_notify_speed_limited_[is_upload] = + Time::now() + + static_cast(td_->option_manager_->get_option_integer("upload_premium_speedup_notify_period")); + send_closure(G()->td(), &Td::send_update, td_api::make_object(is_upload)); +} + void UpdatesManager::process_get_difference_updates( vector> &&new_messages, vector> &&new_encrypted_messages, @@ -1639,6 +1814,14 @@ void UpdatesManager::process_get_difference_updates( CHECK(!running_get_difference_); } + if (constructor_id == telegram_api::updateStoryID::ID) { + LOG(INFO) << "Receive update about sent story " << to_string(update); + auto update_story_id = move_tl_object_as(update); + td_->story_manager_->on_update_story_id(update_story_id->random_id_, StoryId(update_story_id->id_), + "getDifference"); + CHECK(!running_get_difference_); + } + if (constructor_id == telegram_api::updateEncryption::ID) { on_update(move_tl_object_as(update), Promise()); CHECK(!running_get_difference_); @@ -1693,14 +1876,13 @@ void UpdatesManager::process_get_difference_updates( } void UpdatesManager::on_get_difference(tl_object_ptr &&difference_ptr) { - VLOG(get_difference) << "----- END GET DIFFERENCE-----"; - running_get_difference_ = false; - - if (!td_->auth_manager_->is_authorized()) { - // just in case + if (G()->close_flag() || !td_->auth_manager_->is_authorized()) { return; } + VLOG(get_difference) << "----- END GET DIFFERENCE-----"; + running_get_difference_ = false; + LOG(DEBUG) << "Result of get difference: " << to_string(difference_ptr); CHECK(difference_ptr != nullptr); @@ -1728,7 +1910,7 @@ void UpdatesManager::on_get_difference(tl_object_ptr(difference_ptr); VLOG(get_difference) << "In get difference receive " << difference->users_.size() << " users and " << difference->chats_.size() << " chats"; - td_->contacts_manager_->on_get_users(std::move(difference->users_), "updates.difference"); - td_->contacts_manager_->on_get_chats(std::move(difference->chats_), "updates.difference"); + td_->user_manager_->on_get_users(std::move(difference->users_), "updates.difference"); + td_->chat_manager_->on_get_chats(std::move(difference->chats_), "updates.difference"); + + if (get_difference_retry_count_ <= 5) { + for (const auto &message : difference->new_messages_) { + if (MessagesManager::is_invalid_poll_message(message.get())) { + get_difference_retry_count_++; + LOG(ERROR) << "Receive invalid poll message in updates.difference after " << get_difference_retry_count_ + << " tries"; + return run_get_difference(true, "reget difference"); + } + } + } process_get_difference_updates(std::move(difference->new_messages_), std::move(difference->new_encrypted_messages_), @@ -1762,8 +1955,19 @@ void UpdatesManager::on_get_difference(tl_object_ptrusers_.size() << " users and " << difference->chats_.size() << " chats"; - td_->contacts_manager_->on_get_users(std::move(difference->users_), "updates.differenceSlice"); - td_->contacts_manager_->on_get_chats(std::move(difference->chats_), "updates.differenceSlice"); + td_->user_manager_->on_get_users(std::move(difference->users_), "updates.differenceSlice"); + td_->chat_manager_->on_get_chats(std::move(difference->chats_), "updates.differenceSlice"); + + if (get_difference_retry_count_ <= 5) { + for (const auto &message : difference->new_messages_) { + if (MessagesManager::is_invalid_poll_message(message.get())) { + get_difference_retry_count_++; + LOG(ERROR) << "Receive invalid poll message in updates.differenceSlice after " + << get_difference_retry_count_ << " tries"; + return run_get_difference(true, "reget difference"); + } + } + } process_get_difference_updates(std::move(difference->new_messages_), std::move(difference->new_encrypted_messages_), @@ -1813,18 +2017,113 @@ void UpdatesManager::on_get_difference(tl_object_ptr difference_ptr) { + if (G()->close_flag() || !td_->auth_manager_->is_authorized()) { + return; + } + LOG(DEBUG) << "Receive update with PTS " << pts << ": " << to_string(difference_ptr); + if (get_pts() != pts - 1 || running_get_difference_ || !postponed_pts_updates_.empty() || + pending_pts_updates_.empty() || pending_pts_updates_.begin()->pts > pts + 1 || + pending_pts_updates_.begin()->pts != pts + pending_pts_updates_.begin()->pts_count) { + return; + } + + switch (difference_ptr->get_id()) { + case telegram_api::updates_difference::ID: { + auto difference = move_tl_object_as(difference_ptr); + difference_ptr = telegram_api::make_object( + std::move(difference->new_messages_), std::move(difference->new_encrypted_messages_), + std::move(difference->other_updates_), std::move(difference->chats_), std::move(difference->users_), + std::move(difference->state_)); + } + // fallthrough + case telegram_api::updates_differenceSlice::ID: { + auto difference = move_tl_object_as(difference_ptr); + + if (have_update_pts_changed(difference->other_updates_)) { + return; + } + + td_->user_manager_->on_get_users(std::move(difference->users_), "on_get_pts_update"); + td_->chat_manager_->on_get_chats(std::move(difference->chats_), "on_get_pts_update"); + + for (auto &message : difference->new_messages_) { + difference->other_updates_.push_back( + telegram_api::make_object(std::move(message), pts, 1)); + } + telegram_api::object_ptr *update_ptr = nullptr; + size_t update_count = 0; + for (auto &update : difference->other_updates_) { + auto constructor_id = update->get_id(); + if (constructor_id == telegram_api::updateMessageID::ID) { + // in getDifference updateMessageID can't be received for scheduled messages + LOG(INFO) << "Receive update about sent message " << to_string(update); + auto update_message_id = move_tl_object_as(update); + td_->messages_manager_->on_update_message_id( + update_message_id->random_id_, MessageId(ServerMessageId(update_message_id->id_)), "on_get_pts_update"); + continue; + } + if (constructor_id == telegram_api::updateDeleteMessages::ID) { + auto *update_delete_messages = static_cast(update.get()); + if (update_delete_messages->pts_count_ != 0 || update_delete_messages->messages_.size() != 1) { + LOG(ERROR) << "Receive in getDifference " << to_string(update); + } + } + + update_ptr = &update; + update_count++; + } + + if (!difference->new_encrypted_messages_.empty() || update_count != 1) { + LOG(ERROR) << "Receive unexpected updates with PTS " << pts << ": " << to_string(difference); + break; + } + + CHECK(update_ptr != nullptr); + VLOG(get_difference) << "Repair update with PTS " << pts; + pts_fixed_short_gap_++; + add_pending_pts_update(std::move(*update_ptr), pts, 1, Time::now(), Promise(), "on_get_pts_update"); + break; + } + case telegram_api::updates_differenceEmpty::ID: + case telegram_api::updates_differenceTooLong::ID: { + LOG(ERROR) << "Receive " << oneline(to_string(difference_ptr)) << " for request with PTS = " << pts - 1 + << ", but have pending " << oneline(to_string(pending_pts_updates_.begin()->update)) + << " with PTS = " << pending_pts_updates_.begin()->pts; + break; + default: + UNREACHABLE(); + } + } +} + +void UpdatesManager::confirm_pts_qts(int32 qts) { + int32 pts = get_pts(); + if (pts < 0) { + pts = 0; + } + + td_->create_handler()->send(pts, qts); + + last_confirmed_pts_ = pts; + last_confirmed_qts_ = qts; +} + void UpdatesManager::after_get_difference() { CHECK(!running_get_difference_); retry_timeout_.cancel_timeout(); retry_time_ = 1; - finished_first_get_difference_ = true; + skipped_postponed_updates_after_start_ = 0; td_->option_manager_->set_option_empty("since_last_open"); // cancels qts_gap_timeout_ if needed, can apply some updates received during getDifference, @@ -1846,12 +2145,12 @@ void UpdatesManager::after_get_difference() { size_t total_update_count = 0; while (!postponed_updates_.empty()) { auto it = postponed_updates_.begin(); - auto updates = std::move(it->second.updates); - auto updates_seq_begin = it->second.seq_begin; - auto updates_seq_end = it->second.seq_end; - auto receive_time = it->second.receive_time; - auto promise = std::move(it->second.promise); - // ignore it->second.date, because it may be too old + auto updates = std::move(it->updates); + auto updates_seq_begin = it->seq_begin; + auto updates_seq_end = it->seq_end; + auto receive_time = it->receive_time; + auto promise = std::move(it->promise); + // ignore it->date, because it may be too old postponed_updates_.erase(it); auto update_count = updates.size(); on_pending_updates(std::move(updates), updates_seq_begin, updates_seq_end, 0, receive_time, std::move(promise), @@ -1878,10 +2177,11 @@ void UpdatesManager::after_get_difference() { auto begin_time = Time::now(); auto update_count = postponed_updates.size(); + auto old_pts = get_pts(); VLOG(get_difference) << "Begin to apply " << postponed_updates.size() << " postponed PTS updates with PTS = " << get_pts(); for (auto &postponed_update : postponed_updates) { - auto &update = postponed_update.second; + auto &update = postponed_update; add_pending_pts_update(std::move(update.update), update.pts, update.pts_count, update.receive_time, std::move(update.promise), AFTER_GET_DIFFERENCE_SOURCE); CHECK(!running_get_difference_); @@ -1891,8 +2191,9 @@ void UpdatesManager::after_get_difference() { << postponed_pts_updates_.size() << " pending PTS updates"; auto passed_time = Time::now() - begin_time; if (passed_time >= UPDATE_APPLY_WARNING_TIME) { - LOG(WARNING) << "Applied " << update_count << " PTS updates in " << passed_time - << " seconds after postponing them for " << (Time::now() - get_difference_start_time_) << " seconds"; + LOG(WARNING) << "Updated PTS from " << old_pts << " to " << get_pts() << " and applied " << update_count + << " PTS updates in " << passed_time << " seconds after postponing them for " + << (Time::now() - get_difference_start_time_) << " seconds"; } } @@ -1929,7 +2230,7 @@ void UpdatesManager::try_reload_data_static(void *td) { void UpdatesManager::try_reload_data() { if (!td_->auth_manager_->is_authorized() || td_->auth_manager_->is_bot() || running_get_difference_ || - !td_->is_online()) { + !td_->online_manager_->is_online()) { return; } @@ -1947,19 +2248,28 @@ void UpdatesManager::try_reload_data() { LOG(INFO) << "Reload data"; td_->animations_manager_->reload_saved_animations(true); td_->autosave_manager_->reload_autosave_settings(); - td_->contacts_manager_->reload_created_public_dialogs(PublicDialogType::HasUsername, std::move(promise)); - td_->contacts_manager_->reload_created_public_dialogs(PublicDialogType::IsLocationBased, Auto()); + td_->chat_manager_->reload_created_public_dialogs(PublicDialogType::HasUsername, std::move(promise)); + td_->chat_manager_->reload_created_public_dialogs(PublicDialogType::IsLocationBased, Auto()); + td_->chat_manager_->reload_created_public_dialogs(PublicDialogType::ForPersonalDialog, Auto()); get_default_emoji_statuses(td_, Auto()); + get_default_channel_emoji_statuses(td_, Auto()); + reload_paid_reaction_privacy(td_); td_->notification_settings_manager_->reload_saved_ringtones(Auto()); + td_->notification_settings_manager_->send_get_reaction_notification_settings_query(Auto()); td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Private, Auto()); td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Group, Auto()); td_->notification_settings_manager_->send_get_scope_notification_settings_query(NotificationSettingsScope::Channel, Auto()); - td_->stickers_manager_->reload_reactions(); - td_->stickers_manager_->reload_recent_reactions(); - td_->stickers_manager_->reload_top_reactions(); + td_->quick_reply_manager_->reload_quick_reply_shortcuts(); + td_->reaction_manager_->reload_reactions(); + td_->reaction_manager_->reload_message_effects(); + for (int32 type = 0; type < MAX_REACTION_LIST_TYPE; type++) { + auto reaction_list_type = static_cast(type); + td_->reaction_manager_->reload_reaction_list(reaction_list_type, "try_reload_data"); + } + td_->star_manager_->reload_owned_star_count(); for (int32 type = 0; type < MAX_STICKER_TYPE; type++) { auto sticker_type = static_cast(type); td_->stickers_manager_->get_installed_sticker_sets(sticker_type, Auto()); @@ -1973,9 +2283,19 @@ void UpdatesManager::try_reload_data() { td_->stickers_manager_->reload_special_sticker_set_by_type(SpecialStickerSetType::premium_gifts()); td_->stickers_manager_->reload_special_sticker_set_by_type(SpecialStickerSetType::generic_animations()); td_->stickers_manager_->reload_special_sticker_set_by_type(SpecialStickerSetType::default_statuses()); + td_->stickers_manager_->reload_special_sticker_set_by_type(SpecialStickerSetType::default_channel_statuses()); td_->stickers_manager_->reload_special_sticker_set_by_type(SpecialStickerSetType::default_topic_icons()); - td_->stickers_manager_->get_default_dialog_photo_custom_emoji_stickers(false, true, Auto()); - td_->stickers_manager_->get_default_dialog_photo_custom_emoji_stickers(true, true, Auto()); + td_->stickers_manager_->get_default_custom_emoji_stickers(StickerListType::DialogPhoto, true, Auto()); + td_->stickers_manager_->get_default_custom_emoji_stickers(StickerListType::UserProfilePhoto, true, Auto()); + td_->stickers_manager_->get_default_custom_emoji_stickers(StickerListType::Background, true, Auto()); + td_->stickers_manager_->get_sticker_list_emoji_statuses(StickerListType::DisallowedChannelEmojiStatus, true, Auto()); + td_->story_manager_->reload_active_stories(); + td_->story_manager_->reload_all_read_stories(); + td_->theme_manager_->reload_accent_colors(); + td_->theme_manager_->reload_chat_themes(); + td_->theme_manager_->reload_profile_accent_colors(); + td_->time_zone_manager_->reload_time_zones(Auto()); + td_->user_manager_->reload_contact_birthdates(false); schedule_data_reload(); } @@ -1990,32 +2310,6 @@ void UpdatesManager::on_data_reloaded() { schedule_data_reload(); } -void UpdatesManager::subscribe_to_transcribed_audio_updates(int64 transcription_id, TranscribedAudioHandler on_update) { - CHECK(transcription_id != 0); - if (pending_audio_transcriptions_.count(transcription_id) != 0) { - on_pending_audio_transcription_failed(transcription_id, - Status::Error(500, "Receive duplicate speech recognition identifier")); - } - bool is_inserted = pending_audio_transcriptions_.emplace(transcription_id, std::move(on_update)).second; - CHECK(is_inserted); - pending_audio_transcription_timeout_.set_timeout_in(transcription_id, AUDIO_TRANSCRIPTION_TIMEOUT); -} - -void UpdatesManager::on_pending_audio_transcription_failed(int64 transcription_id, Status &&error) { - if (G()->close_flag()) { - return; - } - auto it = pending_audio_transcriptions_.find(transcription_id); - if (it == pending_audio_transcriptions_.end()) { - return; - } - auto on_update = std::move(it->second); - pending_audio_transcriptions_.erase(it); - pending_audio_transcription_timeout_.cancel_timeout(transcription_id); - - on_update(std::move(error)); -} - void UpdatesManager::on_pending_updates(vector> &&updates, int32 seq_begin, int32 seq_end, int32 date, double receive_time, Promise &&promise, const char *source) { @@ -2090,7 +2384,7 @@ void UpdatesManager::on_pending_updates(vectorcontacts_manager_->have_channel_force(channel_id)) { + if (td_->chat_manager_->have_channel_force(channel_id, source)) { if (td_->messages_manager_->is_old_channel_update(dialog_id, pts)) { // the update will be ignored anyway, so there is no reason to replace it or force get_difference LOG(INFO) << "Allow an outdated unacceptable update from " << source; @@ -2122,7 +2416,7 @@ void UpdatesManager::on_pending_updates(vectorcontacts_manager_->on_update_user_local_was_online(user_id, date); + td_->user_manager_->on_update_user_local_was_online(user_id, date); } } } @@ -2189,7 +2483,6 @@ void UpdatesManager::on_pending_updates(vectorget_id(); if (id == telegram_api::updateMessageID::ID) { - LOG(INFO) << "Receive from " << source << " " << to_string(update); auto sent_message_update = move_tl_object_as(update); MessageId message_id; if (ordinary_new_message_count != 0) { @@ -2204,6 +2497,11 @@ void UpdatesManager::on_pending_updates(vector(update); + td_->story_manager_->on_update_story_id(update_story_id->random_id_, StoryId(update_story_id->id_), source); + update = nullptr; + } if (id == telegram_api::updateFolderPeers::ID) { on_update(move_tl_object_as(update), get_promise()); update = nullptr; @@ -2270,8 +2568,7 @@ void UpdatesManager::on_pending_updates(vector int32 old_qts = get_qts(); LOG(INFO) << "Process update with QTS = " << qts << ", current QTS = " << old_qts; - if (qts < old_qts - 100001) { + if (qts < old_qts - 1000009) { LOG(WARNING) << "Restore QTS after QTS overflow from " << old_qts << " to " << qts << " by " << oneline(to_string(update)); add_qts(qts - 1).set_value(Unit()); @@ -2513,7 +2807,7 @@ void UpdatesManager::add_pending_pts_update(tl_object_ptr // do not try to run getDifference from this function CHECK(update != nullptr); CHECK(source != nullptr); - LOG(INFO) << "Receive from " << source << " pending " << to_string(update); + LOG(INFO) << "Receive from " << source << " with pts_count = " << pts_count << " pending " << to_string(update); if (pts_count < 0 || new_pts <= pts_count) { LOG(ERROR) << "Receive update with wrong PTS = " << new_pts << " or pts_count = " << pts_count << " from " << source << ": " << oneline(to_string(update)); @@ -2528,7 +2822,7 @@ void UpdatesManager::add_pending_pts_update(tl_object_ptr return promise.set_value(Unit()); } - if (DROP_PTS_UPDATES) { + if (DROP_PTS_UPDATES && Slice(source) != Slice("on_get_pts_update")) { set_pts_gap_timeout(1.0); return promise.set_value(Unit()); } @@ -2537,8 +2831,14 @@ void UpdatesManager::add_pending_pts_update(tl_object_ptr if (new_pts < old_pts - 99 && source != AFTER_GET_DIFFERENCE_SOURCE) { bool need_restore_pts = new_pts < old_pts - 19999; auto now = Time::now(); - if (now > last_pts_jump_warning_time_ + 1 && (need_restore_pts || now < last_pts_jump_warning_time_ + 5) && - !(old_pts == std::numeric_limits::max() && running_get_difference_)) { + if (old_pts == 2100000000 && new_pts < 1100000000 && pts_count <= 10000 && + td_->option_manager_->get_option_integer("session_count") > 1) { + set_pts(1, "restore PTS").set_value(Unit()); + old_pts = get_pts(); + set_pts_gap_timeout(0.001); + return promise.set_value(Unit()); + } else if (now > last_pts_jump_warning_time_ + 1 && need_restore_pts && + !(old_pts == std::numeric_limits::max() && running_get_difference_)) { LOG(ERROR) << "Restore PTS after delete_first_messages from " << old_pts << " to " << new_pts << " is disabled, pts_count = " << pts_count << ", update is from " << source << ": " << oneline(to_string(update)); @@ -2546,13 +2846,6 @@ void UpdatesManager::add_pending_pts_update(tl_object_ptr } if (need_restore_pts) { set_pts_gap_timeout(0.001); - - /* - LOG(WARNING) << "Restore PTS after delete_first_messages"; - set_pts(new_pts - 1, "restore PTS after delete_first_messages"); - old_pts = get_pts(); - CHECK(old_pts == new_pts - 1); - */ } } @@ -2615,20 +2908,29 @@ void UpdatesManager::add_pending_pts_update(tl_object_ptr .set_value(Unit()); // TODO can't set until data are really stored on persistent storage accumulated_pts_count_ = 0; accumulated_pts_ = -1; + } else { + LOG(DEBUG) << "There is no need to process the update"; } promise.set_value(Unit()); return; } - pending_pts_updates_.emplace( - new_pts, PendingPtsUpdate(std::move(update), new_pts, pts_count, receive_time, std::move(promise))); + if (pts_count == 0 && receive_time < Time::now() - MAX_UNFILLED_GAP_TIME && update->get_id() == dummyUpdate::ID) { + // don't warn about fetching of affected history + expect_pts_gap_ = true; + } + + pending_pts_updates_.emplace(std::move(update), new_pts, pts_count, receive_time, std::move(promise)); if (old_pts < accumulated_pts_ - accumulated_pts_count_) { if (old_pts == new_pts - pts_count) { // can't apply all updates, but can apply this and probably some other updates process_pending_pts_updates(); } else { - set_pts_gap_timeout(receive_time + MAX_UNFILLED_GAP_TIME - Time::now()); + LOG(DEBUG) << "Can't process PTS updates, because current PTS = " << old_pts << ", new PTS = " << new_pts + << ", pts_count = " << pts_count << ", maximum known PTS = " << accumulated_pts_ + << ", accumulated_pts_count = " << accumulated_pts_count_; + set_pts_gap_timeout(max(receive_time + MAX_UNFILLED_GAP_TIME - Time::now(), 0.001)); } return; } @@ -2639,11 +2941,10 @@ void UpdatesManager::add_pending_pts_update(tl_object_ptr void UpdatesManager::postpone_pts_update(tl_object_ptr &&update, int32 pts, int32 pts_count, double receive_time, Promise &&promise) { - if (!can_postpone_updates()) { + if (!can_postpone_updates() || (pts_count > 1 && td_->option_manager_->get_option_integer("session_count") <= 1)) { return promise.set_value(Unit()); } - postponed_pts_updates_.emplace(pts, - PendingPtsUpdate(std::move(update), pts, pts_count, receive_time, std::move(promise))); + postponed_pts_updates_.emplace(std::move(update), pts, pts_count, receive_time, std::move(promise)); } void UpdatesManager::process_seq_updates(int32 seq_end, int32 date, @@ -2671,61 +2972,165 @@ void UpdatesManager::process_seq_updates(int32 seq_end, int32 date, void UpdatesManager::process_qts_update(tl_object_ptr &&update_ptr, int32 qts, Promise &&promise) { LOG(DEBUG) << "Process " << to_string(update_ptr); - if (last_confirmed_qts_ < qts - FORCED_GET_DIFFERENCE_PTS_DIFF) { - if (last_confirmed_qts_ != 0) { - schedule_get_difference("rare QTS getDifference"); - } - last_confirmed_qts_ = qts; - } - switch (update_ptr->get_id()) { - case telegram_api::updateNewEncryptedMessage::ID: { - auto update = move_tl_object_as(update_ptr); - send_closure(td_->secret_chats_manager_, &SecretChatsManager::on_new_message, std::move(update->message_), - add_qts(qts)); - break; - } - case telegram_api::updateMessagePollVote::ID: { - auto update = move_tl_object_as(update_ptr); - td_->poll_manager_->on_get_poll_vote(PollId(update->poll_id_), UserId(update->user_id_), - std::move(update->options_)); - add_qts(qts).set_value(Unit()); - break; - } - case telegram_api::updateBotStopped::ID: { - auto update = move_tl_object_as(update_ptr); - td_->contacts_manager_->on_update_bot_stopped(UserId(update->user_id_), update->date_, update->stopped_); - add_qts(qts).set_value(Unit()); - break; - } - case telegram_api::updateChatParticipant::ID: { - auto update = move_tl_object_as(update_ptr); - td_->contacts_manager_->on_update_chat_participant( - ChatId(update->chat_id_), UserId(update->actor_id_), update->date_, - DialogInviteLink(std::move(update->invite_), true, "updateChatParticipant"), - std::move(update->prev_participant_), std::move(update->new_participant_)); - add_qts(qts).set_value(Unit()); - break; - } - case telegram_api::updateChannelParticipant::ID: { - auto update = move_tl_object_as(update_ptr); - td_->contacts_manager_->on_update_channel_participant( - ChannelId(update->channel_id_), UserId(update->actor_id_), update->date_, - DialogInviteLink(std::move(update->invite_), true, "updateChannelParticipant"), update->via_chatlist_, - std::move(update->prev_participant_), std::move(update->new_participant_)); - add_qts(qts).set_value(Unit()); - break; - } - case telegram_api::updateBotChatInviteRequester::ID: { - auto update = move_tl_object_as(update_ptr); - td_->contacts_manager_->on_update_chat_invite_requester( - DialogId(update->peer_), UserId(update->user_id_), std::move(update->about_), update->date_, - DialogInviteLink(std::move(update->invite_), true, "updateBotChatInviteRequester")); - add_qts(qts).set_value(Unit()); - break; + if (last_confirmed_qts_ < qts - FORCED_GET_DIFFERENCE_PTS_DIFF && last_confirmed_qts_ != 0) { + confirm_pts_qts(qts); + } + qts_diff_++; + if (qts_diff_ >= 1000000) { + LOG(WARNING) << "Fixed " << qts_gap_ << " QTS gaps up to QTS " << qts; + qts_gap_ = 0; + qts_diff_ = 0; + } + auto constructor_id = update_ptr->get_id(); + if (constructor_id == telegram_api::updateNewEncryptedMessage::ID) { + auto update = move_tl_object_as(update_ptr); + send_closure(td_->secret_chats_manager_, &SecretChatsManager::on_new_message, std::move(update->message_), + add_qts(qts)); + } else if (td_->auth_manager_->is_bot()) { + switch (constructor_id) { + case telegram_api::updateMessagePollVote::ID: { + auto update = move_tl_object_as(update_ptr); + td_->poll_manager_->on_get_poll_vote(PollId(update->poll_id_), DialogId(update->peer_), + std::move(update->options_)); + break; + } + case telegram_api::updateBotStopped::ID: { + auto update = move_tl_object_as(update_ptr); + td_->dialog_participant_manager_->on_update_bot_stopped(UserId(update->user_id_), update->date_, + update->stopped_); + break; + } + case telegram_api::updateChatParticipant::ID: { + auto update = move_tl_object_as(update_ptr); + bool via_join_request = + update->invite_ != nullptr && update->invite_->get_id() == telegram_api::chatInvitePublicJoinRequests::ID; + td_->dialog_participant_manager_->on_update_chat_participant( + ChatId(update->chat_id_), UserId(update->actor_id_), update->date_, + DialogInviteLink(std::move(update->invite_), true, true, "updateChatParticipant"), via_join_request, + std::move(update->prev_participant_), std::move(update->new_participant_)); + break; + } + case telegram_api::updateChannelParticipant::ID: { + auto update = move_tl_object_as(update_ptr); + bool via_join_request = + update->invite_ != nullptr && update->invite_->get_id() == telegram_api::chatInvitePublicJoinRequests::ID; + td_->dialog_participant_manager_->on_update_channel_participant( + ChannelId(update->channel_id_), UserId(update->actor_id_), update->date_, + DialogInviteLink(std::move(update->invite_), true, true, "updateChannelParticipant"), via_join_request, + update->via_chatlist_, std::move(update->prev_participant_), std::move(update->new_participant_)); + break; + } + case telegram_api::updateBotChatInviteRequester::ID: { + auto update = move_tl_object_as(update_ptr); + td_->dialog_participant_manager_->on_update_chat_invite_requester( + DialogId(update->peer_), UserId(update->user_id_), std::move(update->about_), update->date_, + DialogInviteLink(std::move(update->invite_), true, true, "updateBotChatInviteRequester")); + break; + } + case telegram_api::updateBotChatBoost::ID: { + auto update = move_tl_object_as(update_ptr); + td_->boost_manager_->on_update_dialog_boost(DialogId(update->peer_), std::move(update->boost_)); + break; + } + case telegram_api::updateBotMessageReaction::ID: { + auto update = move_tl_object_as(update_ptr); + auto dialog_id = DialogId(update->peer_); + auto message_id = MessageId(ServerMessageId(update->msg_id_)); + auto date = update->date_; + auto actor_dialog_id = DialogId(update->actor_); + auto old_reaction_types = ReactionType::get_reaction_types(update->old_reactions_); + auto new_reaction_types = ReactionType::get_reaction_types(update->new_reactions_); + if (!dialog_id.is_valid() || !message_id.is_valid() || !actor_dialog_id.is_valid() || date <= 0 || + old_reaction_types == new_reaction_types) { + LOG(ERROR) << "Receive invalid updateBotMessageReaction for " << MessageFullId{dialog_id, message_id} + << " by " << actor_dialog_id << " at " << date << ": " << old_reaction_types << " -> " + << new_reaction_types; + break; + } + + td_->dialog_manager_->force_create_dialog(dialog_id, "on_update_bot_message_reaction", true); + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "updateMessageReaction"), message_id.get(), + get_message_sender_object(td_, actor_dialog_id, "updateMessageReaction"), date, + ReactionType::get_reaction_types_object(old_reaction_types, false), + ReactionType::get_reaction_types_object(new_reaction_types, false))); + break; + } + case telegram_api::updateBotMessageReactions::ID: { + auto update = move_tl_object_as(update_ptr); + auto dialog_id = DialogId(update->peer_); + auto message_id = MessageId(ServerMessageId(update->msg_id_)); + auto date = update->date_; + if (!dialog_id.is_valid() || !message_id.is_valid() || date <= 0) { + LOG(ERROR) << "Receive invalid " << to_string(update); + break; + } + vector> message_reactions; + for (const auto &reaction_count : update->reactions_) { + auto reaction_type = ReactionType(reaction_count->reaction_); + if (reaction_type.is_empty() || reaction_count->count_ <= 0) { + LOG(ERROR) << "Receive invalid reaction in updateBotMessageReactions for " + << MessageFullId{dialog_id, message_id} << " at " << date << ": " << to_string(reaction_count); + continue; + } + message_reactions.push_back(td_api::make_object( + reaction_type.get_reaction_type_object(), reaction_count->count_, false, nullptr, Auto())); + } + td_->dialog_manager_->force_create_dialog(dialog_id, "on_update_bot_message_reactions", true); + send_closure(G()->td(), &Td::send_update, + td_api::make_object( + td_->dialog_manager_->get_chat_id_object(dialog_id, "updateMessageReactions"), + message_id.get(), date, std::move(message_reactions))); + break; + } + case telegram_api::updateBotPurchasedPaidMedia::ID: { + auto update = move_tl_object_as(update_ptr); + auto user_id = UserId(update->user_id_); + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << to_string(update); + break; + } + send_closure( + G()->td(), &Td::send_update, + td_api::make_object( + td_->user_manager_->get_user_id_object(user_id, "updatePaidMediaPurchased"), update->payload_)); + break; + } + case telegram_api::updateBotBusinessConnect::ID: { + auto update = move_tl_object_as(update_ptr); + td_->business_connection_manager_->on_update_bot_business_connect(std::move(update->connection_)); + break; + } + case telegram_api::updateBotNewBusinessMessage::ID: { + auto update = move_tl_object_as(update_ptr); + td_->business_connection_manager_->on_update_bot_new_business_message( + BusinessConnectionId(std::move(update->connection_id_)), std::move(update->message_), + std::move(update->reply_to_message_)); + break; + } + case telegram_api::updateBotEditBusinessMessage::ID: { + auto update = move_tl_object_as(update_ptr); + td_->business_connection_manager_->on_update_bot_edit_business_message( + BusinessConnectionId(std::move(update->connection_id_)), std::move(update->message_), + std::move(update->reply_to_message_)); + break; + } + case telegram_api::updateBotDeleteBusinessMessage::ID: { + auto update = move_tl_object_as(update_ptr); + td_->business_connection_manager_->on_update_bot_delete_business_messages( + BusinessConnectionId(std::move(update->connection_id_)), DialogId(update->peer_), + std::move(update->messages_)); + break; + } + default: + UNREACHABLE(); + break; } - default: - UNREACHABLE(); - break; + add_qts(qts).set_value(Unit()); + } else { + add_qts(qts).set_value(Unit()); + LOG(ERROR) << "Receive " << to_string(update_ptr); } promise.set_value(Unit()); } @@ -2733,8 +3138,8 @@ void UpdatesManager::process_qts_update(tl_object_ptr &&up void UpdatesManager::process_all_pending_pts_updates() { auto begin_time = Time::now(); for (auto &update : pending_pts_updates_) { - td_->messages_manager_->process_pts_update(std::move(update.second.update)); - update.second.promise.set_value(Unit()); + td_->messages_manager_->process_pts_update(std::move(update.update)); + update.promise.set_value(Unit()); } if (last_pts_gap_time_ != 0) { @@ -2755,6 +3160,7 @@ void UpdatesManager::process_all_pending_pts_updates() { void UpdatesManager::drop_all_pending_pts_updates() { accumulated_pts_count_ = 0; accumulated_pts_ = -1; + min_pts_gap_timeout_.cancel_timeout(); pts_gap_timeout_.cancel_timeout(); pending_pts_updates_.clear(); } @@ -2771,18 +3177,18 @@ void UpdatesManager::process_postponed_pts_updates() { int32 applied_update_count = 0; auto update_it = postponed_pts_updates_.begin(); while (update_it != postponed_pts_updates_.end()) { - auto new_pts = update_it->second.pts; - auto pts_count = update_it->second.pts_count; + auto new_pts = update_it->pts; + auto pts_count = update_it->pts_count; if (new_pts <= old_pts || (old_pts >= 1 && new_pts - (1 << 30) > old_pts)) { skipped_update_count++; - td_->messages_manager_->skip_old_pending_pts_update(std::move(update_it->second.update), new_pts, old_pts, - pts_count, "process_postponed_pts_updates"); - update_it->second.promise.set_value(Unit()); + td_->messages_manager_->skip_old_pending_pts_update(std::move(update_it->update), new_pts, old_pts, pts_count, + "process_postponed_pts_updates"); + update_it->promise.set_value(Unit()); update_it = postponed_pts_updates_.erase(update_it); continue; } - if (Time::now() - begin_time >= td::min(UPDATE_APPLY_WARNING_TIME / 2, 0.1)) { + if (Time::now() - begin_time >= 0.1) { // the updates will be applied or skipped later; reget the remaining updates through getDifference break; } @@ -2797,15 +3203,15 @@ void UpdatesManager::process_postponed_pts_updates() { if (old_pts > new_pts - pts_count || last_update_it == postponed_pts_updates_.end() || i == GAP_TIMEOUT_UPDATE_COUNT) { // the updates can't be applied - VLOG(get_difference) << "Can't apply " << i << " next postponed updates with PTS " << update_it->second.pts - << '-' << new_pts << ", because their pts_count is " << pts_count - << " instead of expected " << new_pts - old_pts; + VLOG(get_difference) << "Can't apply " << i << " next postponed updates with PTS " << update_it->pts << '-' + << new_pts << ", because their pts_count is " << pts_count << " instead of expected " + << new_pts - old_pts; last_update_it = update_it; break; } - new_pts = last_update_it->second.pts; - pts_count += last_update_it->second.pts_count; + new_pts = last_update_it->pts; + pts_count += last_update_it->pts_count; } if (last_update_it == update_it) { @@ -2815,11 +3221,11 @@ void UpdatesManager::process_postponed_pts_updates() { CHECK(old_pts == new_pts - pts_count); while (update_it != last_update_it) { - if (update_it->second.pts_count > 0) { + if (update_it->pts_count > 0) { applied_update_count++; - td_->messages_manager_->process_pts_update(std::move(update_it->second.update)); + td_->messages_manager_->process_pts_update(std::move(update_it->update)); } - update_it->second.promise.set_value(Unit()); + update_it->promise.set_value(Unit()); update_it = postponed_pts_updates_.erase(update_it); } old_pts = new_pts; @@ -2854,7 +3260,7 @@ void UpdatesManager::process_pending_pts_updates() { int32 applied_update_count = 0; while (!pending_pts_updates_.empty()) { auto update_it = pending_pts_updates_.begin(); - auto &update = update_it->second; + auto &update = *update_it; if (get_pts() != update.pts - update.pts_count) { // the updates will be applied or skipped later break; @@ -2871,24 +3277,27 @@ void UpdatesManager::process_pending_pts_updates() { CHECK(accumulated_pts_count_ >= update.pts_count); accumulated_pts_count_ -= update.pts_count; } + } else { + LOG(INFO) << "Skip because of pts_count == 0 " << to_string(update.update); } update.promise.set_value(Unit()); pending_pts_updates_.erase(update_it); } if (applied_update_count > 0) { + min_pts_gap_timeout_.cancel_timeout(); pts_gap_timeout_.cancel_timeout(); } if (!pending_pts_updates_.empty()) { // if still have a gap, reset timeout auto update_it = pending_pts_updates_.begin(); - double receive_time = update_it->second.receive_time; + double receive_time = update_it->receive_time; for (size_t i = 0; i < GAP_TIMEOUT_UPDATE_COUNT; i++) { if (++update_it == pending_pts_updates_.end()) { break; } - receive_time = min(receive_time, update_it->second.receive_time); + receive_time = min(receive_time, update_it->receive_time); } - set_pts_gap_timeout(receive_time + MAX_UNFILLED_GAP_TIME - Time::now()); + set_pts_gap_timeout(max(receive_time + MAX_UNFILLED_GAP_TIME - Time::now(), 0.001)); } auto passed_time = Time::now() - begin_time; @@ -2910,7 +3319,7 @@ void UpdatesManager::process_pending_seq_updates() { int32 applied_update_count = 0; while (!pending_seq_updates_.empty() && !running_get_difference_) { auto update_it = pending_seq_updates_.begin(); - auto &update = update_it->second; + auto &update = *update_it; auto seq_begin = update.seq_begin; if (seq_begin - 1 > seq_ && seq_begin - (1 << 30) <= seq_) { // the updates will be applied later @@ -2938,12 +3347,12 @@ void UpdatesManager::process_pending_seq_updates() { if (!pending_seq_updates_.empty()) { // if still have a gap, reset timeout auto update_it = pending_seq_updates_.begin(); - double receive_time = update_it->second.receive_time; + double receive_time = update_it->receive_time; for (size_t i = 0; i < GAP_TIMEOUT_UPDATE_COUNT; i++) { if (++update_it == pending_seq_updates_.end()) { break; } - receive_time = min(receive_time, update_it->second.receive_time); + receive_time = min(receive_time, update_it->receive_time); } set_seq_gap_timeout(receive_time + MAX_UNFILLED_GAP_TIME - Time::now()); } @@ -3012,6 +3421,13 @@ void UpdatesManager::process_pending_qts_updates() { void UpdatesManager::set_pts_gap_timeout(double timeout) { if (!pts_gap_timeout_.has_timeout() || timeout < pts_gap_timeout_.get_timeout()) { + LOG(DEBUG) << "Set PTS gap timeout in " << timeout; + if (timeout > 2 * MIN_UNFILLED_GAP_TIME) { + min_pts_gap_timeout_.set_callback(std::move(check_pts_gap)); + min_pts_gap_timeout_.set_callback_data(static_cast(td_)); + min_pts_gap_timeout_.set_timeout_in(MIN_UNFILLED_GAP_TIME); + } + pts_gap_timeout_.set_callback(std::move(fill_pts_gap)); pts_gap_timeout_.set_callback_data(static_cast(td_)); pts_gap_timeout_.set_timeout_in(timeout); @@ -3021,6 +3437,7 @@ void UpdatesManager::set_pts_gap_timeout(double timeout) { void UpdatesManager::set_seq_gap_timeout(double timeout) { if (!seq_gap_timeout_.has_timeout() || timeout < seq_gap_timeout_.get_timeout()) { + LOG(DEBUG) << "Set seq gap timeout in " << timeout; seq_gap_timeout_.set_callback(std::move(fill_seq_gap)); seq_gap_timeout_.set_callback_data(static_cast(td_)); seq_gap_timeout_.set_timeout_in(timeout); @@ -3029,6 +3446,7 @@ void UpdatesManager::set_seq_gap_timeout(double timeout) { void UpdatesManager::set_qts_gap_timeout(double timeout) { if (!qts_gap_timeout_.has_timeout() || timeout < qts_gap_timeout_.get_timeout()) { + LOG(DEBUG) << "Set QTS gap timeout in " << timeout; qts_gap_timeout_.set_callback(std::move(fill_qts_gap)); qts_gap_timeout_.set_callback_data(static_cast(td_)); qts_gap_timeout_.set_timeout_in(timeout); @@ -3058,6 +3476,7 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { LOG(ERROR) << "Receive not in getDifference and not in on_pending_updates " << to_string(update); + promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, @@ -3107,7 +3526,7 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->messages_manager_->on_dialog_info_full_invalidated(DialogId(ChatId(update->chat_id_))); + td_->dialog_manager_->on_dialog_info_full_invalidated(DialogId(ChatId(update->chat_id_))); promise.set_value(Unit()); } @@ -3133,7 +3552,7 @@ void UpdatesManager::on_update(tl_object_ptr } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->invalidate_channel_full(ChannelId(update->channel_id_), false, "updateChannel"); + td_->chat_manager_->invalidate_channel_full(ChannelId(update->channel_id_), false, "updateChannel"); promise.set_value(Unit()); } @@ -3182,7 +3601,14 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { td_->messages_manager_->on_update_channel_max_unavailable_message_id( - ChannelId(update->channel_id_), MessageId(ServerMessageId(update->available_min_id_))); + ChannelId(update->channel_id_), MessageId(ServerMessageId(update->available_min_id_)), + "updateChannelAvailableMessages"); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + td_->messages_manager_->on_update_dialog_view_as_messages(DialogId(ChannelId(update->channel_id_)), update->enabled_); promise.set_value(Unit()); } @@ -3308,7 +3734,7 @@ void UpdatesManager::on_update(tl_object_ptr } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_peer_located(std::move(update->peers_), true); + td_->people_nearby_manager_->on_update_peer_located(std::move(update->peers_), true); promise.set_value(Unit()); } @@ -3334,7 +3760,17 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->stickers_manager_->reload_recent_reactions(); + td_->reaction_manager_->reload_reaction_list(ReactionListType::Recent, "updateRecentReactions"); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->reaction_manager_->on_update_saved_reaction_tags(Promise()); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->option_manager_->set_option_boolean("is_paid_reaction_anonymous", update->private_); promise.set_value(Unit()); } @@ -3477,6 +3913,14 @@ bool UpdatesManager::is_qts_update(const telegram_api::Update *update) { case telegram_api::updateChatParticipant::ID: case telegram_api::updateChannelParticipant::ID: case telegram_api::updateBotChatInviteRequester::ID: + case telegram_api::updateBotChatBoost::ID: + case telegram_api::updateBotMessageReaction::ID: + case telegram_api::updateBotMessageReactions::ID: + case telegram_api::updateBotBusinessConnect::ID: + case telegram_api::updateBotNewBusinessMessage::ID: + case telegram_api::updateBotEditBusinessMessage::ID: + case telegram_api::updateBotDeleteBusinessMessage::ID: + case telegram_api::updateBotPurchasedPaidMedia::ID: return true; default: return false; @@ -3497,6 +3941,22 @@ int32 UpdatesManager::get_update_qts(const telegram_api::Update *update) { return static_cast(update)->qts_; case telegram_api::updateBotChatInviteRequester::ID: return static_cast(update)->qts_; + case telegram_api::updateBotChatBoost::ID: + return static_cast(update)->qts_; + case telegram_api::updateBotMessageReaction::ID: + return static_cast(update)->qts_; + case telegram_api::updateBotMessageReactions::ID: + return static_cast(update)->qts_; + case telegram_api::updateBotBusinessConnect::ID: + return static_cast(update)->qts_; + case telegram_api::updateBotNewBusinessMessage::ID: + return static_cast(update)->qts_; + case telegram_api::updateBotEditBusinessMessage::ID: + return static_cast(update)->qts_; + case telegram_api::updateBotDeleteBusinessMessage::ID: + return static_cast(update)->qts_; + case telegram_api::updateBotPurchasedPaidMedia::ID: + return static_cast(update)->qts_; default: return 0; } @@ -3516,56 +3976,57 @@ bool UpdatesManager::is_channel_pts_update(const telegram_api::Update *update) { void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { DialogId dialog_id(UserId(update->user_id_)); - td_->messages_manager_->on_dialog_action(dialog_id, MessageId(), dialog_id, DialogAction(std::move(update->action_)), - get_short_update_date()); + td_->dialog_action_manager_->on_dialog_action(dialog_id, MessageId(), dialog_id, + DialogAction(std::move(update->action_)), get_short_update_date()); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->messages_manager_->on_dialog_action(DialogId(ChatId(update->chat_id_)), MessageId(), DialogId(update->from_id_), - DialogAction(std::move(update->action_)), get_short_update_date()); + td_->dialog_action_manager_->on_dialog_action(DialogId(ChatId(update->chat_id_)), MessageId(), + DialogId(update->from_id_), DialogAction(std::move(update->action_)), + get_short_update_date()); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->messages_manager_->on_dialog_action(DialogId(ChannelId(update->channel_id_)), - MessageId(ServerMessageId(update->top_msg_id_)), DialogId(update->from_id_), - DialogAction(std::move(update->action_)), get_short_update_date()); + td_->dialog_action_manager_->on_dialog_action( + DialogId(ChannelId(update->channel_id_)), MessageId(ServerMessageId(update->top_msg_id_)), + DialogId(update->from_id_), DialogAction(std::move(update->action_)), get_short_update_date()); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { SecretChatId secret_chat_id(update->chat_id_); - UserId user_id = td_->contacts_manager_->get_secret_chat_user_id(secret_chat_id); - td_->messages_manager_->on_dialog_action(DialogId(secret_chat_id), MessageId(), DialogId(user_id), - DialogAction::get_typing_action(), get_short_update_date()); + UserId user_id = td_->user_manager_->get_secret_chat_user_id(secret_chat_id); + td_->dialog_action_manager_->on_dialog_action(DialogId(secret_chat_id), MessageId(), DialogId(user_id), + DialogAction::get_typing_action(), get_short_update_date()); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_user_online(UserId(update->user_id_), std::move(update->status_)); + td_->user_manager_->on_update_user_online(UserId(update->user_id_), std::move(update->status_)); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_user_name(UserId(update->user_id_), std::move(update->first_name_), - std::move(update->last_name_), - Usernames{string(), std::move(update->usernames_)}); + td_->user_manager_->on_update_user_name(UserId(update->user_id_), std::move(update->first_name_), + std::move(update->last_name_), + Usernames{string(), std::move(update->usernames_)}); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_user_phone_number(UserId(update->user_id_), std::move(update->phone_)); + td_->user_manager_->on_update_user_phone_number(UserId(update->user_id_), std::move(update->phone_)); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->invalidate_user_full(UserId(update->user_id_)); + td_->user_manager_->invalidate_user_full(UserId(update->user_id_)); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_user_emoji_status(UserId(update->user_id_), std::move(update->emoji_status_)); + td_->user_manager_->on_update_user_emoji_status(UserId(update->user_id_), std::move(update->emoji_status_)); promise.set_value(Unit()); } @@ -3575,58 +4036,59 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->messages_manager_->on_update_dialog_is_blocked(DialogId(update->peer_id_), update->blocked_); + td_->messages_manager_->on_update_dialog_is_blocked(DialogId(update->peer_id_), update->blocked_, + update->blocked_my_stories_from_); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_bot_commands(DialogId(update->peer_), UserId(update->bot_id_), - std::move(update->commands_)); + td_->dialog_manager_->on_update_dialog_bot_commands(DialogId(update->peer_), UserId(update->bot_id_), + std::move(update->commands_)); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_bot_menu_button(UserId(update->bot_id_), std::move(update->button_)); + td_->user_manager_->on_update_bot_menu_button(UserId(update->bot_id_), std::move(update->button_)); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_get_chat_participants(std::move(update->participants_), true); + td_->chat_manager_->on_get_chat_participants(std::move(update->participants_), true); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_chat_add_user(ChatId(update->chat_id_), UserId(update->inviter_id_), - UserId(update->user_id_), update->date_, update->version_); + td_->chat_manager_->on_update_chat_add_user(ChatId(update->chat_id_), UserId(update->inviter_id_), + UserId(update->user_id_), update->date_, update->version_); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_chat_edit_administrator(ChatId(update->chat_id_), UserId(update->user_id_), - update->is_admin_, update->version_); + td_->chat_manager_->on_update_chat_edit_administrator(ChatId(update->chat_id_), UserId(update->user_id_), + update->is_admin_, update->version_); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_chat_delete_user(ChatId(update->chat_id_), UserId(update->user_id_), - update->version_); + td_->chat_manager_->on_update_chat_delete_user(ChatId(update->chat_id_), UserId(update->user_id_), update->version_); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { DialogId dialog_id(update->peer_); - RestrictedRights permissions(update->default_banned_rights_); auto version = update->version_; switch (dialog_id.get_type()) { case DialogType::Chat: - td_->contacts_manager_->on_update_chat_default_permissions(dialog_id.get_chat_id(), permissions, version); + td_->chat_manager_->on_update_chat_default_permissions( + dialog_id.get_chat_id(), RestrictedRights(update->default_banned_rights_, ChannelType::Unknown), version); break; case DialogType::Channel: LOG_IF(ERROR, version != 0) << "Receive version " << version << " in " << dialog_id; - td_->contacts_manager_->on_update_channel_default_permissions(dialog_id.get_channel_id(), permissions); + td_->chat_manager_->on_update_channel_default_permissions( + dialog_id.get_channel_id(), RestrictedRights(update->default_banned_rights_, ChannelType::Megagroup)); break; case DialogType::None: case DialogType::User: @@ -3655,6 +4117,16 @@ void UpdatesManager::on_update(tl_object_ptr promise.set_value(Unit()); } +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->saved_messages_manager_->reload_pinned_saved_messages_topics(); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->saved_messages_manager_->reload_pinned_saved_messages_topics(); + promise.set_value(Unit()); +} + void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { td_->messages_manager_->on_update_dialog_is_marked_as_unread(DialogId(update->peer_), update->unread_); promise.set_value(Unit()); @@ -3678,13 +4150,13 @@ void UpdatesManager::on_update(tl_object_ptr upda } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->inline_queries_manager_->on_new_query(update->query_id_, UserId(update->user_id_), Location(update->geo_), + td_->inline_queries_manager_->on_new_query(update->query_id_, UserId(update->user_id_), Location(td_, update->geo_), std::move(update->peer_type_), update->query_, update->offset_); promise.set_value(Unit()); } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->inline_queries_manager_->on_chosen_result(UserId(update->user_id_), Location(update->geo_), update->query_, + td_->inline_queries_manager_->on_chosen_result(UserId(update->user_id_), Location(td_, update->geo_), update->query_, update->id_, std::move(update->msg_id_)); promise.set_value(Unit()); } @@ -3705,6 +4177,14 @@ void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + td_->callback_queries_manager_->on_new_business_query( + update->query_id_, UserId(update->user_id_), std::move(update->connection_id_), std::move(update->message_), + std::move(update->reply_to_message_), std::move(update->data_), update->chat_instance_); + promise.set_value(Unit()); +} + void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { td_->stickers_manager_->reload_favorite_stickers(true); promise.set_value(Unit()); @@ -3721,7 +4201,18 @@ void UpdatesManager::on_update(tl_object_ptr update, } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - set_pts(std::numeric_limits::max(), "updatePtsChanged").set_value(Unit()); + if (td_->option_manager_->get_option_integer("session_count") > 1) { + auto old_pts = get_pts(); + auto new_pts = 1; + if (old_pts != new_pts) { + LOG(WARNING) << "PTS changes from " << old_pts << " from updatePtsChanged"; + save_pts(new_pts); + add_pts(new_pts).set_value(Unit()); + get_difference("updatePtsChanged"); + } + } else { + set_pts(std::numeric_limits::max(), "updatePtsChanged").set_value(Unit()); + } promise.set_value(Unit()); } @@ -3742,7 +4233,7 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - send_closure(td_->privacy_manager_, &PrivacyManager::update_privacy, std::move(update)); + td_->privacy_manager_->on_update_privacy(std::move(update)); promise.set_value(Unit()); } @@ -3799,7 +4290,7 @@ void UpdatesManager::on_update(tl_object_ptrtd(), &Td::send_update, make_tl_object( - update->query_id_, td_->contacts_manager_->get_user_id_object(user_id, "updateNewShippingQuery"), + update->query_id_, td_->user_manager_->get_user_id_object(user_id, "updateNewShippingQuery"), update->payload_.as_slice().str(), get_address_object(get_address(std::move(update->shipping_address_))))); // TODO use convert_address } @@ -3813,12 +4304,11 @@ void UpdatesManager::on_update(tl_object_ptrtotal_amount_ <= 0 || !check_currency_amount(update->total_amount_)) { LOG(ERROR) << "Receive pre-checkout query with invalid total amount " << update->total_amount_; } else { - send_closure( - G()->td(), &Td::send_update, - make_tl_object( - update->query_id_, td_->contacts_manager_->get_user_id_object(user_id, "updateNewPreCheckoutQuery"), - update->currency_, update->total_amount_, update->payload_.as_slice().str(), update->shipping_option_id_, - get_order_info_object(get_order_info(std::move(update->info_))))); + send_closure(G()->td(), &Td::send_update, + make_tl_object( + update->query_id_, td_->user_manager_->get_user_id_object(user_id, "updateNewPreCheckoutQuery"), + update->currency_, update->total_amount_, update->payload_.as_slice().str(), + update->shipping_option_id_, get_order_info_object(get_order_info(std::move(update->info_))))); } promise.set_value(Unit()); } @@ -3858,9 +4348,9 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { DialogId dialog_id(ChatId(update->chat_id_)); - if (!td_->messages_manager_->have_dialog_force(dialog_id, "updateGroupCall")) { + if (!td_->dialog_manager_->have_dialog_force(dialog_id, "updateGroupCall")) { dialog_id = DialogId(ChannelId(update->chat_id_)); - if (!td_->messages_manager_->have_dialog_force(dialog_id, "updateGroupCall")) { + if (!td_->dialog_manager_->have_dialog_force(dialog_id, "updateGroupCall")) { dialog_id = DialogId(); } } @@ -3876,7 +4366,7 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->contacts_manager_->on_update_contacts_reset(); + td_->user_manager_->on_update_contacts_reset(); promise.set_value(Unit()); } @@ -3957,10 +4447,40 @@ void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + +void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { td_->theme_manager_->on_update_theme(std::move(update->theme_), std::move(promise)); } +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + auto dialog_id = DialogId(update->peer_); + if (dialog_id.get_type() == DialogType::User) { + td_->user_manager_->on_update_user_wallpaper_overridden(dialog_id.get_user_id(), update->wallpaper_overridden_); + } + td_->messages_manager_->on_update_dialog_background(dialog_id, std::move(update->wallpaper_)); + promise.set_value(Unit()); +} + void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { td_->messages_manager_->on_update_dialog_pending_join_requests(DialogId(update->peer_), update->requests_pending_, std::move(update->recent_requesters_)); @@ -3972,33 +4492,131 @@ void UpdatesManager::on_update(tl_object_ptr } void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - auto it = pending_audio_transcriptions_.find(update->transcription_id_); - if (it == pending_audio_transcriptions_.end()) { - return promise.set_value(Unit()); - } - // flags_, dialog_id_ and message_id_ must not be used - if (!update->pending_) { - auto on_update = std::move(it->second); - pending_audio_transcriptions_.erase(it); - pending_audio_transcription_timeout_.cancel_timeout(update->transcription_id_); - on_update(std::move(update)); + td_->transcription_manager_->on_update_transcribed_audio(std::move(update)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->autosave_manager_->reload_autosave_settings(); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->story_manager_->on_get_story(DialogId(update->peer_), std::move(update->story_)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->story_manager_->on_update_read_stories(DialogId(update->peer_), StoryId(update->max_id_)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->story_manager_->on_update_story_stealth_mode(std::move(update->stealth_mode_)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->story_manager_->on_update_story_chosen_reaction_type(DialogId(update->peer_), StoryId(update->story_id_), + ReactionType(update->reaction_)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + LOG(ERROR) << "Receive not in getDifference and not in on_pending_updates " << to_string(update); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + if (update->unconfirmed_) { + td_->account_manager_->on_new_unconfirmed_authorization(update->hash_, update->date_, std::move(update->device_), + std::move(update->location_)); } else { - it->second(std::move(update)); + td_->account_manager_->on_confirm_authorization(update->hash_); } promise.set_value(Unit()); } -void UpdatesManager::on_update(tl_object_ptr update, - Promise &&promise) { +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { LOG(ERROR) << "Receive " << to_string(update); promise.set_value(Unit()); } -void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { - td_->autosave_manager_->reload_autosave_settings(); +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->quick_reply_manager_->reload_quick_reply_shortcuts(); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->quick_reply_manager_->reload_quick_reply_shortcuts(); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->quick_reply_manager_->reload_quick_reply_shortcuts(); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->quick_reply_manager_->update_quick_reply_message(std::move(update->message_)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + vector message_ids; + for (auto message : update->messages_) { + message_ids.push_back(MessageId(ServerMessageId(message))); + } + td_->quick_reply_manager_->delete_quick_reply_messages_from_updates(QuickReplyShortcutId(update->shortcut_id_), + std::move(message_ids)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + +void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + +void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + +void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + auto qts = update->qts_; + add_pending_qts_update(std::move(update), qts, std::move(promise)); +} + +void UpdatesManager::on_update(tl_object_ptr update, + Promise &&promise) { + td_->statistics_manager_->on_update_dialog_revenue_transactions(DialogId(update->peer_), + std::move(update->balances_)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->star_manager_->on_update_owned_star_count(StarManager::get_star_count(update->balance_, true)); + promise.set_value(Unit()); +} + +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + td_->star_manager_->on_update_stars_revenue_status(std::move(update)); promise.set_value(Unit()); } // unsupported updates +void UpdatesManager::on_update(tl_object_ptr update, Promise &&promise) { + promise.set_value(Unit()); +} + } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/UpdatesManager.h b/protocols/Telegram/tdlib/td/td/telegram/UpdatesManager.h index fb9e343606..939050c9ec 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/UpdatesManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/UpdatesManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,15 +9,14 @@ #include "td/telegram/ChannelId.h" #include "td/telegram/ChatId.h" #include "td/telegram/DialogId.h" -#include "td/telegram/FullMessageId.h" #include "td/telegram/InputGroupCallId.h" +#include "td/telegram/MessageFullId.h" #include "td/telegram/MessageId.h" #include "td/telegram/PtsManager.h" #include "td/telegram/telegram_api.h" #include "td/telegram/UserId.h" #include "td/actor/actor.h" -#include "td/actor/MultiTimeout.h" #include "td/actor/Timeout.h" #include "td/utils/common.h" @@ -29,8 +28,8 @@ #include "td/utils/tl_storers.h" #include "td/utils/TlStorerToString.h" -#include #include +#include #include namespace td { @@ -105,9 +104,6 @@ class UpdatesManager final : public Actor { static bool are_empty_updates(const telegram_api::Updates *updates_ptr); - static vector extract_group_invite_privacy_forbidden_updates( - tl_object_ptr &updates_ptr); - static FlatHashSet get_sent_messages_random_ids(const telegram_api::Updates *updates_ptr); static const telegram_api::Message *get_message_by_random_id(const telegram_api::Updates *updates_ptr, @@ -125,11 +121,7 @@ class UpdatesManager final : public Actor { static vector get_chat_dialog_ids(const telegram_api::Updates *updates_ptr); - static int32 get_update_edit_message_pts(const telegram_api::Updates *updates_ptr, FullMessageId full_message_id); - - using TranscribedAudioHandler = - std::function>)>; - void subscribe_to_transcribed_audio_updates(int64 transcription_id, TranscribedAudioHandler on_update); + static int32 get_update_edit_message_pts(const telegram_api::Updates *updates_ptr, MessageFullId message_full_id); void get_difference(const char *source); @@ -139,6 +131,8 @@ class UpdatesManager final : public Actor { void ping_server(); + void notify_speed_limited(bool is_upload); + bool running_get_difference() const { return running_get_difference_; } @@ -148,22 +142,38 @@ class UpdatesManager final : public Actor { private: static constexpr int32 FORCED_GET_DIFFERENCE_PTS_DIFF = 100000; static constexpr int32 GAP_TIMEOUT_UPDATE_COUNT = 20; + static constexpr double MIN_UNFILLED_GAP_TIME = 0.05; static constexpr double MAX_UNFILLED_GAP_TIME = 0.7; static constexpr double MAX_PTS_SAVE_DELAY = 0.05; - static constexpr double UPDATE_APPLY_WARNING_TIME = 0.25; + static constexpr double UPDATE_APPLY_WARNING_TIME = 0.1; static constexpr bool DROP_PTS_UPDATES = false; static constexpr const char *AFTER_GET_DIFFERENCE_SOURCE = "after get difference"; - static constexpr int32 AUDIO_TRANSCRIPTION_TIMEOUT = 60; - friend class OnUpdate; + class OnUpdate { + UpdatesManager *updates_manager_; + telegram_api::object_ptr &update_; + mutable Promise promise_; + + public: + OnUpdate(UpdatesManager *updates_manager, telegram_api::object_ptr &update, + Promise &&promise) + : updates_manager_(updates_manager), update_(update), promise_(std::move(promise)) { + } + + template + void operator()(T &obj) const { + CHECK(&*update_ == &obj); + updates_manager_->on_update(move_tl_object_as(update_), std::move(promise_)); + } + }; class PendingPtsUpdate { public: - tl_object_ptr update; + mutable tl_object_ptr update; int32 pts; int32 pts_count; double receive_time; - Promise promise; + mutable Promise promise; PendingPtsUpdate(tl_object_ptr &&update, int32 pts, int32 pts_count, double receive_time, Promise &&promise) @@ -173,6 +183,13 @@ class UpdatesManager final : public Actor { , receive_time(receive_time) , promise(std::move(promise)) { } + + bool operator<(const PendingPtsUpdate &other) const { + if (pts != other.pts) { + return pts < other.pts; + } + return other.pts_count < pts_count; + } }; class PendingSeqUpdates { @@ -181,8 +198,8 @@ class UpdatesManager final : public Actor { int32 seq_end; int32 date; double receive_time; - vector> updates; - Promise promise; + mutable vector> updates; + mutable Promise promise; PendingSeqUpdates(int32 seq_begin, int32 seq_end, int32 date, double receive_time, vector> &&updates, Promise &&promise) @@ -193,6 +210,13 @@ class UpdatesManager final : public Actor { , updates(std::move(updates)) , promise(std::move(promise)) { } + + bool operator<(const PendingSeqUpdates &other) const { + if (seq_begin != other.seq_begin) { + return seq_begin < other.seq_begin; + } + return other.seq_end < seq_end; + } }; class PendingQtsUpdate { @@ -217,6 +241,15 @@ class UpdatesManager final : public Actor { int32 pending_pts_ = 0; int32 pending_qts_ = 0; + int32 pts_short_gap_ = 0; + int32 pts_fixed_short_gap_ = 0; + int32 pts_gap_ = 0; + int32 pts_diff_ = 0; + int32 last_fetched_pts_ = 0; + + int32 qts_gap_ = 0; + int32 qts_diff_ = 0; + int64 being_processed_updates_ = 0; int32 short_update_date_ = 0; @@ -226,14 +259,15 @@ class UpdatesManager final : public Actor { double last_pts_jump_warning_time_ = 0; double last_pts_gap_time_ = 0; - std::multimap pending_pts_updates_; - std::multimap postponed_pts_updates_; + std::multiset pending_pts_updates_; + std::multiset postponed_pts_updates_; - std::multimap postponed_updates_; // updates received during getDifference - std::multimap pending_seq_updates_; // updates with too big seq + std::multiset postponed_updates_; // updates received during getDifference + std::multiset pending_seq_updates_; // updates with too big seq std::map pending_qts_updates_; // updates with too big QTS + Timeout min_pts_gap_timeout_; Timeout pts_gap_timeout_; Timeout seq_gap_timeout_; @@ -248,16 +282,15 @@ class UpdatesManager final : public Actor { bool is_ping_sent_ = false; + bool expect_pts_gap_ = false; bool running_get_difference_ = false; - bool finished_first_get_difference_ = false; + int32 skipped_postponed_updates_after_start_ = 50000; int32 last_confirmed_pts_ = 0; int32 last_confirmed_qts_ = 0; int32 min_postponed_update_pts_ = 0; int32 min_postponed_update_qts_ = 0; double get_difference_start_time_ = 0; // time from which we started to get difference without success - - FlatHashMap pending_audio_transcriptions_; - MultiTimeout pending_audio_transcription_timeout_{"PendingAudioTranscriptionTimeout"}; + int32 get_difference_retry_count_ = 0; struct SessionInfo { uint64 update_count = 0; @@ -266,6 +299,8 @@ class UpdatesManager final : public Actor { }; FlatHashMap session_infos_; + double next_notify_speed_limited_[2] = {0.0, 0.0}; + void start_up() final; void tear_down() final; @@ -295,8 +330,12 @@ class UpdatesManager final : public Actor { void on_qts_ack(PtsManager::PtsId ack_token); void save_qts(int32 qts); - bool can_postpone_updates() const { - return finished_first_get_difference_; + bool can_postpone_updates() { + if (skipped_postponed_updates_after_start_ == 0) { + return true; + } + skipped_postponed_updates_after_start_--; + return false; } void set_date(int32 date, bool from_update, string date_source); @@ -307,6 +346,8 @@ class UpdatesManager final : public Actor { void on_get_updates_state(tl_object_ptr &&state, const char *source); + void on_get_updates_impl(tl_object_ptr updates_ptr, Promise promise); + void on_server_pong(tl_object_ptr &&state); void on_get_difference(tl_object_ptr &&difference_ptr); @@ -350,6 +391,8 @@ class UpdatesManager final : public Actor { void process_pending_qts_updates(); + static void check_pts_gap(void *td); + static void fill_pts_gap(void *td); static void fill_seq_gap(void *td); @@ -358,9 +401,11 @@ class UpdatesManager final : public Actor { static void fill_get_difference_gap(void *td); - static void fill_gap(void *td, const char *source); + static void fill_gap(void *td, const string &source); + + void repair_pts_gap(); - static void on_pending_audio_transcription_timeout_callback(void *td, int64 transcription_id); + void on_get_pts_update(int32 pts, telegram_api::object_ptr difference_ptr); void set_pts_gap_timeout(double timeout); @@ -370,6 +415,8 @@ class UpdatesManager final : public Actor { void run_get_difference(bool is_recursive, const char *source); + void confirm_pts_qts(int32 qts); + void on_failed_get_updates_state(Status &&error); void on_failed_get_difference(Status &&error); @@ -412,8 +459,6 @@ class UpdatesManager final : public Actor { static vector> *get_updates(telegram_api::Updates *updates_ptr); - void on_pending_audio_transcription_failed(int64 transcription_id, Status &&error); - bool is_acceptable_user(UserId user_id) const; bool is_acceptable_chat(ChatId chat_id) const; @@ -427,15 +472,19 @@ class UpdatesManager final : public Actor { bool is_acceptable_reply_markup(const tl_object_ptr &reply_markup) const; bool is_acceptable_message_reply_header( - const telegram_api::object_ptr &header) const; + const telegram_api::object_ptr &header) const; bool is_acceptable_message_forward_header( const telegram_api::object_ptr &header) const; + bool is_acceptable_message_media(const telegram_api::object_ptr &media_ptr) const; + bool is_acceptable_message(const telegram_api::Message *message_ptr) const; bool is_acceptable_update(const telegram_api::Update *update) const; + static int32 fix_short_message_flags(int32 flags); + void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); @@ -456,6 +505,10 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); @@ -501,6 +554,7 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); @@ -517,6 +571,10 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); @@ -526,6 +584,7 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); @@ -582,20 +641,64 @@ class UpdatesManager final : public Actor { void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); void on_update(tl_object_ptr update, Promise &&promise); - void on_update(tl_object_ptr update, Promise &&promise); - void on_update(tl_object_ptr update, Promise &&promise); + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + + void on_update(tl_object_ptr update, Promise &&promise); + // unsupported updates + + void on_update(tl_object_ptr update, Promise &&promise); }; } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/UserId.h b/protocols/Telegram/tdlib/td/td/telegram/UserId.h index 87c1652255..8a5fa1db11 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/UserId.h +++ b/protocols/Telegram/tdlib/td/td/telegram/UserId.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -29,11 +29,14 @@ class UserId { template ::value>> UserId(T user_id) = delete; - static vector get_user_ids(const vector &input_user_ids) { + static vector get_user_ids(const vector &input_user_ids, bool only_valid = false) { vector user_ids; user_ids.reserve(input_user_ids.size()); for (auto &input_user_id : input_user_ids) { - user_ids.emplace_back(input_user_id); + UserId user_id(input_user_id); + if (!only_valid || user_id.is_valid()) { + user_ids.emplace_back(user_id); + } } return user_ids; } diff --git a/protocols/Telegram/tdlib/td/td/telegram/UserManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/UserManager.cpp new file mode 100644 index 0000000000..ec06b9f9f4 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/UserManager.cpp @@ -0,0 +1,8135 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/UserManager.h" + +#include "td/telegram/AnimationsManager.h" +#include "td/telegram/AuthManager.h" +#include "td/telegram/Birthdate.hpp" +#include "td/telegram/BlockListId.h" +#include "td/telegram/BotMenuButton.h" +#include "td/telegram/BusinessAwayMessage.h" +#include "td/telegram/BusinessGreetingMessage.h" +#include "td/telegram/BusinessInfo.h" +#include "td/telegram/BusinessInfo.hpp" +#include "td/telegram/BusinessIntro.h" +#include "td/telegram/BusinessWorkHours.h" +#include "td/telegram/ChannelType.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/CommonDialogManager.h" +#include "td/telegram/ConfigManager.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogLocation.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/DialogParticipantManager.h" +#include "td/telegram/Document.h" +#include "td/telegram/DocumentsManager.h" +#include "td/telegram/FileReferenceManager.h" +#include "td/telegram/files/FileManager.h" +#include "td/telegram/files/FileType.h" +#include "td/telegram/FolderId.h" +#include "td/telegram/Global.h" +#include "td/telegram/GroupCallManager.h" +#include "td/telegram/InlineQueriesManager.h" +#include "td/telegram/LinkManager.h" +#include "td/telegram/logevent/LogEvent.h" +#include "td/telegram/logevent/LogEventHelper.h" +#include "td/telegram/MessageId.h" +#include "td/telegram/MessagesManager.h" +#include "td/telegram/MessageTtl.h" +#include "td/telegram/misc.h" +#include "td/telegram/NotificationManager.h" +#include "td/telegram/OnlineManager.h" +#include "td/telegram/OptionManager.h" +#include "td/telegram/PeerColor.h" +#include "td/telegram/PeopleNearbyManager.h" +#include "td/telegram/Photo.h" +#include "td/telegram/Photo.hpp" +#include "td/telegram/PhotoSize.h" +#include "td/telegram/PremiumGiftOption.hpp" +#include "td/telegram/ReactionListType.h" +#include "td/telegram/ReactionManager.h" +#include "td/telegram/SecretChatLayer.h" +#include "td/telegram/SecretChatsManager.h" +#include "td/telegram/ServerMessageId.h" +#include "td/telegram/StickerPhotoSize.h" +#include "td/telegram/StoryManager.h" +#include "td/telegram/SuggestedAction.h" +#include "td/telegram/Td.h" +#include "td/telegram/TdDb.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/ThemeManager.h" +#include "td/telegram/UpdatesManager.h" +#include "td/telegram/Version.h" + +#include "td/db/binlog/BinlogEvent.h" +#include "td/db/binlog/BinlogHelper.h" +#include "td/db/SqliteKeyValue.h" +#include "td/db/SqliteKeyValueAsync.h" + +#include "td/utils/algorithm.h" +#include "td/utils/buffer.h" +#include "td/utils/format.h" +#include "td/utils/logging.h" +#include "td/utils/misc.h" +#include "td/utils/Random.h" +#include "td/utils/ScopeGuard.h" +#include "td/utils/Slice.h" +#include "td/utils/SliceBuilder.h" +#include "td/utils/StringBuilder.h" +#include "td/utils/Time.h" +#include "td/utils/tl_helpers.h" +#include "td/utils/utf8.h" + +#include +#include +#include +#include +#include +#include + +namespace td { + +class GetContactsQuery final : public Td::ResultHandler { + public: + void send(int64 hash) { + send_query(G()->net_query_creator().create(telegram_api::contacts_getContacts(hash))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetContactsQuery: " << to_string(ptr); + td_->user_manager_->on_get_contacts(std::move(ptr)); + } + + void on_error(Status status) final { + td_->user_manager_->on_get_contacts_failed(std::move(status)); + } +}; + +class GetContactsBirthdaysQuery final : public Td::ResultHandler { + public: + void send() { + send_query(G()->net_query_creator().create(telegram_api::contacts_getBirthdays())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetContactsBirthdaysQuery: " << to_string(ptr); + td_->user_manager_->on_get_contact_birthdates(std::move(ptr)); + } + + void on_error(Status status) final { + td_->user_manager_->on_get_contact_birthdates(nullptr); + } +}; + +class DismissContactBirthdaysSuggestionQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit DismissContactBirthdaysSuggestionQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::help_dismissSuggestion( + telegram_api::make_object(), "BIRTHDAY_CONTACTS_TODAY"))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetContactsStatusesQuery final : public Td::ResultHandler { + public: + void send() { + send_query(G()->net_query_creator().create(telegram_api::contacts_getStatuses())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->user_manager_->on_get_contacts_statuses(result_ptr.move_as_ok()); + } + + void on_error(Status status) final { + if (!G()->is_expected_error(status)) { + LOG(ERROR) << "Receive error for GetContactsStatusesQuery: " << status; + } + } +}; + +class AddContactQuery final : public Td::ResultHandler { + Promise promise_; + UserId user_id_; + + public: + explicit AddContactQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId user_id, telegram_api::object_ptr &&input_user, const Contact &contact, + bool share_phone_number) { + user_id_ = user_id; + int32 flags = 0; + if (share_phone_number) { + flags |= telegram_api::contacts_addContact::ADD_PHONE_PRIVACY_EXCEPTION_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::contacts_addContact(flags, false /*ignored*/, std::move(input_user), contact.get_first_name(), + contact.get_last_name(), contact.get_phone_number()), + {{DialogId(user_id)}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for AddContactQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + td_->user_manager_->reload_contacts(true); + td_->messages_manager_->reget_dialog_action_bar(DialogId(user_id_), "AddContactQuery"); + } +}; + +class EditCloseFriendsQuery final : public Td::ResultHandler { + Promise promise_; + vector user_ids_; + + public: + explicit EditCloseFriendsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(vector user_ids) { + user_ids_ = std::move(user_ids); + send_query(G()->net_query_creator().create( + telegram_api::contacts_editCloseFriends(UserId::get_input_user_ids(user_ids_)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->user_manager_->on_set_close_friends(user_ids_, std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class ResolvePhoneQuery final : public Td::ResultHandler { + Promise promise_; + string phone_number_; + + public: + explicit ResolvePhoneQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &phone_number) { + phone_number_ = phone_number; + send_query(G()->net_query_creator().create(telegram_api::contacts_resolvePhone(phone_number))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for ResolvePhoneQuery: " << to_string(ptr); + td_->user_manager_->on_get_users(std::move(ptr->users_), "ResolvePhoneQuery"); + // on_get_chats(std::move(ptr->chats_), "ResolvePhoneQuery"); + + DialogId dialog_id(ptr->peer_); + if (dialog_id.get_type() != DialogType::User) { + LOG(ERROR) << "Receive " << dialog_id << " by " << phone_number_; + return on_error(Status::Error(500, "Receive invalid response")); + } + + td_->user_manager_->on_resolved_phone_number(phone_number_, dialog_id.get_user_id()); + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + if (status.message() == Slice("PHONE_NOT_OCCUPIED")) { + td_->user_manager_->on_resolved_phone_number(phone_number_, UserId()); + return promise_.set_value(Unit()); + } + promise_.set_error(std::move(status)); + } +}; + +class AcceptContactQuery final : public Td::ResultHandler { + Promise promise_; + UserId user_id_; + + public: + explicit AcceptContactQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId user_id, telegram_api::object_ptr &&input_user) { + user_id_ = user_id; + send_query(G()->net_query_creator().create(telegram_api::contacts_acceptContact(std::move(input_user)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for AcceptContactQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + td_->user_manager_->reload_contacts(true); + td_->messages_manager_->reget_dialog_action_bar(DialogId(user_id_), "AcceptContactQuery"); + } +}; + +class ImportContactsQuery final : public Td::ResultHandler { + int64 random_id_ = 0; + size_t sent_size_ = 0; + + public: + void send(vector> &&input_phone_contacts, int64 random_id) { + random_id_ = random_id; + sent_size_ = input_phone_contacts.size(); + send_query(G()->net_query_creator().create(telegram_api::contacts_importContacts(std::move(input_phone_contacts)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for ImportContactsQuery: " << to_string(ptr); + if (sent_size_ == ptr->retry_contacts_.size()) { + return on_error(Status::Error(429, "Too Many Requests: retry after 3600")); + } + td_->user_manager_->on_imported_contacts(random_id_, std::move(ptr)); + } + + void on_error(Status status) final { + td_->user_manager_->on_imported_contacts(random_id_, std::move(status)); + } +}; + +class DeleteContactsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit DeleteContactsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(vector> &&input_users) { + send_query(G()->net_query_creator().create(telegram_api::contacts_deleteContacts(std::move(input_users)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for DeleteContactsQuery: " << to_string(ptr); + td_->updates_manager_->on_get_updates(std::move(ptr), std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + td_->user_manager_->reload_contacts(true); + } +}; + +class DeleteContactsByPhoneNumberQuery final : public Td::ResultHandler { + Promise promise_; + vector user_ids_; + + public: + explicit DeleteContactsByPhoneNumberQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(vector &&user_phone_numbers, vector &&user_ids) { + if (user_phone_numbers.empty()) { + return promise_.set_value(Unit()); + } + user_ids_ = std::move(user_ids); + send_query(G()->net_query_creator().create(telegram_api::contacts_deleteByPhones(std::move(user_phone_numbers)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + if (!result) { + return on_error(Status::Error(500, "Some contacts can't be deleted")); + } + + td_->user_manager_->on_deleted_contacts(user_ids_); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + td_->user_manager_->reload_contacts(true); + } +}; + +class ResetContactsQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ResetContactsQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::contacts_resetSaved())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + if (!result) { + LOG(ERROR) << "Failed to delete imported contacts"; + td_->user_manager_->reload_contacts(true); + } else { + td_->user_manager_->on_update_contacts_reset(); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + td_->user_manager_->reload_contacts(true); + } +}; + +class UploadProfilePhotoQuery final : public Td::ResultHandler { + Promise promise_; + UserId user_id_; + FileId file_id_; + bool is_fallback_; + bool only_suggest_; + + public: + explicit UploadProfilePhotoQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId user_id, FileId file_id, telegram_api::object_ptr &&input_file, + bool is_fallback, bool only_suggest, bool is_animation, double main_frame_timestamp) { + CHECK(input_file != nullptr); + CHECK(file_id.is_valid()); + + user_id_ = user_id; + file_id_ = file_id; + is_fallback_ = is_fallback; + only_suggest_ = only_suggest; + + static_assert(static_cast(telegram_api::photos_uploadProfilePhoto::VIDEO_MASK) == + static_cast(telegram_api::photos_uploadContactProfilePhoto::VIDEO_MASK), + ""); + static_assert(static_cast(telegram_api::photos_uploadProfilePhoto::VIDEO_START_TS_MASK) == + static_cast(telegram_api::photos_uploadContactProfilePhoto::VIDEO_START_TS_MASK), + ""); + static_assert(static_cast(telegram_api::photos_uploadProfilePhoto::FILE_MASK) == + static_cast(telegram_api::photos_uploadContactProfilePhoto::FILE_MASK), + ""); + + int32 flags = 0; + telegram_api::object_ptr photo_input_file; + telegram_api::object_ptr video_input_file; + if (is_animation) { + flags |= telegram_api::photos_uploadProfilePhoto::VIDEO_MASK; + video_input_file = std::move(input_file); + + if (main_frame_timestamp != 0.0) { + flags |= telegram_api::photos_uploadProfilePhoto::VIDEO_START_TS_MASK; + } + } else { + flags |= telegram_api::photos_uploadProfilePhoto::FILE_MASK; + photo_input_file = std::move(input_file); + } + if (td_->user_manager_->is_user_bot(user_id)) { + auto r_input_user = td_->user_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return on_error(r_input_user.move_as_error()); + } + flags |= telegram_api::photos_uploadProfilePhoto::BOT_MASK; + send_query(G()->net_query_creator().create( + telegram_api::photos_uploadProfilePhoto(flags, false /*ignored*/, r_input_user.move_as_ok(), + std::move(photo_input_file), std::move(video_input_file), + main_frame_timestamp, nullptr), + {{user_id}})); + } else if (user_id == td_->user_manager_->get_my_id()) { + if (is_fallback) { + flags |= telegram_api::photos_uploadProfilePhoto::FALLBACK_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::photos_uploadProfilePhoto(flags, false /*ignored*/, nullptr, std::move(photo_input_file), + std::move(video_input_file), main_frame_timestamp, nullptr), + {{"me"}})); + } else { + if (only_suggest) { + flags |= telegram_api::photos_uploadContactProfilePhoto::SUGGEST_MASK; + } else { + flags |= telegram_api::photos_uploadContactProfilePhoto::SAVE_MASK; + } + auto r_input_user = td_->user_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return on_error(r_input_user.move_as_error()); + } + send_query(G()->net_query_creator().create( + telegram_api::photos_uploadContactProfilePhoto(flags, false /*ignored*/, false /*ignored*/, + r_input_user.move_as_ok(), std::move(photo_input_file), + std::move(video_input_file), main_frame_timestamp, nullptr), + {{user_id}})); + } + } + + void send(UserId user_id, unique_ptr sticker_photo_size, bool is_fallback, bool only_suggest) { + CHECK(sticker_photo_size != nullptr); + user_id_ = user_id; + file_id_ = FileId(); + is_fallback_ = is_fallback; + only_suggest_ = only_suggest; + + if (td_->user_manager_->is_user_bot(user_id)) { + auto r_input_user = td_->user_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return on_error(r_input_user.move_as_error()); + } + int32 flags = telegram_api::photos_uploadProfilePhoto::VIDEO_EMOJI_MARKUP_MASK; + flags |= telegram_api::photos_uploadProfilePhoto::BOT_MASK; + send_query(G()->net_query_creator().create( + telegram_api::photos_uploadProfilePhoto(flags, false /*ignored*/, r_input_user.move_as_ok(), nullptr, nullptr, + 0.0, sticker_photo_size->get_input_video_size_object(td_)), + {{user_id}})); + } else if (user_id == td_->user_manager_->get_my_id()) { + int32 flags = telegram_api::photos_uploadProfilePhoto::VIDEO_EMOJI_MARKUP_MASK; + if (is_fallback) { + flags |= telegram_api::photos_uploadProfilePhoto::FALLBACK_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::photos_uploadProfilePhoto(flags, false /*ignored*/, nullptr, nullptr, nullptr, 0.0, + sticker_photo_size->get_input_video_size_object(td_)), + {{"me"}})); + } else { + int32 flags = telegram_api::photos_uploadContactProfilePhoto::VIDEO_EMOJI_MARKUP_MASK; + if (only_suggest) { + flags |= telegram_api::photos_uploadContactProfilePhoto::SUGGEST_MASK; + } else { + flags |= telegram_api::photos_uploadContactProfilePhoto::SAVE_MASK; + } + auto r_input_user = td_->user_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return on_error(r_input_user.move_as_error()); + } + send_query(G()->net_query_creator().create( + telegram_api::photos_uploadContactProfilePhoto(flags, false /*ignored*/, false /*ignored*/, + r_input_user.move_as_ok(), nullptr, nullptr, 0.0, + sticker_photo_size->get_input_video_size_object(td_)), + {{user_id}})); + } + } + + void on_result(BufferSlice packet) final { + static_assert(std::is_same::value, + ""); + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + if (!only_suggest_) { + td_->user_manager_->on_set_profile_photo(user_id_, result_ptr.move_as_ok(), is_fallback_, 0, std::move(promise_)); + } else { + promise_.set_value(Unit()); + } + + if (file_id_.is_valid()) { + td_->file_manager_->delete_partial_remote_location(file_id_); + } + } + + void on_error(Status status) final { + if (file_id_.is_valid()) { + td_->file_manager_->delete_partial_remote_location(file_id_); + } + promise_.set_error(std::move(status)); + } +}; + +class UpdateProfilePhotoQuery final : public Td::ResultHandler { + Promise promise_; + UserId user_id_; + FileId file_id_; + int64 old_photo_id_; + bool is_fallback_; + string file_reference_; + + public: + explicit UpdateProfilePhotoQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId user_id, FileId file_id, int64 old_photo_id, bool is_fallback, + telegram_api::object_ptr &&input_photo) { + CHECK(input_photo != nullptr); + user_id_ = user_id; + file_id_ = file_id; + old_photo_id_ = old_photo_id; + is_fallback_ = is_fallback; + file_reference_ = FileManager::extract_file_reference(input_photo); + int32 flags = 0; + if (is_fallback) { + flags |= telegram_api::photos_updateProfilePhoto::FALLBACK_MASK; + } + if (td_->user_manager_->is_user_bot(user_id)) { + auto r_input_user = td_->user_manager_->get_input_user(user_id); + if (r_input_user.is_error()) { + return on_error(r_input_user.move_as_error()); + } + flags |= telegram_api::photos_updateProfilePhoto::BOT_MASK; + send_query(G()->net_query_creator().create( + telegram_api::photos_updateProfilePhoto(flags, false /*ignored*/, r_input_user.move_as_ok(), + std::move(input_photo)), + {{user_id}})); + } else { + send_query(G()->net_query_creator().create( + telegram_api::photos_updateProfilePhoto(flags, false /*ignored*/, nullptr, std::move(input_photo)), + {{"me"}})); + } + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->user_manager_->on_set_profile_photo(user_id_, result_ptr.move_as_ok(), is_fallback_, old_photo_id_, + std::move(promise_)); + } + + void on_error(Status status) final { + if (!td_->auth_manager_->is_bot() && FileReferenceManager::is_file_reference_error(status)) { + if (file_id_.is_valid()) { + VLOG(file_references) << "Receive " << status << " for " << file_id_; + td_->file_manager_->delete_file_reference(file_id_, file_reference_); + td_->file_reference_manager_->repair_file_reference( + file_id_, PromiseCreator::lambda([user_id = user_id_, file_id = file_id_, is_fallback = is_fallback_, + old_photo_id = old_photo_id_, + promise = std::move(promise_)](Result result) mutable { + if (result.is_error()) { + return promise.set_error(Status::Error(400, "Can't find the photo")); + } + + send_closure(G()->user_manager(), &UserManager::send_update_profile_photo_query, user_id, file_id, + old_photo_id, is_fallback, std::move(promise)); + })); + return; + } else { + LOG(ERROR) << "Receive file reference error, but file_id = " << file_id_; + } + } + + promise_.set_error(std::move(status)); + } +}; + +class DeleteContactProfilePhotoQuery final : public Td::ResultHandler { + Promise promise_; + UserId user_id_; + + public: + explicit DeleteContactProfilePhotoQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId user_id, telegram_api::object_ptr &&input_user) { + CHECK(input_user != nullptr); + user_id_ = user_id; + + int32 flags = 0; + flags |= telegram_api::photos_uploadContactProfilePhoto::SAVE_MASK; + send_query(G()->net_query_creator().create( + telegram_api::photos_uploadContactProfilePhoto(flags, false /*ignored*/, false /*ignored*/, + std::move(input_user), nullptr, nullptr, 0, nullptr), + {{user_id}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + ptr->photo_ = nullptr; + td_->user_manager_->on_set_profile_photo(user_id_, std::move(ptr), false, 0, std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class DeleteProfilePhotoQuery final : public Td::ResultHandler { + Promise promise_; + int64 profile_photo_id_; + + public: + explicit DeleteProfilePhotoQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(int64 profile_photo_id) { + profile_photo_id_ = profile_photo_id; + vector> input_photo_ids; + input_photo_ids.push_back(telegram_api::make_object(profile_photo_id, 0, BufferSlice())); + send_query(G()->net_query_creator().create(telegram_api::photos_deletePhotos(std::move(input_photo_ids)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto result = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for DeleteProfilePhotoQuery: " << format::as_array(result); + if (result.size() != 1u) { + LOG(WARNING) << "Photo can't be deleted"; + return on_error(Status::Error(400, "Photo can't be deleted")); + } + + td_->user_manager_->on_delete_profile_photo(profile_photo_id_, std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class UpdateColorQuery final : public Td::ResultHandler { + Promise promise_; + bool for_profile_; + AccentColorId accent_color_id_; + CustomEmojiId background_custom_emoji_id_; + + public: + explicit UpdateColorQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(bool for_profile, AccentColorId accent_color_id, CustomEmojiId background_custom_emoji_id) { + for_profile_ = for_profile; + accent_color_id_ = accent_color_id; + background_custom_emoji_id_ = background_custom_emoji_id; + int32 flags = 0; + if (for_profile) { + flags |= telegram_api::account_updateColor::FOR_PROFILE_MASK; + } + if (accent_color_id.is_valid()) { + flags |= telegram_api::account_updateColor::COLOR_MASK; + } + if (background_custom_emoji_id.is_valid()) { + flags |= telegram_api::account_updateColor::BACKGROUND_EMOJI_ID_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::account_updateColor(flags, false /*ignored*/, accent_color_id.get(), + background_custom_emoji_id.get()), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG(DEBUG) << "Receive result for UpdateColorQuery: " << result_ptr.ok(); + td_->user_manager_->on_update_accent_color_success(for_profile_, accent_color_id_, background_custom_emoji_id_); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class UpdateProfileQuery final : public Td::ResultHandler { + Promise promise_; + int32 flags_; + string first_name_; + string last_name_; + string about_; + + public: + explicit UpdateProfileQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(int32 flags, const string &first_name, const string &last_name, const string &about) { + flags_ = flags; + first_name_ = first_name; + last_name_ = last_name; + about_ = about; + send_query(G()->net_query_creator().create(telegram_api::account_updateProfile(flags, first_name, last_name, about), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG(DEBUG) << "Receive result for UpdateProfileQuery: " << to_string(result_ptr.ok()); + td_->user_manager_->on_get_user(result_ptr.move_as_ok(), "UpdateProfileQuery"); + td_->user_manager_->on_update_profile_success(flags_, first_name_, last_name_, about_); + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class UpdateUsernameQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit UpdateUsernameQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const string &username) { + send_query(G()->net_query_creator().create(telegram_api::account_updateUsername(username), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG(DEBUG) << "Receive result for UpdateUsernameQuery: " << to_string(result_ptr.ok()); + td_->user_manager_->on_get_user(result_ptr.move_as_ok(), "UpdateUsernameQuery"); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + if (status.message() == "USERNAME_NOT_MODIFIED" && !td_->auth_manager_->is_bot()) { + promise_.set_value(Unit()); + return; + } + promise_.set_error(std::move(status)); + } +}; + +class ToggleUsernameQuery final : public Td::ResultHandler { + Promise promise_; + string username_; + bool is_active_; + + public: + explicit ToggleUsernameQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(string &&username, bool is_active) { + username_ = std::move(username); + is_active_ = is_active; + send_query(G()->net_query_creator().create(telegram_api::account_toggleUsername(username_, is_active_), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + LOG(DEBUG) << "Receive result for ToggleUsernameQuery: " << result; + td_->user_manager_->on_update_username_is_active(td_->user_manager_->get_my_id(), std::move(username_), is_active_, + std::move(promise_)); + } + + void on_error(Status status) final { + if (status.message() == "USERNAME_NOT_MODIFIED") { + td_->user_manager_->on_update_username_is_active(td_->user_manager_->get_my_id(), std::move(username_), + is_active_, std::move(promise_)); + return; + } + promise_.set_error(std::move(status)); + } +}; + +class ReorderUsernamesQuery final : public Td::ResultHandler { + Promise promise_; + vector usernames_; + + public: + explicit ReorderUsernamesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(vector &&usernames) { + usernames_ = usernames; + send_query(G()->net_query_creator().create(telegram_api::account_reorderUsernames(std::move(usernames)), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + LOG(DEBUG) << "Receive result for ReorderUsernamesQuery: " << result; + if (!result) { + return on_error(Status::Error(500, "Usernames weren't updated")); + } + + td_->user_manager_->on_update_active_usernames_order(td_->user_manager_->get_my_id(), std::move(usernames_), + std::move(promise_)); + } + + void on_error(Status status) final { + if (status.message() == "USERNAME_NOT_MODIFIED") { + td_->user_manager_->on_update_active_usernames_order(td_->user_manager_->get_my_id(), std::move(usernames_), + std::move(promise_)); + return; + } + promise_.set_error(std::move(status)); + } +}; + +class ToggleBotUsernameQuery final : public Td::ResultHandler { + Promise promise_; + UserId bot_user_id_; + string username_; + bool is_active_; + + public: + explicit ToggleBotUsernameQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId bot_user_id, string &&username, bool is_active) { + bot_user_id_ = bot_user_id; + username_ = std::move(username); + is_active_ = is_active; + auto r_input_user = td_->user_manager_->get_input_user(bot_user_id_); + if (r_input_user.is_error()) { + return on_error(r_input_user.move_as_error()); + } + send_query(G()->net_query_creator().create( + telegram_api::bots_toggleUsername(r_input_user.move_as_ok(), username_, is_active_), {{bot_user_id_}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + LOG(DEBUG) << "Receive result for ToggleBotUsernameQuery: " << result; + td_->user_manager_->on_update_username_is_active(bot_user_id_, std::move(username_), is_active_, + std::move(promise_)); + } + + void on_error(Status status) final { + if (status.message() == "USERNAME_NOT_MODIFIED") { + td_->user_manager_->on_update_username_is_active(bot_user_id_, std::move(username_), is_active_, + std::move(promise_)); + return; + } + promise_.set_error(std::move(status)); + } +}; + +class ReorderBotUsernamesQuery final : public Td::ResultHandler { + Promise promise_; + UserId bot_user_id_; + vector usernames_; + + public: + explicit ReorderBotUsernamesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId bot_user_id, vector &&usernames) { + bot_user_id_ = bot_user_id; + usernames_ = usernames; + auto r_input_user = td_->user_manager_->get_input_user(bot_user_id_); + if (r_input_user.is_error()) { + return on_error(r_input_user.move_as_error()); + } + send_query(G()->net_query_creator().create( + telegram_api::bots_reorderUsernames(r_input_user.move_as_ok(), std::move(usernames)), {{bot_user_id_}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + bool result = result_ptr.ok(); + LOG(DEBUG) << "Receive result for ReorderBotUsernamesQuery: " << result; + if (!result) { + return on_error(Status::Error(500, "Usernames weren't updated")); + } + + td_->user_manager_->on_update_active_usernames_order(bot_user_id_, std::move(usernames_), std::move(promise_)); + } + + void on_error(Status status) final { + if (status.message() == "USERNAME_NOT_MODIFIED") { + td_->user_manager_->on_update_active_usernames_order(bot_user_id_, std::move(usernames_), std::move(promise_)); + return; + } + promise_.set_error(std::move(status)); + } +}; + +class UpdateBirthdayQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit UpdateBirthdayQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const Birthdate &birthdate) { + int32 flags = 0; + if (!birthdate.is_empty()) { + flags |= telegram_api::account_updateBirthday::BIRTHDAY_MASK; + } + send_query(G()->net_query_creator().create( + telegram_api::account_updateBirthday(flags, birthdate.get_input_birthday()), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG(DEBUG) << "Receive result for UpdateBirthdayQuery: " << result_ptr.ok(); + if (result_ptr.ok()) { + promise_.set_value(Unit()); + } else { + promise_.set_error(Status::Error(400, "Failed to change birthdate")); + } + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class UpdatePersonalChannelQuery final : public Td::ResultHandler { + Promise promise_; + ChannelId channel_id_; + + public: + explicit UpdatePersonalChannelQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(ChannelId channel_id) { + channel_id_ = channel_id; + telegram_api::object_ptr input_channel; + if (channel_id == ChannelId()) { + input_channel = telegram_api::make_object(); + } else { + input_channel = td_->chat_manager_->get_input_channel(channel_id); + CHECK(input_channel != nullptr); + } + send_query(G()->net_query_creator().create(telegram_api::account_updatePersonalChannel(std::move(input_channel)), + {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG(DEBUG) << "Receive result for UpdatePersonalChannelQuery: " << result_ptr.ok(); + if (result_ptr.ok()) { + promise_.set_value(Unit()); + } else { + promise_.set_error(Status::Error(400, "Failed to change personal chat")); + } + } + + void on_error(Status status) final { + if (channel_id_.is_valid()) { + td_->chat_manager_->on_get_channel_error(channel_id_, status, "UpdatePersonalChannelQuery"); + } + promise_.set_error(std::move(status)); + } +}; + +class UpdateEmojiStatusQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit UpdateEmojiStatusQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(const EmojiStatus &emoji_status) { + send_query(G()->net_query_creator().create( + telegram_api::account_updateEmojiStatus(emoji_status.get_input_emoji_status()), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG(DEBUG) << "Receive result for UpdateEmojiStatusQuery: " << result_ptr.ok(); + if (result_ptr.ok()) { + promise_.set_value(Unit()); + } else { + promise_.set_error(Status::Error(400, "Failed to change Premium badge")); + } + } + + void on_error(Status status) final { + get_recent_emoji_statuses(td_, Auto()); + promise_.set_error(std::move(status)); + } +}; + +class ToggleSponsoredMessagesQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit ToggleSponsoredMessagesQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(bool sponsored_enabled) { + send_query( + G()->net_query_creator().create(telegram_api::account_toggleSponsoredMessages(sponsored_enabled), {{"me"}})); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + LOG(DEBUG) << "Receive result for ToggleSponsoredMessagesQuery: " << result_ptr.ok(); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetUsersQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetUsersQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(vector> &&input_users) { + send_query(G()->net_query_creator().create(telegram_api::users_getUsers(std::move(input_users)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->user_manager_->on_get_users(result_ptr.move_as_ok(), "GetUsersQuery"); + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetFullUserQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetFullUserQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(telegram_api::object_ptr &&input_user) { + send_query(G()->net_query_creator().create(telegram_api::users_getFullUser(std::move(input_user)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(DEBUG) << "Receive result for GetFullUserQuery: " << to_string(ptr); + td_->user_manager_->on_get_users(std::move(ptr->users_), "GetFullUserQuery"); + td_->chat_manager_->on_get_chats(std::move(ptr->chats_), "GetFullUserQuery"); + td_->user_manager_->on_get_user_full(std::move(ptr->full_user_)); + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetUserPhotosQuery final : public Td::ResultHandler { + Promise promise_; + UserId user_id_; + int32 offset_; + int32 limit_; + + public: + explicit GetUserPhotosQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(UserId user_id, telegram_api::object_ptr &&input_user, int32 offset, int32 limit, + int64 photo_id) { + user_id_ = user_id; + offset_ = offset; + limit_ = limit; + send_query(G()->net_query_creator().create( + telegram_api::photos_getUserPhotos(std::move(input_user), offset, photo_id, limit))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + + LOG(INFO) << "Receive result for GetUserPhotosQuery: " << to_string(ptr); + int32 constructor_id = ptr->get_id(); + if (constructor_id == telegram_api::photos_photos::ID) { + auto photos = move_tl_object_as(ptr); + + td_->user_manager_->on_get_users(std::move(photos->users_), "GetUserPhotosQuery"); + auto photos_size = narrow_cast(photos->photos_.size()); + td_->user_manager_->on_get_user_photos(user_id_, offset_, limit_, photos_size, std::move(photos->photos_)); + } else { + CHECK(constructor_id == telegram_api::photos_photosSlice::ID); + auto photos = move_tl_object_as(ptr); + + td_->user_manager_->on_get_users(std::move(photos->users_), "GetUserPhotosQuery slice"); + td_->user_manager_->on_get_user_photos(user_id_, offset_, limit_, photos->count_, std::move(photos->photos_)); + } + + promise_.set_value(Unit()); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetSupportUserQuery final : public Td::ResultHandler { + Promise promise_; + + public: + explicit GetSupportUserQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send() { + send_query(G()->net_query_creator().create(telegram_api::help_getSupport())); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + auto ptr = result_ptr.move_as_ok(); + LOG(INFO) << "Receive result for GetSupportUserQuery: " << to_string(ptr); + + auto user_id = UserManager::get_user_id(ptr->user_); + td_->user_manager_->on_get_user(std::move(ptr->user_), "GetSupportUserQuery"); + + promise_.set_value(std::move(user_id)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +class GetIsPremiumRequiredToContactQuery final : public Td::ResultHandler { + Promise promise_; + vector user_ids_; + + public: + explicit GetIsPremiumRequiredToContactQuery(Promise &&promise) : promise_(std::move(promise)) { + } + + void send(vector &&user_ids, vector> &&input_users) { + user_ids_ = std::move(user_ids); + send_query( + G()->net_query_creator().create(telegram_api::users_getIsPremiumRequiredToContact(std::move(input_users)))); + } + + void on_result(BufferSlice packet) final { + auto result_ptr = fetch_result(packet); + if (result_ptr.is_error()) { + return on_error(result_ptr.move_as_error()); + } + + td_->user_manager_->on_get_is_premium_required_to_contact_users(std::move(user_ids_), result_ptr.move_as_ok(), + std::move(promise_)); + } + + void on_error(Status status) final { + promise_.set_error(std::move(status)); + } +}; + +template +void UserManager::User::store(StorerT &storer) const { + using td::store; + bool has_last_name = !last_name.empty(); + bool legacy_has_username = false; + bool has_photo = photo.small_file_id.is_valid(); + bool has_language_code = !language_code.empty(); + bool have_access_hash = access_hash != -1; + bool has_cache_version = cache_version != 0; + bool has_is_contact = true; + bool has_restriction_reasons = !restriction_reasons.empty(); + bool has_emoji_status = !emoji_status.is_empty(); + bool has_usernames = !usernames.is_empty(); + bool has_flags2 = true; + bool has_max_active_story_id = max_active_story_id.is_valid(); + bool has_max_read_story_id = max_read_story_id.is_valid(); + bool has_max_active_story_id_next_reload_time = max_active_story_id_next_reload_time > Time::now(); + bool has_accent_color_id = accent_color_id.is_valid(); + bool has_background_custom_emoji_id = background_custom_emoji_id.is_valid(); + bool has_profile_accent_color_id = profile_accent_color_id.is_valid(); + bool has_profile_background_custom_emoji_id = profile_background_custom_emoji_id.is_valid(); + bool has_bot_active_users = bot_active_users != 0; + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_received); + STORE_FLAG(is_verified); + STORE_FLAG(is_deleted); + STORE_FLAG(is_bot); + STORE_FLAG(can_join_groups); + STORE_FLAG(can_read_all_group_messages); + STORE_FLAG(is_inline_bot); + STORE_FLAG(need_location_bot); + STORE_FLAG(has_last_name); + STORE_FLAG(legacy_has_username); + STORE_FLAG(has_photo); + STORE_FLAG(false); // legacy is_restricted + STORE_FLAG(has_language_code); + STORE_FLAG(have_access_hash); + STORE_FLAG(is_support); + STORE_FLAG(is_min_access_hash); + STORE_FLAG(is_scam); + STORE_FLAG(has_cache_version); + STORE_FLAG(has_is_contact); + STORE_FLAG(is_contact); + STORE_FLAG(is_mutual_contact); + STORE_FLAG(has_restriction_reasons); + STORE_FLAG(need_apply_min_photo); + STORE_FLAG(is_fake); + STORE_FLAG(can_be_added_to_attach_menu); + STORE_FLAG(is_premium); + STORE_FLAG(attach_menu_enabled); + STORE_FLAG(has_emoji_status); + STORE_FLAG(has_usernames); + STORE_FLAG(can_be_edited_bot); + END_STORE_FLAGS(); + if (has_flags2) { + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_close_friend); + STORE_FLAG(stories_hidden); + STORE_FLAG(false); + STORE_FLAG(has_max_active_story_id); + STORE_FLAG(has_max_read_story_id); + STORE_FLAG(has_max_active_story_id_next_reload_time); + STORE_FLAG(has_accent_color_id); + STORE_FLAG(has_background_custom_emoji_id); + STORE_FLAG(has_profile_accent_color_id); + STORE_FLAG(has_profile_background_custom_emoji_id); + STORE_FLAG(contact_require_premium); + STORE_FLAG(is_business_bot); + STORE_FLAG(has_bot_active_users); + STORE_FLAG(has_main_app); + END_STORE_FLAGS(); + } + store(first_name, storer); + if (has_last_name) { + store(last_name, storer); + } + store(phone_number, storer); + if (have_access_hash) { + store(access_hash, storer); + } + if (has_photo) { + store(photo, storer); + } + store(was_online, storer); + if (has_restriction_reasons) { + store(restriction_reasons, storer); + } + if (is_inline_bot) { + store(inline_query_placeholder, storer); + } + if (is_bot) { + store(bot_info_version, storer); + } + if (has_language_code) { + store(language_code, storer); + } + if (has_cache_version) { + store(cache_version, storer); + } + if (has_emoji_status) { + store(emoji_status, storer); + } + if (has_usernames) { + store(usernames, storer); + } + if (has_max_active_story_id) { + store(max_active_story_id, storer); + } + if (has_max_read_story_id) { + store(max_read_story_id, storer); + } + if (has_max_active_story_id_next_reload_time) { + store_time(max_active_story_id_next_reload_time, storer); + } + if (has_accent_color_id) { + store(accent_color_id, storer); + } + if (has_background_custom_emoji_id) { + store(background_custom_emoji_id, storer); + } + if (has_profile_accent_color_id) { + store(profile_accent_color_id, storer); + } + if (has_profile_background_custom_emoji_id) { + store(profile_background_custom_emoji_id, storer); + } + if (has_bot_active_users) { + store(bot_active_users, storer); + } +} + +template +void UserManager::User::parse(ParserT &parser) { + using td::parse; + bool has_last_name; + bool legacy_has_username; + bool has_photo; + bool legacy_is_restricted; + bool has_language_code; + bool have_access_hash; + bool has_cache_version; + bool has_is_contact; + bool has_restriction_reasons; + bool has_emoji_status; + bool has_usernames; + bool has_flags2 = parser.version() >= static_cast(Version::AddUserFlags2); + bool legacy_has_stories = false; + bool has_max_active_story_id = false; + bool has_max_read_story_id = false; + bool has_max_active_story_id_next_reload_time = false; + bool has_accent_color_id = false; + bool has_background_custom_emoji_id = false; + bool has_profile_accent_color_id = false; + bool has_profile_background_custom_emoji_id = false; + bool has_bot_active_users = false; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_received); + PARSE_FLAG(is_verified); + PARSE_FLAG(is_deleted); + PARSE_FLAG(is_bot); + PARSE_FLAG(can_join_groups); + PARSE_FLAG(can_read_all_group_messages); + PARSE_FLAG(is_inline_bot); + PARSE_FLAG(need_location_bot); + PARSE_FLAG(has_last_name); + PARSE_FLAG(legacy_has_username); + PARSE_FLAG(has_photo); + PARSE_FLAG(legacy_is_restricted); + PARSE_FLAG(has_language_code); + PARSE_FLAG(have_access_hash); + PARSE_FLAG(is_support); + PARSE_FLAG(is_min_access_hash); + PARSE_FLAG(is_scam); + PARSE_FLAG(has_cache_version); + PARSE_FLAG(has_is_contact); + PARSE_FLAG(is_contact); + PARSE_FLAG(is_mutual_contact); + PARSE_FLAG(has_restriction_reasons); + PARSE_FLAG(need_apply_min_photo); + PARSE_FLAG(is_fake); + PARSE_FLAG(can_be_added_to_attach_menu); + PARSE_FLAG(is_premium); + PARSE_FLAG(attach_menu_enabled); + PARSE_FLAG(has_emoji_status); + PARSE_FLAG(has_usernames); + PARSE_FLAG(can_be_edited_bot); + END_PARSE_FLAGS(); + if (has_flags2) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_close_friend); + PARSE_FLAG(stories_hidden); + PARSE_FLAG(legacy_has_stories); + PARSE_FLAG(has_max_active_story_id); + PARSE_FLAG(has_max_read_story_id); + PARSE_FLAG(has_max_active_story_id_next_reload_time); + PARSE_FLAG(has_accent_color_id); + PARSE_FLAG(has_background_custom_emoji_id); + PARSE_FLAG(has_profile_accent_color_id); + PARSE_FLAG(has_profile_background_custom_emoji_id); + PARSE_FLAG(contact_require_premium); + PARSE_FLAG(is_business_bot); + PARSE_FLAG(has_bot_active_users); + PARSE_FLAG(has_main_app); + END_PARSE_FLAGS(); + } + parse(first_name, parser); + if (has_last_name) { + parse(last_name, parser); + } + if (legacy_has_username) { + CHECK(!has_usernames); + string username; + parse(username, parser); + usernames = Usernames(std::move(username), vector>()); + } + parse(phone_number, parser); + if (parser.version() < static_cast(Version::FixMinUsers)) { + have_access_hash = is_received; + } + if (have_access_hash) { + parse(access_hash, parser); + } else { + is_min_access_hash = true; + } + if (has_photo) { + parse(photo, parser); + } + if (!has_is_contact) { + // enum class LinkState : uint8 { Unknown, None, KnowsPhoneNumber, Contact }; + + uint32 link_state_inbound; + uint32 link_state_outbound; + parse(link_state_inbound, parser); + parse(link_state_outbound, parser); + + is_contact = link_state_outbound == 3; + is_mutual_contact = is_contact && link_state_inbound == 3; + is_close_friend = false; + } + parse(was_online, parser); + if (legacy_is_restricted) { + string restriction_reason; + parse(restriction_reason, parser); + restriction_reasons = get_restriction_reasons(restriction_reason); + } else if (has_restriction_reasons) { + parse(restriction_reasons, parser); + } + if (is_inline_bot) { + parse(inline_query_placeholder, parser); + } + if (is_bot) { + parse(bot_info_version, parser); + } + if (has_language_code) { + parse(language_code, parser); + } + if (has_cache_version) { + parse(cache_version, parser); + } + if (has_emoji_status) { + parse(emoji_status, parser); + } + if (has_usernames) { + CHECK(!legacy_has_username); + parse(usernames, parser); + } + if (has_max_active_story_id) { + parse(max_active_story_id, parser); + } + if (has_max_read_story_id) { + parse(max_read_story_id, parser); + } + if (has_max_active_story_id_next_reload_time) { + parse_time(max_active_story_id_next_reload_time, parser); + } + if (has_accent_color_id) { + parse(accent_color_id, parser); + } + if (has_background_custom_emoji_id) { + parse(background_custom_emoji_id, parser); + } + if (has_profile_accent_color_id) { + parse(profile_accent_color_id, parser); + } + if (has_profile_background_custom_emoji_id) { + parse(profile_background_custom_emoji_id, parser); + } + if (has_bot_active_users) { + parse(bot_active_users, parser); + } + + if (!check_utf8(first_name)) { + LOG(ERROR) << "Have invalid first name \"" << first_name << '"'; + first_name.clear(); + cache_version = 0; + } + if (!check_utf8(last_name)) { + LOG(ERROR) << "Have invalid last name \"" << last_name << '"'; + last_name.clear(); + cache_version = 0; + } + + clean_phone_number(phone_number); + if (first_name.empty() && last_name.empty()) { + first_name = phone_number; + } + if (!is_contact && is_mutual_contact) { + LOG(ERROR) << "Have invalid flag is_mutual_contact"; + is_mutual_contact = false; + cache_version = 0; + } + if (!is_contact && is_close_friend) { + LOG(ERROR) << "Have invalid flag is_close_friend"; + is_close_friend = false; + cache_version = 0; + } +} + +template +void UserManager::UserFull::store(StorerT &storer) const { + using td::store; + bool has_about = !about.empty(); + bool has_photo = !photo.is_empty(); + bool has_description = !description.empty(); + bool has_commands = !commands.empty(); + bool has_private_forward_name = !private_forward_name.empty(); + bool has_group_administrator_rights = group_administrator_rights != AdministratorRights(); + bool has_broadcast_administrator_rights = broadcast_administrator_rights != AdministratorRights(); + bool has_menu_button = menu_button != nullptr; + bool has_description_photo = !description_photo.is_empty(); + bool has_description_animation = description_animation_file_id.is_valid(); + bool has_premium_gift_options = !premium_gift_options.empty(); + bool has_personal_photo = !personal_photo.is_empty(); + bool has_fallback_photo = !fallback_photo.is_empty(); + bool has_business_info = business_info != nullptr && !business_info->is_empty(); + bool has_birthdate = !birthdate.is_empty(); + bool has_personal_channel_id = personal_channel_id.is_valid(); + bool has_flags2 = true; + bool has_privacy_policy_url = !privacy_policy_url.empty(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_about); + STORE_FLAG(is_blocked); + STORE_FLAG(can_be_called); + STORE_FLAG(has_private_calls); + STORE_FLAG(can_pin_messages); + STORE_FLAG(need_phone_number_privacy_exception); + STORE_FLAG(has_photo); + STORE_FLAG(supports_video_calls); + STORE_FLAG(has_description); + STORE_FLAG(has_commands); + STORE_FLAG(has_private_forward_name); + STORE_FLAG(has_group_administrator_rights); + STORE_FLAG(has_broadcast_administrator_rights); + STORE_FLAG(has_menu_button); + STORE_FLAG(has_description_photo); + STORE_FLAG(has_description_animation); + STORE_FLAG(has_premium_gift_options); + STORE_FLAG(voice_messages_forbidden); + STORE_FLAG(has_personal_photo); + STORE_FLAG(has_fallback_photo); + STORE_FLAG(has_pinned_stories); + STORE_FLAG(is_blocked_for_stories); + STORE_FLAG(wallpaper_overridden); + STORE_FLAG(read_dates_private); + STORE_FLAG(contact_require_premium); + STORE_FLAG(has_business_info); + STORE_FLAG(has_birthdate); + STORE_FLAG(has_personal_channel_id); + STORE_FLAG(sponsored_enabled); + STORE_FLAG(has_flags2); + END_STORE_FLAGS(); + if (has_flags2) { + BEGIN_STORE_FLAGS(); + STORE_FLAG(has_preview_medias); + STORE_FLAG(has_privacy_policy_url); + END_STORE_FLAGS(); + } + if (has_about) { + store(about, storer); + } + store(common_chat_count, storer); + store_time(expires_at, storer); + if (has_photo) { + store(photo, storer); + } + if (has_description) { + store(description, storer); + } + if (has_commands) { + store(commands, storer); + } + if (has_private_forward_name) { + store(private_forward_name, storer); + } + if (has_group_administrator_rights) { + store(group_administrator_rights, storer); + } + if (has_broadcast_administrator_rights) { + store(broadcast_administrator_rights, storer); + } + if (has_menu_button) { + store(menu_button, storer); + } + if (has_description_photo) { + store(description_photo, storer); + } + if (has_description_animation) { + storer.context()->td().get_actor_unsafe()->animations_manager_->store_animation(description_animation_file_id, + storer); + } + if (has_premium_gift_options) { + store(premium_gift_options, storer); + } + if (has_personal_photo) { + store(personal_photo, storer); + } + if (has_fallback_photo) { + store(fallback_photo, storer); + } + if (has_business_info) { + store(business_info, storer); + } + if (has_birthdate) { + store(birthdate, storer); + } + if (has_personal_channel_id) { + store(personal_channel_id, storer); + } + if (has_privacy_policy_url) { + store(privacy_policy_url, storer); + } +} + +template +void UserManager::UserFull::parse(ParserT &parser) { + using td::parse; + bool has_about; + bool has_photo; + bool has_description; + bool has_commands; + bool has_private_forward_name; + bool has_group_administrator_rights; + bool has_broadcast_administrator_rights; + bool has_menu_button; + bool has_description_photo; + bool has_description_animation; + bool has_premium_gift_options; + bool has_personal_photo; + bool has_fallback_photo; + bool has_business_info; + bool has_birthdate; + bool has_personal_channel_id; + bool has_flags2; + bool has_privacy_policy_url = false; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_about); + PARSE_FLAG(is_blocked); + PARSE_FLAG(can_be_called); + PARSE_FLAG(has_private_calls); + PARSE_FLAG(can_pin_messages); + PARSE_FLAG(need_phone_number_privacy_exception); + PARSE_FLAG(has_photo); + PARSE_FLAG(supports_video_calls); + PARSE_FLAG(has_description); + PARSE_FLAG(has_commands); + PARSE_FLAG(has_private_forward_name); + PARSE_FLAG(has_group_administrator_rights); + PARSE_FLAG(has_broadcast_administrator_rights); + PARSE_FLAG(has_menu_button); + PARSE_FLAG(has_description_photo); + PARSE_FLAG(has_description_animation); + PARSE_FLAG(has_premium_gift_options); + PARSE_FLAG(voice_messages_forbidden); + PARSE_FLAG(has_personal_photo); + PARSE_FLAG(has_fallback_photo); + PARSE_FLAG(has_pinned_stories); + PARSE_FLAG(is_blocked_for_stories); + PARSE_FLAG(wallpaper_overridden); + PARSE_FLAG(read_dates_private); + PARSE_FLAG(contact_require_premium); + PARSE_FLAG(has_business_info); + PARSE_FLAG(has_birthdate); + PARSE_FLAG(has_personal_channel_id); + PARSE_FLAG(sponsored_enabled); + PARSE_FLAG(has_flags2); + END_PARSE_FLAGS(); + if (has_flags2) { + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(has_preview_medias); + PARSE_FLAG(has_privacy_policy_url); + END_PARSE_FLAGS(); + } + if (has_about) { + parse(about, parser); + } + parse(common_chat_count, parser); + parse_time(expires_at, parser); + if (has_photo) { + parse(photo, parser); + } + if (has_description) { + parse(description, parser); + } + if (has_commands) { + parse(commands, parser); + } + if (has_private_forward_name) { + parse(private_forward_name, parser); + } + if (has_group_administrator_rights) { + parse(group_administrator_rights, parser); + } + if (has_broadcast_administrator_rights) { + parse(broadcast_administrator_rights, parser); + } + if (has_menu_button) { + parse(menu_button, parser); + } + if (has_description_photo) { + parse(description_photo, parser); + } + if (has_description_animation) { + description_animation_file_id = + parser.context()->td().get_actor_unsafe()->animations_manager_->parse_animation(parser); + } + if (has_premium_gift_options) { + parse(premium_gift_options, parser); + } + if (has_personal_photo) { + parse(personal_photo, parser); + } + if (has_fallback_photo) { + parse(fallback_photo, parser); + } + if (has_business_info) { + parse(business_info, parser); + } + if (has_birthdate) { + parse(birthdate, parser); + } + if (has_personal_channel_id) { + parse(personal_channel_id, parser); + } + if (has_privacy_policy_url) { + parse(privacy_policy_url, parser); + } +} + +template +void UserManager::SecretChat::store(StorerT &storer) const { + using td::store; + bool has_layer = layer > static_cast(SecretChatLayer::Default); + bool has_initial_folder_id = initial_folder_id != FolderId(); + BEGIN_STORE_FLAGS(); + STORE_FLAG(is_outbound); + STORE_FLAG(has_layer); + STORE_FLAG(has_initial_folder_id); + END_STORE_FLAGS(); + + store(access_hash, storer); + store(user_id, storer); + store(state, storer); + store(ttl, storer); + store(date, storer); + store(key_hash, storer); + if (has_layer) { + store(layer, storer); + } + if (has_initial_folder_id) { + store(initial_folder_id, storer); + } +} + +template +void UserManager::SecretChat::parse(ParserT &parser) { + using td::parse; + bool has_layer; + bool has_initial_folder_id; + BEGIN_PARSE_FLAGS(); + PARSE_FLAG(is_outbound); + PARSE_FLAG(has_layer); + PARSE_FLAG(has_initial_folder_id); + END_PARSE_FLAGS(); + + if (parser.version() >= static_cast(Version::AddAccessHashToSecretChat)) { + parse(access_hash, parser); + } + parse(user_id, parser); + parse(state, parser); + parse(ttl, parser); + parse(date, parser); + if (parser.version() >= static_cast(Version::AddKeyHashToSecretChat)) { + parse(key_hash, parser); + } + if (has_layer) { + parse(layer, parser); + } else { + layer = static_cast(SecretChatLayer::Default); + } + if (has_initial_folder_id) { + parse(initial_folder_id, parser); + } +} + +class UserManager::UserLogEvent { + public: + UserId user_id; + const User *u_in = nullptr; + unique_ptr u_out; + + UserLogEvent() = default; + + UserLogEvent(UserId user_id, const User *u) : user_id(user_id), u_in(u) { + } + + template + void store(StorerT &storer) const { + td::store(user_id, storer); + td::store(*u_in, storer); + } + + template + void parse(ParserT &parser) { + td::parse(user_id, parser); + td::parse(u_out, parser); + } +}; + +class UserManager::SecretChatLogEvent { + public: + SecretChatId secret_chat_id; + const SecretChat *c_in = nullptr; + unique_ptr c_out; + + SecretChatLogEvent() = default; + + SecretChatLogEvent(SecretChatId secret_chat_id, const SecretChat *c) : secret_chat_id(secret_chat_id), c_in(c) { + } + + template + void store(StorerT &storer) const { + td::store(secret_chat_id, storer); + td::store(*c_in, storer); + } + + template + void parse(ParserT &parser) { + td::parse(secret_chat_id, parser); + td::parse(c_out, parser); + } +}; + +class UserManager::UploadProfilePhotoCallback final : public FileManager::UploadCallback { + public: + void on_upload_ok(FileId file_id, telegram_api::object_ptr input_file) final { + send_closure_later(G()->user_manager(), &UserManager::on_upload_profile_photo, file_id, std::move(input_file)); + } + void on_upload_encrypted_ok(FileId file_id, + telegram_api::object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_secure_ok(FileId file_id, telegram_api::object_ptr input_file) final { + UNREACHABLE(); + } + void on_upload_error(FileId file_id, Status error) final { + send_closure_later(G()->user_manager(), &UserManager::on_upload_profile_photo_error, file_id, std::move(error)); + } +}; + +UserManager::UserManager(Td *td, ActorShared<> parent) : td_(td), parent_(std::move(parent)) { + upload_profile_photo_callback_ = std::make_shared(); + + my_id_ = load_my_id(); + + if (G()->use_chat_info_database()) { + auto next_contacts_sync_date_string = G()->td_db()->get_binlog_pmc()->get("next_contacts_sync_date"); + if (!next_contacts_sync_date_string.empty()) { + next_contacts_sync_date_ = min(to_integer(next_contacts_sync_date_string), G()->unix_time() + 100000); + } + + auto saved_contact_count_string = G()->td_db()->get_binlog_pmc()->get("saved_contact_count"); + if (!saved_contact_count_string.empty()) { + saved_contact_count_ = to_integer(saved_contact_count_string); + } + } else if (!td_->auth_manager_->is_bot()) { + G()->td_db()->get_binlog_pmc()->erase("next_contacts_sync_date"); + G()->td_db()->get_binlog_pmc()->erase("saved_contact_count"); + } + if (G()->use_sqlite_pmc()) { + G()->td_db()->get_sqlite_pmc()->erase_by_prefix("us_bot_info", Auto()); + } + + if (!td_->auth_manager_->is_bot()) { + was_online_local_ = to_integer(G()->td_db()->get_binlog_pmc()->get("my_was_online_local")); + was_online_remote_ = to_integer(G()->td_db()->get_binlog_pmc()->get("my_was_online_remote")); + auto unix_time = G()->unix_time(); + if (was_online_local_ >= unix_time && !td_->online_manager_->is_online()) { + was_online_local_ = unix_time - 1; + } + } + + user_online_timeout_.set_callback(on_user_online_timeout_callback); + user_online_timeout_.set_callback_data(static_cast(this)); + + user_emoji_status_timeout_.set_callback(on_user_emoji_status_timeout_callback); + user_emoji_status_timeout_.set_callback_data(static_cast(this)); + + get_user_queries_.set_merge_function([this](vector query_ids, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + auto input_users = transform(query_ids, [this](int64 query_id) { return get_input_user_force(UserId(query_id)); }); + td_->create_handler(std::move(promise))->send(std::move(input_users)); + }); + get_is_premium_required_to_contact_queries_.set_merge_function( + [this](vector query_ids, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + auto user_ids = UserId::get_user_ids(query_ids); + auto input_users = transform(user_ids, [this](UserId user_id) { return get_input_user_force(user_id); }); + td_->create_handler(std::move(promise)) + ->send(std::move(user_ids), std::move(input_users)); + }); +} + +UserManager::~UserManager() { + Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), users_, users_full_, user_photos_, + unknown_users_, pending_user_photos_, user_profile_photo_file_source_ids_, + my_photo_file_id_, user_full_file_source_ids_, secret_chats_, + unknown_secret_chats_, secret_chats_with_user_); + Scheduler::instance()->destroy_on_scheduler(G()->get_gc_scheduler_id(), loaded_from_database_users_, + unavailable_user_fulls_, loaded_from_database_secret_chats_, + resolved_phone_numbers_, all_imported_contacts_, restricted_user_ids_); +} + +void UserManager::tear_down() { + parent_.reset(); + + LOG(DEBUG) << "Have " << users_.calc_size() << " users and " << secret_chats_.calc_size() << " secret chats to free"; + LOG(DEBUG) << "Have " << users_full_.calc_size() << " full users to free"; +} + +void UserManager::on_user_online_timeout_callback(void *user_manager_ptr, int64 user_id_long) { + if (G()->close_flag()) { + return; + } + + auto user_manager = static_cast(user_manager_ptr); + send_closure_later(user_manager->actor_id(user_manager), &UserManager::on_user_online_timeout, UserId(user_id_long)); +} + +void UserManager::on_user_online_timeout(UserId user_id) { + if (G()->close_flag()) { + return; + } + + auto u = get_user(user_id); + CHECK(u != nullptr); + CHECK(u->is_update_user_sent); + + LOG(INFO) << "Update " << user_id << " online status to offline"; + send_closure(G()->td(), &Td::send_update, + td_api::make_object(user_id.get(), + get_user_status_object(user_id, u, G()->unix_time()))); + + td_->dialog_participant_manager_->update_user_online_member_count(user_id); +} + +void UserManager::on_user_emoji_status_timeout_callback(void *user_manager_ptr, int64 user_id_long) { + if (G()->close_flag()) { + return; + } + + auto user_manager = static_cast(user_manager_ptr); + send_closure_later(user_manager->actor_id(user_manager), &UserManager::on_user_emoji_status_timeout, + UserId(user_id_long)); +} + +void UserManager::on_user_emoji_status_timeout(UserId user_id) { + if (G()->close_flag()) { + return; + } + + auto u = get_user(user_id); + CHECK(u != nullptr); + CHECK(u->is_update_user_sent); + + update_user(u, user_id); +} + +UserId UserManager::get_user_id(const telegram_api::object_ptr &user) { + CHECK(user != nullptr); + switch (user->get_id()) { + case telegram_api::userEmpty::ID: + return UserId(static_cast(user.get())->id_); + case telegram_api::user::ID: + return UserId(static_cast(user.get())->id_); + default: + UNREACHABLE(); + return UserId(); + } +} + +UserId UserManager::load_my_id() { + auto id_string = G()->td_db()->get_binlog_pmc()->get("my_id"); + if (!id_string.empty()) { + UserId my_id(to_integer(id_string)); + if (my_id.is_valid()) { + return my_id; + } + + my_id = UserId(to_integer(Slice(id_string).substr(5))); + if (my_id.is_valid()) { + G()->td_db()->get_binlog_pmc()->set("my_id", to_string(my_id.get())); + return my_id; + } + + LOG(ERROR) << "Wrong my ID = \"" << id_string << "\" stored in database"; + } + return UserId(); +} + +UserId UserManager::get_my_id() const { + LOG_IF(ERROR, !my_id_.is_valid()) << "Wrong or unknown my ID returned"; + return my_id_; +} + +void UserManager::set_my_id(UserId my_id) { + UserId my_old_id = my_id_; + if (my_old_id.is_valid() && my_old_id != my_id) { + LOG(ERROR) << "Already know that me is " << my_old_id << " but received userSelf with " << my_id; + return; + } + if (!my_id.is_valid()) { + LOG(ERROR) << "Receive invalid my ID " << my_id; + return; + } + if (my_old_id != my_id) { + my_id_ = my_id; + G()->td_db()->get_binlog_pmc()->set("my_id", to_string(my_id.get())); + td_->option_manager_->set_option_integer("my_id", my_id_.get()); + if (!td_->auth_manager_->is_bot()) { + G()->td_db()->get_binlog_pmc()->force_sync(Promise(), "set_my_id"); + } + } +} + +UserId UserManager::get_service_notifications_user_id() { + return UserId(static_cast(777000)); +} + +UserId UserManager::add_service_notifications_user() { + auto user_id = get_service_notifications_user_id(); + if (!have_user_force(user_id, "add_service_notifications_user")) { + LOG(FATAL) << "Failed to load service notification user"; + } + return user_id; +} + +UserId UserManager::get_replies_bot_user_id() { + return UserId(static_cast(G()->is_test_dc() ? 708513 : 1271266957)); +} + +UserId UserManager::get_anonymous_bot_user_id() { + return UserId(static_cast(G()->is_test_dc() ? 552888 : 1087968824)); +} + +UserId UserManager::get_channel_bot_user_id() { + return UserId(static_cast(G()->is_test_dc() ? 936174 : 136817688)); +} + +UserId UserManager::get_anti_spam_bot_user_id() { + return UserId(static_cast(G()->is_test_dc() ? 2200583762ll : 5434988373ll)); +} + +UserId UserManager::add_anonymous_bot_user() { + auto user_id = get_anonymous_bot_user_id(); + if (!have_user_force(user_id, "add_anonymous_bot_user")) { + LOG(FATAL) << "Failed to load anonymous bot user"; + } + return user_id; +} + +UserId UserManager::add_channel_bot_user() { + auto user_id = get_channel_bot_user_id(); + if (!have_user_force(user_id, "add_channel_bot_user")) { + LOG(FATAL) << "Failed to load channel bot user"; + } + return user_id; +} + +UserManager::MyOnlineStatusInfo UserManager::get_my_online_status() const { + MyOnlineStatusInfo status_info; + status_info.is_online_local = td_->online_manager_->is_online(); + status_info.is_online_remote = was_online_remote_ > G()->unix_time(); + status_info.was_online_local = was_online_local_; + status_info.was_online_remote = was_online_remote_; + + return status_info; +} + +void UserManager::set_my_online_status(bool is_online, bool send_update, bool is_local) { + if (td_->auth_manager_->is_bot()) { + return; // just in case + } + + auto my_id = get_my_id(); + User *u = get_user_force(my_id, "set_my_online_status"); + if (u != nullptr) { + int32 new_online; + int32 unix_time = G()->unix_time(); + if (is_online) { + new_online = unix_time + 300; + } else { + new_online = unix_time - 1; + } + + auto old_was_online = get_user_was_online(u, my_id, unix_time); + if (is_local) { + LOG(INFO) << "Update my local online from " << my_was_online_local_ << " to " << new_online; + if (!is_online) { + new_online = min(new_online, u->was_online); + } + if (new_online != my_was_online_local_) { + my_was_online_local_ = new_online; + } + } else { + if (my_was_online_local_ != 0 || new_online != u->was_online) { + LOG(INFO) << "Update my online from " << u->was_online << " to " << new_online; + my_was_online_local_ = 0; + u->was_online = new_online; + u->need_save_to_database = true; + } + } + if (old_was_online != get_user_was_online(u, my_id, unix_time)) { + u->is_status_changed = true; + u->is_online_status_changed = true; + } + + if (was_online_local_ != new_online) { + was_online_local_ = new_online; + VLOG(notifications) << "Set was_online_local to " << was_online_local_; + G()->td_db()->get_binlog_pmc()->set("my_was_online_local", to_string(was_online_local_)); + } + + if (send_update) { + update_user(u, my_id); + } + } +} + +void UserManager::on_get_user(telegram_api::object_ptr &&user_ptr, const char *source) { + LOG(DEBUG) << "Receive from " << source << ' ' << to_string(user_ptr); + int32 constructor_id = user_ptr->get_id(); + if (constructor_id == telegram_api::userEmpty::ID) { + auto user = move_tl_object_as(user_ptr); + UserId user_id(user->id_); + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id << " from " << source; + return; + } + LOG(INFO) << "Receive empty " << user_id << " from " << source; + + User *u = get_user_force(user_id, source); + if (u == nullptr && Slice(source) != Slice("GetUsersQuery")) { + // userEmpty should be received only through getUsers for nonexistent users + LOG(ERROR) << "Have no information about " << user_id << ", but received userEmpty from " << source; + } + return; + } + + CHECK(constructor_id == telegram_api::user::ID); + auto user = move_tl_object_as(user_ptr); + UserId user_id(user->id_); + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + int32 flags = user->flags_; + int32 flags2 = user->flags2_; + LOG(INFO) << "Receive " << user_id << " with flags " << flags << ' ' << flags2 << " from " << source; + + // the True fields aren't set for manually created telegram_api::user objects, therefore the flags must be used + bool is_bot = (flags & USER_FLAG_IS_BOT) != 0; + if (flags & USER_FLAG_IS_ME) { + set_my_id(user_id); + if (!is_bot) { + td_->option_manager_->set_option_string("my_phone_number", user->phone_); + } + } + + bool have_access_hash = (flags & USER_FLAG_HAS_ACCESS_HASH) != 0; + bool is_received = (flags & USER_FLAG_IS_INACCESSIBLE) == 0; + bool is_contact = (flags & USER_FLAG_IS_CONTACT) != 0; + + User *u = get_user(user_id); + if (u == nullptr) { + if (!is_received) { + // we must preload received inaccessible users from database in order to not save + // the min-user to the database and to not override access_hash and other data + u = get_user_force(user_id, "on_get_user 2"); + if (u == nullptr) { + LOG(INFO) << "Receive inaccessible " << user_id; + u = add_user(user_id); + } + } else if (is_contact && !are_contacts_loaded_) { + // preload contact users from database to know that is_contact didn't changed + // and the list of contacts doesn't need to be saved to the database + u = get_user_force(user_id, "on_get_user 3"); + if (u == nullptr) { + LOG(INFO) << "Receive contact " << user_id << " for the first time"; + u = add_user(user_id); + } + } else { + u = add_user(user_id); + } + CHECK(u != nullptr); + } + + if (have_access_hash) { // access_hash must be updated before photo + auto access_hash = user->access_hash_; + bool is_min_access_hash = !is_received && !((flags & USER_FLAG_HAS_PHONE_NUMBER) != 0 && user->phone_.empty()); + if (u->access_hash != access_hash && (!is_min_access_hash || u->is_min_access_hash || u->access_hash == -1)) { + LOG(DEBUG) << "Access hash has changed for " << user_id << " from " << u->access_hash << "/" + << u->is_min_access_hash << " to " << access_hash << "/" << is_min_access_hash; + u->access_hash = access_hash; + u->is_min_access_hash = is_min_access_hash; + u->need_save_to_database = true; + } + } + + bool is_verified = (flags & USER_FLAG_IS_VERIFIED) != 0; + bool is_premium = (flags & USER_FLAG_IS_PREMIUM) != 0; + bool is_support = (flags & USER_FLAG_IS_SUPPORT) != 0; + bool is_deleted = (flags & USER_FLAG_IS_DELETED) != 0; + bool can_join_groups = (flags & USER_FLAG_IS_PRIVATE_BOT) == 0; + bool can_read_all_group_messages = (flags & USER_FLAG_IS_BOT_WITH_PRIVACY_DISABLED) != 0; + bool can_be_added_to_attach_menu = (flags & USER_FLAG_IS_ATTACH_MENU_BOT) != 0; + bool has_main_app = user->bot_has_main_app_; + bool attach_menu_enabled = (flags & USER_FLAG_ATTACH_MENU_ENABLED) != 0; + bool is_scam = (flags & USER_FLAG_IS_SCAM) != 0; + bool can_be_edited_bot = (flags2 & USER_FLAG_CAN_BE_EDITED_BOT) != 0; + bool is_inline_bot = (flags & USER_FLAG_IS_INLINE_BOT) != 0; + bool is_business_bot = user->bot_business_; + string inline_query_placeholder = std::move(user->bot_inline_placeholder_); + int32 bot_active_users = user->bot_active_users_; + bool need_location_bot = (flags & USER_FLAG_NEED_LOCATION_BOT) != 0; + bool has_bot_info_version = (flags & USER_FLAG_HAS_BOT_INFO_VERSION) != 0; + bool need_apply_min_photo = (flags & USER_FLAG_NEED_APPLY_MIN_PHOTO) != 0; + bool is_fake = (flags & USER_FLAG_IS_FAKE) != 0; + bool stories_available = user->stories_max_id_ > 0; + bool stories_unavailable = user->stories_unavailable_; + bool stories_hidden = user->stories_hidden_; + bool contact_require_premium = user->contact_require_premium_; + + if (!is_bot && (!can_join_groups || can_read_all_group_messages || can_be_added_to_attach_menu || can_be_edited_bot || + has_main_app || is_inline_bot || is_business_bot)) { + LOG(ERROR) << "Receive not bot " << user_id << " with bot properties from " << source; + can_join_groups = true; + can_read_all_group_messages = false; + can_be_added_to_attach_menu = false; + can_be_edited_bot = false; + has_main_app = false; + is_inline_bot = false; + is_business_bot = false; + } + if (need_location_bot && !is_inline_bot) { + LOG(ERROR) << "Receive not inline bot " << user_id << " which needs user location from " << source; + need_location_bot = false; + } + + if (is_deleted) { + // just in case + is_verified = false; + is_premium = false; + is_support = false; + is_bot = false; + can_join_groups = false; + can_read_all_group_messages = false; + can_be_added_to_attach_menu = false; + can_be_edited_bot = false; + has_main_app = false; + is_inline_bot = false; + is_business_bot = false; + inline_query_placeholder = string(); + bot_active_users = 0; + need_location_bot = false; + has_bot_info_version = false; + need_apply_min_photo = false; + } + + LOG_IF(ERROR, has_bot_info_version && !is_bot) + << "Receive not bot " << user_id << " which has bot info version from " << source; + + int32 bot_info_version = has_bot_info_version ? user->bot_info_version_ : -1; + if (is_verified != u->is_verified || is_support != u->is_support || is_bot != u->is_bot || + can_join_groups != u->can_join_groups || can_read_all_group_messages != u->can_read_all_group_messages || + is_scam != u->is_scam || is_fake != u->is_fake || is_inline_bot != u->is_inline_bot || + is_business_bot != u->is_business_bot || inline_query_placeholder != u->inline_query_placeholder || + need_location_bot != u->need_location_bot || can_be_added_to_attach_menu != u->can_be_added_to_attach_menu || + bot_active_users != u->bot_active_users || has_main_app != u->has_main_app) { + if (is_bot != u->is_bot) { + LOG_IF(ERROR, !is_deleted && !u->is_deleted && u->is_received) + << "User.is_bot has changed for " << user_id << "/" << u->usernames << " from " << source << " from " + << u->is_bot << " to " << is_bot; + u->is_full_info_changed = true; + } + u->is_verified = is_verified; + u->is_support = is_support; + u->is_bot = is_bot; + u->can_join_groups = can_join_groups; + u->can_read_all_group_messages = can_read_all_group_messages; + u->is_scam = is_scam; + u->is_fake = is_fake; + u->is_inline_bot = is_inline_bot; + u->is_business_bot = is_business_bot; + u->inline_query_placeholder = std::move(inline_query_placeholder); + u->need_location_bot = need_location_bot; + u->can_be_added_to_attach_menu = can_be_added_to_attach_menu; + u->bot_active_users = bot_active_users; + u->has_main_app = has_main_app; + + LOG(DEBUG) << "Info has changed for " << user_id; + u->is_changed = true; + } + if (u->contact_require_premium != contact_require_premium) { + u->contact_require_premium = contact_require_premium; + u->is_changed = true; + user_full_contact_require_premium_.erase(user_id); + } + if (is_received && attach_menu_enabled != u->attach_menu_enabled) { + u->attach_menu_enabled = attach_menu_enabled; + u->is_changed = true; + } + if (is_premium != u->is_premium) { + u->is_premium = is_premium; + u->is_is_premium_changed = true; + u->is_changed = true; + u->is_full_info_changed = true; + } + if (is_received && can_be_edited_bot != u->can_be_edited_bot) { + u->can_be_edited_bot = can_be_edited_bot; + u->is_changed = true; + u->is_full_info_changed = true; + } + + if (u->bot_info_version != bot_info_version) { + u->bot_info_version = bot_info_version; + LOG(DEBUG) << "Bot info version has changed for " << user_id; + u->need_save_to_database = true; + } + if (is_received && u->need_apply_min_photo != need_apply_min_photo) { + LOG(DEBUG) << "Need apply min photo has changed for " << user_id; + u->need_apply_min_photo = need_apply_min_photo; + u->need_save_to_database = true; + } + + if (is_received && !u->is_received) { + u->is_received = true; + + LOG(DEBUG) << "Receive " << user_id; + u->is_changed = true; + } + + if (is_deleted != u->is_deleted) { + u->is_deleted = is_deleted; + + LOG(DEBUG) << "User.is_deleted has changed for " << user_id << " to " << u->is_deleted; + u->is_is_deleted_changed = true; + u->is_changed = true; + } + + bool has_language_code = (flags & USER_FLAG_HAS_LANGUAGE_CODE) != 0; + LOG_IF(ERROR, has_language_code && !td_->auth_manager_->is_bot()) + << "Receive language code for " << user_id << " from " << source; + if (u->language_code != user->lang_code_ && !user->lang_code_.empty()) { + u->language_code = user->lang_code_; + + LOG(DEBUG) << "Language code has changed for " << user_id << " to " << u->language_code; + u->is_changed = true; + } + + bool is_me_regular_user = !td_->auth_manager_->is_bot(); + if (is_received || u->need_apply_min_photo || !u->is_received) { + on_update_user_photo(u, user_id, std::move(user->photo_), source); + } + if (is_me_regular_user) { + if (is_received || !u->is_received) { + on_update_user_phone_number(u, user_id, std::move(user->phone_)); + } + if (is_received || !u->is_received || u->was_online == 0) { + on_update_user_online(u, user_id, std::move(user->status_)); + } + if (is_received) { + auto is_mutual_contact = (flags & USER_FLAG_IS_MUTUAL_CONTACT) != 0; + auto is_close_friend = (flags2 & USER_FLAG_IS_CLOSE_FRIEND) != 0; + on_update_user_is_contact(u, user_id, is_contact, is_mutual_contact, is_close_friend); + } + } + + if (is_received || !u->is_received) { + on_update_user_name(u, user_id, std::move(user->first_name_), std::move(user->last_name_)); + on_update_user_usernames(u, user_id, Usernames{std::move(user->username_), std::move(user->usernames_)}); + } + on_update_user_emoji_status(u, user_id, EmojiStatus(std::move(user->emoji_status_))); + PeerColor peer_color(user->color_); + on_update_user_accent_color_id(u, user_id, peer_color.accent_color_id_); + on_update_user_background_custom_emoji_id(u, user_id, peer_color.background_custom_emoji_id_); + PeerColor profile_peer_color(user->profile_color_); + on_update_user_profile_accent_color_id(u, user_id, profile_peer_color.accent_color_id_); + on_update_user_profile_background_custom_emoji_id(u, user_id, profile_peer_color.background_custom_emoji_id_); + if (is_me_regular_user) { + if (is_received) { + on_update_user_stories_hidden(u, user_id, stories_hidden); + } + if (stories_available || stories_unavailable) { + // update at the end, because it calls need_poll_user_active_stories + on_update_user_story_ids_impl(u, user_id, StoryId(user->stories_max_id_), StoryId()); + } + auto restriction_reasons = get_restriction_reasons(std::move(user->restriction_reason_)); + if (restriction_reasons != u->restriction_reasons) { + u->restriction_reasons = std::move(restriction_reasons); + u->is_changed = true; + } + } + + if (u->cache_version != User::CACHE_VERSION && u->is_received) { + u->cache_version = User::CACHE_VERSION; + u->need_save_to_database = true; + } + u->is_received_from_server = true; + update_user(u, user_id); +} + +void UserManager::on_get_users(vector> &&users, const char *source) { + for (auto &user : users) { + on_get_user(std::move(user), source); + } +} + +void UserManager::on_binlog_user_event(BinlogEvent &&event) { + if (!G()->use_chat_info_database()) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + return; + } + + UserLogEvent log_event; + if (log_event_parse(log_event, event.get_data()).is_error()) { + LOG(ERROR) << "Failed to load a user from binlog"; + binlog_erase(G()->td_db()->get_binlog(), event.id_); + return; + } + + auto user_id = log_event.user_id; + if (have_min_user(user_id) || !user_id.is_valid()) { + LOG(ERROR) << "Skip adding already added " << user_id; + binlog_erase(G()->td_db()->get_binlog(), event.id_); + return; + } + + LOG(INFO) << "Add " << user_id << " from binlog"; + users_.set(user_id, std::move(log_event.u_out)); + + User *u = get_user(user_id); + CHECK(u != nullptr); + u->log_event_id = event.id_; + + update_user(u, user_id, true, false); +} + +void UserManager::on_binlog_secret_chat_event(BinlogEvent &&event) { + if (!G()->use_chat_info_database()) { + binlog_erase(G()->td_db()->get_binlog(), event.id_); + return; + } + + SecretChatLogEvent log_event; + if (log_event_parse(log_event, event.get_data()).is_error()) { + LOG(ERROR) << "Failed to load a secret chat from binlog"; + binlog_erase(G()->td_db()->get_binlog(), event.id_); + return; + } + + auto secret_chat_id = log_event.secret_chat_id; + if (have_secret_chat(secret_chat_id) || !secret_chat_id.is_valid()) { + LOG(ERROR) << "Skip adding already added " << secret_chat_id; + binlog_erase(G()->td_db()->get_binlog(), event.id_); + return; + } + + LOG(INFO) << "Add " << secret_chat_id << " from binlog"; + secret_chats_.set(secret_chat_id, std::move(log_event.c_out)); + + SecretChat *c = get_secret_chat(secret_chat_id); + CHECK(c != nullptr); + c->log_event_id = event.id_; + + update_secret_chat(c, secret_chat_id, true, false); +} + +void UserManager::on_update_user_name(UserId user_id, string &&first_name, string &&last_name, Usernames &&usernames) { + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + User *u = get_user_force(user_id, "on_update_user_name"); + if (u != nullptr) { + on_update_user_name(u, user_id, std::move(first_name), std::move(last_name)); + on_update_user_usernames(u, user_id, std::move(usernames)); + update_user(u, user_id); + } else { + LOG(INFO) << "Ignore update user name about unknown " << user_id; + } +} + +void UserManager::on_update_user_name(User *u, UserId user_id, string &&first_name, string &&last_name) { + if (first_name.empty() && last_name.empty()) { + first_name = u->phone_number; + } + if (u->first_name != first_name || u->last_name != last_name) { + u->first_name = std::move(first_name); + u->last_name = std::move(last_name); + u->is_name_changed = true; + LOG(DEBUG) << "Name has changed for " << user_id; + u->is_changed = true; + } +} + +void UserManager::on_update_user_usernames(User *u, UserId user_id, Usernames &&usernames) { + if (u->usernames != usernames) { + td_->dialog_manager_->on_dialog_usernames_updated(DialogId(user_id), u->usernames, usernames); + td_->messages_manager_->on_dialog_usernames_updated(DialogId(user_id), u->usernames, usernames); + if (u->can_be_edited_bot && u->usernames.get_editable_username() != usernames.get_editable_username()) { + u->is_full_info_changed = true; + } + u->usernames = std::move(usernames); + u->is_username_changed = true; + LOG(DEBUG) << "Usernames have changed for " << user_id; + u->is_changed = true; + } else if (u->is_bot || !td_->auth_manager_->is_bot()) { + td_->dialog_manager_->on_dialog_usernames_received(DialogId(user_id), usernames, false); + } +} + +void UserManager::on_update_user_phone_number(UserId user_id, string &&phone_number) { + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + User *u = get_user_force(user_id, "on_update_user_phone_number"); + if (u != nullptr) { + on_update_user_phone_number(u, user_id, std::move(phone_number)); + update_user(u, user_id); + } else { + LOG(INFO) << "Ignore update user phone number about unknown " << user_id; + } +} + +void UserManager::on_update_user_phone_number(User *u, UserId user_id, string &&phone_number) { + if (td_->auth_manager_->is_bot()) { + return; + } + + clean_phone_number(phone_number); + if (u->phone_number != phone_number) { + if (!u->phone_number.empty()) { + auto it = resolved_phone_numbers_.find(u->phone_number); + if (it != resolved_phone_numbers_.end() && it->second == user_id) { + resolved_phone_numbers_.erase(it); + } + } + + u->phone_number = std::move(phone_number); + u->is_phone_number_changed = true; + LOG(DEBUG) << "Phone number has changed for " << user_id; + u->is_changed = true; + } +} + +void UserManager::on_update_user_photo(User *u, UserId user_id, + telegram_api::object_ptr &&photo, + const char *source) { + if (td_->auth_manager_->is_bot() && !G()->use_chat_info_database()) { + if (!u->is_photo_inited) { + auto new_photo_id = get_profile_photo_id(photo); + auto &old_photo = pending_user_photos_[user_id]; + if (new_photo_id == get_profile_photo_id(old_photo)) { + return; + } + if (photo != nullptr && photo->get_id() == telegram_api::userProfilePhoto::ID) { + auto *profile_photo = static_cast(photo.get()); + if ((profile_photo->flags_ & telegram_api::userProfilePhoto::STRIPPED_THUMB_MASK) != 0) { + profile_photo->flags_ -= telegram_api::userProfilePhoto::STRIPPED_THUMB_MASK; + profile_photo->stripped_thumb_ = BufferSlice(); + } + } + + old_photo = std::move(photo); + + drop_user_photos(user_id, new_photo_id == 0, "on_update_user_photo"); + auto user_full = get_user_full(user_id); // must not load UserFull + if (user_full != nullptr && new_photo_id != get_user_full_profile_photo_id(user_full)) { + // we didn't sent updateUser yet, so we must not sent updateUserFull with new_photo_id yet + drop_user_full_photos(user_full, user_id, 0, "on_update_user_photo"); + } + return; + } + if (u->is_received) { + auto new_photo_id = get_profile_photo_id(photo); + if (new_photo_id == u->photo.id) { + return; + } + } + } + + do_update_user_photo(u, user_id, std::move(photo), source); +} + +void UserManager::do_update_user_photo(User *u, UserId user_id, + telegram_api::object_ptr &&photo, + const char *source) { + ProfilePhoto new_photo = get_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, std::move(photo)); + if (td_->auth_manager_->is_bot()) { + new_photo.minithumbnail.clear(); + } + do_update_user_photo(u, user_id, std::move(new_photo), true, source); +} + +void UserManager::do_update_user_photo(User *u, UserId user_id, ProfilePhoto &&new_photo, bool invalidate_photo_cache, + const char *source) { + u->is_photo_inited = true; + if (need_update_profile_photo(u->photo, new_photo)) { + LOG_IF(ERROR, u->access_hash == -1 && new_photo.small_file_id.is_valid()) + << "Update profile photo of " << user_id << " without access hash from " << source; + u->photo = new_photo; + u->is_photo_changed = true; + LOG(DEBUG) << "Photo has changed for " << user_id << " to " << u->photo + << ", invalidate_photo_cache = " << invalidate_photo_cache << " from " << source; + u->is_changed = true; + + if (invalidate_photo_cache) { + drop_user_photos(user_id, u->photo.id == 0, source); + } + auto user_full = get_user_full(user_id); // must not load UserFull + if (user_full != nullptr && u->photo.id != get_user_full_profile_photo_id(user_full)) { + // we didn't sent updateUser yet, so we must not sent updateUserFull with u->photo.id yet + drop_user_full_photos(user_full, user_id, 0, "do_update_user_photo"); + } + } else if (need_update_dialog_photo_minithumbnail(u->photo.minithumbnail, new_photo.minithumbnail)) { + LOG(DEBUG) << "Photo minithumbnail has changed for " << user_id << " from " << source; + u->photo.minithumbnail = std::move(new_photo.minithumbnail); + u->is_photo_changed = true; + u->is_changed = true; + } +} + +void UserManager::register_suggested_profile_photo(const Photo &photo) { + auto photo_file_ids = photo_get_file_ids(photo); + if (photo.is_empty() || photo_file_ids.empty()) { + return; + } + auto first_file_id = photo_file_ids[0]; + auto file_type = td_->file_manager_->get_file_view(first_file_id).get_type(); + if (file_type == FileType::ProfilePhoto) { + return; + } + CHECK(file_type == FileType::Photo); + auto photo_id = photo.id.get(); + if (photo_id != 0) { + my_photo_file_id_[photo_id] = first_file_id; + } +} + +void UserManager::register_user_photo(User *u, UserId user_id, const Photo &photo) { + auto photo_file_ids = photo_get_file_ids(photo); + if (photo.is_empty() || photo_file_ids.empty()) { + return; + } + auto first_file_id = photo_file_ids[0]; + auto file_type = td_->file_manager_->get_file_view(first_file_id).get_type(); + if (file_type == FileType::ProfilePhoto) { + return; + } + CHECK(file_type == FileType::Photo); + CHECK(u != nullptr); + auto photo_id = photo.id.get(); + if (photo_id != 0 && u->photo_ids.emplace(photo_id).second) { + VLOG(file_references) << "Register photo " << photo_id << " of " << user_id; + if (user_id == get_my_id()) { + my_photo_file_id_[photo_id] = first_file_id; + } + auto file_source_id = user_profile_photo_file_source_ids_.get(std::make_pair(user_id, photo_id)); + if (file_source_id.is_valid()) { + VLOG(file_references) << "Move " << file_source_id << " inside of " << user_id; + user_profile_photo_file_source_ids_.erase(std::make_pair(user_id, photo_id)); + } else { + VLOG(file_references) << "Need to create new file source for photo " << photo_id << " of " << user_id; + file_source_id = td_->file_reference_manager_->create_user_photo_file_source(user_id, photo_id); + } + for (auto &file_id : photo_file_ids) { + td_->file_manager_->add_file_source(file_id, file_source_id); + } + } +} + +void UserManager::on_update_user_accent_color_id(User *u, UserId user_id, AccentColorId accent_color_id) { + if (accent_color_id == AccentColorId(user_id) || !accent_color_id.is_valid()) { + accent_color_id = AccentColorId(); + } + if (u->accent_color_id != accent_color_id) { + u->accent_color_id = accent_color_id; + u->is_accent_color_changed = true; + u->is_changed = true; + } +} + +void UserManager::on_update_user_background_custom_emoji_id(User *u, UserId user_id, + CustomEmojiId background_custom_emoji_id) { + if (u->background_custom_emoji_id != background_custom_emoji_id) { + u->background_custom_emoji_id = background_custom_emoji_id; + u->is_accent_color_changed = true; + u->is_changed = true; + } +} + +void UserManager::on_update_user_profile_accent_color_id(User *u, UserId user_id, AccentColorId accent_color_id) { + if (!accent_color_id.is_valid()) { + accent_color_id = AccentColorId(); + } + if (u->profile_accent_color_id != accent_color_id) { + u->profile_accent_color_id = accent_color_id; + u->is_accent_color_changed = true; + u->is_changed = true; + } +} + +void UserManager::on_update_user_profile_background_custom_emoji_id(User *u, UserId user_id, + CustomEmojiId background_custom_emoji_id) { + if (u->profile_background_custom_emoji_id != background_custom_emoji_id) { + u->profile_background_custom_emoji_id = background_custom_emoji_id; + u->is_accent_color_changed = true; + u->is_changed = true; + } +} + +void UserManager::on_update_user_emoji_status(UserId user_id, + telegram_api::object_ptr &&emoji_status) { + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + User *u = get_user_force(user_id, "on_update_user_emoji_status"); + if (u != nullptr) { + on_update_user_emoji_status(u, user_id, EmojiStatus(std::move(emoji_status))); + update_user(u, user_id); + } else { + LOG(INFO) << "Ignore update user emoji status about unknown " << user_id; + } +} + +void UserManager::on_update_user_emoji_status(User *u, UserId user_id, EmojiStatus emoji_status) { + if (u->emoji_status != emoji_status) { + LOG(DEBUG) << "Change emoji status of " << user_id << " from " << u->emoji_status << " to " << emoji_status; + u->emoji_status = std::move(emoji_status); + u->is_emoji_status_changed = true; + // effective emoji status might not be changed; checked in update_user + // u->is_changed = true; + } +} + +void UserManager::on_update_user_story_ids(UserId user_id, StoryId max_active_story_id, StoryId max_read_story_id) { + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + User *u = get_user_force(user_id, "on_update_user_story_ids"); + if (u != nullptr) { + on_update_user_story_ids_impl(u, user_id, max_active_story_id, max_read_story_id); + update_user(u, user_id); + } else { + LOG(INFO) << "Ignore update user story identifiers about unknown " << user_id; + } +} + +void UserManager::on_update_user_story_ids_impl(User *u, UserId user_id, StoryId max_active_story_id, + StoryId max_read_story_id) { + if (td_->auth_manager_->is_bot()) { + return; + } + if (max_active_story_id != StoryId() && !max_active_story_id.is_server()) { + LOG(ERROR) << "Receive max active " << max_active_story_id << " for " << user_id; + return; + } + if (max_read_story_id != StoryId() && !max_read_story_id.is_server()) { + LOG(ERROR) << "Receive max read " << max_read_story_id << " for " << user_id; + return; + } + + auto has_unread_stories = get_user_has_unread_stories(u); + if (u->max_active_story_id != max_active_story_id) { + LOG(DEBUG) << "Change last active story of " << user_id << " from " << u->max_active_story_id << " to " + << max_active_story_id; + u->max_active_story_id = max_active_story_id; + u->need_save_to_database = true; + } + if (need_poll_user_active_stories(u, user_id)) { + auto max_active_story_id_next_reload_time = Time::now() + MAX_ACTIVE_STORY_ID_RELOAD_TIME; + if (max_active_story_id_next_reload_time > + u->max_active_story_id_next_reload_time + MAX_ACTIVE_STORY_ID_RELOAD_TIME / 5) { + LOG(DEBUG) << "Change max_active_story_id_next_reload_time of " << user_id; + u->max_active_story_id_next_reload_time = max_active_story_id_next_reload_time; + u->need_save_to_database = true; + } + } + if (!max_active_story_id.is_valid()) { + CHECK(max_read_story_id == StoryId()); + if (u->max_read_story_id != StoryId()) { + LOG(DEBUG) << "Drop last read " << u->max_read_story_id << " of " << user_id; + u->max_read_story_id = StoryId(); + u->need_save_to_database = true; + } + } else if (max_read_story_id.get() > u->max_read_story_id.get()) { + LOG(DEBUG) << "Change last read story of " << user_id << " from " << u->max_read_story_id << " to " + << max_read_story_id; + u->max_read_story_id = max_read_story_id; + u->need_save_to_database = true; + } + if (has_unread_stories != get_user_has_unread_stories(u)) { + LOG(DEBUG) << "Change has_unread_stories of " << user_id << " to " << !has_unread_stories; + u->is_changed = true; + } +} + +void UserManager::on_update_user_max_read_story_id(UserId user_id, StoryId max_read_story_id) { + CHECK(user_id.is_valid()); + + User *u = get_user(user_id); + if (u != nullptr) { + on_update_user_max_read_story_id(u, user_id, max_read_story_id); + update_user(u, user_id); + } +} + +void UserManager::on_update_user_max_read_story_id(User *u, UserId user_id, StoryId max_read_story_id) { + if (td_->auth_manager_->is_bot() || !u->is_received) { + return; + } + + auto has_unread_stories = get_user_has_unread_stories(u); + if (max_read_story_id.get() > u->max_read_story_id.get()) { + LOG(DEBUG) << "Change last read story of " << user_id << " from " << u->max_read_story_id << " to " + << max_read_story_id; + u->max_read_story_id = max_read_story_id; + u->need_save_to_database = true; + } + if (has_unread_stories != get_user_has_unread_stories(u)) { + LOG(DEBUG) << "Change has_unread_stories of " << user_id << " to " << !has_unread_stories; + u->is_changed = true; + } +} + +void UserManager::on_update_user_stories_hidden(UserId user_id, bool stories_hidden) { + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + User *u = get_user_force(user_id, "on_update_user_stories_hidden"); + if (u != nullptr) { + on_update_user_stories_hidden(u, user_id, stories_hidden); + update_user(u, user_id); + } else { + LOG(INFO) << "Ignore update user stories are archived about unknown " << user_id; + } +} + +void UserManager::on_update_user_stories_hidden(User *u, UserId user_id, bool stories_hidden) { + if (td_->auth_manager_->is_bot()) { + return; + } + + if (u->stories_hidden != stories_hidden) { + LOG(DEBUG) << "Change stories are archived of " << user_id << " to " << stories_hidden; + u->stories_hidden = stories_hidden; + u->is_stories_hidden_changed = true; + u->need_save_to_database = true; + } +} + +void UserManager::on_update_user_is_contact(User *u, UserId user_id, bool is_contact, bool is_mutual_contact, + bool is_close_friend) { + if (td_->auth_manager_->is_bot()) { + return; + } + + UserId my_id = get_my_id(); + if (user_id == my_id) { + is_mutual_contact = is_contact; + is_close_friend = false; + } + if (!is_contact && (is_mutual_contact || is_close_friend)) { + LOG(ERROR) << "Receive is_mutual_contact = " << is_mutual_contact << ", and is_close_friend = " << is_close_friend + << " for non-contact " << user_id; + is_mutual_contact = false; + is_close_friend = false; + } + + if (u->is_contact != is_contact || u->is_mutual_contact != is_mutual_contact || + u->is_close_friend != is_close_friend) { + LOG(DEBUG) << "Update " << user_id << " is_contact from (" << u->is_contact << ", " << u->is_mutual_contact << ", " + << u->is_close_friend << ") to (" << is_contact << ", " << is_mutual_contact << ", " << is_close_friend + << ")"; + if (u->is_contact != is_contact) { + u->is_contact = is_contact; + u->is_is_contact_changed = true; + } + if (u->is_mutual_contact != is_mutual_contact) { + u->is_mutual_contact = is_mutual_contact; + u->is_is_mutual_contact_changed = true; + + reload_contact_birthdates(true); + } + u->is_close_friend = is_close_friend; + u->is_changed = true; + } +} + +void UserManager::on_update_user_online(UserId user_id, telegram_api::object_ptr &&status) { + if (td_->auth_manager_->is_bot()) { + return; + } + + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + User *u = get_user_force(user_id, "on_update_user_online"); + if (u != nullptr) { + if (u->is_bot) { + LOG(ERROR) << "Receive updateUserStatus about bot " << user_id; + return; + } + on_update_user_online(u, user_id, std::move(status)); + update_user(u, user_id); + + if (user_id == get_my_id() && + was_online_remote_ != u->was_online) { // only update was_online_remote_ from updateUserStatus + was_online_remote_ = u->was_online; + VLOG(notifications) << "Set was_online_remote to " << was_online_remote_; + G()->td_db()->get_binlog_pmc()->set("my_was_online_remote", to_string(was_online_remote_)); + } + } else { + LOG(INFO) << "Ignore update user online about unknown " << user_id; + } +} + +void UserManager::on_update_user_online(User *u, UserId user_id, + telegram_api::object_ptr &&status) { + if (td_->auth_manager_->is_bot()) { + return; + } + + int32 id = status == nullptr ? telegram_api::userStatusEmpty::ID : status->get_id(); + int32 new_online; + bool is_offline = false; + if (id == telegram_api::userStatusOnline::ID) { + int32 now = G()->unix_time(); + + auto st = move_tl_object_as(status); + new_online = st->expires_; + LOG_IF(ERROR, new_online < now - 86400) + << "Receive userStatusOnline expired more than one day in past " << new_online; + } else if (id == telegram_api::userStatusOffline::ID) { + int32 now = G()->unix_time(); + + auto st = move_tl_object_as(status); + new_online = st->was_online_; + if (new_online >= now) { + LOG_IF(ERROR, new_online > now + 10) + << "Receive userStatusOffline but was online points to future time " << new_online << ", now is " << now; + new_online = now - 1; + } + is_offline = true; + } else if (id == telegram_api::userStatusRecently::ID) { + auto st = telegram_api::move_object_as(status); + new_online = st->by_me_ ? -4 : -1; + } else if (id == telegram_api::userStatusLastWeek::ID) { + auto st = telegram_api::move_object_as(status); + new_online = st->by_me_ ? -5 : -2; + } else if (id == telegram_api::userStatusLastMonth::ID) { + auto st = telegram_api::move_object_as(status); + new_online = st->by_me_ ? -6 : -3; + } else { + CHECK(id == telegram_api::userStatusEmpty::ID); + new_online = 0; + } + + if (new_online != u->was_online && !(new_online < 0 && user_id == get_my_id())) { + LOG(DEBUG) << "Update " << user_id << " online from " << u->was_online << " to " << new_online; + auto unix_time = G()->unix_time(); + bool old_is_online = u->was_online > unix_time; + bool new_is_online = new_online > unix_time; + u->was_online = new_online; + u->is_status_changed = true; + if (u->was_online > 0) { + u->local_was_online = 0; + } + + if (user_id == get_my_id()) { + if (my_was_online_local_ != 0 || old_is_online != new_is_online) { + my_was_online_local_ = 0; + u->is_online_status_changed = true; + } + if (is_offline) { + td_->online_manager_->on_online_updated(false, false); + } + } else if (old_is_online != new_is_online) { + u->is_online_status_changed = true; + } + } +} + +void UserManager::on_update_user_local_was_online(UserId user_id, int32 local_was_online) { + CHECK(user_id.is_valid()); + if (td_->auth_manager_->is_bot()) { + return; + } + + User *u = get_user_force(user_id, "on_update_user_local_was_online"); + if (u == nullptr) { + return; + } + + on_update_user_local_was_online(u, user_id, local_was_online); + update_user(u, user_id); +} + +void UserManager::on_update_user_local_was_online(User *u, UserId user_id, int32 local_was_online) { + CHECK(u != nullptr); + if (u->is_deleted || u->is_bot || u->is_support || user_id == get_my_id()) { + return; + } + int32 unix_time = G()->unix_time(); + if (u->was_online > unix_time) { + // if user is currently online, ignore local online + return; + } + + // bring users online for 30 seconds + local_was_online += 30; + if (local_was_online < unix_time + 2 || local_was_online <= u->local_was_online || + local_was_online <= u->was_online) { + return; + } + + LOG(DEBUG) << "Update " << user_id << " local online from " << u->local_was_online << " to " << local_was_online; + bool old_is_online = u->local_was_online > unix_time; + u->local_was_online = local_was_online; + u->is_status_changed = true; + + if (!old_is_online) { + u->is_online_status_changed = true; + } +} + +void UserManager::on_update_user_is_blocked(UserId user_id, bool is_blocked, bool is_blocked_for_stories) { + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + UserFull *user_full = get_user_full_force(user_id, "on_update_user_is_blocked"); + if (user_full == nullptr) { + return; + } + on_update_user_full_is_blocked(user_full, user_id, is_blocked, is_blocked_for_stories); + update_user_full(user_full, user_id, "on_update_user_is_blocked"); +} + +void UserManager::on_update_user_full_is_blocked(UserFull *user_full, UserId user_id, bool is_blocked, + bool is_blocked_for_stories) { + CHECK(user_full != nullptr); + if (user_full->is_blocked != is_blocked || user_full->is_blocked_for_stories != is_blocked_for_stories) { + LOG(INFO) << "Receive update user full is blocked with " << user_id << " and is_blocked = " << is_blocked << '/' + << is_blocked_for_stories; + user_full->is_blocked = is_blocked; + user_full->is_blocked_for_stories = is_blocked_for_stories; + user_full->is_changed = true; + } +} + +void UserManager::on_update_user_has_pinned_stories(UserId user_id, bool has_pinned_stories) { + if (td_->auth_manager_->is_bot()) { + return; + } + + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + UserFull *user_full = get_user_full_force(user_id, "on_update_user_has_pinned_stories"); + if (user_full == nullptr || user_full->has_pinned_stories == has_pinned_stories) { + return; + } + user_full->has_pinned_stories = has_pinned_stories; + user_full->is_changed = true; + update_user_full(user_full, user_id, "on_update_user_has_pinned_stories"); +} + +void UserManager::on_update_user_common_chat_count(UserId user_id, int32 common_chat_count) { + LOG(INFO) << "Receive " << common_chat_count << " common chat count with " << user_id; + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + UserFull *user_full = get_user_full_force(user_id, "on_update_user_common_chat_count"); + if (user_full == nullptr) { + return; + } + on_update_user_full_common_chat_count(user_full, user_id, common_chat_count); + update_user_full(user_full, user_id, "on_update_user_common_chat_count"); +} + +void UserManager::on_update_user_full_common_chat_count(UserFull *user_full, UserId user_id, int32 common_chat_count) { + CHECK(user_full != nullptr); + if (common_chat_count < 0) { + LOG(ERROR) << "Receive " << common_chat_count << " as common group count with " << user_id; + common_chat_count = 0; + } + if (user_full->common_chat_count != common_chat_count) { + user_full->common_chat_count = common_chat_count; + user_full->is_common_chat_count_changed = true; + user_full->is_changed = true; + } +} + +void UserManager::on_update_my_user_location(DialogLocation &&location) { + auto user_id = get_my_id(); + UserFull *user_full = get_user_full_force(user_id, "on_update_user_location"); + if (user_full == nullptr) { + return; + } + on_update_user_full_location(user_full, user_id, std::move(location)); + update_user_full(user_full, user_id, "on_update_user_location"); +} + +void UserManager::on_update_user_full_location(UserFull *user_full, UserId user_id, DialogLocation &&location) { + CHECK(user_full != nullptr); + if (BusinessInfo::set_location(user_full->business_info, std::move(location))) { + user_full->is_changed = true; + } +} + +void UserManager::on_update_my_user_work_hours(BusinessWorkHours &&work_hours) { + auto user_id = get_my_id(); + UserFull *user_full = get_user_full_force(user_id, "on_update_user_work_hours"); + if (user_full == nullptr) { + return; + } + on_update_user_full_work_hours(user_full, user_id, std::move(work_hours)); + update_user_full(user_full, user_id, "on_update_user_work_hours"); +} + +void UserManager::on_update_user_full_work_hours(UserFull *user_full, UserId user_id, BusinessWorkHours &&work_hours) { + CHECK(user_full != nullptr); + if (BusinessInfo::set_work_hours(user_full->business_info, std::move(work_hours))) { + user_full->is_changed = true; + } +} + +void UserManager::on_update_my_user_away_message(BusinessAwayMessage &&away_message) { + auto user_id = get_my_id(); + UserFull *user_full = get_user_full_force(user_id, "on_update_user_away_message"); + if (user_full == nullptr) { + return; + } + on_update_user_full_away_message(user_full, user_id, std::move(away_message)); + update_user_full(user_full, user_id, "on_update_user_away_message"); +} + +void UserManager::on_update_user_full_away_message(UserFull *user_full, UserId user_id, + BusinessAwayMessage &&away_message) const { + CHECK(user_full != nullptr); + if (away_message.is_valid() && user_id != get_my_id()) { + LOG(ERROR) << "Receive " << away_message << " for " << user_id; + return; + } + if (BusinessInfo::set_away_message(user_full->business_info, std::move(away_message))) { + user_full->is_changed = true; + } +} + +void UserManager::on_update_my_user_greeting_message(BusinessGreetingMessage &&greeting_message) { + auto user_id = get_my_id(); + UserFull *user_full = get_user_full_force(user_id, "on_update_user_greeting_message"); + if (user_full == nullptr) { + return; + } + on_update_user_full_greeting_message(user_full, user_id, std::move(greeting_message)); + update_user_full(user_full, user_id, "on_update_user_greeting_message"); +} + +void UserManager::on_update_user_full_greeting_message(UserFull *user_full, UserId user_id, + BusinessGreetingMessage &&greeting_message) const { + CHECK(user_full != nullptr); + if (greeting_message.is_valid() && user_id != get_my_id()) { + LOG(ERROR) << "Receive " << greeting_message << " for " << user_id; + return; + } + if (BusinessInfo::set_greeting_message(user_full->business_info, std::move(greeting_message))) { + user_full->is_changed = true; + } +} + +void UserManager::on_update_my_user_intro(BusinessIntro &&intro) { + auto user_id = get_my_id(); + UserFull *user_full = get_user_full_force(user_id, "on_update_user_intro"); + if (user_full == nullptr) { + return; + } + on_update_user_full_intro(user_full, user_id, std::move(intro)); + update_user_full(user_full, user_id, "on_update_user_intro"); +} + +void UserManager::on_update_user_full_intro(UserFull *user_full, UserId user_id, BusinessIntro &&intro) { + CHECK(user_full != nullptr); + if (BusinessInfo::set_intro(user_full->business_info, std::move(intro))) { + user_full->is_changed = true; + } +} + +void UserManager::on_update_user_commands(UserId user_id, + vector> &&bot_commands) { + UserFull *user_full = get_user_full_force(user_id, "on_update_user_commands"); + if (user_full != nullptr) { + on_update_user_full_commands(user_full, user_id, std::move(bot_commands)); + update_user_full(user_full, user_id, "on_update_user_commands"); + } +} + +void UserManager::on_update_user_full_commands( + UserFull *user_full, UserId user_id, vector> &&bot_commands) { + CHECK(user_full != nullptr); + auto commands = + transform(std::move(bot_commands), [](telegram_api::object_ptr &&bot_command) { + return BotCommand(std::move(bot_command)); + }); + if (user_full->commands != commands) { + user_full->commands = std::move(commands); + user_full->is_changed = true; + } +} + +void UserManager::on_update_user_need_phone_number_privacy_exception(UserId user_id, + bool need_phone_number_privacy_exception) { + LOG(INFO) << "Receive " << need_phone_number_privacy_exception << " need phone number privacy exception with " + << user_id; + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + UserFull *user_full = get_user_full_force(user_id, "on_update_user_need_phone_number_privacy_exception"); + if (user_full == nullptr) { + return; + } + on_update_user_full_need_phone_number_privacy_exception(user_full, user_id, need_phone_number_privacy_exception); + update_user_full(user_full, user_id, "on_update_user_need_phone_number_privacy_exception"); +} + +void UserManager::on_update_user_full_need_phone_number_privacy_exception( + UserFull *user_full, UserId user_id, bool need_phone_number_privacy_exception) const { + CHECK(user_full != nullptr); + if (need_phone_number_privacy_exception) { + const User *u = get_user(user_id); + if (u == nullptr || u->is_contact || user_id == get_my_id()) { + need_phone_number_privacy_exception = false; + } + } + if (user_full->need_phone_number_privacy_exception != need_phone_number_privacy_exception) { + user_full->need_phone_number_privacy_exception = need_phone_number_privacy_exception; + user_full->is_changed = true; + } +} + +void UserManager::on_update_user_wallpaper_overridden(UserId user_id, bool wallpaper_overridden) { + LOG(INFO) << "Receive " << wallpaper_overridden << " set chat background for " << user_id; + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + return; + } + + UserFull *user_full = get_user_full_force(user_id, "on_update_user_wallpaper_overridden"); + if (user_full == nullptr) { + return; + } + on_update_user_full_wallpaper_overridden(user_full, user_id, wallpaper_overridden); + update_user_full(user_full, user_id, "on_update_user_wallpaper_overridden"); +} + +void UserManager::on_update_user_full_wallpaper_overridden(UserFull *user_full, UserId user_id, + bool wallpaper_overridden) const { + CHECK(user_full != nullptr); + if (user_full->wallpaper_overridden != wallpaper_overridden) { + user_full->wallpaper_overridden = wallpaper_overridden; + user_full->is_changed = true; + } +} + +void UserManager::on_update_bot_menu_button(UserId bot_user_id, + telegram_api::object_ptr &&bot_menu_button) { + if (!bot_user_id.is_valid()) { + LOG(ERROR) << "Receive updateBotMenuButton about invalid " << bot_user_id; + return; + } + if (!have_user_force(bot_user_id, "on_update_bot_menu_button") || !is_user_bot(bot_user_id)) { + return; + } + if (td_->auth_manager_->is_bot()) { + return; + } + + auto user_full = get_user_full_force(bot_user_id, "on_update_bot_menu_button"); + if (user_full != nullptr) { + on_update_user_full_menu_button(user_full, bot_user_id, std::move(bot_menu_button)); + update_user_full(user_full, bot_user_id, "on_update_bot_menu_button"); + } +} + +void UserManager::on_update_user_full_menu_button( + UserFull *user_full, UserId user_id, telegram_api::object_ptr &&bot_menu_button) { + CHECK(user_full != nullptr); + auto new_button = get_bot_menu_button(std::move(bot_menu_button)); + bool is_changed; + if (user_full->menu_button == nullptr) { + is_changed = (new_button != nullptr); + } else { + is_changed = (new_button == nullptr || *user_full->menu_button != *new_button); + } + if (is_changed) { + user_full->menu_button = std::move(new_button); + user_full->is_changed = true; + } +} + +void UserManager::on_update_bot_has_preview_medias(UserId bot_user_id, bool has_preview_medias) { + if (!bot_user_id.is_valid()) { + LOG(ERROR) << "Receive updateBotHasPreviewMedias about invalid " << bot_user_id; + return; + } + if (!have_user_force(bot_user_id, "on_update_bot_has_preview_medias") || !is_user_bot(bot_user_id)) { + return; + } + if (td_->auth_manager_->is_bot()) { + return; + } + + auto user_full = get_user_full_force(bot_user_id, "on_update_bot_has_preview_medias"); + if (user_full != nullptr) { + on_update_user_full_has_preview_medias(user_full, bot_user_id, has_preview_medias); + update_user_full(user_full, bot_user_id, "on_update_bot_has_preview_medias"); + } +} + +void UserManager::on_update_user_full_has_preview_medias(UserFull *user_full, UserId user_id, bool has_preview_medias) { + CHECK(user_full != nullptr); + if (user_full->has_preview_medias != has_preview_medias) { + user_full->has_preview_medias = has_preview_medias; + user_full->is_changed = true; + } +} + +void UserManager::on_update_secret_chat(SecretChatId secret_chat_id, int64 access_hash, UserId user_id, + SecretChatState state, bool is_outbound, int32 ttl, int32 date, string key_hash, + int32 layer, FolderId initial_folder_id) { + LOG(INFO) << "Update " << secret_chat_id << " with " << user_id << " and access_hash " << access_hash; + auto *secret_chat = add_secret_chat(secret_chat_id); + if (access_hash != secret_chat->access_hash) { + secret_chat->access_hash = access_hash; + secret_chat->need_save_to_database = true; + } + if (user_id.is_valid() && user_id != secret_chat->user_id) { + if (secret_chat->user_id.is_valid()) { + LOG(ERROR) << "Secret chat user has changed from " << secret_chat->user_id << " to " << user_id; + auto &old_secret_chat_ids = secret_chats_with_user_[secret_chat->user_id]; + td::remove(old_secret_chat_ids, secret_chat_id); + } + secret_chat->user_id = user_id; + secret_chats_with_user_[secret_chat->user_id].push_back(secret_chat_id); + secret_chat->is_changed = true; + } + if (state != SecretChatState::Unknown && state != secret_chat->state) { + secret_chat->state = state; + secret_chat->is_changed = true; + secret_chat->is_state_changed = true; + } + if (is_outbound != secret_chat->is_outbound) { + secret_chat->is_outbound = is_outbound; + secret_chat->is_changed = true; + } + + if (ttl != -1 && ttl != secret_chat->ttl) { + secret_chat->ttl = ttl; + secret_chat->need_save_to_database = true; + secret_chat->is_ttl_changed = true; + } + if (date != 0 && date != secret_chat->date) { + secret_chat->date = date; + secret_chat->need_save_to_database = true; + } + if (!key_hash.empty() && key_hash != secret_chat->key_hash) { + secret_chat->key_hash = std::move(key_hash); + secret_chat->is_changed = true; + } + if (layer != 0 && layer != secret_chat->layer) { + secret_chat->layer = layer; + secret_chat->is_changed = true; + } + if (initial_folder_id != FolderId() && initial_folder_id != secret_chat->initial_folder_id) { + secret_chat->initial_folder_id = initial_folder_id; + secret_chat->is_changed = true; + } + + update_secret_chat(secret_chat, secret_chat_id); +} + +void UserManager::on_update_online_status_privacy() { + td_->create_handler()->send(); +} + +void UserManager::on_update_phone_number_privacy() { + // all UserFull.need_phone_number_privacy_exception can be outdated now, + // so mark all of them as expired + users_full_.foreach([&](const UserId &user_id, unique_ptr &user_full) { user_full->expires_at = 0.0; }); +} + +void UserManager::on_ignored_restriction_reasons_changed() { + restricted_user_ids_.foreach([&](const UserId &user_id) { + send_closure(G()->td(), &Td::send_update, get_update_user_object(user_id, get_user(user_id))); + }); +} + +void UserManager::invalidate_user_full(UserId user_id) { + auto user_full = get_user_full_force(user_id, "invalidate_user_full"); + if (user_full != nullptr) { + td_->dialog_manager_->on_dialog_info_full_invalidated(DialogId(user_id)); + + if (!user_full->is_expired()) { + user_full->expires_at = 0.0; + user_full->need_save_to_database = true; + + update_user_full(user_full, user_id, "invalidate_user_full"); + } + } +} + +bool UserManager::have_user(UserId user_id) const { + auto u = get_user(user_id); + return u != nullptr && u->is_received; +} + +bool UserManager::have_min_user(UserId user_id) const { + return users_.count(user_id) > 0; +} + +const UserManager::User *UserManager::get_user(UserId user_id) const { + return users_.get_pointer(user_id); +} + +UserManager::User *UserManager::get_user(UserId user_id) { + return users_.get_pointer(user_id); +} + +UserManager::User *UserManager::add_user(UserId user_id) { + CHECK(user_id.is_valid()); + auto &user_ptr = users_[user_id]; + if (user_ptr == nullptr) { + user_ptr = make_unique(); + } + return user_ptr.get(); +} + +void UserManager::save_user(User *u, UserId user_id, bool from_binlog) { + if (!G()->use_chat_info_database()) { + return; + } + CHECK(u != nullptr); + if (!u->is_saved || !u->is_status_saved) { // TODO more effective handling of !u->is_status_saved + if (!from_binlog) { + auto log_event = UserLogEvent(user_id, u); + auto storer = get_log_event_storer(log_event); + if (u->log_event_id == 0) { + u->log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::Users, storer); + } else { + binlog_rewrite(G()->td_db()->get_binlog(), u->log_event_id, LogEvent::HandlerType::Users, storer); + } + } + + save_user_to_database(u, user_id); + } +} + +string UserManager::get_user_database_key(UserId user_id) { + return PSTRING() << "us" << user_id.get(); +} + +string UserManager::get_user_database_value(const User *u) { + return log_event_store(*u).as_slice().str(); +} + +void UserManager::save_user_to_database(User *u, UserId user_id) { + CHECK(u != nullptr); + if (u->is_being_saved) { + return; + } + if (loaded_from_database_users_.count(user_id)) { + save_user_to_database_impl(u, user_id, get_user_database_value(u)); + return; + } + if (load_user_from_database_queries_.count(user_id) != 0) { + return; + } + + load_user_from_database_impl(user_id, Auto()); +} + +void UserManager::save_user_to_database_impl(User *u, UserId user_id, string value) { + CHECK(u != nullptr); + CHECK(load_user_from_database_queries_.count(user_id) == 0); + CHECK(!u->is_being_saved); + u->is_being_saved = true; + u->is_saved = true; + u->is_status_saved = true; + LOG(INFO) << "Trying to save to database " << user_id; + G()->td_db()->get_sqlite_pmc()->set( + get_user_database_key(user_id), std::move(value), PromiseCreator::lambda([user_id](Result<> result) { + send_closure(G()->user_manager(), &UserManager::on_save_user_to_database, user_id, result.is_ok()); + })); +} + +void UserManager::on_save_user_to_database(UserId user_id, bool success) { + if (G()->close_flag()) { + return; + } + + User *u = get_user(user_id); + CHECK(u != nullptr); + LOG_CHECK(u->is_being_saved) << success << ' ' << user_id << ' ' << u->is_saved << ' ' << u->is_status_saved << ' ' + << load_user_from_database_queries_.count(user_id) << ' ' << u->is_received << ' ' + << u->is_deleted << ' ' << u->is_bot << ' ' << u->need_save_to_database << ' ' + << u->is_changed << ' ' << u->is_status_changed << ' ' << u->is_name_changed << ' ' + << u->is_username_changed << ' ' << u->is_photo_changed << ' ' + << u->is_is_contact_changed << ' ' << u->is_is_deleted_changed << ' ' + << u->is_stories_hidden_changed << ' ' << u->log_event_id; + CHECK(load_user_from_database_queries_.count(user_id) == 0); + u->is_being_saved = false; + + if (!success) { + LOG(ERROR) << "Failed to save " << user_id << " to database"; + u->is_saved = false; + u->is_status_saved = false; + } else { + LOG(INFO) << "Successfully saved " << user_id << " to database"; + } + if (u->is_saved && u->is_status_saved) { + if (u->log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), u->log_event_id); + u->log_event_id = 0; + } + } else { + save_user(u, user_id, u->log_event_id != 0); + } +} + +void UserManager::load_user_from_database(User *u, UserId user_id, Promise promise) { + if (loaded_from_database_users_.count(user_id)) { + promise.set_value(Unit()); + return; + } + + CHECK(u == nullptr || !u->is_being_saved); + load_user_from_database_impl(user_id, std::move(promise)); +} + +void UserManager::load_user_from_database_impl(UserId user_id, Promise promise) { + LOG(INFO) << "Load " << user_id << " from database"; + auto &load_user_queries = load_user_from_database_queries_[user_id]; + load_user_queries.push_back(std::move(promise)); + if (load_user_queries.size() == 1u) { + G()->td_db()->get_sqlite_pmc()->get(get_user_database_key(user_id), PromiseCreator::lambda([user_id](string value) { + send_closure(G()->user_manager(), &UserManager::on_load_user_from_database, + user_id, std::move(value), false); + })); + } +} + +void UserManager::on_load_user_from_database(UserId user_id, string value, bool force) { + if (G()->close_flag() && !force) { + // the user is in Binlog and will be saved after restart + return; + } + + CHECK(user_id.is_valid()); + if (!loaded_from_database_users_.insert(user_id).second) { + return; + } + + auto it = load_user_from_database_queries_.find(user_id); + vector> promises; + if (it != load_user_from_database_queries_.end()) { + promises = std::move(it->second); + CHECK(!promises.empty()); + load_user_from_database_queries_.erase(it); + } + + LOG(INFO) << "Successfully loaded " << user_id << " of size " << value.size() << " from database"; + // G()->td_db()->get_sqlite_pmc()->erase(get_user_database_key(user_id), Auto()); + // return; + + User *u = get_user(user_id); + if (u == nullptr) { + if (!value.empty()) { + u = add_user(user_id); + + if (log_event_parse(*u, value).is_error()) { + LOG(ERROR) << "Failed to load " << user_id << " from database"; + users_.erase(user_id); + } else { + u->is_saved = true; + u->is_status_saved = true; + update_user(u, user_id, true, true); + } + } + } else { + CHECK(!u->is_saved); // user can't be saved before load completes + CHECK(!u->is_being_saved); + auto new_value = get_user_database_value(u); + if (value != new_value) { + save_user_to_database_impl(u, user_id, std::move(new_value)); + } else if (u->log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), u->log_event_id); + u->log_event_id = 0; + } + } + + set_promises(promises); +} + +bool UserManager::have_user_force(UserId user_id, const char *source) { + return get_user_force(user_id, source) != nullptr; +} + +UserManager::User *UserManager::get_user_force(UserId user_id, const char *source) { + auto u = get_user_force_impl(user_id, source); + if ((u == nullptr || !u->is_received) && + (user_id == get_service_notifications_user_id() || user_id == get_replies_bot_user_id() || + user_id == get_anonymous_bot_user_id() || user_id == get_channel_bot_user_id() || + user_id == get_anti_spam_bot_user_id())) { + int32 flags = USER_FLAG_HAS_ACCESS_HASH | USER_FLAG_HAS_FIRST_NAME | USER_FLAG_NEED_APPLY_MIN_PHOTO; + int64 profile_photo_id = 0; + int32 profile_photo_dc_id = 1; + string first_name; + string last_name; + string username; + string phone_number; + int32 bot_info_version = 0; + + if (user_id == get_service_notifications_user_id()) { + flags |= USER_FLAG_HAS_PHONE_NUMBER | USER_FLAG_IS_VERIFIED | USER_FLAG_IS_SUPPORT; + first_name = "Telegram"; + if (G()->is_test_dc()) { + flags |= USER_FLAG_HAS_LAST_NAME; + last_name = "Notifications"; + } + phone_number = "42777"; + profile_photo_id = 3337190045231023; + } else if (user_id == get_replies_bot_user_id()) { + flags |= USER_FLAG_HAS_USERNAME | USER_FLAG_IS_BOT; + if (!G()->is_test_dc()) { + flags |= USER_FLAG_IS_PRIVATE_BOT; + } + first_name = "Replies"; + username = "replies"; + bot_info_version = G()->is_test_dc() ? 1 : 3; + } else if (user_id == get_anonymous_bot_user_id()) { + flags |= USER_FLAG_HAS_USERNAME | USER_FLAG_IS_BOT; + if (!G()->is_test_dc()) { + flags |= USER_FLAG_IS_PRIVATE_BOT; + } + first_name = "Group"; + username = G()->is_test_dc() ? "izgroupbot" : "GroupAnonymousBot"; + bot_info_version = G()->is_test_dc() ? 1 : 3; + profile_photo_id = 5159307831025969322; + } else if (user_id == get_channel_bot_user_id()) { + flags |= USER_FLAG_HAS_USERNAME | USER_FLAG_IS_BOT; + if (!G()->is_test_dc()) { + flags |= USER_FLAG_IS_PRIVATE_BOT; + } + first_name = G()->is_test_dc() ? "Channels" : "Channel"; + username = G()->is_test_dc() ? "channelsbot" : "Channel_Bot"; + bot_info_version = G()->is_test_dc() ? 1 : 4; + profile_photo_id = 587627495930570665; + } else if (user_id == get_service_notifications_user_id()) { + flags |= USER_FLAG_HAS_USERNAME | USER_FLAG_IS_BOT; + if (G()->is_test_dc()) { + first_name = "antispambot"; + username = "tantispambot"; + } else { + flags |= USER_FLAG_IS_VERIFIED; + first_name = "Telegram Anti-Spam"; + username = "tgsantispambot"; + profile_photo_id = 5170408289966598902; + } + } + + telegram_api::object_ptr profile_photo; + if (!G()->is_test_dc() && profile_photo_id != 0) { + profile_photo = telegram_api::make_object(0, false, false, profile_photo_id, + BufferSlice(), profile_photo_dc_id); + } + + auto user = telegram_api::make_object( + flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, 0, false /*ignored*/, false /*ignored*/, + false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, false /*ignored*/, user_id.get(), 1, + first_name, string(), username, phone_number, std::move(profile_photo), nullptr, bot_info_version, Auto(), + string(), string(), nullptr, vector>(), 0, nullptr, nullptr, + 0); + on_get_user(std::move(user), "get_user_force"); + u = get_user(user_id); + CHECK(u != nullptr && u->is_received); + + reload_user(user_id, Promise(), "get_user_force"); + } + return u; +} + +UserManager::User *UserManager::get_user_force_impl(UserId user_id, const char *source) { + if (!user_id.is_valid()) { + return nullptr; + } + + User *u = get_user(user_id); + if (u != nullptr) { + return u; + } + if (!G()->use_chat_info_database()) { + return nullptr; + } + if (loaded_from_database_users_.count(user_id)) { + return nullptr; + } + + LOG(INFO) << "Trying to load " << user_id << " from database from " << source; + on_load_user_from_database(user_id, G()->td_db()->get_sqlite_sync_pmc()->get(get_user_database_key(user_id)), true); + return get_user(user_id); +} + +void UserManager::send_get_me_query(Td *td, Promise &&promise) { + vector> users; + users.push_back(telegram_api::make_object()); + td->create_handler(std::move(promise))->send(std::move(users)); +} + +UserId UserManager::get_me(Promise &&promise) { + auto my_id = get_my_id(); + if (!have_user_force(my_id, "get_me")) { + get_user_queries_.add_query(my_id.get(), std::move(promise), "get_me"); + return UserId(); + } + + promise.set_value(Unit()); + return my_id; +} + +bool UserManager::get_user(UserId user_id, int left_tries, Promise &&promise) { + if (!user_id.is_valid()) { + promise.set_error(Status::Error(400, "Invalid user identifier")); + return false; + } + + if (user_id == get_service_notifications_user_id() || user_id == get_replies_bot_user_id() || + user_id == get_anonymous_bot_user_id() || user_id == get_channel_bot_user_id() || + user_id == get_anti_spam_bot_user_id()) { + get_user_force(user_id, "get_user"); + } + + if (td_->auth_manager_->is_bot() ? !have_user(user_id) : !have_min_user(user_id)) { + if (left_tries > 2 && G()->use_chat_info_database()) { + send_closure_later(actor_id(this), &UserManager::load_user_from_database, nullptr, user_id, std::move(promise)); + return false; + } + auto r_input_user = get_input_user(user_id); + if (left_tries == 1 || r_input_user.is_error()) { + if (r_input_user.is_error()) { + promise.set_error(r_input_user.move_as_error()); + } else { + promise.set_error(Status::Error(400, "User not found")); + } + return false; + } + + get_user_queries_.add_query(user_id.get(), std::move(promise), "get_user"); + return false; + } + + promise.set_value(Unit()); + return true; +} + +void UserManager::reload_user(UserId user_id, Promise &&promise, const char *source) { + if (!user_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid user identifier")); + } + + have_user_force(user_id, source); + + TRY_STATUS_PROMISE(promise, get_input_user(user_id)); + + get_user_queries_.add_query(user_id.get(), std::move(promise), source); +} + +Result> UserManager::get_input_user(UserId user_id) const { + if (user_id == get_my_id()) { + return telegram_api::make_object(); + } + + const User *u = get_user(user_id); + if (u == nullptr || u->access_hash == -1 || u->is_min_access_hash) { + if (td_->auth_manager_->is_bot() && user_id.is_valid()) { + return telegram_api::make_object(user_id.get(), 0); + } + auto it = user_messages_.find(user_id); + if (it != user_messages_.end()) { + CHECK(!it->second.empty()); + auto message_full_id = *it->second.begin(); + return telegram_api::make_object( + td_->chat_manager_->get_simple_input_peer(message_full_id.get_dialog_id()), + message_full_id.get_message_id().get_server_message_id().get(), user_id.get()); + } + if (u == nullptr) { + return Status::Error(400, "User not found"); + } else { + return Status::Error(400, "Have no access to the user"); + } + } + + return telegram_api::make_object(user_id.get(), u->access_hash); +} + +telegram_api::object_ptr UserManager::get_input_user_force(UserId user_id) const { + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_error()) { + CHECK(user_id.is_valid()); + return telegram_api::make_object(user_id.get(), 0); + } + return r_input_user.move_as_ok(); +} + +bool UserManager::have_input_peer_user(UserId user_id, AccessRights access_rights) const { + if (user_id == get_my_id()) { + return true; + } + return have_input_peer_user(get_user(user_id), user_id, access_rights); +} + +bool UserManager::have_input_peer_user(const User *u, UserId user_id, AccessRights access_rights) const { + if (u == nullptr || u->access_hash == -1 || u->is_min_access_hash) { + if (u == nullptr) { + LOG(DEBUG) << "Have no user"; + } else { + LOG(DEBUG) << "Have user without access hash"; + } + if (td_->auth_manager_->is_bot() && user_id.is_valid()) { + return true; + } + if (user_messages_.count(user_id) != 0) { + return true; + } + return false; + } + if (access_rights == AccessRights::Know) { + return true; + } + if (access_rights == AccessRights::Read) { + return true; + } + if (u->is_deleted) { + LOG(DEBUG) << "Have a deleted user"; + return false; + } + return true; +} + +telegram_api::object_ptr UserManager::get_input_peer_user(UserId user_id, + AccessRights access_rights) const { + if (user_id == get_my_id()) { + return telegram_api::make_object(); + } + const User *u = get_user(user_id); + if (!have_input_peer_user(u, user_id, access_rights)) { + return nullptr; + } + if (u == nullptr || u->access_hash == -1 || u->is_min_access_hash) { + if (td_->auth_manager_->is_bot() && user_id.is_valid()) { + return telegram_api::make_object(user_id.get(), 0); + } + auto it = user_messages_.find(user_id); + CHECK(it != user_messages_.end()); + CHECK(!it->second.empty()); + auto message_full_id = *it->second.begin(); + return telegram_api::make_object( + td_->chat_manager_->get_simple_input_peer(message_full_id.get_dialog_id()), + message_full_id.get_message_id().get_server_message_id().get(), user_id.get()); + } + + return telegram_api::make_object(user_id.get(), u->access_hash); +} + +bool UserManager::have_input_encrypted_peer(SecretChatId secret_chat_id, AccessRights access_rights) const { + return have_input_encrypted_peer(get_secret_chat(secret_chat_id), access_rights); +} + +bool UserManager::have_input_encrypted_peer(const SecretChat *secret_chat, AccessRights access_rights) { + if (secret_chat == nullptr) { + LOG(DEBUG) << "Have no secret chat"; + return false; + } + if (access_rights == AccessRights::Know) { + return true; + } + if (access_rights == AccessRights::Read) { + return true; + } + return secret_chat->state == SecretChatState::Active; +} + +telegram_api::object_ptr UserManager::get_input_encrypted_chat( + SecretChatId secret_chat_id, AccessRights access_rights) const { + auto sc = get_secret_chat(secret_chat_id); + if (!have_input_encrypted_peer(sc, access_rights)) { + return nullptr; + } + + return telegram_api::make_object(secret_chat_id.get(), sc->access_hash); +} + +bool UserManager::is_user_contact(UserId user_id, bool is_mutual) const { + return is_user_contact(get_user(user_id), user_id, is_mutual); +} + +bool UserManager::is_user_contact(const User *u, UserId user_id, bool is_mutual) const { + return u != nullptr && (is_mutual ? u->is_mutual_contact : u->is_contact) && user_id != get_my_id(); +} + +bool UserManager::is_user_premium(UserId user_id) const { + return is_user_premium(get_user(user_id)); +} + +bool UserManager::is_user_premium(const User *u) { + return u != nullptr && u->is_premium; +} + +bool UserManager::is_user_deleted(UserId user_id) const { + return is_user_deleted(get_user(user_id)); +} + +bool UserManager::is_user_deleted(const User *u) { + return u == nullptr || u->is_deleted; +} + +bool UserManager::is_user_support(UserId user_id) const { + return is_user_support(get_user(user_id)); +} + +bool UserManager::is_user_support(const User *u) { + return u != nullptr && !u->is_deleted && u->is_support; +} + +bool UserManager::is_user_bot(UserId user_id) const { + return is_user_bot(get_user(user_id)); +} + +bool UserManager::is_user_bot(const User *u) { + return u != nullptr && !u->is_deleted && u->is_bot; +} + +Result UserManager::get_bot_data(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return Status::Error(400, "Bot not found"); + } + if (!u->is_bot) { + return Status::Error(400, "User is not a bot"); + } + if (u->is_deleted) { + return Status::Error(400, "Bot is deleted"); + } + if (!u->is_received) { + return Status::Error(400, "Bot is inaccessible"); + } + + BotData bot_data; + bot_data.username = u->usernames.get_first_username(); + bot_data.can_be_edited = u->can_be_edited_bot; + bot_data.can_join_groups = u->can_join_groups; + bot_data.can_read_all_group_messages = u->can_read_all_group_messages; + bot_data.has_main_app = u->has_main_app; + bot_data.is_inline = u->is_inline_bot; + bot_data.is_business = u->is_business_bot; + bot_data.need_location = u->need_location_bot; + bot_data.can_be_added_to_attach_menu = u->can_be_added_to_attach_menu; + return bot_data; +} + +bool UserManager::is_user_online(UserId user_id, int32 tolerance, int32 unix_time) const { + if (unix_time <= 0) { + unix_time = G()->unix_time(); + } + int32 was_online = get_user_was_online(get_user(user_id), user_id, unix_time); + return was_online > unix_time - tolerance; +} + +int32 UserManager::get_user_was_online(UserId user_id, int32 unix_time) const { + if (unix_time <= 0) { + unix_time = G()->unix_time(); + } + return get_user_was_online(get_user(user_id), user_id, unix_time); +} + +int32 UserManager::get_user_was_online(const User *u, UserId user_id, int32 unix_time) const { + if (u == nullptr || u->is_deleted) { + return 0; + } + + int32 was_online = u->was_online; + if (user_id == get_my_id()) { + if (my_was_online_local_ != 0) { + was_online = my_was_online_local_; + } + } else { + if (u->local_was_online > 0 && u->local_was_online > was_online && u->local_was_online > unix_time) { + was_online = u->local_was_online; + } + } + return was_online; +} + +bool UserManager::is_user_status_exact(UserId user_id) const { + auto u = get_user(user_id); + return u != nullptr && !u->is_deleted && !u->is_bot && u->was_online > 0; +} + +bool UserManager::is_user_received_from_server(UserId user_id) const { + const auto *u = get_user(user_id); + return u != nullptr && u->is_received_from_server; +} + +bool UserManager::can_report_user(UserId user_id) const { + auto u = get_user(user_id); + return u != nullptr && !u->is_deleted && !u->is_support && + (u->is_bot || td_->people_nearby_manager_->is_user_nearby(user_id)); +} + +const DialogPhoto *UserManager::get_user_dialog_photo(UserId user_id) { + auto u = get_user(user_id); + if (u == nullptr) { + return nullptr; + } + + apply_pending_user_photo(u, user_id); + return &u->photo; +} + +const DialogPhoto *UserManager::get_secret_chat_dialog_photo(SecretChatId secret_chat_id) { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return nullptr; + } + return get_user_dialog_photo(c->user_id); +} + +int32 UserManager::get_user_accent_color_id_object(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr || !u->accent_color_id.is_valid()) { + return td_->theme_manager_->get_accent_color_id_object(AccentColorId(user_id)); + } + + return td_->theme_manager_->get_accent_color_id_object(u->accent_color_id, AccentColorId(user_id)); +} + +int32 UserManager::get_secret_chat_accent_color_id_object(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return 5; + } + return get_user_accent_color_id_object(c->user_id); +} + +CustomEmojiId UserManager::get_user_background_custom_emoji_id(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return CustomEmojiId(); + } + + return u->background_custom_emoji_id; +} + +CustomEmojiId UserManager::get_secret_chat_background_custom_emoji_id(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return CustomEmojiId(); + } + return get_user_background_custom_emoji_id(c->user_id); +} + +int32 UserManager::get_user_profile_accent_color_id_object(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return -1; + } + + return td_->theme_manager_->get_profile_accent_color_id_object(u->profile_accent_color_id); +} + +int32 UserManager::get_secret_chat_profile_accent_color_id_object(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return -1; + } + return get_user_profile_accent_color_id_object(c->user_id); +} + +CustomEmojiId UserManager::get_user_profile_background_custom_emoji_id(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return CustomEmojiId(); + } + + return u->profile_background_custom_emoji_id; +} + +CustomEmojiId UserManager::get_secret_chat_profile_background_custom_emoji_id(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return CustomEmojiId(); + } + return get_user_profile_background_custom_emoji_id(c->user_id); +} + +string UserManager::get_user_title(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return string(); + } + if (u->last_name.empty()) { + return u->first_name; + } + if (u->first_name.empty()) { + return u->last_name; + } + return PSTRING() << u->first_name << ' ' << u->last_name; +} + +string UserManager::get_secret_chat_title(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return string(); + } + return get_user_title(c->user_id); +} + +RestrictedRights UserManager::get_user_default_permissions(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr || user_id == get_replies_bot_user_id()) { + return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, u != nullptr, false, ChannelType::Unknown); + } + return RestrictedRights(true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, + true, false, ChannelType::Unknown); +} + +RestrictedRights UserManager::get_secret_chat_default_permissions(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return RestrictedRights(false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, ChannelType::Unknown); + } + return RestrictedRights(true, true, true, true, true, true, true, true, true, true, true, true, true, false, false, + false, false, ChannelType::Unknown); +} + +td_api::object_ptr UserManager::get_user_emoji_status_object(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return nullptr; + } + return u->last_sent_emoji_status.get_emoji_status_object(); +} + +td_api::object_ptr UserManager::get_secret_chat_emoji_status_object( + SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return nullptr; + } + return get_user_emoji_status_object(c->user_id); +} + +bool UserManager::get_user_stories_hidden(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return false; + } + return u->stories_hidden; +} + +bool UserManager::can_poll_user_active_stories(UserId user_id) const { + const User *u = get_user(user_id); + return need_poll_user_active_stories(u, user_id) && Time::now() >= u->max_active_story_id_next_reload_time; +} + +bool UserManager::need_poll_user_active_stories(const User *u, UserId user_id) const { + return u != nullptr && user_id != get_my_id() && !is_user_contact(u, user_id, false) && !is_user_bot(u) && + !is_user_support(u) && !is_user_deleted(u) && u->was_online != 0; +} + +string UserManager::get_user_about(UserId user_id) { + auto user_full = get_user_full_force(user_id, "get_user_about"); + if (user_full != nullptr) { + return user_full->about; + } + return string(); +} + +string UserManager::get_secret_chat_about(SecretChatId secret_chat_id) { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return string(); + } + return get_user_about(c->user_id); +} + +string UserManager::get_user_private_forward_name(UserId user_id) { + auto user_full = get_user_full_force(user_id, "get_user_private_forward_name"); + if (user_full != nullptr) { + return user_full->private_forward_name; + } + return string(); +} + +bool UserManager::get_user_voice_messages_forbidden(UserId user_id) const { + if (!is_user_premium(user_id)) { + return false; + } + auto user_full = get_user_full(user_id); + if (user_full != nullptr) { + return user_full->voice_messages_forbidden; + } + return false; +} + +bool UserManager::get_user_read_dates_private(UserId user_id) { + auto user_full = get_user_full_force(user_id, "get_user_read_dates_private"); + if (user_full != nullptr) { + return user_full->read_dates_private; + } + return false; +} + +string UserManager::get_user_search_text(UserId user_id) const { + auto u = get_user(user_id); + if (u == nullptr) { + return string(); + } + return get_user_search_text(u); +} + +string UserManager::get_user_search_text(const User *u) { + CHECK(u != nullptr); + return PSTRING() << u->first_name << ' ' << u->last_name << ' ' << implode(u->usernames.get_active_usernames()); +} + +void UserManager::for_each_secret_chat_with_user(UserId user_id, const std::function &f) { + auto it = secret_chats_with_user_.find(user_id); + if (it != secret_chats_with_user_.end()) { + for (auto secret_chat_id : it->second) { + f(secret_chat_id); + } + } +} + +string UserManager::get_user_first_username(UserId user_id) const { + if (!user_id.is_valid()) { + return string(); + } + + auto u = get_user(user_id); + if (u == nullptr) { + return string(); + } + return u->usernames.get_first_username(); +} + +int32 UserManager::get_secret_chat_date(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return 0; + } + return c->date; +} + +int32 UserManager::get_secret_chat_ttl(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return 0; + } + return c->ttl; +} + +UserId UserManager::get_secret_chat_user_id(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return UserId(); + } + return c->user_id; +} + +bool UserManager::get_secret_chat_is_outbound(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return false; + } + return c->is_outbound; +} + +SecretChatState UserManager::get_secret_chat_state(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return SecretChatState::Unknown; + } + return c->state; +} + +int32 UserManager::get_secret_chat_layer(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return 0; + } + return c->layer; +} + +FolderId UserManager::get_secret_chat_initial_folder_id(SecretChatId secret_chat_id) const { + auto c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + return FolderId::main(); + } + return c->initial_folder_id; +} + +vector UserManager::get_bot_commands(vector> &&bot_infos, + const vector *participants) { + vector result; + if (td_->auth_manager_->is_bot()) { + return result; + } + for (auto &bot_info : bot_infos) { + if (bot_info->commands_.empty()) { + continue; + } + + auto user_id = UserId(bot_info->user_id_); + const User *u = get_user_force(user_id, "get_bot_commands"); + if (u == nullptr) { + LOG(ERROR) << "Receive unknown " << user_id; + continue; + } + if (!is_user_bot(u)) { + if (!is_user_deleted(u)) { + LOG(ERROR) << "Receive non-bot " << user_id; + } + continue; + } + if (participants != nullptr) { + bool is_participant = false; + for (auto &participant : *participants) { + if (participant.dialog_id_ == DialogId(user_id)) { + is_participant = true; + break; + } + } + if (!is_participant) { + LOG(ERROR) << "Skip commands of non-member bot " << user_id; + continue; + } + } + result.emplace_back(user_id, std::move(bot_info->commands_)); + } + return result; +} + +void UserManager::set_name(const string &first_name, const string &last_name, Promise &&promise) { + auto new_first_name = clean_name(first_name, MAX_NAME_LENGTH); + auto new_last_name = clean_name(last_name, MAX_NAME_LENGTH); + if (new_first_name.empty()) { + return promise.set_error(Status::Error(400, "First name must be non-empty")); + } + + const User *u = get_user(get_my_id()); + int32 flags = 0; + // TODO we can already send request for changing first_name and last_name and wanting to set initial values + // TODO need to be rewritten using invoke after and cancelling previous request + if (u == nullptr || u->first_name != new_first_name) { + flags |= ACCOUNT_UPDATE_FIRST_NAME; + } + if (u == nullptr || u->last_name != new_last_name) { + flags |= ACCOUNT_UPDATE_LAST_NAME; + } + if (flags == 0) { + return promise.set_value(Unit()); + } + + td_->create_handler(std::move(promise))->send(flags, new_first_name, new_last_name, ""); +} + +void UserManager::set_bio(const string &bio, Promise &&promise) { + auto max_bio_length = static_cast(td_->option_manager_->get_option_integer("bio_length_max")); + auto new_bio = strip_empty_characters(bio, max_bio_length); + for (auto &c : new_bio) { + if (c == '\n') { + c = ' '; + } + } + + const UserFull *user_full = get_user_full(get_my_id()); + int32 flags = 0; + // TODO we can already send request for changing bio and wanting to set initial values + // TODO need to be rewritten using invoke after and cancelling previous request + if (user_full == nullptr || user_full->about != new_bio) { + flags |= ACCOUNT_UPDATE_ABOUT; + } + if (flags == 0) { + return promise.set_value(Unit()); + } + + td_->create_handler(std::move(promise))->send(flags, "", "", new_bio); +} + +void UserManager::on_update_profile_success(int32 flags, const string &first_name, const string &last_name, + const string &about) { + CHECK(flags != 0); + + auto my_user_id = get_my_id(); + const User *u = get_user(my_user_id); + if (u == nullptr) { + LOG(ERROR) << "Doesn't receive info about me during update profile"; + return; + } + LOG_IF(ERROR, (flags & ACCOUNT_UPDATE_FIRST_NAME) != 0 && u->first_name != first_name) + << "Wrong first name \"" << u->first_name << "\", expected \"" << first_name << '"'; + LOG_IF(ERROR, (flags & ACCOUNT_UPDATE_LAST_NAME) != 0 && u->last_name != last_name) + << "Wrong last name \"" << u->last_name << "\", expected \"" << last_name << '"'; + + if ((flags & ACCOUNT_UPDATE_ABOUT) != 0) { + UserFull *user_full = get_user_full_force(my_user_id, "on_update_profile_success"); + if (user_full != nullptr) { + user_full->about = about; + user_full->is_changed = true; + update_user_full(user_full, my_user_id, "on_update_profile_success"); + td_->group_call_manager_->on_update_dialog_about(DialogId(my_user_id), user_full->about, true); + } + } +} + +FileId UserManager::get_profile_photo_file_id(int64 photo_id) const { + auto it = my_photo_file_id_.find(photo_id); + if (it == my_photo_file_id_.end()) { + return FileId(); + } + return it->second; +} + +void UserManager::set_bot_profile_photo(UserId bot_user_id, + const td_api::object_ptr &input_photo, + Promise &&promise) { + if (td_->auth_manager_->is_bot()) { + if (bot_user_id != UserId() && bot_user_id != get_my_id()) { + return promise.set_error(Status::Error(400, "Invalid bot user identifier specified")); + } + bot_user_id = get_my_id(); + } else { + TRY_RESULT_PROMISE(promise, bot_data, get_bot_data(bot_user_id)); + if (!bot_data.can_be_edited) { + return promise.set_error(Status::Error(400, "The bot can't be edited")); + } + } + if (input_photo == nullptr) { + td_->create_handler(std::move(promise)) + ->send(bot_user_id, FileId(), 0, false, telegram_api::make_object()); + return; + } + set_profile_photo_impl(bot_user_id, input_photo, false, false, std::move(promise)); +} + +void UserManager::set_profile_photo(const td_api::object_ptr &input_photo, bool is_fallback, + Promise &&promise) { + set_profile_photo_impl(get_my_id(), input_photo, is_fallback, false, std::move(promise)); +} + +void UserManager::set_profile_photo_impl(UserId user_id, const td_api::object_ptr &input_photo, + bool is_fallback, bool only_suggest, Promise &&promise) { + if (input_photo == nullptr) { + return promise.set_error(Status::Error(400, "New profile photo must be non-empty")); + } + + const td_api::object_ptr *input_file = nullptr; + double main_frame_timestamp = 0.0; + bool is_animation = false; + switch (input_photo->get_id()) { + case td_api::inputChatPhotoPrevious::ID: { + if (user_id != get_my_id() || td_->auth_manager_->is_bot()) { + return promise.set_error(Status::Error(400, "Can't use inputChatPhotoPrevious")); + } + auto photo = static_cast(input_photo.get()); + auto photo_id = photo->chat_photo_id_; + auto *u = get_user(user_id); + if (u != nullptr && u->photo.id > 0 && photo_id == u->photo.id) { + // it is possible that u->photo.is_fallback != is_fallback, so we need to set the photo anyway + // return promise.set_value(Unit()); + } + + auto file_id = get_profile_photo_file_id(photo_id); + if (!file_id.is_valid()) { + return promise.set_error(Status::Error(400, "Unknown profile photo ID specified")); + } + return send_update_profile_photo_query(user_id, + td_->file_manager_->dup_file_id(file_id, "set_profile_photo_impl"), + photo_id, is_fallback, std::move(promise)); + } + case td_api::inputChatPhotoStatic::ID: { + auto photo = static_cast(input_photo.get()); + input_file = &photo->photo_; + break; + } + case td_api::inputChatPhotoAnimation::ID: { + auto photo = static_cast(input_photo.get()); + input_file = &photo->animation_; + main_frame_timestamp = photo->main_frame_timestamp_; + is_animation = true; + break; + } + case td_api::inputChatPhotoSticker::ID: { + auto photo = static_cast(input_photo.get()); + TRY_RESULT_PROMISE(promise, sticker_photo_size, StickerPhotoSize::get_sticker_photo_size(td_, photo->sticker_)); + + td_->create_handler(std::move(promise)) + ->send(user_id, std::move(sticker_photo_size), is_fallback, only_suggest); + return; + } + default: + UNREACHABLE(); + break; + } + + const double MAX_ANIMATION_DURATION = 10.0; + if (main_frame_timestamp < 0.0 || main_frame_timestamp > MAX_ANIMATION_DURATION) { + return promise.set_error(Status::Error(400, "Wrong main frame timestamp specified")); + } + + auto file_type = is_animation ? FileType::Animation : FileType::Photo; + TRY_RESULT_PROMISE(promise, file_id, + td_->file_manager_->get_input_file_id(file_type, *input_file, DialogId(user_id), false, false)); + CHECK(file_id.is_valid()); + + upload_profile_photo(user_id, td_->file_manager_->dup_file_id(file_id, "set_profile_photo_impl"), is_fallback, + only_suggest, is_animation, main_frame_timestamp, std::move(promise)); +} + +void UserManager::set_user_profile_photo(UserId user_id, const td_api::object_ptr &input_photo, + bool only_suggest, Promise &&promise) { + TRY_RESULT_PROMISE(promise, input_user, get_input_user(user_id)); + if (!only_suggest && !is_user_contact(user_id)) { + return promise.set_error(Status::Error(400, "User isn't a contact")); + } + if (user_id == get_my_id()) { + return promise.set_error(Status::Error(400, "Can't set personal or suggest photo to self")); + } + if (is_user_bot(user_id)) { + return promise.set_error(Status::Error(400, "Can't set personal or suggest photo to bots")); + } + if (input_photo == nullptr) { + td_->create_handler(std::move(promise))->send(user_id, std::move(input_user)); + return; + } + + set_profile_photo_impl(user_id, input_photo, false, only_suggest, std::move(promise)); +} + +void UserManager::send_update_profile_photo_query(UserId user_id, FileId file_id, int64 old_photo_id, bool is_fallback, + Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + FileView file_view = td_->file_manager_->get_file_view(file_id); + const auto *main_remote_location = file_view.get_main_remote_location(); + CHECK(main_remote_location != nullptr); + td_->create_handler(std::move(promise)) + ->send(user_id, file_id, old_photo_id, is_fallback, main_remote_location->as_input_photo()); +} + +void UserManager::upload_profile_photo(UserId user_id, FileId file_id, bool is_fallback, bool only_suggest, + bool is_animation, double main_frame_timestamp, Promise &&promise, + int reupload_count, vector bad_parts) { + CHECK(file_id.is_valid()); + bool is_inserted = + uploaded_profile_photos_ + .emplace(file_id, UploadedProfilePhoto{user_id, is_fallback, only_suggest, main_frame_timestamp, is_animation, + reupload_count, std::move(promise)}) + .second; + CHECK(is_inserted); + LOG(INFO) << "Ask to upload " << (is_animation ? "animated" : "static") << " profile photo " << file_id + << " for user " << user_id << " with bad parts " << bad_parts; + // TODO use force_reupload if reupload_count >= 1, replace reupload_count with is_reupload + td_->file_manager_->resume_upload(file_id, std::move(bad_parts), upload_profile_photo_callback_, 32, 0); +} + +void UserManager::on_upload_profile_photo(FileId file_id, + telegram_api::object_ptr input_file) { + auto it = uploaded_profile_photos_.find(file_id); + CHECK(it != uploaded_profile_photos_.end()); + + UserId user_id = it->second.user_id; + bool is_fallback = it->second.is_fallback; + bool only_suggest = it->second.only_suggest; + double main_frame_timestamp = it->second.main_frame_timestamp; + bool is_animation = it->second.is_animation; + int32 reupload_count = it->second.reupload_count; + auto promise = std::move(it->second.promise); + + uploaded_profile_photos_.erase(it); + + LOG(INFO) << "Uploaded " << (is_animation ? "animated" : "static") << " profile photo " << file_id << " for " + << user_id << " with reupload_count = " << reupload_count; + FileView file_view = td_->file_manager_->get_file_view(file_id); + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr && input_file == nullptr) { + if (main_remote_location->is_web()) { + return promise.set_error(Status::Error(400, "Can't use web photo as profile photo")); + } + if (reupload_count == 3) { // upload, ForceReupload repair file reference, reupload + return promise.set_error(Status::Error(400, "Failed to reupload the file")); + } + + // delete file reference and forcely reupload the file + if (is_animation) { + CHECK(file_view.get_type() == FileType::Animation); + LOG_CHECK(main_remote_location->is_common()) << *main_remote_location; + } else { + CHECK(file_view.get_type() == FileType::Photo); + LOG_CHECK(main_remote_location->is_photo()) << *main_remote_location; + } + auto file_reference = is_animation ? FileManager::extract_file_reference(main_remote_location->as_input_document()) + : FileManager::extract_file_reference(main_remote_location->as_input_photo()); + td_->file_manager_->delete_file_reference(file_id, file_reference); + upload_profile_photo(user_id, file_id, is_fallback, only_suggest, is_animation, main_frame_timestamp, + std::move(promise), reupload_count + 1, {-1}); + return; + } + CHECK(input_file != nullptr); + + td_->create_handler(std::move(promise)) + ->send(user_id, file_id, std::move(input_file), is_fallback, only_suggest, is_animation, main_frame_timestamp); +} + +void UserManager::on_upload_profile_photo_error(FileId file_id, Status status) { + LOG(INFO) << "File " << file_id << " has upload error " << status; + CHECK(status.is_error()); + + auto it = uploaded_profile_photos_.find(file_id); + CHECK(it != uploaded_profile_photos_.end()); + + auto promise = std::move(it->second.promise); + + uploaded_profile_photos_.erase(it); + + promise.set_error(std::move(status)); // TODO check that status has valid error code +} + +void UserManager::on_set_profile_photo(UserId user_id, telegram_api::object_ptr &&photo, + bool is_fallback, int64 old_photo_id, Promise &&promise) { + LOG(INFO) << "Changed profile photo to " << to_string(photo); + + bool is_bot = is_user_bot(user_id); + bool is_my = (user_id == get_my_id()); + if (is_my && !is_fallback) { + delete_my_profile_photo_from_cache(old_photo_id); + } + bool have_user = false; + for (const auto &user : photo->users_) { + if (get_user_id(user) == user_id) { + have_user = true; + } + } + on_get_users(std::move(photo->users_), "on_set_profile_photo"); + if (!is_bot) { + add_set_profile_photo_to_cache(user_id, get_photo(td_, std::move(photo->photo_), DialogId(user_id)), is_fallback); + } + if (have_user) { + promise.set_value(Unit()); + } else { + reload_user(user_id, std::move(promise), "on_set_profile_photo"); + } +} + +void UserManager::add_set_profile_photo_to_cache(UserId user_id, Photo &&photo, bool is_fallback) { + // we have subsequence of user photos in user_photos_ + // ProfilePhoto in User and Photo in UserFull + + User *u = get_user_force(user_id, "add_set_profile_photo_to_cache"); + if (u == nullptr) { + return; + } + + LOG(INFO) << "Add profile photo " << photo.id.get() << " to cache"; + + bool is_me = user_id == get_my_id(); + + // update photo list + auto user_photos = user_photos_.get_pointer(user_id); + if (is_me && !is_fallback && user_photos != nullptr && user_photos->count != -1 && !photo.is_empty()) { + if (user_photos->offset == 0) { + if (user_photos->photos.empty() || user_photos->photos[0].id.get() != photo.id.get()) { + user_photos->photos.insert(user_photos->photos.begin(), photo); + user_photos->count++; + register_user_photo(u, user_id, user_photos->photos[0]); + } + } else { + user_photos->count++; + user_photos->offset++; + } + } + + // update ProfilePhoto in User + if ((!is_fallback || u->photo.id == 0) && !photo.is_empty()) { + do_update_user_photo(u, user_id, as_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, photo, !is_me), + false, "add_set_profile_photo_to_cache"); + update_user(u, user_id); + } + + // update Photo in UserFull + auto user_full = get_user_full_force(user_id, "add_set_profile_photo_to_cache"); + if (user_full != nullptr) { + Photo *current_photo = nullptr; + // don't update the changed photo if other photos aren't known to avoid having only some photos known + bool need_apply = get_user_full_profile_photo_id(user_full) > 0; + if (!is_me) { + current_photo = &user_full->personal_photo; + if (photo.is_empty()) { + // always can apply empty personal photo + need_apply = true; + } + } else if (!is_fallback) { + current_photo = &user_full->photo; + if (photo.is_empty()) { + // never can apply empty photo + need_apply = false; + } + } else { + current_photo = &user_full->fallback_photo; + if (photo.is_empty()) { + // always can apply empty fallback photo + need_apply = true; + } + } + if (*current_photo != photo && need_apply) { + LOG(INFO) << "Update full photo of " << user_id << " to " << photo; + *current_photo = photo; + user_full->is_changed = true; + if (is_me && !photo.is_empty()) { + if (!is_fallback) { + register_user_photo(u, user_id, photo); + } else { + register_suggested_profile_photo(photo); + } + } + drop_user_full_photos(user_full, user_id, u->photo.id, "add_set_profile_photo_to_cache"); // just in case + } + if (user_full->expires_at > 0.0) { + user_full->expires_at = 0.0; + user_full->need_save_to_database = true; + } + update_user_full(user_full, user_id, "add_set_profile_photo_to_cache"); + reload_user_full(user_id, Auto(), "add_set_profile_photo_to_cache"); + } +} + +bool UserManager::delete_my_profile_photo_from_cache(int64 profile_photo_id) { + if (profile_photo_id == 0 || profile_photo_id == -2) { + return false; + } + + // we have subsequence of user photos in user_photos_ + // ProfilePhoto in User and Photo in UserFull + + LOG(INFO) << "Delete profile photo " << profile_photo_id << " from cache"; + + auto user_id = get_my_id(); + User *u = get_user_force(user_id, "delete_my_profile_photo_from_cache"); + bool is_main_photo_deleted = u != nullptr && u->photo.id == profile_photo_id; + + // update photo list + auto user_photos = user_photos_.get_pointer(user_id); + if (user_photos != nullptr && user_photos->count > 0) { + auto old_size = user_photos->photos.size(); + if (td::remove_if(user_photos->photos, + [profile_photo_id](const auto &photo) { return photo.id.get() == profile_photo_id; })) { + auto removed_photos = old_size - user_photos->photos.size(); + CHECK(removed_photos > 0); + LOG_IF(ERROR, removed_photos != 1) << "Had " << removed_photos << " photos with ID " << profile_photo_id; + user_photos->count -= narrow_cast(removed_photos); + // offset was not changed + CHECK(user_photos->count >= 0); + } else { + // failed to find photo to remove from cache + // don't know how to adjust user_photos->offset, so drop photos cache + LOG(INFO) << "Drop photos of " << user_id; + user_photos->photos.clear(); + user_photos->count = -1; + user_photos->offset = -1; + } + } + bool have_new_photo = + user_photos != nullptr && user_photos->count != -1 && user_photos->offset == 0 && !user_photos->photos.empty(); + + auto user_full = get_user_full_force(user_id, "delete_my_profile_photo_from_cache"); + + // update ProfilePhoto in User + bool need_reget_user = false; + if (is_main_photo_deleted) { + if (have_new_photo) { + do_update_user_photo( + u, user_id, + as_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, user_photos->photos[0], false), false, + "delete_my_profile_photo_from_cache"); + } else { + do_update_user_photo(u, user_id, ProfilePhoto(), false, "delete_my_profile_photo_from_cache 2"); + need_reget_user = user_photos == nullptr || user_photos->count != 0; + } + update_user(u, user_id); + + // update Photo in UserFull + if (user_full != nullptr) { + if (user_full->fallback_photo.id.get() == profile_photo_id) { + LOG(INFO) << "Drop full public photo of " << user_id; + user_full->photo = Photo(); + user_full->is_changed = true; + } else if (have_new_photo) { + if (user_full->photo.id.get() == profile_photo_id && user_photos->photos[0] != user_full->photo) { + LOG(INFO) << "Update full photo of " << user_id << " to " << user_photos->photos[0]; + user_full->photo = user_photos->photos[0]; + user_full->is_changed = true; + } + } else { + // repair UserFull photo + if (!user_full->photo.is_empty()) { + user_full->photo = Photo(); + user_full->is_changed = true; + } + if (!user_full->fallback_photo.is_empty()) { + user_full->fallback_photo = Photo(); + user_full->is_changed = true; + } + } + if (user_full->expires_at > 0.0) { + user_full->expires_at = 0.0; + user_full->need_save_to_database = true; + } + reload_user_full(user_id, Auto(), "delete_my_profile_photo_from_cache"); + update_user_full(user_full, user_id, "delete_my_profile_photo_from_cache"); + } + } + + return need_reget_user; +} + +void UserManager::delete_profile_photo(int64 profile_photo_id, bool is_recursive, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + const UserFull *user_full = get_user_full_force(get_my_id(), "delete_profile_photo"); + if (user_full == nullptr) { + // must load UserFull first, because fallback photo can't be deleted via DeleteProfilePhotoQuery + if (is_recursive) { + return promise.set_error(Status::Error(500, "Failed to load UserFullInfo")); + } + auto reload_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), profile_photo_id, promise = std::move(promise)](Result result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &UserManager::delete_profile_photo, profile_photo_id, true, std::move(promise)); + }); + reload_user_full(get_my_id(), std::move(reload_promise), "delete_profile_photo"); + return; + } + if (user_full->photo.id.get() == profile_photo_id || user_full->fallback_photo.id.get() == profile_photo_id) { + td_->create_handler(std::move(promise)) + ->send(get_my_id(), FileId(), profile_photo_id, user_full->fallback_photo.id.get() == profile_photo_id, + telegram_api::make_object()); + return; + } + + td_->create_handler(std::move(promise))->send(profile_photo_id); +} + +void UserManager::on_delete_profile_photo(int64 profile_photo_id, Promise promise) { + bool need_reget_user = delete_my_profile_photo_from_cache(profile_photo_id); + if (need_reget_user && !G()->close_flag()) { + return reload_user(get_my_id(), std::move(promise), "on_delete_profile_photo"); + } + + promise.set_value(Unit()); +} + +void UserManager::set_username(const string &username, Promise &&promise) { + if (!username.empty() && !is_allowed_username(username)) { + return promise.set_error(Status::Error(400, "Username is invalid")); + } + td_->create_handler(std::move(promise))->send(username); +} + +void UserManager::toggle_username_is_active(string &&username, bool is_active, Promise &&promise) { + get_me(PromiseCreator::lambda([actor_id = actor_id(this), username = std::move(username), is_active, + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &UserManager::toggle_username_is_active_impl, std::move(username), is_active, + std::move(promise)); + } + })); +} + +void UserManager::toggle_username_is_active_impl(string &&username, bool is_active, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + const User *u = get_user(get_my_id()); + CHECK(u != nullptr); + if (!u->usernames.can_toggle(username)) { + return promise.set_error(Status::Error(400, "Wrong username specified")); + } + td_->create_handler(std::move(promise))->send(std::move(username), is_active); +} + +void UserManager::reorder_usernames(vector &&usernames, Promise &&promise) { + get_me(PromiseCreator::lambda([actor_id = actor_id(this), usernames = std::move(usernames), + promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &UserManager::reorder_usernames_impl, std::move(usernames), std::move(promise)); + } + })); +} + +void UserManager::reorder_usernames_impl(vector &&usernames, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + const User *u = get_user(get_my_id()); + CHECK(u != nullptr); + if (!u->usernames.can_reorder_to(usernames)) { + return promise.set_error(Status::Error(400, "Invalid username order specified")); + } + if (usernames.size() <= 1) { + return promise.set_value(Unit()); + } + td_->create_handler(std::move(promise))->send(std::move(usernames)); +} + +void UserManager::on_update_username_is_active(UserId user_id, string &&username, bool is_active, + Promise &&promise) { + User *u = get_user(user_id); + CHECK(u != nullptr); + if (!u->usernames.can_toggle(username)) { + return reload_user(user_id, std::move(promise), "on_update_username_is_active"); + } + on_update_user_usernames(u, user_id, u->usernames.toggle(username, is_active)); + update_user(u, user_id); + promise.set_value(Unit()); +} + +void UserManager::on_update_active_usernames_order(UserId user_id, vector &&usernames, + Promise &&promise) { + User *u = get_user(user_id); + CHECK(u != nullptr); + if (!u->usernames.can_reorder_to(usernames)) { + return reload_user(user_id, std::move(promise), "on_update_active_usernames_order"); + } + on_update_user_usernames(u, user_id, u->usernames.reorder_to(std::move(usernames))); + update_user(u, user_id); + promise.set_value(Unit()); +} + +void UserManager::toggle_bot_username_is_active(UserId bot_user_id, string &&username, bool is_active, + Promise &&promise) { + TRY_RESULT_PROMISE(promise, bot_data, get_bot_data(bot_user_id)); + if (!bot_data.can_be_edited) { + return promise.set_error(Status::Error(400, "The bot can't be edited")); + } + const User *u = get_user(bot_user_id); + CHECK(u != nullptr); + if (!u->usernames.can_toggle(username)) { + return promise.set_error(Status::Error(400, "Wrong username specified")); + } + td_->create_handler(std::move(promise))->send(bot_user_id, std::move(username), is_active); +} + +void UserManager::reorder_bot_usernames(UserId bot_user_id, vector &&usernames, Promise &&promise) { + TRY_RESULT_PROMISE(promise, bot_data, get_bot_data(bot_user_id)); + if (!bot_data.can_be_edited) { + return promise.set_error(Status::Error(400, "The bot can't be edited")); + } + const User *u = get_user(bot_user_id); + CHECK(u != nullptr); + if (!u->usernames.can_reorder_to(usernames)) { + return promise.set_error(Status::Error(400, "Invalid username order specified")); + } + if (usernames.size() <= 1) { + return promise.set_value(Unit()); + } + td_->create_handler(std::move(promise))->send(bot_user_id, std::move(usernames)); +} + +void UserManager::set_accent_color(AccentColorId accent_color_id, CustomEmojiId background_custom_emoji_id, + Promise &&promise) { + if (!accent_color_id.is_valid()) { + return promise.set_error(Status::Error(400, "Invalid accent color identifier specified")); + } + if (accent_color_id == AccentColorId(get_my_id())) { + accent_color_id = AccentColorId(); + } + + td_->create_handler(std::move(promise))->send(false, accent_color_id, background_custom_emoji_id); +} + +void UserManager::set_profile_accent_color(AccentColorId accent_color_id, CustomEmojiId background_custom_emoji_id, + Promise &&promise) { + td_->create_handler(std::move(promise))->send(true, accent_color_id, background_custom_emoji_id); +} + +void UserManager::on_update_accent_color_success(bool for_profile, AccentColorId accent_color_id, + CustomEmojiId background_custom_emoji_id) { + auto user_id = get_my_id(); + User *u = get_user_force(user_id, "on_update_accent_color_success"); + if (u == nullptr) { + return; + } + if (for_profile) { + on_update_user_profile_accent_color_id(u, user_id, accent_color_id); + on_update_user_profile_background_custom_emoji_id(u, user_id, background_custom_emoji_id); + } else { + on_update_user_accent_color_id(u, user_id, accent_color_id); + on_update_user_background_custom_emoji_id(u, user_id, background_custom_emoji_id); + } + update_user(u, user_id); +} + +void UserManager::set_birthdate(Birthdate &&birthdate, Promise &&promise) { + dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::BirthdaySetup}, Promise()); + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), birthdate, promise = std::move(promise)](Result result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &UserManager::on_set_birthdate, birthdate, std::move(promise)); + } else { + promise.set_error(result.move_as_error()); + } + }); + td_->create_handler(std::move(query_promise))->send(birthdate); +} + +void UserManager::on_set_birthdate(Birthdate birthdate, Promise &&promise) { + auto my_user_id = get_my_id(); + UserFull *user_full = get_user_full_force(my_user_id, "on_set_birthdate"); + if (user_full != nullptr && user_full->birthdate != birthdate) { + user_full->birthdate = std::move(birthdate); + user_full->is_changed = true; + update_user_full(user_full, my_user_id, "on_set_birthdate"); + } + promise.set_value(Unit()); +} + +void UserManager::set_personal_channel(DialogId dialog_id, Promise &&promise) { + ChannelId channel_id; + if (dialog_id != DialogId()) { + if (!td_->dialog_manager_->have_dialog_force(dialog_id, "set_personal_channel")) { + return promise.set_error(Status::Error(400, "Chat not found")); + } + if (!td_->dialog_manager_->is_broadcast_channel(dialog_id)) { + return promise.set_error(Status::Error(400, "Chat can't be set as a personal chat")); + } + channel_id = dialog_id.get_channel_id(); + } + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), channel_id, promise = std::move(promise)](Result result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &UserManager::on_set_personal_channel, channel_id, std::move(promise)); + } else { + promise.set_error(result.move_as_error()); + } + }); + td_->create_handler(std::move(query_promise))->send(channel_id); +} + +void UserManager::on_set_personal_channel(ChannelId channel_id, Promise &&promise) { + auto my_user_id = get_my_id(); + UserFull *user_full = get_user_full_force(my_user_id, "on_set_personal_channel"); + if (user_full != nullptr && user_full->personal_channel_id != channel_id) { + user_full->personal_channel_id = channel_id; + user_full->is_changed = true; + update_user_full(user_full, my_user_id, "on_set_personal_channel"); + } + promise.set_value(Unit()); +} + +void UserManager::set_emoji_status(const EmojiStatus &emoji_status, Promise &&promise) { + if (!td_->option_manager_->get_option_boolean("is_premium")) { + return promise.set_error(Status::Error(400, "The method is available only to Telegram Premium users")); + } + add_recent_emoji_status(td_, emoji_status); + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), emoji_status, promise = std::move(promise)](Result result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &UserManager::on_set_emoji_status, emoji_status, std::move(promise)); + } else { + promise.set_error(result.move_as_error()); + } + }); + td_->create_handler(std::move(query_promise))->send(emoji_status); +} + +void UserManager::on_set_emoji_status(EmojiStatus emoji_status, Promise &&promise) { + auto user_id = get_my_id(); + User *u = get_user(user_id); + if (u != nullptr) { + on_update_user_emoji_status(u, user_id, emoji_status); + update_user(u, user_id); + } + promise.set_value(Unit()); +} + +void UserManager::toggle_sponsored_messages(bool sponsored_enabled, Promise &&promise) { + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), sponsored_enabled, promise = std::move(promise)](Result result) mutable { + if (result.is_ok()) { + send_closure(actor_id, &UserManager::on_toggle_sponsored_messages, sponsored_enabled, std::move(promise)); + } else { + promise.set_error(result.move_as_error()); + } + }); + td_->create_handler(std::move(query_promise))->send(sponsored_enabled); +} + +void UserManager::on_toggle_sponsored_messages(bool sponsored_enabled, Promise &&promise) { + auto my_user_id = get_my_id(); + UserFull *user_full = get_user_full_force(my_user_id, "on_toggle_sponsored_messages"); + if (user_full != nullptr && user_full->sponsored_enabled != sponsored_enabled) { + user_full->sponsored_enabled = sponsored_enabled; + user_full->is_changed = true; + update_user_full(user_full, my_user_id, "on_toggle_sponsored_messages"); + } + promise.set_value(Unit()); +} + +void UserManager::get_support_user(Promise> &&promise) { + if (support_user_id_.is_valid()) { + return promise.set_value(get_user_object(support_user_id_)); + } + + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + promise.set_error(result.move_as_error()); + } else { + send_closure(actor_id, &UserManager::on_get_support_user, result.move_as_ok(), std::move(promise)); + } + }); + td_->create_handler(std::move(query_promise))->send(); +} + +void UserManager::on_get_support_user(UserId user_id, Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + const User *u = get_user(user_id); + if (u == nullptr) { + return promise.set_error(Status::Error(500, "Can't find support user")); + } + if (!u->is_support) { + LOG(ERROR) << "Receive non-support " << user_id << ", but expected a support user"; + } + + support_user_id_ = user_id; + promise.set_value(get_user_object(user_id, u)); +} + +void UserManager::get_user_profile_photos(UserId user_id, int32 offset, int32 limit, + Promise> &&promise) { + if (offset < 0) { + return promise.set_error(Status::Error(400, "Parameter offset must be non-negative")); + } + if (limit <= 0) { + return promise.set_error(Status::Error(400, "Parameter limit must be positive")); + } + if (limit > MAX_GET_PROFILE_PHOTOS) { + limit = MAX_GET_PROFILE_PHOTOS; + } + + TRY_STATUS_PROMISE(promise, get_input_user(user_id)); + + auto *u = get_user(user_id); + if (u == nullptr) { + return promise.set_error(Status::Error(400, "User not found")); + } + + apply_pending_user_photo(u, user_id); + + auto user_photos = add_user_photos(user_id); + if (user_photos->count != -1) { // know photo count + CHECK(user_photos->offset != -1); + LOG(INFO) << "Have " << user_photos->count << " cached user profile photos at offset " << user_photos->offset; + vector> photo_objects; + + if (offset >= user_photos->count) { + // offset if too big + return promise.set_value(td_api::make_object(user_photos->count, std::move(photo_objects))); + } + + if (limit > user_photos->count - offset) { + limit = user_photos->count - offset; + } + + int32 cache_begin = user_photos->offset; + int32 cache_end = cache_begin + narrow_cast(user_photos->photos.size()); + if (cache_begin <= offset && offset + limit <= cache_end) { + // answer query from cache + for (int i = 0; i < limit; i++) { + photo_objects.push_back( + get_chat_photo_object(td_->file_manager_.get(), user_photos->photos[i + offset - cache_begin])); + } + return promise.set_value(td_api::make_object(user_photos->count, std::move(photo_objects))); + } + } + + PendingGetPhotoRequest pending_request; + pending_request.offset = offset; + pending_request.limit = limit; + pending_request.promise = std::move(promise); + user_photos->pending_requests.push_back(std::move(pending_request)); + if (user_photos->pending_requests.size() != 1u) { + return; + } + + send_get_user_photos_query(user_id, user_photos); +} + +void UserManager::send_get_user_photos_query(UserId user_id, const UserPhotos *user_photos) { + CHECK(!user_photos->pending_requests.empty()); + auto offset = user_photos->pending_requests[0].offset; + auto limit = user_photos->pending_requests[0].limit; + + if (user_photos->count != -1 && offset >= user_photos->offset) { + int32 cache_end = user_photos->offset + narrow_cast(user_photos->photos.size()); + if (offset < cache_end) { + // adjust offset to the end of cache + CHECK(offset + limit > cache_end); // otherwise the request has already been answered + limit = offset + limit - cache_end; + offset = cache_end; + } + } + + auto query_promise = PromiseCreator::lambda([actor_id = actor_id(this), user_id](Result &&result) { + send_closure(actor_id, &UserManager::on_get_user_profile_photos, user_id, std::move(result)); + }); + + td_->create_handler(std::move(query_promise)) + ->send(user_id, get_input_user_force(user_id), offset, max(limit, MAX_GET_PROFILE_PHOTOS / 5), 0); +} + +void UserManager::on_get_user_profile_photos(UserId user_id, Result &&result) { + G()->ignore_result_if_closing(result); + auto user_photos = add_user_photos(user_id); + auto pending_requests = std::move(user_photos->pending_requests); + CHECK(!pending_requests.empty()); + if (result.is_error()) { + for (auto &request : pending_requests) { + request.promise.set_error(result.error().clone()); + } + return; + } + if (user_photos->count == -1) { + CHECK(have_user(user_id)); + // received result has just been dropped; resend request + if (++pending_requests[0].retry_count >= 3) { + pending_requests[0].promise.set_error(Status::Error(500, "Failed to return profile photos")); + pending_requests.erase(pending_requests.begin()); + if (pending_requests.empty()) { + return; + } + } + user_photos->pending_requests = std::move(pending_requests); + return send_get_user_photos_query(user_id, user_photos); + } + + CHECK(user_photos->offset != -1); + LOG(INFO) << "Have " << user_photos->count << " cached user profile photos at offset " << user_photos->offset; + vector left_requests; + for (size_t request_index = 0; request_index < pending_requests.size(); request_index++) { + auto &request = pending_requests[request_index]; + vector> photo_objects; + + if (request.offset >= user_photos->count) { + // offset if too big + request.promise.set_value(td_api::make_object(user_photos->count, std::move(photo_objects))); + continue; + } + + if (request.limit > user_photos->count - request.offset) { + request.limit = user_photos->count - request.offset; + } + + int32 cache_begin = user_photos->offset; + int32 cache_end = cache_begin + narrow_cast(user_photos->photos.size()); + if (cache_begin <= request.offset && request.offset + request.limit <= cache_end) { + // answer query from cache + for (int i = 0; i < request.limit; i++) { + photo_objects.push_back( + get_chat_photo_object(td_->file_manager_.get(), user_photos->photos[i + request.offset - cache_begin])); + } + request.promise.set_value(td_api::make_object(user_photos->count, std::move(photo_objects))); + continue; + } + + if (request_index == 0 && ++request.retry_count >= 3) { + request.promise.set_error(Status::Error(500, "Failed to get profile photos")); + continue; + } + + left_requests.push_back(std::move(request)); + } + + if (!left_requests.empty()) { + bool need_send = user_photos->pending_requests.empty(); + append(user_photos->pending_requests, std::move(left_requests)); + if (need_send) { + send_get_user_photos_query(user_id, user_photos); + } + } +} + +void UserManager::reload_user_profile_photo(UserId user_id, int64 photo_id, Promise &&promise) { + get_user_force(user_id, "reload_user_profile_photo"); + TRY_RESULT_PROMISE(promise, input_user, get_input_user(user_id)); + + // this request will be needed only to download the photo, + // so there is no reason to combine different requests for a photo into one request + td_->create_handler(std::move(promise))->send(user_id, std::move(input_user), -1, 1, photo_id); +} + +FileSourceId UserManager::get_user_profile_photo_file_source_id(UserId user_id, int64 photo_id) { + if (!user_id.is_valid()) { + return FileSourceId(); + } + + auto u = get_user(user_id); + if (u != nullptr && u->photo_ids.count(photo_id) != 0) { + VLOG(file_references) << "Don't need to create file source for photo " << photo_id << " of " << user_id; + // photo was already added, source ID was registered and shouldn't be needed + return FileSourceId(); + } + + auto &source_id = user_profile_photo_file_source_ids_[std::make_pair(user_id, photo_id)]; + if (!source_id.is_valid()) { + source_id = td_->file_reference_manager_->create_user_photo_file_source(user_id, photo_id); + } + VLOG(file_references) << "Return " << source_id << " for photo " << photo_id << " of " << user_id; + return source_id; +} + +UserManager::UserPhotos *UserManager::add_user_photos(UserId user_id) { + CHECK(user_id.is_valid()); + auto &user_photos_ptr = user_photos_[user_id]; + if (user_photos_ptr == nullptr) { + user_photos_ptr = make_unique(); + } + return user_photos_ptr.get(); +} + +void UserManager::on_get_user_photos(UserId user_id, int32 offset, int32 limit, int32 total_count, + vector> photos) { + auto photo_count = narrow_cast(photos.size()); + int32 min_total_count = (offset >= 0 && photo_count > 0 ? offset : 0) + photo_count; + if (total_count < min_total_count) { + LOG(ERROR) << "Receive wrong photos total_count " << total_count << " for user " << user_id << ": receive " + << photo_count << " photos with offset " << offset; + total_count = min_total_count; + } + LOG_IF(ERROR, limit < photo_count) << "Requested not more than " << limit << " photos, but " << photo_count + << " received"; + + User *u = get_user(user_id); + if (u == nullptr) { + LOG(ERROR) << "Can't find " << user_id; + return; + } + + if (offset == -1) { + // from reload_user_profile_photo + CHECK(limit == 1); + for (auto &photo_ptr : photos) { + if (photo_ptr->get_id() == telegram_api::photo::ID) { + auto server_photo = telegram_api::move_object_as(photo_ptr); + if (server_photo->id_ == u->photo.id) { + auto profile_photo = convert_photo_to_profile_photo(server_photo, u->photo.is_personal); + if (profile_photo) { + LOG_IF(ERROR, u->access_hash == -1) << "Receive profile photo of " << user_id << " without access hash"; + get_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, std::move(profile_photo)); + } else { + LOG(ERROR) << "Failed to get profile photo from " << to_string(server_photo); + } + } + + auto photo = get_photo(td_, std::move(server_photo), DialogId(user_id)); + register_user_photo(u, user_id, photo); + } + } + return; + } + + LOG(INFO) << "Receive " << photo_count << " photos of " << user_id << " out of " << total_count << " with offset " + << offset << " and limit " << limit; + UserPhotos *user_photos = add_user_photos(user_id); + user_photos->count = total_count; + CHECK(!user_photos->pending_requests.empty()); + + if (user_photos->offset == -1) { + user_photos->offset = 0; + CHECK(user_photos->photos.empty()); + } + + if (offset != narrow_cast(user_photos->photos.size()) + user_photos->offset) { + LOG(INFO) << "Inappropriate offset to append " << user_id << " profile photos to cache: offset = " << offset + << ", current_offset = " << user_photos->offset << ", photo_count = " << user_photos->photos.size(); + user_photos->photos.clear(); + user_photos->offset = offset; + } + + for (auto &photo : photos) { + auto user_photo = get_photo(td_, std::move(photo), DialogId(user_id)); + if (user_photo.is_empty()) { + LOG(ERROR) << "Receive empty profile photo in getUserPhotos request for " << user_id << " with offset " << offset + << " and limit " << limit << ". Receive " << photo_count << " photos out of " << total_count + << " photos"; + user_photos->count--; + CHECK(user_photos->count >= 0); + continue; + } + + user_photos->photos.push_back(std::move(user_photo)); + register_user_photo(u, user_id, user_photos->photos.back()); + } + if (user_photos->offset > user_photos->count) { + user_photos->offset = user_photos->count; + user_photos->photos.clear(); + } + + auto known_photo_count = narrow_cast(user_photos->photos.size()); + if (user_photos->offset + known_photo_count > user_photos->count) { + user_photos->photos.resize(user_photos->count - user_photos->offset); + } +} + +void UserManager::apply_pending_user_photo(User *u, UserId user_id) { + if (u == nullptr || u->is_photo_inited) { + return; + } + + if (pending_user_photos_.count(user_id) > 0) { + do_update_user_photo(u, user_id, std::move(pending_user_photos_[user_id]), "apply_pending_user_photo"); + pending_user_photos_.erase(user_id); + update_user(u, user_id); + } +} + +void UserManager::register_message_users(MessageFullId message_full_id, vector user_ids) { + auto dialog_id = message_full_id.get_dialog_id(); + CHECK(dialog_id.get_type() == DialogType::Channel); + if (!td_->chat_manager_->have_channel(dialog_id.get_channel_id())) { + return; + } + for (auto user_id : user_ids) { + CHECK(user_id.is_valid()); + const User *u = get_user(user_id); + if (u == nullptr || u->access_hash == -1 || u->is_min_access_hash) { + auto &user_messages = user_messages_[user_id]; + auto need_update = user_messages.empty(); + user_messages.insert(message_full_id); + if (need_update) { + send_closure(G()->td(), &Td::send_update, get_update_user_object(user_id, u)); + } + } + } +} + +void UserManager::unregister_message_users(MessageFullId message_full_id, vector user_ids) { + if (user_messages_.empty()) { + // fast path + return; + } + for (auto user_id : user_ids) { + auto it = user_messages_.find(user_id); + if (it != user_messages_.end()) { + it->second.erase(message_full_id); + if (it->second.empty()) { + user_messages_.erase(it); + + const User *u = get_user(user_id); + if (u == nullptr || u->access_hash == -1 || u->is_min_access_hash) { + send_closure(G()->td(), &Td::send_update, get_update_user_object(user_id, u)); + } + } + } + } +} + +void UserManager::can_send_message_to_user(UserId user_id, bool force, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + if (user_id == get_my_id()) { + return promise.set_value(td_api::make_object()); + } + const auto *u = get_user(user_id); + if (!have_input_peer_user(u, user_id, AccessRights::Write)) { + return promise.set_value(td_api::make_object()); + } + CHECK(user_id.is_valid()); + if ((u != nullptr && (!u->contact_require_premium || u->is_mutual_contact)) || + td_->option_manager_->get_option_boolean("is_premium")) { + return promise.set_value(td_api::make_object()); + } + + auto user_full = get_user_full_force(user_id, "can_send_message_to_user"); + if (user_full != nullptr) { + if (!user_full->contact_require_premium) { + return promise.set_value(td_api::make_object()); + } + return promise.set_value(td_api::make_object()); + } + + auto it = user_full_contact_require_premium_.find(user_id); + if (it != user_full_contact_require_premium_.end()) { + if (!it->second) { + return promise.set_value(td_api::make_object()); + } + return promise.set_value(td_api::make_object()); + } + + if (force) { + return promise.set_value(td_api::make_object()); + } + + auto query_promise = PromiseCreator::lambda( + [actor_id = actor_id(this), user_id, promise = std::move(promise)](Result &&result) mutable { + if (result.is_error()) { + return promise.set_error(result.move_as_error()); + } + send_closure(actor_id, &UserManager::can_send_message_to_user, user_id, true, std::move(promise)); + }); + get_is_premium_required_to_contact_queries_.add_query(user_id.get(), std::move(query_promise), + "can_send_message_to_user"); +} + +void UserManager::on_get_is_premium_required_to_contact_users(vector &&user_ids, + vector &&is_premium_required, + Promise &&promise) { + if (user_ids.size() != is_premium_required.size()) { + LOG(ERROR) << "Receive " << is_premium_required.size() << " flags instead of " << user_ids.size(); + return promise.set_error(Status::Error(500, "Receive invalid response")); + } + for (size_t i = 0; i < user_ids.size(); i++) { + auto user_id = user_ids[i]; + CHECK(user_id.is_valid()); + if (get_user_full(user_id) == nullptr) { + user_full_contact_require_premium_[user_id] = is_premium_required[i]; + } + } + promise.set_value(Unit()); +} + +void UserManager::allow_send_message_to_user(UserId user_id) { + if (get_user_full(user_id) == nullptr) { + CHECK(user_id.is_valid()); + user_full_contact_require_premium_[user_id] = true; + } +} + +void UserManager::share_phone_number(UserId user_id, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + if (!are_contacts_loaded_) { + load_contacts(PromiseCreator::lambda( + [actor_id = actor_id(this), user_id, promise = std::move(promise)](Result &&) mutable { + send_closure(actor_id, &UserManager::share_phone_number, user_id, std::move(promise)); + })); + return; + } + + LOG(INFO) << "Share phone number with " << user_id; + TRY_RESULT_PROMISE(promise, input_user, get_input_user(user_id)); + + td_->messages_manager_->hide_dialog_action_bar(DialogId(user_id)); + + td_->create_handler(std::move(promise))->send(user_id, std::move(input_user)); +} + +void UserManager::load_contacts(Promise &&promise) { + if (td_->auth_manager_->is_bot()) { + are_contacts_loaded_ = true; + saved_contact_count_ = 0; + } + if (are_contacts_loaded_ && saved_contact_count_ != -1) { + LOG(INFO) << "Contacts are already loaded"; + return promise.set_value(Unit()); + } + load_contacts_queries_.push_back(std::move(promise)); + if (load_contacts_queries_.size() == 1u) { + if (G()->use_chat_info_database() && next_contacts_sync_date_ > 0 && saved_contact_count_ != -1) { + LOG(INFO) << "Load contacts from database"; + G()->td_db()->get_sqlite_pmc()->get( + "user_contacts", PromiseCreator::lambda([](string value) { + send_closure(G()->user_manager(), &UserManager::on_load_contacts_from_database, std::move(value)); + })); + } else { + LOG(INFO) << "Load contacts from server"; + reload_contacts(true); + } + } else { + LOG(INFO) << "Load contacts request has already been sent"; + } +} + +int64 UserManager::get_contacts_hash() { + if (!are_contacts_loaded_) { + return 0; + } + + vector user_ids = contacts_hints_.search_empty(100000).second; + CHECK(std::is_sorted(user_ids.begin(), user_ids.end())); + auto my_id = get_my_id(); + const User *u = get_user_force(my_id, "get_contacts_hash"); + if (u != nullptr && u->is_contact) { + user_ids.insert(std::upper_bound(user_ids.begin(), user_ids.end(), my_id.get()), my_id.get()); + } + + vector numbers; + numbers.reserve(user_ids.size() + 1); + numbers.push_back(saved_contact_count_); + for (auto user_id : user_ids) { + numbers.push_back(user_id); + } + return get_vector_hash(numbers); +} + +void UserManager::reload_contacts(bool force) { + if (!G()->close_flag() && !td_->auth_manager_->is_bot() && + next_contacts_sync_date_ != std::numeric_limits::max() && + (next_contacts_sync_date_ < G()->unix_time() || force)) { + next_contacts_sync_date_ = std::numeric_limits::max(); + td_->create_handler()->send(get_contacts_hash()); + } +} + +void UserManager::save_next_contacts_sync_date() { + if (G()->close_flag()) { + return; + } + if (!G()->use_chat_info_database()) { + return; + } + G()->td_db()->get_binlog_pmc()->set("next_contacts_sync_date", to_string(next_contacts_sync_date_)); +} + +void UserManager::save_contacts_to_database() { + if (!G()->use_chat_info_database() || !are_contacts_loaded_) { + return; + } + + LOG(INFO) << "Schedule save contacts to database"; + vector user_ids = + transform(contacts_hints_.search_empty(100000).second, [](int64 key) { return UserId(key); }); + + G()->td_db()->get_binlog_pmc()->set("saved_contact_count", to_string(saved_contact_count_)); + G()->td_db()->get_binlog()->force_sync( + PromiseCreator::lambda([user_ids = std::move(user_ids)](Result<> result) { + if (result.is_ok()) { + LOG(INFO) << "Saved contacts to database"; + G()->td_db()->get_sqlite_pmc()->set( + "user_contacts", log_event_store(user_ids).as_slice().str(), PromiseCreator::lambda([](Result<> result) { + if (result.is_ok()) { + send_closure(G()->user_manager(), &UserManager::save_next_contacts_sync_date); + } + })); + } + }), + "save_contacts_to_database"); +} + +void UserManager::on_get_contacts(telegram_api::object_ptr &&new_contacts) { + next_contacts_sync_date_ = G()->unix_time() + Random::fast(70000, 100000); + + CHECK(new_contacts != nullptr); + if (new_contacts->get_id() == telegram_api::contacts_contactsNotModified::ID) { + if (saved_contact_count_ == -1) { + saved_contact_count_ = 0; + } + on_get_contacts_finished(contacts_hints_.size()); + td_->create_handler()->send(); + return; + } + + auto contacts = move_tl_object_as(new_contacts); + FlatHashSet contact_user_ids; + for (auto &user : contacts->users_) { + auto user_id = get_user_id(user); + if (!user_id.is_valid()) { + LOG(ERROR) << "Receive invalid " << user_id; + continue; + } + contact_user_ids.insert(user_id); + } + on_get_users(std::move(contacts->users_), "on_get_contacts"); + + UserId my_id = get_my_id(); + users_.foreach([&](const UserId &user_id, unique_ptr &user) { + User *u = user.get(); + bool should_be_contact = contact_user_ids.count(user_id) == 1; + if (u->is_contact != should_be_contact) { + if (u->is_contact) { + LOG(INFO) << "Drop contact with " << user_id; + if (user_id != my_id) { + LOG_CHECK(contacts_hints_.has_key(user_id.get())) + << my_id << " " << user_id << " " << to_string(get_user_object(user_id, u)); + } + on_update_user_is_contact(u, user_id, false, false, false); + CHECK(u->is_is_contact_changed); + u->cache_version = 0; + u->is_repaired = false; + update_user(u, user_id); + CHECK(!u->is_contact); + if (user_id != my_id) { + CHECK(!contacts_hints_.has_key(user_id.get())); + } + } else { + LOG(ERROR) << "Receive non-contact " << user_id << " in the list of contacts"; + } + } + }); + + saved_contact_count_ = contacts->saved_count_; + on_get_contacts_finished(std::numeric_limits::max()); +} + +void UserManager::on_get_contacts_failed(Status error) { + CHECK(error.is_error()); + next_contacts_sync_date_ = G()->unix_time() + Random::fast(5, 10); + fail_promises(load_contacts_queries_, std::move(error)); +} + +void UserManager::on_load_contacts_from_database(string value) { + if (G()->close_flag()) { + return; + } + if (value.empty()) { + reload_contacts(true); + return; + } + + vector user_ids; + if (log_event_parse(user_ids, value).is_error()) { + LOG(ERROR) << "Failed to load contacts from database"; + reload_contacts(true); + return; + } + + if (log_event_get_version(value) < static_cast(Version::AddUserFlags2)) { + next_contacts_sync_date_ = 0; + save_next_contacts_sync_date(); + reload_contacts(true); + } + + LOG(INFO) << "Successfully loaded " << user_ids.size() << " contacts from database"; + + load_contact_users_multipromise_.add_promise(PromiseCreator::lambda( + [actor_id = actor_id(this), expected_contact_count = user_ids.size()](Result result) { + if (result.is_ok()) { + send_closure(actor_id, &UserManager::on_get_contacts_finished, expected_contact_count); + } else { + LOG(INFO) << "Failed to load contact users from database: " << result.error(); + send_closure(actor_id, &UserManager::reload_contacts, true); + } + })); + + auto lock_promise = load_contact_users_multipromise_.get_promise(); + + for (auto user_id : user_ids) { + get_user(user_id, 3, load_contact_users_multipromise_.get_promise()); + } + + lock_promise.set_value(Unit()); +} + +void UserManager::on_get_contacts_finished(size_t expected_contact_count) { + LOG(INFO) << "Finished to get " << contacts_hints_.size() << " contacts out of expected " << expected_contact_count; + are_contacts_loaded_ = true; + set_promises(load_contacts_queries_); + if (expected_contact_count != contacts_hints_.size()) { + save_contacts_to_database(); + } +} + +void UserManager::on_get_contacts_statuses(vector> &&statuses) { + auto my_user_id = get_my_id(); + for (auto &status : statuses) { + UserId user_id(status->user_id_); + if (user_id != my_user_id) { + on_update_user_online(user_id, std::move(status->status_)); + } + } + save_next_contacts_sync_date(); +} + +void UserManager::add_contact(Contact contact, bool share_phone_number, Promise &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + + if (!are_contacts_loaded_) { + load_contacts(PromiseCreator::lambda([actor_id = actor_id(this), contact = std::move(contact), share_phone_number, + promise = std::move(promise)](Result &&) mutable { + send_closure(actor_id, &UserManager::add_contact, std::move(contact), share_phone_number, std::move(promise)); + })); + return; + } + + LOG(INFO) << "Add " << contact << " with share_phone_number = " << share_phone_number; + + auto user_id = contact.get_user_id(); + TRY_RESULT_PROMISE(promise, input_user, get_input_user(user_id)); + + td_->create_handler(std::move(promise)) + ->send(user_id, std::move(input_user), contact, share_phone_number); +} + +std::pair, vector> UserManager::import_contacts(const vector &contacts, int64 &random_id, + Promise &&promise) { + if (!are_contacts_loaded_) { + load_contacts(std::move(promise)); + return {}; + } + + LOG(INFO) << "Asked to import " << contacts.size() << " contacts with random_id = " << random_id; + if (random_id != 0) { + // request has already been sent before + auto it = imported_contacts_.find(random_id); + CHECK(it != imported_contacts_.end()); + auto result = std::move(it->second); + imported_contacts_.erase(it); + + promise.set_value(Unit()); + return result; + } + + do { + random_id = Random::secure_int64(); + } while (random_id == 0 || random_id == 1 || imported_contacts_.count(random_id) > 0); + imported_contacts_[random_id]; // reserve place for result + + do_import_contacts(contacts, random_id, std::move(promise)); + return {}; +} + +void UserManager::do_import_contacts(vector contacts, int64 random_id, Promise &&promise) { + size_t size = contacts.size(); + if (size == 0) { + on_import_contacts_finished(random_id, {}, {}); + return promise.set_value(Unit()); + } + + vector> input_phone_contacts; + input_phone_contacts.reserve(size); + for (size_t i = 0; i < size; i++) { + input_phone_contacts.push_back(contacts[i].get_input_phone_contact(static_cast(i))); + } + + auto task = make_unique(); + task->promise_ = std::move(promise); + task->input_contacts_ = std::move(contacts); + task->imported_user_ids_.resize(size); + task->unimported_contact_invites_.resize(size); + + bool is_added = import_contact_tasks_.emplace(random_id, std::move(task)).second; + CHECK(is_added); + + td_->create_handler()->send(std::move(input_phone_contacts), random_id); +} + +void UserManager::on_imported_contacts( + int64 random_id, Result> result) { + auto it = import_contact_tasks_.find(random_id); + CHECK(it != import_contact_tasks_.end()); + CHECK(it->second != nullptr); + + auto task = it->second.get(); + if (result.is_error()) { + auto promise = std::move(task->promise_); + import_contact_tasks_.erase(it); + return promise.set_error(result.move_as_error()); + } + + auto imported_contacts = result.move_as_ok(); + on_get_users(std::move(imported_contacts->users_), "on_imported_contacts"); + + for (auto &imported_contact : imported_contacts->imported_) { + int64 client_id = imported_contact->client_id_; + if (client_id < 0 || client_id >= static_cast(task->imported_user_ids_.size())) { + LOG(ERROR) << "Wrong client_id " << client_id << " returned"; + continue; + } + + task->imported_user_ids_[static_cast(client_id)] = UserId(imported_contact->user_id_); + } + for (auto &popular_contact : imported_contacts->popular_invites_) { + int64 client_id = popular_contact->client_id_; + if (client_id < 0 || client_id >= static_cast(task->unimported_contact_invites_.size())) { + LOG(ERROR) << "Wrong client_id " << client_id << " returned"; + continue; + } + if (popular_contact->importers_ < 0) { + LOG(ERROR) << "Wrong number of importers " << popular_contact->importers_ << " returned"; + continue; + } + + task->unimported_contact_invites_[static_cast(client_id)] = popular_contact->importers_; + } + + if (!imported_contacts->retry_contacts_.empty()) { + auto total_size = static_cast(task->input_contacts_.size()); + vector> input_phone_contacts; + input_phone_contacts.reserve(imported_contacts->retry_contacts_.size()); + for (auto &client_id : imported_contacts->retry_contacts_) { + if (client_id < 0 || client_id >= total_size) { + LOG(ERROR) << "Wrong client_id " << client_id << " returned"; + continue; + } + auto i = static_cast(client_id); + input_phone_contacts.push_back(task->input_contacts_[i].get_input_phone_contact(client_id)); + } + td_->create_handler()->send(std::move(input_phone_contacts), random_id); + return; + } + + auto promise = std::move(task->promise_); + on_import_contacts_finished(random_id, std::move(task->imported_user_ids_), + std::move(task->unimported_contact_invites_)); + import_contact_tasks_.erase(it); + promise.set_value(Unit()); +} + +void UserManager::on_import_contacts_finished(int64 random_id, vector imported_contact_user_ids, + vector unimported_contact_invites) { + LOG(INFO) << "Contacts import with random_id " << random_id + << " has finished: " << format::as_array(imported_contact_user_ids); + if (random_id == 1) { + // import from change_imported_contacts + all_imported_contacts_ = std::move(next_all_imported_contacts_); + next_all_imported_contacts_.clear(); + + auto result_size = imported_contacts_unique_id_.size(); + auto unique_size = all_imported_contacts_.size(); + auto add_size = imported_contacts_pos_.size(); + + imported_contact_user_ids_.resize(result_size); + unimported_contact_invites_.resize(result_size); + + CHECK(imported_contact_user_ids.size() == add_size); + CHECK(unimported_contact_invites.size() == add_size); + CHECK(imported_contacts_unique_id_.size() == result_size); + + std::unordered_map> unique_id_to_unimported_contact_invites; + for (size_t i = 0; i < add_size; i++) { + auto unique_id = imported_contacts_pos_[i]; + get_user_id_object(imported_contact_user_ids[i], "on_import_contacts_finished"); // to ensure updateUser + all_imported_contacts_[unique_id].set_user_id(imported_contact_user_ids[i]); + unique_id_to_unimported_contact_invites[narrow_cast(unique_id)] = unimported_contact_invites[i]; + } + + if (G()->use_chat_info_database()) { + G()->td_db()->get_binlog()->force_sync( + PromiseCreator::lambda( + [log_event = log_event_store(all_imported_contacts_).as_slice().str()](Result<> result) mutable { + if (result.is_ok()) { + LOG(INFO) << "Save imported contacts to database"; + G()->td_db()->get_sqlite_pmc()->set("user_imported_contacts", std::move(log_event), Auto()); + } + }), + "on_import_contacts_finished"); + } + + for (size_t i = 0; i < result_size; i++) { + auto unique_id = imported_contacts_unique_id_[i]; + CHECK(unique_id < unique_size); + imported_contact_user_ids_[i] = all_imported_contacts_[unique_id].get_user_id(); + auto it = unique_id_to_unimported_contact_invites.find(narrow_cast(unique_id)); + if (it == unique_id_to_unimported_contact_invites.end()) { + unimported_contact_invites_[i] = 0; + } else { + unimported_contact_invites_[i] = it->second; + } + } + return; + } + + auto it = imported_contacts_.find(random_id); + CHECK(it != imported_contacts_.end()); + CHECK(it->second.first.empty()); + CHECK(it->second.second.empty()); + imported_contacts_[random_id] = {std::move(imported_contact_user_ids), std::move(unimported_contact_invites)}; +} + +void UserManager::remove_contacts(const vector &user_ids, Promise &&promise) { + LOG(INFO) << "Delete contacts: " << format::as_array(user_ids); + if (!are_contacts_loaded_) { + load_contacts(std::move(promise)); + return; + } + + vector to_delete_user_ids; + vector> input_users; + for (auto &user_id : user_ids) { + const User *u = get_user(user_id); + if (u != nullptr && u->is_contact) { + auto r_input_user = get_input_user(user_id); + if (r_input_user.is_ok()) { + to_delete_user_ids.push_back(user_id); + input_users.push_back(r_input_user.move_as_ok()); + } + } + } + + if (input_users.empty()) { + return promise.set_value(Unit()); + } + + td_->create_handler(std::move(promise))->send(std::move(input_users)); +} + +void UserManager::remove_contacts_by_phone_number(vector user_phone_numbers, vector user_ids, + Promise &&promise) { + LOG(INFO) << "Delete contacts by phone number: " << format::as_array(user_phone_numbers); + if (!are_contacts_loaded_) { + load_contacts(std::move(promise)); + return; + } + + td_->create_handler(std::move(promise)) + ->send(std::move(user_phone_numbers), std::move(user_ids)); +} + +void UserManager::on_deleted_contacts(const vector &deleted_contact_user_ids) { + LOG(INFO) << "Contacts deletion has finished for " << deleted_contact_user_ids; + + for (auto user_id : deleted_contact_user_ids) { + auto u = get_user(user_id); + CHECK(u != nullptr); + if (!u->is_contact) { + continue; + } + + LOG(INFO) << "Drop contact with " << user_id; + on_update_user_is_contact(u, user_id, false, false, false); + CHECK(u->is_is_contact_changed); + u->cache_version = 0; + u->is_repaired = false; + update_user(u, user_id); + CHECK(!u->is_contact); + CHECK(!contacts_hints_.has_key(user_id.get())); + } +} + +int32 UserManager::get_imported_contact_count(Promise &&promise) { + LOG(INFO) << "Get imported contact count"; + + if (!are_contacts_loaded_ || saved_contact_count_ == -1) { + load_contacts(std::move(promise)); + return 0; + } + reload_contacts(false); + + promise.set_value(Unit()); + return saved_contact_count_; +} + +void UserManager::load_imported_contacts(Promise &&promise) { + if (td_->auth_manager_->is_bot()) { + are_imported_contacts_loaded_ = true; + } + if (are_imported_contacts_loaded_) { + LOG(INFO) << "Imported contacts are already loaded"; + promise.set_value(Unit()); + return; + } + load_imported_contacts_queries_.push_back(std::move(promise)); + if (load_imported_contacts_queries_.size() == 1u) { + if (G()->use_chat_info_database()) { + LOG(INFO) << "Load imported contacts from database"; + G()->td_db()->get_sqlite_pmc()->get("user_imported_contacts", PromiseCreator::lambda([](string value) { + send_closure_later(G()->user_manager(), + &UserManager::on_load_imported_contacts_from_database, + std::move(value)); + })); + } else { + LOG(INFO) << "Have no previously imported contacts"; + send_closure_later(G()->user_manager(), &UserManager::on_load_imported_contacts_from_database, string()); + } + } else { + LOG(INFO) << "Load imported contacts request has already been sent"; + } +} + +void UserManager::on_load_imported_contacts_from_database(string value) { + if (G()->close_flag()) { + return; + } + + CHECK(!are_imported_contacts_loaded_); + if (need_clear_imported_contacts_) { + need_clear_imported_contacts_ = false; + value.clear(); + } + if (value.empty()) { + CHECK(all_imported_contacts_.empty()); + } else { + if (log_event_parse(all_imported_contacts_, value).is_error()) { + LOG(ERROR) << "Failed to load all imported contacts from database"; + all_imported_contacts_.clear(); + } else { + LOG(INFO) << "Successfully loaded " << all_imported_contacts_.size() << " imported contacts from database"; + } + } + + load_imported_contact_users_multipromise_.add_promise( + PromiseCreator::lambda([actor_id = actor_id(this)](Result result) { + if (result.is_ok()) { + send_closure_later(actor_id, &UserManager::on_load_imported_contacts_finished); + } + })); + + auto lock_promise = load_imported_contact_users_multipromise_.get_promise(); + + for (const auto &contact : all_imported_contacts_) { + auto user_id = contact.get_user_id(); + if (user_id.is_valid()) { + get_user(user_id, 3, load_imported_contact_users_multipromise_.get_promise()); + } + } + + lock_promise.set_value(Unit()); +} + +void UserManager::on_load_imported_contacts_finished() { + LOG(INFO) << "Finished to load " << all_imported_contacts_.size() << " imported contacts"; + + for (const auto &contact : all_imported_contacts_) { + get_user_id_object(contact.get_user_id(), "on_load_imported_contacts_finished"); // to ensure updateUser + } + + if (need_clear_imported_contacts_) { + need_clear_imported_contacts_ = false; + all_imported_contacts_.clear(); + } + are_imported_contacts_loaded_ = true; + set_promises(load_imported_contacts_queries_); +} + +std::pair, vector> UserManager::change_imported_contacts(vector &contacts, + int64 &random_id, + Promise &&promise) { + if (!are_contacts_loaded_) { + load_contacts(std::move(promise)); + return {}; + } + if (!are_imported_contacts_loaded_) { + load_imported_contacts(std::move(promise)); + return {}; + } + + LOG(INFO) << "Asked to change imported contacts to a list of " << contacts.size() + << " contacts with random_id = " << random_id; + if (random_id != 0) { + // request has already been sent before + if (need_clear_imported_contacts_) { + need_clear_imported_contacts_ = false; + all_imported_contacts_.clear(); + if (G()->use_chat_info_database()) { + G()->td_db()->get_sqlite_pmc()->erase("user_imported_contacts", Auto()); + } + reload_contacts(true); + } + + CHECK(are_imported_contacts_changing_); + are_imported_contacts_changing_ = false; + + auto unimported_contact_invites = std::move(unimported_contact_invites_); + unimported_contact_invites_.clear(); + + auto imported_contact_user_ids = std::move(imported_contact_user_ids_); + imported_contact_user_ids_.clear(); + + promise.set_value(Unit()); + return {std::move(imported_contact_user_ids), std::move(unimported_contact_invites)}; + } + + if (are_imported_contacts_changing_) { + promise.set_error(Status::Error(400, "ChangeImportedContacts can be called only once at the same time")); + return {}; + } + + vector new_contacts_unique_id(contacts.size()); + vector unique_new_contacts; + unique_new_contacts.reserve(contacts.size()); + std::unordered_map different_new_contacts; + std::unordered_set> different_new_phone_numbers; + size_t unique_size = 0; + for (size_t i = 0; i < contacts.size(); i++) { + auto it_success = different_new_contacts.emplace(std::move(contacts[i]), unique_size); + new_contacts_unique_id[i] = it_success.first->second; + if (it_success.second) { + unique_new_contacts.push_back(it_success.first->first); + different_new_phone_numbers.insert(unique_new_contacts.back().get_phone_number()); + unique_size++; + } + } + + vector to_delete; + vector to_delete_user_ids; + for (auto &old_contact : all_imported_contacts_) { + auto user_id = old_contact.get_user_id(); + auto it = different_new_contacts.find(old_contact); + if (it == different_new_contacts.end()) { + auto phone_number = old_contact.get_phone_number(); + if (different_new_phone_numbers.count(phone_number) == 0) { + to_delete.push_back(std::move(phone_number)); + if (user_id.is_valid()) { + to_delete_user_ids.push_back(user_id); + } + } + } else { + unique_new_contacts[it->second].set_user_id(user_id); + different_new_contacts.erase(it); + } + } + std::pair, vector> to_add; + for (auto &new_contact : different_new_contacts) { + to_add.first.push_back(new_contact.second); + to_add.second.push_back(new_contact.first); + } + + if (to_add.first.empty() && to_delete.empty()) { + for (size_t i = 0; i < contacts.size(); i++) { + auto unique_id = new_contacts_unique_id[i]; + contacts[i].set_user_id(unique_new_contacts[unique_id].get_user_id()); + } + + promise.set_value(Unit()); + return {transform(contacts, [&](const Contact &contact) { return contact.get_user_id(); }), + vector(contacts.size())}; + } + + are_imported_contacts_changing_ = true; + random_id = 1; + + remove_contacts_by_phone_number( + std::move(to_delete), std::move(to_delete_user_ids), + PromiseCreator::lambda([new_contacts = std::move(unique_new_contacts), + new_contacts_unique_id = std::move(new_contacts_unique_id), to_add = std::move(to_add), + promise = std::move(promise)](Result<> result) mutable { + if (result.is_ok()) { + send_closure_later(G()->user_manager(), &UserManager::on_clear_imported_contacts, std::move(new_contacts), + std::move(new_contacts_unique_id), std::move(to_add), std::move(promise)); + } else { + promise.set_error(result.move_as_error()); + } + })); + return {}; +} + +void UserManager::clear_imported_contacts(Promise &&promise) { + LOG(INFO) << "Delete imported contacts"; + + if (saved_contact_count_ == 0) { + promise.set_value(Unit()); + return; + } + + td_->create_handler(std::move(promise))->send(); +} + +void UserManager::on_clear_imported_contacts(vector &&contacts, vector contacts_unique_id, + std::pair, vector> &&to_add, + Promise &&promise) { + LOG(INFO) << "Add " << to_add.first.size() << " contacts"; + next_all_imported_contacts_ = std::move(contacts); + imported_contacts_unique_id_ = std::move(contacts_unique_id); + imported_contacts_pos_ = std::move(to_add.first); + + do_import_contacts(std::move(to_add.second), 1, std::move(promise)); +} + +void UserManager::on_update_contacts_reset() { + /* + UserId my_id = get_my_id(); + users_.foreach([&](const UserId &user_id, unique_ptr &user) { + User *u = user.get(); + if (u->is_contact) { + LOG(INFO) << "Drop contact with " << user_id; + if (user_id != my_id) { + CHECK(contacts_hints_.has_key(user_id.get())); + } + on_update_user_is_contact(u, user_id, false, false, false); + CHECK(u->is_is_contact_changed); + u->cache_version = 0; + u->is_repaired = false; + update_user(u, user_id); + CHECK(!u->is_contact); + if (user_id != my_id) { + CHECK(!contacts_hints_.has_key(user_id.get())); + } + } + }); + */ + + saved_contact_count_ = 0; + if (G()->use_chat_info_database()) { + G()->td_db()->get_binlog_pmc()->set("saved_contact_count", "0"); + G()->td_db()->get_sqlite_pmc()->erase("user_imported_contacts", Auto()); + } + if (!are_imported_contacts_loaded_) { + if (load_imported_contacts_queries_.empty()) { + CHECK(all_imported_contacts_.empty()); + LOG(INFO) << "Imported contacts were never loaded, just clear them"; + } else { + LOG(INFO) << "Imported contacts are being loaded, clear them after they will be loaded"; + need_clear_imported_contacts_ = true; + } + } else { + if (!are_imported_contacts_changing_) { + LOG(INFO) << "Imported contacts were loaded, but aren't changing now, just clear them"; + all_imported_contacts_.clear(); + } else { + LOG(INFO) << "Imported contacts are changing now, clear them after they will be changed"; + need_clear_imported_contacts_ = true; + } + } + reload_contacts(true); +} + +void UserManager::update_contacts_hints(const User *u, UserId user_id, bool from_database) { + bool is_contact = is_user_contact(u, user_id, false); + if (td_->auth_manager_->is_bot()) { + LOG_IF(ERROR, is_contact) << "Bot has " << user_id << " in the contacts list"; + return; + } + + int64 key = user_id.get(); + string old_value = contacts_hints_.key_to_string(key); + string new_value = is_contact ? get_user_search_text(u) : string(); + + if (new_value != old_value) { + if (is_contact) { + contacts_hints_.add(key, new_value); + } else { + contacts_hints_.remove(key); + } + } + + if (G()->use_chat_info_database()) { + // update contacts database + if (!are_contacts_loaded_) { + if (!from_database && load_contacts_queries_.empty() && is_contact && u->is_is_contact_changed) { + search_contacts("", std::numeric_limits::max(), Auto()); + } + } else { + if (old_value.empty() == is_contact) { + save_contacts_to_database(); + } + } + } +} + +std::pair> UserManager::search_contacts(const string &query, int32 limit, + Promise &&promise) { + LOG(INFO) << "Search contacts with query = \"" << query << "\" and limit = " << limit; + + if (limit < 0) { + promise.set_error(Status::Error(400, "Limit must be non-negative")); + return {}; + } + + if (!are_contacts_loaded_) { + load_contacts(std::move(promise)); + return {}; + } + reload_contacts(false); + + std::pair> result; + if (query.empty()) { + result = contacts_hints_.search_empty(limit); + } else { + result = contacts_hints_.search(query, limit); + } + + vector user_ids; + user_ids.reserve(result.second.size()); + for (auto key : result.second) { + user_ids.emplace_back(key); + } + + promise.set_value(Unit()); + return {narrow_cast(result.first), std::move(user_ids)}; +} + +void UserManager::reload_contact_birthdates(bool force) { + if (td_->option_manager_->get_option_boolean("dismiss_birthday_contact_today")) { + contact_birthdates_.need_drop_ = true; + if (!contact_birthdates_.is_being_synced_) { + contact_birthdates_.is_being_synced_ = true; + on_get_contact_birthdates(nullptr); + } + return; + } + if (!G()->close_flag() && !td_->auth_manager_->is_bot() && !contact_birthdates_.is_being_synced_ && + (contact_birthdates_.next_sync_time_ < Time::now() || force)) { + contact_birthdates_.is_being_synced_ = true; + td_->create_handler()->send(); + } +} + +void UserManager::on_get_contact_birthdates( + telegram_api::object_ptr &&birthdays) { + CHECK(contact_birthdates_.is_being_synced_); + contact_birthdates_.is_being_synced_ = false; + if (contact_birthdates_.need_drop_) { + birthdays = telegram_api::make_object(Auto(), Auto()); + contact_birthdates_.need_drop_ = false; + } + if (birthdays == nullptr) { + contact_birthdates_.next_sync_time_ = Time::now() + Random::fast(120, 180); + return; + } + contact_birthdates_.next_sync_time_ = Time::now() + Random::fast(86400 / 4, 86400 / 3); + + on_get_users(std::move(birthdays->users_), "on_get_contact_birthdates"); + vector> users; + for (auto &contact : birthdays->contacts_) { + UserId user_id(contact->contact_id_); + if (is_user_contact(user_id)) { + Birthdate birthdate(std::move(contact->birthday_)); + UserFull *user_full = get_user_full_force(user_id, "on_get_contact_birthdates"); + if (user_full != nullptr && user_full->birthdate != birthdate) { + user_full->birthdate = birthdate; + user_full->is_changed = true; + update_user_full(user_full, user_id, "on_get_contact_birthdates"); + } + if (!birthdate.is_empty()) { + users.emplace_back(user_id, birthdate); + } + } + } + if (contact_birthdates_.users_ != users) { + contact_birthdates_.users_ = std::move(users); + send_closure(G()->td(), &Td::send_update, get_update_contact_close_birthdays()); + } + // there is no need to save them between restarts +} + +void UserManager::hide_contact_birthdays(Promise &&promise) { + td_->create_handler(std::move(promise))->send(); +} + +vector UserManager::get_close_friends(Promise &&promise) { + if (!are_contacts_loaded_) { + load_contacts(std::move(promise)); + return {}; + } + reload_contacts(false); + + auto result = contacts_hints_.search_empty(10000); + + vector user_ids; + for (auto key : result.second) { + UserId user_id(key); + const User *u = get_user(user_id); + if (u != nullptr && u->is_close_friend) { + user_ids.push_back(user_id); + } + } + + promise.set_value(Unit()); + return user_ids; +} + +void UserManager::set_close_friends(vector user_ids, Promise &&promise) { + for (auto &user_id : user_ids) { + if (!have_user(user_id)) { + return promise.set_error(Status::Error(400, "User not found")); + } + } + + td_->create_handler(std::move(promise))->send(std::move(user_ids)); +} + +void UserManager::on_set_close_friends(const vector &user_ids, Promise &&promise) { + FlatHashSet close_friend_user_ids; + for (auto &user_id : user_ids) { + CHECK(user_id.is_valid()); + close_friend_user_ids.insert(user_id); + } + users_.foreach([&](const UserId &user_id, unique_ptr &user) { + User *u = user.get(); + if (u->is_contact && u->is_close_friend != (close_friend_user_ids.count(user_id) > 0)) { + on_update_user_is_contact(u, user_id, u->is_contact, u->is_mutual_contact, !u->is_close_friend); + update_user(u, user_id); + } + }); + promise.set_value(Unit()); +} + +UserId UserManager::search_user_by_phone_number(string phone_number, bool only_local, Promise &&promise) { + clean_phone_number(phone_number); + if (phone_number.empty()) { + promise.set_error(Status::Error(200, "Phone number is invalid")); + return UserId(); + } + + auto it = resolved_phone_numbers_.find(phone_number); + if (it != resolved_phone_numbers_.end()) { + promise.set_value(Unit()); + return it->second; + } + + if (only_local) { + promise.set_value(Unit()); + } else { + td_->create_handler(std::move(promise))->send(phone_number); + } + return UserId(); +} + +void UserManager::on_resolved_phone_number(const string &phone_number, UserId user_id) { + if (!user_id.is_valid()) { + resolved_phone_numbers_.emplace(phone_number, UserId()); // negative cache + return; + } + + auto it = resolved_phone_numbers_.find(phone_number); + if (it != resolved_phone_numbers_.end()) { + if (it->second != user_id) { + LOG(WARNING) << "Resolve phone number \"" << phone_number << "\" to " << user_id << ", but have it in " + << it->second; + it->second = user_id; + } + return; + } + + auto *u = get_user(user_id); + if (u == nullptr) { + LOG(ERROR) << "Resolve phone number \"" << phone_number << "\" to unknown " << user_id; + } else if (!u->phone_number.empty()) { + LOG(ERROR) << "Resolve phone number \"" << phone_number << "\" to " << user_id << " with phone number " + << u->phone_number; + } else { + // the user's phone number can be hidden by privacy settings, despite the user can be found by the phone number + } + resolved_phone_numbers_[phone_number] = user_id; // always update cached value +} + +const UserManager::UserFull *UserManager::get_user_full(UserId user_id) const { + return users_full_.get_pointer(user_id); +} + +UserManager::UserFull *UserManager::get_user_full(UserId user_id) { + return users_full_.get_pointer(user_id); +} + +UserManager::UserFull *UserManager::add_user_full(UserId user_id) { + CHECK(user_id.is_valid()); + auto &user_full_ptr = users_full_[user_id]; + if (user_full_ptr == nullptr) { + user_full_ptr = make_unique(); + user_full_contact_require_premium_.erase(user_id); + } + return user_full_ptr.get(); +} + +UserManager::UserFull *UserManager::get_user_full_force(UserId user_id, const char *source) { + if (!have_user_force(user_id, source)) { + return nullptr; + } + + UserFull *user_full = get_user_full(user_id); + if (user_full != nullptr) { + return user_full; + } + if (!G()->use_chat_info_database()) { + return nullptr; + } + if (!unavailable_user_fulls_.insert(user_id).second) { + return nullptr; + } + + LOG(INFO) << "Trying to load full " << user_id << " from database from " << source; + on_load_user_full_from_database(user_id, + G()->td_db()->get_sqlite_sync_pmc()->get(get_user_full_database_key(user_id))); + return get_user_full(user_id); +} + +void UserManager::load_user_full(UserId user_id, bool force, Promise &&promise, const char *source) { + auto u = get_user(user_id); + if (u == nullptr) { + return promise.set_error(Status::Error(400, "User not found")); + } + + auto user_full = get_user_full_force(user_id, source); + if (user_full == nullptr) { + TRY_RESULT_PROMISE(promise, input_user, get_input_user(user_id)); + return send_get_user_full_query(user_id, std::move(input_user), std::move(promise), source); + } + if (user_full->is_expired()) { + auto input_user = get_input_user_force(user_id); + if (td_->auth_manager_->is_bot() && !force) { + return send_get_user_full_query(user_id, std::move(input_user), std::move(promise), "load expired user_full"); + } + + send_get_user_full_query(user_id, std::move(input_user), Auto(), "load expired user_full"); + } + + td_->story_manager_->on_view_dialog_active_stories({DialogId(user_id)}); + promise.set_value(Unit()); +} + +void UserManager::reload_user_full(UserId user_id, Promise &&promise, const char *source) { + TRY_RESULT_PROMISE(promise, input_user, get_input_user(user_id)); + send_get_user_full_query(user_id, std::move(input_user), std::move(promise), source); +} + +void UserManager::send_get_user_full_query(UserId user_id, + telegram_api::object_ptr &&input_user, + Promise &&promise, const char *source) { + LOG(INFO) << "Get full " << user_id << " from " << source; + if (!user_id.is_valid()) { + return promise.set_error(Status::Error(500, "Invalid user_id")); + } + auto send_query = + PromiseCreator::lambda([td = td_, input_user = std::move(input_user)](Result> &&promise) mutable { + if (promise.is_ok() && !G()->close_flag()) { + td->create_handler(promise.move_as_ok())->send(std::move(input_user)); + } + }); + get_user_full_queries_.add_query(user_id.get(), std::move(send_query), std::move(promise)); +} + +void UserManager::on_get_user_full(telegram_api::object_ptr &&user) { + LOG(INFO) << "Receive " << to_string(user); + + UserId user_id(user->id_); + User *u = get_user(user_id); + if (u == nullptr) { + LOG(ERROR) << "Failed to find " << user_id; + return; + } + + apply_pending_user_photo(u, user_id); + + td_->messages_manager_->on_update_dialog_notify_settings(DialogId(user_id), std::move(user->notify_settings_), + "on_get_user_full"); + + td_->messages_manager_->on_update_dialog_background(DialogId(user_id), std::move(user->wallpaper_)); + + td_->messages_manager_->on_update_dialog_theme_name(DialogId(user_id), std::move(user->theme_emoticon_)); + + td_->messages_manager_->on_update_dialog_last_pinned_message_id(DialogId(user_id), + MessageId(ServerMessageId(user->pinned_msg_id_))); + + td_->messages_manager_->on_update_dialog_folder_id(DialogId(user_id), FolderId(user->folder_id_)); + + td_->messages_manager_->on_update_dialog_has_scheduled_server_messages(DialogId(user_id), user->has_scheduled_); + + td_->messages_manager_->on_update_dialog_message_ttl(DialogId(user_id), MessageTtl(user->ttl_period_)); + + td_->messages_manager_->on_update_dialog_is_blocked(DialogId(user_id), user->blocked_, + user->blocked_my_stories_from_); + + td_->messages_manager_->on_update_dialog_is_translatable(DialogId(user_id), !user->translations_disabled_); + + send_closure_later(td_->story_manager_actor_, &StoryManager::on_get_dialog_stories, DialogId(user_id), + std::move(user->stories_), Promise()); + + UserFull *user_full = add_user_full(user_id); + user_full->expires_at = Time::now() + USER_FULL_EXPIRE_TIME; + + on_update_user_full_is_blocked(user_full, user_id, user->blocked_, user->blocked_my_stories_from_); + on_update_user_full_common_chat_count(user_full, user_id, user->common_chats_count_); + on_update_user_full_location(user_full, user_id, DialogLocation(td_, std::move(user->business_location_))); + on_update_user_full_work_hours(user_full, user_id, BusinessWorkHours(std::move(user->business_work_hours_))); + on_update_user_full_away_message(user_full, user_id, BusinessAwayMessage(std::move(user->business_away_message_))); + on_update_user_full_greeting_message(user_full, user_id, + BusinessGreetingMessage(std::move(user->business_greeting_message_))); + on_update_user_full_intro(user_full, user_id, BusinessIntro(td_, std::move(user->business_intro_))); + on_update_user_full_need_phone_number_privacy_exception(user_full, user_id, + user->settings_->need_contacts_exception_); + on_update_user_full_wallpaper_overridden(user_full, user_id, user->wallpaper_overridden_); + + bool can_pin_messages = user->can_pin_message_; + bool can_be_called = user->phone_calls_available_ && !user->phone_calls_private_; + bool supports_video_calls = user->video_calls_available_ && !user->phone_calls_private_; + bool has_private_calls = user->phone_calls_private_; + bool voice_messages_forbidden = u->is_premium ? user->voice_messages_forbidden_ : false; + auto premium_gift_options = get_premium_gift_options(std::move(user->premium_gifts_)); + AdministratorRights group_administrator_rights(user->bot_group_admin_rights_, ChannelType::Megagroup); + AdministratorRights broadcast_administrator_rights(user->bot_broadcast_admin_rights_, ChannelType::Broadcast); + bool has_pinned_stories = user->stories_pinned_available_; + auto birthdate = Birthdate(std::move(user->birthday_)); + auto personal_channel_id = ChannelId(user->personal_channel_id_); + auto sponsored_enabled = user->sponsored_enabled_; + if (user_full->can_be_called != can_be_called || user_full->supports_video_calls != supports_video_calls || + user_full->has_private_calls != has_private_calls || + user_full->group_administrator_rights != group_administrator_rights || + user_full->broadcast_administrator_rights != broadcast_administrator_rights || + user_full->premium_gift_options != premium_gift_options || + user_full->voice_messages_forbidden != voice_messages_forbidden || + user_full->can_pin_messages != can_pin_messages || user_full->has_pinned_stories != has_pinned_stories || + user_full->sponsored_enabled != sponsored_enabled) { + user_full->can_be_called = can_be_called; + user_full->supports_video_calls = supports_video_calls; + user_full->has_private_calls = has_private_calls; + user_full->group_administrator_rights = group_administrator_rights; + user_full->broadcast_administrator_rights = broadcast_administrator_rights; + user_full->premium_gift_options = std::move(premium_gift_options); + user_full->voice_messages_forbidden = voice_messages_forbidden; + user_full->can_pin_messages = can_pin_messages; + user_full->has_pinned_stories = has_pinned_stories; + user_full->sponsored_enabled = sponsored_enabled; + + user_full->is_changed = true; + } + if (user_full->birthdate != birthdate) { + user_full->birthdate = birthdate; + user_full->is_changed = true; + + if (u->is_mutual_contact) { + reload_contact_birthdates(true); + } + } + + if (user_full->private_forward_name != user->private_forward_name_) { + if (user_full->private_forward_name.empty() != user->private_forward_name_.empty()) { + user_full->is_changed = true; + } + user_full->private_forward_name = std::move(user->private_forward_name_); + user_full->need_save_to_database = true; + } + if (user_full->read_dates_private != user->read_dates_private_ || + user_full->contact_require_premium != user->contact_require_premium_) { + user_full->read_dates_private = user->read_dates_private_; + user_full->contact_require_premium = user->contact_require_premium_; + user_full->need_save_to_database = true; + } + if (user_full->about != user->about_) { + user_full->about = std::move(user->about_); + user_full->is_changed = true; + td_->group_call_manager_->on_update_dialog_about(DialogId(user_id), user_full->about, true); + } + string description; + Photo description_photo; + FileId description_animation_file_id; + if (user->bot_info_ != nullptr && !td_->auth_manager_->is_bot()) { + description = std::move(user->bot_info_->description_); + description_photo = get_photo(td_, std::move(user->bot_info_->description_photo_), DialogId(user_id)); + auto document = std::move(user->bot_info_->description_document_); + if (document != nullptr) { + int32 document_id = document->get_id(); + if (document_id == telegram_api::document::ID) { + auto parsed_document = td_->documents_manager_->on_get_document( + move_tl_object_as(document), DialogId(user_id)); + if (parsed_document.type == Document::Type::Animation) { + description_animation_file_id = parsed_document.file_id; + } else { + LOG(ERROR) << "Receive non-animation document in bot description"; + } + } + } + + on_update_user_full_commands(user_full, user_id, std::move(user->bot_info_->commands_)); + on_update_user_full_menu_button(user_full, user_id, std::move(user->bot_info_->menu_button_)); + on_update_user_full_has_preview_medias(user_full, user_id, std::move(user->bot_info_->has_preview_medias_)); + + if (user_full->privacy_policy_url != user->bot_info_->privacy_policy_url_) { + user_full->privacy_policy_url = std::move(user->bot_info_->privacy_policy_url_); + user_full->is_changed = true; + } + } + if (user_full->description != description) { + user_full->description = std::move(description); + user_full->is_changed = true; + } + if (user_full->description_photo != description_photo || + user_full->description_animation_file_id != description_animation_file_id) { + user_full->description_photo = std::move(description_photo); + user_full->description_animation_file_id = description_animation_file_id; + user_full->is_changed = true; + } + if (personal_channel_id != ChannelId() && + td_->chat_manager_->get_channel_type(personal_channel_id) != ChannelType::Broadcast) { + LOG(ERROR) << "Receive personal " << personal_channel_id << " of the type " + << static_cast(td_->chat_manager_->get_channel_type(personal_channel_id)); + personal_channel_id = ChannelId(); + } + if (user_full->personal_channel_id != personal_channel_id) { + user_full->personal_channel_id = personal_channel_id; + user_full->is_changed = true; + } + if (user_full->personal_channel_id != ChannelId()) { + auto personal_message_id = MessageId(ServerMessageId(user->personal_channel_message_)); + td_->messages_manager_->get_channel_difference_if_needed(DialogId(user_full->personal_channel_id), + personal_message_id, "on_get_user_full personal chat"); + } + + auto photo = get_photo(td_, std::move(user->profile_photo_), DialogId(user_id)); + auto personal_photo = get_photo(td_, std::move(user->personal_photo_), DialogId(user_id)); + auto fallback_photo = get_photo(td_, std::move(user->fallback_photo_), DialogId(user_id)); + // do_update_user_photo should be a no-op if server sent consistent data + const Photo *photo_ptr = nullptr; + bool is_personal = false; + if (!personal_photo.is_empty()) { + photo_ptr = &personal_photo; + is_personal = true; + } else if (!photo.is_empty()) { + photo_ptr = &photo; + } else { + photo_ptr = &fallback_photo; + } + bool is_photo_empty = photo_ptr->is_empty(); + do_update_user_photo(u, user_id, + as_profile_photo(td_->file_manager_.get(), user_id, u->access_hash, *photo_ptr, is_personal), + false, "on_get_user_full"); + if (photo != user_full->photo) { + user_full->photo = std::move(photo); + user_full->is_changed = true; + } + if (personal_photo != user_full->personal_photo) { + user_full->personal_photo = std::move(personal_photo); + user_full->is_changed = true; + } + if (fallback_photo != user_full->fallback_photo) { + user_full->fallback_photo = std::move(fallback_photo); + user_full->is_changed = true; + } + if (!user_full->photo.is_empty()) { + register_user_photo(u, user_id, user_full->photo); + } + if (user_id == get_my_id() && !user_full->fallback_photo.is_empty()) { + register_suggested_profile_photo(user_full->fallback_photo); + } + if (is_photo_empty) { + drop_user_photos(user_id, true, "on_get_user_full"); + } + + // User must be updated before UserFull + if (u->is_changed) { + LOG(ERROR) << "Receive inconsistent chatPhoto and chatPhotoInfo for " << user_id; + update_user(u, user_id); + } + + user_full->is_update_user_full_sent = true; + update_user_full(user_full, user_id, "on_get_user_full"); + + // update peer settings after UserFull is created and updated to not update twice need_phone_number_privacy_exception + td_->messages_manager_->on_get_peer_settings(DialogId(user_id), std::move(user->settings_)); +} + +FileSourceId UserManager::get_user_full_file_source_id(UserId user_id) { + if (!user_id.is_valid()) { + return FileSourceId(); + } + + auto user_full = get_user_full(user_id); + if (user_full != nullptr) { + VLOG(file_references) << "Don't need to create file source for full " << user_id; + // user full was already added, source ID was registered and shouldn't be needed + return user_full->is_update_user_full_sent ? FileSourceId() : user_full->file_source_id; + } + + auto &source_id = user_full_file_source_ids_[user_id]; + if (!source_id.is_valid()) { + source_id = td_->file_reference_manager_->create_user_full_file_source(user_id); + } + VLOG(file_references) << "Return " << source_id << " for full " << user_id; + return source_id; +} + +void UserManager::save_user_full(const UserFull *user_full, UserId user_id) { + if (!G()->use_chat_info_database()) { + return; + } + + LOG(INFO) << "Trying to save to database full " << user_id; + CHECK(user_full != nullptr); + G()->td_db()->get_sqlite_pmc()->set(get_user_full_database_key(user_id), get_user_full_database_value(user_full), + Auto()); +} + +string UserManager::get_user_full_database_key(UserId user_id) { + return PSTRING() << "usf" << user_id.get(); +} + +string UserManager::get_user_full_database_value(const UserFull *user_full) { + return log_event_store(*user_full).as_slice().str(); +} + +void UserManager::on_load_user_full_from_database(UserId user_id, string value) { + LOG(INFO) << "Successfully loaded full " << user_id << " of size " << value.size() << " from database"; + // G()->td_db()->get_sqlite_pmc()->erase(get_user_full_database_key(user_id), Auto()); + // return; + + if (get_user_full(user_id) != nullptr || value.empty()) { + return; + } + + UserFull *user_full = add_user_full(user_id); + auto status = log_event_parse(*user_full, value); + if (status.is_error()) { + // can't happen unless database is broken + LOG(ERROR) << "Repair broken full " << user_id << ' ' << format::as_hex_dump<4>(Slice(value)); + + // just clean all known data about the user and pretend that there was nothing in the database + users_full_.erase(user_id); + G()->td_db()->get_sqlite_pmc()->erase(get_user_full_database_key(user_id), Auto()); + return; + } + + Dependencies dependencies; + dependencies.add(user_id); + if (user_full->business_info != nullptr) { + user_full->business_info->add_dependencies(dependencies); + } + dependencies.add(user_full->personal_channel_id); + if (!dependencies.resolve_force(td_, "on_load_user_full_from_database")) { + users_full_.erase(user_id); + G()->td_db()->get_sqlite_pmc()->erase(get_user_full_database_key(user_id), Auto()); + return; + } + + if (user_full->need_phone_number_privacy_exception && is_user_contact(user_id)) { + user_full->need_phone_number_privacy_exception = false; + } + + User *u = get_user(user_id); + CHECK(u != nullptr); + drop_user_full_photos(user_full, user_id, u->photo.id, "on_load_user_full_from_database"); + if (!user_full->photo.is_empty()) { + register_user_photo(u, user_id, user_full->photo); + } + if (user_id == get_my_id() && !user_full->fallback_photo.is_empty()) { + register_suggested_profile_photo(user_full->fallback_photo); + } + + td_->group_call_manager_->on_update_dialog_about(DialogId(user_id), user_full->about, false); + + user_full->is_update_user_full_sent = true; + update_user_full(user_full, user_id, "on_load_user_full_from_database", true); + + if (is_user_deleted(u)) { + drop_user_full(user_id); + } else if (user_full->expires_at == 0.0) { + reload_user_full(user_id, Auto(), "on_load_user_full_from_database"); + } +} + +int64 UserManager::get_user_full_profile_photo_id(const UserFull *user_full) { + if (!user_full->personal_photo.is_empty()) { + return user_full->personal_photo.id.get(); + } + if (!user_full->photo.is_empty()) { + return user_full->photo.id.get(); + } + return user_full->fallback_photo.id.get(); +} + +void UserManager::drop_user_full_photos(UserFull *user_full, UserId user_id, int64 expected_photo_id, + const char *source) { + if (user_full == nullptr) { + return; + } + LOG(INFO) << "Expect full photo " << expected_photo_id << " from " << source; + for (auto photo_ptr : {&user_full->personal_photo, &user_full->photo, &user_full->fallback_photo}) { + if (photo_ptr->is_empty()) { + continue; + } + if (expected_photo_id == 0) { + // if profile photo is empty, we must drop the full photo + *photo_ptr = Photo(); + user_full->is_changed = true; + } else if (expected_photo_id != photo_ptr->id.get()) { + LOG(INFO) << "Drop full photo " << photo_ptr->id.get(); + // if full profile photo is unknown, we must drop the full photo + *photo_ptr = Photo(); + user_full->is_changed = true; + } else { + // nothing to drop + break; + } + } + if (expected_photo_id != get_user_full_profile_photo_id(user_full)) { + user_full->expires_at = 0.0; + } + if (user_full->is_update_user_full_sent) { + update_user_full(user_full, user_id, "drop_user_full_photos"); + } +} + +void UserManager::drop_user_photos(UserId user_id, bool is_empty, const char *source) { + LOG(INFO) << "Drop user photos to " << (is_empty ? "empty" : "unknown") << " from " << source; + auto user_photos = user_photos_.get_pointer(user_id); + if (user_photos != nullptr) { + int32 new_count = is_empty ? 0 : -1; + if (user_photos->count == new_count) { + CHECK(user_photos->photos.empty()); + CHECK(user_photos->offset == user_photos->count); + } else { + LOG(INFO) << "Drop photos of " << user_id << " to " << (is_empty ? "empty" : "unknown") << " from " << source; + user_photos->photos.clear(); + user_photos->count = new_count; + user_photos->offset = user_photos->count; + } + } +} + +void UserManager::drop_user_full(UserId user_id) { + auto user_full = get_user_full_force(user_id, "drop_user_full"); + + drop_user_photos(user_id, false, "drop_user_full"); + + if (user_full == nullptr) { + return; + } + + user_full->expires_at = 0.0; + + user_full->photo = Photo(); + user_full->personal_photo = Photo(); + user_full->fallback_photo = Photo(); + // user_full->is_blocked = false; + // user_full->is_blocked_for_stories = false; + user_full->can_be_called = false; + user_full->supports_video_calls = false; + user_full->has_private_calls = false; + user_full->need_phone_number_privacy_exception = false; + user_full->wallpaper_overridden = false; + user_full->about = string(); + user_full->description = string(); + user_full->description_photo = Photo(); + user_full->description_animation_file_id = FileId(); + user_full->menu_button = nullptr; + user_full->commands.clear(); + user_full->common_chat_count = 0; + user_full->personal_channel_id = ChannelId(); + user_full->business_info = nullptr; + user_full->private_forward_name.clear(); + user_full->group_administrator_rights = {}; + user_full->broadcast_administrator_rights = {}; + user_full->premium_gift_options.clear(); + user_full->voice_messages_forbidden = false; + user_full->has_pinned_stories = false; + user_full->read_dates_private = false; + user_full->contact_require_premium = false; + user_full->birthdate = {}; + user_full->sponsored_enabled = false; + user_full->has_preview_medias = false; + user_full->privacy_policy_url = string(); + user_full->is_changed = true; + + update_user_full(user_full, user_id, "drop_user_full"); + td_->group_call_manager_->on_update_dialog_about(DialogId(user_id), user_full->about, true); +} + +bool UserManager::have_secret_chat(SecretChatId secret_chat_id) const { + return secret_chats_.count(secret_chat_id) > 0; +} + +const UserManager::SecretChat *UserManager::get_secret_chat(SecretChatId secret_chat_id) const { + return secret_chats_.get_pointer(secret_chat_id); +} + +UserManager::SecretChat *UserManager::get_secret_chat(SecretChatId secret_chat_id) { + return secret_chats_.get_pointer(secret_chat_id); +} + +UserManager::SecretChat *UserManager::add_secret_chat(SecretChatId secret_chat_id) { + CHECK(secret_chat_id.is_valid()); + auto &secret_chat_ptr = secret_chats_[secret_chat_id]; + if (secret_chat_ptr == nullptr) { + secret_chat_ptr = make_unique(); + } + return secret_chat_ptr.get(); +} + +bool UserManager::have_secret_chat_force(SecretChatId secret_chat_id, const char *source) { + return get_secret_chat_force(secret_chat_id, source) != nullptr; +} + +UserManager::SecretChat *UserManager::get_secret_chat_force(SecretChatId secret_chat_id, const char *source) { + if (!secret_chat_id.is_valid()) { + return nullptr; + } + + SecretChat *c = get_secret_chat(secret_chat_id); + if (c != nullptr) { + if (!have_user_force(c->user_id, source)) { + LOG(ERROR) << "Can't find " << c->user_id << " from " << secret_chat_id << " from " << source; + } + return c; + } + if (!G()->use_chat_info_database()) { + return nullptr; + } + if (loaded_from_database_secret_chats_.count(secret_chat_id)) { + return nullptr; + } + + LOG(INFO) << "Trying to load " << secret_chat_id << " from database from " << source; + on_load_secret_chat_from_database( + secret_chat_id, G()->td_db()->get_sqlite_sync_pmc()->get(get_secret_chat_database_key(secret_chat_id)), true); + return get_secret_chat(secret_chat_id); +} + +bool UserManager::get_secret_chat(SecretChatId secret_chat_id, bool force, Promise &&promise) { + if (!secret_chat_id.is_valid()) { + promise.set_error(Status::Error(400, "Invalid secret chat identifier")); + return false; + } + + if (!have_secret_chat(secret_chat_id)) { + if (!force && G()->use_chat_info_database()) { + send_closure_later(actor_id(this), &UserManager::load_secret_chat_from_database, nullptr, secret_chat_id, + std::move(promise)); + return false; + } + + promise.set_error(Status::Error(400, "Secret chat not found")); + return false; + } + + promise.set_value(Unit()); + return true; +} + +void UserManager::save_secret_chat(SecretChat *c, SecretChatId secret_chat_id, bool from_binlog) { + if (!G()->use_chat_info_database()) { + return; + } + CHECK(c != nullptr); + if (!c->is_saved) { + if (!from_binlog) { + auto log_event = SecretChatLogEvent(secret_chat_id, c); + auto storer = get_log_event_storer(log_event); + if (c->log_event_id == 0) { + c->log_event_id = binlog_add(G()->td_db()->get_binlog(), LogEvent::HandlerType::SecretChatInfos, storer); + } else { + binlog_rewrite(G()->td_db()->get_binlog(), c->log_event_id, LogEvent::HandlerType::SecretChatInfos, storer); + } + } + + save_secret_chat_to_database(c, secret_chat_id); + return; + } +} + +string UserManager::get_secret_chat_database_key(SecretChatId secret_chat_id) { + return PSTRING() << "sc" << secret_chat_id.get(); +} + +string UserManager::get_secret_chat_database_value(const SecretChat *c) { + return log_event_store(*c).as_slice().str(); +} + +void UserManager::save_secret_chat_to_database(SecretChat *c, SecretChatId secret_chat_id) { + CHECK(c != nullptr); + if (c->is_being_saved) { + return; + } + if (loaded_from_database_secret_chats_.count(secret_chat_id)) { + save_secret_chat_to_database_impl(c, secret_chat_id, get_secret_chat_database_value(c)); + return; + } + if (load_secret_chat_from_database_queries_.count(secret_chat_id) != 0) { + return; + } + + load_secret_chat_from_database_impl(secret_chat_id, Auto()); +} + +void UserManager::save_secret_chat_to_database_impl(SecretChat *c, SecretChatId secret_chat_id, string value) { + CHECK(c != nullptr); + CHECK(load_secret_chat_from_database_queries_.count(secret_chat_id) == 0); + CHECK(!c->is_being_saved); + c->is_being_saved = true; + c->is_saved = true; + LOG(INFO) << "Trying to save to database " << secret_chat_id; + G()->td_db()->get_sqlite_pmc()->set(get_secret_chat_database_key(secret_chat_id), std::move(value), + PromiseCreator::lambda([secret_chat_id](Result<> result) { + send_closure(G()->user_manager(), &UserManager::on_save_secret_chat_to_database, + secret_chat_id, result.is_ok()); + })); +} + +void UserManager::on_save_secret_chat_to_database(SecretChatId secret_chat_id, bool success) { + if (G()->close_flag()) { + return; + } + + SecretChat *c = get_secret_chat(secret_chat_id); + CHECK(c != nullptr); + CHECK(c->is_being_saved); + CHECK(load_secret_chat_from_database_queries_.count(secret_chat_id) == 0); + c->is_being_saved = false; + + if (!success) { + LOG(ERROR) << "Failed to save " << secret_chat_id << " to database"; + c->is_saved = false; + } else { + LOG(INFO) << "Successfully saved " << secret_chat_id << " to database"; + } + if (c->is_saved) { + if (c->log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), c->log_event_id); + c->log_event_id = 0; + } + } else { + save_secret_chat(c, secret_chat_id, c->log_event_id != 0); + } +} + +void UserManager::load_secret_chat_from_database(SecretChat *c, SecretChatId secret_chat_id, Promise promise) { + if (loaded_from_database_secret_chats_.count(secret_chat_id)) { + promise.set_value(Unit()); + return; + } + + CHECK(c == nullptr || !c->is_being_saved); + load_secret_chat_from_database_impl(secret_chat_id, std::move(promise)); +} + +void UserManager::load_secret_chat_from_database_impl(SecretChatId secret_chat_id, Promise promise) { + LOG(INFO) << "Load " << secret_chat_id << " from database"; + auto &load_secret_chat_queries = load_secret_chat_from_database_queries_[secret_chat_id]; + load_secret_chat_queries.push_back(std::move(promise)); + if (load_secret_chat_queries.size() == 1u) { + G()->td_db()->get_sqlite_pmc()->get( + get_secret_chat_database_key(secret_chat_id), PromiseCreator::lambda([secret_chat_id](string value) { + send_closure(G()->user_manager(), &UserManager::on_load_secret_chat_from_database, secret_chat_id, + std::move(value), false); + })); + } +} + +void UserManager::on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value, bool force) { + if (G()->close_flag() && !force) { + // the secret chat is in Binlog and will be saved after restart + return; + } + + CHECK(secret_chat_id.is_valid()); + if (!loaded_from_database_secret_chats_.insert(secret_chat_id).second) { + return; + } + + auto it = load_secret_chat_from_database_queries_.find(secret_chat_id); + vector> promises; + if (it != load_secret_chat_from_database_queries_.end()) { + promises = std::move(it->second); + CHECK(!promises.empty()); + load_secret_chat_from_database_queries_.erase(it); + } + + LOG(INFO) << "Successfully loaded " << secret_chat_id << " of size " << value.size() << " from database"; + // G()->td_db()->get_sqlite_pmc()->erase(get_secret_chat_database_key(secret_chat_id), Auto()); + // return; + + SecretChat *c = get_secret_chat(secret_chat_id); + if (c == nullptr) { + if (!value.empty()) { + c = add_secret_chat(secret_chat_id); + + if (log_event_parse(*c, value).is_error()) { + LOG(ERROR) << "Failed to load " << secret_chat_id << " from database"; + secret_chats_.erase(secret_chat_id); + } else { + c->is_saved = true; + update_secret_chat(c, secret_chat_id, true, true); + } + } + } else { + CHECK(!c->is_saved); // secret chat can't be saved before load completes + CHECK(!c->is_being_saved); + auto new_value = get_secret_chat_database_value(c); + if (value != new_value) { + save_secret_chat_to_database_impl(c, secret_chat_id, std::move(new_value)); + } else if (c->log_event_id != 0) { + binlog_erase(G()->td_db()->get_binlog(), c->log_event_id); + c->log_event_id = 0; + } + } + + // TODO load users asynchronously + if (c != nullptr && !have_user_force(c->user_id, "on_load_secret_chat_from_database")) { + LOG(ERROR) << "Can't find " << c->user_id << " from " << secret_chat_id; + } + + set_promises(promises); +} + +void UserManager::create_new_secret_chat(UserId user_id, Promise> &&promise) { + TRY_RESULT_PROMISE(promise, input_user, get_input_user(user_id)); + if (input_user->get_id() != telegram_api::inputUser::ID) { + return promise.set_error(Status::Error(400, "Can't create secret chat with the user")); + } + auto user = static_cast(input_user.get()); + + send_closure( + G()->secret_chats_manager(), &SecretChatsManager::create_chat, UserId(user->user_id_), user->access_hash_, + PromiseCreator::lambda( + [actor_id = actor_id(this), promise = std::move(promise)](Result r_secret_chat_id) mutable { + if (r_secret_chat_id.is_error()) { + return promise.set_error(r_secret_chat_id.move_as_error()); + } + send_closure(actor_id, &UserManager::on_create_new_secret_chat, r_secret_chat_id.ok(), std::move(promise)); + })); +} + +void UserManager::on_create_new_secret_chat(SecretChatId secret_chat_id, + Promise> &&promise) { + TRY_STATUS_PROMISE(promise, G()->close_status()); + CHECK(secret_chat_id.is_valid()); + DialogId dialog_id(secret_chat_id); + td_->dialog_manager_->force_create_dialog(dialog_id, "on_create_new_secret_chat"); + promise.set_value(td_->messages_manager_->get_chat_object(dialog_id, "on_create_new_secret_chat")); +} + +void UserManager::update_user(User *u, UserId user_id, bool from_binlog, bool from_database) { + CHECK(u != nullptr); + + if (u->is_being_updated) { + LOG(ERROR) << "Detected recursive update of " << user_id; + } + u->is_being_updated = true; + SCOPE_EXIT { + u->is_being_updated = false; + }; + + if (user_id == get_my_id()) { + if (td_->option_manager_->get_option_boolean("is_premium") != u->is_premium) { + td_->option_manager_->set_option_boolean("is_premium", u->is_premium); + send_closure(td_->config_manager_, &ConfigManager::request_config, true); + if (!td_->auth_manager_->is_bot()) { + td_->reaction_manager_->reload_reaction_list(ReactionListType::Top, "update_user is_premium"); + td_->messages_manager_->update_is_translatable(u->is_premium); + } + } + } + if (u->is_name_changed || u->is_username_changed || u->is_is_contact_changed) { + update_contacts_hints(u, user_id, from_database); + u->is_username_changed = false; + } + if (u->is_is_contact_changed) { + td_->messages_manager_->on_dialog_user_is_contact_updated(DialogId(user_id), u->is_contact); + send_closure_later(td_->story_manager_actor_, &StoryManager::on_dialog_active_stories_order_updated, + DialogId(user_id), "is_contact"); + if (is_user_contact(u, user_id, false)) { + auto user_full = get_user_full(user_id); + if (user_full != nullptr && user_full->need_phone_number_privacy_exception) { + on_update_user_full_need_phone_number_privacy_exception(user_full, user_id, false); + update_user_full(user_full, user_id, "update_user"); + } + } + u->is_is_contact_changed = false; + } + if (u->is_is_mutual_contact_changed) { + if (!from_database && u->is_update_user_sent) { + send_closure_later(td_->story_manager_actor_, &StoryManager::reload_dialog_expiring_stories, DialogId(user_id)); + } + u->is_is_mutual_contact_changed = false; + } + if (u->is_is_deleted_changed) { + td_->messages_manager_->on_dialog_user_is_deleted_updated(DialogId(user_id), u->is_deleted); + if (u->is_deleted) { + auto user_full = get_user_full(user_id); // must not load user_full from database before sending updateUser + if (user_full != nullptr) { + u->is_full_info_changed = false; + drop_user_full(user_id); + } + } + u->is_is_deleted_changed = false; + } + if (u->is_is_premium_changed) { + send_closure_later(td_->story_manager_actor_, &StoryManager::on_dialog_active_stories_order_updated, + DialogId(user_id), "is_premium"); + u->is_is_premium_changed = false; + } + if (u->is_name_changed) { + auto messages_manager = td_->messages_manager_.get(); + messages_manager->on_dialog_title_updated(DialogId(user_id)); + for_each_secret_chat_with_user(user_id, [messages_manager](SecretChatId secret_chat_id) { + messages_manager->on_dialog_title_updated(DialogId(secret_chat_id)); + }); + u->is_name_changed = false; + } + if (u->is_photo_changed) { + auto messages_manager = td_->messages_manager_.get(); + messages_manager->on_dialog_photo_updated(DialogId(user_id)); + for_each_secret_chat_with_user(user_id, [messages_manager](SecretChatId secret_chat_id) { + messages_manager->on_dialog_photo_updated(DialogId(secret_chat_id)); + }); + u->is_photo_changed = false; + } + if (u->is_accent_color_changed) { + auto messages_manager = td_->messages_manager_.get(); + messages_manager->on_dialog_accent_colors_updated(DialogId(user_id)); + for_each_secret_chat_with_user(user_id, [messages_manager](SecretChatId secret_chat_id) { + messages_manager->on_dialog_accent_colors_updated(DialogId(secret_chat_id)); + }); + u->is_accent_color_changed = false; + } + if (u->is_phone_number_changed) { + if (!u->phone_number.empty() && !td_->auth_manager_->is_bot()) { + resolved_phone_numbers_[u->phone_number] = user_id; + } + u->is_phone_number_changed = false; + } + auto unix_time = G()->unix_time(); + if (u->is_status_changed && user_id != get_my_id()) { + auto left_time = get_user_was_online(u, user_id, unix_time) - G()->server_time(); + if (left_time >= 0 && left_time < 30 * 86400) { + left_time += 2.0; // to guarantee expiration + LOG(DEBUG) << "Set online timeout for " << user_id << " in " << left_time << " seconds"; + user_online_timeout_.set_timeout_in(user_id.get(), left_time); + } else { + LOG(DEBUG) << "Cancel online timeout for " << user_id; + user_online_timeout_.cancel_timeout(user_id.get()); + } + } + if (u->is_stories_hidden_changed) { + send_closure_later(td_->story_manager_actor_, &StoryManager::on_dialog_active_stories_order_updated, + DialogId(user_id), "stories_hidden"); + u->is_stories_hidden_changed = false; + } + if (!td_->auth_manager_->is_bot()) { + if (u->restriction_reasons.empty()) { + restricted_user_ids_.erase(user_id); + } else { + restricted_user_ids_.insert(user_id); + } + } + + auto effective_emoji_status = u->emoji_status.get_effective_emoji_status(u->is_premium, unix_time); + if (effective_emoji_status != u->last_sent_emoji_status) { + if (!u->last_sent_emoji_status.is_empty()) { + user_emoji_status_timeout_.cancel_timeout(user_id.get()); + } + u->last_sent_emoji_status = effective_emoji_status; + if (!u->last_sent_emoji_status.is_empty()) { + auto until_date = u->last_sent_emoji_status.get_until_date(); + auto left_time = until_date - unix_time; + if (left_time >= 0 && left_time < 30 * 86400) { + user_emoji_status_timeout_.set_timeout_in(user_id.get(), left_time); + } + } + u->is_changed = true; + + auto messages_manager = td_->messages_manager_.get(); + messages_manager->on_dialog_emoji_status_updated(DialogId(user_id)); + for_each_secret_chat_with_user(user_id, [messages_manager](SecretChatId secret_chat_id) { + messages_manager->on_dialog_emoji_status_updated(DialogId(secret_chat_id)); + }); + u->is_emoji_status_changed = false; + } else if (u->is_emoji_status_changed) { + LOG(DEBUG) << "Emoji status for " << user_id << " has changed"; + u->need_save_to_database = true; + u->is_emoji_status_changed = false; + } + + if (u->is_deleted) { + td_->inline_queries_manager_->remove_recent_inline_bot(user_id, Promise<>()); + } + if (from_binlog || from_database) { + td_->dialog_manager_->on_dialog_usernames_received(DialogId(user_id), u->usernames, true); + } + + LOG(DEBUG) << "Update " << user_id << ": need_save_to_database = " << u->need_save_to_database + << ", is_changed = " << u->is_changed << ", is_status_changed = " << u->is_status_changed + << ", from_binlog = " << from_binlog << ", from_database = " << from_database; + u->need_save_to_database |= u->is_changed; + if (u->need_save_to_database) { + if (!from_database) { + u->is_saved = false; + } + u->need_save_to_database = false; + } + if (u->is_changed) { + send_closure(G()->td(), &Td::send_update, get_update_user_object(user_id, u)); + u->is_changed = false; + u->is_status_changed = false; + u->is_update_user_sent = true; + } + if (u->is_status_changed) { + if (!from_database) { + u->is_status_saved = false; + } + CHECK(u->is_update_user_sent); + send_closure( + G()->td(), &Td::send_update, + td_api::make_object(user_id.get(), get_user_status_object(user_id, u, unix_time))); + u->is_status_changed = false; + } + if (u->is_online_status_changed) { + td_->dialog_participant_manager_->update_user_online_member_count(user_id); + u->is_online_status_changed = false; + } + + if (!from_database) { + save_user(u, user_id, from_binlog); + } + + if (u->cache_version != User::CACHE_VERSION && !u->is_repaired && + have_input_peer_user(u, user_id, AccessRights::Read) && !G()->close_flag()) { + u->is_repaired = true; + + LOG(INFO) << "Repairing cache of " << user_id; + reload_user(user_id, Promise(), "update_user"); + } + + if (u->is_full_info_changed) { + u->is_full_info_changed = false; + auto user_full = get_user_full(user_id); + if (user_full != nullptr) { + user_full->need_send_update = true; + update_user_full(user_full, user_id, "update_user is_full_info_changed"); + reload_user_full(user_id, Promise(), "update_user"); + } + } +} + +void UserManager::update_secret_chat(SecretChat *c, SecretChatId secret_chat_id, bool from_binlog, bool from_database) { + CHECK(c != nullptr); + + if (c->is_being_updated) { + LOG(ERROR) << "Detected recursive update of " << secret_chat_id; + } + c->is_being_updated = true; + SCOPE_EXIT { + c->is_being_updated = false; + }; + + LOG(DEBUG) << "Update " << secret_chat_id << ": need_save_to_database = " << c->need_save_to_database + << ", is_changed = " << c->is_changed; + c->need_save_to_database |= c->is_changed; + if (c->need_save_to_database) { + if (!from_database) { + c->is_saved = false; + } + c->need_save_to_database = false; + + DialogId dialog_id(secret_chat_id); + send_closure_later(G()->messages_manager(), &MessagesManager::force_create_dialog, dialog_id, "update secret chat", + true, true); + if (c->is_state_changed) { + send_closure_later(G()->messages_manager(), &MessagesManager::on_update_secret_chat_state, secret_chat_id, + c->state); + c->is_state_changed = false; + } + if (c->is_ttl_changed) { + send_closure_later(G()->messages_manager(), &MessagesManager::on_update_dialog_message_ttl, + DialogId(secret_chat_id), MessageTtl(c->ttl)); + c->is_ttl_changed = false; + } + } + if (c->is_changed) { + send_closure(G()->td(), &Td::send_update, get_update_secret_chat_object(secret_chat_id, c)); + c->is_changed = false; + } + + if (!from_database) { + save_secret_chat(c, secret_chat_id, from_binlog); + } +} + +void UserManager::update_user_full(UserFull *user_full, UserId user_id, const char *source, bool from_database) { + CHECK(user_full != nullptr); + + if (user_full->is_being_updated) { + LOG(ERROR) << "Detected recursive update of full " << user_id << " from " << source; + } + user_full->is_being_updated = true; + SCOPE_EXIT { + user_full->is_being_updated = false; + }; + + unavailable_user_fulls_.erase(user_id); // don't needed anymore + if (user_full->is_common_chat_count_changed) { + td_->common_dialog_manager_->drop_common_dialogs_cache(user_id); + user_full->is_common_chat_count_changed = false; + } + if (true) { + vector file_ids; + if (!user_full->personal_photo.is_empty()) { + append(file_ids, photo_get_file_ids(user_full->personal_photo)); + } + if (!user_full->fallback_photo.is_empty()) { + append(file_ids, photo_get_file_ids(user_full->fallback_photo)); + } + if (!user_full->description_photo.is_empty()) { + append(file_ids, photo_get_file_ids(user_full->description_photo)); + } + if (user_full->description_animation_file_id.is_valid()) { + file_ids.push_back(user_full->description_animation_file_id); + } + if (user_full->business_info != nullptr) { + append(file_ids, user_full->business_info->get_file_ids(td_)); + } + if (user_full->registered_file_ids != file_ids) { + auto &file_source_id = user_full->file_source_id; + if (!file_source_id.is_valid()) { + file_source_id = user_full_file_source_ids_.get(user_id); + if (file_source_id.is_valid()) { + VLOG(file_references) << "Move " << file_source_id << " inside of " << user_id; + user_full_file_source_ids_.erase(user_id); + } else { + VLOG(file_references) << "Need to create new file source for full " << user_id; + file_source_id = td_->file_reference_manager_->create_user_full_file_source(user_id); + } + } + + td_->file_manager_->change_files_source(file_source_id, user_full->registered_file_ids, file_ids); + user_full->registered_file_ids = std::move(file_ids); + } + } + + user_full->need_send_update |= user_full->is_changed; + user_full->need_save_to_database |= user_full->is_changed; + user_full->is_changed = false; + if (user_full->need_send_update || user_full->need_save_to_database) { + LOG(INFO) << "Update full " << user_id << " from " << source; + } + if (user_full->need_send_update) { + { + auto u = get_user(user_id); + CHECK(u == nullptr || u->is_update_user_sent); + } + if (!user_full->is_update_user_full_sent) { + LOG(ERROR) << "Send partial updateUserFullInfo for " << user_id << " from " << source; + user_full->is_update_user_full_sent = true; + } + send_closure(G()->td(), &Td::send_update, + td_api::make_object(get_user_id_object(user_id, "updateUserFullInfo"), + get_user_full_info_object(user_id, user_full))); + user_full->need_send_update = false; + + if (user_id == get_my_id() && !user_full->birthdate.is_empty() && !td_->auth_manager_->is_bot()) { + dismiss_suggested_action(SuggestedAction{SuggestedAction::Type::BirthdaySetup}, Promise()); + } + } + if (user_full->need_save_to_database) { + if (!from_database) { + save_user_full(user_full, user_id); + } + user_full->need_save_to_database = false; + } +} + +td_api::object_ptr UserManager::get_user_status_object(UserId user_id, const User *u, + int32 unix_time) const { + if (u->is_bot) { + return td_api::make_object(std::numeric_limits::max()); + } + + int32 was_online = get_user_was_online(u, user_id, unix_time); + switch (was_online) { + case -6: + case -3: + return td_api::make_object(was_online == -6); + case -5: + case -2: + return td_api::make_object(was_online == -5); + case -4: + case -1: + return td_api::make_object(was_online == -4); + case 0: + return td_api::make_object(); + default: { + int32 time = G()->unix_time(); + if (was_online > time) { + return td_api::make_object(was_online); + } else { + return td_api::make_object(was_online); + } + } + } +} + +bool UserManager::get_user_has_unread_stories(const User *u) { + CHECK(u != nullptr); + return u->max_active_story_id.get() > u->max_read_story_id.get(); +} + +td_api::object_ptr UserManager::get_update_user_object(UserId user_id, const User *u) const { + if (u == nullptr) { + return get_update_unknown_user_object(user_id); + } + return td_api::make_object(get_user_object(user_id, u)); +} + +td_api::object_ptr UserManager::get_update_unknown_user_object(UserId user_id) const { + auto have_access = user_id == get_my_id() || user_messages_.count(user_id) != 0; + return td_api::make_object(td_api::make_object( + user_id.get(), "", "", nullptr, "", td_api::make_object(), nullptr, + td_->theme_manager_->get_accent_color_id_object(AccentColorId(user_id)), 0, -1, 0, nullptr, false, false, false, + false, false, false, "", false, false, false, false, false, have_access, + td_api::make_object(), "", false)); +} + +int64 UserManager::get_user_id_object(UserId user_id, const char *source) const { + if (user_id.is_valid() && get_user(user_id) == nullptr && unknown_users_.count(user_id) == 0) { + LOG(ERROR) << "Have no information about " << user_id << " from " << source; + unknown_users_.insert(user_id); + send_closure(G()->td(), &Td::send_update, get_update_unknown_user_object(user_id)); + } + return user_id.get(); +} + +void UserManager::get_user_id_object_async(UserId user_id, Promise &&promise) { + promise.set_value(get_user_id_object(user_id, "get_user_id_object_async")); +} + +td_api::object_ptr UserManager::get_user_object(UserId user_id) const { + return get_user_object(user_id, get_user(user_id)); +} + +td_api::object_ptr UserManager::get_user_object(UserId user_id, const User *u) const { + if (u == nullptr) { + return nullptr; + } + td_api::object_ptr type; + if (u->is_deleted) { + type = td_api::make_object(); + } else if (u->is_bot) { + type = td_api::make_object( + u->can_be_edited_bot, u->can_join_groups, u->can_read_all_group_messages, u->has_main_app, u->is_inline_bot, + u->inline_query_placeholder, u->need_location_bot, u->is_business_bot, u->can_be_added_to_attach_menu, + u->bot_active_users); + } else { + type = td_api::make_object(); + } + + auto emoji_status = u->last_sent_emoji_status.get_emoji_status_object(); + auto have_access = user_id == get_my_id() || have_input_peer_user(u, user_id, AccessRights::Know); + auto restricts_new_chats = u->contact_require_premium && !u->is_mutual_contact; + return td_api::make_object( + user_id.get(), u->first_name, u->last_name, u->usernames.get_usernames_object(), u->phone_number, + get_user_status_object(user_id, u, G()->unix_time()), + get_profile_photo_object(td_->file_manager_.get(), u->photo), + td_->theme_manager_->get_accent_color_id_object(u->accent_color_id, AccentColorId(user_id)), + u->background_custom_emoji_id.get(), + td_->theme_manager_->get_profile_accent_color_id_object(u->profile_accent_color_id), + u->profile_background_custom_emoji_id.get(), std::move(emoji_status), u->is_contact, u->is_mutual_contact, + u->is_close_friend, u->is_verified, u->is_premium, u->is_support, + get_restriction_reason_description(u->restriction_reasons), u->is_scam, u->is_fake, + u->max_active_story_id.is_valid(), get_user_has_unread_stories(u), restricts_new_chats, have_access, + std::move(type), u->language_code, u->attach_menu_enabled); +} + +vector UserManager::get_user_ids_object(const vector &user_ids, const char *source) const { + return transform(user_ids, [this, source](UserId user_id) { return get_user_id_object(user_id, source); }); +} + +td_api::object_ptr UserManager::get_users_object(int32 total_count, + const vector &user_ids) const { + if (total_count == -1) { + total_count = narrow_cast(user_ids.size()); + } + return td_api::make_object(total_count, get_user_ids_object(user_ids, "get_users_object")); +} + +td_api::object_ptr UserManager::get_user_full_info_object(UserId user_id) const { + return get_user_full_info_object(user_id, get_user_full(user_id)); +} + +td_api::object_ptr UserManager::get_user_full_info_object(UserId user_id, + const UserFull *user_full) const { + CHECK(user_full != nullptr); + td_api::object_ptr bot_info; + const User *u = get_user(user_id); + bool is_bot = is_user_bot(u); + bool is_premium = is_user_premium(u); + td_api::object_ptr bio_object; + if (is_bot) { + auto menu_button = get_bot_menu_button_object(td_, user_full->menu_button.get()); + auto commands = + transform(user_full->commands, [](const auto &command) { return command.get_bot_command_object(); }); + bot_info = td_api::make_object( + user_full->about, user_full->description, + get_photo_object(td_->file_manager_.get(), user_full->description_photo), + td_->animations_manager_->get_animation_object(user_full->description_animation_file_id), + std::move(menu_button), std::move(commands), user_full->privacy_policy_url, + user_full->group_administrator_rights == AdministratorRights() + ? nullptr + : user_full->group_administrator_rights.get_chat_administrator_rights_object(), + user_full->broadcast_administrator_rights == AdministratorRights() + ? nullptr + : user_full->broadcast_administrator_rights.get_chat_administrator_rights_object(), + user_full->has_preview_medias, nullptr, nullptr, nullptr, nullptr); + if (u != nullptr && u->can_be_edited_bot && u->usernames.has_editable_username()) { + auto bot_username = u->usernames.get_editable_username(); + bot_info->edit_commands_link_ = td_api::make_object( + "botfather", PSTRING() << bot_username << "-commands", true); + bot_info->edit_description_link_ = td_api::make_object( + "botfather", PSTRING() << bot_username << "-intro", true); + bot_info->edit_description_media_link_ = td_api::make_object( + "botfather", PSTRING() << bot_username << "-intropic", true); + bot_info->edit_settings_link_ = + td_api::make_object("botfather", bot_username, true); + } + } else { + FormattedText bio; + bio.text = user_full->about; + bio.entities = find_entities(bio.text, true, true); + if (!is_premium) { + td::remove_if(bio.entities, [&](const MessageEntity &entity) { + if (entity.type == MessageEntity::Type::EmailAddress) { + return true; + } + if (entity.type == MessageEntity::Type::Url && + !LinkManager::is_internal_link(utf8_utf16_substr(bio.text, entity.offset, entity.length))) { + return true; + } + return false; + }); + } + bio_object = get_formatted_text_object(this, bio, true, 0); + } + auto voice_messages_forbidden = is_premium ? user_full->voice_messages_forbidden : false; + auto block_list_id = BlockListId(user_full->is_blocked, user_full->is_blocked_for_stories); + auto business_info = is_premium && user_full->business_info != nullptr + ? user_full->business_info->get_business_info_object(td_) + : nullptr; + int64 personal_chat_id = 0; + if (user_full->personal_channel_id.is_valid()) { + DialogId dialog_id(user_full->personal_channel_id); + td_->dialog_manager_->force_create_dialog(dialog_id, "get_user_full_info_object", true); + personal_chat_id = td_->dialog_manager_->get_chat_id_object(dialog_id, "get_user_full_info_object"); + } + return td_api::make_object( + get_chat_photo_object(td_->file_manager_.get(), user_full->personal_photo), + get_chat_photo_object(td_->file_manager_.get(), user_full->photo), + get_chat_photo_object(td_->file_manager_.get(), user_full->fallback_photo), block_list_id.get_block_list_object(), + user_full->can_be_called, user_full->supports_video_calls, user_full->has_private_calls, + !user_full->private_forward_name.empty(), voice_messages_forbidden, user_full->has_pinned_stories, + user_full->sponsored_enabled, user_full->need_phone_number_privacy_exception, user_full->wallpaper_overridden, + std::move(bio_object), user_full->birthdate.get_birthdate_object(), personal_chat_id, + get_premium_payment_options_object(user_full->premium_gift_options), user_full->common_chat_count, + std::move(business_info), std::move(bot_info)); +} + +td_api::object_ptr UserManager::get_update_contact_close_birthdays() const { + return td_api::make_object( + transform(contact_birthdates_.users_, [this](const std::pair &user) { + return td_api::make_object(get_user_id_object(user.first, "closeBirthdayUser"), + user.second.get_birthdate_object()); + })); +} + +td_api::object_ptr UserManager::get_secret_chat_state_object(SecretChatState state) { + switch (state) { + case SecretChatState::Waiting: + return td_api::make_object(); + case SecretChatState::Active: + return td_api::make_object(); + case SecretChatState::Closed: + case SecretChatState::Unknown: + return td_api::make_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +td_api::object_ptr UserManager::get_update_secret_chat_object(SecretChatId secret_chat_id, + const SecretChat *secret_chat) { + if (secret_chat == nullptr) { + return get_update_unknown_secret_chat_object(secret_chat_id); + } + return td_api::make_object(get_secret_chat_object(secret_chat_id, secret_chat)); +} + +td_api::object_ptr UserManager::get_update_unknown_secret_chat_object( + SecretChatId secret_chat_id) { + return td_api::make_object(td_api::make_object( + secret_chat_id.get(), 0, get_secret_chat_state_object(SecretChatState::Unknown), false, string(), 0)); +} + +int32 UserManager::get_secret_chat_id_object(SecretChatId secret_chat_id, const char *source) const { + if (secret_chat_id.is_valid() && get_secret_chat(secret_chat_id) == nullptr && + unknown_secret_chats_.count(secret_chat_id) == 0) { + LOG(ERROR) << "Have no information about " << secret_chat_id << " from " << source; + unknown_secret_chats_.insert(secret_chat_id); + send_closure(G()->td(), &Td::send_update, get_update_unknown_secret_chat_object(secret_chat_id)); + } + return secret_chat_id.get(); +} + +td_api::object_ptr UserManager::get_secret_chat_object(SecretChatId secret_chat_id) { + return get_secret_chat_object(secret_chat_id, get_secret_chat(secret_chat_id)); +} + +td_api::object_ptr UserManager::get_secret_chat_object(SecretChatId secret_chat_id, + const SecretChat *secret_chat) { + if (secret_chat == nullptr) { + return nullptr; + } + get_user_force(secret_chat->user_id, "get_secret_chat_object"); + return get_secret_chat_object_const(secret_chat_id, secret_chat); +} + +td_api::object_ptr UserManager::get_secret_chat_object_const(SecretChatId secret_chat_id, + const SecretChat *secret_chat) const { + return td_api::make_object(secret_chat_id.get(), + get_user_id_object(secret_chat->user_id, "secretChat"), + get_secret_chat_state_object(secret_chat->state), + secret_chat->is_outbound, secret_chat->key_hash, secret_chat->layer); +} + +void UserManager::get_current_state(vector> &updates) const { + for (auto user_id : unknown_users_) { + if (!have_min_user(user_id)) { + updates.push_back(get_update_unknown_user_object(user_id)); + } + } + for (auto secret_chat_id : unknown_secret_chats_) { + if (!have_secret_chat(secret_chat_id)) { + updates.push_back(get_update_unknown_secret_chat_object(secret_chat_id)); + } + } + + users_.foreach([&](const UserId &user_id, const unique_ptr &user) { + updates.push_back(get_update_user_object(user_id, user.get())); + }); + // secret chat objects contain user_id, so they must be sent after users + secret_chats_.foreach([&](const SecretChatId &secret_chat_id, const unique_ptr &secret_chat) { + updates.push_back( + td_api::make_object(get_secret_chat_object_const(secret_chat_id, secret_chat.get()))); + }); + + users_full_.foreach([&](const UserId &user_id, const unique_ptr &user_full) { + updates.push_back(td_api::make_object( + user_id.get(), get_user_full_info_object(user_id, user_full.get()))); + }); + + if (!contact_birthdates_.users_.empty()) { + updates.push_back(get_update_contact_close_birthdays()); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/UserManager.h b/protocols/Telegram/tdlib/td/td/telegram/UserManager.h new file mode 100644 index 0000000000..694821859d --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/UserManager.h @@ -0,0 +1,1130 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/AccentColorId.h" +#include "td/telegram/AccessRights.h" +#include "td/telegram/Birthdate.h" +#include "td/telegram/BotCommand.h" +#include "td/telegram/BotMenuButton.h" +#include "td/telegram/ChannelId.h" +#include "td/telegram/Contact.h" +#include "td/telegram/CustomEmojiId.h" +#include "td/telegram/DialogId.h" +#include "td/telegram/DialogLocation.h" +#include "td/telegram/DialogParticipant.h" +#include "td/telegram/EmojiStatus.h" +#include "td/telegram/files/FileId.h" +#include "td/telegram/files/FileSourceId.h" +#include "td/telegram/FolderId.h" +#include "td/telegram/MessageFullId.h" +#include "td/telegram/Photo.h" +#include "td/telegram/PremiumGiftOption.h" +#include "td/telegram/QueryCombiner.h" +#include "td/telegram/QueryMerger.h" +#include "td/telegram/RestrictionReason.h" +#include "td/telegram/SecretChatId.h" +#include "td/telegram/StoryId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" +#include "td/telegram/Usernames.h" + +#include "td/actor/actor.h" +#include "td/actor/MultiPromise.h" +#include "td/actor/MultiTimeout.h" + +#include "td/utils/common.h" +#include "td/utils/FlatHashMap.h" +#include "td/utils/FlatHashSet.h" +#include "td/utils/HashTableUtils.h" +#include "td/utils/Hints.h" +#include "td/utils/Promise.h" +#include "td/utils/Status.h" +#include "td/utils/StringBuilder.h" +#include "td/utils/Time.h" +#include "td/utils/WaitFreeHashMap.h" +#include "td/utils/WaitFreeHashSet.h" + +#include +#include +#include + +namespace td { + +struct BinlogEvent; +class BusinessAwayMessage; +class BusinessGreetingMessage; +class BusinessInfo; +class BusinessIntro; +class BusinessWorkHours; +class Td; + +class UserManager final : public Actor { + public: + UserManager(Td *td, ActorShared<> parent); + UserManager(const UserManager &) = delete; + UserManager &operator=(const UserManager &) = delete; + UserManager(UserManager &&) = delete; + UserManager &operator=(UserManager &&) = delete; + ~UserManager() final; + + static UserId get_user_id(const telegram_api::object_ptr &user); + + static UserId load_my_id(); + + UserId get_my_id() const; + + static UserId get_service_notifications_user_id(); + + UserId add_service_notifications_user(); + + static UserId get_replies_bot_user_id(); + + static UserId get_anonymous_bot_user_id(); + + static UserId get_channel_bot_user_id(); + + static UserId get_anti_spam_bot_user_id(); + + UserId add_anonymous_bot_user(); + + UserId add_channel_bot_user(); + + struct MyOnlineStatusInfo { + bool is_online_local = false; + bool is_online_remote = false; + int32 was_online_local = 0; + int32 was_online_remote = 0; + }; + MyOnlineStatusInfo get_my_online_status() const; + + void set_my_online_status(bool is_online, bool send_update, bool is_local); + + void on_get_user(telegram_api::object_ptr &&user, const char *source); + + void on_get_users(vector> &&users, const char *source); + + void on_binlog_user_event(BinlogEvent &&event); + + void on_binlog_secret_chat_event(BinlogEvent &&event); + + void on_update_user_name(UserId user_id, string &&first_name, string &&last_name, Usernames &&usernames); + + void on_update_user_phone_number(UserId user_id, string &&phone_number); + + void register_suggested_profile_photo(const Photo &photo); + + void on_update_user_emoji_status(UserId user_id, telegram_api::object_ptr &&emoji_status); + + void on_update_user_story_ids(UserId user_id, StoryId max_active_story_id, StoryId max_read_story_id); + + void on_update_user_max_read_story_id(UserId user_id, StoryId max_read_story_id); + + void on_update_user_stories_hidden(UserId user_id, bool stories_hidden); + + void on_update_user_online(UserId user_id, telegram_api::object_ptr &&status); + + void on_update_user_local_was_online(UserId user_id, int32 local_was_online); + + // use on_update_dialog_is_blocked instead + void on_update_user_is_blocked(UserId user_id, bool is_blocked, bool is_blocked_for_stories); + + void on_update_user_has_pinned_stories(UserId user_id, bool has_pinned_stories); + + void on_update_user_common_chat_count(UserId user_id, int32 common_chat_count); + + void on_update_my_user_location(DialogLocation &&location); + + void on_update_my_user_work_hours(BusinessWorkHours &&work_hours); + + void on_update_my_user_away_message(BusinessAwayMessage &&away_message); + + void on_update_my_user_greeting_message(BusinessGreetingMessage &&greeting_message); + + void on_update_my_user_intro(BusinessIntro &&intro); + + void on_update_user_commands(UserId user_id, + vector> &&bot_commands); + + void on_update_user_need_phone_number_privacy_exception(UserId user_id, bool need_phone_number_privacy_exception); + + void on_update_user_wallpaper_overridden(UserId user_id, bool wallpaper_overridden); + + void on_update_bot_menu_button(UserId bot_user_id, + telegram_api::object_ptr &&bot_menu_button); + + void on_update_bot_has_preview_medias(UserId bot_user_id, bool has_preview_medias); + + void on_update_secret_chat(SecretChatId secret_chat_id, int64 access_hash, UserId user_id, SecretChatState state, + bool is_outbound, int32 ttl, int32 date, string key_hash, int32 layer, + FolderId initial_folder_id); + + void on_update_online_status_privacy(); + + void on_update_phone_number_privacy(); + + void on_ignored_restriction_reasons_changed(); + + void invalidate_user_full(UserId user_id); + + bool have_user(UserId user_id) const; + + bool have_min_user(UserId user_id) const; + + bool have_user_force(UserId user_id, const char *source); + + static void send_get_me_query(Td *td, Promise &&promise); + + UserId get_me(Promise &&promise); + + bool get_user(UserId user_id, int left_tries, Promise &&promise); + + void reload_user(UserId user_id, Promise &&promise, const char *source); + + Result> get_input_user(UserId user_id) const; + + telegram_api::object_ptr get_input_user_force(UserId user_id) const; + + bool have_input_peer_user(UserId user_id, AccessRights access_rights) const; + + telegram_api::object_ptr get_input_peer_user(UserId user_id, + AccessRights access_rights) const; + + bool have_input_encrypted_peer(SecretChatId secret_chat_id, AccessRights access_rights) const; + + telegram_api::object_ptr get_input_encrypted_chat(SecretChatId secret_chat_id, + AccessRights access_rights) const; + + bool is_user_contact(UserId user_id, bool is_mutual = false) const; + + bool is_user_premium(UserId user_id) const; + + bool is_user_deleted(UserId user_id) const; + + bool is_user_support(UserId user_id) const; + + bool is_user_bot(UserId user_id) const; + + struct BotData { + string username; + bool can_be_edited; + bool can_join_groups; + bool can_read_all_group_messages; + bool has_main_app; + bool is_inline; + bool is_business; + bool need_location; + bool can_be_added_to_attach_menu; + }; + Result get_bot_data(UserId user_id) const TD_WARN_UNUSED_RESULT; + + bool is_user_online(UserId user_id, int32 tolerance = 0, int32 unix_time = 0) const; + + int32 get_user_was_online(UserId user_id, int32 unix_time = 0) const; + + bool is_user_status_exact(UserId user_id) const; + + bool is_user_received_from_server(UserId user_id) const; + + bool can_report_user(UserId user_id) const; + + const DialogPhoto *get_user_dialog_photo(UserId user_id); + + const DialogPhoto *get_secret_chat_dialog_photo(SecretChatId secret_chat_id); + + int32 get_user_accent_color_id_object(UserId user_id) const; + + int32 get_secret_chat_accent_color_id_object(SecretChatId secret_chat_id) const; + + CustomEmojiId get_user_background_custom_emoji_id(UserId user_id) const; + + CustomEmojiId get_secret_chat_background_custom_emoji_id(SecretChatId secret_chat_id) const; + + int32 get_user_profile_accent_color_id_object(UserId user_id) const; + + int32 get_secret_chat_profile_accent_color_id_object(SecretChatId secret_chat_id) const; + + CustomEmojiId get_user_profile_background_custom_emoji_id(UserId user_id) const; + + CustomEmojiId get_secret_chat_profile_background_custom_emoji_id(SecretChatId secret_chat_id) const; + + string get_user_title(UserId user_id) const; + + string get_secret_chat_title(SecretChatId secret_chat_id) const; + + RestrictedRights get_user_default_permissions(UserId user_id) const; + + RestrictedRights get_secret_chat_default_permissions(SecretChatId secret_chat_id) const; + + td_api::object_ptr get_user_emoji_status_object(UserId user_id) const; + + td_api::object_ptr get_secret_chat_emoji_status_object(SecretChatId secret_chat_id) const; + + bool get_user_stories_hidden(UserId user_id) const; + + bool can_poll_user_active_stories(UserId user_id) const; + + string get_user_about(UserId user_id); + + string get_secret_chat_about(SecretChatId secret_chat_id); + + string get_user_private_forward_name(UserId user_id); + + bool get_user_voice_messages_forbidden(UserId user_id) const; + + bool get_user_read_dates_private(UserId user_id); + + string get_user_search_text(UserId user_id) const; + + void for_each_secret_chat_with_user(UserId user_id, const std::function &f); + + string get_user_first_username(UserId user_id) const; + + int32 get_secret_chat_date(SecretChatId secret_chat_id) const; + + int32 get_secret_chat_ttl(SecretChatId secret_chat_id) const; + + UserId get_secret_chat_user_id(SecretChatId secret_chat_id) const; + + bool get_secret_chat_is_outbound(SecretChatId secret_chat_id) const; + + SecretChatState get_secret_chat_state(SecretChatId secret_chat_id) const; + + int32 get_secret_chat_layer(SecretChatId secret_chat_id) const; + + FolderId get_secret_chat_initial_folder_id(SecretChatId secret_chat_id) const; + + vector get_bot_commands(vector> &&bot_infos, + const vector *participants); + + void set_name(const string &first_name, const string &last_name, Promise &&promise); + + void set_bio(const string &bio, Promise &&promise); + + void on_update_profile_success(int32 flags, const string &first_name, const string &last_name, const string &about); + + FileId get_profile_photo_file_id(int64 photo_id) const; + + void set_bot_profile_photo(UserId bot_user_id, const td_api::object_ptr &input_photo, + Promise &&promise); + + void set_profile_photo(const td_api::object_ptr &input_photo, bool is_fallback, + Promise &&promise); + + void set_user_profile_photo(UserId user_id, const td_api::object_ptr &input_photo, + bool only_suggest, Promise &&promise); + + void send_update_profile_photo_query(UserId user_id, FileId file_id, int64 old_photo_id, bool is_fallback, + Promise &&promise); + + void on_set_profile_photo(UserId user_id, telegram_api::object_ptr &&photo, + bool is_fallback, int64 old_photo_id, Promise &&promise); + + void delete_profile_photo(int64 profile_photo_id, bool is_recursive, Promise &&promise); + + void on_delete_profile_photo(int64 profile_photo_id, Promise promise); + + void set_username(const string &username, Promise &&promise); + + void toggle_username_is_active(string &&username, bool is_active, Promise &&promise); + + void reorder_usernames(vector &&usernames, Promise &&promise); + + void toggle_bot_username_is_active(UserId bot_user_id, string &&username, bool is_active, Promise &&promise); + + void reorder_bot_usernames(UserId bot_user_id, vector &&usernames, Promise &&promise); + + void on_update_username_is_active(UserId user_id, string &&username, bool is_active, Promise &&promise); + + void on_update_active_usernames_order(UserId user_id, vector &&usernames, Promise &&promise); + + void set_accent_color(AccentColorId accent_color_id, CustomEmojiId background_custom_emoji_id, + Promise &&promise); + + void set_profile_accent_color(AccentColorId accent_color_id, CustomEmojiId background_custom_emoji_id, + Promise &&promise); + + void on_update_accent_color_success(bool for_profile, AccentColorId accent_color_id, + CustomEmojiId background_custom_emoji_id); + + void set_birthdate(Birthdate &&birthdate, Promise &&promise); + + void set_personal_channel(DialogId dialog_id, Promise &&promise); + + void set_emoji_status(const EmojiStatus &emoji_status, Promise &&promise); + + void toggle_sponsored_messages(bool sponsored_enabled, Promise &&promise); + + void get_support_user(Promise> &&promise); + + void get_user_profile_photos(UserId user_id, int32 offset, int32 limit, + Promise> &&promise); + + void reload_user_profile_photo(UserId user_id, int64 photo_id, Promise &&promise); + + FileSourceId get_user_profile_photo_file_source_id(UserId user_id, int64 photo_id); + + void on_get_user_photos(UserId user_id, int32 offset, int32 limit, int32 total_count, + vector> photos); + + void register_message_users(MessageFullId message_full_id, vector user_ids); + + void unregister_message_users(MessageFullId message_full_id, vector user_ids); + + void can_send_message_to_user(UserId user_id, bool force, + Promise> &&promise); + + void on_get_is_premium_required_to_contact_users(vector &&user_ids, vector &&is_premium_required, + Promise &&promise); + + void allow_send_message_to_user(UserId user_id); + + void share_phone_number(UserId user_id, Promise &&promise); + + void reload_contacts(bool force); + + void on_get_contacts(telegram_api::object_ptr &&new_contacts); + + void on_get_contacts_failed(Status error); + + void on_get_contacts_statuses(vector> &&statuses); + + void add_contact(Contact contact, bool share_phone_number, Promise &&promise); + + std::pair, vector> import_contacts(const vector &contacts, int64 &random_id, + Promise &&promise); + + void on_imported_contacts(int64 random_id, + Result> result); + + void remove_contacts(const vector &user_ids, Promise &&promise); + + void remove_contacts_by_phone_number(vector user_phone_numbers, vector user_ids, + Promise &&promise); + + void on_deleted_contacts(const vector &deleted_contact_user_ids); + + int32 get_imported_contact_count(Promise &&promise); + + std::pair, vector> change_imported_contacts(vector &contacts, int64 &random_id, + Promise &&promise); + + void clear_imported_contacts(Promise &&promise); + + void on_update_contacts_reset(); + + std::pair> search_contacts(const string &query, int32 limit, Promise &&promise); + + void reload_contact_birthdates(bool force); + + void on_get_contact_birthdates(telegram_api::object_ptr &&birthdays); + + void hide_contact_birthdays(Promise &&promise); + + vector get_close_friends(Promise &&promise); + + void set_close_friends(vector user_ids, Promise &&promise); + + void on_set_close_friends(const vector &user_ids, Promise &&promise); + + UserId search_user_by_phone_number(string phone_number, bool only_local, Promise &&promise); + + void on_resolved_phone_number(const string &phone_number, UserId user_id); + + void load_user_full(UserId user_id, bool force, Promise &&promise, const char *source); + + void reload_user_full(UserId user_id, Promise &&promise, const char *source); + + void on_get_user_full(telegram_api::object_ptr &&user); + + FileSourceId get_user_full_file_source_id(UserId user_id); + + bool have_secret_chat(SecretChatId secret_chat_id) const; + + bool have_secret_chat_force(SecretChatId secret_chat_id, const char *source); + + bool get_secret_chat(SecretChatId secret_chat_id, bool force, Promise &&promise); + + void create_new_secret_chat(UserId user_id, Promise> &&promise); + + int64 get_user_id_object(UserId user_id, const char *source) const; + + void get_user_id_object_async(UserId user_id, Promise &&promise); + + td_api::object_ptr get_user_object(UserId user_id) const; + + vector get_user_ids_object(const vector &user_ids, const char *source) const; + + td_api::object_ptr get_users_object(int32 total_count, const vector &user_ids) const; + + td_api::object_ptr get_user_full_info_object(UserId user_id) const; + + int32 get_secret_chat_id_object(SecretChatId secret_chat_id, const char *source) const; + + td_api::object_ptr get_secret_chat_object(SecretChatId secret_chat_id); + + void get_current_state(vector> &updates) const; + + private: + struct User { + string first_name; + string last_name; + Usernames usernames; + string phone_number; + int64 access_hash = -1; + EmojiStatus emoji_status; + EmojiStatus last_sent_emoji_status; + + ProfilePhoto photo; + + vector restriction_reasons; + string inline_query_placeholder; + int32 bot_active_users = 0; + int32 bot_info_version = -1; + + AccentColorId accent_color_id; + CustomEmojiId background_custom_emoji_id; + AccentColorId profile_accent_color_id; + CustomEmojiId profile_background_custom_emoji_id; + + int32 was_online = 0; + int32 local_was_online = 0; + + double max_active_story_id_next_reload_time = 0.0; + StoryId max_active_story_id; + StoryId max_read_story_id; + + string language_code; + + FlatHashSet photo_ids; + + static constexpr uint32 CACHE_VERSION = 4; + uint32 cache_version = 0; + + bool is_min_access_hash = true; + bool is_received = false; + bool is_verified = false; + bool is_premium = false; + bool is_support = false; + bool is_deleted = true; + bool is_bot = true; + bool can_join_groups = true; + bool can_read_all_group_messages = true; + bool can_be_edited_bot = false; + bool has_main_app = false; + bool is_inline_bot = false; + bool is_business_bot = false; + bool need_location_bot = false; + bool is_scam = false; + bool is_fake = false; + bool is_contact = false; + bool is_mutual_contact = false; + bool is_close_friend = false; + bool need_apply_min_photo = false; + bool can_be_added_to_attach_menu = false; + bool attach_menu_enabled = false; + bool stories_hidden = false; + bool contact_require_premium = false; + + bool is_photo_inited = false; + + bool is_repaired = false; // whether cached value is rechecked + + bool is_name_changed = true; + bool is_username_changed = true; + bool is_photo_changed = true; + bool is_accent_color_changed = true; + bool is_phone_number_changed = true; + bool is_emoji_status_changed = true; + bool is_is_contact_changed = true; + bool is_is_mutual_contact_changed = true; + bool is_is_deleted_changed = true; + bool is_is_premium_changed = true; + bool is_stories_hidden_changed = true; + bool is_full_info_changed = false; + bool is_being_updated = false; + bool is_changed = true; // have new changes that need to be sent to the client and database + bool need_save_to_database = true; // have new changes that need only to be saved to the database + bool is_status_changed = true; + bool is_online_status_changed = true; // whether online/offline has changed + bool is_update_user_sent = false; + + bool is_saved = false; // is current user version being saved/is saved to the database + bool is_being_saved = false; // is current user being saved to the database + bool is_status_saved = false; // is current user status being saved/is saved to the database + + bool is_received_from_server = false; // true, if the user was received from the server and not the database + + uint64 log_event_id = 0; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + // do not forget to update drop_user_full and on_get_user_full + struct UserFull { + Photo photo; + Photo fallback_photo; + Photo personal_photo; + + string about; + string private_forward_name; + string description; + Photo description_photo; + FileId description_animation_file_id; + vector registered_file_ids; + FileSourceId file_source_id; + + vector premium_gift_options; + + unique_ptr menu_button; + vector commands; + string privacy_policy_url; + AdministratorRights group_administrator_rights; + AdministratorRights broadcast_administrator_rights; + + int32 common_chat_count = 0; + Birthdate birthdate; + + ChannelId personal_channel_id; + + unique_ptr business_info; + + bool is_blocked = false; + bool is_blocked_for_stories = false; + bool can_be_called = false; + bool supports_video_calls = false; + bool has_private_calls = false; + bool can_pin_messages = true; + bool need_phone_number_privacy_exception = false; + bool wallpaper_overridden = false; + bool voice_messages_forbidden = false; + bool has_pinned_stories = false; + bool read_dates_private = false; + bool contact_require_premium = false; + bool sponsored_enabled = false; + bool has_preview_medias = false; + + bool is_common_chat_count_changed = true; + bool is_being_updated = false; + bool is_changed = true; // have new changes that need to be sent to the client and database + bool need_send_update = true; // have new changes that need only to be sent to the client + bool need_save_to_database = true; // have new changes that need only to be saved to the database + bool is_update_user_full_sent = false; + + double expires_at = 0.0; + + bool is_expired() const { + return expires_at < Time::now(); + } + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct SecretChat { + int64 access_hash = 0; + UserId user_id; + SecretChatState state = SecretChatState::Unknown; + string key_hash; + int32 ttl = 0; + int32 date = 0; + int32 layer = 0; + FolderId initial_folder_id; + + bool is_outbound = false; + + bool is_ttl_changed = true; + bool is_state_changed = true; + bool is_being_updated = false; + bool is_changed = true; // have new changes that need to be sent to the client and database + bool need_save_to_database = true; // have new changes that need only to be saved to the database + + bool is_saved = false; // is current secret chat version being saved/is saved to the database + bool is_being_saved = false; // is current secret chat being saved to the database + + uint64 log_event_id = 0; + + template + void store(StorerT &storer) const; + + template + void parse(ParserT &parser); + }; + + struct PendingGetPhotoRequest { + int32 offset = 0; + int32 limit = 0; + int32 retry_count = 0; + Promise> promise; + }; + + struct UserPhotos { + vector photos; + int32 count = -1; + int32 offset = -1; + + vector pending_requests; + }; + + class UserLogEvent; + class SecretChatLogEvent; + + static constexpr int32 MAX_GET_PROFILE_PHOTOS = 100; // server side limit + static constexpr size_t MAX_NAME_LENGTH = 64; // server side limit for first/last name + + static constexpr int32 MAX_ACTIVE_STORY_ID_RELOAD_TIME = 3600; // some reasonable limit + + // the True fields aren't set for manually created telegram_api::user objects, therefore the flags must be used + static constexpr int32 USER_FLAG_HAS_ACCESS_HASH = 1 << 0; + static constexpr int32 USER_FLAG_HAS_FIRST_NAME = 1 << 1; + static constexpr int32 USER_FLAG_HAS_LAST_NAME = 1 << 2; + static constexpr int32 USER_FLAG_HAS_USERNAME = 1 << 3; + static constexpr int32 USER_FLAG_HAS_PHONE_NUMBER = 1 << 4; + static constexpr int32 USER_FLAG_HAS_PHOTO = 1 << 5; + static constexpr int32 USER_FLAG_HAS_STATUS = 1 << 6; + static constexpr int32 USER_FLAG_HAS_BOT_INFO_VERSION = 1 << 14; + static constexpr int32 USER_FLAG_IS_ME = 1 << 10; + static constexpr int32 USER_FLAG_IS_CONTACT = 1 << 11; + static constexpr int32 USER_FLAG_IS_MUTUAL_CONTACT = 1 << 12; + static constexpr int32 USER_FLAG_IS_DELETED = 1 << 13; + static constexpr int32 USER_FLAG_IS_BOT = 1 << 14; + static constexpr int32 USER_FLAG_IS_BOT_WITH_PRIVACY_DISABLED = 1 << 15; + static constexpr int32 USER_FLAG_IS_PRIVATE_BOT = 1 << 16; + static constexpr int32 USER_FLAG_IS_VERIFIED = 1 << 17; + static constexpr int32 USER_FLAG_IS_RESTRICTED = 1 << 18; + static constexpr int32 USER_FLAG_IS_INLINE_BOT = 1 << 19; + static constexpr int32 USER_FLAG_IS_INACCESSIBLE = 1 << 20; + static constexpr int32 USER_FLAG_NEED_LOCATION_BOT = 1 << 21; + static constexpr int32 USER_FLAG_HAS_LANGUAGE_CODE = 1 << 22; + static constexpr int32 USER_FLAG_IS_SUPPORT = 1 << 23; + static constexpr int32 USER_FLAG_IS_SCAM = 1 << 24; + static constexpr int32 USER_FLAG_NEED_APPLY_MIN_PHOTO = 1 << 25; + static constexpr int32 USER_FLAG_IS_FAKE = 1 << 26; + static constexpr int32 USER_FLAG_IS_ATTACH_MENU_BOT = 1 << 27; + static constexpr int32 USER_FLAG_IS_PREMIUM = 1 << 28; + static constexpr int32 USER_FLAG_ATTACH_MENU_ENABLED = 1 << 29; + static constexpr int32 USER_FLAG_HAS_EMOJI_STATUS = 1 << 30; + static constexpr int32 USER_FLAG_HAS_USERNAMES = 1 << 0; + static constexpr int32 USER_FLAG_CAN_BE_EDITED_BOT = 1 << 1; + static constexpr int32 USER_FLAG_IS_CLOSE_FRIEND = 1 << 2; + + static constexpr int32 USER_FULL_EXPIRE_TIME = 60; + + static constexpr int32 ACCOUNT_UPDATE_FIRST_NAME = 1 << 0; + static constexpr int32 ACCOUNT_UPDATE_LAST_NAME = 1 << 1; + static constexpr int32 ACCOUNT_UPDATE_ABOUT = 1 << 2; + + void tear_down() final; + + static void on_user_online_timeout_callback(void *user_manager_ptr, int64 user_id_long); + + void on_user_online_timeout(UserId user_id); + + static void on_user_emoji_status_timeout_callback(void *user_manager_ptr, int64 user_id_long); + + void on_user_emoji_status_timeout(UserId user_id); + + void set_my_id(UserId my_id); + + const User *get_user(UserId user_id) const; + + User *get_user(UserId user_id); + + User *add_user(UserId user_id); + + void save_user(User *u, UserId user_id, bool from_binlog); + + static string get_user_database_key(UserId user_id); + + static string get_user_database_value(const User *u); + + void save_user_to_database(User *u, UserId user_id); + + void save_user_to_database_impl(User *u, UserId user_id, string value); + + void on_save_user_to_database(UserId user_id, bool success); + + void load_user_from_database(User *u, UserId user_id, Promise promise); + + void load_user_from_database_impl(UserId user_id, Promise promise); + + void on_load_user_from_database(UserId user_id, string value, bool force); + + User *get_user_force(UserId user_id, const char *source); + + User *get_user_force_impl(UserId user_id, const char *source); + + bool is_user_contact(const User *u, UserId user_id, bool is_mutual) const; + + static bool is_user_premium(const User *u); + + static bool is_user_deleted(const User *u); + + static bool is_user_support(const User *u); + + static bool is_user_bot(const User *u); + + int32 get_user_was_online(const User *u, UserId user_id, int32 unix_time) const; + + void on_update_user_name(User *u, UserId user_id, string &&first_name, string &&last_name); + + void on_update_user_usernames(User *u, UserId user_id, Usernames &&usernames); + + void on_update_user_phone_number(User *u, UserId user_id, string &&phone_number); + + void on_update_user_photo(User *u, UserId user_id, telegram_api::object_ptr &&photo, + const char *source); + + void do_update_user_photo(User *u, UserId user_id, telegram_api::object_ptr &&photo, + const char *source); + + void do_update_user_photo(User *u, UserId user_id, ProfilePhoto &&new_photo, bool invalidate_photo_cache, + const char *source); + + void register_user_photo(User *u, UserId user_id, const Photo &photo); + + void on_update_user_accent_color_id(User *u, UserId user_id, AccentColorId accent_color_id); + + void on_update_user_background_custom_emoji_id(User *u, UserId user_id, CustomEmojiId background_custom_emoji_id); + + void on_update_user_profile_accent_color_id(User *u, UserId user_id, AccentColorId accent_color_id); + + void on_update_user_profile_background_custom_emoji_id(User *u, UserId user_id, + CustomEmojiId background_custom_emoji_id); + + void on_update_user_emoji_status(User *u, UserId user_id, EmojiStatus emoji_status); + + void on_update_user_story_ids_impl(User *u, UserId user_id, StoryId max_active_story_id, StoryId max_read_story_id); + + void on_update_user_max_read_story_id(User *u, UserId user_id, StoryId max_read_story_id); + + void on_update_user_stories_hidden(User *u, UserId user_id, bool stories_hidden); + + void on_update_user_is_contact(User *u, UserId user_id, bool is_contact, bool is_mutual_contact, + bool is_close_friend); + + void on_update_user_online(User *u, UserId user_id, telegram_api::object_ptr &&status); + + void on_update_user_local_was_online(User *u, UserId user_id, int32 local_was_online); + + static void on_update_user_full_is_blocked(UserFull *user_full, UserId user_id, bool is_blocked, + bool is_blocked_for_stories); + + static void on_update_user_full_common_chat_count(UserFull *user_full, UserId user_id, int32 common_chat_count); + + static void on_update_user_full_location(UserFull *user_full, UserId user_id, DialogLocation &&location); + + static void on_update_user_full_work_hours(UserFull *user_full, UserId user_id, BusinessWorkHours &&work_hours); + + void on_update_user_full_away_message(UserFull *user_full, UserId user_id, BusinessAwayMessage &&away_message) const; + + void on_update_user_full_greeting_message(UserFull *user_full, UserId user_id, + BusinessGreetingMessage &&greeting_message) const; + + static void on_update_user_full_intro(UserFull *user_full, UserId user_id, BusinessIntro &&intro); + + static void on_update_user_full_commands(UserFull *user_full, UserId user_id, + vector> &&bot_commands); + + void on_update_user_full_need_phone_number_privacy_exception(UserFull *user_full, UserId user_id, + bool need_phone_number_privacy_exception) const; + + void on_update_user_full_wallpaper_overridden(UserFull *user_full, UserId user_id, bool wallpaper_overridden) const; + + static void on_update_user_full_menu_button(UserFull *user_full, UserId user_id, + telegram_api::object_ptr &&bot_menu_button); + + static void on_update_user_full_has_preview_medias(UserFull *user_full, UserId user_id, bool has_preview_medias); + + bool have_input_peer_user(const User *u, UserId user_id, AccessRights access_rights) const; + + static bool have_input_encrypted_peer(const SecretChat *secret_chat, AccessRights access_rights); + + bool need_poll_user_active_stories(const User *u, UserId user_id) const; + + static string get_user_search_text(const User *u); + + void set_profile_photo_impl(UserId user_id, const td_api::object_ptr &input_photo, + bool is_fallback, bool only_suggest, Promise &&promise); + + void upload_profile_photo(UserId user_id, FileId file_id, bool is_fallback, bool only_suggest, bool is_animation, + double main_frame_timestamp, Promise &&promise, int reupload_count = 0, + vector bad_parts = {}); + + void on_upload_profile_photo(FileId file_id, telegram_api::object_ptr input_file); + + void on_upload_profile_photo_error(FileId file_id, Status status); + + void add_set_profile_photo_to_cache(UserId user_id, Photo &&photo, bool is_fallback); + + bool delete_my_profile_photo_from_cache(int64 profile_photo_id); + + void toggle_username_is_active_impl(string &&username, bool is_active, Promise &&promise); + + void reorder_usernames_impl(vector &&usernames, Promise &&promise); + + void on_set_birthdate(Birthdate birthdate, Promise &&promise); + + void on_set_personal_channel(ChannelId channel_id, Promise &&promise); + + void on_set_emoji_status(EmojiStatus emoji_status, Promise &&promise); + + void on_toggle_sponsored_messages(bool sponsored_enabled, Promise &&promise); + + void on_get_support_user(UserId user_id, Promise> &&promise); + + void send_get_user_photos_query(UserId user_id, const UserPhotos *user_photos); + + void on_get_user_profile_photos(UserId user_id, Result &&result); + + UserPhotos *add_user_photos(UserId user_id); + + void apply_pending_user_photo(User *u, UserId user_id); + + void load_contacts(Promise &&promise); + + int64 get_contacts_hash(); + + void save_next_contacts_sync_date(); + + void save_contacts_to_database(); + + void on_load_contacts_from_database(string value); + + void on_get_contacts_finished(size_t expected_contact_count); + + void do_import_contacts(vector contacts, int64 random_id, Promise &&promise); + + void on_import_contacts_finished(int64 random_id, vector imported_contact_user_ids, + vector unimported_contact_invites); + + void load_imported_contacts(Promise &&promise); + + void on_load_imported_contacts_from_database(string value); + + void on_load_imported_contacts_finished(); + + void on_clear_imported_contacts(vector &&contacts, vector contacts_unique_id, + std::pair, vector> &&to_add, Promise &&promise); + + void update_contacts_hints(const User *u, UserId user_id, bool from_database); + + const UserFull *get_user_full(UserId user_id) const; + + UserFull *get_user_full(UserId user_id); + + UserFull *add_user_full(UserId user_id); + + UserFull *get_user_full_force(UserId user_id, const char *source); + + void send_get_user_full_query(UserId user_id, telegram_api::object_ptr &&input_user, + Promise &&promise, const char *source); + + static void save_user_full(const UserFull *user_full, UserId user_id); + + static string get_user_full_database_key(UserId user_id); + + static string get_user_full_database_value(const UserFull *user_full); + + void on_load_user_full_from_database(UserId user_id, string value); + + int64 get_user_full_profile_photo_id(const UserFull *user_full); + + void drop_user_full_photos(UserFull *user_full, UserId user_id, int64 expected_photo_id, const char *source); + + void drop_user_photos(UserId user_id, bool is_empty, const char *source); + + void drop_user_full(UserId user_id); + + const SecretChat *get_secret_chat(SecretChatId secret_chat_id) const; + + SecretChat *get_secret_chat(SecretChatId secret_chat_id); + + SecretChat *add_secret_chat(SecretChatId secret_chat_id); + + SecretChat *get_secret_chat_force(SecretChatId secret_chat_id, const char *source); + + void save_secret_chat(SecretChat *c, SecretChatId secret_chat_id, bool from_binlog); + + static string get_secret_chat_database_key(SecretChatId secret_chat_id); + + static string get_secret_chat_database_value(const SecretChat *c); + + void save_secret_chat_to_database(SecretChat *c, SecretChatId secret_chat_id); + + void save_secret_chat_to_database_impl(SecretChat *c, SecretChatId secret_chat_id, string value); + + void on_save_secret_chat_to_database(SecretChatId secret_chat_id, bool success); + + void load_secret_chat_from_database(SecretChat *c, SecretChatId secret_chat_id, Promise promise); + + void load_secret_chat_from_database_impl(SecretChatId secret_chat_id, Promise promise); + + void on_load_secret_chat_from_database(SecretChatId secret_chat_id, string value, bool force); + + void on_create_new_secret_chat(SecretChatId secret_chat_id, Promise> &&promise); + + void update_user(User *u, UserId user_id, bool from_binlog = false, bool from_database = false); + + void update_secret_chat(SecretChat *c, SecretChatId secret_chat_id, bool from_binlog = false, + bool from_database = false); + + void update_user_full(UserFull *user_full, UserId user_id, const char *source, bool from_database = false); + + td_api::object_ptr get_user_status_object(UserId user_id, const User *u, int32 unix_time) const; + + static bool get_user_has_unread_stories(const User *u); + + td_api::object_ptr get_update_user_object(UserId user_id, const User *u) const; + + td_api::object_ptr get_update_unknown_user_object(UserId user_id) const; + + td_api::object_ptr get_user_object(UserId user_id, const User *u) const; + + td_api::object_ptr get_user_full_info_object(UserId user_id, const UserFull *user_full) const; + + td_api::object_ptr get_update_contact_close_birthdays() const; + + static td_api::object_ptr get_secret_chat_state_object(SecretChatState state); + + td_api::object_ptr get_update_secret_chat_object(SecretChatId secret_chat_id, + const SecretChat *secret_chat); + + static td_api::object_ptr get_update_unknown_secret_chat_object( + SecretChatId secret_chat_id); + + td_api::object_ptr get_secret_chat_object(SecretChatId secret_chat_id, + const SecretChat *secret_chat); + + td_api::object_ptr get_secret_chat_object_const(SecretChatId secret_chat_id, + const SecretChat *secret_chat) const; + + Td *td_; + ActorShared<> parent_; + UserId my_id_; + UserId support_user_id_; + int32 my_was_online_local_ = 0; + + WaitFreeHashMap, UserIdHash> users_; + WaitFreeHashMap, UserIdHash> users_full_; + WaitFreeHashMap, UserIdHash> user_photos_; + mutable FlatHashSet unknown_users_; + WaitFreeHashMap, UserIdHash> pending_user_photos_; + struct UserIdPhotoIdHash { + uint32 operator()(const std::pair &pair) const { + return combine_hashes(UserIdHash()(pair.first), Hash()(pair.second)); + } + }; + WaitFreeHashMap, FileSourceId, UserIdPhotoIdHash> user_profile_photo_file_source_ids_; + FlatHashMap my_photo_file_id_; + WaitFreeHashMap user_full_file_source_ids_; + + WaitFreeHashMap, SecretChatIdHash> secret_chats_; + mutable FlatHashSet unknown_secret_chats_; + + FlatHashMap, UserIdHash> secret_chats_with_user_; + + FlatHashMap>, UserIdHash> load_user_from_database_queries_; + FlatHashSet loaded_from_database_users_; + FlatHashSet unavailable_user_fulls_; + + FlatHashMap>, SecretChatIdHash> load_secret_chat_from_database_queries_; + FlatHashSet loaded_from_database_secret_chats_; + + QueryMerger get_user_queries_{"GetUserMerger", 3, 50}; + + QueryMerger get_is_premium_required_to_contact_queries_{"GetIsPremiumRequiredToContactMerger", 3, 100}; + + QueryCombiner get_user_full_queries_{"GetUserFullCombiner", 2.0}; + class UploadProfilePhotoCallback; + std::shared_ptr upload_profile_photo_callback_; + + struct UploadedProfilePhoto { + UserId user_id; + bool is_fallback; + bool only_suggest; + double main_frame_timestamp; + bool is_animation; + int reupload_count; + Promise promise; + + UploadedProfilePhoto(UserId user_id, bool is_fallback, bool only_suggest, double main_frame_timestamp, + bool is_animation, int32 reupload_count, Promise promise) + : user_id(user_id) + , is_fallback(is_fallback) + , only_suggest(only_suggest) + , main_frame_timestamp(main_frame_timestamp) + , is_animation(is_animation) + , reupload_count(reupload_count) + , promise(std::move(promise)) { + } + }; + FlatHashMap uploaded_profile_photos_; + + struct ImportContactsTask { + Promise promise_; + vector input_contacts_; + vector imported_user_ids_; + vector unimported_contact_invites_; + }; + FlatHashMap> import_contact_tasks_; + + FlatHashMap, vector>> imported_contacts_; + + FlatHashMap resolved_phone_numbers_; + + FlatHashMap, UserIdHash> user_messages_; + + bool are_contacts_loaded_ = false; + int32 next_contacts_sync_date_ = 0; + Hints contacts_hints_; // search contacts by first name, last name and usernames + vector> load_contacts_queries_; + MultiPromiseActor load_contact_users_multipromise_{"LoadContactUsersMultiPromiseActor"}; + int32 saved_contact_count_ = -1; + + int32 was_online_local_ = 0; + int32 was_online_remote_ = 0; + + bool are_imported_contacts_loaded_ = false; + vector> load_imported_contacts_queries_; + MultiPromiseActor load_imported_contact_users_multipromise_{"LoadImportedContactUsersMultiPromiseActor"}; + vector all_imported_contacts_; + bool are_imported_contacts_changing_ = false; + bool need_clear_imported_contacts_ = false; + + FlatHashMap user_full_contact_require_premium_; + + WaitFreeHashSet restricted_user_ids_; + + struct ContactBirthdates { + vector> users_; + double next_sync_time_ = 0.0; + bool is_being_synced_ = false; + bool need_drop_ = false; + }; + ContactBirthdates contact_birthdates_; + + vector next_all_imported_contacts_; + vector imported_contacts_unique_id_; + vector imported_contacts_pos_; + + vector imported_contact_user_ids_; // result of change_imported_contacts + vector unimported_contact_invites_; // result of change_imported_contacts + + MultiTimeout user_online_timeout_{"UserOnlineTimeout"}; + MultiTimeout user_emoji_status_timeout_{"UserEmojiStatusTimeout"}; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySetting.cpp b/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySetting.cpp new file mode 100644 index 0000000000..c6e2e4a63e --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySetting.cpp @@ -0,0 +1,160 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/UserPrivacySetting.h" + +namespace td { + +Result UserPrivacySetting::get_user_privacy_setting( + td_api::object_ptr key) { + if (key == nullptr) { + return Status::Error(400, "UserPrivacySetting must be non-empty"); + } + return UserPrivacySetting(*key); +} + +UserPrivacySetting::UserPrivacySetting(const telegram_api::PrivacyKey &key) { + switch (key.get_id()) { + case telegram_api::privacyKeyStatusTimestamp::ID: + type_ = Type::UserStatus; + break; + case telegram_api::privacyKeyChatInvite::ID: + type_ = Type::ChatInvite; + break; + case telegram_api::privacyKeyPhoneCall::ID: + type_ = Type::Call; + break; + case telegram_api::privacyKeyPhoneP2P::ID: + type_ = Type::PeerToPeerCall; + break; + case telegram_api::privacyKeyForwards::ID: + type_ = Type::LinkInForwardedMessages; + break; + case telegram_api::privacyKeyProfilePhoto::ID: + type_ = Type::UserProfilePhoto; + break; + case telegram_api::privacyKeyPhoneNumber::ID: + type_ = Type::UserPhoneNumber; + break; + case telegram_api::privacyKeyAddedByPhone::ID: + type_ = Type::FindByPhoneNumber; + break; + case telegram_api::privacyKeyVoiceMessages::ID: + type_ = Type::VoiceMessages; + break; + case telegram_api::privacyKeyAbout::ID: + type_ = Type::UserBio; + break; + case telegram_api::privacyKeyBirthday::ID: + type_ = Type::UserBirthdate; + break; + default: + UNREACHABLE(); + type_ = Type::UserStatus; + } +} + +td_api::object_ptr UserPrivacySetting::get_user_privacy_setting_object() const { + switch (type_) { + case Type::UserStatus: + return make_tl_object(); + case Type::ChatInvite: + return make_tl_object(); + case Type::Call: + return make_tl_object(); + case Type::PeerToPeerCall: + return make_tl_object(); + case Type::LinkInForwardedMessages: + return make_tl_object(); + case Type::UserProfilePhoto: + return make_tl_object(); + case Type::UserPhoneNumber: + return make_tl_object(); + case Type::FindByPhoneNumber: + return make_tl_object(); + case Type::VoiceMessages: + return make_tl_object(); + case Type::UserBio: + return make_tl_object(); + case Type::UserBirthdate: + return make_tl_object(); + default: + UNREACHABLE(); + return nullptr; + } +} +telegram_api::object_ptr UserPrivacySetting::get_input_privacy_key() const { + switch (type_) { + case Type::UserStatus: + return make_tl_object(); + case Type::ChatInvite: + return make_tl_object(); + case Type::Call: + return make_tl_object(); + case Type::PeerToPeerCall: + return make_tl_object(); + case Type::LinkInForwardedMessages: + return make_tl_object(); + case Type::UserProfilePhoto: + return make_tl_object(); + case Type::UserPhoneNumber: + return make_tl_object(); + case Type::FindByPhoneNumber: + return make_tl_object(); + case Type::VoiceMessages: + return make_tl_object(); + case Type::UserBio: + return make_tl_object(); + case Type::UserBirthdate: + return make_tl_object(); + default: + UNREACHABLE(); + return nullptr; + } +} + +UserPrivacySetting::UserPrivacySetting(const td_api::UserPrivacySetting &key) { + switch (key.get_id()) { + case td_api::userPrivacySettingShowStatus::ID: + type_ = Type::UserStatus; + break; + case td_api::userPrivacySettingAllowChatInvites::ID: + type_ = Type::ChatInvite; + break; + case td_api::userPrivacySettingAllowCalls::ID: + type_ = Type::Call; + break; + case td_api::userPrivacySettingAllowPeerToPeerCalls::ID: + type_ = Type::PeerToPeerCall; + break; + case td_api::userPrivacySettingShowLinkInForwardedMessages::ID: + type_ = Type::LinkInForwardedMessages; + break; + case td_api::userPrivacySettingShowProfilePhoto::ID: + type_ = Type::UserProfilePhoto; + break; + case td_api::userPrivacySettingShowPhoneNumber::ID: + type_ = Type::UserPhoneNumber; + break; + case td_api::userPrivacySettingAllowFindingByPhoneNumber::ID: + type_ = Type::FindByPhoneNumber; + break; + case td_api::userPrivacySettingAllowPrivateVoiceAndVideoNoteMessages::ID: + type_ = Type::VoiceMessages; + break; + case td_api::userPrivacySettingShowBio::ID: + type_ = Type::UserBio; + break; + case td_api::userPrivacySettingShowBirthdate::ID: + type_ = Type::UserBirthdate; + break; + default: + UNREACHABLE(); + type_ = Type::UserStatus; + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySetting.h b/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySetting.h new file mode 100644 index 0000000000..502ff6744c --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySetting.h @@ -0,0 +1,52 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" + +namespace td { + +class UserPrivacySetting { + public: + enum class Type : int32 { + UserStatus, + ChatInvite, + Call, + PeerToPeerCall, + LinkInForwardedMessages, + UserProfilePhoto, + UserPhoneNumber, + FindByPhoneNumber, + VoiceMessages, + UserBio, + UserBirthdate, + Size + }; + + explicit UserPrivacySetting(const telegram_api::PrivacyKey &key); + + static Result get_user_privacy_setting(td_api::object_ptr key); + + td_api::object_ptr get_user_privacy_setting_object() const; + + telegram_api::object_ptr get_input_privacy_key() const; + + Type type() const { + return type_; + } + + private: + Type type_; + + explicit UserPrivacySetting(const td_api::UserPrivacySetting &key); +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySettingRule.cpp b/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySettingRule.cpp new file mode 100644 index 0000000000..1618f50291 --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySettingRule.cpp @@ -0,0 +1,404 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#include "td/telegram/UserPrivacySettingRule.h" + +#include "td/telegram/ChannelId.h" +#include "td/telegram/ChatId.h" +#include "td/telegram/ChatManager.h" +#include "td/telegram/Dependencies.h" +#include "td/telegram/DialogManager.h" +#include "td/telegram/Td.h" +#include "td/telegram/UserManager.h" + +#include "td/utils/algorithm.h" +#include "td/utils/logging.h" + +#include + +namespace td { + +void UserPrivacySettingRule::set_dialog_ids(Td *td, const vector &chat_ids) { + dialog_ids_.clear(); + for (auto chat_id : chat_ids) { + DialogId dialog_id(chat_id); + if (!td->dialog_manager_->have_dialog_force(dialog_id, "UserPrivacySettingRule::set_dialog_ids")) { + LOG(INFO) << "Ignore not found " << dialog_id; + continue; + } + + switch (dialog_id.get_type()) { + case DialogType::Chat: + dialog_ids_.push_back(dialog_id); + break; + case DialogType::Channel: { + auto channel_id = dialog_id.get_channel_id(); + if (!td->chat_manager_->is_megagroup_channel(channel_id)) { + LOG(INFO) << "Ignore broadcast " << channel_id; + break; + } + dialog_ids_.push_back(dialog_id); + break; + } + default: + LOG(INFO) << "Ignore " << dialog_id; + } + } +} + +UserPrivacySettingRule::UserPrivacySettingRule(Td *td, const td_api::UserPrivacySettingRule &rule) { + switch (rule.get_id()) { + case td_api::userPrivacySettingRuleAllowContacts::ID: + type_ = Type::AllowContacts; + break; + case td_api::userPrivacySettingRuleAllowPremiumUsers::ID: + type_ = Type::AllowPremium; + break; + case td_api::userPrivacySettingRuleAllowAll::ID: + type_ = Type::AllowAll; + break; + case td_api::userPrivacySettingRuleAllowUsers::ID: + type_ = Type::AllowUsers; + user_ids_ = UserId::get_user_ids(static_cast(rule).user_ids_); + break; + case td_api::userPrivacySettingRuleAllowChatMembers::ID: + type_ = Type::AllowChatParticipants; + set_dialog_ids(td, static_cast(rule).chat_ids_); + break; + case td_api::userPrivacySettingRuleRestrictContacts::ID: + type_ = Type::RestrictContacts; + break; + case td_api::userPrivacySettingRuleRestrictAll::ID: + type_ = Type::RestrictAll; + break; + case td_api::userPrivacySettingRuleRestrictUsers::ID: + type_ = Type::RestrictUsers; + user_ids_ = + UserId::get_user_ids(static_cast(rule).user_ids_); + break; + case td_api::userPrivacySettingRuleRestrictChatMembers::ID: + type_ = Type::RestrictChatParticipants; + set_dialog_ids(td, static_cast(rule).chat_ids_); + break; + default: + UNREACHABLE(); + } +} + +UserPrivacySettingRule::UserPrivacySettingRule(Td *td, + const telegram_api::object_ptr &rule) { + CHECK(rule != nullptr); + switch (rule->get_id()) { + case telegram_api::privacyValueAllowContacts::ID: + type_ = Type::AllowContacts; + break; + case telegram_api::privacyValueAllowPremium::ID: + type_ = Type::AllowPremium; + break; + case telegram_api::privacyValueAllowCloseFriends::ID: + type_ = Type::AllowCloseFriends; + break; + case telegram_api::privacyValueAllowAll::ID: + type_ = Type::AllowAll; + break; + case telegram_api::privacyValueAllowUsers::ID: + type_ = Type::AllowUsers; + user_ids_ = UserId::get_user_ids(static_cast(*rule).users_); + break; + case telegram_api::privacyValueAllowChatParticipants::ID: + type_ = Type::AllowChatParticipants; + set_dialog_ids_from_server(td, + static_cast(*rule).chats_); + break; + case telegram_api::privacyValueDisallowContacts::ID: + type_ = Type::RestrictContacts; + break; + case telegram_api::privacyValueDisallowAll::ID: + type_ = Type::RestrictAll; + break; + case telegram_api::privacyValueDisallowUsers::ID: + type_ = Type::RestrictUsers; + user_ids_ = UserId::get_user_ids(static_cast(*rule).users_); + break; + case telegram_api::privacyValueDisallowChatParticipants::ID: + type_ = Type::RestrictChatParticipants; + set_dialog_ids_from_server(td, + static_cast(*rule).chats_); + break; + default: + UNREACHABLE(); + } + td::remove_if(user_ids_, [td](UserId user_id) { + if (!td->user_manager_->have_user(user_id)) { + LOG(ERROR) << "Receive unknown " << user_id; + return true; + } + return false; + }); +} + +void UserPrivacySettingRule::set_dialog_ids_from_server(Td *td, const vector &server_chat_ids) { + dialog_ids_.clear(); + for (auto server_chat_id : server_chat_ids) { + ChatId chat_id(server_chat_id); + DialogId dialog_id(chat_id); + if (!td->chat_manager_->have_chat(chat_id)) { + ChannelId channel_id(server_chat_id); + dialog_id = DialogId(channel_id); + if (!td->chat_manager_->have_channel(channel_id)) { + LOG(ERROR) << "Receive unknown group " << server_chat_id << " from the server"; + continue; + } + } + td->dialog_manager_->force_create_dialog(dialog_id, "set_dialog_ids_from_server"); + dialog_ids_.push_back(dialog_id); + } +} + +td_api::object_ptr UserPrivacySettingRule::get_user_privacy_setting_rule_object( + Td *td) const { + switch (type_) { + case Type::AllowContacts: + return make_tl_object(); + case Type::AllowPremium: + return make_tl_object(); + case Type::AllowCloseFriends: + LOG(ERROR) << "Have AllowCloseFriends rule"; + return make_tl_object(); + case Type::AllowAll: + return make_tl_object(); + case Type::AllowUsers: + return make_tl_object( + td->user_manager_->get_user_ids_object(user_ids_, "userPrivacySettingRuleAllowUsers")); + case Type::AllowChatParticipants: + return make_tl_object( + td->dialog_manager_->get_chat_ids_object(dialog_ids_, "UserPrivacySettingRule")); + case Type::RestrictContacts: + return make_tl_object(); + case Type::RestrictAll: + return make_tl_object(); + case Type::RestrictUsers: + return make_tl_object( + td->user_manager_->get_user_ids_object(user_ids_, "userPrivacySettingRuleRestrictUsers")); + case Type::RestrictChatParticipants: + return make_tl_object( + td->dialog_manager_->get_chat_ids_object(dialog_ids_, "UserPrivacySettingRule")); + default: + UNREACHABLE(); + return nullptr; + } +} + +telegram_api::object_ptr UserPrivacySettingRule::get_input_privacy_rule(Td *td) const { + switch (type_) { + case Type::AllowContacts: + return make_tl_object(); + case Type::AllowPremium: + return make_tl_object(); + case Type::AllowCloseFriends: + return make_tl_object(); + case Type::AllowAll: + return make_tl_object(); + case Type::AllowUsers: + return make_tl_object(get_input_users(td)); + case Type::AllowChatParticipants: + return make_tl_object(get_input_chat_ids(td)); + case Type::RestrictContacts: + return make_tl_object(); + case Type::RestrictAll: + return make_tl_object(); + case Type::RestrictUsers: + return make_tl_object(get_input_users(td)); + case Type::RestrictChatParticipants: + return make_tl_object(get_input_chat_ids(td)); + default: + UNREACHABLE(); + } +} + +vector> UserPrivacySettingRule::get_input_users(Td *td) const { + vector> result; + for (auto user_id : user_ids_) { + auto r_input_user = td->user_manager_->get_input_user(user_id); + if (r_input_user.is_ok()) { + result.push_back(r_input_user.move_as_ok()); + } else { + LOG(INFO) << "Have no access to " << user_id; + } + } + return result; +} + +vector UserPrivacySettingRule::get_input_chat_ids(Td *td) const { + vector result; + for (auto dialog_id : dialog_ids_) { + switch (dialog_id.get_type()) { + case DialogType::Chat: + result.push_back(dialog_id.get_chat_id().get()); + break; + case DialogType::Channel: + result.push_back(dialog_id.get_channel_id().get()); + break; + default: + UNREACHABLE(); + } + } + return result; +} + +vector UserPrivacySettingRule::get_restricted_user_ids() const { + if (type_ == Type::RestrictUsers) { + return user_ids_; + } + return {}; +} + +void UserPrivacySettingRule::add_dependencies(Dependencies &dependencies) const { + for (auto user_id : user_ids_) { + dependencies.add(user_id); + } + for (auto dialog_id : dialog_ids_) { + dependencies.add_dialog_and_dependencies(dialog_id); + } +} + +UserPrivacySettingRules UserPrivacySettingRules::get_user_privacy_setting_rules( + Td *td, telegram_api::object_ptr rules) { + td->user_manager_->on_get_users(std::move(rules->users_), "on get privacy rules"); + td->chat_manager_->on_get_chats(std::move(rules->chats_), "on get privacy rules"); + return get_user_privacy_setting_rules(td, std::move(rules->rules_)); +} + +UserPrivacySettingRules UserPrivacySettingRules::get_user_privacy_setting_rules( + Td *td, vector> rules) { + UserPrivacySettingRules result; + for (auto &rule : rules) { + result.rules_.push_back(UserPrivacySettingRule(td, std::move(rule))); + } + if (!result.rules_.empty() && result.rules_.back().type_ == UserPrivacySettingRule::Type::RestrictAll) { + result.rules_.pop_back(); + } + return result; +} + +Result UserPrivacySettingRules::get_user_privacy_setting_rules( + Td *td, td_api::object_ptr rules) { + if (rules == nullptr) { + return Status::Error(400, "UserPrivacySettingRules must be non-empty"); + } + UserPrivacySettingRules result; + for (auto &rule : rules->rules_) { + if (rule == nullptr) { + return Status::Error(400, "UserPrivacySettingRule must be non-empty"); + } + result.rules_.emplace_back(td, *rule); + } + return result; +} + +Result UserPrivacySettingRules::get_user_privacy_setting_rules( + Td *td, td_api::object_ptr settings) { + if (settings == nullptr) { + return Status::Error(400, "StoryPrivacySettings must be non-empty"); + } + UserPrivacySettingRules result; + switch (settings->get_id()) { + case td_api::storyPrivacySettingsEveryone::ID: { + auto user_ids = std::move(static_cast(*settings).except_user_ids_); + if (!user_ids.empty()) { + result.rules_.emplace_back(td, td_api::userPrivacySettingRuleRestrictUsers(std::move(user_ids))); + } + result.rules_.emplace_back(td, td_api::userPrivacySettingRuleAllowAll()); + break; + } + case td_api::storyPrivacySettingsContacts::ID: { + auto user_ids = std::move(static_cast(*settings).except_user_ids_); + if (!user_ids.empty()) { + result.rules_.emplace_back(td, td_api::userPrivacySettingRuleRestrictUsers(std::move(user_ids))); + } + result.rules_.emplace_back(td, td_api::userPrivacySettingRuleAllowContacts()); + break; + } + case td_api::storyPrivacySettingsCloseFriends::ID: { + UserPrivacySettingRule rule; + rule.type_ = UserPrivacySettingRule::Type::AllowCloseFriends; + result.rules_.push_back(std::move(rule)); + break; + } + case td_api::storyPrivacySettingsSelectedUsers::ID: { + auto user_ids = std::move(static_cast(*settings).user_ids_); + result.rules_.emplace_back(td, td_api::userPrivacySettingRuleAllowUsers(std::move(user_ids))); + break; + } + default: + UNREACHABLE(); + } + return result; +} + +td_api::object_ptr UserPrivacySettingRules::get_user_privacy_setting_rules_object( + Td *td) const { + return make_tl_object( + transform(rules_, [td](const auto &rule) { return rule.get_user_privacy_setting_rule_object(td); })); +} + +td_api::object_ptr UserPrivacySettingRules::get_story_privacy_settings_object( + Td *td) const { + if (rules_.empty()) { + return nullptr; + } + if (rules_.size() == 1u && rules_[0].type_ == UserPrivacySettingRule::Type::AllowAll) { + return td_api::make_object(); + } + if (rules_.size() == 2u && rules_[0].type_ == UserPrivacySettingRule::Type::RestrictUsers && + rules_[1].type_ == UserPrivacySettingRule::Type::AllowAll) { + return td_api::make_object( + td->user_manager_->get_user_ids_object(rules_[0].user_ids_, "storyPrivacySettingsEveryone")); + } + if (rules_.size() == 1u && rules_[0].type_ == UserPrivacySettingRule::Type::AllowContacts) { + return td_api::make_object(); + } + if (rules_.size() == 2u && rules_[0].type_ == UserPrivacySettingRule::Type::RestrictUsers && + rules_[1].type_ == UserPrivacySettingRule::Type::AllowContacts) { + return td_api::make_object( + td->user_manager_->get_user_ids_object(rules_[0].user_ids_, "storyPrivacySettingsContacts")); + } + if (rules_.size() == 1u && rules_[0].type_ == UserPrivacySettingRule::Type::AllowCloseFriends) { + return td_api::make_object(); + } + if (rules_.size() == 1u && rules_[0].type_ == UserPrivacySettingRule::Type::AllowUsers) { + return td_api::make_object( + td->user_manager_->get_user_ids_object(rules_[0].user_ids_, "storyPrivacySettingsSelectedUsers")); + } + return td_api::make_object(); +} + +vector> UserPrivacySettingRules::get_input_privacy_rules( + Td *td) const { + auto result = transform(rules_, [td](const auto &rule) { return rule.get_input_privacy_rule(td); }); + if (!result.empty() && result.back()->get_id() == telegram_api::inputPrivacyValueDisallowAll::ID) { + result.pop_back(); + } + return result; +} + +vector UserPrivacySettingRules::get_restricted_user_ids() const { + vector result; + for (auto &rule : rules_) { + combine(result, rule.get_restricted_user_ids()); + } + std::sort(result.begin(), result.end(), [](UserId lhs, UserId rhs) { return lhs.get() < rhs.get(); }); + result.erase(std::unique(result.begin(), result.end()), result.end()); + return result; +} + +void UserPrivacySettingRules::add_dependencies(Dependencies &dependencies) const { + for (auto &rule : rules_) { + rule.add_dependencies(dependencies); + } +} + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySettingRule.h b/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySettingRule.h new file mode 100644 index 0000000000..3e16dcb38c --- /dev/null +++ b/protocols/Telegram/tdlib/td/td/telegram/UserPrivacySettingRule.h @@ -0,0 +1,154 @@ +// +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +#pragma once + +#include "td/telegram/DialogId.h" +#include "td/telegram/td_api.h" +#include "td/telegram/telegram_api.h" +#include "td/telegram/UserId.h" + +#include "td/utils/common.h" +#include "td/utils/Status.h" +#include "td/utils/tl_helpers.h" + +namespace td { + +class Dependencies; +class Td; + +class UserPrivacySettingRule { + public: + UserPrivacySettingRule() = default; + + UserPrivacySettingRule(Td *td, const td_api::UserPrivacySettingRule &rule); + + UserPrivacySettingRule(Td *td, const telegram_api::object_ptr &rule); + + td_api::object_ptr get_user_privacy_setting_rule_object(Td *td) const; + + telegram_api::object_ptr get_input_privacy_rule(Td *td) const; + + bool operator==(const UserPrivacySettingRule &other) const { + return type_ == other.type_ && user_ids_ == other.user_ids_ && dialog_ids_ == other.dialog_ids_; + } + + vector get_restricted_user_ids() const; + + void add_dependencies(Dependencies &dependencies) const; + + template + void store(StorerT &storer) const { + td::store(type_, storer); + if (type_ == Type::AllowUsers || type_ == Type::RestrictUsers) { + td::store(user_ids_, storer); + } + if (type_ == Type::AllowChatParticipants || type_ == Type::RestrictChatParticipants) { + td::store(dialog_ids_, storer); + } + } + + template + void parse(ParserT &parser) { + td::parse(type_, parser); + if (type_ == Type::AllowUsers || type_ == Type::RestrictUsers) { + td::parse(user_ids_, parser); + for (auto user_id : user_ids_) { + if (!user_id.is_valid()) { + parser.set_error("Failed to parse user identifiers"); + } + } + } else if (type_ == Type::AllowChatParticipants || type_ == Type::RestrictChatParticipants) { + td::parse(dialog_ids_, parser); + for (auto dialog_id : dialog_ids_) { + auto dialog_type = dialog_id.get_type(); + if (!dialog_id.is_valid() || (dialog_type != DialogType::Chat && dialog_type != DialogType::Channel)) { + parser.set_error("Failed to parse chat identifiers"); + } + } + } else if (type_ != Type::AllowContacts && type_ != Type::AllowPremium && type_ != Type::AllowCloseFriends && + type_ != Type::AllowAll && type_ != Type::RestrictContacts && type_ != Type::RestrictAll) { + parser.set_error("Invalid privacy rule type"); + } + } + + private: + enum class Type : int32 { + AllowContacts, + AllowCloseFriends, + AllowAll, + AllowUsers, + AllowChatParticipants, + RestrictContacts, + RestrictAll, + RestrictUsers, + RestrictChatParticipants, + AllowPremium + } type_ = Type::RestrictAll; + + friend class UserPrivacySettingRules; + + vector user_ids_; + vector dialog_ids_; + + vector> get_input_users(Td *td) const; + + vector get_input_chat_ids(Td *td) const; + + void set_dialog_ids(Td *td, const vector &chat_ids); + + void set_dialog_ids_from_server(Td *td, const vector &chat_ids); +}; + +class UserPrivacySettingRules { + public: + UserPrivacySettingRules() = default; + + static UserPrivacySettingRules get_user_privacy_setting_rules( + Td *td, telegram_api::object_ptr rules); + + static UserPrivacySettingRules get_user_privacy_setting_rules( + Td *td, vector> rules); + + static Result get_user_privacy_setting_rules( + Td *td, td_api::object_ptr rules); + + static Result get_user_privacy_setting_rules( + Td *td, td_api::object_ptr settings); + + td_api::object_ptr get_user_privacy_setting_rules_object(Td *td) const; + + td_api::object_ptr get_story_privacy_settings_object(Td *td) const; + + vector> get_input_privacy_rules(Td *td) const; + + bool operator==(const UserPrivacySettingRules &other) const { + return rules_ == other.rules_; + } + + bool operator!=(const UserPrivacySettingRules &other) const { + return !(rules_ == other.rules_); + } + + vector get_restricted_user_ids() const; + + void add_dependencies(Dependencies &dependencies) const; + + template + void store(StorerT &storer) const { + td::store(rules_, storer); + } + + template + void parse(ParserT &parser) { + td::parse(rules_, parser); + } + + private: + vector rules_; +}; + +} // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/Venue.cpp b/protocols/Telegram/tdlib/td/td/telegram/Venue.cpp index bd44546356..08d84e2810 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Venue.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/Venue.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -11,9 +11,9 @@ namespace td { -Venue::Venue(const tl_object_ptr &geo_point_ptr, string title, string address, string provider, - string id, string type) - : location_(geo_point_ptr) +Venue::Venue(Td *td, const tl_object_ptr &geo_point_ptr, string title, string address, + string provider, string id, string type) + : location_(td, geo_point_ptr) , title_(std::move(title)) , address_(std::move(address)) , provider_(std::move(provider)) @@ -76,6 +76,12 @@ tl_object_ptr Venue::get_input_bo flags, location_.get_input_geo_point(), title_, address_, provider_, id_, type_, std::move(reply_markup)); } +telegram_api::object_ptr Venue::get_input_media_area_venue( + telegram_api::object_ptr &&coordinates) const { + return telegram_api::make_object(std::move(coordinates), location_.get_fake_geo_point(), + title_, address_, provider_, id_, type_); +} + bool operator==(const Venue &lhs, const Venue &rhs) { return lhs.location_ == rhs.location_ && lhs.title_ == rhs.title_ && lhs.address_ == rhs.address_ && lhs.provider_ == rhs.provider_ && lhs.id_ == rhs.id_ && lhs.type_ == rhs.type_; diff --git a/protocols/Telegram/tdlib/td/td/telegram/Venue.h b/protocols/Telegram/tdlib/td/td/telegram/Venue.h index 5d5c2ff80e..303bac4ddb 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Venue.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Venue.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -19,6 +19,8 @@ namespace td { +class Td; + class Venue { Location location_; string title_; @@ -34,8 +36,8 @@ class Venue { public: Venue() = default; - Venue(const tl_object_ptr &geo_point_ptr, string title, string address, string provider, - string id, string type); + Venue(Td *td, const tl_object_ptr &geo_point_ptr, string title, string address, + string provider, string id, string type); Venue(Location location, string title, string address, string provider, string id, string type); @@ -43,6 +45,10 @@ class Venue { bool empty() const; + bool is_same(const string &provider, const string &id) const { + return provider_ == provider && id_ == id; + } + Location &location(); const Location &location() const; @@ -56,6 +62,9 @@ class Venue { tl_object_ptr get_input_bot_inline_message_media_venue( tl_object_ptr &&reply_markup) const; + telegram_api::object_ptr get_input_media_area_venue( + telegram_api::object_ptr &&coordinates) const; + template void store(StorerT &storer) const { using td::store; diff --git a/protocols/Telegram/tdlib/td/td/telegram/Version.h b/protocols/Telegram/tdlib/td/td/telegram/Version.h index 72aff6812b..83704d26cc 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/Version.h +++ b/protocols/Telegram/tdlib/td/td/telegram/Version.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -10,7 +10,7 @@ namespace td { -constexpr int32 MTPROTO_LAYER = 158; +constexpr int32 MTPROTO_LAYER = 187; enum class Version : int32 { Initial, // 0 @@ -61,15 +61,22 @@ enum class Version : int32 { AddMessageMediaSpoiler, // 45 MakeParticipantFlags64Bit, AddDocumentFlags, + AddUserFlags2, + AddMessageTextFlags, + AddPageBlockChatLinkFlags, // 50 + SupportRepliesInOtherChats, + SupportMultipleSharedUsers, + SupportMoreEmojiGroups, + SupportStarGiveaways, Next }; enum class DbVersion : int32 { - DialogDbCreated = 3, - MessageDbMediaIndex, - MessageDb30MediaIndex, - MessageDbFts, - MessagesCallIndex, + CreateDialogDb = 3, + AddMessageDbMediaIndex, + AddMessageDb30MediaIndex, + AddMessageDbFts, + AddMessagesCallIndex, FixFileRemoteLocationKeyBug, AddNotificationsSupport, AddFolders, diff --git a/protocols/Telegram/tdlib/td/td/telegram/VideoNotesManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/VideoNotesManager.cpp index 928c4785f6..c66c3840af 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/VideoNotesManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/VideoNotesManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -9,16 +9,13 @@ #include "td/telegram/AuthManager.h" #include "td/telegram/files/FileManager.h" #include "td/telegram/Global.h" -#include "td/telegram/MessagesManager.h" #include "td/telegram/OptionManager.h" #include "td/telegram/PhotoFormat.h" #include "td/telegram/secret_api.h" #include "td/telegram/Td.h" #include "td/telegram/td_api.h" #include "td/telegram/telegram_api.h" -#include "td/telegram/UpdatesManager.h" - -#include "td/actor/actor.h" +#include "td/telegram/TranscriptionManager.h" #include "td/utils/buffer.h" #include "td/utils/logging.h" @@ -44,6 +41,15 @@ int32 VideoNotesManager::get_video_note_duration(FileId file_id) const { return video_note->duration; } +TranscriptionInfo *VideoNotesManager::get_video_note_transcription_info(FileId file_id, bool allow_creation) { + auto video_note = get_video_note(file_id); + CHECK(video_note != nullptr); + if (video_note->transcription_info == nullptr && allow_creation) { + video_note->transcription_info = make_unique(); + } + return video_note->transcription_info.get(); +} + tl_object_ptr VideoNotesManager::get_video_note_object(FileId file_id) const { if (!file_id.is_valid()) { return nullptr; @@ -89,7 +95,7 @@ FileId VideoNotesManager::on_get_video_note(unique_ptr new_video_note v->thumbnail = std::move(new_video_note->thumbnail); } if (TranscriptionInfo::update_from(v->transcription_info, std::move(new_video_note->transcription_info))) { - on_video_note_transcription_completed(file_id); + td_->transcription_manager_->on_transcription_completed(file_id); } } return file_id; @@ -170,129 +176,6 @@ void VideoNotesManager::create_video_note(FileId file_id, string minithumbnail, on_get_video_note(std::move(v), replace); } -void VideoNotesManager::register_video_note(FileId video_note_file_id, FullMessageId full_message_id, - const char *source) { - if (full_message_id.get_message_id().is_scheduled() || !full_message_id.get_message_id().is_server() || - td_->auth_manager_->is_bot()) { - return; - } - LOG(INFO) << "Register video note " << video_note_file_id << " from " << full_message_id << " from " << source; - CHECK(video_note_file_id.is_valid()); - bool is_inserted = video_note_messages_[video_note_file_id].insert(full_message_id).second; - LOG_CHECK(is_inserted) << source << ' ' << video_note_file_id << ' ' << full_message_id; - is_inserted = message_video_notes_.emplace(full_message_id, video_note_file_id).second; - CHECK(is_inserted); -} - -void VideoNotesManager::unregister_video_note(FileId video_note_file_id, FullMessageId full_message_id, - const char *source) { - if (full_message_id.get_message_id().is_scheduled() || !full_message_id.get_message_id().is_server() || - td_->auth_manager_->is_bot()) { - return; - } - LOG(INFO) << "Unregister video note " << video_note_file_id << " from " << full_message_id << " from " << source; - CHECK(video_note_file_id.is_valid()); - auto &message_ids = video_note_messages_[video_note_file_id]; - auto is_deleted = message_ids.erase(full_message_id) > 0; - LOG_CHECK(is_deleted) << source << ' ' << video_note_file_id << ' ' << full_message_id; - if (message_ids.empty()) { - video_note_messages_.erase(video_note_file_id); - } - is_deleted = message_video_notes_.erase(full_message_id) > 0; - CHECK(is_deleted); -} - -void VideoNotesManager::recognize_speech(FullMessageId full_message_id, Promise &&promise) { - auto it = message_video_notes_.find(full_message_id); - CHECK(it != message_video_notes_.end()); - - auto file_id = it->second; - auto video_note = get_video_note(file_id); - CHECK(video_note != nullptr); - if (video_note->transcription_info == nullptr) { - video_note->transcription_info = make_unique(); - } - - auto handler = [actor_id = actor_id(this), - file_id](Result> r_update) { - send_closure(actor_id, &VideoNotesManager::on_transcribed_audio_update, file_id, true, std::move(r_update)); - }; - if (video_note->transcription_info->recognize_speech(td_, full_message_id, std::move(promise), std::move(handler))) { - on_video_note_transcription_updated(file_id); - } -} - -void VideoNotesManager::on_transcribed_audio_update( - FileId file_id, bool is_initial, Result> r_update) { - if (G()->close_flag()) { - return; - } - - auto video_note = get_video_note(file_id); - CHECK(video_note != nullptr); - CHECK(video_note->transcription_info != nullptr); - - if (r_update.is_error()) { - auto promises = video_note->transcription_info->on_failed_transcription(r_update.error().clone()); - on_video_note_transcription_updated(file_id); - fail_promises(promises, r_update.move_as_error()); - return; - } - auto update = r_update.move_as_ok(); - auto transcription_id = update->transcription_id_; - if (!update->pending_) { - auto promises = video_note->transcription_info->on_final_transcription(std::move(update->text_), transcription_id); - on_video_note_transcription_completed(file_id); - set_promises(promises); - } else { - auto is_changed = - video_note->transcription_info->on_partial_transcription(std::move(update->text_), transcription_id); - if (is_changed) { - on_video_note_transcription_updated(file_id); - } - - if (is_initial) { - td_->updates_manager_->subscribe_to_transcribed_audio_updates( - transcription_id, [actor_id = actor_id(this), - file_id](Result> r_update) { - send_closure(actor_id, &VideoNotesManager::on_transcribed_audio_update, file_id, false, - std::move(r_update)); - }); - } - } -} - -void VideoNotesManager::on_video_note_transcription_updated(FileId file_id) { - auto it = video_note_messages_.find(file_id); - if (it != video_note_messages_.end()) { - for (const auto &full_message_id : it->second) { - td_->messages_manager_->on_external_update_message_content(full_message_id); - } - } -} - -void VideoNotesManager::on_video_note_transcription_completed(FileId file_id) { - auto it = video_note_messages_.find(file_id); - if (it != video_note_messages_.end()) { - for (const auto &full_message_id : it->second) { - td_->messages_manager_->on_update_message_content(full_message_id); - } - } -} - -void VideoNotesManager::rate_speech_recognition(FullMessageId full_message_id, bool is_good, Promise &&promise) { - auto it = message_video_notes_.find(full_message_id); - CHECK(it != message_video_notes_.end()); - - auto file_id = it->second; - auto video_note = get_video_note(file_id); - CHECK(video_note != nullptr); - if (video_note->transcription_info == nullptr) { - return promise.set_value(Unit()); - } - video_note->transcription_info->rate_speech_recognition(td_, full_message_id, is_good, std::move(promise)); -} - SecretInputMedia VideoNotesManager::get_secret_input_media(FileId video_note_file_id, tl_object_ptr input_file, BufferSlice thumbnail, int32 layer) const { @@ -302,8 +185,9 @@ SecretInputMedia VideoNotesManager::get_secret_input_media(FileId video_note_fil if (!file_view.is_encrypted_secret() || file_view.encryption_key().empty()) { return SecretInputMedia{}; } - if (file_view.has_remote_location()) { - input_file = file_view.main_remote_location().as_input_encrypted_file(); + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr) { + input_file = main_remote_location->as_input_encrypted_file(); } if (!input_file) { return SecretInputMedia{}; @@ -328,17 +212,27 @@ SecretInputMedia VideoNotesManager::get_secret_input_media(FileId video_note_fil tl_object_ptr VideoNotesManager::get_input_media( FileId file_id, tl_object_ptr input_file, - tl_object_ptr input_thumbnail) const { + tl_object_ptr input_thumbnail, int32 ttl) const { auto file_view = td_->file_manager_->get_file_view(file_id); if (file_view.is_encrypted()) { return nullptr; } - if (file_view.has_remote_location() && !file_view.main_remote_location().is_web() && input_file == nullptr) { - return make_tl_object( - 0, false /*ignored*/, file_view.main_remote_location().as_input_document(), 0, string()); + const auto *main_remote_location = file_view.get_main_remote_location(); + if (main_remote_location != nullptr && !main_remote_location->is_web() && input_file == nullptr) { + int32 flags = 0; + if (ttl != 0) { + flags |= telegram_api::inputMediaDocument::TTL_SECONDS_MASK; + } + return make_tl_object(flags, false /*ignored*/, + main_remote_location->as_input_document(), ttl, string()); } - if (file_view.has_url()) { - return make_tl_object(0, false /*ignored*/, file_view.url(), 0); + const auto *url = file_view.get_url(); + if (url != nullptr) { + int32 flags = 0; + if (ttl != 0) { + flags |= telegram_api::inputMediaDocumentExternal::TTL_SECONDS_MASK; + } + return make_tl_object(flags, false /*ignored*/, *url, ttl); } if (input_file != nullptr) { @@ -350,18 +244,22 @@ tl_object_ptr VideoNotesManager::get_input_media( narrow_cast(td_->option_manager_->get_option_integer("suggested_video_note_length", 384)); attributes.push_back(make_tl_object( telegram_api::documentAttributeVideo::ROUND_MESSAGE_MASK, false /*ignored*/, false /*ignored*/, - video_note->duration, video_note->dimensions.width ? video_note->dimensions.width : suggested_video_note_length, - video_note->dimensions.height ? video_note->dimensions.height : suggested_video_note_length)); + false /*ignored*/, video_note->duration, + video_note->dimensions.width ? video_note->dimensions.width : suggested_video_note_length, + video_note->dimensions.height ? video_note->dimensions.height : suggested_video_note_length, 0, 0.0)); int32 flags = telegram_api::inputMediaUploadedDocument::NOSOUND_VIDEO_MASK; + if (ttl != 0) { + flags |= telegram_api::inputMediaUploadedDocument::TTL_SECONDS_MASK; + } if (input_thumbnail != nullptr) { flags |= telegram_api::inputMediaUploadedDocument::THUMB_MASK; } return make_tl_object( flags, false /*ignored*/, false /*ignored*/, false /*ignored*/, std::move(input_file), std::move(input_thumbnail), "video/mp4", std::move(attributes), - vector>(), 0); + vector>(), ttl); } else { - CHECK(!file_view.has_remote_location()); + CHECK(main_remote_location == nullptr); } return nullptr; diff --git a/protocols/Telegram/tdlib/td/td/telegram/VideoNotesManager.h b/protocols/Telegram/tdlib/td/td/telegram/VideoNotesManager.h index 0c4eb3bc19..d4083b548a 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/VideoNotesManager.h +++ b/protocols/Telegram/tdlib/td/td/telegram/VideoNotesManager.h @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -8,7 +8,6 @@ #include "td/telegram/Dimensions.h" #include "td/telegram/files/FileId.h" -#include "td/telegram/FullMessageId.h" #include "td/telegram/PhotoSize.h" #include "td/telegram/SecretInputMedia.h" #include "td/telegram/td_api.h" @@ -19,10 +18,6 @@ #include "td/utils/buffer.h" #include "td/utils/common.h" -#include "td/utils/FlatHashMap.h" -#include "td/utils/FlatHashSet.h" -#include "td/utils/Promise.h" -#include "td/utils/Status.h" #include "td/utils/WaitFreeHashMap.h" namespace td { @@ -40,22 +35,17 @@ class VideoNotesManager final : public Actor { int32 get_video_note_duration(FileId file_id) const; + TranscriptionInfo *get_video_note_transcription_info(FileId file_id, bool allow_creation); + tl_object_ptr get_video_note_object(FileId file_id) const; void create_video_note(FileId file_id, string minithumbnail, PhotoSize thumbnail, int32 duration, Dimensions dimensions, string waveform, bool replace); - void register_video_note(FileId video_note_file_id, FullMessageId full_message_id, const char *source); - - void unregister_video_note(FileId video_note_file_id, FullMessageId full_message_id, const char *source); - - void recognize_speech(FullMessageId full_message_id, Promise &&promise); - - void rate_speech_recognition(FullMessageId full_message_id, bool is_good, Promise &&promise); - tl_object_ptr get_input_media(FileId file_id, tl_object_ptr input_file, - tl_object_ptr input_thumbnail) const; + tl_object_ptr input_thumbnail, + int32 ttl) const; SecretInputMedia get_secret_input_media(FileId video_note_file_id, tl_object_ptr input_file, @@ -94,22 +84,12 @@ class VideoNotesManager final : public Actor { FileId on_get_video_note(unique_ptr new_video_note, bool replace); - void on_video_note_transcription_updated(FileId file_id); - - void on_video_note_transcription_completed(FileId file_id); - - void on_transcribed_audio_update(FileId file_id, bool is_initial, - Result> r_update); - void tear_down() final; Td *td_; ActorShared<> parent_; WaitFreeHashMap, FileIdHash> video_notes_; - - FlatHashMap, FileIdHash> video_note_messages_; - FlatHashMap message_video_notes_; }; } // namespace td diff --git a/protocols/Telegram/tdlib/td/td/telegram/VideosManager.cpp b/protocols/Telegram/tdlib/td/td/telegram/VideosManager.cpp index 6fc23218af..582e8a49ea 100644 --- a/protocols/Telegram/tdlib/td/td/telegram/VideosManager.cpp +++ b/protocols/Telegram/tdlib/td/td/telegram/VideosManager.cpp @@ -1,5 +1,5 @@ // -// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2023 +// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2024 // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -21,6 +21,8 @@ #include "td/utils/misc.h" #include "td/utils/Status.h" +#include + namespace td { VideosManager::VideosManager(Td *td) : td_(td) { @@ -36,7 +38,7 @@ int32 VideosManager::get_video_duration(FileId file_id) const { return video->duration; } -tl_object_ptr VideosManager::get_video_object(FileId file_id) const { +td_api::object_ptr VideosManager::get_video_object(FileId file_id) const { if (!file_id.is_valid()) { return nullptr; } @@ -46,10 +48,26 @@ tl_object_ptr VideosManager::get_video_object(FileId file_id) con auto thumbnail = video->animated_thumbnail.file_id.is_valid() ? get_thumbnail_object(td_->file_manager_.get(), video->animated_thumbnail, PhotoFormat::Mpeg4) : get_thumbnail_object(td_->file_manager_.get(), video->thumbnail, PhotoFormat::Jpeg); - return make_tl_object(video->duration, video->dimensions.width, video->dimensions.height, - video->file_name, video->mime_type, video->has_stickers, - video->supports_streaming, get_minithumbnail_object(video->minithumbnail), - std::move(thumbnail), td_->file_manager_->get_file_object(file_id)); + return td_api::make_object(video->duration, video->dimensions.width, video->dimensions.height, + video->file_name, video->mime_type, video->has_stickers, + video->supports_streaming, get_minithumbnail_object(video->minithumbnail), + std::move(thumbnail), td_->file_manager_->get_file_object(file_id)); +} + +td_api::object_ptr VideosManager::get_story_video_object(FileId file_id) const { + if (!file_id.is_valid()) { + return nullptr; + } + + auto video = get_video(file_id); + CHECK(video != nullptr); + auto thumbnail = video->animated_thumbnail.file_id.is_valid() + ? get_thumbnail_object(td_->file_manager_.get(), video->animated_thumbnail, PhotoFormat::Mpeg4) + : get_thumbnail_object(td_->file_manager_.get(), video->thumbnail, PhotoFormat::Jpeg); + return td_api::make_object( + video->precise_duration, video->dimensions.width, video->dimensions.height, video->has_stickers, + video->is_animation, get_minithumbnail_object(video->minithumbnail), std::move(thumbnail), + video->preload_prefix_size, video->start_ts, td_->file_manager_->get_file_object(file_id)); } FileId VideosManager::on_get_video(unique_ptr